blob: f8ae91c4b41a095d16f1968a68c76246b92dcfb3 (
plain) (
tree)
|
|
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.
|