diff options
author | Filippos Karapetis | 2009-10-10 15:58:51 +0000 |
---|---|---|
committer | Filippos Karapetis | 2009-10-10 15:58:51 +0000 |
commit | d6f5d93dbf554bf7e133b0de7e675b6453736356 (patch) | |
tree | 13c1f08b23745536e400344e00a55a0d4bcb2bb4 | |
parent | 8fd29ecf9f5b7f66824b7df45e3f04dfc2b5cfeb (diff) | |
download | scummvm-rg350-d6f5d93dbf554bf7e133b0de7e675b6453736356.tar.gz scummvm-rg350-d6f5d93dbf554bf7e133b0de7e675b6453736356.tar.bz2 scummvm-rg350-d6f5d93dbf554bf7e133b0de7e675b6453736356.zip |
Started rewriting the Object struct into a class
svn-id: r44878
-rw-r--r-- | engines/sci/console.cpp | 28 | ||||
-rw-r--r-- | engines/sci/engine/gc.cpp | 2 | ||||
-rw-r--r-- | engines/sci/engine/kscripts.cpp | 13 | ||||
-rw-r--r-- | engines/sci/engine/savegame.cpp | 32 | ||||
-rw-r--r-- | engines/sci/engine/scriptdebug.cpp | 2 | ||||
-rw-r--r-- | engines/sci/engine/seg_manager.cpp | 54 | ||||
-rw-r--r-- | engines/sci/engine/segment.cpp | 10 | ||||
-rw-r--r-- | engines/sci/engine/segment.h | 132 | ||||
-rw-r--r-- | engines/sci/engine/selector.cpp | 72 | ||||
-rw-r--r-- | engines/sci/engine/state.cpp | 2 | ||||
-rw-r--r-- | engines/sci/engine/vm.cpp | 6 | ||||
-rw-r--r-- | engines/sci/engine/vm.h | 2 |
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 */ |