From fd7ada2a9c7cff006a2b0e01c57488114f0ec4ef Mon Sep 17 00:00:00 2001 From: PabloMK7 Date: Sun, 23 Oct 2022 22:55:50 +0200 Subject: [PATCH] Fix chainloading for all apps --- src/core/core.cpp | 18 +++---------- src/core/core.h | 4 ++- src/core/hle/service/apt/applet_manager.cpp | 30 ++++++++++++++++----- 3 files changed, 29 insertions(+), 23 deletions(-) diff --git a/src/core/core.cpp b/src/core/core.cpp index 7c4f557b8..accf52e4f 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -576,23 +576,11 @@ void System::Reset() { deliver_arg = apt->GetAppletManager()->ReceiveDeliverArg(); } - bool was_self_delete_pending = self_delete_pending; - Shutdown(); - // Self updating apps may launch themselves after the update, if that's the case - // find the new path to launch. - if (was_self_delete_pending) { - // TODO: We can get the title id, but not the MediaType, so we - // check both NAND and SDMC mediatypes. - m_filepath = Service::AM::GetTitleContentPath(Service::FS::MediaType::NAND, title_id); - if (m_filepath.empty() || !FileUtil::Exists(m_filepath)) { - m_filepath = Service::AM::GetTitleContentPath(Service::FS::MediaType::SDMC, title_id); - if (m_filepath.empty() || !FileUtil::Exists(m_filepath)) { - LOG_CRITICAL(Core, "Failed to get application path for system reset"); - return; - } - } + if (!m_chainloadpath.empty()) { + m_filepath = m_chainloadpath; + m_chainloadpath.clear(); } // Reload the system with the same setting diff --git a/src/core/core.h b/src/core/core.h index b8e80f9f9..146470e26 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -125,7 +125,8 @@ public: bool SendSignal(Signal signal, u32 param = 0); /// Request reset of the system - void RequestReset() { + void RequestReset(const std::string& chainload = "") { + m_chainloadpath = chainload; SendSignal(Signal::Reset); } @@ -382,6 +383,7 @@ private: /// Saved variables for reset Frontend::EmuWindow* m_emu_window; std::string m_filepath; + std::string m_chainloadpath; u64 title_id; bool self_delete_pending; diff --git a/src/core/hle/service/apt/applet_manager.cpp b/src/core/hle/service/apt/applet_manager.cpp index b90f6248e..99b7726e3 100644 --- a/src/core/hle/service/apt/applet_manager.cpp +++ b/src/core/hle/service/apt/applet_manager.cpp @@ -5,6 +5,7 @@ #include "common/common_paths.h" #include "core/core.h" #include "core/hle/applets/applet.h" +#include "core/hle/service/am/am.h" #include "core/hle/service/apt/applet_manager.h" #include "core/hle/service/apt/errors.h" #include "core/hle/service/apt/ns.h" @@ -527,17 +528,31 @@ ResultCode AppletManager::DoApplicationJump(DeliverArg arg) { // prompts it to call GetProgramIdOnApplicationJump and // PrepareToStartApplication/StartApplication on the title to launch. - if (app_jump_parameters.next_title_id == app_jump_parameters.current_title_id) { - // Perform a soft-reset if we're trying to relaunch the same title. - // TODO(Subv): Note that this reboots the entire emulated system, a better way would be to - // simply re-launch the title without closing all services, but this would only work for - // installed titles since we have no way of getting the file path of an arbitrary game dump - // based only on the title id. - system.RequestReset(); + // Perform a soft-reset if we're trying to relaunch the same title. + // TODO(Subv): Note that this reboots the entire emulated system, a better way would be to + // simply re-launch the title without closing all services, but this would only work for + // installed titles since we have no way of getting the file path of an arbitrary game dump + // based only on the title id. + + std::string new_path = Service::AM::GetTitleContentPath(app_jump_parameters.next_media_type, + app_jump_parameters.next_title_id); + if (new_path.empty() || !FileUtil::Exists(new_path)) { + LOG_CRITICAL( + Service_APT, + "Failed to find title during application jump: {} Resetting current title instead.", + new_path); + new_path.clear(); return RESULT_SUCCESS; } + system.RequestReset(new_path); + return RESULT_SUCCESS; + // Launch the title directly. + // The emulator does not suport terminating old processes, would require a lot of cleanup + // This code is left commented for when this is implemented, for now we cannot use NS + // as the old process resources would interfere with the new ones + /* auto process = NS::LaunchTitle(app_jump_parameters.next_media_type, app_jump_parameters.next_title_id); if (!process) { @@ -545,6 +560,7 @@ ResultCode AppletManager::DoApplicationJump(DeliverArg arg) { system.RequestShutdown(); } return RESULT_SUCCESS; + */ } void AppletManager::EnsureHomeMenuLoaded() {