Characters in Direct Input

Started by
6 comments, last by bjogio 18 years, 10 months ago
Is there a function out there that takes a direct input keycode (like DIK_SPACE or DIK_A) and translates it to an actual character value? I looked into the header file and found that all the DIK codes increment like rows on the keyboard, instead of in alphabetical order, which makes converting codes to input a pain in the neck. I read the article here on using windows API functions, but its not well explained how it ties into direct X... does anyone know a simple way to do this conversion?
KA-BOOM!
Advertisement
char nxt::DirectInput::ScanToChar(DWORD scanCode) const{	//obtain keyboard information	static HKL layout = GetKeyboardLayout(0);	static UCHAR keyboardState[256];	if (GetKeyboardState(keyboardState) == false)		return 0;	//translate keyboard press scan code identifier to a char	UINT vk = MapVirtualKeyEx(scanCode, 1, layout);	USHORT asciiValue;	ToAscii(vk, scanCode, keyboardState, &asciiValue, 0);	return static_cast<char>(asciiValue);}


This is what I use. I worked it out from some tutorial somewhere.
yeah that came from this site. I just dont understand what goes into the function. I presume what comes out is the converted char, but i dont get what goes in. What is scancode? Is that the state of a single key that you are querying?

I already have the keyboard state returned by direct input. This function uses windows API to get the state again. Is there any way I can use these functions with the state thats already returned by direct input?
KA-BOOM!
Quote:Original post by Mafian
yeah that came from this site. I just dont understand what goes into the function. I presume what comes out is the converted char, but i dont get what goes in. What is scancode? Is that the state of a single key that you are querying?

I already have the keyboard state returned by direct input. This function uses windows API to get the state again. Is there any way I can use these functions with the state thats already returned by direct input?


The scancode is the DIK_whatever stuff. So you'd pass in DIK_A or DIK_SPACE or whatever you need.

EDIT: I don't understand too fully the inner workings of this function (check the documentation for each function if you want) but the GetKeyboardState() is necessary for the ToAscii() function. As far as I know, it doesn't check to see what keys are being pressed. You do that yourself by checking for whatever key via the function parameter.
Ok... I have tried this code here:

		unsigned int vk = MapVirtualKeyEx(k, 1, m_KBLayout);		unsigned short asciiValue;		ToAscii(vk, k, buff, &asciiValue, 0);		char c = static_cast<char>(asciiValue);


m_KBLavout contains contents retrieved by GetKeyboardLayout(0) and buff is a pointer to an array of unsigned chars returned by direct X's keyboard state function (not windows.h's version GetKeyboardState).

Everything seems to work fine, except holding the shift key has no effect on characters and for some reason, when I push 'q' it is always upper case and when I push 'w' nothing appears. Every other non-shift character is fine. For the record, even when I replace buff with the GetKeyboardState() from windows.h, it still doesnt work.
KA-BOOM!
wow... nevermind. Apparently it does make a difference if you uses Direct X's state as opposed to windows.h's GetKeyboardState.

If you ask me tho... I think its lame to query the keyboard twice every time... once for direct x and then again using GetKeyboardState. There must be a better way...
KA-BOOM!
Quote:Original post by Mafian
I think its lame to query the keyboard twice every time... once for direct x and then again using GetKeyboardState. There must be a better way...


This is from some doom-port if i recall correctly.
Basically you create this lookup-table

char convert_lookup[256][8];

which is size of 256 keys and all combinations of modifier-keys, control, shift and alt

you build the lookup table with this one:

char vk2scan[256];	for(int i=0;i<256;i++)	vk2scan[MapVirtualKey(i,1)] = i;vk2scan[0]=0;for(i=0;i<256;i++){	int c = VkKeyScan((TCHAR)i);	convert_lookup[vk2scan[c & 0xff]][(c >> 8) & 7] =  i;}


Now when you see new key-press in polling input from DX, you take all the modifiers and build a mask out of it and index into the convert_lookup with the DIK_* code and mod-mask.
If this gives you ascii-value, grab that. Else return the key-code (there's no equivalent ascii-char for that then).

ch.
It makes difference. DirectInput DIK_* constant are the scan codes of an american-layout keyboard (directinput engineer was a little lazy). If you have this layout no problems at all but if you come from another country you have to:
//if you are italian
SetKeyboardLayout(theamericanlayout);
scan codes are a way to point a button in the keyboard, they go from 0 to 255 (usually). Not all the keyboard in the world are standard american keyboard so not all the button are placed in the same order. In order to evade problems and to support different country Ms include in win the concept of virtual keys. A virtual key is a mapping of a particular scan code that depends on the actual Layout (ex in Italy we have \ instead of ~). DirectInput works at a very deep level and it present you the raw scancode without the virtual key translation.
[ILTUOMONDOFUTURO]

This topic is closed to new replies.

Advertisement