|
|
2006/10/16 上午 12:45:57
Joystick搖桿兩的如何寫 我現在一支的是正常沒問題,但是我要做雙打的,請問一下我程式要如何改?
case JOYSTICK: if(FAILED(m_Input->GetDirectInputCOM()->EnumDevices(DI8DEVCLASS_GAMECTRL, EnumJoysticks, this, DIEDFL_ATTACHEDONLY))) return FALSE; if(m_pDIDevice == NULL) return FALSE; DataFormat = (DIDATAFORMAT*)&c_dfDIJoystick; break;
// Set the windowed usage m_Windowed = Windowed;
// Set the data format of keyboard if(FAILED(m_pDIDevice->SetDataFormat(DataFormat))) return FALSE;
// Set the cooperative level - Foreground & Nonexclusive if(FAILED(m_pDIDevice->SetCooperativeLevel(m_Input->GethWnd(), DISCL_FOREGROUND | DISCL_NONEXCLUSIVE))) return FALSE;
// Set the special properties if it's a joystick if(Type == JOYSTICK) { // Set the special properties of the joystick - range DIprg.diph.dwSize = sizeof(DIPROPRANGE); DIprg.diph.dwHeaderSize = sizeof(DIPROPHEADER); DIprg.diph.dwHow = DIPH_BYOFFSET; //DIprg.diph.dwHow = DIPH_BYID; DIprg.lMin = -1024; DIprg.lMax = +1024;
// Set X range DIprg.diph.dwObj = DIJOFS_X; if(FAILED(m_pDIDevice->SetProperty(DIPROP_RANGE, &DIprg.diph))) return FALSE;
// Set Y rangine DIprg.diph.dwObj = DIJOFS_Y; if(FAILED(m_pDIDevice->SetProperty(DIPROP_RANGE, &DIprg.diph))) return FALSE;
// Set the special properties of the joystick - deadzone 12% DIpdw.diph.dwSize = sizeof(DIPROPDWORD); DIpdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); DIpdw.diph.dwHow = DIPH_BYOFFSET; DIpdw.dwData = 128; // Set X deadzone DIpdw.diph.dwObj = DIJOFS_X; if(FAILED(m_pDIDevice->SetProperty(DIPROP_DEADZONE, &DIpdw.diph))) return FALSE;
// Set Y deadzone DIpdw.diph.dwObj = DIJOFS_Y; if(FAILED(m_pDIDevice->SetProperty(DIPROP_DEADZONE, &DIpdw.diph))) return FALSE;
|
|
|
|
2006/10/16 上午 12:47:04
有沒有書有寫道兩個搖桿的,或範例?
|
|
|
2006/10/16 上午 09:03:10
1. 引用的標頭檔 #define DIRECTINPUT_VERSION 0x0800 #include <dinput.h>
2.使用的程式庫 #pragma comment (lib, "dinput8.lib") #pragma comment (lib, "dxguid.lib")
3. 搖捍裝置儲存區 #define MAX_JOYSTICKS (2) static LPDIRECTINPUTDEVICE8 m_pJoystick[MAX_JOYSTICKS]; static DWORD m_dwTotalJoysticks;
4. 列舉搖捍裝置時,建立搖捍裝置 static BOOL CALLBACK EnumJoysticksCallback(LPCDIDEVICEINSTANCE pInst, LPVOID pvContext) { DWORD index; HRESULT hr; LPDIRECTINPUTDEVICE8 pdev; DIPROPRANGE diprg;
index = m_dwTotalJoysticks; if(index >= MAX_JOYSTICKS) return DIENUM_STOP;
/* 建立搖捍裝置 */ hr = m_pDI->CreateDevice(pInst->guidInstance, &pdev, NULL); if( FALSE(hr) ) return DIENUM_CONTINUE;
m_pJoystick[index] = pdev;
/* 設定搖捍裝置格式 */ hr = m_pJoystick[index]->SetDataFormat(&c_dfDIJoystick); if( FAILED(hr) ) { m_pJoystick[index]->Release(); m_pJoystick[index] = NULL; return DIENUM_CONTINUE; }
/* 設定搖捍裝置合作層級 */ hr = m_pJoystick[index]->SetCooperativeLevel(m_hWnd, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND); if( FAILED(hr) ) { m_pJoystick[index]->Release(); m_pJoystick[index] = NULL; return DIENUM_CONTINUE; }
/* 設定搖捍裝置特性 */ diprg.diph.dwSize = sizeof(DIPROPRANGE); diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER); diprg.diph.dwHow = DIPH_BYOFFSET; diprg.lMin = -1000; diprg.lMax = +1000;
diprg.diph.dwObj = DIJOFS_X; m_pJoystick[index]->SetProperty(DIPROP_RANGE, &diprg.diph); diprg.diph.dwObj = DIJOFS_Y; m_pJoystick[index]->SetProperty(DIPROP_RANGE, &diprg.diph);
/* 搖捍裝置取得 */ if(m_pJoystick[index]) { m_pJoystick[index]->Acquire(); }
m_dwTotalJoysticks++;
return DIENUM_CONTINUE; }
5. 列舉搖捍裝置 hr = m_pDI->EnumDevices(DI8DEVCLASS_GAMECTRL, EnumJoysticksCallback, NULL, DIEDFL_ATTACHEDONLY); if( FALSE(hr) ) { return hr; }
6. 偵測搖捍裝置 for(i=0; i<MAX_JOYSTICKS; i++) { if(m_pJoystick[i]) { hr = m_pJoystick[i]->Poll(); if( FALSE(hr) ) return;
hr = m_pJoystick[i]->GetDeviceState(sizeof(DIJOYSTATE), &dijs); if( FALSE(hr) ) { m_pJoystick[i]->Acquire(); return; }
/* 左 */ if(dijs.lX < 0) {
} /* 右 */ if(dijs.lX > 0) {
} /* 上 */ if(dijs.lY < 0) {
} /* 下 */ if(dijs.lY > 0) {
} /* 按鈕 */ bPress = (BOOL)(dijs.rgbButtons[buttonid] & 0x80); if(bPress) {
} } }
|
|
|
|
2006/10/18 上午 08:13:04
我照你的方式改了,當我指定nIndex=1(第二個搖桿)去GetPOV(1),都是讀到第一個搖桿的值 第二個搖桿感覺好像沒作用
for (short nJoystick=0;nJoystick<MAX_JOYSTICKS;nJoystick++) { m_pDIDevice_Jokstick[nJoystick]=NULL; m_JoystickState[nJoystick] = (DIJOYSTATE*)&m_State_Joystick[nJoystick]; }
DWORD GetPOV(short nIndex) { return m_JoystickState[nIndex]->rgdwPOV[0]; }
BOOL cInputDevice::ReadJoystick() { HRESULT hr; long BufferSizes[3] = { 256, sizeof(DIMOUSESTATE), sizeof(DIJOYSTATE) }; short i;
for (short nJoystick=0;nJoystick<m_dwTotalJoysticks;nJoystick++) { // Make sure to have a valid IDirectInputDevice8 object if(m_pDIDevice_Jokstick[nJoystick] == NULL) return FALSE;
// Make sure device type if in range if(m_Type < 1 || m_Type > 3) return FALSE;
// Loop polling and reading until succeeded or unknown error // Also take care of lost-focus problems while(1) { // Poll m_pDIDevice_Jokstick[nJoystick]->Poll();
// Read in state if(SUCCEEDED(hr = m_pDIDevice_Jokstick[nJoystick]->GetDeviceState(BufferSizes[m_Type-1], (LPVOID)&m_State_Joystick[nJoystick]))) break;
// Return on an unknown error if(hr != DIERR_INPUTLOST && hr != DIERR_NOTACQUIRED) return FALSE;
// Reacquire and try again if(FAILED(m_pDIDevice_Jokstick[nJoystick]->Acquire())) return FALSE; }
// Since only the mouse coordinates are relative, you'll // have to deal with them now
// Released keys and button need to be unlocked switch(m_Type) { case KEYBOARD: for(i=0;i<256;i++) { if(!(m_State[i] & 0x80)) m_Locks[i] = FALSE; } break; case MOUSE: for(i=0;i<4;i++) { if(!(m_MouseState->rgbButtons[i])) m_Locks[i] = FALSE; } break; case JOYSTICK: for(i=0;i<JOYSTICK_BUTTON;i++) { if(!(m_JoystickState[nJoystick]->rgbButtons[i])) m_Locks_Joystick[nJoystick][i] = FALSE; } break; } }
// return a success return TRUE; }
|
|
|
|
2006/10/18 上午 09:26:22
1. 引用的標頭檔 #define DIRECTINPUT_VERSION 0x0800 #include <dinput.h>
2.使用的程式庫 #pragma comment (lib, "dinput8.lib") #pragma comment (lib, "dxguid.lib")
3. DirectInput 裝置類別 #define MAX_JOYSTICKS (2) class cInputDevice { public: cInputDevice(); ~cInputDevice(); BOOL Create(HWND hWnd); BOOL SyncAcquire(BOOL bSync); BOOL JoystickDetect(void); BOOL JoystickPressLeft(int id); BOOL JoystickPressRight(int id); BOOL JoystickPressUp(int id); BOOL JoystickPressDown(int id); BOOL JoystickPressButton(int id, int buttonid);
private: HWND m_hWnd; LPDIRECTINPUT8 m_pDI; LPDIRECTINPUTDEVICE8 m_pJoystick[MAX_JOYSTICKS]; DWORD m_dwTotalJoysticks; DIJOYSTATE m_JoystickState[MAX_JOYSTICKS]; };
|
|
|
|
2006/10/18 上午 09:27:12
4. 類別初始化和結束 cInputDevice::cInputDevice() { int i;
m_hWnd = NULL; m_pDI = NULL;
for(i=0; i<MAX_JOYSTICKS; i++) { m_pJoystick[i] = NULL;
memset(&m_JoystickState[i], 0, sizeof(DIJOYSTATE)); } m_dwTotalJoysticks = 0; }
cInputDevice::~cInputDevice() { int i;
for(i=0; i<MAX_JOYSTICKS; i++) { if(m_pJoystick[i]) { m_pJoystick[i]->Unacquire(); m_pJoystick[i]->Release(); m_pJoystick[i] = NULL;
memset(&m_JoystickState[i], 0, sizeof(DIJOYSTATE)); } } m_dwTotalJoysticks = 0;
m_hWnd = NULL; }
|
|
|
|
2006/10/18 上午 09:28:24
5. 列舉搖捍裝置時,建立搖捍裝置 static BOOL CALLBACK EnumJoysticksCallback(LPCDIDEVICEINSTANCE pInst, LPVOID pvContext) { cInputDevice *pDirectInput; DWORD index; HRESULT hr; LPDIRECTINPUTDEVICE8 pdev; DIPROPRANGE diprg;
pDirectInput = (cInputDevice*)pvContext; if(pDirectInput == NULL) return DIENUM_STOP;
index = pDirectInput->m_dwTotalJoysticks; if(index >= MAX_JOYSTICKS) return DIENUM_STOP;
/* 建立 DirectInput 搖捍裝置 */ hr = pDirectInput->m_pDI->CreateDevice(pInst->guidInstance, &pdev, NULL); if( FALSE(hr) ) return DIENUM_CONTINUE;
pDirectInput->m_pJoystick[index] = pdev;
/* 設定 DirectInput 搖捍裝置格式 */ hr = pDirectInput->m_pJoystick[index]->SetDataFormat(&c_dfDIJoystick); if( FAILED(hr) ) { pDirectInput->m_pJoystick[index]->Release(); pDirectInput->m_pJoystick[index] = NULL; return DIENUM_CONTINUE; }
/* 設定 DirectInput 搖捍裝置合作層級 */ hr = pDirectInput->m_pJoystick[index]->SetCooperativeLevel(pDirectInput->m_hWnd, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND); if( FAILED(hr) ) { pDirectInput->m_pJoystick[index]->Release(); pDirectInput->m_pJoystick[index] = NULL; return DIENUM_CONTINUE; }
/* 設定 DirectInput 搖捍裝置特性 */ diprg.diph.dwSize = sizeof(DIPROPRANGE); diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER); diprg.diph.dwHow = DIPH_BYOFFSET; diprg.lMin = -1000; diprg.lMax = +1000;
diprg.diph.dwObj = DIJOFS_X; pDirectInput->m_pJoystick[index]->SetProperty(DIPROP_RANGE, &diprg.diph); diprg.diph.dwObj = DIJOFS_Y; pDirectInput->m_pJoystick[index]->SetProperty(DIPROP_RANGE, &diprg.diph);
/* DirectInput 搖捍裝置取得 */ if(pDirectInput->m_pJoystick[index]) { pDirectInput->m_pJoystick[index]->Acquire(); }
pDirectInput->m_dwTotalJoysticks++;
return DIENUM_CONTINUE; }
|
|
|
|
2006/10/18 上午 09:29:26
6. 建立裝置 BOOL cInputDevice::Create(HWND hWnd) { HINSTANCE hInstance; HRESULT hr;
hInstance = GetWindowInstance(hWnd);
/* 建立 DirectInput */ hr = DirectInput8Create(hInstance, DIRECTINPUT_VERSION, IID_IDirectInput8, (VOID**)&m_pDI, NULL); if( FALSE(hr) ) { return FALSE; }
m_hWnd = hWnd;
/* DirectInput 列舉搖捍裝置 */ hr = m_pDI->EnumDevices(DI8DEVCLASS_GAMECTRL, EnumJoysticksCallback, this, DIEDFL_ATTACHEDONLY); if( FALSE(hr) ) { return FALSE; }
return TRUE; }
7. 裝置需求設定 BOOL cInputDevice::SyncAcquire(BOOL bSync) { INT i;
if(bSync) { for(i=0; i<MAX_JOYSTICKS; i++) { if(m_pJoystick[i]) m_pJoystick[i]->Acquire(); } } else { for(i=0; i<MAX_JOYSTICKS; i++) { if(m_pJoystick[i]) m_pJoystick[i]->Unacquire(); } }
return TRUE; }
|
|
|
|
2006/10/18 上午 09:31:08
8. 偵測搖捍裝置(放於主程式迴圈) BOOL cInputDevice::JoystickDetect(void) { DWORD i; DIJOYSTATE dijs; HRESULT hr;
for(i=0; i<MAX_JOYSTICKS; i++) { if(m_pJoystick[i]) { hr = m_pJoystick[i]->Poll(); if( FALSE(hr) ) return FALSE;
hr = m_pJoystick[i]->GetDeviceState(sizeof(DIJOYSTATE), &dijs); if( FALSE(hr) ) return FALSE;
memcpy(&m_JoystickState[i], &dijs, sizeof(DIJOYSTATE)); /* 記錄起來 */ } } return TRUE; }
9. 叛斷搖捍按鈕 BOOL cInputDevice::JoystickPressLeft(int id) { if(m_pJoystick[id]) { /* 左 */ if(m_JoystickState[id].lX < 0) return TRUE; } return FALSE; } BOOL cInputDevice::JoystickPressRight(int id) { if(m_pJoystick[id]) { /* 右 */ if(m_JoystickState[id].lX > 0) return TRUE; return FALSE; } } BOOL cInputDevice::JoystickPressUp(int id) { if(m_pJoystick[id]) { /* 上 */ if(m_JoystickState[id].lY < 0) return TRUE; return FALSE; } } BOOL cInputDevice::JoystickPressDown(int id) { if(m_pJoystick[id]) { /* 下 */ if(m_JoystickState[id].lY > 0) return TRUE; return FALSE; } } BOOL cInputDevice::JoystickPressButton(int id, int buttonid) { if(m_pJoystick[id]) { /* 按鈕 if((BOOL)(m_JoystickState[id].rgbButtons[buttonid] & 0x80)) { return TRUE; } } return FALSE; }
|
|
|
|
2006/10/19 下午 05:05:38
EnumJoysticksCallback這個函數需要呼叫兩次對嗎?
|
|
|
|
2006/10/19 下午 06:25:55
>EnumJoysticksCallback這個函數需要呼叫兩次對嗎?
可能會被呼叫多次,因為他會送電腦上目前連接所有輸入裝置進來給你挑選..... 鍵盤 or 滑鼠 or 搖桿 or GamePAD
|
|
|
|
2006/10/19 下午 06:32:31
沒看到 DI8DEVCLASS_GAMECTRL 只有搖桿類
送電腦上目前連接所有搖桿類輸入裝置進來給你挑選..... 搖桿 or GamePAD
|
|
|
|
2006/10/20 上午 08:28:51
>EnumJoysticksCallback這個函數需要呼叫兩次對嗎? 那是你呼叫 EnumDevices 時,EnumDevices 有找到裝置就會去呼叫你掛的EnumJoysticksCallback,讓你做些相關設定。
|
|
|
|
2006/10/20 下午 05:25:04
我的概念是建立兩個搖桿物件m_Joystick[2]; 我發現這兩個物件的GUID都是一樣GUID={EBC82EE0-6040-11DB-8001-444553540000},這樣是不是都指到同一個搖桿
m_Input.Init(hwnd, hInstance); m_Joystick[ONE_PLAYER].Create(&m_Input, JOYSTICK, TRUE); m_Joystick[TWO_PLAYER].Create(&m_Input, JOYSTICK, TRUE);
VOID DXUtil_ConvertGUIDToString(const GUID* pGuidIn, TCHAR* strOut ) { _stprintf( strOut, TEXT("{%0.8X-%0.4X-%0.4X-%0.2X%0.2X-%0.2X%0.2X%0.2X%0.2X%0.2X%0.2X}"), pGuidIn->Data1, pGuidIn->Data2, pGuidIn->Data3, pGuidIn->Data4[0], pGuidIn->Data4[1], pGuidIn->Data4[2], pGuidIn->Data4[3], pGuidIn->Data4[4], pGuidIn->Data4[5], pGuidIn->Data4[6], pGuidIn->Data4[7] ); }
BOOL FAR PASCAL cInputDevice::EnumJoysticks(LPCDIDEVICEINSTANCE pdInst, LPVOID pvRef) { cInputDevice *Input;
// Stop enumeration if no parent cInputDevice pointer if((Input = (cInputDevice*)pvRef) == NULL) return DIENUM_STOP;
// Try to create a joystick interface if(FAILED(Input->m_Input->GetDirectInputCOM()->CreateDevice(pdInst->guidInstance, &Input->m_pDIDevice, NULL))) return DIENUM_CONTINUE;
TCHAR strOut[128];
DXUtil_ConvertGUIDToString(&pdInst->guidInstance,strOut);
DXUTOutputDebugString(L"GUID=%s\n",strOut);
// All done - stop enumeration return DIENUM_STOP; }
|
|
|
|
2006/10/20 下午 08:59:02
你的列舉的CallBack寫錯了 =.= 找到搖桿物件 建立裝置成功應該把他加入你的 List中 傳回 DIENUM_CONTINUE;
你剛好相反 if(建立失敗 ) return DIENUM_CONTINUE; else 成功 印出 GUID return DIENUM_STOP;
這樣你只找到第一隻搖桿就停止enum了
|
|
|
|
2006/10/24 下午 07:29:58
static BOOL CALLBACK EnumJoysticksCallback(LPCDIDEVICEINSTANCE pInst, LPVOID pvContext)
/* DirectInput 搖捍裝置取得 */ if(pDirectInput->m_pJoystick[index]) { hr=pDirectInput->m_pJoystick[index]->Acquire(); }
Acquire的hr(Poll的hr)都等於ERROR_INVALID_ACCESS(-2147024884),所以無法正確的取得資料
|
|
|
|
2006/10/24 下午 07:42:52
SyncAcquire是用之前就要呼叫一次嗎? 我的搖桿是PS2型的(三國無雙附贈的)
|
|
|
|
2006/10/25 上午 08:44:27
>SyncAcquire是用之前就要呼叫一次嗎? >我的搖桿是PS2型的(三國無雙附贈的)
如果你的視窗收到 case WM_ACTIVATE: if(LOWORD(wParam) == WA_INACTIVE || (BOOL)HIWORD(wParam)) { cInputDevice->SyncAcquire(FALSE); /* DirectInput 裝置不動作 */ } else { cInputDevice->SyncAcquire(TRUE); /* DirectInput 裝置動作 */ } return 0;
|
|
|
2006/10/26 下午 10:51:57
ref DX81 Samples\Multimedia\DirectInput\MultiMapper
|
|
|
|
2006/11/1 下午 05:19:38
7654321(0),我套用你的程式碼還是不行,你的兩支搖桿是ok的嗎? debug時acquire都會return access deny
|
|
|
|
2006/11/2 上午 07:44:43
>7654321(0),我套用你的程式碼還是不行,你的兩支搖桿是ok的嗎? >debug時acquire都會return access deny >
你要不要先到 控制台->遊戲選項 看看你的搖桿是否安裝沒問題?
|
|
|
|
2007/3/14 下午 04:02:04
调试时因为主窗口不是游戏窗口,所以acquire会失败。一旦切换回游戏窗口acquire就会成功。
|
|
|
|
|
|
|
|
| DirectX |
 |
|
| |
專家等級 |
評價 |
|
| |
一代宗師 |
10000 |
|
| |
曠世奇才 |
5000 |
|
| |
頂尖高手 |
3000 |
|
| |
卓越專家 |
1500 |
|
| |
優秀好手 |
750 |
|
|
|
|
|
|
|
|
|
|
|
|
Microsoft Internet Explorer
6.0. Screen 1024x768 pixel. High Color (16 bit).
2000-2013 程式設計俱樂部 http://www.programmer-club.com.tw/ |
|
|