Skip to content

Commit 96edbbb

Browse files
authored
feat(hid-rp): Flesh out gamepads to fill out their interfaces (#381)
* Add some concepts for structs to make it easier to get / set buttons with custom / user-defined structs/classes without having to subclass * Add more getters / setters for each Switch and Xbox * Add specializations to the Xbox class to explicitly match buttons for the xbox controller Makes using the controllers (and converting between controller report types) easier / more painless Build and run `hid-rp/example` Build and run within [esp-usb-ble-hid](https://github.com/finger563/esp-usb-ble-hid)
1 parent a223d36 commit 96edbbb

File tree

4 files changed

+1033
-660
lines changed

4 files changed

+1033
-660
lines changed

components/hid-rp/include/hid-rp-gamepad.hpp

Lines changed: 121 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include <algorithm>
44

5+
#include "format.hpp"
56
#include "hid-rp.hpp"
67

78
namespace espp {
@@ -78,6 +79,38 @@ class GamepadInputReport : public hid::report::base<hid::report::type::INPUT, RE
7879
consumer_record = 0;
7980
}
8081

82+
/// Get the left joystick X and Y axis values
83+
/// @param[out] lx left joystick x axis value, in the range [-1, 1]
84+
/// @param[out] ly left joystick y axis value, in the range [-1, 1]
85+
constexpr void get_left_joystick(float &lx, float &ly) const {
86+
lx = (joystick_axes[0] - joystick_center) / static_cast<float>(joystick_range);
87+
ly = (joystick_axes[1] - joystick_center) / static_cast<float>(joystick_range);
88+
}
89+
90+
/// Get the left joystick X and Y axis values
91+
/// @param[out] lx left joystick x axis value
92+
/// @param[out] ly left joystick y axis value
93+
constexpr void get_left_joystick(JOYSTICK_TYPE &lx, JOYSTICK_TYPE &ly) const {
94+
lx = joystick_axes[0];
95+
ly = joystick_axes[1];
96+
}
97+
98+
/// Get the right joystick X and Y axis values
99+
/// @param[out] rx right joystick x axis value, in the range [-1, 1]
100+
/// @param[out] ry right joystick y axis value, in the range [-1, 1]
101+
constexpr void get_right_joystick(float &rx, float &ry) const {
102+
rx = (joystick_axes[2] - joystick_center) / static_cast<float>(joystick_range);
103+
ry = (joystick_axes[3] - joystick_center) / static_cast<float>(joystick_range);
104+
}
105+
106+
/// Get the right joystick X and Y axis values
107+
/// @param[out] rx right joystick x axis value
108+
/// @param[out] ry right joystick y axis value
109+
constexpr void get_right_joystick(JOYSTICK_TYPE &rx, JOYSTICK_TYPE &ry) const {
110+
rx = joystick_axes[2];
111+
ry = joystick_axes[3];
112+
}
113+
81114
/// Set the left joystick X and Y axis values
82115
/// @param lx left joystick x axis value, in the range [-1, 1]
83116
/// @param ly left joystick y axis value, in the range [-1, 1]
@@ -92,15 +125,87 @@ class GamepadInputReport : public hid::report::base<hid::report::type::INPUT, RE
92125
set_joystick_axis(2, rx);
93126
set_joystick_axis(3, ry);
94127
}
128+
129+
/// Get the brake trigger value
130+
/// @param value brake trigger value, in the range [0, 1]
131+
constexpr void get_brake(float &value) const {
132+
value = (trigger_axes[0] - trigger_center) / static_cast<float>(trigger_range);
133+
}
134+
135+
/// Get the brake trigger value
136+
/// @return brake trigger value
137+
constexpr void get_brake(TRIGGER_TYPE &value) const { value = trigger_axes[0]; }
138+
95139
/// Set the brake trigger value
96140
/// @param value brake trigger value, in the range [0, 1]
97141
constexpr void set_brake(float value) { set_trigger_axis(0, value); }
142+
98143
/// Set the accelerator trigger value
99144
/// @param value accelerator trigger value, in the range [0, 1]
100145
constexpr void set_accelerator(float value) { set_trigger_axis(1, value); }
146+
147+
/// Get the accelerator trigger value
148+
/// @param value accelerator trigger value, in the range [0, 1]
149+
constexpr void get_accelerator(float &value) const {
150+
value = (trigger_axes[1] - trigger_center) / static_cast<float>(trigger_range);
151+
}
152+
153+
/// Get the accelerator trigger value
154+
/// @return accelerator trigger value
155+
constexpr void get_accelerator(TRIGGER_TYPE &value) const { value = trigger_axes[1]; }
156+
101157
/// Set the hat switch (d-pad) value
102158
/// @param hat Hat enum / direction to set
103159
constexpr void set_hat(Hat hat) { set_hat_switch(uint8_t(hat)); }
160+
161+
/// Set the hat switch (d-pad) value
162+
/// @param up up direction
163+
/// @param down down direction
164+
/// @param left left direction
165+
/// @param right right direction
166+
constexpr void set_hat(bool up, bool down, bool left, bool right) {
167+
if (up) {
168+
if (left) {
169+
set_hat(Hat::UP_LEFT);
170+
} else if (right) {
171+
set_hat(Hat::UP_RIGHT);
172+
} else {
173+
set_hat(Hat::UP);
174+
}
175+
} else if (down) {
176+
if (left) {
177+
set_hat(Hat::DOWN_LEFT);
178+
} else if (right) {
179+
set_hat(Hat::DOWN_RIGHT);
180+
} else {
181+
set_hat(Hat::DOWN);
182+
}
183+
} else if (left) {
184+
set_hat(Hat::LEFT);
185+
} else if (right) {
186+
set_hat(Hat::RIGHT);
187+
} else {
188+
set_hat(Hat::CENTERED);
189+
}
190+
}
191+
192+
/// Get the hat switch (d-pad) value
193+
/// @return Hat enum / direction
194+
constexpr Hat get_hat() const { return static_cast<Hat>(hat_switch); }
195+
196+
/// Get the hat switch (d-pad) value
197+
/// @param up up direction
198+
/// @param down down direction
199+
/// @param left left direction
200+
/// @param right right direction
201+
constexpr void get_hat(bool &up, bool &down, bool &left, bool &right) const {
202+
auto hat = get_hat();
203+
up = hat == Hat::UP || hat == Hat::UP_RIGHT || hat == Hat::UP_LEFT;
204+
down = hat == Hat::DOWN || hat == Hat::DOWN_RIGHT || hat == Hat::DOWN_LEFT;
205+
left = hat == Hat::LEFT || hat == Hat::UP_LEFT || hat == Hat::DOWN_LEFT;
206+
right = hat == Hat::RIGHT || hat == Hat::UP_RIGHT || hat == Hat::DOWN_RIGHT;
207+
}
208+
104209
/// Set the button value
105210
/// \param button_index The button for which you want to set the value.
106211
/// Should be between 1 and BUTTON_COUNT, inclusive.
@@ -152,6 +257,17 @@ class GamepadInputReport : public hid::report::base<hid::report::type::INPUT, RE
152257
trigger_max);
153258
}
154259
}
260+
261+
/// Get the button value
262+
/// \param button_index The button for which you want to get the value.
263+
/// \return The true/false value of the button.
264+
constexpr bool get_button(int button_index) const {
265+
if (button_index < 1 || button_index > BUTTON_COUNT) {
266+
return false;
267+
}
268+
return buttons.test(hid::page::button(button_index));
269+
}
270+
155271
/// Set the hat switch value
156272
/// \param hat The hat switch value to set.
157273
constexpr void set_hat_switch(Hat hat) { hat_switch = static_cast<std::uint8_t>(hat); }
@@ -160,14 +276,18 @@ class GamepadInputReport : public hid::report::base<hid::report::type::INPUT, RE
160276
/// \note The value should match the values within the Hat enum.
161277
constexpr void set_hat_switch(std::uint8_t value) { hat_switch = (value & 0xf); }
162278

279+
/// Get the consumer record button value
280+
/// \return The consumer record button value.
281+
constexpr bool get_consumer_record() const { return consumer_record; }
282+
163283
/// Set the consumer record button value
164284
/// \param value The true/false value you want to se the consumer record button to.
165285
constexpr void set_consumer_record(bool value) { consumer_record = value; }
166286

167287
/// Get the input report as a vector of bytes
168288
/// \return The input report as a vector of bytes.
169289
/// \note The report id is not included in the returned vector.
170-
constexpr auto get_report() {
290+
constexpr auto get_report() const {
171291
// the first two bytes are the id and the selector, which we don't want
172292
size_t offset = 2;
173293
auto report_data = this->data() + offset;

components/hid-rp/include/hid-rp-switch-pro-formatters.hpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,19 @@
22

33
#include "format.hpp"
44

5-
template<uint8_t REPORT_ID>
6-
struct fmt::formatter<espp::SwitchProGamepadInputReport<REPORT_ID>> {
5+
template <uint8_t REPORT_ID> struct fmt::formatter<espp::SwitchProGamepadInputReport<REPORT_ID>> {
76
template <typename ParseContext> constexpr auto parse(ParseContext &ctx) const {
87
return ctx.begin();
98
}
109

1110
template <typename FormatContext>
12-
auto
13-
format(const espp::SwitchProGamepadInputReport<REPORT_ID> &report,
14-
FormatContext &ctx) const {
11+
auto format(const espp::SwitchProGamepadInputReport<REPORT_ID> &report,
12+
FormatContext &ctx) const {
1513
auto out = ctx.out();
1614
fmt::format_to(out, "SwitchProGamepadInputReport {{");
1715
fmt::format_to(out, "analog: {::#04x}", report.analog);
18-
uint32_t buttons = report.raw_report[4] << 16 | report.raw_report[3] << 8 | report.raw_report[2];
16+
uint32_t buttons =
17+
report.raw_report[4] << 16 | report.raw_report[3] << 8 | report.raw_report[2];
1918
fmt::format_to(out, "], buttons: [{:#026b}]", buttons);
2019
return fmt::format_to(out, "}}");
2120
}

0 commit comments

Comments
 (0)