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

Unified Diff: content/public/android/java/src/org/chromium/content/browser/input/GamepadDataMapper.java

Issue 165483003: Gamepad API for Android (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: address comments Created 6 years, 9 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: content/public/android/java/src/org/chromium/content/browser/input/GamepadDataMapper.java
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/GamepadDataMapper.java b/content/public/android/java/src/org/chromium/content/browser/input/GamepadDataMapper.java
new file mode 100644
index 0000000000000000000000000000000000000000..6831b71b1c4530d960cfb61104bc22de9e06f80c
--- /dev/null
+++ b/content/public/android/java/src/org/chromium/content/browser/input/GamepadDataMapper.java
@@ -0,0 +1,205 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.content.browser.input;
+
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+
+import org.chromium.base.JNINamespace;
+import org.chromium.content.browser.input.gamepad_mapping.CanonicalAxisIndex;
+import org.chromium.content.browser.input.gamepad_mapping.CanonicalButtonIndex;
+
+import java.util.Arrays;
+
+/**
+ * Device specific input data converter for Gamepad API.
+ * Implemented per device by subclasses.
+ */
+@JNINamespace("content")
+abstract class GamepadDataMapper {
+ protected static final String PS3_SIXAXIS_DEVICE_NAME = "Sony PLAYSTATION(R)3 Controller";
+ protected static final String STANDARD_GAMEPAD_NAME = "(STANDARD_GAMEPAD)";
+ protected static final String STANDARD_MAPPING = "standard";
+
+ protected final WebGamepadData mData;
+
+ public abstract WebGamepadData map(float[] axes, boolean[] buttons);
+
+ // Factory method.
+ public static GamepadDataMapper createDataMapper(String deviceName) {
+ if (deviceName.equals(PS3_SIXAXIS_DEVICE_NAME))
+ return new PS3SixAxisGamepadDataMapper();
+
+ return new GenericGamepadDataMapper(deviceName);
+ }
+
+ protected GamepadDataMapper(String deviceName) {
+ mData = new WebGamepadData();
+ mData.id = deviceName + " " + STANDARD_GAMEPAD_NAME;
+ mData.mapping = STANDARD_MAPPING;
+ mData.axes = new float[CanonicalAxisIndex.NUM_CANONICAL_AXES];
+ mData.buttons = new float[CanonicalButtonIndex.NUM_CANONICAL_BUTTONS];
+ }
+
+ protected void clearAxesAndButtons() {
+ Arrays.fill(mData.axes, 0);
+ Arrays.fill(mData.buttons, 0);
+ }
+
+ // Most of the time we jut use 1 for pressed and 0 for not pressed.
+ // Note that however some devices can represent some buttons of the standard gamepad
+ // with analog values so we still want to store the button values as floats.
+ // For example the Samsung EI-GP20 maps dpad to AXIS_HAT_X and AXIS_HAT_Y.
+ protected float buttonValue(boolean pressed) { return pressed ? 1.0f : 0.0f; }
+
+ protected void mapCommonXYAxes(float[] axes) {
+ mData.axes[CanonicalAxisIndex.AXIS_LEFT_STICK_X] = axes[MotionEvent.AXIS_X];
+ mData.axes[CanonicalAxisIndex.AXIS_LEFT_STICK_Y] = axes[MotionEvent.AXIS_Y];
+ }
+
+ protected void mapCommonTriggerAxes(float[] axes) {
+ mData.buttons[CanonicalButtonIndex.BUTTON_LEFT_SHOULDER] = axes[MotionEvent.AXIS_LTRIGGER];
+ mData.buttons[CanonicalButtonIndex.BUTTON_RIGHT_SHOULDER] = axes[MotionEvent.AXIS_RTRIGGER];
+ }
+
+ protected void mapCommonTriggerButtons(boolean[] buttons) {
+ boolean l1 = buttons[KeyEvent.KEYCODE_BUTTON_L1];
+ boolean r1 = buttons[KeyEvent.KEYCODE_BUTTON_R1];
+ mData.buttons[CanonicalButtonIndex.BUTTON_LEFT_TRIGGER] = buttonValue(l1);
+ mData.buttons[CanonicalButtonIndex.BUTTON_RIGHT_TRIGGER] = buttonValue(r1);
+ }
+
+ protected void mapCommonThumbstickButtons(boolean[] buttons) {
+ boolean thumbL = buttons[KeyEvent.KEYCODE_BUTTON_THUMBL];
+ boolean thumbR = buttons[KeyEvent.KEYCODE_BUTTON_THUMBR];
+ mData.buttons[CanonicalButtonIndex.BUTTON_LEFT_THUMBSTICK] = buttonValue(thumbL);
+ mData.buttons[CanonicalButtonIndex.BUTTON_RIGHT_THUMBSTICK] = buttonValue(thumbR);
+ }
+
+ protected void mapCommonStartSelectButtons(boolean[] buttons) {
+ boolean select = buttons[KeyEvent.KEYCODE_BUTTON_SELECT];
+ boolean start = buttons[KeyEvent.KEYCODE_BUTTON_START];
+ mData.buttons[CanonicalButtonIndex.BUTTON_BACK_SELECT] = buttonValue(select);
+ mData.buttons[CanonicalButtonIndex.BUTTON_START] = buttonValue(start);
+ }
+
+ protected void mapCommonDpadButtons(boolean[] buttons) {
+ boolean dpadDown = buttons[KeyEvent.KEYCODE_DPAD_DOWN];
+ boolean dpadUp = buttons[KeyEvent.KEYCODE_DPAD_UP];
+ boolean dpadLeft = buttons[KeyEvent.KEYCODE_DPAD_LEFT];
+ boolean dpadRight = buttons[KeyEvent.KEYCODE_DPAD_RIGHT];
+ mData.buttons[CanonicalButtonIndex.BUTTON_DPAD_DOWN] = buttonValue(dpadDown);
+ mData.buttons[CanonicalButtonIndex.BUTTON_DPAD_UP] = buttonValue(dpadUp);
+ mData.buttons[CanonicalButtonIndex.BUTTON_DPAD_LEFT] = buttonValue(dpadLeft);
+ mData.buttons[CanonicalButtonIndex.BUTTON_DPAD_RIGHT] = buttonValue(dpadRight);
+ }
+
+ protected void mapCommonXYABButtons(boolean[] buttons) {
+ boolean bA = buttons[KeyEvent.KEYCODE_BUTTON_A];
+ boolean bB = buttons[KeyEvent.KEYCODE_BUTTON_B];
+ boolean bX = buttons[KeyEvent.KEYCODE_BUTTON_X];
+ boolean bY = buttons[KeyEvent.KEYCODE_BUTTON_Y];
+ mData.buttons[CanonicalButtonIndex.BUTTON_PRIMARY] = buttonValue(bA);
+ mData.buttons[CanonicalButtonIndex.BUTTON_SECONDARY] = buttonValue(bB);
+ mData.buttons[CanonicalButtonIndex.BUTTON_TERTIARY] = buttonValue(bX);
+ mData.buttons[CanonicalButtonIndex.BUTTON_QUATERNARY] = buttonValue(bY);
+ }
+}
+
+// This is a last resort if we find a device that we don't know about.
+// The Android API is general enough that this can be better than nothing
+// but we should not really rely on this.
+class GenericGamepadDataMapper extends GamepadDataMapper {
+ private final String mDeviceName;
+
+ GenericGamepadDataMapper(String deviceName) {
+ super(deviceName);
+ mDeviceName = deviceName;
+ }
+
+ // Find something for right stick x and y.
+ private void mapRightSticks(float[] axes) {
+ int position = CanonicalAxisIndex.AXIS_RIGHT_STICK_X;
+ // position + 1 is AXIS_RIGHT_STICK_Y.
+ assert mData.axes.length > position + 1;
+ float x = axes[MotionEvent.AXIS_RX];
+ float y = axes[MotionEvent.AXIS_RY];
+ if (x != 0 || y != 0) {
+ mData.axes[position++] = x;
+ mData.axes[position] = y;
+ return;
+ }
+ x = axes[MotionEvent.AXIS_Z];
+ y = axes[MotionEvent.AXIS_RZ];
+ if (x != 0 || y != 0) {
+ mData.axes[position++] = x;
+ mData.axes[position] = y;
+ return;
+ }
+ x = axes[MotionEvent.AXIS_HAT_X];
+ y = axes[MotionEvent.AXIS_HAT_Y];
+ if (x != 0 || y != 0) {
+ mData.axes[position++] = x;
+ mData.axes[position] = y;
+ }
+ }
+
+ public WebGamepadData map(float[] axes, boolean[] buttons) {
+ clearAxesAndButtons();
+
+ mapCommonXYAxes(axes);
+ mapRightSticks(axes);
+ mapCommonTriggerAxes(axes);
+ mapCommonXYABButtons(buttons);
+ mapCommonTriggerButtons(buttons);
+ mapCommonThumbstickButtons(buttons);
+ mapCommonStartSelectButtons(buttons);
+ mapCommonDpadButtons(buttons);
+
+ // TODO(b.kelemen): meta is missing.
+
+ return mData;
+ }
+}
+
+class PS3SixAxisGamepadDataMapper extends GamepadDataMapper {
+ PS3SixAxisGamepadDataMapper() {
+ super(PS3_SIXAXIS_DEVICE_NAME);
+ }
+
+ public WebGamepadData map(float[] axes, boolean[] buttons) {
+ clearAxesAndButtons();
+
+ mapCommonXYAxes(axes);
+
+ mData.axes[CanonicalAxisIndex.AXIS_RIGHT_STICK_X] = axes[MotionEvent.AXIS_Z];
+ mData.axes[CanonicalAxisIndex.AXIS_RIGHT_STICK_Y] = axes[MotionEvent.AXIS_RZ];
+
+ mapCommonTriggerAxes(axes);
+
+ boolean bA = buttons[KeyEvent.KEYCODE_BUTTON_A];
+ boolean bB = buttons[KeyEvent.KEYCODE_BUTTON_B];
+ boolean bX = buttons[KeyEvent.KEYCODE_BUTTON_X];
+ boolean bY = buttons[KeyEvent.KEYCODE_BUTTON_Y];
+ mData.buttons[CanonicalButtonIndex.BUTTON_PRIMARY] = buttonValue(bX);
+ mData.buttons[CanonicalButtonIndex.BUTTON_SECONDARY] = buttonValue(bY);
+ mData.buttons[CanonicalButtonIndex.BUTTON_TERTIARY] = buttonValue(bA);
+ mData.buttons[CanonicalButtonIndex.BUTTON_QUATERNARY] = buttonValue(bB);
+
+ mapCommonTriggerButtons(buttons);
+ mapCommonThumbstickButtons(buttons);
+ mapCommonStartSelectButtons(buttons);
+ mapCommonDpadButtons(buttons);
+
+ // TODO(b.kelemen): PS button is missing. Looks like it is swallowed by Android
+ // but probably there is a way to configure otherwise and in this case we should
+ // handle it.
+
+ return mData;
+ }
+}
+
+// TODO(b.kelemen): add more implementations. It would be nice to support at least those that are
+// supported on Linux.

Powered by Google App Engine
This is Rietveld 408576698