xbox.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <USB.h>
4 #include <Data/BitSet.h>
5 
6 // tag, type, bits, compare mask
7 #define XBOX360_INPUT_MAP(XX) \
8  XX(dpad_up, bool, 1, 0x01) \
9  XX(dpad_down, bool, 1, 0x01) \
10  XX(dpad_left, bool, 1, 0x01) \
11  XX(dpad_right, bool, 1, 0x01) \
12  XX(btn_start, bool, 1, 0x01) \
13  XX(btn_back, bool, 1, 0x01) \
14  XX(btn_stick_left, bool, 1, 0x01) \
15  XX(btn_stick_right, bool, 1, 0x01) \
16  XX(btn_trig_left, bool, 1, 0x01) \
17  XX(btn_trig_right, bool, 1, 0x01) \
18  XX(btn_mode, bool, 1, 0x01) \
19  XX(btn_unk1, bool, 1, 0x01) \
20  XX(btn_a, bool, 1, 0x01) \
21  XX(btn_b, bool, 1, 0x01) \
22  XX(btn_x, bool, 1, 0x01) \
23  XX(btn_y, bool, 1, 0x01) \
24  XX(trig_left, uint8_t, 8, 0xff) \
25  XX(trig_right, uint8_t, 8, 0xff) \
26  XX(stick_left_x, int16_t, 16, 0xff00) \
27  XX(stick_left_y, int16_t, 16, 0xff00) \
28  XX(stick_right_x, int16_t, 16, 0xff00) \
29  XX(stick_right_y, int16_t, 16, 0xff00)
30 
31 namespace USB::VENDOR
32 {
33 class Xbox : public HostDevice
34 {
35 public:
36  enum class Input {
37 #define XX(tag, ...) tag,
39 #undef XX
40  MAX
41  };
42 
44  using InputChange = Delegate<void(InputMask changed)>;
45 
46  struct InputData {
47 #define XX(tag, type, size, ...) type tag : size;
49 #undef XX
50 
51  int16_t operator[](Input input) const
52  {
53  switch(input) {
54 #define XX(tag, ...) \
55  case Input::tag: \
56  return tag;
58 #undef XX
59  default:
60  return 0;
61  }
62  }
63  };
64 
65  enum class LedCommand {
66  off, // 0: off
67  all_blink_once, // 1: all blink, then previous setting
68  top_left_blink_on, // 2: 1/top-left blink, then on
69  top_right_blink_on, // 3: 2/top-right blink, then on
70  bottom_left_blink_on, // 4: 3/bottom-left blink, then on
71  bottom_right_blink_on, // 5: 4/bottom-right blink, then on
72  top_left_on, // 6: 1/top-left on
73  top_right_on, // 7: 2/top-right on
74  bottom_left_on, // 8: 3/bottom-left on
75  bottom_right_on, // 9: 4/bottom-right on
76  rotate, // 10: rotate
77  blink, // 11: blink, based on previous setting
78  slow_blink, // 12: slow blink, based on previous setting
79  rotate2, // 13: rotate with two lights
80  slow_blink_persist, // 14: persistent slow all blink
81  blink_once, // 15: blink once, then previous setting
82  };
83 
84  bool begin(const Instance& inst, const Config& cfg);
85  bool read();
86  bool setled(LedCommand cmd);
87  bool rumble(uint8_t strong, uint8_t weak);
88 
89  void onChange(InputChange callback)
90  {
91  inputChangeCallback = callback;
92  }
93 
94  const InputData& inputs() const
95  {
96  return inputData;
97  }
98 
99  static const char* getInputName(Xbox::Input input);
100 
101  bool setConfig(uint8_t itf_num) override;
102  bool transferComplete(const Transfer& txfr) override;
103 
104 private:
105  bool parseInterface(DescriptorList list);
106  bool control(tusb_request_recipient_t recipient, uint16_t value, uint16_t length);
107  void control_cb(tuh_xfer_t& xfer);
108  void process_packet();
109  bool output(const void* data, uint8_t length);
110 
111  static void static_control_cb(tuh_xfer_t* xfer)
112  {
113  auto self = reinterpret_cast<Xbox*>(xfer->user_data);
114  self->control_cb(*xfer);
115  }
116 
117  static constexpr size_t bufSize{64};
118  InputData inputData{};
119  InputChange inputChangeCallback;
120  uint8_t controlBuffer[20]{};
121  uint8_t dataBuffer[bufSize];
122  uint8_t outputBuffer[8];
123  uint8_t ep_in{0};
124  uint8_t ep_out{0};
125  uint8_t state{0};
126 };
127 
128 } // namespace USB::VENDOR
#define XX(name, comment)
Definition: DirectoryTemplate.h:47
Manage a set of bit values using enumeration.
Definition: BitSet.h:45
Instance inst
Definition: HostInterface.h:84
Base class to use for custom devices.
Definition: VENDOR/HostDevice.h:32
Definition: xbox.h:34
static const char * getInputName(Xbox::Input input)
bool setled(LedCommand cmd)
bool begin(const Instance &inst, const Config &cfg)
const InputData & inputs() const
Definition: xbox.h:94
Delegate< void(InputMask changed)> InputChange
Definition: xbox.h:44
bool setConfig(uint8_t itf_num) override
Set active configuration.
bool transferComplete(const Transfer &txfr) override
Called when a non-control USB transfer has completed.
bool rumble(uint8_t strong, uint8_t weak)
Input
Definition: xbox.h:36
LedCommand
Definition: xbox.h:65
void onChange(InputChange callback)
Definition: xbox.h:89
Definition: Libraries/USB/src/USB/VENDOR/Device.h:26
Buffer containing list of descriptors.
Definition: Descriptors.h:78
Identifies a TinyUSB host interface.
Definition: HostInterface.h:35
Device configuration received during mount procedure.
Definition: VENDOR/HostDevice.h:37
Structure passed to 'transferComplete' method.
Definition: VENDOR/HostDevice.h:46
Definition: xbox.h:46
int16_t operator[](Input input) const
Definition: xbox.h:51
#define XBOX360_INPUT_MAP(XX)
Definition: xbox.h:7