|
|
@ -15,7 +15,7 @@ namespace InputCommon { |
|
|
|
|
|
|
|
|
namespace { |
|
|
namespace { |
|
|
Common::UUID GetGUID(SDL_Joystick* joystick) { |
|
|
Common::UUID GetGUID(SDL_Joystick* joystick) { |
|
|
const SDL_JoystickGUID guid = SDL_JoystickGetGUID(joystick); |
|
|
|
|
|
|
|
|
const SDL_GUID guid = SDL_GetJoystickGUID(joystick); |
|
|
std::array<u8, 16> data{}; |
|
|
std::array<u8, 16> data{}; |
|
|
std::memcpy(data.data(), guid.data, sizeof(data)); |
|
|
std::memcpy(data.data(), guid.data, sizeof(data)); |
|
|
// Clear controller name crc
|
|
|
// Clear controller name crc
|
|
|
@ -35,9 +35,9 @@ static int SDLEventWatcher(void* user_data, SDL_Event* event) { |
|
|
class SDLJoystick { |
|
|
class SDLJoystick { |
|
|
public: |
|
|
public: |
|
|
SDLJoystick(Common::UUID guid_, int port_, SDL_Joystick* joystick, |
|
|
SDLJoystick(Common::UUID guid_, int port_, SDL_Joystick* joystick, |
|
|
SDL_GameController* game_controller) |
|
|
|
|
|
: guid{guid_}, port{port_}, sdl_joystick{joystick, &SDL_JoystickClose}, |
|
|
|
|
|
sdl_controller{game_controller, &SDL_GameControllerClose} { |
|
|
|
|
|
|
|
|
SDL_Gamepad* game_controller) |
|
|
|
|
|
: guid{guid_}, port{port_}, sdl_joystick{joystick, &SDL_CloseJoystick}, |
|
|
|
|
|
sdl_controller{game_controller, &SDL_CloseGamepad} { |
|
|
EnableMotion(); |
|
|
EnableMotion(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -45,18 +45,18 @@ public: |
|
|
if (!sdl_controller) { |
|
|
if (!sdl_controller) { |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
SDL_GameController* controller = sdl_controller.get(); |
|
|
|
|
|
|
|
|
SDL_Gamepad* controller = sdl_controller.get(); |
|
|
if (HasMotion()) { |
|
|
if (HasMotion()) { |
|
|
SDL_GameControllerSetSensorEnabled(controller, SDL_SENSOR_ACCEL, SDL_FALSE); |
|
|
|
|
|
SDL_GameControllerSetSensorEnabled(controller, SDL_SENSOR_GYRO, SDL_FALSE); |
|
|
|
|
|
|
|
|
SDL_SetGamepadSensorEnabled(controller, SDL_SENSOR_ACCEL, false); |
|
|
|
|
|
SDL_SetGamepadSensorEnabled(controller, SDL_SENSOR_GYRO, false); |
|
|
} |
|
|
} |
|
|
has_accel = SDL_GameControllerHasSensor(controller, SDL_SENSOR_ACCEL) == SDL_TRUE; |
|
|
|
|
|
has_gyro = SDL_GameControllerHasSensor(controller, SDL_SENSOR_GYRO) == SDL_TRUE; |
|
|
|
|
|
|
|
|
has_accel = SDL_GamepadHasSensor(controller, SDL_SENSOR_ACCEL) == true; |
|
|
|
|
|
has_gyro = SDL_GamepadHasSensor(controller, SDL_SENSOR_GYRO) == true; |
|
|
if (has_accel) { |
|
|
if (has_accel) { |
|
|
SDL_GameControllerSetSensorEnabled(controller, SDL_SENSOR_ACCEL, SDL_TRUE); |
|
|
|
|
|
|
|
|
SDL_SetGamepadSensorEnabled(controller, SDL_SENSOR_ACCEL, true); |
|
|
} |
|
|
} |
|
|
if (has_gyro) { |
|
|
if (has_gyro) { |
|
|
SDL_GameControllerSetSensorEnabled(controller, SDL_SENSOR_GYRO, SDL_TRUE); |
|
|
|
|
|
|
|
|
SDL_SetGamepadSensorEnabled(controller, SDL_SENSOR_GYRO, true); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -64,7 +64,7 @@ public: |
|
|
return has_gyro || has_accel; |
|
|
return has_gyro || has_accel; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
bool UpdateMotion(SDL_ControllerSensorEvent event) { |
|
|
|
|
|
|
|
|
bool UpdateMotion(SDL_GamepadSensorEvent event) { |
|
|
constexpr float gravity_constant = 9.80665f; |
|
|
constexpr float gravity_constant = 9.80665f; |
|
|
std::scoped_lock lock{mutex}; |
|
|
std::scoped_lock lock{mutex}; |
|
|
const u64 time_difference = event.timestamp - last_motion_update; |
|
|
const u64 time_difference = event.timestamp - last_motion_update; |
|
|
@ -136,11 +136,11 @@ public: |
|
|
f32 high_amplitude = vibration.high_amplitude * high_frequency_scale; |
|
|
f32 high_amplitude = vibration.high_amplitude * high_frequency_scale; |
|
|
|
|
|
|
|
|
if (sdl_controller) { |
|
|
if (sdl_controller) { |
|
|
return SDL_GameControllerRumble(sdl_controller.get(), static_cast<u16>(low_amplitude), |
|
|
|
|
|
|
|
|
return SDL_RumbleGamepad(sdl_controller.get(), static_cast<u16>(low_amplitude), |
|
|
static_cast<u16>(high_amplitude), |
|
|
static_cast<u16>(high_amplitude), |
|
|
rumble_max_duration_ms) != -1; |
|
|
rumble_max_duration_ms) != -1; |
|
|
} else if (sdl_joystick) { |
|
|
} else if (sdl_joystick) { |
|
|
return SDL_JoystickRumble(sdl_joystick.get(), static_cast<u16>(low_amplitude), |
|
|
|
|
|
|
|
|
return SDL_RumbleJoystick(sdl_joystick.get(), static_cast<u16>(low_amplitude), |
|
|
static_cast<u16>(high_amplitude), |
|
|
static_cast<u16>(high_amplitude), |
|
|
rumble_max_duration_ms) != -1; |
|
|
rumble_max_duration_ms) != -1; |
|
|
} |
|
|
} |
|
|
@ -150,11 +150,11 @@ public: |
|
|
|
|
|
|
|
|
bool HasHDRumble() const { |
|
|
bool HasHDRumble() const { |
|
|
if (sdl_controller) { |
|
|
if (sdl_controller) { |
|
|
const auto type = SDL_GameControllerGetType(sdl_controller.get()); |
|
|
|
|
|
return (type == SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO) || |
|
|
|
|
|
(type == SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_LEFT) || |
|
|
|
|
|
(type == SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT) || |
|
|
|
|
|
(type == SDL_CONTROLLER_TYPE_PS5); |
|
|
|
|
|
|
|
|
const auto type = SDL_GetGamepadType(sdl_controller.get()); |
|
|
|
|
|
return (type == SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_PRO) || |
|
|
|
|
|
(type == SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_LEFT) || |
|
|
|
|
|
(type == SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT) || |
|
|
|
|
|
(type == SDL_GAMEPAD_TYPE_PS5); |
|
|
} |
|
|
} |
|
|
return false; |
|
|
return false; |
|
|
} |
|
|
} |
|
|
@ -201,11 +201,11 @@ public: |
|
|
return sdl_joystick.get(); |
|
|
return sdl_joystick.get(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
SDL_GameController* GetSDLGameController() const { |
|
|
|
|
|
|
|
|
SDL_Gamepad* GetSDLGameController() const { |
|
|
return sdl_controller.get(); |
|
|
return sdl_controller.get(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void SetSDLJoystick(SDL_Joystick* joystick, SDL_GameController* controller) { |
|
|
|
|
|
|
|
|
void SetSDLJoystick(SDL_Joystick* joystick, SDL_Gamepad* controller) { |
|
|
sdl_joystick.reset(joystick); |
|
|
sdl_joystick.reset(joystick); |
|
|
sdl_controller.reset(controller); |
|
|
sdl_controller.reset(controller); |
|
|
} |
|
|
} |
|
|
@ -253,28 +253,28 @@ public: |
|
|
|
|
|
|
|
|
std::string GetControllerName() const { |
|
|
std::string GetControllerName() const { |
|
|
if (sdl_controller) { |
|
|
if (sdl_controller) { |
|
|
switch (SDL_GameControllerGetType(sdl_controller.get())) { |
|
|
|
|
|
case SDL_CONTROLLER_TYPE_XBOX360: |
|
|
|
|
|
|
|
|
switch (SDL_GetGamepadType(sdl_controller.get())) { |
|
|
|
|
|
case SDL_GAMEPAD_TYPE_XBOX360: |
|
|
return "Xbox 360 Controller"; |
|
|
return "Xbox 360 Controller"; |
|
|
case SDL_CONTROLLER_TYPE_XBOXONE: |
|
|
|
|
|
|
|
|
case SDL_GAMEPAD_TYPE_XBOXONE: |
|
|
return "Xbox One Controller"; |
|
|
return "Xbox One Controller"; |
|
|
case SDL_CONTROLLER_TYPE_PS3: |
|
|
|
|
|
|
|
|
case SDL_GAMEPAD_TYPE_PS3: |
|
|
return "DualShock 3 Controller"; |
|
|
return "DualShock 3 Controller"; |
|
|
case SDL_CONTROLLER_TYPE_PS4: |
|
|
|
|
|
|
|
|
case SDL_GAMEPAD_TYPE_PS4: |
|
|
return "DualShock 4 Controller"; |
|
|
return "DualShock 4 Controller"; |
|
|
case SDL_CONTROLLER_TYPE_PS5: |
|
|
|
|
|
|
|
|
case SDL_GAMEPAD_TYPE_PS5: |
|
|
return "DualSense Controller"; |
|
|
return "DualSense Controller"; |
|
|
default: |
|
|
default: |
|
|
break; |
|
|
break; |
|
|
} |
|
|
} |
|
|
const auto name = SDL_GameControllerName(sdl_controller.get()); |
|
|
|
|
|
|
|
|
const auto name = SDL_GetGamepadName(sdl_controller.get()); |
|
|
if (name) { |
|
|
if (name) { |
|
|
return name; |
|
|
return name; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (sdl_joystick) { |
|
|
if (sdl_joystick) { |
|
|
const auto name = SDL_JoystickName(sdl_joystick.get()); |
|
|
|
|
|
|
|
|
const auto name = SDL_GetJoystickName(sdl_joystick.get()); |
|
|
if (name) { |
|
|
if (name) { |
|
|
return name; |
|
|
return name; |
|
|
} |
|
|
} |
|
|
@ -286,8 +286,8 @@ public: |
|
|
private: |
|
|
private: |
|
|
Common::UUID guid; |
|
|
Common::UUID guid; |
|
|
int port; |
|
|
int port; |
|
|
std::unique_ptr<SDL_Joystick, decltype(&SDL_JoystickClose)> sdl_joystick; |
|
|
|
|
|
std::unique_ptr<SDL_GameController, decltype(&SDL_GameControllerClose)> sdl_controller; |
|
|
|
|
|
|
|
|
std::unique_ptr<SDL_Joystick, decltype(&SDL_CloseJoystick)> sdl_joystick; |
|
|
|
|
|
std::unique_ptr<SDL_Gamepad, decltype(&SDL_CloseGamepad)> sdl_controller; |
|
|
mutable std::mutex mutex; |
|
|
mutable std::mutex mutex; |
|
|
|
|
|
|
|
|
u64 last_motion_update{}; |
|
|
u64 last_motion_update{}; |
|
|
@ -323,7 +323,7 @@ std::shared_ptr<SDLJoystick> SDLDriver::GetSDLJoystickByGUID(const std::string& |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
std::shared_ptr<SDLJoystick> SDLDriver::GetSDLJoystickBySDLID(SDL_JoystickID sdl_id) { |
|
|
std::shared_ptr<SDLJoystick> SDLDriver::GetSDLJoystickBySDLID(SDL_JoystickID sdl_id) { |
|
|
auto sdl_joystick = SDL_JoystickFromInstanceID(sdl_id); |
|
|
|
|
|
|
|
|
auto sdl_joystick = SDL_GetJoystickFromID(sdl_id); |
|
|
const auto guid = GetGUID(sdl_joystick); |
|
|
const auto guid = GetGUID(sdl_joystick); |
|
|
|
|
|
|
|
|
std::scoped_lock lock{joystick_map_mutex}; |
|
|
std::scoped_lock lock{joystick_map_mutex}; |
|
|
@ -346,11 +346,11 @@ std::shared_ptr<SDLJoystick> SDLDriver::GetSDLJoystickBySDLID(SDL_JoystickID sdl |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void SDLDriver::InitJoystick(int joystick_index) { |
|
|
void SDLDriver::InitJoystick(int joystick_index) { |
|
|
SDL_Joystick* sdl_joystick = SDL_JoystickOpen(joystick_index); |
|
|
|
|
|
SDL_GameController* sdl_gamecontroller = nullptr; |
|
|
|
|
|
|
|
|
SDL_Joystick* sdl_joystick = SDL_OpenJoystick(joystick_index); |
|
|
|
|
|
SDL_Gamepad* sdl_gamecontroller = nullptr; |
|
|
|
|
|
|
|
|
if (SDL_IsGameController(joystick_index)) { |
|
|
|
|
|
sdl_gamecontroller = SDL_GameControllerOpen(joystick_index); |
|
|
|
|
|
|
|
|
if (SDL_IsGamepad(joystick_index)) { |
|
|
|
|
|
sdl_gamecontroller = SDL_OpenGamepad(joystick_index); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (!sdl_joystick) { |
|
|
if (!sdl_joystick) { |
|
|
@ -364,7 +364,7 @@ void SDLDriver::InitJoystick(int joystick_index) { |
|
|
if (guid.uuid[5] == 0x05 && guid.uuid[4] == 0x7e && |
|
|
if (guid.uuid[5] == 0x05 && guid.uuid[4] == 0x7e && |
|
|
(guid.uuid[8] == 0x06 || guid.uuid[8] == 0x07)) { |
|
|
(guid.uuid[8] == 0x06 || guid.uuid[8] == 0x07)) { |
|
|
LOG_WARNING(Input, "Preferring joycon driver for device index {}", joystick_index); |
|
|
LOG_WARNING(Input, "Preferring joycon driver for device index {}", joystick_index); |
|
|
SDL_JoystickClose(sdl_joystick); |
|
|
|
|
|
|
|
|
SDL_CloseJoystick(sdl_joystick); |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
@ -372,7 +372,7 @@ void SDLDriver::InitJoystick(int joystick_index) { |
|
|
if (Settings::values.enable_procon_driver) { |
|
|
if (Settings::values.enable_procon_driver) { |
|
|
if (guid.uuid[5] == 0x05 && guid.uuid[4] == 0x7e && guid.uuid[8] == 0x09) { |
|
|
if (guid.uuid[5] == 0x05 && guid.uuid[4] == 0x7e && guid.uuid[8] == 0x09) { |
|
|
LOG_WARNING(Input, "Preferring joycon driver for device index {}", joystick_index); |
|
|
LOG_WARNING(Input, "Preferring joycon driver for device index {}", joystick_index); |
|
|
SDL_JoystickClose(sdl_joystick); |
|
|
|
|
|
|
|
|
SDL_CloseJoystick(sdl_joystick); |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
@ -428,35 +428,35 @@ void SDLDriver::PumpEvents() const { |
|
|
|
|
|
|
|
|
void SDLDriver::HandleGameControllerEvent(const SDL_Event& event) { |
|
|
void SDLDriver::HandleGameControllerEvent(const SDL_Event& event) { |
|
|
switch (event.type) { |
|
|
switch (event.type) { |
|
|
case SDL_JOYBUTTONUP: { |
|
|
|
|
|
|
|
|
case SDL_EVENT_JOYSTICK_BUTTON_UP: { |
|
|
if (const auto joystick = GetSDLJoystickBySDLID(event.jbutton.which)) { |
|
|
if (const auto joystick = GetSDLJoystickBySDLID(event.jbutton.which)) { |
|
|
const PadIdentifier identifier = joystick->GetPadIdentifier(); |
|
|
const PadIdentifier identifier = joystick->GetPadIdentifier(); |
|
|
SetButton(identifier, event.jbutton.button, false); |
|
|
SetButton(identifier, event.jbutton.button, false); |
|
|
} |
|
|
} |
|
|
break; |
|
|
break; |
|
|
} |
|
|
} |
|
|
case SDL_JOYBUTTONDOWN: { |
|
|
|
|
|
|
|
|
case SDL_EVENT_JOYSTICK_BUTTON_DOWN: { |
|
|
if (const auto joystick = GetSDLJoystickBySDLID(event.jbutton.which)) { |
|
|
if (const auto joystick = GetSDLJoystickBySDLID(event.jbutton.which)) { |
|
|
const PadIdentifier identifier = joystick->GetPadIdentifier(); |
|
|
const PadIdentifier identifier = joystick->GetPadIdentifier(); |
|
|
SetButton(identifier, event.jbutton.button, true); |
|
|
SetButton(identifier, event.jbutton.button, true); |
|
|
} |
|
|
} |
|
|
break; |
|
|
break; |
|
|
} |
|
|
} |
|
|
case SDL_JOYHATMOTION: { |
|
|
|
|
|
|
|
|
case SDL_EVENT_JOYSTICK_HAT_MOTION: { |
|
|
if (const auto joystick = GetSDLJoystickBySDLID(event.jhat.which)) { |
|
|
if (const auto joystick = GetSDLJoystickBySDLID(event.jhat.which)) { |
|
|
const PadIdentifier identifier = joystick->GetPadIdentifier(); |
|
|
const PadIdentifier identifier = joystick->GetPadIdentifier(); |
|
|
SetHatButton(identifier, event.jhat.hat, event.jhat.value); |
|
|
SetHatButton(identifier, event.jhat.hat, event.jhat.value); |
|
|
} |
|
|
} |
|
|
break; |
|
|
break; |
|
|
} |
|
|
} |
|
|
case SDL_JOYAXISMOTION: { |
|
|
|
|
|
|
|
|
case SDL_EVENT_JOYSTICK_AXIS_MOTION: { |
|
|
if (const auto joystick = GetSDLJoystickBySDLID(event.jaxis.which)) { |
|
|
if (const auto joystick = GetSDLJoystickBySDLID(event.jaxis.which)) { |
|
|
const PadIdentifier identifier = joystick->GetPadIdentifier(); |
|
|
const PadIdentifier identifier = joystick->GetPadIdentifier(); |
|
|
SetAxis(identifier, event.jaxis.axis, event.jaxis.value / 32767.0f); |
|
|
SetAxis(identifier, event.jaxis.axis, event.jaxis.value / 32767.0f); |
|
|
} |
|
|
} |
|
|
break; |
|
|
break; |
|
|
} |
|
|
} |
|
|
case SDL_CONTROLLERSENSORUPDATE: { |
|
|
|
|
|
|
|
|
case SDL_EVENT_GAMEPAD_SENSOR_UPDATE: { |
|
|
if (auto joystick = GetSDLJoystickBySDLID(event.csensor.which)) { |
|
|
if (auto joystick = GetSDLJoystickBySDLID(event.csensor.which)) { |
|
|
if (joystick->UpdateMotion(event.csensor)) { |
|
|
if (joystick->UpdateMotion(event.csensor)) { |
|
|
const PadIdentifier identifier = joystick->GetPadIdentifier(); |
|
|
const PadIdentifier identifier = joystick->GetPadIdentifier(); |
|
|
@ -465,18 +465,18 @@ void SDLDriver::HandleGameControllerEvent(const SDL_Event& event) { |
|
|
} |
|
|
} |
|
|
break; |
|
|
break; |
|
|
} |
|
|
} |
|
|
case SDL_JOYBATTERYUPDATED: { |
|
|
|
|
|
|
|
|
case SDL_EVENT_JOYSTICK_BATTERY_UPDATED: { |
|
|
if (auto joystick = GetSDLJoystickBySDLID(event.jbattery.which)) { |
|
|
if (auto joystick = GetSDLJoystickBySDLID(event.jbattery.which)) { |
|
|
const PadIdentifier identifier = joystick->GetPadIdentifier(); |
|
|
const PadIdentifier identifier = joystick->GetPadIdentifier(); |
|
|
SetBattery(identifier, joystick->GetBatteryLevel(event.jbattery.level)); |
|
|
SetBattery(identifier, joystick->GetBatteryLevel(event.jbattery.level)); |
|
|
} |
|
|
} |
|
|
break; |
|
|
break; |
|
|
} |
|
|
} |
|
|
case SDL_JOYDEVICEREMOVED: |
|
|
|
|
|
|
|
|
case SDL_EVENT_JOYSTICK_REMOVED: |
|
|
LOG_DEBUG(Input, "Controller removed with Instance_ID {}", event.jdevice.which); |
|
|
LOG_DEBUG(Input, "Controller removed with Instance_ID {}", event.jdevice.which); |
|
|
CloseJoystick(SDL_JoystickFromInstanceID(event.jdevice.which)); |
|
|
|
|
|
|
|
|
CloseJoystick(SDL_GetJoystickFromID(event.jdevice.which)); |
|
|
break; |
|
|
break; |
|
|
case SDL_JOYDEVICEADDED: |
|
|
|
|
|
|
|
|
case SDL_EVENT_JOYSTICK_ADDED: |
|
|
LOG_DEBUG(Input, "Controller connected with device index {}", event.jdevice.which); |
|
|
LOG_DEBUG(Input, "Controller connected with device index {}", event.jdevice.which); |
|
|
InitJoystick(event.jdevice.which); |
|
|
InitJoystick(event.jdevice.which); |
|
|
break; |
|
|
break; |
|
|
@ -502,8 +502,8 @@ SDLDriver::SDLDriver(std::string input_engine_) : InputEngine(std::move(input_en |
|
|
SDL_SetHint(SDL_HINT_ACCELEROMETER_AS_JOYSTICK, "0"); |
|
|
SDL_SetHint(SDL_HINT_ACCELEROMETER_AS_JOYSTICK, "0"); |
|
|
|
|
|
|
|
|
// Enable HIDAPI rumble. This prevents SDL from disabling motion on PS4 and PS5 controllers
|
|
|
// Enable HIDAPI rumble. This prevents SDL from disabling motion on PS4 and PS5 controllers
|
|
|
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE, "1"); |
|
|
|
|
|
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE, "1"); |
|
|
|
|
|
|
|
|
SDL_SetHint(SDL_HINT_JOYSTICK_ENHANCED_REPORTS, "1"); |
|
|
|
|
|
SDL_SetHint(SDL_HINT_JOYSTICK_ENHANCED_REPORTS, "1"); |
|
|
SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1"); |
|
|
SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1"); |
|
|
|
|
|
|
|
|
// Disable hidapi drivers for joycon controllers when the custom joycon driver is enabled
|
|
|
// Disable hidapi drivers for joycon controllers when the custom joycon driver is enabled
|
|
|
@ -533,8 +533,8 @@ SDLDriver::SDLDriver(std::string input_engine_) : InputEngine(std::move(input_en |
|
|
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_XBOX, "0"); |
|
|
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_XBOX, "0"); |
|
|
|
|
|
|
|
|
// If the frontend is going to manage the event loop, then we don't start one here
|
|
|
// If the frontend is going to manage the event loop, then we don't start one here
|
|
|
start_thread = SDL_WasInit(SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER) == 0; |
|
|
|
|
|
if (start_thread && SDL_Init(SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER) < 0) { |
|
|
|
|
|
|
|
|
start_thread = SDL_WasInit(SDL_INIT_JOYSTICK | SDL_INIT_GAMEPAD) == 0; |
|
|
|
|
|
if (start_thread && SDL_Init(SDL_INIT_JOYSTICK | SDL_INIT_GAMEPAD) < 0) { |
|
|
LOG_CRITICAL(Input, "SDL_Init failed with: {}", SDL_GetError()); |
|
|
LOG_CRITICAL(Input, "SDL_Init failed with: {}", SDL_GetError()); |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
@ -561,12 +561,12 @@ SDLDriver::SDLDriver(std::string input_engine_) : InputEngine(std::move(input_en |
|
|
|
|
|
|
|
|
SDLDriver::~SDLDriver() { |
|
|
SDLDriver::~SDLDriver() { |
|
|
CloseJoysticks(); |
|
|
CloseJoysticks(); |
|
|
SDL_DelEventWatch(&SDLEventWatcher, this); |
|
|
|
|
|
|
|
|
SDL_RemoveEventWatch(&SDLEventWatcher, this); |
|
|
|
|
|
|
|
|
initialized = false; |
|
|
initialized = false; |
|
|
if (start_thread) { |
|
|
if (start_thread) { |
|
|
vibration_thread.join(); |
|
|
vibration_thread.join(); |
|
|
SDL_QuitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER); |
|
|
|
|
|
|
|
|
SDL_QuitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_GAMEPAD); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -762,13 +762,13 @@ Common::ParamPackage SDLDriver::BuildMotionParam(int port, const Common::UUID& g |
|
|
Common::ParamPackage SDLDriver::BuildParamPackageForBinding( |
|
|
Common::ParamPackage SDLDriver::BuildParamPackageForBinding( |
|
|
int port, const Common::UUID& guid, const SDL_GameControllerButtonBind& binding) const { |
|
|
int port, const Common::UUID& guid, const SDL_GameControllerButtonBind& binding) const { |
|
|
switch (binding.bindType) { |
|
|
switch (binding.bindType) { |
|
|
case SDL_CONTROLLER_BINDTYPE_NONE: |
|
|
|
|
|
|
|
|
case SDL_GAMEPAD_BINDTYPE_NONE: |
|
|
break; |
|
|
break; |
|
|
case SDL_CONTROLLER_BINDTYPE_AXIS: |
|
|
|
|
|
|
|
|
case SDL_GAMEPAD_BINDTYPE_AXIS: |
|
|
return BuildAnalogParamPackageForButton(port, guid, binding.value.axis); |
|
|
return BuildAnalogParamPackageForButton(port, guid, binding.value.axis); |
|
|
case SDL_CONTROLLER_BINDTYPE_BUTTON: |
|
|
|
|
|
|
|
|
case SDL_GAMEPAD_BINDTYPE_BUTTON: |
|
|
return BuildButtonParamPackageForButton(port, guid, binding.value.button); |
|
|
return BuildButtonParamPackageForButton(port, guid, binding.value.button); |
|
|
case SDL_CONTROLLER_BINDTYPE_HAT: |
|
|
|
|
|
|
|
|
case SDL_GAMEPAD_BINDTYPE_HAT: |
|
|
return BuildHatParamPackageForButton(port, guid, binding.value.hat.hat, |
|
|
return BuildHatParamPackageForButton(port, guid, binding.value.hat.hat, |
|
|
static_cast<u8>(binding.value.hat.hat_mask)); |
|
|
static_cast<u8>(binding.value.hat.hat_mask)); |
|
|
} |
|
|
} |
|
|
@ -810,8 +810,8 @@ ButtonMapping SDLDriver::GetButtonMappingForDevice(const Common::ParamPackage& p |
|
|
|
|
|
|
|
|
// Add the missing bindings for ZL/ZR
|
|
|
// Add the missing bindings for ZL/ZR
|
|
|
static constexpr ZButtonBindings switch_to_sdl_axis{{ |
|
|
static constexpr ZButtonBindings switch_to_sdl_axis{{ |
|
|
{Settings::NativeButton::ZL, SDL_CONTROLLER_AXIS_TRIGGERLEFT}, |
|
|
|
|
|
{Settings::NativeButton::ZR, SDL_CONTROLLER_AXIS_TRIGGERRIGHT}, |
|
|
|
|
|
|
|
|
{Settings::NativeButton::ZL, SDL_GAMEPAD_AXIS_LEFT_TRIGGER}, |
|
|
|
|
|
{Settings::NativeButton::ZR, SDL_GAMEPAD_AXIS_RIGHT_TRIGGER}, |
|
|
}}; |
|
|
}}; |
|
|
|
|
|
|
|
|
// Parameters contain two joysticks return dual
|
|
|
// Parameters contain two joysticks return dual
|
|
|
@ -830,41 +830,41 @@ ButtonMapping SDLDriver::GetButtonMappingForDevice(const Common::ParamPackage& p |
|
|
ButtonBindings SDLDriver::GetDefaultButtonBinding( |
|
|
ButtonBindings SDLDriver::GetDefaultButtonBinding( |
|
|
const std::shared_ptr<SDLJoystick>& joystick) const { |
|
|
const std::shared_ptr<SDLJoystick>& joystick) const { |
|
|
// Default SL/SR mapping for other controllers
|
|
|
// Default SL/SR mapping for other controllers
|
|
|
auto sll_button = SDL_CONTROLLER_BUTTON_LEFTSHOULDER; |
|
|
|
|
|
auto srl_button = SDL_CONTROLLER_BUTTON_RIGHTSHOULDER; |
|
|
|
|
|
auto slr_button = SDL_CONTROLLER_BUTTON_LEFTSHOULDER; |
|
|
|
|
|
auto srr_button = SDL_CONTROLLER_BUTTON_RIGHTSHOULDER; |
|
|
|
|
|
|
|
|
auto sll_button = SDL_GAMEPAD_BUTTON_LEFT_SHOULDER; |
|
|
|
|
|
auto srl_button = SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER; |
|
|
|
|
|
auto slr_button = SDL_GAMEPAD_BUTTON_LEFT_SHOULDER; |
|
|
|
|
|
auto srr_button = SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER; |
|
|
|
|
|
|
|
|
if (joystick->IsJoyconLeft()) { |
|
|
if (joystick->IsJoyconLeft()) { |
|
|
sll_button = SDL_CONTROLLER_BUTTON_PADDLE2; |
|
|
|
|
|
srl_button = SDL_CONTROLLER_BUTTON_PADDLE4; |
|
|
|
|
|
|
|
|
sll_button = SDL_GAMEPAD_BUTTON_LEFT_PADDLE1; |
|
|
|
|
|
srl_button = SDL_GAMEPAD_BUTTON_LEFT_PADDLE2; |
|
|
} |
|
|
} |
|
|
if (joystick->IsJoyconRight()) { |
|
|
if (joystick->IsJoyconRight()) { |
|
|
slr_button = SDL_CONTROLLER_BUTTON_PADDLE3; |
|
|
|
|
|
srr_button = SDL_CONTROLLER_BUTTON_PADDLE1; |
|
|
|
|
|
|
|
|
slr_button = SDL_GAMEPAD_BUTTON_RIGHT_PADDLE2; |
|
|
|
|
|
srr_button = SDL_GAMEPAD_BUTTON_RIGHT_PADDLE1; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
return { |
|
|
return { |
|
|
std::pair{Settings::NativeButton::A, SDL_CONTROLLER_BUTTON_B}, |
|
|
|
|
|
{Settings::NativeButton::B, SDL_CONTROLLER_BUTTON_A}, |
|
|
|
|
|
{Settings::NativeButton::X, SDL_CONTROLLER_BUTTON_Y}, |
|
|
|
|
|
{Settings::NativeButton::Y, SDL_CONTROLLER_BUTTON_X}, |
|
|
|
|
|
{Settings::NativeButton::LStick, SDL_CONTROLLER_BUTTON_LEFTSTICK}, |
|
|
|
|
|
{Settings::NativeButton::RStick, SDL_CONTROLLER_BUTTON_RIGHTSTICK}, |
|
|
|
|
|
{Settings::NativeButton::L, SDL_CONTROLLER_BUTTON_LEFTSHOULDER}, |
|
|
|
|
|
{Settings::NativeButton::R, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER}, |
|
|
|
|
|
{Settings::NativeButton::Plus, SDL_CONTROLLER_BUTTON_START}, |
|
|
|
|
|
{Settings::NativeButton::Minus, SDL_CONTROLLER_BUTTON_BACK}, |
|
|
|
|
|
{Settings::NativeButton::DLeft, SDL_CONTROLLER_BUTTON_DPAD_LEFT}, |
|
|
|
|
|
{Settings::NativeButton::DUp, SDL_CONTROLLER_BUTTON_DPAD_UP}, |
|
|
|
|
|
{Settings::NativeButton::DRight, SDL_CONTROLLER_BUTTON_DPAD_RIGHT}, |
|
|
|
|
|
{Settings::NativeButton::DDown, SDL_CONTROLLER_BUTTON_DPAD_DOWN}, |
|
|
|
|
|
|
|
|
std::pair{Settings::NativeButton::A, SDL_GAMEPAD_BUTTON_EAST}, |
|
|
|
|
|
{Settings::NativeButton::B, SDL_GAMEPAD_BUTTON_SOUTH}, |
|
|
|
|
|
{Settings::NativeButton::X, SDL_GAMEPAD_BUTTON_NORTH}, |
|
|
|
|
|
{Settings::NativeButton::Y, SDL_GAMEPAD_BUTTON_WEST}, |
|
|
|
|
|
{Settings::NativeButton::LStick, SDL_GAMEPAD_BUTTON_LEFT_STICK}, |
|
|
|
|
|
{Settings::NativeButton::RStick, SDL_GAMEPAD_BUTTON_RIGHT_STICK}, |
|
|
|
|
|
{Settings::NativeButton::L, SDL_GAMEPAD_BUTTON_LEFT_SHOULDER}, |
|
|
|
|
|
{Settings::NativeButton::R, SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER}, |
|
|
|
|
|
{Settings::NativeButton::Plus, SDL_GAMEPAD_BUTTON_START}, |
|
|
|
|
|
{Settings::NativeButton::Minus, SDL_GAMEPAD_BUTTON_BACK}, |
|
|
|
|
|
{Settings::NativeButton::DLeft, SDL_GAMEPAD_BUTTON_DPAD_LEFT}, |
|
|
|
|
|
{Settings::NativeButton::DUp, SDL_GAMEPAD_BUTTON_DPAD_UP}, |
|
|
|
|
|
{Settings::NativeButton::DRight, SDL_GAMEPAD_BUTTON_DPAD_RIGHT}, |
|
|
|
|
|
{Settings::NativeButton::DDown, SDL_GAMEPAD_BUTTON_DPAD_DOWN}, |
|
|
{Settings::NativeButton::SLLeft, sll_button}, |
|
|
{Settings::NativeButton::SLLeft, sll_button}, |
|
|
{Settings::NativeButton::SRLeft, srl_button}, |
|
|
{Settings::NativeButton::SRLeft, srl_button}, |
|
|
{Settings::NativeButton::SLRight, slr_button}, |
|
|
{Settings::NativeButton::SLRight, slr_button}, |
|
|
{Settings::NativeButton::SRRight, srr_button}, |
|
|
{Settings::NativeButton::SRRight, srr_button}, |
|
|
{Settings::NativeButton::Home, SDL_CONTROLLER_BUTTON_GUIDE}, |
|
|
|
|
|
{Settings::NativeButton::Screenshot, SDL_CONTROLLER_BUTTON_MISC1}, |
|
|
|
|
|
|
|
|
{Settings::NativeButton::Home, SDL_GAMEPAD_BUTTON_GUIDE}, |
|
|
|
|
|
{Settings::NativeButton::Screenshot, SDL_GAMEPAD_BUTTON_MISC1}, |
|
|
}; |
|
|
}; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -960,9 +960,9 @@ AnalogMapping SDLDriver::GetAnalogMappingForDevice(const Common::ParamPackage& p |
|
|
|
|
|
|
|
|
AnalogMapping mapping = {}; |
|
|
AnalogMapping mapping = {}; |
|
|
const auto& binding_left_x = |
|
|
const auto& binding_left_x = |
|
|
SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_LEFTX); |
|
|
|
|
|
|
|
|
SDL_GameControllerGetBindForAxis(controller, SDL_GAMEPAD_AXIS_LEFTX); |
|
|
const auto& binding_left_y = |
|
|
const auto& binding_left_y = |
|
|
SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_LEFTY); |
|
|
|
|
|
|
|
|
SDL_GameControllerGetBindForAxis(controller, SDL_GAMEPAD_AXIS_LEFTY); |
|
|
if (params.Has("guid2")) { |
|
|
if (params.Has("guid2")) { |
|
|
const auto identifier = joystick2->GetPadIdentifier(); |
|
|
const auto identifier = joystick2->GetPadIdentifier(); |
|
|
PreSetController(identifier); |
|
|
PreSetController(identifier); |
|
|
@ -987,9 +987,9 @@ AnalogMapping SDLDriver::GetAnalogMappingForDevice(const Common::ParamPackage& p |
|
|
left_offset_x, left_offset_y)); |
|
|
left_offset_x, left_offset_y)); |
|
|
} |
|
|
} |
|
|
const auto& binding_right_x = |
|
|
const auto& binding_right_x = |
|
|
SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_RIGHTX); |
|
|
|
|
|
|
|
|
SDL_GameControllerGetBindForAxis(controller, SDL_GAMEPAD_AXIS_RIGHTX); |
|
|
const auto& binding_right_y = |
|
|
const auto& binding_right_y = |
|
|
SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_RIGHTY); |
|
|
|
|
|
|
|
|
SDL_GameControllerGetBindForAxis(controller, SDL_GAMEPAD_AXIS_RIGHTY); |
|
|
const auto identifier = joystick->GetPadIdentifier(); |
|
|
const auto identifier = joystick->GetPadIdentifier(); |
|
|
PreSetController(identifier); |
|
|
PreSetController(identifier); |
|
|
PreSetAxis(identifier, binding_right_x.value.axis); |
|
|
PreSetAxis(identifier, binding_right_x.value.axis); |
|
|
@ -1105,13 +1105,13 @@ bool SDLDriver::IsStickInverted(const Common::ParamPackage& params) { |
|
|
const auto& axis_x = params.Get("axis_x", 0); |
|
|
const auto& axis_x = params.Get("axis_x", 0); |
|
|
const auto& axis_y = params.Get("axis_y", 0); |
|
|
const auto& axis_y = params.Get("axis_y", 0); |
|
|
const auto& binding_left_x = |
|
|
const auto& binding_left_x = |
|
|
SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_LEFTX); |
|
|
|
|
|
|
|
|
SDL_GameControllerGetBindForAxis(controller, SDL_GAMEPAD_AXIS_LEFTX); |
|
|
const auto& binding_right_x = |
|
|
const auto& binding_right_x = |
|
|
SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_RIGHTX); |
|
|
|
|
|
|
|
|
SDL_GameControllerGetBindForAxis(controller, SDL_GAMEPAD_AXIS_RIGHTX); |
|
|
const auto& binding_left_y = |
|
|
const auto& binding_left_y = |
|
|
SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_LEFTY); |
|
|
|
|
|
|
|
|
SDL_GameControllerGetBindForAxis(controller, SDL_GAMEPAD_AXIS_LEFTY); |
|
|
const auto& binding_right_y = |
|
|
const auto& binding_right_y = |
|
|
SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_RIGHTY); |
|
|
|
|
|
|
|
|
SDL_GameControllerGetBindForAxis(controller, SDL_GAMEPAD_AXIS_RIGHTY); |
|
|
|
|
|
|
|
|
if (axis_x != binding_left_y.value.axis && axis_x != binding_right_y.value.axis) { |
|
|
if (axis_x != binding_left_y.value.axis && axis_x != binding_right_y.value.axis) { |
|
|
return false; |
|
|
return false; |
|
|
|