aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/engine/seg_manager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/sci/engine/seg_manager.cpp')
-rw-r--r--engines/sci/engine/seg_manager.cpp86
1 files changed, 39 insertions, 47 deletions
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]);
}