![]() |
|
A5 : timer issue |
William Labbett
Member #4,486
March 2004
![]() |
Hi, I've been trying to get to grips with the timer events and timers because I'm trying to work on the speed of animations. I wrote this code : 1#include <allegro5/allegro.h>
2#include <allegro5/allegro_primitives.h>
3#include <allegro5/allegro_image.h>
4#include <allegro5/allegro_font.h>
5#include <stdio.h>
6#include <stdlib.h>
7
8
9
10
11
12int main()
13{
14 ALLEGRO_DISPLAY *display = NULL;
15 ALLEGRO_FONT *font = NULL;
16
17 ALLEGRO_EVENT event;
18
19 int loop_count = 0;
20 bool got_loop_count = false;
21 bool counting_loops = false;
22 int timer_count_before = 0;
23 int timer_count_after = 0;
24 int time_counting = 0;
25
26 al_init();
27 al_set_new_display_flags(ALLEGRO_WINDOWED);
28
29 ALLEGRO_EVENT_QUEUE *queue = al_create_event_queue();
30 ALLEGRO_TIMER *timer = al_create_timer(1.0f/120.0f);
31
32 display = al_create_display(1600, 900);
33 if(display == NULL)
34 {
35 printf("Couldn't create display.");
36 }
37
38 if( al_init_primitives_addon() == false)
39 {
40 printf("Couldn't initialise image addon.");
41 }
42
43 al_init_image_addon();
44 al_init_font_addon();
45
46 al_install_keyboard();
47
48 al_init_primitives_addon();
49
50 font = al_load_font("fixed_font.tga", 24, 0);
51
52
53
54 al_register_event_source(queue, al_get_keyboard_event_source());
55 al_register_event_source(queue, al_get_timer_event_source(timer));
56 al_register_event_source(queue, al_get_display_event_source(display));
57 al_start_timer(timer);
58
59 al_set_target_backbuffer(display);
60
61 al_clear_to_color(al_map_rgb(0, 0, 0));
62
63 al_flip_display();
64
65 while(1)
66 {
67 al_wait_for_event(queue, &event);
68
69 switch(event.type)
70 {
71 case ALLEGRO_EVENT_KEY_DOWN:
72 if(event.keyboard.keycode == ALLEGRO_KEY_ESCAPE)
73 {
74 return 0;
75 }
76 else if(event.keyboard.keycode == ALLEGRO_KEY_F1)
77 {
78 al_destroy_display(display);
79 printf("Program finished.\n\n");
80 system("PAUSE");
81 return 0;
82 }
83 break;
84 case ALLEGRO_EVENT_TIMER:
85
86 if(got_loop_count == false)
87 {
88 printf("Got timer event.\n");
89 }
90
91 if(counting_loops == true)
92 {
93 timer_count_after = al_get_timer_count(timer);
94 printf("timer count (second time) is %d.\n", timer_count_after);
95
96
97 time_counting = timer_count_after - timer_count_before;
98 got_loop_count = true;
99 counting_loops = false;
100 }
101
102 if(counting_loops == false && got_loop_count == false)
103 {
104 counting_loops = true;
105 timer_count_before = al_get_timer_count(timer);
106 printf("timer count (first time) is %d.\n", timer_count_before);
107 }
108
109 //al_flush_event_queue(queue);
110
111 break;
112 case ALLEGRO_EVENT_DISPLAY_CLOSE:
113 return 0;
114 break;
115 default:
116 break;
117
118 }
119
120
121 //al_clear_to_color(al_map_rgb(0, 0, 0));
122 //al_draw_filled_circle(125, 384, 52.0f, al_map_rgb(255, 0, 0));
123
124 if(got_loop_count == true)
125 {
126 al_draw_textf(font, al_map_rgb(255, 255, 255), 30, 10, 0, "Clock ticks = %d. Number of full loops : %d.", time_counting, loop_count);
127 al_draw_textf(font, al_map_rgb(255, 255, 255), 30, 25, 0, "Clock ticks before = %d. Clock ticks after = %d.", timer_count_before, timer_count_after);
128 }
129
130 al_flip_display();
131
132 if(counting_loops == true)
133 {
134 printf("Incrementing loop_count.\n");
135 ++loop_count;
136 }
137
138 }
139
140 return 0;
141
142}
I get this output : Got timer event. If someone would take the trouble to take a look at the code you might notice that despite the output confirming that a timer event and the ++loop_count; line have both occured imbetween the two points where al_get_timer_count is called the two calls to al_get_timer_count() both return 4. This doesn't make any sense to me. Does someone know why it's happening?
|
DanielH
Member #934
January 2001
![]() |
Trying to wrap my head around what you have 1 // a
2 if(got_loop_count == false)
3 {
4 printf("Got timer event.\n");
5 }
6
7 // b
8 if(counting_loops == true)
9 {
10 timer_count_after = al_get_timer_count(timer);
11 printf("timer count (second time) is %d.\n", timer_count_after);
12
13
14 time_counting = timer_count_after - timer_count_before;
15 got_loop_count = true;
16 counting_loops = false;
17 }
18
19 // c
20 if(counting_loops == false && got_loop_count == false)
21 {
22 counting_loops = true;
23 timer_count_before = al_get_timer_count(timer);
24 printf("timer count (first time) is %d.\n", timer_count_before);
25 }
start: glc = false, cl = false; 1st iteration: a printed, b ignored, c processed cl is true so loop_count increments once 2nd iteration: a printed, b processed, c ignored cl is false and will always be false after this point 3rd iteration: a ignored, b ignored, c ignored Nothing happens after that because cl is false and glc is true What is it supposed to do? |
Edgar Reynaldo
Major Reynaldo
May 2007
![]() |
Your code doesn't really make sense. Keep it simple. Allegro has everything you need in the timer event itself. do { ALLEGRO_EVENT ev; al_wait_for_event(queue , &ev); if (ev.type == ALLEGRO_EVENT_TIMER) { old_ticks = tick_count; tick_count = ev.timer.count;/** forgive I can't remember if this is right*/ do_stuff_with_ticks(tick_count - old_ticks); } else {...} } while (!al_is_event_queue_empty(queue);
My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
William Labbett
Member #4,486
March 2004
![]() |
No, the code isn't familiar but it makes perfect sense. It does exactly what Daniel described. Thenks Daniel for working it out. What it's meant to do is simple : It calculates how many clock ticks it takes to run the code after the event loop. So it makes a record of the timer count. Then it does one run of the code after What doesn't make sense it that according to the event queue there's a new timer tick but the timer count hasn't changed. The manual does say that once al_wait_for_event get's an event it copies the event into the ALLEGRO_EVENT * provided and removes it from the queue so the next ALLEGRO_EVENT_TIMER should be a new clock tick meaning the number returned from al_get_timer_count should be larger. BTW If I call al_flush_event_queue which shouldn't be necessary the code works as expected.
|
Edgar Reynaldo
Major Reynaldo
May 2007
![]() |
Don't use al_get_timer_count. That is supposed to be always up to date. Use the tick count from the event. If you need to profile, use a high performance timer. There is one available in Eagle. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
torhu
Member #2,727
September 2002
![]() |
William Labbett said: I need to know this because I need to how frequently my drawing code gets executed. (I simplified the program and left out the drawing code). How frequently compared to your logic timer? Or do you want an FPS counter? Normally you would just draw once per logic update. And maybe skip the drawing when the event queue is not empty after the logic is done to avoid getting behind. |
William Labbett
Member #4,486
March 2004
![]() |
Thanks very much to both of you. torhu said: How frequently compared to your logic timer? It's got to be only as frequent or less frequent right? If it can't be more frequent I'd have to decrease the ticks_per_second passed to al_create_timer() EDIT : if I wanted to slow down the graphics updating ?. I did also want an FPS counter and I figured that was sort of what I was doing in a not so normal way.
|
DanielH
Member #934
January 2001
![]() |
al_wait_for_event will limit your frame counter to events. If you want to calculate FPS then draw every loop iteration and only process an event if there is an event. Check out my Tic Tac Toe game. I don't wait for events. 1void App::processInput()
2{
3 static ALLEGRO_EVENT event;
4
5 while (!al_event_queue_is_empty(this->m_queue))
6 {
7 al_get_next_event(this->m_queue, &event);
8
9 switch (event.type)
10 {
11 case ALLEGRO_EVENT_TIMER:
12 {
13 ++this->m_counter;
14 } break;
15// ...
16}
17
18
19int32_t App::loop()
20{
21 while (!this->m_kill)
22 {
23 this->processInput();
24
25 while (this->m_counter > 0)
26 {
27 this->doLogic();
28 --this->m_counter;
29 }
30
31 if (this->m_dirty)
32 {
33 this->draw();
34 this->m_dirty = false;
35 }
36
37 al_rest(0.01);
38 }
39
40 return 0;
41}
You could remove the 'dirty' check and add a couple vars (frames and seconds). At each draw, increment a frame counter. At each timer increment a seconds counter. FPS = frames/second; |
|