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

Problem using DirectInput for text input.

Started by tifkagh Dec 2, 2001 at 5:50 AM 6 replies 1.1k views
Original Post
tifkagh
tifkagh
I am trying to use Photon''s routine for converting scan codes gathered using DirectInput into ASCII character codes. My program is using the full screen in exclusive mode. Unfortunately whenever I press a key the routine seems to be crashing my program and sending me back to plain old Windows. The function is called as follows: for(int iCount = 0; iCount < (INT)dwItems; iCount++) { //Convert the scan code to its ASCII equivalent. scan2ascii(dodKey[iCount].dwOfs, lpdwAsciiResult); pszText[iNextChar] = (char)lpdwAsciiResult; NextChar++; } And the actual code is: int scan2ascii(DWORD scancode, LPWORD result) { //Establish the keyboard layout for this thread. static HKL layout=GetKeyboardLayout(0); //Get the state of each virtual key and put it into the buffer static BYTE State[256]; if (GetKeyboardState(State)==FALSE) return 0; //Convert the scancode into a virtual keycode. UINT vk=MapVirtualKeyEx(scancode,1,layout); //Convert the virtual key to ASCII based on the state of //the keyboard. God knows why the scancode has to be supplied //again. return ToAsciiEx(vk,scancode,State,result,0,layout); } My guess is that the scan2ascii functionis somehow interfering with DirectDraw''s exclusive mode.
Oluseyi
Oluseyi
Perhaps it''d be simpler to just unacquire the keyboard when performing text input? The function looks hokey to me, but that may just be my layout preferences.

When do you call this function (in user terms as well as in application terms), and why? In any case, single step through your code! Use the debugger; it you''re using MSVC you set a breakpoint with F9, start the debugger with F5, step over a statement with F10, into one with F11, out with Shift+F11 and run to cursor with Ctrl+F10. That way you can monitor the state of your variables and see exactly where the function chokes.
superpig
superpig
quote:
Original post by Oluseyi
In any case, single step through your code! Use the debugger; it you''re using MSVC you set a breakpoint with F9, start the debugger with F5, step over a statement with F10, into one with F11, out with Shift+F11 and run to cursor with Ctrl+F10. That way you can monitor the state of your variables and see exactly where the function chokes.


How exactly would you do this in DDraw fullscreen exclusive mode? Or are you one of those lucky people with dual monitors?


Superpig
- saving pigs from untimely fates
- sleeps in a ham-mock at www.thebinaryrefinery.cjb.net
Richard "Superpig" Fine - saving pigs from untimely fates - Microsoft DirectX MVP 2006/2007/2008/2009
"Shaders are not meant to do everything. Of course you can try to use it for everything, but it's like playing football using cabbage." - MickeyMouse
RomanR
RomanR
How about debug prints?
Romanroman_rodov@hotmail.com
Oluseyi
Oluseyi
quote:
Original post by superpig
How exactly would you do this in DDraw fullscreen exclusive mode?

Don''t go fullscreen exclusive while debugging (not that it''s exactly possible anyway). If you know the problem only occurs when you are fullscreen and exclusive, then log your debug output.
Roof Top Pew Wee
Roof Top Pew Wee
You could just throw together your own function for converting the keys. If you look in...... . oh, not sure which header it is, but one of them has all the defines. Anyway, the DIK_ defines which is what you get from direct input start at 0 and go in order, so what you can do is create an array of char''s that is big enough to hold all of the different keys. Then you can use the constants to get the key held. Quick example:

arrayOfChar[ DIK_A ] = ''a'';
arrayOfChar[ DIK_B ] = ''b'';

And so on. You''d only have to do this once. Then you just use the constant DIK in your array and whammo, you''ve got your character out. Really fast too.

--Vic--
KalvinB
KalvinB
I just use a 256 byte array to store the conversions. Based on which of the 256 possible DInput keys are pressed (see dinput.h) it just a quick lookup conversion.

  
BTYE dkey[256];
unsigned char ascii;
//read in key presses to dkey


for(j=0;j<256;j++)
if(dkey[j]& 0x80)
{
acsii=asciitable[j];
//store ascii someplace

}
[source]


Ben


S1CA
S1CA
DO NOT use DirectInput to get text input. Don''t use WM_KEYUP or WM_KEYDOWN messages either!!

DirectInput treats a keyboard like a big joypad with ~102 buttons on it. The virtual key codes from the WM_KEY* messages just tell you the state of a single key.

The reasons ?:
1. Certain european languages have accented characters (e.g. öõòóô) for which there aren''t enough keys on a keyboard to represent each with its own key. On those keyboards, they have a key which represents the type of accent without the letter, you press this key first, THEN the letter.
So for example to get an accented character on a Danish keyboard you press 2 keys, one after the other - NOT together!

2. The codes in DirectInput and the virtual key codes map to the US keyboard layout - on a German keyboard for example what ASCII code would you display for DIK_Y ? if you say "Y", you''d be wrong!! - a German Keyboard has a layout of QWERTZ rather than QWERTY. Pressing Z gives a DIK_Y... The French keyboard is even more scary!. This is because DInput is just saying "this button was pressed" - it doesn''t care what the sticker on the keyboard might say something different.

3. On top of that, the user may have chosen to use a different keymap with their keyboard. For example I once did some work in Denmark - although the machines I was using had Danish keyboards, I loaded a UK keymap because that''s what I''m used to. DInput and the VK_ codes ignores any soft keymappings loaded.

4. In languages with many more characters than a keyboard supports such as Japanese, Chinese, Korean etc, Windows comes with an IME ("Input Method Editor") where characters can be entered in a few ways - one is spelling the word phonetically where a single character might be the result of say 4 keypresses. Another way of using the IME is to select characters from an on-screen menu. DInput and VK_ codes once again go in below all this.

5. Likewise there are some alternative keyboard types for disabled people with software key translation. Also emerging speech-to-text input etc etc etc...


So what''s the solution to perfect text input on ANY keyboard type in any territory etc ? quite simple really - when you need text input, release any exclusive mode you have over the keyboard, put a TranslateMessage() in your message pump and properly translated ASCII (or UNICODE) characters will be sent to you with a WM_CHAR message. When you need to go back to game style input, re-acquire the keyboard and use DInput again.

--
Simon O''''Connor
Creative Asylum Ltd
www.creative-asylum.com
Simon O'Connor | Technical Director (Newcastle) Lockwood Publishing | LinkedIn | Personal site

Topic Locked

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

Sign in to reply to this topic.