summaryrefslogtreecommitdiff
path: root/src/hid_core/resources/npad
diff options
context:
space:
mode:
authorGravatar Narr the Reg2024-01-10 22:06:54 -0600
committerGravatar german772024-01-15 23:15:40 -0600
commit2cacb9d48c98603176e52ecc94f2374a934797fb (patch)
tree12badf5b4eede22b22dece03a9074197ec631a1e /src/hid_core/resources/npad
parentMerge pull request #12686 from szepeviktor/typos3 (diff)
downloadyuzu-2cacb9d48c98603176e52ecc94f2374a934797fb.tar.gz
yuzu-2cacb9d48c98603176e52ecc94f2374a934797fb.tar.xz
yuzu-2cacb9d48c98603176e52ecc94f2374a934797fb.zip
service: hid: Fully implement abstract vibration
Diffstat (limited to 'src/hid_core/resources/npad')
-rw-r--r--src/hid_core/resources/npad/npad.cpp292
-rw-r--r--src/hid_core/resources/npad/npad.h59
-rw-r--r--src/hid_core/resources/npad/npad_types.h6
-rw-r--r--src/hid_core/resources/npad/npad_vibration.cpp4
-rw-r--r--src/hid_core/resources/npad/npad_vibration.h2
5 files changed, 138 insertions, 225 deletions
diff --git a/src/hid_core/resources/npad/npad.cpp b/src/hid_core/resources/npad/npad.cpp
index 97537a2e2..310fa8ba7 100644
--- a/src/hid_core/resources/npad/npad.cpp
+++ b/src/hid_core/resources/npad/npad.cpp
@@ -21,6 +21,7 @@
21#include "hid_core/hid_util.h" 21#include "hid_core/hid_util.h"
22#include "hid_core/resources/applet_resource.h" 22#include "hid_core/resources/applet_resource.h"
23#include "hid_core/resources/npad/npad.h" 23#include "hid_core/resources/npad/npad.h"
24#include "hid_core/resources/npad/npad_vibration.h"
24#include "hid_core/resources/shared_memory_format.h" 25#include "hid_core/resources/shared_memory_format.h"
25 26
26namespace Service::HID { 27namespace Service::HID {
@@ -31,10 +32,6 @@ NPad::NPad(Core::HID::HIDCore& hid_core_, KernelHelpers::ServiceContext& service
31 for (std::size_t i = 0; i < controller_data[aruid_index].size(); ++i) { 32 for (std::size_t i = 0; i < controller_data[aruid_index].size(); ++i) {
32 auto& controller = controller_data[aruid_index][i]; 33 auto& controller = controller_data[aruid_index][i];
33 controller.device = hid_core.GetEmulatedControllerByIndex(i); 34 controller.device = hid_core.GetEmulatedControllerByIndex(i);
34 controller.vibration[Core::HID::EmulatedDeviceIndex::LeftIndex].latest_vibration_value =
35 Core::HID::DEFAULT_VIBRATION_VALUE;
36 controller.vibration[Core::HID::EmulatedDeviceIndex::RightIndex]
37 .latest_vibration_value = Core::HID::DEFAULT_VIBRATION_VALUE;
38 Core::HID::ControllerUpdateCallback engine_callback{ 35 Core::HID::ControllerUpdateCallback engine_callback{
39 .on_change = 36 .on_change =
40 [this, i](Core::HID::ControllerTriggerType type) { ControllerUpdate(type, i); }, 37 [this, i](Core::HID::ControllerTriggerType type) { ControllerUpdate(type, i); },
@@ -43,6 +40,10 @@ NPad::NPad(Core::HID::HIDCore& hid_core_, KernelHelpers::ServiceContext& service
43 controller.callback_key = controller.device->SetCallback(engine_callback); 40 controller.callback_key = controller.device->SetCallback(engine_callback);
44 } 41 }
45 } 42 }
43 for (std::size_t i = 0; i < abstracted_pads.size(); ++i) {
44 abstracted_pads[i] = AbstractPad{};
45 abstracted_pads[i].SetNpadId(IndexToNpadIdType(i));
46 }
46} 47}
47 48
48NPad::~NPad() { 49NPad::~NPad() {
@@ -359,6 +360,7 @@ void NPad::InitNewlyAddedController(u64 aruid, Core::HID::NpadIdType npad_id) {
359 npad_resource.SignalStyleSetUpdateEvent(aruid, npad_id); 360 npad_resource.SignalStyleSetUpdateEvent(aruid, npad_id);
360 WriteEmptyEntry(controller.shared_memory); 361 WriteEmptyEntry(controller.shared_memory);
361 hid_core.SetLastActiveController(npad_id); 362 hid_core.SetLastActiveController(npad_id);
363 abstracted_pads[NpadIdTypeToIndex(npad_id)].Update();
362} 364}
363 365
364void NPad::WriteEmptyEntry(NpadInternalState* npad) { 366void NPad::WriteEmptyEntry(NpadInternalState* npad) {
@@ -740,171 +742,6 @@ bool NPad::SetNpadMode(u64 aruid, Core::HID::NpadIdType& new_npad_id, Core::HID:
740 return true; 742 return true;
741} 743}
742 744
743bool NPad::VibrateControllerAtIndex(u64 aruid, Core::HID::NpadIdType npad_id,
744 std::size_t device_index,
745 const Core::HID::VibrationValue& vibration_value) {
746 auto& controller = GetControllerFromNpadIdType(aruid, npad_id);
747 if (!controller.device->IsConnected()) {
748 return false;
749 }
750
751 if (!controller.device->IsVibrationEnabled(device_index)) {
752 if (controller.vibration[device_index].latest_vibration_value.low_amplitude != 0.0f ||
753 controller.vibration[device_index].latest_vibration_value.high_amplitude != 0.0f) {
754 // Send an empty vibration to stop any vibrations.
755 Core::HID::VibrationValue vibration{0.0f, 160.0f, 0.0f, 320.0f};
756 controller.device->SetVibration(device_index, vibration);
757 // Then reset the vibration value to its default value.
758 controller.vibration[device_index].latest_vibration_value =
759 Core::HID::DEFAULT_VIBRATION_VALUE;
760 }
761
762 return false;
763 }
764
765 if (!Settings::values.enable_accurate_vibrations.GetValue()) {
766 using std::chrono::duration_cast;
767 using std::chrono::milliseconds;
768 using std::chrono::steady_clock;
769
770 const auto now = steady_clock::now();
771
772 // Filter out non-zero vibrations that are within 15ms of each other.
773 if ((vibration_value.low_amplitude != 0.0f || vibration_value.high_amplitude != 0.0f) &&
774 duration_cast<milliseconds>(
775 now - controller.vibration[device_index].last_vibration_timepoint) <
776 milliseconds(15)) {
777 return false;
778 }
779
780 controller.vibration[device_index].last_vibration_timepoint = now;
781 }
782
783 Core::HID::VibrationValue vibration{
784 vibration_value.low_amplitude, vibration_value.low_frequency,
785 vibration_value.high_amplitude, vibration_value.high_frequency};
786 return controller.device->SetVibration(device_index, vibration);
787}
788
789void NPad::VibrateController(u64 aruid,
790 const Core::HID::VibrationDeviceHandle& vibration_device_handle,
791 const Core::HID::VibrationValue& vibration_value) {
792 if (IsVibrationHandleValid(vibration_device_handle).IsError()) {
793 return;
794 }
795
796 if (!Settings::values.vibration_enabled.GetValue() && !permit_vibration_session_enabled) {
797 return;
798 }
799
800 auto& controller = GetControllerFromHandle(aruid, vibration_device_handle);
801 const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index);
802
803 if (!controller.vibration[device_index].device_mounted || !controller.device->IsConnected()) {
804 return;
805 }
806
807 if (vibration_device_handle.device_index == Core::HID::DeviceIndex::None) {
808 ASSERT_MSG(false, "DeviceIndex should never be None!");
809 return;
810 }
811
812 // Some games try to send mismatched parameters in the device handle, block these.
813 if ((controller.device->GetNpadStyleIndex() == Core::HID::NpadStyleIndex::JoyconLeft &&
814 (vibration_device_handle.npad_type == Core::HID::NpadStyleIndex::JoyconRight ||
815 vibration_device_handle.device_index == Core::HID::DeviceIndex::Right)) ||
816 (controller.device->GetNpadStyleIndex() == Core::HID::NpadStyleIndex::JoyconRight &&
817 (vibration_device_handle.npad_type == Core::HID::NpadStyleIndex::JoyconLeft ||
818 vibration_device_handle.device_index == Core::HID::DeviceIndex::Left))) {
819 return;
820 }
821
822 // Filter out vibrations with equivalent values to reduce unnecessary state changes.
823 if (vibration_value.low_amplitude ==
824 controller.vibration[device_index].latest_vibration_value.low_amplitude &&
825 vibration_value.high_amplitude ==
826 controller.vibration[device_index].latest_vibration_value.high_amplitude) {
827 return;
828 }
829
830 if (VibrateControllerAtIndex(aruid, controller.device->GetNpadIdType(), device_index,
831 vibration_value)) {
832 controller.vibration[device_index].latest_vibration_value = vibration_value;
833 }
834}
835
836void NPad::VibrateControllers(
837 u64 aruid, std::span<const Core::HID::VibrationDeviceHandle> vibration_device_handles,
838 std::span<const Core::HID::VibrationValue> vibration_values) {
839 if (!Settings::values.vibration_enabled.GetValue() && !permit_vibration_session_enabled) {
840 return;
841 }
842
843 ASSERT_OR_EXECUTE_MSG(
844 vibration_device_handles.size() == vibration_values.size(), { return; },
845 "The amount of device handles does not match with the amount of vibration values,"
846 "this is undefined behavior!");
847
848 for (std::size_t i = 0; i < vibration_device_handles.size(); ++i) {
849 VibrateController(aruid, vibration_device_handles[i], vibration_values[i]);
850 }
851}
852
853Core::HID::VibrationValue NPad::GetLastVibration(
854 u64 aruid, const Core::HID::VibrationDeviceHandle& vibration_device_handle) const {
855 if (IsVibrationHandleValid(vibration_device_handle).IsError()) {
856 return {};
857 }
858
859 const auto& controller = GetControllerFromHandle(aruid, vibration_device_handle);
860 const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index);
861 return controller.vibration[device_index].latest_vibration_value;
862}
863
864void NPad::InitializeVibrationDevice(
865 const Core::HID::VibrationDeviceHandle& vibration_device_handle) {
866 if (IsVibrationHandleValid(vibration_device_handle).IsError()) {
867 return;
868 }
869
870 const auto aruid = applet_resource_holder.applet_resource->GetActiveAruid();
871 const auto npad_index = static_cast<Core::HID::NpadIdType>(vibration_device_handle.npad_id);
872 const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index);
873
874 if (aruid == 0) {
875 return;
876 }
877
878 InitializeVibrationDeviceAtIndex(aruid, npad_index, device_index);
879}
880
881void NPad::InitializeVibrationDeviceAtIndex(u64 aruid, Core::HID::NpadIdType npad_id,
882 std::size_t device_index) {
883 auto& controller = GetControllerFromNpadIdType(aruid, npad_id);
884 if (!Settings::values.vibration_enabled.GetValue()) {
885 controller.vibration[device_index].device_mounted = false;
886 return;
887 }
888
889 controller.vibration[device_index].device_mounted =
890 controller.device->IsVibrationEnabled(device_index);
891}
892
893void NPad::SetPermitVibrationSession(bool permit_vibration_session) {
894 permit_vibration_session_enabled = permit_vibration_session;
895}
896
897bool NPad::IsVibrationDeviceMounted(
898 u64 aruid, const Core::HID::VibrationDeviceHandle& vibration_device_handle) const {
899 if (IsVibrationHandleValid(vibration_device_handle).IsError()) {
900 return false;
901 }
902
903 const auto& controller = GetControllerFromHandle(aruid, vibration_device_handle);
904 const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index);
905 return controller.vibration[device_index].device_mounted;
906}
907
908Result NPad::AcquireNpadStyleSetUpdateEventHandle(u64 aruid, Kernel::KReadableEvent** out_event, 745Result NPad::AcquireNpadStyleSetUpdateEventHandle(u64 aruid, Kernel::KReadableEvent** out_event,
909 Core::HID::NpadIdType npad_id) { 746 Core::HID::NpadIdType npad_id) {
910 std::scoped_lock lock{mutex}; 747 std::scoped_lock lock{mutex};
@@ -936,11 +773,6 @@ Result NPad::DisconnectNpad(u64 aruid, Core::HID::NpadIdType npad_id) {
936 773
937 LOG_DEBUG(Service_HID, "Npad disconnected {}", npad_id); 774 LOG_DEBUG(Service_HID, "Npad disconnected {}", npad_id);
938 auto& controller = GetControllerFromNpadIdType(aruid, npad_id); 775 auto& controller = GetControllerFromNpadIdType(aruid, npad_id);
939 for (std::size_t device_idx = 0; device_idx < controller.vibration.size(); ++device_idx) {
940 // Send an empty vibration to stop any vibrations.
941 VibrateControllerAtIndex(aruid, npad_id, device_idx, {});
942 controller.vibration[device_idx].device_mounted = false;
943 }
944 776
945 auto* shared_memory = controller.shared_memory; 777 auto* shared_memory = controller.shared_memory;
946 // Don't reset shared_memory->assignment_mode this value is persistent 778 // Don't reset shared_memory->assignment_mode this value is persistent
@@ -1236,22 +1068,17 @@ void NPad::UnregisterAppletResourceUserId(u64 aruid) {
1236} 1068}
1237 1069
1238void NPad::SetNpadExternals(std::shared_ptr<AppletResource> resource, 1070void NPad::SetNpadExternals(std::shared_ptr<AppletResource> resource,
1239 std::recursive_mutex* shared_mutex) { 1071 std::recursive_mutex* shared_mutex,
1072 std::shared_ptr<HandheldConfig> handheld_config) {
1240 applet_resource_holder.applet_resource = resource; 1073 applet_resource_holder.applet_resource = resource;
1241 applet_resource_holder.shared_mutex = shared_mutex; 1074 applet_resource_holder.shared_mutex = shared_mutex;
1242 applet_resource_holder.shared_npad_resource = &npad_resource; 1075 applet_resource_holder.shared_npad_resource = &npad_resource;
1243} 1076 applet_resource_holder.handheld_config = handheld_config;
1244 1077
1245NPad::NpadControllerData& NPad::GetControllerFromHandle( 1078 for (auto& abstract_pad : abstracted_pads) {
1246 u64 aruid, const Core::HID::VibrationDeviceHandle& device_handle) { 1079 abstract_pad.SetExternals(&applet_resource_holder, nullptr, nullptr, nullptr, nullptr,
1247 const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id); 1080 &vibration_handler, &hid_core);
1248 return GetControllerFromNpadIdType(aruid, npad_id); 1081 }
1249}
1250
1251const NPad::NpadControllerData& NPad::GetControllerFromHandle(
1252 u64 aruid, const Core::HID::VibrationDeviceHandle& device_handle) const {
1253 const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id);
1254 return GetControllerFromNpadIdType(aruid, npad_id);
1255} 1082}
1256 1083
1257NPad::NpadControllerData& NPad::GetControllerFromHandle( 1084NPad::NpadControllerData& NPad::GetControllerFromHandle(
@@ -1389,4 +1216,97 @@ Result NPad::GetLastActiveNpad(Core::HID::NpadIdType& out_npad_id) const {
1389 return ResultSuccess; 1216 return ResultSuccess;
1390} 1217}
1391 1218
1219NpadVibration* NPad::GetVibrationHandler() {
1220 return &vibration_handler;
1221}
1222
1223std::vector<NpadVibrationBase*> NPad::GetAllVibrationDevices() {
1224 std::vector<NpadVibrationBase*> vibration_devices;
1225
1226 for (auto& abstract_pad : abstracted_pads) {
1227 auto* left_device = abstract_pad.GetVibrationDevice(Core::HID::DeviceIndex::Left);
1228 auto* right_device = abstract_pad.GetVibrationDevice(Core::HID::DeviceIndex::Right);
1229 auto* n64_device = abstract_pad.GetGCVibrationDevice();
1230 auto* gc_device = abstract_pad.GetGCVibrationDevice();
1231
1232 if (left_device != nullptr) {
1233 vibration_devices.emplace_back(left_device);
1234 }
1235 if (right_device != nullptr) {
1236 vibration_devices.emplace_back(right_device);
1237 }
1238 if (n64_device != nullptr) {
1239 vibration_devices.emplace_back(n64_device);
1240 }
1241 if (gc_device != nullptr) {
1242 vibration_devices.emplace_back(gc_device);
1243 }
1244 }
1245
1246 return vibration_devices;
1247}
1248
1249NpadVibrationBase* NPad::GetVibrationDevice(const Core::HID::VibrationDeviceHandle& handle) {
1250 if (IsVibrationHandleValid(handle).IsError()) {
1251 return nullptr;
1252 }
1253
1254 const auto npad_index = NpadIdTypeToIndex(static_cast<Core::HID::NpadIdType>(handle.npad_id));
1255 const auto style_inde = static_cast<Core::HID::NpadStyleIndex>(handle.npad_type);
1256 if (style_inde == Core::HID::NpadStyleIndex::GameCube) {
1257 return abstracted_pads[npad_index].GetGCVibrationDevice();
1258 }
1259 if (style_inde == Core::HID::NpadStyleIndex::N64) {
1260 return abstracted_pads[npad_index].GetN64VibrationDevice();
1261 }
1262 return abstracted_pads[npad_index].GetVibrationDevice(handle.device_index);
1263}
1264
1265NpadN64VibrationDevice* NPad::GetN64VibrationDevice(
1266 const Core::HID::VibrationDeviceHandle& handle) {
1267 if (IsVibrationHandleValid(handle).IsError()) {
1268 return nullptr;
1269 }
1270
1271 const auto npad_index = NpadIdTypeToIndex(static_cast<Core::HID::NpadIdType>(handle.npad_id));
1272 const auto style_inde = static_cast<Core::HID::NpadStyleIndex>(handle.npad_type);
1273 if (style_inde != Core::HID::NpadStyleIndex::N64) {
1274 return nullptr;
1275 }
1276 return abstracted_pads[npad_index].GetN64VibrationDevice();
1277}
1278
1279NpadVibrationDevice* NPad::GetNSVibrationDevice(const Core::HID::VibrationDeviceHandle& handle) {
1280 if (IsVibrationHandleValid(handle).IsError()) {
1281 return nullptr;
1282 }
1283
1284 const auto npad_index = NpadIdTypeToIndex(static_cast<Core::HID::NpadIdType>(handle.npad_id));
1285 const auto style_inde = static_cast<Core::HID::NpadStyleIndex>(handle.npad_type);
1286 if (style_inde == Core::HID::NpadStyleIndex::GameCube ||
1287 style_inde == Core::HID::NpadStyleIndex::N64) {
1288 return nullptr;
1289 }
1290
1291 return abstracted_pads[npad_index].GetVibrationDevice(handle.device_index);
1292}
1293
1294NpadGcVibrationDevice* NPad::GetGcVibrationDevice(const Core::HID::VibrationDeviceHandle& handle) {
1295 if (IsVibrationHandleValid(handle).IsError()) {
1296 return nullptr;
1297 }
1298
1299 const auto npad_index = NpadIdTypeToIndex(static_cast<Core::HID::NpadIdType>(handle.npad_id));
1300 const auto style_inde = static_cast<Core::HID::NpadStyleIndex>(handle.npad_type);
1301 if (style_inde != Core::HID::NpadStyleIndex::GameCube) {
1302 return nullptr;
1303 }
1304 return abstracted_pads[npad_index].GetGCVibrationDevice();
1305}
1306
1307void NPad::UpdateHandheldAbstractState() {
1308 std::scoped_lock lock{mutex};
1309 abstracted_pads[NpadIdTypeToIndex(Core::HID::NpadIdType::Handheld)].Update();
1310}
1311
1392} // namespace Service::HID 1312} // namespace Service::HID
diff --git a/src/hid_core/resources/npad/npad.h b/src/hid_core/resources/npad/npad.h
index 01f3dabb1..18b25c688 100644
--- a/src/hid_core/resources/npad/npad.h
+++ b/src/hid_core/resources/npad/npad.h
@@ -10,9 +10,15 @@
10 10
11#include "common/common_types.h" 11#include "common/common_types.h"
12#include "hid_core/hid_types.h" 12#include "hid_core/hid_types.h"
13#include "hid_core/resources/abstracted_pad/abstract_pad.h"
13#include "hid_core/resources/controller_base.h" 14#include "hid_core/resources/controller_base.h"
14#include "hid_core/resources/npad/npad_resource.h" 15#include "hid_core/resources/npad/npad_resource.h"
15#include "hid_core/resources/npad/npad_types.h" 16#include "hid_core/resources/npad/npad_types.h"
17#include "hid_core/resources/npad/npad_vibration.h"
18#include "hid_core/resources/vibration/gc_vibration_device.h"
19#include "hid_core/resources/vibration/n64_vibration_device.h"
20#include "hid_core/resources/vibration/vibration_base.h"
21#include "hid_core/resources/vibration/vibration_device.h"
16 22
17namespace Core::HID { 23namespace Core::HID {
18class EmulatedController; 24class EmulatedController;
@@ -32,6 +38,7 @@ union Result;
32 38
33namespace Service::HID { 39namespace Service::HID {
34class AppletResource; 40class AppletResource;
41struct HandheldConfig;
35struct NpadInternalState; 42struct NpadInternalState;
36struct NpadSixAxisSensorLifo; 43struct NpadSixAxisSensorLifo;
37struct NpadSharedMemoryFormat; 44struct NpadSharedMemoryFormat;
@@ -68,31 +75,6 @@ public:
68 bool SetNpadMode(u64 aruid, Core::HID::NpadIdType& new_npad_id, Core::HID::NpadIdType npad_id, 75 bool SetNpadMode(u64 aruid, Core::HID::NpadIdType& new_npad_id, Core::HID::NpadIdType npad_id,
69 NpadJoyDeviceType npad_device_type, NpadJoyAssignmentMode assignment_mode); 76 NpadJoyDeviceType npad_device_type, NpadJoyAssignmentMode assignment_mode);
70 77
71 bool VibrateControllerAtIndex(u64 aruid, Core::HID::NpadIdType npad_id,
72 std::size_t device_index,
73 const Core::HID::VibrationValue& vibration_value);
74
75 void VibrateController(u64 aruid,
76 const Core::HID::VibrationDeviceHandle& vibration_device_handle,
77 const Core::HID::VibrationValue& vibration_value);
78
79 void VibrateControllers(
80 u64 aruid, std::span<const Core::HID::VibrationDeviceHandle> vibration_device_handles,
81 std::span<const Core::HID::VibrationValue> vibration_values);
82
83 Core::HID::VibrationValue GetLastVibration(
84 u64 aruid, const Core::HID::VibrationDeviceHandle& vibration_device_handle) const;
85
86 void InitializeVibrationDevice(const Core::HID::VibrationDeviceHandle& vibration_device_handle);
87
88 void InitializeVibrationDeviceAtIndex(u64 aruid, Core::HID::NpadIdType npad_id,
89 std::size_t device_index);
90
91 void SetPermitVibrationSession(bool permit_vibration_session);
92
93 bool IsVibrationDeviceMounted(
94 u64 aruid, const Core::HID::VibrationDeviceHandle& vibration_device_handle) const;
95
96 Result AcquireNpadStyleSetUpdateEventHandle(u64 aruid, Kernel::KReadableEvent** out_event, 78 Result AcquireNpadStyleSetUpdateEventHandle(u64 aruid, Kernel::KReadableEvent** out_event,
97 Core::HID::NpadIdType npad_id); 79 Core::HID::NpadIdType npad_id);
98 80
@@ -145,7 +127,8 @@ public:
145 Result RegisterAppletResourceUserId(u64 aruid); 127 Result RegisterAppletResourceUserId(u64 aruid);
146 void UnregisterAppletResourceUserId(u64 aruid); 128 void UnregisterAppletResourceUserId(u64 aruid);
147 void SetNpadExternals(std::shared_ptr<AppletResource> resource, 129 void SetNpadExternals(std::shared_ptr<AppletResource> resource,
148 std::recursive_mutex* shared_mutex); 130 std::recursive_mutex* shared_mutex,
131 std::shared_ptr<HandheldConfig> handheld_config);
149 132
150 AppletDetailedUiType GetAppletDetailedUiType(Core::HID::NpadIdType npad_id); 133 AppletDetailedUiType GetAppletDetailedUiType(Core::HID::NpadIdType npad_id);
151 134
@@ -161,18 +144,20 @@ public:
161 144
162 Result GetLastActiveNpad(Core::HID::NpadIdType& out_npad_id) const; 145 Result GetLastActiveNpad(Core::HID::NpadIdType& out_npad_id) const;
163 146
164private: 147 NpadVibration* GetVibrationHandler();
165 struct VibrationData { 148 std::vector<NpadVibrationBase*> GetAllVibrationDevices();
166 bool device_mounted{}; 149 NpadVibrationBase* GetVibrationDevice(const Core::HID::VibrationDeviceHandle& handle);
167 Core::HID::VibrationValue latest_vibration_value{}; 150 NpadN64VibrationDevice* GetN64VibrationDevice(const Core::HID::VibrationDeviceHandle& handle);
168 std::chrono::steady_clock::time_point last_vibration_timepoint{}; 151 NpadVibrationDevice* GetNSVibrationDevice(const Core::HID::VibrationDeviceHandle& handle);
169 }; 152 NpadGcVibrationDevice* GetGcVibrationDevice(const Core::HID::VibrationDeviceHandle& handle);
170 153
154 void UpdateHandheldAbstractState();
155
156private:
171 struct NpadControllerData { 157 struct NpadControllerData {
172 NpadInternalState* shared_memory = nullptr; 158 NpadInternalState* shared_memory = nullptr;
173 Core::HID::EmulatedController* device = nullptr; 159 Core::HID::EmulatedController* device = nullptr;
174 160
175 std::array<VibrationData, 2> vibration{};
176 bool is_connected{}; 161 bool is_connected{};
177 162
178 // Dual joycons can have only one side connected 163 // Dual joycons can have only one side connected
@@ -192,10 +177,6 @@ private:
192 void WriteEmptyEntry(NpadInternalState* npad); 177 void WriteEmptyEntry(NpadInternalState* npad);
193 178
194 NpadControllerData& GetControllerFromHandle( 179 NpadControllerData& GetControllerFromHandle(
195 u64 aruid, const Core::HID::VibrationDeviceHandle& device_handle);
196 const NpadControllerData& GetControllerFromHandle(
197 u64 aruid, const Core::HID::VibrationDeviceHandle& device_handle) const;
198 NpadControllerData& GetControllerFromHandle(
199 u64 aruid, const Core::HID::SixAxisSensorHandle& device_handle); 180 u64 aruid, const Core::HID::SixAxisSensorHandle& device_handle);
200 const NpadControllerData& GetControllerFromHandle( 181 const NpadControllerData& GetControllerFromHandle(
201 u64 aruid, const Core::HID::SixAxisSensorHandle& device_handle) const; 182 u64 aruid, const Core::HID::SixAxisSensorHandle& device_handle) const;
@@ -215,11 +196,13 @@ private:
215 mutable std::mutex mutex; 196 mutable std::mutex mutex;
216 NPadResource npad_resource; 197 NPadResource npad_resource;
217 AppletResourceHolder applet_resource_holder{}; 198 AppletResourceHolder applet_resource_holder{};
199 std::array<AbstractPad, MaxSupportedNpadIdTypes> abstracted_pads;
200 NpadVibration vibration_handler{};
201
218 Kernel::KEvent* input_event{nullptr}; 202 Kernel::KEvent* input_event{nullptr};
219 std::mutex* input_mutex{nullptr}; 203 std::mutex* input_mutex{nullptr};
220 204
221 std::atomic<u64> press_state{}; 205 std::atomic<u64> press_state{};
222 bool permit_vibration_session_enabled;
223 std::array<std::array<NpadControllerData, MaxSupportedNpadIdTypes>, AruidIndexMax> 206 std::array<std::array<NpadControllerData, MaxSupportedNpadIdTypes>, AruidIndexMax>
224 controller_data{}; 207 controller_data{};
225}; 208};
diff --git a/src/hid_core/resources/npad/npad_types.h b/src/hid_core/resources/npad/npad_types.h
index fd86c8e40..92700d69a 100644
--- a/src/hid_core/resources/npad/npad_types.h
+++ b/src/hid_core/resources/npad/npad_types.h
@@ -8,6 +8,10 @@
8#include "common/common_types.h" 8#include "common/common_types.h"
9#include "hid_core/hid_types.h" 9#include "hid_core/hid_types.h"
10 10
11namespace Core::HID {
12class EmulatedController;
13}
14
11namespace Service::HID { 15namespace Service::HID {
12static constexpr std::size_t MaxSupportedNpadIdTypes = 10; 16static constexpr std::size_t MaxSupportedNpadIdTypes = 10;
13static constexpr std::size_t StyleIndexCount = 7; 17static constexpr std::size_t StyleIndexCount = 7;
@@ -348,7 +352,7 @@ struct IAbstractedPad {
348 u8 indicator; 352 u8 indicator;
349 std::vector<f32> virtual_six_axis_sensor_acceleration; 353 std::vector<f32> virtual_six_axis_sensor_acceleration;
350 std::vector<f32> virtual_six_axis_sensor_angle; 354 std::vector<f32> virtual_six_axis_sensor_angle;
351 u64 xcd_handle; 355 Core::HID::EmulatedController* xcd_handle;
352 u64 color; 356 u64 color;
353}; 357};
354} // namespace Service::HID 358} // namespace Service::HID
diff --git a/src/hid_core/resources/npad/npad_vibration.cpp b/src/hid_core/resources/npad/npad_vibration.cpp
index 7056e8eab..05aad4c54 100644
--- a/src/hid_core/resources/npad/npad_vibration.cpp
+++ b/src/hid_core/resources/npad/npad_vibration.cpp
@@ -77,4 +77,8 @@ Result NpadVibration::EndPermitVibrationSession() {
77 return ResultSuccess; 77 return ResultSuccess;
78} 78}
79 79
80u64 NpadVibration::GetSessionAruid() const {
81 return session_aruid;
82}
83
80} // namespace Service::HID 84} // namespace Service::HID
diff --git a/src/hid_core/resources/npad/npad_vibration.h b/src/hid_core/resources/npad/npad_vibration.h
index 0748aeffc..d5a95f2a0 100644
--- a/src/hid_core/resources/npad/npad_vibration.h
+++ b/src/hid_core/resources/npad/npad_vibration.h
@@ -25,6 +25,8 @@ public:
25 Result BeginPermitVibrationSession(u64 aruid); 25 Result BeginPermitVibrationSession(u64 aruid);
26 Result EndPermitVibrationSession(); 26 Result EndPermitVibrationSession();
27 27
28 u64 GetSessionAruid() const;
29
28private: 30private:
29 f32 volume{}; 31 f32 volume{};
30 u64 session_aruid{}; 32 u64 session_aruid{};