/* 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 BLADERUNNER_VQA_DECODER_H #define BLADERUNNER_VQA_DECODER_H #include "bladerunner/adpcm_decoder.h" #include "audio/audiostream.h" #include "common/debug.h" #include "common/str.h" #include "common/stream.h" #include "common/types.h" #include "graphics/surface.h" #include "video/video_decoder.h" #include "aesc.h" namespace BladeRunner { class Lights; class View; class ZBuffer; enum VQADecoderSkipFlags { kVQAReadCodebook = 1, kVQAReadVectorPointerTable = 2, kVQAReadCustom = 4, kVQAReadVideo = kVQAReadCodebook|kVQAReadVectorPointerTable|kVQAReadCustom, kVQAReadAudio = 8, kVQAReadAll = kVQAReadVideo|kVQAReadAudio }; class VQADecoder { public: VQADecoder(Graphics::Surface *surface); ~VQADecoder(); bool loadStream(Common::SeekableReadStream *s); void readFrame(int frame, uint readFlags = kVQAReadAll); void decodeVideoFrame(int frame, bool forceDraw = false); void decodeZBuffer(ZBuffer *zbuffer); Audio::SeekableAudioStream *decodeAudioFrame(); void decodeView(View *view); void decodeAESC(AESC *aesc); void decodeLights(Lights *lights); uint16 numFrames() const { return _header.numFrames; } uint8 frameRate() const { return _header.frameRate; } uint16 offsetX() const { return _header.offsetX; } uint16 offsetY() const { return _header.offsetY; } bool hasAudio() const { return _header.channels != 0; } uint16 frequency() const { return _header.freq; } bool getLoopBeginAndEndFrame(int loop, int *begin, int *end); protected: private: struct Header { uint16 version; // 0x00 uint16 flags; // 0x02 uint16 numFrames; // 0x04 uint16 width; // 0x06 uint16 height; // 0x08 uint8 blockW; // 0x0A uint8 blockH; // 0x0B uint8 frameRate; // 0x0C uint8 cbParts; // 0x0D uint16 colors; // 0x0E uint16 maxBlocks; // 0x10 uint16 offsetX; // 0x12 uint16 offsetY; // 0x14 uint16 maxVPTRSize; // 0x16 uint16 freq; // 0x18 uint8 channels; // 0x1A uint8 bits; // 0x1B uint32 unk3; // 0x1C uint16 unk4; // 0x20 uint32 maxCBFZSize; // 0x22 uint32 unk5; // 0x26 // 0x2A }; struct Loop { uint16 begin; uint16 end; Common::String name; Loop() : begin(0), end(0) {} }; struct LoopInfo { uint16 loopCount; uint32 flags; Loop *loops; LoopInfo() : loopCount(0), loops(nullptr) {} ~LoopInfo() { delete[] loops; } }; struct CodebookInfo { uint16 frame; uint32 size; uint8 *data; }; class VQAVideoTrack; class VQAAudioTrack; Common::SeekableReadStream *_s; Graphics::Surface *_surface; Header _header; int _readingFrame; int _decodingFrame; LoopInfo _loopInfo; Common::Array _codebooks; uint32 *_frameInfo; uint32 _maxVIEWChunkSize; uint32 _maxZBUFChunkSize; uint32 _maxAESCChunkSize; VQAVideoTrack *_videoTrack; VQAAudioTrack *_audioTrack; void readPacket(uint readFlags); bool readVQHD(Common::SeekableReadStream *s, uint32 size); bool readMSCI(Common::SeekableReadStream *s, uint32 size); bool readMFCI(Common::SeekableReadStream *s, uint32 size); bool readLINF(Common::SeekableReadStream *s, uint32 size); bool readCINF(Common::SeekableReadStream *s, uint32 size); bool readFINF(Common::SeekableReadStream *s, uint32 size); bool readLNIN(Common::SeekableReadStream *s, uint32 size); bool readCLIP(Common::SeekableReadStream *s, uint32 size); CodebookInfo &codebookInfoForFrame(int frame); class VQAVideoTrack { public: VQAVideoTrack(VQADecoder *vqaDecoder, Graphics::Surface *surface); ~VQAVideoTrack(); uint16 getWidth() const; uint16 getHeight() const; int getFrameCount() const; void decodeVideoFrame(bool forceDraw); void decodeZBuffer(ZBuffer *zbuffer); void decodeView(View *view); void decodeAESC(AESC *aesc); void decodeLights(Lights *lights); bool readVQFR(Common::SeekableReadStream *s, uint32 size, uint readFlags); bool readVPTR(Common::SeekableReadStream *s, uint32 size); bool readVQFL(Common::SeekableReadStream *s, uint32 size, uint readFlags); bool readCBFZ(Common::SeekableReadStream *s, uint32 size); bool readZBUF(Common::SeekableReadStream *s, uint32 size); bool readVIEW(Common::SeekableReadStream *s, uint32 size); bool readAESC(Common::SeekableReadStream *s, uint32 size); bool readLITE(Common::SeekableReadStream *s, uint32 size); protected: Common::Rational getFrameRate() const; bool useAudioSync() const { return false; } private: VQADecoder *_vqaDecoder; Graphics::Surface *_surface; bool _hasNewFrame; uint16 _numFrames; uint16 _width, _height; uint8 _blockW, _blockH; uint8 _frameRate; uint16 _maxBlocks; uint16 _offsetX, _offsetY; uint16 _maxVPTRSize; uint32 _maxCBFZSize; uint32 _maxZBUFChunkSize; uint8 *_codebook; uint8 *_cbfz; bool _zbufChunkComplete; uint32 _zbufChunkSize; uint8 *_zbufChunk; uint32 _vpointerSize; uint8 *_vpointer; int _curFrame; uint8 *_viewData; uint32 _viewDataSize; uint8 *_lightsData; uint32 _lightsDataSize; uint8 *_aescData; uint32 _aescDataSize; void VPTRWriteBlock(uint16 *frame, unsigned int dstBlock, unsigned int srcBlock, int count, bool alpha = false); bool decodeFrame(uint16 *frame); }; class VQAAudioTrack { public: VQAAudioTrack(VQADecoder *vqaDecoder); ~VQAAudioTrack(); bool readSND2(Common::SeekableReadStream *s, uint32 size); bool readSN2J(Common::SeekableReadStream *s, uint32 size); Audio::SeekableAudioStream *decodeAudioFrame(); protected: private: uint16 _frequency; ADPCMWestwoodDecoder _adpcmDecoder; uint8 _compressedAudioFrame[735]; }; }; } // End of namespace BladeRunner #endif