DirectInput is too fast

Started by
9 comments, last by smokes 21 years, 6 months ago
I''m currently coding a nice little console. I''m polling a DirectInput keyboard device for input. My problem is that the console receives the character several times because I am only checking if the key is pressed.. and when it is pressed for multiple frames (hard to avoid unless you could tap it 60 times a second :-) I get the same character sprayed all over the screen.. Could I solve this problem by just polling the input say to or three times a second.. or should I somehow implement a KeyReleased() function.. I guess the last option is the only way to go.. I would like to get some ideas of how to build the state machine required for this from some of you who already done it.. and I don''t want to "just use the windows messages" else I would not have written a DirectInput wrapper :-)
Advertisement
In my wrapper for DI, I have access for both "pressed" and "down", since they have different uses. The pressed is handy for typing in text or anything where you only want it to happen once per "press", but the down is often crucial for controls (moving, maybe firing, etc...).

There are a number of sample DI wrappers out there that are fine starting places if you''re wondering how best to implement it.

Onnel
i use a debouncer:


void Get_Input()
{
static int debounce = 0;

if(key_buffer[DIK_ANYKEY] && debounce > some_number)
{
//get input
debounce = 0;
}
}
Onnel:
what is the difference between pressed and down?!?

sleekgeekfreak:
You couldn''t explain to me what a debouncer is? and how it works?
quote:Original post by smokes
Onnel:
what is the difference between pressed and down?!?

sleekgeekfreak:
You couldn''t explain to me what a debouncer is? and how it works?


Pressed is when you hit the key then release it (as though you are typing text). Down is simply held down at the instant you poll it.

Mike

[Piebert Entertainment] [Ask The All-Knowing Oracle A Question]------------------------------------------------------------GDSFUBY GameDev Society For UnBanning YodaTheCodaIf you want to see yoda unbanned then put this in your sig ------------------------------------------------------------DAIAGA Dave Astle is a God Association. To join, put this in your sig!Founder and High Priest of DAIAGA[edited by - YodaTheCoda on December 10, 2003 1:57:54 PM]
I solved it this way.. the function only returns true when a key has been released. As far as I can see the debouncer is just a way of checking the input every N'th frame.. I don't think that is a good approach because input would feel slow and unstable.. tried it first :-)



    WORD OldKey=0;bool IsKeyReleased(WORD Key){	if( !(Keystate[key] & 0x80) && (key == OldKey) )	{		OldKey = 0;		return true;	}	if( Keystate[key] & 0x80 )		OldKey = key; 	return false;}    


Keystate is the buffer returned by GetDeviceState() which is called every frame.. hmm seems I shouldn't have started this tread at all.. no real problem.. sorry but I am a bit tired and first thought of it as a problem :-)

[edited by - Smokes on October 16, 2002 9:33:44 AM]
Another method could be to record the current game frame for a particular key when it is pressed, then only add the letter to your console if the current game frame == frame that key was pressed. So if the user presses 'A' and the current frame is 1782, you just check to see if it is still frame 1782 (or 1783, depending on how you code your engine) before you process whatever it is that the 'A' key does.

I have been using this logic lately with various things, but for a while I was using the same methods as onnel and sleekgeekfreak. In my logic, a key that is 'pressed' is one that is being physically held down by someone's finger on a physical keyboard. A key that is 'down' is one that is both being pressed by the player and 'ready' to have input processed. So if I only want a key to do something once per press (as opposed to every frame that the key is 'pressed'), I make sure that the key is 'ready' and 'pressed'.

Psuedocode Example:


    OnKeyPress(Key KeyThatHasBeenPressed){	if( KeyThatHasBeenPressed is 'ready' )	{		KeyThatHasBeenPressed is 'down'		KeyThatHasBeenPressed is no longer 'ready'	}	else		KeyThatHasBeenPressed is not 'down'	if(KeyThatHasBeenPressed is 'down')		ProcessLogicForKeyPress();}    


Hope that helps!

-Mike

[edited by - doctorsixstring on October 16, 2002 9:37:29 AM]
Doctorsixstring:
Not to offend you but that approach seems like overkill compared to mine.. I mean all the logic is in the function I wrote.. much simpler.. but then again.. I can only get on keypress at a time using this method.. but this is okay for a console.. but perhaps it will bother me later *lol*
No offense taken! Actually, I stand by my code . With the (very basic) logic that I gave, you don't ever have to bother calling a function when a key is released and you can have as many keys being pressed at the same time as your computer/OS allows (due to the fact that I keep track of every key individually in an array of keys). Basically, if a key is being pressed and it wasn't pressed previously (i.e. it is 'ready') then the code can go ahead and process whatever it is you want the key to do.

Also, if you only test for input when a key is released, your input will probably feel somewhat odd. Just try typing in a text editor or here on gamedev: letters are placed in the edit box as soon as you tap the key - they don't wait until you release the key.

And just to avoid confusion, the method I mentioned in my first paragraph is not related in any way to the logic I described in my second paragraph.

-Mike

[edited by - doctorsixstring on October 16, 2002 9:47:42 AM]
you are right.. It would feel kindda stupid :-).. didn''t thought about that.. Now I''ve implemented something similar. thank you :-)

This topic is closed to new replies.

Advertisement