src/joystick/windows/SDL_dxjoystick.c
changeset 6707 70eeb7e3ec2f
parent 6698 28ab2ef7bfc9
child 6709 3b43d3a9b7d5
     1.1 --- a/src/joystick/windows/SDL_dxjoystick.c	Mon Nov 26 23:58:53 2012 -0800
     1.2 +++ b/src/joystick/windows/SDL_dxjoystick.c	Tue Nov 27 00:58:12 2012 -0800
     1.3 @@ -84,7 +84,7 @@
     1.4  	char *joystickname;
     1.5  	Uint8 send_add_event;
     1.6  	int nInstanceID;
     1.7 -	Uint8 bXInputDevice;
     1.8 +	SDL_bool bXInputDevice;
     1.9  	Uint8 XInputUserId;
    1.10  	struct JoyStick_DeviceData_ *pNext;
    1.11  };
    1.12 @@ -674,18 +674,215 @@
    1.13  	    return SDL_SYS_NumJoysticks();
    1.14  }
    1.15  
    1.16 +/* return the number of joysticks that are connected right now */
    1.17 +int SDL_SYS_NumJoysticks()
    1.18 +{
    1.19 +	int nJoysticks = 0;
    1.20 +	JoyStick_DeviceData *device = SYS_Joystick;
    1.21 +	while ( device )
    1.22 +	{
    1.23 +		nJoysticks++;
    1.24 +		device = device->pNext;
    1.25 +	}
    1.26 +
    1.27 +	return nJoysticks;
    1.28 +}
    1.29 +
    1.30 +static int s_iNewGUID = 0;
    1.31 +
    1.32 +/* helper function for direct input, gets called for each connected joystick */
    1.33 +static BOOL CALLBACK
    1.34 +	EnumJoysticksCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext)
    1.35 +{
    1.36 +	JoyStick_DeviceData *pNewJoystick;
    1.37 +	SDL_bool bXInputDevice;
    1.38 +	pNewJoystick = *(JoyStick_DeviceData **)pContext;
    1.39 +	while ( pNewJoystick )
    1.40 +	{
    1.41 +		if ( !SDL_memcmp( &pNewJoystick->dxdevice.guidInstance, &pdidInstance->guidInstance, sizeof(pNewJoystick->dxdevice.guidInstance) ) )
    1.42 +		{
    1.43 +			if ( SYS_Joystick )
    1.44 +			{
    1.45 +				pNewJoystick->pNext = SYS_Joystick;
    1.46 +			}
    1.47 +			SYS_Joystick = pNewJoystick;
    1.48 +			/* if we are replacing the front of the list then update it */
    1.49 +			if ( pNewJoystick == *(JoyStick_DeviceData **)pContext ) 
    1.50 +			{
    1.51 +				*(JoyStick_DeviceData **)pContext = pNewJoystick->pNext;
    1.52 +			}
    1.53 +
    1.54 +			s_pKnownJoystickGUIDs[ s_iNewGUID ] = pdidInstance->guidInstance;
    1.55 +			s_iNewGUID++;
    1.56 +			if ( s_iNewGUID < MAX_JOYSTICKS )
    1.57 +				return DIENUM_CONTINUE; // already have this joystick loaded, just keep going
    1.58 +			else
    1.59 +				return DIENUM_STOP; 
    1.60 +		}
    1.61 +
    1.62 +		pNewJoystick = pNewJoystick->pNext;
    1.63 +	}
    1.64 +
    1.65 +	s_bDeviceAdded = SDL_TRUE;
    1.66 +
    1.67 +	bXInputDevice = IsXInputDevice( &pdidInstance->guidProduct );
    1.68 +
    1.69 +	pNewJoystick = (JoyStick_DeviceData *)SDL_malloc( sizeof(JoyStick_DeviceData) );
    1.70 +
    1.71 +	if ( bXInputDevice )
    1.72 +	{
    1.73 +		SDL_memset(&(pNewJoystick->dxdevice), 0x0,
    1.74 +			sizeof(DIDEVICEINSTANCE));
    1.75 +		pNewJoystick->bXInputDevice = SDL_TRUE;
    1.76 +		pNewJoystick->XInputUserId = INVALID_XINPUT_USERID;
    1.77 +	}
    1.78 +	else
    1.79 +	{
    1.80 +		pNewJoystick->bXInputDevice = SDL_FALSE;
    1.81 +		SDL_memcpy(&(pNewJoystick->dxdevice), pdidInstance,
    1.82 +			sizeof(DIDEVICEINSTANCE));
    1.83 +	}
    1.84 +	pNewJoystick->joystickname = WIN_StringToUTF8(pdidInstance->tszProductName);
    1.85 +	pNewJoystick->send_add_event = 1;
    1.86 +	pNewJoystick->nInstanceID = ++s_nInstanceID;
    1.87 +	SDL_memcpy( &pNewJoystick->guid, &pdidInstance->guidProduct, sizeof(pNewJoystick->guid) );
    1.88 +	pNewJoystick->pNext = NULL;
    1.89 +
    1.90 +	if ( SYS_Joystick )
    1.91 +	{
    1.92 +		pNewJoystick->pNext = SYS_Joystick;
    1.93 +	}
    1.94 +	SYS_Joystick = pNewJoystick;
    1.95 +
    1.96 +	s_pKnownJoystickGUIDs[ s_iNewGUID ] = pdidInstance->guidInstance;
    1.97 +	s_iNewGUID++;
    1.98 +
    1.99 +	if ( s_iNewGUID < MAX_JOYSTICKS )
   1.100 +		return DIENUM_CONTINUE; // already have this joystick loaded, just keep going
   1.101 +	else
   1.102 +		return DIENUM_STOP; 
   1.103 +}
   1.104 +
   1.105 +/* detect any new joysticks being inserted into the system */
   1.106 +void SDL_SYS_JoystickDetect()
   1.107 +{
   1.108 +	HRESULT result;
   1.109 +	JoyStick_DeviceData *pCurList = NULL;
   1.110 +	/* only enum the devices if the joystick thread told us something changed */
   1.111 +	if ( s_bDeviceAdded || s_bDeviceRemoved )
   1.112 +	{
   1.113 +		s_bDeviceAdded = SDL_FALSE;
   1.114 +		s_bDeviceRemoved = SDL_FALSE;
   1.115 +
   1.116 +		pCurList = SYS_Joystick;
   1.117 +		SYS_Joystick = NULL;
   1.118 +		s_iNewGUID = 0;
   1.119 +		SDL_mutexP( s_mutexJoyStickEnum );
   1.120 +
   1.121 +		if ( !s_pKnownJoystickGUIDs )
   1.122 +			s_pKnownJoystickGUIDs = SDL_malloc( sizeof(GUID)*MAX_JOYSTICKS );
   1.123 +				
   1.124 +		SDL_memset( s_pKnownJoystickGUIDs, 0x0, sizeof(GUID)*MAX_JOYSTICKS );
   1.125 +
   1.126 +		/* Look for joysticks, wheels, head trackers, gamepads, etc.. */
   1.127 +		result = IDirectInput8_EnumDevices(dinput,
   1.128 +			DI8DEVCLASS_GAMECTRL,
   1.129 +			EnumJoysticksCallback,
   1.130 +			&pCurList, DIEDFL_ATTACHEDONLY);
   1.131 +
   1.132 +		SDL_mutexV( s_mutexJoyStickEnum );
   1.133 +	}
   1.134 +
   1.135 +	if ( pCurList )
   1.136 +	{
   1.137 +		while ( pCurList )
   1.138 +		{
   1.139 +			JoyStick_DeviceData *pListNext = NULL;
   1.140 +#if !SDL_EVENTS_DISABLED
   1.141 +			SDL_Event event;
   1.142 +			event.type = SDL_JOYDEVICEREMOVED;
   1.143 +
   1.144 +			if (SDL_GetEventState(event.type) == SDL_ENABLE) {
   1.145 +				event.jdevice.which = pCurList->nInstanceID;
   1.146 +				if ((SDL_EventOK == NULL)
   1.147 +					|| (*SDL_EventOK) (SDL_EventOKParam, &event)) {
   1.148 +						SDL_PushEvent(&event);
   1.149 +				}
   1.150 +			}
   1.151 +#endif // !SDL_EVENTS_DISABLED 
   1.152 +
   1.153 +			pListNext = pCurList->pNext;
   1.154 +			SDL_free(pCurList->joystickname);
   1.155 +			SDL_free( pCurList );
   1.156 +			pCurList = pListNext;
   1.157 +		}
   1.158 +
   1.159 +	}
   1.160 +
   1.161 +	if ( s_bDeviceAdded )
   1.162 +	{
   1.163 +		JoyStick_DeviceData *pNewJoystick;
   1.164 +		int device_index = 0;
   1.165 +		s_bDeviceAdded = SDL_FALSE;
   1.166 +		pNewJoystick = SYS_Joystick;
   1.167 +		while ( pNewJoystick )
   1.168 +		{
   1.169 +			if ( pNewJoystick->send_add_event )
   1.170 +			{
   1.171 +#if !SDL_EVENTS_DISABLED
   1.172 +				SDL_Event event;
   1.173 +				event.type = SDL_JOYDEVICEADDED;
   1.174 +
   1.175 +				if (SDL_GetEventState(event.type) == SDL_ENABLE) {
   1.176 +					event.jdevice.which = device_index;
   1.177 +					if ((SDL_EventOK == NULL)
   1.178 +						|| (*SDL_EventOK) (SDL_EventOKParam, &event)) {
   1.179 +							SDL_PushEvent(&event);
   1.180 +					}
   1.181 +				}
   1.182 +#endif /* !SDL_EVENTS_DISABLED */
   1.183 +				pNewJoystick->send_add_event = 0;
   1.184 +			}
   1.185 +			device_index++;
   1.186 +			pNewJoystick = pNewJoystick->pNext;
   1.187 +		}
   1.188 +	}
   1.189 +}
   1.190 +
   1.191 +/* we need to poll if we have pending hotplug device changes or connected devices */
   1.192 +SDL_bool SDL_SYS_JoystickNeedsPolling()
   1.193 +{
   1.194 +	/* we have a new device or one was pulled, we need to think this frame please */
   1.195 +	if ( s_bDeviceAdded || s_bDeviceRemoved )
   1.196 +		return SDL_TRUE;
   1.197 +
   1.198 +	return SDL_FALSE;
   1.199 +}
   1.200 +
   1.201  /* Function to get the device-dependent name of a joystick */
   1.202  const char *
   1.203 -SDL_SYS_JoystickNameForIndex(int index)
   1.204 +SDL_SYS_JoystickNameForDeviceIndex(int device_index)
   1.205  {
   1.206  	JoyStick_DeviceData *device = SYS_Joystick;
   1.207  
   1.208 -	for (; index > 0; index--)
   1.209 +	for (; device_index > 0; device_index--)
   1.210  		device = device->pNext;
   1.211  
   1.212  	return device->joystickname;
   1.213  }
   1.214  
   1.215 +/* Function to perform the mapping between current device instance and this joysticks instance id */
   1.216 +SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index)
   1.217 +{
   1.218 +	JoyStick_DeviceData *device = SYS_Joystick;
   1.219 +	int index;
   1.220 +
   1.221 +	for (index = device_index; index > 0; index--)
   1.222 +		device = device->pNext;
   1.223 +
   1.224 +	return device->nInstanceID;
   1.225 +}
   1.226 +
   1.227  /* Function to open a joystick for use.
   1.228     The joystick to open is specified by the index field of the joystick.
   1.229     This should fill the nbuttons and naxes fields of the joystick structure.
   1.230 @@ -907,6 +1104,13 @@
   1.231      return (0);
   1.232  }
   1.233  
   1.234 +/* return true if this joystick is plugged in right now */
   1.235 +SDL_bool SDL_SYS_JoystickAttached( SDL_Joystick * joystick )
   1.236 +{
   1.237 +	return joystick->closed == 0 && joystick->hwdata->removed == 0;
   1.238 +}
   1.239 +
   1.240 +
   1.241  /* Sort using the data offset into the DInput struct.
   1.242   * This gives a reasonable ordering for the inputs. */
   1.243  static int
   1.244 @@ -1444,214 +1648,8 @@
   1.245  }
   1.246  
   1.247  
   1.248 -/* Function to perform the mapping between current device instance and this joysticks instance id */
   1.249 -SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index)
   1.250 -{
   1.251 -	JoyStick_DeviceData *device = SYS_Joystick;
   1.252 -	int index;
   1.253 -
   1.254 -	for (index = device_index; index > 0; index--)
   1.255 -		device = device->pNext;
   1.256 -
   1.257 -	return device->nInstanceID;
   1.258 -}
   1.259 -
   1.260 -/* return true if this joystick is plugged in right now */
   1.261 -int SDL_SYS_JoystickAttached( SDL_Joystick * joystick )
   1.262 -{
   1.263 -	return joystick->closed == 0 && joystick->hwdata->removed == 0;
   1.264 -}
   1.265 -
   1.266 -
   1.267 -/* return the number of joysticks that are connected right now */
   1.268 -int SDL_SYS_NumJoysticks()
   1.269 -{
   1.270 -	int nJoysticks = 0;
   1.271 -	JoyStick_DeviceData *device = SYS_Joystick;
   1.272 -	while ( device )
   1.273 -	{
   1.274 -		nJoysticks++;
   1.275 -		device = device->pNext;
   1.276 -	}
   1.277 -
   1.278 -	return nJoysticks;
   1.279 -}
   1.280 -
   1.281 -static int s_iNewGUID = 0;
   1.282 -
   1.283 -/* helper function for direct input, gets called for each connected joystick */
   1.284 -static BOOL CALLBACK
   1.285 -	EnumJoysticksCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext)
   1.286 -{
   1.287 -	JoyStick_DeviceData *pNewJoystick;
   1.288 -	SDL_bool bXInputDevice;
   1.289 -	pNewJoystick = *(JoyStick_DeviceData **)pContext;
   1.290 -	while ( pNewJoystick )
   1.291 -	{
   1.292 -		if ( !SDL_memcmp( &pNewJoystick->dxdevice.guidInstance, &pdidInstance->guidInstance, sizeof(pNewJoystick->dxdevice.guidInstance) ) )
   1.293 -		{
   1.294 -			if ( SYS_Joystick )
   1.295 -			{
   1.296 -				pNewJoystick->pNext = SYS_Joystick;
   1.297 -			}
   1.298 -			SYS_Joystick = pNewJoystick;
   1.299 -			/* if we are replacing the front of the list then update it */
   1.300 -			if ( pNewJoystick == *(JoyStick_DeviceData **)pContext ) 
   1.301 -			{
   1.302 -				*(JoyStick_DeviceData **)pContext = pNewJoystick->pNext;
   1.303 -			}
   1.304 -
   1.305 -			s_pKnownJoystickGUIDs[ s_iNewGUID ] = pdidInstance->guidInstance;
   1.306 -			s_iNewGUID++;
   1.307 -			if ( s_iNewGUID < MAX_JOYSTICKS )
   1.308 -				return DIENUM_CONTINUE; // already have this joystick loaded, just keep going
   1.309 -			else
   1.310 -				return DIENUM_STOP; 
   1.311 -		}
   1.312 -
   1.313 -		pNewJoystick = pNewJoystick->pNext;
   1.314 -	}
   1.315 -
   1.316 -	s_bDeviceAdded = SDL_TRUE;
   1.317 -
   1.318 -	bXInputDevice = IsXInputDevice( &pdidInstance->guidProduct );
   1.319 -
   1.320 -	pNewJoystick = (JoyStick_DeviceData *)SDL_malloc( sizeof(JoyStick_DeviceData) );
   1.321 -
   1.322 -	if ( bXInputDevice )
   1.323 -	{
   1.324 -		SDL_memset(&(pNewJoystick->dxdevice), 0x0,
   1.325 -			sizeof(DIDEVICEINSTANCE));
   1.326 -		pNewJoystick->bXInputDevice = 1;
   1.327 -		pNewJoystick->XInputUserId = INVALID_XINPUT_USERID;
   1.328 -	}
   1.329 -	else
   1.330 -	{
   1.331 -		pNewJoystick->bXInputDevice = 0;
   1.332 -		SDL_memcpy(&(pNewJoystick->dxdevice), pdidInstance,
   1.333 -			sizeof(DIDEVICEINSTANCE));
   1.334 -	}
   1.335 -	pNewJoystick->joystickname = WIN_StringToUTF8(pdidInstance->tszProductName);
   1.336 -	pNewJoystick->send_add_event = 1;
   1.337 -	pNewJoystick->nInstanceID = ++s_nInstanceID;
   1.338 -	SDL_memcpy( &pNewJoystick->guid, &pdidInstance->guidProduct, sizeof(pNewJoystick->guid) );
   1.339 -	pNewJoystick->pNext = NULL;
   1.340 -
   1.341 -	if ( SYS_Joystick )
   1.342 -	{
   1.343 -		pNewJoystick->pNext = SYS_Joystick;
   1.344 -	}
   1.345 -	SYS_Joystick = pNewJoystick;
   1.346 -
   1.347 -	s_pKnownJoystickGUIDs[ s_iNewGUID ] = pdidInstance->guidInstance;
   1.348 -	s_iNewGUID++;
   1.349 -
   1.350 -	if ( s_iNewGUID < MAX_JOYSTICKS )
   1.351 -		return DIENUM_CONTINUE; // already have this joystick loaded, just keep going
   1.352 -	else
   1.353 -		return DIENUM_STOP; 
   1.354 -}
   1.355 -
   1.356 -
   1.357 -/* detect any new joysticks being inserted into the system */
   1.358 -void SDL_SYS_JoystickDetect()
   1.359 -{
   1.360 -	HRESULT result;
   1.361 -	JoyStick_DeviceData *pCurList = NULL;
   1.362 -	/* only enum the devices if the joystick thread told us something changed */
   1.363 -	if ( s_bDeviceAdded || s_bDeviceRemoved )
   1.364 -	{
   1.365 -		s_bDeviceAdded = SDL_FALSE;
   1.366 -		s_bDeviceRemoved = SDL_FALSE;
   1.367 -
   1.368 -		pCurList = SYS_Joystick;
   1.369 -		SYS_Joystick = NULL;
   1.370 -		s_iNewGUID = 0;
   1.371 -		SDL_mutexP( s_mutexJoyStickEnum );
   1.372 -
   1.373 -		if ( !s_pKnownJoystickGUIDs )
   1.374 -			s_pKnownJoystickGUIDs = SDL_malloc( sizeof(GUID)*MAX_JOYSTICKS );
   1.375 -				
   1.376 -		SDL_memset( s_pKnownJoystickGUIDs, 0x0, sizeof(GUID)*MAX_JOYSTICKS );
   1.377 -
   1.378 -		/* Look for joysticks, wheels, head trackers, gamepads, etc.. */
   1.379 -		result = IDirectInput8_EnumDevices(dinput,
   1.380 -			DI8DEVCLASS_GAMECTRL,
   1.381 -			EnumJoysticksCallback,
   1.382 -			&pCurList, DIEDFL_ATTACHEDONLY);
   1.383 -
   1.384 -		SDL_mutexV( s_mutexJoyStickEnum );
   1.385 -	}
   1.386 -
   1.387 -	if ( pCurList )
   1.388 -	{
   1.389 -		while ( pCurList )
   1.390 -		{
   1.391 -			JoyStick_DeviceData *pListNext = NULL;
   1.392 -#if !SDL_EVENTS_DISABLED
   1.393 -			SDL_Event event;
   1.394 -			event.type = SDL_JOYDEVICEREMOVED;
   1.395 -
   1.396 -			if (SDL_GetEventState(event.type) == SDL_ENABLE) {
   1.397 -				event.jdevice.which = pCurList->nInstanceID;
   1.398 -				if ((SDL_EventOK == NULL)
   1.399 -					|| (*SDL_EventOK) (SDL_EventOKParam, &event)) {
   1.400 -						SDL_PushEvent(&event);
   1.401 -				}
   1.402 -			}
   1.403 -#endif // !SDL_EVENTS_DISABLED 
   1.404 -
   1.405 -			pListNext = pCurList->pNext;
   1.406 -			SDL_free(pCurList->joystickname);
   1.407 -			SDL_free( pCurList );
   1.408 -			pCurList = pListNext;
   1.409 -		}
   1.410 -
   1.411 -	}
   1.412 -
   1.413 -	if ( s_bDeviceAdded )
   1.414 -	{
   1.415 -		JoyStick_DeviceData *pNewJoystick;
   1.416 -		int device_index = 0;
   1.417 -		s_bDeviceAdded = SDL_FALSE;
   1.418 -		pNewJoystick = SYS_Joystick;
   1.419 -		while ( pNewJoystick )
   1.420 -		{
   1.421 -			if ( pNewJoystick->send_add_event )
   1.422 -			{
   1.423 -#if !SDL_EVENTS_DISABLED
   1.424 -				SDL_Event event;
   1.425 -				event.type = SDL_JOYDEVICEADDED;
   1.426 -
   1.427 -				if (SDL_GetEventState(event.type) == SDL_ENABLE) {
   1.428 -					event.jdevice.which = device_index;
   1.429 -					if ((SDL_EventOK == NULL)
   1.430 -						|| (*SDL_EventOK) (SDL_EventOKParam, &event)) {
   1.431 -							SDL_PushEvent(&event);
   1.432 -					}
   1.433 -				}
   1.434 -#endif /* !SDL_EVENTS_DISABLED */
   1.435 -				pNewJoystick->send_add_event = 0;
   1.436 -			}
   1.437 -			device_index++;
   1.438 -			pNewJoystick = pNewJoystick->pNext;
   1.439 -		}
   1.440 -	}
   1.441 -}
   1.442 -
   1.443 -
   1.444 -/* we need to poll if we have pending hotplug device changes or connected devices */
   1.445 -int SDL_SYS_JoystickNeedsPolling()
   1.446 -{
   1.447 -	/* we have a new device or one was pulled, we need to think this frame please */
   1.448 -	if ( s_bDeviceAdded || s_bDeviceRemoved )
   1.449 -		return 1;
   1.450 -
   1.451 -	return 0;
   1.452 -}
   1.453 -
   1.454  /* return the stable device guid for this device index */
   1.455 -JoystickGUID SDL_SYS_PrivateJoystickGetDeviceGUID( int device_index )
   1.456 +JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index )
   1.457  {
   1.458  	JoyStick_DeviceData *device = SYS_Joystick;
   1.459  	int index;
   1.460 @@ -1662,8 +1660,13 @@
   1.461  	return device->guid;
   1.462  }
   1.463  
   1.464 -/* return 1 if this device is using XInput */
   1.465 -int SDL_SYS_IsXInputDeviceIndex( int device_index )
   1.466 +JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick)
   1.467 +{
   1.468 +	return joystick->hwdata->guid;
   1.469 +}
   1.470 +
   1.471 +/* return SDL_TRUE if this device is using XInput */
   1.472 +SDL_bool SDL_SYS_IsXInputDeviceIndex(int device_index)
   1.473  {
   1.474  	JoyStick_DeviceData *device = SYS_Joystick;
   1.475  	int index;
   1.476 @@ -1674,11 +1677,6 @@
   1.477  	return device->bXInputDevice;
   1.478  }
   1.479  
   1.480 -JoystickGUID SDL_SYS_PrivateJoystickGetGUID(SDL_Joystick * joystick)
   1.481 -{
   1.482 -	return joystick->hwdata->guid;
   1.483 -}
   1.484 -
   1.485  #endif /* SDL_JOYSTICK_DINPUT */
   1.486  
   1.487  /* vi: set ts=4 sw=4 expandtab: */