Visual Studio2008を使っています。
ネットで調べたりして見様見真似でジョイスティックの入力取得をしようとしたんですが、うまくいきません。
ジョイスティックを接続していない状態でデバッグするとデータ形式の設定の所でランタイムエラーを吐いてしまいます。
存在しないジョイスティックの設定をしているのだから当然だとは思うのですが・・・このエラーを回避するにはどうしたらいいのでしょうか?
//=============================================================================
// ジョイスティックの初期化(さっぱりわからんでぇ)
//=============================================================================
HRESULT InitJoystick(HINSTANCE hInst, HWND hWnd)
{
HRESULT hr;
hr = g_pDInput->EnumDevices( DI8DEVCLASS_GAMECTRL, EnumJoysticksCallback, NULL, DIEDFL_ATTACHEDONLY);
// デバイスの作成
if(FAILED(hr))
{
MessageBox( hWnd, "デバイス作成失敗", "エラー", MB_OK);
return hr;
}
// データフォーマットの設定
hr = g_pDIDevJoystick->SetDataFormat(&c_dfDIJoystick2);
if(FAILED(hr))
{
MessageBox(hWnd, "ジョイスティックのデータ形式を設定できませんでした。", "エラー", MB_OK);
return hr;
}
hr = g_pDIDevJoystick->SetCooperativeLevel(hWnd, DISCL_EXCLUSIVE | DISCL_FOREGROUND);
if(FAILED(hr))
{
MessageBox(hWnd, "ジョイスティックの協調モードを設定できませんでした。", "エラー", MB_OK);
}
g_diDevCaps.dwSize = sizeof(DIDEVCAPS);
hr = g_pDIDevJoystick->GetCapabilities(&g_diDevCaps);
if(FAILED(hr))
{
MessageBox(hWnd, "ジョイスティックの能力を取得できませんでした。", "エラー", MB_OK);
return hr;
}
hr = g_pDIDevJoystick->EnumObjects(EnumAxesCallback, (VOID*)hWnd, DIDFT_AXIS);
if(FAILED(hr))
{
MessageBox(hWnd, "ジョイスティックの範囲を指定できませんでした。", "エラー", MB_OK);
return hr;
}
hr = g_pDIDevJoystick->Poll();
if(FAILED(hr))
{
hr = g_pDIDevJoystick->Acquire();
while(hr == DIERR_INPUTLOST){
hr = g_pDIDevJoystick->Acquire();
}
}
return S_OK;
}
//=============================================================================
// ジョイスティックの終了処理
//=============================================================================
void UninitJoystick(void){
if(g_pDIDevJoystick)
{
g_pDIDevJoystick->Unacquire();
g_pDIDevJoystick->Release();
g_pDIDevJoystick = NULL;
}
}
//=============================================================================
// ジョイスティックのコールバック関数
//=============================================================================
BOOL CALLBACK EnumJoysticksCallback( const DIDEVICEINSTANCE *pdidInstance , VOID *pContext )
{
HRESULT hr;
hr = g_pDInput->CreateDevice( pdidInstance->guidInstance , &g_pDIDevJoystick , NULL );
if ( FAILED( hr ) ) return DIENUM_CONTINUE;
return DIENUM_STOP;
}
//=============================================================================
// のコールバック関数
//=============================================================================
BOOL CALLBACK EnumAxesCallback( const DIDEVICEOBJECTINSTANCE *pdidoi , VOID *pContext )
{
HRESULT hr;
DIPROPRANGE diprg;
diprg.diph.dwSize = sizeof( DIPROPRANGE );
diprg.diph.dwHeaderSize = sizeof( DIPROPHEADER );
diprg.diph.dwHow = DIPH_BYID;
diprg.diph.dwObj = pdidoi->dwType;
diprg.lMin = 0 - 1000;
diprg.lMax = 0 + 1000;
hr = g_pDIDevJoystick->SetProperty( DIPROP_RANGE , &diprg.diph );
if ( FAILED( hr ) ) return DIENUM_STOP;
return DIENUM_CONTINUE;
}
HRESULT UpdateJoystick(){
DIJOYSTATE joystick;
HRESULT hr;
char keyStateOld[36];
if(NULL == g_pDIDevJoystick) return FALSE;
hr = g_pDIDevJoystick->Poll();
if(FAILED(hr)) return E_FAIL;
// 押されたボタンの取得
hr = g_pDIDevJoystick->GetDeviceState(sizeof(DIJOYSTATE), &joystick);
if(FAILED(hr)) return E_FAIL;
memcpy(&g_jsKeyState[0], &joystick.rgbButtons[0], JS_KEY_MAX);
if(joystick.lY == -1000) g_jsKeyState[32] = true; // 十字キー上
else g_jsKeyState[32] = false;
if(joystick.lY == 1000) g_jsKeyState[33] = true; // 十字キー下
else g_jsKeyState[33] = false;
if(joystick.lX == -1000) g_jsKeyState[34] = true; // 十字キー左
else g_jsKeyState[34] = false;
if(joystick.lX == 1000) g_jsKeyState[35] = true; // 十字キー右
else g_jsKeyState[35] = false;
memcpy(&keyStateOld[0], &g_jsKeyState[0], JS_ALL_KEY_MAX);
for(int cnt=0; cnt<JS_ALL_KEY_MAX; ++cnt){
// トリガーとリリースの取得
g_jsKeyStateTrigger[cnt] = g_jsKeyState[cnt] & (g_keyState[cnt] ^ keyStateOld[cnt]);
g_jsKeyStateRelease[cnt] = keyStateOld[cnt] & (g_keyState[cnt] ^ keyStateOld[cnt]);
}
if(GetJoystickPress(DIJOFS_BUTTON1)){
return S_OK;
}
return S_OK;
}