diff options
author | Colin Snover | 2017-09-20 12:30:54 -0500 |
---|---|---|
committer | Colin Snover | 2017-09-20 13:07:08 -0500 |
commit | 1515bb31a6fa802314836a9904756d7fcc840c69 (patch) | |
tree | cc57c45570ae604f749084418cd24221f03b3a79 | |
parent | a7479b4f5beb83e75379f868d5c19c23625eabe6 (diff) | |
download | scummvm-rg350-1515bb31a6fa802314836a9904756d7fcc840c69.tar.gz scummvm-rg350-1515bb31a6fa802314836a9904756d7fcc840c69.tar.bz2 scummvm-rg350-1515bb31a6fa802314836a9904756d7fcc840c69.zip |
SCI: Fix detection of end of audio map & entry size in SCI32
Torin RU map 38140 has an unusual terminator entry; instead of a
normal terminating entry of 11 FFs, its terminating entry is
03 FF FF FF FF C4 36 01 FF FF FF. So, two changes are made:
1. The end-of-map check is now the same as in SSCI1.1+ and only
checks that the final byte of the Audio36 tuple is 0xFF,
instead of the entire tuple;
2. The unneeded entry size heuristic has been turned off for
all SCI32 games.
A quick check of the English versions of LB2CD, EQ1CD, SQ4CD, and
KQ6CD, as well as all English SCI32 games, indicates that this
approach seems to be working correctly.
Fixes Trac#10188.
-rw-r--r-- | engines/sci/resource_audio.cpp | 40 |
1 files changed, 30 insertions, 10 deletions
diff --git a/engines/sci/resource_audio.cpp b/engines/sci/resource_audio.cpp index 39d742ac95..b1d2a91a59 100644 --- a/engines/sci/resource_audio.cpp +++ b/engines/sci/resource_audio.cpp @@ -339,13 +339,19 @@ int ResourceManager::readAudioMapSCI11(IntMapResourceSource *map) { SciSpan<const byte>::const_iterator ptr = mapRes->cbegin(); - // Heuristic to detect entry size uint32 entrySize = 0; - for (int i = mapRes->size() - 1; i >= 0; --i) { - if (ptr[i] == 0xff) - entrySize++; - else - break; + if (_volVersion >= kResVersionSci2) { + // The heuristic size detection is incompatible with at least Torin RU, + // which is fine because it is not needed for SCI32 + entrySize = 11; + } else { + // Heuristic to detect entry size + for (int i = mapRes->size() - 1; i >= 0; --i) { + if (ptr[i] == 0xff) + entrySize++; + else + break; + } } if (map->_mapNumber == 65535) { @@ -419,20 +425,34 @@ int ResourceManager::readAudioMapSCI11(IntMapResourceSource *map) { disposeVolumeFileStream(stream, src); } else { - bool isEarly = (entrySize != 11); + // EQ1CD & SQ4CD are "early" games; KQ6CD and all SCI32 are "late" games + const bool isEarly = (entrySize != 11); if (!isEarly) { offset = ptr.getUint32LE(); ptr += 4; } + enum { + kRaveFlag = 0x40, + kSyncFlag = 0x80, + kEndOfMapFlag = 0xFF + }; + while (ptr != mapRes->cend()) { uint32 n = ptr.getUint32BE(); uint32 syncSize = 0; ptr += 4; - if (n == 0xffffffff) + // Checking the entire tuple breaks Torin RU and is not how SSCI + // works + if ((n & kEndOfMapFlag) == kEndOfMapFlag) { + const uint32 bytesLeft = mapRes->cend() - ptr; + if (bytesLeft >= entrySize) { + warning("End of %s reached, but %u entries remain", mapResId.toString().c_str(), bytesLeft / entrySize); + } break; + } if (isEarly) { offset = ptr.getUint32LE(); @@ -442,7 +462,7 @@ int ResourceManager::readAudioMapSCI11(IntMapResourceSource *map) { ptr += 3; } - if (isEarly || (n & 0x80)) { + if (isEarly || (n & kSyncFlag)) { syncSize = ptr.getUint16LE(); ptr += 2; @@ -455,7 +475,7 @@ int ResourceManager::readAudioMapSCI11(IntMapResourceSource *map) { // Checking for this 0x40 flag breaks at least Laura Bow 2 CD 1.1 // map 448 - if (g_sci->getGameId() == GID_KQ6 && (n & 0x40)) { + if (g_sci->getGameId() == GID_KQ6 && (n & kRaveFlag)) { // This seems to define the size of raw lipsync data (at least // in KQ6 CD Windows). uint32 kq6HiresSyncSize = ptr.getUint16LE(); |