aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/engine
diff options
context:
space:
mode:
Diffstat (limited to 'engines/sci/engine')
-rw-r--r--engines/sci/engine/savegame.cpp49
-rw-r--r--engines/sci/engine/savegame.h3
-rw-r--r--engines/sci/engine/seg_manager.cpp12
-rw-r--r--engines/sci/engine/segment.h57
4 files changed, 53 insertions, 68 deletions
diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp
index c4d53a2dc9..c5d2834e58 100644
--- a/engines/sci/engine/savegame.cpp
+++ b/engines/sci/engine/savegame.cpp
@@ -159,23 +159,6 @@ void syncWithSerializer(Common::Serializer &s, SciString &obj) {
}
}
-void syncWithSerializer(Common::Serializer &s, SciBitmap *&obj) {
- bool hasEntry;
- if (s.isSaving()) {
- hasEntry = obj != nullptr;
- }
- s.syncAsByte(hasEntry);
-
- if (hasEntry) {
- if (s.isLoading()) {
- obj = new SciBitmap;
- }
-
- obj->saveLoadWithSerializer(s);
- } else {
- obj = nullptr;
- }
-}
#endif
#pragma mark -
@@ -183,7 +166,7 @@ void syncWithSerializer(Common::Serializer &s, SciBitmap *&obj) {
// By default, sync using syncWithSerializer, which in turn can easily be overloaded.
template<typename T>
struct DefaultSyncer : Common::BinaryFunction<Common::Serializer, T, void> {
- void operator()(Common::Serializer &s, T &obj) const {
+ void operator()(Common::Serializer &s, T &obj, int) const {
syncWithSerializer(s, obj);
}
};
@@ -191,10 +174,31 @@ struct DefaultSyncer : Common::BinaryFunction<Common::Serializer, T, void> {
// Syncer for entries in a segment obj table
template<typename T>
struct SegmentObjTableEntrySyncer : Common::BinaryFunction<Common::Serializer, typename T::Entry &, void> {
- void operator()(Common::Serializer &s, typename T::Entry &entry) const {
+ void operator()(Common::Serializer &s, typename T::Entry &entry, int index) const {
s.syncAsSint32LE(entry.next_free);
- syncWithSerializer(s, entry.data);
+ bool hasData;
+ if (s.getVersion() >= 37) {
+ if (s.isSaving()) {
+ hasData = entry.data != nullptr;
+ }
+ s.syncAsByte(hasData);
+ } else {
+ hasData = (entry.next_free == index);
+ }
+
+ if (hasData) {
+ if (s.isLoading()) {
+ entry.data = new typename T::value_type;
+ }
+ syncWithSerializer(s, *entry.data);
+ } else if (s.isLoading()) {
+ if (s.getVersion() < 37) {
+ typename T::value_type dummy;
+ syncWithSerializer(s, dummy);
+ }
+ entry.data = nullptr;
+ }
}
};
@@ -222,9 +226,8 @@ struct ArraySyncer : Common::BinaryFunction<Common::Serializer, T, void> {
if (s.isLoading())
arr.resize(len);
- typename Common::Array<T>::iterator i;
- for (i = arr.begin(); i != arr.end(); ++i) {
- sync(s, *i);
+ for (int i = 0; i < len; ++i) {
+ sync(s, arr[i], i);
}
}
};
diff --git a/engines/sci/engine/savegame.h b/engines/sci/engine/savegame.h
index c5c2bcef08..1bf66864e8 100644
--- a/engines/sci/engine/savegame.h
+++ b/engines/sci/engine/savegame.h
@@ -37,6 +37,7 @@ struct EngineState;
*
* Version - new/changed feature
* =============================
+ * 37 - Segment entry data changed to pointers
* 36 - SCI32 bitmap segment
* 35 - SCI32 remap
* 34 - SCI32 palettes, and store play time in ticks
@@ -61,7 +62,7 @@ struct EngineState;
*/
enum {
- CURRENT_SAVEGAME_VERSION = 36,
+ CURRENT_SAVEGAME_VERSION = 37,
MINIMUM_SAVEGAME_VERSION = 14
};
diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp
index 608452983a..5cf8d6162d 100644
--- a/engines/sci/engine/seg_manager.cpp
+++ b/engines/sci/engine/seg_manager.cpp
@@ -959,15 +959,11 @@ SciBitmap *SegManager::allocateBitmap(reg_t *addr, const int16 width, const int1
offset = table->allocEntry();
*addr = make_reg(_bitmapSegId, offset);
- SciBitmap *bitmap = table->at(offset);
+ SciBitmap &bitmap = table->at(offset);
- if (bitmap == nullptr) {
- *addr = NULL_REG;
- }
-
- bitmap->create(width, height, skipColor, displaceX, displaceY, scaledWidth, scaledHeight, paletteSize, remap, gc);
+ bitmap.create(width, height, skipColor, displaceX, displaceY, scaledWidth, scaledHeight, paletteSize, remap, gc);
- return bitmap;
+ return &bitmap;
}
SciBitmap *SegManager::lookupBitmap(const reg_t addr) {
@@ -979,7 +975,7 @@ SciBitmap *SegManager::lookupBitmap(const reg_t addr) {
if (!bitmapTable.isValidEntry(addr.getOffset()))
error("Attempt to use invalid entry %04x:%04x as bitmap", PRINT_REG(addr));
- return (bitmapTable.at(addr.getOffset()));
+ return &(bitmapTable.at(addr.getOffset()));
}
void SegManager::freeBitmap(const reg_t addr) {
diff --git a/engines/sci/engine/segment.h b/engines/sci/engine/segment.h
index 97a6cb585f..add5f4c57c 100644
--- a/engines/sci/engine/segment.h
+++ b/engines/sci/engine/segment.h
@@ -227,7 +227,7 @@ template<typename T>
struct SegmentObjTable : public SegmentObj {
typedef T value_type;
struct Entry {
- T data;
+ T *data;
int next_free; /* Only used for free entries */
};
enum { HEAPENTRY_INVALID = -1 };
@@ -243,6 +243,14 @@ public:
initTable();
}
+ ~SegmentObjTable() {
+ for (uint i = 0; i < _table.size(); i++) {
+ if (isValidEntry(i)) {
+ freeEntry(i);
+ }
+ }
+ }
+
void initTable() {
entries_used = 0;
first_free = HEAPENTRY_INVALID;
@@ -256,10 +264,13 @@ public:
first_free = _table[oldff].next_free;
_table[oldff].next_free = oldff;
+ assert(_table[oldff].data == nullptr);
+ _table[oldff].data = new T;
return oldff;
} else {
uint newIdx = _table.size();
_table.push_back(Entry());
+ _table.back().data = new T;
_table[newIdx].next_free = newIdx; // Tag as 'valid'
return newIdx;
}
@@ -278,6 +289,8 @@ public:
::error("Table::freeEntry: Attempt to release invalid table index %d", idx);
_table[idx].next_free = first_free;
+ delete _table[idx].data;
+ _table[idx].data = nullptr;
first_free = idx;
entries_used--;
}
@@ -292,8 +305,8 @@ public:
uint size() const { return _table.size(); }
- T &at(uint index) { return _table[index].data; }
- const T &at(uint index) const { return _table[index].data; }
+ T &at(uint index) { return *_table[index].data; }
+ const T &at(uint index) const { return *_table[index].data; }
T &operator[](uint index) { return at(index); }
const T &operator[](uint index) const { return at(index); }
@@ -353,8 +366,8 @@ struct HunkTable : public SegmentObjTable<Hunk> {
}
virtual void freeEntry(int idx) {
- SegmentObjTable<Hunk>::freeEntry(idx);
freeEntryContents(idx);
+ SegmentObjTable<Hunk>::freeEntry(idx);
}
virtual void freeAtAddress(SegManager *segMan, reg_t sub_addr) {
@@ -792,42 +805,14 @@ public:
virtual void saveLoadWithSerializer(Common::Serializer &ser);
};
-struct BitmapTable : public SegmentObjTable<SciBitmap *> {
- BitmapTable() : SegmentObjTable<SciBitmap *>(SEG_TYPE_BITMAP) {}
-
- virtual ~BitmapTable() {
- for (uint i = 0; i < _table.size(); i++) {
- if (isValidEntry(i)) {
- freeEntryContents(i);
- }
- }
- }
-
- int allocEntry() {
- int offset = SegmentObjTable<SciBitmap *>::allocEntry();
- at(offset) = new SciBitmap;
- return offset;
- }
-
- void freeEntryContents(const int offset) {
- delete at(offset);
- at(offset) = nullptr;
- }
-
- virtual void freeEntry(const int offset) override {
- SegmentObjTable<SciBitmap *>::freeEntry(offset);
- freeEntryContents(offset);
- }
-
- virtual void freeAtAddress(SegManager *segMan, reg_t sub_addr) override {
- freeEntry(sub_addr.getOffset());
- }
+struct BitmapTable : public SegmentObjTable<SciBitmap> {
+ BitmapTable() : SegmentObjTable<SciBitmap>(SEG_TYPE_BITMAP) {}
SegmentRef dereference(reg_t pointer) {
SegmentRef ret;
ret.isRaw = true;
- ret.maxSize = at(pointer.getOffset())->getRawSize();
- ret.raw = at(pointer.getOffset())->getRawData();
+ ret.maxSize = at(pointer.getOffset()).getRawSize();
+ ret.raw = at(pointer.getOffset()).getRawData();
return ret;
}