Timing code amendment

BlitzPlus Forums/BlitzPlus Programming/Timing code amendment

Grey Alien(Posted 2004) [#1]
In the on-line FAQ there is a question about monitor refresh rates that links to an archived forum post that contains some useful code by Swerdnik sent to Anthony Flack. It allows you to make your game run at the same speed on any machine no matter what the refresh rate is. I know there is lots of this sort of thing around but this code is really one of the best. It does it by running a high frame rate of 500 frames per sec for all logic calculations and only outputting a frame when it needs to. You can change it to run at other frame rates, my game runs at 200 for example.

This is great and I have used it to great success BUT I found a bug ... I had a time limit in my game that was supposed to count down in seconds and I used the logic loop to do it (I know I could have done it other ways but that's what I did) and I noticed that it wasn't counting down in exact seconds, it was slightly out. After ages trying to track it down I realised that the main logic loop should NOT start at zero it should start at 1! i.e.
	;now we do the logic loop
	For i = 1 To NumTicks

This change means you can reliably make timers for fades and animations etc. without them being slightly out.

The original code is posted below, I hope Swerdnik doesn't mind:

; Refresh rate Independent smooth graphics for Anthony
;
; made by mike boeh, wee!
;
; In a nutshell, this runs at a high frame rate internally, then scales down
; to what ever hz the user happens to be running
;
;
Graphics 640, 480, 16, 1
SetBuffer BackBuffer()
ClsColor 255,255,255

;load in a simple sprite (nice art btw :D)
Ship = LoadImage("flack.png")
MidHandle(Ship)
ShipX# = 300
ShipY# = 300
ShipXSpeed# = .33
ShipYSpeed# = .55

;set a first value for LastTime (it will be used in the main loop)
LastTime = MilliSecs()/2
LastNumTicks = 1

;start the program loop
While Not KeyHit(1)

	;for our purposes, a tick is 1/500th of a second, just divide millisecs by 2 :)
	;get in the time and make sure at least 1 tick expired
	Repeat
		TmpMS = MilliSecs()/2
		
		;little sanity check here in case the timer flips back to 0 :)
		If TmpMS < LastTime Then LastTime = TmpMS - LastNumTicks
		;		
		
		NumTicks = TmpMS - LastTime
	Until NumTicks > 0
	LastTime = TmpMS
	
	
	;account for when the user alt-tabs :)
	If NumTicks > 20 Then NumTicks = LastNumTicks
	LastNumTicks = NumTicks		
	
	
	;now we do the logic loop
	For i = 0 To NumTicks
		;#################################################################################
		;#  in here is all the game loop's logic, like collisions, movement, etc
		;#################################################################################
		ShipX# = ShipX# + ShipXSpeed#
		If ShipX# < 0 Or ShipX# > 640 Then ShipXSpeed# = 0 - ShipXSpeed#
		ShipY = ShipY + ShipYSpeed
		If ShipY# < 0 Or ShipY# > 480 Then ShipYSpeed# = 0 - ShipYSpeed#
	Next
	
	
	;#################################################################################
	;#  here is where you draw all the graphics
	;#################################################################################
	Cls
	DrawImage(Ship, ShipX#, ShipY#)	
	Flip
Wend