Frame limiting

BlitzMax Forums/BlitzMax Programming/Frame limiting

therevills(Posted 2012) [#1]
Hi All,

I am trying to create smooth frame limiting and my current code has a small hiccup every few frames.

I would like to limit the FPS to 59FPS and I am currently using the following code:



The frame limiting is meant to act like max_fps commands in 3D engines such as the source engine (Half Life) and Tech 3 (Quake).

Has any one got any decent frame limiting code that is better than this?

Thanks!

Last edited 2012


ImaginaryHuman(Posted 2012) [#2]
Could it be that on occasion your code is getting run just before the end of a frame, is doing a short Delay() but the delay takes the code past the vertical blank, and then it has to wait a whole other frame before it draws?


xcessive(Posted 2012) [#3]
Graphics 640, 480, 1, 59


Russell(Posted 2012) [#4]
xcessive, won't that line bomb out on displays that don't support 1 bit (monochrome) display modes and/or 59 hertz refresh rate?

Russell


Jesse(Posted 2012) [#5]
@Therevills

I don't see how that can give you accurate results. Reason being that there can be multiple flips per Milliseconds. and you need to count values to as close to 16.949 to get 59 frames per second so that it can get accurate results. if you can access anything that can count smaller values than a millisecond than you will get more accurate results.

I used code similar to what Mark used in the flip commad and I get the same results. I did noticed that some rates are more accurate than others And that is the result in the fraction of the accumulator which is ignored. I did all of this test with flip 0. Try it with 30, 58, 59 and 60 fps. notice that 30 is pretty accurate 58 is also accurate but 59 and 60 are not. ( at least that was the case in my Macbook).



Last edited 2012


xcessive(Posted 2012) [#6]
@russel: Nope.


neumanix(Posted 2012) [#7]
Here's a way to do it using delta timing.
You set the speed variable to determine the overall speed of any movement. It's set to 100 in the example, but go ahead and test different values.
Every second a delta value is calculated and you multiply your movements with this value.

Notice the speed is the same regardless if vsync is on or off (true/false)

Your gfx card may scream a little with it off though :)

You can also add a Delay(1) in the main loop to give the CPU some slack.

Use the cursor keys to move the "player".

Framework brl.d3d9max2d

SuperStrict

Graphics(640, 480)

DrawRect(0, 0, 32, 32)
Local sprite:TImage = CreateImage(32, 32)

GrabImage(sprite, 0, 0)

Local angle:Float = 0.0
Local delta:Float = 0.0
Local speed:Float = 100
Local x:Float
Local output:Int
Local elapsedTime:Int
Local fps:Int
Local vsync:Int = False

Type Tentity
	Field x:Float
	Field y:Float
	Field img:TImage
End Type

Local player:Tentity = New Tentity
player.img = SPRITE

Local starttime:Int = MilliSecs()

Repeat
	Cls
	x = Sin(angle) * 320 - 16
	DrawImage(sprite, 320 + x, 200)

	DrawImage(player.img, player.x, player.y)

	If KeyDown(KEY_RIGHT)
		player.x:+5 * Delta
	End If
	If KeyDown(KEY_LEFT)
		player.x:-5 * delta
	End If
	If KeyDown(KEY_UP)
		player.y:-5 * delta
	End If
	If KeyDown(KEY_DOWN)
		player.y:+5 * Delta
	End If


	angle:+1 * delta
	fps:+1
	elapsedTime = MilliSecs() - starttime
	If elapsedTime > 1000
		delta = speed / fps
		output = fps
		fps = 0
		starttime = MilliSecs()
	End If
	DrawText("Delta value: " + delta, 0, 0)
	DrawText("FPS: " + output, 0, 11)
	Flip vsync
Until KeyHit(KEY_ESCAPE)
End


Last edited 2012

Last edited 2012


Jesse(Posted 2012) [#8]
that is not really what this thread is trying to solve. Therevills know how to do that. I am sure.


therevills(Posted 2012) [#9]
Thanks for the reply guys.

@IM - yeah maybe...

@xcessive - I am trying to limit both fullscreen and window mode, the hertz parameter doesnt really work that great as a frame limiter

@Jesse - thanks for the code sample, I'll have a look tonight

@neumanix - thanks for trying to help, but Jesse is right I know about dt timing :P