Support FS_SEEK_END and negative offset for zipped files in FS_Seek

Use FS_SEEK_END in sound code instead of working around it.
If FS_SEEK_SET and going to current position, just return.
This commit is contained in:
Zack Middleton 2013-10-26 22:43:53 -05:00
parent c69db4a400
commit 2d45e57068
3 changed files with 40 additions and 17 deletions

View file

@ -157,11 +157,8 @@ int S_OGG_Callback_seek(void *datasource, ogg_int64_t offset, int whence)
case SEEK_END : 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 // 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 // something has gone wrong, so we return here
if(retVal < 0) if(retVal < 0)

View file

@ -146,11 +146,8 @@ int S_OggOpus_Callback_seek(void *datasource, opus_int64 offset, int whence)
case SEEK_END : 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 // 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 // something has gone wrong, so we return here
if(retVal < 0) if(retVal < 0)

View file

@ -277,6 +277,7 @@ typedef struct {
qboolean handleSync; qboolean handleSync;
int fileSize; int fileSize;
int zipFilePos; int zipFilePos;
int zipFileLen;
qboolean zipFile; qboolean zipFile;
qboolean streamed; qboolean streamed;
char name[MAX_ZPATH]; char name[MAX_ZPATH];
@ -1261,6 +1262,7 @@ long FS_FOpenFileReadDir(const char *filename, searchpath_t *search, fileHandle_
// open the file in the zip // open the file in the zip
unzOpenCurrentFile(fsh[*file].handleFiles.file.z); unzOpenCurrentFile(fsh[*file].handleFiles.file.z);
fsh[*file].zipFilePos = pakFile->pos; fsh[*file].zipFilePos = pakFile->pos;
fsh[*file].zipFileLen = pakFile->len;
if(fs_debug->integer) if(fs_debug->integer)
{ {
@ -1635,23 +1637,52 @@ int FS_Seek( fileHandle_t f, long offset, int origin ) {
} }
if (fsh[f].zipFile == qtrue) { if (fsh[f].zipFile == qtrue) {
//FIXME: this is incomplete and really, really //FIXME: this is really, really crappy
//crappy (but better than what was here before) //(but better than what was here before)
byte buffer[PK3_SEEK_BUFFER_SIZE]; byte buffer[PK3_SEEK_BUFFER_SIZE];
int remainder = offset; int remainder;
int currentPosition = FS_FTell( f );
if( offset < 0 || origin == FS_SEEK_END ) { // change negative offsets into FS_SEEK_SET
Com_Error( ERR_FATAL, "Negative offsets and FS_SEEK_END not implemented " if ( offset < 0 ) {
"for FS_Seek on pk3 file contents" ); switch( origin ) {
return -1; case FS_SEEK_END:
remainder = fsh[f].zipFileLen + offset;
break;
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 ) { switch( origin ) {
case FS_SEEK_SET: case FS_SEEK_SET:
if ( remainder == currentPosition ) {
return offset;
}
unzSetOffset(fsh[f].handleFiles.file.z, fsh[f].zipFilePos); unzSetOffset(fsh[f].handleFiles.file.z, fsh[f].zipFilePos);
unzOpenCurrentFile(fsh[f].handleFiles.file.z); unzOpenCurrentFile(fsh[f].handleFiles.file.z);
//fallthrough //fallthrough
case FS_SEEK_END:
case FS_SEEK_CUR: case FS_SEEK_CUR:
while( remainder > PK3_SEEK_BUFFER_SIZE ) { while( remainder > PK3_SEEK_BUFFER_SIZE ) {
FS_Read( buffer, PK3_SEEK_BUFFER_SIZE, f ); FS_Read( buffer, PK3_SEEK_BUFFER_SIZE, f );
@ -1659,12 +1690,10 @@ int FS_Seek( fileHandle_t f, long offset, int origin ) {
} }
FS_Read( buffer, remainder, f ); FS_Read( buffer, remainder, f );
return offset; return offset;
break;
default: default:
Com_Error( ERR_FATAL, "Bad origin in FS_Seek" ); Com_Error( ERR_FATAL, "Bad origin in FS_Seek" );
return -1; return -1;
break;
} }
} else { } else {
FILE *file; FILE *file;