From e209dc1229459fe11bc5715a121d95ae096bb9b0 Mon Sep 17 00:00:00 2001 From: Eladash <18193363+elad335@users.noreply.github.com> Date: Thu, 28 Dec 2023 22:30:05 +0200 Subject: [PATCH] Savestates: Save build version and creation time --- rpcs3/Emu/System.cpp | 41 ++++++++++++++++++++++++++++++++++++++--- rpcs3/rpcs3_version.h | 2 +- rpcs3/util/types.hpp | 2 ++ 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index 25188e124f..75d9096c5f 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -36,6 +36,8 @@ #include "Loader/ELF.h" #include "Loader/disc.h" +#include "rpcs3_version.h" + #include "Utilities/StrUtil.h" #include "../Crypto/unself.h" @@ -964,6 +966,10 @@ game_boot_result Emulator::Load(const std::string& title_id, bool is_disc_patch, const bool from_dev_flash = IsPathInsideDir(m_path, g_cfg_vfs.get_dev_flash()); + std::string savestate_build_version; + std::string savestate_creation_date; + std::string savestate_app_title; + if (m_ar) { struct file_header @@ -991,13 +997,15 @@ game_boot_result Emulator::Load(const std::string& title_id, bool is_disc_patch, g_cfg.savestate.state_inspection_mode.set(header.state_inspection_support); + bool is_incompatible = false; + if (header.flag_versions_is_following_data) { ensure(header.offset == m_ar->pos); if (!is_savestate_version_compatible(m_ar->pop>(), true)) { - return game_boot_result::savestate_version_unsupported; + is_incompatible = true; } } else @@ -1010,14 +1018,35 @@ game_boot_result Emulator::Load(const std::string& title_id, bool is_disc_patch, if (!is_savestate_version_compatible(ar_temp.pop>(), true)) { - return game_boot_result::savestate_version_unsupported; + is_incompatible = true; } // Restore file handler ar_temp.swap_handler(*m_ar); } - if (!load_and_check_reserved(*m_ar, header.flag_versions_is_following_data ? 32 : 31)) + const bool contains_version = m_ar->pop(); + + if (contains_version) + { + savestate_build_version = m_ar->pop(); + savestate_creation_date = m_ar->pop(); + savestate_app_title = m_ar->pop(); + m_ar->pop(); // User note (unused) + + (is_incompatible ? sys_log.error : sys_log.success)("Savestate information: creation time: %s, RPCS3 build: \"%s\"\nGame/Title: \"%s\"", savestate_creation_date, savestate_build_version, savestate_app_title); + } + + if (is_incompatible) + { + return game_boot_result::savestate_version_unsupported; + } + + usz reserved_count = 32; + reserved_count -= (header.flag_versions_is_following_data ? 0 : 1); + reserved_count -= (contains_version ? 0 : 1); + + if (!load_and_check_reserved(*m_ar, reserved_count)) { return game_boot_result::savestate_version_unsupported; } @@ -3081,6 +3110,12 @@ void Emulator::Kill(bool allow_autoexit, bool savestate, savestate_stage* save_s ar(read_used_savestate_versions()); } + ar(u8{1}); + ar(rpcs3::get_verbose_version()); + ar(fmt::format("%s", std::chrono::system_clock::now())); + ar(GetTitleAndTitleID()); + ar(std::string{}); // Possible user note + ar(std::array{}); // Reserved for future use if (auto dir = vfs::get("/dev_bdvd/PS3_GAME"); fs::is_dir(dir) && !fs::is_file(fs::get_parent_dir(dir) + "/PS3_DISC.SFB")) diff --git a/rpcs3/rpcs3_version.h b/rpcs3/rpcs3_version.h index 099afa8dda..4cb0c20597 100644 --- a/rpcs3/rpcs3_version.h +++ b/rpcs3/rpcs3_version.h @@ -7,7 +7,7 @@ namespace rpcs3 std::string_view get_branch(); std::string_view get_full_branch(); std::pair get_commit_and_hash(); - const utils::version& get_version(); + const ::utils::version& get_version(); std::string get_version_and_branch(); std::string get_verbose_version(); bool is_release_build(); diff --git a/rpcs3/util/types.hpp b/rpcs3/util/types.hpp index 8194962566..d3e8e7a8bb 100644 --- a/rpcs3/util/types.hpp +++ b/rpcs3/util/types.hpp @@ -219,6 +219,8 @@ class b8 public: b8() = default; + using enable_bitcopy = std::true_type; + constexpr b8(bool value) noexcept : m_value(value) {