diff options
Diffstat (limited to 'engines')
-rw-r--r-- | engines/sci/engine/kernel.cpp | 2 | ||||
-rw-r--r-- | engines/sci/engine/kevent.cpp | 2 | ||||
-rw-r--r-- | engines/sci/engine/kscripts.cpp | 14 | ||||
-rw-r--r-- | engines/sci/engine/savegame.cpp | 28 | ||||
-rw-r--r-- | engines/sci/engine/scriptconsole.cpp | 4 | ||||
-rw-r--r-- | engines/sci/engine/scriptdebug.cpp | 22 | ||||
-rw-r--r-- | engines/sci/engine/seg_manager.cpp | 86 | ||||
-rw-r--r-- | engines/sci/engine/seg_manager.h | 2 | ||||
-rw-r--r-- | engines/sci/engine/state.h | 2 | ||||
-rw-r--r-- | engines/sci/engine/vm.cpp | 42 | ||||
-rw-r--r-- | engines/sci/engine/vm.h | 24 |
11 files changed, 99 insertions, 129 deletions
diff --git a/engines/sci/engine/kernel.cpp b/engines/sci/engine/kernel.cpp index cf74293763..b7ec82265d 100644 --- a/engines/sci/engine/kernel.cpp +++ b/engines/sci/engine/kernel.cpp @@ -686,7 +686,7 @@ int determine_reg_type(EngineState *s, reg_t reg, int allow_invalid) { return KSIG_OBJECT | KSIG_INVALID; case MEM_OBJ_LOCALS: - if (allow_invalid || reg.offset < (*(LocalVariables *)mobj).nr * sizeof(reg_t)) + if (allow_invalid || reg.offset < (*(LocalVariables *)mobj)._locals.size() * sizeof(reg_t)) return KSIG_REF; else return KSIG_REF | KSIG_INVALID; diff --git a/engines/sci/engine/kevent.cpp b/engines/sci/engine/kevent.cpp index e6da7319a0..91ad504eba 100644 --- a/engines/sci/engine/kevent.cpp +++ b/engines/sci/engine/kevent.cpp @@ -44,7 +44,7 @@ reg_t kGetEvent(EngineState *s, int funct_nr, int argc, reg_t *argv) { if (s->kernel_opt_flags & KERNEL_OPT_FLAG_GOT_2NDEVENT) { // Penalty time- too many requests to this function without // waiting! - int delay = s->script_000->locals_block->locals[SCI_VARIABLE_GAME_SPEED].offset; + int delay = s->script_000->locals_block->_locals[SCI_VARIABLE_GAME_SPEED].offset; gfxop_sleep(s->gfx_state, delay * 1000 / 60); } diff --git a/engines/sci/engine/kscripts.cpp b/engines/sci/engine/kscripts.cpp index 4a71f231ae..83128786b5 100644 --- a/engines/sci/engine/kscripts.cpp +++ b/engines/sci/engine/kscripts.cpp @@ -160,7 +160,6 @@ reg_t kClone(EngineState *s, int funct_nr, int argc, reg_t *argv) { Object *parent_obj = obj_get(s, parent_addr); reg_t clone_addr; Clone *clone_obj; // same as Object* - int varblock_size; if (!parent_obj) { SCIkwarn(SCIkERROR, "Attempt to clone non-object/class at "PREG" failed", PRINT_REG(parent_addr)); @@ -176,17 +175,14 @@ reg_t kClone(EngineState *s, int funct_nr, int argc, reg_t *argv) { return NULL_REG; } - memcpy(clone_obj, parent_obj, sizeof(Clone)); + *clone_obj = *parent_obj; clone_obj->flags = 0; - varblock_size = parent_obj->variables_nr * sizeof(reg_t); - clone_obj->variables = (reg_t*)malloc(varblock_size); - memcpy(clone_obj->variables, parent_obj->variables, varblock_size); // Mark as clone - clone_obj->variables[SCRIPT_INFO_SELECTOR].offset = SCRIPT_INFO_CLONE; - clone_obj->variables[SCRIPT_SPECIES_SELECTOR] = clone_obj->pos; + clone_obj->_variables[SCRIPT_INFO_SELECTOR].offset = SCRIPT_INFO_CLONE; + clone_obj->_variables[SCRIPT_SPECIES_SELECTOR] = clone_obj->pos; if (IS_CLASS(parent_obj)) - clone_obj->variables[SCRIPT_SUPERCLASS_SELECTOR] = parent_obj->pos; + 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); @@ -206,7 +202,7 @@ reg_t kDisposeClone(EngineState *s, int funct_nr, int argc, reg_t *argv) { return s->r_acc; } - if (victim_obj->variables[SCRIPT_INFO_SELECTOR].offset != SCRIPT_INFO_CLONE) { + if (victim_obj->_variables[SCRIPT_INFO_SELECTOR].offset != SCRIPT_INFO_CLONE) { //SCIkwarn("Attempt to dispose something other than a clone at %04x\n", offset); // SCI silently ignores this behaviour; some games actually depend on it return s->r_acc; diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp index 2e2bd66322..ce5e7fc28a 100644 --- a/engines/sci/engine/savegame.cpp +++ b/engines/sci/engine/savegame.cpp @@ -149,6 +149,12 @@ void syncArray(Common::Serializer &s, Common::Array<T> &arr) { } +template <> +void syncWithSerializer(Common::Serializer &s, reg_t &obj) { + sync_reg_t(s, obj); +} + + void MenuItem::saveLoadWithSerializer(Common::Serializer &s) { s.syncAsSint32LE(_type); @@ -259,7 +265,6 @@ void EngineState::saveLoadWithSerializer(Common::Serializer &s) { sync_SegManagerPtr(s, seg_manager); - syncArray<Class>(s, _classtable); sync_sfx_state_t(s, sound); @@ -267,12 +272,7 @@ void EngineState::saveLoadWithSerializer(Common::Serializer &s) { static void sync_LocalVariables(Common::Serializer &s, LocalVariables &obj) { s.syncAsSint32LE(obj.script_id); - - s.syncAsSint32LE(obj.nr); - if (!obj.locals && obj.nr) - obj.locals = (reg_t *)calloc(obj.nr, sizeof(reg_t)); - for (int i = 0; i < obj.nr; ++i) - sync_reg_t(s, obj.locals[i]); + syncArray<reg_t>(s, obj._locals); } template <> @@ -282,11 +282,7 @@ void syncWithSerializer(Common::Serializer &s, Object &obj) { s.syncAsSint32LE(obj.variable_names_nr); s.syncAsSint32LE(obj.methods_nr); - s.syncAsSint32LE(obj.variables_nr); - if (!obj.variables && obj.variables_nr) - obj.variables = (reg_t *)calloc(obj.variables_nr, sizeof(reg_t)); - for (int i = 0; i < obj.variables_nr; ++i) - sync_reg_t(s, obj.variables[i]); + syncArray<reg_t>(s, obj._variables); } template <> @@ -629,14 +625,14 @@ static void reconstruct_scripts(EngineState *s, SegManager *self) { int funct_area = READ_LE_UINT16( data + SCRIPT_FUNCTAREAPTR_OFFSET ); Object *base_obj; - base_obj = obj_get(s, scr->_objects[j].variables[SCRIPT_SPECIES_SELECTOR]); + base_obj = obj_get(s, scr->_objects[j]._variables[SCRIPT_SPECIES_SELECTOR]); if (!base_obj) { sciprintf("Object without a base class: Script %d, index %d (reg address "PREG"\n", - scr->nr, j, PRINT_REG(scr->_objects[j].variables[SCRIPT_SPECIES_SELECTOR])); + scr->nr, j, PRINT_REG(scr->_objects[j]._variables[SCRIPT_SPECIES_SELECTOR])); continue; } - scr->_objects[j].variable_names_nr = base_obj->variables_nr; + scr->_objects[j].variable_names_nr = base_obj->_variables.size(); scr->_objects[j].base_obj = base_obj->base_obj; scr->_objects[j].base_method = (uint16 *)(data + funct_area); @@ -683,7 +679,7 @@ static void reconstruct_clones(EngineState *s, SegManager *self) { continue; } CloneTable::Entry &seeker = ct->_table[j]; - base_obj = obj_get(s, seeker.variables[SCRIPT_SPECIES_SELECTOR]); + base_obj = obj_get(s, seeker._variables[SCRIPT_SPECIES_SELECTOR]); if (!base_obj) { sciprintf("Clone entry without a base class: %d\n", j); seeker.base = seeker.base_obj = NULL; diff --git a/engines/sci/engine/scriptconsole.cpp b/engines/sci/engine/scriptconsole.cpp index 577433371c..569c14a519 100644 --- a/engines/sci/engine/scriptconsole.cpp +++ b/engines/sci/engine/scriptconsole.cpp @@ -328,8 +328,8 @@ int parse_reg_t(EngineState *s, const char *str, reg_t *dest) { // Returns 0 on } if (valid) { - char *objname = (char *) obj->base - + obj->variables[SCRIPT_NAME_SELECTOR].offset; + char *objname = (char *)obj->base + + obj->_variables[SCRIPT_NAME_SELECTOR].offset; if (!strcmp(objname, str_objname)) { // Found a match! if (index < 0 || diff --git a/engines/sci/engine/scriptdebug.cpp b/engines/sci/engine/scriptdebug.cpp index 4ea47c8710..c391543e51 100644 --- a/engines/sci/engine/scriptdebug.cpp +++ b/engines/sci/engine/scriptdebug.cpp @@ -340,7 +340,7 @@ int c_segtable(EngineState *s, const Common::Array<cmd_param_t> &cmdParams) { static void print_obj_head(EngineState *s, Object *obj) { sciprintf(PREG" %s : %3d vars, %3d methods\n", PRINT_REG(obj->pos), obj_get_name(s, obj->pos), - obj->variables_nr, obj->methods_nr); + obj->_variables.size(), obj->methods_nr); } static void print_list(EngineState *s, List *l) { @@ -391,7 +391,7 @@ static void _c_single_seg_info(EngineState *s, MemObject *mobj) { sciprintf(" Synynms: %4d\n", scr->synonyms_nr); if (scr->locals_block) - sciprintf(" Locals : %4d in segment 0x%x\n", scr->locals_block->nr, scr->locals_segment); + sciprintf(" Locals : %4d in segment 0x%x\n", scr->locals_block->_locals.size(), scr->locals_segment); else sciprintf(" Locals : none\n"); @@ -406,7 +406,7 @@ static void _c_single_seg_info(EngineState *s, MemObject *mobj) { case MEM_OBJ_LOCALS: { LocalVariables *locals = (LocalVariables *)mobj; sciprintf("locals for script.%03d\n", locals->script_id); - sciprintf(" %d (0x%x) locals\n", locals->nr, locals->nr); + sciprintf(" %d (0x%x) locals\n", locals->_locals.size(), locals->_locals.size()); } break; @@ -1182,13 +1182,13 @@ int prop_ofs_to_id(EngineState *s, int prop_ofs, reg_t objp) { return -1; } - selectors = obj->variables_nr; + selectors = obj->_variables.size(); if (s->version < SCI_VERSION(1, 001, 000)) selectoroffset = ((byte *)(obj->base_obj)) + SCRIPT_SELECTOR_OFFSET + selectors * 2; else { - if (!(obj->variables[SCRIPT_INFO_SELECTOR].offset & SCRIPT_INFO_CLASS)) { - obj = obj_get(s, obj->variables[SCRIPT_SUPERCLASS_SELECTOR]); + if (!(obj->_variables[SCRIPT_INFO_SELECTOR].offset & SCRIPT_INFO_CLASS)) { + obj = obj_get(s, obj->_variables[SCRIPT_SUPERCLASS_SELECTOR]); selectoroffset = (byte *)obj->base_vars; } else selectoroffset = (byte *)obj->base_vars; @@ -2533,17 +2533,17 @@ int objinfo(EngineState *s, reg_t pos) { print_obj_head(s, obj); - if (!(obj->variables[SCRIPT_INFO_SELECTOR].offset & SCRIPT_INFO_CLASS)) - var_container = obj_get(s, obj->variables[SCRIPT_SUPERCLASS_SELECTOR]); + if (!(obj->_variables[SCRIPT_INFO_SELECTOR].offset & SCRIPT_INFO_CLASS)) + var_container = obj_get(s, obj->_variables[SCRIPT_SUPERCLASS_SELECTOR]); sciprintf(" -- member variables:\n"); - for (i = 0; i < obj->variables_nr; i++) { + for (i = 0; (uint)i < obj->_variables.size(); i++) { sciprintf(" "); if (i < var_container->variable_names_nr) sciprintf("[%03x] %s = ", VM_OBJECT_GET_VARSELECTOR(var_container, i), selector_name(s, VM_OBJECT_GET_VARSELECTOR(var_container, i))); else sciprintf("p#%x = ", i); - sciprintf(PREG"\n", PRINT_REG(obj->variables[i])); + sciprintf(PREG"\n", PRINT_REG(obj->_variables[i])); } sciprintf(" -- methods:\n"); for (i = 0; i < obj->methods_nr; i++) { @@ -2870,7 +2870,7 @@ void script_debug(EngineState *s, reg_t *pc, StackPtr *sp, StackPtr *pp, reg_t * disassemble(s, *pc, 0, 1); if (_debug_seeking == _DEBUG_SEEK_GLOBAL) sciprintf("Global %d (0x%x) = "PREG"\n", _debug_seek_special, - _debug_seek_special, PRINT_REG(s->script_000->locals_block->locals[_debug_seek_special])); + _debug_seek_special, PRINT_REG(s->script_000->locals_block->_locals[_debug_seek_special])); _debugstate_valid = old_debugstate; diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp index 9ca5a9cd80..62976dc548 100644 --- a/engines/sci/engine/seg_manager.cpp +++ b/engines/sci/engine/seg_manager.cpp @@ -361,9 +361,6 @@ void Script::freeScript() { buf = NULL; buf_size = 0; - for (uint i = 0; i < _objects.size(); i++) { - free(_objects[i].variables); - } _objects.clear(); delete obj_indices; @@ -498,38 +495,37 @@ int SegManager::getSynonymsNr(int id, idFlag flag) { return scr->synonyms_nr; } -int SegManager::relocateBlock(reg_t *block, int block_location, int block_items, SegmentId segment, int location) { +int SegManager::relocateBlock(Common::Array<reg_t> &block, int block_location, SegmentId segment, int location) { int rel = location - block_location; - int index; if (rel < 0) return 0; - index = rel >> 1; + uint idx = rel >> 1; - if (index >= block_items) + if (idx >= block.size()) return 0; if (rel & 1) { - sciprintf("Error: Attempt to relocate odd variable #%d.5e (relative to %04x)\n", index, block_location); + sciprintf("Error: Attempt to relocate odd variable #%d.5e (relative to %04x)\n", idx, block_location); return 0; } - block[index].segment = segment; // Perform relocation + block[idx].segment = segment; // Perform relocation if (isSci1_1) - block[index].offset += getScript(segment, SEG_ID)->script_size; + block[idx].offset += getScript(segment, SEG_ID)->script_size; return 1; } int SegManager::relocateLocal(Script *scr, SegmentId segment, int location) { if (scr->locals_block) - return relocateBlock(scr->locals_block->locals, scr->locals_offset, scr->locals_block->nr, segment, location); + return relocateBlock(scr->locals_block->_locals, scr->locals_offset, segment, location); else return 0; // No hands, no cookies } int SegManager::relocateObject(Object *obj, SegmentId segment, int location) { - return relocateBlock(obj->variables, obj->pos.offset, obj->variables_nr, segment, location); + return relocateBlock(obj->_variables, obj->pos.offset, segment, location); } void SegManager::scriptAddCodeBlock(reg_t location) { @@ -573,11 +569,11 @@ void SegManager::scriptRelocate(reg_t block) { sciprintf("While processing relocation block "PREG":\n", PRINT_REG(block)); sciprintf("Relocation failed for index %04x (%d/%d)\n", pos, i + 1, count); if (scr->locals_block) - sciprintf("- locals: %d at %04x\n", scr->locals_block->nr, scr->locals_offset); + sciprintf("- locals: %d at %04x\n", scr->locals_block->_locals.size(), scr->locals_offset); else sciprintf("- No locals\n"); for (k = 0; k < scr->_objects.size(); k++) - sciprintf("- obj#%d at %04x w/ %d vars\n", k, scr->_objects[k].pos.offset, scr->_objects[k].variables_nr); + sciprintf("- obj#%d at %04x w/ %d vars\n", k, scr->_objects[k].pos.offset, scr->_objects[k]._variables.size()); // SQ3 script 71 has broken relocation entries. // Since this is mainstream, we can't break out as we used to do. sciprintf("Trying to continue anyway...\n"); @@ -614,11 +610,11 @@ void SegManager::heapRelocate(EngineState *s, reg_t block) { sciprintf("While processing relocation block "PREG":\n", PRINT_REG(block)); sciprintf("Relocation failed for index %04x (%d/%d)\n", pos, i + 1, count); if (scr->locals_block) - sciprintf("- locals: %d at %04x\n", scr->locals_block->nr, scr->locals_offset); + sciprintf("- locals: %d at %04x\n", scr->locals_block->_locals.size(), scr->locals_offset); else sciprintf("- No locals\n"); for (k = 0; k < scr->_objects.size(); k++) - sciprintf("- obj#%d at %04x w/ %d vars\n", k, scr->_objects[k].pos.offset, scr->_objects[k].variables_nr); + sciprintf("- obj#%d at %04x w/ %d vars\n", k, scr->_objects[k].pos.offset, scr->_objects[k]._variables.size()); sciprintf("Triggering breakpoint...\n"); BREAKPOINT(); } @@ -671,8 +667,7 @@ Object *SegManager::scriptObjInit0(EngineState *s, reg_t obj_pos) { // add again for classes, since those also store selectors + (is_class ? functions_nr * 2 : 0) < scr->buf_size, "Function area extends beyond end of script"); - obj->variables_nr = variables_nr; - obj->variables = (reg_t *)malloc(sizeof(reg_t) * variables_nr); + obj->_variables.resize(variables_nr); obj->methods_nr = functions_nr; obj->base = scr->buf; @@ -681,7 +676,7 @@ Object *SegManager::scriptObjInit0(EngineState *s, reg_t obj_pos) { obj->base_vars = NULL; for (i = 0; i < variables_nr; i++) - obj->variables[i] = make_reg(0, READ_LE_UINT16(data + (i * 2))); + obj->_variables[i] = make_reg(0, READ_LE_UINT16(data + (i * 2))); } return obj; @@ -727,16 +722,15 @@ Object *SegManager::scriptObjInit11(EngineState *s, reg_t obj_pos) { VERIFY(((byte *) funct_area + functions_nr) < scr->buf + scr->buf_size, "Function area extends beyond end of script"); - obj->variables_nr = variables_nr; obj->variable_names_nr = variables_nr; - obj->variables = (reg_t *)malloc(sizeof(reg_t) * variables_nr); + obj->_variables.resize(variables_nr); obj->methods_nr = functions_nr; obj->base = scr->buf; obj->base_obj = data; for (i = 0; i < variables_nr; i++) - obj->variables[i] = make_reg(0, READ_LE_UINT16(data + (i * 2))); + obj->_variables[i] = make_reg(0, READ_LE_UINT16(data + (i * 2))); } return obj; @@ -755,21 +749,19 @@ LocalVariables *SegManager::allocLocalsSegment(Script *scr, int count) { scr->locals_block = NULL; return NULL; } else { - MemObject *mobj; LocalVariables *locals; if (scr->locals_segment) { - mobj = _heap[scr->locals_segment]; - VERIFY(mobj != NULL, "Re-used locals segment was NULL'd out"); - VERIFY(mobj->getType() == MEM_OBJ_LOCALS, "Re-used locals segment did not consist of local variables"); - VERIFY((*(LocalVariables *)mobj).script_id == scr->nr, "Re-used locals segment belonged to other script"); + locals = (LocalVariables *)_heap[scr->locals_segment]; + VERIFY(locals != NULL, "Re-used locals segment was NULL'd out"); + VERIFY(locals->getType() == MEM_OBJ_LOCALS, "Re-used locals segment did not consist of local variables"); + VERIFY(locals->script_id == scr->nr, "Re-used locals segment belonged to other script"); } else - mobj = allocNonscriptSegment(MEM_OBJ_LOCALS, &scr->locals_segment); + locals = (LocalVariables *)allocNonscriptSegment(MEM_OBJ_LOCALS, &scr->locals_segment); - locals = scr->locals_block = (LocalVariables *)mobj; + scr->locals_block = locals; locals->script_id = scr->nr; - locals->locals = (reg_t *)calloc(count, sizeof(reg_t)); - locals->nr = count; + locals->_locals.resize(count); return locals; } @@ -808,7 +800,7 @@ void SegManager::scriptInitialiseLocals(reg_t location) { byte *base = (byte *)(scr->buf + location.offset); for (i = 0; i < count; i++) - locals->locals[i].offset = READ_LE_UINT16(base + i * 2); + locals->_locals[i].offset = READ_LE_UINT16(base + i * 2); } } @@ -861,16 +853,16 @@ void SegManager::scriptInitialiseObjectsSci11(EngineState *s, int seg) { obj = scriptObjInit(s, reg); #if 0 - if (obj->variables[5].offset != 0xffff) { - obj->variables[5] = INST_LOOKUP_CLASS(obj->variables[5].offset); - base_obj = obj_get(s, obj->variables[5]); + if (obj->_variables[5].offset != 0xffff) { + obj->_variables[5] = INST_LOOKUP_CLASS(obj->_variables[5].offset); + base_obj = obj_get(s, obj->_variables[5]); obj->variable_names_nr = base_obj->variables_nr; obj->base_obj = base_obj->base_obj; } #endif // Copy base from species class, as we need its selector IDs - obj->variables[6] = INST_LOOKUP_CLASS(obj->variables[6].offset); + obj->_variables[6] = INST_LOOKUP_CLASS(obj->_variables[6].offset); seeker += READ_LE_UINT16(seeker + 2) * 2; } @@ -1032,8 +1024,11 @@ byte *Script::dereference(reg_t pointer, int *size) { } byte *LocalVariables::dereference(reg_t pointer, int *size) { - int count = nr * sizeof(reg_t); - byte *base = (byte *)locals; + // FIXME: The following doesn't seem to be endian safe. + // To fix this, we'd have to always treat the reg_t + // values stored here as in the little endian format. + int count = _locals.size() * sizeof(reg_t); + byte *base = (byte *)&_locals[0]; if (size) *size = count; @@ -1164,8 +1159,8 @@ void Script::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, (*note)(param, make_reg(script->locals_segment, 0)); Object &obj = script->_objects[idx]; - for (int i = 0; i < obj.variables_nr; i++) - (*note)(param, obj.variables[i]); + for (uint i = 0; i < obj._variables.size(); i++) + (*note)(param, obj._variables[i]); } else { warning("Request for outgoing script-object reference at "PREG" yielded invalid index %d", PRINT_REG(addr), idx); } @@ -1188,7 +1183,6 @@ void Table<T>::listAllDeallocatable(SegmentId segId, void *param, NoteCallback n void CloneTable::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note) { CloneTable *clone_table = this; Clone *clone; - int i; // assert(addr.segment == _segId); @@ -1201,8 +1195,8 @@ void CloneTable::listAllOutgoingReferences(EngineState *s, reg_t addr, void *par clone = &(clone_table->_table[addr.offset]); // Emit all member variables (including references to the 'super' delegate) - for (i = 0; i < clone->variables_nr; i++) - (*note)(param, clone->variables[i]); + for (uint i = 0; i < clone->_variables.size(); i++) + (*note)(param, clone->_variables[i]); // Note that this also includes the 'base' object, which is part of the script and therefore also emits the locals. (*note)(param, clone->pos); @@ -1229,8 +1223,6 @@ void CloneTable::freeAtAddress(SegManager *segmgr, reg_t addr) { sciprintf("[GC] Clone "PREG": Freeing\n", PRINT_REG(addr)); sciprintf("[GC] Clone had pos "PREG"\n", PRINT_REG(victim_obj->pos)); */ - free(victim_obj->variables); - victim_obj->variables = NULL; clone_table->freeEntry(addr.offset); } @@ -1248,8 +1240,8 @@ reg_t LocalVariables::findCanonicAddress(SegManager *segmgr, reg_t addr) { void LocalVariables::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note) { // assert(addr.segment == _segId); - for (int i = 0; i < nr; i++) - (*note)(param, locals[i]); + for (uint i = 0; i < _locals.size(); i++) + (*note)(param, _locals[i]); } diff --git a/engines/sci/engine/seg_manager.h b/engines/sci/engine/seg_manager.h index 50d34081e2..4e7ae1d765 100644 --- a/engines/sci/engine/seg_manager.h +++ b/engines/sci/engine/seg_manager.h @@ -395,7 +395,7 @@ private: Hunk *alloc_Hunk(reg_t *); int relocateLocal(Script *scr, SegmentId segment, int location); - int relocateBlock(reg_t *block, int block_location, int block_items, 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); int findFreeId(int *id); diff --git a/engines/sci/engine/state.h b/engines/sci/engine/state.h index 67a29591a8..7eee4800d0 100644 --- a/engines/sci/engine/state.h +++ b/engines/sci/engine/state.h @@ -231,7 +231,7 @@ public: SegmentId script_000_segment; Script *script_000; /**< script 000, e.g. for globals */ - uint16 currentRoomNumber() { return KP_UINT(script_000->locals_block->locals[13]); } + uint16 currentRoomNumber() { return KP_UINT(script_000->locals_block->_locals[13]); } int parser_lastmatch_word; /**< Position of the input word the parser last matched on, or SAID_NO_MATCH */ diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp index 8b654c1388..9f3f94f319 100644 --- a/engines/sci/engine/vm.cpp +++ b/engines/sci/engine/vm.cpp @@ -72,16 +72,16 @@ static reg_t &validate_property(Object *obj, int index) { return _dummy_register; } - if (index < 0 || index >= obj->variables_nr) { + if (index < 0 || (uint)index >= obj->_variables.size()) { if (sci_debug_flags & 4) sciprintf("[VM] Invalid property #%d (out of [0..%d]) requested!\n", index, - obj->variables_nr); + obj->_variables.size()); _dummy_register = NULL_REG; return _dummy_register; } - return obj->variables[index]; + return obj->_variables[index]; } static StackPtr validate_stack_addr(EngineState *s, StackPtr sp) { @@ -176,7 +176,7 @@ static void validate_write_var(reg_t *r, reg_t *stack_base, int type, int max, i # define validate_variable(r, sb, t, m, i, l) # define validate_read_var(r, sb, t, m, i, l) ((r)[i]) # define validate_write_var(r, sb, t, m, i, l, v) ((r)[i] = (v)) -# define validate_property(o, p) ((o)->variables[p]) +# define validate_property(o, p) ((o)->_variables[p]) # define ASSERT_ARITHMETIC(v) (v).offset #endif @@ -614,7 +614,7 @@ void run_vm(EngineState *s, int restoring) { #ifndef DISABLE_VALIDATIONS // Initialize maximum variable count if (s->script_000->locals_block) - variables_max[VAR_GLOBAL] = s->script_000->locals_block->nr; + variables_max[VAR_GLOBAL] = s->script_000->locals_block->_locals.size(); else variables_max[VAR_GLOBAL] = 0; #endif @@ -625,7 +625,7 @@ void run_vm(EngineState *s, int restoring) { // SCI code reads the zeroeth argument to determine argc if (s->script_000->locals_block) - variables_base[VAR_GLOBAL] = variables[VAR_GLOBAL] = s->script_000->locals_block->locals; + variables_base[VAR_GLOBAL] = variables[VAR_GLOBAL] = s->script_000->locals_block->_locals.begin(); else variables_base[VAR_GLOBAL] = variables[VAR_GLOBAL] = NULL; @@ -682,12 +682,12 @@ void run_vm(EngineState *s, int restoring) { variables_seg[VAR_LOCAL] = local_script->locals_segment; if (local_script->locals_block) - variables_base[VAR_LOCAL] = variables[VAR_LOCAL] = local_script->locals_block->locals; + variables_base[VAR_LOCAL] = variables[VAR_LOCAL] = local_script->locals_block->_locals.begin(); else variables_base[VAR_LOCAL] = variables[VAR_LOCAL] = NULL; #ifndef DISABLE_VALIDATIONS if (local_script->locals_block) - variables_max[VAR_LOCAL] = local_script->locals_block->nr; + variables_max[VAR_LOCAL] = local_script->locals_block->_locals.size(); else variables_max[VAR_LOCAL] = 0; variables_max[VAR_TEMP] = xs->sp - xs->fp; @@ -1489,10 +1489,10 @@ static int _obj_locate_varselector(EngineState *s, Object *obj, Selector slc) { } else { byte *buf = (byte *) obj->base_vars; int i; - int varnum = obj->variables[1].offset; + int varnum = obj->_variables[1].offset; - if (!(obj->variables[SCRIPT_INFO_SELECTOR].offset & SCRIPT_INFO_CLASS)) - buf = ((byte *) obj_get(s, obj->variables[SCRIPT_SUPERCLASS_SELECTOR])->base_vars); + if (!(obj->_variables[SCRIPT_INFO_SELECTOR].offset & SCRIPT_INFO_CLASS)) + buf = ((byte *) obj_get(s, obj->_variables[SCRIPT_SUPERCLASS_SELECTOR])->base_vars); for (i = 0; i < varnum; i++) if (READ_LE_UINT16(buf + (i << 1)) == slc) // Found it? @@ -1534,8 +1534,8 @@ static SelectorType _lookup_selector_function(EngineState *s, int seg_id, Object return kSelectorMethod; } else { - seg_id = obj->variables[SCRIPT_SUPERCLASS_SELECTOR].segment; - obj = obj_get(s, obj->variables[SCRIPT_SUPERCLASS_SELECTOR]); + seg_id = obj->_variables[SCRIPT_SUPERCLASS_SELECTOR].segment; + obj = obj_get(s, obj->_variables[SCRIPT_SUPERCLASS_SELECTOR]); } } @@ -1561,13 +1561,13 @@ SelectorType lookup_selector(EngineState *s, reg_t obj_location, Selector select if (IS_CLASS(obj)) species = obj; else - species = obj_get(s, obj->variables[SCRIPT_SPECIES_SELECTOR]); + species = obj_get(s, obj->_variables[SCRIPT_SPECIES_SELECTOR]); if (!obj) { CORE_ERROR("SLC-LU", "Error while looking up Species class"); sciprintf("Original address was "PREG"\n", PRINT_REG(obj_location)); - sciprintf("Species address was "PREG"\n", PRINT_REG(obj->variables[SCRIPT_SPECIES_SELECTOR])); + sciprintf("Species address was "PREG"\n", PRINT_REG(obj->_variables[SCRIPT_SPECIES_SELECTOR])); return kSelectorNone; } @@ -1576,7 +1576,7 @@ SelectorType lookup_selector(EngineState *s, reg_t obj_location, Selector select if (index >= 0) { // Found it as a variable if (vptr) - *vptr = obj->variables + index; + *vptr = &obj->_variables[index]; return kSelectorVariable; } @@ -1851,14 +1851,14 @@ int script_instantiate_sci0(EngineState *s, int script_nr) { Object *base_obj; // Instantiate the superclass, if neccessary - obj->variables[SCRIPT_SPECIES_SELECTOR] = INST_LOOKUP_CLASS(obj->variables[SCRIPT_SPECIES_SELECTOR].offset); + obj->_variables[SCRIPT_SPECIES_SELECTOR] = INST_LOOKUP_CLASS(obj->_variables[SCRIPT_SPECIES_SELECTOR].offset); - base_obj = obj_get(s, obj->variables[SCRIPT_SPECIES_SELECTOR]); - obj->variable_names_nr = base_obj->variables_nr; + base_obj = obj_get(s, obj->_variables[SCRIPT_SPECIES_SELECTOR]); + obj->variable_names_nr = base_obj->_variables.size(); obj->base_obj = base_obj->base_obj; // Copy base from species class, as we need its selector IDs - obj->variables[SCRIPT_SUPERCLASS_SELECTOR] = INST_LOOKUP_CLASS(obj->variables[SCRIPT_SUPERCLASS_SELECTOR].offset); + obj->_variables[SCRIPT_SUPERCLASS_SELECTOR] = INST_LOOKUP_CLASS(obj->_variables[SCRIPT_SUPERCLASS_SELECTOR].offset); } // if object or class break; case sci_obj_pointers: // A relocation table @@ -2114,7 +2114,7 @@ const char *obj_get_name(EngineState *s, reg_t pos) { if (!obj) return "<no such object>"; - return (const char *)(obj->base + obj->variables[SCRIPT_NAME_SELECTOR].offset); + return (const char *)(obj->base + obj->_variables[SCRIPT_NAME_SELECTOR].offset); } void quit_vm() { diff --git a/engines/sci/engine/vm.h b/engines/sci/engine/vm.h index f7b5adae7d..f14c61b151 100644 --- a/engines/sci/engine/vm.h +++ b/engines/sci/engine/vm.h @@ -225,7 +225,7 @@ struct Class { #define RAW_GET_CLASS_INDEX(scr, reg) ((scr)->obj_indices->checkKey(reg.offset, false)) #define RAW_IS_OBJECT(datablock) (READ_LE_UINT16(((byte *) datablock) + SCRIPT_OBJECT_MAGIC_OFFSET) == SCRIPT_OBJECT_MAGIC_NUMBER) -#define IS_CLASS(obj) (obj->variables[SCRIPT_INFO_SELECTOR].offset & SCRIPT_INFO_CLASS) +#define IS_CLASS(obj) (obj->_variables[SCRIPT_INFO_SELECTOR].offset & SCRIPT_INFO_CLASS) /** This struct is used to buffer the list of send calls in send_selector() */ struct CallsStruct { @@ -242,18 +242,11 @@ struct CallsStruct { struct LocalVariables : public MemObject { int script_id; /**< Script ID this local variable block belongs to */ - reg_t *locals; - int nr; + Common::Array<reg_t> _locals; public: LocalVariables() { script_id = 0; - locals = 0; - nr = 0; - } - ~LocalVariables() { - free(locals); - locals = NULL; } virtual byte *dereference(reg_t pointer, int *size); @@ -269,14 +262,13 @@ public: struct Object { int flags; reg_t pos; /**< Object offset within its script; for clones, this is their base */ - int variables_nr; int variable_names_nr; /**< Number of variable names, may be less than variables_nr */ int methods_nr; byte *base; /**< Points to a buffer all relative references (code, strings) point to */ byte *base_obj; /**< base + object offset within base */ uint16 *base_method; /**< Pointer to the method selector area for this object */ uint16 *base_vars; /**< Pointer to the varselector area for this object */ - reg_t *variables; + Common::Array<reg_t> _variables; }; struct CodeBlock { @@ -286,9 +278,9 @@ struct CodeBlock { #define VM_OBJECT_GET_VARSELECTOR(obj, i) \ (s->version < SCI_VERSION(1,001,000) ? \ - READ_LE_UINT16(obj->base_obj + obj->variables_nr * 2 + i*2) : \ + READ_LE_UINT16(obj->base_obj + obj->_variables.size() * 2 + i*2) : \ *(obj->base_vars + i)) -#define VM_OBJECT_READ_PROPERTY(obj, i) (obj->variables[i]) +#define VM_OBJECT_READ_PROPERTY(obj, i) (obj->_variables[i]) #define VM_OBJECT_GET_FUNCSELECTOR(obj, i) \ (s->version < SCI_VERSION(1,001,000) ? \ READ_LE_UINT16((byte *) (obj->base_method + i)) : \ @@ -485,12 +477,6 @@ public: /* CloneTable */ struct CloneTable : public Table<Clone> { - virtual void freeEntry(int idx) { - Table<Clone>::freeEntry(idx); - - free(_table[idx].variables); // Free the dynamically allocated memory part - } - virtual void freeAtAddress(SegManager *segmgr, reg_t sub_addr); virtual void listAllOutgoingReferences(EngineState *s, reg_t object, void *param, NoteCallback note); }; |