diff options
author | Max Horn | 2009-05-15 09:27:07 +0000 |
---|---|---|
committer | Max Horn | 2009-05-15 09:27:07 +0000 |
commit | 75c0d719c9d79eb1093c997960b3c6239c5a8a29 (patch) | |
tree | d355e42a21241f9ec0388354ac4d1b6b29cfa2b6 /engines | |
parent | 565cfa074d25fbfc2458a65fe8fc300d78a2afa8 (diff) | |
download | scummvm-rg350-75c0d719c9d79eb1093c997960b3c6239c5a8a29.tar.gz scummvm-rg350-75c0d719c9d79eb1093c997960b3c6239c5a8a29.tar.bz2 scummvm-rg350-75c0d719c9d79eb1093c997960b3c6239c5a8a29.zip |
SCI: Turned several script related SegManager methods into Script methods
svn-id: r40597
Diffstat (limited to 'engines')
-rw-r--r-- | engines/sci/engine/kscripts.cpp | 6 | ||||
-rw-r--r-- | engines/sci/engine/kstring.cpp | 4 | ||||
-rw-r--r-- | engines/sci/engine/savegame.cpp | 2 | ||||
-rw-r--r-- | engines/sci/engine/scriptdebug.cpp | 2 | ||||
-rw-r--r-- | engines/sci/engine/seg_manager.cpp | 89 | ||||
-rw-r--r-- | engines/sci/engine/seg_manager.h | 102 | ||||
-rw-r--r-- | engines/sci/engine/vm.cpp | 112 | ||||
-rw-r--r-- | engines/sci/engine/vm.h | 88 |
8 files changed, 180 insertions, 225 deletions
diff --git a/engines/sci/engine/kscripts.cpp b/engines/sci/engine/kscripts.cpp index 3ce2ebb5a7..b66647e390 100644 --- a/engines/sci/engine/kscripts.cpp +++ b/engines/sci/engine/kscripts.cpp @@ -184,8 +184,8 @@ reg_t kClone(EngineState *s, int funct_nr, int argc, reg_t *argv) { clone_obj->_variables[SCRIPT_SPECIES_SELECTOR] = clone_obj->pos; if (IS_CLASS(parent_obj)) clone_obj->_variables[SCRIPT_SUPERCLASS_SELECTOR] = parent_obj->pos; - s->seg_manager->incrementLockers(parent_obj->pos.segment, SEG_ID); - s->seg_manager->incrementLockers(clone_obj->pos.segment, SEG_ID); + s->seg_manager->getScript(parent_obj->pos.segment, SEG_ID)->incrementLockers(); + s->seg_manager->getScript(clone_obj->pos.segment, SEG_ID)->incrementLockers(); return clone_addr; } @@ -269,7 +269,7 @@ reg_t kDisposeScript(EngineState *s, int funct_nr, int argc, reg_t *argv) { int id = s->seg_manager->segGet(script); if (s->_executionStack[s->execution_stack_pos].addr.pc.segment != id) - s->seg_manager->setLockers(1, script, SCRIPT_ID); + s->seg_manager->getScript(id, SEG_ID)->setLockers(1); } script_uninstantiate(s, script); diff --git a/engines/sci/engine/kstring.cpp b/engines/sci/engine/kstring.cpp index e7149e51df..9c9eb6ede8 100644 --- a/engines/sci/engine/kstring.cpp +++ b/engines/sci/engine/kstring.cpp @@ -200,12 +200,12 @@ reg_t kSetSynonyms(EngineState *s, int funct_nr, int argc, reg_t *argv) { seg = s->seg_manager->segGet(script); if (seg >= 0) - synonyms_nr = s->seg_manager->getSynonymsNr(seg, SEG_ID); + synonyms_nr = s->seg_manager->getScript(seg, SEG_ID)->getSynonymsNr(); if (synonyms_nr) { byte *synonyms; - synonyms = s->seg_manager->getSynonyms(seg, SEG_ID); + synonyms = s->seg_manager->getScript(seg, SEG_ID)->getSynonyms(); if (synonyms) { SCIkdebug(SCIkPARSER, "Setting %d synonyms for script.%d\n", synonyms_nr, script); diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp index 51c3059329..69275e8ada 100644 --- a/engines/sci/engine/savegame.cpp +++ b/engines/sci/engine/savegame.cpp @@ -343,7 +343,7 @@ static void sync_Script(Common::Serializer &s, Script &obj) { s.syncAsSint32LE(obj.locals_offset); s.syncAsSint32LE(obj.locals_segment); - s.syncAsSint32LE(obj.marked_as_deleted); + s.syncAsSint32LE(obj._markedAsDeleted); } static void sync_SystemString(Common::Serializer &s, SystemString &obj) { diff --git a/engines/sci/engine/scriptdebug.cpp b/engines/sci/engine/scriptdebug.cpp index e54efdc5d8..ae538554d7 100644 --- a/engines/sci/engine/scriptdebug.cpp +++ b/engines/sci/engine/scriptdebug.cpp @@ -639,7 +639,7 @@ int c_segkill(EngineState *s, const Common::Array<cmd_param_t> &cmdParams) { while (i < cmdParams.size()) { int nr = cmdParams[i++].val; - s->seg_manager->setLockers(nr, 0, SEG_ID); + s->seg_manager->getScript(nr, SEG_ID)->setLockers(0); } return 0; } diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp index 848c3a044d..b4cbc75d55 100644 --- a/engines/sci/engine/seg_manager.cpp +++ b/engines/sci/engine/seg_manager.cpp @@ -193,7 +193,7 @@ int SegManager::initialiseScript(Script &scr, EngineState *s, int script_nr) { scr._codeBlocks.clear(); scr.nr = script_nr; - scr.marked_as_deleted = 0; + scr._markedAsDeleted = false; scr.relocated = 0; scr.obj_indices = new IntMapper(); @@ -251,33 +251,18 @@ int SegManager::deallocate(int seg, bool recursive) { return 1; } -int SegManager::scriptMarkedDeleted(int script_nr) { - Script *scr = getScript(script_nr, SCRIPT_ID); - return scr->marked_as_deleted; -} - -void SegManager::markScriptDeleted(int script_nr) { - Script *scr = getScript(script_nr, SCRIPT_ID); - scr->marked_as_deleted = 1; -} - -void SegManager::unmarkScriptDeleted(int script_nr) { - Script *scr = getScript(script_nr, SCRIPT_ID); - scr->marked_as_deleted = 0; -} - -int SegManager::scriptIsMarkedAsDeleted(SegmentId seg) { +bool SegManager::scriptIsMarkedAsDeleted(SegmentId seg) { Script *scr; if (!check(seg)) - return 0; + return false; if (_heap[seg]->getType() != MEM_OBJ_SCRIPT) - return 0; + return false; scr = (Script *)_heap[seg]; - return scr->marked_as_deleted; + return scr->_markedAsDeleted; } @@ -371,10 +356,10 @@ void Script::freeScript() { // memory operations -void SegManager::mcpyInOut(int dst, const void *src, size_t n, int id, idFlag flag) { - Script *scr = getScript(id, flag); - if (scr->buf) { - memcpy(scr->buf + dst, src, n); +void Script::mcpyInOut(int dst, const void *src, size_t n) { + if (buf) { + assert(dst + n <= buf_size); + memcpy(buf + dst, src, n); } } @@ -439,36 +424,30 @@ int SegManager::scriptIsLoaded(int id, idFlag flag) { return check(id); } -void SegManager::incrementLockers(int id, idFlag flag) { - Script *scr = getScript(id, flag); - scr->lockers++; +void Script::incrementLockers() { + lockers++; } -void SegManager::decrementLockers(int id, idFlag flag) { - Script *scr = getScript(id, flag); - if (scr->lockers > 0) - scr->lockers--; +void Script::decrementLockers() { + if (lockers > 0) + lockers--; } -int SegManager::getLockers(int id, idFlag flag) { - Script *scr = getScript(id, flag); - return scr->lockers; +int Script::getLockers() const { + return lockers; } -void SegManager::setLockers(int lockers, int id, idFlag flag) { - Script *scr = getScript(id, flag); - scr->lockers = lockers; +void Script::setLockers(int lockers_) { + lockers = lockers_; } -void SegManager::setExportTableOffset(int offset, int id, idFlag flag) { - Script *scr = getScript(id, flag); - +void Script::setExportTableOffset(int offset) { if (offset) { - scr->export_table = (uint16 *)(scr->buf + offset + 2); - scr->exports_nr = READ_LE_UINT16((byte *)(scr->export_table - 1)); + export_table = (uint16 *)(buf + offset + 2); + exports_nr = READ_LE_UINT16((byte *)(export_table - 1)); } else { - scr->export_table = NULL; - scr->exports_nr = 0; + export_table = NULL; + exports_nr = 0; } } @@ -476,24 +455,20 @@ void SegManager::setExportWidth(int flag) { exports_wide = flag; } -void SegManager::setSynonymsOffset(int offset, int id, idFlag flag) { - Script *scr = getScript(id, flag); - scr->synonyms = scr->buf + offset; +void Script::setSynonymsOffset(int offset) { + synonyms = buf + offset; } -byte *SegManager::getSynonyms(int id, idFlag flag) { - Script *scr = getScript(id, flag); - return scr->synonyms; +byte *Script::getSynonyms() const { + return synonyms; } -void SegManager::setSynonymsNr(int nr, int id, idFlag flag) { - Script *scr = getScript(id, flag); - scr->synonyms_nr = nr; +void Script::setSynonymsNr(int n) { + synonyms_nr = n; } -int SegManager::getSynonymsNr(int id, idFlag flag) { - Script *scr = getScript(id, flag); - return scr->synonyms_nr; +int Script::getSynonymsNr() const { + return synonyms_nr; } int SegManager::relocateBlock(Common::Array<reg_t> &block, int block_location, SegmentId segment, int location) { @@ -1149,7 +1124,7 @@ void Script::freeAtAddress(SegManager *segmgr, reg_t addr) { sciprintf("[GC] Freeing locals %04x:0000\n", locals_segment); */ - if (marked_as_deleted) + if (_markedAsDeleted) segmgr->deallocateScript(nr); } diff --git a/engines/sci/engine/seg_manager.h b/engines/sci/engine/seg_manager.h index f68fa6a23a..9521d84b7b 100644 --- a/engines/sci/engine/seg_manager.h +++ b/engines/sci/engine/seg_manager.h @@ -97,55 +97,6 @@ public: Script *getScript(int id, idFlag flag); - // script lock operations - - // Increments the number of lockers of the script in question by one - // Parameters: (int) id: ID of the script or script segment to modify - // (idFlag) flag: Whether to address the script by script number (SCRIPT_ID) or - // by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID, - // but less convenient. - void incrementLockers(int id, idFlag flag); - - // Decrements the number of lockers of the script in question by one - // Parameters: (int) id: ID of the script or script segment to modify - // (idFlag) flag: Whether to address the script by script number (SCRIPT_ID) or - // by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID, - // but less convenient. - void decrementLockers(int id, idFlag flag); - - // Retrieves the number of locks held on this script - // Parameters: (int) id: ID of the script or script segment to read from - // (idFlag) flag: Whether to address the script by script number (SCRIPT_ID) or - // by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID, - // but less convenient. - // Returns : (int) The number of locks held on the previously identified script - int getLockers(int id, idFlag flag); - - // Sets the number of locks held on the specified script - // Parameters: (int) id: ID of the script or script segment to modify - // (idFlag) flag: Whether to address the script by script number (SCRIPT_ID) or - // by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID, - // but less convenient. - void setLockers(int lockers, int id, idFlag flag); - - // Retrieves a pointer to the synonyms associated with the specified script - // Parameters: (int) id: ID of the script or script segment to read from - // (idFlag) flag: Whether to address the script by script number (SCRIPT_ID) or - // by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID, - // but less convenient. - // Returns : (byte *) Pointer to the synonyms, in non-parsed format. - // A dynamic failure is issued if the specified ID does not reference a proper script. - byte *getSynonyms(int id, idFlag flag); - - // Retrieves the number of synonyms associated with the specified script - // Parameters: (int) id: ID of the script or script segment to read from - // (idFlag) flag: Whether to address the script by script number (SCRIPT_ID) or - // by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID, - // but less convenient. - // Returns : (int) The number of synonyms associated with the specified script - // A dynamic failure is issued if the specified ID does not reference a proper script. - int getSynonymsNr(int id, idFlag flag); - // 1b. Script Initialisation @@ -186,50 +137,11 @@ public: // objects have been instantiated, or a run-time error will occur. void scriptRelocate(reg_t block); - // Sets the script-relative offset of the exports table - // Parameters: (int) offset: The script-relative exports table offset - // (int) id: ID of the script or script segment to write to - // (idFlag) flag: Whether to address the script by script number (SCRIPT_ID) or - // by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID, - // but less convenient. - // A dynamic failure is issued if the specified ID does not reference a proper script. - void setExportTableOffset(int offset, int id, idFlag flag); - - // Sets the script-relative offset of the synonyms associated with the specified script - // Parameters: (int) offset: The script-relative offset of the synonyms block - // (int) id: ID of the script or script segment to write to - // (idFlag) flag: Whether to address the script by script number (SCRIPT_ID) or - // by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID, - // but less convenient. - // A dynamic failure is issued if the specified ID does not reference a proper script. - void setSynonymsOffset(int offset, int id, idFlag flag); - - // Sets the number of synonyms associated with the specified script - // Parameters: (int) nr: The number of synonyms, as to be stored within the script - // (int) id: ID of the script or script segment to write to - // (idFlag) flag: Whether to address the script by script number (SCRIPT_ID) or - // by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID, - // but less convenient. - // A dynamic failure is issued if the specified ID does not reference a proper script. - void setSynonymsNr(int nr, int id, idFlag flag); - - // Marks the script identified by its script number as deleted - // Parameters: (int) script_nr: Script number to mark as deleted - // This will not actually delete the script. If references remain present on the - // heap or the stack, the script will stay in memory in a quasi-deleted state until - // either unreachable (resulting in its eventual deletion) or reloaded (resulting - // in its data being updated). - void markScriptDeleted(int script_nr); - - // Marks the script identified by its script number as not deleted - // Parameters: (int) script_nr: Script number to mark as not deleted - void unmarkScriptDeleted(int script_nr); - // Determines whether the script referenced by the indicated segment is marked as being deleted. // Parameters: (SegmentId) Segment ID of the script to investigate // Returns : (int) 1 iff seg points to a script and the segment is deleted, 0 otherwise // Will return 0 when applied to an invalid or non-script seg. - int scriptIsMarkedAsDeleted(SegmentId seg); + bool scriptIsMarkedAsDeleted(SegmentId seg); // 2. Clones @@ -249,17 +161,6 @@ public: // Returns : (int16) The value read from the specified location int16 getHeap(reg_t reg); - // Copies a byte string into a script's heap representation - // Parameters: (int) dst: The script-relative offset of the destination area - // (const void *) src: Pointer to the data source location - // (size_t) n: Number of bytes to copy - // (int) id: ID of the script or script segment to write to - // (idFlag) flag: Whether to address the script by script number (SCRIPT_ID) or - // by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID, - // but less convenient. - // A dynamic failure is issued if the specified ID does not reference a proper script. - void mcpyInOut(int dst, const void *src, size_t n, int id, idFlag flag); - // 4. Stack @@ -360,7 +261,6 @@ public: void heapRelocate(EngineState *s, reg_t block); void scriptRelocateExportsSci11(int seg); void scriptInitialiseObjectsSci11(EngineState *s, int seg); - int scriptMarkedDeleted(int script_nr); int initialiseScript(Script &scr, EngineState *s, int script_nr); private: diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp index 43022dc3f5..e1d3b254e8 100644 --- a/engines/sci/engine/vm.cpp +++ b/engines/sci/engine/vm.cpp @@ -222,7 +222,7 @@ reg_t get_class_address(EngineState *s, int classnr, int lock, reg_t caller) { } } else if (caller.segment != the_class->reg.segment) - s->seg_manager->incrementLockers(the_class->reg.segment, SEG_ID); + s->seg_manager->getScript(the_class->reg.segment, SEG_ID)->incrementLockers(); return the_class->reg; } @@ -255,12 +255,12 @@ ExecStack *execute_method(EngineState *s, uint16 script, uint16 pubfunct, StackP int seg; uint16 temp; - if (!s->seg_manager->scriptIsLoaded(script, SCRIPT_ID)) // Script not present yet? + seg = s->seg_manager->segGet(script); + + if (!s->seg_manager->scriptIsLoaded(seg, SEG_ID)) // Script not present yet? script_instantiate(s, script); else - s->seg_manager->unmarkScriptDeleted(script); - - seg = s->seg_manager->segGet(script); + s->seg_manager->getScript(seg, SEG_ID)->unmarkDeleted(); temp = s->seg_manager->validateExportFunc(pubfunct, seg); if (!temp) { @@ -528,11 +528,7 @@ void vm_handle_fatal_error(EngineState *s, int line, const char *file) { } static Script *script_locate_by_segment(EngineState *s, SegmentId seg) { - MemObject *memobj = GET_SEGMENT(*s->seg_manager, seg, MEM_OBJ_SCRIPT); - if (memobj) - return (Script *)memobj; - - return NULL; + return (Script *)GET_SEGMENT(*s->seg_manager, seg, MEM_OBJ_SCRIPT); } static reg_t pointer_add(EngineState *s, reg_t base, int offset) { @@ -1595,7 +1591,7 @@ SegmentId script_get_segment(EngineState *s, int script_nr, int load) { if (segment > 0) { if ((load & SCRIPT_GET_LOCK) == SCRIPT_GET_LOCK) - s->seg_manager->incrementLockers(segment, SEG_ID); + s->seg_manager->getScript(segment, SEG_ID)->incrementLockers(); return segment; } else @@ -1604,7 +1600,6 @@ SegmentId script_get_segment(EngineState *s, int script_nr, int load) { reg_t script_lookup_export(EngineState *s, int script_nr, int export_index) { SegmentId seg = script_get_segment(s, script_nr, SCRIPT_GET_DONT_LOAD); - MemObject *memobj; Script *script = NULL; #ifndef DISABLE_VALIDATIONS @@ -1616,10 +1611,7 @@ reg_t script_lookup_export(EngineState *s, int script_nr, int export_index) { } #endif - memobj = GET_SEGMENT(*s->seg_manager, seg, MEM_OBJ_SCRIPT); - - if (memobj) - script = (Script *)memobj; + script = script_locate_by_segment(s, seg); #ifndef DISABLE_VALIDATIONS if (script @@ -1643,9 +1635,7 @@ reg_t script_lookup_export(EngineState *s, int script_nr, int export_index) { #define INST_LOOKUP_CLASS(id) ((id == 0xffff)? NULL_REG : get_class_address(s, id, SCRIPT_GET_LOCK, reg)) int script_instantiate_common(EngineState *s, int script_nr, Resource **script, Resource **heap, int *was_new) { - int seg; int seg_id; - int marked_for_deletion; reg_t reg; *was_new = 1; @@ -1671,23 +1661,22 @@ int script_instantiate_common(EngineState *s, int script_nr, Resource **script, return 0; } - Script *scr = 0; - seg = s->seg_manager->segGet(script_nr); - if (s->seg_manager->scriptIsLoaded(script_nr, SCRIPT_ID)) { - marked_for_deletion = s->seg_manager->scriptMarkedDeleted(script_nr); - if (!marked_for_deletion) { - s->seg_manager->incrementLockers(seg, SEG_ID); - return seg; + seg_id = s->seg_manager->segGet(script_nr); + Script *scr = script_locate_by_segment(s, seg_id); + if (scr) { + if (!scr->isMarkedAsDeleted()) { + scr->incrementLockers(); + return seg_id; } else { - seg_id = seg; - scr = (Script *)s->seg_manager->_heap[seg]; - assert(scr); scr->freeScript(); } - } else if (!(scr = s->seg_manager->allocateScript(s, script_nr, &seg_id))) { // ALL YOUR SCRIPT BASE ARE BELONG TO US - sciprintf("Not enough heap space for script size 0x%x of script 0x%x, should this happen?`\n", (*script)->size, script_nr); - script_debug_flag = script_error_flag = 1; - return 0; + } else { + scr = s->seg_manager->allocateScript(s, script_nr, &seg_id); + if (!scr) { // ALL YOUR SCRIPT BASE ARE BELONG TO US + sciprintf("Not enough heap space for script size 0x%x of script 0x%x, should this happen?`\n", (*script)->size, script_nr); + script_debug_flag = script_error_flag = 1; + return 0; + } } s->seg_manager->initialiseScript(*scr, s, script_nr); @@ -1696,10 +1685,10 @@ int script_instantiate_common(EngineState *s, int script_nr, Resource **script, reg.offset = 0; // Set heap position (beyond the size word) - s->seg_manager->setLockers(1, reg.segment, SEG_ID); - s->seg_manager->setExportTableOffset(0, reg.segment, SEG_ID); - s->seg_manager->setSynonymsOffset(0, reg.segment, SEG_ID); - s->seg_manager->setSynonymsNr(0, reg.segment, SEG_ID); + scr->setLockers(1); + scr->setExportTableOffset(0); + scr->setSynonymsOffset(0); + scr->setSynonymsNr(0); *was_new = 0; @@ -1724,6 +1713,8 @@ int script_instantiate_sci0(EngineState *s, int script_nr) { reg.segment = seg_id; reg.offset = 0; + Script *scr = s->seg_manager->getScript(seg_id, SEG_ID); + if (s->flags & GF_SCI0_OLD) { // int locals_nr = READ_LE_UINT16(script->data); @@ -1733,14 +1724,14 @@ int script_instantiate_sci0(EngineState *s, int script_nr) { // Instead, the script starts with a 16 bit int specifying the // number of locals we need; these are then allocated and zeroed. - s->seg_manager->mcpyInOut(0, script->data, script->size, reg.segment, SEG_ID); + scr->mcpyInOut(0, script->data, script->size); magic_pos_adder = 2; // Step over the funny prefix if (locals_nr) s->seg_manager->scriptInitialiseLocalsZero(reg.segment, locals_nr); } else { - s->seg_manager->mcpyInOut(0, script->data, script->size, reg.segment, SEG_ID); + scr->mcpyInOut(0, script->data, script->size); magic_pos_adder = 0; } @@ -1767,13 +1758,13 @@ int script_instantiate_sci0(EngineState *s, int script_nr) { switch (objtype) { case SCI_OBJ_EXPORTS: { - s->seg_manager->setExportTableOffset(data_base.offset, reg.segment, SEG_ID); + scr->setExportTableOffset(data_base.offset); } break; case SCI_OBJ_SYNONYMS: - s->seg_manager->setSynonymsOffset(addr.offset, reg.segment, SEG_ID); // +4 is to step over the header - s->seg_manager->setSynonymsNr((objlength) / 4, reg.segment, SEG_ID); + scr->setSynonymsOffset(addr.offset); // +4 is to step over the header + scr->setSynonymsNr((objlength) / 4); break; case SCI_OBJ_LOCALVARS: @@ -1870,15 +1861,17 @@ int script_instantiate_sci11(EngineState *s, int script_nr) { if (was_new) return seg_id; + Script *scr = s->seg_manager->getScript(seg_id, SEG_ID); + heap_start = script->size; if (script->size & 2) heap_start ++; - s->seg_manager->mcpyInOut(0, script->data, script->size, seg_id, SEG_ID); - s->seg_manager->mcpyInOut(heap_start, heap->data, heap->size, seg_id, SEG_ID); + scr->mcpyInOut(0, script->data, script->size); + scr->mcpyInOut(heap_start, heap->data, heap->size); if (READ_LE_UINT16(script->data + 6) > 0) - s->seg_manager->setExportTableOffset(6, seg_id, SEG_ID); + scr->setExportTableOffset(6); reg.segment = seg_id; reg.offset = heap_start + 4; @@ -1903,6 +1896,7 @@ int script_instantiate(EngineState *s, int script_nr) { void script_uninstantiate_sci0(EngineState *s, int script_nr, SegmentId seg) { reg_t reg = make_reg(seg, (s->flags & GF_SCI0_OLD) ? 2 : 0); int objtype, objlength; + Script *scr = s->seg_manager->getScript(seg, SEG_ID); // Make a pass over the object in order uninstantiate all superclasses objlength = 0; @@ -1911,7 +1905,8 @@ void script_uninstantiate_sci0(EngineState *s, int script_nr, SegmentId seg) { reg.offset += objlength; // Step over the last checked object objtype = SEG_GET_HEAP(s, reg); - if (!objtype) break; + if (!objtype) + break; objlength = SEG_GET_HEAP(s, make_reg(reg.segment, reg.offset + 2)); // use SEG_UGET_HEAP ?? reg.offset += 4; // Step over header @@ -1927,8 +1922,8 @@ void script_uninstantiate_sci0(EngineState *s, int script_nr, SegmentId seg) { int superclass_script = s->_classtable[superclass].script; if (superclass_script == script_nr) { - if (s->seg_manager->getLockers(reg.segment, SEG_ID)) - s->seg_manager->decrementLockers(reg.segment, SEG_ID); // Decrease lockers if this is us ourselves + if (scr->getLockers()) + scr->decrementLockers(); // Decrease lockers if this is us ourselves } else script_uninstantiate(s, superclass_script); // Recurse to assure that the superclass lockers number gets decreased @@ -1946,16 +1941,17 @@ void script_uninstantiate(EngineState *s, int script_nr) { reg_t reg = make_reg(0, (s->flags & GF_SCI0_OLD) ? 2 : 0); reg.segment = s->seg_manager->segGet(script_nr); + Script *scr = script_locate_by_segment(s, reg.segment); - if (!s->seg_manager->scriptIsLoaded(script_nr, SCRIPT_ID) || reg.segment <= 0) { // Is it already loaded? + if (!scr) { // Is it already loaded? //warning("unloading script 0x%x requested although not loaded", script_nr); // This is perfectly valid SCI behaviour return; } - s->seg_manager->decrementLockers(reg.segment, SEG_ID); // One less locker + scr->decrementLockers(); // One less locker - if (s->seg_manager->getLockers(reg.segment, SEG_ID) > 0) + if (scr->getLockers() > 0) return; // Free all classtable references to this script @@ -1968,12 +1964,12 @@ void script_uninstantiate(EngineState *s, int script_nr) { else sciprintf("FIXME: Add proper script uninstantiation for SCI 1.1\n"); - if (s->seg_manager->getLockers(reg.segment, SEG_ID)) + if (scr->getLockers()) return; // if xxx.lockers > 0 // Otherwise unload it completely // Explanation: I'm starting to believe that this work is done by SCI itself. - s->seg_manager->markScriptDeleted(script_nr); + scr->markDeleted(); if (script_checkloads_flag) sciprintf("Unloaded script 0x%x.\n", script_nr); @@ -2064,17 +2060,17 @@ int game_run(EngineState **_s) { } Object *obj_get(EngineState *s, reg_t offset) { - MemObject *memobj = GET_OBJECT_SEGMENT(*s->seg_manager, offset.segment); + MemObject *mobj = GET_OBJECT_SEGMENT(*s->seg_manager, offset.segment); Object *obj = NULL; int idx; - if (memobj != NULL) { - if (memobj->getType() == MEM_OBJ_CLONES) { - CloneTable *ct = (CloneTable *)memobj; + if (mobj != NULL) { + if (mobj->getType() == MEM_OBJ_CLONES) { + CloneTable *ct = (CloneTable *)mobj; if (ct->isValidEntry(offset.offset)) obj = &(ct->_table[offset.offset]); - } else if (memobj->getType() == MEM_OBJ_SCRIPT) { - Script *scr = (Script *)memobj; + } else if (mobj->getType() == MEM_OBJ_SCRIPT) { + Script *scr = (Script *)mobj; if (offset.offset <= scr->buf_size && offset.offset >= -SCRIPT_OBJECT_MAGIC_OFFSET && RAW_IS_OBJECT(scr->buf + offset.offset)) { idx = RAW_GET_CLASS_INDEX(scr, offset); diff --git a/engines/sci/engine/vm.h b/engines/sci/engine/vm.h index fc3744f551..b7969c3447 100644 --- a/engines/sci/engine/vm.h +++ b/engines/sci/engine/vm.h @@ -330,7 +330,7 @@ struct Script : public MemObject { Common::Array<CodeBlock> _codeBlocks; int relocated; - int marked_as_deleted; + bool _markedAsDeleted; public: Script() { @@ -351,7 +351,7 @@ public: locals_block = NULL; relocated = 0; - marked_as_deleted = 0; + _markedAsDeleted = 0; } ~Script() { @@ -367,6 +367,90 @@ public: virtual void listAllOutgoingReferences(EngineState *s, reg_t object, void *param, NoteCallback note); // virtual void saveLoadWithSerializer(Common::Serializer &ser); + + // script lock operations + + /** Increments the number of lockers of this script by one. */ + void incrementLockers(); + + /** Decrements the number of lockers of this script by one. */ + void decrementLockers(); + + /** + * Retrieves the number of locks held on this script. + * @return the number of locks held on the previously identified script + */ + int getLockers() const; + + /** Sets the number of locks held on this script. */ + void setLockers(int lockers); + + /** + * Retrieves a pointer to the synonyms associated with this script + * @return pointer to the synonyms, in non-parsed format. + */ + byte *getSynonyms() const; + + /** + * Retrieves the number of synonyms associated with this script. + * @return the number of synonyms associated with this script + */ + int getSynonymsNr() const; + + + /** + * Sets the script-relative offset of the exports table. + * @param offset script-relative exports table offset + */ + void setExportTableOffset(int offset); + + /** + * Sets the script-relative offset of the synonyms associated with this script. + * @param offset script-relative offset of the synonyms block + */ + void setSynonymsOffset(int offset); + + /** + * Sets the number of synonyms associated with this script, + * @param nr number of synonyms, as to be stored within the script + */ + void setSynonymsNr(int nr); + + + /** + * Copies a byte string into a script's heap representation. + * @param dst script-relative offset of the destination area + * @param src pointer to the data source location + * @param n number of bytes to copy + */ + void mcpyInOut(int dst, const void *src, size_t n); + + + /** + * Marks the script as deleted. + * This will not actually delete the script. If references remain present on the + * heap or the stack, the script will stay in memory in a quasi-deleted state until + * either unreachable (resulting in its eventual deletion) or reloaded (resulting + * in its data being updated). + */ + void markDeleted() { + _markedAsDeleted = true; + } + + /** + * Marks the script as not deleted. + */ + void unmarkDeleted() { + _markedAsDeleted = false; + } + + /** + * Determines whether the script is marked as being deleted. + */ + bool isMarkedAsDeleted() const { + return _markedAsDeleted; + } + }; /** Data stack */ |