aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Snover2017-09-23 20:13:06 -0500
committerColin Snover2017-09-23 20:57:03 -0500
commitf83c61fcb62567f1a7d1916e018117eee619b322 (patch)
tree833129e1371573251b3e9cb9d347fb7536bcb90f
parent643a572610377d36c3d43d44c7487dd15b36e5e2 (diff)
downloadscummvm-rg350-f83c61fcb62567f1a7d1916e018117eee619b322.tar.gz
scummvm-rg350-f83c61fcb62567f1a7d1916e018117eee619b322.tar.bz2
scummvm-rg350-f83c61fcb62567f1a7d1916e018117eee619b322.zip
SCI32: Fix relocation of locals in SCI3
Somehow, up until trying to view an encrypted data cube in RAMA, the missing relocation of locals did not seem to cause any trouble in any of the other SCI3 games.
-rw-r--r--engines/sci/engine/script.cpp32
-rw-r--r--engines/sci/engine/script.h2
2 files changed, 19 insertions, 15 deletions
diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp
index a0243defa8..c1da3f25e0 100644
--- a/engines/sci/engine/script.cpp
+++ b/engines/sci/engine/script.cpp
@@ -698,9 +698,9 @@ int Script::relocateOffsetSci3(uint32 offset) const {
}
#endif
-bool Script::relocateLocal(SegmentId segment, int location) {
+bool Script::relocateLocal(SegmentId segment, int location, uint32 offset) {
if (_localsBlock)
- return relocateBlock(_localsBlock->_locals, _localsOffset, segment, location, getHeapOffset());
+ return relocateBlock(_localsBlock->_locals, _localsOffset, segment, location, offset);
else
return false;
}
@@ -804,7 +804,7 @@ void Script::relocateSci0Sci21(const SegmentId segmentId) {
// We only relocate locals and objects here, and ignore relocation of
// code blocks. In SCI1.1 and newer versions, only locals and objects
// are relocated.
- if (!relocateLocal(segmentId, pos)) {
+ if (!relocateLocal(segmentId, pos, getHeapOffset())) {
// Not a local? It's probably an object or code block. If it's an
// object, relocate it.
const ObjMap::iterator end = _objects.end();
@@ -817,19 +817,23 @@ void Script::relocateSci0Sci21(const SegmentId segmentId) {
#ifdef ENABLE_SCI32
void Script::relocateSci3(const SegmentId segmentId) {
- SciSpan<const byte> relocStart = _buf->subspan(_buf->getUint32SEAt(8));
+ SciSpan<const byte> relocEntry = _buf->subspan(_buf->getUint32SEAt(8));
const uint relocCount = _buf->getUint16SEAt(18);
- ObjMap::iterator it;
- for (it = _objects.begin(); it != _objects.end(); ++it) {
- SciSpan<const byte> seeker = relocStart;
- for (uint i = 0; i < relocCount; ++i) {
- it->_value.relocateSci3(segmentId,
- seeker.getUint32SEAt(0),
- seeker.getUint32SEAt(4),
- _script.size());
- seeker += 10;
+ for (uint i = 0; i < relocCount; ++i) {
+ const uint location = relocEntry.getUint32SEAt(0);
+ const uint offset = relocEntry.getUint32SEAt(4);
+
+ if (!relocateLocal(segmentId, location, offset)) {
+ const ObjMap::iterator end = _objects.end();
+ for (ObjMap::iterator it = _objects.begin(); it != end; ++it) {
+ if (it->_value.relocateSci3(segmentId, location, offset, _script.size())) {
+ break;
+ }
+ }
}
+
+ relocEntry += 10;
}
}
#endif
@@ -973,7 +977,7 @@ void Script::initializeLocals(SegManager *segMan) {
const SciSpan<const byte> base = _buf->subspan(getLocalsOffset());
for (uint16 i = 0; i < getLocalsCount(); i++)
- locals->_locals[i] = make_reg(0, base.getUint16SEAt(i * 2));
+ locals->_locals[i] = make_reg(0, base.getUint16SEAt(i * sizeof(uint16)));
} else {
// In SCI0 early, locals are set at run time, thus zero them all here
for (uint16 i = 0; i < getLocalsCount(); i++)
diff --git a/engines/sci/engine/script.h b/engines/sci/engine/script.h
index 1befef1c8a..f4afca7681 100644
--- a/engines/sci/engine/script.h
+++ b/engines/sci/engine/script.h
@@ -318,7 +318,7 @@ private:
void relocateSci3(const SegmentId segmentId);
#endif
- bool relocateLocal(SegmentId segment, int location);
+ bool relocateLocal(SegmentId segment, int location, uint32 offset);
#ifdef ENABLE_SCI32
/**