You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
224 lines
5.2 KiB
224 lines
5.2 KiB
7 years ago
|
/*
|
||
|
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"
|
||
|
#ifdef __ANDROID__
|
||
|
#include <android/log.h>
|
||
|
#endif
|
||
|
|
||
|
#if !defined( _WIN32 ) && !defined( XASH_MOBILE_PLATFORM )
|
||
|
#define COLORIZE_CONSOLE
|
||
|
#define USE_SELECT
|
||
|
#endif
|
||
|
|
||
|
#ifdef USE_SELECT
|
||
|
// non-blocking console input
|
||
|
#include <sys/select.h>
|
||
|
#endif
|
||
|
|
||
|
typedef struct {
|
||
|
char title[64];
|
||
|
qboolean log_active;
|
||
|
char log_path[MAX_SYSPATH];
|
||
|
FILE *logfile;
|
||
|
int logfileno;
|
||
|
} LogData;
|
||
|
|
||
|
static LogData s_ld;
|
||
|
|
||
|
char *Sys_Input( void )
|
||
|
{
|
||
|
#ifdef USE_SELECT
|
||
|
{
|
||
|
fd_set rfds;
|
||
|
static char line[1024];
|
||
|
static int len;
|
||
|
struct timeval tv;
|
||
|
tv.tv_sec = 0;
|
||
|
tv.tv_usec = 0;
|
||
|
FD_ZERO(&rfds);
|
||
|
FD_SET(0, &rfds); // stdin
|
||
|
while( select(1, &rfds, NULL, NULL, &tv ) > 0 )
|
||
|
{
|
||
|
if( read( 0, &line[len], 1 ) != 1 )
|
||
|
break;
|
||
|
if( line[len] == '\n' || len > 1022 )
|
||
|
{
|
||
|
line[ ++len ] = 0;
|
||
|
len = 0;
|
||
|
return line;
|
||
|
}
|
||
|
len++;
|
||
|
tv.tv_sec = 0;
|
||
|
tv.tv_usec = 0;
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
#ifdef _WIN32
|
||
|
return Wcon_Input();
|
||
|
#endif
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
void Sys_DestroyConsole( void )
|
||
|
{
|
||
|
// last text message into console or log
|
||
|
MsgDev( D_NOTE, "Sys_DestroyConsole: Exiting!\n" );
|
||
|
#ifdef _WIN32
|
||
|
Wcon_DestroyConsole();
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
===============================================================================
|
||
|
|
||
|
SYSTEM LOG
|
||
|
|
||
|
===============================================================================
|
||
|
*/
|
||
|
void Sys_InitLog( void )
|
||
|
{
|
||
|
const char *mode;
|
||
|
|
||
|
if( host.change_game && host.type != HOST_DEDICATED )
|
||
|
mode = "a";
|
||
|
else mode = "w";
|
||
|
|
||
|
// create log if needed
|
||
|
if( s_ld.log_active )
|
||
|
{
|
||
|
s_ld.logfile = fopen( s_ld.log_path, mode );
|
||
|
if( !s_ld.logfile ) MsgDev( D_ERROR, "Sys_InitLog: can't create log file %s\n", s_ld.log_path );
|
||
|
|
||
|
fprintf( s_ld.logfile, "=================================================================================\n" );
|
||
|
fprintf( s_ld.logfile, "\t%s (build %i) started at %s\n", s_ld.title, Q_buildnum(), Q_timestamp( TIME_FULL ));
|
||
|
fprintf( s_ld.logfile, "=================================================================================\n" );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void Sys_CloseLog( void )
|
||
|
{
|
||
|
char event_name[64];
|
||
|
|
||
|
// continue logged
|
||
|
switch( host.status )
|
||
|
{
|
||
|
case HOST_CRASHED:
|
||
|
Q_strncpy( event_name, "crashed", sizeof( event_name ));
|
||
|
break;
|
||
|
case HOST_ERR_FATAL:
|
||
|
Q_strncpy( event_name, "stopped with error", sizeof( event_name ));
|
||
|
break;
|
||
|
default:
|
||
|
if( !host.change_game ) Q_strncpy( event_name, "stopped", sizeof( event_name ));
|
||
|
else Q_strncpy( event_name, host.finalmsg, sizeof( event_name ));
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if( s_ld.logfile )
|
||
|
{
|
||
|
fprintf( s_ld.logfile, "\n");
|
||
|
fprintf( s_ld.logfile, "=================================================================================");
|
||
|
if( host.change_game ) fprintf( s_ld.logfile, "\n\t%s (build %i) %s\n", s_ld.title, Q_buildnum(), event_name );
|
||
|
else fprintf( s_ld.logfile, "\n\t%s (build %i) %s at %s\n", s_ld.title, Q_buildnum(), event_name, Q_timestamp( TIME_FULL ));
|
||
|
fprintf( s_ld.logfile, "=================================================================================");
|
||
|
if( host.change_game ) fprintf( s_ld.logfile, "\n" ); // just for tabulate
|
||
|
|
||
|
fclose( s_ld.logfile );
|
||
|
s_ld.logfile = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void Sys_PrintLog( const char *pMsg )
|
||
|
{
|
||
|
time_t crt_time;
|
||
|
const struct tm *crt_tm;
|
||
|
char logtime[32] = "";
|
||
|
static char lastchar;
|
||
|
|
||
|
time( &crt_time );
|
||
|
crt_tm = localtime( &crt_time );
|
||
|
#ifdef __ANDROID__
|
||
|
__android_log_print( ANDROID_LOG_DEBUG, "Xash", "%s", pMsg );
|
||
|
#endif
|
||
|
|
||
|
#if TARGET_OS_IOS
|
||
|
void IOS_Log(const char*);
|
||
|
IOS_Log(pMsg);
|
||
|
#endif
|
||
|
|
||
|
|
||
|
if( !lastchar || lastchar == '\n')
|
||
|
strftime( logtime, sizeof( logtime ), "[%H:%M:%S] ", crt_tm ); //short time
|
||
|
|
||
|
#ifdef COLORIZE_CONSOLE
|
||
|
{
|
||
|
char colored[4096];
|
||
|
const char *msg = pMsg;
|
||
|
int len = 0;
|
||
|
while( *msg && ( len < 4090 ) )
|
||
|
{
|
||
|
static char q3ToAnsi[ 8 ] =
|
||
|
{
|
||
|
'0', // COLOR_BLACK
|
||
|
'1', // COLOR_RED
|
||
|
'2', // COLOR_GREEN
|
||
|
'3', // COLOR_YELLOW
|
||
|
'4', // COLOR_BLUE
|
||
|
'6', // COLOR_CYAN
|
||
|
'5', // COLOR_MAGENTA
|
||
|
0 // COLOR_WHITE
|
||
|
};
|
||
|
|
||
|
if( IsColorString( msg ) )
|
||
|
{
|
||
|
int color;
|
||
|
|
||
|
msg++;
|
||
|
color = q3ToAnsi[ *msg++ % 8 ];
|
||
|
colored[len++] = '\033';
|
||
|
colored[len++] = '[';
|
||
|
if( color )
|
||
|
{
|
||
|
colored[len++] = '3';
|
||
|
colored[len++] = color;
|
||
|
}
|
||
|
else
|
||
|
colored[len++] = '0';
|
||
|
colored[len++] = 'm';
|
||
|
}
|
||
|
else
|
||
|
colored[len++] = *msg++;
|
||
|
}
|
||
|
colored[len] = 0;
|
||
|
printf( "\033[34m%s\033[0m%s\033[0m", logtime, colored );
|
||
|
}
|
||
|
#else
|
||
|
#if !defined __ANDROID__ || defined XASH_DEDICATED
|
||
|
printf( "%s %s", logtime, pMsg );
|
||
|
fflush( stdout );
|
||
|
#endif
|
||
|
#endif
|
||
|
lastchar = pMsg[strlen(pMsg)-1];
|
||
|
if( !s_ld.logfile )
|
||
|
return;
|
||
|
|
||
|
if( !lastchar || lastchar == '\n')
|
||
|
strftime( logtime, sizeof( logtime ), "[%Y:%m:%d|%H:%M:%S]", crt_tm ); //full time
|
||
|
|
||
|
fprintf( s_ld.logfile, "%s %s", logtime, pMsg );
|
||
|
fflush( s_ld.logfile );
|
||
|
}
|