aboutsummaryrefslogtreecommitdiff
path: root/engines/sci
diff options
context:
space:
mode:
Diffstat (limited to 'engines/sci')
-rw-r--r--engines/sci/engine/kernel.cpp2
-rw-r--r--engines/sci/engine/kevent.cpp2
-rw-r--r--engines/sci/engine/kscripts.cpp14
-rw-r--r--engines/sci/engine/savegame.cpp28
-rw-r--r--engines/sci/engine/scriptconsole.cpp4
-rw-r--r--engines/sci/engine/scriptdebug.cpp22
-rw-r--r--engines/sci/engine/seg_manager.cpp86
-rw-r--r--engines/sci/engine/seg_manager.h2
-rw-r--r--engines/sci/engine/state.h2
-rw-r--r--engines/sci/engine/vm.cpp42
-rw-r--r--engines/sci/engine/vm.h24
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);
};