Skip to main content
GameDev.net gamedev.net
🔒 Locked

Direct input keyboard & input languages

Started by leidegren Oct 15, 2007 at 3:50 PM 4 replies 5.6k views
Original Post
leidegren
leidegren
Okay, so what I get from a Direct Input device (keyboard) is scan codes. I need to translate this into more sensible keystrokes. For instance, i'm a bit concerned with keyboard layouts. I know of a couple popular functions like MapVirtualKeyEx and ToAsciiEx. It would be fine by me to constrain the input to this (e.g. not considering Japanees). The thing is that the acutal returned language by GetKeyboardLayout() on main thread is still 'en' while i use a swedish keyboard layout. But this seem to have some other unforseen impact, as 'W' ends up as a upwards arrow in the console. And don't even get me started on characters such as åäö, or for that matter CAPS LOCK or Shift combinations... it' seem to make no difference... This is the code I'm using:

S_UINT read = 10;
HRESULT hr = m_dx8Keyboard->GetDeviceData( sizeof( DIDEVICEOBJECTDATA ), m_dData, (LPDWORD)&read, 0 );
m_dx8Keyboard->GetDeviceState( 0x100, m_keyboardState )
for( S_UINT i = 0; i < read; i++ )
{
WORD c;
S_UINT sc = m_dData.dwOfs; // Scan code
S_UINT vkey = MapVirtualKeyEx( sc, 1, m_keyboardLayout );

if( ToAsciiEx( vkey, sc, m_keyboardState, &c, 0, m_keyboardLayout ) )
    printf( "KEY %3u %c\n", sc, char(c) );
}
This is just a fragment, but I hope it shows well enough of what I'm currently doing. e.g. that I'm using the state from the direct input device and what methods i'm calling to get the actual output. I don't mind writing a bit of code, but what I want is a way of mapping these direct input scan codes to some sensible text output, or keystrokes. probably by putting this into my own custom format to represent actions i can trigger on certain combinations. But i wannt to use as much of the WINAPI as possible to accomplish this so that most of the work will be done by the API as long as the correct input locale is provided. But this is obivously not working and I'm not sure why...

m_keyboardLayout = GetKeyboardLayout(); // Current thread
WORD lcid = (WORD)m_keyboardLayout; // low-word equals language identifier
CHAR langName[9];
GetLocaleInfo( lcid, LOCALE_SISO639LANGNAME, langName, 9 );
printf( "ISO639LANGNAME: %s\n", langName );
e.g. the above code should (according to me) print 'sv' since that's my keyboard layout, but it prints 'en'... I would be very greatful for any advice when using a Direct Input Keyboard.
MJP
MJP
If you'd like my advice regarding using DirectInput keyboard input....its that you shoudn't use DirectInput keyboard input. Handling the standard Windows messages for keyboard input is not only easier and simpler, but will allow you to use international keyboards without a problem.

From a performance perspective using DirectInput isn't a good idea either, since internally it creates a thread that's just used for processing Windows RawInput messages.
leidegren
leidegren
How obsolete is Direct Input really?

I've been using the RAWINPUT stuff and WM_INPUT instead and seems to work just as well. But for some reason the code I'm using now is making the window useless, the cursor hover the window with the waiting cursor and is bascially non-responsive...

RAWINPUTDEVICE Rid[2];        Rid[0].usUsagePage  = 0x01; Rid[0].usUsage      = 0x02;             // MouseRid[0].dwFlags      = RIDEV_NOLEGACY;   Rid[0].hwndTarget   = 0;Rid[1].usUsagePage  = 0x01; Rid[1].usUsage      = 0x06;             // KeyboardRid[1].dwFlags      = RIDEV_NOLEGACY;   Rid[1].hwndTarget   = 0;if( RegisterRawInputDevices( Rid, 2, sizeof( RAWINPUTDEVICE ) ) ){    printf( "RegisterRawInputDevices: OK\n" );}


I'm recieving the correct WM_INPUT messages, but the window itself is not usable... I realized that this is due to the RIDEV_NOLEGACY flag, no WM_MOUSEMOVE or WM_KEYPRESSED seem to be sent. But when working with a game, you don't really need that input, so it seems kinda redudant, is there a good middle-ground between using raw input and keeping the window itself reponsive?

[Edited by - leidegren on October 16, 2007 2:52:18 AM]
Evil Steve
Evil Steve
Quote:
Original post by Mike.Popoloski
I am going to preempt Evil Steve here by linking to his journal:

Reasons not to use DirectInput for Keyboard Input.
Hooray! I knew that would come in handy [smile]

Quote:
Original post by leidegren
How obsolete is Direct Input really?
The only reason for using it is if you're targetting Win9x (Which is 10 years old and not even supported by Microsoft any more) where WM_INPUT isn't available. It's available on Win2k and above.

Quote:
Original post by leidegren
I've been using the RAWINPUT stuff and WM_INPUT instead and seems to work just as well. But for some reason the code I'm using now is making the window useless, the cursor hover the window with the waiting cursor and is bascially non-responsive...
Why use raw input at all for keyboard input? Your window procedure is already recieving WM_KEYUP, WM_KEYDOWN and WM_CHAR messages, you might as well use them instead of jumping through hoops and even slowing things down (Admittedly by a tiny amount) by using raw input.
You should be pumping your window messages once per game loop anyway, so your WM_KEY* messages will be processed anyway.
leidegren
leidegren
Actually I have diffrent approach. And I'm confident that raw input is the way to go for me. e.g. WM_MOUSEMOVE is not sent if the mouse is not moved ontop of the window while raw input, sends WM_INPUT as long as the window has focus. Also high-resolution data is not available with WM_MOUSEMOVE so raw input is a better. I'm also confident in that raw input has a smaller overhead...

I'm not running the game and the message pump on the same thread, I would never do that, and I will never consider it. The message pump is only conserned with significant win32 messages...

But there is still the issue with running the game in windowed mode. As the window doesn't respond at all. This works fine with full-screen game but not with a windowed game.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.