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 MapperLogitechDualAction(
12    const blink::WebGamepad& input,
13    blink::WebGamepad* mapped) {
14  *mapped = input;
15  mapped->buttons[kButtonPrimary] = input.buttons[1];
16  mapped->buttons[kButtonSecondary] = input.buttons[2];
17  mapped->buttons[kButtonTertiary] = input.buttons[0];
18  mapped->axes[kAxisRightStickY] = input.axes[5];
19  DpadFromAxis(mapped, input.axes[9]);
20
21  mapped->buttonsLength = kNumButtons;
22  mapped->axesLength = kNumAxes;
23}
24
25void Mapper2Axes8Keys(
26    const blink::WebGamepad& input,
27    blink::WebGamepad* mapped) {
28  *mapped = input;
29  mapped->buttons[kButtonPrimary] = input.buttons[2];
30  mapped->buttons[kButtonSecondary] = input.buttons[1];
31  mapped->buttons[kButtonTertiary] = input.buttons[3];
32  mapped->buttons[kButtonQuaternary] = input.buttons[0];
33  mapped->buttons[kButtonDpadUp] = AxisNegativeAsButton(input.axes[1]);
34  mapped->buttons[kButtonDpadDown] = AxisPositiveAsButton(input.axes[1]);
35  mapped->buttons[kButtonDpadLeft] = AxisNegativeAsButton(input.axes[0]);
36  mapped->buttons[kButtonDpadRight] = AxisPositiveAsButton(input.axes[0]);
37
38  // Missing buttons
39  mapped->buttons[kButtonLeftTrigger] = blink::WebGamepadButton();
40  mapped->buttons[kButtonRightTrigger] = blink::WebGamepadButton();
41  mapped->buttons[kButtonLeftThumbstick] = blink::WebGamepadButton();
42  mapped->buttons[kButtonRightThumbstick] = blink::WebGamepadButton();
43  mapped->buttons[kButtonMeta] = blink::WebGamepadButton();
44
45  mapped->buttonsLength = kNumButtons - 1;
46  mapped->axesLength = 0;
47}
48
49void MapperDualshock4(
50    const blink::WebGamepad& input,
51    blink::WebGamepad* mapped) {
52  enum Dualshock4Buttons {
53    kTouchpadButton = kNumButtons,
54    kNumDualshock4Buttons
55  };
56
57  *mapped = input;
58  mapped->buttons[kButtonPrimary] = input.buttons[1];
59  mapped->buttons[kButtonSecondary] = input.buttons[2];
60  mapped->buttons[kButtonTertiary] = input.buttons[0];
61  mapped->buttons[kButtonQuaternary] = input.buttons[3];
62  mapped->buttons[kButtonLeftShoulder] = input.buttons[4];
63  mapped->buttons[kButtonRightShoulder] = input.buttons[5];
64  mapped->buttons[kButtonLeftTrigger] = AxisToButton(input.axes[3]);
65  mapped->buttons[kButtonRightTrigger] = AxisToButton(input.axes[4]);
66  mapped->buttons[kButtonBackSelect] = input.buttons[8];
67  mapped->buttons[kButtonStart] = input.buttons[9];
68  mapped->buttons[kButtonLeftThumbstick] = input.buttons[10];
69  mapped->buttons[kButtonRightThumbstick] = input.buttons[11];
70  mapped->buttons[kButtonMeta] = input.buttons[12];
71  mapped->buttons[kTouchpadButton] = input.buttons[13];
72  mapped->axes[kAxisRightStickY] = input.axes[5];
73  DpadFromAxis(mapped, input.axes[9]);
74
75  mapped->buttonsLength = kNumDualshock4Buttons;
76  mapped->axesLength = kNumAxes;
77}
78
79void MapperOnLiveWireless(
80    const blink::WebGamepad& input,
81    blink::WebGamepad* mapped) {
82  *mapped = input;
83  mapped->buttons[kButtonPrimary] = input.buttons[0];
84  mapped->buttons[kButtonSecondary] = input.buttons[1];
85  mapped->buttons[kButtonTertiary] = input.buttons[3];
86  mapped->buttons[kButtonQuaternary] = input.buttons[4];
87  mapped->buttons[kButtonLeftShoulder] = input.buttons[6];
88  mapped->buttons[kButtonRightShoulder] = input.buttons[7];
89  mapped->buttons[kButtonLeftTrigger] = AxisToButton(input.axes[2]);
90  mapped->buttons[kButtonRightTrigger] = AxisToButton(input.axes[5]);
91  mapped->buttons[kButtonBackSelect] = input.buttons[10];
92  mapped->buttons[kButtonStart] = input.buttons[11];
93  mapped->buttons[kButtonLeftThumbstick] = input.buttons[13];
94  mapped->buttons[kButtonRightThumbstick] = input.buttons[14];
95  mapped->buttons[kButtonMeta] = input.buttons[12];
96  mapped->axes[kAxisRightStickX] = input.axes[3];
97  mapped->axes[kAxisRightStickY] = input.axes[4];
98  DpadFromAxis(mapped, input.axes[9]);
99
100  mapped->buttonsLength = kNumButtons;
101  mapped->axesLength = kNumAxes;
102}
103
104void MapperADT1(
105    const blink::WebGamepad& input,
106    blink::WebGamepad* mapped) {
107  *mapped = input;
108  mapped->buttons[kButtonPrimary] = input.buttons[0];
109  mapped->buttons[kButtonSecondary] = input.buttons[1];
110  mapped->buttons[kButtonTertiary] = input.buttons[3];
111  mapped->buttons[kButtonQuaternary] = input.buttons[4];
112  mapped->buttons[kButtonLeftShoulder] = input.buttons[6];
113  mapped->buttons[kButtonRightShoulder] = input.buttons[7];
114  mapped->buttons[kButtonLeftTrigger] = AxisToButton(input.axes[4]);
115  mapped->buttons[kButtonRightTrigger] = AxisToButton(input.axes[3]);
116  mapped->buttons[kButtonBackSelect] = NullButton();
117  mapped->buttons[kButtonStart] = NullButton();
118  mapped->buttons[kButtonLeftThumbstick] = input.buttons[13];
119  mapped->buttons[kButtonRightThumbstick] = input.buttons[14];
120  mapped->buttons[kButtonMeta] = input.buttons[12];
121  mapped->axes[kAxisRightStickY] = input.axes[5];
122  DpadFromAxis(mapped, input.axes[9]);
123
124  mapped->buttonsLength = kNumButtons;
125  mapped->axesLength = kNumAxes;
126}
127
128struct MappingData {
129  const char* const vendor_id;
130  const char* const product_id;
131  GamepadStandardMappingFunction function;
132} AvailableMappings[] = {
133  // http://www.linux-usb.org/usb.ids
134  { "046d", "c216", MapperLogitechDualAction }, // Logitech DualAction
135  { "0079", "0011", Mapper2Axes8Keys },         // 2Axes 8Keys Game Pad
136  { "054c", "05c4", MapperDualshock4 },         // Playstation Dualshock 4
137  { "2378", "1008", MapperOnLiveWireless },     // OnLive Controller (Bluetooth)
138  { "2378", "100a", MapperOnLiveWireless },     // OnLive Controller (Wired)
139  { "18d1", "2c40", MapperADT1 },               // ADT-1 Controller
140};
141
142}  // namespace
143
144GamepadStandardMappingFunction GetGamepadStandardMappingFunction(
145    const base::StringPiece& vendor_id,
146    const base::StringPiece& product_id) {
147  for (size_t i = 0; i < arraysize(AvailableMappings); ++i) {
148    MappingData& item = AvailableMappings[i];
149    if (vendor_id == item.vendor_id && product_id == item.product_id)
150      return item.function;
151  }
152  return NULL;
153}
154
155}  // namespace content
156