FrameRateControl - Module

Share your advanced PureBasic knowledge/code with the community.
User avatar
StarBootics
Addict
Addict
Posts: 1006
Joined: Sun Jul 07, 2013 11:35 am
Location: Canada

FrameRateControl - Module

Post by StarBootics »

Hello everyone,

Another Guimauve's code conversion see here : http://www.purebasic.fr/english/viewtop ... 3&start=15
A FrameRateControl Module.

Best regards
StarBootics

Code: Select all

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Project name : FrameRateControl - Module
; File Name : FrameRateControl - Module.pb
; File version: 1.0.0
; Programming : OK
; Programmed by : StarBootics
; Date : 24-05-2016
; Last Update : 24-05-2016
; PureBasic code : V5.42 LTS
; Platform : Windows, Linux, MacOS X
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; This code was originally created by Guimauve
; to control a loop frame rate.
;
; I deserve credit only to convert the original 
; code into a Module.
;
; This code is free to be use where ever you like 
; but you use it at your own risk.
;
; The author can in no way be held responsible 
; for data loss, damage or other annoying 
; situations that may occur.
;
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

DeclareModule FrameRateControl
  
  Declare.d FpsActual() 
  Declare Initialize(P_Frequency.l)
  Declare StartTimers()
  Declare UpdateTimerFlip()
  Declare SlowDownIfNeeded()
  Declare Reset()
  Declare ReadPrefs(GroupName.s)
  Declare WritePrefs(GroupName.s)
  
EndDeclareModule

Module FrameRateControl
  
  Enumeration
    
    #TIMER_FPS
    #TIMER_FLIP
    #TIMER_MAX
    
  EndEnumeration 
  
  ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  ; <<<<< Déclaration de la Structure <<<<<
  
  Structure FrameRateControl
    
    FpsCounter.l
    FpsActual.d
    Frequency.l
    FrameTime.l
    DelayTime.l
    CurrentTick.l[#TIMER_MAX]
    LastTick.l[#TIMER_MAX]
    ElapsedTick.l[#TIMER_MAX]
    
  EndStructure
  
  Global FrameRateControl.FrameRateControl
  
  Procedure.d FpsActual()
    
    ProcedureReturn FrameRateControl\FpsActual
  EndProcedure
  
  Procedure Initialize(P_Frequency.l)
    
    FrameRateControl\FpsCounter = 0
    FrameRateControl\FpsActual = P_Frequency
    FrameRateControl\Frequency = P_Frequency
    FrameRateControl\FrameTime = 1000/P_Frequency
    FrameRateControl\DelayTime = 0
    
    For TimerID = 0 To #TIMER_MAX - 1
      FrameRateControl\CurrentTick[TimerID] = 0
      FrameRateControl\LastTick[TimerID] = 0
      FrameRateControl\ElapsedTick[TimerID] = 0
    Next
    
  EndProcedure
  
  Procedure StartTimers()

    For TimerID = 0 To #TIMER_MAX - 1
      FrameRateControl\CurrentTick[TimerID] = ElapsedMilliseconds()
      FrameRateControl\LastTick[TimerID] = FrameRateControl\CurrentTick[TimerID]
      FrameRateControl\ElapsedTick[TimerID] = 0
    Next
    
  EndProcedure
  
  Procedure UpdateTimerFlip()
    
    FrameRateControl\CurrentTick[#TIMER_FLIP] = ElapsedMilliseconds()
    FrameRateControl\ElapsedTick[#TIMER_FLIP] = FrameRateControl\CurrentTick[#TIMER_FLIP] - FrameRateControl\LastTick[#TIMER_FLIP]
    FrameRateControl\LastTick[#TIMER_FLIP] = FrameRateControl\CurrentTick[#TIMER_FLIP]
    FrameRateControl\FpsCounter = FrameRateControl\FpsCounter + 1
    
  EndProcedure
  
  Procedure SlowDownIfNeeded()
    
    FrameRateControl\CurrentTick[#TIMER_FPS] = ElapsedMilliseconds()
    FrameRateControl\ElapsedTick[#TIMER_FPS] = FrameRateControl\CurrentTick[#TIMER_FPS] - FrameRateControl\LastTick[#TIMER_FPS]
    
    If FrameRateControl\ElapsedTick[#TIMER_FPS] >= 1000
      
      FrameRateControl\FpsActual = (FrameRateControl\FpsCounter / FrameRateControl\ElapsedTick[#TIMER_FPS]) * 1000
      FrameRateControl\CurrentTick[#TIMER_FPS] = ElapsedMilliseconds()
      FrameRateControl\ElapsedTick[#TIMER_FPS] = FrameRateControl\CurrentTick[#TIMER_FPS] - FrameRateControl\LastTick[#TIMER_FPS]
      FrameRateControl\LastTick[#TIMER_FPS] = FrameRateControl\CurrentTick[#TIMER_FPS]
      FrameRateControl\FpsCounter = 0
      
    EndIf
    
    FrameRateControl\CurrentTick[#TIMER_FLIP] = ElapsedMilliseconds()
    FrameRateControl\ElapsedTick[#TIMER_FLIP] = FrameRateControl\CurrentTick[#TIMER_FLIP] - FrameRateControl\LastTick[#TIMER_FLIP]
    FrameRateControl\DelayTime = FrameRateControl\FrameTime - FrameRateControl\ElapsedTick[#TIMER_FLIP]
    
    If FrameRateControl\DelayTime >= 1
      Delay(FrameRateControl\DelayTime)
    EndIf
    
  EndProcedure
  
  Procedure Reset()
    
    FrameRateControl\FpsCounter = 0
    FrameRateControl\FpsActual = 0.0
    FrameRateControl\Frequency = 0
    FrameRateControl\FrameTime = 0
    FrameRateControl\DelayTime = 0
    
    For TimerID = 0 To #TIMER_MAX - 1
      FrameRateControl\CurrentTick[TimerID] = 0
      FrameRateControl\LastTick[TimerID] = 0
      FrameRateControl\ElapsedTick[TimerID] = 0
    Next
    
  EndProcedure

  Procedure ReadPrefs(GroupName.s)
    
    PreferenceGroup(GroupName)
    
    FrameRateControl\Frequency = ReadPreferenceLong("Frequency", FrameRateControl\Frequency)
    
    If FrameRateControl\Frequency <> 0
      FrameRateControl\FrameTime = 1000 / FrameRateControl\Frequency
    EndIf
    
  EndProcedure
  
  Procedure WritePrefs(GroupName.s)
    
    PreferenceGroup(GroupName)
    
    WritePreferenceLong("Frequency", FrameRateControl\Frequency)
    
  EndProcedure

EndModule

CompilerIf #PB_Compiler_IsMainFile
  
  FrameRateControl::Initialize(59)
  
  FrameRateControl::StartTimers()
  
  Repeat
    
    FrameRateControl::UpdateTimerFlip()
    
    ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    ; <<<<< Début de la section des instructions <<<<<
    ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    
    ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    ; 1. Gestion Évenèments + Clavier, Souris, Joystick
    
    ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    ; 2. Mise à jour de l'espace 3D (Position, Collision)
    
    ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    ; 3. Affichage de l'espace 3D vue par la(les) caméra(s)
    
    ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    ; 4. Affichage des éléments 2D (Messages, menus, etc.) 
    
    Debug StrD(FrameRateControl::FpsActual(), 1) + " FPS"
    
    ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    ; <<<<< Fin de la section des instructions <<<<<
    ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    
    FrameRateControl::SlowDownIfNeeded()
    
    If LoopCount >= 250
      Quit = #True
    Else 
      LoopCount + 1
      Debug LoopCount
    EndIf 
    
  Until Quit = #True
  
  FrameRateControl::Reset()
  
CompilerEndIf

; <<<<<<<<<<<<<<<<<<<<<<<
; <<<<< END OF FILE <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<
The Stone Age did not end due to a shortage of stones !