mirror of
https://github.com/FWGS/xash3d-fwgs
synced 2024-11-28 21:10:16 +01:00
filesystem: add functions to directly look up into archives
This commit is contained in:
parent
567cf44111
commit
b94446161e
@ -2477,45 +2477,19 @@ static void FS_CustomFree( void *data )
|
||||
Mem_Free( data );
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
FS_LoadFile
|
||||
|
||||
Filename are relative to the xash directory.
|
||||
Always appends a 0 byte.
|
||||
============
|
||||
*/
|
||||
static byte *FS_LoadFile_( const char *path, fs_offset_t *filesizeptr, const qboolean gamedironly, const qboolean custom_alloc )
|
||||
static byte *FS_LoadFileFromArchive( searchpath_t *sp, const char *path, int pack_ind, fs_offset_t *filesizeptr, const qboolean sys_malloc )
|
||||
{
|
||||
searchpath_t *search;
|
||||
fs_offset_t filesize;
|
||||
file_t *file;
|
||||
byte *buf;
|
||||
char netpath[MAX_SYSPATH];
|
||||
int pack_ind;
|
||||
void *( *pfnAlloc )( size_t ) = custom_alloc ? FS_CustomAlloc : malloc;
|
||||
void ( *pfnFree )( void * ) = custom_alloc ? FS_CustomFree : free;
|
||||
|
||||
// some mappers used leading '/' or '\' in path to models or sounds
|
||||
if( path[0] == '/' || path[0] == '\\' )
|
||||
path++;
|
||||
|
||||
if( path[0] == '/' || path[0] == '\\' )
|
||||
path++;
|
||||
|
||||
if( !fs_searchpaths || FS_CheckNastyPath( path ))
|
||||
return NULL;
|
||||
|
||||
search = FS_FindFile( path, &pack_ind, netpath, sizeof( netpath ), gamedironly );
|
||||
|
||||
if( !search )
|
||||
return NULL;
|
||||
void *( *pfnAlloc )( size_t ) = sys_malloc ? malloc : FS_CustomAlloc;
|
||||
void ( *pfnFree )( void * ) = sys_malloc ? free : FS_CustomFree;
|
||||
|
||||
// custom load file function for compressed files
|
||||
if( search->pfnLoadFile )
|
||||
return search->pfnLoadFile( search, netpath, pack_ind, filesizeptr, pfnAlloc, pfnFree );
|
||||
if( sp->pfnLoadFile )
|
||||
return sp->pfnLoadFile( sp, path, pack_ind, filesizeptr, pfnAlloc, pfnFree );
|
||||
|
||||
file = search->pfnOpenFile( search, netpath, "rb", pack_ind );
|
||||
file = sp->pfnOpenFile( sp, path, "rb", pack_ind );
|
||||
|
||||
if( !file ) // TODO: indicate errors
|
||||
return NULL;
|
||||
@ -2538,6 +2512,38 @@ static byte *FS_LoadFile_( const char *path, fs_offset_t *filesizeptr, const qbo
|
||||
return buf;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
FS_LoadFile
|
||||
|
||||
Filename are relative to the xash directory.
|
||||
Always appends a 0 byte.
|
||||
============
|
||||
*/
|
||||
static byte *FS_LoadFile_( const char *path, fs_offset_t *filesizeptr, const qboolean gamedironly, const qboolean custom_alloc )
|
||||
{
|
||||
searchpath_t *search;
|
||||
char netpath[MAX_SYSPATH];
|
||||
int pack_ind;
|
||||
|
||||
// some mappers used leading '/' or '\' in path to models or sounds
|
||||
if( path[0] == '/' || path[0] == '\\' )
|
||||
path++;
|
||||
|
||||
if( path[0] == '/' || path[0] == '\\' )
|
||||
path++;
|
||||
|
||||
if( !fs_searchpaths || FS_CheckNastyPath( path ))
|
||||
return NULL;
|
||||
|
||||
search = FS_FindFile( path, &pack_ind, netpath, sizeof( netpath ), gamedironly );
|
||||
|
||||
if( !search )
|
||||
return NULL;
|
||||
|
||||
return FS_LoadFileFromArchive( search, netpath, pack_ind, filesizeptr, !custom_alloc );
|
||||
}
|
||||
|
||||
byte *FS_LoadFileMalloc( const char *path, fs_offset_t *filesizeptr, qboolean gamedironly )
|
||||
{
|
||||
return FS_LoadFile_( path, filesizeptr, gamedironly, false );
|
||||
@ -2976,6 +2982,29 @@ static qboolean FS_IsArchiveExtensionSupported( const char *ext, uint flags )
|
||||
return false;
|
||||
}
|
||||
|
||||
static searchpath_t *FS_GetArchiveByName( const char *name, searchpath_t *prev )
|
||||
{
|
||||
searchpath_t *sp = prev ? prev->next : fs_searchpaths;
|
||||
|
||||
for( ; sp; sp = sp->next )
|
||||
{
|
||||
if( !Q_stricmp( COM_FileWithoutPath( sp->filename ), name ))
|
||||
return sp;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int FS_FindFileInArchive( searchpath_t *sp, const char *path, char *truepath, size_t len )
|
||||
{
|
||||
return sp->pfnFindFile( sp, path, truepath, len );
|
||||
}
|
||||
|
||||
static file_t *FS_OpenFileFromArchive( searchpath_t *sp, const char *path, const char *mode, int pack_ind )
|
||||
{
|
||||
return sp->pfnOpenFile( sp, path, mode, pack_ind );
|
||||
}
|
||||
|
||||
void FS_InitMemory( void )
|
||||
{
|
||||
fs_mempool = Mem_AllocPool( "FileSystem Pool" );
|
||||
@ -3106,6 +3135,10 @@ const fs_api_t g_api =
|
||||
FS_LoadFileMalloc,
|
||||
|
||||
FS_IsArchiveExtensionSupported,
|
||||
FS_GetArchiveByName,
|
||||
FS_FindFileInArchive,
|
||||
FS_OpenFileFromArchive,
|
||||
FS_LoadFileFromArchive,
|
||||
};
|
||||
|
||||
int EXPORT GetFSAPI( int version, fs_api_t *api, fs_globals_t **globals, fs_interface_t *engfuncs );
|
||||
|
@ -51,6 +51,8 @@ enum
|
||||
FS_GAMEDIRONLY_SEARCH_FLAGS = FS_GAMEDIR_PATH | FS_CUSTOM_PATH | FS_GAMERODIR_PATH
|
||||
};
|
||||
|
||||
typedef struct searchpath_s searchpath_t;
|
||||
|
||||
// IsArchiveExtensionSupported flags
|
||||
enum
|
||||
{
|
||||
@ -201,8 +203,26 @@ 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
|
||||
// **** archive interface ****
|
||||
// query supported formats
|
||||
qboolean (*IsArchiveExtensionSupported)( const char *ext, uint flags );
|
||||
|
||||
// to speed up archive lookups, this function can be used to get the archive object by it's name
|
||||
// because archive can share the name, you can call this function repeatedly to get all archives
|
||||
searchpath_t *(*GetArchiveByName)( const char *name, searchpath_t *prev );
|
||||
|
||||
// return an index into the archive and a true path, if possible
|
||||
int (*FindFileInArchive)( searchpath_t *sp, const char *path, char *outpath, size_t len );
|
||||
|
||||
// similarly to Open, opens file but from specified archive
|
||||
// NOTE: for speed reasons, path is case-sensitive here!
|
||||
// Use FindFileInArchive to retrieve real path from caseinsensitive FS emulation!
|
||||
file_t *(*OpenFileFromArchive)( searchpath_t *, const char *path, const char *mode, int pack_ind );
|
||||
|
||||
// similarly to LoadFile, loads whole file into memory from specified archive
|
||||
// NOTE: for speed reasons, path is case-sensitive here!
|
||||
// Use FindFileInArchive to retrieve real path from caseinsensitive FS emulation!
|
||||
byte *(*LoadFileFromArchive)( searchpath_t *sp, const char *path, int pack_ind, fs_offset_t *filesizeptr, const qboolean sys_malloc );
|
||||
} fs_api_t;
|
||||
|
||||
typedef struct fs_interface_t
|
||||
|
Loading…
Reference in New Issue
Block a user