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

Side by Side 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: updated 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package org.chromium.content.browser.input;
6
7 import android.util.SparseArray;
8 import android.view.KeyEvent;
9 import android.view.MotionEvent;
10
11 import org.chromium.base.JNINamespace;
12
13 /**
14 * Device specific input data converter for Gamepad API.
15 * Implemented per device by subclasses.
16 */
17 @JNINamespace("content")
18 abstract class GamepadDataMapper {
19 protected static final String PS3_SIXAXIS_DEVICE_NAME = "Sony PLAYSTATION(R) 3 Controller";
20
21 public abstract WebGamepadData map(SparseArray<Float> axes, SparseArray<Bool ean> buttons);
22
23 // Factory method.
24 public static GamepadDataMapper createDataMapper(String deviceName) {
25 if (deviceName.equals(PS3_SIXAXIS_DEVICE_NAME))
26 return new PS3SixAxisGamepadDataMapper();
27
28 return new GenericGamepadDataMapper(deviceName);
29 }
30
31 // CanonicalButtonIndex and CanonicalAxisIndex mirror the same enums
32 // from C++ (in gamepad_standard_mappings.h).
33
34 protected enum CanonicalButtonIndex {
bulach 2014/03/05 12:34:39 enums are a no-go in android :( http://developer.a
kbalazs 2014/03/05 19:56:11 Should I keep the naming scheme kButtonWhatever? I
35 BUTTON_PRIMARY,
36 BUTTON_SECONDARY,
37 BUTTON_TERTIARY,
38 BUTTON_QUATERNARY,
39 BUTTON_LEFT_SHOULDER,
40 BUTTON_RIGHT_SHOULDER,
41 BUTTON_LEFT_TRIGGER,
42 BUTTON_RIGHT_TRIGGER,
43 BUTTON_BACK_SELECT,
44 BUTTON_START,
45 BUTTON_LEFT_THUMBSTICK,
46 BUTTON_RIGHT_THUMBSTICK,
47 BUTTON_DPAD_UP,
48 BUTTON_DPAD_DOWN,
49 BUTTON_DPAD_LEFT,
50 BUTTON_DPAD_RIGHT,
51 BUTTON_META,
52 NUM_BUTTONS;
53 };
54
55 protected static final int NumberOfCanonicalButtons =
56 CanonicalButtonIndex.NUM_BUTTONS.ordinal();
57
58 protected enum CanonicalAxisIndex {
59 AXIS_LEFT_STICK_X,
60 AXIS_LEFT_STICK_Y,
61 AXIS_RIGHT_STICK_X,
62 AXIS_RIGHT_STICK_Y,
63 NUM_AXES
64 };
65
66 protected static final int NumberOfCanonicalAxes =
67 CanonicalAxisIndex.NUM_AXES.ordinal();
68
69 protected static float axisValue(Float f) { return f == null ? 0 : f.floatVa lue(); }
70 protected static float buttonValue(Boolean b) { return (b == null || !b) ? 0 : 1; }
71
72 protected static WebGamepadData createWebGamepadData() {
73 WebGamepadData data = new WebGamepadData();
74 data.axes = new float[NumberOfCanonicalAxes];
75 data.buttons = new float[NumberOfCanonicalButtons];
76 return data;
77 }
78
79 protected static void mapCommonXYAxes(WebGamepadData data, SparseArray<Float > axes) {
80 Float x = (Float) axes.get(MotionEvent.AXIS_X);
81 Float y = (Float) axes.get(MotionEvent.AXIS_Y);
82 data.axes[CanonicalAxisIndex.AXIS_LEFT_STICK_X.ordinal()] = axisValue(x) ;
83 data.axes[CanonicalAxisIndex.AXIS_LEFT_STICK_Y.ordinal()] = axisValue(y) ;
84 }
85
86 protected static void mapCommonTriggerAxes(WebGamepadData data, SparseArray< Float> axes) {
87 Float lTrigger = (Float) axes.get(MotionEvent.AXIS_LTRIGGER);
88 Float rTrigger = (Float) axes.get(MotionEvent.AXIS_RTRIGGER);
89 data.buttons[CanonicalButtonIndex.BUTTON_LEFT_SHOULDER.ordinal()] = axis Value(lTrigger);
90 data.buttons[CanonicalButtonIndex.BUTTON_RIGHT_SHOULDER.ordinal()] = axi sValue(rTrigger);
91 }
92
93 protected static void mapCommonTriggerButtons(
94 WebGamepadData data, SparseArray<Boolean> buttons) {
95 Boolean l1 = (Boolean) buttons.get(KeyEvent.KEYCODE_BUTTON_L1);
96 Boolean r1 = (Boolean) buttons.get(KeyEvent.KEYCODE_BUTTON_R1);
97 data.buttons[CanonicalButtonIndex.BUTTON_LEFT_TRIGGER.ordinal()] = butto nValue(l1);
98 data.buttons[CanonicalButtonIndex.BUTTON_RIGHT_TRIGGER.ordinal()] = butt onValue(r1);
99 }
100
101 protected static void mapCommonThumbstickButtons(
102 WebGamepadData data, SparseArray<Boolean> buttons) {
103 Boolean thumbL = (Boolean) buttons.get(KeyEvent.KEYCODE_BUTTON_THUMBL);
104 Boolean thumbR = (Boolean) buttons.get(KeyEvent.KEYCODE_BUTTON_THUMBR);
105 data.buttons[CanonicalButtonIndex.BUTTON_LEFT_THUMBSTICK.ordinal()] = bu ttonValue(thumbL);
106 data.buttons[CanonicalButtonIndex.BUTTON_RIGHT_THUMBSTICK.ordinal()] = b uttonValue(thumbR);
107 }
108
109 protected static void mapCommonStartSelectButtons(
110 WebGamepadData data, SparseArray<Boolean> buttons) {
111 Boolean select = (Boolean) buttons.get(KeyEvent.KEYCODE_BUTTON_SELECT);
112 Boolean start = (Boolean) buttons.get(KeyEvent.KEYCODE_BUTTON_START);
113 data.buttons[CanonicalButtonIndex.BUTTON_BACK_SELECT.ordinal()] = button Value(select);
114 data.buttons[CanonicalButtonIndex.BUTTON_START.ordinal()] = buttonValue( start);
115 }
116
117 protected static void mapCommonDpadButtons(
118 WebGamepadData data, SparseArray<Boolean> buttons) {
119 Boolean dpadDown = (Boolean) buttons.get(KeyEvent.KEYCODE_DPAD_DOWN);
120 Boolean dpadUp = (Boolean) buttons.get(KeyEvent.KEYCODE_DPAD_UP);
121 Boolean dpadLeft = (Boolean) buttons.get(KeyEvent.KEYCODE_DPAD_LEFT);
122 Boolean dpadRight = (Boolean) buttons.get(KeyEvent.KEYCODE_DPAD_RIGHT);
123 data.buttons[CanonicalButtonIndex.BUTTON_DPAD_DOWN.ordinal()] = buttonVa lue(dpadDown);
124 data.buttons[CanonicalButtonIndex.BUTTON_DPAD_UP.ordinal()] = buttonValu e(dpadUp);
125 data.buttons[CanonicalButtonIndex.BUTTON_DPAD_LEFT.ordinal()] = buttonVa lue(dpadLeft);
126 data.buttons[CanonicalButtonIndex.BUTTON_DPAD_RIGHT.ordinal()] = buttonV alue(dpadRight);
127 }
128
129 protected static void mapCommonXYABButtons(
130 WebGamepadData data, SparseArray<Boolean> buttons) {
131 Boolean bA = (Boolean) buttons.get(KeyEvent.KEYCODE_BUTTON_A);
132 Boolean bB = (Boolean) buttons.get(KeyEvent.KEYCODE_BUTTON_B);
133 Boolean bX = (Boolean) buttons.get(KeyEvent.KEYCODE_BUTTON_X);
134 Boolean bY = (Boolean) buttons.get(KeyEvent.KEYCODE_BUTTON_Y);
135 data.buttons[CanonicalButtonIndex.BUTTON_PRIMARY.ordinal()] = buttonValu e(bA);
136 data.buttons[CanonicalButtonIndex.BUTTON_SECONDARY.ordinal()] = buttonVa lue(bB);
137 data.buttons[CanonicalButtonIndex.BUTTON_TERTIARY.ordinal()] = buttonVal ue(bX);
138 data.buttons[CanonicalButtonIndex.BUTTON_QUATERNARY.ordinal()] = buttonV alue(bY);
139 }
140 }
141
142 // This is a last resort if we find a device that we don't know about.
143 // The Android API is general enough that this can be better than nothing
144 // but we should not really rely on this.
145 class GenericGamepadDataMapper extends GamepadDataMapper {
146 private final String mDeviceName;
147
148 GenericGamepadDataMapper(String deviceName) {
149 mDeviceName = deviceName;
150 }
151
152 // Find something for right stick x and y. If there is even more axes, map t hem to
153 // non-canonical positions.
154 private static void mapRightAndExtraSticks(WebGamepadData data, SparseArray< Float> axes) {
155 int position = CanonicalAxisIndex.AXIS_RIGHT_STICK_X.ordinal();
156 // position + 1 is AXIS_RIGHT_STICK_Y.
157 Float x = (Float) axes.get(MotionEvent.AXIS_RX);
158 Float y = (Float) axes.get(MotionEvent.AXIS_RY);
159 if (x != null || y != null) {
160 data.axes[position++] = axisValue(x);
161 data.axes[position++] = axisValue(y);
162 }
163 x = (Float) axes.get(MotionEvent.AXIS_Z);
164 y = (Float) axes.get(MotionEvent.AXIS_RZ);
165 if (x != null || y != null) {
166 data.axes[position++] = axisValue(x);
167 data.axes[position++] = axisValue(y);
168 }
169 x = (Float) axes.get(MotionEvent.AXIS_HAT_X);
170 y = (Float) axes.get(MotionEvent.AXIS_HAT_Y);
171 if (x != null || y != null) {
172 data.axes[position++] = axisValue(x);
173 data.axes[position++] = axisValue(y);
174 }
175 }
176
177 public WebGamepadData map(SparseArray<Float> axes, SparseArray<Boolean> butt ons) {
178 WebGamepadData data = createWebGamepadData();
179 data.id = mDeviceName + " (STANDARD_GAMEPAD)";
180 data.mapping = "standard";
181 mapCommonXYAxes(data, axes);
182 mapRightAndExtraSticks(data, axes);
183 mapCommonTriggerAxes(data, axes);
184 mapCommonXYABButtons(data, buttons);
185 mapCommonTriggerButtons(data, buttons);
186 mapCommonThumbstickButtons(data, buttons);
187 mapCommonStartSelectButtons(data, buttons);
188 mapCommonDpadButtons(data, buttons);
189
190 // TODO(b.kelemen): meta is missing.
191
192 return data;
193 }
194 }
195
196 class PS3SixAxisGamepadDataMapper extends GamepadDataMapper {
197 public WebGamepadData map(SparseArray<Float> axes, SparseArray<Boolean> butt ons) {
198 WebGamepadData data = createWebGamepadData();
199 data.id = PS3_SIXAXIS_DEVICE_NAME + " (STANDARD_GAMEPAD)";
200 data.mapping = "standard";
201
202 mapCommonXYAxes(data, axes);
203
204 Float z = (Float) axes.get(MotionEvent.AXIS_Z);
205 Float rz = (Float) axes.get(MotionEvent.AXIS_RZ);
206 data.axes[CanonicalAxisIndex.AXIS_RIGHT_STICK_X.ordinal()] = axisValue(z );
207 data.axes[CanonicalAxisIndex.AXIS_RIGHT_STICK_Y.ordinal()] = axisValue(r z);
208
209 mapCommonTriggerAxes(data, axes);
210
211 Boolean bA = (Boolean) buttons.get(KeyEvent.KEYCODE_BUTTON_A);
212 Boolean bB = (Boolean) buttons.get(KeyEvent.KEYCODE_BUTTON_B);
213 Boolean bX = (Boolean) buttons.get(KeyEvent.KEYCODE_BUTTON_X);
214 Boolean bY = (Boolean) buttons.get(KeyEvent.KEYCODE_BUTTON_Y);
215 data.buttons[CanonicalButtonIndex.BUTTON_PRIMARY.ordinal()] = buttonValu e(bX);
216 data.buttons[CanonicalButtonIndex.BUTTON_SECONDARY.ordinal()] = buttonVa lue(bY);
217 data.buttons[CanonicalButtonIndex.BUTTON_TERTIARY.ordinal()] = buttonVal ue(bA);
218 data.buttons[CanonicalButtonIndex.BUTTON_QUATERNARY.ordinal()] = buttonV alue(bB);
219
220 mapCommonTriggerButtons(data, buttons);
221 mapCommonThumbstickButtons(data, buttons);
222 mapCommonStartSelectButtons(data, buttons);
223 mapCommonDpadButtons(data, buttons);
224
225 // TODO(b.kelemen): PS button is missing. Looks like it is swallowed by Android
226 // but probably there is a way to configure otherwise and in this case w e should
227 // handle it.
228
229 return data;
230 }
231 }
232
233 // TODO(b.kelemen): add more implementations. It would be nice to support at lea st those that are
234 // supported on Linux.
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698