From 1515bb31a6fa802314836a9904756d7fcc840c69 Mon Sep 17 00:00:00 2001 From: Colin Snover Date: Wed, 20 Sep 2017 12:30:54 -0500 Subject: 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. --- engines/sci/resource_audio.cpp | 40 ++++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) (limited to 'engines') 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_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(); -- cgit v1.2.3