diff options
Diffstat (limited to 'engines/titanic/support/avi_surface.cpp')
-rw-r--r-- | engines/titanic/support/avi_surface.cpp | 33 |
1 files changed, 27 insertions, 6 deletions
diff --git a/engines/titanic/support/avi_surface.cpp b/engines/titanic/support/avi_surface.cpp index 07458812b9..525c6513dd 100644 --- a/engines/titanic/support/avi_surface.cpp +++ b/engines/titanic/support/avi_surface.cpp @@ -41,6 +41,7 @@ AVISurface::AVISurface(const CResourceKey &key) { _streamCount = 0; _movieFrameSurface[0] = _movieFrameSurface[1] = nullptr; _framePixels = nullptr; + _priorFrameTime = 0; // Reset current frame. We need to keep track of frames separately from the decoder, // since it needs to be able to go beyond the frame count or to negative to allow @@ -164,8 +165,8 @@ bool AVISurface::handleEvents(CMovieEventList &events) { _currentFrame += _isReversed ? -1 : 1; int newFrame = _currentFrame; - if ((info->_isReversed && newFrame <= info->_endFrame) || - (!info->_isReversed && newFrame >= info->_endFrame)) { + if ((info->_isReversed && newFrame < info->_endFrame) || + (!info->_isReversed && newFrame > info->_endFrame)) { if (info->_isRepeat) { newFrame = info->_startFrame; } else { @@ -180,6 +181,7 @@ bool AVISurface::handleEvents(CMovieEventList &events) { // Not empty, so move onto new first one info = _movieRangeInfo.front(); newFrame = info->_startFrame; + setReversed(info->_isReversed); } } } @@ -286,8 +288,20 @@ void AVISurface::setFrame(int frameNumber) { renderFrame(); } -bool AVISurface::isNextFrame() const { - return _decoder->getTimeToNextFrame() == 0; +bool AVISurface::isNextFrame() { + if (!_decoder->endOfVideo()) + return _decoder->getTimeToNextFrame() == 0; + + // We're at the end of the video, so we need to manually + // keep track of frame delays. Hardcoded at the moment for 15FPS + const uint FRAME_TIME = 1000 / 15; + uint32 currTime = g_system->getMillis(); + if (currTime >= (_priorFrameTime + FRAME_TIME)) { + _priorFrameTime = currTime; + return true; + } + + return false; } bool AVISurface::renderFrame() { @@ -347,7 +361,12 @@ bool AVISurface::addEvent(int frameNumber, CGameObject *obj) { } void AVISurface::setFrameRate(double rate) { - _decoder->setRate(Common::Rational((int)rate)); + // Convert rate from fps to relative to 1.0 (normal speed) + const int PRECISION = 10000; + double playRate = rate / 15.0; // Standard 15 FPS + Common::Rational pRate(playRate * PRECISION, PRECISION); + + _decoder->setRate(pRate); } Graphics::ManagedSurface *AVISurface::getSecondarySurface() { @@ -370,10 +389,12 @@ void AVISurface::playCutscene(const Rect &r, uint startFrame, uint endFrame) { _movieFrameSurface[0]->h != r.height(); startAtFrame(startFrame); + _currentFrame = startFrame; + while (_currentFrame < (int)endFrame && !g_vm->shouldQuit()) { if (isNextFrame()) { renderFrame(); - _currentFrame = _decoder->getCurFrame(); + ++_currentFrame; if (isDifferent) { // Clear the destination area, and use the transBlitFrom method, |