1#define BUTTON(x) @(JOYButtonUsageGeneric0 + (x))
2#define AXIS(x) @(JOYAxisUsageGeneric0 + (x))
3#define AXES2D(x) @(JOYAxes2DUsageGeneric0 + (x))
4
5hacksByManufacturer = @{
6    @(0x045E): @{ // Microsoft
7
8        JOYAxisGroups: @{
9              @(kHIDUsage_GD_X): @(0),
10              @(kHIDUsage_GD_Y): @(0),
11              @(kHIDUsage_GD_Z): @(2),
12              @(kHIDUsage_GD_Rx): @(1),
13              @(kHIDUsage_GD_Ry): @(1),
14              @(kHIDUsage_GD_Rz): @(2),
15        },
16
17        JOYButtonUsageMapping: @{
18              BUTTON(1): @(JOYButtonUsageA),
19              BUTTON(2): @(JOYButtonUsageB),
20              BUTTON(3): @(JOYButtonUsageX),
21              BUTTON(4): @(JOYButtonUsageY),
22              BUTTON(5): @(JOYButtonUsageL1),
23              BUTTON(6): @(JOYButtonUsageR1),
24              BUTTON(7): @(JOYButtonUsageLStick),
25              BUTTON(8): @(JOYButtonUsageRStick),
26              BUTTON(9): @(JOYButtonUsageStart),
27              BUTTON(10): @(JOYButtonUsageSelect),
28              BUTTON(11): @(JOYButtonUsageHome),
29         },
30
31         JOYAxisUsageMapping: @{
32             AXIS(3): @(JOYAxisUsageL1),
33             AXIS(6): @(JOYAxisUsageR1),
34         },
35
36         JOYAxes2DUsageMapping: @{
37             AXES2D(1): @(JOYAxes2DUsageLeftStick),
38             AXES2D(3): @(JOYAxes2DUsageRightStick),
39         },
40
41         JOYEmulateAxisButtons: @YES,
42    },
43
44    @(0x054C): @{ // Sony
45        /* Generally untested, but should work */
46
47        JOYAxisGroups: @{
48              @(kHIDUsage_GD_X): @(0),
49              @(kHIDUsage_GD_Y): @(0),
50              @(kHIDUsage_GD_Z): @(1),
51              @(kHIDUsage_GD_Rx): @(2),
52              @(kHIDUsage_GD_Ry): @(3),
53              @(kHIDUsage_GD_Rz): @(1),
54        },
55
56        JOYButtonUsageMapping: @{
57              BUTTON(1): @(JOYButtonUsageY),
58              BUTTON(2): @(JOYButtonUsageB),
59              BUTTON(3): @(JOYButtonUsageA),
60              BUTTON(4): @(JOYButtonUsageX),
61              BUTTON(5): @(JOYButtonUsageL1),
62              BUTTON(6): @(JOYButtonUsageR1),
63              BUTTON(7): @(JOYButtonUsageL2),
64              BUTTON(8): @(JOYButtonUsageR2),
65              BUTTON(9): @(JOYButtonUsageSelect),
66              BUTTON(10): @(JOYButtonUsageStart),
67              BUTTON(11): @(JOYButtonUsageLStick),
68              BUTTON(12): @(JOYButtonUsageRStick),
69              BUTTON(13): @(JOYButtonUsageHome),
70              BUTTON(14): @(JOYButtonUsageMisc),
71         },
72
73         JOYAxisUsageMapping: @{
74             AXIS(4): @(JOYAxisUsageL2),
75             AXIS(5): @(JOYAxisUsageR2),
76         },
77
78         JOYAxes2DUsageMapping: @{
79             AXES2D(1): @(JOYAxes2DUsageLeftStick),
80             AXES2D(4): @(JOYAxes2DUsageRightStick),
81         },
82
83         // When DualSense mode is activated on BT, The report ID is 0x31 and there's an extra byte
84         JOYCustomReports: @{
85            @(0x31): @[
86            /* 1D and 2D axes */
87            @{@"reportID": @(0x31), @"size":@8, @"offset":@0x08, @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_X), @"min": @0, @"max": @255},
88            @{@"reportID": @(0x31), @"size":@8, @"offset":@0x10, @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_Y), @"min": @0, @"max": @255},
89            @{@"reportID": @(0x31), @"size":@8, @"offset":@0x18, @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_Z), @"min": @0, @"max": @255},
90            @{@"reportID": @(0x31), @"size":@8, @"offset":@0x20, @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_Rz), @"min": @0, @"max": @255},
91            @{@"reportID": @(0x31), @"size":@8, @"offset":@0x28, @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_Rx), @"min": @0, @"max": @255},
92            @{@"reportID": @(0x31), @"size":@8, @"offset":@0x30, @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_Ry), @"min": @0, @"max": @255},
93
94            /* Hat Switch*/
95            @{@"reportID": @(0x31), @"size":@4, @"offset":@0x40, @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_Hatswitch), @"min": @0, @"max": @7},
96
97            /* Buttons */
98            @{@"reportID": @(0x31), @"size":@1, @"offset":@0x44, @"usagePage":@(kHIDPage_Button), @"usage":@1},
99            @{@"reportID": @(0x31), @"size":@1, @"offset":@0x45, @"usagePage":@(kHIDPage_Button), @"usage":@2},
100            @{@"reportID": @(0x31), @"size":@1, @"offset":@0x46, @"usagePage":@(kHIDPage_Button), @"usage":@3},
101            @{@"reportID": @(0x31), @"size":@1, @"offset":@0x47, @"usagePage":@(kHIDPage_Button), @"usage":@4},
102            @{@"reportID": @(0x31), @"size":@1, @"offset":@0x48, @"usagePage":@(kHIDPage_Button), @"usage":@5},
103            @{@"reportID": @(0x31), @"size":@1, @"offset":@0x49, @"usagePage":@(kHIDPage_Button), @"usage":@6},
104            @{@"reportID": @(0x31), @"size":@1, @"offset":@0x4a, @"usagePage":@(kHIDPage_Button), @"usage":@7},
105            @{@"reportID": @(0x31), @"size":@1, @"offset":@0x4b, @"usagePage":@(kHIDPage_Button), @"usage":@8},
106            @{@"reportID": @(0x31), @"size":@1, @"offset":@0x4c, @"usagePage":@(kHIDPage_Button), @"usage":@9},
107            @{@"reportID": @(0x31), @"size":@1, @"offset":@0x4d, @"usagePage":@(kHIDPage_Button), @"usage":@10},
108            @{@"reportID": @(0x31), @"size":@1, @"offset":@0x4e, @"usagePage":@(kHIDPage_Button), @"usage":@11},
109            @{@"reportID": @(0x31), @"size":@1, @"offset":@0x4f, @"usagePage":@(kHIDPage_Button), @"usage":@12},
110            @{@"reportID": @(0x31), @"size":@1, @"offset":@0x50, @"usagePage":@(kHIDPage_Button), @"usage":@13},
111            @{@"reportID": @(0x31), @"size":@1, @"offset":@0x51, @"usagePage":@(kHIDPage_Button), @"usage":@14},
112            @{@"reportID": @(0x31), @"size":@1, @"offset":@0x52, @"usagePage":@(kHIDPage_Button), @"usage":@15},
113            ],
114        },
115
116         JOYIsSony: @YES,
117    }
118};
119
120hacksByName = @{
121    @"WUP-028": @{ // Nintendo GameCube Controller Adapter
122        JOYReportIDFilters: @[@[@1], @[@2], @[@3], @[@4]],
123        JOYButtonUsageMapping: @{
124            BUTTON(1): @(JOYButtonUsageA),
125            BUTTON(2): @(JOYButtonUsageB),
126            BUTTON(3): @(JOYButtonUsageX),
127            BUTTON(4): @(JOYButtonUsageY),
128            BUTTON(5): @(JOYButtonUsageStart),
129            BUTTON(6): @(JOYButtonUsageZ),
130            BUTTON(7): @(JOYButtonUsageR1),
131            BUTTON(8): @(JOYButtonUsageL1),
132        },
133
134        JOYAxisUsageMapping: @{
135            AXIS(3): @(JOYAxisUsageL1),
136            AXIS(6): @(JOYAxisUsageR1),
137        },
138
139        JOYAxes2DUsageMapping: @{
140            AXES2D(1): @(JOYAxes2DUsageLeftStick),
141            AXES2D(4): @(JOYAxes2DUsageRightStick),
142        },
143
144        JOYAxisGroups: @{
145            @(kHIDUsage_GD_X): @(0),
146            @(kHIDUsage_GD_Y): @(0),
147            @(kHIDUsage_GD_Z): @(2),
148            @(kHIDUsage_GD_Rx): @(1),
149            @(kHIDUsage_GD_Ry): @(1),
150            @(kHIDUsage_GD_Rz): @(3),
151        },
152
153        JOYRumbleUsage: @1,
154        JOYRumbleUsagePage: @0xFF00,
155
156        JOYConnectedUsage: @2,
157        JOYConnectedUsagePage: @0xFF00,
158
159        JOYActivationReport: [NSData dataWithBytes:(uint8_t[]){0x13} length:1],
160
161        JOYCustomReports: @{
162
163            // Rumble
164            @(-17): @[
165                @{@"reportID": @(1), @"size":@1, @"offset":@0,  @"usagePage":@(0xFF00), @"usage":@1, @"min": @0, @"max": @1},
166                @{@"reportID": @(2), @"size":@1, @"offset":@8,  @"usagePage":@(0xFF00), @"usage":@1, @"min": @0, @"max": @1},
167                @{@"reportID": @(3), @"size":@1, @"offset":@16, @"usagePage":@(0xFF00), @"usage":@1, @"min": @0, @"max": @1},
168                @{@"reportID": @(4), @"size":@1, @"offset":@24, @"usagePage":@(0xFF00), @"usage":@1, @"min": @0, @"max": @1},
169            ],
170
171            @(33): @[
172
173            // Player 1
174
175            @{@"reportID": @(1), @"size":@1, @"offset":@4, @"usagePage":@(0xFF00), @"usage":@2, @"min": @0, @"max": @1},
176
177            @{@"reportID": @(1), @"size":@1, @"offset":@8, @"usagePage":@(kHIDPage_Button), @"usage":@1},
178            @{@"reportID": @(1), @"size":@1, @"offset":@9, @"usagePage":@(kHIDPage_Button), @"usage":@2},
179            @{@"reportID": @(1), @"size":@1, @"offset":@10,@"usagePage":@(kHIDPage_Button), @"usage":@3},
180            @{@"reportID": @(1), @"size":@1, @"offset":@11,@"usagePage":@(kHIDPage_Button), @"usage":@4},
181
182            @{@"reportID": @(1), @"size":@1, @"offset":@12, @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_DPadLeft)},
183            @{@"reportID": @(1), @"size":@1, @"offset":@13, @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_DPadRight)},
184            @{@"reportID": @(1), @"size":@1, @"offset":@14, @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_DPadDown)},
185            @{@"reportID": @(1), @"size":@1, @"offset":@15, @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_DPadUp)},
186
187
188            @{@"reportID": @(1), @"size":@1, @"offset":@16, @"usagePage":@(kHIDPage_Button), @"usage":@5},
189            @{@"reportID": @(1), @"size":@1, @"offset":@17, @"usagePage":@(kHIDPage_Button), @"usage":@6},
190            @{@"reportID": @(1), @"size":@1, @"offset":@18, @"usagePage":@(kHIDPage_Button), @"usage":@7},
191            @{@"reportID": @(1), @"size":@1, @"offset":@19, @"usagePage":@(kHIDPage_Button), @"usage":@8},
192
193            @{@"reportID": @(1), @"size":@8, @"offset":@24, @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_X), @"min": @0, @"max": @255},
194            @{@"reportID": @(1), @"size":@8, @"offset":@32, @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_Y), @"min": @255, @"max": @0},
195
196            @{@"reportID": @(1), @"size":@8, @"offset":@40, @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_Rx), @"min": @0, @"max": @255},
197            @{@"reportID": @(1), @"size":@8, @"offset":@48, @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_Ry), @"min": @255, @"max": @0},
198
199            @{@"reportID": @(1), @"size":@8, @"offset":@56, @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_Z), @"min": @0, @"max": @255},
200            @{@"reportID": @(1), @"size":@8, @"offset":@64, @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_Rz), @"min": @0, @"max": @255},
201
202            // Player 2
203
204            @{@"reportID": @(2), @"size":@1, @"offset":@(4 + 72), @"usagePage":@(0xFF00), @"usage":@2, @"min": @0, @"max": @1},
205
206
207            @{@"reportID": @(2), @"size":@1, @"offset":@(8 + 72), @"usagePage":@(kHIDPage_Button), @"usage":@1},
208            @{@"reportID": @(2), @"size":@1, @"offset":@(9 + 72), @"usagePage":@(kHIDPage_Button), @"usage":@2},
209            @{@"reportID": @(2), @"size":@1, @"offset":@(10 + 72), @"usagePage":@(kHIDPage_Button), @"usage":@3},
210            @{@"reportID": @(2), @"size":@1, @"offset":@(11 + 72), @"usagePage":@(kHIDPage_Button), @"usage":@4},
211
212            @{@"reportID": @(2), @"size":@1, @"offset":@(12 + 72),  @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_DPadLeft)},
213            @{@"reportID": @(2), @"size":@1, @"offset":@(13 + 72),  @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_DPadRight)},
214            @{@"reportID": @(2), @"size":@1, @"offset":@(14 + 72), @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_DPadDown)},
215            @{@"reportID": @(2), @"size":@1, @"offset":@(15 + 72), @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_DPadUp)},
216
217
218            @{@"reportID": @(2), @"size":@1, @"offset":@(16 + 72), @"usagePage":@(kHIDPage_Button), @"usage":@5},
219            @{@"reportID": @(2), @"size":@1, @"offset":@(17 + 72), @"usagePage":@(kHIDPage_Button), @"usage":@6},
220            @{@"reportID": @(2), @"size":@1, @"offset":@(18 + 72), @"usagePage":@(kHIDPage_Button), @"usage":@7},
221            @{@"reportID": @(2), @"size":@1, @"offset":@(19 + 72), @"usagePage":@(kHIDPage_Button), @"usage":@8},
222
223            @{@"reportID": @(2), @"size":@8, @"offset":@(24 + 72), @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_X), @"min": @0, @"max": @255},
224            @{@"reportID": @(2), @"size":@8, @"offset":@(32 + 72), @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_Y), @"min": @255, @"max": @0},
225
226            @{@"reportID": @(2), @"size":@8, @"offset":@(40 + 72), @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_Rx), @"min": @0, @"max": @255},
227            @{@"reportID": @(2), @"size":@8, @"offset":@(48 + 72), @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_Ry), @"min": @255, @"max": @0},
228
229            @{@"reportID": @(2), @"size":@8, @"offset":@(56 + 72), @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_Z), @"min": @0, @"max": @255},
230            @{@"reportID": @(2), @"size":@8, @"offset":@(64 + 72), @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_Rz), @"min": @0, @"max": @255},
231
232            // Player 3
233
234            @{@"reportID": @(3), @"size":@1, @"offset":@(4 + 144), @"usagePage":@(0xFF00), @"usage":@2, @"min": @0, @"max": @1},
235
236            @{@"reportID": @(3), @"size":@1, @"offset":@(8 + 144), @"usagePage":@(kHIDPage_Button), @"usage":@1},
237            @{@"reportID": @(3), @"size":@1, @"offset":@(9 + 144), @"usagePage":@(kHIDPage_Button), @"usage":@2},
238            @{@"reportID": @(3), @"size":@1, @"offset":@(10 + 144), @"usagePage":@(kHIDPage_Button), @"usage":@3},
239            @{@"reportID": @(3), @"size":@1, @"offset":@(11 + 144), @"usagePage":@(kHIDPage_Button), @"usage":@4},
240
241            @{@"reportID": @(3), @"size":@1, @"offset":@(12 + 144),  @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_DPadLeft)},
242            @{@"reportID": @(3), @"size":@1, @"offset":@(13 + 144),  @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_DPadRight)},
243            @{@"reportID": @(3), @"size":@1, @"offset":@(14 + 144), @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_DPadDown)},
244            @{@"reportID": @(3), @"size":@1, @"offset":@(15 + 144), @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_DPadUp)},
245
246
247            @{@"reportID": @(3), @"size":@1, @"offset":@(16 + 144), @"usagePage":@(kHIDPage_Button), @"usage":@5},
248            @{@"reportID": @(3), @"size":@1, @"offset":@(17 + 144), @"usagePage":@(kHIDPage_Button), @"usage":@6},
249            @{@"reportID": @(3), @"size":@1, @"offset":@(18 + 144), @"usagePage":@(kHIDPage_Button), @"usage":@7},
250            @{@"reportID": @(3), @"size":@1, @"offset":@(19 + 144), @"usagePage":@(kHIDPage_Button), @"usage":@8},
251
252            @{@"reportID": @(3), @"size":@8, @"offset":@(24 + 144), @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_X), @"min": @0, @"max": @255},
253            @{@"reportID": @(3), @"size":@8, @"offset":@(32 + 144), @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_Y), @"min": @255, @"max": @0},
254
255            @{@"reportID": @(3), @"size":@8, @"offset":@(40 + 144), @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_Rx), @"min": @0, @"max": @255},
256            @{@"reportID": @(3), @"size":@8, @"offset":@(48 + 144), @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_Ry), @"min": @255, @"max": @0},
257
258            @{@"reportID": @(3), @"size":@8, @"offset":@(56 + 144), @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_Z), @"min": @0, @"max": @255},
259            @{@"reportID": @(3), @"size":@8, @"offset":@(64 + 144), @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_Rz), @"min": @0, @"max": @255},
260
261            // Player 4
262
263            @{@"reportID": @(4), @"size":@1, @"offset":@(4 + 216), @"usagePage":@(0xFF00), @"usage":@2, @"min": @0, @"max": @1},
264
265            @{@"reportID": @(4), @"size":@1, @"offset":@(8 + 216), @"usagePage":@(kHIDPage_Button), @"usage":@1},
266            @{@"reportID": @(4), @"size":@1, @"offset":@(9 + 216), @"usagePage":@(kHIDPage_Button), @"usage":@2},
267            @{@"reportID": @(4), @"size":@1, @"offset":@(10 + 216), @"usagePage":@(kHIDPage_Button), @"usage":@3},
268            @{@"reportID": @(4), @"size":@1, @"offset":@(11 + 216), @"usagePage":@(kHIDPage_Button), @"usage":@4},
269
270            @{@"reportID": @(4), @"size":@1, @"offset":@(12 + 216),  @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_DPadLeft)},
271            @{@"reportID": @(4), @"size":@1, @"offset":@(13 + 216),  @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_DPadRight)},
272            @{@"reportID": @(4), @"size":@1, @"offset":@(14 + 216), @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_DPadDown)},
273            @{@"reportID": @(4), @"size":@1, @"offset":@(15 + 216), @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_DPadUp)},
274
275
276            @{@"reportID": @(4), @"size":@1, @"offset":@(16 + 216), @"usagePage":@(kHIDPage_Button), @"usage":@5},
277            @{@"reportID": @(4), @"size":@1, @"offset":@(17 + 216), @"usagePage":@(kHIDPage_Button), @"usage":@6},
278            @{@"reportID": @(4), @"size":@1, @"offset":@(18 + 216), @"usagePage":@(kHIDPage_Button), @"usage":@7},
279            @{@"reportID": @(4), @"size":@1, @"offset":@(19 + 216), @"usagePage":@(kHIDPage_Button), @"usage":@8},
280
281            @{@"reportID": @(4), @"size":@8, @"offset":@(24 + 216), @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_X), @"min": @0, @"max": @255},
282            @{@"reportID": @(4), @"size":@8, @"offset":@(32 + 216), @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_Y), @"min": @255, @"max": @0},
283
284            @{@"reportID": @(4), @"size":@8, @"offset":@(40 + 216), @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_Rx), @"min": @0, @"max": @255},
285            @{@"reportID": @(4), @"size":@8, @"offset":@(48 + 216), @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_Ry), @"min": @255, @"max": @0},
286
287            @{@"reportID": @(4), @"size":@8, @"offset":@(56 + 216), @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_Z), @"min": @0, @"max": @255},
288            @{@"reportID": @(4), @"size":@8, @"offset":@(64 + 216), @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_Rz), @"min": @0, @"max": @255},
289
290
291        ]},
292    },
293
294    @"GameCube Controller Adapter": @{ // GameCube Controller PC Adapter
295        JOYAxisGroups: @{
296            @(kHIDUsage_GD_X): @(0),
297            @(kHIDUsage_GD_Y): @(0),
298            @(kHIDUsage_GD_Z): @(1),
299            @(kHIDUsage_GD_Rx): @(2),
300            @(kHIDUsage_GD_Ry): @(3),
301            @(kHIDUsage_GD_Rz): @(1),
302        },
303        JOYReportIDFilters: @[@[@1], @[@2], @[@3], @[@4]],
304        JOYButtonUsageMapping: @{
305            BUTTON(1): @(JOYButtonUsageX),
306            BUTTON(2): @(JOYButtonUsageA),
307            BUTTON(3): @(JOYButtonUsageB),
308            BUTTON(4): @(JOYButtonUsageY),
309            BUTTON(5): @(JOYButtonUsageL1),
310            BUTTON(6): @(JOYButtonUsageR1),
311            BUTTON(8): @(JOYButtonUsageZ),
312            BUTTON(10): @(JOYButtonUsageStart),
313            BUTTON(13): @(JOYButtonUsageDPadUp),
314            BUTTON(14): @(JOYButtonUsageDPadRight),
315            BUTTON(15): @(JOYButtonUsageDPadDown),
316            BUTTON(16): @(JOYButtonUsageDPadLeft),
317        },
318
319        JOYAxisUsageMapping: @{
320            AXIS(4): @(JOYAxisUsageL1),
321            AXIS(5): @(JOYAxisUsageR1),
322        },
323
324        JOYAxes2DUsageMapping: @{
325            AXES2D(1): @(JOYAxes2DUsageLeftStick),
326            AXES2D(3): @(JOYAxes2DUsageRightStick),
327        },
328
329        JOYRumbleUsage: @1,
330        JOYRumbleUsagePage: @0xFF00,
331        JOYRumbleMin: @0,
332        JOYRumbleMax: @255,
333        JOYSwapZRz: @YES,
334    },
335
336    @"Twin USB Joystick": @{ // DualShock PC Adapter
337        JOYAxisGroups: @{
338            @(kHIDUsage_GD_X): @(0),
339            @(kHIDUsage_GD_Y): @(0),
340            @(kHIDUsage_GD_Z): @(1),
341            @(kHIDUsage_GD_Rx): @(2),
342            @(kHIDUsage_GD_Ry): @(2),
343            @(kHIDUsage_GD_Rz): @(1),
344        },
345        JOYReportIDFilters: @[@[@1], @[@2]],
346        JOYButtonUsageMapping: @{
347            BUTTON(1): @(JOYButtonUsageX),
348            BUTTON(2): @(JOYButtonUsageA),
349            BUTTON(3): @(JOYButtonUsageB),
350            BUTTON(4): @(JOYButtonUsageY),
351            BUTTON(5): @(JOYButtonUsageL2),
352            BUTTON(6): @(JOYButtonUsageR2),
353            BUTTON(7): @(JOYButtonUsageL1),
354            BUTTON(8): @(JOYButtonUsageR1),
355            BUTTON(9): @(JOYButtonUsageSelect),
356            BUTTON(10): @(JOYButtonUsageStart),
357            BUTTON(11): @(JOYButtonUsageLStick),
358            BUTTON(12): @(JOYButtonUsageRStick),
359            BUTTON(13): @(JOYButtonUsageDPadUp),
360            BUTTON(14): @(JOYButtonUsageDPadRight),
361            BUTTON(15): @(JOYButtonUsageDPadDown),
362            BUTTON(16): @(JOYButtonUsageDPadLeft),
363        },
364
365        JOYAxes2DUsageMapping: @{
366            AXES2D(1): @(JOYAxes2DUsageLeftStick),
367            AXES2D(6): @(JOYAxes2DUsageRightStick),
368        },
369
370        JOYSwapZRz: @YES,
371    },
372
373    @"Pro Controller": @{ // Switch Pro Controller
374        JOYIsSwitch: @YES,
375        JOYAxisGroups: @{
376              @(kHIDUsage_GD_X): @(0),
377              @(kHIDUsage_GD_Y): @(0),
378              @(kHIDUsage_GD_Z): @(0),
379              @(kHIDUsage_GD_Rx): @(1),
380              @(kHIDUsage_GD_Ry): @(1),
381              @(kHIDUsage_GD_Rz): @(1),
382        },
383
384        JOYButtonUsageMapping: @{
385            BUTTON(1): @(JOYButtonUsageB),
386            BUTTON(2): @(JOYButtonUsageA),
387            BUTTON(3): @(JOYButtonUsageY),
388            BUTTON(4): @(JOYButtonUsageX),
389            BUTTON(5): @(JOYButtonUsageL1),
390            BUTTON(6): @(JOYButtonUsageR1),
391            BUTTON(7): @(JOYButtonUsageL2),
392            BUTTON(8): @(JOYButtonUsageR2),
393            BUTTON(9): @(JOYButtonUsageSelect),
394            BUTTON(10): @(JOYButtonUsageStart),
395            BUTTON(11): @(JOYButtonUsageLStick),
396            BUTTON(12): @(JOYButtonUsageRStick),
397            BUTTON(13): @(JOYButtonUsageHome),
398            BUTTON(14): @(JOYButtonUsageMisc),
399        },
400
401        JOYAxes2DUsageMapping: @{
402            AXES2D(1): @(JOYAxes2DUsageLeftStick),
403            AXES2D(4): @(JOYAxes2DUsageRightStick),
404        },
405
406        JOYCustomReports: @{
407            @(0x30): @[
408
409            // For USB mode, which uses the wrong report descriptor
410
411            @{@"reportID": @(1), @"size":@1, @"offset":@16, @"usagePage":@(kHIDPage_Button), @"usage":@3},
412            @{@"reportID": @(1), @"size":@1, @"offset":@17, @"usagePage":@(kHIDPage_Button), @"usage":@4},
413            @{@"reportID": @(1), @"size":@1, @"offset":@18, @"usagePage":@(kHIDPage_Button), @"usage":@1},
414            @{@"reportID": @(1), @"size":@1, @"offset":@19, @"usagePage":@(kHIDPage_Button), @"usage":@2},
415
416            // SR and SL not used on the Pro Controller
417            @{@"reportID": @(1), @"size":@1, @"offset":@22, @"usagePage":@(kHIDPage_Button), @"usage":@6},
418            @{@"reportID": @(1), @"size":@1, @"offset":@23, @"usagePage":@(kHIDPage_Button), @"usage":@8},
419
420            @{@"reportID": @(1), @"size":@1, @"offset":@24, @"usagePage":@(kHIDPage_Button), @"usage":@9},
421            @{@"reportID": @(1), @"size":@1, @"offset":@25, @"usagePage":@(kHIDPage_Button), @"usage":@10},
422            @{@"reportID": @(1), @"size":@1, @"offset":@26, @"usagePage":@(kHIDPage_Button), @"usage":@12},
423            @{@"reportID": @(1), @"size":@1, @"offset":@27, @"usagePage":@(kHIDPage_Button), @"usage":@11},
424
425            @{@"reportID": @(1), @"size":@1, @"offset":@28, @"usagePage":@(kHIDPage_Button), @"usage":@13},
426            @{@"reportID": @(1), @"size":@1, @"offset":@29, @"usagePage":@(kHIDPage_Button), @"usage":@14},
427
428            @{@"reportID": @(1), @"size":@1, @"offset":@32, @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_DPadDown)},
429            @{@"reportID": @(1), @"size":@1, @"offset":@33, @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_DPadUp)},
430            @{@"reportID": @(1), @"size":@1, @"offset":@34, @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_DPadRight)},
431            @{@"reportID": @(1), @"size":@1, @"offset":@35, @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_DPadLeft)},
432
433            // SR and SL not used on the Pro Controller
434            @{@"reportID": @(1), @"size":@1, @"offset":@38, @"usagePage":@(kHIDPage_Button), @"usage":@5},
435            @{@"reportID": @(1), @"size":@1, @"offset":@39, @"usagePage":@(kHIDPage_Button), @"usage":@7},
436
437            /* Sticks */
438            @{@"reportID": @(1), @"size":@12, @"offset":@40, @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_X), @"min": @0, @"max": @0xFFF},
439            @{@"reportID": @(1), @"size":@12, @"offset":@52, @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_Y), @"min": @0xFFF, @"max": @0},
440
441            @{@"reportID": @(1), @"size":@12, @"offset":@64, @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_Rx), @"min": @0, @"max": @0xFFF},
442            @{@"reportID": @(1), @"size":@12, @"offset":@76, @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_Ry), @"min": @0xFFF, @"max": @0},
443            ],
444        },
445
446        JOYIgnoredReports: @[@(0x30)], // Ignore the real 0x30 report as it's broken
447    },
448    @"PLAYSTATION(R)3 Controller": @{ // DualShock 3
449        JOYAxisGroups: @{
450            @(kHIDUsage_GD_X): @(0),
451            @(kHIDUsage_GD_Y): @(0),
452            @(kHIDUsage_GD_Z): @(1),
453            @(kHIDUsage_GD_Rx): @(2),
454            @(kHIDUsage_GD_Ry): @(3),
455            @(kHIDUsage_GD_Rz): @(1),
456        },
457
458        JOYButtonUsageMapping: @{
459            BUTTON(1): @(JOYButtonUsageSelect),
460            BUTTON(2): @(JOYButtonUsageL3),
461            BUTTON(3): @(JOYButtonUsageR3),
462            BUTTON(4): @(JOYButtonUsageStart),
463            BUTTON(5): @(JOYButtonUsageDPadUp),
464            BUTTON(6): @(JOYButtonUsageDPadRight),
465            BUTTON(7): @(JOYButtonUsageDPadDown),
466            BUTTON(8): @(JOYButtonUsageDPadLeft),
467            BUTTON(9): @(JOYButtonUsageL2),
468            BUTTON(10): @(JOYButtonUsageR2),
469            BUTTON(11): @(JOYButtonUsageL1),
470            BUTTON(12): @(JOYButtonUsageR1),
471            BUTTON(13): @(JOYButtonUsageX),
472            BUTTON(14): @(JOYButtonUsageA),
473            BUTTON(15): @(JOYButtonUsageB),
474            BUTTON(16): @(JOYButtonUsageY),
475            BUTTON(17): @(JOYButtonUsageHome),
476        },
477
478        JOYAxisUsageMapping: @{
479            AXIS(4): @(JOYAxisUsageL1),
480            AXIS(5): @(JOYAxisUsageR1),
481            AXIS(8): @(JOYAxisUsageL2),
482            AXIS(9): @(JOYAxisUsageR2),
483        },
484
485        JOYAxes2DUsageMapping: @{
486            AXES2D(1): @(JOYAxes2DUsageLeftStick),
487            AXES2D(3): @(JOYAxes2DUsageRightStick),
488        },
489
490        JOYCustomReports: @{
491            @(0x01): @[
492            /* Pressure sensitive inputs */
493            @{@"reportID": @(1), @"size":@8, @"offset":@(13 * 8), @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_Slider), @"min": @0, @"max": @255},
494            @{@"reportID": @(1), @"size":@8, @"offset":@(14 * 8), @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_Slider), @"min": @0, @"max": @255},
495            @{@"reportID": @(1), @"size":@8, @"offset":@(15 * 8), @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_Slider), @"min": @0, @"max": @255},
496            @{@"reportID": @(1), @"size":@8, @"offset":@(16 * 8), @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_Slider), @"min": @0, @"max": @255},
497            @{@"reportID": @(1), @"size":@8, @"offset":@(17 * 8), @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_Dial), @"min": @0, @"max": @255},
498            @{@"reportID": @(1), @"size":@8, @"offset":@(18 * 8), @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_Wheel), @"min": @0, @"max": @255},
499            @{@"reportID": @(1), @"size":@8, @"offset":@(19 * 8), @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_Rx), @"min": @0, @"max": @255},
500            @{@"reportID": @(1), @"size":@8, @"offset":@(20 * 8), @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_Ry), @"min": @0, @"max": @255},
501            @{@"reportID": @(1), @"size":@8, @"offset":@(21 * 8), @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_Slider), @"min": @0, @"max": @255},
502            @{@"reportID": @(1), @"size":@8, @"offset":@(22 * 8), @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_Slider), @"min": @0, @"max": @255},
503            @{@"reportID": @(1), @"size":@8, @"offset":@(23 * 8), @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_Slider), @"min": @0, @"max": @255},
504            @{@"reportID": @(1), @"size":@8, @"offset":@(24 * 8), @"usagePage":@(kHIDPage_GenericDesktop), @"usage":@(kHIDUsage_GD_Slider), @"min": @0, @"max": @255},
505            ]
506        },
507
508        JOYIsDualShock3: @YES,
509    },
510
511};
512