DirectInput.. GetDeviceState not working properly??

Started by
6 comments, last by footlead 20 years, 6 months ago
Hi. I'm trying to get DirectInput8 (on SDK version 9) to work. The thing is, everything initializes okay, all the function calls don't return errors. Everything should be fine.. but for some reason, it's not recognizing anything from my keyboard. Here is some code that demonstrates this: This is how the input device is set:

	if (FAILED (dinput->CreateDevice(deviceGUID, &_dinputdevice, NULL)))
		return FALSE;
	if (FAILED (_dinputdevice->SetDataFormat(_dataformat)))
		return FALSE;
	if (FAILED (_dinputdevice->SetCooperativeLevel(hWnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE)))
		return FALSE;
	if (FAILED (_dinputdevice->Acquire()))
		return FALSE;
	return TRUE;
deviceGUID is passed as GUID_SysKeyboard, and _dataformat is of type LPCDIDATAFORMAT, and is set earlier to &c_dfDIKeyboard. No problems reported here, it returns just fine. This code is how the device is read:
   
	HRESULT hr;

	while (true)
	{
		if (FAILED (_dinputdevice->Poll()))
			return FALSE;
		hr = _dinputdevice->GetDeviceState(_buffersize, &_buffer);
		if (SUCCEEDED(hr))
		{
			return TRUE;
		}
		if ((hr == DIERR_INPUTLOST) || (hr==DIERR_NOTACQUIRED))
		{
			if (FAILED(_dinputdevice->Acquire()))
				return FALSE;
		}
		else
			return FALSE;
	}
_buffersize is set to 256 earlier, and _buffer is declared as: char _buffer[256]; Again, this function returns just fine (hr always succeeds). This is my simple function that checks if a key was pressed:
   
BOOL eKeyboard::GetKeyState(unsigned char key)
{
	return ((_buffer[key] & 0x80) ? TRUE : FALSE);
}
Of course, this is where the problem lies; the function always returns false. I did a check to see what the integer value of _buffer[key] is, and it's always zero. In the constructor of the class, I zeroed the memory of the buffer as so: ZeroMemory (&_buffer, 256); I think the problem is, the _buffer never gets updated correctly by GetDeviceState. I believe this is so because, originally, I did not have the ZeroMemory function. Without the ZeroMemory function, EVERY _buffer[whatever] value seemed to be non-zero and thus ALWAYS returned true (when checking the value, it was -51 or something). I'm not sure why this is not working. Could it *possibly* be that in my main loop, the windows messaging system "interferes" with the input? I have this called in my main loop: if(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) { if(!GetMessage(&msg, NULL, 0, 0 )) return msg.wParam; TranslateMessage(&msg); DispatchMessage(&msg); } Anyway, any help will be appreciated. Thanks! [edited by - footlead on October 6, 2003 7:18:23 AM] [edited by - footlead on October 6, 2003 7:19:15 AM]
Advertisement
Ok, one thing to note is that you say you declare your key buffer as "char _buffer[256];" but then your GetKeyState function takes an argument of "unsigned char key". Make sure that both these types match.

Another thing is that unless you''re using events for your keyboard (unlikely) you don''t need to call "Poll" on the keyboard device. The docs say that if the device doesn''t need polling, then the call doesn''t do anything but you never know.

The SDK comes with a DirectInput sample on how to setup the keyboard. You might want to look there and compare their code to yours. Handling keyboard and mouse input isn''t all that complicated so the SDK code will probably be pretty similar to yours. DirectInput starts to get a little more difficult when you deal with weird types of joysticks and action mapping, but for mouse and keyboard input, it''s pretty straight forward.

neneboricua
Use a buffer of ''unsigned char'' to reach 255. (Right?)

.lick
Yes. I think the SDK samples use something like "BYTE buffer[256];" In Windows, a BYTE is a "typedef" for an "unsigned char"

neneboricua
I tried setting my buffer to BYTE and to ''unsigned char''. Didn''t do anything. Also I tried taking out the Poll function.. also no effect.
Even if the functions don''t return an error, there could still be some kind of output in the debug spew. Is there anything there?

Also, did you check the SDK keyboard sample?

neneboricua
First, thanks for replying to my post.. I appreciate the help.
I took a look at the sample keyboard files, but I can't see anything about the Device programming that I'm doing wrong. But it seems they process messages differently, and I'm starting to think that *may* be the problem. This is the loop of my main program:
	while(1)	{		if(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))		{			if(!GetMessage(&msg, NULL, 0, 0 )) return msg.wParam;			TranslateMessage(&msg); 			DispatchMessage(&msg);		}		else		{			DoFrame();		}	}


On a hunch I used outputs to check just how often the DoFrame() function is called (where I do the keyboard reading function). It seems to be called only roughly half the time (it varies , it seems randomly). This is even when I'm not even pressing any keys, clicking any buttons, or doing anything at all. Is this normal? I'm not too well versed with exactly how Windows does its messages. Or is there a better way I should be handling this? I don't fully understand the DXSDK's keyboard sample's approach to the message handling.

Also, I'm not sure what is meant by output in the debug spew. Do you mean in Visual C++, or with DirectX SDK Debug version (because I'm not sure if I installed the debug version).


[edited by - footlead on October 6, 2003 8:07:55 PM]

[edited by - footlead on October 6, 2003 8:08:43 PM]
I think your message loop looks fine. I haven''t played with message loops in so long it''s hard to remember. I wrote it once a while ago and then haven''t messed with it since. If you''re using Visual Studio 6 or greater, you can use the DirectX App Wizard that is installed by the SDK. It can set up a basic DX app for you, including all the message loop issues. You can compare that code to yours and see where it''s different. Or you can just use the code generated by the App Wizard.

As far as the debug spew goes, I''m talking about the small window in Visual Studio that reports errors and such when your program is running. ALL DirectX development should be done using the debug runtime. When you installed the DirectX SDK it asks you if you would like to have the debug runtime installed. You should say "yes" to this because it will allow you to track down your bugs much more easily.

You can switch between debug and release versions of the runtime by going to Control Panel and then clicking on the DirectX icon. Go to the Direct3D tab. Make sure the Debug Output Level is all the way to the right. And make sure that you have a bullet beside "Use Debug Version of Direct3D".

neneboricua

This topic is closed to new replies.

Advertisement