[quake3-commits] r2045 - in trunk/code: client null qcommon sdl server sys

DONOTREPLY at icculus.org DONOTREPLY at icculus.org
Tue Jun 21 07:18:35 EDT 2011


Author: thilo
Date: 2011-06-21 07:18:35 -0400 (Tue, 21 Jun 2011)
New Revision: 2045

Modified:
   trunk/code/client/cl_cgame.c
   trunk/code/client/cl_cin.c
   trunk/code/client/cl_console.c
   trunk/code/client/cl_input.c
   trunk/code/client/cl_keys.c
   trunk/code/client/cl_main.c
   trunk/code/client/cl_parse.c
   trunk/code/client/cl_scrn.c
   trunk/code/client/cl_ui.c
   trunk/code/client/client.h
   trunk/code/null/null_client.c
   trunk/code/qcommon/common.c
   trunk/code/qcommon/files.c
   trunk/code/qcommon/qcommon.h
   trunk/code/sdl/sdl_input.c
   trunk/code/server/sv_init.c
   trunk/code/sys/sys_main.c
Log:
- 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()


Modified: trunk/code/client/cl_cgame.c
===================================================================
--- trunk/code/client/cl_cgame.c	2011-06-18 14:52:16 UTC (rev 2044)
+++ trunk/code/client/cl_cgame.c	2011-06-21 11:18:35 UTC (rev 2045)
@@ -743,7 +743,7 @@
 	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
@@ -756,7 +756,7 @@
 
 	// 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();
 
@@ -894,7 +894,7 @@
 	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;
@@ -965,8 +965,8 @@
 */
 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 ) {
@@ -982,7 +982,7 @@
 			cl.newSnapshots = qfalse;
 			CL_FirstSnapshot();
 		}
-		if ( cls.state != CA_ACTIVE ) {
+		if ( clc.state != CA_ACTIVE ) {
 			return;
 		}
 	}	
@@ -1095,7 +1095,7 @@
 		// 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
 		}
 	}

Modified: trunk/code/client/cl_cin.c
===================================================================
--- trunk/code/client/cl_cin.c	2011-06-18 14:52:16 UTC (rev 2044)
+++ trunk/code/client/cl_cin.c	2011-06-21 11:18:35 UTC (rev 2045)
@@ -1281,7 +1281,7 @@
 	}
 
 	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
@@ -1314,7 +1314,7 @@
 	}
 
 	if (cinTable[currentHandle].alterGameState) {
-		if ( cls.state != CA_CINEMATIC ) {
+		if ( clc.state != CA_CINEMATIC ) {
 			return cinTable[currentHandle].status;
 		}
 	}
@@ -1355,7 +1355,7 @@
 	currentHandle = handle;
 
 	if (cinTable[currentHandle].alterGameState) {
-		if ( cls.state != CA_CINEMATIC ) {
+		if ( clc.state != CA_CINEMATIC ) {
 			return cinTable[currentHandle].status;
 		}
 	}
@@ -1479,7 +1479,7 @@
 		Com_DPrintf("trFMV::play(), playing %s\n", arg);
 
 		if (cinTable[currentHandle].alterGameState) {
-			cls.state = CA_CINEMATIC;
+			clc.state = CA_CINEMATIC;
 		}
 		
 		Con_Close();
@@ -1614,7 +1614,7 @@
 	int bits = CIN_system;
 
 	Com_DPrintf("CL_PlayCinematic_f\n");
-	if (cls.state == CA_CINEMATIC) {
+	if (clc.state == CA_CINEMATIC) {
 		SCR_StopCinematic();
 	}
 

Modified: trunk/code/client/cl_console.c
===================================================================
--- trunk/code/client/cl_console.c	2011-06-18 14:52:16 UTC (rev 2044)
+++ trunk/code/client/cl_console.c	2011-06-21 11:18:35 UTC (rev 2045)
@@ -72,7 +72,7 @@
 */
 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;
 	}
 
@@ -343,6 +343,21 @@
 	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");
+}
 
 /*
 ===============
@@ -487,7 +502,7 @@
 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;
 	}
 
@@ -704,7 +719,7 @@
 	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;
@@ -715,7 +730,7 @@
 		Con_DrawSolidConsole( con.displayFrac );
 	} else {
 		// draw notify lines
-		if ( cls.state == CA_ACTIVE ) {
+		if ( clc.state == CA_ACTIVE ) {
 			Con_DrawNotify ();
 		}
 	}

Modified: trunk/code/client/cl_input.c
===================================================================
--- trunk/code/client/cl_input.c	2011-06-18 14:52:16 UTC (rev 2044)
+++ trunk/code/client/cl_input.c	2011-06-21 11:18:35 UTC (rev 2045)
@@ -640,7 +640,7 @@
 	int			cmdNum;
 
 	// no need to create usercmds until we have a gamestate
-	if ( cls.state < CA_PRIMED ) {
+	if ( clc.state < CA_PRIMED ) {
 		return;
 	}
 
@@ -677,7 +677,7 @@
 	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;
 	}
 
@@ -689,8 +689,8 @@
 
 	// 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;
@@ -754,7 +754,7 @@
 	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;
 	}
 
@@ -949,7 +949,7 @@
 */
 void CL_SendCmd( void ) {
 	// don't send any message if not connected
-	if ( cls.state < CA_CONNECTED ) {
+	if ( clc.state < CA_CONNECTED ) {
 		return;
 	}
 
@@ -1047,3 +1047,77 @@
 	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
+}

Modified: trunk/code/client/cl_keys.c
===================================================================
--- trunk/code/client/cl_keys.c	2011-06-18 14:52:16 UTC (rev 2044)
+++ trunk/code/client/cl_keys.c	2011-06-21 11:18:35 UTC (rev 2045)
@@ -586,7 +586,7 @@
 	// 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] != '/' ) {
@@ -625,7 +625,7 @@
 
 		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;
@@ -731,7 +731,7 @@
 
 	if ( key == K_ENTER || key == K_KP_ENTER )
 	{
-		if ( chatField.buffer[0] && cls.state == CA_ACTIVE ) {
+		if ( chatField.buffer[0] && clc.state == CA_ACTIVE ) {
 			if (chat_playerNum != -1 )
 
 				Com_sprintf( buffer, sizeof( buffer ), "tell %i \"%s\"\n", chat_playerNum, chatField.buffer );
@@ -1196,7 +1196,7 @@
 
 	// 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","");
@@ -1220,10 +1220,10 @@
 		}
 
 		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 );
@@ -1248,7 +1248,7 @@
 		} 
 	} else if ( Key_GetCatcher( ) & KEYCATCH_MESSAGE ) {
 		Message_Key( key );
-	} else if ( cls.state == CA_DISCONNECTED ) {
+	} else if ( clc.state == CA_DISCONNECTED ) {
 		Console_Key( key );
 	} else {
 		// send the bound action
@@ -1285,7 +1285,7 @@
 	// 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 ) {
@@ -1336,7 +1336,7 @@
 	{
 		Field_CharEvent( &chatField, key );
 	}
-	else if ( cls.state == CA_DISCONNECTED )
+	else if ( clc.state == CA_DISCONNECTED )
 	{
 		Field_CharEvent( &g_consoleField, key );
 	}

Modified: trunk/code/client/cl_main.c
===================================================================
--- trunk/code/client/cl_main.c	2011-06-18 14:52:16 UTC (rev 2044)
+++ trunk/code/client/cl_main.c	2011-06-21 11:18:35 UTC (rev 2045)
@@ -231,7 +231,7 @@
 	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";
@@ -329,7 +329,7 @@
 
 	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.
@@ -623,7 +623,7 @@
 		return;
 	}
 
-	if ( cls.state != CA_ACTIVE ) {
+	if ( clc.state != CA_ACTIVE ) {
 		Com_Printf ("You must be in a level to record.\n");
 		return;
 	}
@@ -1009,12 +1009,12 @@
 
 	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
@@ -1068,8 +1068,14 @@
 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();
 #endif
@@ -1081,9 +1087,10 @@
 	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;
@@ -1093,17 +1100,15 @@
 
 /*
 =================
-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 ) {
@@ -1116,8 +1121,21 @@
 		// 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);
 }
 
 /*
@@ -1131,7 +1149,7 @@
 */
 void CL_MapLoading( void ) {
 	if ( com_dedicated->integer ) {
-		cls.state = CA_DISCONNECTED;
+		clc.state = CA_DISCONNECTED;
 		Key_SetCatcher( KEYCATCH_CONSOLE );
 		return;
 	}
@@ -1144,8 +1162,8 @@
 	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 ) );
@@ -1155,12 +1173,12 @@
 		// clear nextmap so the cinematic shutdown doesn't execute it
 		Cvar_Set( "nextmap", "" );
 		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();
@@ -1203,6 +1221,17 @@
 			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);
+	}
+}
 
 /*
 =====================
@@ -1277,7 +1306,7 @@
 
 	// 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();
@@ -1292,7 +1321,7 @@
 	// 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" );
@@ -1311,7 +1340,9 @@
 		SCR_UpdateScreen( );
 		CL_CloseAVI( );
 	}
+
 	CL_UpdateGUID( NULL, 0 );
+	CL_OldGame();
 }
 
 
@@ -1334,7 +1365,7 @@
 		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;
 	}
@@ -1477,7 +1508,7 @@
 ==================
 */
 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;
 	}
@@ -1496,7 +1527,7 @@
 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");
 	}
 }
@@ -1509,12 +1540,12 @@
 ================
 */
 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 ) );
 }
 
 /*
@@ -1568,11 +1599,11 @@
 	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) {
@@ -1581,7 +1612,7 @@
 
 	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 ) );
@@ -1591,10 +1622,10 @@
 	// 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();
@@ -1659,7 +1690,7 @@
 	// 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)) {
@@ -1723,49 +1754,55 @@
 
 	// 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;
+	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
 
-	// unpause so the cgame definately gets a snapshot and renders a frame
-	Cvar_Set( "cl_paused", "0" );
+		cls.rendererStarted = qfalse;
+		cls.uiStarted = qfalse;
+		cls.cgameStarted = qfalse;
+		cls.soundRegistered = qfalse;
 
-	// 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();
-	}
+		// unpause so the cgame definately gets a snapshot and renders a frame
+		Cvar_Set("cl_paused", "0");
 
-	// initialize the renderer interface
-	CL_InitRef();
+		// initialize the renderer interface
+		CL_InitRef();
 
-	// startup all the client stuff
-	CL_StartHunkUsers( qfalse );
+		// 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();
+		// start the cgame if connected
+		if(clc.state > CA_CONNECTED && clc.state != CA_CINEMATIC)
+		{
+			cls.cgameStarted = qtrue;
+			CL_InitCGame();
+			// send pure checksums
+			CL_SendPureChecksums();
+		}
 	}
 }
 
@@ -1826,7 +1863,7 @@
 	int		i;
 	int		ofs;
 
-	if ( cls.state != CA_ACTIVE ) {
+	if ( clc.state != CA_ACTIVE ) {
 		Com_Printf( "Not connected to a server.\n");
 		return;
 	}
@@ -1847,8 +1884,8 @@
 */
 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" );
@@ -1898,14 +1935,14 @@
 	}
 
 	// 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;
 	}
 
@@ -2091,7 +2128,7 @@
 
 		if ( *clc.downloadList ) {
 			// if autodownloading is not enabled on the server
-			cls.state = CA_CONNECTED;
+			clc.state = CA_CONNECTED;
 
 			*clc.downloadTempName = *clc.downloadName = 0;
 			Cvar_Set( "cl_downloadName", "" );
@@ -2123,7 +2160,7 @@
 	}
 
 	// 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;
 	}
 
@@ -2135,7 +2172,7 @@
 	clc.connectPacketCount++;
 
 
-	switch ( cls.state ) {
+	switch ( clc.state ) {
 	case CA_CONNECTING:
 		// requesting a challenge .. IPv6 users always get in as authorize server supports no ipv6.
 #ifndef STANDALONE
@@ -2177,7 +2214,7 @@
 		break;
 
 	default:
-		Com_Error( ERR_FATAL, "CL_CheckForResend: bad cls.state" );
+		Com_Error( ERR_FATAL, "CL_CheckForResend: bad clc.state" );
 	}
 }
 
@@ -2192,7 +2229,7 @@
 ===================
 */
 void CL_DisconnectPacket( netadr_t from ) {
-	if ( cls.state < CA_AUTHORIZING ) {
+	if ( clc.state < CA_AUTHORIZING ) {
 		return;
 	}
 
@@ -2410,7 +2447,7 @@
 	// 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;
@@ -2433,7 +2470,7 @@
 
 		// 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;
 
@@ -2446,11 +2483,11 @@
 
 	// 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;
 		}
@@ -2459,7 +2496,7 @@
 			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;
 	}
@@ -2542,7 +2579,7 @@
 		return;
 	}
 
-	if ( cls.state < CA_CONNECTED ) {
+	if ( clc.state < CA_CONNECTED ) {
 		return;		// can't be a valid sequenced packet
 	}
 
@@ -2596,7 +2633,7 @@
 	// 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");
@@ -2635,7 +2672,7 @@
 */
 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
@@ -2666,7 +2703,7 @@
 	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;
@@ -2685,7 +2722,7 @@
 		// bring up the cd error dialog if needed
 		cls.cddialog = qfalse;
 		VM_Call( uivm, UI_SET_ACTIVE_MENU, UIMENU_NEED_CD );
-	} else	if ( cls.state == CA_DISCONNECTED && !( Key_GetCatcher( ) & KEYCATCH_UI )
+	} else	if ( clc.state == CA_DISCONNECTED && !( Key_GetCatcher( ) & KEYCATCH_UI )
 		&& !com_sv_running->integer && uivm ) {
 		// if disconnected, bring up the menu
 		S_StopAllSounds();
@@ -2695,7 +2732,7 @@
 	// 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'
@@ -2707,7 +2744,7 @@
 	}
 	
 	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;
@@ -2724,7 +2761,7 @@
 					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, ":" );
@@ -2738,7 +2775,7 @@
 			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( );
 		}
@@ -3119,10 +3156,12 @@
 
 	Con_Init ();
 
-	CL_ClearState ();
+	if(!com_fullyInitialized)
+	{
+		CL_ClearState();
+		clc.state = CA_DISCONNECTED;	// no longer CA_UNINITIALIZED
+	}
 
-	cls.state = CA_DISCONNECTED;	// no longer CA_UNINITIALIZED
-
 	cls.realtime = 0;
 
 	CL_InitInput ();
@@ -3334,7 +3373,8 @@
 
 ===============
 */
-void CL_Shutdown( char *finalmsg ) {
+void CL_Shutdown(char *finalmsg, qboolean disconnect)
+{
 	static qboolean recursive = qfalse;
 	
 	// check whether the client is running at all.
@@ -3349,16 +3389,15 @@
 	}
 	recursive = qtrue;
 
-	CL_Disconnect( qtrue );
-
+	if(disconnect)
+		CL_Disconnect(qtrue);
+	
 	CL_Snd_Shutdown();
-	CL_ShutdownRef();
-	
-	CL_ShutdownUI();
+	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");
@@ -3367,16 +3406,23 @@
 	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" );
 
 	recursive = qfalse;
@@ -4168,7 +4214,7 @@
 
 	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");

Modified: trunk/code/client/cl_parse.c
===================================================================
--- trunk/code/client/cl_parse.c	2011-06-18 14:52:16 UTC (rev 2044)
+++ trunk/code/client/cl_parse.c	2011-06-21 11:18:35 UTC (rev 2045)
@@ -463,6 +463,7 @@
 	entityState_t	nullstate;
 	int				cmd;
 	char			*s;
+	char oldGame[MAX_QPATH];
 
 	Con_Close();
 
@@ -518,6 +519,9 @@
 	// 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();
 
@@ -529,7 +533,8 @@
 		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

Modified: trunk/code/client/cl_scrn.c
===================================================================
--- trunk/code/client/cl_scrn.c	2011-06-18 14:52:16 UTC (rev 2044)
+++ trunk/code/client/cl_scrn.c	2011-06-21 11:18:35 UTC (rev 2045)
@@ -360,7 +360,7 @@
 		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.
@@ -488,7 +488,7 @@
 
 	// 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 );
@@ -499,9 +499,9 @@
 	// 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();

Modified: trunk/code/client/cl_ui.c
===================================================================
--- trunk/code/client/cl_ui.c	2011-06-18 14:52:16 UTC (rev 2044)
+++ trunk/code/client/cl_ui.c	2011-06-21 11:18:35 UTC (rev 2045)
@@ -35,8 +35,8 @@
 */
 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;
@@ -1115,7 +1115,7 @@
 	if (v == UI_OLD_API_VERSION) {
 //		Com_Printf(S_COLOR_YELLOW "WARNING: loading old Quake III Arena User Interface version %d\n", v );
 		// 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 );
@@ -1123,7 +1123,7 @@
 	}
 	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) );
 	}
 }
 

Modified: trunk/code/client/client.h
===================================================================
--- trunk/code/client/client.h	2011-06-18 14:52:16 UTC (rev 2044)
+++ trunk/code/client/client.h	2011-06-21 11:18:35 UTC (rev 2045)
@@ -162,10 +162,13 @@
 
 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
@@ -301,12 +304,8 @@
 } 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;
@@ -333,6 +332,8 @@
 	serverInfo_t	favoriteServers[MAX_OTHER_SERVERS];
 
 	int pingUpdateSource;		// source currently pinging or updating
+	
+	char		oldGame[MAX_QPATH];
 
 	// update server info
 	netadr_t	updateServer;
@@ -442,8 +443,6 @@
 //
 
 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 );
@@ -491,7 +490,8 @@
 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);
@@ -535,7 +535,8 @@
 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);

Modified: trunk/code/null/null_client.c
===================================================================
--- trunk/code/null/null_client.c	2011-06-18 14:52:16 UTC (rev 2044)
+++ trunk/code/null/null_client.c	2011-06-21 11:18:35 UTC (rev 2045)
@@ -25,7 +25,8 @@
 
 cvar_t *cl_shownet;
 
-void CL_Shutdown( char *finalmsg ) {
+void CL_Shutdown(char *finalmsg, qboolean disconnect)
+{
 }
 
 void CL_Init( void ) {
@@ -79,16 +80,23 @@
 void CL_CDDialog( void ) {
 }
 
-void CL_FlushMemory( void ) {
+void CL_FlushMemory(void)
+{
 }
 
+void CL_ShutdownAll(qboolean shutdownRef)
+{
+}
+
 void CL_StartHunkUsers( qboolean rendererOnly ) {
 }
 
+void CL_InitRef(void)
+{
+}
+
 void CL_Snd_Shutdown(void)
 {
 }
 
-void CL_ShutdownAll(void) {}
-
 qboolean CL_CDKeyValidate( const char *key, const char *checksum ) { return qtrue; }

Modified: trunk/code/qcommon/common.c
===================================================================
--- trunk/code/qcommon/common.c	2011-06-18 14:52:16 UTC (rev 2044)
+++ trunk/code/qcommon/common.c	2011-06-21 11:18:35 UTC (rev 2045)
@@ -338,7 +338,7 @@
 		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();
 	}
@@ -363,7 +363,7 @@
 	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);
 	}
@@ -2386,34 +2386,46 @@
 ==================
 */
 
-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;
 	}
@@ -2761,6 +2773,7 @@
 	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);
 
 	com_introPlayed = Cvar_Get( "com_introplayed", "0", CVAR_ARCHIVE);
 

Modified: trunk/code/qcommon/files.c
===================================================================
--- trunk/code/qcommon/files.c	2011-06-18 14:52:16 UTC (rev 2044)
+++ trunk/code/qcommon/files.c	2011-06-21 11:18:35 UTC (rev 2045)
@@ -3875,19 +3875,16 @@
 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;
 }

Modified: trunk/code/qcommon/qcommon.h
===================================================================
--- trunk/code/qcommon/qcommon.h	2011-06-18 14:52:16 UTC (rev 2044)
+++ trunk/code/qcommon/qcommon.h	2011-06-21 11:18:35 UTC (rev 2045)
@@ -597,7 +597,7 @@
 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
 
@@ -813,7 +813,7 @@
 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 );
@@ -868,6 +868,7 @@
 extern	int		com_frameTime;
 
 extern	qboolean	com_errorEntered;
+extern	qboolean	com_fullyInitialized;
 
 extern	fileHandle_t	com_journalFile;
 extern	fileHandle_t	com_journalDataFile;
@@ -957,7 +958,7 @@
 
 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);
@@ -987,12 +988,15 @@
 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
 

Modified: trunk/code/sdl/sdl_input.c
===================================================================
--- trunk/code/sdl/sdl_input.c	2011-06-18 14:52:16 UTC (rev 2044)
+++ trunk/code/sdl/sdl_input.c	2011-06-21 11:18:35 UTC (rev 2045)
@@ -973,7 +973,7 @@
 	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 );
 
 	if( !r_fullscreen->integer && ( Key_GetCatcher( ) & KEYCATCH_CONSOLE ) )
 	{

Modified: trunk/code/server/sv_init.c
===================================================================
--- trunk/code/server/sv_init.c	2011-06-18 14:52:16 UTC (rev 2044)
+++ trunk/code/server/sv_init.c	2011-06-21 11:18:35 UTC (rev 2045)
@@ -417,7 +417,7 @@
 	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();

Modified: trunk/code/sys/sys_main.c
===================================================================
--- trunk/code/sys/sys_main.c	2011-06-18 14:52:16 UTC (rev 2044)
+++ trunk/code/sys/sys_main.c	2011-06-21 11:18:35 UTC (rev 2045)
@@ -351,7 +351,7 @@
 	Q_vsnprintf (string, sizeof(string), error, argptr);
 	va_end (argptr);
 
-	CL_Shutdown( string );
+	CL_Shutdown(string, qtrue);
 	Sys_ErrorDialog( string );
 
 	Sys_Exit( 3 );
@@ -498,9 +498,9 @@
 	{
 		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 )



More information about the quake3-commits mailing list