From f7f96e3c8515d8ff1864c4705e129da063f325bc Mon Sep 17 00:00:00 2001 From: Marcel Bierling Date: Wed, 9 Sep 2026 22:43:53 +0200 Subject: [PATCH 1/2] Give the VQA IO commands a type of their own --- code/vqalib/vqaplay.h | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/code/vqalib/vqaplay.h b/code/vqalib/vqaplay.h index 268e7fb24..06f9d9577 100644 --- a/code/vqalib/vqaplay.h +++ b/code/vqalib/vqaplay.h @@ -355,16 +355,18 @@ typedef struct _VQAHandle { // derives from AMIGA IFF handling https://wiki.amigaos.net/wiki/IFFParse_Library /* Possible IO command values */ -#define VQACMD_NOTHING 0 -#define VQACMD_INIT 1 /* Prepare the IO for a session */ -#define VQACMD_CLEANUP 2 /* Terminate IO session */ -#define VQACMD_OPEN 3 /* Open file */ -#define VQACMD_CLOSE 4 /* Close file */ -#define VQACMD_READ 5 /* Read bytes */ -#define VQACMD_WRITE 6 /* Write bytes */ -#define VQACMD_SEEK 7 /* Seek */ -#define VQACMD_SEEKPEEK 8 -#define VQACMD_SIZE 9 +enum VQACommandType : int32_t { + VQACMD_NOTHING = 0, + VQACMD_INIT = 1, /* Prepare the IO for a session */ + VQACMD_CLEANUP = 2, /* Terminate IO session */ + VQACMD_OPEN = 3, /* Open file */ + VQACMD_CLOSE = 4, /* Close file */ + VQACMD_READ = 5, /* Read bytes */ + VQACMD_WRITE = 6, /* Write bytes */ + VQACMD_SEEK = 7, /* Seek */ + VQACMD_SEEKPEEK = 8, + VQACMD_SIZE = 9 +}; #define VQAMEM_0 0 #define VQAMEM_1 1 From 2f4e4d8ff979fa65bdd1acb16ddc909d9fdf35df Mon Sep 17 00:00:00 2001 From: Marcel Bierling Date: Wed, 9 Sep 2026 22:44:08 +0200 Subject: [PATCH 2/2] Make the seek origin part of the seek command --- code/vqa.cpp | 76 ++++++++++++++++++++++------------------- code/vqalib/dstream.cpp | 65 ++++++++++++++++++----------------- code/vqalib/loader.cpp | 24 ++++++------- code/vqalib/task.cpp | 6 ++-- code/vqalib/vqaplay.h | 8 +++-- 5 files changed, 95 insertions(+), 84 deletions(-) diff --git a/code/vqa.cpp b/code/vqa.cpp index bb892ddd4..66a9c2752 100644 --- a/code/vqa.cpp +++ b/code/vqa.cpp @@ -298,25 +298,19 @@ long VQAClass::CacheHandler(long action, void * buffer, long nbytes) } break; - case VQACMD_SEEK: - switch ((int)(intptr_t)buffer) { - case 1: - Cache.file_buffer_pos += nbytes; - rc = 0; - break; - case 0: - Cache.file_buffer_pos = nbytes; - rc = 0; - break; - case 2: - Cache.file_buffer_pos = Cache.file_size - nbytes - 1; - rc = 0; - break; - - default: - rc = 1; - break; - } + case VQACMD_SEEK_CUR: + Cache.file_buffer_pos += nbytes; + rc = 0; + break; + + case VQACMD_SEEK_SET: + Cache.file_buffer_pos = nbytes; + rc = 0; + break; + + case VQACMD_SEEK_END: + Cache.file_buffer_pos = Cache.file_size - nbytes - 1; + rc = 0; break; @@ -846,26 +840,32 @@ long VQAClass::CCFileHandler(long action, void * buffer, long nbytes) break; /* - ** VQACMD_SEEK asks that you perform a seek relative to the current - ** position. NBytes is a signed number, indicating seek direction - ** (positive for forward, negative for backward). Buffer has no meaning - ** here. + ** The seek commands each name their own origin, and NBytes is the offset + ** from it, signed for VQACMD_SEEK_CUR. Buffer has no meaning here. ** ** Any error code returned will be remapped by VQA library into ** VQAERR_SEEK. */ - case VQACMD_SEEK: - error = (FileHandle.Seek(nbytes, (int)(intptr_t)buffer) == 0); + case VQACMD_SEEK_SET: + error = (FileHandle.Seek(nbytes, SEEK_SET) == 0); + break; + + case VQACMD_SEEK_CUR: + error = (FileHandle.Seek(nbytes, SEEK_CUR) == 0); + break; + + case VQACMD_SEEK_END: + error = (FileHandle.Seek(nbytes, SEEK_END) == 0); break; case VQACMD_SEEKPEEK: if (nbytes > 0) { - error = FileHandle.Seek(nbytes - sizeof(tmp), (int)(intptr_t)buffer) == 0; + error = FileHandle.Seek(nbytes - sizeof(tmp), SEEK_SET) == 0; if (error == 0) { error = FileHandle.Read(&tmp, sizeof(tmp)) != sizeof(tmp); } } else { - error = FileHandle.Seek(nbytes, (int)(intptr_t)buffer) == 0; + error = FileHandle.Seek(nbytes, SEEK_SET) == 0; if (error == 0) { error = FileHandle.Read(&tmp, sizeof(tmp)) != sizeof(tmp); if (error == 0) { @@ -973,26 +973,32 @@ long VQAClass::MixFileHandler(long action, void * buffer, long nbytes) break; /* - ** VQACMD_SEEK asks that you perform a seek relative to the current - ** position. NBytes is a signed number, indicating seek direction - ** (positive for forward, negative for backward). Buffer has no meaning - ** here. + ** The seek commands each name their own origin, and NBytes is the offset + ** from it, signed for VQACMD_SEEK_CUR. Buffer has no meaning here. ** ** Any error code returned will be remapped by VQA library into ** VQAERR_SEEK. */ - case VQACMD_SEEK: - error = (FileHandle.Seek(nbytes, (int)(intptr_t)buffer) == 0); + case VQACMD_SEEK_SET: + error = (FileHandle.Seek(nbytes, SEEK_SET) == 0); + break; + + case VQACMD_SEEK_CUR: + error = (FileHandle.Seek(nbytes, SEEK_CUR) == 0); + break; + + case VQACMD_SEEK_END: + error = (FileHandle.Seek(nbytes, SEEK_END) == 0); break; case VQACMD_SEEKPEEK: if (nbytes > 0) { - error = FileHandle.Seek(nbytes - sizeof(tmp), (int)(intptr_t)buffer) == 0; + error = FileHandle.Seek(nbytes - sizeof(tmp), SEEK_SET) == 0; if (error == 0) { error = FileHandle.Read(&tmp, sizeof(tmp)) != sizeof(tmp); } } else { - error = FileHandle.Seek(nbytes, (int)(intptr_t)buffer) == 0; + error = FileHandle.Seek(nbytes, SEEK_SET) == 0; if (error == 0) { error = FileHandle.Read(&tmp, sizeof(tmp)) != sizeof(tmp); if (error == 0) { diff --git a/code/vqalib/dstream.cpp b/code/vqalib/dstream.cpp index 456462e0f..ce673874a 100644 --- a/code/vqalib/dstream.cpp +++ b/code/vqalib/dstream.cpp @@ -89,31 +89,37 @@ intptr_t __cdecl Disk_VQA_Stream_Handler(VQAHandle *vqa, long action, void *buff error = 1; break; - /* VQACMD_SEEK asks that you perform a seek relative to the current - * position. NBytes is a signed number, indicating seek direction - * (positive for forward, negative for backward). Buffer has no meaning - * here. + /* The seek commands each name their own origin, and NBytes is the offset + * from it, signed for VQACMD_SEEK_CUR. Buffer has no meaning here. * * Any error code returned will be remapped by VQA library into * VQAERR_SEEK. */ - case VQACMD_SEEK: - error = (lseek(fh, nbytes, (int)(intptr_t)buffer) == -1); + case VQACMD_SEEK_SET: + error = (lseek(fh, nbytes, SEEK_SET) == -1); + break; + + case VQACMD_SEEK_CUR: + error = (lseek(fh, nbytes, SEEK_CUR) == -1); + break; + + case VQACMD_SEEK_END: + error = (lseek(fh, nbytes, SEEK_END) == -1); break; case VQACMD_SEEKPEEK: if (nbytes > 0) { - error = lseek(fh, nbytes - 1, (int)(intptr_t)buffer) == -1; + error = lseek(fh, nbytes - 1, SEEK_SET) == -1; if (error == 0) { error = read(fh, &temp, 1) != 1; } } else { - error = lseek(fh, nbytes, (int)(intptr_t)buffer) == -1; + error = lseek(fh, nbytes, SEEK_SET) == -1; if (error == 0) { error = read(fh, &temp, 1) != 1; } if (error == 0) { - error = lseek(fh, -1, 1) == -1; + error = lseek(fh, -1, SEEK_CUR) == -1; } } break; @@ -186,34 +192,31 @@ intptr_t __cdecl Memory_VQA_Stream_Handler(VQAHandle *vqa, long action, void *bu error = 1; break; - /* VQACMD_SEEK asks that you perform a seek relative to the current - * position. NBytes is a signed number, indicating seek direction - * (positive for forward, negative for backward). Buffer has no meaning - * here. + /* The seek commands each name their own origin, and NBytes is the offset + * from it, signed for VQACMD_SEEK_CUR. VQACMD_SEEKPEEK seeks as + * VQACMD_SEEK_SET does. Buffer has no meaning here. The loop cache holds + * one span of the file, so it cannot seek from the end. * * Any error code returned will be remapped by VQA library into * VQAERR_SEEK. */ - case VQACMD_SEEK: + case VQACMD_SEEK_CUR: + cache->Offset += nbytes; + error = 0; + break; + + case VQACMD_SEEK_SET: case VQACMD_SEEKPEEK: - switch ((intptr_t)buffer) { - - case 1: - cache->Offset += nbytes; - error = 0; - break; - - case 0: - p = cache->FileOffset; - if (nbytes >= p) { - cache->Offset = nbytes - p; - break; - } - - default: - error = 1; - break; + p = cache->FileOffset; + if (nbytes >= p) { + cache->Offset = nbytes - p; + break; } + error = 1; + break; + + case VQACMD_SEEK_END: + error = 1; break; case VQACMD_SIZE: diff --git a/code/vqalib/loader.cpp b/code/vqalib/loader.cpp index 63200ec69..9c443fe0e 100644 --- a/code/vqalib/loader.cpp +++ b/code/vqalib/loader.cpp @@ -260,7 +260,7 @@ long VQA_LoadFrame(VQAHandleP *vqap, long flags) if (tocache > 0) { if (config->StreamHandler != Memory_VQA_Stream_Handler) { - config->StreamHandler((VQAHandle *)vqap, VQACMD_SEEK, NULL, foffset); + config->StreamHandler((VQAHandle *)vqap, VQACMD_SEEK_SET, NULL, foffset); } if (config->StreamHandler((VQAHandle *)vqap, VQACMD_READ, &cache->Ptr[cache->Offset], tocache)) { return -4; @@ -827,7 +827,7 @@ long VQA_LoadFrame_Internal(VQAHandleP *vqap, long flags) /* fall through to the generic skip. */ if (skip == true) { - if (config->StreamHandler((VQAHandle *)vqap, VQACMD_SEEK, (void *)SEEK_CUR, PADSIZE(iffsize))) { + if (config->StreamHandler((VQAHandle *)vqap, VQACMD_SEEK_CUR, NULL, PADSIZE(iffsize))) { return(VQAERR_SEEK); } } @@ -1074,7 +1074,7 @@ long VQA_SeekLoop(VQAHandleP *vqap, long framenum, long flags) needs_seek = true; } cache->Offset = 0; - } else if (vqap->Config.StreamHandler((VQAHandle *)vqap, VQACMD_SEEK, 0, VQAFRAME_OFFSET(foff[framenum])) != 0) { + } else if (vqap->Config.StreamHandler((VQAHandle *)vqap, VQACMD_SEEK_SET, NULL, VQAFRAME_OFFSET(foff[framenum])) != 0) { return(VQAERR_SEEK); } @@ -1083,7 +1083,7 @@ long VQA_SeekLoop(VQAHandleP *vqap, long framenum, long flags) } if (rc == VQAERR_NONE) { - if (needs_seek && vqap->Config.StreamHandler((VQAHandle *)vqap, VQACMD_SEEKPEEK, 0, cache->FileOffset + cache->Bytes) != 0) { + if (needs_seek && vqap->Config.StreamHandler((VQAHandle *)vqap, VQACMD_SEEKPEEK, NULL, cache->FileOffset + cache->Bytes) != 0) { return(VQAERR_SEEK); } } @@ -1215,7 +1215,7 @@ long VQA_ReloadPalette(VQAHandleP *vqap, long framenum, int force) if (pal_frame >= 0 ) { - if (!config->StreamHandler((VQAHandle *)vqap, VQACMD_SEEK, (void *)SEEK_SET, VQAFRAME_OFFSET(vqap->Foff[pal_frame]))) { + if (!config->StreamHandler((VQAHandle *)vqap, VQACMD_SEEK_SET, NULL, VQAFRAME_OFFSET(vqap->Foff[pal_frame]))) { if (force) { loader->NumPartialCB = 0; @@ -1462,7 +1462,7 @@ long VQA_SeekGroup(VQAHandleP *vqap, long framenum, long groupsize, VQABool prel /* Seek to the start of the group containing the partial codebooks for * the target frame. */ - if (!config->StreamHandler((VQAHandle *)vqap, VQACMD_SEEK, (void *)SEEK_SET, VQAFRAME_OFFSET(vqap->Foff[group]))) { + if (!config->StreamHandler((VQAHandle *)vqap, VQACMD_SEEK_SET, NULL, VQAFRAME_OFFSET(vqap->Foff[group]))) { loader->CurFrameNum = group; rc = -1; @@ -1826,7 +1826,7 @@ long Load_VQF(VQAHandleP *vqap, unsigned long frame_iffsize, char flags) /* Skip any unknown chunks. */ if (skip == true) { - if (vqap->Config.StreamHandler((VQAHandle *)vqap, VQACMD_SEEK, (void *)1, PADSIZE(iffsize))) { + if (vqap->Config.StreamHandler((VQAHandle *)vqap, VQACMD_SEEK_CUR, NULL, PADSIZE(iffsize))) { return(VQAERR_SEEK); } } @@ -2588,7 +2588,7 @@ long Load_FINF(VQAHandleP *vqap, unsigned long iffsize) return(VQAERR_READ); } } else { - if (vqap->Config.StreamHandler((VQAHandle *)vqap, VQACMD_SEEK, (void *)SEEK_CUR, + if (vqap->Config.StreamHandler((VQAHandle *)vqap, VQACMD_SEEK_CUR, NULL, PADSIZE(iffsize))) { return(VQAERR_SEEK); } @@ -3223,7 +3223,7 @@ long Load_SND0(VQAHandleP *vqap, unsigned long iffsize) || (audio->Buffer == NULL)) { #endif /* VQAVOC_ON */ - if (config->StreamHandler((VQAHandle *)vqap, VQACMD_SEEK, (void *)SEEK_CUR, + if (config->StreamHandler((VQAHandle *)vqap, VQACMD_SEEK_CUR, NULL, padsize)) { return(VQAERR_SEEK); } else { @@ -3324,7 +3324,7 @@ long Load_SND1(VQAHandleP *vqap, unsigned long iffsize) || (audio->Buffer == NULL)) { #endif /* VQAVOC_ON */ - if (config->StreamHandler((VQAHandle *)vqap, VQACMD_SEEK, (void *)SEEK_CUR, + if (config->StreamHandler((VQAHandle *)vqap, VQACMD_SEEK_CUR, NULL, padsize)) { return(VQAERR_SEEK); } else { @@ -3455,7 +3455,7 @@ long Load_SND2(VQAHandleP *vqap, unsigned long iffsize) || (audio->Buffer == NULL)) { #endif /* VQAVOC_ON */ - if (config->StreamHandler((VQAHandle *)vqap, VQACMD_SEEK, (void *)SEEK_CUR, + if (config->StreamHandler((VQAHandle *)vqap, VQACMD_SEEK_CUR, NULL, padsize)) { return(VQAERR_SEEK); } else { @@ -3540,7 +3540,7 @@ long Load_SN2J(VQAHandleP *vqap, unsigned long iffsize) || (audio->Buffer == NULL)) { #endif /* VQAVOC_ON */ - if (config->StreamHandler((VQAHandle *)vqap, VQACMD_SEEK, (void *)SEEK_CUR, + if (config->StreamHandler((VQAHandle *)vqap, VQACMD_SEEK_CUR, NULL, padsize)) { return(VQAERR_SEEK); } diff --git a/code/vqalib/task.cpp b/code/vqalib/task.cpp index e617216cd..53014ea8a 100644 --- a/code/vqalib/task.cpp +++ b/code/vqalib/task.cpp @@ -372,7 +372,7 @@ long VQA_Open(char const *filename, VQAConfig *_config, VQAHandle **handle) } } else { - if (vqap->IOHandler(vqa, VQACMD_SEEK, (void *)SEEK_CUR, + if (vqap->IOHandler(vqa, VQACMD_SEEK_CUR, NULL, PADSIZE(chunk.size))) { VQA_Close(vqa); return(VQAERR_SEEK); @@ -420,7 +420,7 @@ long VQA_Open(char const *filename, VQAConfig *_config, VQAHandle **handle) } } else { - if (vqap->IOHandler(vqa, VQACMD_SEEK, (void *)SEEK_CUR, + if (vqap->IOHandler(vqa, VQACMD_SEEK_CUR, NULL, PADSIZE(chunk.size))) { VQA_Close(vqa); return(VQAERR_SEEK); @@ -496,7 +496,7 @@ long VQA_Open(char const *filename, VQAConfig *_config, VQAHandle **handle) break; default: - if (config->StreamHandler(vqa, VQACMD_SEEK, (void *)SEEK_CUR, + if (config->StreamHandler(vqa, VQACMD_SEEK_CUR, NULL, PADSIZE(chunk.size))) { VQA_Close(vqa); return(VQAERR_SEEK); diff --git a/code/vqalib/vqaplay.h b/code/vqalib/vqaplay.h index 06f9d9577..47e1c6c14 100644 --- a/code/vqalib/vqaplay.h +++ b/code/vqalib/vqaplay.h @@ -363,9 +363,11 @@ enum VQACommandType : int32_t { VQACMD_CLOSE = 4, /* Close file */ VQACMD_READ = 5, /* Read bytes */ VQACMD_WRITE = 6, /* Write bytes */ - VQACMD_SEEK = 7, /* Seek */ - VQACMD_SEEKPEEK = 8, - VQACMD_SIZE = 9 + VQACMD_SEEK_SET = 7, /* Seek to an offset from the start of the stream */ + VQACMD_SEEKPEEK = 8, /* Fail unless the stream reaches NBytes */ + VQACMD_SIZE = 9, + VQACMD_SEEK_CUR = 10, /* Seek to a signed offset from the current position */ + VQACMD_SEEK_END = 11 /* Seek relative to the end of the stream */ }; #define VQAMEM_0 0