Browse Source

Move Win32 console into separate file(second commit), hide Win32 console code under _WIN32 macro. Add some fork-specific macros. Add sys_con.c for generic log file implementation.

pull/2/head
Alibek Omarov 6 years ago
parent
commit
4a0add4063
  1. 4
      engine/common/com_strings.h
  2. 10
      engine/common/common.h
  3. 27
      engine/common/host.c
  4. 223
      engine/common/sys_con.c
  5. 537
      engine/common/system.c
  6. 31
      engine/common/system.h
  7. 16
      engine/menu_int.h
  8. 43
      engine/platform/win32/win_con.c

4
engine/common/com_strings.h

@ -57,4 +57,6 @@ GNU General Public License for more details. @@ -57,4 +57,6 @@ GNU General Public License for more details.
#define DEFAULT_BSP_BUILD_ERROR "%s can't be loaded in this build. Please rebuild engine with enabled SUPPORT_BSP2_FORMAT\n"
#endif//COM_STRINGS_H
#define DEFAULT_UPDATE_PAGE "https://github.com/FWGS/xash3d-fwgs/releases/latest"
#endif//COM_STRINGS_H

10
engine/common/common.h

@ -186,8 +186,6 @@ typedef enum @@ -186,8 +186,6 @@ typedef enum
#define CIN_MAIN 0
#define CIN_LOGO 1
#define MAX_NUM_ARGVS 128
// config strings are a general means of communication from
// the server to all connected clients.
// each config string can be at most CS_SIZE characters.
@ -426,7 +424,7 @@ typedef struct host_parm_s @@ -426,7 +424,7 @@ typedef struct host_parm_s
// command line parms
int argc;
const char *argv[MAX_NUM_ARGVS];
const char **argv;
double realtime; // host.curtime
double frametime; // time between engine frames
@ -916,6 +914,8 @@ void Key_SetKeyDest( int key_dest ); @@ -916,6 +914,8 @@ void Key_SetKeyDest( int key_dest );
#include "avi/avi.h"
// shared calls
typedef struct sv_client_s sv_client_t;
typedef struct sizebuf_s sizebuf_t;
qboolean CL_IsInGame( void );
qboolean CL_IsInMenu( void );
qboolean CL_IsInConsole( void );
@ -934,12 +934,12 @@ int COM_ExpandFilename( const char *fileName, char *nameOutBuffer, int nameOutBu @@ -934,12 +934,12 @@ int COM_ExpandFilename( const char *fileName, char *nameOutBuffer, int nameOutBu
struct pmtrace_s *PM_TraceLine( float *start, float *end, int flags, int usehull, int ignore_pe );
void SV_StartSound( edict_t *ent, int chan, const char *sample, float vol, float attn, int flags, int pitch );
void SV_StartMusic( const char *curtrack, const char *looptrack, long position );
void SV_CreateDecal( struct sizebuf_s *msg, const float *origin, int decalIndex, int entityIndex, int modelIndex, int flags, float scale );
void SV_CreateDecal( sizebuf_t *msg, const float *origin, int decalIndex, int entityIndex, int modelIndex, int flags, float scale );
void Log_Printf( const char *fmt, ... );
struct sizebuf_s *SV_GetReliableDatagram( void );
void SV_BroadcastCommand( const char *fmt, ... );
qboolean SV_RestoreCustomDecal( struct decallist_s *entry, edict_t *pEdict, qboolean adjacent );
void SV_BroadcastPrintf( struct sv_client_s *ignore, char *fmt, ... );
void SV_BroadcastPrintf( sv_client_t *ignore, char *fmt, ... );
int R_CreateDecalList( struct decallist_s *pList );
void R_DecalRemoveAll( int texture );
void R_ClearAllDecals( void );

27
engine/common/host.c

@ -393,12 +393,11 @@ void Host_GetCommands( void ) @@ -393,12 +393,11 @@ void Host_GetCommands( void )
{
char *cmd;
if( host.type != HOST_DEDICATED )
return;
cmd = Con_Input();
if( cmd ) Cbuf_AddText( cmd );
Cbuf_Execute ();
while( ( cmd = Sys_Input() ) )
{
Cbuf_AddText( cmd );
Cbuf_Execute();
}
}
/*
@ -786,7 +785,9 @@ void Host_InitCommon( int argc, char **argv, const char *progname, qboolean bCha @@ -786,7 +785,9 @@ void Host_InitCommon( int argc, char **argv, const char *progname, qboolean bCha
// member console allowing
host.allow_console_init = host.allow_console;
Con_CreateConsole(); // system console used by dedicated server or show fatal errors
#ifdef _WIN32
Wcon_CreateConsole(); // system console used by dedicated server or show fatal errors
#endif
// NOTE: this message couldn't be passed into game console but it doesn't matter
MsgDev( D_NOTE, "Sys_LoadLibrary: Loading xash.dll - ok\n" );
@ -889,7 +890,9 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa @@ -889,7 +890,9 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa
if( host.type == HOST_DEDICATED )
{
Con_InitConsoleCommands ();
#ifdef _WIN32
Wcon_InitConsoleCommands ();
#endif
Cmd_AddCommand( "quit", Sys_Quit, "quit the game" );
Cmd_AddCommand( "exit", Sys_Quit, "quit the game" );
@ -902,7 +905,9 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa @@ -902,7 +905,9 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa
switch( host.type )
{
case HOST_NORMAL:
Con_ShowConsole( false ); // hide console
#ifdef _WIN32
Wcon_ShowConsole( false ); // hide console
#endif
// execute startup config and cmdline
Cbuf_AddText( va( "exec %s.rc\n", SI.rcName ));
Cbuf_Execute();
@ -963,7 +968,9 @@ void EXPORT Host_Shutdown( void ) @@ -963,7 +968,9 @@ void EXPORT Host_Shutdown( void )
Mod_Shutdown();
NET_Shutdown();
Host_FreeCommon();
Con_DestroyConsole();
#ifdef _WIN32
Wcon_DestroyConsole();
#endif
// must be last, console uses this
Mem_FreePool( &host.mempool );

223
engine/common/sys_con.c

@ -0,0 +1,223 @@ @@ -0,0 +1,223 @@
/*
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 );
}

537
engine/common/sys_win.c → engine/common/system.c

@ -15,16 +15,40 @@ GNU General Public License for more details. @@ -15,16 +15,40 @@ GNU General Public License for more details.
#include "common.h"
#include "mathlib.h"
#include <time.h>
#include <stdlib.h>
#ifdef XASH_SDL
#include <SDL.h>
#endif
#ifndef _WIN32
#include <unistd.h>
#include <signal.h>
#include <dlfcn.h>
#ifndef __ANDROID__
extern char **environ;
#include <pwd.h>
#endif
#endif
#include "menu_int.h" // _UPDATE_PAGE macro
qboolean error_on_exit = false; // arg for exit();
#define DEBUG_BREAK
#if defined _WIN32 && !defined XASH_SDL
#include <winbase.h>
#endif
/*
================
Sys_DoubleTime
================
*/
double Sys_DoubleTime( void )
double GAME_EXPORT Sys_DoubleTime( void )
{
#if XASH_TIMER == TIMER_WIN32
static LARGE_INTEGER g_PerformanceFrequency;
static LARGE_INTEGER g_ClockStart;
LARGE_INTEGER CurrentTime;
@ -37,8 +61,92 @@ double Sys_DoubleTime( void ) @@ -37,8 +61,92 @@ double Sys_DoubleTime( void )
QueryPerformanceCounter( &CurrentTime );
return (double)( CurrentTime.QuadPart - g_ClockStart.QuadPart ) / (double)( g_PerformanceFrequency.QuadPart );
#elif XASH_TIMER == TIMER_SDL
static longtime_t g_PerformanceFrequency;
static longtime_t g_ClockStart;
longtime_t CurrentTime;
if( !g_PerformanceFrequency )
{
g_PerformanceFrequency = SDL_GetPerformanceFrequency();
g_ClockStart = SDL_GetPerformanceCounter();
}
CurrentTime = SDL_GetPerformanceCounter();
return (double)( CurrentTime - g_ClockStart ) / (double)( g_PerformanceFrequency );
#elif XASH_TIMER == TIMER_LINUX
static longtime_t g_PerformanceFrequency;
static longtime_t g_ClockStart;
longtime_t CurrentTime;
struct timespec ts;
if( !g_PerformanceFrequency )
{
struct timespec res;
if( !clock_getres(CLOCK_MONOTONIC, &res) )
g_PerformanceFrequency = 1000000000LL/res.tv_nsec;
}
clock_gettime(CLOCK_MONOTONIC, &ts);
return (double) ts.tv_sec + (double) ts.tv_nsec/1000000000.0;
#endif
}
#ifdef GDB_BREAK
#include <fcntl.h>
qboolean Sys_DebuggerPresent( void )
{
char buf[1024];
int status_fd = open( "/proc/self/status", O_RDONLY );
if ( status_fd == -1 )
return 0;
ssize_t num_read = read( status_fd, buf, sizeof( buf ) );
if ( num_read > 0 )
{
static const char TracerPid[] = "TracerPid:";
const byte *tracer_pid;
buf[num_read] = 0;
tracer_pid = (const byte*)Q_strstr( buf, TracerPid );
if( !tracer_pid )
return false;
//printf( "%s\n", tracer_pid );
while( *tracer_pid < '0' || *tracer_pid > '9' )
if( *tracer_pid++ == '\n' )
return false;
//printf( "%s\n", tracer_pid );
return !!Q_atoi( (const char*)tracer_pid );
}
return false;
}
#undef DEBUG_BREAK
#ifdef __i386__
#define DEBUG_BREAK \
if( Sys_DebuggerPresent() ) \
asm volatile("int $3;")
#else
#define DEBUG_BREAK \
if( Sys_DebuggerPresent() ) \
raise( SIGINT )
#endif
#endif
#if defined _WIN32 && !defined XASH_64BIT
#ifdef _MSC_VER
BOOL WINAPI IsDebuggerPresent(void);
#define DEBUG_BREAK if( IsDebuggerPresent() ) \
_asm{ int 3 }
#else
#define DEBUG_BREAK if( IsDebuggerPresent() ) \
asm volatile("int $3;")
#endif
#endif
/*
================
Sys_GetClipboardData
@ -48,31 +156,19 @@ create buffer, that contain clipboard @@ -48,31 +156,19 @@ create buffer, that contain clipboard
*/
char *Sys_GetClipboardData( void )
{
static char *data = NULL;
static char data[1024];
char *cliptext;
if( data )
{
// release previous cbd
Z_Free( data );
data = NULL;
}
data[0] = '\0';
if( OpenClipboard( NULL ) != 0 )
#ifdef XASH_SDL
cliptext = SDL_GetClipboardText();
if( cliptext )
{
HANDLE hClipboardData;
if(( hClipboardData = GetClipboardData( CF_TEXT )) != 0 )
{
if(( cliptext = GlobalLock( hClipboardData )) != 0 )
{
data = Z_Malloc( GlobalSize( hClipboardData ) + 1 );
Q_strcpy( data, cliptext );
GlobalUnlock( hClipboardData );
}
}
CloseClipboard();
Q_strncpy( data, cliptext, sizeof( data ) );
SDL_free( cliptext );
}
#endif // XASH_SDL
return data;
}
@ -86,23 +182,9 @@ write screenshot into clipboard @@ -86,23 +182,9 @@ write screenshot into clipboard
*/
void Sys_SetClipboardData( const byte *buffer, size_t size )
{
EmptyClipboard();
if( OpenClipboard( NULL ) != 0 )
{
HGLOBAL hResult = GlobalAlloc( GMEM_MOVEABLE, size );
byte *bufferCopy = (byte *)GlobalLock( hResult );
memcpy( bufferCopy, buffer, size );
GlobalUnlock( hResult );
if( SetClipboardData( CF_DIB, hResult ) == NULL )
{
MsgDev( D_ERROR, "unable to write screenshot\n" );
GlobalFree( hResult );
}
CloseClipboard();
}
#ifdef XASH_SDL
SDL_SetClipboardText((char *)buffer);
#endif
}
/*
@ -114,8 +196,17 @@ freeze application for some time @@ -114,8 +196,17 @@ freeze application for some time
*/
void Sys_Sleep( int msec )
{
msec = bound( 1, msec, 1000 );
if( !msec )
return;
msec = min( msec, 1000 );
#if XASH_TIMER == TIMER_WIN32
Sleep( msec );
#elif XASH_TIMER == TIMER_SDL
SDL_Delay( msec );
#elif XASH_TIEMR == TIMER_LINUX
usleep( msec * 1000 );
#endif
}
/*
@ -127,63 +218,106 @@ returns username for current profile @@ -127,63 +218,106 @@ returns username for current profile
*/
char *Sys_GetCurrentUser( void )
{
static string sys_user_name;
dword size = sizeof( sys_user_name );
if( !sys_user_name[0] )
{
HINSTANCE advapi32_dll = LoadLibrary( "advapi32.dll" );
BOOL (_stdcall *pGetUserNameA)( LPSTR lpBuffer, LPDWORD nSize ) = NULL;
if( advapi32_dll ) pGetUserNameA = (void *)GetProcAddress( advapi32_dll, "GetUserNameA" );
if( pGetUserNameA) pGetUserNameA( sys_user_name, &size );
if( advapi32_dll ) FreeLibrary( advapi32_dll ); // no need anymore...
if( !sys_user_name[0] ) Q_strcpy( sys_user_name, "player" );
}
return sys_user_name;
#if defined(_WIN32)
static string s_userName;
unsigned long size = sizeof( s_userName );
if( GetUserName( s_userName, &size ))
return s_userName;
#elif !defined(__ANDROID__)
uid_t uid = geteuid();
struct passwd *pw = getpwuid( uid );
if( pw )
return pw->pw_name;
#endif
return "Player";
}
/*
=================
Sys_GetMachineKey
=================
*/
const char *Sys_GetMachineKey( int *nLength )
#if (defined(__linux__) && !defined(__ANDROID__)) || defined (__FreeBSD__) || defined (__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
static qboolean Sys_FindExecutable( const char *baseName, char *buf, size_t size )
{
HINSTANCE rpcrt4_dll = LoadLibrary( "rpcrt4.dll" );
RPC_STATUS (_stdcall *pUuidCreateSequential)( UUID __RPC_FAR *Uuid ) = NULL;
static byte key[32];
byte mac[8];
UUID uuid;
int i;
char *envPath;
char *part;
size_t length;
size_t baseNameLength;
size_t needTrailingSlash;
if( rpcrt4_dll ) pUuidCreateSequential = (void *)GetProcAddress( rpcrt4_dll, "UuidCreateSequential" );
if( pUuidCreateSequential ) pUuidCreateSequential( &uuid ); // ask OS to create UUID
if( rpcrt4_dll ) FreeLibrary( rpcrt4_dll ); // no need anymore...
if( !baseName || !baseName[0] )
return false;
envPath = getenv( "PATH" );
if( !envPath )
return false;
for( i = 2; i < 8; i++ ) // bytes 2 through 7 inclusive are MAC address
mac[i-2] = uuid.Data4[i];
baseNameLength = Q_strlen( baseName );
while( *envPath )
{
part = Q_strchr( envPath, ':' );
if( part )
length = part - envPath;
else
length = Q_strlen( envPath );
Q_snprintf( key, sizeof( key ), "%02X-%02X-%02X-%02X-%02X-%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5] );
if( length > 0 )
{
needTrailingSlash = ( envPath[length - 1] == '/' ) ? 0 : 1;
if( length + baseNameLength + needTrailingSlash < size )
{
Q_strncpy( buf, envPath, length + 1 );
if( needTrailingSlash )
Q_strcpy( buf + length, "/" );
Q_strcpy( buf + length + needTrailingSlash, baseName );
buf[length + needTrailingSlash + baseNameLength] = '\0';
if( access( buf, X_OK ) == 0 )
return true;
}
}
if( nLength ) *nLength = Q_strlen( key );
return key;
envPath += length;
if( *envPath == ':' )
envPath++;
}
return false;
}
#endif
/*
=================
Sys_ShellExecute
=================
*/
void Sys_ShellExecute( const char *path, const char *parms, qboolean exit )
void Sys_ShellExecute( const char *path, const char *parms, qboolean shouldExit )
{
HINSTANCE shell32_dll = LoadLibrary( "shell32.dll" );
HINSTANCE (_stdcall *pShellExecuteA)( HWND hwnd, LPCSTR lpOp, LPCSTR lpFile, LPCSTR lpParam, LPCSTR lpDir, INT nShowCmd ) = NULL;
if( shell32_dll ) pShellExecuteA = (void *)GetProcAddress( shell32_dll, "ShellExecuteA" );
if( pShellExecuteA ) pShellExecuteA( NULL, "open", path, parms, NULL, SW_SHOW );
if( shell32_dll ) FreeLibrary( shell32_dll ); // no need anymore...
#ifdef _WIN32
if( !Q_strcmp( path, GENERIC_UPDATE_PAGE ) || !Q_strcmp( path, PLATFORM_UPDATE_PAGE ))
path = DEFAULT_UPDATE_PAGE;
ShellExecute( NULL, "open", path, parms, NULL, SW_SHOW );
#elif (defined(__linux__) && !defined (__ANDROID__)) || defined (__FreeBSD__) || defined (__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
if( !Q_strcmp( path, GENERIC_UPDATE_PAGE ) || !Q_strcmp( path, PLATFORM_UPDATE_PAGE ))
path = DEFAULT_UPDATE_PAGE;
char xdgOpen[128];
if( Sys_FindExecutable( OPEN_COMMAND, xdgOpen, sizeof( xdgOpen ) ) )
{
const char *argv[] = {xdgOpen, path, NULL};
pid_t id = fork( );
if( id == 0 )
{
execve( xdgOpen, (char **)argv, environ );
fprintf( stderr, "error opening %s %s", xdgOpen, path );
_exit( 1 );
}
}
else MsgDev( D_WARN, "Could not find "OPEN_COMMAND" utility\n" );
#elif defined(__ANDROID__) && !defined(XASH_DEDICATED)
Android_ShellExecute( path, parms );
#endif
if( exit ) Sys_Quit();
if( shouldExit )
Sys_Quit();
}
/*
@ -223,7 +357,7 @@ Sys_MergeCommandLine @@ -223,7 +357,7 @@ Sys_MergeCommandLine
==================
*/
void Sys_MergeCommandLine( )
void Sys_MergeCommandLine( void )
{
const char *blank = "censored";
int i;
@ -280,6 +414,7 @@ qboolean _Sys_GetParmFromCmdLine( char *parm, char *out, size_t size ) @@ -280,6 +414,7 @@ qboolean _Sys_GetParmFromCmdLine( char *parm, char *out, size_t size )
void Sys_SendKeyEvents( void )
{
#ifdef _WIN32
MSG msg;
while( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ))
@ -290,6 +425,7 @@ void Sys_SendKeyEvents( void ) @@ -290,6 +425,7 @@ void Sys_SendKeyEvents( void )
TranslateMessage( &msg );
DispatchMessage( &msg );
}
#endif
}
//=======================================================================
@ -383,6 +519,7 @@ wait for 'Esc' key will be hit @@ -383,6 +519,7 @@ wait for 'Esc' key will be hit
*/
void Sys_WaitForQuit( void )
{
#ifdef _WIN32
MSG msg;
Con_RegisterHotkeys();
@ -399,37 +536,7 @@ void Sys_WaitForQuit( void ) @@ -399,37 +536,7 @@ void Sys_WaitForQuit( void )
}
else Sys_Sleep( 20 );
}
}
long _stdcall Sys_Crash( PEXCEPTION_POINTERS pInfo )
{
// save config
if( host.status != HOST_CRASHED )
{
// check to avoid recursive call
error_on_exit = true;
host.crashed = true;
if( host.type == HOST_NORMAL )
CL_Crashed(); // tell client about crash
else host.status = HOST_CRASHED;
Con_Printf( "unhandled exception: %p at address %p\n", pInfo->ExceptionRecord->ExceptionAddress, pInfo->ExceptionRecord->ExceptionCode );
if( !host_developer.value )
{
// for non-development mode
Sys_Quit();
return EXCEPTION_CONTINUE_EXECUTION;
}
// all other states keep unchanged to let debugger find bug
Con_DestroyConsole();
}
if( host.oldFilter )
return host.oldFilter( pInfo );
return EXCEPTION_CONTINUE_EXECUTION;
#endif
}
/*
@ -466,7 +573,9 @@ void Sys_Error( const char *error, ... ) @@ -466,7 +573,9 @@ void Sys_Error( const char *error, ... )
{
va_list argptr;
char text[MAX_SYSPATH];
DEBUG_BREAK;
if( host.status == HOST_ERR_FATAL )
return; // don't multiple executes
@ -481,27 +590,48 @@ void Sys_Error( const char *error, ... ) @@ -481,27 +590,48 @@ void Sys_Error( const char *error, ... )
SV_SysError( text );
if( host.type == HOST_NORMAL )
if( !Host_IsDedicated() )
{
if( host.hWnd ) ShowWindow( host.hWnd, SW_HIDE );
#ifdef XASH_SDL
if( host.hWnd ) SDL_HideWindow( host.hWnd );
#endif
}
if( host_developer.value )
{
#ifdef _WIN32
Con_ShowConsole( true );
Con_DisableInput(); // disable input line for dedicated server
#endif
Sys_Print( text ); // print error message
Sys_WaitForQuit();
}
else
{
#ifdef _WIN32
Con_ShowConsole( false );
#endif
MSGBOX( text );
}
Sys_Quit();
}
#ifdef __EMSCRIPTEN__
/* strange glitchy bug on emscripten
_exit->_Exit->asm._exit->_exit
As we do not need atexit(), just throw hidden exception
*/
#include <emscripten.h>
#define exit my_exit
void my_exit(int ret)
{
emscripten_cancel_main_loop();
printf("exit(%d)\n", ret);
EM_ASM(if(showElement)showElement('reload', true);throw 'SimulateInfiniteLoop');
}
#endif
/*
================
Sys_Quit
@ -522,65 +652,75 @@ print into window console @@ -522,65 +652,75 @@ print into window console
*/
void Sys_Print( const char *pMsg )
{
const char *msg;
static char buffer[MAX_PRINT_MSG];
static char logbuf[MAX_PRINT_MSG];
char *b = buffer;
char *c = logbuf;
int i = 0;
if( host.type == HOST_NORMAL )
if( !Host_IsDedicated() )
Con_Print( pMsg );
// if the message is REALLY long, use just the last portion of it
if( Q_strlen( pMsg ) > sizeof( buffer ) - 1 )
msg = pMsg + Q_strlen( pMsg ) - sizeof( buffer ) + 1;
else msg = pMsg;
// copy into an intermediate buffer
while( msg[i] && (( b - buffer ) < sizeof( buffer ) - 1 ))
#ifdef _WIN32
{
if( msg[i] == '\n' && msg[i+1] == '\r' )
{
b[0] = '\r';
b[1] = c[0] = '\n';
b += 2, c++;
i++;
}
else if( msg[i] == '\r' )
{
b[0] = c[0] = '\r';
b[1] = '\n';
b += 2, c++;
}
else if( msg[i] == '\n' )
{
b[0] = '\r';
b[1] = c[0] = '\n';
b += 2, c++;
}
else if( msg[i] == '\35' || msg[i] == '\36' || msg[i] == '\37' )
{
i++; // skip console pseudo graph
}
else if( IsColorString( &msg[i] ))
{
i++; // skip color prefix
}
else
const char *msg;
static char buffer[MAX_PRINT_MSG];
static char logbuf[MAX_PRINT_MSG];
char *b = buffer;
char *c = logbuf;
int i = 0;
if( host.type == HOST_NORMAL )
Con_Print( pMsg );
// if the message is REALLY long, use just the last portion of it
if( Q_strlen( pMsg ) > sizeof( buffer ) - 1 )
msg = pMsg + Q_strlen( pMsg ) - sizeof( buffer ) + 1;
else msg = pMsg;
// copy into an intermediate buffer
while( msg[i] && (( b - buffer ) < sizeof( buffer ) - 1 ))
{
if( msg[i] == '\1' || msg[i] == '\2' )
if( msg[i] == '\n' && msg[i+1] == '\r' )
{
b[0] = '\r';
b[1] = c[0] = '\n';
b += 2, c++;
i++;
*b = *c = msg[i];
b++, c++;
}
else if( msg[i] == '\r' )
{
b[0] = c[0] = '\r';
b[1] = '\n';
b += 2, c++;
}
else if( msg[i] == '\n' )
{
b[0] = '\r';
b[1] = c[0] = '\n';
b += 2, c++;
}
else if( msg[i] == '\35' || msg[i] == '\36' || msg[i] == '\37' )
{
i++; // skip console pseudo graph
}
else if( IsColorString( &msg[i] ))
{
i++; // skip color prefix
}
else
{
if( msg[i] == '\1' || msg[i] == '\2' )
i++;
*b = *c = msg[i];
b++, c++;
}
i++;
}
i++;
*b = *c = 0; // terminator
Con_WinPrint( buffer );
}
#endif
*b = *c = 0; // terminator
Sys_PrintLog( pMsg );
Sys_PrintLog( logbuf );
Con_WinPrint( buffer );
// Rcon_Print( pMsg );
}
/*
@ -617,70 +757,3 @@ void MsgDev( int type, const char *pMsg, ... ) @@ -617,70 +757,3 @@ void MsgDev( int type, const char *pMsg, ... )
break;
}
}
/*
===============================================================================
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_wcd.log_active )
{
s_wcd.logfile = fopen( s_wcd.log_path, mode );
if( !s_wcd.logfile ) MsgDev( D_ERROR, "Sys_InitLog: can't create log file %s\n", s_wcd.log_path );
fprintf( s_wcd.logfile, "=================================================================================\n" );
fprintf( s_wcd.logfile, "\t%s (build %i) started at %s\n", s_wcd.title, Q_buildnum(), Q_timestamp( TIME_FULL ));
fprintf( s_wcd.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_wcd.logfile )
{
fprintf( s_wcd.logfile, "\n");
fprintf( s_wcd.logfile, "=================================================================================");
if( host.change_game ) fprintf( s_wcd.logfile, "\n\t%s (build %i) %s\n", s_wcd.title, Q_buildnum(), event_name );
else fprintf( s_wcd.logfile, "\n\t%s (build %i) %s at %s\n", s_wcd.title, Q_buildnum(), event_name, Q_timestamp( TIME_FULL ));
fprintf( s_wcd.logfile, "=================================================================================");
if( host.change_game ) fprintf( s_wcd.logfile, "\n" ); // just for tabulate
fclose( s_wcd.logfile );
s_wcd.logfile = NULL;
}
}
void Sys_PrintLog( const char *pMsg )
{
if( !s_wcd.logfile ) return;
fprintf( s_wcd.logfile, pMsg );
fflush( s_wcd.logfile );
}

31
engine/common/system.h

@ -86,7 +86,7 @@ void Sys_Error( const char *error, ... ); @@ -86,7 +86,7 @@ void Sys_Error( const char *error, ... );
qboolean Sys_LoadLibrary( dll_info_t *dll );
void* Sys_GetProcAddress( dll_info_t *dll, const char* name );
qboolean Sys_FreeLibrary( dll_info_t *dll );
void Sys_ParseCommandLine( int argc, char **argv );
void Sys_ParseCommandLine( int argc, const char **argv );
void Sys_MergeCommandLine( void );
void Sys_SetupCrashHandler( void );
void Sys_RestoreCrashHandler( void );
@ -94,7 +94,6 @@ void Sys_SetClipboardData( const byte *buffer, size_t size ); @@ -94,7 +94,6 @@ void Sys_SetClipboardData( const byte *buffer, size_t size );
#define Sys_GetParmFromCmdLine( parm, out ) _Sys_GetParmFromCmdLine( parm, out, sizeof( out ))
qboolean _Sys_GetParmFromCmdLine( char *parm, char *out, size_t size );
void Sys_ShellExecute( const char *path, const char *parms, qboolean exit );
const char *Sys_GetMachineKey( int *nLength );
void Sys_SendKeyEvents( void );
void Sys_Print( const char *pMsg );
void Sys_PrintLog( const char *pMsg );
@ -105,14 +104,26 @@ void Sys_Quit( void ); @@ -105,14 +104,26 @@ void Sys_Quit( void );
//
// sys_con.c
//
void Con_ShowConsole( qboolean show );
void Con_WinPrint( const char *pMsg );
void Con_InitConsoleCommands( void );
void Con_CreateConsole( void );
void Con_DestroyConsole( void );
void Con_RegisterHotkeys( void );
void Con_DisableInput( void );
char *Con_Input( void );
char *Sys_Input( void );
void Sys_DestroyConsole( void );
void Sys_CloseLog( void );
void Sys_InitLog( void );
void Sys_PrintLog( const char *pMsg );
int Sys_LogFileNo( void );
//
// con_win.c
//
#ifdef _WIN32
void Wcon_ShowConsole( qboolean show );
void Wcon_Print( const char *pMsg );
void Wcon_Init( void );
void Wcon_CreateConsole( void );
void Wcon_DestroyConsole( void );
void Wcon_DisableInput( void );
void Wcon_Clear( void );
char *Wcon_Input( void );
#endif
// text messages
#define Msg Con_Printf

16
engine/menu_int.h

@ -164,6 +164,13 @@ typedef struct ui_enginefuncs_s @@ -164,6 +164,13 @@ typedef struct ui_enginefuncs_s
const char *(*pfnGetModeString)( int vid_mode );
} ui_enginefuncs_t;
typedef struct ui_textfuncs_s {
void (*pfnEnableTextInput)( int enable );
int (*pfnUtfProcessChar) ( int ch );
int (*pfnUtfMoveLeft) ( char *str, int pos );
int (*pfnUtfMoveRight) ( char *str, int pos, int length );
} ui_textfuncs_t;
typedef struct
{
int (*pfnVidInit)( void );
@ -186,4 +193,11 @@ typedef struct @@ -186,4 +193,11 @@ typedef struct
typedef int (*MENUAPI)( UI_FUNCTIONS *pFunctionTable, ui_enginefuncs_t* engfuncs, ui_globalvars_t *pGlobals );
#endif//MENU_INT_H
typedef int (*UITEXTAPI)( ui_textfuncs_t* engfuncs );
typedef void (*ADDTOUCHBUTTONTOLIST)( const char *name, const char *texture, const char *command, unsigned char *color, int flags );
#define PLATFORM_UPDATE_PAGE "PlatformUpdatePage"
#define GENERIC_UPDATE_PAGE "GenericUpdatePage"
#endif//MENU_INT_H

43
engine/platform/win32/win_con.c

@ -56,12 +56,11 @@ typedef struct @@ -56,12 +56,11 @@ typedef struct
// log stuff
qboolean log_active;
char log_path[MAX_SYSPATH];
FILE *logfile;
} WinConData;
static WinConData s_wcd;
void Con_ShowConsole( qboolean show )
void Wcon_ShowConsole( qboolean show )
{
if( !s_wcd.hWnd || show == s_wcd.status )
return;
@ -75,21 +74,21 @@ void Con_ShowConsole( qboolean show ) @@ -75,21 +74,21 @@ void Con_ShowConsole( qboolean show )
else ShowWindow( s_wcd.hWnd, SW_HIDE );
}
void Con_DisableInput( void )
void Wcon_DisableInput( void )
{
if( host.type != HOST_DEDICATED ) return;
SendMessage( s_wcd.hwndButtonSubmit, WM_ENABLE, 0, 0 );
SendMessage( s_wcd.hwndInputLine, WM_ENABLE, 0, 0 );
}
void Con_SetInputText( const char *inputText )
void Wcon_SetInputText( const char *inputText )
{
if( host.type != HOST_DEDICATED ) return;
SetWindowText( s_wcd.hwndInputLine, inputText );
SendMessage( s_wcd.hwndInputLine, EM_SETSEL, Q_strlen( inputText ), -1 );
}
static void Con_Clear_f( void )
static void Wcon_Clear_f( void )
{
if( host.type != HOST_DEDICATED ) return;
SendMessage( s_wcd.hwndBuffer, EM_SETSEL, 0, -1 );
@ -97,7 +96,7 @@ static void Con_Clear_f( void ) @@ -97,7 +96,7 @@ static void Con_Clear_f( void )
UpdateWindow( s_wcd.hwndBuffer );
}
static int Con_KeyEvent( int key, qboolean down )
static int Wcon_KeyEvent( int key, qboolean down )
{
char inputBuffer[1024];
@ -109,24 +108,24 @@ static int Con_KeyEvent( int key, qboolean down ) @@ -109,24 +108,24 @@ static int Con_KeyEvent( int key, qboolean down )
case VK_TAB:
GetWindowText( s_wcd.hwndInputLine, inputBuffer, sizeof( inputBuffer ));
Cmd_AutoComplete( inputBuffer );
Con_SetInputText( inputBuffer );
Wcon_SetInputText( inputBuffer );
return 1;
case VK_DOWN:
if( s_wcd.historyLine == s_wcd.nextHistoryLine )
return 0;
s_wcd.historyLine++;
Con_SetInputText( s_wcd.historyLines[s_wcd.historyLine % COMMAND_HISTORY] );
Wcon_SetInputText( s_wcd.historyLines[s_wcd.historyLine % COMMAND_HISTORY] );
return 1;
case VK_UP:
if( s_wcd.nextHistoryLine - s_wcd.historyLine < COMMAND_HISTORY && s_wcd.historyLine > 0 )
s_wcd.historyLine--;
Con_SetInputText( s_wcd.historyLines[s_wcd.historyLine % COMMAND_HISTORY] );
Wcon_SetInputText( s_wcd.historyLines[s_wcd.historyLine % COMMAND_HISTORY] );
return 1;
}
return 0;
}
static long _stdcall Con_WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
static long _stdcall Wcon_WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch( uMsg )
{
@ -172,7 +171,7 @@ static long _stdcall Con_WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lP @@ -172,7 +171,7 @@ static long _stdcall Con_WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lP
return DefWindowProc( hWnd, uMsg, wParam, lParam );
}
long _stdcall Con_InputLineProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
long _stdcall Wcon_InputLineProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
char inputBuffer[1024];
@ -187,16 +186,16 @@ long _stdcall Con_InputLineProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPa @@ -187,16 +186,16 @@ long _stdcall Con_InputLineProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPa
break;
case WM_SYSKEYDOWN:
case WM_KEYDOWN:
if( Con_KeyEvent( LOWORD( wParam ), true ))
if( Wcon_KeyEvent( LOWORD( wParam ), true ))
return 0;
break;
case WM_SYSKEYUP:
case WM_KEYUP:
if( Con_KeyEvent( LOWORD( wParam ), false ))
if( Wcon_KeyEvent( LOWORD( wParam ), false ))
return 0;
break;
case WM_CHAR:
if( Con_KeyEvent( wParam, true ))
if( Wcon_KeyEvent( wParam, true ))
return 0;
if( wParam == 13 && host.status != HOST_ERR_FATAL )
{
@ -232,7 +231,7 @@ Con_WinPrint @@ -232,7 +231,7 @@ Con_WinPrint
print into window console
================
*/
void Con_WinPrint( const char *pMsg )
void Wcon_WinPrint( const char *pMsg )
{
size_t len = Q_strlen( pMsg );
@ -259,7 +258,7 @@ Con_CreateConsole @@ -259,7 +258,7 @@ Con_CreateConsole
create win32 console
================
*/
void Con_CreateConsole( void )
void Wcon_CreateConsole( void )
{
HDC hDC;
WNDCLASS wc;
@ -345,7 +344,7 @@ void Con_CreateConsole( void ) @@ -345,7 +344,7 @@ void Con_CreateConsole( void )
s_wcd.hwndButtonSubmit = CreateWindow( "button", NULL, BS_PUSHBUTTON|WS_VISIBLE|WS_CHILD|BS_DEFPUSHBUTTON, 552, 367, 87, 25, s_wcd.hWnd, (HMENU)SUBMIT_ID, host.hInst, NULL );
SendMessage( s_wcd.hwndButtonSubmit, WM_SETTEXT, 0, ( LPARAM ) "submit" );
}
}
// create the scrollbuffer
GetClientRect( s_wcd.hWnd, &rect );
@ -355,7 +354,7 @@ void Con_CreateConsole( void ) @@ -355,7 +354,7 @@ void Con_CreateConsole( void )
if( host.type == HOST_DEDICATED )
{
s_wcd.SysInputLineWndProc = (WNDPROC)SetWindowLong( s_wcd.hwndInputLine, GWL_WNDPROC, (long)Con_InputLineProc );
s_wcd.SysInputLineWndProc = (WNDPROC)SetWindowLong( s_wcd.hwndInputLine, GWL_WNDPROC, (long)Wcon_InputLineProc );
SendMessage( s_wcd.hwndInputLine, WM_SETFONT, ( WPARAM )s_wcd.hfBufferFont, 0 );
}
@ -382,7 +381,7 @@ Con_InitConsoleCommands @@ -382,7 +381,7 @@ Con_InitConsoleCommands
register console commands (dedicated only)
================
*/
void Con_InitConsoleCommands( void )
void Wcon_InitConsoleCommands( void )
{
if( host.type != HOST_DEDICATED ) return;
Cmd_AddCommand( "clear", Con_Clear_f, "clear console history" );
@ -395,7 +394,7 @@ Con_DestroyConsole @@ -395,7 +394,7 @@ Con_DestroyConsole
destroy win32 console
================
*/
void Con_DestroyConsole( void )
void Wcon_DestroyConsole( void )
{
// last text message into console or log
MsgDev( D_NOTE, "Sys_FreeLibrary: Unloading xash.dll\n" );
@ -440,7 +439,7 @@ Con_Input @@ -440,7 +439,7 @@ Con_Input
returned input text
================
*/
char *Con_Input( void )
char *Wcon_Input( void )
{
if( s_wcd.consoleText[0] == 0 )
return NULL;
@ -458,7 +457,7 @@ Con_SetFocus @@ -458,7 +457,7 @@ Con_SetFocus
change focus to console hwnd
================
*/
void Con_RegisterHotkeys( void )
void Wcon_RegisterHotkeys( void )
{
SetFocus( s_wcd.hWnd );

Loading…
Cancel
Save