aboutsummaryrefslogblamecommitdiffstats
path: root/src/classes/UTime.pas
blob: f8ae91c4b41a095d16f1968a68c76246b92dcfb3 (plain) (tree)
1
2
3
4
5
6
7
8
9



           


                
 
                 
 

               









                                                                                             
                           
          
                                                       


                               


                                                             




                           

   
                      

                               




                      



              
      
          


                             
 
  

                                                                           
 


                                                                                      


  

                           
                                



                        


                                                         

    
                       
     

                                                               

    









                         
                             
     
                                                 

    



                 







                                                                                
     


                                  














                                  



                                                                              

                                      







                                                             





                                                                                         














                                                                           

                             

                                        

    











                                                                                   
 
    
unit UTime;

interface

{$IFDEF FPC}
  {$MODE Delphi}
{$ENDIF}

{$I switches.inc}

type
  TTime = class
    public
      constructor Create;
      function GetTime(): real;
  end;

  TRelativeTimer = class
    private
      AbsoluteTime: int64;      // system-clock reference time for calculation of CurrentTime
      RelativeTimeOffset: real;
      Paused: boolean;
      TriggerMode: boolean;
    public
      constructor Create(TriggerMode: boolean = false);
      procedure Pause();
      procedure Resume();
      function GetTime(): real;
      function GetAndResetTime(): real;
      procedure SetTime(Time: real; Trigger: boolean = true);
      procedure Reset();
  end;

procedure CountSkipTimeSet;
procedure CountSkipTime;
procedure CountMidTime;

var
  USTime      : TTime;
  VideoBGTimer: TRelativeTimer;

  TimeNew     : int64;
  TimeOld     : int64;
  TimeSkip    : real;
  TimeMid     : real;
  TimeMidTemp : int64;

implementation

uses
  sdl,
  ucommon;
  
const
  cSDLCorrectionRatio = 1000;

(*
BEST Option now ( after discussion with whiteshark ) seems to be to use SDL
timer functions...

SDL_delay
SDL_GetTicks
http://www.gamedev.net/community/forums/topic.asp?topic_id=466145&whichpage=1%EE%8D%B7
*)


procedure CountSkipTimeSet;
begin
  TimeNew     := SDL_GetTicks();
end;

procedure CountSkipTime;
begin
  TimeOld     := TimeNew;
  TimeNew     := SDL_GetTicks();
  TimeSkip    := (TimeNew-TimeOld) / cSDLCorrectionRatio;
end;

procedure CountMidTime;
begin
  TimeMidTemp := SDL_GetTicks();
  TimeMid     := (TimeMidTemp - TimeNew) / cSDLCorrectionRatio;
end;

{**
 * TTime
 **}

constructor TTime.Create;
begin
  inherited;
  CountSkipTimeSet;
end;

function TTime.GetTime: real;
begin
  Result := SDL_GetTicks() / cSDLCorrectionRatio;
end;

{**
 * TRelativeTimer
 **}

(*
 * Creates a new timer.
 * If TriggerMode is false (default), the timer
 * will immediately begin with counting.
 * If TriggerMode is true, it will wait until Get/SetTime() or Pause() is called
 * for the first time.
 *)
constructor TRelativeTimer.Create(TriggerMode: boolean);
begin
  inherited Create();
  Self.TriggerMode := TriggerMode;
  Reset();
  Paused := false;
end;

procedure TRelativeTimer.Pause();
begin
  RelativeTimeOffset := GetTime();
  Paused := true;
end;

procedure TRelativeTimer.Resume();
begin
  AbsoluteTime := SDL_GetTicks();
  Paused := false;
end;

(*
 * Returns the counter of the timer.
 * If in TriggerMode it will return 0 and start the counter on the first call.
 *)
function TRelativeTimer.GetTime: real;
begin
  // initialize absolute time on first call in triggered mode
  if (TriggerMode and (AbsoluteTime = 0)) then
  begin
    AbsoluteTime := SDL_GetTicks();
    Result := RelativeTimeOffset;
    Exit;
  end;

  if Paused then
    Result := RelativeTimeOffset
  else
    Result := RelativeTimeOffset + (SDL_GetTicks() - AbsoluteTime) / cSDLCorrectionRatio;
end;

(*
 * Returns the counter of the timer and resets the counter to 0 afterwards.
 * Note: In TriggerMode the counter will not be stopped as with Reset().
 *)
function TRelativeTimer.GetAndResetTime(): real;
begin
  Result := GetTime();
  SetTime(0);
end;

(*
 * Sets the timer to the given time. This will trigger in TriggerMode if
 * Trigger is set to true. Otherwise the counter's state will not change.
 *)
procedure TRelativeTimer.SetTime(Time: real; Trigger: boolean);
begin
  RelativeTimeOffset := Time;
  if ((not TriggerMode) or Trigger) then
    AbsoluteTime := SDL_GetTicks();
end;

(*
 * Resets the counter of the timer to 0.
 * If in TriggerMode the timer will not start counting until it is triggered again.
 *)
procedure TRelativeTimer.Reset();
begin
  RelativeTimeOffset := 0;
  if (TriggerMode) then
    AbsoluteTime := 0
  else
    AbsoluteTime := SDL_GetTicks();
end;

end.