sdl_input_source.h (3565B)
1 // SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <stenzek@gmail.com> 2 // SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0) 3 4 #pragma once 5 #include "input_source.h" 6 7 #include <SDL.h> 8 9 #include <array> 10 #include <functional> 11 #include <mutex> 12 #include <vector> 13 14 class SettingsInterface; 15 16 class SDLInputSource final : public InputSource 17 { 18 public: 19 static constexpr u32 MAX_LED_COLORS = 4; 20 21 SDLInputSource(); 22 ~SDLInputSource(); 23 24 bool Initialize(SettingsInterface& si, std::unique_lock<std::mutex>& settings_lock) override; 25 void UpdateSettings(SettingsInterface& si, std::unique_lock<std::mutex>& settings_lock) override; 26 bool ReloadDevices() override; 27 void Shutdown() override; 28 29 void PollEvents() override; 30 std::vector<std::pair<std::string, std::string>> EnumerateDevices() override; 31 std::vector<InputBindingKey> EnumerateMotors() override; 32 bool GetGenericBindingMapping(std::string_view device, GenericInputBindingMapping* mapping) override; 33 void UpdateMotorState(InputBindingKey key, float intensity) override; 34 void UpdateMotorState(InputBindingKey large_key, InputBindingKey small_key, float large_intensity, 35 float small_intensity) override; 36 37 std::optional<InputBindingKey> ParseKeyString(std::string_view device, std::string_view binding) override; 38 TinyString ConvertKeyToString(InputBindingKey key) override; 39 TinyString ConvertKeyToIcon(InputBindingKey key) override; 40 41 bool ProcessSDLEvent(const SDL_Event* event); 42 43 SDL_Joystick* GetJoystickForDevice(std::string_view device); 44 45 static u32 GetRGBForPlayerId(SettingsInterface& si, u32 player_id); 46 static u32 ParseRGBForPlayerId(std::string_view str, u32 player_id); 47 48 static bool IsHandledInputEvent(const SDL_Event* ev); 49 50 static bool ALLOW_EVENT_POLLING; 51 52 private: 53 struct ControllerData 54 { 55 SDL_Haptic* haptic; 56 SDL_GameController* game_controller; 57 SDL_Joystick* joystick; 58 u16 rumble_intensity[2]; 59 int haptic_left_right_effect; 60 int joystick_id; 61 int player_id; 62 bool use_game_controller_rumble; 63 64 // Used to disable Joystick controls that are used in GameController inputs so we don't get double events 65 std::vector<bool> joy_button_used_in_gc; 66 std::vector<bool> joy_axis_used_in_gc; 67 68 // Track last hat state so we can send "unpressed" events. 69 std::vector<u8> last_hat_state; 70 }; 71 72 using ControllerDataVector = std::vector<ControllerData>; 73 74 bool InitializeSubsystem(); 75 void ShutdownSubsystem(); 76 void LoadSettings(SettingsInterface& si); 77 void SetHints(); 78 79 ControllerDataVector::iterator GetControllerDataForJoystickId(int id); 80 ControllerDataVector::iterator GetControllerDataForPlayerId(int id); 81 int GetFreePlayerId() const; 82 83 bool OpenDevice(int index, bool is_gamecontroller); 84 bool CloseDevice(int joystick_index); 85 bool HandleControllerAxisEvent(const SDL_ControllerAxisEvent* ev); 86 bool HandleControllerButtonEvent(const SDL_ControllerButtonEvent* ev); 87 bool HandleJoystickAxisEvent(const SDL_JoyAxisEvent* ev); 88 bool HandleJoystickButtonEvent(const SDL_JoyButtonEvent* ev); 89 bool HandleJoystickHatEvent(const SDL_JoyHatEvent* ev); 90 void SendRumbleUpdate(ControllerData* cd); 91 92 ControllerDataVector m_controllers; 93 94 std::array<u32, MAX_LED_COLORS> m_led_colors{}; 95 std::vector<std::pair<std::string, std::string>> m_sdl_hints; 96 97 bool m_sdl_subsystem_initialized = false; 98 bool m_controller_enhanced_mode = false; 99 bool m_controller_ps5_player_led = false; 100 101 #ifdef __APPLE__ 102 bool m_enable_iokit_driver = false; 103 bool m_enable_mfi_driver = false; 104 #endif 105 };