Allegro.cc - Online Community

Allegro.cc Forums » Allegro Development » Problem in Allegro 5.2.4 Timer!

This thread is locked; no one can reply to it. rss feed Print
Problem in Allegro 5.2.4 Timer!
Mahmoud Fayed
Member #8,895
August 2007

Hello

After switching from Allegro 5.1 to Allegro 5.2.4
And using binaries in this distribution for Visual C/C++
https://www.nuget.org/packages/Allegro/

I discovered a problem in the (Timer) !
Where the timer event is always fired without waiting for the time to pass.

I'm using the timer to control the drawing at (60 FPS)
With Allegro 5.1 (No Problem) - I get the expected behavior (60 FPS)
While with Allegro 5.2.4 - I get over 350 FPS !

The code looks like this (In Ring programming language - Just normal calls to Allegro)

#SelectExpand
1 func setup 2 al_init() 3 al_init_font_addon() 4 al_init_ttf_addon() 5 al_init_image_addon() 6 al_install_audio() 7 al_init_acodec_addon() 8 al_reserve_samples(1) 9 al_set_new_display_flags(ALLEGRO_OPENGL) 10 display = al_create_display(SCREEN_W,SCREEN_H) 11 al_set_window_title(display,TITLE) 12 al_clear_to_color(al_map_rgb(0,0,0)) 13 event_queue = al_create_event_queue() 14 al_register_event_source(event_queue, 15 al_get_display_event_source(display)) 16 ev = al_new_allegro_event() 17 timeout = al_new_allegro_timeout() 18 al_init_timeout(timeout, 0.06) 19 timer = al_create_timer(1.0 / FPS) 20 al_register_event_source(event_queue, 21 al_get_timer_event_source(timer)) 22 al_start_timer(timer) 23 al_install_mouse() 24 al_register_event_source(event_queue, 25 al_get_mouse_event_source()) 26 al_install_keyboard() 27 al_register_event_source(event_queue, 28 al_get_keyboard_event_source()) 29 30 func eventsLoop 31 while true 32 al_wait_for_event_until(event_queue, ev, timeout) 33 switch al_get_allegro_event_type(ev) 34 on ALLEGRO_EVENT_DISPLAY_CLOSE 35 CloseEvent() 36 on ALLEGRO_EVENT_TIMER 37 redraw = true 38 off 39 if redraw and al_is_event_queue_empty(event_queue) 40 redraw = false 41 drawScene() 42 al_flip_display() 43 ok 44 end

Greetings,
Mahmoud

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

Peter Hull
Member #1,136
March 2001

I haven't compiled the code but my guess is: ALLEGRO_TIMEOUT is an absolute time so the first call to al_wait_for_event_until will wait 60ms but the ones after will be zero. Probably al_wait_for_event_timed is what you want
Hope that helps
Pete

Mahmoud Fayed
Member #8,895
August 2007

Hello Edgar

Yes, This is what I mean, and I will attach a C program

Hello Peter

Yes, the problem is related to ALLEGRO_TIMEOUT

(1) The Ring code uses a pointer for the ALLEGRO_TIMEOUT and doing the initialize operation just one time! ---> (I fixed that to avoid the problem, Thanks :D )

(2) It was also a change in behavior between Allegro 5.1.11 and Allegro 5.2.4 where the problem doesn't exist in Allegro 5.1.11

Attached the C source code, written just for testing to demonstrate the change.

#SelectExpand
1#include "stdlib.h" 2#include "stdio.h" 3 4#define ALLEGRO_NO_MAGIC_MAIN 5 6#include <allegro5/allegro.h> 7#include <allegro5/allegro_color.h> 8 9int SCREEN_W = 800; 10int SCREEN_H = 600; 11int FPS = 60; 12int Counter = 0; 13int RunProgram = 1; 14int Wait = 7; 15 16ALLEGRO_EVENT_QUEUE *event_queue = NULL; 17ALLEGRO_DISPLAY *display = NULL; 18ALLEGRO_TIMER *timer = NULL; 19 20void Setup(void); 21void EventsLoop(void); 22void DrawScene(void); 23void FreeResources(void); 24 25int main(int argc,char *argv) { 26 printf("Welcome to the Timer test program!\n"); 27 printf("The program must wait for around 7 seconds then exit!\n"); 28 Setup(); 29 EventsLoop(); 30 FreeResources(); 31 return 0; 32} 33 34void Setup(void) { 35 al_init(); 36 al_set_new_display_flags(ALLEGRO_OPENGL); 37 al_set_new_display_option(ALLEGRO_DEPTH_SIZE, 16, ALLEGRO_SUGGEST); 38 display = al_create_display(SCREEN_W,SCREEN_H); 39 al_set_window_title(display,"Test Timer"); 40 al_clear_to_color(al_map_rgb(0,0,0)); 41 event_queue = al_create_event_queue(); 42 al_register_event_source(event_queue,al_get_display_event_source(display)); 43 timer = al_create_timer(1.0 / FPS); 44 al_register_event_source(event_queue,al_get_timer_event_source(timer)); 45 al_start_timer(timer); 46 al_install_mouse(); 47 al_register_event_source(event_queue, al_get_mouse_event_source()); 48 al_install_keyboard(); 49 al_register_event_source(event_queue, al_get_keyboard_event_source()); 50 al_flip_display(); 51} 52 53void EventsLoop(void) { 54 int redraw = 0 ; 55 while (RunProgram) { 56 ALLEGRO_EVENT ev ; 57 ALLEGRO_TIMEOUT timeout ; 58 // We can ignore the next line in Allegro 5.1.11 (But we can't do that for Allegro 5.2.4) 59 // al_init_timeout(&timeout, 0.06); 60 al_wait_for_event_until(event_queue, &ev, &timeout); 61 switch( ev.type ) { 62 case ALLEGRO_EVENT_DISPLAY_CLOSE : 63 RunProgram = 0; 64 break; 65 case ALLEGRO_EVENT_TIMER : 66 redraw = 1; 67 break; 68 } 69 if (redraw && al_is_event_queue_empty(event_queue) ) { 70 redraw = 0 ; 71 DrawScene(); 72 } 73 } 74} 75 76void DrawScene(void) { 77 Counter++; 78 if (Counter == FPS * Wait ) RunProgram = 0 ; 79} 80 81void FreeResources(void) { 82 al_destroy_display(display); 83 al_destroy_event_queue(event_queue); 84 al_destroy_timer(timer); 85}

Greetings,
Mahmoud

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

Mahmoud said:

ALLEGRO_TIMEOUT timeout ;
// We can ignore the next line in Allegro 5.1.11 (But we can't do that for Allegro 5.2.4)
// al_init_timeout(&timeout, 0.06);
al_wait_for_event_until(event_queue, &ev, &timeout);

Take notice that 'timeout' is UNINITIALIZED if you don't call al_init_timeout.

Now if you call al_init_timeout, and wait until the timeout returns, it SHOULD remain the same as far as timeout value goes. If it changes before the next call to al_wait_for_event_until, that's a bug in Allegro, or at the least its undocumented behavior.

The fact that it works in 5.1.11 makes no difference. 5.1 is VERY old as far as versions go. You should be using 5.2.4 if you can.

SiegeLord
Member #7,827
October 2006
avatar

This is probably due to this bug being fixed:

https://github.com/liballeg/allegro5/issues/593

Before it was fixed, even though your timeout was effectively 0 (being set in the past), al_wait_for_event_until would still wait for an event to show up.

"For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18
[SiegeLord's Abode][Codes]:[DAllegro5]:[RustAllegro]

Peter Hull
Member #1,136
March 2001

But, if you've got a timer firing every 60ms, you don't need a timeout at all because the timer event do the same thing (or am I missing something?)

And, if you do want to use al_wait_for_event_until you should check the return value; if it returns due to the timeout, the event will be invalid.

Go to: