aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
Diffstat (limited to 'engines')
-rw-r--r--engines/sci/engine/kscripts.cpp2
-rw-r--r--engines/sci/engine/savegame.cpp82
-rw-r--r--engines/sci/engine/seg_manager.cpp55
-rw-r--r--engines/sci/engine/seg_manager.h14
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)