diff options
-rw-r--r-- | src/client/cl_cgame.c | 14 | ||||
-rw-r--r-- | src/client/cl_cin.c | 21 | ||||
-rw-r--r-- | src/client/cl_console.c | 21 | ||||
-rw-r--r-- | src/client/cl_input.c | 86 | ||||
-rw-r--r-- | src/client/cl_keys.c | 16 | ||||
-rw-r--r-- | src/client/cl_main.c | 277 | ||||
-rw-r--r-- | src/client/cl_parse.c | 7 | ||||
-rw-r--r-- | src/client/cl_scrn.c | 8 | ||||
-rw-r--r-- | src/client/cl_ui.c | 8 | ||||
-rw-r--r-- | src/client/client.h | 17 | ||||
-rw-r--r-- | src/null/null_client.c | 16 | ||||
-rw-r--r-- | src/qcommon/common.c | 39 | ||||
-rw-r--r-- | src/qcommon/files.c | 7 | ||||
-rw-r--r-- | src/qcommon/qcommon.h | 16 | ||||
-rw-r--r-- | src/sdl/sdl_input.c | 2 | ||||
-rw-r--r-- | src/server/sv_init.c | 2 | ||||
-rw-r--r-- | src/sys/sys_main.c | 6 |
17 files changed, 369 insertions, 194 deletions
diff --git a/src/client/cl_cgame.c b/src/client/cl_cgame.c index c86eb248..e295fdf7 100644 --- a/src/client/cl_cgame.c +++ b/src/client/cl_cgame.c @@ -781,7 +781,7 @@ void CL_InitCGame( void ) { if ( !cgvm ) { Com_Error( ERR_DROP, "VM_Create on cgame failed" ); } - cls.state = CA_LOADING; + clc.state = CA_LOADING; // init for this gamestate // use the lastExecutedServerCommand instead of the serverCommandSequence @@ -794,7 +794,7 @@ void CL_InitCGame( void ) { // we will send a usercmd this frame, which // will cause the server to send us the first snapshot - cls.state = CA_PRIMED; + clc.state = CA_PRIMED; t2 = Sys_Milliseconds(); @@ -944,7 +944,7 @@ void CL_FirstSnapshot( void ) { if ( cl.snap.snapFlags & SNAPFLAG_NOT_ACTIVE ) { return; } - cls.state = CA_ACTIVE; + clc.state = CA_ACTIVE; // set the timedelta so we are exactly on this first frame cl.serverTimeDelta = cl.snap.serverTime - cls.realtime; @@ -1015,8 +1015,8 @@ CL_SetCGameTime */ void CL_SetCGameTime( void ) { // getting a valid frame message ends the connection process - if ( cls.state != CA_ACTIVE ) { - if ( cls.state != CA_PRIMED ) { + if ( clc.state != CA_ACTIVE ) { + if ( clc.state != CA_PRIMED ) { return; } if ( clc.demoplaying ) { @@ -1032,7 +1032,7 @@ void CL_SetCGameTime( void ) { cl.newSnapshots = qfalse; CL_FirstSnapshot(); } - if ( cls.state != CA_ACTIVE ) { + if ( clc.state != CA_ACTIVE ) { return; } } @@ -1145,7 +1145,7 @@ void CL_SetCGameTime( void ) { // feed another messag, which should change // the contents of cl.snap CL_ReadDemoMessage(); - if ( cls.state != CA_ACTIVE ) { + if ( clc.state != CA_ACTIVE ) { return; // end of demo } } diff --git a/src/client/cl_cin.c b/src/client/cl_cin.c index 213b7a40..3793dcd9 100644 --- a/src/client/cl_cin.c +++ b/src/client/cl_cin.c @@ -1264,6 +1264,8 @@ static void RoQ_init( void ) ******************************************************************************/ static void RoQShutdown( void ) { + const char *s; + if (!cinTable[currentHandle].buf) { return; } @@ -1280,7 +1282,16 @@ static void RoQShutdown( void ) { } if (cinTable[currentHandle].alterGameState) { - cls.state = CA_DISCONNECTED; + clc.state = CA_DISCONNECTED; + // we can't just do a vstr nextmap, because + // if we are aborting the intro cinematic with + // a devmap command, nextmap would be valid by + // the time it was referenced + s = Cvar_VariableString( "nextmap" ); + if ( s[0] ) { + Cbuf_ExecuteText( EXEC_APPEND, va("%s\n", s) ); + Cvar_Set( "nextmap", "" ); + } CL_handle = -1; } cinTable[currentHandle].fileName[0] = 0; @@ -1304,7 +1315,7 @@ e_status CIN_StopCinematic(int handle) { } if (cinTable[currentHandle].alterGameState) { - if ( cls.state != CA_CINEMATIC ) { + if ( clc.state != CA_CINEMATIC ) { return cinTable[currentHandle].status; } } @@ -1345,7 +1356,7 @@ e_status CIN_RunCinematic (int handle) currentHandle = handle; if (cinTable[currentHandle].alterGameState) { - if ( cls.state != CA_CINEMATIC ) { + if ( clc.state != CA_CINEMATIC ) { return cinTable[currentHandle].status; } } @@ -1469,7 +1480,7 @@ int CIN_PlayCinematic( const char *arg, int x, int y, int w, int h, int systemBi Com_DPrintf("trFMV::play(), playing %s\n", arg); if (cinTable[currentHandle].alterGameState) { - cls.state = CA_CINEMATIC; + clc.state = CA_CINEMATIC; } Con_Close(); @@ -1604,7 +1615,7 @@ void CL_PlayCinematic_f(void) { int bits = CIN_system; Com_DPrintf("CL_PlayCinematic_f\n"); - if (cls.state == CA_CINEMATIC) { + if (clc.state == CA_CINEMATIC) { SCR_StopCinematic(); } diff --git a/src/client/cl_console.c b/src/client/cl_console.c index c7d01bc7..6cb80980 100644 --- a/src/client/cl_console.c +++ b/src/client/cl_console.c @@ -70,7 +70,7 @@ Con_ToggleConsole_f */ void Con_ToggleConsole_f (void) { // Can't toggle the console when it's the only thing available - if ( cls.state == CA_DISCONNECTED && Key_GetCatcher( ) == KEYCATCH_CONSOLE ) { + if ( clc.state == CA_DISCONNECTED && Key_GetCatcher( ) == KEYCATCH_CONSOLE ) { return; } @@ -269,6 +269,21 @@ void Con_Init (void) { Cmd_SetCommandCompletionFunc( "condump", Cmd_CompleteTxtName ); } +/* +================ +Con_Shutdown +================ +*/ +void Con_Shutdown(void) +{ + Cmd_RemoveCommand("toggleconsole"); + Cmd_RemoveCommand("messagemode"); + Cmd_RemoveCommand("messagemode2"); + Cmd_RemoveCommand("messagemode3"); + Cmd_RemoveCommand("messagemode4"); + Cmd_RemoveCommand("clear"); + Cmd_RemoveCommand("condump"); +} /* =============== @@ -400,7 +415,7 @@ Draw the editline after a ] prompt void Con_DrawInput (void) { int y; - if ( cls.state != CA_DISCONNECTED && !(Key_GetCatcher( ) & KEYCATCH_CONSOLE ) ) { + if ( clc.state != CA_DISCONNECTED && !(Key_GetCatcher( ) & KEYCATCH_CONSOLE ) ) { return; } @@ -538,7 +553,7 @@ void Con_DrawConsole( void ) { Con_CheckResize (); // if disconnected, render console full screen - if ( cls.state == CA_DISCONNECTED ) { + if ( clc.state == CA_DISCONNECTED ) { if ( !( Key_GetCatcher( ) & (KEYCATCH_UI | KEYCATCH_CGAME)) ) { Con_DrawSolidConsole( 1.0 ); return; diff --git a/src/client/cl_input.c b/src/client/cl_input.c index ee5b478e..f9ec9d04 100644 --- a/src/client/cl_input.c +++ b/src/client/cl_input.c @@ -641,7 +641,7 @@ void CL_CreateNewCommands( void ) { int cmdNum; // no need to create usercmds until we have a gamestate - if ( cls.state < CA_PRIMED ) { + if ( clc.state < CA_PRIMED ) { return; } @@ -678,7 +678,7 @@ qboolean CL_ReadyToSendPacket( void ) { int delta; // don't send anything if playing back a demo - if ( clc.demoplaying || cls.state == CA_CINEMATIC ) { + if ( clc.demoplaying || clc.state == CA_CINEMATIC ) { return qfalse; } @@ -690,8 +690,8 @@ qboolean CL_ReadyToSendPacket( void ) { // if we don't have a valid gamestate yet, only send // one packet a second - if ( cls.state != CA_ACTIVE && - cls.state != CA_PRIMED && + if ( clc.state != CA_ACTIVE && + clc.state != CA_PRIMED && !*clc.downloadTempName && cls.realtime - clc.lastPacketSentTime < 1000 ) { return qfalse; @@ -755,7 +755,7 @@ void CL_WritePacket( void ) { int count, key; // don't send anything if playing back a demo - if ( clc.demoplaying || cls.state == CA_CINEMATIC ) { + if ( clc.demoplaying || clc.state == CA_CINEMATIC ) { return; } @@ -910,7 +910,7 @@ Called every frame to builds and sends a command packet to the server. */ void CL_SendCmd( void ) { // don't send any message if not connected - if ( cls.state < CA_CONNECTED ) { + if ( clc.state < CA_CONNECTED ) { return; } @@ -1008,3 +1008,77 @@ void CL_InitInput( void ) { cl_nodelta = Cvar_Get ("cl_nodelta", "0", 0); cl_debugMove = Cvar_Get ("cl_debugMove", "0", 0); } + +/* +============ +CL_ShutdownInput +============ +*/ +void CL_ShutdownInput(void) +{ + Cmd_RemoveCommand("centerview"); + + Cmd_RemoveCommand("+moveup"); + Cmd_RemoveCommand("-moveup"); + Cmd_RemoveCommand("+movedown"); + Cmd_RemoveCommand("-movedown"); + Cmd_RemoveCommand("+left"); + Cmd_RemoveCommand("-left"); + Cmd_RemoveCommand("+right"); + Cmd_RemoveCommand("-right"); + Cmd_RemoveCommand("+forward"); + Cmd_RemoveCommand("-forward"); + Cmd_RemoveCommand("+back"); + Cmd_RemoveCommand("-back"); + Cmd_RemoveCommand("+lookup"); + Cmd_RemoveCommand("-lookup"); + Cmd_RemoveCommand("+lookdown"); + Cmd_RemoveCommand("-lookdown"); + Cmd_RemoveCommand("+strafe"); + Cmd_RemoveCommand("-strafe"); + Cmd_RemoveCommand("+moveleft"); + Cmd_RemoveCommand("-moveleft"); + Cmd_RemoveCommand("+moveright"); + Cmd_RemoveCommand("-moveright"); + Cmd_RemoveCommand("+speed"); + Cmd_RemoveCommand("-speed"); + Cmd_RemoveCommand("+attack"); + Cmd_RemoveCommand("-attack"); + Cmd_RemoveCommand("+button0"); + Cmd_RemoveCommand("-button0"); + Cmd_RemoveCommand("+button1"); + Cmd_RemoveCommand("-button1"); + Cmd_RemoveCommand("+button2"); + Cmd_RemoveCommand("-button2"); + Cmd_RemoveCommand("+button3"); + Cmd_RemoveCommand("-button3"); + Cmd_RemoveCommand("+button4"); + Cmd_RemoveCommand("-button4"); + Cmd_RemoveCommand("+button5"); + Cmd_RemoveCommand("-button5"); + Cmd_RemoveCommand("+button6"); + Cmd_RemoveCommand("-button6"); + Cmd_RemoveCommand("+button7"); + Cmd_RemoveCommand("-button7"); + Cmd_RemoveCommand("+button8"); + Cmd_RemoveCommand("-button8"); + Cmd_RemoveCommand("+button9"); + Cmd_RemoveCommand("-button9"); + Cmd_RemoveCommand("+button10"); + Cmd_RemoveCommand("-button10"); + Cmd_RemoveCommand("+button11"); + Cmd_RemoveCommand("-button11"); + Cmd_RemoveCommand("+button12"); + Cmd_RemoveCommand("-button12"); + Cmd_RemoveCommand("+button13"); + Cmd_RemoveCommand("-button13"); + Cmd_RemoveCommand("+button14"); + Cmd_RemoveCommand("-button14"); + Cmd_RemoveCommand("+mlook"); + Cmd_RemoveCommand("-mlook"); + +#ifdef USE_VOIP + Cmd_RemoveCommand("+voiprecord"); + Cmd_RemoveCommand("-voiprecord"); +#endif +} diff --git a/src/client/cl_keys.c b/src/client/cl_keys.c index 71569fe5..8bd0b654 100644 --- a/src/client/cl_keys.c +++ b/src/client/cl_keys.c @@ -583,7 +583,7 @@ void Console_Key (int key) { // enter finishes the line if ( key == K_ENTER || key == K_KP_ENTER ) { // if not in the game explicitly prepend a slash if needed - if ( cls.state != CA_ACTIVE && + if ( clc.state != CA_ACTIVE && g_consoleField.buffer[0] && g_consoleField.buffer[0] != '\\' && g_consoleField.buffer[0] != '/' ) { @@ -622,7 +622,7 @@ void Console_Key (int key) { CL_SaveConsoleHistory( ); - if ( cls.state == CA_DISCONNECTED ) { + if ( clc.state == CA_DISCONNECTED ) { SCR_UpdateScreen (); // force an update, because the command } // may take some time return; @@ -1148,7 +1148,7 @@ void CL_KeyDownEvent( int key, unsigned time ) // keys can still be used for bound actions if ( ( key < 128 || key == K_MOUSE1 ) && - ( !clc.demoplaying && cls.state == CA_CINEMATIC ) && Key_GetCatcher( ) == 0 ) { + ( clc.demoplaying || clc.state == CA_CINEMATIC ) && Key_GetCatcher( ) == 0 ) { if (Cvar_VariableValue ("com_cameraMode") == 0) { Cvar_Set ("nextdemo",""); @@ -1166,10 +1166,10 @@ void CL_KeyDownEvent( int key, unsigned time ) } if ( !( Key_GetCatcher( ) & KEYCATCH_UI ) ) { - if ( cls.state == CA_ACTIVE && !clc.demoplaying ) { + if ( clc.state == CA_ACTIVE && !clc.demoplaying ) { VM_Call( uivm, UI_SET_ACTIVE_MENU, UIMENU_INGAME ); } - else if ( cls.state != CA_DISCONNECTED ) { + else if ( clc.state != CA_DISCONNECTED ) { CL_Disconnect_f(); S_StopAllSounds(); VM_Call( uivm, UI_SET_ACTIVE_MENU, UIMENU_MAIN ); @@ -1192,7 +1192,7 @@ void CL_KeyDownEvent( int key, unsigned time ) if ( cgvm ) { VM_Call( cgvm, CG_KEY_EVENT, key, qtrue ); } - } else if ( cls.state == CA_DISCONNECTED ) { + } else if ( clc.state == CA_DISCONNECTED ) { Console_Key( key ); } else { // send the bound action @@ -1229,7 +1229,7 @@ void CL_KeyUpEvent( int key, unsigned time ) // console mode and menu mode, to keep the character from continuing // an action started before a mode switch. // - if( cls.state != CA_DISCONNECTED ) + if( clc.state != CA_DISCONNECTED ) CL_ParseBinding( key, qfalse, time ); if ( Key_GetCatcher( ) & KEYCATCH_UI && uivm ) { @@ -1276,7 +1276,7 @@ void CL_CharEvent( int key ) { { VM_Call( uivm, UI_KEY_EVENT, key | K_CHAR_FLAG, qtrue ); } - else if ( cls.state == CA_DISCONNECTED ) + else if ( clc.state == CA_DISCONNECTED ) { Field_CharEvent( &g_consoleField, key ); } diff --git a/src/client/cl_main.c b/src/client/cl_main.c index 296662fc..24043f88 100644 --- a/src/client/cl_main.c +++ b/src/client/cl_main.c @@ -285,7 +285,7 @@ void CL_Voip_f( void ) const char *cmd = Cmd_Argv(1); const char *reason = NULL; - if (cls.state != CA_ACTIVE) + if (clc.state != CA_ACTIVE) reason = "Not connected to a server"; else if (!clc.speexInitialized) reason = "Speex not initialized"; @@ -381,7 +381,7 @@ void CL_CaptureVoip(void) if (cl_voipSend->modified) { qboolean dontCapture = qfalse; - if (cls.state != CA_ACTIVE) + if (clc.state != CA_ACTIVE) dontCapture = qtrue; // not connected to a server. else if (!cl_connectedToVoipServer) dontCapture = qtrue; // server doesn't support VoIP. @@ -675,7 +675,7 @@ void CL_Record_f( void ) { return; } - if ( cls.state != CA_ACTIVE ) { + if ( clc.state != CA_ACTIVE ) { Com_Printf ("You must be in a level to record.\n"); return; } @@ -1061,12 +1061,12 @@ void CL_PlayDemo_f( void ) { Con_Close(); - cls.state = CA_CONNECTED; + clc.state = CA_CONNECTED; clc.demoplaying = qtrue; - Q_strncpyz( cls.servername, Cmd_Argv(1), sizeof( cls.servername ) ); + Q_strncpyz( clc.servername, Cmd_Argv(1), sizeof( clc.servername ) ); // read demo messages until connected - while ( cls.state >= CA_CONNECTED && cls.state < CA_PRIMED ) { + while ( clc.state >= CA_CONNECTED && clc.state < CA_PRIMED ) { CL_ReadDemoMessage(); } // don't get the first snapshot this frame, to prevent the long @@ -1166,7 +1166,13 @@ void CL_DemoName( char *buffer, int size ) { CL_ShutdownAll ===================== */ -void CL_ShutdownAll(void) { +void CL_ShutdownAll(qboolean shutdownRef) +{ + if(CL_VideoRecording()) + CL_CloseAVI(); + + if(clc.demorecording) + CL_StopRecord_f(); #ifdef USE_CURL CL_cURL_Shutdown(); @@ -1179,9 +1185,10 @@ void CL_ShutdownAll(void) { CL_ShutdownUI(); // shutdown the renderer - if ( re.Shutdown ) { - re.Shutdown( qfalse ); // don't destroy window or context - } + if(shutdownRef) + CL_ShutdownRef(); + else if(re.Shutdown) + re.Shutdown(qfalse); // don't destroy window or context cls.uiStarted = qfalse; cls.cgameStarted = qfalse; @@ -1191,17 +1198,15 @@ void CL_ShutdownAll(void) { /* ================= -CL_FlushMemory +CL_ClearMemory -Called by CL_MapLoading, CL_Connect_f, CL_PlayDemo_f, and CL_ParseGamestate the only -ways a client gets into a game -Also called by Com_Error +Called by Com_GameRestart ================= */ -void CL_FlushMemory( void ) { - +void CL_ClearMemory(qboolean shutdownRef) +{ // shutdown all the client stuff - CL_ShutdownAll(); + CL_ShutdownAll(shutdownRef); // if not running a server clear the whole hunk if ( !com_sv_running->integer ) { @@ -1214,8 +1219,21 @@ void CL_FlushMemory( void ) { // clear all the client data on the hunk Hunk_ClearToMark(); } +} - CL_StartHunkUsers( qfalse ); +/* +================= +CL_FlushMemory + +Called by CL_MapLoading, CL_Connect_f, CL_PlayDemo_f, and CL_ParseGamestate the only +ways a client gets into a game +Also called by Com_Error +================= +*/ +void CL_FlushMemory(void) +{ + CL_ClearMemory(qfalse); + CL_StartHunkUsers(qfalse); } /* @@ -1229,7 +1247,7 @@ memory on the hunk from cgame, ui, and renderer */ void CL_MapLoading( void ) { if ( com_dedicated->integer ) { - cls.state = CA_DISCONNECTED; + clc.state = CA_DISCONNECTED; Key_SetCatcher( KEYCATCH_CONSOLE ); return; } @@ -1242,8 +1260,8 @@ void CL_MapLoading( void ) { Key_SetCatcher( 0 ); // if we are already connected to the local host, stay connected - if ( cls.state >= CA_CONNECTED && !Q_stricmp( cls.servername, "localhost" ) ) { - cls.state = CA_CONNECTED; // so the connect screen is drawn + if ( clc.state >= CA_CONNECTED && !Q_stricmp( clc.servername, "localhost" ) ) { + clc.state = CA_CONNECTED; // so the connect screen is drawn Com_Memset( cls.updateInfoString, 0, sizeof( cls.updateInfoString ) ); Com_Memset( clc.serverMessage, 0, sizeof( clc.serverMessage ) ); Com_Memset( &cl.gameState, 0, sizeof( cl.gameState ) ); @@ -1251,12 +1269,12 @@ void CL_MapLoading( void ) { SCR_UpdateScreen(); } else { CL_Disconnect( qtrue ); - Q_strncpyz( cls.servername, "localhost", sizeof(cls.servername) ); - cls.state = CA_CHALLENGING; // so the connect screen is drawn + Q_strncpyz( clc.servername, "localhost", sizeof(clc.servername) ); + clc.state = CA_CHALLENGING; // so the connect screen is drawn Key_SetCatcher( 0 ); SCR_UpdateScreen(); clc.connectTime = -RETRANSMIT_TIMEOUT; - NET_StringToAdr( cls.servername, &clc.serverAddress, NA_UNSPEC); + NET_StringToAdr( clc.servername, &clc.serverAddress, NA_UNSPEC); // we don't need a challenge on the localhost CL_CheckForResend(); @@ -1299,6 +1317,17 @@ static void CL_UpdateGUID( const char *prefix, int prefix_len ) prefix, prefix_len ) ); } +static void CL_OldGame(void) +{ + char *curGame = Cvar_VariableString("fs_game"); + + if(cls.oldGame[0] || *curGame) + { + // change back to previous fs_game + Cvar_Set("fs_game", cls.oldGame); + Com_GameRestart(0, qtrue); + } +} /* ===================== @@ -1373,7 +1402,7 @@ void CL_Disconnect( qboolean showMainMenu ) { // send a disconnect message to the server // send it a few times in case one is dropped - if ( cls.state >= CA_CONNECTED ) { + if ( clc.state >= CA_CONNECTED ) { CL_AddReliableCommand("disconnect", qtrue); CL_WritePacket(); CL_WritePacket(); @@ -1388,7 +1417,7 @@ void CL_Disconnect( qboolean showMainMenu ) { // wipe the client connection Com_Memset( &clc, 0, sizeof( clc ) ); - cls.state = CA_DISCONNECTED; + clc.state = CA_DISCONNECTED; // allow cheats locally Cvar_Set( "sv_cheats", "1" ); @@ -1407,7 +1436,9 @@ void CL_Disconnect( qboolean showMainMenu ) { SCR_UpdateScreen( ); CL_CloseAVI( ); } + CL_UpdateGUID( NULL, 0 ); + CL_OldGame(); } @@ -1430,7 +1461,7 @@ void CL_ForwardCommandToServer( const char *string ) { return; } - if ( clc.demoplaying || cls.state < CA_CONNECTED || cmd[0] == '+' ) { + if ( clc.demoplaying || clc.state < CA_CONNECTED || cmd[0] == '+' ) { Com_Printf ("Unknown command \"%s" S_COLOR_WHITE "\"\n", cmd); return; } @@ -1498,7 +1529,7 @@ CL_ForwardToServer_f ================== */ void CL_ForwardToServer_f( void ) { - if ( cls.state != CA_ACTIVE || clc.demoplaying ) { + if ( clc.state != CA_ACTIVE || clc.demoplaying ) { Com_Printf ("Not connected to a server.\n"); return; } @@ -1517,7 +1548,7 @@ CL_Disconnect_f void CL_Disconnect_f( void ) { SCR_StopCinematic(); Cvar_Set("ui_singlePlayerActive", "0"); - if ( cls.state != CA_DISCONNECTED && cls.state != CA_CINEMATIC ) { + if ( clc.state != CA_DISCONNECTED && clc.state != CA_CINEMATIC ) { Com_Error (ERR_DISCONNECT, "Disconnected from server"); } } @@ -1530,12 +1561,12 @@ CL_Reconnect_f ================ */ void CL_Reconnect_f( void ) { - if ( !strlen( cls.servername ) || !strcmp( cls.servername, "localhost" ) ) { + if ( !strlen( clc.servername ) || !strcmp( clc.servername, "localhost" ) ) { Com_Printf( "Can't reconnect to localhost.\n" ); return; } Cvar_Set("ui_singlePlayerActive", "0"); - Cbuf_AddText( va("connect %s\n", cls.servername ) ); + Cbuf_AddText( va("connect %s\n", clc.servername ) ); } /* @@ -1589,11 +1620,11 @@ void CL_Connect_f( void ) { CL_Disconnect( qtrue ); Con_Close(); - Q_strncpyz( cls.servername, server, sizeof(cls.servername) ); + Q_strncpyz( clc.servername, server, sizeof(clc.servername) ); - if (!NET_StringToAdr(cls.servername, &clc.serverAddress, family) ) { + if (!NET_StringToAdr(clc.servername, &clc.serverAddress, family) ) { Com_Printf ("Bad server address\n"); - cls.state = CA_DISCONNECTED; + clc.state = CA_DISCONNECTED; return; } if (clc.serverAddress.port == 0) { @@ -1602,7 +1633,7 @@ void CL_Connect_f( void ) { serverString = NET_AdrToStringwPort(clc.serverAddress); - Com_Printf( "%s resolved to %s\n", cls.servername, serverString); + Com_Printf( "%s resolved to %s\n", clc.servername, serverString); if( cl_guidServerUniq->integer ) CL_UpdateGUID( serverString, strlen( serverString ) ); @@ -1612,10 +1643,10 @@ void CL_Connect_f( void ) { // if we aren't playing on a lan, we need to authenticate // with the cd key if(NET_IsLocalAddress(clc.serverAddress)) - cls.state = CA_CHALLENGING; + clc.state = CA_CHALLENGING; else { - cls.state = CA_CONNECTING; + clc.state = CA_CONNECTING; // Set a client challenge number that ideally is mirrored back by the server. clc.challenge = ((rand() << 16) ^ rand()) ^ Com_Milliseconds(); @@ -1680,7 +1711,7 @@ void CL_Rcon_f( void ) { // https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=543 Q_strcat (message, MAX_RCON_MESSAGE, Cmd_Cmd()+5); - if ( cls.state >= CA_CONNECTED ) { + if ( clc.state >= CA_CONNECTED ) { to = clc.netchan.remoteAddress; } else { if (!strlen(rconAddress->string)) { @@ -1744,49 +1775,55 @@ void CL_Vid_Restart_f( void ) { // don't let them loop during the restart S_StopAllSounds(); - // shutdown the UI - CL_ShutdownUI(); - // shutdown the CGame - CL_ShutdownCGame(); - // shutdown the renderer and clear the renderer interface - CL_ShutdownRef(); - // client is no longer pure untill new checksums are sent - CL_ResetPureClientAtServer(); - // clear pak references - FS_ClearPakReferences( FS_UI_REF | FS_CGAME_REF ); - // reinitialize the filesystem if the game directory or checksum has changed - FS_ConditionalRestart( clc.checksumFeed ); - cls.rendererStarted = qfalse; - cls.uiStarted = qfalse; - cls.cgameStarted = qfalse; - cls.soundRegistered = qfalse; - - // unpause so the cgame definately gets a snapshot and renders a frame - Cvar_Set( "cl_paused", "0" ); - - // if not running a server clear the whole hunk - if ( !com_sv_running->integer ) { - // clear the whole hunk - Hunk_Clear(); - } - else { - // clear all the client data on the hunk - Hunk_ClearToMark(); - } - - // initialize the renderer interface - CL_InitRef(); - - // startup all the client stuff - CL_StartHunkUsers( qfalse ); - - // start the cgame if connected - if ( cls.state > CA_CONNECTED && cls.state != CA_CINEMATIC ) { - cls.cgameStarted = qtrue; - CL_InitCGame(); - // send pure checksums - CL_SendPureChecksums(); + if(!FS_ConditionalRestart(clc.checksumFeed, qtrue)) + { + // if not running a server clear the whole hunk + if(com_sv_running->integer) + { + // clear all the client data on the hunk + Hunk_ClearToMark(); + } + else + { + // clear the whole hunk + Hunk_Clear(); + } + + // shutdown the UI + CL_ShutdownUI(); + // shutdown the CGame + CL_ShutdownCGame(); + // shutdown the renderer and clear the renderer interface + CL_ShutdownRef(); + // client is no longer pure untill new checksums are sent + CL_ResetPureClientAtServer(); + // clear pak references + FS_ClearPakReferences( FS_UI_REF | FS_CGAME_REF ); + // reinitialize the filesystem if the game directory or checksum has changed + + cls.rendererStarted = qfalse; + cls.uiStarted = qfalse; + cls.cgameStarted = qfalse; + cls.soundRegistered = qfalse; + + // unpause so the cgame definately gets a snapshot and renders a frame + Cvar_Set("cl_paused", "0"); + + // initialize the renderer interface + CL_InitRef(); + + // startup all the client stuff + CL_StartHunkUsers(qfalse); + + // start the cgame if connected + if(clc.state > CA_CONNECTED && clc.state != CA_CINEMATIC) + { + cls.cgameStarted = qtrue; + CL_InitCGame(); + // send pure checksums + CL_SendPureChecksums(); + } } } @@ -1847,7 +1884,7 @@ void CL_Configstrings_f( void ) { int i; int ofs; - if ( cls.state != CA_ACTIVE ) { + if ( clc.state != CA_ACTIVE ) { Com_Printf( "Not connected to a server.\n"); return; } @@ -1868,8 +1905,8 @@ CL_Clientinfo_f */ void CL_Clientinfo_f( void ) { Com_Printf( "--------- Client Information ---------\n" ); - Com_Printf( "state: %i\n", cls.state ); - Com_Printf( "Server: %s\n", cls.servername ); + Com_Printf( "state: %i\n", clc.state ); + Com_Printf( "Server: %s\n", clc.servername ); Com_Printf ("User info settings:\n"); Info_Print( Cvar_InfoString( CVAR_USERINFO ) ); Com_Printf( "--------------------------------------\n" ); @@ -1922,14 +1959,14 @@ void CL_DownloadsComplete( void ) { } // let the client game init and load data - cls.state = CA_LOADING; + clc.state = CA_LOADING; // Pump the loop, this may change gamestate! Com_EventLoop(); // if the gamestate was changed by calling Com_EventLoop // then we loaded everything already and we don't want to do it again. - if ( cls.state != CA_LOADING ) { + if ( clc.state != CA_LOADING ) { return; } @@ -2202,7 +2239,8 @@ void CL_InitDownloads(void) { Com_Printf("Need paks: %s\n", clc.downloadList ); Cvar_Set( "com_downloadPrompt", "0" ); if ( *clc.downloadList ) { - cls.state = CA_CONNECTED; + // if autodownloading is not enabled on the server + clc.state = CA_CONNECTED; *clc.downloadTempName = *clc.downloadName = 0; Cvar_Set( "cl_downloadName", "" ); @@ -2232,7 +2270,7 @@ void CL_CheckForResend( void ) { } // resend if we haven't gotten a reply yet - if ( cls.state != CA_CONNECTING && cls.state != CA_CHALLENGING ) { + if ( clc.state != CA_CONNECTING && clc.state != CA_CHALLENGING ) { return; } @@ -2244,7 +2282,7 @@ void CL_CheckForResend( void ) { clc.connectPacketCount++; - switch ( cls.state ) { + switch ( clc.state ) { case CA_CONNECTING: // requesting a challenge @@ -2282,7 +2320,7 @@ void CL_CheckForResend( void ) { break; default: - Com_Error( ERR_FATAL, "CL_CheckForResend: bad cls.state" ); + Com_Error( ERR_FATAL, "CL_CheckForResend: bad clc.state" ); } } @@ -2297,7 +2335,7 @@ to the client so it doesn't have to wait for the full timeout period. =================== */ void CL_DisconnectPacket( netadr_t from ) { - if ( cls.state < CA_AUTHORIZING ) { + if ( clc.state < CA_AUTHORIZING ) { return; } @@ -2619,7 +2657,7 @@ void CL_ConnectionlessPacket( netadr_t from, msg_t *msg ) { // challenge from the server we are connecting to if (!Q_stricmp(c, "challengeResponse")) { - if (cls.state != CA_CONNECTING) + if (clc.state != CA_CONNECTING) { Com_DPrintf("Unwanted challenge response received. Ignored.\n"); return; @@ -2642,7 +2680,7 @@ void CL_ConnectionlessPacket( netadr_t from, msg_t *msg ) { // start sending challenge response instead of challenge request packets clc.challenge = atoi(Cmd_Argv(1)); - cls.state = CA_CHALLENGING; + clc.state = CA_CHALLENGING; clc.connectPacketCount = 0; clc.connectTime = -99999; @@ -2655,11 +2693,11 @@ void CL_ConnectionlessPacket( netadr_t from, msg_t *msg ) { // server connection if ( !Q_stricmp(c, "connectResponse") ) { - if ( cls.state >= CA_CONNECTED ) { + if ( clc.state >= CA_CONNECTED ) { Com_Printf ("Dup connect received. Ignored.\n"); return; } - if ( cls.state != CA_CHALLENGING ) { + if ( clc.state != CA_CHALLENGING ) { Com_Printf ("connectResponse packet while not connecting. Ignored.\n"); return; } @@ -2668,7 +2706,7 @@ void CL_ConnectionlessPacket( netadr_t from, msg_t *msg ) { return; } Netchan_Setup (NS_CLIENT, &clc.netchan, from, Cvar_VariableValue( "net_qport" ) ); - cls.state = CA_CONNECTED; + clc.state = CA_CONNECTED; clc.lastPacketSentTime = -9999; // send first packet immediately return; } @@ -2750,7 +2788,7 @@ void CL_PacketEvent( netadr_t from, msg_t *msg ) { return; } - if ( cls.state < CA_CONNECTED ) { + if ( clc.state < CA_CONNECTED ) { return; // can't be a valid sequenced packet } @@ -2804,7 +2842,7 @@ void CL_CheckTimeout( void ) { // check timeout // if ( ( !CL_CheckPaused() || !sv_paused->integer ) - && cls.state >= CA_CONNECTED && cls.state != CA_CINEMATIC + && clc.state >= CA_CONNECTED && clc.state != CA_CINEMATIC && cls.realtime - clc.lastPacketTime > cl_timeout->value*1000) { if (++cl.timeoutcount > 5) { // timeoutcount saves debugger Com_Printf ("\nServer connection timed out.\n"); @@ -2843,7 +2881,7 @@ CL_CheckUserinfo */ void CL_CheckUserinfo( void ) { // don't add reliable commands when not yet connected - if(cls.state < CA_CONNECTED) + if(clc.state < CA_CONNECTED) return; // don't overflow the reliable command buffer when paused @@ -2896,7 +2934,7 @@ void CL_Frame ( int msec ) { if(clc.downloadCURLM) { CL_cURL_PerformDownload(); // we can't process frames normally when in disconnected - // download mode since the ui vm expects cls.state to be + // download mode since the ui vm expects clc.state to be // CA_CONNECTED if(clc.cURLDisconnected) { cls.realFrametime = msec; @@ -2911,7 +2949,7 @@ void CL_Frame ( int msec ) { } #endif - if ( cls.state == CA_DISCONNECTED && !( Key_GetCatcher( ) & KEYCATCH_UI ) + if ( clc.state == CA_DISCONNECTED && !( Key_GetCatcher( ) & KEYCATCH_UI ) && !com_sv_running->integer && uivm ) { // if disconnected, bring up the menu S_StopAllSounds(); @@ -2921,7 +2959,7 @@ void CL_Frame ( int msec ) { // if recording an avi, lock to a fixed fps if ( CL_VideoRecording( ) && cl_aviFrameRate->integer && msec) { // save the current screen - if ( cls.state == CA_ACTIVE || cl_forceavidemo->integer) { + if ( clc.state == CA_ACTIVE || cl_forceavidemo->integer) { CL_TakeVideoFrame( ); // fixed time for next frame' @@ -2933,7 +2971,7 @@ void CL_Frame ( int msec ) { } if( cl_autoRecordDemo->integer ) { - if( cls.state == CA_ACTIVE && !clc.demorecording && !clc.demoplaying ) { + if( clc.state == CA_ACTIVE && !clc.demorecording && !clc.demoplaying ) { // If not recording a demo, and we should be, start one qtime_t now; char *nowString; @@ -2950,7 +2988,7 @@ void CL_Frame ( int msec ) { now.tm_min, now.tm_sec ); - Q_strncpyz( serverName, cls.servername, MAX_OSPATH ); + Q_strncpyz( serverName, clc.servername, MAX_OSPATH ); // Replace the ":" in the address as it is not a valid // file name character p = strstr( serverName, ":" ); @@ -2964,7 +3002,7 @@ void CL_Frame ( int msec ) { Cbuf_ExecuteText( EXEC_NOW, va( "record %s-%s-%s", nowString, serverName, mapName ) ); } - else if( cls.state != CA_ACTIVE && clc.demorecording ) { + else if( clc.state != CA_ACTIVE && clc.demorecording ) { // Recording, but not CA_ACTIVE, so stop recording CL_StopRecord_f( ); } @@ -3345,9 +3383,11 @@ void CL_Init( void ) { Con_Init (); - CL_ClearState (); - - cls.state = CA_DISCONNECTED; // no longer CA_UNINITIALIZED + if(!com_fullyInitialized) + { + CL_ClearState(); + clc.state = CA_DISCONNECTED; // no longer CA_UNINITIALIZED + } cls.realtime = 0; @@ -3549,7 +3589,8 @@ CL_Shutdown =============== */ -void CL_Shutdown( char *finalmsg ) { +void CL_Shutdown(char *finalmsg, qboolean disconnect) +{ static qboolean recursive = qfalse; // check whether the client is running at all. @@ -3564,16 +3605,15 @@ void CL_Shutdown( char *finalmsg ) { } recursive = qtrue; - CL_Disconnect( qtrue ); - - CL_Snd_Shutdown(); - CL_ShutdownRef(); + if(disconnect) + CL_Disconnect(qtrue); - CL_ShutdownUI(); + CL_Snd_Shutdown(); + CL_ClearMemory(qtrue); Cmd_RemoveCommand ("cmd"); Cmd_RemoveCommand ("configstrings"); - Cmd_RemoveCommand ("userinfo"); + Cmd_RemoveCommand ("clientinfo"); Cmd_RemoveCommand ("snd_restart"); Cmd_RemoveCommand ("vid_restart"); Cmd_RemoveCommand ("disconnect"); @@ -3582,15 +3622,22 @@ void CL_Shutdown( char *finalmsg ) { Cmd_RemoveCommand ("cinematic"); Cmd_RemoveCommand ("stoprecord"); Cmd_RemoveCommand ("connect"); + Cmd_RemoveCommand ("reconnect"); Cmd_RemoveCommand ("localservers"); Cmd_RemoveCommand ("globalservers"); Cmd_RemoveCommand ("rcon"); Cmd_RemoveCommand ("ping"); Cmd_RemoveCommand ("serverstatus"); Cmd_RemoveCommand ("showip"); + Cmd_RemoveCommand ("fs_openedList"); + Cmd_RemoveCommand ("fs_referencedList"); Cmd_RemoveCommand ("model"); Cmd_RemoveCommand ("video"); Cmd_RemoveCommand ("stopvideo"); + Cmd_RemoveCommand ("minimize"); + + CL_ShutdownInput(); + Con_Shutdown(); Cvar_Set( "cl_running", "0" ); @@ -4366,7 +4413,7 @@ void CL_ServerStatus_f(void) { if ( argc != 2 && argc != 3 ) { - if (cls.state != CA_ACTIVE || clc.demoplaying) + if (clc.state != CA_ACTIVE || clc.demoplaying) { Com_Printf ("Not connected to a server.\n"); Com_Printf( "usage: serverstatus [-4|-6] server\n"); diff --git a/src/client/cl_parse.c b/src/client/cl_parse.c index 5405ebd8..12d2baab 100644 --- a/src/client/cl_parse.c +++ b/src/client/cl_parse.c @@ -460,6 +460,7 @@ void CL_ParseGamestate( msg_t *msg ) { entityState_t nullstate; int cmd; char *s; + char oldGame[MAX_QPATH]; Con_Close(); @@ -515,6 +516,9 @@ void CL_ParseGamestate( msg_t *msg ) { // read the checksum feed clc.checksumFeed = MSG_ReadLong( msg ); + // save old gamedir + Cvar_VariableStringBuffer("fs_game", oldGame, sizeof(oldGame)); + // parse useful values out of CS_SERVERINFO CL_ParseServerInfo(); @@ -526,7 +530,8 @@ void CL_ParseGamestate( msg_t *msg ) { CL_StopRecord_f(); // reinitialize the filesystem if the game directory has changed - FS_ConditionalRestart( clc.checksumFeed ); + if(FS_ConditionalRestart(clc.checksumFeed, qfalse) && !cls.oldGame[0]) + Q_strncpyz(cls.oldGame, oldGame, sizeof(cls.oldGame)); // This used to call CL_StartHunkUsers, but now we enter the download state before loading the // cgame diff --git a/src/client/cl_scrn.c b/src/client/cl_scrn.c index e0c3f7d5..70539317 100644 --- a/src/client/cl_scrn.c +++ b/src/client/cl_scrn.c @@ -341,7 +341,7 @@ void SCR_DrawVoipMeter( void ) { return; // player doesn't want to show meter at all. else if (!cl_voipSend->integer) return; // not recording at the moment. - else if (cls.state != CA_ACTIVE) + else if (clc.state != CA_ACTIVE) return; // not connected to a server. else if (!cl_connectedToVoipServer) return; // server doesn't support VoIP. @@ -469,7 +469,7 @@ void SCR_DrawScreenField( stereoFrame_t stereoFrame ) { // wide aspect ratio screens need to have the sides cleared // unless they are displaying game renderings - if ( uiFullscreen || (cls.state != CA_ACTIVE && cls.state != CA_CINEMATIC) ) { + if ( uiFullscreen || (clc.state != CA_ACTIVE && clc.state != CA_CINEMATIC) ) { if ( cls.glconfig.vidWidth * 480 > cls.glconfig.vidHeight * 640 ) { re.SetColor( g_color_table[0] ); re.DrawStretchPic( 0, 0, cls.glconfig.vidWidth, cls.glconfig.vidHeight, 0, 0, 0, 0, cls.whiteShader ); @@ -480,9 +480,9 @@ void SCR_DrawScreenField( stereoFrame_t stereoFrame ) { // if the menu is going to cover the entire screen, we // don't need to render anything under it if ( uivm && !uiFullscreen ) { - switch( cls.state ) { + switch( clc.state ) { default: - Com_Error( ERR_FATAL, "SCR_DrawScreenField: bad cls.state" ); + Com_Error( ERR_FATAL, "SCR_DrawScreenField: bad clc.state" ); break; case CA_CINEMATIC: SCR_DrawCinematic(); diff --git a/src/client/cl_ui.c b/src/client/cl_ui.c index 8ee5d1b4..faa1237a 100644 --- a/src/client/cl_ui.c +++ b/src/client/cl_ui.c @@ -32,8 +32,8 @@ GetClientState */ static void GetClientState( uiClientState_t *state ) { state->connectPacketCount = clc.connectPacketCount; - state->connState = cls.state; - Q_strncpyz( state->servername, cls.servername, sizeof( state->servername ) ); + state->connState = clc.state; + Q_strncpyz( state->servername, clc.servername, sizeof( state->servername ) ); Q_strncpyz( state->updateInfoString, cls.updateInfoString, sizeof( state->updateInfoString ) ); Q_strncpyz( state->messageString, clc.serverMessage, sizeof( state->messageString ) ); state->clientNum = cl.snap.ps.clientNum; @@ -1103,7 +1103,7 @@ void CL_InitUI( void ) { v = VM_Call( uivm, UI_GETAPIVERSION ); if (v == UI_OLD_API_VERSION) { // init for this gamestate - VM_Call( uivm, UI_INIT, (cls.state >= CA_AUTHORIZING && cls.state < CA_ACTIVE)); + VM_Call( uivm, UI_INIT, (clc.state >= CA_AUTHORIZING && clc.state < CA_ACTIVE)); } else if (v != UI_API_VERSION) { Com_Error( ERR_DROP, "User Interface is version %d, expected %d", v, UI_API_VERSION ); @@ -1111,7 +1111,7 @@ void CL_InitUI( void ) { } else { // init for this gamestate - VM_Call( uivm, UI_INIT, (cls.state >= CA_AUTHORIZING && cls.state < CA_ACTIVE) ); + VM_Call( uivm, UI_INIT, (clc.state >= CA_AUTHORIZING && clc.state < CA_ACTIVE) ); // show where the ui folder was loaded from Cmd_ExecuteString( "which ui/\n" ); diff --git a/src/client/client.h b/src/client/client.h index 26af5072..059167e3 100644 --- a/src/client/client.h +++ b/src/client/client.h @@ -163,10 +163,13 @@ demo through a file. typedef struct { + connstate_t state; // connection status + int clientNum; int lastPacketSentTime; // for retransmits during connection int lastPacketTime; // for timeouts + char servername[MAX_OSPATH]; // name of server from original connect (used by reconnect) netadr_t serverAddress; int connectTime; // for connection retransmits int connectPacketCount; // for display on connection dialog @@ -303,12 +306,8 @@ typedef struct { } serverInfo_t; typedef struct { - connstate_t state; // connection status - qboolean cddialog; // bring up the cd needed dialog next frame - char servername[MAX_OSPATH]; // name of server from original connect (used by reconnect) - // when the server clears the hunk, all of these must be restarted qboolean rendererStarted; qboolean soundStarted; @@ -339,6 +338,8 @@ typedef struct { serverInfo_t favoriteServers[MAX_OTHER_SERVERS]; int pingUpdateSource; // source currently pinging or updating + + char oldGame[MAX_QPATH]; // update server info netadr_t updateServer; @@ -448,8 +449,6 @@ extern cvar_t *cl_voip; // void CL_Init (void); -void CL_FlushMemory(void); -void CL_ShutdownAll(void); void CL_AddReliableCommand(const char *cmd, qboolean isDisconnectCmd); void CL_StartHunkUsers( qboolean rendererOnly ); @@ -499,7 +498,8 @@ extern kbutton_t in_speed; extern kbutton_t in_voiprecord; #endif -void CL_InitInput (void); +void CL_InitInput(void); +void CL_ShutdownInput(void); void CL_SendCmd (void); void CL_ClearState (void); void CL_ReadPackets (void); @@ -543,7 +543,8 @@ qboolean CL_UpdateVisiblePings_f( int source ); void Con_DrawCharacter (int cx, int line, int num); void Con_CheckResize (void); -void Con_Init (void); +void Con_Init(void); +void Con_Shutdown(void); void Con_Clear_f (void); void Con_ToggleConsole_f (void); void Con_DrawNotify (void); diff --git a/src/null/null_client.c b/src/null/null_client.c index 87f72629..cfb35c13 100644 --- a/src/null/null_client.c +++ b/src/null/null_client.c @@ -26,7 +26,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA cvar_t *cl_shownet; -void CL_Shutdown( char *finalmsg ) { +void CL_Shutdown(char *finalmsg, qboolean disconnect) +{ } void CL_Init( void ) { @@ -80,14 +81,21 @@ void CL_InitKeyCommands( void ) { void CL_CDDialog( void ) { } -void CL_FlushMemory( void ) { +void CL_FlushMemory(void) +{ +} + +void CL_ShutdownAll(qboolean shutdownRef) +{ } void CL_StartHunkUsers( qboolean rendererOnly ) { } -void CL_Snd_Shutdown(void) +void CL_InitRef(void) { } -void CL_ShutdownAll(void) {} +void CL_Snd_Shutdown(void) +{ +} diff --git a/src/qcommon/common.c b/src/qcommon/common.c index 9a9ca12d..160501b5 100644 --- a/src/qcommon/common.c +++ b/src/qcommon/common.c @@ -337,7 +337,7 @@ void QDECL Com_Error( int code, const char *fmt, ... ) { longjmp (abortframe, -1); } else { VM_Forced_Unload_Start(); - CL_Shutdown (va("Client fatal crashed: %s", com_errorMessage)); + CL_Shutdown (va("Client fatal crashed: %s", com_errorMessage), qtrue); SV_Shutdown (va("Server fatal crashed: %s", com_errorMessage)); VM_Forced_Unload_Done(); } @@ -362,7 +362,7 @@ void Com_Quit_f( void ) { char *p = Cmd_Args( ); if ( !com_errorEntered ) { SV_Shutdown (p[0] ? p : "Server quit"); - CL_Shutdown (p[0] ? p : "Client quit"); + CL_Shutdown (p[0] ? p : "Client quit", qtrue); Com_Shutdown (); FS_Shutdown(qtrue); } @@ -2385,34 +2385,46 @@ Change to a new mod properly with cleaning up cvars before switching. ================== */ -void Com_GameRestart(int checksumFeed, qboolean clientRestart) +void Com_GameRestart(int checksumFeed, qboolean disconnect) { // make sure no recursion can be triggered if(!com_gameRestarting && com_fullyInitialized) { + int clWasRunning = com_cl_running->integer; + com_gameRestarting = qtrue; - if(clientRestart) - { - CL_Disconnect(qfalse); - CL_ShutdownAll(); - } - // Kill server if we have one if(com_sv_running->integer) SV_Shutdown("Game directory changed"); + if(clWasRunning) + { + if(disconnect) + CL_Disconnect(qfalse); + + CL_Shutdown("Game directory changed", disconnect); + } + FS_Restart(checksumFeed); // Clean out any user and VM created cvars Cvar_Restart(qtrue); Com_ExecuteCfg(); - // shut down sound system before restart - CL_Snd_Shutdown(); - - if(clientRestart) + if(disconnect) + { + // We don't want to change any network settings if gamedir + // change was triggered by a connect to server because the + // new network settings might make the connection fail. + NET_Restart_f(); + } + + if(clWasRunning) + { + CL_Init(); CL_StartHunkUsers(qfalse); + } com_gameRestarting = qfalse; } @@ -2633,6 +2645,7 @@ void Com_Init( char *commandLine ) { com_maxfpsMinimized = Cvar_Get( "com_maxfpsMinimized", "0", CVAR_ARCHIVE ); com_abnormalExit = Cvar_Get( "com_abnormalExit", "0", CVAR_ROM ); com_busyWait = Cvar_Get("com_busyWait", "0", CVAR_ARCHIVE); + Cvar_Get("com_errorMessage", "", CVAR_ROM | CVAR_NORESTART); s = va("%s %s %s", Q3_VERSION, PLATFORM_STRING, __DATE__ ); com_version = Cvar_Get ("version", s, CVAR_ROM | CVAR_SERVERINFO ); diff --git a/src/qcommon/files.c b/src/qcommon/files.c index e2ca20d0..c11e9ba8 100644 --- a/src/qcommon/files.c +++ b/src/qcommon/files.c @@ -3587,19 +3587,16 @@ FS_ConditionalRestart restart if necessary ================= */ -qboolean FS_ConditionalRestart(int checksumFeed) +qboolean FS_ConditionalRestart(int checksumFeed, qboolean disconnect) { if(fs_gamedirvar->modified) { - Com_GameRestart(checksumFeed, qfalse); + Com_GameRestart(checksumFeed, disconnect); return qtrue; } else if(checksumFeed != fs_checksumFeed) - { FS_Restart(checksumFeed); - return qtrue; - } return qfalse; } diff --git a/src/qcommon/qcommon.h b/src/qcommon/qcommon.h index 4b1d48c2..10f548e3 100644 --- a/src/qcommon/qcommon.h +++ b/src/qcommon/qcommon.h @@ -585,7 +585,7 @@ qboolean FS_Initialized( void ); void FS_InitFilesystem ( void ); void FS_Shutdown( qboolean closemfp ); -qboolean FS_ConditionalRestart( int checksumFeed ); +qboolean FS_ConditionalRestart(int checksumFeed, qboolean disconnect); void FS_Restart( int checksumFeed ); // shutdown and restart the filesystem so changes to fs_gamedir can take effect @@ -796,7 +796,7 @@ void QDECL Com_Printf( const char *fmt, ... ) __attribute__ ((format (printf, void QDECL Com_DPrintf( const char *fmt, ... ) __attribute__ ((format (printf, 1, 2))); void QDECL Com_Error( int code, const char *fmt, ... ) __attribute__ ((format (printf, 2, 3))); void Com_Quit_f( void ); -void Com_GameRestart(int checksumFeed, qboolean clientRestart); +void Com_GameRestart(int checksumFeed, qboolean disconnect); int Com_Milliseconds( void ); // will be journaled properly unsigned Com_BlockChecksum( const void *buffer, int length ); @@ -847,6 +847,7 @@ extern int time_backend; // renderer backend time extern int com_frameTime; extern qboolean com_errorEntered; +extern qboolean com_fullyInitialized; extern fileHandle_t com_journalFile; extern fileHandle_t com_journalDataFile; @@ -936,7 +937,7 @@ void CL_InitKeyCommands( void ); void CL_Init( void ); void CL_Disconnect( qboolean showMainMenu ); -void CL_Shutdown( char *finalmsg ); +void CL_Shutdown(char *finalmsg, qboolean disconnect); void CL_Frame( int msec ); qboolean CL_GameCommand( void ); void CL_KeyEvent (int key, qboolean down, unsigned time); @@ -966,12 +967,15 @@ void CL_ForwardCommandToServer( const char *string ); void CL_CDDialog( void ); // bring up the "need a cd to play" dialog -void CL_ShutdownAll( void ); -// shutdown all the client stuff - void CL_FlushMemory( void ); // dump all memory on an error +void CL_ShutdownAll(qboolean shutdownRef); +// shutdown client + +void CL_InitRef(void); +// initialize renderer interface + void CL_StartHunkUsers( qboolean rendererOnly ); // start all the client stuff using the hunk diff --git a/src/sdl/sdl_input.c b/src/sdl/sdl_input.c index a2353490..83b26086 100644 --- a/src/sdl/sdl_input.c +++ b/src/sdl/sdl_input.c @@ -1023,7 +1023,7 @@ void IN_Frame( void ) IN_ProcessEvents( ); // If not DISCONNECTED (main menu) or ACTIVE (in game), we're loading - loading = !!( cls.state != CA_DISCONNECTED && cls.state != CA_ACTIVE ); + loading = !!( clc.state != CA_DISCONNECTED && clc.state != CA_ACTIVE ); cursorShowing = Key_GetCatcher( ) & KEYCATCH_UI; if( !r_fullscreen->integer && ( Key_GetCatcher( ) & KEYCATCH_CONSOLE ) ) diff --git a/src/server/sv_init.c b/src/server/sv_init.c index a723f68c..e29cd2dc 100644 --- a/src/server/sv_init.c +++ b/src/server/sv_init.c @@ -447,7 +447,7 @@ void SV_SpawnServer( char *server, qboolean killBots ) { CL_MapLoading(); // make sure all the client stuff is unloaded - CL_ShutdownAll(); + CL_ShutdownAll(qfalse); // clear the whole hunk because we're (re)loading the server Hunk_Clear(); diff --git a/src/sys/sys_main.c b/src/sys/sys_main.c index 5036009e..8bc5f80f 100644 --- a/src/sys/sys_main.c +++ b/src/sys/sys_main.c @@ -352,7 +352,7 @@ void Sys_Error( const char *error, ... ) Q_vsnprintf (string, sizeof(string), error, argptr); va_end (argptr); - CL_Shutdown( string ); + CL_Shutdown(string, qtrue); Sys_ErrorDialog( string ); Sys_Exit( 3 ); @@ -499,9 +499,9 @@ void Sys_SigHandler( int signal ) { signalcaught = qtrue; #ifndef DEDICATED - CL_Shutdown( va( "Received signal %d", signal ) ); + CL_Shutdown(va("Received signal %d", signal), qtrue); #endif - SV_Shutdown( va( "Received signal %d", signal ) ); + SV_Shutdown(va("Received signal %d", signal) ); } if( signal == SIGTERM || signal == SIGINT ) |