forked from mirrors/gecko-dev
		
	
		
			
				
	
	
		
			1700 lines
		
	
	
		
			No EOL
		
	
	
		
			54 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			1700 lines
		
	
	
		
			No EOL
		
	
	
		
			54 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 | |
| /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 | |
| /* This Source Code Form is subject to the terms of the Mozilla Public
 | |
|  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 | |
|  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 | |
| 
 | |
| // Based on
 | |
| // https://cs.chromium.org/chromium/src/device/gamepad/gamepad_standard_mappings.h
 | |
| 
 | |
| // Copyright (c) 2012 The Chromium Authors. All rights reserved.
 | |
| // Use of this source code is governed by a BSD-style license that can be
 | |
| // found in the LICENSE file.
 | |
| 
 | |
| #include "mozilla/dom/GamepadRemapping.h"
 | |
| 
 | |
| namespace mozilla {
 | |
| namespace dom {
 | |
| 
 | |
| // Follow the canonical ordering recommendation for the "Standard Gamepad"
 | |
| // from https://www.w3.org/TR/gamepad/#remapping.
 | |
| enum CanonicalButtonIndex {
 | |
|   BUTTON_INDEX_PRIMARY,
 | |
|   BUTTON_INDEX_SECONDARY,
 | |
|   BUTTON_INDEX_TERTIARY,
 | |
|   BUTTON_INDEX_QUATERNARY,
 | |
|   BUTTON_INDEX_LEFT_SHOULDER,
 | |
|   BUTTON_INDEX_RIGHT_SHOULDER,
 | |
|   BUTTON_INDEX_LEFT_TRIGGER,
 | |
|   BUTTON_INDEX_RIGHT_TRIGGER,
 | |
|   BUTTON_INDEX_BACK_SELECT,
 | |
|   BUTTON_INDEX_START,
 | |
|   BUTTON_INDEX_LEFT_THUMBSTICK,
 | |
|   BUTTON_INDEX_RIGHT_THUMBSTICK,
 | |
|   BUTTON_INDEX_DPAD_UP,
 | |
|   BUTTON_INDEX_DPAD_DOWN,
 | |
|   BUTTON_INDEX_DPAD_LEFT,
 | |
|   BUTTON_INDEX_DPAD_RIGHT,
 | |
|   BUTTON_INDEX_META,
 | |
|   BUTTON_INDEX_COUNT
 | |
| };
 | |
| 
 | |
| enum CanonicalAxisIndex {
 | |
|   AXIS_INDEX_LEFT_STICK_X,
 | |
|   AXIS_INDEX_LEFT_STICK_Y,
 | |
|   AXIS_INDEX_RIGHT_STICK_X,
 | |
|   AXIS_INDEX_RIGHT_STICK_Y,
 | |
|   AXIS_INDEX_COUNT
 | |
| };
 | |
| 
 | |
| float NormalizeTouch(long aValue, long aMin, long aMax) {
 | |
|   return (2.f * (aValue - aMin) / static_cast<float>(aMax - aMin)) - 1.f;
 | |
| }
 | |
| 
 | |
| bool AxisNegativeAsButton(float input) {
 | |
|   const float value = (input < -0.5f) ? 1.f : 0.f;
 | |
|   return value > 0.1f;
 | |
| }
 | |
| 
 | |
| bool AxisPositiveAsButton(float input) {
 | |
|   const float value = (input > 0.5f) ? 1.f : 0.f;
 | |
|   return value > 0.1f;
 | |
| }
 | |
| 
 | |
| void FetchDpadFromAxis(uint32_t aIndex, double dir) {
 | |
|   bool up = false;
 | |
|   bool right = false;
 | |
|   bool down = false;
 | |
|   bool left = false;
 | |
| 
 | |
|   // Dpad is mapped as a direction on one axis, where -1 is up and it
 | |
|   // increases clockwise to 1, which is up + left. It's set to a large (> 1.f)
 | |
|   // number when nothing is depressed, except on start up, sometimes it's 0.0
 | |
|   // for no data, rather than the large number.
 | |
|   if (dir != 0.0f) {
 | |
|     up = (dir >= -1.f && dir < -0.7f) || (dir >= .95f && dir <= 1.f);
 | |
|     right = dir >= -.75f && dir < -.1f;
 | |
|     down = dir >= -.2f && dir < .45f;
 | |
|     left = dir >= .4f && dir <= 1.f;
 | |
|   }
 | |
| 
 | |
|   RefPtr<GamepadPlatformService> service =
 | |
|       GamepadPlatformService::GetParentService();
 | |
|   if (!service) {
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   service->NewButtonEvent(aIndex, BUTTON_INDEX_DPAD_UP, up);
 | |
|   service->NewButtonEvent(aIndex, BUTTON_INDEX_DPAD_RIGHT, right);
 | |
|   service->NewButtonEvent(aIndex, BUTTON_INDEX_DPAD_DOWN, down);
 | |
|   service->NewButtonEvent(aIndex, BUTTON_INDEX_DPAD_LEFT, left);
 | |
| }
 | |
| 
 | |
| class DefaultRemapper final : public GamepadRemapper {
 | |
|  public:
 | |
|   virtual uint32_t GetAxisCount() const override { return numAxes; }
 | |
| 
 | |
|   virtual uint32_t GetButtonCount() const override { return numButtons; }
 | |
| 
 | |
|   virtual void SetAxisCount(uint32_t aAxisCount) override {
 | |
|     numAxes = aAxisCount;
 | |
|   }
 | |
| 
 | |
|   virtual void SetButtonCount(uint32_t aButtonCount) override {
 | |
|     numButtons = aButtonCount;
 | |
|   }
 | |
| 
 | |
|   virtual GamepadMappingType GetMappingType() const override {
 | |
|     return GamepadMappingType::_empty;
 | |
|   }
 | |
| 
 | |
|   virtual void RemapAxisMoveEvent(uint32_t aIndex, uint32_t aAxis,
 | |
|                                   double aValue) const override {
 | |
|     if (GetAxisCount() <= aAxis) {
 | |
|       NS_WARNING(
 | |
|           nsPrintfCString("Axis idx '%d' doesn't support in DefaultRemapper().",
 | |
|                           aAxis)
 | |
|               .get());
 | |
|       return;
 | |
|     }
 | |
|     RefPtr<GamepadPlatformService> service =
 | |
|         GamepadPlatformService::GetParentService();
 | |
|     if (!service) {
 | |
|       return;
 | |
|     }
 | |
|     service->NewAxisMoveEvent(aIndex, aAxis, aValue);
 | |
|   }
 | |
| 
 | |
|   virtual void RemapButtonEvent(uint32_t aIndex, uint32_t aButton,
 | |
|                                 bool aPressed) const override {
 | |
|     if (GetButtonCount() <= aButton) {
 | |
|       NS_WARNING(
 | |
|           nsPrintfCString(
 | |
|               "Button idx '%d' doesn't support in DefaultRemapper().", aButton)
 | |
|               .get());
 | |
|       return;
 | |
|     }
 | |
|     RefPtr<GamepadPlatformService> service =
 | |
|         GamepadPlatformService::GetParentService();
 | |
|     if (!service) {
 | |
|       return;
 | |
|     }
 | |
|     service->NewButtonEvent(aIndex, aButton, aPressed);
 | |
|   }
 | |
| 
 | |
|  private:
 | |
|   uint32_t numAxes;
 | |
|   uint32_t numButtons;
 | |
| };
 | |
| 
 | |
| class ADT1Remapper final : public GamepadRemapper {
 | |
|  public:
 | |
|   virtual uint32_t GetAxisCount() const override { return AXIS_INDEX_COUNT; }
 | |
| 
 | |
|   virtual uint32_t GetButtonCount() const override {
 | |
|     return BUTTON_INDEX_COUNT;
 | |
|   }
 | |
| 
 | |
|   virtual void RemapAxisMoveEvent(uint32_t aIndex, uint32_t aAxis,
 | |
|                                   double aValue) const override {
 | |
|     RefPtr<GamepadPlatformService> service =
 | |
|         GamepadPlatformService::GetParentService();
 | |
|     if (!service) {
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     switch (aAxis) {
 | |
|       case 0:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_LEFT_STICK_X, aValue);
 | |
|         break;
 | |
|       case 1:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_LEFT_STICK_Y, aValue);
 | |
|         break;
 | |
|       case 2:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_RIGHT_STICK_X, aValue);
 | |
|         break;
 | |
|       case 3:
 | |
|         service->NewButtonEvent(aIndex, BUTTON_INDEX_RIGHT_TRIGGER,
 | |
|                                 aValue > 0.1f);
 | |
|         break;
 | |
|       case 4:
 | |
|         service->NewButtonEvent(aIndex, BUTTON_INDEX_LEFT_TRIGGER,
 | |
|                                 aValue > 0.1f);
 | |
|         break;
 | |
|       case 5:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_RIGHT_STICK_Y, aValue);
 | |
|         break;
 | |
|       case 9:
 | |
|         FetchDpadFromAxis(aIndex, aValue);
 | |
|         break;
 | |
|       default:
 | |
|         NS_WARNING(
 | |
|             nsPrintfCString("Axis idx '%d' doesn't support in ADT1Remapper().",
 | |
|                             aAxis)
 | |
|                 .get());
 | |
|         break;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   virtual void RemapButtonEvent(uint32_t aIndex, uint32_t aButton,
 | |
|                                 bool aPressed) const override {
 | |
|     RefPtr<GamepadPlatformService> service =
 | |
|         GamepadPlatformService::GetParentService();
 | |
|     if (!service) {
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     if (GetButtonCount() <= aButton) {
 | |
|       NS_WARNING(
 | |
|           nsPrintfCString("Button idx '%d' doesn't support in ADT1Remapper().",
 | |
|                           aButton)
 | |
|               .get());
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     const std::map<uint32_t, uint32_t> buttonMapping = {
 | |
|         {3, BUTTON_INDEX_TERTIARY},
 | |
|         {4, BUTTON_INDEX_QUATERNARY},
 | |
|         {6, BUTTON_INDEX_LEFT_SHOULDER},
 | |
|         {7, BUTTON_INDEX_RIGHT_SHOULDER},
 | |
|         {12, BUTTON_INDEX_META},
 | |
|         {13, BUTTON_INDEX_LEFT_THUMBSTICK},
 | |
|         {14, BUTTON_INDEX_RIGHT_THUMBSTICK}};
 | |
| 
 | |
|     auto find = buttonMapping.find(aButton);
 | |
|     if (find != buttonMapping.end()) {
 | |
|       service->NewButtonEvent(aIndex, find->second, aPressed);
 | |
|     } else {
 | |
|       service->NewButtonEvent(aIndex, aButton, aPressed);
 | |
|     }
 | |
|   }
 | |
| };
 | |
| 
 | |
| class TwoAxesEightKeysRemapper final : public GamepadRemapper {
 | |
|  public:
 | |
|   virtual uint32_t GetAxisCount() const override { return 0; }
 | |
| 
 | |
|   virtual uint32_t GetButtonCount() const override {
 | |
|     return BUTTON_INDEX_COUNT - 1;
 | |
|   }
 | |
| 
 | |
|   virtual void RemapAxisMoveEvent(uint32_t aIndex, uint32_t aAxis,
 | |
|                                   double aValue) const override {
 | |
|     RefPtr<GamepadPlatformService> service =
 | |
|         GamepadPlatformService::GetParentService();
 | |
|     if (!service) {
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     switch (aAxis) {
 | |
|       case 0:
 | |
|         service->NewButtonEvent(aIndex, BUTTON_INDEX_DPAD_LEFT,
 | |
|                                 AxisNegativeAsButton(aValue));
 | |
|         service->NewButtonEvent(aIndex, BUTTON_INDEX_DPAD_RIGHT,
 | |
|                                 AxisPositiveAsButton(aValue));
 | |
|         break;
 | |
|       case 1:
 | |
|         service->NewButtonEvent(aIndex, BUTTON_INDEX_DPAD_UP,
 | |
|                                 AxisNegativeAsButton(aValue));
 | |
|         service->NewButtonEvent(aIndex, BUTTON_INDEX_DPAD_DOWN,
 | |
|                                 AxisPositiveAsButton(aValue));
 | |
|         break;
 | |
|       default:
 | |
|         NS_WARNING(
 | |
|             nsPrintfCString(
 | |
|                 "Axis idx '%d' doesn't support in TwoAxesEightKeysRemapper().",
 | |
|                 aAxis)
 | |
|                 .get());
 | |
|         break;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   virtual void RemapButtonEvent(uint32_t aIndex, uint32_t aButton,
 | |
|                                 bool aPressed) const override {
 | |
|     RefPtr<GamepadPlatformService> service =
 | |
|         GamepadPlatformService::GetParentService();
 | |
|     if (!service) {
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     if (GetButtonCount() <= aButton) {
 | |
|       NS_WARNING(
 | |
|           nsPrintfCString(
 | |
|               "Button idx '%d' doesn't support in TwoAxesEightKeysRemapper().",
 | |
|               aButton)
 | |
|               .get());
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     const std::map<uint32_t, uint32_t> buttonMapping = {
 | |
|         {0, BUTTON_INDEX_QUATERNARY},
 | |
|         {2, BUTTON_INDEX_PRIMARY},
 | |
|         {3, BUTTON_INDEX_TERTIARY}};
 | |
| 
 | |
|     auto find = buttonMapping.find(aButton);
 | |
|     if (find != buttonMapping.end()) {
 | |
|       service->NewButtonEvent(aIndex, find->second, aPressed);
 | |
|     } else {
 | |
|       service->NewButtonEvent(aIndex, aButton, aPressed);
 | |
|     }
 | |
|   }
 | |
| };
 | |
| 
 | |
| class StadiaControllerRemapper final : public GamepadRemapper {
 | |
|  public:
 | |
|   virtual uint32_t GetAxisCount() const override { return AXIS_INDEX_COUNT; }
 | |
| 
 | |
|   virtual uint32_t GetButtonCount() const override {
 | |
|     return STADIA_BUTTON_COUNT;
 | |
|   }
 | |
| 
 | |
|   virtual void RemapAxisMoveEvent(uint32_t aIndex, uint32_t aAxis,
 | |
|                                   double aValue) const override {
 | |
|     RefPtr<GamepadPlatformService> service =
 | |
|         GamepadPlatformService::GetParentService();
 | |
|     if (!service) {
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     switch (aAxis) {
 | |
|       case 0:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_LEFT_STICK_X, aValue);
 | |
|         break;
 | |
|       case 1:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_LEFT_STICK_Y, aValue);
 | |
|         break;
 | |
|       case 2:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_RIGHT_STICK_X, aValue);
 | |
|         break;
 | |
|       case 3:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_RIGHT_STICK_Y, aValue);
 | |
|         break;
 | |
|       case 4:
 | |
|         service->NewButtonEvent(aIndex, BUTTON_INDEX_LEFT_TRIGGER, aValue);
 | |
|         break;
 | |
|       case 5:
 | |
|         service->NewButtonEvent(aIndex, BUTTON_INDEX_RIGHT_TRIGGER, aValue);
 | |
|         break;
 | |
|       default:
 | |
|         NS_WARNING(
 | |
|             nsPrintfCString(
 | |
|                 "Axis idx '%d' doesn't support in StadiaControllerRemapper().",
 | |
|                 aAxis)
 | |
|                 .get());
 | |
|         break;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   virtual void RemapButtonEvent(uint32_t aIndex, uint32_t aButton,
 | |
|                                 bool aPressed) const override {
 | |
|     RefPtr<GamepadPlatformService> service =
 | |
|         GamepadPlatformService::GetParentService();
 | |
|     if (!service) {
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     if (STADIA_BUTTON_COUNT <= aButton) {
 | |
|       NS_WARNING(
 | |
|           nsPrintfCString(
 | |
|               "Button idx '%d' doesn't support in StadiaControllerRemapper().",
 | |
|               aButton)
 | |
|               .get());
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     service->NewButtonEvent(aIndex, aButton, aPressed);
 | |
|   }
 | |
| 
 | |
|  private:
 | |
|   enum STADIAButtons {
 | |
|     STADIA_BUTTON_EXTRA1 = BUTTON_INDEX_COUNT,
 | |
|     STADIA_BUTTON_EXTRA2,
 | |
|     STADIA_BUTTON_COUNT
 | |
|   };
 | |
| };
 | |
| 
 | |
| class Playstation3Remapper final : public GamepadRemapper {
 | |
|  public:
 | |
|   Playstation3Remapper() = default;
 | |
| 
 | |
|   uint32_t GetAxisCount() const override { return AXIS_INDEX_COUNT; }
 | |
| 
 | |
|   uint32_t GetButtonCount() const override { return BUTTON_INDEX_COUNT; }
 | |
| 
 | |
|   void RemapAxisMoveEvent(uint32_t aIndex, uint32_t aAxis,
 | |
|                           double aValue) const override {
 | |
|     RefPtr<GamepadPlatformService> service =
 | |
|         GamepadPlatformService::GetParentService();
 | |
|     if (!service) {
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     switch (aAxis) {
 | |
|       case 0:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_LEFT_STICK_X, aValue);
 | |
|         break;
 | |
|       case 1:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_LEFT_STICK_Y, aValue);
 | |
|         break;
 | |
|       case 2:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_RIGHT_STICK_X, aValue);
 | |
|         break;
 | |
|       case 5:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_RIGHT_STICK_Y, aValue);
 | |
|         break;
 | |
|       default:
 | |
|         NS_WARNING(
 | |
|             nsPrintfCString(
 | |
|                 "Axis idx '%d' doesn't support in Dualshock4Remapper().", aAxis)
 | |
|                 .get());
 | |
|         break;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   void RemapButtonEvent(uint32_t aIndex, uint32_t aButton,
 | |
|                         bool aPressed) const override {
 | |
|     RefPtr<GamepadPlatformService> service =
 | |
|         GamepadPlatformService::GetParentService();
 | |
|     if (!service) {
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     const std::vector<uint32_t> buttonMapping = {BUTTON_INDEX_BACK_SELECT,
 | |
|                                                  BUTTON_INDEX_LEFT_THUMBSTICK,
 | |
|                                                  BUTTON_INDEX_RIGHT_THUMBSTICK,
 | |
|                                                  BUTTON_INDEX_START,
 | |
|                                                  BUTTON_INDEX_DPAD_UP,
 | |
|                                                  BUTTON_INDEX_DPAD_RIGHT,
 | |
|                                                  BUTTON_INDEX_DPAD_DOWN,
 | |
|                                                  BUTTON_INDEX_DPAD_LEFT,
 | |
|                                                  BUTTON_INDEX_LEFT_TRIGGER,
 | |
|                                                  BUTTON_INDEX_RIGHT_TRIGGER,
 | |
|                                                  BUTTON_INDEX_LEFT_SHOULDER,
 | |
|                                                  BUTTON_INDEX_RIGHT_SHOULDER,
 | |
|                                                  BUTTON_INDEX_QUATERNARY,
 | |
|                                                  BUTTON_INDEX_SECONDARY,
 | |
|                                                  BUTTON_INDEX_PRIMARY,
 | |
|                                                  BUTTON_INDEX_TERTIARY,
 | |
|                                                  BUTTON_INDEX_META};
 | |
| 
 | |
|     if (buttonMapping.size() <= aButton) {
 | |
|       NS_WARNING(
 | |
|           nsPrintfCString(
 | |
|               "Button idx '%d' doesn't support in Playstation3Remapper().",
 | |
|               aButton)
 | |
|               .get());
 | |
|       return;
 | |
|     }
 | |
|     service->NewButtonEvent(aIndex, buttonMapping[aButton], aPressed);
 | |
|   }
 | |
| };
 | |
| 
 | |
| class Dualshock4Remapper final : public GamepadRemapper {
 | |
|  public:
 | |
|   Dualshock4Remapper() {
 | |
|     mLastTouches.SetLength(TOUCH_EVENT_COUNT);
 | |
|     mLastTouchId.SetLength(TOUCH_EVENT_COUNT);
 | |
|   }
 | |
| 
 | |
|   virtual uint32_t GetAxisCount() const override { return AXIS_INDEX_COUNT; }
 | |
| 
 | |
|   virtual uint32_t GetButtonCount() const override {
 | |
|     return DUALSHOCK_BUTTON_COUNT;
 | |
|   }
 | |
| 
 | |
|   virtual uint32_t GetLightIndicatorCount() const override {
 | |
|     return LIGHT_INDICATOR_COUNT;
 | |
|   }
 | |
| 
 | |
|   virtual void GetLightIndicators(
 | |
|       nsTArray<GamepadLightIndicatorType>& aTypes) const override {
 | |
|     const uint32_t len = GetLightIndicatorCount();
 | |
|     aTypes.SetLength(len);
 | |
|     for (uint32_t i = 0; i < len; ++i) {
 | |
|       aTypes[i] = GamepadLightIndicatorType::Rgb;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   virtual uint32_t GetTouchEventCount() const override {
 | |
|     return TOUCH_EVENT_COUNT;
 | |
|   }
 | |
| 
 | |
|   virtual void GetLightColorReport(
 | |
|       uint8_t aRed, uint8_t aGreen, uint8_t aBlue,
 | |
|       std::vector<uint8_t>& aReport) const override {
 | |
|     const size_t report_length = 32;
 | |
|     aReport.resize(report_length);
 | |
|     aReport.assign(report_length, 0);
 | |
| 
 | |
|     aReport[0] = 0x05;  // report ID USB only
 | |
|     aReport[1] = 0x02;  // LED only
 | |
|     aReport[6] = aRed;
 | |
|     aReport[7] = aGreen;
 | |
|     aReport[8] = aBlue;
 | |
|   }
 | |
| 
 | |
|   virtual uint32_t GetMaxInputReportLength() const override {
 | |
|     return MAX_INPUT_LEN;
 | |
|   }
 | |
| 
 | |
|   virtual void ProcessTouchData(uint32_t aIndex, void* aInput) override {
 | |
|     nsTArray<GamepadTouchState> touches(TOUCH_EVENT_COUNT);
 | |
|     touches.SetLength(TOUCH_EVENT_COUNT);
 | |
|     uint8_t* rawData = (uint8_t*)aInput;
 | |
| 
 | |
|     const uint32_t kTouchDimensionX = 1920;
 | |
|     const uint32_t kTouchDimensionY = 942;
 | |
|     bool touch0Pressed = (((rawData[35] & 0xff) >> 7) == 0);
 | |
|     bool touch1Pressed = (((rawData[39] & 0xff) >> 7) == 0);
 | |
| 
 | |
|     if ((touch0Pressed && (rawData[35] & 0xff) < mLastTouchId[0]) ||
 | |
|         (touch1Pressed && (rawData[39] & 0xff) < mLastTouchId[1])) {
 | |
|       mTouchIdBase += 128;
 | |
|     }
 | |
| 
 | |
|     if (touch0Pressed) {
 | |
|       touches[0].touchId = mTouchIdBase + (rawData[35] & 0x7f);
 | |
|       touches[0].surfaceId = 0;
 | |
|       touches[0].position[0] = NormalizeTouch(
 | |
|           ((rawData[37] & 0xf) << 8) | rawData[36], 0, (kTouchDimensionX - 1));
 | |
|       touches[0].position[1] =
 | |
|           NormalizeTouch(rawData[38] << 4 | ((rawData[37] & 0xf0) >> 4), 0,
 | |
|                          (kTouchDimensionY - 1));
 | |
|       touches[0].surfaceDimensions[0] = kTouchDimensionX;
 | |
|       touches[0].surfaceDimensions[1] = kTouchDimensionY;
 | |
|       touches[0].isSurfaceDimensionsValid = true;
 | |
|       mLastTouchId[0] = rawData[35] & 0x7f;
 | |
|     }
 | |
|     if (touch1Pressed) {
 | |
|       touches[1].touchId = mTouchIdBase + (rawData[39] & 0x7f);
 | |
|       touches[1].surfaceId = 0;
 | |
|       touches[1].position[0] =
 | |
|           NormalizeTouch((((rawData[41] & 0xf) << 8) | rawData[40]) + 1, 0,
 | |
|                          (kTouchDimensionX - 1));
 | |
|       touches[1].position[1] =
 | |
|           NormalizeTouch(rawData[42] << 4 | ((rawData[41] & 0xf0) >> 4), 0,
 | |
|                          (kTouchDimensionY - 1));
 | |
|       touches[1].surfaceDimensions[0] = kTouchDimensionX;
 | |
|       touches[1].surfaceDimensions[1] = kTouchDimensionY;
 | |
|       touches[1].isSurfaceDimensionsValid = true;
 | |
|       mLastTouchId[1] = rawData[39] & 0x7f;
 | |
|     }
 | |
| 
 | |
|     RefPtr<GamepadPlatformService> service =
 | |
|         GamepadPlatformService::GetParentService();
 | |
|     if (!service) {
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     // Avoid to send duplicate untouched events to the gamepad service.
 | |
|     if ((mLastTouches[0] != touch0Pressed) || touch0Pressed) {
 | |
|       service->NewMultiTouchEvent(aIndex, 0, touches[0]);
 | |
|     }
 | |
|     if ((mLastTouches[1] != touch1Pressed) || touch1Pressed) {
 | |
|       service->NewMultiTouchEvent(aIndex, 1, touches[1]);
 | |
|     }
 | |
|     mLastTouches[0] = touch0Pressed;
 | |
|     mLastTouches[1] = touch1Pressed;
 | |
|   }
 | |
| 
 | |
|   virtual void RemapAxisMoveEvent(uint32_t aIndex, uint32_t aAxis,
 | |
|                                   double aValue) const override {
 | |
|     RefPtr<GamepadPlatformService> service =
 | |
|         GamepadPlatformService::GetParentService();
 | |
|     if (!service) {
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     switch (aAxis) {
 | |
|       case 0:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_LEFT_STICK_X, aValue);
 | |
|         break;
 | |
|       case 1:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_LEFT_STICK_Y, aValue);
 | |
|         break;
 | |
|       case 2:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_RIGHT_STICK_X, aValue);
 | |
|         break;
 | |
|       case 3:
 | |
|         service->NewButtonEvent(aIndex, BUTTON_INDEX_LEFT_TRIGGER,
 | |
|                                 aValue > 0.1f);
 | |
|         break;
 | |
|       case 4:
 | |
|         service->NewButtonEvent(aIndex, BUTTON_INDEX_RIGHT_TRIGGER,
 | |
|                                 aValue > 0.1f);
 | |
|         break;
 | |
|       case 5:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_RIGHT_STICK_Y, aValue);
 | |
|         break;
 | |
|       case 9:
 | |
|         FetchDpadFromAxis(aIndex, aValue);
 | |
|         break;
 | |
|       default:
 | |
|         NS_WARNING(
 | |
|             nsPrintfCString(
 | |
|                 "Axis idx '%d' doesn't support in Dualshock4Remapper().", aAxis)
 | |
|                 .get());
 | |
|         break;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   virtual void RemapButtonEvent(uint32_t aIndex, uint32_t aButton,
 | |
|                                 bool aPressed) const override {
 | |
|     RefPtr<GamepadPlatformService> service =
 | |
|         GamepadPlatformService::GetParentService();
 | |
|     if (!service) {
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     const std::vector<uint32_t> buttonMapping = {BUTTON_INDEX_TERTIARY,
 | |
|                                                  BUTTON_INDEX_PRIMARY,
 | |
|                                                  BUTTON_INDEX_SECONDARY,
 | |
|                                                  BUTTON_INDEX_QUATERNARY,
 | |
|                                                  BUTTON_INDEX_LEFT_SHOULDER,
 | |
|                                                  BUTTON_INDEX_RIGHT_SHOULDER,
 | |
|                                                  BUTTON_INDEX_LEFT_TRIGGER,
 | |
|                                                  BUTTON_INDEX_RIGHT_TRIGGER,
 | |
|                                                  BUTTON_INDEX_BACK_SELECT,
 | |
|                                                  BUTTON_INDEX_START,
 | |
|                                                  BUTTON_INDEX_LEFT_THUMBSTICK,
 | |
|                                                  BUTTON_INDEX_RIGHT_THUMBSTICK,
 | |
|                                                  BUTTON_INDEX_META,
 | |
|                                                  DUALSHOCK_BUTTON_TOUCHPAD};
 | |
| 
 | |
|     if (buttonMapping.size() <= aButton) {
 | |
|       NS_WARNING(nsPrintfCString(
 | |
|                      "Button idx '%d' doesn't support in Dualshock4Remapper().",
 | |
|                      aButton)
 | |
|                      .get());
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     service->NewButtonEvent(aIndex, buttonMapping[aButton], aPressed);
 | |
|   }
 | |
| 
 | |
|  private:
 | |
|   enum Dualshock4Buttons {
 | |
|     DUALSHOCK_BUTTON_TOUCHPAD = BUTTON_INDEX_COUNT,
 | |
|     DUALSHOCK_BUTTON_COUNT
 | |
|   };
 | |
| 
 | |
|   static const uint32_t LIGHT_INDICATOR_COUNT = 1;
 | |
|   static const uint32_t TOUCH_EVENT_COUNT = 2;
 | |
|   static const uint32_t MAX_INPUT_LEN = 68;
 | |
| 
 | |
|   nsTArray<unsigned long> mLastTouchId;
 | |
|   nsTArray<bool> mLastTouches;
 | |
|   unsigned long mTouchIdBase = 0;
 | |
| };
 | |
| 
 | |
| class LogitechDInputRemapper final : public GamepadRemapper {
 | |
|  public:
 | |
|   virtual uint32_t GetAxisCount() const override { return AXIS_INDEX_COUNT; }
 | |
| 
 | |
|   virtual uint32_t GetButtonCount() const override {
 | |
|     // The Logitech button (BUTTON_INDEX_META) is not accessible through the
 | |
|     // device's D-mode.
 | |
|     return BUTTON_INDEX_COUNT - 1;
 | |
|   }
 | |
| 
 | |
|   virtual void RemapAxisMoveEvent(uint32_t aIndex, uint32_t aAxis,
 | |
|                                   double aValue) const override {
 | |
|     RefPtr<GamepadPlatformService> service =
 | |
|         GamepadPlatformService::GetParentService();
 | |
|     if (!service) {
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     switch (aAxis) {
 | |
|       case 0:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_LEFT_STICK_X, aValue);
 | |
|         break;
 | |
|       case 1:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_LEFT_STICK_Y, aValue);
 | |
|         break;
 | |
|       case 2:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_RIGHT_STICK_X, aValue);
 | |
|         break;
 | |
|       case 5:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_RIGHT_STICK_Y, aValue);
 | |
|         break;
 | |
|       case 9:
 | |
|         FetchDpadFromAxis(aIndex, aValue);
 | |
|         break;
 | |
|       default:
 | |
|         NS_WARNING(
 | |
|             nsPrintfCString(
 | |
|                 "Axis idx '%d' doesn't support in LogitechDInputRemapper().",
 | |
|                 aAxis)
 | |
|                 .get());
 | |
|         break;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   virtual void RemapButtonEvent(uint32_t aIndex, uint32_t aButton,
 | |
|                                 bool aPressed) const override {
 | |
|     RefPtr<GamepadPlatformService> service =
 | |
|         GamepadPlatformService::GetParentService();
 | |
|     if (!service) {
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     if (GetButtonCount() <= aButton) {
 | |
|       NS_WARNING(
 | |
|           nsPrintfCString(
 | |
|               "Button idx '%d' doesn't support in LogitechDInputRemapper().",
 | |
|               aButton)
 | |
|               .get());
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     const std::map<uint32_t, uint32_t> buttonMapping = {
 | |
|         {0, BUTTON_INDEX_TERTIARY},
 | |
|         {1, BUTTON_INDEX_PRIMARY},
 | |
|         {2, BUTTON_INDEX_SECONDARY}};
 | |
| 
 | |
|     auto find = buttonMapping.find(aButton);
 | |
|     if (find != buttonMapping.end()) {
 | |
|       service->NewButtonEvent(aIndex, find->second, aPressed);
 | |
|     } else {
 | |
|       service->NewButtonEvent(aIndex, aButton, aPressed);
 | |
|     }
 | |
|   }
 | |
| };
 | |
| 
 | |
| class SwitchJoyConRemapper final : public GamepadRemapper {
 | |
|  public:
 | |
|   virtual uint32_t GetAxisCount() const override { return 2; }
 | |
| 
 | |
|   virtual uint32_t GetButtonCount() const override {
 | |
|     return BUTTON_INDEX_COUNT;
 | |
|   }
 | |
| 
 | |
|   virtual void RemapAxisMoveEvent(uint32_t aIndex, uint32_t aAxis,
 | |
|                                   double aValue) const override {
 | |
|     if (GetAxisCount() <= aAxis) {
 | |
|       NS_WARNING(
 | |
|           nsPrintfCString(
 | |
|               "Axis idx '%d' doesn't support in SwitchJoyConRemapper().", aAxis)
 | |
|               .get());
 | |
|       return;
 | |
|     }
 | |
|     RefPtr<GamepadPlatformService> service =
 | |
|         GamepadPlatformService::GetParentService();
 | |
|     if (!service) {
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     service->NewAxisMoveEvent(aIndex, AXIS_INDEX_LEFT_STICK_X, aValue);
 | |
|   }
 | |
| 
 | |
|   virtual void RemapButtonEvent(uint32_t aIndex, uint32_t aButton,
 | |
|                                 bool aPressed) const override {
 | |
|     RefPtr<GamepadPlatformService> service =
 | |
|         GamepadPlatformService::GetParentService();
 | |
|     if (!service) {
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     service->NewButtonEvent(aIndex, aButton, aPressed);
 | |
|   }
 | |
| };
 | |
| 
 | |
| class SwitchProRemapper final : public GamepadRemapper {
 | |
|  public:
 | |
|   virtual uint32_t GetAxisCount() const override { return AXIS_INDEX_COUNT; }
 | |
| 
 | |
|   virtual uint32_t GetButtonCount() const override {
 | |
|     // The Switch Pro controller has a Capture button that has no equivalent in
 | |
|     // the Standard Gamepad.
 | |
|     return SWITCHPRO_BUTTON_COUNT;
 | |
|   }
 | |
| 
 | |
|   virtual void RemapAxisMoveEvent(uint32_t aIndex, uint32_t aAxis,
 | |
|                                   double aValue) const override {
 | |
|     if (GetAxisCount() <= aAxis) {
 | |
|       NS_WARNING(
 | |
|           nsPrintfCString(
 | |
|               "Axis idx '%d' doesn't support in SwitchProRemapper().", aAxis)
 | |
|               .get());
 | |
|       return;
 | |
|     }
 | |
|     RefPtr<GamepadPlatformService> service =
 | |
|         GamepadPlatformService::GetParentService();
 | |
|     if (!service) {
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     service->NewAxisMoveEvent(aIndex, AXIS_INDEX_LEFT_STICK_X, aValue);
 | |
|   }
 | |
| 
 | |
|   virtual void RemapButtonEvent(uint32_t aIndex, uint32_t aButton,
 | |
|                                 bool aPressed) const override {
 | |
|     RefPtr<GamepadPlatformService> service =
 | |
|         GamepadPlatformService::GetParentService();
 | |
|     if (!service) {
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     service->NewButtonEvent(aIndex, aButton, aPressed);
 | |
|   }
 | |
| 
 | |
|  private:
 | |
|   enum SwitchProButtons {
 | |
|     SWITCHPRO_BUTTON_EXTRA = BUTTON_INDEX_COUNT,
 | |
|     SWITCHPRO_BUTTON_COUNT
 | |
|   };
 | |
| };
 | |
| 
 | |
| class NvShieldRemapper final : public GamepadRemapper {
 | |
|  public:
 | |
|   virtual uint32_t GetAxisCount() const override { return AXIS_INDEX_COUNT; }
 | |
| 
 | |
|   virtual uint32_t GetButtonCount() const override {
 | |
|     return SHIELD_BUTTON_COUNT;
 | |
|   }
 | |
| 
 | |
|   virtual void RemapAxisMoveEvent(uint32_t aIndex, uint32_t aAxis,
 | |
|                                   double aValue) const override {
 | |
|     RefPtr<GamepadPlatformService> service =
 | |
|         GamepadPlatformService::GetParentService();
 | |
|     if (!service) {
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     switch (aAxis) {
 | |
|       case 0:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_LEFT_STICK_X, aValue);
 | |
|         break;
 | |
|       case 1:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_LEFT_STICK_Y, aValue);
 | |
|         break;
 | |
|       case 2:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_RIGHT_STICK_X, aValue);
 | |
|         break;
 | |
|       case 3:
 | |
|         service->NewButtonEvent(aIndex, BUTTON_INDEX_RIGHT_TRIGGER,
 | |
|                                 aValue > 0.1f);
 | |
|         break;
 | |
|       case 4:
 | |
|         service->NewButtonEvent(aIndex, BUTTON_INDEX_LEFT_TRIGGER,
 | |
|                                 aValue > 0.1f);
 | |
|         break;
 | |
|       case 5:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_RIGHT_STICK_Y, aValue);
 | |
|         break;
 | |
|       case 9:
 | |
|         FetchDpadFromAxis(aIndex, aValue);
 | |
|         break;
 | |
|       default:
 | |
|         NS_WARNING(
 | |
|             nsPrintfCString(
 | |
|                 "Axis idx '%d' doesn't support in NvShieldRemapper().", aAxis)
 | |
|                 .get());
 | |
|         break;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   virtual void RemapButtonEvent(uint32_t aIndex, uint32_t aButton,
 | |
|                                 bool aPressed) const override {
 | |
|     RefPtr<GamepadPlatformService> service =
 | |
|         GamepadPlatformService::GetParentService();
 | |
|     if (!service) {
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     if (GetButtonCount() <= aButton) {
 | |
|       NS_WARNING(
 | |
|           nsPrintfCString(
 | |
|               "Button idx '%d' doesn't support in NvShieldRemapper().", aButton)
 | |
|               .get());
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     const std::map<uint32_t, uint32_t> buttonMapping = {
 | |
|         {2, BUTTON_INDEX_META},
 | |
|         {3, BUTTON_INDEX_TERTIARY},
 | |
|         {4, BUTTON_INDEX_QUATERNARY},
 | |
|         {5, SHIELD_BUTTON_CIRCLE},
 | |
|         {6, BUTTON_INDEX_LEFT_SHOULDER},
 | |
|         {7, BUTTON_INDEX_RIGHT_SHOULDER},
 | |
|         {9, BUTTON_INDEX_BACK_SELECT},
 | |
|         {11, BUTTON_INDEX_START},
 | |
|         {13, BUTTON_INDEX_LEFT_THUMBSTICK},
 | |
|         {14, BUTTON_INDEX_RIGHT_THUMBSTICK}};
 | |
| 
 | |
|     auto find = buttonMapping.find(aButton);
 | |
|     if (find != buttonMapping.end()) {
 | |
|       service->NewButtonEvent(aIndex, find->second, aPressed);
 | |
|     } else {
 | |
|       service->NewButtonEvent(aIndex, aButton, aPressed);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|  private:
 | |
|   enum ShieldButtons {
 | |
|     SHIELD_BUTTON_CIRCLE = BUTTON_INDEX_COUNT,
 | |
|     SHIELD_BUTTON_COUNT
 | |
|   };
 | |
| };
 | |
| 
 | |
| class NvShield2017Remapper final : public GamepadRemapper {
 | |
|  public:
 | |
|   virtual uint32_t GetAxisCount() const override { return AXIS_INDEX_COUNT; }
 | |
| 
 | |
|   virtual uint32_t GetButtonCount() const override {
 | |
|     return SHIELD2017_BUTTON_COUNT;
 | |
|   }
 | |
| 
 | |
|   virtual void RemapAxisMoveEvent(uint32_t aIndex, uint32_t aAxis,
 | |
|                                   double aValue) const override {
 | |
|     RefPtr<GamepadPlatformService> service =
 | |
|         GamepadPlatformService::GetParentService();
 | |
|     if (!service) {
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     switch (aAxis) {
 | |
|       case 0:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_LEFT_STICK_X, aValue);
 | |
|         break;
 | |
|       case 1:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_LEFT_STICK_Y, aValue);
 | |
|         break;
 | |
|       case 2:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_RIGHT_STICK_X, aValue);
 | |
|         break;
 | |
|       case 3:
 | |
|         service->NewButtonEvent(aIndex, BUTTON_INDEX_RIGHT_TRIGGER,
 | |
|                                 aValue > 0.1f);
 | |
|         break;
 | |
|       case 4:
 | |
|         service->NewButtonEvent(aIndex, BUTTON_INDEX_LEFT_TRIGGER,
 | |
|                                 aValue > 0.1f);
 | |
|         break;
 | |
|       case 5:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_RIGHT_STICK_Y, aValue);
 | |
|         break;
 | |
|       case 9:
 | |
|         FetchDpadFromAxis(aIndex, aValue);
 | |
|         break;
 | |
|       default:
 | |
|         NS_WARNING(
 | |
|             nsPrintfCString(
 | |
|                 "Axis idx '%d' doesn't support in NvShield2017Remapper().",
 | |
|                 aAxis)
 | |
|                 .get());
 | |
|         break;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   virtual void RemapButtonEvent(uint32_t aIndex, uint32_t aButton,
 | |
|                                 bool aPressed) const override {
 | |
|     RefPtr<GamepadPlatformService> service =
 | |
|         GamepadPlatformService::GetParentService();
 | |
|     if (!service) {
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     if (GetButtonCount() <= aButton) {
 | |
|       NS_WARNING(
 | |
|           nsPrintfCString(
 | |
|               "Button idx '%d' doesn't support in NvShield2017Remapper().",
 | |
|               aButton)
 | |
|               .get());
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     const std::map<uint32_t, uint32_t> buttonMapping = {
 | |
|         {2, BUTTON_INDEX_META},
 | |
|         {3, BUTTON_INDEX_TERTIARY},
 | |
|         {4, BUTTON_INDEX_QUATERNARY},
 | |
|         {5, BUTTON_INDEX_START},
 | |
|         {6, BUTTON_INDEX_LEFT_SHOULDER},
 | |
|         {7, BUTTON_INDEX_RIGHT_SHOULDER},
 | |
|         {8, BUTTON_INDEX_BACK_SELECT},
 | |
|         {11, SHIELD2017_BUTTON_PLAYPAUSE},
 | |
|         {13, BUTTON_INDEX_LEFT_THUMBSTICK},
 | |
|         {14, BUTTON_INDEX_RIGHT_THUMBSTICK}};
 | |
| 
 | |
|     auto find = buttonMapping.find(aButton);
 | |
|     if (find != buttonMapping.end()) {
 | |
|       service->NewButtonEvent(aIndex, find->second, aPressed);
 | |
|     } else {
 | |
|       service->NewButtonEvent(aIndex, aButton, aPressed);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|  private:
 | |
|   enum Shield2017Buttons {
 | |
|     SHIELD2017_BUTTON_PLAYPAUSE = BUTTON_INDEX_COUNT,
 | |
|     SHIELD2017_BUTTON_COUNT
 | |
|   };
 | |
| };
 | |
| 
 | |
| class IBuffaloRemapper final : public GamepadRemapper {
 | |
|  public:
 | |
|   virtual uint32_t GetAxisCount() const override { return 2; }
 | |
| 
 | |
|   virtual uint32_t GetButtonCount() const override {
 | |
|     return BUTTON_INDEX_COUNT - 1; /* no meta */
 | |
|   }
 | |
| 
 | |
|   virtual void RemapAxisMoveEvent(uint32_t aIndex, uint32_t aAxis,
 | |
|                                   double aValue) const override {
 | |
|     RefPtr<GamepadPlatformService> service =
 | |
|         GamepadPlatformService::GetParentService();
 | |
|     if (!service) {
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     switch (aAxis) {
 | |
|       case 0:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_LEFT_STICK_X, aValue);
 | |
|         service->NewButtonEvent(aIndex, BUTTON_INDEX_DPAD_LEFT,
 | |
|                                 AxisNegativeAsButton(aValue));
 | |
|         service->NewButtonEvent(aIndex, BUTTON_INDEX_DPAD_RIGHT,
 | |
|                                 AxisPositiveAsButton(aValue));
 | |
|         break;
 | |
|       case 1:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_LEFT_STICK_Y, aValue);
 | |
|         service->NewButtonEvent(aIndex, BUTTON_INDEX_DPAD_UP,
 | |
|                                 AxisNegativeAsButton(aValue));
 | |
|         service->NewButtonEvent(aIndex, BUTTON_INDEX_DPAD_DOWN,
 | |
|                                 AxisPositiveAsButton(aValue));
 | |
|         break;
 | |
|       default:
 | |
|         NS_WARNING(
 | |
|             nsPrintfCString(
 | |
|                 "Axis idx '%d' doesn't support in IBuffaloRemapper().", aAxis)
 | |
|                 .get());
 | |
|         break;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   virtual void RemapButtonEvent(uint32_t aIndex, uint32_t aButton,
 | |
|                                 bool aPressed) const override {
 | |
|     RefPtr<GamepadPlatformService> service =
 | |
|         GamepadPlatformService::GetParentService();
 | |
|     if (!service) {
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     if (GetButtonCount() <= aButton) {
 | |
|       NS_WARNING(
 | |
|           nsPrintfCString(
 | |
|               "Button idx '%d' doesn't support in IBuffaloRemapper().", aButton)
 | |
|               .get());
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     const std::map<uint32_t, uint32_t> buttonMapping = {
 | |
|         {0, BUTTON_INDEX_SECONDARY},     {1, BUTTON_INDEX_PRIMARY},
 | |
|         {2, BUTTON_INDEX_QUATERNARY},    {3, BUTTON_INDEX_TERTIARY},
 | |
|         {5, BUTTON_INDEX_RIGHT_TRIGGER}, {6, BUTTON_INDEX_BACK_SELECT},
 | |
|         {7, BUTTON_INDEX_START}};
 | |
| 
 | |
|     auto find = buttonMapping.find(aButton);
 | |
|     if (find != buttonMapping.end()) {
 | |
|       service->NewButtonEvent(aIndex, find->second, aPressed);
 | |
|     } else {
 | |
|       service->NewButtonEvent(aIndex, aButton, aPressed);
 | |
|     }
 | |
|   }
 | |
| };
 | |
| 
 | |
| class XSkillsRemapper final : public GamepadRemapper {
 | |
|  public:
 | |
|   virtual uint32_t GetAxisCount() const override { return AXIS_INDEX_COUNT; }
 | |
| 
 | |
|   virtual uint32_t GetButtonCount() const override {
 | |
|     return GAMECUBE_BUTTON_COUNT;
 | |
|   }
 | |
| 
 | |
|   virtual void RemapAxisMoveEvent(uint32_t aIndex, uint32_t aAxis,
 | |
|                                   double aValue) const override {
 | |
|     RefPtr<GamepadPlatformService> service =
 | |
|         GamepadPlatformService::GetParentService();
 | |
|     if (!service) {
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     switch (aAxis) {
 | |
|       case 0:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_LEFT_STICK_X, aValue);
 | |
|         break;
 | |
|       case 1:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_LEFT_STICK_Y, aValue);
 | |
|         break;
 | |
|       case 2:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_RIGHT_STICK_Y, aValue);
 | |
|         break;
 | |
|       case 3:
 | |
|         service->NewButtonEvent(aIndex, BUTTON_INDEX_RIGHT_TRIGGER,
 | |
|                                 aValue > 0.1f);
 | |
|         break;
 | |
|       case 4:
 | |
|         service->NewButtonEvent(aIndex, BUTTON_INDEX_LEFT_TRIGGER,
 | |
|                                 aValue > 0.1f);
 | |
|         break;
 | |
|       case 5:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_RIGHT_STICK_X, aValue);
 | |
|         break;
 | |
|       default:
 | |
|         NS_WARNING(
 | |
|             nsPrintfCString(
 | |
|                 "Axis idx '%d' doesn't support in XSkillsRemapper().", aAxis)
 | |
|                 .get());
 | |
|         break;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   virtual void RemapButtonEvent(uint32_t aIndex, uint32_t aButton,
 | |
|                                 bool aPressed) const override {
 | |
|     RefPtr<GamepadPlatformService> service =
 | |
|         GamepadPlatformService::GetParentService();
 | |
|     if (!service) {
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     if (GetButtonCount() <= aIndex) {
 | |
|       NS_WARNING(
 | |
|           nsPrintfCString(
 | |
|               "Button idx '%d' doesn't support in XSkillsRemapper().", aButton)
 | |
|               .get());
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     const std::map<uint32_t, uint32_t> buttonMapping = {
 | |
|         {0, BUTTON_INDEX_PRIMARY},     // A
 | |
|         {1, BUTTON_INDEX_TERTIARY},    // B
 | |
|         {2, BUTTON_INDEX_SECONDARY},   // X
 | |
|         {3, BUTTON_INDEX_QUATERNARY},  // Y
 | |
|         {4, GAMECUBE_BUTTON_LEFT_TRIGGER_CLICK},
 | |
|         {5, GAMECUBE_BUTTON_RIGHT_TRIGGER_CLICK},
 | |
|         {6, BUTTON_INDEX_RIGHT_SHOULDER},
 | |
|         {7, BUTTON_INDEX_START},
 | |
|         {8, BUTTON_INDEX_DPAD_LEFT},
 | |
|         {9, BUTTON_INDEX_DPAD_RIGHT},
 | |
|         {10, BUTTON_INDEX_DPAD_DOWN},
 | |
|         {11, BUTTON_INDEX_DPAD_UP}};
 | |
| 
 | |
|     auto find = buttonMapping.find(aButton);
 | |
|     if (find != buttonMapping.end()) {
 | |
|       service->NewButtonEvent(aIndex, find->second, aPressed);
 | |
|     } else {
 | |
|       service->NewButtonEvent(aIndex, aButton, aPressed);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|  private:
 | |
|   enum GamecubeButtons {
 | |
|     GAMECUBE_BUTTON_LEFT_TRIGGER_CLICK = BUTTON_INDEX_COUNT,
 | |
|     GAMECUBE_BUTTON_RIGHT_TRIGGER_CLICK,
 | |
|     GAMECUBE_BUTTON_COUNT
 | |
|   };
 | |
| };
 | |
| 
 | |
| class BoomN64PsxRemapper final : public GamepadRemapper {
 | |
|  public:
 | |
|   virtual uint32_t GetAxisCount() const override { return AXIS_INDEX_COUNT; }
 | |
| 
 | |
|   virtual uint32_t GetButtonCount() const override {
 | |
|     return BUTTON_INDEX_COUNT - 1;  // no meta
 | |
|   }
 | |
| 
 | |
|   virtual void RemapAxisMoveEvent(uint32_t aIndex, uint32_t aAxis,
 | |
|                                   double aValue) const override {
 | |
|     RefPtr<GamepadPlatformService> service =
 | |
|         GamepadPlatformService::GetParentService();
 | |
|     if (!service) {
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     switch (aAxis) {
 | |
|       case 0:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_LEFT_STICK_X, aValue);
 | |
|         break;
 | |
|       case 1:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_LEFT_STICK_Y, aValue);
 | |
|         break;
 | |
|       case 2:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_RIGHT_STICK_X, aValue);
 | |
|         break;
 | |
|       case 5:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_RIGHT_STICK_Y, aValue);
 | |
|         break;
 | |
|       default:
 | |
|         NS_WARNING(
 | |
|             nsPrintfCString(
 | |
|                 "Axis idx '%d' doesn't support in BoomN64PsxRemapper().", aAxis)
 | |
|                 .get());
 | |
|         break;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   virtual void RemapButtonEvent(uint32_t aIndex, uint32_t aButton,
 | |
|                                 bool aPressed) const override {
 | |
|     RefPtr<GamepadPlatformService> service =
 | |
|         GamepadPlatformService::GetParentService();
 | |
|     if (!service) {
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     const std::vector<uint32_t> buttonMapping = {
 | |
|         BUTTON_INDEX_QUATERNARY,       BUTTON_INDEX_SECONDARY,
 | |
|         BUTTON_INDEX_PRIMARY,          BUTTON_INDEX_TERTIARY,
 | |
|         BUTTON_INDEX_LEFT_TRIGGER,     BUTTON_INDEX_RIGHT_TRIGGER,
 | |
|         BUTTON_INDEX_LEFT_SHOULDER,    BUTTON_INDEX_RIGHT_SHOULDER,
 | |
|         BUTTON_INDEX_BACK_SELECT,      BUTTON_INDEX_LEFT_THUMBSTICK,
 | |
|         BUTTON_INDEX_RIGHT_THUMBSTICK, BUTTON_INDEX_START,
 | |
|         BUTTON_INDEX_DPAD_UP,          BUTTON_INDEX_DPAD_RIGHT,
 | |
|         BUTTON_INDEX_DPAD_DOWN,        BUTTON_INDEX_DPAD_LEFT};
 | |
| 
 | |
|     if (buttonMapping.size() <= aButton) {
 | |
|       NS_WARNING(nsPrintfCString(
 | |
|                      "Button idx '%d' doesn't support in BoomN64PsxRemapper().",
 | |
|                      aButton)
 | |
|                      .get());
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     service->NewButtonEvent(aIndex, buttonMapping[aButton], aPressed);
 | |
|   }
 | |
| 
 | |
|  private:
 | |
|   enum GamecubeButtons {
 | |
|     GAMECUBE_BUTTON_LEFT_TRIGGER_CLICK = BUTTON_INDEX_COUNT,
 | |
|     GAMECUBE_BUTTON_RIGHT_TRIGGER_CLICK,
 | |
|     GAMECUBE_BUTTON_COUNT
 | |
|   };
 | |
| };
 | |
| 
 | |
| class AnalogGamepadRemapper final : public GamepadRemapper {
 | |
|  public:
 | |
|   virtual uint32_t GetAxisCount() const override { return AXIS_INDEX_COUNT; }
 | |
| 
 | |
|   virtual uint32_t GetButtonCount() const override {
 | |
|     return ANALOG_GAMEPAD_BUTTON_COUNT;
 | |
|   }
 | |
| 
 | |
|   virtual void RemapAxisMoveEvent(uint32_t aIndex, uint32_t aAxis,
 | |
|                                   double aValue) const override {
 | |
|     RefPtr<GamepadPlatformService> service =
 | |
|         GamepadPlatformService::GetParentService();
 | |
|     if (!service) {
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     switch (aAxis) {
 | |
|       case 0:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_LEFT_STICK_X, aValue);
 | |
|         break;
 | |
|       case 1:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_LEFT_STICK_Y, aValue);
 | |
|         break;
 | |
|       case 2:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_RIGHT_STICK_X, aValue);
 | |
|         break;
 | |
|       case 3:
 | |
|         service->NewButtonEvent(aIndex, BUTTON_INDEX_RIGHT_TRIGGER,
 | |
|                                 aValue > 0.1f);
 | |
|         break;
 | |
|       case 4:
 | |
|         service->NewButtonEvent(aIndex, BUTTON_INDEX_LEFT_TRIGGER,
 | |
|                                 aValue > 0.1f);
 | |
|         break;
 | |
|       case 5:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_RIGHT_STICK_Y, aValue);
 | |
|         break;
 | |
|       case 9:
 | |
|         FetchDpadFromAxis(aIndex, aValue);
 | |
|         break;
 | |
|       default:
 | |
|         NS_WARNING(
 | |
|             nsPrintfCString(
 | |
|                 "Axis idx '%d' doesn't support in AnalogGamepadRemapper().",
 | |
|                 aAxis)
 | |
|                 .get());
 | |
|         break;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   virtual void RemapButtonEvent(uint32_t aIndex, uint32_t aButton,
 | |
|                                 bool aPressed) const override {
 | |
|     RefPtr<GamepadPlatformService> service =
 | |
|         GamepadPlatformService::GetParentService();
 | |
|     if (!service) {
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     if (GetButtonCount() <= aButton) {
 | |
|       NS_WARNING(
 | |
|           nsPrintfCString(
 | |
|               "Button idx '%d' doesn't support in AnalogGamepadRemapper().",
 | |
|               aButton)
 | |
|               .get());
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     const std::map<uint32_t, uint32_t> buttonMapping = {
 | |
|         {3, BUTTON_INDEX_TERTIARY},
 | |
|         {4, BUTTON_INDEX_QUATERNARY},
 | |
|         {6, BUTTON_INDEX_LEFT_SHOULDER},
 | |
|         {7, BUTTON_INDEX_RIGHT_SHOULDER},
 | |
|         {10, BUTTON_INDEX_BACK_SELECT},
 | |
|         {11, BUTTON_INDEX_META},
 | |
|         {12, BUTTON_INDEX_START},
 | |
|         {13, BUTTON_INDEX_LEFT_THUMBSTICK},
 | |
|         {14, BUTTON_INDEX_RIGHT_THUMBSTICK},
 | |
|         {16, ANALOG_GAMEPAD_BUTTON_EXTRA},
 | |
|         {17, ANALOG_GAMEPAD_BUTTON_EXTRA2}};
 | |
| 
 | |
|     auto find = buttonMapping.find(aButton);
 | |
|     if (find != buttonMapping.end()) {
 | |
|       service->NewButtonEvent(aIndex, find->second, aPressed);
 | |
|     } else {
 | |
|       service->NewButtonEvent(aIndex, aButton, aPressed);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|  private:
 | |
|   enum AnalogGamepadButtons {
 | |
|     ANALOG_GAMEPAD_BUTTON_EXTRA = BUTTON_INDEX_COUNT,
 | |
|     ANALOG_GAMEPAD_BUTTON_EXTRA2,
 | |
|     ANALOG_GAMEPAD_BUTTON_COUNT
 | |
|   };
 | |
| };
 | |
| 
 | |
| class RazerServalRemapper final : public GamepadRemapper {
 | |
|  public:
 | |
|   virtual uint32_t GetAxisCount() const override { return AXIS_INDEX_COUNT; }
 | |
| 
 | |
|   virtual uint32_t GetButtonCount() const override {
 | |
|     return BUTTON_INDEX_COUNT - 1; /* no meta */
 | |
|   }
 | |
| 
 | |
|   virtual void RemapAxisMoveEvent(uint32_t aIndex, uint32_t aAxis,
 | |
|                                   double aValue) const override {
 | |
|     RefPtr<GamepadPlatformService> service =
 | |
|         GamepadPlatformService::GetParentService();
 | |
|     if (!service) {
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     switch (aAxis) {
 | |
|       case 0:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_LEFT_STICK_X, aValue);
 | |
|         break;
 | |
|       case 1:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_LEFT_STICK_Y, aValue);
 | |
|         break;
 | |
|       case 2:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_RIGHT_STICK_X, aValue);
 | |
|         break;
 | |
|       case 3:
 | |
|         service->NewButtonEvent(aIndex, BUTTON_INDEX_RIGHT_TRIGGER,
 | |
|                                 aValue > 0.1f);
 | |
|         break;
 | |
|       case 4:
 | |
|         service->NewButtonEvent(aIndex, BUTTON_INDEX_LEFT_TRIGGER,
 | |
|                                 aValue > 0.1f);
 | |
|         break;
 | |
|       case 5:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_RIGHT_STICK_Y, aValue);
 | |
|         break;
 | |
|       case 9:
 | |
|         FetchDpadFromAxis(aIndex, aValue);
 | |
|         break;
 | |
|       default:
 | |
|         NS_WARNING(
 | |
|             nsPrintfCString(
 | |
|                 "Axis idx '%d' doesn't support in RazerServalRemapper().",
 | |
|                 aAxis)
 | |
|                 .get());
 | |
|         break;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   virtual void RemapButtonEvent(uint32_t aIndex, uint32_t aButton,
 | |
|                                 bool aPressed) const override {
 | |
|     RefPtr<GamepadPlatformService> service =
 | |
|         GamepadPlatformService::GetParentService();
 | |
|     if (!service) {
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     if (GetButtonCount() <= aButton) {
 | |
|       NS_WARNING(
 | |
|           nsPrintfCString(
 | |
|               "Button idx '%d' doesn't support in RazerServalRemapper().",
 | |
|               aButton)
 | |
|               .get());
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     const std::map<uint32_t, uint32_t> buttonMapping = {
 | |
|         {3, BUTTON_INDEX_TERTIARY},         {4, BUTTON_INDEX_QUATERNARY},
 | |
|         {6, BUTTON_INDEX_LEFT_SHOULDER},    {7, BUTTON_INDEX_RIGHT_SHOULDER},
 | |
|         {10, BUTTON_INDEX_BACK_SELECT},     {11, BUTTON_INDEX_START},
 | |
|         {12, BUTTON_INDEX_START},           {13, BUTTON_INDEX_LEFT_THUMBSTICK},
 | |
|         {14, BUTTON_INDEX_RIGHT_THUMBSTICK}};
 | |
| 
 | |
|     auto find = buttonMapping.find(aButton);
 | |
|     if (find != buttonMapping.end()) {
 | |
|       service->NewButtonEvent(aIndex, find->second, aPressed);
 | |
|     } else {
 | |
|       service->NewButtonEvent(aIndex, aButton, aPressed);
 | |
|     }
 | |
|   }
 | |
| };
 | |
| 
 | |
| class MogaProRemapper final : public GamepadRemapper {
 | |
|  public:
 | |
|   virtual uint32_t GetAxisCount() const override { return AXIS_INDEX_COUNT; }
 | |
| 
 | |
|   virtual uint32_t GetButtonCount() const override {
 | |
|     return BUTTON_INDEX_COUNT - 1; /* no meta */
 | |
|   }
 | |
| 
 | |
|   virtual void RemapAxisMoveEvent(uint32_t aIndex, uint32_t aAxis,
 | |
|                                   double aValue) const override {
 | |
|     RefPtr<GamepadPlatformService> service =
 | |
|         GamepadPlatformService::GetParentService();
 | |
|     if (!service) {
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     switch (aAxis) {
 | |
|       case 0:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_LEFT_STICK_X, aValue);
 | |
|         break;
 | |
|       case 1:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_LEFT_STICK_Y, aValue);
 | |
|         break;
 | |
|       case 2:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_RIGHT_STICK_X, aValue);
 | |
|         break;
 | |
|       case 3:
 | |
|         service->NewButtonEvent(aIndex, BUTTON_INDEX_RIGHT_TRIGGER,
 | |
|                                 aValue > 0.1f);
 | |
|         break;
 | |
|       case 4:
 | |
|         service->NewButtonEvent(aIndex, BUTTON_INDEX_LEFT_TRIGGER,
 | |
|                                 aValue > 0.1f);
 | |
|         break;
 | |
|       case 5:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_RIGHT_STICK_Y, aValue);
 | |
|         break;
 | |
|       case 9:
 | |
|         FetchDpadFromAxis(aIndex, aValue);
 | |
|         break;
 | |
|       default:
 | |
|         NS_WARNING(
 | |
|             nsPrintfCString(
 | |
|                 "Axis idx '%d' doesn't support in MogaProRemapper().", aAxis)
 | |
|                 .get());
 | |
|         break;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   virtual void RemapButtonEvent(uint32_t aIndex, uint32_t aButton,
 | |
|                                 bool aPressed) const override {
 | |
|     RefPtr<GamepadPlatformService> service =
 | |
|         GamepadPlatformService::GetParentService();
 | |
|     if (!service) {
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     if (GetButtonCount() <= aButton) {
 | |
|       NS_WARNING(
 | |
|           nsPrintfCString(
 | |
|               "Button idx '%d' doesn't support in MogaProRemapper().", aButton)
 | |
|               .get());
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     const std::map<uint32_t, uint32_t> buttonMapping = {
 | |
|         {3, BUTTON_INDEX_TERTIARY},         {4, BUTTON_INDEX_QUATERNARY},
 | |
|         {6, BUTTON_INDEX_LEFT_SHOULDER},    {7, BUTTON_INDEX_RIGHT_SHOULDER},
 | |
|         {11, BUTTON_INDEX_START},           {13, BUTTON_INDEX_LEFT_THUMBSTICK},
 | |
|         {14, BUTTON_INDEX_RIGHT_THUMBSTICK}};
 | |
| 
 | |
|     auto find = buttonMapping.find(aButton);
 | |
|     if (find != buttonMapping.end()) {
 | |
|       service->NewButtonEvent(aIndex, find->second, aPressed);
 | |
|     } else {
 | |
|       service->NewButtonEvent(aIndex, aButton, aPressed);
 | |
|     }
 | |
|   }
 | |
| };
 | |
| 
 | |
| class OnLiveWirelessRemapper final : public GamepadRemapper {
 | |
|  public:
 | |
|   virtual uint32_t GetAxisCount() const override { return AXIS_INDEX_COUNT; }
 | |
| 
 | |
|   virtual uint32_t GetButtonCount() const override {
 | |
|     return BUTTON_INDEX_COUNT;
 | |
|   }
 | |
| 
 | |
|   virtual void RemapAxisMoveEvent(uint32_t aIndex, uint32_t aAxis,
 | |
|                                   double aValue) const override {
 | |
|     RefPtr<GamepadPlatformService> service =
 | |
|         GamepadPlatformService::GetParentService();
 | |
|     if (!service) {
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     switch (aAxis) {
 | |
|       case 0:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_LEFT_STICK_X, aValue);
 | |
|         break;
 | |
|       case 1:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_LEFT_STICK_Y, aValue);
 | |
|         break;
 | |
|       case 2:
 | |
|         service->NewButtonEvent(aIndex, BUTTON_INDEX_LEFT_TRIGGER,
 | |
|                                 aValue > 0.1f);
 | |
|         break;
 | |
|       case 3:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_RIGHT_STICK_X, aValue);
 | |
|         break;
 | |
|       case 4:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_RIGHT_STICK_Y, aValue);
 | |
|         break;
 | |
|       case 5:
 | |
|         service->NewButtonEvent(aIndex, BUTTON_INDEX_RIGHT_TRIGGER,
 | |
|                                 aValue > 0.1f);
 | |
|         break;
 | |
|       case 9:
 | |
|         FetchDpadFromAxis(aIndex, aValue);
 | |
|         break;
 | |
|       default:
 | |
|         NS_WARNING(
 | |
|             nsPrintfCString(
 | |
|                 "Axis idx '%d' doesn't support in OnLiveWirelessRemapper().",
 | |
|                 aAxis)
 | |
|                 .get());
 | |
|         break;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   virtual void RemapButtonEvent(uint32_t aIndex, uint32_t aButton,
 | |
|                                 bool aPressed) const override {
 | |
|     RefPtr<GamepadPlatformService> service =
 | |
|         GamepadPlatformService::GetParentService();
 | |
|     if (!service) {
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     if (GetButtonCount() <= aButton) {
 | |
|       NS_WARNING(
 | |
|           nsPrintfCString(
 | |
|               "Button idx '%d' doesn't support in OnLiveWirelessRemapper().",
 | |
|               aButton)
 | |
|               .get());
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     const std::map<uint32_t, uint32_t> buttonMapping = {
 | |
|         {3, BUTTON_INDEX_TERTIARY},
 | |
|         {4, BUTTON_INDEX_QUATERNARY},
 | |
|         {6, BUTTON_INDEX_LEFT_SHOULDER},
 | |
|         {7, BUTTON_INDEX_RIGHT_SHOULDER},
 | |
|         {12, BUTTON_INDEX_META},
 | |
|         {13, BUTTON_INDEX_LEFT_THUMBSTICK},
 | |
|         {14, BUTTON_INDEX_RIGHT_THUMBSTICK}};
 | |
| 
 | |
|     auto find = buttonMapping.find(aButton);
 | |
|     if (find != buttonMapping.end()) {
 | |
|       service->NewButtonEvent(aIndex, find->second, aPressed);
 | |
|     } else {
 | |
|       service->NewButtonEvent(aIndex, aButton, aPressed);
 | |
|     }
 | |
|   }
 | |
| };
 | |
| 
 | |
| class OUYARemapper final : public GamepadRemapper {
 | |
|  public:
 | |
|   virtual uint32_t GetAxisCount() const override { return AXIS_INDEX_COUNT; }
 | |
| 
 | |
|   virtual uint32_t GetButtonCount() const override {
 | |
|     return BUTTON_INDEX_COUNT;
 | |
|   }
 | |
| 
 | |
|   virtual void RemapAxisMoveEvent(uint32_t aIndex, uint32_t aAxis,
 | |
|                                   double aValue) const override {
 | |
|     RefPtr<GamepadPlatformService> service =
 | |
|         GamepadPlatformService::GetParentService();
 | |
|     if (!service) {
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     switch (aAxis) {
 | |
|       case 0:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_LEFT_STICK_X, aValue);
 | |
|         break;
 | |
|       case 1:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_LEFT_STICK_Y, aValue);
 | |
|         break;
 | |
|       case 2:
 | |
|         service->NewButtonEvent(aIndex, BUTTON_INDEX_LEFT_TRIGGER,
 | |
|                                 aValue > 0.1f);
 | |
|         break;
 | |
|       case 3:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_RIGHT_STICK_X, aValue);
 | |
|         break;
 | |
|       case 4:
 | |
|         service->NewAxisMoveEvent(aIndex, AXIS_INDEX_RIGHT_STICK_Y, aValue);
 | |
|         break;
 | |
|       case 5:
 | |
|         service->NewButtonEvent(aIndex, BUTTON_INDEX_RIGHT_TRIGGER,
 | |
|                                 aValue > 0.1f);
 | |
|         break;
 | |
|       default:
 | |
|         NS_WARNING(
 | |
|             nsPrintfCString("Axis idx '%d' doesn't support in OUYARemapper().",
 | |
|                             aAxis)
 | |
|                 .get());
 | |
|         break;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   virtual void RemapButtonEvent(uint32_t aIndex, uint32_t aButton,
 | |
|                                 bool aPressed) const override {
 | |
|     RefPtr<GamepadPlatformService> service =
 | |
|         GamepadPlatformService::GetParentService();
 | |
|     if (!service) {
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     if (GetButtonCount() <= aButton) {
 | |
|       NS_WARNING(
 | |
|           nsPrintfCString("Button idx '%d' doesn't support in OUYARemapper().",
 | |
|                           aButton)
 | |
|               .get());
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     const std::map<uint32_t, uint32_t> buttonMapping = {
 | |
|         {1, BUTTON_INDEX_TERTIARY},         {2, BUTTON_INDEX_QUATERNARY},
 | |
|         {3, BUTTON_INDEX_SECONDARY},        {6, BUTTON_INDEX_LEFT_THUMBSTICK},
 | |
|         {7, BUTTON_INDEX_RIGHT_THUMBSTICK}, {8, BUTTON_INDEX_DPAD_UP},
 | |
|         {9, BUTTON_INDEX_DPAD_DOWN},        {10, BUTTON_INDEX_DPAD_LEFT},
 | |
|         {11, BUTTON_INDEX_DPAD_RIGHT},      {15, BUTTON_INDEX_META}};
 | |
| 
 | |
|     auto find = buttonMapping.find(aButton);
 | |
|     if (find != buttonMapping.end()) {
 | |
|       service->NewButtonEvent(aIndex, find->second, aPressed);
 | |
|     } else {
 | |
|       service->NewButtonEvent(aIndex, aButton, aPressed);
 | |
|     }
 | |
|   }
 | |
| };
 | |
| 
 | |
| already_AddRefed<GamepadRemapper> GetGamepadRemapper(const uint16_t aVendorId,
 | |
|                                                      const uint16_t aProductId,
 | |
|                                                      bool& aUsingDefault) {
 | |
|   const std::vector<GamepadRemappingData> remappingRules = {
 | |
|       {GamepadId::kAsusTekProduct4500, new ADT1Remapper()},
 | |
|       {GamepadId::kDragonRiseProduct0011, new TwoAxesEightKeysRemapper()},
 | |
|       {GamepadId::kGoogleProduct2c40, new ADT1Remapper()},
 | |
|       {GamepadId::kGoogleProduct9400, new StadiaControllerRemapper()},
 | |
|       {GamepadId::kLogitechProductc216, new LogitechDInputRemapper()},
 | |
|       {GamepadId::kLogitechProductc218, new LogitechDInputRemapper()},
 | |
|       {GamepadId::kLogitechProductc219, new LogitechDInputRemapper()},
 | |
|       {GamepadId::kNintendoProduct2006, new SwitchJoyConRemapper()},
 | |
|       {GamepadId::kNintendoProduct2007, new SwitchJoyConRemapper()},
 | |
|       {GamepadId::kNintendoProduct2009, new SwitchProRemapper()},
 | |
|       {GamepadId::kNintendoProduct200e, new SwitchProRemapper()},
 | |
|       {GamepadId::kNvidiaProduct7210, new NvShieldRemapper()},
 | |
|       {GamepadId::kNvidiaProduct7214, new NvShield2017Remapper()},
 | |
|       {GamepadId::kPadixProduct2060, new IBuffaloRemapper()},
 | |
|       {GamepadId::kPlayComProduct0005, new XSkillsRemapper()},
 | |
|       {GamepadId::kPrototypeVendorProduct0667, new BoomN64PsxRemapper()},
 | |
|       {GamepadId::kPrototypeVendorProduct9401, new AnalogGamepadRemapper()},
 | |
|       {GamepadId::kRazer1532Product0900, new RazerServalRemapper()},
 | |
|       {GamepadId::kSonyProduct0268, new Playstation3Remapper()},
 | |
|       {GamepadId::kSonyProduct05c4, new Dualshock4Remapper()},
 | |
|       {GamepadId::kSonyProduct09cc, new Dualshock4Remapper()},
 | |
|       {GamepadId::kSonyProduct0ba0, new Dualshock4Remapper()},
 | |
|       {GamepadId::kVendor20d6Product6271, new MogaProRemapper()},
 | |
|       {GamepadId::kVendor2378Product1008, new OnLiveWirelessRemapper()},
 | |
|       {GamepadId::kVendor2378Product100a, new OnLiveWirelessRemapper()},
 | |
|       {GamepadId::kVendor2836Product0001, new OUYARemapper()}};
 | |
|   const GamepadId id = static_cast<GamepadId>((aVendorId << 16) | aProductId);
 | |
| 
 | |
|   for (uint32_t i = 0; i < remappingRules.size(); ++i) {
 | |
|     if (id == remappingRules[i].id) {
 | |
|       aUsingDefault = false;
 | |
|       return do_AddRef(remappingRules[i].remapping.get());
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   static RefPtr<GamepadRemapper> defaultRemapper = new DefaultRemapper();
 | |
|   aUsingDefault = true;
 | |
|   return do_AddRef(defaultRemapper.get());
 | |
| }
 | |
| 
 | |
| }  // namespace dom
 | |
| }  // namespace mozilla
 | 
