VOYEUR: Adding support for manually set backgrounds to RL2 playback

This commit is contained in:
Paul Gilbert 2013-12-30 07:33:36 +11:00
parent 3fd1abbe32
commit beb64fe527
4 changed files with 67 additions and 31 deletions

View File

@ -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):

View File

@ -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<Common::Rect> *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<Common::Rect> *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<Common::Rect> *getDirtyRects() const;
void clearDirtyRects();
void copyDirtyRectsToBuffer(uint8 *dst, uint pitch);
RL2VideoTrack *getVideoTrack();
};
} // End of namespace Video

View File

@ -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;

View File

@ -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();