Project64-input: Detect devices changed

This commit is contained in:
zilmar 2020-07-15 20:40:20 +09:30
parent d21c3a89f2
commit f2b35fb5b4
6 changed files with 96 additions and 6 deletions

View File

@ -16,6 +16,15 @@ CProject64Input::~CProject64Input()
{
}
void CProject64Input::DevicesChanged(void)
{
CGuard guard(m_CS);
if (m_DirectInput.get() != nullptr)
{
m_DirectInput->DevicesChanged();
}
}
void CProject64Input::InitiateControllers(CONTROL_INFO * ControlInfo)
{
CGuard guard(m_CS);
@ -101,10 +110,13 @@ std::wstring CProject64Input::ButtonAssignment(BUTTON & Button)
bool CProject64Input::SaveController(uint32_t ControlIndex)
{
CGuard guard(m_CS);
if (ControlIndex >= sizeof(m_Controllers) / sizeof(m_Controllers[0]))
{
return false;
}
g_Settings->SaveController(ControlIndex, m_ControlInfo.Controls[ControlIndex], m_Controllers[ControlIndex]);
m_DirectInput->MapControllerDevice(m_Controllers[ControlIndex]);
return true;
}

View File

@ -11,6 +11,7 @@ public:
CProject64Input(HINSTANCE hinst);
~CProject64Input();
void DevicesChanged(void);
void InitiateControllers(CONTROL_INFO * ControlInfo);
void GetKeys(int32_t Control, BUTTONS * Keys);
void StartScanDevices(int32_t DisplayCtrlId);

View File

@ -0,0 +1,34 @@
#include "DeviceNotification.h"
#include "CProject64Input.h"
#include <dbt.h>
DeviceNotification::DeviceNotification()
{
Create(NULL);
}
DeviceNotification::~DeviceNotification()
{
DestroyWindow();
}
int DeviceNotification::OnCreate(LPCREATESTRUCT /*lpCreateStruct*/)
{
DEV_BROADCAST_DEVICEINTERFACE notificationFilter = { 0 };
notificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
notificationFilter.dbcc_size = sizeof(notificationFilter);
HDEVNOTIFY hDevNotify;
hDevNotify = RegisterDeviceNotification(m_hWnd, &notificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE | DEVICE_NOTIFY_ALL_INTERFACE_CLASSES);
return TRUE;
}
BOOL DeviceNotification::OnDeviceChange(UINT nEventType, DWORD /*dwData*/)
{
if (g_InputPlugin != nullptr && (nEventType == DBT_DEVICEARRIVAL || nEventType == DBT_DEVICEREMOVECOMPLETE))
{
g_InputPlugin->DevicesChanged();
}
return TRUE;
}

View File

@ -0,0 +1,23 @@
#pragma once
#include "wtl.h"
typedef CWinTraits<WS_OVERLAPPED, WS_EX_APPWINDOW> DeviceNotificationTraits;
class DeviceNotification :
public CWindowImpl<DeviceNotification, CWindow, DeviceNotificationTraits>
{
public:
DECLARE_WND_CLASS(_T("My Window Class"))
BEGIN_MSG_MAP(DeviceNotification)
MSG_WM_CREATE(OnCreate)
MSG_WM_DEVICECHANGE(OnDeviceChange)
END_MSG_MAP()
DeviceNotification();
~DeviceNotification();
private:
int OnCreate(LPCREATESTRUCT lpCreateStruct);
BOOL OnDeviceChange(UINT nEventType, DWORD dwData);
};

View File

@ -1,5 +1,6 @@
#include "DirectInput.h"
#include <Common\StdString.h>
#include <Common\SyncEvent.h>
CDirectInput::CDirectInput(HINSTANCE hinst) :
m_hDirectInputDLL(nullptr),
@ -25,10 +26,7 @@ CDirectInput::CDirectInput(HINSTANCE hinst) :
}
}
if (m_pDIHandle != nullptr)
{
m_pDIHandle->EnumDevices(DI8DEVCLASS_ALL, stEnumMakeDeviceList, this, DIEDFL_ATTACHEDONLY);
}
RefreshDeviceList();
}
}
@ -101,6 +99,12 @@ BOOL CDirectInput::EnumMakeDeviceList(LPCDIDEVICEINSTANCE lpddi)
return DIENUM_CONTINUE;
}
DEVICE_MAP::iterator itr = m_Devices.find(lpddi->guidInstance);
if (itr != m_Devices.end())
{
return DIENUM_CONTINUE;
}
DEVICE Device = { 0 };
Device.didHandle = nullptr;
Device.dwDevType = lpddi->dwDevType;
@ -207,7 +211,7 @@ std::wstring CDirectInput::ButtonAssignment(BUTTON & Button)
return L"Keyboard: ???";
}
}
else if (Button.BtnType == BTNTYPE_UNASSIGNED)
if (Button.BtnType == BTNTYPE_UNASSIGNED)
{
return L"";
}
@ -287,6 +291,19 @@ void CDirectInput::UpdateDeviceData(void)
}
}
void CDirectInput::DevicesChanged(void)
{
RefreshDeviceList();
}
void CDirectInput::RefreshDeviceList(void)
{
if (m_pDIHandle != nullptr)
{
m_pDIHandle->EnumDevices(DI8DEVCLASS_ALL, stEnumMakeDeviceList, this, DIEDFL_ATTACHEDONLY);
}
}
CDirectInput::ScanResult CDirectInput::ScanKeyboard(const GUID & DeviceGuid, LPDIRECTINPUTDEVICE8 didHandle, uint8_t * KeyboardState, BUTTON & pButton)
{
if (didHandle == nullptr)

View File

@ -1,6 +1,7 @@
#pragma once
#include "ControllerSpec1.1.h"
#include "Button.h"
#include "DeviceNotification.h"
#include "N64Controller.h"
#define DIRECTINPUT_VERSION 0x0800
#include <Windows.h>
@ -28,6 +29,7 @@ public:
bool IsButtonPressed(BUTTON & Button);
int8_t AxisPos(BUTTON & PosBtn, BUTTON & NegBtn, uint8_t Range);
void UpdateDeviceData(void);
void DevicesChanged(void);
private:
CDirectInput();
@ -38,7 +40,7 @@ private:
BOOL EnumMakeDeviceList(LPCDIDEVICEINSTANCE lpddi);
ScanResult ScanKeyboard(const GUID & DeviceGuid, LPDIRECTINPUTDEVICE8 didHandle, uint8_t * KeyboardState, BUTTON & pButton);
bool AcquireDevice(LPDIRECTINPUTDEVICE8 lpDirectInputDevice);
void LoadConfig(void);
void RefreshDeviceList(void);
typedef struct
{
@ -63,6 +65,7 @@ private:
};
typedef std::map<GUID, DEVICE, GUIDComparer> DEVICE_MAP;
DeviceNotification m_DeviceNotification;
DEVICE_MAP m_Devices;
HMODULE m_hDirectInputDLL;
LPDIRECTINPUT8 m_pDIHandle;