Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(255)

Unified Diff: device/gamepad/android/java/src/org/chromium/device/gamepad/GamepadMappings.java

Issue 2071223002: Gamepad: Improve gamepad mapping code and unknown gamepad heuristics (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add missing switch default case Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: device/gamepad/android/java/src/org/chromium/device/gamepad/GamepadMappings.java
diff --git a/device/gamepad/android/java/src/org/chromium/device/gamepad/GamepadMappings.java b/device/gamepad/android/java/src/org/chromium/device/gamepad/GamepadMappings.java
index ee031a20fe05e475a0ac6394a1a643ef678c6977..1f067ec0921279cc80436432c7a38c7cf4101588 100644
--- a/device/gamepad/android/java/src/org/chromium/device/gamepad/GamepadMappings.java
+++ b/device/gamepad/android/java/src/org/chromium/device/gamepad/GamepadMappings.java
@@ -14,7 +14,7 @@ import org.chromium.base.annotations.JNINamespace;
* Class to manage mapping information related to each supported gamepad controller device.
*/
@JNINamespace("content")
-class GamepadMappings {
+abstract class GamepadMappings {
@VisibleForTesting
static final String NVIDIA_SHIELD_DEVICE_NAME_PREFIX = "NVIDIA Corporation NVIDIA Controller";
@VisibleForTesting
@@ -26,29 +26,37 @@ class GamepadMappings {
@VisibleForTesting
static final String AMAZON_FIRE_DEVICE_NAME = "Amazon Fire Game Controller";
- public static boolean mapToStandardGamepad(float[] mappedAxes, float[] mappedButtons,
- float[] rawAxes, float[] rawButtons, String deviceName) {
- if (deviceName.startsWith(NVIDIA_SHIELD_DEVICE_NAME_PREFIX)) {
- mapShieldGamepad(mappedButtons, rawButtons, mappedAxes, rawAxes);
- return true;
- } else if (deviceName.equals(MICROSOFT_XBOX_PAD_DEVICE_NAME)) {
- mapXBox360Gamepad(mappedButtons, rawButtons, mappedAxes, rawAxes);
- return true;
+ public static GamepadMappings getMappings(String deviceName, int[] axes) {
+ if (deviceName.startsWith(NVIDIA_SHIELD_DEVICE_NAME_PREFIX)
+ || deviceName.equals(MICROSOFT_XBOX_PAD_DEVICE_NAME)) {
+ return new XboxCompatibleGamepadMappings();
} else if (deviceName.equals(PS3_SIXAXIS_DEVICE_NAME)) {
- mapPS3SixAxisGamepad(mappedButtons, rawButtons, mappedAxes, rawAxes);
- return true;
+ return new PS3SixAxisGamepadMappings();
} else if (deviceName.equals(SAMSUNG_EI_GP20_DEVICE_NAME)) {
- mapSamsungEIGP20Gamepad(mappedButtons, rawButtons, mappedAxes, rawAxes);
- return true;
+ return new SamsungEIGP20GamepadMappings();
} else if (deviceName.equals(AMAZON_FIRE_DEVICE_NAME)) {
- mapAmazonFireGamepad(mappedButtons, rawButtons, mappedAxes, rawAxes);
- return true;
+ return new AmazonFireGamepadMappings();
}
- mapUnknownGamepad(mappedButtons, rawButtons, mappedAxes, rawAxes);
- return false;
+ return new UnknownGamepadMappings(axes);
}
+ /**
+ * Method that specifies whether the mappings are standard or not.
+ * It should be overridden in subclasses that don't provide standard
+ * mappings.
+ */
+ public boolean isStandard() {
+ return true;
+ }
+
+ /**
+ * Method implemented by subclasses to perform mapping from raw axes and buttons
+ * to canonical axes and buttons.
+ */
+ public abstract void mapToStandardGamepad(float[] mappedAxes, float[] mappedButtons,
+ float[] rawAxes, float[] rawButtons);
+
private static void mapCommonXYABButtons(float[] mappedButtons, float[] rawButtons) {
float a = rawButtons[KeyEvent.KEYCODE_BUTTON_A];
float b = rawButtons[KeyEvent.KEYCODE_BUTTON_B];
@@ -76,7 +84,14 @@ class GamepadMappings {
mappedButtons[CanonicalButtonIndex.RIGHT_THUMBSTICK] = thumbR;
}
- private static void mapCommonTriggerButtons(float[] mappedButtons, float[] rawButtons) {
+ /**
+ * Method for mapping the L1/R1 buttons to lower shoulder buttons, rather than
+ * upper shoulder as the user would normally expect. Please think twice before
+ * using this, as it can easily confuse the user. It is only really useful if
+ * the controller completely lacks a second set of shoulder buttons.
+ */
+ private static void mapUpperTriggerButtonsToBottomShoulder(float[] mappedButtons,
+ float[] rawButtons) {
float l1 = rawButtons[KeyEvent.KEYCODE_BUTTON_L1];
float r1 = rawButtons[KeyEvent.KEYCODE_BUTTON_R1];
mappedButtons[CanonicalButtonIndex.LEFT_TRIGGER] = l1;
@@ -116,13 +131,6 @@ class GamepadMappings {
mappedAxes[CanonicalAxisIndex.RIGHT_STICK_Y] = rawAxes[MotionEvent.AXIS_RZ];
}
- private static void mapTriggerAxexToShoulderButtons(float[] mappedButtons, float[] rawAxes) {
- float lTrigger = rawAxes[MotionEvent.AXIS_LTRIGGER];
- float rTrigger = rawAxes[MotionEvent.AXIS_RTRIGGER];
- mappedButtons[CanonicalButtonIndex.LEFT_SHOULDER] = lTrigger;
- mappedButtons[CanonicalButtonIndex.RIGHT_SHOULDER] = rTrigger;
- }
-
private static void mapPedalAxesToBottomShoulder(float[] mappedButtons, float[] rawAxes) {
float lTrigger = rawAxes[MotionEvent.AXIS_BRAKE];
float rTrigger = rawAxes[MotionEvent.AXIS_GAS];
@@ -137,6 +145,14 @@ class GamepadMappings {
mappedButtons[CanonicalButtonIndex.RIGHT_TRIGGER] = rTrigger;
}
+ private static void mapLowerTriggerButtonsToBottomShoulder(float[] mappedButtons,
+ float[] rawButtons) {
+ float l2 = rawButtons[KeyEvent.KEYCODE_BUTTON_L2];
+ float r2 = rawButtons[KeyEvent.KEYCODE_BUTTON_R2];
+ mappedButtons[CanonicalButtonIndex.LEFT_TRIGGER] = l2;
+ mappedButtons[CanonicalButtonIndex.RIGHT_TRIGGER] = r2;
+ }
+
@VisibleForTesting
static float negativeAxisValueAsButton(float input) {
return (input < -0.5f) ? 1.f : 0.f;
@@ -156,98 +172,182 @@ class GamepadMappings {
mappedButtons[CanonicalButtonIndex.DPAD_DOWN] = positiveAxisValueAsButton(hatY);
}
- /**
- * Method for mapping Amazon Fire gamepad axis and button values
- * to standard gamepad button and axes values.
- */
- private static void mapAmazonFireGamepad(
- float[] mappedButtons, float[] rawButtons, float[] mappedAxes, float[] rawAxes) {
- mapCommonXYABButtons(mappedButtons, rawButtons);
- mapTriggerButtonsToTopShoulder(mappedButtons, rawButtons);
- mapCommonThumbstickButtons(mappedButtons, rawButtons);
- mapCommonStartSelectMetaButtons(mappedButtons, rawButtons);
- mapPedalAxesToBottomShoulder(mappedButtons, rawAxes);
- mapHatAxisToDpadButtons(mappedButtons, rawAxes);
-
- mapXYAxes(mappedAxes, rawAxes);
- mapZAndRZAxesToRightStick(mappedAxes, rawAxes);
+ private static class AmazonFireGamepadMappings extends GamepadMappings {
+
+ /**
+ * Method for mapping Amazon Fire gamepad axis and button values
+ * to standard gamepad button and axes values.
+ */
+ @Override
+ public void mapToStandardGamepad(float[] mappedAxes, float[] mappedButtons,
+ float[] rawAxes, float[] rawButtons) {
+ mapCommonXYABButtons(mappedButtons, rawButtons);
+ mapTriggerButtonsToTopShoulder(mappedButtons, rawButtons);
+ mapCommonThumbstickButtons(mappedButtons, rawButtons);
+ mapCommonStartSelectMetaButtons(mappedButtons, rawButtons);
+ mapPedalAxesToBottomShoulder(mappedButtons, rawAxes);
+ mapHatAxisToDpadButtons(mappedButtons, rawAxes);
+
+ mapXYAxes(mappedAxes, rawAxes);
+ mapZAndRZAxesToRightStick(mappedAxes, rawAxes);
+ }
}
- /**
- * Method for mapping Nvidia gamepad axis and button values
- * to standard gamepad button and axes values.
- */
- private static void mapShieldGamepad(
- float[] mappedButtons, float[] rawButtons, float[] mappedAxes, float[] rawAxes) {
- mapCommonXYABButtons(mappedButtons, rawButtons);
- mapTriggerButtonsToTopShoulder(mappedButtons, rawButtons);
- mapCommonThumbstickButtons(mappedButtons, rawButtons);
- mapCommonStartSelectMetaButtons(mappedButtons, rawButtons);
- mapTriggerAxesToBottomShoulder(mappedButtons, rawAxes);
- mapHatAxisToDpadButtons(mappedButtons, rawAxes);
-
- mapXYAxes(mappedAxes, rawAxes);
- mapZAndRZAxesToRightStick(mappedAxes, rawAxes);
+ private static class XboxCompatibleGamepadMappings extends GamepadMappings {
+
+ /**
+ * Method for mapping Xbox 360-compatible gamepad axis and button values
+ * to standard gamepad button and axes values.
+ */
+ @Override
+ public void mapToStandardGamepad(float[] mappedAxes, float[] mappedButtons,
+ float[] rawAxes, float[] rawButtons) {
+ mapCommonXYABButtons(mappedButtons, rawButtons);
+ mapTriggerButtonsToTopShoulder(mappedButtons, rawButtons);
+ mapCommonThumbstickButtons(mappedButtons, rawButtons);
+ mapCommonStartSelectMetaButtons(mappedButtons, rawButtons);
+ mapTriggerAxesToBottomShoulder(mappedButtons, rawAxes);
+ mapHatAxisToDpadButtons(mappedButtons, rawAxes);
+
+ mapXYAxes(mappedAxes, rawAxes);
+ mapZAndRZAxesToRightStick(mappedAxes, rawAxes);
+ }
}
- /**
- * Method for mapping Microsoft XBox 360 gamepad axis and button values
- * to standard gamepad button and axes values.
- */
- private static void mapXBox360Gamepad(
- float[] mappedButtons, float[] rawButtons, float[] mappedAxes, float[] rawAxes) {
- // These are actually mapped the same way in Android.
- mapShieldGamepad(mappedButtons, rawButtons, mappedAxes, rawAxes);
+ private static class PS3SixAxisGamepadMappings extends GamepadMappings {
+
+ /**
+ * Method for mapping PS3 gamepad axis and button values
+ * to standard gamepad button and axes values.
+ */
+ @Override
+ public void mapToStandardGamepad(float[] mappedAxes, float[] mappedButtons,
+ float[] rawAxes, float[] rawButtons) {
+ // On PS3 X/Y has higher priority.
+ float a = rawButtons[KeyEvent.KEYCODE_BUTTON_A];
+ float b = rawButtons[KeyEvent.KEYCODE_BUTTON_B];
+ float x = rawButtons[KeyEvent.KEYCODE_BUTTON_X];
+ float y = rawButtons[KeyEvent.KEYCODE_BUTTON_Y];
+ mappedButtons[CanonicalButtonIndex.PRIMARY] = x;
+ mappedButtons[CanonicalButtonIndex.SECONDARY] = y;
+ mappedButtons[CanonicalButtonIndex.TERTIARY] = a;
+ mappedButtons[CanonicalButtonIndex.QUATERNARY] = b;
+
+ mapTriggerButtonsToTopShoulder(mappedButtons, rawButtons);
+ mapCommonThumbstickButtons(mappedButtons, rawButtons);
+ mapCommonDpadButtons(mappedButtons, rawButtons);
+ mapCommonStartSelectMetaButtons(mappedButtons, rawButtons);
+ mapTriggerAxesToBottomShoulder(mappedButtons, rawAxes);
+
+ mapXYAxes(mappedAxes, rawAxes);
+ mapZAndRZAxesToRightStick(mappedAxes, rawAxes);
+ }
}
- private static void mapPS3SixAxisGamepad(
- float[] mappedButtons, float[] rawButtons, float[] mappedAxes, float[] rawAxes) {
- // On PS3 X/Y has higher priority.
- float a = rawButtons[KeyEvent.KEYCODE_BUTTON_A];
- float b = rawButtons[KeyEvent.KEYCODE_BUTTON_B];
- float x = rawButtons[KeyEvent.KEYCODE_BUTTON_X];
- float y = rawButtons[KeyEvent.KEYCODE_BUTTON_Y];
- mappedButtons[CanonicalButtonIndex.PRIMARY] = x;
- mappedButtons[CanonicalButtonIndex.SECONDARY] = y;
- mappedButtons[CanonicalButtonIndex.TERTIARY] = a;
- mappedButtons[CanonicalButtonIndex.QUATERNARY] = b;
-
- mapCommonTriggerButtons(mappedButtons, rawButtons);
- mapCommonThumbstickButtons(mappedButtons, rawButtons);
- mapCommonDpadButtons(mappedButtons, rawButtons);
- mapCommonStartSelectMetaButtons(mappedButtons, rawButtons);
- mapTriggerAxexToShoulderButtons(mappedButtons, rawAxes);
-
- mapXYAxes(mappedAxes, rawAxes);
- mapZAndRZAxesToRightStick(mappedAxes, rawAxes);
+ private static class SamsungEIGP20GamepadMappings extends GamepadMappings {
+
+ /**
+ * Method for mapping PS3 gamepad axis and button values
+ * to standard gamepad button and axes values.
+ */
+ @Override
+ public void mapToStandardGamepad(float[] mappedAxes, float[] mappedButtons,
+ float[] rawAxes, float[] rawButtons) {
+ mapCommonXYABButtons(mappedButtons, rawButtons);
+ mapUpperTriggerButtonsToBottomShoulder(mappedButtons, rawButtons);
+ mapCommonThumbstickButtons(mappedButtons, rawButtons);
+ mapCommonStartSelectMetaButtons(mappedButtons, rawButtons);
+ mapHatAxisToDpadButtons(mappedButtons, rawAxes);
+
+ mapXYAxes(mappedAxes, rawAxes);
+ mapRXAndRYAxesToRightStick(mappedAxes, rawAxes);
+ }
}
- private static void mapSamsungEIGP20Gamepad(
- float[] mappedButtons, float[] rawButtons, float[] mappedAxes, float[] rawAxes) {
- mapCommonXYABButtons(mappedButtons, rawButtons);
- mapCommonTriggerButtons(mappedButtons, rawButtons);
- mapCommonThumbstickButtons(mappedButtons, rawButtons);
- mapCommonStartSelectMetaButtons(mappedButtons, rawButtons);
- mapHatAxisToDpadButtons(mappedButtons, rawAxes);
+ private static class UnknownGamepadMappings extends GamepadMappings {
+ private int mLeftTriggerAxis = -1;
+ private int mRightTriggerAxis = -1;
+ private int mRightStickXAxis = -1;
+ private int mRightStickYAxis = -1;
+ private boolean mUseHatAxes = false;
+
+ UnknownGamepadMappings(int[] axes) {
+ int hatAxesFound = 0;
+
+ for (int axis : axes) {
+ switch (axis) {
+ case MotionEvent.AXIS_LTRIGGER:
+ case MotionEvent.AXIS_BRAKE:
+ mLeftTriggerAxis = axis;
+ break;
+ case MotionEvent.AXIS_RTRIGGER:
+ case MotionEvent.AXIS_GAS:
+ case MotionEvent.AXIS_THROTTLE:
+ mRightTriggerAxis = axis;
+ break;
+ case MotionEvent.AXIS_RX:
+ case MotionEvent.AXIS_Z:
+ mRightStickXAxis = axis;
+ break;
+ case MotionEvent.AXIS_RY:
+ case MotionEvent.AXIS_RZ:
+ mRightStickYAxis = axis;
+ break;
+ case MotionEvent.AXIS_HAT_X:
+ hatAxesFound++;
+ break;
+ case MotionEvent.AXIS_HAT_Y:
+ hatAxesFound++;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (hatAxesFound == 2) {
+ mUseHatAxes = true;
+ }
+ }
- mapXYAxes(mappedAxes, rawAxes);
- mapRXAndRYAxesToRightStick(mappedAxes, rawAxes);
- }
+ @Override
+ public boolean isStandard() {
+ // These mappings should not be considered standard
+ return false;
+ }
- /**
- * Method for mapping Unkown gamepad axis and button values
- * to standard gamepad button and axes values.
- */
- private static void mapUnknownGamepad(
- float[] mappedButtons, float[] rawButtons, float[] mappedAxes, float[] rawAxes) {
- mapCommonXYABButtons(mappedButtons, rawButtons);
- mapCommonTriggerButtons(mappedButtons, rawButtons);
- mapCommonThumbstickButtons(mappedButtons, rawButtons);
- mapCommonStartSelectMetaButtons(mappedButtons, rawButtons);
- mapTriggerAxexToShoulderButtons(mappedButtons, rawAxes);
- mapCommonDpadButtons(mappedButtons, rawButtons);
-
- mapXYAxes(mappedAxes, rawAxes);
- mapRXAndRYAxesToRightStick(mappedAxes, rawAxes);
+ @Override
+ public void mapToStandardGamepad(float[] mappedAxes, float[] mappedButtons,
+ float[] rawAxes, float[] rawButtons) {
+ // These are shared among all gamepads intended for use with Android
+ // that we tested so far.
+ mapCommonXYABButtons(mappedButtons, rawButtons);
+ mapTriggerButtonsToTopShoulder(mappedButtons, rawButtons);
+ mapCommonThumbstickButtons(mappedButtons, rawButtons);
+ mapCommonStartSelectMetaButtons(mappedButtons, rawButtons);
+ mapXYAxes(mappedAxes, rawAxes);
+
+ if (mLeftTriggerAxis != -1 && mRightTriggerAxis != -1) {
+ float lTrigger = rawAxes[mLeftTriggerAxis];
+ float rTrigger = rawAxes[mRightTriggerAxis];
+ mappedButtons[CanonicalButtonIndex.LEFT_TRIGGER] = lTrigger;
+ mappedButtons[CanonicalButtonIndex.RIGHT_TRIGGER] = rTrigger;
+ } else {
+ // Devices without analog triggers use digital buttons
+ mapLowerTriggerButtonsToBottomShoulder(mappedButtons, rawButtons);
+ }
+
+ if (mRightStickXAxis != -1 && mRightStickYAxis != -1) {
+ float rX = rawAxes[mRightStickXAxis];
+ float rY = rawAxes[mRightStickYAxis];
+ mappedAxes[CanonicalAxisIndex.RIGHT_STICK_X] = rX;
+ mappedAxes[CanonicalAxisIndex.RIGHT_STICK_Y] = rY;
+ }
+
+ if (mUseHatAxes) {
+ mapHatAxisToDpadButtons(mappedButtons, rawAxes);
+ } else {
+ mapCommonDpadButtons(mappedButtons, rawButtons);
+ }
+ }
}
}

Powered by Google App Engine
This is Rietveld 408576698