SDLInputSource: Use controller information for icons

This commit is contained in:
TheLastRar 2025-02-16 22:14:28 +00:00
parent 919ebd0190
commit edd98128e7
3 changed files with 186 additions and 22 deletions

View File

@ -489,7 +489,7 @@ bool ImGuiManager::AddIconFonts(float size)
{
// clang-format off
static constexpr ImWchar range_fa[] = { 0xe06f,0xe06f,0xf002,0xf002,0xf005,0xf005,0xf007,0xf007,0xf00c,0xf00e,0xf011,0xf011,0xf013,0xf013,0xf017,0xf017,0xf019,0xf019,0xf021,0xf023,0xf025,0xf028,0xf02b,0xf02b,0xf02e,0xf02e,0xf030,0xf030,0xf03a,0xf03a,0xf03d,0xf03e,0xf04b,0xf04c,0xf04e,0xf04e,0xf050,0xf050,0xf052,0xf052,0xf05a,0xf05a,0xf05e,0xf05e,0xf063,0xf063,0xf067,0xf067,0xf06a,0xf06a,0xf06e,0xf06e,0xf071,0xf071,0xf077,0xf078,0xf07b,0xf07c,0xf084,0xf084,0xf091,0xf091,0xf0ac,0xf0ad,0xf0b0,0xf0b0,0xf0c5,0xf0c5,0xf0c7,0xf0c8,0xf0cb,0xf0cb,0xf0d0,0xf0d0,0xf0dc,0xf0dc,0xf0e2,0xf0e2,0xf0eb,0xf0eb,0xf0f3,0xf0f3,0xf0fe,0xf0fe,0xf11b,0xf11c,0xf120,0xf121,0xf129,0xf12a,0xf140,0xf140,0xf14a,0xf14a,0xf15b,0xf15b,0xf15d,0xf15d,0xf187,0xf188,0xf191,0xf192,0xf1b3,0xf1b3,0xf1de,0xf1de,0xf1e6,0xf1e6,0xf1ea,0xf1eb,0xf1f8,0xf1f8,0xf1fc,0xf1fc,0xf21e,0xf21e,0xf245,0xf245,0xf26c,0xf26c,0xf279,0xf279,0xf2bd,0xf2bd,0xf2db,0xf2db,0xf2f2,0xf2f2,0xf302,0xf302,0xf3c1,0xf3c1,0xf3fd,0xf3fd,0xf410,0xf410,0xf462,0xf462,0xf466,0xf466,0xf4e2,0xf4e2,0xf51f,0xf51f,0xf545,0xf545,0xf54c,0xf54c,0xf553,0xf553,0xf56d,0xf56d,0xf5a2,0xf5a2,0xf65d,0xf65e,0xf6a9,0xf6a9,0xf70e,0xf70e,0xf756,0xf756,0xf780,0xf780,0xf794,0xf794,0xf815,0xf815,0xf84c,0xf84c,0xf8cc,0xf8cc,0x0,0x0 };
static constexpr ImWchar range_pf[] = { 0x2198,0x2199,0x219e,0x21a3,0x21b0,0x21b3,0x21ba,0x21c3,0x21ce,0x21ce,0x21d0,0x21d4,0x21dc,0x21dd,0x21e0,0x21e3,0x21f3,0x21f3,0x21f7,0x21f8,0x21fa,0x21fb,0x221a,0x221a,0x227a,0x227d,0x22bf,0x22c8,0x2349,0x2349,0x235a,0x235e,0x2360,0x2361,0x2364,0x2367,0x237a,0x237b,0x237d,0x237d,0x237f,0x237f,0x23b2,0x23b5,0x23cc,0x23cc,0x23f4,0x23f7,0x2427,0x243a,0x243d,0x243d,0x2443,0x2443,0x2460,0x246b,0x248f,0x248f,0x24f5,0x24fd,0x24ff,0x24ff,0x2605,0x2605,0x2699,0x2699,0x278a,0x278e,0xe001,0xe001,0xff21,0xff3a,0x0,0x0 };
static constexpr ImWchar range_pf[] = { 0x2198,0x2199,0x219e,0x21a7,0x21b0,0x21b3,0x21ba,0x21c3,0x21ce,0x21ce,0x21d0,0x21d4,0x21dc,0x21dd,0x21e0,0x21e3,0x21e6,0x21e8,0x21f3,0x21f3,0x21f7,0x21f8,0x21fa,0x21fb,0x2206,0x2208,0x221a,0x221a,0x227a,0x227d,0x22bf,0x22c8,0x2349,0x2349,0x235a,0x235e,0x2360,0x2361,0x2364,0x2367,0x237a,0x237b,0x237d,0x237d,0x237f,0x237f,0x23b2,0x23b5,0x23cc,0x23cc,0x23f4,0x23f7,0x2427,0x243a,0x243d,0x243d,0x2443,0x2443,0x2460,0x246b,0x248f,0x248f,0x24f5,0x24fd,0x24ff,0x24ff,0x2605,0x2605,0x2699,0x2699,0x278a,0x278e,0xe000,0xe001,0xff21,0xff3a,0x0,0x0 };
// clang-format on
{

View File

@ -33,9 +33,28 @@ static constexpr const char* s_sdl_axis_icons[][2] = {
{ICON_PF_LEFT_ANALOG_UP, ICON_PF_LEFT_ANALOG_DOWN}, // SDL_GAMEPAD_AXIS_LEFTY
{ICON_PF_RIGHT_ANALOG_LEFT, ICON_PF_RIGHT_ANALOG_RIGHT}, // SDL_GAMEPAD_AXIS_RIGHTX
{ICON_PF_RIGHT_ANALOG_UP, ICON_PF_RIGHT_ANALOG_DOWN}, // SDL_GAMEPAD_AXIS_RIGHTY
{nullptr, ICON_PF_LEFT_TRIGGER_PULL}, // SDL_GAMEPAD_AXIS_LEFT_TRIGGER
{nullptr, ICON_PF_RIGHT_TRIGGER_PULL}, // SDL_GAMEPAD_AXIS_RIGHT_TRIGGER
};
static constexpr const char* s_sdl_trigger_icons[] = {
ICON_PF_LEFT_TRIGGER_PULL, // SDL_GAMEPAD_AXIS_LEFT_TRIGGER
ICON_PF_RIGHT_TRIGGER_PULL, // SDL_GAMEPAD_AXIS_RIGHT_TRIGGER
};
static constexpr const char* s_sdl_trigger_ps_icons[] = {
ICON_PF_LEFT_TRIGGER_L2, // SDL_GAMEPAD_AXIS_LEFT_TRIGGER
ICON_PF_RIGHT_TRIGGER_R2, // SDL_GAMEPAD_AXIS_RIGHT_TRIGGER
};
static const char* const* s_sdl_trigger_icons_list[] = {
s_sdl_trigger_icons, // SDL_GAMEPAD_TYPE_UNKNOWN
s_sdl_trigger_icons, // SDL_GAMEPAD_TYPE_STANDARD
s_sdl_trigger_icons, // SDL_GAMEPAD_TYPE_XBOX360
s_sdl_trigger_icons, // SDL_GAMEPAD_TYPE_XBOXONE
s_sdl_trigger_ps_icons, // SDL_GAMEPAD_TYPE_PS3
s_sdl_trigger_ps_icons, // SDL_GAMEPAD_TYPE_PS4
s_sdl_trigger_ps_icons, // SDL_GAMEPAD_TYPE_PS5
// Switch
};
static constexpr const GenericInputBinding s_sdl_generic_binding_axis_mapping[][2] = {
{GenericInputBinding::LeftStickLeft, GenericInputBinding::LeftStickRight}, // SDL_GAMEPAD_AXIS_LEFTX
{GenericInputBinding::LeftStickUp, GenericInputBinding::LeftStickDown}, // SDL_GAMEPAD_AXIS_LEFTY
@ -68,11 +87,23 @@ static constexpr const char* s_sdl_button_names[] = {
"Paddle4", // SDL_GAMEPAD_BUTTON_LEFT_PADDLE2
"Touchpad", // SDL_GAMEPAD_BUTTON_TOUCHPAD
};
static constexpr const char* s_sdl_face_button_icons[] = {
nullptr, // SDL_GAMEPAD_BUTTON_LABEL_UNKNOWN
ICON_PF_BUTTON_A, // SDL_GAMEPAD_BUTTON_LABEL_A
ICON_PF_BUTTON_B, // SDL_GAMEPAD_BUTTON_LABEL_B
ICON_PF_BUTTON_X, // SDL_GAMEPAD_BUTTON_LABEL_X
ICON_PF_BUTTON_Y, // SDL_GAMEPAD_BUTTON_LABEL_Y
ICON_PF_BUTTON_CROSS, // SDL_GAMEPAD_BUTTON_LABEL_CROSS
ICON_PF_BUTTON_CIRCLE, // SDL_GAMEPAD_BUTTON_LABEL_CIRCLE
ICON_PF_BUTTON_SQUARE, // SDL_GAMEPAD_BUTTON_LABEL_SQUARE
ICON_PF_BUTTON_TRIANGLE, // SDL_GAMEPAD_BUTTON_LABEL_TRIANGLE
};
static constexpr const char* s_sdl_button_icons[] = {
ICON_PF_BUTTON_A, // SDL_GAMEPAD_BUTTON_SOUTH
ICON_PF_BUTTON_B, // SDL_GAMEPAD_BUTTON_EAST
ICON_PF_BUTTON_X, // SDL_GAMEPAD_BUTTON_WEST
ICON_PF_BUTTON_Y, // SDL_GAMEPAD_BUTTON_NORTH
ICON_PF_BUTTON_DOWN_A, // SDL_GAMEPAD_BUTTON_SOUTH
ICON_PF_BUTTON_RIGHT_B, // SDL_GAMEPAD_BUTTON_EAST
ICON_PF_BUTTON_LEFT_X, // SDL_GAMEPAD_BUTTON_WEST
ICON_PF_BUTTON_UP_Y, // SDL_GAMEPAD_BUTTON_NORTH
ICON_PF_SHARE_CAPTURE, // SDL_GAMEPAD_BUTTON_BACK
ICON_PF_XBOX, // SDL_GAMEPAD_BUTTON_GUIDE
ICON_PF_BURGER_MENU, // SDL_GAMEPAD_BUTTON_START
@ -85,6 +116,91 @@ static constexpr const char* s_sdl_button_icons[] = {
ICON_PF_XBOX_DPAD_LEFT, // SDL_GAMEPAD_BUTTON_DPAD_LEFT
ICON_PF_XBOX_DPAD_RIGHT, // SDL_GAMEPAD_BUTTON_DPAD_RIGHT
};
static constexpr const char* s_sdl_button_ps3_icons[] = {
ICON_PF_BUTTON_CROSS, // SDL_GAMEPAD_BUTTON_SOUTH
ICON_PF_BUTTON_CIRCLE, // SDL_GAMEPAD_BUTTON_EAST
ICON_PF_BUTTON_SQUARE, // SDL_GAMEPAD_BUTTON_WEST
ICON_PF_BUTTON_TRIANGLE, // SDL_GAMEPAD_BUTTON_NORTH
ICON_PF_SELECT_SHARE, // SDL_GAMEPAD_BUTTON_BACK
ICON_PF_XBOX, // SDL_GAMEPAD_BUTTON_GUIDE
ICON_PF_START, // SDL_GAMEPAD_BUTTON_START
ICON_PF_LEFT_ANALOG_CLICK, // SDL_GAMEPAD_BUTTON_LEFT_STICK
ICON_PF_RIGHT_ANALOG_CLICK, // SDL_GAMEPAD_BUTTON_RIGHT_STICK
ICON_PF_LEFT_SHOULDER_L1, // SDL_GAMEPAD_BUTTON_LEFT_SHOULDER
ICON_PF_RIGHT_SHOULDER_R1, // SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER
ICON_PF_DPAD_UP, // SDL_GAMEPAD_BUTTON_DPAD_UP
ICON_PF_DPAD_DOWN, // SDL_GAMEPAD_BUTTON_DPAD_DOWN
ICON_PF_DPAD_LEFT, // SDL_GAMEPAD_BUTTON_DPAD_LEFT
ICON_PF_DPAD_RIGHT, // SDL_GAMEPAD_BUTTON_DPAD_RIGHT
};
static constexpr const char* s_sdl_button_ps4_icons[] = {
ICON_PF_BUTTON_CROSS, // SDL_GAMEPAD_BUTTON_SOUTH
ICON_PF_BUTTON_CIRCLE, // SDL_GAMEPAD_BUTTON_EAST
ICON_PF_BUTTON_SQUARE, // SDL_GAMEPAD_BUTTON_WEST
ICON_PF_BUTTON_TRIANGLE, // SDL_GAMEPAD_BUTTON_NORTH
ICON_PF_DUALSHOCK_SHARE, // SDL_GAMEPAD_BUTTON_BACK
ICON_PF_PLAYSTATION, // SDL_GAMEPAD_BUTTON_GUIDE
ICON_PF_DUALSHOCK_OPTIONS, // SDL_GAMEPAD_BUTTON_START
ICON_PF_LEFT_ANALOG_CLICK, // SDL_GAMEPAD_BUTTON_LEFT_STICK
ICON_PF_RIGHT_ANALOG_CLICK, // SDL_GAMEPAD_BUTTON_RIGHT_STICK
ICON_PF_LEFT_SHOULDER_L1, // SDL_GAMEPAD_BUTTON_LEFT_SHOULDER
ICON_PF_RIGHT_SHOULDER_R1, // SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER
ICON_PF_DPAD_UP, // SDL_GAMEPAD_BUTTON_DPAD_UP
ICON_PF_DPAD_DOWN, // SDL_GAMEPAD_BUTTON_DPAD_DOWN
ICON_PF_DPAD_LEFT, // SDL_GAMEPAD_BUTTON_DPAD_LEFT
ICON_PF_DPAD_RIGHT, // SDL_GAMEPAD_BUTTON_DPAD_RIGHT
nullptr, // SDL_GAMEPAD_BUTTON_MISC1
nullptr, // SDL_GAMEPAD_BUTTON_RIGHT_PADDLE1
nullptr, // SDL_GAMEPAD_BUTTON_LEFT_PADDLE1
nullptr, // SDL_GAMEPAD_BUTTON_RIGHT_PADDLE2
nullptr, // SDL_GAMEPAD_BUTTON_LEFT_PADDLE2
ICON_PF_DUALSHOCK_TOUCHPAD, // SDL_GAMEPAD_BUTTON_TOUCHPAD
};
static constexpr const char* s_sdl_button_ps5_icons[] = {
ICON_PF_BUTTON_CROSS, // SDL_GAMEPAD_BUTTON_SOUTH
ICON_PF_BUTTON_CIRCLE, // SDL_GAMEPAD_BUTTON_EAST
ICON_PF_BUTTON_SQUARE, // SDL_GAMEPAD_BUTTON_WEST
ICON_PF_BUTTON_TRIANGLE, // SDL_GAMEPAD_BUTTON_NORTH
ICON_PF_DUALSENSE_SHARE, // SDL_GAMEPAD_BUTTON_BACK
ICON_PF_PLAYSTATION, // SDL_GAMEPAD_BUTTON_GUIDE
ICON_PF_DUALSENSE_OPTIONS, // SDL_GAMEPAD_BUTTON_START
ICON_PF_LEFT_ANALOG_CLICK, // SDL_GAMEPAD_BUTTON_LEFT_STICK
ICON_PF_RIGHT_ANALOG_CLICK, // SDL_GAMEPAD_BUTTON_RIGHT_STICK
ICON_PF_LEFT_SHOULDER_L1, // SDL_GAMEPAD_BUTTON_LEFT_SHOULDER
ICON_PF_RIGHT_SHOULDER_R1, // SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER
ICON_PF_DPAD_UP, // SDL_GAMEPAD_BUTTON_DPAD_UP
ICON_PF_DPAD_DOWN, // SDL_GAMEPAD_BUTTON_DPAD_DOWN
ICON_PF_DPAD_LEFT, // SDL_GAMEPAD_BUTTON_DPAD_LEFT
ICON_PF_DPAD_RIGHT, // SDL_GAMEPAD_BUTTON_DPAD_RIGHT
nullptr, // SDL_GAMEPAD_BUTTON_MISC1
nullptr, // SDL_GAMEPAD_BUTTON_RIGHT_PADDLE1
nullptr, // SDL_GAMEPAD_BUTTON_LEFT_PADDLE1
nullptr, // SDL_GAMEPAD_BUTTON_RIGHT_PADDLE2
nullptr, // SDL_GAMEPAD_BUTTON_LEFT_PADDLE2
ICON_PF_DUALSENSE_TOUCHPAD, // SDL_GAMEPAD_BUTTON_TOUCHPAD
};
static constexpr const char* const* s_sdl_button_icons_list[] = {
s_sdl_button_icons, // SDL_GAMEPAD_TYPE_UNKNOWN
s_sdl_button_icons, // SDL_GAMEPAD_TYPE_STANDARD
s_sdl_button_icons, // SDL_GAMEPAD_TYPE_XBOX360
s_sdl_button_icons, // SDL_GAMEPAD_TYPE_XBOXONE
s_sdl_button_ps3_icons, // SDL_GAMEPAD_TYPE_PS3
s_sdl_button_ps4_icons, // SDL_GAMEPAD_TYPE_PS4
s_sdl_button_ps5_icons, // SDL_GAMEPAD_TYPE_PS5
// Switch
};
static constexpr size_t s_sdl_button_iconsize_list[] = {
std::size(s_sdl_button_icons), // SDL_GAMEPAD_TYPE_UNKNOWN
std::size(s_sdl_button_icons), // SDL_GAMEPAD_TYPE_STANDARD
std::size(s_sdl_button_icons), // SDL_GAMEPAD_TYPE_XBOX360
std::size(s_sdl_button_icons), // SDL_GAMEPAD_TYPE_XBOXONE
std::size(s_sdl_button_ps3_icons), // SDL_GAMEPAD_TYPE_PS3
std::size(s_sdl_button_ps4_icons), // SDL_GAMEPAD_TYPE_PS4
std::size(s_sdl_button_ps5_icons), // SDL_GAMEPAD_TYPE_PS5
// Switch
};
static constexpr const GenericInputBinding s_sdl_generic_binding_button_mapping[] = {
GenericInputBinding::Cross, // SDL_GAMEPAD_BUTTON_SOUTH
GenericInputBinding::Circle, // SDL_GAMEPAD_BUTTON_EAST
@ -543,17 +659,52 @@ TinyString SDLInputSource::ConvertKeyToIcon(InputBindingKey key)
if (key.source_type == InputSourceType::SDL)
{
std::lock_guard lock(m_controllers_key_mutex);
SDL_GamepadType type = SDL_GAMEPAD_TYPE_UNKNOWN;
auto it = GetControllerDataForPlayerId(key.source_index);
if (it != m_controllers.end())
type = SDL_GetRealGamepadType(it->gamepad);
if (key.source_subtype == InputSubclass::ControllerAxis)
{
if (key.data < std::size(s_sdl_axis_icons) && key.modifier != InputModifier::FullAxis)
if (key.modifier != InputModifier::FullAxis)
{
ret.format("SDL-{} {}", static_cast<u32>(key.source_index),
s_sdl_axis_icons[key.data][key.modifier == InputModifier::None]);
if (key.data < std::size(s_sdl_axis_icons))
{
ret.format("SDL-{} {}", static_cast<u32>(key.source_index),
s_sdl_axis_icons[key.data][key.modifier == InputModifier::None]);
}
else if (key.data - std::size(s_sdl_axis_icons) < std::size(s_sdl_trigger_icons))
{
const u32 trigger_index = key.data - std::size(s_sdl_axis_icons);
if (type < std::size(s_sdl_button_icons_list))
ret.format("SDL-{} {}", static_cast<u32>(key.source_index), s_sdl_trigger_icons_list[type][trigger_index]);
else
ret.format("SDL-{} {}", static_cast<u32>(key.source_index), s_sdl_trigger_icons[trigger_index]);
}
}
}
else if (key.source_subtype == InputSubclass::ControllerButton)
{
if (key.data < std::size(s_sdl_button_icons))
if (type > SDL_GAMEPAD_TYPE_STANDARD && type < std::size(s_sdl_button_icons_list))
{
if (key.data < s_sdl_button_iconsize_list[type] && s_sdl_button_icons_list[type][key.data] != nullptr)
ret.format("SDL-{} {}", static_cast<u32>(key.source_index), s_sdl_button_icons_list[type][key.data]);
}
else if (key.data < 4)
{
SDL_GamepadButtonLabel label = SDL_GAMEPAD_BUTTON_LABEL_UNKNOWN;
if (it != m_controllers.end() && it->gamepad)
label = SDL_GetGamepadButtonLabel(it->gamepad, static_cast<SDL_GamepadButton>(key.data));
if (label > SDL_GAMEPAD_BUTTON_LABEL_UNKNOWN && label < std::size(s_sdl_face_button_icons))
ret.format("SDL-{} {}", static_cast<u32>(key.source_index), s_sdl_face_button_icons[label]);
else
ret.format("SDL-{} {}", static_cast<u32>(key.source_index), s_sdl_button_icons[key.data]);
}
else if (key.data < std::size(s_sdl_button_icons))
ret.format("SDL-{} {}", static_cast<u32>(key.source_index), s_sdl_button_icons[key.data]);
}
}
@ -822,7 +973,10 @@ bool SDLInputSource::OpenDevice(int index, bool is_gamepad)
}
}
m_controllers.push_back(std::move(cd));
{
std::unique_lock lock(m_controllers_key_mutex);
m_controllers.push_back(std::move(cd));
}
InputManager::OnInputDeviceConnected(fmt::format("SDL-{}", player_id), name);
return true;
@ -834,19 +988,23 @@ bool SDLInputSource::CloseDevice(int joystick_index)
if (it == m_controllers.end())
return false;
InputManager::OnInputDeviceDisconnected(
{InputBindingKey{.source_type = InputSourceType::SDL, .source_index = static_cast<u32>(it->player_id)}},
fmt::format("SDL-{}", it->player_id));
{
std::lock_guard lock(m_controllers_key_mutex);
InputManager::OnInputDeviceDisconnected(
{InputBindingKey{.source_type = InputSourceType::SDL, .source_index = static_cast<u32>(it->player_id)}},
fmt::format("SDL-{}", it->player_id));
if (it->haptic)
SDL_CloseHaptic(it->haptic);
if (it->haptic)
SDL_CloseHaptic(it->haptic);
if (it->gamepad)
SDL_CloseGamepad(it->gamepad);
else
SDL_CloseJoystick(it->joystick);
if (it->gamepad)
SDL_CloseGamepad(it->gamepad);
else
SDL_CloseJoystick(it->joystick);
m_controllers.erase(it);
}
m_controllers.erase(it);
return true;
}

View File

@ -88,6 +88,12 @@ private:
ControllerDataVector m_controllers;
// ConvertKeyToIcon can inspect the currently connected gamepad
// to provide labels matching the connected gamepad
// Those functions can be called on the main thread, while
// gamepad addition/removal is done on the CPU thread
std::mutex m_controllers_key_mutex;
std::array<u32, MAX_LED_COLORS> m_led_colors{};
std::vector<std::pair<std::string, std::string>> m_sdl_hints;