#pragma once #include "Emu/Io/PadHandler.h" #include "Utilities/CRC.h" #include "hidapi.h" #include class dualsense_pad_handler final : public PadHandlerBase { enum DualSenseKeyCodes { Triangle = 0, Circle, Cross, Square, Left, Right, Up, Down, R1, R3, L1, L3, Share, Options, PSButton, Mic, TouchPad, L2, R2, LSXNeg, LSXPos, LSYNeg, LSYPos, RSXNeg, RSXPos, RSYNeg, RSYPos, KeyCodeCount }; enum DualSenseCalibIndex { // gyro PITCH = 0, YAW, ROLL, // accel X, Y, Z, COUNT }; enum class DualSenseDataStatus { NewData, NoNewData, ReadError, }; enum class DualSenseDataMode { Simple, Enhanced }; struct DualSenseCalibData { s16 bias; s32 sens_numer; s32 sens_denom; }; struct DualSenseDevice : public PadDevice { hid_device* hidDevice{ nullptr }; std::string path{ "" }; bool btCon{ false }; bool has_calib_data{false}; std::array calib_data{}; DualSenseDataMode dataMode{ DualSenseDataMode::Simple }; std::array padData{}; bool newVibrateData{true}; u8 largeVibrate{0}; u8 smallVibrate{0}; }; const u16 DUALSENSE_VID = 0x054C; const u16 DUALSENSE_PID = 0x0CE6; std::unordered_map> controllers; CRCPP::CRC::Table crcTable{CRCPP::CRC::CRC_32()}; public: dualsense_pad_handler(); ~dualsense_pad_handler(); bool Init() override; std::vector ListDevices() override; void init_config(pad_config* cfg, const std::string& name) override; private: bool is_init = false; DualSenseDataStatus status; private: std::shared_ptr GetDualSenseDevice(const std::string& padId); DualSenseDataStatus GetRawData(const std::shared_ptr& dualsenseDevice); bool get_calibration_data(const std::shared_ptr& dualsense_device); inline s16 apply_calibration(s32 rawValue, const DualSenseCalibData& calib_data) { const s32 biased = rawValue - 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); if (output > INT16_MAX) return INT16_MAX; else if (output < INT16_MIN) return INT16_MIN; else return static_cast(output); } void CheckAddDevice(hid_device* hidDevice, hid_device_info* hidDevInfo); int send_output_report(const std::shared_ptr& device); std::shared_ptr get_device(const std::string& device) override; bool get_is_left_trigger(u64 keyCode) override; bool get_is_right_trigger(u64 keyCode) override; bool get_is_left_stick(u64 keyCode) override; bool get_is_right_stick(u64 keyCode) override; PadHandlerBase::connection update_connection(const std::shared_ptr& device) override; std::unordered_map get_button_values(const std::shared_ptr& device) override; pad_preview_values get_preview_values(const std::unordered_map& data) override; void get_extended_info(const std::shared_ptr& device, const std::shared_ptr& pad) override; void apply_pad_data(const std::shared_ptr& device, const std::shared_ptr& pad) override; };