Skip to content

Commit

Permalink
Fix dwDevType in GetCapabilities and GetDeviceInfo
Browse files Browse the repository at this point in the history
  • Loading branch information
elishacloud committed Jun 15, 2024
1 parent b26b9d8 commit 0a3a399
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 44 deletions.
2 changes: 1 addition & 1 deletion BuildNo.rc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
#define BUILD_NUMBER 60
#define BUILD_NUMBER 61
19 changes: 11 additions & 8 deletions IDirectInputDeviceX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ void m_IDirectInputDeviceX::InitializeEnumObjectData()
DIDEVICEINSTANCEW didi { sizeof(didi) };
if (SUCCEEDED(ProxyInterface->GetDeviceInfo(&didi)))
{
DevType7 = ConvertDevTypeTo7(GET_DIDEVICE_TYPE(didi.dwDevType));
DevType7 = ConvertDevTypeTo7(GET_DIDEVICE_TYPE(didi.dwDevType), didi.wUsagePage, didi.wUsage, didi.dwDevType & DIDEVTYPE_HID);

// We only need to do this trickery for game controllers - keyboard/mice should be sorted fine
// If this is ever proven to be false, just add code here for other DIDEVTYPE_*
Expand Down Expand Up @@ -276,12 +276,15 @@ HRESULT m_IDirectInputDeviceX::GetCapabilities(LPDIDEVCAPS lpDIDevCaps)

if (SUCCEEDED(hr))
{
DWORD devType = GET_DIDEVICE_TYPE(lpDIDevCaps->dwDevType);
DWORD devSubType = GET_DIDEVICE_SUBTYPE(lpDIDevCaps->dwDevType);
DWORD hidDevice = lpDIDevCaps->dwDevType & DIDEVTYPE_HID;
DWORD devType7 = ConvertDevTypeTo7(devType);
DWORD devSubType7 = ConvertDevSubTypeTo7(devType, devSubType);
lpDIDevCaps->dwDevType = devType7 | (devSubType7 << 8) | hidDevice;
DIDEVICEINSTANCE didi;
ZeroMemory(&didi, sizeof(didi));
didi.dwSize = sizeof(DIDEVICEINSTANCE);

hr = GetDeviceInfo(&didi);
if (SUCCEEDED(hr))
{
lpDIDevCaps->dwDevType = didi.dwDevType;
}
}

return hr;
Expand Down Expand Up @@ -647,7 +650,7 @@ HRESULT m_IDirectInputDeviceX::GetDeviceInfoX(V pdidi)
DWORD devType = GET_DIDEVICE_TYPE(pdidi->dwDevType);
DWORD devSubType = GET_DIDEVICE_SUBTYPE(pdidi->dwDevType);
DWORD hidDevice = pdidi->dwDevType & DIDEVTYPE_HID;
DWORD devType7 = ConvertDevTypeTo7(devType);
DWORD devType7 = ConvertDevTypeTo7(devType, pdidi->wUsagePage, pdidi->wUsage, hidDevice);
DWORD devSubType7 = ConvertDevSubTypeTo7(devType, devSubType);
pdidi->dwDevType = devType7 | (devSubType7 << 8) | hidDevice;
}
Expand Down
22 changes: 21 additions & 1 deletion IDirectInputTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,35 @@
*/

#include "dinputto8.h"
#include <hidusage.h>

DWORD ConvertDevTypeTo7(DWORD dwDevType)
DWORD ConvertDevTypeTo7(DWORD dwDevType, WORD wUsagePage, WORD wUsage, BOOL isHID)
{
switch (dwDevType)
{
case DIDEVTYPE_DEVICE:
case DI8DEVTYPE_DEVICE:
case DI8DEVTYPE_DEVICECTRL:
default:
if (isHID && wUsagePage == HID_USAGE_PAGE_GENERIC)
{
if (wUsage == HID_USAGE_GENERIC_MOUSE)
{
return DIDEVTYPE_MOUSE;
}
else if (wUsage == HID_USAGE_GENERIC_JOYSTICK || wUsage == HID_USAGE_GENERIC_GAMEPAD)
{
return DIDEVTYPE_JOYSTICK;
}
else if (wUsage == HID_USAGE_GENERIC_KEYBOARD)
{
return DIDEVTYPE_KEYBOARD;
}
}
if (isHID && wUsagePage == HID_USAGE_PAGE_KEYBOARD)
{
return DIDEVTYPE_KEYBOARD;
}
return DIDEVTYPE_DEVICE;
case DIDEVTYPE_MOUSE:
case DI8DEVTYPE_MOUSE:
Expand Down
2 changes: 1 addition & 1 deletion IDirectInputTypes.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#pragma once

DWORD ConvertDevTypeTo7(DWORD dwDevType);
DWORD ConvertDevTypeTo7(DWORD dwDevType, WORD wUsagePage, WORD wUsage, BOOL isHID);
DWORD ConvertDevSubTypeTo7(DWORD dwDevType, DWORD dwDevSubType);
44 changes: 11 additions & 33 deletions IDirectInputX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
*/

#include "dinputto8.h"
#include <hidusage.h>

HRESULT m_IDirectInputX::QueryInterface(REFIID riid, LPVOID FAR * ppvObj, DWORD DirectXVersion)
{
Expand Down Expand Up @@ -79,15 +78,19 @@ HRESULT m_IDirectInputX::EnumDevicesX(DWORD dwDevType, V lpCallback, LPVOID pvRe
{
V lpCallback = nullptr;
LPVOID pvRef = nullptr;
DWORD dwStructSize = sizeof(D);
bool bEnumerateGameControllers = true;
DWORD diVersion = 0;

static BOOL CALLBACK EnumDeviceCallback(const D *lpddi, LPVOID pvRef)
{
const DeviceEnumerator* self = static_cast<DeviceEnumerator*>(pvRef);
const DWORD dwConvertedDevType = ConvertDevTypeTo7(lpddi->dwDevType & 0xFF);
DWORD devType = GET_DIDEVICE_TYPE(lpddi->dwDevType);
DWORD devSubType = GET_DIDEVICE_SUBTYPE(lpddi->dwDevType);
DWORD hidDevice = lpddi->dwDevType & DIDEVTYPE_HID;
DWORD devType7 = ConvertDevTypeTo7(devType, lpddi->wUsagePage, lpddi->wUsage, hidDevice);
DWORD devSubType7 = ConvertDevSubTypeTo7(devType, devSubType);

if (dwConvertedDevType == DIDEVTYPE_JOYSTICK && !self->bEnumerateGameControllers)
// DirectInput 0x300 and earlier do not enumerate any game controllers
if (devType7 == DIDEVTYPE_JOYSTICK && self->diVersion <= 0x300)
{
return DIENUM_CONTINUE;
}
Expand All @@ -96,41 +99,16 @@ HRESULT m_IDirectInputX::EnumDevicesX(DWORD dwDevType, V lpCallback, LPVOID pvRe
CopyMemory(&DI, lpddi, lpddi->dwSize);

// Prevent DInput3 games from encountering a structure bigger than they might expect.
DI.dwSize = self->dwStructSize;

DI.dwDevType = (lpddi->dwDevType & ~0xFFFF) | // Remove device type and sub type
ConvertDevSubTypeTo7(lpddi->dwDevType & 0xFF, (lpddi->dwDevType & 0xFF00) >> 8) << 8 | // Add converted sub type
dwConvertedDevType; // Add converted device type
DI.dwSize = self->diVersion <= 0x300 ? sizeof(D) : sizeof(D_Old);

if ((DI.dwDevType & DIDEVTYPE_DEVICE) && (DI.dwDevType & DIDEVTYPE_HID))
{
// Check if the device is a mouse
if (DI.wUsagePage == HID_USAGE_PAGE_GENERIC && DI.wUsage == HID_USAGE_GENERIC_MOUSE)
{
DI.dwDevType = (DI.dwDevType & ~DIDEVTYPE_DEVICE) | DIDEVTYPE_MOUSE;
}
// Check if the device is a joystick or gamepad
else if (DI.wUsagePage == HID_USAGE_PAGE_GENERIC &&
(DI.wUsage == HID_USAGE_GENERIC_JOYSTICK || DI.wUsage == HID_USAGE_GENERIC_GAMEPAD))
{
DI.dwDevType = (DI.dwDevType & ~DIDEVTYPE_DEVICE) | DIDEVTYPE_JOYSTICK;
}
// Check if the device is a keyboard
else if ((DI.wUsagePage == HID_USAGE_PAGE_GENERIC && DI.wUsage == HID_USAGE_GENERIC_KEYBOARD) ||
DI.wUsagePage == HID_USAGE_PAGE_KEYBOARD)
{
DI.dwDevType = (DI.dwDevType & ~DIDEVTYPE_DEVICE) | DIDEVTYPE_KEYBOARD;
}
}
DI.dwDevType = devType7 | (devSubType7 << 8) | hidDevice;

return self->lpCallback(&DI, self->pvRef);
}
} CallbackContext;
CallbackContext.pvRef = pvRef;
CallbackContext.lpCallback = lpCallback;
// DirectInput 0x300 and earlier do not enumerate any game controllers
CallbackContext.bEnumerateGameControllers = diVersion > 0x300;
CallbackContext.dwStructSize = diVersion >= 0x500 ? sizeof(D) : sizeof(D_Old);
CallbackContext.diVersion = diVersion;

// Reorder to send game devices first
if (dwDevType == DI8DEVCLASS_ALL)
Expand Down

0 comments on commit 0a3a399

Please sign in to comment.