Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » fps and timer stuff

Credits go to Derezo, Erkle, Evert, flares, FMC, gering, ImLeftFooted, jamal, Marco Radaelli, Matt Smith, Nunca Ese, Oscar Giner, Rampage, tobing, Trezker, and umperio for helping out!
This thread is locked; no one can reply to it. rss feed Print
 1   2   3 
fps and timer stuff
Evert
Member #794
November 2000
avatar

Quote:

So how can I propose this change for consideration for the next allegro change?

You can send a patch (or post manually how the code should be changed) on the mailinglist, this forum, or through private message/email to one of the developers.

tobing
Member #5,213
November 2004
avatar

Thanks. I think I'll post the instructions how to change based on 4.1.17 into a new thread this evening. Same for dlg.

gering
Member #4,101
December 2003
avatar

__________________________________________________________
[ FreeGameDevLibs ]

tobing
Member #5,213
November 2004
avatar

That look a bit similar to what I'm doing in my game loop (which I posted in some thread last week, forgot which it was). Essentially I call rest(1) if I have some time to waste. As for the fps, I only want about 60fps (or another number, as this is configurable), I don't care for the very exact number here as long as it is about the requested number in the long run.

gering
Member #4,101
December 2003
avatar

Have you tested timeBeginPeriod() in your gameloop?
FPS should get more accurate, but what about the CPU time (better or worse)?

Or are you using Linux?

__________________________________________________________
[ FreeGameDevLibs ]

tobing
Member #5,213
November 2004
avatar

I'm using Windows XP, and the fps got more accurate. Actually, that's not the whole truth. The code is using timers to control the loop. One timer is at 60/sec, one is at 1/sec to count the actual frame rate, and I use a third timer at 10000/sec to measure times of code sections at 0.1ms precision. The point was: If I use rest(1) within my game loop to give time back when I don't need that time for my current frame, I got different measures between my internal measurement and the task manager. Now that's pretty close, and overall cpu usage is reduced. Some secrets remain, though. Maybe I should report these in a separate thread, so you could try my latest executable (which is not online yet).

gering
Member #4,101
December 2003
avatar

Quote:

The code is using timers to control the loop.

Are you using Allegro's Timers? Because they are not accurate, you schould use QueryPerformanceCounter() to get exactly the fps you want. ;)

[edit]
and use the highest resolution possible - in ticks!

__________________________________________________________
[ FreeGameDevLibs ]

tobing
Member #5,213
November 2004
avatar

Yes, I'm using allegro's timers. I think that using timeBeginPeriod() and timeEndPeriod() also might increase precision of those timers.

Well, I might use any Windows specific functions, but that would mean I decide to not port the game to any other platform in future. Somehow I hesitate to make such a decision, so I would really prefer to stick to allegro's features.

gering
Member #4,101
December 2003
avatar

Quote:

Yes, I'm using allegro's timers. I think that using timeBeginPeriod() and timeEndPeriod() also might increase precision of those timers.

could be,
but resolution of 1ms isn't good enough, if you want fixed FPS and give CPU time back.

e.g.

You want to run your game at 60 FPS
Then one Frame schould take 16.6667 ms.

With allegro's timers you can get 16 or 17 (if timeBeginPeriod() increase precision on that timer)

if 16 then your FPS will be at 62.5
if 17 then your FPS will be at 58.8

The higher the FPS the less accurate the result.

Quote:

Well, I might use any Windows specific functions, but that would mean I decide to not port the game to any other platform in future. Somehow I hesitate to make such a decision, so I would really prefer to stick to allegro's features.

I would write an timer class and use #ifdef _WIN32 for QueryPerformanceCounter() and timeBeginPeriod()
and #else for Linux. It has an High Resolution Timer too, something like getdaytime()?! :-/

__________________________________________________________
[ FreeGameDevLibs ]

tobing
Member #5,213
November 2004
avatar

Actually I'm using allegro timers which call a function incrementing a variable at a given speed. I don't know that these are unprecise the way you suggest here, instead I found these timers quite reliable. So I have Timers working in a separate thread (I assume) and my game loop just looks at the values of the variables being incremented by these timers. So I can show the next frame when the variable becomes nonzero. Maybe my frames are not precisely 16.66666...ms apart, but in average they are, because some take 16ms where others would take 17ms.

gering
Member #4,101
December 2003
avatar

OK +- 2 FPS is not that big deal for most games. :P
How do you move objects? Is motion smooth? Do you use delta_time?

__________________________________________________________
[ FreeGameDevLibs ]

tobing
Member #5,213
November 2004
avatar

Cutrrently I'm not moving objects smoothly. Internally I distinuish between physical and logical time, because I want to be able to adjust the game speed in a wide range. So essentially this means that I put several logical frames into a physical frame (when game speed is high), and I can skip displaying physical frames also to avoid slowdown.

For later versions I want to implement smooth movement also, but currently I'm working on my A-Train clone (see depot) which did not have smooth movement in original, so I decided to do it the same way for the first version. Also I don't have animated sprites or tiles yet, that's also planned for the future.

gering
Member #4,101
December 2003
avatar

What I am doing is:

I have a FPS (Frames Per Second) set to maximum 62 -> rest goes to CPU
and I have a LPS (Logic(Frames) Per Second) set to exactly 100

The FPS can drop as low as 1 Frame Per Second, but the Logic Per Second stays always at 100 (it takes 2 ms on my computer, while rendering takes ~9-11ms). I can spent ~3-4 ms pro Frame to the CPU, which is ~25% (depends on CPU).

I have a counter (64Bit) that counts the ticks since program start.
1 Tick = ~8.500.000 ms (If I remember correctly)

I do not use ms to calculate my movement, but ticks.

For that I have 2 helper function
long long ms2ticks(float ms);
float ticks2ms(long long ticks);

This way movement gets very precise on fast an also slow systems.

BTW the Logic is fixed to 100 updates because of my network code, which results in better ping times. :)

__________________________________________________________
[ FreeGameDevLibs ]

tobing
Member #5,213
November 2004
avatar

Sounds good.

Somehow I get the impression here, that almost everybody starting to program a game re-invents the game loop again and again. It might be a good idea to create a small collection of 'good' or 'state-of-the-art' game loops somewhere on this site, what do you think?

Anyway, I would like to see your game loop to learn how you do these things...

gering
Member #4,101
December 2003
avatar

Quote:

Somehow I get the impression here, that almost everybody starting to program a game re-invents the game loop again and again. It might be a good idea to create a small collection of 'good' or 'state-of-the-art' game loops somewhere on this site, what do you think?

this is a good idea
1) easy game loops - like the one in the faq - but not that accurate
can have more than one timer and use those for easy animation
2) synchron (fps = lps) needs delta or fixed speed
3) asynchron (fps <> lps) uses only one timer -
2 kinds of movement: pixels/logic or pixel/time

Quote:

Anyway, I would like to see your game loop to learn how you do these things...

OK, kann ich später posten (da ich grad im Büro bin). Muss erst ein bissl suchen, da ich lange nicht mehr an dem Projekt gearbeitet habe, kaum Zeit gehabt... ::)

__________________________________________________________
[ FreeGameDevLibs ]

tobing
Member #5,213
November 2004
avatar

Kein Problem. :D und Dank im Voraus!

Edit:

The right place to collect game loops would be the Resources -> Code Gallery, which by now only has 3 entries.

gering
Member #4,101
December 2003
avatar

OK, I found a gameloop, but this one is without my c++ timer class.

m2t() converts ms to ticks
t2m() converts ticks to ms

This was written a while ago - next step is port all to c++ and make code cleaner...

1void main_loop(void)
2{
3 long long logic_delta;
4 long long render_delta;
5 
6 long long logic_wait = timer_ticks() + m2t(1000/LPS_wanted);
7 long long render_wait = timer_ticks() + m2t(1000/FPS_wanted);
8 
9 // game loop
10 while (isLoop)
11 {
12 // logic skip
13 logic_delta = logic_wait - timer_ticks();
14 if (logic_delta < 0)
15 {
16 // calculate new logic_wait
17 logic_wait += m2t(1000/LPS_wanted);
18 
19 // update lps and gtpl
20 timer_update(LPS);
21 
22 // update logic
23 main_logic();
24 }
25 
26 // render skip
27 render_delta = render_wait - timer_ticks();
28 if (render_delta < 0)
29 {
30 // calculate new render_wait
31 render_wait += m2t(1000/FPS_wanted);
32 
33 // update fps
34 timer_update(FPS);
35 
36 // render frame
37 main_render();
38 }
39 
40 // give os rest of cpu power & save battery
41 if (t2m(min(logic_delta, render_delta)) > 1)
42 {
43 // update sleep
44 timer_update(SLEEP);
45
46 // CPU Sleep for 1 msec
47 Sleep(1);
48 }
49 }
50}

__________________________________________________________
[ FreeGameDevLibs ]

Kitty Cat
Member #2,815
October 2002
avatar

Quote:

I have a FPS (Frames Per Second) set to maximum 62 -> rest goes to CPU
and I have a LPS (Logic(Frames) Per Second) set to exactly 100

Why are these different? Your logic rate should be the same as your max FPS (one logic update per frame, with frame dropping), or keep them in sync (FPS = LPS) using time deltas.

--
"Do not meddle in the affairs of cats, for they are subtle and will pee on your computer." -- Bruce Graham

gering
Member #4,101
December 2003
avatar

I want the network code (which is in a logic frame) highly responsive and I am scared of using threads. :o

Using 100 Logic updates gives me way better results than 62 logic updates. But I don't want to render more often than 62/60 because it's a waste of CPU time. Ping is also getting better by using rest() / Sleep() , because RakNet is running in threads. ;)

__________________________________________________________
[ FreeGameDevLibs ]

 1   2   3 


Go to: