From 4a307a7b3aa3afea7d62674f6cf40b76f3ffb5e3 Mon Sep 17 00:00:00 2001
From: Narr the Reg <juangerman-13@hotmail.com>
Date: Fri, 13 Jan 2023 13:39:33 -0600
Subject: [PATCH] core: hid: Only set the polling mode to the correct side

---
 src/core/hid/emulated_controller.cpp          | 30 +++++++++++++------
 src/core/hid/emulated_controller.h            |  4 ++-
 src/core/hle/service/hid/controllers/npad.cpp | 14 ++++++++-
 src/core/hle/service/hid/hidbus/ringcon.cpp   |  6 ++--
 src/core/hle/service/hid/irs.cpp              | 27 +++++++++++------
 src/core/hle/service/nfc/nfc_device.cpp       |  6 ++--
 src/core/hle/service/nfp/nfp_device.cpp       |  6 ++--
 src/yuzu/configuration/configure_ringcon.cpp  |  6 ++--
 8 files changed, 71 insertions(+), 28 deletions(-)

diff --git a/src/core/hid/emulated_controller.cpp b/src/core/hid/emulated_controller.cpp
index faf9e7c4e..f83abad05 100644
--- a/src/core/hid/emulated_controller.cpp
+++ b/src/core/hid/emulated_controller.cpp
@@ -1208,19 +1208,31 @@ bool EmulatedController::IsVibrationEnabled(std::size_t device_index) {
 }
 
 Common::Input::DriverResult EmulatedController::SetPollingMode(
-    Common::Input::PollingMode polling_mode) {
-    LOG_INFO(Service_HID, "Set polling mode {}", polling_mode);
-    auto& output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)];
+    EmulatedDeviceIndex device_index, Common::Input::PollingMode polling_mode) {
+    LOG_INFO(Service_HID, "Set polling mode {}, device_index={}", polling_mode, device_index);
+
+    auto& left_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Left)];
+    auto& right_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)];
     auto& nfc_output_device = output_devices[3];
 
-    const auto virtual_nfc_result = nfc_output_device->SetPollingMode(polling_mode);
-    const auto mapped_nfc_result = output_device->SetPollingMode(polling_mode);
-
-    if (virtual_nfc_result == Common::Input::DriverResult::Success) {
-        return virtual_nfc_result;
+    if (device_index == EmulatedDeviceIndex::LeftIndex) {
+        return left_output_device->SetPollingMode(polling_mode);
     }
 
-    return mapped_nfc_result;
+    if (device_index == EmulatedDeviceIndex::RightIndex) {
+        const auto virtual_nfc_result = nfc_output_device->SetPollingMode(polling_mode);
+        const auto mapped_nfc_result = right_output_device->SetPollingMode(polling_mode);
+
+        if (virtual_nfc_result == Common::Input::DriverResult::Success) {
+            return virtual_nfc_result;
+        }
+        return mapped_nfc_result;
+    }
+
+    left_output_device->SetPollingMode(polling_mode);
+    right_output_device->SetPollingMode(polling_mode);
+    nfc_output_device->SetPollingMode(polling_mode);
+    return Common::Input::DriverResult::Success;
 }
 
 bool EmulatedController::SetCameraFormat(
diff --git a/src/core/hid/emulated_controller.h b/src/core/hid/emulated_controller.h
index edebfc15c..3ac77b2b5 100644
--- a/src/core/hid/emulated_controller.h
+++ b/src/core/hid/emulated_controller.h
@@ -363,10 +363,12 @@ public:
 
     /**
      * Sets the desired data to be polled from a controller
+     * @param device_index index of the controller to set the polling mode
      * @param polling_mode type of input desired buttons, gyro, nfc, ir, etc.
      * @return driver result from this command
      */
-    Common::Input::DriverResult SetPollingMode(Common::Input::PollingMode polling_mode);
+    Common::Input::DriverResult SetPollingMode(EmulatedDeviceIndex device_index,
+                                               Common::Input::PollingMode polling_mode);
 
     /**
      * Sets the desired camera format to be polled from a controller
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index fe5bf94d2..5713f1288 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -337,7 +337,19 @@ void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) {
     controller.is_connected = true;
     controller.device->Connect();
     controller.device->SetLedPattern();
-    controller.device->SetPollingMode(Common::Input::PollingMode::Active);
+    if (controller_type == Core::HID::NpadStyleIndex::JoyconDual) {
+        if (controller.is_dual_left_connected) {
+            controller.device->SetPollingMode(Core::HID::EmulatedDeviceIndex::LeftIndex,
+                                              Common::Input::PollingMode::Active);
+        }
+        if (controller.is_dual_right_connected) {
+            controller.device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
+                                              Common::Input::PollingMode::Active);
+        }
+    } else {
+        controller.device->SetPollingMode(Core::HID::EmulatedDeviceIndex::AllDevices,
+                                          Common::Input::PollingMode::Active);
+    }
     SignalStyleSetChangedEvent(npad_id);
     WriteEmptyEntry(controller.shared_memory);
 }
diff --git a/src/core/hle/service/hid/hidbus/ringcon.cpp b/src/core/hle/service/hid/hidbus/ringcon.cpp
index af776d506..78ed47014 100644
--- a/src/core/hle/service/hid/hidbus/ringcon.cpp
+++ b/src/core/hle/service/hid/hidbus/ringcon.cpp
@@ -18,12 +18,14 @@ RingController::RingController(Core::HID::HIDCore& hid_core_,
 RingController::~RingController() = default;
 
 void RingController::OnInit() {
-    input->SetPollingMode(Common::Input::PollingMode::Ring);
+    input->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
+                          Common::Input::PollingMode::Ring);
     return;
 }
 
 void RingController::OnRelease() {
-    input->SetPollingMode(Common::Input::PollingMode::Active);
+    input->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
+                          Common::Input::PollingMode::Active);
     return;
 };
 
diff --git a/src/core/hle/service/hid/irs.cpp b/src/core/hle/service/hid/irs.cpp
index 1a6fa2a44..52f402c56 100644
--- a/src/core/hle/service/hid/irs.cpp
+++ b/src/core/hle/service/hid/irs.cpp
@@ -108,7 +108,8 @@ void IRS::StopImageProcessor(Kernel::HLERequestContext& ctx) {
     auto result = IsIrCameraHandleValid(parameters.camera_handle);
     if (result.IsSuccess()) {
         // TODO: Stop Image processor
-        npad_device->SetPollingMode(Common::Input::PollingMode::Active);
+        npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
+                                    Common::Input::PollingMode::Active);
         result = ResultSuccess;
     }
 
@@ -140,7 +141,8 @@ void IRS::RunMomentProcessor(Kernel::HLERequestContext& ctx) {
         MakeProcessor<MomentProcessor>(parameters.camera_handle, device);
         auto& image_transfer_processor = GetProcessor<MomentProcessor>(parameters.camera_handle);
         image_transfer_processor.SetConfig(parameters.processor_config);
-        npad_device->SetPollingMode(Common::Input::PollingMode::IR);
+        npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
+                                    Common::Input::PollingMode::IR);
     }
 
     IPC::ResponseBuilder rb{ctx, 2};
@@ -172,7 +174,8 @@ void IRS::RunClusteringProcessor(Kernel::HLERequestContext& ctx) {
         auto& image_transfer_processor =
             GetProcessor<ClusteringProcessor>(parameters.camera_handle);
         image_transfer_processor.SetConfig(parameters.processor_config);
-        npad_device->SetPollingMode(Common::Input::PollingMode::IR);
+        npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
+                                    Common::Input::PollingMode::IR);
     }
 
     IPC::ResponseBuilder rb{ctx, 2};
@@ -222,7 +225,8 @@ void IRS::RunImageTransferProcessor(Kernel::HLERequestContext& ctx) {
             GetProcessor<ImageTransferProcessor>(parameters.camera_handle);
         image_transfer_processor.SetConfig(parameters.processor_config);
         image_transfer_processor.SetTransferMemoryPointer(transfer_memory);
-        npad_device->SetPollingMode(Common::Input::PollingMode::IR);
+        npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
+                                    Common::Input::PollingMode::IR);
     }
 
     IPC::ResponseBuilder rb{ctx, 2};
@@ -298,7 +302,8 @@ void IRS::RunTeraPluginProcessor(Kernel::HLERequestContext& ctx) {
         auto& image_transfer_processor =
             GetProcessor<TeraPluginProcessor>(parameters.camera_handle);
         image_transfer_processor.SetConfig(parameters.processor_config);
-        npad_device->SetPollingMode(Common::Input::PollingMode::IR);
+        npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
+                                    Common::Input::PollingMode::IR);
     }
 
     IPC::ResponseBuilder rb{ctx, 2};
@@ -348,7 +353,8 @@ void IRS::RunPointingProcessor(Kernel::HLERequestContext& ctx) {
         MakeProcessor<PointingProcessor>(camera_handle, device);
         auto& image_transfer_processor = GetProcessor<PointingProcessor>(camera_handle);
         image_transfer_processor.SetConfig(processor_config);
-        npad_device->SetPollingMode(Common::Input::PollingMode::IR);
+        npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
+                                    Common::Input::PollingMode::IR);
     }
 
     IPC::ResponseBuilder rb{ctx, 2};
@@ -459,7 +465,8 @@ void IRS::RunImageTransferExProcessor(Kernel::HLERequestContext& ctx) {
             GetProcessor<ImageTransferProcessor>(parameters.camera_handle);
         image_transfer_processor.SetConfig(parameters.processor_config);
         image_transfer_processor.SetTransferMemoryPointer(transfer_memory);
-        npad_device->SetPollingMode(Common::Input::PollingMode::IR);
+        npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
+                                    Common::Input::PollingMode::IR);
     }
 
     IPC::ResponseBuilder rb{ctx, 2};
@@ -486,7 +493,8 @@ void IRS::RunIrLedProcessor(Kernel::HLERequestContext& ctx) {
         MakeProcessor<IrLedProcessor>(camera_handle, device);
         auto& image_transfer_processor = GetProcessor<IrLedProcessor>(camera_handle);
         image_transfer_processor.SetConfig(processor_config);
-        npad_device->SetPollingMode(Common::Input::PollingMode::IR);
+        npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
+                                    Common::Input::PollingMode::IR);
     }
 
     IPC::ResponseBuilder rb{ctx, 2};
@@ -512,7 +520,8 @@ void IRS::StopImageProcessorAsync(Kernel::HLERequestContext& ctx) {
     auto result = IsIrCameraHandleValid(parameters.camera_handle);
     if (result.IsSuccess()) {
         // TODO: Stop image processor async
-        npad_device->SetPollingMode(Common::Input::PollingMode::Active);
+        npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
+                                    Common::Input::PollingMode::Active);
         result = ResultSuccess;
     }
 
diff --git a/src/core/hle/service/nfc/nfc_device.cpp b/src/core/hle/service/nfc/nfc_device.cpp
index c9815edbc..9a3234e8c 100644
--- a/src/core/hle/service/nfc/nfc_device.cpp
+++ b/src/core/hle/service/nfc/nfc_device.cpp
@@ -130,7 +130,8 @@ Result NfcDevice::StartDetection(NFP::TagProtocol allowed_protocol) {
         return WrongDeviceState;
     }
 
-    if (npad_device->SetPollingMode(Common::Input::PollingMode::NFC) !=
+    if (npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
+                                    Common::Input::PollingMode::NFC) !=
         Common::Input::DriverResult::Success) {
         LOG_ERROR(Service_NFC, "Nfc not supported");
         return NfcDisabled;
@@ -142,7 +143,8 @@ Result NfcDevice::StartDetection(NFP::TagProtocol allowed_protocol) {
 }
 
 Result NfcDevice::StopDetection() {
-    npad_device->SetPollingMode(Common::Input::PollingMode::Active);
+    npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
+                                Common::Input::PollingMode::Active);
 
     if (device_state == NFP::DeviceState::Initialized) {
         return ResultSuccess;
diff --git a/src/core/hle/service/nfp/nfp_device.cpp b/src/core/hle/service/nfp/nfp_device.cpp
index 7b8013961..e67a76f55 100644
--- a/src/core/hle/service/nfp/nfp_device.cpp
+++ b/src/core/hle/service/nfp/nfp_device.cpp
@@ -152,7 +152,8 @@ Result NfpDevice::StartDetection(TagProtocol allowed_protocol) {
         return WrongDeviceState;
     }
 
-    if (npad_device->SetPollingMode(Common::Input::PollingMode::NFC) !=
+    if (npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
+                                    Common::Input::PollingMode::NFC) !=
         Common::Input::DriverResult::Success) {
         LOG_ERROR(Service_NFP, "Nfc not supported");
         return NfcDisabled;
@@ -164,7 +165,8 @@ Result NfpDevice::StartDetection(TagProtocol allowed_protocol) {
 }
 
 Result NfpDevice::StopDetection() {
-    npad_device->SetPollingMode(Common::Input::PollingMode::Active);
+    npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
+                                Common::Input::PollingMode::Active);
 
     if (device_state == DeviceState::Initialized) {
         return ResultSuccess;
diff --git a/src/yuzu/configuration/configure_ringcon.cpp b/src/yuzu/configuration/configure_ringcon.cpp
index 697c36fb4..1275f10c8 100644
--- a/src/yuzu/configuration/configure_ringcon.cpp
+++ b/src/yuzu/configuration/configure_ringcon.cpp
@@ -214,7 +214,8 @@ ConfigureRingController::ConfigureRingController(QWidget* parent,
 }
 
 ConfigureRingController::~ConfigureRingController() {
-    emulated_controller->SetPollingMode(Common::Input::PollingMode::Active);
+    emulated_controller->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
+                                        Common::Input::PollingMode::Active);
     emulated_controller->DisableConfiguration();
 
     if (is_controller_set) {
@@ -290,7 +291,8 @@ void ConfigureRingController::EnableRingController() {
     // SetPollingMode is blocking. Allow to update the button status before calling the command
     repaint();
 
-    const auto result = emulated_controller->SetPollingMode(Common::Input::PollingMode::Ring);
+    const auto result = emulated_controller->SetPollingMode(
+        Core::HID::EmulatedDeviceIndex::RightIndex, Common::Input::PollingMode::Ring);
     switch (result) {
     case Common::Input::DriverResult::Success:
         is_ring_enabled = true;