Lets talk about RAWINPUT and why it is a useful tool for any game engine programmer to understand.
So what is RAWINPUT?
Well it is an alternative to using the standard method Windows input method, it provides methods for not only accessing the keyboard and mouse, but any HID device.
Before the RAWINPUT API was implemented you had to according to MSDN:
To get input from the unsupported HIDs, an application had to do many things: open the device, manage the shared mode, periodically read the device or set up the I/O completion port, and so forth. The raw input model and the associated APIs were developed to allow simple access to raw input from all input devices, including the keyboard and mouse.
RAWINPUT is different that the standard windows input which relies on posted messages which means only devices that Windows implements handling for can be handled. With RAWINPUT the user needs to according to MSDN.
for raw input an application must register the devices it wants to get data from. Also, the application gets the raw input through the WM_INPUT message.
Lets talk about how to implement a basic RAWINPUT setup in code.
This assumes you are already using the Windows API for creating and opening a window and have a basic knowledge of the Windows API.
The first thing you need to do is register the input devices, for this example I will be sticking to just the mouse and the keyboard.
RAWINPUTDEVICE keyboard;
RAWINPUTDEVICE mouse;
keyboard.usUsagePage = 0x01;
keyboard.usUsage = 0x06;
keyboard.dwFlags = NULL;
keyboard.hwndTarget = hWnd;
mouse.usUsagePage = 0x01;
mouse.usUsage = 0x02;
mouse.dwFlags = NULL;
mouse.hwndTarget = hWnd;
if(!RegisterRawInputDevices(&keyboard, 1, sizeof(RAWINPUTDEVICE)))
{
Logger::getInstance()->write("Failed to register the keyboard device");
}
if(!RegisterRawInputDevices(&mouse, 1, sizeof(RAWINPUTDEVICE)))
{
Logger::getInstance()->write("Failed to register the mouse device");
}
After this you need to handle the input as part of the windows loop. All you need to do here is add an additional case to handle WM_INPUT, then you can break up the input into a type and pass it off to whatever handlers you want.
case WM_INPUT:
{
RAWINPUT InputData;
UINT DataSize = sizeof(RAWINPUT);
GetRawInputData((HRAWINPUT)lParam,
RID_INPUT,
&InputData,
&DataSize,
sizeof(RAWINPUTHEADER));
if(InputData.header.dwType == RIM_TYPEKEYBOARD)
{
// Pass InputData.data.keyboard to your keyboard handler
}
if(InputData.header.dwType == RIM_TYPEMOUSE)
{
// Pass InputData.data.mouse to your keyboard handler.
}
return 0;
}
In order to handle the input data you need check what value the Vkey variable is. Here is a condensed list of the most common keys. for a more complete list check
Here. The following is for the keyboard.
0x08 // BACKSPACE key
0x09 // TAB key
0x0C // CLEAR key
0x0D // ENTER key
if(MakeCode == 0x1C && Flags == (RI_KEY_MAKE|RI_KEY_E0) || Flags == (RI_KEY_BREAK|RI_KEY_E0)) // Right Input Key
else if(MakeCode == 0x1C && Flags == (RI_KEY_MAKE|!RI_KEY_E0) || Flags == (RI_KEY_BREAK|!RI_KEY_E0)) // Left Input Key
0x10 // SHIFT key
if(MakeCode == 0x2A) // Left Shift
else if (MakeCode == 0x36) // Right Shift
0x11 // CTRL key
if (MakeCode == 0x1D && Flags == (RI_KEY_MAKE|RI_KEY_E0) || Flags == (RI_KEY_BREAK|RI_KEY_E0)) // Right Control
else if (MakeCode == 0x1D && Flags == (RI_KEY_MAKE|!RI_KEY_E0) || Flags == (RI_KEY_BREAK|!RI_KEY_E0)) // Left Control
0x12 // ALT key
if (MakeCode == 0x38 && Flags == (RI_KEY_MAKE|RI_KEY_E0) || Flags == (RI_KEY_BREAK|RI_KEY_E0)) // Right Alt
else if (MakeCode == 0x38 && Flags == (RI_KEY_MAKE|!RI_KEY_E0) || Flags == (RI_KEY_BREAK|!RI_KEY_E0)) // Left Alt
0x13 // PAUSE key
0x14 // CAPS LOCK key
0x1B // ESC key
0x20 // SPACEBAR
0x21 // PAGE UP key
0x22 // PAGE DOWN key
0x23 // END key
0x24 // HOME key
0x25 // LEFT ARROW key
0x26 // UP ARROW key
0x27 // RIGHT ARROW key
0x28 // DOWN ARROW key
0x2C // PRINT SCREEN key
0x2D // INS key
0x2E // DEL key
0x30 // 0 key
0x31 // 1 key
0x32 // 2 key
0x33 // 3 key
0x34 // 4 key
0x35 // 5 key
0x36 // 6 key
0x37 // 7 key
0x38 // 8 key
0x39 // 9 key
0x41 // A key
0x42 // B key
0x43 // C key
0x44 // D key
0x45 // E key
0x46 // F key
0x47 // G key
0x48 // H key
0x49 // I key
0x4A // J key
0x4B // K key
0x4C // L key
0x4D // M key
0x4E // N key
0x4F // O key
0x50 // P key
0x51 // Q key
0x52 // R key
0x53 // S key
0x54 // T key
0x55 // U key
0x56 // V key
0x57 // W key
0x58 // X key
0x59 // Y key
0x5A // Z key
0x60 // Numeric keypad 0 key
0x61 // Numeric keypad 1 key
0x62 // Numeric keypad 2 key
0x63 // Numeric keypad 3 key
0x64 // Numeric keypad 4 key
0x65 // Numeric keypad 5 key
0x66 // Numeric keypad 6 key
0x67 // Numeric keypad 7 key
0x68 // Numeric keypad 8 key
0x69 // Numeric keypad 9 key
0x6A // Multiply key
0x6B // Add key
0x6D // Subtract key
0x6E // Decimal key
0x6F // Divide key
0x70 // F1 key
0x71 // F2 key
0x72 // F3 key
0x73 // F4 key
0x74 // F5 key
0x75 // F6 key
0x76 // F7 key
0x77 // F8 key
0x78 // F9 key
0x79 // F10 key
0x7A // F11 key
0x7B // F12 key
0x90 // NUM LOCK key
0x91 // SCROLL LOCK key
0xBA // Windows 2000 for the US standard keyboard, the ';' key
0xBB // Windows 2000 for any country/region, the '=+' key
0xBC // Windows 2000 for any country/region, the ',<' key
0xBD // Windows 2000 for any country/region, the '-_' key
0xBE // Windows 2000 for any country/region, the '.>' key
0xBF // Windows 2000 for the US standard keyboard, the '/?' key
0xC0 // Windows 2000 for the US standard keyboard, the '`~' key
0xDB // Windows 2000 for the US standard keyboard, the '[{' key
0xDC // Windows 2000 for the US standard keyboard, the '\|' key
0xDD // Windows 2000 for the US standard keyboard, the ']}' key
0xDE // Windows 2000 for the US standard keyboard, the 'single-quote/double-quote' key
For the mouse you will need these codes.
case 0x0001: // Left mouse button down
case 0x0002: // Left mouse button up
case 0x0004: // Right mouse button down
case 0x0008: // Right mouse button up
case 0x0010: // Middle mouse button (three-button mouse) down
case 0x0020: // Middle mouse button (three-button mouse) up
case 0x0040: // Windows 2000: X1 mouse button down
case 0x0080: // Windows 2000: X1 mouse button up
case 0x100: // Windows 2000: X2 mouse button down
case 0x0200: // Windows 2000: X2 mouse button up
case 0x0400: // Mouse Wheel
You should handle these in any way you see fit, but everything above will get you started in implementing RAWINPUT into your engine.
For additional information visit
MSDN RAW INPUT