Started rewriting the Object struct into a class
svn-id: r44878
This commit is contained in:
parent
8fd29ecf9f
commit
d6f5d93dbf
12 changed files with 165 additions and 204 deletions
|
@ -1353,11 +1353,11 @@ bool Console::segmentInfo(int nr) {
|
||||||
for (it = scr->_objects.begin(); it != end; ++it) {
|
for (it = scr->_objects.begin(); it != end; ++it) {
|
||||||
DebugPrintf(" ");
|
DebugPrintf(" ");
|
||||||
// Object header
|
// Object header
|
||||||
Object *obj = _vm->_gamestate->_segMan->getObject(it->_value._pos);
|
Object *obj = _vm->_gamestate->_segMan->getObject(it->_value.getPos());
|
||||||
if (obj)
|
if (obj)
|
||||||
DebugPrintf("[%04x:%04x] %s : %3d vars, %3d methods\n", PRINT_REG(it->_value._pos),
|
DebugPrintf("[%04x:%04x] %s : %3d vars, %3d methods\n", PRINT_REG(it->_value.getPos()),
|
||||||
_vm->_gamestate->_segMan->getObjectName(it->_value._pos),
|
_vm->_gamestate->_segMan->getObjectName(it->_value.getPos()),
|
||||||
obj->_variables.size(), obj->methods_nr);
|
obj->getVarCount(), obj->getMethodCount());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1400,11 +1400,11 @@ bool Console::segmentInfo(int nr) {
|
||||||
objpos.segment = nr;
|
objpos.segment = nr;
|
||||||
DebugPrintf(" [%04x] %s; copy of ", i, _vm->_gamestate->_segMan->getObjectName(objpos));
|
DebugPrintf(" [%04x] %s; copy of ", i, _vm->_gamestate->_segMan->getObjectName(objpos));
|
||||||
// Object header
|
// Object header
|
||||||
Object *obj = _vm->_gamestate->_segMan->getObject(ct->_table[i]._pos);
|
Object *obj = _vm->_gamestate->_segMan->getObject(ct->_table[i].getPos());
|
||||||
if (obj)
|
if (obj)
|
||||||
DebugPrintf("[%04x:%04x] %s : %3d vars, %3d methods\n", PRINT_REG(ct->_table[i]._pos),
|
DebugPrintf("[%04x:%04x] %s : %3d vars, %3d methods\n", PRINT_REG(ct->_table[i].getPos()),
|
||||||
_vm->_gamestate->_segMan->getObjectName(ct->_table[i]._pos),
|
_vm->_gamestate->_segMan->getObjectName(ct->_table[i].getPos()),
|
||||||
obj->_variables.size(), obj->methods_nr);
|
obj->getVarCount(), obj->getMethodCount());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -2935,7 +2935,7 @@ int Console::printObject(reg_t pos) {
|
||||||
EngineState *s = _vm->_gamestate; // for the several defines in this function
|
EngineState *s = _vm->_gamestate; // for the several defines in this function
|
||||||
Object *obj = s->_segMan->getObject(pos);
|
Object *obj = s->_segMan->getObject(pos);
|
||||||
Object *var_container = obj;
|
Object *var_container = obj;
|
||||||
int i;
|
uint i;
|
||||||
|
|
||||||
if (!obj) {
|
if (!obj) {
|
||||||
DebugPrintf("[%04x:%04x]: Not an object.", PRINT_REG(pos));
|
DebugPrintf("[%04x:%04x]: Not an object.", PRINT_REG(pos));
|
||||||
|
@ -2944,20 +2944,20 @@ int Console::printObject(reg_t pos) {
|
||||||
|
|
||||||
// Object header
|
// Object header
|
||||||
DebugPrintf("[%04x:%04x] %s : %3d vars, %3d methods\n", PRINT_REG(pos), s->_segMan->getObjectName(pos),
|
DebugPrintf("[%04x:%04x] %s : %3d vars, %3d methods\n", PRINT_REG(pos), s->_segMan->getObjectName(pos),
|
||||||
obj->_variables.size(), obj->methods_nr);
|
obj->getVarCount(), obj->getMethodCount());
|
||||||
|
|
||||||
if (!(obj->getInfoSelector().offset & SCRIPT_INFO_CLASS))
|
if (!(obj->getInfoSelector().offset & SCRIPT_INFO_CLASS))
|
||||||
var_container = s->_segMan->getObject(obj->getSuperClassSelector());
|
var_container = s->_segMan->getObject(obj->getSuperClassSelector());
|
||||||
DebugPrintf(" -- member variables:\n");
|
DebugPrintf(" -- member variables:\n");
|
||||||
for (i = 0; (uint)i < obj->_variables.size(); i++) {
|
for (i = 0; (uint)i < obj->getVarCount(); i++) {
|
||||||
printf(" ");
|
printf(" ");
|
||||||
if (i < var_container->variable_names_nr) {
|
if (i < var_container->getVarCount()) {
|
||||||
uint16 varSelector = var_container->getVarSelector(i);
|
uint16 varSelector = var_container->getVarSelector(i);
|
||||||
DebugPrintf("[%03x] %s = ", varSelector, selector_name(s, varSelector));
|
DebugPrintf("[%03x] %s = ", varSelector, selector_name(s, varSelector));
|
||||||
} else
|
} else
|
||||||
DebugPrintf("p#%x = ", i);
|
DebugPrintf("p#%x = ", i);
|
||||||
|
|
||||||
reg_t val = obj->_variables[i];
|
reg_t val = obj->getVariable(i);
|
||||||
DebugPrintf("%04x:%04x", PRINT_REG(val));
|
DebugPrintf("%04x:%04x", PRINT_REG(val));
|
||||||
|
|
||||||
Object *ref = s->_segMan->getObject(val);
|
Object *ref = s->_segMan->getObject(val);
|
||||||
|
@ -2967,7 +2967,7 @@ int Console::printObject(reg_t pos) {
|
||||||
DebugPrintf("\n");
|
DebugPrintf("\n");
|
||||||
}
|
}
|
||||||
DebugPrintf(" -- methods:\n");
|
DebugPrintf(" -- methods:\n");
|
||||||
for (i = 0; i < obj->methods_nr; i++) {
|
for (i = 0; i < obj->getMethodCount(); i++) {
|
||||||
reg_t fptr = obj->getFunction(i);
|
reg_t fptr = obj->getFunction(i);
|
||||||
DebugPrintf(" [%03x] %s = %04x:%04x\n", obj->getFuncSelector(i), selector_name(s, obj->getFuncSelector(i)), PRINT_REG(fptr));
|
DebugPrintf(" [%03x] %s = %04x:%04x\n", obj->getFuncSelector(i), selector_name(s, obj->getFuncSelector(i)), PRINT_REG(fptr));
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,7 +122,7 @@ reg_t_hash_map *find_all_used_references(EngineState *s) {
|
||||||
ObjMap::iterator it;
|
ObjMap::iterator it;
|
||||||
const ObjMap::iterator end = script->_objects.end();
|
const ObjMap::iterator end = script->_objects.end();
|
||||||
for (it = script->_objects.begin(); it != end; ++it) {
|
for (it = script->_objects.begin(); it != end; ++it) {
|
||||||
wm.push(it->_value._pos);
|
wm.push(it->_value.getPos());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -123,15 +123,14 @@ reg_t kClone(EngineState *s, int argc, reg_t *argv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
*clone_obj = *parent_obj;
|
*clone_obj = *parent_obj;
|
||||||
clone_obj->_flags = 0;
|
|
||||||
|
|
||||||
// Mark as clone
|
// Mark as clone
|
||||||
clone_obj->setInfoSelector(make_reg(0, SCRIPT_INFO_CLONE));
|
clone_obj->setInfoSelector(make_reg(0, SCRIPT_INFO_CLONE));
|
||||||
clone_obj->setSpeciesSelector(clone_obj->_pos);
|
clone_obj->setSpeciesSelector(clone_obj->getPos());
|
||||||
if (parent_obj->isClass())
|
if (parent_obj->isClass())
|
||||||
clone_obj->setSuperClassSelector(parent_obj->_pos);
|
clone_obj->setSuperClassSelector(parent_obj->getPos());
|
||||||
s->_segMan->getScript(parent_obj->_pos.segment)->incrementLockers();
|
s->_segMan->getScript(parent_obj->getPos().segment)->incrementLockers();
|
||||||
s->_segMan->getScript(clone_obj->_pos.segment)->incrementLockers();
|
s->_segMan->getScript(clone_obj->getPos().segment)->incrementLockers();
|
||||||
|
|
||||||
return clone_addr;
|
return clone_addr;
|
||||||
}
|
}
|
||||||
|
@ -167,8 +166,8 @@ reg_t kDisposeClone(EngineState *s, int argc, reg_t *argv) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
victim_obj->_flags |= OBJECT_FLAG_FREED;
|
victim_obj->markAsFreed();
|
||||||
|
|
||||||
_k_view_list_mark_free(s, victim_addr); // Free on view list, if neccessary
|
_k_view_list_mark_free(s, victim_addr); // Free on view list, if neccessary
|
||||||
|
|
||||||
return s->r_acc;
|
return s->r_acc;
|
||||||
|
|
|
@ -312,14 +312,21 @@ void LocalVariables::saveLoadWithSerializer(Common::Serializer &s) {
|
||||||
syncArray<reg_t>(s, _locals);
|
syncArray<reg_t>(s, _locals);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
|
||||||
void syncWithSerializer(Common::Serializer &s, Object &obj) {
|
|
||||||
s.syncAsSint32LE(obj._flags);
|
|
||||||
sync_reg_t(s, obj._pos);
|
|
||||||
s.syncAsSint32LE(obj.variable_names_nr);
|
|
||||||
s.syncAsSint32LE(obj.methods_nr);
|
|
||||||
|
|
||||||
syncArray<reg_t>(s, obj._variables);
|
void Object::saveLoadWithSerializer(Common::Serializer &s) {
|
||||||
|
s.syncAsSint32LE(_flags);
|
||||||
|
sync_reg_t(s, _pos);
|
||||||
|
int varCount;
|
||||||
|
if (s.isLoading()) {
|
||||||
|
s.syncAsSint32LE(varCount);
|
||||||
|
_variables.resize(varCount);
|
||||||
|
} else {
|
||||||
|
varCount = _variables.size();
|
||||||
|
s.syncAsSint32LE(varCount);
|
||||||
|
}
|
||||||
|
s.syncAsSint32LE(_methodCount); // that's actually a uint16
|
||||||
|
|
||||||
|
syncArray<reg_t>(s, _variables);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
|
@ -411,7 +418,7 @@ void Script::saveLoadWithSerializer(Common::Serializer &s) {
|
||||||
Object tmp;
|
Object tmp;
|
||||||
for (uint i = 0; i < numObjs; ++i) {
|
for (uint i = 0; i < numObjs; ++i) {
|
||||||
syncWithSerializer<Object>(s, tmp);
|
syncWithSerializer<Object>(s, tmp);
|
||||||
_objects[tmp._pos.offset] = tmp;
|
_objects[tmp.getPos().offset] = tmp;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ObjMap::iterator it;
|
ObjMap::iterator it;
|
||||||
|
@ -605,8 +612,7 @@ void SegManager::reconstructScripts(EngineState *s) {
|
||||||
ObjMap::iterator it;
|
ObjMap::iterator it;
|
||||||
const ObjMap::iterator end = scr->_objects.end();
|
const ObjMap::iterator end = scr->_objects.end();
|
||||||
for (it = scr->_objects.begin(); it != end; ++it) {
|
for (it = scr->_objects.begin(); it != end; ++it) {
|
||||||
byte *data = scr->_buf + it->_value._pos.offset;
|
byte *data = scr->_buf + it->_value.getPos().offset;
|
||||||
it->_value.base = scr->_buf;
|
|
||||||
it->_value.base_obj = data;
|
it->_value.base_obj = data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -622,7 +628,7 @@ void SegManager::reconstructScripts(EngineState *s) {
|
||||||
ObjMap::iterator it;
|
ObjMap::iterator it;
|
||||||
const ObjMap::iterator end = scr->_objects.end();
|
const ObjMap::iterator end = scr->_objects.end();
|
||||||
for (it = scr->_objects.begin(); it != end; ++it) {
|
for (it = scr->_objects.begin(); it != end; ++it) {
|
||||||
byte *data = scr->_buf + it->_value._pos.offset;
|
byte *data = scr->_buf + it->_value.getPos().offset;
|
||||||
|
|
||||||
if (getSciVersion() >= SCI_VERSION_1_1) {
|
if (getSciVersion() >= SCI_VERSION_1_1) {
|
||||||
uint16 *funct_area = (uint16 *)(scr->_buf + READ_LE_UINT16( data + 6 ));
|
uint16 *funct_area = (uint16 *)(scr->_buf + READ_LE_UINT16( data + 6 ));
|
||||||
|
@ -641,11 +647,11 @@ void SegManager::reconstructScripts(EngineState *s) {
|
||||||
scr->_nr, i, PRINT_REG(it->_value.getSpeciesSelector()));
|
scr->_nr, i, PRINT_REG(it->_value.getSpeciesSelector()));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
it->_value.variable_names_nr = base_obj->_variables.size();
|
it->_value.setVarCount(base_obj->getVarCount());
|
||||||
it->_value.base_obj = base_obj->base_obj;
|
it->_value.base_obj = base_obj->base_obj;
|
||||||
|
|
||||||
it->_value.base_method = (uint16 *)(data + funct_area);
|
it->_value.base_method = (uint16 *)(data + funct_area);
|
||||||
it->_value.base_vars = (uint16 *)(data + it->_value.variable_names_nr * 2 + SCRIPT_SELECTOR_OFFSET);
|
it->_value.base_vars = (uint16 *)(data + it->_value.getVarCount() * 2 + SCRIPT_SELECTOR_OFFSET);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,7 +75,7 @@ int propertyOffsetToId(SegManager *segMan, int prop_ofs, reg_t objp) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
selectors = obj->_variables.size();
|
selectors = obj->getVarCount();
|
||||||
|
|
||||||
if (getSciVersion() < SCI_VERSION_1_1)
|
if (getSciVersion() < SCI_VERSION_1_1)
|
||||||
selectoroffset = ((byte *)(obj->base_obj)) + SCRIPT_SELECTOR_OFFSET + selectors * 2;
|
selectoroffset = ((byte *)(obj->base_obj)) + SCRIPT_SELECTOR_OFFSET + selectors * 2;
|
||||||
|
|
|
@ -184,9 +184,7 @@ int SegManager::deallocate(SegmentId seg, bool recursive) {
|
||||||
|
|
||||||
bool SegManager::isHeapObject(reg_t pos) {
|
bool SegManager::isHeapObject(reg_t pos) {
|
||||||
Object *obj = getObject(pos);
|
Object *obj = getObject(pos);
|
||||||
if (obj == NULL)
|
if (obj == NULL || (obj && obj->isFreed()))
|
||||||
return false;
|
|
||||||
if (obj->_flags & OBJECT_FLAG_FREED)
|
|
||||||
return false;
|
return false;
|
||||||
Script *scr = getScriptIfLoaded(pos.segment);
|
Script *scr = getScriptIfLoaded(pos.segment);
|
||||||
return !(scr && scr->_markedAsDeleted);
|
return !(scr && scr->_markedAsDeleted);
|
||||||
|
@ -305,7 +303,7 @@ reg_t SegManager::findObjectByName(const Common::String &name, int index) {
|
||||||
|
|
||||||
if (mobj->getType() == SEG_TYPE_SCRIPT) {
|
if (mobj->getType() == SEG_TYPE_SCRIPT) {
|
||||||
obj = &(it->_value);
|
obj = &(it->_value);
|
||||||
objpos.offset = obj->_pos.offset;
|
objpos.offset = obj->getPos().offset;
|
||||||
++it;
|
++it;
|
||||||
} else if (mobj->getType() == SEG_TYPE_CLONES) {
|
} else if (mobj->getType() == SEG_TYPE_CLONES) {
|
||||||
if (!ct->isValidEntry(idx))
|
if (!ct->isValidEntry(idx))
|
||||||
|
@ -396,7 +394,7 @@ int Script::relocateLocal(SegmentId segment, int location) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int Script::relocateObject(Object &obj, SegmentId segment, int location) {
|
int Script::relocateObject(Object &obj, SegmentId segment, int location) {
|
||||||
return relocateBlock(obj._variables, obj._pos.offset, segment, location);
|
return relocateBlock(obj._variables, obj.getPos().offset, segment, location);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Script::scriptAddCodeBlock(reg_t location) {
|
void Script::scriptAddCodeBlock(reg_t location) {
|
||||||
|
@ -442,7 +440,7 @@ void Script::scriptRelocate(reg_t block) {
|
||||||
else
|
else
|
||||||
printf("- No locals\n");
|
printf("- No locals\n");
|
||||||
for (it = _objects.begin(), k = 0; it != end; ++it, ++k)
|
for (it = _objects.begin(), k = 0; it != end; ++it, ++k)
|
||||||
printf("- obj#%d at %04x w/ %d vars\n", k, it->_value._pos.offset, it->_value._variables.size());
|
printf("- obj#%d at %04x w/ %d vars\n", k, it->_value.getPos().offset, it->_value.getVarCount());
|
||||||
// SQ3 script 71 has broken relocation entries.
|
// SQ3 script 71 has broken relocation entries.
|
||||||
printf("Trying to continue anyway...\n");
|
printf("Trying to continue anyway...\n");
|
||||||
}
|
}
|
||||||
|
@ -481,7 +479,7 @@ void Script::heapRelocate(reg_t block) {
|
||||||
else
|
else
|
||||||
printf("- No locals\n");
|
printf("- No locals\n");
|
||||||
for (it = _objects.begin(), k = 0; it != end; ++it, ++k)
|
for (it = _objects.begin(), k = 0; it != end; ++it, ++k)
|
||||||
printf("- obj#%d at %04x w/ %d vars\n", k, it->_value._pos.offset, it->_value._variables.size());
|
printf("- obj#%d at %04x w/ %d vars\n", k, it->_value.getPos().offset, it->_value.getVarCount());
|
||||||
error("Breakpoint in %s, line %d", __FILE__, __LINE__);
|
error("Breakpoint in %s, line %d", __FILE__, __LINE__);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -545,45 +543,7 @@ Object *Script::scriptObjInit(reg_t obj_pos) {
|
||||||
|
|
||||||
VERIFY(obj_pos.offset + SCRIPT_FUNCTAREAPTR_OFFSET < (int)_bufSize, "Function area pointer stored beyond end of script\n");
|
VERIFY(obj_pos.offset + SCRIPT_FUNCTAREAPTR_OFFSET < (int)_bufSize, "Function area pointer stored beyond end of script\n");
|
||||||
|
|
||||||
byte *data = (byte *)(_buf + obj_pos.offset);
|
obj->init(_buf, obj_pos);
|
||||||
uint16 *funct_area = 0;
|
|
||||||
bool isClass;
|
|
||||||
|
|
||||||
if (getSciVersion() < SCI_VERSION_1_1) {
|
|
||||||
obj->variable_names_nr = READ_LE_UINT16(data + SCRIPT_SELECTORCTR_OFFSET);
|
|
||||||
obj->base_vars = 0;
|
|
||||||
funct_area = (uint16 *)(data + READ_LE_UINT16(data + SCRIPT_FUNCTAREAPTR_OFFSET));
|
|
||||||
obj->methods_nr = READ_LE_UINT16(funct_area - 1);
|
|
||||||
isClass = READ_LE_UINT16(data + 4) & SCRIPT_INFO_CLASS; // SCRIPT_INFO_OFFSET
|
|
||||||
} else {
|
|
||||||
obj->variable_names_nr = READ_LE_UINT16(data + 2);
|
|
||||||
obj->base_vars = (uint16 *)(_buf + READ_LE_UINT16(data + 4));
|
|
||||||
funct_area = (uint16 *)(_buf + READ_LE_UINT16(data + 6));
|
|
||||||
obj->methods_nr = READ_LE_UINT16(funct_area);
|
|
||||||
isClass = READ_LE_UINT16(data + 14) & SCRIPT_INFO_CLASS;
|
|
||||||
}
|
|
||||||
|
|
||||||
obj->_flags = 0;
|
|
||||||
obj->_pos = obj_pos;
|
|
||||||
obj->base_method = funct_area;
|
|
||||||
|
|
||||||
VERIFY((byte *)funct_area < _buf + _bufSize, "Function area pointer references beyond end of script");
|
|
||||||
|
|
||||||
if (getSciVersion() < SCI_VERSION_1_1) {
|
|
||||||
VERIFY((byte *)funct_area + obj->methods_nr * 2
|
|
||||||
// add again for classes, since those also store selectors
|
|
||||||
+ (isClass ? obj->methods_nr * 2 : 0) < _buf + _bufSize, "Function area extends beyond end of script");
|
|
||||||
} else {
|
|
||||||
VERIFY(((byte *)funct_area + obj->variable_names_nr) < _buf + _bufSize, "Function area extends beyond end of script");
|
|
||||||
}
|
|
||||||
|
|
||||||
obj->_variables.resize(obj->variable_names_nr);
|
|
||||||
|
|
||||||
obj->base = _buf;
|
|
||||||
obj->base_obj = data;
|
|
||||||
|
|
||||||
for (int i = 0; i < obj->variable_names_nr; i++)
|
|
||||||
obj->_variables[i] = make_reg(0, READ_LE_UINT16(data + (i * 2)));
|
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
@ -829,12 +789,10 @@ void SegManager::reconstructClones() {
|
||||||
base_obj = getObject(seeker.getSpeciesSelector());
|
base_obj = getObject(seeker.getSpeciesSelector());
|
||||||
if (!base_obj) {
|
if (!base_obj) {
|
||||||
warning("Clone entry without a base class: %d", j);
|
warning("Clone entry without a base class: %d", j);
|
||||||
seeker.base = NULL;
|
|
||||||
seeker.base_obj = NULL;
|
seeker.base_obj = NULL;
|
||||||
seeker.base_vars = NULL;
|
seeker.base_vars = NULL;
|
||||||
seeker.base_method = NULL;
|
seeker.base_method = NULL;
|
||||||
} else {
|
} else {
|
||||||
seeker.base = base_obj->base;
|
|
||||||
seeker.base_obj = base_obj->base_obj;
|
seeker.base_obj = base_obj->base_obj;
|
||||||
seeker.base_vars = base_obj->base_vars;
|
seeker.base_vars = base_obj->base_vars;
|
||||||
seeker.base_method = base_obj->base_method;
|
seeker.base_method = base_obj->base_method;
|
||||||
|
|
|
@ -336,8 +336,8 @@ void Script::listAllOutgoingReferences(reg_t addr, void *param, NoteCallback not
|
||||||
if (_localsSegment)
|
if (_localsSegment)
|
||||||
(*note)(param, make_reg(_localsSegment, 0));
|
(*note)(param, make_reg(_localsSegment, 0));
|
||||||
|
|
||||||
for (uint i = 0; i < obj->_variables.size(); i++)
|
for (uint i = 0; i < obj->getVarCount(); i++)
|
||||||
(*note)(param, obj->_variables[i]);
|
(*note)(param, obj->getVariable(i));
|
||||||
} else {
|
} else {
|
||||||
warning("Request for outgoing script-object reference at %04x:%04x failed", PRINT_REG(addr));
|
warning("Request for outgoing script-object reference at %04x:%04x failed", PRINT_REG(addr));
|
||||||
}
|
}
|
||||||
|
@ -362,11 +362,11 @@ void CloneTable::listAllOutgoingReferences(reg_t addr, void *param, NoteCallback
|
||||||
clone = &(_table[addr.offset]);
|
clone = &(_table[addr.offset]);
|
||||||
|
|
||||||
// Emit all member variables (including references to the 'super' delegate)
|
// Emit all member variables (including references to the 'super' delegate)
|
||||||
for (uint i = 0; i < clone->_variables.size(); i++)
|
for (uint i = 0; i < clone->getVarCount(); i++)
|
||||||
(*note)(param, clone->_variables[i]);
|
(*note)(param, clone->getVariable(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->getPos());
|
||||||
//debugC(2, kDebugLevelGC, "[GC] Reporting clone-pos %04x:%04x\n", PRINT_REG(clone->pos));
|
//debugC(2, kDebugLevelGC, "[GC] Reporting clone-pos %04x:%04x\n", PRINT_REG(clone->pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -191,80 +191,112 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Clone has been marked as 'freed' */
|
/** Clone has been marked as 'freed' */
|
||||||
#define OBJECT_FLAG_FREED (0x1 << 0)
|
#define OBJECT_FLAG_FREED (1 << 0)
|
||||||
|
|
||||||
// TODO: convert to class, perhaps?
|
class Object {
|
||||||
struct Object {
|
public:
|
||||||
int _flags;
|
Object() {
|
||||||
reg_t _pos; /**< Object offset within its script; for clones, this is their base */
|
_flags = 0;
|
||||||
int variable_names_nr; /**< Number of variable names, may be less than variables_nr */
|
_offset = getSciVersion() < SCI_VERSION_1_1 ? 0 : 5;
|
||||||
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 */
|
|
||||||
Common::Array<reg_t> _variables;
|
|
||||||
|
|
||||||
uint16 getVarSelector(uint16 i) {
|
~Object() { }
|
||||||
|
|
||||||
|
reg_t getSpeciesSelector() { return _variables[_offset]; }
|
||||||
|
void setSpeciesSelector(reg_t value) { _variables[_offset] = value; }
|
||||||
|
|
||||||
|
reg_t getSuperClassSelector() { return _variables[_offset + 1]; }
|
||||||
|
void setSuperClassSelector(reg_t value) { _variables[_offset + 1] = value; }
|
||||||
|
|
||||||
|
reg_t getInfoSelector() { return _variables[_offset + 2]; }
|
||||||
|
void setInfoSelector(reg_t value) { _variables[_offset + 2] = value; }
|
||||||
|
|
||||||
|
reg_t getNameSelector() { return _variables[_offset + 3]; }
|
||||||
|
void setNameSelector(reg_t value) { _variables[_offset + 3] = value; }
|
||||||
|
|
||||||
|
reg_t getClassScriptSelector() { return _variables[4]; }
|
||||||
|
void setClassScriptSelector(reg_t value) { _variables[4] = value; }
|
||||||
|
|
||||||
|
Selector getVarSelector(uint16 i) {
|
||||||
if (getSciVersion() < SCI_VERSION_1_1)
|
if (getSciVersion() < SCI_VERSION_1_1)
|
||||||
return READ_LE_UINT16(base_obj + _variables.size() * 2 + i * 2);
|
return READ_LE_UINT16(base_obj + _variables.size() * 2 + i * 2);
|
||||||
else
|
else
|
||||||
return *(base_vars + i);
|
return *(base_vars + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
reg_t getSpeciesSelector() {
|
Selector getFuncSelector(uint16 i) {
|
||||||
return _variables[getSciVersion() < SCI_VERSION_1_1 ? 0 : 5];
|
|
||||||
}
|
|
||||||
|
|
||||||
void setSpeciesSelector(reg_t value) {
|
|
||||||
_variables[getSciVersion() < SCI_VERSION_1_1 ? 0 : 5] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
reg_t getSuperClassSelector() {
|
|
||||||
return _variables[getSciVersion() < SCI_VERSION_1_1 ? 1 : 6];
|
|
||||||
}
|
|
||||||
|
|
||||||
void setSuperClassSelector(reg_t value) {
|
|
||||||
_variables[getSciVersion() < SCI_VERSION_1_1 ? 1 : 6] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
reg_t getInfoSelector() {
|
|
||||||
return _variables[getSciVersion() < SCI_VERSION_1_1 ? 2 : 7];
|
|
||||||
}
|
|
||||||
|
|
||||||
void setInfoSelector(reg_t value) {
|
|
||||||
_variables[getSciVersion() < SCI_VERSION_1_1 ? 2 : 7] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
reg_t getNameSelector() {
|
|
||||||
return _variables[getSciVersion() < SCI_VERSION_1_1 ? 3 : 8];
|
|
||||||
}
|
|
||||||
|
|
||||||
void setNameSelector(reg_t value) {
|
|
||||||
_variables[getSciVersion() < SCI_VERSION_1_1 ? 3 : 8] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
reg_t getClassScriptSelector() {
|
|
||||||
return _variables[4];
|
|
||||||
}
|
|
||||||
|
|
||||||
void setClassScriptSelector(reg_t value) {
|
|
||||||
_variables[4] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16 getFuncSelector(uint16 i) {
|
|
||||||
uint16 offset = (getSciVersion() < SCI_VERSION_1_1) ? i : i * 2 + 1;
|
uint16 offset = (getSciVersion() < SCI_VERSION_1_1) ? i : i * 2 + 1;
|
||||||
return READ_LE_UINT16((byte *) (base_method + offset));
|
return READ_LE_UINT16((byte *) (base_method + offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if this object is a class and explicitly defines the
|
||||||
|
* selector as a funcselector. Does NOT say anything about the object's
|
||||||
|
* superclasses, i.e. failure may be returned even if one of the
|
||||||
|
* superclasses defines the funcselector
|
||||||
|
*/
|
||||||
|
int funcSelectorPosition(Selector sel) {
|
||||||
|
for (uint i = 0; i < _methodCount; i++)
|
||||||
|
if (getFuncSelector(i) == sel)
|
||||||
|
return i;
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
reg_t getFunction(uint16 i) {
|
reg_t getFunction(uint16 i) {
|
||||||
uint16 offset = (getSciVersion() < SCI_VERSION_1_1) ? methods_nr + 1 + i : i * 2 + 2;
|
uint16 offset = (getSciVersion() < SCI_VERSION_1_1) ? _methodCount + 1 + i : i * 2 + 2;
|
||||||
return make_reg(_pos.segment, READ_LE_UINT16((byte *) (base_method + offset)));
|
return make_reg(_pos.segment, READ_LE_UINT16((byte *) (base_method + offset)));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isClass() {
|
bool isClass() { return (getInfoSelector().offset & SCRIPT_INFO_CLASS); }
|
||||||
return (getInfoSelector().offset & SCRIPT_INFO_CLASS);
|
|
||||||
|
void markAsFreed() { _flags |= OBJECT_FLAG_FREED; }
|
||||||
|
bool isFreed() { return _flags & OBJECT_FLAG_FREED; }
|
||||||
|
|
||||||
|
void setVarCount(uint size) { _variables.resize(size); }
|
||||||
|
uint getVarCount() { return _variables.size(); }
|
||||||
|
|
||||||
|
void init(byte *buf, reg_t obj_pos) {
|
||||||
|
byte *data = (byte *)(buf + obj_pos.offset);
|
||||||
|
base_obj = data;
|
||||||
|
_pos = obj_pos;
|
||||||
|
|
||||||
|
if (getSciVersion() < SCI_VERSION_1_1) {
|
||||||
|
setVarCount(READ_LE_UINT16(data + SCRIPT_SELECTORCTR_OFFSET));
|
||||||
|
base_vars = 0;
|
||||||
|
base_method = (uint16 *)(data + READ_LE_UINT16(data + SCRIPT_FUNCTAREAPTR_OFFSET));
|
||||||
|
_methodCount = READ_LE_UINT16(base_method - 1);
|
||||||
|
} else {
|
||||||
|
setVarCount(READ_LE_UINT16(data + 2));
|
||||||
|
base_vars = (uint16 *)(buf + READ_LE_UINT16(data + 4));
|
||||||
|
base_method = (uint16 *)(buf + READ_LE_UINT16(data + 6));
|
||||||
|
_methodCount = READ_LE_UINT16(base_method);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint i = 0; i < _variables.size(); i++)
|
||||||
|
_variables[i] = make_reg(0, READ_LE_UINT16(data + (i * 2)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reg_t getVariable(uint var) { return _variables[var]; }
|
||||||
|
|
||||||
|
uint16 getMethodCount() { return _methodCount; }
|
||||||
|
reg_t getPos() { return _pos; }
|
||||||
|
|
||||||
|
void saveLoadWithSerializer(Common::Serializer &ser);
|
||||||
|
|
||||||
|
// TODO: make private. Used by validate_property(), ObjVarRef::getPointer and Script::relocateObject
|
||||||
|
Common::Array<reg_t> _variables;
|
||||||
|
|
||||||
|
// TODO: make private
|
||||||
|
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 */
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint16 _methodCount;
|
||||||
|
int _flags;
|
||||||
|
uint16 _offset;
|
||||||
|
reg_t _pos; /**< Object offset within its script; for clones, this is their base */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CodeBlock {
|
struct CodeBlock {
|
||||||
|
|
|
@ -104,7 +104,7 @@ static int _obj_locate_varselector(SegManager *segMan, Object *obj, Selector slc
|
||||||
uint varnum;
|
uint varnum;
|
||||||
|
|
||||||
if (getSciVersion() < SCI_VERSION_1_1) {
|
if (getSciVersion() < SCI_VERSION_1_1) {
|
||||||
varnum = obj->variable_names_nr;
|
varnum = obj->getVarCount();
|
||||||
int selector_name_offset = varnum * 2 + SCRIPT_SELECTOR_OFFSET;
|
int selector_name_offset = varnum * 2 + SCRIPT_SELECTOR_OFFSET;
|
||||||
buf = obj->base_obj + selector_name_offset;
|
buf = obj->base_obj + selector_name_offset;
|
||||||
} else {
|
} else {
|
||||||
|
@ -112,7 +112,7 @@ static int _obj_locate_varselector(SegManager *segMan, Object *obj, Selector slc
|
||||||
obj = segMan->getObject(obj->getSuperClassSelector());
|
obj = segMan->getObject(obj->getSuperClassSelector());
|
||||||
|
|
||||||
buf = (byte *)obj->base_vars;
|
buf = (byte *)obj->base_vars;
|
||||||
varnum = obj->_variables[1].toUint16();
|
varnum = obj->getVariable(1).toUint16();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint i = 0; i < varnum; i++)
|
for (uint i = 0; i < varnum; i++)
|
||||||
|
@ -122,46 +122,8 @@ static int _obj_locate_varselector(SegManager *segMan, Object *obj, Selector slc
|
||||||
return -1; // Failed
|
return -1; // Failed
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _class_locate_funcselector(Object *obj, Selector slc) {
|
|
||||||
// Determines if obj is a class and explicitly defines slc as a funcselector
|
|
||||||
// Does NOT say anything about obj's superclasses, i.e. failure may be
|
|
||||||
// returned even if one of the superclasses defines the funcselector.
|
|
||||||
int funcnum = obj->methods_nr;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < funcnum; i++)
|
|
||||||
if (obj->getFuncSelector(i) == slc) // Found it?
|
|
||||||
return i; // report success
|
|
||||||
|
|
||||||
return -1; // Failed
|
|
||||||
}
|
|
||||||
|
|
||||||
static SelectorType _lookup_selector_function(SegManager *segMan, int seg_id, Object *obj, Selector selector_id, reg_t *fptr) {
|
|
||||||
int index;
|
|
||||||
|
|
||||||
// "recursive" lookup
|
|
||||||
|
|
||||||
while (obj) {
|
|
||||||
index = _class_locate_funcselector(obj, selector_id);
|
|
||||||
|
|
||||||
if (index >= 0) {
|
|
||||||
if (fptr) {
|
|
||||||
*fptr = obj->getFunction(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
return kSelectorMethod;
|
|
||||||
} else {
|
|
||||||
seg_id = obj->getSuperClassSelector().segment;
|
|
||||||
obj = segMan->getObject(obj->getSuperClassSelector());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return kSelectorNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
SelectorType lookup_selector(SegManager *segMan, reg_t obj_location, Selector selector_id, ObjVarRef *varp, reg_t *fptr) {
|
SelectorType lookup_selector(SegManager *segMan, reg_t obj_location, Selector selector_id, ObjVarRef *varp, reg_t *fptr) {
|
||||||
Object *obj = segMan->getObject(obj_location);
|
Object *obj = segMan->getObject(obj_location);
|
||||||
Object *species;
|
|
||||||
int index;
|
int index;
|
||||||
bool oldScriptHeader = (getSciVersion() == SCI_VERSION_0_EARLY);
|
bool oldScriptHeader = (getSciVersion() == SCI_VERSION_0_EARLY);
|
||||||
|
|
||||||
|
@ -175,18 +137,6 @@ SelectorType lookup_selector(SegManager *segMan, reg_t obj_location, Selector se
|
||||||
PRINT_REG(obj_location));
|
PRINT_REG(obj_location));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj->isClass())
|
|
||||||
species = obj;
|
|
||||||
else
|
|
||||||
species = segMan->getObject(obj->getSpeciesSelector());
|
|
||||||
|
|
||||||
|
|
||||||
if (!obj) {
|
|
||||||
error("lookup_selector(): Error while looking up Species class.\nOriginal address was %04x:%04x. Species address was %04x:%04x",
|
|
||||||
PRINT_REG(obj_location), PRINT_REG(obj->getSpeciesSelector()));
|
|
||||||
return kSelectorNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
index = _obj_locate_varselector(segMan, obj, selector_id);
|
index = _obj_locate_varselector(segMan, obj, selector_id);
|
||||||
|
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
|
@ -196,9 +146,25 @@ SelectorType lookup_selector(SegManager *segMan, reg_t obj_location, Selector se
|
||||||
varp->varindex = index;
|
varp->varindex = index;
|
||||||
}
|
}
|
||||||
return kSelectorVariable;
|
return kSelectorVariable;
|
||||||
|
} else {
|
||||||
|
// Check if it's a method, with recursive lookup in superclasses
|
||||||
|
while (obj) {
|
||||||
|
index = obj->funcSelectorPosition(selector_id);
|
||||||
|
if (index >= 0) {
|
||||||
|
if (fptr)
|
||||||
|
*fptr = obj->getFunction(index);
|
||||||
|
|
||||||
|
return kSelectorMethod;
|
||||||
|
} else {
|
||||||
|
obj = segMan->getObject(obj->getSuperClassSelector());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return kSelectorNone;
|
||||||
}
|
}
|
||||||
|
|
||||||
return _lookup_selector_function(segMan, obj_location.segment, obj, selector_id, fptr);
|
|
||||||
|
// return _lookup_selector_function(segMan, obj, selector_id, fptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // End of namespace Sci
|
} // End of namespace Sci
|
||||||
|
|
|
@ -403,7 +403,7 @@ SciVersion EngineState::detectLofsType() {
|
||||||
|
|
||||||
// Check methods of the Game class for lofs operations
|
// Check methods of the Game class for lofs operations
|
||||||
if (obj) {
|
if (obj) {
|
||||||
for (int m = 0; m < obj->methods_nr; m++) {
|
for (uint m = 0; m < obj->getMethodCount(); m++) {
|
||||||
reg_t fptr = obj->getFunction(m);
|
reg_t fptr = obj->getFunction(m);
|
||||||
|
|
||||||
Script *script = _segMan->getScript(fptr.segment);
|
Script *script = _segMan->getScript(fptr.segment);
|
||||||
|
|
|
@ -67,9 +67,9 @@ static reg_t &validate_property(Object *obj, int index) {
|
||||||
return dummyReg;
|
return dummyReg;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (index < 0 || (uint)index >= obj->_variables.size()) {
|
if (index < 0 || (uint)index >= obj->getVarCount()) {
|
||||||
debugC(2, kDebugLevelVM, "[VM] Invalid property #%d (out of [0..%d]) requested!\n",
|
debugC(2, kDebugLevelVM, "[VM] Invalid property #%d (out of [0..%d]) requested!\n",
|
||||||
index, obj->_variables.size());
|
index, obj->getVarCount());
|
||||||
return dummyReg;
|
return dummyReg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1598,7 +1598,7 @@ int script_instantiate_sci0(ResourceManager *resMan, SegManager *segMan, int scr
|
||||||
obj->setSpeciesSelector(INST_LOOKUP_CLASS(obj->getSpeciesSelector().offset));
|
obj->setSpeciesSelector(INST_LOOKUP_CLASS(obj->getSpeciesSelector().offset));
|
||||||
|
|
||||||
base_obj = segMan->getObject(obj->getSpeciesSelector());
|
base_obj = segMan->getObject(obj->getSpeciesSelector());
|
||||||
obj->variable_names_nr = base_obj->_variables.size();
|
obj->setVarCount(base_obj->getVarCount());
|
||||||
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
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ namespace Sci {
|
||||||
|
|
||||||
class SegManager;
|
class SegManager;
|
||||||
struct EngineState;
|
struct EngineState;
|
||||||
struct Object;
|
class Object;
|
||||||
class ResourceManager;
|
class ResourceManager;
|
||||||
|
|
||||||
/** Number of bytes to be allocated for the stack */
|
/** Number of bytes to be allocated for the stack */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue