Exemple #1
0
void ReadJoystick (int nJoystick_, LPDIRECTINPUTDEVICE2 pDevice_)
{
    HRESULT hr;
    int i;

    DIJOYSTATE dijs = { 0 };
    if (pDevice_ && (FAILED(hr = pDevice_->Poll()) || FAILED(hr = pDevice_->GetDeviceState(sizeof(dijs), &dijs))))
    {
        if (FAILED(hr = pDevice_->Acquire()))
            return;

        if (FAILED(hr = pDevice_->Poll()) || FAILED(hr = pDevice_->GetDeviceState(sizeof(dijs), &dijs)))
            TRACE("!!! Failed to read joystick %d state (%#08lx)\n", nJoystick_, hr);
    }


    DWORD dwButtons = 0;
    int nPosition = HJ_CENTRE;

    // Combine the states of all buttons so any button works as fire
    for (i = 0 ; i < _countof(dijs.rgbButtons) ; i++)
    {
        if (dijs.rgbButtons[i] & 0x80)
            dwButtons |= (1 << i);
    }

    // Set the position from the main axes
    if (dijs.lX < 0 || dijs.lRx < 0) nPosition |= HJ_LEFT;
    if (dijs.lX > 0 || dijs.lRx > 0) nPosition |= HJ_RIGHT;
    if (dijs.lY < 0 || dijs.lRy < 0) nPosition |= HJ_UP;
    if (dijs.lY > 0 || dijs.lRy > 0) nPosition |= HJ_DOWN;

    // Consider all hat positions too
    for (i = 0 ; i < _countof(dijs.rgdwPOV) ; i++)
    {
        static int an[] = { HJ_UP, HJ_UP|HJ_RIGHT, HJ_RIGHT, HJ_DOWN|HJ_RIGHT, HJ_DOWN, HJ_DOWN|HJ_LEFT, HJ_LEFT, HJ_UP|HJ_LEFT };

        // For best driver compatibility, only check the low WORD for the centre position
        if (LOWORD(dijs.rgdwPOV[i]) == 0xffff)
            continue;

        // Round the position and determine which of the 8 directions it's pointing
        int nPos = ((dijs.rgdwPOV[i] + 4500/2) / 4500) & 7;
        nPosition |= an[nPos];
    }

    Joystick::SetPosition(nJoystick_, nPosition);
    Joystick::SetButtons(nJoystick_, dwButtons);
}
Exemple #2
0
//===========================================================================
// DIUtilPollJoystick
//
// Polls the joystick device and returns the device state.
//
// Parameters:
//  LPDIRECTINPUTDEVICE2    pdiDevice2  - ptr to device object
//  DIJOYSTATE              *pdijs      - ptr to store joystick state
//
// Returns: HRESULT
//
//===========================================================================
HRESULT DIUtilPollJoystick(LPDIRECTINPUTDEVICE2 pdiDevice2, DIJOYSTATE *pdijs)
{
    HRESULT hRes    = E_NOTIMPL;

    // validate pointers
    if( (IsBadReadPtr((void*)pdiDevice2, sizeof(IDirectInputDevice2))) ||
        (IsBadWritePtr((void*)pdiDevice2, sizeof(IDirectInputDevice2))) )
    {
        ERROUT(TEXT("DIUtilPollJoystick() - invalid pdiDevice2\n"));
        return E_POINTER;
    }
    if( (IsBadReadPtr((void*)pdijs, sizeof(DIJOYSTATE))) ||
        (IsBadWritePtr((void*)pdijs, sizeof(DIJOYSTATE))) )
    {
        ERROUT(TEXT("DIUtilPollJoystick() - invalid pdijs\n"));
        return E_POINTER;
    }

    // clear the pdijs memory
    //
    // this way, if we fail, we return no data
    ZeroMemory(pdijs, sizeof(DIJOYSTATE));

    // poll the joystick
    //
    // don't worry if it fails, not all devices require polling
    hRes = pdiDevice2->Poll();
    
    // query the device state
    hRes = pdiDevice2->GetDeviceState(sizeof(DIJOYSTATE), pdijs);
    if(FAILED(hRes))
    {
        ERROUT(TEXT("DIUtilPollJoystick() - GetDeviceState() failed\n"));
        return hRes;
    }

    // done
    return hRes;

} //*** end DIUtilPollJoystick()
// TODO: RequestExclusive(false) when SetRumble() hasn't been called for several seconds.
void Joystick_DX5::UpdateInternal(void)
{
 DIJOYSTATE2 js;
 HRESULT hres;

 if(DevCaps.dwFlags & (DIDC_POLLEDDEVICE | DIDC_POLLEDDATAFORMAT))
 {
  do { /* */ hres = dev->Poll(); /* */ } while((hres == DIERR_INPUTLOST) && ((hres = dev->Acquire()) == DI_OK));
  if(hres != DI_OK)
   return;
 }

 do { /* */ hres = dev->GetDeviceState(sizeof(js), &js); /* */ } while((hres == DIERR_INPUTLOST) && ((hres = dev->Acquire()) == DI_OK));
 if(hres != DI_OK)
  return;

 for(unsigned button = 0; button < DevCaps.dwButtons; button++)
 {
  button_state[button] = (bool)(js.rgbButtons[button] & 0x80);
 }

 for(unsigned axis = 0; axis < DIAxisInfo.size(); axis++)
 {
  int64 rv = (&js.lX)[DIAxisInfo[axis].jd_logical_offset];

  rv = (((rv - DIAxisInfo[axis].minimum) * 32767 * 2) / (DIAxisInfo[axis].maximum - DIAxisInfo[axis].minimum)) - 32767;
  if(rv < -32767)
   rv = -32767;

  if(rv > 32767)
   rv = 32767;
  axis_state[axis] = rv;
 }

 for(unsigned hat = 0; hat < DevCaps.dwPOVs; hat++)
 {
  DWORD hat_val = js.rgdwPOV[hat];

  //if((uint16)hat_val == 0xFFFF)	// Reportedly some drivers report 0xFFFF instead of 0xFFFFFFFF? (comment from byuu)
  if(hat_val >= 36000)
  {
   axis_state[(DIAxisInfo.size() + hat * 2) + 0] = 0;
   axis_state[(DIAxisInfo.size() + hat * 2) + 1] = 0;
  }
  else
  {
   int32 x, y;

   //axis_state[(DIAxisInfo.size() + hat * 2) + 0] = 32767 * sin((double)M_PI * 2 * hat_val / 36000);	// x
   //axis_state[(DIAxisInfo.size() + hat * 2) + 1] = 32767 * -cos((double)M_PI * 2 * hat_val / 36000);	// y
   unsigned octant = (hat_val / 4500) & 0x7;
   signed octant_doff = hat_val % 4500;

   switch(octant)
   {
    case 0: x = octant_doff * 32767 / 4500; y = -32767; break;
    case 1: x = 32767; y = (-4500 + octant_doff) * 32767 / 4500; break;

    case 2: x = 32767; y = octant_doff * 32767 / 4500; break;
    case 3: x = (4500 - octant_doff) * 32767 / 4500; y = 32767; break;

    case 4: x = (-octant_doff) * 32767 / 4500; y = 32767; break;
    case 5: x = -32767; y = (4500 - octant_doff) * 32767 / 4500; break;
    
    case 6: x = -32767; y = (-octant_doff) * 32767 / 4500; break;
    case 7: x = (-4500 + octant_doff) * 32767 / 4500; y = -32767; break;
   }

   axis_state[(DIAxisInfo.size() + hat * 2) + 0] = x;
   axis_state[(DIAxisInfo.size() + hat * 2) + 1] = y;
  }
 }
}