mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-14 13:50:13 +00:00
Changed the way object selectors are accessed, by removing the relevant defines and adding appropriate methods to the Object structure
svn-id: r44138
This commit is contained in:
parent
0a037ccc45
commit
f890a69428
@ -3065,13 +3065,14 @@ int Console::printObject(reg_t pos) {
|
||||
DebugPrintf("[%04x:%04x] %s : %3d vars, %3d methods\n", PRINT_REG(pos), s->segMan->getObjectName(pos),
|
||||
obj->_variables.size(), obj->methods_nr);
|
||||
|
||||
if (!(obj->_variables[SCRIPT_INFO_SELECTOR].offset & SCRIPT_INFO_CLASS))
|
||||
var_container = s->segMan->getObject(obj->_variables[SCRIPT_SUPERCLASS_SELECTOR]);
|
||||
if (!(obj->getInfoSelector(version).offset & SCRIPT_INFO_CLASS))
|
||||
var_container = s->segMan->getObject(obj->getSuperClassSelector(version));
|
||||
DebugPrintf(" -- member variables:\n");
|
||||
for (i = 0; (uint)i < obj->_variables.size(); i++) {
|
||||
printf(" ");
|
||||
if (i < var_container->variable_names_nr) {
|
||||
DebugPrintf("[%03x] %s = ", VM_OBJECT_GET_VARSELECTOR(var_container, i), selector_name(s, VM_OBJECT_GET_VARSELECTOR(var_container, i)));
|
||||
uint16 varSelector = var_container->getVarSelector(i, version);
|
||||
DebugPrintf("[%03x] %s = ", varSelector, selector_name(s, varSelector));
|
||||
} else
|
||||
DebugPrintf("p#%x = ", i);
|
||||
|
||||
@ -3086,8 +3087,8 @@ int Console::printObject(reg_t pos) {
|
||||
}
|
||||
DebugPrintf(" -- methods:\n");
|
||||
for (i = 0; i < obj->methods_nr; i++) {
|
||||
reg_t fptr = VM_OBJECT_READ_FUNCTION(obj, i);
|
||||
DebugPrintf(" [%03x] %s = %04x:%04x\n", VM_OBJECT_GET_FUNCSELECTOR(obj, i), selector_name(s, VM_OBJECT_GET_FUNCSELECTOR(obj, i)), PRINT_REG(fptr));
|
||||
reg_t fptr = obj->getFunction(i, version);
|
||||
DebugPrintf(" [%03x] %s = %04x:%04x\n", obj->getFuncSelector(i, version), selector_name(s, obj->getFuncSelector(i, version)), PRINT_REG(fptr));
|
||||
}
|
||||
if (s->segMan->_heap[pos.segment]->getType() == SEG_TYPE_SCRIPT)
|
||||
DebugPrintf("\nOwner script:\t%d\n", s->segMan->getScript(pos.segment)->_nr);
|
||||
|
@ -204,10 +204,10 @@ reg_t kClone(EngineState *s, int, int argc, reg_t *argv) {
|
||||
SciVersion version = s->resMan->sciVersion(); // for the selector defines
|
||||
|
||||
// Mark as clone
|
||||
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->setInfoSelector(make_reg(0, SCRIPT_INFO_CLONE), version);
|
||||
clone_obj->setSpeciesSelector(clone_obj->pos, version);
|
||||
if (parent_obj->isClass(version))
|
||||
clone_obj->setSuperClassSelector(parent_obj->pos, version);
|
||||
s->segMan->getScript(parent_obj->pos.segment)->incrementLockers();
|
||||
s->segMan->getScript(clone_obj->pos.segment)->incrementLockers();
|
||||
|
||||
@ -230,7 +230,7 @@ reg_t kDisposeClone(EngineState *s, int, int argc, reg_t *argv) {
|
||||
|
||||
SciVersion version = s->resMan->sciVersion(); // for the selector defines
|
||||
|
||||
if (victim_obj->_variables[SCRIPT_INFO_SELECTOR].offset != SCRIPT_INFO_CLONE) {
|
||||
if (victim_obj->getInfoSelector(version).offset != SCRIPT_INFO_CLONE) {
|
||||
//warning("Attempt to dispose something other than a clone at %04x", offset);
|
||||
// SCI silently ignores this behaviour; some games actually depend on it
|
||||
return s->r_acc;
|
||||
|
@ -198,6 +198,7 @@ public:
|
||||
/** Clone has been marked as 'freed' */
|
||||
#define OBJECT_FLAG_FREED (0x1 << 0)
|
||||
|
||||
// TODO: convert to class, perhaps?
|
||||
struct Object {
|
||||
int flags;
|
||||
reg_t pos; /**< Object offset within its script; for clones, this is their base */
|
||||
@ -208,6 +209,67 @@ struct Object {
|
||||
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, SciVersion version) {
|
||||
if (version < SCI_VERSION_1_1)
|
||||
return READ_LE_UINT16(base_obj + _variables.size() * 2 + i * 2);
|
||||
else
|
||||
return *(base_vars + i);
|
||||
}
|
||||
|
||||
reg_t getSpeciesSelector(SciVersion version) {
|
||||
return _variables[version < SCI_VERSION_1_1 ? 0 : 5];
|
||||
}
|
||||
|
||||
void setSpeciesSelector(reg_t value, SciVersion version) {
|
||||
_variables[version < SCI_VERSION_1_1 ? 0 : 5] = value;
|
||||
}
|
||||
|
||||
reg_t getSuperClassSelector(SciVersion version) {
|
||||
return _variables[version < SCI_VERSION_1_1 ? 1 : 6];
|
||||
}
|
||||
|
||||
void setSuperClassSelector(reg_t value, SciVersion version) {
|
||||
_variables[version < SCI_VERSION_1_1 ? 1 : 6] = value;
|
||||
}
|
||||
|
||||
reg_t getInfoSelector(SciVersion version) {
|
||||
return _variables[version < SCI_VERSION_1_1 ? 2 : 7];
|
||||
}
|
||||
|
||||
void setInfoSelector(reg_t value, SciVersion version) {
|
||||
_variables[version < SCI_VERSION_1_1 ? 2 : 7] = value;
|
||||
}
|
||||
|
||||
reg_t getNameSelector(SciVersion version) {
|
||||
return _variables[version < SCI_VERSION_1_1 ? 3 : 8];
|
||||
}
|
||||
|
||||
void setNameSelector(reg_t value, SciVersion version) {
|
||||
_variables[version < 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, SciVersion version) {
|
||||
uint16 offset = (version < SCI_VERSION_1_1) ? i : i * 2 + 1;
|
||||
return READ_LE_UINT16((byte *) (base_method + offset));
|
||||
}
|
||||
|
||||
reg_t getFunction(uint16 i, SciVersion version) {
|
||||
uint16 offset = (version < SCI_VERSION_1_1) ? methods_nr + 1 + i : i * 2 + 2;
|
||||
return make_reg(pos.segment, READ_LE_UINT16((byte *) (base_method + offset)));
|
||||
}
|
||||
|
||||
bool isClass(SciVersion version) {
|
||||
return (getInfoSelector(version).offset & SCRIPT_INFO_CLASS);
|
||||
}
|
||||
};
|
||||
|
||||
struct CodeBlock {
|
||||
@ -215,28 +277,6 @@ struct CodeBlock {
|
||||
int size;
|
||||
};
|
||||
|
||||
#define VM_OBJECT_GET_VARSELECTOR(obj, i) \
|
||||
(version < SCI_VERSION_1_1 ? \
|
||||
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_GET_FUNCSELECTOR(obj, i) \
|
||||
(version < SCI_VERSION_1_1 ? \
|
||||
READ_LE_UINT16((byte *) (obj->base_method + i)) : \
|
||||
READ_LE_UINT16((byte *) (obj->base_method + i*2 + 1)))
|
||||
#define VM_OBJECT_READ_FUNCTION(obj, i) \
|
||||
(version < SCI_VERSION_1_1 ? \
|
||||
make_reg(obj->pos.segment, \
|
||||
READ_LE_UINT16((byte *) (obj->base_method \
|
||||
+ obj->methods_nr + 1 \
|
||||
+ i))) : \
|
||||
make_reg(obj->pos.segment, \
|
||||
READ_LE_UINT16((byte *) (obj->base_method \
|
||||
+ i * 2 + 2))))
|
||||
|
||||
|
||||
|
||||
|
||||
class Script : public SegmentObj {
|
||||
public:
|
||||
int _nr; /**< Script number */
|
||||
|
@ -613,11 +613,11 @@ static void reconstruct_scripts(EngineState *s, SegManager *self) {
|
||||
int funct_area = READ_LE_UINT16( data + SCRIPT_FUNCTAREAPTR_OFFSET );
|
||||
Object *base_obj;
|
||||
|
||||
base_obj = s->segMan->getObject(scr->_objects[j]._variables[SCRIPT_SPECIES_SELECTOR]);
|
||||
base_obj = s->segMan->getObject(scr->_objects[j].getSpeciesSelector(version));
|
||||
|
||||
if (!base_obj) {
|
||||
warning("Object without a base class: Script %d, index %d (reg address %04x:%04x",
|
||||
scr->_nr, j, PRINT_REG(scr->_objects[j]._variables[SCRIPT_SPECIES_SELECTOR]));
|
||||
scr->_nr, j, PRINT_REG(scr->_objects[j].getSpeciesSelector(version)));
|
||||
continue;
|
||||
}
|
||||
scr->_objects[j].variable_names_nr = base_obj->_variables.size();
|
||||
|
@ -81,8 +81,8 @@ int propertyOffsetToId(SegManager *segMan, int prop_ofs, reg_t objp) {
|
||||
if (segMan->sciVersion() < SCI_VERSION_1_1)
|
||||
selectoroffset = ((byte *)(obj->base_obj)) + SCRIPT_SELECTOR_OFFSET + selectors * 2;
|
||||
else {
|
||||
if (!(obj->_variables[SCRIPT_INFO_SELECTOR].offset & SCRIPT_INFO_CLASS)) {
|
||||
obj = segMan->getObject(obj->_variables[SCRIPT_SUPERCLASS_SELECTOR]);
|
||||
if (!(obj->getInfoSelector(version).offset & SCRIPT_INFO_CLASS)) {
|
||||
obj = segMan->getObject(obj->getSuperClassSelector(version));
|
||||
selectoroffset = (byte *)obj->base_vars;
|
||||
} else
|
||||
selectoroffset = (byte *)obj->base_vars;
|
||||
|
@ -266,11 +266,11 @@ const char *SegManager::getObjectName(reg_t pos) {
|
||||
if (!obj)
|
||||
return "<no such object>";
|
||||
|
||||
reg_t nameReg = obj->_variables[SCRIPT_NAME_SELECTOR];
|
||||
reg_t nameReg = obj->getNameSelector(version);
|
||||
if (nameReg.isNull())
|
||||
return "<no name>";
|
||||
|
||||
const char *name = derefString(obj->_variables[SCRIPT_NAME_SELECTOR]);
|
||||
const char *name = derefString(nameReg);
|
||||
if (!name)
|
||||
return "<invalid name>";
|
||||
|
||||
@ -678,8 +678,8 @@ void SegManager::scriptInitialiseObjectsSci11(SegmentId seg) {
|
||||
#endif
|
||||
|
||||
// Copy base from species class, as we need its selector IDs
|
||||
obj->_variables[SCRIPT_SUPERCLASS_SELECTOR] =
|
||||
getClassAddress(obj->_variables[SCRIPT_SUPERCLASS_SELECTOR].offset, SCRIPT_GET_LOCK, NULL_REG);
|
||||
obj->setSuperClassSelector(
|
||||
getClassAddress(obj->getSuperClassSelector(version).offset, SCRIPT_GET_LOCK, NULL_REG), version);
|
||||
|
||||
// Set the -classScript- selector to the script number.
|
||||
// FIXME: As this selector is filled in at run-time, it is likely
|
||||
@ -687,7 +687,7 @@ void SegManager::scriptInitialiseObjectsSci11(SegmentId seg) {
|
||||
// uses this selector together with -propDict- to compare classes.
|
||||
// For the purpose of Obj::isKindOf, using the script number appears
|
||||
// to be sufficient.
|
||||
obj->_variables[SCRIPT_CLASSSCRIPT_SELECTOR] = make_reg(0, scr->_nr);
|
||||
obj->setClassScriptSelector(make_reg(0, scr->_nr));
|
||||
|
||||
seeker += READ_LE_UINT16(seeker + 2) * 2;
|
||||
}
|
||||
@ -809,7 +809,7 @@ void SegManager::reconstructClones() {
|
||||
continue;
|
||||
|
||||
CloneTable::Entry &seeker = ct->_table[j];
|
||||
base_obj = getObject(seeker._variables[SCRIPT_SPECIES_SELECTOR]);
|
||||
base_obj = getObject(seeker.getSpeciesSelector(version));
|
||||
if (!base_obj) {
|
||||
warning("Clone entry without a base class: %d", j);
|
||||
seeker.base = NULL;
|
||||
|
@ -335,7 +335,7 @@ SciVersion EngineState::detectSetCursorType() {
|
||||
|
||||
SciVersion EngineState::detectLofsType() {
|
||||
if (_lofsType == SCI_VERSION_AUTODETECT) {
|
||||
SciVersion version = segMan->sciVersion(); // FIXME: for VM_OBJECT_READ_FUNCTION
|
||||
SciVersion version = segMan->sciVersion();
|
||||
|
||||
// This detection only works (and is only needed) pre-SCI1.1
|
||||
if (version >= SCI_VERSION_1_1) {
|
||||
@ -355,7 +355,7 @@ SciVersion EngineState::detectLofsType() {
|
||||
// Check methods of the Game class for lofs operations
|
||||
if (obj) {
|
||||
for (int m = 0; m < obj->methods_nr; m++) {
|
||||
reg_t fptr = VM_OBJECT_READ_FUNCTION(obj, m);
|
||||
reg_t fptr = obj->getFunction(m, version);
|
||||
|
||||
Script *script = segMan->getScript(fptr.segment);
|
||||
|
||||
|
@ -1406,8 +1406,8 @@ static int _obj_locate_varselector(SegManager *segMan, Object *obj, Selector slc
|
||||
int selector_name_offset = varnum * 2 + SCRIPT_SELECTOR_OFFSET;
|
||||
buf = obj->base_obj + selector_name_offset;
|
||||
} else {
|
||||
if (!(obj->_variables[SCRIPT_INFO_SELECTOR].offset & SCRIPT_INFO_CLASS))
|
||||
obj = segMan->getObject(obj->_variables[SCRIPT_SUPERCLASS_SELECTOR]);
|
||||
if (!(obj->getInfoSelector(version).offset & SCRIPT_INFO_CLASS))
|
||||
obj = segMan->getObject(obj->getSuperClassSelector(version));
|
||||
|
||||
buf = (byte *)obj->base_vars;
|
||||
varnum = obj->_variables[1].toUint16();
|
||||
@ -1428,7 +1428,7 @@ static int _class_locate_funcselector(Object *obj, Selector slc, SciVersion vers
|
||||
int i;
|
||||
|
||||
for (i = 0; i < funcnum; i++)
|
||||
if (VM_OBJECT_GET_FUNCSELECTOR(obj, i) == slc) // Found it?
|
||||
if (obj->getFuncSelector(i, version) == slc) // Found it?
|
||||
return i; // report success
|
||||
|
||||
return -1; // Failed
|
||||
@ -1445,13 +1445,13 @@ static SelectorType _lookup_selector_function(SegManager *segMan, int seg_id, Ob
|
||||
|
||||
if (index >= 0) {
|
||||
if (fptr) {
|
||||
*fptr = VM_OBJECT_READ_FUNCTION(obj, index);
|
||||
*fptr = obj->getFunction(index, version);
|
||||
}
|
||||
|
||||
return kSelectorMethod;
|
||||
} else {
|
||||
seg_id = obj->_variables[SCRIPT_SUPERCLASS_SELECTOR].segment;
|
||||
obj = segMan->getObject(obj->_variables[SCRIPT_SUPERCLASS_SELECTOR]);
|
||||
seg_id = obj->getSuperClassSelector(version).segment;
|
||||
obj = segMan->getObject(obj->getSuperClassSelector(version));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1475,15 +1475,15 @@ SelectorType lookup_selector(SegManager *segMan, reg_t obj_location, Selector se
|
||||
PRINT_REG(obj_location));
|
||||
}
|
||||
|
||||
if (IS_CLASS(obj))
|
||||
if (obj->isClass(version))
|
||||
species = obj;
|
||||
else
|
||||
species = segMan->getObject(obj->_variables[SCRIPT_SPECIES_SELECTOR]);
|
||||
species = segMan->getObject(obj->getSpeciesSelector(version));
|
||||
|
||||
|
||||
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->_variables[SCRIPT_SPECIES_SELECTOR]));
|
||||
PRINT_REG(obj_location), PRINT_REG(obj->getSpeciesSelector(version)));
|
||||
return kSelectorNone;
|
||||
}
|
||||
|
||||
@ -1694,14 +1694,14 @@ int script_instantiate_sci0(ResourceManager *resMan, SegManager *segMan, int scr
|
||||
Object *base_obj;
|
||||
|
||||
// Instantiate the superclass, if neccessary
|
||||
obj->_variables[SCRIPT_SPECIES_SELECTOR] = INST_LOOKUP_CLASS(obj->_variables[SCRIPT_SPECIES_SELECTOR].offset);
|
||||
obj->setSpeciesSelector(INST_LOOKUP_CLASS(obj->getSpeciesSelector(version).offset), version);
|
||||
|
||||
base_obj = segMan->getObject(obj->_variables[SCRIPT_SPECIES_SELECTOR]);
|
||||
base_obj = segMan->getObject(obj->getSpeciesSelector(version));
|
||||
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->setSuperClassSelector(INST_LOOKUP_CLASS(obj->getSuperClassSelector(version).offset), version);
|
||||
} // if object or class
|
||||
break;
|
||||
case SCI_OBJ_POINTERS: // A relocation table
|
||||
|
@ -68,11 +68,9 @@ class ResourceManager;
|
||||
|
||||
/** Offset of the name pointer */
|
||||
#define SCRIPT_NAME_OFFSET (version < SCI_VERSION_1_1 ? 14 -8 : 16)
|
||||
#define SCRIPT_NAME_SELECTOR (version < SCI_VERSION_1_1 ? 3 : 8)
|
||||
|
||||
/** Object-relative offset of the -info- selector */
|
||||
#define SCRIPT_INFO_OFFSET (version < SCI_VERSION_1_1 ? 12 -8 : 14)
|
||||
#define SCRIPT_INFO_SELECTOR (version < SCI_VERSION_1_1 ? 2 : 7)
|
||||
|
||||
/** Flag fo the -info- selector */
|
||||
#define SCRIPT_INFO_CLONE 0x0001
|
||||
@ -91,17 +89,9 @@ class ResourceManager;
|
||||
|
||||
#define SCRIPT_SUPERCLASS_OFFSET (version < SCI_VERSION_1_1 ? 10 -8 : 12)
|
||||
|
||||
/*---------------------------------*/
|
||||
/* Script selector index variables */
|
||||
/*---------------------------------*/
|
||||
#define SCRIPT_SPECIES_SELECTOR (version < SCI_VERSION_1_1 ? 0 : 5)
|
||||
#define SCRIPT_SUPERCLASS_SELECTOR (version < SCI_VERSION_1_1 ? 1 : 6)
|
||||
#define SCRIPT_CLASSSCRIPT_SELECTOR 4
|
||||
|
||||
/** Magic adjustment value for lofsa and lofss */
|
||||
#define SCRIPT_LOFS_MAGIC 3
|
||||
|
||||
|
||||
/** Stack pointer value: Use predecessor's value */
|
||||
#define CALL_SP_CARRY NULL
|
||||
|
||||
@ -119,9 +109,6 @@ struct Class {
|
||||
|
||||
#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)
|
||||
|
||||
|
||||
/** Contains selector IDs for a few selected selectors */
|
||||
struct selector_map_t {
|
||||
Selector init; /**< Init function */
|
||||
|
Loading…
Reference in New Issue
Block a user