21 #include "../../SDL_internal.h" 23 #include "../SDL_sysjoystick.h" 25 #if SDL_JOYSTICK_DINPUT 31 #ifndef DIDFT_OPTIONAL 32 #define DIDFT_OPTIONAL 0x80000000 35 #define INPUT_QSIZE 32 36 #define JOY_AXIS_THRESHOLD (((SDL_JOYSTICK_AXIS_MAX)-(SDL_JOYSTICK_AXIS_MIN))/100) 39 extern HWND SDL_HelperWindow;
43 static LPDIRECTINPUT8 dinput =
NULL;
44 static PRAWINPUTDEVICELIST SDL_RawDevList =
NULL;
45 static UINT SDL_RawDevListCount = 0;
48 static DIOBJECTDATAFORMAT dfDIJoystick2[] = {
49 { &GUID_XAxis, DIJOFS_X, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
50 { &GUID_YAxis, DIJOFS_Y, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
51 { &GUID_ZAxis, DIJOFS_Z, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
52 { &GUID_RxAxis, DIJOFS_RX, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
53 { &GUID_RyAxis, DIJOFS_RY, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
54 { &GUID_RzAxis, DIJOFS_RZ, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
55 { &GUID_Slider, DIJOFS_SLIDER(0), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
56 { &GUID_Slider, DIJOFS_SLIDER(1), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
57 { &GUID_POV, DIJOFS_POV(0), DIDFT_OPTIONAL | DIDFT_POV | DIDFT_ANYINSTANCE, 0 },
58 { &GUID_POV, DIJOFS_POV(1), DIDFT_OPTIONAL | DIDFT_POV | DIDFT_ANYINSTANCE, 0 },
59 { &GUID_POV, DIJOFS_POV(2), DIDFT_OPTIONAL | DIDFT_POV | DIDFT_ANYINSTANCE, 0 },
60 { &GUID_POV, DIJOFS_POV(3), DIDFT_OPTIONAL | DIDFT_POV | DIDFT_ANYINSTANCE, 0 },
61 {
NULL, DIJOFS_BUTTON(0), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
62 {
NULL, DIJOFS_BUTTON(1), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
63 {
NULL, DIJOFS_BUTTON(2), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
64 {
NULL, DIJOFS_BUTTON(3), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
65 {
NULL, DIJOFS_BUTTON(4), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
66 {
NULL, DIJOFS_BUTTON(5), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
67 {
NULL, DIJOFS_BUTTON(6), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
68 {
NULL, DIJOFS_BUTTON(7), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
69 {
NULL, DIJOFS_BUTTON(8), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
70 {
NULL, DIJOFS_BUTTON(9), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
71 {
NULL, DIJOFS_BUTTON(10), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
72 {
NULL, DIJOFS_BUTTON(11), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
73 {
NULL, DIJOFS_BUTTON(12), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
74 {
NULL, DIJOFS_BUTTON(13), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
75 {
NULL, DIJOFS_BUTTON(14), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
76 {
NULL, DIJOFS_BUTTON(15), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
77 {
NULL, DIJOFS_BUTTON(16), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
78 {
NULL, DIJOFS_BUTTON(17), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
79 {
NULL, DIJOFS_BUTTON(18), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
80 {
NULL, DIJOFS_BUTTON(19), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
81 {
NULL, DIJOFS_BUTTON(20), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
82 {
NULL, DIJOFS_BUTTON(21), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
83 {
NULL, DIJOFS_BUTTON(22), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
84 {
NULL, DIJOFS_BUTTON(23), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
85 {
NULL, DIJOFS_BUTTON(24), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
86 {
NULL, DIJOFS_BUTTON(25), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
87 {
NULL, DIJOFS_BUTTON(26), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
88 {
NULL, DIJOFS_BUTTON(27), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
89 {
NULL, DIJOFS_BUTTON(28), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
90 {
NULL, DIJOFS_BUTTON(29), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
91 {
NULL, DIJOFS_BUTTON(30), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
92 {
NULL, DIJOFS_BUTTON(31), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
93 {
NULL, DIJOFS_BUTTON(32), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
94 {
NULL, DIJOFS_BUTTON(33), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
95 {
NULL, DIJOFS_BUTTON(34), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
96 {
NULL, DIJOFS_BUTTON(35), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
97 {
NULL, DIJOFS_BUTTON(36), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
98 {
NULL, DIJOFS_BUTTON(37), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
99 {
NULL, DIJOFS_BUTTON(38), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
100 {
NULL, DIJOFS_BUTTON(39), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
101 {
NULL, DIJOFS_BUTTON(40), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
102 {
NULL, DIJOFS_BUTTON(41), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
103 {
NULL, DIJOFS_BUTTON(42), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
104 {
NULL, DIJOFS_BUTTON(43), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
105 {
NULL, DIJOFS_BUTTON(44), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
106 {
NULL, DIJOFS_BUTTON(45), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
107 {
NULL, DIJOFS_BUTTON(46), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
108 {
NULL, DIJOFS_BUTTON(47), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
109 {
NULL, DIJOFS_BUTTON(48), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
110 {
NULL, DIJOFS_BUTTON(49), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
111 {
NULL, DIJOFS_BUTTON(50), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
112 {
NULL, DIJOFS_BUTTON(51), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
113 {
NULL, DIJOFS_BUTTON(52), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
114 {
NULL, DIJOFS_BUTTON(53), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
115 {
NULL, DIJOFS_BUTTON(54), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
116 {
NULL, DIJOFS_BUTTON(55), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
117 {
NULL, DIJOFS_BUTTON(56), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
118 {
NULL, DIJOFS_BUTTON(57), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
119 {
NULL, DIJOFS_BUTTON(58), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
120 {
NULL, DIJOFS_BUTTON(59), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
121 {
NULL, DIJOFS_BUTTON(60), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
122 {
NULL, DIJOFS_BUTTON(61), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
123 {
NULL, DIJOFS_BUTTON(62), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
124 {
NULL, DIJOFS_BUTTON(63), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
125 {
NULL, DIJOFS_BUTTON(64), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
126 {
NULL, DIJOFS_BUTTON(65), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
127 {
NULL, DIJOFS_BUTTON(66), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
128 {
NULL, DIJOFS_BUTTON(67), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
129 {
NULL, DIJOFS_BUTTON(68), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
130 {
NULL, DIJOFS_BUTTON(69), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
131 {
NULL, DIJOFS_BUTTON(70), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
132 {
NULL, DIJOFS_BUTTON(71), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
133 {
NULL, DIJOFS_BUTTON(72), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
134 {
NULL, DIJOFS_BUTTON(73), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
135 {
NULL, DIJOFS_BUTTON(74), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
136 {
NULL, DIJOFS_BUTTON(75), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
137 {
NULL, DIJOFS_BUTTON(76), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
138 {
NULL, DIJOFS_BUTTON(77), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
139 {
NULL, DIJOFS_BUTTON(78), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
140 {
NULL, DIJOFS_BUTTON(79), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
141 {
NULL, DIJOFS_BUTTON(80), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
142 {
NULL, DIJOFS_BUTTON(81), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
143 {
NULL, DIJOFS_BUTTON(82), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
144 {
NULL, DIJOFS_BUTTON(83), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
145 {
NULL, DIJOFS_BUTTON(84), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
146 {
NULL, DIJOFS_BUTTON(85), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
147 {
NULL, DIJOFS_BUTTON(86), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
148 {
NULL, DIJOFS_BUTTON(87), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
149 {
NULL, DIJOFS_BUTTON(88), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
150 {
NULL, DIJOFS_BUTTON(89), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
151 {
NULL, DIJOFS_BUTTON(90), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
152 {
NULL, DIJOFS_BUTTON(91), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
153 {
NULL, DIJOFS_BUTTON(92), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
154 {
NULL, DIJOFS_BUTTON(93), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
155 {
NULL, DIJOFS_BUTTON(94), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
156 {
NULL, DIJOFS_BUTTON(95), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
157 {
NULL, DIJOFS_BUTTON(96), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
158 {
NULL, DIJOFS_BUTTON(97), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
159 {
NULL, DIJOFS_BUTTON(98), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
160 {
NULL, DIJOFS_BUTTON(99), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
161 {
NULL, DIJOFS_BUTTON(100), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
162 {
NULL, DIJOFS_BUTTON(101), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
163 {
NULL, DIJOFS_BUTTON(102), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
164 {
NULL, DIJOFS_BUTTON(103), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
165 {
NULL, DIJOFS_BUTTON(104), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
166 {
NULL, DIJOFS_BUTTON(105), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
167 {
NULL, DIJOFS_BUTTON(106), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
168 {
NULL, DIJOFS_BUTTON(107), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
169 {
NULL, DIJOFS_BUTTON(108), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
170 {
NULL, DIJOFS_BUTTON(109), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
171 {
NULL, DIJOFS_BUTTON(110), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
172 {
NULL, DIJOFS_BUTTON(111), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
173 {
NULL, DIJOFS_BUTTON(112), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
174 {
NULL, DIJOFS_BUTTON(113), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
175 {
NULL, DIJOFS_BUTTON(114), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
176 {
NULL, DIJOFS_BUTTON(115), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
177 {
NULL, DIJOFS_BUTTON(116), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
178 {
NULL, DIJOFS_BUTTON(117), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
179 {
NULL, DIJOFS_BUTTON(118), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
180 {
NULL, DIJOFS_BUTTON(119), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
181 {
NULL, DIJOFS_BUTTON(120), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
182 {
NULL, DIJOFS_BUTTON(121), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
183 {
NULL, DIJOFS_BUTTON(122), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
184 {
NULL, DIJOFS_BUTTON(123), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
185 {
NULL, DIJOFS_BUTTON(124), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
186 {
NULL, DIJOFS_BUTTON(125), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
187 {
NULL, DIJOFS_BUTTON(126), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
188 {
NULL, DIJOFS_BUTTON(127), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 },
189 { &GUID_XAxis,
FIELD_OFFSET(DIJOYSTATE2, lVX), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
190 { &GUID_YAxis,
FIELD_OFFSET(DIJOYSTATE2, lVY), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
191 { &GUID_ZAxis,
FIELD_OFFSET(DIJOYSTATE2, lVZ), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
192 { &GUID_RxAxis,
FIELD_OFFSET(DIJOYSTATE2, lVRx), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
193 { &GUID_RyAxis,
FIELD_OFFSET(DIJOYSTATE2, lVRy), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
194 { &GUID_RzAxis,
FIELD_OFFSET(DIJOYSTATE2, lVRz), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
195 { &GUID_Slider,
FIELD_OFFSET(DIJOYSTATE2, rglVSlider[0]), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
196 { &GUID_Slider,
FIELD_OFFSET(DIJOYSTATE2, rglVSlider[1]), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
197 { &GUID_XAxis,
FIELD_OFFSET(DIJOYSTATE2, lAX), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
198 { &GUID_YAxis,
FIELD_OFFSET(DIJOYSTATE2, lAY), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
199 { &GUID_ZAxis,
FIELD_OFFSET(DIJOYSTATE2, lAZ), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
200 { &GUID_RxAxis,
FIELD_OFFSET(DIJOYSTATE2, lARx), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
201 { &GUID_RyAxis,
FIELD_OFFSET(DIJOYSTATE2, lARy), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
202 { &GUID_RzAxis,
FIELD_OFFSET(DIJOYSTATE2, lARz), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
203 { &GUID_Slider,
FIELD_OFFSET(DIJOYSTATE2, rglASlider[0]), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
204 { &GUID_Slider,
FIELD_OFFSET(DIJOYSTATE2, rglASlider[1]), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
205 { &GUID_XAxis,
FIELD_OFFSET(DIJOYSTATE2, lFX), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
206 { &GUID_YAxis,
FIELD_OFFSET(DIJOYSTATE2, lFY), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
207 { &GUID_ZAxis,
FIELD_OFFSET(DIJOYSTATE2, lFZ), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
208 { &GUID_RxAxis,
FIELD_OFFSET(DIJOYSTATE2, lFRx), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
209 { &GUID_RyAxis,
FIELD_OFFSET(DIJOYSTATE2, lFRy), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
210 { &GUID_RzAxis,
FIELD_OFFSET(DIJOYSTATE2, lFRz), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
211 { &GUID_Slider,
FIELD_OFFSET(DIJOYSTATE2, rglFSlider[0]), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
212 { &GUID_Slider,
FIELD_OFFSET(DIJOYSTATE2, rglFSlider[1]), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 },
215 const DIDATAFORMAT SDL_c_dfDIJoystick2 = {
216 sizeof(DIDATAFORMAT),
217 sizeof(DIOBJECTDATAFORMAT),
226 SetDIerror(
const char *
function, HRESULT code)
232 return SDL_SetError(
"%s() DirectX error 0x%8.8lx",
function, code);
236 SDL_IsXInputDevice(
const GUID* pGuidProductFromDirectInput)
238 static GUID IID_ValveStreamingGamepad = { MAKELONG(0x28DE, 0x11FF), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
239 static GUID IID_X360WiredGamepad = { MAKELONG(0x045E, 0x02A1), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
240 static GUID IID_X360WirelessGamepad = { MAKELONG(0x045E, 0x028E), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
241 static GUID IID_XOneWiredGamepad = { MAKELONG(0x045E, 0x02FF), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
242 static GUID IID_XOneWirelessGamepad = { MAKELONG(0x045E, 0x02DD), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
243 static GUID IID_XOneNewWirelessGamepad = { MAKELONG(0x045E, 0x02D1), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
244 static GUID IID_XOneSWirelessGamepad = { MAKELONG(0x045E, 0x02EA), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
245 static GUID IID_XOneSBluetoothGamepad = { MAKELONG(0x045E, 0x02E0), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
246 static GUID IID_XOneEliteWirelessGamepad = { MAKELONG(0x045E, 0x02E3), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
248 static const GUID *s_XInputProductGUID[] = {
249 &IID_ValveStreamingGamepad,
250 &IID_X360WiredGamepad,
251 &IID_X360WirelessGamepad,
252 &IID_XOneWiredGamepad,
253 &IID_XOneWirelessGamepad,
254 &IID_XOneNewWirelessGamepad,
255 &IID_XOneSWirelessGamepad,
256 &IID_XOneSBluetoothGamepad,
257 &IID_XOneEliteWirelessGamepad
269 for (iDevice = 0; iDevice <
SDL_arraysize(s_XInputProductGUID); ++iDevice) {
270 if (
SDL_memcmp(pGuidProductFromDirectInput, s_XInputProductGUID[iDevice],
sizeof(GUID)) == 0) {
277 if (SDL_RawDevList ==
NULL) {
278 if ((GetRawInputDeviceList(
NULL, &SDL_RawDevListCount,
sizeof(RAWINPUTDEVICELIST)) == -1) || (!SDL_RawDevListCount)) {
282 SDL_RawDevList = (PRAWINPUTDEVICELIST)
SDL_malloc(
sizeof(RAWINPUTDEVICELIST) * SDL_RawDevListCount);
283 if (SDL_RawDevList ==
NULL) {
288 if (GetRawInputDeviceList(SDL_RawDevList, &SDL_RawDevListCount,
sizeof(RAWINPUTDEVICELIST)) == -1) {
290 SDL_RawDevList =
NULL;
295 for (i = 0; i < SDL_RawDevListCount; i++) {
298 UINT rdiSize =
sizeof(rdi);
301 rdi.cbSize =
sizeof(rdi);
302 if ((SDL_RawDevList[i].dwType == RIM_TYPEHID) &&
303 (GetRawInputDeviceInfoA(SDL_RawDevList[i].hDevice, RIDI_DEVICEINFO, &rdi, &rdiSize) != ((UINT)-1)) &&
304 (MAKELONG(rdi.hid.dwVendorId, rdi.hid.dwProductId) == ((LONG)pGuidProductFromDirectInput->Data1)) &&
305 (GetRawInputDeviceInfoA(SDL_RawDevList[i].hDevice, RIDI_DEVICENAME, devName, &nameSize) != ((UINT)-1)) &&
322 return SetDIerror(
"CoInitialize", result);
327 result = CoCreateInstance(&CLSID_DirectInput8,
NULL, CLSCTX_INPROC_SERVER,
328 &IID_IDirectInput8, (LPVOID)&dinput);
331 return SetDIerror(
"CoCreateInstance", result);
335 instance = GetModuleHandle(
NULL);
336 if (instance ==
NULL) {
337 return SDL_SetError(
"GetModuleHandle() failed with error code %lu.", GetLastError());
342 return SetDIerror(
"IDirectInput::Initialize", result);
349 EnumJoysticksCallback(
const DIDEVICEINSTANCE * pdidInstance, VOID * pContext)
351 const Uint16 BUS_USB = 0x03;
352 const Uint16 BUS_BLUETOOTH = 0x05;
355 const DWORD devtype = (pdidInstance->dwDevType & 0xFF);
357 WCHAR hidPath[MAX_PATH];
359 if (devtype == DI8DEVTYPE_SUPPLEMENTAL) {
361 #define MAKE_TABLE_ENTRY(VID, PID) ((((DWORD)PID)<<16)|VID) 362 static DWORD ignored_devices[] = {
363 MAKE_TABLE_ENTRY(0, 0)
365 #undef MAKE_TABLE_ENTRY 369 if (pdidInstance->guidProduct.Data1 == ignored_devices[i]) {
370 return DIENUM_CONTINUE;
375 if (SDL_IsXInputDevice(&pdidInstance->guidProduct)) {
376 return DIENUM_CONTINUE;
381 LPDIRECTINPUTDEVICE8
device;
382 LPDIRECTINPUTDEVICE8 InputDevice;
383 DIPROPGUIDANDPATH dipdw2;
385 result = IDirectInput8_CreateDevice(dinput, &(pdidInstance->guidInstance), &device,
NULL);
387 return DIENUM_CONTINUE;
391 result = IDirectInputDevice8_QueryInterface(device, &IID_IDirectInputDevice8, (LPVOID *)&InputDevice);
393 IDirectInputDevice8_Release(device);
395 return DIENUM_CONTINUE;
397 dipdw2.diph.dwSize =
sizeof(dipdw2);
398 dipdw2.diph.dwHeaderSize =
sizeof(dipdw2.diph);
399 dipdw2.diph.dwObj = 0;
400 dipdw2.diph.dwHow = DIPH_DEVICE;
402 result = IDirectInputDevice8_GetProperty(InputDevice, DIPROP_GUIDANDPATH, &dipdw2.diph);
403 IDirectInputDevice8_Release(InputDevice);
405 return DIENUM_CONTINUE;
413 while (pNewJoystick) {
418 }
else if (pPrevJoystick) {
423 pNewJoystick->
dxdevice = *pdidInstance;
428 return DIENUM_CONTINUE;
431 pPrevJoystick = pNewJoystick;
432 pNewJoystick = pNewJoystick->
pNext;
437 return DIENUM_CONTINUE;
445 return DIENUM_CONTINUE;
454 if (
SDL_memcmp(&pdidInstance->guidProduct.Data4[2],
"PIDVID", 6) == 0) {
472 return DIENUM_CONTINUE;
477 return DIENUM_CONTINUE;
483 IDirectInput8_EnumDevices(dinput, DI8DEVCLASS_GAMECTRL, EnumJoysticksCallback, pContext, DIEDFL_ATTACHEDONLY);
485 if (SDL_RawDevList) {
487 SDL_RawDevList =
NULL;
489 SDL_RawDevListCount = 0;
493 EnumDevObjectsCallback(LPCDIDEVICEOBJECTINSTANCE dev, LPVOID pvRef)
495 SDL_Joystick *joystick = (SDL_Joystick *)pvRef;
497 input_t *
in = &joystick->hwdata->Inputs[joystick->hwdata->NumInputs];
499 if (dev->dwType & DIDFT_BUTTON) {
501 in->
num = joystick->nbuttons;
502 in->
ofs = DIJOFS_BUTTON(in->
num);
503 joystick->nbuttons++;
504 }
else if (dev->dwType & DIDFT_POV) {
506 in->
num = joystick->nhats;
507 in->
ofs = DIJOFS_POV(in->
num);
509 }
else if (dev->dwType & DIDFT_AXIS) {
514 in->
num = joystick->naxes;
515 if (!
SDL_memcmp(&dev->guidType, &GUID_XAxis,
sizeof(dev->guidType)))
517 else if (!
SDL_memcmp(&dev->guidType, &GUID_YAxis,
sizeof(dev->guidType)))
519 else if (!
SDL_memcmp(&dev->guidType, &GUID_ZAxis,
sizeof(dev->guidType)))
521 else if (!
SDL_memcmp(&dev->guidType, &GUID_RxAxis,
sizeof(dev->guidType)))
523 else if (!
SDL_memcmp(&dev->guidType, &GUID_RyAxis,
sizeof(dev->guidType)))
525 else if (!
SDL_memcmp(&dev->guidType, &GUID_RzAxis,
sizeof(dev->guidType)))
527 else if (!
SDL_memcmp(&dev->guidType, &GUID_Slider,
sizeof(dev->guidType))) {
528 in->
ofs = DIJOFS_SLIDER(joystick->hwdata->NumSliders);
529 ++joystick->hwdata->NumSliders;
531 return DIENUM_CONTINUE;
534 diprg.diph.dwSize =
sizeof(diprg);
535 diprg.diph.dwHeaderSize =
sizeof(diprg.diph);
536 diprg.diph.dwObj = dev->dwType;
537 diprg.diph.dwHow = DIPH_BYID;
542 IDirectInputDevice8_SetProperty(joystick->hwdata->InputDevice,
543 DIPROP_RANGE, &diprg.diph);
545 return DIENUM_CONTINUE;
549 dilong.diph.dwSize =
sizeof(dilong);
550 dilong.diph.dwHeaderSize =
sizeof(dilong.diph);
551 dilong.diph.dwObj = dev->dwType;
552 dilong.diph.dwHow = DIPH_BYID;
555 IDirectInputDevice8_SetProperty(joystick->hwdata->InputDevice,
556 DIPROP_DEADZONE, &dilong.diph);
558 return DIENUM_CONTINUE;
564 return DIENUM_CONTINUE;
567 joystick->hwdata->NumInputs++;
569 if (joystick->hwdata->NumInputs ==
MAX_INPUTS) {
573 return DIENUM_CONTINUE;
580 SortDevFunc(
const void *
a,
const void *
b)
585 if (inputA->
ofs < inputB->
ofs)
587 if (inputA->
ofs > inputB->
ofs)
594 SortDevObjects(SDL_Joystick *joystick)
596 input_t *inputs = joystick->hwdata->Inputs;
602 SDL_qsort(inputs, joystick->hwdata->NumInputs,
sizeof(
input_t), SortDevFunc);
604 for (n = 0; n < joystick->hwdata->NumInputs; n++) {
605 switch (inputs[n].
type) {
607 inputs[
n].
num = nButtons;
612 inputs[
n].
num = nHats;
617 inputs[
n].
num = nAxis;
628 LPDIRECTINPUTDEVICE8
device;
631 joystick->hwdata->buffered =
SDL_TRUE;
632 joystick->hwdata->Capabilities.dwSize =
sizeof(DIDEVCAPS);
635 dipdw.diph.dwSize =
sizeof(DIPROPDWORD);
636 dipdw.diph.dwHeaderSize =
sizeof(DIPROPHEADER);
639 IDirectInput8_CreateDevice(dinput,
640 &(joystickdevice->
dxdevice.guidInstance), &device,
NULL);
642 return SetDIerror(
"IDirectInput::CreateDevice", result);
646 result = IDirectInputDevice8_QueryInterface(device,
647 &IID_IDirectInputDevice8,
648 (LPVOID *)& joystick->
651 IDirectInputDevice8_Release(device);
654 return SetDIerror(
"IDirectInputDevice8::QueryInterface", result);
660 IDirectInputDevice8_SetCooperativeLevel(joystick->hwdata->
661 InputDevice, SDL_HelperWindow,
665 return SetDIerror(
"IDirectInputDevice8::SetCooperativeLevel", result);
670 IDirectInputDevice8_SetDataFormat(joystick->hwdata->InputDevice,
671 &SDL_c_dfDIJoystick2);
673 return SetDIerror(
"IDirectInputDevice8::SetDataFormat", result);
678 IDirectInputDevice8_GetCapabilities(joystick->hwdata->InputDevice,
679 &joystick->hwdata->Capabilities);
681 return SetDIerror(
"IDirectInputDevice8::GetCapabilities", result);
685 if (joystick->hwdata->Capabilities.dwFlags & DIDC_FORCEFEEDBACK) {
687 result = IDirectInputDevice8_Acquire(joystick->hwdata->InputDevice);
689 return SetDIerror(
"IDirectInputDevice8::Acquire", result);
694 IDirectInputDevice8_SendForceFeedbackCommand(joystick->hwdata->
704 result = IDirectInputDevice8_Unacquire(joystick->hwdata->InputDevice);
707 return SetDIerror(
"IDirectInputDevice8::Unacquire", result);
712 dipdw.diph.dwObj = 0;
713 dipdw.diph.dwHow = DIPH_DEVICE;
714 dipdw.dwData = DIPROPAUTOCENTER_ON;
717 IDirectInputDevice8_SetProperty(joystick->hwdata->InputDevice,
718 DIPROP_AUTOCENTER, &dipdw.diph);
728 IDirectInputDevice8_EnumObjects(joystick->hwdata->InputDevice,
729 EnumDevObjectsCallback, joystick,
730 DIDFT_BUTTON | DIDFT_AXIS | DIDFT_POV);
734 SortDevObjects(joystick);
736 dipdw.diph.dwObj = 0;
737 dipdw.diph.dwHow = DIPH_DEVICE;
738 dipdw.dwData = INPUT_QSIZE;
742 IDirectInputDevice8_SetProperty(joystick->hwdata->InputDevice,
743 DIPROP_BUFFERSIZE, &dipdw.diph);
745 if (result == DI_POLLEDDEVICE) {
749 }
else if (
FAILED(result)) {
750 return SetDIerror(
"IDirectInputDevice8::SetProperty", result);
756 TranslatePOV(DWORD
value)
758 const int HAT_VALS[] = {
769 if (LOWORD(value) == 0xFFFF)
780 return HAT_VALS[
value];
784 UpdateDINPUTJoystickState_Buffered(SDL_Joystick * joystick)
789 DIDEVICEOBJECTDATA evtbuf[INPUT_QSIZE];
791 numevents = INPUT_QSIZE;
793 IDirectInputDevice8_GetDeviceData(joystick->hwdata->InputDevice,
794 sizeof(DIDEVICEOBJECTDATA), evtbuf,
796 if (result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED) {
797 IDirectInputDevice8_Acquire(joystick->hwdata->InputDevice);
799 IDirectInputDevice8_GetDeviceData(joystick->hwdata->InputDevice,
800 sizeof(DIDEVICEOBJECTDATA),
801 evtbuf, &numevents, 0);
806 joystick->hwdata->send_remove_event =
SDL_TRUE;
807 joystick->hwdata->removed =
SDL_TRUE;
811 for (i = 0; i < (int)numevents; ++
i) {
814 for (j = 0; j < joystick->hwdata->NumInputs; ++
j) {
815 const input_t *in = &joystick->hwdata->Inputs[
j];
817 if (evtbuf[i].dwOfs != in->
ofs)
830 Uint8 pos = TranslatePOV(evtbuf[i].dwData);
845 UpdateDINPUTJoystickState_Polled(SDL_Joystick * joystick)
852 IDirectInputDevice8_GetDeviceState(joystick->hwdata->InputDevice,
853 sizeof(DIJOYSTATE2), &state);
854 if (result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED) {
855 IDirectInputDevice8_Acquire(joystick->hwdata->InputDevice);
857 IDirectInputDevice8_GetDeviceState(joystick->hwdata->InputDevice,
858 sizeof(DIJOYSTATE2), &state);
861 if (result != DI_OK) {
862 joystick->hwdata->send_remove_event =
SDL_TRUE;
863 joystick->hwdata->removed =
SDL_TRUE;
868 for (i = 0; i < joystick->hwdata->NumInputs; ++
i) {
869 const input_t *in = &joystick->hwdata->Inputs[
i];
892 case DIJOFS_SLIDER(0):
895 case DIJOFS_SLIDER(1):
907 Uint8 pos = TranslatePOV(state.rgdwPOV[in->
ofs - DIJOFS_POV(0)]);
920 result = IDirectInputDevice8_Poll(joystick->hwdata->InputDevice);
921 if (result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED) {
922 IDirectInputDevice8_Acquire(joystick->hwdata->InputDevice);
923 IDirectInputDevice8_Poll(joystick->hwdata->InputDevice);
926 if (joystick->hwdata->buffered) {
927 UpdateDINPUTJoystickState_Buffered(joystick);
929 UpdateDINPUTJoystickState_Polled(joystick);
936 IDirectInputDevice8_Unacquire(joystick->hwdata->InputDevice);
937 IDirectInputDevice8_Release(joystick->hwdata->InputDevice);
943 if (dinput !=
NULL) {
944 IDirectInput8_Release(dinput);
JoyStick_DeviceData * SYS_Joystick
int SDL_PrivateJoystickHat(SDL_Joystick *joystick, Uint8 hat, Uint8 value)
#define DIRECTINPUT_VERSION
struct JoyStick_DeviceData * pNext
void SDL_SYS_AddJoystickDevice(JoyStick_DeviceData *device)
int SDL_PrivateJoystickButton(SDL_Joystick *joystick, Uint8 button, Uint8 state)
int SDL_PrivateJoystickAxis(SDL_Joystick *joystick, Uint8 axis, Sint16 value)
static SDL_AudioDeviceID device
#define SDL_JOYSTICK_AXIS_MIN
struct joystick_hwdata * hwdata
#define SDL_JOYSTICK_AXIS_MAX
HRESULT WIN_CoInitialize(void)
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int int in j)
SDL_bool SDL_ShouldIgnoreGameController(const char *name, SDL_JoystickGUID guid)
GLsizei const GLfloat * value
#define WIN_StringToUTF8(S)
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
SDL_bool SDL_IsGameControllerNameAndGUID(const char *name, SDL_JoystickGUID guid)
#define SDL_OutOfMemory()
void WIN_CoUninitialize(void)
GLuint GLuint GLsizei GLenum type
#define SDL_arraysize(array)
DIDEVICEINSTANCE dxdevice
GLboolean GLboolean GLboolean GLboolean a
GLboolean GLboolean GLboolean b
#define FIELD_OFFSET(type, field)
#define SDL_Unsupported()