aboutsummaryrefslogtreecommitdiffstats
path: root/src/Classes/UTime.pas
diff options
context:
space:
mode:
Diffstat (limited to 'src/Classes/UTime.pas')
-rw-r--r--src/Classes/UTime.pas185
1 files changed, 185 insertions, 0 deletions
diff --git a/src/Classes/UTime.pas b/src/Classes/UTime.pas
new file mode 100644
index 00000000..f8ae91c4
--- /dev/null
+++ b/src/Classes/UTime.pas
@@ -0,0 +1,185 @@
+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.