From a0f7f2b309e4920e0e3f1217441a4628023f59b8 Mon Sep 17 00:00:00 2001
From: Narr the Reg <juangerman-13@hotmail.com>
Date: Tue, 30 Jan 2024 10:36:42 -0600
Subject: [PATCH] service: hid: Implement GetPlayerLedPattern accurately

---
 src/core/hle/service/hid/hid_server.cpp | 45 ++++++++++++++++++-------
 src/core/hle/service/hid/hid_server.h   |  5 ++-
 src/hid_core/hid_types.h                |  5 ++-
 src/hid_core/resources/npad/npad.cpp    | 11 ------
 src/hid_core/resources/npad/npad.h      |  2 --
 5 files changed, 41 insertions(+), 27 deletions(-)

diff --git a/src/core/hle/service/hid/hid_server.cpp b/src/core/hle/service/hid/hid_server.cpp
index 09c47b5e30..938b934514 100644
--- a/src/core/hle/service/hid/hid_server.cpp
+++ b/src/core/hle/service/hid/hid_server.cpp
@@ -8,6 +8,7 @@
 #include "core/hle/kernel/k_shared_memory.h"
 #include "core/hle/kernel/k_transfer_memory.h"
 #include "core/hle/kernel/kernel.h"
+#include "core/hle/service/cmif_serialization.h"
 #include "core/hle/service/hid/hid_server.h"
 #include "core/hle/service/ipc_helpers.h"
 #include "core/memory.h"
@@ -153,7 +154,7 @@ IHidServer::IHidServer(Core::System& system_, std::shared_ptr<ResourceManager> r
         {104, &IHidServer::DeactivateNpad, "DeactivateNpad"},
         {106, &IHidServer::AcquireNpadStyleSetUpdateEventHandle, "AcquireNpadStyleSetUpdateEventHandle"},
         {107, &IHidServer::DisconnectNpad, "DisconnectNpad"},
-        {108, &IHidServer::GetPlayerLedPattern, "GetPlayerLedPattern"},
+        {108, C<&IHidServer::GetPlayerLedPattern>, "GetPlayerLedPattern"},
         {109, &IHidServer::ActivateNpadWithRevision, "ActivateNpadWithRevision"},
         {120, &IHidServer::SetNpadJoyHoldType, "SetNpadJoyHoldType"},
         {121, &IHidServer::GetNpadJoyHoldType, "GetNpadJoyHoldType"},
@@ -1136,19 +1137,39 @@ void IHidServer::DisconnectNpad(HLERequestContext& ctx) {
     rb.Push(ResultSuccess);
 }
 
-void IHidServer::GetPlayerLedPattern(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-    const auto npad_id{rp.PopEnum<Core::HID::NpadIdType>()};
-
-    Core::HID::LedPattern pattern{0, 0, 0, 0};
-    auto controller = GetResourceManager()->GetNpad();
-    const auto result = controller->GetLedPattern(npad_id, pattern);
-
+Result IHidServer::GetPlayerLedPattern(Out<Core::HID::LedPattern> out_led_pattern,
+                                       Core::HID::NpadIdType npad_id) {
     LOG_DEBUG(Service_HID, "called, npad_id={}", npad_id);
 
-    IPC::ResponseBuilder rb{ctx, 4};
-    rb.Push(result);
-    rb.Push(pattern.raw);
+    switch (npad_id) {
+    case Core::HID::NpadIdType::Player1:
+        *out_led_pattern = Core::HID::LedPattern{1, 0, 0, 0};
+        R_SUCCEED();
+    case Core::HID::NpadIdType::Player2:
+        *out_led_pattern = Core::HID::LedPattern{1, 1, 0, 0};
+        R_SUCCEED();
+    case Core::HID::NpadIdType::Player3:
+        *out_led_pattern = Core::HID::LedPattern{1, 1, 1, 0};
+        R_SUCCEED();
+    case Core::HID::NpadIdType::Player4:
+        *out_led_pattern = Core::HID::LedPattern{1, 1, 1, 1};
+        R_SUCCEED();
+    case Core::HID::NpadIdType::Player5:
+        *out_led_pattern = Core::HID::LedPattern{1, 0, 0, 1};
+        R_SUCCEED();
+    case Core::HID::NpadIdType::Player6:
+        *out_led_pattern = Core::HID::LedPattern{1, 0, 1, 0};
+        R_SUCCEED();
+    case Core::HID::NpadIdType::Player7:
+        *out_led_pattern = Core::HID::LedPattern{1, 0, 1, 1};
+        R_SUCCEED();
+    case Core::HID::NpadIdType::Player8:
+        *out_led_pattern = Core::HID::LedPattern{0, 1, 1, 0};
+        R_SUCCEED();
+    default:
+        *out_led_pattern = Core::HID::LedPattern{0, 0, 0, 0};
+        R_SUCCEED();
+    }
 }
 
 void IHidServer::ActivateNpadWithRevision(HLERequestContext& ctx) {
diff --git a/src/core/hle/service/hid/hid_server.h b/src/core/hle/service/hid/hid_server.h
index 3a2e0a2301..faf7756896 100644
--- a/src/core/hle/service/hid/hid_server.h
+++ b/src/core/hle/service/hid/hid_server.h
@@ -3,7 +3,9 @@
 
 #pragma once
 
+#include "core/hle/service/cmif_types.h"
 #include "core/hle/service/service.h"
+#include "hid_core/hid_types.h"
 
 namespace Core {
 class System;
@@ -66,7 +68,8 @@ private:
     void DeactivateNpad(HLERequestContext& ctx);
     void AcquireNpadStyleSetUpdateEventHandle(HLERequestContext& ctx);
     void DisconnectNpad(HLERequestContext& ctx);
-    void GetPlayerLedPattern(HLERequestContext& ctx);
+    Result GetPlayerLedPattern(Out<Core::HID::LedPattern> out_led_pattern,
+                               Core::HID::NpadIdType npad_id);
     void ActivateNpadWithRevision(HLERequestContext& ctx);
     void SetNpadJoyHoldType(HLERequestContext& ctx);
     void GetNpadJoyHoldType(HLERequestContext& ctx);
diff --git a/src/hid_core/hid_types.h b/src/hid_core/hid_types.h
index b310ab72d3..ffb5f1926b 100644
--- a/src/hid_core/hid_types.h
+++ b/src/hid_core/hid_types.h
@@ -422,7 +422,10 @@ struct NpadPowerInfo {
 static_assert(sizeof(NpadPowerInfo) == 0xC, "NpadPowerInfo is an invalid size");
 
 struct LedPattern {
-    explicit LedPattern(u64 light1, u64 light2, u64 light3, u64 light4) {
+    LedPattern() {
+        raw = 0;
+    }
+    LedPattern(u64 light1, u64 light2, u64 light3, u64 light4) {
         position1.Assign(light1);
         position2.Assign(light2);
         position3.Assign(light3);
diff --git a/src/hid_core/resources/npad/npad.cpp b/src/hid_core/resources/npad/npad.cpp
index cde84b1bb2..2823be3487 100644
--- a/src/hid_core/resources/npad/npad.cpp
+++ b/src/hid_core/resources/npad/npad.cpp
@@ -956,17 +956,6 @@ Result NPad::SwapNpadAssignment(u64 aruid, Core::HID::NpadIdType npad_id_1,
     return ResultSuccess;
 }
 
-Result NPad::GetLedPattern(Core::HID::NpadIdType npad_id, Core::HID::LedPattern& pattern) const {
-    if (!IsNpadIdValid(npad_id)) {
-        LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
-        return ResultInvalidNpadId;
-    }
-    const auto aruid = applet_resource_holder.applet_resource->GetActiveAruid();
-    const auto& controller = GetControllerFromNpadIdType(aruid, npad_id).device;
-    pattern = controller->GetLedPattern();
-    return ResultSuccess;
-}
-
 Result NPad::IsUnintendedHomeButtonInputProtectionEnabled(bool& out_is_enabled, u64 aruid,
                                                           Core::HID::NpadIdType npad_id) const {
     std::scoped_lock lock{mutex};
diff --git a/src/hid_core/resources/npad/npad.h b/src/hid_core/resources/npad/npad.h
index 502cb9b55c..3b1a69e7f2 100644
--- a/src/hid_core/resources/npad/npad.h
+++ b/src/hid_core/resources/npad/npad.h
@@ -97,8 +97,6 @@ public:
     Result ResetIsSixAxisSensorDeviceNewlyAssigned(
         u64 aruid, const Core::HID::SixAxisSensorHandle& sixaxis_handle);
 
-    Result GetLedPattern(Core::HID::NpadIdType npad_id, Core::HID::LedPattern& pattern) const;
-
     Result IsUnintendedHomeButtonInputProtectionEnabled(bool& out_is_enabled, u64 aruid,
                                                         Core::HID::NpadIdType npad_id) const;
     Result EnableUnintendedHomeButtonInputProtection(u64 aruid, Core::HID::NpadIdType npad_id,