Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

Thunder_Hawk

FPS Limiting

This topic is 5667 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts


    
void LimitFPS (DWORD fps)
{
	static DWORD dwFpsTimerCount = 0;
	static DWORD fun = 0;		// Used for evener...a very pseudo-random number :)

	fun++;				// If number overflows, it goes back to zero, so what? ¦*þ

	DWORD evener = (1000%fps && !(fun%int(10/(double(1000%fps)/double(fps)))/10))? 1 : 0;
	/* Use lazy evaluater to protect against division by zero.  Expression uses a predictably
	random number to ensure the fps is accurate...fixes the accuracy problem introduced by
	the integer while loop below. */
	DWORD count = 1000/fps + evener;
	if( dwFpsTimerCount != 0 )
		while(timeGetTime() < (dwFpsTimerCount + count) );
	dwFpsTimerCount = timeGetTime();
}
    
Does anyone know an easy way I can give up the wasted time there to other (hungry) programs? ______________________________ And the Phoenix shall rise from the ashes... --Thunder_Hawk -- ¦þ ______________________________ [edited by - Thunder_Hawk on February 9, 2003 9:22:33 PM]

Share this post


Link to post
Share on other sites
Advertisement
You could use sleep,

but in unix threads(or should I say posix) there is a function called yield() which tells the OS : "I have some free time, so give it to other processes". The advantage of that over sleep is that if no other processes need the power, it will give it back to you, so you have less time imprecision than with sleep.

I have never done threading in windows, so I don''t know if there is something like yield, but I assume there is.

Share this post


Link to post
Share on other sites
You _could_ use Sleep(0), your program then uses 100% of the processor but whenever another application wants some CPU time it will free the necessary CPU time for it.
But in the end your processor will still run at 100%.

Using Sleep() is not entirely precise and the time specified for the application to sleep can fluctuate within a 10ms resolution, so if you want exact results Sleep() is not the way to go.

Share this post


Link to post
Share on other sites
quote:
Original post by EinVante
You _could_ use Sleep(0), your program then uses 100% of the processor but whenever another application wants some CPU time it will free the necessary CPU time for it.

erm, no. calling sleep suspends your execution for the specified duration, which means that calling thread will not use any cpu time.

Share this post


Link to post
Share on other sites
As far as I know, no. However, I built a function called Rest that takes the desired maximum amount of CPU power and calls Sleep every few frames, the net result being that you have a little more control over your usage. I''ve tried running it under full load, and it''s accurate within +-2% on average.

I got the idea from SHilbert, but my implementation uses a static local timer object that packages things up. I''m not posting code here because it''s too implementation specific, but if you want to do something similar, the description I''ve given should be sufficient.

//email me.//zealouselixir software.//msdn.//n00biez.//
miscellaneous links

Share this post


Link to post
Share on other sites
ZE: I tried something similar to your idea and it turned out very "jumpy" (a very disturbing effect) and not much more accurate... I think I''ll just resort to sleep when doing text or something more static...

Share this post


Link to post
Share on other sites
Clearly you did something wrong, because this code works beautifully:

void CGame::Rest(float TimePercent)
{
float TimePerSec = 1000*(1-TimePercent);
static CTimer SleepTimer;
static float Accum = 0;

Accum += SleepTimer.GetLastFrameTime()*TimePerSec;

if(Accum >= 10)
{
Sleep(int(Accum));
Accum -= int(Accum);
}

SleepTimer.Update();
}

Later,
ZE.

//email me.//zealouselixir software.//msdn.//n00biez.//
miscellaneous links

Share this post


Link to post
Share on other sites
ZE: As usual you were right. Although, I wouldn't say that code is overly implementation dependant (it's written clear as a bell). The inaccuracy I reported was due to me sticking with the "evener" setup instead of using a float straight out. However, I believe the "jumpiness" is inherant to the structure of the code. It seems my eye can distinguish between the sleeping frames and the no stop frames. Increasing the interval has proven to stop it from being noticable though. Here's my new code:


    
void LimitFPS (float fps)
{
if (fps <= 0) return; // Obvious error

static DWORD dwFpsTimerCount = 0;
static float total = 0;
DWORD dMilliseconds;
if (dwFpsTimerCount) {
dMilliseconds = timeGetTime() - dwFpsTimerCount;
} else {
dMilliseconds = 0;
}
total += 1000/fps - dMilliseconds;
if (total >= 3) {
Sleep (int(total));
total -= int(total);
}
dwFpsTimerCount = timeGetTime();
}


This code seems just as accurate as my old code (usu. within 0.1 of the desired fps).

______________________________

And the Phoenix shall rise from the ashes...

--Thunder_Hawk -- ¦þ
______________________________


[edited by - Thunder_Hawk on February 10, 2003 8:38:28 PM]

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!