Merge branch 'gamepad' into master

Improvements in gamepad code for deadzone, triggers and (un)signed
This commit is contained in:
Iwan Timmer
2014-03-11 21:37:26 +01:00
4 changed files with 44 additions and 13 deletions

View File

@@ -11,14 +11,18 @@ public class EvdevAbsolute {
public final static int UP = 1, DOWN = -1, NONE = 0; public final static int UP = 1, DOWN = -1, NONE = 0;
private static final int SHORT_MAX_UNSIGNED = 0xFFFF;
private static final int BYTE_MAX_UNSIGNED = 0xFF;
private final static int ABS_OFFSET = 0x40; private final static int ABS_OFFSET = 0x40;
private final static int READ_ONLY = 2; private final static int READ_ONLY = 2;
private final static char EVDEV_TYPE = 'E'; private final static char EVDEV_TYPE = 'E';
private int max;
private int avg; private int avg;
private int range; private int range;
private boolean reverse; private boolean reverse;
private boolean signed;
public EvdevAbsolute(String filename, int axis, boolean reverse) { public EvdevAbsolute(String filename, int axis, boolean reverse) {
ByteBuffer buffer = ByteBuffer.allocate(6*4); ByteBuffer buffer = ByteBuffer.allocate(6*4);
@@ -29,10 +33,10 @@ public class EvdevAbsolute {
buffer.getInt(); //Skip current value buffer.getInt(); //Skip current value
int min = buffer.getInt(); int min = buffer.getInt();
int max = buffer.getInt(); max = buffer.getInt();
avg = (min+max)/2; avg = (min+max)/2;
range = max-avg; range = max-avg;
signed = min < 0;
this.reverse = reverse; this.reverse = reverse;
} }
@@ -46,7 +50,10 @@ public class EvdevAbsolute {
* @return input value as short * @return input value as short
*/ */
public short getShort(int value) { public short getShort(int value) {
return (short) ((value-avg) * (reverse?-range:range) / Short.MAX_VALUE); if (signed)
return (short) ((reverse ? -1 - value : value) * (Short.MAX_VALUE + 1) / (max + 1));
else
return (short) ((reverse ? max - value : value) * SHORT_MAX_UNSIGNED / max);
} }
/** /**
@@ -55,7 +62,11 @@ public class EvdevAbsolute {
* @return input value as byte * @return input value as byte
*/ */
public byte getByte(int value) { public byte getByte(int value) {
return (byte) ((value-avg) * (reverse?-range:range) / Byte.MAX_VALUE); if (signed) {
return (byte) ((reverse ? -1 - value : value) * (Byte.MAX_VALUE + 1) / (max + 1));
} else {
return (byte) ((reverse ? max - value : value) * BYTE_MAX_UNSIGNED / max);
}
} }
/** /**

View File

@@ -150,6 +150,8 @@ public class EvdevConstants {
public static final short ABS_THROTTLE = 0x06; public static final short ABS_THROTTLE = 0x06;
public static final short ABS_RUDDER = 0x07; public static final short ABS_RUDDER = 0x07;
public static final short BTN_THROTTLE = 311;
public static final short BTN_RUDDER = 312;
public static final short BTN_SOUTH = 0x130; public static final short BTN_SOUTH = 0x130;
public static final short BTN_EAST = 0x131; public static final short BTN_EAST = 0x131;

View File

@@ -135,11 +135,17 @@ public class EvdevHandler implements Runnable {
conn.sendMouseButtonDown(mouseButton); conn.sendMouseButtonDown(mouseButton);
else if (value==EvdevConstants.KEY_RELEASED) else if (value==EvdevConstants.KEY_RELEASED)
conn.sendMouseButtonUp(mouseButton); conn.sendMouseButtonUp(mouseButton);
} else if (gamepadButton>0) { } else {
if (value==EvdevConstants.KEY_PRESSED) { if (gamepadButton != 0) {
buttonFlags |= gamepadButton; if (value==EvdevConstants.KEY_PRESSED) {
} else if (value==EvdevConstants.KEY_RELEASED){ buttonFlags |= gamepadButton;
buttonFlags &= ~gamepadButton; } else if (value==EvdevConstants.KEY_RELEASED){
buttonFlags &= ~gamepadButton;
}
} else if (code==mapping.btn_throttle) {
leftTrigger = (byte) (value==EvdevConstants.KEY_PRESSED ? -1 : 0);
} else if (code==mapping.btn_rudder) {
rightTrigger = (byte) (value==EvdevConstants.KEY_PRESSED ? -1 : 0);
} }
conn.sendControllerInput(buttonFlags, leftTrigger, rightTrigger, leftStickX, leftStickY, rightStickX, rightStickY); conn.sendControllerInput(buttonFlags, leftTrigger, rightTrigger, leftStickX, leftStickY, rightStickX, rightStickY);
} }
@@ -151,13 +157,13 @@ public class EvdevHandler implements Runnable {
conn.sendMouseMove((short) 0, (short) value); conn.sendMouseMove((short) 0, (short) value);
} else if (type==EvdevConstants.EV_ABS) { } else if (type==EvdevConstants.EV_ABS) {
if (code==mapping.abs_x) if (code==mapping.abs_x)
leftStickX = absLX.getShort(value); leftStickX = accountForDeadzone(absLX.getShort(value));
else if (code==mapping.abs_y) else if (code==mapping.abs_y)
leftStickY = absLY.getShort(value); leftStickY = accountForDeadzone(absLY.getShort(value));
else if (code==mapping.abs_rx) else if (code==mapping.abs_rx)
rightStickX = absRX.getShort(value); rightStickX = accountForDeadzone(absRX.getShort(value));
else if (code==mapping.abs_ry) else if (code==mapping.abs_ry)
rightStickY = absRY.getShort(value); rightStickY = accountForDeadzone(absRY.getShort(value));
else if (code==mapping.abs_throttle) else if (code==mapping.abs_throttle)
leftTrigger = absLT.getByte(value); leftTrigger = absLT.getByte(value);
else if (code==mapping.abs_rudder) else if (code==mapping.abs_rudder)
@@ -192,6 +198,14 @@ public class EvdevHandler implements Runnable {
} }
} }
private short accountForDeadzone(short value) {
if (Math.abs(value) > mapping.abs_deadzone) {
return value;
} else {
return 0;
}
}
@Override @Override
public void run() { public void run() {
try { try {

View File

@@ -18,11 +18,15 @@ public class GamepadMapping {
public short abs_rx = EvdevConstants.ABS_RX; public short abs_rx = EvdevConstants.ABS_RX;
public short abs_ry = EvdevConstants.ABS_RY; public short abs_ry = EvdevConstants.ABS_RY;
public short abs_deadzone = 0;
public short abs_dpad_y = -1; public short abs_dpad_y = -1;
public short abs_dpad_x = -1; public short abs_dpad_x = -1;
public short abs_throttle = EvdevConstants.ABS_THROTTLE; public short abs_throttle = EvdevConstants.ABS_THROTTLE;
public short abs_rudder = EvdevConstants.ABS_RUDDER; public short abs_rudder = EvdevConstants.ABS_RUDDER;
public short btn_throttle = EvdevConstants.BTN_THROTTLE;
public short btn_rudder = EvdevConstants.BTN_RUDDER;
public boolean reverse_x, reverse_y; public boolean reverse_x, reverse_y;
public boolean reverse_rx, reverse_ry; public boolean reverse_rx, reverse_ry;