diff options
| author | 2020-10-20 13:55:25 -0400 | |
|---|---|---|
| committer | 2020-11-15 23:33:20 -0500 | |
| commit | e9e1876e821b8bd1bb5c8254ec93e2cc479e16dd (patch) | |
| tree | 344b40a5a874cb188c6e7aa7d1622c77a215090d /src/core | |
| parent | configure_input: Add per-player vibration (diff) | |
| download | yuzu-e9e1876e821b8bd1bb5c8254ec93e2cc479e16dd.tar.gz yuzu-e9e1876e821b8bd1bb5c8254ec93e2cc479e16dd.tar.xz yuzu-e9e1876e821b8bd1bb5c8254ec93e2cc479e16dd.zip | |
input_common: Add VibrationDevice and VibrationDeviceFactory
A vibration device is an input device that returns an unsigned byte as status.
It represents whether the vibration device supports vibration or not.
If the status returns 1, it supports vibration. Otherwise, it does not support vibration.
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/frontend/input.h | 7 | ||||
| -rw-r--r-- | src/core/hle/service/hid/controllers/npad.cpp | 48 | ||||
| -rw-r--r-- | src/core/hle/service/hid/controllers/npad.h | 11 | ||||
| -rw-r--r-- | src/core/hle/service/hid/hid.cpp | 1 |
4 files changed, 34 insertions, 33 deletions
diff --git a/src/core/frontend/input.h b/src/core/frontend/input.h index fb2ce2514..25ac5af46 100644 --- a/src/core/frontend/input.h +++ b/src/core/frontend/input.h | |||
| @@ -122,6 +122,13 @@ using ButtonDevice = InputDevice<bool>; | |||
| 122 | using AnalogDevice = InputDevice<std::tuple<float, float>>; | 122 | using AnalogDevice = InputDevice<std::tuple<float, float>>; |
| 123 | 123 | ||
| 124 | /** | 124 | /** |
| 125 | * A vibration device is an input device that returns an unsigned byte as status. | ||
| 126 | * It represents whether the vibration device supports vibration or not. | ||
| 127 | * If the status returns 1, it supports vibration. Otherwise, it does not support vibration. | ||
| 128 | */ | ||
| 129 | using VibrationDevice = InputDevice<u8>; | ||
| 130 | |||
| 131 | /** | ||
| 125 | * A motion status is an object that returns a tuple of accelerometer state vector, | 132 | * A motion status is an object that returns a tuple of accelerometer state vector, |
| 126 | * gyroscope state vector, rotation state vector and orientation state matrix. | 133 | * gyroscope state vector, rotation state vector and orientation state matrix. |
| 127 | * | 134 | * |
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index dc9954377..27099de24 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp | |||
| @@ -271,6 +271,10 @@ void Controller_NPad::OnLoadInputDevices() { | |||
| 271 | std::transform(players[i].analogs.begin() + Settings::NativeAnalog::STICK_HID_BEGIN, | 271 | std::transform(players[i].analogs.begin() + Settings::NativeAnalog::STICK_HID_BEGIN, |
| 272 | players[i].analogs.begin() + Settings::NativeAnalog::STICK_HID_END, | 272 | players[i].analogs.begin() + Settings::NativeAnalog::STICK_HID_END, |
| 273 | sticks[i].begin(), Input::CreateDevice<Input::AnalogDevice>); | 273 | sticks[i].begin(), Input::CreateDevice<Input::AnalogDevice>); |
| 274 | std::transform(players[i].vibrations.begin() + | ||
| 275 | Settings::NativeVibration::VIBRATION_HID_BEGIN, | ||
| 276 | players[i].vibrations.begin() + Settings::NativeVibration::VIBRATION_HID_END, | ||
| 277 | vibrations[i].begin(), Input::CreateDevice<Input::VibrationDevice>); | ||
| 274 | std::transform(players[i].motions.begin() + Settings::NativeMotion::MOTION_HID_BEGIN, | 278 | std::transform(players[i].motions.begin() + Settings::NativeMotion::MOTION_HID_BEGIN, |
| 275 | players[i].motions.begin() + Settings::NativeMotion::MOTION_HID_END, | 279 | players[i].motions.begin() + Settings::NativeMotion::MOTION_HID_END, |
| 276 | motions[i].begin(), Input::CreateDevice<Input::MotionDevice>); | 280 | motions[i].begin(), Input::CreateDevice<Input::MotionDevice>); |
| @@ -278,8 +282,10 @@ void Controller_NPad::OnLoadInputDevices() { | |||
| 278 | } | 282 | } |
| 279 | 283 | ||
| 280 | void Controller_NPad::OnRelease() { | 284 | void Controller_NPad::OnRelease() { |
| 281 | for (std::size_t index = 0; index < connected_controllers.size(); ++index) { | 285 | for (std::size_t npad_idx = 0; npad_idx < vibrations.size(); ++npad_idx) { |
| 282 | VibrateControllerAtIndex(index, {}); | 286 | for (std::size_t device_idx = 0; device_idx < vibrations[npad_idx].size(); ++device_idx) { |
| 287 | VibrateControllerAtIndex(npad_idx, device_idx); | ||
| 288 | } | ||
| 283 | } | 289 | } |
| 284 | } | 290 | } |
| 285 | 291 | ||
| @@ -674,9 +680,9 @@ void Controller_NPad::SetNpadMode(u32 npad_id, NpadAssignments assignment_mode) | |||
| 674 | } | 680 | } |
| 675 | } | 681 | } |
| 676 | 682 | ||
| 677 | bool Controller_NPad::VibrateControllerAtIndex(std::size_t npad_index, | 683 | bool Controller_NPad::VibrateControllerAtIndex(std::size_t npad_index, std::size_t device_index, |
| 678 | const VibrationValue& vibration_value) { | 684 | const VibrationValue& vibration_value) { |
| 679 | if (!connected_controllers[npad_index].is_connected) { | 685 | if (!connected_controllers[npad_index].is_connected || !vibrations[npad_index][device_index]) { |
| 680 | return false; | 686 | return false; |
| 681 | } | 687 | } |
| 682 | 688 | ||
| @@ -686,10 +692,7 @@ bool Controller_NPad::VibrateControllerAtIndex(std::size_t npad_index, | |||
| 686 | return false; | 692 | return false; |
| 687 | } | 693 | } |
| 688 | 694 | ||
| 689 | using namespace Settings::NativeButton; | 695 | return vibrations[npad_index][device_index]->SetRumblePlay( |
| 690 | const auto& button_state = buttons[npad_index]; | ||
| 691 | |||
| 692 | return button_state[A - BUTTON_HID_BEGIN]->SetRumblePlay( | ||
| 693 | std::min(vibration_value.amp_low * player.vibration_strength / 100.0f, 1.0f), | 696 | std::min(vibration_value.amp_low * player.vibration_strength / 100.0f, 1.0f), |
| 694 | vibration_value.freq_low, | 697 | vibration_value.freq_low, |
| 695 | std::min(vibration_value.amp_high * player.vibration_strength / 100.0f, 1.0f), | 698 | std::min(vibration_value.amp_high * player.vibration_strength / 100.0f, 1.0f), |
| @@ -717,6 +720,11 @@ void Controller_NPad::VibrateControllers(const std::vector<DeviceHandle>& vibrat | |||
| 717 | continue; | 720 | continue; |
| 718 | } | 721 | } |
| 719 | 722 | ||
| 723 | if (vibration_device_handles[i].device_index == DeviceIndex::None) { | ||
| 724 | UNREACHABLE_MSG("DeviceIndex should never be None!"); | ||
| 725 | continue; | ||
| 726 | } | ||
| 727 | |||
| 720 | // Some games try to send mismatched parameters in the device handle, block these. | 728 | // Some games try to send mismatched parameters in the device handle, block these. |
| 721 | if ((connected_controllers[npad_index].type == NPadControllerType::JoyLeft && | 729 | if ((connected_controllers[npad_index].type == NPadControllerType::JoyLeft && |
| 722 | (vibration_device_handles[i].npad_type == NpadType::JoyconRight || | 730 | (vibration_device_handles[i].npad_type == NpadType::JoyconRight || |
| @@ -747,28 +755,8 @@ void Controller_NPad::VibrateControllers(const std::vector<DeviceHandle>& vibrat | |||
| 747 | continue; | 755 | continue; |
| 748 | } | 756 | } |
| 749 | 757 | ||
| 750 | // TODO: Vibrate left/right vibration motors independently if possible. | 758 | if (VibrateControllerAtIndex(npad_index, device_index, vibration_values[i])) { |
| 751 | if (VibrateControllerAtIndex(npad_index, vibration_values[i])) { | 759 | latest_vibration_values[npad_index][device_index] = vibration_values[i]; |
| 752 | switch (connected_controllers[npad_index].type) { | ||
| 753 | case NPadControllerType::None: | ||
| 754 | UNREACHABLE(); | ||
| 755 | break; | ||
| 756 | case NPadControllerType::ProController: | ||
| 757 | case NPadControllerType::Handheld: | ||
| 758 | case NPadControllerType::JoyDual: | ||
| 759 | // Since we can't vibrate motors independently yet, we can reduce state changes by | ||
| 760 | // assigning all 3 device indices the current vibration value. | ||
| 761 | latest_vibration_values[npad_index][0] = vibration_values[i]; | ||
| 762 | latest_vibration_values[npad_index][1] = vibration_values[i]; | ||
| 763 | latest_vibration_values[npad_index][2] = vibration_values[i]; | ||
| 764 | break; | ||
| 765 | case NPadControllerType::JoyLeft: | ||
| 766 | case NPadControllerType::JoyRight: | ||
| 767 | case NPadControllerType::Pokeball: | ||
| 768 | default: | ||
| 769 | latest_vibration_values[npad_index][device_index] = vibration_values[i]; | ||
| 770 | break; | ||
| 771 | } | ||
| 772 | } | 760 | } |
| 773 | } | 761 | } |
| 774 | } | 762 | } |
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index 576ef1558..3ae9fb8e6 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h | |||
| @@ -148,7 +148,8 @@ public: | |||
| 148 | 148 | ||
| 149 | void SetNpadMode(u32 npad_id, NpadAssignments assignment_mode); | 149 | void SetNpadMode(u32 npad_id, NpadAssignments assignment_mode); |
| 150 | 150 | ||
| 151 | bool VibrateControllerAtIndex(std::size_t npad_index, const VibrationValue& vibration_value); | 151 | bool VibrateControllerAtIndex(std::size_t npad_index, std::size_t device_index, |
| 152 | const VibrationValue& vibration_value = {}); | ||
| 152 | 153 | ||
| 153 | void VibrateControllers(const std::vector<DeviceHandle>& vibration_device_handles, | 154 | void VibrateControllers(const std::vector<DeviceHandle>& vibration_device_handles, |
| 154 | const std::vector<VibrationValue>& vibration_values); | 155 | const std::vector<VibrationValue>& vibration_values); |
| @@ -399,18 +400,22 @@ private: | |||
| 399 | using StickArray = std::array< | 400 | using StickArray = std::array< |
| 400 | std::array<std::unique_ptr<Input::AnalogDevice>, Settings::NativeAnalog::NUM_STICKS_HID>, | 401 | std::array<std::unique_ptr<Input::AnalogDevice>, Settings::NativeAnalog::NUM_STICKS_HID>, |
| 401 | 10>; | 402 | 10>; |
| 403 | using VibrationArray = std::array<std::array<std::unique_ptr<Input::VibrationDevice>, | ||
| 404 | Settings::NativeVibration::NUM_VIBRATIONS_HID>, | ||
| 405 | 10>; | ||
| 402 | using MotionArray = std::array< | 406 | using MotionArray = std::array< |
| 403 | std::array<std::unique_ptr<Input::MotionDevice>, Settings::NativeMotion::NUM_MOTION_HID>, | 407 | std::array<std::unique_ptr<Input::MotionDevice>, Settings::NativeMotion::NUM_MOTIONS_HID>, |
| 404 | 10>; | 408 | 10>; |
| 405 | ButtonArray buttons; | 409 | ButtonArray buttons; |
| 406 | StickArray sticks; | 410 | StickArray sticks; |
| 411 | VibrationArray vibrations; | ||
| 407 | MotionArray motions; | 412 | MotionArray motions; |
| 408 | std::vector<u32> supported_npad_id_types{}; | 413 | std::vector<u32> supported_npad_id_types{}; |
| 409 | NpadHoldType hold_type{NpadHoldType::Vertical}; | 414 | NpadHoldType hold_type{NpadHoldType::Vertical}; |
| 410 | NpadHandheldActivationMode handheld_activation_mode{NpadHandheldActivationMode::Dual}; | 415 | NpadHandheldActivationMode handheld_activation_mode{NpadHandheldActivationMode::Dual}; |
| 411 | // Each controller should have their own styleset changed event | 416 | // Each controller should have their own styleset changed event |
| 412 | std::array<Kernel::EventPair, 10> styleset_changed_events; | 417 | std::array<Kernel::EventPair, 10> styleset_changed_events; |
| 413 | std::array<std::array<VibrationValue, 3>, 10> latest_vibration_values; | 418 | std::array<std::array<VibrationValue, 2>, 10> latest_vibration_values{}; |
| 414 | std::array<ControllerHolder, 10> connected_controllers{}; | 419 | std::array<ControllerHolder, 10> connected_controllers{}; |
| 415 | std::array<bool, 10> unintended_home_button_input_protection{}; | 420 | std::array<bool, 10> unintended_home_button_input_protection{}; |
| 416 | GyroscopeZeroDriftMode gyroscope_zero_drift_mode{GyroscopeZeroDriftMode::Standard}; | 421 | GyroscopeZeroDriftMode gyroscope_zero_drift_mode{GyroscopeZeroDriftMode::Standard}; |
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index e88f30d6a..1d882a977 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp | |||
| @@ -998,6 +998,7 @@ void Hid::GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx) { | |||
| 998 | break; | 998 | break; |
| 999 | case Controller_NPad::DeviceIndex::None: | 999 | case Controller_NPad::DeviceIndex::None: |
| 1000 | default: | 1000 | default: |
| 1001 | UNREACHABLE_MSG("DeviceIndex should never be None!"); | ||
| 1001 | vibration_device_info.position = VibrationDevicePosition::None; | 1002 | vibration_device_info.position = VibrationDevicePosition::None; |
| 1002 | break; | 1003 | break; |
| 1003 | } | 1004 | } |