aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/gob/inter_v1.cpp9
-rw-r--r--engines/gob/inter_v2.cpp4
-rw-r--r--engines/gob/videoplayer.cpp50
-rw-r--r--engines/gob/videoplayer.h7
-rw-r--r--video/coktel_decoder.cpp45
-rw-r--r--video/coktel_decoder.h9
6 files changed, 122 insertions, 2 deletions
diff --git a/engines/gob/inter_v1.cpp b/engines/gob/inter_v1.cpp
index 9aa190a456..4aa54f720b 100644
--- a/engines/gob/inter_v1.cpp
+++ b/engines/gob/inter_v1.cpp
@@ -1744,10 +1744,15 @@ void Inter_v1::o1_writeData(OpFuncParams &params) {
void Inter_v1::o1_manageDataFile(OpFuncParams &params) {
Common::String file = _vm->_game->_script->evalString();
- if (!file.empty())
+ if (!file.empty()) {
_vm->_dataIO->openArchive(file, true);
- else
+ } else {
_vm->_dataIO->closeArchive(true);
+
+ // NOTE: Lost in Time might close a data file without explicitely closing a video in it.
+ // So we make sure that all open videos are still available.
+ _vm->_vidPlayer->reopenAll();
+ }
}
void Inter_v1::o1_setState(OpGobParams &params) {
diff --git a/engines/gob/inter_v2.cpp b/engines/gob/inter_v2.cpp
index 1e5b7bb24c..54f6a1acc1 100644
--- a/engines/gob/inter_v2.cpp
+++ b/engines/gob/inter_v2.cpp
@@ -1002,6 +1002,10 @@ void Inter_v2::o2_openItk() {
void Inter_v2::o2_closeItk() {
_vm->_dataIO->closeArchive(false);
+
+ // NOTE: Lost in Time might close a data file without explicitely closing a video in it.
+ // So we make sure that all open videos are still available.
+ _vm->_vidPlayer->reopenAll();
}
void Inter_v2::o2_setImdFrontSurf() {
diff --git a/engines/gob/videoplayer.cpp b/engines/gob/videoplayer.cpp
index 221f5ab3c9..a478492ccc 100644
--- a/engines/gob/videoplayer.cpp
+++ b/engines/gob/videoplayer.cpp
@@ -234,6 +234,23 @@ void VideoPlayer::closeAll() {
closeVideo(i);
}
+bool VideoPlayer::reopenVideo(int slot) {
+ Video *video = getVideoBySlot(slot);
+ if (!video)
+ return true;
+
+ return reopenVideo(*video);
+}
+
+bool VideoPlayer::reopenAll() {
+ bool all = true;
+ for (int i = 0; i < kVideoSlotCount; i++)
+ if (!reopenVideo(i))
+ all = false;
+
+ return all;
+}
+
void VideoPlayer::pauseVideo(int slot, bool pause) {
Video *video = getVideoBySlot(slot);
if (!video || !video->decoder)
@@ -850,6 +867,39 @@ Common::String VideoPlayer::findFile(const Common::String &file, Properties &pro
return video;
}
+bool VideoPlayer::reopenVideo(Video &video) {
+ if (video.isEmpty())
+ return true;
+
+ if (video.fileName.empty()) {
+ video.close();
+ return false;
+ }
+
+ Properties properties;
+
+ properties.type = video.properties.type;
+
+ Common::String fileName = findFile(video.fileName, properties);
+ if (fileName.empty()) {
+ video.close();
+ return false;
+ }
+
+ Common::SeekableReadStream *stream = _vm->_dataIO->getFile(fileName);
+ if (!stream) {
+ video.close();
+ return false;
+ }
+
+ if (!video.decoder->reloadStream(stream)) {
+ delete stream;
+ return false;
+ }
+
+ return true;
+}
+
void VideoPlayer::copyPalette(const Video &video, int16 palStart, int16 palEnd) {
if (!video.decoder->hasPalette() || !video.decoder->isPaletted())
return;
diff --git a/engines/gob/videoplayer.h b/engines/gob/videoplayer.h
index bc7cb48768..129ccef67a 100644
--- a/engines/gob/videoplayer.h
+++ b/engines/gob/videoplayer.h
@@ -110,6 +110,9 @@ public:
void closeLiveSound();
void closeAll();
+ bool reopenVideo(int slot = 0);
+ bool reopenAll();
+
void pauseVideo(int slot, bool pause);
void pauseAll(bool pause);
@@ -163,6 +166,8 @@ private:
bool isEmpty() const;
void close();
+
+ void reopen();
};
static const int kVideoSlotCount = 32;
@@ -188,6 +193,8 @@ private:
::Video::CoktelDecoder *openVideo(const Common::String &file, Properties &properties);
+ bool reopenVideo(Video &video);
+
bool playFrame(int slot, Properties &properties);
void checkAbort(Video &video, Properties &properties);
diff --git a/video/coktel_decoder.cpp b/video/coktel_decoder.cpp
index be36874db4..0c7ade1b8a 100644
--- a/video/coktel_decoder.cpp
+++ b/video/coktel_decoder.cpp
@@ -646,6 +646,21 @@ PreIMDDecoder::~PreIMDDecoder() {
close();
}
+bool PreIMDDecoder::reloadStream(Common::SeekableReadStream *stream) {
+ if (!_stream)
+ return false;
+
+ if (!stream->seek(_stream->pos())) {
+ close();
+ return false;
+ }
+
+ delete _stream;
+ _stream = stream;
+
+ return true;
+}
+
bool PreIMDDecoder::seek(int32 frame, int whence, bool restart) {
if (!evaluateSeekFrame(frame, whence))
return false;
@@ -840,6 +855,21 @@ IMDDecoder::~IMDDecoder() {
close();
}
+bool IMDDecoder::reloadStream(Common::SeekableReadStream *stream) {
+ if (!_stream)
+ return false;
+
+ if (!stream->seek(_stream->pos())) {
+ close();
+ return false;
+ }
+
+ delete _stream;
+ _stream = stream;
+
+ return true;
+}
+
bool IMDDecoder::seek(int32 frame, int whence, bool restart) {
if (!evaluateSeekFrame(frame, whence))
return false;
@@ -1536,6 +1566,21 @@ VMDDecoder::~VMDDecoder() {
close();
}
+bool VMDDecoder::reloadStream(Common::SeekableReadStream *stream) {
+ if (!_stream)
+ return false;
+
+ if (!stream->seek(_stream->pos())) {
+ close();
+ return false;
+ }
+
+ delete _stream;
+ _stream = stream;
+
+ return true;
+}
+
bool VMDDecoder::seek(int32 frame, int whence, bool restart) {
if (!evaluateSeekFrame(frame, whence))
return false;
diff --git a/video/coktel_decoder.h b/video/coktel_decoder.h
index 68696d5ff3..c88d982191 100644
--- a/video/coktel_decoder.h
+++ b/video/coktel_decoder.h
@@ -79,6 +79,9 @@ public:
Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType);
~CoktelDecoder();
+ /** Replace the current video stream with this identical one. */
+ virtual bool reloadStream(Common::SeekableReadStream *stream) = 0;
+
virtual bool seek(int32 frame, int whence = SEEK_SET, bool restart = false) = 0;
/** Draw directly onto the specified video memory. */
@@ -237,6 +240,8 @@ public:
Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType);
~PreIMDDecoder();
+ bool reloadStream(Common::SeekableReadStream *stream);
+
bool seek(int32 frame, int whence = SEEK_SET, bool restart = false);
@@ -268,6 +273,8 @@ public:
IMDDecoder(Audio::Mixer *mixer, Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType);
~IMDDecoder();
+ bool reloadStream(Common::SeekableReadStream *stream);
+
bool seek(int32 frame, int whence = SEEK_SET, bool restart = false);
void setXY(uint16 x, uint16 y);
@@ -364,6 +371,8 @@ public:
VMDDecoder(Audio::Mixer *mixer, Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType);
~VMDDecoder();
+ bool reloadStream(Common::SeekableReadStream *stream);
+
bool seek(int32 frame, int whence = SEEK_SET, bool restart = false);
void setXY(uint16 x, uint16 y);