From 24f7db19d8324355bbfcd02a11e1069f171c45b0 Mon Sep 17 00:00:00 2001 From: Velaron Date: Fri, 18 Nov 2022 15:35:21 +0200 Subject: [PATCH] filesystem: switch file operations to an interface --- filesystem/dir.c | 110 ++++++++++++++++ filesystem/filesystem.c | 214 +++++-------------------------- filesystem/filesystem_internal.h | 56 +++++--- filesystem/pak.c | 48 ++++--- filesystem/wad.c | 62 ++++++--- filesystem/zip.c | 39 ++++-- 6 files changed, 281 insertions(+), 248 deletions(-) create mode 100644 filesystem/dir.c diff --git a/filesystem/dir.c b/filesystem/dir.c new file mode 100644 index 00000000..a46af43c --- /dev/null +++ b/filesystem/dir.c @@ -0,0 +1,110 @@ +/* +dir.c - directory operations +Copyright (C) 2022 Alibek Omarov, Velaron + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +*/ + +#include +#include +#include +#if XASH_POSIX +#include +#endif +#include +#include +#include "port.h" +#include "filesystem_internal.h" +#include "crtlib.h" +#include "xash3d_mathlib.h" +#include "common/com_strings.h" + +void FS_Close_DIR( searchpath_t *search ) {} + +void FS_PrintInfo_DIR( searchpath_t *search, char *dst, size_t size ) +{ + Q_strncpy( dst, search->filename, size ); +} + +int FS_FindFile_DIR( searchpath_t *search, const char *path ) +{ + char netpath[MAX_SYSPATH]; + + Q_sprintf( netpath, "%s%s", search->filename, path ); + + if( FS_SysFileExists( netpath, !( search->flags & FS_CUSTOM_PATH ) ) ) + return 0; + + return -1; +} + +void FS_Search_DIR( searchpath_t *search, stringlist_t *list, const char *pattern, int caseinsensitive ) +{ + string netpath, temp; + stringlist_t dirlist; + const char *slash, *backslash, *colon, *separator; + int basepathlength, dirlistindex, resultlistindex; + char *basepath; + + slash = Q_strrchr( pattern, '/' ); + backslash = Q_strrchr( pattern, '\\' ); + colon = Q_strrchr( pattern, ':' ); + separator = Q_max( slash, backslash ); + separator = Q_max( separator, colon ); + basepathlength = separator ? (separator + 1 - pattern) : 0; + basepath = Mem_Calloc( fs_mempool, basepathlength + 1 ); + if( basepathlength ) memcpy( basepath, pattern, basepathlength ); + basepath[basepathlength] = 0; + + Q_sprintf( netpath, "%s%s", search->filename, basepath ); + + stringlistinit( &dirlist ); + listdirectory( &dirlist, netpath, caseinsensitive ); + + for( dirlistindex = 0; dirlistindex < dirlist.numstrings; dirlistindex++ ) + { + Q_sprintf( temp, "%s%s", basepath, dirlist.strings[dirlistindex] ); + + if( matchpattern( temp, (char *)pattern, true ) ) + { + for( resultlistindex = 0; resultlistindex < list->numstrings; resultlistindex++ ) + { + if( !Q_strcmp( list->strings[resultlistindex], temp ) ) + break; + } + + if( resultlistindex == list->numstrings ) + stringlistappend( list, temp ); + } + } + + stringlistfreecontents( &dirlist ); + + Mem_Free( basepath ); +} + +int FS_FileTime_DIR( struct searchpath_s *search, const char *filename ) +{ + char path[MAX_SYSPATH]; + + // found in the filesystem? + Q_sprintf( path, "%s%s", search->filename, filename ); + return FS_SysFileTime( path ); +} + +file_t *FS_OpenFile_DIR( struct searchpath_s *search, const char *filename, const char *mode, int pack_ind ) +{ + char path[MAX_SYSPATH]; + + // found in the filesystem? + Q_sprintf( path, "%s%s", search->filename, filename ); + return FS_SysOpen( path, mode ); +} \ No newline at end of file diff --git a/filesystem/filesystem.c b/filesystem/filesystem.c index bbb445d5..e8de5277 100644 --- a/filesystem/filesystem.c +++ b/filesystem/filesystem.c @@ -117,12 +117,12 @@ FILEMATCH COMMON SYSTEM ============================================================================= */ -static void stringlistinit( stringlist_t *list ) +void stringlistinit( stringlist_t *list ) { memset( list, 0, sizeof( *list )); } -static void stringlistfreecontents( stringlist_t *list ) +void stringlistfreecontents( stringlist_t *list ) { int i; @@ -193,7 +193,7 @@ static void listlowercase( stringlist_t *list ) } } -static void listdirectory( stringlist_t *list, const char *path, qboolean lowercase ) +void listdirectory( stringlist_t *list, const char *path, qboolean lowercase ) { int i; signed char *c; @@ -463,6 +463,14 @@ void FS_AddGameDirectory( const char *dir, uint flags ) search->next = fs_searchpaths; search->type = SEARCHPATH_PLAIN; search->flags = flags; + + search->printinfo = FS_PrintInfo_DIR; + search->close = FS_Close_DIR; + search->openfile = FS_OpenFile_DIR; + search->filetime = FS_FileTime_DIR; + search->findfile = FS_FindFile_DIR; + search->search = FS_Search_DIR; + fs_searchpaths = search; } @@ -488,20 +496,7 @@ void FS_ClearSearchPath( void ) } else fs_searchpaths = search->next; - switch( search->type ) - { - case SEARCHPATH_PAK: - FS_ClosePAK( search->pack ); - break; - case SEARCHPATH_WAD: - FS_CloseWAD( search->wad ); - break; - case SEARCHPATH_ZIP: - FS_CloseZIP( search->zip ); - break; - default: - break; - } + search->close( search ); Mem_Free( search ); } @@ -1323,7 +1318,7 @@ static qboolean FS_FindLibrary( const char *dllname, qboolean directpath, fs_dll dllInfo->encrypted = FS_CheckForCrypt( dllInfo->shortPath ); - if( index < 0 && !dllInfo->encrypted && search ) + if( index >= 0 && !dllInfo->encrypted && search ) { Q_snprintf( dllInfo->fullPath, sizeof( dllInfo->fullPath ), "%s%s", search->filename, dllInfo->shortPath ); @@ -1533,21 +1528,7 @@ void FS_Path_f( void ) { string info; - switch( s->type ) - { - case SEARCHPATH_PAK: - FS_PrintPAKInfo( info, sizeof( info ), s->pack ); - break; - case SEARCHPATH_WAD: - FS_PrintWADInfo( info, sizeof( info ), s->wad ); - break; - case SEARCHPATH_ZIP: - FS_PrintZIPInfo( info, sizeof( info ), s->zip ); - break; - case SEARCHPATH_PLAIN: - Q_strncpy( info, s->filename, sizeof( info )); - break; - } + s->printinfo( s, info, sizeof(info) ); Con_Printf( "%s", info ); @@ -1816,48 +1797,16 @@ searchpath_t *FS_FindFile( const char *name, int *index, qboolean gamedironly ) // search through the path, one element at a time for( search = fs_searchpaths; search; search = search->next ) { + int pack_ind; + if( gamedironly & !FBitSet( search->flags, FS_GAMEDIRONLY_SEARCH_FLAGS )) continue; - // is the element a pak file? - if( search->type == SEARCHPATH_PAK ) + pack_ind = search->findfile( search, name ); + if( pack_ind >= 0 ) { - int pack_ind = FS_FindFilePAK( search->pack, name ); - if( pack_ind >= 0 ) - { - if( index ) *index = pack_ind; - return search; - } - } - else if( search->type == SEARCHPATH_WAD ) - { - int pack_ind = FS_FindFileWAD( search->wad, name ); - if( pack_ind >= 0 ) - { - if( index ) *index = pack_ind; - return search; - } - } - else if( search->type == SEARCHPATH_ZIP ) - { - int pack_ind = FS_FindFileZIP( search->zip, name ); - if( pack_ind >= 0 ) - { - if( index ) *index = pack_ind; - return search; - } - } - else - { - char netpath[MAX_SYSPATH]; - - Q_sprintf( netpath, "%s%s", search->filename, name ); - - if( FS_SysFileExists( netpath, !( search->flags & FS_CUSTOM_PATH ) )) - { - if( index != NULL ) *index = -1; - return search; - } + if( index ) *index = pack_ind; + return search; } } @@ -1907,26 +1856,7 @@ file_t *FS_OpenReadFile( const char *filename, const char *mode, qboolean gamedi if( search == NULL ) return NULL; - switch( search->type ) - { - case SEARCHPATH_PAK: - return FS_OpenPackedFile( search->pack, pack_ind ); - case SEARCHPATH_WAD: - return NULL; // let W_LoadFile get lump correctly - case SEARCHPATH_ZIP: - return FS_OpenZipFile( search->zip, pack_ind ); - default: - if( pack_ind < 0 ) - { - char path [MAX_SYSPATH]; - - // found in the filesystem? - Q_sprintf( path, "%s%s", search->filename, filename ); - return FS_SysOpen( path, mode ); - } - } - - return NULL; + return search->openfile( search, filename, mode, pack_ind ); } /* @@ -2611,26 +2541,7 @@ int FS_FileTime( const char *filename, qboolean gamedironly ) search = FS_FindFile( filename, &pack_ind, gamedironly ); if( !search ) return -1; // doesn't exist - switch( search->type ) - { - case SEARCHPATH_PAK: - return FS_FileTimePAK( search->pack ); - case SEARCHPATH_WAD: - return FS_FileTimeWAD( search->wad ); - case SEARCHPATH_ZIP: - return FS_FileTimeZIP( search->zip ); - default: - if( pack_ind < 0 ) - { - char path [MAX_SYSPATH]; - - // found in the filesystem? - Q_sprintf( path, "%s%s", search->filename, filename ); - return FS_SysFileTime( path ); - } - } - - return -1; // doesn't exist + return search->filetime( search, filename ); } /* @@ -2724,80 +2635,23 @@ Allocate and fill a search structure with information on matching filenames. */ search_t *FS_Search( const char *pattern, int caseinsensitive, int gamedironly ) { - search_t *search = NULL; - searchpath_t *searchpath; - pack_t *pak; - wfile_t *wad; - zip_t *zip; - int i, basepathlength, numfiles, numchars; - int resultlistindex, dirlistindex; - const char *slash, *backslash, *colon, *separator; - string netpath, temp; - stringlist_t resultlist; - stringlist_t dirlist; - char *basepath; + search_t *search = NULL; + searchpath_t *searchpath; + int i, numfiles, numchars; + stringlist_t resultlist; if( pattern[0] == '.' || pattern[0] == ':' || pattern[0] == '/' || pattern[0] == '\\' ) return NULL; // punctuation issues stringlistinit( &resultlist ); - stringlistinit( &dirlist ); - slash = Q_strrchr( pattern, '/' ); - backslash = Q_strrchr( pattern, '\\' ); - colon = Q_strrchr( pattern, ':' ); - separator = Q_max( slash, backslash ); - separator = Q_max( separator, colon ); - basepathlength = separator ? (separator + 1 - pattern) : 0; - basepath = Mem_Calloc( fs_mempool, basepathlength + 1 ); - if( basepathlength ) memcpy( basepath, pattern, basepathlength ); - basepath[basepathlength] = 0; // search through the path, one element at a time for( searchpath = fs_searchpaths; searchpath; searchpath = searchpath->next ) { if( gamedironly && !FBitSet( searchpath->flags, FS_GAMEDIRONLY_SEARCH_FLAGS )) continue; - - // is the element a pak file? - if( searchpath->type == SEARCHPATH_PAK ) - { - // look through all the pak file elements - FS_SearchPAK( &resultlist, searchpath->pack, pattern ); - } - else if( searchpath->type == SEARCHPATH_ZIP ) - { - FS_SearchZIP( &resultlist, searchpath->zip, pattern ); - } - else if( searchpath->type == SEARCHPATH_WAD ) - { - FS_SearchWAD( &resultlist, searchpath->wad, pattern ); - } - else - { - // get a directory listing and look at each name - Q_sprintf( netpath, "%s%s", searchpath->filename, basepath ); - stringlistinit( &dirlist ); - listdirectory( &dirlist, netpath, caseinsensitive ); - - for( dirlistindex = 0; dirlistindex < dirlist.numstrings; dirlistindex++ ) - { - Q_sprintf( temp, "%s%s", basepath, dirlist.strings[dirlistindex] ); - - if( matchpattern( temp, (char *)pattern, true )) - { - for( resultlistindex = 0; resultlistindex < resultlist.numstrings; resultlistindex++ ) - { - if( !Q_strcmp( resultlist.strings[resultlistindex], temp )) - break; - } - - if( resultlistindex == resultlist.numstrings ) - stringlistappend( &resultlist, temp ); - } - } - - stringlistfreecontents( &dirlist ); - } + + searchpath->search( searchpath, &resultlist, pattern, caseinsensitive ); } if( resultlist.numstrings ) @@ -2806,21 +2660,21 @@ search_t *FS_Search( const char *pattern, int caseinsensitive, int gamedironly ) numfiles = resultlist.numstrings; numchars = 0; - for( resultlistindex = 0; resultlistindex < resultlist.numstrings; resultlistindex++ ) - numchars += (int)Q_strlen( resultlist.strings[resultlistindex]) + 1; + for( i = 0; i < resultlist.numstrings; i++ ) + numchars += (int)Q_strlen( resultlist.strings[i]) + 1; search = Mem_Calloc( fs_mempool, sizeof(search_t) + numchars + numfiles * sizeof( char* )); search->filenames = (char **)((char *)search + sizeof( search_t )); search->filenamesbuffer = (char *)((char *)search + sizeof( search_t ) + numfiles * sizeof( char* )); search->numfilenames = (int)numfiles; numfiles = numchars = 0; - for( resultlistindex = 0; resultlistindex < resultlist.numstrings; resultlistindex++ ) + for( i = 0; i < resultlist.numstrings; i++ ) { size_t textlen; search->filenames[numfiles] = search->filenamesbuffer + numchars; - textlen = Q_strlen(resultlist.strings[resultlistindex]) + 1; - memcpy( search->filenames[numfiles], resultlist.strings[resultlistindex], textlen ); + textlen = Q_strlen(resultlist.strings[i]) + 1; + memcpy( search->filenames[numfiles], resultlist.strings[i], textlen ); numfiles++; numchars += (int)textlen; } @@ -2828,8 +2682,6 @@ search_t *FS_Search( const char *pattern, int caseinsensitive, int gamedironly ) stringlistfreecontents( &resultlist ); - Mem_Free( basepath ); - return search; } diff --git a/filesystem/filesystem_internal.h b/filesystem/filesystem_internal.h index 99250189..01591f4d 100644 --- a/filesystem/filesystem_internal.h +++ b/filesystem/filesystem_internal.h @@ -69,13 +69,22 @@ typedef struct searchpath_s string filename; int type; int flags; + union { pack_t *pack; wfile_t *wad; zip_t *zip; }; + struct searchpath_s *next; + + void ( *printinfo )( struct searchpath_s *search, char *dst, size_t size ); + void ( *close )( struct searchpath_s *search ); + file_t *( *openfile )( struct searchpath_s *search, const char *filename, const char *mode, int pack_ind ); + int ( *filetime )( struct searchpath_s *search, const char *filename ); + int ( *findfile )( struct searchpath_s *search, const char *path ); + void ( *search )( struct searchpath_s *search, stringlist_t *list, const char *pattern, int caseinsensitive ); } searchpath_t; extern fs_globals_t FI; @@ -156,7 +165,10 @@ qboolean FS_Rename( const char *oldname, const char *newname ); qboolean FS_Delete( const char *path ); qboolean FS_SysFileExists( const char *path, qboolean casesensitive ); const char *FS_GetDiskPath( const char *name, qboolean gamedironly ); +void stringlistinit( stringlist_t *list ); +void stringlistfreecontents( stringlist_t *list ); void stringlistappend( stringlist_t *list, char *text ); +void listdirectory( stringlist_t *list, const char *path, qboolean lowercase ); void FS_CreatePath( char *path ); qboolean FS_SysFolderExists( const char *path ); file_t *FS_OpenReadFile( const char *filename, const char *mode, qboolean gamedironly ); @@ -170,22 +182,22 @@ searchpath_t *FS_FindFile( const char *name, int *index, qboolean gamedironly ); // // pak.c // -int FS_FileTimePAK( pack_t *pack ); -int FS_FindFilePAK( pack_t *pack, const char *name ); -void FS_PrintPAKInfo( char *dst, size_t size, pack_t *pack ); -void FS_ClosePAK( pack_t *pack ); -void FS_SearchPAK( stringlist_t *list, pack_t *pack, const char *pattern ); -file_t *FS_OpenPackedFile( pack_t *pack, int pack_ind ); +int FS_FileTime_PAK( searchpath_t *search, const char *filename ); +int FS_FindFile_PAK( searchpath_t *search, const char *path ); +void FS_PrintInfo_PAK( searchpath_t *search, char *dst, size_t size ); +void FS_Close_PAK( searchpath_t *search ); +void FS_Search_PAK( searchpath_t *search, stringlist_t *list, const char *pattern, int caseinsensitive ); +file_t *FS_OpenFile_PAK( searchpath_t *search, const char *filename, const char *mode, int pack_ind ); qboolean FS_AddPak_Fullpath( const char *pakfile, qboolean *already_loaded, int flags ); // // wad.c // -int FS_FileTimeWAD( wfile_t *wad ); -int FS_FindFileWAD( wfile_t *wad, const char *name ); -void FS_PrintWADInfo( char *dst, size_t size, wfile_t *wad ); -void FS_CloseWAD( wfile_t *wad ); -void FS_SearchWAD( stringlist_t *list, wfile_t *wad, const char *pattern ); +int FS_FileTime_WAD( searchpath_t *search, const char *filename ); +int FS_FindFile_WAD( searchpath_t *search, const char *path ); +void FS_PrintInfo_WAD( searchpath_t *search, char *dst, size_t size ); +void FS_Close_WAD( searchpath_t *search ); +void FS_Search_WAD( searchpath_t *search, stringlist_t *list, const char *pattern, int caseinsensitive ); byte *FS_LoadWADFile( const char *path, fs_offset_t *sizeptr, qboolean gamedironly ); qboolean FS_AddWad_Fullpath( const char *wadfile, qboolean *already_loaded, int flags ); @@ -199,15 +211,25 @@ void FS_WatchFrame( void ); // // zip.c // -int FS_FileTimeZIP( zip_t *zip ); -int FS_FindFileZIP( zip_t *zip, const char *name ); -void FS_PrintZIPInfo( char *dst, size_t size, zip_t *zip ); -void FS_CloseZIP( zip_t *zip ); -void FS_SearchZIP( stringlist_t *list, zip_t *zip, const char *pattern ); +int FS_FileTime_ZIP( searchpath_t *search, const char *filename ); +int FS_FindFile_ZIP( searchpath_t *search, const char *path ); +void FS_PrintInfo_ZIP( searchpath_t *search, char *dst, size_t size ); +void FS_Close_ZIP( searchpath_t *search ); +void FS_Search_ZIP( searchpath_t *search, stringlist_t *list, const char *pattern, int caseinsensitive ); byte *FS_LoadZIPFile( const char *path, fs_offset_t *sizeptr, qboolean gamedironly ); -file_t *FS_OpenZipFile( zip_t *zip, int pack_ind ); +file_t *FS_OpenFile_ZIP( searchpath_t *search, const char *filename, const char *mode, int pack_ind ); qboolean FS_AddZip_Fullpath( const char *zipfile, qboolean *already_loaded, int flags ); +// +// dir.c +// +void FS_PrintInfo_DIR( searchpath_t *search, char *dst, size_t size ); +void FS_Close_DIR( searchpath_t *search ); +file_t *FS_OpenFile_DIR( searchpath_t *search, const char *filename, const char *mode, int pack_ind ); +int FS_FileTime_DIR( searchpath_t *search, const char *filename ); +int FS_FindFile_DIR( searchpath_t *search, const char *path ); +void FS_Search_DIR( searchpath_t *search, stringlist_t *list, const char *pattern, int caseinsensitive ); + #ifdef __cplusplus } #endif diff --git a/filesystem/pak.c b/filesystem/pak.c index 1cc0037a..080fd975 100644 --- a/filesystem/pak.c +++ b/filesystem/pak.c @@ -230,13 +230,13 @@ FS_OpenPackedFile Open a packed file using its package file descriptor =========== */ -file_t *FS_OpenPackedFile( pack_t *pack, int pack_ind ) +file_t *FS_OpenFile_PAK( searchpath_t *search, const char *filename, const char *mode, int pack_ind ) { dpackfile_t *pfile; - pfile = &pack->files[pack_ind]; + pfile = &search->pack->files[pack_ind]; - return FS_OpenHandle( pack->filename, pack->handle, pfile->filepos, pfile->filelen ); + return FS_OpenHandle( search->pack->filename, search->pack->handle, pfile->filepos, pfile->filelen ); } /* @@ -284,6 +284,14 @@ qboolean FS_AddPak_Fullpath( const char *pakfile, qboolean *already_loaded, int search->type = SEARCHPATH_PAK; search->next = fs_searchpaths; search->flags |= flags; + + search->printinfo = FS_PrintInfo_PAK; + search->close = FS_Close_PAK; + search->openfile = FS_OpenFile_PAK; + search->filetime = FS_FileTime_PAK; + search->findfile = FS_FindFile_PAK; + search->search = FS_Search_PAK; + fs_searchpaths = search; Con_Reportf( "Adding pakfile: %s (%i files)\n", pakfile, pak->numfiles ); @@ -308,19 +316,19 @@ qboolean FS_AddPak_Fullpath( const char *pakfile, qboolean *already_loaded, int } } -int FS_FindFilePAK( pack_t *pack, const char *name ) +int FS_FindFile_PAK( searchpath_t *search, const char *path ) { int left, right, middle; // look for the file (binary search) left = 0; - right = pack->numfiles - 1; + right = search->pack->numfiles - 1; while( left <= right ) { int diff; middle = (left + right) / 2; - diff = Q_stricmp( pack->files[middle].name, name ); + diff = Q_stricmp( search->pack->files[middle].name, path ); // Found it if( !diff ) @@ -337,15 +345,15 @@ int FS_FindFilePAK( pack_t *pack, const char *name ) return -1; } -void FS_SearchPAK( stringlist_t *list, pack_t *pack, const char *pattern ) +void FS_Search_PAK( searchpath_t *search, stringlist_t *list, const char *pattern, int caseinsensitive ) { string temp; const char *slash, *backslash, *colon, *separator; int j, i; - for( i = 0; i < pack->numfiles; i++ ) + for( i = 0; i < search->pack->numfiles; i++ ) { - Q_strncpy( temp, pack->files[i].name, sizeof( temp )); + Q_strncpy( temp, search->pack->files[i].name, sizeof( temp )); while( temp[0] ) { if( matchpattern( temp, pattern, true )) @@ -377,21 +385,21 @@ void FS_SearchPAK( stringlist_t *list, pack_t *pack, const char *pattern ) } } -int FS_FileTimePAK( pack_t *pack ) +int FS_FileTime_PAK( searchpath_t *search, const char *filename ) { - return pack->filetime; + return search->pack->filetime; } -void FS_PrintPAKInfo( char *dst, size_t size, pack_t *pack ) +void FS_PrintInfo_PAK( searchpath_t *search, char *dst, size_t size ) { - Q_snprintf( dst, size, "%s (%i files)", pack->filename, pack->numfiles ); + Q_snprintf( dst, size, "%s (%i files)", search->pack->filename, search->pack->numfiles ); } -void FS_ClosePAK( pack_t *pack ) +void FS_Close_PAK( searchpath_t *search ) { - if( pack->files ) - Mem_Free( pack->files ); - if( pack->handle >= 0 ) - close( pack->handle ); - Mem_Free( pack ); -} + if( search->pack->files ) + Mem_Free( search->pack->files ); + if( search->pack->handle >= 0 ) + close( search->pack->handle ); + Mem_Free( search->pack ); +} \ No newline at end of file diff --git a/filesystem/wad.c b/filesystem/wad.c index 646476d3..b1b69ccb 100644 --- a/filesystem/wad.c +++ b/filesystem/wad.c @@ -216,6 +216,26 @@ void FS_CloseWAD( wfile_t *wad ) Mem_Free( wad ); // free himself } +/* +=========== +FS_Close_WAD +=========== +*/ +void FS_Close_WAD( searchpath_t *search ) +{ + FS_CloseWAD( search->wad ); +} + +/* +=========== +FS_OpenFile_WAD +=========== +*/ +file_t *FS_OpenFile_WAD( searchpath_t *search, const char *filename, const char *mode, int pack_ind ) +{ + return NULL; +} + /* =========== W_Open @@ -376,6 +396,14 @@ qboolean FS_AddWad_Fullpath( const char *wadfile, qboolean *already_loaded, int search->type = SEARCHPATH_WAD; search->next = fs_searchpaths; search->flags |= flags; + + search->printinfo = FS_PrintInfo_WAD; + search->close = FS_Close_WAD; + search->openfile = FS_OpenFile_WAD; + search->filetime = FS_FileTime_WAD; + search->findfile = FS_FindFile_WAD; + search->search = FS_Search_WAD; + fs_searchpaths = search; Con_Reportf( "Adding wadfile: %s (%i files)\n", wadfile, wad->numlumps ); @@ -501,20 +529,20 @@ byte *FS_LoadWADFile( const char *path, fs_offset_t *lumpsizeptr, qboolean gamed return NULL; } -int FS_FileTimeWAD( wfile_t *wad ) +int FS_FileTime_WAD( searchpath_t *search, const char *filename ) { - return wad->filetime; + return search->wad->filetime; } -void FS_PrintWADInfo( char *dst, size_t size, wfile_t *wad ) +void FS_PrintInfo_WAD( searchpath_t *search, char *dst, size_t size ) { - Q_snprintf( dst, size, "%s (%i files)", wad->filename, wad->numlumps ); + Q_snprintf( dst, size, "%s (%i files)", search->wad->filename, search->wad->numlumps ); } -int FS_FindFileWAD( wfile_t *wad, const char *name ) +int FS_FindFile_WAD( searchpath_t *search, const char *path ) { dlumpinfo_t *lump; - signed char type = W_TypeFromExt( name ); + signed char type = W_TypeFromExt( path ); qboolean anywadname = true; string wadname, wadfolder; string shortname; @@ -523,7 +551,7 @@ int FS_FindFileWAD( wfile_t *wad, const char *name ) if( type == TYP_NONE ) return -1; - COM_ExtractFilePath( name, wadname ); + COM_ExtractFilePath( path, wadname ); wadfolder[0] = '\0'; if( COM_CheckStringEmpty( wadname ) ) @@ -535,7 +563,7 @@ int FS_FindFileWAD( wfile_t *wad, const char *name ) } // make wadname from wad fullpath - COM_FileBase( wad->filename, shortname ); + COM_FileBase( search->wad->filename, shortname ); COM_DefaultExtension( shortname, ".wad" ); // quick reject by wadname @@ -544,20 +572,20 @@ int FS_FindFileWAD( wfile_t *wad, const char *name ) // NOTE: we can't using long names for wad, // because we using original wad names[16]; - COM_FileBase( name, shortname ); + COM_FileBase( path, shortname ); - lump = W_FindLump( wad, shortname, type ); + lump = W_FindLump( search->wad, shortname, type ); if( lump ) { - return lump - wad->lumps; + return lump - search->wad->lumps; } return -1; } -void FS_SearchWAD( stringlist_t *list, wfile_t *wad, const char *pattern ) +void FS_Search_WAD( searchpath_t *search, stringlist_t *list, const char *pattern, int caseinsensitive ) { string wadpattern, wadname, temp2; signed char type = W_TypeFromExt( pattern ); @@ -583,21 +611,21 @@ void FS_SearchWAD( stringlist_t *list, wfile_t *wad, const char *pattern ) } // make wadname from wad fullpath - COM_FileBase( wad->filename, temp2 ); + COM_FileBase( search->wad->filename, temp2 ); COM_DefaultExtension( temp2, ".wad" ); // quick reject by wadname if( !anywadname && Q_stricmp( wadname, temp2 )) return; - for( i = 0; i < wad->numlumps; i++ ) + for( i = 0; i < search->wad->numlumps; i++ ) { // if type not matching, we already have no chance ... - if( type != TYP_ANY && wad->lumps[i].type != type ) + if( type != TYP_ANY && search->wad->lumps[i].type != type ) continue; // build the lumpname with image suffix (if present) - Q_strncpy( temp, wad->lumps[i].name, sizeof( temp )); + Q_strncpy( temp, search->wad->lumps[i].name, sizeof( temp )); while( temp[0] ) { @@ -613,7 +641,7 @@ void FS_SearchWAD( stringlist_t *list, wfile_t *wad, const char *pattern ) { // build path: wadname/lumpname.ext Q_snprintf( temp2, sizeof(temp2), "%s/%s", wadfolder, temp ); - COM_DefaultExtension( temp2, va(".%s", W_ExtFromType( wad->lumps[i].type ))); + COM_DefaultExtension( temp2, va(".%s", W_ExtFromType( search->wad->lumps[i].type ))); stringlistappend( list, temp2 ); } } diff --git a/filesystem/zip.c b/filesystem/zip.c index 829d1553..cb40160f 100644 --- a/filesystem/zip.c +++ b/filesystem/zip.c @@ -159,6 +159,11 @@ void FS_CloseZIP( zip_t *zip ) Mem_Free( zip ); } +void FS_Close_ZIP( searchpath_t *search ) +{ + FS_CloseZIP( search->zip ); +} + /* ============ FS_SortZip @@ -392,10 +397,10 @@ FS_OpenZipFile Open a packed file using its package file descriptor =========== */ -file_t *FS_OpenZipFile( zip_t *zip, int pack_ind ) +file_t *FS_OpenFile_ZIP( searchpath_t *search, const char *filename, const char *mode, int pack_ind ) { zipfile_t *pfile; - pfile = &zip->files[pack_ind]; + pfile = &search->zip->files[pack_ind]; // compressed files handled in Zip_LoadFile if( pfile->flags != ZIP_COMPRESSION_NO_COMPRESSION ) @@ -404,7 +409,7 @@ file_t *FS_OpenZipFile( zip_t *zip, int pack_ind ) return NULL; } - return FS_OpenHandle( zip->filename, zip->handle, pfile->offset, pfile->size ); + return FS_OpenHandle( search->zip->filename, search->zip->handle, pfile->offset, pfile->size ); } byte *FS_LoadZIPFile( const char *path, fs_offset_t *sizeptr, qboolean gamedironly ) @@ -578,6 +583,14 @@ qboolean FS_AddZip_Fullpath( const char *zipfile, qboolean *already_loaded, int search->type = SEARCHPATH_ZIP; search->next = fs_searchpaths; search->flags |= flags; + + search->printinfo = FS_PrintInfo_ZIP; + search->close = FS_Close_ZIP; + search->openfile = FS_OpenFile_ZIP; + search->filetime = FS_FileTime_ZIP; + search->findfile = FS_FindFile_ZIP; + search->search = FS_Search_ZIP; + fs_searchpaths = search; Con_Reportf( "Adding zipfile: %s (%i files)\n", zipfile, zip->numfiles ); @@ -601,29 +614,29 @@ qboolean FS_AddZip_Fullpath( const char *zipfile, qboolean *already_loaded, int } } -int FS_FileTimeZIP( zip_t *zip ) +int FS_FileTime_ZIP( searchpath_t *search, const char *filename ) { - return zip->filetime; + return search->zip->filetime; } -void FS_PrintZIPInfo( char *dst, size_t size, zip_t *zip ) +void FS_PrintInfo_ZIP( searchpath_t *search, char *dst, size_t size ) { - Q_snprintf( dst, size, "%s (%i files)", zip->filename, zip->numfiles ); + Q_snprintf( dst, size, "%s (%i files)", search->zip->filename, search->zip->numfiles ); } -int FS_FindFileZIP( zip_t *zip, const char *name ) +int FS_FindFile_ZIP( searchpath_t *search, const char *path ) { int left, right, middle; // look for the file (binary search) left = 0; - right = zip->numfiles - 1; + right = search->zip->numfiles - 1; while( left <= right ) { int diff; middle = (left + right) / 2; - diff = Q_stricmp( zip->files[middle].name, name ); + diff = Q_stricmp( search->zip->files[middle].name, path ); // Found it if( !diff ) @@ -638,15 +651,15 @@ int FS_FindFileZIP( zip_t *zip, const char *name ) return -1; } -void FS_SearchZIP( stringlist_t *list, zip_t *zip, const char *pattern ) +void FS_Search_ZIP( searchpath_t *search, stringlist_t *list, const char *pattern, int caseinsensitive ) { string temp; const char *slash, *backslash, *colon, *separator; int j, i; - for( i = 0; i < zip->numfiles; i++ ) + for( i = 0; i < search->zip->numfiles; i++ ) { - Q_strncpy( temp, zip->files[i].name, sizeof( temp )); + Q_strncpy( temp, search->zip->files[i].name, sizeof( temp )); while( temp[0] ) { if( matchpattern( temp, pattern, true ))