2 ===========================================================================
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
26 ===========================================================================
29 #include "../idlib/precompiled.h"
32 #include "../renderer/Image.h"
34 #define MAX_PRINT_MSG_SIZE 4096
35 #define MAX_WARNING_LIST 256
39 ERP_FATAL, // exit the entire game with a popup window
40 ERP_DROP, // print to console and disconnect from game
41 ERP_DISCONNECT // don't kill server
45 #define BUILD_DEBUG "-debug"
47 #define BUILD_DEBUG ""
51 version_s( void ) { sprintf( string, "%s.%d%s %s %s %s", ENGINE_VERSION, BUILD_NUMBER, BUILD_DEBUG, BUILD_STRING, __DATE__, __TIME__ ); }
55 idCVar com_version( "si_version", version.string, CVAR_SYSTEM|CVAR_ROM|CVAR_SERVERINFO, "engine version" );
56 idCVar com_skipRenderer( "com_skipRenderer", "0", CVAR_BOOL|CVAR_SYSTEM, "skip the renderer completely" );
57 idCVar com_machineSpec( "com_machineSpec", "-1", CVAR_INTEGER | CVAR_ARCHIVE | CVAR_SYSTEM, "hardware classification, -1 = not detected, 0 = low quality, 1 = medium quality, 2 = high quality, 3 = ultra quality" );
58 idCVar com_purgeAll( "com_purgeAll", "0", CVAR_BOOL | CVAR_ARCHIVE | CVAR_SYSTEM, "purge everything between level loads" );
59 idCVar com_memoryMarker( "com_memoryMarker", "-1", CVAR_INTEGER | CVAR_SYSTEM | CVAR_INIT, "used as a marker for memory stats" );
60 idCVar com_preciseTic( "com_preciseTic", "1", CVAR_BOOL|CVAR_SYSTEM, "run one game tick every async thread update" );
61 idCVar com_asyncInput( "com_asyncInput", "0", CVAR_BOOL|CVAR_SYSTEM, "sample input from the async thread" );
62 #define ASYNCSOUND_INFO "0: mix sound inline, 1: memory mapped async mix, 2: callback mixing, 3: write async mix"
63 #if defined( MACOS_X )
64 idCVar com_asyncSound( "com_asyncSound", "2", CVAR_INTEGER|CVAR_SYSTEM|CVAR_ROM, ASYNCSOUND_INFO );
65 #elif defined( __linux__ )
66 idCVar com_asyncSound( "com_asyncSound", "3", CVAR_INTEGER|CVAR_SYSTEM|CVAR_ROM, ASYNCSOUND_INFO );
68 idCVar com_asyncSound( "com_asyncSound", "1", CVAR_INTEGER|CVAR_SYSTEM, ASYNCSOUND_INFO, 0, 1 );
70 idCVar com_forceGenericSIMD( "com_forceGenericSIMD", "0", CVAR_BOOL | CVAR_SYSTEM | CVAR_NOCHEAT, "force generic platform independent SIMD" );
71 idCVar com_developer( "developer", "0", CVAR_BOOL|CVAR_SYSTEM|CVAR_NOCHEAT, "developer mode" );
72 idCVar com_allowConsole( "com_allowConsole", "0", CVAR_BOOL | CVAR_SYSTEM | CVAR_NOCHEAT, "allow toggling console with the tilde key" );
73 idCVar com_speeds( "com_speeds", "0", CVAR_BOOL|CVAR_SYSTEM|CVAR_NOCHEAT, "show engine timings" );
74 idCVar com_showFPS( "com_showFPS", "0", CVAR_BOOL|CVAR_SYSTEM|CVAR_ARCHIVE|CVAR_NOCHEAT, "show frames rendered per second" );
75 idCVar com_showMemoryUsage( "com_showMemoryUsage", "0", CVAR_BOOL|CVAR_SYSTEM|CVAR_NOCHEAT, "show total and per frame memory usage" );
76 idCVar com_showAsyncStats( "com_showAsyncStats", "0", CVAR_BOOL|CVAR_SYSTEM|CVAR_NOCHEAT, "show async network stats" );
77 idCVar com_showSoundDecoders( "com_showSoundDecoders", "0", CVAR_BOOL|CVAR_SYSTEM|CVAR_NOCHEAT, "show sound decoders" );
78 idCVar com_timestampPrints( "com_timestampPrints", "0", CVAR_SYSTEM, "print time with each console print, 1 = msec, 2 = sec", 0, 2, idCmdSystem::ArgCompletion_Integer<0,2> );
79 idCVar com_timescale( "timescale", "1", CVAR_SYSTEM | CVAR_FLOAT, "scales the time", 0.1f, 10.0f );
80 idCVar com_logFile( "logFile", "0", CVAR_SYSTEM | CVAR_NOCHEAT, "1 = buffer log, 2 = flush after each print", 0, 2, idCmdSystem::ArgCompletion_Integer<0,2> );
81 idCVar com_logFileName( "logFileName", "qconsole.log", CVAR_SYSTEM | CVAR_NOCHEAT, "name of log file, if empty, qconsole.log will be used" );
82 idCVar com_makingBuild( "com_makingBuild", "0", CVAR_BOOL | CVAR_SYSTEM, "1 when making a build" );
83 idCVar com_updateLoadSize( "com_updateLoadSize", "0", CVAR_BOOL | CVAR_SYSTEM | CVAR_NOCHEAT, "update the load size after loading a map" );
84 idCVar com_videoRam( "com_videoRam", "64", CVAR_INTEGER | CVAR_SYSTEM | CVAR_NOCHEAT | CVAR_ARCHIVE, "holds the last amount of detected video ram" );
86 idCVar com_product_lang_ext( "com_product_lang_ext", "1", CVAR_INTEGER | CVAR_SYSTEM | CVAR_ARCHIVE, "Extension to use when creating language files." );
91 int time_frontend; // renderSystem frontend time
92 int time_backend; // renderSystem backend time
94 int com_frameTime; // time for the current frame in milliseconds
95 int com_frameNumber; // variable frame number
96 volatile int com_ticNumber; // 60 hz tics
97 int com_editors; // currently opened editor(s)
98 bool com_editorActive; // true if an editor has focus
101 HWND com_hwndMsg = NULL;
102 bool com_outputMsg = false;
103 unsigned int com_msgID = -1;
107 idGame * game = NULL;
108 idGameEdit * gameEdit = NULL;
111 // writes si_version to the config file - in a kinda obfuscated way
112 //#define ID_WRITE_VERSION
114 class idCommonLocal : public idCommon {
116 idCommonLocal( void );
118 virtual void Init( int argc, const char **argv, const char *cmdline );
119 virtual void Shutdown( void );
120 virtual void Quit( void );
121 virtual bool IsInitialized( void ) const;
122 virtual void Frame( void );
123 virtual void GUIFrame( bool execCmd, bool network );
124 virtual void Async( void );
125 virtual void StartupVariable( const char *match, bool once );
126 virtual void InitTool( const toolFlag_t tool, const idDict *dict );
127 virtual void ActivateTool( bool active );
128 virtual void WriteConfigToFile( const char *filename );
129 virtual void WriteFlaggedCVarsToFile( const char *filename, int flags, const char *setCmd );
130 virtual void BeginRedirect( char *buffer, int buffersize, void (*flush)( const char * ) );
131 virtual void EndRedirect( void );
132 virtual void SetRefreshOnPrint( bool set );
133 virtual void Printf( const char *fmt, ... ) id_attribute((format(printf,2,3)));
134 virtual void VPrintf( const char *fmt, va_list arg );
135 virtual void DPrintf( const char *fmt, ... ) id_attribute((format(printf,2,3)));
136 virtual void Warning( const char *fmt, ... ) id_attribute((format(printf,2,3)));
137 virtual void DWarning( const char *fmt, ...) id_attribute((format(printf,2,3)));
138 virtual void PrintWarnings( void );
139 virtual void ClearWarnings( const char *reason );
140 virtual void Error( const char *fmt, ... ) id_attribute((format(printf,2,3)));
141 virtual void FatalError( const char *fmt, ... ) id_attribute((format(printf,2,3)));
142 virtual const idLangDict * GetLanguageDict( void );
144 virtual const char * KeysFromBinding( const char *bind );
145 virtual const char * BindingFromKey( const char *key );
147 virtual int ButtonState( int key );
148 virtual int KeyState( int key );
150 void InitGame( void );
151 void ShutdownGame( bool reloading );
154 void InitLanguageDict( void );
155 void LocalizeGui( const char *fileName, idLangDict &langDict );
156 void LocalizeMapData( const char *fileName, idLangDict &langDict );
157 void LocalizeSpecificMapData( const char *fileName, idLangDict &langDict, const idLangDict &replaceArgs );
159 void SetMachineSpec( void );
162 void InitCommands( void );
163 void InitRenderSystem( void );
164 void InitSIMD( void );
165 bool AddStartupCommands( void );
166 void ParseCommandLine( int argc, const char **argv );
167 void ClearCommandLine( void );
168 bool SafeMode( void );
169 void CheckToolMode( void );
170 void CloseLogFile( void );
171 void WriteConfiguration( void );
172 void DumpWarnings( void );
173 void SingleAsyncTic( void );
174 void LoadGameDLL( void );
175 void UnloadGameDLL( void );
176 void PrintLoadingMessage( const char *msg );
177 void FilterLangList( idStrList* list, idStr lang );
179 bool com_fullyInitialized;
180 bool com_refreshOnPrint; // update the screen every print for dmap
181 int com_errorEntered; // 0, ERP_DROP, etc
182 bool com_shuttingDown;
186 char errorMessage[MAX_PRINT_MSG_SIZE];
190 void (*rd_flush)( const char *buffer );
192 idStr warningCaption;
193 idStrList warningList;
198 idLangDict languageDict;
200 #ifdef ID_WRITE_VERSION
201 idCompressor * config_compressor;
205 idCommonLocal commonLocal;
206 idCommon * common = &commonLocal;
211 idCommonLocal::idCommonLocal
214 idCommonLocal::idCommonLocal( void ) {
215 com_fullyInitialized = false;
216 com_refreshOnPrint = false;
217 com_errorEntered = 0;
218 com_shuttingDown = false;
222 strcpy( errorMessage, "" );
230 #ifdef ID_WRITE_VERSION
231 config_compressor = NULL;
237 idCommonLocal::BeginRedirect
240 void idCommonLocal::BeginRedirect( char *buffer, int buffersize, void (*flush)( const char *) ) {
241 if ( !buffer || !buffersize || !flush ) {
245 rd_buffersize = buffersize;
253 idCommonLocal::EndRedirect
256 void idCommonLocal::EndRedirect( void ) {
257 if ( rd_flush && rd_buffer[ 0 ] ) {
258 rd_flush( rd_buffer );
273 BOOL CALLBACK EnumWindowsProc( HWND hwnd, LPARAM lParam ) {
276 ::GetWindowText( hwnd, buff, sizeof( buff ) );
277 if ( idStr::Icmpn( buff, EDITOR_WINDOWTEXT, strlen( EDITOR_WINDOWTEXT ) ) == 0 ) {
289 bool FindEditor( void ) {
291 EnumWindows( EnumWindowsProc, 0 );
292 return !( com_hwndMsg == NULL );
299 idCommonLocal::CloseLogFile
302 void idCommonLocal::CloseLogFile( void ) {
304 com_logFile.SetBool( false ); // make sure no further VPrintf attempts to open the log file again
305 fileSystem->CloseFile( logFile );
312 idCommonLocal::SetRefreshOnPrint
315 void idCommonLocal::SetRefreshOnPrint( bool set ) {
316 com_refreshOnPrint = set;
321 idCommonLocal::VPrintf
323 A raw string should NEVER be passed as fmt, because of "%f" type crashes.
326 void idCommonLocal::VPrintf( const char *fmt, va_list args ) {
327 char msg[MAX_PRINT_MSG_SIZE];
329 static bool logFileFailed = false;
331 // if the cvar system is not initialized
332 if ( !cvarSystem->IsInitialized() ) {
336 // optionally put a timestamp at the beginning of each print,
337 // so we can see how long different init sections are taking
338 if ( com_timestampPrints.GetInteger() ) {
339 int t = Sys_Milliseconds();
340 if ( com_timestampPrints.GetInteger() == 1 ) {
343 sprintf( msg, "[%i]", t );
344 timeLength = strlen( msg );
350 if ( idStr::vsnPrintf( msg+timeLength, MAX_PRINT_MSG_SIZE-timeLength-1, fmt, args ) < 0 ) {
351 msg[sizeof(msg)-2] = '\n'; msg[sizeof(msg)-1] = '\0'; // avoid output garbling
352 Sys_Printf( "idCommon::VPrintf: truncated to %d characters\n", strlen(msg)-1 );
356 if ( (int)( strlen( msg ) + strlen( rd_buffer ) ) > ( rd_buffersize - 1 ) ) {
357 rd_flush( rd_buffer );
360 strcat( rd_buffer, msg );
364 // echo to console buffer
365 console->Print( msg );
367 // remove any color codes
368 idStr::RemoveColors( msg );
370 // echo to dedicated console and early console
371 Sys_Printf( "%s", msg );
373 // print to script debugger server
374 // DebuggerServerPrint( msg );
377 #if defined(_DEBUG) && defined(WIN32)
378 if ( strlen( msg ) < 512 ) {
385 if ( com_logFile.GetInteger() && !logFileFailed && fileSystem->IsInitialized() ) {
386 static bool recursing;
388 if ( !logFile && !recursing ) {
391 const char *fileName = com_logFileName.GetString()[0] ? com_logFileName.GetString() : "qconsole.log";
393 // fileSystem->OpenFileWrite can cause recursive prints into here
396 logFile = fileSystem->OpenFileWrite( fileName );
398 logFileFailed = true;
399 FatalError( "failed to open log file '%s'\n", fileName );
404 if ( com_logFile.GetInteger() > 1 ) {
405 // force it to not buffer so we get valid
406 // data even if we are crashing
407 logFile->ForceFlush();
411 newtime = localtime( &aclock );
412 Printf( "log file '%s' opened on %s\n", fileName, asctime( newtime ) );
415 logFile->Write( msg, strlen( msg ) );
416 logFile->Flush(); // ForceFlush doesn't help a whole lot
420 // don't trigger any updates if we are in the process of doing a fatal error
421 if ( com_errorEntered != ERP_FATAL ) {
422 // update the console if we are in a long-running command, like dmap
423 if ( com_refreshOnPrint ) {
424 session->UpdateScreen();
427 // let session redraw the animated loading screen if necessary
428 session->PacifierUpdate();
433 if ( com_outputMsg ) {
434 if ( com_msgID == -1 ) {
435 com_msgID = ::RegisterWindowMessage( DMAP_MSGID );
436 if ( !FindEditor() ) {
437 com_outputMsg = false;
439 Sys_ShowWindow( false );
443 ATOM atom = ::GlobalAddAtom( msg );
444 ::PostMessage( com_hwndMsg, com_msgID, 0, static_cast<LPARAM>(atom) );
453 idCommonLocal::Printf
455 Both client and server can use this, and it will output to the appropriate place.
457 A raw string should NEVER be passed as fmt, because of "%f" type crashers.
460 void idCommonLocal::Printf( const char *fmt, ... ) {
462 va_start( argptr, fmt );
463 VPrintf( fmt, argptr );
469 idCommonLocal::DPrintf
471 prints message that only shows up if the "developer" cvar is set
474 void idCommonLocal::DPrintf( const char *fmt, ... ) {
476 char msg[MAX_PRINT_MSG_SIZE];
478 if ( !cvarSystem->IsInitialized() || !com_developer.GetBool() ) {
479 return; // don't confuse non-developers with techie stuff...
482 va_start( argptr, fmt );
483 idStr::vsnPrintf( msg, sizeof(msg), fmt, argptr );
485 msg[sizeof(msg)-1] = '\0';
487 // never refresh the screen, which could cause reentrency problems
488 bool temp = com_refreshOnPrint;
489 com_refreshOnPrint = false;
491 Printf( S_COLOR_RED"%s", msg );
493 com_refreshOnPrint = temp;
498 idCommonLocal::DWarning
500 prints warning message in yellow that only shows up if the "developer" cvar is set
503 void idCommonLocal::DWarning( const char *fmt, ... ) {
505 char msg[MAX_PRINT_MSG_SIZE];
507 if ( !com_developer.GetBool() ) {
508 return; // don't confuse non-developers with techie stuff...
511 va_start( argptr, fmt );
512 idStr::vsnPrintf( msg, sizeof(msg), fmt, argptr );
514 msg[sizeof(msg)-1] = '\0';
516 Printf( S_COLOR_YELLOW"WARNING: %s\n", msg );
521 idCommonLocal::Warning
523 prints WARNING %s and adds the warning message to a queue to be printed later on
526 void idCommonLocal::Warning( const char *fmt, ... ) {
528 char msg[MAX_PRINT_MSG_SIZE];
530 va_start( argptr, fmt );
531 idStr::vsnPrintf( msg, sizeof(msg), fmt, argptr );
533 msg[sizeof(msg)-1] = 0;
535 Printf( S_COLOR_YELLOW "WARNING: " S_COLOR_RED "%s\n", msg );
537 if ( warningList.Num() < MAX_WARNING_LIST ) {
538 warningList.AddUnique( msg );
544 idCommonLocal::PrintWarnings
547 void idCommonLocal::PrintWarnings( void ) {
550 if ( !warningList.Num() ) {
556 Printf( "------------- Warnings ---------------\n" );
557 Printf( "during %s...\n", warningCaption.c_str() );
559 for ( i = 0; i < warningList.Num(); i++ ) {
560 Printf( S_COLOR_YELLOW "WARNING: " S_COLOR_RED "%s\n", warningList[i].c_str() );
562 if ( warningList.Num() ) {
563 if ( warningList.Num() >= MAX_WARNING_LIST ) {
564 Printf( "more than %d warnings\n", MAX_WARNING_LIST );
566 Printf( "%d warnings\n", warningList.Num() );
573 idCommonLocal::ClearWarnings
576 void idCommonLocal::ClearWarnings( const char *reason ) {
577 warningCaption = reason;
583 idCommonLocal::DumpWarnings
586 void idCommonLocal::DumpWarnings( void ) {
590 if ( !warningList.Num() ) {
594 warningFile = fileSystem->OpenFileWrite( "warnings.txt", "fs_savepath" );
597 warningFile->Printf( "------------- Warnings ---------------\n\n" );
598 warningFile->Printf( "during %s...\n", warningCaption.c_str() );
600 for ( i = 0; i < warningList.Num(); i++ ) {
601 warningList[i].RemoveColors();
602 warningFile->Printf( "WARNING: %s\n", warningList[i].c_str() );
604 if ( warningList.Num() >= MAX_WARNING_LIST ) {
605 warningFile->Printf( "\nmore than %d warnings!\n", MAX_WARNING_LIST );
607 warningFile->Printf( "\n%d warnings.\n", warningList.Num() );
610 warningFile->Printf( "\n\n-------------- Errors ---------------\n\n" );
612 for ( i = 0; i < errorList.Num(); i++ ) {
613 errorList[i].RemoveColors();
614 warningFile->Printf( "ERROR: %s", errorList[i].c_str() );
617 warningFile->ForceFlush();
619 fileSystem->CloseFile( warningFile );
621 #if defined(_WIN32) && !defined(_DEBUG)
623 osPath = fileSystem->RelativePathToOSPath( "warnings.txt", "fs_savepath" );
624 WinExec( va( "Notepad.exe %s", osPath.c_str() ), SW_SHOW );
634 void idCommonLocal::Error( const char *fmt, ... ) {
636 static int lastErrorTime;
637 static int errorCount;
642 // always turn this off after an error
643 com_refreshOnPrint = false;
645 // when we are running automated scripts, make sure we
646 // know if anything failed
647 if ( cvarSystem->GetCVarInteger( "fs_copyfiles" ) ) {
651 // if we don't have GL running, make it a fatal error
652 if ( !renderSystem->IsOpenGLRunning() ) {
656 // if we got a recursive error, make it fatal
657 if ( com_errorEntered ) {
658 // if we are recursively erroring while exiting
659 // from a fatal error, just kill the entire
660 // process immediately, which will prevent a
661 // full screen rendering window covering the
663 if ( com_errorEntered == ERP_FATAL ) {
669 // if we are getting a solid stream of ERP_DROP, do an ERP_FATAL
670 currentTime = Sys_Milliseconds();
671 if ( currentTime - lastErrorTime < 100 ) {
672 if ( ++errorCount > 3 ) {
678 lastErrorTime = currentTime;
680 com_errorEntered = code;
682 va_start (argptr,fmt);
683 idStr::vsnPrintf( errorMessage, sizeof(errorMessage), fmt, argptr );
685 errorMessage[sizeof(errorMessage)-1] = '\0';
687 // copy the error message to the clip board
688 Sys_SetClipboardData( errorMessage );
690 // add the message to the error list
691 errorList.AddUnique( errorMessage );
693 // Dont shut down the session for gui editor or debugger
694 if ( !( com_editors & ( EDITOR_GUI | EDITOR_DEBUGGER ) ) ) {
698 if ( code == ERP_DISCONNECT ) {
699 com_errorEntered = 0;
700 throw idException( errorMessage );
701 // The gui editor doesnt want thing to com_error so it handles exceptions instead
702 } else if( com_editors & ( EDITOR_GUI | EDITOR_DEBUGGER ) ) {
703 com_errorEntered = 0;
704 throw idException( errorMessage );
705 } else if ( code == ERP_DROP ) {
706 Printf( "********************\nERROR: %s\n********************\n", errorMessage );
707 com_errorEntered = 0;
708 throw idException( errorMessage );
710 Printf( "********************\nERROR: %s\n********************\n", errorMessage );
713 if ( cvarSystem->GetCVarBool( "r_fullscreen" ) ) {
714 cmdSystem->BufferCommandText( CMD_EXEC_NOW, "vid_restart partial windowed\n" );
719 Sys_Error( "%s", errorMessage );
724 idCommonLocal::FatalError
726 Dump out of the game to a system dialog
729 void idCommonLocal::FatalError( const char *fmt, ... ) {
732 // if we got a recursive error, make it fatal
733 if ( com_errorEntered ) {
734 // if we are recursively erroring while exiting
735 // from a fatal error, just kill the entire
736 // process immediately, which will prevent a
737 // full screen rendering window covering the
740 Sys_Printf( "FATAL: recursed fatal error:\n%s\n", errorMessage );
742 va_start( argptr, fmt );
743 idStr::vsnPrintf( errorMessage, sizeof(errorMessage), fmt, argptr );
745 errorMessage[sizeof(errorMessage)-1] = '\0';
747 Sys_Printf( "%s\n", errorMessage );
749 // write the console to a log file?
752 com_errorEntered = ERP_FATAL;
754 va_start( argptr, fmt );
755 idStr::vsnPrintf( errorMessage, sizeof(errorMessage), fmt, argptr );
757 errorMessage[sizeof(errorMessage)-1] = '\0';
759 if ( cvarSystem->GetCVarBool( "r_fullscreen" ) ) {
760 cmdSystem->BufferCommandText( CMD_EXEC_NOW, "vid_restart partial windowed\n" );
763 Sys_SetFatalError( errorMessage );
767 Sys_Error( "%s", errorMessage );
775 void idCommonLocal::Quit( void ) {
777 #ifdef ID_ALLOW_TOOLS
778 if ( com_editors & EDITOR_RADIANT ) {
784 // don't try to shutdown if we are in a recursive error
785 if ( !com_errorEntered ) {
794 ============================================================================
796 COMMAND LINE FUNCTIONS
798 + characters separate the commandLine string into multiple console
801 All of these are valid:
803 doom +set test blah +map test
804 doom set test blah+map test
805 doom set test blah + map test
807 ============================================================================
810 #define MAX_CONSOLE_LINES 32
811 int com_numConsoleLines;
812 idCmdArgs com_consoleLines[MAX_CONSOLE_LINES];
816 idCommonLocal::ParseCommandLine
819 void idCommonLocal::ParseCommandLine( int argc, const char **argv ) {
820 int i, current_count;
822 com_numConsoleLines = 0;
824 // API says no program path
825 for ( i = 0; i < argc; i++ ) {
826 if ( argv[ i ][ 0 ] == '+' ) {
827 com_numConsoleLines++;
828 com_consoleLines[ com_numConsoleLines-1 ].AppendArg( argv[ i ] + 1 );
830 if ( !com_numConsoleLines ) {
831 com_numConsoleLines++;
833 com_consoleLines[ com_numConsoleLines-1 ].AppendArg( argv[ i ] );
840 idCommonLocal::ClearCommandLine
843 void idCommonLocal::ClearCommandLine( void ) {
844 com_numConsoleLines = 0;
849 idCommonLocal::SafeMode
851 Check for "safe" on the command line, which will
852 skip loading of config file (DoomConfig.cfg)
855 bool idCommonLocal::SafeMode( void ) {
858 for ( i = 0 ; i < com_numConsoleLines ; i++ ) {
859 if ( !idStr::Icmp( com_consoleLines[ i ].Argv(0), "safe" )
860 || !idStr::Icmp( com_consoleLines[ i ].Argv(0), "cvar_restart" ) ) {
861 com_consoleLines[ i ].Clear();
870 idCommonLocal::CheckToolMode
872 Check for "renderbump", "dmap", or "editor" on the command line,
873 and force fullscreen off in those cases
876 void idCommonLocal::CheckToolMode( void ) {
879 for ( i = 0 ; i < com_numConsoleLines ; i++ ) {
880 if ( !idStr::Icmp( com_consoleLines[ i ].Argv(0), "guieditor" ) ) {
881 com_editors |= EDITOR_GUI;
883 else if ( !idStr::Icmp( com_consoleLines[ i ].Argv(0), "debugger" ) ) {
884 com_editors |= EDITOR_DEBUGGER;
886 else if ( !idStr::Icmp( com_consoleLines[ i ].Argv(0), "editor" ) ) {
887 com_editors |= EDITOR_RADIANT;
889 // Nerve: Add support for the material editor
890 else if ( !idStr::Icmp( com_consoleLines[ i ].Argv(0), "materialEditor" ) ) {
891 com_editors |= EDITOR_MATERIAL;
894 if ( !idStr::Icmp( com_consoleLines[ i ].Argv(0), "renderbump" )
895 || !idStr::Icmp( com_consoleLines[ i ].Argv(0), "editor" )
896 || !idStr::Icmp( com_consoleLines[ i ].Argv(0), "guieditor" )
897 || !idStr::Icmp( com_consoleLines[ i ].Argv(0), "debugger" )
898 || !idStr::Icmp( com_consoleLines[ i ].Argv(0), "dmap" )
899 || !idStr::Icmp( com_consoleLines[ i ].Argv(0), "materialEditor" )
901 cvarSystem->SetCVarBool( "r_fullscreen", false );
909 idCommonLocal::StartupVariable
911 Searches for command line parameters that are set commands.
912 If match is not NULL, only that cvar will be looked for.
913 That is necessary because cddir and basedir need to be set
914 before the filesystem is started, but all other sets should
915 be after execing the config and default.
918 void idCommonLocal::StartupVariable( const char *match, bool once ) {
923 while ( i < com_numConsoleLines ) {
924 if ( strcmp( com_consoleLines[ i ].Argv( 0 ), "set" ) ) {
929 s = com_consoleLines[ i ].Argv(1);
931 if ( !match || !idStr::Icmp( s, match ) ) {
932 cvarSystem->SetCVarString( s, com_consoleLines[ i ].Argv( 2 ) );
936 while ( j < com_numConsoleLines ) {
937 com_consoleLines[ j - 1 ] = com_consoleLines[ j ];
940 com_numConsoleLines--;
950 idCommonLocal::AddStartupCommands
952 Adds command line parameters as script statements
953 Commands are separated by + signs
955 Returns true if any late commands were added, which
956 will keep the demoloop from immediately starting
959 bool idCommonLocal::AddStartupCommands( void ) {
964 // quote every token, so args with semicolons can work
965 for ( i = 0; i < com_numConsoleLines; i++ ) {
966 if ( !com_consoleLines[i].Argc() ) {
970 // set commands won't override menu startup
971 if ( idStr::Icmpn( com_consoleLines[i].Argv(0), "set", 3 ) ) {
974 // directly as tokenized so nothing gets screwed
975 cmdSystem->BufferCommandArgs( CMD_EXEC_APPEND, com_consoleLines[i] );
983 idCommonLocal::InitTool
986 void idCommonLocal::InitTool( const toolFlag_t tool, const idDict *dict ) {
987 #ifdef ID_ALLOW_TOOLS
988 if ( tool & EDITOR_SOUND ) {
989 SoundEditorInit( dict );
990 } else if ( tool & EDITOR_LIGHT ) {
991 LightEditorInit( dict );
992 } else if ( tool & EDITOR_PARTICLE ) {
993 ParticleEditorInit( dict );
994 } else if ( tool & EDITOR_AF ) {
995 AFEditorInit( dict );
1002 idCommonLocal::ActivateTool
1004 Activates or Deactivates a tool
1007 void idCommonLocal::ActivateTool( bool active ) {
1008 com_editorActive = active;
1009 Sys_GrabMouseCursor( !active );
1014 idCommonLocal::WriteFlaggedCVarsToFile
1017 void idCommonLocal::WriteFlaggedCVarsToFile( const char *filename, int flags, const char *setCmd ) {
1020 f = fileSystem->OpenFileWrite( filename );
1022 Printf( "Couldn't write %s.\n", filename );
1025 cvarSystem->WriteFlaggedVariables( flags, setCmd, f );
1026 fileSystem->CloseFile( f );
1031 idCommonLocal::WriteConfigToFile
1034 void idCommonLocal::WriteConfigToFile( const char *filename ) {
1036 #ifdef ID_WRITE_VERSION
1040 idFile_Memory compressed( "compressed" );
1044 f = fileSystem->OpenFileWrite( filename );
1046 Printf ("Couldn't write %s.\n", filename );
1050 #ifdef ID_WRITE_VERSION
1051 assert( config_compressor );
1053 curtime = ctime( &t );
1054 sprintf( runtag, "%s - %s", cvarSystem->GetCVarString( "si_version" ), curtime );
1055 config_compressor->Init( &compressed, true, 8 );
1056 config_compressor->Write( runtag.c_str(), runtag.Length() );
1057 config_compressor->FinishCompress( );
1058 out.Encode( (const byte *)compressed.GetDataPtr(), compressed.Length() );
1059 f->Printf( "// %s\n", out.c_str() );
1062 idKeyInput::WriteBindings( f );
1063 cvarSystem->WriteFlaggedVariables( CVAR_ARCHIVE, "seta", f );
1064 fileSystem->CloseFile( f );
1069 idCommonLocal::WriteConfiguration
1071 Writes key bindings and archived cvars to config file if modified
1074 void idCommonLocal::WriteConfiguration( void ) {
1075 // if we are quiting without fully initializing, make sure
1076 // we don't write out anything
1077 if ( !com_fullyInitialized ) {
1081 if ( !( cvarSystem->GetModifiedFlags() & CVAR_ARCHIVE ) ) {
1084 cvarSystem->ClearModifiedFlags( CVAR_ARCHIVE );
1086 // disable printing out the "Writing to:" message
1087 bool developer = com_developer.GetBool();
1088 com_developer.SetBool( false );
1090 WriteConfigToFile( CONFIG_FILE );
1091 session->WriteCDKey( );
1093 // restore the developer cvar
1094 com_developer.SetBool( developer );
1100 Returns the key bound to the command
1103 const char* idCommonLocal::KeysFromBinding( const char *bind ) {
1104 return idKeyInput::KeysFromBinding( bind );
1110 Returns the binding bound to key
1113 const char* idCommonLocal::BindingFromKey( const char *key ) {
1114 return idKeyInput::BindingFromKey( key );
1120 Returns the state of the button
1123 int idCommonLocal::ButtonState( int key ) {
1124 return usercmdGen->ButtonState(key);
1130 Returns the state of the key
1133 int idCommonLocal::KeyState( int key ) {
1134 return usercmdGen->KeyState(key);
1137 //============================================================================
1139 #ifdef ID_ALLOW_TOOLS
1144 we can start the editor dynamically, but we won't ever get back
1147 static void Com_Editor_f( const idCmdArgs &args ) {
1153 Com_ScriptDebugger_f
1156 static void Com_ScriptDebugger_f( const idCmdArgs &args ) {
1157 // Make sure it wasnt on the command line
1158 if ( !( com_editors & EDITOR_DEBUGGER ) ) {
1159 common->Printf( "Script debugger is currently disabled\n" );
1160 // DebuggerClientLaunch();
1169 static void Com_EditGUIs_f( const idCmdArgs &args ) {
1175 Com_MaterialEditor_f
1178 static void Com_MaterialEditor_f( const idCmdArgs &args ) {
1180 soundSystem->SetMute( true );
1181 MaterialEditorInit();
1183 #endif // ID_ALLOW_TOOLS
1187 idCmdSystemLocal::PrintMemInfo_f
1189 This prints out memory debugging data
1192 static void PrintMemInfo_f( const idCmdArgs &args ) {
1195 memset( &mi, 0, sizeof( mi ) );
1196 mi.filebase = session->GetCurrentMapName();
1198 renderSystem->PrintMemInfo( &mi ); // textures and models
1199 soundSystem->PrintMemInfo( &mi ); // sounds
1201 common->Printf( " Used image memory: %s bytes\n", idStr::FormatNumber( mi.imageAssetsTotal ).c_str() );
1202 mi.assetTotals += mi.imageAssetsTotal;
1204 common->Printf( " Used model memory: %s bytes\n", idStr::FormatNumber( mi.modelAssetsTotal ).c_str() );
1205 mi.assetTotals += mi.modelAssetsTotal;
1207 common->Printf( " Used sound memory: %s bytes\n", idStr::FormatNumber( mi.soundAssetsTotal ).c_str() );
1208 mi.assetTotals += mi.soundAssetsTotal;
1210 common->Printf( " Used asset memory: %s bytes\n", idStr::FormatNumber( mi.assetTotals ).c_str() );
1212 // write overview file
1215 f = fileSystem->OpenFileAppend( "maps/printmeminfo.txt" );
1220 f->Printf( "total(%s ) image(%s ) model(%s ) sound(%s ): %s\n", idStr::FormatNumber( mi.assetTotals ).c_str(), idStr::FormatNumber( mi.imageAssetsTotal ).c_str(),
1221 idStr::FormatNumber( mi.modelAssetsTotal ).c_str(), idStr::FormatNumber( mi.soundAssetsTotal ).c_str(), mi.filebase.c_str() );
1223 fileSystem->CloseFile( f );
1226 #ifdef ID_ALLOW_TOOLS
1232 static void Com_EditLights_f( const idCmdArgs &args ) {
1233 LightEditorInit( NULL );
1234 cvarSystem->SetCVarInteger( "g_editEntityMode", 1 );
1242 static void Com_EditSounds_f( const idCmdArgs &args ) {
1243 SoundEditorInit( NULL );
1244 cvarSystem->SetCVarInteger( "g_editEntityMode", 2 );
1252 static void Com_EditDecls_f( const idCmdArgs &args ) {
1253 DeclBrowserInit( NULL );
1261 static void Com_EditAFs_f( const idCmdArgs &args ) {
1262 AFEditorInit( NULL );
1270 static void Com_EditParticles_f( const idCmdArgs &args ) {
1271 ParticleEditorInit( NULL );
1279 static void Com_EditScripts_f( const idCmdArgs &args ) {
1280 ScriptEditorInit( NULL );
1288 static void Com_EditPDAs_f( const idCmdArgs &args ) {
1289 PDAEditorInit( NULL );
1291 #endif // ID_ALLOW_TOOLS
1297 Just throw a fatal error to test error shutdown procedures.
1300 static void Com_Error_f( const idCmdArgs &args ) {
1301 if ( !com_developer.GetBool() ) {
1302 commonLocal.Printf( "error may only be used in developer mode\n" );
1306 if ( args.Argc() > 1 ) {
1307 commonLocal.FatalError( "Testing fatal error" );
1309 commonLocal.Error( "Testing drop error" );
1317 Just freeze in place for a given number of seconds to test error recovery.
1320 static void Com_Freeze_f( const idCmdArgs &args ) {
1324 if ( args.Argc() != 2 ) {
1325 commonLocal.Printf( "freeze <seconds>\n" );
1329 if ( !com_developer.GetBool() ) {
1330 commonLocal.Printf( "freeze may only be used in developer mode\n" );
1334 s = atof( args.Argv(1) );
1336 start = eventLoop->Milliseconds();
1339 now = eventLoop->Milliseconds();
1340 if ( ( now - start ) * 0.001f > s ) {
1350 A way to force a bus error for development reasons
1353 static void Com_Crash_f( const idCmdArgs &args ) {
1354 if ( !com_developer.GetBool() ) {
1355 commonLocal.Printf( "crash may only be used in developer mode\n" );
1359 * ( int * ) 0 = 0x12345678;
1367 static void Com_Quit_f( const idCmdArgs &args ) {
1375 Write the config file to a specific name
1378 void Com_WriteConfig_f( const idCmdArgs &args ) {
1381 if ( args.Argc() != 2 ) {
1382 commonLocal.Printf( "Usage: writeconfig <filename>\n" );
1386 filename = args.Argv(1);
1387 filename.DefaultFileExtension( ".cfg" );
1388 commonLocal.Printf( "Writing %s.\n", filename.c_str() );
1389 commonLocal.WriteConfigToFile( filename );
1394 Com_SetMachineSpecs_f
1397 void Com_SetMachineSpec_f( const idCmdArgs &args ) {
1398 commonLocal.SetMachineSpec();
1403 Com_ExecMachineSpecs_f
1407 void OSX_GetVideoCard( int& outVendorId, int& outDeviceId );
1408 bool OSX_GetCPUIdentification( int& cpuId, bool& oldArchitecture );
1410 void Com_ExecMachineSpec_f( const idCmdArgs &args ) {
1411 if ( com_machineSpec.GetInteger() == 3 ) {
1412 cvarSystem->SetCVarInteger( "image_anisotropy", 1, CVAR_ARCHIVE );
1413 cvarSystem->SetCVarInteger( "image_lodbias", 0, CVAR_ARCHIVE );
1414 cvarSystem->SetCVarInteger( "image_forceDownSize", 0, CVAR_ARCHIVE );
1415 cvarSystem->SetCVarInteger( "image_roundDown", 1, CVAR_ARCHIVE );
1416 cvarSystem->SetCVarInteger( "image_preload", 1, CVAR_ARCHIVE );
1417 cvarSystem->SetCVarInteger( "image_useAllFormats", 1, CVAR_ARCHIVE );
1418 cvarSystem->SetCVarInteger( "image_downSizeSpecular", 0, CVAR_ARCHIVE );
1419 cvarSystem->SetCVarInteger( "image_downSizeBump", 0, CVAR_ARCHIVE );
1420 cvarSystem->SetCVarInteger( "image_downSizeSpecularLimit", 64, CVAR_ARCHIVE );
1421 cvarSystem->SetCVarInteger( "image_downSizeBumpLimit", 256, CVAR_ARCHIVE );
1422 cvarSystem->SetCVarInteger( "image_usePrecompressedTextures", 0, CVAR_ARCHIVE );
1423 cvarSystem->SetCVarInteger( "image_downsize", 0 , CVAR_ARCHIVE );
1424 cvarSystem->SetCVarString( "image_filter", "GL_LINEAR_MIPMAP_LINEAR", CVAR_ARCHIVE );
1425 cvarSystem->SetCVarInteger( "image_anisotropy", 8, CVAR_ARCHIVE );
1426 cvarSystem->SetCVarInteger( "image_useCompression", 0, CVAR_ARCHIVE );
1427 cvarSystem->SetCVarInteger( "image_ignoreHighQuality", 0, CVAR_ARCHIVE );
1428 cvarSystem->SetCVarInteger( "s_maxSoundsPerShader", 0, CVAR_ARCHIVE );
1429 cvarSystem->SetCVarInteger( "r_mode", 5, CVAR_ARCHIVE );
1430 cvarSystem->SetCVarInteger( "image_useNormalCompression", 0, CVAR_ARCHIVE );
1431 cvarSystem->SetCVarInteger( "r_multiSamples", 0, CVAR_ARCHIVE );
1432 } else if ( com_machineSpec.GetInteger() == 2 ) {
1433 cvarSystem->SetCVarString( "image_filter", "GL_LINEAR_MIPMAP_LINEAR", CVAR_ARCHIVE );
1434 cvarSystem->SetCVarInteger( "image_anisotropy", 1, CVAR_ARCHIVE );
1435 cvarSystem->SetCVarInteger( "image_lodbias", 0, CVAR_ARCHIVE );
1436 cvarSystem->SetCVarInteger( "image_forceDownSize", 0, CVAR_ARCHIVE );
1437 cvarSystem->SetCVarInteger( "image_roundDown", 1, CVAR_ARCHIVE );
1438 cvarSystem->SetCVarInteger( "image_preload", 1, CVAR_ARCHIVE );
1439 cvarSystem->SetCVarInteger( "image_useAllFormats", 1, CVAR_ARCHIVE );
1440 cvarSystem->SetCVarInteger( "image_downSizeSpecular", 0, CVAR_ARCHIVE );
1441 cvarSystem->SetCVarInteger( "image_downSizeBump", 0, CVAR_ARCHIVE );
1442 cvarSystem->SetCVarInteger( "image_downSizeSpecularLimit", 64, CVAR_ARCHIVE );
1443 cvarSystem->SetCVarInteger( "image_downSizeBumpLimit", 256, CVAR_ARCHIVE );
1444 cvarSystem->SetCVarInteger( "image_usePrecompressedTextures", 1, CVAR_ARCHIVE );
1445 cvarSystem->SetCVarInteger( "image_downsize", 0, CVAR_ARCHIVE );
1446 cvarSystem->SetCVarInteger( "image_anisotropy", 8, CVAR_ARCHIVE );
1447 cvarSystem->SetCVarInteger( "image_useCompression", 1, CVAR_ARCHIVE );
1448 cvarSystem->SetCVarInteger( "image_ignoreHighQuality", 0, CVAR_ARCHIVE );
1449 cvarSystem->SetCVarInteger( "s_maxSoundsPerShader", 0, CVAR_ARCHIVE );
1450 cvarSystem->SetCVarInteger( "image_useNormalCompression", 0, CVAR_ARCHIVE );
1451 cvarSystem->SetCVarInteger( "r_mode", 4, CVAR_ARCHIVE );
1452 cvarSystem->SetCVarInteger( "r_multiSamples", 0, CVAR_ARCHIVE );
1453 } else if ( com_machineSpec.GetInteger() == 1 ) {
1454 cvarSystem->SetCVarString( "image_filter", "GL_LINEAR_MIPMAP_LINEAR", CVAR_ARCHIVE );
1455 cvarSystem->SetCVarInteger( "image_anisotropy", 1, CVAR_ARCHIVE );
1456 cvarSystem->SetCVarInteger( "image_lodbias", 0, CVAR_ARCHIVE );
1457 cvarSystem->SetCVarInteger( "image_downSize", 0, CVAR_ARCHIVE );
1458 cvarSystem->SetCVarInteger( "image_forceDownSize", 0, CVAR_ARCHIVE );
1459 cvarSystem->SetCVarInteger( "image_roundDown", 1, CVAR_ARCHIVE );
1460 cvarSystem->SetCVarInteger( "image_preload", 1, CVAR_ARCHIVE );
1461 cvarSystem->SetCVarInteger( "image_useCompression", 1, CVAR_ARCHIVE );
1462 cvarSystem->SetCVarInteger( "image_useAllFormats", 1, CVAR_ARCHIVE );
1463 cvarSystem->SetCVarInteger( "image_usePrecompressedTextures", 1, CVAR_ARCHIVE );
1464 cvarSystem->SetCVarInteger( "image_downSizeSpecular", 0, CVAR_ARCHIVE );
1465 cvarSystem->SetCVarInteger( "image_downSizeBump", 0, CVAR_ARCHIVE );
1466 cvarSystem->SetCVarInteger( "image_downSizeSpecularLimit", 64, CVAR_ARCHIVE );
1467 cvarSystem->SetCVarInteger( "image_downSizeBumpLimit", 256, CVAR_ARCHIVE );
1468 cvarSystem->SetCVarInteger( "image_useNormalCompression", 2, CVAR_ARCHIVE );
1469 cvarSystem->SetCVarInteger( "r_mode", 3, CVAR_ARCHIVE );
1470 cvarSystem->SetCVarInteger( "r_multiSamples", 0, CVAR_ARCHIVE );
1472 cvarSystem->SetCVarString( "image_filter", "GL_LINEAR_MIPMAP_LINEAR", CVAR_ARCHIVE );
1473 cvarSystem->SetCVarInteger( "image_anisotropy", 1, CVAR_ARCHIVE );
1474 cvarSystem->SetCVarInteger( "image_lodbias", 0, CVAR_ARCHIVE );
1475 cvarSystem->SetCVarInteger( "image_roundDown", 1, CVAR_ARCHIVE );
1476 cvarSystem->SetCVarInteger( "image_preload", 1, CVAR_ARCHIVE );
1477 cvarSystem->SetCVarInteger( "image_useAllFormats", 1, CVAR_ARCHIVE );
1478 cvarSystem->SetCVarInteger( "image_usePrecompressedTextures", 1, CVAR_ARCHIVE );
1479 cvarSystem->SetCVarInteger( "image_downSize", 1, CVAR_ARCHIVE );
1480 cvarSystem->SetCVarInteger( "image_anisotropy", 0, CVAR_ARCHIVE );
1481 cvarSystem->SetCVarInteger( "image_useCompression", 1, CVAR_ARCHIVE );
1482 cvarSystem->SetCVarInteger( "image_ignoreHighQuality", 1, CVAR_ARCHIVE );
1483 cvarSystem->SetCVarInteger( "s_maxSoundsPerShader", 1, CVAR_ARCHIVE );
1484 cvarSystem->SetCVarInteger( "image_downSizeSpecular", 1, CVAR_ARCHIVE );
1485 cvarSystem->SetCVarInteger( "image_downSizeBump", 1, CVAR_ARCHIVE );
1486 cvarSystem->SetCVarInteger( "image_downSizeSpecularLimit", 64, CVAR_ARCHIVE );
1487 cvarSystem->SetCVarInteger( "image_downSizeBumpLimit", 256, CVAR_ARCHIVE );
1488 cvarSystem->SetCVarInteger( "r_mode", 3 , CVAR_ARCHIVE );
1489 cvarSystem->SetCVarInteger( "image_useNormalCompression", 2, CVAR_ARCHIVE );
1490 cvarSystem->SetCVarInteger( "r_multiSamples", 0, CVAR_ARCHIVE );
1493 if ( Sys_GetVideoRam() < 128 ) {
1494 cvarSystem->SetCVarBool( "image_ignoreHighQuality", true, CVAR_ARCHIVE );
1495 cvarSystem->SetCVarInteger( "image_downSize", 1, CVAR_ARCHIVE );
1496 cvarSystem->SetCVarInteger( "image_downSizeLimit", 256, CVAR_ARCHIVE );
1497 cvarSystem->SetCVarInteger( "image_downSizeSpecular", 1, CVAR_ARCHIVE );
1498 cvarSystem->SetCVarInteger( "image_downSizeSpecularLimit", 64, CVAR_ARCHIVE );
1499 cvarSystem->SetCVarInteger( "image_downSizeBump", 1, CVAR_ARCHIVE );
1500 cvarSystem->SetCVarInteger( "image_downSizeBumpLimit", 256, CVAR_ARCHIVE );
1503 if ( Sys_GetSystemRam() < 512 ) {
1504 cvarSystem->SetCVarBool( "image_ignoreHighQuality", true, CVAR_ARCHIVE );
1505 cvarSystem->SetCVarInteger( "s_maxSoundsPerShader", 1, CVAR_ARCHIVE );
1506 cvarSystem->SetCVarInteger( "image_downSize", 1, CVAR_ARCHIVE );
1507 cvarSystem->SetCVarInteger( "image_downSizeLimit", 256, CVAR_ARCHIVE );
1508 cvarSystem->SetCVarInteger( "image_downSizeSpecular", 1, CVAR_ARCHIVE );
1509 cvarSystem->SetCVarInteger( "image_downSizeSpecularLimit", 64, CVAR_ARCHIVE );
1510 cvarSystem->SetCVarBool( "com_purgeAll", true, CVAR_ARCHIVE );
1511 cvarSystem->SetCVarBool( "r_forceLoadImages", true, CVAR_ARCHIVE );
1513 cvarSystem->SetCVarBool( "com_purgeAll", false, CVAR_ARCHIVE );
1514 cvarSystem->SetCVarBool( "r_forceLoadImages", false, CVAR_ARCHIVE );
1517 bool oldCard = false;
1518 bool nv10or20 = false;
1519 renderSystem->GetCardCaps( oldCard, nv10or20 );
1521 cvarSystem->SetCVarBool( "g_decals", false, CVAR_ARCHIVE );
1522 cvarSystem->SetCVarBool( "g_projectileLights", false, CVAR_ARCHIVE );
1523 cvarSystem->SetCVarBool( "g_doubleVision", false, CVAR_ARCHIVE );
1524 cvarSystem->SetCVarBool( "g_muzzleFlash", false, CVAR_ARCHIVE );
1526 cvarSystem->SetCVarBool( "g_decals", true, CVAR_ARCHIVE );
1527 cvarSystem->SetCVarBool( "g_projectileLights", true, CVAR_ARCHIVE );
1528 cvarSystem->SetCVarBool( "g_doubleVision", true, CVAR_ARCHIVE );
1529 cvarSystem->SetCVarBool( "g_muzzleFlash", true, CVAR_ARCHIVE );
1532 cvarSystem->SetCVarInteger( "image_useNormalCompression", 1, CVAR_ARCHIVE );
1536 // On low settings, G4 systems & 64MB FX5200/NV34 Systems should default shadows off
1538 int vendorId, deviceId, cpuId;
1539 OSX_GetVideoCard( vendorId, deviceId );
1540 OSX_GetCPUIdentification( cpuId, oldArch );
1541 bool isFX5200 = vendorId == 0x10DE && ( deviceId & 0x0FF0 ) == 0x0320;
1542 if ( ( oldArch || ( isFX5200 && Sys_GetVideoRam() < 128 ) ) && com_machineSpec.GetInteger() == 0 ) {
1543 cvarSystem->SetCVarBool( "r_shadows", false, CVAR_ARCHIVE );
1545 cvarSystem->SetCVarBool( "r_shadows", true, CVAR_ARCHIVE );
1555 void Com_ReloadEngine_f( const idCmdArgs &args ) {
1558 if ( !commonLocal.IsInitialized() ) {
1562 if ( args.Argc() > 1 && idStr::Icmp( args.Argv( 1 ), "menu" ) == 0 ) {
1566 common->Printf( "============= ReloadEngine start =============\n" );
1568 Sys_ShowConsole( 1, false );
1570 commonLocal.ShutdownGame( true );
1571 commonLocal.InitGame();
1572 if ( !menu && !idAsyncNetwork::serverDedicated.GetBool() ) {
1573 Sys_ShowConsole( 0, false );
1575 common->Printf( "============= ReloadEngine end ===============\n" );
1577 if ( !cmdSystem->PostReloadEngine() ) {
1579 session->StartMenu( );
1586 idCommonLocal::GetLanguageDict
1589 const idLangDict *idCommonLocal::GetLanguageDict( void ) {
1590 return &languageDict;
1595 idCommonLocal::FilterLangList
1598 void idCommonLocal::FilterLangList( idStrList* list, idStr lang ) {
1601 for( int i = 0; i < list->Num(); i++ ) {
1603 temp = temp.Right(temp.Length()-strlen("strings/"));
1604 temp = temp.Left(lang.Length());
1605 if(idStr::Icmp(temp, lang) != 0) {
1606 list->RemoveIndex(i);
1614 idCommonLocal::InitLanguageDict
1617 void idCommonLocal::InitLanguageDict( void ) {
1619 languageDict.Clear();
1621 //D3XP: Instead of just loading a single lang file for each language
1622 //we are going to load all files that begin with the language name
1623 //similar to the way pak files work. So you can place english001.lang
1624 //to add new strings to the english language dictionary
1625 idFileList* langFiles;
1626 langFiles = fileSystem->ListFilesTree( "strings", ".lang", true );
1628 idStrList langList = langFiles->GetList();
1630 StartupVariable( "sys_lang", false ); // let it be set on the command line - this is needed because this init happens very early
1631 idStr langName = cvarSystem->GetCVarString( "sys_lang" );
1633 //Loop through the list and filter
1634 idStrList currentLangList = langList;
1635 FilterLangList(¤tLangList, langName);
1637 if ( currentLangList.Num() == 0 ) {
1638 // reset cvar to default and try to load again
1639 cmdSystem->BufferCommandText( CMD_EXEC_NOW, "reset sys_lang" );
1640 langName = cvarSystem->GetCVarString( "sys_lang" );
1641 currentLangList = langList;
1642 FilterLangList(¤tLangList, langName);
1645 for( int i = 0; i < currentLangList.Num(); i++ ) {
1646 //common->Printf("%s\n", currentLangList[i].c_str());
1647 languageDict.Load( currentLangList[i], false );
1650 fileSystem->FreeFileList(langFiles);
1652 Sys_InitScanTable();
1657 idCommonLocal::LocalizeSpecificMapData
1660 void idCommonLocal::LocalizeSpecificMapData( const char *fileName, idLangDict &langDict, const idLangDict &replaceArgs ) {
1661 idStr out, ws, work;
1664 if ( map.Parse( fileName, false, false ) ) {
1665 int count = map.GetNumEntities();
1666 for ( int i = 0; i < count; i++ ) {
1667 idMapEntity *ent = map.GetEntity( i );
1669 for ( int j = 0; j < replaceArgs.GetNumKeyVals(); j++ ) {
1670 const idLangKeyValue *kv = replaceArgs.GetKeyVal( j );
1671 const char *temp = ent->epairs.GetString( kv->key );
1672 if ( temp && *temp ) {
1673 idStr val = kv->value;
1674 if ( val == temp ) {
1675 ent->epairs.Set( kv->key, langDict.AddString( temp ) );
1681 map.Write( fileName, ".map" );
1687 idCommonLocal::LocalizeMapData
1690 void idCommonLocal::LocalizeMapData( const char *fileName, idLangDict &langDict ) {
1691 const char *buffer = NULL;
1692 idLexer src( LEXFL_NOFATALERRORS | LEXFL_NOSTRINGCONCAT | LEXFL_ALLOWMULTICHARLITERALS | LEXFL_ALLOWBACKSLASHSTRINGCONCAT );
1694 common->SetRefreshOnPrint( true );
1696 if ( fileSystem->ReadFile( fileName, (void**)&buffer ) > 0 ) {
1697 src.LoadMemory( buffer, strlen(buffer), fileName );
1698 if ( src.IsLoaded() ) {
1699 common->Printf( "Processing %s\n", fileName );
1701 idToken token, token2;
1702 idLangDict replaceArgs;
1703 while ( src.ReadToken( &token ) ) {
1704 mapFileName = token;
1705 replaceArgs.Clear();
1706 src.ExpectTokenString( "{" );
1707 while ( src.ReadToken( &token) ) {
1708 if ( token == "}" ) {
1711 if ( src.ReadToken( &token2 ) ) {
1712 if ( token2 == "}" ) {
1715 replaceArgs.AddKeyVal( token, token2 );
1718 common->Printf( " localizing map %s...\n", mapFileName.c_str() );
1719 LocalizeSpecificMapData( mapFileName, langDict, replaceArgs );
1722 fileSystem->FreeFile( (void*)buffer );
1725 common->SetRefreshOnPrint( false );
1730 idCommonLocal::LocalizeGui
1733 void idCommonLocal::LocalizeGui( const char *fileName, idLangDict &langDict ) {
1734 idStr out, ws, work;
1735 const char *buffer = NULL;
1742 idLexer src( LEXFL_NOFATALERRORS | LEXFL_NOSTRINGCONCAT | LEXFL_ALLOWMULTICHARLITERALS | LEXFL_ALLOWBACKSLASHSTRINGCONCAT );
1743 if ( fileSystem->ReadFile( fileName, (void**)&buffer ) > 0 ) {
1744 src.LoadMemory( buffer, strlen(buffer), fileName );
1745 if ( src.IsLoaded() ) {
1746 idFile *outFile = fileSystem->OpenFileWrite( fileName );
1747 common->Printf( "Processing %s\n", fileName );
1748 session->UpdateScreen();
1750 while( src.ReadToken( &token ) ) {
1751 src.GetLastWhiteSpace( ws );
1753 if ( token.type == TT_STRING ) {
1754 out += va( "\"%s\"", token.c_str() );
1758 if ( out.Length() > 200000 ) {
1759 outFile->Write( out.c_str(), out.Length() );
1762 work = token.Right( 6 );
1763 if ( token.Icmp( "text" ) == 0 || work.Icmp( "::text" ) == 0 || token.Icmp( "choices" ) == 0 ) {
1764 if ( src.ReadToken( &token ) ) {
1765 // see if already exists, if so save that id to this position in this file
1766 // otherwise add this to the list and save the id to this position in this file
1767 src.GetLastWhiteSpace( ws );
1769 token = langDict.AddString( token );
1771 for ( k = 0; k < token.Length(); k++ ) {
1776 } else if ( ch == '\n' || ch == '\r' ) {
1785 } else if ( token.Icmp( "comment" ) == 0 ) {
1786 if ( src.ReadToken( &token ) ) {
1787 // need to write these out by hand to preserve any \n's
1788 // see if already exists, if so save that id to this position in this file
1789 // otherwise add this to the list and save the id to this position in this file
1790 src.GetLastWhiteSpace( ws );
1793 for ( k = 0; k < token.Length(); k++ ) {
1798 } else if ( ch == '\n' || ch == '\r' ) {
1809 outFile->Write( out.c_str(), out.Length() );
1810 fileSystem->CloseFile( outFile );
1812 fileSystem->FreeFile( (void*)buffer );
1821 void Com_ReloadLanguage_f( const idCmdArgs &args ) {
1822 commonLocal.InitLanguageDict();
1825 typedef idHashTable<idStrList> ListHash;
1826 void LoadMapLocalizeData(ListHash& listHash) {
1828 idStr fileName = "map_localize.cfg";
1829 const char *buffer = NULL;
1830 idLexer src( LEXFL_NOFATALERRORS | LEXFL_NOSTRINGCONCAT | LEXFL_ALLOWMULTICHARLITERALS | LEXFL_ALLOWBACKSLASHSTRINGCONCAT );
1832 if ( fileSystem->ReadFile( fileName, (void**)&buffer ) > 0 ) {
1833 src.LoadMemory( buffer, strlen(buffer), fileName );
1834 if ( src.IsLoaded() ) {
1840 while ( src.ReadToken( &token ) ) {
1842 src.ExpectTokenString( "{" );
1845 while ( src.ReadToken( &token) ) {
1846 if ( token == "}" ) {
1852 listHash.Set(classname, list);
1855 fileSystem->FreeFile( (void*)buffer );
1860 void LoadGuiParmExcludeList(idStrList& list) {
1862 idStr fileName = "guiparm_exclude.cfg";
1863 const char *buffer = NULL;
1864 idLexer src( LEXFL_NOFATALERRORS | LEXFL_NOSTRINGCONCAT | LEXFL_ALLOWMULTICHARLITERALS | LEXFL_ALLOWBACKSLASHSTRINGCONCAT );
1866 if ( fileSystem->ReadFile( fileName, (void**)&buffer ) > 0 ) {
1867 src.LoadMemory( buffer, strlen(buffer), fileName );
1868 if ( src.IsLoaded() ) {
1874 while ( src.ReadToken( &token ) ) {
1878 fileSystem->FreeFile( (void*)buffer );
1882 bool TestMapVal(idStr& str) {
1883 //Already Localized?
1884 if(str.Find("#str_") != -1) {
1891 bool TestGuiParm(const char* parm, const char* value, idStrList& excludeList) {
1893 idStr testVal = value;
1895 //Already Localized?
1896 if(testVal.Find("#str_") != -1) {
1901 if(testVal.IsNumeric()) {
1906 if(testVal.Find("::") != -1) {
1911 if(testVal.Find("/") != -1) {
1915 if(excludeList.Find(testVal)) {
1922 void GetFileList(const char* dir, const char* ext, idStrList& list) {
1924 //Recurse Subdirectories
1926 Sys_ListFiles(dir, "/", dirList);
1927 for(int i = 0; i < dirList.Num(); i++) {
1928 if(dirList[i] == "." || dirList[i] == "..") {
1931 idStr fullName = va("%s/%s", dir, dirList[i].c_str());
1932 GetFileList(fullName, ext, list);
1936 Sys_ListFiles(dir, ext, fileList);
1937 for(int i = 0; i < fileList.Num(); i++) {
1938 idStr fullName = va("%s/%s", dir, fileList[i].c_str());
1939 list.Append(fullName);
1943 int LocalizeMap(const char* mapName, idLangDict &langDict, ListHash& listHash, idStrList& excludeList, bool writeFile) {
1945 common->Printf("Localizing Map '%s'\n", mapName);
1950 if ( map.Parse(mapName, false, false ) ) {
1951 int count = map.GetNumEntities();
1952 for ( int j = 0; j < count; j++ ) {
1953 idMapEntity *ent = map.GetEntity( j );
1956 idStr classname = ent->epairs.GetString("classname");
1958 //Hack: for info_location
1959 bool hasLocation = false;
1962 listHash.Get(classname, &list);
1965 for(int k = 0; k < list->Num(); k++) {
1967 idStr val = ent->epairs.GetString((*list)[k], "");
1969 if(val.Length() && classname == "info_location" && (*list)[k] == "location") {
1973 if(val.Length() && TestMapVal(val)) {
1975 if(!hasLocation || (*list)[k] == "location") {
1978 ent->epairs.Set( (*list)[k], langDict.AddString( val ) );
1984 listHash.Get("all", &list);
1986 for(int k = 0; k < list->Num(); k++) {
1987 idStr val = ent->epairs.GetString((*list)[k], "");
1988 if(val.Length() && TestMapVal(val)) {
1991 ent->epairs.Set( (*list)[k], langDict.AddString( val ) );
1996 //Localize the gui_parms
1997 const idKeyValue* kv = ent->epairs.MatchPrefix("gui_parm");
1999 if(TestGuiParm(kv->GetKey(), kv->GetValue(), excludeList)) {
2002 ent->epairs.Set( kv->GetKey(), langDict.AddString( kv->GetValue() ) );
2004 kv = ent->epairs.MatchPrefix( "gui_parm", kv );
2008 if(writeFile && strCount > 0) {
2009 //Before we write the map file lets make a backup of the original
2010 idStr file = fileSystem->RelativePathToOSPath(mapName);
2011 idStr bak = file.Left(file.Length() - 4);
2012 bak.Append(".bak_loc");
2013 fileSystem->CopyFile( file, bak );
2015 map.Write( mapName, ".map" );
2019 common->Printf("Count: %d\n", strCount);
2028 void Com_LocalizeMaps_f( const idCmdArgs &args ) {
2029 if ( args.Argc() < 2 ) {
2030 common->Printf( "Usage: localizeMaps <count | dictupdate | all> <map>\n" );
2037 bool dictUpdate = false;
2040 if ( idStr::Icmp( args.Argv(1), "count" ) == 0 ) {
2042 } else if ( idStr::Icmp( args.Argv(1), "dictupdate" ) == 0 ) {
2045 } else if ( idStr::Icmp( args.Argv(1), "all" ) == 0 ) {
2050 common->Printf( "Invalid Command\n" );
2051 common->Printf( "Usage: localizeMaps <count | dictupdate | all>\n" );
2056 idLangDict strTable;
2057 idStr filename = va("strings/english%.3i.lang", com_product_lang_ext.GetInteger());
2058 if(strTable.Load( filename ) == false) {
2059 //This is a new file so set the base index
2060 strTable.SetBaseID(com_product_lang_ext.GetInteger()*100000);
2063 common->SetRefreshOnPrint( true );
2066 LoadMapLocalizeData(listHash);
2068 idStrList excludeList;
2069 LoadGuiParmExcludeList(excludeList);
2071 if(args.Argc() == 3) {
2072 strCount += LocalizeMap(args.Argv(2), strTable, listHash, excludeList, write);
2075 GetFileList("z:/d3xp/d3xp/maps/game", "*.map", files);
2076 for ( int i = 0; i < files.Num(); i++ ) {
2077 idStr file = fileSystem->OSPathToRelativePath(files[i]);
2078 strCount += LocalizeMap(file, strTable, listHash, excludeList, write);
2083 common->Printf("Localize String Count: %d\n", strCount);
2086 common->SetRefreshOnPrint( false );
2089 strTable.Save( filename );
2098 void Com_LocalizeGuis_f( const idCmdArgs &args ) {
2100 if ( args.Argc() != 2 ) {
2101 common->Printf( "Usage: localizeGuis <all | gui>\n" );
2105 idLangDict strTable;
2107 idStr filename = va("strings/english%.3i.lang", com_product_lang_ext.GetInteger());
2108 if(strTable.Load( filename ) == false) {
2109 //This is a new file so set the base index
2110 strTable.SetBaseID(com_product_lang_ext.GetInteger()*100000);
2114 if ( idStr::Icmp( args.Argv(1), "all" ) == 0 ) {
2115 idStr game = cvarSystem->GetCVarString( "fs_game" );
2117 files = fileSystem->ListFilesTree( "guis", "*.gui", true, game );
2119 files = fileSystem->ListFilesTree( "guis", "*.gui", true );
2121 for ( int i = 0; i < files->GetNumFiles(); i++ ) {
2122 commonLocal.LocalizeGui( files->GetFile( i ), strTable );
2124 fileSystem->FreeFileList( files );
2127 files = fileSystem->ListFilesTree( "guis", "*.pd", true, game );
2129 files = fileSystem->ListFilesTree( "guis", "*.pd", true, "d3xp" );
2132 for ( int i = 0; i < files->GetNumFiles(); i++ ) {
2133 commonLocal.LocalizeGui( files->GetFile( i ), strTable );
2135 fileSystem->FreeFileList( files );
2138 commonLocal.LocalizeGui( args.Argv(1), strTable );
2140 strTable.Save( filename );
2143 void Com_LocalizeGuiParmsTest_f( const idCmdArgs &args ) {
2145 common->SetRefreshOnPrint( true );
2147 idFile *localizeFile = fileSystem->OpenFileWrite( "gui_parm_localize.csv" );
2148 idFile *noLocalizeFile = fileSystem->OpenFileWrite( "gui_parm_nolocalize.csv" );
2150 idStrList excludeList;
2151 LoadGuiParmExcludeList(excludeList);
2154 GetFileList("z:/d3xp/d3xp/maps/game", "*.map", files);
2156 for ( int i = 0; i < files.Num(); i++ ) {
2158 common->Printf("Testing Map '%s'\n", files[i].c_str());
2161 idStr file = fileSystem->OSPathToRelativePath(files[i]);
2162 if ( map.Parse(file, false, false ) ) {
2163 int count = map.GetNumEntities();
2164 for ( int j = 0; j < count; j++ ) {
2165 idMapEntity *ent = map.GetEntity( j );
2167 const idKeyValue* kv = ent->epairs.MatchPrefix("gui_parm");
2169 if(TestGuiParm(kv->GetKey(), kv->GetValue(), excludeList)) {
2170 idStr out = va("%s,%s,%s\r\n", kv->GetValue().c_str(), kv->GetKey().c_str(), file.c_str());
2171 localizeFile->Write( out.c_str(), out.Length() );
2173 idStr out = va("%s,%s,%s\r\n", kv->GetValue().c_str(), kv->GetKey().c_str(), file.c_str());
2174 noLocalizeFile->Write( out.c_str(), out.Length() );
2176 kv = ent->epairs.MatchPrefix( "gui_parm", kv );
2183 fileSystem->CloseFile( localizeFile );
2184 fileSystem->CloseFile( noLocalizeFile );
2186 common->SetRefreshOnPrint( false );
2190 void Com_LocalizeMapsTest_f( const idCmdArgs &args ) {
2193 LoadMapLocalizeData(listHash);
2196 common->SetRefreshOnPrint( true );
2198 idFile *localizeFile = fileSystem->OpenFileWrite( "map_localize.csv" );
2201 GetFileList("z:/d3xp/d3xp/maps/game", "*.map", files);
2203 for ( int i = 0; i < files.Num(); i++ ) {
2205 common->Printf("Testing Map '%s'\n", files[i].c_str());
2208 idStr file = fileSystem->OSPathToRelativePath(files[i]);
2209 if ( map.Parse(file, false, false ) ) {
2210 int count = map.GetNumEntities();
2211 for ( int j = 0; j < count; j++ ) {
2212 idMapEntity *ent = map.GetEntity( j );
2215 //Temp code to get a list of all entity key value pairs
2216 /*idStr classname = ent->epairs.GetString("classname");
2217 if(classname == "worldspawn" || classname == "func_static" || classname == "light" || classname == "speaker" || classname.Left(8) == "trigger_") {
2220 for( int i = 0; i < ent->epairs.GetNumKeyVals(); i++) {
2221 const idKeyValue* kv = ent->epairs.GetKeyVal(i);
2222 idStr out = va("%s,%s,%s,%s\r\n", classname.c_str(), kv->GetKey().c_str(), kv->GetValue().c_str(), file.c_str());
2223 localizeFile->Write( out.c_str(), out.Length() );
2226 idStr classname = ent->epairs.GetString("classname");
2228 //Hack: for info_location
2229 bool hasLocation = false;
2232 listHash.Get(classname, &list);
2235 for(int k = 0; k < list->Num(); k++) {
2237 idStr val = ent->epairs.GetString((*list)[k], "");
2239 if(classname == "info_location" && (*list)[k] == "location") {
2243 if(val.Length() && TestMapVal(val)) {
2245 if(!hasLocation || (*list)[k] == "location") {
2246 idStr out = va("%s,%s,%s\r\n", val.c_str(), (*list)[k].c_str(), file.c_str());
2247 localizeFile->Write( out.c_str(), out.Length() );
2253 listHash.Get("all", &list);
2255 for(int k = 0; k < list->Num(); k++) {
2256 idStr val = ent->epairs.GetString((*list)[k], "");
2257 if(val.Length() && TestMapVal(val)) {
2258 idStr out = va("%s,%s,%s\r\n", val.c_str(), (*list)[k].c_str(), file.c_str());
2259 localizeFile->Write( out.c_str(), out.Length() );
2268 fileSystem->CloseFile( localizeFile );
2270 common->SetRefreshOnPrint( false );
2278 void Com_StartBuild_f( const idCmdArgs &args ) {
2279 globalImages->StartBuild();
2287 void Com_FinishBuild_f( const idCmdArgs &args ) {
2289 game->CacheDictionaryMedia( NULL );
2291 globalImages->FinishBuild( ( args.Argc() > 1 ) );
2299 void Com_Help_f( const idCmdArgs &args ) {
2300 common->Printf( "\nCommonly used commands:\n" );
2301 common->Printf( " spawnServer - start the server.\n" );
2302 common->Printf( " disconnect - shut down the server.\n" );
2303 common->Printf( " listCmds - list all console commands.\n" );
2304 common->Printf( " listCVars - list all console variables.\n" );
2305 common->Printf( " kick - kick a client by number.\n" );
2306 common->Printf( " gameKick - kick a client by name.\n" );
2307 common->Printf( " serverNextMap - immediately load next map.\n" );
2308 common->Printf( " serverMapRestart - restart the current map.\n" );
2309 common->Printf( " serverForceReady - force all players to ready status.\n" );
2310 common->Printf( "\nCommonly used variables:\n" );
2311 common->Printf( " si_name - server name (change requires a restart to see)\n" );
2312 common->Printf( " si_gametype - type of game.\n" );
2313 common->Printf( " si_fragLimit - max kills to win (or lives in Last Man Standing).\n" );
2314 common->Printf( " si_timeLimit - maximum time a game will last.\n" );
2315 common->Printf( " si_warmup - do pre-game warmup.\n" );
2316 common->Printf( " si_pure - pure server.\n" );
2317 common->Printf( " g_mapCycle - name of .scriptcfg file for cycling maps.\n" );
2318 common->Printf( "See mapcycle.scriptcfg for an example of a mapcyle script.\n\n" );
2323 idCommonLocal::InitCommands
2326 void idCommonLocal::InitCommands( void ) {
2327 cmdSystem->AddCommand( "error", Com_Error_f, CMD_FL_SYSTEM|CMD_FL_CHEAT, "causes an error" );
2328 cmdSystem->AddCommand( "crash", Com_Crash_f, CMD_FL_SYSTEM|CMD_FL_CHEAT, "causes a crash" );
2329 cmdSystem->AddCommand( "freeze", Com_Freeze_f, CMD_FL_SYSTEM|CMD_FL_CHEAT, "freezes the game for a number of seconds" );
2330 cmdSystem->AddCommand( "quit", Com_Quit_f, CMD_FL_SYSTEM, "quits the game" );
2331 cmdSystem->AddCommand( "exit", Com_Quit_f, CMD_FL_SYSTEM, "exits the game" );
2332 cmdSystem->AddCommand( "writeConfig", Com_WriteConfig_f, CMD_FL_SYSTEM, "writes a config file" );
2333 cmdSystem->AddCommand( "reloadEngine", Com_ReloadEngine_f, CMD_FL_SYSTEM, "reloads the engine down to including the file system" );
2334 cmdSystem->AddCommand( "setMachineSpec", Com_SetMachineSpec_f, CMD_FL_SYSTEM, "detects system capabilities and sets com_machineSpec to appropriate value" );
2335 cmdSystem->AddCommand( "execMachineSpec", Com_ExecMachineSpec_f, CMD_FL_SYSTEM, "execs the appropriate config files and sets cvars based on com_machineSpec" );
2337 #if !defined( ID_DEMO_BUILD ) && !defined( ID_DEDICATED )
2339 cmdSystem->AddCommand( "dmap", Dmap_f, CMD_FL_TOOL, "compiles a map", idCmdSystem::ArgCompletion_MapName );
2340 cmdSystem->AddCommand( "renderbump", RenderBump_f, CMD_FL_TOOL, "renders a bump map", idCmdSystem::ArgCompletion_ModelName );
2341 cmdSystem->AddCommand( "renderbumpFlat", RenderBumpFlat_f, CMD_FL_TOOL, "renders a flat bump map", idCmdSystem::ArgCompletion_ModelName );
2342 cmdSystem->AddCommand( "runAAS", RunAAS_f, CMD_FL_TOOL, "compiles an AAS file for a map", idCmdSystem::ArgCompletion_MapName );
2343 cmdSystem->AddCommand( "runAASDir", RunAASDir_f, CMD_FL_TOOL, "compiles AAS files for all maps in a folder", idCmdSystem::ArgCompletion_MapName );
2344 cmdSystem->AddCommand( "runReach", RunReach_f, CMD_FL_TOOL, "calculates reachability for an AAS file", idCmdSystem::ArgCompletion_MapName );
2345 cmdSystem->AddCommand( "roq", RoQFileEncode_f, CMD_FL_TOOL, "encodes a roq file" );
2348 #ifdef ID_ALLOW_TOOLS
2350 cmdSystem->AddCommand( "editor", Com_Editor_f, CMD_FL_TOOL, "launches the level editor Radiant" );
2351 cmdSystem->AddCommand( "editLights", Com_EditLights_f, CMD_FL_TOOL, "launches the in-game Light Editor" );
2352 cmdSystem->AddCommand( "editSounds", Com_EditSounds_f, CMD_FL_TOOL, "launches the in-game Sound Editor" );
2353 cmdSystem->AddCommand( "editDecls", Com_EditDecls_f, CMD_FL_TOOL, "launches the in-game Declaration Editor" );
2354 cmdSystem->AddCommand( "editAFs", Com_EditAFs_f, CMD_FL_TOOL, "launches the in-game Articulated Figure Editor" );
2355 cmdSystem->AddCommand( "editParticles", Com_EditParticles_f, CMD_FL_TOOL, "launches the in-game Particle Editor" );
2356 cmdSystem->AddCommand( "editScripts", Com_EditScripts_f, CMD_FL_TOOL, "launches the in-game Script Editor" );
2357 cmdSystem->AddCommand( "editGUIs", Com_EditGUIs_f, CMD_FL_TOOL, "launches the GUI Editor" );
2358 cmdSystem->AddCommand( "editPDAs", Com_EditPDAs_f, CMD_FL_TOOL, "launches the in-game PDA Editor" );
2359 cmdSystem->AddCommand( "debugger", Com_ScriptDebugger_f, CMD_FL_TOOL, "launches the Script Debugger" );
2361 //BSM Nerve: Add support for the material editor
2362 cmdSystem->AddCommand( "materialEditor", Com_MaterialEditor_f, CMD_FL_TOOL, "launches the Material Editor" );
2365 cmdSystem->AddCommand( "printMemInfo", PrintMemInfo_f, CMD_FL_SYSTEM, "prints memory debugging data" );
2368 cmdSystem->AddCommand( "memoryDump", Mem_Dump_f, CMD_FL_SYSTEM|CMD_FL_CHEAT, "creates a memory dump" );
2369 cmdSystem->AddCommand( "memoryDumpCompressed", Mem_DumpCompressed_f, CMD_FL_SYSTEM|CMD_FL_CHEAT, "creates a compressed memory dump" );
2370 cmdSystem->AddCommand( "showStringMemory", idStr::ShowMemoryUsage_f, CMD_FL_SYSTEM, "shows memory used by strings" );
2371 cmdSystem->AddCommand( "showDictMemory", idDict::ShowMemoryUsage_f, CMD_FL_SYSTEM, "shows memory used by dictionaries" );
2372 cmdSystem->AddCommand( "listDictKeys", idDict::ListKeys_f, CMD_FL_SYSTEM|CMD_FL_CHEAT, "lists all keys used by dictionaries" );
2373 cmdSystem->AddCommand( "listDictValues", idDict::ListValues_f, CMD_FL_SYSTEM|CMD_FL_CHEAT, "lists all values used by dictionaries" );
2374 cmdSystem->AddCommand( "testSIMD", idSIMD::Test_f, CMD_FL_SYSTEM|CMD_FL_CHEAT, "test SIMD code" );
2377 cmdSystem->AddCommand( "localizeGuis", Com_LocalizeGuis_f, CMD_FL_SYSTEM|CMD_FL_CHEAT, "localize guis" );
2378 cmdSystem->AddCommand( "localizeMaps", Com_LocalizeMaps_f, CMD_FL_SYSTEM|CMD_FL_CHEAT, "localize maps" );
2379 cmdSystem->AddCommand( "reloadLanguage", Com_ReloadLanguage_f, CMD_FL_SYSTEM, "reload language dict" );
2382 cmdSystem->AddCommand( "localizeGuiParmsTest", Com_LocalizeGuiParmsTest_f, CMD_FL_SYSTEM, "Create test files that show gui parms localized and ignored." );
2383 cmdSystem->AddCommand( "localizeMapsTest", Com_LocalizeMapsTest_f, CMD_FL_SYSTEM, "Create test files that shows which strings will be localized." );
2386 cmdSystem->AddCommand( "startBuild", Com_StartBuild_f, CMD_FL_SYSTEM|CMD_FL_CHEAT, "prepares to make a build" );
2387 cmdSystem->AddCommand( "finishBuild", Com_FinishBuild_f, CMD_FL_SYSTEM|CMD_FL_CHEAT, "finishes the build process" );
2390 cmdSystem->AddCommand( "help", Com_Help_f, CMD_FL_SYSTEM, "shows help" );
2396 idCommonLocal::InitRenderSystem
2399 void idCommonLocal::InitRenderSystem( void ) {
2400 if ( com_skipRenderer.GetBool() ) {
2404 renderSystem->InitOpenGL();
2405 PrintLoadingMessage( common->GetLanguageDict()->GetString( "#str_04343" ) );
2410 idCommonLocal::PrintLoadingMessage
2413 void idCommonLocal::PrintLoadingMessage( const char *msg ) {
2414 if ( !( msg && *msg ) ) {
2417 renderSystem->BeginFrame( renderSystem->GetScreenWidth(), renderSystem->GetScreenHeight() );
2418 renderSystem->DrawStretchPic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0, 1, 1, declManager->FindMaterial( "splashScreen" ) );
2419 int len = strlen( msg );
2420 renderSystem->DrawSmallStringExt( ( 640 - len * SMALLCHAR_WIDTH ) / 2, 410, msg, idVec4( 0.0f, 0.81f, 0.94f, 1.0f ), true, declManager->FindMaterial( "textures/bigchars" ) );
2421 renderSystem->EndFrame( NULL, NULL );
2426 idCommonLocal::InitSIMD
2429 void idCommonLocal::InitSIMD( void ) {
2430 idSIMD::InitProcessor( "doom", com_forceGenericSIMD.GetBool() );
2431 com_forceGenericSIMD.ClearModified();
2436 idCommonLocal::Frame
2439 void idCommonLocal::Frame( void ) {
2442 // pump all the events
2443 Sys_GenerateEvents();
2445 // write config file if anything changed
2446 WriteConfiguration();
2448 // change SIMD implementation if required
2449 if ( com_forceGenericSIMD.IsModified() ) {
2453 eventLoop->RunEventLoop();
2455 com_frameTime = com_ticNumber * USERCMD_MSEC;
2457 idAsyncNetwork::RunFrame();
2459 if ( idAsyncNetwork::IsActive() ) {
2460 if ( idAsyncNetwork::serverDedicated.GetInteger() != 1 ) {
2461 session->GuiFrameEvents();
2462 session->UpdateScreen( false );
2467 // normal, in-sequence screen update
2468 session->UpdateScreen( false );
2471 // report timing information
2472 if ( com_speeds.GetBool() ) {
2473 static int lastTime;
2474 int nowTime = Sys_Milliseconds();
2475 int com_frameMsec = nowTime - lastTime;
2477 Printf( "frame:%i all:%3i gfr:%3i rf:%3i bk:%3i\n", com_frameNumber, com_frameMsec, time_gameFrame, time_frontend, time_backend );
2484 // set idLib frame number for frame based memory dumps
2485 idLib::frameNumber = com_frameNumber;
2487 // the FPU stack better be empty at this point or some bad code or compiler bug left values on the stack
2488 if ( !Sys_FPU_StackIsEmpty() ) {
2489 Printf( Sys_FPU_GetState() );
2490 FatalError( "idCommon::Frame: the FPU stack is not empty at the end of the frame\n" );
2494 catch( idException & ) {
2495 return; // an ERP_DROP was thrown
2501 idCommonLocal::GUIFrame
2504 void idCommonLocal::GUIFrame( bool execCmd, bool network ) {
2505 Sys_GenerateEvents();
2506 eventLoop->RunEventLoop( execCmd ); // and execute any commands
2507 com_frameTime = com_ticNumber * USERCMD_MSEC;
2509 idAsyncNetwork::RunFrame();
2512 session->UpdateScreen( false );
2517 idCommonLocal::SingleAsyncTic
2519 The system will asyncronously call this function 60 times a second to
2520 handle the time-critical functions that we don't want limited to
2524 user input generation (conditioned by com_asyncInput)
2525 packet server operation
2526 packet client operation
2528 We are not using thread safe libraries, so any functionality put here must
2529 be VERY VERY careful about what it calls.
2534 int milliseconds; // should always be incremeting by 60hz
2535 int deltaMsec; // should always be 16
2536 int timeConsumed; // msec spent in Com_AsyncThread()
2537 int clientPacketsReceived;
2538 int serverPacketsReceived;
2539 int mostRecentServerPacketSequence;
2542 static const int MAX_ASYNC_STATS = 1024;
2543 asyncStats_t com_asyncStats[MAX_ASYNC_STATS]; // indexed by com_ticNumber
2547 void idCommonLocal::SingleAsyncTic( void ) {
2548 // main thread code can prevent this from happening while modifying
2549 // critical data structures
2550 Sys_EnterCriticalSection();
2552 asyncStats_t *stat = &com_asyncStats[com_ticNumber & (MAX_ASYNC_STATS-1)];
2553 memset( stat, 0, sizeof( *stat ) );
2554 stat->milliseconds = Sys_Milliseconds();
2555 stat->deltaMsec = stat->milliseconds - com_asyncStats[(com_ticNumber - 1) & (MAX_ASYNC_STATS-1)].milliseconds;
2557 if ( usercmdGen && com_asyncInput.GetBool() ) {
2558 usercmdGen->UsercmdInterrupt();
2561 switch ( com_asyncSound.GetInteger() ) {
2563 soundSystem->AsyncUpdate( stat->milliseconds );
2566 soundSystem->AsyncUpdateWrite( stat->milliseconds );
2570 // we update com_ticNumber after all the background tasks
2571 // have completed their work for this tic
2574 stat->timeConsumed = Sys_Milliseconds() - stat->milliseconds;
2576 Sys_LeaveCriticalSection();
2581 idCommonLocal::Async
2584 void idCommonLocal::Async( void ) {
2585 if ( com_shuttingDown ) {
2589 int msec = Sys_Milliseconds();
2590 if ( !lastTicMsec ) {
2591 lastTicMsec = msec - USERCMD_MSEC;
2594 if ( !com_preciseTic.GetBool() ) {
2595 // just run a single tic, even if the exact msec isn't precise
2600 int ticMsec = USERCMD_MSEC;
2602 // the number of msec per tic can be varies with the timescale cvar
2603 float timescale = com_timescale.GetFloat();
2604 if ( timescale != 1.0f ) {
2605 ticMsec /= timescale;
2606 if ( ticMsec < 1 ) {
2611 // don't skip too many
2612 if ( timescale == 1.0f ) {
2613 if ( lastTicMsec + 10 * USERCMD_MSEC < msec ) {
2614 lastTicMsec = msec - 10*USERCMD_MSEC;
2618 while ( lastTicMsec + ticMsec <= msec ) {
2620 lastTicMsec += ticMsec;
2626 idCommonLocal::LoadGameDLL
2629 void idCommonLocal::LoadGameDLL( void ) {
2631 char dllPath[ MAX_OSPATH ];
2633 gameImport_t gameImport;
2634 gameExport_t gameExport;
2635 GetGameAPI_t GetGameAPI;
2637 fileSystem->FindDLL( "game", dllPath, true );
2639 if ( !dllPath[ 0 ] ) {
2640 common->FatalError( "couldn't find game dynamic library" );
2643 common->DPrintf( "Loading game DLL: '%s'\n", dllPath );
2644 gameDLL = sys->DLL_Load( dllPath );
2646 common->FatalError( "couldn't load game dynamic library" );
2650 GetGameAPI = (GetGameAPI_t) Sys_DLL_GetProcAddress( gameDLL, "GetGameAPI" );
2651 if ( !GetGameAPI ) {
2652 Sys_DLL_Unload( gameDLL );
2654 common->FatalError( "couldn't find game DLL API" );
2658 gameImport.version = GAME_API_VERSION;
2659 gameImport.sys = ::sys;
2660 gameImport.common = ::common;
2661 gameImport.cmdSystem = ::cmdSystem;
2662 gameImport.cvarSystem = ::cvarSystem;
2663 gameImport.fileSystem = ::fileSystem;
2664 gameImport.networkSystem = ::networkSystem;
2665 gameImport.renderSystem = ::renderSystem;
2666 gameImport.soundSystem = ::soundSystem;
2667 gameImport.renderModelManager = ::renderModelManager;
2668 gameImport.uiManager = ::uiManager;
2669 gameImport.declManager = ::declManager;
2670 gameImport.AASFileManager = ::AASFileManager;
2671 gameImport.collisionModelManager = ::collisionModelManager;
2673 gameExport = *GetGameAPI( &gameImport );
2675 if ( gameExport.version != GAME_API_VERSION ) {
2676 Sys_DLL_Unload( gameDLL );
2678 common->FatalError( "wrong game DLL API version" );
2682 game = gameExport.game;
2683 gameEdit = gameExport.gameEdit;
2687 // initialize the game object
2688 if ( game != NULL ) {
2695 idCommonLocal::UnloadGameDLL
2698 void idCommonLocal::UnloadGameDLL( void ) {
2700 // shut down the game object
2701 if ( game != NULL ) {
2708 Sys_DLL_Unload( gameDLL );
2719 idCommonLocal::IsInitialized
2722 bool idCommonLocal::IsInitialized( void ) const {
2723 return com_fullyInitialized;
2728 idCommonLocal::SetMachineSpec
2731 void idCommonLocal::SetMachineSpec( void ) {
2732 cpuid_t cpu = Sys_GetProcessorId();
2733 double ghz = Sys_ClockTicksPerSecond() * 0.000000001f;
2734 int vidRam = Sys_GetVideoRam();
2735 int sysRam = Sys_GetSystemRam();
2736 bool oldCard = false;
2737 bool nv10or20 = false;
2739 renderSystem->GetCardCaps( oldCard, nv10or20 );
2741 Printf( "Detected\n \t%.2f GHz CPU\n\t%i MB of System memory\n\t%i MB of Video memory on %s\n\n", ghz, sysRam, vidRam, ( oldCard ) ? "a less than optimal video architecture" : "an optimal video architecture" );
2743 if ( ghz >= 2.75f && vidRam >= 512 && sysRam >= 1024 && !oldCard ) {
2744 Printf( "This system qualifies for Ultra quality!\n" );
2745 com_machineSpec.SetInteger( 3 );
2746 } else if ( ghz >= ( ( cpu & CPUID_AMD ) ? 1.9f : 2.19f ) && vidRam >= 256 && sysRam >= 512 && !oldCard ) {
2747 Printf( "This system qualifies for High quality!\n" );
2748 com_machineSpec.SetInteger( 2 );
2749 } else if ( ghz >= ( ( cpu & CPUID_AMD ) ? 1.1f : 1.25f ) && vidRam >= 128 && sysRam >= 384 ) {
2750 Printf( "This system qualifies for Medium quality.\n" );
2751 com_machineSpec.SetInteger( 1 );
2753 Printf( "This system qualifies for Low quality.\n" );
2754 com_machineSpec.SetInteger( 0 );
2756 com_videoRam.SetInteger( vidRam );
2764 void idCommonLocal::Init( int argc, const char **argv, const char *cmdline ) {
2767 // set interface pointers used by idLib
2769 idLib::common = common;
2770 idLib::cvarSystem = cvarSystem;
2771 idLib::fileSystem = fileSystem;
2776 // clear warning buffer
2777 ClearWarnings( GAME_NAME " initialization" );
2779 // parse command line options
2782 // tokenize if the OS doesn't do it for us
2783 args.TokenizeString( cmdline, true );
2784 argv = args.GetArgs( &argc );
2786 ParseCommandLine( argc, argv );
2788 // init console command system
2794 // start file logging right away, before early console or whatever
2795 StartupVariable( "win_outputDebugString", false );
2797 // register all static CVars
2798 idCVar::RegisterStaticVars();
2800 // print engine version
2801 Printf( "%s\n", version.string );
2803 // initialize key input/binding, done early so bind command exists
2806 // init the console so we can take prints
2809 // get architecture info
2812 // initialize networking
2813 Sys_InitNetworking();
2815 // override cvars from command line
2816 StartupVariable( NULL, false );
2818 if ( !idAsyncNetwork::serverDedicated.GetInteger() && Sys_AlreadyRunning() ) {
2822 // initialize processor specific SIMD implementation
2828 #ifdef ID_WRITE_VERSION
2829 config_compressor = idCompressor::AllocArithmetic();
2832 // game specific initialization
2835 // don't add startup commands if no CD key is present
2837 if ( !session->CDKeysAreValid( false ) || !AddStartupCommands() ) {
2839 if ( !AddStartupCommands() ) {
2841 // if the user didn't give any commands, run default action
2842 session->StartMenu( true );
2845 Printf( "--- Common Initialization Complete ---\n" );
2847 // print all warnings queued during initialization
2851 Printf( "\nType 'help' for dedicated server info.\n\n" );
2854 // remove any prints from the notify lines
2855 console->ClearNotifyLines();
2859 com_fullyInitialized = true;
2862 catch( idException & ) {
2863 Sys_Error( "Error during initialization" );
2870 idCommonLocal::Shutdown
2873 void idCommonLocal::Shutdown( void ) {
2875 com_shuttingDown = true;
2877 idAsyncNetwork::server.Kill();
2878 idAsyncNetwork::client.Shutdown();
2880 // game specific shut down
2881 ShutdownGame( false );
2883 // shut down non-portable system services
2886 // shut down the console
2887 console->Shutdown();
2889 // shut down the key system
2890 idKeyInput::Shutdown();
2892 // shut down the cvar system
2893 cvarSystem->Shutdown();
2895 // shut down the console command system
2896 cmdSystem->Shutdown();
2898 #ifdef ID_WRITE_VERSION
2899 delete config_compressor;
2900 config_compressor = NULL;
2903 // free any buffered warning messages
2904 ClearWarnings( GAME_NAME " shutdown" );
2905 warningCaption.Clear();
2908 // free language dictionary
2909 languageDict.Clear();
2912 Mem_EnableLeakTest( "doom" );
2920 idCommonLocal::InitGame
2923 void idCommonLocal::InitGame( void ) {
2924 // initialize the file system
2927 // initialize the declaration manager
2928 declManager->Init();
2930 // force r_fullscreen 0 if running a tool
2933 idFile *file = fileSystem->OpenExplicitFileRead( fileSystem->RelativePathToOSPath( CONFIG_SPEC, "fs_savepath" ) );
2934 bool sysDetect = ( file == NULL );
2936 fileSystem->CloseFile( file );
2938 file = fileSystem->OpenFileWrite( CONFIG_SPEC );
2939 fileSystem->CloseFile( file );
2945 Com_ExecMachineSpec_f( args );
2948 // initialize the renderSystem data structures, but don't start OpenGL yet
2949 renderSystem->Init();
2951 // initialize string database right off so we can use it for loading messages
2954 PrintLoadingMessage( common->GetLanguageDict()->GetString( "#str_04344" ) );
2956 // load the font, etc
2957 console->LoadGraphics();
2959 // init journalling, etc
2962 PrintLoadingMessage( common->GetLanguageDict()->GetString( "#str_04345" ) );
2964 // exec the startup scripts
2965 cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "exec editor.cfg\n" );
2966 cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "exec default.cfg\n" );
2968 // skip the config file if "safe" is on the command line
2969 if ( !SafeMode() ) {
2970 cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "exec " CONFIG_FILE "\n" );
2972 cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "exec autoexec.cfg\n" );
2974 // reload the language dictionary now that we've loaded config files
2975 cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "reloadLanguage\n" );
2977 // run cfg execution
2978 cmdSystem->ExecuteCommandBuffer();
2980 // re-override anything from the config files with command line args
2981 StartupVariable( NULL, false );
2983 // if any archived cvars are modified after this, we will trigger a writing of the config file
2984 cvarSystem->ClearModifiedFlags( CVAR_ARCHIVE );
2986 // cvars are initialized, but not the rendering system. Allow preference startup dialog
2987 Sys_DoPreferences();
2989 // init the user command input code
2992 PrintLoadingMessage( common->GetLanguageDict()->GetString( "#str_04346" ) );
2994 // start the sound system, but don't do any hardware operations yet
2995 soundSystem->Init();
2997 PrintLoadingMessage( common->GetLanguageDict()->GetString( "#str_04347" ) );
2999 // init async network
3000 idAsyncNetwork::Init();
3003 idAsyncNetwork::server.InitPort();
3004 cvarSystem->SetCVarBool( "s_noSound", true );
3006 if ( idAsyncNetwork::serverDedicated.GetInteger() == 1 ) {
3007 idAsyncNetwork::server.InitPort();
3008 cvarSystem->SetCVarBool( "s_noSound", true );
3010 // init OpenGL, which will open a window and connect sound and input hardware
3011 PrintLoadingMessage( common->GetLanguageDict()->GetString( "#str_04348" ) );
3016 PrintLoadingMessage( common->GetLanguageDict()->GetString( "#str_04349" ) );
3018 // initialize the user interfaces
3021 // startup the script debugger
3022 // DebuggerServerInit();
3024 PrintLoadingMessage( common->GetLanguageDict()->GetString( "#str_04350" ) );
3026 // load the game dll
3029 PrintLoadingMessage( common->GetLanguageDict()->GetString( "#str_04351" ) );
3034 // have to do this twice.. first one sets the correct r_mode for the renderer init
3035 // this time around the backend is all setup correct.. a bit fugly but do not want
3036 // to mess with all the gl init at this point.. an old vid card will never qualify for
3039 Com_ExecMachineSpec_f( args );
3040 cvarSystem->SetCVarInteger( "s_numberOfSpeakers", 6 );
3041 cmdSystem->BufferCommandText( CMD_EXEC_NOW, "s_restart\n" );
3042 cmdSystem->ExecuteCommandBuffer();
3048 idCommonLocal::ShutdownGame
3051 void idCommonLocal::ShutdownGame( bool reloading ) {
3054 idSoundWorld *sw = soundSystem->GetPlayingSoundWorld();
3056 sw->StopAllSounds();
3058 soundSystem->ClearBuffer();
3060 // shutdown the script debugger
3061 // DebuggerServerShutdown();
3063 idAsyncNetwork::client.Shutdown();
3065 // shut down the session
3066 session->Shutdown();
3068 // shut down the user interfaces
3069 uiManager->Shutdown();
3071 // shut down the sound system
3072 soundSystem->Shutdown();
3074 // shut down async networking
3075 idAsyncNetwork::Shutdown();
3077 // shut down the user command input code
3078 usercmdGen->Shutdown();
3080 // shut down the event loop
3081 eventLoop->Shutdown();
3083 // shut down the renderSystem
3084 renderSystem->Shutdown();
3086 // shutdown the decl manager
3087 declManager->Shutdown();
3089 // unload the game dll
3092 // dump warnings to "warnings.txt"
3096 // only shut down the log file after all output is done
3099 // shut down the file system
3100 fileSystem->Shutdown( reloading );