Fix chainloading for all apps

This commit is contained in:
PabloMK7 2022-10-23 22:55:50 +02:00
parent d396944487
commit fd7ada2a9c
3 changed files with 29 additions and 23 deletions

View file

@ -576,23 +576,11 @@ void System::Reset() {
deliver_arg = apt->GetAppletManager()->ReceiveDeliverArg(); deliver_arg = apt->GetAppletManager()->ReceiveDeliverArg();
} }
bool was_self_delete_pending = self_delete_pending;
Shutdown(); Shutdown();
// Self updating apps may launch themselves after the update, if that's the case if (!m_chainloadpath.empty()) {
// find the new path to launch. m_filepath = m_chainloadpath;
if (was_self_delete_pending) { m_chainloadpath.clear();
// 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;
}
}
} }
// Reload the system with the same setting // Reload the system with the same setting

View file

@ -125,7 +125,8 @@ public:
bool SendSignal(Signal signal, u32 param = 0); bool SendSignal(Signal signal, u32 param = 0);
/// Request reset of the system /// Request reset of the system
void RequestReset() { void RequestReset(const std::string& chainload = "") {
m_chainloadpath = chainload;
SendSignal(Signal::Reset); SendSignal(Signal::Reset);
} }
@ -382,6 +383,7 @@ private:
/// Saved variables for reset /// Saved variables for reset
Frontend::EmuWindow* m_emu_window; Frontend::EmuWindow* m_emu_window;
std::string m_filepath; std::string m_filepath;
std::string m_chainloadpath;
u64 title_id; u64 title_id;
bool self_delete_pending; bool self_delete_pending;

View file

@ -5,6 +5,7 @@
#include "common/common_paths.h" #include "common/common_paths.h"
#include "core/core.h" #include "core/core.h"
#include "core/hle/applets/applet.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/applet_manager.h"
#include "core/hle/service/apt/errors.h" #include "core/hle/service/apt/errors.h"
#include "core/hle/service/apt/ns.h" #include "core/hle/service/apt/ns.h"
@ -527,17 +528,31 @@ ResultCode AppletManager::DoApplicationJump(DeliverArg arg) {
// prompts it to call GetProgramIdOnApplicationJump and // prompts it to call GetProgramIdOnApplicationJump and
// PrepareToStartApplication/StartApplication on the title to launch. // 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. // 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 // 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 // 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 // installed titles since we have no way of getting the file path of an arbitrary game dump
// based only on the title id. // based only on the title id.
system.RequestReset();
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; return RESULT_SUCCESS;
} }
system.RequestReset(new_path);
return RESULT_SUCCESS;
// Launch the title directly. // 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 = auto process =
NS::LaunchTitle(app_jump_parameters.next_media_type, app_jump_parameters.next_title_id); NS::LaunchTitle(app_jump_parameters.next_media_type, app_jump_parameters.next_title_id);
if (!process) { if (!process) {
@ -545,6 +560,7 @@ ResultCode AppletManager::DoApplicationJump(DeliverArg arg) {
system.RequestShutdown(); system.RequestShutdown();
} }
return RESULT_SUCCESS; return RESULT_SUCCESS;
*/
} }
void AppletManager::EnsureHomeMenuLoaded() { void AppletManager::EnsureHomeMenuLoaded() {