15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/gamepad/gamepad_standard_mappings.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gamepad_hardware_buffer.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)float AxisToButton(float input) {
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return (input + 1.f) / 2.f;
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)float AxisNegativeAsButton(float input) {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return (input < -0.5f) ? 1.f : 0.f;
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)float AxisPositiveAsButton(float input) {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return (input > 0.5f) ? 1.f : 0.f;
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MapperXInputStyleGamepad(
26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const blink::WebGamepad& input,
27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    blink::WebGamepad* mapped) {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *mapped = input;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttons[kButtonLeftTrigger] = AxisToButton(input.axes[2]);
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttons[kButtonRightTrigger] = AxisToButton(input.axes[5]);
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttons[kButtonBackSelect] = input.buttons[6];
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttons[kButtonStart] = input.buttons[7];
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttons[kButtonLeftThumbstick] = input.buttons[9];
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttons[kButtonRightThumbstick] = input.buttons[10];
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttons[kButtonDpadUp] = AxisNegativeAsButton(input.axes[7]);
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttons[kButtonDpadDown] = AxisPositiveAsButton(input.axes[7]);
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttons[kButtonDpadLeft] = AxisNegativeAsButton(input.axes[6]);
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttons[kButtonDpadRight] = AxisPositiveAsButton(input.axes[6]);
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttons[kButtonMeta] = input.buttons[8];
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->axes[kAxisRightStickX] = input.axes[3];
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->axes[kAxisRightStickY] = input.axes[4];
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttonsLength = kNumButtons;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->axesLength = kNumAxes;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MapperLakeviewResearch(
47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const blink::WebGamepad& input,
48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    blink::WebGamepad* mapped) {
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *mapped = input;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttons[kButtonPrimary] = input.buttons[2];
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttons[kButtonTertiary] = input.buttons[3];
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttons[kButtonQuaternary] = input.buttons[0];
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttons[kButtonLeftShoulder] = input.buttons[6];
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttons[kButtonRightShoulder] = input.buttons[7];
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttons[kButtonLeftTrigger] = input.buttons[4];
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttons[kButtonRightTrigger] = input.buttons[5];
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttons[kButtonBackSelect] = input.buttons[9];
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttons[kButtonStart] = input.buttons[8];
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttons[kButtonDpadUp] = AxisNegativeAsButton(input.axes[5]);
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttons[kButtonDpadDown] = AxisPositiveAsButton(input.axes[5]);
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttons[kButtonDpadLeft] = AxisNegativeAsButton(input.axes[4]);
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttons[kButtonDpadRight] = AxisPositiveAsButton(input.axes[4]);
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttonsLength = kNumButtons - 1; // no Meta on this device
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->axesLength = kNumAxes;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MapperPlaystationSixAxis(
68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const blink::WebGamepad& input,
69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    blink::WebGamepad* mapped) {
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *mapped = input;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttons[kButtonPrimary] = input.buttons[14];
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttons[kButtonSecondary] = input.buttons[13];
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttons[kButtonTertiary] = input.buttons[15];
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttons[kButtonQuaternary] = input.buttons[12];
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttons[kButtonLeftShoulder] = input.buttons[10];
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttons[kButtonRightShoulder] = input.buttons[11];
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttons[kButtonLeftTrigger] = AxisToButton(input.axes[12]);
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttons[kButtonRightTrigger] = AxisToButton(input.axes[13]);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttons[kButtonBackSelect] = input.buttons[0];
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttons[kButtonStart] = input.buttons[3];
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttons[kButtonLeftThumbstick] = input.buttons[1];
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttons[kButtonRightThumbstick] = input.buttons[2];
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttons[kButtonDpadUp] = AxisToButton(input.axes[8]);
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttons[kButtonDpadDown] = AxisToButton(input.axes[10]);
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttons[kButtonDpadLeft] = input.buttons[7];
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttons[kButtonDpadRight] = AxisToButton(input.axes[9]);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttons[kButtonMeta] = input.buttons[16];
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttonsLength = kNumButtons;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->axesLength = kNumAxes;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MapperXGEAR(
94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const blink::WebGamepad& input,
95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    blink::WebGamepad* mapped) {
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *mapped = input;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttons[kButtonPrimary] = input.buttons[2];
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttons[kButtonSecondary] = input.buttons[1];
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttons[kButtonTertiary] = input.buttons[3];
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttons[kButtonQuaternary] = input.buttons[0];
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttons[kButtonLeftShoulder] = input.buttons[6];
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttons[kButtonRightShoulder] = input.buttons[7];
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttons[kButtonLeftTrigger] = input.buttons[4];
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttons[kButtonRightTrigger] = input.buttons[5];
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttons[kButtonDpadUp] = AxisNegativeAsButton(input.axes[5]);
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttons[kButtonDpadDown] = AxisPositiveAsButton(input.axes[5]);
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttons[kButtonDpadLeft] = AxisNegativeAsButton(input.axes[4]);
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttons[kButtonDpadRight] = AxisPositiveAsButton(input.axes[4]);
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->axes[kAxisRightStickX] = input.axes[3];
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->axes[kAxisRightStickY] = input.axes[2];
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->buttonsLength = kNumButtons - 1; // no Meta on this device
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mapped->axesLength = kNumAxes;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MapperDragonRiseGeneric(
117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const blink::WebGamepad& input,
118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    blink::WebGamepad* mapped) {
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *mapped = input;
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mapped->buttons[kButtonDpadUp] = AxisNegativeAsButton(input.axes[6]);
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mapped->buttons[kButtonDpadDown] = AxisPositiveAsButton(input.axes[6]);
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mapped->buttons[kButtonDpadLeft] = AxisNegativeAsButton(input.axes[5]);
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mapped->buttons[kButtonDpadRight] = AxisPositiveAsButton(input.axes[5]);
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mapped->axes[kAxisLeftStickX] = input.axes[0];
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mapped->axes[kAxisLeftStickY] = input.axes[1];
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mapped->axes[kAxisRightStickX] = input.axes[3];
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mapped->axes[kAxisRightStickY] = input.axes[4];
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mapped->buttonsLength = kNumButtons - 1; // no Meta on this device
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mapped->axesLength = kNumAxes;
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct MappingData {
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* const vendor_id;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* const product_id;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GamepadStandardMappingFunction function;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} AvailableMappings[] = {
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // http://www.linux-usb.org/usb.ids
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  { "0079", "0006", MapperDragonRiseGeneric }, // DragonRise Generic USB
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "045e", "028e", MapperXInputStyleGamepad }, // Xbox 360 Controller
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "045e", "028f", MapperXInputStyleGamepad }, // Xbox 360 Wireless Controller
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "046d", "c21d", MapperXInputStyleGamepad }, // Logitech F310
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "046d", "c21e", MapperXInputStyleGamepad }, // Logitech F510
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "046d", "c21f", MapperXInputStyleGamepad }, // Logitech F710
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "054c", "0268", MapperPlaystationSixAxis }, // Playstation SIXAXIS
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "0925", "0005", MapperLakeviewResearch }, // SmartJoy PLUS Adapter
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "0925", "8866", MapperLakeviewResearch }, // WiseGroup MP-8866
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { "0e8f", "0003", MapperXGEAR }, // XFXforce XGEAR PS2 Controller
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GamepadStandardMappingFunction GetGamepadStandardMappingFunction(
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::StringPiece& vendor_id,
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::StringPiece& product_id) {
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(AvailableMappings); ++i) {
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MappingData& item = AvailableMappings[i];
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (vendor_id == item.vendor_id && product_id == item.product_id)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return item.function;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
165