しかし、テスト結果を見て、パッドによりボタンの番号の振り方が違うことが分かりました。
そこで、質問なのですが、どうやったらボタンの番号を統一できるのでしょうか?
例えば、PS2のコントローラーの▲に当たる場所のボタンを押したとき、全てのパッドが0番を返してくれるようにしたいということです。
もしくは、DirectXでのパッド入力より、パッド入力が出来る他のライブラリなどをお借りした方がいいのでしょうか?
もし、お借りした方がいい場合、どのライブラリをお借りすればよろしいのでしょうか?
あと、もう一つ質問があるのですが、このパッドクラスはWinMain関数の最後で、ちゃんとデストラクタを実行してくれますよね?
↓追記
OS:Windows10
コンパイラ:VisualStudio2010
言語:C++
ライブラリ:DirectX SDK (June 2010)
Main.cpp
//インクルード
#include"d3dx9.h"
#include"Monitoring.h"
#include"Pad.h"
#pragma comment (lib, "d3d9.lib")
#pragma comment (lib, "d3dx9.lib")
#pragma comment (lib, "dxguid.lib")
#pragma comment (lib, "winmm.lib")
#pragma comment (lib, "dinput8.lib")
//定数定義
#define SCREEN_WIDTH (800)
#define SCREEN_HEIGHT (600)
#define CLASS_NAME "AppClass"
#define WINDOW_NAME "DirectX"
//グローバル変数
LPDIRECT3D9 g_pD3D = NULL;
LPDIRECT3DDEVICE9 g_pD3DDevice = NULL;
int g_nCountFPS = 0;
//プロトタイプ宣言
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
HRESULT Init(HINSTANCE hInstance, HWND hWnd, BOOL bWindow);
void Uninit();
void Update();
void Draw();
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){
WNDCLASSEX wcex = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0, 0, hInstance, NULL, LoadCursor(NULL, IDC_ARROW), (HBRUSH)(COLOR_WINDOW + 1), NULL, CLASS_NAME, NULL };
HWND hWnd;
MSG msg;
RegisterClassEx(&wcex);
hWnd = CreateWindowEx(0, CLASS_NAME, WINDOW_NAME, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, (SCREEN_WIDTH + GetSystemMetrics(SM_CXDLGFRAME) * 2), (SCREEN_HEIGHT + GetSystemMetrics(SM_CXDLGFRAME) * 2 + GetSystemMetrics(SM_CYCAPTION)), NULL, NULL, hInstance, NULL);
if(FAILED(Init(hInstance, hWnd, TRUE))){ return -1; }
DWORD dwExecLastTime;
DWORD dwFPSLastTime;
DWORD dwCurrentTime;
DWORD dwFrameCount;
timeBeginPeriod(1);
dwExecLastTime = dwFPSLastTime = timeGetTime();
dwCurrentTime = dwFrameCount = 0;
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
while(1){
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) != 0){
if(msg.message == WM_QUIT){
break;
}else{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}else{
dwCurrentTime = timeGetTime();
if((dwCurrentTime - dwFPSLastTime) >= 500){
g_nCountFPS = (dwFrameCount * 1000) / (dwCurrentTime - dwFPSLastTime);
dwFPSLastTime = dwCurrentTime;
dwFrameCount = 0;
}
if((dwCurrentTime - dwExecLastTime) >= (1000/60)){
dwExecLastTime = dwCurrentTime;
Update();
Draw();
dwFrameCount++;
}
}
}
UnregisterClass(CLASS_NAME, wcex.hInstance);
Uninit();
timeEndPeriod(1);
return (int)msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){
switch(uMsg){
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_KEYDOWN:
switch(wParam){
case VK_ESCAPE:
DestroyWindow(hWnd);
break;
}
break;
case WM_CLOSE:
DestroyWindow(hWnd);
break;
default:
break;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
HRESULT Init(HINSTANCE hInstance, HWND hWnd, BOOL bWindow){
D3DPRESENT_PARAMETERS d3dpp;
D3DDISPLAYMODE d3ddm;
g_pD3D = Direct3DCreate9(D3D_SDK_VERSION);
if(g_pD3D == NULL){
return E_FAIL;
}
if(FAILED(g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm))){
return E_FAIL;
}
ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.BackBufferWidth = SCREEN_WIDTH;
d3dpp.BackBufferHeight = SCREEN_HEIGHT;
d3dpp.BackBufferFormat = d3ddm.Format;
d3dpp.BackBufferCount = 1;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.Windowed = bWindow;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
if(bWindow){
d3dpp.FullScreen_RefreshRateInHz = 0;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
}else{
d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
}
if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &g_pD3DDevice))){
if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pD3DDevice))){
if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pD3DDevice))){
return E_FAIL;
}
}
}
g_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
g_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
g_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
g_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
g_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
g_pD3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
g_pD3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
MONITORING::Init(g_pD3DDevice);
PAD::Init(hInstance, hWnd);
return S_OK;
}
void Update(){
PAD::Update();
for(int i = 0; i < 100; i++){
if(PAD::Push(i)){
MONITORING::SetStr("InputButton:%d\n", i);
}
}
}
void Draw(){
g_pD3DDevice->Clear(0, NULL, (D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER), D3DCOLOR_RGBA(0,0,0,0), 1.0f, 0);
if(SUCCEEDED(g_pD3DDevice->BeginScene())){
MONITORING::SetStr("LX:%d\n", PAD::PositionX());
MONITORING::SetStr("LY:%d\n", PAD::PositionY());
MONITORING::SetStr("RX:%d\n", PAD::PositionRX());
MONITORING::SetStr("RY:%d\n", PAD::PositionRY());
MONITORING::SetStr("RgdwPOV:%d\n", PAD::RgdwPOV(0));
MONITORING::Draw();
g_pD3DDevice->EndScene();
}
g_pD3DDevice->Present(NULL, NULL, NULL, NULL);
}
void Uninit(){
if(g_pD3DDevice != NULL){
g_pD3DDevice->Release();
g_pD3DDevice = NULL;
}
if(g_pD3D != NULL){
g_pD3D->Release();
g_pD3D = NULL;
}
}
#include"Pad.h"
LPDIRECTINPUT8 PAD::pDInput;
DIJOYSTATE PAD::joyState[MAX_CONTROLER];
DIJOYSTATE PAD::joyStatePrev[MAX_CONTROLER];
LPDIRECTINPUTDEVICE8 PAD::pDIDevJoypad[MAX_CONTROLER];
int PAD::nJoypadNum;
BYTE PAD::joyStateTrigger[MAX_CONTROLER][32];
void PAD::Init(HINSTANCE hInst, HWND hWnd){
pDInput = NULL;
nJoypadNum = 0;
if(!pDInput){
DirectInput8Create(hInst, DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&pDInput, NULL);
}
int nLoop;
for(nLoop = 0; nLoop < MAX_CONTROLER; nLoop++)
pDIDevJoypad[nLoop] = NULL;
if(FAILED(pDInput->EnumDevices(DI8DEVCLASS_GAMECTRL, EnumJoyCallback, NULL, DIEDFL_ATTACHEDONLY)))
return ;
for(nLoop = 0; nLoop < MAX_CONTROLER; nLoop++){
if(pDIDevJoypad[nLoop] == NULL)
continue;
if(FAILED(pDIDevJoypad[nLoop]->SetDataFormat(&c_dfDIJoystick)))
return ;
if(FAILED(pDIDevJoypad[nLoop]->SetCooperativeLevel(hWnd, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND)))
return ;
pDIDevJoypad[nLoop]->Acquire();
}
return ;
}
PAD::~PAD(){
for(int nLoop = 0; nLoop < MAX_CONTROLER; nLoop++){
if(pDIDevJoypad[nLoop]){
pDIDevJoypad[nLoop]->Release();
pDIDevJoypad[nLoop] = NULL;
}
}
if(pDInput){
pDInput->Release();
pDInput = NULL;
}
}
void PAD::Update(){
int nLoop;
for(nLoop = 0; nLoop < MAX_CONTROLER; nLoop++){
joyStatePrev[nLoop] = joyState[nLoop];
if(pDIDevJoypad[nLoop]){
if(FAILED(pDIDevJoypad[nLoop]->GetDeviceState(sizeof(DIJOYSTATE), &joyState[nLoop])))
pDIDevJoypad[nLoop]->Acquire();
}
for(int i = 0; i < 32; i++){
if(joyState[nLoop].rgbButtons[i] & 0x80 && !(joyStatePrev[nLoop].rgbButtons[i] & 0x80)){
joyStateTrigger[nLoop][i] = 0x80;
} else {
joyStateTrigger[nLoop][i] = 0x00;
}
}
}
}
BOOL CALLBACK PAD::EnumJoyCallback(const DIDEVICEINSTANCE* lpddi, VOID* pvRef){
DIDEVCAPS diDevCaps;
if(FAILED(pDInput->CreateDevice(lpddi->guidInstance, &pDIDevJoypad[nJoypadNum], NULL)))
return DIENUM_CONTINUE;
diDevCaps.dwSize = sizeof(DIDEVCAPS);
if(FAILED(pDIDevJoypad[nJoypadNum]->GetCapabilities(&diDevCaps))){
if(pDIDevJoypad[nJoypadNum])
pDIDevJoypad[nJoypadNum]->Release();
pDIDevJoypad[nJoypadNum] = NULL;
return DIENUM_CONTINUE;
}
nJoypadNum++;
if(nJoypadNum == MAX_CONTROLER)
return DIENUM_STOP;
else
return DIENUM_CONTINUE;
}
bool PAD::Push(int button){
return (joyState[0].rgbButtons[button] & 0x80) ? true : false;
}
bool PAD::Tri(int button){
return (joyStateTrigger[0][button] & 0x80) ? true : false;
}
LONG PAD::PositionX(){
return joyState[0].lX;
}
LONG PAD::PositionY(){
return joyState[0].lY;
}
LONG PAD::PositionRX(){
return joyState[0].lRx;
}
LONG PAD::PositionRY(){
return joyState[0].lRy;
}
LONG PAD::Slider(int number){
return joyState[0].rglSlider[number];
}
DWORD PAD::RgdwPOV(int number){
return joyState[0].rgdwPOV[number];
}
#pragma once
#define DIRECTINPUT_VERSION (0x0800)
#include"dinput.h"
#define MAX_CONTROLER (2)
class PAD{
private:
static LPDIRECTINPUT8 pDInput;
static DIJOYSTATE joyState[MAX_CONTROLER];
static DIJOYSTATE joyStatePrev[MAX_CONTROLER];
static LPDIRECTINPUTDEVICE8 pDIDevJoypad[MAX_CONTROLER];
static int nJoypadNum;
static BYTE joyStateTrigger[MAX_CONTROLER][32];
static BOOL CALLBACK EnumJoyCallback(const DIDEVICEINSTANCE* lpddi, VOID* pvRef);
public:
~PAD();
static void Init(HINSTANCE hInst, HWND hWnd);
static void Update();
static bool Push(int button);
static bool Tri(int button);
static LONG PositionX();
static LONG PositionY();
static LONG PositionRX();
static LONG PositionRY();
static LONG Slider(int number);
static DWORD RgdwPOV(int number);
};
※ボタン配置はPS2コントローラーのもの
・パッド1(Logicool)
△:3
〇:1
×:0
□:2
L1:4
L2:反応なし
R1:5
R2:反応なし
L3:8
R3:9
スタート:6
セレクト:7
--------------------------
十字ボタン↑:0
十字ボタン→:9000
十字ボタン↓:18000
十字ボタン←:27000
左スティック:反応あり
右スティック:反応あり
・パッド2(ELECOM)
△:1
〇:3
×:2
□:0
L1:4
L2:6
R1:5
R2:7
L3:8
R3:9
スタート:10
セレクト:11
--------------------------
十字ボタン↑:0
十字ボタン→:9000
十字ボタン↓:18000
十字ボタン←:27000
左スティック:反応あり
右スティック:反応なし(常に値が0)
・パッド3(PS2コントローラ )
△:0
〇:1
×:2
□:3
L1:6
L2:4
R1:7
R2:5
L3:10
R3:11
スタート:8
セレクト:9
--------------------------
十字ボタン↑:0
十字ボタン→:9000
十字ボタン↓:18000
十字ボタン←:27000
左スティック:反応あり
右スティック:反応なし(常に値が0)