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 27653 2016-09-04 16:06:50Z alberth $ */
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 struct FileToSaveLoad {
27 SaveLoadOperation file_op;
28 DetailedFileType detail_ftype;
29 AbstractFileType abstract_ftype;
30 char name[MAX_PATH];
31 char title[255];
32
33 void SetMode(FiosType ft);
34 void SetMode(SaveLoadOperation fop, AbstractFileType aft, DetailedFileType dft);
35 void SetName(const char *name);
36 void SetTitle(const char *title);
37 };
38
40 enum SavegameType {
41 SGT_TTD,
42 SGT_TTDP1,
43 SGT_TTDP2,
44 SGT_OTTD,
45 SGT_TTO,
46 SGT_INVALID = 0xFF,
47 };
48
49 extern FileToSaveLoad _file_to_saveload;
50
51 void GenerateDefaultSaveName(char *buf, const char *last);
52 void SetSaveLoadError(uint16 str);
53 const char *GetSaveLoadErrorString();
54 SaveOrLoadResult SaveOrLoad(const char *filename, SaveLoadOperation fop, DetailedFileType dft, Subdirectory sb, bool threaded = true);
55 void WaitTillSaved();
56 void ProcessAsyncSaveFinish();
57 void DoExitSave();
58
59 SaveOrLoadResult SaveWithFilter(struct SaveFilter *writer, bool threaded);
60 SaveOrLoadResult LoadWithFilter(struct LoadFilter *reader);
61
62 typedef void ChunkSaveLoadProc();
63 typedef void AutolengthProc(void *arg);
64
66 struct ChunkHandler {
67 uint32 id;
68 ChunkSaveLoadProc *save_proc;
69 ChunkSaveLoadProc *load_proc;
70 ChunkSaveLoadProc *ptrs_proc;
71 ChunkSaveLoadProc *load_check_proc;
72 uint32 flags;
73 };
74
75 struct NullStruct {
76 byte null;
77 };
78
80 enum SLRefType {
81 REF_ORDER = 0,
82 REF_VEHICLE = 1,
83 REF_STATION = 2,
84 REF_TOWN = 3,
85 REF_VEHICLE_OLD = 4,
86 REF_ROADSTOPS = 5,
87 REF_ENGINE_RENEWS = 6,
88 REF_CARGO_PACKET = 7,
89 REF_ORDERLIST = 8,
90 REF_STORAGE = 9,
91 REF_LINK_GRAPH = 10,
92 REF_LINK_GRAPH_JOB = 11,
93 };
94
96 #define SL_MAX_VERSION UINT16_MAX
97
99 enum ChunkType {
100 CH_RIFF = 0,
101 CH_ARRAY = 1,
102 CH_SPARSE_ARRAY = 2,
103 CH_TYPE_MASK = 3,
104 CH_LAST = 8,
105 CH_AUTO_LENGTH = 16,
106 };
107
116 enum VarTypes {
117 /* 4 bits allocated a maximum of 16 types for NumberType */
118 SLE_FILE_I8 = 0,
119 SLE_FILE_U8 = 1,
120 SLE_FILE_I16 = 2,
121 SLE_FILE_U16 = 3,
122 SLE_FILE_I32 = 4,
123 SLE_FILE_U32 = 5,
124 SLE_FILE_I64 = 6,
125 SLE_FILE_U64 = 7,
126 SLE_FILE_STRINGID = 8,
127 SLE_FILE_STRING = 9,
128 /* 6 more possible file-primitives */
129
130 /* 4 bits allocated a maximum of 16 types for NumberType */
131 SLE_VAR_BL = 0 << 4,
132 SLE_VAR_I8 = 1 << 4,
133 SLE_VAR_U8 = 2 << 4,
134 SLE_VAR_I16 = 3 << 4,
135 SLE_VAR_U16 = 4 << 4,
136 SLE_VAR_I32 = 5 << 4,
137 SLE_VAR_U32 = 6 << 4,
138 SLE_VAR_I64 = 7 << 4,
139 SLE_VAR_U64 = 8 << 4,
140 SLE_VAR_NULL = 9 << 4,
141 SLE_VAR_STRB = 10 << 4,
142 SLE_VAR_STRBQ = 11 << 4,
143 SLE_VAR_STR = 12 << 4,
144 SLE_VAR_STRQ = 13 << 4,
145 SLE_VAR_NAME = 14 << 4,
146 /* 1 more possible memory-primitives */
147
148 /* Shortcut values */
149 SLE_VAR_CHAR = SLE_VAR_I8,
150
151 /* Default combinations of variables. As savegames change, so can variables
152 * and thus it is possible that the saved value and internal size do not
153 * match and you need to specify custom combo. The defaults are listed here */
154 SLE_BOOL = SLE_FILE_I8 | SLE_VAR_BL,
155 SLE_INT8 = SLE_FILE_I8 | SLE_VAR_I8,
156 SLE_UINT8 = SLE_FILE_U8 | SLE_VAR_U8,
157 SLE_INT16 = SLE_FILE_I16 | SLE_VAR_I16,
158 SLE_UINT16 = SLE_FILE_U16 | SLE_VAR_U16,
159 SLE_INT32 = SLE_FILE_I32 | SLE_VAR_I32,
160 SLE_UINT32 = SLE_FILE_U32 | SLE_VAR_U32,
161 SLE_INT64 = SLE_FILE_I64 | SLE_VAR_I64,
162 SLE_UINT64 = SLE_FILE_U64 | SLE_VAR_U64,
163 SLE_CHAR = SLE_FILE_I8 | SLE_VAR_CHAR,
164 SLE_STRINGID = SLE_FILE_STRINGID | SLE_VAR_U16,
165 SLE_STRINGBUF = SLE_FILE_STRING | SLE_VAR_STRB,
166 SLE_STRINGBQUOTE = SLE_FILE_STRING | SLE_VAR_STRBQ,
167 SLE_STRING = SLE_FILE_STRING | SLE_VAR_STR,
168 SLE_STRINGQUOTE = SLE_FILE_STRING | SLE_VAR_STRQ,
169 SLE_NAME = SLE_FILE_STRINGID | SLE_VAR_NAME,
170
171 /* Shortcut values */
172 SLE_UINT = SLE_UINT32,
173 SLE_INT = SLE_INT32,
174 SLE_STRB = SLE_STRINGBUF,
175 SLE_STRBQ = SLE_STRINGBQUOTE,
176 SLE_STR = SLE_STRING,
177 SLE_STRQ = SLE_STRINGQUOTE,
178
179 /* 8 bits allocated for a maximum of 8 flags
180 * Flags directing saving/loading of a variable */
181 SLF_NOT_IN_SAVE = 1 << 8,
182 SLF_NOT_IN_CONFIG = 1 << 9,
183 SLF_NO_NETWORK_SYNC = 1 << 10,
184 SLF_ALLOW_CONTROL = 1 << 11,
185 SLF_ALLOW_NEWLINE = 1 << 12,
186 /* 3 more possible flags */
187 };
188
189 typedef uint32 VarType;
190
192 enum SaveLoadTypes {
193 SL_VAR = 0,
194 SL_REF = 1,
195 SL_ARR = 2,
196 SL_STR = 3,
197 SL_LST = 4,
198 /* non-normal save-load types */
199 SL_WRITEBYTE = 8,
200 SL_VEH_INCLUDE = 9,
201 SL_ST_INCLUDE = 10,
202 SL_END = 15
203 };
204
205 typedef byte SaveLoadType;
206
208 struct SaveLoad {
209 bool global;
210 SaveLoadType cmd;
211 VarType conv;
212 uint16 length;
213 uint16 version_from;
214 uint16 version_to;
215 /* NOTE: This element either denotes the address of the variable for a global
216 * variable, or the offset within a struct which is then bound to a variable
217 * during runtime. Decision on which one to use is controlled by the function
218 * that is called to save it. address: global=true, offset: global=false */
219 void *address;
220 size_t size;
221 };
222
224 typedef SaveLoad SaveLoadGlobVarList;
225
236 #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)}
237
246 #define SLE_CONDVAR(base, variable, type, from, to) SLE_GENERAL(SL_VAR, base, variable, type, 0, from, to)
247
256 #define SLE_CONDREF(base, variable, type, from, to) SLE_GENERAL(SL_REF, base, variable, type, 0, from, to)
257
267 #define SLE_CONDARR(base, variable, type, length, from, to) SLE_GENERAL(SL_ARR, base, variable, type, length, from, to)
268
278 #define SLE_CONDSTR(base, variable, type, length, from, to) SLE_GENERAL(SL_STR, base, variable, type, length, from, to)
279
288 #define SLE_CONDLST(base, variable, type, from, to) SLE_GENERAL(SL_LST, base, variable, type, 0, from, to)
289
296 #define SLE_VAR(base, variable, type) SLE_CONDVAR(base, variable, type, 0, SL_MAX_VERSION)
297
304 #define SLE_REF(base, variable, type) SLE_CONDREF(base, variable, type, 0, SL_MAX_VERSION)
305
313 #define SLE_ARR(base, variable, type, length) SLE_CONDARR(base, variable, type, length, 0, SL_MAX_VERSION)
314
322 #define SLE_STR(base, variable, type, length) SLE_CONDSTR(base, variable, type, length, 0, SL_MAX_VERSION)
323
330 #define SLE_LST(base, variable, type) SLE_CONDLST(base, variable, type, 0, SL_MAX_VERSION)
331
336 #define SLE_NULL(length) SLE_CONDNULL(length, 0, SL_MAX_VERSION)
337
344 #define SLE_CONDNULL(length, from, to) SLE_CONDARR(NullStruct, null, SLE_FILE_U8 | SLE_VAR_NULL | SLF_NOT_IN_CONFIG, length, from, to)
345
347 #define SLE_WRITEBYTE(base, variable, value) SLE_GENERAL(SL_WRITEBYTE, base, variable, 0, 0, value, value)
348
349 #define SLE_VEH_INCLUDE() {false, SL_VEH_INCLUDE, 0, 0, 0, SL_MAX_VERSION, NULL, 0}
350 #define SLE_ST_INCLUDE() {false, SL_ST_INCLUDE, 0, 0, 0, SL_MAX_VERSION, NULL, 0}
351
353 #define SLE_END() {false, SL_END, 0, 0, 0, 0, NULL, 0}
354
364 #define SLEG_GENERAL(cmd, variable, type, length, from, to) {true, cmd, type, length, from, to, (void*)&variable, sizeof(variable)}
365
373 #define SLEG_CONDVAR(variable, type, from, to) SLEG_GENERAL(SL_VAR, variable, type, 0, from, to)
374
382 #define SLEG_CONDREF(variable, type, from, to) SLEG_GENERAL(SL_REF, variable, type, 0, from, to)
383
392 #define SLEG_CONDARR(variable, type, length, from, to) SLEG_GENERAL(SL_ARR, variable, type, length, from, to)
393
402 #define SLEG_CONDSTR(variable, type, length, from, to) SLEG_GENERAL(SL_STR, variable, type, length, from, to)
403
411 #define SLEG_CONDLST(variable, type, from, to) SLEG_GENERAL(SL_LST, variable, type, 0, from, to)
412
418 #define SLEG_VAR(variable, type) SLEG_CONDVAR(variable, type, 0, SL_MAX_VERSION)
419
425 #define SLEG_REF(variable, type) SLEG_CONDREF(variable, type, 0, SL_MAX_VERSION)
426
432 #define SLEG_ARR(variable, type) SLEG_CONDARR(variable, type, lengthof(variable), 0, SL_MAX_VERSION)
433
439 #define SLEG_STR(variable, type) SLEG_CONDSTR(variable, type, lengthof(variable), 0, SL_MAX_VERSION)
440
446 #define SLEG_LST(variable, type) SLEG_CONDLST(variable, type, 0, SL_MAX_VERSION)
447
454 #define SLEG_CONDNULL(length, from, to) {true, SL_ARR, SLE_FILE_U8 | SLE_VAR_NULL | SLF_NOT_IN_CONFIG, length, from, to, (void*)NULL}
455
457 #define SLEG_END() {true, SL_END, 0, 0, 0, 0, NULL, 0}
458
465 static inline bool IsSavegameVersionBefore(uint16 major, byte minor = 0)
466 {
467 extern uint16 _sl_version;
468 extern byte _sl_minor_version;
469 return _sl_version < major || (minor > 0 && _sl_version == major && _sl_minor_version < minor);
470 }
471
479 static inline bool SlIsObjectCurrentlyValid(uint16 version_from, uint16 version_to)
480 {
481 extern const uint16 SAVEGAME_VERSION;
482 if (SAVEGAME_VERSION < version_from || SAVEGAME_VERSION > version_to) return false;
483
484 return true;
485 }
486
493 static inline VarType GetVarMemType(VarType type)
494 {
495 return type & 0xF0; // GB(type, 4, 4) << 4;
496 }
497
504 static inline VarType GetVarFileType(VarType type)
505 {
506 return type & 0xF; // GB(type, 0, 4);
507 }
508
514 static inline bool IsNumericType(VarType conv)
515 {
516 return GetVarMemType(conv) <= SLE_VAR_U64;
517 }
518
525 static inline void *GetVariableAddress(const void *object, const SaveLoad *sld)
526 {
527 return const_cast<byte *>((const byte*)(sld->global ? NULL : object) + (ptrdiff_t)sld->address);
528 }
529
530 int64 ReadValue(const void *ptr, VarType conv);
531 void WriteValue(void *ptr, VarType conv, int64 val);
532
533 void SlSetArrayIndex(uint index);
534 int SlIterateArray();
535
536 void SlAutolength(AutolengthProc *proc, void *arg);
537 size_t SlGetFieldLength();
538 void SlSetLength(size_t length);
539 size_t SlCalcObjMemberLength(const void *object, const SaveLoad *sld);
540 size_t SlCalcObjLength(const void *object, const SaveLoad *sld);
541
542 byte SlReadByte();
543 void SlWriteByte(byte b);
544
545 void SlGlobList(const SaveLoadGlobVarList *sldg);
546 void SlArray(void *array, size_t length, VarType conv);
547 void SlObject(void *object, const SaveLoad *sld);
548 bool SlObjectMember(void *object, const SaveLoad *sld);
549 void NORETURN SlError(StringID string, const char *extra_msg = NULL);
550 void NORETURN SlErrorCorrupt(const char *msg);
551
552 bool SaveloadCrashWithMissingNewGRFs();
553
554 extern char _savegame_format[8];
555 extern bool _do_autosave;
556
557 #endif /* SAVELOAD_H */