Skip to content

Commit c6b661f

Browse files
authored
Merge pull request #3 from dmadison/development
Board Type Check & Send Data When Changed
2 parents 6f35ba6 + 205e021 commit c6b661f

3 files changed

Lines changed: 94 additions & 15 deletions

File tree

keywords.txt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,19 @@ setJoystick KEYWORD2
3131

3232
releaseAll KEYWORD2
3333

34+
# Read Control Data
35+
getButton KEYWORD2
36+
getDpad KEYWORD2
37+
getTrigger KEYWORD2
38+
getJoystickX KEYWORD2
39+
getJoystickY KEYWORD2
40+
3441
# Receive data
3542
getPlayer KEYWORD2
3643
getRumble KEYWORD2
3744
getRumbleLeft KEYWORD2
3845
getRumbleRight KEYWORD2
3946

40-
getLEDPatternID KEYWORD2
4147
getLEDPatternID KEYWORD2
4248

4349
# USB I/O

src/XInput.cpp

Lines changed: 78 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,24 @@
2525
*/
2626

2727
#include "XInput.h"
28+
29+
// Teensy 3.1-3.2: __MK20DX256__
30+
// Teensy LC: __MKL26Z64__
31+
// Teensy 3.5: __MK64FX512__
32+
// Teensy 3.6: __MK66FX1M0__
33+
34+
#if defined(TEENSYDUINO) && \
35+
(defined(__MK20DX256__) || defined(__MKL26Z64__) || \
36+
defined(__MK64FX512__) || defined(__MK66FX1M0__))
37+
38+
#ifndef USB_XINPUT
39+
#error "USB type is not set to XInput in boards menu!"
40+
#endif
41+
42+
#else
43+
#error "Not a supported board! Must use Teensy 3.1/3.2, LC, 3.5, or 3.6"
44+
#endif
45+
2846
#include <limits>
2947

3048
// --------------------------------------------------------
@@ -55,7 +73,7 @@ static const XInputMap_Button Map_ButtonR3(2, 7);
5573

5674
static const XInputMap_Button Map_ButtonLB(3, 0);
5775
static const XInputMap_Button Map_ButtonRB(3, 1);
58-
static const XInputMap_Button Map_ButtonLogo(3, 3);
76+
static const XInputMap_Button Map_ButtonLogo(3, 2);
5977
static const XInputMap_Button Map_ButtonA(3, 4);
6078
static const XInputMap_Button Map_ButtonB(3, 5);
6179
static const XInputMap_Button Map_ButtonX(3, 6);
@@ -180,8 +198,11 @@ void XInputGamepad::release(XInputControl button) {
180198
void XInputGamepad::setButton(XInputControl button, boolean state) {
181199
const XInputMap_Button * buttonData = getButtonFromEnum(button);
182200
if (buttonData != nullptr) {
201+
if (getButton(button) == state) return; // Button hasn't changed
202+
183203
if (state) { tx[buttonData->index] |= buttonData->mask; } // Press
184204
else { tx[buttonData->index] &= ~(buttonData->mask); } // Release
205+
newData = true;
185206
}
186207
else {
187208
Range * triggerRange = getRangeFromEnum(button);
@@ -208,8 +229,12 @@ void XInputGamepad::setDpad(boolean up, boolean down, boolean left, boolean righ
208229
void XInputGamepad::setTrigger(XInputControl trigger, int32_t val) {
209230
const XInputMap_Trigger * triggerData = getTriggerFromEnum(trigger);
210231
if (triggerData == nullptr) return; // Not a trigger
232+
211233
val = rescaleInput(val, *getRangeFromEnum(trigger), triggerData->range);
234+
if (getTrigger(trigger) == val) return; // Trigger hasn't changed
235+
212236
tx[triggerData->index] = val;
237+
newData = true;
213238
}
214239

215240
void XInputGamepad::setJoystick(XInputControl joy, int32_t x, int32_t y) {
@@ -219,16 +244,49 @@ void XInputGamepad::setJoystick(XInputControl joy, int32_t x, int32_t y) {
219244
x = rescaleInput(x, *getRangeFromEnum(joy), joyData->range);
220245
y = rescaleInput(y, *getRangeFromEnum(joy), joyData->range);
221246

247+
if (getJoystickX(joy) == x && getJoystickY(joy) == y) return; // Joy hasn't changed
248+
222249
tx[joyData->x_low] = lowByte(x);
223250
tx[joyData->x_high] = highByte(x);
224251

225252
tx[joyData->y_low] = lowByte(y);
226253
tx[joyData->y_high] = highByte(y);
254+
255+
newData = true;
227256
}
228257

229258
void XInputGamepad::releaseAll() {
230259
const uint8_t offset = 2; // Skip message type and packet size
231260
memset(tx + offset, 0x00, sizeof(tx) - offset); // Clear TX array
261+
newData = true; // Data changed and is unsent
262+
}
263+
264+
boolean XInputGamepad::getButton(XInputControl button) const {
265+
const XInputMap_Button * buttonData = getButtonFromEnum(button);
266+
if (buttonData == nullptr) return 0; // Not a button
267+
return tx[buttonData->index] & buttonData->mask;
268+
}
269+
270+
boolean XInputGamepad::getDpad(XInputControl dpad) const {
271+
return getButton(dpad);
272+
}
273+
274+
uint8_t XInputGamepad::getTrigger(XInputControl trigger) const {
275+
const XInputMap_Trigger * triggerData = getTriggerFromEnum(trigger);
276+
if (triggerData == nullptr) return 0; // Not a trigger
277+
return tx[triggerData->index];
278+
}
279+
280+
int16_t XInputGamepad::getJoystickX(XInputControl joy) const {
281+
const XInputMap_Joystick * joyData = getJoyFromEnum(joy);
282+
if (joyData == nullptr) return 0; // Not a joystick
283+
return (tx[joyData->x_high] << 8) | tx[joyData->x_low];
284+
}
285+
286+
int16_t XInputGamepad::getJoystickY(XInputControl joy) const {
287+
const XInputMap_Joystick * joyData = getJoyFromEnum(joy);
288+
if (joyData == nullptr) return 0; // Not a joystick
289+
return (tx[joyData->y_high] << 8) | tx[joyData->y_low];
232290
}
233291

234292
uint8_t XInputGamepad::getPlayer() const {
@@ -257,7 +315,9 @@ uint8_t XInputGamepad::getLEDPatternID() const {
257315

258316
//Send an update packet to the PC
259317
void XInputGamepad::send() {
318+
if (!newData) return; // TX data hasn't changed
260319
XInputUSB.send(tx, USB_Timeout);
320+
newData = false;
261321
}
262322

263323
void XInputGamepad::receive() {
@@ -284,23 +344,28 @@ void XInputGamepad::parseLED(uint8_t leds) {
284344
if (leds > 0x0D) return; // Not a known pattern
285345

286346
ledPattern = (XInputLEDPattern) leds; // Save pattern
287-
if (ledPattern == XInputLEDPattern::Off || ledPattern == XInputLEDPattern::Blinking) {
347+
switch (ledPattern) {
348+
case(XInputLEDPattern::Off):
349+
case(XInputLEDPattern::Blinking):
288350
player = 0; // Not connected
289-
}
290-
else if (ledPattern == XInputLEDPattern::On1 || ledPattern == XInputLEDPattern::Flash1) {
351+
break;
352+
case(XInputLEDPattern::On1):
353+
case(XInputLEDPattern::Flash1):
291354
player = 1;
292-
}
293-
else if (ledPattern == XInputLEDPattern::On2 || ledPattern == XInputLEDPattern::Flash2) {
355+
break;
356+
case(XInputLEDPattern::On2):
357+
case(XInputLEDPattern::Flash2):
294358
player = 2;
295-
}
296-
else if (ledPattern == XInputLEDPattern::On3 || ledPattern == XInputLEDPattern::Flash3) {
359+
break;
360+
case(XInputLEDPattern::On3):
361+
case(XInputLEDPattern::Flash3):
297362
player = 3;
298-
}
299-
else if (ledPattern == XInputLEDPattern::On4 || ledPattern == XInputLEDPattern::Flash4) {
363+
break;
364+
case(XInputLEDPattern::On4):
365+
case(XInputLEDPattern::Flash4):
300366
player = 4;
301-
}
302-
else {
303-
return; // Pattern doesn't affect player #
367+
break;
368+
default: return; // Pattern doesn't affect player #
304369
}
305370
}
306371

src/XInput.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ class XInputGamepad {
7373
public:
7474
XInputGamepad();
7575

76-
// Control surfaces
76+
// Set Control Surfaces
7777
void press(XInputControl button);
7878
void release(XInputControl button);
7979
void setButton(XInputControl button, boolean state);
@@ -87,6 +87,13 @@ class XInputGamepad {
8787

8888
void releaseAll();
8989

90+
// Read Control Surfaces
91+
boolean getButton(XInputControl button) const;
92+
boolean getDpad(XInputControl dpad) const;
93+
uint8_t getTrigger(XInputControl trigger) const;
94+
int16_t getJoystickX(XInputControl joy) const;
95+
int16_t getJoystickY(XInputControl joy) const;
96+
9097
// Received Data
9198
uint8_t getPlayer() const; // Player # assigned to the controller (0 is unassigned)
9299
uint16_t getRumble() const; // Rumble motors. MSB is large weight, LSB is small
@@ -113,6 +120,7 @@ class XInputGamepad {
113120
private:
114121
static const uint32_t USB_Timeout = 12840; // Packet timeout, in milliseconds
115122
uint8_t tx[20]; // USB transmit data
123+
boolean newData; // Flag for tx data changed
116124

117125
uint8_t player; // Gamepad player #, buffered
118126
uint8_t rumble[2]; // Rumble motor data in, buffered

0 commit comments

Comments
 (0)