|
|
| fps and timer stuff |
|
Nunca Ese
Member #5,262
November 2004
|
Quote:
It completely changes the dynamics of the game if what was a fast-paced jump'n run game suddenly runs at half speed. Imagine what would happen if you tried to run an RTS over a network where not all computers have the same speed.
Agree. I was talking about my turn based game and also solo games. evert said: Did you remember to declare speed_counter as volatile? could be, dunno. evert said:
The problem is that timeslice size changes from so version, so its like rest(variable) IMO.
1st so = os (sorry, spanish SO -> english OS (Operating System)) evert said:
Look at the code. They're not calling it from the active (meaning logic) loop.
Dont see why 'active' means 'inside logic', explain please |
|
Evert
Member #794
November 2000
|
Quote: I was talking about my turn based game and also solo games.
It could a viable alternative in those cases. I wouldn't say it's better. Quote: you will rest un uncertain time, you dont know timeslice size and how far you are from the end of the timeslice. If your program is designed well enough, then you shouldn't care about this. As is said, rest(1) rests on average 1 ms. Quote: Dont see why 'active' means 'inside logic', explain please Nothing to explain, really. That's just what the docs mean by active. |
|
Nunca Ese
Member #5,262
November 2004
|
evert said: It could a viable alternative in those cases. I wouldn't say it's better. Yea, depends on who consumes the time, render or logic, and what you want to show. evert said:
you will rest un uncertain time, you dont know timeslice size and how far you are from the end of the timeslice. Agree. Im using yield_timeslace. Quote:
Dont see why 'active' means 'inside logic', explain please Ok. My mistake then. Nice thread by the way! |
|
Trezker
Member #1,739
December 2001
|
|
Oscar Giner
Member #2,207
April 2002
|
Quote: One reason why not is beat frequencies. Your example would give an artifact at 15 Hz, which is acceptable IMO, but an extreme example would be logic at 60Hz with display at 61Hz, which in a slow scroll would produce a visible jerkiness at 1Hz intevals Actually that's the big problem with hardcoding the ticks per second in the game. Playing a game coded at 60fps on a 85Hz display mode looks very jerky (this is most noticeable in 3D games or 2D games with fast scrolling). One solution is to force display frequency, but not all video drivers allow it, or the user may have disallowed it, so it's not a perfect solution. That's why most comercial games use a variable timing interval (they check how much time has passed since the last logic, using WinAPI's GetPerformanceTimer()). I haven't tried this method yet, but I'll certainly do. The general algorithm to move an object this way would be something like this:
-- |
|
Marco Radaelli
Member #3,028
December 2002
|
I suggested rest(1), but probably I should have said rest(0). Right now I think the latter is the correct. IIRC there was a bug somewhere about yield_timeslice() and people suggested me to use rest(), probably with 0, not with 1. Using 0, IIRC will release the timeslice, without any wait.
|
|
lucaz
Member #4,194
January 2004
|
Well I'm more confused now. For example, to show a circle that change it color per loop.
|
|
ImLeftFooted
Member #3,935
October 2003
|
|
|
Nunca Ese
Member #5,262
November 2004
|
@ImLeftFooted ... if(timer) { timer-- // vs ++ ...
This code works (some mistakes on lucaz code). Take it and play with RATE param (set to 60 or whatever u want). |
|
lucaz
Member #4,194
January 2004
|
Yeesssssssssssssss, I hope Ive understood the idea. |
|
Nunca Ese
Member #5,262
November 2004
|
lucaz said:
Yeesssssssssssssss, I hope Ive understood the idea.
Not exactly. Timers are events thrown 'n' times in a sec. Those 'n' times are also known as ticks. What the program is doing is firing 60 ticks per second. change you will notice that timer is always 1. |
|
lucaz
Member #4,194
January 2004
|
thanks a lot people! |
|
Kitty Cat
Member #2,815
October 2002
|
Don't draw in the logic loop.
-- |
|
lucaz
Member #4,194
January 2004
|
Why not? :S |
|
Kitty Cat
Member #2,815
October 2002
|
Because the rendering is usually the most expensive (system-wise) in your program. You want it seperated out so you can skip it if you fall behind (ie. frame skipping). Even you absolutely have to draw for your logic to properly run (which is rare), you still don't need to draw to the screen (unless you're using direct dirty rectangles like Allegro's GUI). It also helps the CPU cache when you access larger buffers, since the CPU wouldn't have to try to cache the buffer everytime you draw something more after doing a bit more logic. As well, WIndows and X don't really like mixing drawing to VRAM and using other input functions at the same time. -- |
|
gering
Member #4,101
December 2003
|
read this - about timing http://www.geisswerks.com/ryan/FAQS/timing.html Average duration of Sleep(1) --- timeBeginPeriod() solves the problem: __________________________________________________________ |
|
Kitty Cat
Member #2,815
October 2002
|
Quote: So if you're on windows 2000 and you call timeBeginPeriod(1) and then Sleep(1), it will truly sleep for just 1 millisecond, rather than the default 10! I bet it doesn't do a thing for CPU usage that way either. -- |
|
tobing
Member #5,213
November 2004
|
Thx for this really interesting article. |
|
gering
Member #4,101
December 2003
|
Kitty Cat said: I bet it doesn't do a thing for CPU usage that way either.
It does! __________________________________________________________ |
|
gnolam
Member #2,030
March 2002
|
If it really works it should be added to Allegro... -- |
|
count
Member #5,401
January 2005
|
Ok, this is one of the best threads I ever read. My code currently looks like this and it works very good!
THX!
|
|
Derezo
Member #1,666
April 2001
|
Quote: timeBeginPeriod() solves the problem: That's some interesting information Quote: I bet it doesn't do a thing for CPU usage that way either. Why wouldn't it? "He who controls the stuffing controls the Universe" |
|
lucaz
Member #4,194
January 2004
|
I wonder how much confused can I be! |
|
Kitty Cat
Member #2,815
October 2002
|
Quote: If you're averaging a wait of 16ms (~60fps) in 1ms increments, you're only making a maximum 16 "if (x)" checks each logic update. So naturally you're using far less CPU time. But something needs to constantly check if that 1ms time period has passed or not. The scheduler granularity in Windows is 10ms, so the process that does the Sleep checking will only run approximately once every 10ms (unless you give it a higher priority, which will cause it to take more CPU). To get more than that, you'd need to busy loop, which doesn't do anything for CPU usage. More than that though, even if you can get more Sleep granularity while still sleeping the CPU, the efficiency of Sleep reducing CPU usage will deteriorate since it will have to return to the program and check if another frame is ready more often, before going back to sleep. It's like going to bed then waking up every hour to check if 8 hours have passed, or sleeping at least 8 hours and not waking up before you need to. A game with 100 logic frames per second (or less) will do just fine with a Sleep granularity of ~10ms. -- |
|
tobing
Member #5,213
November 2004
|
I have done some experiments with timeBeginPeriod() and rest() and such. First, thanks to all for these really interesting infos. So now I can understand my measurements much better, which relate internal CPU counter and the CPU usage indicated in the task manager. Now, using timeBeginPeriod(1) in the start of my program changes the confusing behaviour I saw before into some understandable behaviour now. Well, I was forced to include winmm.dll and stuff into my main program, so I tried to move timeBeginPeriod() into the implementation of rest(). That was a good idea! Works perfectly well for my program, and also better than changing the main program only. So how can I propose this change for consideration for the next allegro change? Next I have again analysed the behaviour of dlg, which uses 100% CPU on doing nothing, but not all the time. I think I should write the results in an extra thread, but again I have two little changes to propose here, one for allegro and one for dlg. How do I do that? |
|
|
|