mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-19 19:15:26 +00:00
hid: add support of android devices
This commit is contained in:
parent
d766baef12
commit
8100779512
12 changed files with 81 additions and 26 deletions
|
@ -218,7 +218,7 @@ void ds3_pad_handler::init_config(cfg_pad* cfg)
|
|||
cfg->from_default();
|
||||
}
|
||||
|
||||
void ds3_pad_handler::check_add_device(hid_device* hidDevice, std::string_view path, std::wstring_view wide_serial)
|
||||
void ds3_pad_handler::check_add_device(hid_device* hidDevice, hid_enumerated_device_view path, std::wstring_view wide_serial)
|
||||
{
|
||||
if (!hidDevice)
|
||||
{
|
||||
|
@ -508,12 +508,16 @@ bool ds3_pad_handler::get_is_right_stick(const std::shared_ptr<PadDevice>& /*dev
|
|||
PadHandlerBase::connection ds3_pad_handler::update_connection(const std::shared_ptr<PadDevice>& device)
|
||||
{
|
||||
ds3_device* dev = static_cast<ds3_device*>(device.get());
|
||||
if (!dev || dev->path.empty())
|
||||
if (!dev || dev->path == hid_enumerated_device_default)
|
||||
return connection::disconnected;
|
||||
|
||||
if (dev->hidDevice == nullptr)
|
||||
{
|
||||
#ifdef ANDROID
|
||||
if (hid_device* hid_dev = hid_libusb_wrap_sys_device(dev->path, -1))
|
||||
#else
|
||||
if (hid_device* hid_dev = hid_open_path(dev->path.c_str()))
|
||||
#endif
|
||||
{
|
||||
if (hid_set_nonblocking(hid_dev, 1) == -1)
|
||||
{
|
||||
|
|
|
@ -145,7 +145,7 @@ public:
|
|||
private:
|
||||
ds3_pad_handler::DataStatus get_data(ds3_device* ds3dev) override;
|
||||
int send_output_report(ds3_device* ds3dev) override;
|
||||
void check_add_device(hid_device* hidDevice, std::string_view path, std::wstring_view serial) override;
|
||||
void check_add_device(hid_device* hidDevice, hid_enumerated_device_view path, std::wstring_view serial) override;
|
||||
|
||||
bool get_is_left_trigger(const std::shared_ptr<PadDevice>& device, u64 keyCode) override;
|
||||
bool get_is_right_trigger(const std::shared_ptr<PadDevice>& device, u64 keyCode) override;
|
||||
|
|
|
@ -556,7 +556,7 @@ bool ds4_pad_handler::GetCalibrationData(DS4Device* ds4Dev) const
|
|||
return true;
|
||||
}
|
||||
|
||||
void ds4_pad_handler::check_add_device(hid_device* hidDevice, std::string_view path, std::wstring_view wide_serial)
|
||||
void ds4_pad_handler::check_add_device(hid_device* hidDevice, hid_enumerated_device_view path, std::wstring_view wide_serial)
|
||||
{
|
||||
if (!hidDevice)
|
||||
{
|
||||
|
@ -831,13 +831,17 @@ bool ds4_pad_handler::get_is_touch_pad_motion(const std::shared_ptr<PadDevice>&
|
|||
PadHandlerBase::connection ds4_pad_handler::update_connection(const std::shared_ptr<PadDevice>& device)
|
||||
{
|
||||
DS4Device* dev = static_cast<DS4Device*>(device.get());
|
||||
if (!dev || dev->path.empty())
|
||||
if (!dev || dev->path == hid_enumerated_device_default)
|
||||
return connection::disconnected;
|
||||
|
||||
if (dev->hidDevice == nullptr)
|
||||
{
|
||||
// try to reconnect
|
||||
#ifdef ANDROID
|
||||
if (hid_device* hid_dev = hid_libusb_wrap_sys_device(dev->path, -1))
|
||||
#else
|
||||
if (hid_device* hid_dev = hid_open_path(dev->path.c_str()))
|
||||
#endif
|
||||
{
|
||||
if (hid_set_nonblocking(hid_dev, 1) == -1)
|
||||
{
|
||||
|
|
|
@ -184,7 +184,7 @@ private:
|
|||
// Copies data into padData if status is NewData, otherwise buffer is untouched
|
||||
DataStatus get_data(DS4Device* ds4Device) override;
|
||||
int send_output_report(DS4Device* device) override;
|
||||
void check_add_device(hid_device* hidDevice, std::string_view path, std::wstring_view serial) override;
|
||||
void check_add_device(hid_device* hidDevice, hid_enumerated_device_view path, std::wstring_view serial) override;
|
||||
|
||||
bool get_is_left_trigger(const std::shared_ptr<PadDevice>& device, u64 keyCode) override;
|
||||
bool get_is_right_trigger(const std::shared_ptr<PadDevice>& device, u64 keyCode) override;
|
||||
|
|
|
@ -99,7 +99,7 @@ dualsense_pad_handler::dualsense_pad_handler()
|
|||
m_thumb_threshold = thumb_max / 2;
|
||||
}
|
||||
|
||||
void dualsense_pad_handler::check_add_device(hid_device* hidDevice, std::string_view path, std::wstring_view wide_serial)
|
||||
void dualsense_pad_handler::check_add_device(hid_device* hidDevice, hid_enumerated_device_view path, std::wstring_view wide_serial)
|
||||
{
|
||||
if (!hidDevice)
|
||||
{
|
||||
|
@ -562,13 +562,17 @@ bool dualsense_pad_handler::get_is_touch_pad_motion(const std::shared_ptr<PadDev
|
|||
PadHandlerBase::connection dualsense_pad_handler::update_connection(const std::shared_ptr<PadDevice>& device)
|
||||
{
|
||||
DualSenseDevice* dev = static_cast<DualSenseDevice*>(device.get());
|
||||
if (!dev || dev->path.empty())
|
||||
if (!dev || dev->path == hid_enumerated_device_default)
|
||||
return connection::disconnected;
|
||||
|
||||
if (dev->hidDevice == nullptr)
|
||||
{
|
||||
// try to reconnect
|
||||
#ifdef ANDROID
|
||||
if (hid_device* hid_dev = hid_libusb_wrap_sys_device(dev->path, -1))
|
||||
#else
|
||||
if (hid_device* hid_dev = hid_open_path(dev->path.c_str()))
|
||||
#endif
|
||||
{
|
||||
if (hid_set_nonblocking(hid_dev, 1) == -1)
|
||||
{
|
||||
|
|
|
@ -245,7 +245,7 @@ private:
|
|||
bool get_calibration_data(DualSenseDevice* dev) const;
|
||||
|
||||
DataStatus get_data(DualSenseDevice* device) override;
|
||||
void check_add_device(hid_device* hidDevice, std::string_view path, std::wstring_view wide_serial) override;
|
||||
void check_add_device(hid_device* hidDevice, hid_enumerated_device_view path, std::wstring_view wide_serial) override;
|
||||
int send_output_report(DualSenseDevice* device) override;
|
||||
|
||||
bool get_is_left_trigger(const std::shared_ptr<PadDevice>& device, u64 keyCode) override;
|
||||
|
|
|
@ -18,6 +18,11 @@
|
|||
|
||||
LOG_CHANNEL(hid_log, "HID");
|
||||
|
||||
#ifdef ANDROID
|
||||
std::vector<int> g_android_usb_devices;
|
||||
std::mutex g_android_usb_devices_mutex;
|
||||
#endif
|
||||
|
||||
struct hid_instance
|
||||
{
|
||||
public:
|
||||
|
@ -56,9 +61,9 @@ public:
|
|||
|
||||
hid_log.notice("Initializing HIDAPI ...");
|
||||
|
||||
if (hid_init() != 0)
|
||||
if (int errorCode = hid_init(); errorCode != 0)
|
||||
{
|
||||
hid_log.fatal("hid_init error");
|
||||
hid_log.fatal("hid_init error %d", errorCode);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -179,9 +184,18 @@ template <class Device>
|
|||
void hid_pad_handler<Device>::enumerate_devices()
|
||||
{
|
||||
Timer timer;
|
||||
std::set<std::string> device_paths;
|
||||
std::map<std::string, std::wstring> serials;
|
||||
std::set<hid_enumerated_device_type> device_paths;
|
||||
std::map<hid_enumerated_device_type, std::wstring> serials;
|
||||
|
||||
#ifdef ANDROID
|
||||
{
|
||||
std::lock_guard lock(g_android_usb_devices_mutex);
|
||||
for (auto device : g_android_usb_devices)
|
||||
{
|
||||
device_paths.insert(device);
|
||||
}
|
||||
}
|
||||
#else
|
||||
for (const auto& [vid, pid] : m_ids)
|
||||
{
|
||||
hid_device_info* dev_info = hid_enumerate(vid, pid);
|
||||
|
@ -209,6 +223,7 @@ void hid_pad_handler<Device>::enumerate_devices()
|
|||
}
|
||||
hid_free_enumeration(head);
|
||||
}
|
||||
#endif
|
||||
hid_log.notice("%s enumeration found %d devices (%f ms)", m_type, device_paths.size(), timer.GetElapsedTimeInMilliSec());
|
||||
|
||||
std::lock_guard lock(m_enumeration_mutex);
|
||||
|
@ -254,7 +269,7 @@ void hid_pad_handler<Device>::update_devices()
|
|||
// Scrap devices that are not in the new list
|
||||
for (auto& controller : m_controllers)
|
||||
{
|
||||
if (controller.second && !controller.second->path.empty() && !m_new_enumerated_devices.contains(controller.second->path))
|
||||
if (controller.second && controller.second->path != hid_enumerated_device_default && !m_new_enumerated_devices.contains(controller.second->path))
|
||||
{
|
||||
controller.second->close();
|
||||
cfg_pad* config = controller.second->config;
|
||||
|
@ -284,7 +299,11 @@ void hid_pad_handler<Device>::update_devices()
|
|||
}
|
||||
#endif
|
||||
|
||||
if (hid_device* dev = hid_open_path(path.c_str()))
|
||||
#ifdef ANDROID
|
||||
if (hid_device* dev = hid_libusb_wrap_sys_device(path, -1))
|
||||
#else
|
||||
if (hid_device* dev = hid_open_path(path))
|
||||
#endif
|
||||
{
|
||||
if (const hid_device_info* info = hid_get_device_info(dev))
|
||||
{
|
||||
|
|
|
@ -6,8 +6,24 @@
|
|||
|
||||
#include "hidapi.h"
|
||||
|
||||
#ifdef ANDROID
|
||||
#include "hidapi_libusb.h"
|
||||
#endif
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#ifdef ANDROID
|
||||
using hid_enumerated_device_type = int;
|
||||
using hid_enumerated_device_view = int;
|
||||
inline constexpr auto hid_enumerated_device_default = -1;
|
||||
extern std::vector<int> g_android_usb_devices;
|
||||
extern std::mutex g_android_usb_devices_mutex;
|
||||
#else
|
||||
using hid_enumerated_device_type = std::string;
|
||||
using hid_enumerated_device_view = std::string_view;
|
||||
inline constexpr auto hid_enumerated_device_default = std::string();
|
||||
#endif
|
||||
|
||||
struct CalibData
|
||||
{
|
||||
s16 bias = 0;
|
||||
|
@ -38,7 +54,7 @@ public:
|
|||
#ifdef _WIN32
|
||||
hid_device* bt_device{nullptr}; // Used in ps move handler
|
||||
#endif
|
||||
std::string path;
|
||||
hid_enumerated_device_type path = hid_enumerated_device_default;
|
||||
u8 led_delay_on{0};
|
||||
u8 led_delay_off{0};
|
||||
u8 battery_level{0};
|
||||
|
@ -78,9 +94,9 @@ protected:
|
|||
// pseudo 'controller id' to keep track of unique controllers
|
||||
std::map<std::string, std::shared_ptr<Device>> m_controllers;
|
||||
|
||||
std::set<std::string> m_last_enumerated_devices;
|
||||
std::set<std::string> m_new_enumerated_devices;
|
||||
std::map<std::string, std::wstring> m_enumerated_serials;
|
||||
std::set<hid_enumerated_device_type> m_last_enumerated_devices;
|
||||
std::set<hid_enumerated_device_type> m_new_enumerated_devices;
|
||||
std::map<hid_enumerated_device_type, std::wstring> m_enumerated_serials;
|
||||
std::mutex m_enumeration_mutex;
|
||||
std::unique_ptr<named_thread<std::function<void()>>> m_enumeration_thread;
|
||||
|
||||
|
@ -88,7 +104,7 @@ protected:
|
|||
void update_devices();
|
||||
std::shared_ptr<Device> get_hid_device(const std::string& padId);
|
||||
|
||||
virtual void check_add_device(hid_device* hidDevice, std::string_view path, std::wstring_view serial) = 0;
|
||||
virtual void check_add_device(hid_device* hidDevice, hid_enumerated_device_view path, std::wstring_view serial) = 0;
|
||||
virtual int send_output_report(Device* device) = 0;
|
||||
virtual DataStatus get_data(Device* device) = 0;
|
||||
|
||||
|
|
|
@ -265,7 +265,7 @@ hid_device* ps_move_handler::connect_move_device(ps_move_device* device, std::st
|
|||
}
|
||||
#endif
|
||||
|
||||
void ps_move_handler::check_add_device(hid_device* hidDevice, std::string_view path, std::wstring_view wide_serial)
|
||||
void ps_move_handler::check_add_device(hid_device* hidDevice, hid_enumerated_device_view path, std::wstring_view wide_serial)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
if (!hidDevice)
|
||||
|
@ -422,7 +422,7 @@ ps_move_handler::DataStatus ps_move_handler::get_data(ps_move_device* device)
|
|||
PadHandlerBase::connection ps_move_handler::update_connection(const std::shared_ptr<PadDevice>& device)
|
||||
{
|
||||
ps_move_device* move_device = static_cast<ps_move_device*>(device.get());
|
||||
if (!move_device || move_device->path.empty())
|
||||
if (!move_device || move_device->path == hid_enumerated_device_default)
|
||||
return connection::disconnected;
|
||||
|
||||
if (move_device->hidDevice == nullptr)
|
||||
|
@ -433,8 +433,12 @@ PadHandlerBase::connection ps_move_handler::update_connection(const std::shared_
|
|||
{
|
||||
move_device->hidDevice = dev;
|
||||
}
|
||||
#else
|
||||
#ifdef ANDROID
|
||||
if (hid_device* dev = hid_libusb_wrap_sys_device(move_device->path, -1))
|
||||
#else
|
||||
if (hid_device* dev = hid_open_path(move_device->path.c_str()))
|
||||
#endif
|
||||
{
|
||||
if (hid_set_nonblocking(dev, 1) == -1)
|
||||
{
|
||||
|
|
|
@ -189,7 +189,7 @@ private:
|
|||
#endif
|
||||
|
||||
DataStatus get_data(ps_move_device* device) override;
|
||||
void check_add_device(hid_device* hidDevice, std::string_view path, std::wstring_view wide_serial) override;
|
||||
void check_add_device(hid_device* hidDevice, hid_enumerated_device_view path, std::wstring_view wide_serial) override;
|
||||
int send_output_report(ps_move_device* device) override;
|
||||
|
||||
bool get_is_left_trigger(const std::shared_ptr<PadDevice>& device, u64 keyCode) override;
|
||||
|
|
|
@ -149,7 +149,7 @@ void skateboard_pad_handler::init_config(cfg_pad* cfg)
|
|||
cfg->from_default();
|
||||
}
|
||||
|
||||
void skateboard_pad_handler::check_add_device(hid_device* hidDevice, std::string_view path, std::wstring_view wide_serial)
|
||||
void skateboard_pad_handler::check_add_device(hid_device* hidDevice, hid_enumerated_device_view path, std::wstring_view wide_serial)
|
||||
{
|
||||
if (!hidDevice)
|
||||
{
|
||||
|
@ -233,13 +233,17 @@ skateboard_pad_handler::DataStatus skateboard_pad_handler::get_data(skateboard_d
|
|||
PadHandlerBase::connection skateboard_pad_handler::update_connection(const std::shared_ptr<PadDevice>& device)
|
||||
{
|
||||
skateboard_device* dev = static_cast<skateboard_device*>(device.get());
|
||||
if (!dev || dev->path.empty())
|
||||
if (!dev || dev->path == hid_enumerated_device_default)
|
||||
return connection::disconnected;
|
||||
|
||||
if (dev->hidDevice == nullptr)
|
||||
{
|
||||
// try to reconnect
|
||||
#ifdef ANDROID
|
||||
if (hid_device* hid_dev = hid_libusb_wrap_sys_device(dev->path, -1))
|
||||
#else
|
||||
if (hid_device* hid_dev = hid_open_path(dev->path.c_str()))
|
||||
#endif
|
||||
{
|
||||
if (hid_set_nonblocking(hid_dev, 1) == -1)
|
||||
{
|
||||
|
|
|
@ -179,7 +179,7 @@ public:
|
|||
|
||||
private:
|
||||
DataStatus get_data(skateboard_device* device) override;
|
||||
void check_add_device(hid_device* hidDevice, std::string_view path, std::wstring_view wide_serial) override;
|
||||
void check_add_device(hid_device* hidDevice, hid_enumerated_device_view path, std::wstring_view wide_serial) override;
|
||||
int send_output_report(skateboard_device* device) override;
|
||||
|
||||
PadHandlerBase::connection update_connection(const std::shared_ptr<PadDevice>& device) override;
|
||||
|
|
Loading…
Add table
Reference in a new issue