diff options
author | Filippos Karapetis | 2010-06-13 22:15:30 +0000 |
---|---|---|
committer | Filippos Karapetis | 2010-06-13 22:15:30 +0000 |
commit | b5ebd40d614ab7b1c2f1408750c09f528b7ae2de (patch) | |
tree | 2eb8b6da50501982a0612102c3e0a916773e3f0a /engines | |
parent | 01d53a62165d229b88db11647ffe40ff2502d7b4 (diff) | |
download | scummvm-rg350-b5ebd40d614ab7b1c2f1408750c09f528b7ae2de.tar.gz scummvm-rg350-b5ebd40d614ab7b1c2f1408750c09f528b7ae2de.tar.bz2 scummvm-rg350-b5ebd40d614ab7b1c2f1408750c09f528b7ae2de.zip |
The offset of script local variables is now calculated when the script is loaded, thus we no longer need to save it. Merged scriptInitialiseLocals() with scriptInitialiseLocalsZero()
svn-id: r49640
Diffstat (limited to 'engines')
-rw-r--r-- | engines/sci/engine/savegame.cpp | 2 | ||||
-rw-r--r-- | engines/sci/engine/savegame.h | 2 | ||||
-rw-r--r-- | engines/sci/engine/script.cpp | 66 | ||||
-rw-r--r-- | engines/sci/engine/seg_manager.h | 12 | ||||
-rw-r--r-- | engines/sci/engine/segment.cpp | 4 |
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; } } |