HID-RP
The hid-rp component provides a wrapper around https://github.com/intergatedcircuits/hid-rp and also provides an example implementation of a configurable HID Gamepad using hid-rp.
It also implements Playstation Dualsense, Nintendo Switch Pro, and Xbox gamepad reports.
API Reference
Header File
Header File
Unions
- espp::gamepad::Accelerometer.__unnamed9__
- espp::gamepad::Gyroscope.__unnamed13__
Public Members
- struct espp::gamepad::Gyroscope
- struct espp::gamepad::Gyroscope
-
std::int16_t raw[3]
Header File
Header File
Classes
-
template<size_t BUTTON_COUNT = 15, typename JOYSTICK_TYPE = std::uint16_t, typename TRIGGER_TYPE = std::uint16_t, JOYSTICK_TYPE JOYSTICK_MIN = 0, JOYSTICK_TYPE JOYSTICK_MAX = 65535, TRIGGER_TYPE TRIGGER_MIN = 0, TRIGGER_TYPE TRIGGER_MAX = 1023, uint8_t REPORT_ID = 1>
class GamepadInputReport : public hid::report::base<hid::report::type::INPUT, 1> HID Gamepad Input Report This class implements a HID Gamepad with a configurable number of buttons, a hat switch, 4 joystick axes and two trigger axes. It supports setting the buttons, hat switch, joysticks, and triggers, as well as serializing the input report and getting the report descriptor.
HID-RP Gamepad Example
static constexpr uint8_t input_report_id = 1; static constexpr uint8_t battery_report_id = 4; static constexpr size_t num_buttons = 15; static constexpr int joystick_min = 0; static constexpr int joystick_max = 65535; static constexpr int trigger_min = 0; static constexpr int trigger_max = 1023; using GamepadInput = espp::GamepadInputReport<num_buttons, std::uint16_t, std::uint16_t, joystick_min, joystick_max, trigger_min, trigger_max, input_report_id>; GamepadInput gamepad_input_report; using XboxInput = espp::XboxGamepadInputReport<input_report_id>; XboxInput xbox_input_report; using BatteryReport = espp::XboxBatteryInputReport<battery_report_id>; BatteryReport battery_input_report; static constexpr uint8_t led_output_report_id = 2; static constexpr size_t num_leds = 4; using GamepadLeds = espp::GamepadLedOutputReport<num_leds, led_output_report_id>; GamepadLeds gamepad_leds_report; static constexpr uint8_t rumble_output_report_id = 3; using RumbleReport = espp::XboxRumbleOutputReport<rumble_output_report_id>; RumbleReport rumble_output_report; using namespace hid::page; using namespace hid::rdf; auto raw_descriptor = descriptor(usage_page<generic_desktop>(), usage(generic_desktop::GAMEPAD), collection::application(gamepad_input_report.get_descriptor(), rumble_output_report.get_descriptor(), battery_input_report.get_descriptor(), gamepad_leds_report.get_descriptor())); // Generate the report descriptor for the gamepad auto descriptor = std::vector<uint8_t>(raw_descriptor.begin(), raw_descriptor.end()); logger.info("Report Descriptor:"); logger.info(" Size: {}", descriptor.size()); logger.info(" Data: {::#04X}", descriptor); using SwitchProInput = espp::SwitchProGamepadInputReport<>; SwitchProInput switch_pro_input_report; logger.info("{}", switch_pro_input_report); logger.info("Switch Pro Input Report Size: {}", switch_pro_input_report.get_report().size()); logger.info("Switch Pro Input Report Data: {::#04X}", switch_pro_input_report.get_report()); auto sp_raw_descriptor = espp::switch_pro_descriptor(); auto sp_descriptor = std::vector<uint8_t>(sp_raw_descriptor.begin(), sp_raw_descriptor.end()); logger.info("Switch Report Descriptor:"); logger.info(" Size: {}", sp_descriptor.size()); std::string str = ""; for (auto &byte : sp_descriptor) { str += fmt::format("0x{:02X}, ", byte); } logger.info(" Data: [{}]", str); using PlaystationDualsenseBleSimpleInput = espp::PlaystationDualsenseBLESimpleInputReport<>; PlaystationDualsenseBleSimpleInput dualsense_simple_input_report; using PlaystationDualsenseBleComplexInput = espp::PlaystationDualsenseBLEComplexInputReport<>; PlaystationDualsenseBleComplexInput dualsense_complex_input_report; logger.info("Playstation Dualsense BLE Report Descriptor:"); auto ps_raw_descriptor = espp::playstation_dualsense_ble_descriptor(); auto ps_descriptor = std::vector<uint8_t>(ps_raw_descriptor.begin(), ps_raw_descriptor.end()); logger.info(" Size: {}", ps_descriptor.size()); str = ""; for (auto &byte : ps_descriptor) { str += fmt::format("0x{:02X}, ", byte); } logger.info(" Data: [{}]", str); GamepadInput::Hat hat = GamepadInput::Hat::UP_RIGHT; int button_index = 5; float angle = 2.0f * M_PI * button_index / num_buttons; // reset all reports gamepad_input_report.reset(); xbox_input_report.reset(); switch_pro_input_report.reset(); dualsense_simple_input_report.reset(); dualsense_complex_input_report.reset(); // print out the reports in their default states logger.info("{}", gamepad_input_report); logger.info("{}", xbox_input_report); logger.info("{}", switch_pro_input_report); logger.info("{}", dualsense_simple_input_report); logger.info("{}", dualsense_complex_input_report); // update the gamepad input report logger.info("{}", gamepad_input_report); gamepad_input_report.set_hat(hat); gamepad_input_report.set_button(button_index, true); // joystick inputs are in the range [-1, 1] float gamepad_input_report.set_right_joystick(cos(angle), sin(angle)); gamepad_input_report.set_left_joystick(sin(angle), cos(angle)); // trigger inputs are in the range [0, 1] float gamepad_input_report.set_accelerator(std::abs(sin(angle))); gamepad_input_report.set_brake(std::abs(cos(angle))); switch_pro_input_report.set_button(button_index, true); switch_pro_input_report.set_dpad(false, true, false, true); // down-right switch_pro_input_report.set_left_joystick(sin(angle), cos(angle)); switch_pro_input_report.set_right_joystick(cos(angle), sin(angle)); switch_pro_input_report.set_left_trigger((float)std::abs(cos(angle))); switch_pro_input_report.set_right_trigger((float)std::abs(sin(angle))); dualsense_simple_input_report.set_button(button_index, true); dualsense_simple_input_report.set_hat(hat); dualsense_simple_input_report.set_left_joystick(sin(angle), cos(angle)); dualsense_simple_input_report.set_right_joystick(cos(angle), sin(angle)); dualsense_simple_input_report.set_left_trigger(std::abs(cos(angle))); dualsense_simple_input_report.set_right_trigger(std::abs(sin(angle))); dualsense_complex_input_report.set_button(button_index, true); dualsense_complex_input_report.set_hat(hat); dualsense_complex_input_report.set_left_joystick(sin(angle), cos(angle)); dualsense_complex_input_report.set_right_joystick(cos(angle), sin(angle)); dualsense_complex_input_report.set_left_trigger(std::abs(cos(angle))); dualsense_complex_input_report.set_right_trigger(std::abs(sin(angle))); button_index = (button_index % num_buttons) + 1; // send an input report auto report = gamepad_input_report.get_report(); logger.info("{}", gamepad_input_report); logger.info("Gamepad Input report:"); logger.info(" Size: {}", report.size()); logger.info(" Data: {::#02X}", report); report = switch_pro_input_report.get_report(); logger.info("{}", switch_pro_input_report); logger.info("Switch Pro Input report:"); logger.info(" Size: {}", report.size()); logger.info(" Data: {::#02X}", report); report = dualsense_simple_input_report.get_report(); logger.info("{}", dualsense_simple_input_report); logger.info("Playstation Dualsense BLE Simple Input report:"); logger.info(" Size: {}", report.size()); logger.info(" Data: {::#02X}", report); report = dualsense_complex_input_report.get_report(); logger.info("{}", dualsense_complex_input_report); logger.info("Playstation Dualsense BLE Complex Input report:"); logger.info(" Size: {}", report.size()); logger.info(" Data: {::#02X}", report); // update the battery input report battery_input_report.reset(); battery_input_report.set_rechargeable(true); battery_input_report.set_charging(false); battery_input_report.set_rechargeable(true); // note: it can only show 5, 40, 70, 100 so this will be rounded to 40 battery_input_report.set_battery_level(50); // send a battery report report = battery_input_report.get_report(); logger.info("Battery report:"); logger.info(" Size: {}", report.size()); logger.info(" Data: {::#02X}", report);
Subclassed by espp::XboxGamepadInputReport< REPORT_ID >
Public Functions
-
constexpr GamepadInputReport() = default
Construct a new Gamepad Input Report object.
-
inline constexpr void reset()
Reset the gamepad inputs.
-
inline constexpr void get_left_joystick(float &lx, float &ly) const
Get the left joystick X and Y axis values
- Parameters:
lx – [out] left joystick x axis value, in the range [-1, 1]
ly – [out] left joystick y axis value, in the range [-1, 1]
-
inline constexpr void get_left_joystick(JOYSTICK_TYPE &lx, JOYSTICK_TYPE &ly) const
Get the left joystick X and Y axis values
- Parameters:
lx – [out] left joystick x axis value
ly – [out] left joystick y axis value
-
inline constexpr void get_right_joystick(float &rx, float &ry) const
Get the right joystick X and Y axis values
- Parameters:
rx – [out] right joystick x axis value, in the range [-1, 1]
ry – [out] right joystick y axis value, in the range [-1, 1]
-
inline constexpr void get_right_joystick(JOYSTICK_TYPE &rx, JOYSTICK_TYPE &ry) const
Get the right joystick X and Y axis values
- Parameters:
rx – [out] right joystick x axis value
ry – [out] right joystick y axis value
-
inline constexpr void set_left_joystick(float lx, float ly)
Set the left joystick X and Y axis values
- Parameters:
lx – left joystick x axis value, in the range [-1, 1]
ly – left joystick y axis value, in the range [-1, 1]
-
inline constexpr void set_right_joystick(float rx, float ry)
Set the right joystick X and Y axis values
- Parameters:
rx – right joystick x axis value, in the range [-1, 1]
ry – right joystick y axis value, in the range [-1, 1]
-
inline constexpr void get_brake(float &value) const
Get the brake trigger value
- Parameters:
value – brake trigger value, in the range [0, 1]
-
inline constexpr void get_brake(TRIGGER_TYPE &value) const
Get the brake trigger value
- Parameters:
value – brake trigger value
-
inline constexpr void get_left_trigger(float &value) const
Get the left trigger value
- Parameters:
value – left trigger value, in the range [0, 1]
-
inline constexpr void set_brake(float value)
Set the brake trigger value
- Parameters:
value – brake trigger value, in the range [0, 1]
-
inline constexpr void set_left_trigger(float value)
Set the left trigger value
- Parameters:
value – left trigger value, in the range [0, 1]
-
inline constexpr void get_accelerator(float &value) const
Get the accelerator trigger value
- Parameters:
value – accelerator trigger value, in the range [0, 1]
-
inline constexpr void get_accelerator(TRIGGER_TYPE &value) const
Get the accelerator trigger value
- Parameters:
value – accelerator trigger value
-
inline constexpr void get_right_trigger(float &value) const
Get the right trigger value
- Parameters:
value – right trigger value, in the range [0, 1]
-
inline constexpr void set_accelerator(float value)
Set the accelerator trigger value
- Parameters:
value – accelerator trigger value, in the range [0, 1]
-
inline constexpr void set_right_trigger(float value)
Set the right trigger value
- Parameters:
value – right trigger value, in the range [0, 1]
-
inline constexpr void set_hat(Hat hat)
Set the hat switch (d-pad) value
- Parameters:
hat – Hat enum / direction to set
-
inline constexpr void set_hat(bool up, bool down, bool left, bool right)
Set the hat switch (d-pad) value
- Parameters:
up – up direction
down – down direction
left – left direction
right – right direction
-
inline constexpr Hat get_hat() const
Get the hat switch (d-pad) value
- Returns:
Hat enum / direction
-
inline constexpr void get_hat(bool &up, bool &down, bool &left, bool &right) const
Get the hat switch (d-pad) value
- Parameters:
up – up direction
down – down direction
left – left direction
right – right direction
-
inline constexpr void set_button(int button_index, bool value)
Set the button value
- Parameters:
button_index – The button for which you want to set the value. Should be between 1 and BUTTON_COUNT, inclusive.
value – The true/false value you want to se the button to.
-
inline constexpr void set_joystick_axis(size_t index, JOYSTICK_TYPE value)
Set the joystick axis value
Note
The value should be in the range [joystick_min, joystick_max].
- Parameters:
index – The index of the joystick axis to set. Should be between 0 and 3, inclusive.
value – The value to set the joystick axis to.
-
inline constexpr void set_joystick_axis(size_t index, float value)
Set the joystick axis value
Note
The value should be in the range [-1, 1].
- Parameters:
index – The index of the joystick axis to set. Should be between 0 and 3, inclusive.
value – The value to set the joystick axis to.
-
inline constexpr void set_trigger_axis(size_t index, TRIGGER_TYPE value)
Set the trigger axis value
Note
The value should be in the range [trigger_min, trigger_max].
- Parameters:
index – The index of the trigger axis to set. Should be between 0 and 1, inclusive.
value – The value to set the trigger axis to.
-
inline constexpr void set_trigger_axis(size_t index, float value)
Set the trigger axis value
Note
The value should be in the range [0, 1].
- Parameters:
index – The index of the trigger axis to set. Should be between 0 and 1, inclusive.
value – The value to set the trigger axis to.
-
inline constexpr bool get_button(int button_index) const
Get the button value
- Parameters:
button_index – The button for which you want to get the value.
- Returns:
The true/false value of the button.
-
inline constexpr void set_hat_switch(Hat hat)
Set the hat switch value
- Parameters:
hat – The hat switch value to set.
-
inline constexpr void set_hat_switch(std::uint8_t value)
Set the hat switch value
Note
The value should match the values within the Hat enum.
- Parameters:
value – The hat switch value to set.
-
inline constexpr bool get_consumer_record() const
Get the consumer record button value
- Returns:
The consumer record button value.
-
inline constexpr void set_consumer_record(bool value)
Set the consumer record button value
- Parameters:
value – The true/false value you want to se the consumer record button to.
-
inline constexpr auto get_report() const
Get the input report as a vector of bytes
Note
The report id is not included in the returned vector.
- Returns:
The input report as a vector of bytes.
-
inline constexpr void set_data(const std::vector<uint8_t> &data)
Set the output report data from a vector of bytes
- Parameters:
data – The data to set the output report to.
Public Static Functions
-
static inline constexpr auto get_descriptor()
Get the report descriptor as a hid::rdf::descriptor
Note
This is an incomplete descriptor, you will need to add it to a collection::application descriptor to create a complete report descriptor.
using namespace hid::page; using namespace hid::rdf; auto gamepad_descriptor = gamepad_input_report.get_descriptor(); auto rdf_descriptor = descriptor( usage_page<generic_desktop>(), usage(generic_desktop::GAMEPAD), collection::application( gamepad_descriptor ) ); auto descriptor = std::vector<uint8_t>(rdf_descriptor.begin(), rdf_descriptor.end());
- Returns:
The report descriptor as a hid::rdf::descriptor.
-
constexpr GamepadInputReport() = default
-
template<size_t LED_COUNT = 4, uint8_t REPORT_ID = 2>
class GamepadLedOutputReport : public hid::report::base<hid::report::type::OUTPUT, 2> HID Gamepad LED Output Report This class implements a HID Gamepad with a configurable number of LEDs. It supports setting the LEDs, as well as serializing the output report and getting the report descriptor.
Public Functions
-
inline constexpr void set_led(int led_index, bool value)
Set the LED value
- Parameters:
led_index – The LED for which you want to set the value. Should be between 1 and LED_COUNT, inclusive.
value – The true/false value you want to se the LED to.
-
inline constexpr auto get_min_led()
Get the minimum led usage
- Returns:
The minimum led usage
-
inline constexpr auto get_max_led()
Get the maximum led usage
- Returns:
The maximum led usage
-
inline constexpr bool get_led(hid::page::leds led)
Get the LED value
- Parameters:
led – The LED for which you want to get the value.
- Returns:
The true/false value of the LED.
-
inline constexpr bool get_led(int led_index)
Get the LED value
- Parameters:
led_index – The LED for which you want to get the value. Should be between 1 and LED_COUNT, inclusive.
- Returns:
The true/false value of the LED.
-
inline constexpr auto get_report()
Get the output report as a vector of bytes
Note
The report id is not included in the returned vector.
- Returns:
The output report as a vector of bytes.
-
inline constexpr void set_data(const std::vector<uint8_t> &data)
Set the output report data from a vector of bytes
- Parameters:
data – The data to set the output report to.
Public Static Functions
-
static inline constexpr auto get_descriptor()
Get the report descriptor as a hid::rdf::descriptor
Note
This is an incomplete descriptor, you will need to add it to a collection::application descriptor to create a complete report descriptor.
using namespace hid::page; using namespace hid::rdf; auto led_descriptor = gamepad_led_report.get_descriptor(); auto rdf_descriptor = descriptor( usage_page<generic_desktop>(), usage(generic_desktop::GAMEPAD), collection::application( led_descriptor ) ); auto descriptor = std::vector<uint8_t>(rdf_descriptor.begin(), rdf_descriptor.end());
- Returns:
The report descriptor as a hid::rdf::descriptor.
-
inline constexpr void set_led(int led_index, bool value)
Header File
Unions
-
union PlaystationDualsenseGamepadButtons
- #include <hid-rp-playstation.hpp>
Playstation DualSense Gamepad Buttons Used in input reports (0x01, 0x31) when used over BLE.
Public Members
-
std::array<std::uint8_t, 3> raw
Buttons as bytes.
- struct espp::PlaystationDualsenseGamepadButtons
-
std::array<std::uint8_t, 3> raw
-
union PlaystationDualsenseVendorDefinedData
- #include <hid-rp-playstation.hpp>
Playstation DualSense Vendor Defined Data. Used for IMU, touchpad, battery, etc. in input report 0x31 (49) over Bluetooth.
Public Types
-
using Accelerometer = espp::gamepad::Accelerometer
Accelerometer type.
-
using Gyroscope = espp::gamepad::Gyroscope
Gyroscope type.
Public Members
-
std::array<std::uint8_t, 65> raw
Vendor defined data.
- struct espp::PlaystationDualsenseVendorDefinedData
-
using Accelerometer = espp::gamepad::Accelerometer
- espp::PlaystationTouchpadData.__unnamed21__
Public Members
-
std::uint8_t raw[9]
Raw data array.
- struct espp::PlaystationTouchpadData
-
std::uint8_t raw[9]
- espp::PlaystationDualsenseVendorDefinedData.__unnamed27__.__unnamed29__
Public Members
-
std::array<std::int16_t, 6> imu
IMU data as array.
- struct espp::PlaystationDualsenseVendorDefinedData
-
std::array<std::int16_t, 6> imu
- espp::PlaystationDualsenseVendorDefinedData.__unnamed27__.__unnamed31__
Public Members
-
std::array<std::uint8_t, 2> battery_raw
- struct espp::PlaystationDualsenseVendorDefinedData
-
std::array<std::uint8_t, 2> battery_raw
Classes
-
template<uint8_t REPORT_ID = 1>
class PlaystationDualsenseBLESimpleInputReport : public hid::report::base<hid::report::type::INPUT, 1> HID Playstation DualSense Bluetooth Gamepad Input Report
This class implements a HID Playstation DualSense Bluetooth Gamepad Report. It supports 14 buttons, a d-pad, 4 joystick axes, and 2 trigger axes.
This is the simple report which is used by default when connecting the controller over bluetooth and matches report ID 0x01.
HID-RP Playstation Gamepad Example
static constexpr uint8_t input_report_id = 1; static constexpr uint8_t battery_report_id = 4; static constexpr size_t num_buttons = 15; static constexpr int joystick_min = 0; static constexpr int joystick_max = 65535; static constexpr int trigger_min = 0; static constexpr int trigger_max = 1023; using GamepadInput = espp::GamepadInputReport<num_buttons, std::uint16_t, std::uint16_t, joystick_min, joystick_max, trigger_min, trigger_max, input_report_id>; GamepadInput gamepad_input_report; using XboxInput = espp::XboxGamepadInputReport<input_report_id>; XboxInput xbox_input_report; using BatteryReport = espp::XboxBatteryInputReport<battery_report_id>; BatteryReport battery_input_report; static constexpr uint8_t led_output_report_id = 2; static constexpr size_t num_leds = 4; using GamepadLeds = espp::GamepadLedOutputReport<num_leds, led_output_report_id>; GamepadLeds gamepad_leds_report; static constexpr uint8_t rumble_output_report_id = 3; using RumbleReport = espp::XboxRumbleOutputReport<rumble_output_report_id>; RumbleReport rumble_output_report; using namespace hid::page; using namespace hid::rdf; auto raw_descriptor = descriptor(usage_page<generic_desktop>(), usage(generic_desktop::GAMEPAD), collection::application(gamepad_input_report.get_descriptor(), rumble_output_report.get_descriptor(), battery_input_report.get_descriptor(), gamepad_leds_report.get_descriptor())); // Generate the report descriptor for the gamepad auto descriptor = std::vector<uint8_t>(raw_descriptor.begin(), raw_descriptor.end()); logger.info("Report Descriptor:"); logger.info(" Size: {}", descriptor.size()); logger.info(" Data: {::#04X}", descriptor); using SwitchProInput = espp::SwitchProGamepadInputReport<>; SwitchProInput switch_pro_input_report; logger.info("{}", switch_pro_input_report); logger.info("Switch Pro Input Report Size: {}", switch_pro_input_report.get_report().size()); logger.info("Switch Pro Input Report Data: {::#04X}", switch_pro_input_report.get_report()); auto sp_raw_descriptor = espp::switch_pro_descriptor(); auto sp_descriptor = std::vector<uint8_t>(sp_raw_descriptor.begin(), sp_raw_descriptor.end()); logger.info("Switch Report Descriptor:"); logger.info(" Size: {}", sp_descriptor.size()); std::string str = ""; for (auto &byte : sp_descriptor) { str += fmt::format("0x{:02X}, ", byte); } logger.info(" Data: [{}]", str); using PlaystationDualsenseBleSimpleInput = espp::PlaystationDualsenseBLESimpleInputReport<>; PlaystationDualsenseBleSimpleInput dualsense_simple_input_report; using PlaystationDualsenseBleComplexInput = espp::PlaystationDualsenseBLEComplexInputReport<>; PlaystationDualsenseBleComplexInput dualsense_complex_input_report; logger.info("Playstation Dualsense BLE Report Descriptor:"); auto ps_raw_descriptor = espp::playstation_dualsense_ble_descriptor(); auto ps_descriptor = std::vector<uint8_t>(ps_raw_descriptor.begin(), ps_raw_descriptor.end()); logger.info(" Size: {}", ps_descriptor.size()); str = ""; for (auto &byte : ps_descriptor) { str += fmt::format("0x{:02X}, ", byte); } logger.info(" Data: [{}]", str); GamepadInput::Hat hat = GamepadInput::Hat::UP_RIGHT; int button_index = 5; float angle = 2.0f * M_PI * button_index / num_buttons; // reset all reports gamepad_input_report.reset(); xbox_input_report.reset(); switch_pro_input_report.reset(); dualsense_simple_input_report.reset(); dualsense_complex_input_report.reset(); // print out the reports in their default states logger.info("{}", gamepad_input_report); logger.info("{}", xbox_input_report); logger.info("{}", switch_pro_input_report); logger.info("{}", dualsense_simple_input_report); logger.info("{}", dualsense_complex_input_report); // update the gamepad input report logger.info("{}", gamepad_input_report); gamepad_input_report.set_hat(hat); gamepad_input_report.set_button(button_index, true); // joystick inputs are in the range [-1, 1] float gamepad_input_report.set_right_joystick(cos(angle), sin(angle)); gamepad_input_report.set_left_joystick(sin(angle), cos(angle)); // trigger inputs are in the range [0, 1] float gamepad_input_report.set_accelerator(std::abs(sin(angle))); gamepad_input_report.set_brake(std::abs(cos(angle))); switch_pro_input_report.set_button(button_index, true); switch_pro_input_report.set_dpad(false, true, false, true); // down-right switch_pro_input_report.set_left_joystick(sin(angle), cos(angle)); switch_pro_input_report.set_right_joystick(cos(angle), sin(angle)); switch_pro_input_report.set_left_trigger((float)std::abs(cos(angle))); switch_pro_input_report.set_right_trigger((float)std::abs(sin(angle))); dualsense_simple_input_report.set_button(button_index, true); dualsense_simple_input_report.set_hat(hat); dualsense_simple_input_report.set_left_joystick(sin(angle), cos(angle)); dualsense_simple_input_report.set_right_joystick(cos(angle), sin(angle)); dualsense_simple_input_report.set_left_trigger(std::abs(cos(angle))); dualsense_simple_input_report.set_right_trigger(std::abs(sin(angle))); dualsense_complex_input_report.set_button(button_index, true); dualsense_complex_input_report.set_hat(hat); dualsense_complex_input_report.set_left_joystick(sin(angle), cos(angle)); dualsense_complex_input_report.set_right_joystick(cos(angle), sin(angle)); dualsense_complex_input_report.set_left_trigger(std::abs(cos(angle))); dualsense_complex_input_report.set_right_trigger(std::abs(sin(angle))); button_index = (button_index % num_buttons) + 1; // send an input report auto report = gamepad_input_report.get_report(); logger.info("{}", gamepad_input_report); logger.info("Gamepad Input report:"); logger.info(" Size: {}", report.size()); logger.info(" Data: {::#02X}", report); report = switch_pro_input_report.get_report(); logger.info("{}", switch_pro_input_report); logger.info("Switch Pro Input report:"); logger.info(" Size: {}", report.size()); logger.info(" Data: {::#02X}", report); report = dualsense_simple_input_report.get_report(); logger.info("{}", dualsense_simple_input_report); logger.info("Playstation Dualsense BLE Simple Input report:"); logger.info(" Size: {}", report.size()); logger.info(" Data: {::#02X}", report); report = dualsense_complex_input_report.get_report(); logger.info("{}", dualsense_complex_input_report); logger.info("Playstation Dualsense BLE Complex Input report:"); logger.info(" Size: {}", report.size()); logger.info(" Data: {::#02X}", report); // update the battery input report battery_input_report.reset(); battery_input_report.set_rechargeable(true); battery_input_report.set_charging(false); battery_input_report.set_rechargeable(true); // note: it can only show 5, 40, 70, 100 so this will be rounded to 40 battery_input_report.set_battery_level(50); // send a battery report report = battery_input_report.get_report(); logger.info("Battery report:"); logger.info(" Size: {}", report.size()); logger.info(" Data: {::#02X}", report);
Note
I have tested the playstation dualsense report descriptor and input reports over BLE with iOS, MacOS, Windows, and Android and found that:
iOS, MacOS, and Windows only parse the complex report (0x31) and ignore the simple report (0x01). This means that the simple report is effectively unused fields in the report descriptor.
Android seems to require Audio support, which it cannot find over BLE, so it does not work at all.
Public Types
-
using Hat = PlaystationHat
The type used for the hat switch.
-
using JOYSTICK_TYPE = std::uint8_t
The type used for the joystick axes.
-
using TRIGGER_TYPE = std::uint8_t
The type used for the trigger axes.
Public Functions
-
constexpr PlaystationDualsenseBLESimpleInputReport() = default
Construct a new PlaystationPDualSenseBLE Gamepad Input Report object.
-
inline constexpr void reset()
Reset the gamepad inputs.
-
template<PlaystationDualsenseButtonStruct T>
inline constexpr void set_buttons(const T &buttons) Set the buttons
- Parameters:
buttons – The struct containing the button values
-
template<PlaystationDualsenseButtonStruct T>
inline constexpr void get_buttons(T &t) const Get the button values
- Parameters:
t – The struct to fill with the button values
-
inline constexpr void get_left_joystick(float &lx, float &ly) const
Get the left joystick X and Y axis values
- Parameters:
lx – [out] left joystick x axis value, in the range [-1, 1]
ly – [out] left joystick y axis value, in the range [-1, 1]
-
inline constexpr void get_left_joystick(JOYSTICK_TYPE &lx, JOYSTICK_TYPE &ly) const
Get the left joystick X and Y axis values
- Parameters:
lx – [out] left joystick x axis value
ly – [out] left joystick y axis value
-
inline constexpr void get_right_joystick(float &rx, float &ry) const
Get the right joystick X and Y axis values
- Parameters:
rx – [out] right joystick x axis value, in the range [-1, 1]
ry – [out] right joystick y axis value, in the range [-1, 1]
-
inline constexpr void get_right_joystick(JOYSTICK_TYPE &rx, JOYSTICK_TYPE &ry) const
Get the right joystick X and Y axis values
- Parameters:
rx – [out] right joystick x axis value
ry – [out] right joystick y axis value
-
inline constexpr void set_left_joystick(float lx, float ly)
Set the left joystick X and Y axis values
- Parameters:
lx – left joystick x axis value, in the range [-1, 1]
ly – left joystick y axis value, in the range [-1, 1]
-
inline constexpr void set_right_joystick(float rx, float ry)
Set the right joystick X and Y axis values
- Parameters:
rx – right joystick x axis value, in the range [-1, 1]
ry – right joystick y axis value, in the range [-1, 1]
-
inline constexpr void get_left_trigger(float &value) const
Get the left trigger value
- Parameters:
value – left trigger value, in the range [0, 1]
-
inline constexpr void set_left_trigger(float value)
Set the left trigger value
- Parameters:
value – left trigger value, in the range [0, 1]
-
inline constexpr void get_right_trigger(float &value) const
Get the right trigger value
- Parameters:
value – right trigger value, in the range [0, 1]
-
inline constexpr void set_right_trigger(float value)
Set the right trigger value
- Parameters:
value – right trigger value, in the range [0, 1]
-
inline constexpr void set_joystick_axis(size_t index, JOYSTICK_TYPE value)
Set the joystick axis value
Note
The value should be in the range [joystick_min, joystick_max].
- Parameters:
index – The index of the joystick axis to set. Should be between 0 and 3, inclusive.
value – The value to set the joystick axis to.
-
inline constexpr void set_joystick_axis(size_t index, float value)
Set the joystick axis value
Note
The value should be in the range [-1, 1].
- Parameters:
index – The index of the joystick axis to set. Should be between 0 and 3, inclusive.
value – The value to set the joystick axis to.
-
inline constexpr void get_joystick_axis(size_t index, float &value) const
Get the joystick axis value
- Parameters:
index – The index of the joystick axis to get. Should be between 0 and 3, inclusive.
value – The variable to store the joystick axis value in.
-
inline constexpr void get_joystick_axis(size_t index, JOYSTICK_TYPE &value) const
Get the joystick axis value
- Parameters:
index – The index of the joystick axis to get. Should be between 0 and 3, inclusive.
value – The variable to store the joystick axis value in.
-
inline constexpr void set_trigger_axis(size_t index, TRIGGER_TYPE value)
Set the trigger axis value
Note
The value should be in the range [trigger_min, trigger_max].
- Parameters:
index – The index of the trigger axis to set. Should be between 0 and 1, inclusive.
value – The value to set the trigger axis to.
-
inline constexpr void set_trigger_axis(size_t index, float value)
Set the trigger axis value
Note
The value should be in the range [0, 1].
- Parameters:
index – The index of the trigger axis to set. Should be between 0 and 1, inclusive.
value – The value to set the trigger axis to.
-
inline constexpr void get_trigger_axis(size_t index, float &value) const
Get the trigger axis value
- Parameters:
index – The index of the trigger axis to get. Should be between 0 and 1, inclusive.
value – The variable to store the trigger axis value in.
-
inline constexpr void get_trigger_axis(size_t index, TRIGGER_TYPE &value) const
Get the trigger axis value
- Parameters:
index – The index of the trigger axis to get. Should be between 0 and 1, inclusive.
value – The variable to store the trigger axis value in.
-
inline constexpr bool get_button(int button_index) const
Get the button value
- Parameters:
button_index – The button for which you want to get the value.
- Returns:
The true/false value of the button.
-
inline constexpr void set_button(int button_index, bool value)
Set the button value
- Parameters:
button_index – The button for which you want to set the value. Should be between 1 and 14, inclusive.
value – The true/false value you want to se the button to.
-
inline constexpr void set_hat_switch(espp::gamepad::Hat hat)
Set the hat switch value from espp::gamepad::Hat
- Parameters:
hat – The espp::gamepad::Hat value to set.
-
inline constexpr void set_hat_switch(Hat hat)
Set the hat switch value
- Parameters:
hat – The hat switch value to set.
-
inline constexpr void set_hat_switch(std::uint8_t value)
Set the hat switch value
Note
The value should match the values within the Hat enum.
- Parameters:
value – The hat switch value to set.
-
inline constexpr void set_hat(espp::gamepad::Hat hat)
Set the hat switch (d-pad) value
- Parameters:
hat – Hat enum / direction to set
-
inline constexpr void set_hat(Hat hat)
Set the hat switch (d-pad) value
- Parameters:
hat – Hat enum / direction to set
-
inline constexpr void set_hat(bool up, bool down, bool left, bool right)
Set the hat switch (d-pad) value
- Parameters:
up – up direction
down – down direction
left – left direction
right – right direction
-
inline constexpr Hat get_hat() const
Get the hat switch (d-pad) value
- Returns:
Hat enum / direction
-
inline constexpr void get_hat(bool &up, bool &down, bool &left, bool &right) const
Get the hat switch (d-pad) value
- Parameters:
up – up direction
down – down direction
left – left direction
right – right direction
-
inline constexpr auto get_report() const
Get the input report as a vector of bytes
Note
The report id is not included in the returned vector.
- Returns:
The input report as a vector of bytes.
-
inline constexpr void set_data(const std::vector<uint8_t> &data)
Set the output report data from a vector of bytes
- Parameters:
data – The data to set the output report to.
Public Static Functions
-
static inline constexpr auto get_descriptor()
Get the report descriptor as a hid::rdf::descriptor
Note
This is an incomplete descriptor, you will need to add it to a collection::application descriptor to create a complete report descriptor.
using namespace hid::page; using namespace hid::rdf; auto gamepad_descriptor = gamepad_input_report.get_descriptor(); auto rdf_descriptor = descriptor( usage_page<generic_desktop>(), usage(generic_desktop::GAMEPAD), collection::application( gamepad_descriptor ) ); auto descriptor = std::vector<uint8_t>(rdf_descriptor.begin(), rdf_descriptor.end());
- Returns:
The report descriptor as a hid::rdf::descriptor.
Public Static Attributes
-
static constexpr size_t button_count = 14
Number of buttons supported.
-
static constexpr JOYSTICK_TYPE joystick_min = 0
Minimum value for the joystick axes.
-
static constexpr JOYSTICK_TYPE joystick_max = 255
Maximum value for the joystick axes.
-
static constexpr JOYSTICK_TYPE joystick_center = (joystick_min + joystick_max) / 2
Center value for the joystick axes.
-
static constexpr size_t joystick_value_range = joystick_max - joystick_min
Range of values for the joystick axes.
-
static constexpr JOYSTICK_TYPE joystick_range = joystick_value_range / 2
Half the range of values for the joystick axes.
-
static constexpr size_t num_joystick_bits = num_bits(joystick_value_range)
Number of bits needed to represent the joystick axes.
-
static constexpr TRIGGER_TYPE trigger_min = 0
Minimum value for the trigger axes.
-
static constexpr TRIGGER_TYPE trigger_max = 255
Maximum value for the trigger axes.
-
static constexpr TRIGGER_TYPE trigger_center = trigger_min
Center value for the trigger axes.
-
static constexpr size_t trigger_range = trigger_max - trigger_min
Range of values for the trigger axes.
-
static constexpr size_t num_trigger_bits = num_bits(trigger_range)
Number of bits needed to represent the trigger axes.
-
static constexpr std::size_t BTN_SQUARE_INDEX = {1}
The index of the SQUARE button.
-
static constexpr std::size_t BTN_CROSS_INDEX = {2}
The index of the CROSS button.
-
static constexpr std::size_t BTN_CIRCLE_INDEX = {3}
The index of the CIRCLE button.
-
static constexpr std::size_t BTN_TRIANGLE_INDEX = {4}
The index of the TRIANGLE button.
-
static constexpr std::size_t BTN_L1_INDEX = {5}
The index of the L1 button.
-
static constexpr std::size_t BTN_R1_INDEX = {6}
The index of the R1 button.
-
static constexpr std::size_t BTN_L2_INDEX = {7}
The index of the L2 button.
-
static constexpr std::size_t BTN_R2_INDEX = {8}
The index of the R2 button.
-
static constexpr std::size_t BTN_L3_INDEX = {11}
The index of the L3 button.
-
static constexpr std::size_t BTN_R3_INDEX = {12}
The index of the R3 button.
-
static constexpr std::size_t BTN_HOME_INDEX = {13}
The index of the Home button.
-
static constexpr std::size_t BTN_MENU_INDEX = {10}
The index of the Menu button.
-
static constexpr std::size_t BTN_OPTIONS_INDEX = {9}
The index of the Options button.
-
static constexpr std::size_t BTN_CAPTURE_INDEX = {14}
The index of the Capture button.
-
template<uint8_t REPORT_ID = 49>
class PlaystationDualsenseBLEComplexInputReport : public hid::report::base<hid::report::type::INPUT, 49> HID Playstation DualSense Bluetooth Gamepad Input Report
This class implements a HID Playstation DualSense Bluetooth Gamepad Report. It supports 15 buttons, a d-pad, 4 joystick axes, and 2 trigger axes. It also includes a timestamp, packet counter, and vendor defined data. The vendor defined data includes IMU data, battery level, touchpad data, and CRC32.
This matches the information found here: https://github.com/nondebug/dualsense which provides a bluetooth VID/PID of 054C:0CE6
HID-RP Playstation Gamepad Example
static constexpr uint8_t input_report_id = 1; static constexpr uint8_t battery_report_id = 4; static constexpr size_t num_buttons = 15; static constexpr int joystick_min = 0; static constexpr int joystick_max = 65535; static constexpr int trigger_min = 0; static constexpr int trigger_max = 1023; using GamepadInput = espp::GamepadInputReport<num_buttons, std::uint16_t, std::uint16_t, joystick_min, joystick_max, trigger_min, trigger_max, input_report_id>; GamepadInput gamepad_input_report; using XboxInput = espp::XboxGamepadInputReport<input_report_id>; XboxInput xbox_input_report; using BatteryReport = espp::XboxBatteryInputReport<battery_report_id>; BatteryReport battery_input_report; static constexpr uint8_t led_output_report_id = 2; static constexpr size_t num_leds = 4; using GamepadLeds = espp::GamepadLedOutputReport<num_leds, led_output_report_id>; GamepadLeds gamepad_leds_report; static constexpr uint8_t rumble_output_report_id = 3; using RumbleReport = espp::XboxRumbleOutputReport<rumble_output_report_id>; RumbleReport rumble_output_report; using namespace hid::page; using namespace hid::rdf; auto raw_descriptor = descriptor(usage_page<generic_desktop>(), usage(generic_desktop::GAMEPAD), collection::application(gamepad_input_report.get_descriptor(), rumble_output_report.get_descriptor(), battery_input_report.get_descriptor(), gamepad_leds_report.get_descriptor())); // Generate the report descriptor for the gamepad auto descriptor = std::vector<uint8_t>(raw_descriptor.begin(), raw_descriptor.end()); logger.info("Report Descriptor:"); logger.info(" Size: {}", descriptor.size()); logger.info(" Data: {::#04X}", descriptor); using SwitchProInput = espp::SwitchProGamepadInputReport<>; SwitchProInput switch_pro_input_report; logger.info("{}", switch_pro_input_report); logger.info("Switch Pro Input Report Size: {}", switch_pro_input_report.get_report().size()); logger.info("Switch Pro Input Report Data: {::#04X}", switch_pro_input_report.get_report()); auto sp_raw_descriptor = espp::switch_pro_descriptor(); auto sp_descriptor = std::vector<uint8_t>(sp_raw_descriptor.begin(), sp_raw_descriptor.end()); logger.info("Switch Report Descriptor:"); logger.info(" Size: {}", sp_descriptor.size()); std::string str = ""; for (auto &byte : sp_descriptor) { str += fmt::format("0x{:02X}, ", byte); } logger.info(" Data: [{}]", str); using PlaystationDualsenseBleSimpleInput = espp::PlaystationDualsenseBLESimpleInputReport<>; PlaystationDualsenseBleSimpleInput dualsense_simple_input_report; using PlaystationDualsenseBleComplexInput = espp::PlaystationDualsenseBLEComplexInputReport<>; PlaystationDualsenseBleComplexInput dualsense_complex_input_report; logger.info("Playstation Dualsense BLE Report Descriptor:"); auto ps_raw_descriptor = espp::playstation_dualsense_ble_descriptor(); auto ps_descriptor = std::vector<uint8_t>(ps_raw_descriptor.begin(), ps_raw_descriptor.end()); logger.info(" Size: {}", ps_descriptor.size()); str = ""; for (auto &byte : ps_descriptor) { str += fmt::format("0x{:02X}, ", byte); } logger.info(" Data: [{}]", str); GamepadInput::Hat hat = GamepadInput::Hat::UP_RIGHT; int button_index = 5; float angle = 2.0f * M_PI * button_index / num_buttons; // reset all reports gamepad_input_report.reset(); xbox_input_report.reset(); switch_pro_input_report.reset(); dualsense_simple_input_report.reset(); dualsense_complex_input_report.reset(); // print out the reports in their default states logger.info("{}", gamepad_input_report); logger.info("{}", xbox_input_report); logger.info("{}", switch_pro_input_report); logger.info("{}", dualsense_simple_input_report); logger.info("{}", dualsense_complex_input_report); // update the gamepad input report logger.info("{}", gamepad_input_report); gamepad_input_report.set_hat(hat); gamepad_input_report.set_button(button_index, true); // joystick inputs are in the range [-1, 1] float gamepad_input_report.set_right_joystick(cos(angle), sin(angle)); gamepad_input_report.set_left_joystick(sin(angle), cos(angle)); // trigger inputs are in the range [0, 1] float gamepad_input_report.set_accelerator(std::abs(sin(angle))); gamepad_input_report.set_brake(std::abs(cos(angle))); switch_pro_input_report.set_button(button_index, true); switch_pro_input_report.set_dpad(false, true, false, true); // down-right switch_pro_input_report.set_left_joystick(sin(angle), cos(angle)); switch_pro_input_report.set_right_joystick(cos(angle), sin(angle)); switch_pro_input_report.set_left_trigger((float)std::abs(cos(angle))); switch_pro_input_report.set_right_trigger((float)std::abs(sin(angle))); dualsense_simple_input_report.set_button(button_index, true); dualsense_simple_input_report.set_hat(hat); dualsense_simple_input_report.set_left_joystick(sin(angle), cos(angle)); dualsense_simple_input_report.set_right_joystick(cos(angle), sin(angle)); dualsense_simple_input_report.set_left_trigger(std::abs(cos(angle))); dualsense_simple_input_report.set_right_trigger(std::abs(sin(angle))); dualsense_complex_input_report.set_button(button_index, true); dualsense_complex_input_report.set_hat(hat); dualsense_complex_input_report.set_left_joystick(sin(angle), cos(angle)); dualsense_complex_input_report.set_right_joystick(cos(angle), sin(angle)); dualsense_complex_input_report.set_left_trigger(std::abs(cos(angle))); dualsense_complex_input_report.set_right_trigger(std::abs(sin(angle))); button_index = (button_index % num_buttons) + 1; // send an input report auto report = gamepad_input_report.get_report(); logger.info("{}", gamepad_input_report); logger.info("Gamepad Input report:"); logger.info(" Size: {}", report.size()); logger.info(" Data: {::#02X}", report); report = switch_pro_input_report.get_report(); logger.info("{}", switch_pro_input_report); logger.info("Switch Pro Input report:"); logger.info(" Size: {}", report.size()); logger.info(" Data: {::#02X}", report); report = dualsense_simple_input_report.get_report(); logger.info("{}", dualsense_simple_input_report); logger.info("Playstation Dualsense BLE Simple Input report:"); logger.info(" Size: {}", report.size()); logger.info(" Data: {::#02X}", report); report = dualsense_complex_input_report.get_report(); logger.info("{}", dualsense_complex_input_report); logger.info("Playstation Dualsense BLE Complex Input report:"); logger.info(" Size: {}", report.size()); logger.info(" Data: {::#02X}", report); // update the battery input report battery_input_report.reset(); battery_input_report.set_rechargeable(true); battery_input_report.set_charging(false); battery_input_report.set_rechargeable(true); // note: it can only show 5, 40, 70, 100 so this will be rounded to 40 battery_input_report.set_battery_level(50); // send a battery report report = battery_input_report.get_report(); logger.info("Battery report:"); logger.info(" Size: {}", report.size()); logger.info(" Data: {::#02X}", report);
Note
I have tested the playstation dualsense report descriptor and input reports over BLE with iOS, MacOS, Windows, and Android and found that:
iOS, MacOS, and Windows only parse the complex report (0x31) and ignore the simple report (0x01). This means that the simple report is effectively unused fields in the report descriptor.
Android seems to require Audio support, which it cannot find over BLE, so it does not work at all.
Public Types
-
using Hat = PlaystationHat
The type used for the hat switch.
-
using JOYSTICK_TYPE = std::uint8_t
The type used for the joystick axes.
-
using TRIGGER_TYPE = std::uint8_t
The type used for the trigger axes.
Public Functions
-
constexpr PlaystationDualsenseBLEComplexInputReport() = default
Construct a new PlaystationPDualSenseBLE Gamepad Input Report object.
-
inline constexpr void reset()
Reset the gamepad inputs.
-
inline constexpr void set_counter(uint8_t value)
Set the counter
- Parameters:
value – The value to set the counter to.
-
inline constexpr void increment_counter(uint8_t inc = 1)
Increment the counter.
-
inline constexpr uint8_t get_counter() const
Get the counter value
- Returns:
The counter value
-
inline constexpr void set_battery_level(uint8_t level, bool charging)
Set the battery level as a percentage (0-100) and if it is charging
- Parameters:
level – The battery level as a percentage (0-100)
charging – True if the battery is charging, false otherwise
-
inline constexpr void set_battery_level(uint8_t level)
Set the battery level as a percentage (0-100)
- Parameters:
level – The battery level as a percentage (0-100)
-
inline constexpr uint8_t get_battery_level() const
Get the battery level as a percentage (0-100)
- Returns:
The battery level as a percentage (0-100)
-
inline constexpr bool is_battery_charging() const
Check if the battery is charging
- Returns:
True if the battery is charging, false otherwise
-
inline constexpr void set_battery_charging(bool charging)
Set if the battery is charging
- Parameters:
charging – True if the battery is charging, false otherwise
-
template<PlaystationDualsenseButtonStruct T>
inline constexpr void set_buttons(const T &buttons) Set the buttons
- Parameters:
buttons – The struct containing the button values
-
template<PlaystationDualsenseButtonStruct T>
inline constexpr void get_buttons(T &t) const Get the button values
- Parameters:
t – The struct to fill with the button values
-
inline constexpr void get_left_joystick(float &lx, float &ly) const
Get the left joystick X and Y axis values
- Parameters:
lx – [out] left joystick x axis value, in the range [-1, 1]
ly – [out] left joystick y axis value, in the range [-1, 1]
-
inline constexpr void get_left_joystick(JOYSTICK_TYPE &lx, JOYSTICK_TYPE &ly) const
Get the left joystick X and Y axis values
- Parameters:
lx – [out] left joystick x axis value
ly – [out] left joystick y axis value
-
inline constexpr void get_right_joystick(float &rx, float &ry) const
Get the right joystick X and Y axis values
- Parameters:
rx – [out] right joystick x axis value, in the range [-1, 1]
ry – [out] right joystick y axis value, in the range [-1, 1]
-
inline constexpr void get_right_joystick(JOYSTICK_TYPE &rx, JOYSTICK_TYPE &ry) const
Get the right joystick X and Y axis values
- Parameters:
rx – [out] right joystick x axis value
ry – [out] right joystick y axis value
-
inline constexpr void set_left_joystick(float lx, float ly)
Set the left joystick X and Y axis values
- Parameters:
lx – left joystick x axis value, in the range [-1, 1]
ly – left joystick y axis value, in the range [-1, 1]
-
inline constexpr void set_right_joystick(float rx, float ry)
Set the right joystick X and Y axis values
- Parameters:
rx – right joystick x axis value, in the range [-1, 1]
ry – right joystick y axis value, in the range [-1, 1]
-
inline constexpr void get_left_trigger(float &value) const
Get the left trigger value
- Parameters:
value – left trigger value, in the range [0, 1]
-
inline constexpr void set_left_trigger(float value)
Set the left trigger value
- Parameters:
value – left trigger value, in the range [0, 1]
-
inline constexpr void get_right_trigger(float &value) const
Get the right trigger value
- Parameters:
value – right trigger value, in the range [0, 1]
-
inline constexpr void set_right_trigger(float value)
Set the right trigger value
- Parameters:
value – right trigger value, in the range [0, 1]
-
inline constexpr void set_joystick_axis(size_t index, JOYSTICK_TYPE value)
Set the joystick axis value
Note
The value should be in the range [joystick_min, joystick_max].
- Parameters:
index – The index of the joystick axis to set. Should be between 0 and 3, inclusive.
value – The value to set the joystick axis to.
-
inline constexpr void set_joystick_axis(size_t index, float value)
Set the joystick axis value
Note
The value should be in the range [-1, 1].
- Parameters:
index – The index of the joystick axis to set. Should be between 0 and 3, inclusive.
value – The value to set the joystick axis to.
-
inline constexpr void get_joystick_axis(size_t index, float &value) const
Get the joystick axis value
- Parameters:
index – The index of the joystick axis to get. Should be between 0 and 3, inclusive.
value – The variable to store the joystick axis value in.
-
inline constexpr void get_joystick_axis(size_t index, JOYSTICK_TYPE &value) const
Get the joystick axis value
- Parameters:
index – The index of the joystick axis to get. Should be between 0 and 3, inclusive.
value – The variable to store the joystick axis value in.
-
inline constexpr void set_trigger_axis(size_t index, TRIGGER_TYPE value)
Set the trigger axis value
Note
The value should be in the range [trigger_min, trigger_max].
- Parameters:
index – The index of the trigger axis to set. Should be between 0 and 1, inclusive.
value – The value to set the trigger axis to.
-
inline constexpr void set_trigger_axis(size_t index, float value)
Set the trigger axis value
Note
The value should be in the range [0, 1].
- Parameters:
index – The index of the trigger axis to set. Should be between 0 and 1, inclusive.
value – The value to set the trigger axis to.
-
inline constexpr void get_trigger_axis(size_t index, float &value) const
Get the trigger axis value
- Parameters:
index – The index of the trigger axis to get. Should be between 0 and 1, inclusive.
value – The variable to store the trigger axis value in.
-
inline constexpr void get_trigger_axis(size_t index, TRIGGER_TYPE &value) const
Get the trigger axis value
- Parameters:
index – The index of the trigger axis to get. Should be between 0 and 1, inclusive.
value – The variable to store the trigger axis value in.
-
inline constexpr bool get_button(int button_index) const
Get the button value
- Parameters:
button_index – The button for which you want to get the value.
- Returns:
The true/false value of the button.
-
inline constexpr void set_button(int button_index, bool value)
Set the button value
- Parameters:
button_index – The button for which you want to set the value. Should be between 1 and 14, inclusive.
value – The true/false value you want to se the button to.
-
inline constexpr void set_hat_switch(espp::gamepad::Hat hat)
Set the hat switch value from espp::gamepad::Hat
- Parameters:
hat – The espp::gamepad::Hat value to set.
-
inline constexpr void set_hat_switch(Hat hat)
Set the hat switch value
- Parameters:
hat – The hat switch value to set.
-
inline constexpr void set_hat_switch(std::uint8_t value)
Set the hat switch value
Note
The value should match the values within the Hat enum.
- Parameters:
value – The hat switch value to set.
-
inline constexpr void set_hat(espp::gamepad::Hat hat)
Set the hat switch (d-pad) value
- Parameters:
hat – Hat enum / direction to set
-
inline constexpr void set_hat(Hat hat)
Set the hat switch (d-pad) value
- Parameters:
hat – Hat enum / direction to set
-
inline constexpr void set_hat(bool up, bool down, bool left, bool right)
Set the hat switch (d-pad) value
- Parameters:
up – up direction
down – down direction
left – left direction
right – right direction
-
inline constexpr Hat get_hat() const
Get the hat switch (d-pad) value
- Returns:
Hat enum / direction
-
inline constexpr void get_hat(bool &up, bool &down, bool &left, bool &right) const
Get the hat switch (d-pad) value
- Parameters:
up – up direction
down – down direction
left – left direction
right – right direction
-
inline constexpr auto get_report() const
Get the input report as a vector of bytes
Note
The report id is not included in the returned vector.
- Returns:
The input report as a vector of bytes.
-
inline constexpr void set_data(const std::vector<uint8_t> &data)
Set the output report data from a vector of bytes
- Parameters:
data – The data to set the output report to.
Public Static Functions
-
static inline constexpr auto get_descriptor()
Get the report descriptor as a hid::rdf::descriptor
Note
This is an incomplete descriptor, you will need to add it to a collection::application descriptor to create a complete report descriptor.
using namespace hid::page; using namespace hid::rdf; auto gamepad_descriptor = gamepad_input_report.get_descriptor(); auto rdf_descriptor = descriptor( usage_page<generic_desktop>(), usage(generic_desktop::GAMEPAD), collection::application( gamepad_descriptor ) ); auto descriptor = std::vector<uint8_t>(rdf_descriptor.begin(), rdf_descriptor.end());
- Returns:
The report descriptor as a hid::rdf::descriptor.
Public Static Attributes
-
static constexpr size_t button_count = 15
Number of buttons supported.
-
static constexpr JOYSTICK_TYPE joystick_min = 0
Minimum value for the joystick axes.
-
static constexpr JOYSTICK_TYPE joystick_max = 255
Maximum value for the joystick axes.
-
static constexpr JOYSTICK_TYPE joystick_center = (joystick_min + joystick_max) / 2
Center value for the joystick axes.
-
static constexpr size_t joystick_value_range = joystick_max - joystick_min
Range of values for the joystick axes.
-
static constexpr JOYSTICK_TYPE joystick_range = joystick_value_range / 2
Half the range of values for the joystick axes.
-
static constexpr size_t num_joystick_bits = num_bits(joystick_value_range)
Number of bits needed to represent the joystick axes.
-
static constexpr TRIGGER_TYPE trigger_min = 0
Minimum value for the trigger axes.
-
static constexpr TRIGGER_TYPE trigger_max = 255
Maximum value for the trigger axes.
-
static constexpr TRIGGER_TYPE trigger_center = trigger_min
Center value for the trigger axes.
-
static constexpr size_t trigger_range = trigger_max - trigger_min
Range of values for the trigger axes.
-
static constexpr size_t num_trigger_bits = num_bits(trigger_range)
Number of bits needed to represent the trigger axes.
-
static constexpr std::size_t BTN_SQUARE_INDEX = {1}
The index of the SQUARE button.
-
static constexpr std::size_t BTN_CROSS_INDEX = {2}
The index of the CROSS button.
-
static constexpr std::size_t BTN_CIRCLE_INDEX = {3}
The index of the CIRCLE button.
-
static constexpr std::size_t BTN_TRIANGLE_INDEX = {4}
The index of the TRIANGLE button.
-
static constexpr std::size_t BTN_L1_INDEX = {5}
The index of the L1 button.
-
static constexpr std::size_t BTN_R1_INDEX = {6}
The index of the R1 button.
-
static constexpr std::size_t BTN_L2_INDEX = {7}
The index of the L2 button.
-
static constexpr std::size_t BTN_R2_INDEX = {8}
The index of the R2 button.
-
static constexpr std::size_t BTN_L3_INDEX = {11}
The index of the L3 button.
-
static constexpr std::size_t BTN_R3_INDEX = {12}
The index of the R3 button.
-
static constexpr std::size_t BTN_HOME_INDEX = {13}
The index of the Home button.
-
static constexpr std::size_t BTN_MENU_INDEX = {10}
The index of the Menu button.
-
static constexpr std::size_t BTN_OPTIONS_INDEX = {9}
The index of the Options button.
-
static constexpr std::size_t BTN_CAPTURE_INDEX = {14}
The index of the Capture button.
-
static constexpr std::size_t BTN_MIC_INDEX = {15}
The index of the Mic Mute button.
Header File
Classes
-
template<uint8_t REPORT_ID = 0x30>
class SwitchProGamepadInputReport : public hid::report::base<hid::report::type::INPUT, 0x30> HID Switch Pro Gamepad Input Report
This class implements a HID Switch Pro Gamepad Input Report. It supports 15 buttons, a d-pad, 4 joystick axes and two trigger buttons. It supports setting the buttons, d-pad, joysticks, and triggers, as well as serializing the input report and getting the report descriptor.
HID-RP Switch Pro Example
static constexpr uint8_t input_report_id = 1; static constexpr uint8_t battery_report_id = 4; static constexpr size_t num_buttons = 15; static constexpr int joystick_min = 0; static constexpr int joystick_max = 65535; static constexpr int trigger_min = 0; static constexpr int trigger_max = 1023; using GamepadInput = espp::GamepadInputReport<num_buttons, std::uint16_t, std::uint16_t, joystick_min, joystick_max, trigger_min, trigger_max, input_report_id>; GamepadInput gamepad_input_report; using XboxInput = espp::XboxGamepadInputReport<input_report_id>; XboxInput xbox_input_report; using BatteryReport = espp::XboxBatteryInputReport<battery_report_id>; BatteryReport battery_input_report; static constexpr uint8_t led_output_report_id = 2; static constexpr size_t num_leds = 4; using GamepadLeds = espp::GamepadLedOutputReport<num_leds, led_output_report_id>; GamepadLeds gamepad_leds_report; static constexpr uint8_t rumble_output_report_id = 3; using RumbleReport = espp::XboxRumbleOutputReport<rumble_output_report_id>; RumbleReport rumble_output_report; using namespace hid::page; using namespace hid::rdf; auto raw_descriptor = descriptor(usage_page<generic_desktop>(), usage(generic_desktop::GAMEPAD), collection::application(gamepad_input_report.get_descriptor(), rumble_output_report.get_descriptor(), battery_input_report.get_descriptor(), gamepad_leds_report.get_descriptor())); // Generate the report descriptor for the gamepad auto descriptor = std::vector<uint8_t>(raw_descriptor.begin(), raw_descriptor.end()); logger.info("Report Descriptor:"); logger.info(" Size: {}", descriptor.size()); logger.info(" Data: {::#04X}", descriptor); using SwitchProInput = espp::SwitchProGamepadInputReport<>; SwitchProInput switch_pro_input_report; logger.info("{}", switch_pro_input_report); logger.info("Switch Pro Input Report Size: {}", switch_pro_input_report.get_report().size()); logger.info("Switch Pro Input Report Data: {::#04X}", switch_pro_input_report.get_report()); auto sp_raw_descriptor = espp::switch_pro_descriptor(); auto sp_descriptor = std::vector<uint8_t>(sp_raw_descriptor.begin(), sp_raw_descriptor.end()); logger.info("Switch Report Descriptor:"); logger.info(" Size: {}", sp_descriptor.size()); std::string str = ""; for (auto &byte : sp_descriptor) { str += fmt::format("0x{:02X}, ", byte); } logger.info(" Data: [{}]", str); using PlaystationDualsenseBleSimpleInput = espp::PlaystationDualsenseBLESimpleInputReport<>; PlaystationDualsenseBleSimpleInput dualsense_simple_input_report; using PlaystationDualsenseBleComplexInput = espp::PlaystationDualsenseBLEComplexInputReport<>; PlaystationDualsenseBleComplexInput dualsense_complex_input_report; logger.info("Playstation Dualsense BLE Report Descriptor:"); auto ps_raw_descriptor = espp::playstation_dualsense_ble_descriptor(); auto ps_descriptor = std::vector<uint8_t>(ps_raw_descriptor.begin(), ps_raw_descriptor.end()); logger.info(" Size: {}", ps_descriptor.size()); str = ""; for (auto &byte : ps_descriptor) { str += fmt::format("0x{:02X}, ", byte); } logger.info(" Data: [{}]", str); GamepadInput::Hat hat = GamepadInput::Hat::UP_RIGHT; int button_index = 5; float angle = 2.0f * M_PI * button_index / num_buttons; // reset all reports gamepad_input_report.reset(); xbox_input_report.reset(); switch_pro_input_report.reset(); dualsense_simple_input_report.reset(); dualsense_complex_input_report.reset(); // print out the reports in their default states logger.info("{}", gamepad_input_report); logger.info("{}", xbox_input_report); logger.info("{}", switch_pro_input_report); logger.info("{}", dualsense_simple_input_report); logger.info("{}", dualsense_complex_input_report); // update the gamepad input report logger.info("{}", gamepad_input_report); gamepad_input_report.set_hat(hat); gamepad_input_report.set_button(button_index, true); // joystick inputs are in the range [-1, 1] float gamepad_input_report.set_right_joystick(cos(angle), sin(angle)); gamepad_input_report.set_left_joystick(sin(angle), cos(angle)); // trigger inputs are in the range [0, 1] float gamepad_input_report.set_accelerator(std::abs(sin(angle))); gamepad_input_report.set_brake(std::abs(cos(angle))); switch_pro_input_report.set_button(button_index, true); switch_pro_input_report.set_dpad(false, true, false, true); // down-right switch_pro_input_report.set_left_joystick(sin(angle), cos(angle)); switch_pro_input_report.set_right_joystick(cos(angle), sin(angle)); switch_pro_input_report.set_left_trigger((float)std::abs(cos(angle))); switch_pro_input_report.set_right_trigger((float)std::abs(sin(angle))); dualsense_simple_input_report.set_button(button_index, true); dualsense_simple_input_report.set_hat(hat); dualsense_simple_input_report.set_left_joystick(sin(angle), cos(angle)); dualsense_simple_input_report.set_right_joystick(cos(angle), sin(angle)); dualsense_simple_input_report.set_left_trigger(std::abs(cos(angle))); dualsense_simple_input_report.set_right_trigger(std::abs(sin(angle))); dualsense_complex_input_report.set_button(button_index, true); dualsense_complex_input_report.set_hat(hat); dualsense_complex_input_report.set_left_joystick(sin(angle), cos(angle)); dualsense_complex_input_report.set_right_joystick(cos(angle), sin(angle)); dualsense_complex_input_report.set_left_trigger(std::abs(cos(angle))); dualsense_complex_input_report.set_right_trigger(std::abs(sin(angle))); button_index = (button_index % num_buttons) + 1; // send an input report auto report = gamepad_input_report.get_report(); logger.info("{}", gamepad_input_report); logger.info("Gamepad Input report:"); logger.info(" Size: {}", report.size()); logger.info(" Data: {::#02X}", report); report = switch_pro_input_report.get_report(); logger.info("{}", switch_pro_input_report); logger.info("Switch Pro Input report:"); logger.info(" Size: {}", report.size()); logger.info(" Data: {::#02X}", report); report = dualsense_simple_input_report.get_report(); logger.info("{}", dualsense_simple_input_report); logger.info("Playstation Dualsense BLE Simple Input report:"); logger.info(" Size: {}", report.size()); logger.info(" Data: {::#02X}", report); report = dualsense_complex_input_report.get_report(); logger.info("{}", dualsense_complex_input_report); logger.info("Playstation Dualsense BLE Complex Input report:"); logger.info(" Size: {}", report.size()); logger.info(" Data: {::#02X}", report); // update the battery input report battery_input_report.reset(); battery_input_report.set_rechargeable(true); battery_input_report.set_charging(false); battery_input_report.set_rechargeable(true); // note: it can only show 5, 40, 70, 100 so this will be rounded to 40 battery_input_report.set_battery_level(50); // send a battery report report = battery_input_report.get_report(); logger.info("Battery report:"); logger.info(" Size: {}", report.size()); logger.info(" Data: {::#02X}", report);
Public Functions
-
constexpr SwitchProGamepadInputReport() = default
Construct a new Gamepad Input Report object.
-
inline constexpr void reset()
Reset the gamepad inputs.
-
inline constexpr void set_counter(uint8_t value)
Set the counter
- Parameters:
value – The value to set the counter to.
-
inline constexpr void increment_counter()
Increment the counter.
-
inline constexpr uint8_t get_counter() const
Get the counter value
- Returns:
The counter value
-
inline constexpr void set_subcmd_ack(uint8_t ack)
Set the subcommand ACK
- Parameters:
ack – The subcommand ACK to set
-
inline constexpr uint8_t get_subcmd_ack() const
Get the subcommand ACK
- Returns:
The subcommand ACK
-
inline constexpr void set_subcmd_id(uint8_t id)
Set the subcommand ID
- Parameters:
id – The subcommand ID to set
-
inline constexpr uint8_t get_subcmd_id() const
Get the subcommand ID
- Returns:
The subcommand ID
-
inline constexpr void set_subcmd_reply(const std::vector<uint8_t> &reply)
Set the subcommand reply
- Parameters:
reply – The subcommand reply to set
-
inline constexpr auto get_subcmd_reply() const
Get the subcommand reply
- Returns:
The subcommand reply
-
inline constexpr void set_left_joystick(float lx, float ly)
Set the left joystick X and Y axis values
- Parameters:
lx – left joystick x axis value, in the range [-1, 1]
ly – left joystick y axis value, in the range [-1, 1]
-
inline constexpr void set_right_joystick(float rx, float ry)
Set the right joystick X and Y axis values
- Parameters:
rx – right joystick x axis value, in the range [-1, 1]
ry – right joystick y axis value, in the range [-1, 1]
-
inline constexpr void get_left_joystick(float &lx, float &ly) const
Get the left joystick X and Y axis values
- Parameters:
lx – left joystick x axis value, in the range [-1, 1]
ly – left joystick y axis value, in the range [-1, 1]
-
inline constexpr void get_left_joystick(JOYSTICK_TYPE &lx, JOYSTICK_TYPE &ly) const
Get the left joystick X and Y axis values
- Parameters:
lx – left joystick x axis value
ly – left joystick y axis value
-
inline constexpr void get_right_joystick(float &rx, float &ry) const
Get the right joystick X and Y axis values
- Parameters:
rx – right joystick x axis value, in the range [-1, 1]
ry – right joystick y axis value, in the range [-1, 1]
-
inline constexpr void get_right_joystick(JOYSTICK_TYPE &rx, JOYSTICK_TYPE &ry) const
Get the right joystick X and Y axis values
- Parameters:
rx – right joystick x axis value
ry – right joystick y axis value
-
inline constexpr void set_left_trigger(float value)
Set the left trigger value
- Parameters:
value – The value to set the left trigger to. Should be in the range [0, 1].
-
inline constexpr void set_left_trigger(bool pressed)
Set the right trigger value
- Parameters:
pressed – Whether the right trigger is pressed or not
-
inline constexpr void set_right_trigger(float value)
Set the right trigger value
- Parameters:
value – The value to set the right trigger to. Should be in the range [0, 1].
-
inline constexpr void set_right_trigger(bool pressed)
Set the right trigger value
- Parameters:
pressed – Whether the right trigger is pressed or not
-
inline constexpr void set_brake(bool pressed)
Set the brake trigger value
- Parameters:
pressed – Whether the brake trigger is pressed or not
-
inline constexpr void set_brake(float value)
Set the brake trigger value
- Parameters:
value – The value to set the brake trigger to. Should be in the range [0, 1].
-
inline constexpr void set_accelerator(bool pressed)
Set the accelerator trigger value
- Parameters:
pressed – Whether the accelerator trigger is pressed or not
-
inline constexpr void set_accelerator(float value)
Set the accelerator trigger value
- Parameters:
value – The value to set the accelerator trigger to. Should be in the range [0, 1].
-
inline constexpr void get_brake(float &value) const
Get the brake trigger value
- Parameters:
value – The value of the brake trigger
-
inline constexpr void get_accelerator(float &value) const
Get the accelerator trigger value
- Parameters:
value – The value of the accelerator trigger
-
inline constexpr void set_battery_level(float level)
Set the battery level
- Parameters:
level – battery level, in the range [0, 100]
-
inline constexpr void set_battery_charging(bool charging)
Set the battery charging status
- Parameters:
charging – whether the battery is charging or not
-
inline constexpr void set_connection_info(uint8_t info)
Set the connection info
- Parameters:
info – connection info
-
inline constexpr void set_dpad(bool up, bool down, bool left, bool right)
Set the dpad value
- Parameters:
up – up dpad value
down – down dpad value
left – left dpad value
right – right dpad value
-
inline constexpr void set_hat_switch(espp::gamepad::Hat hat)
Set the d-pad as a hat switch value from espp::gamepad::Hat
- Parameters:
hat – The espp::gamepad::Hat value to set.
-
inline constexpr void set_hat(espp::gamepad::Hat hat)
Set the hat switch (d-pad) value
- Parameters:
hat – Hat enum / direction to set
-
template<SwitchProButtonStruct T>
inline constexpr void set_buttons(const T &buttons) Set the buttons
- Parameters:
buttons – The struct containing the button values
-
template<SwitchProButtonStruct T>
inline constexpr void get_buttons(T &t) const Get the button values
- Parameters:
t – The struct to fill with the button values
-
inline constexpr void get_dpad(bool &up, bool &down, bool &left, bool &right) const
Get the dpad value
- Parameters:
up – up dpad value
down – down dpad value
left – left dpad value
right – right dpad value
-
inline constexpr void set_button(int button_index, bool value)
Set the button value
- Parameters:
button_index – The button for which you want to set the value. Should be between 1 and 24, inclusive.
value – The true/false value you want to se the button to.
-
inline constexpr bool get_button(int button_index) const
Get the button value
- Parameters:
button_index – The button for which you want to get the value. Should be between 1 and 24, inclusive.
- Returns:
The true/false value of the button.
-
inline constexpr void set_trigger_axis(size_t index, float value)
Set the trigger axis value
Note
The value should be in the range [0, 1].
- Parameters:
index – The index of the trigger axis to set. Should be between 0 and 1, inclusive.
value – The value to set the trigger axis to.
-
inline constexpr void set_trigger_axis(size_t index, bool pressed)
Set the trigger pressed value
- Parameters:
index – The index of the trigger axis to set. Should be between 0 and 1, inclusive.
pressed – Whether the trigger is pressed or not
-
inline constexpr auto get_report() const
Get the input report as a vector of bytes
Note
The report id is not included in the returned vector.
- Returns:
The input report as a vector of bytes.
-
inline constexpr void set_data(const std::vector<uint8_t> &data)
Set the output report data from a vector of bytes
- Parameters:
data – The data to set the output report to.
Public Static Functions
-
static inline constexpr auto get_descriptor()
Get the report descriptor as a hid::rdf::descriptor
Note
This is an incomplete descriptor, you will need to add it to a collection::application descriptor to create a complete report descriptor.
- Returns:
The report descriptor as a hid::rdf::descriptor.
-
constexpr SwitchProGamepadInputReport() = default
Header File
Classes
-
template<uint8_t REPORT_ID = 1>
class XboxGamepadInputReport : public espp::GamepadInputReport<15, std::uint16_t, std::uint16_t, 0, 65535, 0, 1023, 1> HID Xbox Gamepad Input Report
This class implements a HID Xbox Gamepad Report. It supports 15 buttons, a d-pad, 4 joystick axes, 2 trigger axes as well as consumer record button.
HID-RP Xbox Gamepad Example
static constexpr uint8_t input_report_id = 1; static constexpr uint8_t battery_report_id = 4; static constexpr size_t num_buttons = 15; static constexpr int joystick_min = 0; static constexpr int joystick_max = 65535; static constexpr int trigger_min = 0; static constexpr int trigger_max = 1023; using GamepadInput = espp::GamepadInputReport<num_buttons, std::uint16_t, std::uint16_t, joystick_min, joystick_max, trigger_min, trigger_max, input_report_id>; GamepadInput gamepad_input_report; using XboxInput = espp::XboxGamepadInputReport<input_report_id>; XboxInput xbox_input_report; using BatteryReport = espp::XboxBatteryInputReport<battery_report_id>; BatteryReport battery_input_report; static constexpr uint8_t led_output_report_id = 2; static constexpr size_t num_leds = 4; using GamepadLeds = espp::GamepadLedOutputReport<num_leds, led_output_report_id>; GamepadLeds gamepad_leds_report; static constexpr uint8_t rumble_output_report_id = 3; using RumbleReport = espp::XboxRumbleOutputReport<rumble_output_report_id>; RumbleReport rumble_output_report; using namespace hid::page; using namespace hid::rdf; auto raw_descriptor = descriptor(usage_page<generic_desktop>(), usage(generic_desktop::GAMEPAD), collection::application(gamepad_input_report.get_descriptor(), rumble_output_report.get_descriptor(), battery_input_report.get_descriptor(), gamepad_leds_report.get_descriptor())); // Generate the report descriptor for the gamepad auto descriptor = std::vector<uint8_t>(raw_descriptor.begin(), raw_descriptor.end()); logger.info("Report Descriptor:"); logger.info(" Size: {}", descriptor.size()); logger.info(" Data: {::#04X}", descriptor); using SwitchProInput = espp::SwitchProGamepadInputReport<>; SwitchProInput switch_pro_input_report; logger.info("{}", switch_pro_input_report); logger.info("Switch Pro Input Report Size: {}", switch_pro_input_report.get_report().size()); logger.info("Switch Pro Input Report Data: {::#04X}", switch_pro_input_report.get_report()); auto sp_raw_descriptor = espp::switch_pro_descriptor(); auto sp_descriptor = std::vector<uint8_t>(sp_raw_descriptor.begin(), sp_raw_descriptor.end()); logger.info("Switch Report Descriptor:"); logger.info(" Size: {}", sp_descriptor.size()); std::string str = ""; for (auto &byte : sp_descriptor) { str += fmt::format("0x{:02X}, ", byte); } logger.info(" Data: [{}]", str); using PlaystationDualsenseBleSimpleInput = espp::PlaystationDualsenseBLESimpleInputReport<>; PlaystationDualsenseBleSimpleInput dualsense_simple_input_report; using PlaystationDualsenseBleComplexInput = espp::PlaystationDualsenseBLEComplexInputReport<>; PlaystationDualsenseBleComplexInput dualsense_complex_input_report; logger.info("Playstation Dualsense BLE Report Descriptor:"); auto ps_raw_descriptor = espp::playstation_dualsense_ble_descriptor(); auto ps_descriptor = std::vector<uint8_t>(ps_raw_descriptor.begin(), ps_raw_descriptor.end()); logger.info(" Size: {}", ps_descriptor.size()); str = ""; for (auto &byte : ps_descriptor) { str += fmt::format("0x{:02X}, ", byte); } logger.info(" Data: [{}]", str); GamepadInput::Hat hat = GamepadInput::Hat::UP_RIGHT; int button_index = 5; float angle = 2.0f * M_PI * button_index / num_buttons; // reset all reports gamepad_input_report.reset(); xbox_input_report.reset(); switch_pro_input_report.reset(); dualsense_simple_input_report.reset(); dualsense_complex_input_report.reset(); // print out the reports in their default states logger.info("{}", gamepad_input_report); logger.info("{}", xbox_input_report); logger.info("{}", switch_pro_input_report); logger.info("{}", dualsense_simple_input_report); logger.info("{}", dualsense_complex_input_report); // update the gamepad input report logger.info("{}", gamepad_input_report); gamepad_input_report.set_hat(hat); gamepad_input_report.set_button(button_index, true); // joystick inputs are in the range [-1, 1] float gamepad_input_report.set_right_joystick(cos(angle), sin(angle)); gamepad_input_report.set_left_joystick(sin(angle), cos(angle)); // trigger inputs are in the range [0, 1] float gamepad_input_report.set_accelerator(std::abs(sin(angle))); gamepad_input_report.set_brake(std::abs(cos(angle))); switch_pro_input_report.set_button(button_index, true); switch_pro_input_report.set_dpad(false, true, false, true); // down-right switch_pro_input_report.set_left_joystick(sin(angle), cos(angle)); switch_pro_input_report.set_right_joystick(cos(angle), sin(angle)); switch_pro_input_report.set_left_trigger((float)std::abs(cos(angle))); switch_pro_input_report.set_right_trigger((float)std::abs(sin(angle))); dualsense_simple_input_report.set_button(button_index, true); dualsense_simple_input_report.set_hat(hat); dualsense_simple_input_report.set_left_joystick(sin(angle), cos(angle)); dualsense_simple_input_report.set_right_joystick(cos(angle), sin(angle)); dualsense_simple_input_report.set_left_trigger(std::abs(cos(angle))); dualsense_simple_input_report.set_right_trigger(std::abs(sin(angle))); dualsense_complex_input_report.set_button(button_index, true); dualsense_complex_input_report.set_hat(hat); dualsense_complex_input_report.set_left_joystick(sin(angle), cos(angle)); dualsense_complex_input_report.set_right_joystick(cos(angle), sin(angle)); dualsense_complex_input_report.set_left_trigger(std::abs(cos(angle))); dualsense_complex_input_report.set_right_trigger(std::abs(sin(angle))); button_index = (button_index % num_buttons) + 1; // send an input report auto report = gamepad_input_report.get_report(); logger.info("{}", gamepad_input_report); logger.info("Gamepad Input report:"); logger.info(" Size: {}", report.size()); logger.info(" Data: {::#02X}", report); report = switch_pro_input_report.get_report(); logger.info("{}", switch_pro_input_report); logger.info("Switch Pro Input report:"); logger.info(" Size: {}", report.size()); logger.info(" Data: {::#02X}", report); report = dualsense_simple_input_report.get_report(); logger.info("{}", dualsense_simple_input_report); logger.info("Playstation Dualsense BLE Simple Input report:"); logger.info(" Size: {}", report.size()); logger.info(" Data: {::#02X}", report); report = dualsense_complex_input_report.get_report(); logger.info("{}", dualsense_complex_input_report); logger.info("Playstation Dualsense BLE Complex Input report:"); logger.info(" Size: {}", report.size()); logger.info(" Data: {::#02X}", report); // update the battery input report battery_input_report.reset(); battery_input_report.set_rechargeable(true); battery_input_report.set_charging(false); battery_input_report.set_rechargeable(true); // note: it can only show 5, 40, 70, 100 so this will be rounded to 40 battery_input_report.set_battery_level(50); // send a battery report report = battery_input_report.get_report(); logger.info("Battery report:"); logger.info(" Size: {}", report.size()); logger.info(" Data: {::#02X}", report);
Public Functions
-
template<XboxButtonStruct T>
inline constexpr void set_buttons(const T &buttons) Set the buttons
- Parameters:
buttons – The struct containing the button values
-
template<XboxButtonStruct T>
inline constexpr void get_buttons(T &t) const Get the button values
- Parameters:
t – The struct to fill with the button values
-
inline constexpr void reset()
Reset the gamepad inputs.
-
inline constexpr void get_left_joystick(float &lx, float &ly) const
Get the left joystick X and Y axis values
- Parameters:
lx – [out] left joystick x axis value, in the range [-1, 1]
ly – [out] left joystick y axis value, in the range [-1, 1]
-
inline constexpr void get_left_joystick(JOYSTICK_TYPE &lx, JOYSTICK_TYPE &ly) const
Get the left joystick X and Y axis values
- Parameters:
lx – [out] left joystick x axis value
ly – [out] left joystick y axis value
-
inline constexpr void get_right_joystick(float &rx, float &ry) const
Get the right joystick X and Y axis values
- Parameters:
rx – [out] right joystick x axis value, in the range [-1, 1]
ry – [out] right joystick y axis value, in the range [-1, 1]
-
inline constexpr void get_right_joystick(JOYSTICK_TYPE &rx, JOYSTICK_TYPE &ry) const
Get the right joystick X and Y axis values
- Parameters:
rx – [out] right joystick x axis value
ry – [out] right joystick y axis value
-
inline constexpr void set_left_joystick(float lx, float ly)
Set the left joystick X and Y axis values
- Parameters:
lx – left joystick x axis value, in the range [-1, 1]
ly – left joystick y axis value, in the range [-1, 1]
-
inline constexpr void set_right_joystick(float rx, float ry)
Set the right joystick X and Y axis values
- Parameters:
rx – right joystick x axis value, in the range [-1, 1]
ry – right joystick y axis value, in the range [-1, 1]
-
inline constexpr void get_brake(float &value) const
Get the brake trigger value
- Parameters:
value – brake trigger value, in the range [0, 1]
-
inline constexpr void get_brake(TRIGGER_TYPE &value) const
Get the brake trigger value
- Parameters:
value – brake trigger value
-
inline constexpr void get_left_trigger(float &value) const
Get the left trigger value
- Parameters:
value – left trigger value, in the range [0, 1]
-
inline constexpr void set_brake(float value)
Set the brake trigger value
- Parameters:
value – brake trigger value, in the range [0, 1]
-
inline constexpr void set_left_trigger(float value)
Set the left trigger value
- Parameters:
value – left trigger value, in the range [0, 1]
-
inline constexpr void get_accelerator(float &value) const
Get the accelerator trigger value
- Parameters:
value – accelerator trigger value, in the range [0, 1]
-
inline constexpr void get_accelerator(TRIGGER_TYPE &value) const
Get the accelerator trigger value
- Parameters:
value – accelerator trigger value
-
inline constexpr void get_right_trigger(float &value) const
Get the right trigger value
- Parameters:
value – right trigger value, in the range [0, 1]
-
inline constexpr void set_accelerator(float value)
Set the accelerator trigger value
- Parameters:
value – accelerator trigger value, in the range [0, 1]
-
inline constexpr void set_right_trigger(float value)
Set the right trigger value
- Parameters:
value – right trigger value, in the range [0, 1]
-
inline constexpr void set_hat(Hat hat)
Set the hat switch (d-pad) value
- Parameters:
hat – Hat enum / direction to set
-
inline constexpr void set_hat(bool up, bool down, bool left, bool right)
Set the hat switch (d-pad) value
- Parameters:
up – up direction
down – down direction
left – left direction
right – right direction
-
inline constexpr Hat get_hat() const
Get the hat switch (d-pad) value
- Returns:
Hat enum / direction
-
inline constexpr void get_hat(bool &up, bool &down, bool &left, bool &right) const
Get the hat switch (d-pad) value
- Parameters:
up – up direction
down – down direction
left – left direction
right – right direction
-
inline constexpr void set_button(int button_index, bool value)
Set the button value
- Parameters:
button_index – The button for which you want to set the value. Should be between 1 and BUTTON_COUNT, inclusive.
value – The true/false value you want to se the button to.
-
inline constexpr void set_joystick_axis(size_t index, JOYSTICK_TYPE value)
Set the joystick axis value
Note
The value should be in the range [joystick_min, joystick_max].
- Parameters:
index – The index of the joystick axis to set. Should be between 0 and 3, inclusive.
value – The value to set the joystick axis to.
-
inline constexpr void set_joystick_axis(size_t index, float value)
Set the joystick axis value
Note
The value should be in the range [-1, 1].
- Parameters:
index – The index of the joystick axis to set. Should be between 0 and 3, inclusive.
value – The value to set the joystick axis to.
-
inline constexpr void set_trigger_axis(size_t index, TRIGGER_TYPE value)
Set the trigger axis value
Note
The value should be in the range [trigger_min, trigger_max].
- Parameters:
index – The index of the trigger axis to set. Should be between 0 and 1, inclusive.
value – The value to set the trigger axis to.
-
inline constexpr void set_trigger_axis(size_t index, float value)
Set the trigger axis value
Note
The value should be in the range [0, 1].
- Parameters:
index – The index of the trigger axis to set. Should be between 0 and 1, inclusive.
value – The value to set the trigger axis to.
-
inline constexpr bool get_button(int button_index) const
Get the button value
- Parameters:
button_index – The button for which you want to get the value.
- Returns:
The true/false value of the button.
-
inline constexpr void set_hat_switch(Hat hat)
Set the hat switch value
- Parameters:
hat – The hat switch value to set.
-
inline constexpr void set_hat_switch(std::uint8_t value)
Set the hat switch value
Note
The value should match the values within the Hat enum.
- Parameters:
value – The hat switch value to set.
-
inline constexpr bool get_consumer_record() const
Get the consumer record button value
- Returns:
The consumer record button value.
-
inline constexpr void set_consumer_record(bool value)
Set the consumer record button value
- Parameters:
value – The true/false value you want to se the consumer record button to.
-
inline constexpr auto get_report() const
Get the input report as a vector of bytes
Note
The report id is not included in the returned vector.
- Returns:
The input report as a vector of bytes.
-
inline constexpr void set_data(const std::vector<uint8_t> &data)
Set the output report data from a vector of bytes
- Parameters:
data – The data to set the output report to.
Public Static Functions
-
static inline constexpr auto get_descriptor()
Get the report descriptor as a hid::rdf::descriptor
Note
This is an incomplete descriptor, you will need to add it to a collection::application descriptor to create a complete report descriptor.
using namespace hid::page; using namespace hid::rdf; auto gamepad_descriptor = gamepad_input_report.get_descriptor(); auto rdf_descriptor = descriptor( usage_page<generic_desktop>(), usage(generic_desktop::GAMEPAD), collection::application( gamepad_descriptor ) ); auto descriptor = std::vector<uint8_t>(rdf_descriptor.begin(), rdf_descriptor.end());
- Returns:
The report descriptor as a hid::rdf::descriptor.
Public Static Attributes
-
static constexpr std::size_t BTN_A_INDEX = {1}
The index of the A button.
-
static constexpr std::size_t BTN_B_INDEX = {2}
The index of the B button.
-
static constexpr std::size_t BTN_X_INDEX = {4}
The index of the X button.
-
static constexpr std::size_t BTN_Y_INDEX = {5}
The index of the Y button.
-
static constexpr std::size_t BTN_L1_INDEX = {7}
The index of the L1 button.
-
static constexpr std::size_t BTN_R1_INDEX = {8}
The index of the R1 button.
-
static constexpr std::size_t BTN_L2_INDEX = {9}
The index of the L2 button.
-
static constexpr std::size_t BTN_R2_INDEX = {10}
The index of the R2 button.
-
static constexpr std::size_t BTN_L3_INDEX = {14}
The index of the L3 button.
-
static constexpr std::size_t BTN_R3_INDEX = {15}
The index of the R3 button.
-
static constexpr std::size_t BTN_HOME_INDEX = {13}
The index of the Home button.
-
static constexpr std::size_t BTN_MENU_INDEX = {12}
The index of the Menu button.
-
static constexpr std::size_t BTN_OPTIONS_INDEX = {11}
The index of the Options button.
-
template<XboxButtonStruct T>
-
template<uint8_t REPORT_ID = 3>
class XboxRumbleOutputReport : public hid::report::base<hid::report::type::OUTPUT, 3> HID Xbox Rumble Output Report
This class implements a HID Rumble Output Report providing rumble effect on the left and right motors, as well as serializing the output report and getting the report descriptor.
Public Functions
-
constexpr XboxRumbleOutputReport() = default
Construct a new Xbox Rumble Output Report object.
-
inline constexpr void reset()
Reset the rumble effect.
-
inline constexpr auto get_enabled()
Get the enabled mask for the rumble motors
- Returns:
The enabled mask for the rumble motors
-
inline constexpr void set_enabled(std::uint8_t new_enabled)
Set the enabled mask for the rumble motors
- Parameters:
new_enabled – The enabled mask for the rumble motors
-
inline constexpr auto get_magnitude(std::size_t motor)
Get the magnitude of the rumble effect for the specified motor
- Parameters:
motor – The motor for which you want to get the magnitude.
- Returns:
The magnitude of the rumble effect for the specified motor.
-
inline constexpr void set_magnitude(std::size_t motor, std::uint8_t value)
Set the magnitude of the rumble effect for the specified motor
Note
The value should be in the range [0, 100].
- Parameters:
motor – The motor for which you want to set the magnitude.
value – The magnitude of the rumble effect for the specified motor.
-
inline constexpr void set_magnitude(std::size_t motor, float value)
Set the magnitude of the rumble effect for the specified motor
Note
The value should be in the range [0, 1].
- Parameters:
motor – The motor for which you want to set the magnitude.
value – The magnitude of the rumble effect for the specified motor.
-
inline constexpr auto get_duration()
Get the duration of the rumble effect
- Returns:
The duration of the rumble effect
-
inline constexpr void set_duration(std::uint8_t value)
Set the duration of the rumble effect
Note
The value should be in the range [0, 255].
- Parameters:
value – The duration of the rumble effect.
-
inline constexpr auto get_start_delay()
Get the start delay of the rumble effect
- Returns:
The start delay of the rumble effect
-
inline constexpr void set_start_delay(std::uint8_t value)
Set the start delay of the rumble effect
Note
The value should be in the range [0, 255].
- Parameters:
value – The start delay of the rumble effect.
-
inline constexpr auto get_loop_count()
Get the loop count of the rumble effect
- Returns:
The loop count of the rumble effect
-
inline constexpr void set_loop_count(std::uint8_t value)
Set the loop count of the rumble effect
Note
The value should be in the range [0, 255].
- Parameters:
value – The loop count of the rumble effect.
-
inline constexpr auto get_report() const
Get the output report as a vector of bytes
Note
The report id is not included in the returned vector.
- Returns:
The output report as a vector of bytes.
-
inline constexpr void set_data(const std::vector<uint8_t> &data)
Set the output report data from a vector of bytes
- Parameters:
data – The data to set the output report to.
Public Static Functions
-
static inline constexpr auto get_descriptor()
Get the report descriptor as a hid::rdf::descriptor
Note
This is an incomplete descriptor, you will need to add it to a collection::application descriptor to create a complete report descriptor.
- Returns:
The report descriptor as a hid::rdf::descriptor.
-
constexpr XboxRumbleOutputReport() = default
-
template<uint8_t REPORT_ID = 4>
class XboxBatteryInputReport : public hid::report::base<hid::report::type::INPUT, 4> HID Xbox Battery Input Report This class implements a copy of the Xbox Battery input report. It is a single byte input which contains information about the type of the battery, its battery level, as well as a few other things.
HID-RP Xbox Battery Input Example
static constexpr uint8_t input_report_id = 1; static constexpr uint8_t battery_report_id = 4; static constexpr size_t num_buttons = 15; static constexpr int joystick_min = 0; static constexpr int joystick_max = 65535; static constexpr int trigger_min = 0; static constexpr int trigger_max = 1023; using GamepadInput = espp::GamepadInputReport<num_buttons, std::uint16_t, std::uint16_t, joystick_min, joystick_max, trigger_min, trigger_max, input_report_id>; GamepadInput gamepad_input_report; using XboxInput = espp::XboxGamepadInputReport<input_report_id>; XboxInput xbox_input_report; using BatteryReport = espp::XboxBatteryInputReport<battery_report_id>; BatteryReport battery_input_report; static constexpr uint8_t led_output_report_id = 2; static constexpr size_t num_leds = 4; using GamepadLeds = espp::GamepadLedOutputReport<num_leds, led_output_report_id>; GamepadLeds gamepad_leds_report; static constexpr uint8_t rumble_output_report_id = 3; using RumbleReport = espp::XboxRumbleOutputReport<rumble_output_report_id>; RumbleReport rumble_output_report; using namespace hid::page; using namespace hid::rdf; auto raw_descriptor = descriptor(usage_page<generic_desktop>(), usage(generic_desktop::GAMEPAD), collection::application(gamepad_input_report.get_descriptor(), rumble_output_report.get_descriptor(), battery_input_report.get_descriptor(), gamepad_leds_report.get_descriptor())); // Generate the report descriptor for the gamepad auto descriptor = std::vector<uint8_t>(raw_descriptor.begin(), raw_descriptor.end()); logger.info("Report Descriptor:"); logger.info(" Size: {}", descriptor.size()); logger.info(" Data: {::#04X}", descriptor); using SwitchProInput = espp::SwitchProGamepadInputReport<>; SwitchProInput switch_pro_input_report; logger.info("{}", switch_pro_input_report); logger.info("Switch Pro Input Report Size: {}", switch_pro_input_report.get_report().size()); logger.info("Switch Pro Input Report Data: {::#04X}", switch_pro_input_report.get_report()); auto sp_raw_descriptor = espp::switch_pro_descriptor(); auto sp_descriptor = std::vector<uint8_t>(sp_raw_descriptor.begin(), sp_raw_descriptor.end()); logger.info("Switch Report Descriptor:"); logger.info(" Size: {}", sp_descriptor.size()); std::string str = ""; for (auto &byte : sp_descriptor) { str += fmt::format("0x{:02X}, ", byte); } logger.info(" Data: [{}]", str); using PlaystationDualsenseBleSimpleInput = espp::PlaystationDualsenseBLESimpleInputReport<>; PlaystationDualsenseBleSimpleInput dualsense_simple_input_report; using PlaystationDualsenseBleComplexInput = espp::PlaystationDualsenseBLEComplexInputReport<>; PlaystationDualsenseBleComplexInput dualsense_complex_input_report; logger.info("Playstation Dualsense BLE Report Descriptor:"); auto ps_raw_descriptor = espp::playstation_dualsense_ble_descriptor(); auto ps_descriptor = std::vector<uint8_t>(ps_raw_descriptor.begin(), ps_raw_descriptor.end()); logger.info(" Size: {}", ps_descriptor.size()); str = ""; for (auto &byte : ps_descriptor) { str += fmt::format("0x{:02X}, ", byte); } logger.info(" Data: [{}]", str); GamepadInput::Hat hat = GamepadInput::Hat::UP_RIGHT; int button_index = 5; float angle = 2.0f * M_PI * button_index / num_buttons; // reset all reports gamepad_input_report.reset(); xbox_input_report.reset(); switch_pro_input_report.reset(); dualsense_simple_input_report.reset(); dualsense_complex_input_report.reset(); // print out the reports in their default states logger.info("{}", gamepad_input_report); logger.info("{}", xbox_input_report); logger.info("{}", switch_pro_input_report); logger.info("{}", dualsense_simple_input_report); logger.info("{}", dualsense_complex_input_report); // update the gamepad input report logger.info("{}", gamepad_input_report); gamepad_input_report.set_hat(hat); gamepad_input_report.set_button(button_index, true); // joystick inputs are in the range [-1, 1] float gamepad_input_report.set_right_joystick(cos(angle), sin(angle)); gamepad_input_report.set_left_joystick(sin(angle), cos(angle)); // trigger inputs are in the range [0, 1] float gamepad_input_report.set_accelerator(std::abs(sin(angle))); gamepad_input_report.set_brake(std::abs(cos(angle))); switch_pro_input_report.set_button(button_index, true); switch_pro_input_report.set_dpad(false, true, false, true); // down-right switch_pro_input_report.set_left_joystick(sin(angle), cos(angle)); switch_pro_input_report.set_right_joystick(cos(angle), sin(angle)); switch_pro_input_report.set_left_trigger((float)std::abs(cos(angle))); switch_pro_input_report.set_right_trigger((float)std::abs(sin(angle))); dualsense_simple_input_report.set_button(button_index, true); dualsense_simple_input_report.set_hat(hat); dualsense_simple_input_report.set_left_joystick(sin(angle), cos(angle)); dualsense_simple_input_report.set_right_joystick(cos(angle), sin(angle)); dualsense_simple_input_report.set_left_trigger(std::abs(cos(angle))); dualsense_simple_input_report.set_right_trigger(std::abs(sin(angle))); dualsense_complex_input_report.set_button(button_index, true); dualsense_complex_input_report.set_hat(hat); dualsense_complex_input_report.set_left_joystick(sin(angle), cos(angle)); dualsense_complex_input_report.set_right_joystick(cos(angle), sin(angle)); dualsense_complex_input_report.set_left_trigger(std::abs(cos(angle))); dualsense_complex_input_report.set_right_trigger(std::abs(sin(angle))); button_index = (button_index % num_buttons) + 1; // send an input report auto report = gamepad_input_report.get_report(); logger.info("{}", gamepad_input_report); logger.info("Gamepad Input report:"); logger.info(" Size: {}", report.size()); logger.info(" Data: {::#02X}", report); report = switch_pro_input_report.get_report(); logger.info("{}", switch_pro_input_report); logger.info("Switch Pro Input report:"); logger.info(" Size: {}", report.size()); logger.info(" Data: {::#02X}", report); report = dualsense_simple_input_report.get_report(); logger.info("{}", dualsense_simple_input_report); logger.info("Playstation Dualsense BLE Simple Input report:"); logger.info(" Size: {}", report.size()); logger.info(" Data: {::#02X}", report); report = dualsense_complex_input_report.get_report(); logger.info("{}", dualsense_complex_input_report); logger.info("Playstation Dualsense BLE Complex Input report:"); logger.info(" Size: {}", report.size()); logger.info(" Data: {::#02X}", report); // update the battery input report battery_input_report.reset(); battery_input_report.set_rechargeable(true); battery_input_report.set_charging(false); battery_input_report.set_rechargeable(true); // note: it can only show 5, 40, 70, 100 so this will be rounded to 40 battery_input_report.set_battery_level(50); // send a battery report report = battery_input_report.get_report(); logger.info("Battery report:"); logger.info(" Size: {}", report.size()); logger.info(" Data: {::#02X}", report);
Public Types
Public Functions
-
inline constexpr void reset()
Reset the battery status.
-
inline constexpr void set_rechargeable(bool rechargeable)
Set whether the battery is rechargeable
- Parameters:
rechargeable – True if the battery is rechargeable, false otherwise.
-
inline constexpr void set_battery_level(int level)
Set the battery level
- Parameters:
level – The battery level as a percentage, from 0 to 100.
-
inline constexpr void set_cable_connected(bool connected)
Set whether the battery is connected to a cable
- Parameters:
connected – True if the battery is connected to a cable, false otherwise.
-
inline constexpr void set_charging(bool charging)
Set whether the battery is charging
- Parameters:
charging – True if the battery is charging, false otherwise.
-
inline constexpr void set_error(Error error)
Set the error state of the battery
- Parameters:
error – The error state of the battery.
-
inline constexpr auto get_report() const
Get the input report as a vector of bytes
Note
The report id is not included in the returned vector.
- Returns:
The input report as a vector of bytes.
-
inline constexpr auto set_data(const std::vector<uint8_t> &data)
Set the input report data from a vector of bytes
- Parameters:
data – The data to set the input report to.
Public Static Functions
-
static inline constexpr auto get_descriptor()
Get the report descriptor as a hid::rdf::descriptor
Note
This is an incomplete descriptor, you will need to add it to a collection::application descriptor to create a complete report descriptor.
- Returns:
The report descriptor as a hid::rdf::descriptor.
-
inline constexpr void reset()