|
|
@@ -703,6 +703,23 @@ bool Controller_NPad::VibrateControllerAtIndex(std::size_t npad_index, std::size
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
+ if (!Settings::values.enable_accurate_vibrations.GetValue()) {
|
|
|
+ using std::chrono::duration_cast;
|
|
|
+ using std::chrono::milliseconds;
|
|
|
+ using std::chrono::steady_clock;
|
|
|
+
|
|
|
+ const auto now = steady_clock::now();
|
|
|
+
|
|
|
+ // Filter out non-zero vibrations that are within 10ms of each other.
|
|
|
+ if ((vibration_value.amp_low != 0.0f || vibration_value.amp_high != 0.0f) &&
|
|
|
+ duration_cast<milliseconds>(now - last_vibration_timepoints[npad_index][device_index]) <
|
|
|
+ milliseconds(10)) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ last_vibration_timepoints[npad_index][device_index] = now;
|
|
|
+ }
|
|
|
+
|
|
|
return vibrations[npad_index][device_index]->SetRumblePlay(
|
|
|
std::min(vibration_value.amp_low * player.vibration_strength / 100.0f, 1.0f),
|
|
|
vibration_value.freq_low,
|
|
|
@@ -710,66 +727,59 @@ bool Controller_NPad::VibrateControllerAtIndex(std::size_t npad_index, std::size
|
|
|
vibration_value.freq_high);
|
|
|
}
|
|
|
|
|
|
-void Controller_NPad::VibrateControllers(const std::vector<DeviceHandle>& vibration_device_handles,
|
|
|
- const std::vector<VibrationValue>& vibration_values) {
|
|
|
- LOG_TRACE(Service_HID, "called");
|
|
|
-
|
|
|
+void Controller_NPad::VibrateController(const DeviceHandle& vibration_device_handle,
|
|
|
+ const VibrationValue& vibration_value) {
|
|
|
if (!Settings::values.vibration_enabled.GetValue()) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- ASSERT_MSG(vibration_device_handles.size() == vibration_values.size(),
|
|
|
- "The amount of device handles does not match with the amount of vibration values,"
|
|
|
- "this is undefined behavior!");
|
|
|
+ const auto npad_index = NPadIdToIndex(vibration_device_handle.npad_id);
|
|
|
+ const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index);
|
|
|
|
|
|
- for (std::size_t i = 0; i < vibration_device_handles.size(); ++i) {
|
|
|
- const auto npad_index = NPadIdToIndex(vibration_device_handles[i].npad_id);
|
|
|
- const auto device_index =
|
|
|
- static_cast<std::size_t>(vibration_device_handles[i].device_index);
|
|
|
+ if (!vibration_devices_mounted[npad_index][device_index] ||
|
|
|
+ !connected_controllers[npad_index].is_connected) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
- if (!vibration_devices_mounted[npad_index][device_index] ||
|
|
|
- !connected_controllers[npad_index].is_connected) {
|
|
|
- continue;
|
|
|
- }
|
|
|
+ if (vibration_device_handle.device_index == DeviceIndex::None) {
|
|
|
+ UNREACHABLE_MSG("DeviceIndex should never be None!");
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
- if (vibration_device_handles[i].device_index == DeviceIndex::None) {
|
|
|
- UNREACHABLE_MSG("DeviceIndex should never be None!");
|
|
|
- continue;
|
|
|
- }
|
|
|
+ // Some games try to send mismatched parameters in the device handle, block these.
|
|
|
+ if ((connected_controllers[npad_index].type == NPadControllerType::JoyLeft &&
|
|
|
+ (vibration_device_handle.npad_type == NpadType::JoyconRight ||
|
|
|
+ vibration_device_handle.device_index == DeviceIndex::Right)) ||
|
|
|
+ (connected_controllers[npad_index].type == NPadControllerType::JoyRight &&
|
|
|
+ (vibration_device_handle.npad_type == NpadType::JoyconLeft ||
|
|
|
+ vibration_device_handle.device_index == DeviceIndex::Left))) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
- // Some games try to send mismatched parameters in the device handle, block these.
|
|
|
- if ((connected_controllers[npad_index].type == NPadControllerType::JoyLeft &&
|
|
|
- (vibration_device_handles[i].npad_type == NpadType::JoyconRight ||
|
|
|
- vibration_device_handles[i].device_index == DeviceIndex::Right)) ||
|
|
|
- (connected_controllers[npad_index].type == NPadControllerType::JoyRight &&
|
|
|
- (vibration_device_handles[i].npad_type == NpadType::JoyconLeft ||
|
|
|
- vibration_device_handles[i].device_index == DeviceIndex::Left))) {
|
|
|
- continue;
|
|
|
- }
|
|
|
+ // Filter out vibrations with equivalent values to reduce unnecessary state changes.
|
|
|
+ if (vibration_value.amp_low == latest_vibration_values[npad_index][device_index].amp_low &&
|
|
|
+ vibration_value.amp_high == latest_vibration_values[npad_index][device_index].amp_high) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
- // Filter out vibrations with equivalent values to reduce unnecessary state changes.
|
|
|
- if (vibration_values[i].amp_low ==
|
|
|
- latest_vibration_values[npad_index][device_index].amp_low &&
|
|
|
- vibration_values[i].amp_high ==
|
|
|
- latest_vibration_values[npad_index][device_index].amp_high) {
|
|
|
- continue;
|
|
|
- }
|
|
|
+ if (VibrateControllerAtIndex(npad_index, device_index, vibration_value)) {
|
|
|
+ latest_vibration_values[npad_index][device_index] = vibration_value;
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
- // Filter out non-zero vibrations that are within 0.015625 absolute amplitude of each other.
|
|
|
- if (!Settings::values.enable_accurate_vibrations.GetValue() &&
|
|
|
- (vibration_values[i].amp_low != 0.0f || vibration_values[i].amp_high != 0.0f) &&
|
|
|
- (latest_vibration_values[npad_index][device_index].amp_low != 0.0f ||
|
|
|
- latest_vibration_values[npad_index][device_index].amp_high != 0.0f) &&
|
|
|
- (abs(vibration_values[i].amp_low -
|
|
|
- latest_vibration_values[npad_index][device_index].amp_low) < 0.015625f &&
|
|
|
- abs(vibration_values[i].amp_high -
|
|
|
- latest_vibration_values[npad_index][device_index].amp_high) < 0.015625f)) {
|
|
|
- continue;
|
|
|
- }
|
|
|
+void Controller_NPad::VibrateControllers(const std::vector<DeviceHandle>& vibration_device_handles,
|
|
|
+ const std::vector<VibrationValue>& vibration_values) {
|
|
|
+ if (!Settings::values.vibration_enabled.GetValue()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
- if (VibrateControllerAtIndex(npad_index, device_index, vibration_values[i])) {
|
|
|
- latest_vibration_values[npad_index][device_index] = vibration_values[i];
|
|
|
- }
|
|
|
+ ASSERT_OR_EXECUTE_MSG(
|
|
|
+ vibration_device_handles.size() == vibration_values.size(), { return; },
|
|
|
+ "The amount of device handles does not match with the amount of vibration values,"
|
|
|
+ "this is undefined behavior!");
|
|
|
+
|
|
|
+ for (std::size_t i = 0; i < vibration_device_handles.size(); ++i) {
|
|
|
+ VibrateController(vibration_device_handles[i], vibration_values[i]);
|
|
|
}
|
|
|
}
|
|
|
|