mirror of
https://github.com/FWGS/xash3d-fwgs.git
synced 2026-08-05 03:24:56 +08:00
filesystem: archive mounting refactoring
This commit is contained in:
@@ -470,19 +470,11 @@ public:
|
|||||||
bool AddPackFile( const char *path, const char *id ) override
|
bool AddPackFile( const char *path, const char *id ) override
|
||||||
{
|
{
|
||||||
char dir[MAX_VA_STRING], fullpath[MAX_VA_STRING];
|
char dir[MAX_VA_STRING], fullpath[MAX_VA_STRING];
|
||||||
const char *ext = COM_FileExtension( path );
|
|
||||||
|
|
||||||
IdToDir( dir, sizeof( dir ), id );
|
IdToDir( dir, sizeof( dir ), id );
|
||||||
Q_snprintf( fullpath, sizeof( fullpath ), "%s/%s", dir, path );
|
Q_snprintf( fullpath, sizeof( fullpath ), "%s/%s", dir, path );
|
||||||
COM_FixSlashes( fullpath );
|
COM_FixSlashes( fullpath );
|
||||||
|
return FS_MountArchive_Fullpath( fullpath, FS_CUSTOM_PATH ) != NULL;
|
||||||
for( const fs_archive_t *archive = g_archives; archive->ext; archive++ )
|
|
||||||
{
|
|
||||||
if( archive->type == SEARCHPATH_PAK && !Q_stricmp( ext, archive->ext ))
|
|
||||||
return FS_AddArchive_Fullpath( archive, fullpath, FS_CUSTOM_PATH );
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FileHandle_t OpenFromCacheForRead( const char *path , const char *mode, const char *id ) override
|
FileHandle_t OpenFromCacheForRead( const char *path , const char *mode, const char *id ) override
|
||||||
|
|||||||
@@ -52,35 +52,70 @@ GNU General Public License for more details.
|
|||||||
#define SAVE_AGED_COUNT 2 // the default count of quick and auto saves
|
#define SAVE_AGED_COUNT 2 // the default count of quick and auto saves
|
||||||
|
|
||||||
fs_globals_t FI;
|
fs_globals_t FI;
|
||||||
qboolean fs_ext_path = false; // attempt to read\write from ./ or ../ pathes
|
|
||||||
poolhandle_t fs_mempool;
|
poolhandle_t fs_mempool;
|
||||||
char fs_rodir[MAX_SYSPATH];
|
|
||||||
char fs_rootdir[MAX_SYSPATH];
|
char fs_rootdir[MAX_SYSPATH];
|
||||||
searchpath_t *fs_writepath;
|
searchpath_t *fs_writepath;
|
||||||
|
|
||||||
static searchpath_t *fs_searchpaths = NULL; // chain
|
static searchpath_t *fs_searchpaths = NULL; // chain
|
||||||
static char fs_basedir[MAX_SYSPATH]; // base game directory
|
static char fs_basedir[MAX_SYSPATH]; // base game directory
|
||||||
static char fs_gamedir[MAX_SYSPATH]; // game current directory
|
static char fs_gamedir[MAX_SYSPATH]; // game current directory
|
||||||
|
static char fs_rodir[MAX_SYSPATH];
|
||||||
static string fs_language;
|
static string fs_language;
|
||||||
|
static qboolean fs_ext_path = false; // attempt to read\write from ./ or ../ pathes
|
||||||
|
|
||||||
|
typedef struct fs_archive_s
|
||||||
|
{
|
||||||
|
const char *ext;
|
||||||
|
int type;
|
||||||
|
FS_ADDARCHIVE_FULLPATH pfnAddArchive_Fullpath;
|
||||||
|
qboolean load_wads; // load wads from this archive
|
||||||
|
qboolean real_archive;
|
||||||
|
} fs_archive_t;
|
||||||
|
|
||||||
// add archives in specific order PAK -> PK3 -> WAD
|
// add archives in specific order PAK -> PK3 -> WAD
|
||||||
// so raw WADs takes precedence over WADs included into PAKs and PK3s
|
// so raw WADs takes precedence over WADs included into PAKs and PK3s
|
||||||
const fs_archive_t g_archives[] =
|
static const fs_archive_t g_archives[] =
|
||||||
{
|
{
|
||||||
{ "pak", SEARCHPATH_PAK, FS_AddPak_Fullpath, true, true },
|
{
|
||||||
{ "pk3", SEARCHPATH_ZIP, FS_AddZip_Fullpath, true, true },
|
.ext = "pak",
|
||||||
{ "pk3dir", SEARCHPATH_PK3DIR, FS_AddDir_Fullpath, true, false },
|
.type = SEARCHPATH_PAK,
|
||||||
{ "wad", SEARCHPATH_WAD, FS_AddWad_Fullpath, false, true },
|
.pfnAddArchive_Fullpath = FS_AddPak_Fullpath,
|
||||||
{ NULL }, // end marker
|
.load_wads = true,
|
||||||
|
.real_archive = true,
|
||||||
|
}, {
|
||||||
|
.ext = "pk3",
|
||||||
|
.type = SEARCHPATH_ZIP,
|
||||||
|
.pfnAddArchive_Fullpath = FS_AddZip_Fullpath,
|
||||||
|
.load_wads = true,
|
||||||
|
.real_archive = true,
|
||||||
|
}, {
|
||||||
|
.ext = "pk3dir",
|
||||||
|
.type = SEARCHPATH_PK3DIR,
|
||||||
|
.pfnAddArchive_Fullpath = FS_AddDir_Fullpath,
|
||||||
|
.load_wads = true,
|
||||||
|
.real_archive = false,
|
||||||
|
}, {
|
||||||
|
.ext = "wad",
|
||||||
|
.type = SEARCHPATH_WAD,
|
||||||
|
.pfnAddArchive_Fullpath = FS_AddWad_Fullpath,
|
||||||
|
.load_wads = false,
|
||||||
|
.real_archive = true,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// special fs_archive_t for plain directories
|
// special fs_archive_t for plain directories
|
||||||
static const fs_archive_t g_directory_archive =
|
static const fs_archive_t g_directory_archive =
|
||||||
{ NULL, SEARCHPATH_PLAIN, FS_AddDir_Fullpath, false };
|
{
|
||||||
|
.type = SEARCHPATH_PLAIN,
|
||||||
|
.pfnAddArchive_Fullpath = FS_AddDir_Fullpath,
|
||||||
|
};
|
||||||
|
|
||||||
#if XASH_ANDROID
|
#if XASH_ANDROID
|
||||||
static const fs_archive_t g_android_archive =
|
static const fs_archive_t g_android_archive =
|
||||||
{ NULL, SEARCHPATH_ANDROID_ASSETS, FS_AddAndroidAssets_Fullpath, false };
|
{
|
||||||
|
.type = SEARCHPATH_ANDROID_ASSETS,
|
||||||
|
.pfnAddArchive_Fullpath = FS_AddAndroidAssets_Fullpath
|
||||||
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef XASH_REDUCE_FD
|
#ifdef XASH_REDUCE_FD
|
||||||
@@ -328,10 +363,31 @@ void FS_CreatePath( char *path )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
searchpath_t *FS_AddArchive_Fullpath( const fs_archive_t *archive, const char *file, int flags )
|
static searchpath_t *FS_AddArchive_Fullpath( const fs_archive_t *archive, const char *file, int flags )
|
||||||
{
|
{
|
||||||
searchpath_t *search;
|
searchpath_t *search;
|
||||||
|
|
||||||
|
if( !archive )
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
const char *ext = COM_FileExtension( file );
|
||||||
|
|
||||||
|
for( i = 0; i < sizeof( g_archives ) / sizeof( g_archives[0] ); i++ )
|
||||||
|
{
|
||||||
|
if( !Q_stricmp( g_archives[i].ext, ext ))
|
||||||
|
{
|
||||||
|
archive = &g_archives[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !archive )
|
||||||
|
{
|
||||||
|
Con_Printf( S_ERROR "%s: unknown archive format %s, not mounted\n", __func__, file );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for( search = fs_searchpaths; search; search = search->next )
|
for( search = fs_searchpaths; search; search = search->next )
|
||||||
{
|
{
|
||||||
if( search->type == archive->type && !Q_stricmp( search->filename, file ))
|
if( search->type == archive->type && !Q_stricmp( search->filename, file ))
|
||||||
@@ -380,18 +436,9 @@ searchpath_t *FS_AddArchive_Fullpath( const fs_archive_t *archive, const char *f
|
|||||||
FS_AddArchive_Fullpath
|
FS_AddArchive_Fullpath
|
||||||
================
|
================
|
||||||
*/
|
*/
|
||||||
static searchpath_t *FS_MountArchive_Fullpath( const char *file, int flags )
|
searchpath_t *FS_MountArchive_Fullpath( const char *file, int flags )
|
||||||
{
|
{
|
||||||
const fs_archive_t *archive;
|
return FS_AddArchive_Fullpath( NULL, file, flags );
|
||||||
const char *ext = COM_FileExtension( file );
|
|
||||||
|
|
||||||
for( archive = g_archives; archive->ext; archive++ )
|
|
||||||
{
|
|
||||||
if( !Q_stricmp( ext, archive->ext ))
|
|
||||||
return FS_AddArchive_Fullpath( archive, file, flags );
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -404,27 +451,26 @@ then loads and adds pak1.pak pak2.pak ...
|
|||||||
*/
|
*/
|
||||||
void FS_AddGameDirectory( const char *dir, uint flags )
|
void FS_AddGameDirectory( const char *dir, uint flags )
|
||||||
{
|
{
|
||||||
const fs_archive_t *archive;
|
|
||||||
stringlist_t list;
|
stringlist_t list;
|
||||||
searchpath_t *search;
|
searchpath_t *search;
|
||||||
char fullpath[MAX_SYSPATH];
|
int i, j;
|
||||||
int i;
|
|
||||||
|
|
||||||
stringlistinit( &list );
|
stringlistinit( &list );
|
||||||
listdirectory( &list, dir, false );
|
listdirectory( &list, dir, false );
|
||||||
stringlistsort( &list );
|
stringlistsort( &list );
|
||||||
|
|
||||||
for( archive = g_archives; archive->ext; archive++ )
|
for( j = 0; j < sizeof( g_archives ) / sizeof( g_archives[0] ); j++ )
|
||||||
{
|
{
|
||||||
|
char fullpath[MAX_SYSPATH];
|
||||||
|
int i;
|
||||||
|
|
||||||
for( i = 0; i < list.numstrings; i++ )
|
for( i = 0; i < list.numstrings; i++ )
|
||||||
{
|
{
|
||||||
const char *ext = COM_FileExtension( list.strings[i] );
|
if( Q_stricmp( COM_FileExtension( list.strings[i] ), g_archives[j].ext ))
|
||||||
|
|
||||||
if( Q_stricmp( ext, archive->ext ))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Q_snprintf( fullpath, sizeof( fullpath ), "%s%s", dir, list.strings[i] );
|
Q_snprintf( fullpath, sizeof( fullpath ), "%s%s", dir, list.strings[i] );
|
||||||
FS_AddArchive_Fullpath( archive, fullpath, flags );
|
FS_AddArchive_Fullpath( &g_archives[j], fullpath, flags );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3294,7 +3340,7 @@ static qboolean FS_IsArchiveExtensionSupported( const char *ext, uint flags )
|
|||||||
if( ext == NULL )
|
if( ext == NULL )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for( i = 0; i < ( sizeof( g_archives ) / sizeof( g_archives[0] )) - 1; i++ )
|
for( i = 0; i < sizeof( g_archives ) / sizeof( g_archives[0] ); i++ )
|
||||||
{
|
{
|
||||||
if( FBitSet( flags, IAES_ONLY_REAL_ARCHIVES ) && !g_archives[i].real_archive )
|
if( FBitSet( flags, IAES_ONLY_REAL_ARCHIVES ) && !g_archives[i].real_archive )
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -122,24 +122,12 @@ typedef struct searchpath_s
|
|||||||
|
|
||||||
typedef searchpath_t *(*FS_ADDARCHIVE_FULLPATH)( const char *path, int flags );
|
typedef searchpath_t *(*FS_ADDARCHIVE_FULLPATH)( const char *path, int flags );
|
||||||
|
|
||||||
typedef struct fs_archive_s
|
|
||||||
{
|
|
||||||
const char *ext;
|
|
||||||
int type;
|
|
||||||
FS_ADDARCHIVE_FULLPATH pfnAddArchive_Fullpath;
|
|
||||||
qboolean load_wads; // load wads from this archive
|
|
||||||
qboolean real_archive;
|
|
||||||
} fs_archive_t;
|
|
||||||
|
|
||||||
extern fs_globals_t FI;
|
extern fs_globals_t FI;
|
||||||
extern searchpath_t *fs_writepath;
|
extern searchpath_t *fs_writepath;
|
||||||
extern poolhandle_t fs_mempool;
|
extern poolhandle_t fs_mempool;
|
||||||
extern fs_interface_t g_engfuncs;
|
extern fs_interface_t g_engfuncs;
|
||||||
extern qboolean fs_ext_path;
|
|
||||||
extern char fs_rodir[MAX_SYSPATH];
|
|
||||||
extern char fs_rootdir[MAX_SYSPATH];
|
extern char fs_rootdir[MAX_SYSPATH];
|
||||||
extern const fs_api_t g_api;
|
extern const fs_api_t g_api;
|
||||||
extern const fs_archive_t g_archives[];
|
|
||||||
|
|
||||||
#define GI FI.GameInfo
|
#define GI FI.GameInfo
|
||||||
|
|
||||||
@@ -161,7 +149,7 @@ extern const fs_archive_t g_archives[];
|
|||||||
//
|
//
|
||||||
qboolean FS_InitStdio( qboolean caseinsensitive, const char *rootdir, const char *basedir, const char *gamedir, const char *rodir );
|
qboolean FS_InitStdio( qboolean caseinsensitive, const char *rootdir, const char *basedir, const char *gamedir, const char *rodir );
|
||||||
void FS_ShutdownStdio( void );
|
void FS_ShutdownStdio( void );
|
||||||
searchpath_t *FS_AddArchive_Fullpath( const fs_archive_t *archive, const char *file, int flags );
|
searchpath_t *FS_MountArchive_Fullpath( const char *file, int flags );
|
||||||
void _Mem_Free( void *data, const char *filename, int fileline );
|
void _Mem_Free( void *data, const char *filename, int fileline );
|
||||||
void *_Mem_Alloc( poolhandle_t poolptr, size_t size, qboolean clear, const char *filename, int fileline )
|
void *_Mem_Alloc( poolhandle_t poolptr, size_t size, qboolean clear, const char *filename, int fileline )
|
||||||
ALLOC_CHECK( 2 ) MALLOC_LIKE( _Mem_Free, 1 ) WARN_UNUSED_RESULT;
|
ALLOC_CHECK( 2 ) MALLOC_LIKE( _Mem_Free, 1 ) WARN_UNUSED_RESULT;
|
||||||
|
|||||||
Reference in New Issue
Block a user