@@ -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
0 commit comments