|
|
@ -269,7 +269,7 @@ static void stringlistappend( stringlist_t *list, char *text ) |
|
|
|
{ |
|
|
|
{ |
|
|
|
size_t textlen; |
|
|
|
size_t textlen; |
|
|
|
|
|
|
|
|
|
|
|
if( !Q_stricmp( text, "." ) || !Q_stricmp( text, ".." )) |
|
|
|
if( !Q_strcmp( text, "." ) || !Q_strcmp( text, ".." )) |
|
|
|
return; // ignore the virtual directories
|
|
|
|
return; // ignore the virtual directories
|
|
|
|
|
|
|
|
|
|
|
|
if( list->numstrings >= list->maxstrings ) |
|
|
|
if( list->numstrings >= list->maxstrings ) |
|
|
@ -1257,7 +1257,7 @@ void FS_AddGameHierarchy( const char *dir, uint flags ) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if( host.rodir[0] ) |
|
|
|
if( COM_CheckStringEmpty( host.rodir ) ) |
|
|
|
{ |
|
|
|
{ |
|
|
|
// append new flags to rodir, except FS_GAMEDIR_PATH and FS_CUSTOM_PATH
|
|
|
|
// append new flags to rodir, except FS_GAMEDIR_PATH and FS_CUSTOM_PATH
|
|
|
|
uint newFlags = FS_NOWRITE_PATH | (flags & (~FS_GAMEDIR_PATH|FS_CUSTOM_PATH)); |
|
|
|
uint newFlags = FS_NOWRITE_PATH | (flags & (~FS_GAMEDIR_PATH|FS_CUSTOM_PATH)); |
|
|
@ -1342,7 +1342,7 @@ int FS_CheckNastyPath( const char *path, qboolean isgamedir ) |
|
|
|
// instead of /, but we rely on / working already, so there's no reason to
|
|
|
|
// instead of /, but we rely on / working already, so there's no reason to
|
|
|
|
// support a Mac-only path
|
|
|
|
// support a Mac-only path
|
|
|
|
// Amiga and Windows: : tries to go to root of drive
|
|
|
|
// Amiga and Windows: : tries to go to root of drive
|
|
|
|
if( Q_strstr( path, ":" )) return 1; // non-portable attempt to go to root of drive
|
|
|
|
if( Q_strchr( path, ':' )) return 1; // non-portable attempt to go to root of drive
|
|
|
|
|
|
|
|
|
|
|
|
// Amiga: // is parent directory
|
|
|
|
// Amiga: // is parent directory
|
|
|
|
if( Q_strstr( path, "//" )) return 1; // non-portable attempt to go to parent directory
|
|
|
|
if( Q_strstr( path, "//" )) return 1; // non-portable attempt to go to parent directory
|
|
|
@ -1428,24 +1428,24 @@ static void FS_WriteGameInfo( const char *filepath, gameinfo_t *GameInfo ) |
|
|
|
|
|
|
|
|
|
|
|
FS_Printf( f, "// generated by %s %s-%s (%s-%s)\n\n\n", XASH_ENGINE_NAME, XASH_VERSION, Q_buildcommit(), Q_buildos(), Q_buildarch() ); |
|
|
|
FS_Printf( f, "// generated by %s %s-%s (%s-%s)\n\n\n", XASH_ENGINE_NAME, XASH_VERSION, Q_buildcommit(), Q_buildos(), Q_buildarch() ); |
|
|
|
|
|
|
|
|
|
|
|
if( Q_strlen( GameInfo->basedir )) |
|
|
|
if( COM_CheckStringEmpty( GameInfo->basedir ) ) |
|
|
|
FS_Printf( f, "basedir\t\t\"%s\"\n", GameInfo->basedir ); |
|
|
|
FS_Printf( f, "basedir\t\t\"%s\"\n", GameInfo->basedir ); |
|
|
|
|
|
|
|
|
|
|
|
// DEPRECATED: gamedir key isn't supported by FWGS fork
|
|
|
|
// DEPRECATED: gamedir key isn't supported by FWGS fork
|
|
|
|
// but write it anyway to keep compability with original Xash3D
|
|
|
|
// but write it anyway to keep compability with original Xash3D
|
|
|
|
if( Q_strlen( GameInfo->gamefolder )) |
|
|
|
if( COM_CheckStringEmpty( GameInfo->gamefolder ) ) |
|
|
|
FS_Printf( f, "gamedir\t\t\"%s\"\n", GameInfo->gamefolder ); |
|
|
|
FS_Printf( f, "gamedir\t\t\"%s\"\n", GameInfo->gamefolder ); |
|
|
|
|
|
|
|
|
|
|
|
if( Q_strlen( GameInfo->falldir )) |
|
|
|
if( COM_CheckStringEmpty( GameInfo->falldir ) ) |
|
|
|
FS_Printf( f, "fallback_dir\t\"%s\"\n", GameInfo->falldir ); |
|
|
|
FS_Printf( f, "fallback_dir\t\"%s\"\n", GameInfo->falldir ); |
|
|
|
|
|
|
|
|
|
|
|
if( Q_strlen( GameInfo->title )) |
|
|
|
if( COM_CheckStringEmpty( GameInfo->title ) ) |
|
|
|
FS_Printf( f, "title\t\t\"%s\"\n", GameInfo->title ); |
|
|
|
FS_Printf( f, "title\t\t\"%s\"\n", GameInfo->title ); |
|
|
|
|
|
|
|
|
|
|
|
if( Q_strlen( GameInfo->startmap )) |
|
|
|
if( COM_CheckStringEmpty( GameInfo->startmap ) ) |
|
|
|
FS_Printf( f, "startmap\t\t\"%s\"\n", GameInfo->startmap ); |
|
|
|
FS_Printf( f, "startmap\t\t\"%s\"\n", GameInfo->startmap ); |
|
|
|
|
|
|
|
|
|
|
|
if( Q_strlen( GameInfo->trainmap )) |
|
|
|
if( COM_CheckStringEmpty( GameInfo->trainmap ) ) |
|
|
|
FS_Printf( f, "trainmap\t\t\"%s\"\n", GameInfo->trainmap ); |
|
|
|
FS_Printf( f, "trainmap\t\t\"%s\"\n", GameInfo->trainmap ); |
|
|
|
|
|
|
|
|
|
|
|
if( GameInfo->version != 0.0f ) |
|
|
|
if( GameInfo->version != 0.0f ) |
|
|
@ -1454,32 +1454,32 @@ static void FS_WriteGameInfo( const char *filepath, gameinfo_t *GameInfo ) |
|
|
|
if( GameInfo->size != 0 ) |
|
|
|
if( GameInfo->size != 0 ) |
|
|
|
FS_Printf( f, "size\t\t%lu\n", GameInfo->size ); |
|
|
|
FS_Printf( f, "size\t\t%lu\n", GameInfo->size ); |
|
|
|
|
|
|
|
|
|
|
|
if( Q_strlen( GameInfo->game_url )) |
|
|
|
if( COM_CheckStringEmpty( GameInfo->game_url ) ) |
|
|
|
FS_Printf( f, "url_info\t\t\"%s\"\n", GameInfo->game_url ); |
|
|
|
FS_Printf( f, "url_info\t\t\"%s\"\n", GameInfo->game_url ); |
|
|
|
|
|
|
|
|
|
|
|
if( Q_strlen( GameInfo->update_url )) |
|
|
|
if( COM_CheckStringEmpty( GameInfo->update_url ) ) |
|
|
|
FS_Printf( f, "url_update\t\t\"%s\"\n", GameInfo->update_url ); |
|
|
|
FS_Printf( f, "url_update\t\t\"%s\"\n", GameInfo->update_url ); |
|
|
|
|
|
|
|
|
|
|
|
if( Q_strlen( GameInfo->type )) |
|
|
|
if( COM_CheckStringEmpty( GameInfo->type ) ) |
|
|
|
FS_Printf( f, "type\t\t\"%s\"\n", GameInfo->type ); |
|
|
|
FS_Printf( f, "type\t\t\"%s\"\n", GameInfo->type ); |
|
|
|
|
|
|
|
|
|
|
|
if( Q_strlen( GameInfo->date )) |
|
|
|
if( COM_CheckStringEmpty( GameInfo->date ) ) |
|
|
|
FS_Printf( f, "date\t\t\"%s\"\n", GameInfo->date ); |
|
|
|
FS_Printf( f, "date\t\t\"%s\"\n", GameInfo->date ); |
|
|
|
|
|
|
|
|
|
|
|
if( Q_strlen( GameInfo->dll_path )) |
|
|
|
if( COM_CheckStringEmpty( GameInfo->dll_path ) ) |
|
|
|
FS_Printf( f, "dllpath\t\t\"%s\"\n", GameInfo->dll_path ); |
|
|
|
FS_Printf( f, "dllpath\t\t\"%s\"\n", GameInfo->dll_path ); |
|
|
|
|
|
|
|
|
|
|
|
if( Q_strlen( GameInfo->game_dll )) |
|
|
|
if( COM_CheckStringEmpty( GameInfo->game_dll ) ) |
|
|
|
FS_Printf( f, "gamedll\t\t\"%s\"\n", GameInfo->game_dll ); |
|
|
|
FS_Printf( f, "gamedll\t\t\"%s\"\n", GameInfo->game_dll ); |
|
|
|
|
|
|
|
|
|
|
|
if( Q_strlen( GameInfo->game_dll_linux )) |
|
|
|
if( COM_CheckStringEmpty( GameInfo->game_dll_linux ) ) |
|
|
|
FS_Printf( f, "gamedll_linux\t\t\"%s\"\n", GameInfo->game_dll_linux ); |
|
|
|
FS_Printf( f, "gamedll_linux\t\t\"%s\"\n", GameInfo->game_dll_linux ); |
|
|
|
|
|
|
|
|
|
|
|
if( Q_strlen( GameInfo->game_dll_osx )) |
|
|
|
if( COM_CheckStringEmpty( GameInfo->game_dll_osx ) ) |
|
|
|
FS_Printf( f, "gamedll_osx\t\t\"%s\"\n", GameInfo->game_dll_osx ); |
|
|
|
FS_Printf( f, "gamedll_osx\t\t\"%s\"\n", GameInfo->game_dll_osx ); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if( Q_strlen( GameInfo->iconpath )) |
|
|
|
if( COM_CheckStringEmpty( GameInfo->iconpath )) |
|
|
|
FS_Printf( f, "icon\t\t\"%s\"\n", GameInfo->iconpath ); |
|
|
|
FS_Printf( f, "icon\t\t\"%s\"\n", GameInfo->iconpath ); |
|
|
|
|
|
|
|
|
|
|
|
switch( GameInfo->gamemode ) |
|
|
|
switch( GameInfo->gamemode ) |
|
|
@ -1488,11 +1488,11 @@ static void FS_WriteGameInfo( const char *filepath, gameinfo_t *GameInfo ) |
|
|
|
case 2: FS_Print( f, "gamemode\t\t\"multiplayer_only\"\n" ); break; |
|
|
|
case 2: FS_Print( f, "gamemode\t\t\"multiplayer_only\"\n" ); break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if( Q_strlen( GameInfo->sp_entity )) |
|
|
|
if( COM_CheckStringEmpty( GameInfo->sp_entity )) |
|
|
|
FS_Printf( f, "sp_entity\t\t\"%s\"\n", GameInfo->sp_entity ); |
|
|
|
FS_Printf( f, "sp_entity\t\t\"%s\"\n", GameInfo->sp_entity ); |
|
|
|
if( Q_strlen( GameInfo->mp_entity )) |
|
|
|
if( COM_CheckStringEmpty( GameInfo->mp_entity )) |
|
|
|
FS_Printf( f, "mp_entity\t\t\"%s\"\n", GameInfo->mp_entity ); |
|
|
|
FS_Printf( f, "mp_entity\t\t\"%s\"\n", GameInfo->mp_entity ); |
|
|
|
if( Q_strlen( GameInfo->mp_filter )) |
|
|
|
if( COM_CheckStringEmpty( GameInfo->mp_filter )) |
|
|
|
FS_Printf( f, "mp_filter\t\t\"%s\"\n", GameInfo->mp_filter ); |
|
|
|
FS_Printf( f, "mp_filter\t\t\"%s\"\n", GameInfo->mp_filter ); |
|
|
|
|
|
|
|
|
|
|
|
if( GameInfo->secure ) |
|
|
|
if( GameInfo->secure ) |
|
|
@ -1900,7 +1900,7 @@ static qboolean FS_ParseGameInfo( const char *gamedir, gameinfo_t *GameInfo ) |
|
|
|
Q_snprintf( liblist_path, sizeof( liblist_path ), "%s/liblist.gam", gamedir ); |
|
|
|
Q_snprintf( liblist_path, sizeof( liblist_path ), "%s/liblist.gam", gamedir ); |
|
|
|
|
|
|
|
|
|
|
|
// here goes some RoDir magic...
|
|
|
|
// here goes some RoDir magic...
|
|
|
|
if( host.rodir[0] ) |
|
|
|
if( COM_CheckStringEmpty( host.rodir ) ) |
|
|
|
{ |
|
|
|
{ |
|
|
|
string filepath_ro, liblist_ro; |
|
|
|
string filepath_ro, liblist_ro; |
|
|
|
fs_offset_t roLibListTime, roGameInfoTime, rwGameInfoTime; |
|
|
|
fs_offset_t roLibListTime, roGameInfoTime, rwGameInfoTime; |
|
|
@ -2033,7 +2033,7 @@ void FS_Init( void ) |
|
|
|
|
|
|
|
|
|
|
|
if( !fs_caseinsensitive ) |
|
|
|
if( !fs_caseinsensitive ) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if( host.rodir[0] && !Q_strcmp( host.rodir, host.rootdir ) ) |
|
|
|
if( COM_CheckStringEmpty( host.rodir ) && !Q_strcmp( host.rodir, host.rootdir ) ) |
|
|
|
{ |
|
|
|
{ |
|
|
|
Sys_Error( "RoDir and default rootdir can't point to same directory!" ); |
|
|
|
Sys_Error( "RoDir and default rootdir can't point to same directory!" ); |
|
|
|
} |
|
|
|
} |
|
|
@ -2041,7 +2041,7 @@ void FS_Init( void ) |
|
|
|
else |
|
|
|
else |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
{ |
|
|
|
{ |
|
|
|
if( host.rodir[0] && !Q_stricmp( host.rodir, host.rootdir ) ) |
|
|
|
if( COM_CheckStringEmpty( host.rodir ) && !Q_stricmp( host.rodir, host.rootdir ) ) |
|
|
|
{ |
|
|
|
{ |
|
|
|
Sys_Error( "RoDir and default rootdir can't point to same directory!" ); |
|
|
|
Sys_Error( "RoDir and default rootdir can't point to same directory!" ); |
|
|
|
} |
|
|
|
} |
|
|
@ -2068,7 +2068,7 @@ void FS_Init( void ) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// add readonly directories first
|
|
|
|
// add readonly directories first
|
|
|
|
if( host.rodir[0] ) |
|
|
|
if( COM_CheckStringEmpty( host.rodir ) ) |
|
|
|
{ |
|
|
|
{ |
|
|
|
stringlistinit( &dirs ); |
|
|
|
stringlistinit( &dirs ); |
|
|
|
listdirectory( &dirs, host.rodir, false ); |
|
|
|
listdirectory( &dirs, host.rodir, false ); |
|
|
@ -2109,7 +2109,7 @@ void FS_Init( void ) |
|
|
|
|
|
|
|
|
|
|
|
for( i = 0; i < dirs.numstrings; i++ ) |
|
|
|
for( i = 0; i < dirs.numstrings; i++ ) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if( !FS_SysFolderExists( dirs.strings[i] ) || ( !Q_stricmp( dirs.strings[i], ".." ) && !fs_ext_path )) |
|
|
|
if( !FS_SysFolderExists( dirs.strings[i] ) || ( !Q_strcmp( dirs.strings[i], ".." ) && !fs_ext_path )) |
|
|
|
continue; |
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
|
|
if( SI.games[SI.numgames] == NULL ) |
|
|
|
if( SI.games[SI.numgames] == NULL ) |
|
|
@ -2468,7 +2468,7 @@ static searchpath_t *FS_FindFile( const char *name, int *index, qboolean gamedir |
|
|
|
COM_ExtractFilePath( name, wadname ); |
|
|
|
COM_ExtractFilePath( name, wadname ); |
|
|
|
wadfolder[0] = '\0'; |
|
|
|
wadfolder[0] = '\0'; |
|
|
|
|
|
|
|
|
|
|
|
if( Q_strlen( wadname )) |
|
|
|
if( COM_CheckStringEmpty( wadname ) ) |
|
|
|
{ |
|
|
|
{ |
|
|
|
COM_FileBase( wadname, wadname ); |
|
|
|
COM_FileBase( wadname, wadname ); |
|
|
|
Q_strncpy( wadfolder, wadname, sizeof( wadfolder )); |
|
|
|
Q_strncpy( wadfolder, wadname, sizeof( wadfolder )); |
|
|
@ -3249,6 +3249,7 @@ dll_user_t *FS_FindLibrary( const char *dllname, qboolean directpath ) |
|
|
|
dll_user_t *hInst; |
|
|
|
dll_user_t *hInst; |
|
|
|
int i, index; |
|
|
|
int i, index; |
|
|
|
int start = 0; |
|
|
|
int start = 0; |
|
|
|
|
|
|
|
int len; |
|
|
|
|
|
|
|
|
|
|
|
// check for bad exports
|
|
|
|
// check for bad exports
|
|
|
|
if( !COM_CheckString( dllname )) |
|
|
|
if( !COM_CheckString( dllname )) |
|
|
@ -3261,7 +3262,9 @@ dll_user_t *FS_FindLibrary( const char *dllname, qboolean directpath ) |
|
|
|
start += 9; |
|
|
|
start += 9; |
|
|
|
|
|
|
|
|
|
|
|
// replace all backward slashes
|
|
|
|
// replace all backward slashes
|
|
|
|
for( i = 0; i < Q_strlen( dllname ); i++ ) |
|
|
|
len = Q_strlen( dllname ); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for( i = 0; i < len; i++ ) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if( dllname[i+start] == '\\' ) dllpath[i] = '/'; |
|
|
|
if( dllname[i+start] == '\\' ) dllpath[i] = '/'; |
|
|
|
else dllpath[i] = Q_tolower( dllname[i+start] ); |
|
|
|
else dllpath[i] = Q_tolower( dllname[i+start] ); |
|
|
@ -3555,7 +3558,7 @@ search_t *FS_Search( const char *pattern, int caseinsensitive, int gamedironly ) |
|
|
|
COM_FileBase( pattern, wadpattern ); |
|
|
|
COM_FileBase( pattern, wadpattern ); |
|
|
|
wadfolder[0] = '\0'; |
|
|
|
wadfolder[0] = '\0'; |
|
|
|
|
|
|
|
|
|
|
|
if( Q_strlen( wadname )) |
|
|
|
if( COM_CheckStringEmpty( wadname )) |
|
|
|
{ |
|
|
|
{ |
|
|
|
COM_FileBase( wadname, wadname ); |
|
|
|
COM_FileBase( wadname, wadname ); |
|
|
|
Q_strncpy( wadfolder, wadname, sizeof( wadfolder )); |
|
|
|
Q_strncpy( wadfolder, wadname, sizeof( wadfolder )); |
|
|
@ -3914,7 +3917,7 @@ wfile_t *W_Open( const char *filename, int *error ) |
|
|
|
wad->handle = FS_Open( basename, "rb", false ); |
|
|
|
wad->handle = FS_Open( basename, "rb", false ); |
|
|
|
|
|
|
|
|
|
|
|
// HACKHACK: try to open WAD by full path for RoDir, when searchpaths are not ready
|
|
|
|
// HACKHACK: try to open WAD by full path for RoDir, when searchpaths are not ready
|
|
|
|
if( host.rodir[0] && fs_ext_path && wad->handle == NULL ) |
|
|
|
if( COM_CheckStringEmpty( host.rodir ) && fs_ext_path && wad->handle == NULL ) |
|
|
|
wad->handle = FS_SysOpen( filename, "rb" ); |
|
|
|
wad->handle = FS_SysOpen( filename, "rb" ); |
|
|
|
|
|
|
|
|
|
|
|
if( wad->handle == NULL ) |
|
|
|
if( wad->handle == NULL ) |
|
|
|