mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-25 23:25:41 +00:00
System: Include cheevos state in save states
This commit is contained in:
parent
584525cb11
commit
a55b5022c7
|
@ -188,6 +188,18 @@ public:
|
||||||
Do(data);
|
Do(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SkipBytes(size_t count)
|
||||||
|
{
|
||||||
|
if (m_mode != Mode::Read)
|
||||||
|
{
|
||||||
|
m_error = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_error)
|
||||||
|
m_error = !m_stream->SeekRelative(static_cast<s64>(count));
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ByteStream* m_stream;
|
ByteStream* m_stream;
|
||||||
Mode m_mode;
|
Mode m_mode;
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "common/log.h"
|
#include "common/log.h"
|
||||||
#include "common/md5_digest.h"
|
#include "common/md5_digest.h"
|
||||||
#include "common/platform.h"
|
#include "common/platform.h"
|
||||||
|
#include "common/state_wrapper.h"
|
||||||
#include "common/string_util.h"
|
#include "common/string_util.h"
|
||||||
#include "common/timestamp.h"
|
#include "common/timestamp.h"
|
||||||
#include "core/bios.h"
|
#include "core/bios.h"
|
||||||
|
@ -310,6 +311,69 @@ void Update()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DoState(StateWrapper& sw)
|
||||||
|
{
|
||||||
|
// if we're inactive, we still need to skip the data (if any)
|
||||||
|
if (!g_active)
|
||||||
|
{
|
||||||
|
u32 data_size = 0;
|
||||||
|
sw.Do(&data_size);
|
||||||
|
if (data_size > 0)
|
||||||
|
sw.SkipBytes(data_size);
|
||||||
|
|
||||||
|
return !sw.HasError();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sw.IsReading())
|
||||||
|
{
|
||||||
|
u32 data_size = 0;
|
||||||
|
sw.Do(&data_size);
|
||||||
|
if (data_size == 0)
|
||||||
|
{
|
||||||
|
// reset runtime, no data (state might've been created without cheevos)
|
||||||
|
Log_DevPrintf("State is missing cheevos data, resetting runtime");
|
||||||
|
rc_runtime_reset(&s_rcheevos_runtime);
|
||||||
|
return !sw.HasError();
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::unique_ptr<u8[]> data(new u8[data_size]);
|
||||||
|
sw.DoBytes(data.get(), data_size);
|
||||||
|
if (sw.HasError())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const int result = rc_runtime_deserialize_progress(&s_rcheevos_runtime, data.get(), nullptr);
|
||||||
|
if (result != RC_OK)
|
||||||
|
{
|
||||||
|
Log_WarningPrintf("Failed to deserialize cheevos state (%d), resetting", result);
|
||||||
|
rc_runtime_reset(&s_rcheevos_runtime);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// internally this happens twice.. not great.
|
||||||
|
const int size = rc_runtime_progress_size(&s_rcheevos_runtime, nullptr);
|
||||||
|
|
||||||
|
u32 data_size = (size >= 0) ? static_cast<u32>(size) : 0;
|
||||||
|
std::unique_ptr<u8[]> data(new u8[data_size]);
|
||||||
|
|
||||||
|
const int result = rc_runtime_serialize_progress(data.get(), &s_rcheevos_runtime, nullptr);
|
||||||
|
if (result != RC_OK)
|
||||||
|
{
|
||||||
|
// set data to zero, effectively serializing nothing
|
||||||
|
Log_WarningPrintf("Failed to serialize cheevos state (%d)", result);
|
||||||
|
data_size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
sw.Do(&data_size);
|
||||||
|
if (data_size > 0)
|
||||||
|
sw.DoBytes(data.get(), data_size);
|
||||||
|
|
||||||
|
return !sw.HasError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool IsLoggedIn()
|
bool IsLoggedIn()
|
||||||
{
|
{
|
||||||
return s_logged_in;
|
return s_logged_in;
|
||||||
|
@ -410,8 +474,8 @@ bool LoginAsync(const char* username, const char* password)
|
||||||
if (ImGuiFullscreen::IsInitialized())
|
if (ImGuiFullscreen::IsInitialized())
|
||||||
{
|
{
|
||||||
ImGuiFullscreen::OpenBackgroundProgressDialog(
|
ImGuiFullscreen::OpenBackgroundProgressDialog(
|
||||||
"cheevos_async_login", g_host_interface->TranslateStdString("Cheevos", "Logging in to RetroAchivements..."), 0,
|
"cheevos_async_login", g_host_interface->TranslateStdString("Cheevos", "Logging in to RetroAchivements..."), 0, 1,
|
||||||
1, 0);
|
0);
|
||||||
}
|
}
|
||||||
|
|
||||||
SendLogin(username, password, s_http_downloader.get(), LoginASyncCallback);
|
SendLogin(username, password, s_http_downloader.get(), LoginASyncCallback);
|
||||||
|
@ -545,8 +609,8 @@ static std::string GetBadgeImageFilename(const char* badge_name, bool locked, bo
|
||||||
SmallString clean_name(badge_name);
|
SmallString clean_name(badge_name);
|
||||||
FileSystem::SanitizeFileName(clean_name);
|
FileSystem::SanitizeFileName(clean_name);
|
||||||
return g_host_interface->GetUserDirectoryRelativePath("cache" FS_OSPATH_SEPARATOR_STR
|
return g_host_interface->GetUserDirectoryRelativePath("cache" FS_OSPATH_SEPARATOR_STR
|
||||||
"achievement_badge" FS_OSPATH_SEPARATOR_STR "%s%s.png",
|
"achievement_badge" FS_OSPATH_SEPARATOR_STR "%s%s.png",
|
||||||
clean_name.GetCharArray(), locked ? "_lock" : "");
|
clean_name.GetCharArray(), locked ? "_lock" : "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1019,9 +1083,9 @@ void GameChanged(const std::string& path, CDImage* image)
|
||||||
|
|
||||||
if (s_game_hash.empty())
|
if (s_game_hash.empty())
|
||||||
{
|
{
|
||||||
g_host_interface->AddOSDMessage(g_host_interface->TranslateStdString(
|
g_host_interface->AddOSDMessage(
|
||||||
"OSDMessage", "Failed to read executable from disc. Achievements disabled."),
|
g_host_interface->TranslateStdString("OSDMessage", "Failed to read executable from disc. Achievements disabled."),
|
||||||
10.0f);
|
10.0f);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
class CDImage;
|
class CDImage;
|
||||||
|
class StateWrapper;
|
||||||
|
|
||||||
namespace Cheevos {
|
namespace Cheevos {
|
||||||
|
|
||||||
|
@ -79,7 +80,9 @@ bool Initialize(bool test_mode, bool use_first_disc_from_playlist, bool enable_r
|
||||||
bool include_unofficial);
|
bool include_unofficial);
|
||||||
void Reset();
|
void Reset();
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
|
|
||||||
void Update();
|
void Update();
|
||||||
|
bool DoState(StateWrapper& sw);
|
||||||
|
|
||||||
bool IsLoggedIn();
|
bool IsLoggedIn();
|
||||||
bool IsTestModeActive();
|
bool IsTestModeActive();
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
static constexpr u32 SAVE_STATE_MAGIC = 0x43435544;
|
static constexpr u32 SAVE_STATE_MAGIC = 0x43435544;
|
||||||
static constexpr u32 SAVE_STATE_VERSION = 55;
|
static constexpr u32 SAVE_STATE_VERSION = 56;
|
||||||
static constexpr u32 SAVE_STATE_MINIMUM_VERSION = 42;
|
static constexpr u32 SAVE_STATE_MINIMUM_VERSION = 42;
|
||||||
|
|
||||||
static_assert(SAVE_STATE_VERSION >= SAVE_STATE_MINIMUM_VERSION);
|
static_assert(SAVE_STATE_VERSION >= SAVE_STATE_MINIMUM_VERSION);
|
||||||
|
|
|
@ -45,6 +45,10 @@
|
||||||
#include <thread>
|
#include <thread>
|
||||||
Log_SetChannel(System);
|
Log_SetChannel(System);
|
||||||
|
|
||||||
|
#ifdef WITH_CHEEVOS
|
||||||
|
#include "cheevos.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
// #define PROFILE_MEMORY_SAVE_STATES 1
|
// #define PROFILE_MEMORY_SAVE_STATES 1
|
||||||
|
|
||||||
SystemBootParameters::SystemBootParameters() = default;
|
SystemBootParameters::SystemBootParameters() = default;
|
||||||
|
@ -71,7 +75,8 @@ static bool LoadEXE(const char* filename);
|
||||||
/// Opens CD image, preloading if needed.
|
/// Opens CD image, preloading if needed.
|
||||||
static std::unique_ptr<CDImage> OpenCDImage(const char* path, Common::Error* error, bool force_preload,
|
static std::unique_ptr<CDImage> OpenCDImage(const char* path, Common::Error* error, bool force_preload,
|
||||||
bool check_for_patches);
|
bool check_for_patches);
|
||||||
static bool ReadExecutableFromImage(ISOReader& iso, std::string* out_executable_name, std::vector<u8>* out_executable_data);
|
static bool ReadExecutableFromImage(ISOReader& iso, std::string* out_executable_name,
|
||||||
|
std::vector<u8>* out_executable_data);
|
||||||
static bool ShouldCheckForImagePatches();
|
static bool ShouldCheckForImagePatches();
|
||||||
|
|
||||||
static bool DoLoadState(ByteStream* stream, bool force_software_renderer, bool update_display);
|
static bool DoLoadState(ByteStream* stream, bool force_software_renderer, bool update_display);
|
||||||
|
@ -1142,6 +1147,33 @@ bool DoState(StateWrapper& sw, HostDisplayTexture** host_texture, bool update_di
|
||||||
UpdateOverclock();
|
UpdateOverclock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!is_memory_state)
|
||||||
|
{
|
||||||
|
if (sw.GetVersion() >= 56)
|
||||||
|
{
|
||||||
|
if (!sw.DoMarker("Cheevos"))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
#ifdef WITH_CHEEVOS
|
||||||
|
if (!Cheevos::DoState(sw))
|
||||||
|
return false;
|
||||||
|
#else
|
||||||
|
// if we compiled without cheevos, we need to toss out the data from states which were
|
||||||
|
u32 data_size = 0;
|
||||||
|
sw.Do(&data_size);
|
||||||
|
if (data_size > 0)
|
||||||
|
sw.SkipBytes(data_size);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifdef WITH_CHEEVOS
|
||||||
|
// loading an old state without cheevos, so reset the runtime
|
||||||
|
Cheevos::Reset();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return !sw.HasError();
|
return !sw.HasError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1172,6 +1204,10 @@ void Reset()
|
||||||
TimingEvents::Reset();
|
TimingEvents::Reset();
|
||||||
ResetPerformanceCounters();
|
ResetPerformanceCounters();
|
||||||
|
|
||||||
|
#ifdef WITH_CHEEVOS
|
||||||
|
Cheevos::Reset();
|
||||||
|
#endif
|
||||||
|
|
||||||
g_gpu->ResetGraphicsAPIState();
|
g_gpu->ResetGraphicsAPIState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -250,10 +250,6 @@ void CommonHostInterface::PowerOffSystem(bool save_resume_state)
|
||||||
void CommonHostInterface::ResetSystem()
|
void CommonHostInterface::ResetSystem()
|
||||||
{
|
{
|
||||||
HostInterface::ResetSystem();
|
HostInterface::ResetSystem();
|
||||||
|
|
||||||
#ifdef WITH_CHEEVOS
|
|
||||||
Cheevos::Reset();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void PrintCommandLineVersion(const char* frontend_name)
|
static void PrintCommandLineVersion(const char* frontend_name)
|
||||||
|
@ -768,10 +764,6 @@ bool CommonHostInterface::UndoLoadState()
|
||||||
System::ResetPerformanceCounters();
|
System::ResetPerformanceCounters();
|
||||||
System::ResetThrottler();
|
System::ResetThrottler();
|
||||||
|
|
||||||
#ifdef WITH_CHEEVOS
|
|
||||||
Cheevos::Reset();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Log_InfoPrintf("Loaded undo save state.");
|
Log_InfoPrintf("Loaded undo save state.");
|
||||||
m_undo_load_state.reset();
|
m_undo_load_state.reset();
|
||||||
return true;
|
return true;
|
||||||
|
|
Loading…
Reference in a new issue