summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/hid/emulated_controller.cpp298
-rw-r--r--src/core/hid/emulated_controller.h64
-rw-r--r--src/core/hid/emulated_devices.cpp46
-rw-r--r--src/core/hid/emulated_devices.h18
-rw-r--r--src/core/hid/input_converter.cpp12
-rw-r--r--src/core/hid/input_converter.h10
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp18
-rw-r--r--src/core/hle/service/hid/hidbus.cpp24
-rw-r--r--src/core/hle/service/hid/hidbus/ringcon.cpp8
-rw-r--r--src/core/hle/service/hid/hidbus/ringcon.h4
-rw-r--r--src/core/hle/service/hid/irs.cpp18
-rw-r--r--src/core/hle/service/nfc/nfc_device.cpp7
-rw-r--r--src/core/hle/service/nfp/nfp_device.cpp7
13 files changed, 361 insertions, 173 deletions
diff --git a/src/core/hid/emulated_controller.cpp b/src/core/hid/emulated_controller.cpp
index a959c9db9..6e9812e6e 100644
--- a/src/core/hid/emulated_controller.cpp
+++ b/src/core/hid/emulated_controller.cpp
@@ -2,6 +2,7 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include <algorithm> 4#include <algorithm>
5#include <common/scope_exit.h>
5 6
6#include "common/polyfill_ranges.h" 7#include "common/polyfill_ranges.h"
7#include "common/thread.h" 8#include "common/thread.h"
@@ -94,6 +95,7 @@ void EmulatedController::ReloadFromSettings() {
94 motion_params[index] = Common::ParamPackage(player.motions[index]); 95 motion_params[index] = Common::ParamPackage(player.motions[index]);
95 } 96 }
96 97
98 controller.color_values = {};
97 controller.colors_state.fullkey = { 99 controller.colors_state.fullkey = {
98 .body = GetNpadColor(player.body_color_left), 100 .body = GetNpadColor(player.body_color_left),
99 .button = GetNpadColor(player.button_color_left), 101 .button = GetNpadColor(player.button_color_left),
@@ -107,6 +109,8 @@ void EmulatedController::ReloadFromSettings() {
107 .button = GetNpadColor(player.button_color_right), 109 .button = GetNpadColor(player.button_color_right),
108 }; 110 };
109 111
112 ring_params[0] = Common::ParamPackage(Settings::values.ringcon_analogs);
113
110 // Other or debug controller should always be a pro controller 114 // Other or debug controller should always be a pro controller
111 if (npad_id_type != NpadIdType::Other) { 115 if (npad_id_type != NpadIdType::Other) {
112 SetNpadStyleIndex(MapSettingsTypeToNPad(player.controller_type)); 116 SetNpadStyleIndex(MapSettingsTypeToNPad(player.controller_type));
@@ -133,18 +137,28 @@ void EmulatedController::LoadDevices() {
133 trigger_params[LeftIndex] = button_params[Settings::NativeButton::ZL]; 137 trigger_params[LeftIndex] = button_params[Settings::NativeButton::ZL];
134 trigger_params[RightIndex] = button_params[Settings::NativeButton::ZR]; 138 trigger_params[RightIndex] = button_params[Settings::NativeButton::ZR];
135 139
140 color_params[LeftIndex] = left_joycon;
141 color_params[RightIndex] = right_joycon;
142 color_params[LeftIndex].Set("color", true);
143 color_params[RightIndex].Set("color", true);
144
136 battery_params[LeftIndex] = left_joycon; 145 battery_params[LeftIndex] = left_joycon;
137 battery_params[RightIndex] = right_joycon; 146 battery_params[RightIndex] = right_joycon;
138 battery_params[LeftIndex].Set("battery", true); 147 battery_params[LeftIndex].Set("battery", true);
139 battery_params[RightIndex].Set("battery", true); 148 battery_params[RightIndex].Set("battery", true);
140 149
141 camera_params = Common::ParamPackage{"engine:camera,camera:1"}; 150 camera_params[0] = right_joycon;
142 nfc_params = Common::ParamPackage{"engine:virtual_amiibo,nfc:1"}; 151 camera_params[0].Set("camera", true);
152 camera_params[1] = Common::ParamPackage{"engine:camera,camera:1"};
153 ring_params[1] = Common::ParamPackage{"engine:joycon,axis_x:100,axis_y:101"};
154 nfc_params[0] = Common::ParamPackage{"engine:virtual_amiibo,nfc:1"};
155 nfc_params[1] = right_joycon;
156 nfc_params[1].Set("nfc", true);
143 157
144 output_params[LeftIndex] = left_joycon; 158 output_params[LeftIndex] = left_joycon;
145 output_params[RightIndex] = right_joycon; 159 output_params[RightIndex] = right_joycon;
146 output_params[2] = camera_params; 160 output_params[2] = camera_params[1];
147 output_params[3] = nfc_params; 161 output_params[3] = nfc_params[0];
148 output_params[LeftIndex].Set("output", true); 162 output_params[LeftIndex].Set("output", true);
149 output_params[RightIndex].Set("output", true); 163 output_params[RightIndex].Set("output", true);
150 output_params[2].Set("output", true); 164 output_params[2].Set("output", true);
@@ -160,8 +174,11 @@ void EmulatedController::LoadDevices() {
160 Common::Input::CreateInputDevice); 174 Common::Input::CreateInputDevice);
161 std::ranges::transform(battery_params, battery_devices.begin(), 175 std::ranges::transform(battery_params, battery_devices.begin(),
162 Common::Input::CreateInputDevice); 176 Common::Input::CreateInputDevice);
163 camera_devices = Common::Input::CreateInputDevice(camera_params); 177 std::ranges::transform(color_params, color_devices.begin(), Common::Input::CreateInputDevice);
164 nfc_devices = Common::Input::CreateInputDevice(nfc_params); 178 std::ranges::transform(camera_params, camera_devices.begin(), Common::Input::CreateInputDevice);
179 std::ranges::transform(ring_params, ring_analog_devices.begin(),
180 Common::Input::CreateInputDevice);
181 std::ranges::transform(nfc_params, nfc_devices.begin(), Common::Input::CreateInputDevice);
165 std::ranges::transform(output_params, output_devices.begin(), 182 std::ranges::transform(output_params, output_devices.begin(),
166 Common::Input::CreateOutputDevice); 183 Common::Input::CreateOutputDevice);
167 184
@@ -323,6 +340,19 @@ void EmulatedController::ReloadInput() {
323 battery_devices[index]->ForceUpdate(); 340 battery_devices[index]->ForceUpdate();
324 } 341 }
325 342
343 for (std::size_t index = 0; index < color_devices.size(); ++index) {
344 if (!color_devices[index]) {
345 continue;
346 }
347 color_devices[index]->SetCallback({
348 .on_change =
349 [this, index](const Common::Input::CallbackStatus& callback) {
350 SetColors(callback, index);
351 },
352 });
353 color_devices[index]->ForceUpdate();
354 }
355
326 for (std::size_t index = 0; index < motion_devices.size(); ++index) { 356 for (std::size_t index = 0; index < motion_devices.size(); ++index) {
327 if (!motion_devices[index]) { 357 if (!motion_devices[index]) {
328 continue; 358 continue;
@@ -336,22 +366,37 @@ void EmulatedController::ReloadInput() {
336 motion_devices[index]->ForceUpdate(); 366 motion_devices[index]->ForceUpdate();
337 } 367 }
338 368
339 if (camera_devices) { 369 for (std::size_t index = 0; index < camera_devices.size(); ++index) {
340 camera_devices->SetCallback({ 370 if (!camera_devices[index]) {
371 continue;
372 }
373 camera_devices[index]->SetCallback({
341 .on_change = 374 .on_change =
342 [this](const Common::Input::CallbackStatus& callback) { SetCamera(callback); }, 375 [this](const Common::Input::CallbackStatus& callback) { SetCamera(callback); },
343 }); 376 });
344 camera_devices->ForceUpdate(); 377 camera_devices[index]->ForceUpdate();
345 } 378 }
346 379
347 if (nfc_devices) { 380 for (std::size_t index = 0; index < ring_analog_devices.size(); ++index) {
348 if (npad_id_type == NpadIdType::Handheld || npad_id_type == NpadIdType::Player1) { 381 if (!ring_analog_devices[index]) {
349 nfc_devices->SetCallback({ 382 continue;
350 .on_change =
351 [this](const Common::Input::CallbackStatus& callback) { SetNfc(callback); },
352 });
353 nfc_devices->ForceUpdate();
354 } 383 }
384 ring_analog_devices[index]->SetCallback({
385 .on_change =
386 [this](const Common::Input::CallbackStatus& callback) { SetRingAnalog(callback); },
387 });
388 ring_analog_devices[index]->ForceUpdate();
389 }
390
391 for (std::size_t index = 0; index < nfc_devices.size(); ++index) {
392 if (!nfc_devices[index]) {
393 continue;
394 }
395 nfc_devices[index]->SetCallback({
396 .on_change =
397 [this](const Common::Input::CallbackStatus& callback) { SetNfc(callback); },
398 });
399 nfc_devices[index]->ForceUpdate();
355 } 400 }
356 401
357 // Register TAS devices. No need to force update 402 // Register TAS devices. No need to force update
@@ -421,6 +466,9 @@ void EmulatedController::UnloadInput() {
421 for (auto& battery : battery_devices) { 466 for (auto& battery : battery_devices) {
422 battery.reset(); 467 battery.reset();
423 } 468 }
469 for (auto& color : color_devices) {
470 color.reset();
471 }
424 for (auto& output : output_devices) { 472 for (auto& output : output_devices) {
425 output.reset(); 473 output.reset();
426 } 474 }
@@ -436,8 +484,15 @@ void EmulatedController::UnloadInput() {
436 for (auto& stick : virtual_stick_devices) { 484 for (auto& stick : virtual_stick_devices) {
437 stick.reset(); 485 stick.reset();
438 } 486 }
439 camera_devices.reset(); 487 for (auto& camera : camera_devices) {
440 nfc_devices.reset(); 488 camera.reset();
489 }
490 for (auto& ring : ring_analog_devices) {
491 ring.reset();
492 }
493 for (auto& nfc : nfc_devices) {
494 nfc.reset();
495 }
441} 496}
442 497
443void EmulatedController::EnableConfiguration() { 498void EmulatedController::EnableConfiguration() {
@@ -449,6 +504,11 @@ void EmulatedController::EnableConfiguration() {
449void EmulatedController::DisableConfiguration() { 504void EmulatedController::DisableConfiguration() {
450 is_configuring = false; 505 is_configuring = false;
451 506
507 // Get Joycon colors before turning on the controller
508 for (const auto& color_device : color_devices) {
509 color_device->ForceUpdate();
510 }
511
452 // Apply temporary npad type to the real controller 512 // Apply temporary npad type to the real controller
453 if (tmp_npad_type != npad_type) { 513 if (tmp_npad_type != npad_type) {
454 if (is_connected) { 514 if (is_connected) {
@@ -502,6 +562,9 @@ void EmulatedController::SaveCurrentConfig() {
502 for (std::size_t index = 0; index < player.motions.size(); ++index) { 562 for (std::size_t index = 0; index < player.motions.size(); ++index) {
503 player.motions[index] = motion_params[index].Serialize(); 563 player.motions[index] = motion_params[index].Serialize();
504 } 564 }
565 if (npad_id_type == NpadIdType::Player1) {
566 Settings::values.ringcon_analogs = ring_params[0].Serialize();
567 }
505} 568}
506 569
507void EmulatedController::RestoreConfig() { 570void EmulatedController::RestoreConfig() {
@@ -773,17 +836,21 @@ void EmulatedController::SetStick(const Common::Input::CallbackStatus& callback,
773 if (index >= controller.stick_values.size()) { 836 if (index >= controller.stick_values.size()) {
774 return; 837 return;
775 } 838 }
776 std::unique_lock lock{mutex}; 839 auto trigger_guard =
840 SCOPE_GUARD({ TriggerOnChange(ControllerTriggerType::Stick, !is_configuring); });
841 std::scoped_lock lock{mutex};
777 const auto stick_value = TransformToStick(callback); 842 const auto stick_value = TransformToStick(callback);
778 843
779 // Only read stick values that have the same uuid or are over the threshold to avoid flapping 844 // Only read stick values that have the same uuid or are over the threshold to avoid flapping
780 if (controller.stick_values[index].uuid != uuid) { 845 if (controller.stick_values[index].uuid != uuid) {
781 const bool is_tas = uuid == TAS_UUID; 846 const bool is_tas = uuid == TAS_UUID;
782 if (is_tas && stick_value.x.value == 0 && stick_value.y.value == 0) { 847 if (is_tas && stick_value.x.value == 0 && stick_value.y.value == 0) {
848 trigger_guard.Cancel();
783 return; 849 return;
784 } 850 }
785 if (!is_tas && !stick_value.down && !stick_value.up && !stick_value.left && 851 if (!is_tas && !stick_value.down && !stick_value.up && !stick_value.left &&
786 !stick_value.right) { 852 !stick_value.right) {
853 trigger_guard.Cancel();
787 return; 854 return;
788 } 855 }
789 } 856 }
@@ -794,8 +861,6 @@ void EmulatedController::SetStick(const Common::Input::CallbackStatus& callback,
794 if (is_configuring) { 861 if (is_configuring) {
795 controller.analog_stick_state.left = {}; 862 controller.analog_stick_state.left = {};
796 controller.analog_stick_state.right = {}; 863 controller.analog_stick_state.right = {};
797 lock.unlock();
798 TriggerOnChange(ControllerTriggerType::Stick, false);
799 return; 864 return;
800 } 865 }
801 866
@@ -827,9 +892,6 @@ void EmulatedController::SetStick(const Common::Input::CallbackStatus& callback,
827 controller.npad_button_state.stick_r_down.Assign(controller.stick_values[index].down); 892 controller.npad_button_state.stick_r_down.Assign(controller.stick_values[index].down);
828 break; 893 break;
829 } 894 }
830
831 lock.unlock();
832 TriggerOnChange(ControllerTriggerType::Stick, true);
833} 895}
834 896
835void EmulatedController::SetTrigger(const Common::Input::CallbackStatus& callback, 897void EmulatedController::SetTrigger(const Common::Input::CallbackStatus& callback,
@@ -837,7 +899,9 @@ void EmulatedController::SetTrigger(const Common::Input::CallbackStatus& callbac
837 if (index >= controller.trigger_values.size()) { 899 if (index >= controller.trigger_values.size()) {
838 return; 900 return;
839 } 901 }
840 std::unique_lock lock{mutex}; 902 auto trigger_guard =
903 SCOPE_GUARD({ TriggerOnChange(ControllerTriggerType::Trigger, !is_configuring); });
904 std::scoped_lock lock{mutex};
841 const auto trigger_value = TransformToTrigger(callback); 905 const auto trigger_value = TransformToTrigger(callback);
842 906
843 // Only read trigger values that have the same uuid or are pressed once 907 // Only read trigger values that have the same uuid or are pressed once
@@ -853,13 +917,12 @@ void EmulatedController::SetTrigger(const Common::Input::CallbackStatus& callbac
853 if (is_configuring) { 917 if (is_configuring) {
854 controller.gc_trigger_state.left = 0; 918 controller.gc_trigger_state.left = 0;
855 controller.gc_trigger_state.right = 0; 919 controller.gc_trigger_state.right = 0;
856 lock.unlock();
857 TriggerOnChange(ControllerTriggerType::Trigger, false);
858 return; 920 return;
859 } 921 }
860 922
861 // Only GC controllers have analog triggers 923 // Only GC controllers have analog triggers
862 if (npad_type != NpadStyleIndex::GameCube) { 924 if (npad_type != NpadStyleIndex::GameCube) {
925 trigger_guard.Cancel();
863 return; 926 return;
864 } 927 }
865 928
@@ -876,9 +939,6 @@ void EmulatedController::SetTrigger(const Common::Input::CallbackStatus& callbac
876 controller.npad_button_state.zr.Assign(trigger.pressed.value); 939 controller.npad_button_state.zr.Assign(trigger.pressed.value);
877 break; 940 break;
878 } 941 }
879
880 lock.unlock();
881 TriggerOnChange(ControllerTriggerType::Trigger, true);
882} 942}
883 943
884void EmulatedController::SetMotion(const Common::Input::CallbackStatus& callback, 944void EmulatedController::SetMotion(const Common::Input::CallbackStatus& callback,
@@ -886,7 +946,8 @@ void EmulatedController::SetMotion(const Common::Input::CallbackStatus& callback
886 if (index >= controller.motion_values.size()) { 946 if (index >= controller.motion_values.size()) {
887 return; 947 return;
888 } 948 }
889 std::unique_lock lock{mutex}; 949 SCOPE_EXIT({ TriggerOnChange(ControllerTriggerType::Motion, !is_configuring); });
950 std::scoped_lock lock{mutex};
890 auto& raw_status = controller.motion_values[index].raw_status; 951 auto& raw_status = controller.motion_values[index].raw_status;
891 auto& emulated = controller.motion_values[index].emulated; 952 auto& emulated = controller.motion_values[index].emulated;
892 953
@@ -907,8 +968,6 @@ void EmulatedController::SetMotion(const Common::Input::CallbackStatus& callback
907 force_update_motion = raw_status.force_update; 968 force_update_motion = raw_status.force_update;
908 969
909 if (is_configuring) { 970 if (is_configuring) {
910 lock.unlock();
911 TriggerOnChange(ControllerTriggerType::Motion, false);
912 return; 971 return;
913 } 972 }
914 973
@@ -918,9 +977,56 @@ void EmulatedController::SetMotion(const Common::Input::CallbackStatus& callback
918 motion.rotation = emulated.GetRotations(); 977 motion.rotation = emulated.GetRotations();
919 motion.orientation = emulated.GetOrientation(); 978 motion.orientation = emulated.GetOrientation();
920 motion.is_at_rest = !emulated.IsMoving(motion_sensitivity); 979 motion.is_at_rest = !emulated.IsMoving(motion_sensitivity);
980}
921 981
922 lock.unlock(); 982void EmulatedController::SetColors(const Common::Input::CallbackStatus& callback,
923 TriggerOnChange(ControllerTriggerType::Motion, true); 983 std::size_t index) {
984 if (index >= controller.color_values.size()) {
985 return;
986 }
987 auto trigger_guard =
988 SCOPE_GUARD({ TriggerOnChange(ControllerTriggerType::Color, !is_configuring); });
989 std::scoped_lock lock{mutex};
990 controller.color_values[index] = TransformToColor(callback);
991
992 if (is_configuring) {
993 return;
994 }
995
996 if (controller.color_values[index].body == 0) {
997 trigger_guard.Cancel();
998 return;
999 }
1000
1001 controller.colors_state.fullkey = {
1002 .body = GetNpadColor(controller.color_values[index].body),
1003 .button = GetNpadColor(controller.color_values[index].buttons),
1004 };
1005 if (npad_type == NpadStyleIndex::ProController) {
1006 controller.colors_state.left = {
1007 .body = GetNpadColor(controller.color_values[index].left_grip),
1008 .button = GetNpadColor(controller.color_values[index].buttons),
1009 };
1010 controller.colors_state.right = {
1011 .body = GetNpadColor(controller.color_values[index].right_grip),
1012 .button = GetNpadColor(controller.color_values[index].buttons),
1013 };
1014 } else {
1015 switch (index) {
1016 case LeftIndex:
1017 controller.colors_state.left = {
1018 .body = GetNpadColor(controller.color_values[index].body),
1019 .button = GetNpadColor(controller.color_values[index].buttons),
1020 };
1021 break;
1022 case RightIndex:
1023 controller.colors_state.right = {
1024 .body = GetNpadColor(controller.color_values[index].body),
1025 .button = GetNpadColor(controller.color_values[index].buttons),
1026 };
1027 break;
1028 }
1029 }
924} 1030}
925 1031
926void EmulatedController::SetBattery(const Common::Input::CallbackStatus& callback, 1032void EmulatedController::SetBattery(const Common::Input::CallbackStatus& callback,
@@ -928,12 +1034,11 @@ void EmulatedController::SetBattery(const Common::Input::CallbackStatus& callbac
928 if (index >= controller.battery_values.size()) { 1034 if (index >= controller.battery_values.size()) {
929 return; 1035 return;
930 } 1036 }
931 std::unique_lock lock{mutex}; 1037 SCOPE_EXIT({ TriggerOnChange(ControllerTriggerType::Battery, !is_configuring); });
1038 std::scoped_lock lock{mutex};
932 controller.battery_values[index] = TransformToBattery(callback); 1039 controller.battery_values[index] = TransformToBattery(callback);
933 1040
934 if (is_configuring) { 1041 if (is_configuring) {
935 lock.unlock();
936 TriggerOnChange(ControllerTriggerType::Battery, false);
937 return; 1042 return;
938 } 1043 }
939 1044
@@ -989,18 +1094,14 @@ void EmulatedController::SetBattery(const Common::Input::CallbackStatus& callbac
989 }; 1094 };
990 break; 1095 break;
991 } 1096 }
992
993 lock.unlock();
994 TriggerOnChange(ControllerTriggerType::Battery, true);
995} 1097}
996 1098
997void EmulatedController::SetCamera(const Common::Input::CallbackStatus& callback) { 1099void EmulatedController::SetCamera(const Common::Input::CallbackStatus& callback) {
998 std::unique_lock lock{mutex}; 1100 SCOPE_EXIT({ TriggerOnChange(ControllerTriggerType::IrSensor, !is_configuring); });
1101 std::scoped_lock lock{mutex};
999 controller.camera_values = TransformToCamera(callback); 1102 controller.camera_values = TransformToCamera(callback);
1000 1103
1001 if (is_configuring) { 1104 if (is_configuring) {
1002 lock.unlock();
1003 TriggerOnChange(ControllerTriggerType::IrSensor, false);
1004 return; 1105 return;
1005 } 1106 }
1006 1107
@@ -1008,18 +1109,28 @@ void EmulatedController::SetCamera(const Common::Input::CallbackStatus& callback
1008 controller.camera_state.format = 1109 controller.camera_state.format =
1009 static_cast<Core::IrSensor::ImageTransferProcessorFormat>(controller.camera_values.format); 1110 static_cast<Core::IrSensor::ImageTransferProcessorFormat>(controller.camera_values.format);
1010 controller.camera_state.data = controller.camera_values.data; 1111 controller.camera_state.data = controller.camera_values.data;
1112}
1011 1113
1012 lock.unlock(); 1114void EmulatedController::SetRingAnalog(const Common::Input::CallbackStatus& callback) {
1013 TriggerOnChange(ControllerTriggerType::IrSensor, true); 1115 SCOPE_EXIT({ TriggerOnChange(ControllerTriggerType::RingController, !is_configuring); });
1116 std::scoped_lock lock{mutex};
1117 const auto force_value = TransformToStick(callback);
1118
1119 controller.ring_analog_value = force_value.x;
1120
1121 if (is_configuring) {
1122 return;
1123 }
1124
1125 controller.ring_analog_state.force = force_value.x.value;
1014} 1126}
1015 1127
1016void EmulatedController::SetNfc(const Common::Input::CallbackStatus& callback) { 1128void EmulatedController::SetNfc(const Common::Input::CallbackStatus& callback) {
1017 std::unique_lock lock{mutex}; 1129 SCOPE_EXIT({ TriggerOnChange(ControllerTriggerType::Nfc, !is_configuring); });
1130 std::scoped_lock lock{mutex};
1018 controller.nfc_values = TransformToNfc(callback); 1131 controller.nfc_values = TransformToNfc(callback);
1019 1132
1020 if (is_configuring) { 1133 if (is_configuring) {
1021 lock.unlock();
1022 TriggerOnChange(ControllerTriggerType::Nfc, false);
1023 return; 1134 return;
1024 } 1135 }
1025 1136
@@ -1027,9 +1138,6 @@ void EmulatedController::SetNfc(const Common::Input::CallbackStatus& callback) {
1027 controller.nfc_values.state, 1138 controller.nfc_values.state,
1028 controller.nfc_values.data, 1139 controller.nfc_values.data,
1029 }; 1140 };
1030
1031 lock.unlock();
1032 TriggerOnChange(ControllerTriggerType::Nfc, true);
1033} 1141}
1034 1142
1035bool EmulatedController::SetVibration(std::size_t device_index, VibrationValue vibration) { 1143bool EmulatedController::SetVibration(std::size_t device_index, VibrationValue vibration) {
@@ -1061,7 +1169,7 @@ bool EmulatedController::SetVibration(std::size_t device_index, VibrationValue v
1061 .type = type, 1169 .type = type,
1062 }; 1170 };
1063 return output_devices[device_index]->SetVibration(status) == 1171 return output_devices[device_index]->SetVibration(status) ==
1064 Common::Input::VibrationError::None; 1172 Common::Input::DriverResult::Success;
1065} 1173}
1066 1174
1067bool EmulatedController::IsVibrationEnabled(std::size_t device_index) { 1175bool EmulatedController::IsVibrationEnabled(std::size_t device_index) {
@@ -1083,16 +1191,32 @@ bool EmulatedController::IsVibrationEnabled(std::size_t device_index) {
1083 return output_devices[device_index]->IsVibrationEnabled(); 1191 return output_devices[device_index]->IsVibrationEnabled();
1084} 1192}
1085 1193
1086bool EmulatedController::SetPollingMode(Common::Input::PollingMode polling_mode) { 1194Common::Input::DriverResult EmulatedController::SetPollingMode(
1087 LOG_INFO(Service_HID, "Set polling mode {}", polling_mode); 1195 EmulatedDeviceIndex device_index, Common::Input::PollingMode polling_mode) {
1088 auto& output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)]; 1196 LOG_INFO(Service_HID, "Set polling mode {}, device_index={}", polling_mode, device_index);
1197
1198 auto& left_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Left)];
1199 auto& right_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)];
1089 auto& nfc_output_device = output_devices[3]; 1200 auto& nfc_output_device = output_devices[3];
1090 1201
1091 const auto virtual_nfc_result = nfc_output_device->SetPollingMode(polling_mode); 1202 if (device_index == EmulatedDeviceIndex::LeftIndex) {
1092 const auto mapped_nfc_result = output_device->SetPollingMode(polling_mode); 1203 return left_output_device->SetPollingMode(polling_mode);
1204 }
1205
1206 if (device_index == EmulatedDeviceIndex::RightIndex) {
1207 const auto virtual_nfc_result = nfc_output_device->SetPollingMode(polling_mode);
1208 const auto mapped_nfc_result = right_output_device->SetPollingMode(polling_mode);
1209
1210 if (virtual_nfc_result == Common::Input::DriverResult::Success) {
1211 return virtual_nfc_result;
1212 }
1213 return mapped_nfc_result;
1214 }
1093 1215
1094 return virtual_nfc_result == Common::Input::PollingError::None || 1216 left_output_device->SetPollingMode(polling_mode);
1095 mapped_nfc_result == Common::Input::PollingError::None; 1217 right_output_device->SetPollingMode(polling_mode);
1218 nfc_output_device->SetPollingMode(polling_mode);
1219 return Common::Input::DriverResult::Success;
1096} 1220}
1097 1221
1098bool EmulatedController::SetCameraFormat( 1222bool EmulatedController::SetCameraFormat(
@@ -1103,13 +1227,22 @@ bool EmulatedController::SetCameraFormat(
1103 auto& camera_output_device = output_devices[2]; 1227 auto& camera_output_device = output_devices[2];
1104 1228
1105 if (right_output_device->SetCameraFormat(static_cast<Common::Input::CameraFormat>( 1229 if (right_output_device->SetCameraFormat(static_cast<Common::Input::CameraFormat>(
1106 camera_format)) == Common::Input::CameraError::None) { 1230 camera_format)) == Common::Input::DriverResult::Success) {
1107 return true; 1231 return true;
1108 } 1232 }
1109 1233
1110 // Fallback to Qt camera if native device doesn't have support 1234 // Fallback to Qt camera if native device doesn't have support
1111 return camera_output_device->SetCameraFormat(static_cast<Common::Input::CameraFormat>( 1235 return camera_output_device->SetCameraFormat(static_cast<Common::Input::CameraFormat>(
1112 camera_format)) == Common::Input::CameraError::None; 1236 camera_format)) == Common::Input::DriverResult::Success;
1237}
1238
1239Common::ParamPackage EmulatedController::GetRingParam() const {
1240 return ring_params[0];
1241}
1242
1243void EmulatedController::SetRingParam(Common::ParamPackage param) {
1244 ring_params[0] = std::move(param);
1245 ReloadInput();
1113} 1246}
1114 1247
1115bool EmulatedController::HasNfc() const { 1248bool EmulatedController::HasNfc() const {
@@ -1263,39 +1396,35 @@ void EmulatedController::Connect(bool use_temporary_value) {
1263 return; 1396 return;
1264 } 1397 }
1265 1398
1266 std::unique_lock lock{mutex}; 1399 auto trigger_guard =
1400 SCOPE_GUARD({ TriggerOnChange(ControllerTriggerType::Connected, !is_configuring); });
1401 std::scoped_lock lock{mutex};
1267 if (is_configuring) { 1402 if (is_configuring) {
1268 tmp_is_connected = true; 1403 tmp_is_connected = true;
1269 lock.unlock();
1270 TriggerOnChange(ControllerTriggerType::Connected, false);
1271 return; 1404 return;
1272 } 1405 }
1273 1406
1274 if (is_connected) { 1407 if (is_connected) {
1408 trigger_guard.Cancel();
1275 return; 1409 return;
1276 } 1410 }
1277 is_connected = true; 1411 is_connected = true;
1278
1279 lock.unlock();
1280 TriggerOnChange(ControllerTriggerType::Connected, true);
1281} 1412}
1282 1413
1283void EmulatedController::Disconnect() { 1414void EmulatedController::Disconnect() {
1284 std::unique_lock lock{mutex}; 1415 auto trigger_guard =
1416 SCOPE_GUARD({ TriggerOnChange(ControllerTriggerType::Disconnected, !is_configuring); });
1417 std::scoped_lock lock{mutex};
1285 if (is_configuring) { 1418 if (is_configuring) {
1286 tmp_is_connected = false; 1419 tmp_is_connected = false;
1287 lock.unlock();
1288 TriggerOnChange(ControllerTriggerType::Disconnected, false);
1289 return; 1420 return;
1290 } 1421 }
1291 1422
1292 if (!is_connected) { 1423 if (!is_connected) {
1424 trigger_guard.Cancel();
1293 return; 1425 return;
1294 } 1426 }
1295 is_connected = false; 1427 is_connected = false;
1296
1297 lock.unlock();
1298 TriggerOnChange(ControllerTriggerType::Disconnected, true);
1299} 1428}
1300 1429
1301bool EmulatedController::IsConnected(bool get_temporary_value) const { 1430bool EmulatedController::IsConnected(bool get_temporary_value) const {
@@ -1320,19 +1449,21 @@ NpadStyleIndex EmulatedController::GetNpadStyleIndex(bool get_temporary_value) c
1320} 1449}
1321 1450
1322void EmulatedController::SetNpadStyleIndex(NpadStyleIndex npad_type_) { 1451void EmulatedController::SetNpadStyleIndex(NpadStyleIndex npad_type_) {
1323 std::unique_lock lock{mutex}; 1452 auto trigger_guard =
1453 SCOPE_GUARD({ TriggerOnChange(ControllerTriggerType::Type, !is_configuring); });
1454 std::scoped_lock lock{mutex};
1324 1455
1325 if (is_configuring) { 1456 if (is_configuring) {
1326 if (tmp_npad_type == npad_type_) { 1457 if (tmp_npad_type == npad_type_) {
1458 trigger_guard.Cancel();
1327 return; 1459 return;
1328 } 1460 }
1329 tmp_npad_type = npad_type_; 1461 tmp_npad_type = npad_type_;
1330 lock.unlock();
1331 TriggerOnChange(ControllerTriggerType::Type, false);
1332 return; 1462 return;
1333 } 1463 }
1334 1464
1335 if (npad_type == npad_type_) { 1465 if (npad_type == npad_type_) {
1466 trigger_guard.Cancel();
1336 return; 1467 return;
1337 } 1468 }
1338 if (is_connected) { 1469 if (is_connected) {
@@ -1340,9 +1471,6 @@ void EmulatedController::SetNpadStyleIndex(NpadStyleIndex npad_type_) {
1340 NpadIdTypeToIndex(npad_id_type)); 1471 NpadIdTypeToIndex(npad_id_type));
1341 } 1472 }
1342 npad_type = npad_type_; 1473 npad_type = npad_type_;
1343
1344 lock.unlock();
1345 TriggerOnChange(ControllerTriggerType::Type, true);
1346} 1474}
1347 1475
1348LedPattern EmulatedController::GetLedPattern() const { 1476LedPattern EmulatedController::GetLedPattern() const {
@@ -1403,6 +1531,10 @@ CameraValues EmulatedController::GetCameraValues() const {
1403 return controller.camera_values; 1531 return controller.camera_values;
1404} 1532}
1405 1533
1534RingAnalogValue EmulatedController::GetRingSensorValues() const {
1535 return controller.ring_analog_value;
1536}
1537
1406HomeButtonState EmulatedController::GetHomeButtons() const { 1538HomeButtonState EmulatedController::GetHomeButtons() const {
1407 std::scoped_lock lock{mutex}; 1539 std::scoped_lock lock{mutex};
1408 if (is_configuring) { 1540 if (is_configuring) {
@@ -1436,7 +1568,7 @@ DebugPadButton EmulatedController::GetDebugPadButtons() const {
1436} 1568}
1437 1569
1438AnalogSticks EmulatedController::GetSticks() const { 1570AnalogSticks EmulatedController::GetSticks() const {
1439 std::unique_lock lock{mutex}; 1571 std::scoped_lock lock{mutex};
1440 1572
1441 if (is_configuring) { 1573 if (is_configuring) {
1442 return {}; 1574 return {};
@@ -1486,6 +1618,10 @@ const CameraState& EmulatedController::GetCamera() const {
1486 return controller.camera_state; 1618 return controller.camera_state;
1487} 1619}
1488 1620
1621RingSensorForce EmulatedController::GetRingSensorForce() const {
1622 return controller.ring_analog_state;
1623}
1624
1489const NfcState& EmulatedController::GetNfc() const { 1625const NfcState& EmulatedController::GetNfc() const {
1490 std::scoped_lock lock{mutex}; 1626 std::scoped_lock lock{mutex};
1491 return controller.nfc_state; 1627 return controller.nfc_state;
diff --git a/src/core/hid/emulated_controller.h b/src/core/hid/emulated_controller.h
index a398543a6..3ac77b2b5 100644
--- a/src/core/hid/emulated_controller.h
+++ b/src/core/hid/emulated_controller.h
@@ -35,19 +35,27 @@ using ControllerMotionDevices =
35 std::array<std::unique_ptr<Common::Input::InputDevice>, Settings::NativeMotion::NumMotions>; 35 std::array<std::unique_ptr<Common::Input::InputDevice>, Settings::NativeMotion::NumMotions>;
36using TriggerDevices = 36using TriggerDevices =
37 std::array<std::unique_ptr<Common::Input::InputDevice>, Settings::NativeTrigger::NumTriggers>; 37 std::array<std::unique_ptr<Common::Input::InputDevice>, Settings::NativeTrigger::NumTriggers>;
38using ColorDevices =
39 std::array<std::unique_ptr<Common::Input::InputDevice>, max_emulated_controllers>;
38using BatteryDevices = 40using BatteryDevices =
39 std::array<std::unique_ptr<Common::Input::InputDevice>, max_emulated_controllers>; 41 std::array<std::unique_ptr<Common::Input::InputDevice>, max_emulated_controllers>;
40using CameraDevices = std::unique_ptr<Common::Input::InputDevice>; 42using CameraDevices =
41using NfcDevices = std::unique_ptr<Common::Input::InputDevice>; 43 std::array<std::unique_ptr<Common::Input::InputDevice>, max_emulated_controllers>;
44using RingAnalogDevices =
45 std::array<std::unique_ptr<Common::Input::InputDevice>, max_emulated_controllers>;
46using NfcDevices =
47 std::array<std::unique_ptr<Common::Input::InputDevice>, max_emulated_controllers>;
42using OutputDevices = std::array<std::unique_ptr<Common::Input::OutputDevice>, output_devices_size>; 48using OutputDevices = std::array<std::unique_ptr<Common::Input::OutputDevice>, output_devices_size>;
43 49
44using ButtonParams = std::array<Common::ParamPackage, Settings::NativeButton::NumButtons>; 50using ButtonParams = std::array<Common::ParamPackage, Settings::NativeButton::NumButtons>;
45using StickParams = std::array<Common::ParamPackage, Settings::NativeAnalog::NumAnalogs>; 51using StickParams = std::array<Common::ParamPackage, Settings::NativeAnalog::NumAnalogs>;
46using ControllerMotionParams = std::array<Common::ParamPackage, Settings::NativeMotion::NumMotions>; 52using ControllerMotionParams = std::array<Common::ParamPackage, Settings::NativeMotion::NumMotions>;
47using TriggerParams = std::array<Common::ParamPackage, Settings::NativeTrigger::NumTriggers>; 53using TriggerParams = std::array<Common::ParamPackage, Settings::NativeTrigger::NumTriggers>;
54using ColorParams = std::array<Common::ParamPackage, max_emulated_controllers>;
48using BatteryParams = std::array<Common::ParamPackage, max_emulated_controllers>; 55using BatteryParams = std::array<Common::ParamPackage, max_emulated_controllers>;
49using CameraParams = Common::ParamPackage; 56using CameraParams = std::array<Common::ParamPackage, max_emulated_controllers>;
50using NfcParams = Common::ParamPackage; 57using RingAnalogParams = std::array<Common::ParamPackage, max_emulated_controllers>;
58using NfcParams = std::array<Common::ParamPackage, max_emulated_controllers>;
51using OutputParams = std::array<Common::ParamPackage, output_devices_size>; 59using OutputParams = std::array<Common::ParamPackage, output_devices_size>;
52 60
53using ButtonValues = std::array<Common::Input::ButtonStatus, Settings::NativeButton::NumButtons>; 61using ButtonValues = std::array<Common::Input::ButtonStatus, Settings::NativeButton::NumButtons>;
@@ -58,6 +66,7 @@ using ControllerMotionValues = std::array<ControllerMotionInfo, Settings::Native
58using ColorValues = std::array<Common::Input::BodyColorStatus, max_emulated_controllers>; 66using ColorValues = std::array<Common::Input::BodyColorStatus, max_emulated_controllers>;
59using BatteryValues = std::array<Common::Input::BatteryStatus, max_emulated_controllers>; 67using BatteryValues = std::array<Common::Input::BatteryStatus, max_emulated_controllers>;
60using CameraValues = Common::Input::CameraStatus; 68using CameraValues = Common::Input::CameraStatus;
69using RingAnalogValue = Common::Input::AnalogStatus;
61using NfcValues = Common::Input::NfcStatus; 70using NfcValues = Common::Input::NfcStatus;
62using VibrationValues = std::array<Common::Input::VibrationStatus, max_emulated_controllers>; 71using VibrationValues = std::array<Common::Input::VibrationStatus, max_emulated_controllers>;
63 72
@@ -84,6 +93,10 @@ struct CameraState {
84 std::size_t sample{}; 93 std::size_t sample{};
85}; 94};
86 95
96struct RingSensorForce {
97 f32 force;
98};
99
87struct NfcState { 100struct NfcState {
88 Common::Input::NfcState state{}; 101 Common::Input::NfcState state{};
89 std::vector<u8> data{}; 102 std::vector<u8> data{};
@@ -116,6 +129,7 @@ struct ControllerStatus {
116 BatteryValues battery_values{}; 129 BatteryValues battery_values{};
117 VibrationValues vibration_values{}; 130 VibrationValues vibration_values{};
118 CameraValues camera_values{}; 131 CameraValues camera_values{};
132 RingAnalogValue ring_analog_value{};
119 NfcValues nfc_values{}; 133 NfcValues nfc_values{};
120 134
121 // Data for HID serices 135 // Data for HID serices
@@ -129,6 +143,7 @@ struct ControllerStatus {
129 ControllerColors colors_state{}; 143 ControllerColors colors_state{};
130 BatteryLevelState battery_state{}; 144 BatteryLevelState battery_state{};
131 CameraState camera_state{}; 145 CameraState camera_state{};
146 RingSensorForce ring_analog_state{};
132 NfcState nfc_state{}; 147 NfcState nfc_state{};
133}; 148};
134 149
@@ -141,6 +156,7 @@ enum class ControllerTriggerType {
141 Battery, 156 Battery,
142 Vibration, 157 Vibration,
143 IrSensor, 158 IrSensor,
159 RingController,
144 Nfc, 160 Nfc,
145 Connected, 161 Connected,
146 Disconnected, 162 Disconnected,
@@ -294,6 +310,9 @@ public:
294 /// Returns the latest camera status from the controller with parameters 310 /// Returns the latest camera status from the controller with parameters
295 CameraValues GetCameraValues() const; 311 CameraValues GetCameraValues() const;
296 312
313 /// Returns the latest status of analog input from the ring sensor with parameters
314 RingAnalogValue GetRingSensorValues() const;
315
297 /// Returns the latest status of button input for the hid::HomeButton service 316 /// Returns the latest status of button input for the hid::HomeButton service
298 HomeButtonState GetHomeButtons() const; 317 HomeButtonState GetHomeButtons() const;
299 318
@@ -324,6 +343,9 @@ public:
324 /// Returns the latest camera status from the controller 343 /// Returns the latest camera status from the controller
325 const CameraState& GetCamera() const; 344 const CameraState& GetCamera() const;
326 345
346 /// Returns the latest ringcon force sensor value
347 RingSensorForce GetRingSensorForce() const;
348
327 /// Returns the latest ntag status from the controller 349 /// Returns the latest ntag status from the controller
328 const NfcState& GetNfc() const; 350 const NfcState& GetNfc() const;
329 351
@@ -341,10 +363,12 @@ public:
341 363
342 /** 364 /**
343 * Sets the desired data to be polled from a controller 365 * Sets the desired data to be polled from a controller
366 * @param device_index index of the controller to set the polling mode
344 * @param polling_mode type of input desired buttons, gyro, nfc, ir, etc. 367 * @param polling_mode type of input desired buttons, gyro, nfc, ir, etc.
345 * @return true if SetPollingMode was successfull 368 * @return driver result from this command
346 */ 369 */
347 bool SetPollingMode(Common::Input::PollingMode polling_mode); 370 Common::Input::DriverResult SetPollingMode(EmulatedDeviceIndex device_index,
371 Common::Input::PollingMode polling_mode);
348 372
349 /** 373 /**
350 * Sets the desired camera format to be polled from a controller 374 * Sets the desired camera format to be polled from a controller
@@ -353,6 +377,15 @@ public:
353 */ 377 */
354 bool SetCameraFormat(Core::IrSensor::ImageTransferProcessorFormat camera_format); 378 bool SetCameraFormat(Core::IrSensor::ImageTransferProcessorFormat camera_format);
355 379
380 // Returns the current mapped ring device
381 Common::ParamPackage GetRingParam() const;
382
383 /**
384 * Updates the current mapped ring device
385 * @param param ParamPackage with ring sensor data to be mapped
386 */
387 void SetRingParam(Common::ParamPackage param);
388
356 /// Returns true if the device has nfc support 389 /// Returns true if the device has nfc support
357 bool HasNfc() const; 390 bool HasNfc() const;
358 391
@@ -433,9 +466,16 @@ private:
433 void SetMotion(const Common::Input::CallbackStatus& callback, std::size_t index); 466 void SetMotion(const Common::Input::CallbackStatus& callback, std::size_t index);
434 467
435 /** 468 /**
469 * Updates the color status of the controller
470 * @param callback A CallbackStatus containing the color status
471 * @param index color ID of the to be updated
472 */
473 void SetColors(const Common::Input::CallbackStatus& callback, std::size_t index);
474
475 /**
436 * Updates the battery status of the controller 476 * Updates the battery status of the controller
437 * @param callback A CallbackStatus containing the battery status 477 * @param callback A CallbackStatus containing the battery status
438 * @param index Button ID of the to be updated 478 * @param index battery ID of the to be updated
439 */ 479 */
440 void SetBattery(const Common::Input::CallbackStatus& callback, std::size_t index); 480 void SetBattery(const Common::Input::CallbackStatus& callback, std::size_t index);
441 481
@@ -446,6 +486,12 @@ private:
446 void SetCamera(const Common::Input::CallbackStatus& callback); 486 void SetCamera(const Common::Input::CallbackStatus& callback);
447 487
448 /** 488 /**
489 * Updates the ring analog sensor status of the ring controller
490 * @param callback A CallbackStatus containing the force status
491 */
492 void SetRingAnalog(const Common::Input::CallbackStatus& callback);
493
494 /**
449 * Updates the nfc status of the controller 495 * Updates the nfc status of the controller
450 * @param callback A CallbackStatus containing the nfc status 496 * @param callback A CallbackStatus containing the nfc status
451 */ 497 */
@@ -484,7 +530,9 @@ private:
484 ControllerMotionParams motion_params; 530 ControllerMotionParams motion_params;
485 TriggerParams trigger_params; 531 TriggerParams trigger_params;
486 BatteryParams battery_params; 532 BatteryParams battery_params;
533 ColorParams color_params;
487 CameraParams camera_params; 534 CameraParams camera_params;
535 RingAnalogParams ring_params;
488 NfcParams nfc_params; 536 NfcParams nfc_params;
489 OutputParams output_params; 537 OutputParams output_params;
490 538
@@ -493,7 +541,9 @@ private:
493 ControllerMotionDevices motion_devices; 541 ControllerMotionDevices motion_devices;
494 TriggerDevices trigger_devices; 542 TriggerDevices trigger_devices;
495 BatteryDevices battery_devices; 543 BatteryDevices battery_devices;
544 ColorDevices color_devices;
496 CameraDevices camera_devices; 545 CameraDevices camera_devices;
546 RingAnalogDevices ring_analog_devices;
497 NfcDevices nfc_devices; 547 NfcDevices nfc_devices;
498 OutputDevices output_devices; 548 OutputDevices output_devices;
499 549
diff --git a/src/core/hid/emulated_devices.cpp b/src/core/hid/emulated_devices.cpp
index e421828d2..836f32c0f 100644
--- a/src/core/hid/emulated_devices.cpp
+++ b/src/core/hid/emulated_devices.cpp
@@ -14,7 +14,6 @@ EmulatedDevices::EmulatedDevices() = default;
14EmulatedDevices::~EmulatedDevices() = default; 14EmulatedDevices::~EmulatedDevices() = default;
15 15
16void EmulatedDevices::ReloadFromSettings() { 16void EmulatedDevices::ReloadFromSettings() {
17 ring_params = Common::ParamPackage(Settings::values.ringcon_analogs);
18 ReloadInput(); 17 ReloadInput();
19} 18}
20 19
@@ -66,8 +65,6 @@ void EmulatedDevices::ReloadInput() {
66 key_index++; 65 key_index++;
67 } 66 }
68 67
69 ring_analog_device = Common::Input::CreateInputDevice(ring_params);
70
71 for (std::size_t index = 0; index < mouse_button_devices.size(); ++index) { 68 for (std::size_t index = 0; index < mouse_button_devices.size(); ++index) {
72 if (!mouse_button_devices[index]) { 69 if (!mouse_button_devices[index]) {
73 continue; 70 continue;
@@ -122,13 +119,6 @@ void EmulatedDevices::ReloadInput() {
122 }, 119 },
123 }); 120 });
124 } 121 }
125
126 if (ring_analog_device) {
127 ring_analog_device->SetCallback({
128 .on_change =
129 [this](const Common::Input::CallbackStatus& callback) { SetRingAnalog(callback); },
130 });
131 }
132} 122}
133 123
134void EmulatedDevices::UnloadInput() { 124void EmulatedDevices::UnloadInput() {
@@ -145,7 +135,6 @@ void EmulatedDevices::UnloadInput() {
145 for (auto& button : keyboard_modifier_devices) { 135 for (auto& button : keyboard_modifier_devices) {
146 button.reset(); 136 button.reset();
147 } 137 }
148 ring_analog_device.reset();
149} 138}
150 139
151void EmulatedDevices::EnableConfiguration() { 140void EmulatedDevices::EnableConfiguration() {
@@ -165,7 +154,6 @@ void EmulatedDevices::SaveCurrentConfig() {
165 if (!is_configuring) { 154 if (!is_configuring) {
166 return; 155 return;
167 } 156 }
168 Settings::values.ringcon_analogs = ring_params.Serialize();
169} 157}
170 158
171void EmulatedDevices::RestoreConfig() { 159void EmulatedDevices::RestoreConfig() {
@@ -175,15 +163,6 @@ void EmulatedDevices::RestoreConfig() {
175 ReloadFromSettings(); 163 ReloadFromSettings();
176} 164}
177 165
178Common::ParamPackage EmulatedDevices::GetRingParam() const {
179 return ring_params;
180}
181
182void EmulatedDevices::SetRingParam(Common::ParamPackage param) {
183 ring_params = std::move(param);
184 ReloadInput();
185}
186
187void EmulatedDevices::SetKeyboardButton(const Common::Input::CallbackStatus& callback, 166void EmulatedDevices::SetKeyboardButton(const Common::Input::CallbackStatus& callback,
188 std::size_t index) { 167 std::size_t index) {
189 if (index >= device_status.keyboard_values.size()) { 168 if (index >= device_status.keyboard_values.size()) {
@@ -430,23 +409,6 @@ void EmulatedDevices::SetMouseStick(const Common::Input::CallbackStatus& callbac
430 TriggerOnChange(DeviceTriggerType::Mouse); 409 TriggerOnChange(DeviceTriggerType::Mouse);
431} 410}
432 411
433void EmulatedDevices::SetRingAnalog(const Common::Input::CallbackStatus& callback) {
434 std::lock_guard lock{mutex};
435 const auto force_value = TransformToStick(callback);
436
437 device_status.ring_analog_value = force_value.x;
438
439 if (is_configuring) {
440 device_status.ring_analog_value = {};
441 TriggerOnChange(DeviceTriggerType::RingController);
442 return;
443 }
444
445 device_status.ring_analog_state.force = force_value.x.value;
446
447 TriggerOnChange(DeviceTriggerType::RingController);
448}
449
450KeyboardValues EmulatedDevices::GetKeyboardValues() const { 412KeyboardValues EmulatedDevices::GetKeyboardValues() const {
451 std::scoped_lock lock{mutex}; 413 std::scoped_lock lock{mutex};
452 return device_status.keyboard_values; 414 return device_status.keyboard_values;
@@ -462,10 +424,6 @@ MouseButtonValues EmulatedDevices::GetMouseButtonsValues() const {
462 return device_status.mouse_button_values; 424 return device_status.mouse_button_values;
463} 425}
464 426
465RingAnalogValue EmulatedDevices::GetRingSensorValues() const {
466 return device_status.ring_analog_value;
467}
468
469KeyboardKey EmulatedDevices::GetKeyboard() const { 427KeyboardKey EmulatedDevices::GetKeyboard() const {
470 std::scoped_lock lock{mutex}; 428 std::scoped_lock lock{mutex};
471 return device_status.keyboard_state; 429 return device_status.keyboard_state;
@@ -491,10 +449,6 @@ AnalogStickState EmulatedDevices::GetMouseWheel() const {
491 return device_status.mouse_wheel_state; 449 return device_status.mouse_wheel_state;
492} 450}
493 451
494RingSensorForce EmulatedDevices::GetRingSensorForce() const {
495 return device_status.ring_analog_state;
496}
497
498void EmulatedDevices::TriggerOnChange(DeviceTriggerType type) { 452void EmulatedDevices::TriggerOnChange(DeviceTriggerType type) {
499 std::scoped_lock lock{callback_mutex}; 453 std::scoped_lock lock{callback_mutex};
500 for (const auto& poller_pair : callback_list) { 454 for (const auto& poller_pair : callback_list) {
diff --git a/src/core/hid/emulated_devices.h b/src/core/hid/emulated_devices.h
index 4cdbf9dc6..76f9150df 100644
--- a/src/core/hid/emulated_devices.h
+++ b/src/core/hid/emulated_devices.h
@@ -26,11 +26,9 @@ using MouseButtonDevices = std::array<std::unique_ptr<Common::Input::InputDevice
26using MouseAnalogDevices = std::array<std::unique_ptr<Common::Input::InputDevice>, 26using MouseAnalogDevices = std::array<std::unique_ptr<Common::Input::InputDevice>,
27 Settings::NativeMouseWheel::NumMouseWheels>; 27 Settings::NativeMouseWheel::NumMouseWheels>;
28using MouseStickDevice = std::unique_ptr<Common::Input::InputDevice>; 28using MouseStickDevice = std::unique_ptr<Common::Input::InputDevice>;
29using RingAnalogDevice = std::unique_ptr<Common::Input::InputDevice>;
30 29
31using MouseButtonParams = 30using MouseButtonParams =
32 std::array<Common::ParamPackage, Settings::NativeMouseButton::NumMouseButtons>; 31 std::array<Common::ParamPackage, Settings::NativeMouseButton::NumMouseButtons>;
33using RingAnalogParams = Common::ParamPackage;
34 32
35using KeyboardValues = 33using KeyboardValues =
36 std::array<Common::Input::ButtonStatus, Settings::NativeKeyboard::NumKeyboardKeys>; 34 std::array<Common::Input::ButtonStatus, Settings::NativeKeyboard::NumKeyboardKeys>;
@@ -41,17 +39,12 @@ using MouseButtonValues =
41using MouseAnalogValues = 39using MouseAnalogValues =
42 std::array<Common::Input::AnalogStatus, Settings::NativeMouseWheel::NumMouseWheels>; 40 std::array<Common::Input::AnalogStatus, Settings::NativeMouseWheel::NumMouseWheels>;
43using MouseStickValue = Common::Input::TouchStatus; 41using MouseStickValue = Common::Input::TouchStatus;
44using RingAnalogValue = Common::Input::AnalogStatus;
45 42
46struct MousePosition { 43struct MousePosition {
47 f32 x; 44 f32 x;
48 f32 y; 45 f32 y;
49}; 46};
50 47
51struct RingSensorForce {
52 f32 force;
53};
54
55struct DeviceStatus { 48struct DeviceStatus {
56 // Data from input_common 49 // Data from input_common
57 KeyboardValues keyboard_values{}; 50 KeyboardValues keyboard_values{};
@@ -59,7 +52,6 @@ struct DeviceStatus {
59 MouseButtonValues mouse_button_values{}; 52 MouseButtonValues mouse_button_values{};
60 MouseAnalogValues mouse_analog_values{}; 53 MouseAnalogValues mouse_analog_values{};
61 MouseStickValue mouse_stick_value{}; 54 MouseStickValue mouse_stick_value{};
62 RingAnalogValue ring_analog_value{};
63 55
64 // Data for HID serices 56 // Data for HID serices
65 KeyboardKey keyboard_state{}; 57 KeyboardKey keyboard_state{};
@@ -67,7 +59,6 @@ struct DeviceStatus {
67 MouseButton mouse_button_state{}; 59 MouseButton mouse_button_state{};
68 MousePosition mouse_position_state{}; 60 MousePosition mouse_position_state{};
69 AnalogStickState mouse_wheel_state{}; 61 AnalogStickState mouse_wheel_state{};
70 RingSensorForce ring_analog_state{};
71}; 62};
72 63
73enum class DeviceTriggerType { 64enum class DeviceTriggerType {
@@ -138,9 +129,6 @@ public:
138 /// Returns the latest status of button input from the mouse with parameters 129 /// Returns the latest status of button input from the mouse with parameters
139 MouseButtonValues GetMouseButtonsValues() const; 130 MouseButtonValues GetMouseButtonsValues() const;
140 131
141 /// Returns the latest status of analog input from the ring sensor with parameters
142 RingAnalogValue GetRingSensorValues() const;
143
144 /// Returns the latest status of button input from the keyboard 132 /// Returns the latest status of button input from the keyboard
145 KeyboardKey GetKeyboard() const; 133 KeyboardKey GetKeyboard() const;
146 134
@@ -156,9 +144,6 @@ public:
156 /// Returns the latest mouse wheel change 144 /// Returns the latest mouse wheel change
157 AnalogStickState GetMouseWheel() const; 145 AnalogStickState GetMouseWheel() const;
158 146
159 /// Returns the latest ringcon force sensor value
160 RingSensorForce GetRingSensorForce() const;
161
162 /** 147 /**
163 * Adds a callback to the list of events 148 * Adds a callback to the list of events
164 * @param update_callback InterfaceUpdateCallback that will be triggered 149 * @param update_callback InterfaceUpdateCallback that will be triggered
@@ -224,14 +209,11 @@ private:
224 209
225 bool is_configuring{false}; 210 bool is_configuring{false};
226 211
227 RingAnalogParams ring_params;
228
229 KeyboardDevices keyboard_devices; 212 KeyboardDevices keyboard_devices;
230 KeyboardModifierDevices keyboard_modifier_devices; 213 KeyboardModifierDevices keyboard_modifier_devices;
231 MouseButtonDevices mouse_button_devices; 214 MouseButtonDevices mouse_button_devices;
232 MouseAnalogDevices mouse_analog_devices; 215 MouseAnalogDevices mouse_analog_devices;
233 MouseStickDevice mouse_stick_device; 216 MouseStickDevice mouse_stick_device;
234 RingAnalogDevice ring_analog_device;
235 217
236 mutable std::mutex mutex; 218 mutable std::mutex mutex;
237 mutable std::mutex callback_mutex; 219 mutable std::mutex callback_mutex;
diff --git a/src/core/hid/input_converter.cpp b/src/core/hid/input_converter.cpp
index 502692875..3f7b8c090 100644
--- a/src/core/hid/input_converter.cpp
+++ b/src/core/hid/input_converter.cpp
@@ -304,6 +304,18 @@ Common::Input::NfcStatus TransformToNfc(const Common::Input::CallbackStatus& cal
304 return nfc; 304 return nfc;
305} 305}
306 306
307Common::Input::BodyColorStatus TransformToColor(const Common::Input::CallbackStatus& callback) {
308 switch (callback.type) {
309 case Common::Input::InputType::Color:
310 return callback.color_status;
311 break;
312 default:
313 LOG_ERROR(Input, "Conversion from type {} to color not implemented", callback.type);
314 return {};
315 break;
316 }
317}
318
307void SanitizeAnalog(Common::Input::AnalogStatus& analog, bool clamp_value) { 319void SanitizeAnalog(Common::Input::AnalogStatus& analog, bool clamp_value) {
308 const auto& properties = analog.properties; 320 const auto& properties = analog.properties;
309 float& raw_value = analog.raw_value; 321 float& raw_value = analog.raw_value;
diff --git a/src/core/hid/input_converter.h b/src/core/hid/input_converter.h
index b7eb6e660..c51c03e57 100644
--- a/src/core/hid/input_converter.h
+++ b/src/core/hid/input_converter.h
@@ -88,11 +88,19 @@ Common::Input::CameraStatus TransformToCamera(const Common::Input::CallbackStatu
88 * Converts raw input data into a valid nfc status. 88 * Converts raw input data into a valid nfc status.
89 * 89 *
90 * @param callback Supported callbacks: Nfc. 90 * @param callback Supported callbacks: Nfc.
91 * @return A valid CameraObject object. 91 * @return A valid data tag vector.
92 */ 92 */
93Common::Input::NfcStatus TransformToNfc(const Common::Input::CallbackStatus& callback); 93Common::Input::NfcStatus TransformToNfc(const Common::Input::CallbackStatus& callback);
94 94
95/** 95/**
96 * Converts raw input data into a valid color status.
97 *
98 * @param callback Supported callbacks: Color.
99 * @return A valid Color object.
100 */
101Common::Input::BodyColorStatus TransformToColor(const Common::Input::CallbackStatus& callback);
102
103/**
96 * Converts raw analog data into a valid analog value 104 * Converts raw analog data into a valid analog value
97 * @param analog An analog object containing raw data and properties 105 * @param analog An analog object containing raw data and properties
98 * @param clamp_value determines if the value needs to be clamped between -1.0f and 1.0f. 106 * @param clamp_value determines if the value needs to be clamped between -1.0f and 1.0f.
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index 2f871de31..5713f1288 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -272,6 +272,8 @@ void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) {
272 } 272 }
273 break; 273 break;
274 case Core::HID::NpadStyleIndex::JoyconLeft: 274 case Core::HID::NpadStyleIndex::JoyconLeft:
275 shared_memory->fullkey_color.attribute = ColorAttribute::Ok;
276 shared_memory->fullkey_color.fullkey = body_colors.left;
275 shared_memory->joycon_color.attribute = ColorAttribute::Ok; 277 shared_memory->joycon_color.attribute = ColorAttribute::Ok;
276 shared_memory->joycon_color.left = body_colors.left; 278 shared_memory->joycon_color.left = body_colors.left;
277 shared_memory->battery_level_dual = battery_level.left.battery_level; 279 shared_memory->battery_level_dual = battery_level.left.battery_level;
@@ -285,6 +287,8 @@ void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) {
285 shared_memory->sixaxis_left_properties.is_newly_assigned.Assign(1); 287 shared_memory->sixaxis_left_properties.is_newly_assigned.Assign(1);
286 break; 288 break;
287 case Core::HID::NpadStyleIndex::JoyconRight: 289 case Core::HID::NpadStyleIndex::JoyconRight:
290 shared_memory->fullkey_color.attribute = ColorAttribute::Ok;
291 shared_memory->fullkey_color.fullkey = body_colors.right;
288 shared_memory->joycon_color.attribute = ColorAttribute::Ok; 292 shared_memory->joycon_color.attribute = ColorAttribute::Ok;
289 shared_memory->joycon_color.right = body_colors.right; 293 shared_memory->joycon_color.right = body_colors.right;
290 shared_memory->battery_level_right = battery_level.right.battery_level; 294 shared_memory->battery_level_right = battery_level.right.battery_level;
@@ -332,6 +336,20 @@ void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) {
332 336
333 controller.is_connected = true; 337 controller.is_connected = true;
334 controller.device->Connect(); 338 controller.device->Connect();
339 controller.device->SetLedPattern();
340 if (controller_type == Core::HID::NpadStyleIndex::JoyconDual) {
341 if (controller.is_dual_left_connected) {
342 controller.device->SetPollingMode(Core::HID::EmulatedDeviceIndex::LeftIndex,
343 Common::Input::PollingMode::Active);
344 }
345 if (controller.is_dual_right_connected) {
346 controller.device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
347 Common::Input::PollingMode::Active);
348 }
349 } else {
350 controller.device->SetPollingMode(Core::HID::EmulatedDeviceIndex::AllDevices,
351 Common::Input::PollingMode::Active);
352 }
335 SignalStyleSetChangedEvent(npad_id); 353 SignalStyleSetChangedEvent(npad_id);
336 WriteEmptyEntry(controller.shared_memory); 354 WriteEmptyEntry(controller.shared_memory);
337} 355}
diff --git a/src/core/hle/service/hid/hidbus.cpp b/src/core/hle/service/hid/hidbus.cpp
index e5e50845f..17252a84a 100644
--- a/src/core/hle/service/hid/hidbus.cpp
+++ b/src/core/hle/service/hid/hidbus.cpp
@@ -297,13 +297,13 @@ void HidBus::EnableExternalDevice(Kernel::HLERequestContext& ctx) {
297 297
298 const auto parameters{rp.PopRaw<Parameters>()}; 298 const auto parameters{rp.PopRaw<Parameters>()};
299 299
300 LOG_INFO(Service_HID, 300 LOG_DEBUG(Service_HID,
301 "called, enable={}, abstracted_pad_id={}, bus_type={}, internal_index={}, " 301 "called, enable={}, abstracted_pad_id={}, bus_type={}, internal_index={}, "
302 "player_number={}, is_valid={}, inval={}, applet_resource_user_id{}", 302 "player_number={}, is_valid={}, inval={}, applet_resource_user_id{}",
303 parameters.enable, parameters.bus_handle.abstracted_pad_id, 303 parameters.enable, parameters.bus_handle.abstracted_pad_id,
304 parameters.bus_handle.bus_type, parameters.bus_handle.internal_index, 304 parameters.bus_handle.bus_type, parameters.bus_handle.internal_index,
305 parameters.bus_handle.player_number, parameters.bus_handle.is_valid, parameters.inval, 305 parameters.bus_handle.player_number, parameters.bus_handle.is_valid, parameters.inval,
306 parameters.applet_resource_user_id); 306 parameters.applet_resource_user_id);
307 307
308 const auto device_index = GetDeviceIndexFromHandle(parameters.bus_handle); 308 const auto device_index = GetDeviceIndexFromHandle(parameters.bus_handle);
309 309
@@ -326,11 +326,11 @@ void HidBus::GetExternalDeviceId(Kernel::HLERequestContext& ctx) {
326 IPC::RequestParser rp{ctx}; 326 IPC::RequestParser rp{ctx};
327 const auto bus_handle_{rp.PopRaw<BusHandle>()}; 327 const auto bus_handle_{rp.PopRaw<BusHandle>()};
328 328
329 LOG_INFO(Service_HID, 329 LOG_DEBUG(Service_HID,
330 "called, abstracted_pad_id={}, bus_type={}, internal_index={}, player_number={}, " 330 "called, abstracted_pad_id={}, bus_type={}, internal_index={}, player_number={}, "
331 "is_valid={}", 331 "is_valid={}",
332 bus_handle_.abstracted_pad_id, bus_handle_.bus_type, bus_handle_.internal_index, 332 bus_handle_.abstracted_pad_id, bus_handle_.bus_type, bus_handle_.internal_index,
333 bus_handle_.player_number, bus_handle_.is_valid); 333 bus_handle_.player_number, bus_handle_.is_valid);
334 334
335 const auto device_index = GetDeviceIndexFromHandle(bus_handle_); 335 const auto device_index = GetDeviceIndexFromHandle(bus_handle_);
336 336
diff --git a/src/core/hle/service/hid/hidbus/ringcon.cpp b/src/core/hle/service/hid/hidbus/ringcon.cpp
index 57f1a2a26..78ed47014 100644
--- a/src/core/hle/service/hid/hidbus/ringcon.cpp
+++ b/src/core/hle/service/hid/hidbus/ringcon.cpp
@@ -1,7 +1,7 @@
1// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/hid/emulated_devices.h" 4#include "core/hid/emulated_controller.h"
5#include "core/hid/hid_core.h" 5#include "core/hid/hid_core.h"
6#include "core/hle/kernel/k_event.h" 6#include "core/hle/kernel/k_event.h"
7#include "core/hle/kernel/k_readable_event.h" 7#include "core/hle/kernel/k_readable_event.h"
@@ -12,16 +12,20 @@ namespace Service::HID {
12RingController::RingController(Core::HID::HIDCore& hid_core_, 12RingController::RingController(Core::HID::HIDCore& hid_core_,
13 KernelHelpers::ServiceContext& service_context_) 13 KernelHelpers::ServiceContext& service_context_)
14 : HidbusBase(service_context_) { 14 : HidbusBase(service_context_) {
15 input = hid_core_.GetEmulatedDevices(); 15 input = hid_core_.GetEmulatedController(Core::HID::NpadIdType::Player1);
16} 16}
17 17
18RingController::~RingController() = default; 18RingController::~RingController() = default;
19 19
20void RingController::OnInit() { 20void RingController::OnInit() {
21 input->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
22 Common::Input::PollingMode::Ring);
21 return; 23 return;
22} 24}
23 25
24void RingController::OnRelease() { 26void RingController::OnRelease() {
27 input->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
28 Common::Input::PollingMode::Active);
25 return; 29 return;
26}; 30};
27 31
diff --git a/src/core/hle/service/hid/hidbus/ringcon.h b/src/core/hle/service/hid/hidbus/ringcon.h
index b37df50ac..845ce85a5 100644
--- a/src/core/hle/service/hid/hidbus/ringcon.h
+++ b/src/core/hle/service/hid/hidbus/ringcon.h
@@ -9,7 +9,7 @@
9#include "core/hle/service/hid/hidbus/hidbus_base.h" 9#include "core/hle/service/hid/hidbus/hidbus_base.h"
10 10
11namespace Core::HID { 11namespace Core::HID {
12class EmulatedDevices; 12class EmulatedController;
13} // namespace Core::HID 13} // namespace Core::HID
14 14
15namespace Service::HID { 15namespace Service::HID {
@@ -248,6 +248,6 @@ private:
248 .zero = {.value = idle_value, .crc = 225}, 248 .zero = {.value = idle_value, .crc = 225},
249 }; 249 };
250 250
251 Core::HID::EmulatedDevices* input; 251 Core::HID::EmulatedController* input;
252}; 252};
253} // namespace Service::HID 253} // namespace Service::HID
diff --git a/src/core/hle/service/hid/irs.cpp b/src/core/hle/service/hid/irs.cpp
index 6a3453457..52f402c56 100644
--- a/src/core/hle/service/hid/irs.cpp
+++ b/src/core/hle/service/hid/irs.cpp
@@ -108,6 +108,8 @@ void IRS::StopImageProcessor(Kernel::HLERequestContext& ctx) {
108 auto result = IsIrCameraHandleValid(parameters.camera_handle); 108 auto result = IsIrCameraHandleValid(parameters.camera_handle);
109 if (result.IsSuccess()) { 109 if (result.IsSuccess()) {
110 // TODO: Stop Image processor 110 // TODO: Stop Image processor
111 npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
112 Common::Input::PollingMode::Active);
111 result = ResultSuccess; 113 result = ResultSuccess;
112 } 114 }
113 115
@@ -139,6 +141,8 @@ void IRS::RunMomentProcessor(Kernel::HLERequestContext& ctx) {
139 MakeProcessor<MomentProcessor>(parameters.camera_handle, device); 141 MakeProcessor<MomentProcessor>(parameters.camera_handle, device);
140 auto& image_transfer_processor = GetProcessor<MomentProcessor>(parameters.camera_handle); 142 auto& image_transfer_processor = GetProcessor<MomentProcessor>(parameters.camera_handle);
141 image_transfer_processor.SetConfig(parameters.processor_config); 143 image_transfer_processor.SetConfig(parameters.processor_config);
144 npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
145 Common::Input::PollingMode::IR);
142 } 146 }
143 147
144 IPC::ResponseBuilder rb{ctx, 2}; 148 IPC::ResponseBuilder rb{ctx, 2};
@@ -170,6 +174,8 @@ void IRS::RunClusteringProcessor(Kernel::HLERequestContext& ctx) {
170 auto& image_transfer_processor = 174 auto& image_transfer_processor =
171 GetProcessor<ClusteringProcessor>(parameters.camera_handle); 175 GetProcessor<ClusteringProcessor>(parameters.camera_handle);
172 image_transfer_processor.SetConfig(parameters.processor_config); 176 image_transfer_processor.SetConfig(parameters.processor_config);
177 npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
178 Common::Input::PollingMode::IR);
173 } 179 }
174 180
175 IPC::ResponseBuilder rb{ctx, 2}; 181 IPC::ResponseBuilder rb{ctx, 2};
@@ -219,6 +225,8 @@ void IRS::RunImageTransferProcessor(Kernel::HLERequestContext& ctx) {
219 GetProcessor<ImageTransferProcessor>(parameters.camera_handle); 225 GetProcessor<ImageTransferProcessor>(parameters.camera_handle);
220 image_transfer_processor.SetConfig(parameters.processor_config); 226 image_transfer_processor.SetConfig(parameters.processor_config);
221 image_transfer_processor.SetTransferMemoryPointer(transfer_memory); 227 image_transfer_processor.SetTransferMemoryPointer(transfer_memory);
228 npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
229 Common::Input::PollingMode::IR);
222 } 230 }
223 231
224 IPC::ResponseBuilder rb{ctx, 2}; 232 IPC::ResponseBuilder rb{ctx, 2};
@@ -294,6 +302,8 @@ void IRS::RunTeraPluginProcessor(Kernel::HLERequestContext& ctx) {
294 auto& image_transfer_processor = 302 auto& image_transfer_processor =
295 GetProcessor<TeraPluginProcessor>(parameters.camera_handle); 303 GetProcessor<TeraPluginProcessor>(parameters.camera_handle);
296 image_transfer_processor.SetConfig(parameters.processor_config); 304 image_transfer_processor.SetConfig(parameters.processor_config);
305 npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
306 Common::Input::PollingMode::IR);
297 } 307 }
298 308
299 IPC::ResponseBuilder rb{ctx, 2}; 309 IPC::ResponseBuilder rb{ctx, 2};
@@ -343,6 +353,8 @@ void IRS::RunPointingProcessor(Kernel::HLERequestContext& ctx) {
343 MakeProcessor<PointingProcessor>(camera_handle, device); 353 MakeProcessor<PointingProcessor>(camera_handle, device);
344 auto& image_transfer_processor = GetProcessor<PointingProcessor>(camera_handle); 354 auto& image_transfer_processor = GetProcessor<PointingProcessor>(camera_handle);
345 image_transfer_processor.SetConfig(processor_config); 355 image_transfer_processor.SetConfig(processor_config);
356 npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
357 Common::Input::PollingMode::IR);
346 } 358 }
347 359
348 IPC::ResponseBuilder rb{ctx, 2}; 360 IPC::ResponseBuilder rb{ctx, 2};
@@ -453,6 +465,8 @@ void IRS::RunImageTransferExProcessor(Kernel::HLERequestContext& ctx) {
453 GetProcessor<ImageTransferProcessor>(parameters.camera_handle); 465 GetProcessor<ImageTransferProcessor>(parameters.camera_handle);
454 image_transfer_processor.SetConfig(parameters.processor_config); 466 image_transfer_processor.SetConfig(parameters.processor_config);
455 image_transfer_processor.SetTransferMemoryPointer(transfer_memory); 467 image_transfer_processor.SetTransferMemoryPointer(transfer_memory);
468 npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
469 Common::Input::PollingMode::IR);
456 } 470 }
457 471
458 IPC::ResponseBuilder rb{ctx, 2}; 472 IPC::ResponseBuilder rb{ctx, 2};
@@ -479,6 +493,8 @@ void IRS::RunIrLedProcessor(Kernel::HLERequestContext& ctx) {
479 MakeProcessor<IrLedProcessor>(camera_handle, device); 493 MakeProcessor<IrLedProcessor>(camera_handle, device);
480 auto& image_transfer_processor = GetProcessor<IrLedProcessor>(camera_handle); 494 auto& image_transfer_processor = GetProcessor<IrLedProcessor>(camera_handle);
481 image_transfer_processor.SetConfig(processor_config); 495 image_transfer_processor.SetConfig(processor_config);
496 npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
497 Common::Input::PollingMode::IR);
482 } 498 }
483 499
484 IPC::ResponseBuilder rb{ctx, 2}; 500 IPC::ResponseBuilder rb{ctx, 2};
@@ -504,6 +520,8 @@ void IRS::StopImageProcessorAsync(Kernel::HLERequestContext& ctx) {
504 auto result = IsIrCameraHandleValid(parameters.camera_handle); 520 auto result = IsIrCameraHandleValid(parameters.camera_handle);
505 if (result.IsSuccess()) { 521 if (result.IsSuccess()) {
506 // TODO: Stop image processor async 522 // TODO: Stop image processor async
523 npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
524 Common::Input::PollingMode::Active);
507 result = ResultSuccess; 525 result = ResultSuccess;
508 } 526 }
509 527
diff --git a/src/core/hle/service/nfc/nfc_device.cpp b/src/core/hle/service/nfc/nfc_device.cpp
index 78578f723..9a3234e8c 100644
--- a/src/core/hle/service/nfc/nfc_device.cpp
+++ b/src/core/hle/service/nfc/nfc_device.cpp
@@ -130,7 +130,9 @@ Result NfcDevice::StartDetection(NFP::TagProtocol allowed_protocol) {
130 return WrongDeviceState; 130 return WrongDeviceState;
131 } 131 }
132 132
133 if (!npad_device->SetPollingMode(Common::Input::PollingMode::NFC)) { 133 if (npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
134 Common::Input::PollingMode::NFC) !=
135 Common::Input::DriverResult::Success) {
134 LOG_ERROR(Service_NFC, "Nfc not supported"); 136 LOG_ERROR(Service_NFC, "Nfc not supported");
135 return NfcDisabled; 137 return NfcDisabled;
136 } 138 }
@@ -141,7 +143,8 @@ Result NfcDevice::StartDetection(NFP::TagProtocol allowed_protocol) {
141} 143}
142 144
143Result NfcDevice::StopDetection() { 145Result NfcDevice::StopDetection() {
144 npad_device->SetPollingMode(Common::Input::PollingMode::Active); 146 npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
147 Common::Input::PollingMode::Active);
145 148
146 if (device_state == NFP::DeviceState::Initialized) { 149 if (device_state == NFP::DeviceState::Initialized) {
147 return ResultSuccess; 150 return ResultSuccess;
diff --git a/src/core/hle/service/nfp/nfp_device.cpp b/src/core/hle/service/nfp/nfp_device.cpp
index c860fd1a1..e67a76f55 100644
--- a/src/core/hle/service/nfp/nfp_device.cpp
+++ b/src/core/hle/service/nfp/nfp_device.cpp
@@ -152,7 +152,9 @@ Result NfpDevice::StartDetection(TagProtocol allowed_protocol) {
152 return WrongDeviceState; 152 return WrongDeviceState;
153 } 153 }
154 154
155 if (!npad_device->SetPollingMode(Common::Input::PollingMode::NFC)) { 155 if (npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
156 Common::Input::PollingMode::NFC) !=
157 Common::Input::DriverResult::Success) {
156 LOG_ERROR(Service_NFP, "Nfc not supported"); 158 LOG_ERROR(Service_NFP, "Nfc not supported");
157 return NfcDisabled; 159 return NfcDisabled;
158 } 160 }
@@ -163,7 +165,8 @@ Result NfpDevice::StartDetection(TagProtocol allowed_protocol) {
163} 165}
164 166
165Result NfpDevice::StopDetection() { 167Result NfpDevice::StopDetection() {
166 npad_device->SetPollingMode(Common::Input::PollingMode::Active); 168 npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
169 Common::Input::PollingMode::Active);
167 170
168 if (device_state == DeviceState::Initialized) { 171 if (device_state == DeviceState::Initialized) {
169 return ResultSuccess; 172 return ResultSuccess;