diff options
Diffstat (limited to 'engines/sci')
-rw-r--r-- | engines/sci/engine/script.cpp | 50 | ||||
-rw-r--r-- | engines/sci/engine/seg_manager.cpp | 6 | ||||
-rw-r--r-- | engines/sci/engine/seg_manager.h | 2 | ||||
-rw-r--r-- | engines/sci/engine/segment.cpp | 24 | ||||
-rw-r--r-- | engines/sci/engine/segment.h | 6 |
5 files changed, 42 insertions, 46 deletions
diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp index 54edd38f90..6dfd39a496 100644 --- a/engines/sci/engine/script.cpp +++ b/engines/sci/engine/script.cpp @@ -161,49 +161,19 @@ reg_t SegManager::getClassAddress(int classnr, ScriptLoadType lock, reg_t caller void SegManager::scriptInitialiseLocals(SegmentId segmentId) { Script *scr = getScript(segmentId); - uint16 count; - - 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; - } - } - - return; - } - - // Check if the script actually has local variables - if (scr->_localsOffset == 0) - return; - 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 + scr->_localsOffset - 2); - else - count = (READ_LE_UINT16(scr->_buf + scr->_localsOffset - 2) - 4) >> 1; - // half block size - - 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); + LocalVariables *locals = allocLocalsSegment(scr); if (locals) { - uint i; - const byte *base = (const byte *)(scr->_buf + scr->_localsOffset); + if (getSciVersion() > SCI_VERSION_0_EARLY) { + const byte *base = (const byte *)(scr->_buf + scr->getLocalsOffset()); - for (i = 0; i < count; i++) - locals->_locals[i] = make_reg(0, READ_SCI11ENDIAN_UINT16(base + i * 2)); + for (uint16 i = 0; i < scr->getLocalsCount(); i++) + locals->_locals[i] = make_reg(0, READ_SCI11ENDIAN_UINT16(base + i * 2)); + } else { + // In SCI0 early, locals are set at run time, thus zero them all here + for (uint16 i = 0; i < scr->getLocalsCount(); i++) + locals->_locals[i] = NULL_REG; + } } } diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp index 4d3e6f754e..8d51b27099 100644 --- a/engines/sci/engine/seg_manager.cpp +++ b/engines/sci/engine/seg_manager.cpp @@ -377,8 +377,8 @@ SegmentId SegManager::getScriptSegment(int script_nr, ScriptLoadType load) { return segment; } -LocalVariables *SegManager::allocLocalsSegment(Script *scr, int count) { - if (!count) { // No locals +LocalVariables *SegManager::allocLocalsSegment(Script *scr) { + if (!scr->getLocalsCount()) { // No locals scr->_localsSegment = 0; scr->_localsBlock = NULL; return NULL; @@ -395,7 +395,7 @@ LocalVariables *SegManager::allocLocalsSegment(Script *scr, int count) { scr->_localsBlock = locals; locals->script_id = scr->_nr; - locals->_locals.resize(count); + locals->_locals.resize(scr->getLocalsCount()); return locals; } diff --git a/engines/sci/engine/seg_manager.h b/engines/sci/engine/seg_manager.h index 62dcddbcbe..ec89e42f9c 100644 --- a/engines/sci/engine/seg_manager.h +++ b/engines/sci/engine/seg_manager.h @@ -478,7 +478,7 @@ private: private: SegmentObj *allocSegment(SegmentObj *mem, SegmentId *segid); - LocalVariables *allocLocalsSegment(Script *scr, int count); + LocalVariables *allocLocalsSegment(Script *scr); int deallocate(SegmentId seg, bool recursive); void createClassTable(); diff --git a/engines/sci/engine/segment.cpp b/engines/sci/engine/segment.cpp index 4b3df11d8f..c32823a7c2 100644 --- a/engines/sci/engine/segment.cpp +++ b/engines/sci/engine/segment.cpp @@ -100,6 +100,7 @@ Script::Script() : SegmentObj(SEG_TYPE_SCRIPT) { _localsOffset = 0; _localsSegment = 0; _localsBlock = NULL; + _localsCount = 0; _markedAsDeleted = false; } @@ -122,6 +123,7 @@ void Script::init(int script_nr, ResourceManager *resMan) { _localsOffset = 0; _localsBlock = NULL; + _localsCount = 0; _codeBlocks.clear(); @@ -198,6 +200,7 @@ void Script::load(ResourceManager *resMan) { _exportTable = (const uint16 *)(_buf + 1 + 5 + 2); _numExports = READ_SCI11ENDIAN_UINT16(_exportTable - 1); _localsOffset = _scriptSize + 4; + _localsCount = READ_SCI11ENDIAN_UINT16(_buf + _localsOffset - 2); } } else { _exportTable = (const uint16 *)findBlock(SCI_OBJ_EXPORTS); @@ -211,8 +214,27 @@ void Script::load(ResourceManager *resMan) { _synonyms += 4; // skip header } const byte* localsBlock = findBlock(SCI_OBJ_LOCALVARS); - if (localsBlock) + if (localsBlock) { _localsOffset = localsBlock - _buf + 4; + _localsCount = (READ_LE_UINT16(_buf + _localsOffset - 2) - 4) >> 1; // half block size + } + } + + if (getSciVersion() > SCI_VERSION_0_EARLY) { + // Does the script actually have locals? If not, set the locals offset to 0 + if (!_localsCount) + _localsOffset = 0; + + if (_localsOffset + _localsCount * 2 + 1 >= (int)_bufSize) { + warning("Locals extend beyond end of script: offset %04x, count %x vs size %x", _localsOffset, _localsCount, _bufSize); + _localsCount = (_bufSize - _localsOffset) >> 1; + } + } else { + // 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. + _localsCount = READ_LE_UINT16(_buf); + _localsOffset = -_localsCount * 2; // Make sure it's invalid } } diff --git a/engines/sci/engine/segment.h b/engines/sci/engine/segment.h index f1b6dccaa2..8759c630e8 100644 --- a/engines/sci/engine/segment.h +++ b/engines/sci/engine/segment.h @@ -364,6 +364,9 @@ private: Common::Array<CodeBlock> _codeBlocks; + int _localsOffset; + uint16 _localsCount; + public: /** * Table for objects, contains property variables. @@ -371,7 +374,8 @@ public: */ ObjMap _objects; - int _localsOffset; + int getLocalsOffset() const { return _localsOffset; } + uint16 getLocalsCount() const { return _localsCount; } SegmentId _localsSegment; /**< The local variable segment */ LocalVariables *_localsBlock; |