@@ -669,6 +669,364 @@ class Dualshock4Remapper final : public GamepadRemapper {
669669 unsigned long mTouchIdBase = 0 ;
670670};
671671
672+ class Xbox360Remapper final : public GamepadRemapper {
673+ public:
674+ virtual uint32_t GetAxisCount () const override { return AXIS_INDEX_COUNT; }
675+
676+ virtual uint32_t GetButtonCount () const override {
677+ return BUTTON_INDEX_COUNT;
678+ }
679+
680+ virtual void RemapAxisMoveEvent (uint32_t aIndex, uint32_t aAxis,
681+ double aValue) const override {
682+ RefPtr<GamepadPlatformService> service =
683+ GamepadPlatformService::GetParentService ();
684+ if (!service) {
685+ return ;
686+ }
687+
688+ switch (aAxis) {
689+ case 0 :
690+ service->NewAxisMoveEvent (aIndex, AXIS_INDEX_LEFT_STICK_X, aValue);
691+ break ;
692+ case 1 :
693+ service->NewAxisMoveEvent (aIndex, AXIS_INDEX_LEFT_STICK_Y, aValue);
694+ break ;
695+ case 2 : {
696+ const double value = AxisToButtonValue (aValue);
697+ service->NewButtonEvent (aIndex, BUTTON_INDEX_LEFT_TRIGGER,
698+ value > BUTTON_THRESHOLD_VALUE, value);
699+ break ;
700+ }
701+ case 3 :
702+ service->NewAxisMoveEvent (aIndex, AXIS_INDEX_RIGHT_STICK_X, aValue);
703+ break ;
704+ case 4 :
705+ service->NewAxisMoveEvent (aIndex, AXIS_INDEX_RIGHT_STICK_Y, aValue);
706+ break ;
707+ case 5 : {
708+ const double value = AxisToButtonValue (aValue);
709+ service->NewButtonEvent (aIndex, BUTTON_INDEX_RIGHT_TRIGGER,
710+ value > BUTTON_THRESHOLD_VALUE, value);
711+ break ;
712+ }
713+ default :
714+ NS_WARNING (
715+ nsPrintfCString (
716+ " Axis idx '%d' doesn't support in Xbox360Remapper()." , aAxis)
717+ .get());
718+ break ;
719+ }
720+ }
721+
722+ virtual void RemapButtonEvent (uint32_t aIndex, uint32_t aButton,
723+ bool aPressed) const override {
724+ RefPtr<GamepadPlatformService> service =
725+ GamepadPlatformService::GetParentService ();
726+ if (!service) {
727+ return ;
728+ }
729+
730+ if (GetButtonCount () <= aButton) {
731+ NS_WARNING (
732+ nsPrintfCString (
733+ " Button idx '%d' doesn't support in Xbox360Remapper()." , aButton)
734+ .get());
735+ return ;
736+ }
737+
738+ const std::unordered_map<uint32_t , uint32_t > buttonMapping = {
739+ {6 , BUTTON_INDEX_LEFT_THUMBSTICK}, {7 , BUTTON_INDEX_RIGHT_THUMBSTICK},
740+ {8 , BUTTON_INDEX_START}, {9 , BUTTON_INDEX_BACK_SELECT},
741+ {10 , BUTTON_INDEX_META}, {11 , BUTTON_INDEX_DPAD_UP},
742+ {12 , BUTTON_INDEX_DPAD_DOWN}, {13 , BUTTON_INDEX_DPAD_LEFT},
743+ {14 , BUTTON_INDEX_DPAD_RIGHT}};
744+
745+ auto find = buttonMapping.find(aButton);
746+ if (find != buttonMapping.end ()) {
747+ service->NewButtonEvent (aIndex, find->second , aPressed);
748+ } else {
749+ service->NewButtonEvent (aIndex, aButton, aPressed);
750+ }
751+ }
752+ };
753+
754+ class XboxOneSRemapper final : public GamepadRemapper {
755+ public:
756+ virtual uint32_t GetAxisCount () const override { return AXIS_INDEX_COUNT; }
757+
758+ virtual uint32_t GetButtonCount () const override {
759+ return BUTTON_INDEX_COUNT;
760+ }
761+
762+ virtual void RemapAxisMoveEvent (uint32_t aIndex, uint32_t aAxis,
763+ double aValue) const override {
764+ RefPtr<GamepadPlatformService> service =
765+ GamepadPlatformService::GetParentService ();
766+ if (!service) {
767+ return ;
768+ }
769+
770+ switch (aAxis) {
771+ case 0 :
772+ service->NewAxisMoveEvent (aIndex, AXIS_INDEX_LEFT_STICK_X, aValue);
773+ break ;
774+ case 1 :
775+ service->NewAxisMoveEvent (aIndex, AXIS_INDEX_LEFT_STICK_Y, aValue);
776+ break ;
777+ case 2 : {
778+ const double value = AxisToButtonValue (aValue);
779+ service->NewButtonEvent (aIndex, BUTTON_INDEX_LEFT_TRIGGER,
780+ value > BUTTON_THRESHOLD_VALUE, value);
781+ break ;
782+ }
783+ case 3 :
784+ service->NewAxisMoveEvent (aIndex, AXIS_INDEX_RIGHT_STICK_X, aValue);
785+ break ;
786+ case 4 :
787+ service->NewAxisMoveEvent (aIndex, AXIS_INDEX_RIGHT_STICK_Y, aValue);
788+ break ;
789+ case 5 : {
790+ const double value = AxisToButtonValue (aValue);
791+ service->NewButtonEvent (aIndex, BUTTON_INDEX_RIGHT_TRIGGER,
792+ value > BUTTON_THRESHOLD_VALUE, value);
793+ break ;
794+ }
795+ case 9 :
796+ FetchDpadFromAxis (aIndex, aValue);
797+ break ;
798+ default :
799+ NS_WARNING (
800+ nsPrintfCString (
801+ " Axis idx '%d' doesn't support in XboxOneSRemapper()." , aAxis)
802+ .get());
803+ break ;
804+ }
805+ }
806+
807+ virtual void RemapButtonEvent (uint32_t aIndex, uint32_t aButton,
808+ bool aPressed) const override {
809+ RefPtr<GamepadPlatformService> service =
810+ GamepadPlatformService::GetParentService ();
811+ if (!service) {
812+ return ;
813+ }
814+
815+ if (GetButtonCount () <= aButton) {
816+ NS_WARNING (
817+ nsPrintfCString (
818+ " Button idx '%d' doesn't support in XboxOneSRemapper()." , aButton)
819+ .get());
820+ return ;
821+ }
822+
823+ const std::unordered_map<uint32_t , uint32_t > buttonMapping = {
824+ {6 , BUTTON_INDEX_BACK_SELECT},
825+ {7 , BUTTON_INDEX_START},
826+ {8 , BUTTON_INDEX_LEFT_THUMBSTICK},
827+ {9 , BUTTON_INDEX_RIGHT_THUMBSTICK},
828+ {10 , BUTTON_INDEX_META}};
829+
830+ auto find = buttonMapping.find(aButton);
831+ if (find != buttonMapping.end ()) {
832+ service->NewButtonEvent (aIndex, find->second , aPressed);
833+ } else {
834+ service->NewButtonEvent (aIndex, aButton, aPressed);
835+ }
836+ }
837+ };
838+
839+ class XboxOneS2016FirmwareRemapper final : public GamepadRemapper {
840+ public:
841+ virtual uint32_t GetAxisCount () const override { return AXIS_INDEX_COUNT; }
842+
843+ virtual uint32_t GetButtonCount () const override {
844+ return BUTTON_INDEX_COUNT;
845+ }
846+
847+ virtual void RemapAxisMoveEvent (uint32_t aIndex, uint32_t aAxis,
848+ double aValue) const override {
849+ RefPtr<GamepadPlatformService> service =
850+ GamepadPlatformService::GetParentService ();
851+ if (!service) {
852+ return ;
853+ }
854+
855+ switch (aAxis) {
856+ case 0 :
857+ service->NewAxisMoveEvent (aIndex, AXIS_INDEX_LEFT_STICK_X, aValue);
858+ break ;
859+ case 1 :
860+ service->NewAxisMoveEvent (aIndex, AXIS_INDEX_LEFT_STICK_Y, aValue);
861+ break ;
862+ case 2 :
863+ service->NewAxisMoveEvent (aIndex, AXIS_INDEX_RIGHT_STICK_X, aValue);
864+ break ;
865+ case 3 : {
866+ const double value = AxisToButtonValue (aValue);
867+ service->NewButtonEvent (aIndex, BUTTON_INDEX_LEFT_TRIGGER,
868+ value > BUTTON_THRESHOLD_VALUE, value);
869+ break ;
870+ }
871+ case 4 : {
872+ const double value = AxisToButtonValue (aValue);
873+ service->NewButtonEvent (aIndex, BUTTON_INDEX_RIGHT_TRIGGER,
874+ value > BUTTON_THRESHOLD_VALUE, value);
875+ break ;
876+ }
877+ case 5 :
878+ service->NewAxisMoveEvent (aIndex, AXIS_INDEX_RIGHT_STICK_Y, aValue);
879+ break ;
880+ case 9 :
881+ FetchDpadFromAxis (aIndex, aValue);
882+ break ;
883+ default :
884+ NS_WARNING (nsPrintfCString(" Axis idx '%d' doesn't support in "
885+ " XboxOneS2016FirmwareRemapper()." ,
886+ aAxis)
887+ .get());
888+ break ;
889+ }
890+ }
891+
892+ virtual void RemapButtonEvent (uint32_t aIndex, uint32_t aButton,
893+ bool aPressed) const override {
894+ RefPtr<GamepadPlatformService> service =
895+ GamepadPlatformService::GetParentService ();
896+ if (!service) {
897+ return ;
898+ }
899+
900+ if (GetButtonCount () <= aButton) {
901+ NS_WARNING (nsPrintfCString(" Button idx '%d' doesn't support in "
902+ " XboxOneS2016FirmwareRemapper()." ,
903+ aButton)
904+ .get());
905+ return ;
906+ }
907+
908+ // kMicrosoftProductXboxOneSWireless2016 controller received a firmware
909+ // update in 2019 that changed which field is populated with the meta button
910+ // state. In order to cover the old and new cases, we have to check both
911+ // fields of {12, 15} buttons.
912+ const std::unordered_map<uint32_t , uint32_t > buttonMapping = {
913+ {0 , BUTTON_INDEX_PRIMARY},
914+ {1 , BUTTON_INDEX_SECONDARY},
915+ {3 , BUTTON_INDEX_TERTIARY},
916+ {4 , BUTTON_INDEX_QUATERNARY},
917+ {6 , BUTTON_INDEX_LEFT_SHOULDER},
918+ {7 , BUTTON_INDEX_RIGHT_SHOULDER},
919+ {11 , BUTTON_INDEX_START},
920+ {12 , BUTTON_INDEX_META},
921+ {13 , BUTTON_INDEX_LEFT_THUMBSTICK},
922+ {14 , BUTTON_INDEX_RIGHT_THUMBSTICK},
923+ {15 , BUTTON_INDEX_META},
924+ {16 , BUTTON_INDEX_BACK_SELECT}};
925+
926+ auto find = buttonMapping.find (aButton);
927+ if (find != buttonMapping.end ()) {
928+ service->NewButtonEvent (aIndex, find->second , aPressed);
929+ } else {
930+ service->NewButtonEvent (aIndex, aButton, aPressed);
931+ }
932+ }
933+ };
934+
935+ class XboxOneRemapper final : public GamepadRemapper {
936+ public:
937+ virtual uint32_t GetAxisCount () const override { return AXIS_INDEX_COUNT; }
938+
939+ virtual uint32_t GetButtonCount () const override {
940+ return BUTTON_INDEX_COUNT;
941+ }
942+
943+ virtual void RemapAxisMoveEvent (uint32_t aIndex, uint32_t aAxis,
944+ double aValue) const override {
945+ RefPtr<GamepadPlatformService> service =
946+ GamepadPlatformService::GetParentService ();
947+ if (!service) {
948+ return ;
949+ }
950+
951+ switch (aAxis) {
952+ case 0 :
953+ service->NewAxisMoveEvent (aIndex, AXIS_INDEX_LEFT_STICK_X, aValue);
954+ break ;
955+ case 1 :
956+ service->NewAxisMoveEvent (aIndex, AXIS_INDEX_LEFT_STICK_Y, aValue);
957+ break ;
958+ case 2 :
959+ service->NewAxisMoveEvent (aIndex, AXIS_INDEX_RIGHT_STICK_X, aValue);
960+ break ;
961+ case 3 :
962+ service->NewAxisMoveEvent (aIndex, AXIS_INDEX_RIGHT_STICK_Y, aValue);
963+ break ;
964+ case 9 :
965+ FetchDpadFromAxis (aIndex, aValue);
966+ break ;
967+ case 10 : {
968+ const double value = AxisToButtonValue (aValue);
969+ service->NewButtonEvent (aIndex, BUTTON_INDEX_LEFT_TRIGGER,
970+ value > BUTTON_THRESHOLD_VALUE, value);
971+ break ;
972+ }
973+ case 11 : {
974+ const double value = AxisToButtonValue (aValue);
975+ service->NewButtonEvent (aIndex, BUTTON_INDEX_RIGHT_TRIGGER,
976+ value > BUTTON_THRESHOLD_VALUE, value);
977+ break ;
978+ }
979+ default :
980+ NS_WARNING (
981+ nsPrintfCString (
982+ " Axis idx '%d' doesn't support in XboxOneRemapper()." , aAxis)
983+ .get());
984+ break ;
985+ }
986+ }
987+
988+ virtual void RemapButtonEvent (uint32_t aIndex, uint32_t aButton,
989+ bool aPressed) const override {
990+ RefPtr<GamepadPlatformService> service =
991+ GamepadPlatformService::GetParentService ();
992+ if (!service) {
993+ return ;
994+ }
995+
996+ if (GetButtonCount () <= aButton) {
997+ NS_WARNING (
998+ nsPrintfCString (
999+ " Button idx '%d' doesn't support in XboxOneRemapper()." , aButton)
1000+ .get());
1001+ return ;
1002+ }
1003+
1004+ // Accessing {30, 31} buttons looks strange to me
1005+ // and without an avilable device to help verify it.
1006+ // It is according to `MapperXboxOneBluetooth()` in
1007+ // https://cs.chromium.org/chromium/src/device/gamepad/gamepad_standard_mappings_mac.mm
1008+ const std::unordered_map<uint32_t , uint32_t > buttonMapping = {
1009+ {0 , BUTTON_INDEX_PRIMARY},
1010+ {1 , BUTTON_INDEX_SECONDARY},
1011+ {3 , BUTTON_INDEX_TERTIARY},
1012+ {4 , BUTTON_INDEX_QUATERNARY},
1013+ {6 , BUTTON_INDEX_LEFT_SHOULDER},
1014+ {7 , BUTTON_INDEX_RIGHT_SHOULDER},
1015+ {11 , BUTTON_INDEX_START},
1016+ {13 , BUTTON_INDEX_LEFT_THUMBSTICK},
1017+ {14 , BUTTON_INDEX_RIGHT_THUMBSTICK},
1018+ {30 , BUTTON_INDEX_META},
1019+ {31 , BUTTON_INDEX_BACK_SELECT}};
1020+
1021+ auto find = buttonMapping.find(aButton);
1022+ if (find != buttonMapping.end ()) {
1023+ service->NewButtonEvent (aIndex, find->second , aPressed);
1024+ } else {
1025+ service->NewButtonEvent (aIndex, aButton, aPressed);
1026+ }
1027+ }
1028+ };
1029+
6721030class LogitechDInputRemapper final : public GamepadRemapper {
6731031 public:
6741032 virtual uint32_t GetAxisCount () const override { return AXIS_INDEX_COUNT; }
@@ -1717,6 +2075,14 @@ already_AddRefed<GamepadRemapper> GetGamepadRemapper(const uint16_t aVendorId,
17172075 {GamepadId::kLogitechProductc216 , new LogitechDInputRemapper ()},
17182076 {GamepadId::kLogitechProductc218 , new LogitechDInputRemapper ()},
17192077 {GamepadId::kLogitechProductc219 , new LogitechDInputRemapper ()},
2078+ {GamepadId::kMicrosoftProductXbox360Wireless , new Xbox360Remapper ()},
2079+ {GamepadId::kMicrosoftProductXbox360Wireless2 , new Xbox360Remapper ()},
2080+ {GamepadId::kMicrosoftProductXboxOneElite2Wireless ,
2081+ new XboxOneRemapper ()},
2082+ {GamepadId::kMicrosoftProductXboxOneSWireless , new XboxOneSRemapper ()},
2083+ {GamepadId::kMicrosoftProductXboxOneSWireless2016 ,
2084+ new XboxOneS2016FirmwareRemapper ()},
2085+ {GamepadId::kMicrosoftProductXboxAdaptiveWireless , new XboxOneRemapper ()},
17202086 {GamepadId::kNintendoProduct2006 , new SwitchJoyConRemapper ()},
17212087 {GamepadId::kNintendoProduct2007 , new SwitchJoyConRemapper ()},
17222088 {GamepadId::kNintendoProduct2009 , new SwitchProRemapper ()},
@@ -1746,7 +2112,7 @@ already_AddRefed<GamepadRemapper> GetGamepadRemapper(const uint16_t aVendorId,
17462112 }
17472113 }
17482114
1749- static RefPtr<GamepadRemapper> defaultRemapper = new DefaultRemapper ();
2115+ RefPtr<GamepadRemapper> defaultRemapper = new DefaultRemapper ();
17502116 aUsingDefault = true ;
17512117 return do_AddRef (defaultRemapper.get ());
17522118}
0 commit comments