[Scummvm-cvs-logs] scummvm master -> 8c3d2fc7410ab3f55735f6a78dadbeec23c59b6c
DrMcCoy
drmccoy at drmccoy.de
Thu Jun 7 00:30:35 CEST 2012
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
8c3d2fc741 GOB: Add a way to reopen currently opened IMD/VMD videos
Commit: 8c3d2fc7410ab3f55735f6a78dadbeec23c59b6c
https://github.com/scummvm/scummvm/commit/8c3d2fc7410ab3f55735f6a78dadbeec23c59b6c
Author: Sven Hesse (drmccoy at users.sourceforge.net)
Date: 2012-06-06T15:29:46-07:00
Commit Message:
GOB: Add a way to reopen currently opened IMD/VMD videos
This is a workaround for how Lost in Time behaves in combination
with changes I made to the DataIO code for running Urban Runner
on low-memory devices.
Urban Runner's intro are far to big to have them copied into
memory for these devices, so I made the DataIO code return a
SafeSeekableSubReadStream into the opened archive stream instead.
Unfortunately, Lost in Time might not close a video file when it
closes the data file which it was originally in, especially when
loading a saved game. Since the video player needs to be able to
gaplessly continue a video and there does not, by itself, close
the video if not requested by the scripts, this leads to reading
out of an already closed stream in certain cases.
So, to worka round this issues, the video player tries to reopen
each currently opened video after a data archive was closed, to
make sure that that video is still available. If not, the video
is closed.
Changed paths:
engines/gob/inter_v1.cpp
engines/gob/inter_v2.cpp
engines/gob/videoplayer.cpp
engines/gob/videoplayer.h
video/coktel_decoder.cpp
video/coktel_decoder.h
diff --git a/engines/gob/inter_v1.cpp b/engines/gob/inter_v1.cpp
index 9aa190a..4aa54f7 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 1e5b7bb..54f6a1a 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 221f5ab..a478492 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 bc7cb48..129ccef 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 be36874..0c7ade1 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 68696d5..c88d982 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);
More information about the Scummvm-git-logs
mailing list