aboutsummaryrefslogtreecommitdiff
path: root/engines/zvision/video
diff options
context:
space:
mode:
Diffstat (limited to 'engines/zvision/video')
-rw-r--r--engines/zvision/video/rlf_decoder.cpp62
-rw-r--r--engines/zvision/video/rlf_decoder.h8
-rw-r--r--engines/zvision/video/video.cpp25
-rw-r--r--engines/zvision/video/zork_avi_decoder.cpp21
4 files changed, 66 insertions, 50 deletions
diff --git a/engines/zvision/video/rlf_decoder.cpp b/engines/zvision/video/rlf_decoder.cpp
index bdb5dc18bc..3bbf22edff 100644
--- a/engines/zvision/video/rlf_decoder.cpp
+++ b/engines/zvision/video/rlf_decoder.cpp
@@ -30,8 +30,6 @@
#include "common/debug.h"
#include "common/endian.h"
-#include "graphics/colormasks.h"
-
namespace ZVision {
RLFDecoder::~RLFDecoder() {
@@ -41,9 +39,13 @@ RLFDecoder::~RLFDecoder() {
bool RLFDecoder::loadStream(Common::SeekableReadStream *stream) {
close();
- addTrack(new RLFVideoTrack(stream));
-
- return true;
+ // Check if the stream is valid
+ if (stream && !stream->err() && stream->readUint32BE() == MKTAG('F', 'E', 'L', 'R')) {
+ addTrack(new RLFVideoTrack(stream));
+ return true;
+ } else {
+ return false;
+ }
}
RLFDecoder::RLFVideoTrack::RLFVideoTrack(Common::SeekableReadStream *stream)
@@ -54,7 +56,7 @@ RLFDecoder::RLFVideoTrack::RLFVideoTrack(Common::SeekableReadStream *stream)
_height(0),
_frameTime(0),
_frames(0),
- _curFrame(0),
+ _displayedFrame(-1),
_frameBufferByteSize(0) {
if (!readHeader()) {
@@ -62,7 +64,7 @@ RLFDecoder::RLFVideoTrack::RLFVideoTrack(Common::SeekableReadStream *stream)
return;
}
- _currentFrameBuffer.create(_width, _height, Graphics::createPixelFormat<565>());
+ _currentFrameBuffer.create(_width, _height, getPixelFormat());
_frameBufferByteSize = _width * _height * sizeof(uint16);
_frames = new Frame[_frameCount];
@@ -83,10 +85,6 @@ RLFDecoder::RLFVideoTrack::~RLFVideoTrack() {
}
bool RLFDecoder::RLFVideoTrack::readHeader() {
- if (_readStream->readUint32BE() != MKTAG('F', 'E', 'L', 'R')) {
- return false;
- }
-
// Read the header
_readStream->readUint32LE(); // Size1
_readStream->readUint32LE(); // Unknown1
@@ -161,22 +159,17 @@ RLFDecoder::RLFVideoTrack::Frame RLFDecoder::RLFVideoTrack::readNextFrame() {
bool RLFDecoder::RLFVideoTrack::seek(const Audio::Timestamp &time) {
uint frame = getFrameAtTime(time);
- assert(frame < (int)_frameCount);
+ assert(frame < _frameCount);
- if ((uint)_curFrame == frame)
+ if ((uint)_displayedFrame == frame)
return true;
- if (frame < 0) {
- _curFrame = 0;
- return false;
- }
-
- int closestFrame = _curFrame;
- int distance = (int)frame - _curFrame;
+ int closestFrame = _displayedFrame;
+ int distance = (int)frame - closestFrame;
if (distance < 0) {
for (uint i = 0; i < _completeFrames.size(); ++i) {
- if ((int)_completeFrames[i] > frame)
+ if (_completeFrames[i] > frame)
break;
closestFrame = _completeFrames[i];
}
@@ -196,19 +189,18 @@ bool RLFDecoder::RLFVideoTrack::seek(const Audio::Timestamp &time) {
applyFrameToCurrent(i);
}
- _curFrame = frame;
+ _displayedFrame = frame - 1;
return true;
}
const Graphics::Surface *RLFDecoder::RLFVideoTrack::decodeNextFrame() {
- // When an animation ends, rewind
- if (_curFrame == (int)_frameCount)
- seek(Audio::Timestamp(0, getFrameRate().toInt()));
-
- applyFrameToCurrent(_curFrame);
+ if (_displayedFrame >= (int)_frameCount)
+ return NULL;
+
+ _displayedFrame++;
+ applyFrameToCurrent(_displayedFrame);
- _curFrame++;
return &_currentFrameBuffer;
}
@@ -242,10 +234,7 @@ void RLFDecoder::RLFVideoTrack::decodeMaskedRunLengthEncoding(int8 *source, int8
return;
}
- byte r, g, b;
- Graphics::colorToRGB<Graphics::ColorMasks<555> >(READ_LE_UINT16(source + sourceOffset), r, g, b);
- uint16 destColor = Graphics::RGBToColor<Graphics::ColorMasks<565> >(r, g, b);
- WRITE_UINT16(dest + destOffset, destColor);
+ WRITE_UINT16(dest + destOffset, READ_LE_UINT16(source + sourceOffset));
sourceOffset += 2;
destOffset += 2;
@@ -289,10 +278,7 @@ void RLFDecoder::RLFVideoTrack::decodeSimpleRunLengthEncoding(int8 *source, int8
return;
}
- byte r, g, b;
- Graphics::colorToRGB<Graphics::ColorMasks<555> >(READ_LE_UINT16(source + sourceOffset), r, g, b);
- uint16 destColor = Graphics::RGBToColor<Graphics::ColorMasks<565> >(r, g, b);
- WRITE_UINT16(dest + destOffset, destColor);
+ WRITE_UINT16(dest + destOffset, READ_LE_UINT16(source + sourceOffset));
sourceOffset += 2;
destOffset += 2;
@@ -306,9 +292,7 @@ void RLFDecoder::RLFVideoTrack::decodeSimpleRunLengthEncoding(int8 *source, int8
return;
}
- byte r, g, b;
- Graphics::colorToRGB<Graphics::ColorMasks<555> >(READ_LE_UINT16(source + sourceOffset), r, g, b);
- uint16 sampleColor = Graphics::RGBToColor<Graphics::ColorMasks<565> >(r, g, b);
+ uint16 sampleColor = READ_LE_UINT16(source + sourceOffset);
sourceOffset += 2;
numberOfCopy = numberOfSamples + 2;
diff --git a/engines/zvision/video/rlf_decoder.h b/engines/zvision/video/rlf_decoder.h
index f0f31c2128..8b8cbaecd5 100644
--- a/engines/zvision/video/rlf_decoder.h
+++ b/engines/zvision/video/rlf_decoder.h
@@ -45,15 +45,15 @@ private:
uint16 getWidth() const { return _width; }
uint16 getHeight() const { return _height; }
- Graphics::PixelFormat getPixelFormat() const { return Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0); /*RGB 565*/ }
- int getCurFrame() const { return _curFrame; }
+ Graphics::PixelFormat getPixelFormat() const { return Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0); /* RGB 555 */ }
+ int getCurFrame() const { return _displayedFrame; }
int getFrameCount() const { return _frameCount; }
const Graphics::Surface *decodeNextFrame();
bool isSeekable() const { return true; }
bool seek(const Audio::Timestamp &time);
protected:
- Common::Rational getFrameRate() const { return Common::Rational(60, _frameTime); }
+ Common::Rational getFrameRate() const { return Common::Rational(1000, _frameTime); }
private:
enum EncodingType {
@@ -121,7 +121,7 @@ private:
Frame *_frames;
Common::Array<uint> _completeFrames;
- int _curFrame;
+ int _displayedFrame;
Graphics::Surface _currentFrameBuffer;
uint32 _frameBufferByteSize;
diff --git a/engines/zvision/video/video.cpp b/engines/zvision/video/video.cpp
index 189fb22194..1cfd0f4197 100644
--- a/engines/zvision/video/video.cpp
+++ b/engines/zvision/video/video.cpp
@@ -23,13 +23,17 @@
#include "common/scummsys.h"
#include "common/system.h"
#include "video/video_decoder.h"
+#ifdef USE_MPEG2
+#include "video/mpegps_decoder.h"
+#endif
#include "engines/util.h"
#include "graphics/surface.h"
#include "zvision/zvision.h"
#include "zvision/core/clock.h"
#include "zvision/graphics/render_manager.h"
-#include "zvision/graphics/subtitles.h"
+#include "zvision/scripting/script_manager.h"
+#include "zvision/text/subtitles.h"
#include "zvision/video/rlf_decoder.h"
#include "zvision/video/zork_avi_decoder.h"
@@ -44,12 +48,21 @@ Video::VideoDecoder *ZVision::loadAnimation(const Common::String &fileName) {
animation = new RLFDecoder();
else if (tmpFileName.hasSuffix(".avi"))
animation = new ZorkAVIDecoder();
+#ifdef USE_MPEG2
+ else if (tmpFileName.hasSuffix(".vob"))
+ animation = new Video::MPEGPSDecoder();
+#endif
else
error("Unknown suffix for animation %s", fileName.c_str());
Common::File *_file = getSearchManager()->openFile(tmpFileName);
- animation->loadStream(_file);
-
+ if (!_file)
+ error("Error opening %s", tmpFileName.c_str());
+
+ bool loaded = animation->loadStream(_file);
+ if (!loaded)
+ error("Error loading animation %s", tmpFileName.c_str());
+
return animation;
}
@@ -70,6 +83,7 @@ void ZVision::playVideo(Video::VideoDecoder &vid, const Common::Rect &destRect,
uint16 y = _workingWindow.top + dst.top;
uint16 finalWidth = dst.width() < _workingWindow.width() ? dst.width() : _workingWindow.width();
uint16 finalHeight = dst.height() < _workingWindow.height() ? dst.height() : _workingWindow.height();
+ bool showSubs = (_scriptManager->getStateValue(StateKey_Subtitles) == 1);
_clock.stop();
vid.start();
@@ -101,7 +115,7 @@ void ZVision::playVideo(Video::VideoDecoder &vid, const Common::Rect &destRect,
if (vid.needsUpdate()) {
const Graphics::Surface *frame = vid.decodeNextFrame();
- if (sub)
+ if (sub && showSubs)
sub->process(vid.getCurFrame());
if (frame) {
@@ -109,7 +123,8 @@ void ZVision::playVideo(Video::VideoDecoder &vid, const Common::Rect &destRect,
_renderManager->scaleBuffer(frame->getPixels(), scaled->getPixels(), frame->w, frame->h, frame->format.bytesPerPixel, scaled->w, scaled->h);
frame = scaled;
}
- _system->copyRectToScreen((const byte *)frame->getPixels(), frame->pitch, x, y, finalWidth, finalHeight);
+ Common::Rect rect = Common::Rect(x, y, x + finalWidth, y + finalHeight);
+ _renderManager->copyToScreen(*frame, rect, 0, 0);
_renderManager->processSubs(0);
}
}
diff --git a/engines/zvision/video/zork_avi_decoder.cpp b/engines/zvision/video/zork_avi_decoder.cpp
index 67fab0a114..cf8505ec82 100644
--- a/engines/zvision/video/zork_avi_decoder.cpp
+++ b/engines/zvision/video/zork_avi_decoder.cpp
@@ -39,17 +39,34 @@ Video::AVIDecoder::AVIAudioTrack *ZorkAVIDecoder::createAudioTrack(Video::AVIDec
}
void ZorkAVIDecoder::ZorkAVIAudioTrack::queueSound(Common::SeekableReadStream *stream) {
+ bool updateCurChunk = true;
if (_audStream) {
if (_wvInfo.tag == kWaveFormatZorkPCM) {
assert(_wvInfo.size == 8);
RawChunkStream::RawChunk chunk = decoder->readNextChunk(stream);
delete stream;
- if (chunk.data)
- _audStream->queueBuffer((byte *)chunk.data, chunk.size, DisposeAfterUse::YES, Audio::FLAG_16BITS | Audio::FLAG_LITTLE_ENDIAN | Audio::FLAG_STEREO);
+ if (chunk.data) {
+ byte flags = Audio::FLAG_16BITS | Audio::FLAG_STEREO;
+#ifdef SCUMM_LITTLE_ENDIAN
+ // RawChunkStream produces native endianness int16
+ flags |= Audio::FLAG_LITTLE_ENDIAN;
+#endif
+ _audStream->queueBuffer((byte *)chunk.data, chunk.size, DisposeAfterUse::YES, flags);
+ }
} else {
+ updateCurChunk = false;
AVIAudioTrack::queueSound(stream);
}
+ } else {
+ delete stream;
+ }
+
+ // The superclass always updates _curChunk, whether or not audio has
+ // been queued, so we should do that too. Unless the superclass already
+ // has done it for us.
+ if (updateCurChunk) {
+ _curChunk++;
}
}