TITANIC: Add movie _handled flag, simplify frame timinig code

This commit is contained in:
Paul Gilbert 2016-07-20 07:38:13 -04:00
parent 53c7517dfb
commit d5bf17e73f
5 changed files with 27 additions and 37 deletions

View File

@ -192,14 +192,20 @@ void CGameManager::update() {
}
void CGameManager::updateMovies() {
// Initial iteration to mark all the movies as not yet handled
for (CMovieList::iterator i = CMovie::_playingMovies->begin();
i != CMovie::_playingMovies->end(); ++i)
(*i)->_handled = false;
bool repeatFlag;
do {
repeatFlag = false;
// Scan for a movie to process
for (CMovieList::iterator i = CMovie::_playingMovies->begin();
i != CMovie::_playingMovies->end(); ) {
i != CMovie::_playingMovies->end(); ++i) {
CMovie *movie = *i;
if (movie->_state)
if (movie->_handled)
continue;
CMovieEventList eventsList;
@ -229,8 +235,9 @@ void CGameManager::updateMovies() {
eventsList.remove(movieEvent);
}
// Flag the movie as having been handled
movie->_handled = true;
repeatFlag = true;
movie->_state = MSTATE_1;
break;
}
} while (repeatFlag);

View File

@ -260,10 +260,13 @@ int AVISurface::getFrame() const {
return _decoders[0]->getCurFrame();
}
bool AVISurface::isFrameReady() const {
return _decoders[0]->needsUpdate() && (!_decoders[1] || _decoders[1]->needsUpdate());
}
bool AVISurface::renderFrame() {
// Check there's a frame ready for display
assert(_videoSurface);
if (!_decoders[0]->needsUpdate() || (_decoders[1] && !_decoders[1]->needsUpdate()))
if (!isFrameReady())
return false;
// Decode each decoder's video stream into the appropriate surface

View File

@ -162,6 +162,11 @@ public:
* Duplicates the secondary frame, if the movie has a second video track
*/
Graphics::ManagedSurface *duplicateSecondaryFrame() const;
/**
* Returns true if a frame is ready to be rendered
*/
bool isFrameReady() const;
};
} // End of namespace Titanic

View File

@ -36,7 +36,7 @@ namespace Titanic {
CMovieList *CMovie::_playingMovies;
CVideoSurface *CMovie::_movieSurface;
CMovie::CMovie() : ListItem(), _state(MSTATE_0), _field10(0),
CMovie::CMovie() : ListItem(), _handled(false), _field10(0),
_field14(0) {
}
@ -84,9 +84,6 @@ OSMovie::OSMovie(const CResourceKey &name, CVideoSurface *surface) :
_field24 = 0;
_field28 = 0;
_field2C = 0;
_ticksStart = 0;
_frameTime1 = 0;
_frameTime2 = 17066;
surface->resize(_aviSurface.getWidth(), _aviSurface.getHeight());
_aviSurface.setVideoSurface(surface);
@ -165,25 +162,13 @@ void OSMovie::setFrame(uint frameNumber) {
bool OSMovie::handleEvents(CMovieEventList &events) {
if (!_aviSurface._isPlaying)
return false;
int time = (g_vm->_events->getTicksCount() + ((_ticksStart << 24) - _ticksStart)) << 8;
if (time < _frameTime1)
if (!_aviSurface.isFrameReady())
return _aviSurface._isPlaying;
if (!_field14 && (time - _frameTime1) > (_frameTime2 * 2))
_frameTime1 = time;
_frameTime1 += _frameTime2;
_aviSurface.handleEvents(events);
_videoSurface->setMovieFrameSurface(_aviSurface.getSecondarySurface());
if (_field14) {
while (_frameTime1 >= time && events.empty()) {
_aviSurface.handleEvents(events);
_videoSurface->setMovieFrameSurface(_aviSurface.getSecondarySurface());
_frameTime1 += _frameTime2;
}
// Handle updating the frame
while (_aviSurface.isFrameReady()) {
_aviSurface.handleEvents(events);
_videoSurface->setMovieFrameSurface(_aviSurface.getSecondarySurface());
}
return _aviSurface._isPlaying;
@ -202,9 +187,6 @@ int OSMovie::getFrame() const {
}
void OSMovie::movieStarted() {
_frameTime1 = _frameTime2 = 256000.0 / _aviSurface._frameRate;
_ticksStart = g_vm->_events->getTicksCount();
if (_aviSurface._hasAudio)
_aviSurface._soundManager->movieStarted();

View File

@ -32,10 +32,6 @@
namespace Titanic {
enum MovieState {
MSTATE_0 = 0, MSTATE_1 = 1
};
class CGameObject;
class CMovie;
class CSoundManager;
@ -52,7 +48,7 @@ protected:
*/
void addToPlayingMovies();
public:
MovieState _state;
bool _handled;
int _field10;
int _field14;
public:
@ -158,9 +154,6 @@ private:
int _field24;
int _field28;
int _field2C;
int _ticksStart;
int _frameTime1;
int _frameTime2;
private:
/**
* Called when a movie is started playing