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 /engines/sci/engine/segment.h | |
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
Diffstat (limited to 'engines/sci/engine/segment.h')
-rw-r--r-- | engines/sci/engine/segment.h | 132 |
1 files changed, 82 insertions, 50 deletions
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 { |