From 9e43e451d1b5c4d7d17559d42aaf87d2710530ee Mon Sep 17 00:00:00 2001 From: PabloMK7 Date: Fri, 19 Jun 2026 09:00:33 +0200 Subject: [PATCH] core: Implement APT:MapProgramIdForDebug (#2224) --- src/core/hle/service/apt/applet_manager.cpp | 9 +++++++++ src/core/hle/service/apt/applet_manager.h | 2 ++ src/core/hle/service/apt/apt.cpp | 22 +++++++++++++++++++++ src/core/hle/service/apt/apt.h | 2 ++ src/core/hle/service/apt/apt_a.cpp | 2 +- src/core/hle/service/apt/apt_s.cpp | 2 +- src/core/hle/service/apt/apt_u.cpp | 2 +- 7 files changed, 38 insertions(+), 3 deletions(-) diff --git a/src/core/hle/service/apt/applet_manager.cpp b/src/core/hle/service/apt/applet_manager.cpp index b459fdd1f..a6cc6f254 100644 --- a/src/core/hle/service/apt/applet_manager.cpp +++ b/src/core/hle/service/apt/applet_manager.cpp @@ -359,6 +359,15 @@ bool AppletManager::CancelParameter(bool check_sender, AppletId sender_appid, bo return cancellation_success; } +void AppletManager::MapProgramIdForDebug(AppletId app_id, u64 title_id, FS::MediaType media_type) { + auto slot = GetAppletSlotFromId(app_id); + if (slot != AppletSlot::Error) { + auto applet_slot = GetAppletSlot(slot); + applet_slot->title_id = title_id; + applet_slot->media_type = media_type; + } +} + ResultVal AppletManager::GetLockHandle( AppletAttributes attributes) { auto corrected_attributes = attributes; diff --git a/src/core/hle/service/apt/applet_manager.h b/src/core/hle/service/apt/applet_manager.h index 0def102d3..5e7f69040 100644 --- a/src/core/hle/service/apt/applet_manager.h +++ b/src/core/hle/service/apt/applet_manager.h @@ -288,6 +288,8 @@ public: bool CancelParameter(bool check_sender, AppletId sender_appid, bool check_receiver, AppletId receiver_appid); + void MapProgramIdForDebug(AppletId app_id, u64 title_id, FS::MediaType media_type); + struct GetLockHandleResult { AppletAttributes corrected_attributes; u32 state; diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp index 355f98bab..c3dc315c4 100644 --- a/src/core/hle/service/apt/apt.cpp +++ b/src/core/hle/service/apt/apt.cpp @@ -574,6 +574,28 @@ void Module::APTInterface::CancelParameter(Kernel::HLERequestContext& ctx) { receiver_appid)); } +void Module::APTInterface::MapProgramIdForDebug(Kernel::HLERequestContext& ctx) { + // This function got stubbed at some point and no longer + // does anything on real hardware. It is implemented here + // so that emulated applications can take advantage of it. + + IPC::RequestParser rp(ctx); + const auto app_id = rp.PopEnum(); + u64 title_id = rp.Pop(); + + // NOTE: Real hardware forces the media type to nand. + // To allow better control of this service call, + // treat the highest byte of the title ID as the + // media type instead. + FS::MediaType media_type = static_cast(title_id >> 56); + title_id &= ~0xFF00000000000000ULL; + + apt->applet_manager->MapProgramIdForDebug(app_id, title_id, media_type); + + IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); + rb.Push(ResultSuccess); // No error +} + void Module::APTInterface::PrepareToDoApplicationJump(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp(ctx); auto flags = rp.PopEnum(); diff --git a/src/core/hle/service/apt/apt.h b/src/core/hle/service/apt/apt.h index 3eaf5fa65..0bc4825ab 100644 --- a/src/core/hle/service/apt/apt.h +++ b/src/core/hle/service/apt/apt.h @@ -376,6 +376,8 @@ public: */ void CancelParameter(Kernel::HLERequestContext& ctx); + void MapProgramIdForDebug(Kernel::HLERequestContext& ctx); + /** * APT::PrepareToStartApplication service function. When the input title-info programID is * zero, NS will load the actual program ID via AMNet:GetTitleIDList. After doing some diff --git a/src/core/hle/service/apt/apt_a.cpp b/src/core/hle/service/apt/apt_a.cpp index 9de07a57d..ab2314983 100644 --- a/src/core/hle/service/apt/apt_a.cpp +++ b/src/core/hle/service/apt/apt_a.cpp @@ -27,7 +27,7 @@ APT_A::APT_A(std::shared_ptr apt) {0x000E, &APT_A::GlanceParameter, "GlanceParameter"}, {0x000F, &APT_A::CancelParameter, "CancelParameter"}, {0x0010, nullptr, "DebugFunc"}, - {0x0011, nullptr, "MapProgramIdForDebug"}, + {0x0011, &APT_A::MapProgramIdForDebug, "MapProgramIdForDebug"}, {0x0012, nullptr, "SetHomeMenuAppletIdForDebug"}, {0x0013, nullptr, "GetPreparationState"}, {0x0014, nullptr, "SetPreparationState"}, diff --git a/src/core/hle/service/apt/apt_s.cpp b/src/core/hle/service/apt/apt_s.cpp index a332cebf6..1ffc074c4 100644 --- a/src/core/hle/service/apt/apt_s.cpp +++ b/src/core/hle/service/apt/apt_s.cpp @@ -27,7 +27,7 @@ APT_S::APT_S(std::shared_ptr apt) {0x000E, &APT_S::GlanceParameter, "GlanceParameter"}, {0x000F, &APT_S::CancelParameter, "CancelParameter"}, {0x0010, nullptr, "DebugFunc"}, - {0x0011, nullptr, "MapProgramIdForDebug"}, + {0x0011, &APT_S::MapProgramIdForDebug, "MapProgramIdForDebug"}, {0x0012, nullptr, "SetHomeMenuAppletIdForDebug"}, {0x0013, nullptr, "GetPreparationState"}, {0x0014, nullptr, "SetPreparationState"}, diff --git a/src/core/hle/service/apt/apt_u.cpp b/src/core/hle/service/apt/apt_u.cpp index 8e1fd18c6..eb1cb5c98 100644 --- a/src/core/hle/service/apt/apt_u.cpp +++ b/src/core/hle/service/apt/apt_u.cpp @@ -27,7 +27,7 @@ APT_U::APT_U(std::shared_ptr apt) {0x000E, &APT_U::GlanceParameter, "GlanceParameter"}, {0x000F, &APT_U::CancelParameter, "CancelParameter"}, {0x0010, nullptr, "DebugFunc"}, - {0x0011, nullptr, "MapProgramIdForDebug"}, + {0x0011, &APT_U::MapProgramIdForDebug, "MapProgramIdForDebug"}, {0x0012, nullptr, "SetHomeMenuAppletIdForDebug"}, {0x0013, nullptr, "GetPreparationState"}, {0x0014, nullptr, "SetPreparationState"},