From ca7f949ee84a7f15990c9e09f2de9ea54b8f997a Mon Sep 17 00:00:00 2001
From: german77 <juangerman-13@hotmail.com>
Date: Sat, 24 Feb 2024 12:13:47 -0600
Subject: [PATCH] core: hid: Reintroduce vibration filter

---
 src/hid_core/frontend/emulated_controller.cpp | 17 +++++++++++++++++
 src/hid_core/frontend/emulated_controller.h   |  1 +
 src/hid_core/hid_types.h                      |  6 +++++-
 src/hid_core/resources/npad/npad.cpp          |  1 -
 4 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/src/hid_core/frontend/emulated_controller.cpp b/src/hid_core/frontend/emulated_controller.cpp
index 5cd26819c..7664341bd 100644
--- a/src/hid_core/frontend/emulated_controller.cpp
+++ b/src/hid_core/frontend/emulated_controller.cpp
@@ -2,6 +2,7 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
 
 #include <algorithm>
+#include <chrono>
 #include <common/scope_exit.h>
 
 #include "common/polyfill_ranges.h"
@@ -1287,6 +1288,22 @@ bool EmulatedController::SetVibration(DeviceIndex device_index, const VibrationV
         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 15ms of each other.
+        if ((vibration.low_amplitude != 0.0f || vibration.high_amplitude != 0.0f) &&
+            duration_cast<milliseconds>(now - last_vibration_timepoint[index]) < milliseconds(15)) {
+            return false;
+        }
+
+        last_vibration_timepoint[index] = now;
+    }
+
     // Exponential amplification is too strong at low amplitudes. Switch to a linear
     // amplification if strength is set below 0.7f
     const Common::Input::VibrationAmplificationType type =
diff --git a/src/hid_core/frontend/emulated_controller.h b/src/hid_core/frontend/emulated_controller.h
index ab3c6fcd3..17ad6069e 100644
--- a/src/hid_core/frontend/emulated_controller.h
+++ b/src/hid_core/frontend/emulated_controller.h
@@ -583,6 +583,7 @@ private:
     std::size_t nfc_handles{0};
     std::array<VibrationValue, 2> last_vibration_value{DEFAULT_VIBRATION_VALUE,
                                                        DEFAULT_VIBRATION_VALUE};
+    std::array<std::chrono::steady_clock::time_point, 2> last_vibration_timepoint{};
 
     // Temporary values to avoid doing changes while the controller is in configuring mode
     NpadStyleIndex tmp_npad_type{NpadStyleIndex::None};
diff --git a/src/hid_core/hid_types.h b/src/hid_core/hid_types.h
index 1b2fc6295..38888fdd1 100644
--- a/src/hid_core/hid_types.h
+++ b/src/hid_core/hid_types.h
@@ -638,7 +638,11 @@ struct VibrationValue {
         if (low_amplitude != b.low_amplitude || high_amplitude != b.high_amplitude) {
             return false;
         }
-        if (low_frequency != b.low_amplitude || high_frequency != b.high_frequency) {
+        // Changes in frequency without amplitude don't have any effect
+        if (low_amplitude == 0 && high_amplitude == 0) {
+            return true;
+        }
+        if (low_frequency != b.low_frequency || high_frequency != b.high_frequency) {
             return false;
         }
         return true;
diff --git a/src/hid_core/resources/npad/npad.cpp b/src/hid_core/resources/npad/npad.cpp
index e10e97e1c..ca1ccd659 100644
--- a/src/hid_core/resources/npad/npad.cpp
+++ b/src/hid_core/resources/npad/npad.cpp
@@ -3,7 +3,6 @@
 
 #include <algorithm>
 #include <array>
-#include <chrono>
 #include <cstring>
 
 #include "common/assert.h"