Finding out which Key was pressed

Started by
3 comments, last by Delryn 19 years, 3 months ago
Hi! My class DXKeyboard has a method to check wether a key is pressed or not: bool KeyPressed(int key). Now you can use this method like this: if(instance.KeyPressed(DIK_A)) // do something. This works fine, but now im trying to find out which key was pressed after the last GetDeviceState()-Update. My idea: GetDeviceState() stores data in a bool array[256]. For example, if the key "A" is pressed, array[65] gets the value true, because A = 65. In addition to that, I know that the keyboard bus has a size of 8 Bit, this means only one key can be pressed at the same time. So I wrote this method:

char DXKeyboard::KeyPressed()
{
	for(int i=0; i<256; ++i)
	{
		if(m_Keystates)
		{
			ofstream key("key.txt", ios::app);
			key<<"m_Keystates["<<i<<"] = "<<(bool)m_Keystates<<", char: "<<static_cast<char>(i)<<endl;

			return(static_cast<char>(i)); // Convert i to the character...
		}
	}
	return(0);
}
In my opinion this method should work perfect, but when I type "abcd" the file output is
Quote: m_Keystates[30] = 128, char: m_Keystates[48] = 128, char: 0 m_Keystates[46] = 128, char: . m_Keystates[32] = 128, char:
Whats wrong?!
Advertisement
You might want to try (bool)m_Keystates&0x80 just to get the high bit which is why instead on 1 you're getting 128. Also you're setting your bool array based on the virtual key codes not ASCII which is what you're outputting. Yes in DirectX 46 is 'c' but in ascii it's '.', that's why you are seeing such strange output. Also if you're using DirectX 9 I believe there is a function to convert virtual key codes to ASCII codes try looking it up on MSDN or do a search on GDNet.
Quote:Original post by Delryn
GetDeviceState() stores data in a bool array[256]. For example, if the key "A" is pressed, array[65] gets the value true, because A = 65.


This is incorrect. GetDeviceState() stores data in a byte array[256]. If the high bit of the byte is set, then the key has been pressed. This is the code that I use:

/* PREPROCESSOR DEFINES */#define KEYDOWN(name, key) ( name[key] & 0x80 )/* INPUT FUNCTION */char keys[256];	 // Array to hold keystates in (bytes NOT booleans)// Get the raw data firstif( FAILED( keyboard->GetDeviceState( sizeof( keys ), (LPVOID)&keys ) ) ){   // The keyboard has been lost, reaquire it   HRESULT hr = keyboard->Acquire();   // Keep looping until it can be reaquired   while( hr == DIERR_INPUTLOST )         hr = keyboard->Acquire();		   // Try to get the data again   // If it fails again, the app is probably minimized, so just return   if( FAILED( keyboard->GetDeviceState( sizeof( keys ), (LPVOID)&keys ) ) )	return E_FAIL;}// Use the raw data to control the appif( KEYDOWN( keys, DIK_UP ) || KEYDOWN( keys, DIK_W ) ){   // Up or W has been pressed}


The important thing here that is different from your code is the KEYDOWN macro. Note that it just checks the high bit of the array at the specified index.
Dustin Franklin ( circlesoft :: KBase :: Mystic GD :: ApolloNL )
Another thing: if you want to use DInput for straight keyboard typing (as in entering text into a text box, ect...), it is recommended that you check the Win32 message WM_CHAR instead. This is because the Windows API automatically handles many text-related issues that DirectInput does not (timing the keypresses for key repeating, correct shift keys, and IME). Just do a search of GDNet or Google for WM_CHAR - you will get tons of hits.
Dustin Franklin ( circlesoft :: KBase :: Mystic GD :: ApolloNL )
I never had problems with the type bool? Everything always worked fine.
I think I found the function, it is called ToAscii, my problem is that I dont understand the needed parameters:

ToAscii()

int ToAscii(

UINT uVirtKey,
UINT uScanCode,
PBYTE lpKeyState,
LPWORD lpChar,
UINT uFlags
);

Quote:
uScanCode
[in] Specifies the hardware scan code of the key to be translated. The high-order bit of this value is set if the key is up (not pressed).


What is the hardware scan code?

Quote:
lpKeyState
[in] Pointer to a 256-byte array that contains the current keyboard state. Each element (byte) in the array contains the state of one key. If the high-order bit of a byte is set, the key is down (pressed).
The low bit, if set, indicates that the key is toggled on. In this function, only the toggle bit of the CAPS LOCK key is relevant. The toggle state of the NUM LOCK and SCROLL LOCK keys is ignored.
lpChar


This must be my m_Keystates[256], but which type is needed? I always used bool.


And I found this example, but as I said I got problems with the parameters:
http://www.gamedev.net/reference/articles/article842.asp

This topic is closed to new replies.

Advertisement