mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-26 23:55:40 +00:00
StateWrapper: Track save state version
This commit is contained in:
parent
893268bba5
commit
69b2c3fc2d
|
@ -5,7 +5,10 @@
|
|||
#include <cstring>
|
||||
Log_SetChannel(StateWrapper);
|
||||
|
||||
StateWrapper::StateWrapper(ByteStream* stream, Mode mode) : m_stream(stream), m_mode(mode) {}
|
||||
StateWrapper::StateWrapper(ByteStream* stream, Mode mode, u32 version)
|
||||
: m_stream(stream), m_mode(mode), m_version(version)
|
||||
{
|
||||
}
|
||||
|
||||
StateWrapper::~StateWrapper() = default;
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ public:
|
|||
Write
|
||||
};
|
||||
|
||||
StateWrapper(ByteStream* stream, Mode mode);
|
||||
StateWrapper(ByteStream* stream, Mode mode, u32 version);
|
||||
StateWrapper(const StateWrapper&) = delete;
|
||||
~StateWrapper();
|
||||
|
||||
|
@ -30,6 +30,7 @@ public:
|
|||
bool IsWriting() const { return (m_mode == Mode::Write); }
|
||||
Mode GetMode() const { return m_mode; }
|
||||
void SetMode(Mode mode) { m_mode = mode; }
|
||||
u32 GetVersion() const { return m_version; }
|
||||
|
||||
/// Overload for integral or floating-point types. Writes bytes as-is.
|
||||
template<typename T, std::enable_if_t<std::is_integral_v<T> || std::is_floating_point_v<T>, int> = 0>
|
||||
|
@ -175,8 +176,21 @@ public:
|
|||
|
||||
bool DoMarker(const char* marker);
|
||||
|
||||
template<typename T>
|
||||
void DoEx(T* data, u32 version_introduced, T default_value)
|
||||
{
|
||||
if (m_version < version_introduced)
|
||||
{
|
||||
*data = std::move(default_value);
|
||||
return;
|
||||
}
|
||||
|
||||
Do(data);
|
||||
}
|
||||
|
||||
private:
|
||||
ByteStream* m_stream;
|
||||
Mode m_mode;
|
||||
u32 m_version;
|
||||
bool m_error = false;
|
||||
};
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
static constexpr u32 SAVE_STATE_MAGIC = 0x43435544;
|
||||
static constexpr u32 SAVE_STATE_VERSION = 42;
|
||||
static constexpr u32 SAVE_STATE_MINIMUM_VERSION = 42;
|
||||
|
||||
#pragma pack(push, 4)
|
||||
struct SAVE_STATE_HEADER
|
||||
|
|
|
@ -491,7 +491,7 @@ bool RecreateGPU(GPURenderer renderer)
|
|||
|
||||
// save current state
|
||||
std::unique_ptr<ByteStream> state_stream = ByteStream_CreateGrowableMemoryStream();
|
||||
StateWrapper sw(state_stream.get(), StateWrapper::Mode::Write);
|
||||
StateWrapper sw(state_stream.get(), StateWrapper::Mode::Write, SAVE_STATE_VERSION);
|
||||
const bool state_valid = g_gpu->DoState(sw) && TimingEvents::DoState(sw);
|
||||
if (!state_valid)
|
||||
Log_ErrorPrintf("Failed to save old GPU state when switching renderers");
|
||||
|
@ -946,12 +946,12 @@ bool DoLoadState(ByteStream* state, bool force_software_renderer)
|
|||
if (header.magic != SAVE_STATE_MAGIC)
|
||||
return false;
|
||||
|
||||
if (header.version != SAVE_STATE_VERSION)
|
||||
if (header.version < SAVE_STATE_MINIMUM_VERSION)
|
||||
{
|
||||
g_host_interface->ReportFormattedError(
|
||||
g_host_interface->TranslateString("System",
|
||||
"Save state is incompatible: expecting version %u but state is version %u."),
|
||||
SAVE_STATE_VERSION, header.version);
|
||||
"Save state is incompatible: minimum version is %u but state is version %u."),
|
||||
SAVE_STATE_MINIMUM_VERSION, header.version);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1041,7 +1041,7 @@ bool DoLoadState(ByteStream* state, bool force_software_renderer)
|
|||
if (!state->SeekAbsolute(header.offset_to_data))
|
||||
return false;
|
||||
|
||||
StateWrapper sw(state, StateWrapper::Mode::Read);
|
||||
StateWrapper sw(state, StateWrapper::Mode::Read, header.version);
|
||||
if (!DoState(sw))
|
||||
return false;
|
||||
|
||||
|
@ -1108,7 +1108,7 @@ bool SaveState(ByteStream* state, u32 screenshot_size /* = 128 */)
|
|||
|
||||
g_gpu->RestoreGraphicsAPIState();
|
||||
|
||||
StateWrapper sw(state, StateWrapper::Mode::Write);
|
||||
StateWrapper sw(state, StateWrapper::Mode::Write, SAVE_STATE_VERSION);
|
||||
const bool result = DoState(sw);
|
||||
|
||||
g_gpu->ResetGraphicsAPIState();
|
||||
|
|
Loading…
Reference in a new issue