diff options
-rw-r--r-- | engines/sci/engine/script.cpp | 74 | ||||
-rw-r--r-- | engines/sci/engine/script.h | 24 | ||||
-rw-r--r-- | engines/sci/engine/seg_manager.h | 21 |
3 files changed, 63 insertions, 56 deletions
diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp index 748a8f9140..18244c7906 100644 --- a/engines/sci/engine/script.cpp +++ b/engines/sci/engine/script.cpp @@ -384,34 +384,31 @@ SegmentRef Script::dereference(reg_t pointer) { return ret; } -void SegManager::scriptInitialiseLocals(SegmentId segmentId) { - Script *scr = getScript(segmentId); - - LocalVariables *locals = allocLocalsSegment(scr); +void Script::initialiseLocals(SegManager *segMan) { + LocalVariables *locals = segMan->allocLocalsSegment(this); if (locals) { if (getSciVersion() > SCI_VERSION_0_EARLY) { - const byte *base = (const byte *)(scr->_buf + scr->getLocalsOffset()); + const byte *base = (const byte *)(_buf + getLocalsOffset()); - for (uint16 i = 0; i < scr->getLocalsCount(); i++) + for (uint16 i = 0; i < 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++) + for (uint16 i = 0; i < getLocalsCount(); i++) locals->_locals[i] = NULL_REG; } } } -void SegManager::scriptInitialiseClasses(SegmentId seg) { - Script *scr = getScript(seg); +void Script::initialiseClasses(SegManager *segMan) { const byte *seeker = 0; uint16 mult = 0; if (getSciVersion() >= SCI_VERSION_1_1) { - seeker = scr->_heapStart + 4 + READ_SCI11ENDIAN_UINT16(scr->_heapStart + 2) * 2; + seeker = _heapStart + 4 + READ_SCI11ENDIAN_UINT16(_heapStart + 2) * 2; mult = 2; } else { - seeker = scr->findBlock(SCI_OBJ_CLASS); + seeker = findBlock(SCI_OBJ_CLASS); mult = 1; } @@ -422,7 +419,7 @@ void SegManager::scriptInitialiseClasses(SegmentId seg) { // In SCI0-SCI1, this is the segment type. In SCI11, it's a marker (0x1234) uint16 marker = READ_SCI11ENDIAN_UINT16(seeker); bool isClass; - uint16 classpos = seeker - scr->_buf; + uint16 classpos = seeker - _buf; int16 species; if (!marker) @@ -439,24 +436,25 @@ void SegManager::scriptInitialiseClasses(SegmentId seg) { if (isClass) { // WORKAROUND for an invalid species access in the demo of LSL2 - if (g_sci->getGameId() == GID_LSL2 && g_sci->isDemo() && species == (int)classTableSize()) - resizeClassTable(classTableSize() + 1); + if (g_sci->getGameId() == GID_LSL2 && g_sci->isDemo() && species == (int)segMan->classTableSize()) + segMan->resizeClassTable(segMan->classTableSize() + 1); - if (species < 0 || species >= (int)classTableSize()) + if (species < 0 || species >= (int)segMan->classTableSize()) error("Invalid species %d(0x%x) not in interval [0,%d) while instantiating script %d\n", - species, species, classTableSize(), scr->_nr); + species, species, segMan->classTableSize(), _nr); - setClassOffset(species, make_reg(seg, classpos)); + SegmentId segmentId = segMan->getScriptSegment(_nr); + segMan->setClassOffset(species, make_reg(segmentId, classpos)); } seeker += READ_SCI11ENDIAN_UINT16(seeker + 2) * mult; } } -void SegManager::scriptInitialiseObjectsSci0(SegmentId seg) { - Script *scr = getScript(seg); +void Script::initialiseObjectsSci0(SegManager *segMan) { bool oldScriptHeader = (getSciVersion() == SCI_VERSION_0_EARLY); - const byte *seeker = scr->_buf + (oldScriptHeader ? 2 : 0); + const byte *seeker = _buf + (oldScriptHeader ? 2 : 0); + SegmentId segmentId = segMan->getScriptSegment(_nr); do { uint16 objType = READ_SCI11ENDIAN_UINT16(seeker); @@ -467,14 +465,14 @@ void SegManager::scriptInitialiseObjectsSci0(SegmentId seg) { case SCI_OBJ_OBJECT: case SCI_OBJ_CLASS: { - reg_t addr = make_reg(seg, seeker - scr->_buf + 4); - Object *obj = scr->scriptObjInit(addr); - obj->initSpecies(this, addr); + reg_t addr = make_reg(segmentId, seeker - _buf + 4); + Object *obj = scriptObjInit(addr); + obj->initSpecies(segMan, addr); - if (!obj->initBaseObject(this, addr)) { + if (!obj->initBaseObject(segMan, addr)) { // Script 202 of KQ5 French has an invalid object. This is non-fatal. warning("Failed to locate base object for object at %04X:%04X; skipping", PRINT_REG(addr)); - scr->scriptObjRemove(addr); + scriptObjRemove(addr); } } break; @@ -484,20 +482,20 @@ void SegManager::scriptInitialiseObjectsSci0(SegmentId seg) { } seeker += READ_SCI11ENDIAN_UINT16(seeker + 2); - } while ((uint32)(seeker - scr->_buf) < scr->getScriptSize() - 2); + } while ((uint32)(seeker - _buf) < getScriptSize() - 2); } -void SegManager::scriptInitialiseObjectsSci11(SegmentId seg) { - Script *scr = getScript(seg); - const byte *seeker = scr->_heapStart + 4 + READ_SCI11ENDIAN_UINT16(scr->_heapStart + 2) * 2; +void Script::initialiseObjectsSci11(SegManager *segMan) { + const byte *seeker = _heapStart + 4 + READ_SCI11ENDIAN_UINT16(_heapStart + 2) * 2; + SegmentId segmentId = segMan->getScriptSegment(_nr); while (READ_SCI11ENDIAN_UINT16(seeker) == SCRIPT_OBJECT_MAGIC_NUMBER) { - reg_t reg = make_reg(seg, seeker - scr->_buf); - Object *obj = scr->scriptObjInit(reg); + reg_t reg = make_reg(segmentId, seeker - _buf); + Object *obj = scriptObjInit(reg); // Copy base from species class, as we need its selector IDs obj->setSuperClassSelector( - getClassAddress(obj->getSuperClassSelector().offset, SCRIPT_GET_LOCK, NULL_REG)); + segMan->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. @@ -505,7 +503,7 @@ void SegManager::scriptInitialiseObjectsSci11(SegmentId seg) { // clicking on ego if (!obj->isClass()) { reg_t classObject = obj->getSuperClassSelector(); - Object *classObj = getObject(classObject); + Object *classObj = segMan->getObject(classObject); obj->setPropDictSelector(classObj->getPropDictSelector()); } @@ -515,7 +513,7 @@ void SegManager::scriptInitialiseObjectsSci11(SegmentId seg) { // 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)); + obj->setClassScriptSelector(make_reg(0, _nr)); seeker += READ_SCI11ENDIAN_UINT16(seeker + 2) * 2; } @@ -537,14 +535,14 @@ int script_instantiate(ResourceManager *resMan, SegManager *segMan, int scriptNu scr->init(scriptNum, resMan); scr->load(resMan); - segMan->scriptInitialiseLocals(segmentId); - segMan->scriptInitialiseClasses(segmentId); + scr->initialiseLocals(segMan); + scr->initialiseClasses(segMan); if (getSciVersion() >= SCI_VERSION_1_1) { - segMan->scriptInitialiseObjectsSci11(segmentId); + scr->initialiseObjectsSci11(segMan); scr->relocate(make_reg(segmentId, READ_SCI11ENDIAN_UINT16(scr->_heapStart))); } else { - segMan->scriptInitialiseObjectsSci0(segmentId); + scr->initialiseObjectsSci0(segMan); byte *relocationBlock = scr->findBlock(SCI_OBJ_POINTERS); if (relocationBlock) scr->relocate(make_reg(segmentId, relocationBlock - scr->_buf + 4)); diff --git a/engines/sci/engine/script.h b/engines/sci/engine/script.h index 62d2228c9a..cc3c0263e8 100644 --- a/engines/sci/engine/script.h +++ b/engines/sci/engine/script.h @@ -140,6 +140,30 @@ public: */ void relocate(reg_t block); + /** + * Initializes the script's local variables + * @param segMan A reference to the segment manager + */ + void initialiseLocals(SegManager *segMan); + + /** + * Adds the script's classes to the segment manager's class table + * @param segMan A reference to the segment manager + */ + void initialiseClasses(SegManager *segMan); + + /** + * Initializes the script's objects (SCI0) + * @param segMan A reference to the segment manager + */ + void initialiseObjectsSci0(SegManager *segMan); + + /** + * Initializes the script's objects (SCI1.1+) + * @param segMan A reference to the segment manager + */ + void initialiseObjectsSci11(SegManager *segMan); + private: bool relocateLocal(SegmentId segment, int location); diff --git a/engines/sci/engine/seg_manager.h b/engines/sci/engine/seg_manager.h index 19fd06f596..324527400b 100644 --- a/engines/sci/engine/seg_manager.h +++ b/engines/sci/engine/seg_manager.h @@ -139,19 +139,6 @@ public: */ Script *getScriptIfLoaded(SegmentId seg); - - // 1b. Script Initialisation - - // The set of functions below are intended - // to be used during script instantiation, - // i.e. loading and linking. - - /** - * Initializes a script's local variable block according to a prototype - * @param segmentId Segment containing the script to initialize - */ - void scriptInitialiseLocals(SegmentId segmentId); - // 2. Clones /** @@ -427,10 +414,6 @@ public: */ reg_t findObjectByName(const Common::String &name, int index = -1); - void scriptInitialiseClasses(SegmentId seg); - void scriptInitialiseObjectsSci0(SegmentId seg); - void scriptInitialiseObjectsSci11(SegmentId seg); - uint32 classTableSize() { return _classTable.size(); } Class getClass(int index) { return _classTable[index]; } void setClassOffset(int index, reg_t offset) { _classTable[index].reg = offset; } @@ -481,7 +464,6 @@ private: private: SegmentObj *allocSegment(SegmentObj *mem, SegmentId *segid); - LocalVariables *allocLocalsSegment(Script *scr); int deallocate(SegmentId seg, bool recursive); void createClassTable(); @@ -494,6 +476,9 @@ private: * 'seg' is a valid segment */ bool check(SegmentId seg); + +public: + LocalVariables *allocLocalsSegment(Script *scr); }; } // End of namespace Sci |