Code archives/Algorithms/AppTiming module
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
Any time-sensitive routine should be modulated by the application speed. This set of commands will make the task easier. Call UpdateAppTime() once every game loop. You can specify a framerate your application should run at. The default value is 60. Multiply every time-dependent value in your program with the function AppSpeed(). If the program is supposed to run at 60 FPS but it is running at 120, AppSpeed() will return 0.5. AppTime() will return the same value until the next call to UpdateAppTime(). This ensures your entire game loop is always using uniform timing. PauseApp() and ResumeApp() will stop and resume the application without effecting timing. UPS() will return updates per second. The value is calculated once per second and rounded to an integer. This is not a precise measurement, but rather a visual approximation for printing to the screen. Because of the limited resolution of the Millisecs() timer, the application will cap the UPS at 1000. A delay will be called to ensure that errors do not occur. If you use this code, your application will always run at the same speed regardless of framerate. | |||||
Module leadwerks.apptiming Private Global AppTime_UPS Global AppTime_Iterator Global AppTime_CurrentTime Global AppTime_PauseStart=0 Global AppTime_Speed:Float=1.0 Global AppTime_DesiredLoopTime#=1000.0/60.0 Global AppTime_LastUpdateTime=0 Global AppTime_LastUPSTime Public Rem bbdoc: EndRem Function UpdateAppTime(framerate=60) Local time Local elapsed If AppTime_PauseStart Return AppTime_DesiredLoopTime=1000.0/framerate time=MilliSecs() If AppTime_LastUpdateTime=0 AppTime_Speed#=1.0 AppTime_LastUpdateTime=time AppTime_CurrentTime=time AppTime_LastUPSTime=time Else elapsed=time-AppTime_LastUpdateTime If Not elapsed elapsed=1 Delay 1 time:+1 EndIf AppTime_Speed=Float(elapsed)/Float(AppTime_DesiredLoopTime) AppTime_CurrentTime=time AppTime_LastUpdateTime=time EndIf AppTime_Iterator:+1 If AppTime_CurrentTime-AppTime_LastUPSTime>=1000 AppTime_UPS=Float(AppTime_Iterator)/(Float(AppTime_CurrentTime-AppTime_LastUPSTime)/1000.0) AppTime_LastUPSTime=AppTime_CurrentTime AppTime_Iterator=0 EndIf EndFunction Rem bbdoc: EndRem Function AppTime() Return AppTime_CurrentTime EndFunction Rem bbdoc: EndRem Function AppSpeed#() Return AppTime_Speed EndFunction Rem bbdoc: EndRem Function UPS:Int() Return AppTime_UPS EndFunction Rem bbdoc: EndRem Function PauseApp() If AppTime_PauseStart Return AppTime_PauseStart=MilliSecs() EndFunction Rem bbdoc: EndRem Function ResumeApp() If Not AppTime_PauseStart Return If AppTime_LastUpdateTime Local elapsed=MilliSecs()-AppTime_PauseStart AppTime_LastUpdateTime:+elapsed EndIf AppTime_PauseStart=0 EndFunction |
Comments
| ||
Hmm, wouldn't it make more sense if UPS returns 0 if paused and the same for AppSpeed? Currently, it will remain on constant speed while paused even thought the world shouldn't change anymore ... Fixed it would look like this: Module leadwerks.apptiming Private Global AppTime_UPS Global AppTime_Iterator Global AppTime_CurrentTime Global AppTime_PauseStart=0 Global AppTime_Speed:Float=1.0 Global AppTime_DesiredLoopTime#=1000.0/60.0 Global AppTime_LastUpdateTime=0 Global AppTime_LastUPSTime Global AppTime_DesiredFrequency% 'mainly to avoid float rounding errors Public Rem bbdoc: EndRem Function UpdateAppTime(framerate=60) Local time Local elapsed If AppTime_PauseStart Return AppTime_DesiredFrequency = framerate AppTime_DesiredLoopTime=1000.0/framerate time=MilliSecs() If AppTime_LastUpdateTime=0 AppTime_Speed#=1.0 AppTime_LastUpdateTime=time AppTime_CurrentTime=time AppTime_LastUPSTime=time Else elapsed=time-AppTime_LastUpdateTime If Not elapsed elapsed=1 Delay 1 time:+1 EndIf AppTime_Speed=Float(elapsed)/Float(AppTime_DesiredLoopTime) AppTime_CurrentTime=time AppTime_LastUpdateTime=time EndIf AppTime_Iterator:+1 If AppTime_CurrentTime-AppTime_LastUPSTime>=1000 AppTime_UPS=Float(AppTime_Iterator)/(Float(AppTime_CurrentTime-AppTime_LastUPSTime)/1000.0) AppTime_LastUPSTime=AppTime_CurrentTime AppTime_Iterator=0 EndIf EndFunction Rem bbdoc: EndRem Function AppTime() Return AppTime_CurrentTime EndFunction Rem bbdoc: EndRem Function AppSpeed#() Return AppTime_Speed EndFunction Rem bbdoc: EndRem Function UPS:Int() Return AppTime_UPS EndFunction Rem bbdoc: EndRem Function PauseApp() If AppTime_PauseStart Return AppTime_PauseStart=MilliSecs() AppTime_UPS = 0 AppTime_Speed = 0 EndFunction Rem bbdoc: EndRem Function ResumeApp() If Not AppTime_PauseStart Return If AppTime_LastUpdateTime Local elapsed=MilliSecs()-AppTime_PauseStart AppTime_LastUpdateTime:+elapsed EndIf AppTime_PauseStart=0 UpdateAppTime( AppTime_DesiredFrequency ) EndFunction |
| ||
thanks leadwerks and dreamora, we need a standard (and easy) way to fix framerate |
| ||
If the user is calling AppSpeed() and UPS() while the application is paused they are doing something wrong. Pause and resume are for menus or GUI applications, where you stop the game loop and do some other unrelated stuff. |
Code Archives Forum