13ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar// Copyright (c) 2012 The Chromium Authors. All rights reserved.
23ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar// Use of this source code is governed by a BSD-style license that can be
33ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar// found in the LICENSE file.
43ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar
53ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar#include "content/browser/gamepad/gamepad_standard_mappings.h"
63ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar
73ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbarnamespace content {
83ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar
93ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbarnamespace {
101eb4e64eed08837b85a375d6a953503daa844f07Daniel Dunbar
111eb4e64eed08837b85a375d6a953503daa844f07Daniel Dunbarvoid MapperXInputStyleGamepad(
123ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar    const blink::WebGamepad& input,
133ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar    blink::WebGamepad* mapped) {
143ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar  *mapped = input;
153ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar  mapped->buttons[kButtonLeftTrigger] = AxisToButton(input.axes[2]);
163ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar  mapped->buttons[kButtonRightTrigger] = AxisToButton(input.axes[5]);
172c6f6f3c170502c5b810102cf85f05732a2aa9d0Daniel Dunbar  mapped->buttons[kButtonBackSelect] = input.buttons[6];
182c6f6f3c170502c5b810102cf85f05732a2aa9d0Daniel Dunbar  mapped->buttons[kButtonStart] = input.buttons[7];
192c6f6f3c170502c5b810102cf85f05732a2aa9d0Daniel Dunbar  mapped->buttons[kButtonLeftThumbstick] = input.buttons[9];
20510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar  mapped->buttons[kButtonRightThumbstick] = input.buttons[10];
213ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar  mapped->buttons[kButtonDpadUp] = AxisNegativeAsButton(input.axes[7]);
22dd98e2cad165ca73c769e4f105a4e47c2216387aDaniel Dunbar  mapped->buttons[kButtonDpadDown] = AxisPositiveAsButton(input.axes[7]);
238f25c79e59d88df41c5a3cabba1c58035d384a6eDaniel Dunbar  mapped->buttons[kButtonDpadLeft] = AxisNegativeAsButton(input.axes[6]);
248f25c79e59d88df41c5a3cabba1c58035d384a6eDaniel Dunbar  mapped->buttons[kButtonDpadRight] = AxisPositiveAsButton(input.axes[6]);
254ad4b3ebbe5769143389dccfcfadb666a4ba5940Daniel Dunbar  mapped->buttons[kButtonMeta] = input.buttons[8];
26af07f936b698575f2c91f1c1134c116f1ef0deddDaniel Dunbar  mapped->axes[kAxisRightStickX] = input.axes[3];
27365c02f65be026f90e67a8e00e7b827cee60e228Daniel Dunbar  mapped->axes[kAxisRightStickY] = input.axes[4];
283ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar  mapped->buttonsLength = kNumButtons;
294ad4b3ebbe5769143389dccfcfadb666a4ba5940Daniel Dunbar  mapped->axesLength = kNumAxes;
301b3bb6efc59a21f794b534078f9ae7e95393f510Daniel Dunbar}
313ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar
32510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbarvoid MapperLakeviewResearch(
33510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar    const blink::WebGamepad& input,
34510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar    blink::WebGamepad* mapped) {
35510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar  *mapped = input;
36510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar  mapped->buttons[kButtonPrimary] = input.buttons[2];
37510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar  mapped->buttons[kButtonTertiary] = input.buttons[3];
38510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar  mapped->buttons[kButtonQuaternary] = input.buttons[0];
39510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar  mapped->buttons[kButtonLeftShoulder] = input.buttons[6];
40510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar  mapped->buttons[kButtonRightShoulder] = input.buttons[7];
41510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar  mapped->buttons[kButtonLeftTrigger] = input.buttons[4];
42510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar  mapped->buttons[kButtonRightTrigger] = input.buttons[5];
43510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar  mapped->buttons[kButtonBackSelect] = input.buttons[9];
44510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar  mapped->buttons[kButtonStart] = input.buttons[8];
45510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar  mapped->buttons[kButtonDpadUp] = AxisNegativeAsButton(input.axes[5]);
46510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar  mapped->buttons[kButtonDpadDown] = AxisPositiveAsButton(input.axes[5]);
47510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar  mapped->buttons[kButtonDpadLeft] = AxisNegativeAsButton(input.axes[4]);
48510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar  mapped->buttons[kButtonDpadRight] = AxisPositiveAsButton(input.axes[4]);
49510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar  mapped->buttonsLength = kNumButtons - 1; // no Meta on this device
50510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar  mapped->axesLength = kNumAxes;
51510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar}
52510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar
53510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbarvoid MapperPlaystationSixAxis(
54510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar    const blink::WebGamepad& input,
55510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar    blink::WebGamepad* mapped) {
56510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar  *mapped = input;
57510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar  mapped->buttons[kButtonPrimary] = input.buttons[14];
58510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar  mapped->buttons[kButtonSecondary] = input.buttons[13];
59510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar  mapped->buttons[kButtonTertiary] = input.buttons[15];
60510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar  mapped->buttons[kButtonQuaternary] = input.buttons[12];
61510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar  mapped->buttons[kButtonLeftShoulder] = input.buttons[10];
62510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar  mapped->buttons[kButtonRightShoulder] = input.buttons[11];
63510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar  mapped->buttons[kButtonLeftTrigger] = AxisToButton(input.axes[12]);
64734932c7dc77a16b15d466588e10d76bcd6d13c7Daniel Dunbar  mapped->buttons[kButtonRightTrigger] = AxisToButton(input.axes[13]);
65734932c7dc77a16b15d466588e10d76bcd6d13c7Daniel Dunbar  mapped->buttons[kButtonBackSelect] = input.buttons[0];
66734932c7dc77a16b15d466588e10d76bcd6d13c7Daniel Dunbar  mapped->buttons[kButtonStart] = input.buttons[3];
67734932c7dc77a16b15d466588e10d76bcd6d13c7Daniel Dunbar  mapped->buttons[kButtonLeftThumbstick] = input.buttons[1];
68734932c7dc77a16b15d466588e10d76bcd6d13c7Daniel Dunbar  mapped->buttons[kButtonRightThumbstick] = input.buttons[2];
69734932c7dc77a16b15d466588e10d76bcd6d13c7Daniel Dunbar  mapped->buttons[kButtonDpadUp] = AxisToButton(input.axes[8]);
70734932c7dc77a16b15d466588e10d76bcd6d13c7Daniel Dunbar  mapped->buttons[kButtonDpadDown] = AxisToButton(input.axes[10]);
713ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar  mapped->buttons[kButtonDpadLeft] = input.buttons[7];
723ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar  mapped->buttons[kButtonDpadRight] = AxisToButton(input.axes[9]);
738f25c79e59d88df41c5a3cabba1c58035d384a6eDaniel Dunbar  mapped->buttons[kButtonMeta] = input.buttons[16];
743ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar
75734932c7dc77a16b15d466588e10d76bcd6d13c7Daniel Dunbar  mapped->buttonsLength = kNumButtons;
76510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar  mapped->axesLength = kNumAxes;
77510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar}
78510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar
79510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbarvoid MapperDualshock4(
80510d73200ec48496a2b10703385fe99b51e31fa5Daniel Dunbar    const blink::WebGamepad& input,
81af07f936b698575f2c91f1c1134c116f1ef0deddDaniel Dunbar    blink::WebGamepad* mapped) {
82af07f936b698575f2c91f1c1134c116f1ef0deddDaniel Dunbar  enum Dualshock4Buttons {
83af07f936b698575f2c91f1c1134c116f1ef0deddDaniel Dunbar    kTouchpadButton = kNumButtons,
84af07f936b698575f2c91f1c1134c116f1ef0deddDaniel Dunbar    kNumDualshock4Buttons
85e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar  };
86e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar
87e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar  *mapped = input;
88e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar  mapped->buttons[kButtonPrimary] = input.buttons[1];
89e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar  mapped->buttons[kButtonSecondary] = input.buttons[2];
90e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar  mapped->buttons[kButtonTertiary] = input.buttons[0];
91e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar  mapped->buttons[kButtonQuaternary] = input.buttons[3];
92e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar  mapped->buttons[kButtonLeftShoulder] = input.buttons[4];
93e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar  mapped->buttons[kButtonRightShoulder] = input.buttons[5];
94e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar  mapped->buttons[kButtonLeftTrigger] = AxisToButton(input.axes[3]);
95e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar  mapped->buttons[kButtonRightTrigger] = AxisToButton(input.axes[4]);
96e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar  mapped->buttons[kButtonBackSelect] = input.buttons[8];
97e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar  mapped->buttons[kButtonStart] = input.buttons[9];
98e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar  mapped->buttons[kButtonLeftThumbstick] = input.buttons[10];
99e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar  mapped->buttons[kButtonRightThumbstick] = input.buttons[11];
100e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar  mapped->buttons[kButtonDpadUp] = AxisNegativeAsButton(input.axes[7]);
101e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar  mapped->buttons[kButtonDpadDown] = AxisPositiveAsButton(input.axes[7]);
102e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar  mapped->buttons[kButtonDpadLeft] = AxisNegativeAsButton(input.axes[6]);
103e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar  mapped->buttons[kButtonDpadRight] = AxisPositiveAsButton(input.axes[6]);
104e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar  mapped->buttons[kButtonMeta] = input.buttons[12];
105e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar  mapped->buttons[kTouchpadButton] = input.buttons[13];
106e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar  mapped->axes[kAxisRightStickY] = input.axes[5];
107e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar
108e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar  mapped->buttonsLength = kNumDualshock4Buttons;
109e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar  mapped->axesLength = kNumAxes;
110e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar}
111e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar
112e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbarvoid MapperXGEAR(
113e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar    const blink::WebGamepad& input,
114e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar    blink::WebGamepad* mapped) {
115e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar  *mapped = input;
116e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar  mapped->buttons[kButtonPrimary] = input.buttons[2];
117e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar  mapped->buttons[kButtonSecondary] = input.buttons[1];
118e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar  mapped->buttons[kButtonTertiary] = input.buttons[3];
119e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar  mapped->buttons[kButtonQuaternary] = input.buttons[0];
120e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar  mapped->buttons[kButtonLeftShoulder] = input.buttons[6];
121e5be6dac24946e9521af78fce8e531e605f563d4Daniel Dunbar  mapped->buttons[kButtonRightShoulder] = input.buttons[7];
1223ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar  mapped->buttons[kButtonLeftTrigger] = input.buttons[4];
123af96def468042cfbed55a4cc12b1bb917ead4f33Daniel Dunbar  mapped->buttons[kButtonRightTrigger] = input.buttons[5];
124af96def468042cfbed55a4cc12b1bb917ead4f33Daniel Dunbar  mapped->buttons[kButtonDpadUp] = AxisNegativeAsButton(input.axes[5]);
125af96def468042cfbed55a4cc12b1bb917ead4f33Daniel Dunbar  mapped->buttons[kButtonDpadDown] = AxisPositiveAsButton(input.axes[5]);
1268f25c79e59d88df41c5a3cabba1c58035d384a6eDaniel Dunbar  mapped->buttons[kButtonDpadLeft] = AxisNegativeAsButton(input.axes[4]);
1278f25c79e59d88df41c5a3cabba1c58035d384a6eDaniel Dunbar  mapped->buttons[kButtonDpadRight] = AxisPositiveAsButton(input.axes[4]);
1288f25c79e59d88df41c5a3cabba1c58035d384a6eDaniel Dunbar  mapped->axes[kAxisRightStickX] = input.axes[3];
129af96def468042cfbed55a4cc12b1bb917ead4f33Daniel Dunbar  mapped->axes[kAxisRightStickY] = input.axes[2];
1303ede8d0a7d1813f678ccc6011a99a0834b1b6116Daniel Dunbar  mapped->buttonsLength = kNumButtons - 1; // no Meta on this device
1317ec3dafdda96abcd1ff0841deef4eadfeb8f1208Daniel Dunbar  mapped->axesLength = kNumAxes;
132}
133
134
135void MapperDragonRiseGeneric(
136    const blink::WebGamepad& input,
137    blink::WebGamepad* mapped) {
138  *mapped = input;
139  mapped->buttons[kButtonDpadUp] = AxisNegativeAsButton(input.axes[6]);
140  mapped->buttons[kButtonDpadDown] = AxisPositiveAsButton(input.axes[6]);
141  mapped->buttons[kButtonDpadLeft] = AxisNegativeAsButton(input.axes[5]);
142  mapped->buttons[kButtonDpadRight] = AxisPositiveAsButton(input.axes[5]);
143  mapped->axes[kAxisLeftStickX] = input.axes[0];
144  mapped->axes[kAxisLeftStickY] = input.axes[1];
145  mapped->axes[kAxisRightStickX] = input.axes[3];
146  mapped->axes[kAxisRightStickY] = input.axes[4];
147  mapped->buttonsLength = kNumButtons - 1; // no Meta on this device
148  mapped->axesLength = kNumAxes;
149}
150
151void MapperOnLiveWireless(
152    const blink::WebGamepad& input,
153    blink::WebGamepad* mapped) {
154  *mapped = input;
155  mapped->buttons[kButtonLeftTrigger] = AxisToButton(input.axes[2]);
156  mapped->buttons[kButtonRightTrigger] = AxisToButton(input.axes[5]);
157  mapped->buttons[kButtonBackSelect] = input.buttons[6];
158  mapped->buttons[kButtonStart] = input.buttons[7];
159  mapped->buttons[kButtonLeftThumbstick] = input.buttons[9];
160  mapped->buttons[kButtonRightThumbstick] = input.buttons[10];
161  mapped->buttons[kButtonDpadUp] = AxisNegativeAsButton(input.axes[7]);
162  mapped->buttons[kButtonDpadDown] = AxisPositiveAsButton(input.axes[7]);
163  mapped->buttons[kButtonDpadLeft] = AxisNegativeAsButton(input.axes[6]);
164  mapped->buttons[kButtonDpadRight] = AxisPositiveAsButton(input.axes[6]);
165  mapped->buttons[kButtonMeta] = input.buttons[8];
166  mapped->axes[kAxisRightStickX] = input.axes[3];
167  mapped->axes[kAxisRightStickY] = input.axes[4];
168
169  mapped->buttonsLength = kNumButtons;
170  mapped->axesLength = kNumAxes;
171}
172
173void MapperADT1(
174    const blink::WebGamepad& input,
175    blink::WebGamepad* mapped) {
176  *mapped = input;
177  mapped->buttons[kButtonLeftTrigger] = AxisToButton(input.axes[5]);
178  mapped->buttons[kButtonRightTrigger] = AxisToButton(input.axes[4]);
179  mapped->buttons[kButtonBackSelect] = NullButton();
180  mapped->buttons[kButtonStart] = NullButton();
181  mapped->buttons[kButtonLeftThumbstick] = input.buttons[7];
182  mapped->buttons[kButtonRightThumbstick] = input.buttons[8];
183  mapped->buttons[kButtonDpadUp] = AxisNegativeAsButton(input.axes[7]);
184  mapped->buttons[kButtonDpadDown] = AxisPositiveAsButton(input.axes[7]);
185  mapped->buttons[kButtonDpadLeft] = AxisNegativeAsButton(input.axes[6]);
186  mapped->buttons[kButtonDpadRight] = AxisPositiveAsButton(input.axes[6]);
187  mapped->buttons[kButtonMeta] = input.buttons[6];
188
189  mapped->buttonsLength = kNumButtons;
190  mapped->axesLength = kNumAxes;
191}
192
193struct MappingData {
194  const char* const vendor_id;
195  const char* const product_id;
196  GamepadStandardMappingFunction function;
197} AvailableMappings[] = {
198  // http://www.linux-usb.org/usb.ids
199  { "0079", "0006", MapperDragonRiseGeneric },  // DragonRise Generic USB
200  { "045e", "028e", MapperXInputStyleGamepad }, // Xbox 360 Controller
201  { "045e", "028f", MapperXInputStyleGamepad }, // Xbox 360 Wireless Controller
202  { "046d", "c21d", MapperXInputStyleGamepad }, // Logitech F310
203  { "046d", "c21e", MapperXInputStyleGamepad }, // Logitech F510
204  { "046d", "c21f", MapperXInputStyleGamepad }, // Logitech F710
205  { "054c", "0268", MapperPlaystationSixAxis }, // Playstation SIXAXIS
206  { "054c", "05c4", MapperDualshock4 },         // Playstation Dualshock 4
207  { "0925", "0005", MapperLakeviewResearch },   // SmartJoy PLUS Adapter
208  { "0925", "8866", MapperLakeviewResearch },   // WiseGroup MP-8866
209  { "0e8f", "0003", MapperXGEAR },              // XFXforce XGEAR PS2 Controller
210  { "2378", "1008", MapperOnLiveWireless },     // OnLive Controller (Bluetooth)
211  { "2378", "100a", MapperOnLiveWireless },     // OnLive Controller (Wired)
212  { "18d1", "2c40", MapperADT1 },               // ADT-1 Controller
213};
214
215}  // namespace
216
217GamepadStandardMappingFunction GetGamepadStandardMappingFunction(
218    const base::StringPiece& vendor_id,
219    const base::StringPiece& product_id) {
220  for (size_t i = 0; i < arraysize(AvailableMappings); ++i) {
221    MappingData& item = AvailableMappings[i];
222    if (vendor_id == item.vendor_id && product_id == item.product_id)
223      return item.function;
224  }
225  return NULL;
226}
227
228}  // namespace content
229