/* ==================== CL_Init ==================== */ void CL_Init( void ) { qboolean loaded; Q_memset( &cls, 0, sizeof( cls ) ); if( Host_IsDedicated() ) return; // nothing running on the client Con_Init(); CL_InitLocal(); R_Init(); // init renderer S_Init(); // init sound // unreliable buffer. unsed for unreliable commands and voice stream BF_Init( &cls.datagram, "cls.datagram", cls.datagram_buf, sizeof( cls.datagram_buf )); IN_TouchInit(); #if defined (__ANDROID__) { char clientlib[256]; Q_snprintf( clientlib, sizeof(clientlib), "%s/" CLIENTDLL, getenv("XASH3D_GAMELIBDIR")); loaded = CL_LoadProgs( clientlib ); if( !loaded ) { Q_snprintf( clientlib, sizeof(clientlib), "%s/" CLIENTDLL, getenv("XASH3D_ENGLIBDIR")); loaded = CL_LoadProgs( clientlib ); } } #else { char clientlib[256]; Com_ResetLibraryError(); if( Sys_GetParmFromCmdLine( "-clientlib", clientlib ) ) loaded = CL_LoadProgs( clientlib ); else loaded = CL_LoadProgs( va( "%s/%s" , GI->dll_path, SI.clientlib )); if( !loaded ) { loaded = CL_LoadProgs( CLIENTDLL ); } } #endif if( loaded ) { cls.initialized = true; cls.keybind_changed = false; cl.maxclients = 1; // allow to drawing player in menu cls.olddemonum = -1; cls.demonum = -1; } else Sys_Warn("Could not load client library:\n%s", Com_GetLibraryError()); }
/* ================ FS_Init ================ */ void CFileSystem::Init() { mpLowLevelFileSystem->Init(); tStringList dirs; bool hasDefaultDir = false; int i; // Init memory fs_mempool = Mem_AllocPool( "FileSystem Pool" ); // add a path separator to the end of the basedir if it lacks one if( fs_basedir[0] && fs_basedir[Q_strlen(fs_basedir) - 1] != '/' && fs_basedir[Q_strlen(fs_basedir) - 1] != '\\' ) Q_strncat( fs_basedir, "/", sizeof( fs_basedir )); fs_searchpaths = NULL; mpConsole->AddCommand("fs_rescan", FS_Rescan_f, "rescan filesystem search pathes"); mpConsole->AddCommand("fs_path", FS_Path_f, "show filesystem search pathes"); mpConsole->AddCommand("fs_clearpaths", FS_ClearPaths_f, "clear filesystem search pathes"); // ignore commandlineoption "-game" for other stuff if( host.type == HOST_NORMAL || host.type == HOST_DEDICATED ) { stringlistinit( &dirs ); listdirectory( &dirs, "./" ); stringlistsort( &dirs ); SI.numgames = 0; if( !Sys_GetParmFromCmdLine( "-game", gs_basedir )) Q_strcpy( gs_basedir, SI.ModuleName ); // default dir if( FS_CheckNastyPath( gs_basedir, true )) { DevMsg( D_ERROR, "FS_Init: invalid game directory \"%s\"\n", gs_basedir ); Q_strcpy( gs_basedir, SI.ModuleName ); // default dir }; // validate directories for( i = 0; i < dirs.numstrings; i++ ) { if( !Q_stricmp( SI.ModuleName, dirs.strings[i] )) hasDefaultDir = true; if( !Q_stricmp( gs_basedir, dirs.strings[i] )) break; } if( i == dirs.numstrings ) { DevMsg( D_INFO, "FS_Init: game directory \"%s\" not exist\n", gs_basedir ); if(hasDefaultDir) Q_strncpy( gs_basedir, SI.ModuleName, sizeof( gs_basedir )); // default dir }; // build list of game directories here FS_AddGameDirectory( "./", 0 ); for( i = 0; i < dirs.numstrings; i++ ) { if(!mpLowLevelFileSystem->SysFolderExists( dirs.strings[i] ) || (!Q_stricmp( dirs.strings[i], ".." ) && !fs_ext_path )) continue; if( !SI.games[SI.numgames] ) SI.games[SI.numgames] = (gameinfo_t *)Mem_Alloc( fs_mempool, sizeof( gameinfo_t )); if( FS_ParseGameInfo( dirs.strings[i], SI.games[SI.numgames] )) SI.numgames++; // added }; stringlistfreecontents( &dirs ); }; MsgDev( D_NOTE, "FS_Init: done\n" ); };
/* ================= 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(); }
/* ================= 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(); }
/* ================ VGui_Startup Load vgui_support library and call VGui_Startup ================ */ void VGui_Startup( int width, int height ) { static qboolean failed = false; if( failed ) return; if(!vgui.initialized) { void (*F) ( vguiapi_t * ); char vguiloader[256]; char vguilib[256]; Com_ResetLibraryError(); // hack: load vgui with correct path first if specified. // it will be reused while resolving vgui support and client deps if( Sys_GetParmFromCmdLine( "-vguilib", vguilib ) ) { if( Q_strstr( vguilib, ".dll") ) Q_strncpy( vguiloader, "vgui_support.dll", 256 ); else Q_strncpy( vguiloader, VGUI_SUPPORT_DLL, 256 ); if( !Com_LoadLibrary( vguilib, false ) ) MsgDev( D_WARN, "VGUI preloading failed. Default library will be used!\n"); } if( !Sys_GetParmFromCmdLine( "-vguiloader", vguiloader ) ) Q_strncpy( vguiloader, VGUI_SUPPORT_DLL, 256 ); lib = Com_LoadLibrary( vguiloader, false ); if(!lib) MsgDev( D_ERROR, "Failed to load vgui_support library: %s", Com_GetLibraryError() ); else { F = Com_GetProcAddress( lib, "InitAPI" ); if( F ) { F( &vgui ); vgui.initialized = true; VGUI_InitCursors(); } else MsgDev( D_ERROR, "Failed to find vgui_support library entry point!\n" ); } } // vgui may crash if it cannot find font if( width <= 320 ) width = 320; else if( width <= 400 ) width = 400; else if( width <= 512 ) width = 512; else if( width <= 640 ) width = 640; else if( width <= 800 ) width = 800; else if( width <= 1024 ) width = 1024; else if( width <= 1152 ) width = 1152; else if( width <= 1280 ) width = 1280; else //if( width <= 1600 ) width = 1600; if( vgui.initialized ) { //host.mouse_visible = true; vgui.Startup( width, height ); } else failed = true; }