From e3b6f7a3585eb9a45cbc1adc2370f29819a5e4bd Mon Sep 17 00:00:00 2001 From: Maufeat Date: Sun, 23 Aug 2026 12:14:38 +0200 Subject: [PATCH] fix filepath when launching another program index --- src/core/core.cpp | 13 +++++++++++++ src/core/core.h | 3 +++ .../am/service/application_functions.cpp | 17 +++++++++-------- src/yuzu/main_window.cpp | 17 ++++++++++++++++- 4 files changed, 41 insertions(+), 9 deletions(-) diff --git a/src/core/core.cpp b/src/core/core.cpp index 4356bc2e28..f5dc5e86c7 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -295,6 +296,8 @@ struct System::Impl { SystemResultStatus Load(System& system, Frontend::EmuWindow& emu_window, const std::string& filepath, Service::AM::FrontendAppletParameters& params) { InitializeKernel(system); + system.SetCurrentApplicationFilePath(filepath); + const auto file = GetGameFileFromPath(virtual_filesystem, filepath); // Create the application process @@ -489,6 +492,8 @@ struct System::Impl { std::array dynarmic_ticks{}; std::array build_id{}; + std::string current_application_filepath; + /// Service manager std::shared_ptr service_manager; /// ContentProviderUnion instance @@ -929,6 +934,14 @@ void System::ExecuteProgram(std::size_t program_index) { } } +const std::string& System::GetCurrentApplicationFilePath() const { + return impl->current_application_filepath; +} + +void System::SetCurrentApplicationFilePath(const std::string& filepath) { + impl->current_application_filepath = filepath; +} + /// @brief Gets a reference to the user channel stack. /// It is used to transfer data between programs. std::vector>& System::GetUserChannel() { diff --git a/src/core/core.h b/src/core/core.h index c6c0b810ac..7ad8d8f1fa 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -427,6 +427,9 @@ public: bool TryPopGeneralChannel(std::vector& out_data); [[nodiscard]] Service::Event& GetGeneralChannelEvent(); + [[nodiscard]] const std::string& GetCurrentApplicationFilePath() const; + void SetCurrentApplicationFilePath(const std::string& filepath); + /// Type used for the frontend to designate a callback for System to exit the application. using ExitCallback = std::function; diff --git a/src/core/hle/service/am/service/application_functions.cpp b/src/core/hle/service/am/service/application_functions.cpp index 25a666233f..ee1fddf2ef 100644 --- a/src/core/hle/service/am/service/application_functions.cpp +++ b/src/core/hle/service/am/service/application_functions.cpp @@ -150,7 +150,7 @@ Result IApplicationFunctions::EnsureSaveData(Out out_size, Common::UUID use Result IApplicationFunctions::GetDesiredLanguage(Out out_language_code) { // FIXME: all of this stuff belongs to ns // TODO(bunnei): This should be configurable - LOG_DEBUG(Service_AM, "called"); + LOG_DEBUG(Service_AM, "called, program_id={:016X}", m_applet->program_id); // Get supported languages from NACP, if possible // Default to 0 (all languages supported) @@ -430,15 +430,16 @@ Result IApplicationFunctions::ExecuteProgram(ProgramSpecifyKind kind, u64 value) // https://switchbrew.org/wiki/Applet_Manager_services#CreateApplicationAndRequestToStart Result IApplicationFunctions::CreateApplicationAndRequestToStart(u64 application_id) { - LOG_INFO(Service_AM, "called, application_id={:016X}", application_id); + LOG_INFO(Service_AM, "called, application_id={:016X} current_program_id={:016X}", application_id, m_applet->program_id); - // If application_id is 0, relaunch the current application - const u64 target_application_id = - (application_id == 0) ? m_applet->program_id : application_id; + // If application_id is 0 or matches the current application, relaunch the current application. + if (application_id == 0 || application_id == m_applet->program_id) { + system.GetUserChannel() = m_applet->user_channel_launch_parameter; + system.ExecuteProgram(0); + R_SUCCEED(); + } - system.GetUserChannel() = m_applet->user_channel_launch_parameter; - system.ExecuteProgram(target_application_id); - R_SUCCEED(); + R_THROW(ResultUnknown); } Result IApplicationFunctions::ClearUserChannel() { diff --git a/src/yuzu/main_window.cpp b/src/yuzu/main_window.cpp index babdc1a32d..f605742ebf 100644 --- a/src/yuzu/main_window.cpp +++ b/src/yuzu/main_window.cpp @@ -3086,12 +3086,27 @@ void MainWindow::OnLoadComplete() { } void MainWindow::OnExecuteProgram(std::size_t program_index) { + const u64 previous_program_id = QtCommon::system->GetApplicationProcessProgramID(); + + LOG_INFO(Frontend, "ExecuteProgram requested, program_index={} previous_program_id={:016X}", + program_index, previous_program_id); + ShutdownGame(); auto params = ApplicationAppletParameters(); params.program_index = static_cast(program_index); params.launch_type = Service::AM::LaunchType::ApplicationInitiated; - BootGame(last_filename_booted, params); + if (previous_program_id != 0) { + params.previous_program_index = static_cast(previous_program_id & 0xFFF); + } + + const auto& current_path = QtCommon::system->GetCurrentApplicationFilePath(); + const auto filename = current_path.empty() ? last_filename_booted + : QString::fromStdString(current_path); + + LOG_DEBUG(Frontend, "ExecuteProgram booting from path: {}", filename.toStdString()); + + BootGame(filename, params); } void MainWindow::OnExit() {