Mercurial > sdl-ios-xcode
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: */ |