[SOLVED] key input seems "buffered"

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
Andreas
Posts: 166
Joined: Sun Oct 31, 2004 7:15 am
Location: Münster / Germany
Contact:

[SOLVED] key input seems "buffered"

Post by Andreas »

Hi everybody,

i am having a little problem with the key input on linux 2.6 and Irrlicht 0.9:
I'd like to receive Events if a key is pressed down for the first time, and then again when it is finally released. But the engine seems to be "firing" key events continuously (like when entering a character in a ComboBox and holding the key pressed down and the box fills with that character). So using:

Code: Select all

keyBuff[event.KeyInput.Key] = event.KeyInput.PressedDown
doesn't work... :(

any help would be welcome! :)
Andreas


P.S.: Just for my defence: I read the following but that didn't solve my problem:
http://irrlicht.sourceforge.net/phpBB2/ ... .php?t=808
http://www.irrforge.org/index.php/Keyboard_Input
http://irrlicht.sourceforge.net/phpBB2/ ... ered#40294
I also tryed to search the API for something like eventReceiver->setNonBuffered() but with no luck...
Last edited by Andreas on Sat May 28, 2005 8:22 am, edited 1 time in total.
Guest

Post by Guest »

Buffered is not the right term: the keys are repeating. You'll realise that when you notice that it only starts doing that after a second or so.

What you get is pairs of releases and presses.

You should be able to use that information.

Do something like:

bool keypressed[MAXKEYS];

in event receiver:
1. if key pressed, set the keypressed flag for the key

in main loop, for every key you want to check:
1. check if the keypressed flag is on. If so, the key was pressed
2. clear the keypressed flag.

That should guarantee that when the event receiver is run the next time (during device->run()), the keypressed flag is cleared.

You could use ints to count keypresses, but processing the keystate in the mainloop does not take the order of the keypresses into account.
Andreas
Posts: 166
Joined: Sun Oct 31, 2004 7:15 am
Location: Münster / Germany
Contact:

Post by Andreas »

Thank you for your fast reply :)

But i see one more problem: since i don't know when a key is repeating or when its pressed several times, i can't use an int that counts when to clear the keypressed variable.

What i mean is: when i clear the keypressed variable after 1 keypress, i don't need it at all (thats what i am doing now), but when i clear it after the key is pressed 20 times, the modell will move on and on if the user presses the key once. But the modell should stop moving when the key is released.

So is there a way to get to know if a key is pressed several times or if it is repeating?
Guest

Post by Guest »

I wouldn't worry about that if I were you. How long does it take to go through your whole mainloop?
Let's assume you get 10 frames per second. Key repeats are probably less frequent than that. And the chance that the user happens to press the same key twice in that time is pretty slim.

If you really want to handle every keypress but no repeats, you'll have to compare the time of the release with the time of the press. My guess is that they're the same with a repeat. If they're not, they'll be ridiculously close to each other. It's probably safe to assume they'll truly arrive in pairs (no other events in between), so you could store the last event time as well as the last keycode, and if that keycode is the same as the new keycode, you may be getting a repeat. And that's where the time comparison comes in.
jox
Bug Slayer
Posts: 726
Joined: Thu Apr 22, 2004 6:55 pm
Location: Germany

Post by jox »

Why would you clear the keypressed flag yourself?

keyBuff[event.KeyInput.Key] = event.KeyInput.PressedDown

will do that when the key is released.

And how do you know when a key is repeating or when its pressed several times? When it's repeating there will be no keyup events (PressedDown == false).

But I must admit I really don't understand what you're trying to achieve. Do you simply want to have your model start moving on keydown and have it stopped on keyup?
It is like it is. And because it is like it is, things are like they are.
Andreas
Posts: 166
Joined: Sun Oct 31, 2004 7:15 am
Location: Münster / Germany
Contact:

Post by Andreas »

First of all, thanks for your replies!

My problem is that i am sending "movement-packets" for network play according to key press events. The more packets i send the more time it costs to react on those packets. Let me give an example:

Code: Select all

if (event.KeyInput.PressedDown)
					nethandler->sendMovement(players[playerID].getPosition(), players[playerID].getRotation(), ID_FORWARD);
				else
					nethandler->sendMovement(players[playerID].getPosition(), players[playerID].getRotation(), ID_FORWARD_STOP);
As it is implemented now, network play even lags with two players in LAN :(
I' m sorry not to mention that earlier, this is no question about smooth character movement, but about reducing network traffic. If anyone has a better idea about how to handle position updates in network play, i would be glad to hear about it! :)

@jox:
When it's repeating there will be no keyup events (PressedDown == false)
I'm sorry, but i think that's not true. That is exactly my problem: there are tons of keydown <-> keyup event pairs when a key is repeating... :(
jox
Bug Slayer
Posts: 726
Joined: Thu Apr 22, 2004 6:55 pm
Location: Germany

Post by jox »

Andreas wrote:I'm sorry, but i think that's not true. That is exactly my problem: there are tons of keydown <-> keyup event pairs when a key is repeating... :(
Oh really? But this is a Linux issue then. Because on windows there is only key up events when the key actually is left up (just tested it to make sure).
It is like it is. And because it is like it is, things are like they are.
Andreas
Posts: 166
Joined: Sun Oct 31, 2004 7:15 am
Location: Münster / Germany
Contact:

Post by Andreas »

Damn it, so i have to switch back to windows i guess :wink:

Anyway, thanks for all replies :)
Andreas
Posts: 166
Joined: Sun Oct 31, 2004 7:15 am
Location: Münster / Germany
Contact:

Post by Andreas »

I got it working now, with a little addition to Keless' key input howto:

Code: Select all

bool curKeys[KEY_KEY_CODES_COUNT]; 
bool lastKeys[KEY_KEY_CODES_COUNT]; 
bool switchUp;

if (curKeys[KEY_UP] && !lastKeys[KEY_UP] && !switchUp) {
   nethandler->sendMoveForward(...);			
	switchUp = true;
}
else if (!curKeys[KEY_UP] && lastKeys[KEY_UP] && switchUp) {
	nethandler->sendMoveForwardStop(...);	
	switchUp = false;
}
sends a packet if the key is pressed the first time and again when the key is finally released...
Post Reply