13 Mar 2011

This commit is contained in:
g-cont 2011-03-13 00:00:00 +03:00 committed by Alibek Omarov
parent 3bb78ced21
commit 62f7ad7bb1
35 changed files with 959 additions and 1792 deletions

View File

@ -27,7 +27,6 @@ engine\server\
engine\common\
engine\common\imagelib\
engine\common\soundlib\
launch\
pm_shared\
mainui\
mainui\legacy

View File

@ -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

View File

@ -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;

View File

@ -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" );
}
/*

View File

@ -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;
}

View File

@ -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 );

View File

@ -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 ));
}

View File

@ -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
{

View File

@ -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

View File

@ -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;

View File

@ -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 )

View File

@ -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) )
{

View File

@ -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 );

View File

@ -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;
}

View File

@ -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 );
}
/*

View File

@ -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 );

View File

@ -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;
}

View File

@ -4,6 +4,7 @@
//=======================================================================
#include "imagelib.h"
#include "mathlib.h"
convar_t *gl_round_down;

View File

@ -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 );

View File

@ -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 );

View File

@ -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 );
}

View File

@ -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;
}
}

View File

@ -6,11 +6,17 @@
#ifndef SYSTEM_H
#define SYSTEM_H
#ifdef __cplusplus
extern "C" {
#endif
#include <setjmp.h>
#include <stdio.h>
#include <time.h>
#include <windows.h>
#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

View File

@ -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 )

View File

@ -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

View File

@ -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 ));
}
}

View File

@ -5,16 +5,16 @@
#include <windows.h>
// 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 );
}

View File

@ -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"

View File

@ -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

View File

@ -1,152 +0,0 @@
//=======================================================================
// Copyright XashXT Group 2007 ©
// launch.h - launch.dll main header
//=======================================================================
#ifndef LAUNCHER_H
#define LAUNCHER_H
#include <limits.h>
#include <fcntl.h>
#include <direct.h>
#include <sys/stat.h>
#include <windows.h>
#include <stdio.h>
#include <io.h>
#include <time.h>
#include <winreg.h>
#include <math.h>
#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

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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

View File

@ -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>