ホーム > DirectInput > 直接データでジョイスティックの状態を取得

直接データでジョイスティックの状態を取得

目次

  1. 初期化
  2. デバイスの状態を取得
  3. 終了処理
  4. 最後に

初期化

共通の処理DirectInput8オブジェクトの作成からアクセス権の取得とほぼ同じ処理をします。使用可能なGUIDを調べる、軸の範囲の設定、の2つ処理を追加します。

ジョイスティックのデバイスの作成は、使用可能なGUIDを調べる必要があります。

// デバイスを列挙して作成
LPDIRECTINPUTDEVICE8 g_lpDIDevice = NULL;
g_lpDI->EnumDevices( DI8DEVCLASS_GAMECTRL, EnumJoysticksCallback,
                     NULL, DIEDFL_ATTACHEDONLY );
// ジョイスティックを列挙して作成する関数
BOOL CALLBACK EnumJoysticksCallback( const DIDEVICEINSTANCE* lpddi, LPVOID lpContext )
{
  HRESULT hr;

  // 列挙されたジョイスティックへのインターフェイスを取得する。
  hr = g_lpDI->CreateDevice( lpddi->guidInstance, &g_lpDIDevice, NULL );
  if( FAILED(hr) )  return DIENUM_CONTINUE;

  // ジョイスティックの能力を調べる
  g_diDevCaps.dwSize = sizeof(DIDEVCAPS);
  hr = g_lpDIDevice->GetCapabilities( &g_diDevCaps );
  if( FAILED(hr) )
  {
    // ジョイスティック能力の取得に失敗
    RELEASE( g_lpDIDevice );
    return DIENUM_CONTINUE;
  }

  //
  // このジョイスティックを使用するか、能力を調べる
  //

  // このデバイスを使用
  return DIENUM_STOP;
}

軸の動く範囲の最大値と最小値を設定します。

// コールバック関数を使って各軸のモードを設定
g_lpDIDevice->EnumObjects( EnumAxesCallback, NULL, DIDFT_AXIS );
// ジョイスティックの軸を列挙する関数
BOOL CALLBACK EnumAxesCallback( LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID lpvRef )
{
  HRESULT hr;

  // 軸の値の範囲を設定(-1000~1000)
  DIPROPRANGE diprg;
  ZeroMemory( &diprg, sizeof(diprg) );
  diprg.diph.dwSize       = sizeof(diprg); 
  diprg.diph.dwHeaderSize = sizeof(diprg.diph); 
  diprg.diph.dwObj        = lpddoi->dwType;
  diprg.diph.dwHow        = DIPH_BYID;
  diprg.lMin              = -1000;
  diprg.lMax              = +1000;
  hr = g_lpDIDevice->SetProperty( DIPROP_RANGE, &diprg.diph );
  if( FAILED(hr) )  return DIENUM_STOP;

  return DIENUM_CONTINUE;
}

デバイスの状態を取得

「IDirectInputDevice8::Poll」を呼び出してから、DIJOYSTATE構造体のポインタを渡して取得します。構造体の「dijs.lX」「dijs.lY」「dijs.lZ」にはジョイスティック(十字キー)の位置が、「rgbButtons」配列にはジョイスティックのボタンの状態が格納されていて、キーが押されたときに最上位ビットが1になります。ジョイスティックの十字キーとボタン1が押されているか判定するには下記のようにします。

// ジョイスティックの状態を取得
DIJOYSTATE dijs;
g_lpDIDevice->Poll();
g_lpDIDevice->GetDeviceState( sizeof(DIJOYSTATE), &dijs );

if( dijs.lX > +1000/2 )
{
  // 十字キーの右が押されている
}
else if( dijs.lX < -1000/2 )
{
  // 十字キーの左が押されている
}

if( dims.rgbButtons[0] & 0x80 )
{
  // ボタン1が押されている
}

終了処理

共通の処理 / 終了処理と同じ処理をします。

最後に

ここまでの手順でジョイスティックの状態を直接データで取得できます。キーボード、マウスを直接データで取得する方法とは若干違いがあるので少し難しいですね。ここの説明では分からない方の多いと思うのでサンプルを置いておきます。



inserted by FC2 system