src/joystick/windows/SDL_dxjoystick.c
changeset 6990 2514368c2aaf
parent 6977 b73d51026c68
child 6991 ff49588e3ddb
     1.1 --- a/src/joystick/windows/SDL_dxjoystick.c	Sun Mar 10 09:09:31 2013 -0700
     1.2 +++ b/src/joystick/windows/SDL_dxjoystick.c	Sun Mar 10 13:05:47 2013 -0400
     1.3 @@ -73,7 +73,6 @@
     1.4  static SDL_mutex *s_mutexJoyStickEnum = NULL;
     1.5  static SDL_Thread *s_threadJoystick = NULL;
     1.6  static SDL_bool s_bJoystickThreadQuit = SDL_FALSE;
     1.7 -static HANDLE s_pXInputDLL = 0;
     1.8  static SDL_bool s_bXInputEnabled = SDL_TRUE;
     1.9  
    1.10  extern HRESULT(WINAPI * DInputCreate) (HINSTANCE hinst, DWORD dwVersion,
    1.11 @@ -91,36 +90,6 @@
    1.12  	struct JoyStick_DeviceData_ *pNext;
    1.13  };
    1.14  
    1.15 -
    1.16 -/* Forward decl's for XInput API's we load dynamically and use if available */
    1.17 -typedef DWORD (WINAPI *XInputGetState_t)
    1.18 -	(
    1.19 -	DWORD         dwUserIndex,  // [in] Index of the gamer associated with the device
    1.20 -	XINPUT_STATE_EX* pState        // [out] Receives the current state
    1.21 -	);
    1.22 -
    1.23 -typedef DWORD (WINAPI *XInputSetState_t)
    1.24 -	(
    1.25 -	DWORD             dwUserIndex,  // [in] Index of the gamer associated with the device
    1.26 -	XINPUT_VIBRATION* pVibration    // [in, out] The vibration information to send to the controller
    1.27 -	);
    1.28 -
    1.29 -typedef DWORD (WINAPI *XInputGetCapabilities_t)
    1.30 -	(
    1.31 -	DWORD                dwUserIndex,   // [in] Index of the gamer associated with the device
    1.32 -	DWORD                dwFlags,       // [in] Input flags that identify the device type
    1.33 -	XINPUT_CAPABILITIES* pCapabilities  // [out] Receives the capabilities
    1.34 -	);
    1.35 -
    1.36 -XInputGetState_t PC_XInputGetState;
    1.37 -XInputSetState_t PC_XInputSetState;
    1.38 -XInputGetCapabilities_t PC_XInputGetCapabilities;
    1.39 -
    1.40 -#define XINPUTGETSTATE			PC_XInputGetState
    1.41 -#define XINPUTSETSTATE			PC_XInputSetState
    1.42 -#define XINPUTGETCAPABILITIES	PC_XInputGetCapabilities
    1.43 -#define INVALID_XINPUT_USERID 255
    1.44 -
    1.45  typedef struct JoyStick_DeviceData_ JoyStick_DeviceData;
    1.46  
    1.47  static JoyStick_DeviceData *SYS_Joystick;    /* array to hold joystick ID values */
    1.48 @@ -634,7 +603,7 @@
    1.49  {
    1.50      HRESULT result;
    1.51      HINSTANCE instance;
    1.52 -	const char *env = SDL_GetHint(SD_HINT_XINPUT_ENABLED);
    1.53 +	const char *env = SDL_GetHint(SDL_HINT_XINPUT_ENABLED);
    1.54  	if (env && !SDL_atoi(env)) {
    1.55  		s_bXInputEnabled = SDL_FALSE;
    1.56  	}
    1.57 @@ -672,32 +641,15 @@
    1.58          return (-1);
    1.59      }
    1.60  
    1.61 -	s_mutexJoyStickEnum = SDL_CreateMutex();
    1.62 -	s_condJoystickThread = SDL_CreateCond();
    1.63 -	s_bDeviceAdded = SDL_TRUE; // force a scan of the system for joysticks this first time
    1.64 -	SDL_SYS_JoystickDetect();
    1.65 +    s_mutexJoyStickEnum = SDL_CreateMutex();
    1.66 +    s_condJoystickThread = SDL_CreateCond();
    1.67 +    s_bDeviceAdded = SDL_TRUE; // force a scan of the system for joysticks this first time
    1.68 +    SDL_SYS_JoystickDetect();
    1.69  
    1.70 -    if (s_bXInputEnabled) {
    1.71 -		// try to load XInput support if available
    1.72 -		s_pXInputDLL = LoadLibrary( L"XInput1_3.dll" );
    1.73 -		if ( !s_pXInputDLL )
    1.74 -			s_pXInputDLL = LoadLibrary( L"bin\\XInput1_3.dll" );
    1.75 -		if ( s_pXInputDLL )
    1.76 -		{
    1.77 -			// 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...
    1.78 -			PC_XInputGetState = (XInputGetState_t)GetProcAddress( (HMODULE)s_pXInputDLL, (LPCSTR)100 );
    1.79 -			PC_XInputSetState = (XInputSetState_t)GetProcAddress( (HMODULE)s_pXInputDLL, "XInputSetState" );
    1.80 -			PC_XInputGetCapabilities = (XInputGetCapabilities_t)GetProcAddress( (HMODULE)s_pXInputDLL, "XInputGetCapabilities" );
    1.81 -			if ( !PC_XInputGetState || !PC_XInputSetState || !PC_XInputGetCapabilities )
    1.82 -			{
    1.83 -				SDL_SYS_JoystickQuit();
    1.84 -				SDL_SetError("GetProcAddress() failed when loading XInput.", GetLastError());
    1.85 -				return (-1);
    1.86 -			}
    1.87 -		}
    1.88 +    if ((s_bXInputEnabled) && (WIN_LoadXInputDLL() == -1)) {
    1.89 +        s_bXInputEnabled = SDL_FALSE;  /* oh well. */
    1.90      }
    1.91  
    1.92 -
    1.93  	if ( !s_threadJoystick )
    1.94  	{
    1.95  		s_bJoystickThreadQuit = SDL_FALSE;
    1.96 @@ -978,6 +930,7 @@
    1.97  			result = XINPUTGETCAPABILITIES( userId, XINPUT_FLAG_GAMEPAD, &capabilities );
    1.98  			if ( result == ERROR_SUCCESS )
    1.99  			{
   1.100 +                const SDL_bool bIs14OrLater = (SDL_XInputVersion >= ((1<<16)|4));
   1.101  				SDL_bool bIsSupported = SDL_FALSE;
   1.102  				// Current version of XInput mistakenly returns 0 as the Type. Ignore it and ensure the subtype is a gamepad.
   1.103  				bIsSupported = ( capabilities.SubType == XINPUT_DEVSUBTYPE_GAMEPAD );
   1.104 @@ -990,6 +943,9 @@
   1.105  				{
   1.106  					// valid
   1.107  					joystick->hwdata->bXInputDevice = SDL_TRUE;
   1.108 +                    if ((!bIs14OrLater) || (capabilities.Flags & XINPUT_CAPS_FFB_SUPPORTED)) {
   1.109 +					    joystick->hwdata->bXInputHaptic = SDL_TRUE;
   1.110 +                    }
   1.111  					SDL_memset( joystick->hwdata->XInputState, 0x0, sizeof(joystick->hwdata->XInputState) );
   1.112  					joystickdevice->XInputUserId = userId;
   1.113  					joystick->hwdata->userid = userId;
   1.114 @@ -1683,11 +1639,9 @@
   1.115  		s_pKnownJoystickGUIDs = NULL;
   1.116  	}
   1.117  
   1.118 -	if ( s_pXInputDLL )
   1.119 -	{
   1.120 -		FreeLibrary( s_pXInputDLL );
   1.121 -		s_pXInputDLL = NULL;
   1.122 -	}
   1.123 +    if (s_bXInputEnabled) {
   1.124 +        WIN_UnloadXInputDLL();
   1.125 +    }
   1.126  }
   1.127  
   1.128