📄 gp_input.cpp
字号:
{
//缓冲数据
if((rgdod[i].dwData & 0x80)) //按下
{
KeyBuffer[KeyBuffer_End] = (BYTE)(rgdod[i].dwOfs);
KeyBuffer_End ++;
if( KeyBuffer_End >= KEYBUFFERSIZE ) //循环
KeyBuffer_End = 0;
}
else //释放+128
{
KeyBuffer[KeyBuffer_End] = (BYTE)(rgdod[i].dwOfs+128);
KeyBuffer_End ++;
if( KeyBuffer_End >= KEYBUFFERSIZE ) KeyBuffer_End = 0;
}
//即时数据
KeyState[rgdod[i].dwOfs] = (BYTE)(rgdod[i].dwData & 0x80);
}
}
}
//从缓冲区取一个值(0=无)
unsigned char WINAPI CKey::GetKey()
{
//缓冲区为空
if( KeyBuffer_Start == KeyBuffer_End )
return 0;
byte ret=KeyBuffer_Start;
KeyBuffer_Start++;
if( KeyBuffer_Start >= KEYBUFFERSIZE )
KeyBuffer_Start = 0;
return KeyBuffer[ret];
}
//清空键盘缓冲区
void WINAPI CKey::ReleaseKeyBuffer()
{
while(1)
{
GetKeyData();
if( GetKey()== 0 ) break;
}
}
//////////////////////////////////////////////////////////////////////////
// Joystick
//////////////////////////////////////////////////////////////////////////
#if USE_DX8
LPDIRECTINPUT8 CJoystick::g_pDI=NULL;
LPDIRECTINPUTDEVICE8 CJoystick::m_pJoystick=NULL;
#else
LPDIRECTINPUT7 CJoystick::g_pDI=NULL;
LPDIRECTINPUTDEVICE2 CJoystick::m_pJoystick=NULL;
#endif
DIDEVCAPS CJoystick::m_diDevCaps;
CJoystick::CJoystick()
{
memset( State, 0, MAXKEY );
memset( Buffer, 0, BUFFERSIZE );
Buffer_Start = Buffer_End = 0;
}
CJoystick::~CJoystick()
{
}
//媒举手柄的回调函数
BOOL CALLBACK EnumJoysticksCallback( const DIDEVICEINSTANCE* pdidInstance, VOID* pContext )
{
HRESULT hr;
// 得到一个被媒举的手柄的接口
#if USE_DX8
hr = CJoystick::g_pDI->CreateDevice( pdidInstance->guidInstance,&CJoystick::m_pJoystick, NULL );
#else
hr = CJoystick::g_pDI->CreateDeviceEx( pdidInstance->guidInstance, IID_IDirectInputDevice2,
(VOID**)&CJoystick::m_pJoystick, NULL );
#endif
// 失败了,我们就不能使用这个手柄,那么接着媒举
if( FAILED(hr) )
return DIENUM_CONTINUE;
// 成功了,那么就停止媒举,我们只使用第一个手柄
return DIENUM_STOP;
}
//媒举手柄的方向轴的回调函数
BOOL CALLBACK EnumAxesCallback( const DIDEVICEOBJECTINSTANCE* pdidoi, VOID* pContext )
{
HWND hDlg = (HWND)pContext; //pContext放的是窗口句柄
DIPROPRANGE diprg;
diprg.diph.dwSize = sizeof(DIPROPRANGE);
diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER);
diprg.diph.dwHow = DIPH_BYOFFSET;
diprg.diph.dwObj = pdidoi->dwOfs; // 媒举方向轴
diprg.lMin = -1000;
diprg.lMax = +1000;
//设置方向轴的范围
if( FAILED( CJoystick::m_pJoystick->SetProperty( DIPROP_RANGE, &diprg.diph ) ) )
return DIENUM_STOP; //失败了,就不继续了
DIPROPDWORD property;
property.diph.dwSize=sizeof(DIPROPDWORD);
property.diph.dwHeaderSize=sizeof(DIPROPHEADER);
property.diph.dwHow = DIPH_BYOFFSET;
property.diph.dwObj = pdidoi->dwOfs;
property.dwData = 5000;
HRESULT hr = CJoystick::m_pJoystick->SetProperty(DIPROP_DEADZONE,&property.diph);
if(FAILED(hr))
{
// 设置死区失败
MessageBox(hDlg, "error on set Joystick deadzone size", "error", MB_OK);
return FALSE;
}
// 让我们的应用程序根据方向轴所支持的方式做出不同的响应
// 配合传进来的窗口句柄可以做很多的事情…………
switch( pdidoi->dwOfs )
{
case DIJOFS_X:
break;
case DIJOFS_Y:
break;
case DIJOFS_Z:
break;
case DIJOFS_RX:
break;
case DIJOFS_RY:
break;
case DIJOFS_RZ:
break;
case DIJOFS_SLIDER(0):
break;
case DIJOFS_SLIDER(1):
break;
}
return DIENUM_CONTINUE; //继续媒举下一个方向
}
//初始化
HRESULT CJoystick::InitInput_Joystick( HWND hDlg )
{
HRESULT hr;
//创建DirectInput
#if USE_DX8
hr = DirectInput8Create( hInst, DIRECTINPUT_VERSION,IID_IDirectInput8,
(LPVOID*)&g_pDI, NULL );
#else
hr = DirectInputCreateEx( hInst, DIRECTINPUT_VERSION,IID_IDirectInput7,
(LPVOID*)&g_pDI, NULL );
#endif
if( FAILED(hr) )
return hr;
// 媒举一个手柄
#if USE_DX8
#define JOY DI8DEVCLASS_GAMECTRL
#else
#define JOY DIDEVTYPE_JOYSTICK
#endif
hr = g_pDI->EnumDevices( JOY, EnumJoysticksCallback, NULL, DIEDFL_ATTACHEDONLY );
if( FAILED(hr) )
return hr;
// 确认得到了一个手柄,上一个函数只保证它自己调用成功,不保证得到了一个可以用的手柄
if( NULL == m_pJoystick )
{
return E_FAIL;
}
//设置数据格式
hr = m_pJoystick->SetDataFormat( &c_dfDIJoystick );
if( FAILED(hr) )
return hr;
//设置协作级
hr = m_pJoystick->SetCooperativeLevel( hDlg, DISCL_NONEXCLUSIVE|DISCL_FOREGROUND );
if( FAILED(hr) )
return hr;
m_diDevCaps.dwSize = sizeof(DIDEVCAPS);
hr = m_pJoystick->GetCapabilities(&m_diDevCaps);
if ( FAILED(hr) )
return hr;
//媒举方向轴
m_pJoystick->EnumObjects( EnumAxesCallback, (VOID*)hDlg, DIDFT_AXIS );
//设置属性
DIPROPDWORD property;
property.diph.dwSize=sizeof(DIPROPDWORD);
property.diph.dwHeaderSize=sizeof(DIPROPHEADER);
property.diph.dwObj=0;
property.diph.dwHow=DIPH_DEVICE;
property.dwData=32;
hr = m_pJoystick->SetProperty(DIPROP_BUFFERSIZE, &property.diph);
if FAILED(hr)
{
// 设置缓冲区失败
MessageBox(hDlg, "error on set Joystick Buffer size", "error", MB_OK);
return FALSE;
}
//得到设备
SetAcquire(hWnd);
return true;
}
//获取设备
HRESULT CJoystick::SetAcquire( HWND hWnd )
{
if( m_pJoystick )
{
if( bActive )
m_pJoystick->Acquire();
else
m_pJoystick->Unacquire();
}
return S_OK;
}
//得到手柄的当前状态
HRESULT CJoystick::GetJoystickState()
{
HRESULT hr;
DIJOYSTATE js;
static DIJOYSTATE oldjs; //上一个状态
if( m_pJoystick )
{
do
{ //Poll
hr = m_pJoystick->Poll();
if( FAILED(hr) )
return hr;
//得到当前状态
hr = m_pJoystick->GetDeviceState( sizeof(DIJOYSTATE), &js );
if( hr == DIERR_INPUTLOST )
{
hr = m_pJoystick->Acquire();
if( FAILED(hr) )
return hr;
}
}
while( DIERR_INPUTLOST == hr );
if( FAILED(hr) )
return hr;
//清0
for(int i =0;i<MAXKEY;i++)
State[i] =0;
//我们只是关心这几个的值
//先是上下方向的
if(js.lY<0&&abs(oldjs.lY-js.lY)<10)
State[DIJ_UP] = DIJ_UP+128;
if(js.lY>0&&abs(oldjs.lY-js.lY)<10)
State[DIJ_DOWN] = DIJ_DOWN+128;
if(js.lY>0&&abs(oldjs.lY)<10)
State[DIJ_DOWN] = DIJ_DOWN;
if(js.lY<0&&abs(oldjs.lY)<10)
State[DIJ_UP] = DIJ_UP;
//然后是左右方向的
if(js.lX<0&&abs(oldjs.lX-js.lX)<10)
State[DIJ_LEFT] = DIJ_LEFT+128;
if(js.lX>0&&abs(oldjs.lX-js.lX)<10)
State[DIJ_RIGHT] = DIJ_RIGHT+128;
if(js.lX>0&&abs(oldjs.lX)<10)
State[DIJ_RIGHT] = DIJ_RIGHT;
if(js.lX<0&&abs(oldjs.lX)<10)
State[DIJ_LEFT] = DIJ_LEFT;
//最后是按纽
State[DIJ_3] = (js.rgbButtons[0]&0x80?DIJ_3+48:0); //按下或者是放开
State[DIJ_4] = (js.rgbButtons[1]&0x80?DIJ_4+48:0);
State[DIJ_2] = (js.rgbButtons[2]&0x80?DIJ_2+48:0);
State[DIJ_1] = (js.rgbButtons[3]&0x80?DIJ_1+48:0);
memcpy(&oldjs,&js,sizeof(js));
}
return S_OK;
}
//返回一个键当前是否按下
unsigned char CJoystick::GetState(unsigned char Key)
{
return State[Key];
}
//***************************
//返回缓冲区数据
void WINAPI CJoystick::GetJoystickData()
{
DIDEVICEOBJECTDATA rgdod[BUFFERSIZE];
DWORD dwItems = BUFFERSIZE;
if( m_pJoystick )
{
_again:
// Poll
HRESULT hr = m_pJoystick->Poll();
if( FAILED(hr) ) return;
hr = m_pJoystick->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), rgdod, &dwItems, 0);
if(hr != DI_OK)
{
if( FAILED(hr) )
{
hr = m_pJoystick->Acquire();
if FAILED(hr)
{
return;
}
if SUCCEEDED(hr)
{
goto _again;
}
}
}
if( SUCCEEDED(hr) && dwItems>0 )
{
DWORD i;
for(i=0; i<dwItems; i++)
{
//缓冲数据,两个按纽的数据
if(rgdod[i].dwOfs == DIJOFS_BUTTON0)
{
if((rgdod[i].dwData & 0x80) ) //按下
{
Buffer[Buffer_End] = (BYTE)(DIJ_3);
Buffer_End ++;
if( Buffer_End >= BUFFERSIZE )
Buffer_End = 0;
}
else //释放
{
Buffer[Buffer_End] = (BYTE)(DIJ_3+48);
Buffer_End ++;
if( Buffer_End >= BUFFERSIZE )
Buffer_End = 0;
}
}
if(rgdod[i].dwOfs == DIJOFS_BUTTON1)
{
if((rgdod[i].dwData & 0x80) ) //按下
{
Buffer[Buffer_End] = (BYTE)(DIJ_4);
Buffer_End ++;
if( Buffer_End >= BUFFERSIZE )
Buffer_End = 0;
}
else //释放
{
Buffer[Buffer_End] = (BYTE)(DIJ_4+48);
Buffer_End ++;
if( Buffer_End >= BUFFERSIZE )
Buffer_End = 0;
}
}
if(rgdod[i].dwOfs == DIJOFS_BUTTON2)
{
if((rgdod[i].dwData & 0x80) ) //按下
{
Buffer[Buffer_End] = (BYTE)(DIJ_2);
Buffer_End ++;
if( Buffer_End >= BUFFERSIZE )
Buffer_End = 0;
}
else //释放
{
Buffer[Buffer_End] = (BYTE)(DIJ_2+48);
Buffer_End ++;
if( Buffer_End >= BUFFERSIZE )
Buffer_End = 0;
}
}
if(rgdod[i].dwOfs == DIJOFS_BUTTON3)
{
if((rgdod[i].dwData & 0x80) ) //按下
{
Buffer[Buffer_End] = (BYTE)(DIJ_1);
Buffer_End ++;
if( Buffer_End >= BUFFERSIZE )
Buffer_End = 0;
}
else //释放
{
Buffer[Buffer_End] = (BYTE)(DIJ_1+48);
Buffer_End ++;
if( Buffer_End >= BUFFERSIZE )
Buffer_End = 0;
}
}
}
}
}
}
//从缓冲区取一个值(0=无)
unsigned char WINAPI CJoystick::GetKey()
{
if( m_pJoystick )
{
//缓冲区为空
if( Buffer_Start == Buffer_End )
return 0;
byte ret=Buffer_Start;
Buffer_Start++;
if( Buffer_Start >= BUFFERSIZE )
Buffer_Start = 0;
return Buffer[ret];
}
return 0;
}
//清空缓冲区
void WINAPI CJoystick::ReleaseBuffer()
{
if( m_pJoystick )
{
while(1)
{
GetJoystickData();
if( GetKey()== 0 ) break;
}
}
}
//释放手柄
HRESULT CJoystick::FreeInput_Joystick()
{
if( m_pJoystick != NULL )
{
m_pJoystick->Unacquire();
m_pJoystick->Release();
m_pJoystick = NULL;
}
if( lpDI )
{
lpDI->Release();
lpDI = NULL;
}
return S_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -