予告どおり入力の処理です。
入力はDirectInputを使います。なんかクラス見たらDirectX8のまま変わってなかったんで楽勝、と思ったらやっぱり微妙に違う(汗) まぁほぼ手直し無しで済んだけどね。
今回もDirectXに依存する部分をCInputBaseクラス、入力を処理する部分をCInputクラスに分けます。使うデバイスはキーボードとゲームパッドです。使うボタンはキーボードはテンキーと十字キー、あとZとXとCのボタンにします。ゲームパッドの方は十字キーと0と1と2のボタンです。
キーボードは簡単に初期化出来るんだけど、ゲームパッドはモノによってボタンや十字キー(もしくはアナログスティック)の数が違うので、コールバックで再帰的に設定します。まあ定型処理だし、最低限のボタンしか使わないから、関係ないけどね。
今回はCInputBaseだけ組んで、次回CInputで実際に入力キーを取り出します。
//--------------------------------------------------------- // 初期化 BOOL CInputBase::Init(HWND hWnd) { HRESULT hr; // DirectInputオブジェクトを作成する hr=DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&DInput, NULL); if FAILED(hr) { MessageBox(NULL, "DirectInputオブジェクトの生成に失敗しました", "CInputBase::Init", MB_OK); return E_FAIL; } // キーボードの初期化 hr=InitKeyboard(hWnd); if FAILED(hr) { return E_FAIL; } // ジョイスティックの初期化 hr=InitJoystick(hWnd); if FAILED(hr) { return E_FAIL; } return S_OK; } //--------------------------------------------------------- // キーボードの初期化 BOOL CInputBase::InitKeyboard(HWND hWnd) { HRESULT hr; // キーボードデバイスを取得する hr=DInput->CreateDevice(GUID_SysKeyboard, &DIKeyboard, NULL); if FAILED(hr) { MessageBox(NULL, "DirectInputキーボードデバイスの生成に失敗しました", "CInputBase::InitKeyboard", MB_OK); TermDInput(); return E_FAIL; } // キーボードのデータ形式を設定する hr=DIKeyboard->SetDataFormat(&c_dfDIKeyboard); if FAILED(hr) { MessageBox(NULL, "DirectInputキーボードのデータ形式の取得に失敗しました", "CInputBase::InitKeyboard", MB_OK); TermDInput(); return E_FAIL; } // キーボードの協調レベルを設定する hr=DIKeyboard->SetCooperativeLevel(hWnd, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE); if FAILED(hr) { MessageBox(NULL, "DirectInputキーボードの強調レベルの取得に失敗しました", "CInputBase::InitKeyboard", MB_OK); TermDInput(); return E_FAIL; } // キーボードの入力デバイスにアクセスする hr=DIKeyboard->Acquire(); if FAILED(hr) { MessageBox(NULL, "DirectInputキーボードへのアクセスに失敗しました", "CInputBase::InitKeyboard", MB_OK); TermDInput(); return E_FAIL; } return S_OK; } //--------------------------------------------------------- // ジョイスティックの初期化 BOOL CInputBase::InitJoystick(HWND hWnd) { HRESULT hr; DIDEVCAPS g_DevCaps; //ジョイスティックのコールバック設定 hr=DInput->EnumDevices(DI8DEVCLASS_GAMECTRL, EnumJoysticksCallback, NULL, DIEDFL_ATTACHEDONLY); if FAILED(hr) { MessageBox(NULL, "DirectInputジョイスティックコールバックの生成に失敗しました", "CInputBase::InitJoystick", MB_OK); TermDInput(); return E_FAIL; } // ジョイスティックが存在しているか? if (DIJoystick==NULL) { return S_OK; } // ジョイスティックのデータ形式を設定する hr=DIJoystick->SetDataFormat(&c_dfDIJoystick); if FAILED(hr) { MessageBox(NULL, "DirectInputジョイスティックのデータ形式の取得に失敗しました", "CInputBase::InitJoystick", MB_OK); TermDInput(); return E_FAIL; } // ジョイスティックの協調レベルを設定する hr=DIJoystick->SetCooperativeLevel(hWnd, DISCL_BACKGROUND | DISCL_EXCLUSIVE); if FAILED(hr) { MessageBox(NULL, "DirectInputジョイスティックの強調レベルの取得に失敗しました", "CInputBase::InitJoystick", MB_OK); TermDInput(); return E_FAIL; } // ジョイスティックの能力を取得する g_DevCaps.dwSize = sizeof(DIDEVCAPS); hr=DIJoystick->GetCapabilities(&g_DevCaps); if FAILED(hr) { MessageBox(NULL, "DirectInputジョイスティックの能力の取得に失敗しました", "CInputBase::InitJoystick", MB_OK); TermDInput(); return E_FAIL; } // 全ての軸を列挙する hr=DIJoystick->EnumObjects(EnumAxesCallback, (void*)hWnd, DIDFT_AXIS); if FAILED(hr) { MessageBox(NULL, "DirectInputジョイスティックの軸の列挙に失敗しました", "CInputBase::InitJoystick", MB_OK); TermDInput(); return E_FAIL; } // ジョイスティックの入力デバイスにアクセスする hr=DIJoystick->Acquire(); if FAILED(hr) { MessageBox(NULL, "DirectInputジョイスティックへのアクセスに失敗しました", "CInputBase::InitJoystick", MB_OK); TermDInput(); return E_FAIL; } return S_OK; } //--------------------------------------------------------- // ジョイスティック列挙コールバック BOOL CALLBACK EnumJoysticksCallback(const DIDEVICEINSTANCE* pdidInstance, VOID* pContext) { HRESULT hr; // ジョイスティックデバイスを取得する hr=System->Input->DInput->CreateDevice(pdidInstance->guidInstance, &System->Input->DIJoystick, NULL ); if FAILED(hr) { return DIENUM_CONTINUE; } // ジョイスティックが取得できたらこの関数は呼び出されなくなる return DIENUM_STOP; } //--------------------------------------------------------- // ジョイスティック軸列挙コールバック BOOL CALLBACK EnumAxesCallback(const DIDEVICEOBJECTINSTANCE* pdidoi, VOID* pContext) { HWND hDlg=(HWND)pContext; DIPROPRANGE diprg; diprg.diph.dwSize = sizeof(DIPROPRANGE); diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER); diprg.diph.dwHow = DIPH_BYID; diprg.diph.dwObj = pdidoi->dwType; // Specify the enumerated axis diprg.lMin = -1000; diprg.lMax = +1000; // ジョイスティックデバイスを設定する if (FAILED(System->Input->DIJoystick->SetProperty(DIPROP_RANGE, &diprg.diph))) { return DIENUM_STOP; } return DIENUM_CONTINUE; } //--------------------------------------------------------- // DirectInput解放 void CInputBase::TermDInput() { if (DInput) { if (DIKeyboard) { // Release()を呼び出す前は常にデバイスを解放する DIKeyboard->Unacquire(); DIKeyboard->Release(); DIKeyboard=NULL; } if (DIJoystick) { // Release()を呼び出す前は常にデバイスを解放する DIJoystick->Unacquire(); DIJoystick->Release(); DIJoystick=NULL; } DInput->Release(); DInput=NULL; } } //--------------------------------------------------------- // キーボード入力取得 BOOL CInputBase::ProcessKeyboard(char *buffer) { HRESULT hr; if (DIKeyboard==NULL) { return E_FAIL; } // キーボードステータス取得 hr=DIKeyboard->GetDeviceState(256/*sizeof(buffer)*/,(LPVOID)buffer); if FAILED(hr) { return E_FAIL; } return S_OK; } //--------------------------------------------------------- // ジョイスティック入力取得 BOOL CInputBase::ProcessJoystick(DIJOYSTATE *js) { HRESULT hr; if (DIJoystick==NULL) { return E_FAIL; } // ジョイスティックポーリング hr=DIJoystick->Poll(); if FAILED(hr) { hr=DIJoystick->Acquire(); while(hr==DIERR_INPUTLOST) hr=DIJoystick->Acquire(); return E_FAIL; } // ジョイスティックステータス取得 hr=DIJoystick->GetDeviceState(sizeof(DIJOYSTATE), js); if FAILED(hr) { return E_FAIL; } return S_OK; }