Skip to content

Commit

Permalink
feat(hid-rp): Add gamepad set_data and formatters (#373)
Browse files Browse the repository at this point in the history
* Add formatter for easy printing of gamepad data
* Add `set_data` function for setting the raw bytes of the report (e.g. from a received binary input report) for parsing it

Helps when you want to parse an input gamepad report of this type and print the values
  • Loading branch information
finger563 authored Feb 17, 2025
1 parent 61d6452 commit bace7f4
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 0 deletions.
1 change: 1 addition & 0 deletions components/hid-rp/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
idf_component_register(
INCLUDE_DIRS "include" "../../external/hid-rp/hid-rp"
REQUIRES "format"
)
41 changes: 41 additions & 0 deletions components/hid-rp/include/hid-rp-gamepad-formatters.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#pragma once

#include "format.hpp"

template <size_t BUTTON_COUNT, typename JOYSTICK_TYPE, typename TRIGGER_TYPE, JOYSTICK_TYPE JOYSTICK_MIN,
JOYSTICK_TYPE JOYSTICK_MAX, TRIGGER_TYPE TRIGGER_MIN, TRIGGER_TYPE TRIGGER_MAX, uint8_t REPORT_ID>
struct fmt::formatter<espp::GamepadInputReport<BUTTON_COUNT, JOYSTICK_TYPE, TRIGGER_TYPE, JOYSTICK_MIN, JOYSTICK_MAX,
TRIGGER_MIN, TRIGGER_MAX, REPORT_ID>> {
template <typename ParseContext> constexpr auto parse(ParseContext &ctx) const {
return ctx.begin();
}

template <typename FormatContext>
auto format(const espp::GamepadInputReport<BUTTON_COUNT, JOYSTICK_TYPE, TRIGGER_TYPE, JOYSTICK_MIN,
JOYSTICK_MAX, TRIGGER_MIN, TRIGGER_MAX, REPORT_ID> &report, FormatContext &ctx) const {
auto out = ctx.out();
fmt::format_to(out, "GamepadInputReport<{}> {{", BUTTON_COUNT);
fmt::format_to(out, "joystick_axes: [");
for (size_t i = 0; i < 4; i++) {
fmt::format_to(out, "{}", report.joystick_axes[i]);
if (i < 3) {
fmt::format_to(out, ", ");
}
}
fmt::format_to(out, "], trigger_axes: [");
for (size_t i = 0; i < 2; i++) {
fmt::format_to(out, "{}", report.trigger_axes[i]);
if (i < 1) {
fmt::format_to(out, ", ");
}
}
fmt::format_to(out, "], hat_switch: {}, buttons: [", report.hat_switch);
std::bitset<BUTTON_COUNT> buttons;
for (size_t i = 1; i <= BUTTON_COUNT; i++) {
buttons.set(i - 1, report.buttons.test(hid::page::button(i)));
}
fmt::format_to(out, "{}", buttons);
fmt::format_to(out, "], consumer_record: {}", (bool)report.consumer_record);
return fmt::format_to(out, "}}");
}
};
15 changes: 15 additions & 0 deletions components/hid-rp/include/hid-rp-gamepad.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,15 @@ class GamepadInputReport : public hid::report::base<hid::report::type::INPUT, RE
return std::vector<uint8_t>(report_data, report_data + report_size);
}

/// Set the output report data from a vector of bytes
/// \param data The data to set the output report to.
constexpr void set_data(const std::vector<uint8_t> &data) {
// the first two bytes are the id and the selector, which we don't want
size_t offset = 2;
// copy the data into our data array
std::copy(data.begin(), data.end(), this->data() + offset);
}

/// Get the report descriptor as a hid::rdf::descriptor
/// \return The report descriptor as a hid::rdf::descriptor.
/// \note This is an incomplete descriptor, you will need to add it to a
Expand Down Expand Up @@ -277,6 +286,10 @@ class GamepadInputReport : public hid::report::base<hid::report::type::INPUT, RE
);
// clang-format on
}

friend fmt::formatter<GamepadInputReport<BUTTON_COUNT, JOYSTICK_TYPE, TRIGGER_TYPE, JOYSTICK_MIN, JOYSTICK_MAX,
TRIGGER_MIN, TRIGGER_MAX, REPORT_ID>>;

};

/// HID Gamepad Output Report
Expand Down Expand Up @@ -696,3 +709,5 @@ class GamepadLedOutputReport : public hid::report::base<hid::report::type::OUTPU
};

} // namespace espp

#include "hid-rp-gamepad-formatters.hpp"

0 comments on commit bace7f4

Please sign in to comment.