Jump to content

Joystick Callback - DirectInput DIERR_INPUTLOST


photo

Recommended Posts

Unigine API Joystick support on Windows I believe is provided by DirectInput.

One of the return values for GetDeviceData (see link to docs below) is a flag indicating the device is no longer present.  There's an expectation among customers that should a device be unplugged (kicked out of the socket or swapped), the application should handle this elegantly.

Could we have call-backs in the Joystick API for DIERR_INPUTLOST and when new devices are available?


IDirectInputDevice8::GetDeviceData Method | Microsoft Docs

Link to comment

Thanks for looking at this request.

It's difficult to propose actual usage as I'm not clear on how Unigine under the hood uses DirectInput8 joysticks, ( event or polling method ).

I went to find some of my old DLL code that handled this only to find a zero files size which made me unhappy. However I can constructively reply with a little web based research.

Setting up Unigine user API call-backs should be similar to how your UI API call-backs work (consistency and path of least surprise). 
e.g.
 

Unigine.Input.AddCallback( Unigine.Input.CALLBACK_INDEX.HID_DEVICE_LOST , ()=> Log.MessageLine("HI Device Unplugged") );
Unigine.Input.AddCallback( Unigine.Input.CALLBACK_INDEX.HID_DEVICE_ADDED , ()=> Log.MessageLine("HI Device Plugged In") );




If you are polling via

IDirectInputDevice8::Poll

And the return value is: DIERR_INPUTLOST  then we should invoke the Device Lost call-back if configured. It's up to the user to handle these events and react appropriately, without impacting any existing Unigine input functionality.


To detect devices plugged in, that requires a bit more work and I haven't been able to fully test this yet. It requires registering your window handle to listen for device changes, then handling the WM_DEVICECHANGE event.

C++ code for Windows XP and upwards... For handling the event..
 

WndProc(HWND a_hWnd, UINT a_msg, WPARAM a_wparam, LPARAM a_lparam) {
   switch (a_msg) {
       ...
       case WM_DEVICECHANGE:
           if (a_wparam == DBT_DEVICEARRIVAL) {
               // Device plugged in code goes here
           } else if (a_wparam == DBT_DEVICEREMOVECOMPLETE) {
              // Device removed
           }
       break;
       ...
   }
   ...
}


And the important magic, the registering the hWnd window handle for receive the device change notification BUT with filter set to respond only for HID devices.....
 

DEV_BROADCAST_DEVICEINTERFACE notificationFilter;
ZeroMemory(&notificationFilter, sizeof(notificationFilter));
 

static const GUID GuidDevInterfaceHID = {0x745a17a0, 0x74d3, 0x11d0, { 0xb6, 0xfe, 0x00, 0xa0, 0xc9, 0x0f, 0x57, 0xda }};
notificationFilter.dbcc_classguid = GuidDevInterfaceHID;
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);
 
if(hDevNotify == NULL) {
   // do some error handling
}



Reading covered by this:
Registering for device notification - Win32 apps | Microsoft Docs
Detecting Media Insertion or Removal - Win32 apps | Microsoft Docs
DBT_DEVICEARRIVAL event (Dbt.h) - Win32 apps | Microsoft Docs



End comment: Just to restate that how it can be done depends on how Unigine reads DInput8 devices. But this is roughly how I did this in the past.

  • Like 1
Link to comment
×
×
  • Create New...