From beb64fe5278c7a97bb52499446a868ad2ec81d77 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 30 Dec 2013 07:33:36 +1100 Subject: VOYEUR: Adding support for manually set backgrounds to RL2 playback --- engines/voyeur/animation.cpp | 56 +++++++++++++++++++++++++++++++++--------- engines/voyeur/animation.h | 36 ++++++++++++++------------- engines/voyeur/voyeur.cpp | 2 ++ engines/voyeur/voyeur_game.cpp | 4 +-- 4 files changed, 67 insertions(+), 31 deletions(-) (limited to 'engines') diff --git a/engines/voyeur/animation.cpp b/engines/voyeur/animation.cpp index 4099ea87bd..0fce36d54b 100644 --- a/engines/voyeur/animation.cpp +++ b/engines/voyeur/animation.cpp @@ -90,11 +90,11 @@ void RL2Decoder::copyDirtyRectsToBuffer(uint8 *dst, uint pitch) { ((RL2VideoTrack *)track)->copyDirtyRectsToBuffer(dst, pitch); } -Graphics::Surface *RL2Decoder::getVideoSurface() { +RL2Decoder::RL2VideoTrack *RL2Decoder::getVideoTrack() { Track *track = getTrack(1); assert(track); - return ((RL2VideoTrack *)track)->getSurface(); + return (RL2VideoTrack *)track; } /*------------------------------------------------------------------------*/ @@ -162,12 +162,11 @@ RL2Decoder::RL2VideoTrack::RL2VideoTrack(const RL2FileHeader &header, RL2AudioTr _surface = new Graphics::Surface(); _surface->create(320, 200, Graphics::PixelFormat::createFormatCLUT8()); - if (header._backSize == 0 || !strncmp((char *)&header._signature, "RLV3", 4)) { - _backSurface = NULL; - } else { - _backSurface = new Graphics::Surface(); - _backSurface->create(320, 200, Graphics::PixelFormat::createFormatCLUT8()); - } + + _backSurface = NULL; + _hasBackFrame = header._backSize != 0 && strncmp((char *)&header._signature, "RLV3", 4); + if (_hasBackFrame) + initBackSurface(); _videoBase = header._videoBase; _dirtyPalette = true; @@ -187,6 +186,11 @@ RL2Decoder::RL2VideoTrack::~RL2VideoTrack() { } } +void RL2Decoder::RL2VideoTrack::initBackSurface() { + _backSurface = new Graphics::Surface(); + _backSurface->create(320, 200, Graphics::PixelFormat::createFormatCLUT8()); +} + bool RL2Decoder::RL2VideoTrack::endOfTrack() const { return getCurFrame() >= getFrameCount(); } @@ -211,7 +215,7 @@ Graphics::PixelFormat RL2Decoder::RL2VideoTrack::getPixelFormat() const { } const Graphics::Surface *RL2Decoder::RL2VideoTrack::decodeNextFrame() { - if (_curFrame == 0 && _backSurface) { + if (_curFrame == 0 && _hasBackFrame) { // Read in the background frame _fileStream->seek(0x324); rl2DecodeFrameWithoutBackground(0); @@ -228,7 +232,7 @@ const Graphics::Surface *RL2Decoder::RL2VideoTrack::decodeNextFrame() { _fileStream->seek(_header._frameSoundSizes[_curFrame], SEEK_CUR); // Decode the graphic data - if (_backSurface) { + if (_hasBackFrame) { if (_curFrame > 0) Common::copy((byte *)_backSurface->getPixels(), (byte *)_backSurface->getPixels() + (320 * 200), (byte *)_surface->getPixels()); @@ -266,22 +270,38 @@ void RL2Decoder::RL2VideoTrack::copyFrame(uint8 *data) { void RL2Decoder::RL2VideoTrack::rl2DecodeFrameWithoutBackground(int screenOffset) { if (screenOffset == -1) screenOffset = _videoBase; - byte *destP = (byte *)_surface->getPixels() + screenOffset; + const byte *srcP = !_backSurface ? NULL : (const byte *)_backSurface->getPixels(); + byte *destP = (byte *)_surface->getPixels(); int frameSize = _surface->w * _surface->h - screenOffset; + // If a background was manually set, copy over the initial part remaining unchanged + if (srcP && screenOffset > 0) { + Common::copy(srcP, srcP + screenOffset, destP); + srcP += screenOffset; + } + destP += screenOffset; + + // Main frame decode loop while (frameSize > 0) { byte nextByte = _fileStream->readByte(); if (nextByte < 0x80) { *destP++ = nextByte; --frameSize; + if (srcP) + ++srcP; } else if (nextByte == 0x80) { int runLength = _fileStream->readByte(); if (runLength == 0) return; runLength = MIN(runLength, frameSize); - Common::fill(destP, destP + runLength, 0); + if (srcP) { + Common::copy(srcP, srcP + runLength, destP); + srcP += runLength; + } else { + Common::fill(destP, destP + runLength, 0); + } destP += runLength; frameSize -= runLength; } else { @@ -291,6 +311,8 @@ void RL2Decoder::RL2VideoTrack::rl2DecodeFrameWithoutBackground(int screenOffset Common::fill(destP, destP + runLength, nextByte & 0x7f); destP += runLength; frameSize -= runLength; + if (srcP) + srcP += runLength; } } } @@ -332,6 +354,16 @@ void RL2Decoder::RL2VideoTrack::rl2DecodeFrameWithBackground() { } } +void RL2Decoder::RL2VideoTrack::setupBackSurface(Graphics::Surface *surface) { + if (!_backSurface) + initBackSurface(); + + assert(surface->w == _backSurface->w && surface->h == _backSurface->h); + const byte *srcP = (const byte *)surface->getPixels(); + byte *destP = (byte *)_backSurface->getPixels(); + Common::copy(srcP, srcP + surface->w * surface->h, destP); +} + /*------------------------------------------------------------------------*/ RL2Decoder::RL2AudioTrack::RL2AudioTrack(const RL2FileHeader &header, Common::SeekableReadStream *stream, Audio::Mixer::SoundType soundType): diff --git a/engines/voyeur/animation.h b/engines/voyeur/animation.h index feaaf2166c..bb3f34a461 100644 --- a/engines/voyeur/animation.h +++ b/engines/voyeur/animation.h @@ -39,7 +39,7 @@ namespace Video { * - voyeur */ class RL2Decoder : public VideoDecoder { - +private: class RL2FileHeader { public: uint32 _form; @@ -65,21 +65,6 @@ class RL2Decoder : public VideoDecoder { bool isValid() const; }; -private: - Audio::Mixer::SoundType _soundType; - RL2FileHeader _header; -public: - RL2Decoder(Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType); - virtual ~RL2Decoder(); - - bool loadStream(Common::SeekableReadStream *stream); - bool loadVideo(int videoId); - - const Common::List *getDirtyRects() const; - void clearDirtyRects(); - void copyDirtyRectsToBuffer(uint8 *dst, uint pitch); - Graphics::Surface *getVideoSurface(); -private: class RL2AudioTrack : public AudioTrack { public: RL2AudioTrack(const RL2FileHeader &header, Common::SeekableReadStream *stream, @@ -120,10 +105,10 @@ private: const Graphics::Surface *decodeNextFrame(); const byte *getPalette() const { _dirtyPalette = false; return _header._palette; } bool hasDirtyPalette() const { return _dirtyPalette; } - const Common::List *getDirtyRects() const { return &_dirtyRects; } void clearDirtyRects() { _dirtyRects.clear(); } void copyDirtyRectsToBuffer(uint8 *dst, uint pitch); + void setupBackSurface(Graphics::Surface *surface); private: Common::SeekableReadStream *_fileStream; @@ -131,6 +116,7 @@ private: RL2AudioTrack *_audioTrack; Graphics::Surface *_surface; Graphics::Surface *_backSurface; + bool _hasBackFrame; mutable bool _dirtyPalette; @@ -145,7 +131,23 @@ private: void copyFrame(uint8 *data); void rl2DecodeFrameWithBackground(); void rl2DecodeFrameWithoutBackground(int screenOffset = -1); + void initBackSurface(); }; + +private: + Audio::Mixer::SoundType _soundType; + RL2FileHeader _header; +public: + RL2Decoder(Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType); + virtual ~RL2Decoder(); + + bool loadStream(Common::SeekableReadStream *stream); + bool loadVideo(int videoId); + + const Common::List *getDirtyRects() const; + void clearDirtyRects(); + void copyDirtyRectsToBuffer(uint8 *dst, uint pitch); + RL2VideoTrack *getVideoTrack(); }; } // End of namespace Video diff --git a/engines/voyeur/voyeur.cpp b/engines/voyeur/voyeur.cpp index dbd48f7a6a..62544ea3b3 100644 --- a/engines/voyeur/voyeur.cpp +++ b/engines/voyeur/voyeur.cpp @@ -555,6 +555,8 @@ void VoyeurEngine::playAVideoDuration(int videoId, int duration) { decoder.loadVideo(videoId); decoder.start(); + decoder.getVideoTrack()->setupBackSurface(&_graphicsManager._screenSurface); + decoder.seek(Audio::Timestamp(_voy._vocSecondsOffset * 1000)); int endFrame = decoder.getCurFrame() + totalFrames; diff --git a/engines/voyeur/voyeur_game.cpp b/engines/voyeur/voyeur_game.cpp index 46b4ef6ce1..ef7a70886f 100644 --- a/engines/voyeur/voyeur_game.cpp +++ b/engines/voyeur/voyeur_game.cpp @@ -497,8 +497,8 @@ void VoyeurEngine::doGossip() { pal->startFade(); // Transfer initial background to video decoder - PictureResource videoFrame(decoder.getVideoSurface()); - _graphicsManager.sDrawPic(bgPic, &videoFrame, Common::Point(-32, -20)); + //PictureResource videoFrame(decoder.getVideoSurface()); + //_graphicsManager.sDrawPic(bgPic, &videoFrame, Common::Point(-32, -20)); flipPageAndWait(); -- cgit v1.2.3