aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorSven Hesse2011-01-19 18:57:43 +0000
committerSven Hesse2011-01-19 18:57:43 +0000
commitbad7f1ce9a67e71eaaa390ac56ae5a3720c3fb7a (patch)
tree49de1da704aa8cfc8f65f4e551e7b7ec66e44b33 /engines
parent878bedf454a8440b3d3c8887bc021a698dbb5605 (diff)
downloadscummvm-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.cpp7
-rw-r--r--engines/gob/util.cpp3
-rw-r--r--engines/gob/videoplayer.cpp42
-rw-r--r--engines/gob/videoplayer.h7
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