GetRealisticFPS()
Posted: Sun Oct 11, 2009 6:06 am
Wasn't sure what to call this, GetRealisticFPS() was the only thing I could think of,
found this source kicking around and decided to share it, it probably could be optimized some so have at it if anyone feel like it.
Public Domain.
found this source kicking around and decided to share it, it probably could be optimized some so have at it if anyone feel like it.
Public Domain.
Code: Select all
;If you use timeBeginPeriod_(ms) and timeEndPeriod_(ms)
;you can achieve a pretty stable framerate.
;But at a cost of system overhead as all timers that rely on the system timer resolution
;is also affected, due to this MicroSoft changed latest Windows Media Player to use 5ms system timer resolution.
;In my own tests I also found 5m to give the least timer flutter when
;using timeGetTime_() and Delay() or Sleep_()
;The following simple code lets you list "usable" resolutions vs framerates (Press F5 to compile with debugger).
;Or (Press Shift+F5 to compile without debugger) enter your preferred framerate and get a realistic framerate in return.
;Realistic framerates are those that either can be represented directly i milliseconds,
;or are a multiple of your desired framerate in some way (frame doubling and frame halving)
;which should make your graphics timings and calculations a lot easier.
;GetRealisticFPS() tries to return an exact match, or the nearest (up or down) match to your desired FPS,
;if it fails it will return 0 fps, meaning you either input an invalid FPS or you need to use dynamic framerate (FPS throttling) instead.
;Public Domain
EnableExplicit
Procedure.l GetRealisticFPS(fps.l)
Protected result.l,min.l,max.l,f.l,x.l
If (fps>=1) And (fps<=1000)
If Not (1000%fps)
result=fps
Else
f=fps
Repeat
If Not (f%2)
x=f/2
If Not (1000%x)
min=x
Else
f=x
EndIf
Else
f=0
EndIf
Until min Or (f<1)
f=fps
Repeat
x=f*2
If Not (1000%x)
max=x
Else
f=x
EndIf
Until max Or (f>1000)
If max And min
If (max-fps)<(fps-min)
result=max
Else
result=min
EndIf
ElseIf min Or max
If max
result=max
ElseIf min
result=min
EndIf
Else
For f=fps To 1 Step -1
If Not (1000%f)
min=f
EndIf
Next
For f=fps To 1000
If Not (1000%f)
max=f
EndIf
Next
EndIf
EndIf
EndIf
ProcedureReturn result
EndProcedure
Define desiredfps.l,realisticfps.l,text$
CompilerIf #PB_Compiler_Debugger
Define i.i
For i=0 To 1001
realisticfps=GetRealisticFPS(i)
If realisticfps
Debug Str(i)+" = "+Str(realisticfps)
EndIf
Next
CompilerElse
desiredfps=Val(InputRequester("FPS Timing Calculator","Enter desired FPS",""))
If desiredfps
realisticfps=GetRealisticFPS(desiredfps)
If Not realisticfps
text$=Str(desiredfps)+" FPS is not achievable without dynamic timings."
ElseIf desiredfps<>realisticfps
text$=Str(desiredfps)+" FPS is achievable by frame "
If desiredfps<realisticfps
text$+"doubling"
Else
text$+"halving"
EndIf
text$+"."+#LF$+#LF$
text$+"A timing of "+Str(1000/realisticfps)+" ms is needed to get "+Str(realisticfps)+" FPS."+#LF$+#LF$
text$+"Use a divisor of "+Str(desiredfps/realisticfps)+" or multiply by "+StrF(realisticfps/desiredfps)+" and"+#LF$
text$+"a multiplicator of "+Str(desiredfps/realisticfps)+" or "+StrF(desiredfps/realisticfps)+" to"+#LF$
text$+"to calculate from/to the actual framerate."
Else
text$=Str(desiredfps)+" FPS is realistic and simply needs a timing resolution of "+Str(1000/desiredfps)+" ms."
EndIf
MessageRequester("Realistic FPS",text$)
EndIf
CompilerEndIf