Achievements: Ensure loading old states behave the same as new

This commit is contained in:
Stenzek 2025-01-13 13:13:14 +10:00
parent 8f39dbb464
commit 3621705933
No known key found for this signature in database
5 changed files with 21 additions and 18 deletions

View File

@ -1642,7 +1642,7 @@ void Achievements::HandleServerReconnectedEvent(const rc_client_event_t* event)
});
}
void Achievements::ResetClient()
void Achievements::Reset()
{
#ifdef ENABLE_RAINTEGRATION
if (IsUsingRAIntegration())
@ -1750,11 +1750,13 @@ void Achievements::SetHardcoreMode(bool enabled, bool force_display_message)
bool Achievements::DoState(StateWrapper& sw)
{
static constexpr u32 REQUIRED_VERSION = 56;
// if we're inactive, we still need to skip the data (if any)
if (!IsActive())
{
u32 data_size = 0;
sw.Do(&data_size);
sw.DoEx(&data_size, REQUIRED_VERSION, 0u);
if (data_size > 0)
sw.SkipBytes(data_size);
@ -1780,8 +1782,11 @@ bool Achievements::DoState(StateWrapper& sw)
GPUThread::RunOnThread([]() { FullscreenUI::CloseLoadingScreen(); });
}
// loading an old state without cheevos, so reset the runtime
Achievements::Reset();
u32 data_size = 0;
sw.Do(&data_size);
sw.DoEx(&data_size, REQUIRED_VERSION, 0u);
if (data_size == 0)
{
// reset runtime, no data (state might've been created without cheevos)

View File

@ -41,7 +41,7 @@ bool Initialize();
void UpdateSettings(const Settings& old_config);
/// Resets the internal state of all achievement tracking. Call on system reset.
void ResetClient();
void Reset();
/// Called when the system is being reset. If it returns false, the reset should be aborted.
bool ConfirmSystemReset();

View File

@ -2457,20 +2457,9 @@ bool System::DoState(StateWrapper& sw, bool update_display)
UpdateOverclock();
}
if (sw.GetVersion() >= 56) [[unlikely]]
{
if (!sw.DoMarker("Cheevos"))
if (!sw.DoMarkerEx("Cheevos", 56) || !Achievements::DoState(sw))
return false;
if (!Achievements::DoState(sw))
return false;
}
else
{
// loading an old state without cheevos, so reset the runtime
Achievements::ResetClient();
}
if (sw.HasError())
return false;
@ -2750,7 +2739,7 @@ void System::InternalReset()
MDEC::Reset();
SIO::Reset();
PCDrv::Reset();
Achievements::ResetClient();
Achievements::Reset();
s_state.frame_number = 1;
s_state.internal_frame_number = 0;
}

View File

@ -111,6 +111,14 @@ bool StateWrapper::DoMarker(const char* marker)
return false;
}
bool StateWrapper::DoMarkerEx(const char* marker, u32 version_introduced)
{
if (m_version < version_introduced)
return !HasError();
return DoMarker(marker);
}
std::span<u8> StateWrapper::GetDeferredBytes(size_t size)
{
if ((m_error = (m_error || (m_pos + size) > m_size))) [[unlikely]]

View File

@ -180,6 +180,7 @@ public:
}
bool DoMarker(const char* marker);
bool DoMarkerEx(const char* marker, u32 version_introduced);
template<typename T>
void DoEx(T* data, u32 version_introduced, T default_value)