1// Copyright (c) 2012 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#include "content/browser/gamepad/gamepad_standard_mappings.h"
6
7namespace content {
8
9namespace {
10
11void MapperXInputStyleGamepad(
12    const blink::WebGamepad& input,
13    blink::WebGamepad* mapped) {
14  *mapped = input;
15  mapped->buttons[kButtonLeftTrigger] = AxisToButton(input.axes[2]);
16  mapped->buttons[kButtonRightTrigger] = AxisToButton(input.axes[5]);
17  mapped->buttons[kButtonBackSelect] = input.buttons[6];
18  mapped->buttons[kButtonStart] = input.buttons[7];
19  mapped->buttons[kButtonLeftThumbstick] = input.buttons[9];
20  mapped->buttons[kButtonRightThumbstick] = input.buttons[10];
21  mapped->buttons[kButtonDpadUp] = AxisNegativeAsButton(input.axes[7]);
22  mapped->buttons[kButtonDpadDown] = AxisPositiveAsButton(input.axes[7]);
23  mapped->buttons[kButtonDpadLeft] = AxisNegativeAsButton(input.axes[6]);
24  mapped->buttons[kButtonDpadRight] = AxisPositiveAsButton(input.axes[6]);
25  mapped->buttons[kButtonMeta] = input.buttons[8];
26  mapped->axes[kAxisRightStickX] = input.axes[3];
27  mapped->axes[kAxisRightStickY] = input.axes[4];
28  mapped->buttonsLength = kNumButtons;
29  mapped->axesLength = kNumAxes;
30}
31
32void MapperLakeviewResearch(
33    const blink::WebGamepad& input,
34    blink::WebGamepad* mapped) {
35  *mapped = input;
36  mapped->buttons[kButtonPrimary] = input.buttons[2];
37  mapped->buttons[kButtonTertiary] = input.buttons[3];
38  mapped->buttons[kButtonQuaternary] = input.buttons[0];
39  mapped->buttons[kButtonLeftShoulder] = input.buttons[6];
40  mapped->buttons[kButtonRightShoulder] = input.buttons[7];
41  mapped->buttons[kButtonLeftTrigger] = input.buttons[4];
42  mapped->buttons[kButtonRightTrigger] = input.buttons[5];
43  mapped->buttons[kButtonBackSelect] = input.buttons[9];
44  mapped->buttons[kButtonStart] = input.buttons[8];
45  mapped->buttons[kButtonDpadUp] = AxisNegativeAsButton(input.axes[5]);
46  mapped->buttons[kButtonDpadDown] = AxisPositiveAsButton(input.axes[5]);
47  mapped->buttons[kButtonDpadLeft] = AxisNegativeAsButton(input.axes[4]);
48  mapped->buttons[kButtonDpadRight] = AxisPositiveAsButton(input.axes[4]);
49  mapped->buttonsLength = kNumButtons - 1; // no Meta on this device
50  mapped->axesLength = kNumAxes;
51}
52
53void MapperPlaystationSixAxis(
54    const blink::WebGamepad& input,
55    blink::WebGamepad* mapped) {
56  *mapped = input;
57  mapped->buttons[kButtonPrimary] = input.buttons[14];
58  mapped->buttons[kButtonSecondary] = input.buttons[13];
59  mapped->buttons[kButtonTertiary] = input.buttons[15];
60  mapped->buttons[kButtonQuaternary] = input.buttons[12];
61  mapped->buttons[kButtonLeftShoulder] = input.buttons[10];
62  mapped->buttons[kButtonRightShoulder] = input.buttons[11];
63  mapped->buttons[kButtonLeftTrigger] = AxisToButton(input.axes[12]);
64  mapped->buttons[kButtonRightTrigger] = AxisToButton(input.axes[13]);
65  mapped->buttons[kButtonBackSelect] = input.buttons[0];
66  mapped->buttons[kButtonStart] = input.buttons[3];
67  mapped->buttons[kButtonLeftThumbstick] = input.buttons[1];
68  mapped->buttons[kButtonRightThumbstick] = input.buttons[2];
69  mapped->buttons[kButtonDpadUp] = AxisToButton(input.axes[8]);
70  mapped->buttons[kButtonDpadDown] = AxisToButton(input.axes[10]);
71  mapped->buttons[kButtonDpadLeft] = input.buttons[7];
72  mapped->buttons[kButtonDpadRight] = AxisToButton(input.axes[9]);
73  mapped->buttons[kButtonMeta] = input.buttons[16];
74
75  mapped->buttonsLength = kNumButtons;
76  mapped->axesLength = kNumAxes;
77}
78
79void MapperDualshock4(
80    const blink::WebGamepad& input,
81    blink::WebGamepad* mapped) {
82  enum Dualshock4Buttons {
83    kTouchpadButton = kNumButtons,
84    kNumDualshock4Buttons
85  };
86
87  *mapped = input;
88  mapped->buttons[kButtonPrimary] = input.buttons[1];
89  mapped->buttons[kButtonSecondary] = input.buttons[2];
90  mapped->buttons[kButtonTertiary] = input.buttons[0];
91  mapped->buttons[kButtonQuaternary] = input.buttons[3];
92  mapped->buttons[kButtonLeftShoulder] = input.buttons[4];
93  mapped->buttons[kButtonRightShoulder] = input.buttons[5];
94  mapped->buttons[kButtonLeftTrigger] = AxisToButton(input.axes[3]);
95  mapped->buttons[kButtonRightTrigger] = AxisToButton(input.axes[4]);
96  mapped->buttons[kButtonBackSelect] = input.buttons[8];
97  mapped->buttons[kButtonStart] = input.buttons[9];
98  mapped->buttons[kButtonLeftThumbstick] = input.buttons[10];
99  mapped->buttons[kButtonRightThumbstick] = input.buttons[11];
100  mapped->buttons[kButtonDpadUp] = AxisNegativeAsButton(input.axes[7]);
101  mapped->buttons[kButtonDpadDown] = AxisPositiveAsButton(input.axes[7]);
102  mapped->buttons[kButtonDpadLeft] = AxisNegativeAsButton(input.axes[6]);
103  mapped->buttons[kButtonDpadRight] = AxisPositiveAsButton(input.axes[6]);
104  mapped->buttons[kButtonMeta] = input.buttons[12];
105  mapped->buttons[kTouchpadButton] = input.buttons[13];
106  mapped->axes[kAxisRightStickY] = input.axes[5];
107
108  mapped->buttonsLength = kNumDualshock4Buttons;
109  mapped->axesLength = kNumAxes;
110}
111
112void MapperXGEAR(
113    const blink::WebGamepad& input,
114    blink::WebGamepad* mapped) {
115  *mapped = input;
116  mapped->buttons[kButtonPrimary] = input.buttons[2];
117  mapped->buttons[kButtonSecondary] = input.buttons[1];
118  mapped->buttons[kButtonTertiary] = input.buttons[3];
119  mapped->buttons[kButtonQuaternary] = input.buttons[0];
120  mapped->buttons[kButtonLeftShoulder] = input.buttons[6];
121  mapped->buttons[kButtonRightShoulder] = input.buttons[7];
122  mapped->buttons[kButtonLeftTrigger] = input.buttons[4];
123  mapped->buttons[kButtonRightTrigger] = input.buttons[5];
124  mapped->buttons[kButtonDpadUp] = AxisNegativeAsButton(input.axes[5]);
125  mapped->buttons[kButtonDpadDown] = AxisPositiveAsButton(input.axes[5]);
126  mapped->buttons[kButtonDpadLeft] = AxisNegativeAsButton(input.axes[4]);
127  mapped->buttons[kButtonDpadRight] = AxisPositiveAsButton(input.axes[4]);
128  mapped->axes[kAxisRightStickX] = input.axes[3];
129  mapped->axes[kAxisRightStickY] = input.axes[2];
130  mapped->buttonsLength = kNumButtons - 1; // no Meta on this device
131  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