ScummVM API documentation
saveload.h
1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #ifndef TSAGE_SAVELOAD_H
23 #define TSAGE_SAVELOAD_H
24 
25 #include "common/scummsys.h"
26 #include "common/list.h"
27 #include "common/memstream.h"
28 #include "common/savefile.h"
29 #include "common/serializer.h"
30 
31 namespace TsAGE {
32 
33 typedef void (*SaveNotifierFn)(bool postFlag);
34 
35 #define TSAGE_SAVEGAME_VERSION 15
36 
37 class SavedObject;
38 
40  uint8 _version;
41  Common::String _saveName;
42  Graphics::Surface *_thumbnail;
43  int _saveYear, _saveMonth, _saveDay;
44  int _saveHour, _saveMinutes;
45  int _totalFrames;
46 };
47 
48 /*--------------------------------------------------------------------------*/
49 
50 // FIXME: workaround to suppress spurious strict-alias warnings on older GCC
51 // versions. this should be resolved with the savegame rewrite
52 #define SYNC_POINTER(x) do { \
53  SavedObject **y = (SavedObject **)((void *)&x); \
54  s.syncPointer(y); \
55 } while (false)
56 
57 #define SYNC_ENUM(FIELD, TYPE) int v_##FIELD = (int)FIELD; s.syncAsUint16LE(v_##FIELD); \
58  if (s.isLoading()) FIELD = (TYPE)v_##FIELD;
59 
64 public:
66 
67  // HACK: TSAGE saved games contain a single byte for the savegame version,
68  // thus the normal syncVersion() Serializer member won't work here. In order
69  // to maintain compatibility with older game saves, this method is provided
70  // in order to set the savegame version from a byte
71  void setSaveVersion(byte version) { _version = version; }
72 
73  void syncPointer(SavedObject **ptr, Common::Serializer::Version minVersion = 0,
74  Common::Serializer::Version maxVersion = kLastVersion);
75  void validate(const Common::String &s, Common::Serializer::Version minVersion = 0,
76  Common::Serializer::Version maxVersion = kLastVersion);
77  void validate(int v, Common::Serializer::Version minVersion = 0,
78  Common::Serializer::Version maxVersion = kLastVersion);
79  void syncAsDouble(double &v);
80 };
81 
82 /*--------------------------------------------------------------------------*/
83 
84 class Serialisable {
85 public:
86  virtual ~Serialisable() {}
87  virtual void synchronize(Serializer &s) = 0;
88 };
89 
90 class SaveListener {
91 public:
92  virtual ~SaveListener() {}
93  virtual void listenerSynchronize(Serializer &s) = 0;
94 };
95 
96 /*--------------------------------------------------------------------------*/
97 
98 class SavedObject : public Serialisable {
99 public:
100  SavedObject();
101  ~SavedObject() override;
102 
103  virtual Common::String getClassName() { return "SavedObject"; }
104  void synchronize(Serializer &s) override {}
105 
106  static SavedObject *createInstance(const Common::String &className);
107 };
108 
109 /*--------------------------------------------------------------------------*/
110 
114 template<typename T>
115 class SynchronizedList : public Common::List<T> {
116 public:
117  void synchronize(Serializer &s) {
118  int entryCount = 0;
119 
120  if (s.isLoading()) {
121  this->clear();
122  s.syncAsUint32LE(entryCount);
123 
124  for (int idx = 0; idx < entryCount; ++idx) {
125  this->push_back(static_cast<T>((T)NULL));
126  T &obj = Common::List<T>::back();
127  s.syncPointer((SavedObject **)&obj);
128  }
129  } else {
130  // Get the list size
131  entryCount = this->size();
132 
133  // Write out list
134  s.syncAsUint32LE(entryCount);
135  for (typename Common::List<T>::iterator i = this->begin(); i != this->end(); ++i) {
136  s.syncPointer((SavedObject **)&*i);
137  }
138  }
139  }
140 
141  void addBefore(T existingItem, T newItem) {
142  typename SynchronizedList<T>::iterator i = this->begin();
143  while ((i != this->end()) && (*i != existingItem)) ++i;
144  this->insert(i, newItem);
145  }
146  void addAfter(T existingItem, T newItem) {
147  typename SynchronizedList<T>::iterator i = this->begin();
148  while ((i != this->end()) && (*i != existingItem)) ++i;
149  if (i != this->end()) ++i;
150  this->insert(i, newItem);
151  }
152 
153  bool contains(T item) {
154  typename SynchronizedList<T>::iterator i = this->begin();
155  for (; i != this->end(); ++i) {
156  if (*i == item)
157  return true;
158  }
159 
160  return false;
161  }
162 };
163 
171 template<typename T>
172 inline bool contains(const Common::List<T> &l, const T &v) {
173  return (Common::find(l.begin(), l.end(), v) != l.end());
174 }
175 
179 template<typename T>
180 class FunctionList : public Common::List<void (*)(T)> {
181 public:
182  void notify(T v) {
183  for (typename Common::List<void (*)(T)>::iterator i = this->begin(); i != this->end(); ++i) {
184  (*i)(v);
185  }
186  }
187 };
188 
189 /*--------------------------------------------------------------------------*/
190 
192 public:
193  SavedObject **_savedObject;
194  int _objIndex;
195 
196  SavedObjectRef() : _savedObject(NULL), _objIndex(-1) {}
197  SavedObjectRef(SavedObject **so, int objIndex) : _savedObject(so), _objIndex(objIndex) {}
198 };
199 
200 typedef SavedObject *(*SavedObjectFactory)(const Common::String &className);
201 
202 class Saver {
204 private:
206  FunctionList<bool> _saveNotifiers;
207  FunctionList<bool> _loadNotifiers;
208  Common::List<SaveListener *> _listeners;
209 
210  Common::List<SavedObjectRef> _unresolvedPtrs;
211  SavedObjectFactory _factoryPtr;
212 
213  bool _macroSaveFlag;
214  bool _macroRestoreFlag;
215 
216  void resolveLoadPointers(DynObjects &dynObjects);
217 public:
218  Saver();
219  ~Saver();
220 
221  Common::Error save(int slot, const Common::String &saveName);
222  Common::Error restore(int slot);
223  WARN_UNUSED_RESULT static bool readSavegameHeader(Common::InSaveFile *in, tSageSavegameHeader &header, bool skipThumbnail = true);
224  static void writeSavegameHeader(Common::OutSaveFile *out, tSageSavegameHeader &header);
225 
226  void addListener(SaveListener *obj);
227  void addSaveNotifier(SaveNotifierFn fn);
228  void addLoadNotifier(SaveNotifierFn fn);
229  void addObject(SavedObject *obj);
230  void removeObject(SavedObject *obj);
231  void addFactory(SavedObjectFactory fn) { _factoryPtr = fn; }
232  void addSavedObjectPtr(SavedObject **ptr, int objIndex) {
233  _unresolvedPtrs.push_back(SavedObjectRef(ptr, objIndex));
234  }
235 
236  bool savegamesExist() const;
237  bool getMacroSaveFlag() const { return _macroSaveFlag; }
238  bool getMacroRestoreFlag() const { return _macroRestoreFlag; }
239  int blockIndexOf(SavedObject *p);
240  int getObjectCount() const;
241  void listObjects();
242 };
243 
244 extern Saver *g_saver;
245 
246 } // End of namespace TsAGE
247 
248 #endif
Definition: saveload.h:39
Definition: str.h:59
Definition: saveload.h:98
Definition: saveload.h:84
Definition: surface.h:67
Definition: saveload.h:191
Definition: stream.h:77
Definition: savefile.h:54
Definition: error.h:84
In find(In first, In last, const T &v)
Definition: algorithm.h:225
Definition: list.h:44
Definition: stream.h:745
Definition: saveload.h:202
Definition: serializer.h:79
t_T & back()
Definition: list.h:167
iterator end()
Definition: list.h:240
iterator begin()
Definition: list.h:227
bool skipThumbnail(Common::SeekableReadStream &in)
Definition: saveload.h:115
Definition: blueforce_dialogs.h:30
Definition: saveload.h:63
Definition: list_intern.h:51
void push_back(const t_T &element)
Definition: list.h:140
Definition: saveload.h:90
Definition: saveload.h:180