poll DInput for number of joysticks instead of polling registry for num HID devices. Fixes us resetting INPUTMAN too early (after Windows sees the HID device but before DirectInput exposes it)

This commit is contained in:
Chris Danford
2006-02-09 00:53:20 +00:00
parent ecce21a0b4
commit a1fcc64baf
4 changed files with 30 additions and 20 deletions
@@ -16,7 +16,7 @@ static vector<DIDevice> Devices;
/* Number of joysticks found: */
static int g_iNumJoysticks;
static BOOL CALLBACK EnumDevices( const DIDEVICEINSTANCE *pdidInstance, void *pContext )
static BOOL CALLBACK EnumDevicesCallback( const DIDEVICEINSTANCE *pdidInstance, void *pContext )
{
DIDevice device;
@@ -60,13 +60,22 @@ static void CheckForDirectInputDebugMode()
}
}
static int GetNumUsbHidDevices()
static BOOL CALLBACK CountDevicesCallback( const DIDEVICEINSTANCE *pdidInstance, void *pContext )
{
// The "Enum" key doesn't exist if no hid devices are attached, so it's expected that GetRegValue will sometimes fail.
// TODO: Does this work in Win98 and Win2K?
int i = 0;
RegistryAccess::GetRegValue( "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\HidUsb\\Enum", "Count", i, false ); // don't warn on error
return i;
(*(int*)pContext)++;
return DIENUM_CONTINUE;
}
static int GetNumJoysticksQuick()
{
int iCount = 0;
HRESULT hr = g_dinput->EnumDevices( DIDEVTYPE_JOYSTICK, CountDevicesCallback, &iCount, DIEDFL_ATTACHEDONLY );
if( hr != DI_OK )
{
LOG->Warn( hr_ssprintf(hr, "g_dinput->EnumDevices") );
}
return iCount;
}
InputHandler_DInput::InputHandler_DInput()
@@ -76,21 +85,20 @@ InputHandler_DInput::InputHandler_DInput()
CheckForDirectInputDebugMode();
m_bShutdown = false;
m_iLastSeenNumUsbHid = GetNumUsbHidDevices();
g_iNumJoysticks = 0;
AppInstance inst;
HRESULT hr = DirectInputCreate(inst.Get(), DIRECTINPUT_VERSION, &dinput, NULL);
HRESULT hr = DirectInputCreate(inst.Get(), DIRECTINPUT_VERSION, &g_dinput, NULL);
if( hr != DI_OK )
RageException::Throw( hr_ssprintf(hr, "InputHandler_DInput: DirectInputCreate") );
LOG->Trace( "InputHandler_DInput: IDirectInput::EnumDevices(DIDEVTYPE_KEYBOARD)" );
hr = dinput->EnumDevices( DIDEVTYPE_KEYBOARD, EnumDevices, NULL, DIEDFL_ATTACHEDONLY );
hr = g_dinput->EnumDevices( DIDEVTYPE_KEYBOARD, EnumDevicesCallback, NULL, DIEDFL_ATTACHEDONLY );
if( hr != DI_OK )
RageException::Throw( hr_ssprintf(hr, "InputHandler_DInput: IDirectInput::EnumDevices") );
LOG->Trace( "InputHandler_DInput: IDirectInput::EnumDevices(DIDEVTYPE_JOYSTICK)" );
hr = dinput->EnumDevices( DIDEVTYPE_JOYSTICK, EnumDevices, NULL, DIEDFL_ATTACHEDONLY );
hr = g_dinput->EnumDevices( DIDEVTYPE_JOYSTICK, EnumDevicesCallback, NULL, DIEDFL_ATTACHEDONLY );
if( hr != DI_OK )
RageException::Throw( hr_ssprintf(hr, "InputHandler_DInput: IDirectInput::EnumDevices") );
@@ -116,6 +124,8 @@ InputHandler_DInput::InputHandler_DInput()
Devices[i].buffered? "buffered": "unbuffered" );
}
m_iLastSeenNumJoysticks = GetNumJoysticksQuick();
StartThread();
}
@@ -149,8 +159,8 @@ InputHandler_DInput::~InputHandler_DInput()
Devices[i].Close();
Devices.clear();
dinput->Release();
dinput = NULL;
g_dinput->Release();
g_dinput = NULL;
}
void InputHandler_DInput::WindowReset()
@@ -505,9 +515,9 @@ void InputHandler_DInput::Update()
bool InputHandler_DInput::DevicesChanged()
{
int iOldNumUsbHid = m_iLastSeenNumUsbHid;
m_iLastSeenNumUsbHid = GetNumUsbHidDevices();
return iOldNumUsbHid != m_iLastSeenNumUsbHid;
int iOldNumJoysticks = m_iLastSeenNumJoysticks;
m_iLastSeenNumJoysticks = GetNumJoysticksQuick();
return iOldNumJoysticks != m_iLastSeenNumJoysticks;
}
void InputHandler_DInput::InputThreadMain()
@@ -18,7 +18,7 @@ public:
private:
RageThread m_Thread;
bool m_bShutdown;
int m_iLastSeenNumUsbHid; // use this to figure out if a device was plugged/unplugged
int m_iLastSeenNumJoysticks; // use this to figure out if a joystick was plugged/unplugged
void UpdatePolled( DIDevice &device, const RageTimer &tm );
void UpdateBuffered( DIDevice &device, const RageTimer &tm );
@@ -10,7 +10,7 @@
#pragma comment(lib, "dxguid.lib")
#endif
#endif
LPDIRECTINPUT dinput = NULL;
LPDIRECTINPUT g_dinput = NULL;
static int ConvertScancodeToKey( int scancode );
static BOOL CALLBACK DIJoystick_EnumDevObjectsProc(LPCDIDEVICEOBJECTINSTANCE dev, LPVOID data);
@@ -30,7 +30,7 @@ bool DIDevice::Open()
buffered = true;
LPDIRECTINPUTDEVICE tmpdevice;
HRESULT hr = dinput->CreateDevice( JoystickInst.guidInstance, &tmpdevice, NULL );
HRESULT hr = g_dinput->CreateDevice( JoystickInst.guidInstance, &tmpdevice, NULL );
if ( hr != DI_OK )
{
LOG->Info( hr_ssprintf(hr, "OpenDevice: IDirectInput_CreateDevice") );
@@ -5,7 +5,7 @@
#define DIRECTINPUT_VERSION 0x0500
#include <dinput.h>
extern LPDIRECTINPUT dinput;
extern LPDIRECTINPUT g_dinput;
#define INPUT_QSIZE 32