diff options
Diffstat (limited to 'src/input_common/sdl/sdl_impl.cpp')
| -rw-r--r-- | src/input_common/sdl/sdl_impl.cpp | 74 |
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 | |||
| 332 | private: | 325 | private: |
| 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 | ||
| 408 | class SDLVibration final : public Input::VibrationDevice { | ||
| 409 | public: | ||
| 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 | |||
| 430 | private: | ||
| 431 | std::shared_ptr<SDLJoystick> joystick; | ||
| 432 | }; | ||
| 433 | |||
| 415 | class SDLDirectionMotion final : public Input::MotionDevice { | 434 | class SDLDirectionMotion final : public Input::MotionDevice { |
| 416 | public: | 435 | public: |
| 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> { | |||
| 554 | public: | 573 | public: |
| 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 | ||
| 603 | class SDLVibrationFactory final : public Input::Factory<Input::VibrationDevice> { | ||
| 604 | public: | ||
| 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 | |||
| 618 | private: | ||
| 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 |
| 584 | class SDLMotionFactory final : public Input::Factory<Input::MotionDevice> { | 623 | class SDLMotionFactory final : public Input::Factory<Input::MotionDevice> { |
| 585 | public: | 624 | public: |
| @@ -646,11 +685,13 @@ private: | |||
| 646 | 685 | ||
| 647 | SDLState::SDLState() { | 686 | SDLState::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(); |