12 Mar 2011

This commit is contained in:
g-cont 2011-03-12 00:00:00 +03:00 committed by Alibek Omarov
parent 50b167110b
commit 3bb78ced21
26 changed files with 785 additions and 2822 deletions

View File

@ -694,7 +694,7 @@ pfnMemAlloc
*/
static void *pfnMemAlloc( size_t cb, const char *filename, const int fileline )
{
return com.malloc( menu.mempool, cb, filename, fileline );
return _Mem_Alloc( menu.mempool, cb, filename, fileline );
}
/*
@ -705,7 +705,7 @@ pfnMemFree
*/
static void pfnMemFree( void *mem, const char *filename, const int fileline )
{
com.free( mem, filename, fileline );
_Mem_Free( mem, filename, fileline );
}
/*

View File

@ -439,7 +439,7 @@ static dllfunc_t wgl3DFXgammacontrolfuncs[] =
{ NULL, NULL }
};
dll_info_t opengl_dll = { "opengl32.dll", wgl_funcs, NULL, NULL, NULL, true };
dll_info_t opengl_dll = { "opengl32.dll", wgl_funcs, true };
/*
=================
@ -1239,7 +1239,7 @@ R_Init_OpenGL
*/
qboolean R_Init_OpenGL( void )
{
Sys_LoadLibrary( NULL, &opengl_dll ); // load opengl32.dll
Sys_LoadLibrary( &opengl_dll ); // load opengl32.dll
if( !opengl_dll.link ) return false;
// TODO: allow 3dfx drivers too

View File

@ -17,7 +17,7 @@ static dllfunc_t dsound_funcs[] =
{ NULL, NULL }
};
dll_info_t dsound_dll = { "dsound.dll", dsound_funcs, NULL, NULL, NULL, false, 0, 0 };
dll_info_t dsound_dll = { "dsound.dll", dsound_funcs, false };
#define SAMPLE_16BIT_SHIFT 1
#define SECONDARY_BUFFER_SIZE 0x10000
@ -285,7 +285,7 @@ si_state_t SNDDMA_InitDirect( void *hInst )
if( !dsound_dll.link )
{
if( !Sys_LoadLibrary( NULL, &dsound_dll ))
if( !Sys_LoadLibrary( &dsound_dll ))
return SIS_FAILURE;
}

View File

@ -15,7 +15,7 @@ int ipset_room_prev;
int ipset_room_typeprev;
int idsp_room;
static DSP_FUNCTIONS gDspFuncs;
static dll_info_t room_dll = { "room.dll", NULL, NULL, NULL, NULL, false };
static dll_info_t room_dll = { "room.dll", NULL, false };
// engine callbacks
static dsp_enginefuncs_t gEngfuncs =
@ -73,7 +73,7 @@ qboolean AllocDsps( void )
static ROOMAPI InitDSP;
static dsp_enginefuncs_t gpEngfuncs;
if( !Sys_LoadLibrary( NULL, &room_dll ))
if( !Sys_LoadLibrary( &room_dll ))
{
MsgDev( D_INFO, "DSP: disabled\n" );
return false;

View File

@ -20,7 +20,7 @@ static dllfunc_t msvfw_funcs[] =
{ NULL, NULL }
};
dll_info_t msvfw_dll = { "msvfw32.dll", msvfw_funcs, NULL, NULL, NULL, false };
dll_info_t msvfw_dll = { "msvfw32.dll", msvfw_funcs, false };
// msacm32.dll exports
static MMRESULT (_stdcall *pacmStreamOpen)( LPHACMSTREAM, HACMDRIVER, LPWAVEFORMATEX, LPWAVEFORMATEX, LPWAVEFILTER, DWORD, DWORD, DWORD );
@ -41,7 +41,7 @@ static dllfunc_t msacm_funcs[] =
{ NULL, NULL }
};
dll_info_t msacm_dll = { "msacm32.dll", msacm_funcs, NULL, NULL, NULL, false };
dll_info_t msacm_dll = { "msacm32.dll", msacm_funcs, false };
// avifil32.dll exports
static int (_stdcall *pAVIStreamInfo)( PAVISTREAM pavi, AVISTREAMINFO *psi, LONG lSize );
@ -76,7 +76,7 @@ static dllfunc_t avifile_funcs[] =
{ NULL, NULL }
};
dll_info_t avifile_dll = { "avifil32.dll", avifile_funcs, NULL, NULL, NULL, false };
dll_info_t avifile_dll = { "avifil32.dll", avifile_funcs, false };
typedef struct movie_state_s
{
@ -625,20 +625,20 @@ movie_state_t *AVI_GetState( int num )
qboolean AVI_Initailize( void )
{
if( !Sys_LoadLibrary( NULL, &avifile_dll ))
if( !Sys_LoadLibrary( &avifile_dll ))
{
MsgDev( D_ERROR, "AVI_Initailize: failed\n" );
return false;
}
if( !Sys_LoadLibrary( NULL, &msvfw_dll ))
if( !Sys_LoadLibrary( &msvfw_dll ))
{
MsgDev( D_ERROR, "AVI_Initailize: failed\n" );
Sys_FreeLibrary( &avifile_dll );
return false;
}
if( !Sys_LoadLibrary( NULL, &msacm_dll ))
if( !Sys_LoadLibrary( &msacm_dll ))
{
MsgDev( D_ERROR, "AVI_Initailize: failed\n" );
Sys_FreeLibrary( &avifile_dll );

View File

@ -150,7 +150,7 @@ char *_copystring( byte *mempool, const char *s, const char *filename, int filel
if( !s ) return NULL;
if( !mempool ) mempool = host.mempool;
b = com.malloc( mempool, Q_strlen( s ) + 1, filename, fileline );
b = _Mem_Alloc( mempool, Q_strlen( s ) + 1, filename, fileline );
Q_strcpy( b, s );
return b;
@ -963,4 +963,6 @@ void CRT_Init( void )
_Q_memcpy = crt_memcpy;
_Q_memset = crt_memset;
}
Memory_Init();
}

View File

@ -150,6 +150,35 @@ char *va( const char *format, ... );
void (*_Q_memcpy)( void *dest, const void *src, size_t size, const char *filename, int fileline );
void (*_Q_memset)( void *dest, int set, size_t size, const char *filename, int fileline );
//
// zone.c
//
//
// memlib.c
//
void Memory_Init( void );
void _Mem_Move( byte *poolptr, void **dest, void *src, size_t size, const char *filename, int fileline );
void *_Mem_Realloc( byte *poolptr, void *memptr, size_t size, const char *filename, int fileline );
void *_Mem_Alloc( byte *poolptr, size_t size, const char *filename, int fileline );
byte *_Mem_AllocPool( const char *name, const char *filename, int fileline );
void _Mem_FreePool( byte **poolptr, const char *filename, int fileline );
void _Mem_EmptyPool( byte *poolptr, const char *filename, int fileline );
void _Mem_Free( void *data, const char *filename, int fileline );
void _Mem_Check( const char *filename, int fileline );
qboolean Mem_IsAllocatedExt( byte *poolptr, void *data );
void Mem_PrintList( size_t minallocationsize );
void Mem_PrintStats( void );
#define Mem_Alloc( pool, size ) _Mem_Alloc( pool, size, __FILE__, __LINE__ )
#define Mem_Realloc( pool, ptr, size ) _Mem_Realloc( pool, ptr, size, __FILE__, __LINE__ )
#define Mem_Free( mem ) _Mem_Free( mem, __FILE__, __LINE__ )
#define Mem_AllocPool( name ) _Mem_AllocPool( name, __FILE__, __LINE__ )
#define Mem_FreePool( pool ) _Mem_FreePool( pool, __FILE__, __LINE__ )
#define Mem_EmptyPool( pool ) _Mem_EmptyPool( pool, __FILE__, __LINE__ )
#define Mem_Move( pool, dest, src, size ) _Mem_Move( pool, dest, src, size, __FILE__, __LINE__ )
#define Mem_IsAllocated( mem ) Mem_IsAllocatedExt( NULL, mem )
#define Mem_Check() _Mem_Check( __FILE__, __LINE__ )
void CRT_Init( void ); // must be call first
#endif//STDLIB_H

View File

@ -16,10 +16,10 @@ Cvar_InfoValidate
static qboolean Cvar_ValidateString( const char *s, qboolean isvalue )
{
if( !s ) return false;
if( com.strstr( s, "\\" ) && !isvalue )
if( Q_strstr( s, "\\" ) && !isvalue )
return false;
if( com.strstr( s, "\"" )) return false;
if( com.strstr( s, ";" )) return false;
if( Q_strstr( s, "\"" )) return false;
if( Q_strstr( s, ";" )) return false;
return true;
}
@ -34,7 +34,7 @@ convar_t *Cvar_FindVar( const char *var_name )
for( var = cvar_vars; var; var = var->next )
{
if( !com.stricmp( var_name, var->name ))
if( !Q_stricmp( var_name, var->name ))
return var;
}
return NULL;
@ -210,8 +210,8 @@ convar_t *Cvar_Get( const char *var_name, const char *var_value, int flags, cons
var->string = copystring( var_value );
var->reset_string = copystring( var_value );
if( var_desc ) var->description = copystring( var_desc );
var->value = com.atof( var->string );
var->integer = com.atoi( var->string );
var->value = Q_atof( var->string );
var->integer = Q_atoi( var->string );
var->modified = true;
var->flags = flags;
@ -277,7 +277,7 @@ void Cvar_RegisterVariable( cvar_t *var )
}
var->string = cur->string; // we already have right string
var->value = com.atof( var->string );
var->value = Q_atof( var->string );
var->flags |= CVAR_EXTDLL; // all cvars passed this function are game cvars
var->next = (cvar_t *)cur->next;
@ -292,7 +292,7 @@ void Cvar_RegisterVariable( cvar_t *var )
{
// copy the value off, because future sets will Z_Free it
var->string = copystring( var->string );
var->value = com.atof( var->string );
var->value = Q_atof( var->string );
var->flags |= CVAR_EXTDLL; // all cvars passed this function are game cvars
// link the variable in
@ -338,7 +338,7 @@ convar_t *Cvar_Set2( const char *var_name, const char *value, qboolean force )
else value = var->reset_string;
}
if( !com.strcmp( value, var->string ))
if( !Q_strcmp( value, var->string ))
return var;
// any latched values not allowed for game cvars
@ -362,13 +362,13 @@ convar_t *Cvar_Set2( const char *var_name, const char *value, qboolean force )
{
if( var->latched_string )
{
if(!com.strcmp( value, var->latched_string ))
if(!Q_strcmp( value, var->latched_string ))
return var;
Mem_Free( var->latched_string );
}
else
{
if( !com.strcmp( value, var->string ))
if( !Q_strcmp( value, var->string ))
return var;
}
@ -386,8 +386,8 @@ convar_t *Cvar_Set2( const char *var_name, const char *value, qboolean force )
{
Mem_Free( var->string ); // free the old value string
var->string = copystring( value );
var->value = com.atof( var->string );
var->integer = com.atoi( var->string );
var->value = Q_atof( var->string );
var->integer = Q_atoi( var->string );
}
var->modified = true;
@ -440,9 +440,9 @@ convar_t *Cvar_Set2( const char *var_name, const char *value, qboolean force )
*pD = '\0';
// if it's empty, then insert a marker string
if( !com.strlen( szNew ))
if( !Q_strlen( szNew ))
{
com.strcpy( szNew, "default" );
Q_strcpy( szNew, "default" );
}
// point the value here.
@ -450,7 +450,7 @@ convar_t *Cvar_Set2( const char *var_name, const char *value, qboolean force )
}
// nothing to change
if( !com.strcmp( pszValue, var->string ))
if( !Q_strcmp( pszValue, var->string ))
return var;
if( var->flags & CVAR_USERINFO )
@ -468,11 +468,11 @@ convar_t *Cvar_Set2( const char *var_name, const char *value, qboolean force )
// free the old value string
Mem_Free( var->string );
var->string = copystring( pszValue );
var->value = com.atof( var->string );
var->value = Q_atof( var->string );
if( !dll_variable )
{
var->integer = com.atoi( var->string );
var->integer = Q_atoi( var->string );
var->modified = true;
}
@ -550,12 +550,12 @@ void Cvar_FullSet( const char *var_name, const char *value, int flags )
Mem_Free( var->string ); // free the old value string
var->string = copystring( value );
var->value = com.atof( var->string );
var->value = Q_atof( var->string );
var->flags = flags;
if( dll_variable ) return; // below field doesn't exist in cvar_t
var->integer = com.atoi( var->string );
var->integer = Q_atoi( var->string );
var->modified = true;
}
@ -627,16 +627,16 @@ void Cvar_DirectSet( cvar_t *var, const char *value )
*pD = '\0';
// if it's empty, then insert a marker string
if( !com.strlen( szNew ))
if( !Q_strlen( szNew ))
{
com.strcpy( szNew, "default" );
Q_strcpy( szNew, "default" );
}
// point the value here.
pszValue = szNew;
}
if( !com.strcmp( pszValue, var->string ))
if( !Q_strcmp( pszValue, var->string ))
return;
if( var->flags & CVAR_USERINFO )
@ -654,7 +654,7 @@ void Cvar_DirectSet( cvar_t *var, const char *value )
// free the old value string
Mem_Free( var->string );
var->string = copystring( pszValue );
var->value = com.atof( var->string );
var->value = Q_atof( var->string );
}
/*
@ -667,8 +667,8 @@ void Cvar_SetFloat( const char *var_name, float value )
char val[32];
if( value == (int)value )
com.sprintf( val, "%i", (int)value );
else com.sprintf( val, "%f", value );
Q_sprintf( val, "%i", (int)value );
else Q_sprintf( val, "%f", value );
Cvar_Set( var_name, val );
}
@ -705,7 +705,7 @@ void Cvar_SetCheatState( void )
Mem_Free( var->latched_string );
var->latched_string = NULL;
}
if( com.strcmp( var->reset_string, var->string ))
if( Q_strcmp( var->reset_string, var->string ))
{
Cvar_Set( var->name, var->reset_string );
}
@ -787,11 +787,11 @@ void Cvar_Set_f( void )
for( i = 2; i < c; i++ )
{
len = com.strlen( Cmd_Argv(i) + 1 );
len = Q_strlen( Cmd_Argv(i) + 1 );
if ( l + len >= MAX_CMD_TOKENS - 2 )
break;
com.strcat( combined, Cmd_Argv(i));
if ( i != c-1 ) com.strcat( combined, " " );
Q_strcat( combined, Cmd_Argv(i));
if ( i != c-1 ) Q_strcat( combined, " " );
l += len;
}
@ -960,7 +960,7 @@ void Cvar_List_f( void )
for( var = cvar_vars; var; var = var->next, i++ )
{
if( match && !com.stricmpext( match, var->name ))
if( match && !Q_stricmpext( match, var->name ))
continue;
if( var->flags & CVAR_SERVERINFO ) Msg( "SV " );

View File

@ -227,7 +227,7 @@ void *Cache_Check( byte *mempool, cache_user_t *c )
if( !c->data )
return NULL;
if( !Mem_IsAllocated( mempool, c->data ))
if( !Mem_IsAllocatedExt( mempool, c->data ))
return NULL;
return c->data;

View File

@ -2228,7 +2228,7 @@ file_t *FS_OpenFile( const char *path, fs_offset_t *filesizeptr, qboolean gamedi
void FS_FreeFile( void *buffer )
{
if( buffer && Mem_IsAllocated( fs_mempool, buffer ))
if( buffer && Mem_IsAllocatedExt( fs_mempool, buffer ))
Mem_Free( buffer );
}

View File

@ -580,7 +580,7 @@ void Host_InitCommon( const int argc, const char **argv )
Cvar_Init();
// share developer level across all dlls
com.snprintf( dev_level, sizeof( dev_level ), "%i", host.developer );
Q_snprintf( dev_level, sizeof( dev_level ), "%i", host.developer );
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" );

View File

@ -62,7 +62,7 @@ static dllfunc_t winsock_funcs[] =
{ NULL, NULL }
};
dll_info_t winsock_dll = { "wsock32.dll", winsock_funcs, NULL, NULL, NULL, false };
dll_info_t winsock_dll = { "wsock32.dll", winsock_funcs, false };
typedef struct
{
@ -92,7 +92,7 @@ qboolean NET_OpenWinSock( void )
{
// initialize the Winsock function vectors (we do this instead of statically linking
// so we can run on Win 3.1, where there isn't necessarily Winsock)
if( Sys_LoadLibrary( NULL, &winsock_dll ))
if( Sys_LoadLibrary( &winsock_dll ))
return true;
return false;
}

View File

@ -180,7 +180,7 @@ void Sys_QueEvent( ev_type_t type, int value, int value2, int length, void *ptr
MsgDev( D_ERROR, "Sys_QueEvent: overflow\n");
// make sure what memory is allocated by engine
if( Mem_IsAllocated( host.mempool, ev->data ))
if( Mem_IsAllocatedExt( host.mempool, ev->data ))
Mem_Free( ev->data );
event_tail++;
}
@ -248,4 +248,85 @@ sys_event_t Sys_GetEvent( void )
Q_memset( &ev, 0, sizeof( ev ));
return ev;
}
//=======================================================================
// DLL'S MANAGER SYSTEM
//=======================================================================
qboolean Sys_LoadLibrary( dll_info_t *dll )
{
const dllfunc_t *func;
string errorstring;
// check errors
if( !dll ) return false; // invalid desc
if( dll->link ) return true; // already loaded
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;
}
if( !dll->link ) dll->link = LoadLibrary ( dll->name ); // environment pathes
// no DLL found
if( !dll->link )
{
Q_snprintf( errorstring, sizeof( errorstring ), "Sys_LoadLibrary: couldn't load %s\n", dll->name );
goto error;
}
// Get the function adresses
for( func = dll->fcts; func && func->name != NULL; func++ )
{
if( !( *func->func = Sys_GetProcAddress( dll, func->name )))
{
Q_snprintf( errorstring, sizeof( errorstring ), "Sys_LoadLibrary: %s missing or invalid function (%s)\n", dll->name, func->name );
goto error;
}
}
MsgDev( D_NOTE, " - ok\n" );
return true;
error:
MsgDev( D_NOTE, " - failed\n" );
Sys_FreeLibrary( dll ); // trying to free
if( dll->crash ) com.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( host.state == HOST_CRASHED )
{
// 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;
}

View File

@ -50,10 +50,36 @@ typedef struct
size_t length;
} sys_event_t;
/*
========================================================================
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 dllfunc_s
{
const char *name;
void **func;
} dllfunc_t;
typedef struct dll_info_s
{
const char *name; // name of library
const dllfunc_t *fcts; // list of dll exports
qboolean crash; // crash if dll not found
void *link; // hinstance of loading library
} dll_info_t;
void Sys_Sleep( int msec );
double Sys_DoubleTime( void );
char *Sys_GetClipboardData( void );
char *Sys_GetCurrentUser( void );
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_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 );

493
engine/common/zone.c Normal file
View File

@ -0,0 +1,493 @@
//=======================================================================
// Copyright XashXT Group 2007 ©
// zone.c - zone memory allocation from DarkPlaces
//=======================================================================
#include "common.h"
#define MEMCLUMPSIZE (65536 - 1536) // give malloc padding so we can't waste most of a page at the end
#define MEMUNIT 8 // smallest unit we care about is this many bytes
#define MEMBITS (MEMCLUMPSIZE / MEMUNIT)
#define MEMBITINTS (MEMBITS / 32)
#define MEMCLUMP_SENTINEL 0xABADCAFE
#define MEMHEADER_SENTINEL1 0xDEADF00D
#define MEMHEADER_SENTINEL2 0xDF
typedef struct memheader_s
{
struct memheader_s *next; // next and previous memheaders in chain belonging to pool
struct memheader_s *prev;
struct mempool_s *pool; // pool this memheader belongs to
struct memclump_s *clump; // clump this memheader lives in, NULL if not in a clump
size_t size; // size of the memory after the header (excluding header and sentinel2)
const char *filename; // file name and line where Mem_Alloc was called
uint fileline;
uint sentinel1; // should always be MEMHEADER_SENTINEL1
// immediately followed by data, which is followed by a MEMHEADER_SENTINEL2 byte
} memheader_t;
typedef struct memclump_s
{
byte block[MEMCLUMPSIZE];// contents of the clump
uint sentinel1; // should always be MEMCLUMP_SENTINEL
int bits[MEMBITINTS]; // if a bit is on, it means that the MEMUNIT bytes it represents are allocated, otherwise free
uint sentinel2; // should always be MEMCLUMP_SENTINEL
size_t blocksinuse; // if this drops to 0, the clump is freed
size_t largestavailable; // largest block of memory available
struct memclump_s *chain; // next clump in the chain
} memclump_t;
typedef struct mempool_s
{
uint sentinel1; // should always be MEMHEADER_SENTINEL1
struct memheader_s *chain; // chain of individual memory allocations
struct memclump_s *clumpchain; // chain of clumps (if any)
size_t totalsize; // total memory allocated in this pool (inside memheaders)
size_t realsize; // total memory allocated in this pool (actual malloc total)
size_t lastchecksize; // updated each time the pool is displayed by memlist
struct mempool_s *next; // linked into global mempool list
const char *filename; // file name and line where Mem_AllocPool was called
int fileline;
char name[64]; // name of the pool
uint sentinel2; // should always be MEMHEADER_SENTINEL1
} mempool_t;
mempool_t *poolchain = NULL; // critical stuff
void *_Mem_Alloc( byte *poolptr, size_t size, const char *filename, int fileline )
{
int i, j, k, needed, endbit, largest;
memclump_t *clump, **clumpchainpointer;
memheader_t *mem;
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 );
pool->totalsize += size;
if( size < 4096 )
{
// clumping
needed = ( sizeof( memheader_t ) + size + sizeof( int ) + (MEMUNIT - 1)) / MEMUNIT;
endbit = MEMBITS - needed;
for( clumpchainpointer = &pool->clumpchain; *clumpchainpointer; clumpchainpointer = &(*clumpchainpointer)->chain )
{
clump = *clumpchainpointer;
if( clump->sentinel1 != MEMCLUMP_SENTINEL )
com.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 );
if( clump->largestavailable >= needed )
{
largest = 0;
for( i = 0; i < endbit; i++ )
{
if( clump->bits[i>>5] & (1 << (i & 31)))
continue;
k = i + needed;
for( j = i; i < k; i++ )
if( clump->bits[i>>5] & (1 << (i & 31)))
goto loopcontinue;
goto choseclump;
loopcontinue:;
if( largest < j - i )
largest = j - i;
}
// since clump falsely advertised enough space (nothing wrong
// with that), update largest count to avoid wasting time in
// later allocations
clump->largestavailable = largest;
}
}
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 );
_Q_memset( clump, 0, sizeof( memclump_t ), filename, fileline );
*clumpchainpointer = clump;
clump->sentinel1 = MEMCLUMP_SENTINEL;
clump->sentinel2 = MEMCLUMP_SENTINEL;
clump->chain = NULL;
clump->blocksinuse = 0;
clump->largestavailable = MEMBITS - needed;
j = 0;
choseclump:
mem = (memheader_t *)((byte *)clump->block + j * MEMUNIT );
mem->clump = clump;
clump->blocksinuse += needed;
for( i = j + needed; j < i; j++ )
clump->bits[j >> 5] |= (1 << (j & 31));
}
else
{
// 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 );
mem->clump = NULL;
}
mem->filename = filename;
mem->fileline = fileline;
mem->size = size;
mem->pool = pool;
mem->sentinel1 = MEMHEADER_SENTINEL1;
// we have to use only a single byte for this sentinel, because it may not be aligned
// and some platforms can't use unaligned accesses
*((byte *)mem + sizeof( memheader_t ) + mem->size ) = MEMHEADER_SENTINEL2;
// append to head of list
mem->next = pool->chain;
mem->prev = NULL;
pool->chain = mem;
if( mem->next ) mem->next->prev = mem;
_Q_memset((void *)((byte *)mem + sizeof( memheader_t )), 0, mem->size, filename, fileline );
return (void *)((byte *)mem + sizeof( memheader_t ));
}
static const char *Mem_CheckFilename( const char *filename )
{
static const char *dummy = "<corrupted>\0";
const char *out = filename;
int i;
if( !out ) return dummy;
for( i = 0; i < 32; i++, out++ )
if( out == '\0' ) break; // valid name
if( i == 32 ) return dummy;
return filename;
}
static void Mem_FreeBlock( memheader_t *mem, const char *filename, int fileline )
{
int i, firstblock, endblock;
memclump_t *clump, **clumpchainpointer;
mempool_t *pool;
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 );
}
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 );
}
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 );
if( mem->prev ) mem->prev->next = mem->next;
else pool->chain = mem->next;
if( mem->next )
mem->next->prev = mem->prev;
// memheader has been unlinked, do the actual free now
pool->totalsize -= mem->size;
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 );
if( clump->sentinel2 != MEMCLUMP_SENTINEL )
com.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 );
firstblock /= MEMUNIT;
endblock = firstblock + ((sizeof( memheader_t ) + mem->size + sizeof( int ) + (MEMUNIT - 1)) / MEMUNIT );
clump->blocksinuse -= endblock - firstblock;
// could use &, but we know the bit is set
for( i = firstblock; i < endblock; i++ )
clump->bits[i >> 5] -= (1 << (i & 31));
if( clump->blocksinuse <= 0 )
{
// unlink from chain
for( clumpchainpointer = &pool->clumpchain; *clumpchainpointer; clumpchainpointer = &(*clumpchainpointer)->chain )
{
if (*clumpchainpointer == clump)
{
*clumpchainpointer = clump->chain;
break;
}
}
pool->realsize -= sizeof( memclump_t );
_Q_memset( clump, 0xBF, sizeof( memclump_t ), filename, fileline );
free( clump );
}
else
{
// clump still has some allocations
// force re-check of largest available space on next alloc
clump->largestavailable = MEMBITS - clump->blocksinuse;
}
}
else
{
pool->realsize -= sizeof( memheader_t ) + mem->size + sizeof( int );
free( mem );
}
}
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 );
Mem_FreeBlock((memheader_t *)((byte *)data - sizeof( memheader_t )), filename, fileline );
}
void *_Mem_Realloc( byte *poolptr, void *memptr, size_t size, const char *filename, int fileline )
{
char *nb;
memheader_t *memhdr;
if( size <= 0 ) return memptr; // no need to reallocate
if( memptr )
{
memhdr = (memheader_t *)((byte *)memptr - sizeof( memheader_t ));
if( size == memhdr->size ) return memptr;
}
nb = _Mem_Alloc( poolptr, size, filename, fileline );
if( memptr ) // first allocate?
{
size_t newsize;
// get size of old block
newsize = memhdr->size < size ? memhdr->size : size; // upper data can be trucnated!
_Q_memcpy( nb, memptr, newsize, filename, fileline );
_Mem_Free( memptr, filename, fileline ); // free unused old block
}
return (void *)nb;
}
void _Mem_Move( byte *poolptr, void **dest, void *src, size_t size, const char *filename, int fileline )
{
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( size <= 0 )
{
// just free memory
_Mem_Free( memptr, filename, fileline );
*dest = src; // swap blocks
return;
}
mem = (memheader_t *)((byte *) memptr - sizeof(memheader_t)); // get size of old block
if( mem->size != size )
{
_Mem_Free( memptr, filename, fileline ); // release old buffer
memptr = _Mem_Alloc( poolptr, size, filename, fileline ); // alloc new size
}
else _Q_memset( memptr, 0x00, size, filename, fileline ); // no need to reallocate buffer
_Q_memcpy( memptr, src, size, filename, fileline ); // move memory...
_Mem_Free( src, filename, fileline ); // ...and free old pointer
*dest = memptr;
}
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 );
_Q_memset( pool, 0, sizeof(mempool_t), filename, fileline );
// fill header
pool->sentinel1 = MEMHEADER_SENTINEL1;
pool->sentinel2 = MEMHEADER_SENTINEL1;
pool->filename = filename;
pool->fileline = fileline;
pool->chain = NULL;
pool->totalsize = 0;
pool->realsize = sizeof(mempool_t);
Q_strncpy(pool->name, name, sizeof (pool->name));
pool->next = poolchain;
poolchain = pool;
return (byte *)((mempool_t *)pool);
}
void _Mem_FreePool( byte **poolptr, const char *filename, int fileline )
{
mempool_t *pool = (mempool_t *)((byte *)*poolptr );
mempool_t **chainaddress;
if( pool )
{
// 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 );
*chainaddress = pool->next;
// free memory owned by the pool
while( pool->chain ) Mem_FreeBlock( pool->chain, filename, fileline );
// free the pool itself
_Q_memset( pool, 0xBF, sizeof( mempool_t ), filename, fileline );
free( pool );
*poolptr = NULL;
}
}
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( 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 );
// free memory owned by the pool
while( pool->chain ) Mem_FreeBlock( pool->chain, filename, fileline );
}
qboolean Mem_CheckAlloc( mempool_t *pool, void *data )
{
memheader_t *header, *target;
if( pool )
{
// search only one pool
target = (memheader_t *)((byte *)data - sizeof(memheader_t));
for( header = pool->chain; header; header = header->next )
if( header == target ) return true;
}
else
{
// search all pools
for( pool = poolchain; pool; pool = pool->next )
if( Mem_CheckAlloc( pool, data ))
return true;
}
return false;
}
/*
========================
Check pointer for memory
========================
*/
qboolean Mem_IsAllocatedExt( byte *poolptr, void *data )
{
mempool_t *pool = NULL;
if( poolptr ) pool = (mempool_t *)((byte *)poolptr);
return Mem_CheckAlloc( pool, data );
}
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);
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);
}
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);
}
}
static void Mem_CheckClumpSentinels( memclump_t *clump, const char *filename, int fileline )
{
// 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 );
if( clump->sentinel2 != MEMCLUMP_SENTINEL )
com.error( "Mem_CheckClumpSentinels: trashed sentinel 2 (sentinel check at %s:%i)\n", filename, fileline );
}
void _Mem_Check( const char *filename, int fileline )
{
memheader_t *mem;
mempool_t *pool;
memclump_t *clump;
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 );
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 );
}
for( pool = poolchain; pool; pool = pool->next )
for( mem = pool->chain; mem; mem = mem->next )
Mem_CheckHeaderSentinels((void *)((byte *) mem + sizeof(memheader_t)), filename, fileline );
for( pool = poolchain; pool; pool = pool->next )
for( clump = pool->clumpchain; clump; clump = clump->chain )
Mem_CheckClumpSentinels( clump, filename, fileline );
}
void Mem_PrintStats( void )
{
size_t count = 0, size = 0, realsize = 0;
mempool_t *pool;
Mem_Check();
for( pool = poolchain; pool; pool = pool->next )
{
count++;
size += pool->totalsize;
realsize += pool->realsize;
}
Msg( "^3%lu^7 memory pools, totalling: ^1%s\n", (dword)count, Q_memprint( size ));
Msg( "Total allocated size: ^1%s\n", Q_memprint( realsize ));
}
void Mem_PrintList( size_t minallocationsize )
{
mempool_t *pool;
memheader_t *mem;
Mem_Check();
Msg( "memory pool list:\n"" ^3size name\n");
for( pool = poolchain; pool; pool = pool->next )
{
// poolnames can contain color symbols, make sure what color is reset
if( ((long)pool->totalsize - pool->lastchecksize ) != 0 )
Msg( "%5luk (%5luk actual) %s (^7%+3li byte change)\n", (dword)((pool->totalsize + 1023) / 1024), (dword)((pool->realsize + 1023) / 1024), pool->name, (long)pool->totalsize - pool->lastchecksize );
else Msg( "%5luk (%5luk actual) %s\n", (dword)((pool->totalsize + 1023) / 1024), (dword)((pool->realsize + 1023) / 1024), pool->name );
pool->lastchecksize = pool->totalsize;
for( mem = pool->chain; mem; mem = mem->next )
if( mem->size >= minallocationsize )
Msg( "%10lu bytes allocated at %s:%i\n", (dword)mem->size, mem->filename, mem->fileline );
}
}
/*
========================
Memory_Init
========================
*/
void Memory_Init( void )
{
poolchain = NULL; // init mem chain
}

View File

@ -484,6 +484,10 @@ SOURCE=.\common\vgui_int.cpp
SOURCE=.\common\world.c
# End Source File
# Begin Source File
SOURCE=.\common\zone.c
# End Source File
# End Group
# Begin Group "Header Files"

View File

@ -4448,7 +4448,7 @@ void SV_SpawnEntities( const char *mapname, char *entities )
// spawn the rest of the entities on the map
SV_LoadFromFile( entities );
if( !Mem_IsAllocated( sv.worldmodel->mempool, entities ))
if( !Mem_IsAllocatedExt( sv.worldmodel->mempool, entities ))
Mem_Free( entities ); // only free memory that allocated by entpatch
MsgDev( D_NOTE, "Total %i entities spawned\n", svgame.numEntities );

View File

@ -67,7 +67,7 @@ void SV_CheckAllEnts( void )
continue;
}
if( !e->pvPrivateData || !Mem_IsAllocated( svgame.mempool, e->pvPrivateData ))
if( !e->pvPrivateData || !Mem_IsAllocatedExt( svgame.mempool, e->pvPrivateData ))
{
MsgDev( D_ERROR, "Entity %s (%i) trashed private data.\n", SV_ClassName( e ), i );
e->pvPrivateData = NULL;

View File

@ -72,7 +72,7 @@ void Con_SetInputText( const char *inputText )
if( Sys.con_readonly ) return;
SetWindowText( s_wcd.hwndInputLine, inputText );
SendMessage( s_wcd.hwndInputLine, EM_SETSEL, com.strlen( inputText ), -1 );
SendMessage( s_wcd.hwndInputLine, EM_SETSEL, strlen( inputText ), -1 );
}
static int Con_KeyEvent( int key, qboolean down )
@ -179,13 +179,13 @@ long _stdcall Con_InputLineProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPa
if( wParam == 13 && Sys.app_state != SYS_ERROR )
{
GetWindowText( s_wcd.hwndInputLine, inputBuffer, sizeof( inputBuffer ));
com.strncat( s_wcd.consoleText, inputBuffer, sizeof( s_wcd.consoleText ) - com.strlen( s_wcd.consoleText ) - 5 );
com.strcat( s_wcd.consoleText, "\n" );
strncat( s_wcd.consoleText, inputBuffer, sizeof( s_wcd.consoleText ) - strlen( s_wcd.consoleText ) - 5 );
strcat( s_wcd.consoleText, "\n" );
SetWindowText( s_wcd.hwndInputLine, "" );
Msg( ">%s\n", inputBuffer );
// copy line to history buffer
com.strncpy( s_wcd.historyLines[s_wcd.nextHistoryLine % COMMAND_HISTORY], inputBuffer, MAX_STRING );
strncpy( s_wcd.historyLines[s_wcd.nextHistoryLine % COMMAND_HISTORY], inputBuffer, MAX_STRING );
s_wcd.nextHistoryLine++;
s_wcd.historyLine = s_wcd.nextHistoryLine;
return 0;
@ -212,7 +212,7 @@ print into window console
*/
void Con_Print( const char *pMsg )
{
size_t len = com.strlen( pMsg );
size_t len = strlen( pMsg );
// replace selection instead of appending if we're overflowing
s_wcd.outLen += len;
@ -278,7 +278,7 @@ void Con_CreateConsole( void )
rect.right = 536;
rect.top = 0;
rect.bottom = 280;
com.strncpy( FontName, "Arial", sizeof( FontName ));
strncpy( FontName, "Arial", sizeof( FontName ));
fontsize = 16;
}
else if( Sys.con_readonly )
@ -287,7 +287,7 @@ void Con_CreateConsole( void )
rect.right = 536;
rect.top = 0;
rect.bottom = 364;
com.strncpy( FontName, "Fixedsys", sizeof( FontName ));
strncpy( FontName, "Fixedsys", sizeof( FontName ));
fontsize = 8;
}
else // dedicated console
@ -296,11 +296,11 @@ void Con_CreateConsole( void )
rect.right = 640;
rect.top = 0;
rect.bottom = 392;
com.strncpy( FontName, "System", sizeof( FontName ));
strncpy( FontName, "System", sizeof( FontName ));
fontsize = 14;
}
com.strncpy( Title, Sys.caption, sizeof( Title ));
strncpy( Title, Sys.caption, sizeof( Title ));
AdjustWindowRect( &rect, DEDSTYLE, FALSE );
hDC = GetDC( GetDesktopWindow() );
@ -402,7 +402,7 @@ char *Con_Input( void )
if( s_wcd.consoleText[0] == 0 )
return NULL;
com.strncpy( s_wcd.returnedText, s_wcd.consoleText, sizeof( s_wcd.returnedText ));
strncpy( s_wcd.returnedText, s_wcd.consoleText, sizeof( s_wcd.returnedText ));
s_wcd.consoleText[0] = 0;
return s_wcd.returnedText;
@ -445,29 +445,29 @@ void Sys_InitLog( void )
if(!Sys.logfile) MsgDev( D_ERROR, "Sys_InitLog: can't create log file %s\n", Sys.log_path );
fprintf( Sys.logfile, "=======================================================================\n" );
fprintf( Sys.logfile, "\t%s started at %s\n", Sys.caption, com.timestamp( TIME_FULL ));
fprintf( Sys.logfile, "\t%s started at %s\n", Sys.caption, timestamp( TIME_FULL ));
fprintf( Sys.logfile, "=======================================================================\n");
}
}
void Sys_CloseLog( void )
{
string event_name;
char event_name[32];
// continue logged
switch( Sys.app_state )
{
case SYS_CRASH: com.strncpy( event_name, "crashed", sizeof( event_name )); break;
case SYS_ERROR: com.strncpy( event_name, "stopped with error", sizeof( event_name )); break;
case SYS_RESTART: com.strncpy( event_name, "restarted", sizeof( event_name )); break;
default: com.strncpy( event_name, "stopped", sizeof( event_name )); break;
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;
}
if( Sys.logfile )
{
fprintf( Sys.logfile, "\n");
fprintf( Sys.logfile, "=======================================================================");
fprintf( Sys.logfile, "\n\t%s %s at %s\n", Sys.caption, event_name, com.timestamp(TIME_FULL));
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

View File

@ -1,469 +0,0 @@
//=======================================================================
// Copyright XashXT Group 2007 ©
// cpuinfo.c - get cpu information
//=======================================================================
#include "launch.h"
typedef signed __int64 int64;
sysinfo_t SI;
// Processor Information:
typedef struct cpuinfo_s
{
qboolean m_bRDTSC; // is RDTSC supported?
qboolean m_bCMOV; // is CMOV supported?
qboolean m_bFCMOV; // is FCMOV supported?
qboolean m_bSSE; // is SSE supported?
qboolean m_bSSE2; // is SSE2 Supported?
qboolean m_b3DNow; // is 3DNow! Supported?
qboolean m_bMMX; // is MMX supported?
qboolean m_bHT; // is HyperThreading supported?
byte m_usNumLogicCore; // number op logical processors.
byte m_usNumPhysCore; // number of physical processors
int64 m_speed; // in cycles per second.
int m_size; // structure size
char *m_szCPUID; // processor vendor identification.
} cpuinfo_t;
typedef struct register_s
{
dword eax;
dword ebx;
dword ecx;
dword edx;
qboolean retval;
} register_t;
static register_t cpuid(uint function )
{
register_t local;
local.retval = true;
_asm pushad;
__try
{
_asm
{
xor edx, edx // Clue the compiler that EDX is about to be used.
mov eax, function // set up CPUID to return processor version and features
// 0 = vendor string, 1 = version info, 2 = cache info
cpuid // code bytes = 0fh, 0a2h
mov local.eax, eax // features returned in eax
mov local.ebx, ebx // features returned in ebx
mov local.ecx, ecx // features returned in ecx
mov local.edx, edx // features returned in edx
}
}
__except( EXCEPTION_EXECUTE_HANDLER )
{
local.retval = false;
}
_asm popad
return local;
}
qboolean CheckMMXTechnology( void )
{
register_t mmx = cpuid( 1 );
if( !mmx.retval ) return false;
return ( mmx.edx & 0x800000 ) != 0;
}
qboolean CheckSSETechnology( void )
{
register_t sse = cpuid( 1 );
if( !sse.retval ) return false;
return ( sse.edx & 0x2000000L ) != 0;
}
qboolean CheckSSE2Technology( void )
{
register_t sse2 = cpuid( 1 );
if( !sse2.retval ) return false;
return ( sse2.edx & 0x04000000 ) != 0;
}
qboolean Check3DNowTechnology( void )
{
register_t amd = cpuid( 0x80000000 );
if( !amd.retval ) return false;
if( amd.eax > 0x80000000L )
{
amd = cpuid( 0x80000001 );
if( !amd.retval ) return false;
return ( amd.edx & 1<<31 ) != 0;
}
return false;
}
qboolean CheckCMOVTechnology()
{
register_t cmov = cpuid( 1 );
if( !cmov.retval ) return false;
return ( cmov.edx & (1<<15) ) != 0;
}
qboolean CheckFCMOVTechnology( void )
{
register_t fcmov = cpuid( 1 );
if( !fcmov.retval ) return false;
return ( fcmov.edx & (1<<16) ) != 0;
}
qboolean CheckRDTSCTechnology(void)
{
register_t rdtsc = cpuid( 1 );
if( !rdtsc.retval ) return false;
return rdtsc.edx & 0x10 != 0;
}
/*
================
Return the Processor's vendor identification string, or "Generic_x86" if it doesn't exist on this CPU
================
*/
const char* GetProcessorVendorId( void )
{
static char VendorID[13];
register_t vendor = cpuid( 0 );
Mem_Set( VendorID, 0, sizeof( VendorID ));
if( !vendor.retval )
{
com.strcpy( VendorID, "Generic_x86" );
}
else
{
Mem_Copy( VendorID+0, &(vendor.ebx), sizeof( vendor.ebx ) );
Mem_Copy( VendorID+4, &(vendor.edx), sizeof( vendor.edx ) );
Mem_Copy( VendorID+8, &(vendor.ecx), sizeof( vendor.ecx ) );
}
return VendorID;
}
/*
================
Returns non-zero if Hyper-Threading Technology is supported on the processors and zero if not.
This does not mean that Hyper-Threading Technology is necessarily enabled.
================
*/
static qboolean HTSupported( void )
{
const uint HT_BIT = 0x10000000; // EDX[28] - Bit 28 set indicates Hyper-Threading Technology is supported in hardware.
const uint FAMILY_ID = 0x0f00; // EAX[11:8] - Bit 11 thru 8 contains family processor id
const uint EXT_FAMILY_ID = 0x0f00000; // EAX[23:20] - Bit 23 thru 20 contains extended family processor id
const uint PENTIUM4_ID = 0x0f00; // Pentium 4 family processor id
register_t intel1 = cpuid( 0 );
register_t intel2 = cpuid( 1 );
if( !intel1.retval || !intel2.retval )
return false;
// Check to see if this is a Pentium 4 or later processor
if((( intel2.eax & FAMILY_ID ) == PENTIUM4_ID ) || ( intel2.eax & EXT_FAMILY_ID ))
if( intel1.ebx == 'uneG' && intel1.edx == 'Ieni' && intel1.ecx == 'letn' )
return (intel2.edx & HT_BIT) != 0; // Genuine Intel Processor with Hyper-Threading Technology
return false; // this is not a genuine Intel processor.
}
/*
================
Returns the number of logical processors per physical processors.
================
*/
static byte LogicalProcessorsPerPackage( void )
{
const uint NUM_LOGICAL_BITS = 0x00FF0000; // EBX[23:16] indicate number of logical processors per package
register_t core = cpuid( 1 );
if( !HTSupported( )) return 1;
if( !core.retval) return 1;
return (byte)((core.ebx & NUM_LOGICAL_BITS) >> 16);
}
int64 ClockSample( void )
{
static int64 m_time = 0;
dword *pSample = (dword *)&m_time;
__asm
{
mov ecx, pSample
rdtsc
mov [ecx], eax
mov [ecx+4], edx
}
return m_time;
}
/*
================
Measure the processor clock speed by sampling the cycle count, waiting
for some fraction of a second, then measuring the elapsed number of cycles.
================
*/
static int64 CalculateClockSpeed( void )
{
LARGE_INTEGER waitTime, startCount, curCount;
int scale = 5; // Take 1/32 of a second for the measurement.
int64 start, end;
QueryPerformanceCounter( &startCount );
QueryPerformanceFrequency( &waitTime );
waitTime.QuadPart >>= scale;
start = ClockSample();
do
{
QueryPerformanceCounter( &curCount );
} while( curCount.QuadPart - startCount.QuadPart < waitTime.QuadPart );
end = ClockSample();
return (end - start) << scale;
}
/*
================
GetCPUInfo
================
*/
cpuinfo_t GetCPUInfo( void )
{
static cpuinfo_t pi;
SYSTEM_INFO si;
if( pi.m_size == sizeof( pi ))
return pi; // has the structure already been initialized and filled out?
Mem_Set( &pi, 0, sizeof( pi )); // redundant, but just in case the user somehow messes with the size.
pi.m_size = sizeof(pi); // fill out the structure, and return it:
pi.m_speed = CalculateClockSpeed(); // grab the processor frequency:
// get the logical and physical processor counts:
pi.m_usNumLogicCore = LogicalProcessorsPerPackage();
Mem_Set( &si, 0, sizeof( si ));
GetSystemInfo( &si );
pi.m_usNumPhysCore = si.dwNumberOfProcessors / pi.m_usNumLogicCore;
pi.m_usNumLogicCore *= pi.m_usNumPhysCore;
// make sure I always report at least one, when running WinXP with the /ONECPU switch,
// it likes to report 0 processors for some reason.
if( pi.m_usNumPhysCore == 0 && pi.m_usNumLogicCore == 0 )
{
pi.m_usNumPhysCore = 1;
pi.m_usNumLogicCore = 1;
}
// Determine Processor Features:
pi.m_bRDTSC = CheckRDTSCTechnology();
pi.m_bCMOV = CheckCMOVTechnology();
pi.m_bFCMOV = CheckFCMOVTechnology();
pi.m_bMMX = CheckMMXTechnology();
pi.m_bSSE = CheckSSETechnology();
pi.m_bSSE2 = CheckSSE2Technology();
pi.m_b3DNow = Check3DNowTechnology();
pi.m_szCPUID = (char*)GetProcessorVendorId();
return pi;
}
void Sys_InitMathlib( cpuinfo_t *cpu )
{
size_t i, size = 1024 * 1024;
double start, min, result[8];
void *buf0 = Malloc( size );
void *buf1 = Malloc( size );
int numchecks = 16; // iterations
start = Sys_DoubleTime();
for( i = 0; i < numchecks; i++ ) _crt_mem_copy( buf0, buf1, size, __FILE__, __LINE__ );
result[0] = Sys_DoubleTime() - start;
MsgDev( D_NOTE, "crt_memcpy %i ms\n", (int)( result[0] * 1000 ));
start = Sys_DoubleTime();
for( i = 0; i < numchecks; i++ ) _asm_mem_copy( buf0, buf1, size, __FILE__, __LINE__ );
result[1] = Sys_DoubleTime() - start;
MsgDev( D_NOTE, "asm_memcpy %i ms\n", (int)( result[1] * 1000 ));
start = Sys_DoubleTime();
for( i = 0; i < numchecks; i++ ) _com_mem_copy( buf0, buf1, size, __FILE__, __LINE__ );
result[2] = Sys_DoubleTime() - start;
MsgDev( D_NOTE, "com_memcpy %i ms\n", (int)( result[2] * 1000 ));
if( cpu->m_bMMX )
{
start = Sys_DoubleTime();
for( i = 0; i < numchecks; i++ ) _mmx_mem_copy( buf0, buf1, size, __FILE__, __LINE__ );
result[3] = Sys_DoubleTime() - start;
MsgDev( D_NOTE, "mmx_memcpy %i ms\n", (int)( result[3] * 1000 ));
}
else
{
result[3] = 0x7fffffff;
MsgDev( D_NOTE, "mmx_memcpy not supported\n" );
}
if( cpu->m_b3DNow )
{
start = Sys_DoubleTime();
for( i = 0; i < numchecks; i++ ) _amd_mem_copy( buf0, buf1, size, __FILE__, __LINE__ );
result[4] = Sys_DoubleTime() - start;
MsgDev( D_NOTE, "amd_memcpy %i ms\n", (int)( result[4] * 1000 ));
}
else
{
result[4] = 0x7fffffff;
MsgDev( D_NOTE, "amd_memcpy not supported\n" );
}
min = min( result[0], min( result[1], min( result[2], min( result[3], result[4] ))));
if( min == result[0] )
{
MsgDev( D_NOTE, "Sys_InitMathlib: using crt_memcpy\n" );
com.memcpy = _crt_mem_copy;
}
else if( min == result[1] )
{
MsgDev( D_NOTE, "Sys_InitMathlib: using asm_memcpy\n" );
com.memcpy = _asm_mem_copy;
}
else if( min == result[2] )
{
MsgDev( D_NOTE, "Sys_InitMathlib: using com_memcpy\n" );
com.memcpy = _com_mem_copy;
}
else if( min == result[3] )
{
MsgDev( D_NOTE, "Sys_InitMathlib: using mmx_memcpy\n" );
com.memcpy = _mmx_mem_copy;
}
else if( min == result[4] )
{
MsgDev( D_NOTE, "Sys_InitMathlib: using amd_memcpy\n" );
com.memcpy = _amd_mem_copy;
}
// memset
start = Sys_DoubleTime();
for( i = 0; i < numchecks; i++ ) _crt_mem_set( buf0, 0, size, __FILE__, __LINE__ );
result[0] = Sys_DoubleTime() - start;
MsgDev( D_NOTE, "crt_memset %i ms\n", (int)( result[0] * 1000 ));
start = Sys_DoubleTime();
for( i = 0; i < numchecks; i++ ) _asm_mem_set( buf0, 0, size, __FILE__, __LINE__ );
result[1] = Sys_DoubleTime() - start;
MsgDev( D_NOTE, "asm_memset %i ms\n", (int)( result[1] * 1000 ));
start = Sys_DoubleTime();
for( i = 0; i < numchecks; i++ ) _com_mem_set( buf0, 0, size, __FILE__, __LINE__ );
result[2] = Sys_DoubleTime() - start;
MsgDev( D_NOTE, "com_memset %i ms\n", (int)( result[2] * 1000 ));
if( cpu->m_bMMX )
{
start = Sys_DoubleTime();
for( i = 0; i < numchecks; i++ ) _mmx_mem_set( buf0, 0, size, __FILE__, __LINE__ );
result[3] = Sys_DoubleTime() - start;
MsgDev( D_NOTE, "mmx_memset %i ms\n", (int)( result[3] * 1000 ));
}
else
{
result[3] = 0x7fffffff;
MsgDev( D_NOTE, "mmx_memset not supported\n" );
}
min = min( result[0], min( result[1], min( result[2], result[3] )));
if( min == result[0] )
{
MsgDev( D_NOTE, "Sys_InitMathlib: using crt_memset\n" );
com.memset = _crt_mem_set;
}
else if( min == result[1] )
{
MsgDev( D_NOTE, "Sys_InitMathlib: using asm_memset\n" );
com.memset = _asm_mem_set;
}
else if( min == result[2] )
{
MsgDev( D_NOTE, "Sys_InitMathlib: using com_memset\n" );
com.memset = _com_mem_set;
}
else if( min == result[3] )
{
MsgDev( D_NOTE, "Sys_InitMathlib: using mmx_memset\n" );
com.memset = _mmx_mem_set;
}
// release test memory
if( buf0 ) Mem_Free( buf0 );
if( buf1 ) Mem_Free( buf1 );
}
void Sys_InitCPU( void )
{
cpuinfo_t cpu = GetCPUInfo();
string szFeatureString;
// Compute Frequency in Mhz:
char* szFrequencyDenomination = "Mhz";
double fFrequency = cpu.m_speed / 1000000.0;
// Adjust to Ghz if nessecary:
if( fFrequency > 1000.0 )
{
fFrequency /= 1000.0;
szFrequencyDenomination = "Ghz";
}
com.strcpy( szFeatureString, "" );
if( cpu.m_bMMX ) com.strcat( szFeatureString, "MMX " );
if( cpu.m_b3DNow ) com.strcat( szFeatureString, "3DNow " );
if( cpu.m_bSSE ) com.strcat( szFeatureString, "SSE " );
if( cpu.m_bSSE2 ) com.strcat( szFeatureString, "SSE2 " );
if( cpu.m_bRDTSC ) com.strcat( szFeatureString, "RDTSC " );
if( cpu.m_bCMOV ) com.strcat( szFeatureString, "CMOV " );
if( cpu.m_bFCMOV ) com.strcat( szFeatureString, "FCMOV " );
// remove the trailing space. There will always be one.
szFeatureString[com.strlen( szFeatureString ) - 1] = '\0';
// Dump CPU information:
if( cpu.m_usNumLogicCore == 1 )
{
MsgDev( D_INFO, "CPU: %s [1 core]. Frequency: %.01f %s\n", cpu.m_szCPUID, fFrequency, szFrequencyDenomination );
}
else
{
string buffer;
if( cpu.m_usNumPhysCore != cpu.m_usNumLogicCore )
com.snprintf( buffer, sizeof( buffer ), " (%i physical)", (int) cpu.m_usNumPhysCore );
else buffer[0] = '\0';
MsgDev( D_INFO, "CPU: %s [%i core's%s]. Frequency: %.01f %s\n ", cpu.m_szCPUID, (int)cpu.m_usNumLogicCore, buffer, fFrequency, szFrequencyDenomination );
}
MsgDev( D_NOTE, "CPU Features: %s\n", szFeatureString );
Sys_InitMathlib( &cpu );
}

View File

@ -116,14 +116,6 @@ SOURCE=.\console.c
# End Source File
# Begin Source File
SOURCE=.\cpuinfo.c
# End Source File
# Begin Source File
SOURCE=.\memlib.c
# End Source File
# Begin Source File
SOURCE=.\stdlib.c
# End Source File
# Begin Source File

View File

@ -33,6 +33,33 @@ enum state_e
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
@ -61,7 +88,6 @@ typedef struct system_s
qboolean con_showalways;
qboolean con_showcredits;
qboolean con_silentmode;
byte *basepool;
qboolean shutdown_issued;
qboolean error;
@ -91,7 +117,6 @@ char *Con_Input( void );
//
// system.c
//
void Sys_InitCPU( void );
void Sys_ParseCommandLine( LPSTR lpCmdLine );
void Sys_LookupInstance( void );
void Sys_NewInstance( const char *name, const char *fmsg );
@ -120,85 +145,8 @@ void Sys_MsgDev( int level, const char *pMsg, ... );
//
// stdlib.c
//
void com_strnupr(const char *in, char *out, size_t size_out);
void com_strupr(const char *in, char *out);
void com_strnlwr(const char *in, char *out, size_t size_out);
void com_strlwr(const char *in, char *out);
int com_strlen( const char *string );
int com_cstrlen( const char *string );
char com_toupper(const char in );
char com_tolower(const char in );
size_t com_strncat(char *dst, const char *src, size_t siz);
size_t com_strcat(char *dst, const char *src );
size_t com_strncpy(char *dst, const char *src, size_t siz);
size_t com_strcpy(char *dst, const char *src );
char *com_stralloc(byte *mempool, const char *s, const char *filename, int fileline);
qboolean com_isdigit( const char *str );
int com_atoi(const char *str);
float com_atof(const char *str);
void com_atov( float *vec, const char *str, size_t siz );
char *com_strchr(const char *s, char c);
char *com_strrchr(const char *s, char c);
int com_strnicmp(const char *s1, const char *s2, int n);
int com_stricmp(const char *s1, const char *s2);
int com_strncmp (const char *s1, const char *s2, int n);
int com_strcmp (const char *s1, const char *s2);
qboolean com_stricmpext( const char *s1, const char *s2 );
const char* com_timestamp( int format );
char *com_stristr( const char *string, const char *string2 );
char *com_strstr( const char *string, const char *string2 );
int com_vsnprintf(char *buffer, size_t buffersize, const char *format, va_list args);
int com_vsprintf(char *buffer, const char *format, va_list args);
int com_snprintf(char *buffer, size_t buffersize, const char *format, ...);
int com_sprintf(char *buffer, const char *format, ...);
char *com_pretifymem( float value, int digitsafterdecimal );
char *va(const char *format, ...);
#define copystring( str ) com_stralloc( NULL, str, __FILE__, __LINE__)
#define copystring2( pool, str ) com_stralloc( pool, str, __FILE__, __LINE__)
//
// memlib.c
//
void Memory_Init( void );
void Memory_Shutdown( void );
void _mem_move(byte *poolptr, void **dest, void *src, size_t size, const char *filename, int fileline);
void *_mem_realloc(byte *poolptr, void *memptr, size_t size, const char *filename, int fileline);
void _com_mem_copy(void *dest, const void *src, size_t size, const char *filename, int fileline);
void _crt_mem_copy(void *dest, const void *src, size_t size, const char *filename, int fileline);
void _asm_mem_copy(void *dest, const void *src, size_t size, const char *filename, int fileline);
void _mmx_mem_copy(void *dest, const void *src, size_t size, const char *filename, int fileline);
void _amd_mem_copy(void *dest, const void *src, size_t size, const char *filename, int fileline);
void _com_mem_set(void *dest, int set, size_t size, const char *filename, int fileline);
void _crt_mem_set(void *dest, int set, size_t size, const char *filename, int fileline);
void _asm_mem_set(void* dest, int set, size_t size, const char *filename, int fileline);
void _mmx_mem_set(void* dest, int set, size_t size, const char *filename, int fileline);
void *_mem_alloc(byte *poolptr, size_t size, const char *filename, int fileline);
byte *_mem_allocpool(const char *name, const char *filename, int fileline);
void _mem_freepool(byte **poolptr, const char *filename, int fileline);
void _mem_emptypool(byte *poolptr, const char *filename, int fileline);
void _mem_free(void *data, const char *filename, int fileline);
void _mem_check(const char *filename, int fileline);
qboolean _is_allocated( byte *poolptr, void *data);
void _mem_printlist(size_t minallocationsize);
void _mem_printstats(void);
#define Mem_Alloc(pool, size) _mem_alloc(pool, size, __FILE__, __LINE__)
#define Mem_Realloc(pool, ptr, size) _mem_realloc(pool, ptr, size, __FILE__, __LINE__)
#define Mem_Free(mem) _mem_free(mem, __FILE__, __LINE__)
#define Mem_AllocPool(name) _mem_allocpool(name, __FILE__, __LINE__)
#define Mem_FreePool(pool) _mem_freepool(pool, __FILE__, __LINE__)
#define Mem_EmptyPool(pool) _mem_emptypool(pool, __FILE__, __LINE__)
#define Mem_Move(pool, dest, src, size ) _mem_move(pool, dest, src, size, __FILE__, __LINE__)
#define Mem_Copy(dest, src, size ) com.memcpy(dest, src, size, __FILE__, __LINE__)
#define Mem_Set(dest, val, size ) com.memset(dest, val, size, __FILE__, __LINE__)
#define Mem_IsAllocated( mem ) _is_allocated( NULL, mem )
#define Mem_Check() _mem_check(__FILE__, __LINE__)
#define Mem_Pretify( x ) com_pretifymem(x, 3)
#define Malloc( size ) Mem_Alloc( Sys.basepool, size )
//
// parselib.c
//
char *va( const char *format, ... );
const char* timestamp( int format );
void Com_FileBase( const char *in, char *out );
#endif//LAUNCHER_H

View File

@ -61,7 +61,6 @@ 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
typedef struct { const char *name; void **func; } dllfunc_t; // Sys_LoadLibrary stuff
// timestamp modes
enum
@ -130,32 +129,6 @@ typedef struct sysinfo_s
int numgames;
} sysinfo_t;
/*
========================================================================
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 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;
/*
==============================================================================
@ -181,59 +154,6 @@ typedef struct stdilib_api_s
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
// memlib.c funcs
void (*memcpy)(void *dest, const void *src, size_t size, const char *file, int line);
void (*memset)(void *dest, int set, size_t size, const char *filename, int fileline);
void *(*realloc)(byte *pool, void *mem, size_t size, const char *file, int line);
void (*move)(byte *pool, void **dest, void *src, size_t size, const char *file, int line); // not a memmove
void *(*malloc)(byte *pool, size_t size, const char *file, int line);
void (*free)(void *data, const char *file, int line);
byte *(*mallocpool)(const char *name, const char *file, int line);
void (*freepool)(byte **poolptr, const char *file, int line);
void (*clearpool)(byte *poolptr, const char *file, int line);
void (*memcheck)(const char *file, int line); // check memory pools for consistensy
qboolean (*is_allocated)( byte *poolptr, void *data ); // return true is memory is allocated
void (*memlist)( size_t minallocationsize );
void (*memstats)( void );
qboolean (*Com_LoadLibrary)( const char *name, dll_info_t *dll ); // load library
qboolean (*Com_FreeLibrary)( dll_info_t *dll ); // free library
void*(*Com_GetProcAddress)( dll_info_t *dll, const char* name ); // gpa
// stdlib.c funcs
void (*strnupr)(const char *in, char *out, size_t size_out); // convert string to upper case
void (*strnlwr)(const char *in, char *out, size_t size_out); // convert string to lower case
void (*strupr)(const char *in, char *out); // convert string to upper case
void (*strlwr)(const char *in, char *out); // convert string to lower case
int (*strlen)( const char *string ); // returns string real length
int (*cstrlen)( const char *string ); // strlen that stripped color prefixes
char (*toupper)(const char in ); // convert one charcster to upper case
char (*tolower)(const char in ); // convert one charcster to lower case
size_t (*strncat)(char *dst, const char *src, size_t n); // add new string at end of buffer
size_t (*strcat)(char *dst, const char *src); // add new string at end of buffer
size_t (*strncpy)(char *dst, const char *src, size_t n); // copy string to existing buffer
size_t (*strcpy)(char *dst, const char *src); // copy string to existing buffer
qboolean (*is_digit)( const char *str ); // check string for digits
int (*atoi)(const char *str); // convert string to integer
float (*atof)(const char *str); // convert string to float
void (*atov)( float *dst, const char *src, size_t n ); // convert string to vector
char *(*strchr)(const char *s, char c); // find charcster at start of string
char *(*strrchr)(const char *s, char c); // find charcster at end of string
int (*strnicmp)(const char *s1, const char *s2, int n); // compare strings with case insensative
int (*stricmp)(const char *s1, const char *s2); // compare strings with case insensative
int (*strncmp)(const char *s1, const char *s2, int n); // compare strings with case sensative
int (*strcmp)(const char *s1, const char *s2); // compare strings with case sensative
char *(*stristr)( const char *s1, const char *s2 ); // find s2 in s1 with case insensative
char *(*strstr)( const char *s1, const char *s2 ); // find s2 in s1 with case sensative
int (*vsprintf)(char *buf, const char *fmt, va_list args); // format message
int (*sprintf)(char *buffer, const char *format, ...); // print into buffer
qboolean (*stricmpext)( const char *s1, const char *s2 ); // allow '*', '?' etc
char *(*va)(const char *format, ...); // print into temp buffer
int (*vsnprintf)( char *buf, size_t size, const char *fmt, va_list args ); // format message
int (*snprintf)( char *buffer, size_t buffersize, const char *format, ... ); // print into buffer
char *(*pretifymem)( float value, int digitsafterdecimal ); // pretify memory string
const char* (*timestamp)( int format ); // returns current time stamp
} stdlib_api_t;
/*
@ -265,25 +185,6 @@ typedef struct { size_t api_size; size_t com_size; } generic_api_t;
#ifndef LAUNCH_DLL
/*
==========================================
memory manager funcs
==========================================
*/
#define Mem_Alloc(pool, size) com.malloc(pool, size, __FILE__, __LINE__)
#define Mem_Realloc(pool, ptr, size) com.realloc(pool, ptr, size, __FILE__, __LINE__)
#define Mem_Move(pool, ptr, data, size) com.move(pool, ptr, data, size, __FILE__, __LINE__)
#define Mem_Free(mem) com.free(mem, __FILE__, __LINE__)
#define Mem_AllocPool(name) com.mallocpool(name, __FILE__, __LINE__)
#define Mem_FreePool(pool) com.freepool(pool, __FILE__, __LINE__)
#define Mem_EmptyPool(pool) com.clearpool(pool, __FILE__, __LINE__)
#define Mem_Copy(dest, src, size ) com.memcpy(dest, src, size, __FILE__, __LINE__)
#define Mem_Set(dest, val, size ) com.memset(dest, val, size, __FILE__, __LINE__)
#define Mem_Check() com.memcheck(__FILE__, __LINE__)
#define Mem_IsAllocated( pool, ptr ) com.is_allocated( pool, ptr )
#define Mem_PrintList( size ) com.memlist( size );
#define Mem_PrintStats() com.memstats()
/*
===========================================
filesystem manager
@ -302,9 +203,6 @@ misc utils
#define GI com.SysInfo->GameInfo
#define Msg com.printf
#define MsgDev com.dprintf
#define Sys_LoadLibrary com.Com_LoadLibrary
#define Sys_FreeLibrary com.Com_FreeLibrary
#define Sys_GetProcAddress com.Com_GetProcAddress
#define Sys_NewInstance com.instance
#define Sys_Print com.print
#define Sys_Quit com.exit

File diff suppressed because it is too large Load Diff

View File

@ -5,505 +5,12 @@
#include "launch.h"
void com_strnupr( const char *in, char *out, size_t size_out )
{
if( size_out == 0 ) return;
while( *in && size_out > 1 )
{
if( *in >= 'a' && *in <= 'z' )
*out++ = *in++ + 'A' - 'a';
else *out++ = *in++;
size_out--;
}
*out = '\0';
}
void com_strupr( const char *in, char *out )
{
com_strnupr( in, out, 99999 );
}
void com_strnlwr( const char *in, char *out, size_t size_out )
{
if( size_out == 0 ) return;
while( *in && size_out > 1 )
{
if( *in >= 'A' && *in <= 'Z' )
*out++ = *in++ + 'a' - 'A';
else *out++ = *in++;
size_out--;
}
*out = '\0';
}
void com_strlwr( const char *in, char *out )
{
com_strnlwr(in, out, 99999 );
}
/*
==============
isdigit
==============
*/
qboolean com_isdigit( const char *str )
{
if( str && *str )
{
while( isdigit( *str )) str++;
if( !*str ) return true;
}
return false;
}
/*
============
strlen
returned string length
============
*/
int com_strlen( const char *string )
{
int len;
const char *p;
if( !string ) return 0;
len = 0;
p = string;
while( *p )
{
p++;
len++;
}
return len;
}
/*
============
cstrlen
skipped color prefixes
============
*/
int com_cstrlen( const char *string )
{
int len;
const char *p;
if( !string ) return 0;
len = 0;
p = string;
while( *p )
{
if( IsColorString( p ))
{
p += 2;
continue;
}
p++;
len++;
}
return len;
}
char com_toupper( const char in )
{
char out;
if( in >= 'a' && in <= 'z' )
out = in + 'A' - 'a';
else out = in;
return out;
}
char com_tolower( const char in )
{
char out;
if( in >= 'A' && in <= 'Z' )
out = in + 'a' - 'A';
else out = in;
return out;
}
size_t com_strncat( char *dst, const char *src, size_t size )
{
register char *d = dst;
register const char *s = src;
register size_t n = size;
size_t dlen;
if( !dst || !src || !size )
return 0;
// find the end of dst and adjust bytes left but don't go past end
while( n-- != 0 && *d != '\0' ) d++;
dlen = d - dst;
n = size - dlen;
if( n == 0 ) return( dlen + com_strlen( s ));
while( *s != '\0' )
{
if( n != 1 )
{
*d++ = *s;
n--;
}
s++;
}
*d = '\0';
return( dlen + ( s - src )); // count does not include NULL
}
size_t com_strcat( char *dst, const char *src )
{
return com_strncat( dst, src, 99999 );
}
size_t com_strncpy( char *dst, const char *src, size_t size )
{
register char *d = dst;
register const char *s = src;
register size_t n = size;
if( !dst || !src || !size )
return 0;
// copy as many bytes as will fit
if( n != 0 && --n != 0 )
{
do
{
if(( *d++ = *s++ ) == 0 )
break;
} while( --n != 0 );
}
// not enough room in dst, add NULL and traverse rest of src
if( n == 0 )
{
if( size != 0 )
*d = '\0'; // NULL-terminate dst
while( *s++ );
}
return ( s - src - 1 ); // count does not include NULL
}
size_t com_strcpy( char *dst, const char *src )
{
return com_strncpy( dst, src, 99999 );
}
int com_atoi( const char *str )
{
int val = 0;
int c, sign;
if( !str ) return 0;
// check for empty charachters in string
while( *str == ' ' && str ) str++;
if( *str == '-' )
{
sign = -1;
str++;
}
else sign = 1;
// check for hex
if( str[0] == '0' && ( str[1] == 'x' || str[1] == 'X' ))
{
str += 2;
while( 1 )
{
c = *str++;
if( c >= '0' && c <= '9' ) val = (val<<4) + c - '0';
else if( c >= 'a' && c <= 'f' ) val = (val<<4) + c - 'a' + 10;
else if( c >= 'A' && c <= 'F' ) val = (val<<4) + c - 'A' + 10;
else return val * sign;
}
}
// check for character
if( str[0] == '\'' )
return sign * str[1];
// assume decimal
while( 1 )
{
c = *str++;
if( c < '0' || c > '9' )
return val * sign;
val = val * 10 + c - '0';
}
return 0;
}
float com_atof( const char *str )
{
double val = 0;
int c, sign, decimal, total;
if( !str ) return 0.0f;
// check for empty charachters in string
while( *str == ' ' && str ) str++;
if( *str == '-' )
{
sign = -1;
str++;
}
else sign = 1;
// check for hex
if( str[0] == '0' && ( str[1] == 'x' || str[1] == 'X' ))
{
str += 2;
while( 1 )
{
c = *str++;
if( c >= '0' && c <= '9' ) val = (val * 16) + c - '0';
else if( c >= 'a' && c <= 'f' ) val = (val * 16) + c - 'a' + 10;
else if( c >= 'A' && c <= 'F' ) val = (val * 16) + c - 'A' + 10;
else return val * sign;
}
}
// check for character
if( str[0] == '\'' ) return sign * str[1];
// assume decimal
decimal = -1;
total = 0;
while( 1 )
{
c = *str++;
if( c == '.' )
{
decimal = total;
continue;
}
if( c < '0' || c > '9' )
break;
val = val * 10 + c - '0';
total++;
}
if( decimal == -1 )
return val * sign;
while( total > decimal )
{
val /= 10;
total--;
}
return val * sign;
}
void com_atov( float *vec, const char *str, size_t siz )
{
string buffer;
char *pstr, *pfront;
int j;
com_strncpy( buffer, str, sizeof( buffer ));
Mem_Set( vec, 0, sizeof( float ) * siz );
pstr = pfront = buffer;
for( j = 0; j < siz; j++ )
{
vec[j] = com.atof( pfront );
// valid separator is space
while( *pstr && *pstr != ' ' )
pstr++;
if( !*pstr ) break;
pstr++;
pfront = pstr;
}
}
/*
============
strchr
find one charcster in string
============
*/
char *com_strchr( const char *s, char c )
{
int len = com_strlen( s );
while( len-- )
{
if( *++s == c )
return(char *)s;
}
return 0;
}
/*
============
strrchr
find one charcster in string
============
*/
char *com_strrchr( const char *s, char c )
{
int len = com_strlen( s );
s += len;
while( len-- )
{
if( *--s == c )
return (char *)s;
}
return 0;
}
int com_strnicmp( const char *s1, const char *s2, int n )
{
int c1, c2;
if( s1 == NULL )
{
if( s2 == NULL ) return 0;
else return -1;
}
else if( s2 == NULL ) return 1;
do {
c1 = *s1++;
c2 = *s2++;
if( !n-- ) return 0; // strings are equal until end point
if( c1 != c2 )
{
if( c1 >= 'a' && c1 <= 'z' ) c1 -= ('a' - 'A');
if( c2 >= 'a' && c2 <= 'z' ) c2 -= ('a' - 'A');
if( c1 != c2 ) return c1 < c2 ? -1 : 1;
}
} while( c1 );
// strings are equal
return 0;
}
int com_strncmp( const char *s1, const char *s2, int n )
{
int c1, c2;
if( s1 == NULL )
{
if( s2 == NULL ) return 0;
else return -1;
}
else if( s2 == NULL ) return 1;
do {
c1 = *s1++;
c2 = *s2++;
// strings are equal until end point
if( !n-- ) return 0;
if( c1 != c2 ) return c1 < c2 ? -1 : 1;
} while( c1 );
// strings are equal
return 0;
}
int com_stricmp( const char *s1, const char *s2 )
{
return com_strnicmp( s1, s2, 99999 );
}
int com_strcmp( const char *s1, const char *s2 )
{
return com_strncmp( s1, s2, 99999 );
}
/*
==============
Q_WildCmpAfterStar
==============
*/
static qboolean com_starcmp( const char *pattern, const char *text )
{
char c, c1;
const char *p = pattern, *t = text;
while(( c = *p++ ) == '?' || c == '*' )
{
if( c == '?' && *t++ == '\0' )
return false;
}
if( c == '\0' ) return true;
for( c1 = (( c == '\\' ) ? *p : c ); ; )
{
if( com_tolower( *t ) == c1 && com_stricmpext( p - 1, t ))
return true;
if( *t++ == '\0' ) return false;
}
}
/*
==============
stricmpext
==============
*/
qboolean com_stricmpext( const char *pattern, const char *text )
{
char c;
while(( c = *pattern++ ) != '\0' )
{
switch( c )
{
case '?':
if( *text++ == '\0' )
return false;
break;
case '\\':
if( com_tolower( *pattern++ ) != com_tolower( *text++ ))
return false;
break;
case '*':
return com_starcmp( pattern, text );
default:
if( com_tolower( c ) != com_tolower( *text++ ))
return false;
}
}
return ( *text == '\0' );
}
/*
====================
timestamp
====================
*/
const char* com_timestamp( int format )
const char *timestamp( int format )
{
static string timestamp;
time_t crt_time;
@ -542,187 +49,10 @@ const char* com_timestamp( int format )
default: return NULL;
}
com_strncpy( timestamp, timestring, sizeof( timestamp ));
strncpy( timestamp, timestring, sizeof( timestamp ));
return timestamp;
}
/*
============
strstr
search case - sensitive for string2 in string
============
*/
char *com_strstr( const char *string, const char *string2 )
{
int c, len;
if( !string || !string2 ) return NULL;
c = *string2;
len = com_strlen( string2 );
while( string )
{
for( ; *string && *string != c; string++ );
if( *string )
{
if( !com_strncmp( string, string2, len ))
break;
string++;
}
else return NULL;
}
return (char *)string;
}
/*
============
stristr
search case - insensitive for string2 in string
============
*/
char *com_stristr( const char *string, const char *string2 )
{
int c, len;
if( !string || !string2 ) return NULL;
c = com_tolower( *string2 );
len = com_strlen( string2 );
while( string )
{
for( ; *string && com_tolower( *string ) != c; string++ );
if( *string )
{
if( !com_strnicmp( string, string2, len ))
break;
string++;
}
else return NULL;
}
return (char *)string;
}
int com_vsnprintf( char *buffer, size_t buffersize, const char *format, va_list args )
{
size_t result;
result = _vsnprintf( buffer, buffersize, format, args );
if( result < 0 || result >= buffersize )
{
buffer[buffersize - 1] = '\0';
return -1;
}
return result;
}
int com_vsprintf( char *buffer, const char *format, va_list args )
{
return com_vsnprintf( buffer, 99999, format, args );
}
int com_snprintf( char *buffer, size_t buffersize, const char *format, ... )
{
va_list args;
int result;
va_start( args, format );
result = com_vsnprintf( buffer, buffersize, format, args );
va_end( args );
return result;
}
int com_sprintf( char *buffer, const char *format, ... )
{
va_list args;
int result;
va_start( args, format );
result = com_vsnprintf( buffer, 99999, format, args );
va_end( args );
return result;
}
char *com_pretifymem( float value, int digitsafterdecimal )
{
static char output[8][32];
static int current;
float onekb = 1024.0f;
float onemb = onekb * onekb;
char suffix[8];
char *out = output[current];
char val[32], *i, *o, *dot;
int pos;
current = ( current + 1 ) & ( 8 - 1 );
// first figure out which bin to use
if( value > onemb )
{
value /= onemb;
com_sprintf( suffix, " Mb" );
}
else if( value > onekb )
{
value /= onekb;
com_sprintf( suffix, " Kb" );
}
else com_sprintf( suffix, " bytes" );
// clamp to >= 0
digitsafterdecimal = max( digitsafterdecimal, 0 );
// if it's basically integral, don't do any decimals
if( fabs( value - (int)value ) < 0.00001 )
{
com_sprintf( val, "%i%s", (int)value, suffix );
}
else
{
char fmt[32];
// otherwise, create a format string for the decimals
com_sprintf( fmt, "%%.%if%s", digitsafterdecimal, suffix );
com_sprintf( val, fmt, value );
}
// copy from in to out
i = val;
o = out;
// search for decimal or if it was integral, find the space after the raw number
dot = com_strstr( i, "." );
if( !dot ) dot = com_strstr( i, " " );
pos = dot - i; // compute position of dot
pos -= 3; // don't put a comma if it's <= 3 long
while( *i )
{
// if pos is still valid then insert a comma every third digit, except if we would be
// putting one in the first spot
if( pos >= 0 && !( pos % 3 ))
{
// never in first spot
if( o != out ) *o++ = ',';
}
pos--; // count down comma position
*o++ = *i++; // copy rest of data as normal
}
*o = 0; // terminate
return out;
}
/*
============
va
@ -741,7 +71,7 @@ char *va( const char *format, ... )
s = string[stringindex];
stringindex = (stringindex + 1) & 255;
va_start( argptr, format );
com_vsnprintf( s, sizeof( string[0] ), format, argptr );
_vsnprintf( s, sizeof( string[0] ), format, argptr );
va_end( argptr );
return s;
@ -758,7 +88,7 @@ void Com_FileBase( const char *in, char *out )
{
int len, start, end;
len = com.strlen( in );
len = strlen( in );
if( !len ) return;
// scan backward for '.'
@ -786,6 +116,6 @@ void Com_FileBase( const char *in, char *out )
len = end - start + 1;
// Copy partial string
com.strncpy( out, &in[start], len + 1 );
strncpy( out, &in[start], len + 1 );
out[len] = 0;
}

View File

@ -8,6 +8,7 @@
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 ) };
@ -38,59 +39,6 @@ void Sys_GetStdAPI( void )
com.Com_GetParm = Sys_GetParmFromCmdLine; // get argument for specified parm
com.input = Con_Input;
// memlib.c
com.memcpy = _crt_mem_copy; // first time using
com.memset = _crt_mem_set; // first time using
com.realloc = _mem_realloc;
com.move = _mem_move;
com.malloc = _mem_alloc;
com.free = _mem_free;
com.is_allocated = _is_allocated;
com.mallocpool = _mem_allocpool;
com.freepool = _mem_freepool;
com.clearpool = _mem_emptypool;
com.memcheck = _mem_check;
com.memlist = _mem_printlist;
com.memstats = _mem_printstats;
com.Com_LoadLibrary = Sys_LoadLibrary; // load library
com.Com_FreeLibrary = Sys_FreeLibrary; // free library
com.Com_GetProcAddress = Sys_GetProcAddress; // gpa
// stdlib.c funcs
com.strnupr = com_strnupr;
com.strnlwr = com_strnlwr;
com.strupr = com_strupr;
com.strlwr = com_strlwr;
com.strlen = com_strlen;
com.cstrlen = com_cstrlen;
com.toupper = com_toupper;
com.tolower = com_tolower;
com.strncat = com_strncat;
com.strcat = com_strcat;
com.strncpy = com_strncpy;
com.strcpy = com_strcpy;
com.is_digit = com_isdigit;
com.atoi = com_atoi;
com.atof = com_atof;
com.atov = com_atov;
com.strchr = com_strchr;
com.strrchr = com_strrchr;
com.strnicmp = com_strnicmp;
com.stricmp = com_stricmp;
com.strncmp = com_strncmp;
com.strcmp = com_strcmp;
com.stristr = com_stristr;
com.strstr = com_strstr;
com.vsprintf = com_vsprintf;
com.sprintf = com_sprintf;
com.stricmpext = com_stricmpext;
com.va = va;
com.vsnprintf = com_vsnprintf;
com.snprintf = com_snprintf;
com.pretifymem = com_pretifymem;
com.timestamp = com_timestamp;
com.SysInfo = &SI;
}
@ -108,42 +56,42 @@ NOTE: at this day we have ten instances
*/
void Sys_LookupInstance( void )
{
char szTemp[4096];
char szTemp[128];
qboolean dedicated = false;
Sys.app_name = HOST_OFFLINE;
// we can specified custom name, from Sys_NewInstance
if( GetModuleFileName( NULL, szTemp, MAX_SYSPATH ) && Sys.app_state != SYS_RESTART )
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] == '©' ) com.strcpy( Sys.progname, "credits" );
if( SI.ModuleName[0] == '©' ) strcpy( Sys.progname, "credits" );
// cutoff hidden symbols
com.strncpy( szTemp, SI.ModuleName + 1, MAX_SYSPATH );
com.strncpy( SI.ModuleName, szTemp, MAX_SYSPATH );
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
com.strncpy( SI.ModuleName, Sys.progname + 1, MAX_SYSPATH );
com.strncpy( Sys.progname, "normal", MAX_SYSPATH ); // set as "normal"
strncpy( SI.ModuleName, Sys.progname + 1, sizeof( SI.ModuleName ));
strncpy( Sys.progname, "normal", sizeof( Sys.progname )); // set as "normal"
}
// lookup all instances
if( !com.strcmp( Sys.progname, "credits" ))
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
com.strcpy( Sys.caption, "About" );
strcpy( Sys.caption, "About" );
Sys.con_showcredits = true;
}
else if( !com.strcmp( Sys.progname, "normal" ))
else if( !strcmp( Sys.progname, "normal" ))
{
if( dedicated )
{
@ -162,21 +110,19 @@ void Sys_LookupInstance( void )
CloseHandle( Sys.hMutex );
Sys.hMutex = CreateSemaphore( NULL, 0, 1, "Xash Dedicated Server" );
if( !Sys.developer ) Sys.developer = 3; // otherwise we see empty console
com.sprintf( Sys.log_path, "dedicated.log", com.timestamp( TIME_FILENAME )); // logs folder
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;
com.sprintf( Sys.log_path, "engine.log", com.timestamp( TIME_FILENAME )); // logs folder
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
com.strcpy( Sys.caption, "Xash3D" );
strcpy( Sys.caption, "Xash3D" );
}
// share instance over all system
@ -212,7 +158,7 @@ void Sys_CreateInstance( void )
Sys.Crashed = Host->Crashed;
break;
case HOST_CREDITS:
Sys_Break( show_credits, com.timestamp( TIME_YEAR_ONLY ));
Sys_Break( show_credits, timestamp( TIME_YEAR_ONLY ));
break;
case HOST_OFFLINE:
Sys_Break( "Host offline\n" );
@ -285,18 +231,18 @@ void Sys_MergeCommandLine( LPSTR lpCmdLine )
for( i = 0; i < Sys.argc; i++ )
{
// we wan't return to first game
if( !com.stricmp( "-game", Sys.argv[i] )) Sys.argv[i] = (char *)blank;
if( !stricmp( "-game", Sys.argv[i] )) Sys.argv[i] = (char *)blank;
// probably it's timewaster, because engine rejected second change
if( !com.stricmp( "+game", Sys.argv[i] )) Sys.argv[i] = (char *)blank;
if( !stricmp( "+game", Sys.argv[i] )) Sys.argv[i] = (char *)blank;
// you sure what is map exists in new game?
if( !com.stricmp( "+map", Sys.argv[i] )) Sys.argv[i] = (char *)blank;
if( !stricmp( "+map", Sys.argv[i] )) Sys.argv[i] = (char *)blank;
// just stupid action
if( !com.stricmp( "+load", Sys.argv[i] )) Sys.argv[i] = (char *)blank;
if( !stricmp( "+load", Sys.argv[i] )) Sys.argv[i] = (char *)blank;
// changelevel beetwen games? wow it's great idea!
if( !com.stricmp( "+changelevel", Sys.argv[i] )) Sys.argv[i] = (char *)blank;
if( !stricmp( "+changelevel", Sys.argv[i] )) Sys.argv[i] = (char *)blank;
// second call
if( Sys.app_name == HOST_DEDICATED && !com.strnicmp( "+menu_", Sys.argv[i], 6 ))
if( Sys.app_name == HOST_DEDICATED && !strnicmp( "+menu_", Sys.argv[i], 6 ))
Sys.argv[i] = (char *)blank;
}
}
@ -322,8 +268,8 @@ void Sys_Print( const char *pMsg )
Sys.CPrint( pMsg );
// if the message is REALLY long, use just the last portion of it
if( com.strlen( pMsg ) > sizeof( buffer ) - 1 )
msg = pMsg + com.strlen( pMsg ) - sizeof( buffer ) + 1;
if( strlen( pMsg ) > sizeof( buffer ) - 1 )
msg = pMsg + strlen( pMsg ) - sizeof( buffer ) + 1;
else msg = pMsg;
// copy into an intermediate buffer
@ -388,7 +334,7 @@ void Sys_Msg( const char *pMsg, ... )
char text[8192];
va_start( argptr, pMsg );
com.vsnprintf( text, sizeof( text ), pMsg, argptr );
_vsnprintf( text, sizeof( text ), pMsg, argptr );
va_end( argptr );
Sys_Print( text );
@ -402,7 +348,7 @@ void Sys_MsgDev( int level, const char *pMsg, ... )
if( Sys.developer < level ) return;
va_start( argptr, pMsg );
com.vsnprintf( text, sizeof( text ), pMsg, argptr );
_vsnprintf( text, sizeof( text ), pMsg, argptr );
va_end( argptr );
switch( level )
@ -458,7 +404,7 @@ int Sys_CheckParm( const char *parm )
{
// NEXTSTEP sometimes clears appkit vars.
if( !Sys.argv[i] ) continue;
if( !com.stricmp( parm, Sys.argv[i] )) return i;
if( !stricmp( parm, Sys.argv[i] )) return i;
}
return 0;
}
@ -478,7 +424,7 @@ qboolean Sys_GetParmFromCmdLine( char *parm, char *out, size_t size )
if( !out ) return false;
if( !Sys.argv[argc + 1] ) return false;
com.strncpy( out, Sys.argv[argc+1], size );
strncpy( out, Sys.argv[argc+1], size );
return true;
}
@ -507,7 +453,8 @@ void Sys_WaitForQuit( void )
MSG msg;
Con_RegisterHotkeys();
Mem_Set( &msg, 0, sizeof( msg ));
msg.message = 0;
// wait for the user to quit
while( msg.message != WM_QUIT )
@ -545,7 +492,7 @@ void Sys_Error( const char *error, ... )
Sys.error = true;
Sys.app_state = SYS_ERROR;
va_start( argptr, error );
com.vsprintf( text, error, argptr );
vsprintf( text, error, argptr );
va_end( argptr );
if( Sys.app_name == HOST_NORMAL )
@ -575,7 +522,7 @@ void Sys_Break( const char *error, ... )
return; // don't multiple executes
va_start( argptr, error );
com.vsprintf( text, error, argptr );
vsprintf( text, error, argptr );
va_end( argptr );
Sys.error = true;
@ -661,8 +608,8 @@ void Sys_Init( void )
{
if( Sys_GetParmFromCmdLine( "-dev", dev_level, sizeof( dev_level )))
{
if( com.is_digit( dev_level ))
Sys.developer = abs( com.atoi( 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
@ -687,15 +634,12 @@ void Sys_Init( void )
// first text message into console or log
MsgDev( D_NOTE, "Sys_LoadLibrary: Loading launch.dll - ok\n" );
if( com.strlen( Sys.fmessage ) && !Sys.con_showcredits )
if( strlen( Sys.fmessage ) && !Sys.con_showcredits )
{
Sys_Print( Sys.fmessage );
Sys.fmessage[0] = '\0';
}
Memory_Init();
Sys_InitCPU();
SI.developer = Sys.developer;
Sys_CreateInstance();
}
@ -707,7 +651,6 @@ void Sys_Shutdown( void )
Sys_FreeLibrary( Sys.linked_dll );
Sys.CPrint = NullPrint;
Memory_Shutdown();
Con_DestroyConsole();
// restore filter
@ -769,7 +712,7 @@ qboolean Sys_LoadLibrary( const char *dll_name, dll_info_t *dll )
// no DLL found
if( !dll->link )
{
com.sprintf( errorstring, "Sys_LoadLibrary: couldn't load %s\n", dll->name );
sprintf( errorstring, "Sys_LoadLibrary: couldn't load %s\n", dll->name );
goto error;
}
@ -777,7 +720,7 @@ qboolean Sys_LoadLibrary( const char *dll_name, dll_info_t *dll )
{
if(( dll->main = Sys_GetProcAddress( dll, dll->entry )) == 0 )
{
com.sprintf( errorstring, "Sys_LoadLibrary: %s has no valid entry point\n", dll->name );
sprintf( errorstring, "Sys_LoadLibrary: %s has no valid entry point\n", dll->name );
goto error;
}
}
@ -788,7 +731,7 @@ qboolean Sys_LoadLibrary( const char *dll_name, dll_info_t *dll )
{
if( !( *func->func = Sys_GetProcAddress( dll, func->name )))
{
com.sprintf( errorstring, "Sys_LoadLibrary: %s missing or invalid function (%s)\n", dll->name, func->name );
sprintf( errorstring, "Sys_LoadLibrary: %s missing or invalid function (%s)\n", dll->name, func->name );
goto error;
}
}
@ -804,17 +747,17 @@ qboolean Sys_LoadLibrary( const char *dll_name, dll_info_t *dll )
if( !check )
{
com.sprintf( errorstring, "Sys_LoadLibrary: \"%s\" have no export\n", dll->name );
sprintf( errorstring, "Sys_LoadLibrary: \"%s\" have no export\n", dll->name );
goto error;
}
if( check->api_size != dll->api_size )
{
com.sprintf( errorstring, "Sys_LoadLibrary: \"%s\" mismatch interface size (%i should be %i)\n", dll->name, 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 )
{
com.sprintf( errorstring, "Sys_LoadLibrary: \"%s\" mismatch stdlib api size (%i should be %i)\n", dll->name, 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;
}
}
@ -870,13 +813,13 @@ void Sys_NewInstance( const char *name, const char *fmsg )
string tmp;
// save parms
com.strncpy( tmp, name, sizeof( tmp ));
com.strncpy( Sys.fmessage, fmsg, sizeof( Sys.fmessage ));
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
com.strncpy( SI.ModuleName, tmp, sizeof( SI.ModuleName ));
strncpy( SI.ModuleName, tmp, sizeof( SI.ModuleName ));
// NOTE: we never return to old instance,
// because Sys_Exit call exit(0); and terminate program
@ -898,7 +841,7 @@ Main Entry Point
*/
EXPORT int CreateAPI( const char *hostname, qboolean console )
{
com_strncpy( Sys.progname, hostname, sizeof( Sys.progname ));
strncpy( Sys.progname, hostname, sizeof( Sys.progname ));
Sys_Init();
Sys.Main();