Keyboard behavior kinda - wrong.... (data queues)

I was taking a look at the StandardKeyboard and DirectInputKeyboard classes and noticed that there is an issue that has been overlooked in the APIs design. The keyboard classes poll the keyboard using:

public boolean poll()

This retrieves the CURRENT state of a device at the time its polled. This means that events can actually be missed which is wrong. isKeyPressed is fine because it will return whether or not a key is currently pressed, but there needs to be another method for getting the latest key value from an input queue.

I’ve coded the current OSX keyboard implementation so that it can do both, but until I have a method in the API that will allow you to get queued input I have no way of exposing that functionality.

Hi
This issue applies to mice buttons and joystick buttons too if your not carefull. The best thing to do in the native side seems to be to always set the button to being on if you have received an button on event since the last poll, this does mean in theory though it is possible to hit a key fast enough that it looks like you are holding it down, but not doing this means that unless you happen to be holding it down when the device is polled (and that is up to the application not the library) then you won’t get any indication that it ever has been pressed

Cheers

Endolf

The input library for DirectX (particularly for mice) is internally queued in dinput.dll - and may be for joysticks as well. I have two options that I can perform in HID:

  1. I can return the next element on the input queue (stream of input events)
  2. I can return the current state of an element

I cannot do 1 with the current API implementation. All input in the entire system should be queued or else the system will simply drop events as the frame rate or other falls behind. Doing non-queue’d input is going to be a problem.

Im not sure I see the problem here.
Polling the input each time around the loop is pretty typical of console programming. In general, your eyes have a much faster response time then your physical reflexes and a frame rate which is eye acceptable should be more then acceptable for controllers.

(The one exception i know of, which the Win32 input plugin handles internally, is the mouse because the mouse isn’t really a hardware device at all but a software construction that is polling the hardware at its own OS determined rate.)

Do you have an example program that illustrates where this isn’t true?

or to put it more simply… missing a key held down for a 25th or less of a second is not a terribly likely occurrence.

if you were to queue these you would ALSO have to queue the amount of time for which they were held in order for it to havbe any real meaning. If I hit a key 75 times in a second it shouldnt be any different then holding that key down once for the entire section, but if you look at it as events, there are 75 times as many “events” resulting in 75 times the resulting action.

Icky no bad.

It is far simpler just to view the world in frame-rate increments and as long as your simulation keeps up its frame rate to a decent speed (10fps or more) its should be fast enough for the typical human.

Jk

Hi
It’s late so you will have to excuse me if this makes no sence :), if my app runs at 10fps, then all I have to do is hold a key down for less than 1/10th of a second and it will be completely ignored. I’ve just done a quick test with ReadTest and I can press the mouse buttons or the keyboard fast enough that it doesn’t show up, and that is with a 50ms poll or 20 fps, at 10 it would be twice as easy to do. I don’t know how directx or mac work, but under linux events get thrown and queued (at the kernel level), my stuff comes along and reads this queue, and then with keyboard it says, if a key was has a key pressed event with it at all since the last poll, report it, so you will never miss a key press. I think greg (is greg ok?) is saying is that under mac there are events but he can’t get to them and has to ask what the current device state is, which from the evidence is how the directx one works and can miss key presses.

Hope that made some sence

Cheers

Endolf

Not quite.

You have to hit the key in the EXACT 10th of a second between reads.

Really its more like a 20thof a second on the average that yould have to be holding it to miss it and then you’;ld miss every other oen over time, i believe.

Is missing a 5th of a second of key control really significant?

(Also I HOPE you are getting better then 10fps. That sucks. 15 is more like a minimum acceptable speed which means a 30th of a second key press.)

Unfrotunately you really don’t want queuing, what it soudsn like youa re asking for is a “lock” where, if the key was pressed at all in that window you want to treat it as if it remains pressed until the next poll request.

Im not sure if DX would support such a thing or if other OSs do…

Hi
Trust me, i’ve done it on readtest, it is possible to do, without too much effort, and thats on 1/10th of a second, true that most apps should be polling faster than this, but the fact that it can be done suggests it problably will somewhere down the line. Currently if they key happened to be down when it polled then it is as though it was is held down untill the next poll, I don’t see whats wrong with saying that if they key was pressed in this frame it’s down untill the next frame at least?, I’m just confused as to why this would be wrong behavior?

Cheers

Endolf

An example of where that breaks down? I’m playing a shooter and enter an area where there are suddenly lots of enemies or the VM starts doing a full gc which causes the framerate to drop off. I pressed the fire button eight times and I know I pressed it 8 times and in my mind I know I pressed it eight times for the pattern of 8 enemies coming down screen however only 7 shots are fired (or even once it drops the one press of the fire button I did press that would have fired my smartbomb). That’s a pretty significant miss, and for certain genres of games - that type of miss is just not acceptable.

This is a ‘been there, done that’ type of thing. Its why there are input queues in the LWJGL input libraries, its why we queued up events for the Intel Open Arcade input devices (man that was a failed project), and its why at least the Dreamcast, Playstation, and SNES buffer input events. We need to allow people to read input events off the stream. There is no reason to knowingly let events get lost IMO.

I agree. Better safe than sorry.

Okay although it still seems counter-intutitive to me, you gusy have convinced me.

Now for the real question, is there a good way to do this queuing in DX? I know queuing can be enabled for mcie (it currently is) is that all that has to happen for jkeybaord is se tthe right DX flags? And if so, does someone want to volunteer to do it?

I will investigate the possibilities on Friday, but I can’t do all the code work. I will post the DirectX 9 flags and methods so someone else can hop into that codebase and handle things.