From ace0e5e88f63f34dad94962c95f57f3ec42258ae Mon Sep 17 00:00:00 2001 From: Marisa-Chan Date: Sat, 14 Jun 2014 15:18:24 +0700 Subject: ZVISION: Fix compilation errors with latest scummvm --- engines/zvision/video/video.cpp | 6 +++--- engines/zvision/video/zork_avi_decoder.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'engines/zvision/video') diff --git a/engines/zvision/video/video.cpp b/engines/zvision/video/video.cpp index 0ad9000fcb..7a120df76b 100644 --- a/engines/zvision/video/video.cpp +++ b/engines/zvision/video/video.cpp @@ -24,9 +24,9 @@ #include "zvision/zvision.h" -#include "zvision/clock.h" -#include "zvision/render_manager.h" -#include "zvision/subtitles.h" +#include "zvision/utility/clock.h" +#include "zvision/graphics/render_manager.h" +#include "zvision/subtitles/subtitles.h" #include "common/system.h" diff --git a/engines/zvision/video/zork_avi_decoder.h b/engines/zvision/video/zork_avi_decoder.h index d8937ac057..db1ad312c7 100644 --- a/engines/zvision/video/zork_avi_decoder.h +++ b/engines/zvision/video/zork_avi_decoder.h @@ -25,7 +25,7 @@ #define ZORK_AVI_DECODER_H #include "video/avi_decoder.h" -#include "zork_raw.h" +#include "zvision/sound/zork_raw.h" namespace ZVision { -- cgit v1.2.3 From 3f21de4694080f07f7927afdc11c4093e523dd6f Mon Sep 17 00:00:00 2001 From: Marisa-Chan Date: Tue, 4 Nov 2014 10:08:07 +0600 Subject: ZVISION: Make ZorkAVIAudioTrack resetable --- engines/zvision/video/zork_avi_decoder.cpp | 4 ++++ engines/zvision/video/zork_avi_decoder.h | 1 + 2 files changed, 5 insertions(+) (limited to 'engines/zvision/video') diff --git a/engines/zvision/video/zork_avi_decoder.cpp b/engines/zvision/video/zork_avi_decoder.cpp index e7624342e8..a9dc7765d4 100644 --- a/engines/zvision/video/zork_avi_decoder.cpp +++ b/engines/zvision/video/zork_avi_decoder.cpp @@ -55,4 +55,8 @@ void ZorkAVIDecoder::ZorkAVIAudioTrack::queueSound(Common::SeekableReadStream *s } } +void ZorkAVIDecoder::ZorkAVIAudioTrack::resetStream() { + decoder->init(); +} + } // End of namespace ZVision diff --git a/engines/zvision/video/zork_avi_decoder.h b/engines/zvision/video/zork_avi_decoder.h index db1ad312c7..89c0d1e4b9 100644 --- a/engines/zvision/video/zork_avi_decoder.h +++ b/engines/zvision/video/zork_avi_decoder.h @@ -52,6 +52,7 @@ private: } void queueSound(Common::SeekableReadStream *stream); + void resetStream(); private: RawChunkStream *decoder; }; -- cgit v1.2.3 From d40caba5b748be38f2b6fe4c70af7eeccedd0ab8 Mon Sep 17 00:00:00 2001 From: Marisa-Chan Date: Tue, 4 Nov 2014 10:09:27 +0600 Subject: ZVISION: If ZorkAVIAudioTrack got another format call AVIAudioTrack::queueSound --- engines/zvision/video/zork_avi_decoder.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'engines/zvision/video') diff --git a/engines/zvision/video/zork_avi_decoder.cpp b/engines/zvision/video/zork_avi_decoder.cpp index a9dc7765d4..415a20d3f2 100644 --- a/engines/zvision/video/zork_avi_decoder.cpp +++ b/engines/zvision/video/zork_avi_decoder.cpp @@ -48,10 +48,9 @@ void ZorkAVIDecoder::ZorkAVIAudioTrack::queueSound(Common::SeekableReadStream *s if (chunk.data) _audStream->queueBuffer((byte *)chunk.data, chunk.size, DisposeAfterUse::YES, Audio::FLAG_16BITS | Audio::FLAG_LITTLE_ENDIAN | Audio::FLAG_STEREO); + } else { + AVIAudioTrack::queueSound(stream); } - } else { - warning("Got %d wave format in AVI\n", _wvInfo.tag); - delete stream; } } -- cgit v1.2.3 From 2a4a6df5f2ae89132fd93d26b03599b6cc5c5fb7 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Wed, 3 Dec 2014 01:12:35 +0200 Subject: ZVISION: Remove superfluous spacing and reorder some includes --- engines/zvision/video/video.cpp | 15 ++++----------- engines/zvision/video/zork_avi_decoder.cpp | 1 - 2 files changed, 4 insertions(+), 12 deletions(-) (limited to 'engines/zvision/video') diff --git a/engines/zvision/video/video.cpp b/engines/zvision/video/video.cpp index 7a120df76b..25125ec2fb 100644 --- a/engines/zvision/video/video.cpp +++ b/engines/zvision/video/video.cpp @@ -21,21 +21,15 @@ */ #include "common/scummsys.h" - -#include "zvision/zvision.h" - -#include "zvision/utility/clock.h" -#include "zvision/graphics/render_manager.h" -#include "zvision/subtitles/subtitles.h" - #include "common/system.h" - #include "video/video_decoder.h" - #include "engines/util.h" - #include "graphics/surface.h" +#include "zvision/zvision.h" +#include "zvision/utility/clock.h" +#include "zvision/graphics/render_manager.h" +#include "zvision/subtitles/subtitles.h" namespace ZVision { @@ -52,7 +46,6 @@ void ZVision::playVideo(Video::VideoDecoder &vid, const Common::Rect &destRect, scaled->create(dst.width(), dst.height(), vid.getPixelFormat()); } - uint16 x = _workingWindow.left + dst.left; uint16 y = _workingWindow.top + dst.top; uint16 finalWidth = dst.width() < _workingWindow.width() ? dst.width() : _workingWindow.width(); diff --git a/engines/zvision/video/zork_avi_decoder.cpp b/engines/zvision/video/zork_avi_decoder.cpp index 415a20d3f2..67fab0a114 100644 --- a/engines/zvision/video/zork_avi_decoder.cpp +++ b/engines/zvision/video/zork_avi_decoder.cpp @@ -31,7 +31,6 @@ #include "audio/audiostream.h" #include "audio/decoders/raw.h" - namespace ZVision { Video::AVIDecoder::AVIAudioTrack *ZorkAVIDecoder::createAudioTrack(Video::AVIDecoder::AVIStreamHeader sHeader, Video::AVIDecoder::PCMWaveFormat wvInfo) { -- cgit v1.2.3 From dab4ce1f7bc5c72f9f90bc0de8553e4b4e945624 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Wed, 3 Dec 2014 02:38:06 +0200 Subject: ZVISION: Move the subtitle class --- engines/zvision/video/video.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'engines/zvision/video') diff --git a/engines/zvision/video/video.cpp b/engines/zvision/video/video.cpp index 25125ec2fb..36b5f9b921 100644 --- a/engines/zvision/video/video.cpp +++ b/engines/zvision/video/video.cpp @@ -29,7 +29,7 @@ #include "zvision/zvision.h" #include "zvision/utility/clock.h" #include "zvision/graphics/render_manager.h" -#include "zvision/subtitles/subtitles.h" +#include "zvision/graphics/subtitles.h" namespace ZVision { -- cgit v1.2.3 From ec1fdeb25ad6b2d9aae69a544f45eb7fc5e189b8 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Mon, 8 Dec 2014 01:08:27 +0200 Subject: ZVISION: Implement several advanced engine features and ScummVM dialogs The functionality to return to launcher, list saves, delete saves, load games from the launcher and load and save games during runtime has been implemented. Also, ScummVM save/load dialogs have been implemented. Saved games now have three numbers in their file extension, bumping the possible save game slots up to 999 --- engines/zvision/video/video.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'engines/zvision/video') diff --git a/engines/zvision/video/video.cpp b/engines/zvision/video/video.cpp index 36b5f9b921..db6161bf0c 100644 --- a/engines/zvision/video/video.cpp +++ b/engines/zvision/video/video.cpp @@ -53,6 +53,7 @@ void ZVision::playVideo(Video::VideoDecoder &vid, const Common::Rect &destRect, _clock.stop(); vid.start(); + _videoIsPlaying = true; // Only continue while the video is still playing while (!shouldQuit() && !vid.endOfVideo() && vid.isPlaying()) { @@ -99,6 +100,7 @@ void ZVision::playVideo(Video::VideoDecoder &vid, const Common::Rect &destRect, _system->delayMillis(vid.getTimeToNextFrame() / 2); } + _videoIsPlaying = false; _clock.start(); if (scaled) { -- cgit v1.2.3 From 3315522ba1607d68c3402f3d1c8b51b7dc38a7dd Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Sat, 13 Dec 2014 15:28:22 +0200 Subject: ZVISION: Move the RLF decoder --- engines/zvision/video/rlf_decoder.cpp | 382 ++++++++++++++++++++++++++++++++++ engines/zvision/video/rlf_decoder.h | 172 +++++++++++++++ 2 files changed, 554 insertions(+) create mode 100644 engines/zvision/video/rlf_decoder.cpp create mode 100644 engines/zvision/video/rlf_decoder.h (limited to 'engines/zvision/video') diff --git a/engines/zvision/video/rlf_decoder.cpp b/engines/zvision/video/rlf_decoder.cpp new file mode 100644 index 0000000000..a4f16af9b0 --- /dev/null +++ b/engines/zvision/video/rlf_decoder.cpp @@ -0,0 +1,382 @@ +/* ScummVM - Graphic Adventure Engine +* +* ScummVM is the legal property of its developers, whose names +* are too numerous to list here. Please refer to the COPYRIGHT +* file distributed with this source distribution. +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. + +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. + +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +* +*/ + +#include "common/scummsys.h" + +#include "zvision/video/rlf_decoder.h" + +#include "common/str.h" +#include "common/file.h" +#include "common/textconsole.h" +#include "common/debug.h" +#include "common/endian.h" + +#include "graphics/colormasks.h" + +namespace ZVision { + +RLFDecoder::RLFDecoder(const Common::String &fileName, bool stream) + : _stream(stream), + _readStream(NULL), + _lastFrameRead(0), + _frameCount(0), + _width(0), + _height(0), + _frameTime(0), + _frames(0), + _nextFrame(0), + _frameBufferByteSize(0) { + + Common::File *_file = new Common::File; + if (!_file->open(fileName)) { + warning("RLF animation file %s could not be opened", fileName.c_str()); + return; + } + + _readStream = _file; + + if (!readHeader()) { + warning("%s is not a RLF animation file. Wrong magic number", fileName.c_str()); + return; + } + + _currentFrameBuffer.create(_width, _height, Graphics::createPixelFormat<565>()); + _frameBufferByteSize = _width * _height * sizeof(uint16); + + if (!stream) { + _frames = new Frame[_frameCount]; + + // Read in each frame + for (uint i = 0; i < _frameCount; ++i) { + _frames[i] = readNextFrame(); + } + } +} + +RLFDecoder::RLFDecoder(Common::SeekableReadStream *rstream, bool stream) + : _stream(stream), + _readStream(rstream), + _lastFrameRead(0), + _frameCount(0), + _width(0), + _height(0), + _frameTime(0), + _frames(0), + _nextFrame(0), + _frameBufferByteSize(0) { + + if (!readHeader()) { + warning("Stream is not a RLF animation. Wrong magic number"); + return; + } + + _currentFrameBuffer.create(_width, _height, Graphics::createPixelFormat<565>()); + _frameBufferByteSize = _width * _height * sizeof(uint16); + + if (!stream) { + _frames = new Frame[_frameCount]; + + // Read in each frame + for (uint i = 0; i < _frameCount; ++i) { + _frames[i] = readNextFrame(); + } + } +} + +RLFDecoder::~RLFDecoder() { + for (uint i = 0; i < _frameCount; ++i) { + delete[] _frames[i].encodedData; + } + delete[] _frames; + delete _readStream; + _currentFrameBuffer.free(); +} + +bool RLFDecoder::readHeader() { + if (_readStream->readUint32BE() != MKTAG('F', 'E', 'L', 'R')) { + return false; + } + + // Read the header + _readStream->readUint32LE(); // Size1 + _readStream->readUint32LE(); // Unknown1 + _readStream->readUint32LE(); // Unknown2 + _frameCount = _readStream->readUint32LE(); // Frame count + + // Since we don't need any of the data, we can just seek right to the + // entries we need rather than read in all the individual entries. + _readStream->seek(136, SEEK_CUR); + + //// Read CIN header + //_readStream->readUint32BE(); // Magic number FNIC + //_readStream->readUint32LE(); // Size2 + //_readStream->readUint32LE(); // Unknown3 + //_readStream->readUint32LE(); // Unknown4 + //_readStream->readUint32LE(); // Unknown5 + //_readStream->seek(0x18, SEEK_CUR); // VRLE + //_readStream->readUint32LE(); // LRVD + //_readStream->readUint32LE(); // Unknown6 + //_readStream->seek(0x18, SEEK_CUR); // HRLE + //_readStream->readUint32LE(); // ELHD + //_readStream->readUint32LE(); // Unknown7 + //_readStream->seek(0x18, SEEK_CUR); // HKEY + //_readStream->readUint32LE(); // ELRH + + //// Read MIN info header + //_readStream->readUint32BE(); // Magic number FNIM + //_readStream->readUint32LE(); // Size3 + //_readStream->readUint32LE(); // OEDV + //_readStream->readUint32LE(); // Unknown8 + //_readStream->readUint32LE(); // Unknown9 + //_readStream->readUint32LE(); // Unknown10 + _width = _readStream->readUint32LE(); // Width + _height = _readStream->readUint32LE(); // Height + + // Read time header + _readStream->readUint32BE(); // Magic number EMIT + _readStream->readUint32LE(); // Size4 + _readStream->readUint32LE(); // Unknown11 + _frameTime = _readStream->readUint32LE() / 10; // Frame time in microseconds + + return true; +} + +RLFDecoder::Frame RLFDecoder::readNextFrame() { + RLFDecoder::Frame frame; + + _readStream->readUint32BE(); // Magic number MARF + uint32 size = _readStream->readUint32LE(); // Size + _readStream->readUint32LE(); // Unknown1 + _readStream->readUint32LE(); // Unknown2 + uint32 type = _readStream->readUint32BE(); // Either ELHD or ELRH + uint32 headerSize = _readStream->readUint32LE(); // Offset from the beginning of this frame to the frame data. Should always be 28 + _readStream->readUint32LE(); // Unknown3 + + frame.encodedSize = size - headerSize; + frame.encodedData = new int8[frame.encodedSize]; + _readStream->read(frame.encodedData, frame.encodedSize); + + if (type == MKTAG('E', 'L', 'H', 'D')) { + frame.type = Masked; + } else if (type == MKTAG('E', 'L', 'R', 'H')) { + frame.type = Simple; + _completeFrames.push_back(_lastFrameRead); + } else { + warning("Frame %u doesn't have type that can be decoded", _lastFrameRead); + } + + _lastFrameRead++; + return frame; +} + +void RLFDecoder::seekToFrame(int frameNumber) { + assert(!_stream); + assert(frameNumber < (int)_frameCount || frameNumber >= -1); + + if (_nextFrame == frameNumber) + return; + + if (frameNumber < 0) { + _nextFrame = 0; + return; + } + + int closestFrame = _nextFrame; + int distance = (int)frameNumber - _nextFrame; + + if (distance < 0) { + for (uint i = 0; i < _completeFrames.size(); ++i) { + if ((int)_completeFrames[i] > frameNumber) + break; + closestFrame = _completeFrames[i]; + } + } else { + for (uint i = 0; i < _completeFrames.size(); ++i) { + int newDistance = (int)frameNumber - (int)(_completeFrames[i]); + if (newDistance < 0) + break; + if (newDistance < distance) { + closestFrame = _completeFrames[i]; + distance = newDistance; + } + } + } + + for (int i = closestFrame; i < frameNumber; ++i) { + applyFrameToCurrent(i); + } + + _nextFrame = frameNumber; +} + +const Graphics::Surface *RLFDecoder::getFrameData(uint frameNumber) { + assert(!_stream); + assert(frameNumber < _frameCount); + + // Since this method is so expensive, first check to see if we can use + // decodeNextFrame() it's cheap. + if ((int)frameNumber == _nextFrame - 1) { + return &_currentFrameBuffer; + } else if (_nextFrame == (int)frameNumber) { + return decodeNextFrame(); + } + + seekToFrame(frameNumber); + return decodeNextFrame(); +} + +const Graphics::Surface *RLFDecoder::decodeNextFrame() { + assert(_nextFrame < (int)_frameCount); + + if (_stream) { + applyFrameToCurrent(readNextFrame()); + } else { + applyFrameToCurrent(_nextFrame); + } + + _nextFrame++; + return &_currentFrameBuffer; +} + +void RLFDecoder::applyFrameToCurrent(uint frameNumber) { + if (_frames[frameNumber].type == Masked) { + decodeMaskedRunLengthEncoding(_frames[frameNumber].encodedData, (int8 *)_currentFrameBuffer.getPixels(), _frames[frameNumber].encodedSize, _frameBufferByteSize); + } else if (_frames[frameNumber].type == Simple) { + decodeSimpleRunLengthEncoding(_frames[frameNumber].encodedData, (int8 *)_currentFrameBuffer.getPixels(), _frames[frameNumber].encodedSize, _frameBufferByteSize); + } +} + +void RLFDecoder::applyFrameToCurrent(const RLFDecoder::Frame &frame) { + if (frame.type == Masked) { + decodeMaskedRunLengthEncoding(frame.encodedData, (int8 *)_currentFrameBuffer.getPixels(), frame.encodedSize, _frameBufferByteSize); + } else if (frame.type == Simple) { + decodeSimpleRunLengthEncoding(frame.encodedData, (int8 *)_currentFrameBuffer.getPixels(), frame.encodedSize, _frameBufferByteSize); + } +} + +void RLFDecoder::decodeMaskedRunLengthEncoding(int8 *source, int8 *dest, uint32 sourceSize, uint32 destSize) const { + uint32 sourceOffset = 0; + uint32 destOffset = 0; + int16 numberOfCopy = 0; + + while (sourceOffset < sourceSize) { + int8 numberOfSamples = source[sourceOffset]; + sourceOffset++; + + // If numberOfSamples is negative, the next abs(numberOfSamples) samples should + // be copied directly from source to dest + if (numberOfSamples < 0) { + numberOfCopy = -numberOfSamples; + + while (numberOfCopy > 0) { + if (sourceOffset + 1 >= sourceSize) { + return; + } else if (destOffset + 1 >= destSize) { + debug(2, "Frame decoding overflow\n\tsourceOffset=%u\tsourceSize=%u\n\tdestOffset=%u\tdestSize=%u", sourceOffset, sourceSize, destOffset, destSize); + return; + } + + byte r, g, b; + Graphics::colorToRGB >(READ_LE_UINT16(source + sourceOffset), r, g, b); + uint16 destColor = Graphics::RGBToColor >(r, g, b); + WRITE_UINT16(dest + destOffset, destColor); + + sourceOffset += 2; + destOffset += 2; + numberOfCopy--; + } + + // If numberOfSamples is >= 0, move destOffset forward ((numberOfSamples * 2) + 2) + // This function assumes the dest buffer has been memset with 0's. + } else { + if (sourceOffset + 1 >= sourceSize) { + return; + } else if (destOffset + 1 >= destSize) { + debug(2, "Frame decoding overflow\n\tsourceOffset=%u\tsourceSize=%u\n\tdestOffset=%u\tdestSize=%u", sourceOffset, sourceSize, destOffset, destSize); + return; + } + + destOffset += (numberOfSamples * 2) + 2; + } + } +} + +void RLFDecoder::decodeSimpleRunLengthEncoding(int8 *source, int8 *dest, uint32 sourceSize, uint32 destSize) const { + uint32 sourceOffset = 0; + uint32 destOffset = 0; + int16 numberOfCopy = 0; + + while (sourceOffset < sourceSize) { + int8 numberOfSamples = source[sourceOffset]; + sourceOffset++; + + // If numberOfSamples is negative, the next abs(numberOfSamples) samples should + // be copied directly from source to dest + if (numberOfSamples < 0) { + numberOfCopy = -numberOfSamples; + + while (numberOfCopy > 0) { + if (sourceOffset + 1 >= sourceSize) { + return; + } else if (destOffset + 1 >= destSize) { + debug(2, "Frame decoding overflow\n\tsourceOffset=%u\tsourceSize=%u\n\tdestOffset=%u\tdestSize=%u", sourceOffset, sourceSize, destOffset, destSize); + return; + } + + byte r, g, b; + Graphics::colorToRGB >(READ_LE_UINT16(source + sourceOffset), r, g, b); + uint16 destColor = Graphics::RGBToColor >(r, g, b); + WRITE_UINT16(dest + destOffset, destColor); + + sourceOffset += 2; + destOffset += 2; + numberOfCopy--; + } + + // If numberOfSamples is >= 0, copy one sample from source to the + // next (numberOfSamples + 2) dest spots + } else { + if (sourceOffset + 1 >= sourceSize) { + return; + } + + byte r, g, b; + Graphics::colorToRGB >(READ_LE_UINT16(source + sourceOffset), r, g, b); + uint16 sampleColor = Graphics::RGBToColor >(r, g, b); + sourceOffset += 2; + + numberOfCopy = numberOfSamples + 2; + while (numberOfCopy > 0) { + if (destOffset + 1 >= destSize) { + debug(2, "Frame decoding overflow\n\tsourceOffset=%u\tsourceSize=%u\n\tdestOffset=%u\tdestSize=%u", sourceOffset, sourceSize, destOffset, destSize); + return; + } + + WRITE_UINT16(dest + destOffset, sampleColor); + destOffset += 2; + numberOfCopy--; + } + } + } +} + +} // End of namespace ZVision diff --git a/engines/zvision/video/rlf_decoder.h b/engines/zvision/video/rlf_decoder.h new file mode 100644 index 0000000000..dcfd8606c2 --- /dev/null +++ b/engines/zvision/video/rlf_decoder.h @@ -0,0 +1,172 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef ZVISION_RLF_DECODER_H +#define ZVISION_RLF_DECODER_H + +#include "common/file.h" + +#include "graphics/surface.h" + +namespace Common { +class String; +} + +namespace ZVision { + +class RLFDecoder { +public: + RLFDecoder(const Common::String &fileName, bool stream = true); + RLFDecoder(Common::SeekableReadStream *rstream, bool stream); + ~RLFDecoder(); + +private: + enum EncodingType { + Masked, + Simple + }; + + struct Frame { + EncodingType type; + int8 *encodedData; + uint32 encodedSize; + }; + +private: + Common::SeekableReadStream *_readStream; + bool _stream; + uint _lastFrameRead; + + uint _frameCount; + uint _width; + uint _height; + uint32 _frameTime; // In milliseconds + Frame *_frames; + Common::Array _completeFrames; + + int _nextFrame; + Graphics::Surface _currentFrameBuffer; + uint32 _frameBufferByteSize; + +public: + uint frameCount() { + return _frameCount; + } + uint width() { + return _width; + } + uint height() { + return _height; + } + uint32 frameTime() { + return _frameTime; + } + + /** + * Seeks to the frameNumber and updates the internal Surface with + * the new frame data. If frameNumber == -1, it only sets _currentFrame, + * the internal Surface is unchanged. This function requires _stream = false + * + * @param frameNumber The frame number to seek to + */ + void seekToFrame(int frameNumber); + + /** + * Returns the pixel data of the frame specified. It will try to use + * decodeNextFrame() if possible. If not, it uses seekToFrame() to + * update the internal Surface and then returns a pointer to it. + * This function requires _stream = false + * + * @param frameNumber The frame number to get data for + * @return A pointer to the pixel data. Do NOT delete this. + */ + const Graphics::Surface *getFrameData(uint frameNumber); + /** + * Returns the pixel data of current frame and go to next. It is up to the user to + * check if the current frame is valid before calling this. + * IE. Use endOfAnimation() + * + * @return A pointer to the pixel data. Do NOT delete this. + */ + const Graphics::Surface *decodeNextFrame(); + /** + * @return Is the currentFrame is the last frame in the animation? + */ + bool endOfAnimation() { + return _nextFrame == (int)_frameCount; + } + +private: + /** + * Reads in the header of the RLF file + * + * @return Will return false if the header magic number is wrong + */ + bool readHeader(); + /** + * Reads the next frame from the RLF file, stores the data in + * a Frame object, then returns the object + * + * @return A Frame object representing the frame data + */ + Frame readNextFrame(); + + /** + * Applies the frame corresponding to frameNumber on top of _currentFrameBuffer. + * This function requires _stream = false so it can look up the Frame object + * referenced by frameNumber. + * + * @param frameNumber The frame number to apply to _currentFrameBuffer + */ + void applyFrameToCurrent(uint frameNumber); + /** + * Applies the data from a Frame object on top of a _currentFrameBuffer. + * + * @param frame A Frame object to apply to _currentFrameBuffer + */ + void applyFrameToCurrent(const RLFDecoder::Frame &frame); + + /** + * Decode frame data that uses masked run length encoding. This is the encoding + * used by P-frames. + * + * @param source The source pixel data + * @param dest The destination buffer + * @param sourceSize The size of the source pixel data + * @param destSize The size of the destination buffer + */ + void decodeMaskedRunLengthEncoding(int8 *source, int8 *dest, uint32 sourceSize, uint32 destSize) const; + /** + * Decode frame data that uses simple run length encoding. This is the encoding + * used by I-frames. + * + * @param source The source pixel data + * @param dest The destination buffer + * @param sourceSize The size of the source pixel data + * @param destSize The size of the destination buffer + */ + void decodeSimpleRunLengthEncoding(int8 *source, int8 *dest, uint32 sourceSize, uint32 destSize) const; +}; + +} // End of namespace ZVision + +#endif -- cgit v1.2.3 From 7f61a094781256f7c2734aa08637494c1dfac6bf Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Tue, 16 Dec 2014 00:48:16 +0200 Subject: ZVISION: Make the RLF decoder a subclass of the common video decoder This way, the redundant MetaAnimation class can now be removed --- engines/zvision/video/rlf_decoder.cpp | 141 +++++++-------------- engines/zvision/video/rlf_decoder.h | 224 ++++++++++++++-------------------- engines/zvision/video/video.cpp | 20 +++ 3 files changed, 157 insertions(+), 228 deletions(-) (limited to 'engines/zvision/video') diff --git a/engines/zvision/video/rlf_decoder.cpp b/engines/zvision/video/rlf_decoder.cpp index a4f16af9b0..bdb5dc18bc 100644 --- a/engines/zvision/video/rlf_decoder.cpp +++ b/engines/zvision/video/rlf_decoder.cpp @@ -34,75 +34,46 @@ namespace ZVision { -RLFDecoder::RLFDecoder(const Common::String &fileName, bool stream) - : _stream(stream), - _readStream(NULL), - _lastFrameRead(0), - _frameCount(0), - _width(0), - _height(0), - _frameTime(0), - _frames(0), - _nextFrame(0), - _frameBufferByteSize(0) { - - Common::File *_file = new Common::File; - if (!_file->open(fileName)) { - warning("RLF animation file %s could not be opened", fileName.c_str()); - return; - } - - _readStream = _file; - - if (!readHeader()) { - warning("%s is not a RLF animation file. Wrong magic number", fileName.c_str()); - return; - } +RLFDecoder::~RLFDecoder() { + close(); +} - _currentFrameBuffer.create(_width, _height, Graphics::createPixelFormat<565>()); - _frameBufferByteSize = _width * _height * sizeof(uint16); +bool RLFDecoder::loadStream(Common::SeekableReadStream *stream) { + close(); - if (!stream) { - _frames = new Frame[_frameCount]; + addTrack(new RLFVideoTrack(stream)); - // Read in each frame - for (uint i = 0; i < _frameCount; ++i) { - _frames[i] = readNextFrame(); - } - } + return true; } -RLFDecoder::RLFDecoder(Common::SeekableReadStream *rstream, bool stream) - : _stream(stream), - _readStream(rstream), +RLFDecoder::RLFVideoTrack::RLFVideoTrack(Common::SeekableReadStream *stream) + : _readStream(stream), _lastFrameRead(0), _frameCount(0), _width(0), _height(0), _frameTime(0), _frames(0), - _nextFrame(0), + _curFrame(0), _frameBufferByteSize(0) { if (!readHeader()) { - warning("Stream is not a RLF animation. Wrong magic number"); + warning("Not a RLF animation file. Wrong magic number"); return; } _currentFrameBuffer.create(_width, _height, Graphics::createPixelFormat<565>()); _frameBufferByteSize = _width * _height * sizeof(uint16); - if (!stream) { - _frames = new Frame[_frameCount]; + _frames = new Frame[_frameCount]; - // Read in each frame - for (uint i = 0; i < _frameCount; ++i) { - _frames[i] = readNextFrame(); - } + // Read in each frame + for (uint i = 0; i < _frameCount; ++i) { + _frames[i] = readNextFrame(); } } -RLFDecoder::~RLFDecoder() { +RLFDecoder::RLFVideoTrack::~RLFVideoTrack() { for (uint i = 0; i < _frameCount; ++i) { delete[] _frames[i].encodedData; } @@ -111,7 +82,7 @@ RLFDecoder::~RLFDecoder() { _currentFrameBuffer.free(); } -bool RLFDecoder::readHeader() { +bool RLFDecoder::RLFVideoTrack::readHeader() { if (_readStream->readUint32BE() != MKTAG('F', 'E', 'L', 'R')) { return false; } @@ -160,8 +131,8 @@ bool RLFDecoder::readHeader() { return true; } -RLFDecoder::Frame RLFDecoder::readNextFrame() { - RLFDecoder::Frame frame; +RLFDecoder::RLFVideoTrack::Frame RLFDecoder::RLFVideoTrack::readNextFrame() { + RLFDecoder::RLFVideoTrack::Frame frame; _readStream->readUint32BE(); // Magic number MARF uint32 size = _readStream->readUint32LE(); // Size @@ -188,30 +159,30 @@ RLFDecoder::Frame RLFDecoder::readNextFrame() { return frame; } -void RLFDecoder::seekToFrame(int frameNumber) { - assert(!_stream); - assert(frameNumber < (int)_frameCount || frameNumber >= -1); +bool RLFDecoder::RLFVideoTrack::seek(const Audio::Timestamp &time) { + uint frame = getFrameAtTime(time); + assert(frame < (int)_frameCount); - if (_nextFrame == frameNumber) - return; + if ((uint)_curFrame == frame) + return true; - if (frameNumber < 0) { - _nextFrame = 0; - return; + if (frame < 0) { + _curFrame = 0; + return false; } - int closestFrame = _nextFrame; - int distance = (int)frameNumber - _nextFrame; + int closestFrame = _curFrame; + int distance = (int)frame - _curFrame; if (distance < 0) { for (uint i = 0; i < _completeFrames.size(); ++i) { - if ((int)_completeFrames[i] > frameNumber) + if ((int)_completeFrames[i] > frame) break; closestFrame = _completeFrames[i]; } } else { for (uint i = 0; i < _completeFrames.size(); ++i) { - int newDistance = (int)frameNumber - (int)(_completeFrames[i]); + int newDistance = (int)frame - (int)(_completeFrames[i]); if (newDistance < 0) break; if (newDistance < distance) { @@ -221,43 +192,27 @@ void RLFDecoder::seekToFrame(int frameNumber) { } } - for (int i = closestFrame; i < frameNumber; ++i) { + for (uint i = closestFrame; i < frame; ++i) { applyFrameToCurrent(i); } - _nextFrame = frameNumber; -} - -const Graphics::Surface *RLFDecoder::getFrameData(uint frameNumber) { - assert(!_stream); - assert(frameNumber < _frameCount); + _curFrame = frame; - // Since this method is so expensive, first check to see if we can use - // decodeNextFrame() it's cheap. - if ((int)frameNumber == _nextFrame - 1) { - return &_currentFrameBuffer; - } else if (_nextFrame == (int)frameNumber) { - return decodeNextFrame(); - } - - seekToFrame(frameNumber); - return decodeNextFrame(); + return true; } -const Graphics::Surface *RLFDecoder::decodeNextFrame() { - assert(_nextFrame < (int)_frameCount); +const Graphics::Surface *RLFDecoder::RLFVideoTrack::decodeNextFrame() { + // When an animation ends, rewind + if (_curFrame == (int)_frameCount) + seek(Audio::Timestamp(0, getFrameRate().toInt())); + + applyFrameToCurrent(_curFrame); - if (_stream) { - applyFrameToCurrent(readNextFrame()); - } else { - applyFrameToCurrent(_nextFrame); - } - - _nextFrame++; + _curFrame++; return &_currentFrameBuffer; } -void RLFDecoder::applyFrameToCurrent(uint frameNumber) { +void RLFDecoder::RLFVideoTrack::applyFrameToCurrent(uint frameNumber) { if (_frames[frameNumber].type == Masked) { decodeMaskedRunLengthEncoding(_frames[frameNumber].encodedData, (int8 *)_currentFrameBuffer.getPixels(), _frames[frameNumber].encodedSize, _frameBufferByteSize); } else if (_frames[frameNumber].type == Simple) { @@ -265,15 +220,7 @@ void RLFDecoder::applyFrameToCurrent(uint frameNumber) { } } -void RLFDecoder::applyFrameToCurrent(const RLFDecoder::Frame &frame) { - if (frame.type == Masked) { - decodeMaskedRunLengthEncoding(frame.encodedData, (int8 *)_currentFrameBuffer.getPixels(), frame.encodedSize, _frameBufferByteSize); - } else if (frame.type == Simple) { - decodeSimpleRunLengthEncoding(frame.encodedData, (int8 *)_currentFrameBuffer.getPixels(), frame.encodedSize, _frameBufferByteSize); - } -} - -void RLFDecoder::decodeMaskedRunLengthEncoding(int8 *source, int8 *dest, uint32 sourceSize, uint32 destSize) const { +void RLFDecoder::RLFVideoTrack::decodeMaskedRunLengthEncoding(int8 *source, int8 *dest, uint32 sourceSize, uint32 destSize) const { uint32 sourceOffset = 0; uint32 destOffset = 0; int16 numberOfCopy = 0; @@ -320,7 +267,7 @@ void RLFDecoder::decodeMaskedRunLengthEncoding(int8 *source, int8 *dest, uint32 } } -void RLFDecoder::decodeSimpleRunLengthEncoding(int8 *source, int8 *dest, uint32 sourceSize, uint32 destSize) const { +void RLFDecoder::RLFVideoTrack::decodeSimpleRunLengthEncoding(int8 *source, int8 *dest, uint32 sourceSize, uint32 destSize) const { uint32 sourceOffset = 0; uint32 destOffset = 0; int16 numberOfCopy = 0; diff --git a/engines/zvision/video/rlf_decoder.h b/engines/zvision/video/rlf_decoder.h index dcfd8606c2..f0f31c2128 100644 --- a/engines/zvision/video/rlf_decoder.h +++ b/engines/zvision/video/rlf_decoder.h @@ -24,147 +24,109 @@ #define ZVISION_RLF_DECODER_H #include "common/file.h" +#include "video/video_decoder.h" #include "graphics/surface.h" -namespace Common { -class String; -} - namespace ZVision { -class RLFDecoder { +class RLFDecoder : public Video::VideoDecoder { public: - RLFDecoder(const Common::String &fileName, bool stream = true); - RLFDecoder(Common::SeekableReadStream *rstream, bool stream); + RLFDecoder() {} ~RLFDecoder(); -private: - enum EncodingType { - Masked, - Simple - }; - - struct Frame { - EncodingType type; - int8 *encodedData; - uint32 encodedSize; - }; - -private: - Common::SeekableReadStream *_readStream; - bool _stream; - uint _lastFrameRead; - - uint _frameCount; - uint _width; - uint _height; - uint32 _frameTime; // In milliseconds - Frame *_frames; - Common::Array _completeFrames; - - int _nextFrame; - Graphics::Surface _currentFrameBuffer; - uint32 _frameBufferByteSize; - -public: - uint frameCount() { - return _frameCount; - } - uint width() { - return _width; - } - uint height() { - return _height; - } - uint32 frameTime() { - return _frameTime; - } - - /** - * Seeks to the frameNumber and updates the internal Surface with - * the new frame data. If frameNumber == -1, it only sets _currentFrame, - * the internal Surface is unchanged. This function requires _stream = false - * - * @param frameNumber The frame number to seek to - */ - void seekToFrame(int frameNumber); - - /** - * Returns the pixel data of the frame specified. It will try to use - * decodeNextFrame() if possible. If not, it uses seekToFrame() to - * update the internal Surface and then returns a pointer to it. - * This function requires _stream = false - * - * @param frameNumber The frame number to get data for - * @return A pointer to the pixel data. Do NOT delete this. - */ - const Graphics::Surface *getFrameData(uint frameNumber); - /** - * Returns the pixel data of current frame and go to next. It is up to the user to - * check if the current frame is valid before calling this. - * IE. Use endOfAnimation() - * - * @return A pointer to the pixel data. Do NOT delete this. - */ - const Graphics::Surface *decodeNextFrame(); - /** - * @return Is the currentFrame is the last frame in the animation? - */ - bool endOfAnimation() { - return _nextFrame == (int)_frameCount; - } + bool loadStream(Common::SeekableReadStream *stream); private: - /** - * Reads in the header of the RLF file - * - * @return Will return false if the header magic number is wrong - */ - bool readHeader(); - /** - * Reads the next frame from the RLF file, stores the data in - * a Frame object, then returns the object - * - * @return A Frame object representing the frame data - */ - Frame readNextFrame(); - - /** - * Applies the frame corresponding to frameNumber on top of _currentFrameBuffer. - * This function requires _stream = false so it can look up the Frame object - * referenced by frameNumber. - * - * @param frameNumber The frame number to apply to _currentFrameBuffer - */ - void applyFrameToCurrent(uint frameNumber); - /** - * Applies the data from a Frame object on top of a _currentFrameBuffer. - * - * @param frame A Frame object to apply to _currentFrameBuffer - */ - void applyFrameToCurrent(const RLFDecoder::Frame &frame); - - /** - * Decode frame data that uses masked run length encoding. This is the encoding - * used by P-frames. - * - * @param source The source pixel data - * @param dest The destination buffer - * @param sourceSize The size of the source pixel data - * @param destSize The size of the destination buffer - */ - void decodeMaskedRunLengthEncoding(int8 *source, int8 *dest, uint32 sourceSize, uint32 destSize) const; - /** - * Decode frame data that uses simple run length encoding. This is the encoding - * used by I-frames. - * - * @param source The source pixel data - * @param dest The destination buffer - * @param sourceSize The size of the source pixel data - * @param destSize The size of the destination buffer - */ - void decodeSimpleRunLengthEncoding(int8 *source, int8 *dest, uint32 sourceSize, uint32 destSize) const; + class RLFVideoTrack : public FixedRateVideoTrack { + public: + RLFVideoTrack(Common::SeekableReadStream *stream); + ~RLFVideoTrack(); + + 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; } + 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); } + + private: + enum EncodingType { + Masked, + Simple + }; + + struct Frame { + EncodingType type; + int8 *encodedData; + uint32 encodedSize; + }; + + /** + * Reads in the header of the RLF file + * + * @return Will return false if the header magic number is wrong + */ + bool readHeader(); + + /** + * Reads the next frame from the RLF file, stores the data in + * a Frame object, then returns the object + * + * @return A Frame object representing the frame data + */ + Frame readNextFrame(); + + /** + * Applies the frame corresponding to frameNumber on top of _currentFrameBuffer. + * This function requires _stream = false so it can look up the Frame object + * referenced by frameNumber. + * + * @param frameNumber The frame number to apply to _currentFrameBuffer + */ + void applyFrameToCurrent(uint frameNumber); + + /** + * Decode frame data that uses masked run length encoding. This is the encoding + * used by P-frames. + * + * @param source The source pixel data + * @param dest The destination buffer + * @param sourceSize The size of the source pixel data + * @param destSize The size of the destination buffer + */ + void decodeMaskedRunLengthEncoding(int8 *source, int8 *dest, uint32 sourceSize, uint32 destSize) const; + /** + * Decode frame data that uses simple run length encoding. This is the encoding + * used by I-frames. + * + * @param source The source pixel data + * @param dest The destination buffer + * @param sourceSize The size of the source pixel data + * @param destSize The size of the destination buffer + */ + void decodeSimpleRunLengthEncoding(int8 *source, int8 *dest, uint32 sourceSize, uint32 destSize) const; + + uint _lastFrameRead; + + uint _frameCount; + uint _width; + uint _height; + uint32 _frameTime; // In milliseconds + Frame *_frames; + Common::Array _completeFrames; + + int _curFrame; + Graphics::Surface _currentFrameBuffer; + uint32 _frameBufferByteSize; + + Common::SeekableReadStream *_readStream; + }; // RLFVideoTrack }; } // End of namespace ZVision diff --git a/engines/zvision/video/video.cpp b/engines/zvision/video/video.cpp index db6161bf0c..c8f968d975 100644 --- a/engines/zvision/video/video.cpp +++ b/engines/zvision/video/video.cpp @@ -30,9 +30,29 @@ #include "zvision/utility/clock.h" #include "zvision/graphics/render_manager.h" #include "zvision/graphics/subtitles.h" +#include "zvision/video/rlf_decoder.h" +#include "zvision/video/zork_avi_decoder.h" namespace ZVision { +Video::VideoDecoder *ZVision::loadAnimation(const Common::String &fileName) { + Common::String tmpFileName = fileName; + tmpFileName.toLowercase(); + Video::VideoDecoder *animation = NULL; + + if (tmpFileName.hasSuffix(".rlf")) + animation = new RLFDecoder(); + else if (tmpFileName.hasSuffix(".avi")) + animation = new ZorkAVIDecoder(); + else + error("Unknown suffix for animation %s", fileName.c_str()); + + Common::File *_file = getSearchManager()->openFile(tmpFileName); + animation->loadStream(_file); + + return animation; +} + void ZVision::playVideo(Video::VideoDecoder &vid, const Common::Rect &destRect, bool skippable, Subtitle *sub) { Common::Rect dst = destRect; // If destRect is empty, no specific scaling was requested. However, we may choose to do scaling anyway -- cgit v1.2.3 From 7630e3204e3b932d9b43bda7dc4b658405fabf33 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Tue, 16 Dec 2014 01:21:57 +0200 Subject: ZVISION: Move all the remaining utility classes into the core --- engines/zvision/video/video.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'engines/zvision/video') diff --git a/engines/zvision/video/video.cpp b/engines/zvision/video/video.cpp index c8f968d975..189fb22194 100644 --- a/engines/zvision/video/video.cpp +++ b/engines/zvision/video/video.cpp @@ -27,7 +27,7 @@ #include "graphics/surface.h" #include "zvision/zvision.h" -#include "zvision/utility/clock.h" +#include "zvision/core/clock.h" #include "zvision/graphics/render_manager.h" #include "zvision/graphics/subtitles.h" #include "zvision/video/rlf_decoder.h" -- cgit v1.2.3 From fb924089fc5f6968f5c86fc780131f67268e8de6 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Tue, 23 Dec 2014 00:07:17 +0200 Subject: ZVISION: Avoid using color masks for in-game animations This fixes the transparency for some in-game animations. Since colors can be truncated with color masks, and since accurate colors are required for transparency, color masks can't be used. This fixes the transparency of the in-game item examination interface in ZGI --- engines/zvision/video/rlf_decoder.cpp | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'engines/zvision/video') diff --git a/engines/zvision/video/rlf_decoder.cpp b/engines/zvision/video/rlf_decoder.cpp index bdb5dc18bc..d51dee0c6a 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() { @@ -62,7 +60,7 @@ RLFDecoder::RLFVideoTrack::RLFVideoTrack(Common::SeekableReadStream *stream) return; } - _currentFrameBuffer.create(_width, _height, Graphics::createPixelFormat<565>()); + _currentFrameBuffer.create(_width, _height, Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0)); _frameBufferByteSize = _width * _height * sizeof(uint16); _frames = new Frame[_frameCount]; @@ -243,8 +241,10 @@ void RLFDecoder::RLFVideoTrack::decodeMaskedRunLengthEncoding(int8 *source, int8 } byte r, g, b; - Graphics::colorToRGB >(READ_LE_UINT16(source + sourceOffset), r, g, b); - uint16 destColor = Graphics::RGBToColor >(r, g, b); + // NOTE: Color masks can't be used here, since accurate colors + // are required to handle transparency correctly + Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0).colorToRGB(READ_LE_UINT16(source + sourceOffset), r, g, b); + uint16 destColor = Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0).RGBToColor(r, g, b); WRITE_UINT16(dest + destOffset, destColor); sourceOffset += 2; @@ -290,8 +290,10 @@ void RLFDecoder::RLFVideoTrack::decodeSimpleRunLengthEncoding(int8 *source, int8 } byte r, g, b; - Graphics::colorToRGB >(READ_LE_UINT16(source + sourceOffset), r, g, b); - uint16 destColor = Graphics::RGBToColor >(r, g, b); + // NOTE: Color masks can't be used here, since accurate colors + // are required to handle transparency correctly + Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0).colorToRGB(READ_LE_UINT16(source + sourceOffset), r, g, b); + uint16 destColor = Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0).RGBToColor(r, g, b); WRITE_UINT16(dest + destOffset, destColor); sourceOffset += 2; @@ -307,8 +309,10 @@ void RLFDecoder::RLFVideoTrack::decodeSimpleRunLengthEncoding(int8 *source, int8 } byte r, g, b; - Graphics::colorToRGB >(READ_LE_UINT16(source + sourceOffset), r, g, b); - uint16 sampleColor = Graphics::RGBToColor >(r, g, b); + // NOTE: Color masks can't be used here, since accurate colors + // are required to handle transparency correctly + Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0).colorToRGB(READ_LE_UINT16(source + sourceOffset), r, g, b); + uint16 sampleColor = Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0).RGBToColor(r, g, b); sourceOffset += 2; numberOfCopy = numberOfSamples + 2; -- cgit v1.2.3 From eb4645cda855b0ac919124fefc79c580883903d3 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Tue, 23 Dec 2014 00:10:12 +0200 Subject: ZVISION: Spacing --- engines/zvision/video/rlf_decoder.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'engines/zvision/video') diff --git a/engines/zvision/video/rlf_decoder.cpp b/engines/zvision/video/rlf_decoder.cpp index d51dee0c6a..b798093869 100644 --- a/engines/zvision/video/rlf_decoder.cpp +++ b/engines/zvision/video/rlf_decoder.cpp @@ -309,8 +309,8 @@ void RLFDecoder::RLFVideoTrack::decodeSimpleRunLengthEncoding(int8 *source, int8 } byte r, g, b; - // NOTE: Color masks can't be used here, since accurate colors - // are required to handle transparency correctly + // NOTE: Color masks can't be used here, since accurate colors + // are required to handle transparency correctly Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0).colorToRGB(READ_LE_UINT16(source + sourceOffset), r, g, b); uint16 sampleColor = Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0).RGBToColor(r, g, b); sourceOffset += 2; -- cgit v1.2.3 From 15154641ac5ea674a4865d9478074cf1b1d8a36b Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Tue, 23 Dec 2014 01:53:40 +0200 Subject: ZVISION: Move all of the text related code together --- engines/zvision/video/video.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'engines/zvision/video') diff --git a/engines/zvision/video/video.cpp b/engines/zvision/video/video.cpp index 189fb22194..97fbd8721c 100644 --- a/engines/zvision/video/video.cpp +++ b/engines/zvision/video/video.cpp @@ -29,7 +29,7 @@ #include "zvision/zvision.h" #include "zvision/core/clock.h" #include "zvision/graphics/render_manager.h" -#include "zvision/graphics/subtitles.h" +#include "zvision/text/subtitles.h" #include "zvision/video/rlf_decoder.h" #include "zvision/video/zork_avi_decoder.h" -- cgit v1.2.3 From 78ba3e32466992ee7d01aabff493617a6401273e Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Tue, 23 Dec 2014 21:46:20 +0200 Subject: ZVISION: Add error checking when loading in-game animations and videos --- engines/zvision/video/rlf_decoder.cpp | 14 +++++++------- engines/zvision/video/video.cpp | 7 ++++++- 2 files changed, 13 insertions(+), 8 deletions(-) (limited to 'engines/zvision/video') diff --git a/engines/zvision/video/rlf_decoder.cpp b/engines/zvision/video/rlf_decoder.cpp index b798093869..76fd70cf35 100644 --- a/engines/zvision/video/rlf_decoder.cpp +++ b/engines/zvision/video/rlf_decoder.cpp @@ -39,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) @@ -81,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 diff --git a/engines/zvision/video/video.cpp b/engines/zvision/video/video.cpp index 97fbd8721c..50a6fc136a 100644 --- a/engines/zvision/video/video.cpp +++ b/engines/zvision/video/video.cpp @@ -48,7 +48,12 @@ Video::VideoDecoder *ZVision::loadAnimation(const Common::String &fileName) { 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; } -- cgit v1.2.3 From 6afeec129504a16ee67c77b35cd27f0808d566d2 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Tue, 23 Dec 2014 21:55:42 +0200 Subject: ZVISION: Handle animation rewinding outside the RLF encoder --- engines/zvision/video/rlf_decoder.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'engines/zvision/video') diff --git a/engines/zvision/video/rlf_decoder.cpp b/engines/zvision/video/rlf_decoder.cpp index 76fd70cf35..f1ac10bf88 100644 --- a/engines/zvision/video/rlf_decoder.cpp +++ b/engines/zvision/video/rlf_decoder.cpp @@ -200,9 +200,8 @@ bool RLFDecoder::RLFVideoTrack::seek(const Audio::Timestamp &time) { } const Graphics::Surface *RLFDecoder::RLFVideoTrack::decodeNextFrame() { - // When an animation ends, rewind if (_curFrame == (int)_frameCount) - seek(Audio::Timestamp(0, getFrameRate().toInt())); + return NULL; applyFrameToCurrent(_curFrame); -- cgit v1.2.3 From e8e21fabe4dbe4effdfb3df05fd3fae75940f1c5 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Wed, 24 Dec 2014 22:40:54 +0200 Subject: ZVISION: Set all the internal graphics operations to use RGB555 (1/2) This is the first part of the changes to make the engine use RGB555 internally again. This is done to simplify the rendering pipeline - the engine will use RGB555 internally, but will output to RGB565. The overall changes have been broken into two commits, thus this first commit will break all the game colors --- engines/zvision/video/rlf_decoder.cpp | 22 ++++------------------ engines/zvision/video/rlf_decoder.h | 2 +- 2 files changed, 5 insertions(+), 19 deletions(-) (limited to 'engines/zvision/video') diff --git a/engines/zvision/video/rlf_decoder.cpp b/engines/zvision/video/rlf_decoder.cpp index f1ac10bf88..260f912ade 100644 --- a/engines/zvision/video/rlf_decoder.cpp +++ b/engines/zvision/video/rlf_decoder.cpp @@ -64,7 +64,7 @@ RLFDecoder::RLFVideoTrack::RLFVideoTrack(Common::SeekableReadStream *stream) return; } - _currentFrameBuffer.create(_width, _height, Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0)); + _currentFrameBuffer.create(_width, _height, getPixelFormat()); _frameBufferByteSize = _width * _height * sizeof(uint16); _frames = new Frame[_frameCount]; @@ -239,12 +239,7 @@ void RLFDecoder::RLFVideoTrack::decodeMaskedRunLengthEncoding(int8 *source, int8 return; } - byte r, g, b; - // NOTE: Color masks can't be used here, since accurate colors - // are required to handle transparency correctly - Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0).colorToRGB(READ_LE_UINT16(source + sourceOffset), r, g, b); - uint16 destColor = Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0).RGBToColor(r, g, b); - WRITE_UINT16(dest + destOffset, destColor); + WRITE_UINT16(dest + destOffset, READ_LE_UINT16(source + sourceOffset)); sourceOffset += 2; destOffset += 2; @@ -288,12 +283,7 @@ void RLFDecoder::RLFVideoTrack::decodeSimpleRunLengthEncoding(int8 *source, int8 return; } - byte r, g, b; - // NOTE: Color masks can't be used here, since accurate colors - // are required to handle transparency correctly - Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0).colorToRGB(READ_LE_UINT16(source + sourceOffset), r, g, b); - uint16 destColor = Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0).RGBToColor(r, g, b); - WRITE_UINT16(dest + destOffset, destColor); + WRITE_UINT16(dest + destOffset, READ_LE_UINT16(source + sourceOffset)); sourceOffset += 2; destOffset += 2; @@ -307,11 +297,7 @@ void RLFDecoder::RLFVideoTrack::decodeSimpleRunLengthEncoding(int8 *source, int8 return; } - byte r, g, b; - // NOTE: Color masks can't be used here, since accurate colors - // are required to handle transparency correctly - Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0).colorToRGB(READ_LE_UINT16(source + sourceOffset), r, g, b); - uint16 sampleColor = Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0).RGBToColor(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..d56ff2da92 100644 --- a/engines/zvision/video/rlf_decoder.h +++ b/engines/zvision/video/rlf_decoder.h @@ -45,7 +45,7 @@ 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*/ } + Graphics::PixelFormat getPixelFormat() const { return Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0); /* RGB 555 */ } int getCurFrame() const { return _curFrame; } int getFrameCount() const { return _frameCount; } const Graphics::Surface *decodeNextFrame(); -- cgit v1.2.3 From 5f8418394b925adfc62ee6d180515157190a8cd9 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Wed, 24 Dec 2014 22:54:24 +0200 Subject: ZVISION: Set all the internal graphics operations to use RGB555 (2/2) This is the second part of the changes to make the engine use RGB555 internally again. This is done to simplify the rendering pipeline - the engine will use RGB555 internally, but will output to RGB565. The overall changes have been broken into two commits, with this commit finishing all the changes. This is needed, as the game uses RGB555 graphics internally, but its AVI animations (full screen and in-game) use RGB565 --- engines/zvision/video/video.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'engines/zvision/video') diff --git a/engines/zvision/video/video.cpp b/engines/zvision/video/video.cpp index 50a6fc136a..e67e6570c5 100644 --- a/engines/zvision/video/video.cpp +++ b/engines/zvision/video/video.cpp @@ -114,7 +114,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); } } -- cgit v1.2.3 From 36c851d0e47b18205ac7ac91eb33666e4abe95ca Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Thu, 25 Dec 2014 16:22:36 +0200 Subject: ZVISION: Fix frame rate for RLF videos and remove hack in AnimationNode _frameTime refers to msec, not ticks --- engines/zvision/video/rlf_decoder.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'engines/zvision/video') diff --git a/engines/zvision/video/rlf_decoder.h b/engines/zvision/video/rlf_decoder.h index d56ff2da92..740f3fdd43 100644 --- a/engines/zvision/video/rlf_decoder.h +++ b/engines/zvision/video/rlf_decoder.h @@ -53,7 +53,7 @@ private: 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 { -- cgit v1.2.3 From b3712cc877482e150a3532fa0f21f5c03dc839f1 Mon Sep 17 00:00:00 2001 From: Ori Avtalion Date: Sat, 27 Dec 2014 16:36:41 +0200 Subject: ZVISION: Remove dead code (uint is always > 0) --- engines/zvision/video/rlf_decoder.cpp | 5 ----- 1 file changed, 5 deletions(-) (limited to 'engines/zvision/video') diff --git a/engines/zvision/video/rlf_decoder.cpp b/engines/zvision/video/rlf_decoder.cpp index 260f912ade..1478822d00 100644 --- a/engines/zvision/video/rlf_decoder.cpp +++ b/engines/zvision/video/rlf_decoder.cpp @@ -164,11 +164,6 @@ bool RLFDecoder::RLFVideoTrack::seek(const Audio::Timestamp &time) { if ((uint)_curFrame == frame) return true; - if (frame < 0) { - _curFrame = 0; - return false; - } - int closestFrame = _curFrame; int distance = (int)frame - _curFrame; -- cgit v1.2.3 From 02eada1d0ddd5f5c179ca39840bb7f73286df6e1 Mon Sep 17 00:00:00 2001 From: Willem Jan Palenstijn Date: Sat, 27 Dec 2014 23:12:54 +0100 Subject: ZVISION: Fix Zork AVI audio on BE systems --- engines/zvision/video/zork_avi_decoder.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'engines/zvision/video') diff --git a/engines/zvision/video/zork_avi_decoder.cpp b/engines/zvision/video/zork_avi_decoder.cpp index 67fab0a114..5618250d79 100644 --- a/engines/zvision/video/zork_avi_decoder.cpp +++ b/engines/zvision/video/zork_avi_decoder.cpp @@ -45,8 +45,14 @@ void ZorkAVIDecoder::ZorkAVIAudioTrack::queueSound(Common::SeekableReadStream *s 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 { AVIAudioTrack::queueSound(stream); } -- cgit v1.2.3 From f4d5b150f1e4b786f2f6f79a1acd3315da9a8699 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Mon, 29 Dec 2014 12:34:55 +0200 Subject: ZVISION: Show system messages when subtitles are disabled Thanks to Marisa-Chan for spotting this --- engines/zvision/video/video.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'engines/zvision/video') diff --git a/engines/zvision/video/video.cpp b/engines/zvision/video/video.cpp index e67e6570c5..0913b28818 100644 --- a/engines/zvision/video/video.cpp +++ b/engines/zvision/video/video.cpp @@ -29,6 +29,7 @@ #include "zvision/zvision.h" #include "zvision/core/clock.h" #include "zvision/graphics/render_manager.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" @@ -75,6 +76,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(); @@ -106,7 +108,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) { -- cgit v1.2.3 From 7182b4f704a312427dc701ccc8452331ca66faae Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Tue, 30 Dec 2014 03:51:15 +0200 Subject: ZVISION: Initialize the starting frame to -1 in RLF animations --- engines/zvision/video/rlf_decoder.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'engines/zvision/video') diff --git a/engines/zvision/video/rlf_decoder.cpp b/engines/zvision/video/rlf_decoder.cpp index 1478822d00..6e2000f93c 100644 --- a/engines/zvision/video/rlf_decoder.cpp +++ b/engines/zvision/video/rlf_decoder.cpp @@ -56,7 +56,7 @@ RLFDecoder::RLFVideoTrack::RLFVideoTrack(Common::SeekableReadStream *stream) _height(0), _frameTime(0), _frames(0), - _curFrame(0), + _curFrame(-1), _frameBufferByteSize(0) { if (!readHeader()) { -- cgit v1.2.3 From 88ba96aa3cb76c7d251a60f32d41f415a40b3dc4 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Tue, 30 Dec 2014 12:55:19 +0200 Subject: ZVISION: Fix an off-by-one error in the RLF decoder A regression from 7f61a09478. The current frame is the currently displayed frame, not the frame that should be displayed next. Thanks to clone2727 and Marisa-Chan for the explanation and fixes --- engines/zvision/video/rlf_decoder.cpp | 16 ++++++++-------- engines/zvision/video/rlf_decoder.h | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) (limited to 'engines/zvision/video') diff --git a/engines/zvision/video/rlf_decoder.cpp b/engines/zvision/video/rlf_decoder.cpp index 6e2000f93c..db598a25b6 100644 --- a/engines/zvision/video/rlf_decoder.cpp +++ b/engines/zvision/video/rlf_decoder.cpp @@ -56,7 +56,7 @@ RLFDecoder::RLFVideoTrack::RLFVideoTrack(Common::SeekableReadStream *stream) _height(0), _frameTime(0), _frames(0), - _curFrame(-1), + _displayedFrame(-1), _frameBufferByteSize(0) { if (!readHeader()) { @@ -161,11 +161,11 @@ bool RLFDecoder::RLFVideoTrack::seek(const Audio::Timestamp &time) { uint frame = getFrameAtTime(time); assert(frame < (int)_frameCount); - if ((uint)_curFrame == frame) + if ((uint)_displayedFrame == frame) return true; - 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) { @@ -189,18 +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() { - if (_curFrame == (int)_frameCount) + if (_displayedFrame >= (int)_frameCount) return NULL; - applyFrameToCurrent(_curFrame); + _displayedFrame++; + applyFrameToCurrent(_displayedFrame); - _curFrame++; return &_currentFrameBuffer; } diff --git a/engines/zvision/video/rlf_decoder.h b/engines/zvision/video/rlf_decoder.h index 740f3fdd43..8b8cbaecd5 100644 --- a/engines/zvision/video/rlf_decoder.h +++ b/engines/zvision/video/rlf_decoder.h @@ -46,7 +46,7 @@ private: uint16 getWidth() const { return _width; } uint16 getHeight() const { return _height; } Graphics::PixelFormat getPixelFormat() const { return Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0); /* RGB 555 */ } - int getCurFrame() const { return _curFrame; } + int getCurFrame() const { return _displayedFrame; } int getFrameCount() const { return _frameCount; } const Graphics::Surface *decodeNextFrame(); bool isSeekable() const { return true; } @@ -121,7 +121,7 @@ private: Frame *_frames; Common::Array _completeFrames; - int _curFrame; + int _displayedFrame; Graphics::Surface _currentFrameBuffer; uint32 _frameBufferByteSize; -- cgit v1.2.3 From e4969a98f82f151382106b89f170990cb7eed54b Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Wed, 7 Jan 2015 11:31:07 +0200 Subject: ZVISION: Fix typo in include --- engines/zvision/video/video.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'engines/zvision/video') diff --git a/engines/zvision/video/video.cpp b/engines/zvision/video/video.cpp index 0913b28818..3edad7a193 100644 --- a/engines/zvision/video/video.cpp +++ b/engines/zvision/video/video.cpp @@ -29,7 +29,7 @@ #include "zvision/zvision.h" #include "zvision/core/clock.h" #include "zvision/graphics/render_manager.h" -#include "zvision/scripting//script_manager.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" -- cgit v1.2.3 From 4ffaf4df376e6d93c1b5c4c820c975fdee64ec8f Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Wed, 7 Jan 2015 11:39:02 +0200 Subject: ZVISION: Add stubs for the hires VOB MPEG2 videos of ZGI DVD VOB file handling is based on clone2727's work. The lowres videos are played for now, until AC3 sound handling is implemented --- engines/zvision/video/video.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'engines/zvision/video') diff --git a/engines/zvision/video/video.cpp b/engines/zvision/video/video.cpp index 3edad7a193..66a567abb2 100644 --- a/engines/zvision/video/video.cpp +++ b/engines/zvision/video/video.cpp @@ -23,6 +23,11 @@ #include "common/scummsys.h" #include "common/system.h" #include "video/video_decoder.h" +// TODO: Enable once VOB + AC3 support is implemented +#if 0 +//#ifdef USE_MPEG2 +#include "video/mpegps_decoder.h" +#endif #include "engines/util.h" #include "graphics/surface.h" @@ -45,6 +50,12 @@ Video::VideoDecoder *ZVision::loadAnimation(const Common::String &fileName) { animation = new RLFDecoder(); else if (tmpFileName.hasSuffix(".avi")) animation = new ZorkAVIDecoder(); +// TODO: Enable once VOB + AC3 support is implemented +#if 0 +//#ifdef USE_MPEG2 + else if (tmpFileName.hasSuffix(".vob")) + animation = new Video::MPEGPSDecoder(); +#endif else error("Unknown suffix for animation %s", fileName.c_str()); -- cgit v1.2.3 From 899cf4813c7e009e1dbee56be8ad10d20650cf10 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Sat, 10 Jan 2015 21:32:15 +0200 Subject: ZVISION: Change screen resolution for the hires DVD videos to 800x600 Also, this hooks up the MPEG-PS decoder, but only if libmpeg2 is compiled in. The DVD videos are still disabled until AC3 audio support is implemented. The hires DVD videos are encoded a 720x480 resolution, with double the frame rate of the lowres ones (29.97FPS up from 15FPS) --- engines/zvision/video/video.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'engines/zvision/video') diff --git a/engines/zvision/video/video.cpp b/engines/zvision/video/video.cpp index 66a567abb2..d5ffbeb536 100644 --- a/engines/zvision/video/video.cpp +++ b/engines/zvision/video/video.cpp @@ -23,9 +23,7 @@ #include "common/scummsys.h" #include "common/system.h" #include "video/video_decoder.h" -// TODO: Enable once VOB + AC3 support is implemented -#if 0 -//#ifdef USE_MPEG2 +#ifdef USE_MPEG2 #include "video/mpegps_decoder.h" #endif #include "engines/util.h" @@ -50,9 +48,7 @@ Video::VideoDecoder *ZVision::loadAnimation(const Common::String &fileName) { animation = new RLFDecoder(); else if (tmpFileName.hasSuffix(".avi")) animation = new ZorkAVIDecoder(); -// TODO: Enable once VOB + AC3 support is implemented -#if 0 -//#ifdef USE_MPEG2 +#ifdef USE_MPEG2 else if (tmpFileName.hasSuffix(".vob")) animation = new Video::MPEGPSDecoder(); #endif -- cgit v1.2.3 From 3f66f28624812910834600d8a2cecb084dedea9f Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sun, 18 Jan 2015 20:32:55 +0100 Subject: ZVISION: Remove trailing whitespace --- engines/zvision/video/rlf_decoder.cpp | 2 +- engines/zvision/video/video.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'engines/zvision/video') diff --git a/engines/zvision/video/rlf_decoder.cpp b/engines/zvision/video/rlf_decoder.cpp index db598a25b6..040582bcf8 100644 --- a/engines/zvision/video/rlf_decoder.cpp +++ b/engines/zvision/video/rlf_decoder.cpp @@ -197,7 +197,7 @@ bool RLFDecoder::RLFVideoTrack::seek(const Audio::Timestamp &time) { const Graphics::Surface *RLFDecoder::RLFVideoTrack::decodeNextFrame() { if (_displayedFrame >= (int)_frameCount) return NULL; - + _displayedFrame++; applyFrameToCurrent(_displayedFrame); diff --git a/engines/zvision/video/video.cpp b/engines/zvision/video/video.cpp index d5ffbeb536..1cfd0f4197 100644 --- a/engines/zvision/video/video.cpp +++ b/engines/zvision/video/video.cpp @@ -62,7 +62,7 @@ Video::VideoDecoder *ZVision::loadAnimation(const Common::String &fileName) { bool loaded = animation->loadStream(_file); if (!loaded) error("Error loading animation %s", tmpFileName.c_str()); - + return animation; } -- cgit v1.2.3 From 08b6a5b4865453e916709003e3a0b1a032b8e97e Mon Sep 17 00:00:00 2001 From: Fedor Date: Mon, 19 Jan 2015 23:25:40 +0300 Subject: ZVISION: Fix comparison between signed and unsigned integers --- engines/zvision/video/rlf_decoder.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'engines/zvision/video') diff --git a/engines/zvision/video/rlf_decoder.cpp b/engines/zvision/video/rlf_decoder.cpp index 040582bcf8..3e11a70f27 100644 --- a/engines/zvision/video/rlf_decoder.cpp +++ b/engines/zvision/video/rlf_decoder.cpp @@ -169,7 +169,7 @@ bool RLFDecoder::RLFVideoTrack::seek(const Audio::Timestamp &time) { if (distance < 0) { for (uint i = 0; i < _completeFrames.size(); ++i) { - if ((int)_completeFrames[i] > frame) + if (_completeFrames[i] > frame) break; closestFrame = _completeFrames[i]; } -- cgit v1.2.3 From ca83ecd8c22c132da3f9b8963ffb76702692a272 Mon Sep 17 00:00:00 2001 From: Torbjörn Andersson Date: Sat, 24 Jan 2015 14:54:25 +0100 Subject: ZVISION: Fix lag at beginning of cutscenes We have to update _curChunk when decoding audio, otherwise it will decode the entire audio track on the first frame. For the ZGI intro this would take 700-800 ms, and since the audio started playing before the video it looked to me as if it had to play the first bit faster to catch up. Thanks to fuzzie for setting me on the right track with an off-hand remark about the Zork AVI decoder (I was looking at the standard AVI decoder), and for finding the cause a few seconds before I did. --- engines/zvision/video/zork_avi_decoder.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'engines/zvision/video') diff --git a/engines/zvision/video/zork_avi_decoder.cpp b/engines/zvision/video/zork_avi_decoder.cpp index 5618250d79..abf48543c9 100644 --- a/engines/zvision/video/zork_avi_decoder.cpp +++ b/engines/zvision/video/zork_avi_decoder.cpp @@ -39,6 +39,7 @@ 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); @@ -54,9 +55,17 @@ void ZorkAVIDecoder::ZorkAVIAudioTrack::queueSound(Common::SeekableReadStream *s _audStream->queueBuffer((byte *)chunk.data, chunk.size, DisposeAfterUse::YES, flags); } } else { + updateCurChunk = false; AVIAudioTrack::queueSound(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++; + } } void ZorkAVIDecoder::ZorkAVIAudioTrack::resetStream() { -- cgit v1.2.3 From 4e1ffc9434f771d3f43e66104adeea9e0166123c Mon Sep 17 00:00:00 2001 From: Torbjörn Andersson Date: Sat, 24 Jan 2015 14:56:48 +0100 Subject: ZVISION: Delete stream if there is no audio stream to queue to This probably never happens, but is consistent with our common AVI decoder. --- engines/zvision/video/zork_avi_decoder.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'engines/zvision/video') diff --git a/engines/zvision/video/zork_avi_decoder.cpp b/engines/zvision/video/zork_avi_decoder.cpp index abf48543c9..cf8505ec82 100644 --- a/engines/zvision/video/zork_avi_decoder.cpp +++ b/engines/zvision/video/zork_avi_decoder.cpp @@ -58,6 +58,8 @@ void ZorkAVIDecoder::ZorkAVIAudioTrack::queueSound(Common::SeekableReadStream *s updateCurChunk = false; AVIAudioTrack::queueSound(stream); } + } else { + delete stream; } // The superclass always updates _curChunk, whether or not audio has -- cgit v1.2.3 From 53cd90b32c7ad6fe7e1ac5f4c781c5e776bd9348 Mon Sep 17 00:00:00 2001 From: Torbjörn Andersson Date: Thu, 5 Mar 2015 07:28:40 +0100 Subject: ZVISION: Fix GCC signed/unsigned warning --- engines/zvision/video/rlf_decoder.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'engines/zvision/video') diff --git a/engines/zvision/video/rlf_decoder.cpp b/engines/zvision/video/rlf_decoder.cpp index 3e11a70f27..3bbf22edff 100644 --- a/engines/zvision/video/rlf_decoder.cpp +++ b/engines/zvision/video/rlf_decoder.cpp @@ -159,7 +159,7 @@ 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)_displayedFrame == frame) return true; -- cgit v1.2.3