@@ -669,6 +669,364 @@ class Dualshock4Remapper final : public GamepadRemapper {
669
669
unsigned long mTouchIdBase = 0 ;
670
670
};
671
671
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
+
672
1030
class LogitechDInputRemapper final : public GamepadRemapper {
673
1031
public:
674
1032
virtual uint32_t GetAxisCount () const override { return AXIS_INDEX_COUNT; }
@@ -1717,6 +2075,14 @@ already_AddRefed<GamepadRemapper> GetGamepadRemapper(const uint16_t aVendorId,
1717
2075
{GamepadId::kLogitechProductc216 , new LogitechDInputRemapper ()},
1718
2076
{GamepadId::kLogitechProductc218 , new LogitechDInputRemapper ()},
1719
2077
{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 ()},
1720
2086
{GamepadId::kNintendoProduct2006 , new SwitchJoyConRemapper ()},
1721
2087
{GamepadId::kNintendoProduct2007 , new SwitchJoyConRemapper ()},
1722
2088
{GamepadId::kNintendoProduct2009 , new SwitchProRemapper ()},
@@ -1746,7 +2112,7 @@ already_AddRefed<GamepadRemapper> GetGamepadRemapper(const uint16_t aVendorId,
1746
2112
}
1747
2113
}
1748
2114
1749
- static RefPtr<GamepadRemapper> defaultRemapper = new DefaultRemapper ();
2115
+ RefPtr<GamepadRemapper> defaultRemapper = new DefaultRemapper ();
1750
2116
aUsingDefault = true ;
1751
2117
return do_AddRef (defaultRemapper.get ());
1752
2118
}
0 commit comments