summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/snd_codec_ogg.c5
-rw-r--r--src/client/snd_codec_opus.c5
-rw-r--r--src/qcommon/files.c47
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;