diff options
Diffstat (limited to 'engines')
-rw-r--r-- | engines/sci/engine/kscripts.cpp | 8 | ||||
-rw-r--r-- | engines/sci/engine/memobj.cpp | 26 | ||||
-rw-r--r-- | engines/sci/engine/memobj.h | 44 | ||||
-rw-r--r-- | engines/sci/engine/seg_manager.cpp | 81 | ||||
-rw-r--r-- | engines/sci/engine/seg_manager.h | 33 | ||||
-rw-r--r-- | engines/sci/engine/vm.cpp | 10 |
6 files changed, 105 insertions, 97 deletions
diff --git a/engines/sci/engine/kscripts.cpp b/engines/sci/engine/kscripts.cpp index f3689a6025..5aabd86732 100644 --- a/engines/sci/engine/kscripts.cpp +++ b/engines/sci/engine/kscripts.cpp @@ -318,9 +318,13 @@ reg_t kDisposeScript(EngineState *s, int, int argc, reg_t *argv) { } } -int is_heap_object(EngineState *s, reg_t pos) { +bool is_heap_object(EngineState *s, reg_t pos) { Object *obj = s->segMan->getObject(pos); - return (obj != NULL && (!(obj->flags & OBJECT_FLAG_FREED)) && (!s->segMan->scriptIsMarkedAsDeleted(pos.segment))); + if (obj == NULL) + return false; + if (obj->flags & OBJECT_FLAG_FREED) + return false; + return !s->segMan->scriptIsMarkedAsDeleted(pos.segment); } reg_t kIsObject(EngineState *s, int, int argc, reg_t *argv) { diff --git a/engines/sci/engine/memobj.cpp b/engines/sci/engine/memobj.cpp index 9ed5eb8758..4697e0a706 100644 --- a/engines/sci/engine/memobj.cpp +++ b/engines/sci/engine/memobj.cpp @@ -114,7 +114,21 @@ void Script::freeScript() { _codeBlocks.clear(); } -void Script::init() { +bool Script::init(int script_nr, ResourceManager *resMan) { + setScriptSize(script_nr, resMan); + + _buf = (byte *)malloc(_bufSize); + +#ifdef DEBUG_segMan + printf("_buf = %p ", _buf); +#endif + if (!_buf) { + freeScript(); + warning("Not enough memory space for script size"); + _bufSize = 0; + return false; + } + _localsOffset = 0; _localsBlock = NULL; @@ -124,6 +138,16 @@ void Script::init() { _markedAsDeleted = false; _objIndices = new IntMapper(); + + _nr = script_nr; + + _sciVersion = resMan->sciVersion(); + if (_sciVersion >= SCI_VERSION_1_1) + _heapStart = _buf + _scriptSize; + else + _heapStart = _buf; + + return true; } Object *Script::allocateObject(uint16 offset) { diff --git a/engines/sci/engine/memobj.h b/engines/sci/engine/memobj.h index 500d268bc5..0294fb01c9 100644 --- a/engines/sci/engine/memobj.h +++ b/engines/sci/engine/memobj.h @@ -258,6 +258,8 @@ protected: IntMapper *_objIndices; + SciVersion _sciVersion; + public: /** * Table for objects, contains property variables. @@ -279,7 +281,7 @@ public: ~Script(); void freeScript(); - void init(); + bool init(int script_nr, ResourceManager *resMan); virtual bool isValidOffset(uint16 offset) const; virtual byte *dereference(reg_t pointer, int *size); @@ -293,6 +295,43 @@ public: Object *allocateObject(uint16 offset); Object *getObject(uint16 offset); + /** + * Informs the segment manager that a code block must be relocated + * @param location Start of block to relocate + */ + void scriptAddCodeBlock(reg_t location); + + /** + * Initializes an object within the segment manager + * @param obj_pos Location (segment, offset) of the object. It must + * point to the beginning of the script/class block + * (as opposed to what the VM considers to be the + * object location) + * @returns A newly created Object describing the object, + * stored within the relevant script + */ + Object *scriptObjInit(reg_t obj_pos); + + /** + * Processes a relocation block witin a script + * This function is idempotent, but it must only be called after all + * objects have been instantiated, or a run-time error will occur. + * @param obj_pos Location (segment, offset) of the block + * @return Location of the relocation block + */ + void scriptRelocate(reg_t block); + + void heapRelocate(reg_t block); + +private: + int relocateLocal(SegmentId segment, int location); + int relocateBlock(Common::Array<reg_t> &block, int block_location, SegmentId segment, int location); + int relocateObject(Object *obj, SegmentId segment, int location); + + Object *scriptObjInit0(reg_t obj_pos); + Object *scriptObjInit11(reg_t obj_pos); + +public: // script lock operations /** Increments the number of lockers of this script by one. */ @@ -382,6 +421,9 @@ public: * @return the value read from the specified location */ int16 getHeap(uint16 offset) const; + +private: + void setScriptSize(int script_nr, ResourceManager *resMan); }; /** Data stack */ diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp index 5e6d15a1d4..e2c56852fa 100644 --- a/engines/sci/engine/seg_manager.cpp +++ b/engines/sci/engine/seg_manager.cpp @@ -133,7 +133,8 @@ Script *SegManager::allocateScript(int script_nr, SegmentId *seg_id) { return (Script *)mem; } -void SegManager::setScriptSize(Script &scr, int script_nr) { +void Script::setScriptSize(int script_nr, ResourceManager *_resMan) { + Script &scr = *this; // FIXME: Hack Resource *script = _resMan->findResource(ResourceId(kResourceTypeScript, script_nr), 0); Resource *heap = _resMan->findResource(ResourceId(kResourceTypeHeap, script_nr), 0); bool oldScriptHeader = (_resMan->sciVersion() == SCI_VERSION_0_EARLY); @@ -169,34 +170,6 @@ void SegManager::setScriptSize(Script &scr, int script_nr) { } } -int SegManager::initialiseScript(Script &scr, int script_nr) { - // allocate the script._buf - - setScriptSize(scr, script_nr); - scr._buf = (byte *)malloc(scr._bufSize); - -#ifdef DEBUG_segMan - printf("scr._buf = %p ", scr._buf); -#endif - if (!scr._buf) { - scr.freeScript(); - warning("SegManager: Not enough memory space for script size"); - scr._bufSize = 0; - return 0; - } - - // Initialize objects - scr.init(); - scr._nr = script_nr; - - if (_resMan->sciVersion() >= SCI_VERSION_1_1) - scr._heapStart = scr._buf + scr._scriptSize; - else - scr._heapStart = scr._buf; - - return 1; -} - int SegManager::deallocate(SegmentId seg, bool recursive) { MemObject *mobj; VERIFY(check(seg), "invalid seg id"); @@ -332,7 +305,7 @@ void SegManager::setExportAreWide(bool flag) { _exportsAreWide = flag; } -int SegManager::relocateBlock(Common::Array<reg_t> &block, int block_location, SegmentId segment, int location) { +int Script::relocateBlock(Common::Array<reg_t> &block, int block_location, SegmentId segment, int location) { int rel = location - block_location; if (rel < 0) @@ -348,34 +321,32 @@ int SegManager::relocateBlock(Common::Array<reg_t> &block, int block_location, S return 0; } block[idx].segment = segment; // Perform relocation - if (_resMan->sciVersion() >= SCI_VERSION_1_1) - block[idx].offset += getScript(segment)->_scriptSize; + if (_sciVersion >= SCI_VERSION_1_1) + block[idx].offset += _scriptSize; return 1; } -int SegManager::relocateLocal(Script *scr, SegmentId segment, int location) { - if (scr->_localsBlock) - return relocateBlock(scr->_localsBlock->_locals, scr->_localsOffset, segment, location); +int Script::relocateLocal(SegmentId segment, int location) { + if (_localsBlock) + return relocateBlock(_localsBlock->_locals, _localsOffset, segment, location); else return 0; // No hands, no cookies } -int SegManager::relocateObject(Object *obj, SegmentId segment, int location) { +int Script::relocateObject(Object *obj, SegmentId segment, int location) { return relocateBlock(obj->_variables, obj->pos.offset, segment, location); } -void SegManager::scriptAddCodeBlock(reg_t location) { - Script *scr = getScript(location.segment); - +void Script::scriptAddCodeBlock(reg_t location) { CodeBlock cb; cb.pos = location; - cb.size = READ_LE_UINT16(scr->_buf + location.offset - 2); - scr->_codeBlocks.push_back(cb); + cb.size = READ_LE_UINT16(_buf + location.offset - 2); + _codeBlocks.push_back(cb); } -void SegManager::scriptRelocate(reg_t block) { - Script *scr = getScript(block.segment); +void Script::scriptRelocate(reg_t block) { + Script *scr = this; // FIXME: Hack VERIFY(block.offset < (uint16)scr->_bufSize && READ_LE_UINT16(scr->_buf + block.offset) * 2 + block.offset < (uint16)scr->_bufSize, "Relocation block outside of script\n"); @@ -387,7 +358,7 @@ void SegManager::scriptRelocate(reg_t block) { if (!pos) continue; // FIXME: A hack pending investigation - if (!relocateLocal(scr, block.segment, pos)) { + if (!relocateLocal(block.segment, pos)) { bool done = false; uint k; @@ -418,8 +389,8 @@ void SegManager::scriptRelocate(reg_t block) { } } -void SegManager::heapRelocate(reg_t block) { - Script *scr = getScript(block.segment); +void Script::heapRelocate(reg_t block) { + Script *scr = this; // FIXME: Hack VERIFY(block.offset < (uint16)scr->_heapSize && READ_LE_UINT16(scr->_heapStart + block.offset) * 2 + block.offset < (uint16)scr->_bufSize, "Relocation block outside of script\n"); @@ -432,7 +403,7 @@ void SegManager::heapRelocate(reg_t block) { for (int i = 0; i < count; i++) { int pos = READ_LE_UINT16(scr->_heapStart + block.offset + 2 + (i * 2)) + scr->_scriptSize; - if (!relocateLocal(scr, block.segment, pos)) { + if (!relocateLocal(block.segment, pos)) { bool done = false; uint k; @@ -504,12 +475,12 @@ reg_t SegManager::getClassAddress(int classnr, ScriptLoadType lock, reg_t caller } } -Object *SegManager::scriptObjInit0(reg_t obj_pos) { +Object *Script::scriptObjInit0(reg_t obj_pos) { Object *obj; - SciVersion version = _resMan->sciVersion(); // for the offset defines + SciVersion version = _sciVersion; // for the offset defines uint base = obj_pos.offset - SCRIPT_OBJECT_MAGIC_OFFSET; - Script *scr = getScript(obj_pos.segment); + Script *scr = this; // FIXME: Hack VERIFY(base < scr->_bufSize, "Attempt to initialize object beyond end of script\n"); @@ -553,11 +524,11 @@ Object *SegManager::scriptObjInit0(reg_t obj_pos) { return obj; } -Object *SegManager::scriptObjInit11(reg_t obj_pos) { +Object *Script::scriptObjInit11(reg_t obj_pos) { Object *obj; uint base = obj_pos.offset; - Script *scr = getScript(obj_pos.segment); + Script *scr = this; // FIXME: Hack VERIFY(base < scr->_bufSize, "Attempt to initialize object beyond end of script\n"); @@ -602,8 +573,8 @@ Object *SegManager::scriptObjInit11(reg_t obj_pos) { return obj; } -Object *SegManager::scriptObjInit(reg_t obj_pos) { - if (_resMan->sciVersion() < SCI_VERSION_1_1) +Object *Script::scriptObjInit(reg_t obj_pos) { + if (_sciVersion < SCI_VERSION_1_1) return scriptObjInit0(obj_pos); else return scriptObjInit11(obj_pos); @@ -715,7 +686,7 @@ void SegManager::scriptInitialiseObjectsSci11(SegmentId seg) { reg.segment = seg; reg.offset = seeker - scr->_buf; - obj = scriptObjInit(reg); + obj = scr->scriptObjInit(reg); #if 0 if (obj->_variables[5].offset != 0xffff) { diff --git a/engines/sci/engine/seg_manager.h b/engines/sci/engine/seg_manager.h index 9b274890d5..a4a7851fac 100644 --- a/engines/sci/engine/seg_manager.h +++ b/engines/sci/engine/seg_manager.h @@ -156,38 +156,12 @@ public: void scriptInitialiseLocals(reg_t location); /** - * Initializes an object within the segment manager - * @param obj_pos Location (segment, offset) of the object. It must - * point to the beginning of the script/class block - * (as opposed to what the VM considers to be the - * object location) - * @returns A newly created Object describing the object, - * stored within the relevant script - */ - Object *scriptObjInit(reg_t obj_pos); - - /** - * Informs the segment manager that a code block must be relocated - * @param location Start of block to relocate - */ - void scriptAddCodeBlock(reg_t location); - - /** * Tells the segment manager whether exports are wide (32-bit) or not. * @param flag true if exports are wide, false otherwise */ void setExportAreWide(bool flag); /** - * Processes a relocation block witin a script - * This function is idempotent, but it must only be called after all - * objects have been instantiated, or a run-time error will occur. - * @param obj_pos Location (segment, offset) of the block - * @return Location of the relocation block - */ - void scriptRelocate(reg_t block); - - /** * Determines whether the script referenced by the indicated segment * is marked as being deleted. * Will return 0 when applied to an invalid or non-script seg. @@ -387,10 +361,8 @@ public: */ const char *getObjectName(reg_t pos); - void heapRelocate(reg_t block); void scriptRelocateExportsSci11(SegmentId seg); void scriptInitialiseObjectsSci11(SegmentId seg); - int initialiseScript(Script &scr, int script_nr); SciVersion sciVersion() { return _resMan->sciVersion(); } @@ -417,12 +389,7 @@ private: Hunk *alloc_Hunk(reg_t *); - int relocateLocal(Script *scr, SegmentId segment, int location); - int relocateBlock(Common::Array<reg_t> &block, int block_location, SegmentId segment, int location); - int relocateObject(Object *obj, SegmentId segment, int location); - SegmentId findFreeSegment() const; - void setScriptSize(Script &scr, int script_nr); Object *scriptObjInit0(reg_t obj_pos); Object *scriptObjInit11(reg_t obj_pos); diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp index 69366758ea..dc22666188 100644 --- a/engines/sci/engine/vm.cpp +++ b/engines/sci/engine/vm.cpp @@ -1546,7 +1546,7 @@ int script_instantiate_common(ResourceManager *resMan, SegManager *segMan, int s } } - segMan->initialiseScript(*scr, script_nr); + scr->init(script_nr, resMan); reg.segment = seg_id; reg.offset = 0; @@ -1688,11 +1688,11 @@ int script_instantiate_sci0(ResourceManager *resMan, SegManager *segMan, int scr switch (objtype) { case SCI_OBJ_CODE: - segMan->scriptAddCodeBlock(addr); + scr->scriptAddCodeBlock(addr); break; case SCI_OBJ_OBJECT: case SCI_OBJ_CLASS: { // object or class? - Object *obj = segMan->scriptObjInit(addr); + Object *obj = scr->scriptObjInit(addr); Object *base_obj; // Instantiate the superclass, if neccessary @@ -1717,7 +1717,7 @@ int script_instantiate_sci0(ResourceManager *resMan, SegManager *segMan, int scr } while (objtype != 0 && reg.offset < script->size - 2); if (relocation >= 0) - segMan->scriptRelocate(make_reg(seg_id, relocation)); + scr->scriptRelocate(make_reg(seg_id, relocation)); return reg.segment; // instantiation successful } @@ -1753,7 +1753,7 @@ int script_instantiate_sci11(ResourceManager *resMan, SegManager *segMan, int sc segMan->scriptInitialiseObjectsSci11(seg_id); reg.offset = READ_LE_UINT16(heap->data); - segMan->heapRelocate(reg); + scr->heapRelocate(reg); return seg_id; } |