summaryrefslogtreecommitdiff
path: root/Source/Core/InputCommon/ControllerInterface/SDL/SDL.cpp
diff options
context:
space:
mode:
authorJordan Woyak <jordan.woyak@gmail.com>2025-01-21 19:19:01 -0600
committerJordan Woyak <jordan.woyak@gmail.com>2025-01-21 19:19:01 -0600
commitfb512adc5ff397e50157c20dfc3e425e3bbd4abe (patch)
tree6ec11863dc6c86876678df053340a50262a825d8 /Source/Core/InputCommon/ControllerInterface/SDL/SDL.cpp
parent510a688a2ae7fd127b8fb29808d8c65af9fa9214 (diff)
InputCommon: Make SDL Motor L/R Outputs not fight each other.
Diffstat (limited to 'Source/Core/InputCommon/ControllerInterface/SDL/SDL.cpp')
-rw-r--r--Source/Core/InputCommon/ControllerInterface/SDL/SDL.cpp64
1 files changed, 49 insertions, 15 deletions
diff --git a/Source/Core/InputCommon/ControllerInterface/SDL/SDL.cpp b/Source/Core/InputCommon/ControllerInterface/SDL/SDL.cpp
index 7b68b96712..de8644e2e8 100644
--- a/Source/Core/InputCommon/ControllerInterface/SDL/SDL.cpp
+++ b/Source/Core/InputCommon/ControllerInterface/SDL/SDL.cpp
@@ -187,30 +187,55 @@ private:
};
// Rumble
- template <int LowEnable, int HighEnable, int SuffixIndex>
- class GenericMotor : public Output
+ class Motor : public Output
{
public:
- explicit GenericMotor(SDL_GameController* gc) : m_gc(gc) {}
- std::string GetName() const override
+ Motor(const char* name, GameController& gc, Uint16* state)
+ : m_name{name}, m_gc{gc}, m_state{*state}
{
- return std::string("Motor") + motor_suffixes[SuffixIndex];
}
+ std::string GetName() const override { return m_name; }
void SetState(ControlState state) override
{
- Uint16 rumble = state * std::numeric_limits<Uint16>::max();
- SDL_GameControllerRumble(m_gc, rumble * LowEnable, rumble * HighEnable, RUMBLE_LENGTH_MS);
+ const auto new_state = state * std::numeric_limits<Uint16>::max();
+ if (m_state == new_state)
+ return;
+
+ m_state = new_state;
+ m_gc.UpdateRumble();
}
private:
- SDL_GameController* const m_gc;
+ const char* const m_name;
+ GameController& m_gc;
+ Uint16& m_state;
};
- static constexpr const char* motor_suffixes[] = {"", " L", " R"};
+ class CombinedMotor : public Output
+ {
+ public:
+ CombinedMotor(const char* name, GameController& gc, Uint16* low_state, Uint16* high_state)
+ : m_name{name}, m_gc{gc}, m_low_state{*low_state}, m_high_state{*high_state}
+ {
+ }
+ std::string GetName() const override { return m_name; }
+ void SetState(ControlState state) override
+ {
+ const auto new_state = state * std::numeric_limits<Uint16>::max();
+ if (m_low_state == new_state && m_high_state == new_state)
+ return;
+
+ m_low_state = new_state;
+ m_high_state = new_state;
+ m_gc.UpdateRumble();
+ }
- using Motor = GenericMotor<1, 1, 0>;
- using MotorL = GenericMotor<1, 0, 1>;
- using MotorR = GenericMotor<0, 1, 2>;
+ private:
+ const char* const m_name;
+ GameController& m_gc;
+ Uint16& m_low_state;
+ Uint16& m_high_state;
+ };
class HapticEffect : public Output
{
@@ -364,6 +389,15 @@ public:
}
private:
+ void UpdateRumble()
+ {
+ SDL_GameControllerRumble(m_gamecontroller, m_low_freq_rumble, m_high_freq_rumble,
+ RUMBLE_LENGTH_MS);
+ }
+
+ Uint16 m_low_freq_rumble = 0;
+ Uint16 m_high_freq_rumble = 0;
+
SDL_GameController* const m_gamecontroller;
std::string m_name;
SDL_Joystick* const m_joystick;
@@ -754,9 +788,9 @@ GameController::GameController(SDL_GameController* const gamecontroller,
// Rumble
if (SDL_GameControllerHasRumble(m_gamecontroller))
{
- AddOutput(new Motor(m_gamecontroller));
- AddOutput(new MotorL(m_gamecontroller));
- AddOutput(new MotorR(m_gamecontroller));
+ AddOutput(new CombinedMotor("Motor", *this, &m_low_freq_rumble, &m_high_freq_rumble));
+ AddOutput(new Motor("Motor L", *this, &m_low_freq_rumble));
+ AddOutput(new Motor("Motor R", *this, &m_high_freq_rumble));
}
// Touchpad