From 52f9aad4d099d8670d4187db1f35c07d7275856b Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Tue, 30 Jul 2024 02:03:15 +0300 Subject: [PATCH] filesystem: add new call to fs_stdio C API to check whether we support that archive format --- filesystem/filesystem.c | 43 ++++++++++++++++++++------------ filesystem/filesystem.h | 12 +++++++-- filesystem/filesystem_internal.h | 1 + filesystem/tests/no-init.c | 9 +++++++ 4 files changed, 47 insertions(+), 18 deletions(-) diff --git a/filesystem/filesystem.c b/filesystem/filesystem.c index 3ddd2e31..e5c95606 100644 --- a/filesystem/filesystem.c +++ b/filesystem/filesystem.c @@ -61,10 +61,10 @@ static char fs_gamedir[MAX_SYSPATH]; // game current directory // so raw WADs takes precedence over WADs included into PAKs and PK3s const fs_archive_t g_archives[] = { -{ "pak", SEARCHPATH_PAK, FS_AddPak_Fullpath, true }, -{ "pk3", SEARCHPATH_ZIP, FS_AddZip_Fullpath, true }, -{ "pk3dir", SEARCHPATH_PK3DIR, FS_AddDir_Fullpath, true }, -{ "wad", SEARCHPATH_WAD, FS_AddWad_Fullpath, false }, +{ "pak", SEARCHPATH_PAK, FS_AddPak_Fullpath, true, true }, +{ "pk3", SEARCHPATH_ZIP, FS_AddZip_Fullpath, true, true }, +{ "pk3dir", SEARCHPATH_PK3DIR, FS_AddDir_Fullpath, true, false }, +{ "wad", SEARCHPATH_WAD, FS_AddWad_Fullpath, false, true }, { NULL }, // end marker }; @@ -2653,19 +2653,9 @@ return NULL for file in pack const char *FS_GetDiskPath( const char *name, qboolean gamedironly ) { static char diskpath[MAX_SYSPATH]; - char fullpath[MAX_SYSPATH]; - searchpath_t *search; - search = FS_FindFile( name, NULL, fullpath, sizeof( fullpath ), gamedironly ); - - if( search ) - { - if( search->type != SEARCHPATH_PLAIN ) // file in pack or wad - return NULL; - - Q_snprintf( diskpath, sizeof( diskpath ), "%s/%s", search->filename, fullpath ); + if( FS_GetFullDiskPath( diskpath, sizeof( diskpath ), name, gamedironly )) return diskpath; - } return NULL; } @@ -2687,7 +2677,7 @@ qboolean FS_GetFullDiskPath( char *buffer, size_t size, const char *name, qboole if( search && search->type == SEARCHPATH_PLAIN ) { - Q_snprintf( buffer, size, "%s/%s", search->filename, temp ); + Q_snprintf( buffer, size, "%s%s", search->filename, temp ); return true; } @@ -2931,6 +2921,25 @@ static const char *FS_ArchivePath( file_t *f ) return "plain"; } +static qboolean FS_IsArchiveExtensionSupported( const char *ext, uint flags ) +{ + int i; + + if( ext == NULL ) + return false; + + for( i = 0; i < ( sizeof( g_archives ) / sizeof( g_archives[0] )) - 1; i++ ) + { + if( FBitSet( flags, IAES_ONLY_REAL_ARCHIVES ) && !g_archives[i].real_archive ) + continue; + + if( !Q_stricmp( ext, g_archives[i].ext )) + return true; + } + + return false; +} + void FS_InitMemory( void ) { fs_mempool = Mem_AllocPool( "FileSystem Pool" ); @@ -3059,6 +3068,8 @@ const fs_api_t g_api = FS_GetFullDiskPath, FS_LoadFileMalloc, + + FS_IsArchiveExtensionSupported, }; int EXPORT GetFSAPI( int version, fs_api_t *api, fs_globals_t **globals, fs_interface_t *engfuncs ); diff --git a/filesystem/filesystem.h b/filesystem/filesystem.h index 57d1abc2..0cb6b2aa 100644 --- a/filesystem/filesystem.h +++ b/filesystem/filesystem.h @@ -50,6 +50,13 @@ enum FS_GAMEDIRONLY_SEARCH_FLAGS = FS_GAMEDIR_PATH | FS_CUSTOM_PATH | FS_GAMERODIR_PATH }; +// IsArchiveExtensionSupported flags +enum +{ + // excludes directories and pk3dir, i.e. archives that cannot be represented as a single file + IAES_ONLY_REAL_ARCHIVES = BIT( 0 ), +}; + typedef struct { int numfilenames; @@ -135,8 +142,6 @@ typedef struct fs_globals_t int numgames; } fs_globals_t; -typedef void (*fs_event_callback_t)( const char *path ); - typedef struct fs_api_t { qboolean (*InitStdio)( qboolean unused_set_to_true, const char *rootdir, const char *basedir, const char *gamedir, const char *rodir ); @@ -199,6 +204,9 @@ typedef struct fs_api_t // like LoadFile but returns pointer that can be free'd using standard library function byte *(*LoadFileMalloc)( const char *path, fs_offset_t *filesizeptr, qboolean gamedironly ); + + // queries supported archive formats + qboolean (*IsArchiveExtensionSupported)( const char *ext, uint flags ); } fs_api_t; typedef struct fs_interface_t diff --git a/filesystem/filesystem_internal.h b/filesystem/filesystem_internal.h index 315a10a0..c202ca80 100644 --- a/filesystem/filesystem_internal.h +++ b/filesystem/filesystem_internal.h @@ -114,6 +114,7 @@ typedef struct fs_archive_s 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; diff --git a/filesystem/tests/no-init.c b/filesystem/tests/no-init.c index 3ea2935e..61de215b 100644 --- a/filesystem/tests/no-init.c +++ b/filesystem/tests/no-init.c @@ -57,6 +57,15 @@ static int TestNoInit( void ) p = g_fs.LoadDirectFile( "hehe", NULL ); if( p ) free( p ); + if( !g_fs.IsArchiveExtensionSupported( "pk3", 0 )) return 0; + if( !g_fs.IsArchiveExtensionSupported( "wad", 0 )) return 0; + if( !g_fs.IsArchiveExtensionSupported( "pak", 0 )) return 0; + if( !g_fs.IsArchiveExtensionSupported( "pk3dir", 0 )) return 0; + + if( !g_fs.IsArchiveExtensionSupported( "pk3", IAES_ONLY_REAL_ARCHIVES )) return 0; + if( g_fs.IsArchiveExtensionSupported( "pk3dir", IAES_ONLY_REAL_ARCHIVES )) return 0; + if( g_fs.IsArchiveExtensionSupported( "vpk", 0)) return 0; + g_fs.FileExists( "asdcv", 0 ); g_fs.FileTime( "zxcasdfd", 0 ); g_fs.FileSize( "asdqwe", 1 );