qboolean COM_IsUint( const char *s ) { int c; if( !*s ) { return qfalse; } do { c = *s++; if( !Q_isdigit( c ) ) { return qfalse; } } while( *s ); return qtrue; }
/* ================== COM_IsFloat Returns true if the given string is valid representation of floating point number. ================== */ qboolean COM_IsFloat( const char *s ) { int c, dot = '.'; if( *s == '-' ) { s++; } if( !*s ) { return qfalse; } do { c = *s++; if( c == dot ) { dot = 0; } else if( !Q_isdigit( c ) ) { return qfalse; } } while( *s ); return qtrue; }
// scan g_Sentences, looking for pszin sentence name // return pointer to sentence data if found, null if not // CONSIDER: if we have a large number of sentences, should // CONSIDER: sort strings in g_Sentences and do binary search. char *VOX_LookupString( const char *pSentenceName, int *psentencenum ) { int i; if( Q_isdigit( pSentenceName ) && (i = Q_atoi( pSentenceName )) < g_numSentences ) { if( psentencenum ) *psentencenum = i; return (g_Sentences[i].pName + Q_strlen( g_Sentences[i].pName ) + 1 ); } for( i = 0; i < g_numSentences; i++ ) { if( !Q_stricmp( pSentenceName, g_Sentences[i].pName )) { if( psentencenum ) *psentencenum = i; return (g_Sentences[i].pName + Q_strlen( g_Sentences[i].pName ) + 1 ); } } return NULL; }
char *Cvar_CopyString( const char *in, int tag ) { char *out; int len; zstatic_t *z; #ifndef NDEBUG if (!in) Com_Error (ERR_FATAL, "CopyString: in == NULL, tagged %i:%s!", tag, z_stats[(unsigned)tag < TAG_MAX_TAGS ? tag : TAG_NOT_TAGGED].name); #endif if( !in[0] ) { z = &z_static[10]; z_stats[TAG_STATIC].count++; z_stats[TAG_STATIC].bytes += z->z.size; return z->data; } if( !in[1] && Q_isdigit( in[0] ) ) { z = &z_static[ in[0] - '0' ]; z_stats[TAG_STATIC].count++; z_stats[TAG_STATIC].bytes += z->z.size; return z->data; } len = strlen(in); #ifndef NDEBUG out = _Z_TagMalloc (len+1, tag, "Cvar_CopyString", 1); #else out = Z_TagMalloc (len+1, tag); #endif strcpy( out, in ); return out; }
/* * GS_Cmd_UseItem */ gsitem_t *GS_Cmd_UseItem( player_state_t *playerState, const char *string, int typeMask ) { gsitem_t *item = NULL; assert( playerState ); if( playerState->pmove.pm_type >= PM_SPECTATOR ) return NULL; if( !string || !string[0] ) return NULL; if( Q_isdigit( string ) ) { int tag = atoi( string ); item = GS_FindItemByTag( tag ); } else item = GS_FindItemByName( string ); if( !item ) return NULL; if( typeMask && !( item->type & typeMask ) ) return NULL; // we don't have this item in the inventory if( !playerState->inventory[item->tag] ) { if( gs.module == GS_MODULE_CGAME && !( item->type & IT_WEAPON ) ) module_Printf( "Item %s is not in inventory\n", item->name ); return NULL; } // see if we can use it if( !(item->flags & ITFLAG_USABLE) ) return NULL; if( item->type & IT_WEAPON ) { if( !( playerState->pmove.stats[PM_STAT_FEATURES] & PMFEAT_WEAPONSWITCH ) ) return NULL; if( item->tag == playerState->stats[STAT_PENDING_WEAPON] ) // it's already being loaded return NULL; // check for need of any kind of ammo/fuel/whatever if( item->ammo_tag != AMMO_NONE && item->weakammo_tag != AMMO_NONE ) { gs_weapon_definition_t *weapondef = GS_GetWeaponDef( item->tag ); if( weapondef ) { // do we have any of these ammos ? if( playerState->inventory[item->weakammo_tag] >= weapondef->firedef_weak.usage_count ) return item; if( playerState->inventory[item->ammo_tag] >= weapondef->firedef.usage_count ) return item; } return NULL; } return item; // one of the weapon modes doesn't require ammo to be fired } if( item->type & IT_AMMO ) return item; if( item->type & IT_HEALTH ) return item; if( item->type & IT_POWERUP ) return item; return NULL; }
/* ================== SV_SetPlayer Sets sv_client and sv_player to the player with idnum Cmd_Argv(1) ================== */ qboolean SV_SetPlayer( void ) { char *s; sv_client_t *cl; int i, idnum; if( !svs.clients || sv.background ) { Msg( "^3No server running.\n" ); return false; } if( sv_maxclients->integer == 1 || Cmd_Argc() < 2 ) { // special case for local client svs.currentPlayer = svs.clients; svs.currentPlayerNum = 0; return true; } s = Cmd_Argv( 1 ); // numeric values are just slot numbers if( Q_isdigit( s ) || (s[0] == '-' && Q_isdigit( s + 1 ))) { idnum = Q_atoi( s ); if( idnum < 0 || idnum >= sv_maxclients->integer ) { Msg( "Bad client slot: %i\n", idnum ); return false; } svs.currentPlayer = &svs.clients[idnum]; svs.currentPlayerNum = idnum; if( !svs.currentPlayer->state ) { Msg( "Client %i is not active\n", idnum ); return false; } return true; } // check for a name match for( i = 0, cl = svs.clients; i < sv_maxclients->integer; i++, cl++ ) { if( !cl->state ) continue; if( !Q_strcmp( cl->name, s )) { svs.currentPlayer = cl; svs.currentPlayerNum = (cl - svs.clients); return true; } } Msg( "Userid %s is not on the server\n", s ); svs.currentPlayer = NULL; svs.currentPlayerNum = 0; return false; }
/* ================= Host_InitCommon ================= */ void Host_InitCommon( int argc, const char** argv, const char *progname, qboolean bChangeGame ) { char dev_level[4]; char *baseDir; // some commands may turn engine into infinite loop, // e.g. xash.exe +game xash -game xash // so we clear all cmd_args, but leave dbg states as well Sys_ParseCommandLine( argc, argv ); host.enabledll = !Sys_CheckParm( "-nodll" ); host.shutdown_issued = false; host.crashed = false; #ifdef DLL_LOADER if( host.enabledll ) Setup_LDT_Keeper( ); // Must call before any thread creating #endif #if defined(XASH_SDL) && !(defined(PANDORA) || defined(RPI)) if( SDL_Init( SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK | SDL_INIT_EVENTS )) { Sys_Error( "SDL_Init: %s", SDL_GetError() ); } #endif if( ( baseDir = getenv( "XASH3D_BASEDIR" ) ) ) { Q_strncpy( host.rootdir, baseDir, sizeof(host.rootdir) ); } else { #if defined(PANDORA) || defined(RPI) Q_strncpy( host.rootdir, ".", sizeof( host.rootdir ) ); #else #if defined(XASH_SDL) if( !( baseDir = SDL_GetBasePath() ) ) Sys_Error( "couldn't determine current directory: %s", SDL_GetError() ); Q_strncpy( host.rootdir, baseDir, sizeof( host.rootdir ) ); #else if( !getcwd( host.rootdir, sizeof(host.rootdir) ) ) host.rootdir[0] = 0; #endif #endif } if( host.rootdir[Q_strlen( host.rootdir ) - 1] == '/' ) host.rootdir[Q_strlen( host.rootdir ) - 1] = 0; if( !Sys_CheckParm( "-noch" ) ) { Sys_SetupCrashHandler(); } host.change_game = bChangeGame; host.state = HOST_INIT; // initialization started host.developer = host.old_developer = 0; host.textmode = false; 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 } #ifdef XASH_DEDICATED host.type = HOST_DEDICATED; // predict state #else if( Sys_CheckParm("-dedicated") || progname[0] == '#' ) host.type = HOST_DEDICATED; else host.type = HOST_NORMAL; #endif host.con_showalways = true; host.mouse_visible = false; #ifdef XASH_SDL if( SDL_Init( SDL_INIT_TIMER | SDL_INIT_VIDEO | SDL_INIT_EVENTS )) { SDL_Init( SDL_INIT_TIMER ); host.type = HOST_DEDICATED; } #endif if ( SetCurrentDirectory( host.rootdir ) != 0) MsgDev( D_INFO, "%s is working directory now\n", host.rootdir ); else Sys_Error( "Changing working directory to %s failed.\n", host.rootdir ); // set default gamedir if( progname[0] == '#' ) progname++; Q_strncpy( SI.ModuleName, progname, sizeof( SI.ModuleName )); if( host.type == HOST_DEDICATED ) { Sys_MergeCommandLine( ); if( host.developer < 3 ) host.developer = 3; // otherwise we see empty console } else { // don't show console as default if( host.developer < D_WARN ) host.con_showalways = false; } host.old_developer = host.developer; if( !Sys_CheckParm( "-nowcon" ) ) Con_CreateConsole(); // first text message into console or log MsgDev( D_NOTE, "Sys_LoadLibrary: Loading Engine Library - ok\n" ); // startup cmds and cvars subsystem Cmd_Init(); Cvar_Init(); // share developer level across all dlls 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" ); Cmd_AddCommand( "userconfigd", Host_Userconfigd_f, "execute all scripts from userconfig.d" ); cmd_scripting = Cvar_Get( "cmd_scripting", "0", CVAR_ARCHIVE, "enable simple condition checking and variable operations" ); FS_Init(); Image_Init(); Sound_Init(); FS_LoadGameInfo( NULL ); Q_strncpy( host.gamefolder, GI->gamefolder, sizeof( host.gamefolder )); #if !(defined(PANDORA) || defined(RPI)) if( GI->secure ) { // clear all developer levels when game is protected Cvar_FullSet( "developer", "0", CVAR_INIT ); host.developer = host.old_developer = 0; host.con_showalways = false; } #endif HPAK_Init(); IN_Init(); Key_Init(); }
/* ================= Host_InitCommon ================= */ void Host_InitCommon( const char* moduleName, const char* cmdLine, const char *progname, qboolean bChangeGame ) { char dev_level[4]; char szTemp[MAX_SYSPATH]; string szRootPath; #ifdef _WIN32 MEMORYSTATUS lpBuffer; lpBuffer.dwLength = sizeof( MEMORYSTATUS ); GlobalMemoryStatus( &lpBuffer ); #endif #ifndef __ANDROID__ if( !(SDL_GetBasePath()) ) Sys_Error( "couldn't determine current directory" ); Q_strncpy(host.rootdir, SDL_GetBasePath(), sizeof(host.rootdir)); if( host.rootdir[Q_strlen( host.rootdir ) - 1] == '/' ) host.rootdir[Q_strlen( host.rootdir ) - 1] = 0; #else Q_strncpy(host.rootdir, GAMEPATH, sizeof(host.rootdir)); #endif #ifdef _WIN32 host.oldFilter = SetUnhandledExceptionFilter( Sys_Crash ); host.hInst = GetModuleHandle( NULL ); #endif host.change_game = bChangeGame; host.state = HOST_INIT; // initialzation started host.developer = host.old_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 if( cmdLine ) Sys_ParseCommandLine( cmdLine ); #ifdef _WIN32 SetErrorMode( SEM_FAILCRITICALERRORS ); // no abort/retry/fail errors #endif 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; #ifdef PANDORA if( Sys_CheckParm( "-noshouldermb" )) noshouldermb = 1; #endif #ifdef __ANDROID__ if (chdir(host.rootdir) == 0) MsgDev(D_INFO,"%s is working directory now",host.rootdir); else MsgDev(D_ERROR,"%s is not exists",host.rootdir); #else // we can specified custom name, from Sys_NewInstance if( SDL_GetBasePath() && !host.change_game ) { Q_strncpy( szTemp, SDL_GetBasePath(), sizeof(szTemp) ); FS_FileBase( szTemp, SI.ModuleName ); } if(moduleName) Q_strncpy(SI.ModuleName, moduleName, sizeof(SI.ModuleName)); FS_ExtractFilePath( SI.ModuleName, szRootPath ); if( Q_stricmp( host.rootdir, szRootPath )) { Q_strncpy( host.rootdir, szRootPath, sizeof( host.rootdir )); #ifdef _WIN32 SetCurrentDirectory( host.rootdir ); #else chdir( host.rootdir ); #endif } #endif 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 = SDL_CreateMutex( ); if( !host.hMutex ) { MSGBOX( "Dedicated server already running" ); Sys_Quit(); return; } Sys_MergeCommandLine( cmdLine ); SDL_DestroyMutex( host.hMutex ); host.hMutex = SDL_CreateSemaphore( 0 ); if( host.developer < 3 ) host.developer = 3; // otherwise we see empty console } else { // don't show console as default if( host.developer < D_WARN ) host.con_showalways = false; } host.old_developer = host.developer; Con_CreateConsole(); // first text message into console or log MsgDev( D_NOTE, "Sys_LoadLibrary: Loading xash.dll - ok\n" ); // startup cmds and cvars subsystem Cmd_Init(); Cvar_Init(); // share developer level across all dlls 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" ); FS_Init(); Image_Init(); Sound_Init(); FS_LoadGameInfo( NULL ); Q_strncpy( host.gamefolder, GI->gamefolder, sizeof( host.gamefolder )); if( GI->secure ) { // clear all developer levels when game is protected Cvar_FullSet( "developer", "0", CVAR_INIT ); host.developer = host.old_developer = 0; host.con_showalways = false; } HPAK_Init(); IN_Init(); Key_Init(); }