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: */ /* Number of joysticks found: */
static int g_iNumJoysticks; static int g_iNumJoysticks;
static BOOL CALLBACK EnumDevices( const DIDEVICEINSTANCE *pdidInstance, void *pContext ) static BOOL CALLBACK EnumDevicesCallback( const DIDEVICEINSTANCE *pdidInstance, void *pContext )
{ {
DIDevice device; 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. (*(int*)pContext)++;
// TODO: Does this work in Win98 and Win2K? return DIENUM_CONTINUE;
int i = 0; }
RegistryAccess::GetRegValue( "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\HidUsb\\Enum", "Count", i, false ); // don't warn on error
return i; 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() InputHandler_DInput::InputHandler_DInput()
@@ -76,21 +85,20 @@ InputHandler_DInput::InputHandler_DInput()
CheckForDirectInputDebugMode(); CheckForDirectInputDebugMode();
m_bShutdown = false; m_bShutdown = false;
m_iLastSeenNumUsbHid = GetNumUsbHidDevices();
g_iNumJoysticks = 0; g_iNumJoysticks = 0;
AppInstance inst; 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 ) if( hr != DI_OK )
RageException::Throw( hr_ssprintf(hr, "InputHandler_DInput: DirectInputCreate") ); RageException::Throw( hr_ssprintf(hr, "InputHandler_DInput: DirectInputCreate") );
LOG->Trace( "InputHandler_DInput: IDirectInput::EnumDevices(DIDEVTYPE_KEYBOARD)" ); 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 ) if( hr != DI_OK )
RageException::Throw( hr_ssprintf(hr, "InputHandler_DInput: IDirectInput::EnumDevices") ); RageException::Throw( hr_ssprintf(hr, "InputHandler_DInput: IDirectInput::EnumDevices") );
LOG->Trace( "InputHandler_DInput: IDirectInput::EnumDevices(DIDEVTYPE_JOYSTICK)" ); 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 ) if( hr != DI_OK )
RageException::Throw( hr_ssprintf(hr, "InputHandler_DInput: IDirectInput::EnumDevices") ); RageException::Throw( hr_ssprintf(hr, "InputHandler_DInput: IDirectInput::EnumDevices") );
@@ -116,6 +124,8 @@ InputHandler_DInput::InputHandler_DInput()
Devices[i].buffered? "buffered": "unbuffered" ); Devices[i].buffered? "buffered": "unbuffered" );
} }
m_iLastSeenNumJoysticks = GetNumJoysticksQuick();
StartThread(); StartThread();
} }
@@ -149,8 +159,8 @@ InputHandler_DInput::~InputHandler_DInput()
Devices[i].Close(); Devices[i].Close();
Devices.clear(); Devices.clear();
dinput->Release(); g_dinput->Release();
dinput = NULL; g_dinput = NULL;
} }
void InputHandler_DInput::WindowReset() void InputHandler_DInput::WindowReset()
@@ -505,9 +515,9 @@ void InputHandler_DInput::Update()
bool InputHandler_DInput::DevicesChanged() bool InputHandler_DInput::DevicesChanged()
{ {
int iOldNumUsbHid = m_iLastSeenNumUsbHid; int iOldNumJoysticks = m_iLastSeenNumJoysticks;
m_iLastSeenNumUsbHid = GetNumUsbHidDevices(); m_iLastSeenNumJoysticks = GetNumJoysticksQuick();
return iOldNumUsbHid != m_iLastSeenNumUsbHid; return iOldNumJoysticks != m_iLastSeenNumJoysticks;
} }
void InputHandler_DInput::InputThreadMain() void InputHandler_DInput::InputThreadMain()
@@ -18,7 +18,7 @@ public:
private: private:
RageThread m_Thread; RageThread m_Thread;
bool m_bShutdown; 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 UpdatePolled( DIDevice &device, const RageTimer &tm );
void UpdateBuffered( DIDevice &device, const RageTimer &tm ); void UpdateBuffered( DIDevice &device, const RageTimer &tm );
@@ -10,7 +10,7 @@
#pragma comment(lib, "dxguid.lib") #pragma comment(lib, "dxguid.lib")
#endif #endif
#endif #endif
LPDIRECTINPUT dinput = NULL; LPDIRECTINPUT g_dinput = NULL;
static int ConvertScancodeToKey( int scancode ); static int ConvertScancodeToKey( int scancode );
static BOOL CALLBACK DIJoystick_EnumDevObjectsProc(LPCDIDEVICEOBJECTINSTANCE dev, LPVOID data); static BOOL CALLBACK DIJoystick_EnumDevObjectsProc(LPCDIDEVICEOBJECTINSTANCE dev, LPVOID data);
@@ -30,7 +30,7 @@ bool DIDevice::Open()
buffered = true; buffered = true;
LPDIRECTINPUTDEVICE tmpdevice; LPDIRECTINPUTDEVICE tmpdevice;
HRESULT hr = dinput->CreateDevice( JoystickInst.guidInstance, &tmpdevice, NULL ); HRESULT hr = g_dinput->CreateDevice( JoystickInst.guidInstance, &tmpdevice, NULL );
if ( hr != DI_OK ) if ( hr != DI_OK )
{ {
LOG->Info( hr_ssprintf(hr, "OpenDevice: IDirectInput_CreateDevice") ); LOG->Info( hr_ssprintf(hr, "OpenDevice: IDirectInput_CreateDevice") );
@@ -5,7 +5,7 @@
#define DIRECTINPUT_VERSION 0x0500 #define DIRECTINPUT_VERSION 0x0500
#include <dinput.h> #include <dinput.h>
extern LPDIRECTINPUT dinput; extern LPDIRECTINPUT g_dinput;
#define INPUT_QSIZE 32 #define INPUT_QSIZE 32