diff --git a/engine/client/cl_cmds.c b/engine/client/cl_cmds.c index 1a78b6bd..0c7ec45b 100644 --- a/engine/client/cl_cmds.c +++ b/engine/client/cl_cmds.c @@ -322,16 +322,29 @@ splash logo while map is loading void CL_LevelShot_f( void ) { size_t ft1, ft2; + string filename; if( cls.scrshot_request != scrshot_plaque ) return; cls.scrshot_request = scrshot_inactive; // check for exist - Q_sprintf( cls.shotname, "levelshots/%s_%s.bmp", clgame.mapname, glState.wideScreen ? "16x9" : "4x3" ); + if( cls.demoplayback && ( cls.demonum != -1 )) + { + Q_sprintf( cls.shotname, "levelshots/%s_%s.bmp", cls.demoname, glState.wideScreen ? "16x9" : "4x3" ); + Q_snprintf( filename, sizeof( filename ), "demos/%s.dem", cls.demoname ); - // make sure what entity patch is never than bsp - ft1 = FS_FileTime( cl.worldmodel->name, false ); - ft2 = FS_FileTime( cls.shotname, true ); + // make sure what levelshot is newer than demo + ft1 = FS_FileTime( filename, false ); + ft2 = FS_FileTime( cls.shotname, true ); + } + else + { + Q_sprintf( cls.shotname, "levelshots/%s_%s.bmp", clgame.mapname, glState.wideScreen ? "16x9" : "4x3" ); + + // make sure what levelshot is newer than bsp + ft1 = FS_FileTime( cl.worldmodel->name, false ); + ft2 = FS_FileTime( cls.shotname, true ); + } // missing levelshot or level never than levelshot if( ft2 == -1 || ft1 > ft2 ) diff --git a/engine/client/cl_demo.c b/engine/client/cl_demo.c index 21309527..2a08f1a2 100644 --- a/engine/client/cl_demo.c +++ b/engine/client/cl_demo.c @@ -41,26 +41,25 @@ const char *demo_cmd[dem_lastcmd+1] = "dem_userdata", "dem_usercmd", "dem_stop", - }; typedef struct { - int id; // should be IDEM - int dem_protocol; // should be DEMO_PROTOCOL - int net_protocol; // should be PROTOCOL_VERSION - char mapname[64]; // name of map - char gamedir[64]; // name of game directory (FS_Gamedir()) - int directory_offset; // offset of Entry Directory. + int id; // should be IDEM + int dem_protocol; // should be DEMO_PROTOCOL + int net_protocol; // should be PROTOCOL_VERSION + char mapname[64]; // name of map + char gamedir[64]; // name of game directory (FS_Gamedir()) + int directory_offset; // offset of Entry Directory. } demoheader_t; typedef struct { - int entrytype; // DEMO_STARTUP or DEMO_NORMAL - float playback_time; // time of track - int playback_frames; // # of frames in track - int offset; // file offset of track data - int length; // length of track + int entrytype; // DEMO_STARTUP or DEMO_NORMAL + float playback_time; // time of track + int playback_frames; // # of frames in track + int offset; // file offset of track data + int length; // length of track } demoentry_t; typedef struct @@ -123,11 +122,25 @@ void CL_CloseDemoHeader( void ) FS_Close( cls.demoheader ); } +/* +==================== +CL_GetDemoRecordClock + +write time while demo is recording +==================== +*/ float CL_GetDemoRecordClock( void ) { return cl.mtime[0]; } +/* +==================== +CL_GetDemoPlaybackClock + +overwrite host.realtime +==================== +*/ float CL_GetDemoPlaybackClock( void ) { return host.realtime + host.frametime; @@ -164,7 +177,8 @@ Update level time on a next level */ void CL_WriteDemoJumpTime( void ) { - if( cls.demowaiting || !cls.demofile ) return; + if( cls.demowaiting || !cls.demofile ) + return; demo.starttime = CL_GetDemoRecordClock(); // setup the demo starttime @@ -234,9 +248,9 @@ Dumps the current net message, prefixed by the length */ void CL_WriteDemoMessage( qboolean startup, int start, sizebuf_t *msg ) { - byte c; - int swlen; file_t *file = startup ? cls.demoheader : cls.demofile; + int swlen; + byte c; if( !file ) return; @@ -249,6 +263,7 @@ void CL_WriteDemoMessage( qboolean startup, int start, sizebuf_t *msg ) if( !startup ) { + cls.demotime += host.frametime; demo.framecount++; } @@ -261,7 +276,7 @@ void CL_WriteDemoMessage( qboolean startup, int start, sizebuf_t *msg ) // write the length out. FS_Write( file, &swlen, sizeof( int )); - // output the buffer. Skip the network packet stuff. + // output the buffer. Skip the network packet stuff. FS_Write( file, BF_GetData( msg ) + start, swlen ); } @@ -304,6 +319,7 @@ void CL_WriteDemoHeader( const char *name ) MsgDev( D_INFO, "recording to %s.\n", name ); cls.demofile = FS_Open( name, "wb", false ); + cls.demotime = 0.0; if( !cls.demofile ) { @@ -422,7 +438,8 @@ void CL_StopRecord( void ) menu.globals->demoname[0] = '\0'; Msg( "Completed demo\n" ); - MsgDev( D_INFO, "Recording time %.2f\n", stoptime - demo.realstarttime ); + MsgDev( D_INFO, "Recording time %.2f\n", cls.demotime ); + cls.demotime = 0.0; } /* @@ -667,7 +684,7 @@ qboolean CL_DemoReadMessage( byte *buffer, size_t *length ) if( !cls.netchan.remote_address.type ) cls.netchan.remote_address.type = NA_LOOPBACK; - if( cl.refdef.paused || cls.key_dest != key_game ) + if(( !cl.background && ( cl.refdef.paused || cls.key_dest != key_game )) || cls.key_dest == key_console ) { demo.starttime += host.frametime; return false; // paused @@ -752,23 +769,6 @@ qboolean CL_DemoReadMessage( byte *buffer, size_t *length ) return CL_ReadRawNetworkData( buffer, length ); } -/* -================= -CL_ReadDemoMessage - -obsolete -================= -*/ -void CL_ReadDemoMessage( void ) -{ - if( cl.refdef.paused || cls.key_dest != key_game ) - return; - - // don't need another message yet - if(( cl.time + host.frametime ) <= cl.mtime[0] ) - return; -} - /* ============== CL_StopPlayback @@ -799,8 +799,10 @@ void CL_StopPlayback( void ) if( !cls.changedemo ) { - // let game known about movie state + // let game known about demo state + Cvar_FullSet( "cl_background", "0", CVAR_READ_ONLY ); cls.state = ca_disconnected; + cl.background = 0; cls.demonum = -1; } } @@ -887,7 +889,6 @@ qboolean CL_NextDemo( void ) if( cls.demonum == -1 ) return false; // don't play demos - S_StopAllSounds(); if( !cls.demos[cls.demonum][0] || cls.demonum == MAX_DEMOS ) @@ -916,20 +917,25 @@ CL_DemoGetName */ void CL_DemoGetName( int lastnum, char *filename ) { - int a, b; + int a, b, c, d; if( !filename ) return; - if( lastnum < 0 || lastnum > 99 ) + if( lastnum < 0 || lastnum > 9999 ) { // bound - Q_strcpy( filename, "demo99" ); + Q_strcpy( filename, "demo9999" ); return; } - a = lastnum / 10; - b = lastnum % 10; + a = lastnum / 1000; + lastnum -= a * 1000; + b = lastnum / 100; + lastnum -= b * 100; + c = lastnum / 10; + lastnum -= c * 10; + d = lastnum; - Q_sprintf( filename, "demo%i%i", a, b ); + Q_sprintf( filename, "demo%i%i%i%i", a, b, c, d ); } /* @@ -981,14 +987,14 @@ void CL_Record_f( void ) if( !Q_stricmp( name, "new" )) { // scan for a free filename - for( n = 0; n < 100; n++ ) + for( n = 0; n < 10000; n++ ) { CL_DemoGetName( n, demoname ); if( !FS_FileExists( va( "demos/%s.dem", demoname ), true )) break; } - if( n == 100 ) + if( n == 10000 ) { Msg( "^3ERROR: no free slots for demo recording\n" ); return; @@ -1102,7 +1108,7 @@ void CL_PlayDemo_f( void ) if( cls.changedemo ) { S_StopAllSounds(); - SCR_BeginLoadingPlaque( cl.background ); + SCR_BeginLoadingPlaque( false ); CL_ClearState (); CL_InitEdicts (); // re-arrange edicts @@ -1132,6 +1138,7 @@ void CL_PlayDemo_f( void ) cls.demoplayback = true; cls.state = ca_connected; + cl.background = (cls.demonum != -1) ? true : false; demo.starttime = CL_GetDemoPlaybackClock(); // for determining whether to read another message @@ -1168,8 +1175,9 @@ void CL_StartDemos_f( void ) for( i = 1; i < c + 1; i++ ) Q_strncpy( cls.demos[i-1], Cmd_Argv( i ), sizeof( cls.demos[0] )); - if( !SV_Active() && cls.demonum != -1 && !cls.demoplayback ) + if( !SV_Active() && !cls.demoplayback ) { + // run demos loop in background mode cls.demonum = 0; CL_NextDemo (); } diff --git a/engine/client/cl_frame.c b/engine/client/cl_frame.c index 220a7369..27c857ff 100644 --- a/engine/client/cl_frame.c +++ b/engine/client/cl_frame.c @@ -86,7 +86,7 @@ void CL_UpdateEntityFields( cl_entity_t *ent ) ent->model = Mod_Handle( ent->curstate.modelindex ); ent->curstate.msg_time = cl.time; - if( ent->player ) // stupid Half-Life bug + if( ent->player && RP_LOCALCLIENT( ent )) // stupid Half-Life bug ent->angles[PITCH] = -ent->angles[PITCH] / 3.0f; // make me lerp diff --git a/engine/client/cl_game.c b/engine/client/cl_game.c index f7f4ef13..49e725d0 100644 --- a/engine/client/cl_game.c +++ b/engine/client/cl_game.c @@ -3853,6 +3853,7 @@ void CL_UnloadProgs( void ) if( !( !Q_stricmp( GI->gamedir, "hlfx" ) && GI->version == 0.5f )) clgame.dllFuncs.pfnShutdown(); + Cvar_FullSet( "cl_background", "0", CVAR_READ_ONLY ); Cvar_FullSet( "host_clientloaded", "0", CVAR_INIT ); Com_FreeLibrary( clgame.hInstance ); diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index e6dc30d0..8e32d452 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -315,7 +315,7 @@ void CL_CreateCmd( void ) V_ProcessOverviewCmds( &cmd ); V_ProcessShowTexturesCmds( &cmd ); - if( cl.background || gl_overview->integer || cls.changelevel ) + if(( cl.background && !cls.demoplayback ) || gl_overview->integer || cls.changelevel ) { VectorCopy( angles, cl.refdef.cl_viewangles ); VectorCopy( angles, cmd.viewangles ); @@ -762,6 +762,7 @@ void CL_ClearState( void ) BF_Clear( &cls.netchan.message ); Q_memset( &clgame.fade, 0, sizeof( clgame.fade )); Q_memset( &clgame.shake, 0, sizeof( clgame.shake )); + Cvar_FullSet( "cl_background", "0", CVAR_READ_ONLY ); cl.refdef.movevars = &clgame.movevars; cl.maxclients = 1; // allow to drawing player in menu @@ -873,13 +874,6 @@ void CL_LocalServers_f( void ) { netadr_t adr; - // don't scan servers in singleplayer - if( cls.state == ca_active && CL_GetMaxClients() == 1 ) - { - MsgDev( D_INFO, "First disconnect from local game\n" ); - return; - } - MsgDev( D_INFO, "Scanning for servers on the local network area...\n" ); NET_Config( true ); // allow remote @@ -902,13 +896,6 @@ void CL_InternetServers_f( void ) char part2query[128]; string fullquery; - // don't scan servers in singleplayer - if( cls.state == ca_active && CL_GetMaxClients() == 1 ) - { - MsgDev( D_INFO, "First disconnect from local game\n" ); - return; - } - MsgDev( D_INFO, "Scanning for servers on the internet area...\n" ); NET_Config( true ); // allow remote @@ -1108,7 +1095,7 @@ void CL_PrepSound( void ) { cl.sound_index[i+1] = S_RegisterSound( cl.sound_precache[i+1] ); Cvar_SetFloat( "scr_loading", scr_loading->value + 5.0f / sndcount ); - if( cl_allow_levelshots->integer || host.developer > 3 || cl.background ) + if( cl_allow_levelshots->integer || host.developer > 3 || cls.demoplayback ) SCR_UpdateScreen(); } @@ -1175,7 +1162,7 @@ void CL_PrepVideo( void ) Q_strncpy( name, cl.model_precache[i+1], MAX_STRING ); Mod_RegisterModel( name, i+1 ); Cvar_SetFloat( "scr_loading", scr_loading->value + 75.0f / mdlcount ); - if( cl_allow_levelshots->integer || host.developer > 3 || cl.background ) + if( cl_allow_levelshots->integer || host.developer > 3 || cls.demoplayback ) SCR_UpdateScreen(); } @@ -1520,7 +1507,7 @@ void CL_ProcessFile( BOOL successfully_received, const char *filename ) if( cls.downloadfileid == cls.downloadcount - 1 ) { - MsgDev( D_INFO,"All Files downloaded\n" ); + MsgDev( D_INFO, "All Files downloaded\n" ); BF_WriteByte( &cls.netchan.message, clc_stringcmd ); BF_WriteString( &cls.netchan.message, "continueloading" ); @@ -1635,6 +1622,7 @@ void CL_InitLocal( void ) Cvar_Get( "hud_scale", "0", CVAR_ARCHIVE|CVAR_LATCH, "scale hud at current resolution" ); Cvar_Get( "skin", "", CVAR_USERINFO, "player skin" ); // XDM 3.3 want this cvar Cvar_Get( "cl_updaterate", "60", CVAR_USERINFO|CVAR_ARCHIVE, "refresh rate of server messages" ); + Cvar_Get( "cl_background", "0", CVAR_READ_ONLY, "indicate what background map is running" ); // these two added to shut up CS 1.5 about 'unknown' commands Cvar_Get( "lightgamma", "1", CVAR_ARCHIVE, "ambient lighting level (legacy, unused)" ); diff --git a/engine/client/cl_parse.c b/engine/client/cl_parse.c index 4fdb0210..80b8b19a 100644 --- a/engine/client/cl_parse.c +++ b/engine/client/cl_parse.c @@ -557,6 +557,7 @@ CL_ParseServerData void CL_ParseServerData( sizebuf_t *msg ) { string gamefolder; + qboolean background; int i; MsgDev( D_NOTE, "Serverdata packet received.\n" ); @@ -584,13 +585,26 @@ void CL_ParseServerData( sizebuf_t *msg ) clgame.maxEntities = bound( 600, clgame.maxEntities, 4096 ); Q_strncpy( clgame.mapname, BF_ReadString( msg ), MAX_STRING ); Q_strncpy( clgame.maptitle, BF_ReadString( msg ), MAX_STRING ); - cl.background = BF_ReadOneBit( msg ); + background = BF_ReadOneBit( msg ); Q_strncpy( gamefolder, BF_ReadString( msg ), MAX_STRING ); host.features = (uint)BF_ReadLong( msg ); if( cl.maxclients > 1 && host.developer < 1 ) host.developer++; + // set the background state + if( cls.demoplayback && ( cls.demonum != -1 )) + { + // re-init mouse + host.mouse_visible = false; + cl.background = true; + } + else cl.background = background; + + if( cl.background ) // tell the game parts about background state + Cvar_FullSet( "cl_background", "1", CVAR_READ_ONLY ); + else Cvar_FullSet( "cl_background", "0", CVAR_READ_ONLY ); + if( !cls.changelevel ) { // continue playing if we are changing level @@ -600,7 +614,9 @@ void CL_ParseServerData( sizebuf_t *msg ) // NOTE: this is not tested as well. Use with precaution CL_ChangeGame( gamefolder, false ); #endif - UI_SetActiveMenu( cl.background ); + if( !cls.changedemo ) + UI_SetActiveMenu( cl.background ); + else Key_SetKeyDest( key_menu ); cl.refdef.viewentity = cl.playernum + 1; // always keep viewent an actual @@ -611,16 +627,16 @@ void CL_ParseServerData( sizebuf_t *msg ) CL_InitEdicts (); // re-arrange edicts // get splash name - Cvar_Set( "cl_levelshot_name", va( "levelshots/%s_%s", clgame.mapname, glState.wideScreen ? "16x9" : "4x3" )); + if( cls.demoplayback && ( cls.demonum != -1 )) + Cvar_Set( "cl_levelshot_name", va( "levelshots/%s_%s", cls.demoname, glState.wideScreen ? "16x9" : "4x3" )); + else Cvar_Set( "cl_levelshot_name", va( "levelshots/%s_%s", clgame.mapname, glState.wideScreen ? "16x9" : "4x3" )); Cvar_SetFloat( "scr_loading", 0.0f ); // reset progress bar if(( cl_allow_levelshots->integer && !cls.changelevel ) || cl.background ) { if( !FS_FileExists( va( "%s.bmp", cl_levelshot_name->string ), true )) - { - Cvar_Set( "cl_levelshot_name", "*black" ); // render a black screen - cls.scrshot_request = scrshot_plaque; // make levelshot - } + Cvar_Set( "cl_levelshot_name", "*black" ); // render a black screen + cls.scrshot_request = scrshot_plaque; // request levelshot even if exist (check filetime) } if( scr_dark->integer ) diff --git a/engine/client/cl_pmove.c b/engine/client/cl_pmove.c index c033cee6..2493a732 100644 --- a/engine/client/cl_pmove.c +++ b/engine/client/cl_pmove.c @@ -785,11 +785,6 @@ void CL_PredictMovement( void ) clientdata_t *cd; if( cls.state != ca_active ) return; - if( cl.refdef.paused || cls.key_dest == key_menu ) return; - - player = CL_GetLocalPlayer (); - viewent = CL_GetEntityByIndex( cl.refdef.viewentity ); - cd = &cl.frame.local.client; if( cls.demoplayback && cl.refdef.cmd != NULL ) { @@ -797,6 +792,12 @@ void CL_PredictMovement( void ) VectorCopy( cl.refdef.cmd->viewangles, cl.refdef.cl_viewangles ); } + if( cl.refdef.paused || cls.key_dest == key_menu ) return; + + player = CL_GetLocalPlayer (); + viewent = CL_GetEntityByIndex( cl.refdef.viewentity ); + cd = &cl.frame.local.client; + // unpredicted pure angled values converted into axis AngleVectors( cl.refdef.cl_viewangles, cl.refdef.forward, cl.refdef.right, cl.refdef.up ); diff --git a/engine/client/cl_scrn.c b/engine/client/cl_scrn.c index 4b36a109..52198d3c 100644 --- a/engine/client/cl_scrn.c +++ b/engine/client/cl_scrn.c @@ -264,14 +264,12 @@ void SCR_DrawPlaque( void ) { int levelshot; - if(( cl_allow_levelshots->integer && !cls.changelevel ) || Cvar_VariableInteger( "sv_background" )) + if(( cl_allow_levelshots->integer && !cls.changelevel ) || cl.background ) { levelshot = GL_LoadTexture( cl_levelshot_name->string, NULL, 0, TF_IMAGE, NULL ); GL_SetRenderMode( kRenderNormal ); R_DrawStretchPic( 0, 0, scr_width->integer, scr_height->integer, 0, 0, 1, 1, levelshot ); - - if( !Cvar_VariableInteger( "sv_background" )) - CL_DrawHUD( CL_LOADING ); + if( !cl.background ) CL_DrawHUD( CL_LOADING ); } } diff --git a/engine/client/client.h b/engine/client/client.h index 2feeaf76..383982cc 100644 --- a/engine/client/client.h +++ b/engine/client/client.h @@ -454,6 +454,7 @@ typedef struct qboolean demowaiting; // don't record until a non-delta message is received qboolean timedemo; string demoname; // for demo looping + double demotime; // recording time file_t *demofile; file_t *demoheader; // contain demo startup info in case we record a demo on this level diff --git a/engine/client/gl_draw.c b/engine/client/gl_draw.c index 96b269fd..b5064126 100644 --- a/engine/client/gl_draw.c +++ b/engine/client/gl_draw.c @@ -247,7 +247,6 @@ void R_Set2DMode( qboolean enable ) return; // set 2D virtual screen size - pglScissor( 0, 0, glState.width, glState.height ); pglViewport( 0, 0, glState.width, glState.height ); pglMatrixMode( GL_PROJECTION ); pglLoadIdentity(); diff --git a/engine/client/gl_local.h b/engine/client/gl_local.h index a57e38f6..d67c37f3 100644 --- a/engine/client/gl_local.h +++ b/engine/client/gl_local.h @@ -109,7 +109,6 @@ typedef struct cl_entity_t *currentbeam; // same as above but for beams int viewport[4]; - int scissor[4]; mplane_t frustum[6]; vec3_t pvsorigin; diff --git a/engine/client/gl_rmain.c b/engine/client/gl_rmain.c index d2379a2a..393f7f14 100644 --- a/engine/client/gl_rmain.c +++ b/engine/client/gl_rmain.c @@ -865,8 +865,23 @@ static void R_SetupGL( void ) Matrix4x4_Concat( RI.worldviewProjectionMatrix, RI.projectionMatrix, RI.worldviewMatrix ); - pglScissor( RI.scissor[0], RI.scissor[1], RI.scissor[2], RI.scissor[3] ); - pglViewport( RI.viewport[0], RI.viewport[1], RI.viewport[2], RI.viewport[3] ); + if( RP_NORMALPASS( )) + { + int x, x2, y, y2; + + // set up viewport (main, playersetup) + x = floor( RI.viewport[0] * glState.width / glState.width ); + x2 = ceil(( RI.viewport[0] + RI.viewport[2] ) * glState.width / glState.width ); + y = floor( glState.height - RI.viewport[1] * glState.height / glState.height ); + y2 = ceil( glState.height - ( RI.viewport[1] + RI.viewport[3] ) * glState.height / glState.height ); + + pglViewport( x, y2, x2 - x, y - y2 ); + } + else + { + // envpass, mirrorpass + pglViewport( RI.viewport[0], RI.viewport[1], RI.viewport[2], RI.viewport[3] ); + } pglMatrixMode( GL_PROJECTION ); GL_LoadMatrix( RI.projectionMatrix ); @@ -1307,12 +1322,6 @@ void R_RenderFrame( const ref_params_t *fd, qboolean drawWorld ) if( !r_lockcull->integer ) VectorCopy( fd->vieworg, RI.cullorigin ); VectorCopy( fd->vieworg, RI.pvsorigin ); - - // setup scissor - RI.scissor[0] = fd->viewport[0]; - RI.scissor[1] = fd->viewport[1]; - RI.scissor[2] = fd->viewport[2]; - RI.scissor[3] = fd->viewport[3]; // setup viewport RI.viewport[0] = fd->viewport[0]; @@ -1377,12 +1386,6 @@ void R_DrawCubemapView( const vec3_t origin, const vec3_t angles, int size ) VectorCopy( angles, fd->viewangles ); VectorCopy( fd->vieworg, RI.pvsorigin ); - // setup scissor - RI.scissor[0] = fd->viewport[0]; - RI.scissor[1] = fd->viewport[1]; - RI.scissor[2] = fd->viewport[2]; - RI.scissor[3] = fd->viewport[3]; - // setup viewport RI.viewport[0] = fd->viewport[0]; RI.viewport[1] = fd->viewport[1]; diff --git a/engine/client/gl_vidnt.c b/engine/client/gl_vidnt.c index 9e03ea57..2c78b06a 100644 --- a/engine/client/gl_vidnt.c +++ b/engine/client/gl_vidnt.c @@ -19,11 +19,12 @@ GNU General Public License for more details. #include "mod_local.h" #include "input.h" -#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) -#define WINDOW_NAME "Xash Window" // Half-Life +#define VID_DEFAULTMODE "1" +#define DISP_CHANGE_BADDUALVIEW -6 // MSVC 6.0 doesn't +#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) +#define WINDOW_NAME "Xash Window" // Half-Life convar_t *renderinfo; convar_t *gl_allow_software; @@ -1167,6 +1168,7 @@ void VID_DestroyWindow( void ) rserr_t R_ChangeDisplaySettings( int vid_mode, qboolean fullscreen ) { int width, height; + int cds_result; HDC hDC; R_SaveVideoMode( vid_mode ); @@ -1203,8 +1205,10 @@ rserr_t R_ChangeDisplaySettings( int vid_mode, qboolean fullscreen ) dm.dmFields |= DM_DISPLAYFREQUENCY; dm.dmDisplayFrequency = vid_displayfrequency->integer; } + + cds_result = ChangeDisplaySettings( &dm, CDS_FULLSCREEN ); - if( ChangeDisplaySettings( &dm, CDS_FULLSCREEN ) == DISP_CHANGE_SUCCESSFUL ) + if( cds_result == DISP_CHANGE_SUCCESSFUL ) { glState.fullScreen = true; @@ -1212,13 +1216,11 @@ rserr_t R_ChangeDisplaySettings( int vid_mode, qboolean fullscreen ) return rserr_invalid_mode; return rserr_ok; } - else + else if( cds_result == DISP_CHANGE_BADDUALVIEW ) { dm.dmPelsWidth = width * 2; dm.dmPelsHeight = height; dm.dmFields = DM_PELSWIDTH|DM_PELSHEIGHT; - dm.dmBitsPerPel = 24; - dm.dmFields |= DM_BITSPERPEL; // our first CDS failed, so maybe we're running on some weird dual monitor system if( ChangeDisplaySettings( &dm, CDS_FULLSCREEN ) != DISP_CHANGE_SUCCESSFUL ) @@ -1237,6 +1239,39 @@ rserr_t R_ChangeDisplaySettings( int vid_mode, qboolean fullscreen ) return rserr_ok; } } + else + { + int freq_specified = 0; + + if( vid_displayfrequency->integer > 0 ) + { + // clear out custom frequency + freq_specified = vid_displayfrequency->integer; + Cvar_SetFloat( "vid_displayfrequency", 0.0f ); + dm.dmFields &= ~DM_DISPLAYFREQUENCY; + dm.dmDisplayFrequency = 0; + } + + // our first CDS failed, so maybe we're running with too high displayfrequency + if( ChangeDisplaySettings( &dm, CDS_FULLSCREEN ) != DISP_CHANGE_SUCCESSFUL ) + { + ChangeDisplaySettings( 0, 0 ); + glState.fullScreen = false; + if( !VID_CreateWindow( width, height, false )) + return rserr_invalid_mode; + return rserr_invalid_fullscreen; + } + else + { + if( !VID_CreateWindow( width, height, true )) + return rserr_invalid_mode; + + if( freq_specified ) + MsgDev( D_ERROR, "VID_SetMode: display frequency %i Hz not supported by your display\n", freq_specified ); + glState.fullScreen = true; + return rserr_ok; + } + } } else { @@ -1245,6 +1280,7 @@ rserr_t R_ChangeDisplaySettings( int vid_mode, qboolean fullscreen ) if( !VID_CreateWindow( width, height, false )) return rserr_invalid_mode; } + return rserr_ok; } @@ -1374,7 +1410,7 @@ static void GL_SetDefaults( void ) pglDisable( GL_DEPTH_TEST ); pglDisable( GL_CULL_FACE ); - pglEnable( GL_SCISSOR_TEST ); + pglDisable( GL_SCISSOR_TEST ); pglDepthFunc( GL_LEQUAL ); pglDepthMask( GL_FALSE ); diff --git a/engine/common/console.c b/engine/common/console.c index 0c80233d..0811ab8a 100644 --- a/engine/common/console.c +++ b/engine/common/console.c @@ -281,7 +281,7 @@ void Con_ToggleConsole_f( void ) if( cls.key_dest == key_console ) { - if( Cvar_VariableInteger( "sv_background" )) + if( Cvar_VariableInteger( "sv_background" ) || Cvar_VariableInteger( "cl_background" )) UI_SetActiveMenu( true ); else UI_SetActiveMenu( false ); } @@ -1587,7 +1587,7 @@ Draws the debug messages (not passed to console history) */ void Con_DrawDebug( void ) { - if( !host.developer || Cvar_VariableInteger( "sv_background" )) + if( !host.developer || Cvar_VariableInteger( "cl_background" ) || Cvar_VariableInteger( "sv_background" )) return; if( con.draw_notify && !Con_Visible( )) @@ -1613,7 +1613,7 @@ void Con_DrawNotify( void ) if( !con.curFont ) return; - if( host.developer && !Cvar_VariableInteger( "sv_background" )) + if( host.developer && ( !Cvar_VariableInteger( "cl_background" ) && !Cvar_VariableInteger( "sv_background" ))) { currentColor = 7; pglColor4ubv( g_color_table[currentColor] ); @@ -1780,7 +1780,7 @@ void Con_DrawConsole( void ) { if( !cl_allow_levelshots->integer ) { - if( Cvar_VariableInteger( "sv_background" ) && cls.key_dest != key_console ) + if(( Cvar_VariableInteger( "cl_background" ) || Cvar_VariableInteger( "sv_background" )) && cls.key_dest != key_console ) con.displayFrac = con.finalFrac = 0.0f; else con.displayFrac = con.finalFrac = 1.0f; } @@ -1820,7 +1820,7 @@ void Con_DrawConsole( void ) break; case ca_active: case ca_cinematic: - if( Cvar_VariableInteger( "sv_background" )) + if( Cvar_VariableInteger( "cl_background" ) || Cvar_VariableInteger( "sv_background" )) { if( cls.key_dest == key_console ) Con_DrawSolidConsole( 1.0f ); diff --git a/engine/common/filesystem.c b/engine/common/filesystem.c index 6298b8b9..b96a9c22 100644 --- a/engine/common/filesystem.c +++ b/engine/common/filesystem.c @@ -2703,7 +2703,7 @@ qboolean FS_Delete( const char *path ) COM_FixSlashes( real_path ); iRet = remove( real_path ); - return (iRet == 0) ? true : false; + return (iRet == 0); } /* diff --git a/engine/common/host.c b/engine/common/host.c index 14b15a40..25f0a0f7 100644 --- a/engine/common/host.c +++ b/engine/common/host.c @@ -130,10 +130,13 @@ void Host_EndGame( const char *message, ... ) if( host.type == HOST_DEDICATED ) Sys_Break( "Host_EndGame: %s\n", string ); // dedicated servers exit - +Msg( "Endgame()\n" ); if( CL_NextDemo( )); else CL_Disconnect(); + // recreate world if needs + CL_ClearEdicts (); + // release all models Mod_ClearAll(); @@ -220,8 +223,8 @@ Host_Exec_f void Host_Exec_f( void ) { string cfgpath; + char *f, *txt; size_t len; - char *f; if( Cmd_Argc() != 2 ) { @@ -246,9 +249,15 @@ void Host_Exec_f( void ) return; } - MsgDev( D_INFO, "execing %s\n", Cmd_Argv( 1 )); - Cbuf_InsertText( f ); + // adds \n\0 at end of the file + txt = Z_Malloc( len + 2 ); + Q_memcpy( txt, f, len ); + Q_strncat( txt, "\n", len + 2 ); Mem_Free( f ); + + MsgDev( D_INFO, "execing %s\n", Cmd_Argv( 1 )); + Cbuf_InsertText( txt ); + Mem_Free( txt ); } /* @@ -500,7 +509,7 @@ qboolean Host_FilterTime( float time ) host.realframetime = bound( MIN_FRAMETIME, host.frametime, MAX_FRAMETIME ); oldtime = host.realtime; - if( host_framerate->value > 0 && ( Host_IsLocalGame()/* || CL_IsPlaybackDemo() */)) + if( host_framerate->value > 0 && ( Host_IsLocalGame())) { float fps = host_framerate->value; if( fps > 1 ) fps = 1.0f / fps; diff --git a/engine/common/mod_local.h b/engine/common/mod_local.h index 2a50d679..4be7a0db 100644 --- a/engine/common/mod_local.h +++ b/engine/common/mod_local.h @@ -26,7 +26,6 @@ GNU General Public License for more details. #define DIST_EPSILON (1.0f / 32.0f) #define FRAC_EPSILON (1.0f / 1024.0f) #define BACKFACE_EPSILON 0.01f -#define DEFAULT_SMOOTHING_ANGLE 50.0f #define MAX_BOX_LEAFS 256 #define DVIS_PVS 0 #define DVIS_PHS 1 @@ -84,7 +83,6 @@ typedef struct int lm_sample_size; // defaulting to 16 (BSP31 uses 8) int block_size; // lightmap blocksize color24 *deluxedata; // deluxemap data pointer - float smooth_threshold; // used for calc smoothed TBN vec3_t mins; // real accuracy world bounds vec3_t maxs; diff --git a/engine/common/model.c b/engine/common/model.c index 6d9ed767..26f8f47b 100644 --- a/engine/common/model.c +++ b/engine/common/model.c @@ -1302,91 +1302,6 @@ static void Mod_CalcSurfaceBounds( msurface_t *surf, mextrasurf_t *info ) VectorAverage( info->mins, info->maxs, info->origin ); } -// this is a great time-waster. move to hlrad -static void Mod_ComputeSmoothTBN( const msurface_t *f1, const int num, vec3_t t, vec3_t b, vec3_t n ) -{ - vec3_t n1, n2; // plane normals - int i, j, e, vert; - - if( f1->flags & SURF_PLANEBACK ) - VectorNegate( f1->plane->normal, n1 ); - else VectorCopy( f1->plane->normal, n1 ); - - e = loadmodel->surfedges[f1->firstedge + num]; - if( e > 0 ) vert = loadmodel->edges[e].v[0]; - else vert = loadmodel->edges[-e].v[1]; - - VectorClear( t ); - VectorClear( b ); - VectorClear( n ); - - for( i = 0; i < loadmodel->numsurfaces; i++ ) - { - // check if this face contains vert - msurface_t *f2 = &loadmodel->surfaces[i]; - qboolean hasVert = false; - - for( j = 0; j < f2->numedges; j++ ) - { - e = loadmodel->surfedges[f2->firstedge + j]; - - if( e > 0 && loadmodel->edges[e].v[0] == vert ) - { - hasVert = true; - break; - } - - if( e < 0 && loadmodel->edges[-e].v[1] == vert ) - { - hasVert = true; - break; - } - } - - if( !hasVert ) continue; - - if( f2->flags & SURF_PLANEBACK ) - VectorNegate( f2->plane->normal, n2 ); - else VectorCopy( f2->plane->normal, n2 ); - - if( DotProduct( n1, n2 ) < world.smooth_threshold ) - continue; - - VectorAdd( t, f2->texinfo->vecs[0], t ); - VectorNormalize( t ); - - VectorAdd( b, f2->texinfo->vecs[1], b ); - VectorNormalize( b ); - - VectorAdd( n, n2, n ); - VectorNormalize( n ); - } - - if( VectorIsNull( t )) - { - VectorCopy( f1->texinfo->vecs[0], t ); - VectorNormalize( t ); - } - - if( VectorIsNull( b )) - { - VectorCopy( f1->texinfo->vecs[1], b ); - VectorNormalize( b ); - } - - if( VectorIsNull( n )) - { - VectorCopy( n1, n ); - } - - // FIXME: get rid of this stupid binormal inversion! - // 1. cleanup VHLT code - // 2. cleanum Engine code - // 3. cleanup Paranoia2 renderer - // 4. cleanup XashXT renderer - VectorNegate( b, b ); -} - /* ================= Mod_BuildPolygon @@ -2285,9 +2200,6 @@ static void Mod_LoadEntities( const dlump_t *l ) Q_memcpy( loadmodel->entities, mod_base + l->fileofs, l->filelen ); if( !world.loading ) return; - // sets ZHLT\VHLT default value - world.smooth_threshold = (float)cos( DEG2RAD( DEFAULT_SMOOTHING_ANGLE )); - world.entdatasize = l->filelen; pfile = (char *)loadmodel->entities; wadlist.count = 0; @@ -2332,8 +2244,6 @@ static void Mod_LoadEntities( const dlump_t *l ) } else if( !Q_stricmp( keyname, "mapversion" )) world.mapversion = Q_atoi( token ); - else if( !Q_stricmp( keyname, "smoothangle" )) - world.smooth_threshold = (float)cos( DEG2RAD( Q_atof( token ))); } return; // all done } diff --git a/engine/server/sv_cmds.c b/engine/server/sv_cmds.c index 1385ae9a..674d382d 100644 --- a/engine/server/sv_cmds.c +++ b/engine/server/sv_cmds.c @@ -213,6 +213,9 @@ void SV_Map_f( void ) return; } + // init network stuff + NET_Config(( sv_maxclients->integer > 1 )); + // changing singleplayer to multiplayer or back. refresh the player count if(( sv_maxclients->modified ) || ( deathmatch->modified ) || ( coop->modified ) || ( teamplay->modified )) Host_ShutdownServer(); diff --git a/engine/server/sv_save.c b/engine/server/sv_save.c index 4afa6335..53f3711a 100644 --- a/engine/server/sv_save.c +++ b/engine/server/sv_save.c @@ -1918,6 +1918,8 @@ void SV_ChangeLevel( qboolean loadfromsavedgame, const char *mapname, const char startspot = _startspot; } + // init network stuff + NET_Config(( sv_maxclients->integer > 1 )); Q_strncpy( level, mapname, MAX_STRING ); Q_strncpy( oldlevel, sv.name, MAX_STRING ); sv.background = false; @@ -2118,6 +2120,9 @@ qboolean SV_LoadGame( const char *pName ) Q_snprintf( name, sizeof( name ), "save/%s.sav", pName ); + // init network stuff + NET_Config(( sv_maxclients->integer > 1 )); + if( sv.background ) SV_Shutdown( true ); sv.background = false; diff --git a/mainui/basemenu.cpp b/mainui/basemenu.cpp index 40baa6ae..13130cbb 100644 --- a/mainui/basemenu.cpp +++ b/mainui/basemenu.cpp @@ -864,7 +864,7 @@ bool UI_StartBackGroundMap( void ) first = FALSE; // some map is already running - if( !uiStatic.bgmapcount || CVAR_GET_FLOAT( "host_serverstate" )) + if( !uiStatic.bgmapcount || CVAR_GET_FLOAT( "host_serverstate" ) || gpGlobals->demoplayback ) return FALSE; int bgmapid = RANDOM_LONG( 0, uiStatic.bgmapcount - 1 ); @@ -1010,7 +1010,7 @@ void UI_UpdateMenu( float flTime ) uiStatic.realTime = flTime * 1000; uiStatic.framecount++; - if( CVAR_GET_FLOAT( "sv_background" ) && !g_engfuncs.pfnClientInGame()) + if( CVAR_GET_FLOAT( "cl_background" ) && !g_engfuncs.pfnClientInGame()) return; // don't draw menu while level is loading if( uiStatic.firstDraw ) diff --git a/mainui/enginecallback.h b/mainui/enginecallback.h index 4e744af0..7fc54781 100644 --- a/mainui/enginecallback.h +++ b/mainui/enginecallback.h @@ -104,7 +104,7 @@ inline HIMAGE PIC_Load( const char *szPicName, const byte *ucRawImage, long ulRa #define GET_SAVE_COMMENT (*g_engfuncs.pfnGetSaveComment) #define GET_DEMO_COMMENT (*g_engfuncs.pfnGetDemoComment) -#define CL_IsActive() (g_engfuncs.pfnClientInGame() && !CVAR_GET_FLOAT( "sv_background" )) +#define CL_IsActive() (g_engfuncs.pfnClientInGame() && !CVAR_GET_FLOAT( "cl_background" )) inline void PIC_Set( HIMAGE hPic, int r, int g, int b ) { diff --git a/mainui/menu_creategame.cpp b/mainui/menu_creategame.cpp index 2495f126..04a231a7 100644 --- a/mainui/menu_creategame.cpp +++ b/mainui/menu_creategame.cpp @@ -127,7 +127,7 @@ static void UI_CreateGame_Begin( void ) static void UI_PromptDialog( void ) { - if( !CVAR_GET_FLOAT( "host_serverstate" ) || CVAR_GET_FLOAT( "sv_background" )) + if( !CVAR_GET_FLOAT( "host_serverstate" ) || CVAR_GET_FLOAT( "cl_background" )) { UI_CreateGame_Begin(); return; diff --git a/mainui/menu_credits.cpp b/mainui/menu_credits.cpp index 6c1bc5fa..fff2764a 100644 --- a/mainui/menu_credits.cpp +++ b/mainui/menu_credits.cpp @@ -64,7 +64,7 @@ static void UI_Credits_DrawFunc( void ) int color = 0; // draw the background first - if( !uiCredits.finalCredits && !CVAR_GET_FLOAT( "sv_background" )) + if( !uiCredits.finalCredits && !CVAR_GET_FLOAT( "cl_background" )) UI_DrawPic( 0, 0, 1024 * uiStatic.scaleX, 768 * uiStatic.scaleY, uiColorWhite, ART_BACKGROUND ); else speed = 45.0f; // syncronize with final background track :-) diff --git a/mainui/menu_internetgames.cpp b/mainui/menu_internetgames.cpp index 0564793a..d11cdddc 100644 --- a/mainui/menu_internetgames.cpp +++ b/mainui/menu_internetgames.cpp @@ -191,7 +191,7 @@ static void UI_Background_Ownerdraw( void *self ) { menuCommon_s *item = (menuCommon_s *)self; - if( !CVAR_GET_FLOAT( "sv_background" )) + if( !CVAR_GET_FLOAT( "cl_background" )) UI_DrawBackground_Callback( self ); if( uiStatic.realTime > uiInternetGames.refreshTime ) diff --git a/mainui/menu_langame.cpp b/mainui/menu_langame.cpp index 1ebb16e3..6ff3e01c 100644 --- a/mainui/menu_langame.cpp +++ b/mainui/menu_langame.cpp @@ -191,7 +191,7 @@ static void UI_Background_Ownerdraw( void *self ) { menuCommon_s *item = (menuCommon_s *)self; - if( !CVAR_GET_FLOAT( "sv_background" )) + if( !CVAR_GET_FLOAT( "cl_background" )) UI_DrawBackground_Callback( self ); if( uiStatic.realTime > uiLanGame.refreshTime ) diff --git a/mainui/menu_main.cpp b/mainui/menu_main.cpp index 5e904c6b..3df94dc6 100644 --- a/mainui/menu_main.cpp +++ b/mainui/menu_main.cpp @@ -101,7 +101,7 @@ static void UI_Background_Ownerdraw( void *self ) menuCommon_s *item = (menuCommon_s *)self; // map has background - if( CVAR_GET_FLOAT( "sv_background" )) + if( CVAR_GET_FLOAT( "cl_background" )) return; UI_DrawBackground_Callback( self ); diff --git a/mainui/menu_playersetup.cpp b/mainui/menu_playersetup.cpp index 2e8a51c5..7732e07f 100644 --- a/mainui/menu_playersetup.cpp +++ b/mainui/menu_playersetup.cpp @@ -491,10 +491,10 @@ static void UI_PlayerSetup_Init( void ) uiPlayerSetup.refdef.fov_x = 40; // NOTE: must be called after UI_AddItem whan we sure what UI_ScaleCoords is done - uiPlayerSetup.refdef.viewport[0] = uiPlayerSetup.view.generic.x + (uiPlayerSetup.view.generic.width / 12); - uiPlayerSetup.refdef.viewport[1] = uiPlayerSetup.view.generic.y + (uiPlayerSetup.view.generic.height / 12); - uiPlayerSetup.refdef.viewport[2] = uiPlayerSetup.view.generic.width-(uiPlayerSetup.view.generic.width / 6); - uiPlayerSetup.refdef.viewport[3] = uiPlayerSetup.view.generic.height-(uiPlayerSetup.view.generic.height / 6); + uiPlayerSetup.refdef.viewport[0] = uiPlayerSetup.view.generic.x; + uiPlayerSetup.refdef.viewport[1] = uiPlayerSetup.view.generic.y; + uiPlayerSetup.refdef.viewport[2] = uiPlayerSetup.view.generic.width; + uiPlayerSetup.refdef.viewport[3] = uiPlayerSetup.view.generic.height; UI_PlayerSetup_CalcFov( &uiPlayerSetup.refdef ); uiPlayerSetup.ent = GET_MENU_EDICT (); @@ -518,11 +518,9 @@ static void UI_PlayerSetup_Init( void ) uiPlayerSetup.ent->latched.prevcontroller[1] = 127; uiPlayerSetup.ent->latched.prevcontroller[2] = 127; uiPlayerSetup.ent->latched.prevcontroller[3] = 127; - if(( ScreenWidth * 3 ) == ( 4 * ScreenHeight ) || ( ScreenWidth * 4 ) == ( ScreenHeight * 5 )) - uiPlayerSetup.ent->origin[0] = uiPlayerSetup.ent->curstate.origin[0] = 92; - else uiPlayerSetup.ent->origin[0] = uiPlayerSetup.ent->curstate.origin[0] = 120; - uiPlayerSetup.ent->origin[2] = uiPlayerSetup.ent->curstate.origin[2] = 2; - uiPlayerSetup.ent->angles[1] = uiPlayerSetup.ent->curstate.angles[1] = 180; + uiPlayerSetup.ent->origin[0] = uiPlayerSetup.ent->curstate.origin[0] = 45.0f / tan( DEG2RAD( uiPlayerSetup.refdef.fov_y / 2.0f )); + uiPlayerSetup.ent->origin[2] = uiPlayerSetup.ent->curstate.origin[2] = 2.0f; + uiPlayerSetup.ent->angles[1] = uiPlayerSetup.ent->curstate.angles[1] = 180.0f; uiPlayerSetup.ent->player = true; // yes, draw me as playermodel } diff --git a/mainui/utils.cpp b/mainui/utils.cpp index 7becdf49..f1eea899 100644 --- a/mainui/utils.cpp +++ b/mainui/utils.cpp @@ -1979,7 +1979,7 @@ void UI_Bitmap_Draw( menuBitmap_s *b ) { if( b->generic.id == ID_BACKGROUND ) // background is always 0! { - if( CVAR_GET_FLOAT( "sv_background" )) + if( CVAR_GET_FLOAT( "cl_background" )) return; // has background map disable images // UGLY HACK for replace all backgrounds