diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/client/snd_codec_ogg.c | 5 | ||||
-rw-r--r-- | src/client/snd_codec_opus.c | 5 | ||||
-rw-r--r-- | src/qcommon/files.c | 47 |
3 files changed, 40 insertions, 17 deletions
diff --git a/src/client/snd_codec_ogg.c b/src/client/snd_codec_ogg.c index 882bfcb4..eb187be9 100644 --- a/src/client/snd_codec_ogg.c +++ b/src/client/snd_codec_ogg.c @@ -158,11 +158,8 @@ int S_OGG_Callback_seek(void *datasource, ogg_int64_t offset, int whence) case SEEK_END : { - // Quake 3 seems to have trouble with FS_SEEK_END - // so we use the file length and FS_SEEK_SET - // set the file position in the actual file with the Q3 function - retVal = FS_Seek(stream->file, (long) stream->length + (long) offset, FS_SEEK_SET); + retVal = FS_Seek(stream->file, (long) offset, FS_SEEK_END); // something has gone wrong, so we return here if(retVal < 0) diff --git a/src/client/snd_codec_opus.c b/src/client/snd_codec_opus.c index 190aee9a..b43dea44 100644 --- a/src/client/snd_codec_opus.c +++ b/src/client/snd_codec_opus.c @@ -146,11 +146,8 @@ int S_OggOpus_Callback_seek(void *datasource, opus_int64 offset, int whence) case SEEK_END : { - // Quake 3 seems to have trouble with FS_SEEK_END - // so we use the file length and FS_SEEK_SET - // set the file position in the actual file with the Q3 function - retVal = FS_Seek(stream->file, (long) stream->length + (long) offset, FS_SEEK_SET); + retVal = FS_Seek(stream->file, (long) offset, FS_SEEK_END); // something has gone wrong, so we return here if(retVal < 0) 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; |