|
|
@ -21,9 +21,11 @@ GNU General Public License for more details. |
|
|
|
#include "filesystem.h" |
|
|
|
#include "filesystem.h" |
|
|
|
#include "filesystem_internal.h" |
|
|
|
#include "filesystem_internal.h" |
|
|
|
#include "VFileSystem009.h" |
|
|
|
#include "VFileSystem009.h" |
|
|
|
|
|
|
|
#include "common/com_strings.h" |
|
|
|
|
|
|
|
|
|
|
|
#if __cplusplus < 201103L |
|
|
|
#if __cplusplus < 201103L |
|
|
|
#define override |
|
|
|
#define override |
|
|
|
|
|
|
|
#define nullptr NULL |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
// GoldSrc Directories and ID
|
|
|
|
// GoldSrc Directories and ID
|
|
|
@ -35,7 +37,11 @@ GNU General Public License for more details. |
|
|
|
// PLATFORM platform
|
|
|
|
// PLATFORM platform
|
|
|
|
// CONFIG platform/config
|
|
|
|
// CONFIG platform/config
|
|
|
|
|
|
|
|
|
|
|
|
static inline qboolean IsIdGamedir( const char *id ) |
|
|
|
#define FixupPath( var, str ) \ |
|
|
|
|
|
|
|
char *var = static_cast<char *>( alloca( Q_strlen(( str )) + 1 )); \ |
|
|
|
|
|
|
|
CopyAndFixSlashes(( var ),( str )) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static inline bool IsIdGamedir( const char *id ) |
|
|
|
{ |
|
|
|
{ |
|
|
|
return !Q_strcmp( id, "GAME" ) || |
|
|
|
return !Q_strcmp( id, "GAME" ) || |
|
|
|
!Q_strcmp( id, "GAMECONFIG" ) || |
|
|
|
!Q_strcmp( id, "GAMECONFIG" ) || |
|
|
@ -46,18 +52,23 @@ static inline const char *IdToDir( char *dir, size_t size, const char *id ) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if( !Q_strcmp( id, "GAME" )) |
|
|
|
if( !Q_strcmp( id, "GAME" )) |
|
|
|
return GI->gamefolder; |
|
|
|
return GI->gamefolder; |
|
|
|
else if( !Q_strcmp( id, "GAMEDOWNLOAD" )) |
|
|
|
|
|
|
|
|
|
|
|
if( !Q_strcmp( id, "GAMEDOWNLOAD" )) |
|
|
|
{ |
|
|
|
{ |
|
|
|
Q_snprintf( dir, size, "%s/downloaded", GI->gamefolder ); |
|
|
|
Q_snprintf( dir, size, "%s/downloaded", GI->gamefolder ); |
|
|
|
return dir; |
|
|
|
return dir; |
|
|
|
} |
|
|
|
} |
|
|
|
else if( !Q_strcmp( id, "GAMECONFIG" )) |
|
|
|
|
|
|
|
|
|
|
|
if( !Q_strcmp( id, "GAMECONFIG" )) |
|
|
|
return fs_writepath->filename; // full path here so it's totally our write allowed directory
|
|
|
|
return fs_writepath->filename; // full path here so it's totally our write allowed directory
|
|
|
|
else if( !Q_strcmp( id, "PLATFORM" )) |
|
|
|
|
|
|
|
|
|
|
|
if( !Q_strcmp( id, "PLATFORM" )) |
|
|
|
return "platform"; // stub
|
|
|
|
return "platform"; // stub
|
|
|
|
else if( !Q_strcmp( id, "CONFIG" )) |
|
|
|
|
|
|
|
|
|
|
|
if( !Q_strcmp( id, "CONFIG" )) |
|
|
|
return "platform/config"; // stub
|
|
|
|
return "platform/config"; // stub
|
|
|
|
else // ROOT || BASE
|
|
|
|
|
|
|
|
|
|
|
|
// ROOT || BASE
|
|
|
|
return fs_rootdir; // give at least root directory
|
|
|
|
return fs_rootdir; // give at least root directory
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -74,12 +85,11 @@ private: |
|
|
|
{ |
|
|
|
{ |
|
|
|
public: |
|
|
|
public: |
|
|
|
CSearchState( CSearchState **head, search_t *search ) : |
|
|
|
CSearchState( CSearchState **head, search_t *search ) : |
|
|
|
next( *head ), search( search ), index( 0 ) |
|
|
|
next( *head ), |
|
|
|
|
|
|
|
search( search ), |
|
|
|
|
|
|
|
index( 0 ), |
|
|
|
|
|
|
|
handle( *head ? ( *head )->handle + 1 : 0 ) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if( *head ) |
|
|
|
|
|
|
|
handle = (*head)->handle + 1; |
|
|
|
|
|
|
|
else handle = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*head = this; |
|
|
|
*head = this; |
|
|
|
} |
|
|
|
} |
|
|
|
~CSearchState() |
|
|
|
~CSearchState() |
|
|
@ -100,17 +110,15 @@ private: |
|
|
|
for( CSearchState *state = searchHead; state; state = state->next ) |
|
|
|
for( CSearchState *state = searchHead; state; state = state->next ) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if( state->handle == handle ) |
|
|
|
if( state->handle == handle ) |
|
|
|
{ |
|
|
|
|
|
|
|
return state; |
|
|
|
return state; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Con_DPrintf( "Can't find search state by handle %d\n", handle ); |
|
|
|
Con_DPrintf( "Can't find search state by handle %d\n", handle ); |
|
|
|
return NULL; |
|
|
|
return nullptr; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public: |
|
|
|
public: |
|
|
|
CXashFS() : searchHead( NULL ) |
|
|
|
CXashFS() : searchHead( nullptr ) |
|
|
|
{ |
|
|
|
{ |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -121,17 +129,13 @@ public: |
|
|
|
|
|
|
|
|
|
|
|
void AddSearchPath( const char *path, const char *id ) override |
|
|
|
void AddSearchPath( const char *path, const char *id ) override |
|
|
|
{ |
|
|
|
{ |
|
|
|
char *p = (char *)alloca( Q_strlen( path ) + 1 ); |
|
|
|
FixupPath( p, path ); |
|
|
|
CopyAndFixSlashes( p, path ); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FS_AddGameDirectory( p, FS_CUSTOM_PATH ); |
|
|
|
FS_AddGameDirectory( p, FS_CUSTOM_PATH ); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void AddSearchPathNoWrite( const char *path, const char *id ) override |
|
|
|
void AddSearchPathNoWrite( const char *path, const char *id ) override |
|
|
|
{ |
|
|
|
{ |
|
|
|
char *p = (char *)alloca( Q_strlen( path ) + 1 ); |
|
|
|
FixupPath( p, path ); |
|
|
|
CopyAndFixSlashes( p, path ); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FS_AddGameDirectory( p, FS_NOWRITE_PATH | FS_CUSTOM_PATH ); |
|
|
|
FS_AddGameDirectory( p, FS_NOWRITE_PATH | FS_CUSTOM_PATH ); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -156,110 +160,111 @@ public: |
|
|
|
|
|
|
|
|
|
|
|
bool FileExists( const char *path ) override |
|
|
|
bool FileExists( const char *path ) override |
|
|
|
{ |
|
|
|
{ |
|
|
|
char *p = (char *)alloca( Q_strlen( path ) + 1 ); |
|
|
|
FixupPath( p, path ); |
|
|
|
CopyAndFixSlashes( p, path ); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return FS_FileExists( p, false ); |
|
|
|
return FS_FileExists( p, false ); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool IsDirectory( const char *path ) override |
|
|
|
bool IsDirectory( const char *path ) override |
|
|
|
{ |
|
|
|
{ |
|
|
|
char *p = (char *)alloca( Q_strlen( path ) + 1 ); |
|
|
|
FixupPath( p, path ); |
|
|
|
CopyAndFixSlashes( p, path ); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return FS_SysFolderExists( p ); |
|
|
|
return FS_SysFolderExists( p ); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
FileHandle_t Open( const char *path, const char *mode, const char *id ) override |
|
|
|
FileHandle_t Open( const char *path, const char *mode, const char *id ) override |
|
|
|
{ |
|
|
|
{ |
|
|
|
char *p = (char *)alloca( Q_strlen( path ) + 1 ); |
|
|
|
file_t *fd; |
|
|
|
CopyAndFixSlashes( p, path ); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
file_t *fd = FS_Open( p, mode, IsIdGamedir( id ) ); |
|
|
|
FixupPath( p, path ); |
|
|
|
|
|
|
|
fd = FS_Open( p, mode, IsIdGamedir( id )); |
|
|
|
|
|
|
|
|
|
|
|
return fd; |
|
|
|
return fd; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void Close( FileHandle_t handle ) override |
|
|
|
void Close( FileHandle_t handle ) override |
|
|
|
{ |
|
|
|
{ |
|
|
|
FS_Close( (file_t *)handle ); |
|
|
|
FS_Close( static_cast<file_t *>( handle )); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void Seek( FileHandle_t handle, int offset, FileSystemSeek_t whence ) override |
|
|
|
void Seek( FileHandle_t handle, int offset, FileSystemSeek_t whence ) override |
|
|
|
{ |
|
|
|
{ |
|
|
|
int whence_ = SEEK_SET; |
|
|
|
int whence_ = SEEK_SET; |
|
|
|
|
|
|
|
|
|
|
|
switch( whence ) |
|
|
|
switch( whence ) |
|
|
|
{ |
|
|
|
{ |
|
|
|
case FILESYSTEM_SEEK_HEAD: whence_ = SEEK_SET; break; |
|
|
|
case FILESYSTEM_SEEK_HEAD: |
|
|
|
case FILESYSTEM_SEEK_CURRENT: whence_ = SEEK_CUR; break; |
|
|
|
whence_ = SEEK_SET; |
|
|
|
case FILESYSTEM_SEEK_TAIL: whence_ = SEEK_END; break; |
|
|
|
break; |
|
|
|
|
|
|
|
case FILESYSTEM_SEEK_CURRENT: |
|
|
|
|
|
|
|
whence_ = SEEK_CUR; |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case FILESYSTEM_SEEK_TAIL: |
|
|
|
|
|
|
|
whence_ = SEEK_END; |
|
|
|
|
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
FS_Seek( (file_t *)handle, offset, whence_ ); |
|
|
|
FS_Seek( static_cast<file_t *>( handle ), offset, whence_ ); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
unsigned int Tell( FileHandle_t handle ) override |
|
|
|
unsigned int Tell( FileHandle_t handle ) override |
|
|
|
{ |
|
|
|
{ |
|
|
|
return FS_Tell( (file_t *)handle ); |
|
|
|
return FS_Tell( static_cast<file_t *>( handle )); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
unsigned int Size( FileHandle_t handle ) override |
|
|
|
unsigned int Size( FileHandle_t handle ) override |
|
|
|
{ |
|
|
|
{ |
|
|
|
file_t *fd = (file_t *)handle; |
|
|
|
return static_cast<file_t *>( handle )->real_length; |
|
|
|
return fd->real_length; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
unsigned int Size( const char *path ) override |
|
|
|
unsigned int Size( const char *path ) override |
|
|
|
{ |
|
|
|
{ |
|
|
|
char *p = (char *)alloca( Q_strlen( path ) + 1 ); |
|
|
|
FixupPath( p, path ); |
|
|
|
CopyAndFixSlashes( p, path ); |
|
|
|
|
|
|
|
return FS_FileSize( p, false ); |
|
|
|
return FS_FileSize( p, false ); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
long int GetFileTime( const char *path ) override |
|
|
|
long int GetFileTime( const char *path ) override |
|
|
|
{ |
|
|
|
{ |
|
|
|
char *p = (char *)alloca( Q_strlen( path ) + 1 ); |
|
|
|
FixupPath( p, path ); |
|
|
|
CopyAndFixSlashes( p, path ); |
|
|
|
|
|
|
|
return FS_FileTime( p, false ); |
|
|
|
return FS_FileTime( p, false ); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void FileTimeToString( char *p, int size, long int time ) override |
|
|
|
void FileTimeToString( char *p, int size, long int time ) override |
|
|
|
{ |
|
|
|
{ |
|
|
|
time_t curtime = time; |
|
|
|
const time_t curtime = time; |
|
|
|
char *buf = ctime( &curtime ); |
|
|
|
char *buf = ctime( &curtime ); |
|
|
|
|
|
|
|
|
|
|
|
Q_strncpy( p, buf, size ); |
|
|
|
Q_strncpy( p, buf, size ); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool IsOk( FileHandle_t handle ) override |
|
|
|
bool IsOk( FileHandle_t handle ) override |
|
|
|
{ |
|
|
|
{ |
|
|
|
return !FS_Eof( (file_t *)handle ); |
|
|
|
return !FS_Eof( static_cast<file_t *>( handle )); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void Flush( FileHandle_t handle ) override |
|
|
|
void Flush( FileHandle_t handle ) override |
|
|
|
{ |
|
|
|
{ |
|
|
|
FS_Flush( (file_t *)handle ); |
|
|
|
FS_Flush( static_cast<file_t *>( handle )); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool EndOfFile( FileHandle_t handle ) override |
|
|
|
bool EndOfFile( FileHandle_t handle ) override |
|
|
|
{ |
|
|
|
{ |
|
|
|
return FS_Eof( (file_t *)handle ); |
|
|
|
return FS_Eof( static_cast<file_t *>( handle )); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int Read( void *buf, int size, FileHandle_t handle ) override |
|
|
|
int Read( void *buf, int size, FileHandle_t handle ) override |
|
|
|
{ |
|
|
|
{ |
|
|
|
return FS_Read( (file_t *)handle, buf, size ); |
|
|
|
return FS_Read( static_cast<file_t *>( handle ), buf, size ); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int Write( const void *buf, int size, FileHandle_t handle ) override |
|
|
|
int Write( const void *buf, int size, FileHandle_t handle ) override |
|
|
|
{ |
|
|
|
{ |
|
|
|
return FS_Write( (file_t *)handle, buf, size ); |
|
|
|
return FS_Write( static_cast<file_t *>( handle ), buf, size ); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
char *ReadLine( char *buf, int size, FileHandle_t handle ) override |
|
|
|
char *ReadLine( char *buf, int size, FileHandle_t handle ) override |
|
|
|
{ |
|
|
|
{ |
|
|
|
int c = FS_Gets( (file_t *)handle, (byte*)buf, size ); |
|
|
|
const int c = FS_Gets( static_cast<file_t *>( handle ), buf, size ); |
|
|
|
|
|
|
|
|
|
|
|
return c >= 0 ? buf : NULL; |
|
|
|
return c >= 0 ? buf : nullptr; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int FPrintf( FileHandle_t handle, char *fmt, ... ) override |
|
|
|
int FPrintf( FileHandle_t handle, char *fmt, ... ) override |
|
|
@ -268,41 +273,41 @@ public: |
|
|
|
int ret; |
|
|
|
int ret; |
|
|
|
|
|
|
|
|
|
|
|
va_start( ap, fmt ); |
|
|
|
va_start( ap, fmt ); |
|
|
|
ret = FS_VPrintf( (file_t *)handle, fmt, ap ); |
|
|
|
ret = FS_VPrintf( static_cast<file_t *>( handle ), fmt, ap ); |
|
|
|
va_end( ap ); |
|
|
|
va_end( ap ); |
|
|
|
|
|
|
|
|
|
|
|
return ret; |
|
|
|
return ret; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void * GetReadBuffer(FileHandle_t, int *size, bool) override |
|
|
|
void *GetReadBuffer( FileHandle_t, int *size, bool ) override |
|
|
|
{ |
|
|
|
{ |
|
|
|
// deprecated by Valve
|
|
|
|
// deprecated by Valve
|
|
|
|
*size = 0; |
|
|
|
*size = 0; |
|
|
|
return NULL; |
|
|
|
return nullptr; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void ReleaseReadBuffer(FileHandle_t, void *) override |
|
|
|
void ReleaseReadBuffer( FileHandle_t, void * ) override |
|
|
|
{ |
|
|
|
{ |
|
|
|
// deprecated by Valve
|
|
|
|
// deprecated by Valve
|
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const char *FindFirst(const char *pattern, FileFindHandle_t *handle, const char *id) override |
|
|
|
const char *FindFirst( const char *pattern, FileFindHandle_t *handle, const char *id ) override |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
CSearchState *state; |
|
|
|
|
|
|
|
search_t *search; |
|
|
|
|
|
|
|
|
|
|
|
if( !handle || !pattern ) |
|
|
|
if( !handle || !pattern ) |
|
|
|
return NULL; |
|
|
|
return nullptr; |
|
|
|
|
|
|
|
|
|
|
|
char *p = (char *)alloca( Q_strlen( pattern ) + 1 ); |
|
|
|
FixupPath( p, pattern ); |
|
|
|
CopyAndFixSlashes( p, pattern ); |
|
|
|
search = FS_Search( p, true, IsIdGamedir( id )); |
|
|
|
search_t *search = FS_Search( p, true, IsIdGamedir( id )); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if( !search ) |
|
|
|
if( !search ) |
|
|
|
return NULL; |
|
|
|
return nullptr; |
|
|
|
|
|
|
|
|
|
|
|
CSearchState *state = new CSearchState( &searchHead, search ); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
state = new CSearchState( &searchHead, search ); |
|
|
|
*handle = state->handle; |
|
|
|
*handle = state->handle; |
|
|
|
|
|
|
|
|
|
|
|
return state->search->filenames[0]; |
|
|
|
return state->search->filenames[0]; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -310,10 +315,11 @@ public: |
|
|
|
{ |
|
|
|
{ |
|
|
|
CSearchState *state = GetSearchStateByHandle( handle ); |
|
|
|
CSearchState *state = GetSearchStateByHandle( handle ); |
|
|
|
|
|
|
|
|
|
|
|
if( !state ) return NULL; |
|
|
|
if( !state ) |
|
|
|
|
|
|
|
return nullptr; |
|
|
|
|
|
|
|
|
|
|
|
if( state->index + 1 >= state->search->numfilenames ) |
|
|
|
if( state->index + 1 >= state->search->numfilenames ) |
|
|
|
return NULL; |
|
|
|
return nullptr; |
|
|
|
|
|
|
|
|
|
|
|
return state->search->filenames[++state->index]; |
|
|
|
return state->search->filenames[++state->index]; |
|
|
|
} |
|
|
|
} |
|
|
@ -333,32 +339,35 @@ public: |
|
|
|
|
|
|
|
|
|
|
|
void FindClose( FileFindHandle_t handle ) override |
|
|
|
void FindClose( FileFindHandle_t handle ) override |
|
|
|
{ |
|
|
|
{ |
|
|
|
for( CSearchState *state = searchHead, **prev = NULL; |
|
|
|
CSearchState *prev; |
|
|
|
state; |
|
|
|
CSearchState *i; |
|
|
|
*prev = state, state = state->next ) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if( state->handle == handle ) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if( prev ) |
|
|
|
|
|
|
|
(*prev)->next = state->next; |
|
|
|
|
|
|
|
else searchHead = state->next; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
delete state; |
|
|
|
for( prev = nullptr, i = searchHead; |
|
|
|
|
|
|
|
i != nullptr && i->handle != handle; |
|
|
|
|
|
|
|
prev = i, i = i->next ); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if( i == nullptr ) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
Con_DPrintf( "FindClose: Can't find search state by handle %d\n", handle ); |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Con_DPrintf( "FindClose: Can't find search state by handle %d\n", handle ); |
|
|
|
if( prev != nullptr ) |
|
|
|
return; |
|
|
|
prev->next = i->next; |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
searchHead = i->next; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
delete i; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const char * GetLocalPath( const char *name, char *buf, int size ) override |
|
|
|
const char *GetLocalPath( const char *name, char *buf, int size ) override |
|
|
|
{ |
|
|
|
{ |
|
|
|
if( !name ) return NULL; |
|
|
|
const char *fullpath; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if( !name ) |
|
|
|
|
|
|
|
return nullptr; |
|
|
|
|
|
|
|
|
|
|
|
char *p = (char *)alloca( Q_strlen( name ) + 1 ); |
|
|
|
FixupPath( p, name ); |
|
|
|
CopyAndFixSlashes( p, name ); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if !XASH_WIN32 |
|
|
|
#if !XASH_WIN32 |
|
|
|
if( p[0] == '/' ) |
|
|
|
if( p[0] == '/' ) |
|
|
@ -371,9 +380,9 @@ public: |
|
|
|
return buf; |
|
|
|
return buf; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const char *fullpath = FS_GetDiskPath( p, false ); |
|
|
|
fullpath = FS_GetDiskPath( p, false ); |
|
|
|
if( !fullpath ) |
|
|
|
if( !fullpath ) |
|
|
|
return NULL; |
|
|
|
return nullptr; |
|
|
|
|
|
|
|
|
|
|
|
Q_strncpy( buf, fullpath, size ); |
|
|
|
Q_strncpy( buf, fullpath, size ); |
|
|
|
return buf; |
|
|
|
return buf; |
|
|
@ -382,24 +391,27 @@ public: |
|
|
|
char *ParseFile( char *buf, char *token, bool *quoted ) override |
|
|
|
char *ParseFile( char *buf, char *token, bool *quoted ) override |
|
|
|
{ |
|
|
|
{ |
|
|
|
qboolean qquoted; |
|
|
|
qboolean qquoted; |
|
|
|
|
|
|
|
char *p; |
|
|
|
|
|
|
|
|
|
|
|
char *p = COM_ParseFileSafe( buf, token, PFILE_FS_TOKEN_MAX_LENGTH, 0, NULL, &qquoted ); |
|
|
|
p = COM_ParseFileSafe( buf, token, PFILE_FS_TOKEN_MAX_LENGTH, 0, nullptr, &qquoted ); |
|
|
|
if( quoted ) *quoted = qquoted; |
|
|
|
|
|
|
|
|
|
|
|
if( quoted ) |
|
|
|
|
|
|
|
*quoted = qquoted; |
|
|
|
|
|
|
|
|
|
|
|
return p; |
|
|
|
return p; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool FullPathToRelativePath( const char *path, char *out ) override |
|
|
|
bool FullPathToRelativePath( const char *path, char *out ) override |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
searchpath_t *sp; |
|
|
|
|
|
|
|
|
|
|
|
if( !COM_CheckString( path )) |
|
|
|
if( !COM_CheckString( path )) |
|
|
|
{ |
|
|
|
{ |
|
|
|
*out = 0; |
|
|
|
*out = 0; |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
char *p = (char *)alloca( Q_strlen( path ) + 1 ); |
|
|
|
FixupPath( p, path ); |
|
|
|
CopyAndFixSlashes( p, path ); |
|
|
|
|
|
|
|
searchpath_t *sp; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for( sp = fs_searchpaths; sp; sp = sp->next ) |
|
|
|
for( sp = fs_searchpaths; sp; sp = sp->next ) |
|
|
|
{ |
|
|
|
{ |
|
|
@ -429,13 +441,13 @@ public: |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void SetWarningFunc(void (*)(const char *, ...)) override |
|
|
|
void SetWarningFunc( void (*)( const char *, ... )) override |
|
|
|
{ |
|
|
|
{ |
|
|
|
// TODO:
|
|
|
|
// TODO:
|
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void SetWarningLevel(FileWarningLevel_t) override |
|
|
|
void SetWarningLevel( FileWarningLevel_t ) override |
|
|
|
{ |
|
|
|
{ |
|
|
|
// TODO:
|
|
|
|
// TODO:
|
|
|
|
return; |
|
|
|
return; |
|
|
@ -447,7 +459,7 @@ public: |
|
|
|
return 0; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void GetInterfaceVersion(char *p, int size) override |
|
|
|
void GetInterfaceVersion( char *p, int size ) override |
|
|
|
{ |
|
|
|
{ |
|
|
|
Q_strncpy( p, "Stdio", size ); |
|
|
|
Q_strncpy( p, "Stdio", size ); |
|
|
|
} |
|
|
|
} |
|
|
@ -459,13 +471,12 @@ public: |
|
|
|
Q_snprintf( fullpath, sizeof( fullpath ), "%s/%s", IdToDir( dir, sizeof( dir ), id ), path ); |
|
|
|
Q_snprintf( fullpath, sizeof( fullpath ), "%s/%s", IdToDir( dir, sizeof( dir ), id ), path ); |
|
|
|
CopyAndFixSlashes( fullpath, path ); |
|
|
|
CopyAndFixSlashes( fullpath, path ); |
|
|
|
|
|
|
|
|
|
|
|
return !!FS_AddPak_Fullpath( fullpath, NULL, FS_CUSTOM_PATH ); |
|
|
|
return !!FS_AddPak_Fullpath( fullpath, nullptr, FS_CUSTOM_PATH ); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
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 |
|
|
|
{ |
|
|
|
{ |
|
|
|
char *p = (char *)alloca( Q_strlen( path ) + 1 ); |
|
|
|
FixupPath( p, path ); |
|
|
|
CopyAndFixSlashes( p, path ); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return FS_OpenReadFile( p, mode, IsIdGamedir( id )); |
|
|
|
return FS_OpenReadFile( p, mode, IsIdGamedir( id )); |
|
|
|
} |
|
|
|
} |
|
|
@ -473,20 +484,24 @@ public: |
|
|
|
// stubs
|
|
|
|
// stubs
|
|
|
|
void Mount() override {} |
|
|
|
void Mount() override {} |
|
|
|
void Unmount() override {} |
|
|
|
void Unmount() override {} |
|
|
|
void GetLocalCopy(const char *) override {} |
|
|
|
void GetLocalCopy( const char * ) override {} |
|
|
|
void LogLevelLoadStarted(const char *) override {} |
|
|
|
void LogLevelLoadStarted( const char * ) override {} |
|
|
|
void LogLevelLoadFinished(const char *) override {} |
|
|
|
void LogLevelLoadFinished( const char * ) override {} |
|
|
|
void CancelWaitForResources(WaitForResourcesHandle_t) override {} |
|
|
|
void CancelWaitForResources( WaitForResourcesHandle_t ) override {} |
|
|
|
int HintResourceNeed(const char *, int) override { return 0; } |
|
|
|
int HintResourceNeed( const char *, int ) override { return 0; } |
|
|
|
WaitForResourcesHandle_t WaitForResources(const char *) override { return 0; } |
|
|
|
WaitForResourcesHandle_t WaitForResources( const char * ) override { return 0; } |
|
|
|
int PauseResourcePreloading() override { return 0; } |
|
|
|
int PauseResourcePreloading() override { return 0; } |
|
|
|
int ResumeResourcePreloading() override { return 0; } |
|
|
|
int ResumeResourcePreloading() override { return 0; } |
|
|
|
bool IsAppReadyForOfflinePlay(int) override { return true; } |
|
|
|
bool IsAppReadyForOfflinePlay( int ) override { return true; } |
|
|
|
bool IsFileImmediatelyAvailable(const char *) override { return true; } |
|
|
|
bool IsFileImmediatelyAvailable( const char * ) override { return true; } |
|
|
|
bool GetWaitForResourcesProgress(WaitForResourcesHandle_t, float *pProgress, bool *pOverride) override |
|
|
|
bool GetWaitForResourcesProgress( WaitForResourcesHandle_t, float *pProgress, bool *pOverride ) override |
|
|
|
{ |
|
|
|
{ |
|
|
|
if( pProgress ) *pProgress = 0; |
|
|
|
if( pProgress ) |
|
|
|
if( pOverride ) *pOverride = true; |
|
|
|
*pProgress = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if( pOverride ) |
|
|
|
|
|
|
|
*pOverride = true; |
|
|
|
|
|
|
|
|
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
} g_VFileSystem009; |
|
|
|
} g_VFileSystem009; |
|
|
@ -495,22 +510,27 @@ extern "C" void EXPORT *CreateInterface( const char *interface, int *retval ) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if( !Q_strcmp( interface, "VFileSystem009" )) |
|
|
|
if( !Q_strcmp( interface, "VFileSystem009" )) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if( retval ) *retval = 0; |
|
|
|
if( retval ) |
|
|
|
|
|
|
|
*retval = 0; |
|
|
|
|
|
|
|
|
|
|
|
return &g_VFileSystem009; |
|
|
|
return &g_VFileSystem009; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if( !Q_strcmp( interface, FS_API_CREATEINTERFACE_TAG )) |
|
|
|
if( !Q_strcmp( interface, FS_API_CREATEINTERFACE_TAG )) |
|
|
|
{ |
|
|
|
{ |
|
|
|
// return a copy, to disallow overriding
|
|
|
|
static fs_api_t copy = { 0 }; // return a copy, to disallow overriding
|
|
|
|
static fs_api_t copy = { 0 }; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if( !copy.InitStdio ) |
|
|
|
if( !copy.InitStdio ) |
|
|
|
memcpy( ©, &g_api, sizeof( copy )); |
|
|
|
memcpy( ©, &g_api, sizeof( copy )); |
|
|
|
|
|
|
|
|
|
|
|
if( retval ) *retval = 0; |
|
|
|
if( retval ) |
|
|
|
|
|
|
|
*retval = 0; |
|
|
|
|
|
|
|
|
|
|
|
return © |
|
|
|
return © |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if( retval ) *retval = 1; |
|
|
|
if( retval ) |
|
|
|
return NULL; |
|
|
|
*retval = 1; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return nullptr; |
|
|
|
} |
|
|
|
} |
|
|
|