Initial stubs for extending the save/load version checking/upgrade code,
with support for tests on individually versioned features as well as savegame versions. This is mainly for improved handling of features added to patchpacks. The current status-quo of picking a random number for the savegame version when releasing a patch breaks loading of savegames from newer trunk savegame versions, with or without the same patch applied, as savegame upgrade code is not run, which can also lead to crashes on load. Instead don't change the savegame version (but set the high bit to keep trunk versions away), but instead include the versions of individual features using a separate mechanism.pull/155/head
parent
67366cf03d
commit
17e8693e62
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @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<uint32> _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<ExtendedSaveLoadFeatureIndex>(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<ExtendedSaveLoadFeatureTestOperator>(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;
|
||||
}
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @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 <vector>
|
||||
|
||||
/**
|
||||
* 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 */
|
Loading…
Reference in New Issue