aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFilippos Karapetis2009-09-17 08:51:38 +0000
committerFilippos Karapetis2009-09-17 08:51:38 +0000
commitf890a69428b0d5ed0314db98cde06c7246041ac4 (patch)
treed34d28e6f6351eed01189b2f9c8a61112026a0fc
parent0a037ccc45cda6a2eb1f1604c2c5ec64977ed0ce (diff)
downloadscummvm-rg350-f890a69428b0d5ed0314db98cde06c7246041ac4.tar.gz
scummvm-rg350-f890a69428b0d5ed0314db98cde06c7246041ac4.tar.bz2
scummvm-rg350-f890a69428b0d5ed0314db98cde06c7246041ac4.zip
Changed the way object selectors are accessed, by removing the relevant defines and adding appropriate methods to the Object structure
svn-id: r44138
-rw-r--r--engines/sci/console.cpp11
-rw-r--r--engines/sci/engine/kscripts.cpp10
-rw-r--r--engines/sci/engine/memobj.h84
-rw-r--r--engines/sci/engine/savegame.cpp4
-rw-r--r--engines/sci/engine/scriptdebug.cpp4
-rw-r--r--engines/sci/engine/seg_manager.cpp12
-rw-r--r--engines/sci/engine/state.cpp4
-rw-r--r--engines/sci/engine/vm.cpp24
-rw-r--r--engines/sci/engine/vm.h13
9 files changed, 97 insertions, 69 deletions
diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp
index 9f75b14d99..3f4148fcc0 100644
--- a/engines/sci/console.cpp
+++ b/engines/sci/console.cpp
@@ -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);
diff --git a/engines/sci/engine/kscripts.cpp b/engines/sci/engine/kscripts.cpp
index 318d4b9c4d..157f285541 100644
--- a/engines/sci/engine/kscripts.cpp
+++ b/engines/sci/engine/kscripts.cpp
@@ -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;
diff --git a/engines/sci/engine/memobj.h b/engines/sci/engine/memobj.h
index e792ac80ae..38a165a33a 100644
--- a/engines/sci/engine/memobj.h
+++ b/engines/sci/engine/memobj.h
@@ -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 */
diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp
index 11599797e2..0782530a7c 100644
--- a/engines/sci/engine/savegame.cpp
+++ b/engines/sci/engine/savegame.cpp
@@ -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();
diff --git a/engines/sci/engine/scriptdebug.cpp b/engines/sci/engine/scriptdebug.cpp
index 38879a48ae..670aee3981 100644
--- a/engines/sci/engine/scriptdebug.cpp
+++ b/engines/sci/engine/scriptdebug.cpp
@@ -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;
diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp
index c503d7bcd0..cb178098b2 100644
--- a/engines/sci/engine/seg_manager.cpp
+++ b/engines/sci/engine/seg_manager.cpp
@@ -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;
diff --git a/engines/sci/engine/state.cpp b/engines/sci/engine/state.cpp
index 4c60b26fa4..bf385d6551 100644
--- a/engines/sci/engine/state.cpp
+++ b/engines/sci/engine/state.cpp
@@ -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);
diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp
index c0381519cc..617016f3e6 100644
--- a/engines/sci/engine/vm.cpp
+++ b/engines/sci/engine/vm.cpp
@@ -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
diff --git a/engines/sci/engine/vm.h b/engines/sci/engine/vm.h
index 57fad31c8f..f2d51fafb1 100644
--- a/engines/sci/engine/vm.h
+++ b/engines/sci/engine/vm.h
@@ -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 */