From a3f235f8a23303796a3727978806f2dcb13894eb Mon Sep 17 00:00:00 2001
From: german77 <juangerman-13@hotmail.com>
Date: Sat, 16 Sep 2023 08:38:10 -0600
Subject: [PATCH] service: hid: Implement ApplyNpadSystemCommonPolicy

---
 src/core/hle/service/hid/controllers/npad.cpp | 25 +++++++++++++++
 src/core/hle/service/hid/controllers/npad.h   |  2 ++
 src/core/hle/service/hid/hid.cpp              | 31 ++++++++++++++-----
 src/core/hle/service/hid/hid.h                |  2 +-
 4 files changed, 52 insertions(+), 8 deletions(-)

diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index 3b349b4c4e..c744b0f877 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -1508,6 +1508,31 @@ Core::HID::NpadButton Controller_NPad::GetAndResetPressState() {
     return static_cast<Core::HID::NpadButton>(press_state.exchange(0));
 }
 
+void Controller_NPad::ApplyNpadSystemCommonPolicy() {
+    Core::HID::NpadStyleTag styletag{};
+    styletag.fullkey.Assign(1);
+    styletag.handheld.Assign(1);
+    styletag.joycon_dual.Assign(1);
+    styletag.system_ext.Assign(1);
+    styletag.system.Assign(1);
+    SetSupportedStyleSet(styletag);
+
+    SetNpadHandheldActivationMode(NpadHandheldActivationMode::Dual);
+
+    supported_npad_id_types.clear();
+    supported_npad_id_types.resize(10);
+    supported_npad_id_types[0] = Core::HID::NpadIdType::Player1;
+    supported_npad_id_types[1] = Core::HID::NpadIdType::Player2;
+    supported_npad_id_types[2] = Core::HID::NpadIdType::Player3;
+    supported_npad_id_types[3] = Core::HID::NpadIdType::Player4;
+    supported_npad_id_types[4] = Core::HID::NpadIdType::Player5;
+    supported_npad_id_types[5] = Core::HID::NpadIdType::Player6;
+    supported_npad_id_types[6] = Core::HID::NpadIdType::Player7;
+    supported_npad_id_types[7] = Core::HID::NpadIdType::Player8;
+    supported_npad_id_types[8] = Core::HID::NpadIdType::Other;
+    supported_npad_id_types[9] = Core::HID::NpadIdType::Handheld;
+}
+
 bool Controller_NPad::IsControllerSupported(Core::HID::NpadStyleIndex controller) const {
     if (controller == Core::HID::NpadStyleIndex::Handheld) {
         const bool support_handheld =
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h
index 776411261d..0e9f899a45 100644
--- a/src/core/hle/service/hid/controllers/npad.h
+++ b/src/core/hle/service/hid/controllers/npad.h
@@ -190,6 +190,8 @@ public:
     // Specifically for cheat engine and other features.
     Core::HID::NpadButton GetAndResetPressState();
 
+    void ApplyNpadSystemCommonPolicy();
+
     static bool IsNpadIdValid(Core::HID::NpadIdType npad_id);
     static Result IsDeviceHandleValid(const Core::HID::VibrationDeviceHandle& device_handle);
     static Result VerifyValidSixAxisSensorHandle(
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index fd466db7b4..6f711c0da7 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -231,8 +231,10 @@ std::shared_ptr<IAppletResource> Hid::GetAppletResource() {
     return applet_resource;
 }
 
-Hid::Hid(Core::System& system_)
-    : ServiceFramework{system_, "hid"}, service_context{system_, service_name} {
+Hid::Hid(Core::System& system_, std::shared_ptr<IAppletResource> applet_resource_)
+    : ServiceFramework{system_, "hid"}, applet_resource{applet_resource_}, service_context{
+                                                                               system_,
+                                                                               service_name} {
     // clang-format off
     static const FunctionInfo functions[] = {
         {0, &Hid::CreateAppletResource, "CreateAppletResource"},
@@ -2543,8 +2545,9 @@ public:
 
 class HidSys final : public ServiceFramework<HidSys> {
 public:
-    explicit HidSys(Core::System& system_)
-        : ServiceFramework{system_, "hid:sys"}, service_context{system_, "hid:sys"} {
+    explicit HidSys(Core::System& system_, std::shared_ptr<IAppletResource> applet_resource_)
+        : ServiceFramework{system_, "hid:sys"}, service_context{system_, "hid:sys"},
+          applet_resource{applet_resource_} {
         // clang-format off
         static const FunctionInfo functions[] = {
             {31, nullptr, "SendKeyboardLockKeyEvent"},
@@ -2756,9 +2759,12 @@ public:
 
 private:
     void ApplyNpadSystemCommonPolicy(HLERequestContext& ctx) {
-        // We already do this for homebrew so we can just stub it out
         LOG_WARNING(Service_HID, "called");
 
+        GetAppletResource()
+            ->GetController<Controller_NPad>(HidController::NPad)
+            .ApplyNpadSystemCommonPolicy();
+
         IPC::ResponseBuilder rb{ctx, 2};
         rb.Push(ResultSuccess);
     }
@@ -2821,17 +2827,28 @@ private:
         rb.PushRaw(touchscreen_config);
     }
 
+    std::shared_ptr<IAppletResource> GetAppletResource() {
+        if (applet_resource == nullptr) {
+            applet_resource = std::make_shared<IAppletResource>(system, service_context);
+        }
+
+        return applet_resource;
+    }
+
     Kernel::KEvent* joy_detach_event;
     KernelHelpers::ServiceContext service_context;
+    std::shared_ptr<IAppletResource> applet_resource;
 };
 
 void LoopProcess(Core::System& system) {
     auto server_manager = std::make_unique<ServerManager>(system);
+    std::shared_ptr<IAppletResource> applet_resource;
 
-    server_manager->RegisterNamedService("hid", std::make_shared<Hid>(system));
+    server_manager->RegisterNamedService("hid", std::make_shared<Hid>(system, applet_resource));
     server_manager->RegisterNamedService("hidbus", std::make_shared<HidBus>(system));
     server_manager->RegisterNamedService("hid:dbg", std::make_shared<HidDbg>(system));
-    server_manager->RegisterNamedService("hid:sys", std::make_shared<HidSys>(system));
+    server_manager->RegisterNamedService("hid:sys",
+                                         std::make_shared<HidSys>(system, applet_resource));
 
     server_manager->RegisterNamedService("irs", std::make_shared<Service::IRS::IRS>(system));
     server_manager->RegisterNamedService("irs:sys",
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h
index f247b83c25..0ca43de935 100644
--- a/src/core/hle/service/hid/hid.h
+++ b/src/core/hle/service/hid/hid.h
@@ -95,7 +95,7 @@ private:
 
 class Hid final : public ServiceFramework<Hid> {
 public:
-    explicit Hid(Core::System& system_);
+    explicit Hid(Core::System& system_, std::shared_ptr<IAppletResource> applet_resource_);
     ~Hid() override;
 
     std::shared_ptr<IAppletResource> GetAppletResource();
-- 
GitLab