前田稔(Maeda Minoru)の超初心者のプログラム入門
/*******************************************/ /*★ Direct Input Controller 前田 稔 ★*/ /*******************************************/ #define NAME "DirectX8 Input Controller2" #include <windows.h> #include <dinput.h> #pragma comment(lib,"dinput8.lib") #pragma comment(lib,"dxguid.lib") #define SAFE_RELEASE(p) { if (p) { (p)->Release(); (p)=NULL; } } //DirectInput Object LPDIRECTINPUT8 g_pDInput = NULL; // DirectInput LPDIRECTINPUTDEVICE8 g_pDIDev = NULL; // DirectInput デバイス-1 LPDIRECTINPUTDEVICE8 g_pDIDev2 = NULL; // DirectInput デバイス-2 //Global Area HWND g_hWnd; HINSTANCE g_Inst; bool g_bActive = FALSE; // ウインドウのアクティブ状態 POINT Pos,WPos; // 円の座標 POINT Pos2,WPos2; // 矩形の座標 DIDEVCAPS g_diDevCaps; // ジョイスティックの能力 |
// DirectInput 初期化 HRESULT InitDInput(void) { HRESULT hr; // DirectInputの作成 hr = DirectInput8Create(g_Inst, DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&g_pDInput, NULL); if (FAILED(hr)) { MessageBox(NULL,"DirectInput8オブジェクトの作成に失敗","Direct Input Error",MB_OK); return hr; } // デバイスを列挙して作成 hr = g_pDInput->EnumDevices(DI8DEVCLASS_GAMECTRL, EnumJoysticksCallback, NULL, DIEDFL_ATTACHEDONLY); if (FAILED(hr) || g_pDIDev==NULL || g_pDIDev2==NULL) { MessageBox(NULL,"DirectInputDevice8オブジェクトの作成に失敗","Direct Input Error",MB_OK); return hr; } // データ形式を設定 hr = g_pDIDev->SetDataFormat(&c_dfDIJoystick2); if (FAILED(hr)) { MessageBox(NULL,"c_dfDIJoystick2形式の設定に失敗","Direct Input Error",MB_OK); return hr; } hr = g_pDIDev2->SetDataFormat(&c_dfDIJoystick2); if (FAILED(hr)) { MessageBox(NULL,"c_dfDIJoystick2形式の設定に失敗","Direct Input Error",MB_OK); return hr; } // 協調モードを設定(フォアグラウンド&非排他モード) hr = g_pDIDev->SetCooperativeLevel(g_hWnd,DISCL_NONEXCLUSIVE | DISCL_FOREGROUND); if (FAILED(hr)) { MessageBox(NULL,"フォアグラウンド&非排他モードの設定に失敗","Direct Input Error",MB_OK); return hr; } hr = g_pDIDev2->SetCooperativeLevel(g_hWnd,DISCL_NONEXCLUSIVE | DISCL_FOREGROUND); if (FAILED(hr)) { MessageBox(NULL,"フォアグラウンド&非排他モードの設定に失敗","Direct Input Error",MB_OK); return hr; } // コールバック関数を使って各軸のモードを設定 hr = g_pDIDev->EnumObjects(EnumAxesCallback, NULL, DIDFT_AXIS); if (FAILED(hr)) { MessageBox(NULL,"軸モードの設定に失敗","Direct Input Error",MB_OK); return hr; } // コールバック関数を使って各軸のモードを設定 hr = g_pDIDev2->EnumObjects(EnumAxesCallback2, NULL, DIDFT_AXIS); if (FAILED(hr)) { MessageBox(NULL,"軸モードの設定に失敗-2","Direct Input Error",MB_OK); return hr; } // 入力制御開始 g_pDIDev->Acquire(); g_pDIDev2->Acquire(); return S_OK; } |
// ジョイスティックを列挙する関数 BOOL CALLBACK EnumJoysticksCallback(const DIDEVICEINSTANCE* pdidInstance, VOID* pContext) { HRESULT hr; // 列挙されたジョイスティックへのインターフェイスを取得する。 if (g_pDIDev==NULL) { hr = g_pDInput->CreateDevice(pdidInstance->guidInstance, &g_pDIDev, NULL); if (FAILED(hr)) return DIENUM_CONTINUE; // ジョイスティックの能力を調べる g_diDevCaps.dwSize = sizeof(DIDEVCAPS); hr = g_pDIDev->GetCapabilities(&g_diDevCaps); if (FAILED(hr)) { // ジョイスティック能力の取得に失敗 SAFE_RELEASE(g_pDIDev); } return DIENUM_CONTINUE; } if (g_pDIDev2==NULL) { hr = g_pDInput->CreateDevice(pdidInstance->guidInstance, &g_pDIDev2, NULL); if (FAILED(hr)) return DIENUM_CONTINUE; // ジョイスティックの能力を調べる g_diDevCaps.dwSize = sizeof(DIDEVCAPS); hr = g_pDIDev2->GetCapabilities(&g_diDevCaps); if (FAILED(hr)) { // ジョイスティック能力の取得に失敗 SAFE_RELEASE(g_pDIDev2); return DIENUM_CONTINUE; } } return DIENUM_STOP; } |
// Controller 入力 void KeyCheck() { DIJOYSTATE2 dijs; HRESULT hr; hr= g_pDIDev->GetDeviceState(sizeof(DIJOYSTATE2), &dijs); if (SUCCEEDED(hr)) { if (dijs.rgbButtons[0] & 0x80) PostMessage(g_hWnd,WM_CLOSE,0,0); //△ボタン if (dijs.rgbButtons[1] & 0x80) PostMessage(g_hWnd,WM_CLOSE,0,0); //○ボタン if (dijs.lX) Pos.x+= dijs.lX/1000; if (dijs.lY) Pos.y+= dijs.lY/1000; } else if (hr==DIERR_INPUTLOST) g_pDIDev->Acquire(); hr= g_pDIDev2->GetDeviceState(sizeof(DIJOYSTATE2), &dijs); if (SUCCEEDED(hr)) { if (dijs.rgbButtons[0] & 0x80) PostMessage(g_hWnd,WM_CLOSE,0,0); //△ボタン if (dijs.rgbButtons[1] & 0x80) PostMessage(g_hWnd,WM_CLOSE,0,0); //○ボタン if (dijs.lX) Pos2.x+= dijs.lX/1000; if (dijs.lY) Pos2.y+= dijs.lY/1000; } else if (hr==DIERR_INPUTLOST) g_pDIDev2->Acquire(); } |
// 描画処理 void Draw(void) { HDC hdc; RECT rect; if (Pos.x==WPos.x && Pos.y==WPos.y && Pos2.x==WPos2.x && Pos2.y==WPos2.y) return; GetWindowRect(g_hWnd,&rect); rect.right-= rect.left; rect.bottom-= rect.top; rect.left=rect.top= 0; hdc= GetDC(g_hWnd); FillRect(hdc,&rect,(HBRUSH)GetStockObject(BLACK_BRUSH)); Ellipse(hdc,Pos.x,Pos.y,Pos.x+50,Pos.y+50); Rectangle(hdc,Pos2.x,Pos2.y,Pos2.x+50,Pos2.y+50); ReleaseDC(g_hWnd,hdc); WPos= Pos; WPos2= Pos2; } |
// 終了の処理 void Cleanup() { if (g_pDIDev) g_pDIDev->Unacquire(); SAFE_RELEASE(g_pDIDev); if (g_pDIDev2) g_pDIDev2->Unacquire(); SAFE_RELEASE(g_pDIDev2); SAFE_RELEASE(g_pDInput); } |
// ウィンドウ処理 LRESULT CALLBACK MainWndProc(HWND hWnd,UINT msg,UINT wParam,LONG lParam) { switch(msg) { case WM_ACTIVATE: if (g_pDIDev==NULL) break; g_bActive= wParam!=WA_INACTIVE; if (wParam==WA_INACTIVE) { g_pDIDev->Unacquire(); g_pDIDev2->Unacquire(); } else { g_pDIDev->Acquire(); g_pDIDev2->Acquire(); } return 0L; case WM_DESTROY: PostQuitMessage(0); break; } return DefWindowProc(hWnd,msg,wParam,lParam); } |
前田稔(Maeda Minoru)の超初心者のプログラム入門