slouken@1895
|
1 |
/*
|
slouken@5535
|
2 |
Simple DirectMedia Layer
|
slouken@6885
|
3 |
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
slouken@1895
|
4 |
|
slouken@5535
|
5 |
This software is provided 'as-is', without any express or implied
|
slouken@5535
|
6 |
warranty. In no event will the authors be held liable for any damages
|
slouken@5535
|
7 |
arising from the use of this software.
|
slouken@1895
|
8 |
|
slouken@5535
|
9 |
Permission is granted to anyone to use this software for any purpose,
|
slouken@5535
|
10 |
including commercial applications, and to alter it and redistribute it
|
slouken@5535
|
11 |
freely, subject to the following restrictions:
|
slouken@1895
|
12 |
|
slouken@5535
|
13 |
1. The origin of this software must not be misrepresented; you must not
|
slouken@5535
|
14 |
claim that you wrote the original software. If you use this software
|
slouken@5535
|
15 |
in a product, an acknowledgment in the product documentation would be
|
slouken@5535
|
16 |
appreciated but is not required.
|
slouken@5535
|
17 |
2. Altered source versions must be plainly marked as such, and must not be
|
slouken@5535
|
18 |
misrepresented as being the original software.
|
slouken@5535
|
19 |
3. This notice may not be removed or altered from any source distribution.
|
slouken@1895
|
20 |
*/
|
slouken@1895
|
21 |
#include "SDL_config.h"
|
slouken@1895
|
22 |
|
slouken@1895
|
23 |
#ifdef SDL_JOYSTICK_DINPUT
|
slouken@1895
|
24 |
|
slouken@1895
|
25 |
/* DirectInput joystick driver; written by Glenn Maynard, based on Andrei de
|
slouken@7191
|
26 |
* A. Formiga's WINMM driver.
|
slouken@1895
|
27 |
*
|
slouken@1895
|
28 |
* Hats and sliders are completely untested; the app I'm writing this for mostly
|
slouken@7191
|
29 |
* doesn't use them and I don't own any joysticks with them.
|
slouken@1895
|
30 |
*
|
slouken@1895
|
31 |
* We don't bother to use event notification here. It doesn't seem to work
|
slouken@6690
|
32 |
* with polled devices, and it's fine to call IDirectInputDevice8_GetDeviceData and
|
slouken@1895
|
33 |
* let it return 0 events. */
|
slouken@1895
|
34 |
|
slouken@1895
|
35 |
#include "SDL_error.h"
|
icculus@6993
|
36 |
#include "SDL_assert.h"
|
slouken@1895
|
37 |
#include "SDL_events.h"
|
slouken@6690
|
38 |
#include "SDL_thread.h"
|
slouken@6690
|
39 |
#include "SDL_timer.h"
|
slouken@6690
|
40 |
#include "SDL_mutex.h"
|
slouken@6690
|
41 |
#include "SDL_events.h"
|
slouken@6971
|
42 |
#include "SDL_hints.h"
|
slouken@7260
|
43 |
#include "SDL_joystick.h"
|
slouken@7260
|
44 |
#include "../SDL_sysjoystick.h"
|
slouken@6690
|
45 |
#if !SDL_EVENTS_DISABLED
|
slouken@6690
|
46 |
#include "../../events/SDL_events_c.h"
|
slouken@6690
|
47 |
#endif
|
slouken@1895
|
48 |
|
slouken@7260
|
49 |
/* The latest version of mingw-w64 defines IID_IWbemLocator in wbemcli.h
|
slouken@7260
|
50 |
instead of declaring it like Visual Studio and other mingw32 compilers.
|
slouken@7260
|
51 |
So, we need to take care of this here before we define INITGUID.
|
slouken@7260
|
52 |
*/
|
slouken@7260
|
53 |
#ifdef __MINGW32__
|
slouken@7260
|
54 |
#define __IWbemLocator_INTERFACE_DEFINED__
|
slouken@7260
|
55 |
#endif /* __MINGW32__ */
|
slouken@7260
|
56 |
|
slouken@7260
|
57 |
#define INITGUID /* Only set here, if set twice will cause mingw32 to break. */
|
slouken@7260
|
58 |
#include "SDL_dxjoystick_c.h"
|
slouken@7260
|
59 |
|
slouken@7260
|
60 |
#ifdef __MINGW32__
|
slouken@7260
|
61 |
/* And now that we've included wbemcli.h we need to declare these interfaces */
|
slouken@7260
|
62 |
typedef struct IWbemLocatorVtbl {
|
slouken@7260
|
63 |
BEGIN_INTERFACE
|
slouken@7260
|
64 |
HRESULT (WINAPI *QueryInterface)(IWbemLocator *This,REFIID riid,void **ppvObject);
|
slouken@7260
|
65 |
ULONG (WINAPI *AddRef)(IWbemLocator *This);
|
slouken@7260
|
66 |
ULONG (WINAPI *Release)(IWbemLocator *This);
|
slouken@7265
|
67 |
HRESULT (WINAPI *ConnectServer)(IWbemLocator *This,const BSTR strNetworkResource,const BSTR strUser,const BSTR strPassword,const BSTR strLocale,LONG lSecurityFlags,const BSTR strAuthority,IWbemContext *pCtx,IWbemServices **ppNamespace);
|
slouken@7260
|
68 |
END_INTERFACE
|
slouken@7260
|
69 |
} IWbemLocatorVtbl;
|
slouken@7260
|
70 |
struct IWbemLocator {
|
slouken@7260
|
71 |
CONST_VTBL struct IWbemLocatorVtbl *lpVtbl;
|
slouken@7260
|
72 |
};
|
slouken@7260
|
73 |
#define IWbemLocator_ConnectServer(This,strNetworkResource,strUser,strPassword,strLocale,lSecurityFlags,strAuthority,pCtx,ppNamespace) (This)->lpVtbl->ConnectServer(This,strNetworkResource,strUser,strPassword,strLocale,lSecurityFlags,strAuthority,pCtx,ppNamespace)
|
slouken@7260
|
74 |
#endif /* __MINGW32__ */
|
slouken@7260
|
75 |
|
slouken@2761
|
76 |
#ifndef DIDFT_OPTIONAL
|
slouken@7191
|
77 |
#define DIDFT_OPTIONAL 0x80000000
|
slouken@2761
|
78 |
#endif
|
slouken@2761
|
79 |
|
slouken@2761
|
80 |
|
slouken@7191
|
81 |
#define INPUT_QSIZE 32 /* Buffer up to 32 input messages */
|
slouken@6690
|
82 |
#define MAX_JOYSTICKS 8
|
slouken@7191
|
83 |
#define AXIS_MIN -32768 /* minimum value for axis coordinate */
|
slouken@7191
|
84 |
#define AXIS_MAX 32767 /* maximum value for axis coordinate */
|
slouken@7191
|
85 |
#define JOY_AXIS_THRESHOLD (((AXIS_MAX)-(AXIS_MIN))/100) /* 1% motion */
|
slouken@1895
|
86 |
|
slouken@2198
|
87 |
/* external variables referenced. */
|
slouken@2713
|
88 |
extern HWND SDL_HelperWindow;
|
slouken@2198
|
89 |
|
slouken@2198
|
90 |
|
slouken@2198
|
91 |
/* local variables */
|
icculus@5591
|
92 |
static SDL_bool coinitialized = SDL_FALSE;
|
icculus@6716
|
93 |
static LPDIRECTINPUT8 dinput = NULL;
|
slouken@6690
|
94 |
static SDL_bool s_bDeviceAdded = SDL_FALSE;
|
slouken@6690
|
95 |
static SDL_bool s_bDeviceRemoved = SDL_FALSE;
|
slouken@6974
|
96 |
static SDL_JoystickID s_nInstanceID = -1;
|
slouken@6690
|
97 |
static GUID *s_pKnownJoystickGUIDs = NULL;
|
slouken@6690
|
98 |
static SDL_cond *s_condJoystickThread = NULL;
|
slouken@6690
|
99 |
static SDL_mutex *s_mutexJoyStickEnum = NULL;
|
slouken@6690
|
100 |
static SDL_Thread *s_threadJoystick = NULL;
|
slouken@6690
|
101 |
static SDL_bool s_bJoystickThreadQuit = SDL_FALSE;
|
urkle@6965
|
102 |
static SDL_bool s_bXInputEnabled = SDL_TRUE;
|
slouken@6690
|
103 |
|
icculus@6991
|
104 |
XInputGetState_t SDL_XInputGetState = NULL;
|
icculus@6991
|
105 |
XInputSetState_t SDL_XInputSetState = NULL;
|
icculus@6991
|
106 |
XInputGetCapabilities_t SDL_XInputGetCapabilities = NULL;
|
icculus@6991
|
107 |
DWORD SDL_XInputVersion = 0;
|
icculus@6991
|
108 |
|
icculus@6991
|
109 |
static HANDLE s_pXInputDLL = 0;
|
icculus@6991
|
110 |
static int s_XInputDLLRefCount = 0;
|
icculus@6991
|
111 |
|
icculus@6991
|
112 |
int
|
icculus@6991
|
113 |
WIN_LoadXInputDLL(void)
|
icculus@6991
|
114 |
{
|
icculus@6991
|
115 |
DWORD version = 0;
|
icculus@6991
|
116 |
|
icculus@6991
|
117 |
if (s_pXInputDLL) {
|
icculus@6991
|
118 |
SDL_assert(s_XInputDLLRefCount > 0);
|
icculus@6991
|
119 |
s_XInputDLLRefCount++;
|
icculus@6991
|
120 |
return 0; /* already loaded */
|
icculus@6991
|
121 |
}
|
icculus@6991
|
122 |
|
icculus@6991
|
123 |
version = (1 << 16) | 4;
|
slouken@7191
|
124 |
s_pXInputDLL = LoadLibrary( L"XInput1_4.dll" ); /* 1.4 Ships with Windows 8. */
|
icculus@6991
|
125 |
if (!s_pXInputDLL) {
|
icculus@6991
|
126 |
version = (1 << 16) | 3;
|
slouken@7191
|
127 |
s_pXInputDLL = LoadLibrary( L"XInput1_3.dll" ); /* 1.3 Ships with Vista and Win7, can be installed as a redistributable component. */
|
icculus@6991
|
128 |
}
|
icculus@6991
|
129 |
if (!s_pXInputDLL) {
|
icculus@6991
|
130 |
s_pXInputDLL = LoadLibrary( L"bin\\XInput1_3.dll" );
|
icculus@6991
|
131 |
}
|
icculus@6991
|
132 |
if (!s_pXInputDLL) {
|
icculus@6991
|
133 |
return -1;
|
icculus@6991
|
134 |
}
|
icculus@6991
|
135 |
|
icculus@6991
|
136 |
SDL_assert(s_XInputDLLRefCount == 0);
|
icculus@6991
|
137 |
SDL_XInputVersion = version;
|
icculus@6991
|
138 |
s_XInputDLLRefCount = 1;
|
icculus@6991
|
139 |
|
icculus@6991
|
140 |
/* 100 is the ordinal for _XInputGetStateEx, which returns the same struct as XinputGetState, but with extra data in wButtons for the guide button, we think... */
|
icculus@6991
|
141 |
SDL_XInputGetState = (XInputGetState_t)GetProcAddress( (HMODULE)s_pXInputDLL, (LPCSTR)100 );
|
icculus@6991
|
142 |
SDL_XInputSetState = (XInputSetState_t)GetProcAddress( (HMODULE)s_pXInputDLL, "XInputSetState" );
|
icculus@6991
|
143 |
SDL_XInputGetCapabilities = (XInputGetCapabilities_t)GetProcAddress( (HMODULE)s_pXInputDLL, "XInputGetCapabilities" );
|
icculus@6991
|
144 |
if ( !SDL_XInputGetState || !SDL_XInputSetState || !SDL_XInputGetCapabilities ) {
|
icculus@6991
|
145 |
WIN_UnloadXInputDLL();
|
icculus@6991
|
146 |
return -1;
|
icculus@6991
|
147 |
}
|
icculus@6991
|
148 |
|
icculus@6991
|
149 |
return 0;
|
icculus@6991
|
150 |
}
|
icculus@6991
|
151 |
|
icculus@6991
|
152 |
void
|
icculus@6991
|
153 |
WIN_UnloadXInputDLL(void)
|
icculus@6991
|
154 |
{
|
icculus@6991
|
155 |
if ( s_pXInputDLL ) {
|
icculus@6991
|
156 |
SDL_assert(s_XInputDLLRefCount > 0);
|
icculus@6991
|
157 |
if (--s_XInputDLLRefCount == 0) {
|
icculus@6991
|
158 |
FreeLibrary( s_pXInputDLL );
|
icculus@6991
|
159 |
s_pXInputDLL = NULL;
|
icculus@6991
|
160 |
}
|
icculus@6991
|
161 |
} else {
|
icculus@6991
|
162 |
SDL_assert(s_XInputDLLRefCount == 0);
|
icculus@6991
|
163 |
}
|
icculus@6991
|
164 |
}
|
icculus@6991
|
165 |
|
icculus@6991
|
166 |
|
slouken@2198
|
167 |
extern HRESULT(WINAPI * DInputCreate) (HINSTANCE hinst, DWORD dwVersion,
|
slouken@2198
|
168 |
LPDIRECTINPUT * ppDI,
|
slouken@2198
|
169 |
LPUNKNOWN punkOuter);
|
slouken@6690
|
170 |
struct JoyStick_DeviceData_
|
slouken@6690
|
171 |
{
|
slouken@7191
|
172 |
SDL_JoystickGUID guid;
|
slouken@7191
|
173 |
DIDEVICEINSTANCE dxdevice;
|
slouken@7191
|
174 |
char *joystickname;
|
slouken@7191
|
175 |
Uint8 send_add_event;
|
slouken@7191
|
176 |
SDL_JoystickID nInstanceID;
|
slouken@7191
|
177 |
SDL_bool bXInputDevice;
|
slouken@7191
|
178 |
Uint8 XInputUserId;
|
slouken@7191
|
179 |
struct JoyStick_DeviceData_ *pNext;
|
slouken@6690
|
180 |
};
|
slouken@2198
|
181 |
|
slouken@6690
|
182 |
typedef struct JoyStick_DeviceData_ JoyStick_DeviceData;
|
slouken@6690
|
183 |
|
slouken@6690
|
184 |
static JoyStick_DeviceData *SYS_Joystick; /* array to hold joystick ID values */
|
slouken@6690
|
185 |
|
slouken@2198
|
186 |
/* local prototypes */
|
icculus@7037
|
187 |
static int SetDIerror(const char *function, HRESULT code);
|
slouken@2198
|
188 |
static BOOL CALLBACK EnumJoysticksCallback(const DIDEVICEINSTANCE *
|
slouken@2198
|
189 |
pdidInstance, VOID * pContext);
|
slouken@2198
|
190 |
static BOOL CALLBACK EnumDevObjectsCallback(LPCDIDEVICEOBJECTINSTANCE dev,
|
slouken@2198
|
191 |
LPVOID pvRef);
|
slouken@6220
|
192 |
static void SortDevObjects(SDL_Joystick *joystick);
|
slouken@2198
|
193 |
static Uint8 TranslatePOV(DWORD value);
|
slouken@2198
|
194 |
static int SDL_PrivateJoystickAxis_Int(SDL_Joystick * joystick, Uint8 axis,
|
slouken@2198
|
195 |
Sint16 value);
|
slouken@2198
|
196 |
static int SDL_PrivateJoystickHat_Int(SDL_Joystick * joystick, Uint8 hat,
|
slouken@2198
|
197 |
Uint8 value);
|
slouken@2198
|
198 |
static int SDL_PrivateJoystickButton_Int(SDL_Joystick * joystick,
|
slouken@2198
|
199 |
Uint8 button, Uint8 state);
|
slouken@2198
|
200 |
|
slouken@7191
|
201 |
/* Taken from Wine - Thanks! */
|
slouken@2760
|
202 |
DIOBJECTDATAFORMAT dfDIJoystick2[] = {
|
slouken@3013
|
203 |
{ &GUID_XAxis,DIJOFS_X,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
204 |
{ &GUID_YAxis,DIJOFS_Y,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
205 |
{ &GUID_ZAxis,DIJOFS_Z,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
206 |
{ &GUID_RxAxis,DIJOFS_RX,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
207 |
{ &GUID_RyAxis,DIJOFS_RY,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
208 |
{ &GUID_RzAxis,DIJOFS_RZ,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
209 |
{ &GUID_Slider,DIJOFS_SLIDER(0),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
210 |
{ &GUID_Slider,DIJOFS_SLIDER(1),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
211 |
{ &GUID_POV,DIJOFS_POV(0),DIDFT_OPTIONAL|DIDFT_POV|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
212 |
{ &GUID_POV,DIJOFS_POV(1),DIDFT_OPTIONAL|DIDFT_POV|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
213 |
{ &GUID_POV,DIJOFS_POV(2),DIDFT_OPTIONAL|DIDFT_POV|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
214 |
{ &GUID_POV,DIJOFS_POV(3),DIDFT_OPTIONAL|DIDFT_POV|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
215 |
{ NULL,DIJOFS_BUTTON(0),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
216 |
{ NULL,DIJOFS_BUTTON(1),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
217 |
{ NULL,DIJOFS_BUTTON(2),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
218 |
{ NULL,DIJOFS_BUTTON(3),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
219 |
{ NULL,DIJOFS_BUTTON(4),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
220 |
{ NULL,DIJOFS_BUTTON(5),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
221 |
{ NULL,DIJOFS_BUTTON(6),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
222 |
{ NULL,DIJOFS_BUTTON(7),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
223 |
{ NULL,DIJOFS_BUTTON(8),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
224 |
{ NULL,DIJOFS_BUTTON(9),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
225 |
{ NULL,DIJOFS_BUTTON(10),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
226 |
{ NULL,DIJOFS_BUTTON(11),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
227 |
{ NULL,DIJOFS_BUTTON(12),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
228 |
{ NULL,DIJOFS_BUTTON(13),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
229 |
{ NULL,DIJOFS_BUTTON(14),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
230 |
{ NULL,DIJOFS_BUTTON(15),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
231 |
{ NULL,DIJOFS_BUTTON(16),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
232 |
{ NULL,DIJOFS_BUTTON(17),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
233 |
{ NULL,DIJOFS_BUTTON(18),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
234 |
{ NULL,DIJOFS_BUTTON(19),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
235 |
{ NULL,DIJOFS_BUTTON(20),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
236 |
{ NULL,DIJOFS_BUTTON(21),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
237 |
{ NULL,DIJOFS_BUTTON(22),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
238 |
{ NULL,DIJOFS_BUTTON(23),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
239 |
{ NULL,DIJOFS_BUTTON(24),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
240 |
{ NULL,DIJOFS_BUTTON(25),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
241 |
{ NULL,DIJOFS_BUTTON(26),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
242 |
{ NULL,DIJOFS_BUTTON(27),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
243 |
{ NULL,DIJOFS_BUTTON(28),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
244 |
{ NULL,DIJOFS_BUTTON(29),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
245 |
{ NULL,DIJOFS_BUTTON(30),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
246 |
{ NULL,DIJOFS_BUTTON(31),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
247 |
{ NULL,DIJOFS_BUTTON(32),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
248 |
{ NULL,DIJOFS_BUTTON(33),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
249 |
{ NULL,DIJOFS_BUTTON(34),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
250 |
{ NULL,DIJOFS_BUTTON(35),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
251 |
{ NULL,DIJOFS_BUTTON(36),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
252 |
{ NULL,DIJOFS_BUTTON(37),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
253 |
{ NULL,DIJOFS_BUTTON(38),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
254 |
{ NULL,DIJOFS_BUTTON(39),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
255 |
{ NULL,DIJOFS_BUTTON(40),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
256 |
{ NULL,DIJOFS_BUTTON(41),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
257 |
{ NULL,DIJOFS_BUTTON(42),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
258 |
{ NULL,DIJOFS_BUTTON(43),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
259 |
{ NULL,DIJOFS_BUTTON(44),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
260 |
{ NULL,DIJOFS_BUTTON(45),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
261 |
{ NULL,DIJOFS_BUTTON(46),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
262 |
{ NULL,DIJOFS_BUTTON(47),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
263 |
{ NULL,DIJOFS_BUTTON(48),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
264 |
{ NULL,DIJOFS_BUTTON(49),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
265 |
{ NULL,DIJOFS_BUTTON(50),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
266 |
{ NULL,DIJOFS_BUTTON(51),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
267 |
{ NULL,DIJOFS_BUTTON(52),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
268 |
{ NULL,DIJOFS_BUTTON(53),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
269 |
{ NULL,DIJOFS_BUTTON(54),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
270 |
{ NULL,DIJOFS_BUTTON(55),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
271 |
{ NULL,DIJOFS_BUTTON(56),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
272 |
{ NULL,DIJOFS_BUTTON(57),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
273 |
{ NULL,DIJOFS_BUTTON(58),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
274 |
{ NULL,DIJOFS_BUTTON(59),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
275 |
{ NULL,DIJOFS_BUTTON(60),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
276 |
{ NULL,DIJOFS_BUTTON(61),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
277 |
{ NULL,DIJOFS_BUTTON(62),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
278 |
{ NULL,DIJOFS_BUTTON(63),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
279 |
{ NULL,DIJOFS_BUTTON(64),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
280 |
{ NULL,DIJOFS_BUTTON(65),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
281 |
{ NULL,DIJOFS_BUTTON(66),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
282 |
{ NULL,DIJOFS_BUTTON(67),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
283 |
{ NULL,DIJOFS_BUTTON(68),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
284 |
{ NULL,DIJOFS_BUTTON(69),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
285 |
{ NULL,DIJOFS_BUTTON(70),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
286 |
{ NULL,DIJOFS_BUTTON(71),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
287 |
{ NULL,DIJOFS_BUTTON(72),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
288 |
{ NULL,DIJOFS_BUTTON(73),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
289 |
{ NULL,DIJOFS_BUTTON(74),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
290 |
{ NULL,DIJOFS_BUTTON(75),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
291 |
{ NULL,DIJOFS_BUTTON(76),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
292 |
{ NULL,DIJOFS_BUTTON(77),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
293 |
{ NULL,DIJOFS_BUTTON(78),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
294 |
{ NULL,DIJOFS_BUTTON(79),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
295 |
{ NULL,DIJOFS_BUTTON(80),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
296 |
{ NULL,DIJOFS_BUTTON(81),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
297 |
{ NULL,DIJOFS_BUTTON(82),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
298 |
{ NULL,DIJOFS_BUTTON(83),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
299 |
{ NULL,DIJOFS_BUTTON(84),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
300 |
{ NULL,DIJOFS_BUTTON(85),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
301 |
{ NULL,DIJOFS_BUTTON(86),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
302 |
{ NULL,DIJOFS_BUTTON(87),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
303 |
{ NULL,DIJOFS_BUTTON(88),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
304 |
{ NULL,DIJOFS_BUTTON(89),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
305 |
{ NULL,DIJOFS_BUTTON(90),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
306 |
{ NULL,DIJOFS_BUTTON(91),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
307 |
{ NULL,DIJOFS_BUTTON(92),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
308 |
{ NULL,DIJOFS_BUTTON(93),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
309 |
{ NULL,DIJOFS_BUTTON(94),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
310 |
{ NULL,DIJOFS_BUTTON(95),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
311 |
{ NULL,DIJOFS_BUTTON(96),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
312 |
{ NULL,DIJOFS_BUTTON(97),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
313 |
{ NULL,DIJOFS_BUTTON(98),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
314 |
{ NULL,DIJOFS_BUTTON(99),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
315 |
{ NULL,DIJOFS_BUTTON(100),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
316 |
{ NULL,DIJOFS_BUTTON(101),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
317 |
{ NULL,DIJOFS_BUTTON(102),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
318 |
{ NULL,DIJOFS_BUTTON(103),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
319 |
{ NULL,DIJOFS_BUTTON(104),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
320 |
{ NULL,DIJOFS_BUTTON(105),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
321 |
{ NULL,DIJOFS_BUTTON(106),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
322 |
{ NULL,DIJOFS_BUTTON(107),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
323 |
{ NULL,DIJOFS_BUTTON(108),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
324 |
{ NULL,DIJOFS_BUTTON(109),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
325 |
{ NULL,DIJOFS_BUTTON(110),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
326 |
{ NULL,DIJOFS_BUTTON(111),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
327 |
{ NULL,DIJOFS_BUTTON(112),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
328 |
{ NULL,DIJOFS_BUTTON(113),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
329 |
{ NULL,DIJOFS_BUTTON(114),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
330 |
{ NULL,DIJOFS_BUTTON(115),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
331 |
{ NULL,DIJOFS_BUTTON(116),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
332 |
{ NULL,DIJOFS_BUTTON(117),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
333 |
{ NULL,DIJOFS_BUTTON(118),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
334 |
{ NULL,DIJOFS_BUTTON(119),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
335 |
{ NULL,DIJOFS_BUTTON(120),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
336 |
{ NULL,DIJOFS_BUTTON(121),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
337 |
{ NULL,DIJOFS_BUTTON(122),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
338 |
{ NULL,DIJOFS_BUTTON(123),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
339 |
{ NULL,DIJOFS_BUTTON(124),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
340 |
{ NULL,DIJOFS_BUTTON(125),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
341 |
{ NULL,DIJOFS_BUTTON(126),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
342 |
{ NULL,DIJOFS_BUTTON(127),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
343 |
{ &GUID_XAxis,FIELD_OFFSET(DIJOYSTATE2,lVX),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
344 |
{ &GUID_YAxis,FIELD_OFFSET(DIJOYSTATE2,lVY),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
345 |
{ &GUID_ZAxis,FIELD_OFFSET(DIJOYSTATE2,lVZ),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
346 |
{ &GUID_RxAxis,FIELD_OFFSET(DIJOYSTATE2,lVRx),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
347 |
{ &GUID_RyAxis,FIELD_OFFSET(DIJOYSTATE2,lVRy),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
348 |
{ &GUID_RzAxis,FIELD_OFFSET(DIJOYSTATE2,lVRz),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
349 |
{ &GUID_Slider,FIELD_OFFSET(DIJOYSTATE2,rglVSlider[0]),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
350 |
{ &GUID_Slider,FIELD_OFFSET(DIJOYSTATE2,rglVSlider[1]),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
351 |
{ &GUID_XAxis,FIELD_OFFSET(DIJOYSTATE2,lAX),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
352 |
{ &GUID_YAxis,FIELD_OFFSET(DIJOYSTATE2,lAY),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
353 |
{ &GUID_ZAxis,FIELD_OFFSET(DIJOYSTATE2,lAZ),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
354 |
{ &GUID_RxAxis,FIELD_OFFSET(DIJOYSTATE2,lARx),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
355 |
{ &GUID_RyAxis,FIELD_OFFSET(DIJOYSTATE2,lARy),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
356 |
{ &GUID_RzAxis,FIELD_OFFSET(DIJOYSTATE2,lARz),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
357 |
{ &GUID_Slider,FIELD_OFFSET(DIJOYSTATE2,rglASlider[0]),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
358 |
{ &GUID_Slider,FIELD_OFFSET(DIJOYSTATE2,rglASlider[1]),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
359 |
{ &GUID_XAxis,FIELD_OFFSET(DIJOYSTATE2,lFX),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
360 |
{ &GUID_YAxis,FIELD_OFFSET(DIJOYSTATE2,lFY),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
361 |
{ &GUID_ZAxis,FIELD_OFFSET(DIJOYSTATE2,lFZ),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
362 |
{ &GUID_RxAxis,FIELD_OFFSET(DIJOYSTATE2,lFRx),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
363 |
{ &GUID_RyAxis,FIELD_OFFSET(DIJOYSTATE2,lFRy),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
364 |
{ &GUID_RzAxis,FIELD_OFFSET(DIJOYSTATE2,lFRz),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
365 |
{ &GUID_Slider,FIELD_OFFSET(DIJOYSTATE2,rglFSlider[0]),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
|
slouken@3013
|
366 |
{ &GUID_Slider,FIELD_OFFSET(DIJOYSTATE2,rglFSlider[1]),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
|
slouken@2760
|
367 |
};
|
slouken@2760
|
368 |
|
slouken@2760
|
369 |
const DIDATAFORMAT c_dfDIJoystick2 = {
|
slouken@2760
|
370 |
sizeof(DIDATAFORMAT),
|
slouken@2760
|
371 |
sizeof(DIOBJECTDATAFORMAT),
|
slouken@2760
|
372 |
DIDF_ABSAXIS,
|
slouken@2760
|
373 |
sizeof(DIJOYSTATE2),
|
slouken@2760
|
374 |
SDL_arraysize(dfDIJoystick2),
|
slouken@2760
|
375 |
dfDIJoystick2
|
slouken@2760
|
376 |
};
|
slouken@2760
|
377 |
|
slouken@2198
|
378 |
|
slouken@1895
|
379 |
/* Convert a DirectInput return code to a text message */
|
icculus@7037
|
380 |
static int
|
slouken@2198
|
381 |
SetDIerror(const char *function, HRESULT code)
|
slouken@1895
|
382 |
{
|
slouken@2760
|
383 |
/*
|
icculus@7037
|
384 |
return SDL_SetError("%s() [%s]: %s", function,
|
slouken@3013
|
385 |
DXGetErrorString9A(code), DXGetErrorDescription9A(code));
|
slouken@2760
|
386 |
*/
|
icculus@7037
|
387 |
return SDL_SetError("%s() DirectX error %d", function, code);
|
slouken@1895
|
388 |
}
|
slouken@1895
|
389 |
|
slouken@1895
|
390 |
|
slouken@6690
|
391 |
#define SAFE_RELEASE(p) \
|
slouken@6690
|
392 |
{ \
|
slouken@7191
|
393 |
if (p) { \
|
slouken@7191
|
394 |
(p)->lpVtbl->Release((p)); \
|
slouken@7191
|
395 |
(p) = 0; \
|
slouken@7191
|
396 |
} \
|
slouken@6690
|
397 |
}
|
slouken@6690
|
398 |
|
slouken@6690
|
399 |
|
slouken@6690
|
400 |
DEFINE_GUID(CLSID_WbemLocator, 0x4590f811,0x1d3a,0x11d0,0x89,0x1F,0x00,0xaa,0x00,0x4b,0x2e,0x24);
|
slouken@7230
|
401 |
/* The Windows SDK doesn't define this GUID */
|
slouken@6690
|
402 |
DEFINE_GUID(IID_IWbemLocator, 0xdc12a687,0x737f,0x11cf,0x88,0x4d,0x00,0xaa,0x00,0x4b,0x2e,0x24);
|
slouken@6690
|
403 |
|
slouken@7191
|
404 |
/*-----------------------------------------------------------------------------
|
slouken@7191
|
405 |
*
|
slouken@7191
|
406 |
* code from MSDN: http://msdn.microsoft.com/en-us/library/windows/desktop/ee417014(v=vs.85).aspx
|
slouken@7191
|
407 |
*
|
slouken@7191
|
408 |
* Enum each PNP device using WMI and check each device ID to see if it contains
|
slouken@7191
|
409 |
* "IG_" (ex. "VID_045E&PID_028E&IG_00"). If it does, then it's an XInput device
|
slouken@7191
|
410 |
* Unfortunately this information can not be found by just using DirectInput
|
slouken@7191
|
411 |
*-----------------------------------------------------------------------------*/
|
slouken@6690
|
412 |
BOOL IsXInputDevice( const GUID* pGuidProductFromDirectInput )
|
slouken@6690
|
413 |
{
|
slouken@7191
|
414 |
IWbemLocator* pIWbemLocator = NULL;
|
slouken@7191
|
415 |
IEnumWbemClassObject* pEnumDevices = NULL;
|
slouken@7191
|
416 |
IWbemClassObject* pDevices[20];
|
slouken@7191
|
417 |
IWbemServices* pIWbemServices = NULL;
|
slouken@7191
|
418 |
DWORD uReturned = 0;
|
slouken@7191
|
419 |
BSTR bstrNamespace = NULL;
|
slouken@7191
|
420 |
BSTR bstrDeviceID = NULL;
|
slouken@7191
|
421 |
BSTR bstrClassName = NULL;
|
slouken@7191
|
422 |
SDL_bool bIsXinputDevice= SDL_FALSE;
|
slouken@7191
|
423 |
UINT iDevice = 0;
|
slouken@7191
|
424 |
VARIANT var;
|
slouken@7191
|
425 |
HRESULT hr;
|
slouken@7191
|
426 |
DWORD bCleanupCOM;
|
slouken@6690
|
427 |
|
urkle@6965
|
428 |
if (!s_bXInputEnabled)
|
urkle@6965
|
429 |
{
|
urkle@6965
|
430 |
return SDL_FALSE;
|
urkle@6965
|
431 |
}
|
urkle@6965
|
432 |
|
slouken@7191
|
433 |
SDL_memset( pDevices, 0x0, sizeof(pDevices) );
|
slouken@6690
|
434 |
|
slouken@7191
|
435 |
/* CoInit if needed */
|
slouken@7191
|
436 |
hr = CoInitialize(NULL);
|
slouken@7191
|
437 |
bCleanupCOM = SUCCEEDED(hr);
|
slouken@6690
|
438 |
|
slouken@7191
|
439 |
/* Create WMI */
|
slouken@7191
|
440 |
hr = CoCreateInstance( &CLSID_WbemLocator,
|
slouken@7191
|
441 |
NULL,
|
slouken@7191
|
442 |
CLSCTX_INPROC_SERVER,
|
slouken@7191
|
443 |
&IID_IWbemLocator,
|
slouken@7191
|
444 |
(LPVOID*) &pIWbemLocator);
|
slouken@7191
|
445 |
if( FAILED(hr) || pIWbemLocator == NULL )
|
slouken@7191
|
446 |
goto LCleanup;
|
slouken@6690
|
447 |
|
slouken@7191
|
448 |
bstrNamespace = SysAllocString( L"\\\\.\\root\\cimv2" );if( bstrNamespace == NULL ) goto LCleanup;
|
slouken@7191
|
449 |
bstrClassName = SysAllocString( L"Win32_PNPEntity" ); if( bstrClassName == NULL ) goto LCleanup;
|
slouken@7191
|
450 |
bstrDeviceID = SysAllocString( L"DeviceID" ); if( bstrDeviceID == NULL ) goto LCleanup;
|
slouken@6690
|
451 |
|
slouken@7191
|
452 |
/* Connect to WMI */
|
slouken@7191
|
453 |
hr = IWbemLocator_ConnectServer( pIWbemLocator, bstrNamespace, NULL, NULL, 0L,
|
slouken@7191
|
454 |
0L, NULL, NULL, &pIWbemServices );
|
slouken@7191
|
455 |
if( FAILED(hr) || pIWbemServices == NULL )
|
slouken@7191
|
456 |
goto LCleanup;
|
slouken@6690
|
457 |
|
slouken@7191
|
458 |
/* Switch security level to IMPERSONATE. */
|
slouken@7191
|
459 |
CoSetProxyBlanket( (IUnknown *)pIWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL,
|
slouken@7191
|
460 |
RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE );
|
slouken@6690
|
461 |
|
slouken@7191
|
462 |
hr = IWbemServices_CreateInstanceEnum( pIWbemServices, bstrClassName, 0, NULL, &pEnumDevices );
|
slouken@7191
|
463 |
if( FAILED(hr) || pEnumDevices == NULL )
|
slouken@7191
|
464 |
goto LCleanup;
|
slouken@6690
|
465 |
|
slouken@7191
|
466 |
/* Loop over all devices */
|
slouken@7191
|
467 |
for( ;; )
|
slouken@7191
|
468 |
{
|
slouken@7191
|
469 |
/* Get 20 at a time */
|
slouken@7191
|
470 |
hr = IEnumWbemClassObject_Next( pEnumDevices, 10000, 20, pDevices, &uReturned );
|
slouken@7191
|
471 |
if( FAILED(hr) )
|
slouken@7191
|
472 |
goto LCleanup;
|
slouken@7191
|
473 |
if( uReturned == 0 )
|
slouken@7191
|
474 |
break;
|
slouken@6690
|
475 |
|
slouken@7191
|
476 |
for( iDevice=0; iDevice<uReturned; iDevice++ )
|
slouken@7191
|
477 |
{
|
slouken@7191
|
478 |
/* For each device, get its device ID */
|
slouken@7191
|
479 |
hr = IWbemClassObject_Get( pDevices[iDevice], bstrDeviceID, 0L, &var, NULL, NULL );
|
slouken@7191
|
480 |
if( SUCCEEDED( hr ) && var.vt == VT_BSTR && var.bstrVal != NULL )
|
slouken@7191
|
481 |
{
|
slouken@7191
|
482 |
/* Check if the device ID contains "IG_". If it does, then it's an XInput device */
|
slouken@7191
|
483 |
/* This information can not be found from DirectInput */
|
slouken@7191
|
484 |
char *pDeviceString = WIN_StringToUTF8( var.bstrVal );
|
slouken@7191
|
485 |
if( SDL_strstr( pDeviceString, "IG_" ) )
|
slouken@7191
|
486 |
{
|
slouken@7191
|
487 |
/* If it does, then get the VID/PID from var.bstrVal */
|
slouken@7191
|
488 |
long dwPid = 0, dwVid = 0;
|
slouken@7191
|
489 |
char * strPid = NULL;
|
slouken@7191
|
490 |
DWORD dwVidPid = 0;
|
slouken@7191
|
491 |
char * strVid = SDL_strstr( pDeviceString, "VID_" );
|
slouken@7191
|
492 |
if( strVid )
|
slouken@7191
|
493 |
{
|
slouken@7191
|
494 |
dwVid = SDL_strtol( strVid + 4, NULL, 16 );
|
slouken@7191
|
495 |
}
|
slouken@7191
|
496 |
strPid = SDL_strstr( pDeviceString, "PID_" );
|
slouken@7191
|
497 |
if( strPid )
|
slouken@7191
|
498 |
{
|
slouken@7191
|
499 |
dwPid = SDL_strtol( strPid + 4, NULL, 16 );
|
slouken@7191
|
500 |
}
|
slouken@6690
|
501 |
|
slouken@7191
|
502 |
/* Compare the VID/PID to the DInput device */
|
slouken@7191
|
503 |
dwVidPid = MAKELONG( dwVid, dwPid );
|
slouken@7191
|
504 |
if( dwVidPid == pGuidProductFromDirectInput->Data1 )
|
slouken@7191
|
505 |
{
|
slouken@7191
|
506 |
bIsXinputDevice = SDL_TRUE;
|
slouken@7191
|
507 |
}
|
slouken@7191
|
508 |
}
|
slouken@7191
|
509 |
if ( pDeviceString )
|
slouken@7191
|
510 |
SDL_free( pDeviceString );
|
slouken@7191
|
511 |
|
slouken@7191
|
512 |
if ( bIsXinputDevice )
|
slouken@7191
|
513 |
break;
|
slouken@7191
|
514 |
}
|
slouken@7191
|
515 |
SAFE_RELEASE( pDevices[iDevice] );
|
slouken@7191
|
516 |
}
|
slouken@7191
|
517 |
}
|
slouken@7191
|
518 |
|
slouken@6690
|
519 |
LCleanup:
|
slouken@6690
|
520 |
|
slouken@7191
|
521 |
for( iDevice=0; iDevice<20; iDevice++ )
|
slouken@7191
|
522 |
SAFE_RELEASE( pDevices[iDevice] );
|
slouken@7191
|
523 |
SAFE_RELEASE( pEnumDevices );
|
slouken@7191
|
524 |
SAFE_RELEASE( pIWbemLocator );
|
slouken@7191
|
525 |
SAFE_RELEASE( pIWbemServices );
|
slouken@6690
|
526 |
|
slouken@7191
|
527 |
if ( bstrNamespace )
|
slouken@7191
|
528 |
SysFreeString( bstrNamespace );
|
slouken@7191
|
529 |
if ( bstrClassName )
|
slouken@7191
|
530 |
SysFreeString( bstrClassName );
|
slouken@7191
|
531 |
if ( bstrDeviceID )
|
slouken@7191
|
532 |
SysFreeString( bstrDeviceID );
|
slouken@6690
|
533 |
|
slouken@7191
|
534 |
if( bCleanupCOM )
|
slouken@7191
|
535 |
CoUninitialize();
|
slouken@7191
|
536 |
|
slouken@7191
|
537 |
return bIsXinputDevice;
|
slouken@6690
|
538 |
}
|
slouken@6690
|
539 |
|
slouken@6690
|
540 |
|
slouken@6690
|
541 |
static SDL_bool s_bWindowsDeviceChanged = SDL_FALSE;
|
slouken@6690
|
542 |
|
philipp@7133
|
543 |
/* windowproc for our joystick detect thread message only window, to detect any USB device addition/removal
|
slouken@6690
|
544 |
*/
|
slouken@6690
|
545 |
LRESULT CALLBACK SDL_PrivateJoystickDetectProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
|
slouken@7191
|
546 |
switch (message) {
|
slouken@7191
|
547 |
case WM_DEVICECHANGE:
|
slouken@7191
|
548 |
switch (wParam) {
|
slouken@7191
|
549 |
case DBT_DEVICEARRIVAL:
|
slouken@7191
|
550 |
if (((DEV_BROADCAST_HDR*)lParam)->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) {
|
slouken@7191
|
551 |
s_bWindowsDeviceChanged = SDL_TRUE;
|
slouken@7191
|
552 |
}
|
slouken@7191
|
553 |
break;
|
slouken@7191
|
554 |
case DBT_DEVICEREMOVECOMPLETE:
|
slouken@7191
|
555 |
if (((DEV_BROADCAST_HDR*)lParam)->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) {
|
slouken@7191
|
556 |
s_bWindowsDeviceChanged = SDL_TRUE;
|
slouken@7191
|
557 |
}
|
slouken@7191
|
558 |
break;
|
slouken@7191
|
559 |
}
|
slouken@7191
|
560 |
return 0;
|
slouken@7191
|
561 |
}
|
slouken@6690
|
562 |
|
slouken@7191
|
563 |
return DefWindowProc (hwnd, message, wParam, lParam);
|
slouken@6690
|
564 |
}
|
slouken@6690
|
565 |
|
slouken@6690
|
566 |
|
slouken@6690
|
567 |
DEFINE_GUID(GUID_DEVINTERFACE_USB_DEVICE, 0xA5DCBF10L, 0x6530, 0x11D2, 0x90, 0x1F, 0x00, \
|
slouken@7191
|
568 |
0xC0, 0x4F, 0xB9, 0x51, 0xED);
|
slouken@6690
|
569 |
|
slouken@6690
|
570 |
/* Function/thread to scan the system for joysticks.
|
slouken@6690
|
571 |
*/
|
slouken@6690
|
572 |
static int
|
slouken@6690
|
573 |
SDL_JoystickThread(void *_data)
|
slouken@6690
|
574 |
{
|
slouken@7191
|
575 |
HWND messageWindow = 0;
|
slouken@7191
|
576 |
HDEVNOTIFY hNotify = 0;
|
slouken@7191
|
577 |
DEV_BROADCAST_DEVICEINTERFACE dbh;
|
slouken@7191
|
578 |
SDL_bool bOpenedXInputDevices[4];
|
slouken@7191
|
579 |
WNDCLASSEX wincl;
|
slouken@6710
|
580 |
|
slouken@7191
|
581 |
SDL_memset( bOpenedXInputDevices, 0x0, sizeof(bOpenedXInputDevices) );
|
slouken@6690
|
582 |
|
slouken@7223
|
583 |
WIN_CoInitialize();
|
slouken@6690
|
584 |
|
slouken@7191
|
585 |
SDL_memset( &wincl, 0x0, sizeof(wincl) );
|
slouken@7191
|
586 |
wincl.hInstance = GetModuleHandle( NULL );
|
slouken@7191
|
587 |
wincl.lpszClassName = L"Message";
|
slouken@7191
|
588 |
wincl.lpfnWndProc = SDL_PrivateJoystickDetectProc; /* This function is called by windows */
|
slouken@7191
|
589 |
wincl.cbSize = sizeof (WNDCLASSEX);
|
slouken@6712
|
590 |
|
slouken@7191
|
591 |
if (!RegisterClassEx (&wincl))
|
slouken@7191
|
592 |
{
|
slouken@7191
|
593 |
return SDL_SetError("Failed to create register class for joystick autodetect.", GetLastError());
|
slouken@7191
|
594 |
}
|
slouken@6712
|
595 |
|
slouken@7191
|
596 |
messageWindow = (HWND)CreateWindowEx( 0, L"Message", NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL );
|
slouken@7191
|
597 |
if ( !messageWindow )
|
slouken@7191
|
598 |
{
|
slouken@7191
|
599 |
return SDL_SetError("Failed to create message window for joystick autodetect.", GetLastError());
|
slouken@7191
|
600 |
}
|
slouken@6690
|
601 |
|
slouken@7191
|
602 |
SDL_memset(&dbh, 0x0, sizeof(dbh));
|
slouken@6690
|
603 |
|
slouken@7191
|
604 |
dbh.dbcc_size = sizeof(dbh);
|
slouken@7191
|
605 |
dbh.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
|
slouken@7191
|
606 |
dbh.dbcc_classguid = GUID_DEVINTERFACE_USB_DEVICE;
|
slouken@6690
|
607 |
|
slouken@7191
|
608 |
hNotify = RegisterDeviceNotification( messageWindow, &dbh, DEVICE_NOTIFY_WINDOW_HANDLE );
|
slouken@7191
|
609 |
if ( !hNotify )
|
slouken@7191
|
610 |
{
|
slouken@7191
|
611 |
return SDL_SetError("Failed to create notify device for joystick autodetect.", GetLastError());
|
slouken@7191
|
612 |
}
|
slouken@6690
|
613 |
|
slouken@7191
|
614 |
SDL_LockMutex( s_mutexJoyStickEnum );
|
slouken@7191
|
615 |
while ( s_bJoystickThreadQuit == SDL_FALSE )
|
slouken@7191
|
616 |
{
|
slouken@7191
|
617 |
MSG messages;
|
slouken@7191
|
618 |
Uint8 userId;
|
slouken@7191
|
619 |
int nCurrentOpenedXInputDevices = 0;
|
slouken@7191
|
620 |
int nNewOpenedXInputDevices = 0;
|
slouken@7191
|
621 |
SDL_CondWaitTimeout( s_condJoystickThread, s_mutexJoyStickEnum, 300 );
|
slouken@6690
|
622 |
|
slouken@7191
|
623 |
while ( s_bJoystickThreadQuit == SDL_FALSE && PeekMessage(&messages, messageWindow, 0, 0, PM_NOREMOVE) )
|
slouken@7191
|
624 |
{
|
slouken@7191
|
625 |
if ( GetMessage(&messages, messageWindow, 0, 0) != 0 ) {
|
slouken@7191
|
626 |
TranslateMessage(&messages);
|
slouken@7191
|
627 |
DispatchMessage(&messages);
|
slouken@7191
|
628 |
}
|
slouken@7191
|
629 |
}
|
slouken@6690
|
630 |
|
slouken@7191
|
631 |
if ( s_bXInputEnabled && XINPUTGETCAPABILITIES )
|
slouken@7191
|
632 |
{
|
slouken@7191
|
633 |
/* scan for any change in XInput devices */
|
slouken@7191
|
634 |
for ( userId = 0; userId < 4; userId++ )
|
slouken@7191
|
635 |
{
|
slouken@7191
|
636 |
XINPUT_CAPABILITIES capabilities;
|
slouken@7191
|
637 |
DWORD result;
|
slouken@6710
|
638 |
|
slouken@7191
|
639 |
if ( bOpenedXInputDevices[userId] == SDL_TRUE )
|
slouken@7191
|
640 |
nCurrentOpenedXInputDevices++;
|
slouken@6710
|
641 |
|
slouken@7191
|
642 |
result = XINPUTGETCAPABILITIES( userId, XINPUT_FLAG_GAMEPAD, &capabilities );
|
slouken@7191
|
643 |
if ( result == ERROR_SUCCESS )
|
slouken@7191
|
644 |
{
|
slouken@7191
|
645 |
bOpenedXInputDevices[userId] = SDL_TRUE;
|
slouken@7191
|
646 |
nNewOpenedXInputDevices++;
|
slouken@7191
|
647 |
}
|
slouken@7191
|
648 |
else
|
slouken@7191
|
649 |
{
|
slouken@7191
|
650 |
bOpenedXInputDevices[userId] = SDL_FALSE;
|
slouken@7191
|
651 |
}
|
slouken@7191
|
652 |
}
|
slouken@7191
|
653 |
}
|
slouken@6710
|
654 |
|
slouken@7191
|
655 |
if ( s_pKnownJoystickGUIDs && ( s_bWindowsDeviceChanged || nNewOpenedXInputDevices != nCurrentOpenedXInputDevices ) )
|
slouken@7191
|
656 |
{
|
slouken@7191
|
657 |
SDL_Delay( 300 ); /* wait for direct input to find out about this device */
|
slouken@6690
|
658 |
|
slouken@7191
|
659 |
s_bDeviceRemoved = SDL_TRUE;
|
slouken@7191
|
660 |
s_bDeviceAdded = SDL_TRUE;
|
slouken@7191
|
661 |
s_bWindowsDeviceChanged = SDL_FALSE;
|
slouken@7191
|
662 |
}
|
slouken@7191
|
663 |
}
|
slouken@7191
|
664 |
SDL_UnlockMutex( s_mutexJoyStickEnum );
|
slouken@6690
|
665 |
|
slouken@7191
|
666 |
if ( hNotify )
|
slouken@7191
|
667 |
UnregisterDeviceNotification( hNotify );
|
slouken@6690
|
668 |
|
slouken@7191
|
669 |
if ( messageWindow )
|
slouken@7191
|
670 |
DestroyWindow( messageWindow );
|
slouken@6712
|
671 |
|
slouken@7191
|
672 |
UnregisterClass( wincl.lpszClassName, wincl.hInstance );
|
slouken@7191
|
673 |
messageWindow = 0;
|
slouken@7191
|
674 |
WIN_CoUninitialize();
|
slouken@7191
|
675 |
return 1;
|
slouken@6690
|
676 |
}
|
slouken@6690
|
677 |
|
slouken@6690
|
678 |
|
slouken@1895
|
679 |
/* Function to scan the system for joysticks.
|
slouken@1895
|
680 |
* This function should set SDL_numjoysticks to the number of available
|
slouken@1895
|
681 |
* joysticks. Joystick 0 should be the system default joystick.
|
slouken@1895
|
682 |
* It should return 0, or -1 on an unrecoverable fatal error.
|
slouken@1895
|
683 |
*/
|
slouken@1895
|
684 |
int
|
slouken@1895
|
685 |
SDL_SYS_JoystickInit(void)
|
slouken@1895
|
686 |
{
|
slouken@1895
|
687 |
HRESULT result;
|
slouken@2713
|
688 |
HINSTANCE instance;
|
slouken@7191
|
689 |
const char *env = SDL_GetHint(SDL_HINT_XINPUT_ENABLED);
|
slouken@7191
|
690 |
if (env && !SDL_atoi(env)) {
|
slouken@7191
|
691 |
s_bXInputEnabled = SDL_FALSE;
|
slouken@7191
|
692 |
}
|
slouken@1895
|
693 |
|
icculus@5591
|
694 |
result = WIN_CoInitialize();
|
slouken@2198
|
695 |
if (FAILED(result)) {
|
icculus@7037
|
696 |
return SetDIerror("CoInitialize", result);
|
slouken@1895
|
697 |
}
|
slouken@1895
|
698 |
|
icculus@5591
|
699 |
coinitialized = SDL_TRUE;
|
icculus@5591
|
700 |
|
slouken@6690
|
701 |
result = CoCreateInstance(&CLSID_DirectInput8, NULL, CLSCTX_INPROC_SERVER,
|
slouken@6690
|
702 |
&IID_IDirectInput8, (LPVOID)&dinput);
|
slouken@2198
|
703 |
|
slouken@2198
|
704 |
if (FAILED(result)) {
|
icculus@5591
|
705 |
SDL_SYS_JoystickQuit();
|
icculus@7037
|
706 |
return SetDIerror("CoCreateInstance", result);
|
slouken@2198
|
707 |
}
|
slouken@2198
|
708 |
|
slouken@2198
|
709 |
/* Because we used CoCreateInstance, we need to Initialize it, first. */
|
slouken@2713
|
710 |
instance = GetModuleHandle(NULL);
|
slouken@2713
|
711 |
if (instance == NULL) {
|
icculus@5591
|
712 |
SDL_SYS_JoystickQuit();
|
icculus@7037
|
713 |
return SDL_SetError("GetModuleHandle() failed with error code %d.", GetLastError());
|
slouken@2713
|
714 |
}
|
slouken@6690
|
715 |
result = IDirectInput8_Initialize(dinput, instance, DIRECTINPUT_VERSION);
|
slouken@2198
|
716 |
|
slouken@2198
|
717 |
if (FAILED(result)) {
|
icculus@5591
|
718 |
SDL_SYS_JoystickQuit();
|
icculus@7037
|
719 |
return SetDIerror("IDirectInput::Initialize", result);
|
slouken@2198
|
720 |
}
|
slouken@2198
|
721 |
|
icculus@6990
|
722 |
s_mutexJoyStickEnum = SDL_CreateMutex();
|
icculus@6990
|
723 |
s_condJoystickThread = SDL_CreateCond();
|
slouken@7191
|
724 |
s_bDeviceAdded = SDL_TRUE; /* force a scan of the system for joysticks this first time */
|
icculus@6990
|
725 |
SDL_SYS_JoystickDetect();
|
slouken@1895
|
726 |
|
icculus@6990
|
727 |
if ((s_bXInputEnabled) && (WIN_LoadXInputDLL() == -1)) {
|
icculus@6990
|
728 |
s_bXInputEnabled = SDL_FALSE; /* oh well. */
|
urkle@6965
|
729 |
}
|
slouken@1895
|
730 |
|
slouken@7191
|
731 |
if ( !s_threadJoystick )
|
slouken@7191
|
732 |
{
|
slouken@7191
|
733 |
s_bJoystickThreadQuit = SDL_FALSE;
|
slouken@7191
|
734 |
/* spin up the thread to detect hotplug of devices */
|
slouken@6690
|
735 |
#if defined(__WIN32__) && !defined(HAVE_LIBC)
|
slouken@6690
|
736 |
#undef SDL_CreateThread
|
slouken@7191
|
737 |
s_threadJoystick= SDL_CreateThread( SDL_JoystickThread, "SDL_joystick", NULL, NULL, NULL );
|
slouken@6690
|
738 |
#else
|
slouken@7191
|
739 |
s_threadJoystick = SDL_CreateThread( SDL_JoystickThread, "SDL_joystick", NULL );
|
slouken@6690
|
740 |
#endif
|
slouken@7191
|
741 |
}
|
slouken@7191
|
742 |
return SDL_SYS_NumJoysticks();
|
slouken@2198
|
743 |
}
|
slouken@2198
|
744 |
|
slouken@6707
|
745 |
/* return the number of joysticks that are connected right now */
|
slouken@6707
|
746 |
int SDL_SYS_NumJoysticks()
|
slouken@6707
|
747 |
{
|
slouken@7191
|
748 |
int nJoysticks = 0;
|
slouken@7191
|
749 |
JoyStick_DeviceData *device = SYS_Joystick;
|
slouken@7191
|
750 |
while ( device )
|
slouken@7191
|
751 |
{
|
slouken@7191
|
752 |
nJoysticks++;
|
slouken@7191
|
753 |
device = device->pNext;
|
slouken@7191
|
754 |
}
|
slouken@6707
|
755 |
|
slouken@7191
|
756 |
return nJoysticks;
|
slouken@6707
|
757 |
}
|
slouken@6707
|
758 |
|
slouken@6707
|
759 |
static int s_iNewGUID = 0;
|
slouken@6707
|
760 |
|
slouken@6707
|
761 |
/* helper function for direct input, gets called for each connected joystick */
|
slouken@6707
|
762 |
static BOOL CALLBACK
|
slouken@7191
|
763 |
EnumJoysticksCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext)
|
slouken@6707
|
764 |
{
|
slouken@7191
|
765 |
JoyStick_DeviceData *pNewJoystick;
|
slouken@7191
|
766 |
JoyStick_DeviceData *pPrevJoystick = NULL;
|
slouken@7191
|
767 |
SDL_bool bXInputDevice;
|
slouken@7191
|
768 |
pNewJoystick = *(JoyStick_DeviceData **)pContext;
|
slouken@7191
|
769 |
while ( pNewJoystick )
|
slouken@7191
|
770 |
{
|
slouken@7191
|
771 |
if ( !SDL_memcmp( &pNewJoystick->dxdevice.guidInstance, &pdidInstance->guidInstance, sizeof(pNewJoystick->dxdevice.guidInstance) ) )
|
slouken@7191
|
772 |
{
|
slouken@7191
|
773 |
/* if we are replacing the front of the list then update it */
|
slouken@7191
|
774 |
if ( pNewJoystick == *(JoyStick_DeviceData **)pContext )
|
slouken@7191
|
775 |
{
|
slouken@7191
|
776 |
*(JoyStick_DeviceData **)pContext = pNewJoystick->pNext;
|
slouken@7191
|
777 |
}
|
slouken@7191
|
778 |
else if ( pPrevJoystick )
|
slouken@7191
|
779 |
{
|
slouken@7191
|
780 |
pPrevJoystick->pNext = pNewJoystick->pNext;
|
slouken@7191
|
781 |
}
|
slouken@6712
|
782 |
|
slouken@7191
|
783 |
pNewJoystick->pNext = SYS_Joystick;
|
slouken@7191
|
784 |
SYS_Joystick = pNewJoystick;
|
slouken@6707
|
785 |
|
slouken@7191
|
786 |
s_pKnownJoystickGUIDs[ s_iNewGUID ] = pdidInstance->guidInstance;
|
slouken@7191
|
787 |
s_iNewGUID++;
|
slouken@7191
|
788 |
if ( s_iNewGUID < MAX_JOYSTICKS )
|
slouken@7191
|
789 |
return DIENUM_CONTINUE; /* already have this joystick loaded, just keep going */
|
slouken@7191
|
790 |
else
|
slouken@7191
|
791 |
return DIENUM_STOP;
|
slouken@7191
|
792 |
}
|
slouken@6707
|
793 |
|
slouken@7191
|
794 |
pPrevJoystick = pNewJoystick;
|
slouken@7191
|
795 |
pNewJoystick = pNewJoystick->pNext;
|
slouken@7191
|
796 |
}
|
slouken@6707
|
797 |
|
slouken@7191
|
798 |
s_bDeviceAdded = SDL_TRUE;
|
slouken@6707
|
799 |
|
slouken@7191
|
800 |
bXInputDevice = IsXInputDevice( &pdidInstance->guidProduct );
|
slouken@6707
|
801 |
|
slouken@7191
|
802 |
pNewJoystick = (JoyStick_DeviceData *)SDL_malloc( sizeof(JoyStick_DeviceData) );
|
slouken@6707
|
803 |
|
slouken@7191
|
804 |
if ( bXInputDevice )
|
slouken@7191
|
805 |
{
|
slouken@7191
|
806 |
pNewJoystick->bXInputDevice = SDL_TRUE;
|
slouken@7191
|
807 |
pNewJoystick->XInputUserId = INVALID_XINPUT_USERID;
|
slouken@7191
|
808 |
}
|
slouken@7191
|
809 |
else
|
slouken@7191
|
810 |
{
|
slouken@7191
|
811 |
pNewJoystick->bXInputDevice = SDL_FALSE;
|
slouken@7191
|
812 |
}
|
slouken@6712
|
813 |
|
slouken@7191
|
814 |
SDL_memcpy(&(pNewJoystick->dxdevice), pdidInstance,
|
slouken@7191
|
815 |
sizeof(DIDEVICEINSTANCE));
|
slouken@6707
|
816 |
|
slouken@7191
|
817 |
pNewJoystick->joystickname = WIN_StringToUTF8(pdidInstance->tszProductName);
|
slouken@7191
|
818 |
pNewJoystick->send_add_event = 1;
|
slouken@7191
|
819 |
pNewJoystick->nInstanceID = ++s_nInstanceID;
|
slouken@7191
|
820 |
SDL_memcpy( &pNewJoystick->guid, &pdidInstance->guidProduct, sizeof(pNewJoystick->guid) );
|
slouken@7191
|
821 |
pNewJoystick->pNext = NULL;
|
slouken@6707
|
822 |
|
slouken@7191
|
823 |
if ( SYS_Joystick )
|
slouken@7191
|
824 |
{
|
slouken@7191
|
825 |
pNewJoystick->pNext = SYS_Joystick;
|
slouken@7191
|
826 |
}
|
slouken@7191
|
827 |
SYS_Joystick = pNewJoystick;
|
slouken@6707
|
828 |
|
slouken@7191
|
829 |
s_pKnownJoystickGUIDs[ s_iNewGUID ] = pdidInstance->guidInstance;
|
slouken@7191
|
830 |
s_iNewGUID++;
|
slouken@7191
|
831 |
|
slouken@7191
|
832 |
if ( s_iNewGUID < MAX_JOYSTICKS )
|
slouken@7191
|
833 |
return DIENUM_CONTINUE; /* already have this joystick loaded, just keep going */
|
slouken@7191
|
834 |
else
|
slouken@7191
|
835 |
return DIENUM_STOP;
|
slouken@6707
|
836 |
}
|
slouken@6707
|
837 |
|
slouken@6707
|
838 |
/* detect any new joysticks being inserted into the system */
|
slouken@6707
|
839 |
void SDL_SYS_JoystickDetect()
|
slouken@6707
|
840 |
{
|
slouken@7191
|
841 |
JoyStick_DeviceData *pCurList = NULL;
|
slouken@7191
|
842 |
/* only enum the devices if the joystick thread told us something changed */
|
slouken@7191
|
843 |
if ( s_bDeviceAdded || s_bDeviceRemoved )
|
slouken@7191
|
844 |
{
|
slouken@7191
|
845 |
s_bDeviceAdded = SDL_FALSE;
|
slouken@7191
|
846 |
s_bDeviceRemoved = SDL_FALSE;
|
slouken@6707
|
847 |
|
slouken@7191
|
848 |
pCurList = SYS_Joystick;
|
slouken@7191
|
849 |
SYS_Joystick = NULL;
|
slouken@7191
|
850 |
s_iNewGUID = 0;
|
slouken@7191
|
851 |
SDL_LockMutex( s_mutexJoyStickEnum );
|
slouken@6707
|
852 |
|
slouken@7191
|
853 |
if ( !s_pKnownJoystickGUIDs )
|
slouken@7191
|
854 |
s_pKnownJoystickGUIDs = SDL_malloc( sizeof(GUID)*MAX_JOYSTICKS );
|
slouken@6707
|
855 |
|
slouken@7191
|
856 |
SDL_memset( s_pKnownJoystickGUIDs, 0x0, sizeof(GUID)*MAX_JOYSTICKS );
|
slouken@6707
|
857 |
|
slouken@7191
|
858 |
/* Look for joysticks, wheels, head trackers, gamepads, etc.. */
|
slouken@7223
|
859 |
IDirectInput8_EnumDevices(dinput,
|
slouken@7191
|
860 |
DI8DEVCLASS_GAMECTRL,
|
slouken@7191
|
861 |
EnumJoysticksCallback,
|
slouken@7191
|
862 |
&pCurList, DIEDFL_ATTACHEDONLY);
|
slouken@6707
|
863 |
|
slouken@7191
|
864 |
SDL_UnlockMutex( s_mutexJoyStickEnum );
|
slouken@7191
|
865 |
}
|
slouken@7191
|
866 |
|
slouken@7191
|
867 |
if ( pCurList )
|
slouken@7191
|
868 |
{
|
slouken@7191
|
869 |
while ( pCurList )
|
slouken@7191
|
870 |
{
|
slouken@7191
|
871 |
JoyStick_DeviceData *pListNext = NULL;
|
slouken@6707
|
872 |
#if !SDL_EVENTS_DISABLED
|
slouken@7191
|
873 |
SDL_Event event;
|
slouken@7191
|
874 |
event.type = SDL_JOYDEVICEREMOVED;
|
slouken@6707
|
875 |
|
slouken@7191
|
876 |
if (SDL_GetEventState(event.type) == SDL_ENABLE) {
|
slouken@7191
|
877 |
event.jdevice.which = pCurList->nInstanceID;
|
slouken@7191
|
878 |
if ((SDL_EventOK == NULL)
|
slouken@7191
|
879 |
|| (*SDL_EventOK) (SDL_EventOKParam, &event)) {
|
slouken@7191
|
880 |
SDL_PushEvent(&event);
|
slouken@7191
|
881 |
}
|
slouken@7191
|
882 |
}
|
slouken@7191
|
883 |
#endif /* !SDL_EVENTS_DISABLED */
|
slouken@6707
|
884 |
|
slouken@7191
|
885 |
pListNext = pCurList->pNext;
|
slouken@7191
|
886 |
SDL_free(pCurList->joystickname);
|
slouken@7191
|
887 |
SDL_free( pCurList );
|
slouken@7191
|
888 |
pCurList = pListNext;
|
slouken@7191
|
889 |
}
|
slouken@6707
|
890 |
|
slouken@7191
|
891 |
}
|
slouken@6707
|
892 |
|
slouken@7191
|
893 |
if ( s_bDeviceAdded )
|
slouken@7191
|
894 |
{
|
slouken@7191
|
895 |
JoyStick_DeviceData *pNewJoystick;
|
slouken@7191
|
896 |
int device_index = 0;
|
slouken@7191
|
897 |
s_bDeviceAdded = SDL_FALSE;
|
slouken@7191
|
898 |
pNewJoystick = SYS_Joystick;
|
slouken@7191
|
899 |
while ( pNewJoystick )
|
slouken@7191
|
900 |
{
|
slouken@7191
|
901 |
if ( pNewJoystick->send_add_event )
|
slouken@7191
|
902 |
{
|
slouken@6707
|
903 |
#if !SDL_EVENTS_DISABLED
|
slouken@7191
|
904 |
SDL_Event event;
|
slouken@7191
|
905 |
event.type = SDL_JOYDEVICEADDED;
|
slouken@6707
|
906 |
|
slouken@7191
|
907 |
if (SDL_GetEventState(event.type) == SDL_ENABLE) {
|
slouken@7191
|
908 |
event.jdevice.which = device_index;
|
slouken@7191
|
909 |
if ((SDL_EventOK == NULL)
|
slouken@7191
|
910 |
|| (*SDL_EventOK) (SDL_EventOKParam, &event)) {
|
slouken@7191
|
911 |
SDL_PushEvent(&event);
|
slouken@7191
|
912 |
}
|
slouken@7191
|
913 |
}
|
slouken@6707
|
914 |
#endif /* !SDL_EVENTS_DISABLED */
|
slouken@7191
|
915 |
pNewJoystick->send_add_event = 0;
|
slouken@7191
|
916 |
}
|
slouken@7191
|
917 |
device_index++;
|
slouken@7191
|
918 |
pNewJoystick = pNewJoystick->pNext;
|
slouken@7191
|
919 |
}
|
slouken@7191
|
920 |
}
|
slouken@6707
|
921 |
}
|
slouken@6707
|
922 |
|
slouken@6707
|
923 |
/* we need to poll if we have pending hotplug device changes or connected devices */
|
slouken@6707
|
924 |
SDL_bool SDL_SYS_JoystickNeedsPolling()
|
slouken@6707
|
925 |
{
|
slouken@7191
|
926 |
/* we have a new device or one was pulled, we need to think this frame please */
|
slouken@7191
|
927 |
if ( s_bDeviceAdded || s_bDeviceRemoved )
|
slouken@7191
|
928 |
return SDL_TRUE;
|
slouken@6707
|
929 |
|
slouken@7191
|
930 |
return SDL_FALSE;
|
slouken@6707
|
931 |
}
|
slouken@6707
|
932 |
|
slouken@1895
|
933 |
/* Function to get the device-dependent name of a joystick */
|
slouken@1895
|
934 |
const char *
|
slouken@6707
|
935 |
SDL_SYS_JoystickNameForDeviceIndex(int device_index)
|
slouken@1895
|
936 |
{
|
slouken@7191
|
937 |
JoyStick_DeviceData *device = SYS_Joystick;
|
slouken@6690
|
938 |
|
slouken@7191
|
939 |
for (; device_index > 0; device_index--)
|
slouken@7191
|
940 |
device = device->pNext;
|
slouken@6690
|
941 |
|
slouken@7191
|
942 |
return device->joystickname;
|
slouken@1895
|
943 |
}
|
slouken@1895
|
944 |
|
slouken@6707
|
945 |
/* Function to perform the mapping between current device instance and this joysticks instance id */
|
slouken@6707
|
946 |
SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index)
|
slouken@6707
|
947 |
{
|
slouken@7191
|
948 |
JoyStick_DeviceData *device = SYS_Joystick;
|
slouken@7191
|
949 |
int index;
|
slouken@6707
|
950 |
|
slouken@7191
|
951 |
for (index = device_index; index > 0; index--)
|
slouken@7191
|
952 |
device = device->pNext;
|
slouken@6707
|
953 |
|
slouken@7191
|
954 |
return device->nInstanceID;
|
slouken@6707
|
955 |
}
|
slouken@6707
|
956 |
|
slouken@1895
|
957 |
/* Function to open a joystick for use.
|
slouken@1895
|
958 |
The joystick to open is specified by the index field of the joystick.
|
slouken@1895
|
959 |
This should fill the nbuttons and naxes fields of the joystick structure.
|
slouken@1895
|
960 |
It returns 0, or -1 if there is an error.
|
slouken@1895
|
961 |
*/
|
slouken@1895
|
962 |
int
|
slouken@6690
|
963 |
SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index)
|
slouken@1895
|
964 |
{
|
slouken@1895
|
965 |
HRESULT result;
|
icculus@6716
|
966 |
LPDIRECTINPUTDEVICE8 device;
|
slouken@2198
|
967 |
DIPROPDWORD dipdw;
|
slouken@7191
|
968 |
JoyStick_DeviceData *joystickdevice = SYS_Joystick;
|
slouken@6690
|
969 |
|
slouken@7191
|
970 |
for (; device_index > 0; device_index--)
|
slouken@7191
|
971 |
joystickdevice = joystickdevice->pNext;
|
slouken@2198
|
972 |
|
slouken@2713
|
973 |
SDL_memset(&dipdw, 0, sizeof(DIPROPDWORD));
|
slouken@2198
|
974 |
dipdw.diph.dwSize = sizeof(DIPROPDWORD);
|
slouken@2198
|
975 |
dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
|
slouken@2198
|
976 |
|
slouken@1895
|
977 |
/* allocate memory for system specific hardware data */
|
slouken@7191
|
978 |
joystick->instance_id = joystickdevice->nInstanceID;
|
urkle@6965
|
979 |
joystick->closed = 0;
|
slouken@1895
|
980 |
joystick->hwdata =
|
slouken@2713
|
981 |
(struct joystick_hwdata *) SDL_malloc(sizeof(struct joystick_hwdata));
|
slouken@1895
|
982 |
if (joystick->hwdata == NULL) {
|
icculus@7037
|
983 |
return SDL_OutOfMemory();
|
slouken@1895
|
984 |
}
|
slouken@2713
|
985 |
SDL_memset(joystick->hwdata, 0, sizeof(struct joystick_hwdata));
|
slouken@1895
|
986 |
joystick->hwdata->buffered = 1;
|
slouken@7191
|
987 |
joystick->hwdata->removed = 0;
|
slouken@2198
|
988 |
joystick->hwdata->Capabilities.dwSize = sizeof(DIDEVCAPS);
|
slouken@7191
|
989 |
joystick->hwdata->guid = joystickdevice->guid;
|
slouken@1895
|
990 |
|
slouken@7191
|
991 |
if ( joystickdevice->bXInputDevice )
|
slouken@7191
|
992 |
{
|
slouken@7191
|
993 |
XINPUT_CAPABILITIES capabilities;
|
slouken@7191
|
994 |
Uint8 userId = 0;
|
slouken@7191
|
995 |
DWORD result;
|
slouken@7191
|
996 |
JoyStick_DeviceData *joysticklist = SYS_Joystick;
|
slouken@7191
|
997 |
/* scan the opened joysticks and pick the next free xinput userid for this one */
|
slouken@7191
|
998 |
for( ; joysticklist; joysticklist = joysticklist->pNext)
|
slouken@7191
|
999 |
{
|
slouken@7191
|
1000 |
if ( joysticklist->bXInputDevice && joysticklist->XInputUserId == userId )
|
slouken@7191
|
1001 |
userId++;
|
slouken@7191
|
1002 |
}
|
slouken@1895
|
1003 |
|
slouken@7191
|
1004 |
if ( s_bXInputEnabled && XINPUTGETCAPABILITIES )
|
slouken@7191
|
1005 |
{
|
slouken@7191
|
1006 |
result = XINPUTGETCAPABILITIES( userId, XINPUT_FLAG_GAMEPAD, &capabilities );
|
slouken@7191
|
1007 |
if ( result == ERROR_SUCCESS )
|
slouken@7191
|
1008 |
{
|
icculus@6990
|
1009 |
const SDL_bool bIs14OrLater = (SDL_XInputVersion >= ((1<<16)|4));
|
slouken@7191
|
1010 |
SDL_bool bIsSupported = SDL_FALSE;
|
slouken@7191
|
1011 |
/* Current version of XInput mistakenly returns 0 as the Type. Ignore it and ensure the subtype is a gamepad. */
|
slouken@7191
|
1012 |
bIsSupported = ( capabilities.SubType == XINPUT_DEVSUBTYPE_GAMEPAD );
|
slouken@2198
|
1013 |
|
slouken@7191
|
1014 |
if ( !bIsSupported )
|
slouken@7191
|
1015 |
{
|
slouken@7191
|
1016 |
joystickdevice->bXInputDevice = SDL_FALSE;
|
slouken@7191
|
1017 |
}
|
slouken@7191
|
1018 |
else
|
slouken@7191
|
1019 |
{
|
slouken@7191
|
1020 |
/* valid */
|
slouken@7191
|
1021 |
joystick->hwdata->bXInputDevice = SDL_TRUE;
|
icculus@6990
|
1022 |
if ((!bIs14OrLater) || (capabilities.Flags & XINPUT_CAPS_FFB_SUPPORTED)) {
|
slouken@7191
|
1023 |
joystick->hwdata->bXInputHaptic = SDL_TRUE;
|
icculus@6990
|
1024 |
}
|
slouken@7191
|
1025 |
SDL_memset( joystick->hwdata->XInputState, 0x0, sizeof(joystick->hwdata->XInputState) );
|
slouken@7191
|
1026 |
joystickdevice->XInputUserId = userId;
|
slouken@7191
|
1027 |
joystick->hwdata->userid = userId;
|
slouken@7191
|
1028 |
joystick->hwdata->currentXInputSlot = 0;
|
slouken@7191
|
1029 |
/* The XInput API has a hard coded button/axis mapping, so we just match it */
|
slouken@7191
|
1030 |
joystick->naxes = 6;
|
slouken@7191
|
1031 |
joystick->nbuttons = 15;
|
slouken@7191
|
1032 |
joystick->nballs = 0;
|
slouken@7191
|
1033 |
joystick->nhats = 0;
|
slouken@7191
|
1034 |
}
|
slouken@7191
|
1035 |
}
|
slouken@7191
|
1036 |
else
|
slouken@7191
|
1037 |
{
|
slouken@7191
|
1038 |
joystickdevice->bXInputDevice = SDL_FALSE;
|
slouken@7191
|
1039 |
}
|
slouken@7191
|
1040 |
}
|
slouken@7191
|
1041 |
else
|
slouken@7191
|
1042 |
{
|
slouken@7191
|
1043 |
joystickdevice->bXInputDevice = SDL_FALSE;
|
slouken@7191
|
1044 |
}
|
slouken@7191
|
1045 |
}
|
slouken@1895
|
1046 |
|
slouken@7191
|
1047 |
if ( joystickdevice->bXInputDevice == SDL_FALSE )
|
slouken@7191
|
1048 |
{
|
slouken@7191
|
1049 |
joystick->hwdata->bXInputDevice = SDL_FALSE;
|
slouken@1895
|
1050 |
|
slouken@7191
|
1051 |
result =
|
slouken@7191
|
1052 |
IDirectInput8_CreateDevice(dinput,
|
slouken@7191
|
1053 |
&(joystickdevice->dxdevice.guidInstance), &device, NULL);
|
slouken@7191
|
1054 |
if (FAILED(result)) {
|
slouken@7191
|
1055 |
return SetDIerror("IDirectInput::CreateDevice", result);
|
slouken@7191
|
1056 |
}
|
slouken@1895
|
1057 |
|
slouken@7191
|
1058 |
/* Now get the IDirectInputDevice8 interface, instead. */
|
slouken@7191
|
1059 |
result = IDirectInputDevice8_QueryInterface(device,
|
slouken@7191
|
1060 |
&IID_IDirectInputDevice8,
|
slouken@7191
|
1061 |
(LPVOID *) & joystick->
|
slouken@7191
|
1062 |
hwdata->InputDevice);
|
slouken@7191
|
1063 |
/* We are done with this object. Use the stored one from now on. */
|
slouken@7191
|
1064 |
IDirectInputDevice8_Release(device);
|
slouken@1895
|
1065 |
|
slouken@7191
|
1066 |
if (FAILED(result)) {
|
slouken@7191
|
1067 |
return SetDIerror("IDirectInputDevice8::QueryInterface", result);
|
slouken@7191
|
1068 |
}
|
slouken@2198
|
1069 |
|
slouken@7191
|
1070 |
/* Acquire shared access. Exclusive access is required for forces,
|
slouken@7191
|
1071 |
* though. */
|
slouken@7191
|
1072 |
result =
|
slouken@7191
|
1073 |
IDirectInputDevice8_SetCooperativeLevel(joystick->hwdata->
|
slouken@7191
|
1074 |
InputDevice, SDL_HelperWindow,
|
slouken@7191
|
1075 |
DISCL_NONEXCLUSIVE |
|
slouken@7191
|
1076 |
DISCL_BACKGROUND);
|
slouken@7191
|
1077 |
if (FAILED(result)) {
|
slouken@7191
|
1078 |
return SetDIerror("IDirectInputDevice8::SetCooperativeLevel", result);
|
slouken@7191
|
1079 |
}
|
slouken@2198
|
1080 |
|
slouken@7191
|
1081 |
/* Use the extended data structure: DIJOYSTATE2. */
|
slouken@7191
|
1082 |
result =
|
slouken@7191
|
1083 |
IDirectInputDevice8_SetDataFormat(joystick->hwdata->InputDevice,
|
slouken@7191
|
1084 |
&c_dfDIJoystick2);
|
slouken@7191
|
1085 |
if (FAILED(result)) {
|
slouken@7191
|
1086 |
return SetDIerror("IDirectInputDevice8::SetDataFormat", result);
|
slouken@7191
|
1087 |
}
|
slouken@2198
|
1088 |
|
slouken@7191
|
1089 |
/* Get device capabilities */
|
slouken@7191
|
1090 |
result =
|
slouken@7191
|
1091 |
IDirectInputDevice8_GetCapabilities(joystick->hwdata->InputDevice,
|
slouken@7191
|
1092 |
&joystick->hwdata->Capabilities);
|
slouken@2198
|
1093 |
|
slouken@7191
|
1094 |
if (FAILED(result)) {
|
slouken@7191
|
1095 |
return SetDIerror("IDirectInputDevice8::GetCapabilities", result);
|
slouken@7191
|
1096 |
}
|
slouken@2198
|
1097 |
|
slouken@7191
|
1098 |
/* Force capable? */
|
slouken@7191
|
1099 |
if (joystick->hwdata->Capabilities.dwFlags & DIDC_FORCEFEEDBACK) {
|
slouken@2198
|
1100 |
|
slouken@7191
|
1101 |
result = IDirectInputDevice8_Acquire(joystick->hwdata->InputDevice);
|
slouken@2198
|
1102 |
|
slouken@7191
|
1103 |
if (FAILED(result)) {
|
slouken@7191
|
1104 |
return SetDIerror("IDirectInputDevice8::Acquire", result);
|
slouken@7191
|
1105 |
}
|
slouken@2198
|
1106 |
|
slouken@7191
|
1107 |
/* reset all accuators. */
|
slouken@7191
|
1108 |
result =
|
slouken@7191
|
1109 |
IDirectInputDevice8_SendForceFeedbackCommand(joystick->hwdata->
|
slouken@7191
|
1110 |
InputDevice,
|
slouken@7191
|
1111 |
DISFFC_RESET);
|
slouken@2198
|
1112 |
|
slouken@7191
|
1113 |
/* Not necessarily supported, ignore if not supported.
|
slouken@7191
|
1114 |
if (FAILED(result)) {
|
slouken@7191
|
1115 |
return SetDIerror("IDirectInputDevice8::SendForceFeedbackCommand", result);
|
slouken@7191
|
1116 |
}
|
slouken@7191
|
1117 |
*/
|
slouken@1895
|
1118 |
|
slouken@7191
|
1119 |
result = IDirectInputDevice8_Unacquire(joystick->hwdata->InputDevice);
|
slouken@1895
|
1120 |
|
slouken@7191
|
1121 |
if (FAILED(result)) {
|
slouken@7191
|
1122 |
return SetDIerror("IDirectInputDevice8::Unacquire", result);
|
slouken@7191
|
1123 |
}
|
slouken@2198
|
1124 |
|
slouken@7191
|
1125 |
/* Turn on auto-centering for a ForceFeedback device (until told
|
slouken@7191
|
1126 |
* otherwise). */
|
slouken@7191
|
1127 |
dipdw.diph.dwObj = 0;
|
slouken@7191
|
1128 |
dipdw.diph.dwHow = DIPH_DEVICE;
|
slouken@7191
|
1129 |
dipdw.dwData = DIPROPAUTOCENTER_ON;
|
slouken@6220
|
1130 |
|
slouken@7191
|
1131 |
result =
|
slouken@7191
|
1132 |
IDirectInputDevice8_SetProperty(joystick->hwdata->InputDevice,
|
slouken@7191
|
1133 |
DIPROP_AUTOCENTER, &dipdw.diph);
|
slouken@2198
|
1134 |
|
slouken@7191
|
1135 |
/* Not necessarily supported, ignore if not supported.
|
slouken@7191
|
1136 |
if (FAILED(result)) {
|
slouken@7191
|
1137 |
return SetDIerror("IDirectInputDevice8::SetProperty", result);
|
slouken@7191
|
1138 |
}
|
slouken@7191
|
1139 |
*/
|
slouken@7191
|
1140 |
}
|
slouken@2198
|
1141 |
|
slouken@7191
|
1142 |
/* What buttons and axes does it have? */
|
slouken@7191
|
1143 |
IDirectInputDevice8_EnumObjects(joystick->hwdata->InputDevice,
|
slouken@7191
|
1144 |
EnumDevObjectsCallback, joystick,
|
slouken@7191
|
1145 |
DIDFT_BUTTON | DIDFT_AXIS | DIDFT_POV);
|
slouken@2198
|
1146 |
|
slouken@7191
|
1147 |
/* Reorder the input objects. Some devices do not report the X axis as
|
slouken@7191
|
1148 |
* the first axis, for example. */
|
slouken@7191
|
1149 |
SortDevObjects(joystick);
|
slouken@6690
|
1150 |
|
slouken@7191
|
1151 |
dipdw.diph.dwObj = 0;
|
slouken@7191
|
1152 |
dipdw.diph.dwHow = DIPH_DEVICE;
|
slouken@7191
|
1153 |
dipdw.dwData = INPUT_QSIZE;
|
slouken@6690
|
1154 |
|
slouken@7191
|
1155 |
/* Set the buffer size */
|
slouken@7191
|
1156 |
result =
|
slouken@7191
|
1157 |
IDirectInputDevice8_SetProperty(joystick->hwdata->InputDevice,
|
slouken@7191
|
1158 |
DIPROP_BUFFERSIZE, &dipdw.diph);
|
slouken@6690
|
1159 |
|
slouken@7191
|
1160 |
if (result == DI_POLLEDDEVICE) {
|
slouken@7191
|
1161 |
/* This device doesn't support buffering, so we're forced
|
slouken@7191
|
1162 |
* to use less reliable polling. */
|
slouken@7191
|
1163 |
joystick->hwdata->buffered = 0;
|
slouken@7191
|
1164 |
} else if (FAILED(result)) {
|
slouken@7191
|
1165 |
return SetDIerror("IDirectInputDevice8::SetProperty", result);
|
slouken@7191
|
1166 |
}
|
slouken@7191
|
1167 |
}
|
slouken@1895
|
1168 |
return (0);
|
slouken@1895
|
1169 |
}
|
slouken@1895
|
1170 |
|
slouken@6707
|
1171 |
/* return true if this joystick is plugged in right now */
|
slouken@6707
|
1172 |
SDL_bool SDL_SYS_JoystickAttached( SDL_Joystick * joystick )
|
slouken@6707
|
1173 |
{
|
slouken@7191
|
1174 |
return joystick->closed == 0 && joystick->hwdata->removed == 0;
|
slouken@6707
|
1175 |
}
|
slouken@6707
|
1176 |
|
slouken@6707
|
1177 |
|
slouken@6220
|
1178 |
/* Sort using the data offset into the DInput struct.
|
slouken@6220
|
1179 |
* This gives a reasonable ordering for the inputs. */
|
slouken@6220
|
1180 |
static int
|
slouken@6220
|
1181 |
SortDevFunc(const void *a, const void *b)
|
slouken@6220
|
1182 |
{
|
slouken@7191
|
1183 |
const input_t *inputA = (const input_t*)a;
|
slouken@7191
|
1184 |
const input_t *inputB = (const input_t*)b;
|
slouken@6220
|
1185 |
|
slouken@7191
|
1186 |
if (inputA->ofs < inputB->ofs)
|
slouken@7191
|
1187 |
return -1;
|
slouken@7191
|
1188 |
if (inputA->ofs > inputB->ofs)
|
slouken@7191
|
1189 |
return 1;
|
slouken@7191
|
1190 |
return 0;
|
slouken@6220
|
1191 |
}
|
slouken@6220
|
1192 |
|
slouken@6220
|
1193 |
/* Sort the input objects and recalculate the indices for each input. */
|
slouken@6220
|
1194 |
static void
|
slouken@6220
|
1195 |
SortDevObjects(SDL_Joystick *joystick)
|
slouken@6220
|
1196 |
{
|
slouken@7191
|
1197 |
input_t *inputs = joystick->hwdata->Inputs;
|
slouken@7191
|
1198 |
int nButtons = 0;
|
slouken@7191
|
1199 |
int nHats = 0;
|
slouken@7191
|
1200 |
int nAxis = 0;
|
slouken@7191
|
1201 |
int n;
|
slouken@6220
|
1202 |
|
slouken@7191
|
1203 |
SDL_qsort(inputs, joystick->hwdata->NumInputs, sizeof(input_t), SortDevFunc);
|
slouken@6220
|
1204 |
|
slouken@7191
|
1205 |
for (n = 0; n < joystick->hwdata->NumInputs; n++)
|
slouken@7191
|
1206 |
{
|
slouken@7191
|
1207 |
switch (inputs[n].type)
|
slouken@7191
|
1208 |
{
|
slouken@7191
|
1209 |
case BUTTON:
|
slouken@7191
|
1210 |
inputs[n].num = nButtons;
|
slouken@7191
|
1211 |
nButtons++;
|
slouken@7191
|
1212 |
break;
|
slouken@6220
|
1213 |
|
slouken@7191
|
1214 |
case HAT:
|
slouken@7191
|
1215 |
inputs[n].num = nHats;
|
slouken@7191
|
1216 |
nHats++;
|
slouken@7191
|
1217 |
break;
|
slouken@6220
|
1218 |
|
slouken@7191
|
1219 |
case AXIS:
|
slouken@7191
|
1220 |
inputs[n].num = nAxis;
|
slouken@7191
|
1221 |
nAxis++;
|
slouken@7191
|
1222 |
break;
|
slouken@7191
|
1223 |
}
|
slouken@7191
|
1224 |
}
|
slouken@6220
|
1225 |
}
|
slouken@6220
|
1226 |
|
slouken@2198
|
1227 |
static BOOL CALLBACK
|
slouken@2198
|
1228 |
EnumDevObjectsCallback(LPCDIDEVICEOBJECTINSTANCE dev, LPVOID pvRef)
|
slouken@2198
|
1229 |
{
|
slouken@2198
|
1230 |
SDL_Joystick *joystick = (SDL_Joystick *) pvRef;
|
slouken@2198
|
1231 |
HRESULT result;
|
slouken@2198
|
1232 |
input_t *in = &joystick->hwdata->Inputs[joystick->hwdata->NumInputs];
|
slouken@2198
|
1233 |
|
slouken@2198
|
1234 |
if (dev->dwType & DIDFT_BUTTON) {
|
slouken@2198
|
1235 |
in->type = BUTTON;
|
slouken@2198
|
1236 |
in->num = joystick->nbuttons;
|
slouken@7191
|
1237 |
in->ofs = DIJOFS_BUTTON( in->num );
|
slouken@2198
|
1238 |
joystick->nbuttons++;
|
slouken@2198
|
1239 |
} else if (dev->dwType & DIDFT_POV) {
|
slouken@2198
|
1240 |
in->type = HAT;
|
slouken@2198
|
1241 |
in->num = joystick->nhats;
|
slouken@7191
|
1242 |
in->ofs = DIJOFS_POV( in->num );
|
slouken@2198
|
1243 |
joystick->nhats++;
|
slouken@2198
|
1244 |
} else if (dev->dwType & DIDFT_AXIS) {
|
slouken@2198
|
1245 |
DIPROPRANGE diprg;
|
slouken@2198
|
1246 |
DIPROPDWORD dilong;
|
slouken@2198
|
1247 |
|
slouken@2198
|
1248 |
in->type = AXIS;
|
slouken@2198
|
1249 |
in->num = joystick->naxes;
|
slouken@7191
|
1250 |
/* work our the axis this guy maps too, thanks for the code icculus! */
|
slouken@7191
|
1251 |
if ( !SDL_memcmp( &dev->guidType, &GUID_XAxis, sizeof(dev->guidType) ) )
|
slouken@7191
|
1252 |
in->ofs = DIJOFS_X;
|
slouken@7191
|
1253 |
else if ( !SDL_memcmp( &dev->guidType, &GUID_YAxis, sizeof(dev->guidType) ) )
|
slouken@7191
|
1254 |
in->ofs = DIJOFS_Y;
|
slouken@7191
|
1255 |
else if ( !SDL_memcmp( &dev->guidType, &GUID_ZAxis, sizeof(dev->guidType) ) )
|
slouken@7191
|
1256 |
in->ofs = DIJOFS_Z;
|
slouken@7191
|
1257 |
else if ( !SDL_memcmp( &dev->guidType, &GUID_RxAxis, sizeof(dev->guidType) ) )
|
slouken@7191
|
1258 |
in->ofs = DIJOFS_RX;
|
slouken@7191
|
1259 |
else if ( !SDL_memcmp( &dev->guidType, &GUID_RyAxis, sizeof(dev->guidType) ) )
|
slouken@7191
|
1260 |
in->ofs = DIJOFS_RY;
|
slouken@7191
|
1261 |
else if ( !SDL_memcmp( &dev->guidType, &GUID_RzAxis, sizeof(dev->guidType) ) )
|
slouken@7191
|
1262 |
in->ofs = DIJOFS_RZ;
|
slouken@7191
|
1263 |
else if ( !SDL_memcmp( &dev->guidType, &GUID_Slider, sizeof(dev->guidType) ) )
|
slouken@7191
|
1264 |
{
|
slouken@7191
|
1265 |
in->ofs = DIJOFS_SLIDER( joystick->hwdata->NumSliders );
|
slouken@7191
|
1266 |
++joystick->hwdata->NumSliders;
|
slouken@7191
|
1267 |
}
|
slouken@7191
|
1268 |
else
|
slouken@7191
|
1269 |
{
|
slouken@7191
|
1270 |
return DIENUM_CONTINUE; /* not an axis we can grok */
|
slouken@7191
|
1271 |
}
|
slouken@2198
|
1272 |
|
slouken@2198
|
1273 |
diprg.diph.dwSize = sizeof(diprg);
|
slouken@2198
|
1274 |
diprg.diph.dwHeaderSize = sizeof(diprg.diph);
|
slouken@6690
|
1275 |
diprg.diph.dwObj = dev->dwType;
|
slouken@6690
|
1276 |
diprg.diph.dwHow = DIPH_BYID;
|
slouken@2198
|
1277 |
diprg.lMin = AXIS_MIN;
|
slouken@2198
|
1278 |
diprg.lMax = AXIS_MAX;
|
slouken@2198
|
1279 |
|
slouken@2198
|
1280 |
result =
|
slouken@6690
|
1281 |
IDirectInputDevice8_SetProperty(joystick->hwdata->InputDevice,
|
slouken@2198
|
1282 |
DIPROP_RANGE, &diprg.diph);
|
slouken@2198
|
1283 |
if (FAILED(result)) {
|
slouken@2198
|
1284 |
return DIENUM_CONTINUE; /* don't use this axis */
|
slouken@2198
|
1285 |
}
|
slouken@2198
|
1286 |
|
slouken@2198
|
1287 |
/* Set dead zone to 0. */
|
slouken@2198
|
1288 |
dilong.diph.dwSize = sizeof(dilong);
|
slouken@2198
|
1289 |
dilong.diph.dwHeaderSize = sizeof(dilong.diph);
|
slouken@6690
|
1290 |
dilong.diph.dwObj = dev->dwType;
|
slouken@6690
|
1291 |
dilong.diph.dwHow = DIPH_BYID;
|
slouken@2198
|
1292 |
dilong.dwData = 0;
|
slouken@2198
|
1293 |
result =
|
slouken@6690
|
1294 |
IDirectInputDevice8_SetProperty(joystick->hwdata->InputDevice,
|
slouken@2198
|
1295 |
DIPROP_DEADZONE, &dilong.diph);
|
slouken@2198
|
1296 |
if (FAILED(result)) {
|
slouken@2198
|
1297 |
return DIENUM_CONTINUE; /* don't use this axis */
|
slouken@2198
|
1298 |
}
|
slouken@2198
|
1299 |
|
slouken@2198
|
1300 |
joystick->naxes++;
|
slouken@2198
|
1301 |
} else {
|
slouken@2198
|
1302 |
/* not supported at this time */
|
slouken@2198
|
1303 |
return DIENUM_CONTINUE;
|
slouken@2198
|
1304 |
}
|
slouken@2198
|
1305 |
|
slouken@2198
|
1306 |
joystick->hwdata->NumInputs++;
|
slouken@2198
|
1307 |
|
slouken@2198
|
1308 |
if (joystick->hwdata->NumInputs == MAX_INPUTS) {
|
slouken@2198
|
1309 |
return DIENUM_STOP; /* too many */
|
slouken@2198
|
1310 |
}
|
slouken@2198
|
1311 |
|
slouken@2198
|
1312 |
return DIENUM_CONTINUE;
|
slouken@2198
|
1313 |
}
|
slouken@2198
|
1314 |
|
slouken@2198
|
1315 |
/* Function to update the state of a joystick - called as a device poll.
|
slouken@2198
|
1316 |
* This function shouldn't update the joystick structure directly,
|
slouken@2198
|
1317 |
* but instead should call SDL_PrivateJoystick*() to deliver events
|
slouken@2198
|
1318 |
* and update joystick device state.
|
slouken@2198
|
1319 |
*/
|
slouken@2198
|
1320 |
void
|
slouken@2198
|
1321 |
SDL_SYS_JoystickUpdate_Polled(SDL_Joystick * joystick)
|
slouken@2198
|
1322 |
{
|
slouken@2198
|
1323 |
DIJOYSTATE2 state;
|
slouken@2198
|
1324 |
HRESULT result;
|
slouken@2198
|
1325 |
int i;
|
slouken@2198
|
1326 |
|
slouken@2198
|
1327 |
result =
|
slouken@6690
|
1328 |
IDirectInputDevice8_GetDeviceState(joystick->hwdata->InputDevice,
|
slouken@2198
|
1329 |
sizeof(DIJOYSTATE2), &state);
|
slouken@2198
|
1330 |
if (result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED) {
|
slouken@6690
|
1331 |
IDirectInputDevice8_Acquire(joystick->hwdata->InputDevice);
|
slouken@2198
|
1332 |
result =
|
slouken@6690
|
1333 |
IDirectInputDevice8_GetDeviceState(joystick->hwdata->InputDevice,
|
slouken@2198
|
1334 |
sizeof(DIJOYSTATE2), &state);
|
slouken@2198
|
1335 |
}
|
slouken@2198
|
1336 |
|
slouken@7191
|
1337 |
if ( result != DI_OK )
|
slouken@7191
|
1338 |
{
|
slouken@7191
|
1339 |
joystick->hwdata->send_remove_event = 1;
|
slouken@7191
|
1340 |
joystick->hwdata->removed = 1;
|
slouken@7191
|
1341 |
return;
|
slouken@7191
|
1342 |
}
|
slouken@6690
|
1343 |
|
slouken@2198
|
1344 |
/* Set each known axis, button and POV. */
|
slouken@2198
|
1345 |
for (i = 0; i < joystick->hwdata->NumInputs; ++i) {
|
slouken@2198
|
1346 |
const input_t *in = &joystick->hwdata->Inputs[i];
|
slouken@2198
|
1347 |
|
slouken@2198
|
1348 |
switch (in->type) {
|
slouken@2198
|
1349 |
case AXIS:
|
slouken@2198
|
1350 |
switch (in->ofs) {
|
slouken@2198
|
1351 |
case DIJOFS_X:
|
slouken@2198
|
1352 |
SDL_PrivateJoystickAxis_Int(joystick, in->num,
|
slouken@2198
|
1353 |
(Sint16) state.lX);
|
slouken@2198
|
1354 |
break;
|
slouken@2198
|
1355 |
case DIJOFS_Y:
|
slouken@2198
|
1356 |
SDL_PrivateJoystickAxis_Int(joystick, in->num,
|
slouken@2198
|
1357 |
(Sint16) state.lY);
|
slouken@2198
|
1358 |
break;
|
slouken@2198
|
1359 |
case DIJOFS_Z:
|
slouken@2198
|
1360 |
SDL_PrivateJoystickAxis_Int(joystick, in->num,
|
slouken@2198
|
1361 |
(Sint16) state.lZ);
|
slouken@2198
|
1362 |
break;
|
slouken@2198
|
1363 |
case DIJOFS_RX:
|
slouken@2198
|
1364 |
SDL_PrivateJoystickAxis_Int(joystick, in->num,
|
slouken@2198
|
1365 |
(Sint16) state.lRx);
|
slouken@2198
|
1366 |
break;
|
slouken@2198
|
1367 |
case DIJOFS_RY:
|
slouken@2198
|
1368 |
SDL_PrivateJoystickAxis_Int(joystick, in->num,
|
slouken@2198
|
1369 |
(Sint16) state.lRy);
|
slouken@2198
|
1370 |
break;
|
slouken@2198
|
1371 |
case DIJOFS_RZ:
|
slouken@2198
|
1372 |
SDL_PrivateJoystickAxis_Int(joystick, in->num,
|
slouken@2198
|
1373 |
(Sint16) state.lRz);
|
slouken@2198
|
1374 |
break;
|
slouken@2198
|
1375 |
case DIJOFS_SLIDER(0):
|
slouken@2198
|
1376 |
SDL_PrivateJoystickAxis_Int(joystick, in->num,
|
slouken@2198
|
1377 |
(Sint16) state.rglSlider[0]);
|
slouken@2198
|
1378 |
break;
|
slouken@2198
|
1379 |
case DIJOFS_SLIDER(1):
|
slouken@2198
|
1380 |
SDL_PrivateJoystickAxis_Int(joystick, in->num,
|
slouken@2198
|
1381 |
(Sint16) state.rglSlider[1]);
|
slouken@2198
|
1382 |
break;
|
slouken@2198
|
1383 |
}
|
slouken@2198
|
1384 |
|
slouken@2198
|
1385 |
break;
|
slouken@2198
|
1386 |
|
slouken@2198
|
1387 |
case BUTTON:
|
slouken@2198
|
1388 |
SDL_PrivateJoystickButton_Int(joystick, in->num,
|
slouken@3013
|
1389 |
(Uint8) (state.
|
slouken@3013
|
1390 |
rgbButtons[in->ofs -
|
slouken@3013
|
1391 |
DIJOFS_BUTTON0]
|
slouken@2198
|
1392 |
? SDL_PRESSED :
|
slouken@2198
|
1393 |
SDL_RELEASED));
|
slouken@2198
|
1394 |
break;
|
slouken@2198
|
1395 |
case HAT:
|
slouken@2198
|
1396 |
{
|
slouken@2198
|
1397 |
Uint8 pos = TranslatePOV(state.rgdwPOV[in->ofs -
|
slouken@2198
|
1398 |
DIJOFS_POV(0)]);
|
slouken@2198
|
1399 |
SDL_PrivateJoystickHat_Int(joystick, in->num, pos);
|
slouken@2198
|
1400 |
break;
|
slouken@2198
|
1401 |
}
|
slouken@2198
|
1402 |
}
|
slouken@2198
|
1403 |
}
|
slouken@2198
|
1404 |
}
|
slouken@2198
|
1405 |
|
slouken@2198
|
1406 |
void
|
slouken@2198
|
1407 |
SDL_SYS_JoystickUpdate_Buffered(SDL_Joystick * joystick)
|
slouken@2198
|
1408 |
{
|
slouken@2198
|
1409 |
int i;
|
slouken@2198
|
1410 |
HRESULT result;
|
slouken@2198
|
1411 |
DWORD numevents;
|
slouken@2198
|
1412 |
DIDEVICEOBJECTDATA evtbuf[INPUT_QSIZE];
|
slouken@2198
|
1413 |
|
slouken@2198
|
1414 |
numevents = INPUT_QSIZE;
|
slouken@2198
|
1415 |
result =
|
slouken@6690
|
1416 |
IDirectInputDevice8_GetDeviceData(joystick->hwdata->InputDevice,
|
slouken@2198
|
1417 |
sizeof(DIDEVICEOBJECTDATA), evtbuf,
|
slouken@2198
|
1418 |
&numevents, 0);
|
slouken@2198
|
1419 |
if (result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED) {
|
slouken@6690
|
1420 |
IDirectInputDevice8_Acquire(joystick->hwdata->InputDevice);
|
slouken@2198
|
1421 |
result =
|
slouken@6690
|
1422 |
IDirectInputDevice8_GetDeviceData(joystick->hwdata->InputDevice,
|
slouken@2198
|
1423 |
sizeof(DIDEVICEOBJECTDATA),
|
slouken@2198
|
1424 |
evtbuf, &numevents, 0);
|
slouken@2198
|
1425 |
}
|
slouken@2198
|
1426 |
|
slouken@2198
|
1427 |
/* Handle the events or punt */
|
slouken@2198
|
1428 |
if (FAILED(result))
|
slouken@7191
|
1429 |
{
|
slouken@7191
|
1430 |
joystick->hwdata->send_remove_event = 1;
|
slouken@7191
|
1431 |
joystick->hwdata->removed = 1;
|
slouken@2198
|
1432 |
return;
|
slouken@7191
|
1433 |
}
|
slouken@2198
|
1434 |
|
slouken@2198
|
1435 |
for (i = 0; i < (int) numevents; ++i) {
|
slouken@2198
|
1436 |
int j;
|
slouken@2198
|
1437 |
|
slouken@2198
|
1438 |
for (j = 0; j < joystick->hwdata->NumInputs; ++j) {
|
slouken@2198
|
1439 |
const input_t *in = &joystick->hwdata->Inputs[j];
|
slouken@2198
|
1440 |
|
slouken@2198
|
1441 |
if (evtbuf[i].dwOfs != in->ofs)
|
slouken@2198
|
1442 |
continue;
|
slouken@2198
|
1443 |
|
slouken@2198
|
1444 |
switch (in->type) {
|
slouken@2198
|
1445 |
case AXIS:
|
slouken@2198
|
1446 |
SDL_PrivateJoystickAxis(joystick, in->num,
|
slouken@2198
|
1447 |
(Sint16) evtbuf[i].dwData);
|
slouken@2198
|
1448 |
break;
|
slouken@2198
|
1449 |
case BUTTON:
|
slouken@2198
|
1450 |
SDL_PrivateJoystickButton(joystick, in->num,
|
slouken@3013
|
1451 |
(Uint8) (evtbuf[i].
|
slouken@3013
|
1452 |
dwData ? SDL_PRESSED :
|
slouken@2198
|
1453 |
SDL_RELEASED));
|
slouken@2198
|
1454 |
break;
|
slouken@2198
|
1455 |
case HAT:
|
slouken@2198
|
1456 |
{
|
slouken@2198
|
1457 |
Uint8 pos = TranslatePOV(evtbuf[i].dwData);
|
slouken@2198
|
1458 |
SDL_PrivateJoystickHat(joystick, in->num, pos);
|
slouken@2198
|
1459 |
}
|
slouken@2198
|
1460 |
}
|
slouken@2198
|
1461 |
}
|
slouken@2198
|
1462 |
}
|
slouken@2198
|
1463 |
}
|
slouken@2198
|
1464 |
|
slouken@2198
|
1465 |
|
slouken@6690
|
1466 |
/* Function to return > 0 if a bit array of buttons differs after applying a mask
|
slouken@6690
|
1467 |
*/
|
slouken@6690
|
1468 |
int ButtonChanged( int ButtonsNow, int ButtonsPrev, int ButtonMask )
|
slouken@6690
|
1469 |
{
|
slouken@7191
|
1470 |
return ( ButtonsNow & ButtonMask ) != ( ButtonsPrev & ButtonMask );
|
slouken@6690
|
1471 |
}
|
slouken@6690
|
1472 |
|
slouken@6690
|
1473 |
/* Function to update the state of a XInput style joystick.
|
slouken@6690
|
1474 |
*/
|
slouken@6690
|
1475 |
void
|
slouken@6690
|
1476 |
SDL_SYS_JoystickUpdate_XInput(SDL_Joystick * joystick)
|
slouken@6690
|
1477 |
{
|
slouken@7191
|
1478 |
HRESULT result;
|
slouken@6690
|
1479 |
|
slouken@7191
|
1480 |
if ( !XINPUTGETSTATE )
|
slouken@7191
|
1481 |
return;
|
slouken@6690
|
1482 |
|
slouken@7191
|
1483 |
result = XINPUTGETSTATE( joystick->hwdata->userid, &joystick->hwdata->XInputState[joystick->hwdata->currentXInputSlot] );
|
slouken@7191
|
1484 |
if ( result == ERROR_DEVICE_NOT_CONNECTED )
|
slouken@7191
|
1485 |
{
|
slouken@7191
|
1486 |
joystick->hwdata->send_remove_event = 1;
|
slouken@7191
|
1487 |
joystick->hwdata->removed = 1;
|
slouken@7191
|
1488 |
return;
|
slouken@7191
|
1489 |
}
|
slouken@6690
|
1490 |
|
slouken@7191
|
1491 |
/* only fire events if the data changed from last time */
|
slouken@7191
|
1492 |
if ( joystick->hwdata->XInputState[joystick->hwdata->currentXInputSlot].dwPacketNumber != 0
|
slouken@7191
|
1493 |
&& joystick->hwdata->XInputState[joystick->hwdata->currentXInputSlot].dwPacketNumber != joystick->hwdata->XInputState[joystick->hwdata->currentXInputSlot^1].dwPacketNumber )
|
slouken@7191
|
1494 |
{
|
slouken@7191
|
1495 |
XINPUT_STATE_EX *pXInputState = &joystick->hwdata->XInputState[joystick->hwdata->currentXInputSlot];
|
slouken@7191
|
1496 |
XINPUT_STATE_EX *pXInputStatePrev = &joystick->hwdata->XInputState[joystick->hwdata->currentXInputSlot ^ 1];
|
slouken@6690
|
1497 |
|
slouken@7191
|
1498 |
SDL_PrivateJoystickAxis(joystick, 0, (Sint16)pXInputState->Gamepad.sThumbLX );
|
slouken@7191
|
1499 |
SDL_PrivateJoystickAxis(joystick, 1, (Sint16)(-1*pXInputState->Gamepad.sThumbLY-1) );
|
slouken@7191
|
1500 |
SDL_PrivateJoystickAxis(joystick, 2, (Sint16)pXInputState->Gamepad.sThumbRX );
|
slouken@7191
|
1501 |
SDL_PrivateJoystickAxis(joystick, 3, (Sint16)(-1*pXInputState->Gamepad.sThumbRY-1) );
|
slouken@7191
|
1502 |
SDL_PrivateJoystickAxis(joystick, 4, (Sint16)((int)pXInputState->Gamepad.bLeftTrigger*32767/255) );
|
slouken@7191
|
1503 |
SDL_PrivateJoystickAxis(joystick, 5, (Sint16)((int)pXInputState->Gamepad.bRightTrigger*32767/255) );
|
slouken@6690
|
1504 |
|
slouken@7191
|
1505 |
if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_DPAD_UP ) )
|
slouken@7191
|
1506 |
SDL_PrivateJoystickButton(joystick, 0, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP ? SDL_PRESSED : SDL_RELEASED );
|
slouken@7191
|
1507 |
if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_DPAD_DOWN ) )
|
slouken@7191
|
1508 |
SDL_PrivateJoystickButton(joystick, 1, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN ? SDL_PRESSED : SDL_RELEASED );
|
slouken@7191
|
1509 |
if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_DPAD_LEFT ) )
|
slouken@7191
|
1510 |
SDL_PrivateJoystickButton(joystick, 2, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT ? SDL_PRESSED : SDL_RELEASED );
|
slouken@7191
|
1511 |
if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_DPAD_RIGHT ) )
|
slouken@7191
|
1512 |
SDL_PrivateJoystickButton(joystick, 3, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT ? SDL_PRESSED : SDL_RELEASED );
|
slouken@7191
|
1513 |
if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_START ) )
|
slouken@7191
|
1514 |
SDL_PrivateJoystickButton(joystick, 4, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_START ? SDL_PRESSED : SDL_RELEASED );
|
slouken@7191
|
1515 |
if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_BACK ) )
|
slouken@7191
|
1516 |
SDL_PrivateJoystickButton(joystick, 5, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_BACK ? SDL_PRESSED : SDL_RELEASED );
|
slouken@7191
|
1517 |
if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_LEFT_THUMB ) )
|
slouken@7191
|
1518 |
SDL_PrivateJoystickButton(joystick, 6, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB ? SDL_PRESSED : SDL_RELEASED );
|
slouken@7191
|
1519 |
if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_RIGHT_THUMB ) )
|
slouken@7191
|
1520 |
SDL_PrivateJoystickButton(joystick, 7, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB ? SDL_PRESSED : SDL_RELEASED );
|
slouken@7191
|
1521 |
if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_LEFT_SHOULDER ) )
|
slouken@7191
|
1522 |
SDL_PrivateJoystickButton(joystick, 8, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER ? SDL_PRESSED : SDL_RELEASED );
|
slouken@7191
|
1523 |
if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_RIGHT_SHOULDER ) )
|
slouken@7191
|
1524 |
SDL_PrivateJoystickButton(joystick, 9, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER ? SDL_PRESSED : SDL_RELEASED );
|
slouken@7191
|
1525 |
if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_A ) )
|
slouken@7191
|
1526 |
SDL_PrivateJoystickButton(joystick, 10, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_A ? SDL_PRESSED : SDL_RELEASED );
|
slouken@7191
|
1527 |
if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_B ) )
|
slouken@7191
|
1528 |
SDL_PrivateJoystickButton(joystick, 11, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_B ? SDL_PRESSED : SDL_RELEASED );
|
slouken@7191
|
1529 |
if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_X ) )
|
slouken@7191
|
1530 |
SDL_PrivateJoystickButton(joystick, 12, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_X ? SDL_PRESSED : SDL_RELEASED );
|
slouken@7191
|
1531 |
if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_Y ) )
|
slouken@7191
|
1532 |
SDL_PrivateJoystickButton(joystick, 13, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_Y ? SDL_PRESSED : SDL_RELEASED );
|
slouken@7191
|
1533 |
if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, 0x400 ) )
|
slouken@7191
|
1534 |
SDL_PrivateJoystickButton(joystick, 14, pXInputState->Gamepad.wButtons & 0x400 ? SDL_PRESSED : SDL_RELEASED ); /* 0x400 is the undocumented code for the guide button */
|
slouken@6690
|
1535 |
|
slouken@7191
|
1536 |
joystick->hwdata->currentXInputSlot ^= 1;
|
slouken@6690
|
1537 |
|
slouken@7191
|
1538 |
}
|
slouken@6690
|
1539 |
}
|
slouken@6690
|
1540 |
|
slouken@6690
|
1541 |
|
slouken@1895
|
1542 |
static Uint8
|
slouken@1895
|
1543 |
TranslatePOV(DWORD value)
|
slouken@1895
|
1544 |
{
|
slouken@1895
|
1545 |
const int HAT_VALS[] = {
|
slouken@1895
|
1546 |
SDL_HAT_UP,
|
slouken@1895
|
1547 |
SDL_HAT_UP | SDL_HAT_RIGHT,
|
slouken@1895
|
1548 |
SDL_HAT_RIGHT,
|
slouken@1895
|
1549 |
SDL_HAT_DOWN | SDL_HAT_RIGHT,
|
slouken@1895
|
1550 |
SDL_HAT_DOWN,
|
slouken@1895
|
1551 |
SDL_HAT_DOWN | SDL_HAT_LEFT,
|
slouken@1895
|
1552 |
SDL_HAT_LEFT,
|
slouken@1895
|
1553 |
SDL_HAT_UP | SDL_HAT_LEFT
|
slouken@1895
|
1554 |
};
|
slouken@1895
|
1555 |
|
slouken@1895
|
1556 |
if (LOWORD(value) == 0xFFFF)
|
slouken@1895
|
1557 |
return SDL_HAT_CENTERED;
|
slouken@1895
|
1558 |
|
slouken@1895
|
1559 |
/* Round the value up: */
|
slouken@1895
|
1560 |
value += 4500 / 2;
|
slouken@1895
|
1561 |
value %= 36000;
|
slouken@1895
|
1562 |
value /= 4500;
|
slouken@1895
|
1563 |
|
slouken@1895
|
1564 |
if (value >= 8)
|
slouken@1895
|
1565 |
return SDL_HAT_CENTERED; /* shouldn't happen */
|
slouken@1895
|
1566 |
|
slouken@1895
|
1567 |
return HAT_VALS[value];
|
slouken@1895
|
1568 |
}
|
slouken@1895
|
1569 |
|
slouken@1895
|
1570 |
/* SDL_PrivateJoystick* doesn't discard duplicate events, so we need to
|
slouken@1895
|
1571 |
* do it. */
|
slouken@1895
|
1572 |
static int
|
slouken@1895
|
1573 |
SDL_PrivateJoystickAxis_Int(SDL_Joystick * joystick, Uint8 axis, Sint16 value)
|
slouken@1895
|
1574 |
{
|
slouken@1895
|
1575 |
if (joystick->axes[axis] != value)
|
slouken@1895
|
1576 |
return SDL_PrivateJoystickAxis(joystick, axis, value);
|
slouken@1895
|
1577 |
return 0;
|
slouken@1895
|
1578 |
}
|
slouken@1895
|
1579 |
|
slouken@1895
|
1580 |
static int
|
slouken@1895
|
1581 |
SDL_PrivateJoystickHat_Int(SDL_Joystick * joystick, Uint8 hat, Uint8 value)
|
slouken@1895
|
1582 |
{
|
slouken@1895
|
1583 |
if (joystick->hats[hat] != value)
|
slouken@1895
|
1584 |
return SDL_PrivateJoystickHat(joystick, hat, value);
|
slouken@1895
|
1585 |
return 0;
|
slouken@1895
|
1586 |
}
|
slouken@1895
|
1587 |
|
slouken@1895
|
1588 |
static int
|
slouken@1895
|
1589 |
SDL_PrivateJoystickButton_Int(SDL_Joystick * joystick, Uint8 button,
|
slouken@1895
|
1590 |
Uint8 state)
|
slouken@1895
|
1591 |
{
|
slouken@1895
|
1592 |
if (joystick->buttons[button] != state)
|
slouken@1895
|
1593 |
return SDL_PrivateJoystickButton(joystick, button, state);
|
slouken@1895
|
1594 |
return 0;
|
slouken@1895
|
1595 |
}
|
slouken@1895
|
1596 |
|
slouken@1895
|
1597 |
void
|
slouken@1895
|
1598 |
SDL_SYS_JoystickUpdate(SDL_Joystick * joystick)
|
slouken@1895
|
1599 |
{
|
slouken@1895
|
1600 |
HRESULT result;
|
slouken@1895
|
1601 |
|
slouken@7191
|
1602 |
if ( joystick->closed || !joystick->hwdata )
|
slouken@7191
|
1603 |
return;
|
slouken@1895
|
1604 |
|
slouken@7191
|
1605 |
if (joystick->hwdata->bXInputDevice)
|
slouken@7191
|
1606 |
{
|
slouken@7191
|
1607 |
SDL_SYS_JoystickUpdate_XInput(joystick);
|
slouken@7191
|
1608 |
}
|
slouken@7191
|
1609 |
else
|
slouken@7191
|
1610 |
{
|
slouken@7191
|
1611 |
result = IDirectInputDevice8_Poll(joystick->hwdata->InputDevice);
|
slouken@7191
|
1612 |
if (result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED) {
|
slouken@7191
|
1613 |
IDirectInputDevice8_Acquire(joystick->hwdata->InputDevice);
|
slouken@7191
|
1614 |
IDirectInputDevice8_Poll(joystick->hwdata->InputDevice);
|
slouken@7191
|
1615 |
}
|
slouken@6690
|
1616 |
|
slouken@7191
|
1617 |
if (joystick->hwdata->buffered)
|
slouken@7191
|
1618 |
SDL_SYS_JoystickUpdate_Buffered(joystick);
|
slouken@7191
|
1619 |
else
|
slouken@7191
|
1620 |
SDL_SYS_JoystickUpdate_Polled(joystick);
|
slouken@7191
|
1621 |
}
|
slouken@6690
|
1622 |
|
slouken@7191
|
1623 |
if ( joystick->hwdata->removed )
|
slouken@7191
|
1624 |
{
|
slouken@7191
|
1625 |
joystick->closed = 1;
|
slouken@7191
|
1626 |
joystick->uncentered = 1;
|
slouken@7191
|
1627 |
}
|
slouken@1895
|
1628 |
}
|
slouken@1895
|
1629 |
|
slouken@1895
|
1630 |
/* Function to close a joystick after use */
|
slouken@1895
|
1631 |
void
|
slouken@1895
|
1632 |
SDL_SYS_JoystickClose(SDL_Joystick * joystick)
|
slouken@1895
|
1633 |
{
|
slouken@7191
|
1634 |
if ( joystick->hwdata->bXInputDevice )
|
slouken@7191
|
1635 |
{
|
slouken@7191
|
1636 |
JoyStick_DeviceData *joysticklist = SYS_Joystick;
|
slouken@7191
|
1637 |
/* scan the opened joysticks and clear the userid for this instance */
|
slouken@7191
|
1638 |
for( ; joysticklist; joysticklist = joysticklist->pNext)
|
slouken@7191
|
1639 |
{
|
slouken@7191
|
1640 |
if ( joysticklist->bXInputDevice && joysticklist->nInstanceID == joystick->instance_id )
|
slouken@7191
|
1641 |
{
|
slouken@7191
|
1642 |
joysticklist->XInputUserId = INVALID_XINPUT_USERID;
|
slouken@7191
|
1643 |
}
|
slouken@7191
|
1644 |
}
|
slouken@6690
|
1645 |
|
slouken@7191
|
1646 |
}
|
slouken@7191
|
1647 |
else
|
slouken@7191
|
1648 |
{
|
slouken@7191
|
1649 |
IDirectInputDevice8_Unacquire(joystick->hwdata->InputDevice);
|
slouken@7191
|
1650 |
IDirectInputDevice8_Release(joystick->hwdata->InputDevice);
|
slouken@7191
|
1651 |
}
|
slouken@1895
|
1652 |
|
slouken@1895
|
1653 |
if (joystick->hwdata != NULL) {
|
slouken@1895
|
1654 |
/* free system specific hardware data */
|
slouken@2713
|
1655 |
SDL_free(joystick->hwdata);
|
slouken@1895
|
1656 |
}
|
slouken@6690
|
1657 |
|
slouken@7191
|
1658 |
joystick->closed = 1;
|
slouken@1895
|
1659 |
}
|
slouken@1895
|
1660 |
|
slouken@1895
|
1661 |
/* Function to perform any system-specific joystick related cleanup */
|
slouken@1895
|
1662 |
void
|
slouken@1895
|
1663 |
SDL_SYS_JoystickQuit(void)
|
slouken@1895
|
1664 |
{
|
slouken@7191
|
1665 |
JoyStick_DeviceData *device = SYS_Joystick;
|
slouken@5090
|
1666 |
|
slouken@7191
|
1667 |
while ( device )
|
slouken@7191
|
1668 |
{
|
slouken@7191
|
1669 |
JoyStick_DeviceData *device_next = device->pNext;
|
slouken@7191
|
1670 |
SDL_free(device->joystickname);
|
slouken@7191
|
1671 |
SDL_free(device);
|
slouken@7191
|
1672 |
device = device_next;
|
slouken@7191
|
1673 |
}
|
slouken@7191
|
1674 |
SYS_Joystick = NULL;
|
slouken@6690
|
1675 |
|
slouken@7191
|
1676 |
if ( s_threadJoystick )
|
slouken@7191
|
1677 |
{
|
slouken@7191
|
1678 |
SDL_LockMutex( s_mutexJoyStickEnum );
|
slouken@7191
|
1679 |
s_bJoystickThreadQuit = SDL_TRUE;
|
slouken@7191
|
1680 |
SDL_CondBroadcast( s_condJoystickThread ); /* signal the joystick thread to quit */
|
slouken@7191
|
1681 |
SDL_UnlockMutex( s_mutexJoyStickEnum );
|
slouken@7191
|
1682 |
SDL_WaitThread( s_threadJoystick, NULL ); /* wait for it to bugger off */
|
slouken@6690
|
1683 |
|
slouken@7191
|
1684 |
SDL_DestroyMutex( s_mutexJoyStickEnum );
|
slouken@7191
|
1685 |
SDL_DestroyCond( s_condJoystickThread );
|
slouken@7191
|
1686 |
s_condJoystickThread= NULL;
|
slouken@7191
|
1687 |
s_mutexJoyStickEnum = NULL;
|
slouken@7191
|
1688 |
s_threadJoystick = NULL;
|
slouken@7191
|
1689 |
}
|
slouken@5090
|
1690 |
|
icculus@5591
|
1691 |
if (dinput != NULL) {
|
slouken@6690
|
1692 |
IDirectInput8_Release(dinput);
|
icculus@5591
|
1693 |
dinput = NULL;
|
icculus@5591
|
1694 |
}
|
icculus@5591
|
1695 |
|
icculus@5591
|
1696 |
if (coinitialized) {
|
icculus@5591
|
1697 |
WIN_CoUninitialize();
|
icculus@5591
|
1698 |
coinitialized = SDL_FALSE;
|
icculus@5591
|
1699 |
}
|
slouken@6690
|
1700 |
|
slouken@7191
|
1701 |
if ( s_pKnownJoystickGUIDs )
|
slouken@7191
|
1702 |
{
|
slouken@7191
|
1703 |
SDL_free( s_pKnownJoystickGUIDs );
|
slouken@7191
|
1704 |
s_pKnownJoystickGUIDs = NULL;
|
slouken@7191
|
1705 |
}
|
slouken@6690
|
1706 |
|
icculus@6990
|
1707 |
if (s_bXInputEnabled) {
|
icculus@6990
|
1708 |
WIN_UnloadXInputDLL();
|
icculus@6990
|
1709 |
}
|
slouken@6690
|
1710 |
}
|
slouken@6690
|
1711 |
|
slouken@6690
|
1712 |
|
slouken@6690
|
1713 |
/* return the stable device guid for this device index */
|
slouken@6738
|
1714 |
SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index )
|
slouken@6690
|
1715 |
{
|
slouken@7191
|
1716 |
JoyStick_DeviceData *device = SYS_Joystick;
|
slouken@7191
|
1717 |
int index;
|
slouken@6690
|
1718 |
|
slouken@7191
|
1719 |
for (index = device_index; index > 0; index--)
|
slouken@7191
|
1720 |
device = device->pNext;
|
slouken@6690
|
1721 |
|
slouken@7191
|
1722 |
return device->guid;
|
slouken@6690
|
1723 |
}
|
slouken@6690
|
1724 |
|
slouken@6738
|
1725 |
SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick)
|
slouken@6707
|
1726 |
{
|
slouken@7191
|
1727 |
return joystick->hwdata->guid;
|
slouken@6707
|
1728 |
}
|
slouken@6707
|
1729 |
|
slouken@6707
|
1730 |
/* return SDL_TRUE if this device is using XInput */
|
slouken@6707
|
1731 |
SDL_bool SDL_SYS_IsXInputDeviceIndex(int device_index)
|
slouken@6690
|
1732 |
{
|
slouken@7191
|
1733 |
JoyStick_DeviceData *device = SYS_Joystick;
|
slouken@7191
|
1734 |
int index;
|
slouken@6690
|
1735 |
|
slouken@7191
|
1736 |
for (index = device_index; index > 0; index--)
|
slouken@7191
|
1737 |
device = device->pNext;
|
slouken@6690
|
1738 |
|
slouken@7191
|
1739 |
return device->bXInputDevice;
|
slouken@6690
|
1740 |
}
|
slouken@6690
|
1741 |
|
slouken@1895
|
1742 |
#endif /* SDL_JOYSTICK_DINPUT */
|
slouken@3575
|
1743 |
|
slouken@1895
|
1744 |
/* vi: set ts=4 sw=4 expandtab: */
|