aboutsummaryrefslogtreecommitdiff
path: root/engines/titanic/support
diff options
context:
space:
mode:
authorPaul Gilbert2016-07-23 14:39:07 -0400
committerPaul Gilbert2016-07-23 14:39:07 -0400
commit00c568e17572ce2ac4e9c97c21c00a734951ae9a (patch)
tree7bf97a5ba8758bd96a6f5ebca270952855d78468 /engines/titanic/support
parent9e02409ef4ece6b3184c1d745106e87f3169e6ca (diff)
downloadscummvm-rg350-00c568e17572ce2ac4e9c97c21c00a734951ae9a.tar.gz
scummvm-rg350-00c568e17572ce2ac4e9c97c21c00a734951ae9a.tar.bz2
scummvm-rg350-00c568e17572ce2ac4e9c97c21c00a734951ae9a.zip
TITANIC: Fix for movie play ranges that end at the AVI file end
Diffstat (limited to 'engines/titanic/support')
-rw-r--r--engines/titanic/support/avi_surface.cpp46
-rw-r--r--engines/titanic/support/avi_surface.h8
-rw-r--r--engines/titanic/support/movie.cpp4
3 files changed, 33 insertions, 25 deletions
diff --git a/engines/titanic/support/avi_surface.cpp b/engines/titanic/support/avi_surface.cpp
index c3a720154a..6507c8bbd4 100644
--- a/engines/titanic/support/avi_surface.cpp
+++ b/engines/titanic/support/avi_surface.cpp
@@ -57,6 +57,12 @@ AVISurface::AVISurface(const CResourceKey &key) {
_streamCount = 0;
_movieFrameSurface[0] = _movieFrameSurface[1] = nullptr;
+ // Reset current frame. We need to keep track of frames separately from the decoders,
+ // since it needs to be able to go beyond the frame count or to negative to allow
+ // correct detection of when range playbacks have finished
+ _currentFrame = -1;
+ _isReversed = false;
+
// Create a decoder for the audio (if any) and primary video track
_decoders[0] = new AVIDecoder(Audio::Mixer::kPlainSoundType, primaryTrackSelect);
if (!_decoders[0]->loadFile(key.getString()))
@@ -103,6 +109,7 @@ bool AVISurface::play(int startFrame, int endFrame, int initialFrame, uint flags
info->_startFrame = startFrame;
info->_endFrame = endFrame;
info->_isReversed = endFrame < startFrame;
+ info->_initialFrame = 0;
info->_isRepeat = flags & MOVIE_REPEAT;
if (obj) {
@@ -161,6 +168,8 @@ void AVISurface::seekToFrame(uint frameNumber) {
_decoders[0]->seekToFrame(frameNumber);
if (_decoders[1])
_decoders[1]->seekToFrame(frameNumber);
+
+ _currentFrame = (int)frameNumber;
}
renderFrame();
@@ -170,6 +179,8 @@ void AVISurface::setReversed(bool isReversed) {
_decoders[0]->setReverse(isReversed);
if (_decoders[1])
_decoders[1]->setReverse(isReversed);
+
+ _isReversed = isReversed;
}
bool AVISurface::handleEvents(CMovieEventList &events) {
@@ -177,12 +188,13 @@ bool AVISurface::handleEvents(CMovieEventList &events) {
return true;
CMovieRangeInfo *info = _movieRangeInfo.front();
- int currentPos = getFrame();
+ _currentFrame += _isReversed ? -1 : 1;
- if ((info->_isReversed && currentPos < info->_endFrame) ||
- (!info->_isReversed && currentPos > info->_endFrame)) {
+ int newFrame = _currentFrame;
+ if ((info->_isReversed && newFrame <= info->_endFrame) ||
+ (!info->_isReversed && newFrame >= info->_endFrame)) {
if (info->_isRepeat) {
- currentPos = info->_startFrame;
+ newFrame = info->_startFrame;
} else {
info->getMovieEnd(events);
_movieRangeInfo.remove(info);
@@ -194,20 +206,20 @@ bool AVISurface::handleEvents(CMovieEventList &events) {
} else {
// Not empty, so move onto new first one
info = _movieRangeInfo.front();
- currentPos = info->_startFrame;
+ newFrame = info->_startFrame;
}
}
}
if (isPlaying()) {
- if (currentPos != getFrame()) {
+ if (newFrame != getFrame()) {
// The frame has been changed, so move to new position
setReversed(info->_isReversed);
- seekToFrame(currentPos);
+ seekToFrame(newFrame);
}
// Get any events for the given position
- info->getMovieFrame(events, currentPos);
+ info->getMovieFrame(events, newFrame);
return renderFrame();
} else {
return false;
@@ -272,18 +284,13 @@ void AVISurface::setFrame(int frameNumber) {
renderFrame();
}
-int AVISurface::getFrame() const {
- return _decoders[0]->getCurFrame();
-}
-
-bool AVISurface::isFrameReady() const {
- return _decoders[0]->needsUpdate() &&
- (!_decoders[1] || _decoders[1]->needsUpdate());
+bool AVISurface::isNextFrame() const {
+ return _decoders[0]->getTimeToNextFrame() == 0;
}
bool AVISurface::renderFrame() {
// Check there's a frame ready for display
- if (!isFrameReady())
+ if (!_decoders[0]->needsUpdate())
return false;
// Decode each decoder's video stream into the appropriate surface
@@ -331,10 +338,9 @@ bool AVISurface::addEvent(int frameNumber, CGameObject *obj) {
}
void AVISurface::setFrameRate(double rate) {
- if (rate >= 0.0 && rate <= 100.0) {
- _frameRate = rate;
- warning("TODO: Frame rate set to %d yet to be implemented", (int)rate);
- }
+ _decoders[0]->setRate(Common::Rational(rate));
+ if (_decoders[1])
+ _decoders[1]->setRate(Common::Rational(rate));
}
Graphics::ManagedSurface *AVISurface::getSecondarySurface() {
diff --git a/engines/titanic/support/avi_surface.h b/engines/titanic/support/avi_surface.h
index 77186edeb4..53e2aae6fc 100644
--- a/engines/titanic/support/avi_surface.h
+++ b/engines/titanic/support/avi_surface.h
@@ -55,6 +55,8 @@ private:
CMovieRangeInfoList _movieRangeInfo;
int _streamCount;
Graphics::ManagedSurface *_movieFrameSurface[2];
+ bool _isReversed;
+ int _currentFrame;
private:
/**
* Render a frame to the video surface
@@ -141,7 +143,7 @@ public:
/**
* Gets the current frame
*/
- int getFrame() const;
+ int getFrame() const { return _currentFrame; }
/**
* Add a movie event
@@ -171,9 +173,9 @@ public:
Graphics::ManagedSurface *duplicateSecondaryFrame() const;
/**
- * Returns true if a frame is ready to be rendered
+ * Returns true if it's time for the next
*/
- bool isFrameReady() const;
+ bool isNextFrame() const;
};
} // End of namespace Titanic
diff --git a/engines/titanic/support/movie.cpp b/engines/titanic/support/movie.cpp
index eba878e875..3c935e83a8 100644
--- a/engines/titanic/support/movie.cpp
+++ b/engines/titanic/support/movie.cpp
@@ -171,11 +171,11 @@ void OSMovie::setFrame(uint frameNumber) {
bool OSMovie::handleEvents(CMovieEventList &events) {
if (!_aviSurface.isPlaying())
return false;
- if (!_aviSurface.isFrameReady())
+ if (!_aviSurface.isNextFrame())
return _aviSurface.isPlaying();
// Handle updating the frame
- while (_aviSurface.isPlaying() && _aviSurface.isFrameReady()) {
+ while (_aviSurface.isPlaying() && _aviSurface.isNextFrame()) {
_aviSurface.handleEvents(events);
_videoSurface->setMovieFrameSurface(_aviSurface.getSecondarySurface());
}