aboutsummaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorrdenno <rhysdenno@gmail.com>2026-10-31 16:01:13 -0400
committerrdenno <rhysdenno@gmail.com>2026-10-31 16:11:26 -0400
commitdee08ca5afb80793fbe967b5a330f738f8bc41a3 (patch)
tree6908f7f0b10f30bf031452ab06960f9705776c7b /src/core
parent9dca3ab2e436e786ab53e862e4d515f620a11669 (diff)
am: map Switch 2 library applet ids to the applet in their low byte (Pokopia name entry)
Pokopia opens the software keyboard with an applet id whose low byte is 0x11 but that has extra high bits, so it got the stub applet and looped forever on its own name check. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'src/core')
-rw-r--r--src/core/hle/service/am/frontend/applets.cpp2
-rw-r--r--src/core/hle/service/am/service/library_applet_creator.cpp42
2 files changed, 43 insertions, 1 deletions
diff --git a/src/core/hle/service/am/frontend/applets.cpp b/src/core/hle/service/am/frontend/applets.cpp
index c59e4b9c6b..c1a0a1dd29 100644
--- a/src/core/hle/service/am/frontend/applets.cpp
+++ b/src/core/hle/service/am/frontend/applets.cpp
@@ -253,7 +253,7 @@ std::shared_ptr<FrontendApplet> FrontendAppletHolder::GetApplet(std::shared_ptr<
case AppletId::None:
return nullptr;
default:
- UNIMPLEMENTED_MSG("No frontend implementation exists for applet_id={:02X} program_id={:016X}! Using stub applet.", static_cast<u8>(id), applet->program_id);
+ UNIMPLEMENTED_MSG("No frontend implementation exists for applet_id={:#x} program_id={:016X}! Using stub applet.", static_cast<u32>(id), applet->program_id);
return std::make_shared<StubApplet>(system, applet, id, mode);
}
}
diff --git a/src/core/hle/service/am/service/library_applet_creator.cpp b/src/core/hle/service/am/service/library_applet_creator.cpp
index 4ee92908b5..afdb609c00 100644
--- a/src/core/hle/service/am/service/library_applet_creator.cpp
+++ b/src/core/hle/service/am/service/library_applet_creator.cpp
@@ -4,6 +4,9 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
+#include <mutex>
+#include <unordered_set>
+
#include "common/settings.h"
#include "core/hle/kernel/k_transfer_memory.h"
#include "core/hle/service/am/applet_data_broker.h"
@@ -99,6 +102,41 @@ AppletProgramId AppletIdToProgramId(AppletId applet_id) {
}
}
+AppletId NormalizeAppletId(AppletId id) {
+ const u32 raw_id = static_cast<u32>(id);
+ static std::mutex mutex;
+ static std::unordered_set<u32> logged_raw_ids;
+ static std::unordered_set<u32> warned_raw_ids;
+
+ bool log_info = false;
+ {
+ std::scoped_lock lk{mutex};
+ log_info = logged_raw_ids.insert(raw_id).second;
+ }
+ if (log_info) {
+ LOG_INFO(Service_AM, "CreateLibraryApplet called with raw applet_id={:#x}", raw_id);
+ }
+
+ if (AppletIdToProgramId(id) == static_cast<AppletProgramId>(0)) {
+ const auto low_byte = static_cast<AppletId>(raw_id & 0xFF);
+ if (AppletIdToProgramId(low_byte) != static_cast<AppletProgramId>(0)) {
+ bool log_warning = false;
+ {
+ std::scoped_lock lk{mutex};
+ log_warning = warned_raw_ids.insert(raw_id).second;
+ }
+ if (log_warning) {
+ LOG_WARNING(Service_AM,
+ "Normalizing unknown raw applet_id={:#x} to low byte {:#x}",
+ raw_id, static_cast<u32>(low_byte));
+ }
+ return low_byte;
+ }
+ }
+
+ return id;
+}
+
std::shared_ptr<ILibraryAppletAccessor> CreateGuestApplet(Core::System& system,
WindowSystem& window_system,
std::shared_ptr<Applet> caller_applet,
@@ -184,6 +222,8 @@ Result ILibraryAppletCreator::CreateLibraryApplet(
LOG_DEBUG(Service_AM, "called with applet_id={} applet_mode={}", applet_id,
library_applet_mode);
+ applet_id = NormalizeAppletId(applet_id);
+
std::shared_ptr<ILibraryAppletAccessor> library_applet;
if (ShouldCreateGuestApplet(applet_id)) {
library_applet =
@@ -210,6 +250,8 @@ Result ILibraryAppletCreator::CreateLibraryAppletEx(
LOG_DEBUG(Service_AM, "called with applet_id={} applet_mode={} thread_id={}", applet_id,
library_applet_mode, thread_id);
+ applet_id = NormalizeAppletId(applet_id);
+
std::shared_ptr<ILibraryAppletAccessor> library_applet;
if (ShouldCreateGuestApplet(applet_id)) {
library_applet =