diff --git a/source.list b/source.list index df35cdd26e..62b1dd3f43 100644 --- a/source.list +++ b/source.list @@ -633,6 +633,8 @@ saveload/subsidy_sl.cpp saveload/town_sl.cpp saveload/vehicle_sl.cpp saveload/waypoint_sl.cpp +saveload/extended_ver_sl.h +saveload/extended_ver_sl.cpp # Tables table/airport_defaults.h diff --git a/src/saveload/extended_ver_sl.cpp b/src/saveload/extended_ver_sl.cpp new file mode 100644 index 0000000000..143167d6ed --- /dev/null +++ b/src/saveload/extended_ver_sl.cpp @@ -0,0 +1,105 @@ +/* $Id$ */ + +/* + * This file is part of OpenTTD. + * 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. + * 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. + * 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 . + */ + +/** @file extended_ver_sl.cpp Functions related to handling save/load extended version info. */ + +#include "../stdafx.h" +#include "../debug.h" +#include "extended_ver_sl.h" + +#include "../safeguards.h" + +uint16 _sl_xv_feature_versions[XSLFI_SIZE]; ///< array of all known feature types and their current versions +std::vector _sl_xv_discardable_chunk_ids; ///< list of chunks IDs which we can discard if no chunk loader exists + +/** + * Extended save/load feature test + * + * First performs a tradional check on the provided @p savegame_version against @p savegame_version_from and @p savegame_version_to. + * Then, if the feature set in the constructor is not XSLFI_NULL, also check than the feature version is inclusively bounded by @p min_version and @p max_version, + * and return the combination of the two tests using the operator defined in the constructor. + * Otherwise just returns the result of the savegame version test + */ +bool ExtendedSaveLoadFeatureTest::IsFeaturePresent(uint16 savegame_version, uint16 savegame_version_from, uint16 savegame_version_to) const +{ + bool savegame_version_ok = savegame_version >= savegame_version_from && savegame_version <= savegame_version_to; + + ExtendedSaveLoadFeatureIndex feature = static_cast(GB(this->value, 0, 16)); + if (feature == XSLFI_NULL) return savegame_version_ok; + + uint16 min_version = GB(this->value, 16, 16); + uint16 max_version = GB(this->value, 32, 16); + ExtendedSaveLoadFeatureTestOperator op = static_cast(GB(this->value, 48, 16)); + bool feature_ok = SlXvIsFeaturePresent(feature, min_version, max_version); + + switch (op) { + case XSLFTO_OR: + return savegame_version_ok || feature_ok; + + case XSLFTO_AND: + return savegame_version_ok && feature_ok; + + default: + NOT_REACHED(); + return false; + } +} + +/** + * Returns true if @p feature is present and has a version inclusively bounded by @p min_version and @p max_version + */ +bool SlXvIsFeaturePresent(ExtendedSaveLoadFeatureIndex feature, uint16 min_version, uint16 max_version) +{ + assert(feature < XSLFI_SIZE); + return _sl_xv_feature_versions[feature] >= min_version && _sl_xv_feature_versions[feature] <= max_version; +} + +/** + * Resets all extended feature versions to 0 + */ +void SlXvResetState() +{ + memset(_sl_xv_feature_versions, 0, sizeof(_sl_xv_feature_versions)); +} + +/** + * Resets all extended feature versions to their currently enabled versions, i.e. versions suitable for saving + */ +void SlXvSetCurrentState() +{ + extern bool _sl_is_ext_version; + + SlXvResetState(); + _sl_is_ext_version = true; + + // TODO: set versions for currently enabled features here +} + +/** + * Check for "special" savegame versions (i.e. known patchpacks) and set correct savegame version, settings, etc. + */ +void SlXvCheckSpecialSavegameVersions() +{ + extern uint16 _sl_version; + + // TODO: check for savegame versions +} + +/** + * Return true if this chunk has been marked as discardable + */ +bool SlXvIsChunkDiscardable(uint32 id) +{ + for(size_t i = 0; i < _sl_xv_discardable_chunk_ids.size(); i++) { + if (_sl_xv_discardable_chunk_ids[i] == id) { + return true; + } + } + return false; +} diff --git a/src/saveload/extended_ver_sl.h b/src/saveload/extended_ver_sl.h new file mode 100644 index 0000000000..96b0feddec --- /dev/null +++ b/src/saveload/extended_ver_sl.h @@ -0,0 +1,79 @@ +/* $Id$ */ + +/* + * This file is part of OpenTTD. + * 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. + * 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. + * 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 . + */ + +/** @file extended_ver_sl.h Functions/types related to handling save/load extended version info. */ + +#ifndef EXTENDED_VER_SL_H +#define EXTENDED_VER_SL_H + +#include "../core/bitmath_func.hpp" + +#include + +/** + * List of extended features, each feature has its own (16 bit) version + */ +enum ExtendedSaveLoadFeatureIndex { + XSLFI_NULL = 0, ///< Unused value, to indicate that no extended feature test is in use + + XSLFI_SIZE, ///< Total count of features, including null feature +}; + +extern uint16 _sl_xv_feature_versions[XSLFI_SIZE]; + +/** + * Operator to use when combining traditional savegame number test with an extended feature version test + */ +enum ExtendedSaveLoadFeatureTestOperator { + XSLFTO_OR = 0, ///< Test if traditional savegame version is in bounds OR extended feature is in version bounds + XSLFTO_AND ///< Test if traditional savegame version is in bounds AND extended feature is in version bounds +}; + +/** + * Structure to describe an extended feature version test, and how it combines with a traditional savegame version test + */ +struct ExtendedSaveLoadFeatureTest { + private: + uint64 value; + + public: + ExtendedSaveLoadFeatureTest() + : value(0) { } + + ExtendedSaveLoadFeatureTest(ExtendedSaveLoadFeatureTestOperator op, ExtendedSaveLoadFeatureIndex feature, uint16 min_version = 1, uint16 max_version = 0xFFFF) + { + this->value = 0; + SB(this->value, 0, 16, feature); + SB(this->value, 16, 16, min_version); + SB(this->value, 32, 16, max_version); + SB(this->value, 48, 16, op); + } + + bool IsFeaturePresent(uint16 savegame_version, uint16 savegame_version_from, uint16 savegame_version_to) const; +}; + +bool SlXvIsFeaturePresent(ExtendedSaveLoadFeatureIndex feature, uint16 min_version = 1, uint16 max_version = 0xFFFF); + +/** + * Returns true if @p feature is missing (i.e. has a version of 0) + */ +inline bool SlXvIsFeatureMissing(ExtendedSaveLoadFeatureIndex feature) +{ + return !SlXvIsFeaturePresent(feature); +} + +void SlXvResetState(); + +void SlXvSetCurrentState(); + +void SlXvCheckSpecialSavegameVersions(); + +bool SlXvIsChunkDiscardable(uint32 id); + +#endif /* EXTENDED_VER_SL_H */ diff --git a/src/saveload/saveload.cpp b/src/saveload/saveload.cpp index bd3c83d139..06836855da 100644 --- a/src/saveload/saveload.cpp +++ b/src/saveload/saveload.cpp @@ -48,9 +48,12 @@ #include "saveload_internal.h" #include "saveload_filter.h" +#include "extended_ver_sl.h" #include "../safeguards.h" +#include + /* * Previous savegame versions, the trunk revision where they were * introduced and the released version that had that particular @@ -264,12 +267,14 @@ * 194 26881 1.5.x */ extern const uint16 SAVEGAME_VERSION = 194; ///< Current savegame version of OpenTTD. +const uint16 SAVEGAME_VERSION_EXT = 0x8000; ///< Savegame extension indicator mask SavegameType _savegame_type; ///< type of savegame we are loading uint32 _ttdp_version; ///< version of TTDP savegame (if applicable) uint16 _sl_version; ///< the major savegame version identifier byte _sl_minor_version; ///< the minor savegame version, DO NOT USE! +bool _sl_is_ext_version; ///< is this an extended savegame version, with more info in the SLXI chunk? char _savegame_format[8]; ///< how to compress savegames bool _do_autosave; ///< are we doing an autosave at the moment? @@ -414,6 +419,7 @@ struct SaveLoadParams { static SaveLoadParams _sl; ///< Parameters used for/at saveload. /* these define the chunks */ +//extern const ChunkHandler _version_ext_chunk_handlers[]; extern const ChunkHandler _gamelog_chunk_handlers[]; extern const ChunkHandler _map_chunk_handlers[]; extern const ChunkHandler _misc_chunk_handlers[]; @@ -450,6 +456,7 @@ extern const ChunkHandler _persistent_storage_chunk_handlers[]; /** Array of all chunks in a savegame, \c NULL terminated. */ static const ChunkHandler * const _chunk_handlers[] = { +// _version_ext_chunk_handlers, // this should be first, such that it is saved first, as when loading it affects the loading of subsequent chunks _gamelog_chunk_handlers, _map_chunk_handlers, _misc_chunk_handlers, @@ -503,6 +510,7 @@ static void SlNullPointers() * during NULLing; especially those that try to get * pointers from other pools. */ _sl_version = SAVEGAME_VERSION; + SlXvSetCurrentState(); DEBUG(sl, 1, "Nulling pointers"); @@ -1414,7 +1422,7 @@ static void SlList(void *list, SLRefType conv) /** Are we going to save this object or not? */ static inline bool SlIsObjectValidInSavegame(const SaveLoad *sld) { - if (_sl_version < sld->version_from || _sl_version > sld->version_to) return false; + if (!sld->ext_feature_test.IsFeaturePresent(_sl_version, sld->version_from, sld->version_to)) return false; if (sld->conv & SLF_NOT_IN_SAVE) return false; return true; @@ -1692,7 +1700,7 @@ static void SlLoadChunk(const ChunkHandler *ch) /** * Load a chunk of data for checking savegames. * If the chunkhandler is NULL, the chunk is skipped. - * @param ch The chunkhandler that will be used for the operation + * @param ch The chunkhandler that will be used for the operation, this may be NULL */ static void SlLoadCheckChunk(const ChunkHandler *ch) { @@ -1706,14 +1714,14 @@ static void SlLoadCheckChunk(const ChunkHandler *ch) switch (m) { case CH_ARRAY: _sl.array_index = 0; - if (ch->load_check_proc) { + if (ch && ch->load_check_proc) { ch->load_check_proc(); } else { SlSkipArray(); } break; case CH_SPARSE_ARRAY: - if (ch->load_check_proc) { + if (ch && ch->load_check_proc) { ch->load_check_proc(); } else { SlSkipArray(); @@ -1726,7 +1734,7 @@ static void SlLoadCheckChunk(const ChunkHandler *ch) len += SlReadUint16(); _sl.obj_len = len; endoffs = _sl.reader->GetSize() + len; - if (ch->load_check_proc) { + if (ch && ch->load_check_proc) { ch->load_check_proc(); } else { SlSkipBytes(len); @@ -1840,8 +1848,16 @@ static void SlLoadChunks() DEBUG(sl, 2, "Loading chunk %c%c%c%c", id >> 24, id >> 16, id >> 8, id); ch = SlFindChunkHandler(id); - if (ch == NULL) SlErrorCorrupt("Unknown chunk type"); - SlLoadChunk(ch); + if (ch == NULL) { + if (SlXvIsChunkDiscardable(id)) { + DEBUG(sl, 1, "Discarding chunk %c%c%c%c", id >> 24, id >> 16, id >> 8, id); + SlLoadCheckChunk(NULL); + } else { + SlErrorCorrupt("Unknown chunk type"); + } + } else { + SlLoadChunk(ch); + } } } @@ -1855,7 +1871,7 @@ static void SlLoadCheckChunks() DEBUG(sl, 2, "Loading chunk %c%c%c%c", id >> 24, id >> 16, id >> 8, id); ch = SlFindChunkHandler(id); - if (ch == NULL) SlErrorCorrupt("Unknown chunk type"); + if (ch == NULL && !SlXvIsChunkDiscardable(id)) SlErrorCorrupt("Unknown chunk type"); SlLoadCheckChunk(ch); } } @@ -2511,7 +2527,7 @@ static SaveOrLoadResult SaveFileToDisk(bool threaded) const SaveLoadFormat *fmt = GetSavegameFormat(_savegame_format, &compression); /* We have written our stuff to memory, now write it to file! */ - uint32 hdr[2] = { fmt->tag, TO_BE32(SAVEGAME_VERSION << 16) }; + uint32 hdr[2] = { fmt->tag, TO_BE32((SAVEGAME_VERSION | SAVEGAME_VERSION_EXT) << 16) }; _sl.sf->Write((byte*)hdr, sizeof(hdr)); _sl.sf = fmt->init_write(_sl.sf, compression); @@ -2578,6 +2594,7 @@ static SaveOrLoadResult DoSave(SaveFilter *writer, bool threaded) _sl.sf = writer; _sl_version = SAVEGAME_VERSION; + SlXvSetCurrentState(); SaveViewportBeforeSaveGame(); SlSaveChunks(); @@ -2629,6 +2646,8 @@ static SaveOrLoadResult DoLoad(LoadFilter *reader, bool load_check) _load_check_data.checkable = true; } + SlXvResetState(); + uint32 hdr[2]; if (_sl.lf->Read((byte*)hdr, sizeof(hdr)) != sizeof(hdr)) SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE); @@ -2641,6 +2660,8 @@ static SaveOrLoadResult DoLoad(LoadFilter *reader, bool load_check) _sl.lf->Reset(); _sl_version = 0; _sl_minor_version = 0; + _sl_is_ext_version = false; + SlXvResetState(); /* Try to find the LZO savegame format; it uses 'OTTD' as tag. */ fmt = _saveload_formats; @@ -2663,7 +2684,14 @@ static SaveOrLoadResult DoLoad(LoadFilter *reader, bool load_check) * Therefore it is loaded, but never saved (or, it saves a 0 in any scenario). */ _sl_minor_version = (TO_BE32(hdr[1]) >> 8) & 0xFF; - DEBUG(sl, 1, "Loading savegame version %d", _sl_version); + if (_sl_version & SAVEGAME_VERSION_EXT) { + _sl_version &= ~SAVEGAME_VERSION_EXT; + _sl_is_ext_version = true; + } else { + SlXvCheckSpecialSavegameVersions(); + } + + DEBUG(sl, 1, "Loading savegame version %d%s", _sl_version, _sl_is_ext_version ? " (extended)" : ""); /* Is the version higher than the current? */ if (_sl_version > SAVEGAME_VERSION) SlError(STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME); @@ -2800,6 +2828,8 @@ SaveOrLoadResult SaveOrLoad(const char *filename, int mode, Subdirectory sb, boo if (!LoadOldSaveGame(filename)) return SL_REINIT; _sl_version = 0; _sl_minor_version = 0; + _sl_is_ext_version = false; + SlXvResetState(); GamelogStartAction(GLAT_LOAD); if (!AfterLoadGame()) { GamelogStopAction(); diff --git a/src/saveload/saveload.h b/src/saveload/saveload.h index 72c51fa69d..230203b4e7 100644 --- a/src/saveload/saveload.h +++ b/src/saveload/saveload.h @@ -14,6 +14,7 @@ #include "../fileio_type.h" #include "../strings_type.h" +#include "extended_ver_sl.h" /** Save or load result codes. */ enum SaveOrLoadResult { @@ -213,6 +214,7 @@ struct SaveLoad { * that is called to save it. address: global=true, offset: global=false */ void *address; ///< address of variable OR offset of variable in the struct (max offset is 65536) size_t size; ///< the sizeof size. + ExtendedSaveLoadFeatureTest ext_feature_test; ///< extended feature test }; /** Same as #SaveLoad but global variables are used (for better readability); */ @@ -226,9 +228,11 @@ typedef SaveLoad SaveLoadGlobVarList; * @param type Storage of the data in memory and in the savegame. * @param from First savegame version that has the field. * @param to Last savegame version that has the field. + * @param extver ExtendedSaveLoadFeatureTest to test (along with from and to) which savegames have the field * @note In general, it is better to use one of the SLE_* macros below. */ -#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)} +#define SLE_GENERAL_X(cmd, base, variable, type, length, from, to, extver) {false, cmd, type, length, from, to, (void*)cpp_offsetof(base, variable), cpp_sizeof(base, variable), extver} +#define SLE_GENERAL(cmd, base, variable, type, length, from, to) SLE_GENERAL_X(cmd, base, variable, type, length, from, to, {}) /** * Storage of a variable in some savegame versions. @@ -237,8 +241,10 @@ typedef SaveLoad SaveLoadGlobVarList; * @param type Storage of the data in memory and in the savegame. * @param from First savegame version that has the field. * @param to Last savegame version that has the field. + * @param extver ExtendedSaveLoadFeatureTest to test (along with from and to) which savegames have the field */ -#define SLE_CONDVAR(base, variable, type, from, to) SLE_GENERAL(SL_VAR, base, variable, type, 0, from, to) +#define SLE_CONDVAR_X(base, variable, type, from, to, extver) SLE_GENERAL_X(SL_VAR, base, variable, type, 0, from, to, extver) +#define SLE_CONDVAR(base, variable, type, from, to) SLE_CONDVAR_X(base, variable, type, from, to, {}) /** * Storage of a reference in some savegame versions. @@ -247,8 +253,10 @@ typedef SaveLoad SaveLoadGlobVarList; * @param type Type of the reference, a value from #SLRefType. * @param from First savegame version that has the field. * @param to Last savegame version that has the field. + * @param extver ExtendedSaveLoadFeatureTest to test (along with from and to) which savegames have the field */ -#define SLE_CONDREF(base, variable, type, from, to) SLE_GENERAL(SL_REF, base, variable, type, 0, from, to) +#define SLE_CONDREF_X(base, variable, type, from, to, extver) SLE_GENERAL_X(SL_REF, base, variable, type, 0, from, to, extver) +#define SLE_CONDREF(base, variable, type, from, to) SLE_CONDREF_X(base, variable, type, from, to, {}) /** * Storage of an array in some savegame versions. @@ -258,8 +266,10 @@ typedef SaveLoad SaveLoadGlobVarList; * @param length Number of elements in the array. * @param from First savegame version that has the array. * @param to Last savegame version that has the array. + * @param extver ExtendedSaveLoadFeatureTest to test (along with from and to) which savegames have the field */ -#define SLE_CONDARR(base, variable, type, length, from, to) SLE_GENERAL(SL_ARR, base, variable, type, length, from, to) +#define SLE_CONDARR_X(base, variable, type, length, from, to, extver) SLE_GENERAL_X(SL_ARR, base, variable, type, length, from, to, extver) +#define SLE_CONDARR(base, variable, type, length, from, to) SLE_CONDARR_X(base, variable, type, length, from, to, {}) /** * Storage of a string in some savegame versions. @@ -269,8 +279,10 @@ typedef SaveLoad SaveLoadGlobVarList; * @param length Number of elements in the string (only used for fixed size buffers). * @param from First savegame version that has the string. * @param to Last savegame version that has the string. + * @param extver ExtendedSaveLoadFeatureTest to test (along with from and to) which savegames have the field */ -#define SLE_CONDSTR(base, variable, type, length, from, to) SLE_GENERAL(SL_STR, base, variable, type, length, from, to) +#define SLE_CONDSTR_X(base, variable, type, length, from, to, extver) SLE_GENERAL_X(SL_STR, base, variable, type, length, from, to, extver) +#define SLE_CONDSTR(base, variable, type, length, from, to) SLE_CONDSTR_X(base, variable, type, length, from, to, {}) /** * Storage of a list in some savegame versions. @@ -279,8 +291,10 @@ typedef SaveLoad SaveLoadGlobVarList; * @param type Storage of the data in memory and in the savegame. * @param from First savegame version that has the list. * @param to Last savegame version that has the list. + * @param extver ExtendedSaveLoadFeatureTest to test (along with from and to) which savegames have the field */ -#define SLE_CONDLST(base, variable, type, from, to) SLE_GENERAL(SL_LST, base, variable, type, 0, from, to) +#define SLE_CONDLST_X(base, variable, type, from, to, extver) SLE_GENERAL_X(SL_LST, base, variable, type, 0, from, to, extver) +#define SLE_CONDLST(base, variable, type, from, to) SLE_CONDLST_X(base, variable, type, from, to, {}) /** * Storage of a variable in every version of a savegame. @@ -335,17 +349,19 @@ typedef SaveLoad SaveLoadGlobVarList; * @param length Length of the empty space. * @param from First savegame version that has the empty space. * @param to Last savegame version that has the empty space. + * @param extver ExtendedSaveLoadFeatureTest to test (along with from and to) which savegames have empty space */ -#define SLE_CONDNULL(length, from, to) SLE_CONDARR(NullStruct, null, SLE_FILE_U8 | SLE_VAR_NULL | SLF_NOT_IN_CONFIG, length, from, to) +#define SLE_CONDNULL_X(length, from, to, extver) SLE_CONDARR_X(NullStruct, null, SLE_FILE_U8 | SLE_VAR_NULL | SLF_NOT_IN_CONFIG, length, from, to, extver) +#define SLE_CONDNULL(length, from, to) SLE_CONDNULL_X(length, from, to, {}) /** Translate values ingame to different values in the savegame and vv. */ #define SLE_WRITEBYTE(base, variable, value) SLE_GENERAL(SL_WRITEBYTE, base, variable, 0, 0, value, value) -#define SLE_VEH_INCLUDE() {false, SL_VEH_INCLUDE, 0, 0, 0, SL_MAX_VERSION, NULL, 0} -#define SLE_ST_INCLUDE() {false, SL_ST_INCLUDE, 0, 0, 0, SL_MAX_VERSION, NULL, 0} +#define SLE_VEH_INCLUDE() {false, SL_VEH_INCLUDE, 0, 0, 0, SL_MAX_VERSION, NULL, 0, {}} +#define SLE_ST_INCLUDE() {false, SL_ST_INCLUDE, 0, 0, 0, SL_MAX_VERSION, NULL, 0, {}} /** End marker of a struct/class save or load. */ -#define SLE_END() {false, SL_END, 0, 0, 0, 0, NULL, 0} +#define SLE_END() {false, SL_END, 0, 0, 0, 0, NULL, 0, {}} /** * Storage of global simple variables, references (pointers), and arrays. @@ -354,9 +370,11 @@ typedef SaveLoad SaveLoadGlobVarList; * @param type Storage of the data in memory and in the savegame. * @param from First savegame version that has the field. * @param to Last savegame version that has the field. + * @param extver ExtendedSaveLoadFeatureTest to test (along with from and to) which savegames have the field * @note In general, it is better to use one of the SLEG_* macros below. */ -#define SLEG_GENERAL(cmd, variable, type, length, from, to) {true, cmd, type, length, from, to, (void*)&variable, sizeof(variable)} +#define SLEG_GENERAL_X(cmd, variable, type, length, from, to, extver) {true, cmd, type, length, from, to, (void*)&variable, sizeof(variable), extver} +#define SLEG_GENERAL(cmd, variable, type, length, from, to) SLEG_GENERAL_X(cmd, variable, type, length, from, to, {}) /** * Storage of a global variable in some savegame versions. @@ -364,8 +382,10 @@ typedef SaveLoad SaveLoadGlobVarList; * @param type Storage of the data in memory and in the savegame. * @param from First savegame version that has the field. * @param to Last savegame version that has the field. + * @param extver ExtendedSaveLoadFeatureTest to test (along with from and to) which savegames have the field */ -#define SLEG_CONDVAR(variable, type, from, to) SLEG_GENERAL(SL_VAR, variable, type, 0, from, to) +#define SLEG_CONDVAR_X(variable, type, from, to, extver) SLEG_GENERAL_X(SL_VAR, variable, type, 0, from, to, extver) +#define SLEG_CONDVAR(variable, type, from, to) SLEG_CONDVAR_X(variable, type, from, to, {}) /** * Storage of a global reference in some savegame versions. @@ -373,8 +393,10 @@ typedef SaveLoad SaveLoadGlobVarList; * @param type Storage of the data in memory and in the savegame. * @param from First savegame version that has the field. * @param to Last savegame version that has the field. + * @param extver ExtendedSaveLoadFeatureTest to test (along with from and to) which savegames have the field */ -#define SLEG_CONDREF(variable, type, from, to) SLEG_GENERAL(SL_REF, variable, type, 0, from, to) +#define SLEG_CONDREF_X(variable, type, from, to, extver) SLEG_GENERAL_X(SL_REF, variable, type, 0, from, to, extver) +#define SLEG_CONDREF(variable, type, from, to) SLEG_CONDREF_X(variable, type, from, to, {}) /** * Storage of a global array in some savegame versions. @@ -383,8 +405,10 @@ typedef SaveLoad SaveLoadGlobVarList; * @param length Number of elements in the array. * @param from First savegame version that has the array. * @param to Last savegame version that has the array. + * @param extver ExtendedSaveLoadFeatureTest to test (along with from and to) which savegames have the field */ -#define SLEG_CONDARR(variable, type, length, from, to) SLEG_GENERAL(SL_ARR, variable, type, length, from, to) +#define SLEG_CONDARR_X(variable, type, length, from, to, extver) SLEG_GENERAL_X(SL_ARR, variable, type, length, from, to, extver) +#define SLEG_CONDARR(variable, type, length, from, to) SLEG_CONDARR_X(variable, type, length, from, to, {}) /** * Storage of a global string in some savegame versions. @@ -393,8 +417,10 @@ typedef SaveLoad SaveLoadGlobVarList; * @param length Number of elements in the string (only used for fixed size buffers). * @param from First savegame version that has the string. * @param to Last savegame version that has the string. + * @param extver ExtendedSaveLoadFeatureTest to test (along with from and to) which savegames have the field */ -#define SLEG_CONDSTR(variable, type, length, from, to) SLEG_GENERAL(SL_STR, variable, type, length, from, to) +#define SLEG_CONDSTR_X(variable, type, length, from, to, extver) SLEG_GENERAL_X(SL_STR, variable, type, length, from, to, extver) +#define SLEG_CONDSTR(variable, type, length, from, to) SLEG_CONDSTR_X(variable, type, length, from, to, {}) /** * Storage of a global list in some savegame versions. @@ -402,8 +428,10 @@ typedef SaveLoad SaveLoadGlobVarList; * @param type Storage of the data in memory and in the savegame. * @param from First savegame version that has the list. * @param to Last savegame version that has the list. + * @param extver ExtendedSaveLoadFeatureTest to test (along with from and to) which savegames have the field */ -#define SLEG_CONDLST(variable, type, from, to) SLEG_GENERAL(SL_LST, variable, type, 0, from, to) +#define SLEG_CONDLST_X(variable, type, from, to, extver) SLEG_GENERAL_X(SL_LST, variable, type, 0, from, to, extver) +#define SLEG_CONDLST(variable, type, from, to) SLEG_CONDLST_X(variable, type, from, to, {}) /** * Storage of a global variable in every savegame version. @@ -445,11 +473,12 @@ typedef SaveLoad SaveLoadGlobVarList; * @param length Length of the empty space. * @param from First savegame version that has the empty space. * @param to Last savegame version that has the empty space. + * @param extver ExtendedSaveLoadFeatureTest to test (along with from and to) which savegames have empty space */ -#define SLEG_CONDNULL(length, from, to) {true, SL_ARR, SLE_FILE_U8 | SLE_VAR_NULL | SLF_NOT_IN_CONFIG, length, from, to, (void*)NULL} +#define SLEG_CONDNULL(length, from, to) {true, SL_ARR, SLE_FILE_U8 | SLE_VAR_NULL | SLF_NOT_IN_CONFIG, length, from, to, (void*)NULL, {}} /** End marker of global variables save or load. */ -#define SLEG_END() {true, SL_END, 0, 0, 0, 0, NULL, 0} +#define SLEG_END() {true, SL_END, 0, 0, 0, 0, NULL, 0, {}} /** * Checks whether the savegame is below \a major.\a minor. @@ -471,10 +500,10 @@ static inline bool IsSavegameVersionBefore(uint16 major, byte minor = 0) * @param version_to Highest version number that falls within the range. * @return Active savegame version falls within the given range. */ -static inline bool SlIsObjectCurrentlyValid(uint16 version_from, uint16 version_to) +static inline bool SlIsObjectCurrentlyValid(uint16 version_from, uint16 version_to, ExtendedSaveLoadFeatureTest ext_feature_test) { extern const uint16 SAVEGAME_VERSION; - if (SAVEGAME_VERSION < version_from || SAVEGAME_VERSION > version_to) return false; + if (!ext_feature_test.IsFeaturePresent(SAVEGAME_VERSION, version_from, version_to)) return false; return true; } diff --git a/src/settings.cpp b/src/settings.cpp index e6754bb905..2ed2f6f26b 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -486,7 +486,7 @@ static void IniLoadSettings(IniFile *ini, const SettingDesc *sd, const char *grp const SettingDescBase *sdb = &sd->desc; const SaveLoad *sld = &sd->save; - if (!SlIsObjectCurrentlyValid(sld->version_from, sld->version_to)) continue; + if (!SlIsObjectCurrentlyValid(sld->version_from, sld->version_to, sld->ext_feature_test)) continue; /* For settings.xx.yy load the settings from [xx] yy = ? */ s = strchr(sdb->name, '.'); @@ -585,7 +585,7 @@ static void IniSaveSettings(IniFile *ini, const SettingDesc *sd, const char *grp /* If the setting is not saved to the configuration * file, just continue with the next setting */ - if (!SlIsObjectCurrentlyValid(sld->version_from, sld->version_to)) continue; + if (!SlIsObjectCurrentlyValid(sld->version_from, sld->version_to, sld->ext_feature_test)) continue; if (sld->conv & SLF_NOT_IN_CONFIG) continue; /* XXX - wtf is this?? (group override?) */ @@ -1381,7 +1381,7 @@ static void HandleOldDiffCustom(bool savegame) for (uint i = 0; i < options_to_load; i++) { const SettingDesc *sd = &_settings[i]; /* Skip deprecated options */ - if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to)) continue; + if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to, sd->save.ext_feature_test)) continue; void *var = GetVariableAddress(savegame ? &_settings_game : &_settings_newgame, &sd->save); Write_ValidateSetting(var, sd, (int32)((i == 4 ? 1000 : 1) * _old_diff_custom[i])); } @@ -1839,7 +1839,7 @@ CommandCost CmdChangeSetting(TileIndex tile, DoCommandFlag flags, uint32 p1, uin const SettingDesc *sd = GetSettingDescription(p1); if (sd == NULL) return CMD_ERROR; - if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to)) return CMD_ERROR; + if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to, sd->save.ext_feature_test)) return CMD_ERROR; if (!sd->IsEditable(true)) return CMD_ERROR; @@ -2050,13 +2050,13 @@ const SettingDesc *GetSettingFromName(const char *name, uint *i) /* First check all full names */ for (*i = 0, sd = _settings; sd->save.cmd != SL_END; sd++, (*i)++) { - if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to)) continue; + if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to, sd->save.ext_feature_test)) continue; if (strcmp(sd->desc.name, name) == 0) return sd; } /* Then check the shortcut variant of the name. */ for (*i = 0, sd = _settings; sd->save.cmd != SL_END; sd++, (*i)++) { - if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to)) continue; + if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to, sd->save.ext_feature_test)) continue; const char *short_name = strchr(sd->desc.name, '.'); if (short_name != NULL) { short_name++; @@ -2067,7 +2067,7 @@ const SettingDesc *GetSettingFromName(const char *name, uint *i) if (strncmp(name, "company.", 8) == 0) name += 8; /* And finally the company-based settings */ for (*i = 0, sd = _company_settings; sd->save.cmd != SL_END; sd++, (*i)++) { - if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to)) continue; + if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to, sd->save.ext_feature_test)) continue; if (strcmp(sd->desc.name, name) == 0) return sd; } @@ -2161,7 +2161,7 @@ void IConsoleListSettings(const char *prefilter) IConsolePrintF(CC_WARNING, "All settings with their current value:"); for (const SettingDesc *sd = _settings; sd->save.cmd != SL_END; sd++) { - if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to)) continue; + if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to, sd->save.ext_feature_test)) continue; if (prefilter != NULL && strstr(sd->desc.name, prefilter) == NULL) continue; char value[80]; const void *ptr = GetVariableAddress(&GetGameSettings(), &sd->save); diff --git a/src/table/company_settings.ini b/src/table/company_settings.ini index 71b95cc393..615e808cb3 100644 --- a/src/table/company_settings.ini +++ b/src/table/company_settings.ini @@ -18,8 +18,8 @@ static const SettingDesc _company_settings[] = { [post-amble] }; [templates] -SDT_BOOL = SDT_BOOL($base, $var, $flags, $guiflags, $def, $str, $strhelp, $strval, $proc, $from, $to, $cat), -SDT_VAR = SDT_VAR($base, $var, $type, $flags, $guiflags, $def, $min, $max, $interval, $str, $strhelp, $strval, $proc, $from, $to, $cat), +SDT_BOOL = SDT_BOOL($base, $var, $flags, $guiflags, $def, $str, $strhelp, $strval, $proc, $from, $to, $cat, $extver), +SDT_VAR = SDT_VAR($base, $var, $type, $flags, $guiflags, $def, $min, $max, $interval, $str, $strhelp, $strval, $proc, $from, $to, $cat, $extver), SDT_END = SDT_END() [defaults] @@ -34,6 +34,7 @@ load = NULL from = 0 to = SL_MAX_VERSION cat = SC_ADVANCED +extver = {} diff --git a/src/table/currency_settings.ini b/src/table/currency_settings.ini index dede8b0fb7..e38349f3df 100644 --- a/src/table/currency_settings.ini +++ b/src/table/currency_settings.ini @@ -11,9 +11,9 @@ static const SettingDesc _currency_settings[] = { [post-amble] }; [templates] -SDT_VAR = SDT_VAR($base, $var, $type, $flags, $guiflags, $def, $min, $max, $interval, $str, $strhelp, $strval, $proc, $from, $to, $cat), -SDT_CHR = SDT_CHR($base, $var, $flags, $guiflags, $def, $str, $strhelp, $strval, $proc, $from, $to, $cat), -SDT_STR = SDT_STR($base, $var, $type, $flags, $guiflags, $def, $str, $strhelp, $strval, $proc, $from, $to, $cat), +SDT_VAR = SDT_VAR($base, $var, $type, $flags, $guiflags, $def, $min, $max, $interval, $str, $strhelp, $strval, $proc, $from, $to, $cat, $extver), +SDT_CHR = SDT_CHR($base, $var, $flags, $guiflags, $def, $str, $strhelp, $strval, $proc, $from, $to, $cat, $extver), +SDT_STR = SDT_STR($base, $var, $type, $flags, $guiflags, $def, $str, $strhelp, $strval, $proc, $from, $to, $cat, $extver), SDT_END = SDT_END() [defaults] @@ -28,6 +28,7 @@ load = NULL from = 0 to = SL_MAX_VERSION cat = SC_ADVANCED +extver = {} diff --git a/src/table/gameopt_settings.ini b/src/table/gameopt_settings.ini index 3a47c09e33..593d849ab8 100644 --- a/src/table/gameopt_settings.ini +++ b/src/table/gameopt_settings.ini @@ -41,13 +41,13 @@ static const SettingDesc _gameopt_settings[] = { [post-amble] }; [templates] -SDTG_GENERAL = SDTG_GENERAL($name, $sdt_cmd, $sle_cmd, $type, $flags, $guiflags, $var, $length, $def, $min, $max, $interval, $full, $str, $strhelp, $strval, $proc, $from, $to, $cat), -SDTG_VAR = SDTG_VAR($name, $type, $flags, $guiflags, $var, $def, $min, $max, $interval, $str, $strhelp, $strval, $proc, $from, $to, $cat), -SDT_NULL = SDT_NULL($length, $from, $to), -SDTC_OMANY = SDTC_OMANY( $var, $type, $flags, $guiflags, $def, $max, $full, $str, $strhelp, $strval, $proc, $from, $to, $cat), -SDTG_OMANY = SDTG_OMANY($name, $type, $flags, $guiflags, $var, $def, $max, $full, $str, $strhelp, $strval, $proc, $from, $to, $cat), -SDT_OMANY = SDT_OMANY($base, $var, $type, $flags, $guiflags, $def, $max, $full, $str, $strhelp, $strval, $proc, $from, $to, $load, $cat), -SDT_VAR = SDT_VAR($base, $var, $type, $flags, $guiflags, $def, $min, $max, $interval, $str, $strhelp, $strval, $proc, $from, $to, $cat), +SDTG_GENERAL = SDTG_GENERAL($name, $sdt_cmd, $sle_cmd, $type, $flags, $guiflags, $var, $length, $def, $min, $max, $interval, $full, $str, $strhelp, $strval, $proc, $from, $to, $cat, $extver), +SDTG_VAR = SDTG_VAR($name, $type, $flags, $guiflags, $var, $def, $min, $max, $interval, $str, $strhelp, $strval, $proc, $from, $to, $cat, $extver), +SDT_NULL = SDT_NULL($length, $from, $to, $extver), +SDTC_OMANY = SDTC_OMANY( $var, $type, $flags, $guiflags, $def, $max, $full, $str, $strhelp, $strval, $proc, $from, $to, $cat, $extver), +SDTG_OMANY = SDTG_OMANY($name, $type, $flags, $guiflags, $var, $def, $max, $full, $str, $strhelp, $strval, $proc, $from, $to, $cat, $extver), +SDT_OMANY = SDT_OMANY($base, $var, $type, $flags, $guiflags, $def, $max, $full, $str, $strhelp, $strval, $proc, $from, $to, $load, $cat, $extver), +SDT_VAR = SDT_VAR($base, $var, $type, $flags, $guiflags, $def, $min, $max, $interval, $str, $strhelp, $strval, $proc, $from, $to, $cat, $extver), SDT_END = SDT_END() [defaults] @@ -62,6 +62,7 @@ load = NULL from = 0 to = SL_MAX_VERSION cat = SC_ADVANCED +extver = {} diff --git a/src/table/misc_settings.ini b/src/table/misc_settings.ini index 52ca2d16ef..26620318e6 100644 --- a/src/table/misc_settings.ini +++ b/src/table/misc_settings.ini @@ -15,12 +15,12 @@ static const SettingDescGlobVarList _misc_settings[] = { [post-amble] }; [templates] -SDTG_LIST = SDTG_LIST($name, $type, $length, $flags, $guiflags, $var, $def, $str, $strhelp, $strval, $proc, $from, $to, $cat), -SDTG_MMANY = SDTG_MMANY($name, $type, $flags, $guiflags, $var, $def, $full, $str, $strhelp, $strval, $proc, $from, $to, $cat), -SDTG_OMANY = SDTG_OMANY($name, $type, $flags, $guiflags, $var, $def, $max, $full, $str, $strhelp, $strval, $proc, $from, $to, $cat), -SDTG_STR = SDTG_STR($name, $type, $flags, $guiflags, $var, $def, $str, $strhelp, $strval, $proc, $from, $to, $cat), -SDTG_BOOL = SDTG_BOOL($name, $flags, $guiflags, $var, $def, $str, $strhelp, $strval, $proc, $from, $to, $cat), -SDTG_VAR = SDTG_VAR($name, $type, $flags, $guiflags, $var, $def, $min, $max, $interval, $str, $strhelp, $strval, $proc, $from, $to, $cat), +SDTG_LIST = SDTG_LIST($name, $type, $length, $flags, $guiflags, $var, $def, $str, $strhelp, $strval, $proc, $from, $to, $cat, $extver), +SDTG_MMANY = SDTG_MMANY($name, $type, $flags, $guiflags, $var, $def, $full, $str, $strhelp, $strval, $proc, $from, $to, $cat, $extver), +SDTG_OMANY = SDTG_OMANY($name, $type, $flags, $guiflags, $var, $def, $max, $full, $str, $strhelp, $strval, $proc, $from, $to, $cat, $extver), +SDTG_STR = SDTG_STR($name, $type, $flags, $guiflags, $var, $def, $str, $strhelp, $strval, $proc, $from, $to, $cat, $extver), +SDTG_BOOL = SDTG_BOOL($name, $flags, $guiflags, $var, $def, $str, $strhelp, $strval, $proc, $from, $to, $cat, $extver), +SDTG_VAR = SDTG_VAR($name, $type, $flags, $guiflags, $var, $def, $min, $max, $interval, $str, $strhelp, $strval, $proc, $from, $to, $cat, $extver), SDTG_END = SDTG_END() [defaults] @@ -35,6 +35,7 @@ load = NULL from = 0 to = SL_MAX_VERSION cat = SC_ADVANCED +extver = {} diff --git a/src/table/settings.h.preamble b/src/table/settings.h.preamble index 33345bb713..7c0ca8a972 100644 --- a/src/table/settings.h.preamble +++ b/src/table/settings.h.preamble @@ -61,76 +61,76 @@ static size_t ConvertLandscape(const char *value); /* Macros for various objects to go in the configuration file. * This section is for global variables */ -#define SDTG_GENERAL(name, sdt_cmd, sle_cmd, type, flags, guiflags, var, length, def, min, max, interval, full, str, strhelp, strval, proc, from, to, cat)\ - {NSD_GENERAL(name, def, sdt_cmd, guiflags, min, max, interval, full, str, strhelp, strval, proc, NULL, cat), SLEG_GENERAL(sle_cmd, var, type | flags, length, from, to)} +#define SDTG_GENERAL(name, sdt_cmd, sle_cmd, type, flags, guiflags, var, length, def, min, max, interval, full, str, strhelp, strval, proc, from, to, cat, extver)\ + {NSD_GENERAL(name, def, sdt_cmd, guiflags, min, max, interval, full, str, strhelp, strval, proc, NULL, cat), SLEG_GENERAL_X(sle_cmd, var, type | flags, length, from, to, extver)} -#define SDTG_VAR(name, type, flags, guiflags, var, def, min, max, interval, str, strhelp, strval, proc, from, to, cat)\ - SDTG_GENERAL(name, SDT_NUMX, SL_VAR, type, flags, guiflags, var, 0, def, min, max, interval, NULL, str, strhelp, strval, proc, from, to, cat) +#define SDTG_VAR(name, type, flags, guiflags, var, def, min, max, interval, str, strhelp, strval, proc, from, to, cat, extver)\ + SDTG_GENERAL(name, SDT_NUMX, SL_VAR, type, flags, guiflags, var, 0, def, min, max, interval, NULL, str, strhelp, strval, proc, from, to, cat, extver) -#define SDTG_BOOL(name, flags, guiflags, var, def, str, strhelp, strval, proc, from, to, cat)\ - SDTG_GENERAL(name, SDT_BOOLX, SL_VAR, SLE_BOOL, flags, guiflags, var, 0, def, 0, 1, 0, NULL, str, strhelp, strval, proc, from, to, cat) +#define SDTG_BOOL(name, flags, guiflags, var, def, str, strhelp, strval, proc, from, to, cat, extver)\ + SDTG_GENERAL(name, SDT_BOOLX, SL_VAR, SLE_BOOL, flags, guiflags, var, 0, def, 0, 1, 0, NULL, str, strhelp, strval, proc, from, to, cat, extver) -#define SDTG_LIST(name, type, length, flags, guiflags, var, def, str, strhelp, strval, proc, from, to, cat)\ - SDTG_GENERAL(name, SDT_INTLIST, SL_ARR, type, flags, guiflags, var, length, def, 0, 0, 0, NULL, str, strhelp, strval, proc, from, to, cat) +#define SDTG_LIST(name, type, length, flags, guiflags, var, def, str, strhelp, strval, proc, from, to, cat, extver)\ + SDTG_GENERAL(name, SDT_INTLIST, SL_ARR, type, flags, guiflags, var, length, def, 0, 0, 0, NULL, str, strhelp, strval, proc, from, to, cat, extver) -#define SDTG_STR(name, type, flags, guiflags, var, def, str, strhelp, strval, proc, from, to, cat)\ - SDTG_GENERAL(name, SDT_STRING, SL_STR, type, flags, guiflags, var, lengthof(var), def, 0, 0, 0, NULL, str, strhelp, strval, proc, from, to, cat) +#define SDTG_STR(name, type, flags, guiflags, var, def, str, strhelp, strval, proc, from, to, cat, extver)\ + SDTG_GENERAL(name, SDT_STRING, SL_STR, type, flags, guiflags, var, lengthof(var), def, 0, 0, 0, NULL, str, strhelp, strval, proc, from, to, cat, extver) -#define SDTG_OMANY(name, type, flags, guiflags, var, def, max, full, str, strhelp, strval, proc, from, to, cat)\ - SDTG_GENERAL(name, SDT_ONEOFMANY, SL_VAR, type, flags, guiflags, var, 0, def, 0, max, 0, full, str, strhelp, strval, proc, from, to, cat) +#define SDTG_OMANY(name, type, flags, guiflags, var, def, max, full, str, strhelp, strval, proc, from, to, cat, extver)\ + SDTG_GENERAL(name, SDT_ONEOFMANY, SL_VAR, type, flags, guiflags, var, 0, def, 0, max, 0, full, str, strhelp, strval, proc, from, to, cat, extver) -#define SDTG_MMANY(name, type, flags, guiflags, var, def, full, str, strhelp, strval, proc, from, to, cat)\ - SDTG_GENERAL(name, SDT_MANYOFMANY, SL_VAR, type, flags, guiflags, var, 0, def, 0, 0, 0, full, str, strhelp, strval, proc, from, to, cat) +#define SDTG_MMANY(name, type, flags, guiflags, var, def, full, str, strhelp, strval, proc, from, to, cat, extver)\ + SDTG_GENERAL(name, SDT_MANYOFMANY, SL_VAR, type, flags, guiflags, var, 0, def, 0, 0, 0, full, str, strhelp, strval, proc, from, to, cat, extver) -#define SDTG_NULL(length, from, to)\ - {{"", NULL, {0}, {0}, 0, 0, 0, NULL, STR_NULL, STR_NULL, STR_NULL, NULL, NULL, SC_NONE}, SLEG_NULL(length, from, to)} +#define SDTG_NULL(length, from, to, extver)\ + {{"", NULL, {0}, {0}, 0, 0, 0, NULL, STR_NULL, STR_NULL, STR_NULL, NULL, NULL, SC_NONE}, SLEG_NULL_X(length, from, to, extver)} #define SDTG_END() {{NULL, NULL, {0}, {0}, 0, 0, 0, NULL, STR_NULL, STR_NULL, STR_NULL, NULL, NULL, SC_NONE}, SLEG_END()} /* Macros for various objects to go in the configuration file. * This section is for structures where their various members are saved */ -#define SDT_GENERAL(name, sdt_cmd, sle_cmd, type, flags, guiflags, base, var, length, def, min, max, interval, full, str, strhelp, strval, proc, load, from, to, cat)\ - {NSD_GENERAL(name, def, sdt_cmd, guiflags, min, max, interval, full, str, strhelp, strval, proc, load, cat), SLE_GENERAL(sle_cmd, base, var, type | flags, length, from, to)} +#define SDT_GENERAL(name, sdt_cmd, sle_cmd, type, flags, guiflags, base, var, length, def, min, max, interval, full, str, strhelp, strval, proc, load, from, to, cat, extver)\ + {NSD_GENERAL(name, def, sdt_cmd, guiflags, min, max, interval, full, str, strhelp, strval, proc, load, cat), SLE_GENERAL_X(sle_cmd, base, var, type | flags, length, from, to, extver)} -#define SDT_VAR(base, var, type, flags, guiflags, def, min, max, interval, str, strhelp, strval, proc, from, to, cat)\ - SDT_GENERAL(#var, SDT_NUMX, SL_VAR, type, flags, guiflags, base, var, 1, def, min, max, interval, NULL, str, strhelp, strval, proc, NULL, from, to, cat) +#define SDT_VAR(base, var, type, flags, guiflags, def, min, max, interval, str, strhelp, strval, proc, from, to, cat, extver)\ + SDT_GENERAL(#var, SDT_NUMX, SL_VAR, type, flags, guiflags, base, var, 1, def, min, max, interval, NULL, str, strhelp, strval, proc, NULL, from, to, cat, extver) -#define SDT_BOOL(base, var, flags, guiflags, def, str, strhelp, strval, proc, from, to, cat)\ - SDT_GENERAL(#var, SDT_BOOLX, SL_VAR, SLE_BOOL, flags, guiflags, base, var, 1, def, 0, 1, 0, NULL, str, strhelp, strval, proc, NULL, from, to, cat) +#define SDT_BOOL(base, var, flags, guiflags, def, str, strhelp, strval, proc, from, to, cat, extver)\ + SDT_GENERAL(#var, SDT_BOOLX, SL_VAR, SLE_BOOL, flags, guiflags, base, var, 1, def, 0, 1, 0, NULL, str, strhelp, strval, proc, NULL, from, to, cat, extver) -#define SDT_LIST(base, var, type, flags, guiflags, def, str, strhelp, strval, proc, from, to, cat)\ - SDT_GENERAL(#var, SDT_INTLIST, SL_ARR, type, flags, guiflags, base, var, lengthof(((base*)8)->var), def, 0, 0, 0, NULL, str, strhelp, strval, proc, NULL, from, to, cat) +#define SDT_LIST(base, var, type, flags, guiflags, def, str, strhelp, strval, proc, from, to, cat, extver)\ + SDT_GENERAL(#var, SDT_INTLIST, SL_ARR, type, flags, guiflags, base, var, lengthof(((base*)8)->var), def, 0, 0, 0, NULL, str, strhelp, strval, proc, NULL, from, to, cat, extver) -#define SDT_STR(base, var, type, flags, guiflags, def, str, strhelp, strval, proc, from, to, cat)\ - SDT_GENERAL(#var, SDT_STRING, SL_STR, type, flags, guiflags, base, var, lengthof(((base*)8)->var), def, 0, 0, 0, NULL, str, strhelp, strval, proc, NULL, from, to, cat) +#define SDT_STR(base, var, type, flags, guiflags, def, str, strhelp, strval, proc, from, to, cat, extver)\ + SDT_GENERAL(#var, SDT_STRING, SL_STR, type, flags, guiflags, base, var, lengthof(((base*)8)->var), def, 0, 0, 0, NULL, str, strhelp, strval, proc, NULL, from, to, cat, extver) -#define SDT_CHR(base, var, flags, guiflags, def, str, strhelp, strval, proc, from, to, cat)\ - SDT_GENERAL(#var, SDT_STRING, SL_VAR, SLE_CHAR, flags, guiflags, base, var, 1, def, 0, 0, 0, NULL, str, strhelp, strval, proc, NULL, from, to, cat) +#define SDT_CHR(base, var, flags, guiflags, def, str, strhelp, strval, proc, from, to, cat, extver)\ + SDT_GENERAL(#var, SDT_STRING, SL_VAR, SLE_CHAR, flags, guiflags, base, var, 1, def, 0, 0, 0, NULL, str, strhelp, strval, proc, NULL, from, to, cat, extver) -#define SDT_OMANY(base, var, type, flags, guiflags, def, max, full, str, strhelp, strval, proc, from, to, load, cat)\ - SDT_GENERAL(#var, SDT_ONEOFMANY, SL_VAR, type, flags, guiflags, base, var, 1, def, 0, max, 0, full, str, strhelp, strval, proc, load, from, to, cat) +#define SDT_OMANY(base, var, type, flags, guiflags, def, max, full, str, strhelp, strval, proc, from, to, load, cat, extver)\ + SDT_GENERAL(#var, SDT_ONEOFMANY, SL_VAR, type, flags, guiflags, base, var, 1, def, 0, max, 0, full, str, strhelp, strval, proc, load, from, to, cat, extver) -#define SDT_MMANY(base, var, type, flags, guiflags, def, full, str, proc, strhelp, strval, from, to, cat)\ - SDT_GENERAL(#var, SDT_MANYOFMANY, SL_VAR, type, flags, guiflags, base, var, 1, def, 0, 0, 0, full, str, strhelp, strval, proc, NULL, from, to, cat) +#define SDT_MMANY(base, var, type, flags, guiflags, def, full, str, proc, strhelp, strval, from, to, cat, extver)\ + SDT_GENERAL(#var, SDT_MANYOFMANY, SL_VAR, type, flags, guiflags, base, var, 1, def, 0, 0, 0, full, str, strhelp, strval, proc, NULL, from, to, cat, extver) -#define SDT_NULL(length, from, to)\ - {{"", NULL, {0}, {0}, 0, 0, 0, NULL, STR_NULL, STR_NULL, STR_NULL, NULL, NULL, SC_NONE}, SLE_CONDNULL(length, from, to)} +#define SDT_NULL(length, from, to, extver)\ + {{"", NULL, {0}, {0}, 0, 0, 0, NULL, STR_NULL, STR_NULL, STR_NULL, NULL, NULL, SC_NONE}, SLE_CONDNULL_X(length, from, to, extver)} -#define SDTC_VAR(var, type, flags, guiflags, def, min, max, interval, str, strhelp, strval, proc, from, to, cat)\ - SDTG_GENERAL(#var, SDT_NUMX, SL_VAR, type, flags, guiflags, _settings_client.var, 1, def, min, max, interval, NULL, str, strhelp, strval, proc, from, to, cat) +#define SDTC_VAR(var, type, flags, guiflags, def, min, max, interval, str, strhelp, strval, proc, from, to, cat, extver)\ + SDTG_GENERAL(#var, SDT_NUMX, SL_VAR, type, flags, guiflags, _settings_client.var, 1, def, min, max, interval, NULL, str, strhelp, strval, proc, from, to, cat, extver) -#define SDTC_BOOL(var, flags, guiflags, def, str, strhelp, strval, proc, from, to, cat)\ - SDTG_GENERAL(#var, SDT_BOOLX, SL_VAR, SLE_BOOL, flags, guiflags, _settings_client.var, 1, def, 0, 1, 0, NULL, str, strhelp, strval, proc, from, to, cat) +#define SDTC_BOOL(var, flags, guiflags, def, str, strhelp, strval, proc, from, to, cat, extver)\ + SDTG_GENERAL(#var, SDT_BOOLX, SL_VAR, SLE_BOOL, flags, guiflags, _settings_client.var, 1, def, 0, 1, 0, NULL, str, strhelp, strval, proc, from, to, cat, extver) -#define SDTC_LIST(var, type, flags, guiflags, def, str, strhelp, strval, proc, from, to, cat)\ - SDTG_GENERAL(#var, SDT_INTLIST, SL_ARR, type, flags, guiflags, _settings_client.var, lengthof(_settings_client.var), def, 0, 0, 0, NULL, str, strhelp, strval, proc, from, to, cat) +#define SDTC_LIST(var, type, flags, guiflags, def, str, strhelp, strval, proc, from, to, cat, extver)\ + SDTG_GENERAL(#var, SDT_INTLIST, SL_ARR, type, flags, guiflags, _settings_client.var, lengthof(_settings_client.var), def, 0, 0, 0, NULL, str, strhelp, strval, proc, from, to, cat, extver) -#define SDTC_STR(var, type, flags, guiflags, def, str, strhelp, strval, proc, from, to, cat)\ - SDTG_GENERAL(#var, SDT_STRING, SL_STR, type, flags, guiflags, _settings_client.var, lengthof(_settings_client.var), def, 0, 0, 0, NULL, str, strhelp, strval, proc, from, to, cat) +#define SDTC_STR(var, type, flags, guiflags, def, str, strhelp, strval, proc, from, to, cat, extver)\ + SDTG_GENERAL(#var, SDT_STRING, SL_STR, type, flags, guiflags, _settings_client.var, lengthof(_settings_client.var), def, 0, 0, 0, NULL, str, strhelp, strval, proc, from, to, cat, extver) -#define SDTC_OMANY(var, type, flags, guiflags, def, max, full, str, strhelp, strval, proc, from, to, cat)\ - SDTG_GENERAL(#var, SDT_ONEOFMANY, SL_VAR, type, flags, guiflags, _settings_client.var, 1, def, 0, max, 0, full, str, strhelp, strval, proc, from, to, cat) +#define SDTC_OMANY(var, type, flags, guiflags, def, max, full, str, strhelp, strval, proc, from, to, cat, extver)\ + SDTG_GENERAL(#var, SDT_ONEOFMANY, SL_VAR, type, flags, guiflags, _settings_client.var, 1, def, 0, max, 0, full, str, strhelp, strval, proc, from, to, cat, extver) #define SDT_END() {{NULL, NULL, {0}, {0}, 0, 0, 0, NULL, STR_NULL, STR_NULL, STR_NULL, NULL, NULL, SC_NONE}, SLE_END()} diff --git a/src/table/settings.ini b/src/table/settings.ini index f314f21e92..3256e20dab 100644 --- a/src/table/settings.ini +++ b/src/table/settings.ini @@ -64,19 +64,19 @@ const SettingDesc _settings[] = { [post-amble] }; [templates] -SDTG_BOOL = SDTG_BOOL($name, $flags, $guiflags, $var, $def, $str, $strhelp, $strval, $proc, $from, $to, $cat), -SDTG_VAR = SDTG_VAR($name, $type, $flags, $guiflags, $var, $def, $min, $max, $interval, $str, $strhelp, $strval, $proc, $from, $to, $cat), -SDTG_OMANY = SDTG_OMANY($name, $type, $flags, $guiflags, $var, $def, $max, $full, $str, $strhelp, $strval, $proc, $from, $to, $cat), -SDTC_BOOL = SDTC_BOOL( $var, $flags, $guiflags, $def, $str, $strhelp, $strval, $proc, $from, $to, $cat), -SDTC_LIST = SDTC_LIST( $var, $type, $flags, $guiflags, $def, $str, $strhelp, $strval, $proc, $from, $to, $cat), -SDTC_OMANY = SDTC_OMANY( $var, $type, $flags, $guiflags, $def, $max, $full, $str, $strhelp, $strval, $proc, $from, $to, $cat), -SDTC_STR = SDTC_STR( $var, $type, $flags, $guiflags, $def, $str, $strhelp, $strval, $proc, $from, $to, $cat), -SDTC_VAR = SDTC_VAR( $var, $type, $flags, $guiflags, $def, $min, $max, $interval, $str, $strhelp, $strval, $proc, $from, $to, $cat), -SDT_BOOL = SDT_BOOL($base, $var, $flags, $guiflags, $def, $str, $strhelp, $strval, $proc, $from, $to, $cat), -SDT_OMANY = SDT_OMANY($base, $var, $type, $flags, $guiflags, $def, $max, $full, $str, $strhelp, $strval, $proc, $from, $to, $load, $cat), -SDT_STR = SDT_STR($base, $var, $type, $flags, $guiflags, $def, $str, $strhelp, $strval, $proc, $from, $to, $cat), -SDT_VAR = SDT_VAR($base, $var, $type, $flags, $guiflags, $def, $min, $max, $interval, $str, $strhelp, $strval, $proc, $from, $to, $cat), -SDT_NULL = SDT_NULL($length, $from, $to), +SDTG_BOOL = SDTG_BOOL($name, $flags, $guiflags, $var, $def, $str, $strhelp, $strval, $proc, $from, $to, $cat, $extver), +SDTG_VAR = SDTG_VAR($name, $type, $flags, $guiflags, $var, $def, $min, $max, $interval, $str, $strhelp, $strval, $proc, $from, $to, $cat, $extver), +SDTG_OMANY = SDTG_OMANY($name, $type, $flags, $guiflags, $var, $def, $max, $full, $str, $strhelp, $strval, $proc, $from, $to, $cat, $extver), +SDTC_BOOL = SDTC_BOOL( $var, $flags, $guiflags, $def, $str, $strhelp, $strval, $proc, $from, $to, $cat, $extver), +SDTC_LIST = SDTC_LIST( $var, $type, $flags, $guiflags, $def, $str, $strhelp, $strval, $proc, $from, $to, $cat, $extver), +SDTC_OMANY = SDTC_OMANY( $var, $type, $flags, $guiflags, $def, $max, $full, $str, $strhelp, $strval, $proc, $from, $to, $cat, $extver), +SDTC_STR = SDTC_STR( $var, $type, $flags, $guiflags, $def, $str, $strhelp, $strval, $proc, $from, $to, $cat, $extver), +SDTC_VAR = SDTC_VAR( $var, $type, $flags, $guiflags, $def, $min, $max, $interval, $str, $strhelp, $strval, $proc, $from, $to, $cat, $extver), +SDT_BOOL = SDT_BOOL($base, $var, $flags, $guiflags, $def, $str, $strhelp, $strval, $proc, $from, $to, $cat, $extver), +SDT_OMANY = SDT_OMANY($base, $var, $type, $flags, $guiflags, $def, $max, $full, $str, $strhelp, $strval, $proc, $from, $to, $load, $cat, $extver), +SDT_STR = SDT_STR($base, $var, $type, $flags, $guiflags, $def, $str, $strhelp, $strval, $proc, $from, $to, $cat, $extver), +SDT_VAR = SDT_VAR($base, $var, $type, $flags, $guiflags, $def, $min, $max, $interval, $str, $strhelp, $strval, $proc, $from, $to, $cat, $extver), +SDT_NULL = SDT_NULL($length, $from, $to, $extver), SDT_END = SDT_END() [defaults] @@ -91,6 +91,7 @@ load = NULL from = 0 to = SL_MAX_VERSION cat = SC_ADVANCED +extver = {} diff --git a/src/table/win32_settings.ini b/src/table/win32_settings.ini index 1e0c9ad023..71b8499d2b 100644 --- a/src/table/win32_settings.ini +++ b/src/table/win32_settings.ini @@ -17,8 +17,8 @@ static const SettingDescGlobVarList _win32_settings[] = { }; #endif /* WIN32 */ [templates] -SDTG_BOOL = SDTG_BOOL($name, $flags, $guiflags, $var, $def, $str, $strhelp, $strval, $proc, $from, $to, $cat), -SDTG_VAR = SDTG_VAR($name, $type, $flags, $guiflags, $var, $def, $min, $max, $interval, $str, $strhelp, $strval, $proc, $from, $to, $cat), +SDTG_BOOL = SDTG_BOOL($name, $flags, $guiflags, $var, $def, $str, $strhelp, $strval, $proc, $from, $to, $cat, $extver), +SDTG_VAR = SDTG_VAR($name, $type, $flags, $guiflags, $var, $def, $min, $max, $interval, $str, $strhelp, $strval, $proc, $from, $to, $cat, $extver), SDTG_END = SDTG_END() [defaults] @@ -33,6 +33,7 @@ load = NULL from = 0 to = SL_MAX_VERSION cat = SC_ADVANCED +extver = {} diff --git a/src/table/window_settings.ini b/src/table/window_settings.ini index ad77423d9d..cfa2f76d5a 100644 --- a/src/table/window_settings.ini +++ b/src/table/window_settings.ini @@ -12,8 +12,8 @@ static const SettingDesc _window_settings[] = { [post-amble] }; [templates] -SDT_BOOL = SDT_BOOL($base, $var, $flags, $guiflags, $def, $str, $strhelp, $strval, $proc, $from, $to, $cat), -SDT_VAR = SDT_VAR($base, $var, $type, $flags, $guiflags, $def, $min, $max, $interval, $str, $strhelp, $strval, $proc, $from, $to, $cat), +SDT_BOOL = SDT_BOOL($base, $var, $flags, $guiflags, $def, $str, $strhelp, $strval, $proc, $from, $to, $cat, $extver), +SDT_VAR = SDT_VAR($base, $var, $type, $flags, $guiflags, $def, $min, $max, $interval, $str, $strhelp, $strval, $proc, $from, $to, $cat, $extver), SDT_END = SDT_END() [defaults] @@ -29,6 +29,7 @@ load = NULL from = 0 to = SL_MAX_VERSION cat = SC_ADVANCED +extver = {}