diff options
-rw-r--r-- | engines/gob/inter_v1.cpp | 9 | ||||
-rw-r--r-- | engines/gob/inter_v2.cpp | 4 | ||||
-rw-r--r-- | engines/gob/videoplayer.cpp | 50 | ||||
-rw-r--r-- | engines/gob/videoplayer.h | 7 | ||||
-rw-r--r-- | video/coktel_decoder.cpp | 45 | ||||
-rw-r--r-- | video/coktel_decoder.h | 9 |
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 ¶ms) { void Inter_v1::o1_manageDataFile(OpFuncParams ¶ms) { 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 ¶ms) { 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); |