Smoothing Delta Timing

Miscellaneous Forums/General Discussion/Smoothing Delta Timing

The forum is locked. These are the original blitzbasic.com forums, kept so they can still be read. No new topics, replies or edits can be made here. To join in, head over to the Blitz3D+ forums.

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. :-)