diff --git a/pcsx2/Config.h b/pcsx2/Config.h index 2ea58ae551..7bfe3880d9 100644 --- a/pcsx2/Config.h +++ b/pcsx2/Config.h @@ -48,7 +48,7 @@ struct SettingInfo const char* max_value; const char* step_value; const char* format; - const char** options; + const char* const* options; float multiplier; const char* StringDefaultValue() const; @@ -65,6 +65,7 @@ struct SettingInfo enum class GenericInputBinding : u8; +// TODO(Stenzek): Move to InputCommon.h or something? struct InputBindingInfo { enum class Type : u8 @@ -84,6 +85,49 @@ struct InputBindingInfo GenericInputBinding generic_mapping; }; +/// Generic input bindings. These roughly match a DualShock 4 or XBox One controller. +/// They are used for automatic binding to PS2 controller types, and for big picture mode navigation. +enum class GenericInputBinding : u8 +{ + Unknown, + + DPadUp, + DPadRight, + DPadLeft, + DPadDown, + + LeftStickUp, + LeftStickRight, + LeftStickDown, + LeftStickLeft, + L3, + + RightStickUp, + RightStickRight, + RightStickDown, + RightStickLeft, + R3, + + Triangle, // Y on XBox pads. + Circle, // B on XBox pads. + Cross, // A on XBox pads. + Square, // X on XBox pads. + + Select, // Share on DS4, View on XBox pads. + Start, // Options on DS4, Menu on XBox pads. + System, // PS button on DS4, Guide button on XBox pads. + + L1, // LB on Xbox pads. + L2, // Left trigger on XBox pads. + R1, // RB on XBox pads. + R2, // Right trigger on Xbox pads. + + SmallMotor, // High frequency vibration. + LargeMotor, // Low frequency vibration. + + Count, +}; + enum GamefixId { GamefixId_FIRST = 0, diff --git a/pcsx2/Frontend/DInputSource.cpp b/pcsx2/Frontend/DInputSource.cpp index 8dbc7cc433..01156fb32a 100644 --- a/pcsx2/Frontend/DInputSource.cpp +++ b/pcsx2/Frontend/DInputSource.cpp @@ -84,8 +84,8 @@ bool DInputSource::Initialize(SettingsInterface& si, std::unique_lock(m_dinput.put()), nullptr); + HRESULT hr = + create(GetModuleHandleA(nullptr), DIRECTINPUT_VERSION, IID_IDirectInput8W, reinterpret_cast(m_dinput.put()), nullptr); m_joystick_data_format = get_joystick_data_format(); if (FAILED(hr) || !m_joystick_data_format) { @@ -309,7 +309,7 @@ std::vector DInputSource::EnumerateMotors() return {}; } -bool DInputSource::GetGenericBindingMapping(const std::string_view& device, GenericInputBindingMapping* mapping) +bool DInputSource::GetGenericBindingMapping(const std::string_view& device, InputManager::GenericInputBindingMapping* mapping) { return {}; } @@ -391,7 +391,8 @@ std::string DInputSource::ConvertKeyToString(InputBindingKey key) { if (key.source_subtype == InputSubclass::ControllerAxis) { - ret = fmt::format("DInput-{}/{}Axis{}", u32(key.source_index), key.modifier == InputModifier::Negate ? '-' : '+', u32(key.data)); + ret = + fmt::format("DInput-{}/{}Axis{}", u32(key.source_index), key.modifier == InputModifier::Negate ? '-' : '+', u32(key.data)); } else if (key.source_subtype == InputSubclass::ControllerButton && key.data >= MAX_NUM_BUTTONS) { diff --git a/pcsx2/Frontend/DInputSource.h b/pcsx2/Frontend/DInputSource.h index 1fb1415a01..dfb0900fe6 100644 --- a/pcsx2/Frontend/DInputSource.h +++ b/pcsx2/Frontend/DInputSource.h @@ -52,7 +52,7 @@ public: void PollEvents() override; std::vector> EnumerateDevices() override; std::vector EnumerateMotors() override; - bool GetGenericBindingMapping(const std::string_view& device, GenericInputBindingMapping* mapping) override; + bool GetGenericBindingMapping(const std::string_view& device, InputManager::GenericInputBindingMapping* mapping) override; void UpdateMotorState(InputBindingKey key, float intensity) override; void UpdateMotorState(InputBindingKey large_key, InputBindingKey small_key, float large_intensity, float small_intensity) override; diff --git a/pcsx2/Frontend/InputManager.cpp b/pcsx2/Frontend/InputManager.cpp index df49f5718e..7769d3b40a 100644 --- a/pcsx2/Frontend/InputManager.cpp +++ b/pcsx2/Frontend/InputManager.cpp @@ -1150,7 +1150,7 @@ static void GetKeyboardGenericBindingMapping(std::vectoremplace_back(GenericInputBinding::R3, "Keyboard/4"); } -static bool GetInternalGenericBindingMapping(const std::string_view& device, GenericInputBindingMapping* mapping) +static bool GetInternalGenericBindingMapping(const std::string_view& device, InputManager::GenericInputBindingMapping* mapping) { if (device == "Keyboard") { @@ -1161,7 +1161,7 @@ static bool GetInternalGenericBindingMapping(const std::string_view& device, Gen return false; } -GenericInputBindingMapping InputManager::GetGenericBindingMapping(const std::string_view& device) +InputManager::GenericInputBindingMapping InputManager::GetGenericBindingMapping(const std::string_view& device) { GenericInputBindingMapping mapping; diff --git a/pcsx2/Frontend/InputManager.h b/pcsx2/Frontend/InputManager.h index 7043cdcf97..1838e5e095 100644 --- a/pcsx2/Frontend/InputManager.h +++ b/pcsx2/Frontend/InputManager.h @@ -26,6 +26,8 @@ #include "common/SettingsInterface.h" #include "common/WindowInfo.h" +#include "pcsx2/Config.h" + /// Class, or source of an input event. enum class InputSourceType : u32 { @@ -143,50 +145,6 @@ DECLARE_HOTKEY_LIST(g_common_hotkeys); DECLARE_HOTKEY_LIST(g_gs_hotkeys); DECLARE_HOTKEY_LIST(g_host_hotkeys); -/// Generic input bindings. These roughly match a DualShock 4 or XBox One controller. -/// They are used for automatic binding to PS2 controller types, and for big picture mode navigation. -enum class GenericInputBinding : u8 -{ - Unknown, - - DPadUp, - DPadRight, - DPadLeft, - DPadDown, - - LeftStickUp, - LeftStickRight, - LeftStickDown, - LeftStickLeft, - L3, - - RightStickUp, - RightStickRight, - RightStickDown, - RightStickLeft, - R3, - - Triangle, // Y on XBox pads. - Circle, // B on XBox pads. - Cross, // A on XBox pads. - Square, // X on XBox pads. - - Select, // Share on DS4, View on XBox pads. - Start, // Options on DS4, Menu on XBox pads. - System, // PS button on DS4, Guide button on XBox pads. - - L1, // LB on Xbox pads. - L2, // Left trigger on XBox pads. - R1, // RB on XBox pads. - R2, // Right trigger on Xbox pads. - - SmallMotor, // High frequency vibration. - LargeMotor, // Low frequency vibration. - - Count, -}; -using GenericInputBindingMapping = std::vector>; - /// Host mouse relative axes are X, Y, wheel horizontal, wheel vertical. enum class InputPointerAxis : u8 { @@ -255,6 +213,7 @@ namespace InputManager std::vector EnumerateMotors(); /// Retrieves bindings that match the generic bindings for the specified device. + using GenericInputBindingMapping = std::vector>; GenericInputBindingMapping GetGenericBindingMapping(const std::string_view& device); /// Returns whether a given input source is enabled. diff --git a/pcsx2/Frontend/InputSource.h b/pcsx2/Frontend/InputSource.h index 3f9ada3fac..863725e75a 100644 --- a/pcsx2/Frontend/InputSource.h +++ b/pcsx2/Frontend/InputSource.h @@ -38,8 +38,7 @@ public: virtual void PollEvents() = 0; - virtual std::optional ParseKeyString( - const std::string_view& device, const std::string_view& binding) = 0; + virtual std::optional ParseKeyString(const std::string_view& device, const std::string_view& binding) = 0; virtual std::string ConvertKeyToString(InputBindingKey key) = 0; /// Enumerates available devices. Returns a pair of the prefix (e.g. SDL-0) and the device name. @@ -50,7 +49,7 @@ public: /// Retrieves bindings that match the generic bindings for the specified device. /// Returns false if it's not one of our devices. - virtual bool GetGenericBindingMapping(const std::string_view& device, GenericInputBindingMapping* mapping) = 0; + virtual bool GetGenericBindingMapping(const std::string_view& device, InputManager::GenericInputBindingMapping* mapping) = 0; /// 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; diff --git a/pcsx2/Frontend/SDLInputSource.cpp b/pcsx2/Frontend/SDLInputSource.cpp index c77858156b..d53a1d4f1f 100644 --- a/pcsx2/Frontend/SDLInputSource.cpp +++ b/pcsx2/Frontend/SDLInputSource.cpp @@ -89,7 +89,10 @@ static const GenericInputBinding s_sdl_generic_binding_button_mapping[] = { SDLInputSource::SDLInputSource() = default; -SDLInputSource::~SDLInputSource() { pxAssert(m_controllers.empty()); } +SDLInputSource::~SDLInputSource() +{ + pxAssert(m_controllers.empty()); +} bool SDLInputSource::Initialize(SettingsInterface& si, std::unique_lock& settings_lock) { @@ -207,8 +210,7 @@ std::vector> SDLInputSource::EnumerateDevice return ret; } -std::optional SDLInputSource::ParseKeyString( - const std::string_view& device, const std::string_view& binding) +std::optional SDLInputSource::ParseKeyString(const std::string_view& device, const std::string_view& binding) { if (!StringUtil::StartsWith(device, "SDL-") || binding.empty()) return std::nullopt; @@ -388,14 +390,12 @@ bool SDLInputSource::ProcessSDLEvent(const SDL_Event* event) SDLInputSource::ControllerDataVector::iterator SDLInputSource::GetControllerDataForJoystickId(int id) { - return std::find_if( - m_controllers.begin(), m_controllers.end(), [id](const ControllerData& cd) { return cd.joystick_id == id; }); + return std::find_if(m_controllers.begin(), m_controllers.end(), [id](const ControllerData& cd) { return cd.joystick_id == id; }); } SDLInputSource::ControllerDataVector::iterator SDLInputSource::GetControllerDataForPlayerId(int id) { - return std::find_if( - m_controllers.begin(), m_controllers.end(), [id](const ControllerData& cd) { return cd.player_id == id; }); + return std::find_if(m_controllers.begin(), m_controllers.end(), [id](const ControllerData& cd) { return cd.player_id == id; }); } int SDLInputSource::GetFreePlayerId() const @@ -439,8 +439,8 @@ bool SDLInputSource::OpenGameController(int index) player_id = free_player_id; } - Console.WriteLn("(SDLInputSource) Opened controller %d (instance id %d, player id %d): %s", index, joystick_id, - player_id, SDL_GameControllerName(gcontroller)); + Console.WriteLn("(SDLInputSource) Opened controller %d (instance id %d, player id %d): %s", index, joystick_id, player_id, + SDL_GameControllerName(gcontroller)); ControllerData cd = {}; cd.player_id = player_id; @@ -452,7 +452,7 @@ bool SDLInputSource::OpenGameController(int index) const int num_buttons = SDL_JoystickNumButtons(joystick); cd.joy_axis_used_in_gc.resize(num_axes, false); cd.joy_button_used_in_gc.resize(num_buttons, false); - auto mark_bind = [&](SDL_GameControllerButtonBind bind){ + auto mark_bind = [&](SDL_GameControllerButtonBind bind) { if (bind.bindType == SDL_CONTROLLER_BINDTYPE_AXIS && bind.value.axis < num_axes) cd.joy_axis_used_in_gc[bind.value.axis] = true; if (bind.bindType == SDL_CONTROLLER_BINDTYPE_BUTTON && bind.value.button < num_buttons) @@ -466,8 +466,7 @@ bool SDLInputSource::OpenGameController(int index) cd.use_game_controller_rumble = (SDL_GameControllerRumble(gcontroller, 0, 0, 0) == 0); if (cd.use_game_controller_rumble) { - Console.WriteLn( - "(SDLInputSource) Rumble is supported on '%s' via gamecontroller", SDL_GameControllerName(gcontroller)); + Console.WriteLn("(SDLInputSource) Rumble is supported on '%s' via gamecontroller", SDL_GameControllerName(gcontroller)); } else { @@ -500,8 +499,7 @@ bool SDLInputSource::OpenGameController(int index) } if (cd.haptic) - Console.WriteLn( - "(SDLInputSource) Rumble is supported on '%s' via haptic", SDL_GameControllerName(gcontroller)); + Console.WriteLn("(SDLInputSource) Rumble is supported on '%s' via haptic", SDL_GameControllerName(gcontroller)); } if (!cd.haptic && !cd.use_game_controller_rumble) @@ -555,8 +553,8 @@ bool SDLInputSource::HandleControllerButtonEvent(const SDL_ControllerButtonEvent const InputBindingKey key(MakeGenericControllerButtonKey(InputSourceType::SDL, it->player_id, ev->button)); const GenericInputBinding generic_key = (ev->button < std::size(s_sdl_generic_binding_button_mapping)) ? - s_sdl_generic_binding_button_mapping[ev->button] : - GenericInputBinding::Unknown; + s_sdl_generic_binding_button_mapping[ev->button] : + GenericInputBinding::Unknown; return InputManager::InvokeEvents(key, (ev->state == SDL_PRESSED) ? 1.0f : 0.0f, generic_key); } @@ -616,7 +614,7 @@ std::vector SDLInputSource::EnumerateMotors() return ret; } -bool SDLInputSource::GetGenericBindingMapping(const std::string_view& device, GenericInputBindingMapping* mapping) +bool SDLInputSource::GetGenericBindingMapping(const std::string_view& device, InputManager::GenericInputBindingMapping* mapping) { if (!StringUtil::StartsWith(device, "SDL-")) return false; diff --git a/pcsx2/Frontend/SDLInputSource.h b/pcsx2/Frontend/SDLInputSource.h index c560782521..ffe8592c00 100644 --- a/pcsx2/Frontend/SDLInputSource.h +++ b/pcsx2/Frontend/SDLInputSource.h @@ -26,63 +26,63 @@ class SettingsInterface; class SDLInputSource final : public InputSource { public: - SDLInputSource(); - ~SDLInputSource(); + SDLInputSource(); + ~SDLInputSource(); - bool Initialize(SettingsInterface& si, std::unique_lock& settings_lock) override; - void UpdateSettings(SettingsInterface& si, std::unique_lock& settings_lock) override; - bool ReloadDevices() override; - void Shutdown() override; + bool Initialize(SettingsInterface& si, std::unique_lock& settings_lock) override; + void UpdateSettings(SettingsInterface& si, std::unique_lock& settings_lock) override; + bool ReloadDevices() override; + void Shutdown() override; - void PollEvents() override; - std::vector> EnumerateDevices() override; - std::vector EnumerateMotors() override; - bool GetGenericBindingMapping(const std::string_view& device, GenericInputBindingMapping* mapping) override; - void UpdateMotorState(InputBindingKey key, float intensity) override; - void UpdateMotorState(InputBindingKey large_key, InputBindingKey small_key, float large_intensity, float small_intensity) override; + void PollEvents() override; + std::vector> EnumerateDevices() override; + std::vector EnumerateMotors() override; + bool GetGenericBindingMapping(const std::string_view& device, InputManager::GenericInputBindingMapping* mapping) override; + void UpdateMotorState(InputBindingKey key, float intensity) override; + void UpdateMotorState(InputBindingKey large_key, InputBindingKey small_key, float large_intensity, float small_intensity) override; - std::optional ParseKeyString(const std::string_view& device, const std::string_view& binding) override; - std::string ConvertKeyToString(InputBindingKey key) override; + std::optional ParseKeyString(const std::string_view& device, const std::string_view& binding) override; + std::string ConvertKeyToString(InputBindingKey key) override; - bool ProcessSDLEvent(const SDL_Event* event); + bool ProcessSDLEvent(const SDL_Event* event); private: - struct ControllerData - { - SDL_Haptic* haptic; - SDL_GameController* game_controller; - u16 rumble_intensity[2]; - int haptic_left_right_effect; - int joystick_id; - int player_id; - bool use_game_controller_rumble; + struct ControllerData + { + SDL_Haptic* haptic; + SDL_GameController* game_controller; + u16 rumble_intensity[2]; + int haptic_left_right_effect; + int joystick_id; + int player_id; + bool use_game_controller_rumble; - // Used to disable Joystick controls that are used in GameController inputs so we don't get double events - std::vector joy_button_used_in_gc; - std::vector joy_axis_used_in_gc; - }; + // Used to disable Joystick controls that are used in GameController inputs so we don't get double events + std::vector joy_button_used_in_gc; + std::vector joy_axis_used_in_gc; + }; - using ControllerDataVector = std::vector; + using ControllerDataVector = std::vector; - bool InitializeSubsystem(); - void ShutdownSubsystem(); - void LoadSettings(SettingsInterface& si); - void SetHints(); + bool InitializeSubsystem(); + void ShutdownSubsystem(); + void LoadSettings(SettingsInterface& si); + void SetHints(); - ControllerDataVector::iterator GetControllerDataForJoystickId(int id); - ControllerDataVector::iterator GetControllerDataForPlayerId(int id); - int GetFreePlayerId() const; + ControllerDataVector::iterator GetControllerDataForJoystickId(int id); + ControllerDataVector::iterator GetControllerDataForPlayerId(int id); + int GetFreePlayerId() const; - bool OpenGameController(int index); - bool CloseGameController(int joystick_index); - bool HandleControllerAxisEvent(const SDL_ControllerAxisEvent* event); - bool HandleControllerButtonEvent(const SDL_ControllerButtonEvent* event); - bool HandleJoystickAxisEvent(const SDL_JoyAxisEvent* event); - bool HandleJoystickButtonEvent(const SDL_JoyButtonEvent* event); - void SendRumbleUpdate(ControllerData* cd); + bool OpenGameController(int index); + bool CloseGameController(int joystick_index); + bool HandleControllerAxisEvent(const SDL_ControllerAxisEvent* event); + bool HandleControllerButtonEvent(const SDL_ControllerButtonEvent* event); + bool HandleJoystickAxisEvent(const SDL_JoyAxisEvent* event); + bool HandleJoystickButtonEvent(const SDL_JoyButtonEvent* event); + void SendRumbleUpdate(ControllerData* cd); - ControllerDataVector m_controllers; + ControllerDataVector m_controllers; - bool m_sdl_subsystem_initialized = false; - bool m_controller_enhanced_mode = false; + bool m_sdl_subsystem_initialized = false; + bool m_controller_enhanced_mode = false; }; diff --git a/pcsx2/Frontend/XInputSource.cpp b/pcsx2/Frontend/XInputSource.cpp index dc6ce7a46a..dabc1942b5 100644 --- a/pcsx2/Frontend/XInputSource.cpp +++ b/pcsx2/Frontend/XInputSource.cpp @@ -56,20 +56,9 @@ const char* XInputSource::s_button_names[XInputSource::NUM_BUTTONS] = { "Guide", // XINPUT_GAMEPAD_GUIDE }; const u16 XInputSource::s_button_masks[XInputSource::NUM_BUTTONS] = { - XINPUT_GAMEPAD_DPAD_UP, - XINPUT_GAMEPAD_DPAD_DOWN, - XINPUT_GAMEPAD_DPAD_LEFT, - XINPUT_GAMEPAD_DPAD_RIGHT, - XINPUT_GAMEPAD_START, - XINPUT_GAMEPAD_BACK, - XINPUT_GAMEPAD_LEFT_THUMB, - XINPUT_GAMEPAD_RIGHT_THUMB, - XINPUT_GAMEPAD_LEFT_SHOULDER, - XINPUT_GAMEPAD_RIGHT_SHOULDER, - XINPUT_GAMEPAD_A, - XINPUT_GAMEPAD_B, - XINPUT_GAMEPAD_X, - XINPUT_GAMEPAD_Y, + XINPUT_GAMEPAD_DPAD_UP, XINPUT_GAMEPAD_DPAD_DOWN, XINPUT_GAMEPAD_DPAD_LEFT, XINPUT_GAMEPAD_DPAD_RIGHT, XINPUT_GAMEPAD_START, + XINPUT_GAMEPAD_BACK, XINPUT_GAMEPAD_LEFT_THUMB, XINPUT_GAMEPAD_RIGHT_THUMB, XINPUT_GAMEPAD_LEFT_SHOULDER, XINPUT_GAMEPAD_RIGHT_SHOULDER, + XINPUT_GAMEPAD_A, XINPUT_GAMEPAD_B, XINPUT_GAMEPAD_X, XINPUT_GAMEPAD_Y, 0x400, // XINPUT_GAMEPAD_GUIDE }; static const GenericInputBinding s_xinput_generic_binding_button_mapping[] = { @@ -114,18 +103,15 @@ bool XInputSource::Initialize(SettingsInterface& si, std::unique_lock