aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorMatthew Hoops2011-09-17 21:16:52 -0400
committerMatthew Hoops2011-09-18 15:36:05 -0400
commit1390db1df12a8a853deca62df2e11a899c111fcf (patch)
tree7679e3f78dc7ac8e3a0126c915a613961a267804 /engines
parente90287f7f1063e9784239c5be558b7fb6cd3aa54 (diff)
downloadscummvm-rg350-1390db1df12a8a853deca62df2e11a899c111fcf.tar.gz
scummvm-rg350-1390db1df12a8a853deca62df2e11a899c111fcf.tar.bz2
scummvm-rg350-1390db1df12a8a853deca62df2e11a899c111fcf.zip
PEGASUS: Rewrite TimeBase to be a bit more accurate with timing
Diffstat (limited to 'engines')
-rwxr-xr-xengines/pegasus/timers.cpp92
-rwxr-xr-xengines/pegasus/timers.h5
2 files changed, 55 insertions, 42 deletions
diff --git a/engines/pegasus/timers.cpp b/engines/pegasus/timers.cpp
index 03e7a64784..1699867314 100755
--- a/engines/pegasus/timers.cpp
+++ b/engines/pegasus/timers.cpp
@@ -56,6 +56,16 @@ TimeBase::TimeBase(const TimeScale preferredScale) {
_callBackList = 0;
_paused = false;
_flags = 0;
+ _lastMillis = 0;
+ _time = 0;
+ _rate = 0;
+ _startTime = 0;
+ _startScale = 1;
+ _stopTime = 0xffffffff;
+ _stopScale = 1;
+ _master = 0;
+ _pausedRate = 0;
+
((PegasusEngine *)g_engine)->addTimeBase(this);
}
@@ -70,39 +80,18 @@ TimeBase::~TimeBase() {
}
void TimeBase::setTime(const TimeValue time, const TimeScale scale) {
- // So, we're saying the *current* time from g_system->getMillis() is
- // what time/scale is. Which means we need to subtract time/scale from
- // the offset so that g_system->getMillis() - _currentOffset is
- // equal to time/scale.
- _timeOffset = g_system->getMillis() - time * 1000 / ((scale == 0) ? _preferredScale : scale);
-
- // TODO: Also adjust the slaves' offsets (once we're actually using the
- // masters for calculating time)
+ _time = Common::Rational(time, (scale == 0) ? _preferredScale : scale);
}
TimeValue TimeBase::getTime(const TimeScale scale) {
- if (_paused)
- return _pausedTime;
-
- Common::Rational normalTime = Common::Rational((g_system->getMillis() - _timeOffset) * ((scale == 0) ? _preferredScale : scale), 1000);
-
- // Adjust it according to our rate
- return (normalTime * getEffectiveRate()).toInt();
+ return _time.getNumerator() * ((scale == 0) ? _preferredScale : scale) / _time.getDenominator();
}
void TimeBase::setRate(const Common::Rational rate) {
- if (rate == 0) {
- _paused = false;
- _timeOffset = 0;
- } else if (_timeOffset != 0) {
- // Convert the time from the old rate to the new rate
- _timeOffset = g_system->getMillis() - (rate * (g_system->getMillis() - _timeOffset) / _rate).toInt();
- } else {
- // TODO: Check this
- setTime(_startTime, _startScale);
- }
-
_rate = rate;
+
+ if (_rate == 0)
+ _paused = false;
}
Common::Rational TimeBase::getEffectiveRate() const {
@@ -125,7 +114,6 @@ void TimeBase::pause() {
if (isRunning() && !_paused) {
_pausedRate = getRate();
stop();
- _pausedTime = getTime();
_paused = true;
}
}
@@ -150,9 +138,9 @@ bool TimeBase::isRunning() {
return true;
if (rate > 0)
- return getTime() < getStop();
+ return getTime() != getStop();
- return getTime() > getStart();
+ return getTime() != getStart();
}
void TimeBase::setStart(const TimeValue startTime, const TimeScale scale) {
@@ -208,31 +196,55 @@ void TimeBase::setMasterTimeBase(TimeBase *tb) {
}
void TimeBase::checkCallBacks() {
- uint32 time = getTime();
- uint32 startTime = getStart();
- uint32 stopTime = getStop();
+ // Nothing to do if we're paused or not running
+ if (_paused || !isRunning())
+ return;
+
+ Common::Rational startTime = Common::Rational(_startTime, _startScale);
+ Common::Rational stopTime = Common::Rational(_stopTime, _stopScale);
+
+ // First step: update the times
+ if (_lastMillis == 0) {
+ _lastMillis = g_system->getMillis();
+ } else {
+ uint32 curTime = g_system->getMillis();
+ if (_lastMillis == curTime) // No change
+ return;
+
+ _time += Common::Rational(curTime - _lastMillis, 1000) * getEffectiveRate();
+ _lastMillis = curTime;
+
+ // Clip time to the boundaries
+ if (_time >= stopTime)
+ _time = stopTime;
+ else if (_time <= startTime)
+ _time = startTime;
+ }
+
+ // TODO: Update the slaves?
+ // Check if we've triggered any callbacks
for (TimeBaseCallBack *runner = _callBackList; runner != 0; runner = runner->_nextCallBack) {
if (runner->_type == kCallBackAtTime && runner->_trigger == kTriggerTimeFwd) {
- if (time >= (runner->_param2 * _preferredScale / runner->_param3) && getRate() > 0)
+ if (_time >= (runner->_param2 * _preferredScale / runner->_param3) && getRate() > 0)
runner->callBack();
} else if (runner->_type == kCallBackAtExtremes) {
if (runner->_trigger == kTriggerAtStop) {
- if (time >= stopTime)
+ if (_time == stopTime)
runner->callBack();
} else if (runner->_trigger == kTriggerAtStart) {
- if (time <= startTime)
+ if (_time == startTime)
runner->callBack();
}
}
}
+ // Loop if necessary
if (getFlags() & kLoopTimeBase) {
- // Loop
- if (time >= startTime)
- setTime(stopTime);
- else if (time <= stopTime)
- setTime(startTime);
+ if (_time == startTime)
+ _time = stopTime;
+ else if (_time == stopTime)
+ _time = startTime;
}
}
diff --git a/engines/pegasus/timers.h b/engines/pegasus/timers.h
index 55c2ba0ca0..04dd235dae 100755
--- a/engines/pegasus/timers.h
+++ b/engines/pegasus/timers.h
@@ -115,9 +115,10 @@ protected:
bool _paused;
uint32 _startTime, _startScale;
uint32 _stopTime, _stopScale;
- int32 _timeOffset;
uint32 _flags;
- TimeValue _pausedTime;
+
+ Common::Rational _time;
+ uint32 _lastMillis;
private:
Common::Rational getEffectiveRate() const;