diff options
Diffstat (limited to 'src/joystick/windows')
-rw-r--r-- | src/joystick/windows/SDL_dxjoystick.c | 1704 | ||||
-rw-r--r-- | src/joystick/windows/SDL_dxjoystick_c.h | 60 | ||||
-rw-r--r-- | src/joystick/windows/SDL_mmjoystick.c | 16 |
3 files changed, 890 insertions, 890 deletions
diff --git a/src/joystick/windows/SDL_dxjoystick.c b/src/joystick/windows/SDL_dxjoystick.c index b610220046..9e86e2f0e9 100644 --- a/src/joystick/windows/SDL_dxjoystick.c +++ b/src/joystick/windows/SDL_dxjoystick.c @@ -23,10 +23,10 @@ #ifdef SDL_JOYSTICK_DINPUT /* DirectInput joystick driver; written by Glenn Maynard, based on Andrei de - * A. Formiga's WINMM driver. + * A. Formiga's WINMM driver. * * Hats and sliders are completely untested; the app I'm writing this for mostly - * doesn't use them and I don't own any joysticks with them. + * doesn't use them and I don't own any joysticks with them. * * We don't bother to use event notification here. It doesn't seem to work * with polled devices, and it's fine to call IDirectInputDevice8_GetDeviceData and @@ -49,15 +49,15 @@ #endif #ifndef DIDFT_OPTIONAL -#define DIDFT_OPTIONAL 0x80000000 +#define DIDFT_OPTIONAL 0x80000000 #endif -#define INPUT_QSIZE 32 /* Buffer up to 32 input messages */ +#define INPUT_QSIZE 32 /* Buffer up to 32 input messages */ #define MAX_JOYSTICKS 8 -#define AXIS_MIN -32768 /* minimum value for axis coordinate */ -#define AXIS_MAX 32767 /* maximum value for axis coordinate */ -#define JOY_AXIS_THRESHOLD (((AXIS_MAX)-(AXIS_MIN))/100) /* 1% motion */ +#define AXIS_MIN -32768 /* minimum value for axis coordinate */ +#define AXIS_MAX 32767 /* maximum value for axis coordinate */ +#define JOY_AXIS_THRESHOLD (((AXIS_MAX)-(AXIS_MIN))/100) /* 1% motion */ /* external variables referenced. */ extern HWND SDL_HelperWindow; @@ -96,10 +96,10 @@ WIN_LoadXInputDLL(void) } version = (1 << 16) | 4; - s_pXInputDLL = LoadLibrary( L"XInput1_4.dll" ); // 1.4 Ships with Windows 8. + s_pXInputDLL = LoadLibrary( L"XInput1_4.dll" ); /* 1.4 Ships with Windows 8. */ if (!s_pXInputDLL) { version = (1 << 16) | 3; - s_pXInputDLL = LoadLibrary( L"XInput1_3.dll" ); // 1.3 Ships with Vista and Win7, can be installed as a redistributable component. + s_pXInputDLL = LoadLibrary( L"XInput1_3.dll" ); /* 1.3 Ships with Vista and Win7, can be installed as a redistributable component. */ } if (!s_pXInputDLL) { s_pXInputDLL = LoadLibrary( L"bin\\XInput1_3.dll" ); @@ -144,14 +144,14 @@ extern HRESULT(WINAPI * DInputCreate) (HINSTANCE hinst, DWORD dwVersion, LPUNKNOWN punkOuter); struct JoyStick_DeviceData_ { - SDL_JoystickGUID guid; - DIDEVICEINSTANCE dxdevice; - char *joystickname; - Uint8 send_add_event; - SDL_JoystickID nInstanceID; - SDL_bool bXInputDevice; - Uint8 XInputUserId; - struct JoyStick_DeviceData_ *pNext; + SDL_JoystickGUID guid; + DIDEVICEINSTANCE dxdevice; + char *joystickname; + Uint8 send_add_event; + SDL_JoystickID nInstanceID; + SDL_bool bXInputDevice; + Uint8 XInputUserId; + struct JoyStick_DeviceData_ *pNext; }; typedef struct JoyStick_DeviceData_ JoyStick_DeviceData; @@ -173,7 +173,7 @@ static int SDL_PrivateJoystickHat_Int(SDL_Joystick * joystick, Uint8 hat, static int SDL_PrivateJoystickButton_Int(SDL_Joystick * joystick, Uint8 button, Uint8 state); -// Taken from Wine - Thanks! +/* Taken from Wine - Thanks! */ DIOBJECTDATAFORMAT dfDIJoystick2[] = { { &GUID_XAxis,DIJOFS_X,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, { &GUID_YAxis,DIJOFS_Y,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0}, @@ -365,150 +365,150 @@ SetDIerror(const char *function, HRESULT code) #define SAFE_RELEASE(p) \ { \ - if (p) { \ - (p)->lpVtbl->Release((p)); \ - (p) = 0; \ - } \ + if (p) { \ + (p)->lpVtbl->Release((p)); \ + (p) = 0; \ + } \ } DEFINE_GUID(CLSID_WbemLocator, 0x4590f811,0x1d3a,0x11d0,0x89,0x1F,0x00,0xaa,0x00,0x4b,0x2e,0x24); DEFINE_GUID(IID_IWbemLocator, 0xdc12a687,0x737f,0x11cf,0x88,0x4d,0x00,0xaa,0x00,0x4b,0x2e,0x24); -//----------------------------------------------------------------------------- -// -// code from MSDN: http://msdn.microsoft.com/en-us/library/windows/desktop/ee417014(v=vs.85).aspx -// -// Enum each PNP device using WMI and check each device ID to see if it contains -// "IG_" (ex. "VID_045E&PID_028E&IG_00"). If it does, then it's an XInput device -// Unfortunately this information can not be found by just using DirectInput -//----------------------------------------------------------------------------- +/*----------------------------------------------------------------------------- + * + * code from MSDN: http://msdn.microsoft.com/en-us/library/windows/desktop/ee417014(v=vs.85).aspx + * + * Enum each PNP device using WMI and check each device ID to see if it contains + * "IG_" (ex. "VID_045E&PID_028E&IG_00"). If it does, then it's an XInput device + * Unfortunately this information can not be found by just using DirectInput + *-----------------------------------------------------------------------------*/ BOOL IsXInputDevice( const GUID* pGuidProductFromDirectInput ) { - IWbemLocator* pIWbemLocator = NULL; - IEnumWbemClassObject* pEnumDevices = NULL; - IWbemClassObject* pDevices[20]; - IWbemServices* pIWbemServices = NULL; - DWORD uReturned = 0; - BSTR bstrNamespace = NULL; - BSTR bstrDeviceID = NULL; - BSTR bstrClassName = NULL; - SDL_bool bIsXinputDevice= SDL_FALSE; - UINT iDevice = 0; - VARIANT var; - HRESULT hr; - DWORD bCleanupCOM; + IWbemLocator* pIWbemLocator = NULL; + IEnumWbemClassObject* pEnumDevices = NULL; + IWbemClassObject* pDevices[20]; + IWbemServices* pIWbemServices = NULL; + DWORD uReturned = 0; + BSTR bstrNamespace = NULL; + BSTR bstrDeviceID = NULL; + BSTR bstrClassName = NULL; + SDL_bool bIsXinputDevice= SDL_FALSE; + UINT iDevice = 0; + VARIANT var; + HRESULT hr; + DWORD bCleanupCOM; if (!s_bXInputEnabled) { return SDL_FALSE; } - SDL_memset( pDevices, 0x0, sizeof(pDevices) ); - - // CoInit if needed - hr = CoInitialize(NULL); - bCleanupCOM = SUCCEEDED(hr); - - // Create WMI - hr = CoCreateInstance( &CLSID_WbemLocator, - NULL, - CLSCTX_INPROC_SERVER, - &IID_IWbemLocator, - (LPVOID*) &pIWbemLocator); - if( FAILED(hr) || pIWbemLocator == NULL ) - goto LCleanup; - - bstrNamespace = SysAllocString( L"\\\\.\\root\\cimv2" );if( bstrNamespace == NULL ) goto LCleanup; - bstrClassName = SysAllocString( L"Win32_PNPEntity" ); if( bstrClassName == NULL ) goto LCleanup; - bstrDeviceID = SysAllocString( L"DeviceID" ); if( bstrDeviceID == NULL ) goto LCleanup; - - // Connect to WMI - hr = IWbemLocator_ConnectServer( pIWbemLocator, bstrNamespace, NULL, NULL, 0L, - 0L, NULL, NULL, &pIWbemServices ); - if( FAILED(hr) || pIWbemServices == NULL ) - goto LCleanup; - - // Switch security level to IMPERSONATE. - CoSetProxyBlanket( (IUnknown *)pIWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, - RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE ); - - hr = IWbemServices_CreateInstanceEnum( pIWbemServices, bstrClassName, 0, NULL, &pEnumDevices ); - if( FAILED(hr) || pEnumDevices == NULL ) - goto LCleanup; - - // Loop over all devices - for( ;; ) - { - // Get 20 at a time - hr = IEnumWbemClassObject_Next( pEnumDevices, 10000, 20, pDevices, &uReturned ); - if( FAILED(hr) ) - goto LCleanup; - if( uReturned == 0 ) - break; - - for( iDevice=0; iDevice<uReturned; iDevice++ ) - { - // For each device, get its device ID - hr = IWbemClassObject_Get( pDevices[iDevice], bstrDeviceID, 0L, &var, NULL, NULL ); - if( SUCCEEDED( hr ) && var.vt == VT_BSTR && var.bstrVal != NULL ) - { - // Check if the device ID contains "IG_". If it does, then it's an XInput device - // This information can not be found from DirectInput - char *pDeviceString = WIN_StringToUTF8( var.bstrVal ); - if( SDL_strstr( pDeviceString, "IG_" ) ) - { - // If it does, then get the VID/PID from var.bstrVal - long dwPid = 0, dwVid = 0; - char * strPid = NULL; - DWORD dwVidPid = 0; - char * strVid = SDL_strstr( pDeviceString, "VID_" ); - if( strVid ) - { - dwVid = SDL_strtol( strVid + 4, NULL, 16 ); - } - strPid = SDL_strstr( pDeviceString, "PID_" ); - if( strPid ) - { - dwPid = SDL_strtol( strPid + 4, NULL, 16 ); - } - - // Compare the VID/PID to the DInput device - dwVidPid = MAKELONG( dwVid, dwPid ); - if( dwVidPid == pGuidProductFromDirectInput->Data1 ) - { - bIsXinputDevice = SDL_TRUE; - } - } - if ( pDeviceString ) - SDL_free( pDeviceString ); - - if ( bIsXinputDevice ) - break; - } - SAFE_RELEASE( pDevices[iDevice] ); - } - } - + SDL_memset( pDevices, 0x0, sizeof(pDevices) ); + + /* CoInit if needed */ + hr = CoInitialize(NULL); + bCleanupCOM = SUCCEEDED(hr); + + /* Create WMI */ + hr = CoCreateInstance( &CLSID_WbemLocator, + NULL, + CLSCTX_INPROC_SERVER, + &IID_IWbemLocator, + (LPVOID*) &pIWbemLocator); + if( FAILED(hr) || pIWbemLocator == NULL ) + goto LCleanup; + + bstrNamespace = SysAllocString( L"\\\\.\\root\\cimv2" );if( bstrNamespace == NULL ) goto LCleanup; + bstrClassName = SysAllocString( L"Win32_PNPEntity" ); if( bstrClassName == NULL ) goto LCleanup; + bstrDeviceID = SysAllocString( L"DeviceID" ); if( bstrDeviceID == NULL ) goto LCleanup; + + /* Connect to WMI */ + hr = IWbemLocator_ConnectServer( pIWbemLocator, bstrNamespace, NULL, NULL, 0L, + 0L, NULL, NULL, &pIWbemServices ); + if( FAILED(hr) || pIWbemServices == NULL ) + goto LCleanup; + + /* Switch security level to IMPERSONATE. */ + CoSetProxyBlanket( (IUnknown *)pIWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, + RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE ); + + hr = IWbemServices_CreateInstanceEnum( pIWbemServices, bstrClassName, 0, NULL, &pEnumDevices ); + if( FAILED(hr) || pEnumDevices == NULL ) + goto LCleanup; + + /* Loop over all devices */ + for( ;; ) + { + /* Get 20 at a time */ + hr = IEnumWbemClassObject_Next( pEnumDevices, 10000, 20, pDevices, &uReturned ); + if( FAILED(hr) ) + goto LCleanup; + if( uReturned == 0 ) + break; + + for( iDevice=0; iDevice<uReturned; iDevice++ ) + { + /* For each device, get its device ID */ + hr = IWbemClassObject_Get( pDevices[iDevice], bstrDeviceID, 0L, &var, NULL, NULL ); + if( SUCCEEDED( hr ) && var.vt == VT_BSTR && var.bstrVal != NULL ) + { + /* Check if the device ID contains "IG_". If it does, then it's an XInput device */ + /* This information can not be found from DirectInput */ + char *pDeviceString = WIN_StringToUTF8( var.bstrVal ); + if( SDL_strstr( pDeviceString, "IG_" ) ) + { + /* If it does, then get the VID/PID from var.bstrVal */ + long dwPid = 0, dwVid = 0; + char * strPid = NULL; + DWORD dwVidPid = 0; + char * strVid = SDL_strstr( pDeviceString, "VID_" ); + if( strVid ) + { + dwVid = SDL_strtol( strVid + 4, NULL, 16 ); + } + strPid = SDL_strstr( pDeviceString, "PID_" ); + if( strPid ) + { + dwPid = SDL_strtol( strPid + 4, NULL, 16 ); + } + + /* Compare the VID/PID to the DInput device */ + dwVidPid = MAKELONG( dwVid, dwPid ); + if( dwVidPid == pGuidProductFromDirectInput->Data1 ) + { + bIsXinputDevice = SDL_TRUE; + } + } + if ( pDeviceString ) + SDL_free( pDeviceString ); + + if ( bIsXinputDevice ) + break; + } + SAFE_RELEASE( pDevices[iDevice] ); + } + } + LCleanup: - for( iDevice=0; iDevice<20; iDevice++ ) - SAFE_RELEASE( pDevices[iDevice] ); - SAFE_RELEASE( pEnumDevices ); - SAFE_RELEASE( pIWbemLocator ); - SAFE_RELEASE( pIWbemServices ); - - if ( bstrNamespace ) - SysFreeString( bstrNamespace ); - if ( bstrClassName ) - SysFreeString( bstrClassName ); - if ( bstrDeviceID ) - SysFreeString( bstrDeviceID ); - - if( bCleanupCOM ) - CoUninitialize(); - - return bIsXinputDevice; + for( iDevice=0; iDevice<20; iDevice++ ) + SAFE_RELEASE( pDevices[iDevice] ); + SAFE_RELEASE( pEnumDevices ); + SAFE_RELEASE( pIWbemLocator ); + SAFE_RELEASE( pIWbemServices ); + + if ( bstrNamespace ) + SysFreeString( bstrNamespace ); + if ( bstrClassName ) + SysFreeString( bstrClassName ); + if ( bstrDeviceID ) + SysFreeString( bstrDeviceID ); + + if( bCleanupCOM ) + CoUninitialize(); + + return bIsXinputDevice; } @@ -517,137 +517,137 @@ static SDL_bool s_bWindowsDeviceChanged = SDL_FALSE; /* windowproc for our joystick detect thread message only window, to detect any USB device addition/removal */ LRESULT CALLBACK SDL_PrivateJoystickDetectProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { - switch (message) { - case WM_DEVICECHANGE: - switch (wParam) { - case DBT_DEVICEARRIVAL: - if (((DEV_BROADCAST_HDR*)lParam)->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) { - s_bWindowsDeviceChanged = SDL_TRUE; - } - break; - case DBT_DEVICEREMOVECOMPLETE: - if (((DEV_BROADCAST_HDR*)lParam)->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) { - s_bWindowsDeviceChanged = SDL_TRUE; - } - break; - } - return 0; - } - - return DefWindowProc (hwnd, message, wParam, lParam); + switch (message) { + case WM_DEVICECHANGE: + switch (wParam) { + case DBT_DEVICEARRIVAL: + if (((DEV_BROADCAST_HDR*)lParam)->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) { + s_bWindowsDeviceChanged = SDL_TRUE; + } + break; + case DBT_DEVICEREMOVECOMPLETE: + if (((DEV_BROADCAST_HDR*)lParam)->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) { + s_bWindowsDeviceChanged = SDL_TRUE; + } + break; + } + return 0; + } + + return DefWindowProc (hwnd, message, wParam, lParam); } DEFINE_GUID(GUID_DEVINTERFACE_USB_DEVICE, 0xA5DCBF10L, 0x6530, 0x11D2, 0x90, 0x1F, 0x00, \ - 0xC0, 0x4F, 0xB9, 0x51, 0xED); + 0xC0, 0x4F, 0xB9, 0x51, 0xED); /* Function/thread to scan the system for joysticks. */ static int SDL_JoystickThread(void *_data) { - HRESULT result = S_OK; - HWND messageWindow = 0; - HDEVNOTIFY hNotify = 0; - DEV_BROADCAST_DEVICEINTERFACE dbh; - SDL_bool bOpenedXInputDevices[4]; - WNDCLASSEX wincl; - - SDL_memset( bOpenedXInputDevices, 0x0, sizeof(bOpenedXInputDevices) ); - - result = WIN_CoInitialize(); - - SDL_memset( &wincl, 0x0, sizeof(wincl) ); - wincl.hInstance = GetModuleHandle( NULL ); - wincl.lpszClassName = L"Message"; - wincl.lpfnWndProc = SDL_PrivateJoystickDetectProc; // This function is called by windows - wincl.cbSize = sizeof (WNDCLASSEX); - - if (!RegisterClassEx (&wincl)) - { - return SDL_SetError("Failed to create register class for joystick autodetect.", GetLastError()); - } - - messageWindow = (HWND)CreateWindowEx( 0, L"Message", NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL ); - if ( !messageWindow ) - { - return SDL_SetError("Failed to create message window for joystick autodetect.", GetLastError()); - } - - SDL_memset(&dbh, 0x0, sizeof(dbh)); - - dbh.dbcc_size = sizeof(dbh); - dbh.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; - dbh.dbcc_classguid = GUID_DEVINTERFACE_USB_DEVICE; - - hNotify = RegisterDeviceNotification( messageWindow, &dbh, DEVICE_NOTIFY_WINDOW_HANDLE ); - if ( !hNotify ) - { - return SDL_SetError("Failed to create notify device for joystick autodetect.", GetLastError()); - } - - SDL_LockMutex( s_mutexJoyStickEnum ); - while ( s_bJoystickThreadQuit == SDL_FALSE ) - { - MSG messages; - Uint8 userId; - int nCurrentOpenedXInputDevices = 0; - int nNewOpenedXInputDevices = 0; - SDL_CondWaitTimeout( s_condJoystickThread, s_mutexJoyStickEnum, 300 ); - - while ( s_bJoystickThreadQuit == SDL_FALSE && PeekMessage(&messages, messageWindow, 0, 0, PM_NOREMOVE) ) - { - if ( GetMessage(&messages, messageWindow, 0, 0) != 0 ) { - TranslateMessage(&messages); - DispatchMessage(&messages); - } - } - - if ( s_bXInputEnabled && XINPUTGETCAPABILITIES ) - { - // scan for any change in XInput devices - for ( userId = 0; userId < 4; userId++ ) - { - XINPUT_CAPABILITIES capabilities; - DWORD result; - - if ( bOpenedXInputDevices[userId] == SDL_TRUE ) - nCurrentOpenedXInputDevices++; - - result = XINPUTGETCAPABILITIES( userId, XINPUT_FLAG_GAMEPAD, &capabilities ); - if ( result == ERROR_SUCCESS ) - { - bOpenedXInputDevices[userId] = SDL_TRUE; - nNewOpenedXInputDevices++; - } - else - { - bOpenedXInputDevices[userId] = SDL_FALSE; - } - } - } - - if ( s_pKnownJoystickGUIDs && ( s_bWindowsDeviceChanged || nNewOpenedXInputDevices != nCurrentOpenedXInputDevices ) ) - { - SDL_Delay( 300 ); // wait for direct input to find out about this device - - s_bDeviceRemoved = SDL_TRUE; - s_bDeviceAdded = SDL_TRUE; - s_bWindowsDeviceChanged = SDL_FALSE; - } - } - SDL_UnlockMutex( s_mutexJoyStickEnum ); - - if ( hNotify ) - UnregisterDeviceNotification( hNotify ); - - if ( messageWindow ) - DestroyWindow( messageWindow ); - - UnregisterClass( wincl.lpszClassName, wincl.hInstance ); - messageWindow = 0; - WIN_CoUninitialize(); - return 1; + HRESULT result = S_OK; + HWND messageWindow = 0; + HDEVNOTIFY hNotify = 0; + DEV_BROADCAST_DEVICEINTERFACE dbh; + SDL_bool bOpenedXInputDevices[4]; + WNDCLASSEX wincl; + + SDL_memset( bOpenedXInputDevices, 0x0, sizeof(bOpenedXInputDevices) ); + + result = WIN_CoInitialize(); + + SDL_memset( &wincl, 0x0, sizeof(wincl) ); + wincl.hInstance = GetModuleHandle( NULL ); + wincl.lpszClassName = L"Message"; + wincl.lpfnWndProc = SDL_PrivateJoystickDetectProc; /* This function is called by windows */ + wincl.cbSize = sizeof (WNDCLASSEX); + + if (!RegisterClassEx (&wincl)) + { + return SDL_SetError("Failed to create register class for joystick autodetect.", GetLastError()); + } + + messageWindow = (HWND)CreateWindowEx( 0, L"Message", NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL ); + if ( !messageWindow ) + { + return SDL_SetError("Failed to create message window for joystick autodetect.", GetLastError()); + } + + SDL_memset(&dbh, 0x0, sizeof(dbh)); + + dbh.dbcc_size = sizeof(dbh); + dbh.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; + dbh.dbcc_classguid = GUID_DEVINTERFACE_USB_DEVICE; + + hNotify = RegisterDeviceNotification( messageWindow, &dbh, DEVICE_NOTIFY_WINDOW_HANDLE ); + if ( !hNotify ) + { + return SDL_SetError("Failed to create notify device for joystick autodetect.", GetLastError()); + } + + SDL_LockMutex( s_mutexJoyStickEnum ); + while ( s_bJoystickThreadQuit == SDL_FALSE ) + { + MSG messages; + Uint8 userId; + int nCurrentOpenedXInputDevices = 0; + int nNewOpenedXInputDevices = 0; + SDL_CondWaitTimeout( s_condJoystickThread, s_mutexJoyStickEnum, 300 ); + + while ( s_bJoystickThreadQuit == SDL_FALSE && PeekMessage(&messages, messageWindow, 0, 0, PM_NOREMOVE) ) + { + if ( GetMessage(&messages, messageWindow, 0, 0) != 0 ) { + TranslateMessage(&messages); + DispatchMessage(&messages); + } + } + + if ( s_bXInputEnabled && XINPUTGETCAPABILITIES ) + { + /* scan for any change in XInput devices */ + for ( userId = 0; userId < 4; userId++ ) + { + XINPUT_CAPABILITIES capabilities; + DWORD result; + + if ( bOpenedXInputDevices[userId] == SDL_TRUE ) + nCurrentOpenedXInputDevices++; + + result = XINPUTGETCAPABILITIES( userId, XINPUT_FLAG_GAMEPAD, &capabilities ); + if ( result == ERROR_SUCCESS ) + { + bOpenedXInputDevices[userId] = SDL_TRUE; + nNewOpenedXInputDevices++; + } + else + { + bOpenedXInputDevices[userId] = SDL_FALSE; + } + } + } + + if ( s_pKnownJoystickGUIDs && ( s_bWindowsDeviceChanged || nNewOpenedXInputDevices != nCurrentOpenedXInputDevices ) ) + { + SDL_Delay( 300 ); /* wait for direct input to find out about this device */ + + s_bDeviceRemoved = SDL_TRUE; + s_bDeviceAdded = SDL_TRUE; + s_bWindowsDeviceChanged = SDL_FALSE; + } + } + SDL_UnlockMutex( s_mutexJoyStickEnum ); + + if ( hNotify ) + UnregisterDeviceNotification( hNotify ); + + if ( messageWindow ) + DestroyWindow( messageWindow ); + + UnregisterClass( wincl.lpszClassName, wincl.hInstance ); + messageWindow = 0; + WIN_CoUninitialize(); + return 1; } @@ -661,10 +661,10 @@ SDL_SYS_JoystickInit(void) { HRESULT result; HINSTANCE instance; - const char *env = SDL_GetHint(SDL_HINT_XINPUT_ENABLED); - if (env && !SDL_atoi(env)) { - s_bXInputEnabled = SDL_FALSE; - } + const char *env = SDL_GetHint(SDL_HINT_XINPUT_ENABLED); + if (env && !SDL_atoi(env)) { + s_bXInputEnabled = SDL_FALSE; + } result = WIN_CoInitialize(); if (FAILED(result)) { @@ -696,238 +696,238 @@ SDL_SYS_JoystickInit(void) s_mutexJoyStickEnum = SDL_CreateMutex(); s_condJoystickThread = SDL_CreateCond(); - s_bDeviceAdded = SDL_TRUE; // force a scan of the system for joysticks this first time + s_bDeviceAdded = SDL_TRUE; /* force a scan of the system for joysticks this first time */ SDL_SYS_JoystickDetect(); if ((s_bXInputEnabled) && (WIN_LoadXInputDLL() == -1)) { s_bXInputEnabled = SDL_FALSE; /* oh well. */ } - if ( !s_threadJoystick ) - { - s_bJoystickThreadQuit = SDL_FALSE; - /* spin up the thread to detect hotplug of devices */ + if ( !s_threadJoystick ) + { + s_bJoystickThreadQuit = SDL_FALSE; + /* spin up the thread to detect hotplug of devices */ #if defined(__WIN32__) && !defined(HAVE_LIBC) #undef SDL_CreateThread - s_threadJoystick= SDL_CreateThread( SDL_JoystickThread, "SDL_joystick", NULL, NULL, NULL ); + s_threadJoystick= SDL_CreateThread( SDL_JoystickThread, "SDL_joystick", NULL, NULL, NULL ); #else - s_threadJoystick = SDL_CreateThread( SDL_JoystickThread, "SDL_joystick", NULL ); + s_threadJoystick = SDL_CreateThread( SDL_JoystickThread, "SDL_joystick", NULL ); #endif - } - return SDL_SYS_NumJoysticks(); + } + return SDL_SYS_NumJoysticks(); } /* return the number of joysticks that are connected right now */ int SDL_SYS_NumJoysticks() { - int nJoysticks = 0; - JoyStick_DeviceData *device = SYS_Joystick; - while ( device ) - { - nJoysticks++; - device = device->pNext; - } - - return nJoysticks; + int nJoysticks = 0; + JoyStick_DeviceData *device = SYS_Joystick; + while ( device ) + { + nJoysticks++; + device = device->pNext; + } + + return nJoysticks; } static int s_iNewGUID = 0; /* helper function for direct input, gets called for each connected joystick */ static BOOL CALLBACK - EnumJoysticksCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext) + EnumJoysticksCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext) { - JoyStick_DeviceData *pNewJoystick; - JoyStick_DeviceData *pPrevJoystick = NULL; - SDL_bool bXInputDevice; - pNewJoystick = *(JoyStick_DeviceData **)pContext; - while ( pNewJoystick ) - { - if ( !SDL_memcmp( &pNewJoystick->dxdevice.guidInstance, &pdidInstance->guidInstance, sizeof(pNewJoystick->dxdevice.guidInstance) ) ) - { - /* if we are replacing the front of the list then update it */ - if ( pNewJoystick == *(JoyStick_DeviceData **)pContext ) - { - *(JoyStick_DeviceData **)pContext = pNewJoystick->pNext; - } - else if ( pPrevJoystick ) - { - pPrevJoystick->pNext = pNewJoystick->pNext; - } - - pNewJoystick->pNext = SYS_Joystick; - SYS_Joystick = pNewJoystick; - - s_pKnownJoystickGUIDs[ s_iNewGUID ] = pdidInstance->guidInstance; - s_iNewGUID++; - if ( s_iNewGUID < MAX_JOYSTICKS ) - return DIENUM_CONTINUE; // already have this joystick loaded, just keep going - else - return DIENUM_STOP; - } - - pPrevJoystick = pNewJoystick; - pNewJoystick = pNewJoystick->pNext; - } - - s_bDeviceAdded = SDL_TRUE; - - bXInputDevice = IsXInputDevice( &pdidInstance->guidProduct ); - - pNewJoystick = (JoyStick_DeviceData *)SDL_malloc( sizeof(JoyStick_DeviceData) ); - - if ( bXInputDevice ) - { - pNewJoystick->bXInputDevice = SDL_TRUE; - pNewJoystick->XInputUserId = INVALID_XINPUT_USERID; - } - else - { - pNewJoystick->bXInputDevice = SDL_FALSE; - } - - SDL_memcpy(&(pNewJoystick->dxdevice), pdidInstance, - sizeof(DIDEVICEINSTANCE)); - - pNewJoystick->joystickname = WIN_StringToUTF8(pdidInstance->tszProductName); - pNewJoystick->send_add_event = 1; - pNewJoystick->nInstanceID = ++s_nInstanceID; - SDL_memcpy( &pNewJoystick->guid, &pdidInstance->guidProduct, sizeof(pNewJoystick->guid) ); - pNewJoystick->pNext = NULL; - - if ( SYS_Joystick ) - { - pNewJoystick->pNext = SYS_Joystick; - } - SYS_Joystick = pNewJoystick; - - s_pKnownJoystickGUIDs[ s_iNewGUID ] = pdidInstance->guidInstance; - s_iNewGUID++; - - if ( s_iNewGUID < MAX_JOYSTICKS ) - return DIENUM_CONTINUE; // already have this joystick loaded, just keep going - else - return DIENUM_STOP; + JoyStick_DeviceData *pNewJoystick; + JoyStick_DeviceData *pPrevJoystick = NULL; + SDL_bool bXInputDevice; + pNewJoystick = *(JoyStick_DeviceData **)pContext; + while ( pNewJoystick ) + { + if ( !SDL_memcmp( &pNewJoystick->dxdevice.guidInstance, &pdidInstance->guidInstance, sizeof(pNewJoystick->dxdevice.guidInstance) ) ) + { + /* if we are replacing the front of the list then update it */ + if ( pNewJoystick == *(JoyStick_DeviceData **)pContext ) + { + *(JoyStick_DeviceData **)pContext = pNewJoystick->pNext; + } + else if ( pPrevJoystick ) + { + pPrevJoystick->pNext = pNewJoystick->pNext; + } + + pNewJoystick->pNext = SYS_Joystick; + SYS_Joystick = pNewJoystick; + + s_pKnownJoystickGUIDs[ s_iNewGUID ] = pdidInstance->guidInstance; + s_iNewGUID++; + if ( s_iNewGUID < MAX_JOYSTICKS ) + return DIENUM_CONTINUE; /* already have this joystick loaded, just keep going */ + else + return DIENUM_STOP; + } + + pPrevJoystick = pNewJoystick; + pNewJoystick = pNewJoystick->pNext; + } + + s_bDeviceAdded = SDL_TRUE; + + bXInputDevice = IsXInputDevice( &pdidInstance->guidProduct ); + + pNewJoystick = (JoyStick_DeviceData *)SDL_malloc( sizeof(JoyStick_DeviceData) ); + + if ( bXInputDevice ) + { + pNewJoystick->bXInputDevice = SDL_TRUE; + pNewJoystick->XInputUserId = INVALID_XINPUT_USERID; + } + else + { + pNewJoystick->bXInputDevice = SDL_FALSE; + } + + SDL_memcpy(&(pNewJoystick->dxdevice), pdidInstance, + sizeof(DIDEVICEINSTANCE)); + + pNewJoystick->joystickname = WIN_StringToUTF8(pdidInstance->tszProductName); + pNewJoystick->send_add_event = 1; + pNewJoystick->nInstanceID = ++s_nInstanceID; + SDL_memcpy( &pNewJoystick->guid, &pdidInstance->guidProduct, sizeof(pNewJoystick->guid) ); + pNewJoystick->pNext = NULL; + + if ( SYS_Joystick ) + { + pNewJoystick->pNext = SYS_Joystick; + } + SYS_Joystick = pNewJoystick; + + s_pKnownJoystickGUIDs[ s_iNewGUID ] = pdidInstance->guidInstance; + s_iNewGUID++; + + if ( s_iNewGUID < MAX_JOYSTICKS ) + return DIENUM_CONTINUE; /* already have this joystick loaded, just keep going */ + else + return DIENUM_STOP; } /* detect any new joysticks being inserted into the system */ void SDL_SYS_JoystickDetect() { - HRESULT result; - JoyStick_DeviceData *pCurList = NULL; - /* only enum the devices if the joystick thread told us something changed */ - if ( s_bDeviceAdded || s_bDeviceRemoved ) - { - s_bDeviceAdded = SDL_FALSE; - s_bDeviceRemoved = SDL_FALSE; - - pCurList = SYS_Joystick; - SYS_Joystick = NULL; - s_iNewGUID = 0; - SDL_LockMutex( s_mutexJoyStickEnum ); - - if ( !s_pKnownJoystickGUIDs ) - s_pKnownJoystickGUIDs = SDL_malloc( sizeof(GUID)*MAX_JOYSTICKS ); - - SDL_memset( s_pKnownJoystickGUIDs, 0x0, sizeof(GUID)*MAX_JOYSTICKS ); - - /* Look for joysticks, wheels, head trackers, gamepads, etc.. */ - result = IDirectInput8_EnumDevices(dinput, - DI8DEVCLASS_GAMECTRL, - EnumJoysticksCallback, - &pCurList, DIEDFL_ATTACHEDONLY); - - SDL_UnlockMutex( s_mutexJoyStickEnum ); - } - - if ( pCurList ) - { - while ( pCurList ) - { - JoyStick_DeviceData *pListNext = NULL; + HRESULT result; + JoyStick_DeviceData *pCurList = NULL; + /* only enum the devices if the joystick thread told us something changed */ + if ( s_bDeviceAdded || s_bDeviceRemoved ) + { + s_bDeviceAdded = SDL_FALSE; + s_bDeviceRemoved = SDL_FALSE; + + pCurList = SYS_Joystick; + SYS_Joystick = NULL; + s_iNewGUID = 0; + SDL_LockMutex( s_mutexJoyStickEnum ); + + if ( !s_pKnownJoystickGUIDs ) + s_pKnownJoystickGUIDs = SDL_malloc( sizeof(GUID)*MAX_JOYSTICKS ); + + SDL_memset( s_pKnownJoystickGUIDs, 0x0, sizeof(GUID)*MAX_JOYSTICKS ); + + /* Look for joysticks, wheels, head trackers, gamepads, etc.. */ + result = IDirectInput8_EnumDevices(dinput, + DI8DEVCLASS_GAMECTRL, + EnumJoysticksCallback, + &pCurList, DIEDFL_ATTACHEDONLY); + + SDL_UnlockMutex( s_mutexJoyStickEnum ); + } + + if ( pCurList ) + { + while ( pCurList ) + { + JoyStick_DeviceData *pListNext = NULL; #if !SDL_EVENTS_DISABLED - SDL_Event event; - event.type = SDL_JOYDEVICEREMOVED; - - if (SDL_GetEventState(event.type) == SDL_ENABLE) { - event.jdevice.which = pCurList->nInstanceID; - if ((SDL_EventOK == NULL) - || (*SDL_EventOK) (SDL_EventOKParam, &event)) { - SDL_PushEvent(&event); - } - } -#endif // !SDL_EVENTS_DISABLED - - pListNext = pCurList->pNext; - SDL_free(pCurList->joystickname); - SDL_free( pCurList ); - pCurList = pListNext; - } - - } - - if ( s_bDeviceAdded ) - { - JoyStick_DeviceData *pNewJoystick; - int device_index = 0; - s_bDeviceAdded = SDL_FALSE; - pNewJoystick = SYS_Joystick; - while ( pNewJoystick ) - { - if ( pNewJoystick->send_add_event ) - { + SDL_Event event; + event.type = SDL_JOYDEVICEREMOVED; + + if (SDL_GetEventState(event.type) == SDL_ENABLE) { + event.jdevice.which = pCurList->nInstanceID; + if ((SDL_EventOK == NULL) + || (*SDL_EventOK) (SDL_EventOKParam, &event)) { + SDL_PushEvent(&event); + } + } +#endif /* !SDL_EVENTS_DISABLED */ + + pListNext = pCurList->pNext; + SDL_free(pCurList->joystickname); + SDL_free( pCurList ); + pCurList = pListNext; + } + + } + + if ( s_bDeviceAdded ) + { + JoyStick_DeviceData *pNewJoystick; + int device_index = 0; + s_bDeviceAdded = SDL_FALSE; + pNewJoystick = SYS_Joystick; + while ( pNewJoystick ) + { + if ( pNewJoystick->send_add_event ) + { #if !SDL_EVENTS_DISABLED - SDL_Event event; - event.type = SDL_JOYDEVICEADDED; - - if (SDL_GetEventState(event.type) == SDL_ENABLE) { - event.jdevice.which = device_index; - if ((SDL_EventOK == NULL) - || (*SDL_EventOK) (SDL_EventOKParam, &event)) { - SDL_PushEvent(&event); - } - } + SDL_Event event; + event.type = SDL_JOYDEVICEADDED; + + if (SDL_GetEventState(event.type) == SDL_ENABLE) { + event.jdevice.which = device_index; + if ((SDL_EventOK == NULL) + || (*SDL_EventOK) (SDL_EventOKParam, &event)) { + SDL_PushEvent(&event); + } + } #endif /* !SDL_EVENTS_DISABLED */ - pNewJoystick->send_add_event = 0; - } - device_index++; - pNewJoystick = pNewJoystick->pNext; - } - } + pNewJoystick->send_add_event = 0; + } + device_index++; + pNewJoystick = pNewJoystick->pNext; + } + } } /* we need to poll if we have pending hotplug device changes or connected devices */ SDL_bool SDL_SYS_JoystickNeedsPolling() { - /* we have a new device or one was pulled, we need to think this frame please */ - if ( s_bDeviceAdded || s_bDeviceRemoved ) - return SDL_TRUE; + /* we have a new device or one was pulled, we need to think this frame please */ + if ( s_bDeviceAdded || s_bDeviceRemoved ) + return SDL_TRUE; - return SDL_FALSE; + return SDL_FALSE; } /* Function to get the device-dependent name of a joystick */ const char * SDL_SYS_JoystickNameForDeviceIndex(int device_index) { - JoyStick_DeviceData *device = SYS_Joystick; + JoyStick_DeviceData *device = SYS_Joystick; - for (; device_index > 0; device_index--) - device = device->pNext; + for (; device_index > 0; device_index--) + device = device->pNext; - return device->joystickname; + return device->joystickname; } /* Function to perform the mapping between current device instance and this joysticks instance id */ SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index) { - JoyStick_DeviceData *device = SYS_Joystick; - int index; + JoyStick_DeviceData *device = SYS_Joystick; + int index; - for (index = device_index; index > 0; index--) - device = device->pNext; + for (index = device_index; index > 0; index--) + device = device->pNext; - return device->nInstanceID; + return device->nInstanceID; } /* Function to open a joystick for use. @@ -941,17 +941,17 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index) HRESULT result; LPDIRECTINPUTDEVICE8 device; DIPROPDWORD dipdw; - JoyStick_DeviceData *joystickdevice = SYS_Joystick; + JoyStick_DeviceData *joystickdevice = SYS_Joystick; - for (; device_index > 0; device_index--) - joystickdevice = joystickdevice->pNext; + for (; device_index > 0; device_index--) + joystickdevice = joystickdevice->pNext; SDL_memset(&dipdw, 0, sizeof(DIPROPDWORD)); dipdw.diph.dwSize = sizeof(DIPROPDWORD); dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); /* allocate memory for system specific hardware data */ - joystick->instance_id = joystickdevice->nInstanceID; + joystick->instance_id = joystickdevice->nInstanceID; joystick->closed = 0; joystick->hwdata = (struct joystick_hwdata *) SDL_malloc(sizeof(struct joystick_hwdata)); @@ -960,194 +960,194 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index) } SDL_memset(joystick->hwdata, 0, sizeof(struct joystick_hwdata)); joystick->hwdata->buffered = 1; - joystick->hwdata->removed = 0; + joystick->hwdata->removed = 0; joystick->hwdata->Capabilities.dwSize = sizeof(DIDEVCAPS); - joystick->hwdata->guid = joystickdevice->guid; - - if ( joystickdevice->bXInputDevice ) - { - XINPUT_CAPABILITIES capabilities; - Uint8 userId = 0; - DWORD result; - JoyStick_DeviceData *joysticklist = SYS_Joystick; - // scan the opened joysticks and pick the next free xinput userid for this one - for( ; joysticklist; joysticklist = joysticklist->pNext) - { - if ( joysticklist->bXInputDevice && joysticklist->XInputUserId == userId ) - userId++; - } - - if ( s_bXInputEnabled && XINPUTGETCAPABILITIES ) - { - result = XINPUTGETCAPABILITIES( userId, XINPUT_FLAG_GAMEPAD, &capabilities ); - if ( result == ERROR_SUCCESS ) - { + joystick->hwdata->guid = joystickdevice->guid; + + if ( joystickdevice->bXInputDevice ) + { + XINPUT_CAPABILITIES capabilities; + Uint8 userId = 0; + DWORD result; + JoyStick_DeviceData *joysticklist = SYS_Joystick; + /* scan the opened joysticks and pick the next free xinput userid for this one */ + for( ; joysticklist; joysticklist = joysticklist->pNext) + { + if ( joysticklist->bXInputDevice && joysticklist->XInputUserId == userId ) + userId++; + } + + if ( s_bXInputEnabled && XINPUTGETCAPABILITIES ) + { + result = XINPUTGETCAPABILITIES( userId, XINPUT_FLAG_GAMEPAD, &capabilities ); + if ( result == ERROR_SUCCESS ) + { const SDL_bool bIs14OrLater = (SDL_XInputVersion >= ((1<<16)|4)); - SDL_bool bIsSupported = SDL_FALSE; - // Current version of XInput mistakenly returns 0 as the Type. Ignore it and ensure the subtype is a gamepad. - bIsSupported = ( capabilities.SubType == XINPUT_DEVSUBTYPE_GAMEPAD ); - - if ( !bIsSupported ) - { - joystickdevice->bXInputDevice = SDL_FALSE; - } - else - { - // valid - joystick->hwdata->bXInputDevice = SDL_TRUE; + SDL_bool bIsSupported = SDL_FALSE; + /* Current version of XInput mistakenly returns 0 as the Type. Ignore it and ensure the subtype is a gamepad. */ + bIsSupported = ( capabilities.SubType == XINPUT_DEVSUBTYPE_GAMEPAD ); + + if ( !bIsSupported ) + { + joystickdevice->bXInputDevice = SDL_FALSE; + } + else + { + /* valid */ + joystick->hwdata->bXInputDevice = SDL_TRUE; if ((!bIs14OrLater) || (capabilities.Flags & XINPUT_CAPS_FFB_SUPPORTED)) { - joystick->hwdata->bXInputHaptic = SDL_TRUE; + joystick->hwdata->bXInputHaptic = SDL_TRUE; } - SDL_memset( joystick->hwdata->XInputState, 0x0, sizeof(joystick->hwdata->XInputState) ); - joystickdevice->XInputUserId = userId; - joystick->hwdata->userid = userId; - joystick->hwdata->currentXInputSlot = 0; - // The XInput API has a hard coded button/axis mapping, so we just match it - joystick->naxes = 6; - joystick->nbuttons = 15; - joystick->nballs = 0; - joystick->nhats = 0; - } - } - else - { - joystickdevice->bXInputDevice = SDL_FALSE; - } - } - else - { - joystickdevice->bXInputDevice = SDL_FALSE; - } - } - - if ( joystickdevice->bXInputDevice == SDL_FALSE ) - { - joystick->hwdata->bXInputDevice = SDL_FALSE; - - result = - IDirectInput8_CreateDevice(dinput, - &(joystickdevice->dxdevice.guidInstance), &device, NULL); - if (FAILED(result)) { - return SetDIerror("IDirectInput::CreateDevice", result); - } - - /* Now get the IDirectInputDevice8 interface, instead. */ - result = IDirectInputDevice8_QueryInterface(device, - &IID_IDirectInputDevice8, - (LPVOID *) & joystick-> - hwdata->InputDevice); - /* We are done with this object. Use the stored one from now on. */ - IDirectInputDevice8_Release(device); - - if (FAILED(result)) { - return SetDIerror("IDirectInputDevice8::QueryInterface", result); - } - - /* Acquire shared access. Exclusive access is required for forces, - * though. */ - result = - IDirectInputDevice8_SetCooperativeLevel(joystick->hwdata-> - InputDevice, SDL_HelperWindow, - DISCL_NONEXCLUSIVE | - DISCL_BACKGROUND); - if (FAILED(result)) { - return SetDIerror("IDirectInputDevice8::SetCooperativeLevel", result); - } - - /* Use the extended data structure: DIJOYSTATE2. */ - result = - IDirectInputDevice8_SetDataFormat(joystick->hwdata->InputDevice, - &c_dfDIJoystick2); - if (FAILED(result)) { - return SetDIerror("IDirectInputDevice8::SetDataFormat", result); - } - - /* Get device capabilities */ - result = - IDirectInputDevice8_GetCapabilities(joystick->hwdata->InputDevice, - &joystick->hwdata->Capabilities); - - if (FAILED(result)) { - return SetDIerror("IDirectInputDevice8::GetCapabilities", result); - } - - /* Force capable? */ - if (joystick->hwdata->Capabilities.dwFlags & DIDC_FORCEFEEDBACK) { - - result = IDirectInputDevice8_Acquire(joystick->hwdata->InputDevice); - - if (FAILED(result)) { - return SetDIerror("IDirectInputDevice8::Acquire", result); - } - - /* reset all accuators. */ - result = - IDirectInputDevice8_SendForceFeedbackCommand(joystick->hwdata-> - InputDevice, - DISFFC_RESET); - - /* Not necessarily supported, ignore if not supported. - if (FAILED(result)) { - return SetDIerror("IDirectInputDevice8::SendForceFeedbackCommand", result); - } - */ - - result = IDirectInputDevice8_Unacquire(joystick->hwdata->InputDevice); - - if (FAILED(result)) { - return SetDIerror("IDirectInputDevice8::Unacquire", result); - } - - /* Turn on auto-centering for a ForceFeedback device (until told - * otherwise). */ - dipdw.diph.dwObj = 0; - dipdw.diph.dwHow = DIPH_DEVICE; - dipdw.dwData = DIPROPAUTOCENTER_ON; - - result = - IDirectInputDevice8_SetProperty(joystick->hwdata->InputDevice, - DIPROP_AUTOCENTER, &dipdw.diph); - - /* Not necessarily supported, ignore if not supported. - if (FAILED(result)) { - return SetDIerror("IDirectInputDevice8::SetProperty", result); - } - */ - } - - /* What buttons and axes does it have? */ - IDirectInputDevice8_EnumObjects(joystick->hwdata->InputDevice, - EnumDevObjectsCallback, joystick, - DIDFT_BUTTON | DIDFT_AXIS | DIDFT_POV); - - /* Reorder the input objects. Some devices do not report the X axis as - * the first axis, for example. */ - SortDevObjects(joystick); - - dipdw.diph.dwObj = 0; - dipdw.diph.dwHow = DIPH_DEVICE; - dipdw.dwData = INPUT_QSIZE; - - /* Set the buffer size */ - result = - IDirectInputDevice8_SetProperty(joystick->hwdata->InputDevice, - DIPROP_BUFFERSIZE, &dipdw.diph); - - if (result == DI_POLLEDDEVICE) { - /* This device doesn't support buffering, so we're forced - * to use less reliable polling. */ - joystick->hwdata->buffered = 0; - } else if (FAILED(result)) { - return SetDIerror("IDirectInputDevice8::SetProperty", result); - } - } + SDL_memset( joystick->hwdata->XInputState, 0x0, sizeof(joystick->hwdata->XInputState) ); + joystickdevice->XInputUserId = userId; + joystick->hwdata->userid = userId; + joystick->hwdata->currentXInputSlot = 0; + /* The XInput API has a hard coded button/axis mapping, so we just match it */ + joystick->naxes = 6; + joystick->nbuttons = 15; + joystick->nballs = 0; + joystick->nhats = 0; + } + } + else + { + joystickdevice->bXInputDevice = SDL_FALSE; + } + } + else + { + joystickdevice->bXInputDevice = SDL_FALSE; + } + } + + if ( joystickdevice->bXInputDevice == SDL_FALSE ) + { + joystick->hwdata->bXInputDevice = SDL_FALSE; + + result = + IDirectInput8_CreateDevice(dinput, + &(joystickdevice->dxdevice.guidInstance), &device, NULL); + if (FAILED(result)) { + return SetDIerror("IDirectInput::CreateDevice", result); + } + + /* Now get the IDirectInputDevice8 interface, instead. */ + result = IDirectInputDevice8_QueryInterface(device, + &IID_IDirectInputDevice8, + (LPVOID *) & joystick-> + hwdata->InputDevice); + /* We are done with this object. Use the stored one from now on. */ + IDirectInputDevice8_Release(device); + + if (FAILED(result)) { + return SetDIerror("IDirectInputDevice8::QueryInterface", result); + } + + /* Acquire shared access. Exclusive access is required for forces, + * though. */ + result = + IDirectInputDevice8_SetCooperativeLevel(joystick->hwdata-> + InputDevice, SDL_HelperWindow, + DISCL_NONEXCLUSIVE | + DISCL_BACKGROUND); + if (FAILED(result)) { + return SetDIerror("IDirectInputDevice8::SetCooperativeLevel", result); + } + + /* Use the extended data structure: DIJOYSTATE2. */ + result = + IDirectInputDevice8_SetDataFormat(joystick->hwdata->InputDevice, + &c_dfDIJoystick2); + if (FAILED(result)) { + return SetDIerror("IDirectInputDevice8::SetDataFormat", result); + } + + /* Get device capabilities */ + result = + IDirectInputDevice8_GetCapabilities(joystick->hwdata->InputDevice, + &joystick->hwdata->Capabilities); + + if (FAILED(result)) { + return SetDIerror("IDirectInputDevice8::GetCapabilities", result); + } + + /* Force capable? */ + if (joystick->hwdata->Capabilities.dwFlags & DIDC_FORCEFEEDBACK) { + + result = IDirectInputDevice8_Acquire(joystick->hwdata->InputDevice); + + if (FAILED(result)) { + return SetDIerror("IDirectInputDevice8::Acquire", result); + } + + /* reset all accuators. */ + result = + IDirectInputDevice8_SendForceFeedbackCommand(joystick->hwdata-> + InputDevice, + DISFFC_RESET); + + /* Not necessarily supported, ignore if not supported. + if (FAILED(result)) { + return SetDIerror("IDirectInputDevice8::SendForceFeedbackCommand", result); + } + */ + + result = IDirectInputDevice8_Unacquire(joystick->hwdata->InputDevice); + + if (FAILED(result)) { + return SetDIerror("IDirectInputDevice8::Unacquire", result); + } + + /* Turn on auto-centering for a ForceFeedback device (until told + * otherwise). */ + dipdw.diph.dwObj = 0; + dipdw.diph.dwHow = DIPH_DEVICE; + dipdw.dwData = DIPROPAUTOCENTER_ON; + + result = + IDirectInputDevice8_SetProperty(joystick->hwdata->InputDevice, + DIPROP_AUTOCENTER, &dipdw.diph); + + /* Not necessarily supported, ignore if not supported. + if (FAILED(result)) { + return SetDIerror("IDirectInputDevice8::SetProperty", result); + } + */ + } + + /* What buttons and axes does it have? */ + IDirectInputDevice8_EnumObjects(joystick->hwdata->InputDevice, + EnumDevObjectsCallback, joystick, + DIDFT_BUTTON | DIDFT_AXIS | DIDFT_POV); + + /* Reorder the input objects. Some devices do not report the X axis as + * the first axis, for example. */ + SortDevObjects(joystick); + + dipdw.diph.dwObj = 0; + dipdw.diph.dwHow = DIPH_DEVICE; + dipdw.dwData = INPUT_QSIZE; + + /* Set the buffer size */ + result = + IDirectInputDevice8_SetProperty(joystick->hwdata->InputDevice, + DIPROP_BUFFERSIZE, &dipdw.diph); + + if (result == DI_POLLEDDEVICE) { + /* This device doesn't support buffering, so we're forced + * to use less reliable polling. */ + joystick->hwdata->buffered = 0; + } else if (FAILED(result)) { + return SetDIerror("IDirectInputDevice8::SetProperty", result); + } + } return (0); } /* return true if this joystick is plugged in right now */ SDL_bool SDL_SYS_JoystickAttached( SDL_Joystick * joystick ) { - return joystick->closed == 0 && joystick->hwdata->removed == 0; + return joystick->closed == 0 && joystick->hwdata->removed == 0; } @@ -1156,48 +1156,48 @@ SDL_bool SDL_SYS_JoystickAttached( SDL_Joystick * joystick ) static int SortDevFunc(const void *a, const void *b) { - const input_t *inputA = (const input_t*)a; - const input_t *inputB = (const input_t*)b; - - if (inputA->ofs < inputB->ofs) - return -1; - if (inputA->ofs > inputB->ofs) - return 1; - return 0; + const input_t *inputA = (const input_t*)a; + const input_t *inputB = (const input_t*)b; + + if (inputA->ofs < inputB->ofs) + return -1; + if (inputA->ofs > inputB->ofs) + return 1; + return 0; } /* Sort the input objects and recalculate the indices for each input. */ static void SortDevObjects(SDL_Joystick *joystick) { - input_t *inputs = joystick->hwdata->Inputs; - int nButtons = 0; - int nHats = 0; - int nAxis = 0; - int n; - - SDL_qsort(inputs, joystick->hwdata->NumInputs, sizeof(input_t), SortDevFunc); - - for (n = 0; n < joystick->hwdata->NumInputs; n++) - { - switch (inputs[n].type) - { - case BUTTON: - inputs[n].num = nButtons; - nButtons++; - break; - - case HAT: - inputs[n].num = nHats; - nHats++; - break; - - case AXIS: - inputs[n].num = nAxis; - nAxis++; - break; - } - } + input_t *inputs = joystick->hwdata->Inputs; + int nButtons = 0; + int nHats = 0; + int nAxis = 0; + int n; + + SDL_qsort(inputs, joystick->hwdata->NumInputs, sizeof(input_t), SortDevFunc); + + for (n = 0; n < joystick->hwdata->NumInputs; n++) + { + switch (inputs[n].type) + { + case BUTTON: + inputs[n].num = nButtons; + nButtons++; + break; + + case HAT: + inputs[n].num = nHats; + nHats++; + break; + + case AXIS: + inputs[n].num = nAxis; + nAxis++; + break; + } + } } static BOOL CALLBACK @@ -1210,12 +1210,12 @@ EnumDevObjectsCallback(LPCDIDEVICEOBJECTINSTANCE dev, LPVOID pvRef) if (dev->dwType & DIDFT_BUTTON) { in->type = BUTTON; in->num = joystick->nbuttons; - in->ofs = DIJOFS_BUTTON( in->num ); + in->ofs = DIJOFS_BUTTON( in->num ); joystick->nbuttons++; } else if (dev->dwType & DIDFT_POV) { in->type = HAT; in->num = joystick->nhats; - in->ofs = DIJOFS_POV( in->num ); + in->ofs = DIJOFS_POV( in->num ); joystick->nhats++; } else if (dev->dwType & DIDFT_AXIS) { DIPROPRANGE diprg; @@ -1223,28 +1223,28 @@ EnumDevObjectsCallback(LPCDIDEVICEOBJECTINSTANCE dev, LPVOID pvRef) in->type = AXIS; in->num = joystick->naxes; - // work our the axis this guy maps too, thanks for the code icculus! - if ( !SDL_memcmp( &dev->guidType, &GUID_XAxis, sizeof(dev->guidType) ) ) - in->ofs = DIJOFS_X; - else if ( !SDL_memcmp( &dev->guidType, &GUID_YAxis, sizeof(dev->guidType) ) ) - in->ofs = DIJOFS_Y; - else if ( !SDL_memcmp( &dev->guidType, &GUID_ZAxis, sizeof(dev->guidType) ) ) - in->ofs = DIJOFS_Z; - else if ( !SDL_memcmp( &dev->guidType, &GUID_RxAxis, sizeof(dev->guidType) ) ) - in->ofs = DIJOFS_RX; - else if ( !SDL_memcmp( &dev->guidType, &GUID_RyAxis, sizeof(dev->guidType) ) ) - in->ofs = DIJOFS_RY; - else if ( !SDL_memcmp( &dev->guidType, &GUID_RzAxis, sizeof(dev->guidType) ) ) - in->ofs = DIJOFS_RZ; - else if ( !SDL_memcmp( &dev->guidType, &GUID_Slider, sizeof(dev->guidType) ) ) - { - in->ofs = DIJOFS_SLIDER( joystick->hwdata->NumSliders ); - ++joystick->hwdata->NumSliders; - } - else - { - return DIENUM_CONTINUE; // not an axis we can grok - } + /* work our the axis this guy maps too, thanks for the code icculus! */ + if ( !SDL_memcmp( &dev->guidType, &GUID_XAxis, sizeof(dev->guidType) ) ) + in->ofs = DIJOFS_X; + else if ( !SDL_memcmp( &dev->guidType, &GUID_YAxis, sizeof(dev->guidType) ) ) + in->ofs = DIJOFS_Y; + else if ( !SDL_memcmp( &dev->guidType, &GUID_ZAxis, sizeof(dev->guidType) ) ) + in->ofs = DIJOFS_Z; + else if ( !SDL_memcmp( &dev->guidType, &GUID_RxAxis, sizeof(dev->guidType) ) ) + in->ofs = DIJOFS_RX; + else if ( !SDL_memcmp( &dev->guidType, &GUID_RyAxis, sizeof(dev->guidType) ) ) + in->ofs = DIJOFS_RY; + else if ( !SDL_memcmp( &dev->guidType, &GUID_RzAxis, sizeof(dev->guidType) ) ) + in->ofs = DIJOFS_RZ; + else if ( !SDL_memcmp( &dev->guidType, &GUID_Slider, sizeof(dev->guidType) ) ) + { + in->ofs = DIJOFS_SLIDER( joystick->hwdata->NumSliders ); + ++joystick->hwdata->NumSliders; + } + else + { + return DIENUM_CONTINUE; /* not an axis we can grok */ + } diprg.diph.dwSize = sizeof(diprg); diprg.diph.dwHeaderSize = sizeof(diprg.diph); @@ -1310,12 +1310,12 @@ SDL_SYS_JoystickUpdate_Polled(SDL_Joystick * joystick) sizeof(DIJOYSTATE2), &state); } - if ( result != DI_OK ) - { - joystick->hwdata->send_remove_event = 1; - joystick->hwdata->removed = 1; - return; - } + if ( result != DI_OK ) + { + joystick->hwdata->send_remove_event = 1; + joystick->hwdata->removed = 1; + return; + } /* Set each known axis, button and POV. */ for (i = 0; i < joystick->hwdata->NumInputs; ++i) { @@ -1402,11 +1402,11 @@ SDL_SYS_JoystickUpdate_Buffered(SDL_Joystick * joystick) /* Handle the events or punt */ if (FAILED(result)) - { - joystick->hwdata->send_remove_event = 1; - joystick->hwdata->removed = 1; + { + joystick->hwdata->send_remove_event = 1; + joystick->hwdata->removed = 1; return; - } + } for (i = 0; i < (int) numevents; ++i) { int j; @@ -1443,7 +1443,7 @@ SDL_SYS_JoystickUpdate_Buffered(SDL_Joystick * joystick) */ int ButtonChanged( int ButtonsNow, int ButtonsPrev, int ButtonMask ) { - return ( ButtonsNow & ButtonMask ) != ( ButtonsPrev & ButtonMask ); + return ( ButtonsNow & ButtonMask ) != ( ButtonsPrev & ButtonMask ); } /* Function to update the state of a XInput style joystick. @@ -1451,67 +1451,67 @@ int ButtonChanged( int ButtonsNow, int ButtonsPrev, int ButtonMask ) void SDL_SYS_JoystickUpdate_XInput(SDL_Joystick * joystick) { - HRESULT result; - - if ( !XINPUTGETSTATE ) - return; - - result = XINPUTGETSTATE( joystick->hwdata->userid, &joystick->hwdata->XInputState[joystick->hwdata->currentXInputSlot] ); - if ( result == ERROR_DEVICE_NOT_CONNECTED ) - { - joystick->hwdata->send_remove_event = 1; - joystick->hwdata->removed = 1; - return; - } - - // only fire events if the data changed from last time - if ( joystick->hwdata->XInputState[joystick->hwdata->currentXInputSlot].dwPacketNumber != 0 - && joystick->hwdata->XInputState[joystick->hwdata->currentXInputSlot].dwPacketNumber != joystick->hwdata->XInputState[joystick->hwdata->currentXInputSlot^1].dwPacketNumber ) - { - XINPUT_STATE_EX *pXInputState = &joystick->hwdata->XInputState[joystick->hwdata->currentXInputSlot]; - XINPUT_STATE_EX *pXInputStatePrev = &joystick->hwdata->XInputState[joystick->hwdata->currentXInputSlot ^ 1]; - - SDL_PrivateJoystickAxis(joystick, 0, (Sint16)pXInputState->Gamepad.sThumbLX ); - SDL_PrivateJoystickAxis(joystick, 1, (Sint16)(-1*pXInputState->Gamepad.sThumbLY-1) ); - SDL_PrivateJoystickAxis(joystick, 2, (Sint16)pXInputState->Gamepad.sThumbRX ); - SDL_PrivateJoystickAxis(joystick, 3, (Sint16)(-1*pXInputState->Gamepad.sThumbRY-1) ); - SDL_PrivateJoystickAxis(joystick, 4, (Sint16)((int)pXInputState->Gamepad.bLeftTrigger*32767/255) ); - SDL_PrivateJoystickAxis(joystick, 5, (Sint16)((int)pXInputState->Gamepad.bRightTrigger*32767/255) ); - - if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_DPAD_UP ) ) - SDL_PrivateJoystickButton(joystick, 0, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP ? SDL_PRESSED : SDL_RELEASED ); - if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_DPAD_DOWN ) ) - SDL_PrivateJoystickButton(joystick, 1, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN ? SDL_PRESSED : SDL_RELEASED ); - if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_DPAD_LEFT ) ) - SDL_PrivateJoystickButton(joystick, 2, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT ? SDL_PRESSED : SDL_RELEASED ); - if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_DPAD_RIGHT ) ) - SDL_PrivateJoystickButton(joystick, 3, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT ? SDL_PRESSED : SDL_RELEASED ); - if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_START ) ) - SDL_PrivateJoystickButton(joystick, 4, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_START ? SDL_PRESSED : SDL_RELEASED ); - if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_BACK ) ) - SDL_PrivateJoystickButton(joystick, 5, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_BACK ? SDL_PRESSED : SDL_RELEASED ); - if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_LEFT_THUMB ) ) - SDL_PrivateJoystickButton(joystick, 6, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB ? SDL_PRESSED : SDL_RELEASED ); - if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_RIGHT_THUMB ) ) - SDL_PrivateJoystickButton(joystick, 7, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB ? SDL_PRESSED : SDL_RELEASED ); - if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_LEFT_SHOULDER ) ) - SDL_PrivateJoystickButton(joystick, 8, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER ? SDL_PRESSED : SDL_RELEASED ); - if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_RIGHT_SHOULDER ) ) - SDL_PrivateJoystickButton(joystick, 9, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER ? SDL_PRESSED : SDL_RELEASED ); - if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_A ) ) - SDL_PrivateJoystickButton(joystick, 10, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_A ? SDL_PRESSED : SDL_RELEASED ); - if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_B ) ) - SDL_PrivateJoystickButton(joystick, 11, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_B ? SDL_PRESSED : SDL_RELEASED ); - if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_X ) ) - SDL_PrivateJoystickButton(joystick, 12, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_X ? SDL_PRESSED : SDL_RELEASED ); - if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_Y ) ) - SDL_PrivateJoystickButton(joystick, 13, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_Y ? SDL_PRESSED : SDL_RELEASED ); - if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, 0x400 ) ) - SDL_PrivateJoystickButton(joystick, 14, pXInputState->Gamepad.wButtons & 0x400 ? SDL_PRESSED : SDL_RELEASED ); // 0x400 is the undocumented code for the guide button - - joystick->hwdata->currentXInputSlot ^= 1; - - } + HRESULT result; + + if ( !XINPUTGETSTATE ) + return; + + result = XINPUTGETSTATE( joystick->hwdata->userid, &joystick->hwdata->XInputState[joystick->hwdata->currentXInputSlot] ); + if ( result == ERROR_DEVICE_NOT_CONNECTED ) + { + joystick->hwdata->send_remove_event = 1; + joystick->hwdata->removed = 1; + return; + } + + /* only fire events if the data changed from last time */ + if ( joystick->hwdata->XInputState[joystick->hwdata->currentXInputSlot].dwPacketNumber != 0 + && joystick->hwdata->XInputState[joystick->hwdata->currentXInputSlot].dwPacketNumber != joystick->hwdata->XInputState[joystick->hwdata->currentXInputSlot^1].dwPacketNumber ) + { + XINPUT_STATE_EX *pXInputState = &joystick->hwdata->XInputState[joystick->hwdata->currentXInputSlot]; + XINPUT_STATE_EX *pXInputStatePrev = &joystick->hwdata->XInputState[joystick->hwdata->currentXInputSlot ^ 1]; + + SDL_PrivateJoystickAxis(joystick, 0, (Sint16)pXInputState->Gamepad.sThumbLX ); + SDL_PrivateJoystickAxis(joystick, 1, (Sint16)(-1*pXInputState->Gamepad.sThumbLY-1) ); + SDL_PrivateJoystickAxis(joystick, 2, (Sint16)pXInputState->Gamepad.sThumbRX ); + SDL_PrivateJoystickAxis(joystick, 3, (Sint16)(-1*pXInputState->Gamepad.sThumbRY-1) ); + SDL_PrivateJoystickAxis(joystick, 4, (Sint16)((int)pXInputState->Gamepad.bLeftTrigger*32767/255) ); + SDL_PrivateJoystickAxis(joystick, 5, (Sint16)((int)pXInputState->Gamepad.bRightTrigger*32767/255) ); + + if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_DPAD_UP ) ) + SDL_PrivateJoystickButton(joystick, 0, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP ? SDL_PRESSED : SDL_RELEASED ); + if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_DPAD_DOWN ) ) + SDL_PrivateJoystickButton(joystick, 1, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN ? SDL_PRESSED : SDL_RELEASED ); + if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_DPAD_LEFT ) ) + SDL_PrivateJoystickButton(joystick, 2, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT ? SDL_PRESSED : SDL_RELEASED ); + if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_DPAD_RIGHT ) ) + SDL_PrivateJoystickButton(joystick, 3, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT ? SDL_PRESSED : SDL_RELEASED ); + if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_START ) ) + SDL_PrivateJoystickButton(joystick, 4, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_START ? SDL_PRESSED : SDL_RELEASED ); + if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_BACK ) ) + SDL_PrivateJoystickButton(joystick, 5, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_BACK ? SDL_PRESSED : SDL_RELEASED ); + if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_LEFT_THUMB ) ) + SDL_PrivateJoystickButton(joystick, 6, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB ? SDL_PRESSED : SDL_RELEASED ); + if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_RIGHT_THUMB ) ) + SDL_PrivateJoystickButton(joystick, 7, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB ? SDL_PRESSED : SDL_RELEASED ); + if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_LEFT_SHOULDER ) ) + SDL_PrivateJoystickButton(joystick, 8, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER ? SDL_PRESSED : SDL_RELEASED ); + if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_RIGHT_SHOULDER ) ) + SDL_PrivateJoystickButton(joystick, 9, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER ? SDL_PRESSED : SDL_RELEASED ); + if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_A ) ) + SDL_PrivateJoystickButton(joystick, 10, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_A ? SDL_PRESSED : SDL_RELEASED ); + if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_B ) ) + SDL_PrivateJoystickButton(joystick, 11, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_B ? SDL_PRESSED : SDL_RELEASED ); + if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_X ) ) + SDL_PrivateJoystickButton(joystick, 12, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_X ? SDL_PRESSED : SDL_RELEASED ); + if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, XINPUT_GAMEPAD_Y ) ) + SDL_PrivateJoystickButton(joystick, 13, pXInputState->Gamepad.wButtons & XINPUT_GAMEPAD_Y ? SDL_PRESSED : SDL_RELEASED ); + if ( ButtonChanged( pXInputState->Gamepad.wButtons, pXInputStatePrev->Gamepad.wButtons, 0x400 ) ) + SDL_PrivateJoystickButton(joystick, 14, pXInputState->Gamepad.wButtons & 0x400 ? SDL_PRESSED : SDL_RELEASED ); /* 0x400 is the undocumented code for the guide button */ + + joystick->hwdata->currentXInputSlot ^= 1; + + } } @@ -1575,94 +1575,94 @@ SDL_SYS_JoystickUpdate(SDL_Joystick * joystick) { HRESULT result; - if ( joystick->closed || !joystick->hwdata ) - return; - - if (joystick->hwdata->bXInputDevice) - { - SDL_SYS_JoystickUpdate_XInput(joystick); - } - else - { - result = IDirectInputDevice8_Poll(joystick->hwdata->InputDevice); - if (result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED) { - IDirectInputDevice8_Acquire(joystick->hwdata->InputDevice); - IDirectInputDevice8_Poll(joystick->hwdata->InputDevice); - } - - if (joystick->hwdata->buffered) - SDL_SYS_JoystickUpdate_Buffered(joystick); - else - SDL_SYS_JoystickUpdate_Polled(joystick); - } - - if ( joystick->hwdata->removed ) - { - joystick->closed = 1; - joystick->uncentered = 1; - } + if ( joystick->closed || !joystick->hwdata ) + return; + + if (joystick->hwdata->bXInputDevice) + { + SDL_SYS_JoystickUpdate_XInput(joystick); + } + else + { + result = IDirectInputDevice8_Poll(joystick->hwdata->InputDevice); + if (result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED) { + IDirectInputDevice8_Acquire(joystick->hwdata->InputDevice); + IDirectInputDevice8_Poll(joystick->hwdata->InputDevice); + } + + if (joystick->hwdata->buffered) + SDL_SYS_JoystickUpdate_Buffered(joystick); + else + SDL_SYS_JoystickUpdate_Polled(joystick); + } + + if ( joystick->hwdata->removed ) + { + joystick->closed = 1; + joystick->uncentered = 1; + } } /* Function to close a joystick after use */ void SDL_SYS_JoystickClose(SDL_Joystick * joystick) { - if ( joystick->hwdata->bXInputDevice ) - { - JoyStick_DeviceData *joysticklist = SYS_Joystick; - // scan the opened joysticks and clear the userid for this instance - for( ; joysticklist; joysticklist = joysticklist->pNext) - { - if ( joysticklist->bXInputDevice && joysticklist->nInstanceID == joystick->instance_id ) - { - joysticklist->XInputUserId = INVALID_XINPUT_USERID; - } - } - - } - else - { - IDirectInputDevice8_Unacquire(joystick->hwdata->InputDevice); - IDirectInputDevice8_Release(joystick->hwdata->InputDevice); - } + if ( joystick->hwdata->bXInputDevice ) + { + JoyStick_DeviceData *joysticklist = SYS_Joystick; + /* scan the opened joysticks and clear the userid for this instance */ + for( ; joysticklist; joysticklist = joysticklist->pNext) + { + if ( joysticklist->bXInputDevice && joysticklist->nInstanceID == joystick->instance_id ) + { + joysticklist->XInputUserId = INVALID_XINPUT_USERID; + } + } + + } + else + { + IDirectInputDevice8_Unacquire(joystick->hwdata->InputDevice); + IDirectInputDevice8_Release(joystick->hwdata->InputDevice); + } if (joystick->hwdata != NULL) { /* free system specific hardware data */ SDL_free(joystick->hwdata); } - joystick->closed = 1; + joystick->closed = 1; } /* Function to perform any system-specific joystick related cleanup */ void SDL_SYS_JoystickQuit(void) { - JoyStick_DeviceData *device = SYS_Joystick; - - while ( device ) - { - JoyStick_DeviceData *device_next = device->pNext; - SDL_free(device->joystickname); - SDL_free(device); - device = device_next; - } - SYS_Joystick = NULL; - - if ( s_threadJoystick ) - { - SDL_LockMutex( s_mutexJoyStickEnum ); - s_bJoystickThreadQuit = SDL_TRUE; - SDL_CondBroadcast( s_condJoystickThread ); // signal the joystick thread to quit - SDL_UnlockMutex( s_mutexJoyStickEnum ); - SDL_WaitThread( s_threadJoystick, NULL ); // wait for it to bugger off - - SDL_DestroyMutex( s_mutexJoyStickEnum ); - SDL_DestroyCond( s_condJoystickThread ); - s_condJoystickThread= NULL; - s_mutexJoyStickEnum = NULL; - s_threadJoystick = NULL; - } + JoyStick_DeviceData *device = SYS_Joystick; + + while ( device ) + { + JoyStick_DeviceData *device_next = device->pNext; + SDL_free(device->joystickname); + SDL_free(device); + device = device_next; + } + SYS_Joystick = NULL; + + if ( s_threadJoystick ) + { + SDL_LockMutex( s_mutexJoyStickEnum ); + s_bJoystickThreadQuit = SDL_TRUE; + SDL_CondBroadcast( s_condJoystickThread ); /* signal the joystick thread to quit */ + SDL_UnlockMutex( s_mutexJoyStickEnum ); + SDL_WaitThread( s_threadJoystick, NULL ); /* wait for it to bugger off */ + + SDL_DestroyMutex( s_mutexJoyStickEnum ); + SDL_DestroyCond( s_condJoystickThread ); + s_condJoystickThread= NULL; + s_mutexJoyStickEnum = NULL; + s_threadJoystick = NULL; + } if (dinput != NULL) { IDirectInput8_Release(dinput); @@ -1674,11 +1674,11 @@ SDL_SYS_JoystickQuit(void) coinitialized = SDL_FALSE; } - if ( s_pKnownJoystickGUIDs ) - { - SDL_free( s_pKnownJoystickGUIDs ); - s_pKnownJoystickGUIDs = NULL; - } + if ( s_pKnownJoystickGUIDs ) + { + SDL_free( s_pKnownJoystickGUIDs ); + s_pKnownJoystickGUIDs = NULL; + } if (s_bXInputEnabled) { WIN_UnloadXInputDLL(); @@ -1689,30 +1689,30 @@ SDL_SYS_JoystickQuit(void) /* return the stable device guid for this device index */ SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index ) { - JoyStick_DeviceData *device = SYS_Joystick; - int index; + JoyStick_DeviceData *device = SYS_Joystick; + int index; - for (index = device_index; index > 0; index--) - device = device->pNext; + for (index = device_index; index > 0; index--) + device = device->pNext; - return device->guid; + return device->guid; } SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick) { - return joystick->hwdata->guid; + return joystick->hwdata->guid; } /* return SDL_TRUE if this device is using XInput */ SDL_bool SDL_SYS_IsXInputDeviceIndex(int device_index) { - JoyStick_DeviceData *device = SYS_Joystick; - int index; + JoyStick_DeviceData *device = SYS_Joystick; + int index; - for (index = device_index; index > 0; index--) - device = device->pNext; + for (index = device_index; index > 0; index--) + device = device->pNext; - return device->bXInputDevice; + return device->bXInputDevice; } #endif /* SDL_JOYSTICK_DINPUT */ diff --git a/src/joystick/windows/SDL_dxjoystick_c.h b/src/joystick/windows/SDL_dxjoystick_c.h index 564a566bb4..01cfca9705 100644 --- a/src/joystick/windows/SDL_dxjoystick_c.h +++ b/src/joystick/windows/SDL_dxjoystick_c.h @@ -23,10 +23,10 @@ #ifndef SDL_JOYSTICK_DINPUT_H /* DirectInput joystick driver; written by Glenn Maynard, based on Andrei de - * A. Formiga's WINMM driver. + * A. Formiga's WINMM driver. * * Hats and sliders are completely untested; the app I'm writing this for mostly - * doesn't use them and I don't own any joysticks with them. + * doesn't use them and I don't own any joysticks with them. * * We don't bother to use event notification here. It doesn't seem to work * with polled devices, and it's fine to call IDirectInputDevice2_GetDeviceData and @@ -57,7 +57,7 @@ typedef struct DWORD dwPaddingReserved; } XINPUT_GAMEPAD_EX; -typedef struct +typedef struct { DWORD dwPacketNumber; XINPUT_GAMEPAD_EX Gamepad; @@ -65,23 +65,23 @@ typedef struct /* Forward decl's for XInput API's we load dynamically and use if available */ typedef DWORD (WINAPI *XInputGetState_t) - ( - DWORD dwUserIndex, // [in] Index of the gamer associated with the device - XINPUT_STATE_EX* pState // [out] Receives the current state - ); + ( + DWORD dwUserIndex, /* [in] Index of the gamer associated with the device */ + XINPUT_STATE_EX* pState /* [out] Receives the current state */ + ); typedef DWORD (WINAPI *XInputSetState_t) - ( - DWORD dwUserIndex, // [in] Index of the gamer associated with the device - XINPUT_VIBRATION* pVibration // [in, out] The vibration information to send to the controller - ); + ( + DWORD dwUserIndex, /* [in] Index of the gamer associated with the device */ + XINPUT_VIBRATION* pVibration /* [in, out] The vibration information to send to the controller */ + ); typedef DWORD (WINAPI *XInputGetCapabilities_t) - ( - DWORD dwUserIndex, // [in] Index of the gamer associated with the device - DWORD dwFlags, // [in] Input flags that identify the device type - XINPUT_CAPABILITIES* pCapabilities // [out] Receives the capabilities - ); + ( + DWORD dwUserIndex, /* [in] Index of the gamer associated with the device */ + DWORD dwFlags, /* [in] Input flags that identify the device type */ + XINPUT_CAPABILITIES* pCapabilities /* [out] Receives the capabilities */ + ); extern int WIN_LoadXInputDLL(void); extern void WIN_UnloadXInputDLL(void); @@ -89,11 +89,11 @@ extern void WIN_UnloadXInputDLL(void); extern XInputGetState_t SDL_XInputGetState; extern XInputSetState_t SDL_XInputSetState; extern XInputGetCapabilities_t SDL_XInputGetCapabilities; -extern DWORD SDL_XInputVersion; // ((major << 16) & 0xFF00) | (minor & 0xFF) +extern DWORD SDL_XInputVersion; /* ((major << 16) & 0xFF00) | (minor & 0xFF) */ -#define XINPUTGETSTATE SDL_XInputGetState -#define XINPUTSETSTATE SDL_XInputSetState -#define XINPUTGETCAPABILITIES SDL_XInputGetCapabilities +#define XINPUTGETSTATE SDL_XInputGetState +#define XINPUTSETSTATE SDL_XInputSetState +#define XINPUTGETCAPABILITIES SDL_XInputGetCapabilities #define INVALID_XINPUT_USERID 255 #define SDL_XINPUT_MAX_DEVICES 4 @@ -102,7 +102,7 @@ extern DWORD SDL_XInputVersion; // ((major << 16) & 0xFF00) | (minor & 0xFF) #endif -#define MAX_INPUTS 256 /* each joystick can have up to 256 inputs */ +#define MAX_INPUTS 256 /* each joystick can have up to 256 inputs */ /* local types */ @@ -127,18 +127,18 @@ struct joystick_hwdata LPDIRECTINPUTDEVICE8 InputDevice; DIDEVCAPS Capabilities; int buffered; - SDL_JoystickGUID guid; + SDL_JoystickGUID guid; input_t Inputs[MAX_INPUTS]; int NumInputs; - int NumSliders; - Uint8 removed; - Uint8 send_remove_event; - Uint8 bXInputDevice; // 1 if this device supports using the xinput API rather than DirectInput - Uint8 bXInputHaptic; // Supports force feedback via XInput. - Uint8 userid; // XInput userid index for this joystick - Uint8 currentXInputSlot; // the current position to write to in XInputState below, used so we can compare old and new values - XINPUT_STATE_EX XInputState[2]; + int NumSliders; + Uint8 removed; + Uint8 send_remove_event; + Uint8 bXInputDevice; /* 1 if this device supports using the xinput API rather than DirectInput */ + Uint8 bXInputHaptic; /* Supports force feedback via XInput. */ + Uint8 userid; /* XInput userid index for this joystick */ + Uint8 currentXInputSlot; /* the current position to write to in XInputState below, used so we can compare old and new values */ + XINPUT_STATE_EX XInputState[2]; }; #endif /* SDL_JOYSTICK_DINPUT_H */ diff --git a/src/joystick/windows/SDL_mmjoystick.c b/src/joystick/windows/SDL_mmjoystick.c index 73ad7fb955..413053f14d 100644 --- a/src/joystick/windows/SDL_mmjoystick.c +++ b/src/joystick/windows/SDL_mmjoystick.c @@ -33,14 +33,14 @@ #include "../SDL_sysjoystick.h" #include "../SDL_joystick_c.h" -#define MAX_JOYSTICKS 16 -#define MAX_AXES 6 /* each joystick can have up to 6 axes */ -#define MAX_BUTTONS 32 /* and 32 buttons */ -#define AXIS_MIN -32768 /* minimum value for axis coordinate */ -#define AXIS_MAX 32767 /* maximum value for axis coordinate */ +#define MAX_JOYSTICKS 16 +#define MAX_AXES 6 /* each joystick can have up to 6 axes */ +#define MAX_BUTTONS 32 /* and 32 buttons */ +#define AXIS_MIN -32768 /* minimum value for axis coordinate */ +#define AXIS_MAX 32767 /* maximum value for axis coordinate */ /* limit axis to 256 possible positions to filter out noise */ #define JOY_AXIS_THRESHOLD (((AXIS_MAX)-(AXIS_MIN))/256) -#define JOY_BUTTON_FLAG(n) (1<<n) +#define JOY_BUTTON_FLAG(n) (1<<n) /* array to hold joystick ID values */ @@ -407,7 +407,7 @@ SDL_SYS_JoystickQuit(void) SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index ) { SDL_JoystickGUID guid; - // the GUID is just the first 16 chars of the name for now + /* the GUID is just the first 16 chars of the name for now */ const char *name = SDL_SYS_JoystickNameForDeviceIndex( device_index ); SDL_zero( guid ); SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) ); @@ -417,7 +417,7 @@ SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index ) SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick) { SDL_JoystickGUID guid; - // the GUID is just the first 16 chars of the name for now + /* the GUID is just the first 16 chars of the name for now */ const char *name = joystick->name; SDL_zero( guid ); SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) ); |