Browse Source

revert input system to main

eden-orbis-ps4
lizzie 2 weeks ago
parent
commit
eec39bb3e6
  1. 3
      src/hid_core/resource_manager.cpp
  2. 3
      src/hid_core/resources/debug_pad/debug_pad.cpp
  3. 3
      src/hid_core/resources/digitizer/digitizer.cpp
  4. 3
      src/hid_core/resources/keyboard/keyboard.cpp
  5. 3
      src/hid_core/resources/mouse/debug_mouse.cpp
  6. 3
      src/hid_core/resources/mouse/mouse.cpp
  7. 3
      src/hid_core/resources/six_axis/console_six_axis.cpp
  8. 3
      src/hid_core/resources/six_axis/six_axis.cpp
  9. 3
      src/hid_core/resources/system_buttons/capture_button.cpp
  10. 3
      src/hid_core/resources/system_buttons/home_button.cpp
  11. 3
      src/hid_core/resources/system_buttons/sleep_button.cpp
  12. 15
      src/input_common/drivers/joycon.cpp
  13. 12
      src/input_common/drivers/joycon.h
  14. 41
      src/input_common/drivers/sdl_driver.cpp
  15. 38
      src/input_common/helpers/joycon_driver.cpp
  16. 55
      src/input_common/helpers/joycon_protocol/common_protocol.cpp
  17. 12
      src/input_common/helpers/joycon_protocol/joycon_types.h

3
src/hid_core/resource_manager.cpp

@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later

3
src/hid_core/resources/debug_pad/debug_pad.cpp

@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later

3
src/hid_core/resources/digitizer/digitizer.cpp

@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later

3
src/hid_core/resources/keyboard/keyboard.cpp

@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later

3
src/hid_core/resources/mouse/debug_mouse.cpp

@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later

3
src/hid_core/resources/mouse/mouse.cpp

@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later

3
src/hid_core/resources/six_axis/console_six_axis.cpp

@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later

3
src/hid_core/resources/six_axis/six_axis.cpp

@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later

3
src/hid_core/resources/system_buttons/capture_button.cpp

@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later

3
src/hid_core/resources/system_buttons/home_button.cpp

@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later

3
src/hid_core/resources/system_buttons/sleep_button.cpp

@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later

15
src/input_common/drivers/joycon.cpp

@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
@ -23,14 +23,12 @@ Joycons::Joycons(const std::string& input_engine_) : InputEngine(input_engine_)
return; return;
} }
LOG_INFO(Input, "Joycon driver Initialization started"); LOG_INFO(Input, "Joycon driver Initialization started");
#if SDL_VERSION_ATLEAST(2, 26, 4)
int const res = SDL_hid_init();
if (res == 0) {
const int init_res = SDL_hid_init();
if (init_res == 0) {
Setup(); Setup();
} else { } else {
LOG_ERROR(Input, "Hidapi could not be initialized. failed with error = {}", res);
LOG_ERROR(Input, "Hidapi could not be initialized. failed with error = {}", init_res);
} }
#endif
} }
Joycons::~Joycons() { Joycons::~Joycons() {
@ -57,9 +55,7 @@ void Joycons::Reset() {
} }
device->Stop(); device->Stop();
} }
#if SDL_VERSION_ATLEAST(2, 26, 4)
SDL_hid_exit(); SDL_hid_exit();
#endif
} }
void Joycons::Setup() { void Joycons::Setup() {
@ -84,9 +80,9 @@ void Joycons::Setup() {
} }
void Joycons::ScanThread(std::stop_token stop_token) { void Joycons::ScanThread(std::stop_token stop_token) {
#if SDL_VERSION_ATLEAST(2, 26, 4)
constexpr u16 nintendo_vendor_id = 0x057e; constexpr u16 nintendo_vendor_id = 0x057e;
Common::SetCurrentThreadName("JoyconScanThread"); Common::SetCurrentThreadName("JoyconScanThread");
do { do {
SDL_hid_device_info* devs = SDL_hid_enumerate(nintendo_vendor_id, 0x0); SDL_hid_device_info* devs = SDL_hid_enumerate(nintendo_vendor_id, 0x0);
SDL_hid_device_info* cur_dev = devs; SDL_hid_device_info* cur_dev = devs;
@ -102,7 +98,6 @@ void Joycons::ScanThread(std::stop_token stop_token) {
SDL_hid_free_enumeration(devs); SDL_hid_free_enumeration(devs);
} while (Common::StoppableTimedWait(stop_token, std::chrono::seconds{5})); } while (Common::StoppableTimedWait(stop_token, std::chrono::seconds{5}));
#endif
} }
bool Joycons::IsDeviceNew(SDL_hid_device_info* device_info) const { bool Joycons::IsDeviceNew(SDL_hid_device_info* device_info) const {

12
src/input_common/drivers/joycon.h

@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@ -9,14 +6,7 @@
#include <array> #include <array>
#include <span> #include <span>
#include <thread> #include <thread>
#include <SDL.h>
#if SDL_VERSION_ATLEAST(2, 26, 4)
# include <SDL_hidapi.h>
#else
struct SDL_hid_device;
struct SDL_hid_device_info;
#endif
#include <SDL_hidapi.h>
#include "input_common/input_engine.h" #include "input_common/input_engine.h"

41
src/input_common/drivers/sdl_driver.cpp

@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: 2018 Citra Emulator Project // SPDX-FileCopyrightText: 2018 Citra Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@ -42,7 +42,6 @@ public:
} }
void EnableMotion() { void EnableMotion() {
#if SDL_VERSION_ATLEAST(2, 26, 4)
if (!sdl_controller) { if (!sdl_controller) {
return; return;
} }
@ -59,14 +58,12 @@ public:
if (has_gyro) { if (has_gyro) {
SDL_GameControllerSetSensorEnabled(controller, SDL_SENSOR_GYRO, SDL_TRUE); SDL_GameControllerSetSensorEnabled(controller, SDL_SENSOR_GYRO, SDL_TRUE);
} }
#endif
} }
bool HasMotion() const { bool HasMotion() const {
return has_gyro || has_accel; return has_gyro || has_accel;
} }
#if SDL_VERSION_ATLEAST(2, 26, 4)
bool UpdateMotion(SDL_ControllerSensorEvent event) { bool UpdateMotion(SDL_ControllerSensorEvent event) {
constexpr float gravity_constant = 9.80665f; constexpr float gravity_constant = 9.80665f;
std::scoped_lock lock{mutex}; std::scoped_lock lock{mutex};
@ -108,7 +105,6 @@ public:
motion.delta_timestamp = time_difference * 1000; motion.delta_timestamp = time_difference * 1000;
return true; return true;
} }
#endif
const BasicMotion& GetMotion() const { const BasicMotion& GetMotion() const {
return motion; return motion;
@ -153,15 +149,13 @@ public:
} }
bool HasHDRumble() const { bool HasHDRumble() const {
#if SDL_VERSION_ATLEAST(2, 26, 4)
if (sdl_controller) { if (sdl_controller) {
auto const type = SDL_GameControllerGetType(sdl_controller.get());
const auto type = SDL_GameControllerGetType(sdl_controller.get());
return (type == SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO) || return (type == SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO) ||
(type == SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_LEFT) || (type == SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_LEFT) ||
(type == SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT) || (type == SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT) ||
(type == SDL_CONTROLLER_TYPE_PS5); (type == SDL_CONTROLLER_TYPE_PS5);
} }
#endif
return false; return false;
} }
@ -258,21 +252,26 @@ public:
} }
std::string GetControllerName() const { std::string GetControllerName() const {
#if SDL_VERSION_ATLEAST(2, 26, 4)
if (sdl_controller) { if (sdl_controller) {
switch (SDL_GameControllerGetType(sdl_controller.get())) { switch (SDL_GameControllerGetType(sdl_controller.get())) {
case SDL_CONTROLLER_TYPE_XBOX360: return "Xbox 360 Controller";
case SDL_CONTROLLER_TYPE_XBOXONE: return "Xbox One Controller";
case SDL_CONTROLLER_TYPE_PS3: return "DualShock 3 Controller";
case SDL_CONTROLLER_TYPE_PS4: return "DualShock 4 Controller";
case SDL_CONTROLLER_TYPE_PS5: return "DualSense Controller";
case SDL_CONTROLLER_TYPE_XBOX360:
return "Xbox 360 Controller";
case SDL_CONTROLLER_TYPE_XBOXONE:
return "Xbox One Controller";
case SDL_CONTROLLER_TYPE_PS3:
return "DualShock 3 Controller";
case SDL_CONTROLLER_TYPE_PS4:
return "DualShock 4 Controller";
case SDL_CONTROLLER_TYPE_PS5:
return "DualSense Controller";
default: default:
if (auto const name = SDL_GameControllerName(sdl_controller.get()); name)
return name;
break; break;
} }
const auto name = SDL_GameControllerName(sdl_controller.get());
if (name) {
return name;
}
} }
#endif
if (sdl_joystick) { if (sdl_joystick) {
const auto name = SDL_JoystickName(sdl_joystick.get()); const auto name = SDL_JoystickName(sdl_joystick.get());
@ -457,7 +456,6 @@ void SDLDriver::HandleGameControllerEvent(const SDL_Event& event) {
} }
break; break;
} }
#if SDL_VERSION_ATLEAST(2, 26, 4)
case SDL_CONTROLLERSENSORUPDATE: { case SDL_CONTROLLERSENSORUPDATE: {
if (auto joystick = GetSDLJoystickBySDLID(event.csensor.which)) { if (auto joystick = GetSDLJoystickBySDLID(event.csensor.which)) {
if (joystick->UpdateMotion(event.csensor)) { if (joystick->UpdateMotion(event.csensor)) {
@ -474,7 +472,6 @@ void SDLDriver::HandleGameControllerEvent(const SDL_Event& event) {
} }
break; break;
} }
#endif
case SDL_JOYDEVICEREMOVED: case SDL_JOYDEVICEREMOVED:
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_JoystickFromInstanceID(event.jdevice.which));
@ -492,7 +489,6 @@ void SDLDriver::CloseJoysticks() {
} }
SDLDriver::SDLDriver(std::string input_engine_) : InputEngine(std::move(input_engine_)) { SDLDriver::SDLDriver(std::string input_engine_) : InputEngine(std::move(input_engine_)) {
#if SDL_VERSION_ATLEAST(2, 26, 4)
// Set our application name. Currently passed to DBus by SDL and visible to the user through // Set our application name. Currently passed to DBus by SDL and visible to the user through
// their desktop environment. // their desktop environment.
SDL_SetHint(SDL_HINT_APP_NAME, "Eden"); SDL_SetHint(SDL_HINT_APP_NAME, "Eden");
@ -533,7 +529,6 @@ SDLDriver::SDLDriver(std::string input_engine_) : InputEngine(std::move(input_en
// Disable hidapi driver for xbox. Already default on Windows, this causes conflict with native // Disable hidapi driver for xbox. Already default on Windows, this causes conflict with native
// driver on Linux. // driver on Linux.
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_XBOX, "0"); SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_XBOX, "0");
#endif
// 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; start_thread = SDL_WasInit(SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER) == 0;
@ -838,7 +833,6 @@ ButtonBindings SDLDriver::GetDefaultButtonBinding(
auto slr_button = SDL_CONTROLLER_BUTTON_LEFTSHOULDER; auto slr_button = SDL_CONTROLLER_BUTTON_LEFTSHOULDER;
auto srr_button = SDL_CONTROLLER_BUTTON_RIGHTSHOULDER; auto srr_button = SDL_CONTROLLER_BUTTON_RIGHTSHOULDER;
#if SDL_VERSION_ATLEAST(2, 26, 4)
if (joystick->IsJoyconLeft()) { if (joystick->IsJoyconLeft()) {
sll_button = SDL_CONTROLLER_BUTTON_PADDLE2; sll_button = SDL_CONTROLLER_BUTTON_PADDLE2;
srl_button = SDL_CONTROLLER_BUTTON_PADDLE4; srl_button = SDL_CONTROLLER_BUTTON_PADDLE4;
@ -847,7 +841,6 @@ ButtonBindings SDLDriver::GetDefaultButtonBinding(
slr_button = SDL_CONTROLLER_BUTTON_PADDLE3; slr_button = SDL_CONTROLLER_BUTTON_PADDLE3;
srr_button = SDL_CONTROLLER_BUTTON_PADDLE1; srr_button = SDL_CONTROLLER_BUTTON_PADDLE1;
} }
#endif
return { return {
std::pair{Settings::NativeButton::A, SDL_CONTROLLER_BUTTON_B}, std::pair{Settings::NativeButton::A, SDL_CONTROLLER_BUTTON_B},
@ -869,9 +862,7 @@ ButtonBindings SDLDriver::GetDefaultButtonBinding(
{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::Home, SDL_CONTROLLER_BUTTON_GUIDE},
#if SDL_VERSION_ATLEAST(2, 26, 4)
{Settings::NativeButton::Screenshot, SDL_CONTROLLER_BUTTON_MISC1}, {Settings::NativeButton::Screenshot, SDL_CONTROLLER_BUTTON_MISC1},
#endif
}; };
} }

38
src/input_common/helpers/joycon_driver.cpp

@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@ -41,8 +38,8 @@ Common::Input::DriverResult JoyconDriver::RequestDeviceAccess(SDL_hid_device_inf
return Common::Input::DriverResult::UnsupportedControllerType; return Common::Input::DriverResult::UnsupportedControllerType;
} }
#if SDL_VERSION_ATLEAST(2, 26, 4)
hidapi_handle->handle = SDL_hid_open(device_info->vendor_id, device_info->product_id, device_info->serial_number);
hidapi_handle->handle =
SDL_hid_open(device_info->vendor_id, device_info->product_id, device_info->serial_number);
std::memcpy(&handle_serial_number, device_info->serial_number, 15); std::memcpy(&handle_serial_number, device_info->serial_number, 15);
if (!hidapi_handle->handle) { if (!hidapi_handle->handle) {
LOG_ERROR(Input, "Yuzu can't gain access to this device: ID {:04X}:{:04X}.", LOG_ERROR(Input, "Yuzu can't gain access to this device: ID {:04X}:{:04X}.",
@ -51,9 +48,6 @@ Common::Input::DriverResult JoyconDriver::RequestDeviceAccess(SDL_hid_device_inf
} }
SDL_hid_set_nonblocking(hidapi_handle->handle, 1); SDL_hid_set_nonblocking(hidapi_handle->handle, 1);
return Common::Input::DriverResult::Success; return Common::Input::DriverResult::Success;
#else
return Common::Input::DriverResult::UnsupportedControllerType;
#endif
} }
Common::Input::DriverResult JoyconDriver::InitializeDevice() { Common::Input::DriverResult JoyconDriver::InitializeDevice() {
@ -144,6 +138,8 @@ void JoyconDriver::InputThread(std::stop_token stop_token) {
Common::SetCurrentThreadName("JoyconInput"); Common::SetCurrentThreadName("JoyconInput");
input_thread_running = true; input_thread_running = true;
// Max update rate is 5ms, ensure we are always able to read a bit faster
constexpr int ThreadDelay = 3;
std::vector<u8> buffer(MaxBufferSize); std::vector<u8> buffer(MaxBufferSize);
while (!stop_token.stop_requested()) { while (!stop_token.stop_requested()) {
@ -154,17 +150,14 @@ void JoyconDriver::InputThread(std::stop_token stop_token) {
continue; continue;
} }
#if SDL_VERSION_ATLEAST(2, 26, 4)
// Max update rate is 5ms, ensure we are always able to read a bit faster
int constexpr thread_delay = 3;
// By disabling the input thread we can ensure custom commands will succeed as no package is // By disabling the input thread we can ensure custom commands will succeed as no package is
// skipped // skipped
if (!disable_input_thread) { if (!disable_input_thread) {
status = SDL_hid_read_timeout(hidapi_handle->handle, buffer.data(), buffer.size(), thread_delay);
status = SDL_hid_read_timeout(hidapi_handle->handle, buffer.data(), buffer.size(),
ThreadDelay);
} else { } else {
std::this_thread::sleep_for(std::chrono::milliseconds(thread_delay));
std::this_thread::sleep_for(std::chrono::milliseconds(ThreadDelay));
} }
#endif
if (IsPayloadCorrect(status, buffer)) { if (IsPayloadCorrect(status, buffer)) {
OnNewData(buffer); OnNewData(buffer);
@ -697,18 +690,19 @@ void JoyconDriver::SetCallbacks(const JoyconCallbacks& callbacks) {
joycon_poller->SetCallbacks(callbacks); joycon_poller->SetCallbacks(callbacks);
} }
Common::Input::DriverResult JoyconDriver::GetDeviceType(SDL_hid_device_info* device_info, ControllerType& controller_type) {
#if SDL_VERSION_ATLEAST(2, 26, 4)
Common::Input::DriverResult JoyconDriver::GetDeviceType(SDL_hid_device_info* device_info,
ControllerType& controller_type) {
static constexpr std::array<std::pair<u32, ControllerType>, 6> supported_devices{ static constexpr std::array<std::pair<u32, ControllerType>, 6> supported_devices{
std::pair<u32, ControllerType>{0x2006, ControllerType::Left}, std::pair<u32, ControllerType>{0x2006, ControllerType::Left},
{0x2007, ControllerType::Right}, {0x2007, ControllerType::Right},
{0x2009, ControllerType::Pro}, {0x2009, ControllerType::Pro},
}; };
constexpr u16 nintendo_vendor_id = 0x057e; constexpr u16 nintendo_vendor_id = 0x057e;
controller_type = ControllerType::None; controller_type = ControllerType::None;
if (device_info->vendor_id != nintendo_vendor_id)
if (device_info->vendor_id != nintendo_vendor_id) {
return Common::Input::DriverResult::UnsupportedControllerType; return Common::Input::DriverResult::UnsupportedControllerType;
}
for (const auto& [product_id, type] : supported_devices) { for (const auto& [product_id, type] : supported_devices) {
if (device_info->product_id == static_cast<u16>(product_id)) { if (device_info->product_id == static_cast<u16>(product_id)) {
@ -716,20 +710,16 @@ Common::Input::DriverResult JoyconDriver::GetDeviceType(SDL_hid_device_info* dev
return Common::Input::DriverResult::Success; return Common::Input::DriverResult::Success;
} }
} }
#endif
return Common::Input::DriverResult::UnsupportedControllerType; return Common::Input::DriverResult::UnsupportedControllerType;
} }
Common::Input::DriverResult JoyconDriver::GetSerialNumber(SDL_hid_device_info* device_info, SerialNumber& serial_number) {
#if SDL_VERSION_ATLEAST(2, 26, 4)
Common::Input::DriverResult JoyconDriver::GetSerialNumber(SDL_hid_device_info* device_info,
SerialNumber& serial_number) {
if (device_info->serial_number == nullptr) { if (device_info->serial_number == nullptr) {
return Common::Input::DriverResult::Unknown; return Common::Input::DriverResult::Unknown;
} }
std::memcpy(&serial_number, device_info->serial_number, 15); std::memcpy(&serial_number, device_info->serial_number, 15);
return Common::Input::DriverResult::Success; return Common::Input::DriverResult::Success;
#else
return Common::Input::DriverResult::Unknown;
#endif
} }
} // namespace InputCommon::Joycon } // namespace InputCommon::Joycon

55
src/input_common/helpers/joycon_protocol/common_protocol.cpp

@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@ -18,15 +15,11 @@ u8 JoyconCommonProtocol::GetCounter() {
} }
void JoyconCommonProtocol::SetBlocking() { void JoyconCommonProtocol::SetBlocking() {
#if SDL_VERSION_ATLEAST(2, 26, 4)
SDL_hid_set_nonblocking(hidapi_handle->handle, 0); SDL_hid_set_nonblocking(hidapi_handle->handle, 0);
#endif
} }
void JoyconCommonProtocol::SetNonBlocking() { void JoyconCommonProtocol::SetNonBlocking() {
#if SDL_VERSION_ATLEAST(2, 26, 4)
SDL_hid_set_nonblocking(hidapi_handle->handle, 1); SDL_hid_set_nonblocking(hidapi_handle->handle, 1);
#endif
} }
Common::Input::DriverResult JoyconCommonProtocol::GetDeviceType(ControllerType& controller_type) { Common::Input::DriverResult JoyconCommonProtocol::GetDeviceType(ControllerType& controller_type) {
@ -42,23 +35,26 @@ Common::Input::DriverResult JoyconCommonProtocol::GetDeviceType(ControllerType&
return result; return result;
} }
Common::Input::DriverResult JoyconCommonProtocol::CheckDeviceAccess(SDL_hid_device_info* device_info) {
Common::Input::DriverResult JoyconCommonProtocol::CheckDeviceAccess(
SDL_hid_device_info* device_info) {
ControllerType controller_type{ControllerType::None}; ControllerType controller_type{ControllerType::None};
const auto result = GetDeviceType(controller_type); const auto result = GetDeviceType(controller_type);
if (result != Common::Input::DriverResult::Success || controller_type == ControllerType::None) { if (result != Common::Input::DriverResult::Success || controller_type == ControllerType::None) {
return Common::Input::DriverResult::UnsupportedControllerType; return Common::Input::DriverResult::UnsupportedControllerType;
} }
#if SDL_VERSION_ATLEAST(2, 26, 4)
hidapi_handle->handle = SDL_hid_open(device_info->vendor_id, device_info->product_id, device_info->serial_number);
hidapi_handle->handle =
SDL_hid_open(device_info->vendor_id, device_info->product_id, device_info->serial_number);
if (!hidapi_handle->handle) { if (!hidapi_handle->handle) {
LOG_ERROR(Input, "Yuzu can't gain access to this device: ID {:04X}:{:04X}.", device_info->vendor_id, device_info->product_id);
LOG_ERROR(Input, "Yuzu can't gain access to this device: ID {:04X}:{:04X}.",
device_info->vendor_id, device_info->product_id);
return Common::Input::DriverResult::HandleInUse; return Common::Input::DriverResult::HandleInUse;
} }
SetNonBlocking(); SetNonBlocking();
return Common::Input::DriverResult::Success; return Common::Input::DriverResult::Success;
#else
return Common::Input::DriverResult::UnsupportedControllerType;
#endif
} }
Common::Input::DriverResult JoyconCommonProtocol::SetReportMode(ReportMode report_mode) { Common::Input::DriverResult JoyconCommonProtocol::SetReportMode(ReportMode report_mode) {
@ -67,21 +63,21 @@ Common::Input::DriverResult JoyconCommonProtocol::SetReportMode(ReportMode repor
} }
Common::Input::DriverResult JoyconCommonProtocol::SendRawData(std::span<const u8> buffer) { Common::Input::DriverResult JoyconCommonProtocol::SendRawData(std::span<const u8> buffer) {
#if SDL_VERSION_ATLEAST(2, 26, 4)
auto const result = SDL_hid_write(hidapi_handle->handle, buffer.data(), buffer.size());
if (result == -1)
const auto result = SDL_hid_write(hidapi_handle->handle, buffer.data(), buffer.size());
if (result == -1) {
return Common::Input::DriverResult::ErrorWritingData; return Common::Input::DriverResult::ErrorWritingData;
}
return Common::Input::DriverResult::Success; return Common::Input::DriverResult::Success;
#else
return Common::Input::DriverResult::ErrorWritingData;
#endif
} }
Common::Input::DriverResult JoyconCommonProtocol::GetSubCommandResponse(SubCommand sc, SubCommandResponse& output) {
#if SDL_VERSION_ATLEAST(2, 26, 4)
Common::Input::DriverResult JoyconCommonProtocol::GetSubCommandResponse(
SubCommand sc, SubCommandResponse& output) {
constexpr int timeout_mili = 66; constexpr int timeout_mili = 66;
constexpr int MaxTries = 10; constexpr int MaxTries = 10;
int tries = 0; int tries = 0;
do { do {
int result = SDL_hid_read_timeout(hidapi_handle->handle, reinterpret_cast<u8*>(&output), int result = SDL_hid_read_timeout(hidapi_handle->handle, reinterpret_cast<u8*>(&output),
sizeof(SubCommandResponse), timeout_mili); sizeof(SubCommandResponse), timeout_mili);
@ -92,8 +88,9 @@ Common::Input::DriverResult JoyconCommonProtocol::GetSubCommandResponse(SubComma
if (tries++ > MaxTries) { if (tries++ > MaxTries) {
return Common::Input::DriverResult::Timeout; return Common::Input::DriverResult::Timeout;
} }
} while (output.input_report.report_mode != ReportMode::SUBCMD_REPLY && output.sub_command != sc);
#endif
} while (output.input_report.report_mode != ReportMode::SUBCMD_REPLY &&
output.sub_command != sc);
return Common::Input::DriverResult::Success; return Common::Input::DriverResult::Success;
} }
@ -221,11 +218,12 @@ Common::Input::DriverResult JoyconCommonProtocol::ConfigureMCU(const MCUConfig&
return result; return result;
} }
Common::Input::DriverResult JoyconCommonProtocol::GetMCUDataResponse(ReportMode report_mode, MCUCommandResponse& output) {
#if SDL_VERSION_ATLEAST(2, 26, 4)
Common::Input::DriverResult JoyconCommonProtocol::GetMCUDataResponse(ReportMode report_mode,
MCUCommandResponse& output) {
constexpr int TimeoutMili = 200; constexpr int TimeoutMili = 200;
constexpr int MaxTries = 9; constexpr int MaxTries = 9;
int tries = 0; int tries = 0;
do { do {
int result = SDL_hid_read_timeout(hidapi_handle->handle, reinterpret_cast<u8*>(&output), int result = SDL_hid_read_timeout(hidapi_handle->handle, reinterpret_cast<u8*>(&output),
sizeof(MCUCommandResponse), TimeoutMili); sizeof(MCUCommandResponse), TimeoutMili);
@ -236,8 +234,9 @@ Common::Input::DriverResult JoyconCommonProtocol::GetMCUDataResponse(ReportMode
if (tries++ > MaxTries) { if (tries++ > MaxTries) {
return Common::Input::DriverResult::Timeout; return Common::Input::DriverResult::Timeout;
} }
} while (output.input_report.report_mode != report_mode || output.mcu_report == MCUReport::EmptyAwaitingCmd);
#endif
} while (output.input_report.report_mode != report_mode ||
output.mcu_report == MCUReport::EmptyAwaitingCmd);
return Common::Input::DriverResult::Success; return Common::Input::DriverResult::Success;
} }

12
src/input_common/helpers/joycon_protocol/joycon_types.h

@ -1,6 +1,3 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@ -13,14 +10,7 @@
#include <array> #include <array>
#include <functional> #include <functional>
#include <SDL.h>
#if SDL_VERSION_ATLEAST(2, 26, 4)
# include <SDL_hidapi.h>
#else
struct SDL_hid_device;
struct SDL_hid_device_info;
#endif
#include <SDL_hidapi.h>
#include "common/bit_field.h" #include "common/bit_field.h"
#include "common/common_funcs.h" #include "common/common_funcs.h"

Loading…
Cancel
Save