diff options
Diffstat (limited to 'src/input_common/sdl/sdl_impl.cpp')
| -rw-r--r-- | src/input_common/sdl/sdl_impl.cpp | 89 |
1 files changed, 45 insertions, 44 deletions
diff --git a/src/input_common/sdl/sdl_impl.cpp b/src/input_common/sdl/sdl_impl.cpp index bd480570a..9c3035920 100644 --- a/src/input_common/sdl/sdl_impl.cpp +++ b/src/input_common/sdl/sdl_impl.cpp | |||
| @@ -56,9 +56,9 @@ static int SDLEventWatcher(void* user_data, SDL_Event* event) { | |||
| 56 | class SDLJoystick { | 56 | class SDLJoystick { |
| 57 | public: | 57 | public: |
| 58 | SDLJoystick(std::string guid_, int port_, SDL_Joystick* joystick, | 58 | SDLJoystick(std::string guid_, int port_, SDL_Joystick* joystick, |
| 59 | SDL_GameController* gamecontroller) | 59 | SDL_GameController* game_controller) |
| 60 | : guid{std::move(guid_)}, port{port_}, sdl_joystick{joystick, &SDL_JoystickClose}, | 60 | : guid{std::move(guid_)}, port{port_}, sdl_joystick{joystick, &SDL_JoystickClose}, |
| 61 | sdl_controller{gamecontroller, &SDL_GameControllerClose} {} | 61 | sdl_controller{game_controller, &SDL_GameControllerClose} {} |
| 62 | 62 | ||
| 63 | void SetButton(int button, bool value) { | 63 | void SetButton(int button, bool value) { |
| 64 | std::lock_guard lock{mutex}; | 64 | std::lock_guard lock{mutex}; |
| @@ -77,10 +77,10 @@ public: | |||
| 77 | 77 | ||
| 78 | float GetAxis(int axis, float range) const { | 78 | float GetAxis(int axis, float range) const { |
| 79 | std::lock_guard lock{mutex}; | 79 | std::lock_guard lock{mutex}; |
| 80 | return state.axes.at(axis) / (32767.0f * range); | 80 | return static_cast<float>(state.axes.at(axis)) / (32767.0f * range); |
| 81 | } | 81 | } |
| 82 | 82 | ||
| 83 | bool RumblePlay(f32 amp_low, f32 amp_high, int time) { | 83 | bool RumblePlay(f32 amp_low, f32 amp_high, u32 time) { |
| 84 | const u16 raw_amp_low = static_cast<u16>(amp_low * 0xFFFF); | 84 | const u16 raw_amp_low = static_cast<u16>(amp_low * 0xFFFF); |
| 85 | const u16 raw_amp_high = static_cast<u16>(amp_high * 0xFFFF); | 85 | const u16 raw_amp_high = static_cast<u16>(amp_high * 0xFFFF); |
| 86 | // Lower drastically the number of state changes | 86 | // Lower drastically the number of state changes |
| @@ -124,7 +124,7 @@ public: | |||
| 124 | return std::make_tuple(x, y); | 124 | return std::make_tuple(x, y); |
| 125 | } | 125 | } |
| 126 | 126 | ||
| 127 | const InputCommon::MotionInput& GetMotion() const { | 127 | const MotionInput& GetMotion() const { |
| 128 | return motion; | 128 | return motion; |
| 129 | } | 129 | } |
| 130 | 130 | ||
| @@ -172,15 +172,15 @@ private: | |||
| 172 | } state; | 172 | } state; |
| 173 | std::string guid; | 173 | std::string guid; |
| 174 | int port; | 174 | int port; |
| 175 | u16 last_state_rumble_high; | 175 | u16 last_state_rumble_high = 0; |
| 176 | u16 last_state_rumble_low; | 176 | u16 last_state_rumble_low = 0; |
| 177 | std::chrono::time_point<std::chrono::system_clock> last_vibration; | 177 | std::chrono::time_point<std::chrono::system_clock> last_vibration; |
| 178 | std::unique_ptr<SDL_Joystick, decltype(&SDL_JoystickClose)> sdl_joystick; | 178 | std::unique_ptr<SDL_Joystick, decltype(&SDL_JoystickClose)> sdl_joystick; |
| 179 | std::unique_ptr<SDL_GameController, decltype(&SDL_GameControllerClose)> sdl_controller; | 179 | std::unique_ptr<SDL_GameController, decltype(&SDL_GameControllerClose)> sdl_controller; |
| 180 | mutable std::mutex mutex; | 180 | mutable std::mutex mutex; |
| 181 | 181 | ||
| 182 | // motion is initalized without PID values as motion input is not aviable for SDL2 | 182 | // Motion is initialized without PID values as motion input is not aviable for SDL2 |
| 183 | InputCommon::MotionInput motion{0.0f, 0.0f, 0.0f}; | 183 | MotionInput motion{0.0f, 0.0f, 0.0f}; |
| 184 | }; | 184 | }; |
| 185 | 185 | ||
| 186 | std::shared_ptr<SDLJoystick> SDLState::GetSDLJoystickByGUID(const std::string& guid, int port) { | 186 | std::shared_ptr<SDLJoystick> SDLState::GetSDLJoystickByGUID(const std::string& guid, int port) { |
| @@ -192,7 +192,7 @@ std::shared_ptr<SDLJoystick> SDLState::GetSDLJoystickByGUID(const std::string& g | |||
| 192 | nullptr, nullptr); | 192 | nullptr, nullptr); |
| 193 | it->second.emplace_back(std::move(joystick)); | 193 | it->second.emplace_back(std::move(joystick)); |
| 194 | } | 194 | } |
| 195 | return it->second[port]; | 195 | return it->second[static_cast<std::size_t>(port)]; |
| 196 | } | 196 | } |
| 197 | auto joystick = std::make_shared<SDLJoystick>(guid, 0, nullptr, nullptr); | 197 | auto joystick = std::make_shared<SDLJoystick>(guid, 0, nullptr, nullptr); |
| 198 | return joystick_map[guid].emplace_back(std::move(joystick)); | 198 | return joystick_map[guid].emplace_back(std::move(joystick)); |
| @@ -212,7 +212,7 @@ std::shared_ptr<SDLJoystick> SDLState::GetSDLJoystickBySDLID(SDL_JoystickID sdl_ | |||
| 212 | return sdl_joystick == joystick->GetSDLJoystick(); | 212 | return sdl_joystick == joystick->GetSDLJoystick(); |
| 213 | }); | 213 | }); |
| 214 | if (vec_it != map_it->second.end()) { | 214 | if (vec_it != map_it->second.end()) { |
| 215 | // This is the common case: There is already an existing SDL_Joystick maped to a | 215 | // This is the common case: There is already an existing SDL_Joystick mapped to a |
| 216 | // SDLJoystick. return the SDLJoystick | 216 | // SDLJoystick. return the SDLJoystick |
| 217 | return *vec_it; | 217 | return *vec_it; |
| 218 | } | 218 | } |
| @@ -220,7 +220,7 @@ std::shared_ptr<SDLJoystick> SDLState::GetSDLJoystickBySDLID(SDL_JoystickID sdl_ | |||
| 220 | // Search for a SDLJoystick without a mapped SDL_Joystick... | 220 | // Search for a SDLJoystick without a mapped SDL_Joystick... |
| 221 | const auto nullptr_it = std::find_if(map_it->second.begin(), map_it->second.end(), | 221 | const auto nullptr_it = std::find_if(map_it->second.begin(), map_it->second.end(), |
| 222 | [](const std::shared_ptr<SDLJoystick>& joystick) { | 222 | [](const std::shared_ptr<SDLJoystick>& joystick) { |
| 223 | return !joystick->GetSDLJoystick(); | 223 | return joystick->GetSDLJoystick() == nullptr; |
| 224 | }); | 224 | }); |
| 225 | if (nullptr_it != map_it->second.end()) { | 225 | if (nullptr_it != map_it->second.end()) { |
| 226 | // ... and map it | 226 | // ... and map it |
| @@ -273,22 +273,19 @@ void SDLState::InitJoystick(int joystick_index) { | |||
| 273 | void SDLState::CloseJoystick(SDL_Joystick* sdl_joystick) { | 273 | void SDLState::CloseJoystick(SDL_Joystick* sdl_joystick) { |
| 274 | const std::string guid = GetGUID(sdl_joystick); | 274 | const std::string guid = GetGUID(sdl_joystick); |
| 275 | 275 | ||
| 276 | std::shared_ptr<SDLJoystick> joystick; | 276 | std::lock_guard lock{joystick_map_mutex}; |
| 277 | { | 277 | auto& joystick_guid_list = joystick_map[guid]; |
| 278 | std::lock_guard lock{joystick_map_mutex}; | 278 | auto joystick_it = std::find_if( |
| 279 | // This call to guid is safe since the joystick is guaranteed to be in the map | 279 | joystick_guid_list.begin(), joystick_guid_list.end(), |
| 280 | const auto& joystick_guid_list = joystick_map[guid]; | 280 | [&sdl_joystick](auto& joystick) { return joystick->GetSDLJoystick() == sdl_joystick; }); |
| 281 | const auto joystick_it = | ||
| 282 | std::find_if(joystick_guid_list.begin(), joystick_guid_list.end(), | ||
| 283 | [&sdl_joystick](const std::shared_ptr<SDLJoystick>& joystick) { | ||
| 284 | return joystick->GetSDLJoystick() == sdl_joystick; | ||
| 285 | }); | ||
| 286 | joystick = *joystick_it; | ||
| 287 | } | ||
| 288 | 281 | ||
| 289 | // Destruct SDL_Joystick outside the lock guard because SDL can internally call the | 282 | if (joystick_it != joystick_guid_list.end()) { |
| 290 | // event callback which locks the mutex again. | 283 | (*joystick_it)->SetSDLJoystick(nullptr, nullptr); |
| 291 | joystick->SetSDLJoystick(nullptr, nullptr); | 284 | joystick_guid_list.erase(joystick_it); |
| 285 | if (joystick_guid_list.empty()) { | ||
| 286 | joystick_map.erase(guid); | ||
| 287 | } | ||
| 288 | } | ||
| 292 | } | 289 | } |
| 293 | 290 | ||
| 294 | void SDLState::HandleGameControllerEvent(const SDL_Event& event) { | 291 | void SDLState::HandleGameControllerEvent(const SDL_Event& event) { |
| @@ -392,8 +389,8 @@ private: | |||
| 392 | 389 | ||
| 393 | class SDLAnalog final : public Input::AnalogDevice { | 390 | class SDLAnalog final : public Input::AnalogDevice { |
| 394 | public: | 391 | public: |
| 395 | SDLAnalog(std::shared_ptr<SDLJoystick> joystick_, int axis_x_, int axis_y_, float deadzone_, | 392 | explicit SDLAnalog(std::shared_ptr<SDLJoystick> joystick_, int axis_x_, int axis_y_, |
| 396 | float range_) | 393 | float deadzone_, float range_) |
| 397 | : joystick(std::move(joystick_)), axis_x(axis_x_), axis_y(axis_y_), deadzone(deadzone_), | 394 | : joystick(std::move(joystick_)), axis_x(axis_x_), axis_y(axis_y_), deadzone(deadzone_), |
| 398 | range(range_) {} | 395 | range(range_) {} |
| 399 | 396 | ||
| @@ -672,13 +669,13 @@ SDLState::SDLState() { | |||
| 672 | RegisterFactory<ButtonDevice>("sdl", button_factory); | 669 | RegisterFactory<ButtonDevice>("sdl", button_factory); |
| 673 | RegisterFactory<MotionDevice>("sdl", motion_factory); | 670 | RegisterFactory<MotionDevice>("sdl", motion_factory); |
| 674 | 671 | ||
| 675 | // If the frontend is going to manage the event loop, then we dont start one here | 672 | // If the frontend is going to manage the event loop, then we don't start one here |
| 676 | start_thread = !SDL_WasInit(SDL_INIT_JOYSTICK); | 673 | start_thread = SDL_WasInit(SDL_INIT_JOYSTICK) == 0; |
| 677 | if (start_thread && SDL_Init(SDL_INIT_JOYSTICK) < 0) { | 674 | if (start_thread && SDL_Init(SDL_INIT_JOYSTICK) < 0) { |
| 678 | LOG_CRITICAL(Input, "SDL_Init(SDL_INIT_JOYSTICK) failed with: {}", SDL_GetError()); | 675 | LOG_CRITICAL(Input, "SDL_Init(SDL_INIT_JOYSTICK) failed with: {}", SDL_GetError()); |
| 679 | return; | 676 | return; |
| 680 | } | 677 | } |
| 681 | has_gamecontroller = SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER); | 678 | has_gamecontroller = SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER) != 0; |
| 682 | if (SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1") == SDL_FALSE) { | 679 | if (SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1") == SDL_FALSE) { |
| 683 | LOG_ERROR(Input, "Failed to set hint for background events with: {}", SDL_GetError()); | 680 | LOG_ERROR(Input, "Failed to set hint for background events with: {}", SDL_GetError()); |
| 684 | } | 681 | } |
| @@ -723,8 +720,8 @@ std::vector<Common::ParamPackage> SDLState::GetInputDevices() { | |||
| 723 | std::vector<Common::ParamPackage> devices; | 720 | std::vector<Common::ParamPackage> devices; |
| 724 | for (const auto& [key, value] : joystick_map) { | 721 | for (const auto& [key, value] : joystick_map) { |
| 725 | for (const auto& joystick : value) { | 722 | for (const auto& joystick : value) { |
| 726 | auto joy = joystick->GetSDLJoystick(); | 723 | auto* joy = joystick->GetSDLJoystick(); |
| 727 | if (auto controller = joystick->GetSDLGameController()) { | 724 | if (auto* controller = joystick->GetSDLGameController()) { |
| 728 | std::string name = | 725 | std::string name = |
| 729 | fmt::format("{} {}", SDL_GameControllerName(controller), joystick->GetPort()); | 726 | fmt::format("{} {}", SDL_GameControllerName(controller), joystick->GetPort()); |
| 730 | devices.emplace_back(Common::ParamPackage{ | 727 | devices.emplace_back(Common::ParamPackage{ |
| @@ -748,7 +745,7 @@ std::vector<Common::ParamPackage> SDLState::GetInputDevices() { | |||
| 748 | } | 745 | } |
| 749 | 746 | ||
| 750 | namespace { | 747 | namespace { |
| 751 | Common::ParamPackage BuildAnalogParamPackageForButton(int port, std::string guid, u8 axis, | 748 | Common::ParamPackage BuildAnalogParamPackageForButton(int port, std::string guid, s32 axis, |
| 752 | float value = 0.1f) { | 749 | float value = 0.1f) { |
| 753 | Common::ParamPackage params({{"engine", "sdl"}}); | 750 | Common::ParamPackage params({{"engine", "sdl"}}); |
| 754 | params.Set("port", port); | 751 | params.Set("port", port); |
| @@ -764,7 +761,7 @@ Common::ParamPackage BuildAnalogParamPackageForButton(int port, std::string guid | |||
| 764 | return params; | 761 | return params; |
| 765 | } | 762 | } |
| 766 | 763 | ||
| 767 | Common::ParamPackage BuildButtonParamPackageForButton(int port, std::string guid, u8 button) { | 764 | Common::ParamPackage BuildButtonParamPackageForButton(int port, std::string guid, s32 button) { |
| 768 | Common::ParamPackage params({{"engine", "sdl"}}); | 765 | Common::ParamPackage params({{"engine", "sdl"}}); |
| 769 | params.Set("port", port); | 766 | params.Set("port", port); |
| 770 | params.Set("guid", std::move(guid)); | 767 | params.Set("guid", std::move(guid)); |
| @@ -772,7 +769,7 @@ Common::ParamPackage BuildButtonParamPackageForButton(int port, std::string guid | |||
| 772 | return params; | 769 | return params; |
| 773 | } | 770 | } |
| 774 | 771 | ||
| 775 | Common::ParamPackage BuildHatParamPackageForButton(int port, std::string guid, u8 hat, u8 value) { | 772 | Common::ParamPackage BuildHatParamPackageForButton(int port, std::string guid, s32 hat, s32 value) { |
| 776 | Common::ParamPackage params({{"engine", "sdl"}}); | 773 | Common::ParamPackage params({{"engine", "sdl"}}); |
| 777 | 774 | ||
| 778 | params.Set("port", port); | 775 | params.Set("port", port); |
| @@ -802,17 +799,19 @@ Common::ParamPackage SDLEventToButtonParamPackage(SDLState& state, const SDL_Eve | |||
| 802 | case SDL_JOYAXISMOTION: { | 799 | case SDL_JOYAXISMOTION: { |
| 803 | const auto joystick = state.GetSDLJoystickBySDLID(event.jaxis.which); | 800 | const auto joystick = state.GetSDLJoystickBySDLID(event.jaxis.which); |
| 804 | return BuildAnalogParamPackageForButton(joystick->GetPort(), joystick->GetGUID(), | 801 | return BuildAnalogParamPackageForButton(joystick->GetPort(), joystick->GetGUID(), |
| 805 | event.jaxis.axis, event.jaxis.value); | 802 | static_cast<s32>(event.jaxis.axis), |
| 803 | event.jaxis.value); | ||
| 806 | } | 804 | } |
| 807 | case SDL_JOYBUTTONUP: { | 805 | case SDL_JOYBUTTONUP: { |
| 808 | const auto joystick = state.GetSDLJoystickBySDLID(event.jbutton.which); | 806 | const auto joystick = state.GetSDLJoystickBySDLID(event.jbutton.which); |
| 809 | return BuildButtonParamPackageForButton(joystick->GetPort(), joystick->GetGUID(), | 807 | return BuildButtonParamPackageForButton(joystick->GetPort(), joystick->GetGUID(), |
| 810 | event.jbutton.button); | 808 | static_cast<s32>(event.jbutton.button)); |
| 811 | } | 809 | } |
| 812 | case SDL_JOYHATMOTION: { | 810 | case SDL_JOYHATMOTION: { |
| 813 | const auto joystick = state.GetSDLJoystickBySDLID(event.jhat.which); | 811 | const auto joystick = state.GetSDLJoystickBySDLID(event.jhat.which); |
| 814 | return BuildHatParamPackageForButton(joystick->GetPort(), joystick->GetGUID(), | 812 | return BuildHatParamPackageForButton(joystick->GetPort(), joystick->GetGUID(), |
| 815 | event.jhat.hat, event.jhat.value); | 813 | static_cast<s32>(event.jhat.hat), |
| 814 | static_cast<s32>(event.jhat.value)); | ||
| 816 | } | 815 | } |
| 817 | } | 816 | } |
| 818 | return {}; | 817 | return {}; |
| @@ -823,17 +822,19 @@ Common::ParamPackage SDLEventToMotionParamPackage(SDLState& state, const SDL_Eve | |||
| 823 | case SDL_JOYAXISMOTION: { | 822 | case SDL_JOYAXISMOTION: { |
| 824 | const auto joystick = state.GetSDLJoystickBySDLID(event.jaxis.which); | 823 | const auto joystick = state.GetSDLJoystickBySDLID(event.jaxis.which); |
| 825 | return BuildAnalogParamPackageForButton(joystick->GetPort(), joystick->GetGUID(), | 824 | return BuildAnalogParamPackageForButton(joystick->GetPort(), joystick->GetGUID(), |
| 826 | event.jaxis.axis, event.jaxis.value); | 825 | static_cast<s32>(event.jaxis.axis), |
| 826 | event.jaxis.value); | ||
| 827 | } | 827 | } |
| 828 | case SDL_JOYBUTTONUP: { | 828 | case SDL_JOYBUTTONUP: { |
| 829 | const auto joystick = state.GetSDLJoystickBySDLID(event.jbutton.which); | 829 | const auto joystick = state.GetSDLJoystickBySDLID(event.jbutton.which); |
| 830 | return BuildButtonParamPackageForButton(joystick->GetPort(), joystick->GetGUID(), | 830 | return BuildButtonParamPackageForButton(joystick->GetPort(), joystick->GetGUID(), |
| 831 | event.jbutton.button); | 831 | static_cast<s32>(event.jbutton.button)); |
| 832 | } | 832 | } |
| 833 | case SDL_JOYHATMOTION: { | 833 | case SDL_JOYHATMOTION: { |
| 834 | const auto joystick = state.GetSDLJoystickBySDLID(event.jhat.which); | 834 | const auto joystick = state.GetSDLJoystickBySDLID(event.jhat.which); |
| 835 | return BuildHatParamPackageForButton(joystick->GetPort(), joystick->GetGUID(), | 835 | return BuildHatParamPackageForButton(joystick->GetPort(), joystick->GetGUID(), |
| 836 | event.jhat.hat, event.jhat.value); | 836 | static_cast<s32>(event.jhat.hat), |
| 837 | static_cast<s32>(event.jhat.value)); | ||
| 837 | } | 838 | } |
| 838 | } | 839 | } |
| 839 | return {}; | 840 | return {}; |
| @@ -1062,7 +1063,7 @@ public: | |||
| 1062 | if (event.type == SDL_JOYAXISMOTION) { | 1063 | if (event.type == SDL_JOYAXISMOTION) { |
| 1063 | const auto axis = event.jaxis.axis; | 1064 | const auto axis = event.jaxis.axis; |
| 1064 | const auto joystick = state.GetSDLJoystickBySDLID(event.jaxis.which); | 1065 | const auto joystick = state.GetSDLJoystickBySDLID(event.jaxis.which); |
| 1065 | const auto controller = joystick->GetSDLGameController(); | 1066 | auto* const controller = joystick->GetSDLGameController(); |
| 1066 | if (controller) { | 1067 | if (controller) { |
| 1067 | const auto axis_left_x = | 1068 | const auto axis_left_x = |
| 1068 | SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_LEFTX) | 1069 | SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_LEFTX) |