diff options
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 | } |