From 62f7ad7bb122f4168df4ca605e1db7aecdd72d12 Mon Sep 17 00:00:00 2001 From: g-cont Date: Sun, 13 Mar 2011 00:00:00 +0300 Subject: [PATCH] 13 Mar 2011 --- backup.lst | 1 - debug.bat | 3 - engine/client/cl_menu.c | 10 +- engine/client/gl_rmain.c | 2 +- engine/client/gl_vidnt.c | 4 +- engine/client/sound/sound.h | 2 - engine/common/cmd.c | 8 +- engine/common/com_export.h | 11 - engine/common/common.h | 143 +++- engine/common/con_utils.c | 6 +- engine/common/console.c | 2 +- engine/common/crtlib.c | 14 +- engine/common/crtlib.h | 11 + engine/common/cvar.c | 2 +- engine/common/engfuncs.c | 4 +- engine/common/filesystem.c | 38 +- engine/common/host.c | 220 +++-- engine/common/imagelib/img_utils.c | 1 + engine/common/mathlib.h | 1 + engine/common/net_encode.c | 6 +- launch/console.c => engine/common/sys_con.c | 182 +++-- engine/common/sys_win.c | 398 ++++++++- engine/common/system.h | 39 + engine/common/zone.c | 56 +- engine/engine.dsp | 20 +- engine/server/sv_game.c | 10 +- game_launch/game.cpp | 60 +- game_launch/game.dsp | 4 +- launch/launch.dsp | 139 ---- launch/launch.h | 152 ---- launch/launch_api.h | 215 ----- launch/stdlib.c | 121 --- launch/system.c | 851 -------------------- release.bat | 3 - xash.dsw | 12 - 35 files changed, 959 insertions(+), 1792 deletions(-) rename launch/console.c => engine/common/sys_con.c (62%) delete mode 100644 launch/launch.dsp delete mode 100644 launch/launch.h delete mode 100644 launch/launch_api.h delete mode 100644 launch/stdlib.c delete mode 100644 launch/system.c diff --git a/backup.lst b/backup.lst index ff715c92..a2f2e654 100644 --- a/backup.lst +++ b/backup.lst @@ -27,7 +27,6 @@ engine\server\ engine\common\ engine\common\imagelib\ engine\common\soundlib\ -launch\ pm_shared\ mainui\ mainui\legacy diff --git a/debug.bat b/debug.bat index 1833dba5..5ca44fca 100644 --- a/debug.bat +++ b/debug.bat @@ -20,9 +20,6 @@ if errorlevel 1 set BUILD_ERROR=1 %MSDEV% mainui/mainui.dsp %CONFIG%"mainui - Win32 Debug" %build_target% if errorlevel 1 set BUILD_ERROR=1 -%MSDEV% launch/launch.dsp %CONFIG%"launch - Win32 Debug" %build_target% -if errorlevel 1 set BUILD_ERROR=1 - %MSDEV% room/room.dsp %CONFIG%"room - Win32 Debug" %build_target% if errorlevel 1 set BUILD_ERROR=1 diff --git a/engine/client/cl_menu.c b/engine/client/cl_menu.c index 8cd5c607..3bbd8789 100644 --- a/engine/client/cl_menu.c +++ b/engine/client/cl_menu.c @@ -730,7 +730,7 @@ pfnGetGamesList */ static GAMEINFO **pfnGetGamesList( int *numGames ) { - if( numGames ) *numGames = SI->numgames; + if( numGames ) *numGames = SI.numgames; return menu.modsInfo; } @@ -812,7 +812,7 @@ static void pfnChangeInstance( const char *newInstance, const char *szFinalMessa if( !szFinalMessage ) szFinalMessage = ""; if( !newInstance || !*newInstance ) return; - Sys_NewInstance( newInstance, szFinalMessage ); + Host_NewInstance( newInstance, szFinalMessage ); } /* @@ -973,13 +973,13 @@ qboolean UI_LoadProgs( const char *name ) } // setup gameinfo - for( i = 0; i < SI->numgames; i++ ) + for( i = 0; i < SI.numgames; i++ ) { menu.modsInfo[i] = Mem_Alloc( menu.mempool, sizeof( GAMEINFO )); - UI_ConvertGameInfo( menu.modsInfo[i], SI->games[i] ); + UI_ConvertGameInfo( menu.modsInfo[i], SI.games[i] ); } - UI_ConvertGameInfo( &menu.gameInfo, SI->GameInfo ); // current gameinfo + UI_ConvertGameInfo( &menu.gameInfo, SI.GameInfo ); // current gameinfo // setup globals menu.globals->developer = host.developer; diff --git a/engine/client/gl_rmain.c b/engine/client/gl_rmain.c index 1bd3dd16..c560a69c 100644 --- a/engine/client/gl_rmain.c +++ b/engine/client/gl_rmain.c @@ -1002,7 +1002,7 @@ void R_EndFrame( void ) GL_CheckForErrors (); if( !pwglSwapBuffers( glw_state.hDC )) - Sys_Break( "wglSwapBuffers() failed!\n" ); + Sys_Error( "wglSwapBuffers() failed!\n" ); } /* diff --git a/engine/client/gl_vidnt.c b/engine/client/gl_vidnt.c index 7a2e9246..16172e81 100644 --- a/engine/client/gl_vidnt.c +++ b/engine/client/gl_vidnt.c @@ -1222,7 +1222,7 @@ void VID_CheckChanges( void ) if( !VID_SetMode()) { // can't initialize video subsystem - Sys_NewInstance( va("#%s", GI->gamefolder ), "fallback to dedicated mode\n" ); + Host_NewInstance( va("#%s", GI->gamefolder ), "fallback to dedicated mode\n" ); } else { @@ -1614,7 +1614,7 @@ qboolean R_Init( void ) R_Free_OpenGL(); // can't initialize video subsystem - Sys_NewInstance( va("#%s", GI->gamefolder ), "fallback to dedicated mode\n" ); + Host_NewInstance( va("#%s", GI->gamefolder ), "fallback to dedicated mode\n" ); return false; } diff --git a/engine/client/sound/sound.h b/engine/client/sound/sound.h index 3693fc04..915d98a8 100644 --- a/engine/client/sound/sound.h +++ b/engine/client/sound/sound.h @@ -165,8 +165,6 @@ typedef struct ==================================================================== */ -#define Host_Error com.error - // initializes cycling through a DMA buffer and returns information on it qboolean SNDDMA_Init( void *hInst ); int SNDDMA_GetSoundtime( void ); diff --git a/engine/common/cmd.c b/engine/common/cmd.c index 5f5a16ea..c1fd355b 100644 --- a/engine/common/cmd.c +++ b/engine/common/cmd.c @@ -150,7 +150,7 @@ void Cbuf_Execute( void ) } if( i >= MAX_CMD_LINE - 1 ) - com.error( "Cbuf_Execute: command string owerflow\n" ); + Sys_Error( "Cbuf_Execute: command string owerflow\n" ); Q_memcpy( line, text, i ); line[i] = 0; @@ -171,7 +171,7 @@ void Cbuf_Execute( void ) } // execute the command line - Cmd_ExecuteString( line ); + Cmd_ExecuteString( line ); } } /* @@ -222,7 +222,7 @@ void Cmd_StuffCmds_f( void ) if( !host.argv[i] ) continue; if(( host.argv[i][0] == '+' || host.argv[i][0] == '-' ) && ( host.argv[i][1] < '0' || host.argv[i][1] > '9' )) break; - if( l + Q_strlen( host.argv[i]) + 4 > sizeof( build ) - 1 ) + if( l + Q_strlen( host.argv[i] ) + 4 > sizeof( build ) - 1 ) break; build[l++] = ' '; @@ -668,5 +668,5 @@ void Cmd_Init( void ) Cmd_AddCommand ("echo", Cmd_Echo_f, "print a message to the console (useful in scripts)" ); Cmd_AddCommand ("wait", Cmd_Wait_f, "make script execution wait for some rendered frames" ); Cmd_AddCommand ("cmdlist", Cmd_List_f, "display all console commands beginning with the specified prefix" ); - Cmd_AddCommand ("stuffcmds", Cmd_StuffCmds_f, va( "execute commandline parameters (must be present in %s.rc script)", SI->ModuleName )); + Cmd_AddCommand ("stuffcmds", Cmd_StuffCmds_f, va( "execute commandline parameters (must be present in %s.rc script)", SI.ModuleName )); } \ No newline at end of file diff --git a/engine/common/com_export.h b/engine/common/com_export.h index 202e808d..c1d16b5b 100644 --- a/engine/common/com_export.h +++ b/engine/common/com_export.h @@ -5,17 +5,6 @@ #ifndef COM_EXPORT_H #define COM_EXPORT_H -#ifdef __cplusplus -extern "C" { -#endif - -// linked interfaces -extern stdlib_api_t com; - -#ifdef __cplusplus -} -#endif - // MD5 Hash typedef struct { diff --git a/engine/common/common.h b/engine/common/common.h index 2365c49a..75b56321 100644 --- a/engine/common/common.h +++ b/engine/common/common.h @@ -5,8 +5,61 @@ #ifndef COMMON_H #define COMMON_H +#ifdef __cplusplus +extern "C" { +#endif + +// disable some warnings +#pragma warning(disable : 4244) // MIPS +#pragma warning(disable : 4018) // signed/unsigned mismatch +#pragma warning(disable : 4305) // truncation from const double to float + +#define MAX_STRING 256 // generic string +#define MAX_INFO_STRING 256 // infostrings are transmitted across network +#define MAX_SYSPATH 1024 // system filepath +#define MAX_MODS 512 // environment games that engine can keep visible +#define EXPORT __declspec( dllexport ) +#define BIT( n ) (1<<( n )) + +#ifndef __cplusplus +#define NULL ((void *)0) +#endif + +// color strings +#define IsColorString( p ) ( p && *( p ) == '^' && *(( p ) + 1) && *(( p ) + 1) >= '0' && *(( p ) + 1 ) <= '9' ) + +typedef unsigned long dword; +typedef unsigned int uint; +typedef char string[MAX_STRING]; +typedef long fs_offset_t; +typedef struct file_s file_t; // normal file +typedef struct wfile_s wfile_t; // wad file +typedef struct stream_s stream_t; // sound stream for background music playing + +typedef struct +{ + int numfilenames; + char **filenames; + char *filenamesbuffer; +} search_t; + +enum +{ + D_INFO = 1, // "-dev 1", shows various system messages + D_WARN, // "-dev 2", shows not critical system warnings + D_ERROR, // "-dev 3", shows critical warnings + D_AICONSOLE, // "-dev 4", special case for game aiconsole + D_NOTE // "-dev 5", show system notifications for engine developers +}; + +typedef enum +{ + HOST_NORMAL, // listen server, singleplayer + HOST_DEDICATED, + HOST_CREDITS // easter egg +} instance_t; + #include "system.h" -#include "launch_api.h" #include "ref_params.h" #include "com_export.h" #include "com_model.h" @@ -29,6 +82,8 @@ #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. @@ -44,6 +99,10 @@ #define FS_NOWRITE_PATH 2 // default behavior - last added gamedir set as writedir. This flag disables it #define FS_GAMEDIR_PATH 4 // just a marker for gamedir path +#define GI SI.GameInfo +#define FS_Gamedir() SI.GameInfo->gamedir +#define FS_Title() SI.GameInfo->title + #ifdef _DEBUG void DBG_AssertFunction( qboolean fExpr, const char* szExpr, const char* szFile, int szLine, const char* szMessage ); #define Assert( f ) DBG_AssertFunction( f, #f, __FILE__, __LINE__, NULL ) @@ -69,12 +128,65 @@ HOST INTERFACE */ #define MAX_SYSEVENTS 1024 +/* +======================================================================== + +GAMEINFO stuff + +internal shared gameinfo structure (readonly for engine parts) +======================================================================== +*/ +typedef struct gameinfo_s +{ + // filesystem info + char gamefolder[64]; // used for change game '-game x' + char basedir[64]; // main game directory (like 'id1' for Quake or 'valve' for Half-Life) + char gamedir[64]; // game directory (can be match with basedir, used as primary dir and as write path + char startmap[64]; // map to start singleplayer game + char trainmap[64]; // map to start hazard course (if specified) + char title[64]; // Game Main Title + float version; // game version (optional) + + // .dll pathes + char dll_path[64]; // e.g. "bin" or "cl_dlls" + char game_dll[64]; // custom path for game.dll + + // about mod info + string game_url; // link to a developer's site + string update_url; // link to updates page + char type[64]; // single, toolkit, multiplayer etc + char date[64]; + size_t size; + + int gamemode; + + char sp_entity[32]; // e.g. info_player_start + char mp_entity[32]; // e.g. info_player_deathmatch + + float client_mins[4][3]; // 4 hulls allowed + float client_maxs[4][3]; // 4 hulls allowed + + int max_edicts; // min edicts is 600, max edicts is 4096 + int max_tents; // min temp ents is 300, max is 2048 + int max_beams; // min beams is 64, max beams is 512 + int max_particles; // min particles is 512, max particles is 8192 +} gameinfo_t; + +typedef struct sysinfo_s +{ + string ModuleName; // exe.filename + gameinfo_t *GameInfo; // current GameInfo + gameinfo_t *games[MAX_MODS]; // environment games (founded at each engine start) + int numgames; +} sysinfo_t; + typedef enum { HOST_INIT = 0, // initalize operations HOST_FRAME, // host running HOST_SHUTDOWN, // shutdown operations HOST_ERROR, // host stopped by error + HOST_ERR_FATAL, // sys error HOST_SLEEP, // sleeped by different reason, e.g. minimize window HOST_NOFOCUS, // same as HOST_FRAME, but disable mouse HOST_RESTART, // during the changes video mode @@ -116,7 +228,10 @@ typedef struct host_redirect_s typedef struct host_parm_s { - HINSTANCE hInst; + HINSTANCE hInst; + HANDLE hMutex; + LPTOP_LEVEL_EXCEPTION_FILTER oldFilter; + host_state state; // global host state uint type; // running at jmp_buf abortframe; // abort current frame @@ -127,7 +242,7 @@ typedef struct host_parm_s // command line parms int argc; - const char **argv; + const char *argv[MAX_NUM_ARGVS]; double realtime; // host.curtime double frametime; // time between engine frames @@ -146,7 +261,10 @@ typedef struct host_parm_s int developer; // show all developer's message qboolean key_overstrike; // key overstrike mode qboolean stuffcmdsrun; // execute stuff commands - + qboolean con_showalways; // show console always (developer and dedicated) + qboolean change_game; // initialize when game is changed + qboolean shutdown_issued; // engine is shutting down + byte *imagepool; // imagelib mempool byte *soundpool; // soundlib mempool @@ -161,15 +279,8 @@ typedef struct host_parm_s int numsounds; } host_parm_t; -#ifdef __cplusplus -extern "C" { -#endif - extern host_parm_t host; - -#ifdef __cplusplus -} -#endif +extern sysinfo_t SI; // // filesystem.c @@ -392,12 +503,11 @@ int com_buildnum( void ); // // host.c // -void Host_Init( const int argc, const char **argv ); -void Host_Main( void ); -void Host_Free( void ); +void EXPORT Host_Shutdown( void ); void Host_SetServerState( int state ); int Host_ServerState( void ); int Host_CompareFileTime( long ft1, long ft2 ); +void Host_NewInstance( const char *name, const char *finalmsg ); qboolean Host_NewGame( const char *mapName, qboolean loadGame ); void Host_EndGame( const char *message, ... ); void Host_AbortCurrentFrame( void ); @@ -610,4 +720,7 @@ void S_StopSound( int entnum, int channel, const char *soundname ); int S_GetCurrentStaticSounds( soundlist_t *pout, int size ); void S_StopAllSounds( void ); +#ifdef __cplusplus +} +#endif #endif//COMMON_H \ No newline at end of file diff --git a/engine/common/con_utils.c b/engine/common/con_utils.c index 3b2a9641..acb6e4ed 100644 --- a/engine/common/con_utils.c +++ b/engine/common/con_utils.c @@ -590,10 +590,10 @@ qboolean Cmd_GetGamesList( const char *s, char *completedname, int length ) string matchbuf; // compare gamelist with current keyword - for( i = 0, numgamedirs = 0; i < SI->numgames; i++ ) + for( i = 0, numgamedirs = 0; i < SI.numgames; i++ ) { - if(( *s == '*' ) || !Q_strnicmp( SI->games[i]->gamefolder, s, Q_strlen( s ))) - Q_strcpy( gamedirs[numgamedirs++], SI->games[i]->gamefolder ); + if(( *s == '*' ) || !Q_strnicmp( SI.games[i]->gamefolder, s, Q_strlen( s ))) + Q_strcpy( gamedirs[numgamedirs++], SI.games[i]->gamefolder ); } if( !numgamedirs ) return false; diff --git a/engine/common/console.c b/engine/common/console.c index b343b190..f43b31f3 100644 --- a/engine/common/console.c +++ b/engine/common/console.c @@ -17,7 +17,7 @@ convar_t *con_fontsize; #define CON_TIMES 5 // need for 4 lines #define COLOR_DEFAULT '7' -#define CON_HISTORY 32 +#define CON_HISTORY 64 #define MAX_DBG_NOTIFY 128 #define ColorIndex( c ) ((( c ) - '0' ) & 7 ) diff --git a/engine/common/crtlib.c b/engine/common/crtlib.c index 21ace8c5..9ca9dc6b 100644 --- a/engine/common/crtlib.c +++ b/engine/common/crtlib.c @@ -648,14 +648,14 @@ char *va( const char *format, ... ) void crt_memcpy( void *dest, const void *src, size_t count, const char *filename, int fileline ) { if( src == NULL || count <= 0 ) return; // nothing to copy - if( dest == NULL ) com.error( "memcpy: dest == NULL (called at %s:%i)\n", filename, fileline ); + if( dest == NULL ) Sys_Error( "memcpy: dest == NULL (called at %s:%i)\n", filename, fileline ); memcpy( dest, src, count ); } void mmx_memcpy8B( void *dest, const void *src, size_t count, const char *filename, int fileline ) { if( src == NULL || count <= 0 ) return; // nothing to copy - if( dest == NULL ) com.error( "memcpy: dest == NULL (called at %s:%i)\n", filename, fileline ); + if( dest == NULL ) Sys_Error( "memcpy: dest == NULL (called at %s:%i)\n", filename, fileline ); _asm { @@ -678,7 +678,7 @@ loop1: void mmx_memcpy64B( void *dest, const void *src, size_t count, const char *filename, int fileline ) { if( src == NULL || count <= 0 ) return; // nothing to copy - if( dest == NULL ) com.error( "memcpy: dest == NULL (called at %s:%i)\n", filename, fileline ); + if( dest == NULL ) Sys_Error( "memcpy: dest == NULL (called at %s:%i)\n", filename, fileline ); _asm { @@ -722,7 +722,7 @@ void mmx_memcpy2kB( void *dest, const void *src, size_t count, const char *filen byte *tbuf = &buf[0]; if( src == NULL || count <= 0 ) return; // nothing to copy - if( dest == NULL ) com.error( "memcpy: dest == NULL (called at %s:%i)\n", filename, fileline ); + if( dest == NULL ) Sys_Error( "memcpy: dest == NULL (called at %s:%i)\n", filename, fileline ); __asm { @@ -800,7 +800,7 @@ loopL1ToMem: void mmx_memcpy( void *dest, const void *src, size_t size, const char *filename, int fileline ) { if( src == NULL || size <= 0 ) return; // nothing to copy - if( dest == NULL ) com.error( "memcpy: dest == NULL (called at %s:%i)\n", filename, fileline ); + if( dest == NULL ) Sys_Error( "memcpy: dest == NULL (called at %s:%i)\n", filename, fileline ); // if copying more than 16 bytes and we can copy 8 byte aligned if( size > 16 && !(((int)dest ^ (int)src) & 7 )) @@ -852,7 +852,7 @@ void mmx_memcpy( void *dest, const void *src, size_t size, const char *filename, void crt_memset( void *dest, int set, size_t count, const char *filename, int fileline ) { - if( dest == NULL ) com.error( "memset: dest == NULL (called at %s:%i)\n", filename, fileline ); + if( dest == NULL ) Sys_Error( "memset: dest == NULL (called at %s:%i)\n", filename, fileline ); memset( dest, set, count ); } @@ -868,7 +868,7 @@ void mmx_memset( void *dest, int set, size_t size, const char *filename, int fil byte *dst = (byte *)dest; int count = size; - if( dest == NULL ) com.error( "memset: dest == NULL (called at %s:%i)\n", filename, fileline ); + if( dest == NULL ) Sys_Error( "memset: dest == NULL (called at %s:%i)\n", filename, fileline ); while( count > 0 && (((int)dst) & 7) ) { diff --git a/engine/common/crtlib.h b/engine/common/crtlib.h index cc07f488..cc028384 100644 --- a/engine/common/crtlib.h +++ b/engine/common/crtlib.h @@ -13,6 +13,17 @@ enum EXEC_APPEND, }; +// timestamp modes +enum +{ + TIME_FULL = 0, + TIME_DATE_ONLY, + TIME_TIME_ONLY, + TIME_NO_SECONDS, + TIME_YEAR_ONLY, + TIME_FILENAME, +}; + typedef void (*setpair_t)( const char *key, const char *value, void *buffer, void *numpairs ); typedef void (*xcommand_t)( void ); diff --git a/engine/common/cvar.c b/engine/common/cvar.c index 91b0889b..5c66d823 100644 --- a/engine/common/cvar.c +++ b/engine/common/cvar.c @@ -125,7 +125,7 @@ convar_t *Cvar_Get( const char *var_name, const char *var_value, int flags, cons if( !var_name ) { - com.error( "Cvar_Get: passed NULL name\n" ); + Sys_Error( "Cvar_Get: passed NULL name\n" ); return NULL; } diff --git a/engine/common/engfuncs.c b/engine/common/engfuncs.c index 81602f77..cb421277 100644 --- a/engine/common/engfuncs.c +++ b/engine/common/engfuncs.c @@ -427,7 +427,7 @@ void Con_Printf( char *szFmt, ... ) Q_vsnprintf( buffer, 2048, szFmt, args ); va_end( args ); - com.print( buffer ); + Sys_Print( buffer ); } /* @@ -448,7 +448,7 @@ void Con_DPrintf( char *szFmt, ... ) Q_vsnprintf( buffer, 2048, szFmt, args ); va_end( args ); - com.print( buffer ); + Sys_Print( buffer ); } /* diff --git a/engine/common/filesystem.c b/engine/common/filesystem.c index 9fcf24ac..d4d73184 100644 --- a/engine/common/filesystem.c +++ b/engine/common/filesystem.c @@ -1039,7 +1039,7 @@ void FS_CreateDefaultGameInfo( const char *filename ) Q_strncpy( defGI.title, "New Game", sizeof( defGI.title )); Q_strncpy( defGI.gamedir, gs_basedir, sizeof( defGI.gamedir )); - Q_strncpy( defGI.basedir, SI->ModuleName, sizeof( defGI.basedir )); + Q_strncpy( defGI.basedir, SI.ModuleName, sizeof( defGI.basedir )); Q_strncpy( defGI.sp_entity, "info_player_start", sizeof( defGI.sp_entity )); Q_strncpy( defGI.mp_entity, "info_player_deathmatch", sizeof( defGI.mp_entity )); Q_strncpy( defGI.dll_path, "cl_dlls", sizeof( defGI.dll_path )); @@ -1077,7 +1077,7 @@ static qboolean FS_ParseLiblistGam( const char *filename, const char *gamedir, g Q_strncpy( GameInfo->title, "New Game", sizeof( GameInfo->title )); Q_strncpy( GameInfo->gamedir, gamedir, sizeof( GameInfo->gamedir )); - Q_strncpy( GameInfo->basedir, SI->ModuleName, sizeof( GameInfo->basedir )); + Q_strncpy( GameInfo->basedir, SI.ModuleName, sizeof( GameInfo->basedir )); Q_strncpy( GameInfo->sp_entity, "info_player_start", sizeof( GameInfo->sp_entity )); Q_strncpy( GameInfo->mp_entity, "info_player_deathmatch", sizeof( GameInfo->mp_entity )); Q_strncpy( GameInfo->game_dll, "dlls/hl.dll", sizeof( GameInfo->game_dll )); @@ -1378,16 +1378,16 @@ void FS_LoadGameInfo( const char *rootfolder ) FS_ClearSearchPath(); // validate gamedir - for( i = 0; i < SI->numgames; i++ ) + for( i = 0; i < SI.numgames; i++ ) { - if( !Q_stricmp( SI->games[i]->gamefolder, gs_basedir )) + if( !Q_stricmp( SI.games[i]->gamefolder, gs_basedir )) break; } - if( i == SI->numgames ) - Sys_Break( "Couldn't find game directory '%s'\n", gs_basedir ); + if( i == SI.numgames ) + Sys_Error( "Couldn't find game directory '%s'\n", gs_basedir ); - SI->GameInfo = SI->games[i]; + SI.GameInfo = SI.games[i]; FS_Rescan(); // create new filesystem } @@ -1416,21 +1416,21 @@ void FS_Init( void ) stringlistinit( &dirs ); listdirectory( &dirs, "./" ); stringlistsort( &dirs ); - SI->numgames = 0; + SI.numgames = 0; if( !Sys_GetParmFromCmdLine( "-game", gs_basedir )) - Q_strcpy( gs_basedir, SI->ModuleName ); // default dir + Q_strcpy( gs_basedir, SI.ModuleName ); // default dir if( FS_CheckNastyPath( gs_basedir, true )) { MsgDev( D_ERROR, "FS_Init: invalid game directory \"%s\"\n", gs_basedir ); - Q_strcpy( gs_basedir, SI->ModuleName ); // default dir + Q_strcpy( gs_basedir, SI.ModuleName ); // default dir } // validate directories for( i = 0; i < dirs.numstrings; i++ ) { - if( !Q_stricmp( SI->ModuleName, dirs.strings[i] )) + if( !Q_stricmp( SI.ModuleName, dirs.strings[i] )) hasDefaultDir = true; if( !Q_stricmp( gs_basedir, dirs.strings[i] )) @@ -1440,7 +1440,7 @@ void FS_Init( void ) if( i == dirs.numstrings ) { MsgDev( D_INFO, "FS_Init: game directory \"%s\" not exist\n", gs_basedir ); - if( hasDefaultDir ) Q_strncpy( gs_basedir, SI->ModuleName, sizeof( gs_basedir )); // default dir + if( hasDefaultDir ) Q_strncpy( gs_basedir, SI.ModuleName, sizeof( gs_basedir )); // default dir } // build list of game directories here @@ -1452,10 +1452,10 @@ void FS_Init( void ) if( Q_stricmp( ext, "" ) || (!Q_stricmp( dirs.strings[i], ".." ) && !fs_ext_path )) continue; - if( !SI->games[SI->numgames] ) - SI->games[SI->numgames] = (gameinfo_t *)Mem_Alloc( fs_mempool, sizeof( gameinfo_t )); - if( FS_ParseGameInfo( dirs.strings[i], SI->games[SI->numgames] )) - SI->numgames++; // added + if( !SI.games[SI.numgames] ) + SI.games[SI.numgames] = (gameinfo_t *)Mem_Alloc( fs_mempool, sizeof( gameinfo_t )); + if( FS_ParseGameInfo( dirs.strings[i], SI.games[SI.numgames] )) + SI.numgames++; // added } stringlistfreecontents( &dirs ); } @@ -1477,10 +1477,10 @@ void FS_Shutdown( void ) int i; // release gamedirs - for( i = 0; i < SI->numgames; i++ ) - if( SI->games[i] ) Mem_Free( SI->games[i] ); + for( i = 0; i < SI.numgames; i++ ) + if( SI.games[i] ) Mem_Free( SI.games[i] ); - Q_memset( SI, 0, sizeof( sysinfo_t )); + Q_memset( &SI, 0, sizeof( sysinfo_t )); FS_ClearSearchPath(); // release all wad files too Mem_FreePool( &fs_mempool ); diff --git a/engine/common/host.c b/engine/common/host.c index aae93754..5484bffb 100644 --- a/engine/common/host.c +++ b/engine/common/host.c @@ -7,10 +7,18 @@ #include "netchan.h" #include "protocol.h" #include "cm_local.h" +#include "mathlib.h" #include "input.h" +static const char *show_credits = "\n\n\n\n\tCopyright XashXT Group %s ©\n\t\ + All Rights Reserved\n\n\t Visit www.xash.ru\n"; + +typedef void (*pfnChangeGame)( const char *progname ); + +pfnChangeGame pChangeGame = NULL; +HINSTANCE hCurrent; // hinstance of current .dll host_parm_t host; // host parms -stdlib_api_t com; +sysinfo_t SI; convar_t *host_serverstate; convar_t *host_gameloaded; @@ -20,6 +28,8 @@ convar_t *host_maxfps; convar_t *host_framerate; convar_t *con_gamemaps; +static int num_decals; + // these cvars will be duplicated on each client across network int Host_ServerState( void ) { @@ -46,11 +56,6 @@ void Host_ShutdownServer( void ) SV_Shutdown( false ); } -void Host_Null( void ) -{ - // just a stub for some commands in dedicated-mode -} - /* ================ Host_NewGame @@ -117,6 +122,15 @@ void Host_SetServerState( int state ) Cvar_FullSet( "host_serverstate", va( "%i", state ), CVAR_INIT ); } +void Host_NewInstance( const char *name, const char *finalmsg ) +{ + if( !pChangeGame ) return; + + host.change_game = true; + Q_strncpy( host.finalmsg, finalmsg, sizeof( host.finalmsg )); + pChangeGame( name ); +} + /* ================= Host_ChangeGame_f @@ -135,16 +149,24 @@ void Host_ChangeGame_f( void ) } // validate gamedir - for( i = 0; i < SI->numgames; i++ ) + for( i = 0; i < SI.numgames; i++ ) { - if( !Q_stricmp( SI->games[i]->gamefolder, Cmd_Argv( 1 ))) + if( !Q_stricmp( SI.games[i]->gamefolder, Cmd_Argv( 1 ))) break; } - if( i == SI->numgames ) Msg( "%s not exist\n", Cmd_Argv( 1 )); + if( i == SI.numgames ) + { + Msg( "%s not exist\n", Cmd_Argv( 1 )); + } else if( !Q_stricmp( GI->gamefolder, Cmd_Argv( 1 ))) + { Msg( "%s already active\n", Cmd_Argv( 1 )); - else Sys_NewInstance( Cmd_Argv( 1 ), va( "Host_ChangeGame: %s\n", SI->games[i]->title )); + } + else + { + Host_NewInstance( Cmd_Argv( 1 ), va( "change game to '%s'", SI.games[i]->title )); + } } /* @@ -214,8 +236,6 @@ qboolean Host_IsLocalGame( void ) return false; } -static int num_decals; - /* ================= Host_RegisterDecal @@ -492,12 +512,12 @@ void Host_Error( const char *error, ... ) if( host.framecount < 3 ) { SV_SysError( hosterror1 ); - com.error( "Host_InitError: %s", hosterror1 ); + Sys_Error( "Host_InitError: %s", hosterror1 ); } else if( host.framecount == host.errorframe ) { SV_SysError( hosterror2 ); - com.error( "Host_MultiError: %s", hosterror2 ); + Sys_Error( "Host_MultiError: %s", hosterror2 ); return; } else @@ -512,7 +532,7 @@ void Host_Error( const char *error, ... ) if( recursive ) { Msg( "Host_RecursiveError: %s", hosterror2 ); - com.error( hosterror1 ); + Sys_Error( hosterror1 ); return; // don't multiple executes } @@ -543,7 +563,7 @@ void Sys_Error_f( void ) if( !*error ) error = "Invoked sys error"; SV_SysError( error ); - com.error( "%s\n", error ); + Sys_Error( "%s\n", error ); } void Net_Error_f( void ) @@ -562,19 +582,99 @@ static void Host_Crash_f( void ) *(int *)0 = 0xffffffff; } -void Host_InitCommon( const int argc, const char **argv ) +void Host_InitCommon( const char *progname, qboolean bChangeGame ) { - char dev_level[4]; + MEMORYSTATUS lpBuffer; + char dev_level[4]; + char szTemp[MAX_SYSPATH]; - // get developer mode - host.developer = SI->developer; - host.argc = argc; - host.argv = argv; + lpBuffer.dwLength = sizeof( MEMORYSTATUS ); + GlobalMemoryStatus( &lpBuffer ); - // get current hInstance + host.oldFilter = SetUnhandledExceptionFilter( Sys_Crash ); host.hInst = GetModuleHandle( NULL ); + host.change_game = bChangeGame; + host.state = HOST_INIT; // initialzation started + host.developer = 0; + + CRT_Init(); // init some CRT functions + + // some commands may turn engine into infinity loop, + // e.g. xash.exe +game xash -game xash + // so we clearing all cmd_args, but leave dbg states as well + Sys_ParseCommandLine( GetCommandLine( )); + SetErrorMode( SEM_FAILCRITICALERRORS ); // no abort/retry/fail errors + host.mempool = Mem_AllocPool( "Zone Engine" ); + if( Sys_CheckParm( "-console" )) host.developer = 1; + if( Sys_CheckParm( "-dev" )) + { + if( Sys_GetParmFromCmdLine( "-dev", dev_level )) + { + if( Q_isdigit( dev_level )) + host.developer = abs( Q_atoi( dev_level )); + else host.developer++; // -dev == 1, -dev -console == 2 + } + else host.developer++; // -dev == 1, -dev -console == 2 + } + + host.type = HOST_NORMAL; // predict state + host.con_showalways = true; + + // we can specified custom name, from Sys_NewInstance + if( GetModuleFileName( NULL, szTemp, sizeof( szTemp )) && !host.change_game ) + FS_FileBase( szTemp, SI.ModuleName ); + + if( SI.ModuleName[0] == '#' ) host.type = HOST_DEDICATED; + + // determine host type + if( progname[0] == '#' ) + { + Q_strncpy( SI.ModuleName, progname + 1, sizeof( SI.ModuleName )); + host.type = HOST_DEDICATED; + } + else Q_strncpy( SI.ModuleName, progname, sizeof( SI.ModuleName )); + + if( host.type == HOST_DEDICATED ) + { + // check for duplicate dedicated server + host.hMutex = CreateMutex( NULL, 0, "Xash Dedicated Server" ); + if( !host.hMutex ) + { + MSGBOX( "Dedicated server already running" ); + Sys_Quit(); + return; + } + + CloseHandle( host.hMutex ); + host.hMutex = CreateSemaphore( NULL, 0, 1, "Xash Dedicated Server" ); + if( host.developer < 3 ) host.developer = 3; // otherwise we see empty console + host.change_game = false; + } + else + { + // don't show console as default + if( host.developer < D_WARN ) host.con_showalways = false; + } + + if( GetModuleFileName( hCurrent, szTemp, sizeof( szTemp ))) + FS_FileBase( szTemp, szTemp ); + + if( Q_stricmp( szTemp, "xash" )) + { + host.type = HOST_CREDITS; + host.con_showalways = true; + Con_CreateConsole(); + Sys_Break( show_credits, szTemp ); + } + + Con_CreateConsole(); + + // first text message into console or log + MsgDev( D_NOTE, "Sys_LoadLibrary: Loading xash.dll - ok\n" ); + Sys_MergeCommandLine( GetCommandLine( )); + // startup cmds and cvars subsystem Cmd_Init(); Cvar_Init(); @@ -584,6 +684,7 @@ void Host_InitCommon( const int argc, const char **argv ) Cvar_Get( "developer", dev_level, CVAR_INIT, "current developer level" ); Cmd_AddCommand( "exec", Host_Exec_f, "execute a script file" ); Cmd_AddCommand( "memlist", Host_MemStats_f, "prints memory pool information" ); + FS_Init(); Image_Init(); Sound_Init(); @@ -595,6 +696,7 @@ void Host_InitCommon( const int argc, const char **argv ) Host_InitDecals(); IN_Init(); + Key_Init(); } void Host_FreeCommon( void ) @@ -609,18 +711,16 @@ void Host_FreeCommon( void ) /* ================= -Host_Init +Host_Main ================= */ -void Host_Init( const int argc, const char **argv ) +int EXPORT Host_Main( const char *progname, int bChangeGame, pfnChangeGame func ) { - host.state = HOST_INIT; // initialzation started - host.type = g_Instance(); + static double oldtime, newtime; - CRT_Init(); // init some CRT functions + pChangeGame = func; - Host_InitCommon( argc, argv ); - Key_Init(); + Host_InitCommon( progname, bChangeGame ); // init commands and vars if( host.developer >= 3 ) @@ -663,7 +763,6 @@ void Host_Init( const int argc, const char **argv ) { Cmd_AddCommand( "quit", Sys_Quit, "quit the game" ); Cmd_AddCommand( "exit", Sys_Quit, "quit the game" ); - Cmd_AddCommand( "@crashed", Host_Null, "" ); // dedicated servers using settings from server.cfg file Cbuf_AddText( va( "exec %s\n", Cvar_VariableString( "servercfgfile" ))); @@ -678,7 +777,7 @@ void Host_Init( const int argc, const char **argv ) } // allow to change game from the console - Cmd_AddCommand( "game", Host_ChangeGame_f, "change game" ); + if( pChangeGame != NULL ) Cmd_AddCommand( "game", Host_ChangeGame_f, "change game" ); host.errorframe = 0; Cbuf_Execute(); @@ -689,8 +788,9 @@ void Host_Init( const int argc, const char **argv ) switch( host.type ) { case HOST_NORMAL: + Con_ShowConsole( false ); // hide console // execute startup config and cmdline - Cbuf_AddText( va( "exec %s.rc\n", SI->ModuleName )); + Cbuf_AddText( va( "exec %s.rc\n", SI.ModuleName )); case HOST_DEDICATED: Cbuf_Execute(); // if stuffcmds wasn't run, then init.rc is probably missing, use default @@ -698,30 +798,24 @@ void Host_Init( const int argc, const char **argv ) break; } + host.change_game = false; // done Cmd_RemoveCommand( "setr" ); // remove potentially backdoor for change render settings Cmd_RemoveCommand( "setgl" ); -} - -/* -================= -Host_Main -================= -*/ -void Host_Main( void ) -{ - static double oldtime, newtime; // we need to execute it again here Cmd_ExecuteString( "exec config.cfg\n" ); oldtime = Sys_DoubleTime(); // main window message loop - while( host.type != HOST_OFFLINE ) + while( 1 ) { newtime = Sys_DoubleTime (); Host_Frame( newtime - oldtime ); oldtime = newtime; } + + // never reached + return 0; } /* @@ -729,13 +823,13 @@ void Host_Main( void ) Host_Shutdown ================= */ -void Host_Free( void ) +void EXPORT Host_Shutdown( void ) { - if( host.state == HOST_SHUTDOWN ) - return; + if( host.shutdown_issued ) return; + host.shutdown_issued = true; - host.state = HOST_SHUTDOWN; // prepare host to normal shutdown - Q_strncpy( host.finalmsg, "Server shutdown\n", MAX_STRING ); + if( host.state != HOST_ERR_FATAL ) host.state = HOST_SHUTDOWN; // prepare host to normal shutdown + if( !host.change_game ) Q_strncpy( host.finalmsg, "Server shutdown\n", sizeof( host.finalmsg )); SV_Shutdown( false ); CL_Shutdown(); @@ -745,33 +839,15 @@ void Host_Free( void ) R_Shutdown(); NET_Shutdown(); Host_FreeCommon(); + Con_DestroyConsole(); + + // restore filter + if( host.oldFilter ) SetUnhandledExceptionFilter( host.oldFilter ); } // main DLL entry point BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved ) { + hCurrent = hinstDLL; return TRUE; -} - -/* -================= -Engine entry point -================= -*/ -launch_exp_t EXPORT *CreateAPI( stdlib_api_t *input, void *unused ) -{ - static launch_exp_t Host; - - com = *input; - Host.api_size = sizeof( launch_exp_t ); - Host.com_size = sizeof( stdlib_api_t ); - - Host.Init = Host_Init; - Host.Main = Host_Main; - Host.Free = Host_Free; - Host.CPrint = Host_Print; - Host.Crashed = CL_Crashed; - Host.CmdComplete = Cmd_AutoComplete; - - return &Host; } \ No newline at end of file diff --git a/engine/common/imagelib/img_utils.c b/engine/common/imagelib/img_utils.c index 7a2d5987..67cb6a8f 100644 --- a/engine/common/imagelib/img_utils.c +++ b/engine/common/imagelib/img_utils.c @@ -4,6 +4,7 @@ //======================================================================= #include "imagelib.h" +#include "mathlib.h" convar_t *gl_round_down; diff --git a/engine/common/mathlib.h b/engine/common/mathlib.h index cfdb790c..0fd87dfa 100644 --- a/engine/common/mathlib.h +++ b/engine/common/mathlib.h @@ -84,6 +84,7 @@ #define PlaneDist(point,plane) ((plane)->type < 3 ? (point)[(plane)->type] : DotProduct((point), (plane)->normal)) #define PlaneDiff(point,plane) (((plane)->type < 3 ? (point)[(plane)->type] : DotProduct((point), (plane)->normal)) - (plane)->dist) #define PlaneDiff2(point, plane) ((((plane)->type < 3) ? (point)[(plane)->type] - (plane)->dist : DotProduct((point), (plane)->normal) - (plane)->dist)) +#define bound( min, num, max ) ((num) >= (min) ? ((num) < (max) ? (num) : (max)) : (min)) float rsqrt( float number ); float anglemod( const float a ); diff --git a/engine/common/net_encode.c b/engine/common/net_encode.c index bb7243f5..d96ff181 100644 --- a/engine/common/net_encode.c +++ b/engine/common/net_encode.c @@ -727,7 +727,7 @@ void Delta_InitFields( void ) Q_snprintf( errormsg, sizeof( errormsg ), "DELTA_Load: couldn't load file %s\n", DELTA_PATH ); SV_SysError( errormsg ); - com.error( errormsg ); + Sys_Error( errormsg ); } pfile = afile; @@ -737,7 +737,7 @@ void Delta_InitFields( void ) dt = Delta_FindStruct( token ); if( dt == NULL ) { - Sys_Break( "delta.lst: unknown struct %s\n", token ); + Sys_Error( "delta.lst: unknown struct %s\n", token ); } pfile = COM_ParseFile( pfile, encodeDll ); @@ -750,7 +750,7 @@ void Delta_InitFields( void ) pfile = COM_ParseFile( pfile, token ); if( token[0] != '{' ) { - Sys_Break( "delta.lst: missing '{' in section %s\n", dt->pName ); + Sys_Error( "delta.lst: missing '{' in section %s\n", dt->pName ); } Delta_ParseTable( &pfile, dt, encodeDll, encodeFunc ); diff --git a/launch/console.c b/engine/common/sys_con.c similarity index 62% rename from launch/console.c rename to engine/common/sys_con.c index cf23301b..a88c3490 100644 --- a/launch/console.c +++ b/engine/common/sys_con.c @@ -1,11 +1,9 @@ //======================================================================= // Copyright XashXT Group 2007 © -// console.c - win and dos console +// sys_con.c - win32 dediacted console //======================================================================= -#include "launch.h" - -HINSTANCE base_hInstance; +#include "common.h" /* =============================================================================== @@ -27,6 +25,7 @@ WIN32 CONSOLE typedef struct { + char title[64]; HWND hWnd; HWND hwndBuffer; HWND hwndButtonSubmit; @@ -43,8 +42,14 @@ typedef struct int windowWidth, windowHeight; WNDPROC SysInputLineWndProc; size_t outLen; + + // log stuff + qboolean log_active; + char log_path[MAX_SYSPATH]; + FILE *logfile; } WinConData; -static WinConData s_wcd; + +static WinConData s_wcd; void Con_ShowConsole( qboolean show ) { @@ -62,17 +67,16 @@ void Con_ShowConsole( qboolean show ) void Con_DisableInput( void ) { - if( Sys.con_readonly ) return; + 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 ) { - if( Sys.con_readonly ) return; - + if( host.type != HOST_DEDICATED ) return; SetWindowText( s_wcd.hwndInputLine, inputText ); - SendMessage( s_wcd.hwndInputLine, EM_SETSEL, strlen( inputText ), -1 ); + SendMessage( s_wcd.hwndInputLine, EM_SETSEL, Q_strlen( inputText ), -1 ); } static int Con_KeyEvent( int key, qboolean down ) @@ -86,7 +90,7 @@ static int Con_KeyEvent( int key, qboolean down ) { case VK_TAB: GetWindowText( s_wcd.hwndInputLine, inputBuffer, sizeof( inputBuffer )); - if( Sys.CmdAuto ) Sys.CmdAuto( inputBuffer ); + Cmd_AutoComplete( inputBuffer ); Con_SetInputText( inputBuffer ); return 1; case VK_DOWN: @@ -113,18 +117,18 @@ static long _stdcall Con_WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lP SetFocus( s_wcd.hwndInputLine ); break; case WM_CLOSE: - if( Sys.app_state == SYS_ERROR ) + if( host.state == HOST_ERR_FATAL ) { // send windows message PostQuitMessage( 0 ); } - else Sys_Exit(); // otherwise + else Sys_Quit(); // otherwise return 0; case WM_CTLCOLORSTATIC: - if( (HWND)lParam == s_wcd.hwndBuffer ) + if((HWND)lParam == s_wcd.hwndBuffer ) { - SetBkColor( (HDC)wParam, RGB( 0x90, 0x90, 0x90 )); - SetTextColor( (HDC)wParam, RGB( 0xff, 0xff, 0xff )); + SetBkColor((HDC)wParam, RGB( 0x90, 0x90, 0x90 )); + SetTextColor((HDC)wParam, RGB( 0xff, 0xff, 0xff )); return (long)s_wcd.hbrEditBackground; } break; @@ -176,16 +180,16 @@ long _stdcall Con_InputLineProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPa case WM_CHAR: if( Con_KeyEvent( wParam, true )) return 0; - if( wParam == 13 && Sys.app_state != SYS_ERROR ) + if( wParam == 13 && host.state != HOST_ERR_FATAL ) { GetWindowText( s_wcd.hwndInputLine, inputBuffer, sizeof( inputBuffer )); - strncat( s_wcd.consoleText, inputBuffer, sizeof( s_wcd.consoleText ) - strlen( s_wcd.consoleText ) - 5 ); - strcat( s_wcd.consoleText, "\n" ); + Q_strncat( s_wcd.consoleText, inputBuffer, sizeof( s_wcd.consoleText ) - Q_strlen( s_wcd.consoleText ) - 5 ); + Q_strcat( s_wcd.consoleText, "\n" ); SetWindowText( s_wcd.hwndInputLine, "" ); Msg( ">%s\n", inputBuffer ); // copy line to history buffer - strncpy( s_wcd.historyLines[s_wcd.nextHistoryLine % COMMAND_HISTORY], inputBuffer, MAX_STRING ); + Q_strncpy( s_wcd.historyLines[s_wcd.nextHistoryLine % COMMAND_HISTORY], inputBuffer, MAX_STRING ); s_wcd.nextHistoryLine++; s_wcd.historyLine = s_wcd.nextHistoryLine; return 0; @@ -205,14 +209,14 @@ WIN32 IO */ /* ================ -Con_Print +Con_WinPrint print into window console ================ */ -void Con_Print( const char *pMsg ) +void Con_WinPrint( const char *pMsg ) { - size_t len = strlen( pMsg ); + size_t len = Q_strlen( pMsg ); // replace selection instead of appending if we're overflowing s_wcd.outLen += len; @@ -244,50 +248,45 @@ void Con_CreateConsole( void ) RECT rect; int nHeight; int swidth, sheight, fontsize; - string Title, FontName; int DEDSTYLE = WS_POPUPWINDOW | WS_CAPTION; int CONSTYLE = WS_CHILD|WS_VISIBLE|WS_VSCROLL|WS_BORDER|WS_EX_CLIENTEDGE|ES_LEFT|ES_MULTILINE|ES_AUTOVSCROLL|ES_READONLY; - - if( Sys.con_silentmode ) - return; - - Sys_InitLog(); + string FontName; wc.style = 0; wc.lpfnWndProc = (WNDPROC)Con_WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; - wc.hInstance = Sys.hInstance; - wc.hIcon = LoadIcon( Sys.hInstance, MAKEINTRESOURCE( IDI_ICON1 )); + wc.hInstance = host.hInst; + wc.hIcon = LoadIcon( host.hInst, MAKEINTRESOURCE( IDI_ICON1 )); wc.hCursor = LoadCursor( NULL, IDC_ARROW ); wc.hbrBackground = (void *)COLOR_3DSHADOW; wc.lpszClassName = SYSCONSOLE; wc.lpszMenuName = 0; - if(!RegisterClass( &wc )) - { - // print into log - MsgDev( D_WARN, "Can't register window class '%s'\n", SYSCONSOLE ); - return; - } + if( Sys_CheckParm( "-log" ) && host.developer != 0 ) + s_wcd.log_active = true; - if( Sys.con_showcredits ) + if( host.type == HOST_CREDITS ) { CONSTYLE &= ~WS_VSCROLL; rect.left = 0; rect.right = 536; rect.top = 0; rect.bottom = 280; - strncpy( FontName, "Arial", sizeof( FontName )); + Q_strncpy( FontName, "Arial", sizeof( FontName )); + Q_strncpy( s_wcd.title, "About", sizeof( s_wcd.title )); + s_wcd.log_active = false; fontsize = 16; } - else if( Sys.con_readonly ) + else if( host.type != HOST_DEDICATED ) { rect.left = 0; rect.right = 536; rect.top = 0; rect.bottom = 364; - strncpy( FontName, "Fixedsys", sizeof( FontName )); + Q_strncpy( FontName, "Fixedsys", sizeof( FontName )); + Q_strncpy( s_wcd.title, va( "Xash3D %g", XASH_VERSION ), sizeof( s_wcd.title )); + Q_strncpy( s_wcd.log_path, "engine.log", sizeof( s_wcd.log_path )); fontsize = 8; } else // dedicated console @@ -296,11 +295,21 @@ void Con_CreateConsole( void ) rect.right = 640; rect.top = 0; rect.bottom = 392; - strncpy( FontName, "System", sizeof( FontName )); + Q_strncpy( FontName, "System", sizeof( FontName )); + Q_strncpy( s_wcd.title, "Xash Dedicated Server", sizeof( s_wcd.title )); + Q_strncpy( s_wcd.log_path, "dedicated.log", sizeof( s_wcd.log_path )); fontsize = 14; } - strncpy( Title, Sys.caption, sizeof( Title )); + Sys_InitLog(); + + if( !RegisterClass( &wc )) + { + // print into log + MsgDev( D_ERROR, "Can't register window class '%s'\n", SYSCONSOLE ); + return; + } + AdjustWindowRect( &rect, DEDSTYLE, FALSE ); hDC = GetDC( GetDesktopWindow() ); @@ -311,49 +320,50 @@ void Con_CreateConsole( void ) s_wcd.windowWidth = rect.right - rect.left; s_wcd.windowHeight = rect.bottom - rect.top; - s_wcd.hWnd = CreateWindowEx( WS_EX_DLGMODALFRAME, SYSCONSOLE, Title, DEDSTYLE, ( swidth - 600 ) / 2, ( sheight - 450 ) / 2 , rect.right - rect.left + 1, rect.bottom - rect.top + 1, NULL, NULL, base_hInstance, NULL ); + s_wcd.hWnd = CreateWindowEx( WS_EX_DLGMODALFRAME, SYSCONSOLE, s_wcd.title, DEDSTYLE, ( swidth - 600 ) / 2, ( sheight - 450 ) / 2 , rect.right - rect.left + 1, rect.bottom - rect.top + 1, NULL, NULL, host.hInst, NULL ); if( s_wcd.hWnd == NULL ) { - Msg( "Can't create window '%s'\n", Title ); + MsgDev( D_ERROR, "Can't create window '%s'\n", s_wcd.title ); return; } // create fonts hDC = GetDC( s_wcd.hWnd ); nHeight = -MulDiv( fontsize, GetDeviceCaps( hDC, LOGPIXELSY ), 72 ); - s_wcd.hfBufferFont = CreateFont( nHeight, 0, 0, 0, FW_LIGHT, 0, 0, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FF_MODERN | FIXED_PITCH, FontName ); + s_wcd.hfBufferFont = CreateFont( nHeight, 0, 0, 0, FW_LIGHT, 0, 0, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FF_MODERN|FIXED_PITCH, FontName ); ReleaseDC( s_wcd.hWnd, hDC ); - if( !Sys.con_readonly ) + if( host.type == HOST_DEDICATED ) { // create the input line - s_wcd.hwndInputLine = CreateWindowEx( WS_EX_CLIENTEDGE, "edit", NULL, WS_CHILD|WS_VISIBLE|WS_BORDER|ES_LEFT|ES_AUTOHSCROLL, 0, 366, 550, 25, s_wcd.hWnd, ( HMENU )INPUT_ID, base_hInstance, NULL ); + s_wcd.hwndInputLine = CreateWindowEx( WS_EX_CLIENTEDGE, "edit", NULL, WS_CHILD|WS_VISIBLE|WS_BORDER|ES_LEFT|ES_AUTOHSCROLL, 0, 366, 550, 25, s_wcd.hWnd, (HMENU)INPUT_ID, host.hInst, NULL ); - s_wcd.hwndButtonSubmit = CreateWindow( "button", NULL, BS_PUSHBUTTON|WS_VISIBLE|WS_CHILD|BS_DEFPUSHBUTTON, 552, 367, 87, 25, s_wcd.hWnd, ( HMENU )SUBMIT_ID, base_hInstance, NULL ); + 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 ); - s_wcd.hwndBuffer = CreateWindowEx( WS_EX_DLGMODALFRAME|WS_EX_CLIENTEDGE, "edit", NULL, CONSTYLE, 0, 0, rect.right - rect.left, min(365, rect.bottom), s_wcd.hWnd, ( HMENU )EDIT_ID, base_hInstance, NULL ); - SendMessage( s_wcd.hwndBuffer, WM_SETFONT, ( WPARAM )s_wcd.hfBufferFont, 0 ); + s_wcd.hwndBuffer = CreateWindowEx( WS_EX_DLGMODALFRAME|WS_EX_CLIENTEDGE, "edit", NULL, CONSTYLE, 0, 0, rect.right - rect.left, min(365, rect.bottom), s_wcd.hWnd, (HMENU)EDIT_ID, host.hInst, NULL ); + SendMessage( s_wcd.hwndBuffer, WM_SETFONT, (WPARAM)s_wcd.hfBufferFont, 0 ); - if( !Sys.con_readonly ) + 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)Con_InputLineProc ); SendMessage( s_wcd.hwndInputLine, WM_SETFONT, ( WPARAM )s_wcd.hfBufferFont, 0 ); } // show console if needed - if( Sys.con_showalways ) + if( host.con_showalways ) { // make console visible - ShowWindow( s_wcd.hWnd, SW_SHOWDEFAULT); + ShowWindow( s_wcd.hWnd, SW_SHOWDEFAULT ); UpdateWindow( s_wcd.hWnd ); SetForegroundWindow( s_wcd.hWnd ); - if( Sys.con_readonly ) SetFocus( s_wcd.hWnd ); + if( host.type != HOST_DEDICATED ) + SetFocus( s_wcd.hWnd ); else SetFocus( s_wcd.hwndInputLine ); s_wcd.status = true; } @@ -370,7 +380,7 @@ destroy win32 console void Con_DestroyConsole( void ) { // last text message into console or log - MsgDev( D_NOTE, "Sys_FreeLibrary: Unloading launch.dll\n" ); + MsgDev( D_NOTE, "Sys_FreeLibrary: Unloading xash.dll\n" ); Sys_CloseLog(); @@ -384,10 +394,10 @@ void Con_DestroyConsole( void ) s_wcd.hWnd = 0; } - UnregisterClass( SYSCONSOLE, Sys.hInstance ); + UnregisterClass( SYSCONSOLE, host.hInst ); // place it here in case Sys_Crash working properly - if( Sys.hMutex ) CloseHandle( Sys.hMutex ); + if( host.hMutex ) CloseHandle( host.hMutex ); } /* @@ -402,7 +412,7 @@ char *Con_Input( void ) if( s_wcd.consoleText[0] == 0 ) return NULL; - strncpy( s_wcd.returnedText, s_wcd.consoleText, sizeof( s_wcd.returnedText )); + Q_strncpy( s_wcd.returnedText, s_wcd.consoleText, sizeof( s_wcd.returnedText )); s_wcd.consoleText[0] = 0; return s_wcd.returnedText; @@ -434,51 +444,57 @@ void Sys_InitLog( void ) { const char *mode; - if( Sys.app_state == SYS_RESTART ) + if( host.change_game ) mode = "a"; else mode = "w"; // create log if needed - if( Sys.log_active && !Sys.con_silentmode ) + if( s_wcd.log_active ) { - Sys.logfile = fopen( Sys.log_path, mode ); - if(!Sys.logfile) MsgDev( D_ERROR, "Sys_InitLog: can't create log file %s\n", Sys.log_path ); + 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( Sys.logfile, "=======================================================================\n" ); - fprintf( Sys.logfile, "\t%s started at %s\n", Sys.caption, timestamp( TIME_FULL )); - fprintf( Sys.logfile, "=======================================================================\n"); + fprintf( s_wcd.logfile, "=======================================================================\n" ); + fprintf( s_wcd.logfile, "\t%s started at %s\n", s_wcd.title, Q_timestamp( TIME_FULL )); + fprintf( s_wcd.logfile, "=======================================================================\n"); } } void Sys_CloseLog( void ) { - char event_name[32]; + char event_name[64]; // continue logged - switch( Sys.app_state ) + switch( host.state ) { - case SYS_CRASH: strncpy( event_name, "crashed", sizeof( event_name )); break; - case SYS_ERROR: strncpy( event_name, "stopped with error", sizeof( event_name )); break; - case SYS_RESTART: strncpy( event_name, "restarted", sizeof( event_name )); break; - default: strncpy( event_name, "stopped", sizeof( event_name )); break; + 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( Sys.logfile ) + if( s_wcd.logfile ) { - fprintf( Sys.logfile, "\n"); - fprintf( Sys.logfile, "======================================================================="); - fprintf( Sys.logfile, "\n\t%s %s at %s\n", Sys.caption, event_name, timestamp( TIME_FULL )); - fprintf( Sys.logfile, "=======================================================================\n"); - if( Sys.app_state == SYS_RESTART ) fprintf( Sys.logfile, "\n" ); // just for tabulate + fprintf( s_wcd.logfile, "\n"); + fprintf( s_wcd.logfile, "======================================================================="); + fprintf( s_wcd.logfile, "\n\t%s %s at %s\n", s_wcd.title, event_name, Q_timestamp( TIME_FULL )); + fprintf( s_wcd.logfile, "=======================================================================\n"); + if( host.change_game ) fprintf( s_wcd.logfile, "\n" ); // just for tabulate - fclose( Sys.logfile ); - Sys.logfile = NULL; + fclose( s_wcd.logfile ); + s_wcd.logfile = NULL; } } void Sys_PrintLog( const char *pMsg ) { - if( !Sys.logfile ) return; - fprintf( Sys.logfile, pMsg ); - fflush( Sys.logfile ); + if( !s_wcd.logfile ) return; + fprintf( s_wcd.logfile, pMsg ); + fflush( s_wcd.logfile ); } \ No newline at end of file diff --git a/engine/common/sys_win.c b/engine/common/sys_win.c index d1f2f702..abcd300c 100644 --- a/engine/common/sys_win.c +++ b/engine/common/sys_win.c @@ -4,10 +4,12 @@ //======================================================================= #include "common.h" +#include "mathlib.h" #define MAX_QUED_EVENTS 256 #define MASK_QUED_EVENTS (MAX_QUED_EVENTS - 1) +qboolean error_on_exit = false; // arg for exit(); sys_event_t event_que[MAX_QUED_EVENTS]; int event_head, event_tail; @@ -161,6 +163,129 @@ void Sys_ShellExecute( const char *path, const char *parms, qboolean exit ) if( exit ) Sys_Quit(); } +/* +================== +Sys_ParseCommandLine + +================== +*/ +void Sys_ParseCommandLine( LPSTR lpCmdLine ) +{ + const char *blank = "censored"; + int i; + + host.argc = 1; + host.argv[0] = "exe"; + + while( *lpCmdLine && ( host.argc < MAX_NUM_ARGVS )) + { + while( *lpCmdLine && *lpCmdLine <= ' ' ) + lpCmdLine++; + if( !*lpCmdLine ) break; + + if( *lpCmdLine == '\"' ) + { + // quoted string + lpCmdLine++; + host.argv[host.argc] = lpCmdLine; + host.argc++; + while( *lpCmdLine && ( *lpCmdLine != '\"' )) + lpCmdLine++; + } + else + { + // unquoted word + host.argv[host.argc] = lpCmdLine; + host.argc++; + while( *lpCmdLine && *lpCmdLine > ' ') + lpCmdLine++; + } + + if( *lpCmdLine ) + { + *lpCmdLine = 0; + lpCmdLine++; + } + } + + if( !host.change_game ) return; + + for( i = 0; i < host.argc; i++ ) + { + // we wan't return to first game + if( !Q_stricmp( "-game", host.argv[i] )) host.argv[i] = (char *)blank; + // probably it's timewaster, because engine rejected second change + if( !Q_stricmp( "+game", host.argv[i] )) host.argv[i] = (char *)blank; + // you sure what is map exists in new game? + if( !Q_stricmp( "+map", host.argv[i] )) host.argv[i] = (char *)blank; + // just stupid action + if( !Q_stricmp( "+load", host.argv[i] )) host.argv[i] = (char *)blank; + // changelevel beetwen games? wow it's great idea! + if( !Q_stricmp( "+changelevel", host.argv[i] )) host.argv[i] = (char *)blank; + } +} + +/* +================== +Sys_MergeCommandLine + +================== +*/ +void Sys_MergeCommandLine( LPSTR lpCmdLine ) +{ + const char *blank = "censored"; + int i; + + if( !host.change_game ) return; + + for( i = 0; i < host.argc; i++ ) + { + // second call + if( host.type == HOST_DEDICATED && !Q_strnicmp( "+menu_", host.argv[i], 6 )) + host.argv[i] = (char *)blank; + } +} + +/* +================ +Sys_CheckParm + +Returns the position (1 to argc-1) in the program's argument list +where the given parameter apears, or 0 if not present +================ +*/ +int Sys_CheckParm( const char *parm ) +{ + int i; + + for( i = 1; i < host.argc; i++ ) + { + if( !host.argv[i] ) continue; + if( !Q_stricmp( parm, host.argv[i] )) + return i; + } + return 0; +} + +/* +================ +Sys_GetParmFromCmdLine + +Returns the argument for specified parm +================ +*/ +qboolean _Sys_GetParmFromCmdLine( char *parm, char *out, size_t size ) +{ + int argc = Sys_CheckParm( parm ); + + if( !argc ) return false; + if( !out ) return false; + if( !host.argv[argc + 1] ) return false; + Q_strncpy( out, host.argv[argc+1], size ); + + return true; +} + /* ================ Sys_QueEvent @@ -225,7 +350,7 @@ sys_event_t Sys_GetEvent( void ) } // check for console commands - s = Sys_Input(); + s = Con_Input(); if( s ) { char *b; @@ -298,7 +423,7 @@ qboolean Sys_LoadLibrary( dll_info_t *dll ) error: MsgDev( D_NOTE, " - failed\n" ); Sys_FreeLibrary( dll ); // trying to free - if( dll->crash ) com.error( errorstring ); + if( dll->crash ) Sys_Error( errorstring ); else MsgDev( D_ERROR, errorstring ); return false; @@ -329,4 +454,273 @@ qboolean Sys_FreeLibrary( dll_info_t *dll ) dll->link = NULL; return true; +} + +/* +================ +Sys_WaitForQuit + +wait for 'Esc' key will be hit +================ +*/ +void Sys_WaitForQuit( void ) +{ + MSG msg; + + Con_RegisterHotkeys(); + + msg.message = 0; + + // wait for the user to quit + while( msg.message != WM_QUIT ) + { + if( PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) + { + TranslateMessage( &msg ); + DispatchMessage( &msg ); + } + else Sys_Sleep( 20 ); + } +} + +long _stdcall Sys_Crash( PEXCEPTION_POINTERS pInfo ) +{ + // save config + if( host.state != HOST_CRASHED ) + { + // check to avoid recursive call + error_on_exit = true; + host.state = HOST_CRASHED; + + if( host.type == HOST_NORMAL ) CL_Crashed(); // tell client about crash + Msg( "Sys_Crash: call %p at address %p\n", pInfo->ExceptionRecord->ExceptionAddress, pInfo->ExceptionRecord->ExceptionCode ); + + if( host.developer <= 0 ) + { + // no reason to call debugger in release build - just exit + 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; +} + +/* +================ +Sys_Error + +NOTE: we must prepare engine to shutdown +before call this +================ +*/ +void Sys_Error( const char *error, ... ) +{ + va_list argptr; + char text[MAX_SYSPATH]; + + if( host.state == HOST_ERR_FATAL ) + return; // don't multiple executes + + // make sure what console received last message + if( host.change_game ) Sys_Sleep( 200 ); + + error_on_exit = true; + host.state = HOST_ERR_FATAL; + va_start( argptr, error ); + Q_vsprintf( text, error, argptr ); + va_end( argptr ); + + if( host.type = HOST_NORMAL ) + CL_Shutdown(); // kill video + + if( host.developer > 0 ) + { + Con_ShowConsole( true ); + Con_DisableInput(); // disable input line for dedicated server + Sys_Print( text ); // print error message + Sys_WaitForQuit(); + } + else + { + Con_ShowConsole( false ); + MSGBOX( text ); + } + Sys_Quit(); +} + +/* +================ +Sys_Break + +same as Error +================ +*/ +void Sys_Break( const char *error, ... ) +{ + va_list argptr; + char text[MAX_SYSPATH]; + + if( host.state == HOST_ERR_FATAL ) + return; // don't multiple executes + + va_start( argptr, error ); + Q_vsprintf( text, error, argptr ); + va_end( argptr ); + + error_on_exit = true; + host.state = HOST_ERR_FATAL; + + if( host.type == HOST_NORMAL ) + CL_Shutdown(); // kill video + + if( host.type != HOST_NORMAL || host.developer > 0 ) + { + Con_ShowConsole( true ); + Sys_Print( text ); + Sys_WaitForQuit(); + } + else + { + Con_ShowConsole( false ); + MSGBOX( text ); + } + Sys_Quit(); +} + +/* +================ +Sys_Quit +================ +*/ +void Sys_Quit( void ) +{ + Host_Shutdown(); + exit( error_on_exit ); +} + +/* +================ +Sys_Print + +print into window console +================ +*/ +void Sys_Print( const char *pMsg ) +{ + const char *msg; + char buffer[32768]; + char logbuf[32768]; + 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] == '\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 + { + *b = *c = msg[i]; + b++, c++; + } + i++; + } + + *b = *c = 0; // cutoff garbage + + Sys_PrintLog( logbuf ); + Con_WinPrint( buffer ); +} + +/* +================ +Msg + +formatted message +================ +*/ +void Msg( const char *pMsg, ... ) +{ + va_list argptr; + char text[8192]; + + va_start( argptr, pMsg ); + Q_vsnprintf( text, sizeof( text ), pMsg, argptr ); + va_end( argptr ); + + Sys_Print( text ); +} + +/* +================ +MsgDev + +formatted developer message +================ +*/ +void MsgDev( int level, const char *pMsg, ... ) +{ + va_list argptr; + char text[8192]; + + if( host.developer < level ) return; + + va_start( argptr, pMsg ); + Q_vsnprintf( text, sizeof( text ), pMsg, argptr ); + va_end( argptr ); + + switch( level ) + { + case D_WARN: + Sys_Print( va( "^3Warning:^7 %s", text )); + break; + case D_ERROR: + Sys_Print( va( "^1Error:^7 %s", text )); + break; + case D_INFO: + case D_NOTE: + case D_AICONSOLE: + Sys_Print( text ); + break; + } } \ No newline at end of file diff --git a/engine/common/system.h b/engine/common/system.h index 333dc31f..6222f5bb 100644 --- a/engine/common/system.h +++ b/engine/common/system.h @@ -6,11 +6,17 @@ #ifndef SYSTEM_H #define SYSTEM_H +#ifdef __cplusplus +extern "C" { +#endif + #include #include #include #include +#define MSGBOX( x ) MessageBox( NULL, x, "Xash Error", MB_OK|MB_SETFOREGROUND|MB_ICONSTOP ) + // basic typedefs typedef int sound_t; typedef float vec_t; @@ -25,6 +31,8 @@ typedef vec_t matrix4x4[4][4]; #include "const.h" +#define ASSERT( exp ) if(!( exp )) Sys_Break( "assert failed at %s:%i\n", __FILE__, __LINE__ ) + /* ======================================================================== @@ -77,13 +85,44 @@ void Sys_Sleep( int msec ); double Sys_DoubleTime( void ); char *Sys_GetClipboardData( void ); char *Sys_GetCurrentUser( void ); +int Sys_CheckParm( const char *parm ); +void Sys_Error( const char *error, ... ); +void Sys_Break( 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( LPSTR lpCmdLine ); +void Sys_MergeCommandLine( LPSTR lpCmdLine ); +long _stdcall Sys_Crash( PEXCEPTION_POINTERS pInfo ); +#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 ); void Sys_QueEvent( ev_type_t type, int value, int value2, int length, void *ptr ); sys_event_t Sys_GetEvent( void ); qboolean Sys_CheckMMX( void ); qboolean Sys_CheckSSE( void ); +void Sys_Print( const char *pMsg ); +void Sys_PrintLog( const char *pMsg ); +void Sys_InitLog( void ); +void Sys_CloseLog( void ); +void Sys_Quit( void ); +// +// sys_con.c +// +void Con_ShowConsole( qboolean show ); +void Con_WinPrint( const char *pMsg ); +void Con_CreateConsole( void ); +void Con_DestroyConsole( void ); +void Con_RegisterHotkeys( void ); +void Con_DisableInput( void ); +char *Con_Input( void ); + +// text messages +void Msg( const char *pMsg, ... ); +void MsgDev( int level, const char *pMsg, ... ); + +#ifdef __cplusplus +} +#endif #endif//SYSTEM_H \ No newline at end of file diff --git a/engine/common/zone.c b/engine/common/zone.c index 35a27547..3eaaa719 100644 --- a/engine/common/zone.c +++ b/engine/common/zone.c @@ -64,7 +64,7 @@ void *_Mem_Alloc( byte *poolptr, size_t size, const char *filename, int fileline mempool_t *pool = (mempool_t *)((byte *)poolptr); if( size <= 0 ) return NULL; - if( poolptr == NULL ) com.error( "Mem_Alloc: pool == NULL (alloc at %s:%i)\n", filename, fileline ); + if( poolptr == NULL ) Sys_Error( "Mem_Alloc: pool == NULL (alloc at %s:%i)\n", filename, fileline ); pool->totalsize += size; if( size < 4096 ) @@ -76,9 +76,9 @@ void *_Mem_Alloc( byte *poolptr, size_t size, const char *filename, int fileline { clump = *clumpchainpointer; if( clump->sentinel1 != MEMCLUMP_SENTINEL ) - com.error( "Mem_Alloc: trashed clump sentinel 1 (alloc at %s:%d)\n", filename, fileline ); + Sys_Error( "Mem_Alloc: trashed clump sentinel 1 (alloc at %s:%d)\n", filename, fileline ); if( clump->sentinel2 != MEMCLUMP_SENTINEL ) - com.error( "Mem_Alloc: trashed clump sentinel 2 (alloc at %s:%d)\n", filename, fileline ); + Sys_Error( "Mem_Alloc: trashed clump sentinel 2 (alloc at %s:%d)\n", filename, fileline ); if( clump->largestavailable >= needed ) { largest = 0; @@ -104,7 +104,7 @@ loopcontinue:; pool->realsize += sizeof( memclump_t ); clump = malloc( sizeof( memclump_t )); - if( clump == NULL ) com.error( "Mem_Alloc: out of memory (alloc at %s:%i)\n", filename, fileline ); + if( clump == NULL ) Sys_Error( "Mem_Alloc: out of memory (alloc at %s:%i)\n", filename, fileline ); _Q_memset( clump, 0, sizeof( memclump_t ), filename, fileline ); *clumpchainpointer = clump; clump->sentinel1 = MEMCLUMP_SENTINEL; @@ -126,7 +126,7 @@ choseclump: // big allocations are not clumped pool->realsize += sizeof( memheader_t ) + size + sizeof( int ); mem = (memheader_t *)malloc( sizeof( memheader_t ) + size + sizeof( int )); - if( mem == NULL ) com.error( "Mem_Alloc: out of memory (alloc at %s:%i)\n", filename, fileline ); + if( mem == NULL ) Sys_Error( "Mem_Alloc: out of memory (alloc at %s:%i)\n", filename, fileline ); mem->clump = NULL; } @@ -170,18 +170,18 @@ static void Mem_FreeBlock( memheader_t *mem, const char *filename, int fileline if( mem->sentinel1 != MEMHEADER_SENTINEL1 ) { mem->filename = Mem_CheckFilename( mem->filename ); // make sure what we don't crash var_args - com.error( "Mem_Free: trashed header sentinel 1 (alloc at %s:%i, free at %s:%i)\n", mem->filename, mem->fileline, filename, fileline ); + Sys_Error( "Mem_Free: trashed header sentinel 1 (alloc at %s:%i, free at %s:%i)\n", mem->filename, mem->fileline, filename, fileline ); } if( *((byte *)mem + sizeof( memheader_t ) + mem->size ) != MEMHEADER_SENTINEL2 ) { mem->filename = Mem_CheckFilename( mem->filename ); // make sure what we don't crash var_args - com.error( "Mem_Free: trashed header sentinel 2 (alloc at %s:%i, free at %s:%i)\n", mem->filename, mem->fileline, filename, fileline ); + Sys_Error( "Mem_Free: trashed header sentinel 2 (alloc at %s:%i, free at %s:%i)\n", mem->filename, mem->fileline, filename, fileline ); } pool = mem->pool; // unlink memheader from doubly linked list if(( mem->prev ? mem->prev->next != mem : pool->chain != mem ) || ( mem->next && mem->next->prev != mem )) - com.error( "Mem_Free: not allocated or double freed (free at %s:%i)\n", filename, fileline ); + Sys_Error( "Mem_Free: not allocated or double freed (free at %s:%i)\n", filename, fileline ); if( mem->prev ) mem->prev->next = mem->next; else pool->chain = mem->next; @@ -195,12 +195,12 @@ static void Mem_FreeBlock( memheader_t *mem, const char *filename, int fileline if(( clump = mem->clump ) != NULL ) { if( clump->sentinel1 != MEMCLUMP_SENTINEL ) - com.error( "Mem_Free: trashed clump sentinel 1 (free at %s:%i)\n", filename, fileline ); + Sys_Error( "Mem_Free: trashed clump sentinel 1 (free at %s:%i)\n", filename, fileline ); if( clump->sentinel2 != MEMCLUMP_SENTINEL ) - com.error( "Mem_Free: trashed clump sentinel 2 (free at %s:%i)\n", filename, fileline ); + Sys_Error( "Mem_Free: trashed clump sentinel 2 (free at %s:%i)\n", filename, fileline ); firstblock = ((byte *)mem - (byte *)clump->block ); if( firstblock & ( MEMUNIT - 1 )) - com.error( "Mem_Free: address not valid in clump (free at %s:%i)\n", filename, fileline ); + Sys_Error( "Mem_Free: address not valid in clump (free at %s:%i)\n", filename, fileline ); firstblock /= MEMUNIT; endblock = firstblock + ((sizeof( memheader_t ) + mem->size + sizeof( int ) + (MEMUNIT - 1)) / MEMUNIT ); clump->blocksinuse -= endblock - firstblock; @@ -240,7 +240,7 @@ static void Mem_FreeBlock( memheader_t *mem, const char *filename, int fileline void _Mem_Free( void *data, const char *filename, int fileline ) { - if( data == NULL ) com.error( "Mem_Free: data == NULL (called at %s:%i)\n", filename, fileline ); + if( data == NULL ) Sys_Error( "Mem_Free: data == NULL (called at %s:%i)\n", filename, fileline ); Mem_FreeBlock((memheader_t *)((byte *)data - sizeof( memheader_t )), filename, fileline ); } @@ -277,8 +277,8 @@ void _Mem_Move( byte *poolptr, void **dest, void *src, size_t size, const char * memheader_t *mem; void *memptr = *dest; - if( !memptr ) com.error( "Mem_Move: dest == NULL (called at %s:%i)\n", filename, fileline ); - if( !src ) com.error( "Mem_Move: src == NULL (called at %s:%i)\n", filename, fileline ); + if( !memptr ) Sys_Error( "Mem_Move: dest == NULL (called at %s:%i)\n", filename, fileline ); + if( !src ) Sys_Error( "Mem_Move: src == NULL (called at %s:%i)\n", filename, fileline ); if( size <= 0 ) { @@ -307,7 +307,7 @@ byte *_Mem_AllocPool( const char *name, const char *filename, int fileline ) mempool_t *pool; pool = (mempool_t *)malloc(sizeof(mempool_t)); - if( pool == NULL ) com.error( "Mem_AllocPool: out of memory (allocpool at %s:%i)\n", filename, fileline ); + if( pool == NULL ) Sys_Error( "Mem_AllocPool: out of memory (allocpool at %s:%i)\n", filename, fileline ); _Q_memset( pool, 0, sizeof(mempool_t), filename, fileline ); // fill header @@ -334,9 +334,9 @@ void _Mem_FreePool( byte **poolptr, const char *filename, int fileline ) { // unlink pool from chain for( chainaddress = &poolchain; *chainaddress && *chainaddress != pool; chainaddress = &((*chainaddress)->next)); - if( *chainaddress != pool) com.error("Mem_FreePool: pool already free (freepool at %s:%i)\n", filename, fileline ); - if( pool->sentinel1 != MEMHEADER_SENTINEL1 ) com.error("Mem_FreePool: trashed pool sentinel 1 (allocpool at %s:%i, freepool at %s:%i)\n", pool->filename, pool->fileline, filename, fileline ); - if( pool->sentinel2 != MEMHEADER_SENTINEL1 ) com.error("Mem_FreePool: trashed pool sentinel 2 (allocpool at %s:%i, freepool at %s:%i)\n", pool->filename, pool->fileline, filename, fileline ); + if( *chainaddress != pool) Sys_Error("Mem_FreePool: pool already free (freepool at %s:%i)\n", filename, fileline ); + if( pool->sentinel1 != MEMHEADER_SENTINEL1 ) Sys_Error("Mem_FreePool: trashed pool sentinel 1 (allocpool at %s:%i, freepool at %s:%i)\n", pool->filename, pool->fileline, filename, fileline ); + if( pool->sentinel2 != MEMHEADER_SENTINEL1 ) Sys_Error("Mem_FreePool: trashed pool sentinel 2 (allocpool at %s:%i, freepool at %s:%i)\n", pool->filename, pool->fileline, filename, fileline ); *chainaddress = pool->next; // free memory owned by the pool @@ -351,10 +351,10 @@ void _Mem_FreePool( byte **poolptr, const char *filename, int fileline ) void _Mem_EmptyPool( byte *poolptr, const char *filename, int fileline ) { mempool_t *pool = (mempool_t *)((byte *)poolptr); - if( poolptr == NULL ) com.error( "Mem_EmptyPool: pool == NULL (emptypool at %s:%i)\n", filename, fileline ); + if( poolptr == NULL ) Sys_Error( "Mem_EmptyPool: pool == NULL (emptypool at %s:%i)\n", filename, fileline ); - if( pool->sentinel1 != MEMHEADER_SENTINEL1 ) com.error( "Mem_EmptyPool: trashed pool sentinel 1 (allocpool at %s:%i, emptypool at %s:%i)\n", pool->filename, pool->fileline, filename, fileline ); - if( pool->sentinel2 != MEMHEADER_SENTINEL1 ) com.error( "Mem_EmptyPool: trashed pool sentinel 2 (allocpool at %s:%i, emptypool at %s:%i)\n", pool->filename, pool->fileline, filename, fileline ); + if( pool->sentinel1 != MEMHEADER_SENTINEL1 ) Sys_Error( "Mem_EmptyPool: trashed pool sentinel 1 (allocpool at %s:%i, emptypool at %s:%i)\n", pool->filename, pool->fileline, filename, fileline ); + if( pool->sentinel2 != MEMHEADER_SENTINEL1 ) Sys_Error( "Mem_EmptyPool: trashed pool sentinel 2 (allocpool at %s:%i, emptypool at %s:%i)\n", pool->filename, pool->fileline, filename, fileline ); // free memory owned by the pool while( pool->chain ) Mem_FreeBlock( pool->chain, filename, fileline ); @@ -398,17 +398,17 @@ void Mem_CheckHeaderSentinels( void *data, const char *filename, int fileline ) { memheader_t *mem; - if (data == NULL) com.error( "Mem_CheckSentinels: data == NULL (sentinel check at %s:%i)\n", filename, fileline); + if (data == NULL) Sys_Error( "Mem_CheckSentinels: data == NULL (sentinel check at %s:%i)\n", filename, fileline); mem = (memheader_t *)((byte *) data - sizeof(memheader_t)); if( mem->sentinel1 != MEMHEADER_SENTINEL1 ) { mem->filename = Mem_CheckFilename( mem->filename ); // make sure what we don't crash var_args - com.error( "Mem_CheckSentinels: trashed header sentinel 1 (block allocated at %s:%i, sentinel check at %s:%i)\n", mem->filename, mem->fileline, filename, fileline); + Sys_Error( "Mem_CheckSentinels: trashed header sentinel 1 (block allocated at %s:%i, sentinel check at %s:%i)\n", mem->filename, mem->fileline, filename, fileline); } if( *((byte *) mem + sizeof(memheader_t) + mem->size) != MEMHEADER_SENTINEL2 ) { mem->filename = Mem_CheckFilename( mem->filename ); // make sure what we don't crash var_args - com.error( "Mem_CheckSentinels: trashed header sentinel 2 (block allocated at %s:%i, sentinel check at %s:%i)\n", mem->filename, mem->fileline, filename, fileline); + Sys_Error( "Mem_CheckSentinels: trashed header sentinel 2 (block allocated at %s:%i, sentinel check at %s:%i)\n", mem->filename, mem->fileline, filename, fileline); } } @@ -416,9 +416,9 @@ static void Mem_CheckClumpSentinels( memclump_t *clump, const char *filename, in { // this isn't really very useful if( clump->sentinel1 != MEMCLUMP_SENTINEL ) - com.error( "Mem_CheckClumpSentinels: trashed sentinel 1 (sentinel check at %s:%i)\n", filename, fileline ); + Sys_Error( "Mem_CheckClumpSentinels: trashed sentinel 1 (sentinel check at %s:%i)\n", filename, fileline ); if( clump->sentinel2 != MEMCLUMP_SENTINEL ) - com.error( "Mem_CheckClumpSentinels: trashed sentinel 2 (sentinel check at %s:%i)\n", filename, fileline ); + Sys_Error( "Mem_CheckClumpSentinels: trashed sentinel 2 (sentinel check at %s:%i)\n", filename, fileline ); } void _Mem_Check( const char *filename, int fileline ) @@ -430,9 +430,9 @@ void _Mem_Check( const char *filename, int fileline ) for( pool = poolchain; pool; pool = pool->next ) { if( pool->sentinel1 != MEMHEADER_SENTINEL1 ) - com.error( "Mem_CheckSentinelsGlobal: trashed pool sentinel 1 (allocpool at %s:%i, sentinel check at %s:%i)\n", pool->filename, pool->fileline, filename, fileline ); + Sys_Error( "Mem_CheckSentinelsGlobal: trashed pool sentinel 1 (allocpool at %s:%i, sentinel check at %s:%i)\n", pool->filename, pool->fileline, filename, fileline ); if( pool->sentinel2 != MEMHEADER_SENTINEL1 ) - com.error( "Mem_CheckSentinelsGlobal: trashed pool sentinel 2 (allocpool at %s:%i, sentinel check at %s:%i)\n", pool->filename, pool->fileline, filename, fileline ); + Sys_Error( "Mem_CheckSentinelsGlobal: trashed pool sentinel 2 (allocpool at %s:%i, sentinel check at %s:%i)\n", pool->filename, pool->fileline, filename, fileline ); } for( pool = poolchain; pool; pool = pool->next ) diff --git a/engine/engine.dsp b/engine/engine.dsp index 9b0451bd..28caf595 100644 --- a/engine/engine.dsp +++ b/engine/engine.dsp @@ -54,15 +54,15 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /opt:nowin98 -# ADD LINK32 user32.lib gdi32.lib shell32.lib advapi32.lib winmm.lib mpeg.lib ../utils/vgui/lib/win32_vc6/vgui.lib /nologo /subsystem:windows /dll /pdb:none /machine:I386 /nodefaultlib:"libc.lib" /libpath:"./common/soundlib" /opt:nowin98 +# ADD LINK32 user32.lib gdi32.lib shell32.lib advapi32.lib winmm.lib mpeg.lib ../utils/vgui/lib/win32_vc6/vgui.lib /nologo /subsystem:windows /dll /pdb:none /machine:I386 /nodefaultlib:"libc.lib" /out:"..\temp\engine\!release/xash.dll" /libpath:"./common/soundlib" /opt:nowin98 # SUBTRACT LINK32 /debug /nodefaultlib # Begin Custom Build TargetDir=\Xash3D\src_main\temp\engine\!release -InputPath=\Xash3D\src_main\temp\engine\!release\engine.dll +InputPath=\Xash3D\src_main\temp\engine\!release\xash.dll SOURCE="$(InputPath)" -"D:\Xash3D\engine.dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - copy $(TargetDir)\engine.dll "D:\Xash3D\engine.dll" +"D:\Xash3D\xash.dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + copy $(TargetDir)\xash.dll "D:\Xash3D\xash.dll" # End Custom Build @@ -91,15 +91,15 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 -# ADD LINK32 user32.lib gdi32.lib shell32.lib advapi32.lib winmm.lib mpeg.lib ../utils/vgui/lib/win32_vc6/vgui.lib /nologo /subsystem:windows /dll /debug /machine:I386 /nodefaultlib:"libc.lib" /pdbtype:sept /libpath:"./common/soundlib" +# ADD LINK32 user32.lib gdi32.lib shell32.lib advapi32.lib winmm.lib mpeg.lib ../utils/vgui/lib/win32_vc6/vgui.lib /nologo /subsystem:windows /dll /debug /machine:I386 /nodefaultlib:"libc.lib" /out:"..\temp\engine\!debug/xash.dll" /pdbtype:sept /libpath:"./common/soundlib" # SUBTRACT LINK32 /incremental:no /map /nodefaultlib # Begin Custom Build TargetDir=\Xash3D\src_main\temp\engine\!debug -InputPath=\Xash3D\src_main\temp\engine\!debug\engine.dll +InputPath=\Xash3D\src_main\temp\engine\!debug\xash.dll SOURCE="$(InputPath)" -"D:\Xash3D\engine.dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - copy $(TargetDir)\engine.dll "D:\Xash3D\engine.dll" +"D:\Xash3D\xash.dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + copy $(TargetDir)\xash.dll "D:\Xash3D\xash.dll" # End Custom Build @@ -470,6 +470,10 @@ SOURCE=.\server\sv_world.c # End Source File # Begin Source File +SOURCE=.\common\sys_con.c +# End Source File +# Begin Source File + SOURCE=.\common\sys_win.c # End Source File # Begin Source File diff --git a/engine/server/sv_game.c b/engine/server/sv_game.c index 6c2906d0..aeb56d66 100644 --- a/engine/server/sv_game.c +++ b/engine/server/sv_game.c @@ -2521,23 +2521,23 @@ static void pfnAlertMessage( ALERT_TYPE level, char *szFmt, ... ) if( level == at_notice ) { - com.print( buffer ); // notice printing always + Sys_Print( buffer ); // notice printing always } else if( level == at_console && host.developer >= D_INFO ) { - com.print( buffer ); + Sys_Print( buffer ); } else if( level == at_aiconsole && host.developer >= D_AICONSOLE ) { - com.print( buffer ); + Sys_Print( buffer ); } else if( level == at_warning && host.developer >= D_WARN ) { - com.print( va( "^3Warning:^7 %s", buffer )); + Sys_Print( va( "^3Warning:^7 %s", buffer )); } else if( level == at_error && host.developer >= D_ERROR ) { - com.print( va( "^1Error:^7 %s", buffer )); + Sys_Print( va( "^1Error:^7 %s", buffer )); } } diff --git a/game_launch/game.cpp b/game_launch/game.cpp index 343bd0de..903e73b5 100644 --- a/game_launch/game.cpp +++ b/game_launch/game.cpp @@ -5,16 +5,16 @@ #include -// NOTE: engine has a two methods to detect basedir: -// first method: by filename, e.g. spirit.exe will be use basedir 'spirit', hostname must be "normal" -// second method: by hostname with leading symbol '$'. e.g. hl.exe with hostname '$valve' set the basedir to 'valve' -// for dedicated servers rename 'YourExeName.exe' to '#YourExeName.exe' -// Keyword "normal" it's a reserved word which switch engine to game mode, other reserved words run Xash Tools. -// +#define GAME_PATH "valve" // default dir to start from -#define GAME_PATH "$valve" // '$' indicates a start of basefolder name +typedef void (*pfnChangeGame)( const char *progname ); +typedef int (*pfnInit)( const char *progname, int bChangeGame, pfnChangeGame func ); +typedef void (*pfnShutdown)( void ); -typedef int (*pfnExecute)( const char *hostname, int console ); // engine entry point format +pfnInit Host_Main; +pfnShutdown Host_Shutdown; +char szGameDir[128]; // safe place to keep gamedir +HINSTANCE hEngine; void Sys_Error( const char *errorstring ) { @@ -22,21 +22,43 @@ void Sys_Error( const char *errorstring ) exit( 1 ); } -int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) +void Sys_LoadEngine( void ) { - HINSTANCE hmain; - - if(( hmain = LoadLibrary( "launch.dll" )) == NULL ) + if(( hEngine = LoadLibrary( "xash.dll" )) == NULL ) { - Sys_Error( "Unable to load the launch.dll" ); + Sys_Error( "Unable to load the xash.dll" ); } - pfnExecute mainFunc; - - if(( mainFunc = (pfnExecute)GetProcAddress( hmain, "CreateAPI" )) == NULL ) + if(( Host_Main = (pfnInit)GetProcAddress( hEngine, "Host_Main" )) == NULL ) { - Sys_Error( "Unable to find entry point in the launch.dll" ); - } + Sys_Error( "xash.dll missed 'Host_Main' export" ); + } - return mainFunc( GAME_PATH, false ); + // this is non-fatal for us but change game will not working + Host_Shutdown = (pfnShutdown)GetProcAddress( hEngine, "Host_Shutdown" ); +} + +void Sys_UnloadEngine( void ) +{ + if( Host_Shutdown ) Host_Shutdown( ); + if( hEngine ) FreeLibrary( hEngine ); +} + +void Sys_ChangeGame( const char *progname ) +{ + if( !progname || !progname[0] ) Sys_Error( "Sys_ChangeGame: NULL gamedir" ); + if( Host_Shutdown == NULL ) Sys_Error( "Sys_ChangeGame: missed 'Host_Shutdown' export\n" ); + strncpy( szGameDir, progname, sizeof( szGameDir ) - 1 ); + + Sys_UnloadEngine (); + Sys_LoadEngine (); + + Host_Main( szGameDir, TRUE, ( Host_Shutdown != NULL ) ? Sys_ChangeGame : NULL ); +} + +int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) +{ + Sys_LoadEngine(); + + return Host_Main( GAME_PATH, FALSE, ( Host_Shutdown != NULL ) ? Sys_ChangeGame : NULL ); } \ No newline at end of file diff --git a/game_launch/game.dsp b/game_launch/game.dsp index 18a0773f..8392fc84 100644 --- a/game_launch/game.dsp +++ b/game_launch/game.dsp @@ -49,8 +49,8 @@ BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 -# ADD LINK32 msvcrt.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /pdb:none /machine:I386 /nodefaultlib:"libc.lib" /out:"hl.exe" +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /opt:nowin98 +# ADD LINK32 msvcrt.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /pdb:none /machine:I386 /opt:nowin98 /nodefaultlib:"libc.lib" /out:"hl.exe" # Begin Target # Name "game - Win32 Release" diff --git a/launch/launch.dsp b/launch/launch.dsp deleted file mode 100644 index 1cf07653..00000000 --- a/launch/launch.dsp +++ /dev/null @@ -1,139 +0,0 @@ -# Microsoft Developer Studio Project File - Name="launch" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=launch - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "launch.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "launch.mak" CFG="launch - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "launch - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "launch - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "launch - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "..\temp\launch\!release" -# PROP Intermediate_Dir "..\temp\launch\!release" -# PROP Ignore_Export_Lib 1 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LAUNCH_EXPORTS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "./" /I "imagelib" /I "./sndlib" /I "../common" /I "../engine" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x419 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /opt:nowin98 -# ADD LINK32 user32.lib gdi32.lib shell32.lib advapi32.lib winmm.lib /nologo /dll /pdb:none /machine:I386 /nodefaultlib:"libc" /opt:nowin98 -# Begin Custom Build -TargetDir=\Xash3D\src_main\temp\launch\!release -InputPath=\Xash3D\src_main\temp\launch\!release\launch.dll -SOURCE="$(InputPath)" - -"D:\Xash3D\launch.dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - copy $(TargetDir)\launch.dll "D:\Xash3D\launch.dll" - -# End Custom Build - -!ELSEIF "$(CFG)" == "launch - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "..\temp\launch\!debug" -# PROP Intermediate_Dir "..\temp\launch\!debug" -# PROP Ignore_Export_Lib 1 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LAUNCH_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /Gi /GX /ZI /Od /I "./" /I "../common" /I "../engine" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /FD /GZ /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x419 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 user32.lib gdi32.lib shell32.lib advapi32.lib winmm.lib /nologo /dll /debug /machine:I386 /nodefaultlib:"libc" /pdbtype:sept -# Begin Custom Build -TargetDir=\Xash3D\src_main\temp\launch\!debug -InputPath=\Xash3D\src_main\temp\launch\!debug\launch.dll -SOURCE="$(InputPath)" - -"D:\Xash3D\launch.dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - copy $(TargetDir)\launch.dll "D:\Xash3D\launch.dll" - -# End Custom Build - -!ENDIF - -# Begin Target - -# Name "launch - Win32 Release" -# Name "launch - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=.\console.c -# End Source File -# Begin Source File - -SOURCE=.\stdlib.c -# End Source File -# Begin Source File - -SOURCE=.\system.c -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=.\launch.h -# End Source File -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/launch/launch.h b/launch/launch.h deleted file mode 100644 index b88b7fb6..00000000 --- a/launch/launch.h +++ /dev/null @@ -1,152 +0,0 @@ -//======================================================================= -// Copyright XashXT Group 2007 © -// launch.h - launch.dll main header -//======================================================================= -#ifndef LAUNCHER_H -#define LAUNCHER_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define LAUNCH_DLL // ignore alias names -#include "launch_api.h" - -#define MAX_NUM_ARGVS 128 - -// just for last chanse to view message (debug only) -#define MSGBOX( x ) MessageBox(NULL, x, "Xash Error", MB_OK|MB_SETFOREGROUND|MB_ICONSTOP ); - -enum state_e -{ - SYS_SHUTDOWN = 0, - SYS_RESTART, - SYS_CRASH, - SYS_ERROR, - SYS_FRAME, -}; - -/* -======================================================================== -internal dll's loader - -two main types - native dlls and other win32 libraries will be recognized automatically -NOTE: never change this structure because all dll descriptions in xash code -writes into struct by offsets not names -======================================================================== -*/ -typedef struct { const char *name; void **func; } dllfunc_t; // Sys_LoadLibrary stuff -typedef struct dll_info_s -{ - const char *name; // name of library - - // generic interface - const dllfunc_t *fcts; // list of dll exports - const char *entry; // entrypoint name (internal libs only) - void *link; // hinstance of loading library - - // xash interface - void *(*main)( void*, void* ); - qboolean crash; // crash if dll not found - - size_t api_size; // interface size - size_t com_size; // main interface size == sizeof( stdilib_api_t ) -} dll_info_t; - -typedef struct system_s -{ - char progname[64]; // instance keyword - char fmessage[64]; // shutdown final message - int app_name; - int app_state; - - int developer; - - // command line parms - int argc; - char *argv[MAX_NUM_ARGVS]; - - // log stuff - qboolean log_active; - char log_path[MAX_SYSPATH]; - FILE *logfile; - - HANDLE hMutex; - HINSTANCE hInstance; - LPTOP_LEVEL_EXCEPTION_FILTER oldFilter; - dll_info_t *linked_dll; - - char caption[64]; - qboolean con_readonly; - qboolean con_showalways; - qboolean con_showcredits; - qboolean con_silentmode; - qboolean shutdown_issued; - qboolean error; - - void ( *Init ) ( int argc, char **argv ); - void ( *Main ) ( void ); // host frame - void ( *Free ) ( void ); // close host - void (*CPrint)( const char *msg ); // console print - void (*CmdAuto)( char *complete_string ); - void (*Crashed)( void ); -} system_t; - -extern system_t Sys; -extern sysinfo_t SI; -extern stdlib_api_t com; - -// -// console.c -// -void Con_ShowConsole( qboolean show ); -void Con_Print( const char *pMsg ); -void Con_CreateConsole( void ); -void Con_DestroyConsole( void ); -void Con_RegisterHotkeys( void ); -void Con_DisableInput( void ); -char *Con_Input( void ); - -// -// system.c -// -void Sys_ParseCommandLine( LPSTR lpCmdLine ); -void Sys_LookupInstance( void ); -void Sys_NewInstance( const char *name, const char *fmsg ); -double Sys_DoubleTime( void ); -void Sys_Sleep( int msec ); -void Sys_Init( void ); -void Sys_Exit( void ); -int Sys_CheckParm( const char *parm ); -qboolean Sys_GetParmFromCmdLine( char *parm, char *out, size_t size ); -qboolean Sys_LoadLibrary( const char *dll_name, dll_info_t *dll ); -void* Sys_GetProcAddress ( dll_info_t *dll, const char* name ); -qboolean Sys_FreeLibrary ( dll_info_t *dll ); -void Sys_WaitForQuit( void ); -void Sys_InitLog( void ); -void Sys_CloseLog( void ); -void Sys_Error(const char *error, ...); -void Sys_Break(const char *error, ...); -void Sys_PrintLog( const char *pMsg ); -void Sys_Print( const char *pMsg ); -void Sys_Msg( const char *pMsg, ... ); -void Sys_MsgDev( int level, const char *pMsg, ... ); - -#define Msg Sys_Msg -#define MsgDev Sys_MsgDev - -// -// stdlib.c -// -char *va( const char *format, ... ); -const char* timestamp( int format ); -void Com_FileBase( const char *in, char *out ); - -#endif//LAUNCHER_H \ No newline at end of file diff --git a/launch/launch_api.h b/launch/launch_api.h deleted file mode 100644 index 36ef6262..00000000 --- a/launch/launch_api.h +++ /dev/null @@ -1,215 +0,0 @@ -//======================================================================= -// Copyright XashXT Group 2008 © -// launch_api.h - main header for all dll's -//======================================================================= -#ifndef LAUNCH_APH_H -#define LAUNCH_APH_H - -// disable some warnings -#pragma warning(disable : 4244) // MIPS -#pragma warning(disable : 4018) // signed/unsigned mismatch -#pragma warning(disable : 4305) // truncation from const double to float - -#define MAX_STRING 256 // generic string -#define MAX_INFO_STRING 256 // infostrings are transmitted across network -#define MAX_SYSPATH 1024 // system filepath -#define bound(min, num, max) ((num) >= (min) ? ((num) < (max) ? (num) : (max)) : (min)) -#define MAX_MODS 512 // environment games that engine can keep visible -#define EXPORT __declspec( dllexport ) -#define BIT( n ) (1<<( n )) - -#ifndef NULL -#define NULL ((void *)0) -#endif - -// color strings -#define IsColorString( p ) ( p && *( p ) == '^' && *(( p ) + 1) && *(( p ) + 1) >= '0' && *(( p ) + 1 ) <= '9' ) - -typedef unsigned long dword; -typedef unsigned int uint; -typedef char string[MAX_STRING]; - -#ifdef LAUNCH_DLL -#ifndef __cplusplus -typedef enum { false, true } qboolean; -#else -typedef int qboolean; -#endif -#endif - -// platform instances -typedef enum -{ - HOST_OFFLINE = 0, // host_init( g_Instance ) same much as: - HOST_CREDITS, // "splash" "©anyname" (easter egg) - HOST_DEDICATED, // "normal" "#gamename" - HOST_NORMAL, // "normal" "gamename" - HOST_MAXCOUNT, // terminator -} instance_t; - -enum dev_level -{ - D_INFO = 1, // "-dev 1", shows various system messages - D_WARN, // "-dev 2", shows not critical system warnings - D_ERROR, // "-dev 3", shows critical warnings - D_AICONSOLE, // "-dev 4", special case for game aiconsole - D_NOTE, // "-dev 5", show system notifications for engine developers -}; - -typedef long fs_offset_t; -typedef struct file_s file_t; // normal file -typedef struct wfile_s wfile_t; // wad file -typedef struct { int numfilenames; char **filenames; char *filenamesbuffer; } search_t; -typedef struct stream_s stream_t; // sound stream for background music playing - -// timestamp modes -enum -{ - TIME_FULL = 0, - TIME_DATE_ONLY, - TIME_TIME_ONLY, - TIME_NO_SECONDS, - TIME_YEAR_ONLY, - TIME_FILENAME, -}; - -/* -======================================================================== - -GAMEINFO stuff - -internal shared gameinfo structure (readonly for engine parts) -======================================================================== -*/ -typedef struct gameinfo_s -{ - // filesystem info - char gamefolder[64]; // used for change game '-game x' - char basedir[64]; // main game directory (like 'id1' for Quake or 'valve' for Half-Life) - char gamedir[64]; // game directory (can be match with basedir, used as primary dir and as write path - char startmap[64]; // map to start singleplayer game - char trainmap[64]; // map to start hazard course (if specified) - char title[64]; // Game Main Title - float version; // game version (optional) - - // .dll pathes - char dll_path[64]; // e.g. "bin" or "cl_dlls" - char game_dll[64]; // custom path for game.dll - - // about mod info - string game_url; // link to a developer's site - string update_url; // link to updates page - char type[64]; // single, toolkit, multiplayer etc - char date[64]; - size_t size; - - int gamemode; - - char sp_entity[32]; // e.g. info_player_start - char mp_entity[32]; // e.g. info_player_deathmatch - - float client_mins[4][3]; // 4 hulls allowed - float client_maxs[4][3]; // 4 hulls allowed - - int max_edicts; // min edicts is 600, max edicts is 4096 - int max_tents; // min temp ents is 300, max is 2048 - int max_beams; // min beams is 64, max beams is 512 - int max_particles; // min particles is 512, max particles is 8192 -} gameinfo_t; - -typedef struct sysinfo_s -{ - char instance; // global engine instance - - int developer; // developer level ( 1 - 7 ) - string ModuleName; // exe.filename - - gameinfo_t *GameInfo; // current GameInfo - gameinfo_t *games[MAX_MODS]; // environment games (founded at each engine start) - int numgames; -} sysinfo_t; - -/* -============================================================================== - -STDLIB SYSTEM INTERFACE -============================================================================== -*/ -typedef struct stdilib_api_s -{ - // interface validator - size_t api_size; // must matched with sizeof(launch_exp_t) - size_t com_size; // must matched with sizeof(stdlib_api_t) - - sysinfo_t *SysInfo; // engine sysinfo (filled by launcher) - - // base events - void (*instance)( const char *name, const char *fmsg ); // restart engine with new instance - void (*print)( const char *msg ); // basic text message - void (*printf)( const char *msg, ... ); // formatted text message - void (*dprintf)( int level, const char *msg, ...); // developer text message - void (*error)( const char *msg, ... ); // abnormal termination with message - void (*abort)( const char *msg, ... ); // normal tremination with message - void (*exit)( void ); // normal silent termination - char *(*input)( void ); // win32 console input (dedicated server) - int (*Com_CheckParm)( const char *parm ); // check parm in cmdline - qboolean (*Com_GetParm)( char *parm, char *out, size_t size );// get parm from cmdline -} stdlib_api_t; - -/* -============================================================================== - - Generic LAUNCH.DLL INTERFACE -============================================================================== -*/ -typedef struct launch_exp_s -{ - // interface validator - size_t api_size; // must matched with sizeof(launch_api_t) - size_t com_size; // must matched with sizeof(stdlib_api_t) - - void (*Init)( const int argc, const char **argv ); // init host - void (*Main)( void ); // host frame - void (*Free)( void ); // close host - void (*CPrint)( const char *msg ); // host print - void (*CmdComplete)( char *complete_string ); // cmd autocomplete for system console - void (*Crashed)( void ); // tell host about crash -} launch_exp_t; - -// this is the only function actually exported at the linker level -typedef void *(*launch_t)( stdlib_api_t*, void* ); -typedef struct { size_t api_size; size_t com_size; } generic_api_t; - -// moved here to enable assertation feature in launch.dll -#define ASSERT( exp ) if(!( exp )) com.abort( "assert failed at %s:%i\n", __FILE__, __LINE__ ); - -#ifndef LAUNCH_DLL - -/* -=========================================== -filesystem manager -=========================================== -*/ -#define FS_Gamedir() com.SysInfo->GameInfo->gamedir -#define FS_Title() com.SysInfo->GameInfo->title -#define g_Instance() com.SysInfo->instance - -/* -=========================================== -misc utils -=========================================== -*/ -#define SI com.SysInfo -#define GI com.SysInfo->GameInfo -#define Msg com.printf -#define MsgDev com.dprintf -#define Sys_NewInstance com.instance -#define Sys_Print com.print -#define Sys_Quit com.exit -#define Sys_Break com.abort -#define Sys_CheckParm com.Com_CheckParm -#define Sys_GetParmFromCmdLine( a, b ) com.Com_GetParm( a, b, sizeof( b )) -#define Sys_Input com.input - -#endif//LAUNCH_DLL -#endif//LAUNCH_APH_H \ No newline at end of file diff --git a/launch/stdlib.c b/launch/stdlib.c deleted file mode 100644 index 0ac5a98a..00000000 --- a/launch/stdlib.c +++ /dev/null @@ -1,121 +0,0 @@ -//======================================================================= -// Copyright XashXT Group 2007 © -// stdlib.c - std lib portable utils -//======================================================================= - -#include "launch.h" - -/* -==================== -timestamp -==================== -*/ -const char *timestamp( int format ) -{ - static string timestamp; - time_t crt_time; - const struct tm *crt_tm; - string timestring; - - time( &crt_time ); - crt_tm = localtime( &crt_time ); - - switch( format ) - { - case TIME_FULL: - // Build the full timestamp (ex: "Apr03 2007 [23:31.55]"); - strftime( timestring, sizeof (timestring), "%b%d %Y [%H:%M.%S]", crt_tm ); - break; - case TIME_DATE_ONLY: - // Build the date stamp only (ex: "Apr03 2007"); - strftime( timestring, sizeof (timestring), "%b%d %Y", crt_tm ); - break; - case TIME_TIME_ONLY: - // Build the time stamp only (ex: "23:31.55"); - strftime( timestring, sizeof (timestring), "%H:%M.%S", crt_tm ); - break; - case TIME_NO_SECONDS: - // Build the time stamp exclude seconds (ex: "13:46"); - strftime( timestring, sizeof (timestring), "%H:%M", crt_tm ); - break; - case TIME_YEAR_ONLY: - // Build the date stamp year only (ex: "2006"); - strftime( timestring, sizeof (timestring), "%Y", crt_tm ); - break; - case TIME_FILENAME: - // Build a timestamp that can use for filename (ex: "Nov2006-26 (19.14.28)"); - strftime( timestring, sizeof (timestring), "%b%Y-%d_%H.%M.%S", crt_tm ); - break; - default: return NULL; - } - - strncpy( timestamp, timestring, sizeof( timestamp )); - return timestamp; -} - -/* -============ -va - -does a varargs printf into a temp buffer, -so I don't need to have varargs versions -of all text functions. -============ -*/ -char *va( const char *format, ... ) -{ - va_list argptr; - static char string[256][1024], *s; // g-cont. 256 temporary strings should be enough... - static int stringindex = 0; - - s = string[stringindex]; - stringindex = (stringindex + 1) & 255; - va_start( argptr, format ); - _vsnprintf( s, sizeof( string[0] ), format, argptr ); - va_end( argptr ); - - return s; -} - -/* -============ -Com_FileBase - -TEMPORARY PLACE. dont forget to remove it -============ -*/ -void Com_FileBase( const char *in, char *out ) -{ - int len, start, end; - - len = strlen( in ); - if( !len ) return; - - // scan backward for '.' - end = len - 1; - - while( end && in[end] != '.' && in[end] != '/' && in[end] != '\\' ) - end--; - - if( in[end] != '.' ) - end = len-1; // no '.', copy to end - else end--; // found ',', copy to left of '.' - - - // scan backward for '/' - start = len - 1; - - while( start >= 0 && in[start] != '/' && in[start] != '\\' ) - start--; - - if( start < 0 || ( in[start] != '/' && in[start] != '\\' )) - start = 0; - else start++; - - // length of new sting - len = end - start + 1; - - // Copy partial string - strncpy( out, &in[start], len + 1 ); - out[len] = 0; -} \ No newline at end of file diff --git a/launch/system.c b/launch/system.c deleted file mode 100644 index bc142028..00000000 --- a/launch/system.c +++ /dev/null @@ -1,851 +0,0 @@ - -//======================================================================= -// Copyright XashXT Group 2007 © -// utils.c - shared launcher utils -//======================================================================= - -#include "launch.h" - - -system_t Sys; -sysinfo_t SI; -stdlib_api_t com; - -dll_info_t engine_dll = { "engine.dll", NULL, "CreateAPI", NULL, NULL, 1, sizeof( launch_exp_t ), sizeof( stdlib_api_t ) }; - -static const char *show_credits = "\n\n\n\n\tCopyright XashXT Group %s ©\n\t\ - All Rights Reserved\n\n\t Visit www.xash.ru\n"; - -// stubs -void NullInit( int argc, char **argv ) {} -void NullFunc( void ) {} -void NullPrint( const char *msg ) {} - -void Sys_GetStdAPI( void ) -{ - // interface validator - com.api_size = sizeof( stdlib_api_t ); - com.com_size = sizeof( stdlib_api_t ); - - // base events - com.instance = Sys_NewInstance; - com.printf = Sys_Msg; - com.dprintf = Sys_MsgDev; - com.error = Sys_Error; - com.abort = Sys_Break; - com.exit = Sys_Exit; - com.print = Sys_Print; - com.Com_CheckParm = Sys_CheckParm; // get parm from cmdline - com.Com_GetParm = Sys_GetParmFromCmdLine; // get argument for specified parm - com.input = Con_Input; - - com.SysInfo = &SI; -} - -/* -================== -Parse program name to launch and determine work style - -NOTE: at this day we have ten instances - -0. "offline" - invalid instance -1. "credits" - show engine credits -2. "dedicated" - dedicated server -3. "normal" - normal or dedicated game launch -================== -*/ -void Sys_LookupInstance( void ) -{ - char szTemp[128]; - qboolean dedicated = false; - - Sys.app_name = HOST_OFFLINE; - // we can specified custom name, from Sys_NewInstance - if( GetModuleFileName( NULL, szTemp, sizeof( szTemp )) && Sys.app_state != SYS_RESTART ) - Com_FileBase( szTemp, SI.ModuleName ); - - // determine host type - if( SI.ModuleName[0] == '#' || SI.ModuleName[0] == '©' ) - { - if( SI.ModuleName[0] == '#' ) dedicated = true; - if( SI.ModuleName[0] == '©' ) strcpy( Sys.progname, "credits" ); - - // cutoff hidden symbols - strncpy( szTemp, SI.ModuleName + 1, sizeof( szTemp )); - strncpy( SI.ModuleName, szTemp, sizeof( SI.ModuleName )); - } - - if( Sys.progname[0] == '$' ) - { - // custom path came from executable, otherwise can't be modified - strncpy( SI.ModuleName, Sys.progname + 1, sizeof( SI.ModuleName )); - strncpy( Sys.progname, "normal", sizeof( Sys.progname )); // set as "normal" - } - - // lookup all instances - if( !strcmp( Sys.progname, "credits" )) - { - Sys.app_name = HOST_CREDITS; // easter egg - Sys.linked_dll = NULL; // no need to loading library - Sys.log_active = Sys.developer = 0; // clear all dbg states - strcpy( Sys.caption, "About" ); - Sys.con_showcredits = true; - } - else if( !strcmp( Sys.progname, "normal" )) - { - if( dedicated ) - { - Sys.app_name = HOST_DEDICATED; - Sys.con_readonly = false; - - // check for duplicate dedicated server - Sys.hMutex = CreateMutex( NULL, 0, "Xash Dedicated Server" ); - if( !Sys.hMutex ) - { - MSGBOX( "Dedicated server already running" ); - Sys_Exit(); - return; - } - - CloseHandle( Sys.hMutex ); - Sys.hMutex = CreateSemaphore( NULL, 0, 1, "Xash Dedicated Server" ); - if( !Sys.developer ) Sys.developer = 3; // otherwise we see empty console - strcpy( Sys.log_path, "dedicated.log" ); - } - else - { - Sys.app_name = HOST_NORMAL; - Sys.con_readonly = true; - // don't show console as default - if( Sys.developer < D_WARN ) Sys.con_showalways = false; - strcpy( Sys.log_path, "engine.log" ); - } - - Sys.linked_dll = &engine_dll; // pointer to engine.dll info - strcpy( Sys.caption, "Xash3D" ); - } - - // share instance over all system - SI.instance = Sys.app_name; -} - -/* -================== -Find needed library, setup and run it -================== -*/ -void Sys_CreateInstance( void ) -{ - // export - launch_t CreateHost; - launch_exp_t *Host; // callback to mainframe - - srand( time( NULL )); // init random generator - Sys_LoadLibrary( NULL, Sys.linked_dll ); // loading library if need - - // pre initializations - switch( Sys.app_name ) - { - case HOST_NORMAL: - case HOST_DEDICATED: - CreateHost = (void *)Sys.linked_dll->main; - Host = CreateHost( &com, NULL ); // second interface not allowed - Sys.Init = Host->Init; - Sys.Main = Host->Main; - Sys.Free = Host->Free; - Sys.CPrint = Host->CPrint; - Sys.CmdAuto = Host->CmdComplete; - Sys.Crashed = Host->Crashed; - break; - case HOST_CREDITS: - Sys_Break( show_credits, timestamp( TIME_YEAR_ONLY )); - break; - case HOST_OFFLINE: - Sys_Break( "Host offline\n" ); - break; - } - - // init our host now! - Sys.Init( Sys.argc, Sys.argv ); - - // post initializations - if( Sys.app_name == HOST_NORMAL ) Con_ShowConsole( false ); // hide console - Sys.app_state = SYS_FRAME; // system is now active -} - -/* -================== -Sys_ParseCommandLine - -================== -*/ -void Sys_ParseCommandLine( LPSTR lpCmdLine ) -{ - Sys.argc = 1; - Sys.argv[0] = "exe"; - - while( *lpCmdLine && ( Sys.argc < MAX_NUM_ARGVS )) - { - while( *lpCmdLine && *lpCmdLine <= ' ' ) - lpCmdLine++; - if( !*lpCmdLine ) break; - - if( *lpCmdLine == '\"' ) - { - // quoted string - lpCmdLine++; - Sys.argv[Sys.argc] = lpCmdLine; - Sys.argc++; - while( *lpCmdLine && ( *lpCmdLine != '\"' )) - lpCmdLine++; - } - else - { - // unquoted word - Sys.argv[Sys.argc] = lpCmdLine; - Sys.argc++; - while( *lpCmdLine && *lpCmdLine > ' ') - lpCmdLine++; - } - - if( *lpCmdLine ) - { - *lpCmdLine = 0; - lpCmdLine++; - } - } - -} - -/* -================== -Sys_MergeCommandLine - -================== -*/ -void Sys_MergeCommandLine( LPSTR lpCmdLine ) -{ - const char *blank = "censored"; - int i; - - for( i = 0; i < Sys.argc; i++ ) - { - // we wan't return to first game - if( !stricmp( "-game", Sys.argv[i] )) Sys.argv[i] = (char *)blank; - // probably it's timewaster, because engine rejected second change - if( !stricmp( "+game", Sys.argv[i] )) Sys.argv[i] = (char *)blank; - // you sure what is map exists in new game? - if( !stricmp( "+map", Sys.argv[i] )) Sys.argv[i] = (char *)blank; - // just stupid action - if( !stricmp( "+load", Sys.argv[i] )) Sys.argv[i] = (char *)blank; - // changelevel beetwen games? wow it's great idea! - if( !stricmp( "+changelevel", Sys.argv[i] )) Sys.argv[i] = (char *)blank; - - // second call - if( Sys.app_name == HOST_DEDICATED && !strnicmp( "+menu_", Sys.argv[i], 6 )) - Sys.argv[i] = (char *)blank; - } -} - -/* -================ -Sys_Print - -print into window console -================ -*/ -void Sys_Print( const char *pMsg ) -{ - const char *msg; - char buffer[32768]; - char logbuf[32768]; - char *b = buffer; - char *c = logbuf; - int i = 0; - - if( Sys.con_silentmode ) return; - if( Sys.CPrint && Sys.app_name == HOST_NORMAL ) - Sys.CPrint( pMsg ); - - // if the message is REALLY long, use just the last portion of it - if( strlen( pMsg ) > sizeof( buffer ) - 1 ) - msg = pMsg + strlen( pMsg ) - sizeof( buffer ) + 1; - else msg = pMsg; - - // copy into an intermediate buffer - while( msg[i] && (( b - buffer ) < sizeof( buffer ) - 1 )) - { - 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 - { - *b = *c = msg[i]; - b++, c++; - } - i++; - } - - *b = *c = 0; // cutoff garbage - - // because we needs to kill any psedo graph symbols - // and color strings for other instances - if( Sys.CPrint && Sys.app_name != HOST_NORMAL ) - Sys.CPrint( logbuf ); - - Sys_PrintLog( logbuf ); - Con_Print( buffer ); -} - -/* -================ -Sys_Msg - -formatted message -================ -*/ -void Sys_Msg( const char *pMsg, ... ) -{ - va_list argptr; - char text[8192]; - - va_start( argptr, pMsg ); - _vsnprintf( text, sizeof( text ), pMsg, argptr ); - va_end( argptr ); - - Sys_Print( text ); -} - -void Sys_MsgDev( int level, const char *pMsg, ... ) -{ - va_list argptr; - char text[8192]; - - if( Sys.developer < level ) return; - - va_start( argptr, pMsg ); - _vsnprintf( text, sizeof( text ), pMsg, argptr ); - va_end( argptr ); - - switch( level ) - { - case D_WARN: - Sys_Print( va( "^3Warning:^7 %s", text )); - break; - case D_ERROR: - Sys_Print( va( "^1Error:^7 %s", text )); - break; - case D_INFO: - case D_NOTE: - case D_AICONSOLE: - Sys_Print( text ); - break; - } -} - -/* -================ -Sys_DoubleTime -================ -*/ -double Sys_DoubleTime( void ) -{ - static LARGE_INTEGER g_PerformanceFrequency; - static LARGE_INTEGER g_ClockStart; - LARGE_INTEGER CurrentTime; - - if( !g_PerformanceFrequency.QuadPart ) - { - QueryPerformanceFrequency( &g_PerformanceFrequency ); - QueryPerformanceCounter( &g_ClockStart ); - } - QueryPerformanceCounter( &CurrentTime ); - - return (double)( CurrentTime.QuadPart - g_ClockStart.QuadPart ) / (double)( g_PerformanceFrequency.QuadPart ); -} - -/* -================ -Sys_CheckParm - -Returns the position (1 to argc-1) in the program's argument list -where the given parameter apears, or 0 if not present -================ -*/ -int Sys_CheckParm( const char *parm ) -{ - int i; - - for( i = 1; i < Sys.argc; i++ ) - { - // NEXTSTEP sometimes clears appkit vars. - if( !Sys.argv[i] ) continue; - if( !stricmp( parm, Sys.argv[i] )) return i; - } - return 0; -} - -/* -================ -Sys_GetParmFromCmdLine - -Returns the argument for specified parm -================ -*/ -qboolean Sys_GetParmFromCmdLine( char *parm, char *out, size_t size ) -{ - int argc = Sys_CheckParm( parm ); - - if( !argc ) return false; - if( !out ) return false; - if( !Sys.argv[argc + 1] ) return false; - - strncpy( out, Sys.argv[argc+1], size ); - return true; -} - -/* -================ -Sys_Sleep - -freeze application for some time -================ -*/ -void Sys_Sleep( int msec ) -{ - msec = bound( 1, msec, 1000 ); - Sleep( msec ); -} - -/* -================ -Sys_WaitForQuit - -wait for 'Esc' key will be hit -================ -*/ -void Sys_WaitForQuit( void ) -{ - MSG msg; - - Con_RegisterHotkeys(); - - msg.message = 0; - - // wait for the user to quit - while( msg.message != WM_QUIT ) - { - if( PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) - { - TranslateMessage( &msg ); - DispatchMessage( &msg ); - } - else Sys_Sleep( 20 ); - } -} - -/* -================ -Sys_Error - -NOTE: we must prepare engine to shutdown -before call this -================ -*/ -void Sys_Error( const char *error, ... ) -{ - va_list argptr; - char text[MAX_SYSPATH]; - - if( Sys.app_state == SYS_ERROR ) - return; // don't multiple executes - - // make sure what console received last message - // stupid windows bug :( - if( Sys.app_state == SYS_RESTART ) - Sys_Sleep( 200 ); - - Sys.error = true; - Sys.app_state = SYS_ERROR; - va_start( argptr, error ); - vsprintf( text, error, argptr ); - va_end( argptr ); - - if( Sys.app_name == HOST_NORMAL ) - Sys.Free(); // kill video - - if( Sys.developer > 0 ) - { - Con_ShowConsole( true ); - Con_DisableInput(); // disable input line for dedicated server - Sys_Print( text ); // print error message - Sys_WaitForQuit(); - } - else - { - Con_ShowConsole( false ); - MSGBOX( text ); - } - Sys_Exit(); -} - -void Sys_Break( const char *error, ... ) -{ - va_list argptr; - char text[MAX_SYSPATH]; - - if( Sys.app_state == SYS_ERROR ) - return; // don't multiple executes - - va_start( argptr, error ); - vsprintf( text, error, argptr ); - va_end( argptr ); - - Sys.error = true; - Sys.app_state = SYS_ERROR; - - if( Sys.app_name == HOST_NORMAL ) - Sys.Free(); // kill video - - if( Sys.con_readonly && ( Sys.developer > 0 || Sys.app_name != HOST_NORMAL )) - { - Con_ShowConsole( true ); - Sys_Print( text ); - Sys_WaitForQuit(); - } - else - { - Con_ShowConsole( false ); - MSGBOX( text ); - } - Sys_Exit(); -} - -long _stdcall Sys_Crash( PEXCEPTION_POINTERS pInfo ) -{ - // save config - if( Sys.app_state != SYS_CRASH ) - { - // check to avoid recursive call - Sys.error = true; - Sys.app_state = SYS_CRASH; - - if( Sys.app_name == HOST_NORMAL && Sys.Crashed ) Sys.Crashed(); // tell client about crash - Msg( "Sys_Crash: call %p at address %p\n", pInfo->ExceptionRecord->ExceptionAddress, pInfo->ExceptionRecord->ExceptionCode ); - - if( Sys.developer <= 0 ) - { - // no reason to call debugger in release build - just exit - Sys_Exit(); - return EXCEPTION_CONTINUE_EXECUTION; - } - - // all other states keep unchanged to let debugger find bug - Con_DestroyConsole(); - } - - if( Sys.oldFilter ) - return Sys.oldFilter( pInfo ); - return EXCEPTION_CONTINUE_EXECUTION; -} - -void Sys_Init( void ) -{ - MEMORYSTATUS lpBuffer; - char dev_level[4]; - - lpBuffer.dwLength = sizeof( MEMORYSTATUS ); - GlobalMemoryStatus( &lpBuffer ); - Sys.logfile = NULL; - - // get current hInstance - Sys.hInstance = (HINSTANCE)GetModuleHandle( NULL ); - Sys.developer = 0; - - Sys_GetStdAPI(); - Sys.Init = NullInit; - Sys.Main = NullFunc; - Sys.Free = NullFunc; - Sys.CPrint = NullPrint; - - Sys.oldFilter = SetUnhandledExceptionFilter( Sys_Crash ); - - // some commands may turn engine into infinity loop, - // e.g. xash.exe +game xash -game xash - // so we clearing all cmd_args, but leave dbg states as well - if( Sys.app_state != SYS_RESTART ) - Sys_ParseCommandLine( GetCommandLine()); - else Sys_MergeCommandLine( GetCommandLine()); - - // parse and copy args into local array - if( Sys_CheckParm( "-log" )) Sys.log_active = true; - if( Sys_CheckParm( "-console" )) Sys.developer = 1; - if( Sys_CheckParm( "-dev" )) - { - if( Sys_GetParmFromCmdLine( "-dev", dev_level, sizeof( dev_level ))) - { - if( isdigit( dev_level[0] )) - Sys.developer = abs( atoi( dev_level )); - else Sys.developer++; // -dev == 1, -dev -console == 2 - } - else Sys.developer++; // -dev == 1, -dev -console == 2 - } - - if( Sys.log_active && !Sys.developer ) - Sys.log_active = false; // nothing to logging :) - - SetErrorMode( SEM_FAILCRITICALERRORS ); // no abort/retry/fail errors - - // set default state - Sys.con_showalways = Sys.con_readonly = true; - Sys.con_showcredits = Sys.con_silentmode = false; - - Sys_LookupInstance(); // init launcher - Con_CreateConsole(); - - // second pass (known state) - if( Sys.app_state == SYS_RESTART ) - Sys_MergeCommandLine( GetCommandLine()); - - // first text message into console or log - MsgDev( D_NOTE, "Sys_LoadLibrary: Loading launch.dll - ok\n" ); - - if( strlen( Sys.fmessage ) && !Sys.con_showcredits ) - { - Sys_Print( Sys.fmessage ); - Sys.fmessage[0] = '\0'; - } - - SI.developer = Sys.developer; - Sys_CreateInstance(); -} - -void Sys_Shutdown( void ) -{ - // prepare host to close - Sys.Free(); - Sys_FreeLibrary( Sys.linked_dll ); - Sys.CPrint = NullPrint; - - Con_DestroyConsole(); - - // restore filter - if( Sys.oldFilter ) - { - SetUnhandledExceptionFilter( Sys.oldFilter ); - } -} - -/* -================ -Sys_Exit - -NOTE: we must prepare engine to shutdown -before call this -================ -*/ -void Sys_Exit( void ) -{ - if( Sys.shutdown_issued ) return; - Sys.shutdown_issued = true; - - if( Sys.app_state != SYS_ERROR ) - Sys.app_state = SYS_SHUTDOWN; - - Sys_Shutdown(); - exit( Sys.error ); -} - -//======================================================================= -// DLL'S MANAGER SYSTEM -//======================================================================= -qboolean Sys_LoadLibrary( const char *dll_name, dll_info_t *dll ) -{ - const dllfunc_t *func; - qboolean native_lib = false; - string errorstring; - - // check errors - if( !dll ) return false; // invalid desc - if( dll->link ) return true; // already loaded - - // check and replace names - if( dll_name && *dll_name ) dll->name = dll_name; - if( !dll->name || !*dll->name ) return false; // nothing to load - - MsgDev( D_NOTE, "Sys_LoadLibrary: Loading %s", dll->name ); - - if( dll->fcts ) - { - // lookup export table - for( func = dll->fcts; func && func->name != NULL; func++ ) - *func->func = NULL; - } - else if( dll->entry ) native_lib = true; - - if( !dll->link ) dll->link = LoadLibrary ( dll->name ); // environment pathes - - // no DLL found - if( !dll->link ) - { - sprintf( errorstring, "Sys_LoadLibrary: couldn't load %s\n", dll->name ); - goto error; - } - - if( native_lib ) - { - if(( dll->main = Sys_GetProcAddress( dll, dll->entry )) == 0 ) - { - sprintf( errorstring, "Sys_LoadLibrary: %s has no valid entry point\n", dll->name ); - goto error; - } - } - else - { - // Get the function adresses - for( func = dll->fcts; func && func->name != NULL; func++ ) - { - if( !( *func->func = Sys_GetProcAddress( dll, func->name ))) - { - sprintf( errorstring, "Sys_LoadLibrary: %s missing or invalid function (%s)\n", dll->name, func->name ); - goto error; - } - } - } - - if( native_lib ) - { - generic_api_t *check = NULL; - - // NOTE: native dlls must support null import! - // e.g. see ..\engine\engine.c for details - check = (void *)dll->main( &com, NULL ); // first iface always stdlib_api_t - - if( !check ) - { - sprintf( errorstring, "Sys_LoadLibrary: \"%s\" have no export\n", dll->name ); - goto error; - } - if( check->api_size != dll->api_size ) - { - sprintf( errorstring, "Sys_LoadLibrary: \"%s\" mismatch interface size (%i should be %i)\n", dll->name, check->api_size, dll->api_size ); - goto error; - } - if( check->com_size != dll->com_size ) - { - sprintf( errorstring, "Sys_LoadLibrary: \"%s\" mismatch stdlib api size (%i should be %i)\n", dll->name, check->com_size, dll->com_size); - goto error; - } - } - MsgDev( D_NOTE, " - ok\n" ); - - return true; -error: - MsgDev( D_NOTE, " - failed\n" ); - Sys_FreeLibrary( dll ); // trying to free - if( dll->crash ) Sys_Error( errorstring ); - else MsgDev( D_ERROR, errorstring ); - - return false; -} - -void* Sys_GetProcAddress( dll_info_t *dll, const char* name ) -{ - if( !dll || !dll->link ) // invalid desc - return NULL; - - return (void *)GetProcAddress( dll->link, name ); -} - -qboolean Sys_FreeLibrary( dll_info_t *dll ) -{ - // invalid desc or alredy freed - if( !dll || !dll->link ) - return false; - - if( Sys.app_state == SYS_CRASH ) - { - // we need to hold down all modules, while MSVC can find error - MsgDev( D_NOTE, "Sys_FreeLibrary: hold %s for debugging\n", dll->name ); - return false; - } - else MsgDev( D_NOTE, "Sys_FreeLibrary: Unloading %s\n", dll->name ); - FreeLibrary( dll->link ); - dll->link = NULL; - - return true; -} - -/* -================ -Sys_NewInstance - -restarted engine with new instance -e.g. for change game or fallback to dedicated mode -================ -*/ -void Sys_NewInstance( const char *name, const char *fmsg ) -{ - string tmp; - - // save parms - strncpy( tmp, name, sizeof( tmp )); - strncpy( Sys.fmessage, fmsg, sizeof( Sys.fmessage )); - Sys.app_state = SYS_RESTART; // set right state - Sys_Shutdown(); // shutdown current instance - - // restore parms here - strncpy( SI.ModuleName, tmp, sizeof( SI.ModuleName )); - - // NOTE: we never return to old instance, - // because Sys_Exit call exit(0); and terminate program - Sys_Init(); - Sys.Main(); - Sys_Exit(); -} - -// main DLL entry point -BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved ) -{ - return TRUE; -} - -/* -================= -Main Entry Point -================= -*/ -EXPORT int CreateAPI( const char *hostname, qboolean console ) -{ - strncpy( Sys.progname, hostname, sizeof( Sys.progname )); - - Sys_Init(); - Sys.Main(); - Sys_Exit(); - - return 0; -} \ No newline at end of file diff --git a/release.bat b/release.bat index 4dd4cfb2..7bde77f3 100644 --- a/release.bat +++ b/release.bat @@ -20,9 +20,6 @@ if errorlevel 1 set BUILD_ERROR=1 %MSDEV% mainui/mainui.dsp %CONFIG%"mainui - Win32 Release" %build_target% if errorlevel 1 set BUILD_ERROR=1 -%MSDEV% launch/launch.dsp %CONFIG%"launch - Win32 Release" %build_target% -if errorlevel 1 set BUILD_ERROR=1 - %MSDEV% room/room.dsp %CONFIG%"room - Win32 Release" %build_target% if errorlevel 1 set BUILD_ERROR=1 diff --git a/xash.dsw b/xash.dsw index 685bf5f5..1aa45c67 100644 --- a/xash.dsw +++ b/xash.dsw @@ -51,18 +51,6 @@ Package=<4> ############################################################################### -Project: "launch"=".\launch\launch.dsp" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - Project: "room"=".\room\room.dsp" - Package Owner=<4> Package=<5>