diff options
| author | 2020-10-25 07:30:23 -0400 | |
|---|---|---|
| committer | 2020-11-15 23:33:21 -0500 | |
| commit | 30e0d1c973290f4813b040eecf83ff4a2c7432c3 (patch) | |
| tree | 2834cf3cc9970e14608a8af0739ffcac56881332 /src/core | |
| parent | input: Disconnect a controller prior to connecting a new one (diff) | |
| download | yuzu-30e0d1c973290f4813b040eecf83ff4a2c7432c3.tar.gz yuzu-30e0d1c973290f4813b040eecf83ff4a2c7432c3.tar.xz yuzu-30e0d1c973290f4813b040eecf83ff4a2c7432c3.zip | |
controllers/npad: Remove the old vibration filter
Previously we used a vibration filter that filters out amplitudes close to each other. It turns out there are cases where this results into vibrations that are too inaccurate. Remove this and move the 100Hz vibration filter (Only allowing a maximum of 100 vibrations per second) from sdl_impl to npad when enable_accurate_vibrations is set to false.
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/hle/service/hid/controllers/npad.cpp | 108 | ||||
| -rw-r--r-- | src/core/hle/service/hid/controllers/npad.h | 4 | ||||
| -rw-r--r-- | src/core/hle/service/hid/hid.cpp | 2 |
3 files changed, 64 insertions, 50 deletions
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index ecc33bc08..cfafabbd8 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp | |||
| @@ -703,6 +703,23 @@ bool Controller_NPad::VibrateControllerAtIndex(std::size_t npad_index, std::size | |||
| 703 | return false; | 703 | return false; |
| 704 | } | 704 | } |
| 705 | 705 | ||
| 706 | if (!Settings::values.enable_accurate_vibrations.GetValue()) { | ||
| 707 | using std::chrono::duration_cast; | ||
| 708 | using std::chrono::milliseconds; | ||
| 709 | using std::chrono::steady_clock; | ||
| 710 | |||
| 711 | const auto now = steady_clock::now(); | ||
| 712 | |||
| 713 | // Filter out non-zero vibrations that are within 10ms of each other. | ||
| 714 | if ((vibration_value.amp_low != 0.0f || vibration_value.amp_high != 0.0f) && | ||
| 715 | duration_cast<milliseconds>(now - last_vibration_timepoints[npad_index][device_index]) < | ||
| 716 | milliseconds(10)) { | ||
| 717 | return false; | ||
| 718 | } | ||
| 719 | |||
| 720 | last_vibration_timepoints[npad_index][device_index] = now; | ||
| 721 | } | ||
| 722 | |||
| 706 | return vibrations[npad_index][device_index]->SetRumblePlay( | 723 | return vibrations[npad_index][device_index]->SetRumblePlay( |
| 707 | std::min(vibration_value.amp_low * player.vibration_strength / 100.0f, 1.0f), | 724 | std::min(vibration_value.amp_low * player.vibration_strength / 100.0f, 1.0f), |
| 708 | vibration_value.freq_low, | 725 | vibration_value.freq_low, |
| @@ -710,66 +727,59 @@ bool Controller_NPad::VibrateControllerAtIndex(std::size_t npad_index, std::size | |||
| 710 | vibration_value.freq_high); | 727 | vibration_value.freq_high); |
| 711 | } | 728 | } |
| 712 | 729 | ||
| 713 | void Controller_NPad::VibrateControllers(const std::vector<DeviceHandle>& vibration_device_handles, | 730 | void Controller_NPad::VibrateController(const DeviceHandle& vibration_device_handle, |
| 714 | const std::vector<VibrationValue>& vibration_values) { | 731 | const VibrationValue& vibration_value) { |
| 715 | LOG_TRACE(Service_HID, "called"); | ||
| 716 | |||
| 717 | if (!Settings::values.vibration_enabled.GetValue()) { | 732 | if (!Settings::values.vibration_enabled.GetValue()) { |
| 718 | return; | 733 | return; |
| 719 | } | 734 | } |
| 720 | 735 | ||
| 721 | ASSERT_MSG(vibration_device_handles.size() == vibration_values.size(), | 736 | const auto npad_index = NPadIdToIndex(vibration_device_handle.npad_id); |
| 722 | "The amount of device handles does not match with the amount of vibration values," | 737 | const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index); |
| 723 | "this is undefined behavior!"); | ||
| 724 | 738 | ||
| 725 | for (std::size_t i = 0; i < vibration_device_handles.size(); ++i) { | 739 | if (!vibration_devices_mounted[npad_index][device_index] || |
| 726 | const auto npad_index = NPadIdToIndex(vibration_device_handles[i].npad_id); | 740 | !connected_controllers[npad_index].is_connected) { |
| 727 | const auto device_index = | 741 | return; |
| 728 | static_cast<std::size_t>(vibration_device_handles[i].device_index); | 742 | } |
| 729 | 743 | ||
| 730 | if (!vibration_devices_mounted[npad_index][device_index] || | 744 | if (vibration_device_handle.device_index == DeviceIndex::None) { |
| 731 | !connected_controllers[npad_index].is_connected) { | 745 | UNREACHABLE_MSG("DeviceIndex should never be None!"); |
| 732 | continue; | 746 | return; |
| 733 | } | 747 | } |
| 734 | 748 | ||
| 735 | if (vibration_device_handles[i].device_index == DeviceIndex::None) { | 749 | // Some games try to send mismatched parameters in the device handle, block these. |
| 736 | UNREACHABLE_MSG("DeviceIndex should never be None!"); | 750 | if ((connected_controllers[npad_index].type == NPadControllerType::JoyLeft && |
| 737 | continue; | 751 | (vibration_device_handle.npad_type == NpadType::JoyconRight || |
| 738 | } | 752 | vibration_device_handle.device_index == DeviceIndex::Right)) || |
| 753 | (connected_controllers[npad_index].type == NPadControllerType::JoyRight && | ||
| 754 | (vibration_device_handle.npad_type == NpadType::JoyconLeft || | ||
| 755 | vibration_device_handle.device_index == DeviceIndex::Left))) { | ||
| 756 | return; | ||
| 757 | } | ||
| 739 | 758 | ||
| 740 | // Some games try to send mismatched parameters in the device handle, block these. | 759 | // Filter out vibrations with equivalent values to reduce unnecessary state changes. |
| 741 | if ((connected_controllers[npad_index].type == NPadControllerType::JoyLeft && | 760 | if (vibration_value.amp_low == latest_vibration_values[npad_index][device_index].amp_low && |
| 742 | (vibration_device_handles[i].npad_type == NpadType::JoyconRight || | 761 | vibration_value.amp_high == latest_vibration_values[npad_index][device_index].amp_high) { |
| 743 | vibration_device_handles[i].device_index == DeviceIndex::Right)) || | 762 | return; |
| 744 | (connected_controllers[npad_index].type == NPadControllerType::JoyRight && | 763 | } |
| 745 | (vibration_device_handles[i].npad_type == NpadType::JoyconLeft || | ||
| 746 | vibration_device_handles[i].device_index == DeviceIndex::Left))) { | ||
| 747 | continue; | ||
| 748 | } | ||
| 749 | 764 | ||
| 750 | // Filter out vibrations with equivalent values to reduce unnecessary state changes. | 765 | if (VibrateControllerAtIndex(npad_index, device_index, vibration_value)) { |
| 751 | if (vibration_values[i].amp_low == | 766 | latest_vibration_values[npad_index][device_index] = vibration_value; |
| 752 | latest_vibration_values[npad_index][device_index].amp_low && | 767 | } |
| 753 | vibration_values[i].amp_high == | 768 | } |
| 754 | latest_vibration_values[npad_index][device_index].amp_high) { | ||
| 755 | continue; | ||
| 756 | } | ||
| 757 | 769 | ||
| 758 | // Filter out non-zero vibrations that are within 0.015625 absolute amplitude of each other. | 770 | void Controller_NPad::VibrateControllers(const std::vector<DeviceHandle>& vibration_device_handles, |
| 759 | if (!Settings::values.enable_accurate_vibrations.GetValue() && | 771 | const std::vector<VibrationValue>& vibration_values) { |
| 760 | (vibration_values[i].amp_low != 0.0f || vibration_values[i].amp_high != 0.0f) && | 772 | if (!Settings::values.vibration_enabled.GetValue()) { |
| 761 | (latest_vibration_values[npad_index][device_index].amp_low != 0.0f || | 773 | return; |
| 762 | latest_vibration_values[npad_index][device_index].amp_high != 0.0f) && | 774 | } |
| 763 | (abs(vibration_values[i].amp_low - | ||
| 764 | latest_vibration_values[npad_index][device_index].amp_low) < 0.015625f && | ||
| 765 | abs(vibration_values[i].amp_high - | ||
| 766 | latest_vibration_values[npad_index][device_index].amp_high) < 0.015625f)) { | ||
| 767 | continue; | ||
| 768 | } | ||
| 769 | 775 | ||
| 770 | if (VibrateControllerAtIndex(npad_index, device_index, vibration_values[i])) { | 776 | ASSERT_OR_EXECUTE_MSG( |
| 771 | latest_vibration_values[npad_index][device_index] = vibration_values[i]; | 777 | vibration_device_handles.size() == vibration_values.size(), { return; }, |
| 772 | } | 778 | "The amount of device handles does not match with the amount of vibration values," |
| 779 | "this is undefined behavior!"); | ||
| 780 | |||
| 781 | for (std::size_t i = 0; i < vibration_device_handles.size(); ++i) { | ||
| 782 | VibrateController(vibration_device_handles[i], vibration_values[i]); | ||
| 773 | } | 783 | } |
| 774 | } | 784 | } |
| 775 | 785 | ||
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index 30e3cb02f..f5122124c 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h | |||
| @@ -151,6 +151,9 @@ public: | |||
| 151 | bool VibrateControllerAtIndex(std::size_t npad_index, std::size_t device_index, | 151 | bool VibrateControllerAtIndex(std::size_t npad_index, std::size_t device_index, |
| 152 | const VibrationValue& vibration_value = {}); | 152 | const VibrationValue& vibration_value = {}); |
| 153 | 153 | ||
| 154 | void VibrateController(const DeviceHandle& vibration_device_handle, | ||
| 155 | const VibrationValue& vibration_value); | ||
| 156 | |||
| 154 | void VibrateControllers(const std::vector<DeviceHandle>& vibration_device_handles, | 157 | void VibrateControllers(const std::vector<DeviceHandle>& vibration_device_handles, |
| 155 | const std::vector<VibrationValue>& vibration_values); | 158 | const std::vector<VibrationValue>& vibration_values); |
| 156 | 159 | ||
| @@ -421,6 +424,7 @@ private: | |||
| 421 | NpadHandheldActivationMode handheld_activation_mode{NpadHandheldActivationMode::Dual}; | 424 | NpadHandheldActivationMode handheld_activation_mode{NpadHandheldActivationMode::Dual}; |
| 422 | // Each controller should have their own styleset changed event | 425 | // Each controller should have their own styleset changed event |
| 423 | std::array<Kernel::EventPair, 10> styleset_changed_events; | 426 | std::array<Kernel::EventPair, 10> styleset_changed_events; |
| 427 | std::array<std::array<std::chrono::steady_clock::time_point, 2>, 10> last_vibration_timepoints; | ||
| 424 | std::array<std::array<VibrationValue, 2>, 10> latest_vibration_values{}; | 428 | std::array<std::array<VibrationValue, 2>, 10> latest_vibration_values{}; |
| 425 | std::array<std::array<bool, 2>, 10> vibration_devices_mounted{}; | 429 | std::array<std::array<bool, 2>, 10> vibration_devices_mounted{}; |
| 426 | std::array<ControllerHolder, 10> connected_controllers{}; | 430 | std::array<ControllerHolder, 10> connected_controllers{}; |
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index ecaa847b2..2e9682bed 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp | |||
| @@ -1029,7 +1029,7 @@ void Hid::SendVibrationValue(Kernel::HLERequestContext& ctx) { | |||
| 1029 | const auto parameters{rp.PopRaw<Parameters>()}; | 1029 | const auto parameters{rp.PopRaw<Parameters>()}; |
| 1030 | 1030 | ||
| 1031 | applet_resource->GetController<Controller_NPad>(HidController::NPad) | 1031 | applet_resource->GetController<Controller_NPad>(HidController::NPad) |
| 1032 | .VibrateControllers({parameters.vibration_device_handle}, {parameters.vibration_value}); | 1032 | .VibrateController(parameters.vibration_device_handle, parameters.vibration_value); |
| 1033 | 1033 | ||
| 1034 | LOG_DEBUG(Service_HID, | 1034 | LOG_DEBUG(Service_HID, |
| 1035 | "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", | 1035 | "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", |