Gadgets

Detecting if a Game Pad is Plugged in or Removed

In the latest download of our shoot em up pc game TWTPB, iteration 23, I implemented basic game pad support. There are a number of issues with this implementation maybe the most prominent one being that it does not handle plugging in and out the game pad during play. I think that it is probably a common scenario to plug in a game pad after the game has started.

This is a short tutorial on how to get your game to react when an usb device, such as a game pad, is plugged in or removed from the computer. This is handy when using the DirectInput api. XInput handles this in a transparent way which is nice, but alas there are many game controls that are not XInput compatible so when developing a pc game you probably need support for both plain DirectInput devices and XInput devices. This tutorial is Windows specific and in the C++ language.

It is not that hard to get a message when a device is added or removed, but it involves some rarely used win32 code that I spent a good few hour trying to get to work.

To start things off Windows sends you the handy WM_DEVICECHANGE windows message message when a device is plugged in or removed from the pc. So in your window message handling function you should have something like this:


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;
       ...
   }
   ...
}

The there are also a number of other messages sent in the wparam parameter. So the tricky part here is that you won't get the DBT_DEVICEARRIVAL or DBT_DEVICEREMOVECOMPLETE as a default. You will only get a number of DBT_DEVNODES_CHANGED messages whether a device is plugged in or removed and this is obviously not what we want in our game code.

You will have to tell Windows that you want additional information when a device is added. You can do this with the RegisterDeviceNotification function. This function is quite complicated and takes a number of strange parameters. I for one love when a function has a void pointer as a parameter, it's great, you can just send anything down there Eye-wink

Anyway the thing we want is to listen to in our game is the device broadcast messages. The following code sets that up. I added this to my window creation function since you need a window handle to the main window, declared as m_hWnd in the code below. The setup is actually much easier than you think by looking at the docs.


DEV_BROADCAST_DEVICEINTERFACE notificationFilter;
ZeroMemory(&notificationFilter, sizeof(notificationFilter));
 
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
}

By using the handy DEVICE_NOTIFY_ALL_INTERFACE_CLASSES flag we can skip most parameters in the notificationFilter parameter except type and size.

Also for this code to even compile you also need to have WINVER defined >= 0x0500 like


#define WINVER 0x0500

Now Windows will send you all messages when a game pad is attached or removed from the pc and you can take the appropriate action in your game code.

Hope you'll find this short article/tutorial handy! Feel free to comment or suggest improvements.


users avatar

Nintendo DS or Sony PSP

I have realized that I need to play more games. Also I don't have the time to really sit down and play so I got thinking that maybe a portable gaming device would be cool. Then I can utilize many smaller snippets of time instead of devoting long hours.

The last time I owned a portable was my old Game & Watch Donkey Kong JR. That was a great game and the only portable I have ever owned. Even my mum considered herself a gamer in those days. My sister and she even started playing the game upside down to get more of a challenge. Alas my hot tempered sister threw the game in the wall in frustration Sticking out tongue, and that was it for the poor fellow...

Anyway I have not paid any attention to the portable scene in a few years but I guess it it pretty much down to getting a Nintendo DS or a Sony PSP. Price is about the same, the PSP is more techy but the DS has the touch screen advantage and is compatible with Gameboy Advance games.

Right now I'm leaning towards the DS... but I really don't know. If you got any experiences or suggestions I'd really like to know...


users avatar
Syndicate content