FullscreenUI: Add option to display PS buttons instead of Xbox

This commit is contained in:
Stenzek 2025-01-05 15:09:07 +10:00
parent 4d6124d41b
commit 5ee069fc63
No known key found for this signature in database
16 changed files with 114 additions and 30 deletions

View File

@ -420,6 +420,34 @@ static GPUTexture* GetTextureForGameListEntryType(GameList::EntryType type);
static GPUTexture* GetGameListCover(const GameList::Entry* entry);
static GPUTexture* GetCoverForCurrentGame();
//////////////////////////////////////////////////////////////////////////
// Constants
//////////////////////////////////////////////////////////////////////////
static constexpr const std::array s_ps_button_mapping{
std::make_pair(ICON_PF_XBOX_DPAD_LEFT, ICON_PF_DPAD_LEFT),
std::make_pair(ICON_PF_XBOX_DPAD_UP, ICON_PF_DPAD_UP),
std::make_pair(ICON_PF_XBOX_DPAD_RIGHT, ICON_PF_DPAD_RIGHT),
std::make_pair(ICON_PF_XBOX_DPAD_DOWN, ICON_PF_DPAD_DOWN),
std::make_pair(ICON_PF_XBOX_DPAD_LEFT_RIGHT, ICON_PF_DPAD_LEFT_RIGHT),
std::make_pair(ICON_PF_XBOX_DPAD_UP_DOWN, ICON_PF_DPAD_UP_DOWN),
std::make_pair(ICON_PF_BUTTON_A, ICON_PF_BUTTON_CROSS),
std::make_pair(ICON_PF_BUTTON_B, ICON_PF_BUTTON_CIRCLE),
std::make_pair(ICON_PF_BUTTON_X, ICON_PF_BUTTON_SQUARE),
std::make_pair(ICON_PF_BUTTON_Y, ICON_PF_BUTTON_TRIANGLE),
std::make_pair(ICON_PF_SHARE_CAPTURE, ICON_PF_DUALSHOCK_SHARE),
std::make_pair(ICON_PF_BURGER_MENU, ICON_PF_DUALSHOCK_OPTIONS),
std::make_pair(ICON_PF_XBOX, ICON_PF_PLAYSTATION),
std::make_pair(ICON_PF_LEFT_SHOULDER_LB, ICON_PF_LEFT_SHOULDER_L1),
std::make_pair(ICON_PF_LEFT_TRIGGER_LT, ICON_PF_LEFT_TRIGGER_L2),
std::make_pair(ICON_PF_RIGHT_SHOULDER_RB, ICON_PF_RIGHT_SHOULDER_R1),
std::make_pair(ICON_PF_RIGHT_TRIGGER_RT, ICON_PF_RIGHT_TRIGGER_R2),
};
//////////////////////////////////////////////////////////////////////////
// State
//////////////////////////////////////////////////////////////////////////
namespace {
struct ALIGN_TO_CACHE_LINE UIState
@ -590,6 +618,9 @@ bool FullscreenUI::Initialize()
ImGuiFullscreen::SetSmoothScrolling(Host::GetBaseBoolSettingValue("Main", "FullscreenUISmoothScrolling", true));
ImGuiFullscreen::UpdateLayoutScale();
if (Host::GetBaseBoolSettingValue("Main", "FullscreenUIDisplayPSIcons", false))
ImGuiFullscreen::SetFullscreenFooterTextIconMapping(s_ps_button_mapping);
if (!ImGuiManager::AddFullscreenFontsIfMissing() || !ImGuiFullscreen::Initialize("images/placeholder.png") ||
!LoadResources())
{
@ -1717,7 +1748,7 @@ void FullscreenUI::DrawInputBindingButton(SettingsInterface* bsi, InputBindingIn
return;
if (oneline && type != InputBindingInfo::Type::Pointer && type != InputBindingInfo::Type::Device)
InputManager::PrettifyInputBinding(value);
InputManager::PrettifyInputBinding(value, &ImGuiFullscreen::GetControllerIconMapping);
if (show_type)
{
@ -3245,6 +3276,18 @@ void FullscreenUI::DrawInterfaceSettingsPage()
ImGuiFullscreen::SetTheme(bsi->GetBoolValue("Main", "UseLightFullscreenUITheme", false));
}
if (DrawToggleSetting(
bsi, FSUI_ICONSTR(ICON_PF_GAMEPAD, "Use DualShock/DualSense Button Icons"),
FSUI_CSTR(
"Displays DualShock/DualSense button icons in the footer and input binding, instead of Xbox buttons."),
"Main", "FullscreenUIDisplayPSIcons", false))
{
if (bsi->GetBoolValue("Main", "FullscreenUIDisplayPSIcons", false))
ImGuiFullscreen::SetFullscreenFooterTextIconMapping(s_ps_button_mapping);
else
ImGuiFullscreen::SetFullscreenFooterTextIconMapping({});
}
if (DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_LIST, "Smooth Scrolling"),
FSUI_CSTR("Enables smooth scrolling of menus in Big Picture UI."), "Main",
"FullscreenUISmoothScrolling", true))
@ -7575,7 +7618,7 @@ void FullscreenUI::CopyTextToClipboard(std::string title, std::string_view text)
void FullscreenUI::DrawAboutWindow()
{
ImGui::SetNextWindowSize(LayoutScale(1000.0f, 540.0f));
ImGui::SetNextWindowSize(LayoutScale(1000.0f, 545.0f));
ImGui::SetNextWindowPos(ImGui::GetIO().DisplaySize * 0.5f, ImGuiCond_Always, ImVec2(0.5f, 0.5f));
ImGui::OpenPopup(FSUI_CSTR("About DuckStation"));

View File

@ -931,7 +931,7 @@ void SaveStateSelectorUI::DestroyTextures()
void SaveStateSelectorUI::RefreshHotkeyLegend()
{
auto format_legend_entry = [](SmallString binding, std::string_view caption) {
InputManager::PrettifyInputBinding(binding);
InputManager::PrettifyInputBinding(binding, &ImGuiFullscreen::GetControllerIconMapping);
return fmt::format("{} - {}", binding, caption);
};

View File

@ -445,7 +445,7 @@ TinyString DInputSource::ConvertKeyToString(InputBindingKey key)
return ret;
}
TinyString DInputSource::ConvertKeyToIcon(InputBindingKey key)
TinyString DInputSource::ConvertKeyToIcon(InputBindingKey key, InputManager::BindingIconMappingFunction mapper)
{
return {};
}

View File

@ -49,7 +49,7 @@ public:
bool ContainsDevice(std::string_view device) const override;
std::optional<InputBindingKey> ParseKeyString(std::string_view device, std::string_view binding) override;
TinyString ConvertKeyToString(InputBindingKey key) override;
TinyString ConvertKeyToIcon(InputBindingKey key) override;
TinyString ConvertKeyToIcon(InputBindingKey key, InputManager::BindingIconMappingFunction mapper) override;
std::unique_ptr<ForceFeedbackDevice> CreateForceFeedbackDevice(std::string_view device, Error* error) override;

View File

@ -125,6 +125,7 @@ struct ALIGN_TO_CACHE_LINE UIState
SmallString fullscreen_footer_text;
SmallString last_fullscreen_footer_text;
std::vector<std::pair<std::string_view, std::string_view>> fullscreen_footer_icon_mapping;
float fullscreen_text_change_time;
bool choice_dialog_open = false;
@ -237,6 +238,7 @@ void ImGuiFullscreen::Shutdown(bool clear_state)
if (clear_state)
{
s_state.fullscreen_footer_icon_mapping = {};
s_state.notifications.clear();
s_state.background_progress_dialogs.clear();
s_state.fullscreen_footer_text.clear();
@ -816,6 +818,16 @@ bool ImGuiFullscreen::IsGamepadInputSource()
return (ImGui::GetCurrentContext()->NavInputSource == ImGuiInputSource_Gamepad);
}
std::string_view ImGuiFullscreen::GetControllerIconMapping(std::string_view icon)
{
const auto iter =
std::lower_bound(s_state.fullscreen_footer_icon_mapping.begin(), s_state.fullscreen_footer_icon_mapping.end(), icon,
[](const auto& it, const auto& value) { return (it.first < value); });
if (iter != s_state.fullscreen_footer_icon_mapping.end() && iter->first == icon)
icon = iter->second;
return icon;
}
void ImGuiFullscreen::CreateFooterTextString(SmallStringBase& dest,
std::span<const std::pair<const char*, std::string_view>> items)
{
@ -825,7 +837,7 @@ void ImGuiFullscreen::CreateFooterTextString(SmallStringBase& dest,
if (!dest.empty())
dest.append(" ");
dest.append(icon);
dest.append(GetControllerIconMapping(icon));
dest.append(' ');
dest.append(text);
}
@ -841,6 +853,21 @@ void ImGuiFullscreen::SetFullscreenFooterText(std::span<const std::pair<const ch
CreateFooterTextString(s_state.fullscreen_footer_text, items);
}
void ImGuiFullscreen::SetFullscreenFooterTextIconMapping(std::span<const std::pair<const char*, const char*>> mapping)
{
if (mapping.empty())
{
s_state.fullscreen_footer_icon_mapping = {};
return;
}
s_state.fullscreen_footer_icon_mapping.reserve(mapping.size());
for (const auto& [icon, mapped_icon] : mapping)
s_state.fullscreen_footer_icon_mapping.emplace_back(icon, mapped_icon);
std::sort(s_state.fullscreen_footer_icon_mapping.begin(), s_state.fullscreen_footer_icon_mapping.end(),
[](const auto& lhs, const auto& rhs) { return (lhs.first < rhs.first); });
}
void ImGuiFullscreen::DrawFullscreenFooter()
{
const ImGuiIO& io = ImGui::GetIO();

View File

@ -187,9 +187,11 @@ bool BeginFullscreenWindow(const ImVec2& position, const ImVec2& size, const cha
void EndFullscreenWindow();
bool IsGamepadInputSource();
std::string_view GetControllerIconMapping(std::string_view icon);
void CreateFooterTextString(SmallStringBase& dest, std::span<const std::pair<const char*, std::string_view>> items);
void SetFullscreenFooterText(std::string_view text);
void SetFullscreenFooterText(std::span<const std::pair<const char*, std::string_view>> items);
void SetFullscreenFooterTextIconMapping(std::span<const std::pair<const char*, const char*>> mapping);
void DrawFullscreenFooter();
void PrerenderMenuButtonBorder();

View File

@ -3,6 +3,6 @@
static constexpr ImWchar FA_ICON_RANGE[] = { 0xe06f,0xe070,0xe086,0xe086,0xf002,0xf002,0xf005,0xf005,0xf007,0xf007,0xf00c,0xf00e,0xf011,0xf013,0xf017,0xf017,0xf019,0xf019,0xf01c,0xf01c,0xf021,0xf021,0xf023,0xf023,0xf025,0xf026,0xf028,0xf028,0xf02e,0xf02e,0xf030,0xf030,0xf03a,0xf03a,0xf03d,0xf03d,0xf04a,0xf04c,0xf050,0xf050,0xf056,0xf056,0xf05e,0xf05e,0xf062,0xf063,0xf065,0xf067,0xf071,0xf071,0xf075,0xf075,0xf077,0xf078,0xf07b,0xf07c,0xf083,0xf085,0xf091,0xf091,0xf0ac,0xf0ae,0xf0b2,0xf0b2,0xf0c3,0xf0c3,0xf0c5,0xf0c5,0xf0c7,0xf0c9,0xf0cb,0xf0cb,0xf0d0,0xf0d0,0xf0dc,0xf0dc,0xf0e0,0xf0e0,0xf0e2,0xf0e2,0xf0e7,0xf0e8,0xf0eb,0xf0eb,0xf0f1,0xf0f1,0xf0f3,0xf0f3,0xf0fe,0xf0fe,0xf110,0xf110,0xf11b,0xf11c,0xf140,0xf140,0xf144,0xf144,0xf146,0xf146,0xf14a,0xf14a,0xf15b,0xf15d,0xf191,0xf192,0xf1ab,0xf1ab,0xf1c0,0xf1c0,0xf1c5,0xf1c5,0xf1de,0xf1de,0xf1e6,0xf1e6,0xf1eb,0xf1eb,0xf1f8,0xf1f8,0xf1fb,0xf1fc,0xf201,0xf201,0xf240,0xf240,0xf242,0xf242,0xf245,0xf245,0xf26c,0xf26c,0xf279,0xf279,0xf2c1,0xf2c1,0xf2d0,0xf2d0,0xf2db,0xf2db,0xf2f1,0xf2f2,0xf302,0xf302,0xf31e,0xf31e,0xf338,0xf338,0xf35d,0xf35d,0xf360,0xf360,0xf362,0xf362,0xf3fd,0xf3fd,0xf410,0xf410,0xf422,0xf422,0xf424,0xf424,0xf462,0xf462,0xf466,0xf466,0xf4ce,0xf4ce,0xf500,0xf500,0xf51f,0xf51f,0xf538,0xf538,0xf53f,0xf53f,0xf545,0xf545,0xf547,0xf548,0xf54c,0xf54c,0xf55b,0xf55b,0xf55d,0xf55d,0xf565,0xf565,0xf56e,0xf570,0xf575,0xf575,0xf5a2,0xf5a2,0xf5aa,0xf5aa,0xf5c7,0xf5c7,0xf5cb,0xf5cb,0xf5e7,0xf5e7,0xf5ee,0xf5ee,0xf61f,0xf61f,0xf65d,0xf65e,0xf6a9,0xf6a9,0xf6cf,0xf6cf,0xf70c,0xf70c,0xf70e,0xf70e,0xf78c,0xf78c,0xf794,0xf794,0xf7a0,0xf7a0,0xf7a4,0xf7a5,0xf7c2,0xf7c2,0xf807,0xf807,0xf815,0xf815,0xf818,0xf818,0xf84c,0xf84c,0xf87d,0xf87d,0xf8cc,0xf8cc,0x0,0x0 };
static constexpr ImWchar PF_ICON_RANGE[] = { 0x2196,0x2199,0x219e,0x21a1,0x21b0,0x21b3,0x21ba,0x21c3,0x21c7,0x21ca,0x21d0,0x21d4,0x21dc,0x21dd,0x21e0,0x21e3,0x21ed,0x21ee,0x21f7,0x21f8,0x21fa,0x21fb,0x227a,0x227f,0x2284,0x2284,0x2349,0x2349,0x235e,0x235e,0x2360,0x2361,0x2364,0x2366,0x23b2,0x23b4,0x23ce,0x23ce,0x23f4,0x23f7,0x2427,0x243a,0x243c,0x243e,0x2460,0x246b,0x248f,0x248f,0x24f5,0x24fd,0x24ff,0x24ff,0x2717,0x2717,0x278a,0x278e,0x27fc,0x27fc,0xe001,0xe001,0xff21,0xff3a,0x1f52b,0x1f52b,0x1f578,0x1f578,0x0,0x0 };
static constexpr ImWchar PF_ICON_RANGE[] = { 0x2196,0x2199,0x219e,0x21a3,0x21b0,0x21b3,0x21ba,0x21c3,0x21c7,0x21ca,0x21d0,0x21d4,0x21e0,0x21e3,0x21e6,0x21e8,0x21ed,0x21ee,0x21f7,0x21f8,0x21fa,0x21fb,0x227a,0x227f,0x2284,0x2284,0x2349,0x2349,0x235e,0x235e,0x2360,0x2361,0x2364,0x2366,0x23b2,0x23b4,0x23ce,0x23ce,0x23f4,0x23f7,0x2427,0x243a,0x243c,0x243e,0x2460,0x246b,0x248f,0x248f,0x24f5,0x24fd,0x24ff,0x24ff,0x2717,0x2717,0x278a,0x278e,0x27fc,0x27fc,0xe000,0xe001,0xff21,0xff3a,0x1f52b,0x1f52b,0x1f578,0x1f578,0x0,0x0 };
static constexpr ImWchar EMOJI_ICON_RANGE[] = { 0x2139,0x2139,0x23e9,0x23ea,0x23f8,0x23f8,0x26a0,0x26a0,0x1f4be,0x1f4be,0x1f4c2,0x1f4c2,0x1f4f7,0x1f4f8,0x1f504,0x1f504,0x1f507,0x1f507,0x1f509,0x1f50a,0x1f50d,0x1f50d,0x1f513,0x1f513,0x0,0x0 };

View File

@ -110,7 +110,8 @@ static std::optional<InputBindingKey> ParseSensorKey(std::string_view source, st
static std::vector<std::string_view> SplitChord(std::string_view binding);
static bool SplitBinding(std::string_view binding, std::string_view* source, std::string_view* sub_binding);
static void PrettifyInputBindingPart(std::string_view binding, SmallString& ret, bool& changed);
static void PrettifyInputBindingPart(std::string_view binding, BindingIconMappingFunction mapper, SmallString& ret,
bool& changed);
static void AddBindings(const std::vector<std::string>& bindings, const InputEventHandler& handler);
static void UpdatePointerCount();
@ -384,11 +385,13 @@ std::string InputManager::ConvertInputBindingKeysToString(InputBindingInfo::Type
return ss.str();
}
bool InputManager::PrettifyInputBinding(SmallStringBase& binding)
bool InputManager::PrettifyInputBinding(SmallStringBase& binding, BindingIconMappingFunction mapper /*= nullptr*/)
{
if (binding.empty())
return false;
mapper = mapper ? mapper : [](std::string_view v) { return v; };
const std::string_view binding_view = binding.view();
SmallString ret;
@ -405,7 +408,7 @@ bool InputManager::PrettifyInputBinding(SmallStringBase& binding)
{
if (!ret.empty())
ret.append(" + ");
PrettifyInputBindingPart(part, ret, changed);
PrettifyInputBindingPart(part, mapper, ret, changed);
}
}
last = next + 1;
@ -417,7 +420,7 @@ bool InputManager::PrettifyInputBinding(SmallStringBase& binding)
{
if (!ret.empty())
ret.append(" + ");
PrettifyInputBindingPart(part, ret, changed);
PrettifyInputBindingPart(part, mapper, ret, changed);
}
}
@ -427,7 +430,8 @@ bool InputManager::PrettifyInputBinding(SmallStringBase& binding)
return changed;
}
void InputManager::PrettifyInputBindingPart(const std::string_view binding, SmallString& ret, bool& changed)
void InputManager::PrettifyInputBindingPart(const std::string_view binding, BindingIconMappingFunction mapper,
SmallString& ret, bool& changed)
{
std::string_view source, sub_binding;
if (!SplitBinding(binding, &source, &sub_binding))
@ -477,7 +481,7 @@ void InputManager::PrettifyInputBindingPart(const std::string_view binding, Smal
std::optional<InputBindingKey> key = s_input_sources[i]->ParseKeyString(source, sub_binding);
if (key.has_value())
{
const TinyString icon = s_input_sources[i]->ConvertKeyToIcon(key.value());
const TinyString icon = s_input_sources[i]->ConvertKeyToIcon(key.value(), mapper);
if (!icon.empty())
{
ret.append(icon);

View File

@ -253,7 +253,9 @@ std::string ConvertInputBindingKeysToString(InputBindingInfo::Type binding_type,
size_t num_keys);
/// Represents a binding with icon fonts, if available.
bool PrettifyInputBinding(SmallStringBase& binding);
/// Optionally maps icon fonts to a different style, e.g. xbox icons -> PS buttons.
using BindingIconMappingFunction = std::string_view(*)(std::string_view);
bool PrettifyInputBinding(SmallStringBase& binding, BindingIconMappingFunction mapper = nullptr);
/// Returns a list of all hotkeys.
std::vector<const HotkeyInfo*> GetHotkeyList();

View File

@ -35,7 +35,7 @@ public:
virtual bool ContainsDevice(std::string_view device) const = 0;
virtual std::optional<InputBindingKey> ParseKeyString(std::string_view device, std::string_view binding) = 0;
virtual TinyString ConvertKeyToString(InputBindingKey key) = 0;
virtual TinyString ConvertKeyToIcon(InputBindingKey key) = 0;
virtual TinyString ConvertKeyToIcon(InputBindingKey key, InputManager::BindingIconMappingFunction mapper) = 0;
/// Enumerates available devices. Returns a pair of the prefix (e.g. SDL-0) and the device name.
virtual std::vector<std::pair<std::string, std::string>> EnumerateDevices() = 0;

View File

@ -41,8 +41,8 @@ static constexpr const char* s_sdl_axis_icons[][2] = {
{ICON_PF_LEFT_ANALOG_UP, ICON_PF_LEFT_ANALOG_DOWN}, // SDL_CONTROLLER_AXIS_LEFTY
{ICON_PF_RIGHT_ANALOG_LEFT, ICON_PF_RIGHT_ANALOG_RIGHT}, // SDL_CONTROLLER_AXIS_RIGHTX
{ICON_PF_RIGHT_ANALOG_UP, ICON_PF_RIGHT_ANALOG_DOWN}, // SDL_CONTROLLER_AXIS_RIGHTY
{nullptr, ICON_PF_LEFT_TRIGGER_PULL}, // SDL_CONTROLLER_AXIS_TRIGGERLEFT
{nullptr, ICON_PF_RIGHT_TRIGGER_PULL}, // SDL_CONTROLLER_AXIS_TRIGGERRIGHT
{nullptr, ICON_PF_LEFT_TRIGGER_LT}, // SDL_CONTROLLER_AXIS_TRIGGERLEFT
{nullptr, ICON_PF_RIGHT_TRIGGER_RT}, // SDL_CONTROLLER_AXIS_TRIGGERRIGHT
};
static constexpr const GenericInputBinding s_sdl_generic_binding_axis_mapping[][2] = {
{GenericInputBinding::LeftStickLeft, GenericInputBinding::LeftStickRight}, // SDL_CONTROLLER_AXIS_LEFTX
@ -92,6 +92,12 @@ static constexpr const char* s_sdl_button_icons[] = {
ICON_PF_XBOX_DPAD_DOWN, // SDL_CONTROLLER_BUTTON_DPAD_DOWN
ICON_PF_XBOX_DPAD_LEFT, // SDL_CONTROLLER_BUTTON_DPAD_LEFT
ICON_PF_XBOX_DPAD_RIGHT, // SDL_CONTROLLER_BUTTON_DPAD_RIGHT
nullptr, // SDL_CONTROLLER_BUTTON_MISC1
nullptr, // SDL_CONTROLLER_BUTTON_PADDLE1
nullptr, // SDL_CONTROLLER_BUTTON_PADDLE2
nullptr, // SDL_CONTROLLER_BUTTON_PADDLE3
nullptr, // SDL_CONTROLLER_BUTTON_PADDLE4
ICON_PF_DUALSHOCK_TOUCHPAD, // SDL_CONTROLLER_BUTTON_TOUCHPAD
};
static constexpr const GenericInputBinding s_sdl_generic_binding_button_mapping[] = {
GenericInputBinding::Cross, // SDL_CONTROLLER_BUTTON_A
@ -539,7 +545,7 @@ TinyString SDLInputSource::ConvertKeyToString(InputBindingKey key)
return ret;
}
TinyString SDLInputSource::ConvertKeyToIcon(InputBindingKey key)
TinyString SDLInputSource::ConvertKeyToIcon(InputBindingKey key, InputManager::BindingIconMappingFunction mapper)
{
TinyString ret;
@ -550,13 +556,13 @@ TinyString SDLInputSource::ConvertKeyToIcon(InputBindingKey key)
if (key.data < std::size(s_sdl_axis_icons) && key.modifier != InputModifier::FullAxis)
{
ret.format("SDL-{} {}", static_cast<u32>(key.source_index),
s_sdl_axis_icons[key.data][key.modifier == InputModifier::None]);
mapper(s_sdl_axis_icons[key.data][key.modifier == InputModifier::None]));
}
}
else if (key.source_subtype == InputSubclass::ControllerButton)
{
if (key.data < std::size(s_sdl_button_icons))
ret.format("SDL-{} {}", static_cast<u32>(key.source_index), s_sdl_button_icons[key.data]);
if (key.data < std::size(s_sdl_button_icons) && s_sdl_button_icons[key.data])
ret.format("SDL-{} {}", static_cast<u32>(key.source_index), mapper(s_sdl_button_icons[key.data]));
}
}

View File

@ -37,7 +37,7 @@ public:
bool ContainsDevice(std::string_view device) const override;
std::optional<InputBindingKey> ParseKeyString(std::string_view device, std::string_view binding) override;
TinyString ConvertKeyToString(InputBindingKey key) override;
TinyString ConvertKeyToIcon(InputBindingKey key) override;
TinyString ConvertKeyToIcon(InputBindingKey key, InputManager::BindingIconMappingFunction mapper) override;
std::unique_ptr<ForceFeedbackDevice> CreateForceFeedbackDevice(std::string_view device, Error* error) override;

View File

@ -106,7 +106,7 @@ TinyString Win32RawInputSource::ConvertKeyToString(InputBindingKey key)
return {};
}
TinyString Win32RawInputSource::ConvertKeyToIcon(InputBindingKey key)
TinyString Win32RawInputSource::ConvertKeyToIcon(InputBindingKey key, InputManager::BindingIconMappingFunction mapper)
{
return {};
}

View File

@ -33,7 +33,7 @@ public:
bool ContainsDevice(std::string_view device) const override;
std::optional<InputBindingKey> ParseKeyString(std::string_view device, std::string_view binding) override;
TinyString ConvertKeyToString(InputBindingKey key) override;
TinyString ConvertKeyToIcon(InputBindingKey key) override;
TinyString ConvertKeyToIcon(InputBindingKey key, InputManager::BindingIconMappingFunction mapper) override;
std::unique_ptr<ForceFeedbackDevice> CreateForceFeedbackDevice(std::string_view device, Error* error) override;

View File

@ -29,8 +29,8 @@ static constexpr const char* s_axis_icons[][2] = {
{ICON_PF_LEFT_ANALOG_UP, ICON_PF_LEFT_ANALOG_DOWN}, // AXIS_LEFTY
{ICON_PF_RIGHT_ANALOG_LEFT, ICON_PF_RIGHT_ANALOG_RIGHT}, // AXIS_RIGHTX
{ICON_PF_RIGHT_ANALOG_UP, ICON_PF_RIGHT_ANALOG_DOWN}, // AXIS_RIGHTY
{nullptr, ICON_PF_LEFT_TRIGGER_PULL}, // AXIS_TRIGGERLEFT
{nullptr, ICON_PF_RIGHT_TRIGGER_PULL}, // AXIS_TRIGGERRIGHT
{nullptr, ICON_PF_LEFT_TRIGGER_LT}, // AXIS_TRIGGERLEFT
{nullptr, ICON_PF_RIGHT_TRIGGER_RT}, // AXIS_TRIGGERRIGHT
};
static const GenericInputBinding s_xinput_generic_binding_axis_mapping[][2] = {
{GenericInputBinding::LeftStickLeft, GenericInputBinding::LeftStickRight}, // AXIS_LEFTX
@ -346,7 +346,7 @@ TinyString XInputSource::ConvertKeyToString(InputBindingKey key)
return ret;
}
TinyString XInputSource::ConvertKeyToIcon(InputBindingKey key)
TinyString XInputSource::ConvertKeyToIcon(InputBindingKey key, InputManager::BindingIconMappingFunction mapper)
{
TinyString ret;
@ -357,13 +357,13 @@ TinyString XInputSource::ConvertKeyToIcon(InputBindingKey key)
if (key.data < std::size(s_axis_icons) && key.modifier != InputModifier::FullAxis)
{
ret.format("XInput-{} {}", static_cast<u32>(key.source_index),
s_axis_icons[key.data][key.modifier == InputModifier::None]);
mapper(s_axis_icons[key.data][key.modifier == InputModifier::None]));
}
}
else if (key.source_subtype == InputSubclass::ControllerButton)
{
if (key.data < std::size(s_button_icons))
ret.format("XInput-{} {}", static_cast<u32>(key.source_index), s_button_icons[key.data]);
ret.format("XInput-{} {}", static_cast<u32>(key.source_index), mapper(s_button_icons[key.data]));
}
}

View File

@ -51,7 +51,7 @@ public:
bool ContainsDevice(std::string_view device) const override;
std::optional<InputBindingKey> ParseKeyString(std::string_view device, std::string_view binding) override;
TinyString ConvertKeyToString(InputBindingKey key) override;
TinyString ConvertKeyToIcon(InputBindingKey key) override;
TinyString ConvertKeyToIcon(InputBindingKey key, InputManager::BindingIconMappingFunction mapper) override;
std::unique_ptr<ForceFeedbackDevice> CreateForceFeedbackDevice(std::string_view device, Error* error) override;