aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/sci/engine/savegame.cpp40
-rw-r--r--engines/sci/engine/segment.cpp21
-rw-r--r--engines/sci/engine/segment.h10
3 files changed, 27 insertions, 44 deletions
diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp
index 07c40b332c..20bcb687d5 100644
--- a/engines/sci/engine/savegame.cpp
+++ b/engines/sci/engine/savegame.cpp
@@ -757,17 +757,11 @@ void SegManager::reconstructScripts(EngineState *s) {
continue;
Script *scr = (Script *)_heap[i];
-
- // FIXME: Unify this code with script_instantiate_* ?
scr->load(g_sci->getResMan());
scr->_localsBlock = (scr->_localsSegment == 0) ? NULL : (LocalVariables *)(_heap[scr->_localsSegment]);
- ObjMap::iterator it;
- const ObjMap::iterator end = scr->_objects.end();
- for (it = scr->_objects.begin(); it != end; ++it) {
- byte *data = scr->_buf + it->_value.getPos().offset;
- it->_value._baseObj = data;
- }
+ for (ObjMap::iterator it = scr->_objects.begin(); it != scr->_objects.end(); ++it)
+ it->_value._baseObj = scr->_buf + it->_value.getPos().offset;
}
for (i = 0; i < _heap.size(); i++) {
@@ -776,29 +770,15 @@ void SegManager::reconstructScripts(EngineState *s) {
Script *scr = (Script *)_heap[i];
- // FIXME: Unify this code with Script::scriptObjInit ?
- ObjMap::iterator it;
- const ObjMap::iterator end = scr->_objects.end();
- for (it = scr->_objects.begin(); it != end; ++it) {
- byte *data = scr->_buf + it->_value.getPos().offset;
-
- if (getSciVersion() >= SCI_VERSION_1_1) {
- it->_value._baseMethod = (uint16 *)(scr->_buf + READ_LE_UINT16( data + 6 ));
- it->_value._baseVars = (uint16 *)(scr->_buf + READ_LE_UINT16( data + 4 ));
- } else {
- int funct_area = READ_LE_UINT16(data + SCRIPT_FUNCTAREAPTR_OFFSET);
- const Object *baseObj = s->_segMan->getObject(it->_value.getSpeciesSelector());
-
- if (!baseObj) {
- warning("Object without a base class: Script %d, index %d (reg address %04x:%04x",
- scr->_nr, i, PRINT_REG(it->_value.getSpeciesSelector()));
- continue;
- }
- it->_value.setVarCount(baseObj->getVarCount());
- it->_value._baseObj = baseObj->_baseObj;
+ for (ObjMap::iterator it = scr->_objects.begin(); it != scr->_objects.end(); ++it) {
+ reg_t addr = it->_value.getPos();
+ Object *obj = scr->scriptObjInit(addr, false);
- it->_value._baseMethod = (uint16 *)(data + funct_area);
- it->_value._baseVars = (uint16 *)(data + it->_value.getVarCount() * 2 + SCRIPT_SELECTOR_OFFSET);
+ if (getSciVersion() < SCI_VERSION_1_1) {
+ if (!obj->initBaseObject(this, addr, false)) {
+ warning("Failed to locate base object for object at %04X:%04X; skipping", PRINT_REG(addr));
+ scr->scriptObjRemove(addr);
+ }
}
}
}
diff --git a/engines/sci/engine/segment.cpp b/engines/sci/engine/segment.cpp
index e1e7fd4ae6..07fe6f0a92 100644
--- a/engines/sci/engine/segment.cpp
+++ b/engines/sci/engine/segment.cpp
@@ -227,10 +227,10 @@ const Object *Script::getObject(uint16 offset) const {
return 0;
}
-Object *Script::scriptObjInit(reg_t obj_pos) {
+Object *Script::scriptObjInit(reg_t obj_pos, bool fullObjectInit) {
Object *obj;
- if (getSciVersion() < SCI_VERSION_1_1)
+ if (getSciVersion() < SCI_VERSION_1_1 && fullObjectInit)
obj_pos.offset += 8; // magic offset (SCRIPT_OBJECT_MAGIC_OFFSET)
VERIFY(obj_pos.offset < _bufSize, "Attempt to initialize object beyond end of script\n");
@@ -239,7 +239,7 @@ Object *Script::scriptObjInit(reg_t obj_pos) {
VERIFY(obj_pos.offset + SCRIPT_FUNCTAREAPTR_OFFSET < (int)_bufSize, "Function area pointer stored beyond end of script\n");
- obj->init(_buf, obj_pos);
+ obj->init(_buf, obj_pos, fullObjectInit);
return obj;
}
@@ -680,7 +680,7 @@ void NodeTable::listAllOutgoingReferences(reg_t addr, void *param, NoteCallback
//-------------------- object ----------------------------
-void Object::init(byte *buf, reg_t obj_pos) {
+void Object::init(byte *buf, reg_t obj_pos, bool initVariables) {
byte *data = buf + obj_pos.offset;
_baseObj = data;
_pos = obj_pos;
@@ -697,8 +697,10 @@ void Object::init(byte *buf, reg_t obj_pos) {
_methodCount = READ_SCI11ENDIAN_UINT16(_baseMethod);
}
- for (uint i = 0; i < _variables.size(); i++)
- _variables[i] = make_reg(0, READ_SCI11ENDIAN_UINT16(data + (i * 2)));
+ if (initVariables) {
+ for (uint i = 0; i < _variables.size(); i++)
+ _variables[i] = make_reg(0, READ_SCI11ENDIAN_UINT16(data + (i * 2)));
+ }
}
const Object *Object::getClass(SegManager *segMan) const {
@@ -769,14 +771,15 @@ void Object::initSuperClass(SegManager *segMan, reg_t addr) {
setSuperClassSelector(segMan->getClassAddress(superClassOffset, SCRIPT_GET_LOCK, addr));
}
-bool Object::initBaseObject(SegManager *segMan, reg_t addr) {
+bool Object::initBaseObject(SegManager *segMan, reg_t addr, bool doInitSuperClass) {
const Object *baseObj = segMan->getObject(getSpeciesSelector());
if (baseObj) {
- setVarCount(baseObj->getVarCount());
+ _variables.resize(baseObj->getVarCount());
// Copy base from species class, as we need its selector IDs
_baseObj = baseObj->_baseObj;
- initSuperClass(segMan, addr);
+ if (doInitSuperClass)
+ initSuperClass(segMan, addr);
return true;
}
diff --git a/engines/sci/engine/segment.h b/engines/sci/engine/segment.h
index dce1eb8445..051354bf7a 100644
--- a/engines/sci/engine/segment.h
+++ b/engines/sci/engine/segment.h
@@ -270,10 +270,9 @@ public:
void markAsFreed() { _flags |= OBJECT_FLAG_FREED; }
bool isFreed() const { return _flags & OBJECT_FLAG_FREED; }
- void setVarCount(uint size) { _variables.resize(size); }
uint getVarCount() const { return _variables.size(); }
- void init(byte *buf, reg_t obj_pos);
+ void init(byte *buf, reg_t obj_pos, bool initVariables = true);
reg_t getVariable(uint var) const { return _variables[var]; }
reg_t &getVariableRef(uint var) { return _variables[var]; }
@@ -295,16 +294,17 @@ public:
void initSpecies(SegManager *segMan, reg_t addr);
void initSuperClass(SegManager *segMan, reg_t addr);
- bool initBaseObject(SegManager *segMan, reg_t addr);
+ bool initBaseObject(SegManager *segMan, reg_t addr, bool doInitSuperClass = true);
// TODO: make private
// Only SegManager::reconstructScripts() is left needing direct access to these
public:
const byte *_baseObj; /**< base + object offset within base */
+
+private:
const uint16 *_baseVars; /**< Pointer to the varselector area for this object */
const uint16 *_baseMethod; /**< Pointer to the method selector area for this object */
-private:
Common::Array<reg_t> _variables;
uint16 _methodCount;
int _flags;
@@ -394,7 +394,7 @@ public:
* @returns A newly created Object describing the object,
* stored within the relevant script
*/
- Object *scriptObjInit(reg_t obj_pos);
+ Object *scriptObjInit(reg_t obj_pos, bool fullObjectInit = true);
/**
* Removes a script object