Smoothing Delta Timing

Miscellaneous Forums/General Discussion/Smoothing Delta Timing

How much does your framerate fluctuate?

I came up with an algorithm not long ago that made the framerate super smooth, but I found that it didn't make the stuff in the game look like it was moving any more smoothly. I couldn't tell the difference at all with a scrolling star background whether it was moving at a rock solid 60fps, or whether it varied by 5fps up and down.

But if you want to try this setup, here's the code:

	Global Time%, Time_Delta%, Time_Delta_Sec#, Last_Time_Delta%, Last_Time_Delta_Sec#
	Global System_Time%, Last_System_Time%
	Global FPS%
	Global State%
	
	Global Frames% = 1
	Global FrameTime%[Frames]
	Global Max_FrameTime%
	Global Frame%
	Global FrameDelay%

					
' Main:

	App.Create("Attack of the Alien Space Beetles!", 800, 600, 0, True, False)

	SeedRnd MilliSecs() 
	System_Time = MilliSecs()
					
	Repeat
	
		Repeat 
			Last_System_Time = System_Time										' Store start time of last frame.
			System_Time 	 = MilliSecs()										' Get the current system time.  
			Time_Delta       = System_Time - Last_System_Time					' Calculate how long last frame took to render, in milliseconds.
			Time_Delta_Sec#  = Float(Time_Delta)/1000.0							' Convert frame time to seconds.
		Until (Time_Delta > 0) And (Time_Delta < 250)							' Handle unnaturally long pauses between frames gracefully.
								
		EventHandler()															' Process window events.
		
		If Not AppSuspended()
									
			Time = Time + Time_Delta											' Calculate current game time.  
						
			If App.Windowed Then ActivateGadget App.Canvas						' If windowed, make sure canvas stays active, or else polled input will go elsewhere.		

			UpdateMouse()														' Get mouse input.
			Gameplay.Update()													' Update game.
			
			Animate.UpdateAll(Time_Delta)										' Animate sprites.

			SetClsColor 0, 0, 0													' Clear screen and draw sprites.
			Cls
			Sprite.DrawAll()				
									
			If KeyHit(KEY_F) Then App.ToggleFullscreen()						' Toggle fullscreen/window mode when user presses F.  (May need to disable this during user input.)
			
			Delay(40)
			
			'Last_Time_Delta      = Time_Delta									' Store timestep for this frame so we can reference it next frame.
			'Last_Time_Delta_Sec# = Time_Delta_Sec#

				
			' Smooth out framerate.
				
				If Not KeyDown(KEY_S)
				
					' Find the longest amount of time a frame took to render over the last few frames.	
								
						Max_FrameTime = 0
						For Frame = 0 To Frames-1
							If FrameTime[Frame] > Max_FrameTime Then Max_FrameTime = FrameTime[Frame]
						Next
					
					' Shift all the elements toward the end of the array by one.	
						For Frame = Frames-1 To 1 Step -1
							FrameTime[Frame] = FrameTime[Frame-1]
						Next					
					
					' Resize the array to have 1/8 as many elements as we are rendering frames per second.
					
					' The reason we do this is so that no matter what the framerate is, the system will adjust to big changes in framerate within 1/8
					' of a second.  The response time is only a concern so far as the system would render at a lower framerate for longer than it
					' really needs to.
					
						If Max_FrameTime > 0 Then Frames = Floor((1000.0 / Max_FrameTime) / 8.0)
						If Frames = 0 Then Frames = 1
										
						FrameTime = FrameTime[..Frames]						
					
					' Calculate how long this frame took to render.
						Time_Delta = MilliSecs()-System_Time
					
					' Add this frame's time to the start of the array.
						FrameTime[0] = Time_Delta
				
					' Delay this frame to make it last as long as the longest frame in our timeframe.
						If Max_FrameTime < 70
							While Time_Delta < Max_FrameTime
								Time_Delta = MilliSecs()-System_Time
							Wend
						EndIf
						
				EndIf

			' Draw framerate if user presses tab.

				If KeyDown(KEY_TAB) 
					
					If Time_Delta > 0 
						FPS = 1000.0 / Float(Time_Delta)
					Else
						FPS = 1000
					EndIf
													
					DrawText FPS, 16, 16										
					DrawText Frames, 16, 32
					
				EndIf
			
			' Flip new frame into view.
				Flip 1
					
		EndIf 
			
	Forever



It might work well if you have really big framerate jumps and low framerates. But it didn't provide any noticeable difference at the super high framerates I am getting in BlitzMax.

Oh and you uh, might want to take that delay out of there. :-)