From 428d37afd440bab45cc689925142f9a42183e5e1 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sat, 19 Jul 2014 03:50:37 -0700 Subject: [PATCH] Improve input device detection --- src/com/limelight/Game.java | 54 ++++++++++++------ .../binding/input/ControllerHandler.java | 57 ++++++++++++++++++- 2 files changed, 93 insertions(+), 18 deletions(-) diff --git a/src/com/limelight/Game.java b/src/com/limelight/Game.java index 5c7e7cf4..10b00d96 100644 --- a/src/com/limelight/Game.java +++ b/src/com/limelight/Game.java @@ -270,10 +270,27 @@ public class Game extends Activity implements SurfaceHolder.Callback, OnGenericM return modifier; } + private static boolean isSourceFlagSet(int sourcesFlags, int flag) { + return (sourcesFlags & flag) == flag; + } + @Override public boolean onKeyDown(int keyCode, KeyEvent event) { - if (event.getDevice() != null && - (event.getDevice().getKeyboardType() == InputDevice.KEYBOARD_TYPE_ALPHABETIC)) { + InputDevice dev = event.getDevice(); + 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()); if (translated == 0) { return super.onKeyDown(keyCode, event); @@ -282,12 +299,7 @@ public class Game extends Activity implements SurfaceHolder.Callback, OnGenericM keybTranslator.sendKeyDown(translated, getModifierState(event)); } - else { - if (!controllerHandler.handleButtonDown(keyCode, event)) { - return super.onKeyDown(keyCode, event); - } - } - + return true; } @@ -302,22 +314,30 @@ public class Game extends Activity implements SurfaceHolder.Callback, OnGenericM h.postDelayed(hideSystemUi, 2000); } } - - if (event.getDevice() != null && - (event.getDevice().getKeyboardType() == InputDevice.KEYBOARD_TYPE_ALPHABETIC)) { + + InputDevice dev = event.getDevice(); + 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()); if (translated == 0) { return super.onKeyUp(keyCode, event); } - + keybTranslator.sendKeyUp(translated, getModifierState(event)); } - else { - if (!controllerHandler.handleButtonUp(keyCode, event)) { - return super.onKeyUp(keyCode, event); - } - } return true; } diff --git a/src/com/limelight/binding/input/ControllerHandler.java b/src/com/limelight/binding/input/ControllerHandler.java index 789fe7be..3a85af60 100644 --- a/src/com/limelight/binding/input/ControllerHandler.java +++ b/src/com/limelight/binding/input/ControllerHandler.java @@ -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; } @@ -177,7 +181,48 @@ public class ControllerHandler { 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) { switch (keyCode) { case KeyEvent.KEYCODE_BUTTON_Y: @@ -317,6 +362,10 @@ public class ControllerHandler { 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 // This allows "instant" button presses (like OUYA's virtual menu button) to work. This // path should not be triggered during normal usage. @@ -440,6 +489,10 @@ public class ControllerHandler { return true; } + if (!isEventExpected(mapping, keyCode)) { + return false; + } + switch (keyCode) { case KeyEvent.KEYCODE_BUTTON_MODE: inputMap |= ControllerPacket.SPECIAL_BUTTON_FLAG; @@ -549,5 +602,7 @@ public class ControllerHandler { public float hatYDeadzone; public boolean isDualShock4; + public boolean isDpad; + public boolean isGamepad; } }