aboutsummaryrefslogtreecommitdiff
path: root/engines/titanic/support/avi_surface.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/titanic/support/avi_surface.cpp')
-rw-r--r--engines/titanic/support/avi_surface.cpp33
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,