Direct input keyboard

Started by
5 comments, last by qxtianlong 17 years, 7 months ago
I recently resurrected some oldish direct input code to manage keyboard input and inexplicably its stopped working. I've gone through the code samples that come with the SDK again and checked my own code and everything seems to be correct as far as I can see so I was hopeing maybe someone could shed some light on this. First the code:

	void	KeyboardManager::PollKeyboard()
	{
		int count = 0;
		HRESULT hr = m_pInputDevice->Acquire();
		while(hr == DIERR_INPUTLOST)
		{
			HRESULT hr = m_pInputDevice->Acquire();
			count++;

			if(count >= 100)
			{
				Log::Write("KeyboardManager::PollKeyboard - Input device lost");
				return;
			}
		}

		m_flip = !m_flip;
		if(m_flip)
		{
			m_pCurrentKeys = &m_keys[256];
			m_pOldKeys = m_keys;
		}
		else
		{
			m_pCurrentKeys = m_keys;
			m_pOldKeys = &m_keys[256];
		}

		hr = m_pInputDevice->GetDeviceState(256, (void*)m_pCurrentKeys);
		if(!Log::TestAndLog("IDirectInput8A::GetDeviceState Keyboard", hr))	{ return; }

		// TEST
		bool keyStates[3];
		if(GetAsyncKeyState('A') & 0x8000)
		{
			keyStates[0] = KeyPressed('A');
			keyStates[1] = KeyHeld('A');
			keyStates[2] = KeyReleased('A');
		}
	}


	inline bool	KeyboardManager::KeyPressed(u8 key) const
	{
		return ((m_pCurrentKeys[key] & 0x80) && !(m_pOldKeys[key] & 0x80)) ? true : false;
	}
It should all be pretty self explanitory, there's nothing complicated going on here. As you can see I've put in a GetAsyncKeyState for testing purposes which I put a break point after so that the code stops when the 'A' key is pressed. Now the problem is that at the break point 'm_pCurrentKeys' which points to the key buffer shows element 30 to be set. However when I get inside the 'KeyPressed()' function the input u8 'key' is 65 and hence the wrong element is being tested. By the way 'u8' is just a typedef'd unsigned char. I check all my DirectX calls with the logger and everything has returned D3D_OK or S_OK so no worries there, just this mis-match. I'm positive this code used to work and I really cant explain whats going on here (although I am pretty tired so maybe its just something really stupid). Anyone got any ideas?
[size="1"] [size="4"]:: SHMUP-DEV ::
Advertisement
Hmmm. That's weird. That should work. The only differences I noticed between mine and yours was:
I used:
//...
HRESULT hr = m_pInputDevice->Acquire();
while(hr !=DI_OK)
{
Sleep(500); //waiting for input focus
HRESULT hr = m_pInputDevice->Acquire();
//...
//assuming BYTE m_pCurrentKeys[256];
hr = m_pInputDevice->GetDeviceState(sizeof(m_pCurrentKeys), m_pCurrentKeys);
....
Btw - Is 0x80 the same as 0x8000?

I don't know, it seems like it should work.
I think the problem is that you're testing a character's index (A is equal to 65) whereas DirectInput uses DIK values (which don't map to characters.) Try using DIK_A instead.

This is exactly why I recommend Windows input now, since you can do exactly the same thing, but easier.

For example:
bool KeyStates[256];// In WindowProc()case WM_KEYDOWN:    {        KeyStates[(int)wParam] = true;        break;    }case WM_KEYUP:    {        KeyStates[(int)wParam] = false;        break;    }


If you need code for setting up a RAWINPUT mouse device, I can post an example.

HTH!
Thanks for the input, that was indeed the problem. Seems a bit silly to me that direct input uses a different mapping for the keys but they probably have their reasons. Many thanks.
[size="1"] [size="4"]:: SHMUP-DEV ::
Quote:
m_pCurrentKeys = &m_keys[256];
m_pOldKeys = m_keys;

why did not you write this,such as .............

m_pCurrentKeys = &m_keys[256];
m_pOldKeys = &m_keys[0];

you use two type in your code....


Quote:Original post by qxtianlong
Quote:
m_pCurrentKeys = &m_keys[256];
m_pOldKeys = m_keys;

why did not you write this,such as .............

m_pCurrentKeys = &m_keys[256];
m_pOldKeys = &m_keys[0];

you use two type in your code....


Hopefully this will explain:

Quote:Taken from http://pw1.netcom.com/~tjensen/ptr/ch2x.htm

In C, the standard states that wherever we might use &var_name[0] we can replace that with var_name, thus in our code where we wrote:

ptr = &my_array[0];

we can write:

ptr = my_array;

to achieve the same result.

This leads many texts to state that the name of an array is a pointer. I prefer to mentally think "the name of the array is the address of first element in the array". Many beginners (including myself when I was learning) have a tendency to become confused by thinking of it as a pointer. For example, while we can write

ptr = my_array;

we cannot write

my_array = ptr;

The reason is that while ptr is a variable, my_array is a constant. That is, the location at which the first element of my_array will be stored cannot be changed once my_array[] has been declared.


In the above context both methods are equivalent and there's no particular reason to choose one over the other except that I'm lazy and prefer the shorter version so I dont have to type as much ;p.
[size="1"] [size="4"]:: SHMUP-DEV ::
Quote:
In the above context both methods are equivalent and there's no particular reason to choose one over the other except that I'm lazy and prefer the shorter version so I dont have to type as much ;p.


I know this,but,the first time,you wrote this style,
for example:
m_pCurrentKeys = &m_keys[256];
the second time,you wrote this style,
for example:
m_pOldKeys = m_keys;
If I can write in the same style,m_pOldKeys = &m_keys[0];

I know m_pOldKeys = m_keys and m_pOldKeys = &m_keys[0] is the same result,

if you wrote like this,it's look good....

I'm no other meaning.:p

-------------------------------------------------------------------------
I think you can try ....
for example:

HRESULT hr;

BYTE Buffer[256];
ZeroMemory( Buffer, sizeof(Buffer) );

hr = lpdiKeyboard->GetDeviceState( sizeof(Buffer), Buffer );
if( FAILED( hr ) )
{
hr = lpdiKeyboard->Acquire();
while( hr == DIERR_INPUTLOST )
hr = lpdiKeyboard->Acquire();
return hr;
}

This topic is closed to new replies.

Advertisement