aboutsummaryrefslogblamecommitdiffstats
path: root/src/base/UTime.pas
blob: 83844cb5c706a6a9dc9541b736ddfc675f92f2e1 (plain) (tree)
























                                                                        



           


                
 
                 
 

               









                                                                                             
                           
          
                                                       


                               


                                                             




                           

   
                      

                               




                     



              
      
          


                             
 
  

                                                                           
 


                                                                                      


  

                           
                            



                        


                                                      

    
                       
     

                                                               

    









                         
                             
     
                                                 

    



                 
  

                                               
                                        
                                                                                


                                                        
     


                                  














                                  



                                                                              

                                      







                                                             





                                                                                         














                                                                           

                             

                                        

    











                                                                                   
 
    
{* UltraStar Deluxe - Karaoke Game
 *
 * UltraStar Deluxe is the legal property of its developers, whose names
 * are too numerous to list here. Please refer to the COPYRIGHT
 * file distributed with this source distribution.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; see the file COPYING. If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 *
 * $URL$
 * $Id$
 *}

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.