mirror of https://github.com/PCSX2/pcsx2.git
FSUI: Automatic "Swap OK/Cancel" will now swap with switch controllers
This commit is contained in:
parent
ec047c5972
commit
c957b558e0
|
@ -628,6 +628,14 @@ void FullscreenUI::ApplyConfirmSetting(const SettingsInterface* bsi)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check gamepad
|
||||||
|
const InputLayout layout = ImGuiFullscreen::GetGamepadLayout();
|
||||||
|
if (layout == InputLayout::Nintendo)
|
||||||
|
{
|
||||||
|
io.ConfigNavSwapGamepadButtons = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// X is confirm
|
// X is confirm
|
||||||
io.ConfigNavSwapGamepadButtons = false;
|
io.ConfigNavSwapGamepadButtons = false;
|
||||||
return;
|
return;
|
||||||
|
@ -642,6 +650,11 @@ void FullscreenUI::LocaleChanged()
|
||||||
ApplyConfirmSetting();
|
ApplyConfirmSetting();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FullscreenUI::GamepadLayoutChanged()
|
||||||
|
{
|
||||||
|
ApplyConfirmSetting();
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
// Main
|
// Main
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -33,6 +33,7 @@ namespace FullscreenUI
|
||||||
void ReturnToMainWindow();
|
void ReturnToMainWindow();
|
||||||
void SetStandardSelectionFooterText(bool back_instead_of_cancel);
|
void SetStandardSelectionFooterText(bool back_instead_of_cancel);
|
||||||
void LocaleChanged();
|
void LocaleChanged();
|
||||||
|
void GamepadLayoutChanged();
|
||||||
|
|
||||||
void Shutdown(bool clear_state);
|
void Shutdown(bool clear_state);
|
||||||
void Render();
|
void Render();
|
||||||
|
|
|
@ -7,9 +7,11 @@
|
||||||
#include "Host.h"
|
#include "Host.h"
|
||||||
#include "GS/Renderers/Common/GSDevice.h"
|
#include "GS/Renderers/Common/GSDevice.h"
|
||||||
#include "GS/Renderers/Common/GSTexture.h"
|
#include "GS/Renderers/Common/GSTexture.h"
|
||||||
|
#include "ImGui/FullscreenUI.h"
|
||||||
#include "ImGui/ImGuiAnimated.h"
|
#include "ImGui/ImGuiAnimated.h"
|
||||||
#include "ImGui/ImGuiFullscreen.h"
|
#include "ImGui/ImGuiFullscreen.h"
|
||||||
#include "ImGui/ImGuiManager.h"
|
#include "ImGui/ImGuiManager.h"
|
||||||
|
#include "Input/InputManager.h"
|
||||||
|
|
||||||
#include "common/Assertions.h"
|
#include "common/Assertions.h"
|
||||||
#include "common/Console.h"
|
#include "common/Console.h"
|
||||||
|
@ -192,6 +194,8 @@ namespace ImGuiFullscreen
|
||||||
|
|
||||||
static std::vector<BackgroundProgressDialogData> s_background_progress_dialogs;
|
static std::vector<BackgroundProgressDialogData> s_background_progress_dialogs;
|
||||||
static std::mutex s_background_progress_lock;
|
static std::mutex s_background_progress_lock;
|
||||||
|
|
||||||
|
static InputLayout s_gamepad_layout = InputLayout::Unknown;
|
||||||
} // namespace ImGuiFullscreen
|
} // namespace ImGuiFullscreen
|
||||||
|
|
||||||
void ImGuiFullscreen::SetFonts(ImFont* standard_font, ImFont* medium_font, ImFont* large_font)
|
void ImGuiFullscreen::SetFonts(ImFont* standard_font, ImFont* medium_font, ImFont* large_font)
|
||||||
|
@ -738,6 +742,20 @@ bool ImGuiFullscreen::IsGamepadInputSource()
|
||||||
return (ImGui::GetCurrentContext()->NavInputSource == ImGuiInputSource_Gamepad);
|
return (ImGui::GetCurrentContext()->NavInputSource == ImGuiInputSource_Gamepad);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ImGuiFullscreen::ReportGamepadLayout(InputLayout layout)
|
||||||
|
{
|
||||||
|
if (s_gamepad_layout == layout)
|
||||||
|
return;
|
||||||
|
|
||||||
|
s_gamepad_layout = layout;
|
||||||
|
FullscreenUI::GamepadLayoutChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
InputLayout ImGuiFullscreen::GetGamepadLayout()
|
||||||
|
{
|
||||||
|
return s_gamepad_layout;
|
||||||
|
}
|
||||||
|
|
||||||
void ImGuiFullscreen::CreateFooterTextString(SmallStringBase& dest,
|
void ImGuiFullscreen::CreateFooterTextString(SmallStringBase& dest,
|
||||||
std::span<const std::pair<const char*, std::string_view>> items)
|
std::span<const std::pair<const char*, std::string_view>> items)
|
||||||
{
|
{
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
class GSTexture;
|
class GSTexture;
|
||||||
|
enum class InputLayout : u8;
|
||||||
|
|
||||||
namespace ImGuiFullscreen
|
namespace ImGuiFullscreen
|
||||||
{
|
{
|
||||||
|
@ -149,6 +150,8 @@ namespace ImGuiFullscreen
|
||||||
void EndFullscreenWindow();
|
void EndFullscreenWindow();
|
||||||
|
|
||||||
bool IsGamepadInputSource();
|
bool IsGamepadInputSource();
|
||||||
|
void ReportGamepadLayout(InputLayout layout);
|
||||||
|
InputLayout GetGamepadLayout();
|
||||||
void CreateFooterTextString(SmallStringBase& dest, std::span<const std::pair<const char*, std::string_view>> items);
|
void CreateFooterTextString(SmallStringBase& dest, std::span<const std::pair<const char*, std::string_view>> items);
|
||||||
void SetFullscreenFooterText(std::string_view text);
|
void SetFullscreenFooterText(std::string_view text);
|
||||||
void SetFullscreenFooterText(std::span<const std::pair<const char*, std::string_view>> items);
|
void SetFullscreenFooterText(std::span<const std::pair<const char*, std::string_view>> items);
|
||||||
|
|
|
@ -921,7 +921,7 @@ bool ImGuiManager::ProcessHostKeyEvent(InputBindingKey key, float value)
|
||||||
return s_imgui_wants_keyboard.load(std::memory_order_acquire);
|
return s_imgui_wants_keyboard.load(std::memory_order_acquire);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImGuiManager::ProcessGenericInputEvent(GenericInputBinding key, float value)
|
bool ImGuiManager::ProcessGenericInputEvent(GenericInputBinding key, InputLayout layout, float value)
|
||||||
{
|
{
|
||||||
static constexpr ImGuiKey key_map[] = {
|
static constexpr ImGuiKey key_map[] = {
|
||||||
ImGuiKey_None, // Unknown,
|
ImGuiKey_None, // Unknown,
|
||||||
|
@ -959,7 +959,10 @@ bool ImGuiManager::ProcessGenericInputEvent(GenericInputBinding key, float value
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
MTGS::RunOnGSThread(
|
MTGS::RunOnGSThread(
|
||||||
[key = key_map[static_cast<u32>(key)], value]() { ImGui::GetIO().AddKeyAnalogEvent(key, (value > 0.0f), value); });
|
[key = key_map[static_cast<u32>(key)], value, layout]() {
|
||||||
|
ImGuiFullscreen::ReportGamepadLayout(layout);
|
||||||
|
ImGui::GetIO().AddKeyAnalogEvent(key, (value > 0.0f), value);
|
||||||
|
});
|
||||||
|
|
||||||
return s_imgui_wants_keyboard.load(std::memory_order_acquire);
|
return s_imgui_wants_keyboard.load(std::memory_order_acquire);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ struct ImFont;
|
||||||
|
|
||||||
union InputBindingKey;
|
union InputBindingKey;
|
||||||
enum class GenericInputBinding : u8;
|
enum class GenericInputBinding : u8;
|
||||||
|
enum class InputLayout : u8;
|
||||||
|
|
||||||
namespace ImGuiManager
|
namespace ImGuiManager
|
||||||
{
|
{
|
||||||
|
@ -94,7 +95,7 @@ namespace ImGuiManager
|
||||||
bool ProcessHostKeyEvent(InputBindingKey key, float value);
|
bool ProcessHostKeyEvent(InputBindingKey key, float value);
|
||||||
|
|
||||||
/// Called on the CPU thread when any input event fires. Allows imgui to take over controller navigation.
|
/// Called on the CPU thread when any input event fires. Allows imgui to take over controller navigation.
|
||||||
bool ProcessGenericInputEvent(GenericInputBinding key, float value);
|
bool ProcessGenericInputEvent(GenericInputBinding key, InputLayout layout, float value);
|
||||||
|
|
||||||
/// Sets an image and scale for a software cursor. Software cursors can be used for things like crosshairs.
|
/// Sets an image and scale for a software cursor. Software cursors can be used for things like crosshairs.
|
||||||
void SetSoftwareCursor(u32 index, std::string image_path, float image_scale, u32 multiply_color = 0xFFFFFF);
|
void SetSoftwareCursor(u32 index, std::string image_path, float image_scale, u32 multiply_color = 0xFFFFFF);
|
||||||
|
|
|
@ -315,6 +315,11 @@ bool DInputSource::GetGenericBindingMapping(const std::string_view device, Input
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
InputLayout DInputSource::GetControllerLayout(u32 index)
|
||||||
|
{
|
||||||
|
return InputLayout::Unknown;
|
||||||
|
}
|
||||||
|
|
||||||
void DInputSource::UpdateMotorState(InputBindingKey key, float intensity)
|
void DInputSource::UpdateMotorState(InputBindingKey key, float intensity)
|
||||||
{
|
{
|
||||||
// not supported
|
// not supported
|
||||||
|
|
|
@ -44,6 +44,7 @@ public:
|
||||||
std::vector<std::pair<std::string, std::string>> EnumerateDevices() override;
|
std::vector<std::pair<std::string, std::string>> EnumerateDevices() override;
|
||||||
std::vector<InputBindingKey> EnumerateMotors() override;
|
std::vector<InputBindingKey> EnumerateMotors() override;
|
||||||
bool GetGenericBindingMapping(const std::string_view device, InputManager::GenericInputBindingMapping* mapping) override;
|
bool GetGenericBindingMapping(const std::string_view device, InputManager::GenericInputBindingMapping* mapping) override;
|
||||||
|
InputLayout GetControllerLayout(u32 index) override;
|
||||||
void UpdateMotorState(InputBindingKey key, float intensity) override;
|
void UpdateMotorState(InputBindingKey key, float intensity) override;
|
||||||
void UpdateMotorState(InputBindingKey large_key, InputBindingKey small_key, float large_intensity, float small_intensity) override;
|
void UpdateMotorState(InputBindingKey large_key, InputBindingKey small_key, float large_intensity, float small_intensity) override;
|
||||||
|
|
||||||
|
|
|
@ -1263,7 +1263,8 @@ bool InputManager::PreprocessEvent(InputBindingKey key, float value, GenericInpu
|
||||||
}
|
}
|
||||||
else if (generic_key != GenericInputBinding::Unknown)
|
else if (generic_key != GenericInputBinding::Unknown)
|
||||||
{
|
{
|
||||||
if (ImGuiManager::ProcessGenericInputEvent(generic_key, value) && value != 0.0f)
|
InputLayout layout = s_input_sources[static_cast<u32>(InputSourceType::SDL)]->GetControllerLayout(key.source_index);
|
||||||
|
if (ImGuiManager::ProcessGenericInputEvent(generic_key, layout, value) && value != 0.0f)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,15 @@ enum class InputSubclass : u32
|
||||||
ControllerHaptic = 4,
|
ControllerHaptic = 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Layout of the source controller
|
||||||
|
enum class InputLayout : u8
|
||||||
|
{
|
||||||
|
Unknown,
|
||||||
|
Xbox,
|
||||||
|
Playstation,
|
||||||
|
Nintendo
|
||||||
|
};
|
||||||
|
|
||||||
enum class InputModifier : u32
|
enum class InputModifier : u32
|
||||||
{
|
{
|
||||||
None = 0,
|
None = 0,
|
||||||
|
|
|
@ -43,6 +43,9 @@ public:
|
||||||
/// Returns false if it's not one of our devices.
|
/// Returns false if it's not one of our devices.
|
||||||
virtual bool GetGenericBindingMapping(const std::string_view device, InputManager::GenericInputBindingMapping* mapping) = 0;
|
virtual bool GetGenericBindingMapping(const std::string_view device, InputManager::GenericInputBindingMapping* mapping) = 0;
|
||||||
|
|
||||||
|
/// Gets the layout of the controller connected at index.
|
||||||
|
virtual InputLayout GetControllerLayout(u32 index) = 0;
|
||||||
|
|
||||||
/// Informs the source of a new vibration motor state. Changes may not take effect until the next PollEvents() call.
|
/// Informs the source of a new vibration motor state. Changes may not take effect until the next PollEvents() call.
|
||||||
virtual void UpdateMotorState(InputBindingKey key, float intensity) = 0;
|
virtual void UpdateMotorState(InputBindingKey key, float intensity) = 0;
|
||||||
|
|
||||||
|
|
|
@ -1519,6 +1519,25 @@ bool SDLInputSource::GetGenericBindingMapping(const std::string_view device, Inp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
InputLayout SDLInputSource::GetControllerLayout(u32 index)
|
||||||
|
{
|
||||||
|
auto it = GetControllerDataForPlayerId(index);
|
||||||
|
if (it == m_controllers.end())
|
||||||
|
return InputLayout::Unknown;
|
||||||
|
|
||||||
|
// Infer layout based on face button label to avoid having
|
||||||
|
// to maintain a long switch statement of gamepad types
|
||||||
|
// clang-format off
|
||||||
|
switch (SDL_GetGamepadButtonLabel(it->gamepad, SDL_GAMEPAD_BUTTON_EAST))
|
||||||
|
{
|
||||||
|
case SDL_GAMEPAD_BUTTON_LABEL_B: return InputLayout::Xbox;
|
||||||
|
case SDL_GAMEPAD_BUTTON_LABEL_A: return InputLayout::Nintendo;
|
||||||
|
case SDL_GAMEPAD_BUTTON_LABEL_CIRCLE: return InputLayout::Playstation;
|
||||||
|
default: return InputLayout::Unknown;
|
||||||
|
}
|
||||||
|
// clang-format on
|
||||||
|
}
|
||||||
|
|
||||||
void SDLInputSource::UpdateMotorState(InputBindingKey key, float intensity)
|
void SDLInputSource::UpdateMotorState(InputBindingKey key, float intensity)
|
||||||
{
|
{
|
||||||
if (key.source_subtype != InputSubclass::ControllerMotor && key.source_subtype != InputSubclass::ControllerHaptic)
|
if (key.source_subtype != InputSubclass::ControllerMotor && key.source_subtype != InputSubclass::ControllerHaptic)
|
||||||
|
|
|
@ -32,6 +32,7 @@ public:
|
||||||
std::vector<std::pair<std::string, std::string>> EnumerateDevices() override;
|
std::vector<std::pair<std::string, std::string>> EnumerateDevices() override;
|
||||||
std::vector<InputBindingKey> EnumerateMotors() override;
|
std::vector<InputBindingKey> EnumerateMotors() override;
|
||||||
bool GetGenericBindingMapping(const std::string_view device, InputManager::GenericInputBindingMapping* mapping) override;
|
bool GetGenericBindingMapping(const std::string_view device, InputManager::GenericInputBindingMapping* mapping) override;
|
||||||
|
InputLayout GetControllerLayout(u32 index) override;
|
||||||
void UpdateMotorState(InputBindingKey key, float intensity) override;
|
void UpdateMotorState(InputBindingKey key, float intensity) override;
|
||||||
void UpdateMotorState(InputBindingKey large_key, InputBindingKey small_key, float large_intensity, float small_intensity) override;
|
void UpdateMotorState(InputBindingKey large_key, InputBindingKey small_key, float large_intensity, float small_intensity) override;
|
||||||
|
|
||||||
|
|
|
@ -466,6 +466,11 @@ bool XInputSource::GetGenericBindingMapping(const std::string_view device, Input
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
InputLayout XInputSource::GetControllerLayout(u32 index)
|
||||||
|
{
|
||||||
|
return InputLayout::Xbox;
|
||||||
|
}
|
||||||
|
|
||||||
void XInputSource::HandleControllerConnection(u32 index)
|
void XInputSource::HandleControllerConnection(u32 index)
|
||||||
{
|
{
|
||||||
INFO_LOG("XInput controller {} connected.", index);
|
INFO_LOG("XInput controller {} connected.", index);
|
||||||
|
|
|
@ -81,6 +81,7 @@ public:
|
||||||
std::vector<std::pair<std::string, std::string>> EnumerateDevices() override;
|
std::vector<std::pair<std::string, std::string>> EnumerateDevices() override;
|
||||||
std::vector<InputBindingKey> EnumerateMotors() override;
|
std::vector<InputBindingKey> EnumerateMotors() override;
|
||||||
bool GetGenericBindingMapping(const std::string_view device, InputManager::GenericInputBindingMapping* mapping) override;
|
bool GetGenericBindingMapping(const std::string_view device, InputManager::GenericInputBindingMapping* mapping) override;
|
||||||
|
InputLayout GetControllerLayout(u32 index) override;
|
||||||
void UpdateMotorState(InputBindingKey key, float intensity) override;
|
void UpdateMotorState(InputBindingKey key, float intensity) override;
|
||||||
void UpdateMotorState(InputBindingKey large_key, InputBindingKey small_key, float large_intensity, float small_intensity) override;
|
void UpdateMotorState(InputBindingKey large_key, InputBindingKey small_key, float large_intensity, float small_intensity) override;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue