2018-04-14 04:08:28 +03:00
|
|
|
/*
|
|
|
|
sys_con.c - stdout and log
|
|
|
|
Copyright (C) 2007 Uncle Mike
|
|
|
|
|
|
|
|
This program 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.
|
|
|
|
|
|
|
|
This program 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.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "common.h"
|
2024-12-24 11:13:05 +03:00
|
|
|
#if XASH_ANDROID
|
2018-04-14 04:08:28 +03:00
|
|
|
#include <android/log.h>
|
|
|
|
#endif
|
2022-01-29 03:04:54 +03:00
|
|
|
#include <string.h>
|
|
|
|
#include <errno.h>
|
2023-01-14 00:35:30 -06:00
|
|
|
#if XASH_IRIX
|
|
|
|
#include <sys/time.h>
|
|
|
|
#endif
|
2024-12-24 11:26:27 +03:00
|
|
|
#include "xash3d_mathlib.h"
|
2018-04-14 04:08:28 +03:00
|
|
|
|
2022-06-14 04:23:09 +03:00
|
|
|
// do not waste precious CPU cycles on mobiles or low memory devices
|
|
|
|
#if !XASH_WIN32 && !XASH_MOBILE_PLATFORM && !XASH_LOW_MEMORY
|
2024-12-24 11:26:27 +03:00
|
|
|
#define XASH_COLORIZE_CONSOLE 1
|
2022-06-14 04:23:09 +03:00
|
|
|
#else
|
2024-12-24 11:26:27 +03:00
|
|
|
#define XASH_COLORIZE_CONSOLE 0
|
2018-04-14 04:08:28 +03:00
|
|
|
#endif
|
|
|
|
|
2025-02-14 00:19:46 +03:00
|
|
|
static struct logdata_s {
|
|
|
|
char title[64];
|
|
|
|
qboolean log_active;
|
|
|
|
qboolean log_time;
|
|
|
|
char log_path[MAX_SYSPATH];
|
|
|
|
FILE *logfile;
|
|
|
|
int logfileno;
|
|
|
|
} s_ld;
|
2018-04-14 04:08:28 +03:00
|
|
|
|
|
|
|
void Sys_DestroyConsole( void )
|
|
|
|
{
|
|
|
|
// last text message into console or log
|
2024-06-19 06:46:08 +03:00
|
|
|
Con_Reportf( "%s: Exiting!\n", __func__ );
|
2019-11-24 03:52:08 +03:00
|
|
|
#if XASH_WIN32
|
2018-04-14 04:08:28 +03:00
|
|
|
Wcon_DestroyConsole();
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
===============================================================================
|
|
|
|
|
|
|
|
SYSTEM LOG
|
|
|
|
|
|
|
|
===============================================================================
|
|
|
|
*/
|
2018-05-14 10:14:41 +03:00
|
|
|
int Sys_LogFileNo( void )
|
|
|
|
{
|
|
|
|
return s_ld.logfileno;
|
|
|
|
}
|
|
|
|
|
2022-02-22 06:08:32 +03:00
|
|
|
static void Sys_FlushStdout( void )
|
|
|
|
{
|
|
|
|
// never printing anything to stdout on mobiles
|
|
|
|
#if !XASH_MOBILE_PLATFORM
|
|
|
|
fflush( stdout );
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
static void Sys_FlushLogfile( void )
|
|
|
|
{
|
|
|
|
if( s_ld.logfile )
|
|
|
|
fflush( s_ld.logfile );
|
|
|
|
}
|
|
|
|
|
2018-04-14 04:08:28 +03:00
|
|
|
void Sys_InitLog( void )
|
|
|
|
{
|
2025-02-14 00:19:46 +03:00
|
|
|
const char *mode;
|
2018-04-14 04:08:28 +03:00
|
|
|
|
2025-02-06 20:03:07 +03:00
|
|
|
if( Sys_CheckParm( "-log" ))
|
2018-05-03 23:51:23 +07:00
|
|
|
{
|
2025-02-14 01:51:50 +03:00
|
|
|
if( !Sys_GetParmFromCmdLine( "-log", s_ld.log_path ) || !isalnum( s_ld.log_path[0] ))
|
2025-02-14 00:19:46 +03:00
|
|
|
Q_strncpy( s_ld.log_path, "engine.log", sizeof( s_ld.log_path ));
|
|
|
|
|
|
|
|
COM_DefaultExtension( s_ld.log_path, ".log", sizeof( s_ld.log_path ));
|
2018-05-03 23:51:23 +07:00
|
|
|
s_ld.log_active = true;
|
|
|
|
}
|
|
|
|
|
2025-02-14 00:19:46 +03:00
|
|
|
s_ld.log_time = Sys_CheckParm( "-logtime" );
|
|
|
|
|
2018-04-14 04:08:28 +03:00
|
|
|
if( host.change_game && host.type != HOST_DEDICATED )
|
|
|
|
mode = "a";
|
|
|
|
else mode = "w";
|
|
|
|
|
2024-03-19 20:41:46 +03:00
|
|
|
if( Host_IsDedicated( ))
|
2024-03-19 21:11:04 +03:00
|
|
|
Q_strncpy( s_ld.title, XASH_DEDICATED_SERVER_NAME " " XASH_VERSION, sizeof( s_ld.title ));
|
|
|
|
else Q_strncpy( s_ld.title, XASH_ENGINE_NAME " " XASH_VERSION, sizeof( s_ld.title ));
|
2024-03-16 21:07:52 +04:00
|
|
|
|
2018-04-14 04:08:28 +03:00
|
|
|
// create log if needed
|
|
|
|
if( s_ld.log_active )
|
|
|
|
{
|
|
|
|
s_ld.logfile = fopen( s_ld.log_path, mode );
|
2022-06-13 22:36:43 +03:00
|
|
|
|
|
|
|
if ( !s_ld.logfile )
|
2022-01-29 03:04:00 +03:00
|
|
|
{
|
2025-02-14 00:19:46 +03:00
|
|
|
Con_Reportf( S_ERROR "%s: can't create log file %s: %s\n", __func__, s_ld.log_path, strerror( errno ));
|
2022-06-13 22:36:43 +03:00
|
|
|
return;
|
2022-01-29 03:04:00 +03:00
|
|
|
}
|
2022-06-13 22:36:43 +03:00
|
|
|
|
|
|
|
s_ld.logfileno = fileno( s_ld.logfile );
|
|
|
|
|
2024-03-19 20:41:46 +03:00
|
|
|
// fit to 80 columns for easier read on standard terminal
|
|
|
|
fputs( "================================================================================\n", s_ld.logfile );
|
2025-01-13 19:20:53 +03:00
|
|
|
fprintf( s_ld.logfile, "%s (%i, %s, %s, %s-%s)\n", s_ld.title, Q_buildnum(), g_buildcommit, g_buildbranch, Q_buildos(), Q_buildarch());
|
2024-03-19 20:41:46 +03:00
|
|
|
fprintf( s_ld.logfile, "Game started at %s\n", Q_timestamp( TIME_FULL ));
|
|
|
|
fputs( "================================================================================\n", s_ld.logfile );
|
2024-03-16 21:24:52 +04:00
|
|
|
fflush( s_ld.logfile );
|
2018-04-14 04:08:28 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-01-09 08:04:18 +03:00
|
|
|
void Sys_CloseLog( const char *finalmsg )
|
2018-04-14 04:08:28 +03:00
|
|
|
{
|
2025-01-09 08:04:18 +03:00
|
|
|
Sys_FlushStdout(); // flush to stdout to ensure all data was written
|
|
|
|
|
|
|
|
if( !s_ld.logfile )
|
|
|
|
return;
|
2018-04-14 04:08:28 +03:00
|
|
|
|
|
|
|
// continue logged
|
2025-01-09 08:04:18 +03:00
|
|
|
if( !finalmsg )
|
2018-04-14 04:08:28 +03:00
|
|
|
{
|
2025-01-09 08:04:18 +03:00
|
|
|
switch( host.status )
|
|
|
|
{
|
|
|
|
case HOST_CRASHED:
|
|
|
|
finalmsg = "crashed";
|
|
|
|
break;
|
|
|
|
case HOST_ERR_FATAL:
|
|
|
|
finalmsg = "stopped with error";
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
finalmsg = "stopped";
|
|
|
|
break;
|
|
|
|
}
|
2018-04-14 04:08:28 +03:00
|
|
|
}
|
|
|
|
|
2025-01-09 08:04:18 +03:00
|
|
|
fputc( '\n', s_ld.logfile );
|
|
|
|
fputs( "================================================================================\n", s_ld.logfile );
|
2025-01-13 19:20:53 +03:00
|
|
|
fprintf( s_ld.logfile, "%s (%i, %s, %s, %s-%s)\n", s_ld.title, Q_buildnum(), g_buildcommit, g_buildbranch, Q_buildos(), Q_buildarch());
|
2025-01-09 08:04:18 +03:00
|
|
|
fprintf( s_ld.logfile, "Stopped with reason \"%s\" at %s\n", finalmsg, Q_timestamp( TIME_FULL ));
|
|
|
|
fputs( "================================================================================\n", s_ld.logfile );
|
|
|
|
fclose( s_ld.logfile );
|
|
|
|
s_ld.logfile = NULL;
|
2018-04-14 04:08:28 +03:00
|
|
|
}
|
|
|
|
|
2024-12-24 11:26:27 +03:00
|
|
|
#if XASH_COLORIZE_CONSOLE
|
|
|
|
static qboolean Sys_WriteEscapeSequenceForColorcode( int fd, int c )
|
2022-02-22 06:08:32 +03:00
|
|
|
{
|
2022-06-14 04:23:09 +03:00
|
|
|
static const char *q3ToAnsi[ 8 ] =
|
2022-02-22 06:08:32 +03:00
|
|
|
{
|
2024-07-17 22:53:35 +03:00
|
|
|
"\033[1;30m", // COLOR_BLACK
|
|
|
|
"\033[1;31m", // COLOR_RED
|
|
|
|
"\033[1;32m", // COLOR_GREEN
|
|
|
|
"\033[1;33m", // COLOR_YELLOW
|
|
|
|
"\033[1;34m", // COLOR_BLUE
|
|
|
|
"\033[1;36m", // COLOR_CYAN
|
|
|
|
"\033[1;35m", // COLOR_MAGENTA
|
2022-06-14 04:23:09 +03:00
|
|
|
"\033[0m", // COLOR_WHITE
|
|
|
|
};
|
|
|
|
const char *esc = q3ToAnsi[c];
|
|
|
|
|
2024-12-24 11:26:27 +03:00
|
|
|
return write( fd, esc, c == 7 ? 4 : 7 ) < 0 ? false : true;
|
2022-02-22 06:08:32 +03:00
|
|
|
}
|
2022-06-14 04:23:09 +03:00
|
|
|
#else
|
2024-12-24 11:26:27 +03:00
|
|
|
static qboolean Sys_WriteEscapeSequenceForColorcode( int fd, int c )
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
2022-06-14 04:23:09 +03:00
|
|
|
#endif
|
2022-02-22 06:08:32 +03:00
|
|
|
|
2024-12-24 11:26:27 +03:00
|
|
|
static void Sys_PrintLogfile( const int fd, const char *logtime, size_t logtime_len, const char *msg, const int colorize )
|
2018-04-14 04:08:28 +03:00
|
|
|
{
|
2022-06-14 03:27:08 +03:00
|
|
|
const char *p = msg;
|
|
|
|
|
2024-12-24 11:26:27 +03:00
|
|
|
if( logtime_len != 0 )
|
|
|
|
{
|
|
|
|
if( write( fd, logtime, logtime_len ) < 0 )
|
|
|
|
{
|
|
|
|
// not critical for us
|
|
|
|
}
|
|
|
|
}
|
2018-04-14 04:08:28 +03:00
|
|
|
|
2022-06-14 03:27:08 +03:00
|
|
|
while( p && *p )
|
2022-06-13 22:36:43 +03:00
|
|
|
{
|
2022-06-14 03:27:08 +03:00
|
|
|
p = Q_strchr( msg, '^' );
|
2022-06-13 22:36:43 +03:00
|
|
|
|
2022-06-14 03:27:08 +03:00
|
|
|
if( p == NULL )
|
|
|
|
{
|
2024-09-30 03:24:39 +03:00
|
|
|
if( write( fd, msg, Q_strlen( msg )) < 0 )
|
|
|
|
{
|
|
|
|
// don't call engine Msg, might cause recursion
|
|
|
|
fprintf( stderr, "%s: write failed: %s\n", __func__, strerror( errno ));
|
|
|
|
}
|
2022-06-14 03:27:08 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
else if( IsColorString( p ))
|
2022-06-13 22:36:43 +03:00
|
|
|
{
|
2022-06-14 03:27:08 +03:00
|
|
|
if( p != msg )
|
2024-09-30 03:24:39 +03:00
|
|
|
{
|
|
|
|
if( write( fd, msg, p - msg ) < 0 )
|
|
|
|
fprintf( stderr, "%s: write failed: %s\n", __func__, strerror( errno ));
|
|
|
|
}
|
2022-06-14 03:27:08 +03:00
|
|
|
msg = p + 2;
|
2022-06-14 04:23:09 +03:00
|
|
|
|
|
|
|
if( colorize )
|
|
|
|
Sys_WriteEscapeSequenceForColorcode( fd, ColorIndex( p[1] ));
|
2022-06-14 03:27:08 +03:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2024-09-30 03:24:39 +03:00
|
|
|
if( write( fd, msg, p - msg + 1 ) < 0 )
|
|
|
|
fprintf( stderr, "%s: write failed: %s\n", __func__, strerror( errno ));
|
2022-06-14 03:27:08 +03:00
|
|
|
msg = p + 1;
|
|
|
|
}
|
2022-06-13 22:36:43 +03:00
|
|
|
}
|
2022-06-14 04:23:09 +03:00
|
|
|
|
|
|
|
// flush the color
|
|
|
|
if( colorize )
|
|
|
|
Sys_WriteEscapeSequenceForColorcode( fd, 7 );
|
2022-06-13 22:36:43 +03:00
|
|
|
}
|
|
|
|
|
2024-12-24 11:26:27 +03:00
|
|
|
static void Sys_PrintStdout( const char *logtime, size_t logtime_len, const char *msg )
|
2022-06-13 22:36:43 +03:00
|
|
|
{
|
|
|
|
#if XASH_MOBILE_PLATFORM
|
|
|
|
static char buf[MAX_PRINT_MSG];
|
2022-02-22 06:08:32 +03:00
|
|
|
|
2022-06-10 11:20:58 +03:00
|
|
|
// strip color codes
|
2022-06-13 22:36:43 +03:00
|
|
|
COM_StripColors( msg, buf );
|
2022-06-10 11:20:58 +03:00
|
|
|
|
2022-02-22 06:08:32 +03:00
|
|
|
// platform-specific output
|
2019-09-19 17:08:16 +03:00
|
|
|
#if XASH_ANDROID && !XASH_DEDICATED
|
2022-06-14 04:23:09 +03:00
|
|
|
__android_log_write( ANDROID_LOG_DEBUG, "Xash", buf );
|
2022-06-13 22:36:43 +03:00
|
|
|
#endif // XASH_ANDROID && !XASH_DEDICATED
|
2018-04-14 04:08:28 +03:00
|
|
|
|
|
|
|
#if TARGET_OS_IOS
|
2022-06-13 22:36:43 +03:00
|
|
|
void IOS_Log( const char * );
|
|
|
|
IOS_Log( buf );
|
|
|
|
#endif // TARGET_OS_IOS
|
2023-02-05 02:09:32 +01:00
|
|
|
|
2023-03-24 03:25:11 +04:00
|
|
|
#if XASH_NSWITCH && NSWITCH_DEBUG
|
2023-02-05 02:09:32 +01:00
|
|
|
// just spew it to stderr normally in debug mode
|
|
|
|
fprintf( stderr, "%s %s", logtime, buf );
|
|
|
|
#endif // XASH_NSWITCH && NSWITCH_DEBUG
|
2023-02-09 05:59:30 +03:00
|
|
|
|
2023-03-24 03:25:11 +04:00
|
|
|
#if XASH_PSVITA
|
|
|
|
// spew to stderr only in developer mode
|
|
|
|
if( host_developer.value )
|
|
|
|
{
|
|
|
|
fprintf( stderr, "%s %s", logtime, buf );
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2022-06-14 04:25:40 +03:00
|
|
|
#elif !XASH_WIN32 // Wcon does the job
|
2024-12-24 11:26:27 +03:00
|
|
|
Sys_PrintLogfile( STDOUT_FILENO, logtime, logtime_len, msg, XASH_COLORIZE_CONSOLE );
|
2022-06-14 04:25:40 +03:00
|
|
|
Sys_FlushStdout();
|
2018-04-14 04:08:28 +03:00
|
|
|
#endif
|
2022-06-13 22:36:43 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void Sys_PrintLog( const char *pMsg )
|
|
|
|
{
|
|
|
|
time_t crt_time;
|
|
|
|
const struct tm *crt_tm;
|
|
|
|
char logtime[32] = "";
|
|
|
|
static char lastchar;
|
2024-12-24 11:26:27 +03:00
|
|
|
qboolean print_time = true;
|
|
|
|
size_t len, logtime_len = 0;
|
2022-06-13 22:36:43 +03:00
|
|
|
|
2024-12-24 11:26:27 +03:00
|
|
|
if( !lastchar || lastchar == '\n' )
|
|
|
|
{
|
|
|
|
if( time( &crt_time ) >= 0 )
|
|
|
|
{
|
|
|
|
crt_tm = localtime( &crt_time );
|
|
|
|
if( crt_tm == NULL )
|
|
|
|
print_time = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else print_time = false;
|
2018-04-14 04:08:28 +03:00
|
|
|
|
2024-12-24 11:26:27 +03:00
|
|
|
if( print_time )
|
|
|
|
{
|
|
|
|
logtime_len = strftime( logtime, sizeof( logtime ), "[%H:%M:%S] ", crt_tm ); // short time
|
|
|
|
logtime_len = Q_min( logtime_len, sizeof( logtime ) - 1 ); // just in case
|
|
|
|
}
|
2018-04-14 04:08:28 +03:00
|
|
|
|
2022-06-13 22:36:43 +03:00
|
|
|
// spew to stdout
|
2024-12-24 11:26:27 +03:00
|
|
|
Sys_PrintStdout( logtime, logtime_len, pMsg );
|
2018-05-03 23:51:23 +07:00
|
|
|
|
2024-08-03 10:59:30 +03:00
|
|
|
len = Q_strlen( pMsg );
|
|
|
|
|
2024-12-24 11:26:27 +03:00
|
|
|
// save last char to detect when line was not ended
|
|
|
|
lastchar = len > 0 ? pMsg[len - 1] : 0;
|
|
|
|
|
2025-02-14 00:19:46 +03:00
|
|
|
// spew to engine.log
|
|
|
|
if( s_ld.logfile )
|
2024-12-24 11:26:27 +03:00
|
|
|
{
|
2025-02-14 00:19:46 +03:00
|
|
|
if( s_ld.log_time && print_time )
|
|
|
|
{
|
|
|
|
logtime_len = strftime( logtime, sizeof( logtime ), "[%Y:%m:%d|%H:%M:%S] ", crt_tm ); //full time
|
|
|
|
logtime_len = Q_min( logtime_len, sizeof( logtime ) - 1 ); // just in case
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
logtime[0] = '\0';
|
|
|
|
logtime_len = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
Sys_PrintLogfile( s_ld.logfileno, logtime, logtime_len, pMsg, false );
|
|
|
|
Sys_FlushLogfile();
|
2024-12-24 11:26:27 +03:00
|
|
|
}
|
2018-04-14 04:08:28 +03:00
|
|
|
}
|
2018-04-18 18:32:30 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
=============================================================================
|
|
|
|
|
|
|
|
CONSOLE PRINT
|
|
|
|
|
|
|
|
=============================================================================
|
|
|
|
*/
|
2024-07-17 22:27:01 +03:00
|
|
|
static void Con_Printfv( qboolean debug, const char *szFmt, va_list args )
|
|
|
|
{
|
|
|
|
static char buffer[MAX_PRINT_MSG];
|
|
|
|
qboolean add_newline;
|
|
|
|
|
|
|
|
add_newline = Q_vsnprintf( buffer, sizeof( buffer ), szFmt, args ) < 0;
|
|
|
|
|
2024-07-29 04:48:17 +03:00
|
|
|
if( debug && !Q_strcmp( buffer, "0\n" ))
|
2024-07-17 22:27:01 +03:00
|
|
|
return; // hlrally spam
|
|
|
|
|
|
|
|
Sys_Print( buffer );
|
|
|
|
if( add_newline )
|
|
|
|
Sys_Print( "\n" );
|
|
|
|
}
|
|
|
|
|
2018-04-18 18:32:30 +03:00
|
|
|
/*
|
|
|
|
=============
|
|
|
|
Con_Printf
|
|
|
|
|
|
|
|
=============
|
|
|
|
*/
|
2020-01-19 08:15:54 +07:00
|
|
|
void GAME_EXPORT Con_Printf( const char *szFmt, ... )
|
2018-04-18 18:32:30 +03:00
|
|
|
{
|
2024-07-17 22:27:01 +03:00
|
|
|
va_list args;
|
2018-04-18 18:32:30 +03:00
|
|
|
|
|
|
|
if( !host.allow_console )
|
|
|
|
return;
|
|
|
|
|
|
|
|
va_start( args, szFmt );
|
2024-07-17 22:27:01 +03:00
|
|
|
Con_Printfv( false, szFmt, args );
|
2018-04-18 18:32:30 +03:00
|
|
|
va_end( args );
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
=============
|
|
|
|
Con_DPrintf
|
|
|
|
|
|
|
|
=============
|
|
|
|
*/
|
2020-01-19 08:15:54 +07:00
|
|
|
void GAME_EXPORT Con_DPrintf( const char *szFmt, ... )
|
2018-04-18 18:32:30 +03:00
|
|
|
{
|
2024-07-17 22:27:01 +03:00
|
|
|
va_list args;
|
2018-04-18 18:32:30 +03:00
|
|
|
|
|
|
|
if( host_developer.value < DEV_NORMAL )
|
|
|
|
return;
|
|
|
|
|
|
|
|
va_start( args, szFmt );
|
2024-07-17 22:27:01 +03:00
|
|
|
Con_Printfv( true, szFmt, args );
|
2018-04-18 18:32:30 +03:00
|
|
|
va_end( args );
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
=============
|
|
|
|
Con_Reportf
|
|
|
|
|
|
|
|
=============
|
|
|
|
*/
|
2018-04-23 23:07:54 +03:00
|
|
|
void Con_Reportf( const char *szFmt, ... )
|
2018-04-18 18:32:30 +03:00
|
|
|
{
|
2024-07-17 22:27:01 +03:00
|
|
|
va_list args;
|
2018-04-18 18:32:30 +03:00
|
|
|
|
|
|
|
if( host_developer.value < DEV_EXTENDED )
|
|
|
|
return;
|
|
|
|
|
|
|
|
va_start( args, szFmt );
|
2024-07-17 22:27:01 +03:00
|
|
|
Con_Printfv( false, szFmt, args );
|
2018-04-18 18:32:30 +03:00
|
|
|
va_end( args );
|
2018-04-22 13:07:40 +03:00
|
|
|
}
|
2020-02-08 23:00:39 +07:00
|
|
|
|
|
|
|
|
|
|
|
#if XASH_MESSAGEBOX == MSGBOX_STDERR
|
|
|
|
void Platform_MessageBox( const char *title, const char *message, qboolean parentMainWindow )
|
|
|
|
{
|
|
|
|
fprintf( stderr,
|
|
|
|
"======================================\n"
|
|
|
|
"%s: %s\n"
|
|
|
|
"======================================\n", title, message );
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|