diff options
Diffstat (limited to 'engines/sci')
-rw-r--r-- | engines/sci/detection.cpp | 8 | ||||
-rw-r--r-- | engines/sci/resource.cpp | 54 |
2 files changed, 39 insertions, 23 deletions
diff --git a/engines/sci/detection.cpp b/engines/sci/detection.cpp index a9dac98572..a80baf182e 100644 --- a/engines/sci/detection.cpp +++ b/engines/sci/detection.cpp @@ -1850,7 +1850,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.000", 0, "4462fe48c7452d98fddcec327a3e738d", 5789138}, {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, - SCI_VERSION_1_1, + SCI_VERSION_AUTODETECT, SCI_VERSION_1_1 }, @@ -1861,7 +1861,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.000", 0, "57d5fe8bb9e044158514476ea7678eb0", 5754790}, {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE}, 0, - SCI_VERSION_1_1, + SCI_VERSION_AUTODETECT, SCI_VERSION_1_1 }, @@ -2574,7 +2574,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.000", 0, "ecace1a2771846b1a8aa1afdd44111a0", 6570147}, {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, - SCI_VERSION_1, + SCI_VERSION_AUTODETECT, SCI_VERSION_1_1 }, @@ -2585,7 +2585,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.000", 0, "ec6f5cf369054dd3e5392995e9975b9e", 768218}, {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, 0, - SCI_VERSION_1, + SCI_VERSION_AUTODETECT, SCI_VERSION_1_1 }, diff --git a/engines/sci/resource.cpp b/engines/sci/resource.cpp index 30e917557d..a1d7fa7a41 100644 --- a/engines/sci/resource.cpp +++ b/engines/sci/resource.cpp @@ -728,26 +728,39 @@ int ResourceManager::detectMapVersion() { } return SCI_VERSION_0; } - // SCI1E/L and some SCI1.1 maps have last directory entry set to 0xFF - // and offset set to filesize - // SCI1 have 6-bytes entries, while SCI1.1 have 5-byte entries - file.seek(1, SEEK_SET); - uint16 off1, off = file.readUint16LE(); - uint16 nEntries = off / 3; - file.seek(1, SEEK_CUR); - file.seek(off - 3, SEEK_SET); - if (file.readByte() == 0xFF && file.readUint16LE() == file.size()) { - file.seek(3, SEEK_SET); - for (int i = 0; i < nEntries; i++) { - file.seek(1, SEEK_CUR); - off1 = file.readUint16LE(); - if ((off1 - off) % 5 && (off1 - off) % 6 == 0) - return SCI_VERSION_1; - if ((off1 - off) % 5 == 0 && (off1 - off) % 6) - return SCI_VERSION_1_1; - off = off1; + + // SCI1 and SCI1.1 maps consist of a fixed 3-byte header, a directory list (3-bytes each) that has one entry + // of id FFh and points to EOF. The actual entries have 6-bytes on SCI1 and 5-bytes on SCI1.1 + byte directoryType = 0; + uint16 directoryOffset = 0; + uint16 lastDirectoryOffset = 0; + uint16 directorySize = 0; + int mapDetected = 0; + file.seek(0, SEEK_SET); + while (!file.eos()) { + directoryType = file.readByte(); + directoryOffset = file.readUint16LE(); + if ((directoryType < 0x80) || ((directoryType > 0xA0) && (directoryType != 0xFF))) + break; + // Offset is above file size? -> definitely not SCI1/SCI1.1 + if (directoryOffset > file.size()) + break; + if (lastDirectoryOffset) { + directorySize = directoryOffset - lastDirectoryOffset; + if ((directorySize % 5) && (directorySize % 6 == 0)) + mapDetected = SCI_VERSION_1; + if ((directorySize % 5 == 0) && (directorySize % 6)) + mapDetected = SCI_VERSION_1_1; } - return SCI_VERSION_1; + if (directoryType==0xFF) { + // FFh entry needs to point to EOF + if (directoryOffset != file.size()) + break; + if (mapDetected) + return mapDetected; + return SCI_VERSION_1; + } + lastDirectoryOffset = directoryOffset; } #ifdef ENABLE_SCI32 @@ -974,6 +987,9 @@ int ResourceManager::readResourceMapSCI0(ResourceSource *map) { res->file_offset = offset & (((~bMask) << 24) | 0xFFFFFF); res->id = resId; res->source = getVolume(map, offset >> bShift); + if (!res->source) { + warning("Could not get volume for resource %d, VolumeID %d\n", resId, offset >> bShift); + } _resMap.setVal(resId, res); } } while (!file.eos()); |