diff --git a/src/input_common/sdl/sdl.h b/src/input_common/sdl/sdl.h index d7f24c68a7..5306daa700 100644 --- a/src/input_common/sdl/sdl.h +++ b/src/input_common/sdl/sdl.h @@ -6,15 +6,8 @@ #include #include -#include "core/frontend/input.h" #include "input_common/main.h" -union SDL_Event; - -namespace Common { -class ParamPackage; -} // namespace Common - namespace InputCommon::Polling { class DevicePoller; enum class DeviceType; diff --git a/src/input_common/sdl/sdl_impl.cpp b/src/input_common/sdl/sdl_impl.cpp index 0b69bfede5..d2e9d278fa 100644 --- a/src/input_common/sdl/sdl_impl.cpp +++ b/src/input_common/sdl/sdl_impl.cpp @@ -6,7 +6,6 @@ #include #include #include -#include #include #include #include @@ -15,7 +14,6 @@ #include #include #include -#include "common/assert.h" #include "common/logging/log.h" #include "common/math_util.h" #include "common/param_package.h" @@ -23,12 +21,10 @@ #include "core/frontend/input.h" #include "input_common/sdl/sdl_impl.h" -namespace InputCommon { - -namespace SDL { +namespace InputCommon::SDL { static std::string GetGUID(SDL_Joystick* joystick) { - SDL_JoystickGUID guid = SDL_JoystickGetGUID(joystick); + const SDL_JoystickGUID guid = SDL_JoystickGetGUID(joystick); char guid_str[33]; SDL_JoystickGetGUIDString(guid, guid_str, sizeof(guid_str)); return guid_str; @@ -37,26 +33,27 @@ static std::string GetGUID(SDL_Joystick* joystick) { /// Creates a ParamPackage from an SDL_Event that can directly be used to create a ButtonDevice static Common::ParamPackage SDLEventToButtonParamPackage(SDLState& state, const SDL_Event& event); -static int SDLEventWatcher(void* userdata, SDL_Event* event) { - SDLState* sdl_state = reinterpret_cast(userdata); +static int SDLEventWatcher(void* user_data, SDL_Event* event) { + auto* const sdl_state = static_cast(user_data); + // Don't handle the event if we are configuring if (sdl_state->polling) { sdl_state->event_queue.Push(*event); } else { sdl_state->HandleGameControllerEvent(*event); } + return 0; } class SDLJoystick { public: - SDLJoystick(std::string guid_, int port_, SDL_Joystick* joystick, - decltype(&SDL_JoystickClose) deleter = &SDL_JoystickClose) - : guid{std::move(guid_)}, port{port_}, sdl_joystick{joystick, deleter} {} + SDLJoystick(std::string guid_, int port_, SDL_Joystick* joystick) + : guid{std::move(guid_)}, port{port_}, sdl_joystick{joystick, &SDL_JoystickClose} {} void SetButton(int button, bool value) { std::lock_guard lock{mutex}; - state.buttons[button] = value; + state.buttons.insert_or_assign(button, value); } bool GetButton(int button) const { @@ -66,7 +63,7 @@ public: void SetAxis(int axis, Sint16 value) { std::lock_guard lock{mutex}; - state.axes[axis] = value; + state.axes.insert_or_assign(axis, value); } float GetAxis(int axis) const { @@ -93,7 +90,7 @@ public: void SetHat(int hat, Uint8 direction) { std::lock_guard lock{mutex}; - state.hats[hat] = direction; + state.hats.insert_or_assign(hat, direction); } bool GetHatDirection(int hat, Uint8 direction) const { @@ -118,10 +115,8 @@ public: return sdl_joystick.get(); } - void SetSDLJoystick(SDL_Joystick* joystick, - decltype(&SDL_JoystickClose) deleter = &SDL_JoystickClose) { - sdl_joystick = - std::unique_ptr(joystick, deleter); + void SetSDLJoystick(SDL_Joystick* joystick) { + sdl_joystick.reset(joystick); } private: @@ -136,59 +131,57 @@ private: mutable std::mutex mutex; }; -/** - * Get the nth joystick with the corresponding GUID - */ std::shared_ptr SDLState::GetSDLJoystickByGUID(const std::string& guid, int port) { std::lock_guard lock{joystick_map_mutex}; const auto it = joystick_map.find(guid); if (it != joystick_map.end()) { while (it->second.size() <= static_cast(port)) { - auto joystick = std::make_shared(guid, static_cast(it->second.size()), - nullptr, [](SDL_Joystick*) {}); + auto joystick = + std::make_shared(guid, static_cast(it->second.size()), nullptr); it->second.emplace_back(std::move(joystick)); } return it->second[port]; } - auto joystick = std::make_shared(guid, 0, nullptr, [](SDL_Joystick*) {}); + auto joystick = std::make_shared(guid, 0, nullptr); return joystick_map[guid].emplace_back(std::move(joystick)); } -/** - * Check how many identical joysticks (by guid) were connected before the one with sdl_id and so tie - * it to a SDLJoystick with the same guid and that port - */ std::shared_ptr SDLState::GetSDLJoystickBySDLID(SDL_JoystickID sdl_id) { auto sdl_joystick = SDL_JoystickFromInstanceID(sdl_id); const std::string guid = GetGUID(sdl_joystick); std::lock_guard lock{joystick_map_mutex}; - auto map_it = joystick_map.find(guid); + const auto map_it = joystick_map.find(guid); if (map_it != joystick_map.end()) { - auto vec_it = std::find_if(map_it->second.begin(), map_it->second.end(), - [&sdl_joystick](const std::shared_ptr& joystick) { - return sdl_joystick == joystick->GetSDLJoystick(); - }); + const auto vec_it = + std::find_if(map_it->second.begin(), map_it->second.end(), + [&sdl_joystick](const std::shared_ptr& joystick) { + return sdl_joystick == joystick->GetSDLJoystick(); + }); if (vec_it != map_it->second.end()) { // This is the common case: There is already an existing SDL_Joystick maped to a // SDLJoystick. return the SDLJoystick return *vec_it; } + // Search for a SDLJoystick without a mapped SDL_Joystick... - auto nullptr_it = std::find_if(map_it->second.begin(), map_it->second.end(), - [](const std::shared_ptr& joystick) { - return !joystick->GetSDLJoystick(); - }); + const auto nullptr_it = std::find_if(map_it->second.begin(), map_it->second.end(), + [](const std::shared_ptr& joystick) { + return !joystick->GetSDLJoystick(); + }); if (nullptr_it != map_it->second.end()) { // ... and map it (*nullptr_it)->SetSDLJoystick(sdl_joystick); return *nullptr_it; } + // There is no SDLJoystick without a mapped SDL_Joystick // Create a new SDLJoystick - auto joystick = std::make_shared(guid, map_it->second.size(), sdl_joystick); + const int port = static_cast(map_it->second.size()); + auto joystick = std::make_shared(guid, port, sdl_joystick); return map_it->second.emplace_back(std::move(joystick)); } + auto joystick = std::make_shared(guid, 0, sdl_joystick); return joystick_map[guid].emplace_back(std::move(joystick)); } @@ -215,17 +208,19 @@ void SDLState::InitJoystick(int joystick_index) { (*it)->SetSDLJoystick(sdl_joystick); return; } - auto joystick = std::make_shared(guid, joystick_guid_list.size(), sdl_joystick); + const int port = static_cast(joystick_guid_list.size()); + auto joystick = std::make_shared(guid, port, sdl_joystick); joystick_guid_list.emplace_back(std::move(joystick)); } void SDLState::CloseJoystick(SDL_Joystick* sdl_joystick) { - std::string guid = GetGUID(sdl_joystick); + const std::string guid = GetGUID(sdl_joystick); + std::shared_ptr joystick; { std::lock_guard lock{joystick_map_mutex}; // This call to guid is safe since the joystick is guaranteed to be in the map - auto& joystick_guid_list = joystick_map[guid]; + const auto& joystick_guid_list = joystick_map[guid]; const auto joystick_it = std::find_if(joystick_guid_list.begin(), joystick_guid_list.end(), [&sdl_joystick](const std::shared_ptr& joystick) { @@ -233,9 +228,10 @@ void SDLState::CloseJoystick(SDL_Joystick* sdl_joystick) { }); joystick = *joystick_it; } - // Destruct SDL_Joystick outside the lock guard because SDL can internally call event calback - // which locks the mutex again - joystick->SetSDLJoystick(nullptr, [](SDL_Joystick*) {}); + + // Destruct SDL_Joystick outside the lock guard because SDL can internally call the + // event callback which locks the mutex again. + joystick->SetSDLJoystick(nullptr); } void SDLState::HandleGameControllerEvent(const SDL_Event& event) { @@ -317,9 +313,10 @@ public: trigger_if_greater(trigger_if_greater_) {} bool GetStatus() const override { - float axis_value = joystick->GetAxis(axis); - if (trigger_if_greater) + const float axis_value = joystick->GetAxis(axis); + if (trigger_if_greater) { return axis_value > threshold; + } return axis_value < threshold; } @@ -444,7 +441,7 @@ public: const int port = params.Get("port", 0); const int axis_x = params.Get("axis_x", 0); const int axis_y = params.Get("axis_y", 1); - float deadzone = std::clamp(params.Get("deadzone", 0.0f), 0.0f, .99f); + const float deadzone = std::clamp(params.Get("deadzone", 0.0f), 0.0f, .99f); auto joystick = state.GetSDLJoystickByGUID(guid, port); @@ -470,7 +467,7 @@ SDLState::SDLState() { return; } if (SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1") == SDL_FALSE) { - LOG_ERROR(Input, "Failed to set Hint for background events", SDL_GetError()); + LOG_ERROR(Input, "Failed to set hint for background events with: {}", SDL_GetError()); } SDL_AddEventWatch(&SDLEventWatcher, this); @@ -507,12 +504,12 @@ SDLState::~SDLState() { } } -Common::ParamPackage SDLEventToButtonParamPackage(SDLState& state, const SDL_Event& event) { +static Common::ParamPackage SDLEventToButtonParamPackage(SDLState& state, const SDL_Event& event) { Common::ParamPackage params({{"engine", "sdl"}}); switch (event.type) { case SDL_JOYAXISMOTION: { - auto joystick = state.GetSDLJoystickBySDLID(event.jaxis.which); + const auto joystick = state.GetSDLJoystickBySDLID(event.jaxis.which); params.Set("port", joystick->GetPort()); params.Set("guid", joystick->GetGUID()); params.Set("axis", event.jaxis.axis); @@ -526,14 +523,14 @@ Common::ParamPackage SDLEventToButtonParamPackage(SDLState& state, const SDL_Eve break; } case SDL_JOYBUTTONUP: { - auto joystick = state.GetSDLJoystickBySDLID(event.jbutton.which); + const auto joystick = state.GetSDLJoystickBySDLID(event.jbutton.which); params.Set("port", joystick->GetPort()); params.Set("guid", joystick->GetGUID()); params.Set("button", event.jbutton.button); break; } case SDL_JOYHATMOTION: { - auto joystick = state.GetSDLJoystickBySDLID(event.jhat.which); + const auto joystick = state.GetSDLJoystickBySDLID(event.jhat.which); params.Set("port", joystick->GetPort()); params.Set("guid", joystick->GetGUID()); params.Set("hat", event.jhat.hat); @@ -607,8 +604,8 @@ public: SDLPoller::Start(); // Reset stored axes - analog_xaxis = -1; - analog_yaxis = -1; + analog_x_axis = -1; + analog_y_axis = -1; analog_axes_joystick = -1; } @@ -620,25 +617,25 @@ public: } // An analog device needs two axes, so we need to store the axis for later and wait for // a second SDL event. The axes also must be from the same joystick. - int axis = event.jaxis.axis; - if (analog_xaxis == -1) { - analog_xaxis = axis; + const int axis = event.jaxis.axis; + if (analog_x_axis == -1) { + analog_x_axis = axis; analog_axes_joystick = event.jaxis.which; - } else if (analog_yaxis == -1 && analog_xaxis != axis && + } else if (analog_y_axis == -1 && analog_x_axis != axis && analog_axes_joystick == event.jaxis.which) { - analog_yaxis = axis; + analog_y_axis = axis; } } Common::ParamPackage params; - if (analog_xaxis != -1 && analog_yaxis != -1) { - auto joystick = state.GetSDLJoystickBySDLID(event.jaxis.which); + if (analog_x_axis != -1 && analog_y_axis != -1) { + const auto joystick = state.GetSDLJoystickBySDLID(event.jaxis.which); params.Set("engine", "sdl"); params.Set("port", joystick->GetPort()); params.Set("guid", joystick->GetGUID()); - params.Set("axis_x", analog_xaxis); - params.Set("axis_y", analog_yaxis); - analog_xaxis = -1; - analog_yaxis = -1; + params.Set("axis_x", analog_x_axis); + params.Set("axis_y", analog_y_axis); + analog_x_axis = -1; + analog_y_axis = -1; analog_axes_joystick = -1; return params; } @@ -646,8 +643,8 @@ public: } private: - int analog_xaxis = -1; - int analog_yaxis = -1; + int analog_x_axis = -1; + int analog_y_axis = -1; SDL_JoystickID analog_axes_joystick = -1; }; } // namespace Polling @@ -667,5 +664,4 @@ SDLState::Pollers SDLState::GetPollers(InputCommon::Polling::DeviceType type) { return pollers; } -} // namespace SDL -} // namespace InputCommon +} // namespace InputCommon::SDL diff --git a/src/input_common/sdl/sdl_impl.h b/src/input_common/sdl/sdl_impl.h index 2579741d65..606a32c5b4 100644 --- a/src/input_common/sdl/sdl_impl.h +++ b/src/input_common/sdl/sdl_impl.h @@ -6,7 +6,10 @@ #include #include +#include #include +#include +#include "common/common_types.h" #include "common/threadsafe_queue.h" #include "input_common/sdl/sdl.h" @@ -16,9 +19,9 @@ using SDL_JoystickID = s32; namespace InputCommon::SDL { -class SDLJoystick; -class SDLButtonFactory; class SDLAnalogFactory; +class SDLButtonFactory; +class SDLJoystick; class SDLState : public State { public: @@ -31,7 +34,13 @@ public: /// Handle SDL_Events for joysticks from SDL_PollEvent void HandleGameControllerEvent(const SDL_Event& event); + /// Get the nth joystick with the corresponding GUID std::shared_ptr GetSDLJoystickBySDLID(SDL_JoystickID sdl_id); + + /** + * Check how many identical joysticks (by guid) were connected before the one with sdl_id and so + * tie it to a SDLJoystick with the same guid and that port + */ std::shared_ptr GetSDLJoystickByGUID(const std::string& guid, int port); /// Get all DevicePoller that use the SDL backend for a specific device type