#pragma comment(linker, "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")
#pragma comment(lib,"dinput8.lib")
#pragma comment(lib,"dxguid.lib")
#define DIRECTINPUT_VERSION 0x0800
#include <dinput.h>
#include <windows.h>
#include <GL/freeglut/freeglut.h>
#define WIDTH 320
#define HEIGHT 240
int x=150,y=80;
#define RELEASE(x) {if(x){(x)->Release();x=NULL;}}//安全に解放する
#define Range 1000
#define Threshold Range/4 //しきい値
// DirectInputの変数
LPDIRECTINPUT8 DInput = NULL; //DirectInput
LPDIRECTINPUTDEVICE8 DIDevice = NULL; //DirectInputデバイス
DIDEVCAPS DevCaps; //ジョイスティックの能力
#define DIDEVICE_BUFFERSIZE 100 //デバイスに設定するバッファ・サイズ
HWND hWnd2=NULL; //ウィンドウハンドル
HINSTANCE hinstance; //インスタンスのハンドル
DIJOYSTATE2 JOYPAD; //ジョイパッドデータ
//ジョイスティックを列挙する関数
BOOL CALLBACK EnumJoysticksCallback(const DIDEVICEINSTANCE* pdidInstance, VOID*
pContext)
{
// 列挙されたジョイスティックへのインターフェイスを取得する。
HRESULT hr = DInput->CreateDevice(pdidInstance->guidInstance,
&DIDevice, NULL);
if (FAILED(hr))return DIENUM_CONTINUE;
// ジョイスティックの能力を調べる
DevCaps.dwSize = sizeof(DIDEVCAPS);
hr = DIDevice->GetCapabilities(&DevCaps);
if (FAILED(hr)){
// ジョイスティック能力の取得に失敗
RELEASE(DIDevice);
return DIENUM_CONTINUE;
}
return DIENUM_STOP;
}
//ジョイスティックの軸を列挙する関数
BOOL CALLBACK EnumAxesCallback(LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID
pvRef)
{
//軸の値の範囲を設定(-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 = -Range;
diprg.lMax = +Range;
HRESULT hr = DIDevice->SetProperty(DIPROP_RANGE, &diprg.diph);
if (FAILED(hr))return DIENUM_STOP;
return DIENUM_CONTINUE;
}
//ウィンドウを検索してHWNDとHINSTANCEを得る
BOOL CALLBACK enumWindowsProc(HWND hWnd,LPARAM lParam)
{
HANDLE hModule=(HANDLE)GetWindowLong(hWnd,GWL_HINSTANCE);
if(GetModuleHandle(NULL)==hModule){
wchar_t ClassName[256];
GetClassNameW(hWnd,ClassName,sizeof(ClassName)/sizeof(ClassName[0]));
if(wcsncmp(ClassName,L"FREEGLUT",wcslen(ClassName))==0){
hWnd2=hWnd;
hinstance=(HINSTANCE)GetWindowLong(hWnd,GWL_HINSTANCE);
return FALSE;
}
}
return TRUE;
}
//DirectInputの初期化
bool Init_DirectInput(void)
{
//DirectInputの作成
HRESULT hr = DirectInput8Create(hinstance, DIRECTINPUT_VERSION,
IID_IDirectInput8, (void**)&DInput, NULL);
if (FAILED(hr)){
MessageBoxW(hWnd2,L"DirectInput8オブジェクトの作成に失敗",L"ERROR !!",MB_OK);
return false;
}
//デバイスを列挙して作成
hr = DInput->EnumDevices(DI8DEVCLASS_GAMECTRL, EnumJoysticksCallback, NULL,
DIEDFL_ATTACHEDONLY);
if (FAILED(hr) || DIDevice==NULL){
MessageBoxW(hWnd2,L"DirectInputDevice8オブジェクトの作成に失敗",L"ERROR !!",MB_OK);
return false;
}
//データ形式を設定
hr = DIDevice->SetDataFormat(&c_dfDIJoystick2);
if (FAILED(hr)){
MessageBoxW(hWnd2,L"c_dfDIJoystick2形式の設定に失敗",L"ERROR !!",MB_OK);
return false;
}
//モードを設定(フォアグラウンド&非排他モード)
hr = DIDevice->SetCooperativeLevel(hWnd2, DISCL_NONEXCLUSIVE |
DISCL_FOREGROUND);
if (FAILED(hr)){
MessageBoxW(hWnd2,L"フォアグラウンド&非排他モードの設定に失敗",L"ERROR !!",MB_OK);
return false;
}
//コールバック関数を使って各軸のモードを設定
hr = DIDevice->EnumObjects(EnumAxesCallback, NULL, DIDFT_AXIS);
if (FAILED(hr)){
MessageBoxW(hWnd2,L"軸モードの設定に失敗",L"ERROR !!",MB_OK);
return false;
}
//軸モードを設定(絶対値モードに設定。デフォルトなので必ずしも設定は必要ない)
DIPROPDWORD diprop;
diprop.diph.dwSize = sizeof(diprop);
diprop.diph.dwHeaderSize = sizeof(diprop.diph);
diprop.diph.dwObj = 0;
diprop.diph.dwHow = DIPH_DEVICE;
diprop.dwData = DIPROPAXISMODE_ABS;
hr = DIDevice->SetProperty(DIPROP_AXISMODE, &diprop.diph);
if (FAILED(hr)){
MessageBoxW(hWnd2,L"軸モードの設定に失敗",L"ERROR !!",MB_OK);
return false;
}
//バッファリング・データを取得するため、バッファ・サイズを設定
diprop.dwData = DIDEVICE_BUFFERSIZE;
hr = DIDevice->SetProperty(DIPROP_BUFFERSIZE, &diprop.diph);
if (FAILED(hr)){
MessageBoxW(hWnd2,L"バッファ・サイズの設定に失敗",L"ERROR !!",MB_OK);
return false;
}
//入力制御開始
DIDevice->Acquire();
return true;
}
void SquareFill2D(int x1,int y1,int x2, int y2){
glBegin(GL_QUADS);
glVertex2i(x1,y1);
glVertex2i(x2,y1);
glVertex2i(x2,y2);
glVertex2i(x1,y2);
glEnd();
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor4f(0.0f,0.0f,1.0f,1.0f);
SquareFill2D(x,y,x+50,y+50);
glutSwapBuffers();
}
void idle(void)
{
if (DIDevice!=NULL){
// デバイスの直接データを取得する
HRESULT hr = DIDevice->Poll();
if (FAILED(hr)){
hr = DIDevice->Acquire();
while (hr==DIERR_INPUTLOST)hr = DIDevice->Acquire();
}
hr = DIDevice->GetDeviceState(sizeof(DIJOYSTATE2), &JOYPAD);
if (SUCCEEDED(hr)){
//方向キー
if(JOYPAD.lX<-Threshold)x-=2;
if(JOYPAD.lX>Threshold)x+=2;
if(JOYPAD.lY<-Threshold)y-=2;
if(JOYPAD.lY>Threshold)y+=2;
//ボタン 128個まで 空制御 コピペ用
if(JOYPAD.rgbButtons[0]);//ボタン1
if(JOYPAD.rgbButtons[1]);//ボタン2
}
}
Sleep(1);
glutPostRedisplay();
}
void Init(){
glClearColor(1.0, 1.0, 1.0, 1.0);
glOrtho(0, WIDTH, HEIGHT, 0, -1, 1);
EnumWindows(enumWindowsProc,0);
Init_DirectInput();
}
int main(int argc, char *argv[])
{
glutInitWindowPosition(100, 100);
glutInitWindowSize(WIDTH, HEIGHT);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA);
glutCreateWindow("ジョイパッド");
glutDisplayFunc(display);
glutIdleFunc(idle);
Init();
glutMainLoop();
return 0;
}
|