aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
Diffstat (limited to 'engines')
-rw-r--r--engines/sci/engine/script.cpp50
-rw-r--r--engines/sci/engine/seg_manager.cpp6
-rw-r--r--engines/sci/engine/seg_manager.h2
-rw-r--r--engines/sci/engine/segment.cpp24
-rw-r--r--engines/sci/engine/segment.h6
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;