aboutsummaryrefslogtreecommitdiff
path: root/engines/sci
diff options
context:
space:
mode:
authorFilippos Karapetis2009-10-10 15:58:51 +0000
committerFilippos Karapetis2009-10-10 15:58:51 +0000
commitd6f5d93dbf554bf7e133b0de7e675b6453736356 (patch)
tree13c1f08b23745536e400344e00a55a0d4bcb2bb4 /engines/sci
parent8fd29ecf9f5b7f66824b7df45e3f04dfc2b5cfeb (diff)
downloadscummvm-rg350-d6f5d93dbf554bf7e133b0de7e675b6453736356.tar.gz
scummvm-rg350-d6f5d93dbf554bf7e133b0de7e675b6453736356.tar.bz2
scummvm-rg350-d6f5d93dbf554bf7e133b0de7e675b6453736356.zip
Started rewriting the Object struct into a class
svn-id: r44878
Diffstat (limited to 'engines/sci')
-rw-r--r--engines/sci/console.cpp28
-rw-r--r--engines/sci/engine/gc.cpp2
-rw-r--r--engines/sci/engine/kscripts.cpp13
-rw-r--r--engines/sci/engine/savegame.cpp32
-rw-r--r--engines/sci/engine/scriptdebug.cpp2
-rw-r--r--engines/sci/engine/seg_manager.cpp54
-rw-r--r--engines/sci/engine/segment.cpp10
-rw-r--r--engines/sci/engine/segment.h132
-rw-r--r--engines/sci/engine/selector.cpp72
-rw-r--r--engines/sci/engine/state.cpp2
-rw-r--r--engines/sci/engine/vm.cpp6
-rw-r--r--engines/sci/engine/vm.h2
12 files changed, 158 insertions, 197 deletions
diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp
index 03700abe65..04d9eaf475 100644
--- a/engines/sci/console.cpp
+++ b/engines/sci/console.cpp
@@ -1353,11 +1353,11 @@ bool Console::segmentInfo(int nr) {
for (it = scr->_objects.begin(); it != end; ++it) {
DebugPrintf(" ");
// Object header
- Object *obj = _vm->_gamestate->_segMan->getObject(it->_value._pos);
+ Object *obj = _vm->_gamestate->_segMan->getObject(it->_value.getPos());
if (obj)
- DebugPrintf("[%04x:%04x] %s : %3d vars, %3d methods\n", PRINT_REG(it->_value._pos),
- _vm->_gamestate->_segMan->getObjectName(it->_value._pos),
- obj->_variables.size(), obj->methods_nr);
+ DebugPrintf("[%04x:%04x] %s : %3d vars, %3d methods\n", PRINT_REG(it->_value.getPos()),
+ _vm->_gamestate->_segMan->getObjectName(it->_value.getPos()),
+ obj->getVarCount(), obj->getMethodCount());
}
}
break;
@@ -1400,11 +1400,11 @@ bool Console::segmentInfo(int nr) {
objpos.segment = nr;
DebugPrintf(" [%04x] %s; copy of ", i, _vm->_gamestate->_segMan->getObjectName(objpos));
// Object header
- Object *obj = _vm->_gamestate->_segMan->getObject(ct->_table[i]._pos);
+ Object *obj = _vm->_gamestate->_segMan->getObject(ct->_table[i].getPos());
if (obj)
- DebugPrintf("[%04x:%04x] %s : %3d vars, %3d methods\n", PRINT_REG(ct->_table[i]._pos),
- _vm->_gamestate->_segMan->getObjectName(ct->_table[i]._pos),
- obj->_variables.size(), obj->methods_nr);
+ DebugPrintf("[%04x:%04x] %s : %3d vars, %3d methods\n", PRINT_REG(ct->_table[i].getPos()),
+ _vm->_gamestate->_segMan->getObjectName(ct->_table[i].getPos()),
+ obj->getVarCount(), obj->getMethodCount());
}
}
break;
@@ -2935,7 +2935,7 @@ int Console::printObject(reg_t pos) {
EngineState *s = _vm->_gamestate; // for the several defines in this function
Object *obj = s->_segMan->getObject(pos);
Object *var_container = obj;
- int i;
+ uint i;
if (!obj) {
DebugPrintf("[%04x:%04x]: Not an object.", PRINT_REG(pos));
@@ -2944,20 +2944,20 @@ int Console::printObject(reg_t pos) {
// Object header
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))
var_container = s->_segMan->getObject(obj->getSuperClassSelector());
DebugPrintf(" -- member variables:\n");
- for (i = 0; (uint)i < obj->_variables.size(); i++) {
+ for (i = 0; (uint)i < obj->getVarCount(); i++) {
printf(" ");
- if (i < var_container->variable_names_nr) {
+ if (i < var_container->getVarCount()) {
uint16 varSelector = var_container->getVarSelector(i);
DebugPrintf("[%03x] %s = ", varSelector, selector_name(s, varSelector));
} else
DebugPrintf("p#%x = ", i);
- reg_t val = obj->_variables[i];
+ reg_t val = obj->getVariable(i);
DebugPrintf("%04x:%04x", PRINT_REG(val));
Object *ref = s->_segMan->getObject(val);
@@ -2967,7 +2967,7 @@ int Console::printObject(reg_t pos) {
DebugPrintf("\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);
DebugPrintf(" [%03x] %s = %04x:%04x\n", obj->getFuncSelector(i), selector_name(s, obj->getFuncSelector(i)), PRINT_REG(fptr));
}
diff --git a/engines/sci/engine/gc.cpp b/engines/sci/engine/gc.cpp
index 160842ebe4..a4d9d4f053 100644
--- a/engines/sci/engine/gc.cpp
+++ b/engines/sci/engine/gc.cpp
@@ -122,7 +122,7 @@ reg_t_hash_map *find_all_used_references(EngineState *s) {
ObjMap::iterator it;
const ObjMap::iterator end = script->_objects.end();
for (it = script->_objects.begin(); it != end; ++it) {
- wm.push(it->_value._pos);
+ wm.push(it->_value.getPos());
}
}
}
diff --git a/engines/sci/engine/kscripts.cpp b/engines/sci/engine/kscripts.cpp
index e409e1a010..6d0433d62a 100644
--- a/engines/sci/engine/kscripts.cpp
+++ b/engines/sci/engine/kscripts.cpp
@@ -123,15 +123,14 @@ reg_t kClone(EngineState *s, int argc, reg_t *argv) {
}
*clone_obj = *parent_obj;
- clone_obj->_flags = 0;
// Mark as 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())
- clone_obj->setSuperClassSelector(parent_obj->_pos);
- s->_segMan->getScript(parent_obj->_pos.segment)->incrementLockers();
- s->_segMan->getScript(clone_obj->_pos.segment)->incrementLockers();
+ clone_obj->setSuperClassSelector(parent_obj->getPos());
+ s->_segMan->getScript(parent_obj->getPos().segment)->incrementLockers();
+ s->_segMan->getScript(clone_obj->getPos().segment)->incrementLockers();
return clone_addr;
}
@@ -167,8 +166,8 @@ reg_t kDisposeClone(EngineState *s, int argc, reg_t *argv) {
}
#endif
- victim_obj->_flags |= OBJECT_FLAG_FREED;
-
+ victim_obj->markAsFreed();
+
_k_view_list_mark_free(s, victim_addr); // Free on view list, if neccessary
return s->r_acc;
diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp
index 0586bec484..4e161fabaf 100644
--- a/engines/sci/engine/savegame.cpp
+++ b/engines/sci/engine/savegame.cpp
@@ -312,14 +312,21 @@ void LocalVariables::saveLoadWithSerializer(Common::Serializer &s) {
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 <>
@@ -411,7 +418,7 @@ void Script::saveLoadWithSerializer(Common::Serializer &s) {
Object tmp;
for (uint i = 0; i < numObjs; ++i) {
syncWithSerializer<Object>(s, tmp);
- _objects[tmp._pos.offset] = tmp;
+ _objects[tmp.getPos().offset] = tmp;
}
} else {
ObjMap::iterator it;
@@ -605,8 +612,7 @@ void SegManager::reconstructScripts(EngineState *s) {
ObjMap::iterator it;
const ObjMap::iterator end = scr->_objects.end();
for (it = scr->_objects.begin(); it != end; ++it) {
- byte *data = scr->_buf + it->_value._pos.offset;
- it->_value.base = scr->_buf;
+ byte *data = scr->_buf + it->_value.getPos().offset;
it->_value.base_obj = data;
}
}
@@ -622,7 +628,7 @@ void SegManager::reconstructScripts(EngineState *s) {
ObjMap::iterator it;
const ObjMap::iterator end = scr->_objects.end();
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) {
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()));
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_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);
}
}
}
diff --git a/engines/sci/engine/scriptdebug.cpp b/engines/sci/engine/scriptdebug.cpp
index e6b5c56899..5da75638e3 100644
--- a/engines/sci/engine/scriptdebug.cpp
+++ b/engines/sci/engine/scriptdebug.cpp
@@ -75,7 +75,7 @@ int propertyOffsetToId(SegManager *segMan, int prop_ofs, reg_t objp) {
return -1;
}
- selectors = obj->_variables.size();
+ selectors = obj->getVarCount();
if (getSciVersion() < SCI_VERSION_1_1)
selectoroffset = ((byte *)(obj->base_obj)) + SCRIPT_SELECTOR_OFFSET + selectors * 2;
diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp
index e7132eda00..50a0d094af 100644
--- a/engines/sci/engine/seg_manager.cpp
+++ b/engines/sci/engine/seg_manager.cpp
@@ -184,9 +184,7 @@ int SegManager::deallocate(SegmentId seg, bool recursive) {
bool SegManager::isHeapObject(reg_t pos) {
Object *obj = getObject(pos);
- if (obj == NULL)
- return false;
- if (obj->_flags & OBJECT_FLAG_FREED)
+ if (obj == NULL || (obj && obj->isFreed()))
return false;
Script *scr = getScriptIfLoaded(pos.segment);
return !(scr && scr->_markedAsDeleted);
@@ -305,7 +303,7 @@ reg_t SegManager::findObjectByName(const Common::String &name, int index) {
if (mobj->getType() == SEG_TYPE_SCRIPT) {
obj = &(it->_value);
- objpos.offset = obj->_pos.offset;
+ objpos.offset = obj->getPos().offset;
++it;
} else if (mobj->getType() == SEG_TYPE_CLONES) {
if (!ct->isValidEntry(idx))
@@ -396,7 +394,7 @@ int Script::relocateLocal(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) {
@@ -442,7 +440,7 @@ void Script::scriptRelocate(reg_t block) {
else
printf("- No locals\n");
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.
printf("Trying to continue anyway...\n");
}
@@ -481,7 +479,7 @@ void Script::heapRelocate(reg_t block) {
else
printf("- No locals\n");
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__);
}
}
@@ -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");
- byte *data = (byte *)(_buf + obj_pos.offset);
- 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)));
+ obj->init(_buf, obj_pos);
return obj;
}
@@ -829,12 +789,10 @@ void SegManager::reconstructClones() {
base_obj = getObject(seeker.getSpeciesSelector());
if (!base_obj) {
warning("Clone entry without a base class: %d", j);
- seeker.base = NULL;
seeker.base_obj = NULL;
seeker.base_vars = NULL;
seeker.base_method = NULL;
} else {
- seeker.base = base_obj->base;
seeker.base_obj = base_obj->base_obj;
seeker.base_vars = base_obj->base_vars;
seeker.base_method = base_obj->base_method;
diff --git a/engines/sci/engine/segment.cpp b/engines/sci/engine/segment.cpp
index 2decf26c5e..38af3e8b29 100644
--- a/engines/sci/engine/segment.cpp
+++ b/engines/sci/engine/segment.cpp
@@ -336,8 +336,8 @@ void Script::listAllOutgoingReferences(reg_t addr, void *param, NoteCallback not
if (_localsSegment)
(*note)(param, make_reg(_localsSegment, 0));
- for (uint i = 0; i < obj->_variables.size(); i++)
- (*note)(param, obj->_variables[i]);
+ for (uint i = 0; i < obj->getVarCount(); i++)
+ (*note)(param, obj->getVariable(i));
} else {
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]);
// Emit all member variables (including references to the 'super' delegate)
- for (uint i = 0; i < clone->_variables.size(); i++)
- (*note)(param, clone->_variables[i]);
+ for (uint i = 0; i < clone->getVarCount(); 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)(param, clone->_pos);
+ (*note)(param, clone->getPos());
//debugC(2, kDebugLevelGC, "[GC] Reporting clone-pos %04x:%04x\n", PRINT_REG(clone->pos));
}
diff --git a/engines/sci/engine/segment.h b/engines/sci/engine/segment.h
index b04747dbf6..38f1895fdd 100644
--- a/engines/sci/engine/segment.h
+++ b/engines/sci/engine/segment.h
@@ -191,80 +191,112 @@ public:
};
/** Clone has been marked as 'freed' */
-#define OBJECT_FLAG_FREED (0x1 << 0)
+#define OBJECT_FLAG_FREED (1 << 0)
-// TODO: convert to class, perhaps?
-struct Object {
- int _flags;
- reg_t _pos; /**< Object offset within its script; for clones, this is their base */
- int variable_names_nr; /**< Number of variable names, may be less than variables_nr */
- 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;
+class Object {
+public:
+ Object() {
+ _flags = 0;
+ _offset = getSciVersion() < SCI_VERSION_1_1 ? 0 : 5;
+ }
+
+ ~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; }
- uint16 getVarSelector(uint16 i) {
+ 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)
return READ_LE_UINT16(base_obj + _variables.size() * 2 + i * 2);
else
return *(base_vars + i);
}
- reg_t getSpeciesSelector() {
- return _variables[getSciVersion() < SCI_VERSION_1_1 ? 0 : 5];
+ Selector getFuncSelector(uint16 i) {
+ uint16 offset = (getSciVersion() < SCI_VERSION_1_1) ? i : i * 2 + 1;
+ return READ_LE_UINT16((byte *) (base_method + offset));
}
- void setSpeciesSelector(reg_t value) {
- _variables[getSciVersion() < SCI_VERSION_1_1 ? 0 : 5] = value;
- }
+ /**
+ * 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;
- reg_t getSuperClassSelector() {
- return _variables[getSciVersion() < SCI_VERSION_1_1 ? 1 : 6];
+ return -1;
}
- void setSuperClassSelector(reg_t value) {
- _variables[getSciVersion() < SCI_VERSION_1_1 ? 1 : 6] = value;
+ reg_t getFunction(uint16 i) {
+ 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)));
}
- reg_t getInfoSelector() {
- return _variables[getSciVersion() < SCI_VERSION_1_1 ? 2 : 7];
- }
+ bool isClass() { return (getInfoSelector().offset & SCRIPT_INFO_CLASS); }
- void setInfoSelector(reg_t value) {
- _variables[getSciVersion() < SCI_VERSION_1_1 ? 2 : 7] = value;
- }
+ void markAsFreed() { _flags |= OBJECT_FLAG_FREED; }
+ bool isFreed() { return _flags & OBJECT_FLAG_FREED; }
- reg_t getNameSelector() {
- return _variables[getSciVersion() < SCI_VERSION_1_1 ? 3 : 8];
- }
+ void setVarCount(uint size) { _variables.resize(size); }
+ uint getVarCount() { return _variables.size(); }
- void setNameSelector(reg_t value) {
- _variables[getSciVersion() < SCI_VERSION_1_1 ? 3 : 8] = value;
- }
+ void init(byte *buf, reg_t obj_pos) {
+ byte *data = (byte *)(buf + obj_pos.offset);
+ base_obj = data;
+ _pos = obj_pos;
- reg_t getClassScriptSelector() {
- return _variables[4];
- }
+ 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);
+ }
- void setClassScriptSelector(reg_t value) {
- _variables[4] = value;
+ for (uint i = 0; i < _variables.size(); i++)
+ _variables[i] = make_reg(0, READ_LE_UINT16(data + (i * 2)));
}
- uint16 getFuncSelector(uint16 i) {
- uint16 offset = (getSciVersion() < SCI_VERSION_1_1) ? i : i * 2 + 1;
- return READ_LE_UINT16((byte *) (base_method + offset));
- }
+ reg_t getVariable(uint var) { return _variables[var]; }
- reg_t getFunction(uint16 i) {
- uint16 offset = (getSciVersion() < SCI_VERSION_1_1) ? methods_nr + 1 + i : i * 2 + 2;
- return make_reg(_pos.segment, READ_LE_UINT16((byte *) (base_method + offset)));
- }
+ uint16 getMethodCount() { return _methodCount; }
+ reg_t getPos() { return _pos; }
- bool isClass() {
- return (getInfoSelector().offset & SCRIPT_INFO_CLASS);
- }
+ 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 {
diff --git a/engines/sci/engine/selector.cpp b/engines/sci/engine/selector.cpp
index 1d44691af5..aa9545d724 100644
--- a/engines/sci/engine/selector.cpp
+++ b/engines/sci/engine/selector.cpp
@@ -104,7 +104,7 @@ static int _obj_locate_varselector(SegManager *segMan, Object *obj, Selector slc
uint varnum;
if (getSciVersion() < SCI_VERSION_1_1) {
- varnum = obj->variable_names_nr;
+ varnum = obj->getVarCount();
int selector_name_offset = varnum * 2 + SCRIPT_SELECTOR_OFFSET;
buf = obj->base_obj + selector_name_offset;
} else {
@@ -112,7 +112,7 @@ static int _obj_locate_varselector(SegManager *segMan, Object *obj, Selector slc
obj = segMan->getObject(obj->getSuperClassSelector());
buf = (byte *)obj->base_vars;
- varnum = obj->_variables[1].toUint16();
+ varnum = obj->getVariable(1).toUint16();
}
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
}
-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) {
Object *obj = segMan->getObject(obj_location);
- Object *species;
int index;
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));
}
- 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);
if (index >= 0) {
@@ -196,9 +146,25 @@ SelectorType lookup_selector(SegManager *segMan, reg_t obj_location, Selector se
varp->varindex = index;
}
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
diff --git a/engines/sci/engine/state.cpp b/engines/sci/engine/state.cpp
index 328cdd4971..047d6ca6c2 100644
--- a/engines/sci/engine/state.cpp
+++ b/engines/sci/engine/state.cpp
@@ -403,7 +403,7 @@ SciVersion EngineState::detectLofsType() {
// Check methods of the Game class for lofs operations
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);
Script *script = _segMan->getScript(fptr.segment);
diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp
index 2f3e2a618c..80c38fb986 100644
--- a/engines/sci/engine/vm.cpp
+++ b/engines/sci/engine/vm.cpp
@@ -67,9 +67,9 @@ static reg_t &validate_property(Object *obj, int index) {
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",
- index, obj->_variables.size());
+ index, obj->getVarCount());
return dummyReg;
}
@@ -1598,7 +1598,7 @@ int script_instantiate_sci0(ResourceManager *resMan, SegManager *segMan, int scr
obj->setSpeciesSelector(INST_LOOKUP_CLASS(obj->getSpeciesSelector().offset));
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;
// Copy base from species class, as we need its selector IDs
diff --git a/engines/sci/engine/vm.h b/engines/sci/engine/vm.h
index e63a09ca16..dddd5d9672 100644
--- a/engines/sci/engine/vm.h
+++ b/engines/sci/engine/vm.h
@@ -37,7 +37,7 @@ namespace Sci {
class SegManager;
struct EngineState;
-struct Object;
+class Object;
class ResourceManager;
/** Number of bytes to be allocated for the stack */