summaryrefslogtreecommitdiff
path: root/src/input_common/sdl/sdl_impl.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/input_common/sdl/sdl_impl.cpp74
1 files changed, 58 insertions, 16 deletions
diff --git a/src/input_common/sdl/sdl_impl.cpp b/src/input_common/sdl/sdl_impl.cpp
index 18fb2ac5e..a2a83cdc9 100644
--- a/src/input_common/sdl/sdl_impl.cpp
+++ b/src/input_common/sdl/sdl_impl.cpp
@@ -85,16 +85,17 @@ public:
85 using std::chrono::milliseconds; 85 using std::chrono::milliseconds;
86 using std::chrono::steady_clock; 86 using std::chrono::steady_clock;
87 87
88 // Prevent vibrations less than 10ms apart from each other. 88 // Block non-zero vibrations less than 10ms apart from each other.
89 if (duration_cast<milliseconds>(steady_clock::now() - last_vibration) < milliseconds(10)) { 89 if ((amp_low != 0 || amp_high != 0) &&
90 duration_cast<milliseconds>(steady_clock::now() - last_vibration) < milliseconds(10)) {
90 return false; 91 return false;
91 }; 92 }
92 93
93 last_vibration = steady_clock::now(); 94 last_vibration = steady_clock::now();
94 95
95 if (sdl_controller != nullptr) { 96 if (sdl_controller) {
96 return SDL_GameControllerRumble(sdl_controller.get(), amp_low, amp_high, 0) == 0; 97 return SDL_GameControllerRumble(sdl_controller.get(), amp_low, amp_high, 0) == 0;
97 } else if (sdl_joystick != nullptr) { 98 } else if (sdl_joystick) {
98 return SDL_JoystickRumble(sdl_joystick.get(), amp_low, amp_high, 0) == 0; 99 return SDL_JoystickRumble(sdl_joystick.get(), amp_low, amp_high, 0) == 0;
99 } 100 }
100 101
@@ -321,14 +322,6 @@ public:
321 return joystick->GetButton(button); 322 return joystick->GetButton(button);
322 } 323 }
323 324
324 bool SetRumblePlay(f32 amp_low, f32 freq_low, f32 amp_high, f32 freq_high) const override {
325 const u16 processed_amp_low =
326 static_cast<u16>(pow(amp_low, 0.5f) * (3.0f - 2.0f * pow(amp_low, 0.15f)) * 0xFFFF);
327 const u16 processed_amp_high =
328 static_cast<u16>(pow(amp_high, 0.5f) * (3.0f - 2.0f * pow(amp_high, 0.15f)) * 0xFFFF);
329 return joystick->RumblePlay(processed_amp_low, processed_amp_high);
330 }
331
332private: 325private:
333 std::shared_ptr<SDLJoystick> joystick; 326 std::shared_ptr<SDLJoystick> joystick;
334 int button; 327 int button;
@@ -412,6 +405,32 @@ private:
412 const float range; 405 const float range;
413}; 406};
414 407
408class SDLVibration final : public Input::VibrationDevice {
409public:
410 explicit SDLVibration(std::shared_ptr<SDLJoystick> joystick_)
411 : joystick(std::move(joystick_)) {}
412
413 u8 GetStatus() const override {
414 joystick->RumblePlay(1, 1);
415 return joystick->RumblePlay(0, 0);
416 }
417
418 bool SetRumblePlay(f32 amp_low, f32 freq_low, f32 amp_high, f32 freq_high) const override {
419 const auto process_amplitude = [](f32 amplitude) {
420 return static_cast<u16>(std::pow(amplitude, 0.5f) *
421 (3.0f - 2.0f * std::pow(amplitude, 0.15f)) * 0xFFFF);
422 };
423
424 const auto processed_amp_low = process_amplitude(amp_low);
425 const auto processed_amp_high = process_amplitude(amp_high);
426
427 return joystick->RumblePlay(processed_amp_low, processed_amp_high);
428 }
429
430private:
431 std::shared_ptr<SDLJoystick> joystick;
432};
433
415class SDLDirectionMotion final : public Input::MotionDevice { 434class SDLDirectionMotion final : public Input::MotionDevice {
416public: 435public:
417 explicit SDLDirectionMotion(std::shared_ptr<SDLJoystick> joystick_, int hat_, Uint8 direction_) 436 explicit SDLDirectionMotion(std::shared_ptr<SDLJoystick> joystick_, int hat_, Uint8 direction_)
@@ -554,7 +573,7 @@ class SDLAnalogFactory final : public Input::Factory<Input::AnalogDevice> {
554public: 573public:
555 explicit SDLAnalogFactory(SDLState& state_) : state(state_) {} 574 explicit SDLAnalogFactory(SDLState& state_) : state(state_) {}
556 /** 575 /**
557 * Creates analog device from joystick axes 576 * Creates an analog device from joystick axes
558 * @param params contains parameters for creating the device: 577 * @param params contains parameters for creating the device:
559 * - "guid": the guid of the joystick to bind 578 * - "guid": the guid of the joystick to bind
560 * - "port": the nth joystick of the same type 579 * - "port": the nth joystick of the same type
@@ -580,6 +599,26 @@ private:
580 SDLState& state; 599 SDLState& state;
581}; 600};
582 601
602/// An vibration device factory that creates vibration devices from SDL joystick
603class SDLVibrationFactory final : public Input::Factory<Input::VibrationDevice> {
604public:
605 explicit SDLVibrationFactory(SDLState& state_) : state(state_) {}
606 /**
607 * Creates a vibration device from a joystick
608 * @param params contains parameters for creating the device:
609 * - "guid": the guid of the joystick to bind
610 * - "port": the nth joystick of the same type
611 */
612 std::unique_ptr<Input::VibrationDevice> Create(const Common::ParamPackage& params) override {
613 const std::string guid = params.Get("guid", "0");
614 const int port = params.Get("port", 0);
615 return std::make_unique<SDLVibration>(state.GetSDLJoystickByGUID(guid, port));
616 }
617
618private:
619 SDLState& state;
620};
621
583/// A motion device factory that creates motion devices from SDL joystick 622/// A motion device factory that creates motion devices from SDL joystick
584class SDLMotionFactory final : public Input::Factory<Input::MotionDevice> { 623class SDLMotionFactory final : public Input::Factory<Input::MotionDevice> {
585public: 624public:
@@ -646,11 +685,13 @@ private:
646 685
647SDLState::SDLState() { 686SDLState::SDLState() {
648 using namespace Input; 687 using namespace Input;
649 analog_factory = std::make_shared<SDLAnalogFactory>(*this);
650 button_factory = std::make_shared<SDLButtonFactory>(*this); 688 button_factory = std::make_shared<SDLButtonFactory>(*this);
689 analog_factory = std::make_shared<SDLAnalogFactory>(*this);
690 vibration_factory = std::make_shared<SDLVibrationFactory>(*this);
651 motion_factory = std::make_shared<SDLMotionFactory>(*this); 691 motion_factory = std::make_shared<SDLMotionFactory>(*this);
652 RegisterFactory<AnalogDevice>("sdl", analog_factory);
653 RegisterFactory<ButtonDevice>("sdl", button_factory); 692 RegisterFactory<ButtonDevice>("sdl", button_factory);
693 RegisterFactory<AnalogDevice>("sdl", analog_factory);
694 RegisterFactory<VibrationDevice>("sdl", vibration_factory);
654 RegisterFactory<MotionDevice>("sdl", motion_factory); 695 RegisterFactory<MotionDevice>("sdl", motion_factory);
655 696
656 // If the frontend is going to manage the event loop, then we don't start one here 697 // If the frontend is going to manage the event loop, then we don't start one here
@@ -687,6 +728,7 @@ SDLState::~SDLState() {
687 using namespace Input; 728 using namespace Input;
688 UnregisterFactory<ButtonDevice>("sdl"); 729 UnregisterFactory<ButtonDevice>("sdl");
689 UnregisterFactory<AnalogDevice>("sdl"); 730 UnregisterFactory<AnalogDevice>("sdl");
731 UnregisterFactory<VibrationDevice>("sdl");
690 UnregisterFactory<MotionDevice>("sdl"); 732 UnregisterFactory<MotionDevice>("sdl");
691 733
692 CloseJoysticks(); 734 CloseJoysticks();