aboutsummaryrefslogtreecommitdiff
path: root/engines/sci
diff options
context:
space:
mode:
Diffstat (limited to 'engines/sci')
-rw-r--r--engines/sci/debug.h2
-rw-r--r--engines/sci/detection.cpp8
-rw-r--r--engines/sci/engine/state.h2
-rw-r--r--engines/sci/resource.cpp62
4 files changed, 48 insertions, 26 deletions
diff --git a/engines/sci/debug.h b/engines/sci/debug.h
index ccf0602600..0963159c98 100644
--- a/engines/sci/debug.h
+++ b/engines/sci/debug.h
@@ -46,7 +46,7 @@ struct ScriptState {
int old_pc_offset;
StackPtr old_sp;
ExecStack *xs;
- uint16 restadjust;
+ int16 restadjust;
reg_t *variables[4]; // global, local, temp, param, as immediate pointers
reg_t *variables_base[4]; // Used for referencing VM ops
SegmentId variables_seg[4]; // Same as above, contains segment IDs
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/engine/state.h b/engines/sci/engine/state.h
index 92a5b5e411..1759b26dcb 100644
--- a/engines/sci/engine/state.h
+++ b/engines/sci/engine/state.h
@@ -208,7 +208,7 @@ public:
bool _executionStackPosChanged; /**< Set to true if the execution stack position should be re-evaluated by the vm */
reg_t r_acc; /**< Accumulator */
- uint16 restAdjust; /**< &rest register (only used for save games) */
+ int16 restAdjust; /**< &rest register (only used for save games) */
reg_t r_prev; /**< previous comparison result */
SegmentId stack_segment; /**< Heap area for the stack to use */
diff --git a/engines/sci/resource.cpp b/engines/sci/resource.cpp
index 30e917557d..5fdc286894 100644
--- a/engines/sci/resource.cpp
+++ b/engines/sci/resource.cpp
@@ -728,32 +728,51 @@ 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
// late SCI1.1 and SCI32 maps have last directory entry set to 0xFF
// offset set to filesize and 4 more bytes
- file.seek(off - 7, SEEK_SET);
+
+ // TODO/FIXME: This code was not updated in r42300, which changed the behavior of this
+ // function a lot. To make it compile again "off" was changed to the newly introduced
+ // "lastDirectoryOffset". This is probably not the correct fix, since before r43000
+ // the loop above could not prematurely terminate and thus this would always check the
+ // last directory entry instead of the last checked directory entry.
+ file.seek(lastDirectoryOffset - 7, SEEK_SET);
if (file.readByte() == 0xFF && file.readUint16LE() == file.size())
return SCI_VERSION_32; // TODO : check if there is a difference between these maps
#endif
@@ -974,6 +993,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", id, offset >> bShift);
+ }
_resMap.setVal(resId, res);
}
} while (!file.eos());