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) void CProject64Input::InitiateControllers(CONTROL_INFO * ControlInfo)
{ {
CGuard guard(m_CS); CGuard guard(m_CS);
@ -101,10 +110,13 @@ std::wstring CProject64Input::ButtonAssignment(BUTTON & Button)
bool CProject64Input::SaveController(uint32_t ControlIndex) bool CProject64Input::SaveController(uint32_t ControlIndex)
{ {
CGuard guard(m_CS);
if (ControlIndex >= sizeof(m_Controllers) / sizeof(m_Controllers[0])) if (ControlIndex >= sizeof(m_Controllers) / sizeof(m_Controllers[0]))
{ {
return false; return false;
} }
g_Settings->SaveController(ControlIndex, m_ControlInfo.Controls[ControlIndex], m_Controllers[ControlIndex]); g_Settings->SaveController(ControlIndex, m_ControlInfo.Controls[ControlIndex], m_Controllers[ControlIndex]);
m_DirectInput->MapControllerDevice(m_Controllers[ControlIndex]);
return true; return true;
} }

View File

@ -11,6 +11,7 @@ public:
CProject64Input(HINSTANCE hinst); CProject64Input(HINSTANCE hinst);
~CProject64Input(); ~CProject64Input();
void DevicesChanged(void);
void InitiateControllers(CONTROL_INFO * ControlInfo); void InitiateControllers(CONTROL_INFO * ControlInfo);
void GetKeys(int32_t Control, BUTTONS * Keys); void GetKeys(int32_t Control, BUTTONS * Keys);
void StartScanDevices(int32_t DisplayCtrlId); 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 "DirectInput.h"
#include <Common\StdString.h> #include <Common\StdString.h>
#include <Common\SyncEvent.h>
CDirectInput::CDirectInput(HINSTANCE hinst) : CDirectInput::CDirectInput(HINSTANCE hinst) :
m_hDirectInputDLL(nullptr), m_hDirectInputDLL(nullptr),
@ -25,10 +26,7 @@ CDirectInput::CDirectInput(HINSTANCE hinst) :
} }
} }
if (m_pDIHandle != nullptr) RefreshDeviceList();
{
m_pDIHandle->EnumDevices(DI8DEVCLASS_ALL, stEnumMakeDeviceList, this, DIEDFL_ATTACHEDONLY);
}
} }
} }
@ -101,6 +99,12 @@ BOOL CDirectInput::EnumMakeDeviceList(LPCDIDEVICEINSTANCE lpddi)
return DIENUM_CONTINUE; return DIENUM_CONTINUE;
} }
DEVICE_MAP::iterator itr = m_Devices.find(lpddi->guidInstance);
if (itr != m_Devices.end())
{
return DIENUM_CONTINUE;
}
DEVICE Device = { 0 }; DEVICE Device = { 0 };
Device.didHandle = nullptr; Device.didHandle = nullptr;
Device.dwDevType = lpddi->dwDevType; Device.dwDevType = lpddi->dwDevType;
@ -207,7 +211,7 @@ std::wstring CDirectInput::ButtonAssignment(BUTTON & Button)
return L"Keyboard: ???"; return L"Keyboard: ???";
} }
} }
else if (Button.BtnType == BTNTYPE_UNASSIGNED) if (Button.BtnType == BTNTYPE_UNASSIGNED)
{ {
return L""; 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) CDirectInput::ScanResult CDirectInput::ScanKeyboard(const GUID & DeviceGuid, LPDIRECTINPUTDEVICE8 didHandle, uint8_t * KeyboardState, BUTTON & pButton)
{ {
if (didHandle == nullptr) if (didHandle == nullptr)

View File

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