/* Function to update the state of a joystick - called as a device poll.
 * This function shouldn't update the joystick structure directly,
 * but instead should call SDL_PrivateJoystick*() to deliver events
 * and update joystick device state.
 */
void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick)
{
	recDevice *device = joystick->hwdata;
	recElement *element;
	SInt32 value;
	int i;

	if (device->removed)  /* device was unplugged; ignore it. */
	{
		if (device->uncentered)
		{
			device->uncentered = 0;

			/* Tell the app that everything is centered/unpressed... */
			for (i = 0; i < device->axes; i++)
				SDL_PrivateJoystickAxis(joystick, i, 0);

			for (i = 0; i < device->buttons; i++)
				SDL_PrivateJoystickButton(joystick, i, 0);

			for (i = 0; i < device->hats; i++)
				SDL_PrivateJoystickHat(joystick, i, SDL_HAT_CENTERED);
		}

		return;
	}

	element = device->firstAxis;
	i = 0;
	while (element)
	{
		value = HIDScaledCalibratedValue(device, element, -32768, 32767);
		if ( value != joystick->axes[i] )
			SDL_PrivateJoystickAxis(joystick, i, value);
		element = element->pNext;
		++i;
	}
	
	element = device->firstButton;
	i = 0;
	while (element)
	{
		value = HIDGetElementValue(device, element);
        if (value > 1)  /* handle pressure-sensitive buttons */
            value = 1;
		if ( value != joystick->buttons[i] )
			SDL_PrivateJoystickButton(joystick, i, value);
		element = element->pNext;
		++i;
	}
	    
	element = device->firstHat;
	i = 0;
	while (element)
	{
		Uint8 pos = 0;

		value = HIDGetElementValue(device, element);
		if (element->max == 3) /* 4 position hatswitch - scale up value */
			value *= 2;
		else if (element->max != 7) /* Neither a 4 nor 8 positions - fall back to default position (centered) */
			value = -1;
		switch(value)
		{
			case 0:
				pos = SDL_HAT_UP;
				break;
			case 1:
				pos = SDL_HAT_RIGHTUP;
				break;
			case 2:
				pos = SDL_HAT_RIGHT;
				break;
			case 3:
				pos = SDL_HAT_RIGHTDOWN;
				break;
			case 4:
				pos = SDL_HAT_DOWN;
				break;
			case 5:
				pos = SDL_HAT_LEFTDOWN;
				break;
			case 6:
				pos = SDL_HAT_LEFT;
				break;
			case 7:
				pos = SDL_HAT_LEFTUP;
				break;
			default:
				/* Every other value is mapped to center. We do that because some
				 * joysticks use 8 and some 15 for this value, and apparently
				 * there are even more variants out there - so we try to be generous.
				 */
				pos = SDL_HAT_CENTERED;
				break;
		}
		if ( pos != joystick->hats[i] )
			SDL_PrivateJoystickHat(joystick, i, pos);
		element = element->pNext;
		++i;
	}
	
	return;
}
示例#2
0
/* Function to update the state of a joystick - called as a device poll.
 * This function shouldn't update the joystick structure directly,
 * but instead should call SDL_PrivateJoystick*() to deliver events
 * and update joystick device state.
 */
void
SDL_SYS_JoystickUpdate(SDL_Joystick * joystick)
{
	recDevice *device = joystick->hwdata;
    recElement *element;
    SInt32 value, range;
    int i;

	if ( !device )
		return;

    if (device->removed) {      /* device was unplugged; ignore it. */
		recDevice *devicelist = gpDeviceList;
		joystick->closed = 1;
		joystick->uncentered = 1;
		
		if ( devicelist == device )
		{
			gpDeviceList = device->pNext;
		}
		else
		{
			while ( devicelist->pNext != device )
			{
				devicelist = devicelist->pNext;
			}
			
			devicelist->pNext = device->pNext;
		}
		
		DisposePtr((Ptr) device);
		joystick->hwdata = NULL;

#if !SDL_EVENTS_DISABLED
		SDL_Event event;
		event.type = SDL_JOYDEVICEREMOVED;
		
		if (SDL_GetEventState(event.type) == SDL_ENABLE) {
			event.jdevice.which = joystick->instance_id;
			if ((SDL_EventOK == NULL)
				|| (*SDL_EventOK) (SDL_EventOKParam, &event)) {
				SDL_PushEvent(&event);
			}
		}
#endif /* !SDL_EVENTS_DISABLED */
		
        return;
    }

    element = device->firstAxis;
    i = 0;
    while (element) {
        value = HIDScaledCalibratedValue(device, element, -32768, 32767);
        if (value != joystick->axes[i])
            SDL_PrivateJoystickAxis(joystick, i, value);
        element = element->pNext;
        ++i;
    }

    element = device->firstButton;
    i = 0;
    while (element) {
        value = HIDGetElementValue(device, element);
        if (value > 1)          /* handle pressure-sensitive buttons */
            value = 1;
        if (value != joystick->buttons[i])
            SDL_PrivateJoystickButton(joystick, i, value);
        element = element->pNext;
        ++i;
    }

    element = device->firstHat;
    i = 0;
    while (element) {
        Uint8 pos = 0;

        range = (element->max - element->min + 1);
        value = HIDGetElementValue(device, element) - element->min;
        if (range == 4)         /* 4 position hatswitch - scale up value */
            value *= 2;
        else if (range != 8)    /* Neither a 4 nor 8 positions - fall back to default position (centered) */
            value = -1;
        switch (value) {
        case 0:
            pos = SDL_HAT_UP;
            break;
        case 1:
            pos = SDL_HAT_RIGHTUP;
            break;
        case 2:
            pos = SDL_HAT_RIGHT;
            break;
        case 3:
            pos = SDL_HAT_RIGHTDOWN;
            break;
        case 4:
            pos = SDL_HAT_DOWN;
            break;
        case 5:
            pos = SDL_HAT_LEFTDOWN;
            break;
        case 6:
            pos = SDL_HAT_LEFT;
            break;
        case 7:
            pos = SDL_HAT_LEFTUP;
            break;
        default:
            /* Every other value is mapped to center. We do that because some
             * joysticks use 8 and some 15 for this value, and apparently
             * there are even more variants out there - so we try to be generous.
             */
            pos = SDL_HAT_CENTERED;
            break;
        }
        if (pos != joystick->hats[i])
            SDL_PrivateJoystickHat(joystick, i, pos);
        element = element->pNext;
        ++i;
    }

    return;
}