mirror of https://github.com/PCSX2/pcsx2.git
Achievements: Eliminate intermediate malloc on state save
This commit is contained in:
parent
46931072c7
commit
f909282973
|
@ -14,6 +14,7 @@
|
||||||
#include "IopMem.h"
|
#include "IopMem.h"
|
||||||
#include "MTGS.h"
|
#include "MTGS.h"
|
||||||
#include "Memory.h"
|
#include "Memory.h"
|
||||||
|
#include "SaveState.h"
|
||||||
#include "VMManager.h"
|
#include "VMManager.h"
|
||||||
#include "svnrev.h"
|
#include "svnrev.h"
|
||||||
#include "vtlb.h"
|
#include "vtlb.h"
|
||||||
|
@ -23,6 +24,7 @@
|
||||||
#include "common/Error.h"
|
#include "common/Error.h"
|
||||||
#include "common/FileSystem.h"
|
#include "common/FileSystem.h"
|
||||||
#include "common/HTTPDownloader.h"
|
#include "common/HTTPDownloader.h"
|
||||||
|
#include "common/HeapArray.h"
|
||||||
#include "common/MD5Digest.h"
|
#include "common/MD5Digest.h"
|
||||||
#include "common/Path.h"
|
#include "common/Path.h"
|
||||||
#include "common/ScopedGuard.h"
|
#include "common/ScopedGuard.h"
|
||||||
|
@ -1466,7 +1468,7 @@ void Achievements::SetHardcoreMode(bool enabled, bool force_display_message)
|
||||||
Host::OnAchievementsHardcoreModeChanged(enabled);
|
Host::OnAchievementsHardcoreModeChanged(enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Achievements::LoadState(const u8* state_data, u32 state_data_size)
|
void Achievements::LoadState(std::span<const u8> data)
|
||||||
{
|
{
|
||||||
const auto lock = GetLock();
|
const auto lock = GetLock();
|
||||||
|
|
||||||
|
@ -1479,14 +1481,14 @@ void Achievements::LoadState(const u8* state_data, u32 state_data_size)
|
||||||
#ifdef ENABLE_RAINTEGRATION
|
#ifdef ENABLE_RAINTEGRATION
|
||||||
if (IsUsingRAIntegration())
|
if (IsUsingRAIntegration())
|
||||||
{
|
{
|
||||||
if (state_data_size == 0)
|
if (data.empty())
|
||||||
{
|
{
|
||||||
Console.Warning("State is missing cheevos data, resetting RAIntegration");
|
Console.Warning("State is missing cheevos data, resetting RAIntegration");
|
||||||
RA_OnReset();
|
RA_OnReset();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
RA_RestoreState(reinterpret_cast<const char*>(state_data));
|
RA_RestoreState(reinterpret_cast<const char*>(data.data()));
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -1503,7 +1505,7 @@ void Achievements::LoadState(const u8* state_data, u32 state_data_size)
|
||||||
EndLoadingScreen(was_running_idle);
|
EndLoadingScreen(was_running_idle);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state_data_size == 0)
|
if (data.empty())
|
||||||
{
|
{
|
||||||
// reset runtime, no data (state might've been created without cheevos)
|
// reset runtime, no data (state might've been created without cheevos)
|
||||||
Console.Warning("State is missing cheevos data, resetting runtime");
|
Console.Warning("State is missing cheevos data, resetting runtime");
|
||||||
|
@ -1513,7 +1515,7 @@ void Achievements::LoadState(const u8* state_data, u32 state_data_size)
|
||||||
|
|
||||||
// These routines scare me a bit.. the data isn't bounds checked.
|
// These routines scare me a bit.. the data isn't bounds checked.
|
||||||
// Really hope that nobody puts any thing malicious in a save state...
|
// Really hope that nobody puts any thing malicious in a save state...
|
||||||
const int result = rc_client_deserialize_progress(s_client, state_data);
|
const int result = rc_client_deserialize_progress_sized(s_client, data.data(), data.size());
|
||||||
if (result != RC_OK)
|
if (result != RC_OK)
|
||||||
{
|
{
|
||||||
Console.Warning("Failed to deserialize cheevos state (%d), resetting", result);
|
Console.Warning("Failed to deserialize cheevos state (%d), resetting", result);
|
||||||
|
@ -1521,10 +1523,8 @@ void Achievements::LoadState(const u8* state_data, u32 state_data_size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<u8> Achievements::SaveState()
|
void Achievements::SaveState(SaveStateBase& writer)
|
||||||
{
|
{
|
||||||
std::vector<u8> ret;
|
|
||||||
|
|
||||||
const auto lock = GetLock();
|
const auto lock = GetLock();
|
||||||
|
|
||||||
#ifdef ENABLE_RAINTEGRATION
|
#ifdef ENABLE_RAINTEGRATION
|
||||||
|
@ -1533,16 +1533,18 @@ std::vector<u8> Achievements::SaveState()
|
||||||
const int size = RA_CaptureState(nullptr, 0);
|
const int size = RA_CaptureState(nullptr, 0);
|
||||||
|
|
||||||
const u32 data_size = (size >= 0) ? static_cast<u32>(size) : 0;
|
const u32 data_size = (size >= 0) ? static_cast<u32>(size) : 0;
|
||||||
ret.resize(data_size);
|
if (data_size > 0)
|
||||||
|
|
||||||
const int result = RA_CaptureState(reinterpret_cast<char*>(ret.data()), static_cast<int>(data_size));
|
|
||||||
if (result != static_cast<int>(data_size))
|
|
||||||
{
|
{
|
||||||
Console.Warning("Failed to serialize cheevos state from RAIntegration.");
|
writer.PrepBlock(static_cast<int>(data_size));
|
||||||
ret.clear();
|
|
||||||
|
const int result = RA_CaptureState(reinterpret_cast<char*>(writer.GetBlockPtr()), static_cast<int>(data_size));
|
||||||
|
if (result != static_cast<int>(data_size))
|
||||||
|
Console.Warning("Failed to serialize cheevos state from RAIntegration.");
|
||||||
|
else
|
||||||
|
writer.CommitBlock(static_cast<int>(data_size));
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1550,18 +1552,17 @@ std::vector<u8> Achievements::SaveState()
|
||||||
{
|
{
|
||||||
// internally this happens twice.. not great.
|
// internally this happens twice.. not great.
|
||||||
const size_t data_size = rc_client_progress_size(s_client);
|
const size_t data_size = rc_client_progress_size(s_client);
|
||||||
ret.resize(data_size);
|
if (data_size > 0)
|
||||||
|
|
||||||
const int result = rc_client_serialize_progress(s_client, ret.data());
|
|
||||||
if (result != RC_OK)
|
|
||||||
{
|
{
|
||||||
// set data to zero, effectively serializing nothing
|
writer.PrepBlock(static_cast<int>(data_size));
|
||||||
Console.Warning("Failed to serialize cheevos state (%d)", result);
|
|
||||||
ret.clear();
|
const int result = rc_client_serialize_progress_sized(s_client, writer.GetBlockPtr(), data_size);
|
||||||
|
if (result != RC_OK)
|
||||||
|
Console.Warning("Failed to serialize cheevos state (%d)", result);
|
||||||
|
else
|
||||||
|
writer.CommitBlock(static_cast<int>(data_size));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -9,12 +9,15 @@
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include <span>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
class Error;
|
class Error;
|
||||||
|
|
||||||
|
class SaveStateBase;
|
||||||
|
|
||||||
namespace Achievements
|
namespace Achievements
|
||||||
{
|
{
|
||||||
enum class LoginRequestReason
|
enum class LoginRequestReason
|
||||||
|
@ -51,8 +54,8 @@ namespace Achievements
|
||||||
void IdleUpdate();
|
void IdleUpdate();
|
||||||
|
|
||||||
/// Saves/loads state.
|
/// Saves/loads state.
|
||||||
void LoadState(const u8* state_data, u32 state_data_size);
|
void LoadState(std::span<const u8> data);
|
||||||
std::vector<u8> SaveState();
|
void SaveState(SaveStateBase& writer);
|
||||||
|
|
||||||
/// Attempts to log in to RetroAchievements using the specified credentials.
|
/// Attempts to log in to RetroAchievements using the specified credentials.
|
||||||
/// If the login is successful, the token returned by the server will be saved.
|
/// If the login is successful, the token returned by the server will be saved.
|
||||||
|
|
|
@ -656,10 +656,10 @@ class SaveStateEntry_Achievements final : public BaseSavestateEntry
|
||||||
if (zf)
|
if (zf)
|
||||||
data = ReadBinaryFileInZip(zf);
|
data = ReadBinaryFileInZip(zf);
|
||||||
|
|
||||||
if (data.has_value() && !data->empty())
|
if (data.has_value())
|
||||||
Achievements::LoadState(data->data(), data->size());
|
Achievements::LoadState(data.value());
|
||||||
else
|
else
|
||||||
Achievements::LoadState(nullptr, 0);
|
Achievements::LoadState(std::span<const u8>());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -669,14 +669,7 @@ class SaveStateEntry_Achievements final : public BaseSavestateEntry
|
||||||
if (!Achievements::IsActive())
|
if (!Achievements::IsActive())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
std::vector<u8> data(Achievements::SaveState());
|
Achievements::SaveState(writer);
|
||||||
if (!data.empty())
|
|
||||||
{
|
|
||||||
writer.PrepBlock(static_cast<int>(data.size()));
|
|
||||||
std::memcpy(writer.GetBlockPtr(), data.data(), data.size());
|
|
||||||
writer.CommitBlock(static_cast<int>(data.size()));
|
|
||||||
}
|
|
||||||
|
|
||||||
return writer.IsOkay();
|
return writer.IsOkay();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue