diff options
-rw-r--r-- | engines/sci/engine/savegame.cpp | 10 | ||||
-rw-r--r-- | engines/sci/engine/segment.cpp | 141 | ||||
-rw-r--r-- | engines/sci/engine/segment.h | 88 |
3 files changed, 103 insertions, 136 deletions
diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp index ab355cebb4..43d00ebc15 100644 --- a/engines/sci/engine/savegame.cpp +++ b/engines/sci/engine/savegame.cpp @@ -328,14 +328,14 @@ void Object::saveLoadWithSerializer(Common::Serializer &s) { } template <> -void syncWithSerializer(Common::Serializer &s, Table<Clone>::Entry &obj) { +void syncWithSerializer(Common::Serializer &s, SegmentObjTable<Clone>::Entry &obj) { s.syncAsSint32LE(obj.next_free); syncWithSerializer<Object>(s, obj); } template <> -void syncWithSerializer(Common::Serializer &s, Table<List>::Entry &obj) { +void syncWithSerializer(Common::Serializer &s, SegmentObjTable<List>::Entry &obj) { s.syncAsSint32LE(obj.next_free); syncWithSerializer(s, obj.first); @@ -343,7 +343,7 @@ void syncWithSerializer(Common::Serializer &s, Table<List>::Entry &obj) { } template <> -void syncWithSerializer(Common::Serializer &s, Table<Node>::Entry &obj) { +void syncWithSerializer(Common::Serializer &s, SegmentObjTable<Node>::Entry &obj) { s.syncAsSint32LE(obj.next_free); syncWithSerializer(s, obj.pred); @@ -354,7 +354,7 @@ void syncWithSerializer(Common::Serializer &s, Table<Node>::Entry &obj) { #ifdef ENABLE_SCI32 template <> -void syncWithSerializer(Common::Serializer &s, Table<SciArray<reg_t> >::Entry &obj) { +void syncWithSerializer(Common::Serializer &s, SegmentObjTable<SciArray<reg_t> >::Entry &obj) { s.syncAsSint32LE(obj.next_free); byte type = 0; @@ -390,7 +390,7 @@ void syncWithSerializer(Common::Serializer &s, Table<SciArray<reg_t> >::Entry &o } template <> -void syncWithSerializer(Common::Serializer &s, Table<SciString>::Entry &obj) { +void syncWithSerializer(Common::Serializer &s, SegmentObjTable<SciString>::Entry &obj) { s.syncAsSint32LE(obj.next_free); uint32 size = 0; diff --git a/engines/sci/engine/segment.cpp b/engines/sci/engine/segment.cpp index 2af4771cea..2bb77c707a 100644 --- a/engines/sci/engine/segment.cpp +++ b/engines/sci/engine/segment.cpp @@ -90,69 +90,6 @@ SegmentRef SegmentObj::dereference(reg_t pointer) { return SegmentRef(); } - -bool LocalVariables::isValidOffset(uint16 offset) const { - return offset < _locals.size() * 2; -} - -SegmentRef LocalVariables::dereference(reg_t pointer) { - SegmentRef ret; - ret.isRaw = false; // reg_t based data! - ret.maxSize = (_locals.size() - pointer.offset / 2) * 2; - - if (pointer.offset & 1) { - ret.maxSize -= 1; - ret.skipByte = true; - } - - if (ret.maxSize > 0) { - ret.reg = &_locals[pointer.offset / 2]; - } else { - if ((g_sci->getEngineState()->currentRoomNumber() == 660 || g_sci->getEngineState()->currentRoomNumber() == 660) - && g_sci->getGameId() == GID_LAURABOW2) { - // Happens in two places during the intro of LB2CD, both from kMemory(peek): - // - room 160: Heap 160 has 83 local variables (0-82), and the game - // asks for variables at indices 83 - 90 too. - // - room 220: Heap 220 has 114 local variables (0-113), and the - // game asks for variables at indices 114-120 too. - } else { - error("LocalVariables::dereference: Offset at end or out of bounds %04x:%04x", PRINT_REG(pointer)); - } - ret.reg = 0; - } - return ret; -} - -bool DataStack::isValidOffset(uint16 offset) const { - return offset < _capacity * 2; -} - -SegmentRef DataStack::dereference(reg_t pointer) { - SegmentRef ret; - ret.isRaw = false; // reg_t based data! - ret.maxSize = (_capacity - pointer.offset / 2) * 2; - - if (pointer.offset & 1) { - ret.maxSize -= 1; - ret.skipByte = true; - } - - ret.reg = &_entries[pointer.offset / 2]; - return ret; -} - -bool DynMem::isValidOffset(uint16 offset) const { - return offset < _size; -} - -SegmentRef DynMem::dereference(reg_t pointer) { - SegmentRef ret; - ret.isRaw = true; - ret.maxSize = _size - pointer.offset; - ret.raw = _buf + pointer.offset; - return ret; -} - //-------------------- clones -------------------- Common::Array<reg_t> CloneTable::listAllOutgoingReferences(reg_t addr) const { @@ -195,18 +132,44 @@ void CloneTable::freeAtAddress(SegManager *segMan, reg_t addr) { //-------------------- locals -------------------- + +SegmentRef LocalVariables::dereference(reg_t pointer) { + SegmentRef ret; + ret.isRaw = false; // reg_t based data! + ret.maxSize = (_locals.size() - pointer.offset / 2) * 2; + + if (pointer.offset & 1) { + ret.maxSize -= 1; + ret.skipByte = true; + } + + if (ret.maxSize > 0) { + ret.reg = &_locals[pointer.offset / 2]; + } else { + if ((g_sci->getEngineState()->currentRoomNumber() == 660 || g_sci->getEngineState()->currentRoomNumber() == 660) + && g_sci->getGameId() == GID_LAURABOW2) { + // Happens in two places during the intro of LB2CD, both from kMemory(peek): + // - room 160: Heap 160 has 83 local variables (0-82), and the game + // asks for variables at indices 83 - 90 too. + // - room 220: Heap 220 has 114 local variables (0-113), and the + // game asks for variables at indices 114-120 too. + } else { + error("LocalVariables::dereference: Offset at end or out of bounds %04x:%04x", PRINT_REG(pointer)); + } + ret.reg = 0; + } + return ret; +} + reg_t LocalVariables::findCanonicAddress(SegManager *segMan, reg_t addr) const { // Reference the owning script SegmentId owner_seg = segMan->getScriptSegment(script_id); - assert(owner_seg > 0); - return make_reg(owner_seg, 0); } Common::Array<reg_t> LocalVariables::listAllOutgoingReferences(reg_t addr) const { Common::Array<reg_t> tmp; - for (uint i = 0; i < _locals.size(); i++) tmp.push_back(_locals[i]); @@ -215,8 +178,19 @@ Common::Array<reg_t> LocalVariables::listAllOutgoingReferences(reg_t addr) const //-------------------- stack -------------------- -reg_t DataStack::findCanonicAddress(SegManager *segMan, reg_t addr) const { - return make_reg(addr.segment, 0); + +SegmentRef DataStack::dereference(reg_t pointer) { + SegmentRef ret; + ret.isRaw = false; // reg_t based data! + ret.maxSize = (_capacity - pointer.offset / 2) * 2; + + if (pointer.offset & 1) { + ret.maxSize -= 1; + ret.skipByte = true; + } + + ret.reg = &_entries[pointer.offset / 2]; + return ret; } Common::Array<reg_t> DataStack::listAllOutgoingReferences(reg_t object) const { @@ -227,16 +201,7 @@ Common::Array<reg_t> DataStack::listAllOutgoingReferences(reg_t object) const { return tmp; } - -//-------------------- hunk --------------------- -void HunkTable::freeAtAddress(SegManager *segMan, reg_t sub_addr) { - freeEntry(sub_addr.offset); -} - //-------------------- lists -------------------- -void ListTable::freeAtAddress(SegManager *segMan, reg_t sub_addr) { - freeEntry(sub_addr.offset); -} Common::Array<reg_t> ListTable::listAllOutgoingReferences(reg_t addr) const { Common::Array<reg_t> tmp; @@ -254,11 +219,7 @@ Common::Array<reg_t> ListTable::listAllOutgoingReferences(reg_t addr) const { return tmp; } - //-------------------- nodes -------------------- -void NodeTable::freeAtAddress(SegManager *segMan, reg_t sub_addr) { - freeEntry(sub_addr.offset); -} Common::Array<reg_t> NodeTable::listAllOutgoingReferences(reg_t addr) const { Common::Array<reg_t> tmp; @@ -279,13 +240,12 @@ Common::Array<reg_t> NodeTable::listAllOutgoingReferences(reg_t addr) const { //-------------------- dynamic memory -------------------- -reg_t DynMem::findCanonicAddress(SegManager *segMan, reg_t addr) const { - return make_reg(addr.segment, 0); -} - -Common::Array<reg_t> DynMem::listAllDeallocatable(SegmentId segId) const { - const reg_t r = make_reg(segId, 0); - return Common::Array<reg_t>(&r, 1); +SegmentRef DynMem::dereference(reg_t pointer) { + SegmentRef ret; + ret.isRaw = true; + ret.maxSize = _size - pointer.offset; + ret.raw = _buf + pointer.offset; + return ret; } #ifdef ENABLE_SCI32 @@ -350,11 +310,6 @@ SegmentRef StringTable::dereference(reg_t pointer) { return ret; } -void StringTable::freeAtAddress(SegManager *segMan, reg_t sub_addr) { - _table[sub_addr.offset].destroy(); - freeEntry(sub_addr.offset); -} - #endif } // End of namespace Sci diff --git a/engines/sci/engine/segment.h b/engines/sci/engine/segment.h index c3ce671632..ffde01f934 100644 --- a/engines/sci/engine/segment.h +++ b/engines/sci/engine/segment.h @@ -149,11 +149,11 @@ struct LocalVariables : public SegmentObj { Common::Array<reg_t> _locals; public: - LocalVariables(): SegmentObj(SEG_TYPE_LOCALS) { - script_id = 0; - } + LocalVariables(): SegmentObj(SEG_TYPE_LOCALS), script_id(0) { } - virtual bool isValidOffset(uint16 offset) const; + virtual bool isValidOffset(uint16 offset) const { + return offset < _locals.size() * 2; + } virtual SegmentRef dereference(reg_t pointer); virtual reg_t findCanonicAddress(SegManager *segMan, reg_t sub_addr) const; virtual Common::Array<reg_t> listAllOutgoingReferences(reg_t object) const; @@ -167,18 +167,19 @@ struct DataStack : SegmentObj { reg_t *_entries; public: - DataStack() : SegmentObj(SEG_TYPE_STACK) { - _capacity = 0; - _entries = NULL; - } + DataStack() : SegmentObj(SEG_TYPE_STACK), _capacity(0), _entries(NULL) { } ~DataStack() { free(_entries); _entries = NULL; } - virtual bool isValidOffset(uint16 offset) const; + virtual bool isValidOffset(uint16 offset) const { + return offset < _capacity * 2; + } 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 addr) const { + return make_reg(addr.segment, 0); + } virtual Common::Array<reg_t> listAllOutgoingReferences(reg_t object) const; virtual void saveLoadWithSerializer(Common::Serializer &ser); @@ -210,7 +211,7 @@ struct Hunk { }; template<typename T> -struct Table : public SegmentObj { +struct SegmentObjTable : public SegmentObj { typedef T value_type; struct Entry : public T { int next_free; /* Only used for free entries */ @@ -224,7 +225,7 @@ struct Table : public SegmentObj { Common::Array<Entry> _table; public: - Table(SegmentType type) : SegmentObj(type) { + SegmentObjTable(SegmentType type) : SegmentObj(type) { initTable(); } @@ -278,8 +279,8 @@ public: /* CloneTable */ -struct CloneTable : public Table<Clone> { - CloneTable() : Table<Clone>(SEG_TYPE_CLONES) {} +struct CloneTable : public SegmentObjTable<Clone> { + CloneTable() : SegmentObjTable<Clone>(SEG_TYPE_CLONES) {} virtual void freeAtAddress(SegManager *segMan, reg_t sub_addr); virtual Common::Array<reg_t> listAllOutgoingReferences(reg_t object) const; @@ -289,10 +290,12 @@ struct CloneTable : public Table<Clone> { /* NodeTable */ -struct NodeTable : public Table<Node> { - NodeTable() : Table<Node>(SEG_TYPE_NODES) {} +struct NodeTable : public SegmentObjTable<Node> { + NodeTable() : SegmentObjTable<Node>(SEG_TYPE_NODES) {} - virtual void freeAtAddress(SegManager *segMan, reg_t sub_addr); + virtual void freeAtAddress(SegManager *segMan, reg_t sub_addr) { + freeEntry(sub_addr.offset); + } virtual Common::Array<reg_t> listAllOutgoingReferences(reg_t object) const; virtual void saveLoadWithSerializer(Common::Serializer &ser); @@ -300,10 +303,12 @@ struct NodeTable : public Table<Node> { /* ListTable */ -struct ListTable : public Table<List> { - ListTable() : Table<List>(SEG_TYPE_LISTS) {} +struct ListTable : public SegmentObjTable<List> { + ListTable() : SegmentObjTable<List>(SEG_TYPE_LISTS) {} - virtual void freeAtAddress(SegManager *segMan, reg_t sub_addr); + virtual void freeAtAddress(SegManager *segMan, reg_t sub_addr) { + freeEntry(sub_addr.offset); + } virtual Common::Array<reg_t> listAllOutgoingReferences(reg_t object) const; virtual void saveLoadWithSerializer(Common::Serializer &ser); @@ -311,8 +316,8 @@ struct ListTable : public Table<List> { /* HunkTable */ -struct HunkTable : public Table<Hunk> { - HunkTable() : Table<Hunk>(SEG_TYPE_HUNK) {} +struct HunkTable : public SegmentObjTable<Hunk> { + HunkTable() : SegmentObjTable<Hunk>(SEG_TYPE_HUNK) {} void freeEntryContents(int idx) { free(_table[idx].mem); @@ -320,11 +325,13 @@ struct HunkTable : public Table<Hunk> { } virtual void freeEntry(int idx) { - Table<Hunk>::freeEntry(idx); + SegmentObjTable<Hunk>::freeEntry(idx); freeEntryContents(idx); } - virtual void freeAtAddress(SegManager *segMan, reg_t sub_addr); + virtual void freeAtAddress(SegManager *segMan, reg_t sub_addr) { + freeEntry(sub_addr.offset); + } virtual void saveLoadWithSerializer(Common::Serializer &ser); }; @@ -343,10 +350,17 @@ public: _buf = NULL; } - virtual bool isValidOffset(uint16 offset) const; + virtual bool isValidOffset(uint16 offset) const { + return offset < _size; + } virtual SegmentRef dereference(reg_t pointer); - virtual reg_t findCanonicAddress(SegManager *segMan, reg_t sub_addr) const; - virtual Common::Array<reg_t> listAllDeallocatable(SegmentId segId) const; + virtual reg_t findCanonicAddress(SegManager *segMan, reg_t addr) const { + return make_reg(addr.segment, 0); + } + virtual Common::Array<reg_t> listAllDeallocatable(SegmentId segId) const { + const reg_t r = make_reg(segId, 0); + return Common::Array<reg_t>(&r, 1); + } virtual void saveLoadWithSerializer(Common::Serializer &ser); }; @@ -356,12 +370,7 @@ public: template <typename T> class SciArray { public: - SciArray() { - _type = -1; - _data = NULL; - _size = 0; - _actualSize = 0; - } + SciArray() : _type(-1), _data(NULL), _size(0), _actualSize(0) { } SciArray(const SciArray<T> &array) { _type = array._type; @@ -476,8 +485,8 @@ public: void fromString(const Common::String &string); }; -struct ArrayTable : public Table<SciArray<reg_t> > { - ArrayTable() : Table<SciArray<reg_t> >(SEG_TYPE_ARRAY) {} +struct ArrayTable : public SegmentObjTable<SciArray<reg_t> > { + ArrayTable() : SegmentObjTable<SciArray<reg_t> >(SEG_TYPE_ARRAY) {} virtual void freeAtAddress(SegManager *segMan, reg_t sub_addr); virtual Common::Array<reg_t> listAllOutgoingReferences(reg_t object) const; @@ -486,10 +495,13 @@ struct ArrayTable : public Table<SciArray<reg_t> > { SegmentRef dereference(reg_t pointer); }; -struct StringTable : public Table<SciString> { - StringTable() : Table<SciString>(SEG_TYPE_STRING) {} +struct StringTable : public SegmentObjTable<SciString> { + StringTable() : SegmentObjTable<SciString>(SEG_TYPE_STRING) {} - virtual void freeAtAddress(SegManager *segMan, reg_t sub_addr); + virtual void freeAtAddress(SegManager *segMan, reg_t sub_addr) { + _table[sub_addr.offset].destroy(); + freeEntry(sub_addr.offset); + } void saveLoadWithSerializer(Common::Serializer &ser); SegmentRef dereference(reg_t pointer); |