aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/sci/engine/savegame.cpp2
-rw-r--r--engines/sci/engine/savegame.h2
-rw-r--r--engines/sci/engine/script.cpp66
-rw-r--r--engines/sci/engine/seg_manager.h12
-rw-r--r--engines/sci/engine/segment.cpp4
5 files changed, 37 insertions, 49 deletions
diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp
index 9c2ff76088..8c743189d7 100644
--- a/engines/sci/engine/savegame.cpp
+++ b/engines/sci/engine/savegame.cpp
@@ -566,7 +566,7 @@ void Script::saveLoadWithSerializer(Common::Serializer &s) {
}
}
- s.syncAsSint32LE(_localsOffset);
+ s.skip(4, VER(9), VER(20)); // OBSOLETE: Used to be _localsOffset
s.syncAsSint32LE(_localsSegment);
s.syncAsSint32LE(_markedAsDeleted);
diff --git a/engines/sci/engine/savegame.h b/engines/sci/engine/savegame.h
index 7be05381da..e7e8fff999 100644
--- a/engines/sci/engine/savegame.h
+++ b/engines/sci/engine/savegame.h
@@ -36,7 +36,7 @@ namespace Sci {
struct EngineState;
enum {
- CURRENT_SAVEGAME_VERSION = 20,
+ CURRENT_SAVEGAME_VERSION = 21,
MINIMUM_SAVEGAME_VERSION = 9
};
diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp
index 1f32e50b67..54edd38f90 100644
--- a/engines/sci/engine/script.cpp
+++ b/engines/sci/engine/script.cpp
@@ -159,41 +159,48 @@ reg_t SegManager::getClassAddress(int classnr, ScriptLoadType lock, reg_t caller
}
}
-void SegManager::scriptInitialiseLocalsZero(SegmentId seg, int count) {
- Script *scr = getScript(seg);
+void SegManager::scriptInitialiseLocals(SegmentId segmentId) {
+ Script *scr = getScript(segmentId);
+ uint16 count;
- scr->_localsOffset = -count * 2; // Make sure it's invalid
+ if (getSciVersion() == SCI_VERSION_0_EARLY) {
+ // Old script block. There won't be a localvar block in this case.
+ // Instead, the script starts with a 16 bit int specifying the
+ // number of locals we need; these are then allocated and zeroed.
+ int localsCount = READ_LE_UINT16(scr->_buf);
+ if (localsCount) {
+ scr->_localsOffset = -localsCount * 2; // Make sure it's invalid
+ LocalVariables *locals = allocLocalsSegment(scr, localsCount);
+ if (locals) {
+ for (int i = 0; i < localsCount; i++)
+ locals->_locals[i] = NULL_REG;
+ }
+ }
- LocalVariables *locals = allocLocalsSegment(scr, count);
- if (locals) {
- for (int i = 0; i < count; i++)
- locals->_locals[i] = NULL_REG;
+ return;
}
-}
-void SegManager::scriptInitialiseLocals(reg_t location) {
- Script *scr = getScript(location.segment);
- unsigned int count;
+ // Check if the script actually has local variables
+ if (scr->_localsOffset == 0)
+ return;
- VERIFY(location.offset + 1 < (uint16)scr->getBufSize(), "Locals beyond end of script\n");
+ VERIFY(scr->_localsOffset + 1 < (uint16)scr->getBufSize(), "Locals beyond end of script\n");
if (getSciVersion() >= SCI_VERSION_1_1)
- count = READ_SCI11ENDIAN_UINT16(scr->_buf + location.offset - 2);
+ count = READ_SCI11ENDIAN_UINT16(scr->_buf + scr->_localsOffset - 2);
else
- count = (READ_LE_UINT16(scr->_buf + location.offset - 2) - 4) >> 1;
+ count = (READ_LE_UINT16(scr->_buf + scr->_localsOffset - 2) - 4) >> 1;
// half block size
- scr->_localsOffset = location.offset;
-
- if (!(location.offset + count * 2 + 1 < scr->getBufSize())) {
- warning("Locals extend beyond end of script: offset %04x, count %x vs size %x", location.offset, count, (uint)scr->getBufSize());
- count = (scr->getBufSize() - location.offset) >> 1;
+ if (!(scr->_localsOffset + count * 2 + 1 < (uint16)scr->getBufSize())) {
+ warning("Locals extend beyond end of script: offset %04x, count %x vs size %x", scr->_localsOffset, count, (uint)scr->getBufSize());
+ count = (scr->getBufSize() - scr->_localsOffset) >> 1;
}
LocalVariables *locals = allocLocalsSegment(scr, count);
if (locals) {
uint i;
- const byte *base = (const byte *)(scr->_buf + location.offset);
+ const byte *base = (const byte *)(scr->_buf + scr->_localsOffset);
for (i = 0; i < count; i++)
locals->_locals[i] = make_reg(0, READ_SCI11ENDIAN_UINT16(base + i * 2));
@@ -258,18 +265,7 @@ void script_instantiate_sci0(Script *scr, int segmentId, SegManager *segMan) {
bool oldScriptHeader = (getSciVersion() == SCI_VERSION_0_EARLY);
uint16 curOffset = oldScriptHeader ? 2 : 0;
- if (oldScriptHeader) {
- // Old script block
- // There won't be a localvar block in this case
- // Instead, the script starts with a 16 bit int specifying the
- // number of locals we need; these are then allocated and zeroed.
- int localsCount = READ_LE_UINT16(scr->_buf);
- if (localsCount)
- segMan->scriptInitialiseLocalsZero(segmentId, localsCount);
- }
-
- // Now do a first pass through the script objects to find the
- // local variable blocks
+ // Now do a first pass through the script objects to find all the object classes
do {
objType = scr->getHeap(curOffset);
@@ -280,9 +276,6 @@ void script_instantiate_sci0(Script *scr, int segmentId, SegManager *segMan) {
curOffset += 4; // skip header
switch (objType) {
- case SCI_OBJ_LOCALVARS:
- segMan->scriptInitialiseLocals(make_reg(segmentId, curOffset));
- break;
case SCI_OBJ_CLASS: {
int classpos = curOffset - SCRIPT_OBJECT_MAGIC_OFFSET;
int species = scr->getHeap(curOffset - SCRIPT_OBJECT_MAGIC_OFFSET + SCRIPT_SPECIES_OFFSET);
@@ -365,10 +358,9 @@ int script_instantiate(ResourceManager *resMan, SegManager *segMan, int scriptNu
scr->init(scriptNum, resMan);
scr->load(resMan);
+ segMan->scriptInitialiseLocals(segmentId);
if (getSciVersion() >= SCI_VERSION_1_1) {
- int heapStart = scr->getScriptSize();
- segMan->scriptInitialiseLocals(make_reg(segmentId, heapStart + 4));
segMan->scriptInitialiseObjectsSci11(segmentId);
scr->relocate(make_reg(segmentId, READ_SCI11ENDIAN_UINT16(scr->_heapStart)));
} else {
diff --git a/engines/sci/engine/seg_manager.h b/engines/sci/engine/seg_manager.h
index 9bcdd80a62..62dcddbcbe 100644
--- a/engines/sci/engine/seg_manager.h
+++ b/engines/sci/engine/seg_manager.h
@@ -146,18 +146,10 @@ public:
// i.e. loading and linking.
/**
- * Initializes a script's local variable block
- * All variables are initialized to zero.
- * @param seg Segment containing the script to initialize
- * @param nr Number of local variables to allocate
- */
- void scriptInitialiseLocalsZero(SegmentId seg, int nr);
-
- /**
* Initializes a script's local variable block according to a prototype
- * @param location Location to initialize from
+ * @param segmentId Segment containing the script to initialize
*/
- void scriptInitialiseLocals(reg_t location);
+ void scriptInitialiseLocals(SegmentId segmentId);
// 2. Clones
diff --git a/engines/sci/engine/segment.cpp b/engines/sci/engine/segment.cpp
index 0e0a759d4b..4b3df11d8f 100644
--- a/engines/sci/engine/segment.cpp
+++ b/engines/sci/engine/segment.cpp
@@ -197,6 +197,7 @@ void Script::load(ResourceManager *resMan) {
if (READ_LE_UINT16(_buf + 1 + 5) > 0) {
_exportTable = (const uint16 *)(_buf + 1 + 5 + 2);
_numExports = READ_SCI11ENDIAN_UINT16(_exportTable - 1);
+ _localsOffset = _scriptSize + 4;
}
} else {
_exportTable = (const uint16 *)findBlock(SCI_OBJ_EXPORTS);
@@ -209,6 +210,9 @@ void Script::load(ResourceManager *resMan) {
_numSynonyms = READ_SCI11ENDIAN_UINT16(_synonyms + 2) / 4;
_synonyms += 4; // skip header
}
+ const byte* localsBlock = findBlock(SCI_OBJ_LOCALVARS);
+ if (localsBlock)
+ _localsOffset = localsBlock - _buf + 4;
}
}