Jump to content
  • Advertisement
Sign in to follow this  
Delryn

Finding out which Key was pressed

This topic is 5030 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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?!

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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 first
if( 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 app
if( 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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!