OpenTTD
saveload.h
Go to the documentation of this file.
1 /* $Id: saveload.h 26591 2014-05-16 17:41:55Z rubidium $ */
2 
3 /*
4  * This file is part of OpenTTD.
5  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
6  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
7  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
8  */
9 
12 #ifndef SAVELOAD_H
13 #define SAVELOAD_H
14 
15 #include "../fileio_type.h"
16 #include "../strings_type.h"
17 
20  SL_OK = 0,
21  SL_ERROR = 1,
22  SL_REINIT = 2,
23 };
24 
27  SL_INVALID = -1,
28  SL_LOAD = 0,
29  SL_SAVE = 1,
31  SL_PNG = 3,
32  SL_BMP = 4,
34 };
35 
43  SGT_INVALID = 0xFF,
44 };
45 
46 void GenerateDefaultSaveName(char *buf, const char *last);
47 void SetSaveLoadError(uint16 str);
48 const char *GetSaveLoadErrorString();
49 SaveOrLoadResult SaveOrLoad(const char *filename, int mode, Subdirectory sb, bool threaded = true);
50 void WaitTillSaved();
52 void DoExitSave();
53 
54 SaveOrLoadResult SaveWithFilter(struct SaveFilter *writer, bool threaded);
56 
57 typedef void ChunkSaveLoadProc();
58 typedef void AutolengthProc(void *arg);
59 
61 struct ChunkHandler {
62  uint32 id;
63  ChunkSaveLoadProc *save_proc;
64  ChunkSaveLoadProc *load_proc;
65  ChunkSaveLoadProc *ptrs_proc;
66  ChunkSaveLoadProc *load_check_proc;
67  uint32 flags;
68 };
69 
70 struct NullStruct {
71  byte null;
72 };
73 
75 enum SLRefType {
76  REF_ORDER = 0,
79  REF_TOWN = 3,
88 };
89 
91 #define SL_MAX_VERSION UINT16_MAX
92 
94 enum ChunkType {
95  CH_RIFF = 0,
96  CH_ARRAY = 1,
97  CH_SPARSE_ARRAY = 2,
98  CH_TYPE_MASK = 3,
99  CH_LAST = 8,
100  CH_AUTO_LENGTH = 16,
101 };
102 
111 enum VarTypes {
112  /* 4 bits allocated a maximum of 16 types for NumberType */
113  SLE_FILE_I8 = 0,
114  SLE_FILE_U8 = 1,
115  SLE_FILE_I16 = 2,
116  SLE_FILE_U16 = 3,
117  SLE_FILE_I32 = 4,
118  SLE_FILE_U32 = 5,
119  SLE_FILE_I64 = 6,
120  SLE_FILE_U64 = 7,
122  SLE_FILE_STRING = 9,
123  /* 6 more possible file-primitives */
124 
125  /* 4 bits allocated a maximum of 16 types for NumberType */
126  SLE_VAR_BL = 0 << 4,
127  SLE_VAR_I8 = 1 << 4,
128  SLE_VAR_U8 = 2 << 4,
129  SLE_VAR_I16 = 3 << 4,
130  SLE_VAR_U16 = 4 << 4,
131  SLE_VAR_I32 = 5 << 4,
132  SLE_VAR_U32 = 6 << 4,
133  SLE_VAR_I64 = 7 << 4,
134  SLE_VAR_U64 = 8 << 4,
135  SLE_VAR_NULL = 9 << 4,
136  SLE_VAR_STRB = 10 << 4,
137  SLE_VAR_STRBQ = 11 << 4,
138  SLE_VAR_STR = 12 << 4,
139  SLE_VAR_STRQ = 13 << 4,
140  SLE_VAR_NAME = 14 << 4,
141  /* 1 more possible memory-primitives */
142 
143  /* Shortcut values */
144  SLE_VAR_CHAR = SLE_VAR_I8,
145 
146  /* Default combinations of variables. As savegames change, so can variables
147  * and thus it is possible that the saved value and internal size do not
148  * match and you need to specify custom combo. The defaults are listed here */
149  SLE_BOOL = SLE_FILE_I8 | SLE_VAR_BL,
150  SLE_INT8 = SLE_FILE_I8 | SLE_VAR_I8,
151  SLE_UINT8 = SLE_FILE_U8 | SLE_VAR_U8,
152  SLE_INT16 = SLE_FILE_I16 | SLE_VAR_I16,
153  SLE_UINT16 = SLE_FILE_U16 | SLE_VAR_U16,
154  SLE_INT32 = SLE_FILE_I32 | SLE_VAR_I32,
155  SLE_UINT32 = SLE_FILE_U32 | SLE_VAR_U32,
156  SLE_INT64 = SLE_FILE_I64 | SLE_VAR_I64,
157  SLE_UINT64 = SLE_FILE_U64 | SLE_VAR_U64,
158  SLE_CHAR = SLE_FILE_I8 | SLE_VAR_CHAR,
159  SLE_STRINGID = SLE_FILE_STRINGID | SLE_VAR_U16,
160  SLE_STRINGBUF = SLE_FILE_STRING | SLE_VAR_STRB,
161  SLE_STRINGBQUOTE = SLE_FILE_STRING | SLE_VAR_STRBQ,
162  SLE_STRING = SLE_FILE_STRING | SLE_VAR_STR,
163  SLE_STRINGQUOTE = SLE_FILE_STRING | SLE_VAR_STRQ,
164  SLE_NAME = SLE_FILE_STRINGID | SLE_VAR_NAME,
165 
166  /* Shortcut values */
167  SLE_UINT = SLE_UINT32,
168  SLE_INT = SLE_INT32,
169  SLE_STRB = SLE_STRINGBUF,
170  SLE_STRBQ = SLE_STRINGBQUOTE,
171  SLE_STR = SLE_STRING,
172  SLE_STRQ = SLE_STRINGQUOTE,
173 
174  /* 8 bits allocated for a maximum of 8 flags
175  * Flags directing saving/loading of a variable */
176  SLF_NOT_IN_SAVE = 1 << 8,
177  SLF_NOT_IN_CONFIG = 1 << 9,
179  SLF_ALLOW_CONTROL = 1 << 11,
180  SLF_ALLOW_NEWLINE = 1 << 12,
181  /* 3 more possible flags */
182 };
183 
184 typedef uint32 VarType;
185 
188  SL_VAR = 0,
189  SL_REF = 1,
190  SL_ARR = 2,
191  SL_STR = 3,
192  SL_LST = 4,
193  /* non-normal save-load types */
194  SL_WRITEBYTE = 8,
195  SL_VEH_INCLUDE = 9,
196  SL_ST_INCLUDE = 10,
197  SL_END = 15
198 };
199 
200 typedef byte SaveLoadType;
201 
203 struct SaveLoad {
204  bool global;
206  VarType conv;
207  uint16 length;
208  uint16 version_from;
209  uint16 version_to;
210  /* NOTE: This element either denotes the address of the variable for a global
211  * variable, or the offset within a struct which is then bound to a variable
212  * during runtime. Decision on which one to use is controlled by the function
213  * that is called to save it. address: global=true, offset: global=false */
214  void *address;
215  size_t size;
216 };
217 
220 
231 #define SLE_GENERAL(cmd, base, variable, type, length, from, to) {false, cmd, type, length, from, to, (void*)cpp_offsetof(base, variable), cpp_sizeof(base, variable)}
232 
241 #define SLE_CONDVAR(base, variable, type, from, to) SLE_GENERAL(SL_VAR, base, variable, type, 0, from, to)
242 
251 #define SLE_CONDREF(base, variable, type, from, to) SLE_GENERAL(SL_REF, base, variable, type, 0, from, to)
252 
262 #define SLE_CONDARR(base, variable, type, length, from, to) SLE_GENERAL(SL_ARR, base, variable, type, length, from, to)
263 
273 #define SLE_CONDSTR(base, variable, type, length, from, to) SLE_GENERAL(SL_STR, base, variable, type, length, from, to)
274 
283 #define SLE_CONDLST(base, variable, type, from, to) SLE_GENERAL(SL_LST, base, variable, type, 0, from, to)
284 
291 #define SLE_VAR(base, variable, type) SLE_CONDVAR(base, variable, type, 0, SL_MAX_VERSION)
292 
299 #define SLE_REF(base, variable, type) SLE_CONDREF(base, variable, type, 0, SL_MAX_VERSION)
300 
308 #define SLE_ARR(base, variable, type, length) SLE_CONDARR(base, variable, type, length, 0, SL_MAX_VERSION)
309 
317 #define SLE_STR(base, variable, type, length) SLE_CONDSTR(base, variable, type, length, 0, SL_MAX_VERSION)
318 
325 #define SLE_LST(base, variable, type) SLE_CONDLST(base, variable, type, 0, SL_MAX_VERSION)
326 
331 #define SLE_NULL(length) SLE_CONDNULL(length, 0, SL_MAX_VERSION)
332 
339 #define SLE_CONDNULL(length, from, to) SLE_CONDARR(NullStruct, null, SLE_FILE_U8 | SLE_VAR_NULL | SLF_NOT_IN_CONFIG, length, from, to)
340 
342 #define SLE_WRITEBYTE(base, variable, value) SLE_GENERAL(SL_WRITEBYTE, base, variable, 0, 0, value, value)
343 
344 #define SLE_VEH_INCLUDE() {false, SL_VEH_INCLUDE, 0, 0, 0, SL_MAX_VERSION, NULL, 0}
345 #define SLE_ST_INCLUDE() {false, SL_ST_INCLUDE, 0, 0, 0, SL_MAX_VERSION, NULL, 0}
346 
348 #define SLE_END() {false, SL_END, 0, 0, 0, 0, NULL, 0}
349 
359 #define SLEG_GENERAL(cmd, variable, type, length, from, to) {true, cmd, type, length, from, to, (void*)&variable, sizeof(variable)}
360 
368 #define SLEG_CONDVAR(variable, type, from, to) SLEG_GENERAL(SL_VAR, variable, type, 0, from, to)
369 
377 #define SLEG_CONDREF(variable, type, from, to) SLEG_GENERAL(SL_REF, variable, type, 0, from, to)
378 
387 #define SLEG_CONDARR(variable, type, length, from, to) SLEG_GENERAL(SL_ARR, variable, type, length, from, to)
388 
397 #define SLEG_CONDSTR(variable, type, length, from, to) SLEG_GENERAL(SL_STR, variable, type, length, from, to)
398 
406 #define SLEG_CONDLST(variable, type, from, to) SLEG_GENERAL(SL_LST, variable, type, 0, from, to)
407 
413 #define SLEG_VAR(variable, type) SLEG_CONDVAR(variable, type, 0, SL_MAX_VERSION)
414 
420 #define SLEG_REF(variable, type) SLEG_CONDREF(variable, type, 0, SL_MAX_VERSION)
421 
427 #define SLEG_ARR(variable, type) SLEG_CONDARR(variable, type, lengthof(variable), 0, SL_MAX_VERSION)
428 
434 #define SLEG_STR(variable, type) SLEG_CONDSTR(variable, type, lengthof(variable), 0, SL_MAX_VERSION)
435 
441 #define SLEG_LST(variable, type) SLEG_CONDLST(variable, type, 0, SL_MAX_VERSION)
442 
449 #define SLEG_CONDNULL(length, from, to) {true, SL_ARR, SLE_FILE_U8 | SLE_VAR_NULL | SLF_NOT_IN_CONFIG, length, from, to, (void*)NULL}
450 
452 #define SLEG_END() {true, SL_END, 0, 0, 0, 0, NULL, 0}
453 
460 static inline bool IsSavegameVersionBefore(uint16 major, byte minor = 0)
461 {
462  extern uint16 _sl_version;
463  extern byte _sl_minor_version;
464  return _sl_version < major || (minor > 0 && _sl_version == major && _sl_minor_version < minor);
465 }
466 
474 static inline bool SlIsObjectCurrentlyValid(uint16 version_from, uint16 version_to)
475 {
476  extern const uint16 SAVEGAME_VERSION;
477  if (SAVEGAME_VERSION < version_from || SAVEGAME_VERSION > version_to) return false;
478 
479  return true;
480 }
481 
488 static inline VarType GetVarMemType(VarType type)
489 {
490  return type & 0xF0; // GB(type, 4, 4) << 4;
491 }
492 
499 static inline VarType GetVarFileType(VarType type)
500 {
501  return type & 0xF; // GB(type, 0, 4);
502 }
503 
509 static inline bool IsNumericType(VarType conv)
510 {
511  return GetVarMemType(conv) <= SLE_VAR_U64;
512 }
513 
520 static inline void *GetVariableAddress(const void *object, const SaveLoad *sld)
521 {
522  return const_cast<byte *>((const byte*)(sld->global ? NULL : object) + (ptrdiff_t)sld->address);
523 }
524 
525 int64 ReadValue(const void *ptr, VarType conv);
526 void WriteValue(void *ptr, VarType conv, int64 val);
527 
528 void SlSetArrayIndex(uint index);
529 int SlIterateArray();
530 
531 void SlAutolength(AutolengthProc *proc, void *arg);
532 size_t SlGetFieldLength();
533 void SlSetLength(size_t length);
534 size_t SlCalcObjMemberLength(const void *object, const SaveLoad *sld);
535 size_t SlCalcObjLength(const void *object, const SaveLoad *sld);
536 
537 byte SlReadByte();
538 void SlWriteByte(byte b);
539 
540 void SlGlobList(const SaveLoadGlobVarList *sldg);
541 void SlArray(void *array, size_t length, VarType conv);
542 void SlObject(void *object, const SaveLoad *sld);
543 bool SlObjectMember(void *object, const SaveLoad *sld);
544 void NORETURN SlError(StringID string, const char *extra_msg = NULL);
545 void NORETURN SlErrorCorrupt(const char *msg);
546 
548 
549 extern char _savegame_format[8];
550 extern bool _do_autosave;
551 
552 #endif /* SAVELOAD_H */