📄 directinput.cpp
字号:
//
// DirectInput class
//
#include "DebugOut.h"
#include "DirectInput.h"
#include "COM.h"
CDirectInput DirectInput;
#define COMUSE TRUE
//
// Table
//
CDirectInput::DIKEYTBL CDirectInput::DIKeyTable[] = {
DIK_ESCAPE, "ESC", DIK_1, "1",
DIK_2, "2", DIK_3, "3",
DIK_4, "4", DIK_5, "5",
DIK_6, "6", DIK_7, "7",
DIK_8, "8", DIK_9, "9",
DIK_0, "0", DIK_MINUS, "-",
DIK_EQUALS, "=", DIK_BACK, "BackSpace",
DIK_TAB, "TAB", DIK_Q, "Q",
DIK_W, "W", DIK_E, "E",
DIK_R, "R", DIK_T, "T",
DIK_Y, "Y", DIK_U, "U",
DIK_I, "I", DIK_O, "O",
DIK_P, "P", DIK_LBRACKET, "[",
DIK_RBRACKET, "]", DIK_RETURN, "Enter",
DIK_LCONTROL, "L Ctrl", DIK_A, "A",
DIK_S, "S", DIK_D, "D",
DIK_F, "F", DIK_G, "G",
DIK_H, "H", DIK_J, "J",
DIK_K, "K", DIK_L, "L",
DIK_SEMICOLON, ";", DIK_APOSTROPHE, "'",
DIK_GRAVE, "`", DIK_LSHIFT, "L Shift",
DIK_BACKSLASH, "\\", DIK_Z, "Z",
DIK_X, "X", DIK_C, "C",
DIK_V, "V", DIK_B, "B",
DIK_N, "N", DIK_M, "M",
DIK_COMMA, ",", DIK_PERIOD, ".",
DIK_SLASH, "/", DIK_RSHIFT, "R Shift",
DIK_MULTIPLY, "*", DIK_LMENU, "L Alt",
DIK_SPACE, "Space",
DIK_F1, "F1", DIK_F2, "F2",
DIK_F3, "F3", DIK_F4, "F4",
DIK_F5, "F5", DIK_F6, "F6",
DIK_F7, "F7", DIK_F8, "F8",
DIK_F9, "F9", DIK_F10, "F10",
DIK_NUMPAD7, "Num 7", DIK_NUMPAD8, "Num 8",
DIK_NUMPAD9, "Num 9", DIK_SUBTRACT, "Num -",
DIK_NUMPAD4, "Num 4", DIK_NUMPAD5, "Num 5",
DIK_NUMPAD6, "Num 6", DIK_ADD, "Num +",
DIK_NUMPAD1, "Num 1", DIK_NUMPAD2, "Num 2",
DIK_NUMPAD3, "Num 3", DIK_NUMPAD0, "Num 0",
DIK_DECIMAL, "Num .", DIK_F11, "F11",
DIK_F12, "F12", DIK_F13, "F13",
DIK_F14, "F14", DIK_F15, "F15",
DIK_CONVERT, "曄姺",
DIK_NOCONVERT, "柍曄姺", DIK_YEN, "\\",
DIK_NUMPADEQUALS,"Num =", DIK_CIRCUMFLEX, "^",
DIK_AT, "@", DIK_COLON, ":",
DIK_UNDERLINE, "_",
DIK_STOP, "Stop", DIK_NUMPADENTER,"Num Enter",
DIK_RCONTROL, "R Ctrl", DIK_NUMPADCOMMA,"Num ,",
DIK_DIVIDE, "Num /", DIK_SYSRQ, "SysRq",
DIK_RMENU, "R Alt", DIK_PAUSE, "Pause",
DIK_HOME, "Home", DIK_UP, "Up",
DIK_PRIOR, "Page Up", DIK_LEFT, "Left",
DIK_RIGHT, "Right", DIK_END, "End",
DIK_DOWN, "Down", DIK_NEXT, "Page Down",
DIK_INSERT, "Insert", DIK_DELETE, "Delete",
DIK_LWIN, "L Windows", DIK_LWIN, "R Windows",
DIK_APPS, "AppMenu",
#if 0
// 僩僌儖宯僉乕側偺偱巊偊側偄
DIK_CAPITAL, "Caps Lock",
DIK_NUMLOCK, "NumLock",
DIK_SCROLL, "ScrollLock",
DIK_KANA, "僇僫",
DIK_KANJI, "娍帤",
#endif
0x00, NULL
};
LPSTR CDirectInput::DIKeyDirTable[] = {
"X+", "X-", "Y+", "Y-", "Z+", "Z-", "RX+", "RX-", "RY+", "RY-", "RZ+", "RZ-"
"", "", "", ""
};
//////////////////////////////////////////////////////////////////////
// 峔抸/徚柵
//////////////////////////////////////////////////////////////////////
CDirectInput::CDirectInput()
{
m_lpDI = NULL;
m_lpKeyboard = NULL;
m_nJoystickNum = 0;
ZEROMEMORY( m_lpJoystick, sizeof(m_lpJoystick) );
ZEROMEMORY( m_Sw, sizeof(m_Sw) );
ZEROMEMORY( m_JoyAxisMode, sizeof(m_JoyAxisMode) );
#if COMUSE
COM::AddRef();
#endif
}
CDirectInput::~CDirectInput()
{
ReleaseDInput();
#if COMUSE
COM::AddRef();
#endif
}
//////////////////////////////////////////////////////////////////////
// 儊儞僶娭悢
//////////////////////////////////////////////////////////////////////
// 僨僶僀僗僆僽僕僃僋僩楍嫇僐乕儖僶僢僋
BOOL CALLBACK CDirectInput::DIEnumDevicesCallback( LPDIDEVICEINSTANCE lpddi, LPVOID pvRef )
{
CDirectInput* pCDi = (CDirectInput*)pvRef;
// DEBUGOUT( "dwDevType=%08X IName:%s PName:%s\n", lpddi->dwDevType, lpddi->tszInstanceName, lpddi->tszProductName );
if( pCDi->AddJoystickDevice( lpddi->guidInstance ) )
return DIENUM_CONTINUE;
return DIENUM_STOP;
}
// 僕儑僀僗僥傿僢僋僨僶僀僗僆僽僕僃僋僩偺嶌惉
BOOL CDirectInput::AddJoystickDevice( GUID deviceguid )
{
LPDIRECTINPUTDEVICE7 lpDIDev;
if( m_lpDI->CreateDeviceEx( deviceguid, IID_IDirectInputDevice7,
(LPVOID*)&lpDIDev, NULL ) != DI_OK ) {
return FALSE;
}
if( lpDIDev->SetDataFormat( &c_dfDIJoystick ) != DI_OK ) {
DEBUGOUT( "CDirectInput:SetDataFormat failed.\n" );
RELEASE( lpDIDev );
return FALSE;
}
// DX7偱偼塀偟梫慺偺僕儑僀僗僥傿僢僋ID偺庢摼(DX8偐傜偼儅僯儏傾儖偵婰嵹偝傟偰偄傞)
DIPROPDWORD diprp_dw;
ZEROMEMORY( &diprp_dw, sizeof(diprp_dw) );
diprp_dw.diph.dwSize = sizeof(DIPROPDWORD);
diprp_dw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
diprp_dw.diph.dwHow = DIPH_DEVICE;
diprp_dw.diph.dwObj = 0;
if( lpDIDev->GetProperty( DIPROP_JOYSTICKID, &diprp_dw.diph ) != DI_OK ) {
DEBUGOUT( "CDirectInput:GetProperty failed.\n" );
RELEASE( lpDIDev );
return FALSE;
}
DEBUGOUT( "ID:%d\n", diprp_dw.dwData );
if( diprp_dw.dwData < DIJOYSTICK_MAX ) {
m_lpJoystick[ diprp_dw.dwData ] = lpDIDev;
// 奺幉偺儗儞僕傪愝掕
DIPROPRANGE diprg;
diprg.diph.dwSize = sizeof(DIPROPRANGE);
diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER);
diprg.diph.dwHow = DIPH_BYOFFSET;
diprg.diph.dwObj = DIJOFS_X;
diprg.lMin = -10000;
diprg.lMax = +10000;
lpDIDev->SetProperty( DIPROP_RANGE, &diprg.diph );
diprg.diph.dwObj = DIJOFS_Y;
lpDIDev->SetProperty( DIPROP_RANGE, &diprg.diph );
diprg.diph.dwObj = DIJOFS_Z;
lpDIDev->SetProperty( DIPROP_RANGE, &diprg.diph );
diprg.diph.dwObj = DIJOFS_RX;
lpDIDev->SetProperty( DIPROP_RANGE, &diprg.diph );
diprg.diph.dwObj = DIJOFS_RY;
lpDIDev->SetProperty( DIPROP_RANGE, &diprg.diph );
diprg.diph.dwObj = DIJOFS_RZ;
lpDIDev->SetProperty( DIPROP_RANGE, &diprg.diph );
// 柤徧偺庢摼
DIDEVICEINSTANCE didins;
ZEROMEMORY( &didins, sizeof(didins) );
didins.dwSize = sizeof( didins );
lpDIDev->GetDeviceInfo( &didins );
m_JoyName[ diprp_dw.dwData ] = didins.tszInstanceName;
//DEBUGOUT( "Instance Name:%s\n", didins.tszInstanceName );
//DEBUGOUT( "Product Name:%s\n", didins.tszProductName );
} else {
m_lpJoystick[ diprp_dw.dwData ] = NULL;
RELEASE( lpDIDev );
}
m_nJoystickNum++;
return TRUE;
}
// DirectInput僆僽僕僃僋僩乛僨僶僀僗僆僽僕僃僋僩偺峔抸
BOOL CDirectInput::InitialDInput(HWND hWnd, HINSTANCE hInst)
{
try {
// CDirectInput僆僽僕僃僋僩偺嶌惉
#if !COMUSE
if( DirectInputCreateEx( hInst, DIRECTINPUT_VERSION, IID_IDirectInput7, (LPVOID*)&m_lpDI, NULL ) != DI_OK ) {
m_lpDI = NULL;
throw "CDirectInput:DirectInputCreateEx failed.";
}
#else
// COM揑棙梡
// COM::AddRef();
if( FAILED(CoCreateInstance( CLSID_DirectInput, NULL, CLSCTX_INPROC_SERVER, IID_IDirectInput7, (VOID**)&m_lpDI )) ) {
m_lpDI = NULL;
throw "CDirectInput:CoCreateInstance failed.";
}
if( m_lpDI->Initialize( hInst, DIRECTINPUT_VERSION ) != DI_OK )
throw "CDirectInput:IDirectInput7->Initialize failed.";
#endif
if( m_lpDI->CreateDevice( GUID_SysKeyboard, &m_lpKeyboard, NULL ) != DI_OK )
throw "CDirectInput:CreateDevice failed.";
if( m_lpKeyboard ) {
if( m_lpKeyboard->SetDataFormat( &c_dfDIKeyboard ) != DI_OK )
throw "CDirectInput:SetDataFormat failed.";
if( m_lpKeyboard->SetCooperativeLevel( hWnd, DISCL_NONEXCLUSIVE|DISCL_BACKGROUND) != DI_OK )
throw "CDirectInput:SetCooperativeLevel failed.";
if( m_lpKeyboard->Acquire() != DI_OK ) {
// DEBUGOUT( "CDirectInput:Acquire failed.\n" );
}
}
m_nJoystickNum = 0;
if( m_lpDI->EnumDevices( DIDEVTYPE_JOYSTICK, (LPDIENUMDEVICESCALLBACK)DIEnumDevicesCallback,
(LPVOID)this, DIEDFL_ATTACHEDONLY ) != DI_OK ) {
DEBUGOUT( "CDirectInput:EnumDevices failed.\n" );
}
if( !m_nJoystickNum ) {
DEBUGOUT( "CDirectInput:No Joystick device available.\n" );
} else {
for( INT i = 0; i < DIJOYSTICK_MAX; i++ ) {
if( m_lpJoystick[i] ) {
if( m_lpJoystick[i]->SetCooperativeLevel( hWnd, DISCL_NONEXCLUSIVE|DISCL_BACKGROUND) != DI_OK ) {
DEBUGOUT( "CDirectInput:SetCooperativeLevel failed.\n" );
throw "CDirectInput:SetCooperativeLevel failed.";
}
}
}
DEBUGOUT( "CDirectInput:Can use %d Joystick(s)\n", m_nJoystickNum );
}
} catch( char *str ) {
ReleaseDInput();
MessageBox( hWnd, str, "ERROR", MB_ICONERROR|MB_OK );
return FALSE;
}
return TRUE;
}
void CDirectInput::ReleaseDInput()
{
for( INT i = 0; i < DIJOYSTICK_MAX; i++ ) {
RELEASE( m_lpJoystick[i] );
}
if( m_lpKeyboard ) {
// m_lpKeyboard->Unacquire();
RELEASE( m_lpKeyboard );
}
if( m_lpDI ) {
RELEASE( m_lpDI );
#if COMUSE
// COM::Release();
#endif
}
}
// 擖椡僼僅乕僇僗傪庢摼
void CDirectInput::Acquire()
{
if( !m_lpDI )
return;
if( m_lpKeyboard )
m_lpKeyboard->Acquire();
for( INT i = 0; i < DIJOYSTICK_MAX; i++ ) {
if( m_lpJoystick[i] ) {
m_lpJoystick[i]->Acquire();
}
}
}
// 擖椡僼僅乕僇僗傪奐曻
void CDirectInput::Unacquire()
{
if( !m_lpDI )
return;
if( m_lpKeyboard )
m_lpKeyboard->Unacquire();
for( INT i = 0; i < DIJOYSTICK_MAX; i++ ) {
if( m_lpJoystick[i] ) {
m_lpJoystick[i]->Unacquire();
}
}
}
// 僨乕僞億乕儕儞僌
void CDirectInput::Poll()
{
DIJOYSTATE js;
ZeroMemory( m_Sw, sizeof(m_Sw) );
if( !m_lpDI ) {
return;
}
if( m_lpKeyboard ) {
if( m_lpKeyboard->GetDeviceState( 256, &m_Sw ) == DIERR_INPUTLOST ) {
m_lpKeyboard->Acquire();
m_lpKeyboard->GetDeviceState( 256, &m_Sw );
}
}
INT idx;
for( INT i = 0; i < DIJOYSTICK_MAX; i++ ) {
if( !m_lpJoystick[i] )
continue;
idx = 256+i*64;
if( m_lpJoystick[i]->Poll() == DIERR_INPUTLOST ) {
m_lpJoystick[i]->Acquire();
m_lpJoystick[i]->Poll();
}
if( m_lpJoystick[i]->GetDeviceState( sizeof(DIJOYSTATE), &js ) != DI_OK ) {
ZEROMEMORY( &js, sizeof(DIJOYSTATE) );
}
m_JoyAxis[i][0] = js.lX;
m_JoyAxis[i][1] = js.lY;
m_JoyAxis[i][2] = js.lZ;
m_JoyAxis[i][3] = js.lRx;
m_JoyAxis[i][4] = js.lRy;
m_JoyAxis[i][5] = js.lRz;
if( !(m_JoyAxisMode[i] & (1<<0)) ) {
if( js.lX > 8000 ) m_Sw[idx + DI_XAXIS+0] = 0x80;
if( js.lX < -8000 ) m_Sw[idx + DI_XAXIS+1] = 0x80;
}
if( !(m_JoyAxisMode[i] & (1<<1)) ) {
if( js.lY > 8000 ) m_Sw[idx + DI_YAXIS+0] = 0x80;
if( js.lY < -8000 ) m_Sw[idx + DI_YAXIS+1] = 0x80;
}
if( !(m_JoyAxisMode[i] & (1<<2)) ) {
if( js.lZ > 8000 ) m_Sw[idx + DI_ZAXIS+0] = 0x80;
if( js.lZ < -8000 ) m_Sw[idx + DI_ZAXIS+1] = 0x80;
}
if( !(m_JoyAxisMode[i] & (1<<3)) ) {
if( js.lRx > 8000 ) m_Sw[idx + DI_RXAXIS+0] = 0x80;
if( js.lRx < -8000 ) m_Sw[idx + DI_RXAXIS+1] = 0x80;
}
if( !(m_JoyAxisMode[i] & (1<<4)) ) {
if( js.lRy > 8000 ) m_Sw[idx + DI_RYAXIS+0] = 0x80;
if( js.lRy < -8000 ) m_Sw[idx + DI_RYAXIS+1] = 0x80;
}
if( !(m_JoyAxisMode[i] & (1<<5)) ) {
if( js.lRz > 8000 ) m_Sw[idx + DI_RZAXIS+0] = 0x80;
if( js.lRz < -8000 ) m_Sw[idx + DI_RZAXIS+1] = 0x80;
}
for( INT j = 0; j < 32; j++ ) {
m_Sw[idx + DI_BUTTON + j] = js.rgbButtons[j];
}
}
}
LPCSTR CDirectInput::SearchKeyName( INT key )
{
LPDIKEYTBL kt = DIKeyTable;
static CHAR KeyStr[256];
if( key == 0x00 )
return NULL;
if( key < 0x100 ) {
while( kt->name != NULL ) {
if( kt->key == key )
return kt->name;
kt++;
}
} else {
INT no = (key-256)>>6;
INT idx = key & 0x3F;
if( idx < DI_MAXAXIS ) {
::wsprintf( KeyStr, "J:%d %s", no, DIKeyDirTable[idx] );
return KeyStr;
} else if( idx >= DI_BUTTON && idx < DI_BUTTON+32 ) {
::wsprintf( KeyStr, "J:%d B:%02d", no, idx-DI_BUTTON );
return KeyStr;
}
}
return NULL;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -