[A5] event queue & timing problems
Neil Roy

I have been working on my game and I have a high score screen which displays several rotating textures in the background while it waits for you to press a key.

The problem is, on my system, it all works great, no flaws, but when I run it on my wife's system, which is older with a built in graphic card, it displays the rotating graphics etc... all LOOKS okay, but you press any key to continue and nothing happens. It's like it's spending too much time on something else, probably drawing. If I have to change this and scale it down I will, but it would be nice if there was another solution, or even a way to detect a slower system and automatically scale things down.

Here's some of the code... (written in C)

#SelectExpand
1 bool done = false; 2 do { 3 al_wait_for_event(event_queue, &event); 4 5 if(event.type == ALLEGRO_EVENT_TIMER) { 6 // Rotate the three flares in the background while we wait for input 7 angle1 += PI/540; 8 if(angle1 > PI*2) angle1 -= PI*2; 9 angle2 -= PI/720; 10 if(angle2 < 0) angle2 += PI*2; 11 angle3 += PI/900; 12 if(angle3 > PI*2) angle3 -= PI*2; 13 al_clear_to_color(al_map_rgba(0, 0, 0, 255)); 14 al_draw_tinted_scaled_rotated_bitmap(flare, al_map_rgb(cr, cg, cb), flare_x, flare_y, 15 WIDTH/2, HEIGHT/2, 2, 2, angle1, 0); 16 al_draw_tinted_scaled_rotated_bitmap(flare, al_map_rgb(cr, cg, cb), flare_x, flare_y, 17 WIDTH/2, HEIGHT/2, 2, 2, angle2, 0); 18 al_draw_tinted_scaled_rotated_bitmap(flare, al_map_rgb(cr, cg, cb), flare_x, flare_y, 19 WIDTH/2, HEIGHT/2, 2, 2, angle3, 0); 20 al_draw_bitmap(buffer, 0, 0, 0); 21 al_flip_display(); 22 } 23 // Wait for key to be pressed and released to continue 24 if(event.type == ALLEGRO_EVENT_KEY_UP) { 25 done = true; 26 } 27 } 28 while(!done);

So as you see, it takes a texture called "flare" (512x512) and stretches, rotates etc... on screen three times, all overlapping and rotating in different directions (it's a flare) while it waits for user to press a key. I realize t here's a lot going on here but I didn't think it was all that much, I could be mistaken though, all that transparency I realize could be a problem, but it actually runs okay, looks smooth, it's just on my system it responds right away to a keypress, on hers, you either sit there tapping the key as fast as you can and hope it responds or force the program to end.

Any advice would be appreciated. I may scale down the graphics for this, but I wanted to see if there is something else I am doing wrong here.

Slartibartfast

It is possible that handling a timer event is taking longer than the interval between timer events. Try adding a check to the ALLEGRO_EVENT_TIMER case comparing the event timestamp to al_get_time and if the event is too old (older than a timer interval), don't do the drawing (i.e. continue;). If that solves it then you know the problem is drawing taking too long.

If you want to speed up drawing you can use al_hold_bitmap_drawing, which should help since you are repeatedly redrawing the same bitmap.
Another thing you should look into is timer, refresh rate and vsync. al_flip_display will wait for vsync if vsync is on (via your code or via drivers), and if the refresh rate is lower then your timer event frequency then drawing each frame will always take longer than the interval between timer events, leading to an ever growing buildup of events. If that is the case, merely discarding any "too old" events like I described earlier would be a good step towards solving the problem.

Thomas Fjellstrom

Slartibartfast's comment is the very reason I suggest starting with an event loop that drains the entire event queue before drawing. No matter how many draw timers it gets, it will only draw once, once the queue is empty. It also helps solve input lag issues (when events get backed up).

Check out my dumb example at the wiki.

Neil Roy

Thanks. It definitely has something to do with the timer event as I minimized the drawing down to just drawing a single, static background screen with a simple al_draw_bitmap() and it still lagged. So I had it print out what it was responding to and it was the ALLEGRO_EVENT_TIMER. So I'll try and recode it as you suggested. Thanks Thomas, I'll recheck that example. I recall when you first posted it on the forums, I still have your example actually, it is how I first really understood Allegro 5.

Edit:
That did it! The thing is, I actually done this as Thomas suggested when I first started this project with Allegro 5 in my main game loop, but this is a separate loop (high score screen), and to make matters worse, it was old Allegro 4 code I had converted over (non-event stuff) so somehow I forgot to clear that event queue ahead of time. Works well now on my wife's slow system and my own, proving Allegro 5 is plenty fast! :D

Here's the updated code (In case anyone stumbles across this post), I don't like to quit a thread without showing how I fixed a problem. ;)

#SelectExpand
1 bool done = false; 2 bool redraw = true; 3 do { 4 al_wait_for_event(event_queue, &event); 5 6 if(event.type == ALLEGRO_EVENT_TIMER) { 7 redraw = true; 8 } 9 // Wait for key to be pressed and released to continue 10 if(event.type == ALLEGRO_EVENT_KEY_UP) { 11 if(event.keyboard.keycode == ALLEGRO_KEY_F12) a5_screenshot("Screenshots/DeluxePacman2"); 12 else done = true; 13 } 14 15 if(redraw && al_is_event_queue_empty(event_queue)) { 16 redraw = false; 17 // Rotate the three flares in the background while we wait for input 18 angle1 += PI/540; 19 if(angle1 > PI*2) angle1 -= PI*2; 20 angle2 -= PI/720; 21 if(angle2 < 0) angle2 += PI*2; 22 angle3 += PI/900; 23 if(angle3 > PI*2) angle3 -= PI*2; 24 al_clear_to_color(al_map_rgba(0, 0, 0, 255)); 25 al_draw_tinted_scaled_rotated_bitmap(flare, al_map_rgb(cr, cg, cb), flare_x, flare_y, 26 WIDTH/2, HEIGHT/2, 2, 2, angle1, 0); 27 al_draw_tinted_scaled_rotated_bitmap(flare, al_map_rgb(cr, cg, cb), flare_x, flare_y, 28 WIDTH/2, HEIGHT/2, 2, 2, angle2, 0); 29 al_draw_tinted_scaled_rotated_bitmap(flare, al_map_rgb(cr, cg, cb), flare_x, flare_y, 30 WIDTH/2, HEIGHT/2, 2, 2, angle3, 0); 31 al_draw_bitmap(buffer, 0, 0, 0); 32 al_flip_display(); 33 } 34 } 35 while(!done);

And a screenshot of how it looks (the flares you can see in the background look really nice, three of them, all transparent and rotating in different directions at different speeds gives a nice effect). The colour of the flares is random each time it is run as well.

{"name":"608840","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/d\/5\/d57fd63796b01daa2579323791ed3060.png","w":800,"h":600,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/d\/5\/d57fd63796b01daa2579323791ed3060"}608840

beoran

That's one cool flare effect, maybe I'll borrow it for my engine if you don't mind. :)

Neil Roy
beoran said:

That's one cool flare effect, maybe I'll borrow it for my engine if you don't mind. :)

Sure, feel free. :)

The flare itself is a 512x512 alpha blended PNG... I'll attach it here...

{"name":"608843","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/7\/c\/7cfc0df9c13c1be4fe97436e0044a5d7.png","w":512,"h":512,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/7\/c\/7cfc0df9c13c1be4fe97436e0044a5d7"}608843

...I done a video of my game up a while back and you can see the effect in this video at around 1:14 (at the time I had fixed the colour, now it is random)...

video

Edgar Reynaldo

That's a great effect! Nice work!

beoran

Thanks! That's one lovely game!

Thread #614531. Printed from Allegro.cc