diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index fe7c48a5..e7ddc36c 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -339,6 +339,10 @@ Using the models argument will also export all needed models by entity declarati * Added invertGreen( normalmap.png ) material keyword to allow flipping the Y-Axis for tangent space normal maps +* Changed to sys_lang to be saved to config so it has to be set per cmdline only a single time + +* Fixed bug that GOG builds default to Japanese instead of English + _______________________________________ diff --git a/neo/astyle-code.bat b/neo/astyle-code.bat index 8e8fe323..1bb359b9 100644 --- a/neo/astyle-code.bat +++ b/neo/astyle-code.bat @@ -1,5 +1,5 @@ astyle.exe -v --formatted --options=astyle-options.ini --exclude="libs" --exclude="extern" --recursive *.h -astyle.exe -v --formatted --options=astyle-options.ini --exclude="libs" --exclude="extern" --exclude="d3xp/gamesys/SysCvar.cpp" --exclude="d3xp/gamesys/Callbacks.cpp" --exclude="sys/win32/win_cpu.cpp" --exclude="sys/win32/win_main.cpp" --recursive *.cpp +astyle.exe -v --formatted --options=astyle-options.ini --exclude="libs" --exclude="extern" --exclude="d3xp/gamesys/SysCvar.cpp" --exclude="d3xp/gamesys/Callbacks.cpp" --exclude="sys/win32/win_cpu.cpp" --recursive *.cpp astyle.exe -v --formatted --options=astyle-options.ini --recursive libs/imgui/*.h astyle.exe -v --formatted --options=astyle-options.ini --recursive libs/imgui/*.cpp diff --git a/neo/framework/CVarSystem.cpp b/neo/framework/CVarSystem.cpp index 8b71e2e9..0c97a7f4 100644 --- a/neo/framework/CVarSystem.cpp +++ b/neo/framework/CVarSystem.cpp @@ -387,7 +387,7 @@ void idInternalCVar::Set( const char* newValue, bool force, bool fromServer ) if( flags & CVAR_INIT ) { - common->Printf( "%s is write protected.\n", nameString.c_str() ); + common->Printf( "%s is write protected and can only be set from the cmdline (or autoexec.cfg).\n", nameString.c_str() ); return; } } diff --git a/neo/sys/sys_local.cpp b/neo/sys/sys_local.cpp index c0fb56cb..d16de819 100644 --- a/neo/sys/sys_local.cpp +++ b/neo/sys/sys_local.cpp @@ -37,7 +37,8 @@ const char* sysLanguageNames[] = const int numLanguages = sizeof( sysLanguageNames ) / sizeof sysLanguageNames[ 0 ] - 1; -idCVar sys_lang( "sys_lang", ID_LANG_ENGLISH, CVAR_SYSTEM | CVAR_INIT, "", sysLanguageNames, idCmdSystem::ArgCompletion_String ); +// RB: allow sys_lang to be saved to config so it has to be set per cmdline only a single time +idCVar sys_lang( "sys_lang", ID_LANG_ENGLISH, CVAR_SYSTEM | CVAR_INIT | CVAR_ARCHIVE, "", sysLanguageNames, idCmdSystem::ArgCompletion_String ); idSysLocal sysLocal; idSys* sys = &sysLocal; @@ -295,6 +296,12 @@ const char* Sys_DefaultLanguage() return ID_LANG_ENGLISH; } + // GK: Prevent sys_lang to revert to english if is set manually + if( idStr::Icmp( ID_LANG_ENGLISH, sys_lang.GetString() ) != 0 ) + { + return sys_lang.GetString(); + } + idStr fileName; //D3XP: Instead of just loading a single lang file for each language @@ -329,14 +336,14 @@ const char* Sys_DefaultLanguage() } else { - if( currentLangList.Find( ID_LANG_JAPANESE ) ) - { - sys_lang.SetString( ID_LANG_JAPANESE ); - } - else if( currentLangList.Find( ID_LANG_ENGLISH ) ) + if( currentLangList.Find( ID_LANG_ENGLISH ) ) { sys_lang.SetString( ID_LANG_ENGLISH ); } + else if( currentLangList.Find( ID_LANG_JAPANESE ) ) + { + sys_lang.SetString( ID_LANG_JAPANESE ); + } else if( currentLangList.Find( ID_LANG_FRENCH ) ) { sys_lang.SetString( ID_LANG_FRENCH ); diff --git a/neo/sys/win32/win_main.cpp b/neo/sys/win32/win_main.cpp index 23c64041..ed2116fd 100644 --- a/neo/sys/win32/win_main.cpp +++ b/neo/sys/win32/win_main.cpp @@ -2,10 +2,10 @@ =========================================================================== Doom 3 BFG Edition GPL Source Code -Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. +Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. Copyright (C) 2012 Robert Beckebans -This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). +This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -41,8 +41,8 @@ If you have questions concerning this license or the applicable additional terms #include #ifndef __MRC__ -#include -#include + #include + #include #endif #include "../sys_local.h" @@ -73,7 +73,8 @@ static HANDLE hProcessMutex; Sys_GetExeLaunchMemoryStatus ================ */ -void Sys_GetExeLaunchMemoryStatus( sysMemoryStats_t &stats ) { +void Sys_GetExeLaunchMemoryStatus( sysMemoryStats_t& stats ) +{ stats = exeLaunchMemoryStats; } @@ -82,7 +83,8 @@ void Sys_GetExeLaunchMemoryStatus( sysMemoryStats_t &stats ) { Sys_Sentry ================== */ -void Sys_Sentry() { +void Sys_Sentry() +{ } @@ -104,13 +106,13 @@ idCVar sys_showMallocs( "sys_showMallocs", "0", CVAR_SYSTEM, "" ); typedef struct CrtMemBlockHeader { - struct _CrtMemBlockHeader *pBlockHeaderNext; // Pointer to the block allocated just before this one: - struct _CrtMemBlockHeader *pBlockHeaderPrev; // Pointer to the block allocated just after this one - char *szFileName; // File name - int nLine; // Line number - size_t nDataSize; // Size of user block - int nBlockUse; // Type of block - long lRequest; // Allocation number + struct _CrtMemBlockHeader* pBlockHeaderNext; // Pointer to the block allocated just before this one: + struct _CrtMemBlockHeader* pBlockHeaderPrev; // Pointer to the block allocated just after this one + char* szFileName; // File name + int nLine; // Line number + size_t nDataSize; // Size of user block + int nBlockUse; // Type of block + long lRequest; // Allocation number byte gap[4]; // Buffer just before (lower than) the user's memory: } CrtMemBlockHeader; @@ -123,22 +125,23 @@ Sys_AllocHook called for every malloc/new/free/delete ================== */ -int Sys_AllocHook( int nAllocType, void *pvData, size_t nSize, int nBlockUse, long lRequest, const unsigned char * szFileName, int nLine ) +int Sys_AllocHook( int nAllocType, void* pvData, size_t nSize, int nBlockUse, long lRequest, const unsigned char* szFileName, int nLine ) { - CrtMemBlockHeader *pHead; - byte *temp; + CrtMemBlockHeader* pHead; + byte* temp; - if ( nBlockUse == _CRT_BLOCK ) + if( nBlockUse == _CRT_BLOCK ) { - return( TRUE ); + return( TRUE ); } // get a pointer to memory block header - temp = ( byte * )pvData; + temp = ( byte* )pvData; temp -= 32; - pHead = ( CrtMemBlockHeader * )temp; + pHead = ( CrtMemBlockHeader* )temp; - switch( nAllocType ) { + switch( nAllocType ) + { case _HOOK_ALLOC: debug_total_alloc += nSize; debug_current_alloc += nSize; @@ -177,9 +180,10 @@ int Sys_AllocHook( int nAllocType, void *pvData, size_t nSize, int nBlockUse, lo Sys_DebugMemory_f ================== */ -void Sys_DebugMemory_f() { - common->Printf( "Total allocation %8dk in %d blocks\n", debug_total_alloc / 1024, debug_total_alloc_count ); - common->Printf( "Current allocation %8dk in %d blocks\n", debug_current_alloc / 1024, debug_current_alloc_count ); +void Sys_DebugMemory_f() +{ + common->Printf( "Total allocation %8dk in %d blocks\n", debug_total_alloc / 1024, debug_total_alloc_count ); + common->Printf( "Current allocation %8dk in %d blocks\n", debug_current_alloc / 1024, debug_current_alloc_count ); } /* @@ -187,9 +191,11 @@ void Sys_DebugMemory_f() { Sys_MemFrame ================== */ -void Sys_MemFrame() { - if( sys_showMallocs.GetInteger() ) { - common->Printf("Frame: %8dk in %5d blocks\n", debug_frame_alloc / 1024, debug_frame_alloc_count ); +void Sys_MemFrame() +{ + if( sys_showMallocs.GetInteger() ) + { + common->Printf( "Frame: %8dk in %5d blocks\n", debug_frame_alloc / 1024, debug_frame_alloc_count ); } debug_frame_alloc = 0; @@ -206,7 +212,8 @@ On windows, the vertex buffers are write combined, so they don't need to be flushed from the cache ================== */ -void Sys_FlushCacheMemory( void *base, int bytes ) { +void Sys_FlushCacheMemory( void* base, int bytes ) +{ } /* @@ -216,14 +223,15 @@ Sys_Error Show the early console as an error dialog ============= */ -void Sys_Error( const char *error, ... ) { +void Sys_Error( const char* error, ... ) +{ va_list argptr; char text[4096]; - MSG msg; + MSG msg; va_start( argptr, error ); vsprintf( text, error, argptr ); - va_end( argptr); + va_end( argptr ); Conbuf_AppendText( text ); Conbuf_AppendText( "\n" ); @@ -238,10 +246,13 @@ void Sys_Error( const char *error, ... ) { GLimp_Shutdown(); extern idCVar com_productionMode; - if ( com_productionMode.GetInteger() == 0 ) { + if( com_productionMode.GetInteger() == 0 ) + { // wait for the user to quit - while ( 1 ) { - if ( !GetMessage( &msg, NULL, 0, 0 ) ) { + while( 1 ) + { + if( !GetMessage( &msg, NULL, 0, 0 ) ) + { common->Quit(); } TranslateMessage( &msg ); @@ -250,7 +261,7 @@ void Sys_Error( const char *error, ... ) { } Sys_DestroyConsole(); - exit (1); + exit( 1 ); } /* @@ -258,18 +269,20 @@ void Sys_Error( const char *error, ... ) { Sys_Launch ======================== */ -void Sys_Launch( const char * path, idCmdArgs & args, void * data, unsigned int dataSize ) { +void Sys_Launch( const char* path, idCmdArgs& args, void* data, unsigned int dataSize ) +{ TCHAR szPathOrig[_MAX_PATH]; STARTUPINFO si; PROCESS_INFORMATION pi; - ZeroMemory( &si, sizeof(si) ); - si.cb = sizeof(si); + ZeroMemory( &si, sizeof( si ) ); + si.cb = sizeof( si ); - strcpy( szPathOrig, va( "\"%s\" %s", Sys_EXEPath(), (const char *)data ) ); + strcpy( szPathOrig, va( "\"%s\" %s", Sys_EXEPath(), ( const char* )data ) ); - if ( !CreateProcess( NULL, szPathOrig, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi ) ) { + if( !CreateProcess( NULL, szPathOrig, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi ) ) + { idLib::Error( "Could not start process: '%s' ", szPathOrig ); return; } @@ -281,7 +294,8 @@ void Sys_Launch( const char * path, idCmdArgs & args, void * data, unsigned int Sys_GetCmdLine ======================== */ -const char * Sys_GetCmdLine() { +const char* Sys_GetCmdLine() +{ return sys_cmdline; } @@ -290,13 +304,14 @@ const char * Sys_GetCmdLine() { Sys_ReLaunch ======================== */ -void Sys_ReLaunch() { +void Sys_ReLaunch() +{ TCHAR szPathOrig[MAX_PRINT_MSG]; STARTUPINFO si; PROCESS_INFORMATION pi; - ZeroMemory( &si, sizeof(si) ); - si.cb = sizeof(si); + ZeroMemory( &si, sizeof( si ) ); + si.cb = sizeof( si ); // DG: we don't have function arguments in Sys_ReLaunch() anymore, everyone only passed // the command-line +" +set com_skipIntroVideos 1" anyway and it was painful on POSIX systems @@ -312,7 +327,8 @@ void Sys_ReLaunch() { CloseHandle( hProcessMutex ); - if ( !CreateProcess( NULL, szPathOrig, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi ) ) { + if( !CreateProcess( NULL, szPathOrig, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi ) ) + { idLib::Error( "Could not start process: '%s' ", szPathOrig ); return; } @@ -324,7 +340,8 @@ void Sys_ReLaunch() { Sys_Quit ============== */ -void Sys_Quit() { +void Sys_Quit() +{ timeEndPeriod( 1 ); Sys_ShutdownInput(); Sys_DestroyConsole(); @@ -338,18 +355,20 @@ Sys_Printf ============== */ #define MAXPRINTMSG 4096 -void Sys_Printf( const char *fmt, ... ) { +void Sys_Printf( const char* fmt, ... ) +{ char msg[MAXPRINTMSG]; va_list argptr; - va_start(argptr, fmt); - idStr::vsnPrintf( msg, MAXPRINTMSG-1, fmt, argptr ); - va_end(argptr); - msg[sizeof(msg)-1] = '\0'; + va_start( argptr, fmt ); + idStr::vsnPrintf( msg, MAXPRINTMSG - 1, fmt, argptr ); + va_end( argptr ); + msg[sizeof( msg ) - 1] = '\0'; OutputDebugString( msg ); - if ( win32.win_outputEditString.GetBool() && idLib::IsMainThread() ) { + if( win32.win_outputEditString.GetBool() && idLib::IsMainThread() ) + { Conbuf_AppendText( msg ); } } @@ -360,13 +379,14 @@ Sys_DebugPrintf ============== */ #define MAXPRINTMSG 4096 -void Sys_DebugPrintf( const char *fmt, ... ) { +void Sys_DebugPrintf( const char* fmt, ... ) +{ char msg[MAXPRINTMSG]; va_list argptr; va_start( argptr, fmt ); - idStr::vsnPrintf( msg, MAXPRINTMSG-1, fmt, argptr ); - msg[ sizeof(msg)-1 ] = '\0'; + idStr::vsnPrintf( msg, MAXPRINTMSG - 1, fmt, argptr ); + msg[ sizeof( msg ) - 1 ] = '\0'; va_end( argptr ); OutputDebugString( msg ); @@ -377,11 +397,12 @@ void Sys_DebugPrintf( const char *fmt, ... ) { Sys_DebugVPrintf ============== */ -void Sys_DebugVPrintf( const char *fmt, va_list arg ) { +void Sys_DebugVPrintf( const char* fmt, va_list arg ) +{ char msg[MAXPRINTMSG]; - idStr::vsnPrintf( msg, MAXPRINTMSG-1, fmt, arg ); - msg[ sizeof(msg)-1 ] = '\0'; + idStr::vsnPrintf( msg, MAXPRINTMSG - 1, fmt, arg ); + msg[ sizeof( msg ) - 1 ] = '\0'; OutputDebugString( msg ); } @@ -391,7 +412,8 @@ void Sys_DebugVPrintf( const char *fmt, va_list arg ) { Sys_Sleep ============== */ -void Sys_Sleep( int msec ) { +void Sys_Sleep( int msec ) +{ Sleep( msec ); } @@ -400,7 +422,8 @@ void Sys_Sleep( int msec ) { Sys_ShowWindow ============== */ -void Sys_ShowWindow( bool show ) { +void Sys_ShowWindow( bool show ) +{ ::ShowWindow( win32.hWnd, show ? SW_SHOW : SW_HIDE ); } @@ -409,7 +432,8 @@ void Sys_ShowWindow( bool show ) { Sys_IsWindowVisible ============== */ -bool Sys_IsWindowVisible() { +bool Sys_IsWindowVisible() +{ return ( ::IsWindowVisible( win32.hWnd ) != 0 ); } @@ -418,8 +442,9 @@ bool Sys_IsWindowVisible() { Sys_Mkdir ============== */ -void Sys_Mkdir( const char *path ) { - _mkdir (path); +void Sys_Mkdir( const char* path ) +{ + _mkdir( path ); } /* @@ -427,20 +452,22 @@ void Sys_Mkdir( const char *path ) { Sys_FileTimeStamp ================= */ -ID_TIME_T Sys_FileTimeStamp( idFileHandle fp ) { +ID_TIME_T Sys_FileTimeStamp( idFileHandle fp ) +{ FILETIME writeTime; GetFileTime( fp, NULL, NULL, &writeTime ); /* - FILETIME = number of 100-nanosecond ticks since midnight - 1 Jan 1601 UTC. time_t = number of 1-second ticks since + FILETIME = number of 100-nanosecond ticks since midnight + 1 Jan 1601 UTC. time_t = number of 1-second ticks since midnight 1 Jan 1970 UTC. To translate, we subtract a FILETIME representation of midnight, 1 Jan 1970 from the time in question and divide by the number of 100-ns ticks in one second. */ - SYSTEMTIME base_st = { + SYSTEMTIME base_st = + { 1970, // wYear 1, // wMonth 0, // wDayOfWeek @@ -466,7 +493,8 @@ ID_TIME_T Sys_FileTimeStamp( idFileHandle fp ) { Sys_Rmdir ======================== */ -bool Sys_Rmdir( const char *path ) { +bool Sys_Rmdir( const char* path ) +{ return _rmdir( path ) == 0; } @@ -475,9 +503,11 @@ bool Sys_Rmdir( const char *path ) { Sys_IsFileWritable ======================== */ -bool Sys_IsFileWritable( const char *path ) { +bool Sys_IsFileWritable( const char* path ) +{ struct _stat st; - if ( _stat( path, &st ) == -1 ) { + if( _stat( path, &st ) == -1 ) + { return true; } return ( st.st_mode & S_IWRITE ) != 0; @@ -488,9 +518,11 @@ bool Sys_IsFileWritable( const char *path ) { Sys_IsFolder ======================== */ -sysFolder_t Sys_IsFolder( const char *path ) { +sysFolder_t Sys_IsFolder( const char* path ) +{ struct _stat buffer; - if ( _stat( path, &buffer ) < 0 ) { + if( _stat( path, &buffer ) < 0 ) + { return FOLDER_ERROR; } return ( buffer.st_mode & _S_IFDIR ) != 0 ? FOLDER_YES : FOLDER_NO; @@ -501,11 +533,12 @@ sysFolder_t Sys_IsFolder( const char *path ) { Sys_Cwd ============== */ -const char *Sys_Cwd() { +const char* Sys_Cwd() +{ static char cwd[MAX_OSPATH]; _getcwd( cwd, sizeof( cwd ) - 1 ); - cwd[MAX_OSPATH-1] = 0; + cwd[MAX_OSPATH - 1] = 0; return cwd; } @@ -515,12 +548,13 @@ const char *Sys_Cwd() { Sys_DefaultBasePath ============== */ -const char *Sys_DefaultBasePath() { +const char* Sys_DefaultBasePath() +{ return Sys_Cwd(); } // Vista shit -typedef HRESULT (WINAPI * SHGetKnownFolderPath_t)( const GUID & rfid, DWORD dwFlags, HANDLE hToken, PWSTR *ppszPath ); +typedef HRESULT( WINAPI* SHGetKnownFolderPath_t )( const GUID& rfid, DWORD dwFlags, HANDLE hToken, PWSTR* ppszPath ); // NOTE: FOLIDERID_SavedGames is already exported from in shell32.dll in Windows 7. We can only detect // the compiler version, but that doesn't doesn't tell us which version of the OS we're linking against. // This GUID value should never change, so we name it something other than FOLDERID_SavedGames to get @@ -532,25 +566,29 @@ const GUID FOLDERID_SavedGames_IdTech5 = { 0x4c5c32ff, 0xbb9d, 0x43b0, { 0xb5, 0 Sys_DefaultSavePath ============== */ -const char *Sys_DefaultSavePath() { +const char* Sys_DefaultSavePath() +{ static char savePath[ MAX_PATH ]; memset( savePath, 0, MAX_PATH ); HMODULE hShell = LoadLibrary( "shell32.dll" ); - if ( hShell ) { - SHGetKnownFolderPath_t SHGetKnownFolderPath = (SHGetKnownFolderPath_t)GetProcAddress( hShell, "SHGetKnownFolderPath" ); - if ( SHGetKnownFolderPath ) { - wchar_t * path; + if( hShell ) + { + SHGetKnownFolderPath_t SHGetKnownFolderPath = ( SHGetKnownFolderPath_t )GetProcAddress( hShell, "SHGetKnownFolderPath" ); + if( SHGetKnownFolderPath ) + { + wchar_t* path; // RB FIXME? #if defined(__MINGW32__) - if ( SUCCEEDED( SHGetKnownFolderPath( FOLDERID_SavedGames_IdTech5, CSIDL_FLAG_CREATE, 0, &path ) ) ) + if( SUCCEEDED( SHGetKnownFolderPath( FOLDERID_SavedGames_IdTech5, CSIDL_FLAG_CREATE, 0, &path ) ) ) #else - if ( SUCCEEDED( SHGetKnownFolderPath( FOLDERID_SavedGames_IdTech5, CSIDL_FLAG_CREATE | CSIDL_FLAG_PER_USER_INIT, 0, &path ) ) ) + if( SUCCEEDED( SHGetKnownFolderPath( FOLDERID_SavedGames_IdTech5, CSIDL_FLAG_CREATE | CSIDL_FLAG_PER_USER_INIT, 0, &path ) ) ) #endif - // RB end + // RB end { - if ( wcstombs( savePath, path, MAX_PATH ) > MAX_PATH ) { + if( wcstombs( savePath, path, MAX_PATH ) > MAX_PATH ) + { savePath[0] = 0; } CoTaskMemFree( path ); @@ -559,7 +597,7 @@ const char *Sys_DefaultSavePath() { FreeLibrary( hShell ); } - if ( savePath[0] == 0 ) + if( savePath[0] == 0 ) { // RB: looks like a bug in the shlobj.h #if defined(__MINGW32__) @@ -581,7 +619,8 @@ const char *Sys_DefaultSavePath() { Sys_EXEPath ============== */ -const char *Sys_EXEPath() { +const char* Sys_EXEPath() +{ static char exe[ MAX_OSPATH ]; GetModuleFileName( NULL, exe, sizeof( exe ) - 1 ); return exe; @@ -592,7 +631,8 @@ const char *Sys_EXEPath() { Sys_ListFiles ============== */ -int Sys_ListFiles( const char *directory, const char *extension, idStrList &list ) { +int Sys_ListFiles( const char* directory, const char* extension, idStrList& list ) +{ idStr search; struct _finddata_t findinfo; // RB: 64 bit fixes, changed int to intptr_t @@ -600,15 +640,19 @@ int Sys_ListFiles( const char *directory, const char *extension, idStrList &list // RB end int flag; - if ( !extension) { + if( !extension ) + { extension = ""; } // passing a slash as extension will find directories - if ( extension[0] == '/' && extension[1] == 0 ) { + if( extension[0] == '/' && extension[1] == 0 ) + { extension = ""; flag = 0; - } else { + } + else + { flag = _A_SUBDIR; } @@ -618,15 +662,19 @@ int Sys_ListFiles( const char *directory, const char *extension, idStrList &list list.Clear(); findhandle = _findfirst( search, &findinfo ); - if ( findhandle == -1 ) { + if( findhandle == -1 ) + { return -1; } - do { - if ( flag ^ ( findinfo.attrib & _A_SUBDIR ) ) { + do + { + if( flag ^ ( findinfo.attrib & _A_SUBDIR ) ) + { list.Append( findinfo.name ); } - } while ( _findnext( findhandle, &findinfo ) != -1 ); + } + while( _findnext( findhandle, &findinfo ) != -1 ); _findclose( findhandle ); @@ -639,19 +687,23 @@ int Sys_ListFiles( const char *directory, const char *extension, idStrList &list Sys_GetClipboardData ================ */ -char *Sys_GetClipboardData() { - char *data = NULL; - char *cliptext; +char* Sys_GetClipboardData() +{ + char* data = NULL; + char* cliptext; - if ( OpenClipboard( NULL ) != 0 ) { + if( OpenClipboard( NULL ) != 0 ) + { HANDLE hClipboardData; - if ( ( hClipboardData = GetClipboardData( CF_TEXT ) ) != 0 ) { - if ( ( cliptext = (char *)GlobalLock( hClipboardData ) ) != 0 ) { - data = (char *)Mem_Alloc( GlobalSize( hClipboardData ) + 1, TAG_CRAP ); + if( ( hClipboardData = GetClipboardData( CF_TEXT ) ) != 0 ) + { + if( ( cliptext = ( char* )GlobalLock( hClipboardData ) ) != 0 ) + { + data = ( char* )Mem_Alloc( GlobalSize( hClipboardData ) + 1, TAG_CRAP ); strcpy( data, cliptext ); GlobalUnlock( hClipboardData ); - + strtok( data, "\n\r\b" ); } } @@ -665,18 +717,21 @@ char *Sys_GetClipboardData() { Sys_SetClipboardData ================ */ -void Sys_SetClipboardData( const char *string ) { +void Sys_SetClipboardData( const char* string ) +{ HGLOBAL HMem; - char *PMem; + char* PMem; // allocate memory block - HMem = (char *)::GlobalAlloc( GMEM_MOVEABLE | GMEM_DDESHARE, strlen( string ) + 1 ); - if ( HMem == NULL ) { + HMem = ( char* )::GlobalAlloc( GMEM_MOVEABLE | GMEM_DDESHARE, strlen( string ) + 1 ); + if( HMem == NULL ) + { return; } // lock allocated memory and obtain a pointer - PMem = (char *)::GlobalLock( HMem ); - if ( PMem == NULL ) { + PMem = ( char* )::GlobalLock( HMem ); + if( PMem == NULL ) + { return; } // copy text into allocated memory block @@ -684,7 +739,8 @@ void Sys_SetClipboardData( const char *string ) { // unlock allocated memory ::GlobalUnlock( HMem ); // open Clipboard - if ( !OpenClipboard( 0 ) ) { + if( !OpenClipboard( 0 ) ) + { ::GlobalFree( HMem ); return; } @@ -702,7 +758,8 @@ void Sys_SetClipboardData( const char *string ) { ExecOutputFn ======================== */ -static void ExecOutputFn( const char * text ) { +static void ExecOutputFn( const char* text ) +{ idLib::Printf( text ); } @@ -716,149 +773,172 @@ If waitMsec is -1, don't wait for the process to exit Other waitMsec values will allow the workFn to be called at those intervals. ======================== */ -bool Sys_Exec( const char * appPath, const char * workingPath, const char * args, - execProcessWorkFunction_t workFn, execOutputFunction_t outputFn, const int waitMS, - unsigned int & exitCode ) { - exitCode = 0; - SECURITY_ATTRIBUTES secAttr; - secAttr.nLength = sizeof( SECURITY_ATTRIBUTES ); - secAttr.bInheritHandle = TRUE; - secAttr.lpSecurityDescriptor = NULL; +bool Sys_Exec( const char* appPath, const char* workingPath, const char* args, + execProcessWorkFunction_t workFn, execOutputFunction_t outputFn, const int waitMS, + unsigned int& exitCode ) +{ + exitCode = 0; + SECURITY_ATTRIBUTES secAttr; + secAttr.nLength = sizeof( SECURITY_ATTRIBUTES ); + secAttr.bInheritHandle = TRUE; + secAttr.lpSecurityDescriptor = NULL; - HANDLE hStdOutRead; - HANDLE hStdOutWrite; - CreatePipe( &hStdOutRead, &hStdOutWrite, &secAttr, 0 ); - SetHandleInformation( hStdOutRead, HANDLE_FLAG_INHERIT, 0 ); + HANDLE hStdOutRead; + HANDLE hStdOutWrite; + CreatePipe( &hStdOutRead, &hStdOutWrite, &secAttr, 0 ); + SetHandleInformation( hStdOutRead, HANDLE_FLAG_INHERIT, 0 ); - HANDLE hStdInRead; - HANDLE hStdInWrite; - CreatePipe( &hStdInRead, &hStdInWrite, &secAttr, 0 ); - SetHandleInformation( hStdInWrite, HANDLE_FLAG_INHERIT, 0 ); + HANDLE hStdInRead; + HANDLE hStdInWrite; + CreatePipe( &hStdInRead, &hStdInWrite, &secAttr, 0 ); + SetHandleInformation( hStdInWrite, HANDLE_FLAG_INHERIT, 0 ); - STARTUPINFO si; - memset( &si, 0, sizeof( si ) ); - si.cb = sizeof( si ); - si.hStdError = hStdOutWrite; - si.hStdOutput = hStdOutWrite; - si.hStdInput = hStdInRead; - si.wShowWindow = FALSE; - si.dwFlags |= STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; + STARTUPINFO si; + memset( &si, 0, sizeof( si ) ); + si.cb = sizeof( si ); + si.hStdError = hStdOutWrite; + si.hStdOutput = hStdOutWrite; + si.hStdInput = hStdInRead; + si.wShowWindow = FALSE; + si.dwFlags |= STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; - PROCESS_INFORMATION pi; - memset ( &pi, 0, sizeof( pi ) ); + PROCESS_INFORMATION pi; + memset( &pi, 0, sizeof( pi ) ); - if ( outputFn != NULL ) { - outputFn( va( "^2Executing Process: ^7%s\n^2working path: ^7%s\n^2args: ^7%s\n", appPath, workingPath, args ) ); - } else { - outputFn = ExecOutputFn; - } + if( outputFn != NULL ) + { + outputFn( va( "^2Executing Process: ^7%s\n^2working path: ^7%s\n^2args: ^7%s\n", appPath, workingPath, args ) ); + } + else + { + outputFn = ExecOutputFn; + } - // we duplicate args here so we can concatenate the exe name and args into a single command line - const char * imageName = appPath; - char * cmdLine = NULL; + // we duplicate args here so we can concatenate the exe name and args into a single command line + const char* imageName = appPath; + char* cmdLine = NULL; + { + // if we have any args, we need to copy them to a new buffer because CreateProcess modifies + // the command line buffer. + if( args != NULL ) { - // if we have any args, we need to copy them to a new buffer because CreateProcess modifies - // the command line buffer. - if ( args != NULL ) { - if ( appPath != NULL ) { - int len = idStr::Length( args ) + idStr::Length( appPath ) + 1 /* for space */ + 1 /* for NULL terminator */ + 2 /* app quotes */; - cmdLine = (char*)Mem_Alloc( len, TAG_TEMP ); - // note that we're putting quotes around the appPath here because when AAS2.exe gets an app path with spaces - // in the path "w:/zion/build/win32/Debug with Inlines/AAS2.exe" it gets more than one arg for the app name, - // which it most certainly should not, so I am assuming this is a side effect of using CreateProcess. - idStr::snPrintf( cmdLine, len, "\"%s\" %s", appPath, args ); - } else { - int len = idStr::Length( args ) + 1; - cmdLine = (char*)Mem_Alloc( len, TAG_TEMP ); - idStr::Copynz( cmdLine, args, len ); - } - // the image name should always be NULL if we have command line arguments because it is already - // prefixed to the command line. - imageName = NULL; + if( appPath != NULL ) + { + int len = idStr::Length( args ) + idStr::Length( appPath ) + 1 /* for space */ + 1 /* for NULL terminator */ + 2 /* app quotes */; + cmdLine = ( char* )Mem_Alloc( len, TAG_TEMP ); + // note that we're putting quotes around the appPath here because when AAS2.exe gets an app path with spaces + // in the path "w:/zion/build/win32/Debug with Inlines/AAS2.exe" it gets more than one arg for the app name, + // which it most certainly should not, so I am assuming this is a side effect of using CreateProcess. + idStr::snPrintf( cmdLine, len, "\"%s\" %s", appPath, args ); } + else + { + int len = idStr::Length( args ) + 1; + cmdLine = ( char* )Mem_Alloc( len, TAG_TEMP ); + idStr::Copynz( cmdLine, args, len ); + } + // the image name should always be NULL if we have command line arguments because it is already + // prefixed to the command line. + imageName = NULL; } + } - BOOL result = CreateProcess( imageName, (LPSTR)cmdLine, NULL, NULL, TRUE, 0, NULL, workingPath, &si, &pi ); + BOOL result = CreateProcess( imageName, ( LPSTR )cmdLine, NULL, NULL, TRUE, 0, NULL, workingPath, &si, &pi ); - if ( result == FALSE ) { - TCHAR szBuf[1024]; - LPVOID lpMsgBuf; - DWORD dw = GetLastError(); + if( result == FALSE ) + { + TCHAR szBuf[1024]; + LPVOID lpMsgBuf; + DWORD dw = GetLastError(); - FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - dw, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR) &lpMsgBuf, - 0, NULL ); + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + dw, + MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), + ( LPTSTR ) &lpMsgBuf, + 0, NULL ); - wsprintf( szBuf, "%d: %s", dw, lpMsgBuf ); - if ( outputFn != NULL ) { - outputFn( szBuf ); - } - LocalFree( lpMsgBuf ); - if ( cmdLine != NULL ) { - Mem_Free( cmdLine ); - } - return false; - } else if ( waitMS >= 0 ) { // if waitMS == -1, don't wait for process to exit - DWORD ec = 0; - DWORD wait = 0; - char buffer[ 4096 ]; - for ( ; ; ) { - wait = WaitForSingleObject( pi.hProcess, waitMS ); - GetExitCodeProcess( pi.hProcess, &ec ); - - DWORD bytesRead = 0; - DWORD bytesAvail = 0; - DWORD bytesLeft = 0; - BOOL ok = PeekNamedPipe( hStdOutRead, NULL, 0, NULL, &bytesAvail, &bytesLeft ); - if ( ok && bytesAvail != 0 ) { - ok = ReadFile( hStdOutRead, buffer, sizeof( buffer ) - 3, &bytesRead, NULL ); - if ( ok && bytesRead > 0 ) { - buffer[ bytesRead ] = '\0'; - if ( outputFn != NULL ) { - int length = 0; - for ( int i = 0; buffer[i] != '\0'; i++ ) { - if ( buffer[i] != '\r' ) { - buffer[length++] = buffer[i]; - } - } - buffer[length++] = '\0'; - outputFn( buffer ); - } - } - } - - if ( ec != STILL_ACTIVE ) { - exitCode = ec; - break; - } - - if ( workFn != NULL ) { - if ( !workFn() ) { - TerminateProcess( pi.hProcess, 0 ); - break; - } - } - } + wsprintf( szBuf, "%d: %s", dw, lpMsgBuf ); + if( outputFn != NULL ) + { + outputFn( szBuf ); } - - // this assumes that windows duplicates the command line string into the created process's - // environment space. - if ( cmdLine != NULL ) { + LocalFree( lpMsgBuf ); + if( cmdLine != NULL ) + { Mem_Free( cmdLine ); } + return false; + } + else if( waitMS >= 0 ) // if waitMS == -1, don't wait for process to exit + { + DWORD ec = 0; + DWORD wait = 0; + char buffer[ 4096 ]; + for( ; ; ) + { + wait = WaitForSingleObject( pi.hProcess, waitMS ); + GetExitCodeProcess( pi.hProcess, &ec ); - CloseHandle( pi.hProcess ); - CloseHandle( pi.hThread ); - CloseHandle( hStdOutRead ); - CloseHandle( hStdOutWrite ); - CloseHandle( hStdInRead ); - CloseHandle( hStdInWrite ); - return true; + DWORD bytesRead = 0; + DWORD bytesAvail = 0; + DWORD bytesLeft = 0; + BOOL ok = PeekNamedPipe( hStdOutRead, NULL, 0, NULL, &bytesAvail, &bytesLeft ); + if( ok && bytesAvail != 0 ) + { + ok = ReadFile( hStdOutRead, buffer, sizeof( buffer ) - 3, &bytesRead, NULL ); + if( ok && bytesRead > 0 ) + { + buffer[ bytesRead ] = '\0'; + if( outputFn != NULL ) + { + int length = 0; + for( int i = 0; buffer[i] != '\0'; i++ ) + { + if( buffer[i] != '\r' ) + { + buffer[length++] = buffer[i]; + } + } + buffer[length++] = '\0'; + outputFn( buffer ); + } + } + } + + if( ec != STILL_ACTIVE ) + { + exitCode = ec; + break; + } + + if( workFn != NULL ) + { + if( !workFn() ) + { + TerminateProcess( pi.hProcess, 0 ); + break; + } + } + } + } + + // this assumes that windows duplicates the command line string into the created process's + // environment space. + if( cmdLine != NULL ) + { + Mem_Free( cmdLine ); + } + + CloseHandle( pi.hProcess ); + CloseHandle( pi.hThread ); + CloseHandle( hStdOutRead ); + CloseHandle( hStdOutWrite ); + CloseHandle( hStdInRead ); + CloseHandle( hStdInWrite ); + return true; } /* @@ -875,10 +955,10 @@ Sys_DLL_Load ===================== */ // RB: 64 bit fixes, changed int to intptr_t -intptr_t Sys_DLL_Load( const char *dllName ) +intptr_t Sys_DLL_Load( const char* dllName ) { HINSTANCE libHandle = LoadLibrary( dllName ); - return (intptr_t)libHandle; + return ( intptr_t )libHandle; } /* @@ -886,10 +966,10 @@ intptr_t Sys_DLL_Load( const char *dllName ) Sys_DLL_GetProcAddress ===================== */ -void *Sys_DLL_GetProcAddress( intptr_t dllHandle, const char *procName ) +void* Sys_DLL_GetProcAddress( intptr_t dllHandle, const char* procName ) { // RB: added missing cast - return ( void* ) GetProcAddress( (HINSTANCE)dllHandle, procName ); + return ( void* ) GetProcAddress( ( HINSTANCE )dllHandle, procName ); } /* @@ -903,19 +983,19 @@ void Sys_DLL_Unload( intptr_t dllHandle ) { return; } - - if( FreeLibrary( (HINSTANCE)dllHandle ) == 0 ) + + if( FreeLibrary( ( HINSTANCE )dllHandle ) == 0 ) { int lastError = GetLastError(); LPVOID lpMsgBuf; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER, - NULL, + NULL, lastError, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language - (LPTSTR) &lpMsgBuf, + MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), // Default language + ( LPTSTR ) &lpMsgBuf, 0, - NULL + NULL ); Sys_Error( "Sys_DLL_Unload: FreeLibrary failed - %s (%d)", lpMsgBuf, lastError ); @@ -946,13 +1026,16 @@ Ptr should either be null, or point to a block of data that can be freed by the game later. ================ */ -void Sys_QueEvent( sysEventType_t type, int value, int value2, int ptrLength, void *ptr, int inputDeviceNum ) { - sysEvent_t * ev = &eventQue[ eventHead & MASK_QUED_EVENTS ]; +void Sys_QueEvent( sysEventType_t type, int value, int value2, int ptrLength, void* ptr, int inputDeviceNum ) +{ + sysEvent_t* ev = &eventQue[ eventHead & MASK_QUED_EVENTS ]; - if ( eventHead - eventTail >= MAX_QUED_EVENTS ) { - common->Printf("Sys_QueEvent: overflow\n"); + if( eventHead - eventTail >= MAX_QUED_EVENTS ) + { + common->Printf( "Sys_QueEvent: overflow\n" ); // we are discarding an event, but don't leak memory - if ( ev->evPtr ) { + if( ev->evPtr ) + { Mem_Free( ev->evPtr ); } eventTail++; @@ -975,25 +1058,31 @@ Sys_PumpEvents This allows windows to be moved during renderbump ============= */ -void Sys_PumpEvents() { - MSG msg; +void Sys_PumpEvents() +{ + MSG msg; // pump the message loop - while( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) ) { - if ( !GetMessage( &msg, NULL, 0, 0 ) ) { + while( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) ) + { + if( !GetMessage( &msg, NULL, 0, 0 ) ) + { common->Quit(); } // save the msg time, because wndprocs don't have access to the timestamp - if ( win32.sysMsgTime && win32.sysMsgTime > (int)msg.time ) { - // don't ever let the event times run backwards + if( win32.sysMsgTime && win32.sysMsgTime > ( int )msg.time ) + { + // don't ever let the event times run backwards // common->Printf( "Sys_PumpEvents: win32.sysMsgTime (%i) > msg.time (%i)\n", win32.sysMsgTime, msg.time ); - } else { + } + else + { win32.sysMsgTime = msg.time; } - - TranslateMessage (&msg); - DispatchMessage (&msg); + + TranslateMessage( &msg ); + DispatchMessage( &msg ); } } @@ -1002,11 +1091,13 @@ void Sys_PumpEvents() { Sys_GenerateEvents ================ */ -void Sys_GenerateEvents() { +void Sys_GenerateEvents() +{ static int entered = false; - char *s; + char* s; - if ( entered ) { + if( entered ) + { return; } entered = true; @@ -1019,12 +1110,13 @@ void Sys_GenerateEvents() { // check for console commands s = Sys_ConsoleInput(); - if ( s ) { - char *b; + if( s ) + { + char* b; int len; len = strlen( s ) + 1; - b = (char *)Mem_Alloc( len, TAG_EVENTS ); + b = ( char* )Mem_Alloc( len, TAG_EVENTS ); strcpy( b, s ); Sys_QueEvent( SE_CONSOLE, 0, 0, len, b, 0 ); } @@ -1037,7 +1129,8 @@ void Sys_GenerateEvents() { Sys_ClearEvents ================ */ -void Sys_ClearEvents() { +void Sys_ClearEvents() +{ eventHead = eventTail = 0; } @@ -1046,16 +1139,18 @@ void Sys_ClearEvents() { Sys_GetEvent ================ */ -sysEvent_t Sys_GetEvent() { +sysEvent_t Sys_GetEvent() +{ sysEvent_t ev; // return if we have data - if ( eventHead > eventTail ) { + if( eventHead > eventTail ) + { eventTail++; - return eventQue[ ( eventTail - 1 ) & MASK_QUED_EVENTS ]; + return eventQue[( eventTail - 1 ) & MASK_QUED_EVENTS ]; } - // return the empty event + // return the empty event memset( &ev, 0, sizeof( ev ) ); return ev; @@ -1070,7 +1165,8 @@ Sys_In_Restart_f Restart the input subsystem ================= */ -void Sys_In_Restart_f( const idCmdArgs &args ) { +void Sys_In_Restart_f( const idCmdArgs& args ) +{ Sys_ShutdownInput(); Sys_InitInput(); } @@ -1082,11 +1178,14 @@ Sys_AlreadyRunning returns true if there is a copy of D3 running already ================ */ -bool Sys_AlreadyRunning() { +bool Sys_AlreadyRunning() +{ #ifndef DEBUG - if ( !win32.win_allowMultipleInstances.GetBool() ) { + if( !win32.win_allowMultipleInstances.GetBool() ) + { hProcessMutex = ::CreateMutex( NULL, FALSE, "DOOM3" ); - if ( ::GetLastError() == ERROR_ALREADY_EXISTS || ::GetLastError() == ERROR_ACCESS_DENIED ) { + if( ::GetLastError() == ERROR_ALREADY_EXISTS || ::GetLastError() == ERROR_ACCESS_DENIED ) + { return true; } } @@ -1104,7 +1203,8 @@ The cvar system must already be setup #define OSR2_BUILD_NUMBER 1111 #define WIN98_BUILD_NUMBER 1998 -void Sys_Init() { +void Sys_Init() +{ CoInitialize( NULL ); @@ -1123,63 +1223,101 @@ void Sys_Init() { // win32.osversion.dwOSVersionInfoSize = sizeof( win32.osversion ); - if ( !GetVersionEx( (LPOSVERSIONINFO)&win32.osversion ) ) + if( !GetVersionEx( ( LPOSVERSIONINFO )&win32.osversion ) ) + { Sys_Error( "Couldn't get OS info" ); + } - if ( win32.osversion.dwMajorVersion < 4 ) { + if( win32.osversion.dwMajorVersion < 4 ) + { Sys_Error( GAME_NAME " requires Windows version 4 (NT) or greater" ); } - if ( win32.osversion.dwPlatformId == VER_PLATFORM_WIN32s ) { + if( win32.osversion.dwPlatformId == VER_PLATFORM_WIN32s ) + { Sys_Error( GAME_NAME " doesn't run on Win32s" ); } - if( win32.osversion.dwPlatformId == VER_PLATFORM_WIN32_NT ) { - if( win32.osversion.dwMajorVersion <= 4 ) { + if( win32.osversion.dwPlatformId == VER_PLATFORM_WIN32_NT ) + { + if( win32.osversion.dwMajorVersion <= 4 ) + { win32.sys_arch.SetString( "WinNT (NT)" ); - } else if( win32.osversion.dwMajorVersion == 5 && win32.osversion.dwMinorVersion == 0 ) { + } + else if( win32.osversion.dwMajorVersion == 5 && win32.osversion.dwMinorVersion == 0 ) + { win32.sys_arch.SetString( "Win2K (NT)" ); - } else if( win32.osversion.dwMajorVersion == 5 && win32.osversion.dwMinorVersion == 1 ) { + } + else if( win32.osversion.dwMajorVersion == 5 && win32.osversion.dwMinorVersion == 1 ) + { win32.sys_arch.SetString( "WinXP (NT)" ); - } else if( win32.osversion.dwMajorVersion == 6 ) { + } + else if( win32.osversion.dwMajorVersion == 6 ) + { win32.sys_arch.SetString( "Vista" ); - } else if( win32.osversion.dwMajorVersion == 6 && win32.osversion.dwMinorVersion == 1 ) { + } + else if( win32.osversion.dwMajorVersion == 6 && win32.osversion.dwMinorVersion == 1 ) + { win32.sys_arch.SetString( "Win7" ); - } else if( win32.osversion.dwMajorVersion == 6 && win32.osversion.dwMinorVersion == 2 ) { + } + else if( win32.osversion.dwMajorVersion == 6 && win32.osversion.dwMinorVersion == 2 ) + { win32.sys_arch.SetString( "Win8" ); - } else if( win32.osversion.dwMajorVersion == 6 && win32.osversion.dwMinorVersion == 3 ) { + } + else if( win32.osversion.dwMajorVersion == 6 && win32.osversion.dwMinorVersion == 3 ) + { win32.sys_arch.SetString( "Win8.1" ); - } else { + } + else + { win32.sys_arch.SetString( "Unknown NT variant" ); } - } else if( win32.osversion.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS ) { - if( win32.osversion.dwMajorVersion == 4 && win32.osversion.dwMinorVersion == 0 ) { + } + else if( win32.osversion.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS ) + { + if( win32.osversion.dwMajorVersion == 4 && win32.osversion.dwMinorVersion == 0 ) + { // Win95 - if( win32.osversion.szCSDVersion[1] == 'C' ) { + if( win32.osversion.szCSDVersion[1] == 'C' ) + { win32.sys_arch.SetString( "Win95 OSR2 (95)" ); - } else { + } + else + { win32.sys_arch.SetString( "Win95 (95)" ); } - } else if( win32.osversion.dwMajorVersion == 4 && win32.osversion.dwMinorVersion == 10 ) { + } + else if( win32.osversion.dwMajorVersion == 4 && win32.osversion.dwMinorVersion == 10 ) + { // Win98 - if( win32.osversion.szCSDVersion[1] == 'A' ) { + if( win32.osversion.szCSDVersion[1] == 'A' ) + { win32.sys_arch.SetString( "Win98SE (95)" ); - } else { + } + else + { win32.sys_arch.SetString( "Win98 (95)" ); } - } else if( win32.osversion.dwMajorVersion == 4 && win32.osversion.dwMinorVersion == 90 ) { - // WinMe - win32.sys_arch.SetString( "WinMe (95)" ); - } else { - win32.sys_arch.SetString( "Unknown 95 variant" ); } - } else { + else if( win32.osversion.dwMajorVersion == 4 && win32.osversion.dwMinorVersion == 90 ) + { + // WinMe + win32.sys_arch.SetString( "WinMe (95)" ); + } + else + { + win32.sys_arch.SetString( "Unknown 95 variant" ); + } + } + else + { win32.sys_arch.SetString( "unknown Windows variant" ); } // // CPU type // - if ( !idStr::Icmp( win32.sys_cpustring.GetString(), "detect" ) ) { + if( !idStr::Icmp( win32.sys_cpustring.GetString(), "detect" ) ) + { idStr string; common->Printf( "%1.0f MHz ", Sys_ClockTicksPerSecond() / 1000000.0f ); @@ -1188,74 +1326,109 @@ void Sys_Init() { string.Clear(); - if ( win32.cpuid & CPUID_AMD ) { + if( win32.cpuid & CPUID_AMD ) + { string += "AMD CPU"; - } else if ( win32.cpuid & CPUID_INTEL ) { + } + else if( win32.cpuid & CPUID_INTEL ) + { string += "Intel CPU"; - } else if ( win32.cpuid & CPUID_UNSUPPORTED ) { + } + else if( win32.cpuid & CPUID_UNSUPPORTED ) + { string += "unsupported CPU"; - } else { + } + else + { string += "generic CPU"; } string += " with "; - if ( win32.cpuid & CPUID_MMX ) { + if( win32.cpuid & CPUID_MMX ) + { string += "MMX & "; } - if ( win32.cpuid & CPUID_3DNOW ) { + if( win32.cpuid & CPUID_3DNOW ) + { string += "3DNow! & "; } - if ( win32.cpuid & CPUID_SSE ) { + if( win32.cpuid & CPUID_SSE ) + { string += "SSE & "; } - if ( win32.cpuid & CPUID_SSE2 ) { - string += "SSE2 & "; + if( win32.cpuid & CPUID_SSE2 ) + { + string += "SSE2 & "; } - if ( win32.cpuid & CPUID_SSE3 ) { + if( win32.cpuid & CPUID_SSE3 ) + { string += "SSE3 & "; } - if ( win32.cpuid & CPUID_HTT ) { + if( win32.cpuid & CPUID_HTT ) + { string += "HTT & "; } string.StripTrailing( " & " ); string.StripTrailing( " with " ); win32.sys_cpustring.SetString( string ); - } else { + } + else + { common->Printf( "forcing CPU type to " ); idLexer src( win32.sys_cpustring.GetString(), idStr::Length( win32.sys_cpustring.GetString() ), "sys_cpustring" ); idToken token; int id = CPUID_NONE; - while( src.ReadToken( &token ) ) { - if ( token.Icmp( "generic" ) == 0 ) { + while( src.ReadToken( &token ) ) + { + if( token.Icmp( "generic" ) == 0 ) + { id |= CPUID_GENERIC; - } else if ( token.Icmp( "intel" ) == 0 ) { + } + else if( token.Icmp( "intel" ) == 0 ) + { id |= CPUID_INTEL; - } else if ( token.Icmp( "amd" ) == 0 ) { + } + else if( token.Icmp( "amd" ) == 0 ) + { id |= CPUID_AMD; - } else if ( token.Icmp( "mmx" ) == 0 ) { + } + else if( token.Icmp( "mmx" ) == 0 ) + { id |= CPUID_MMX; - } else if ( token.Icmp( "3dnow" ) == 0 ) { + } + else if( token.Icmp( "3dnow" ) == 0 ) + { id |= CPUID_3DNOW; - } else if ( token.Icmp( "sse" ) == 0 ) { + } + else if( token.Icmp( "sse" ) == 0 ) + { id |= CPUID_SSE; - } else if ( token.Icmp( "sse2" ) == 0 ) { + } + else if( token.Icmp( "sse2" ) == 0 ) + { id |= CPUID_SSE2; - } else if ( token.Icmp( "sse3" ) == 0 ) { + } + else if( token.Icmp( "sse3" ) == 0 ) + { id |= CPUID_SSE3; - } else if ( token.Icmp( "htt" ) == 0 ) { + } + else if( token.Icmp( "htt" ) == 0 ) + { id |= CPUID_HTT; } } - if ( id == CPUID_NONE ) { + if( id == CPUID_NONE ) + { common->Printf( "WARNING: unknown sys_cpustring '%s'\n", win32.sys_cpustring.GetString() ); id = CPUID_GENERIC; } - win32.cpuid = (cpuid_t) id; + win32.cpuid = ( cpuid_t ) id; } common->Printf( "%s\n", win32.sys_cpustring.GetString() ); - if ( ( win32.cpuid & CPUID_SSE2 ) == 0 ) { + if( ( win32.cpuid & CPUID_SSE2 ) == 0 ) + { common->Error( "SSE2 not supported!" ); } @@ -1267,7 +1440,8 @@ void Sys_Init() { Sys_Shutdown ================ */ -void Sys_Shutdown() { +void Sys_Shutdown() +{ CoUninitialize(); } @@ -1276,8 +1450,9 @@ void Sys_Shutdown() { Sys_GetProcessorId ================ */ -cpuid_t Sys_GetProcessorId() { - return win32.cpuid; +cpuid_t Sys_GetProcessorId() +{ + return win32.cpuid; } /* @@ -1285,7 +1460,8 @@ cpuid_t Sys_GetProcessorId() { Sys_GetProcessorString ================ */ -const char *Sys_GetProcessorString() { +const char* Sys_GetProcessorString() +{ return win32.sys_cpustring.GetString(); } @@ -1299,9 +1475,11 @@ const char *Sys_GetProcessorString() { Win_Frame ==================== */ -void Win_Frame() { +void Win_Frame() +{ // if "viewlog" has been modified, show or hide the log console - if ( win32.win_viewlog.IsModified() ) { + if( win32.win_viewlog.IsModified() ) + { win32.win_viewlog.ClearModified(); } } @@ -1311,29 +1489,52 @@ void Win_Frame() { GetExceptionCodeInfo ==================== */ -const char *GetExceptionCodeInfo( UINT code ) { - switch( code ) { - case EXCEPTION_ACCESS_VIOLATION: return "The thread tried to read from or write to a virtual address for which it does not have the appropriate access."; - case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: return "The thread tried to access an array element that is out of bounds and the underlying hardware supports bounds checking."; - case EXCEPTION_BREAKPOINT: return "A breakpoint was encountered."; - case EXCEPTION_DATATYPE_MISALIGNMENT: return "The thread tried to read or write data that is misaligned on hardware that does not provide alignment. For example, 16-bit values must be aligned on 2-byte boundaries; 32-bit values on 4-byte boundaries, and so on."; - case EXCEPTION_FLT_DENORMAL_OPERAND: return "One of the operands in a floating-point operation is denormal. A denormal value is one that is too small to represent as a standard floating-point value."; - case EXCEPTION_FLT_DIVIDE_BY_ZERO: return "The thread tried to divide a floating-point value by a floating-point divisor of zero."; - case EXCEPTION_FLT_INEXACT_RESULT: return "The result of a floating-point operation cannot be represented exactly as a decimal fraction."; - case EXCEPTION_FLT_INVALID_OPERATION: return "This exception represents any floating-point exception not included in this list."; - case EXCEPTION_FLT_OVERFLOW: return "The exponent of a floating-point operation is greater than the magnitude allowed by the corresponding type."; - case EXCEPTION_FLT_STACK_CHECK: return "The stack overflowed or underflowed as the result of a floating-point operation."; - case EXCEPTION_FLT_UNDERFLOW: return "The exponent of a floating-point operation is less than the magnitude allowed by the corresponding type."; - case EXCEPTION_ILLEGAL_INSTRUCTION: return "The thread tried to execute an invalid instruction."; - case EXCEPTION_IN_PAGE_ERROR: return "The thread tried to access a page that was not present, and the system was unable to load the page. For example, this exception might occur if a network connection is lost while running a program over the network."; - case EXCEPTION_INT_DIVIDE_BY_ZERO: return "The thread tried to divide an integer value by an integer divisor of zero."; - case EXCEPTION_INT_OVERFLOW: return "The result of an integer operation caused a carry out of the most significant bit of the result."; - case EXCEPTION_INVALID_DISPOSITION: return "An exception handler returned an invalid disposition to the exception dispatcher. Programmers using a high-level language such as C should never encounter this exception."; - case EXCEPTION_NONCONTINUABLE_EXCEPTION: return "The thread tried to continue execution after a noncontinuable exception occurred."; - case EXCEPTION_PRIV_INSTRUCTION: return "The thread tried to execute an instruction whose operation is not allowed in the current machine mode."; - case EXCEPTION_SINGLE_STEP: return "A trace trap or other single-instruction mechanism signaled that one instruction has been executed."; - case EXCEPTION_STACK_OVERFLOW: return "The thread used up its stack."; - default: return "Unknown exception"; +const char* GetExceptionCodeInfo( UINT code ) +{ + switch( code ) + { + case EXCEPTION_ACCESS_VIOLATION: + return "The thread tried to read from or write to a virtual address for which it does not have the appropriate access."; + case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: + return "The thread tried to access an array element that is out of bounds and the underlying hardware supports bounds checking."; + case EXCEPTION_BREAKPOINT: + return "A breakpoint was encountered."; + case EXCEPTION_DATATYPE_MISALIGNMENT: + return "The thread tried to read or write data that is misaligned on hardware that does not provide alignment. For example, 16-bit values must be aligned on 2-byte boundaries; 32-bit values on 4-byte boundaries, and so on."; + case EXCEPTION_FLT_DENORMAL_OPERAND: + return "One of the operands in a floating-point operation is denormal. A denormal value is one that is too small to represent as a standard floating-point value."; + case EXCEPTION_FLT_DIVIDE_BY_ZERO: + return "The thread tried to divide a floating-point value by a floating-point divisor of zero."; + case EXCEPTION_FLT_INEXACT_RESULT: + return "The result of a floating-point operation cannot be represented exactly as a decimal fraction."; + case EXCEPTION_FLT_INVALID_OPERATION: + return "This exception represents any floating-point exception not included in this list."; + case EXCEPTION_FLT_OVERFLOW: + return "The exponent of a floating-point operation is greater than the magnitude allowed by the corresponding type."; + case EXCEPTION_FLT_STACK_CHECK: + return "The stack overflowed or underflowed as the result of a floating-point operation."; + case EXCEPTION_FLT_UNDERFLOW: + return "The exponent of a floating-point operation is less than the magnitude allowed by the corresponding type."; + case EXCEPTION_ILLEGAL_INSTRUCTION: + return "The thread tried to execute an invalid instruction."; + case EXCEPTION_IN_PAGE_ERROR: + return "The thread tried to access a page that was not present, and the system was unable to load the page. For example, this exception might occur if a network connection is lost while running a program over the network."; + case EXCEPTION_INT_DIVIDE_BY_ZERO: + return "The thread tried to divide an integer value by an integer divisor of zero."; + case EXCEPTION_INT_OVERFLOW: + return "The result of an integer operation caused a carry out of the most significant bit of the result."; + case EXCEPTION_INVALID_DISPOSITION: + return "An exception handler returned an invalid disposition to the exception dispatcher. Programmers using a high-level language such as C should never encounter this exception."; + case EXCEPTION_NONCONTINUABLE_EXCEPTION: + return "The thread tried to continue execution after a noncontinuable exception occurred."; + case EXCEPTION_PRIV_INSTRUCTION: + return "The thread tried to execute an instruction whose operation is not allowed in the current machine mode."; + case EXCEPTION_SINGLE_STEP: + return "A trace trap or other single-instruction mechanism signaled that one instruction has been executed."; + case EXCEPTION_STACK_OVERFLOW: + return "The thread used up its stack."; + default: + return "Unknown exception"; } } @@ -1344,27 +1545,31 @@ EmailCrashReport emailer originally from Raven/Quake 4 ==================== */ -void EmailCrashReport( LPSTR messageText ) { +void EmailCrashReport( LPSTR messageText ) +{ static int lastEmailTime = 0; - if ( Sys_Milliseconds() < lastEmailTime + 10000 ) { + if( Sys_Milliseconds() < lastEmailTime + 10000 ) + { return; } lastEmailTime = Sys_Milliseconds(); - HINSTANCE mapi = LoadLibrary( "MAPI32.DLL" ); - if( mapi ) { + HINSTANCE mapi = LoadLibrary( "MAPI32.DLL" ); + if( mapi ) + { LPMAPISENDMAIL MAPISendMail = ( LPMAPISENDMAIL )GetProcAddress( mapi, "MAPISendMail" ); - if( MAPISendMail ) { + if( MAPISendMail ) + { MapiRecipDesc toProgrammers = { 0, // ulReserved - MAPI_TO, // ulRecipClass - "DOOM 3 Crash", // lpszName - "SMTP:programmers@idsoftware.com", // lpszAddress - 0, // ulEIDSize - 0 // lpEntry + MAPI_TO, // ulRecipClass + "DOOM 3 Crash", // lpszName + "SMTP:programmers@idsoftware.com", // lpszAddress + 0, // ulEIDSize + 0 // lpEntry }; MapiMessage message = {}; @@ -1379,86 +1584,87 @@ void EmailCrashReport( LPSTR messageText ) { &message, // lpMapiMessage lpMessage MAPI_DIALOG, // FLAGS flFlags 0 // ULONG ulReserved - ); + ); } FreeLibrary( mapi ); } } // RB: disabled unused FPU exception debugging -#if !defined(__MINGW32__) && !defined(_WIN64) +#if 0 //!defined(__MINGW32__) && !defined(_WIN64) -int Sys_FPU_PrintStateFlags( char *ptr, int ctrl, int stat, int tags, int inof, int inse, int opof, int opse ); +int Sys_FPU_PrintStateFlags( char* ptr, int ctrl, int stat, int tags, int inof, int inse, int opof, int opse ); /* ==================== _except_handler ==================== */ -EXCEPTION_DISPOSITION __cdecl _except_handler( struct _EXCEPTION_RECORD *ExceptionRecord, void * EstablisherFrame, - struct _CONTEXT *ContextRecord, void * DispatcherContext ) { +EXCEPTION_DISPOSITION __cdecl _except_handler( struct _EXCEPTION_RECORD* ExceptionRecord, void* EstablisherFrame, + struct _CONTEXT* ContextRecord, void* DispatcherContext ) +{ static char msg[ 8192 ]; char FPUFlags[2048]; Sys_FPU_PrintStateFlags( FPUFlags, ContextRecord->FloatSave.ControlWord, - ContextRecord->FloatSave.StatusWord, - ContextRecord->FloatSave.TagWord, - ContextRecord->FloatSave.ErrorOffset, - ContextRecord->FloatSave.ErrorSelector, - ContextRecord->FloatSave.DataOffset, - ContextRecord->FloatSave.DataSelector ); + ContextRecord->FloatSave.StatusWord, + ContextRecord->FloatSave.TagWord, + ContextRecord->FloatSave.ErrorOffset, + ContextRecord->FloatSave.ErrorSelector, + ContextRecord->FloatSave.DataOffset, + ContextRecord->FloatSave.DataSelector ); - sprintf( msg, - "Please describe what you were doing when DOOM 3 crashed!\n" - "If this text did not pop into your email client please copy and email it to programmers@idsoftware.com\n" - "\n" - "-= FATAL EXCEPTION =-\n" - "\n" - "%s\n" - "\n" - "0x%x at address 0x%08p\n" - "\n" - "%s\n" - "\n" - "EAX = 0x%08x EBX = 0x%08x\n" - "ECX = 0x%08x EDX = 0x%08x\n" - "ESI = 0x%08x EDI = 0x%08x\n" - "EIP = 0x%08x ESP = 0x%08x\n" - "EBP = 0x%08x EFL = 0x%08x\n" - "\n" - "CS = 0x%04x\n" - "SS = 0x%04x\n" - "DS = 0x%04x\n" - "ES = 0x%04x\n" - "FS = 0x%04x\n" - "GS = 0x%04x\n" - "\n" - "%s\n", - com_version.GetString(), - ExceptionRecord->ExceptionCode, - ExceptionRecord->ExceptionAddress, - GetExceptionCodeInfo( ExceptionRecord->ExceptionCode ), - ContextRecord->Eax, ContextRecord->Ebx, - ContextRecord->Ecx, ContextRecord->Edx, - ContextRecord->Esi, ContextRecord->Edi, - ContextRecord->Eip, ContextRecord->Esp, - ContextRecord->Ebp, ContextRecord->EFlags, - ContextRecord->SegCs, - ContextRecord->SegSs, - ContextRecord->SegDs, - ContextRecord->SegEs, - ContextRecord->SegFs, - ContextRecord->SegGs, - FPUFlags - ); + sprintf( msg, + "Please describe what you were doing when DOOM 3 crashed!\n" + "If this text did not pop into your email client please copy and email it to programmers@idsoftware.com\n" + "\n" + "-= FATAL EXCEPTION =-\n" + "\n" + "%s\n" + "\n" + "0x%x at address 0x%08p\n" + "\n" + "%s\n" + "\n" + "EAX = 0x%08x EBX = 0x%08x\n" + "ECX = 0x%08x EDX = 0x%08x\n" + "ESI = 0x%08x EDI = 0x%08x\n" + "EIP = 0x%08x ESP = 0x%08x\n" + "EBP = 0x%08x EFL = 0x%08x\n" + "\n" + "CS = 0x%04x\n" + "SS = 0x%04x\n" + "DS = 0x%04x\n" + "ES = 0x%04x\n" + "FS = 0x%04x\n" + "GS = 0x%04x\n" + "\n" + "%s\n", + com_version.GetString(), + ExceptionRecord->ExceptionCode, + ExceptionRecord->ExceptionAddress, + GetExceptionCodeInfo( ExceptionRecord->ExceptionCode ), + ContextRecord->Eax, ContextRecord->Ebx, + ContextRecord->Ecx, ContextRecord->Edx, + ContextRecord->Esi, ContextRecord->Edi, + ContextRecord->Eip, ContextRecord->Esp, + ContextRecord->Ebp, ContextRecord->EFlags, + ContextRecord->SegCs, + ContextRecord->SegSs, + ContextRecord->SegDs, + ContextRecord->SegEs, + ContextRecord->SegFs, + ContextRecord->SegGs, + FPUFlags + ); EmailCrashReport( msg ); common->FatalError( msg ); - // Tell the OS to restart the faulting instruction - return ExceptionContinueExecution; + // Tell the OS to restart the faulting instruction + return ExceptionContinueExecution; } #endif // RB end @@ -1476,7 +1682,8 @@ EXCEPTION_DISPOSITION __cdecl _except_handler( struct _EXCEPTION_RECORD *Excepti WinMain ================== */ -int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { +int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) +{ const HCURSOR hcurSave = ::SetCursor( LoadCursor( 0, IDC_WAIT ) ); @@ -1485,13 +1692,14 @@ int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin Sys_GetCurrentMemoryStatus( exeLaunchMemoryStats ); #if 0 - DWORD handler = (DWORD)_except_handler; - __asm - { // Build EXCEPTION_REGISTRATION record: - push handler // Address of handler function - push FS:[0] // Address of previous handler - mov FS:[0],ESP // Install new EXECEPTION_REGISTRATION - } + DWORD handler = ( DWORD )_except_handler; + __asm + { + // Build EXCEPTION_REGISTRATION record: + push handler // Address of handler function + push FS:[0] // Address of previous handler + mov FS:[0], ESP // Install new EXECEPTION_REGISTRATION + } #endif win32.hInstance = hInstance; @@ -1503,7 +1711,8 @@ int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin // no abort/retry/fail errors SetErrorMode( SEM_FAILCRITICALERRORS ); - for ( int i = 0; i < MAX_CRITICAL_SECTIONS; i++ ) { + for( int i = 0; i < MAX_CRITICAL_SECTIONS; i++ ) + { InitializeCriticalSection( &win32.criticalSections[i] ); } @@ -1528,18 +1737,22 @@ int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin common->Printf( Sys_FPU_GetState() ); #endif - if ( win32.win_notaskkeys.GetInteger() ) { + if( win32.win_notaskkeys.GetInteger() ) + { DisableTaskKeys( TRUE, FALSE, /*( win32.win_notaskkeys.GetInteger() == 2 )*/ FALSE ); } // hide or show the early console as necessary - if ( win32.win_viewlog.GetInteger() ) { + if( win32.win_viewlog.GetInteger() ) + { Sys_ShowConsole( 1, true ); - } else { + } + else + { Sys_ShowConsole( 0, false ); } -#ifdef SET_THREAD_AFFINITY +#ifdef SET_THREAD_AFFINITY // give the main thread an affinity for the first cpu SetThreadAffinityMask( GetCurrentThread(), 1 ); #endif @@ -1548,8 +1761,9 @@ int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin ::SetFocus( win32.hWnd ); - // main game loop - while( 1 ) { + // main game loop + while( 1 ) + { Win_Frame(); @@ -1573,28 +1787,33 @@ int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin idSysLocal::OpenURL ================== */ -void idSysLocal::OpenURL( const char *url, bool doexit ) { +void idSysLocal::OpenURL( const char* url, bool doexit ) +{ static bool doexit_spamguard = false; HWND wnd; - if (doexit_spamguard) { + if( doexit_spamguard ) + { common->DPrintf( "OpenURL: already in an exit sequence, ignoring %s\n", url ); return; } - common->Printf("Open URL: %s\n", url); + common->Printf( "Open URL: %s\n", url ); - if ( !ShellExecute( NULL, "open", url, NULL, NULL, SW_RESTORE ) ) { + if( !ShellExecute( NULL, "open", url, NULL, NULL, SW_RESTORE ) ) + { common->Error( "Could not open url: '%s' ", url ); return; } wnd = GetForegroundWindow(); - if ( wnd ) { + if( wnd ) + { ShowWindow( wnd, SW_MAXIMIZE ); } - if ( doexit ) { + if( doexit ) + { doexit_spamguard = true; cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "quit\n" ); } @@ -1605,22 +1824,25 @@ void idSysLocal::OpenURL( const char *url, bool doexit ) { idSysLocal::StartProcess ================== */ -void idSysLocal::StartProcess( const char *exePath, bool doexit ) { +void idSysLocal::StartProcess( const char* exePath, bool doexit ) +{ TCHAR szPathOrig[_MAX_PATH]; STARTUPINFO si; PROCESS_INFORMATION pi; - ZeroMemory( &si, sizeof(si) ); - si.cb = sizeof(si); + ZeroMemory( &si, sizeof( si ) ); + si.cb = sizeof( si ); strncpy( szPathOrig, exePath, _MAX_PATH ); - if( !CreateProcess( NULL, szPathOrig, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi ) ) { - common->Error( "Could not start process: '%s' ", szPathOrig ); - return; + if( !CreateProcess( NULL, szPathOrig, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi ) ) + { + common->Error( "Could not start process: '%s' ", szPathOrig ); + return; } - if ( doexit ) { + if( doexit ) + { cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "quit\n" ); } } @@ -1630,7 +1852,8 @@ void idSysLocal::StartProcess( const char *exePath, bool doexit ) { Sys_SetFatalError ================== */ -void Sys_SetFatalError( const char *error ) { +void Sys_SetFatalError( const char* error ) +{ } /* @@ -1639,6 +1862,7 @@ Sys_SetLanguageFromSystem ================ */ extern idCVar sys_lang; -void Sys_SetLanguageFromSystem() { +void Sys_SetLanguageFromSystem() +{ sys_lang.SetString( Sys_DefaultLanguage() ); }