comparison src/joystick/windows/SDL_dxjoystick.c @ 5062:e8916fe9cfc8

Fixed bug #925 Changed "win32" to "windows"
author Sam Lantinga <slouken@libsdl.org>
date Thu, 20 Jan 2011 18:04:05 -0800
parents src/joystick/win32/SDL_dxjoystick.c@7953336267c2
children 327f181542f1
comparison
equal deleted inserted replaced
5061:9e9940eae455 5062:e8916fe9cfc8
1 /*
2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997-2010 Sam Lantinga
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
19 Sam Lantinga
20 slouken@libsdl.org
21 */
22 #include "SDL_config.h"
23
24 #ifdef SDL_JOYSTICK_DINPUT
25
26 /* DirectInput joystick driver; written by Glenn Maynard, based on Andrei de
27 * A. Formiga's WINMM driver.
28 *
29 * Hats and sliders are completely untested; the app I'm writing this for mostly
30 * doesn't use them and I don't own any joysticks with them.
31 *
32 * We don't bother to use event notification here. It doesn't seem to work
33 * with polled devices, and it's fine to call IDirectInputDevice2_GetDeviceData and
34 * let it return 0 events. */
35
36 #include "SDL_error.h"
37 #include "SDL_events.h"
38 #include "SDL_joystick.h"
39 #include "../SDL_sysjoystick.h"
40 #include "../SDL_joystick_c.h"
41 #define INITGUID /* Only set here, if set twice will cause mingw32 to break. */
42 #include "SDL_dxjoystick_c.h"
43
44
45 #ifndef DIDFT_OPTIONAL
46 #define DIDFT_OPTIONAL 0x80000000
47 #endif
48
49
50 #define INPUT_QSIZE 32 /* Buffer up to 32 input messages */
51 #define MAX_JOYSTICKS 8
52 #define AXIS_MIN -32768 /* minimum value for axis coordinate */
53 #define AXIS_MAX 32767 /* maximum value for axis coordinate */
54 #define JOY_AXIS_THRESHOLD (((AXIS_MAX)-(AXIS_MIN))/100) /* 1% motion */
55
56 /* external variables referenced. */
57 extern HWND SDL_HelperWindow;
58
59
60 /* local variables */
61 static LPDIRECTINPUT dinput = NULL;
62 extern HRESULT(WINAPI * DInputCreate) (HINSTANCE hinst, DWORD dwVersion,
63 LPDIRECTINPUT * ppDI,
64 LPUNKNOWN punkOuter);
65 static DIDEVICEINSTANCE SYS_Joystick[MAX_JOYSTICKS]; /* array to hold joystick ID values */
66 static int SYS_NumJoysticks;
67 static HINSTANCE DInputDLL = NULL;
68
69
70 /* local prototypes */
71 static void SetDIerror(const char *function, HRESULT code);
72 static BOOL CALLBACK EnumJoysticksCallback(const DIDEVICEINSTANCE *
73 pdidInstance, VOID * pContext);
74 static BOOL CALLBACK EnumDevObjectsCallback(LPCDIDEVICEOBJECTINSTANCE dev,
75 LPVOID pvRef);
76 static Uint8 TranslatePOV(DWORD value);
77 static int SDL_PrivateJoystickAxis_Int(SDL_Joystick * joystick, Uint8 axis,
78 Sint16 value);
79 static int SDL_PrivateJoystickHat_Int(SDL_Joystick * joystick, Uint8 hat,
80 Uint8 value);
81 static int SDL_PrivateJoystickButton_Int(SDL_Joystick * joystick,
82 Uint8 button, Uint8 state);
83
84 /* Taken from Wine - Thanks! */
85 DIOBJECTDATAFORMAT dfDIJoystick2[] = {
86 { &GUID_XAxis,DIJOFS_X,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
87 { &GUID_YAxis,DIJOFS_Y,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
88 { &GUID_ZAxis,DIJOFS_Z,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
89 { &GUID_RxAxis,DIJOFS_RX,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
90 { &GUID_RyAxis,DIJOFS_RY,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
91 { &GUID_RzAxis,DIJOFS_RZ,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
92 { &GUID_Slider,DIJOFS_SLIDER(0),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
93 { &GUID_Slider,DIJOFS_SLIDER(1),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
94 { &GUID_POV,DIJOFS_POV(0),DIDFT_OPTIONAL|DIDFT_POV|DIDFT_ANYINSTANCE,0},
95 { &GUID_POV,DIJOFS_POV(1),DIDFT_OPTIONAL|DIDFT_POV|DIDFT_ANYINSTANCE,0},
96 { &GUID_POV,DIJOFS_POV(2),DIDFT_OPTIONAL|DIDFT_POV|DIDFT_ANYINSTANCE,0},
97 { &GUID_POV,DIJOFS_POV(3),DIDFT_OPTIONAL|DIDFT_POV|DIDFT_ANYINSTANCE,0},
98 { NULL,DIJOFS_BUTTON(0),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
99 { NULL,DIJOFS_BUTTON(1),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
100 { NULL,DIJOFS_BUTTON(2),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
101 { NULL,DIJOFS_BUTTON(3),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
102 { NULL,DIJOFS_BUTTON(4),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
103 { NULL,DIJOFS_BUTTON(5),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
104 { NULL,DIJOFS_BUTTON(6),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
105 { NULL,DIJOFS_BUTTON(7),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
106 { NULL,DIJOFS_BUTTON(8),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
107 { NULL,DIJOFS_BUTTON(9),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
108 { NULL,DIJOFS_BUTTON(10),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
109 { NULL,DIJOFS_BUTTON(11),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
110 { NULL,DIJOFS_BUTTON(12),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
111 { NULL,DIJOFS_BUTTON(13),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
112 { NULL,DIJOFS_BUTTON(14),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
113 { NULL,DIJOFS_BUTTON(15),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
114 { NULL,DIJOFS_BUTTON(16),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
115 { NULL,DIJOFS_BUTTON(17),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
116 { NULL,DIJOFS_BUTTON(18),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
117 { NULL,DIJOFS_BUTTON(19),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
118 { NULL,DIJOFS_BUTTON(20),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
119 { NULL,DIJOFS_BUTTON(21),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
120 { NULL,DIJOFS_BUTTON(22),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
121 { NULL,DIJOFS_BUTTON(23),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
122 { NULL,DIJOFS_BUTTON(24),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
123 { NULL,DIJOFS_BUTTON(25),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
124 { NULL,DIJOFS_BUTTON(26),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
125 { NULL,DIJOFS_BUTTON(27),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
126 { NULL,DIJOFS_BUTTON(28),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
127 { NULL,DIJOFS_BUTTON(29),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
128 { NULL,DIJOFS_BUTTON(30),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
129 { NULL,DIJOFS_BUTTON(31),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
130 { NULL,DIJOFS_BUTTON(32),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
131 { NULL,DIJOFS_BUTTON(33),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
132 { NULL,DIJOFS_BUTTON(34),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
133 { NULL,DIJOFS_BUTTON(35),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
134 { NULL,DIJOFS_BUTTON(36),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
135 { NULL,DIJOFS_BUTTON(37),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
136 { NULL,DIJOFS_BUTTON(38),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
137 { NULL,DIJOFS_BUTTON(39),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
138 { NULL,DIJOFS_BUTTON(40),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
139 { NULL,DIJOFS_BUTTON(41),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
140 { NULL,DIJOFS_BUTTON(42),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
141 { NULL,DIJOFS_BUTTON(43),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
142 { NULL,DIJOFS_BUTTON(44),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
143 { NULL,DIJOFS_BUTTON(45),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
144 { NULL,DIJOFS_BUTTON(46),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
145 { NULL,DIJOFS_BUTTON(47),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
146 { NULL,DIJOFS_BUTTON(48),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
147 { NULL,DIJOFS_BUTTON(49),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
148 { NULL,DIJOFS_BUTTON(50),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
149 { NULL,DIJOFS_BUTTON(51),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
150 { NULL,DIJOFS_BUTTON(52),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
151 { NULL,DIJOFS_BUTTON(53),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
152 { NULL,DIJOFS_BUTTON(54),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
153 { NULL,DIJOFS_BUTTON(55),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
154 { NULL,DIJOFS_BUTTON(56),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
155 { NULL,DIJOFS_BUTTON(57),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
156 { NULL,DIJOFS_BUTTON(58),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
157 { NULL,DIJOFS_BUTTON(59),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
158 { NULL,DIJOFS_BUTTON(60),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
159 { NULL,DIJOFS_BUTTON(61),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
160 { NULL,DIJOFS_BUTTON(62),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
161 { NULL,DIJOFS_BUTTON(63),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
162 { NULL,DIJOFS_BUTTON(64),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
163 { NULL,DIJOFS_BUTTON(65),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
164 { NULL,DIJOFS_BUTTON(66),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
165 { NULL,DIJOFS_BUTTON(67),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
166 { NULL,DIJOFS_BUTTON(68),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
167 { NULL,DIJOFS_BUTTON(69),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
168 { NULL,DIJOFS_BUTTON(70),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
169 { NULL,DIJOFS_BUTTON(71),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
170 { NULL,DIJOFS_BUTTON(72),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
171 { NULL,DIJOFS_BUTTON(73),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
172 { NULL,DIJOFS_BUTTON(74),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
173 { NULL,DIJOFS_BUTTON(75),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
174 { NULL,DIJOFS_BUTTON(76),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
175 { NULL,DIJOFS_BUTTON(77),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
176 { NULL,DIJOFS_BUTTON(78),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
177 { NULL,DIJOFS_BUTTON(79),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
178 { NULL,DIJOFS_BUTTON(80),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
179 { NULL,DIJOFS_BUTTON(81),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
180 { NULL,DIJOFS_BUTTON(82),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
181 { NULL,DIJOFS_BUTTON(83),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
182 { NULL,DIJOFS_BUTTON(84),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
183 { NULL,DIJOFS_BUTTON(85),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
184 { NULL,DIJOFS_BUTTON(86),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
185 { NULL,DIJOFS_BUTTON(87),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
186 { NULL,DIJOFS_BUTTON(88),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
187 { NULL,DIJOFS_BUTTON(89),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
188 { NULL,DIJOFS_BUTTON(90),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
189 { NULL,DIJOFS_BUTTON(91),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
190 { NULL,DIJOFS_BUTTON(92),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
191 { NULL,DIJOFS_BUTTON(93),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
192 { NULL,DIJOFS_BUTTON(94),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
193 { NULL,DIJOFS_BUTTON(95),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
194 { NULL,DIJOFS_BUTTON(96),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
195 { NULL,DIJOFS_BUTTON(97),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
196 { NULL,DIJOFS_BUTTON(98),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
197 { NULL,DIJOFS_BUTTON(99),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
198 { NULL,DIJOFS_BUTTON(100),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
199 { NULL,DIJOFS_BUTTON(101),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
200 { NULL,DIJOFS_BUTTON(102),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
201 { NULL,DIJOFS_BUTTON(103),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
202 { NULL,DIJOFS_BUTTON(104),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
203 { NULL,DIJOFS_BUTTON(105),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
204 { NULL,DIJOFS_BUTTON(106),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
205 { NULL,DIJOFS_BUTTON(107),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
206 { NULL,DIJOFS_BUTTON(108),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
207 { NULL,DIJOFS_BUTTON(109),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
208 { NULL,DIJOFS_BUTTON(110),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
209 { NULL,DIJOFS_BUTTON(111),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
210 { NULL,DIJOFS_BUTTON(112),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
211 { NULL,DIJOFS_BUTTON(113),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
212 { NULL,DIJOFS_BUTTON(114),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
213 { NULL,DIJOFS_BUTTON(115),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
214 { NULL,DIJOFS_BUTTON(116),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
215 { NULL,DIJOFS_BUTTON(117),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
216 { NULL,DIJOFS_BUTTON(118),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
217 { NULL,DIJOFS_BUTTON(119),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
218 { NULL,DIJOFS_BUTTON(120),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
219 { NULL,DIJOFS_BUTTON(121),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
220 { NULL,DIJOFS_BUTTON(122),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
221 { NULL,DIJOFS_BUTTON(123),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
222 { NULL,DIJOFS_BUTTON(124),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
223 { NULL,DIJOFS_BUTTON(125),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
224 { NULL,DIJOFS_BUTTON(126),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
225 { NULL,DIJOFS_BUTTON(127),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
226 { &GUID_XAxis,FIELD_OFFSET(DIJOYSTATE2,lVX),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
227 { &GUID_YAxis,FIELD_OFFSET(DIJOYSTATE2,lVY),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
228 { &GUID_ZAxis,FIELD_OFFSET(DIJOYSTATE2,lVZ),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
229 { &GUID_RxAxis,FIELD_OFFSET(DIJOYSTATE2,lVRx),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
230 { &GUID_RyAxis,FIELD_OFFSET(DIJOYSTATE2,lVRy),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
231 { &GUID_RzAxis,FIELD_OFFSET(DIJOYSTATE2,lVRz),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
232 { &GUID_Slider,FIELD_OFFSET(DIJOYSTATE2,rglVSlider[0]),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
233 { &GUID_Slider,FIELD_OFFSET(DIJOYSTATE2,rglVSlider[1]),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
234 { &GUID_XAxis,FIELD_OFFSET(DIJOYSTATE2,lAX),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
235 { &GUID_YAxis,FIELD_OFFSET(DIJOYSTATE2,lAY),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
236 { &GUID_ZAxis,FIELD_OFFSET(DIJOYSTATE2,lAZ),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
237 { &GUID_RxAxis,FIELD_OFFSET(DIJOYSTATE2,lARx),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
238 { &GUID_RyAxis,FIELD_OFFSET(DIJOYSTATE2,lARy),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
239 { &GUID_RzAxis,FIELD_OFFSET(DIJOYSTATE2,lARz),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
240 { &GUID_Slider,FIELD_OFFSET(DIJOYSTATE2,rglASlider[0]),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
241 { &GUID_Slider,FIELD_OFFSET(DIJOYSTATE2,rglASlider[1]),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
242 { &GUID_XAxis,FIELD_OFFSET(DIJOYSTATE2,lFX),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
243 { &GUID_YAxis,FIELD_OFFSET(DIJOYSTATE2,lFY),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
244 { &GUID_ZAxis,FIELD_OFFSET(DIJOYSTATE2,lFZ),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
245 { &GUID_RxAxis,FIELD_OFFSET(DIJOYSTATE2,lFRx),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
246 { &GUID_RyAxis,FIELD_OFFSET(DIJOYSTATE2,lFRy),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
247 { &GUID_RzAxis,FIELD_OFFSET(DIJOYSTATE2,lFRz),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
248 { &GUID_Slider,FIELD_OFFSET(DIJOYSTATE2,rglFSlider[0]),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
249 { &GUID_Slider,FIELD_OFFSET(DIJOYSTATE2,rglFSlider[1]),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
250 };
251
252 const DIDATAFORMAT c_dfDIJoystick2 = {
253 sizeof(DIDATAFORMAT),
254 sizeof(DIOBJECTDATAFORMAT),
255 DIDF_ABSAXIS,
256 sizeof(DIJOYSTATE2),
257 SDL_arraysize(dfDIJoystick2),
258 dfDIJoystick2
259 };
260
261
262 /* Convert a DirectInput return code to a text message */
263 static void
264 SetDIerror(const char *function, HRESULT code)
265 {
266 /*
267 SDL_SetError("%s() [%s]: %s", function,
268 DXGetErrorString9A(code), DXGetErrorDescription9A(code));
269 */
270 SDL_SetError("%s() DirectX error %d", function, code);
271 }
272
273
274 /* Function to scan the system for joysticks.
275 * This function should set SDL_numjoysticks to the number of available
276 * joysticks. Joystick 0 should be the system default joystick.
277 * It should return 0, or -1 on an unrecoverable fatal error.
278 */
279 int
280 SDL_SYS_JoystickInit(void)
281 {
282 HRESULT result;
283 HINSTANCE instance;
284
285 SYS_NumJoysticks = 0;
286
287 result = CoInitialize(NULL);
288 if (FAILED(result)) {
289 SetDIerror("CoInitialize", result);
290 return (-1);
291 }
292
293 result = CoCreateInstance(&CLSID_DirectInput, NULL, CLSCTX_INPROC_SERVER,
294 &IID_IDirectInput, (LPVOID)&dinput);
295
296 if (FAILED(result)) {
297 SetDIerror("CoCreateInstance", result);
298 return (-1);
299 }
300
301 /* Because we used CoCreateInstance, we need to Initialize it, first. */
302 instance = GetModuleHandle(NULL);
303 if (instance == NULL) {
304 SDL_SetError("GetModuleHandle() failed with error code %d.",
305 GetLastError());
306 return (-1);
307 }
308 result = IDirectInput_Initialize(dinput, instance, DIRECTINPUT_VERSION);
309
310 if (FAILED(result)) {
311 SetDIerror("IDirectInput::Initialize", result);
312 return (-1);
313 }
314
315 /* Look for joysticks, wheels, head trackers, gamepads, etc.. */
316 result = IDirectInput_EnumDevices(dinput,
317 DIDEVTYPE_JOYSTICK,
318 EnumJoysticksCallback,
319 NULL, DIEDFL_ATTACHEDONLY);
320
321 return SYS_NumJoysticks;
322 }
323
324 static BOOL CALLBACK
325 EnumJoysticksCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext)
326 {
327 SDL_memcpy(&SYS_Joystick[SYS_NumJoysticks], pdidInstance,
328 sizeof(DIDEVICEINSTANCE));
329 SYS_NumJoysticks++;
330
331 if (SYS_NumJoysticks >= MAX_JOYSTICKS)
332 return DIENUM_STOP;
333
334 return DIENUM_CONTINUE;
335 }
336
337 /* Function to get the device-dependent name of a joystick */
338 const char *
339 SDL_SYS_JoystickName(int index)
340 {
341 /***-> test for invalid index ? */
342 return (SYS_Joystick[index].tszProductName);
343 }
344
345 /* Function to open a joystick for use.
346 The joystick to open is specified by the index field of the joystick.
347 This should fill the nbuttons and naxes fields of the joystick structure.
348 It returns 0, or -1 if there is an error.
349 */
350 int
351 SDL_SYS_JoystickOpen(SDL_Joystick * joystick)
352 {
353 HRESULT result;
354 LPDIRECTINPUTDEVICE device;
355 DIPROPDWORD dipdw;
356
357 SDL_memset(&dipdw, 0, sizeof(DIPROPDWORD));
358 dipdw.diph.dwSize = sizeof(DIPROPDWORD);
359 dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
360
361
362 /* allocate memory for system specific hardware data */
363 joystick->hwdata =
364 (struct joystick_hwdata *) SDL_malloc(sizeof(struct joystick_hwdata));
365 if (joystick->hwdata == NULL) {
366 SDL_OutOfMemory();
367 return (-1);
368 }
369 SDL_memset(joystick->hwdata, 0, sizeof(struct joystick_hwdata));
370 joystick->hwdata->buffered = 1;
371 joystick->hwdata->Capabilities.dwSize = sizeof(DIDEVCAPS);
372
373 result =
374 IDirectInput_CreateDevice(dinput,
375 &SYS_Joystick[joystick->index].
376 guidInstance, &device, NULL);
377 if (FAILED(result)) {
378 SetDIerror("IDirectInput::CreateDevice", result);
379 return (-1);
380 }
381
382 /* Now get the IDirectInputDevice2 interface, instead. */
383 result = IDirectInputDevice_QueryInterface(device,
384 &IID_IDirectInputDevice2,
385 (LPVOID *) & joystick->
386 hwdata->InputDevice);
387 /* We are done with this object. Use the stored one from now on. */
388 IDirectInputDevice_Release(device);
389
390 if (FAILED(result)) {
391 SetDIerror("IDirectInputDevice::QueryInterface", result);
392 return (-1);
393 }
394
395 /* Aquire shared access. Exclusive access is required for forces,
396 * though. */
397 result =
398 IDirectInputDevice2_SetCooperativeLevel(joystick->hwdata->
399 InputDevice, SDL_HelperWindow,
400 DISCL_EXCLUSIVE |
401 DISCL_BACKGROUND);
402 if (FAILED(result)) {
403 SetDIerror("IDirectInputDevice2::SetCooperativeLevel", result);
404 return (-1);
405 }
406
407 /* Use the extended data structure: DIJOYSTATE2. */
408 result =
409 IDirectInputDevice2_SetDataFormat(joystick->hwdata->InputDevice,
410 &c_dfDIJoystick2);
411 if (FAILED(result)) {
412 SetDIerror("IDirectInputDevice2::SetDataFormat", result);
413 return (-1);
414 }
415
416 /* Get device capabilities */
417 result =
418 IDirectInputDevice2_GetCapabilities(joystick->hwdata->InputDevice,
419 &joystick->hwdata->Capabilities);
420
421 if (FAILED(result)) {
422 SetDIerror("IDirectInputDevice2::GetCapabilities", result);
423 return (-1);
424 }
425
426 /* Force capable? */
427 if (joystick->hwdata->Capabilities.dwFlags & DIDC_FORCEFEEDBACK) {
428
429 result = IDirectInputDevice2_Acquire(joystick->hwdata->InputDevice);
430
431 if (FAILED(result)) {
432 SetDIerror("IDirectInputDevice2::Acquire", result);
433 return (-1);
434 }
435
436 /* reset all accuators. */
437 result =
438 IDirectInputDevice2_SendForceFeedbackCommand(joystick->hwdata->
439 InputDevice,
440 DISFFC_RESET);
441
442 /* Not necessarily supported, ignore if not supported.
443 if (FAILED(result)) {
444 SetDIerror("IDirectInputDevice2::SendForceFeedbackCommand",
445 result);
446 return (-1);
447 }
448 */
449
450 result = IDirectInputDevice2_Unacquire(joystick->hwdata->InputDevice);
451
452 if (FAILED(result)) {
453 SetDIerror("IDirectInputDevice2::Unacquire", result);
454 return (-1);
455 }
456
457 /* Turn on auto-centering for a ForceFeedback device (until told
458 * otherwise). */
459 dipdw.diph.dwObj = 0;
460 dipdw.diph.dwHow = DIPH_DEVICE;
461 dipdw.dwData = DIPROPAUTOCENTER_ON;
462
463 result =
464 IDirectInputDevice2_SetProperty(joystick->hwdata->InputDevice,
465 DIPROP_AUTOCENTER, &dipdw.diph);
466
467 /* Not necessarily supported, ignore if not supported.
468 if (FAILED(result)) {
469 SetDIerror("IDirectInputDevice2::SetProperty", result);
470 return (-1);
471 }
472 */
473 }
474
475 /* What buttons and axes does it have? */
476 IDirectInputDevice2_EnumObjects(joystick->hwdata->InputDevice,
477 EnumDevObjectsCallback, joystick,
478 DIDFT_BUTTON | DIDFT_AXIS | DIDFT_POV);
479
480 dipdw.diph.dwObj = 0;
481 dipdw.diph.dwHow = DIPH_DEVICE;
482 dipdw.dwData = INPUT_QSIZE;
483
484 /* Set the buffer size */
485 result =
486 IDirectInputDevice2_SetProperty(joystick->hwdata->InputDevice,
487 DIPROP_BUFFERSIZE, &dipdw.diph);
488
489 if (result == DI_POLLEDDEVICE) {
490 /* This device doesn't support buffering, so we're forced
491 * to use less reliable polling. */
492 joystick->hwdata->buffered = 0;
493 } else if (FAILED(result)) {
494 SetDIerror("IDirectInputDevice2::SetProperty", result);
495 return (-1);
496 }
497
498 return (0);
499 }
500
501 static BOOL CALLBACK
502 EnumDevObjectsCallback(LPCDIDEVICEOBJECTINSTANCE dev, LPVOID pvRef)
503 {
504 SDL_Joystick *joystick = (SDL_Joystick *) pvRef;
505 HRESULT result;
506 input_t *in = &joystick->hwdata->Inputs[joystick->hwdata->NumInputs];
507
508 in->ofs = dev->dwOfs;
509
510 if (dev->dwType & DIDFT_BUTTON) {
511 in->type = BUTTON;
512 in->num = joystick->nbuttons;
513 joystick->nbuttons++;
514 } else if (dev->dwType & DIDFT_POV) {
515 in->type = HAT;
516 in->num = joystick->nhats;
517 joystick->nhats++;
518 } else if (dev->dwType & DIDFT_AXIS) {
519 DIPROPRANGE diprg;
520 DIPROPDWORD dilong;
521
522 in->type = AXIS;
523 in->num = joystick->naxes;
524
525 diprg.diph.dwSize = sizeof(diprg);
526 diprg.diph.dwHeaderSize = sizeof(diprg.diph);
527 diprg.diph.dwObj = dev->dwOfs;
528 diprg.diph.dwHow = DIPH_BYOFFSET;
529 diprg.lMin = AXIS_MIN;
530 diprg.lMax = AXIS_MAX;
531
532 result =
533 IDirectInputDevice2_SetProperty(joystick->hwdata->InputDevice,
534 DIPROP_RANGE, &diprg.diph);
535 if (FAILED(result)) {
536 return DIENUM_CONTINUE; /* don't use this axis */
537 }
538
539 /* Set dead zone to 0. */
540 dilong.diph.dwSize = sizeof(dilong);
541 dilong.diph.dwHeaderSize = sizeof(dilong.diph);
542 dilong.diph.dwObj = dev->dwOfs;
543 dilong.diph.dwHow = DIPH_BYOFFSET;
544 dilong.dwData = 0;
545 result =
546 IDirectInputDevice2_SetProperty(joystick->hwdata->InputDevice,
547 DIPROP_DEADZONE, &dilong.diph);
548 if (FAILED(result)) {
549 return DIENUM_CONTINUE; /* don't use this axis */
550 }
551
552 joystick->naxes++;
553 } else {
554 /* not supported at this time */
555 return DIENUM_CONTINUE;
556 }
557
558 joystick->hwdata->NumInputs++;
559
560 if (joystick->hwdata->NumInputs == MAX_INPUTS) {
561 return DIENUM_STOP; /* too many */
562 }
563
564 return DIENUM_CONTINUE;
565 }
566
567 /* Function to update the state of a joystick - called as a device poll.
568 * This function shouldn't update the joystick structure directly,
569 * but instead should call SDL_PrivateJoystick*() to deliver events
570 * and update joystick device state.
571 */
572 void
573 SDL_SYS_JoystickUpdate_Polled(SDL_Joystick * joystick)
574 {
575 DIJOYSTATE2 state;
576 HRESULT result;
577 int i;
578
579 result =
580 IDirectInputDevice2_GetDeviceState(joystick->hwdata->InputDevice,
581 sizeof(DIJOYSTATE2), &state);
582 if (result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED) {
583 IDirectInputDevice2_Acquire(joystick->hwdata->InputDevice);
584 result =
585 IDirectInputDevice2_GetDeviceState(joystick->hwdata->InputDevice,
586 sizeof(DIJOYSTATE2), &state);
587 }
588
589 /* Set each known axis, button and POV. */
590 for (i = 0; i < joystick->hwdata->NumInputs; ++i) {
591 const input_t *in = &joystick->hwdata->Inputs[i];
592
593 switch (in->type) {
594 case AXIS:
595 switch (in->ofs) {
596 case DIJOFS_X:
597 SDL_PrivateJoystickAxis_Int(joystick, in->num,
598 (Sint16) state.lX);
599 break;
600 case DIJOFS_Y:
601 SDL_PrivateJoystickAxis_Int(joystick, in->num,
602 (Sint16) state.lY);
603 break;
604 case DIJOFS_Z:
605 SDL_PrivateJoystickAxis_Int(joystick, in->num,
606 (Sint16) state.lZ);
607 break;
608 case DIJOFS_RX:
609 SDL_PrivateJoystickAxis_Int(joystick, in->num,
610 (Sint16) state.lRx);
611 break;
612 case DIJOFS_RY:
613 SDL_PrivateJoystickAxis_Int(joystick, in->num,
614 (Sint16) state.lRy);
615 break;
616 case DIJOFS_RZ:
617 SDL_PrivateJoystickAxis_Int(joystick, in->num,
618 (Sint16) state.lRz);
619 break;
620 case DIJOFS_SLIDER(0):
621 SDL_PrivateJoystickAxis_Int(joystick, in->num,
622 (Sint16) state.rglSlider[0]);
623 break;
624 case DIJOFS_SLIDER(1):
625 SDL_PrivateJoystickAxis_Int(joystick, in->num,
626 (Sint16) state.rglSlider[1]);
627 break;
628 }
629
630 break;
631
632 case BUTTON:
633 SDL_PrivateJoystickButton_Int(joystick, in->num,
634 (Uint8) (state.
635 rgbButtons[in->ofs -
636 DIJOFS_BUTTON0]
637 ? SDL_PRESSED :
638 SDL_RELEASED));
639 break;
640 case HAT:
641 {
642 Uint8 pos = TranslatePOV(state.rgdwPOV[in->ofs -
643 DIJOFS_POV(0)]);
644 SDL_PrivateJoystickHat_Int(joystick, in->num, pos);
645 break;
646 }
647 }
648 }
649 }
650
651 void
652 SDL_SYS_JoystickUpdate_Buffered(SDL_Joystick * joystick)
653 {
654 int i;
655 HRESULT result;
656 DWORD numevents;
657 DIDEVICEOBJECTDATA evtbuf[INPUT_QSIZE];
658
659 numevents = INPUT_QSIZE;
660 result =
661 IDirectInputDevice2_GetDeviceData(joystick->hwdata->InputDevice,
662 sizeof(DIDEVICEOBJECTDATA), evtbuf,
663 &numevents, 0);
664 if (result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED) {
665 IDirectInputDevice2_Acquire(joystick->hwdata->InputDevice);
666 result =
667 IDirectInputDevice2_GetDeviceData(joystick->hwdata->InputDevice,
668 sizeof(DIDEVICEOBJECTDATA),
669 evtbuf, &numevents, 0);
670 }
671
672 /* Handle the events or punt */
673 if (FAILED(result))
674 return;
675
676 for (i = 0; i < (int) numevents; ++i) {
677 int j;
678
679 for (j = 0; j < joystick->hwdata->NumInputs; ++j) {
680 const input_t *in = &joystick->hwdata->Inputs[j];
681
682 if (evtbuf[i].dwOfs != in->ofs)
683 continue;
684
685 switch (in->type) {
686 case AXIS:
687 SDL_PrivateJoystickAxis(joystick, in->num,
688 (Sint16) evtbuf[i].dwData);
689 break;
690 case BUTTON:
691 SDL_PrivateJoystickButton(joystick, in->num,
692 (Uint8) (evtbuf[i].
693 dwData ? SDL_PRESSED :
694 SDL_RELEASED));
695 break;
696 case HAT:
697 {
698 Uint8 pos = TranslatePOV(evtbuf[i].dwData);
699 SDL_PrivateJoystickHat(joystick, in->num, pos);
700 }
701 }
702 }
703 }
704 }
705
706
707 static Uint8
708 TranslatePOV(DWORD value)
709 {
710 const int HAT_VALS[] = {
711 SDL_HAT_UP,
712 SDL_HAT_UP | SDL_HAT_RIGHT,
713 SDL_HAT_RIGHT,
714 SDL_HAT_DOWN | SDL_HAT_RIGHT,
715 SDL_HAT_DOWN,
716 SDL_HAT_DOWN | SDL_HAT_LEFT,
717 SDL_HAT_LEFT,
718 SDL_HAT_UP | SDL_HAT_LEFT
719 };
720
721 if (LOWORD(value) == 0xFFFF)
722 return SDL_HAT_CENTERED;
723
724 /* Round the value up: */
725 value += 4500 / 2;
726 value %= 36000;
727 value /= 4500;
728
729 if (value >= 8)
730 return SDL_HAT_CENTERED; /* shouldn't happen */
731
732 return HAT_VALS[value];
733 }
734
735 /* SDL_PrivateJoystick* doesn't discard duplicate events, so we need to
736 * do it. */
737 static int
738 SDL_PrivateJoystickAxis_Int(SDL_Joystick * joystick, Uint8 axis, Sint16 value)
739 {
740 if (joystick->axes[axis] != value)
741 return SDL_PrivateJoystickAxis(joystick, axis, value);
742 return 0;
743 }
744
745 static int
746 SDL_PrivateJoystickHat_Int(SDL_Joystick * joystick, Uint8 hat, Uint8 value)
747 {
748 if (joystick->hats[hat] != value)
749 return SDL_PrivateJoystickHat(joystick, hat, value);
750 return 0;
751 }
752
753 static int
754 SDL_PrivateJoystickButton_Int(SDL_Joystick * joystick, Uint8 button,
755 Uint8 state)
756 {
757 if (joystick->buttons[button] != state)
758 return SDL_PrivateJoystickButton(joystick, button, state);
759 return 0;
760 }
761
762 void
763 SDL_SYS_JoystickUpdate(SDL_Joystick * joystick)
764 {
765 HRESULT result;
766
767 result = IDirectInputDevice2_Poll(joystick->hwdata->InputDevice);
768 if (result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED) {
769 IDirectInputDevice2_Acquire(joystick->hwdata->InputDevice);
770 IDirectInputDevice2_Poll(joystick->hwdata->InputDevice);
771 }
772
773 if (joystick->hwdata->buffered)
774 SDL_SYS_JoystickUpdate_Buffered(joystick);
775 else
776 SDL_SYS_JoystickUpdate_Polled(joystick);
777 }
778
779 /* Function to close a joystick after use */
780 void
781 SDL_SYS_JoystickClose(SDL_Joystick * joystick)
782 {
783 IDirectInputDevice2_Unacquire(joystick->hwdata->InputDevice);
784 IDirectInputDevice2_Release(joystick->hwdata->InputDevice);
785
786 if (joystick->hwdata != NULL) {
787 /* free system specific hardware data */
788 SDL_free(joystick->hwdata);
789 }
790 }
791
792 /* Function to perform any system-specific joystick related cleanup */
793 void
794 SDL_SYS_JoystickQuit(void)
795 {
796 IDirectInput_Release(dinput);
797 dinput = NULL;
798 }
799
800 #endif /* SDL_JOYSTICK_DINPUT */
801
802 /* vi: set ts=4 sw=4 expandtab: */