![]() |
|
Delayed key response in Allegro 5.0.10 |
ph03nix
Member #15,028
April 2013
![]() |
I noticed a very slight keyboard delay with Allegro 5.0.10 when switching from Windows key functions to allegro key functions. I decided to test both key events and key state from al_get_keyboard_event with this little program: 1#include <Windows.h>
2#include <iostream>
3#include <allegro5\allegro.h>
4
5int main(){
6
7 //init allegro
8 al_init();
9 al_install_keyboard();
10 ALLEGRO_EVENT_QUEUE *event_queue = al_create_event_queue();
11 ALLEGRO_EVENT_QUEUE *key_queue = al_create_event_queue();
12 ALLEGRO_KEYBOARD_STATE keyState;
13 ALLEGRO_EVENT ev;
14 ALLEGRO_TIMER *timer = al_create_timer(1.0 / 60.0);
15 ALLEGRO_DISPLAY *display = al_create_display(100,100);
16
17 //register events
18 al_register_event_source(key_queue, al_get_display_event_source(display));
19 al_register_event_source(event_queue, al_get_display_event_source(display));
20 al_register_event_source(key_queue, al_get_keyboard_event_source());
21 al_register_event_source(event_queue, al_get_timer_event_source(timer));
22
23 al_start_timer(timer);
24
25 bool allegroKey = false;
26
27 for(;;){
28
29 //get allegro key events
30 do{
31 al_get_next_event(key_queue, &ev);
32 switch(ev.type){
33 case ALLEGRO_EVENT_KEY_DOWN:
34 if(ev.keyboard.keycode == ALLEGRO_KEY_A) allegroKey = true;
35 break;
36 case ALLEGRO_EVENT_KEY_UP:
37 if(ev.keyboard.keycode == ALLEGRO_KEY_A) allegroKey = false;
38 break;
39 }
40 }while(!al_is_event_queue_empty(key_queue));
41
42 //get windows and allegro keys
43 al_get_keyboard_state(&keyState);
44 bool winKey = GetKeyState(0x41)>>15;
45
46 //compare to see if windows registered key but allegro did not
47 if(winKey && !al_key_down(&keyState, ALLEGRO_KEY_A)) std::cout << "keyboard state discrepancy" << std::endl;
48 if(winKey && !allegroKey) std::cout << "keyboard event discrepancy" << std::endl;
49
50 //wait to update display
51 do{
52 al_wait_for_event(event_queue, &ev);
53 switch(ev.type){
54 case ALLEGRO_EVENT_DISPLAY_CLOSE:
55 return 0;
56 }
57 }while(!al_is_event_queue_empty(event_queue));
58 }
59}
I noticed that the two different types of key press discrepancy always occur together. The delay seems to only last one iteration of the loop, so for one iteration windows detects the key is down but allegro does not. Anyway try this program (obviously Windows only) and see if it prints "discrepancy". In theory it never should, but it does for me. It's very random, sometimes I have to press "a" 50 times to see a discrepancy, and sometimes it happens many times in a row. GetKeyState(0x41) is the Windows function for checking for the "a" key, just for clarification. Is this a flaw with Allegro or am I doing something wrong? This occurs with a single event queue as well, I just wanted the code to be more logical in its order. |
Thomas Fjellstrom
Member #476
June 2000
![]() |
I'd just suggest not using the state api, or the Win32 code. Allegro events have all the information you normally need. Also there is never going to be any kind of guarantee that what you get through the state gathering will match the actual current state. It's just a static snapshot of the state at one point in time. It gets out of sync really fast. update your own state based on the events. -- |
ph03nix
Member #15,028
April 2013
![]() |
In my code I clearly tested with both states and events, and both have the exact same problem. I just included both to see if their behavior would differ. |
Thomas Fjellstrom
Member #476
June 2000
![]() |
The events will be ever so slightly be behind the current real-world state. Especially if you're capturing the entire keyboard state, and calling into the win32 api The good thing about the event system, is you won't miss key changes. you will with state apis. -- |
ph03nix
Member #15,028
April 2013
![]() |
My problem isn't with recognizing key presses or releases, or with key events at all. I'm not using allegro's key states in my games, I used it for the first time in this test program to compare results. The problem is that the key press is inconsistently recognized one iteration late using any allegro key recognition method (state and event) compared to window's key press recognition. Sometimes it's perfect, sometimes it's one iteration late. Inconsistency is very noticeable, and there shouldn't be any delay in the first place. |
Thomas Fjellstrom
Member #476
June 2000
![]() |
If you don't handle the events absolutely right away, they will lag behind reality. It's a given. a function that asks what the current state is, will always be a fraction ahead of the event system. -- |
l j
Member #10,584
January 2009
![]() |
al_get_keyboard_state(&keyState); bool winKey = GetKeyState(0x41)>>15; Any different results if you rotate these two?
|
Kris Asick
Member #1,424
July 2001
|
How long of a delay are we talking anyways? If it's less than 50 ms then players are simply not gonna notice and you're worrying about nothing. --- Kris Asick (Gemini) |
ph03nix
Member #15,028
April 2013
![]() |
Thomas Fjellstrom said: a function that asks what the current state is, will always be a fraction ahead of the event system. In my test program I call the Windows function, Allegro event queue, and Allegro keyboard state all simultaneously. At least the keyboard state should be "up to date", right? taron said: Any different results if you rotate these two? Swapping them makes no difference Kris Asick said: If it's less than 50 ms then players are simply not gonna notice This is simply not true. Although it is only 16 ms, it is inconsistent (it's sometimes 0, sometimes 16), which makes it more noticeable to a trained eye. Either way, there should not be a delay at all, it should always be 0. Simply calling the Windows function to check which key is down works with perfect precision, why doesn't allegro's key event? |
Kris Asick
Member #1,424
July 2001
|
ph03nix said: This is simply not true. Although it is only 16 ms, it is inconsistent (it's sometimes 0, sometimes 16), which makes it more noticeable to a trained eye.
You're seriously claiming you can manually tell the difference between instantaneous feedback from a keypress and a single frame delay at 60 FPS? Quote: Either way, there should not be a delay at all, it should always be 0. Simply calling the Windows function to check which key is down works with perfect precision, why doesn't allegro's key event? As Thomas has already pointed out, Allegro's I/O functions take regular snapshots of the state of everything. The al_get_keyboard_state() function simply pulls the current state from the last time Allegro updated its internal state. The reason it works this way is to ensure you don't actually miss keyboard presses or other input. With the method you're using to detect keyboard keys directly without Allegro, yes, it is more responsive. But, let's say someone presses a key for a tiny fraction of a second between one call to GetKeyState() and the next. Allegro will catch that keypress, but GeyKeyState() will miss it because the keypress came and went before it could be called while the key was pressed down. You may think "so what?" but consider that at 60 FPS, yeah, you're probably not gonna miss a lot of keys. Let's say instead your game has slowed to a crawl due to way too many particle effects and you're getting 5 FPS... and only checking the keyboard state five times a second. Now, your highly responsive routines are gonna be missing pretty much every keypress that happens quickly and isn't being held down for at least 0.2 seconds. So yeah, pros and cons to either method. I dunno how long you've been making games for but for most gamers, it's more important that their keypresses get caught than there being a single frame delay in the controls. (And if you have both problems, prepare for many angry eMails.) --- Kris Asick (Gemini) |
Thomas Fjellstrom
Member #476
June 2000
![]() |
ph03nix said: In my test program I call the Windows function, Allegro event queue, and Allegro keyboard state all simultaneously. There is no such thing as simultaneously in a single thread. Each one is executed after the other. Quote: Simply calling the Windows function to check which key is down works with perfect precision, why doesn't allegro's key event? Well, as far as I know, allegro runs a windows event loop in a thread for you, then translates those events into its own events which you then process in that inner loop. Note that there is going to be some thread/context switching when that happens (if you're on a single core, or the two threads happen to be running on the same core/cpu). As Kris mentioned, you will not lose input with the event system, also, each event comes with a timestamp which stores when that event occurred. So you can actually time things between events like fancy combos. -- |
|