From 57696b2c11a1eb729e5111174f13d1dc3a15cf90 Mon Sep 17 00:00:00 2001 From: Steveice10 <1269164+Steveice10@users.noreply.github.com> Date: Mon, 8 Jan 2024 09:20:14 -0800 Subject: [PATCH] core: Persist plg:ldr state across resets without static state. (#7327) --- src/core/core.cpp | 28 ++++++++++++++++++-------- src/core/core.h | 6 ++++++ src/core/hle/service/plgldr/plgldr.cpp | 10 +++------ src/core/hle/service/plgldr/plgldr.h | 21 ++++++++++++------- 4 files changed, 43 insertions(+), 22 deletions(-) diff --git a/src/core/core.cpp b/src/core/core.cpp index db5096a1b..58bb0d2a3 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -296,6 +296,20 @@ System::ResultStatus System::Load(Frontend::EmuWindow& emu_window, const std::st return init_result; } + // Restore any parameters that should be carried through a reset. + if (restore_deliver_arg.has_value()) { + if (auto apt = Service::APT::GetModule(*this)) { + apt->GetAppletManager()->SetDeliverArg(restore_deliver_arg); + } + restore_deliver_arg.reset(); + } + if (restore_plugin_context.has_value()) { + if (auto plg_ldr = Service::PLGLDR::GetService(*this)) { + plg_ldr->SetPluginLoaderContext(restore_plugin_context.value()); + } + restore_plugin_context.reset(); + } + telemetry_session->AddInitialInfo(*app_loader); std::shared_ptr process; const Loader::ResultStatus load_result{app_loader->Load(process)}; @@ -608,10 +622,13 @@ void System::Reset() { // reloading. // TODO: Properly implement the reset - // Since the system is completely reinitialized, we'll have to store the deliver arg manually. - boost::optional deliver_arg; + // Save the APT deliver arg and plugin loader context across resets. + // This is needed as we don't currently support proper app jumping. if (auto apt = Service::APT::GetModule(*this)) { - deliver_arg = apt->GetAppletManager()->ReceiveDeliverArg(); + restore_deliver_arg = apt->GetAppletManager()->ReceiveDeliverArg(); + } + if (auto plg_ldr = Service::PLGLDR::GetService(*this)) { + restore_plugin_context = plg_ldr->GetPluginLoaderContext(); } Shutdown(); @@ -624,11 +641,6 @@ void System::Reset() { // Reload the system with the same setting [[maybe_unused]] const System::ResultStatus result = Load(*m_emu_window, m_filepath, m_secondary_window); - - // Restore the deliver arg. - if (auto apt = Service::APT::GetModule(*this)) { - apt->GetAppletManager()->SetDeliverArg(std::move(deliver_arg)); - } } void System::ApplySettings() { diff --git a/src/core/core.h b/src/core/core.h index 66914f7df..9f7430b72 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -8,10 +8,13 @@ #include #include #include +#include #include #include "common/common_types.h" #include "core/arm/arm_interface.h" #include "core/cheats/cheats.h" +#include "core/hle/service/apt/applet_manager.h" +#include "core/hle/service/plgldr/plgldr.h" #include "core/movie.h" #include "core/perf_stats.h" @@ -444,6 +447,9 @@ private: std::function mic_permission_func; bool mic_permission_granted = false; + boost::optional restore_deliver_arg; + boost::optional restore_plugin_context; + friend class boost::serialization::access; template void serialize(Archive& ar, const unsigned int file_version); diff --git a/src/core/hle/service/plgldr/plgldr.cpp b/src/core/hle/service/plgldr/plgldr.cpp index 376a440d3..1c1a221da 100644 --- a/src/core/hle/service/plgldr/plgldr.cpp +++ b/src/core/hle/service/plgldr/plgldr.cpp @@ -40,10 +40,6 @@ namespace Service::PLGLDR { static const Kernel::CoreVersion plgldr_version = Kernel::CoreVersion(1, 0, 0); -PLG_LDR::PluginLoaderContext PLG_LDR::plgldr_context; -bool PLG_LDR::allow_game_change = true; -PAddr PLG_LDR::plugin_fb_addr = 0; - PLG_LDR::PLG_LDR(Core::System& system_) : ServiceFramework{"plg:ldr", 1}, system(system_) { static const FunctionInfo functions[] = { // clang-format off @@ -70,6 +66,7 @@ PLG_LDR::PLG_LDR(Core::System& system_) : ServiceFramework{"plg:ldr", 1}, system template void PLG_LDR::PluginLoaderContext::serialize(Archive& ar, const unsigned int) { ar& is_enabled; + ar& allow_game_change; ar& plugin_loaded; ar& is_default_path; ar& plugin_path; @@ -82,6 +79,7 @@ void PLG_LDR::PluginLoaderContext::serialize(Archive& ar, const unsigned int) { ar& exe_load_checksum; ar& load_exe_func; ar& load_exe_args; + ar& plugin_fb_addr; } SERIALIZE_IMPL(PLG_LDR::PluginLoaderContext) @@ -89,8 +87,6 @@ template void PLG_LDR::serialize(Archive& ar, const unsigned int) { ar& boost::serialization::base_object(*this); ar& plgldr_context; - ar& plugin_fb_addr; - ar& allow_game_change; } SERIALIZE_IMPL(PLG_LDR) @@ -195,7 +191,7 @@ void PLG_LDR::SetEnabled(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp(ctx); bool enabled = rp.Pop() == 1; - bool can_change = enabled == plgldr_context.is_enabled || allow_game_change; + bool can_change = enabled == plgldr_context.is_enabled || plgldr_context.allow_game_change; if (can_change) { plgldr_context.is_enabled = enabled; Settings::values.plugin_loader_enabled.SetValue(enabled); diff --git a/src/core/hle/service/plgldr/plgldr.h b/src/core/hle/service/plgldr/plgldr.h index ecaeec7db..240324238 100644 --- a/src/core/hle/service/plgldr/plgldr.h +++ b/src/core/hle/service/plgldr/plgldr.h @@ -52,6 +52,7 @@ public: friend class boost::serialization::access; }; bool is_enabled = true; + bool allow_game_change = true; bool plugin_loaded = false; bool is_default_path = false; std::string plugin_path = ""; @@ -69,6 +70,8 @@ public: std::vector load_exe_func; u32_le load_exe_args[4] = {0}; + PAddr plugin_fb_addr = 0; + template void serialize(Archive& ar, const unsigned int); friend class boost::serialization::access; @@ -82,6 +85,12 @@ public: ResultVal GetMemoryChangedHandle(Kernel::KernelSystem& kernel); void OnMemoryChanged(Kernel::Process& process, Kernel::KernelSystem& kernel); + PluginLoaderContext& GetPluginLoaderContext() { + return plgldr_context; + } + void SetPluginLoaderContext(PluginLoaderContext& context) { + plgldr_context = context; + } void SetEnabled(bool enabled) { plgldr_context.is_enabled = enabled; } @@ -89,24 +98,22 @@ public: return plgldr_context.is_enabled; } void SetAllowGameChangeState(bool allow) { - allow_game_change = allow; + plgldr_context.allow_game_change = allow; } bool GetAllowGameChangeState() { - return allow_game_change; + return plgldr_context.allow_game_change; } void SetPluginFBAddr(PAddr addr) { - plugin_fb_addr = addr; + plgldr_context.plugin_fb_addr = addr; } PAddr GetPluginFBAddr() { - return plugin_fb_addr; + return plgldr_context.plugin_fb_addr; } private: Core::System& system; - static PluginLoaderContext plgldr_context; - static PAddr plugin_fb_addr; - static bool allow_game_change; + PluginLoaderContext plgldr_context; void IsEnabled(Kernel::HLERequestContext& ctx); void SetEnabled(Kernel::HLERequestContext& ctx);