April 2011 Archives

Keyboard Question MarkAs I said at the end of my last post, I was going to write an article listing all the little handy utilities/settings that make my life easier as a programmer, but in a change in schedule I've decided to postpone that and write about something I've been coding this week instead whilst it's still fresh in my mind.

As I'm writing my own engine, one of the first things that needs to be done is input processing. In the latest DirectX SDK, there are two options listed for input, namely DirectInput8 and XInput. DirectInput8 is long in the tooth, being over a decade old and has localisation issues as I'll discuss below. XInput is newer and is a cleaner API, but seems to exist entirely for using Xbox 360 controllers (presumably as an aid to porting) and supports nothing else. Neither seemed to be an ideal solution to me.

Twitter to the Rescue

I asked about this on Twitter and got a few replies suggesting I use the Raw Input API which I wasn't previously aware of. Richard Sim pointed me to this MSDN articlecomparing the APIs (in this case the example is reading mouse input). As you can see, the code for using Raw Input is a lot cleaner and simpler than DirectInput8. The article also says that DirectInput8 is built on top of the Raw Input API and uses a separate thread to capture the WM_INPUT messages, adding overhead in the process. It felt to me that using Raw Input directly was the better solution.

Using Raw Input

The MSDN documentation for the Raw Input API is missing a few things which I've had to dig around and find out for myself, so I'll explain what I've found out here. The basic process is that in your initialisation code you register the devices you'd like input from using RegisterRawInputDevices(), and then you receive WM_INPUT messages from the device in the Windows message loop from which you extract the actual keys/mouse input/etc. If you want to register for input from the keyboard, you would use the following code.

RAWINPUTDEVICE keyboard_device;
keyboard_device.usUsagePage = 0x01;
keyboard_device.usUsage = 0x06;
keyboard_device.hwndTarget = hWnd;
keyboard_device.dwFlags = 0;

BOOL ret = RegisterRawInputDevices(&keyboard_device, 1, sizeof(RAWINPUTDEVICE));

The question is - where on Earth do those UsagePage and Usage numbers come from? The MSDN documentation doesn't explain, but after a bit of digging I found out that they're part of the USB HID standard (pdf). On page 26 is table 1 for generic desktop devices, and the keyboard is device number 6, hence the numbers passed to the code above. For the mouse you would use page 1, usage 2. In fact, the Raw Input API lets you register multiple device at once as shown here.

RAWINPUTDEVICE keyboard_and_mouse_devices[2];
keyboard_and_mouse_devices[0].usUsagePage = 0x01; // Generic desktop page
keyboard_and_mouse_devices[0].usUsage = 0x06;     // Keyboard
keyboard_and_mouse_devices[0].hwndTarget = hWnd;
keyboard_and_mouse_devices[0].dwFlags = 0;
keyboard_and_mouse_devices[1].usUsagePage = 0x01; // Generic desktop page
keyboard_and_mouse_devices[1].usUsage = 0x02;     // Mouse
keyboard_and_mouse_devices[1].hwndTarget = hWnd;
keyboard_and_mouse_devices[1].dwFlags = 0;

BOOL ret = RegisterRawInputDevices(keyboard_and_mouse_devices, 2, sizeof(RAWINPUTDEVICE));

I have no idea why the API insists you pass the size of the RAWINPUTDEVICE struct as the final parameter, though it seems to be a common trait for Win32 API functions.

I think the MSDN docs explain actually getting the data well enough, so I won't repeat that here.

Once your application is registered to recieve WM_INPUT messages, it will also receive WM_INPUT_DEVICE_CHANGE messages whenever a device is added/removed from the system so you can print up "Controller Removed" messages, or switch to an alternate controller as your game requires.

Wrapping Up

I mentioned above that DirectInput8 has localisation issues. What I mean by this is that often in games you need to show the name of the key on screen in control select screens or tutorials. To do this you would use GetKeyNameText() which will return a string from a scan code. Unfortunately, DirectInput8 uses its own DIK_ enums for the keys, which don't exactly map onto scan codes. On previous games I've worked on, we've ended up with a large remapping table, with a few exceptions for various locales. The Raw Input API gives you the scan code directly as well as the virtual VK_ enum, so in theory this problem disappears (I still need to confirm this).

This is a crosspost from AltDevBlogADay - 

This is a crosspost from AltDevBlogADay - http://altdevblogaday.org/2011/04/10/workstation-setup-for-gamedevs/.

Greetings all! For my first post I thought I'd start with something I've been thinking about lately. As I'm preparing to leave "AAA" games development and become a fledgling indie, I need to set up my home office for maximum productivity and comfort. I don't have a facilities department to handle all of this for me, so here's my tips for comfort based on my experiences. I'll leave out the actual PC/Mac hardware itself and focus more on the ergonomic aspect of things. This article isn't meant to be authoritative (how could it be without reams of ergonomic data?) so I've avoided recommending specific products, but the general point is that you should try out a few things until you find what works best for you.

Chair - First and foremost, you need a good chair. I can't stress this enough after having lower back pain from working on a bad office chair a few years ago. If you can afford it (and have space in your home office), get an Aeron or whatever your favourite type of chair is. A really good chair may cost a lot at first, but you'll be sitting, slouching and wheeling around on it for a long time so it's a worthwhile investment. It's not something to skimp on. Make sure you take the type of chair for a test run (test sit?) if possible. A few seconds sat on one in a shop really isn't enough. If you know someone who has the chair you're thinking of buying, ask if you can spend an hour or so working on it to see how it works for you (although you may irritate them if you change the settings too much!). Last of all, make sure you're really happy with your choice before handing over your money.

I'm typing this article sat on a solid wooden Ikea Ivar borrowed from the dining room which is far from ideal, so I need to sort out a proper chair sooner rather than later!

Desk - A desk is easier to sort out. It just needs to be the right height (or adjustable) and big enough to put everything you want on it. Also it needs no obstructions underneath for your knees to accidentally bash against. I'm using an Ikea Galant which is a nice corner desk that fits nicely in the room I'm using, has adjustable height legs, is pretty strong (it is no problem for me to sit on it) and it is easily big enough for all the desktop equipment I need. Make sure you have measurements of the room you're going to use before buying so you can eliminate anything that won't fit quickly.

Monitor(s) and Light - A monitor should be big, bright, comfortable to read, well calibrated and more than one if possible. Make sure the height is set up so you don't strain your neck as you look at it. I'm counting light as part of this category as I think it is intrinsically linked to how well your monitor works for you. I like there to be a good level of ambient light in the room to avoid eye-strain from the monitors, but make sure the light is out of your field of vision or it will irritate you in your peripheral zone. Other people I've worked with (mostly artists and older coders), seem to have a preference for working in the dark - though I find that odd as it hurts my eyes after a while. I can (sort of) understand that way of working in the bad old days of curved, highly reflective CRT monitors as darkness would minimise reflections, but these days I think that is minimal. However, it is of course up to you how you light your room - whatever works best for you is most important.

Keyboard - You're going to need something you can type on for hours without causing pain to your wrists. Ideally you want your hands and forearms fairly flat on the desk and not bent upwards so your wrists aren't strained. Ergonomic, straight - it's up to you, but find something that works for you and doesn't cause pain after extended use. Also, you need to find a keyboard that has a key feel you like (how much travel, how "clicky" it is), sounds right (not too loud, not too quiet). Some keyboards also have extra buttons mimicking browser navigation, application shortcuts, volume control, etc. How useful these features are is debatable (I quite like having volume/mute buttons), but once again what works for you is best.

Mouse - Likewise, find something that fits your hand well, has all the buttons you need (mine is right hand shaped with two handy thumb buttons) and slides about the desk smoothly. Optical mice are all very good these days in terms of ability to read surfaces accurately so unless your desk is made of glass, you shouldn't need a mouse mat. Alternatively, you might be someone who prefers a pad, trackball or other pointing device - I only have limited experience with these so comments below welcome! I've recently bought a Wacom Bamboo pad and am getting used to using a pen as a pointing device (as well as for drawing lines and curves).

Headphones - As I'll be working in a house with two young children around, I'll need a way to block out the distraction of their noise whilst they are playing, so a good, comfortable set of headphones is important to me. Find some that don't hurt your ears and have good sound quality (I find cheap tinny sound tends to irritate after a while). Noise cancelling is an option, though on the ones I've tried, sound quality seems flatter (perhaps that's just me though).

Space - An odd thing to include, but I find that when I'm stuck on a problem, I like to pace back on forth whilst my brain is working on a solution. It's something I've deliberately refrained from at big companies as being watched by an office full of people stops my thought processes, but I do it at home (to the chagrin of my wife). Having an area you can do this without driving the people who live with you insane is probably a good idea!

I'd love comments on this article from people with suggestions of your own. For my next article, I plan to look at the software side of things - those little utilities that make my life as a programmer easier and more productive.

About this Archive

This page is an archive of entries from April 2011 listed from newest to oldest.

February 2011 is the previous archive.

May 2011 is the next archive.

Find recent content on the main index or look in the archives to find all content.