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