project64/Source/Project64-input/DirectInput.cpp

216 lines
5.6 KiB
C++

#include "DirectInput.h"
#include <Common\StdString.h>
CDirectInput::CDirectInput(HINSTANCE hinst) :
m_hDirectInputDLL(nullptr),
m_pDIHandle(nullptr),
m_hinst(hinst),
m_hWnd(nullptr)
{
LoadConfig();
if (m_hDirectInputDLL == nullptr)
{
m_hDirectInputDLL = LoadLibrary(L"dinput8.dll");
}
if (m_hDirectInputDLL != nullptr)
{
typedef HRESULT(WINAPI *tylpGetDIHandle)(HINSTANCE, DWORD, REFIID, LPVOID*, LPUNKNOWN);
tylpGetDIHandle lpGetDIHandle = (tylpGetDIHandle)GetProcAddress(m_hDirectInputDLL, "DirectInput8Create");
if (lpGetDIHandle != NULL)
{
HRESULT hr = lpGetDIHandle(m_hinst, DIRECTINPUT_VERSION, IID_IDirectInput8, (LPVOID*)&m_pDIHandle, NULL);
if (FAILED(hr))
{
return;
}
}
if (m_pDIHandle != nullptr)
{
m_pDIHandle->EnumDevices(DI8DEVCLASS_ALL, stEnumMakeDeviceList, this, DIEDFL_ATTACHEDONLY);
}
}
}
CDirectInput::~CDirectInput()
{
for (DEVICE_MAP::iterator itr = m_Devices.begin(); itr != m_Devices.end(); itr++)
{
if (itr->second.didHandle != nullptr)
{
itr->second.didHandle->Release();
itr->second.didHandle = NULL;
}
}
}
void CDirectInput::Initiate(CONTROL_INFO * ControlInfo)
{
m_hWnd = (HWND)ControlInfo->hwnd;
}
BOOL CDirectInput::stEnumMakeDeviceList(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef)
{
return ((CDirectInput *)pvRef)->EnumMakeDeviceList(lpddi);
}
BOOL CDirectInput::EnumMakeDeviceList(LPCDIDEVICEINSTANCE lpddi)
{
uint32_t DeviceType = GET_DIDEVICE_TYPE(lpddi->dwDevType);
if (DeviceType == DI8DEVTYPE_DEVICE)
{
// ignore generic devices
return DIENUM_CONTINUE;
}
DEVICE Device;
Device.didHandle = nullptr;
Device.dwDevType = lpddi->dwDevType;
Device.ProductName = stdstr().FromUTF16(lpddi->tszProductName);
Device.InstanceName = stdstr().FromUTF16(lpddi->tszInstanceName);
HRESULT hResult = m_pDIHandle->CreateDevice(lpddi->guidInstance, &Device.didHandle, NULL);
if (!SUCCEEDED(hResult))
{
return DIENUM_CONTINUE;
}
LPCDIDATAFORMAT ppDiDataFormat = NULL;
if (DeviceType == DI8DEVTYPE_KEYBOARD)
{
ppDiDataFormat = &c_dfDIKeyboard;
}
else if (DeviceType == DI8DEVTYPE_MOUSE)
{
ppDiDataFormat = &c_dfDIMouse2;
}
else
{
ppDiDataFormat = &c_dfDIJoystick;
}
hResult = Device.didHandle->SetDataFormat(ppDiDataFormat);
if (!SUCCEEDED(hResult))
{
Device.didHandle->Release();
return DIENUM_CONTINUE;
}
hResult = Device.didHandle->SetCooperativeLevel(m_hWnd, DISCL_NONEXCLUSIVE | DISCL_BACKGROUND);
if (!SUCCEEDED(hResult))
{
Device.didHandle->Release();
return DIENUM_CONTINUE;
}
std::pair<DEVICE_MAP::iterator, bool> res = m_Devices.insert(DEVICE_MAP::value_type(lpddi->guidInstance, Device));
if (!res.second)
{
Device.didHandle->Release();
}
return DIENUM_CONTINUE;
}
CDirectInput::ScanResult CDirectInput::ScanDevices(BUTTON & Button)
{
ScanResult Result = SCAN_FAILED;
for (DEVICE_MAP::iterator itr = m_Devices.begin(); itr != m_Devices.end(); itr++)
{
DEVICE &device = itr->second;
if (device.didHandle == nullptr)
{
continue;
}
if (FAILED(device.didHandle->Poll()))
{
device.didHandle->Acquire();
}
}
for (DEVICE_MAP::iterator itr = m_Devices.begin(); itr != m_Devices.end(); itr++)
{
DEVICE &device = itr->second;
if (device.didHandle == nullptr)
{
continue;
}
uint8_t DeviceType = LOBYTE(device.dwDevType);
if (DeviceType == DI8DEVTYPE_KEYBOARD)
{
Result = ScanKeyboard(device.didHandle, Button);
}
else if (DeviceType == DI8DEVTYPE_MOUSE)
{
//dwReturn = ScanMouse(&g_devList[i], lpdwCounter, pButton);
}
else
{
// dwReturn = ScanGamePad(&g_devList[i], lpdwCounter, pButton, i);
}
if (Result != SCAN_FAILED)
{
return Result;
}
}
return Result;
}
std::wstring CDirectInput::ButtonAssignment(BUTTON & Button)
{
if (Button.BtnType == BTNTYPE_KEYBUTTON)
{
DEVICE_MAP::iterator itr = m_Devices.find(GUID_SysKeyboard);
if (itr != m_Devices.end())
{
DIDEVICEOBJECTINSTANCE didoi;
didoi.dwSize = sizeof(DIDEVICEOBJECTINSTANCE);
if (itr->second.didHandle->GetObjectInfo(&didoi, Button.Offset, DIPH_BYOFFSET) == DI_OK)
{
return didoi.tszName;
}
return L"Keyboard: ???";
}
}
else if (Button.BtnType == BTNTYPE_UNASSIGNED)
{
return L"";
}
return L"Unknown";
}
CDirectInput::ScanResult CDirectInput::ScanKeyboard(LPDIRECTINPUTDEVICE8 didHandle, BUTTON & pButton)
{
if (didHandle == nullptr)
{
return SCAN_FAILED;
}
uint8_t cKeys[256];
HRESULT hr = didHandle->GetDeviceState(sizeof(cKeys), cKeys);
if (FAILED(hr))
{
didHandle->Acquire();
return SCAN_FAILED;
}
for (size_t i = 0, n = sizeof(cKeys) / sizeof(cKeys[0]); i < n; i++)
{
if ((cKeys[i] & 0x80) == 0)
{
continue;
}
if (i == DIK_ESCAPE)
{
return SCAN_ESCAPE;
}
pButton.Offset = (uint8_t)i;
pButton.AxisID = 0;
pButton.BtnType = BTNTYPE_KEYBUTTON;
return SCAN_SUCCEED;
}
return SCAN_FAILED;
}
void CDirectInput::LoadConfig(void)
{
}