# saveload.h

Go to the documentation of this file.

    00001 /* $Id$ */
    00002
    00003 /*
    00004  * This file is part of OpenTTD.
    00005  * 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.
    00006  * 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.
    00007  * 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/>.
    00008  */
    00009
    00012 #ifndef SAVELOAD_H
    00013 #define SAVELOAD_H
    00014
    00015 #include "../fileio_type.h"
    00016 #include "../strings_type.h"
    00017
    00018 #ifdef SIZE_MAX
    00019 #undef SIZE_MAX
    00020 #endif
    00021
    00022 #define SIZE_MAX ((size_t)-1)
    00023
    00025 enum SaveOrLoadResult {
    00026   SL_OK     = 0,
    00027   SL_ERROR  = 1,
    00028   SL_REINIT = 2,
    00029 };
    00030
    00032 enum SaveOrLoadMode {
    00033   SL_INVALID    = -1,
    00034   SL_LOAD       =  0,
    00035   SL_SAVE       =  1,
    00036   SL_OLD_LOAD   =  2,
    00037   SL_PNG        =  3,
    00038   SL_BMP        =  4,
    00039   SL_LOAD_CHECK =  5,
    00040 };
    00041
    00043 enum SavegameType {
    00044   SGT_TTD,
    00045   SGT_TTDP1,
    00046   SGT_TTDP2,
    00047   SGT_OTTD,
    00048   SGT_TTO,
    00049   SGT_INVALID = 0xFF
    00050 };
    00051
    00052 void GenerateDefaultSaveName(char *buf, const char *last);
    00053 void SetSaveLoadError(uint16 str);
    00054 const char *GetSaveLoadErrorString();
    00055 SaveOrLoadResult SaveOrLoad(const char *filename, int mode, Subdirectory sb, bool threaded = true);
    00056 void WaitTillSaved();
    00057 void ProcessAsyncSaveFinish();
    00058 void DoExitSave();
    00059
    00060 SaveOrLoadResult SaveWithFilter(struct SaveFilter *writer, bool threaded);
    00061 SaveOrLoadResult LoadWithFilter(struct LoadFilter *reader);
    00062
    00063 typedef void ChunkSaveLoadProc();
    00064 typedef void AutolengthProc(void *arg);
    00065
    00067 struct ChunkHandler {
    00068   uint32 id;
    00069   ChunkSaveLoadProc *save_proc;
    00070   ChunkSaveLoadProc *load_proc;
    00071   ChunkSaveLoadProc *ptrs_proc;
    00072   ChunkSaveLoadProc *load_check_proc;
    00073   uint32 flags;
    00074 };
    00075
    00076 struct NullStruct {
    00077   byte null;
    00078 };
    00079
    00081 enum SLRefType {
    00082   REF_ORDER         = 0,
    00083   REF_VEHICLE       = 1,
    00084   REF_STATION       = 2,
    00085   REF_TOWN          = 3,
    00086   REF_VEHICLE_OLD   = 4,
    00087   REF_ROADSTOPS     = 5,
    00088   REF_ENGINE_RENEWS = 6,
    00089   REF_CARGO_PACKET  = 7,
    00090   REF_ORDERLIST     = 8,
    00091 };
    00092
    00096 enum SaveLoadVersions {
    00097   BEFORE_ADDING_PATCHES_SL            = 185,
    00098   BACK_ONE_WAY_SIGNAL_SAFE_WAITING_SL = 186, // Back of one way signals is evil-deadlock.
    00099   TREE_GROWTH_RATE_SL                 = 188, //
    00100   PROG_SIGS_SL                        = 189, // If Then Else signals ...
    00101   DAYLENGHT_SL                        = 190, // Daylenght
    00102   TOWN_CARGO_FACTOR_SL                = 191, // Generated town cargo amount
    00103   SL_RESERVATION                      = 192, // C
    00104   SL_CAPACITIES                       = 193, // A
    00105   SL_COMPONENTS                       = 194, // R
    00106   SL_DEMANDS                          = 195, // G
    00107   SL_MCF                              = 196, // O
    00108   SL_FLOWMAP                          = 197, // D
    00109   SL_CARGOMAP                         = 198, // I
    00110   SL_EXT_RATING                       = 199, // S (for T @see Keep compatible 8 :P )
    00111   TIMESEP_SV                          = 200, // Vehicles seperation
    00112   MORE_HEIGHTLEVEL_SAVEGAME_VERSION   = 201, // High high higher ...
    00113   KEEP_COMPATIBLE_1_SV                = 202, // 147 (with 147 no new chunks are introduced so no need to do the redeclaration trick)
    00114   KEEP_COMPATIBLE_2_SV                = 203, // 148
    00115   KEEP_COMPATIBLE_3_SV                = 204, // 148
    00116   KEEP_COMPATIBLE_4_SV                = 205, // 149
    00117   KEEP_COMPATIBLE_5_SV                = 206, // 150
    00118   KEEP_COMPATIBLE_6_SV                = 206, // MORE_HEIGHTLEVEL_SAVEGAME_VERSION(disaster-vehicle_sl)
    00119   KEEP_COMPATIBLE_7_SV                = 206, // 151
    00120   KEEP_COMPATIBLE_8_SV                = 207, // CargoDist SL_CAPACITIES(last_loading_station)
    00121   INGAME_TREELINE_SV                  = 208, // Fix treeline for old games (and have it configurable ingame at the same time ;) )
    00122   KEEP_COMPATIBLE_9_SV                = 209, // 151 (vehicle_sl-> CONDNULL)
    00123   KEEP_COMPATIBLE_10_SV               = 210, // 152
    00124   KEEP_COMPATIBLE_11_SV               = 210, // 153
    00125   IS_SL                               = 211, // Infrastructure sharing
    00126   EXCLUSIVE_DL_SL                     = 212, // Adjust exclusive counter to daylenght in town_sl.cpp
    00127   KEEP_COMPATIBLE_12_SV               = 213, // 154
    00128   KEEP_COMPATIBLE_13_SV               = 214, // 155
    00129   KEEP_COMPATIBLE_14_SV               = 215, // 156
    00130   KEEP_COMPATIBLE_15_SV               = 216, // 157
    00131   KEEP_COMPATIBLE_16_SV               = 217, // 158
    00132   KEEP_COMPATIBLE_17_SV               = 218, // 159
    00133   KEEP_COMPATIBLE_18_SV               = 219, // 160
    00134   KEEP_COMPATIBLE_19_SV               = 220, // 160
    00135   KEEP_COMPATIBLE_20_SV               = 221, // Save ticks per minute (departure boards)
    00136   SL_IB                               = 222, // Improved breakdowns
    00137   TL_SV                               = 223, // Trafficlights
    00138   TOWN_GROWTH_SV                      = 224, // Town growth needs goods
    00139   DESERT_SV                           = 225, // Amount of desert selectable (not sure if this needs to be saved but it does not hurt ...)
    00140   KEEP_COMPATIBLE_21_SV               = 226, // TOWN_GROWTH_SV -> saving larger towns values
    00141   SPEED_SIGNALS_SV                    = 227, // Speed signals (based on progsigs patch)
    00142   KEEP_COMPATIBLE_22_SV               = 228, // No linkgraph overloading (extension to CargoDist).
    00143   KEEP_COMPATIBLE_23_SV               = 229, // Advanced setting for industrie placement (More Height Levels)
    00144   KEEP_COMPATIBLE_24_SV               = 230, // TL_SV -> Advanced setting for selecting distance between trafficlights in a syncronised consist.
    00145   TREEDRAG_SV                         = 231, // Configurable drag limit for trees.
    00146   INFRA_MAINT_SV                      = 232, // Infrastructure maintenance.
    00147   CHUNNEL_EXIT_SV                     = 233, // Configurable max distance from shores for tunnel exits.
    00148   INFRA_MAINT_FIX_SV                  = 233, // no bump needed here jusk keeping things clear.
    00149
    00151   SL_MAX_VERSION                      = 255
    00152 };
    00153
    00155 enum ChunkType {
    00156   CH_RIFF         =  0,
    00157   CH_ARRAY        =  1,
    00158   CH_SPARSE_ARRAY =  2,
    00159   CH_TYPE_MASK    =  3,
    00160   CH_LAST         =  8,
    00161   CH_AUTO_LENGTH  = 16,
    00162 };
    00163
    00172 enum VarTypes {
    00173   /* 4 bits allocated a maximum of 16 types for NumberType */
    00174   SLE_FILE_I8       = 0,
    00175   SLE_FILE_U8       = 1,
    00176   SLE_FILE_I16      = 2,
    00177   SLE_FILE_U16      = 3,
    00178   SLE_FILE_I32      = 4,
    00179   SLE_FILE_U32      = 5,
    00180   SLE_FILE_I64      = 6,
    00181   SLE_FILE_U64      = 7,
    00182   SLE_FILE_STRINGID = 8,
    00183   SLE_FILE_STRING   = 9,
    00184   /* 6 more possible file-primitives */
    00185
    00186   /* 4 bits allocated a maximum of 16 types for NumberType */
    00187   SLE_VAR_BL    =  0 << 4,
    00188   SLE_VAR_I8    =  1 << 4,
    00189   SLE_VAR_U8    =  2 << 4,
    00190   SLE_VAR_I16   =  3 << 4,
    00191   SLE_VAR_U16   =  4 << 4,
    00192   SLE_VAR_I32   =  5 << 4,
    00193   SLE_VAR_U32   =  6 << 4,
    00194   SLE_VAR_I64   =  7 << 4,
    00195   SLE_VAR_U64   =  8 << 4,
    00196   SLE_VAR_NULL  =  9 << 4,
    00197   SLE_VAR_STRB  = 10 << 4,
    00198   SLE_VAR_STRBQ = 11 << 4,
    00199   SLE_VAR_STR   = 12 << 4,
    00200   SLE_VAR_STRQ  = 13 << 4,
    00201   SLE_VAR_NAME  = 14 << 4,
    00202   /* 1 more possible memory-primitives */
    00203
    00204   /* Shortcut values */
    00205   SLE_VAR_CHAR = SLE_VAR_I8,
    00206
    00207   /* Default combinations of variables. As savegames change, so can variables
    00208    * and thus it is possible that the saved value and internal size do not
    00209    * match and you need to specify custom combo. The defaults are listed here */
    00210   SLE_BOOL         = SLE_FILE_I8  | SLE_VAR_BL,
    00211   SLE_INT8         = SLE_FILE_I8  | SLE_VAR_I8,
    00212   SLE_UINT8        = SLE_FILE_U8  | SLE_VAR_U8,
    00213   SLE_INT16        = SLE_FILE_I16 | SLE_VAR_I16,
    00214   SLE_UINT16       = SLE_FILE_U16 | SLE_VAR_U16,
    00215   SLE_INT32        = SLE_FILE_I32 | SLE_VAR_I32,
    00216   SLE_UINT32       = SLE_FILE_U32 | SLE_VAR_U32,
    00217   SLE_INT64        = SLE_FILE_I64 | SLE_VAR_I64,
    00218   SLE_UINT64       = SLE_FILE_U64 | SLE_VAR_U64,
    00219   SLE_CHAR         = SLE_FILE_I8  | SLE_VAR_CHAR,
    00220   SLE_STRINGID     = SLE_FILE_STRINGID | SLE_VAR_U16,
    00221   SLE_STRINGBUF    = SLE_FILE_STRING   | SLE_VAR_STRB,
    00222   SLE_STRINGBQUOTE = SLE_FILE_STRING   | SLE_VAR_STRBQ,
    00223   SLE_STRING       = SLE_FILE_STRING   | SLE_VAR_STR,
    00224   SLE_STRINGQUOTE  = SLE_FILE_STRING   | SLE_VAR_STRQ,
    00225   SLE_NAME         = SLE_FILE_STRINGID | SLE_VAR_NAME,
    00226
    00227   /* Shortcut values */
    00228   SLE_UINT  = SLE_UINT32,
    00229   SLE_INT   = SLE_INT32,
    00230   SLE_STRB  = SLE_STRINGBUF,
    00231   SLE_STRBQ = SLE_STRINGBQUOTE,
    00232   SLE_STR   = SLE_STRING,
    00233   SLE_STRQ  = SLE_STRINGQUOTE,
    00234
    00235   /* 8 bits allocated for a maximum of 8 flags
    00236    * Flags directing saving/loading of a variable */
    00237   SLF_NOT_IN_SAVE     = 1 <<  8,
    00238   SLF_NOT_IN_CONFIG   = 1 <<  9,
    00239   SLF_NO_NETWORK_SYNC = 1 << 10,
    00240   /* 5 more possible flags */
    00241 };
    00242
    00243 typedef uint32 VarType;
    00244
    00246 enum SaveLoadTypes {
    00247   SL_VAR         =  0,
    00248   SL_REF         =  1,
    00249   SL_ARR         =  2,
    00250   SL_STR         =  3,
    00251   SL_LST         =  4,
    00252   /* non-normal save-load types */
    00253   SL_WRITEBYTE   =  8,
    00254   SL_VEH_INCLUDE =  9,
    00255   SL_ST_INCLUDE  = 10,
    00256   SL_END         = 15
    00257 };
    00258
    00259 typedef byte SaveLoadType;
    00260
    00262 struct SaveLoad {
    00263   bool global;
    00264   SaveLoadType cmd;
    00265   VarType conv;
    00266   uint16 length;
    00267   uint16 version_from;
    00268   uint16 version_to;
    00269   /* NOTE: This element either denotes the address of the variable for a global
    00270    * variable, or the offset within a struct which is then bound to a variable
    00271    * during runtime. Decision on which one to use is controlled by the function
    00272    * that is called to save it. address: global=true, offset: global=false */
    00273   void *address;
    00274 };
    00275
    00277 typedef SaveLoad SaveLoadGlobVarList;
    00278
    00289 #define SLE_GENERAL(cmd, base, variable, type, length, from, to) {false, cmd, type, length, from, to, (void*)cpp_offsetof(base, variable)}
    00290
    00299 #define SLE_CONDVAR(base, variable, type, from, to) SLE_GENERAL(SL_VAR, base, variable, type, 0, from, to)
    00300
    00309 #define SLE_CONDREF(base, variable, type, from, to) SLE_GENERAL(SL_REF, base, variable, type, 0, from, to)
    00310
    00320 #define SLE_CONDARR(base, variable, type, length, from, to) SLE_GENERAL(SL_ARR, base, variable, type, length, from, to)
    00321
    00331 #define SLE_CONDSTR(base, variable, type, length, from, to) SLE_GENERAL(SL_STR, base, variable, type, length, from, to)
    00332
    00341 #define SLE_CONDLST(base, variable, type, from, to) SLE_GENERAL(SL_LST, base, variable, type, 0, from, to)
    00342
    00349 #define SLE_VAR(base, variable, type) SLE_CONDVAR(base, variable, type, 0, SL_MAX_VERSION)
    00350
    00357 #define SLE_REF(base, variable, type) SLE_CONDREF(base, variable, type, 0, SL_MAX_VERSION)
    00358
    00366 #define SLE_ARR(base, variable, type, length) SLE_CONDARR(base, variable, type, length, 0, SL_MAX_VERSION)
    00367
    00375 #define SLE_STR(base, variable, type, length) SLE_CONDSTR(base, variable, type, length, 0, SL_MAX_VERSION)
    00376
    00383 #define SLE_LST(base, variable, type) SLE_CONDLST(base, variable, type, 0, SL_MAX_VERSION)
    00384
    00389 #define SLE_NULL(length) SLE_CONDNULL(length, 0, SL_MAX_VERSION)
    00390
    00397 #define SLE_CONDNULL(length, from, to) SLE_CONDARR(NullStruct, null, SLE_FILE_U8 | SLE_VAR_NULL | SLF_NOT_IN_CONFIG, length, from, to)
    00398
    00400 #define SLE_WRITEBYTE(base, variable, value) SLE_GENERAL(SL_WRITEBYTE, base, variable, 0, 0, value, value)
    00401
    00402 #define SLE_VEH_INCLUDE() {false, SL_VEH_INCLUDE, 0, 0, 0, SL_MAX_VERSION, NULL}
    00403 #define SLE_ST_INCLUDE() {false, SL_ST_INCLUDE, 0, 0, 0, SL_MAX_VERSION, NULL}
    00404
    00406 #define SLE_END() {false, SL_END, 0, 0, 0, 0, NULL}
    00407
    00417 #define SLEG_GENERAL(cmd, variable, type, length, from, to) {true, cmd, type, length, from, to, (void*)&variable}
    00418
    00426 #define SLEG_CONDVAR(variable, type, from, to) SLEG_GENERAL(SL_VAR, variable, type, 0, from, to)
    00427
    00435 #define SLEG_CONDREF(variable, type, from, to) SLEG_GENERAL(SL_REF, variable, type, 0, from, to)
    00436
    00445 #define SLEG_CONDARR(variable, type, length, from, to) SLEG_GENERAL(SL_ARR, variable, type, length, from, to)
    00446
    00455 #define SLEG_CONDSTR(variable, type, length, from, to) SLEG_GENERAL(SL_STR, variable, type, length, from, to)
    00456
    00464 #define SLEG_CONDLST(variable, type, from, to) SLEG_GENERAL(SL_LST, variable, type, 0, from, to)
    00465
    00471 #define SLEG_VAR(variable, type) SLEG_CONDVAR(variable, type, 0, SL_MAX_VERSION)
    00472
    00478 #define SLEG_REF(variable, type) SLEG_CONDREF(variable, type, 0, SL_MAX_VERSION)
    00479
    00485 #define SLEG_ARR(variable, type) SLEG_CONDARR(variable, type, lengthof(variable), 0, SL_MAX_VERSION)
    00486
    00492 #define SLEG_STR(variable, type) SLEG_CONDSTR(variable, type, lengthof(variable), 0, SL_MAX_VERSION)
    00493
    00499 #define SLEG_LST(variable, type) SLEG_CONDLST(variable, type, 0, SL_MAX_VERSION)
    00500
    00507 #define SLEG_CONDNULL(length, from, to) {true, SL_ARR, SLE_FILE_U8 | SLE_VAR_NULL | SLF_NOT_IN_CONFIG, length, from, to, (void*)NULL}
    00508
    00510 #define SLEG_END() {true, SL_END, 0, 0, 0, 0, NULL}
    00511
    00518 static inline bool IsSavegameVersionBefore(uint16 major, byte minor = 0)
    00519 {
    00520   extern uint16 _sl_version;
    00521   extern byte   _sl_minor_version;
    00522   return _sl_version < major || (minor > 0 && _sl_version == major && _sl_minor_version < minor);
    00523 }
    00524
    00532 static inline bool SlIsObjectCurrentlyValid(uint16 version_from, uint16 version_to)
    00533 {
    00534   extern const uint16 SAVEGAME_VERSION;
    00535   if (SAVEGAME_VERSION < version_from || SAVEGAME_VERSION > version_to) return false;
    00536
    00537   return true;
    00538 }
    00539
    00546 static inline VarType GetVarMemType(VarType type)
    00547 {
    00548   return type & 0xF0; // GB(type, 4, 4) << 4;
    00549 }
    00550
    00557 static inline VarType GetVarFileType(VarType type)
    00558 {
    00559   return type & 0xF; // GB(type, 0, 4);
    00560 }
    00561
    00567 static inline bool IsNumericType(VarType conv)
    00568 {
    00569   return GetVarMemType(conv) <= SLE_VAR_U64;
    00570 }
    00571
    00578 static inline void *GetVariableAddress(const void *object, const SaveLoad *sld)
    00579 {
    00580   return (byte*)(sld->global ? NULL : object) + (ptrdiff_t)sld->address;
    00581 }
    00582
    00583 int64 ReadValue(const void *ptr, VarType conv);
    00584 void WriteValue(void *ptr, VarType conv, int64 val);
    00585
    00586 void SlSetArrayIndex(uint index);
    00587 int SlIterateArray();
    00588
    00589 void SlAutolength(AutolengthProc *proc, void *arg);
    00590 size_t SlGetFieldLength();
    00591 void SlSetLength(size_t length);
    00592 size_t SlCalcObjMemberLength(const void *object, const SaveLoad *sld);
    00593 size_t SlCalcObjLength(const void *object, const SaveLoad *sld);
    00594
    00595 byte SlReadByte();
    00596 void SlWriteByte(byte b);
    00597
    00598 void SlGlobList(const SaveLoadGlobVarList *sldg);
    00599 void SlArray(void *array, size_t length, VarType conv);
    00600 void SlObject(void *object, const SaveLoad *sld);
    00601 bool SlObjectMember(void *object, const SaveLoad *sld);
    00602 void NORETURN SlError(StringID string, const char *extra_msg = NULL);
    00603 void NORETURN SlErrorCorrupt(const char *msg);
    00604
    00605 bool SaveloadCrashWithMissingNewGRFs();
    00606
    00607 extern char _savegame_format[8];
    00608 extern bool _do_autosave;
    00609
    00610 #endif /* SAVELOAD_H */