Skip to content

Commit a2f592e

Browse files
authored
Merge pull request #15 from dmadison/joy-dpad
Joystick D-Pad
2 parents b81e317 + abedff5 commit a2f592e

File tree

2 files changed

+47
-7
lines changed

2 files changed

+47
-7
lines changed

src/XInput.cpp

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -236,10 +236,12 @@ void XInputController::setDpad(XInputControl pad, boolean state) {
236236
setButton(pad, state);
237237
}
238238

239-
void XInputController::setDpad(boolean up, boolean down, boolean left, boolean right) {
239+
void XInputController::setDpad(boolean up, boolean down, boolean left, boolean right, boolean useSOCD) {
240240
// Simultaneous Opposite Cardinal Directions (SOCD) Cleaner
241-
if (up && down) { down = false; } // Up + Down = Up
242-
if (left && right) { left = false; right = false; } // Left + Right = Neutral
241+
if (useSOCD) {
242+
if (up && down) { down = false; } // Up + Down = Up
243+
if (left && right) { left = false; right = false; } // Left + Right = Neutral
244+
}
243245

244246
const boolean autoSendTemp = autoSendOption; // Save autosend state
245247
autoSendOption = false; // Disable temporarily
@@ -257,7 +259,7 @@ void XInputController::setTrigger(XInputControl trigger, int32_t val) {
257259
const XInputMap_Trigger * triggerData = getTriggerFromEnum(trigger);
258260
if (triggerData == nullptr) return; // Not a trigger
259261

260-
val = rescaleInput(val, *getRangeFromEnum(trigger), triggerData->range);
262+
val = rescaleInput(val, *getRangeFromEnum(trigger), XInputMap_Trigger::range);
261263
if (getTrigger(trigger) == val) return; // Trigger hasn't changed
262264

263265
tx[triggerData->index] = val;
@@ -269,8 +271,43 @@ void XInputController::setJoystick(XInputControl joy, int32_t x, int32_t y) {
269271
const XInputMap_Joystick * joyData = getJoyFromEnum(joy);
270272
if (joyData == nullptr) return; // Not a joystick
271273

272-
x = rescaleInput(x, *getRangeFromEnum(joy), joyData->range);
273-
y = rescaleInput(y, *getRangeFromEnum(joy), joyData->range);
274+
x = rescaleInput(x, *getRangeFromEnum(joy), XInputMap_Joystick::range);
275+
y = rescaleInput(y, *getRangeFromEnum(joy), XInputMap_Joystick::range);
276+
277+
setJoystickDirect(joy, x, y);
278+
}
279+
280+
void XInputController::setJoystick(XInputControl joy, boolean up, boolean down, boolean left, boolean right, boolean useSOCD) {
281+
const XInputMap_Joystick * joyData = getJoyFromEnum(joy);
282+
if (joyData == nullptr) return; // Not a joystick
283+
284+
const Range & range = XInputMap_Joystick::range;
285+
286+
int16_t x = 0;
287+
int16_t y = 0;
288+
289+
// Simultaneous Opposite Cardinal Directions (SOCD) Cleaner
290+
if (useSOCD) {
291+
if (up && down) { down = false; } // Up + Down = Up
292+
if (left && right) { left = false; right = false; } // Left + Right = Neutral
293+
}
294+
295+
// Analog axis means directions are mutually exclusive. Only change the
296+
// output from '0' if the per-axis inputs are different, in order to
297+
// avoid the '-1' result from adding the int16 extremes
298+
if (left != right) {
299+
x = (right * range.max) - (left * range.min);
300+
}
301+
if (up != down) {
302+
y = (up * range.max) - (down * range.min);
303+
}
304+
305+
setJoystickDirect(joy, x, y);
306+
}
307+
308+
void XInputController::setJoystickDirect(XInputControl joy, int16_t x, int16_t y) {
309+
const XInputMap_Joystick * joyData = getJoyFromEnum(joy);
310+
if (joyData == nullptr) return; // Not a joystick
274311

275312
if (getJoystickX(joy) == x && getJoystickY(joy) == y) return; // Joy hasn't changed
276313

src/XInput.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,12 @@ class XInputController {
8686
void setButton(uint8_t button, boolean state);
8787

8888
void setDpad(XInputControl pad, boolean state);
89-
void setDpad(boolean up, boolean down, boolean left, boolean right);
89+
void setDpad(boolean up, boolean down, boolean left, boolean right, boolean useSOCD = true);
9090

9191
void setTrigger(XInputControl trigger, int32_t val);
9292

9393
void setJoystick(XInputControl joy, int32_t x, int32_t y);
94+
void setJoystick(XInputControl joy, boolean up, boolean down, boolean left, boolean right, boolean useSOCD = true);
9495

9596
void releaseAll();
9697

@@ -140,6 +141,8 @@ class XInputController {
140141
uint8_t tx[20]; // USB transmit data
141142
boolean newData; // Flag for tx data changed
142143
boolean autoSendOption; // Flag for automatically sending data
144+
145+
void setJoystickDirect(XInputControl joy, int16_t x, int16_t y);
143146

144147
void inline autosend() {
145148
if (autoSendOption) { send(); }

0 commit comments

Comments
 (0)