diff options
author | Sven Hesse | 2011-01-19 18:57:43 +0000 |
---|---|---|
committer | Sven Hesse | 2011-01-19 18:57:43 +0000 |
commit | bad7f1ce9a67e71eaaa390ac56ae5a3720c3fb7a (patch) | |
tree | 49de1da704aa8cfc8f65f4e551e7b7ec66e44b33 /engines | |
parent | 878bedf454a8440b3d3c8887bc021a698dbb5605 (diff) | |
download | scummvm-rg350-bad7f1ce9a67e71eaaa390ac56ae5a3720c3fb7a.tar.gz scummvm-rg350-bad7f1ce9a67e71eaaa390ac56ae5a3720c3fb7a.tar.bz2 scummvm-rg350-bad7f1ce9a67e71eaaa390ac56ae5a3720c3fb7a.zip |
GOB: Implement "live" (non-blocking) videos
Many thanks to SylvainTV. :)
Urban Runner might actually be completeable now.
One caveat: Hotspots at that hotel sequence are a bit glitchy...
svn-id: r55333
Diffstat (limited to 'engines')
-rw-r--r-- | engines/gob/inter_v6.cpp | 7 | ||||
-rw-r--r-- | engines/gob/util.cpp | 3 | ||||
-rw-r--r-- | engines/gob/videoplayer.cpp | 42 | ||||
-rw-r--r-- | engines/gob/videoplayer.h | 7 |
4 files changed, 56 insertions, 3 deletions
diff --git a/engines/gob/inter_v6.cpp b/engines/gob/inter_v6.cpp index 9babcf9a45..0ae08dc387 100644 --- a/engines/gob/inter_v6.cpp +++ b/engines/gob/inter_v6.cpp @@ -176,10 +176,15 @@ void Inter_v6::o6_playVmdOrMusic() { return; } + if(!(props.flags & 0x1000) && !(props.flags & VideoPlayer::kFlagNoVideo)) + props.flags |= VideoPlayer::kFlagNonBlocking; + else + props.flags &= ~0x1000; + if (props.startFrame >= 0) _vm->_vidPlayer->play(slot, props); - if (close) + if (close && !(props.flags & VideoPlayer::kFlagNonBlocking)) _vm->_vidPlayer->closeVideo(slot); } diff --git a/engines/gob/util.cpp b/engines/gob/util.cpp index 8e2b3d89cd..c1cf42b1de 100644 --- a/engines/gob/util.cpp +++ b/engines/gob/util.cpp @@ -31,6 +31,7 @@ #include "gob/draw.h" #include "gob/game.h" #include "gob/video.h" +#include "gob/videoplayer.h" #include "gob/sound/sound.h" #include "common/events.h" @@ -94,6 +95,8 @@ void Util::processInput(bool scroll) { int16 x = 0, y = 0; bool hasMove = false; + _vm->_vidPlayer->updateLive(); + while (eventMan->pollEvent(event)) { switch (event.type) { case Common::EVENT_MOUSEMOVE: diff --git a/engines/gob/videoplayer.cpp b/engines/gob/videoplayer.cpp index 1c5f1c1a72..c22a67ac16 100644 --- a/engines/gob/videoplayer.cpp +++ b/engines/gob/videoplayer.cpp @@ -45,7 +45,7 @@ VideoPlayer::Properties::Properties() : type(kVideoTypeTry), sprite(Draw::kFront } -VideoPlayer::Video::Video() : decoder(0) { +VideoPlayer::Video::Video() : decoder(0), live(false) { } bool VideoPlayer::Video::isEmpty() const { @@ -58,6 +58,8 @@ void VideoPlayer::Video::close() { decoder = 0; fileName.clear(); surface.reset(); + + live = false; } @@ -240,6 +242,13 @@ bool VideoPlayer::play(int slot, Properties &properties) { properties.canceled = false; + if (primary && (properties.flags & kFlagNonBlocking)) { + video->live = true; + properties.waitEndFrame = false; + _liveProperties = properties; + return true; + } + while ((properties.startFrame != properties.lastFrame) && (properties.startFrame < (int32)(video->decoder->getFrameCount() - 1))) { @@ -274,6 +283,35 @@ void VideoPlayer::waitEndFrame(int slot, bool onlySound) { _vm->_util->delay(video->decoder->getTimeToNextFrame()); } +void VideoPlayer::updateLive() { + Video *video = getVideoBySlot(0); + if (!video || !video->live) + return; + + if ((_liveProperties.startFrame == _liveProperties.lastFrame) || + (_liveProperties.startFrame >= (int32)(video->decoder->getFrameCount() - 1))) { + + WRITE_VAR_OFFSET(212, (uint32)-1); + _vm->_vidPlayer->closeVideo(); + return; + } + + if (video->decoder->getTimeToNextFrame() > 0) + return; + + WRITE_VAR_OFFSET(212, _liveProperties.startFrame + 1); + + bool backwards = _liveProperties.startFrame > _liveProperties.lastFrame; + playFrame(0, _liveProperties); + + _liveProperties.startFrame += backwards ? -1 : 1; + + if (_liveProperties.fade) { + _vm->_palAnim->fade(_vm->_global->_pPaletteDesc, -2, 0); + _liveProperties.fade = false; + } +} + bool VideoPlayer::playFrame(int slot, Properties &properties) { Video *video = getVideoBySlot(slot); if (!video) @@ -387,7 +425,7 @@ bool VideoPlayer::playFrame(int slot, Properties &properties) { } - if ((video->decoder->getCurFrame() - 1) == properties.startFrame) + if (!video->live && ((video->decoder->getCurFrame() - 1) == properties.startFrame)) // Only retrace if we're playing the frame we actually want to play _vm->_video->retrace(); diff --git a/engines/gob/videoplayer.h b/engines/gob/videoplayer.h index 408597f580..9b68d4a5af 100644 --- a/engines/gob/videoplayer.h +++ b/engines/gob/videoplayer.h @@ -50,6 +50,7 @@ public: kFlagFrontSurface = 0x000080, ///< Draw directly into the front surface. kFlagNoVideo = 0x000100, ///< Only sound. kFlagOtherSurface = 0x000800, ///< Draw into a specific sprite. + kFlagNonBlocking = 0x001000, ///< "Live" video playing while scripts continue. kFlagScreenSurface = 0x400000 ///< Draw into a newly created sprite of screen dimensions. }; @@ -109,6 +110,8 @@ public: bool play(int slot, Properties &properties); void waitEndFrame(int slot, bool onlySound = false); + void updateLive(); + bool slotIsOpen(int slot = 0) const; Common::String getFileName(int slot = 0) const; @@ -141,6 +144,8 @@ private: SurfacePtr surface; + bool live; + Video(); bool isEmpty() const; @@ -151,6 +156,8 @@ private: static const char *_extensions[]; + Properties _liveProperties; + GobEngine *_vm; // _videoSlots[0] is reserved for the "primary" video |