aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/engine/segment.h
diff options
context:
space:
mode:
Diffstat (limited to 'engines/sci/engine/segment.h')
-rw-r--r--engines/sci/engine/segment.h238
1 files changed, 113 insertions, 125 deletions
diff --git a/engines/sci/engine/segment.h b/engines/sci/engine/segment.h
index f1b6dccaa2..1089ada475 100644
--- a/engines/sci/engine/segment.h
+++ b/engines/sci/engine/segment.h
@@ -112,7 +112,7 @@ public:
*
* @param sub_addr base address whose canonic address is to be found
*/
- virtual reg_t findCanonicAddress(SegManager *segMan, reg_t sub_addr) const { return sub_addr; }
+ virtual reg_t findCanonicAddress(SegManager *segMan, reg_t sub_addr) { return sub_addr; }
/**
* Deallocates all memory associated with the specified address.
@@ -125,7 +125,7 @@ public:
* @param note Invoked for each address on which free_at_address() makes sense
* @param param parameter passed to 'note'
*/
- virtual void listAllDeallocatable(SegmentId segId, void *param, NoteCallback note) const {}
+ virtual void listAllDeallocatable(SegmentId segId, void *param, NoteCallback note) {}
/**
* Iterates over all references reachable from the specified object.
@@ -134,7 +134,7 @@ public:
* @param note Invoked for each outgoing reference within the object
* Note: This function may also choose to report numbers (segment 0) as adresses
*/
- virtual void listAllOutgoingReferences(reg_t object, void *param, NoteCallback note) const {}
+ virtual void listAllOutgoingReferences(reg_t object, void *param, NoteCallback note) {}
};
@@ -194,8 +194,8 @@ public:
virtual bool isValidOffset(uint16 offset) const;
virtual SegmentRef dereference(reg_t pointer);
- virtual reg_t findCanonicAddress(SegManager *segMan, reg_t sub_addr) const;
- virtual void listAllOutgoingReferences(reg_t object, void *param, NoteCallback note) const;
+ virtual reg_t findCanonicAddress(SegManager *segMan, reg_t sub_addr);
+ virtual void listAllOutgoingReferences(reg_t object, void *param, NoteCallback note);
virtual void saveLoadWithSerializer(Common::Serializer &ser);
};
@@ -205,22 +205,6 @@ enum {
OBJECT_FLAG_FREED = (1 << 0)
};
-enum infoSelectorFlags {
- kInfoFlagClone = 0x0001,
- kInfoFlagClass = 0x8000
-};
-
-enum ObjectOffsets {
- kOffsetLocalVariables = -6,
- kOffsetFunctionArea = -4,
- kOffsetSelectorCounter = -2,
- kOffsetSelectorSegment = 0,
- kOffsetInfoSelectorSci0 = 4,
- kOffsetNamePointerSci0 = 6,
- kOffsetInfoSelectorSci11 = 14,
- kOffsetNamePointerSci11 = 16
-};
-
class Object {
public:
Object() {
@@ -230,34 +214,31 @@ public:
~Object() { }
- reg_t getSpeciesSelector() const { return _variables[_offset]; }
+ reg_t getSpeciesSelector() { return _variables[_offset]; }
void setSpeciesSelector(reg_t value) { _variables[_offset] = value; }
- reg_t getSuperClassSelector() const { return _variables[_offset + 1]; }
+ reg_t getSuperClassSelector() { return _variables[_offset + 1]; }
void setSuperClassSelector(reg_t value) { _variables[_offset + 1] = value; }
- reg_t getInfoSelector() const { return _variables[_offset + 2]; }
- void setInfoSelector(reg_t value) { _variables[_offset + 2] = value; }
+ reg_t getInfoSelector() { return _variables[_offset + 2]; }
+ void setInfoSelector(reg_t value) { _variables[_offset + 2] = value; }
- reg_t getNameSelector() const { return _variables[_offset + 3]; }
- void setNameSelector(reg_t value) { _variables[_offset + 3] = value; }
+ reg_t getNameSelector() { return _variables[_offset + 3]; }
+ void setNameSelector(reg_t value) { _variables[_offset + 3] = value; }
- reg_t getPropDictSelector() const { return _variables[2]; }
- void setPropDictSelector(reg_t value) { _variables[2] = value; }
-
- reg_t getClassScriptSelector() const { return _variables[4]; }
+ reg_t getClassScriptSelector() { return _variables[4]; }
void setClassScriptSelector(reg_t value) { _variables[4] = value; }
- Selector getVarSelector(uint16 i) const { return READ_SCI11ENDIAN_UINT16(_baseVars + i); }
+ Selector getVarSelector(uint16 i) { return READ_SCI11ENDIAN_UINT16(_baseVars + i); }
- reg_t getFunction(uint16 i) const {
+ reg_t getFunction(uint16 i) {
uint16 offset = (getSciVersion() < SCI_VERSION_1_1) ? _methodCount + 1 + i : i * 2 + 2;
- return make_reg(_pos.segment, READ_SCI11ENDIAN_UINT16(_baseMethod + offset));
+ return make_reg(_pos.segment, READ_SCI11ENDIAN_UINT16((byte *) (_baseMethod + offset)));
}
- Selector getFuncSelector(uint16 i) const {
+ Selector getFuncSelector(uint16 i) {
uint16 offset = (getSciVersion() < SCI_VERSION_1_1) ? i : i * 2 + 1;
- return READ_SCI11ENDIAN_UINT16(_baseMethod + offset);
+ return READ_SCI11ENDIAN_UINT16((byte *) (_baseMethod + offset));
}
/**
@@ -266,7 +247,7 @@ public:
* superclasses, i.e. failure may be returned even if one of the
* superclasses defines the funcselector
*/
- int funcSelectorPosition(Selector sel) const {
+ int funcSelectorPosition(Selector sel) {
for (uint i = 0; i < _methodCount; i++)
if (getFuncSelector(i) == sel)
return i;
@@ -275,56 +256,61 @@ public:
}
/**
- * Determines if the object explicitly defines slc as a varselector.
- * Returns -1 if not found.
+ * Determines if the object explicitly defines slc as a varselector
+ * Returns -1 if not found
*/
- int locateVarSelector(SegManager *segMan, Selector slc) const;
-
- bool isClass() const { return (getInfoSelector().offset & kInfoFlagClass); }
- const Object *getClass(SegManager *segMan) const;
+ int locateVarSelector(SegManager *segMan, Selector slc);
- void markAsClone() { setInfoSelector(make_reg(0, kInfoFlagClone)); }
- bool isClone() const { return (getInfoSelector().offset & kInfoFlagClone); }
+ bool isClass() { return (getInfoSelector().offset & SCRIPT_INFO_CLASS); }
+ Object *getClass(SegManager *segMan);
void markAsFreed() { _flags |= OBJECT_FLAG_FREED; }
- bool isFreed() const { return _flags & OBJECT_FLAG_FREED; }
+ bool isFreed() { return _flags & OBJECT_FLAG_FREED; }
+
+ void setVarCount(uint size) { _variables.resize(size); }
+ uint getVarCount() { return _variables.size(); }
- uint getVarCount() const { return _variables.size(); }
+ void init(byte *buf, reg_t obj_pos) {
+ byte *data = (byte *)(buf + obj_pos.offset);
+ _baseObj = data;
+ _pos = obj_pos;
- void init(byte *buf, reg_t obj_pos, bool initVariables = true);
+ if (getSciVersion() < SCI_VERSION_1_1) {
+ _variables.resize(READ_LE_UINT16(data + SCRIPT_SELECTORCTR_OFFSET));
+ _baseVars = (uint16 *)(_baseObj + _variables.size() * 2);
+ _baseMethod = (uint16 *)(data + READ_LE_UINT16(data + SCRIPT_FUNCTAREAPTR_OFFSET));
+ _methodCount = READ_LE_UINT16(_baseMethod - 1);
+ } else {
+ _variables.resize(READ_SCI11ENDIAN_UINT16(data + 2));
+ _baseVars = (uint16 *)(buf + READ_SCI11ENDIAN_UINT16(data + 4));
+ _baseMethod = (uint16 *)(buf + READ_SCI11ENDIAN_UINT16(data + 6));
+ _methodCount = READ_SCI11ENDIAN_UINT16(_baseMethod);
+ }
+
+ for (uint i = 0; i < _variables.size(); i++)
+ _variables[i] = make_reg(0, READ_SCI11ENDIAN_UINT16(data + (i * 2)));
+ }
- reg_t getVariable(uint var) const { return _variables[var]; }
- reg_t &getVariableRef(uint var) { return _variables[var]; }
+ reg_t getVariable(uint var) { return _variables[var]; }
- uint16 getMethodCount() const { return _methodCount; }
- reg_t getPos() const { return _pos; }
+ uint16 getMethodCount() { return _methodCount; }
+ reg_t getPos() { return _pos; }
void saveLoadWithSerializer(Common::Serializer &ser);
- void cloneFromObject(const Object *obj) {
+ void cloneFromObject(Object *obj) {
_baseObj = obj ? obj->_baseObj : NULL;
_baseMethod = obj ? obj->_baseMethod : NULL;
_baseVars = obj ? obj->_baseVars : NULL;
}
- bool relocate(SegmentId segment, int location, size_t scriptSize);
-
- int propertyOffsetToId(SegManager *segMan, int propertyOffset) const;
-
- void initSpecies(SegManager *segMan, reg_t addr);
- void initSuperClass(SegManager *segMan, reg_t addr);
- bool initBaseObject(SegManager *segMan, reg_t addr, bool doInitSuperClass = true);
-
// TODO: make private
- // Only SegManager::reconstructScripts() is left needing direct access to these
-public:
- const byte *_baseObj; /**< base + object offset within base */
+ Common::Array<reg_t> _variables;
+ byte *_baseObj; /**< base + object offset within base */
+ uint16 *_baseVars; /**< Pointer to the varselector area for this object */
+ uint16 *_baseMethod; /**< Pointer to the method selector area for this object */
private:
- const uint16 *_baseVars; /**< Pointer to the varselector area for this object */
- const uint16 *_baseMethod; /**< Pointer to the method selector area for this object */
-
- Common::Array<reg_t> _variables;
uint16 _methodCount;
int _flags;
uint16 _offset;
@@ -342,27 +328,20 @@ class Script : public SegmentObj {
public:
int _nr; /**< Script number */
byte *_buf; /**< Static data buffer, or NULL if not used */
- byte *_heapStart; /**< Start of heap if SCI1.1, NULL otherwise */
-
- uint32 getScriptSize() { return _scriptSize; }
- uint32 getHeapSize() { return _heapSize; }
- uint32 getBufSize() { return _bufSize; }
-
-protected:
- int _lockers; /**< Number of classes and objects that require this script */
-
-private:
+ size_t _bufSize;
size_t _scriptSize;
size_t _heapSize;
- size_t _bufSize;
- const uint16 *_exportTable; /**< Abs. offset of the export table or 0 if not present */
- uint16 _numExports; /**< Number of entries in the exports table */
+ byte *_heapStart; /**< Start of heap if SCI1.1, NULL otherwise */
- const byte *_synonyms; /**< Synonyms block or 0 if not present*/
- uint16 _numSynonyms; /**< Number of entries in the synonyms block */
+ uint16 *_exportTable; /**< Abs. offset of the export table or 0 if not present */
+ int _numExports; /**< Number of entries in the exports table */
- Common::Array<CodeBlock> _codeBlocks;
+ byte *_synonyms; /**< Synonyms block or 0 if not present*/
+ int _numSynonyms; /**< Number of entries in the synonyms block */
+
+protected:
+ int _lockers; /**< Number of classes and objects that require this script */
public:
/**
@@ -375,6 +354,8 @@ public:
SegmentId _localsSegment; /**< The local variable segment */
LocalVariables *_localsBlock;
+ Common::Array<CodeBlock> _codeBlocks;
+ bool _relocated;
bool _markedAsDeleted;
public:
@@ -382,21 +363,19 @@ public:
~Script();
void freeScript();
- void init(int script_nr, ResourceManager *resMan);
- void load(ResourceManager *resMan);
+ bool init(int script_nr, ResourceManager *resMan);
virtual bool isValidOffset(uint16 offset) const;
virtual SegmentRef dereference(reg_t pointer);
- virtual reg_t findCanonicAddress(SegManager *segMan, reg_t sub_addr) const;
+ virtual reg_t findCanonicAddress(SegManager *segMan, reg_t sub_addr);
virtual void freeAtAddress(SegManager *segMan, reg_t sub_addr);
- virtual void listAllDeallocatable(SegmentId segId, void *param, NoteCallback note) const;
- virtual void listAllOutgoingReferences(reg_t object, void *param, NoteCallback note) const;
+ virtual void listAllDeallocatable(SegmentId segId, void *param, NoteCallback note);
+ virtual void listAllOutgoingReferences(reg_t object, void *param, NoteCallback note);
virtual void saveLoadWithSerializer(Common::Serializer &ser);
Object *allocateObject(uint16 offset);
Object *getObject(uint16 offset);
- const Object *getObject(uint16 offset) const;
/**
* Informs the segment manager that a code block must be relocated
@@ -413,7 +392,7 @@ public:
* @returns A newly created Object describing the object,
* stored within the relevant script
*/
- Object *scriptObjInit(reg_t obj_pos, bool fullObjectInit = true);
+ Object *scriptObjInit(reg_t obj_pos);
/**
* Removes a script object
@@ -428,10 +407,14 @@ public:
* @param obj_pos Location (segment, offset) of the block
* @return Location of the relocation block
*/
- void relocate(reg_t block);
+ void scriptRelocate(reg_t block);
+
+ void heapRelocate(reg_t block);
private:
- bool relocateLocal(SegmentId segment, int location);
+ int relocateLocal(SegmentId segment, int location);
+ int relocateBlock(Common::Array<reg_t> &block, int block_location, SegmentId segment, int location);
+ int relocateObject(Object &obj, SegmentId segment, int location);
public:
// script lock operations
@@ -452,28 +435,22 @@ public:
void setLockers(int lockers);
/**
- * Retrieves a pointer to the exports of this script
- * @return pointer to the exports.
- */
- const uint16 *getExportTable() const { return _exportTable; }
-
- /**
- * Retrieves the number of exports of script.
- * @return the number of exports of this script
- */
- uint16 getExportsNr() const { return _numExports; }
-
- /**
* Retrieves a pointer to the synonyms associated with this script
* @return pointer to the synonyms, in non-parsed format.
*/
- const byte *getSynonyms() const { return _synonyms; }
+ byte *getSynonyms() const;
/**
* Retrieves the number of synonyms associated with this script.
* @return the number of synonyms associated with this script
*/
- uint16 getSynonymsNr() const { return _numSynonyms; }
+ int getSynonymsNr() const;
+
+ /**
+ * Sets the script-relative offset of the exports table.
+ * @param offset script-relative exports table offset
+ */
+ void setExportTableOffset(int offset);
/**
* Validate whether the specified public function is exported by
@@ -485,6 +462,19 @@ public:
uint16 validateExportFunc(int pubfunct);
/**
+ * Sets the script-relative offset of the synonyms associated with this script.
+ * @param offset script-relative offset of the synonyms block
+ */
+ void setSynonymsOffset(int offset);
+
+ /**
+ * Sets the number of synonyms associated with this script,
+ * @param nr number of synonyms, as to be stored within the script
+ */
+ void setSynonymsNr(int nr);
+
+
+ /**
* Marks the script as deleted.
* This will not actually delete the script. If references remain present on the
* heap or the stack, the script will stay in memory in a quasi-deleted state until
@@ -518,10 +508,8 @@ public:
*/
int16 getHeap(uint16 offset) const;
- /**
- * Finds the pointer where a block of a specific type starts from
- */
- byte *findBlock(int type);
+private:
+ void setScriptSize(int script_nr, ResourceManager *resMan);
};
/** Data stack */
@@ -541,8 +529,8 @@ public:
virtual bool isValidOffset(uint16 offset) const;
virtual SegmentRef dereference(reg_t pointer);
- virtual reg_t findCanonicAddress(SegManager *segMan, reg_t sub_addr) const;
- virtual void listAllOutgoingReferences(reg_t object, void *param, NoteCallback note) const;
+ virtual reg_t findCanonicAddress(SegManager *segMan, reg_t sub_addr);
+ virtual void listAllOutgoingReferences(reg_t object, void *param, NoteCallback note);
virtual void saveLoadWithSerializer(Common::Serializer &ser);
};
@@ -630,7 +618,7 @@ public:
entries_used--;
}
- virtual void listAllDeallocatable(SegmentId segId, void *param, NoteCallback note) const {
+ virtual void listAllDeallocatable(SegmentId segId, void *param, NoteCallback note) {
for (uint i = 0; i < _table.size(); i++)
if (isValidEntry(i))
(*note)(param, make_reg(segId, i));
@@ -643,7 +631,7 @@ struct CloneTable : public Table<Clone> {
CloneTable() : Table<Clone>(SEG_TYPE_CLONES) {}
virtual void freeAtAddress(SegManager *segMan, reg_t sub_addr);
- virtual void listAllOutgoingReferences(reg_t object, void *param, NoteCallback note) const;
+ virtual void listAllOutgoingReferences(reg_t object, void *param, NoteCallback note);
virtual void saveLoadWithSerializer(Common::Serializer &ser);
};
@@ -654,7 +642,7 @@ struct NodeTable : public Table<Node> {
NodeTable() : Table<Node>(SEG_TYPE_NODES) {}
virtual void freeAtAddress(SegManager *segMan, reg_t sub_addr);
- virtual void listAllOutgoingReferences(reg_t object, void *param, NoteCallback note) const;
+ virtual void listAllOutgoingReferences(reg_t object, void *param, NoteCallback note);
virtual void saveLoadWithSerializer(Common::Serializer &ser);
};
@@ -665,7 +653,7 @@ struct ListTable : public Table<List> {
ListTable() : Table<List>(SEG_TYPE_LISTS) {}
virtual void freeAtAddress(SegManager *segMan, reg_t sub_addr);
- virtual void listAllOutgoingReferences(reg_t object, void *param, NoteCallback note) const;
+ virtual void listAllOutgoingReferences(reg_t object, void *param, NoteCallback note);
virtual void saveLoadWithSerializer(Common::Serializer &ser);
};
@@ -700,8 +688,8 @@ public:
virtual bool isValidOffset(uint16 offset) const;
virtual SegmentRef dereference(reg_t pointer);
- virtual reg_t findCanonicAddress(SegManager *segMan, reg_t sub_addr) const;
- virtual void listAllDeallocatable(SegmentId segId, void *param, NoteCallback note) const;
+ virtual reg_t findCanonicAddress(SegManager *segMan, reg_t sub_addr);
+ virtual void listAllDeallocatable(SegmentId segId, void *param, NoteCallback note);
virtual void saveLoadWithSerializer(Common::Serializer &ser);
};
@@ -794,7 +782,7 @@ public:
_size = _actualSize = size;
}
- T getValue(uint16 index) const {
+ T getValue(uint16 index) {
if (index >= _size)
error("SciArray::getValue(): %d is out of bounds (%d)", index, _size);
@@ -808,8 +796,8 @@ public:
_data[index] = value;
}
- byte getType() const { return _type; }
- uint32 getSize() const { return _size; }
+ byte getType() { return _type; }
+ uint32 getSize() { return _size; }
T *getRawData() { return _data; }
protected:
@@ -826,15 +814,15 @@ public:
// We overload destroy to ensure the string type is 3 after destroying
void destroy() { SciArray<char>::destroy(); _type = 3; }
- Common::String toString() const;
- void fromString(const Common::String &string);
+ Common::String toString();
+ void fromString(Common::String string);
};
struct ArrayTable : public Table<SciArray<reg_t> > {
ArrayTable() : Table<SciArray<reg_t> >(SEG_TYPE_ARRAY) {}
virtual void freeAtAddress(SegManager *segMan, reg_t sub_addr);
- virtual void listAllOutgoingReferences(reg_t object, void *param, NoteCallback note) const;
+ virtual void listAllOutgoingReferences(reg_t object, void *param, NoteCallback note);
void saveLoadWithSerializer(Common::Serializer &ser);
SegmentRef dereference(reg_t pointer);