From 24ba783d442000c2b1aa959a7136f1eeaece7a84 Mon Sep 17 00:00:00 2001 From: g-cont Date: Wed, 22 Dec 2010 00:00:00 +0300 Subject: [PATCH] 22 Dec 2010 --- cl_dll/hud.cpp | 25 +- engine/client/cl_frame.c | 15 +- engine/client/cl_game.c | 2 +- engine/client/cl_main.c | 18 +- engine/client/cl_menu.c | 5 +- engine/client/cl_pmove.c | 4 + engine/client/cl_scrn.c | 20 +- engine/client/cl_video.c | 9 + engine/client/gl_cull.c | 6 +- engine/client/gl_image.c | 4 +- engine/client/gl_local.h | 2 + engine/client/gl_rmain.c | 3 + engine/client/gl_rmisc.c | 2 - engine/client/gl_rsurf.c | 2 +- engine/client/gl_sprite.c | 40 +-- engine/client/gl_vidnt.c | 464 ++++++++++++++++++++------------ engine/client/sound/s_backend.c | 286 ++------------------ engine/client/sound/s_main.c | 8 +- engine/client/sound/sound.h | 3 +- engine/common/cm_local.h | 1 + engine/common/com_export.h | 1 + engine/common/common.h | 5 +- engine/common/host.c | 63 ----- engine/common/input.c | 20 +- engine/common/model.c | 9 +- engine/server/sv_cmds.c | 6 +- engine/server/sv_studio.c | 2 + engine/server/sv_world.c | 8 + launch/filesystem.c | 4 +- mainui/menu_vidmodes.cpp | 6 +- 30 files changed, 459 insertions(+), 584 deletions(-) diff --git a/cl_dll/hud.cpp b/cl_dll/hud.cpp index 64ac7bed..b0103a5f 100644 --- a/cl_dll/hud.cpp +++ b/cl_dll/hud.cpp @@ -460,14 +460,37 @@ void CHud :: VidInit( void ) // we have already have loaded the sprite reference from hud.txt, but // we need to make sure all the sprites have been loaded (we've gone through a transition, or loaded a save game) client_sprite_t *p = m_pSpriteList; - int index = 0; + + // count the number of sprites of the appropriate res + m_iSpriteCount = 0; for ( int j = 0; j < m_iSpriteCountAllRes; j++ ) + { + if ( p->iRes == m_iRes ) + m_iSpriteCount++; + p++; + } + + delete [] m_rghSprites; + delete [] m_rgrcRects; + delete [] m_rgszSpriteNames; + + // allocated memory for sprite handle arrays + m_rghSprites = new HSPRITE[m_iSpriteCount]; + m_rgrcRects = new wrect_t[m_iSpriteCount]; + m_rgszSpriteNames = new char[m_iSpriteCount * MAX_SPRITE_NAME_LENGTH]; + + p = m_pSpriteList; + int index = 0; + for ( j = 0; j < m_iSpriteCountAllRes; j++ ) { if ( p->iRes == m_iRes ) { char sz[256]; sprintf( sz, "sprites/%s.spr", p->szSprite ); m_rghSprites[index] = SPR_Load(sz); + m_rgrcRects[index] = p->rc; + strncpy( &m_rgszSpriteNames[index * MAX_SPRITE_NAME_LENGTH], p->szName, MAX_SPRITE_NAME_LENGTH ); + index++; } diff --git a/engine/client/cl_frame.c b/engine/client/cl_frame.c index 2ab0267b..5f894e4d 100644 --- a/engine/client/cl_frame.c +++ b/engine/client/cl_frame.c @@ -55,6 +55,14 @@ qboolean CL_AddVisibleEntity( cl_entity_t *ent, int entityType ) return true; } + if( entityType == ET_TEMPENTITY ) + { + // copy actual origin and angles back to let StudioModelRenderer + // get actual value directly from curstate + VectorCopy( ent->origin, ent->curstate.origin ); + VectorCopy( ent->angles, ent->curstate.angles ); + } + // don't add himself on firstperson if(( ent->index - 1 ) == cl.playernum && ent != &clgame.viewent && !cl.thirdperson ) { @@ -328,12 +336,13 @@ void CL_DeltaEntity( sizebuf_t *msg, frame_t *frame, int newnum, entity_state_t if( ent->player ) { - clgame.dllFuncs.pfnProcessPlayerState( &cl.frame.playerstate[ent->index-1], state ); + clgame.dllFuncs.pfnProcessPlayerState( &frame->playerstate[ent->index-1], state ); + + frame->playerstate[ent->index-1].number = ent->index; // fill private structure for local client if(( ent->index - 1 ) == cl.playernum ) - cl.frame.local.playerstate = cl.frame.playerstate[ent->index-1]; - cl.frame.playerstate[ent->index-1].number = ent->index; + frame->local.playerstate = frame->playerstate[ent->index-1]; } } diff --git a/engine/client/cl_game.c b/engine/client/cl_game.c index 1af67e2e..13aa1368 100644 --- a/engine/client/cl_game.c +++ b/engine/client/cl_game.c @@ -1283,7 +1283,6 @@ void CL_ClearWorld( void ) ent->curstate.solid = SOLID_BSP; ent->curstate.movetype = MOVETYPE_PUSH; ent->model = cl.worldmodel; - clgame.numEntities = 1; } void CL_InitEdicts( void ) @@ -1294,6 +1293,7 @@ void CL_InitEdicts( void ) cls.num_client_entities = CL_UPDATE_BACKUP * 64; cls.packet_entities = Z_Realloc( cls.packet_entities, sizeof( entity_state_t ) * cls.num_client_entities ); clgame.entities = Mem_Alloc( clgame.mempool, sizeof( cl_entity_t ) * clgame.maxEntities ); + clgame.numEntities = 1; } void CL_FreeEdicts( void ) diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index 716eb21f..44cfb359 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -70,17 +70,6 @@ qboolean CL_IsPlaybackDemo( void ) return cls.demoplayback; } -void CL_ForceVid( void ) -{ - cl.video_prepped = false; - host.state = HOST_RESTART; -} - -void CL_ForceSnd( void ) -{ - cl.audio_prepped = false; -} - /* =============== CL_LerpPoint @@ -1562,7 +1551,7 @@ void Host_ClientFrame( void ) // predict all unacknowledged movements CL_PredictMovement(); - Host_CheckChanges(); + VID_CheckChanges(); // allow sound and video DLL change if( cls.state == ca_active ) @@ -1602,9 +1591,8 @@ void CL_Init( void ) Con_Init(); CL_InitLocal(); - // give initial openGL configuration - Cbuf_AddText( "exec opengl.cfg\n" ); - Host_CheckChanges (); + R_Init(); // init renderer + S_Init(); // init sound if( !CL_LoadProgs( va( "%s/client.dll", GI->dll_path ))) Host_Error( "CL_InitGame: can't initialize client.dll\n" ); diff --git a/engine/client/cl_menu.c b/engine/client/cl_menu.c index 4d7373ae..38e961c1 100644 --- a/engine/client/cl_menu.c +++ b/engine/client/cl_menu.c @@ -32,7 +32,10 @@ void UI_SetActiveMenu( qboolean fActive ) { movie_state_t *cin_state; - if( !menu.hInstance ) return; + // don't touch menu state when video is restarted + if( !menu.hInstance )//|| host.state == HOST_RESTART ) + return; + menu.drawLogo = fActive; menu.dllFuncs.pfnSetActiveMenu( fActive ); diff --git a/engine/client/cl_pmove.c b/engine/client/cl_pmove.c index c72c34b4..fab9e5dd 100644 --- a/engine/client/cl_pmove.c +++ b/engine/client/cl_pmove.c @@ -110,6 +110,10 @@ void CL_AddLinksToPmove( void ) if( !check || check == &clgame.entities[0] || check->player ) continue; + // can't collide with zeroed hull + if( VectorIsNull( check->curstate.mins ) && VectorIsNull( check->curstate.maxs )) + continue; + if( check->curstate.solid == SOLID_BSP || check->curstate.solid == SOLID_BBOX || check->curstate.solid == SOLID_SLIDEBOX ) { if( clgame.pmove->numphysent == MAX_PHYSENTS ) diff --git a/engine/client/cl_scrn.c b/engine/client/cl_scrn.c index 8799cff0..feea30ed 100644 --- a/engine/client/cl_scrn.c +++ b/engine/client/cl_scrn.c @@ -385,8 +385,11 @@ void SCR_VidInit( void ) VGui_Startup (); + clgame.load_sequence++; // now all hud sprites are invalid + // vid_state has changed if( menu.hInstance ) menu.dllFuncs.pfnVidInit(); + if( clgame.hInstance ) clgame.dllFuncs.pfnVidInit(); // restart console size Con_VidInit (); @@ -416,7 +419,7 @@ void SCR_Init( void ) Cmd_AddCommand( "skyname", CL_SetSky_f, "set new skybox by basename" ); Cmd_AddCommand( "viewpos", SCR_Viewpos_f, "prints current player origin" ); - if( !UI_LoadProgs( va( "%s/MainUI.dll", GI->dll_path ) )) + if( host.state != HOST_RESTART && !UI_LoadProgs( va( "%s/MainUI.dll", GI->dll_path ) )) { Msg( "^1Error: ^7can't initialize MainUI.dll\n" ); // there is non fatal for us if( !host.developer ) host.developer = 1; // we need console, because menu is missing @@ -428,9 +431,12 @@ void SCR_Init( void ) SCR_InitCinematic(); SCR_VidInit(); - if( host.developer && FS_CheckParm( "-toconsole" )) - Cbuf_AddText( "toggleconsole\n" ); - else UI_SetActiveMenu( true ); + if( host.state != HOST_RESTART ) + { + if( host.developer && FS_CheckParm( "-toconsole" )) + Cbuf_AddText( "toggleconsole\n" ); + else UI_SetActiveMenu( true ); + } scr_init = true; } @@ -442,9 +448,11 @@ void SCR_Shutdown( void ) Cmd_RemoveCommand( "timerefresh" ); Cmd_RemoveCommand( "skyname" ); Cmd_RemoveCommand( "viewpos" ); - UI_SetActiveMenu( false ); SCR_FreeCinematic(); - UI_UnloadProgs(); + + if( host.state != HOST_RESTART ) + UI_UnloadProgs(); + scr_init = false; } \ No newline at end of file diff --git a/engine/client/cl_video.c b/engine/client/cl_video.c index beb3e69e..7fbf37f6 100644 --- a/engine/client/cl_video.c +++ b/engine/client/cl_video.c @@ -290,5 +290,14 @@ SCR_FreeCinematic */ void SCR_FreeCinematic( void ) { + movie_state_t *cin_state; + + // release videos + cin_state = AVI_GetState( CIN_LOGO ); + AVI_CloseVideo( cin_state ); + + cin_state = AVI_GetState( CIN_MAIN ); + AVI_CloseVideo( cin_state ); + AVIFileExit(); } \ No newline at end of file diff --git a/engine/client/gl_cull.c b/engine/client/gl_cull.c index b6383fd7..2583e8c3 100644 --- a/engine/client/gl_cull.c +++ b/engine/client/gl_cull.c @@ -26,7 +26,8 @@ qboolean R_CullBox( const vec3_t mins, const vec3_t maxs, uint clipflags ) uint i, bit; const mplane_t *p; - if( r_nocull->integer ) + // client.dll may use additional passes for render custom mirrors etc + if( r_nocull->integer || RI.refdef.nextView != 0 ) return false; for( i = sizeof( RI.frustum ) / sizeof( RI.frustum[0] ), bit = 1, p = RI.frustum; i > 0; i--, bit<<=1, p++ ) @@ -87,7 +88,8 @@ qboolean R_CullSphere( const vec3_t centre, const float radius, const uint clipf uint i, bit; const mplane_t *p; - if( r_nocull->integer ) + // client.dll may use additional passes for render custom mirrors etc + if( r_nocull->integer || RI.refdef.nextView != 0 ) return false; for( i = sizeof( RI.frustum ) / sizeof( RI.frustum[0] ), bit = 1, p = RI.frustum; i > 0; i--, bit<<=1, p++ ) diff --git a/engine/client/gl_image.c b/engine/client/gl_image.c index 430d5cd3..41bdd27e 100644 --- a/engine/client/gl_image.c +++ b/engine/client/gl_image.c @@ -11,10 +11,10 @@ static int r_textureMinFilter = GL_LINEAR_MIPMAP_LINEAR; static int r_textureMagFilter = GL_LINEAR; - static gltexture_t r_textures[MAX_TEXTURES]; static gltexture_t *r_texturesHashTable[TEXTURES_HASH_SIZE]; static int r_numTextures; +static byte *scaledImage = NULL; // pointer to a scaled image static byte data2D[256*256*4]; // intermediate texbuffer static rgbdata_t r_image; // generic pixelbuffer used for internal textures @@ -494,7 +494,6 @@ Assume input buffer is RGBA */ byte *GL_ResampleTexture( const byte *source, int inWidth, int inHeight, int outWidth, int outHeight, qboolean isNormalMap ) { - static byte *scaledImage = NULL; uint frac, fracStep; uint *in = (uint *)source; uint p1[0x1000], p2[0x1000]; @@ -1263,6 +1262,7 @@ void R_InitImages( void ) float f; r_numTextures = 0; + scaledImage = NULL; Mem_Set( r_textures, 0, sizeof( r_textures )); Mem_Set( r_texturesHashTable, 0, sizeof( r_texturesHashTable )); diff --git a/engine/client/gl_local.h b/engine/client/gl_local.h index fafd594e..3062f4e7 100644 --- a/engine/client/gl_local.h +++ b/engine/client/gl_local.h @@ -360,7 +360,9 @@ void R_DrawSkyChain( msurface_t *s ); void GL_CheckForErrors_( const char *filename, const int fileline ); void GL_UpdateSwapInterval( void ); void GL_UpdateGammaRamp( void ); +qboolean GL_DeleteContext( void ); qboolean GL_Support( int r_ext ); +void VID_CheckChanges( void ); qboolean R_Init( void ); void R_Shutdown( void ); diff --git a/engine/client/gl_rmain.c b/engine/client/gl_rmain.c index 641a7342..a9e10838 100644 --- a/engine/client/gl_rmain.c +++ b/engine/client/gl_rmain.c @@ -267,6 +267,9 @@ int R_ComputeFxBlend( cl_entity_t *e ) blend += Com_RandomLong( -32, 31 ); } break; + case kRenderFxDeadPlayer: + blend = renderAmt; // safe current renderamt because it's player index! + break; case kRenderFxNone: case kRenderFxClampMinScale: default: diff --git a/engine/client/gl_rmisc.c b/engine/client/gl_rmisc.c index a97c2b1b..44cb38c8 100644 --- a/engine/client/gl_rmisc.c +++ b/engine/client/gl_rmisc.c @@ -12,8 +12,6 @@ void R_NewMap( void ) { int i; - tr.framecount = tr.visframecount = 1; - GL_BuildLightmaps (); R_SetupSky( cl.refdef.movevars->skyName ); diff --git a/engine/client/gl_rsurf.c b/engine/client/gl_rsurf.c index 8a33bdf3..92025887 100644 --- a/engine/client/gl_rsurf.c +++ b/engine/client/gl_rsurf.c @@ -1255,7 +1255,7 @@ void R_DrawWorld( void ) RI.currententity = clgame.entities; RI.currentmodel = RI.currententity->model; - if( RI.refdef.onlyClientDraw ) + if( !RI.drawWorld || RI.refdef.onlyClientDraw ) return; VectorCopy( RI.cullorigin, modelorg ); diff --git a/engine/client/gl_sprite.c b/engine/client/gl_sprite.c index c1b10454..7d256072 100644 --- a/engine/client/gl_sprite.c +++ b/engine/client/gl_sprite.c @@ -708,23 +708,23 @@ R_GlowSightDistance Set sprite brightness factor ================ */ -static float R_SpriteGlowBlend( cl_entity_t *e, vec3_t origin ) +static float R_SpriteGlowBlend( vec3_t origin, int rendermode, int renderfx, int alpha, float *pscale ) { float dist = R_GlowSightDistance( origin ); float brightness; if( dist <= 0 ) return 0.0f; // occluded - if( e->curstate.renderfx == kRenderFxNoDissipation ) - return (float)e->curstate.renderamt * (1.0f / 255.0f); + if( renderfx == kRenderFxNoDissipation ) + return (float)alpha * (1.0f / 255.0f); // UNDONE: Tweak these magic numbers (19000 - falloff & 200 - sprite size) brightness = 19000.0 / ( dist * dist ); - brightness = bound( 0.05f, brightness, 1.0f ); + brightness = bound( 0.01f, brightness, 1.0f ); // Make the glow fixed size in screen space, taking into consideration the scale setting. - if( e->curstate.scale == 0.0f ) e->curstate.scale = 1.0f; - e->curstate.scale *= dist * ( 1.0f / 200.0f ); + if( *pscale == 0.0f ) *pscale = 1.0f; + *pscale *= dist * ( 1.0f / 200.0f ); return brightness; } @@ -736,7 +736,7 @@ R_SpriteOccluded Do occlusion test for glow-sprites ================ */ -qboolean R_SpriteOccluded( cl_entity_t *e, vec3_t origin ) +qboolean R_SpriteOccluded( cl_entity_t *e, vec3_t origin, int *alpha, float *pscale ) { if( e->curstate.rendermode == kRenderGlow ) { @@ -750,10 +750,10 @@ qboolean R_SpriteOccluded( cl_entity_t *e, vec3_t origin ) if( v[1] < RI.refdef.viewport[1] || v[1] > RI.refdef.viewport[1] + RI.refdef.viewport[3] ) return true; // do scissor - blend *= R_SpriteGlowBlend( e, origin ); - e->curstate.renderamt *= blend; + blend *= R_SpriteGlowBlend( origin, e->curstate.rendermode, e->curstate.renderfx, *alpha, pscale ); + *alpha *= blend; - if( blend <= 0.05f ) + if( blend <= 0.01f ) return true; // faded } else @@ -805,9 +805,10 @@ void R_DrawSpriteModel( cl_entity_t *e ) mspriteframe_t *frame, *oldframe; msprite_t *psprite; model_t *model; + int alpha; int i, state = 0; float angle, sr, cr; - float lerp = 1.0f, ilerp; + float lerp = 1.0f, ilerp, scale; vec3_t v_forward, v_right, v_up; vec3_t origin; color24 color; @@ -836,7 +837,10 @@ void R_DrawSpriteModel( cl_entity_t *e ) } } - if( R_SpriteOccluded( e, origin )) + alpha = e->curstate.renderamt; + scale = e->curstate.scale; + + if( R_SpriteOccluded( e, origin, &alpha, &scale )) return; // sprite culled r_stats.c_sprite_models_drawn++; @@ -943,8 +947,8 @@ void R_DrawSpriteModel( cl_entity_t *e ) if( oldframe == frame ) { // draw the single non-lerped frame - pglColor4ub( color.r, color.g, color.b, e->curstate.renderamt ); - R_DrawSpriteQuad( frame, origin, v_right, v_up, e->curstate.scale ); + pglColor4ub( color.r, color.g, color.b, alpha ); + R_DrawSpriteQuad( frame, origin, v_right, v_up, scale ); } else { @@ -954,14 +958,14 @@ void R_DrawSpriteModel( cl_entity_t *e ) if( ilerp != 0 ) { - pglColor4ub( color.r, color.g, color.b, e->curstate.renderamt * ilerp ); - R_DrawSpriteQuad( oldframe, origin, v_right, v_up, e->curstate.scale ); + pglColor4ub( color.r, color.g, color.b, alpha * ilerp ); + R_DrawSpriteQuad( oldframe, origin, v_right, v_up, scale ); } if( lerp != 0 ) { - pglColor4ub( color.r, color.g, color.b, e->curstate.renderamt * lerp ); - R_DrawSpriteQuad( frame, origin, v_right, v_up, e->curstate.scale ); + pglColor4ub( color.r, color.g, color.b, alpha * lerp ); + R_DrawSpriteQuad( frame, origin, v_right, v_up, scale ); } } diff --git a/engine/client/gl_vidnt.c b/engine/client/gl_vidnt.c index 337c4915..c9c4bc3c 100644 --- a/engine/client/gl_vidnt.c +++ b/engine/client/gl_vidnt.c @@ -10,7 +10,7 @@ #include "input.h" #define MAX_PFDS 256 -#define VID_DEFAULTMODE "3" +#define VID_DEFAULTMODE "1" #define num_vidmodes ((int)(sizeof(vidmode) / sizeof(vidmode[0])) - 1) #define WINDOW_STYLE (WS_OVERLAPPED|WS_BORDER|WS_SYSMENU|WS_CAPTION|WS_VISIBLE) #define WINDOW_EX_STYLE (0) @@ -91,26 +91,24 @@ typedef struct vidmode_s vidmode_t vidmode[] = { -{ "Mode 0: 4x3", 400, 300, false }, -{ "Mode 1: 4x3", 512, 384, false }, -{ "Mode 2: 4x3", 640, 480, false }, -{ "Mode 3: 4x3", 800, 600, false }, -{ "Mode 4: 4x3", 960, 720, false }, -{ "Mode 5: 4x3", 1024, 768, false }, -{ "Mode 6: 4x3", 1152, 864, false }, -{ "Mode 7: 4x3", 1280, 800, false }, -{ "Mode 8: 4x3", 1280, 960, false }, -{ "Mode 9: 4x3", 1280, 1024, false }, -{ "Mode 10: 4x3", 1600, 1200, false }, -{ "Mode 11: 4x3", 2048, 1536, false }, -{ "Mode 12: 16x9", 856, 480, true }, -{ "Mode 13: 16x9", 1024, 576, true }, -{ "Mode 14: 16x9", 1280, 720, true }, -{ "Mode 15: 16x9", 1360, 768, true }, -{ "Mode 16: 16x9", 1440, 900, true }, -{ "Mode 17: 16x9", 1680, 1050, true }, -{ "Mode 18: 16x9", 1920, 1200, true }, -{ "Mode 19: 16x9", 2560, 1600, true }, +{ "Mode 0: 4x3", 640, 480, false }, +{ "Mode 1: 4x3", 800, 600, false }, +{ "Mode 2: 4x3", 960, 720, false }, +{ "Mode 3: 4x3", 1024, 768, false }, +{ "Mode 4: 4x3", 1152, 864, false }, +{ "Mode 5: 4x3", 1280, 800, false }, +{ "Mode 6: 4x3", 1280, 960, false }, +{ "Mode 7: 4x3", 1280, 1024, false }, +{ "Mode 8: 4x3", 1600, 1200, false }, +{ "Mode 9: 4x3", 2048, 1536, false }, +{ "Mode 10: 16x9", 856, 480, true }, +{ "Mode 11: 16x9", 1024, 576, true }, +{ "Mode 12: 16x9", 1280, 720, true }, +{ "Mode 13: 16x9", 1360, 768, true }, +{ "Mode 14: 16x9", 1440, 900, true }, +{ "Mode 15: 16x9", 1680, 1050, true }, +{ "Mode 16: 16x9", 1920, 1200, true }, +{ "Mode 17: 16x9", 2560, 1600, true }, { NULL, 0, 0, 0 }, }; @@ -617,6 +615,35 @@ static void GL_SetDefaultState( void ) glState.initializedMedia = false; } +/* +================= +GL_CreateContext +================= +*/ +qboolean GL_CreateContext( void ) +{ + if(!( glw_state.hGLRC = pwglCreateContext( glw_state.hDC ))) + return GL_DeleteContext(); + + if(!( pwglMakeCurrent( glw_state.hDC, glw_state.hGLRC ))) + return GL_DeleteContext(); + + return true; +} + +/* +================= +GL_UpdateContext +================= +*/ +qboolean GL_UpdateContext( void ) +{ + if(!( pwglMakeCurrent( glw_state.hDC, glw_state.hGLRC ))) + return GL_DeleteContext(); + + return true; +} + /* ================= GL_DeleteContext @@ -624,9 +651,13 @@ GL_DeleteContext */ qboolean GL_DeleteContext( void ) { + if( pwglMakeCurrent ) + pwglMakeCurrent( NULL, NULL ); + if( glw_state.hGLRC ) { - pwglDeleteContext( glw_state.hGLRC ); + if( pwglDeleteContext ) + pwglDeleteContext( glw_state.hGLRC ); glw_state.hGLRC = NULL; } @@ -641,16 +672,16 @@ qboolean GL_DeleteContext( void ) /* ================= -GL_ChoosePFD +VID_ChoosePFD ================= */ -static int GL_ChoosePFD( int colorBits, int alphaBits, int depthBits, int stencilBits ) +static int VID_ChoosePFD( int colorBits, int alphaBits, int depthBits, int stencilBits ) { PIXELFORMATDESCRIPTOR PFDs[MAX_PFDS], *current, *selected; uint flags = PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER; int i, numPFDs, pixelFormat = 0; - MsgDev( D_NOTE, "GL_ChoosePFD( color %i, alpha %i, depth %i, stencil %i )\n", colorBits, alphaBits, depthBits, stencilBits ); + MsgDev( D_NOTE, "VID_ChoosePFD( color %i, alpha %i, depth %i, stencil %i )\n", colorBits, alphaBits, depthBits, stencilBits ); // Count PFDs if( glw_state.minidriver ) @@ -664,7 +695,7 @@ static int GL_ChoosePFD( int colorBits, int alphaBits, int depthBits, int stenci } else if( numPFDs < 1 ) { - MsgDev( D_ERROR, "GL_ChoosePFD failed\n" ); + MsgDev( D_ERROR, "VID_ChoosePFD failed\n" ); return 0; } @@ -754,7 +785,7 @@ static int GL_ChoosePFD( int colorBits, int alphaBits, int depthBits, int stenci if( !pixelFormat ) { - MsgDev( D_ERROR, "GL_ChoosePFD: no hardware acceleration found\n" ); + MsgDev( D_ERROR, "VID_ChoosePFD: no hardware acceleration found\n" ); return 0; } @@ -762,24 +793,109 @@ static int GL_ChoosePFD( int colorBits, int alphaBits, int depthBits, int stenci { if( selected->dwFlags & PFD_GENERIC_ACCELERATED ) { - MsgDev( D_NOTE, "GL_ChoosePFD: usign Generic MCD acceleration\n" ); + MsgDev( D_NOTE, "VID_ChoosePFD: usign Generic MCD acceleration\n" ); glw_state.software = false; } else { - MsgDev( D_NOTE, "GL_ChoosePFD: using software emulation\n" ); + MsgDev( D_NOTE, "VID_ChoosePFD: using software emulation\n" ); glw_state.software = true; } } else { - MsgDev( D_NOTE, "GL_ChoosePFD: using hardware acceleration\n"); + MsgDev( D_NOTE, "VID_ChoosePFD: using hardware acceleration\n"); glw_state.software = false; } return pixelFormat; } +void VID_StartupGamma( void ) +{ + size_t gamma_size; + byte *savedGamma; + + // init gamma ramp + Mem_Set( glState.stateRamp, 0, sizeof( glState.stateRamp )); + + if( pwglGetDeviceGammaRamp3DFX ) + glConfig.deviceSupportsGamma = pwglGetDeviceGammaRamp3DFX( glw_state.hDC, glState.stateRamp ); + else glConfig.deviceSupportsGamma = GetDeviceGammaRamp( glw_state.hDC, glState.stateRamp ); + + // share this extension so engine can grab them + GL_SetExtension( GL_HARDWARE_GAMMA_CONTROL, glConfig.deviceSupportsGamma ); + + savedGamma = FS_LoadFile( "gamma.dat", &gamma_size ); + + if( !savedGamma || gamma_size != sizeof( glState.stateRamp )) + { + // saved gamma not found or corrupted file + FS_WriteFile( "gamma.dat", glState.stateRamp, sizeof( glState.stateRamp )); + MsgDev( D_NOTE, "VID_StartupGamma: gamma.dat initialized\n" ); + if( savedGamma ) Mem_Free( savedGamma ); + } + else + { + GL_BuildGammaTable(); + + // validate base gamma + if( !memcmp( savedGamma, glState.stateRamp, sizeof( glState.stateRamp ))) + { + // all ok, previous gamma is valid + MsgDev( D_NOTE, "VID_StartupGamma: validate screen gamma - ok\n" ); + } + else if( !memcmp( glState.gammaRamp, glState.stateRamp, sizeof( glState.stateRamp ))) + { + // screen gamma is equal to render gamma (probably previous instance crashed) + // run additional check to make sure for it + if( memcmp( savedGamma, glState.stateRamp, sizeof( glState.stateRamp ))) + { + // yes, current gamma it's totally wrong, restore it from gamma.dat + MsgDev( D_NOTE, "VID_StartupGamma: restore original gamma after crash\n" ); + Mem_Copy( glState.stateRamp, savedGamma, sizeof( glState.gammaRamp )); + } + else + { + // oops, savedGamma == glState.stateRamp == glState.gammaRamp + // probably r_gamma set as default + MsgDev( D_NOTE, "VID_StartupGamma: validate screen gamma - disabled\n" ); + } + } + else if( !memcmp( glState.gammaRamp, savedGamma, sizeof( glState.stateRamp ))) + { + // saved gamma is equal render gamma, probably gamma.dat wroted after crash + // run additional check to make sure it + if( memcmp( savedGamma, glState.stateRamp, sizeof( glState.stateRamp ))) + { + // yes, saved gamma it's totally wrong, get origianl gamma from screen + MsgDev( D_NOTE, "VID_StartupGamma: merge gamma.dat after crash\n" ); + FS_WriteFile( "gamma.dat", glState.stateRamp, sizeof( glState.stateRamp )); + } + else + { + // oops, savedGamma == glState.stateRamp == glState.gammaRamp + // probably r_gamma set as default + MsgDev( D_NOTE, "VID_StartupGamma: validate screen gamma - disabled\n" ); + } + } + else + { + // current gamma unset by other application, so we can restore it here + MsgDev( D_NOTE, "VID_StartupGamma: restore original gamma after crash\n" ); + Mem_Copy( glState.stateRamp, savedGamma, sizeof( glState.gammaRamp )); + } + Mem_Free( savedGamma ); + } + vid_gamma->modified = true; +} + +void VID_RestoreGamma( void ) +{ + if( !glw_state.hDC ) return; + SetDeviceGammaRamp( glw_state.hDC, glState.stateRamp ); +} + /* ================= GL_SetPixelformat @@ -791,13 +907,6 @@ qboolean GL_SetPixelformat( void ) int colorBits, alphaBits; int depthBits, stencilBits; int pixelFormat; - size_t gamma_size; - byte *savedGamma; - - Sys_LoadLibrary( NULL, &opengl_dll ); // load opengl32.dll - if( !opengl_dll.link ) return false; - - glw_state.minidriver = false; // FIXME: allow 3dfx drivers too if( glw_state.minidriver ) { @@ -817,20 +926,18 @@ qboolean GL_SetPixelformat( void ) stencilBits = (gl_stencilbits->integer) ? gl_stencilbits->integer : 0; // choose a pixel format - pixelFormat = GL_ChoosePFD( colorBits, alphaBits, depthBits, stencilBits ); + pixelFormat = VID_ChoosePFD( colorBits, alphaBits, depthBits, stencilBits ); if( !pixelFormat ) { // try again with default color/depth/stencil if( colorBits > 16 || depthBits > 16 || alphaBits > 0 || stencilBits > 0 ) - pixelFormat = GL_ChoosePFD( 16, 0, 16, 0 ); - else pixelFormat = GL_ChoosePFD( 32, 0, 24, 0 ); + pixelFormat = VID_ChoosePFD( 16, 0, 16, 0 ); + else pixelFormat = VID_ChoosePFD( 32, 0, 24, 0 ); if( !pixelFormat ) { MsgDev( D_ERROR, "GL_SetPixelformat: failed to find an appropriate PIXELFORMAT\n" ); - ReleaseDC( host.hWnd, glw_state.hDC ); - glw_state.hDC = NULL; return false; } } @@ -843,7 +950,7 @@ qboolean GL_SetPixelformat( void ) if( !pwglSetPixelFormat( glw_state.hDC, pixelFormat, &PFD )) { MsgDev( D_ERROR, "GL_SetPixelformat: failed\n" ); - return GL_DeleteContext(); + return false; } } else @@ -853,7 +960,7 @@ qboolean GL_SetPixelformat( void ) if( !SetPixelFormat( glw_state.hDC, pixelFormat, &PFD )) { MsgDev( D_ERROR, "GL_SetPixelformat: failed\n" ); - return GL_DeleteContext(); + return false; } } @@ -862,11 +969,6 @@ qboolean GL_SetPixelformat( void ) glConfig.depth_bits = PFD.cDepthBits; glConfig.stencil_bits = PFD.cStencilBits; - if(!( glw_state.hGLRC = pwglCreateContext( glw_state.hDC ))) - return GL_DeleteContext(); - if(!( pwglMakeCurrent( glw_state.hDC, glw_state.hGLRC ))) - return GL_DeleteContext(); - if( PFD.cStencilBits != 0 ) glState.stencilEnabled = true; else glState.stencilEnabled = false; @@ -874,127 +976,9 @@ qboolean GL_SetPixelformat( void ) // print out PFD specifics MsgDev( D_NOTE, "GL PFD: color( %d-bits ) alpha( %d-bits ) Z( %d-bit )\n", PFD.cColorBits, PFD.cAlphaBits, PFD.cDepthBits ); - // init gamma ramp - Mem_Set( glState.stateRamp, 0, sizeof( glState.stateRamp )); - - if( pwglGetDeviceGammaRamp3DFX ) - glConfig.deviceSupportsGamma = pwglGetDeviceGammaRamp3DFX( glw_state.hDC, glState.stateRamp ); - else glConfig.deviceSupportsGamma = GetDeviceGammaRamp( glw_state.hDC, glState.stateRamp ); - - // share this extension so engine can grab them - GL_SetExtension( GL_HARDWARE_GAMMA_CONTROL, glConfig.deviceSupportsGamma ); - - savedGamma = FS_LoadFile( "gamma.dat", &gamma_size ); - if( !savedGamma || gamma_size != sizeof( glState.stateRamp )) - { - // saved gamma not found or corrupted file - FS_WriteFile( "gamma.dat", glState.stateRamp, sizeof(glState.stateRamp)); - MsgDev( D_NOTE, "gamma.dat initialized\n" ); - if( savedGamma ) Mem_Free( savedGamma ); - } - else - { - GL_BuildGammaTable(); - - // validate base gamma - if( !memcmp( savedGamma, glState.stateRamp, sizeof( glState.stateRamp ))) - { - // all ok, previous gamma is valid - MsgDev( D_NOTE, "GL_SetPixelformat: validate screen gamma - ok\n" ); - } - else if( !memcmp( glState.gammaRamp, glState.stateRamp, sizeof( glState.stateRamp ))) - { - // screen gamma is equal to render gamma (probably previous instance crashed) - // run additional check to make sure it - if( memcmp( savedGamma, glState.stateRamp, sizeof( glState.stateRamp ))) - { - // yes, current gamma it's totally wrong, restore it from gamma.dat - MsgDev( D_NOTE, "GL_SetPixelformat: restore original gamma after crash\n" ); - Mem_Copy( glState.stateRamp, savedGamma, sizeof( glState.gammaRamp )); - } - else - { - // oops, savedGamma == glState.stateRamp == glState.gammaRamp - // probably r_gamma set as default - MsgDev( D_NOTE, "GL_SetPixelformat: validate screen gamma - disabled\n" ); - } - } - else if( !memcmp( glState.gammaRamp, savedGamma, sizeof( glState.stateRamp ))) - { - // saved gamma is equal render gamma, probably gamma.dat writed after crash - // run additional check to make sure it - if( memcmp( savedGamma, glState.stateRamp, sizeof( glState.stateRamp ))) - { - // yes, saved gamma it's totally wrong, get origianl gamma from screen - MsgDev( D_NOTE, "GL_SetPixelformat: merge gamma.dat after crash\n" ); - FS_WriteFile( "gamma.dat", glState.stateRamp, sizeof( glState.stateRamp )); - } - else - { - // oops, savedGamma == glState.stateRamp == glState.gammaRamp - // probably r_gamma set as default - MsgDev( D_NOTE, "GL_SetPixelformat: validate screen gamma - disabled\n" ); - } - } - else - { - // current gamma unset by other application, we can restore it here - MsgDev( D_NOTE, "GL_SetPixelformat: restore original gamma after crash\n" ); - Mem_Copy( glState.stateRamp, savedGamma, sizeof( glState.gammaRamp )); - } - Mem_Free( savedGamma ); - } - vid_gamma->modified = true; - return true; } -void VID_RestoreGamma( void ) -{ - if( !glw_state.hDC ) return; - SetDeviceGammaRamp( glw_state.hDC, glState.stateRamp ); -} - -void R_Free_OpenGL( void ) -{ - VID_RestoreGamma (); - - if( pwglMakeCurrent ) - pwglMakeCurrent( NULL, NULL ); - - if( glw_state.hGLRC ) - { - if( pwglDeleteContext ) pwglDeleteContext( glw_state.hGLRC ); - glw_state.hGLRC = NULL; - } - - if( glw_state.hDC ) - { - ReleaseDC( host.hWnd, glw_state.hDC ); - glw_state.hDC = NULL; - } - - if( host.hWnd ) - { - DestroyWindow ( host.hWnd ); - host.hWnd = NULL; - } - - UnregisterClass( "Xash Window", host.hInst ); - - if( glState.fullScreen ) - { - ChangeDisplaySettings( 0, 0 ); - glState.fullScreen = false; - } - - Sys_FreeLibrary( &opengl_dll ); - - // now all extensions are disabled - Mem_Set( glConfig.extension, 0, sizeof( glConfig.extension[0] ) * GL_EXTCOUNT ); - glw_state.initialized = false; -} - void R_SaveVideoMode( int vid_mode ) { int mode = bound( 0, vid_mode, num_vidmodes ); // check range @@ -1005,7 +989,7 @@ void R_SaveVideoMode( int vid_mode ) Cvar_FullSet( "width", va( "%i", vidmode[mode].width ), CVAR_READ_ONLY ); Cvar_FullSet( "height", va( "%i", vidmode[mode].height ), CVAR_READ_ONLY ); - Cvar_SetFloat( "r_mode", mode ); // merge if it out of bounds + Cvar_SetFloat( "vid_mode", mode ); // merge if it out of bounds MsgDev( D_NOTE, "Set: %s [%dx%d]\n", vidmode[mode].desc, vidmode[mode].width, vidmode[mode].height ); } @@ -1040,6 +1024,7 @@ qboolean VID_CreateWindow( int width, int height, qboolean fullscreen ) com.snprintf( localPath, sizeof( localPath ), "%s/game.ico", GI->gamedir ); wc.hIcon = LoadImage( NULL, localPath, IMAGE_ICON, 0, 0, LR_LOADFROMFILE|LR_DEFAULTSIZE ); + if( !wc.hIcon ) { MsgDev( D_INFO, "Extract game.ico from pak if you want to see it.\n" ); @@ -1083,6 +1068,7 @@ qboolean VID_CreateWindow( int width, int height, qboolean fullscreen ) if( Cvar_VariableInteger( "vid_mode" ) != glConfig.prev_mode ) { + // adjust window in the screen size if(( x + w > glw_state.desktopWidth ) || ( y + h > glw_state.desktopHeight )) { x = ( glw_state.desktopWidth - w ) / 2; @@ -1116,12 +1102,51 @@ qboolean VID_CreateWindow( int width, int height, qboolean fullscreen ) return false; } + if( !glw_state.initialized ) + { + if( !GL_CreateContext( )) + return false; + + VID_StartupGamma(); + } + else + { + if( !GL_UpdateContext( )) + return false; + } + SetForegroundWindow( host.hWnd ); SetFocus( host.hWnd ); return true; } +void VID_DestroyWindow( void ) +{ + if( pwglMakeCurrent ) + pwglMakeCurrent( NULL, NULL ); + + if( glw_state.hDC ) + { + ReleaseDC( host.hWnd, glw_state.hDC ); + glw_state.hDC = NULL; + } + + if( host.hWnd ) + { + DestroyWindow ( host.hWnd ); + host.hWnd = NULL; + } + + UnregisterClass( "Xash Window", host.hInst ); + + if( glState.fullScreen ) + { + ChangeDisplaySettings( 0, 0 ); + glState.fullScreen = false; + } +} + rserr_t R_ChangeDisplaySettings( int vid_mode, qboolean fullscreen ) { int width, height; @@ -1140,7 +1165,7 @@ rserr_t R_ChangeDisplaySettings( int vid_mode, qboolean fullscreen ) ReleaseDC( GetDesktopWindow(), hDC ); // destroy the existing window - if( host.hWnd ) R_Free_OpenGL(); + if( host.hWnd ) VID_DestroyWindow(); // do a CDS if needed if( fullscreen ) @@ -1208,10 +1233,12 @@ rserr_t R_ChangeDisplaySettings( int vid_mode, qboolean fullscreen ) /* ================== -R_Init_OpenGL +VID_SetMode + +Set the described video mode ================== */ -qboolean R_Init_OpenGL( void ) +qboolean VID_SetMode( void ) { rserr_t err; qboolean fullscreen; @@ -1230,27 +1257,85 @@ qboolean R_Init_OpenGL( void ) { Cvar_SetFloat( "fullscreen", 0 ); vid_fullscreen->modified = false; - MsgDev( D_ERROR, "R_SetMode: fullscreen unavailable in this mode\n" ); + MsgDev( D_ERROR, "VID_SetMode: fullscreen unavailable in this mode\n" ); if(( err = R_ChangeDisplaySettings( vid_mode->integer, false )) == rserr_ok ) return true; } else if( err == rserr_invalid_mode ) { Cvar_SetFloat( "vid_mode", glConfig.prev_mode ); + MsgDev( D_ERROR, "VID_SetMode: invalid mode\n" ); vid_mode->modified = false; - MsgDev( D_ERROR, "R_SetMode: invalid mode\n" ); } // try setting it back to something safe if(( err = R_ChangeDisplaySettings( glConfig.prev_mode, false )) != rserr_ok ) { - MsgDev( D_ERROR, "R_SetMode: could not revert to safe mode\n" ); + MsgDev( D_ERROR, "VID_SetMode: could not revert to safe mode\n" ); return false; } } return true; } +/* +================== +VID_CheckChanges + +check vid modes and fullscreen +================== +*/ +void VID_CheckChanges( void ) +{ + if( vid_fullscreen->modified || vid_mode->modified ) + { + if( !VID_SetMode()) + { + // can't initialize video subsystem + Sys_NewInstance( va("#%s", GI->gamefolder ), "fallback to dedicated mode\n" ); + } + else + { + vid_fullscreen->modified = false; + vid_mode->modified = false; + SCR_VidInit(); // tell the client.dll what vid_mode has changed + } + } +} + +/* +================== +R_Init_OpenGL +================== +*/ +qboolean R_Init_OpenGL( void ) +{ + Sys_LoadLibrary( NULL, &opengl_dll ); // load opengl32.dll + if( !opengl_dll.link ) return false; + + glw_state.minidriver = false; // FIXME: allow 3dfx drivers too + + return VID_SetMode(); +} + +/* +================== +R_Free_OpenGL +================== +*/ +void R_Free_OpenGL( void ) +{ + VID_RestoreGamma (); + + VID_DestroyWindow (); + + Sys_FreeLibrary( &opengl_dll ); + + // now all extensions are disabled + Mem_Set( glConfig.extension, 0, sizeof( glConfig.extension[0] ) * GL_EXTCOUNT ); + glw_state.initialized = false; +} + /* =============== GL_SetDefaults @@ -1409,8 +1494,8 @@ void GL_InitCommands( void ) gl_swapInterval->modified = true; vid_gamma = Cvar_Get( "vid_gamma", "1.0", CVAR_ARCHIVE, "gamma amount" ); - vid_mode = Cvar_Get( "vid_mode", VID_DEFAULTMODE, CVAR_RENDERINFO, "display resolution mode" ); - vid_fullscreen = Cvar_Get( "fullscreen", "0", CVAR_RENDERINFO|CVAR_LATCH_VIDEO, "set in 1 to enable fullscreen mode" ); + vid_mode = Cvar_Get( "vid_mode", VID_DEFAULTMODE, CVAR_ARCHIVE, "display resolution mode" ); + vid_fullscreen = Cvar_Get( "fullscreen", "0", CVAR_RENDERINFO, "set in 1 to enable fullscreen mode" ); vid_displayfrequency = Cvar_Get ( "vid_displayfrequency", "0", CVAR_RENDERINFO|CVAR_LATCH_VIDEO, "fullscreen refresh rate" ); Cmd_AddCommand( "r_info", R_RenderInfo_f, "display renderer info" ); @@ -1578,6 +1663,8 @@ void GL_InitExtensions( void ) Image_Init( NULL, flags ); glw_state.initialized = true; + + tr.framecount = tr.visframecount = 1; } /* @@ -1587,7 +1674,11 @@ R_Init */ qboolean R_Init( void ) { - if( glw_state.initialized ) return true; + if( glw_state.initialized ) + return true; + + // give initial openGL configuration + Cbuf_AddText( "exec opengl.cfg\n" ); GL_InitCommands(); GL_SetDefaultState(); @@ -1597,6 +1688,9 @@ qboolean R_Init( void ) { GL_RemoveCommands(); R_Free_OpenGL(); + + // can't initialize video subsystem + Sys_NewInstance( va("#%s", GI->gamefolder ), "fallback to dedicated mode\n" ); return false; } @@ -1610,6 +1704,9 @@ qboolean R_Init( void ) R_StudioInit(); R_ClearScene(); + // initialize screen + SCR_Init(); + GL_CheckForErrors(); return true; @@ -1622,9 +1719,21 @@ R_Shutdown */ void R_Shutdown( void ) { + int i; + if( !glw_state.initialized ) return; + // release SpriteTextures + for( i = 1; i < MAX_IMAGES; i++ ) + { + if( !clgame.sprites[i].name[0] ) continue; + Mod_UnloadSpriteModel( &clgame.sprites[i] ); + } + + Mem_Set( clgame.sprites, 0, sizeof( clgame.sprites )); + Mod_ClearAll(); + GL_RemoveCommands(); R_ShutdownImages(); @@ -1634,7 +1743,6 @@ void R_Shutdown( void ) R_Free_OpenGL(); } - /* ================= GL_CheckForErrors diff --git a/engine/client/sound/s_backend.c b/engine/client/sound/s_backend.c index 5b518fde..4be37103 100644 --- a/engine/client/sound/s_backend.c +++ b/engine/client/sound/s_backend.c @@ -7,7 +7,7 @@ #include "common.h" #include "sound.h" -#define iDirectSoundCreate( a, b, c ) pDirectSoundCreate( a, b, c ) +#define iDirectSoundCreate( a, b, c ) pDirectSoundCreate( a, b, c ) static HRESULT ( _stdcall *pDirectSoundCreate)(GUID* lpGUID, LPDIRECTSOUND* lplpDS, IUnknown* pUnkOuter ); @@ -20,11 +20,6 @@ static dllfunc_t dsound_funcs[] = dll_info_t dsound_dll = { "dsound.dll", dsound_funcs, NULL, NULL, NULL, false, 0, 0 }; #define SAMPLE_16BIT_SHIFT 1 - -// 64K is > 1 second at 16-bit, 22050 Hz -#define WAV_BUFFERS 64 -#define WAV_MASK 0x3F -#define WAV_BUFFER_SIZE 0x0400 #define SECONDARY_BUFFER_SIZE 0x10000 typedef enum @@ -34,16 +29,11 @@ typedef enum SIS_NOTAVAIL } si_state_t; -convar_t *s_wavonly; +convar_t *s_primary; static HWND snd_hwnd; -static qboolean dsound_init; -static qboolean wav_init; static qboolean snd_firsttime = true; -static qboolean snd_isdirect, snd_iswave; static qboolean primary_format_set; -static int snd_buffer_count = 0; -static int snd_sent, snd_completed; /* ======================================================================= @@ -52,19 +42,14 @@ so it can unlock and free the data block after it has been played. ======================================================================= */ DWORD locksize; -HANDLE hData; HPSTR lpData, lpData2; -HGLOBAL hWaveHdr; LPWAVEHDR lpWaveHdr; -HWAVEOUT hWaveOut; -WAVEOUTCAPS wavecaps; DWORD gSndBufSize; MMTIME mmstarttime; LPDIRECTSOUNDBUFFER pDSBuf, pDSPBuf; LPDIRECTSOUND pDS; qboolean SNDDMA_InitDirect( void *hInst ); -qboolean SNDDMA_InitWav( void ); void SNDDMA_FreeSound( void ); static const char *DSoundError( int error ) @@ -272,8 +257,6 @@ SNDDMA_FreeSound */ void SNDDMA_FreeSound( void ) { - int i; - if( pDS ) { DS_DestroyBuffers(); @@ -281,42 +264,11 @@ void SNDDMA_FreeSound( void ) Sys_FreeLibrary( &dsound_dll ); } - if( hWaveOut ) - { - waveOutReset( hWaveOut ); - - if( lpWaveHdr ) - { - for( i = 0; i < WAV_BUFFERS; i++ ) - waveOutUnprepareHeader( hWaveOut, lpWaveHdr + i, sizeof( WAVEHDR )); - } - - waveOutClose( hWaveOut ); - - if( hWaveHdr ) - { - GlobalUnlock( hWaveHdr ); - GlobalFree( hWaveHdr ); - } - - if( hData ) - { - GlobalUnlock( hData ); - GlobalFree( hData ); - } - - } - pDS = NULL; pDSBuf = NULL; pDSPBuf = NULL; - hWaveOut = 0; - hData = 0; - hWaveHdr = 0; lpData = NULL; lpWaveHdr = NULL; - dsound_init = false; - wav_init = false; } /* @@ -366,113 +318,6 @@ si_state_t SNDDMA_InitDirect( void *hInst ) if( !DS_CreateBuffers( hInst )) return SIS_FAILURE; - dsound_init = true; - - return SIS_SUCCESS; -} - - -/* -================== -SNDDM_InitWav - -Crappy windows multimedia base -================== -*/ -si_state_t SNDDMA_InitWav( void ) -{ - WAVEFORMATEX format; - HRESULT hr; - int i; - - snd_sent = 0; - snd_completed = 0; - - Mem_Set( &format, 0, sizeof( format )); - format.wFormatTag = WAVE_FORMAT_PCM; - format.nChannels = 2; - format.wBitsPerSample = 16; - format.nSamplesPerSec = SOUND_DMA_SPEED; - format.nBlockAlign = format.nChannels * format.wBitsPerSample / 8; - format.nAvgBytesPerSec = format.nSamplesPerSec * format.nBlockAlign; - format.cbSize = 0; - - // open a waveform device for output using window callback. - MsgDev( D_NOTE, "SNDDMA_InitWav: initializing wave sound " ); - if(( hr = waveOutOpen((LPHWAVEOUT)&hWaveOut, WAVE_MAPPER, &format, 0, 0, CALLBACK_NULL)) != MMSYSERR_NOERROR ) - { - if( hr != MMSYSERR_ALLOCATED ) - { - MsgDev( D_NOTE, "- failed\n" ); - return SIS_FAILURE; - } - - MsgDev( D_NOTE, "- failed, hardware already in use\n" ); - return SIS_NOTAVAIL; - } - - MsgDev( D_NOTE, "- ok\n" ); - - // allocate and lock memory for the waveform data. The memory - // for waveform data must be globally allocated with - // GMEM_MOVEABLE and GMEM_SHARE flags. - - gSndBufSize = WAV_BUFFERS * WAV_BUFFER_SIZE; - hData = GlobalAlloc( GMEM_MOVEABLE|GMEM_SHARE, gSndBufSize ); - if( !hData ) - { - SNDDMA_FreeSound(); - return SIS_FAILURE; - } - - lpData = GlobalLock( hData ); - if( !lpData ) - { - SNDDMA_FreeSound (); - return SIS_FAILURE; - } - - Mem_Set( lpData, 0, gSndBufSize ); - - // Allocate and lock memory for the header. This memory must - // also be globally allocated with GMEM_MOVEABLE and - // GMEM_SHARE flags. - hWaveHdr = GlobalAlloc( GMEM_MOVEABLE|GMEM_SHARE, (DWORD)sizeof( WAVEHDR ) * WAV_BUFFERS ); - - if( hWaveHdr == NULL ) - { - SNDDMA_FreeSound (); - return SIS_FAILURE; - } - - lpWaveHdr = (LPWAVEHDR)GlobalLock( hWaveHdr ); - - if( lpWaveHdr == NULL ) - { - SNDDMA_FreeSound(); - return SIS_FAILURE; - } - - Mem_Set( lpWaveHdr, 0, sizeof( WAVEHDR ) * WAV_BUFFERS ); - - // After allocation, set up and prepare headers. - for( i = 0; i < WAV_BUFFERS; i++ ) - { - lpWaveHdr[i].dwBufferLength = WAV_BUFFER_SIZE; - lpWaveHdr[i].lpData = lpData + i * WAV_BUFFER_SIZE; - - if( waveOutPrepareHeader( hWaveOut, lpWaveHdr+i, sizeof( WAVEHDR )) != MMSYSERR_NOERROR ) - { - SNDDMA_FreeSound(); - return SIS_FAILURE; - } - } - - dma.samplepos = 0; - dma.samples = gSndBufSize / 2; - dma.buffer = (byte *)lpData; - wav_init = true; - return SIS_SUCCESS; } @@ -493,50 +338,17 @@ int SNDDMA_Init( void *hInst ) Mem_Set( &dma, 0, sizeof( dma )); - s_wavonly = Cvar_Get( "s_wavonly", "0", CVAR_LATCH_AUDIO|CVAR_ARCHIVE, "force to use WaveOutput only" ); - dsound_init = wav_init = 0; + s_primary = Cvar_Get( "s_primary", "0", CVAR_INIT, "use direct primary buffer" ); // init DirectSound - if( !s_wavonly->integer ) + stat = SNDDMA_InitDirect( hInst ); + + if( stat == SIS_SUCCESS ) { - if( snd_firsttime || snd_isdirect ) - { - stat = SNDDMA_InitDirect( hInst ); - - if( stat == SIS_SUCCESS ) - { - snd_isdirect = true; - - if( snd_firsttime ) - MsgDev( D_INFO, "Audio: DirectSound\n" ); - } - else snd_isdirect = false; - } + if( snd_firsttime ) + MsgDev( D_INFO, "Audio: DirectSound\n" ); } - - // if DirectSound didn't succeed in initializing, try to initialize - // waveOut sound, unless DirectSound failed because the hardware is - // already allocated (in which case the user has already chosen not - // to have sound) - if( !dsound_init && ( stat != SIS_NOTAVAIL )) - { - if( snd_firsttime || snd_iswave ) - { - stat = SNDDMA_InitWav(); - - if( stat == SIS_SUCCESS ) - { - snd_iswave = true; - if( snd_firsttime ) - MsgDev( D_INFO, "Audio: WaveOutput\n" ); - } - else snd_iswave = false; - } - } - - snd_buffer_count = 1; - - if( !dsound_init && !wav_init ) + else { if( snd_firsttime ) MsgDev( D_ERROR, "SNDDMA_Init: can't initialize sound device\n" ); @@ -560,21 +372,12 @@ how many sample are required to fill it up. int SNDDMA_GetDMAPos( void ) { int s; - - if( dsound_init ) - { - MMTIME mmtime; - DWORD dwWrite; + MMTIME mmtime; + DWORD dwWrite; - mmtime.wType = TIME_SAMPLES; - pDSBuf->lpVtbl->GetCurrentPosition( pDSBuf, &mmtime.u.sample, &dwWrite ); - s = mmtime.u.sample - mmstarttime.u.sample; - } - else if( wav_init ) - { - s = snd_sent * WAV_BUFFER_SIZE; - } - + mmtime.wType = TIME_SAMPLES; + pDSBuf->lpVtbl->GetCurrentPosition( pDSBuf, &mmtime.u.sample, &dwWrite ); + s = mmtime.u.sample - mmstarttime.u.sample; s >>= SAMPLE_16BIT_SHIFT; s &= (dma.samples - 1); @@ -674,49 +477,9 @@ Also unlocks the dsound buffer */ void SNDDMA_Submit( void ) { - LPWAVEHDR h; - int wResult; - - if( !dma.buffer ) - return; - + if( !dma.buffer ) return; // unlock the dsound buffer if( pDSBuf ) pDSBuf->lpVtbl->Unlock( pDSBuf, dma.buffer, locksize, NULL, 0 ); - - if( !wav_init ) return; - - // find which sound blocks have completed - while( 1 ) - { - if( snd_completed == snd_sent ) - break; - - if(!( lpWaveHdr[snd_completed & WAV_MASK].dwFlags & WHDR_DONE )) - break; - snd_completed++; // this buffer has been played - } - - // submit a few new sound blocks - while((( snd_sent - snd_completed ) >> SAMPLE_16BIT_SHIFT ) < 8 ) - { - h = lpWaveHdr + ( snd_sent & WAV_MASK ); - - if( paintedtime / 256 <= snd_sent ) - break; - snd_sent++; - - // Now the data block can be sent to the output device. The - // waveOutWrite function returns immediately and waveform - // data is sent to the output device in the background. - wResult = waveOutWrite( hWaveOut, h, sizeof( WAVEHDR )); - - if( wResult != MMSYSERR_NOERROR ) - { - MsgDev( D_ERROR, "SNDDMA_Submit: failed to write block to device\n" ); - SNDDMA_FreeSound (); - return; - } - } } /* @@ -740,8 +503,7 @@ S_PrintDeviceName */ void S_PrintDeviceName( void ) { - if( snd_isdirect ) Msg( "Audio: DirectSound\n" ); - if( snd_iswave ) Msg( "Audio: WaveOutput\n" ); + Msg( "Audio: DirectSound\n" ); } /* @@ -758,16 +520,10 @@ void S_Activate( qboolean active, void *hInst ) if( !dma.initialized ) return; snd_hwnd = (HWND)hInst; + if( !pDS || !snd_hwnd ) + return; + if( active ) - { - if( pDS && snd_hwnd && snd_isdirect ) - DS_CreateBuffers( snd_hwnd ); - } - else - { - if( pDS && snd_hwnd && snd_isdirect ) - DS_DestroyBuffers(); - else if( snd_iswave ) - waveOutReset( hWaveOut ); - } + DS_CreateBuffers( snd_hwnd ); + else DS_DestroyBuffers(); } \ No newline at end of file diff --git a/engine/client/sound/s_main.c b/engine/client/sound/s_main.c index 1ccbeece..0e2bff21 100644 --- a/engine/client/sound/s_main.c +++ b/engine/client/sound/s_main.c @@ -924,10 +924,13 @@ void S_SoundInfo_f( void ) S_Init ================ */ -qboolean S_Init( void *hInst ) +qboolean S_Init( void ) { if( FS_CheckParm( "-nosound" )) + { + MsgDev( D_INFO, "Audio: Disabled\n" ); return false; + } Cmd_ExecuteString( "sndlatch\n" ); @@ -935,7 +938,6 @@ qboolean S_Init( void *hInst ) s_musicvolume = Cvar_Get( "musicvolume", "1.0", CVAR_ARCHIVE, "background music volume" ); s_mixahead = Cvar_Get( "_snd_mixahead", "0.1", CVAR_ARCHIVE, "how much sound to mix ahead of time" ); s_show = Cvar_Get( "s_show", "0", 0, "show playing sounds" ); - s_primary = Cvar_Get( "s_primary", "0", CVAR_LATCH_AUDIO|CVAR_ARCHIVE, "use direct primary buffer" ); s_check_errors = Cvar_Get( "s_check_errors", "1", CVAR_ARCHIVE, "ignore audio engine errors" ); s_lerping = Cvar_Get( "s_lerping", "0", CVAR_ARCHIVE, "apply interpolation to sound output" ); dsp_off = Cvar_Get( "dsp_off", "0", CVAR_ARCHIVE, "set to 1 to disable all dsp processing" ); @@ -946,7 +948,7 @@ qboolean S_Init( void *hInst ) Cmd_AddCommand( "soundlist", S_SoundList_f, "display loaded sounds" ); Cmd_AddCommand( "s_info", S_SoundInfo_f, "print sound system information" ); - if( !SNDDMA_Init( hInst )) + if( !SNDDMA_Init( host.hWnd )) { MsgDev( D_INFO, "S_Init: sound system can't be initialized\n" ); return false; diff --git a/engine/client/sound/sound.h b/engine/client/sound/sound.h index bcef42d0..59dc803d 100644 --- a/engine/client/sound/sound.h +++ b/engine/client/sound/sound.h @@ -194,7 +194,6 @@ extern convar_t *s_volume; extern convar_t *s_musicvolume; extern convar_t *s_show; extern convar_t *s_mixahead; -extern convar_t *s_primary; extern convar_t *s_lerping; extern convar_t *dsp_off; @@ -233,7 +232,7 @@ void DSP_Process( int idsp, portable_samplepair_t *pbfront, int sampleCount ); float DSP_GetGain( int idsp ); void DSP_ClearState( void ); -qboolean S_Init( void *hInst ); +qboolean S_Init( void ); void S_Shutdown( void ); void S_Activate( qboolean active, void *hInst ); void S_SoundList_f( void ); diff --git a/engine/common/cm_local.h b/engine/common/cm_local.h index a9333008..2b2cd436 100644 --- a/engine/common/cm_local.h +++ b/engine/common/cm_local.h @@ -71,6 +71,7 @@ extern model_t *loadmodel; // model.c // void Mod_Init( void ); +void Mod_ClearAll( void ); void Mod_Shutdown( void ); void Mod_SetupHulls( float mins[4][3], float maxs[4][3] ); void Mod_GetBounds( int handle, vec3_t mins, vec3_t maxs ); diff --git a/engine/common/com_export.h b/engine/common/com_export.h index 6089e421..cbba1642 100644 --- a/engine/common/com_export.h +++ b/engine/common/com_export.h @@ -56,6 +56,7 @@ typedef struct qboolean R_Init( void ); void R_Shutdown( void ); +void VID_CheckChanges( void ); int GL_LoadTexture( const char *name, const byte *buf, size_t size, int flags ); void GL_FreeImage( const char *name ); qboolean VID_ScreenShot( const char *filename, int shot_type ); diff --git a/engine/common/common.h b/engine/common/common.h index 7b3fee5a..c2c0356f 100644 --- a/engine/common/common.h +++ b/engine/common/common.h @@ -164,7 +164,6 @@ void Host_WriteOpenGLConfig( void ); void Host_WriteConfig( void ); qboolean Host_IsLocalGame( void ); void Host_ShutdownServer( void ); -void Host_CheckChanges( void ); void Host_Print( const char *txt ); void Host_Error( const char *error, ... ); void Host_Credits( void ); @@ -299,8 +298,6 @@ void CL_SendCmd( void ); void CL_Disconnect( void ); qboolean CL_NextDemo( void ); void CL_Drop( void ); -void CL_ForceVid( void ); -void CL_ForceSnd( void ); void SCR_Init( void ); void SCR_UpdateScreen( void ); void SCR_BeginLoadingPlaque( void ); @@ -333,7 +330,7 @@ typedef struct autocomplete_list_s extern autocomplete_list_t cmd_list[]; // soundlib shared exports -qboolean S_Init( void *hInst ); +qboolean S_Init( void ); void S_Shutdown( void ); void S_Activate( qboolean active, void *hInst ); void S_StopSound( int entnum, int channel, const char *soundname ); diff --git a/engine/common/host.c b/engine/common/host.c index dfefd0b2..f05660e1 100644 --- a/engine/common/host.c +++ b/engine/common/host.c @@ -96,69 +96,6 @@ void Host_EndGame( const char *message, ... ) Host_AbortCurrentFrame (); } -void Host_CheckChanges( void ) -{ - qboolean audio_disabled = false; - - if( FS_CheckParm( "-nosound" )) - { - if( host.state == HOST_INIT ) - audio_disabled = true; - sound_restart = false; - } - - if( video_restart || sound_restart ) - { - if( video_restart ) CL_ForceVid(); - if( sound_restart ) CL_ForceSnd(); - } - else - { - return; - } - - if( video_restart && CL_Active( )) - { - // we're in game and want keep decals when renderer is changed - host.decalList = (decallist_t *)Z_Malloc( sizeof( decallist_t ) * MAX_RENDER_DECALS ); - host.numdecals = R_CreateDecalList( host.decalList, false ); - Msg( "Total stored %i decals\n", host.numdecals ); - } - - if(( video_restart || sound_restart ) && CL_Active( )) - { - host.soundList = (soundlist_t *)Z_Malloc( sizeof( soundlist_t ) * 128 ); - host.numsounds = S_GetCurrentStaticSounds( host.soundList, 128, CHAN_STATIC ); - Msg( "Total stored %i sounds\n", host.numsounds ); - } - - S_StopAllSounds(); // don't let them loop during the restart - - // restart renderer - if( video_restart ) - { - R_Shutdown(); - - if( !R_Init( )) - { - Sys_NewInstance( va("#%s", GI->gamefolder ), "fallback to dedicated mode\n" ); - return; - } - else SCR_Init (); - video_restart = false; - } - - if( audio_disabled ) MsgDev( D_INFO, "Audio: Disabled\n" ); - - // restart sound engine - if( sound_restart ) - { - S_Shutdown(); - S_Init( host.hWnd ); - sound_restart = false; - } -} - /* ================ Host_AbortCurrentFrame diff --git a/engine/common/input.c b/engine/common/input.c index c318ac2c..c61f292c 100644 --- a/engine/common/input.c +++ b/engine/common/input.c @@ -431,6 +431,7 @@ main window procedure long IN_WndProc( void *hWnd, uint uMsg, uint wParam, long lParam ) { int i, temp = 0; + qboolean fActivate; if( uMsg == in_mouse_wheel ) uMsg = WM_MOUSEWHEEL; @@ -465,14 +466,19 @@ long IN_WndProc( void *hWnd, uint uMsg, uint wParam, long lParam ) Cbuf_ExecuteText( EXEC_APPEND, "quit" ); break; case WM_ACTIVATE: - if( HIWORD( wParam )) - host.state = HOST_SLEEP; - else if( LOWORD( wParam ) == WA_INACTIVE ) - host.state = HOST_NOFOCUS; - else host.state = HOST_FRAME; + if( host.state != HOST_RESTART ) + { + if( HIWORD( wParam )) + host.state = HOST_SLEEP; + else if( LOWORD( wParam ) == WA_INACTIVE ) + host.state = HOST_NOFOCUS; + else host.state = HOST_FRAME; + fActivate = (host.state == HOST_FRAME) ? true : false; + } + else fActivate = true; // video sucessfully restarted wnd_caption = GetSystemMetrics( SM_CYCAPTION ) + WND_BORDER; - S_Activate(( host.state == HOST_FRAME ) ? true : false, host.hWnd ); + S_Activate( fActivate, host.hWnd ); Key_ClearStates(); // FIXME!!! if( host.state == HOST_FRAME ) @@ -480,7 +486,7 @@ long IN_WndProc( void *hWnd, uint uMsg, uint wParam, long lParam ) SetForegroundWindow( hWnd ); ShowWindow( hWnd, SW_RESTORE ); } - else if( scr_fullscreen->integer ) + else if( scr_fullscreen->integer && host.state != HOST_RESTART ) { ShowWindow( hWnd, SW_MINIMIZE ); } diff --git a/engine/common/model.c b/engine/common/model.c index 18a8024f..00531e2c 100644 --- a/engine/common/model.c +++ b/engine/common/model.c @@ -379,13 +379,20 @@ void Mod_Init( void ) com_studiocache = Mem_AllocPool( "Studio Cache" ); } -void Mod_Shutdown( void ) +void Mod_ClearAll( void ) { int i; for( i = 0; i < cm_nummodels; i++ ) Mod_FreeModel( &cm_models[i] ); + Mem_Set( cm_models, 0, sizeof( cm_models )); + cm_nummodels = 0; +} + +void Mod_Shutdown( void ) +{ + Mod_ClearAll(); Mem_FreePool( &com_studiocache ); } diff --git a/engine/server/sv_cmds.c b/engine/server/sv_cmds.c index f3cdd48f..e1a2bf95 100644 --- a/engine/server/sv_cmds.c +++ b/engine/server/sv_cmds.c @@ -148,15 +148,13 @@ qboolean SV_SetPlayer( void ) sv_client_t *cl; int i, idnum; - if( sv_maxclients->integer == 1 ) + if( sv_maxclients->integer == 1 || Cmd_Argc() < 2 ) { - // sepcial case for singleplayer + // sepcial case for local client sv_client = svs.clients; return true; } - if( Cmd_Argc() < 2 ) return false; - s = Cmd_Argv( 1 ); // numeric values are just slot numbers diff --git a/engine/server/sv_studio.c b/engine/server/sv_studio.c index 881f3ef8..4fac7889 100644 --- a/engine/server/sv_studio.c +++ b/engine/server/sv_studio.c @@ -824,6 +824,8 @@ static qboolean SV_StudioIntersect( edict_t *ent, const vec3_t start, vec3_t min vec3_t anim_mins, anim_maxs; model_t *mod = CM_ClipHandleToModel( ent->v.modelindex ); + if( !mod ) return false; // FIXME: Xash 0.45 crash at this point (model == NULL) + // create the bounding box of the entire move World_MoveBounds( start, mins, maxs, end, trace_mins, trace_maxs ); diff --git a/engine/server/sv_world.c b/engine/server/sv_world.c index beb57326..9110b508 100644 --- a/engine/server/sv_world.c +++ b/engine/server/sv_world.c @@ -175,6 +175,14 @@ hull_t *SV_HullForEntity( edict_t *ent, int hullNumber, vec3_t mins, vec3_t maxs } #endif } + else + { + // TraceHull stuff + hull = &model->hulls[hullNumber]; + + // calculate an offset value to center the origin + VectorSubtract( hull->clip_mins, mins, offset ); + } VectorAdd( offset, ent->v.origin, offset ); } else diff --git a/launch/filesystem.c b/launch/filesystem.c index f3067590..c06b0c0a 100644 --- a/launch/filesystem.c +++ b/launch/filesystem.c @@ -1165,7 +1165,9 @@ static qboolean FS_ParseLiblistGam( const char *filename, const char *gamedir, g } else if( !com.stricmp( token.string, "gamedll" )) { - PS_GetString( script, false, GameInfo->game_dll, sizeof( GameInfo->game_dll )); + PS_ReadToken( script, false, &token ); + if( !com.strstr( token.string, ".." )) // don't use indirect paths (..\valve\dlls\hl.dll) + com.strncpy( GameInfo->game_dll, token.string, sizeof( GameInfo->game_dll )); } else if( !com.stricmp( token.string, "type" )) { diff --git a/mainui/menu_vidmodes.cpp b/mainui/menu_vidmodes.cpp index c4e5b252..c21cc911 100644 --- a/mainui/menu_vidmodes.cpp +++ b/mainui/menu_vidmodes.cpp @@ -39,8 +39,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. static const char *uiVideoModes[] = { - "400 x 300", - "512 x 384", "640 x 480", "800 x 600", "960 x 720", @@ -109,7 +107,7 @@ static void UI_VidModes_GetConfig( void ) uiVidModes.videoModesPtr[i] = NULL; // terminator uiVidModes.vidList.itemNames = uiVidModes.videoModesPtr; - uiVidModes.vidList.curItem = CVAR_GET_FLOAT( "r_mode" ); + uiVidModes.vidList.curItem = CVAR_GET_FLOAT( "vid_mode" ); if( !CVAR_GET_FLOAT( "fullscreen" )) uiVidModes.windowed.enabled = 1; @@ -125,7 +123,7 @@ UI_VidModes_SetConfig */ static void UI_VidOptions_SetConfig( void ) { - CVAR_SET_FLOAT( "r_mode", uiVidModes.vidList.curItem ); + CVAR_SET_FLOAT( "vid_mode", uiVidModes.vidList.curItem ); CVAR_SET_FLOAT( "fullscreen", !uiVidModes.windowed.enabled ); CVAR_SET_FLOAT( "r_allow_software", uiVidModes.software.enabled );