AxibugEmuOnline/References/VirtuaNESex_src_191105/DirectInput.cpp
2024-08-05 17:58:53 +08:00

478 lines
13 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// DirectInput class
//
#include "DebugOut.h"
#include "DirectInput.h"
#include "COM.h"
#include "Config.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
// ƒgƒOƒŒnƒL<C692>[ÈÌÅŽg¦È¢
DIK_CAPITAL, "Caps Lock",
DIK_NUMLOCK, "NumLock",
DIK_SCROLL, "ScrollLock",
DIK_KANA, "ƒJƒi",
DIK_KANJI, "Š¿Žš",
#endif
0x00, NULL
};
LPSTR CDirectInput::DIKeyDirTable[] = {
"X+", "X-", "Y+", "Y-", "Z+", "Z-",
"RX+", "RX-", "RY+", "RY-", "RZ+", "RZ-",
"S0+", "S0-", "S1+", "S1-",
};
LPSTR CDirectInput::DIKeyDirTable2[] = {
"P0 Up", "P0 Down", "P0 Left", "P0 Right",
"P1 Up", "P1 Down", "P1 Left", "P1 Right",
"P2 Up", "P2 Down", "P2 Left", "P2 Right",
"P3 Up", "P3 Down", "P3 Left", "P3 Right",
};
//////////////////////////////////////////////////////////////////////
// <20>\z/<2F>ÁÅ
//////////////////////////////////////////////////////////////////////
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
}
//////////////////////////////////////////////////////////////////////
// ƒ<>ƒ“ƒoŠÖ<C5A0>
//////////////////////////////////////////////////////////////////////
// ƒfƒoƒCƒXƒIƒuƒWƒFƒNƒg—ñ“ƒR<C692>ƒoƒbƒN
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;
}
// ƒWƒ‡ƒCƒXƒeƒBƒbƒNƒfƒoƒCƒXƒIƒuƒWƒFƒNƒgÌ<E2809A>ì<EFBFBD>¬
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;
}
INT nID = m_nJoystickNum;
if( !Config.general.bNoJoystickID ) {
// DX7Å͉Bµ—vf̃Wƒ‡ƒCƒXƒeƒBƒbƒNID̎擾(DX8©ç̓}ƒjƒ…ƒAƒÉL<E280B9>Ú³êÄ¢é)
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 );
nID = diprp_dw.dwData;
}
if( nID < DIJOYSTICK_MAX ) {
m_lpJoystick[ nID ] = lpDIDev;
// ŠeŽ²ÌƒŒƒ“ƒWð<E2809A>Ýè
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 );
diprg.diph.dwObj = DIJOFS_SLIDER(0);
lpDIDev->SetProperty( DIPROP_RANGE, &diprg.diph );
diprg.diph.dwObj = DIJOFS_SLIDER(1);
lpDIDev->SetProperty( DIPROP_RANGE, &diprg.diph );
// ¼<E28093>Ì̎擾
DIDEVICEINSTANCE didins;
ZEROMEMORY( &didins, sizeof(didins) );
didins.dwSize = sizeof( didins );
lpDIDev->GetDeviceInfo( &didins );
m_JoyName[ nID ] = didins.tszInstanceName;
DEBUGOUT( "Instance Name:%s\n", didins.tszInstanceName );
//DEBUGOUT( "Product Name:%s\n", didins.tszProductName );
} else {
m_lpJoystick[ nID ] = NULL;
RELEASE( lpDIDev );
}
m_nJoystickNum++;
return TRUE;
}
// DirectInputƒIƒuƒWƒFƒNƒg<C692>^ƒfƒoƒCƒXƒIƒuƒWƒFƒNƒgÌ<E2809A>\z
BOOL CDirectInput::InitialDInput(HWND hWnd, HINSTANCE hInst)
{
try {
// CDirectInputƒIƒuƒWƒFƒNƒgÌ<E2809A>ì<EFBFBD>¬
#if !COMUSE
if( DirectInputCreateEx( hInst, DIRECTINPUT_VERSION, IID_IDirectInput7, (LPVOID*)&m_lpDI, NULL ) != DI_OK ) {
m_lpDI = NULL;
throw "CDirectInput:DirectInputCreateEx failed.";
}
#else
// COM“I—˜—p
// 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
}
}
// “ü—̓tƒH<C692>[ƒJƒXðŽæ“¾
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();
}
}
}
// “ü—̓tƒH<C692>[ƒJƒXðŠJ•ú
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();
}
}
}
// ƒf<C692>[ƒ^ƒ|<7C>[ƒŠƒ“ƒO
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;
}
#if 0
// 2003/11/3 ‚Æ‚è‚ ‚¦‚¸–³Œø‰»
if( js.rglSlider[0] > 8000 ) m_Sw[idx + DI_SLIDER0+0] = 0x80;
if( js.rglSlider[0] < -8000 ) m_Sw[idx + DI_SLIDER0+1] = 0x80;
if( js.rglSlider[1] > 8000 ) m_Sw[idx + DI_SLIDER1+0] = 0x80;
if( js.rglSlider[1] < -8000 ) m_Sw[idx + DI_SLIDER1+1] = 0x80;
#endif
for( INT j = 0; j < 32; j++ ) {
m_Sw[idx + DI_BUTTON + j] = js.rgbButtons[j];
}
// POV
for( INT pov = 0; pov < 4; pov++ ) {
DWORD dwPOV = js.rgdwPOV[pov];
BOOL bPOVcenter = (LOWORD(dwPOV) == 0xFFFF);
BYTE data = 0;
if( !bPOVcenter ) {
static const BYTE dirtbl[] = {
(1<<0), (1<<0)|(1<<3), (1<<3), (1<<1)|(1<<3),
(1<<1), (1<<1)|(1<<2), (1<<2), (1<<0)|(1<<2),
};
data = dirtbl[ ((dwPOV+(DWORD)(22.5*DI_DEGREES)) % (360*DI_DEGREES))/(45*DI_DEGREES) ];
}
// Up/Down
if( data & (1<<0) ) m_Sw[idx + DI_POV0_UD+i*4+0] = 0x80;
if( data & (1<<1) ) m_Sw[idx + DI_POV0_UD+i*4+1] = 0x80;
// Left/Right
if( data & (1<<2) ) m_Sw[idx + DI_POV0_LR+i*4+0] = 0x80;
if( data & (1<<3) ) m_Sw[idx + DI_POV0_LR+i*4+1] = 0x80;
}
}
}
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_END ) {
::wsprintf( KeyStr, "J:%d B:%02d", no, idx-DI_BUTTON );
return KeyStr;
} else if( idx >= DI_EXT && idx < DI_EXT_END ) {
::wsprintf( KeyStr, "J:%d %s", no, DIKeyDirTable2[idx-DI_EXT] );
return KeyStr;
}
}
return NULL;
}