OpenTTD

- Main Page
- Related Pages
- Modules
- Namespaces
- Data Structures
- Files

- File List
- Globals

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
19 enum SaveOrLoadResult {
20 SL_OK = 0,
21 SL_ERROR = 1,
22 SL_REINIT = 2,
23 };
24
26 enum SaveOrLoadMode {
27 SL_INVALID = -1,
28 SL_LOAD = 0,
29 SL_SAVE = 1,
30 SL_OLD_LOAD = 2,
31 SL_PNG = 3,
32 SL_BMP = 4,
33 SL_LOAD_CHECK = 5,
34 };
35
37 enum SavegameType {
38 SGT_TTD,
39 SGT_TTDP1,
40 SGT_TTDP2,
41 SGT_OTTD,
42 SGT_TTO,
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();
51 void ProcessAsyncSaveFinish();
52 void DoExitSave();
53
54 SaveOrLoadResult SaveWithFilter(struct SaveFilter *writer, bool threaded);
55 SaveOrLoadResult LoadWithFilter(struct LoadFilter *reader);
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,
77 REF_VEHICLE = 1,
78 REF_STATION = 2,
79 REF_TOWN = 3,
80 REF_VEHICLE_OLD = 4,
81 REF_ROADSTOPS = 5,
82 REF_ENGINE_RENEWS = 6,
83 REF_CARGO_PACKET = 7,
84 REF_ORDERLIST = 8,
85 REF_STORAGE = 9,
86 REF_LINK_GRAPH = 10,
87 REF_LINK_GRAPH_JOB = 11,
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,
121 SLE_FILE_STRINGID = 8,
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,
178 SLF_NO_NETWORK_SYNC = 1 << 10,
179 SLF_ALLOW_CONTROL = 1 << 11,
180 SLF_ALLOW_NEWLINE = 1 << 12,
181 /* 3 more possible flags */
182 };
183
184 typedef uint32 VarType;
185
187 enum SaveLoadTypes {
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;
205 SaveLoadType cmd;
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
219 typedef SaveLoad SaveLoadGlobVarList;
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
547 bool SaveloadCrashWithMissingNewGRFs();
548
549 extern char _savegame_format[8];
550 extern bool _do_autosave;
551
552 #endif /* SAVELOAD_H */