OLD | NEW |
---|---|
(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. | |
OLD | NEW |