Archived

This topic is now archived and is closed to further replies.

BLZBub

DInput for getting text

Recommended Posts

This question has probably been asked before, but how do you use DI for getting input into a Quake-style console??? I''ve read a few articles on GameDev about DI and using various Win32 functions to get ASCII codes but I can''t figure out how to use them. Can anyone offer a simple explaination? I have just called GetDeviceState to fill my "char Keys[256]" array. How do I get a ''?'' or a ''{'' character from there? Thanks in advance....

Share this post


Link to post
Share on other sites
Yup its quite a common question, and the answer remains the same:

"DON''T USE DIRECTINPUT TO GET TEXT!"

DirectInput gets the ***RAW*** keyboard code, so it tells you "key number 162 was pressed". It is designed for "control" input rather than text input - its intended to be used as a 108 key joypad in DI.

The header file contains nice symbols like DIK_A and DIK_Y etc so many people expect that to always get you the same key on all keyboards - big mistake! - the DIK_ names only correspond to the keys on USA keyboards.
Its unfortunate that they named the symbols that way, its one of the core reasons people get confused by this.

If you have a German keyboard for example, pressing the Z key will report back as DIK_Y, and the Y key will report back as DIK_Z - this is because on a German keyboard the stickers on the keys are in different places to the layout of the USA keyboard.

A French keyboard is even more different.

A UK keyboard has the ", £, @ and # in different places.


There is another problem, there aren''t enough keys on a 108 key keyboard to have a key per character for some languages.

For accented European characters (ãàâäåèéêëö etc), the usual way of entering them is to first press a key representing the accent, then press a key for the letter (so for the ö, there''d be a keypress for the two dots, and a keypress for for the o).

For Eastern languages like Japanese it gets worse - they have around 3000 possible characters (Kanji) which isn''t going to fit onto a keyboard, even with CRTL, Alt etc. For this reason they use a thing called the IME which is a program which (AFAIK) lets them enter characters phonetically and will then display all the possible characters it could be in a selectable list. IME is a Windows program running separate to your program.


The usual response to that is "ok, I don''t care about IME, so how does Windows convert from a raw input code into an ASCII code ?". Its a long story but after a keypress has been directed through a few places (RIT etc), it gets translated by a keymap which is set by the locale you have chosen (look for .KBD files in Windows\System), this also handles deadkey characters (the double key sequences for European chars).

There are Windows calls which take a RAW Windows keycode and translate it to ASCII (but don''t handle double key sequences or IME), unfortunately they don''t take DirectInput raw codes - the codes can be different. DInput hooks into the keyboard at a much lower level than the Windows calls know about.


For any text entry in a Windows game, you should always respond to WM_CHAR messages - there is no reason to use DInput for text, and a few headaches if you do!! Objections ?:

1) "But my framerate will be affected by having to use Windows calls"
A) Not by any significant amount, and anyway when the player is typing in text they are hardly bothered about 60fps versus 55fps. When they''ve exited the console you can go back to using DirectInput to read the keyboard.

2) "But it''ll be loads of extra work handling the switch over"
A) To enter the console you have to press a key. Luckily if thats Escape, Tab or ` (¬) its DirectInput scan code is the same across keyboards (ever wonder why commercial games use those keys for console mode, now you know ).
In your keyboard checking code, look for the console key, when its pressed, display the console, then set the cooperative level of the keyboard to normal.
Any key pressed from now on will go to both WM_CHAR and DirectInput - because you''re in console, ignore the DirectInput code.
When you detect the console key again, set the keyboard cooperative level back to exclusive, close the console and return to the game. While DInput has exclusive keyboard, you won''t get any WM_CHAR messages (so don''t worry about still processing them while back in the game).


--
Simon O''''Connor
Creative Asylum Ltd
www.creative-asylum.com

Share this post


Link to post
Share on other sites
S1CA, that is a very nice answer to a problem I have been anticipating for a while and had confirmed when I sent my program to a friend in England and he could not type certain things correctly. I''m going to put that to good use in my game wrapper for text-entry. Thanks again.

Share this post


Link to post
Share on other sites