SCI: Changed object / script local vars storage to use a Common::Array
svn-id: r40515
This commit is contained in:
parent
0255cd0213
commit
7f29670843
11 changed files with 99 additions and 129 deletions
|
@ -686,7 +686,7 @@ int determine_reg_type(EngineState *s, reg_t reg, int allow_invalid) {
|
||||||
return KSIG_OBJECT | KSIG_INVALID;
|
return KSIG_OBJECT | KSIG_INVALID;
|
||||||
|
|
||||||
case MEM_OBJ_LOCALS:
|
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;
|
return KSIG_REF;
|
||||||
else
|
else
|
||||||
return KSIG_REF | KSIG_INVALID;
|
return KSIG_REF | KSIG_INVALID;
|
||||||
|
|
|
@ -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) {
|
if (s->kernel_opt_flags & KERNEL_OPT_FLAG_GOT_2NDEVENT) {
|
||||||
// Penalty time- too many requests to this function without
|
// Penalty time- too many requests to this function without
|
||||||
// waiting!
|
// 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);
|
gfxop_sleep(s->gfx_state, delay * 1000 / 60);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
Object *parent_obj = obj_get(s, parent_addr);
|
||||||
reg_t clone_addr;
|
reg_t clone_addr;
|
||||||
Clone *clone_obj; // same as Object*
|
Clone *clone_obj; // same as Object*
|
||||||
int varblock_size;
|
|
||||||
|
|
||||||
if (!parent_obj) {
|
if (!parent_obj) {
|
||||||
SCIkwarn(SCIkERROR, "Attempt to clone non-object/class at "PREG" failed", PRINT_REG(parent_addr));
|
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;
|
return NULL_REG;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(clone_obj, parent_obj, sizeof(Clone));
|
*clone_obj = *parent_obj;
|
||||||
clone_obj->flags = 0;
|
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
|
// Mark as clone
|
||||||
clone_obj->variables[SCRIPT_INFO_SELECTOR].offset = SCRIPT_INFO_CLONE;
|
clone_obj->_variables[SCRIPT_INFO_SELECTOR].offset = SCRIPT_INFO_CLONE;
|
||||||
clone_obj->variables[SCRIPT_SPECIES_SELECTOR] = clone_obj->pos;
|
clone_obj->_variables[SCRIPT_SPECIES_SELECTOR] = clone_obj->pos;
|
||||||
if (IS_CLASS(parent_obj))
|
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(parent_obj->pos.segment, SEG_ID);
|
||||||
s->seg_manager->incrementLockers(clone_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;
|
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);
|
//SCIkwarn("Attempt to dispose something other than a clone at %04x\n", offset);
|
||||||
// SCI silently ignores this behaviour; some games actually depend on it
|
// SCI silently ignores this behaviour; some games actually depend on it
|
||||||
return s->r_acc;
|
return s->r_acc;
|
||||||
|
|
|
@ -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) {
|
void MenuItem::saveLoadWithSerializer(Common::Serializer &s) {
|
||||||
s.syncAsSint32LE(_type);
|
s.syncAsSint32LE(_type);
|
||||||
|
@ -259,7 +265,6 @@ void EngineState::saveLoadWithSerializer(Common::Serializer &s) {
|
||||||
|
|
||||||
sync_SegManagerPtr(s, seg_manager);
|
sync_SegManagerPtr(s, seg_manager);
|
||||||
|
|
||||||
|
|
||||||
syncArray<Class>(s, _classtable);
|
syncArray<Class>(s, _classtable);
|
||||||
|
|
||||||
sync_sfx_state_t(s, sound);
|
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) {
|
static void sync_LocalVariables(Common::Serializer &s, LocalVariables &obj) {
|
||||||
s.syncAsSint32LE(obj.script_id);
|
s.syncAsSint32LE(obj.script_id);
|
||||||
|
syncArray<reg_t>(s, obj._locals);
|
||||||
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]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
|
@ -282,11 +282,7 @@ void syncWithSerializer(Common::Serializer &s, Object &obj) {
|
||||||
s.syncAsSint32LE(obj.variable_names_nr);
|
s.syncAsSint32LE(obj.variable_names_nr);
|
||||||
s.syncAsSint32LE(obj.methods_nr);
|
s.syncAsSint32LE(obj.methods_nr);
|
||||||
|
|
||||||
s.syncAsSint32LE(obj.variables_nr);
|
syncArray<reg_t>(s, obj._variables);
|
||||||
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]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
|
@ -629,14 +625,14 @@ static void reconstruct_scripts(EngineState *s, SegManager *self) {
|
||||||
int funct_area = READ_LE_UINT16( data + SCRIPT_FUNCTAREAPTR_OFFSET );
|
int funct_area = READ_LE_UINT16( data + SCRIPT_FUNCTAREAPTR_OFFSET );
|
||||||
Object *base_obj;
|
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) {
|
if (!base_obj) {
|
||||||
sciprintf("Object without a base class: Script %d, index %d (reg address "PREG"\n",
|
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;
|
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_obj = base_obj->base_obj;
|
||||||
|
|
||||||
scr->_objects[j].base_method = (uint16 *)(data + funct_area);
|
scr->_objects[j].base_method = (uint16 *)(data + funct_area);
|
||||||
|
@ -683,7 +679,7 @@ static void reconstruct_clones(EngineState *s, SegManager *self) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
CloneTable::Entry &seeker = ct->_table[j];
|
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) {
|
if (!base_obj) {
|
||||||
sciprintf("Clone entry without a base class: %d\n", j);
|
sciprintf("Clone entry without a base class: %d\n", j);
|
||||||
seeker.base = seeker.base_obj = NULL;
|
seeker.base = seeker.base_obj = NULL;
|
||||||
|
|
|
@ -328,8 +328,8 @@ int parse_reg_t(EngineState *s, const char *str, reg_t *dest) { // Returns 0 on
|
||||||
}
|
}
|
||||||
|
|
||||||
if (valid) {
|
if (valid) {
|
||||||
char *objname = (char *) obj->base
|
char *objname = (char *)obj->base
|
||||||
+ obj->variables[SCRIPT_NAME_SELECTOR].offset;
|
+ obj->_variables[SCRIPT_NAME_SELECTOR].offset;
|
||||||
if (!strcmp(objname, str_objname)) {
|
if (!strcmp(objname, str_objname)) {
|
||||||
// Found a match!
|
// Found a match!
|
||||||
if (index < 0 ||
|
if (index < 0 ||
|
||||||
|
|
|
@ -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) {
|
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),
|
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) {
|
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);
|
sciprintf(" Synynms: %4d\n", scr->synonyms_nr);
|
||||||
|
|
||||||
if (scr->locals_block)
|
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
|
else
|
||||||
sciprintf(" Locals : none\n");
|
sciprintf(" Locals : none\n");
|
||||||
|
|
||||||
|
@ -406,7 +406,7 @@ static void _c_single_seg_info(EngineState *s, MemObject *mobj) {
|
||||||
case MEM_OBJ_LOCALS: {
|
case MEM_OBJ_LOCALS: {
|
||||||
LocalVariables *locals = (LocalVariables *)mobj;
|
LocalVariables *locals = (LocalVariables *)mobj;
|
||||||
sciprintf("locals for script.%03d\n", locals->script_id);
|
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;
|
break;
|
||||||
|
|
||||||
|
@ -1182,13 +1182,13 @@ int prop_ofs_to_id(EngineState *s, int prop_ofs, reg_t objp) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
selectors = obj->variables_nr;
|
selectors = obj->_variables.size();
|
||||||
|
|
||||||
if (s->version < SCI_VERSION(1, 001, 000))
|
if (s->version < SCI_VERSION(1, 001, 000))
|
||||||
selectoroffset = ((byte *)(obj->base_obj)) + SCRIPT_SELECTOR_OFFSET + selectors * 2;
|
selectoroffset = ((byte *)(obj->base_obj)) + SCRIPT_SELECTOR_OFFSET + selectors * 2;
|
||||||
else {
|
else {
|
||||||
if (!(obj->variables[SCRIPT_INFO_SELECTOR].offset & SCRIPT_INFO_CLASS)) {
|
if (!(obj->_variables[SCRIPT_INFO_SELECTOR].offset & SCRIPT_INFO_CLASS)) {
|
||||||
obj = obj_get(s, obj->variables[SCRIPT_SUPERCLASS_SELECTOR]);
|
obj = obj_get(s, obj->_variables[SCRIPT_SUPERCLASS_SELECTOR]);
|
||||||
selectoroffset = (byte *)obj->base_vars;
|
selectoroffset = (byte *)obj->base_vars;
|
||||||
} else
|
} else
|
||||||
selectoroffset = (byte *)obj->base_vars;
|
selectoroffset = (byte *)obj->base_vars;
|
||||||
|
@ -2533,17 +2533,17 @@ int objinfo(EngineState *s, reg_t pos) {
|
||||||
|
|
||||||
print_obj_head(s, obj);
|
print_obj_head(s, obj);
|
||||||
|
|
||||||
if (!(obj->variables[SCRIPT_INFO_SELECTOR].offset & SCRIPT_INFO_CLASS))
|
if (!(obj->_variables[SCRIPT_INFO_SELECTOR].offset & SCRIPT_INFO_CLASS))
|
||||||
var_container = obj_get(s, obj->variables[SCRIPT_SUPERCLASS_SELECTOR]);
|
var_container = obj_get(s, obj->_variables[SCRIPT_SUPERCLASS_SELECTOR]);
|
||||||
sciprintf(" -- member variables:\n");
|
sciprintf(" -- member variables:\n");
|
||||||
for (i = 0; i < obj->variables_nr; i++) {
|
for (i = 0; (uint)i < obj->_variables.size(); i++) {
|
||||||
sciprintf(" ");
|
sciprintf(" ");
|
||||||
if (i < var_container->variable_names_nr)
|
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)));
|
sciprintf("[%03x] %s = ", VM_OBJECT_GET_VARSELECTOR(var_container, i), selector_name(s, VM_OBJECT_GET_VARSELECTOR(var_container, i)));
|
||||||
else
|
else
|
||||||
sciprintf("p#%x = ", i);
|
sciprintf("p#%x = ", i);
|
||||||
|
|
||||||
sciprintf(PREG"\n", PRINT_REG(obj->variables[i]));
|
sciprintf(PREG"\n", PRINT_REG(obj->_variables[i]));
|
||||||
}
|
}
|
||||||
sciprintf(" -- methods:\n");
|
sciprintf(" -- methods:\n");
|
||||||
for (i = 0; i < obj->methods_nr; i++) {
|
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);
|
disassemble(s, *pc, 0, 1);
|
||||||
if (_debug_seeking == _DEBUG_SEEK_GLOBAL)
|
if (_debug_seeking == _DEBUG_SEEK_GLOBAL)
|
||||||
sciprintf("Global %d (0x%x) = "PREG"\n", _debug_seek_special,
|
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;
|
_debugstate_valid = old_debugstate;
|
||||||
|
|
||||||
|
|
|
@ -361,9 +361,6 @@ void Script::freeScript() {
|
||||||
buf = NULL;
|
buf = NULL;
|
||||||
buf_size = 0;
|
buf_size = 0;
|
||||||
|
|
||||||
for (uint i = 0; i < _objects.size(); i++) {
|
|
||||||
free(_objects[i].variables);
|
|
||||||
}
|
|
||||||
_objects.clear();
|
_objects.clear();
|
||||||
|
|
||||||
delete obj_indices;
|
delete obj_indices;
|
||||||
|
@ -498,38 +495,37 @@ int SegManager::getSynonymsNr(int id, idFlag flag) {
|
||||||
return scr->synonyms_nr;
|
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 rel = location - block_location;
|
||||||
int index;
|
|
||||||
|
|
||||||
if (rel < 0)
|
if (rel < 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
index = rel >> 1;
|
uint idx = rel >> 1;
|
||||||
|
|
||||||
if (index >= block_items)
|
if (idx >= block.size())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (rel & 1) {
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
block[index].segment = segment; // Perform relocation
|
block[idx].segment = segment; // Perform relocation
|
||||||
if (isSci1_1)
|
if (isSci1_1)
|
||||||
block[index].offset += getScript(segment, SEG_ID)->script_size;
|
block[idx].offset += getScript(segment, SEG_ID)->script_size;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SegManager::relocateLocal(Script *scr, SegmentId segment, int location) {
|
int SegManager::relocateLocal(Script *scr, SegmentId segment, int location) {
|
||||||
if (scr->locals_block)
|
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
|
else
|
||||||
return 0; // No hands, no cookies
|
return 0; // No hands, no cookies
|
||||||
}
|
}
|
||||||
|
|
||||||
int SegManager::relocateObject(Object *obj, SegmentId segment, int location) {
|
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) {
|
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("While processing relocation block "PREG":\n", PRINT_REG(block));
|
||||||
sciprintf("Relocation failed for index %04x (%d/%d)\n", pos, i + 1, count);
|
sciprintf("Relocation failed for index %04x (%d/%d)\n", pos, i + 1, count);
|
||||||
if (scr->locals_block)
|
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
|
else
|
||||||
sciprintf("- No locals\n");
|
sciprintf("- No locals\n");
|
||||||
for (k = 0; k < scr->_objects.size(); k++)
|
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.
|
// SQ3 script 71 has broken relocation entries.
|
||||||
// Since this is mainstream, we can't break out as we used to do.
|
// Since this is mainstream, we can't break out as we used to do.
|
||||||
sciprintf("Trying to continue anyway...\n");
|
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("While processing relocation block "PREG":\n", PRINT_REG(block));
|
||||||
sciprintf("Relocation failed for index %04x (%d/%d)\n", pos, i + 1, count);
|
sciprintf("Relocation failed for index %04x (%d/%d)\n", pos, i + 1, count);
|
||||||
if (scr->locals_block)
|
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
|
else
|
||||||
sciprintf("- No locals\n");
|
sciprintf("- No locals\n");
|
||||||
for (k = 0; k < scr->_objects.size(); k++)
|
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");
|
sciprintf("Triggering breakpoint...\n");
|
||||||
BREAKPOINT();
|
BREAKPOINT();
|
||||||
}
|
}
|
||||||
|
@ -671,8 +667,7 @@ Object *SegManager::scriptObjInit0(EngineState *s, reg_t obj_pos) {
|
||||||
// add again for classes, since those also store selectors
|
// 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");
|
+ (is_class ? functions_nr * 2 : 0) < scr->buf_size, "Function area extends beyond end of script");
|
||||||
|
|
||||||
obj->variables_nr = variables_nr;
|
obj->_variables.resize(variables_nr);
|
||||||
obj->variables = (reg_t *)malloc(sizeof(reg_t) * variables_nr);
|
|
||||||
|
|
||||||
obj->methods_nr = functions_nr;
|
obj->methods_nr = functions_nr;
|
||||||
obj->base = scr->buf;
|
obj->base = scr->buf;
|
||||||
|
@ -681,7 +676,7 @@ Object *SegManager::scriptObjInit0(EngineState *s, reg_t obj_pos) {
|
||||||
obj->base_vars = NULL;
|
obj->base_vars = NULL;
|
||||||
|
|
||||||
for (i = 0; i < variables_nr; i++)
|
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;
|
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");
|
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->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->methods_nr = functions_nr;
|
||||||
obj->base = scr->buf;
|
obj->base = scr->buf;
|
||||||
obj->base_obj = data;
|
obj->base_obj = data;
|
||||||
|
|
||||||
for (i = 0; i < variables_nr; i++)
|
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;
|
return obj;
|
||||||
|
@ -755,21 +749,19 @@ LocalVariables *SegManager::allocLocalsSegment(Script *scr, int count) {
|
||||||
scr->locals_block = NULL;
|
scr->locals_block = NULL;
|
||||||
return NULL;
|
return NULL;
|
||||||
} else {
|
} else {
|
||||||
MemObject *mobj;
|
|
||||||
LocalVariables *locals;
|
LocalVariables *locals;
|
||||||
|
|
||||||
if (scr->locals_segment) {
|
if (scr->locals_segment) {
|
||||||
mobj = _heap[scr->locals_segment];
|
locals = (LocalVariables *)_heap[scr->locals_segment];
|
||||||
VERIFY(mobj != NULL, "Re-used locals segment was NULL'd out");
|
VERIFY(locals != 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(locals->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");
|
VERIFY(locals->script_id == scr->nr, "Re-used locals segment belonged to other script");
|
||||||
} else
|
} 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->script_id = scr->nr;
|
||||||
locals->locals = (reg_t *)calloc(count, sizeof(reg_t));
|
locals->_locals.resize(count);
|
||||||
locals->nr = count;
|
|
||||||
|
|
||||||
return locals;
|
return locals;
|
||||||
}
|
}
|
||||||
|
@ -808,7 +800,7 @@ void SegManager::scriptInitialiseLocals(reg_t location) {
|
||||||
byte *base = (byte *)(scr->buf + location.offset);
|
byte *base = (byte *)(scr->buf + location.offset);
|
||||||
|
|
||||||
for (i = 0; i < count; i++)
|
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);
|
obj = scriptObjInit(s, reg);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if (obj->variables[5].offset != 0xffff) {
|
if (obj->_variables[5].offset != 0xffff) {
|
||||||
obj->variables[5] = INST_LOOKUP_CLASS(obj->variables[5].offset);
|
obj->_variables[5] = INST_LOOKUP_CLASS(obj->_variables[5].offset);
|
||||||
base_obj = obj_get(s, obj->variables[5]);
|
base_obj = obj_get(s, obj->_variables[5]);
|
||||||
obj->variable_names_nr = base_obj->variables_nr;
|
obj->variable_names_nr = base_obj->variables_nr;
|
||||||
obj->base_obj = base_obj->base_obj;
|
obj->base_obj = base_obj->base_obj;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Copy base from species class, as we need its selector IDs
|
// 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;
|
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) {
|
byte *LocalVariables::dereference(reg_t pointer, int *size) {
|
||||||
int count = nr * sizeof(reg_t);
|
// FIXME: The following doesn't seem to be endian safe.
|
||||||
byte *base = (byte *)locals;
|
// 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)
|
if (size)
|
||||||
*size = count;
|
*size = count;
|
||||||
|
@ -1164,8 +1159,8 @@ void Script::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param,
|
||||||
(*note)(param, make_reg(script->locals_segment, 0));
|
(*note)(param, make_reg(script->locals_segment, 0));
|
||||||
|
|
||||||
Object &obj = script->_objects[idx];
|
Object &obj = script->_objects[idx];
|
||||||
for (int i = 0; i < obj.variables_nr; i++)
|
for (uint i = 0; i < obj._variables.size(); i++)
|
||||||
(*note)(param, obj.variables[i]);
|
(*note)(param, obj._variables[i]);
|
||||||
} else {
|
} else {
|
||||||
warning("Request for outgoing script-object reference at "PREG" yielded invalid index %d", PRINT_REG(addr), idx);
|
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) {
|
void CloneTable::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note) {
|
||||||
CloneTable *clone_table = this;
|
CloneTable *clone_table = this;
|
||||||
Clone *clone;
|
Clone *clone;
|
||||||
int i;
|
|
||||||
|
|
||||||
// assert(addr.segment == _segId);
|
// assert(addr.segment == _segId);
|
||||||
|
|
||||||
|
@ -1201,8 +1195,8 @@ void CloneTable::listAllOutgoingReferences(EngineState *s, reg_t addr, void *par
|
||||||
clone = &(clone_table->_table[addr.offset]);
|
clone = &(clone_table->_table[addr.offset]);
|
||||||
|
|
||||||
// Emit all member variables (including references to the 'super' delegate)
|
// Emit all member variables (including references to the 'super' delegate)
|
||||||
for (i = 0; i < clone->variables_nr; i++)
|
for (uint i = 0; i < clone->_variables.size(); i++)
|
||||||
(*note)(param, clone->variables[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 that this also includes the 'base' object, which is part of the script and therefore also emits the locals.
|
||||||
(*note)(param, clone->pos);
|
(*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 "PREG": Freeing\n", PRINT_REG(addr));
|
||||||
sciprintf("[GC] Clone had pos "PREG"\n", PRINT_REG(victim_obj->pos));
|
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);
|
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) {
|
void LocalVariables::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note) {
|
||||||
// assert(addr.segment == _segId);
|
// assert(addr.segment == _segId);
|
||||||
|
|
||||||
for (int i = 0; i < nr; i++)
|
for (uint i = 0; i < _locals.size(); i++)
|
||||||
(*note)(param, locals[i]);
|
(*note)(param, _locals[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -395,7 +395,7 @@ private:
|
||||||
Hunk *alloc_Hunk(reg_t *);
|
Hunk *alloc_Hunk(reg_t *);
|
||||||
|
|
||||||
int relocateLocal(Script *scr, SegmentId segment, int location);
|
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 relocateObject(Object *obj, SegmentId segment, int location);
|
||||||
|
|
||||||
int findFreeId(int *id);
|
int findFreeId(int *id);
|
||||||
|
|
|
@ -231,7 +231,7 @@ public:
|
||||||
SegmentId script_000_segment;
|
SegmentId script_000_segment;
|
||||||
Script *script_000; /**< script 000, e.g. for globals */
|
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 */
|
int parser_lastmatch_word; /**< Position of the input word the parser last matched on, or SAID_NO_MATCH */
|
||||||
|
|
||||||
|
|
|
@ -72,16 +72,16 @@ static reg_t &validate_property(Object *obj, int index) {
|
||||||
return _dummy_register;
|
return _dummy_register;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (index < 0 || index >= obj->variables_nr) {
|
if (index < 0 || (uint)index >= obj->_variables.size()) {
|
||||||
if (sci_debug_flags & 4)
|
if (sci_debug_flags & 4)
|
||||||
sciprintf("[VM] Invalid property #%d (out of [0..%d]) requested!\n", index,
|
sciprintf("[VM] Invalid property #%d (out of [0..%d]) requested!\n", index,
|
||||||
obj->variables_nr);
|
obj->_variables.size());
|
||||||
|
|
||||||
_dummy_register = NULL_REG;
|
_dummy_register = NULL_REG;
|
||||||
return _dummy_register;
|
return _dummy_register;
|
||||||
}
|
}
|
||||||
|
|
||||||
return obj->variables[index];
|
return obj->_variables[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
static StackPtr validate_stack_addr(EngineState *s, StackPtr sp) {
|
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_variable(r, sb, t, m, i, l)
|
||||||
# define validate_read_var(r, sb, t, m, i, l) ((r)[i])
|
# 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_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
|
# define ASSERT_ARITHMETIC(v) (v).offset
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -614,7 +614,7 @@ void run_vm(EngineState *s, int restoring) {
|
||||||
#ifndef DISABLE_VALIDATIONS
|
#ifndef DISABLE_VALIDATIONS
|
||||||
// Initialize maximum variable count
|
// Initialize maximum variable count
|
||||||
if (s->script_000->locals_block)
|
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
|
else
|
||||||
variables_max[VAR_GLOBAL] = 0;
|
variables_max[VAR_GLOBAL] = 0;
|
||||||
#endif
|
#endif
|
||||||
|
@ -625,7 +625,7 @@ void run_vm(EngineState *s, int restoring) {
|
||||||
|
|
||||||
// SCI code reads the zeroeth argument to determine argc
|
// SCI code reads the zeroeth argument to determine argc
|
||||||
if (s->script_000->locals_block)
|
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
|
else
|
||||||
variables_base[VAR_GLOBAL] = variables[VAR_GLOBAL] = NULL;
|
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;
|
variables_seg[VAR_LOCAL] = local_script->locals_segment;
|
||||||
if (local_script->locals_block)
|
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
|
else
|
||||||
variables_base[VAR_LOCAL] = variables[VAR_LOCAL] = NULL;
|
variables_base[VAR_LOCAL] = variables[VAR_LOCAL] = NULL;
|
||||||
#ifndef DISABLE_VALIDATIONS
|
#ifndef DISABLE_VALIDATIONS
|
||||||
if (local_script->locals_block)
|
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
|
else
|
||||||
variables_max[VAR_LOCAL] = 0;
|
variables_max[VAR_LOCAL] = 0;
|
||||||
variables_max[VAR_TEMP] = xs->sp - xs->fp;
|
variables_max[VAR_TEMP] = xs->sp - xs->fp;
|
||||||
|
@ -1489,10 +1489,10 @@ static int _obj_locate_varselector(EngineState *s, Object *obj, Selector slc) {
|
||||||
} else {
|
} else {
|
||||||
byte *buf = (byte *) obj->base_vars;
|
byte *buf = (byte *) obj->base_vars;
|
||||||
int i;
|
int i;
|
||||||
int varnum = obj->variables[1].offset;
|
int varnum = obj->_variables[1].offset;
|
||||||
|
|
||||||
if (!(obj->variables[SCRIPT_INFO_SELECTOR].offset & SCRIPT_INFO_CLASS))
|
if (!(obj->_variables[SCRIPT_INFO_SELECTOR].offset & SCRIPT_INFO_CLASS))
|
||||||
buf = ((byte *) obj_get(s, obj->variables[SCRIPT_SUPERCLASS_SELECTOR])->base_vars);
|
buf = ((byte *) obj_get(s, obj->_variables[SCRIPT_SUPERCLASS_SELECTOR])->base_vars);
|
||||||
|
|
||||||
for (i = 0; i < varnum; i++)
|
for (i = 0; i < varnum; i++)
|
||||||
if (READ_LE_UINT16(buf + (i << 1)) == slc) // Found it?
|
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;
|
return kSelectorMethod;
|
||||||
} else {
|
} else {
|
||||||
seg_id = obj->variables[SCRIPT_SUPERCLASS_SELECTOR].segment;
|
seg_id = obj->_variables[SCRIPT_SUPERCLASS_SELECTOR].segment;
|
||||||
obj = obj_get(s, obj->variables[SCRIPT_SUPERCLASS_SELECTOR]);
|
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))
|
if (IS_CLASS(obj))
|
||||||
species = obj;
|
species = obj;
|
||||||
else
|
else
|
||||||
species = obj_get(s, obj->variables[SCRIPT_SPECIES_SELECTOR]);
|
species = obj_get(s, obj->_variables[SCRIPT_SPECIES_SELECTOR]);
|
||||||
|
|
||||||
|
|
||||||
if (!obj) {
|
if (!obj) {
|
||||||
CORE_ERROR("SLC-LU", "Error while looking up Species class");
|
CORE_ERROR("SLC-LU", "Error while looking up Species class");
|
||||||
sciprintf("Original address was "PREG"\n", PRINT_REG(obj_location));
|
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;
|
return kSelectorNone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1576,7 +1576,7 @@ SelectorType lookup_selector(EngineState *s, reg_t obj_location, Selector select
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
// Found it as a variable
|
// Found it as a variable
|
||||||
if (vptr)
|
if (vptr)
|
||||||
*vptr = obj->variables + index;
|
*vptr = &obj->_variables[index];
|
||||||
return kSelectorVariable;
|
return kSelectorVariable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1851,14 +1851,14 @@ int script_instantiate_sci0(EngineState *s, int script_nr) {
|
||||||
Object *base_obj;
|
Object *base_obj;
|
||||||
|
|
||||||
// Instantiate the superclass, if neccessary
|
// 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]);
|
base_obj = obj_get(s, obj->_variables[SCRIPT_SPECIES_SELECTOR]);
|
||||||
obj->variable_names_nr = base_obj->variables_nr;
|
obj->variable_names_nr = base_obj->_variables.size();
|
||||||
obj->base_obj = base_obj->base_obj;
|
obj->base_obj = base_obj->base_obj;
|
||||||
// Copy base from species class, as we need its selector IDs
|
// 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
|
} // if object or class
|
||||||
break;
|
break;
|
||||||
case sci_obj_pointers: // A relocation table
|
case sci_obj_pointers: // A relocation table
|
||||||
|
@ -2114,7 +2114,7 @@ const char *obj_get_name(EngineState *s, reg_t pos) {
|
||||||
if (!obj)
|
if (!obj)
|
||||||
return "<no such object>";
|
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() {
|
void quit_vm() {
|
||||||
|
|
|
@ -225,7 +225,7 @@ struct Class {
|
||||||
#define RAW_GET_CLASS_INDEX(scr, reg) ((scr)->obj_indices->checkKey(reg.offset, false))
|
#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 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() */
|
/** This struct is used to buffer the list of send calls in send_selector() */
|
||||||
struct CallsStruct {
|
struct CallsStruct {
|
||||||
|
@ -242,18 +242,11 @@ struct CallsStruct {
|
||||||
|
|
||||||
struct LocalVariables : public MemObject {
|
struct LocalVariables : public MemObject {
|
||||||
int script_id; /**< Script ID this local variable block belongs to */
|
int script_id; /**< Script ID this local variable block belongs to */
|
||||||
reg_t *locals;
|
Common::Array<reg_t> _locals;
|
||||||
int nr;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LocalVariables() {
|
LocalVariables() {
|
||||||
script_id = 0;
|
script_id = 0;
|
||||||
locals = 0;
|
|
||||||
nr = 0;
|
|
||||||
}
|
|
||||||
~LocalVariables() {
|
|
||||||
free(locals);
|
|
||||||
locals = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual byte *dereference(reg_t pointer, int *size);
|
virtual byte *dereference(reg_t pointer, int *size);
|
||||||
|
@ -269,14 +262,13 @@ public:
|
||||||
struct Object {
|
struct Object {
|
||||||
int flags;
|
int flags;
|
||||||
reg_t pos; /**< Object offset within its script; for clones, this is their base */
|
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 variable_names_nr; /**< Number of variable names, may be less than variables_nr */
|
||||||
int methods_nr;
|
int methods_nr;
|
||||||
byte *base; /**< Points to a buffer all relative references (code, strings) point to */
|
byte *base; /**< Points to a buffer all relative references (code, strings) point to */
|
||||||
byte *base_obj; /**< base + object offset within base */
|
byte *base_obj; /**< base + object offset within base */
|
||||||
uint16 *base_method; /**< Pointer to the method selector area for this object */
|
uint16 *base_method; /**< Pointer to the method selector area for this object */
|
||||||
uint16 *base_vars; /**< Pointer to the varselector 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 {
|
struct CodeBlock {
|
||||||
|
@ -286,9 +278,9 @@ struct CodeBlock {
|
||||||
|
|
||||||
#define VM_OBJECT_GET_VARSELECTOR(obj, i) \
|
#define VM_OBJECT_GET_VARSELECTOR(obj, i) \
|
||||||
(s->version < SCI_VERSION(1,001,000) ? \
|
(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))
|
*(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) \
|
#define VM_OBJECT_GET_FUNCSELECTOR(obj, i) \
|
||||||
(s->version < SCI_VERSION(1,001,000) ? \
|
(s->version < SCI_VERSION(1,001,000) ? \
|
||||||
READ_LE_UINT16((byte *) (obj->base_method + i)) : \
|
READ_LE_UINT16((byte *) (obj->base_method + i)) : \
|
||||||
|
@ -485,12 +477,6 @@ public:
|
||||||
|
|
||||||
/* CloneTable */
|
/* CloneTable */
|
||||||
struct CloneTable : public Table<Clone> {
|
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 freeAtAddress(SegManager *segmgr, reg_t sub_addr);
|
||||||
virtual void listAllOutgoingReferences(EngineState *s, reg_t object, void *param, NoteCallback note);
|
virtual void listAllOutgoingReferences(EngineState *s, reg_t object, void *param, NoteCallback note);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue