From ae5c134ac621c07d21eb7aec66de354792cee3ca Mon Sep 17 00:00:00 2001
From: Narr the Reg <juangerman-13@hotmail.com>
Date: Thu, 28 Sep 2023 23:01:25 -0600
Subject: [PATCH] service: am: Set push in arguments according to the launched
 applet

---
 src/core/hle/service/am/am.cpp                | 47 ++++++++++++++++--
 src/core/hle/service/am/am.h                  |  1 +
 .../hle/service/am/applets/applet_cabinet.h   | 11 ++++-
 .../am/applets/applet_general_backend.cpp     |  6 +--
 src/core/hle/service/am/applets/applets.cpp   | 16 ++++++
 src/core/hle/service/am/applets/applets.h     | 49 +++++++++++++++----
 src/yuzu/main.cpp                             |  7 +++
 7 files changed, 120 insertions(+), 17 deletions(-)

diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index e9bd04842d..2f65034270 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -8,6 +8,7 @@
 #include "common/settings.h"
 #include "common/settings_enums.h"
 #include "core/core.h"
+#include "core/core_timing.h"
 #include "core/file_sys/control_metadata.h"
 #include "core/file_sys/patch_manager.h"
 #include "core/file_sys/registered_cache.h"
@@ -19,6 +20,7 @@
 #include "core/hle/service/am/am.h"
 #include "core/hle/service/am/applet_ae.h"
 #include "core/hle/service/am/applet_oe.h"
+#include "core/hle/service/am/applets/applet_cabinet.h"
 #include "core/hle/service/am/applets/applet_mii_edit_types.h"
 #include "core/hle/service/am/applets/applet_profile_select.h"
 #include "core/hle/service/am/applets/applet_web_browser.h"
@@ -1385,7 +1387,16 @@ ILibraryAppletSelfAccessor::ILibraryAppletSelfAccessor(Core::System& system_)
     // clang-format on
     RegisterHandlers(functions);
 
-    PushInShowMiiEditData();
+    switch (system.GetAppletManager().GetCurrentAppletId()) {
+    case Applets::AppletId::Cabinet:
+        PushInShowCabinetData();
+        break;
+    case Applets::AppletId::MiiEdit:
+        PushInShowMiiEditData();
+        break;
+    default:
+        break;
+    }
 }
 
 ILibraryAppletSelfAccessor::~ILibraryAppletSelfAccessor() = default;
@@ -1431,7 +1442,7 @@ void ILibraryAppletSelfAccessor::GetLibraryAppletInfo(HLERequestContext& ctx) {
     LOG_WARNING(Service_AM, "(STUBBED) called");
 
     const LibraryAppletInfo applet_info{
-        .applet_id = Applets::AppletId::MiiEdit,
+        .applet_id = system.GetAppletManager().GetCurrentAppletId(),
         .library_applet_mode = Applets::LibraryAppletMode::AllForeground,
     };
 
@@ -1459,6 +1470,35 @@ void ILibraryAppletSelfAccessor::GetCallerAppletIdentityInfo(HLERequestContext&
     rb.PushRaw(applet_info);
 }
 
+void ILibraryAppletSelfAccessor::PushInShowCabinetData() {
+    const Applets::CommonArguments arguments{
+        .arguments_version = Applets::CommonArgumentVersion::Version3,
+        .size = Applets::CommonArgumentSize::Version3,
+        .library_version = static_cast<u32>(Applets::CabinetAppletVersion::Version1),
+        .theme_color = Applets::ThemeColor::BasicBlack,
+        .play_startup_sound = true,
+        .system_tick = system.CoreTiming().GetClockTicks(),
+    };
+
+    const Applets::StartParamForAmiiboSettings amiibo_settings{
+        .param_1 = 0,
+        .applet_mode = system.GetAppletManager().GetCabinetMode(),
+        .flags = Applets::CabinetFlags::None,
+        .amiibo_settings_1 = 0,
+        .device_handle = 0,
+        .tag_info{},
+        .register_info{},
+        .amiibo_settings_3{},
+    };
+
+    std::vector<u8> argument_data(sizeof(arguments));
+    std::vector<u8> settings_data(sizeof(amiibo_settings));
+    std::memcpy(argument_data.data(), &arguments, sizeof(arguments));
+    std::memcpy(settings_data.data(), &amiibo_settings, sizeof(amiibo_settings));
+    queue_data.emplace_back(std::move(argument_data));
+    queue_data.emplace_back(std::move(settings_data));
+}
+
 void ILibraryAppletSelfAccessor::PushInShowMiiEditData() {
     struct MiiEditV3 {
         Applets::MiiEditAppletInputCommon common;
@@ -2238,7 +2278,7 @@ void IProcessWindingController::GetLaunchReason(HLERequestContext& ctx) {
 }
 
 void IProcessWindingController::OpenCallingLibraryApplet(HLERequestContext& ctx) {
-    const auto applet_id = Applets::AppletId::MiiEdit;
+    const auto applet_id = system.GetAppletManager().GetCurrentAppletId();
     const auto applet_mode = Applets::LibraryAppletMode::AllForeground;
 
     LOG_WARNING(Service_AM, "(STUBBED) called with applet_id={:08X}, applet_mode={:08X}", applet_id,
@@ -2259,4 +2299,5 @@ void IProcessWindingController::OpenCallingLibraryApplet(HLERequestContext& ctx)
     rb.Push(ResultSuccess);
     rb.PushIpcInterface<ILibraryAppletAccessor>(system, applet);
 }
+
 } // namespace Service::AM
diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h
index 5b97eb5e35..10b79188fd 100644
--- a/src/core/hle/service/am/am.h
+++ b/src/core/hle/service/am/am.h
@@ -311,6 +311,7 @@ private:
     void ExitProcessAndReturn(HLERequestContext& ctx);
     void GetCallerAppletIdentityInfo(HLERequestContext& ctx);
 
+    void PushInShowCabinetData();
     void PushInShowMiiEditData();
 
     std::deque<std::vector<u8>> queue_data;
diff --git a/src/core/hle/service/am/applets/applet_cabinet.h b/src/core/hle/service/am/applets/applet_cabinet.h
index b56427021e..f498796f71 100644
--- a/src/core/hle/service/am/applets/applet_cabinet.h
+++ b/src/core/hle/service/am/applets/applet_cabinet.h
@@ -29,6 +29,15 @@ enum class CabinetAppletVersion : u32 {
     Version1 = 0x1,
 };
 
+enum class CabinetFlags : u8 {
+    None = 0,
+    DeviceHandle = 1 << 0,
+    TagInfo = 1 << 1,
+    RegisterInfo = 1 << 2,
+    All = DeviceHandle | TagInfo | RegisterInfo,
+};
+DECLARE_ENUM_FLAG_OPERATORS(CabinetFlags)
+
 enum class CabinetResult : u8 {
     Cancel = 0,
     TagInfo = 1 << 1,
@@ -51,7 +60,7 @@ static_assert(sizeof(AmiiboSettingsStartParam) == 0x30,
 struct StartParamForAmiiboSettings {
     u8 param_1;
     Service::NFP::CabinetMode applet_mode;
-    u8 flags;
+    CabinetFlags flags;
     u8 amiibo_settings_1;
     u64 device_handle;
     Service::NFP::TagInfo tag_info;
diff --git a/src/core/hle/service/am/applets/applet_general_backend.cpp b/src/core/hle/service/am/applets/applet_general_backend.cpp
index 8b352020e0..c0032f652b 100644
--- a/src/core/hle/service/am/applets/applet_general_backend.cpp
+++ b/src/core/hle/service/am/applets/applet_general_backend.cpp
@@ -223,9 +223,9 @@ void StubApplet::Initialize() {
 
     const auto data = broker.PeekDataToAppletForDebug();
     system.GetReporter().SaveUnimplementedAppletReport(
-        static_cast<u32>(id), common_args.arguments_version, common_args.library_version,
-        common_args.theme_color, common_args.play_startup_sound, common_args.system_tick,
-        data.normal, data.interactive);
+        static_cast<u32>(id), static_cast<u32>(common_args.arguments_version),
+        common_args.library_version, static_cast<u32>(common_args.theme_color),
+        common_args.play_startup_sound, common_args.system_tick, data.normal, data.interactive);
 
     LogCurrentStorage(broker, "Initialize");
 }
diff --git a/src/core/hle/service/am/applets/applets.cpp b/src/core/hle/service/am/applets/applets.cpp
index 10afbc2dac..89d5434afd 100644
--- a/src/core/hle/service/am/applets/applets.cpp
+++ b/src/core/hle/service/am/applets/applets.cpp
@@ -199,6 +199,14 @@ const AppletFrontendSet& AppletManager::GetAppletFrontendSet() const {
     return frontend;
 }
 
+NFP::CabinetMode AppletManager::GetCabinetMode() const {
+    return cabinet_mode;
+}
+
+AppletId AppletManager::GetCurrentAppletId() const {
+    return current_applet_id;
+}
+
 void AppletManager::SetAppletFrontendSet(AppletFrontendSet set) {
     if (set.cabinet != nullptr) {
         frontend.cabinet = std::move(set.cabinet);
@@ -237,6 +245,14 @@ void AppletManager::SetAppletFrontendSet(AppletFrontendSet set) {
     }
 }
 
+void AppletManager::SetCabinetMode(NFP::CabinetMode mode) {
+    cabinet_mode = mode;
+}
+
+void AppletManager::SetCurrentAppletId(AppletId applet_id) {
+    current_applet_id = applet_id;
+}
+
 void AppletManager::SetDefaultAppletFrontendSet() {
     ClearAll();
     SetDefaultAppletsIfMissing();
diff --git a/src/core/hle/service/am/applets/applets.h b/src/core/hle/service/am/applets/applets.h
index 12f3741998..f02bbc4501 100644
--- a/src/core/hle/service/am/applets/applets.h
+++ b/src/core/hle/service/am/applets/applets.h
@@ -34,6 +34,10 @@ class KEvent;
 class KReadableEvent;
 } // namespace Kernel
 
+namespace Service::NFP {
+enum class CabinetMode : u8;
+} // namespace Service::NFP
+
 namespace Service::AM {
 
 class IStorage;
@@ -41,6 +45,8 @@ class IStorage;
 namespace Applets {
 
 enum class AppletId : u32 {
+    None = 0x00,
+    Application = 0x01,
     OverlayDisplay = 0x02,
     QLaunch = 0x03,
     Starter = 0x04,
@@ -71,6 +77,32 @@ enum class LibraryAppletMode : u32 {
     AllForegroundInitiallyHidden = 4,
 };
 
+enum class CommonArgumentVersion : u32 {
+    Version0,
+    Version1,
+    Version2,
+    Version3,
+};
+
+enum class CommonArgumentSize : u32 {
+    Version3 = 0x20,
+};
+
+enum class ThemeColor : u32 {
+    BasicWhite = 0,
+    BasicBlack = 3,
+};
+
+struct CommonArguments {
+    CommonArgumentVersion arguments_version;
+    CommonArgumentSize size;
+    u32 library_version;
+    ThemeColor theme_color;
+    bool play_startup_sound;
+    u64_le system_tick;
+};
+static_assert(sizeof(CommonArguments) == 0x20, "CommonArguments has incorrect size.");
+
 class AppletDataBroker final {
 public:
     explicit AppletDataBroker(Core::System& system_, LibraryAppletMode applet_mode_);
@@ -161,16 +193,6 @@ public:
     }
 
 protected:
-    struct CommonArguments {
-        u32_le arguments_version;
-        u32_le size;
-        u32_le library_version;
-        u32_le theme_color;
-        bool play_startup_sound;
-        u64_le system_tick;
-    };
-    static_assert(sizeof(CommonArguments) == 0x20, "CommonArguments has incorrect size.");
-
     CommonArguments common_args{};
     AppletDataBroker broker;
     LibraryAppletMode applet_mode;
@@ -219,8 +241,12 @@ public:
     ~AppletManager();
 
     const AppletFrontendSet& GetAppletFrontendSet() const;
+    NFP::CabinetMode GetCabinetMode() const;
+    AppletId GetCurrentAppletId() const;
 
     void SetAppletFrontendSet(AppletFrontendSet set);
+    void SetCabinetMode(NFP::CabinetMode mode);
+    void SetCurrentAppletId(AppletId applet_id);
     void SetDefaultAppletFrontendSet();
     void SetDefaultAppletsIfMissing();
     void ClearAll();
@@ -228,6 +254,9 @@ public:
     std::shared_ptr<Applet> GetApplet(AppletId id, LibraryAppletMode mode) const;
 
 private:
+    AppletId current_applet_id{};
+    NFP::CabinetMode cabinet_mode{};
+
     AppletFrontendSet frontend;
     Core::System& system;
 };
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 0879d61681..ec27361d5f 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -2122,6 +2122,8 @@ void GMainWindow::OnEmulationStopped() {
     OnTasStateChanged();
     render_window->FinalizeCamera();
 
+    system->GetAppletManager().SetCurrentAppletId(Service::AM::Applets::AppletId::None);
+
     // Enable all controllers
     system->HIDCore().SetSupportedStyleTag({Core::HID::NpadStyleSet::All});
 
@@ -4169,6 +4171,9 @@ void GMainWindow::OnCabinet(Service::NFP::CabinetMode mode) {
         return;
     }
 
+    system->GetAppletManager().SetCurrentAppletId(Service::AM::Applets::AppletId::Cabinet);
+    system->GetAppletManager().SetCabinetMode(mode);
+
     const auto filename = QString::fromStdString(cabinet_nca->GetFullPath());
     UISettings::values.roms_path = QFileInfo(filename).path();
     BootGame(filename);
@@ -4190,6 +4195,8 @@ void GMainWindow::OnMiiEdit() {
         return;
     }
 
+    system->GetAppletManager().SetCurrentAppletId(Service::AM::Applets::AppletId::MiiEdit);
+
     const auto filename = QString::fromStdString((mii_applet_nca->GetFullPath()));
     UISettings::values.roms_path = QFileInfo(filename).path();
     BootGame(filename);