From 205f7437ea668be302e22b278a106f27af23fabf Mon Sep 17 00:00:00 2001 From: Walter van Niftrik Date: Fri, 1 Jan 2010 23:48:22 +0000 Subject: SCI: Fix segfault in dual-language KQ5. svn-id: r46864 --- engines/sci/engine/seg_manager.cpp | 7 +++++++ engines/sci/engine/segment.h | 6 ++++++ engines/sci/engine/vm.cpp | 15 +++++++++++---- 3 files changed, 24 insertions(+), 4 deletions(-) (limited to 'engines/sci/engine') diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp index 4983d9b347..d68853a593 100644 --- a/engines/sci/engine/seg_manager.cpp +++ b/engines/sci/engine/seg_manager.cpp @@ -568,6 +568,13 @@ Object *Script::scriptObjInit(reg_t obj_pos) { return obj; } +void Script::scriptObjRemove(reg_t obj_pos) { + if (getSciVersion() < SCI_VERSION_1_1) + obj_pos.offset += 8; + + _objects.erase(obj_pos.toUint16()); +} + LocalVariables *SegManager::allocLocalsSegment(Script *scr, int count) { if (!count) { // No locals scr->_localsSegment = 0; diff --git a/engines/sci/engine/segment.h b/engines/sci/engine/segment.h index d8cdd91da8..62f970722e 100644 --- a/engines/sci/engine/segment.h +++ b/engines/sci/engine/segment.h @@ -380,6 +380,12 @@ public: */ Object *scriptObjInit(reg_t obj_pos); + /** + * Removes a script object + * @param obj_pos Location (segment, offset) of the object. + */ + void scriptObjRemove(reg_t obj_pos); + /** * Processes a relocation block witin a script * This function is idempotent, but it must only be called after all diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp index 9eb3b85981..4792454f1b 100644 --- a/engines/sci/engine/vm.cpp +++ b/engines/sci/engine/vm.cpp @@ -1644,11 +1644,18 @@ int script_instantiate_sci0(ResourceManager *resMan, SegManager *segMan, int scr obj->setSpeciesSelector(INST_LOOKUP_CLASS(obj->getSpeciesSelector().offset)); Object *baseObj = segMan->getObject(obj->getSpeciesSelector()); - obj->setVarCount(baseObj->getVarCount()); - // Copy base from species class, as we need its selector IDs - obj->_baseObj = baseObj->_baseObj; - obj->setSuperClassSelector(INST_LOOKUP_CLASS(obj->getSuperClassSelector().offset)); + if (baseObj) { + obj->setVarCount(baseObj->getVarCount()); + // Copy base from species class, as we need its selector IDs + obj->_baseObj = baseObj->_baseObj; + + obj->setSuperClassSelector(INST_LOOKUP_CLASS(obj->getSuperClassSelector().offset)); + } else { + warning("Failed to locate base object for object at %04X:%04X; skipping", PRINT_REG(addr)); + + scr->scriptObjRemove(addr); + } } // if object or class break; case SCI_OBJ_POINTERS: // A relocation table -- cgit v1.2.3