diff --git a/rpcs3/Emu/savestate_utils.cpp b/rpcs3/Emu/savestate_utils.cpp index 122e7b16c5..9252ecf807 100644 --- a/rpcs3/Emu/savestate_utils.cpp +++ b/rpcs3/Emu/savestate_utils.cpp @@ -19,6 +19,7 @@ LOG_CHANNEL(sys_log, "SYS"); struct serial_ver_t { + std::string ver_name; bool used = false; u16 current_version = 0; std::set compatible_versions; @@ -28,7 +29,7 @@ static std::array s_serial_versions; #define SERIALIZATION_VER(name, identifier, ...) \ \ - const bool s_##name##_serialization_fill = []() { if (::s_serial_versions[identifier].compatible_versions.empty()) ::s_serial_versions[identifier].compatible_versions = {__VA_ARGS__}; return true; }();\ + const bool s_##name##_serialization_fill = []() { auto& e = ::s_serial_versions[identifier]; if (e.compatible_versions.empty()) { e.compatible_versions = {__VA_ARGS__}; e.ver_name = #name; } return true; }();\ \ extern void using_##name##_serialization()\ {\ @@ -85,6 +86,32 @@ SERIALIZATION_VER(sys_io, 23, 2) SERIALIZATION_VER(LLE, 24, 1) SERIALIZATION_VER(HLE, 25, 1) +template <> +void fmt_class_string>::format(std::string& out, u64 arg) +{ + bool is_first = true; + + const auto& serials = get_object(arg); + + out += "{ "; + + for (auto& entry : serials) + { + if (entry.current_version) + { + if (!is_first) + { + out += ", "; + } + + is_first = false; + fmt::append(out, "%s=%d", entry.ver_name, entry.current_version); + } + } + + out += " }"; +} + std::vector get_savestate_versioning_data(fs::file&& file, std::string_view filepath) { if (!file) @@ -132,16 +159,27 @@ bool is_savestate_version_compatible(const std::vector& data, boo bool ok = true; + if (is_boot_check) + { + for (auto& entry : s_serial_versions) + { + // Version 0 means that the entire constructor using the version should be skipped + entry.current_version = 0; + } + } + + auto& channel = (is_boot_check ? sys_log.error : sys_log.trace); + for (auto [identifier, version] : data) { if (identifier >= s_serial_versions.size()) { - (is_boot_check ? sys_log.error : sys_log.trace)("Savestate version identifier is unknown! (category=%u, version=%u)", identifier, version); + channel("Savestate version identifier is unknown! (category=%u, version=%u)", identifier, version); ok = false; // Log all mismatches } else if (!s_serial_versions[identifier].compatible_versions.count(version)) { - (is_boot_check ? sys_log.error : sys_log.trace)("Savestate version is not supported. (category=%u, version=%u)", identifier, version); + channel("Savestate version is not supported. (category=%u, version=%u)", identifier, version); ok = false; } else if (is_boot_check) @@ -150,11 +188,18 @@ bool is_savestate_version_compatible(const std::vector& data, boo } } - if (!ok && is_boot_check) + if (is_boot_check) { - for (auto [identifier, _] : data) + if (ok) { - s_serial_versions[identifier].current_version = 0; + sys_log.success("Savestate versions: %s", s_serial_versions); + } + else + { + for (auto [identifier, _] : data) + { + s_serial_versions[identifier].current_version = 0; + } } }