mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-27 08:05:41 +00:00
StateWrapper: Track save state version
This commit is contained in:
parent
893268bba5
commit
69b2c3fc2d
|
@ -5,7 +5,10 @@
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
Log_SetChannel(StateWrapper);
|
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;
|
StateWrapper::~StateWrapper() = default;
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ public:
|
||||||
Write
|
Write
|
||||||
};
|
};
|
||||||
|
|
||||||
StateWrapper(ByteStream* stream, Mode mode);
|
StateWrapper(ByteStream* stream, Mode mode, u32 version);
|
||||||
StateWrapper(const StateWrapper&) = delete;
|
StateWrapper(const StateWrapper&) = delete;
|
||||||
~StateWrapper();
|
~StateWrapper();
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@ public:
|
||||||
bool IsWriting() const { return (m_mode == Mode::Write); }
|
bool IsWriting() const { return (m_mode == Mode::Write); }
|
||||||
Mode GetMode() const { return m_mode; }
|
Mode GetMode() const { return m_mode; }
|
||||||
void SetMode(Mode mode) { m_mode = 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.
|
/// 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>
|
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);
|
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:
|
private:
|
||||||
ByteStream* m_stream;
|
ByteStream* m_stream;
|
||||||
Mode m_mode;
|
Mode m_mode;
|
||||||
|
u32 m_version;
|
||||||
bool m_error = false;
|
bool m_error = false;
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
static constexpr u32 SAVE_STATE_MAGIC = 0x43435544;
|
static constexpr u32 SAVE_STATE_MAGIC = 0x43435544;
|
||||||
static constexpr u32 SAVE_STATE_VERSION = 42;
|
static constexpr u32 SAVE_STATE_VERSION = 42;
|
||||||
|
static constexpr u32 SAVE_STATE_MINIMUM_VERSION = 42;
|
||||||
|
|
||||||
#pragma pack(push, 4)
|
#pragma pack(push, 4)
|
||||||
struct SAVE_STATE_HEADER
|
struct SAVE_STATE_HEADER
|
||||||
|
|
|
@ -491,7 +491,7 @@ bool RecreateGPU(GPURenderer renderer)
|
||||||
|
|
||||||
// save current state
|
// save current state
|
||||||
std::unique_ptr<ByteStream> state_stream = ByteStream_CreateGrowableMemoryStream();
|
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);
|
const bool state_valid = g_gpu->DoState(sw) && TimingEvents::DoState(sw);
|
||||||
if (!state_valid)
|
if (!state_valid)
|
||||||
Log_ErrorPrintf("Failed to save old GPU state when switching renderers");
|
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)
|
if (header.magic != SAVE_STATE_MAGIC)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (header.version != SAVE_STATE_VERSION)
|
if (header.version < SAVE_STATE_MINIMUM_VERSION)
|
||||||
{
|
{
|
||||||
g_host_interface->ReportFormattedError(
|
g_host_interface->ReportFormattedError(
|
||||||
g_host_interface->TranslateString("System",
|
g_host_interface->TranslateString("System",
|
||||||
"Save state is incompatible: expecting version %u but state is version %u."),
|
"Save state is incompatible: minimum version is %u but state is version %u."),
|
||||||
SAVE_STATE_VERSION, header.version);
|
SAVE_STATE_MINIMUM_VERSION, header.version);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1041,7 +1041,7 @@ bool DoLoadState(ByteStream* state, bool force_software_renderer)
|
||||||
if (!state->SeekAbsolute(header.offset_to_data))
|
if (!state->SeekAbsolute(header.offset_to_data))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
StateWrapper sw(state, StateWrapper::Mode::Read);
|
StateWrapper sw(state, StateWrapper::Mode::Read, header.version);
|
||||||
if (!DoState(sw))
|
if (!DoState(sw))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -1108,7 +1108,7 @@ bool SaveState(ByteStream* state, u32 screenshot_size /* = 128 */)
|
||||||
|
|
||||||
g_gpu->RestoreGraphicsAPIState();
|
g_gpu->RestoreGraphicsAPIState();
|
||||||
|
|
||||||
StateWrapper sw(state, StateWrapper::Mode::Write);
|
StateWrapper sw(state, StateWrapper::Mode::Write, SAVE_STATE_VERSION);
|
||||||
const bool result = DoState(sw);
|
const bool result = DoState(sw);
|
||||||
|
|
||||||
g_gpu->ResetGraphicsAPIState();
|
g_gpu->ResetGraphicsAPIState();
|
||||||
|
|
Loading…
Reference in a new issue