summaryrefslogtreecommitdiff
path: root/source/files.c
diff options
context:
space:
mode:
authorAndrey Nazarov <skuller@skuller.net>2007-12-02 09:31:05 +0000
committerAndrey Nazarov <skuller@skuller.net>2007-12-02 09:31:05 +0000
commite73c5000d53a37a1700862d270ea78723afec686 (patch)
tree0d823640807749420106e1af167c4ec56b40bccd /source/files.c
parent59182dc7d73461ed0da66cf903eba0af9c890f9e (diff)
Finally fixed pak loading order on Windows.
Minimize probability of prediction misses to be counted as ladder steps. Make sure Q_vnsprintf always returns length in range [0, destsize - 1].
Diffstat (limited to 'source/files.c')
-rw-r--r--source/files.c124
1 files changed, 60 insertions, 64 deletions
diff --git a/source/files.c b/source/files.c
index ff24498..6520f2e 100644
--- a/source/files.c
+++ b/source/files.c
@@ -31,8 +31,9 @@ QUAKE FILESYSTEM
- transparently merged from several sources
- relative to the single virtual root
-- case insensitive, at least at pakfiles level
-- only '/' separators supported
+- case insensitive at pakfiles level,
+ but may be case sensitive at host OS level
+- uses / as path separators internally
=============================================================================
*/
@@ -43,10 +44,13 @@ QUAKE FILESYSTEM
#define FS_Malloc( size ) Z_TagMalloc( size, TAG_FILESYSTEM )
#define FS_CopyString( string ) Z_TagCopyString( string, TAG_FILESYSTEM )
+// macros for dealing portably with files at OS level
#ifdef _WIN32
-#define FS_strcmp Q_stricmp
+#define FS_strcmp Q_strcasecmp
+#define FS_strncmp Q_strncasecmp
#else
#define FS_strcmp strcmp
+#define FS_strncmp strncmp
#endif
#define MAX_READ 0x40000 // read in blocks of 256k
@@ -134,8 +138,6 @@ cvar_t *fs_game;
fsAPI_t fs;
-void FS_AddGameDirectory( const char *fmt, ... ) q_printf( 1, 2 );
-
/*
All of Quake's data access is through a hierchal file system,
@@ -239,7 +241,7 @@ qboolean FS_ValidatePath( const char *s ) {
if( back > 1 ) {
return qfalse;
}
- back++;
+ back++; // allow one level back
}
if( *s == '/' || *s == '\\' ) {
// check for two slashes in a row
@@ -270,6 +272,7 @@ qboolean FS_ValidatePath( const char *s ) {
FS_ConvertToSysPath
================
*/
+#if 0
static char *FS_ConvertToSysPath( char *path ) {
char *s;
@@ -282,9 +285,29 @@ static char *FS_ConvertToSysPath( char *path ) {
}
return path;
+}
+#endif
+
+/*
+================
+FS_ReplaceSeparators
+================
+*/
+char *FS_ReplaceSeparators( char *s, int separator ) {
+ char *p;
+
+ p = s;
+ while( *p ) {
+ if( *p == '/' || *p == '\\' ) {
+ *p = separator;
+ }
+ p++;
+ }
+ return s;
}
+
/*
================
FS_GetFileLength
@@ -358,7 +381,7 @@ const char *FS_GetFileFullPath( fileHandle_t f ) {
FS_CreatePath
Creates any directories needed to store the given filename.
-Expects a fully qualified path.
+Expects a fully qualified quake path (i.e. with / separators).
============
*/
void FS_CreatePath( const char *path ) {
@@ -366,16 +389,16 @@ void FS_CreatePath( const char *path ) {
char *ofs;
Q_strncpyz( buffer, path, sizeof( buffer ) );
- FS_ConvertToSysPath( buffer );
+ //FS_ConvertToSysPath( buffer );
FS_DPrintf( "%s: %s\n", __func__, buffer );
for( ofs = buffer + 1; *ofs; ofs++ ) {
- if( *ofs == PATH_SEP_CHAR ) {
+ if( *ofs == '/' ) {
// create the directory
*ofs = 0;
Sys_Mkdir( buffer );
- *ofs = PATH_SEP_CHAR;
+ *ofs = '/';
}
}
}
@@ -415,7 +438,8 @@ void FS_FCloseFile( fileHandle_t f ) {
break;
}
- /* don't clear name and mode, so post-restart reopening works */
+ // don't clear name and mode, in case
+ // this handle will be reopened later
file->type = FS_FREE;
file->fp = NULL;
#if USE_ZLIB
@@ -472,7 +496,7 @@ static int FS_FOpenFileWrite( fsFile_t *file, const char *name ) {
break;
}
- FS_ConvertToSysPath( file->fullpath );
+ //FS_ConvertToSysPath( file->fullpath );
FS_CreatePath( file->fullpath );
@@ -639,7 +663,7 @@ static int FS_FOpenFileRead( fsFile_t *file, const char *name, qboolean unique )
Q_concat( file->fullpath, sizeof( file->fullpath ),
search->filename, "/", name, NULL );
- FS_ConvertToSysPath( file->fullpath );
+ //FS_ConvertToSysPath( file->fullpath );
fs_count_open++;
fp = fopen( file->fullpath, "rb" );
@@ -1169,7 +1193,7 @@ qboolean FS_RemoveFile( const char *filename ) {
}
Q_concat( path, sizeof( path ), fs_gamedir, "/", filename, NULL );
- FS_ConvertToSysPath( path );
+ //FS_ConvertToSysPath( path );
if( !Sys_RemoveFile( path ) ) {
return qfalse;
@@ -1188,18 +1212,18 @@ qboolean FS_RenameFile( const char *from, const char *to ) {
char topath[MAX_OSPATH];
if( !FS_ValidatePath( from ) || !FS_ValidatePath( to ) ) {
- FS_DPrintf( "FS_RenameFile: %s, %s: refusing invalid path\n", from, to );
+ FS_DPrintf( "FS_RenameFile: refusing invalid path: %s to %s\n", from, to );
return qfalse;
}
Q_concat( frompath, sizeof( frompath ), fs_gamedir, "/", from, NULL );
Q_concat( topath, sizeof( topath ), fs_gamedir, "/", to, NULL );
- FS_ConvertToSysPath( frompath );
- FS_ConvertToSysPath( topath );
+// FS_ConvertToSysPath( frompath );
+// FS_ConvertToSysPath( topath );
if( !Sys_RenameFile( frompath, topath ) ) {
- FS_DPrintf( "FS_RenameFile: Sys_RenameFile( '%s', '%s' ) failed\n", frompath, topath );
+ FS_DPrintf( "FS_RenameFile: rename failed: %s to %s\n", frompath, topath );
return qfalse;
}
@@ -1460,12 +1484,15 @@ fail:
}
#endif
+// this is complicated as we need pakXX.pak loaded first,
+// sorted in numerical order, then the rest of the paks in
+// alphabetical order, e.g. pak0.pak, pak2.pak, pak17.pak, abc.pak...
static int QDECL pakcmp( const void *p1, const void *p2 ) {
char *s1 = *( char ** )p1;
char *s2 = *( char ** )p2;
- if( !strncmp( s1, "pak", 3 ) ) {
- if( !strncmp( s2, "pak", 3 ) ) {
+ if( !FS_strncmp( s1, "pak", 3 ) ) {
+ if( !FS_strncmp( s2, "pak", 3 ) ) {
int n1 = strtoul( s1 + 3, &s1, 10 );
int n2 = strtoul( s2 + 3, &s2, 10 );
if( n1 > n2 ) {
@@ -1478,12 +1505,12 @@ static int QDECL pakcmp( const void *p1, const void *p2 ) {
}
return -1;
}
- if( !strncmp( s2, "pak", 3 ) ) {
+ if( !FS_strncmp( s2, "pak", 3 ) ) {
return 1;
}
alphacmp:
- return strcmp( s1, s2 );
+ return FS_strcmp( s1, s2 );
}
static void FS_LoadPackFiles( const char *extension, pack_t *(loadfunc)( const char * ) ) {
@@ -1523,7 +1550,7 @@ Sets fs_gamedir, adds the directory to the head of the path,
then loads and adds pak*.pak, then anything else in alphabethical order.
================
*/
-void FS_AddGameDirectory( const char *fmt, ... ) {
+static void q_printf( 1, 2 ) FS_AddGameDirectory( const char *fmt, ... ) {
va_list argptr;
searchpath_t *search;
int length;
@@ -1533,7 +1560,7 @@ void FS_AddGameDirectory( const char *fmt, ... ) {
va_end( argptr );
#ifdef _WIN32
- Com_ReplaceSeparators( fs_gamedir, '/' );
+ FS_ReplaceSeparators( fs_gamedir, '/' );
#endif
//
@@ -1922,6 +1949,7 @@ char **FS_ListFiles( const char *path, const char *extension,
// remove duplicates
total = 1;
for( i = 1; i < count; i++ ) {
+ // FIXME: use Q_stricmp instead of FS_strcmp here?
if( !FS_strcmp( listedFiles[ i - 1 ], listedFiles[i] ) ) {
Z_Free( listedFiles[ i - 1 ] );
listedFiles[i-1] = NULL;
@@ -2070,7 +2098,7 @@ static void FS_WhereIs_f( void ) {
int total;
if( Cmd_Argc() < 2 ) {
- Com_Printf( "Usage: %s <path>\n", Cmd_Argv( 0 ) );
+ Com_Printf( "Usage: %s <path> [all]\n", Cmd_Argv( 0 ) );
return;
}
@@ -2094,19 +2122,23 @@ static void FS_WhereIs_f( void ) {
if( !Q_stricmp( entry->name, path ) ) {
Com_Printf( "%s/%s (%d bytes)\n", pak->filename,
path, entry->filelen );
+ if( Cmd_Argc() < 3 ) {
+ return;
+ }
total++;
- // return;
}
}
} else {
Q_concat( fullpath, sizeof( fullpath ),
search->filename, "/", path, NULL );
- FS_ConvertToSysPath( fullpath );
+ //FS_ConvertToSysPath( fullpath );
if( Sys_GetFileInfo( fullpath, &info ) ) {
Com_Printf( "%s/%s (%d bytes)\n", search->filename, filename,
info.fileSize );
+ if( Cmd_Argc() < 3 ) {
+ return;
+ }
total++;
- // return;
}
}
@@ -2329,42 +2361,6 @@ static void FS_Link_f( void ) {
l->targetLength = strlen( target );
}
-/*
-================
-FS_NextPath
-
-Allows enumerating all of the directories in the search path
-================
-*/
-char *FS_NextPath( char *prevpath ) {
- searchpath_t *s;
- char *prev;
-
- prev = NULL;
- for( s = fs_searchpaths; s; s = s->next ) {
- if( s->pack )
- continue;
- if( prevpath == prev )
- return s->filename;
- prev = s->filename;
- }
-
- return NULL;
-}
-
-
-
-/*
-============
-FS_Gamedir
-
-Called to find where to write a file (demos, savegames, etc)
-============
-*/
-char *FS_Gamedir( void ) {
- return fs_gamedir;
-}
-
static void FS_FreeSearchPath( searchpath_t *path ) {
pack_t *pak;