engine: move finding root/readonly directory to FS initialization, remove unused host.rodir, host.rootidr

This commit is contained in:
Alibek Omarov 2024-06-12 08:28:22 +03:00
parent a1dceacc8f
commit 393e31e509
3 changed files with 112 additions and 109 deletions

View file

@ -341,8 +341,6 @@ typedef struct host_parm_s
qboolean movevars_changed;
qboolean renderinfo_changed;
char rootdir[MAX_OSPATH]; // member root directory
char rodir[MAX_OSPATH]; // readonly root
char gamefolder[MAX_QPATH]; // it's a default gamefolder
poolhandle_t imagepool; // imagelib mempool
poolhandle_t soundpool; // soundlib mempool
@ -376,7 +374,6 @@ typedef void (*xcommand_t)( void );
//
// filesystem_engine.c
//
qboolean FS_LoadProgs( void );
void FS_Init( void );
void FS_Shutdown( void );
void *FS_GetNativeObject( const char *obj );

View file

@ -16,6 +16,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
#include <errno.h>
#include "common.h"
#include "library.h"
#include "platform/platform.h"
@ -26,6 +27,15 @@ fs_globals_t *FI;
static pfnCreateInterface_t fs_pfnCreateInterface;
static HINSTANCE fs_hInstance;
static void COM_StripDirectorySlash( char *pname )
{
size_t len;
len = Q_strlen( pname );
if( len > 0 && pname[len - 1] == '/' )
pname[len - 1] = 0;
}
void *FS_GetNativeObject( const char *obj )
{
if( fs_pfnCreateInterface )
@ -80,7 +90,7 @@ static void FS_UnloadProgs( void )
#define FILESYSTEM_STDIO_DLL "filesystem_stdio." OS_LIB_EXT
#endif
qboolean FS_LoadProgs( void )
static qboolean FS_LoadProgs( void )
{
const char *name = FILESYSTEM_STDIO_DLL;
FSAPI GetFSAPI;
@ -89,36 +99,104 @@ qboolean FS_LoadProgs( void )
if( !fs_hInstance )
{
Host_Error( "%s: can't load filesystem library %s: %s\n", __func__, name, COM_GetLibraryError() );
Sys_Error( "%s: can't load filesystem library %s: %s\n", __func__, name, COM_GetLibraryError() );
return false;
}
if( !( GetFSAPI = (FSAPI)COM_GetProcAddress( fs_hInstance, GET_FS_API )))
{
FS_UnloadProgs();
Host_Error( "%s: can't find GetFSAPI entry point in %s\n", __func__, name );
Sys_Error( "%s: can't find GetFSAPI entry point in %s\n", __func__, name );
return false;
}
if( GetFSAPI( FS_API_VERSION, &g_fsapi, &FI, &fs_memfuncs ) != FS_API_VERSION )
{
FS_UnloadProgs();
Host_Error( "%s: can't initialize filesystem API: wrong version\n", __func__ );
Sys_Error( "%s: can't initialize filesystem API: wrong version\n", __func__ );
return false;
}
if( !( fs_pfnCreateInterface = (pfnCreateInterface_t)COM_GetProcAddress( fs_hInstance, "CreateInterface" )))
{
FS_UnloadProgs();
Host_Error( "%s: can't find CreateInterface entry point in %s\n", __func__, name );
Sys_Error( "%s: can't find CreateInterface entry point in %s\n", __func__, name );
return false;
}
Con_DPrintf( "%s: filesystem_stdio successfully loaded\n", __func__ );
return true;
}
static qboolean FS_DetermineRootDirectory( char *out, size_t size )
{
const char *path = getenv( "XASH3D_BASEDIR" );
if( COM_CheckString( path ))
{
Q_strncpy( out, path, size );
return true;
}
#if TARGET_OS_IOS
Q_strncpy( out, IOS_GetDocsDir(), size );
return true;
#elif XASH_ANDROID && XASH_SDL
path = SDL_AndroidGetExternalStoragePath();
if( path != NULL )
{
Q_strncpy( out, path, size );
return true;
}
Sys_Error( "couldn't determine Android external storage path: %s", SDL_GetError( ));
return false;
#elif XASH_PSVITA
if( PSVita_GetBasePath( out, size ))
return true;
Sys_Error( "couldn't find Xash3D data directory" );
return false;
#elif ( XASH_SDL == 2 ) && !XASH_NSWITCH // GetBasePath not impl'd in switch-sdl2
path = SDL_GetBasePath();
if( path != NULL )
{
Q_strncpy( out, path, size );
SDL_free(( void *)path );
return true;
}
#if XASH_POSIX || XASH_WIN32
if( getcwd( out, size ))
return true;
Sys_Error( "couldn't determine current directory: %s, getcwd: %s", SDL_GetError(), strerror( errno ));
#else // !( XASH_POSIX || XASH_WIN32 )
Sys_Error( "couldn't determine current directory: %s", SDL_GetError( ));
#endif // !( XASH_POSIX || XASH_WIN32 )
return false;
#else // generic case
if( getcwd( out, size ))
return true;
Sys_Error( "couldn't determine current directory: %s", strerror( errno ));
return false;
#endif // generic case
}
static qboolean FS_DetermineReadOnlyRootDirectory( char *out, size_t size )
{
const char *env_rodir = getenv( "XASH3D_RODIR" );
if( _Sys_GetParmFromCmdLine( "-rodir", out, size ))
return true;
if( COM_CheckString( env_rodir ))
{
Q_strncpy( out, env_rodir, size );
return true;
}
return false;
}
/*
================
FS_Init
@ -127,20 +205,39 @@ FS_Init
void FS_Init( void )
{
string gamedir;
char rodir[MAX_OSPATH], rootdir[MAX_OSPATH];
rodir[0] = rootdir[0] = 0;
Cmd_AddRestrictedCommand( "fs_rescan", FS_Rescan_f, "rescan filesystem search pathes" );
Cmd_AddRestrictedCommand( "fs_path", FS_Path_f_, "show filesystem search pathes" );
Cmd_AddRestrictedCommand( "fs_clearpaths", FS_ClearPaths_f, "clear filesystem search pathes" );
if( !FS_DetermineRootDirectory( rootdir, sizeof( rootdir )) || !COM_CheckStringEmpty( rootdir ))
{
Sys_Error( "couldn't determine current directory (empty string)" );
return;
}
COM_FixSlashes( rootdir );
COM_StripDirectorySlash( rootdir );
FS_DetermineReadOnlyRootDirectory( rodir, sizeof( rodir ));
COM_FixSlashes( rodir );
COM_StripDirectorySlash( rodir );
if( !Sys_GetParmFromCmdLine( "-game", gamedir ))
Q_strncpy( gamedir, SI.basedirName, sizeof( gamedir )); // gamedir == basedir
if( !FS_InitStdio( true, host.rootdir, SI.basedirName, gamedir, host.rodir ))
FS_LoadProgs();
if( !FS_InitStdio( true, rootdir, SI.basedirName, gamedir, rodir ))
{
Host_Error( "Can't init filesystem_stdio!\n" );
Sys_Error( "Can't init filesystem_stdio!\n" );
return;
}
// TODO: this function will cause engine to stop in case of fail
// when it will have an option to return string error, restore Sys_Error
g_fsapi.SetCurrentDirectory( rootdir );
Cmd_AddRestrictedCommand( "fs_rescan", FS_Rescan_f, "rescan filesystem search pathes" );
Cmd_AddRestrictedCommand( "fs_path", FS_Path_f_, "show filesystem search pathes" );
Cmd_AddRestrictedCommand( "fs_clearpaths", FS_ClearPaths_f, "clear filesystem search pathes" );
if( !Sys_GetParmFromCmdLine( "-dll", SI.gamedll ))
SI.gamedll[0] = 0;

View file

@ -18,8 +18,6 @@ GNU General Public License for more details.
#include <SDL.h>
#endif // XASH_SDL
#include <stdarg.h> // va_args
#include <errno.h> // errno
#include <string.h> // strerror
#if !XASH_WIN32
#include <unistd.h> // fork
#include <sys/types.h>
@ -29,7 +27,6 @@ GNU General Public License for more details.
#if XASH_EMSCRIPTEN
#include <emscripten/emscripten.h>
#endif
#include <errno.h>
#include "common.h"
#include "base_cmd.h"
#include "client.h"
@ -1014,24 +1011,21 @@ static void Host_InitCommon( int argc, char **argv, const char *progname, qboole
{
char dev_level[4];
int developer = DEFAULT_DEV;
const char *baseDir;
char ticrate[16];
int len, i;
int i;
// 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 );
if( !Sys_CheckParm( "-disablehelp" ) )
if( !Sys_CheckParm( "-disablehelp" ))
{
if( Sys_CheckParm( "-help" ) || Sys_CheckParm( "-h" ) || Sys_CheckParm( "--help" ) )
{
if( Sys_CheckParm( "-help" ) || Sys_CheckParm( "-h" ) || Sys_CheckParm( "--help" ))
Sys_PrintUsage();
}
}
if( !Sys_CheckParm( "-noch" ) )
if( !Sys_CheckParm( "-noch" ))
Sys_SetupCrashHandler();
host.enabledll = !Sys_CheckParm( "-nodll" );
@ -1146,91 +1140,6 @@ static void Host_InitCommon( int argc, char **argv, const char *progname, qboole
#endif
Platform_Init();
baseDir = getenv( "XASH3D_BASEDIR" );
if( COM_CheckString( baseDir ) )
{
Q_strncpy( host.rootdir, baseDir, sizeof( host.rootdir ));
}
else
{
#if TARGET_OS_IOS
Q_strncpy( host.rootdir, IOS_GetDocsDir(), sizeof( host.rootdir ));
#elif XASH_ANDROID && XASH_SDL
Q_strncpy( host.rootdir, SDL_AndroidGetExternalStoragePath(), sizeof( host.rootdir ));
#elif XASH_PSVITA
if ( !PSVita_GetBasePath( host.rootdir, sizeof( host.rootdir )))
{
Sys_Error( "couldn't find xash3d data directory" );
host.rootdir[0] = 0;
}
#elif (XASH_SDL == 2) && !XASH_NSWITCH // GetBasePath not impl'd in switch-sdl2
char *szBasePath = SDL_GetBasePath();
if( szBasePath )
{
Q_strncpy( host.rootdir, szBasePath, sizeof( host.rootdir ));
SDL_free( szBasePath );
}
else
{
#if XASH_POSIX || XASH_WIN32
if( !getcwd( host.rootdir, sizeof( host.rootdir )))
Sys_Error( "couldn't determine current directory: %s, getcwd: %s", SDL_GetError(), strerror( errno ));
#else
Sys_Error( "couldn't determine current directory: %s", SDL_GetError() );
#endif
}
#else
if( !getcwd( host.rootdir, sizeof( host.rootdir )))
{
Sys_Error( "couldn't determine current directory: %s", strerror( errno ) );
host.rootdir[0] = 0;
}
#endif
}
#if XASH_WIN32
COM_FixSlashes( host.rootdir );
#endif
len = Q_strlen( host.rootdir );
if( len && host.rootdir[len - 1] == '/' )
host.rootdir[len - 1] = 0;
// get readonly root. The order is: check for arg, then env.
// if still not got it, rodir is disabled.
host.rodir[0] = '\0';
if( !Sys_GetParmFromCmdLine( "-rodir", host.rodir ))
{
char *roDir = getenv( "XASH3D_RODIR" );
if( COM_CheckString( roDir ))
Q_strncpy( host.rodir, roDir, sizeof( host.rodir ));
}
#if XASH_WIN32
COM_FixSlashes( host.rootdir );
#endif
len = Q_strlen( host.rodir );
if( len && host.rodir[len - 1] == '/' )
host.rodir[len - 1] = 0;
if( !COM_CheckStringEmpty( host.rootdir ))
{
Sys_Error( "Changing working directory failed (empty working directory)\n" );
return;
}
FS_LoadProgs();
// TODO: this function will cause engine to stop in case of fail
// when it will have an option to return string error, restore Sys_Error
FS_SetCurrentDirectory( host.rootdir );
FS_Init();
Sys_InitLog();