[Scummvm-git-logs] scummvm master -> 0ad54bf79ef8efe3138ecaf047b00f3cb7b678e9
bluegr
noreply at scummvm.org
Sat Nov 22 10:05:35 UTC 2025
This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
fd758fd255 GROOVIE: Avoid crash in Clandestiny finale video
0ad54bf79e GROOVIE: Use camelcase for blockHeaderType variable and parameter
Commit: fd758fd255844ef3c2dc2db04d8bec4a99d1473b
https://github.com/scummvm/scummvm/commit/fd758fd255844ef3c2dc2db04d8bec4a99d1473b
Author: antoniou79 (a.antoniou79 at gmail.com)
Date: 2025-11-22T12:05:30+02:00
Commit Message:
GROOVIE: Avoid crash in Clandestiny finale video
This fixes bug #15086
If a faulty block is processed (in ROQPlayer::processBlock()) and we end up at a different file position (currFilePos) than the one calculated (endPos) based on its block header "size" value, and if currFilePos < endPos, first check the header of the next block at currFilePos for a known/valid type. If the next block has no known type, then go at the endPos instead and check there for a valid header type of the next block. If that is of a known type, continue from there (this is the case with the faulty block in the finale video of Clandestiny). Otherwise, go back to currFilePos and try your luck from there (this was the previous behavior here).
In the reported case, which maybe unique, the type of the fault block is 0x1002 (Quad codebook).
This fix still results in a corrupted frame, but that seems to match the original behavior (based on watching old youtube playthroughs).
Changed paths:
engines/groovie/video/roq.cpp
engines/groovie/video/roq.h
diff --git a/engines/groovie/video/roq.cpp b/engines/groovie/video/roq.cpp
index b92a72d5b84..50467905ef3 100644
--- a/engines/groovie/video/roq.cpp
+++ b/engines/groovie/video/roq.cpp
@@ -545,6 +545,21 @@ bool ROQPlayer::readBlockHeader(ROQBlockHeader &blockHeader) {
}
}
+bool ROQPlayer::isValidBlockHeaderType(uint16 blockHeader_type) {
+ if (blockHeader_type == 0x1001
+ || blockHeader_type == 0x1002
+ || blockHeader_type == 0x1011
+ || blockHeader_type == 0x1012
+ || blockHeader_type == 0x1013
+ || blockHeader_type == 0x1020
+ || blockHeader_type == 0x1021
+ || blockHeader_type == 0x1030) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
bool ROQPlayer::processBlock() {
// Read the header of the block
ROQBlockHeader blockHeader;
@@ -602,9 +617,41 @@ bool ROQPlayer::processBlock() {
}
if (endpos != _file->pos() && !_file->eos()) {
- warning("Groovie::ROQ: BLOCK %04x Should have ended at %lld, and has ended at %lld", blockHeader.type, (long long)endpos, (long long)_file->pos());
+ warning("Groovie::ROQ: BLOCK 0x%04x Should have ended at %lld, and has ended at %lld", blockHeader.type, (long long)endpos, (long long)_file->pos());
warning("Ensure you've copied the files correctly according to the wiki.");
- _file->seek(MIN(_file->pos(), endpos));
+ int64 currFilePos = _file->pos();
+ if (currFilePos < endpos) {
+ // In this case we stay at the current position,
+ // which is *before* the intended endpos (as calculated from its blockHeader.size) of the faulty block
+
+ // We "peek" ahead to see what type of block is next
+ bool foundValidBlockHeaderType = false;
+ uint16 blockHeader_type = _file->readUint16LE();
+ if (!_file->eos() && !isValidBlockHeaderType(blockHeader_type)) {
+ warning("Groovie::ROQ: Peek next BLOCK 0x%04x is of unknown type at %lld!", blockHeader_type, (long long)currFilePos);
+ // This means we were put at the start of an invalid block,
+ // so test what would happen if we instead seek to the indicated endpos of the faulty block
+ _file->seek(endpos);
+ blockHeader_type = _file->readUint16LE();
+ if (!_file->eos() && isValidBlockHeaderType(blockHeader_type)) {
+ debug("Groovie::ROQ: Peek next BLOCK 0x%04x is of KNOWN type at %lld!", blockHeader_type, (long long)endpos);
+ foundValidBlockHeaderType = true;
+ // Seek back to the intended endpos where we now know starts a block with valid block header type
+ _file->seek(endpos);
+ }
+ }
+ if (!foundValidBlockHeaderType) {
+ // As a fallback seek back to currFilePos and continue from there.
+ // This is likely to lead to a failure in processing in some future block.
+ // In practice this should not happen.
+ _file->seek(currFilePos);
+ }
+ } else {
+ // If the intended endpos of the faulty block is *before* the current file pos,
+ // just seek to the intended endpos and continue from there.
+ // We don't do any peeking here since this case is as of yet not connected to any known bugs.
+ _file->seek(endpos);
+ }
}
// End the frame when the graphics have been modified or when there's an error
return endframe || !ok;
diff --git a/engines/groovie/video/roq.h b/engines/groovie/video/roq.h
index bfce3c6660d..6b14b752ac9 100644
--- a/engines/groovie/video/roq.h
+++ b/engines/groovie/video/roq.h
@@ -68,6 +68,7 @@ protected:
private:
bool readBlockHeader(ROQBlockHeader &blockHeader);
+ bool isValidBlockHeaderType(uint16 blockHeader_type);
bool processBlock();
bool processBlockInfo(ROQBlockHeader &blockHeader);
bool processBlockQuadCodebook(ROQBlockHeader &blockHeader);
Commit: 0ad54bf79ef8efe3138ecaf047b00f3cb7b678e9
https://github.com/scummvm/scummvm/commit/0ad54bf79ef8efe3138ecaf047b00f3cb7b678e9
Author: antoniou79 (a.antoniou79 at gmail.com)
Date: 2025-11-22T12:05:30+02:00
Commit Message:
GROOVIE: Use camelcase for blockHeaderType variable and parameter
blockHeader_type is now renamed as blockHeaderType
In ROQ video decoder (roq.h and roq.cpp)
Changed paths:
engines/groovie/video/roq.cpp
engines/groovie/video/roq.h
diff --git a/engines/groovie/video/roq.cpp b/engines/groovie/video/roq.cpp
index 50467905ef3..3267900117a 100644
--- a/engines/groovie/video/roq.cpp
+++ b/engines/groovie/video/roq.cpp
@@ -545,15 +545,15 @@ bool ROQPlayer::readBlockHeader(ROQBlockHeader &blockHeader) {
}
}
-bool ROQPlayer::isValidBlockHeaderType(uint16 blockHeader_type) {
- if (blockHeader_type == 0x1001
- || blockHeader_type == 0x1002
- || blockHeader_type == 0x1011
- || blockHeader_type == 0x1012
- || blockHeader_type == 0x1013
- || blockHeader_type == 0x1020
- || blockHeader_type == 0x1021
- || blockHeader_type == 0x1030) {
+bool ROQPlayer::isValidBlockHeaderType(uint16 blockHeaderType) {
+ if (blockHeaderType == 0x1001
+ || blockHeaderType == 0x1002
+ || blockHeaderType == 0x1011
+ || blockHeaderType == 0x1012
+ || blockHeaderType == 0x1013
+ || blockHeaderType == 0x1020
+ || blockHeaderType == 0x1021
+ || blockHeaderType == 0x1030) {
return true;
} else {
return false;
@@ -626,15 +626,15 @@ bool ROQPlayer::processBlock() {
// We "peek" ahead to see what type of block is next
bool foundValidBlockHeaderType = false;
- uint16 blockHeader_type = _file->readUint16LE();
- if (!_file->eos() && !isValidBlockHeaderType(blockHeader_type)) {
- warning("Groovie::ROQ: Peek next BLOCK 0x%04x is of unknown type at %lld!", blockHeader_type, (long long)currFilePos);
+ uint16 blockHeaderType = _file->readUint16LE();
+ if (!_file->eos() && !isValidBlockHeaderType(blockHeaderType)) {
+ warning("Groovie::ROQ: Peek next BLOCK 0x%04x is of unknown type at %lld!", blockHeaderType, (long long)currFilePos);
// This means we were put at the start of an invalid block,
// so test what would happen if we instead seek to the indicated endpos of the faulty block
_file->seek(endpos);
- blockHeader_type = _file->readUint16LE();
- if (!_file->eos() && isValidBlockHeaderType(blockHeader_type)) {
- debug("Groovie::ROQ: Peek next BLOCK 0x%04x is of KNOWN type at %lld!", blockHeader_type, (long long)endpos);
+ blockHeaderType = _file->readUint16LE();
+ if (!_file->eos() && isValidBlockHeaderType(blockHeaderType)) {
+ debug("Groovie::ROQ: Peek next BLOCK 0x%04x is of KNOWN type at %lld!", blockHeaderType, (long long)endpos);
foundValidBlockHeaderType = true;
// Seek back to the intended endpos where we now know starts a block with valid block header type
_file->seek(endpos);
diff --git a/engines/groovie/video/roq.h b/engines/groovie/video/roq.h
index 6b14b752ac9..fcdc9c056ff 100644
--- a/engines/groovie/video/roq.h
+++ b/engines/groovie/video/roq.h
@@ -68,7 +68,7 @@ protected:
private:
bool readBlockHeader(ROQBlockHeader &blockHeader);
- bool isValidBlockHeaderType(uint16 blockHeader_type);
+ bool isValidBlockHeaderType(uint16 blockHeaderType);
bool processBlock();
bool processBlockInfo(ROQBlockHeader &blockHeader);
bool processBlockQuadCodebook(ROQBlockHeader &blockHeader);
More information about the Scummvm-git-logs
mailing list