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

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: Created 6 years, 10 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.Log;
8 import android.util.SparseArray;
9 import android.view.KeyEvent;
10 import android.view.MotionEvent;
11
12 import org.chromium.base.JNINamespace;
13
14 /**
15 * Device specific input data converter for Gamepad API.
16 * Implemented per device by subclasses.
17 */
18 @JNINamespace("content")
19 abstract class GamepadDataMapper {
20 private static final String TAG = "GamepadDataMapper";
21
22 public abstract WebGamepadData map(SparseArray<Float> axes, SparseArray<Bool ean> buttons);
23
24 // Factory method.
25 public static GamepadDataMapper createDataMapper(String id) {
26 if (id.equals("Sony PLAYSTATION(R)3 Controller")) {
27 return new PS3SixAxisGamepadDataMapper();
28 }
29
30 // TODO(b.kelemen): testing needed. This is probably not the right devic e name.
31 if (id.equals("Samsung Game pad EI-GP20")) {
32 return new SamsungEIGP20GamepadDataMapper();
33 }
34
35 Log.e(TAG, "Fallback to generic gamepad data mapper");
36 return new GenericGamepadDataMapper();
37 }
38
39 // CanonicalButtonIndex and CanonicalAxisIndex mirror the same enums
40 // from C++ (in gamepad_standard_mappings.h).
41
42 protected enum CanonicalButtonIndex {
43 BUTTON_PRIMARY,
44 BUTTON_SECONDARY,
45 BUTTON_TERTIARY,
46 BUTTON_QUATERNARY,
47 BUTTON_LEFT_SHOULDER,
48 BUTTON_RIGHT_SHOULDER,
49 BUTTON_LEFT_TRIGGER,
50 BUTTON_RIGHT_TRIGGER,
51 BUTTON_BACK_SELECT,
52 BUTTON_START,
53 BUTTON_LEFT_THUMBSTICK,
54 BUTTON_RIGHT_THUMBSTICK,
55 BUTTON_DPAD_UP,
56 BUTTON_DPAD_DOWN,
57 BUTTON_DPAD_LEFT,
58 BUTTON_DPAD_RIGHT,
59 BUTTON_META,
60 NUM_BUTTONS;
61 };
62
63 protected static final int NumberOfCanonicalButtons =
64 CanonicalButtonIndex.NUM_BUTTONS.ordinal();
65
66 protected enum CanonicalAxisIndex {
67 AXIS_LEFT_STICK_X,
68 AXIS_LEFT_STICK_Y,
69 AXIS_RIGHT_STICK_X,
70 AXIS_RIGHT_STICK_Y,
71 NUM_AXES
72 };
73
74 protected static final int NumberOfCanonicalAxes =
75 CanonicalAxisIndex.NUM_AXES.ordinal();
76
77 protected static float axisValue(Float f) { return f == null ? 0 : f.floatVa lue(); }
78 protected static float buttonValue(Boolean b) { return (b == null || !b) ? 0 : 1; }
79
80 protected static WebGamepadData createWebGamepadData() {
81 WebGamepadData data = new WebGamepadData();
82 data.axes = new float[NumberOfCanonicalAxes];
83 data.buttons = new float[NumberOfCanonicalButtons];
84 return data;
85 }
86
87 protected static void mapCommonXYAxes(WebGamepadData data, SparseArray<Float > axes) {
88 Float x = (Float) axes.get(MotionEvent.AXIS_X);
89 Float y = (Float) axes.get(MotionEvent.AXIS_Y);
90 data.axes[CanonicalAxisIndex.AXIS_LEFT_STICK_X.ordinal()] = axisValue(x) ;
91 data.axes[CanonicalAxisIndex.AXIS_LEFT_STICK_Y.ordinal()] = axisValue(y) ;
92 }
93
94 protected static void mapCommonTriggerAxes(WebGamepadData data, SparseArray< Float> axes) {
95 Float lTrigger = (Float) axes.get(MotionEvent.AXIS_LTRIGGER);
96 Float rTrigger = (Float) axes.get(MotionEvent.AXIS_RTRIGGER);
97 data.buttons[CanonicalButtonIndex.BUTTON_LEFT_SHOULDER.ordinal()] = axis Value(lTrigger);
98 data.buttons[CanonicalButtonIndex.BUTTON_RIGHT_SHOULDER.ordinal()] = axi sValue(rTrigger);
99 }
100
101 protected static void mapCommonTriggerButtons(
102 WebGamepadData data, SparseArray<Boolean> buttons) {
103 Boolean l1 = (Boolean) buttons.get(KeyEvent.KEYCODE_BUTTON_L1);
104 Boolean r1 = (Boolean) buttons.get(KeyEvent.KEYCODE_BUTTON_R1);
105 data.buttons[CanonicalButtonIndex.BUTTON_LEFT_TRIGGER.ordinal()] = butto nValue(l1);
106 data.buttons[CanonicalButtonIndex.BUTTON_RIGHT_TRIGGER.ordinal()] = butt onValue(r1);
107 }
108
109 protected static void mapCommonThumbstickButtons(
110 WebGamepadData data, SparseArray<Boolean> buttons) {
111 Boolean thumbL = (Boolean) buttons.get(KeyEvent.KEYCODE_BUTTON_THUMBL);
112 Boolean thumbR = (Boolean) buttons.get(KeyEvent.KEYCODE_BUTTON_THUMBR);
113 data.buttons[CanonicalButtonIndex.BUTTON_LEFT_THUMBSTICK.ordinal()] = bu ttonValue(thumbL);
114 data.buttons[CanonicalButtonIndex.BUTTON_RIGHT_THUMBSTICK.ordinal()] = b uttonValue(thumbR);
115 }
116
117 protected static void mapCommonStartSelectButtons(
118 WebGamepadData data, SparseArray<Boolean> buttons) {
119 Boolean select = (Boolean) buttons.get(KeyEvent.KEYCODE_BUTTON_SELECT);
120 Boolean start = (Boolean) buttons.get(KeyEvent.KEYCODE_BUTTON_START);
121 data.buttons[CanonicalButtonIndex.BUTTON_BACK_SELECT.ordinal()] = button Value(select);
122 data.buttons[CanonicalButtonIndex.BUTTON_START.ordinal()] = buttonValue( start);
123 }
124
125 protected static void mapCommonDpadButtons(
126 WebGamepadData data, SparseArray<Boolean> buttons) {
127 Boolean dpadDown = (Boolean) buttons.get(KeyEvent.KEYCODE_DPAD_DOWN);
128 Boolean dpadUp = (Boolean) buttons.get(KeyEvent.KEYCODE_DPAD_UP);
129 Boolean dpadLeft = (Boolean) buttons.get(KeyEvent.KEYCODE_DPAD_LEFT);
130 Boolean dpadRight = (Boolean) buttons.get(KeyEvent.KEYCODE_DPAD_RIGHT);
131 data.buttons[CanonicalButtonIndex.BUTTON_DPAD_DOWN.ordinal()] = buttonVa lue(dpadDown);
132 data.buttons[CanonicalButtonIndex.BUTTON_DPAD_UP.ordinal()] = buttonValu e(dpadUp);
133 data.buttons[CanonicalButtonIndex.BUTTON_DPAD_LEFT.ordinal()] = buttonVa lue(dpadLeft);
134 data.buttons[CanonicalButtonIndex.BUTTON_DPAD_RIGHT.ordinal()] = buttonV alue(dpadRight);
135 }
136
137 protected static void mapCommonXYABButtons(
138 WebGamepadData data, SparseArray<Boolean> buttons) {
139 Boolean bA = (Boolean) buttons.get(KeyEvent.KEYCODE_BUTTON_A);
140 Boolean bB = (Boolean) buttons.get(KeyEvent.KEYCODE_BUTTON_B);
141 Boolean bX = (Boolean) buttons.get(KeyEvent.KEYCODE_BUTTON_X);
142 Boolean bY = (Boolean) buttons.get(KeyEvent.KEYCODE_BUTTON_Y);
143 data.buttons[CanonicalButtonIndex.BUTTON_PRIMARY.ordinal()] = buttonValu e(bA);
144 data.buttons[CanonicalButtonIndex.BUTTON_SECONDARY.ordinal()] = buttonVa lue(bB);
145 data.buttons[CanonicalButtonIndex.BUTTON_TERTIARY.ordinal()] = buttonVal ue(bX);
146 data.buttons[CanonicalButtonIndex.BUTTON_QUATERNARY.ordinal()] = buttonV alue(bY);
147 }
148 }
149
150 // This is a last resort if we find a device that we don't know about.
151 // The Android API is general enough that this can be better than nothing
152 // but we should not really rely on this.
153 class GenericGamepadDataMapper extends GamepadDataMapper {
154 // Find something for right stick x and y. If there is even more axes, map t hem to
155 // non-canonical positions.
156 private static void mapRightAndExtraSticks(WebGamepadData data, SparseArray< Float> axes) {
157 int position = CanonicalAxisIndex.AXIS_RIGHT_STICK_X.ordinal();
158 // position + 1 is AXIS_RIGHT_STICK_Y.
159 Float x = (Float) axes.get(MotionEvent.AXIS_RX);
160 Float y = (Float) axes.get(MotionEvent.AXIS_RY);
161 if (x != null || y != null) {
162 data.axes[position++] = axisValue(x);
163 data.axes[position++] = axisValue(y);
164 }
165 x = (Float) axes.get(MotionEvent.AXIS_Z);
166 y = (Float) axes.get(MotionEvent.AXIS_RZ);
167 if (x != null || y != null) {
168 data.axes[position++] = axisValue(x);
169 data.axes[position++] = axisValue(y);
170 }
171 x = (Float) axes.get(MotionEvent.AXIS_HAT_X);
172 y = (Float) axes.get(MotionEvent.AXIS_HAT_Y);
173 if (x != null || y != null) {
174 data.axes[position++] = axisValue(x);
175 data.axes[position++] = axisValue(y);
176 }
177 }
178
179 public WebGamepadData map(SparseArray<Float> axes, SparseArray<Boolean> butt ons) {
180 WebGamepadData data = createWebGamepadData();
181
182 mapCommonXYAxes(data, axes);
183 mapRightAndExtraSticks(data, axes);
184 mapCommonTriggerAxes(data, axes);
185 mapCommonXYABButtons(data, buttons);
186 mapCommonTriggerButtons(data, buttons);
187 mapCommonThumbstickButtons(data, buttons);
188 mapCommonStartSelectButtons(data, buttons);
189 mapCommonDpadButtons(data, buttons);
190
191 // TODO(b.kelemen): meta is missing.
192
193 return data;
194 }
195 }
196
197 class PS3SixAxisGamepadDataMapper extends GamepadDataMapper {
198 public WebGamepadData map(SparseArray<Float> axes, SparseArray<Boolean> butt ons) {
199 WebGamepadData data = createWebGamepadData();
200
201 mapCommonXYAxes(data, axes);
202
203 Float z = (Float) axes.get(MotionEvent.AXIS_Z);
204 Float rz = (Float) axes.get(MotionEvent.AXIS_RZ);
205 data.axes[CanonicalAxisIndex.AXIS_RIGHT_STICK_X.ordinal()] = axisValue(z );
206 data.axes[CanonicalAxisIndex.AXIS_RIGHT_STICK_Y.ordinal()] = axisValue(r z);
207
208 mapCommonTriggerAxes(data, axes);
209
210 Boolean bA = (Boolean) buttons.get(KeyEvent.KEYCODE_BUTTON_A);
211 Boolean bB = (Boolean) buttons.get(KeyEvent.KEYCODE_BUTTON_B);
212 Boolean bX = (Boolean) buttons.get(KeyEvent.KEYCODE_BUTTON_X);
213 Boolean bY = (Boolean) buttons.get(KeyEvent.KEYCODE_BUTTON_Y);
214 data.buttons[CanonicalButtonIndex.BUTTON_PRIMARY.ordinal()] = buttonValu e(bX);
215 data.buttons[CanonicalButtonIndex.BUTTON_SECONDARY.ordinal()] = buttonVa lue(bY);
216 data.buttons[CanonicalButtonIndex.BUTTON_TERTIARY.ordinal()] = buttonVal ue(bA);
217 data.buttons[CanonicalButtonIndex.BUTTON_QUATERNARY.ordinal()] = buttonV alue(bB);
218
219 mapCommonTriggerButtons(data, buttons);
220 mapCommonThumbstickButtons(data, buttons);
221 mapCommonStartSelectButtons(data, buttons);
222 mapCommonDpadButtons(data, buttons);
223
224 // TODO(b.kelemen): PS button is missing. Looks like it is swallowed by Android
225 // but probably there is a way to configure otherwise and in this case w e should
226 // handle it.
227
228 return data;
229 }
230 }
231
232 // DANGER! Not tested with device yet.
233 // Based on http://developer.samsung.com/mobile-console.
234 // TODO(b.kelemen): test.
235 class SamsungEIGP20GamepadDataMapper extends GamepadDataMapper {
bajones 2014/03/01 00:04:03 I would prefer to not add mappings that haven't be
236 public WebGamepadData map(SparseArray<Float> axes, SparseArray<Boolean> butt ons) {
237 WebGamepadData data = createWebGamepadData();
238
239 mapCommonXYAxes(data, axes);
240
241 Float rx = (Float) axes.get(MotionEvent.AXIS_RX);
242 Float ry = (Float) axes.get(MotionEvent.AXIS_RY);
243 data.axes[CanonicalAxisIndex.AXIS_RIGHT_STICK_X.ordinal()] = axisValue(r x);
244 data.axes[CanonicalAxisIndex.AXIS_RIGHT_STICK_Y.ordinal()] = axisValue(r y);
245
246 Float hatX = (Float) axes.get(MotionEvent.AXIS_HAT_X);
247 Float hatY = (Float) axes.get(MotionEvent.AXIS_HAT_Y);
248 float hx = axisValue(hatX);
249 float hy = axisValue(hatY);
250 float dpadDown = 0, dpadUp = 0, dpadLeft = 0, dpadRight = 0;
251 if (hx < 0) dpadLeft = -hx;
252 else dpadRight = hx;
253 if (hy < 0) dpadUp = -hy;
254 else dpadDown = hy;
255 data.buttons[CanonicalButtonIndex.BUTTON_DPAD_DOWN.ordinal()] = dpadDown ;
256 data.buttons[CanonicalButtonIndex.BUTTON_DPAD_UP.ordinal()] = dpadUp;
257 data.buttons[CanonicalButtonIndex.BUTTON_DPAD_LEFT.ordinal()] = dpadLeft ;
258 data.buttons[CanonicalButtonIndex.BUTTON_DPAD_RIGHT.ordinal()] = dpadRig ht;
259
260 mapCommonXYABButtons(data, buttons);
261 mapCommonStartSelectButtons(data, buttons);
262 mapCommonTriggerButtons(data, buttons);
263
264 // TODO(b.kelemen): where is the game button? The documentation refers
265 // to KEYCODE_BUTTON_GAME but there is no such thing.
266
267 return data;
268 }
269 }
270
271 // TODO(b.kelemen): add more implementations. It would be nice to support at lea st those that are
272 // supported on Linux.
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698