Improve input device detection

This commit is contained in:
Cameron Gutman 2014-07-19 03:50:37 -07:00
parent f5ec665115
commit 428d37afd4
2 changed files with 93 additions and 18 deletions

View File

@ -270,10 +270,27 @@ public class Game extends Activity implements SurfaceHolder.Callback, OnGenericM
return modifier; return modifier;
} }
private static boolean isSourceFlagSet(int sourcesFlags, int flag) {
return (sourcesFlags & flag) == flag;
}
@Override @Override
public boolean onKeyDown(int keyCode, KeyEvent event) { public boolean onKeyDown(int keyCode, KeyEvent event) {
if (event.getDevice() != null && InputDevice dev = event.getDevice();
(event.getDevice().getKeyboardType() == InputDevice.KEYBOARD_TYPE_ALPHABETIC)) { if (dev == null) {
return super.onKeyDown(keyCode, event);
}
int source = dev.getSources();
boolean handled = false;
if (isSourceFlagSet(source, InputDevice.SOURCE_DPAD) ||
isSourceFlagSet(source, InputDevice.SOURCE_GAMEPAD) ||
isSourceFlagSet(source, InputDevice.SOURCE_JOYSTICK))
{
handled = controllerHandler.handleButtonDown(keyCode, event);
}
if (!handled) {
short translated = keybTranslator.translate(event.getKeyCode()); short translated = keybTranslator.translate(event.getKeyCode());
if (translated == 0) { if (translated == 0) {
return super.onKeyDown(keyCode, event); return super.onKeyDown(keyCode, event);
@ -282,12 +299,7 @@ public class Game extends Activity implements SurfaceHolder.Callback, OnGenericM
keybTranslator.sendKeyDown(translated, keybTranslator.sendKeyDown(translated,
getModifierState(event)); getModifierState(event));
} }
else {
if (!controllerHandler.handleButtonDown(keyCode, event)) {
return super.onKeyDown(keyCode, event);
}
}
return true; return true;
} }
@ -302,22 +314,30 @@ public class Game extends Activity implements SurfaceHolder.Callback, OnGenericM
h.postDelayed(hideSystemUi, 2000); h.postDelayed(hideSystemUi, 2000);
} }
} }
if (event.getDevice() != null && InputDevice dev = event.getDevice();
(event.getDevice().getKeyboardType() == InputDevice.KEYBOARD_TYPE_ALPHABETIC)) { if (dev == null) {
return super.onKeyUp(keyCode, event);
}
int source = dev.getSources();
boolean handled = false;
if (isSourceFlagSet(source, InputDevice.SOURCE_DPAD) ||
isSourceFlagSet(source, InputDevice.SOURCE_GAMEPAD) ||
isSourceFlagSet(source, InputDevice.SOURCE_JOYSTICK))
{
handled = controllerHandler.handleButtonUp(keyCode, event);
}
if (!handled) {
short translated = keybTranslator.translate(event.getKeyCode()); short translated = keybTranslator.translate(event.getKeyCode());
if (translated == 0) { if (translated == 0) {
return super.onKeyUp(keyCode, event); return super.onKeyUp(keyCode, event);
} }
keybTranslator.sendKeyUp(translated, keybTranslator.sendKeyUp(translated,
getModifierState(event)); getModifierState(event));
} }
else {
if (!controllerHandler.handleButtonUp(keyCode, event)) {
return super.onKeyUp(keyCode, event);
}
}
return true; return true;
} }

View File

@ -148,6 +148,10 @@ public class ControllerHandler {
} }
} }
mapping.isDpad = (dev.getSources() & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD;
mapping.isGamepad = (dev.getSources() & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD ||
(dev.getSources() & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK;
return mapping; return mapping;
} }
@ -177,7 +181,48 @@ public class ControllerHandler {
leftStickX, leftStickY, rightStickX, rightStickY); leftStickX, leftStickY, rightStickX, rightStickY);
} }
private int handleRemapping(ControllerMapping mapping, int keyCode) { private static boolean isEventExpected(ControllerMapping mapping, int keyCode) {
if (mapping.isDpad) {
switch (keyCode) {
case KeyEvent.KEYCODE_DPAD_LEFT:
case KeyEvent.KEYCODE_DPAD_RIGHT:
case KeyEvent.KEYCODE_DPAD_CENTER:
case KeyEvent.KEYCODE_DPAD_UP:
case KeyEvent.KEYCODE_DPAD_DOWN:
return true;
}
}
if (mapping.isGamepad) {
switch (keyCode) {
case KeyEvent.KEYCODE_BUTTON_MODE:
case KeyEvent.KEYCODE_BUTTON_START:
case KeyEvent.KEYCODE_MENU:
case KeyEvent.KEYCODE_BACK:
case KeyEvent.KEYCODE_BUTTON_SELECT:
case KeyEvent.KEYCODE_DPAD_LEFT:
case KeyEvent.KEYCODE_DPAD_RIGHT:
case KeyEvent.KEYCODE_DPAD_UP:
case KeyEvent.KEYCODE_DPAD_DOWN:
case KeyEvent.KEYCODE_BUTTON_B:
case KeyEvent.KEYCODE_DPAD_CENTER:
case KeyEvent.KEYCODE_BUTTON_A:
case KeyEvent.KEYCODE_BUTTON_X:
case KeyEvent.KEYCODE_BUTTON_Y:
case KeyEvent.KEYCODE_BUTTON_L1:
case KeyEvent.KEYCODE_BUTTON_R1:
case KeyEvent.KEYCODE_BUTTON_THUMBL:
case KeyEvent.KEYCODE_BUTTON_THUMBR:
case KeyEvent.KEYCODE_BUTTON_L2:
case KeyEvent.KEYCODE_BUTTON_R2:
return true;
}
}
return false;
}
private static int handleRemapping(ControllerMapping mapping, int keyCode) {
if (mapping.isDualShock4) { if (mapping.isDualShock4) {
switch (keyCode) { switch (keyCode) {
case KeyEvent.KEYCODE_BUTTON_Y: case KeyEvent.KEYCODE_BUTTON_Y:
@ -317,6 +362,10 @@ public class ControllerHandler {
return true; return true;
} }
if (!isEventExpected(mapping, keyCode)) {
return false;
}
// If the button hasn't been down long enough, sleep for a bit before sending the up event // If the button hasn't been down long enough, sleep for a bit before sending the up event
// This allows "instant" button presses (like OUYA's virtual menu button) to work. This // This allows "instant" button presses (like OUYA's virtual menu button) to work. This
// path should not be triggered during normal usage. // path should not be triggered during normal usage.
@ -440,6 +489,10 @@ public class ControllerHandler {
return true; return true;
} }
if (!isEventExpected(mapping, keyCode)) {
return false;
}
switch (keyCode) { switch (keyCode) {
case KeyEvent.KEYCODE_BUTTON_MODE: case KeyEvent.KEYCODE_BUTTON_MODE:
inputMap |= ControllerPacket.SPECIAL_BUTTON_FLAG; inputMap |= ControllerPacket.SPECIAL_BUTTON_FLAG;
@ -549,5 +602,7 @@ public class ControllerHandler {
public float hatYDeadzone; public float hatYDeadzone;
public boolean isDualShock4; public boolean isDualShock4;
public boolean isDpad;
public boolean isGamepad;
} }
} }