2012-11-26 18:58:24 +00:00
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
Doom 3 BFG Edition GPL Source Code
2012-11-28 15:47:07 +00:00
Copyright ( C ) 1993 - 2012 id Software LLC , a ZeniMax Media company .
2012-11-26 18:58:24 +00:00
2012-11-28 15:47:07 +00:00
This file is part of the Doom 3 BFG Edition GPL Source Code ( " Doom 3 BFG Edition Source Code " ) .
2012-11-26 18:58:24 +00:00
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
the Free Software Foundation , either version 3 of the License , or
( at your option ) any later version .
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with Doom 3 BFG Edition Source Code . If not , see < http : //www.gnu.org/licenses/>.
In addition , the Doom 3 BFG Edition 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 BFG Edition Source Code . If not , please request a copy in writing from id Software at the address below .
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 .
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-12-22 15:18:19 +00:00
# include "precompiled.h"
2012-11-26 18:58:24 +00:00
# pragma hdrstop
# include "Common_local.h"
2012-11-28 15:47:07 +00:00
idCVar com_logFile ( " logFile " , " 0 " , CVAR_SYSTEM | CVAR_NOCHEAT , " 1 = buffer log, 2 = flush after each print " , 0 , 2 , idCmdSystem : : ArgCompletion_Integer < 0 , 2 > ) ;
2012-11-26 18:58:24 +00:00
idCVar com_logFileName ( " logFileName " , " qconsole.log " , CVAR_SYSTEM | CVAR_NOCHEAT , " name of log file, if empty, qconsole.log will be used " ) ;
2012-11-28 15:47:07 +00:00
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 > ) ;
2012-11-26 18:58:24 +00:00
# ifndef ID_RETAIL
2012-11-28 15:47:07 +00:00
idCVar com_printFilter ( " com_printFilter " , " " , CVAR_SYSTEM , " only print lines that contain this, add multiple filters with a ; delimeter " ) ;
2012-11-26 18:58:24 +00:00
# endif
/*
= = = = = = = = = = = = = = = = = =
idCommonLocal : : BeginRedirect
= = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idCommonLocal : : BeginRedirect ( char * buffer , int buffersize , void ( * flush ) ( const char * ) )
{
if ( ! buffer | | ! buffersize | | ! flush )
{
2012-11-26 18:58:24 +00:00
return ;
}
rd_buffer = buffer ;
rd_buffersize = buffersize ;
rd_flush = flush ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
* rd_buffer = 0 ;
}
/*
= = = = = = = = = = = = = = = = = =
idCommonLocal : : EndRedirect
= = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idCommonLocal : : EndRedirect ( )
{
if ( rd_flush & & rd_buffer [ 0 ] )
{
2012-11-26 18:58:24 +00:00
rd_flush ( rd_buffer ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
rd_buffer = NULL ;
rd_buffersize = 0 ;
rd_flush = NULL ;
}
/*
= = = = = = = = = = = = = = = = = =
idCommonLocal : : CloseLogFile
= = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idCommonLocal : : CloseLogFile ( )
{
if ( logFile )
{
2012-11-26 18:58:24 +00:00
com_logFile . SetBool ( false ) ; // make sure no further VPrintf attempts to open the log file again
fileSystem - > CloseFile ( logFile ) ;
logFile = NULL ;
}
}
/*
= = = = = = = = = = = = = = = = = =
idCommonLocal : : SetRefreshOnPrint
= = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idCommonLocal : : SetRefreshOnPrint ( bool set )
{
2012-11-26 18:58:24 +00:00
com_refreshOnPrint = set ;
}
/*
= = = = = = = = = = = = = = = = = =
idCommonLocal : : VPrintf
A raw string should NEVER be passed as fmt , because of " %f " type crashes .
= = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idCommonLocal : : VPrintf ( const char * fmt , va_list args )
{
2012-11-26 18:58:24 +00:00
static bool logFileFailed = false ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// if the cvar system is not initialized
2012-11-28 15:47:07 +00:00
if ( ! cvarSystem - > IsInitialized ( ) )
{
2012-11-26 18:58:24 +00:00
return ;
}
// optionally put a timestamp at the beginning of each print,
// so we can see how long different init sections are taking
int timeLength = 0 ;
char msg [ MAX_PRINT_MSG_SIZE ] ;
msg [ 0 ] = ' \0 ' ;
2012-11-28 15:47:07 +00:00
if ( com_timestampPrints . GetInteger ( ) )
{
2012-11-26 18:58:24 +00:00
int t = Sys_Milliseconds ( ) ;
2012-11-28 15:47:07 +00:00
if ( com_timestampPrints . GetInteger ( ) = = 1 )
{
2012-11-26 18:58:24 +00:00
sprintf ( msg , " [%5.2f] " , t * 0.001f ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
sprintf ( msg , " [%i] " , t ) ;
}
2012-11-28 15:47:07 +00:00
}
2012-11-26 18:58:24 +00:00
timeLength = strlen ( msg ) ;
// don't overflow
2012-11-28 15:47:07 +00:00
if ( idStr : : vsnPrintf ( msg + timeLength , MAX_PRINT_MSG_SIZE - timeLength - 1 , fmt , args ) < 0 )
{
msg [ sizeof ( msg ) - 2 ] = ' \n ' ;
msg [ sizeof ( msg ) - 1 ] = ' \0 ' ; // avoid output garbling
Sys_Printf ( " idCommon::VPrintf: truncated to %d characters \n " , strlen ( msg ) - 1 ) ;
2012-11-26 18:58:24 +00:00
}
2012-11-28 15:47:07 +00:00
if ( rd_buffer )
{
if ( ( int ) ( strlen ( msg ) + strlen ( rd_buffer ) ) > ( rd_buffersize - 1 ) )
{
2012-11-26 18:58:24 +00:00
rd_flush ( rd_buffer ) ;
* rd_buffer = 0 ;
}
strcat ( rd_buffer , msg ) ;
return ;
}
# ifndef ID_RETAIL
2012-11-28 15:47:07 +00:00
if ( com_printFilter . GetString ( ) ! = NULL & & com_printFilter . GetString ( ) [ 0 ] ! = ' \0 ' )
{
2012-11-26 18:58:24 +00:00
idStrStatic < 4096 > filterBuf = com_printFilter . GetString ( ) ;
idStrStatic < 4096 > msgBuf = msg ;
filterBuf . ToLower ( ) ;
msgBuf . ToLower ( ) ;
2012-11-28 15:47:07 +00:00
char * sp = strtok ( & filterBuf [ 0 ] , " ; " ) ;
2012-11-26 18:58:24 +00:00
bool p = false ;
2012-11-28 15:47:07 +00:00
for ( ; sp ! = NULL ; )
{
if ( strstr ( msgBuf , sp ) ! = NULL )
{
2012-11-26 18:58:24 +00:00
p = true ;
break ;
}
sp = strtok ( NULL , " ; " ) ;
}
2012-11-28 15:47:07 +00:00
if ( ! p )
{
2012-11-26 18:58:24 +00:00
return ;
}
}
# endif
2012-12-08 17:20:13 +00:00
2012-11-28 15:47:07 +00:00
if ( ! idLib : : IsMainThread ( ) )
{
2012-12-07 16:06:44 +00:00
// RB: printf should be thread-safe on Linux
# if defined(_WIN32)
2012-11-26 18:58:24 +00:00
OutputDebugString ( msg ) ;
2012-12-07 16:06:44 +00:00
# else
2013-03-16 01:29:22 +00:00
printf ( " %s " , msg ) ;
2012-12-07 16:06:44 +00:00
# endif
// RB end
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// echo to console buffer
console - > Print ( msg ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// remove any color codes
idStr : : RemoveColors ( msg ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// echo to dedicated console and early console
Sys_Printf ( " %s " , msg ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// print to script debugger server
// DebuggerServerPrint( msg );
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
#if 0 // !@#
# if defined(_DEBUG) && defined(WIN32)
2012-11-28 15:47:07 +00:00
if ( strlen ( msg ) < 512 )
{
2012-11-26 18:58:24 +00:00
TRACE ( msg ) ;
}
# endif
# endif
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// logFile
2012-11-28 15:47:07 +00:00
if ( com_logFile . GetInteger ( ) & & ! logFileFailed & & fileSystem - > IsInitialized ( ) )
{
2012-11-26 18:58:24 +00:00
static bool recursing ;
2012-11-28 15:47:07 +00:00
if ( ! logFile & & ! recursing )
{
const char * fileName = com_logFileName . GetString ( ) [ 0 ] ? com_logFileName . GetString ( ) : " qconsole.log " ;
2012-11-26 18:58:24 +00:00
// fileSystem->OpenFileWrite can cause recursive prints into here
recursing = true ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
logFile = fileSystem - > OpenFileWrite ( fileName ) ;
2012-11-28 15:47:07 +00:00
if ( ! logFile )
{
2012-11-26 18:58:24 +00:00
logFileFailed = true ;
FatalError ( " failed to open log file '%s' \n " , fileName ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
recursing = false ;
2012-11-28 15:47:07 +00:00
if ( com_logFile . GetInteger ( ) > 1 )
{
2012-11-26 18:58:24 +00:00
// force it to not buffer so we get valid
// data even if we are crashing
logFile - > ForceFlush ( ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
time_t aclock ;
time ( & aclock ) ;
2012-11-28 15:47:07 +00:00
struct tm * newtime = localtime ( & aclock ) ;
2012-11-26 18:58:24 +00:00
Printf ( " log file '%s' opened on %s \n " , fileName , asctime ( newtime ) ) ;
}
2012-11-28 15:47:07 +00:00
if ( logFile )
{
2012-11-26 18:58:24 +00:00
logFile - > Write ( msg , strlen ( msg ) ) ;
logFile - > Flush ( ) ; // ForceFlush doesn't help a whole lot
}
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// don't trigger any updates if we are in the process of doing a fatal error
2012-11-28 15:47:07 +00:00
if ( com_errorEntered ! = ERP_FATAL )
{
2012-11-26 18:58:24 +00:00
// update the console if we are in a long-running command, like dmap
2012-11-28 15:47:07 +00:00
if ( com_refreshOnPrint )
{
2012-11-26 18:58:24 +00:00
const bool captureToImage = false ;
UpdateScreen ( captureToImage ) ;
}
}
}
/*
= = = = = = = = = = = = = = = = = =
idCommonLocal : : Printf
Both client and server can use this , and it will output to the appropriate place .
A raw string should NEVER be passed as fmt , because of " %f " type crashers .
= = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idCommonLocal : : Printf ( const char * fmt , . . . )
{
2012-11-26 18:58:24 +00:00
va_list argptr ;
va_start ( argptr , fmt ) ;
VPrintf ( fmt , argptr ) ;
va_end ( argptr ) ;
}
/*
= = = = = = = = = = = = = = = = = =
idCommonLocal : : DPrintf
prints message that only shows up if the " developer " cvar is set
= = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idCommonLocal : : DPrintf ( const char * fmt , . . . )
{
2012-11-26 18:58:24 +00:00
va_list argptr ;
char msg [ MAX_PRINT_MSG_SIZE ] ;
2012-11-28 15:47:07 +00:00
if ( ! cvarSystem - > IsInitialized ( ) | | ! com_developer . GetBool ( ) )
{
2012-11-26 18:58:24 +00:00
return ; // don't confuse non-developers with techie stuff...
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
va_start ( argptr , fmt ) ;
2012-11-28 15:47:07 +00:00
idStr : : vsnPrintf ( msg , sizeof ( msg ) , fmt , argptr ) ;
2012-11-26 18:58:24 +00:00
va_end ( argptr ) ;
2012-11-28 15:47:07 +00:00
msg [ sizeof ( msg ) - 1 ] = ' \0 ' ;
2012-11-26 18:58:24 +00:00
// never refresh the screen, which could cause reentrency problems
bool temp = com_refreshOnPrint ;
com_refreshOnPrint = false ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
Printf ( S_COLOR_RED " %s " , msg ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
com_refreshOnPrint = temp ;
}
/*
= = = = = = = = = = = = = = = = = =
idCommonLocal : : DWarning
prints warning message in yellow that only shows up if the " developer " cvar is set
= = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idCommonLocal : : DWarning ( const char * fmt , . . . )
{
2012-11-26 18:58:24 +00:00
va_list argptr ;
char msg [ MAX_PRINT_MSG_SIZE ] ;
2012-11-28 15:47:07 +00:00
if ( ! com_developer . GetBool ( ) )
{
2012-11-26 18:58:24 +00:00
return ; // don't confuse non-developers with techie stuff...
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
va_start ( argptr , fmt ) ;
2012-11-28 15:47:07 +00:00
idStr : : vsnPrintf ( msg , sizeof ( msg ) , fmt , argptr ) ;
2012-11-26 18:58:24 +00:00
va_end ( argptr ) ;
2012-11-28 15:47:07 +00:00
msg [ sizeof ( msg ) - 1 ] = ' \0 ' ;
2012-11-26 18:58:24 +00:00
Printf ( S_COLOR_YELLOW " WARNING: %s \n " , msg ) ;
}
/*
= = = = = = = = = = = = = = = = = =
idCommonLocal : : Warning
prints WARNING % s and adds the warning message to a queue to be printed later on
= = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idCommonLocal : : Warning ( const char * fmt , . . . )
{
2012-11-26 18:58:24 +00:00
va_list argptr ;
char msg [ MAX_PRINT_MSG_SIZE ] ;
2012-11-28 15:47:07 +00:00
if ( ! idLib : : IsMainThread ( ) )
{
2012-11-26 18:58:24 +00:00
return ; // not thread safe!
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
va_start ( argptr , fmt ) ;
2012-11-28 15:47:07 +00:00
idStr : : vsnPrintf ( msg , sizeof ( msg ) , fmt , argptr ) ;
2012-11-26 18:58:24 +00:00
va_end ( argptr ) ;
2012-11-28 15:47:07 +00:00
msg [ sizeof ( msg ) - 1 ] = 0 ;
2012-11-26 18:58:24 +00:00
Printf ( S_COLOR_YELLOW " WARNING: " S_COLOR_RED " %s \n " , msg ) ;
2012-11-28 15:47:07 +00:00
if ( warningList . Num ( ) < MAX_WARNING_LIST )
{
2012-11-26 18:58:24 +00:00
warningList . AddUnique ( msg ) ;
}
}
/*
= = = = = = = = = = = = = = = = = =
idCommonLocal : : PrintWarnings
= = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idCommonLocal : : PrintWarnings ( )
{
2012-11-26 18:58:24 +00:00
int i ;
2012-11-28 15:47:07 +00:00
if ( ! warningList . Num ( ) )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
Printf ( " ------------- Warnings --------------- \n " ) ;
Printf ( " during %s... \n " , warningCaption . c_str ( ) ) ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < warningList . Num ( ) ; i + + )
{
2012-11-26 18:58:24 +00:00
Printf ( S_COLOR_YELLOW " WARNING: " S_COLOR_RED " %s \n " , warningList [ i ] . c_str ( ) ) ;
}
2012-11-28 15:47:07 +00:00
if ( warningList . Num ( ) )
{
if ( warningList . Num ( ) > = MAX_WARNING_LIST )
{
2012-11-26 18:58:24 +00:00
Printf ( " more than %d warnings \n " , MAX_WARNING_LIST ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
Printf ( " %d warnings \n " , warningList . Num ( ) ) ;
}
}
}
/*
= = = = = = = = = = = = = = = = = =
idCommonLocal : : ClearWarnings
= = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idCommonLocal : : ClearWarnings ( const char * reason )
{
2012-11-26 18:58:24 +00:00
warningCaption = reason ;
warningList . Clear ( ) ;
}
/*
= = = = = = = = = = = = = = = = = =
idCommonLocal : : DumpWarnings
= = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idCommonLocal : : DumpWarnings ( )
{
2012-11-26 18:58:24 +00:00
int i ;
2012-11-28 15:47:07 +00:00
idFile * warningFile ;
if ( ! warningList . Num ( ) )
{
2012-11-26 18:58:24 +00:00
return ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
warningFile = fileSystem - > OpenFileWrite ( " warnings.txt " , " fs_savepath " ) ;
2012-11-28 15:47:07 +00:00
if ( warningFile )
{
2012-11-26 18:58:24 +00:00
warningFile - > Printf ( " ------------- Warnings --------------- \n \n " ) ;
warningFile - > Printf ( " during %s... \n " , warningCaption . c_str ( ) ) ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < warningList . Num ( ) ; i + + )
{
2012-11-26 18:58:24 +00:00
warningList [ i ] . RemoveColors ( ) ;
warningFile - > Printf ( " WARNING: %s \n " , warningList [ i ] . c_str ( ) ) ;
}
2012-11-28 15:47:07 +00:00
if ( warningList . Num ( ) > = MAX_WARNING_LIST )
{
2012-11-26 18:58:24 +00:00
warningFile - > Printf ( " \n more than %d warnings! \n " , MAX_WARNING_LIST ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
warningFile - > Printf ( " \n %d warnings. \n " , warningList . Num ( ) ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
warningFile - > Printf ( " \n \n -------------- Errors --------------- \n \n " ) ;
2012-11-28 15:47:07 +00:00
for ( i = 0 ; i < errorList . Num ( ) ; i + + )
{
2012-11-26 18:58:24 +00:00
errorList [ i ] . RemoveColors ( ) ;
warningFile - > Printf ( " ERROR: %s " , errorList [ i ] . c_str ( ) ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
warningFile - > ForceFlush ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
fileSystem - > CloseFile ( warningFile ) ;
2012-11-28 15:47:07 +00:00
2012-12-08 17:20:13 +00:00
// RB begin
2012-12-07 16:06:44 +00:00
# if defined(_WIN32) && !defined(_DEBUG)
2012-12-08 17:20:13 +00:00
// RB end
2012-11-26 18:58:24 +00:00
idStr osPath ;
osPath = fileSystem - > RelativePathToOSPath ( " warnings.txt " , " fs_savepath " ) ;
WinExec ( va ( " Notepad.exe %s " , osPath . c_str ( ) ) , SW_SHOW ) ;
# endif
}
}
/*
= = = = = = = = = = = = = = = = = =
idCommonLocal : : Error
= = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idCommonLocal : : Error ( const char * fmt , . . . )
{
2012-11-26 18:58:24 +00:00
va_list argptr ;
static int lastErrorTime ;
static int errorCount ;
int currentTime ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
errorParm_t code = ERP_DROP ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// always turn this off after an error
com_refreshOnPrint = false ;
2012-11-28 15:47:07 +00:00
if ( com_productionMode . GetInteger ( ) = = 3 )
{
2012-11-26 18:58:24 +00:00
Sys_Quit ( ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// when we are running automated scripts, make sure we
// know if anything failed
2012-11-28 15:47:07 +00:00
if ( cvarSystem - > GetCVarInteger ( " fs_copyfiles " ) )
{
2012-11-26 18:58:24 +00:00
code = ERP_FATAL ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// if we don't have GL running, make it a fatal error
2012-11-28 15:47:07 +00:00
if ( ! renderSystem - > IsOpenGLRunning ( ) )
{
2012-11-26 18:58:24 +00:00
code = ERP_FATAL ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// if we got a recursive error, make it fatal
2012-11-28 15:47:07 +00:00
if ( com_errorEntered )
{
2012-11-26 18:58:24 +00:00
// if we are recursively erroring while exiting
// from a fatal error, just kill the entire
// process immediately, which will prevent a
// full screen rendering window covering the
// error dialog
2012-11-28 15:47:07 +00:00
if ( com_errorEntered = = ERP_FATAL )
{
2012-11-26 18:58:24 +00:00
Sys_Quit ( ) ;
}
code = ERP_FATAL ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// if we are getting a solid stream of ERP_DROP, do an ERP_FATAL
currentTime = Sys_Milliseconds ( ) ;
2012-11-28 15:47:07 +00:00
if ( currentTime - lastErrorTime < 100 )
{
if ( + + errorCount > 3 )
{
2012-11-26 18:58:24 +00:00
code = ERP_FATAL ;
}
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
errorCount = 0 ;
}
lastErrorTime = currentTime ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
com_errorEntered = code ;
2012-11-28 15:47:07 +00:00
va_start ( argptr , fmt ) ;
idStr : : vsnPrintf ( errorMessage , sizeof ( errorMessage ) , fmt , argptr ) ;
va_end ( argptr ) ;
errorMessage [ sizeof ( errorMessage ) - 1 ] = ' \0 ' ;
2012-11-26 18:58:24 +00:00
// copy the error message to the clip board
Sys_SetClipboardData ( errorMessage ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// add the message to the error list
errorList . AddUnique ( errorMessage ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
Stop ( ) ;
2012-11-28 15:47:07 +00:00
if ( code = = ERP_DISCONNECT )
{
2012-11-26 18:58:24 +00:00
com_errorEntered = ERP_NONE ;
throw idException ( errorMessage ) ;
2012-11-28 15:47:07 +00:00
}
else if ( code = = ERP_DROP )
{
2012-11-26 18:58:24 +00:00
Printf ( " ******************** \n ERROR: %s \n ******************** \n " , errorMessage ) ;
com_errorEntered = ERP_NONE ;
throw idException ( errorMessage ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
Printf ( " ******************** \n ERROR: %s \n ******************** \n " , errorMessage ) ;
}
2012-11-28 15:47:07 +00:00
if ( cvarSystem - > GetCVarBool ( " r_fullscreen " ) )
{
2012-11-26 18:58:24 +00:00
cmdSystem - > BufferCommandText ( CMD_EXEC_NOW , " vid_restart partial windowed \n " ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
Sys_Error ( " %s " , errorMessage ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
}
/*
= = = = = = = = = = = = = = = = = =
idCommonLocal : : FatalError
Dump out of the game to a system dialog
= = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idCommonLocal : : FatalError ( const char * fmt , . . . )
{
2012-11-26 18:58:24 +00:00
va_list argptr ;
2012-11-28 15:47:07 +00:00
if ( com_productionMode . GetInteger ( ) = = 3 )
{
2012-11-26 18:58:24 +00:00
Sys_Quit ( ) ;
}
// if we got a recursive error, make it fatal
2012-11-28 15:47:07 +00:00
if ( com_errorEntered )
{
2012-11-26 18:58:24 +00:00
// if we are recursively erroring while exiting
// from a fatal error, just kill the entire
// process immediately, which will prevent a
// full screen rendering window covering the
// error dialog
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
Sys_Printf ( " FATAL: recursed fatal error: \n %s \n " , errorMessage ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
va_start ( argptr , fmt ) ;
2012-11-28 15:47:07 +00:00
idStr : : vsnPrintf ( errorMessage , sizeof ( errorMessage ) , fmt , argptr ) ;
2012-11-26 18:58:24 +00:00
va_end ( argptr ) ;
2012-11-28 15:47:07 +00:00
errorMessage [ sizeof ( errorMessage ) - 1 ] = ' \0 ' ;
2012-11-26 18:58:24 +00:00
Sys_Printf ( " %s \n " , errorMessage ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// write the console to a log file?
Sys_Quit ( ) ;
}
com_errorEntered = ERP_FATAL ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
va_start ( argptr , fmt ) ;
2012-11-28 15:47:07 +00:00
idStr : : vsnPrintf ( errorMessage , sizeof ( errorMessage ) , fmt , argptr ) ;
2012-11-26 18:58:24 +00:00
va_end ( argptr ) ;
2012-11-28 15:47:07 +00:00
errorMessage [ sizeof ( errorMessage ) - 1 ] = ' \0 ' ;
if ( cvarSystem - > GetCVarBool ( " r_fullscreen " ) )
{
2012-11-26 18:58:24 +00:00
cmdSystem - > BufferCommandText ( CMD_EXEC_NOW , " vid_restart partial windowed \n " ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
Sys_SetFatalError ( errorMessage ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
Sys_Error ( " %s " , errorMessage ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
}