2020-08-25 19:23:38 +00:00
|
|
|
/*
|
2024-01-26 09:23:42 +00:00
|
|
|
* Copyright (c) 2020-2024 ndeadly
|
2020-08-25 19:23:38 +00:00
|
|
|
*
|
2020-08-26 22:50:34 +00:00
|
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
|
|
* under the terms and conditions of the GNU General Public License,
|
|
|
|
* version 2, as published by the Free Software Foundation.
|
2020-08-25 19:23:38 +00:00
|
|
|
*
|
2020-08-26 22:50:34 +00:00
|
|
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
|
|
* more details.
|
2020-08-25 19:23:38 +00:00
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
2020-06-02 21:24:40 +00:00
|
|
|
#pragma once
|
2020-08-26 18:52:47 +00:00
|
|
|
#include "emulated_switch_controller.hpp"
|
2020-06-09 20:39:30 +00:00
|
|
|
|
2020-07-11 11:43:21 +00:00
|
|
|
namespace ams::controller {
|
2020-06-02 21:24:40 +00:00
|
|
|
|
2021-07-06 14:19:49 +00:00
|
|
|
enum Dualshock4ReportRate {
|
|
|
|
Dualshock4ReportRate_Max = 0,
|
|
|
|
Dualshock4ReportRate_1000Hz = 1,
|
|
|
|
Dualshock4ReportRate_500Hz = 2,
|
|
|
|
Dualshock4ReportRate_333Hz = 3,
|
|
|
|
Dualshock4ReportRate_250Hz = 4,
|
|
|
|
Dualshock4ReportRate_200Hz = 5,
|
|
|
|
Dualshock4ReportRate_166Hz = 6,
|
|
|
|
Dualshock4ReportRate_142Hz = 7,
|
|
|
|
Dualshock4ReportRate_125Hz = 8,
|
|
|
|
Dualshock4ReportRate_111Hz = 9,
|
|
|
|
Dualshock4ReportRate_100Hz = 10,
|
|
|
|
Dualshock4ReportRate_90Hz = 11,
|
|
|
|
Dualshock4ReportRate_83Hz = 12,
|
|
|
|
Dualshock4ReportRate_76Hz = 13,
|
|
|
|
Dualshock4ReportRate_71Hz = 14,
|
|
|
|
Dualshock4ReportRate_66Hz = 15,
|
|
|
|
Dualshock4ReportRate_62Hz = 16
|
|
|
|
};
|
|
|
|
|
2020-06-02 21:24:40 +00:00
|
|
|
enum Dualshock4DPadDirection {
|
|
|
|
Dualshock4DPad_N,
|
|
|
|
Dualshock4DPad_NE,
|
|
|
|
Dualshock4DPad_E,
|
|
|
|
Dualshock4DPad_SE,
|
|
|
|
Dualshock4DPad_S,
|
|
|
|
Dualshock4DPad_SW,
|
|
|
|
Dualshock4DPad_W,
|
|
|
|
Dualshock4DPad_NW,
|
|
|
|
Dualshock4DPad_Released
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Dualshock4ButtonData {
|
2023-02-22 21:25:51 +00:00
|
|
|
u8 dpad : 4;
|
|
|
|
u8 square : 1;
|
|
|
|
u8 cross : 1;
|
|
|
|
u8 circle : 1;
|
|
|
|
u8 triangle : 1;
|
2020-06-02 21:24:40 +00:00
|
|
|
|
2023-02-22 21:25:51 +00:00
|
|
|
u8 L1 : 1;
|
|
|
|
u8 R1 : 1;
|
|
|
|
u8 L2 : 1;
|
|
|
|
u8 R2 : 1;
|
|
|
|
u8 share : 1;
|
|
|
|
u8 options : 1;
|
|
|
|
u8 L3 : 1;
|
|
|
|
u8 R3 : 1;
|
2020-06-02 21:24:40 +00:00
|
|
|
|
2023-02-22 21:25:51 +00:00
|
|
|
u8 ps : 1;
|
2023-05-14 21:38:23 +00:00
|
|
|
u8 touchpad : 1;
|
2023-02-22 21:25:51 +00:00
|
|
|
u8 counter : 6;
|
|
|
|
} PACKED;
|
2020-06-02 21:24:40 +00:00
|
|
|
|
2020-09-30 23:03:34 +00:00
|
|
|
struct Dualshock4RumbleData {
|
2023-02-22 21:25:51 +00:00
|
|
|
u8 amp_motor_left;
|
|
|
|
u8 amp_motor_right;
|
|
|
|
} PACKED;
|
2020-09-30 23:03:34 +00:00
|
|
|
|
2021-09-09 21:31:22 +00:00
|
|
|
struct Dualshock4ImuCalibrationData {
|
|
|
|
struct {
|
2023-02-22 21:25:51 +00:00
|
|
|
s16 pitch_bias;
|
|
|
|
s16 yaw_bias;
|
|
|
|
s16 roll_bias;
|
|
|
|
s16 pitch_max;
|
|
|
|
s16 yaw_max;
|
|
|
|
s16 roll_max;
|
|
|
|
s16 pitch_min;
|
|
|
|
s16 yaw_min;
|
|
|
|
s16 roll_min;
|
|
|
|
s16 speed_max;
|
|
|
|
s16 speed_min;
|
2021-09-09 21:31:22 +00:00
|
|
|
} gyro;
|
|
|
|
|
|
|
|
struct {
|
2023-02-22 21:25:51 +00:00
|
|
|
s16 x_max;
|
|
|
|
s16 x_min;
|
|
|
|
s16 y_max;
|
|
|
|
s16 y_min;
|
|
|
|
s16 z_max;
|
|
|
|
s16 z_min;
|
2021-09-09 21:31:22 +00:00
|
|
|
} acc;
|
2023-02-22 21:25:51 +00:00
|
|
|
} PACKED;
|
2021-09-09 21:31:22 +00:00
|
|
|
|
2023-05-14 21:38:23 +00:00
|
|
|
struct Dualshock4TouchpadPoint {
|
|
|
|
u8 contact;
|
|
|
|
u8 x_lo;
|
|
|
|
u8 x_hi : 4;
|
|
|
|
u8 y_lo : 4;
|
|
|
|
u8 y_hi;
|
|
|
|
} PACKED;
|
|
|
|
|
|
|
|
struct Dualshock4TouchReport {
|
|
|
|
u8 timestamp;
|
|
|
|
Dualshock4TouchpadPoint points[2];
|
|
|
|
} PACKED;
|
|
|
|
|
2022-03-30 08:27:24 +00:00
|
|
|
struct Dualshock4VersionInfo {
|
|
|
|
char date[48];
|
2023-02-22 21:25:51 +00:00
|
|
|
} PACKED;
|
2022-03-30 08:27:24 +00:00
|
|
|
|
2021-09-09 21:31:22 +00:00
|
|
|
struct Dualshock4FeatureReport0x05 {
|
2022-03-30 08:27:24 +00:00
|
|
|
Dualshock4ImuCalibrationData calibration;
|
2023-02-22 21:25:51 +00:00
|
|
|
u32 crc;
|
|
|
|
} PACKED;
|
2022-03-30 08:27:24 +00:00
|
|
|
|
|
|
|
struct Dualshock4FeatureReport0x06 {
|
|
|
|
Dualshock4VersionInfo version_info;
|
2023-02-22 21:25:51 +00:00
|
|
|
u32 crc;
|
|
|
|
} PACKED;
|
2022-03-30 08:27:24 +00:00
|
|
|
|
|
|
|
struct Dualshock4FeatureReport0xa3 {
|
|
|
|
Dualshock4VersionInfo version_info;
|
2023-02-22 21:25:51 +00:00
|
|
|
} PACKED;
|
2021-09-09 21:31:22 +00:00
|
|
|
|
2021-07-28 19:30:47 +00:00
|
|
|
struct Dualshock4OutputReport0x11 {
|
2020-06-02 21:24:40 +00:00
|
|
|
struct {
|
2023-02-22 21:25:51 +00:00
|
|
|
u8 data[73];
|
2020-06-02 21:24:40 +00:00
|
|
|
};
|
2023-02-22 21:25:51 +00:00
|
|
|
u32 crc;
|
|
|
|
} PACKED;
|
2020-06-02 21:24:40 +00:00
|
|
|
|
|
|
|
struct Dualshock4InputReport0x01 {
|
2024-01-26 00:16:48 +00:00
|
|
|
AnalogStick<u8> left_stick;
|
|
|
|
AnalogStick<u8> right_stick;
|
2022-03-30 08:27:24 +00:00
|
|
|
Dualshock4ButtonData buttons;
|
2023-02-22 21:25:51 +00:00
|
|
|
u8 left_trigger;
|
|
|
|
u8 right_trigger;
|
|
|
|
} PACKED;
|
2020-06-02 21:24:40 +00:00
|
|
|
|
|
|
|
struct Dualshock4InputReport0x11 {
|
2023-02-22 21:25:51 +00:00
|
|
|
u8 _unk0[2];
|
2024-01-26 00:16:48 +00:00
|
|
|
AnalogStick<u8> left_stick;
|
|
|
|
AnalogStick<u8> right_stick;
|
2022-03-30 08:27:24 +00:00
|
|
|
Dualshock4ButtonData buttons;
|
2023-02-22 21:25:51 +00:00
|
|
|
u8 left_trigger;
|
|
|
|
u8 right_trigger;
|
2023-05-14 21:38:23 +00:00
|
|
|
|
2023-02-22 21:25:51 +00:00
|
|
|
u16 timestamp;
|
2023-05-14 21:38:23 +00:00
|
|
|
u8 temperature;
|
2023-02-22 21:25:51 +00:00
|
|
|
s16 vel_x;
|
|
|
|
s16 vel_y;
|
|
|
|
s16 vel_z;
|
|
|
|
s16 acc_x;
|
|
|
|
s16 acc_y;
|
|
|
|
s16 acc_z;
|
|
|
|
u8 _unk1[5];
|
|
|
|
|
|
|
|
u8 battery_level : 4;
|
|
|
|
u8 usb : 1;
|
|
|
|
u8 mic : 1;
|
|
|
|
u8 phone : 1;
|
|
|
|
u8 : 0;
|
2023-05-14 21:38:23 +00:00
|
|
|
u8 _unk2[2];
|
|
|
|
|
|
|
|
u8 num_reports;
|
|
|
|
Dualshock4TouchReport touch_reports[4];
|
|
|
|
u8 _unk3[2];
|
2023-02-22 21:25:51 +00:00
|
|
|
|
2023-05-14 21:38:23 +00:00
|
|
|
u32 crc;
|
2023-02-22 21:25:51 +00:00
|
|
|
} PACKED;
|
2020-06-02 21:24:40 +00:00
|
|
|
|
2020-07-11 11:43:21 +00:00
|
|
|
struct Dualshock4ReportData {
|
2023-02-22 21:25:51 +00:00
|
|
|
u8 id;
|
2020-07-11 11:43:21 +00:00
|
|
|
union {
|
2021-09-09 21:31:22 +00:00
|
|
|
Dualshock4FeatureReport0x05 feature0x05;
|
2022-03-30 08:27:24 +00:00
|
|
|
Dualshock4FeatureReport0x06 feature0x06;
|
|
|
|
Dualshock4FeatureReport0xa3 feature0xa3;
|
2023-02-22 21:25:51 +00:00
|
|
|
Dualshock4OutputReport0x11 output0x11;
|
|
|
|
Dualshock4InputReport0x01 input0x01;
|
|
|
|
Dualshock4InputReport0x11 input0x11;
|
2020-07-11 11:43:21 +00:00
|
|
|
};
|
2023-02-22 21:25:51 +00:00
|
|
|
} PACKED;
|
2020-06-02 21:24:40 +00:00
|
|
|
|
2023-02-22 21:25:51 +00:00
|
|
|
class Dualshock4Controller final : public EmulatedSwitchController {
|
2020-06-02 21:24:40 +00:00
|
|
|
|
|
|
|
public:
|
2021-07-28 19:30:47 +00:00
|
|
|
static constexpr const HardwareID hardware_ids[] = {
|
2020-09-12 17:29:41 +00:00
|
|
|
{0x054c, 0x05c4}, // Official Dualshock4 v1
|
|
|
|
{0x054c, 0x09cc}, // Official Dualshock4 v2
|
2021-01-15 21:06:04 +00:00
|
|
|
{0x0f0d, 0x00f6}, // Hori ONYX
|
2022-12-30 11:59:15 +00:00
|
|
|
{0x1532, 0x1009}, // Razer Raiju Ultimate
|
2023-10-24 14:05:02 +00:00
|
|
|
{0x1532, 0x100a}, // Razer Raiju Tournament
|
|
|
|
{0x2e95, 0x7725} // SCUF Vantage 2
|
2020-06-02 21:24:40 +00:00
|
|
|
};
|
|
|
|
|
2021-07-28 19:30:47 +00:00
|
|
|
Dualshock4Controller(const bluetooth::Address *address, HardwareID id)
|
|
|
|
: EmulatedSwitchController(address, id)
|
|
|
|
, m_report_rate(Dualshock4ReportRate_125Hz)
|
2023-03-07 10:53:10 +00:00
|
|
|
, m_lightbar_colour({0, 0, 0})
|
|
|
|
, m_lightbar_brightness(0)
|
2021-07-28 19:30:47 +00:00
|
|
|
, m_rumble_state({0, 0}) { }
|
2021-07-06 14:19:49 +00:00
|
|
|
|
2022-04-08 15:12:59 +00:00
|
|
|
Result Initialize();
|
2021-03-15 23:09:21 +00:00
|
|
|
Result SetVibration(const SwitchRumbleData *rumble_data);
|
2022-04-08 15:12:59 +00:00
|
|
|
Result CancelVibration();
|
2023-02-22 21:25:51 +00:00
|
|
|
Result SetPlayerLed(u8 led_mask);
|
2020-10-04 15:16:49 +00:00
|
|
|
Result SetLightbarColour(RGBColour colour);
|
2021-07-06 14:19:49 +00:00
|
|
|
|
2022-03-30 08:27:24 +00:00
|
|
|
void ProcessInputData(const bluetooth::HidReport *report) override;
|
2020-06-02 21:24:40 +00:00
|
|
|
|
|
|
|
private:
|
2022-03-30 08:27:24 +00:00
|
|
|
void MapInputReport0x01(const Dualshock4ReportData *src);
|
|
|
|
void MapInputReport0x11(const Dualshock4ReportData *src);
|
2020-07-27 17:42:40 +00:00
|
|
|
|
2020-10-03 15:22:21 +00:00
|
|
|
void MapButtons(const Dualshock4ButtonData *buttons);
|
2020-10-06 18:40:19 +00:00
|
|
|
|
2022-03-30 08:27:24 +00:00
|
|
|
Result GetVersionInfo(Dualshock4VersionInfo *version_info);
|
|
|
|
Result GetCalibrationData(Dualshock4ImuCalibrationData *calibration);
|
2022-04-08 15:12:59 +00:00
|
|
|
Result PushRumbleLedState();
|
2020-07-27 17:42:40 +00:00
|
|
|
|
2021-07-06 14:19:49 +00:00
|
|
|
Dualshock4ReportRate m_report_rate;
|
2023-03-07 10:53:10 +00:00
|
|
|
RGBColour m_lightbar_colour;
|
|
|
|
u8 m_lightbar_brightness;
|
2021-07-28 19:30:47 +00:00
|
|
|
Dualshock4RumbleData m_rumble_state;
|
2022-04-04 06:13:28 +00:00
|
|
|
|
|
|
|
Dualshock4ImuCalibrationData m_motion_calibration;
|
2020-06-02 21:24:40 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|