rpcsx/rpcs3/Input/hid_pad_handler.h

145 lines
3.2 KiB
C
Raw Permalink Normal View History

2021-02-11 22:13:21 +01:00
#pragma once
#include "Emu/Io/PadHandler.h"
#include "util/CRC.h"
#include "util/Thread.h"
2021-02-11 22:13:21 +01:00
#include "hidapi.h"
2025-03-03 19:59:08 +01:00
#ifdef ANDROID
#include "hidapi_libusb.h"
#endif
2025-02-11 03:00:37 +01:00
#include <mutex>
2025-03-03 19:59:08 +01:00
#ifdef ANDROID
using hid_enumerated_device_type = int;
using hid_enumerated_device_view = int;
struct android_usb_device
{
int fd;
u16 vendorId;
u16 productId;
};
2025-03-03 19:59:08 +01:00
inline constexpr auto hid_enumerated_device_default = -1;
extern std::vector<android_usb_device> g_android_usb_devices;
2025-03-03 19:59:08 +01:00
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
2021-02-11 22:13:21 +01:00
struct CalibData
{
s16 bias = 0;
s32 sens_numer = 0;
s32 sens_denom = 0;
2021-02-11 22:13:21 +01:00
};
enum CalibIndex
{
// gyro
PITCH = 0,
YAW,
ROLL,
// accel
X,
Y,
Z,
COUNT
};
class HidDevice : public PadDevice
{
public:
void close();
2021-02-11 22:13:21 +01:00
hid_device* hidDevice{nullptr};
#ifdef _WIN32
hid_device* bt_device{nullptr}; // Used in ps move handler
#endif
2025-03-03 19:59:08 +01:00
hid_enumerated_device_type path = hid_enumerated_device_default;
2021-02-11 22:13:21 +01:00
u8 led_delay_on{0};
u8 led_delay_off{0};
2021-02-28 04:32:08 +01:00
u8 battery_level{0};
u8 last_battery_level{0};
u8 cable_state{0};
2021-02-11 22:13:21 +01:00
};
struct id_pair
{
u16 m_vid = 0;
u16 m_pid = 0;
};
2021-02-11 22:13:21 +01:00
template <class Device>
class hid_pad_handler : public PadHandlerBase
{
public:
hid_pad_handler(pad_handler type, std::vector<id_pair> ids);
2021-02-11 22:13:21 +01:00
~hid_pad_handler();
bool Init() override;
void process() override;
2022-08-13 09:56:04 +02:00
std::vector<pad_list_entry> list_devices() override;
2025-03-04 02:55:59 +01:00
std::vector<pad_list_entry> list_connected_devices();
2021-02-11 22:13:21 +01:00
protected:
enum class DataStatus
{
NewData,
NoNewData,
ReadError,
};
CRCPP::CRC::Table<u32, 32> crcTable{CRCPP::CRC::CRC_32()};
std::vector<id_pair> m_ids;
2021-02-11 22:13:21 +01:00
// pseudo 'controller id' to keep track of unique controllers
std::map<std::string, std::shared_ptr<Device>> m_controllers;
2025-03-03 19:59:08 +01:00
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;
2021-02-11 22:13:21 +01:00
void enumerate_devices();
void update_devices();
2021-02-11 22:13:21 +01:00
std::shared_ptr<Device> get_hid_device(const std::string& padId);
2025-03-03 19:59:08 +01:00
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;
2021-02-11 22:13:21 +01:00
static s16 apply_calibration(s32 raw_value, const CalibData& calib_data)
2021-02-11 22:13:21 +01:00
{
const s32 biased = raw_value - calib_data.bias;
const s32 quot = calib_data.sens_numer / calib_data.sens_denom;
const s32 rem = calib_data.sens_numer % calib_data.sens_denom;
const s32 output = (quot * biased) + ((rem * biased) / calib_data.sens_denom);
2021-02-11 22:13:21 +01:00
return static_cast<s16>(std::clamp<s32>(output, s16{smin}, s16{smax}));
2021-02-11 22:13:21 +01:00
}
2021-04-07 23:05:18 +02:00
static s16 read_s16(const void* buf)
2021-02-11 22:13:21 +01:00
{
2021-04-07 23:05:18 +02:00
return *static_cast<const s16*>(buf);
2021-02-11 22:13:21 +01:00
}
2021-04-07 23:05:18 +02:00
static u32 read_u32(const void* buf)
2021-02-11 22:13:21 +01:00
{
2021-04-07 23:05:18 +02:00
return *static_cast<const u32*>(buf);
2021-02-11 22:13:21 +01:00
}
static u32 get_battery_color(u8 battery_level, u32 brightness);
2021-03-03 00:33:10 +01:00
2021-02-11 22:13:21 +01:00
private:
std::shared_ptr<PadDevice> get_device(const std::string& device) override;
};