diff options
| author | 2024-01-10 22:06:54 -0600 | |
|---|---|---|
| committer | 2024-01-15 23:15:40 -0600 | |
| commit | 2cacb9d48c98603176e52ecc94f2374a934797fb (patch) | |
| tree | 12badf5b4eede22b22dece03a9074197ec631a1e /src/hid_core/resources | |
| parent | Merge pull request #12686 from szepeviktor/typos3 (diff) | |
| download | yuzu-2cacb9d48c98603176e52ecc94f2374a934797fb.tar.gz yuzu-2cacb9d48c98603176e52ecc94f2374a934797fb.tar.xz yuzu-2cacb9d48c98603176e52ecc94f2374a934797fb.zip | |
service: hid: Fully implement abstract vibration
Diffstat (limited to 'src/hid_core/resources')
21 files changed, 413 insertions, 284 deletions
diff --git a/src/hid_core/resources/abstracted_pad/abstract_ir_sensor_handler.cpp b/src/hid_core/resources/abstracted_pad/abstract_ir_sensor_handler.cpp index d4e4181bf..e399edfd7 100644 --- a/src/hid_core/resources/abstracted_pad/abstract_ir_sensor_handler.cpp +++ b/src/hid_core/resources/abstracted_pad/abstract_ir_sensor_handler.cpp | |||
| @@ -115,7 +115,7 @@ Result NpadAbstractIrSensorHandler::GetXcdHandleForNpadWithIrSensor(u64& handle) | |||
| 115 | if (sensor_state < NpadIrSensorState::Available) { | 115 | if (sensor_state < NpadIrSensorState::Available) { |
| 116 | return ResultIrSensorIsNotReady; | 116 | return ResultIrSensorIsNotReady; |
| 117 | } | 117 | } |
| 118 | handle = xcd_handle; | 118 | // handle = xcd_handle; |
| 119 | return ResultSuccess; | 119 | return ResultSuccess; |
| 120 | } | 120 | } |
| 121 | 121 | ||
diff --git a/src/hid_core/resources/abstracted_pad/abstract_ir_sensor_handler.h b/src/hid_core/resources/abstracted_pad/abstract_ir_sensor_handler.h index fe8e005af..997811511 100644 --- a/src/hid_core/resources/abstracted_pad/abstract_ir_sensor_handler.h +++ b/src/hid_core/resources/abstracted_pad/abstract_ir_sensor_handler.h | |||
| @@ -7,6 +7,10 @@ | |||
| 7 | #include "core/hle/result.h" | 7 | #include "core/hle/result.h" |
| 8 | #include "hid_core/hid_types.h" | 8 | #include "hid_core/hid_types.h" |
| 9 | 9 | ||
| 10 | namespace Core::HID { | ||
| 11 | class EmulatedController; | ||
| 12 | } | ||
| 13 | |||
| 10 | namespace Kernel { | 14 | namespace Kernel { |
| 11 | class KEvent; | 15 | class KEvent; |
| 12 | class KReadableEvent; | 16 | class KReadableEvent; |
| @@ -50,7 +54,7 @@ private: | |||
| 50 | 54 | ||
| 51 | s32 ref_counter{}; | 55 | s32 ref_counter{}; |
| 52 | Kernel::KEvent* ir_sensor_event{nullptr}; | 56 | Kernel::KEvent* ir_sensor_event{nullptr}; |
| 53 | u64 xcd_handle{}; | 57 | Core::HID::EmulatedController* xcd_handle{}; |
| 54 | NpadIrSensorState sensor_state{}; | 58 | NpadIrSensorState sensor_state{}; |
| 55 | }; | 59 | }; |
| 56 | } // namespace Service::HID | 60 | } // namespace Service::HID |
diff --git a/src/hid_core/resources/abstracted_pad/abstract_pad.cpp b/src/hid_core/resources/abstracted_pad/abstract_pad.cpp index 2c7691d7c..435b095f0 100644 --- a/src/hid_core/resources/abstracted_pad/abstract_pad.cpp +++ b/src/hid_core/resources/abstracted_pad/abstract_pad.cpp | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project |
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | 2 | // SPDX-License-Identifier: GPL-3.0-or-later |
| 3 | 3 | ||
| 4 | #include "hid_core/hid_core.h" | ||
| 4 | #include "hid_core/hid_result.h" | 5 | #include "hid_core/hid_result.h" |
| 5 | #include "hid_core/resources/abstracted_pad/abstract_pad.h" | 6 | #include "hid_core/resources/abstracted_pad/abstract_pad.h" |
| 6 | #include "hid_core/resources/applet_resource.h" | 7 | #include "hid_core/resources/applet_resource.h" |
| @@ -16,7 +17,7 @@ void AbstractPad::SetExternals(AppletResourceHolder* applet_resource, | |||
| 16 | CaptureButtonResource* capture_button_resource, | 17 | CaptureButtonResource* capture_button_resource, |
| 17 | HomeButtonResource* home_button_resource, | 18 | HomeButtonResource* home_button_resource, |
| 18 | SixAxisResource* sixaxis_resource, PalmaResource* palma_resource, | 19 | SixAxisResource* sixaxis_resource, PalmaResource* palma_resource, |
| 19 | VibrationHandler* vibration) { | 20 | NpadVibration* vibration, Core::HID::HIDCore* core) { |
| 20 | applet_resource_holder = applet_resource; | 21 | applet_resource_holder = applet_resource; |
| 21 | 22 | ||
| 22 | properties_handler.SetAppletResource(applet_resource_holder); | 23 | properties_handler.SetAppletResource(applet_resource_holder); |
| @@ -35,13 +36,14 @@ void AbstractPad::SetExternals(AppletResourceHolder* applet_resource, | |||
| 35 | mcu_handler.SetAbstractPadHolder(&abstract_pad_holder); | 36 | mcu_handler.SetAbstractPadHolder(&abstract_pad_holder); |
| 36 | mcu_handler.SetPropertiesHandler(&properties_handler); | 37 | mcu_handler.SetPropertiesHandler(&properties_handler); |
| 37 | 38 | ||
| 38 | std::array<NpadVibrationDevice*, 2> vibration_devices{&vibration_left, &vibration_right}; | ||
| 39 | vibration_handler.SetAppletResource(applet_resource_holder); | 39 | vibration_handler.SetAppletResource(applet_resource_holder); |
| 40 | vibration_handler.SetAbstractPadHolder(&abstract_pad_holder); | 40 | vibration_handler.SetAbstractPadHolder(&abstract_pad_holder); |
| 41 | vibration_handler.SetPropertiesHandler(&properties_handler); | 41 | vibration_handler.SetPropertiesHandler(&properties_handler); |
| 42 | vibration_handler.SetN64Vibration(&vibration_n64); | 42 | vibration_handler.SetN64Vibration(&vibration_n64); |
| 43 | vibration_handler.SetVibration(vibration_devices); | 43 | vibration_handler.SetVibration(&vibration_left, &vibration_right); |
| 44 | vibration_handler.SetGcVibration(&vibration_gc); | 44 | vibration_handler.SetGcVibration(&vibration_gc); |
| 45 | vibration_handler.SetVibrationHandler(vibration); | ||
| 46 | vibration_handler.SetHidCore(core); | ||
| 45 | 47 | ||
| 46 | sixaxis_handler.SetAppletResource(applet_resource_holder); | 48 | sixaxis_handler.SetAppletResource(applet_resource_holder); |
| 47 | sixaxis_handler.SetAbstractPadHolder(&abstract_pad_holder); | 49 | sixaxis_handler.SetAbstractPadHolder(&abstract_pad_holder); |
| @@ -239,11 +241,6 @@ NpadVibrationDevice* AbstractPad::GetVibrationDevice(Core::HID::DeviceIndex devi | |||
| 239 | return &vibration_left; | 241 | return &vibration_left; |
| 240 | } | 242 | } |
| 241 | 243 | ||
| 242 | void AbstractPad::GetLeftRightVibrationDevice(std::vector<NpadVibrationDevice*> list) { | ||
| 243 | list.emplace_back(&vibration_left); | ||
| 244 | list.emplace_back(&vibration_right); | ||
| 245 | } | ||
| 246 | |||
| 247 | NpadGcVibrationDevice* AbstractPad::GetGCVibrationDevice() { | 244 | NpadGcVibrationDevice* AbstractPad::GetGCVibrationDevice() { |
| 248 | return &vibration_gc; | 245 | return &vibration_gc; |
| 249 | } | 246 | } |
diff --git a/src/hid_core/resources/abstracted_pad/abstract_pad.h b/src/hid_core/resources/abstracted_pad/abstract_pad.h index cbdf84af7..329792457 100644 --- a/src/hid_core/resources/abstracted_pad/abstract_pad.h +++ b/src/hid_core/resources/abstracted_pad/abstract_pad.h | |||
| @@ -32,7 +32,6 @@ class AppletResource; | |||
| 32 | class SixAxisResource; | 32 | class SixAxisResource; |
| 33 | class PalmaResource; | 33 | class PalmaResource; |
| 34 | class NPadResource; | 34 | class NPadResource; |
| 35 | class AbstractPad; | ||
| 36 | class NpadLastActiveHandler; | 35 | class NpadLastActiveHandler; |
| 37 | class NpadIrNfcHandler; | 36 | class NpadIrNfcHandler; |
| 38 | class UniquePads; | 37 | class UniquePads; |
| @@ -44,7 +43,6 @@ class NpadGcVibration; | |||
| 44 | 43 | ||
| 45 | class CaptureButtonResource; | 44 | class CaptureButtonResource; |
| 46 | class HomeButtonResource; | 45 | class HomeButtonResource; |
| 47 | class VibrationHandler; | ||
| 48 | 46 | ||
| 49 | struct HandheldConfig; | 47 | struct HandheldConfig; |
| 50 | 48 | ||
| @@ -57,7 +55,8 @@ public: | |||
| 57 | void SetExternals(AppletResourceHolder* applet_resource, | 55 | void SetExternals(AppletResourceHolder* applet_resource, |
| 58 | CaptureButtonResource* capture_button_resource, | 56 | CaptureButtonResource* capture_button_resource, |
| 59 | HomeButtonResource* home_button_resource, SixAxisResource* sixaxis_resource, | 57 | HomeButtonResource* home_button_resource, SixAxisResource* sixaxis_resource, |
| 60 | PalmaResource* palma_resource, VibrationHandler* vibration); | 58 | PalmaResource* palma_resource, NpadVibration* vibration, |
| 59 | Core::HID::HIDCore* core); | ||
| 61 | void SetNpadId(Core::HID::NpadIdType npad_id); | 60 | void SetNpadId(Core::HID::NpadIdType npad_id); |
| 62 | 61 | ||
| 63 | Result Activate(); | 62 | Result Activate(); |
| @@ -78,7 +77,6 @@ public: | |||
| 78 | 77 | ||
| 79 | NpadN64VibrationDevice* GetN64VibrationDevice(); | 78 | NpadN64VibrationDevice* GetN64VibrationDevice(); |
| 80 | NpadVibrationDevice* GetVibrationDevice(Core::HID::DeviceIndex device_index); | 79 | NpadVibrationDevice* GetVibrationDevice(Core::HID::DeviceIndex device_index); |
| 81 | void GetLeftRightVibrationDevice(std::vector<NpadVibrationDevice*> list); | ||
| 82 | NpadGcVibrationDevice* GetGCVibrationDevice(); | 80 | NpadGcVibrationDevice* GetGCVibrationDevice(); |
| 83 | 81 | ||
| 84 | Core::HID::NpadIdType GetLastActiveNpad(); | 82 | Core::HID::NpadIdType GetLastActiveNpad(); |
diff --git a/src/hid_core/resources/abstracted_pad/abstract_vibration_handler.cpp b/src/hid_core/resources/abstracted_pad/abstract_vibration_handler.cpp index a00d6c9de..ca64b0a43 100644 --- a/src/hid_core/resources/abstracted_pad/abstract_vibration_handler.cpp +++ b/src/hid_core/resources/abstracted_pad/abstract_vibration_handler.cpp | |||
| @@ -1,6 +1,8 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project |
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | 2 | // SPDX-License-Identifier: GPL-3.0-or-later |
| 3 | 3 | ||
| 4 | #include "hid_core/frontend/emulated_controller.h" | ||
| 5 | #include "hid_core/hid_core.h" | ||
| 4 | #include "hid_core/hid_result.h" | 6 | #include "hid_core/hid_result.h" |
| 5 | #include "hid_core/hid_util.h" | 7 | #include "hid_core/hid_util.h" |
| 6 | #include "hid_core/resources/abstracted_pad/abstract_pad_holder.h" | 8 | #include "hid_core/resources/abstracted_pad/abstract_pad_holder.h" |
| @@ -30,14 +32,22 @@ void NpadAbstractVibrationHandler::SetPropertiesHandler(NpadAbstractPropertiesHa | |||
| 30 | properties_handler = handler; | 32 | properties_handler = handler; |
| 31 | } | 33 | } |
| 32 | 34 | ||
| 35 | void NpadAbstractVibrationHandler::SetVibrationHandler(NpadVibration* handler) { | ||
| 36 | vibration_handler = handler; | ||
| 37 | } | ||
| 38 | |||
| 39 | void NpadAbstractVibrationHandler::SetHidCore(Core::HID::HIDCore* core) { | ||
| 40 | hid_core = core; | ||
| 41 | } | ||
| 42 | |||
| 33 | void NpadAbstractVibrationHandler::SetN64Vibration(NpadN64VibrationDevice* n64_device) { | 43 | void NpadAbstractVibrationHandler::SetN64Vibration(NpadN64VibrationDevice* n64_device) { |
| 34 | n64_vibration_device = n64_device; | 44 | n64_vibration_device = n64_device; |
| 35 | } | 45 | } |
| 36 | 46 | ||
| 37 | void NpadAbstractVibrationHandler::SetVibration(std::span<NpadVibrationDevice*> device) { | 47 | void NpadAbstractVibrationHandler::SetVibration(NpadVibrationDevice* left_device, |
| 38 | for (std::size_t i = 0; i < device.size() && i < vibration_device.size(); i++) { | 48 | NpadVibrationDevice* right_device) { |
| 39 | vibration_device[i] = device[i]; | 49 | left_vibration_device = left_device; |
| 40 | } | 50 | right_vibration_device = right_device; |
| 41 | } | 51 | } |
| 42 | 52 | ||
| 43 | void NpadAbstractVibrationHandler::SetGcVibration(NpadGcVibrationDevice* gc_device) { | 53 | void NpadAbstractVibrationHandler::SetGcVibration(NpadGcVibrationDevice* gc_device) { |
| @@ -69,5 +79,29 @@ void NpadAbstractVibrationHandler::UpdateVibrationState() { | |||
| 69 | if (!is_handheld_hid_enabled && is_force_handheld_style_vibration) { | 79 | if (!is_handheld_hid_enabled && is_force_handheld_style_vibration) { |
| 70 | // TODO | 80 | // TODO |
| 71 | } | 81 | } |
| 82 | |||
| 83 | // TODO: This function isn't accurate. It's supposed to get 5 abstracted pads from the | ||
| 84 | // NpadAbstractPropertiesHandler but this handler isn't fully implemented yet | ||
| 85 | IAbstractedPad abstracted_pad{}; | ||
| 86 | const auto npad_id = properties_handler->GetNpadId(); | ||
| 87 | abstracted_pad.xcd_handle = hid_core->GetEmulatedController(npad_id); | ||
| 88 | abstracted_pad.internal_flags.is_connected.Assign(abstracted_pad.xcd_handle->IsConnected()); | ||
| 89 | |||
| 90 | if (abstracted_pad.internal_flags.is_connected) { | ||
| 91 | left_vibration_device->Mount(abstracted_pad, Core::HID::DeviceIndex::Left, | ||
| 92 | vibration_handler); | ||
| 93 | right_vibration_device->Mount(abstracted_pad, Core::HID::DeviceIndex::Right, | ||
| 94 | vibration_handler); | ||
| 95 | gc_vibration_device->Mount(abstracted_pad, 0, vibration_handler); | ||
| 96 | gc_vibration_device->Mount(abstracted_pad, 0, vibration_handler); | ||
| 97 | n64_vibration_device->Mount(abstracted_pad, vibration_handler); | ||
| 98 | return; | ||
| 99 | } | ||
| 100 | |||
| 101 | left_vibration_device->Unmount(); | ||
| 102 | right_vibration_device->Unmount(); | ||
| 103 | gc_vibration_device->Unmount(); | ||
| 104 | gc_vibration_device->Unmount(); | ||
| 105 | n64_vibration_device->Unmount(); | ||
| 72 | } | 106 | } |
| 73 | } // namespace Service::HID | 107 | } // namespace Service::HID |
diff --git a/src/hid_core/resources/abstracted_pad/abstract_vibration_handler.h b/src/hid_core/resources/abstracted_pad/abstract_vibration_handler.h index aeb07ce86..8bc8129c2 100644 --- a/src/hid_core/resources/abstracted_pad/abstract_vibration_handler.h +++ b/src/hid_core/resources/abstracted_pad/abstract_vibration_handler.h | |||
| @@ -9,6 +9,10 @@ | |||
| 9 | #include "core/hle/result.h" | 9 | #include "core/hle/result.h" |
| 10 | #include "hid_core/hid_types.h" | 10 | #include "hid_core/hid_types.h" |
| 11 | 11 | ||
| 12 | namespace Core::HID { | ||
| 13 | class HIDCore; | ||
| 14 | } | ||
| 15 | |||
| 12 | namespace Service::HID { | 16 | namespace Service::HID { |
| 13 | struct AppletResourceHolder; | 17 | struct AppletResourceHolder; |
| 14 | class NpadAbstractedPadHolder; | 18 | class NpadAbstractedPadHolder; |
| @@ -27,9 +31,11 @@ public: | |||
| 27 | void SetAbstractPadHolder(NpadAbstractedPadHolder* holder); | 31 | void SetAbstractPadHolder(NpadAbstractedPadHolder* holder); |
| 28 | void SetAppletResource(AppletResourceHolder* applet_resource); | 32 | void SetAppletResource(AppletResourceHolder* applet_resource); |
| 29 | void SetPropertiesHandler(NpadAbstractPropertiesHandler* handler); | 33 | void SetPropertiesHandler(NpadAbstractPropertiesHandler* handler); |
| 34 | void SetVibrationHandler(NpadVibration* handler); | ||
| 35 | void SetHidCore(Core::HID::HIDCore* core); | ||
| 30 | 36 | ||
| 31 | void SetN64Vibration(NpadN64VibrationDevice* n64_device); | 37 | void SetN64Vibration(NpadN64VibrationDevice* n64_device); |
| 32 | void SetVibration(std::span<NpadVibrationDevice*> device); | 38 | void SetVibration(NpadVibrationDevice* left_device, NpadVibrationDevice* right_device); |
| 33 | void SetGcVibration(NpadGcVibrationDevice* gc_device); | 39 | void SetGcVibration(NpadGcVibrationDevice* gc_device); |
| 34 | 40 | ||
| 35 | Result IncrementRefCounter(); | 41 | Result IncrementRefCounter(); |
| @@ -41,9 +47,11 @@ private: | |||
| 41 | AppletResourceHolder* applet_resource_holder{nullptr}; | 47 | AppletResourceHolder* applet_resource_holder{nullptr}; |
| 42 | NpadAbstractedPadHolder* abstract_pad_holder{nullptr}; | 48 | NpadAbstractedPadHolder* abstract_pad_holder{nullptr}; |
| 43 | NpadAbstractPropertiesHandler* properties_handler{nullptr}; | 49 | NpadAbstractPropertiesHandler* properties_handler{nullptr}; |
| 50 | Core::HID::HIDCore* hid_core{nullptr}; | ||
| 44 | 51 | ||
| 45 | NpadN64VibrationDevice* n64_vibration_device{nullptr}; | 52 | NpadN64VibrationDevice* n64_vibration_device{nullptr}; |
| 46 | std::array<NpadVibrationDevice*, 2> vibration_device{}; | 53 | NpadVibrationDevice* left_vibration_device{}; |
| 54 | NpadVibrationDevice* right_vibration_device{}; | ||
| 47 | NpadGcVibrationDevice* gc_vibration_device{nullptr}; | 55 | NpadGcVibrationDevice* gc_vibration_device{nullptr}; |
| 48 | NpadVibration* vibration_handler{nullptr}; | 56 | NpadVibration* vibration_handler{nullptr}; |
| 49 | s32 ref_counter{}; | 57 | s32 ref_counter{}; |
diff --git a/src/hid_core/resources/applet_resource.cpp b/src/hid_core/resources/applet_resource.cpp index a84826050..db4134037 100644 --- a/src/hid_core/resources/applet_resource.cpp +++ b/src/hid_core/resources/applet_resource.cpp | |||
| @@ -200,6 +200,25 @@ void AppletResource::EnableInput(u64 aruid, bool is_enabled) { | |||
| 200 | data[index].flag.enable_touchscreen.Assign(is_enabled); | 200 | data[index].flag.enable_touchscreen.Assign(is_enabled); |
| 201 | } | 201 | } |
| 202 | 202 | ||
| 203 | bool AppletResource::SetAruidValidForVibration(u64 aruid, bool is_enabled) { | ||
| 204 | const u64 index = GetIndexFromAruid(aruid); | ||
| 205 | if (index >= AruidIndexMax) { | ||
| 206 | return false; | ||
| 207 | } | ||
| 208 | |||
| 209 | if (!is_enabled && aruid == active_vibration_aruid) { | ||
| 210 | active_vibration_aruid = SystemAruid; | ||
| 211 | return true; | ||
| 212 | } | ||
| 213 | |||
| 214 | if (is_enabled && aruid != active_vibration_aruid) { | ||
| 215 | active_vibration_aruid = aruid; | ||
| 216 | return true; | ||
| 217 | } | ||
| 218 | |||
| 219 | return false; | ||
| 220 | } | ||
| 221 | |||
| 203 | void AppletResource::EnableSixAxisSensor(u64 aruid, bool is_enabled) { | 222 | void AppletResource::EnableSixAxisSensor(u64 aruid, bool is_enabled) { |
| 204 | const u64 index = GetIndexFromAruid(aruid); | 223 | const u64 index = GetIndexFromAruid(aruid); |
| 205 | if (index >= AruidIndexMax) { | 224 | if (index >= AruidIndexMax) { |
diff --git a/src/hid_core/resources/applet_resource.h b/src/hid_core/resources/applet_resource.h index f3f32bac1..e9710d306 100644 --- a/src/hid_core/resources/applet_resource.h +++ b/src/hid_core/resources/applet_resource.h | |||
| @@ -101,6 +101,7 @@ public: | |||
| 101 | Result DestroySevenSixAxisTransferMemory(); | 101 | Result DestroySevenSixAxisTransferMemory(); |
| 102 | 102 | ||
| 103 | void EnableInput(u64 aruid, bool is_enabled); | 103 | void EnableInput(u64 aruid, bool is_enabled); |
| 104 | bool SetAruidValidForVibration(u64 aruid, bool is_enabled); | ||
| 104 | void EnableSixAxisSensor(u64 aruid, bool is_enabled); | 105 | void EnableSixAxisSensor(u64 aruid, bool is_enabled); |
| 105 | void EnablePadInput(u64 aruid, bool is_enabled); | 106 | void EnablePadInput(u64 aruid, bool is_enabled); |
| 106 | void EnableTouchScreen(u64 aruid, bool is_enabled); | 107 | void EnableTouchScreen(u64 aruid, bool is_enabled); |
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 | ||
| 26 | namespace Service::HID { | 27 | namespace 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 | ||
| 48 | NPad::~NPad() { | 49 | NPad::~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 | ||
| 364 | void NPad::WriteEmptyEntry(NpadInternalState* npad) { | 366 | void 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 | ||
| 743 | bool 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 | |||
| 789 | void 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 | |||
| 836 | void 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 | |||
| 853 | Core::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 | |||
| 864 | void 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 | |||
| 881 | void 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 | |||
| 893 | void NPad::SetPermitVibrationSession(bool permit_vibration_session) { | ||
| 894 | permit_vibration_session_enabled = permit_vibration_session; | ||
| 895 | } | ||
| 896 | |||
| 897 | bool 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 | |||
| 908 | Result NPad::AcquireNpadStyleSetUpdateEventHandle(u64 aruid, Kernel::KReadableEvent** out_event, | 745 | Result 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 | ||
| 1238 | void NPad::SetNpadExternals(std::shared_ptr<AppletResource> resource, | 1070 | void 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 | ||
| 1245 | NPad::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 | |||
| 1251 | const 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 | ||
| 1257 | NPad::NpadControllerData& NPad::GetControllerFromHandle( | 1084 | NPad::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 | ||
| 1219 | NpadVibration* NPad::GetVibrationHandler() { | ||
| 1220 | return &vibration_handler; | ||
| 1221 | } | ||
| 1222 | |||
| 1223 | std::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 | |||
| 1249 | NpadVibrationBase* 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 | |||
| 1265 | NpadN64VibrationDevice* 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 | |||
| 1279 | NpadVibrationDevice* 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 | |||
| 1294 | NpadGcVibrationDevice* 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 | |||
| 1307 | void 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 | ||
| 17 | namespace Core::HID { | 23 | namespace Core::HID { |
| 18 | class EmulatedController; | 24 | class EmulatedController; |
| @@ -32,6 +38,7 @@ union Result; | |||
| 32 | 38 | ||
| 33 | namespace Service::HID { | 39 | namespace Service::HID { |
| 34 | class AppletResource; | 40 | class AppletResource; |
| 41 | struct HandheldConfig; | ||
| 35 | struct NpadInternalState; | 42 | struct NpadInternalState; |
| 36 | struct NpadSixAxisSensorLifo; | 43 | struct NpadSixAxisSensorLifo; |
| 37 | struct NpadSharedMemoryFormat; | 44 | struct 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 | ||
| 164 | private: | 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 | |||
| 156 | private: | ||
| 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 | ||
| 11 | namespace Core::HID { | ||
| 12 | class EmulatedController; | ||
| 13 | } | ||
| 14 | |||
| 11 | namespace Service::HID { | 15 | namespace Service::HID { |
| 12 | static constexpr std::size_t MaxSupportedNpadIdTypes = 10; | 16 | static constexpr std::size_t MaxSupportedNpadIdTypes = 10; |
| 13 | static constexpr std::size_t StyleIndexCount = 7; | 17 | static 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 | ||
| 80 | u64 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 | |||
| 28 | private: | 30 | private: |
| 29 | f32 volume{}; | 31 | f32 volume{}; |
| 30 | u64 session_aruid{}; | 32 | u64 session_aruid{}; |
diff --git a/src/hid_core/resources/vibration/gc_vibration_device.cpp b/src/hid_core/resources/vibration/gc_vibration_device.cpp index f01f81b9a..ad42b9d66 100644 --- a/src/hid_core/resources/vibration/gc_vibration_device.cpp +++ b/src/hid_core/resources/vibration/gc_vibration_device.cpp | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project |
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | 2 | // SPDX-License-Identifier: GPL-3.0-or-later |
| 3 | 3 | ||
| 4 | #include "hid_core/frontend/emulated_controller.h" | ||
| 4 | #include "hid_core/hid_result.h" | 5 | #include "hid_core/hid_result.h" |
| 5 | #include "hid_core/resources/npad/npad_types.h" | 6 | #include "hid_core/resources/npad/npad_types.h" |
| 6 | #include "hid_core/resources/npad/npad_vibration.h" | 7 | #include "hid_core/resources/npad/npad_vibration.h" |
| @@ -10,24 +11,25 @@ namespace Service::HID { | |||
| 10 | 11 | ||
| 11 | NpadGcVibrationDevice::NpadGcVibrationDevice() {} | 12 | NpadGcVibrationDevice::NpadGcVibrationDevice() {} |
| 12 | 13 | ||
| 13 | Result NpadGcVibrationDevice::IncrementRefCounter() { | 14 | Result NpadGcVibrationDevice::Activate() { |
| 14 | if (ref_counter == 0 && is_mounted) { | 15 | if (ref_counter == 0 && is_mounted) { |
| 15 | f32 volume = 1.0f; | 16 | f32 volume = 1.0f; |
| 16 | const auto result = vibration_handler->GetVibrationVolume(volume); | 17 | const auto result = vibration_handler->GetVibrationVolume(volume); |
| 17 | if (result.IsSuccess()) { | 18 | if (result.IsSuccess()) { |
| 18 | // TODO: SendVibrationGcErmCommand | 19 | xcd_handle->SetVibration(adapter_slot, Core::HID::VibrationGcErmCommand::Stop); |
| 19 | } | 20 | } |
| 20 | } | 21 | } |
| 22 | |||
| 21 | ref_counter++; | 23 | ref_counter++; |
| 22 | return ResultSuccess; | 24 | return ResultSuccess; |
| 23 | } | 25 | } |
| 24 | 26 | ||
| 25 | Result NpadGcVibrationDevice::DecrementRefCounter() { | 27 | Result NpadGcVibrationDevice::Deactivate() { |
| 26 | if (ref_counter == 1 && !is_mounted) { | 28 | if (ref_counter == 1 && is_mounted) { |
| 27 | f32 volume = 1.0f; | 29 | f32 volume = 1.0f; |
| 28 | const auto result = vibration_handler->GetVibrationVolume(volume); | 30 | const auto result = vibration_handler->GetVibrationVolume(volume); |
| 29 | if (result.IsSuccess()) { | 31 | if (result.IsSuccess()) { |
| 30 | // TODO: SendVibrationGcErmCommand | 32 | xcd_handle->SetVibration(adapter_slot, Core::HID::VibrationGcErmCommand::Stop); |
| 31 | } | 33 | } |
| 32 | } | 34 | } |
| 33 | 35 | ||
| @@ -38,6 +40,48 @@ Result NpadGcVibrationDevice::DecrementRefCounter() { | |||
| 38 | return ResultSuccess; | 40 | return ResultSuccess; |
| 39 | } | 41 | } |
| 40 | 42 | ||
| 43 | Result NpadGcVibrationDevice::Mount(IAbstractedPad& abstracted_pad, u32 slot, | ||
| 44 | NpadVibration* handler) { | ||
| 45 | if (!abstracted_pad.internal_flags.is_connected) { | ||
| 46 | return ResultSuccess; | ||
| 47 | } | ||
| 48 | |||
| 49 | // TODO: This device doesn't use a xcd handle instead has an GC adapter handle. This is just to | ||
| 50 | // keep compatibility with the front end. | ||
| 51 | xcd_handle = abstracted_pad.xcd_handle; | ||
| 52 | adapter_slot = slot; | ||
| 53 | vibration_handler = handler; | ||
| 54 | is_mounted = true; | ||
| 55 | |||
| 56 | if (ref_counter == 0) { | ||
| 57 | return ResultSuccess; | ||
| 58 | } | ||
| 59 | |||
| 60 | f32 volume{1.0f}; | ||
| 61 | const auto result = vibration_handler->GetVibrationVolume(volume); | ||
| 62 | if (result.IsSuccess()) { | ||
| 63 | xcd_handle->SetVibration(adapter_slot, Core::HID::VibrationGcErmCommand::Stop); | ||
| 64 | } | ||
| 65 | |||
| 66 | return ResultSuccess; | ||
| 67 | } | ||
| 68 | |||
| 69 | Result NpadGcVibrationDevice::Unmount() { | ||
| 70 | if (ref_counter == 0 || !is_mounted) { | ||
| 71 | is_mounted = false; | ||
| 72 | return ResultSuccess; | ||
| 73 | } | ||
| 74 | |||
| 75 | f32 volume{1.0f}; | ||
| 76 | const auto result = vibration_handler->GetVibrationVolume(volume); | ||
| 77 | if (result.IsSuccess()) { | ||
| 78 | xcd_handle->SetVibration(adapter_slot, Core::HID::VibrationGcErmCommand::Stop); | ||
| 79 | } | ||
| 80 | |||
| 81 | is_mounted = false; | ||
| 82 | return ResultSuccess; | ||
| 83 | } | ||
| 84 | |||
| 41 | Result NpadGcVibrationDevice::SendVibrationGcErmCommand(Core::HID::VibrationGcErmCommand command) { | 85 | Result NpadGcVibrationDevice::SendVibrationGcErmCommand(Core::HID::VibrationGcErmCommand command) { |
| 42 | if (!is_mounted) { | 86 | if (!is_mounted) { |
| 43 | return ResultSuccess; | 87 | return ResultSuccess; |
| @@ -55,7 +99,7 @@ Result NpadGcVibrationDevice::SendVibrationGcErmCommand(Core::HID::VibrationGcEr | |||
| 55 | return ResultSuccess; | 99 | return ResultSuccess; |
| 56 | } | 100 | } |
| 57 | } | 101 | } |
| 58 | // TODO: SendVibrationGcErmCommand | 102 | xcd_handle->SetVibration(adapter_slot, command); |
| 59 | return ResultSuccess; | 103 | return ResultSuccess; |
| 60 | } | 104 | } |
| 61 | 105 | ||
diff --git a/src/hid_core/resources/vibration/gc_vibration_device.h b/src/hid_core/resources/vibration/gc_vibration_device.h index 87abca57d..c624cbb28 100644 --- a/src/hid_core/resources/vibration/gc_vibration_device.h +++ b/src/hid_core/resources/vibration/gc_vibration_device.h | |||
| @@ -20,12 +20,18 @@ class NpadGcVibrationDevice final : public NpadVibrationBase { | |||
| 20 | public: | 20 | public: |
| 21 | explicit NpadGcVibrationDevice(); | 21 | explicit NpadGcVibrationDevice(); |
| 22 | 22 | ||
| 23 | Result IncrementRefCounter() override; | 23 | Result Activate() override; |
| 24 | Result DecrementRefCounter() override; | 24 | Result Deactivate() override; |
| 25 | |||
| 26 | Result Mount(IAbstractedPad& abstracted_pad, u32 slot, NpadVibration* handler); | ||
| 27 | Result Unmount(); | ||
| 25 | 28 | ||
| 26 | Result SendVibrationGcErmCommand(Core::HID::VibrationGcErmCommand command); | 29 | Result SendVibrationGcErmCommand(Core::HID::VibrationGcErmCommand command); |
| 27 | 30 | ||
| 28 | Result GetActualVibrationGcErmCommand(Core::HID::VibrationGcErmCommand& out_command); | 31 | Result GetActualVibrationGcErmCommand(Core::HID::VibrationGcErmCommand& out_command); |
| 29 | Result SendVibrationNotificationPattern(Core::HID::VibrationGcErmCommand command); | 32 | Result SendVibrationNotificationPattern(Core::HID::VibrationGcErmCommand command); |
| 33 | |||
| 34 | private: | ||
| 35 | u32 adapter_slot; | ||
| 30 | }; | 36 | }; |
| 31 | } // namespace Service::HID | 37 | } // namespace Service::HID |
diff --git a/src/hid_core/resources/vibration/n64_vibration_device.cpp b/src/hid_core/resources/vibration/n64_vibration_device.cpp index 639f87abf..94ad37c8f 100644 --- a/src/hid_core/resources/vibration/n64_vibration_device.cpp +++ b/src/hid_core/resources/vibration/n64_vibration_device.cpp | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project |
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | 2 | // SPDX-License-Identifier: GPL-3.0-or-later |
| 3 | 3 | ||
| 4 | #include "hid_core/frontend/emulated_controller.h" | ||
| 4 | #include "hid_core/hid_result.h" | 5 | #include "hid_core/hid_result.h" |
| 5 | #include "hid_core/resources/npad/npad_types.h" | 6 | #include "hid_core/resources/npad/npad_types.h" |
| 6 | #include "hid_core/resources/npad/npad_vibration.h" | 7 | #include "hid_core/resources/npad/npad_vibration.h" |
| @@ -10,12 +11,12 @@ namespace Service::HID { | |||
| 10 | 11 | ||
| 11 | NpadN64VibrationDevice::NpadN64VibrationDevice() {} | 12 | NpadN64VibrationDevice::NpadN64VibrationDevice() {} |
| 12 | 13 | ||
| 13 | Result NpadN64VibrationDevice::IncrementRefCounter() { | 14 | Result NpadN64VibrationDevice::Activate() { |
| 14 | if (ref_counter == 0 && is_mounted) { | 15 | if (ref_counter == 0 && is_mounted) { |
| 15 | f32 volume = 1.0f; | 16 | f32 volume = 1.0f; |
| 16 | const auto result = vibration_handler->GetVibrationVolume(volume); | 17 | const auto result = vibration_handler->GetVibrationVolume(volume); |
| 17 | if (result.IsSuccess()) { | 18 | if (result.IsSuccess()) { |
| 18 | // TODO: SendVibrationInBool | 19 | xcd_handle->SetVibration(false); |
| 19 | } | 20 | } |
| 20 | } | 21 | } |
| 21 | 22 | ||
| @@ -23,19 +24,12 @@ Result NpadN64VibrationDevice::IncrementRefCounter() { | |||
| 23 | return ResultSuccess; | 24 | return ResultSuccess; |
| 24 | } | 25 | } |
| 25 | 26 | ||
| 26 | Result NpadN64VibrationDevice::DecrementRefCounter() { | 27 | Result NpadN64VibrationDevice::Deactivate() { |
| 27 | if (ref_counter == 1) { | 28 | if (ref_counter == 1 && is_mounted) { |
| 28 | if (!is_mounted) { | ||
| 29 | ref_counter = 0; | ||
| 30 | if (is_mounted != false) { | ||
| 31 | // TODO: SendVibrationInBool | ||
| 32 | } | ||
| 33 | return ResultSuccess; | ||
| 34 | } | ||
| 35 | f32 volume = 1.0f; | 29 | f32 volume = 1.0f; |
| 36 | const auto result = vibration_handler->GetVibrationVolume(volume); | 30 | const auto result = vibration_handler->GetVibrationVolume(volume); |
| 37 | if (result.IsSuccess()) { | 31 | if (result.IsSuccess()) { |
| 38 | // TODO | 32 | xcd_handle->SetVibration(false); |
| 39 | } | 33 | } |
| 40 | } | 34 | } |
| 41 | 35 | ||
| @@ -46,6 +40,43 @@ Result NpadN64VibrationDevice::DecrementRefCounter() { | |||
| 46 | return ResultSuccess; | 40 | return ResultSuccess; |
| 47 | } | 41 | } |
| 48 | 42 | ||
| 43 | Result NpadN64VibrationDevice::Mount(IAbstractedPad& abstracted_pad, NpadVibration* handler) { | ||
| 44 | if (!abstracted_pad.internal_flags.is_connected) { | ||
| 45 | return ResultSuccess; | ||
| 46 | } | ||
| 47 | xcd_handle = abstracted_pad.xcd_handle; | ||
| 48 | vibration_handler = handler; | ||
| 49 | is_mounted = true; | ||
| 50 | |||
| 51 | if (ref_counter == 0) { | ||
| 52 | return ResultSuccess; | ||
| 53 | } | ||
| 54 | |||
| 55 | f32 volume{1.0f}; | ||
| 56 | const auto result = vibration_handler->GetVibrationVolume(volume); | ||
| 57 | if (result.IsSuccess()) { | ||
| 58 | xcd_handle->SetVibration(false); | ||
| 59 | } | ||
| 60 | |||
| 61 | return ResultSuccess; | ||
| 62 | } | ||
| 63 | |||
| 64 | Result NpadN64VibrationDevice::Unmount() { | ||
| 65 | if (ref_counter == 0 || !is_mounted) { | ||
| 66 | is_mounted = false; | ||
| 67 | return ResultSuccess; | ||
| 68 | } | ||
| 69 | |||
| 70 | f32 volume{1.0f}; | ||
| 71 | const auto result = vibration_handler->GetVibrationVolume(volume); | ||
| 72 | if (result.IsSuccess()) { | ||
| 73 | xcd_handle->SetVibration(false); | ||
| 74 | } | ||
| 75 | |||
| 76 | is_mounted = false; | ||
| 77 | return ResultSuccess; | ||
| 78 | } | ||
| 79 | |||
| 49 | Result NpadN64VibrationDevice::SendValueInBool(bool is_vibrating) { | 80 | Result NpadN64VibrationDevice::SendValueInBool(bool is_vibrating) { |
| 50 | if (ref_counter < 1) { | 81 | if (ref_counter < 1) { |
| 51 | return ResultVibrationNotInitialized; | 82 | return ResultVibrationNotInitialized; |
| @@ -56,7 +87,7 @@ Result NpadN64VibrationDevice::SendValueInBool(bool is_vibrating) { | |||
| 56 | if (result.IsError()) { | 87 | if (result.IsError()) { |
| 57 | return result; | 88 | return result; |
| 58 | } | 89 | } |
| 59 | // TODO: SendVibrationInBool | 90 | xcd_handle->SetVibration(false); |
| 60 | } | 91 | } |
| 61 | return ResultSuccess; | 92 | return ResultSuccess; |
| 62 | } | 93 | } |
diff --git a/src/hid_core/resources/vibration/n64_vibration_device.h b/src/hid_core/resources/vibration/n64_vibration_device.h index 54e6efc1a..09de7701c 100644 --- a/src/hid_core/resources/vibration/n64_vibration_device.h +++ b/src/hid_core/resources/vibration/n64_vibration_device.h | |||
| @@ -14,14 +14,18 @@ | |||
| 14 | 14 | ||
| 15 | namespace Service::HID { | 15 | namespace Service::HID { |
| 16 | class NpadVibration; | 16 | class NpadVibration; |
| 17 | struct IAbstractedPad; | ||
| 17 | 18 | ||
| 18 | /// Handles Npad request from HID interfaces | 19 | /// Handles Npad request from HID interfaces |
| 19 | class NpadN64VibrationDevice final : public NpadVibrationBase { | 20 | class NpadN64VibrationDevice final : public NpadVibrationBase { |
| 20 | public: | 21 | public: |
| 21 | explicit NpadN64VibrationDevice(); | 22 | explicit NpadN64VibrationDevice(); |
| 22 | 23 | ||
| 23 | Result IncrementRefCounter() override; | 24 | Result Activate() override; |
| 24 | Result DecrementRefCounter() override; | 25 | Result Deactivate() override; |
| 26 | |||
| 27 | Result Mount(IAbstractedPad& abstracted_pad, NpadVibration* handler); | ||
| 28 | Result Unmount(); | ||
| 25 | 29 | ||
| 26 | Result SendValueInBool(bool is_vibrating); | 30 | Result SendValueInBool(bool is_vibrating); |
| 27 | Result SendVibrationNotificationPattern(u32 pattern); | 31 | Result SendVibrationNotificationPattern(u32 pattern); |
diff --git a/src/hid_core/resources/vibration/vibration_base.cpp b/src/hid_core/resources/vibration/vibration_base.cpp index 350f349c2..f28d30406 100644 --- a/src/hid_core/resources/vibration/vibration_base.cpp +++ b/src/hid_core/resources/vibration/vibration_base.cpp | |||
| @@ -10,12 +10,12 @@ namespace Service::HID { | |||
| 10 | 10 | ||
| 11 | NpadVibrationBase::NpadVibrationBase() {} | 11 | NpadVibrationBase::NpadVibrationBase() {} |
| 12 | 12 | ||
| 13 | Result NpadVibrationBase::IncrementRefCounter() { | 13 | Result NpadVibrationBase::Activate() { |
| 14 | ref_counter++; | 14 | ref_counter++; |
| 15 | return ResultSuccess; | 15 | return ResultSuccess; |
| 16 | } | 16 | } |
| 17 | 17 | ||
| 18 | Result NpadVibrationBase::DecrementRefCounter() { | 18 | Result NpadVibrationBase::Deactivate() { |
| 19 | if (ref_counter > 0) { | 19 | if (ref_counter > 0) { |
| 20 | ref_counter--; | 20 | ref_counter--; |
| 21 | } | 21 | } |
diff --git a/src/hid_core/resources/vibration/vibration_base.h b/src/hid_core/resources/vibration/vibration_base.h index c6c5fc4d9..69c26e669 100644 --- a/src/hid_core/resources/vibration/vibration_base.h +++ b/src/hid_core/resources/vibration/vibration_base.h | |||
| @@ -6,6 +6,10 @@ | |||
| 6 | #include "common/common_types.h" | 6 | #include "common/common_types.h" |
| 7 | #include "core/hle/result.h" | 7 | #include "core/hle/result.h" |
| 8 | 8 | ||
| 9 | namespace Core::HID { | ||
| 10 | class EmulatedController; | ||
| 11 | } | ||
| 12 | |||
| 9 | namespace Service::HID { | 13 | namespace Service::HID { |
| 10 | class NpadVibration; | 14 | class NpadVibration; |
| 11 | 15 | ||
| @@ -14,13 +18,13 @@ class NpadVibrationBase { | |||
| 14 | public: | 18 | public: |
| 15 | explicit NpadVibrationBase(); | 19 | explicit NpadVibrationBase(); |
| 16 | 20 | ||
| 17 | virtual Result IncrementRefCounter(); | 21 | virtual Result Activate(); |
| 18 | virtual Result DecrementRefCounter(); | 22 | virtual Result Deactivate(); |
| 19 | 23 | ||
| 20 | bool IsVibrationMounted() const; | 24 | bool IsVibrationMounted() const; |
| 21 | 25 | ||
| 22 | protected: | 26 | protected: |
| 23 | u64 xcd_handle{}; | 27 | Core::HID::EmulatedController* xcd_handle{nullptr}; |
| 24 | s32 ref_counter{}; | 28 | s32 ref_counter{}; |
| 25 | bool is_mounted{}; | 29 | bool is_mounted{}; |
| 26 | NpadVibration* vibration_handler{nullptr}; | 30 | NpadVibration* vibration_handler{nullptr}; |
diff --git a/src/hid_core/resources/vibration/vibration_device.cpp b/src/hid_core/resources/vibration/vibration_device.cpp index 888c3a7ed..08b14591f 100644 --- a/src/hid_core/resources/vibration/vibration_device.cpp +++ b/src/hid_core/resources/vibration/vibration_device.cpp | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project |
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | 2 | // SPDX-License-Identifier: GPL-3.0-or-later |
| 3 | 3 | ||
| 4 | #include "hid_core/frontend/emulated_controller.h" | ||
| 4 | #include "hid_core/hid_result.h" | 5 | #include "hid_core/hid_result.h" |
| 5 | #include "hid_core/resources/npad/npad_types.h" | 6 | #include "hid_core/resources/npad/npad_types.h" |
| 6 | #include "hid_core/resources/npad/npad_vibration.h" | 7 | #include "hid_core/resources/npad/npad_vibration.h" |
| @@ -10,12 +11,30 @@ namespace Service::HID { | |||
| 10 | 11 | ||
| 11 | NpadVibrationDevice::NpadVibrationDevice() {} | 12 | NpadVibrationDevice::NpadVibrationDevice() {} |
| 12 | 13 | ||
| 13 | Result NpadVibrationDevice::IncrementRefCounter() { | 14 | Result NpadVibrationDevice::Activate() { |
| 15 | if (ref_counter == 0 && is_mounted) { | ||
| 16 | f32 volume = 1.0f; | ||
| 17 | const auto result = vibration_handler->GetVibrationVolume(volume); | ||
| 18 | if (result.IsSuccess()) { | ||
| 19 | xcd_handle->SetVibration(device_index, Core::HID::DEFAULT_VIBRATION_VALUE); | ||
| 20 | // TODO: SendNotificationPattern; | ||
| 21 | } | ||
| 22 | } | ||
| 23 | |||
| 14 | ref_counter++; | 24 | ref_counter++; |
| 15 | return ResultSuccess; | 25 | return ResultSuccess; |
| 16 | } | 26 | } |
| 17 | 27 | ||
| 18 | Result NpadVibrationDevice::DecrementRefCounter() { | 28 | Result NpadVibrationDevice::Deactivate() { |
| 29 | if (ref_counter == 1 && is_mounted) { | ||
| 30 | f32 volume = 1.0f; | ||
| 31 | const auto result = vibration_handler->GetVibrationVolume(volume); | ||
| 32 | if (result.IsSuccess()) { | ||
| 33 | xcd_handle->SetVibration(device_index, Core::HID::DEFAULT_VIBRATION_VALUE); | ||
| 34 | // TODO: SendNotificationPattern; | ||
| 35 | } | ||
| 36 | } | ||
| 37 | |||
| 19 | if (ref_counter > 0) { | 38 | if (ref_counter > 0) { |
| 20 | ref_counter--; | 39 | ref_counter--; |
| 21 | } | 40 | } |
| @@ -23,6 +42,45 @@ Result NpadVibrationDevice::DecrementRefCounter() { | |||
| 23 | return ResultSuccess; | 42 | return ResultSuccess; |
| 24 | } | 43 | } |
| 25 | 44 | ||
| 45 | Result NpadVibrationDevice::Mount(IAbstractedPad& abstracted_pad, Core::HID::DeviceIndex index, | ||
| 46 | NpadVibration* handler) { | ||
| 47 | if (!abstracted_pad.internal_flags.is_connected) { | ||
| 48 | return ResultSuccess; | ||
| 49 | } | ||
| 50 | xcd_handle = abstracted_pad.xcd_handle; | ||
| 51 | device_index = index; | ||
| 52 | vibration_handler = handler; | ||
| 53 | is_mounted = true; | ||
| 54 | |||
| 55 | if (ref_counter == 0) { | ||
| 56 | return ResultSuccess; | ||
| 57 | } | ||
| 58 | |||
| 59 | f32 volume{1.0f}; | ||
| 60 | const auto result = vibration_handler->GetVibrationVolume(volume); | ||
| 61 | if (result.IsSuccess()) { | ||
| 62 | xcd_handle->SetVibration(false); | ||
| 63 | } | ||
| 64 | |||
| 65 | return ResultSuccess; | ||
| 66 | } | ||
| 67 | |||
| 68 | Result NpadVibrationDevice::Unmount() { | ||
| 69 | if (ref_counter == 0 || !is_mounted) { | ||
| 70 | is_mounted = false; | ||
| 71 | return ResultSuccess; | ||
| 72 | } | ||
| 73 | |||
| 74 | f32 volume{1.0f}; | ||
| 75 | const auto result = vibration_handler->GetVibrationVolume(volume); | ||
| 76 | if (result.IsSuccess()) { | ||
| 77 | xcd_handle->SetVibration(device_index, Core::HID::DEFAULT_VIBRATION_VALUE); | ||
| 78 | } | ||
| 79 | |||
| 80 | is_mounted = false; | ||
| 81 | return ResultSuccess; | ||
| 82 | } | ||
| 83 | |||
| 26 | Result NpadVibrationDevice::SendVibrationValue(const Core::HID::VibrationValue& value) { | 84 | Result NpadVibrationDevice::SendVibrationValue(const Core::HID::VibrationValue& value) { |
| 27 | if (ref_counter == 0) { | 85 | if (ref_counter == 0) { |
| 28 | return ResultVibrationNotInitialized; | 86 | return ResultVibrationNotInitialized; |
| @@ -37,7 +95,7 @@ Result NpadVibrationDevice::SendVibrationValue(const Core::HID::VibrationValue& | |||
| 37 | return result; | 95 | return result; |
| 38 | } | 96 | } |
| 39 | if (volume <= 0.0f) { | 97 | if (volume <= 0.0f) { |
| 40 | // TODO: SendVibrationValue | 98 | xcd_handle->SetVibration(device_index, Core::HID::DEFAULT_VIBRATION_VALUE); |
| 41 | return ResultSuccess; | 99 | return ResultSuccess; |
| 42 | } | 100 | } |
| 43 | 101 | ||
| @@ -45,7 +103,7 @@ Result NpadVibrationDevice::SendVibrationValue(const Core::HID::VibrationValue& | |||
| 45 | vibration_value.high_amplitude *= volume; | 103 | vibration_value.high_amplitude *= volume; |
| 46 | vibration_value.low_amplitude *= volume; | 104 | vibration_value.low_amplitude *= volume; |
| 47 | 105 | ||
| 48 | // TODO: SendVibrationValue | 106 | xcd_handle->SetVibration(device_index, vibration_value); |
| 49 | return ResultSuccess; | 107 | return ResultSuccess; |
| 50 | } | 108 | } |
| 51 | 109 | ||
| @@ -63,11 +121,11 @@ Result NpadVibrationDevice::SendVibrationNotificationPattern([[maybe_unused]] u3 | |||
| 63 | pattern = 0; | 121 | pattern = 0; |
| 64 | } | 122 | } |
| 65 | 123 | ||
| 66 | // return xcd_handle->SendVibrationNotificationPattern(pattern); | 124 | // TODO: SendVibrationNotificationPattern; |
| 67 | return ResultSuccess; | 125 | return ResultSuccess; |
| 68 | } | 126 | } |
| 69 | 127 | ||
| 70 | Result NpadVibrationDevice::GetActualVibrationValue(Core::HID::VibrationValue& out_value) { | 128 | Result NpadVibrationDevice::GetActualVibrationValue(Core::HID::VibrationValue& out_value) const { |
| 71 | if (ref_counter < 1) { | 129 | if (ref_counter < 1) { |
| 72 | return ResultVibrationNotInitialized; | 130 | return ResultVibrationNotInitialized; |
| 73 | } | 131 | } |
| @@ -77,7 +135,7 @@ Result NpadVibrationDevice::GetActualVibrationValue(Core::HID::VibrationValue& o | |||
| 77 | return ResultSuccess; | 135 | return ResultSuccess; |
| 78 | } | 136 | } |
| 79 | 137 | ||
| 80 | // TODO: SendVibrationValue | 138 | out_value = xcd_handle->GetActualVibrationValue(device_index); |
| 81 | return ResultSuccess; | 139 | return ResultSuccess; |
| 82 | } | 140 | } |
| 83 | 141 | ||
diff --git a/src/hid_core/resources/vibration/vibration_device.h b/src/hid_core/resources/vibration/vibration_device.h index 3574ad60b..c2f9891d3 100644 --- a/src/hid_core/resources/vibration/vibration_device.h +++ b/src/hid_core/resources/vibration/vibration_device.h | |||
| @@ -12,6 +12,10 @@ | |||
| 12 | #include "hid_core/resources/npad/npad_types.h" | 12 | #include "hid_core/resources/npad/npad_types.h" |
| 13 | #include "hid_core/resources/vibration/vibration_base.h" | 13 | #include "hid_core/resources/vibration/vibration_base.h" |
| 14 | 14 | ||
| 15 | namespace Core::HID { | ||
| 16 | enum class DeviceIndex : u8; | ||
| 17 | } | ||
| 18 | |||
| 15 | namespace Service::HID { | 19 | namespace Service::HID { |
| 16 | class NpadVibration; | 20 | class NpadVibration; |
| 17 | 21 | ||
| @@ -20,16 +24,20 @@ class NpadVibrationDevice final : public NpadVibrationBase { | |||
| 20 | public: | 24 | public: |
| 21 | explicit NpadVibrationDevice(); | 25 | explicit NpadVibrationDevice(); |
| 22 | 26 | ||
| 23 | Result IncrementRefCounter(); | 27 | Result Activate(); |
| 24 | Result DecrementRefCounter(); | 28 | Result Deactivate(); |
| 29 | |||
| 30 | Result Mount(IAbstractedPad& abstracted_pad, Core::HID::DeviceIndex index, | ||
| 31 | NpadVibration* handler); | ||
| 32 | Result Unmount(); | ||
| 25 | 33 | ||
| 26 | Result SendVibrationValue(const Core::HID::VibrationValue& value); | 34 | Result SendVibrationValue(const Core::HID::VibrationValue& value); |
| 27 | Result SendVibrationNotificationPattern(u32 pattern); | 35 | Result SendVibrationNotificationPattern(u32 pattern); |
| 28 | 36 | ||
| 29 | Result GetActualVibrationValue(Core::HID::VibrationValue& out_value); | 37 | Result GetActualVibrationValue(Core::HID::VibrationValue& out_value) const; |
| 30 | 38 | ||
| 31 | private: | 39 | private: |
| 32 | u32 device_index{}; | 40 | Core::HID::DeviceIndex device_index{}; |
| 33 | }; | 41 | }; |
| 34 | 42 | ||
| 35 | } // namespace Service::HID | 43 | } // namespace Service::HID |