Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » FPS Timer Class not working

Credits go to taron  for helping out!
This thread is locked; no one can reply to it. rss feed Print
FPS Timer Class not working
Sythical
Member #14,461
July 2012

I created a class that acts FPS timer and has a wait function that returns every time the timer ticks. The problem I'm having is that the timer never ticks and I can't figure out why.

#SelectExpand
1class FrameTimer { 2 3 ALLEGRO_EVENT_QUEUE *event_queue; 4 ALLEGRO_TIMER *timer; 5 6public: 7 8 FrameTimer(int rate) { 9 event_queue = al_create_event_queue(); 10 timer = al_create_timer(1.0 / rate); // I've checked this value, it's what it should be 11 al_start_timer(timer); 12 13 14 // I added the event code in the constructor as well 15 // for testing, and this event also doesn't tick 16 ALLEGRO_EVENT event; 17 std::cout << "a\n"; // this prints 18 al_wait_for_event(event_queue, &event); 19 std::cout << "b\n"; 20 } 21 22 bool wait() { 23 ALLEGRO_EVENT event; 24 std::cout << "c\n"; 25 al_wait_for_event(event_queue, &event); 26 27 return true; 28 } 29};

I'm initialising Allegro in the main method, here is the code:

#SelectExpand
1if(!al_init()) return -1; 2ALLEGRO_DISPLAY *display = al_create_display(640, 480); 3if(!display) return -1; 4FrameTimer frame_timer(60);

Thanks!

taron 
Member #10,584
January 2009
avatar

You're not listening to the event.
use al_register_event_source

Sythical
Member #14,461
July 2012

@taron Ah yes, I keep forgetting to do that. Thank you, works fine now :)

Side question: I'm outputting the FPS and it ranges from 60 to 66 and changes rapidly. Is this normal or am I doing something wrong?

Dizzy Egg
Member #10,824
March 2009
avatar

It's hard to define 'normal' without much, MUCH more inf, but mine usually is 60fps with the odd flicker of 59fps, so maybe just a condition reshuffle or loop re-order; share some code & IDE specs bro! ;D

----------------------------------------------------
Please check out my songs:
https://soundcloud.com/dont-rob-the-machina

Sythical
Member #14,461
July 2012

@Dizzy Egg

Sure thing, I've only just started coding and trying to make the FPS more constant so there isn't much to shuffle. Here is my code: http://pastebin.com/UL9bzauA

I'm using VS11 on Windows 7 64-bit, I've tried both release and debug modes.

Arthur Kalliokoski
Second in Command
February 2005
avatar

I have this in a demo, it's a bit easier to read, and tends to flatten out the spikes.

  char fpscount[256];
  double fpscount = al_get_time();

  if( (frames % 32) == 0)  //frames is an int that gets incremented every al_flip()
  {
    sprintf(fpsmsg,"%8.4f",1.0/((double)(fpscount-oldfps)/32.0));
    oldfps = fpscount;
  }

  al_draw_textf(font,al_map_rgb_f(1.0,1.0,1.0),20.0,20.0,0,"%s",fpsmsg);

“Throughout history, poverty is the normal condition of man. Advances which permit this norm to be exceeded — here and there, now and then — are the work of an extremely small minority, frequently despised, often condemned, and almost always opposed by all right-thinking people. Whenever this tiny minority is kept from creating, or (as sometimes happens) is driven out of a society, the people then slip back into abject poverty. This is known as "bad luck.”

― Robert A. Heinlein

Dizzy Egg
Member #10,824
March 2009
avatar

Your code looks pretty solid; I'm a bit drunk &&|| high so maybe I'm completely wrong, but going by what you've said try changing your constructor:

FrameTimer(double rate);

//code code code

frame_timer FrameTimer(60.0);

???

(Edgar Reynaldo will tell you what's what....or maybe Thomas...wait, or maybe Trent...no wait....ahhhh, one of them will tell all soon. ;D

----------------------------------------------------
Please check out my songs:
https://soundcloud.com/dont-rob-the-machina

Sythical
Member #14,461
July 2012

@Arthur Kalliokoski
Thanks, I'll try that now but isn't calculating the average simply hiding the spikes and not actually getting rid of them?

@Dizzy Egg
I just tried that and that didn't seem to help.

timer = al_create_timer(1.0 / rate);
^ it uses a double (1.0) in the calculation so I assumed rate will automatically be treated as a double.

Arthur Kalliokoski
Second in Command
February 2005
avatar

Sythical said:

hiding the spikes and not actually getting rid of them

Sure. You don't expect the video card to be synced to the system timer, do you?

“Throughout history, poverty is the normal condition of man. Advances which permit this norm to be exceeded — here and there, now and then — are the work of an extremely small minority, frequently despised, often condemned, and almost always opposed by all right-thinking people. Whenever this tiny minority is kept from creating, or (as sometimes happens) is driven out of a society, the people then slip back into abject poverty. This is known as "bad luck.”

― Robert A. Heinlein

Sythical
Member #14,461
July 2012

Sure. You don't expect the video card to be synced to the system timer, do you?

Okay, I see what you mean. That's what I was trying to get to when I asked whether this fluctuation is normal or not. So I shouldn't worry too much about this as long as the actual amount of frames each second is more or less the same?

Arthur Kalliokoski
Second in Command
February 2005
avatar

Sythical said:

So I shouldn't worry too much about this

Correct. Even the example programs do it.

“Throughout history, poverty is the normal condition of man. Advances which permit this norm to be exceeded — here and there, now and then — are the work of an extremely small minority, frequently despised, often condemned, and almost always opposed by all right-thinking people. Whenever this tiny minority is kept from creating, or (as sometimes happens) is driven out of a society, the people then slip back into abject poverty. This is known as "bad luck.”

― Robert A. Heinlein

Trent Gamblin
Member #261
April 2000
avatar

Why are you continuously registering and unregistering the timer event source? Just register it once at the start. If you need to stop and start it use al_start_timer and al_stop_timer. But in this case I don't see why you need to.

Sythical
Member #14,461
July 2012

Why are you continuously registering and unregistering the timer event source?

I did it because I was able to make the program pause by scrolling through the console window. When it resumed, there were a lot of tick events in the queue and the frame rate suddenly jumped to a 1000 for a bit as it tried to quickly go through all of the events. I checked the documentation to find a way to clear the even queue but couldn't find anything so had to resort to registering and unregistering.

I didn't want to start/stop the timer in case that messes up with the frame rate but I didn't give this solution much thought and it's probably a better solution, I'll give it a try.

Also, the frame rate counter now shows 59.999-ish and 60.000-ish so I'm quite happy, thank you everyone.

Trent Gamblin
Member #261
April 2000
avatar

You can flush the event queue with al_flush_event_queue. But in your example you don't really have a game loop set up. To get it to not jump to 1000 FPS you need something like this (this is not ideal and is half-pseudo code because I'm feeling lazy):

#SelectExpand
1while (true) { 2 bool draw = false; 3 while (!al_event_queue_is_empty(queue)) { 4 ALLEGRO_EVENT event; 5 al_get_next_event(queue, &event); 6 // process some events here 7 if (event.type == ALLEGRO_EVENT_TIMER) { 8 draw = true; 9 } 10 // more event processing 11 } 12 if (draw) { 13 // Draw stuff 14 al_flip_display(); 15 } 16}

This keeps the event queue from building up by clearing the whole thing before ever drawing anything. It'll also balance your FPS counter.

Go to: