From a36f4d0a9f2c0fee837856e4db3e4ca10bfed25b Mon Sep 17 00:00:00 2001
From: german77 <juangerman-13@hotmail.com>
Date: Sat, 6 Jan 2024 21:17:57 -0600
Subject: [PATCH 1/4] service: hid: Implement CaptureButtonAssignment

---
 src/core/hle/service/hid/hid_server.cpp       | 18 +++++++++------
 .../hle/service/hid/hid_system_server.cpp     | 23 ++++++++++++++++++-
 src/core/hle/service/hid/hid_system_server.h  |  1 +
 src/hid_core/resources/npad/npad.cpp          | 17 ++++++++++++++
 src/hid_core/resources/npad/npad.h            |  6 +++++
 5 files changed, 57 insertions(+), 8 deletions(-)

diff --git a/src/core/hle/service/hid/hid_server.cpp b/src/core/hle/service/hid/hid_server.cpp
index 2ff00d30de..75bf3e682f 100644
--- a/src/core/hle/service/hid/hid_server.cpp
+++ b/src/core/hle/service/hid/hid_server.cpp
@@ -1466,23 +1466,27 @@ void IHidServer::SetNpadCaptureButtonAssignment(HLERequestContext& ctx) {
 
     const auto parameters{rp.PopRaw<Parameters>()};
 
-    LOG_WARNING(Service_HID,
-                "(STUBBED) called, npad_styleset={}, applet_resource_user_id={}, button={}",
-                parameters.npad_styleset, parameters.applet_resource_user_id, parameters.button);
+    LOG_INFO(Service_HID, "called, npad_styleset={}, applet_resource_user_id={}, button={}",
+             parameters.npad_styleset, parameters.applet_resource_user_id, parameters.button);
+
+    const auto result = GetResourceManager()->GetNpad()->SetNpadCaptureButtonAssignment(
+        parameters.applet_resource_user_id, parameters.npad_styleset, parameters.button);
 
     IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
+    rb.Push(result);
 }
 
 void IHidServer::ClearNpadCaptureButtonAssignment(HLERequestContext& ctx) {
     IPC::RequestParser rp{ctx};
     const auto applet_resource_user_id{rp.Pop<u64>()};
 
-    LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}",
-                applet_resource_user_id);
+    LOG_INFO(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
+
+    const auto result =
+        GetResourceManager()->GetNpad()->ClearNpadCaptureButtonAssignment(applet_resource_user_id);
 
     IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
+    rb.Push(result);
 }
 
 void IHidServer::GetVibrationDeviceInfo(HLERequestContext& ctx) {
diff --git a/src/core/hle/service/hid/hid_system_server.cpp b/src/core/hle/service/hid/hid_system_server.cpp
index 2a65615e8a..ac0d8bd5df 100644
--- a/src/core/hle/service/hid/hid_system_server.cpp
+++ b/src/core/hle/service/hid/hid_system_server.cpp
@@ -46,7 +46,7 @@ IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr<Resour
         {310, &IHidSystemServer::GetMaskedSupportedNpadStyleSet, "GetMaskedSupportedNpadStyleSet"},
         {311, nullptr, "SetNpadPlayerLedBlinkingDevice"},
         {312, &IHidSystemServer::SetSupportedNpadStyleSetAll, "SetSupportedNpadStyleSetAll"},
-        {313, nullptr, "GetNpadCaptureButtonAssignment"},
+        {313, &IHidSystemServer::GetNpadCaptureButtonAssignment, "GetNpadCaptureButtonAssignment"},
         {314, nullptr, "GetAppletFooterUiType"},
         {315, &IHidSystemServer::GetAppletDetailedUiType, "GetAppletDetailedUiType"},
         {316, &IHidSystemServer::GetNpadInterfaceType, "GetNpadInterfaceType"},
@@ -331,6 +331,27 @@ void IHidSystemServer::SetSupportedNpadStyleSetAll(HLERequestContext& ctx) {
     rb.Push(result);
 }
 
+void IHidSystemServer::GetNpadCaptureButtonAssignment(HLERequestContext& ctx) {
+    IPC::RequestParser rp{ctx};
+    const auto applet_resource_user_id{rp.Pop<u64>()};
+    const auto capture_button_list_size{ctx.GetWriteBufferNumElements<Core::HID::NpadButton>()};
+
+    LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
+
+    std::vector<Core::HID::NpadButton> capture_button_list(capture_button_list_size);
+    const auto& npad = GetResourceManager()->GetNpad();
+    const u64 list_size =
+        npad->GetNpadCaptureButtonAssignment(capture_button_list, applet_resource_user_id);
+
+    if (list_size != 0) {
+        ctx.WriteBuffer(capture_button_list);
+    }
+
+    IPC::ResponseBuilder rb{ctx, 4};
+    rb.Push(ResultSuccess);
+    rb.Push(list_size);
+}
+
 void IHidSystemServer::GetAppletDetailedUiType(HLERequestContext& ctx) {
     IPC::RequestParser rp{ctx};
     const auto npad_id_type{rp.PopEnum<Core::HID::NpadIdType>()};
diff --git a/src/core/hle/service/hid/hid_system_server.h b/src/core/hle/service/hid/hid_system_server.h
index f467e2aa8c..53091cf536 100644
--- a/src/core/hle/service/hid/hid_system_server.h
+++ b/src/core/hle/service/hid/hid_system_server.h
@@ -31,6 +31,7 @@ private:
     void GetNpadFullKeyGripColor(HLERequestContext& ctx);
     void GetMaskedSupportedNpadStyleSet(HLERequestContext& ctx);
     void SetSupportedNpadStyleSetAll(HLERequestContext& ctx);
+    void GetNpadCaptureButtonAssignment(HLERequestContext& ctx);
     void GetAppletDetailedUiType(HLERequestContext& ctx);
     void GetNpadInterfaceType(HLERequestContext& ctx);
     void GetNpadLeftRightInterfaceType(HLERequestContext& ctx);
diff --git a/src/hid_core/resources/npad/npad.cpp b/src/hid_core/resources/npad/npad.cpp
index e6c0356289..ea035d7595 100644
--- a/src/hid_core/resources/npad/npad.cpp
+++ b/src/hid_core/resources/npad/npad.cpp
@@ -1339,4 +1339,21 @@ AppletDetailedUiType NPad::GetAppletDetailedUiType(Core::HID::NpadIdType npad_id
     };
 }
 
+Result NPad::SetNpadCaptureButtonAssignment(u64 aruid, Core::HID::NpadStyleSet npad_style_set,
+                                            Core::HID::NpadButton button_assignment) {
+    std::scoped_lock lock{mutex};
+    return npad_resource.SetNpadCaptureButtonAssignment(aruid, npad_style_set, button_assignment);
+}
+
+Result NPad::ClearNpadCaptureButtonAssignment(u64 aruid) {
+    std::scoped_lock lock{mutex};
+    return npad_resource.ClearNpadCaptureButtonAssignment(aruid);
+}
+
+std::size_t NPad::GetNpadCaptureButtonAssignment(std::span<Core::HID::NpadButton> out_list,
+                                                 u64 aruid) const {
+    std::scoped_lock lock{mutex};
+    return npad_resource.GetNpadCaptureButtonAssignment(out_list, aruid);
+}
+
 } // namespace Service::HID
diff --git a/src/hid_core/resources/npad/npad.h b/src/hid_core/resources/npad/npad.h
index 58f8c7acf8..e602ddaea0 100644
--- a/src/hid_core/resources/npad/npad.h
+++ b/src/hid_core/resources/npad/npad.h
@@ -149,6 +149,12 @@ public:
 
     AppletDetailedUiType GetAppletDetailedUiType(Core::HID::NpadIdType npad_id);
 
+    Result SetNpadCaptureButtonAssignment(u64 aruid, Core::HID::NpadStyleSet npad_style_set,
+                                          Core::HID::NpadButton button_assignment);
+    Result ClearNpadCaptureButtonAssignment(u64 aruid);
+    std::size_t GetNpadCaptureButtonAssignment(std::span<Core::HID::NpadButton> out_list,
+                                               u64 aruid) const;
+
 private:
     struct VibrationData {
         bool device_mounted{};

From f224ef6185679338aa8eb8093b150c461f488982 Mon Sep 17 00:00:00 2001
From: german77 <juangerman-13@hotmail.com>
Date: Sat, 6 Jan 2024 21:35:10 -0600
Subject: [PATCH 2/4] service: hid: Implement SetNpadSystemExtStateEnabled

---
 src/core/hle/service/hid/hid_server.cpp       |  4 ++--
 .../hle/service/hid/hid_system_server.cpp     | 22 ++++++++++++++-----
 src/core/hle/service/hid/hid_system_server.h  |  2 +-
 src/hid_core/resources/npad/npad.cpp          | 12 ++++++++++
 src/hid_core/resources/npad/npad.h            |  2 ++
 5 files changed, 34 insertions(+), 8 deletions(-)

diff --git a/src/core/hle/service/hid/hid_server.cpp b/src/core/hle/service/hid/hid_server.cpp
index 75bf3e682f..74898888a2 100644
--- a/src/core/hle/service/hid/hid_server.cpp
+++ b/src/core/hle/service/hid/hid_server.cpp
@@ -1444,8 +1444,8 @@ void IHidServer::SetNpadAnalogStickUseCenterClamp(HLERequestContext& ctx) {
 
     const auto parameters{rp.PopRaw<Parameters>()};
 
-    LOG_WARNING(Service_HID, "(STUBBED) called, use_center_clamp={}, applet_resource_user_id={}",
-                parameters.use_center_clamp, parameters.applet_resource_user_id);
+    LOG_INFO(Service_HID, "called, use_center_clamp={}, applet_resource_user_id={}",
+             parameters.use_center_clamp, parameters.applet_resource_user_id);
 
     GetResourceManager()->GetNpad()->SetNpadAnalogStickUseCenterClamp(
         parameters.applet_resource_user_id, parameters.use_center_clamp);
diff --git a/src/core/hle/service/hid/hid_system_server.cpp b/src/core/hle/service/hid/hid_system_server.cpp
index ac0d8bd5df..ead593ab3a 100644
--- a/src/core/hle/service/hid/hid_system_server.cpp
+++ b/src/core/hle/service/hid/hid_system_server.cpp
@@ -54,8 +54,8 @@ IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr<Resour
         {318, &IHidSystemServer::HasBattery, "HasBattery"},
         {319, &IHidSystemServer::HasLeftRightBattery, "HasLeftRightBattery"},
         {321, &IHidSystemServer::GetUniquePadsFromNpad, "GetUniquePadsFromNpad"},
-        {322, &IHidSystemServer::GetIrSensorState, "GetIrSensorState"},
-        {323, nullptr, "GetXcdHandleForNpadWithIrSensor"},
+        {322, &IHidSystemServer::SetNpadSystemExtStateEnabled, "SetNpadSystemExtStateEnabled"},
+        {323, nullptr, "GetLastActiveUniquePad"},
         {324, nullptr, "GetUniquePadButtonSet"},
         {325, nullptr, "GetUniquePadColor"},
         {326, nullptr, "GetUniquePadAppletDetailedUiType"},
@@ -444,13 +444,25 @@ void IHidSystemServer::GetUniquePadsFromNpad(HLERequestContext& ctx) {
     rb.Push(static_cast<u32>(unique_pads.size()));
 }
 
-void IHidSystemServer::GetIrSensorState(HLERequestContext& ctx) {
+void IHidSystemServer::SetNpadSystemExtStateEnabled(HLERequestContext& ctx) {
     IPC::RequestParser rp{ctx};
+    struct Parameters {
+        bool is_enabled;
+        INSERT_PADDING_BYTES_NOINIT(7);
+        u64 applet_resource_user_id;
+    };
+    static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
 
-    LOG_WARNING(Service_HID, "(STUBBED) called");
+    const auto parameters{rp.PopRaw<Parameters>()};
+
+    LOG_INFO(Service_HID, "called, is_enabled={}, applet_resource_user_id={}",
+             parameters.is_enabled, parameters.applet_resource_user_id);
+
+    const auto result = GetResourceManager()->GetNpad()->SetNpadSystemExtStateEnabled(
+        parameters.applet_resource_user_id, parameters.is_enabled);
 
     IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
+    rb.Push(result);
 }
 void IHidSystemServer::RegisterAppletResourceUserId(HLERequestContext& ctx) {
     IPC::RequestParser rp{ctx};
diff --git a/src/core/hle/service/hid/hid_system_server.h b/src/core/hle/service/hid/hid_system_server.h
index 53091cf536..0c2634e3f1 100644
--- a/src/core/hle/service/hid/hid_system_server.h
+++ b/src/core/hle/service/hid/hid_system_server.h
@@ -38,7 +38,7 @@ private:
     void HasBattery(HLERequestContext& ctx);
     void HasLeftRightBattery(HLERequestContext& ctx);
     void GetUniquePadsFromNpad(HLERequestContext& ctx);
-    void GetIrSensorState(HLERequestContext& ctx);
+    void SetNpadSystemExtStateEnabled(HLERequestContext& ctx);
     void RegisterAppletResourceUserId(HLERequestContext& ctx);
     void UnregisterAppletResourceUserId(HLERequestContext& ctx);
     void EnableAppletToGetInput(HLERequestContext& ctx);
diff --git a/src/hid_core/resources/npad/npad.cpp b/src/hid_core/resources/npad/npad.cpp
index ea035d7595..6be6edb7ec 100644
--- a/src/hid_core/resources/npad/npad.cpp
+++ b/src/hid_core/resources/npad/npad.cpp
@@ -1356,4 +1356,16 @@ std::size_t NPad::GetNpadCaptureButtonAssignment(std::span<Core::HID::NpadButton
     return npad_resource.GetNpadCaptureButtonAssignment(out_list, aruid);
 }
 
+Result NPad::SetNpadSystemExtStateEnabled(u64 aruid, bool is_enabled) {
+    std::scoped_lock lock{mutex};
+    const auto result = npad_resource.SetNpadSystemExtStateEnabled(aruid, is_enabled);
+
+    if (result.IsSuccess()) {
+        std::scoped_lock shared_lock{*applet_resource_holder.shared_mutex};
+        // TODO: abstracted_pad->EnableAppletToGetInput(aruid);
+    }
+
+    return result;
+}
+
 } // namespace Service::HID
diff --git a/src/hid_core/resources/npad/npad.h b/src/hid_core/resources/npad/npad.h
index e602ddaea0..73e2780c4a 100644
--- a/src/hid_core/resources/npad/npad.h
+++ b/src/hid_core/resources/npad/npad.h
@@ -155,6 +155,8 @@ public:
     std::size_t GetNpadCaptureButtonAssignment(std::span<Core::HID::NpadButton> out_list,
                                                u64 aruid) const;
 
+    Result SetNpadSystemExtStateEnabled(u64 aruid, bool is_enabled);
+
 private:
     struct VibrationData {
         bool device_mounted{};

From 3516a2d0bff5a7d6a22ff1b4fb7cbc021c6b4d1e Mon Sep 17 00:00:00 2001
From: german77 <juangerman-13@hotmail.com>
Date: Sat, 6 Jan 2024 21:54:23 -0600
Subject: [PATCH 3/4] service: hid: Implement AssigningSingleOnSlSrPress

---
 src/core/hle/service/hid/hid_system_server.cpp | 14 ++++++++++++--
 src/hid_core/resources/npad/npad.cpp           | 10 ++++++++++
 src/hid_core/resources/npad/npad.h             |  2 ++
 3 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/src/core/hle/service/hid/hid_system_server.cpp b/src/core/hle/service/hid/hid_system_server.cpp
index ead593ab3a..94d566650e 100644
--- a/src/core/hle/service/hid/hid_system_server.cpp
+++ b/src/core/hle/service/hid/hid_system_server.cpp
@@ -251,14 +251,24 @@ void IHidSystemServer::ApplyNpadSystemCommonPolicy(HLERequestContext& ctx) {
 }
 
 void IHidSystemServer::EnableAssigningSingleOnSlSrPress(HLERequestContext& ctx) {
-    LOG_WARNING(Service_HID, "(STUBBED) called");
+    IPC::RequestParser rp{ctx};
+    const auto applet_resource_user_id{rp.Pop<u64>()};
+
+    LOG_INFO(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
+
+    GetResourceManager()->GetNpad()->AssigningSingleOnSlSrPress(applet_resource_user_id, true);
 
     IPC::ResponseBuilder rb{ctx, 2};
     rb.Push(ResultSuccess);
 }
 
 void IHidSystemServer::DisableAssigningSingleOnSlSrPress(HLERequestContext& ctx) {
-    LOG_WARNING(Service_HID, "(STUBBED) called");
+    IPC::RequestParser rp{ctx};
+    const auto applet_resource_user_id{rp.Pop<u64>()};
+
+    LOG_INFO(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
+
+    GetResourceManager()->GetNpad()->AssigningSingleOnSlSrPress(applet_resource_user_id, false);
 
     IPC::ResponseBuilder rb{ctx, 2};
     rb.Push(ResultSuccess);
diff --git a/src/hid_core/resources/npad/npad.cpp b/src/hid_core/resources/npad/npad.cpp
index 6be6edb7ec..2995634c5d 100644
--- a/src/hid_core/resources/npad/npad.cpp
+++ b/src/hid_core/resources/npad/npad.cpp
@@ -1368,4 +1368,14 @@ Result NPad::SetNpadSystemExtStateEnabled(u64 aruid, bool is_enabled) {
     return result;
 }
 
+Result NPad::AssigningSingleOnSlSrPress(u64 aruid, bool is_enabled) {
+    std::scoped_lock lock{mutex};
+    bool is_currently_enabled{};
+    Result result = npad_resource.IsAssigningSingleOnSlSrPressEnabled(is_currently_enabled, aruid);
+    if (result.IsSuccess() && is_enabled != is_currently_enabled) {
+        result = npad_resource.SetAssigningSingleOnSlSrPress(aruid, is_enabled);
+    }
+    return result;
+}
+
 } // namespace Service::HID
diff --git a/src/hid_core/resources/npad/npad.h b/src/hid_core/resources/npad/npad.h
index 73e2780c4a..91bc59afd7 100644
--- a/src/hid_core/resources/npad/npad.h
+++ b/src/hid_core/resources/npad/npad.h
@@ -157,6 +157,8 @@ public:
 
     Result SetNpadSystemExtStateEnabled(u64 aruid, bool is_enabled);
 
+    Result AssigningSingleOnSlSrPress(u64 aruid, bool is_enabled);
+
 private:
     struct VibrationData {
         bool device_mounted{};

From 5105b900179e639a766c8013e7d24551e6a58a95 Mon Sep 17 00:00:00 2001
From: german77 <juangerman-13@hotmail.com>
Date: Sat, 6 Jan 2024 22:04:14 -0600
Subject: [PATCH 4/4] service: hid: Implement GetLastActiveNpad

---
 src/core/hle/service/hid/hid_system_server.cpp | 9 ++++++---
 src/hid_core/resources/npad/npad.cpp           | 6 ++++++
 src/hid_core/resources/npad/npad.h             | 2 ++
 3 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/src/core/hle/service/hid/hid_system_server.cpp b/src/core/hle/service/hid/hid_system_server.cpp
index 94d566650e..3a0cb3cb1d 100644
--- a/src/core/hle/service/hid/hid_system_server.cpp
+++ b/src/core/hle/service/hid/hid_system_server.cpp
@@ -275,11 +275,14 @@ void IHidSystemServer::DisableAssigningSingleOnSlSrPress(HLERequestContext& ctx)
 }
 
 void IHidSystemServer::GetLastActiveNpad(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_HID, "(STUBBED) called"); // Spams a lot when controller applet is running
+    Core::HID::NpadIdType npad_id{};
+    const Result result = GetResourceManager()->GetNpad()->GetLastActiveNpad(npad_id);
+
+    LOG_DEBUG(Service_HID, "called, npad_id={}", npad_id);
 
     IPC::ResponseBuilder rb{ctx, 3};
-    rb.Push(ResultSuccess);
-    rb.Push(0); // Dont forget to fix this
+    rb.Push(result);
+    rb.PushEnum(npad_id);
 }
 
 void IHidSystemServer::ApplyNpadSystemCommonPolicyFull(HLERequestContext& ctx) {
diff --git a/src/hid_core/resources/npad/npad.cpp b/src/hid_core/resources/npad/npad.cpp
index 2995634c5d..14871ebeef 100644
--- a/src/hid_core/resources/npad/npad.cpp
+++ b/src/hid_core/resources/npad/npad.cpp
@@ -1378,4 +1378,10 @@ Result NPad::AssigningSingleOnSlSrPress(u64 aruid, bool is_enabled) {
     return result;
 }
 
+Result NPad::GetLastActiveNpad(Core::HID::NpadIdType& out_npad_id) const {
+    std::scoped_lock lock{mutex};
+    out_npad_id = hid_core.GetLastActiveController();
+    return ResultSuccess;
+}
+
 } // namespace Service::HID
diff --git a/src/hid_core/resources/npad/npad.h b/src/hid_core/resources/npad/npad.h
index 91bc59afd7..01f3dabb15 100644
--- a/src/hid_core/resources/npad/npad.h
+++ b/src/hid_core/resources/npad/npad.h
@@ -159,6 +159,8 @@ public:
 
     Result AssigningSingleOnSlSrPress(u64 aruid, bool is_enabled);
 
+    Result GetLastActiveNpad(Core::HID::NpadIdType& out_npad_id) const;
+
 private:
     struct VibrationData {
         bool device_mounted{};