Reduce duplication in FS path search code

Co-authored-by: smallmodel <15067410+smallmodel@users.noreply.github.com>
This commit is contained in:
Tim Angusandsmallmodel authored and smallmodel committed 2025-09-04 23:28:07 +02:00
1 parent eb6b6173ee
commit e299031470
12 files changed
+347 -383

No files matched your search

+226 -256
View File
@@ -247,10 +247,7 @@ static char fs_gamedir[MAX_OSPATH]; // this will be a single file name with no
cvar_t *fs_debug;
static cvar_t *fs_homepath;
#ifdef __APPLE__
// Also search the .app bundle for .pk3 files
static cvar_t *fs_apppath;
#endif
static cvar_t *fs_apppath;
static cvar_t *fs_steampath;
static cvar_t *fs_gogpath;
static cvar_t *fs_microsoftstorepath;
@@ -263,7 +260,15 @@ static int fs_loadCount; // total files read
static int fs_loadStack; // total files in memory
static int fs_packFiles = 0; // total number of files in packs
static int fs_fakeChkSum;
static cvar_t** const fs_pathVars[] = {
&fs_homepath,
&fs_basepath,
&fs_apppath,
&fs_steampath,
&fs_gogpath,
&fs_microsoftstorepath
};
static int fs_checksumFeed;
static cvar_t* fs_gamedirvar;
@@ -644,6 +649,20 @@ char *FS_BuildOSPath( const char *base, const char *game, const char *qpath ) {
return ospath[ toggle ];
}
/*
===================
FS_BaseDir_BuildOSPath
Qpath may have either forward or backwards slashes
===================
*/
char *FS_BaseDir_BuildOSPath( const char *base, const char *qpath ) {
char *ospath = FS_BuildOSPath(base, qpath, "");
ospath[strlen(ospath) - 1] = '\0';
return ospath;
}
/*
============
@@ -652,10 +671,14 @@ FS_CreatePath
Creates any directories needed to store the given filename
============
*/
qboolean FS_CreatePath (char *OSPath) {
qboolean FS_CreatePath (const char *OSPath) {
char *ofs;
char path[MAX_OSPATH];
if (!OSPath || !*OSPath) {
return qfalse;
}
// make absolutely sure that it can't back up the path
// FIXME: is c: allowed???
if ( strstr( OSPath, ".." ) || strstr( OSPath, "::" ) ) {
@@ -771,43 +794,33 @@ qboolean FS_FileExists(const char *file)
/*
================
FS_SV_FileExists
FS_BaseDir_FileExists
Tests if the file exists
================
*/
qboolean FS_SV_FileExists( const char *file )
qboolean FS_BaseDir_FileExists( const char *file )
{
char *testpath;
testpath = FS_BuildOSPath( fs_homepath->string, file, "");
testpath[strlen(testpath)-1] = '\0';
return FS_FileInPathExists(testpath);
return FS_FileInPathExists(FS_BaseDir_BuildOSPath(fs_homepath->string, file));
}
/*
===========
FS_SV_FOpenFileWrite
FS_OSPath_FOpenFileWrite
===========
*/
fileHandle_t FS_SV_FOpenFileWrite( const char *filename ) {
char *ospath;
static fileHandle_t FS_OSPath_FOpenFileWrite( const char *ospath, const char *filename ) {
fileHandle_t f;
if ( !fs_searchpaths ) {
Com_Error( ERR_FATAL, "Filesystem call made without initialization" );
}
ospath = FS_BuildOSPath( fs_homepath->string, filename, "" );
ospath[strlen(ospath)-1] = '\0';
f = FS_HandleForFile();
fsh[f].zipFile = qfalse;
if ( fs_debug->integer ) {
Com_Printf( "FS_SV_FOpenFileWrite: %s\n", ospath );
Com_Printf( "FS_OSPath_FOpenFileWrite: %s\n", ospath );
}
FS_CheckFilenameIsMutable( ospath, __func__ );
@@ -816,7 +829,6 @@ fileHandle_t FS_SV_FOpenFileWrite( const char *filename ) {
return 0;
}
Com_DPrintf( "writing to: %s\n", ospath );
fsh[f].handleFiles.file.o = Sys_FOpen( ospath, "wb" );
Q_strncpyz( fsh[f].name, filename, sizeof( fsh[f].name ) );
@@ -830,16 +842,28 @@ fileHandle_t FS_SV_FOpenFileWrite( const char *filename ) {
/*
===========
FS_SV_FOpenFileRead
FS_BaseDir_FOpenFileWrite
===========
*/
fileHandle_t FS_BaseDir_FOpenFileWrite( const char *filename ) {
return FS_OSPath_FOpenFileWrite(
FS_BaseDir_BuildOSPath(fs_homepath->string, filename), filename);
}
/*
===========
FS_BaseDir_FOpenFileRead
Search for a file somewhere below the home path then base path
in that order
===========
*/
long FS_SV_FOpenFileRead(const char *filename, fileHandle_t *fp)
long FS_BaseDir_FOpenFileRead(const char *filename, fileHandle_t *fp)
{
char *ospath;
fileHandle_t f = 0;
fileHandle_t f = 0;
qboolean skipHome = !Q_stricmp(fs_homepath->string, fs_basepath->string);
if ( !fs_searchpaths ) {
Com_Error( ERR_FATAL, "Filesystem call made without initialization" );
@@ -853,69 +877,32 @@ long FS_SV_FOpenFileRead(const char *filename, fileHandle_t *fp)
// don't let sound stutter
S_ClearSoundBuffer();
// search homepath
ospath = FS_BuildOSPath( fs_homepath->string, filename, "" );
// remove trailing slash
ospath[strlen(ospath)-1] = '\0';
for(int i = 0; i < ARRAY_LEN( fs_pathVars ) && !fsh[f].handleFiles.file.o; i++) {
const cvar_t *pathVar = *fs_pathVars[i];
if ( fs_debug->integer ) {
Com_Printf( "FS_SV_FOpenFileRead (fs_homepath): %s\n", ospath );
if (!pathVar || !pathVar->string[0]) {
continue;
}
if (skipHome && pathVar == fs_homepath) {
// home == base, skip
continue;
}
ospath = FS_BaseDir_BuildOSPath( pathVar->string, filename );
if ( fs_debug->integer )
{
Com_Printf( "FS_BaseDir_FOpenFileRead (%s): %s\n", pathVar->name, ospath );
}
fsh[f].handleFiles.file.o = Sys_FOpen( ospath, "rb" );
fsh[f].handleSync = qfalse;
}
fsh[f].handleFiles.file.o = Sys_FOpen( ospath, "rb" );
fsh[f].handleSync = qfalse;
if (!fsh[f].handleFiles.file.o)
{
// If fs_homepath == fs_basepath, don't bother
if (Q_stricmp(fs_homepath->string,fs_basepath->string))
{
// search basepath
ospath = FS_BuildOSPath( fs_basepath->string, filename, "" );
ospath[strlen(ospath)-1] = '\0';
if ( fs_debug->integer )
{
Com_Printf( "FS_SV_FOpenFileRead (fs_basepath): %s\n", ospath );
}
fsh[f].handleFiles.file.o = Sys_FOpen( ospath, "rb" );
fsh[f].handleSync = qfalse;
}
// Check fs_steampath
if (!fsh[f].handleFiles.file.o && fs_steampath->string[0])
{
ospath = FS_BuildOSPath( fs_steampath->string, filename, "" );
ospath[strlen(ospath)-1] = '\0';
if ( fs_debug->integer )
{
Com_Printf( "FS_SV_FOpenFileRead (fs_steampath): %s\n", ospath );
}
fsh[f].handleFiles.file.o = Sys_FOpen( ospath, "rb" );
fsh[f].handleSync = qfalse;
}
// Check fs_gogpath
if (!fsh[f].handleFiles.file.o && fs_gogpath->string[0])
{
ospath = FS_BuildOSPath( fs_gogpath->string, filename, "" );
ospath[strlen(ospath)-1] = '\0';
if ( fs_debug->integer )
{
Com_Printf( "FS_SV_FOpenFileRead (fs_gogpath): %s\n", ospath );
}
fsh[f].handleFiles.file.o = Sys_FOpen( ospath, "rb" );
fsh[f].handleSync = qfalse;
}
if ( !fsh[f].handleFiles.file.o )
{
f = 0;
}
f = 0;
}
*fp = f;
@@ -929,11 +916,11 @@ long FS_SV_FOpenFileRead(const char *filename, fileHandle_t *fp)
/*
===========
FS_SV_Rename
FS_BaseDir_Rename
===========
*/
void FS_SV_Rename( const char *from, const char *to, qboolean safe ) {
void FS_BaseDir_Rename( const char *from, const char *to, qboolean safe ) {
char *from_ospath, *to_ospath;
if ( !fs_searchpaths ) {
@@ -943,13 +930,11 @@ void FS_SV_Rename( const char *from, const char *to, qboolean safe ) {
// don't let sound stutter
S_ClearSoundBuffer();
from_ospath = FS_BuildOSPath( fs_homepath->string, from, "" );
to_ospath = FS_BuildOSPath( fs_homepath->string, to, "" );
from_ospath[strlen(from_ospath)-1] = '\0';
to_ospath[strlen(to_ospath)-1] = '\0';
from_ospath = FS_BaseDir_BuildOSPath( fs_homepath->string, from );
to_ospath = FS_BaseDir_BuildOSPath( fs_homepath->string, to );
if ( fs_debug->integer ) {
Com_Printf( "FS_SV_Rename: %s --> %s\n", from_ospath, to_ospath );
Com_Printf( "FS_BaseDir_Rename: %s --> %s\n", from_ospath, to_ospath );
}
if ( safe ) {
@@ -959,36 +944,6 @@ void FS_SV_Rename( const char *from, const char *to, qboolean safe ) {
rename(from_ospath, to_ospath);
}
/*
===========
FS_Rename
===========
*/
void FS_Rename( const char *from, const char *to ) {
char *from_ospath, *to_ospath;
if ( !fs_searchpaths ) {
Com_Error( ERR_FATAL, "Filesystem call made without initialization\n" );
}
// don't let sound stutter
S_ClearSoundBuffer();
from_ospath = FS_BuildOSPath( fs_homepath->string, fs_gamedir, from );
to_ospath = FS_BuildOSPath( fs_homepath->string, fs_gamedir, to );
if ( fs_debug->integer ) {
Com_Printf( "FS_Rename: %s --> %s\n", from_ospath, to_ospath );
}
FS_CheckFilenameIsMutable( to_ospath, __func__ );
rename(from_ospath, to_ospath);
}
/*
==============
FS_FCloseFile
@@ -1027,40 +982,8 @@ FS_FOpenFileWrite
===========
*/
fileHandle_t FS_FOpenFileWrite( const char *filename ) {
char *ospath;
fileHandle_t f;
if ( !fs_searchpaths ) {
Com_Error( ERR_FATAL, "Filesystem call made without initialization" );
}
f = FS_HandleForFile();
fsh[f].zipFile = qfalse;
ospath = FS_BuildOSPath( fs_homepath->string, fs_gamedir, filename );
if ( fs_debug->integer ) {
Com_Printf( "FS_FOpenFileWrite: %s\n", ospath );
}
FS_CheckFilenameIsMutable( ospath, __func__ );
if( FS_CreatePath( ospath ) ) {
return 0;
}
// enabling the following line causes a recursive function call loop
// when running with +set logfile 1 +set developer 1
//Com_DPrintf( "writing to: %s\n", ospath );
fsh[f].handleFiles.file.o = Sys_FOpen( ospath, "wb" );
Q_strncpyz( fsh[f].name, filename, sizeof( fsh[f].name ) );
fsh[f].handleSync = qfalse;
if (!fsh[f].handleFiles.file.o) {
f = 0;
}
return f;
return FS_OSPath_FOpenFileWrite(
FS_BuildOSPath(fs_homepath->string, fs_gamedir, filename), filename);
}
/*
@@ -2652,7 +2575,7 @@ void FS_GetModDescription( const char *modDir, char *description, int descriptio
FILE *file;
Com_sprintf( descPath, sizeof ( descPath ), "%s%cdescription.txt", modDir, PATH_SEP );
nDescLen = FS_SV_FOpenFileRead( descPath, &descHandle );
nDescLen = FS_BaseDir_FOpenFileRead( descPath, &descHandle );
if ( nDescLen > 0 ) {
file = FS_FileForHandle(descHandle);
@@ -2690,15 +2613,18 @@ int FS_GetModList( char *listbuf, int bufsize ) {
char **pFiles0 = NULL;
qboolean bDrop = qfalse;
// paths to search for mods
const char * const paths[] = { fs_basepath->string, fs_homepath->string, fs_steampath->string, fs_gogpath->string };
*listbuf = 0;
nMods = nTotal = 0;
// iterate through paths and get list of potential mods
for (i = 0; i < ARRAY_LEN(paths); i++) {
pFiles0 = Sys_ListFiles(paths[i], NULL, NULL, &dummy, qtrue);
for (i = 0; i < ARRAY_LEN(fs_pathVars); i++) {
const cvar_t *pathVar = *fs_pathVars[i];
if (!pathVar || !pathVar->string[0]) {
continue;
}
pFiles0 = Sys_ListFiles(pathVar->string, NULL, NULL, &dummy, qtrue);
// Sys_ConcatenateFileLists frees the lists so Sys_FreeFileList isn't required
pFiles = Sys_ConcatenateFileLists(pFiles, pFiles0);
}
@@ -2727,8 +2653,14 @@ int FS_GetModList( char *listbuf, int bufsize ) {
// in order to be a valid mod the directory must contain at least one .pk3 or .pk3dir
// we didn't keep the information when we merged the directory names, as to what OS Path it was found under
// so we will try each of them here
for (j = 0; j < ARRAY_LEN(paths); j++) {
path = FS_BuildOSPath(paths[j], name, "");
for (j = 0; j < ARRAY_LEN(fs_pathVars); j++) {
const cvar_t *pathVar = *fs_pathVars[j];
if (!pathVar || !pathVar->string[0]) {
continue;
}
path = FS_BaseDir_BuildOSPath(pathVar->string, name);
nPaks = nDirs = nPakDirs = 0;
pPaks = Sys_ListFiles(path, ".pk3", NULL, &nPaks, qfalse);
pDirs = Sys_ListFiles(path, "/", NULL, &nDirs, qfalse);
@@ -3081,17 +3013,21 @@ then loads the zip headers
================
*/
void FS_AddGameDirectory(const char *path, const char *dir) {
FS_AddGameDirectory2(path, dir, false);
}
void FS_AddGameDirectory2( const char *path, const char *dir, qboolean original_paks_priority) {
searchpath_t *sp;
int i;
searchpath_t *search;
pack_t *pak;
char *pakfile;
char curpath[MAX_OSPATH + 1], *pakfile;
int numfiles;
char **pakfiles;
int pakfilesi;
char **pakfilestmp;
int numdirs;
char **pakdirs;
int pakdirsi;
char **pakdirstmp;
int pakwhich;
int len;
// Unique
for ( sp = fs_searchpaths ; sp ; sp = sp->next ) {
@@ -3103,59 +3039,133 @@ void FS_AddGameDirectory2( const char *path, const char *dir, qboolean original_
Q_strncpyz( fs_gamedir, dir, sizeof( fs_gamedir ) );
// find all pak files in this directory
pakfile = FS_BuildOSPath( path, dir, "" );
pakfile[ strlen(pakfile) - 1 ] = 0; // strip the trailing slash
Q_strncpyz(curpath, FS_BaseDir_BuildOSPath(path, dir), sizeof(curpath));
pakfiles = Sys_ListFiles( pakfile, ".pk3", NULL, &numfiles, qfalse );
// Get .pk3 files
pakfiles = Sys_ListFiles(curpath, ".pk3", NULL, &numfiles, qfalse);
qsort(pakfiles, numfiles, sizeof(char*), paksort);
if (original_paks_priority)
{
if (!stricmp(dir, "main"))
{
FS_SortOriginalPaks(pakfiles, numfiles, fs_originalPaks_main, sizeof(fs_originalPaks_main)/sizeof(fs_originalPaks_main[0]));
}
else if (!stricmp(dir, "mainta"))
{
FS_SortOriginalPaks(pakfiles, numfiles, fs_originalPaks_mainta, sizeof(fs_originalPaks_mainta) / sizeof(fs_originalPaks_mainta[0]));
}
else if (!stricmp(dir, "maintt"))
{
FS_SortOriginalPaks(pakfiles, numfiles, fs_originalPaks_maintt, sizeof(fs_originalPaks_maintt) / sizeof(fs_originalPaks_maintt[0]));
}
if ( pakfiles ) {
qsort( pakfiles, numfiles, sizeof(char*), paksort );
}
for ( i = 0 ; i < numfiles ; i++ ) {
pakfile = FS_BuildOSPath( path, dir, pakfiles[i] );
if ( ( pak = FS_LoadZipFile( pakfile, pakfiles[i] ) ) == 0 )
continue;
// store the game name for downloading
strcpy(pak->pakGamename, dir);
if ( fs_numServerPaks ) {
numdirs = 0;
pakdirs = NULL;
} else {
// Get top level directories (we'll filter them later since the Sys_ListFiles filtering is terrible)
pakdirs = Sys_ListFiles(curpath, "/", NULL, &numdirs, qfalse);
search = (searchpath_t*)Z_Malloc (sizeof(searchpath_t));
search->pack = pak;
search->next = fs_searchpaths;
search->dir = NULL;
fs_searchpaths = search;
qsort( pakdirs, numdirs, sizeof(char *), paksort );
}
pakfilesi = 0;
pakdirsi = 0;
while((pakfilesi < numfiles) || (pakdirsi < numdirs))
{
// Check if a pakfile or pakdir comes next
if (pakfilesi >= numfiles) {
// We've used all the pakfiles, it must be a pakdir.
pakwhich = 0;
}
else if (pakdirsi >= numdirs) {
// We've used all the pakdirs, it must be a pakfile.
pakwhich = 1;
}
else {
// Could be either, compare to see which name comes first
// Need tmp variables for appropriate indirection for paksort()
pakfilestmp = &pakfiles[pakfilesi];
pakdirstmp = &pakdirs[pakdirsi];
pakwhich = (paksort(pakfilestmp, pakdirstmp) < 0);
}
if (pakwhich) {
// The next .pk3 file is before the next .pk3dir
pakfile = FS_BuildOSPath(path, dir, pakfiles[pakfilesi]);
if ((pak = FS_LoadZipFile(pakfile, pakfiles[pakfilesi])) == 0) {
// This isn't a .pk3! Next!
pakfilesi++;
continue;
}
Q_strncpyz(pak->pakPathname, curpath, sizeof(pak->pakPathname));
// store the game name for downloading
Q_strncpyz(pak->pakGamename, dir, sizeof(pak->pakGamename));
fs_packFiles += pak->numfiles;
search = (searchpath_t*)Z_Malloc(sizeof(searchpath_t));
search->pack = pak;
search->next = fs_searchpaths;
fs_searchpaths = search;
pakfilesi++;
}
else {
// The next .pk3dir is before the next .pk3 file
// But wait, this could be any directory, we're filtering to only ending with ".pk3dir" here.
len = strlen(pakdirs[pakdirsi]);
if (!FS_IsExt(pakdirs[pakdirsi], ".pk3dir", len)) {
// This isn't a .pk3dir! Next!
pakdirsi++;
continue;
}
pakfile = FS_BuildOSPath(path, dir, pakdirs[pakdirsi]);
// add the directory to the search path
search = (searchpath_t*)Z_Malloc(sizeof(searchpath_t));
search->dir = (directory_t*)Z_Malloc(sizeof(*search->dir));
Q_strncpyz(search->dir->path, curpath, sizeof(search->dir->path)); // c:\quake3\baseq3
Q_strncpyz(search->dir->fullpath, pakfile, sizeof(search->dir->fullpath)); // c:\quake3\baseq3\mypak.pk3dir
Q_strncpyz(search->dir->gamedir, pakdirs[pakdirsi], sizeof(search->dir->gamedir)); // mypak.pk3dir
search->next = fs_searchpaths;
fs_searchpaths = search;
pakdirsi++;
}
}
// done
Sys_FreeFileList( pakfiles );
Sys_FreeFileList( pakdirs );
//
// add the directory to the search path
//
search = (searchpath_t*)Z_Malloc( sizeof( searchpath_t ) );
search = (searchpath_t*)Z_Malloc (sizeof(searchpath_t));
search->dir = (directory_t*)Z_Malloc( sizeof( *search->dir ) );
search->pack = NULL;
Q_strncpyz( search->dir->path, path, sizeof( search->dir->path ) );
Q_strncpyz( search->dir->gamedir, dir, sizeof( search->dir->gamedir ) );
Q_strncpyz(search->dir->path, path, sizeof(search->dir->path));
Q_strncpyz(search->dir->fullpath, curpath, sizeof(search->dir->fullpath));
Q_strncpyz(search->dir->gamedir, dir, sizeof(search->dir->gamedir));
search->next = fs_searchpaths;
fs_searchpaths = search;
}
/*
================
FS_AddGameDirectories
================
*/
static void FS_AddGameDirectories(const char *dir)
{
// add search path elements in reverse priority order
for(int i = ARRAY_LEN(fs_pathVars) - 1; i >= 0; i--) {
const cvar_t *pathVar = *fs_pathVars[i];
if (!pathVar || !pathVar->string[0]) {
continue;
}
FS_AddGameDirectory(pathVar->string, dir);
}
}
/*
================
FS_idPak
@@ -3290,7 +3300,7 @@ qboolean FS_ComparePaks( char *neededpaks, int len, qboolean dlstring ) {
// Local name
Q_strcat( neededpaks, len, "@");
// Do we have one with the same name?
if ( FS_SV_FileExists( va( "%s.pk3", fs_serverReferencedPakNames[i] ) ) )
if ( FS_BaseDir_FileExists( va( "%s.pk3", fs_serverReferencedPakNames[i] ) ) )
{
char st[MAX_ZPATH];
// We already have one called this, we need to download it to another name
@@ -3317,7 +3327,7 @@ qboolean FS_ComparePaks( char *neededpaks, int len, qboolean dlstring ) {
Q_strcat( neededpaks, len, fs_serverReferencedPakNames[i] );
Q_strcat( neededpaks, len, ".pk3" );
// Do we have one with the same name?
if ( FS_SV_FileExists( va( "%s.pk3", fs_serverReferencedPakNames[i] ) ) )
if ( FS_BaseDir_FileExists( va( "%s.pk3", fs_serverReferencedPakNames[i] ) ) )
{
Q_strcat( neededpaks, len, " (local file exists with wrong checksum)");
}
@@ -3450,6 +3460,13 @@ static void FS_Startup(const char* gameName)
fs_homepath = Cvar_Get ("fs_homepath", homePath, CVAR_INIT|CVAR_PROTECTED );
fs_gamedirvar = Cvar_Get ("fs_game", "", CVAR_INIT|CVAR_SYSTEMINFO );
fs_restrict = Cvar_Get( "fs_restrict", "", CVAR_INIT );
fs_steampath = Cvar_Get ("fs_steampath", Sys_SteamPath(), CVAR_INIT|CVAR_PROTECTED );
fs_gogpath = Cvar_Get ("fs_gogpath", Sys_GogPath(), CVAR_INIT|CVAR_PROTECTED );
fs_microsoftstorepath = Cvar_Get ("fs_microsoftstorepath", Sys_MicrosoftStorePath(), CVAR_INIT|CVAR_PROTECTED );
#ifdef __APPLE__
fs_apppath = Cvar_Get ("fs_apppath", Sys_DefaultAppPath(), CVAR_INIT|CVAR_PROTECTED );
#endif
if (!gameName[0]) {
Cvar_ForceReset( "com_basegame" );
@@ -3473,66 +3490,19 @@ static void FS_Startup(const char* gameName)
Com_Error( ERR_DROP, "Invalid fs_game '%s'", fs_gamedirvar->string );
}
// add search path elements in reverse priority order
fs_microsoftstorepath = Cvar_Get("fs_microsoftstorepath", Sys_MicrosoftStorePath(), CVAR_INIT | CVAR_PROTECTED);
if (fs_microsoftstorepath->string[0]) {
FS_AddGameDirectory(fs_microsoftstorepath->string, gameName);
}
fs_gogpath = Cvar_Get ("fs_gogpath", Sys_GogPath(), CVAR_INIT|CVAR_PROTECTED );
if (fs_gogpath->string[0]) {
FS_AddGameDirectory( fs_gogpath->string, gameName );
}
fs_steampath = Cvar_Get ("fs_steampath", Sys_SteamPath(), CVAR_INIT|CVAR_PROTECTED );
if (fs_steampath->string[0]) {
FS_AddGameDirectory( fs_steampath->string, gameName );
}
if (fs_basepath->string[0]) {
FS_AddGameDirectory( fs_basepath->string, gameName );
}
// fs_homepath is somewhat particular to *nix systems, only add if relevant
#ifdef __APPLE__
fs_apppath = Cvar_Get ("fs_apppath", Sys_DefaultAppPath(), CVAR_INIT|CVAR_PROTECTED );
// Make MacOSX also include the base path included with the .app bundle
if (fs_apppath->string[0])
FS_AddGameDirectory(fs_apppath->string, gameName);
#endif
// NOTE: same filtering below for mods and basegame
if (fs_homepath->string[0] && Q_stricmp(fs_homepath->string,fs_basepath->string)) {
if (fs_homepath->string[0] && Q_stricmp(fs_homepath->string, fs_basepath->string)) {
FS_CreatePath ( fs_homepath->string );
FS_AddGameDirectory ( fs_homepath->string, gameName );
}
FS_AddGameDirectories(gameName);
// check for additional base game so mods can be based upon other mods
if ( fs_basegame->string[0] && Q_stricmp( fs_basegame->string, gameName ) ) {
if (fs_gogpath->string[0]) {
FS_AddGameDirectory(fs_gogpath->string, fs_basegame->string);
}
if (fs_steampath->string[0]) {
FS_AddGameDirectory(fs_steampath->string, fs_basegame->string);
}
if (fs_basepath->string[0]) {
FS_AddGameDirectory(fs_basepath->string, fs_basegame->string);
}
if (fs_homepath->string[0] && Q_stricmp(fs_homepath->string,fs_basepath->string)) {
FS_AddGameDirectory(fs_homepath->string, fs_basegame->string);
}
FS_AddGameDirectories(fs_basegame->string);
}
// check for additional game folder for mods
if ( fs_gamedirvar->string[0] && Q_stricmp( fs_gamedirvar->string, gameName ) ) {
if (fs_gogpath->string[0]) {
FS_AddGameDirectory(fs_gogpath->string, fs_gamedirvar->string);
}
if (fs_steampath->string[0]) {
FS_AddGameDirectory(fs_steampath->string, fs_gamedirvar->string);
}
if (fs_basepath->string[0]) {
FS_AddGameDirectory(fs_basepath->string, fs_gamedirvar->string);
}
if (fs_homepath->string[0] && Q_stricmp(fs_homepath->string,fs_basepath->string)) {
FS_AddGameDirectory(fs_homepath->string, fs_gamedirvar->string);
}
FS_AddGameDirectories(fs_gamedirvar->string);
}
#ifndef STANDALONE