diff options
Diffstat (limited to 'src/qcommon/files.c')
-rw-r--r-- | src/qcommon/files.c | 47 |
1 files changed, 38 insertions, 9 deletions
diff --git a/src/qcommon/files.c b/src/qcommon/files.c index 8d9d832d..67c891e4 100644 --- a/src/qcommon/files.c +++ b/src/qcommon/files.c @@ -255,6 +255,7 @@ typedef struct { qboolean handleSync; int fileSize; int zipFilePos; + int zipFileLen; qboolean zipFile; qboolean streamed; char name[MAX_ZPATH]; @@ -1223,6 +1224,7 @@ long FS_FOpenFileReadDir(const char *filename, searchpath_t *search, fileHandle_ // open the file in the zip unzOpenCurrentFile(fsh[*file].handleFiles.file.z); fsh[*file].zipFilePos = pakFile->pos; + fsh[*file].zipFileLen = pakFile->len; if(fs_debug->integer) { @@ -1597,23 +1599,52 @@ int FS_Seek( fileHandle_t f, long offset, int origin ) { } if (fsh[f].zipFile == qtrue) { - //FIXME: this is incomplete and really, really - //crappy (but better than what was here before) + //FIXME: this is really, really crappy + //(but better than what was here before) byte buffer[PK3_SEEK_BUFFER_SIZE]; - int remainder = offset; + int remainder; + int currentPosition = FS_FTell( f ); + + // change negative offsets into FS_SEEK_SET + if ( offset < 0 ) { + switch( origin ) { + case FS_SEEK_END: + remainder = fsh[f].zipFileLen + offset; + break; - if( offset < 0 || origin == FS_SEEK_END ) { - Com_Error( ERR_FATAL, "Negative offsets and FS_SEEK_END not implemented " - "for FS_Seek on pk3 file contents" ); - return -1; + case FS_SEEK_CUR: + remainder = currentPosition + offset; + break; + + case FS_SEEK_SET: + default: + remainder = 0; + break; + } + + if ( remainder < 0 ) { + remainder = 0; + } + + origin = FS_SEEK_SET; + } else { + if ( origin == FS_SEEK_END ) { + remainder = fsh[f].zipFileLen - currentPosition + offset; + } else { + remainder = offset; + } } switch( origin ) { case FS_SEEK_SET: + if ( remainder == currentPosition ) { + return offset; + } unzSetOffset(fsh[f].handleFiles.file.z, fsh[f].zipFilePos); unzOpenCurrentFile(fsh[f].handleFiles.file.z); //fallthrough + case FS_SEEK_END: case FS_SEEK_CUR: while( remainder > PK3_SEEK_BUFFER_SIZE ) { FS_Read( buffer, PK3_SEEK_BUFFER_SIZE, f ); @@ -1621,12 +1652,10 @@ int FS_Seek( fileHandle_t f, long offset, int origin ) { } FS_Read( buffer, remainder, f ); return offset; - break; default: Com_Error( ERR_FATAL, "Bad origin in FS_Seek" ); return -1; - break; } } else { FILE *file; |