summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThilo Schulz <arny@ats.s.bawue.de>2011-06-21 11:18:35 +0000
committerTim Angus <tim@ngus.net>2013-01-10 21:47:33 +0000
commit555eaebb1b7cb7c4a5e1036892b0effbd62766ae (patch)
tree1038802c3629c85c47a62a5013f2a7271d485bec
parente09392335162f87cd16257506e600268c2cd8ec9 (diff)
- Improve game_restart: * differing screen resolutions and network settings are now honoured when changing fs_game * Fix hunk memory leak on game_restart * Move cls.state and cls.servername to clc so connection state is fully preserved over game_restart * Revert back to previous fs_game after disconnecting from a server that triggered a game_restart * Fix error dialog popping up after every game_restart if an error happened previously (reported by Ensiform) - Fixed that not all commands added by CL_Init() would be removed by CL_Shutdown()
-rw-r--r--src/client/cl_cgame.c14
-rw-r--r--src/client/cl_cin.c21
-rw-r--r--src/client/cl_console.c21
-rw-r--r--src/client/cl_input.c86
-rw-r--r--src/client/cl_keys.c16
-rw-r--r--src/client/cl_main.c277
-rw-r--r--src/client/cl_parse.c7
-rw-r--r--src/client/cl_scrn.c8
-rw-r--r--src/client/cl_ui.c8
-rw-r--r--src/client/client.h17
-rw-r--r--src/null/null_client.c16
-rw-r--r--src/qcommon/common.c39
-rw-r--r--src/qcommon/files.c7
-rw-r--r--src/qcommon/qcommon.h16
-rw-r--r--src/sdl/sdl_input.c2
-rw-r--r--src/server/sv_init.c2
-rw-r--r--src/sys/sys_main.c6
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 )