diff options
Diffstat (limited to 'engines')
-rw-r--r-- | engines/sci/engine/kscripts.cpp | 2 | ||||
-rw-r--r-- | engines/sci/engine/savegame.cpp | 82 | ||||
-rw-r--r-- | engines/sci/engine/seg_manager.cpp | 55 | ||||
-rw-r--r-- | engines/sci/engine/seg_manager.h | 14 |
4 files changed, 70 insertions, 83 deletions
diff --git a/engines/sci/engine/kscripts.cpp b/engines/sci/engine/kscripts.cpp index bc0b7b41e5..3b0df6874f 100644 --- a/engines/sci/engine/kscripts.cpp +++ b/engines/sci/engine/kscripts.cpp @@ -195,7 +195,7 @@ reg_t kClone(EngineState *s, int, int argc, reg_t *argv) { debugC(2, kDebugLevelMemory, "Attempting to clone from %04x:%04x\n", PRINT_REG(parent_addr)); - clone_obj = s->segMan->alloc_Clone(&clone_addr); + clone_obj = s->segMan->allocateClone(&clone_addr); if (!clone_obj) { error("Cloning %04x:%04x failed-- internal error", PRINT_REG(parent_addr)); diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp index 3f785c3a13..f54d8b77de 100644 --- a/engines/sci/engine/savegame.cpp +++ b/engines/sci/engine/savegame.cpp @@ -479,15 +479,6 @@ int gamestate_save(EngineState *s, Common::WriteStream *fh, const char* savename return 0; } -// FIXME: This should probably be turned into a SegManager method -static SegmentId find_unique_seg_by_type(SegManager *self, int type) { - for (uint i = 0; i < self->_heap.size(); i++) - if (self->_heap[i] && - self->_heap[i]->getType() == type) - return i; - return -1; -} - static byte *find_unique_script_block(EngineState *s, byte *buf, int type) { bool oldScriptHeader = (s->resMan->sciVersion() == SCI_VERSION_0_EARLY); @@ -510,7 +501,7 @@ static byte *find_unique_script_block(EngineState *s, byte *buf, int type) { // FIXME: This should probably be turned into an EngineState method static void reconstruct_stack(EngineState *retval) { - SegmentId stack_seg = find_unique_seg_by_type(retval->segMan, MEM_OBJ_STACK); + SegmentId stack_seg = retval->segMan->findSegmentByType(MEM_OBJ_STACK); DataStack *stack = (DataStack *)(retval->segMan->_heap[stack_seg]); retval->stack_segment = stack_seg; @@ -518,18 +509,6 @@ static void reconstruct_stack(EngineState *retval) { retval->stack_top = retval->stack_base + VM_STACK_SIZE; } -static bool clone_entry_used(CloneTable *table, int n) { - int seeker = table->first_free; - - while (seeker != CloneTable::HEAPENTRY_INVALID) { - if (seeker == n) - return false; - seeker = table->_table[seeker].next_free; - } - - return true; -} - static void load_script(EngineState *s, SegmentId seg) { Resource *script, *heap = NULL; Script *scr = (Script *)(s->segMan->_heap[seg]); @@ -635,61 +614,6 @@ static void reconstruct_scripts(EngineState *s, SegManager *self) { } } -// FIXME: The following should likely become a SegManager method -static void reconstruct_clones(SegManager *self) { - SciVersion version = self->sciVersion(); // for the selector defines - - for (uint i = 0; i < self->_heap.size(); i++) { - if (self->_heap[i]) { - MemObject *mobj = self->_heap[i]; - switch (mobj->getType()) { - case MEM_OBJ_CLONES: { - CloneTable *ct = (CloneTable *)mobj; - - /* - printf("Free list: "); - for (uint j = ct->first_free; j != HEAPENTRY_INVALID; j = ct->_table[j].next_free) { - printf("%d ", j); - } - printf("\n"); - - printf("Entries w/zero vars: "); - for (uint j = 0; j < ct->_table.size(); j++) { - if (ct->_table[j].variables == NULL) - printf("%d ", j); - } - printf("\n"); - */ - - for (uint j = 0; j < ct->_table.size(); j++) { - Object *base_obj; - - if (!clone_entry_used(ct, j)) { - continue; - } - CloneTable::Entry &seeker = ct->_table[j]; - base_obj = obj_get(self, seeker._variables[SCRIPT_SPECIES_SELECTOR]); - if (!base_obj) { - printf("Clone entry without a base class: %d\n", j); - seeker.base = seeker.base_obj = NULL; - seeker.base_vars = seeker.base_method = NULL; - } else { - seeker.base = base_obj->base; - seeker.base_obj = base_obj->base_obj; - seeker.base_vars = base_obj->base_vars; - seeker.base_method = base_obj->base_method; - } - } - - break; - } - default: - break; - } - } - } -} - int _reset_graphics_input(EngineState *s); static void reconstruct_sounds(EngineState *s) { @@ -789,11 +713,11 @@ EngineState *gamestate_restore(EngineState *s, Common::SeekableReadStream *fh) { _reset_graphics_input(retval); reconstruct_stack(retval); reconstruct_scripts(retval, retval->segMan); - reconstruct_clones(retval->segMan); + retval->segMan->reconstructClones(); retval->game_obj = s->game_obj; retval->script_000 = retval->segMan->getScript(retval->segMan->getSegment(0, SCRIPT_GET_DONT_LOAD)); retval->gc_countdown = GC_INTERVAL - 1; - retval->sys_strings_segment = find_unique_seg_by_type(retval->segMan, MEM_OBJ_SYS_STRINGS); + retval->sys_strings_segment = retval->segMan->findSegmentByType(MEM_OBJ_SYS_STRINGS); retval->sys_strings = (SystemStrings *)GET_SEGMENT(*retval->segMan, retval->sys_strings_segment, MEM_OBJ_SYS_STRINGS); // Restore system strings diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp index 24331b3e9c..7cba3cb0f3 100644 --- a/engines/sci/engine/seg_manager.cpp +++ b/engines/sci/engine/seg_manager.cpp @@ -287,6 +287,13 @@ Script *SegManager::getScriptIfLoaded(const SegmentId seg) { return (Script *)_heap[seg]; } +SegmentId SegManager::findSegmentByType(int type) { + for (uint i = 0; i < _heap.size(); i++) + if (_heap[i] && _heap[i]->getType() == type) + return i; + return -1; +} + // validate the seg // return: // false - invalid seg @@ -801,7 +808,7 @@ Hunk *SegManager::alloc_hunk_entry(const char *hunk_type, int size, reg_t *reg) return h; } -Clone *SegManager::alloc_Clone(reg_t *addr) { +Clone *SegManager::allocateClone(reg_t *addr) { CloneTable *table; int offset; @@ -816,6 +823,52 @@ Clone *SegManager::alloc_Clone(reg_t *addr) { return &(table->_table[offset]); } +void SegManager::reconstructClones() { + SciVersion version = sciVersion(); // for the selector defines + + for (uint i = 0; i < _heap.size(); i++) { + if (_heap[i]) { + MemObject *mobj = _heap[i]; + if (mobj->getType() == MEM_OBJ_CLONES) { + CloneTable *ct = (CloneTable *)mobj; + + for (uint j = 0; j < ct->_table.size(); j++) { + Object *base_obj; + + // Check if the clone entry is used + uint entryNum = (uint)ct->first_free; + bool isUsed = true; + while (entryNum != CloneTable::HEAPENTRY_INVALID) { + if (entryNum == j) { + isUsed = false; + break; + } + entryNum = ct->_table[entryNum].next_free; + } + + if (!isUsed) + continue; + + CloneTable::Entry &seeker = ct->_table[j]; + base_obj = obj_get(this, seeker._variables[SCRIPT_SPECIES_SELECTOR]); + if (!base_obj) { + warning("Clone entry without a base class: %d", j); + seeker.base = NULL; + seeker.base_obj = NULL; + seeker.base_vars = NULL; + seeker.base_method = NULL; + } else { + seeker.base = base_obj->base; + seeker.base_obj = base_obj->base_obj; + seeker.base_vars = base_obj->base_vars; + seeker.base_method = base_obj->base_method; + } + } // end for + } // end if + } // end if + } // end for +} + List *SegManager::alloc_List(reg_t *addr) { ListTable *table; int offset; diff --git a/engines/sci/engine/seg_manager.h b/engines/sci/engine/seg_manager.h index 40d37d4c69..0bdb9a5a4e 100644 --- a/engines/sci/engine/seg_manager.h +++ b/engines/sci/engine/seg_manager.h @@ -130,7 +130,12 @@ public: */ Script *getScriptIfLoaded(SegmentId seg); - + /** + * Finds a unique segment by type + * @param type The type of the segment to find + * @return The segment number, or -1 if the segment wasn't found + */ + SegmentId findSegmentByType(int type); // 1b. Script Initialisation @@ -203,9 +208,14 @@ public: * @param addr The offset of the freshly allocated clone * @return Reference to the memory allocated for the clone */ - Clone *alloc_Clone(reg_t *addr); + Clone *allocateClone(reg_t *addr); + /** + * Reconstructs clones. Used when restoring saved games + */ + void reconstructClones(); + // 3. Objects (static, from Scripts, and dynmic, from Clones) |