diff options
author | Filippos Karapetis | 2010-06-26 23:13:05 +0000 |
---|---|---|
committer | Filippos Karapetis | 2010-06-26 23:13:05 +0000 |
commit | 3cf0114164aa07cdd2ae557ea49cf59a31ea5f67 (patch) | |
tree | 2139ce7a896d9e15e3617bc7020690d9b00b6495 /engines/sci | |
parent | 3dcebcb1bcf69bafc61ca4466b01237000533656 (diff) | |
download | scummvm-rg350-3cf0114164aa07cdd2ae557ea49cf59a31ea5f67.tar.gz scummvm-rg350-3cf0114164aa07cdd2ae557ea49cf59a31ea5f67.tar.bz2 scummvm-rg350-3cf0114164aa07cdd2ae557ea49cf59a31ea5f67.zip |
Moved script_instantiate_sci0() inside the segment manager, and renamed it to scriptInitialiseObjectsSci0()
svn-id: r50357
Diffstat (limited to 'engines/sci')
-rw-r--r-- | engines/sci/engine/script.cpp | 128 | ||||
-rw-r--r-- | engines/sci/engine/seg_manager.h | 1 |
2 files changed, 65 insertions, 64 deletions
diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp index 8f3792552f..5916428432 100644 --- a/engines/sci/engine/script.cpp +++ b/engines/sci/engine/script.cpp @@ -176,61 +176,8 @@ void SegManager::scriptInitialiseLocals(SegmentId segmentId) { } } -void SegManager::scriptInitialiseObjectsSci11(SegmentId seg) { +void SegManager::scriptInitialiseObjectsSci0(SegmentId seg) { Script *scr = getScript(seg); - const byte *seeker = scr->_heapStart;; - uint16 entrySize = READ_SCI11ENDIAN_UINT16(seeker + 2) * 2; - seeker += entrySize; // skip first entry - seeker += 4; // skip header - - while (READ_SCI11ENDIAN_UINT16(seeker) == SCRIPT_OBJECT_MAGIC_NUMBER) { - if (READ_SCI11ENDIAN_UINT16(seeker + 14) & kInfoFlagClass) { // -info- selector - int classpos = seeker - scr->_buf; - int species = READ_SCI11ENDIAN_UINT16(seeker + 10); - - if (species < 0 || species >= (int)_classTable.size()) { - error("Invalid species %d(0x%x) not in interval [0,%d) while instantiating script %d", - species, species, _classTable.size(), scr->_nr); - return; - } - - setClassOffset(species, make_reg(seg, classpos)); - } - seeker += READ_SCI11ENDIAN_UINT16(seeker + 2) * 2; - } - - seeker = scr->_heapStart + 4 + READ_SCI11ENDIAN_UINT16(scr->_heapStart + 2) * 2; - while (READ_SCI11ENDIAN_UINT16(seeker) == SCRIPT_OBJECT_MAGIC_NUMBER) { - reg_t reg = make_reg(seg, seeker - scr->_buf); - Object *obj = scr->scriptObjInit(reg); - - // Copy base from species class, as we need its selector IDs - obj->setSuperClassSelector( - getClassAddress(obj->getSuperClassSelector().offset, SCRIPT_GET_LOCK, NULL_REG)); - - // If object is instance, get -propDict- from class and set it for this object - // This is needed for ::isMemberOf() to work. - // Example testcase - room 381 of sq4cd - if isMemberOf() doesn't work, talk-clicks on the robot will act like - // clicking on ego - if (!obj->isClass()) { - reg_t classObject = obj->getSuperClassSelector(); - Object *classObj = getObject(classObject); - obj->setPropDictSelector(classObj->getPropDictSelector()); - } - - // Set the -classScript- selector to the script number. - // FIXME: As this selector is filled in at run-time, it is likely - // that it is supposed to hold a pointer. The Obj::isKindOf method - // uses this selector together with -propDict- to compare classes. - // For the purpose of Obj::isKindOf, using the script number appears - // to be sufficient. - obj->setClassScriptSelector(make_reg(0, scr->_nr)); - - seeker += READ_SCI11ENDIAN_UINT16(seeker + 2) * 2; - } -} - -void script_instantiate_sci0(Script *scr, int segmentId, SegManager *segMan) { int objType; reg_t addr; bool oldScriptHeader = (getSciVersion() == SCI_VERSION_0_EARLY); @@ -250,7 +197,7 @@ void script_instantiate_sci0(Script *scr, int segmentId, SegManager *segMan) { objLength = scr->getHeap(curOffset + 2); curOffset += 4; // skip header - addr = make_reg(segmentId, curOffset);; + addr = make_reg(seg, curOffset);; switch (objType) { case SCI_OBJ_OBJECT: @@ -259,24 +206,24 @@ void script_instantiate_sci0(Script *scr, int segmentId, SegManager *segMan) { int classpos = curOffset + 8; // SCRIPT_OBJECT_MAGIC_OFFSET int species = scr->getHeap(classpos); - if (species == (int)segMan->classTableSize()) { + if (species == (int)classTableSize()) { // Happens in the LSL2 demo warning("Applying workaround for an off-by-one invalid species access"); - segMan->resizeClassTable(segMan->classTableSize() + 1); - } else if (species < 0 || species > (int)segMan->classTableSize()) { + resizeClassTable(classTableSize() + 1); + } else if (species < 0 || species > (int)classTableSize()) { error("Invalid species %d(0x%x) not in interval " "[0,%d) while instantiating script at segment %d\n", - species, species, segMan->classTableSize(), - segmentId); + species, species, classTableSize(), + seg); return; } - segMan->setClassOffset(species, make_reg(segmentId, classpos)); + setClassOffset(species, make_reg(seg, classpos)); } else if (pass == 1) { Object *obj = scr->scriptObjInit(addr); - obj->initSpecies(segMan, addr); + obj->initSpecies(this, addr); - if (!obj->initBaseObject(segMan, addr)) { + if (!obj->initBaseObject(this, addr)) { error("Failed to locate base object for object at %04X:%04X; skipping", PRINT_REG(addr)); //scr->scriptObjRemove(addr); } @@ -290,7 +237,60 @@ void script_instantiate_sci0(Script *scr, int segmentId, SegManager *segMan) { curOffset += objLength - 4; } while (objType != 0 && curOffset < scr->getScriptSize() - 2); } // for +} + +void SegManager::scriptInitialiseObjectsSci11(SegmentId seg) { + Script *scr = getScript(seg); + const byte *seeker = scr->_heapStart;; + uint16 entrySize = READ_SCI11ENDIAN_UINT16(seeker + 2) * 2; + seeker += entrySize; // skip first entry + seeker += 4; // skip header + while (READ_SCI11ENDIAN_UINT16(seeker) == SCRIPT_OBJECT_MAGIC_NUMBER) { + if (READ_SCI11ENDIAN_UINT16(seeker + 14) & kInfoFlagClass) { // -info- selector + int classpos = seeker - scr->_buf; + int species = READ_SCI11ENDIAN_UINT16(seeker + 10); + + if (species < 0 || species >= (int)_classTable.size()) { + error("Invalid species %d(0x%x) not in interval [0,%d) while instantiating script %d", + species, species, _classTable.size(), scr->_nr); + return; + } + + setClassOffset(species, make_reg(seg, classpos)); + } + seeker += READ_SCI11ENDIAN_UINT16(seeker + 2) * 2; + } + + seeker = scr->_heapStart + 4 + READ_SCI11ENDIAN_UINT16(scr->_heapStart + 2) * 2; + while (READ_SCI11ENDIAN_UINT16(seeker) == SCRIPT_OBJECT_MAGIC_NUMBER) { + reg_t reg = make_reg(seg, seeker - scr->_buf); + Object *obj = scr->scriptObjInit(reg); + + // Copy base from species class, as we need its selector IDs + obj->setSuperClassSelector( + getClassAddress(obj->getSuperClassSelector().offset, SCRIPT_GET_LOCK, NULL_REG)); + + // If object is instance, get -propDict- from class and set it for this object + // This is needed for ::isMemberOf() to work. + // Example testcase - room 381 of sq4cd - if isMemberOf() doesn't work, talk-clicks on the robot will act like + // clicking on ego + if (!obj->isClass()) { + reg_t classObject = obj->getSuperClassSelector(); + Object *classObj = getObject(classObject); + obj->setPropDictSelector(classObj->getPropDictSelector()); + } + + // Set the -classScript- selector to the script number. + // FIXME: As this selector is filled in at run-time, it is likely + // that it is supposed to hold a pointer. The Obj::isKindOf method + // uses this selector together with -propDict- to compare classes. + // For the purpose of Obj::isKindOf, using the script number appears + // to be sufficient. + obj->setClassScriptSelector(make_reg(0, scr->_nr)); + + seeker += READ_SCI11ENDIAN_UINT16(seeker + 2) * 2; + } } int script_instantiate(ResourceManager *resMan, SegManager *segMan, int scriptNum) { @@ -315,7 +315,7 @@ int script_instantiate(ResourceManager *resMan, SegManager *segMan, int scriptNu segMan->scriptInitialiseObjectsSci11(segmentId); scr->relocate(make_reg(segmentId, READ_SCI11ENDIAN_UINT16(scr->_heapStart))); } else { - script_instantiate_sci0(scr, segmentId, segMan); + segMan->scriptInitialiseObjectsSci0(segmentId); byte *relocationBlock = scr->findBlock(SCI_OBJ_POINTERS); if (relocationBlock) scr->relocate(make_reg(segmentId, relocationBlock - scr->_buf + 4)); diff --git a/engines/sci/engine/seg_manager.h b/engines/sci/engine/seg_manager.h index 990836992c..037f3f0819 100644 --- a/engines/sci/engine/seg_manager.h +++ b/engines/sci/engine/seg_manager.h @@ -426,6 +426,7 @@ public: */ reg_t findObjectByName(const Common::String &name, int index = -1); + void scriptInitialiseObjectsSci0(SegmentId seg); void scriptInitialiseObjectsSci11(SegmentId seg); uint32 classTableSize() { return _classTable.size(); } |