From 7985be57aba821828054109936465be0cf84d8f1 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 30 Nov 2014 15:35:20 -0600 Subject: [PATCH] Translate the analog stick values of controllers with "square" analog stick planes (DS3, DS4, and others) to the circular plane that XInput programs expect --- .../binding/input/ControllerHandler.java | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/app/src/main/java/com/limelight/binding/input/ControllerHandler.java b/app/src/main/java/com/limelight/binding/input/ControllerHandler.java index c8a8052c..6d9a8396 100644 --- a/app/src/main/java/com/limelight/binding/input/ControllerHandler.java +++ b/app/src/main/java/com/limelight/binding/input/ControllerHandler.java @@ -421,12 +421,32 @@ public class ControllerHandler { } } + private void handleAnalogStickPlaneMapping(ControllerMapping mapping, Vector2d stickVector) { + if (!mapping.squareAnalogStick) { + // If the stick vector's magnitude exceeds 1.0 (1.1 to be safe), that means + // that the stick isn't behaving like a circular analog stick but like a square + if (stickVector.getMagnitude() > 1.1f) { + mapping.squareAnalogStick = true; + LimeLog.info("Switching to square analog stick mode"); + } + } + + if (mapping.squareAnalogStick) { + double xSquare = stickVector.getX(); + double ySquare = stickVector.getY(); + stickVector.setX((float)(xSquare * Math.sqrt(1.0 - 0.5*Math.abs(ySquare)))); + stickVector.setY((float)(ySquare * Math.sqrt(1.0 - 0.5*Math.abs(xSquare)))); + } + } + private void handleAxisSet(ControllerMapping mapping, float lsX, float lsY, float rsX, float rsY, float lt, float rt, float hatX, float hatY) { if (mapping.leftStickXAxis != -1 && mapping.leftStickYAxis != -1) { Vector2d leftStickVector = handleDeadZone(lsX, lsY, mapping.leftStickDeadzoneRadius); + handleAnalogStickPlaneMapping(mapping, leftStickVector); + leftStickX = (short) (leftStickVector.getX() * 0x7FFE); leftStickY = (short) (-leftStickVector.getY() * 0x7FFE); } @@ -434,6 +454,8 @@ public class ControllerHandler { if (mapping.rightStickXAxis != -1 && mapping.rightStickYAxis != -1) { Vector2d rightStickVector = handleDeadZone(rsX, rsY, mapping.rightStickDeadzoneRadius); + handleAnalogStickPlaneMapping(mapping, rightStickVector); + rightStickX = (short) (rightStickVector.getX() * 0x7FFE); rightStickY = (short) (-rightStickVector.getY() * 0x7FFE); } @@ -748,5 +770,9 @@ public class ControllerHandler { public boolean backIsStart; public boolean isRemote; public boolean hasJoystickAxes; + + // XInput uses a rounded analog stick where (1.0, 1.0) -> (2^(1/2), 2^(1/2)) + // Some controllers have square sticks which we will map onto the circular plane + public boolean squareAnalogStick; } }