Esempio n. 1
0
void PollXInputButtons(u32 pad, XINPUT_STATE *state)
{
	int i;
	
	// Check buttons
	for ( i = 0; i < 16; i++ )
	{
		WORD mask = 1 << i;

		if ( (state->Gamepad.wButtons & mask) == mask )
			DX_PerKeyDown( pad, 0, DIJOFS_BUTTON(i) );
		else
			DX_PerKeyUp( pad, 0, DIJOFS_BUTTON(i) );
	}
}
int CL_InputDeviceProvider_DirectInput::get_button_count() const
{
	throw_if_disposed();
	int count=0;

	for ( int x = 0; x < 32; x++ )
	{
		count += check_axis(DIJOFS_BUTTON( x )); 
	}
	return count;
}
/*
 * Converts an SDL trigger button to an DIEFFECT trigger button.
 */
static DWORD
DIGetTriggerButton(Uint16 button)
{
    DWORD dwTriggerButton;

    dwTriggerButton = DIEB_NOTRIGGER;

    if (button != 0) {
        dwTriggerButton = DIJOFS_BUTTON(button - 1);
    }

    return dwTriggerButton;
}
static BOOL CALLBACK DIJoystick_EnumDevObjectsProc(LPCDIDEVICEOBJECTINSTANCE dev, LPVOID data)
{
	DIDevice *device = (DIDevice *) data;
	HRESULT hr;

	input_t in;
	const int SupportedMask = DIDFT_BUTTON | DIDFT_POV | DIDFT_AXIS;
	if(!(dev->dwType & SupportedMask))
		return DIENUM_CONTINUE; // unsupported

	if(dev->dwType & DIDFT_BUTTON) {
		if( device->buttons == 24 )
			return DIENUM_CONTINUE; // too many buttons

		in.ofs = DIJOFS_BUTTON(device->buttons);
		in.type = in.BUTTON;
		in.num = device->buttons;
	} else if(dev->dwType & DIDFT_POV) {
		in.ofs = DIJOFS_POV(device->hats);
		in.type = in.HAT;
		in.num = device->hats;
	} else { // dev->dwType & DIDFT_AXIS
		DIPROPRANGE diprg;
		DIPROPDWORD dilong;

		// Figure out which axis we're looking at and store the correct DIJOFS_* value.
		if( dev->guidType == GUID_XAxis )
		{
			in.ofs = DIJOFS_X;
		}
		else if( dev->guidType == GUID_YAxis )
		{
			in.ofs = DIJOFS_Y;
		}
		else if( dev->guidType == GUID_ZAxis )
		{
			in.ofs = DIJOFS_Z;
		}
		else if( dev->guidType == GUID_RxAxis )
		{
			in.ofs = DIJOFS_RX;
		}
		else if( dev->guidType == GUID_RyAxis )
		{
			in.ofs = DIJOFS_RY;
		}
		else if( dev->guidType == GUID_RzAxis )
		{
			in.ofs = DIJOFS_RZ;
		}
		else
		{
			// No idea what this is so ignore it.
			return DIENUM_CONTINUE;
		}

		in.type = in.AXIS;
		in.num = device->axes;

		diprg.diph.dwSize		= sizeof(diprg);
		diprg.diph.dwHeaderSize	= sizeof(diprg.diph);
		diprg.diph.dwObj		= dev->dwType;
		diprg.diph.dwHow		= DIPH_BYID;
		diprg.lMin				= -100;
		diprg.lMax				= 100;

		hr = device->Device->SetProperty( DIPROP_RANGE, &diprg.diph );
		if ( hr != DI_OK )
			return DIENUM_CONTINUE; // don't use this axis

		// Set dead zone to 0.
		dilong.diph.dwSize		= sizeof(dilong);
		dilong.diph.dwHeaderSize	= sizeof(dilong.diph);
		dilong.diph.dwObj		= dev->dwType;
		dilong.diph.dwHow		= DIPH_BYID;
		dilong.dwData = 0;
		hr = device->Device->SetProperty( DIPROP_DEADZONE, &dilong.diph );
		if ( hr != DI_OK )
			return DIENUM_CONTINUE; // don't use this axis
	}

	/* For some devices it's possible to find multiple objects of the same type. When trying to
	 * figure out which device caused an event it doesn't matter which one it finds so there's
	 * no need to include a duplicate if one has already been added.
	 */
	if( std::find_if( device->Inputs.begin(), device->Inputs.end(), input_t::Compare( in.ofs ) ) == device->Inputs.end() )
	{
		device->Inputs.push_back(in);

		// Increment the number of buttons/axes/hats only after it has been added.
		switch ( in.type )
		{
			case input_t::BUTTON:
				++device->buttons;
				break;

			case input_t::AXIS:
				++device->axes;
				break;

			case input_t::HAT:
				++device->hats;
				break;
		}
	}

	return DIENUM_CONTINUE;
}
Esempio n. 5
0
#define numObjects(x) (sizeof(x) / sizeof(x[0]))

typedef struct tagUserData {
    IDirectInputA *pDI;
    DWORD version;
} UserData;

static const DIOBJECTDATAFORMAT dfDIJoystickTest[] = {
  { &GUID_XAxis,DIJOFS_X,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
  { &GUID_YAxis,DIJOFS_Y,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
  { &GUID_ZAxis,DIJOFS_Z,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
  { &GUID_RxAxis,DIJOFS_RX,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
  { &GUID_RyAxis,DIJOFS_RY,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
  { &GUID_RzAxis,DIJOFS_RZ,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
  { &GUID_Button,DIJOFS_BUTTON(0),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  { &GUID_Button,DIJOFS_BUTTON(1),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  { &GUID_Button,DIJOFS_BUTTON(2),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  { &GUID_Button,DIJOFS_BUTTON(3),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  { &GUID_Button,DIJOFS_BUTTON(4),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  { &GUID_Button,DIJOFS_BUTTON(5),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  { &GUID_Button,DIJOFS_BUTTON(6),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  { &GUID_Button,DIJOFS_BUTTON(7),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  { &GUID_Button,DIJOFS_BUTTON(8),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  { &GUID_Button,DIJOFS_BUTTON(9),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  { &GUID_Button,DIJOFS_BUTTON(10),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
};

static const DIDATAFORMAT c_dfDIJoystickTest = {
    sizeof(DIDATAFORMAT),
    sizeof(DIOBJECTDATAFORMAT),
Esempio n. 6
0
#define numObjects(x) (sizeof(x) / sizeof(x[0]))

static const DIOBJECTDATAFORMAT dfDIJoystick[] = {
  { &GUID_XAxis,DIJOFS_X,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
  { &GUID_YAxis,DIJOFS_Y,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
  { &GUID_ZAxis,DIJOFS_Z,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
  { &GUID_RxAxis,DIJOFS_RX,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
  { &GUID_RyAxis,DIJOFS_RY,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
  { &GUID_RzAxis,DIJOFS_RZ,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
  { &GUID_Slider,DIJOFS_SLIDER(0),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
  { &GUID_Slider,DIJOFS_SLIDER(1),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
  { &GUID_POV,DIJOFS_POV(0),DIDFT_OPTIONAL|DIDFT_POV|DIDFT_ANYINSTANCE,0},
  { &GUID_POV,DIJOFS_POV(1),DIDFT_OPTIONAL|DIDFT_POV|DIDFT_ANYINSTANCE,0},
  { &GUID_POV,DIJOFS_POV(2),DIDFT_OPTIONAL|DIDFT_POV|DIDFT_ANYINSTANCE,0},
  { &GUID_POV,DIJOFS_POV(3),DIDFT_OPTIONAL|DIDFT_POV|DIDFT_ANYINSTANCE,0},
  { NULL,DIJOFS_BUTTON(0),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  { NULL,DIJOFS_BUTTON(1),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  { NULL,DIJOFS_BUTTON(2),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  { NULL,DIJOFS_BUTTON(3),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  { NULL,DIJOFS_BUTTON(4),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  { NULL,DIJOFS_BUTTON(5),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  { NULL,DIJOFS_BUTTON(6),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  { NULL,DIJOFS_BUTTON(7),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  { NULL,DIJOFS_BUTTON(8),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  { NULL,DIJOFS_BUTTON(9),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  { NULL,DIJOFS_BUTTON(10),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  { NULL,DIJOFS_BUTTON(11),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  { NULL,DIJOFS_BUTTON(12),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  { NULL,DIJOFS_BUTTON(13),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  { NULL,DIJOFS_BUTTON(14),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
  { NULL,DIJOFS_BUTTON(15),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
/* update_joystick: [joystick thread]
 *  Reads in data for a single DirectInput joystick device, updates
 *  the internal ALLEGRO_JOYSTICK_STATE structure, and generates any Allegro
 *  events required.
 */
static void update_joystick(ALLEGRO_JOYSTICK_DIRECTX *joy)
{
   DIDEVICEOBJECTDATA buffer[DEVICE_BUFFER_SIZE];
   DWORD num_items = DEVICE_BUFFER_SIZE;
   HRESULT hr;
   ALLEGRO_EVENT_SOURCE *es = al_get_joystick_event_source();

   /* some devices require polling */
   IDirectInputDevice8_Poll(joy->device);

   /* get device data into buffer */
   hr = IDirectInputDevice8_GetDeviceData(joy->device, sizeof(DIDEVICEOBJECTDATA), buffer, &num_items, 0);

   if (hr != DI_OK && hr != DI_BUFFEROVERFLOW) {
      if ((hr == DIERR_NOTACQUIRED) || (hr == DIERR_INPUTLOST)) {
         ALLEGRO_WARN("joystick device not acquired or lost\n");
      }
      else {
         ALLEGRO_ERROR("unexpected error while polling the joystick\n");
      }
      return;
   }

   /* don't bother locking the event source if there's no work to do */
   /* this happens a lot for polled devices */
   if (num_items == 0)
      return;

   _al_event_source_lock(es);
   {
      unsigned int i;

      for (i = 0; i < num_items; i++) {
         const DIDEVICEOBJECTDATA *item = &buffer[i];
         const int dwOfs    = item->dwOfs;
         const DWORD dwData = item->dwData;

         switch (dwOfs) {
         case DIJOFS_X:         handle_axis_event(joy, &joy->x_mapping, dwData); break;
         case DIJOFS_Y:         handle_axis_event(joy, &joy->y_mapping, dwData); break;
         case DIJOFS_Z:         handle_axis_event(joy, &joy->z_mapping, dwData); break;
         case DIJOFS_RX:        handle_axis_event(joy, &joy->rx_mapping, dwData); break;
         case DIJOFS_RY:        handle_axis_event(joy, &joy->ry_mapping, dwData); break;
         case DIJOFS_RZ:        handle_axis_event(joy, &joy->rz_mapping, dwData); break;
         case DIJOFS_SLIDER(0): handle_axis_event(joy, &joy->slider_mapping[0], dwData); break;
         case DIJOFS_SLIDER(1): handle_axis_event(joy, &joy->slider_mapping[1], dwData); break;
         case DIJOFS_POV(0):    handle_pov_event(joy, joy->pov_mapping_stick[0], dwData); break;
         case DIJOFS_POV(1):    handle_pov_event(joy, joy->pov_mapping_stick[1], dwData); break;
         case DIJOFS_POV(2):    handle_pov_event(joy, joy->pov_mapping_stick[2], dwData); break;
         case DIJOFS_POV(3):    handle_pov_event(joy, joy->pov_mapping_stick[3], dwData); break;
         default:
            /* buttons */
            if ((dwOfs >= DIJOFS_BUTTON0) &&
                (dwOfs <  DIJOFS_BUTTON(joy->parent.info.num_buttons)))
            {
               int num = (dwOfs - DIJOFS_BUTTON0) / (DIJOFS_BUTTON1 - DIJOFS_BUTTON0);
               handle_button_event(joy, num, (dwData & 0x80));
            }
            break;
         }
      }
   }
   _al_event_source_unlock(es);
}
#define DIDFT_OPTIONAL          0x80000000

static const DIOBJECTDATAFORMAT __al_dfDIJoystick[] = {
   { &__al_GUID_XAxis, DIJOFS_X, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0},
   { &__al_GUID_YAxis, DIJOFS_Y, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0},
   { &__al_GUID_ZAxis, DIJOFS_Z, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0},
   { &__al_GUID_RxAxis, DIJOFS_RX, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0},
   { &__al_GUID_RyAxis, DIJOFS_RY, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0},
   { &__al_GUID_RzAxis, DIJOFS_RZ, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0},
   { &__al_GUID_Slider, DIJOFS_SLIDER(0), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0},
   { &__al_GUID_Slider, DIJOFS_SLIDER(1), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0},
   { &__al_GUID_POV, DIJOFS_POV(0), DIDFT_OPTIONAL | DIDFT_POV | DIDFT_ANYINSTANCE, 0},
   { &__al_GUID_POV, DIJOFS_POV(1), DIDFT_OPTIONAL | DIDFT_POV | DIDFT_ANYINSTANCE, 0},
   { &__al_GUID_POV, DIJOFS_POV(2), DIDFT_OPTIONAL | DIDFT_POV | DIDFT_ANYINSTANCE, 0},
   { &__al_GUID_POV, DIJOFS_POV(3), DIDFT_OPTIONAL | DIDFT_POV | DIDFT_ANYINSTANCE, 0},
   { NULL, DIJOFS_BUTTON(0), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0},
   { NULL, DIJOFS_BUTTON(1), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0},
   { NULL, DIJOFS_BUTTON(2), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0},
   { NULL, DIJOFS_BUTTON(3), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0},
   { NULL, DIJOFS_BUTTON(4), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0},
   { NULL, DIJOFS_BUTTON(5), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0},
   { NULL, DIJOFS_BUTTON(6), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0},
   { NULL, DIJOFS_BUTTON(7), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0},
   { NULL, DIJOFS_BUTTON(8), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0},
   { NULL, DIJOFS_BUTTON(9), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0},
   { NULL, DIJOFS_BUTTON(10), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0},
   { NULL, DIJOFS_BUTTON(11), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0},
   { NULL, DIJOFS_BUTTON(12), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0},
   { NULL, DIJOFS_BUTTON(13), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0},
   { NULL, DIJOFS_BUTTON(14), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0},
   { NULL, DIJOFS_BUTTON(15), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0},
Esempio n. 9
0
static BOOL CALLBACK
EnumDevObjectsCallback(LPCDIDEVICEOBJECTINSTANCE dev, LPVOID pvRef)
{
    SDL_Joystick *joystick = (SDL_Joystick *)pvRef;
    HRESULT result;
    input_t *in = &joystick->hwdata->Inputs[joystick->hwdata->NumInputs];

    if (dev->dwType & DIDFT_BUTTON) {
        in->type = BUTTON;
        in->num = joystick->nbuttons;
        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);
        joystick->nhats++;
    } else if (dev->dwType & DIDFT_AXIS) {
        DIPROPRANGE diprg;
        DIPROPDWORD dilong;

        in->type = AXIS;
        in->num = joystick->naxes;
        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);
        diprg.diph.dwObj = dev->dwType;
        diprg.diph.dwHow = DIPH_BYID;
        diprg.lMin = SDL_JOYSTICK_AXIS_MIN;
        diprg.lMax = SDL_JOYSTICK_AXIS_MAX;

        result =
            IDirectInputDevice8_SetProperty(joystick->hwdata->InputDevice,
            DIPROP_RANGE, &diprg.diph);
        if (FAILED(result)) {
            return DIENUM_CONTINUE;     /* don't use this axis */
        }

        /* Set dead zone to 0. */
        dilong.diph.dwSize = sizeof(dilong);
        dilong.diph.dwHeaderSize = sizeof(dilong.diph);
        dilong.diph.dwObj = dev->dwType;
        dilong.diph.dwHow = DIPH_BYID;
        dilong.dwData = 0;
        result =
            IDirectInputDevice8_SetProperty(joystick->hwdata->InputDevice,
            DIPROP_DEADZONE, &dilong.diph);
        if (FAILED(result)) {
            return DIENUM_CONTINUE;     /* don't use this axis */
        }

        joystick->naxes++;
    } else {
        /* not supported at this time */
        return DIENUM_CONTINUE;
    }

    joystick->hwdata->NumInputs++;

    if (joystick->hwdata->NumInputs == MAX_INPUTS) {
        return DIENUM_STOP;     /* too many */
    }

    return DIENUM_CONTINUE;
}
Esempio n. 10
0
static HRESULT WINAPI LinuxInputEffectImpl_GetParameters(
	LPDIRECTINPUTEFFECT iface,
	LPDIEFFECT peff,
	DWORD dwFlags)
{
    HRESULT diErr = DI_OK;
    LinuxInputEffectImpl *This = impl_from_IDirectInputEffect(iface);
    TRACE("(this=%p,%p,%d)\n", This, peff, dwFlags);

    /* Major conversion factors are:
     * times: millisecond (linux) -> microsecond (windows) (x * 1000)
     * forces: scale 0x7FFF (linux) -> scale 10000 (windows) approx ((x / 33) * 10)
     * angles: scale 0x7FFF (linux) -> scale 35999 (windows) approx ((x / 33) * 36)
     * angle bases: 0 -> -y (down) (linux) -> 0 -> +x (right) (windows)
     */

    if (dwFlags & DIEP_AXES) {
	if (peff->cAxes < 2 /* linuxinput effects always use 2 axes, x and y */)
	    diErr = DIERR_MOREDATA;
	peff->cAxes = 2; 
	if (diErr)
	    return diErr;
	else {
	    peff->rgdwAxes[0] = DIJOFS_X;
	    peff->rgdwAxes[1] = DIJOFS_Y;
	}
    }
 
    if (dwFlags & DIEP_DIRECTION) {
        if (peff->cAxes < 2)
            diErr = DIERR_MOREDATA;
        peff->cAxes = 2; 
        if (diErr)
            return diErr;
        else {
	    if (peff->dwFlags & DIEFF_CARTESIAN) {
		peff->rglDirection[0] = sin(M_PI * 3 * This->effect.direction / 0x7FFF) * 1000;
		peff->rglDirection[1] = cos(M_PI * 3 * This->effect.direction / 0x7FFF) * 1000;
	    } else {
		/* Polar and spherical coordinates are the same for two or less
		 * axes.
		 * Note that we also use this case if NO flags are marked.
		 * According to MSDN, we should return the direction in the
		 * format that it was specified in, if no flags are marked.
		 */
		peff->rglDirection[0] = (This->effect.direction / 33) * 36 + 9000;
		if (peff->rglDirection[0] > 35999)
		    peff->rglDirection[0] -= 35999;
	    }
	}
    }

    if (dwFlags & DIEP_DURATION) {
	peff->dwDuration = (DWORD)This->effect.replay.length * 1000;
    }

    if (dwFlags & DIEP_ENVELOPE) {
	struct ff_envelope* env;
	if (This->effect.type == FF_CONSTANT) env = &This->effect.u.constant.envelope;
	else if (This->effect.type == FF_PERIODIC) env = &This->effect.u.periodic.envelope;
	else if (This->effect.type == FF_RAMP) env = &This->effect.u.ramp.envelope;
	else env = NULL;
	if (env == NULL) {
	    peff->lpEnvelope = NULL;
	} else if (peff->lpEnvelope == NULL) {
	    return DIERR_INVALIDPARAM;
	} else { 
	    peff->lpEnvelope->dwAttackLevel = (env->attack_level / 33) * 10;
	    peff->lpEnvelope->dwAttackTime = env->attack_length * 1000;
	    peff->lpEnvelope->dwFadeLevel = (env->fade_level / 33) * 10;
	    peff->lpEnvelope->dwFadeTime = env->fade_length * 1000;
	}
    }

    if (dwFlags & DIEP_GAIN) {
	peff->dwGain = This->gain * 10000 / 0xFFFF;
    }

    if (dwFlags & DIEP_SAMPLEPERIOD) {
	/* the linux input ff driver has no support for setting
	 * the playback sample period.  0 means default. */
    	peff->dwSamplePeriod = 0;
    }

    if (dwFlags & DIEP_STARTDELAY) {
	peff->dwStartDelay = This->effect.replay.delay * 1000;
    }

    if (dwFlags & DIEP_TRIGGERBUTTON) {
	FIXME("LinuxInput button mapping needs redoing; for now, assuming we're using an actual joystick.\n");
	peff->dwTriggerButton = DIJOFS_BUTTON(This->effect.trigger.button - BTN_JOYSTICK);
    }

    if (dwFlags & DIEP_TRIGGERREPEATINTERVAL) {
	peff->dwTriggerRepeatInterval = This->effect.trigger.interval * 1000;
    }

    if (dwFlags & DIEP_TYPESPECIFICPARAMS) {
	DWORD expectedsize = 0;
	if (This->effect.type == FF_PERIODIC) {
	    expectedsize = sizeof(DIPERIODIC);
	} else if (This->effect.type == FF_CONSTANT) {
	    expectedsize = sizeof(DICONSTANTFORCE);
	} else if (This->effect.type == FF_SPRING 
		|| This->effect.type == FF_FRICTION 
		|| This->effect.type == FF_INERTIA 
		|| This->effect.type == FF_DAMPER) {
	    expectedsize = sizeof(DICONDITION) * 2;
	} else if (This->effect.type == FF_RAMP) {
	    expectedsize = sizeof(DIRAMPFORCE);
	}
	if (expectedsize > peff->cbTypeSpecificParams)
	    diErr = DIERR_MOREDATA;
	peff->cbTypeSpecificParams = expectedsize;
	if (diErr)
	    return diErr;
	else {
	    if (This->effect.type == FF_PERIODIC) {
                LPDIPERIODIC tsp = peff->lpvTypeSpecificParams;
		tsp->dwMagnitude = (This->effect.u.periodic.magnitude / 33) * 10;
		tsp->lOffset = (This->effect.u.periodic.offset / 33) * 10;
		tsp->dwPhase = (This->effect.u.periodic.phase / 33) * 36;
		tsp->dwPeriod = (This->effect.u.periodic.period * 1000);
	    } else if (This->effect.type == FF_CONSTANT) {
                LPDICONSTANTFORCE tsp = peff->lpvTypeSpecificParams;
		tsp->lMagnitude = (This->effect.u.constant.level / 33) * 10;
	    } else if (This->effect.type == FF_SPRING 
		    || This->effect.type == FF_FRICTION 
		    || This->effect.type == FF_INERTIA 
		    || This->effect.type == FF_DAMPER) {
                LPDICONDITION tsp = peff->lpvTypeSpecificParams;
		int i;
		for (i = 0; i < 2; ++i) {
		    tsp[i].lOffset = (This->effect.u.condition[i].center / 33) * 10; 
		    tsp[i].lPositiveCoefficient = (This->effect.u.condition[i].right_coeff / 33) * 10;
		    tsp[i].lNegativeCoefficient = (This->effect.u.condition[i].left_coeff / 33) * 10; 
		    tsp[i].dwPositiveSaturation = (This->effect.u.condition[i].right_saturation / 33) * 10;
		    tsp[i].dwNegativeSaturation = (This->effect.u.condition[i].left_saturation / 33) * 10;
		    tsp[i].lDeadBand = (This->effect.u.condition[i].deadband / 33) * 10;
		}
	    } else if (This->effect.type == FF_RAMP) {
                LPDIRAMPFORCE tsp = peff->lpvTypeSpecificParams;
		tsp->lStart = (This->effect.u.ramp.start_level / 33) * 10;
		tsp->lEnd = (This->effect.u.ramp.end_level / 33) * 10;
	    }
	}
    } 

    return diErr;
}
Esempio n. 11
0
int PERDXFetchNextPress(HWND hWnd, u32 guidnum, char *buttonname)
{
   LPDIRECTINPUT8 lpDI8temp = NULL;
   LPDIRECTINPUTDEVICE8 lpDIDevicetemp;
   DIDEVCAPS didc;
   int buttonid=-1;

   if (FAILED(DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION,
       &IID_IDirectInput8, (LPVOID *)&lpDI8temp, NULL)))
      return -1;

   if (FAILED(IDirectInput8_CreateDevice(lpDI8temp, &GUIDDevice[guidnum], &lpDIDevicetemp,
       NULL)))
   {
      IDirectInput8_Release(lpDI8temp);
      return -1;
   }

   didc.dwSize = sizeof(DIDEVCAPS);

   if (FAILED(IDirectInputDevice8_GetCapabilities(lpDIDevicetemp, &didc)))
   {
      IDirectInputDevice8_Release(lpDIDevicetemp);       
      IDirectInput8_Release(lpDI8temp);
      return -1;
   }

   if (GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_KEYBOARD)
   {
      if (FAILED(IDirectInputDevice8_SetDataFormat(lpDIDevicetemp, &c_dfDIKeyboard)))
      {
         IDirectInputDevice8_Release(lpDIDevicetemp);       
         IDirectInput8_Release(lpDI8temp);
         return -1;
      }
   }       
   else if (GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_GAMEPAD ||
           GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_JOYSTICK)
   {
      if (FAILED(IDirectInputDevice8_SetDataFormat(lpDIDevicetemp, &c_dfDIJoystick)))
      {
         IDirectInputDevice8_Release(lpDIDevicetemp);       
         IDirectInput8_Release(lpDI8temp);
         return -1;
      }
   }
   else if (GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_MOUSE)
   {
      if (FAILED(IDirectInputDevice8_SetDataFormat(lpDIDevicetemp, &c_dfDIMouse2)))
      {
         IDirectInputDevice8_Release(lpDIDevicetemp);       
         IDirectInput8_Release(lpDI8temp);
         return -1;
      }
   }       

   if (DialogBoxParam(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_BUTTONCONFIG), hWnd, (DLGPROC)ButtonConfigDlgProc, (LPARAM)lpDIDevicetemp) == TRUE)
   {
      // Figure out what kind of code to generate
      if (GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_KEYBOARD)
      {
         memset(buttonname, 0, MAX_PATH);
         buttonid = nextpress.dwOfs;
         // This fixes some strange inconsistencies
         if (buttonid == DIK_PAUSE)
            buttonid = DIK_NUMLOCK;
         else if (buttonid == DIK_NUMLOCK)
            buttonid = DIK_PAUSE;
         if (buttonid & 0x80)
            buttonid += 0x80;

         GetKeyNameTextA(buttonid << 16, buttonname, MAX_PATH);
         buttonid = nextpress.dwOfs;
      }
      else if (GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_GAMEPAD ||
               GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_JOYSTICK)
      {
         if (nextpress.dwOfs == DIJOFS_X)
         {
            if (nextpress.dwData <= 0x8000)
            {
               sprintf(buttonname, "Axis Left");
               buttonid = 0x00;
            }
            else
            {
               sprintf(buttonname, "Axis Right");
               buttonid = 0x01;
            }
         }
         else if (nextpress.dwOfs == DIJOFS_Y)
         {
            if (nextpress.dwData <= 0x8000)
            {
               sprintf(buttonname, "Axis Up");
               buttonid = 0x02;
            }
            else
            {
               sprintf(buttonname, "Axis Down");
               buttonid = 0x03;
            }
         }
         else if (nextpress.dwOfs == DIJOFS_POV(0))
         {
            if (nextpress.dwData < 9000)
            {
               sprintf(buttonname, "POV Up");
               buttonid = 0x04;
            }
            else if (nextpress.dwData < 18000)
            {
               sprintf(buttonname, "POV Right");
               buttonid = 0x05;
            }
            else if (nextpress.dwData < 27000)
            {
               sprintf(buttonname, "POV Down");
               buttonid = 0x06;
            }
            else
            {
               sprintf(buttonname, "POV Left");
               buttonid = 0x07;
            }
         }
         else if (nextpress.dwOfs >= DIJOFS_BUTTON(0) && nextpress.dwOfs <= DIJOFS_BUTTON(127))
         {
            sprintf(buttonname, "Button %d", (int)(nextpress.dwOfs - 0x2F));
            buttonid = nextpress.dwOfs;
         }
      }
      else if (GET_DIDEVICE_TYPE(didc.dwDevType) == DI8DEVTYPE_MOUSE)
      {
         buttonid = nextpress.dwOfs-DIMOFS_BUTTON0;
         sprintf(buttonname, "Button %d", buttonid+1);
      }
   }

   IDirectInputDevice8_Unacquire(lpDIDevicetemp);
   IDirectInputDevice8_Release(lpDIDevicetemp);       
   IDirectInput8_Release(lpDI8temp);

   return buttonid;
}
Esempio n. 12
0
void PollKeys(void)
{
   u32 i;
   DWORD i2;
   DWORD size=8;
   DIDEVICEOBJECTDATA didod[8];
   HRESULT hr;

   for (i = 0; i < numpads; i++)
   {
      if (paddevice[i].lpDIDevice == NULL)
         continue;

      hr = IDirectInputDevice8_Poll(paddevice[i].lpDIDevice);

      if (FAILED(hr))
      {
         if (hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED)
         {
            // Make sure device is acquired
            while(IDirectInputDevice8_Acquire(paddevice[i].lpDIDevice) == DIERR_INPUTLOST) {}
            continue;
         }
      }

      size = 8;

      // Poll events
      if (FAILED(IDirectInputDevice8_GetDeviceData(paddevice[i].lpDIDevice,
          sizeof(DIDEVICEOBJECTDATA), didod, &size, 0)))
      {
         if (hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED)
         {
            // Make sure device is acquired
            while(IDirectInputDevice8_Acquire(paddevice[i].lpDIDevice) == DIERR_INPUTLOST) {}
            continue;
         }
      }

      if (size == 0)
         continue;

      switch (paddevice[i].type)
      {
         case TYPE_KEYBOARD:
            // This probably could be optimized
            for (i2 = 0; i2 < size; i2++)
            {
               if (didod[i2].dwData & 0x80)
                  PerKeyDown(didod[i2].dwOfs);
               else
                  PerKeyUp(didod[i2].dwOfs);
            }
            break;
         case TYPE_JOYSTICK:
         {
            // This probably could be optimized
            for (i2 = 0; i2 < size; i2++)
            {
               // X Axis
               if (didod[i2].dwOfs == DIJOFS_X)
               {
                  if (didod[i2].dwData < 0x3FFF)
                  {
                     PerKeyDown(PAD_DIR_AXISLEFT);
                     PerKeyUp(PAD_DIR_AXISRIGHT);
                  }
                  else if (didod[i2].dwData > 0xBFFF)
                  {
                     PerKeyDown(PAD_DIR_AXISRIGHT);
                     PerKeyUp(PAD_DIR_AXISLEFT);
                  }
                  else
                  {
                     PerKeyUp(PAD_DIR_AXISLEFT);
                     PerKeyUp(PAD_DIR_AXISRIGHT);
                  }
               }
               // Y Axis
               else if (didod[i2].dwOfs == DIJOFS_Y)
               {
                  if (didod[i2].dwData < 0x3FFF)
                  {
                     PerKeyDown(PAD_DIR_AXISUP);
                     PerKeyUp(PAD_DIR_AXISDOWN);
                  }
                  else if (didod[i2].dwData > 0xBFFF)
                  {
                     PerKeyDown(PAD_DIR_AXISDOWN);
                     PerKeyUp(PAD_DIR_AXISUP);
                  }
                  else
                  {
                     PerKeyUp(PAD_DIR_AXISUP);
                     PerKeyUp(PAD_DIR_AXISDOWN);
                  }
               } 
               else if (didod[i2].dwOfs == DIJOFS_POV(0))
               {
                  // POV Center
                  if (LOWORD(didod[i2].dwData) == 0xFFFF)
                  {
                     PerKeyUp(PAD_DIR_POVUP);
                     PerKeyUp(PAD_DIR_POVRIGHT);
                     PerKeyUp(PAD_DIR_POVDOWN);
                     PerKeyUp(PAD_DIR_POVLEFT);
                  }
                  // POV Up
                  else if (didod[i2].dwData < 4500)
                  {
                     PerKeyDown(PAD_DIR_POVUP);
                     PerKeyUp(PAD_DIR_POVRIGHT);
                     PerKeyUp(PAD_DIR_POVLEFT);
                  }
                  // POV Up-right
                  else if (didod[i2].dwData < 9000)
                  {
                     PerKeyDown(PAD_DIR_POVUP);
                     PerKeyDown(PAD_DIR_POVRIGHT);
                  }
                  // POV Right
                  else if (didod[i2].dwData < 13500)
                  {
                     PerKeyDown(PAD_DIR_POVRIGHT);
                     PerKeyUp(PAD_DIR_POVDOWN);
                     PerKeyUp(PAD_DIR_POVUP);
                  }
                  // POV Right-down
                  else if (didod[i2].dwData < 18000)
                  {
                     PerKeyDown(PAD_DIR_POVRIGHT);
                     PerKeyDown(PAD_DIR_POVDOWN);
                  }
                  // POV Down
                  else if (didod[i2].dwData < 22500)
                  {
                     PerKeyDown(PAD_DIR_POVDOWN);
                     PerKeyUp(PAD_DIR_POVLEFT);
                     PerKeyUp(PAD_DIR_POVRIGHT);
                  }
                  // POV Down-left
                  else if (didod[i2].dwData < 27000)
                  {
                     PerKeyDown(PAD_DIR_POVDOWN);
                     PerKeyDown(PAD_DIR_POVLEFT);
                  }
                  // POV Left
                  else if (didod[i2].dwData < 31500)
                  {
                     PerKeyDown(PAD_DIR_POVLEFT);
                     PerKeyUp(PAD_DIR_POVUP);
                     PerKeyUp(PAD_DIR_POVDOWN);
                  }
                  // POV Left-up
                  else if (didod[i2].dwData < 36000)
                  {
                     PerKeyDown(PAD_DIR_POVLEFT);
                     PerKeyDown(PAD_DIR_POVUP);
                  }
               }
               else if (didod[i2].dwOfs >= DIJOFS_BUTTON(0) && didod[i2].dwOfs <= DIJOFS_BUTTON(127))
               {
                  if (didod[i2].dwData & 0x80)
                     PerKeyDown(didod[i2].dwOfs);
                  else
                     PerKeyUp(didod[i2].dwOfs);
               }
            }
            break;
         }
         case TYPE_MOUSE:
            for (i2 = 0; i2 < size; i2++)
            {
               if (didod[i2].dwOfs == DIMOFS_X)
                  // X Axis                  
                  PerMouseMove((PerMouse_struct *)pad[i], (s32)didod[i2].dwData, 0);
               else if (didod[i2].dwOfs == DIMOFS_Y)
                  // Y Axis
                  PerMouseMove((PerMouse_struct *)pad[i], 0, 0-(s32)didod[i2].dwData);
               else if (didod[i2].dwOfs >= DIMOFS_BUTTON0 && didod[i2].dwOfs <= DIMOFS_BUTTON7)
               {
                  // Mouse Buttons
                  if (didod[i2].dwData & 0x80)
                     PerKeyDown(didod[i2].dwOfs-DIMOFS_BUTTON0);
                  else
                     PerKeyUp(didod[i2].dwOfs-DIMOFS_BUTTON0);
               }
            }
            break;
         default: break;
      }
   }
}