From f0432bdf2568a0390e02ff18dd73ea5296a007e2 Mon Sep 17 00:00:00 2001 From: Thomas Fach-Pedersen Date: Sat, 17 May 2014 17:13:49 +0200 Subject: BLADERUNNER: Split VQA decoder into player and decoder, add Outtake player --- engines/bladerunner/bladerunner.cpp | 51 +---------- engines/bladerunner/bladerunner.h | 6 +- engines/bladerunner/module.mk | 4 +- engines/bladerunner/outtake.cpp | 67 +++++++++++++++ engines/bladerunner/outtake.h | 54 ++++++++++++ engines/bladerunner/vqa_decoder.cpp | 166 +++++++++++++----------------------- engines/bladerunner/vqa_decoder.h | 22 ++--- engines/bladerunner/vqa_player.cpp | 102 ++++++++++++++++++++++ engines/bladerunner/vqa_player.h | 73 ++++++++++++++++ 9 files changed, 374 insertions(+), 171 deletions(-) create mode 100644 engines/bladerunner/outtake.cpp create mode 100644 engines/bladerunner/outtake.h create mode 100644 engines/bladerunner/vqa_player.cpp create mode 100644 engines/bladerunner/vqa_player.h (limited to 'engines/bladerunner') diff --git a/engines/bladerunner/bladerunner.cpp b/engines/bladerunner/bladerunner.cpp index 7e8466c14a..bcf8c090a8 100644 --- a/engines/bladerunner/bladerunner.cpp +++ b/engines/bladerunner/bladerunner.cpp @@ -25,6 +25,7 @@ #include "bladerunner/chapters.h" #include "bladerunner/gameinfo.h" #include "bladerunner/image.h" +#include "bladerunner/outtake.h" #include "bladerunner/settings.h" #include "bladerunner/vqa_decoder.h" @@ -206,56 +207,12 @@ void BladeRunnerEngine::handleEvents() { } } -void BladeRunnerEngine::playOuttake(int id, bool no_localization) { +void BladeRunnerEngine::outtakePlay(int id, bool noLocalization, int container) { Common::String name = _gameInfo->getOuttake(id); - if (no_localization) - name += ".VQA"; - else - name += "_E.VQA"; + OuttakePlayer player(this); - Common::SeekableReadStream *s = getResourceStream(name); - if (!s) - return; - - VQADecoder vqa_decoder(s); - - bool b = vqa_decoder.readHeader(); - if (!b) return; - - uint32 frame_count = 0; - uint32 start_time = 0; - uint32 next_frame_time = 0; - - for (;;) - { - handleEvents(); - // TODO: Handle skips - if (shouldQuit()) - break; - - uint32 cur_time = next_frame_time + 1; - - if (next_frame_time <= cur_time) - { - int frame_number = vqa_decoder.readFrame(); - debug("frame_number: %d", frame_number); - - if (frame_number < 0) - break; - - b = vqa_decoder.decodeFrame((uint16*)_surface1.getPixels()); - - _system->copyRectToScreen(_surface1.getPixels(), _surface1.pitch, 0, 0, _surface1.w, _surface1.h); - _system->updateScreen(); - - ++frame_count; - - if (!next_frame_time) - next_frame_time = cur_time; - next_frame_time = next_frame_time + (60 * 1000) / 15; - } - } + player.play(name, noLocalization, -1); } bool BladeRunnerEngine::openArchive(const Common::String &name) { diff --git a/engines/bladerunner/bladerunner.h b/engines/bladerunner/bladerunner.h index c679b80f29..bf95ca7922 100644 --- a/engines/bladerunner/bladerunner.h +++ b/engines/bladerunner/bladerunner.h @@ -53,12 +53,12 @@ public: int in_script_counter; + Graphics::Surface _surface1; + private: static const int kArchiveCount = 10; MIXArchive _archives[kArchiveCount]; - Graphics::Surface _surface1; - public: BladeRunnerEngine(OSystem *syst); @@ -77,7 +77,7 @@ public: void gameTick(); void handleEvents(); - void playOuttake(int id, bool no_localization); + void outtakePlay(int id, bool no_localization, int container = -1); bool openArchive(const Common::String &name); bool closeArchive(const Common::String &name); diff --git a/engines/bladerunner/module.mk b/engines/bladerunner/module.mk index c0d6416ad6..44e681abf4 100644 --- a/engines/bladerunner/module.mk +++ b/engines/bladerunner/module.mk @@ -9,8 +9,10 @@ MODULE_OBJS = \ detection.o \ gameinfo.o \ image.o \ + outtake.o \ settings.o \ - vqa_decoder.o + vqa_decoder.o \ + vqa_player.o # This module can be built as a plugin ifeq ($(ENABLE_BLADERUNNER), DYNAMIC_PLUGIN) diff --git a/engines/bladerunner/outtake.cpp b/engines/bladerunner/outtake.cpp new file mode 100644 index 0000000000..01ceefad75 --- /dev/null +++ b/engines/bladerunner/outtake.cpp @@ -0,0 +1,67 @@ +/* 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 "bladerunner/outtake.h" + +#include "bladerunner/bladerunner.h" +#include "bladerunner/vqa_player.h" + +#include "common/system.h" + +namespace BladeRunner { + +void OuttakePlayer::play(const Common::String &name, bool noLocalization, int container) { + if (container > 0) { + debug("OuttakePlayer::play TODO"); + return; + } + + Common::String resName; + if (noLocalization) + resName = name + ".VQA"; + else + resName = name + "_E.VQA"; + + _vqaPlayer = new VQAPlayer(_vm, &_vm->_surface1); + _vqaPlayer->open(resName); + + for (;;) { + _vm->handleEvents(); + if (_vm->shouldQuit()) + break; + + int r = _vqaPlayer->update(); + if (r == -3) + break; + + if (r >= 0) { + _vm->_system->copyRectToScreen(_vm->_surface1.getPixels(), _vm->_surface1.pitch, 0, 0, _vm->_surface1.w, _vm->_surface1.h); + _vm->_system->updateScreen(); + _vm->_system->delayMillis(10); + } + } + + delete _vqaPlayer; + _vqaPlayer = nullptr; +} + +}; // End of namespace BladeRunner diff --git a/engines/bladerunner/outtake.h b/engines/bladerunner/outtake.h new file mode 100644 index 0000000000..4e97b1b516 --- /dev/null +++ b/engines/bladerunner/outtake.h @@ -0,0 +1,54 @@ +/* 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_OUTTAKE_H +#define BLADERUNNER_OUTTAKE_H + +#include "common/str.h" + +#include "graphics/surface.h" + +namespace BladeRunner { + +class BladeRunnerEngine; +class VQAPlayer; + +class OuttakePlayer { + BladeRunnerEngine *_vm; + + bool _isVQAOpen; + VQAPlayer *_vqaPlayer; + Graphics::Surface *_surface; + +public: + OuttakePlayer(BladeRunnerEngine *vm) : + _vm(vm), + _isVQAOpen(false), + _vqaPlayer(nullptr) + {} + + void play(const Common::String &name, bool noLocalization, int container); +}; + +}; // End of namespace BladeRunner + +#endif diff --git a/engines/bladerunner/vqa_decoder.cpp b/engines/bladerunner/vqa_decoder.cpp index 46e45de1a7..c297935ab9 100644 --- a/engines/bladerunner/vqa_decoder.cpp +++ b/engines/bladerunner/vqa_decoder.cpp @@ -66,17 +66,13 @@ namespace BladeRunner { #define kWVQA 0x57565141 #define kZBUF 0x5A425546 -VQADecoder::VQADecoder(Common::SeekableReadStream *s) - : _s(s), +VQADecoder::VQADecoder() + : _s(nullptr), _frame(0), _zbuf(0), _codebook(0), _cbfz(0), _vptr(0), - _curFrame(-1), - _curLoop(-1), - _loopSpecial(-1), - _loopDefault(-1), _hasView(false), _audioFrame(0), _maxVIEWChunkSize(0), @@ -126,7 +122,7 @@ bool readIFFChunkHeader(Common::SeekableReadStream *s, IFFChunkHeader *ts) ts->size = s->readUint32BE(); // if (ts->size != roundup(ts->size)) - // debug("%s: %d\n", strTag(ts->id), ts->size); + // debug("%s: %d", strTag(ts->id), ts->size); return true; } @@ -144,26 +140,27 @@ const char *strTag(uint32 tag) return s; } -bool VQADecoder::readHeader() +bool VQADecoder::open(Common::SeekableReadStream *s) { IFFChunkHeader chd; uint32 type; bool rc; - readIFFChunkHeader(_s, &chd); + readIFFChunkHeader(s, &chd); if (chd.id != kFORM || !chd.size) return false; - type = _s->readUint32BE(); + type = s->readUint32BE(); if (type != kWVQA) return false; + _s = s; do { if (!readIFFChunkHeader(_s, &chd)) return false; - debug("\t%s : %x\n", strTag(chd.id), chd.size); + debug("\t%s : %x", strTag(chd.id), chd.size); rc = false; switch (chd.id) @@ -177,21 +174,21 @@ bool VQADecoder::readHeader() case kMSCI: rc = readMSCI(chd.size); break; case kVQHD: rc = readVQHD(chd.size); break; default: - debug("Unhandled chunk '%s'\n", strTag(chd.id)); + debug("Unhandled chunk '%s'", strTag(chd.id)); _s->skip(roundup(chd.size)); rc = true; } if (!rc) { - debug("failed to handle chunk %s\n", strTag(chd.id)); - return false; + debug("failed to handle chunk %s", strTag(chd.id)); + return -1; } } while (chd.id != kFINF); for (int i = 0; i != _loopInfo.loopCount; ++i) { - debug("LOOP %2d: %4d %4d %s\n", i, + debug("LOOP %2d: %4d %4d %s", i, _loopInfo.loops[i].begin, _loopInfo.loops[i].end, _loopInfo.loops[i].name.c_str()); @@ -229,32 +226,32 @@ bool VQADecoder::readVQHD(uint32 size) if (_header.offset_x || _header.offset_y) { - debug("_header.offset_x, _header.offset_y: %d %d\n", _header.offset_x, _header.offset_y); + debug("_header.offset_x, _header.offset_y: %d %d", _header.offset_x, _header.offset_y); } // if (_header.unk3 || _header.unk4 != 4 || _header.unk5 || _header.flags != 0x0014) { - debug("_header.version %d\n", _header.version); - debug("_header.flags %04x\n", _header.flags); - debug("_header.numFrames %d\n", _header.numFrames); - debug("_header.width %d\n", _header.width); - debug("_header.height %d\n", _header.height); - debug("_header.blockW %d\n", _header.blockW); - debug("_header.blockH %d\n", _header.blockH); - debug("_header.frameRate %d\n", _header.frameRate); - debug("_header.cbParts %d\n", _header.cbParts); - debug("_header.colors %d\n", _header.colors); - debug("_header.maxBlocks %d\n", _header.maxBlocks); - debug("_header.offsetX %d\n", _header.offset_x); - debug("_header.offsetY %d\n", _header.offset_y); - debug("_header.maxVPTRSize %d\n", _header.maxVPTRSize); - debug("_header.freq %d\n", _header.freq); - debug("_header.channels %d\n", _header.channels); - debug("_header.bits %d\n", _header.bits); - debug("_header.unk3 %d\n", _header.unk3); - debug("_header.unk4 %d\n", _header.unk4); - debug("_header.maxCBFZSize %d\n", _header.maxCBFZSize); - debug("_header.unk5 %d\n", _header.unk5); + debug("_header.version %d", _header.version); + debug("_header.flags %04x", _header.flags); + debug("_header.numFrames %d", _header.numFrames); + debug("_header.width %d", _header.width); + debug("_header.height %d", _header.height); + debug("_header.blockW %d", _header.blockW); + debug("_header.blockH %d", _header.blockH); + debug("_header.frameRate %d", _header.frameRate); + debug("_header.cbParts %d", _header.cbParts); + debug("_header.colors %d", _header.colors); + debug("_header.maxBlocks %d", _header.maxBlocks); + debug("_header.offsetX %d", _header.offset_x); + debug("_header.offsetY %d", _header.offset_y); + debug("_header.maxVPTRSize %d", _header.maxVPTRSize); + debug("_header.freq %d", _header.freq); + debug("_header.channels %d", _header.channels); + debug("_header.bits %d", _header.bits); + debug("_header.unk3 %d", _header.unk3); + debug("_header.unk4 %d", _header.unk4); + debug("_header.maxCBFZSize %d", _header.maxCBFZSize); + debug("_header.unk5 %d", _header.unk5); } // exit(-1); @@ -289,19 +286,19 @@ bool VQADecoder::readMSCI(uint32 size) { case kVIEW: _maxVIEWChunkSize = size; - debug("max VIEW size: %08x\n", _maxVIEWChunkSize); + debug("max VIEW size: %08x", _maxVIEWChunkSize); break; case kZBUF: _maxZBUFChunkSize = size; _zbufChunk = new uint8[roundup(_maxZBUFChunkSize)]; - debug("max ZBUF size: %08x\n", _maxZBUFChunkSize); + debug("max ZBUF size: %08x", _maxZBUFChunkSize); break; case kAESC: _maxAESCChunkSize = size; - debug("max AESC size: %08x\n", _maxAESCChunkSize); + debug("max AESC size: %08x", _maxAESCChunkSize); break; default: - debug("Unknown tag in MSCT: %s\n", strTag(tag)); + debug("Unknown tag in MSCT: %s", strTag(tag)); } uint32 zero; @@ -336,7 +333,7 @@ bool VQADecoder::readLINF(uint32 size) _loopInfo.loops[i].begin = _s->readUint16LE(); _loopInfo.loops[i].end = _s->readUint16LE(); - // debug("Loop %d: %04x %04x\n", i, _loopInfo.loops[i].begin, _loopInfo.loops[i].end); + // debug("Loop %d: %04x %04x", i, _loopInfo.loops[i].begin, _loopInfo.loops[i].end); } return true; @@ -363,7 +360,7 @@ bool VQADecoder::readCINF(uint32 size) uint32 b; a = _s->readUint16LE(); b = _s->readUint32LE(); - debug("%4d %08x\n", a, b); + debug("%4d %08x", a, b); } return true; @@ -384,7 +381,7 @@ bool VQADecoder::readFINF(uint32 size) for (uint32 i = 0; i != _header.numFrames; ++i) { uint32 diff = _frameInfo[i] - last; - debug("_frameInfo[%4d] = 0x%08x - %08x\n", i, _frameInfo[i], diff); + debug("_frameInfo[%4d] = 0x%08x - %08x", i, _frameInfo[i], diff); last = _frameInfo[i]; } } @@ -449,57 +446,24 @@ bool VQADecoder::readMFCI(uint32 size) return true; } -int VQADecoder::readFrame() +bool VQADecoder::readFrame() { - // debug("VQADecoder::readFrame(): %d, %d, %d, %d\n", _loopDefault, _loopSpecial, _curLoop, _curFrame); - - if (_loopInfo.loopCount) - { - if (_loopSpecial >= 0) - { - _curLoop = _loopSpecial; - _loopSpecial = -1; - - _curFrame = _loopInfo.loops[_curLoop].begin; - seekToFrame(_curFrame); - } - else if (_curLoop == -1 && _loopDefault >= 0) - { - _curLoop = _loopDefault; - _curFrame = _loopInfo.loops[_curLoop].begin; - seekToFrame(_curFrame); - } - else if (_curLoop >= -1 && _curFrame == _loopInfo.loops[_curLoop].end) - { - if (_loopDefault == -1) - return -1; - - _curLoop = _loopDefault; - _curFrame = _loopInfo.loops[_curLoop].begin; - seekToFrame(_curFrame); - } - else - ++_curFrame; - } - else - ++_curFrame; - - if (_curFrame >= _header.numFrames) - return -1; - IFFChunkHeader chd; + if (!_s) + return false; + _hasView = false; if (remain(_s) < 8) { - debug("remain: %d\n", remain(_s)); - return -1; + debug("remain: %d", remain(_s)); + return false; } do { if (!readIFFChunkHeader(_s, &chd)) { - debug("Error reading chunk header\n"); - return -1; + debug("Error reading chunk header"); + return false; } // debug("%s ", strTag(chd.id)); @@ -522,12 +486,12 @@ int VQADecoder::readFrame() if (!rc) { - debug("Error handling chunk %s\n", strTag(chd.id)); - return -1; + debug("Error handling chunk %s", strTag(chd.id)); + return false; } } while (chd.id != kVQFR); - return _curFrame; + return true; } @@ -551,7 +515,7 @@ bool VQADecoder::readSND2(uint32 size) { if (size != 735) { - debug("audio frame size: %d\n", size); + debug("audio frame size: %d", size); return false; } @@ -592,7 +556,7 @@ bool VQADecoder::readVQFR(uint32 size) if (!rc) { - debug("VQFR: error handling chunk %s\n", strTag(chd.id)); + debug("VQFR: error handling chunk %s", strTag(chd.id)); return false; } } @@ -620,7 +584,7 @@ bool VQADecoder::readVQFL(uint32 size) if (!rc) { - debug("VQFL: error handling chunk %s\n", strTag(chd.id)); + debug("VQFL: error handling chunk %s", strTag(chd.id)); return false; } } @@ -632,7 +596,7 @@ bool VQADecoder::readCBFZ(uint32 size) { if (size > _header.maxCBFZSize) { - debug("%d > %d\n", size, _header.maxCBFZSize); + debug("%d > %d", size, _header.maxCBFZSize); return false; } @@ -698,7 +662,7 @@ int decodeZBUF_partial(uint8 *src, uint16 *curZBUF, uint32 srcLen) bool VQADecoder::readZBUF(uint32 size) { if (size > _maxZBUFChunkSize) { - debug("VQA ERROR: ZBUF chunk size: %08x > %08x\n", size, _maxZBUFChunkSize); + debug("VQA ERROR: ZBUF chunk size: %08x > %08x", size, _maxZBUFChunkSize); _s->skip(roundup(size)); return false; } @@ -713,7 +677,7 @@ bool VQADecoder::readZBUF(uint32 size) if (width != _header.width || height != _header.height) { - debug("%d, %d, %d, %d\n", width, height, complete, unk0); + debug("%d, %d, %d, %d", width, height, complete, unk0); _s->skip(roundup(remain)); return false; } @@ -828,18 +792,6 @@ void VQADecoder::VPTRWriteBlock(uint16 *frame, unsigned int dstBlock, unsigned i while (--count); } -void VQADecoder::setLoopSpecial(int loop, bool wait) -{ - _loopSpecial = loop; - if (!wait) - _curLoop = -1; -} - -void VQADecoder::setLoopDefault(int loop) -{ - _loopDefault = loop; -} - bool VQADecoder::seekToFrame(int frame) { if (frame < 0 || frame >= _header.numFrames) @@ -913,7 +865,7 @@ bool VQADecoder::decodeFrame(uint16 *frame) dstBlock += count; break; default: - debug("Undefined case %d\n", command >> 13); + debug("Undefined case %d", command >> 13); } } diff --git a/engines/bladerunner/vqa_decoder.h b/engines/bladerunner/vqa_decoder.h index cd0123e20a..ab1f9efe4d 100644 --- a/engines/bladerunner/vqa_decoder.h +++ b/engines/bladerunner/vqa_decoder.h @@ -20,8 +20,8 @@ * */ -#ifndef BLADERUNNER_VQA_H -#define BLADERUNNER_VQA_H +#ifndef BLADERUNNER_VQA_DECODER_H +#define BLADERUNNER_VQA_DECODER_H #include "common/debug.h" #include "common/str.h" @@ -103,11 +103,6 @@ class VQADecoder uint32 *_frameInfo; - int _curFrame; - int _curLoop; - int _loopSpecial; - int _loopDefault; - uint32 _maxVIEWChunkSize; uint32 _maxZBUFChunkSize; uint32 _maxAESCChunkSize; @@ -140,16 +135,15 @@ class VQADecoder bool readLITE(uint32 size); public: - VQADecoder(Common::SeekableReadStream *r); + VQADecoder(); ~VQADecoder(); - bool readHeader(); - int readFrame(); + bool open(Common::SeekableReadStream *s); + bool readFrame(); - void VPTRWriteBlock(uint16 *frame, unsigned int dst_block, unsigned int src_block, int count, bool alpha = false) const; + int getFrameTime() { return 1000 / _header.frameRate; } - void setLoopSpecial(int loop, bool wait); - void setLoopDefault(int loop); + void VPTRWriteBlock(uint16 *frame, unsigned int dstBlock, unsigned int srcBlock, int count, bool alpha = false) const; bool seekToFrame(int frame); bool decodeFrame(uint16 *frame); @@ -158,6 +152,8 @@ public: // bool get_view(view_t *view); bool getZBUF(uint16 *zbuf); + + friend class VQAPlayer; }; }; // End of namespace BladeRunner diff --git a/engines/bladerunner/vqa_player.cpp b/engines/bladerunner/vqa_player.cpp new file mode 100644 index 0000000000..8b614813a7 --- /dev/null +++ b/engines/bladerunner/vqa_player.cpp @@ -0,0 +1,102 @@ +/* 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 "bladerunner/vqa_player.h" + +#include "bladerunner/bladerunner.h" + +#include "common/system.h" + +namespace BladeRunner { + +bool VQAPlayer::open(const Common::String &name) { + _s = _vm->getResourceStream(name); + if (!_s) + return false; + + if(!_decoder.open(_s)) { + delete _s; + _s = nullptr; + return false; + } + + return true; +} + +int VQAPlayer::update() { + uint32 now = _vm->_system->getMillis(); + + if (_nextFrameTime == 0) + _nextFrameTime = now; + + if (now < _nextFrameTime) + return -1; + + _nextFrameTime += 1000 / _decoder._header.frameRate; + + if (_decoder._loopInfo.loopCount) { + if (_loopSpecial >= 0) { + _curLoop = _loopSpecial; + _loopSpecial = -3; + + _curFrame = _decoder._loopInfo.loops[_curLoop].begin; + _decoder.seekToFrame(_curFrame); + } else if (_curLoop == -1 && _loopDefault >= 0) { + _curLoop = _loopDefault; + _curFrame = _decoder._loopInfo.loops[_curLoop].begin; + _decoder.seekToFrame(_curFrame); + } else if (_curLoop >= 0 && _curFrame == _decoder._loopInfo.loops[_curLoop].end) { + if (_loopDefault == -1) + return -3; + + _curLoop = _loopDefault; + _curFrame = _decoder._loopInfo.loops[_curLoop].begin; + _decoder.seekToFrame(_curFrame); + } + else + ++_curFrame; + } + else + ++_curFrame; + + if (_curFrame >= _decoder._header.numFrames) + return -3; + + _decoder.readFrame(); + _decoder.decodeFrame((uint16*)_surface->getPixels()); + + return _curFrame; +} + +void VQAPlayer::setLoopSpecial(int loop, bool wait) +{ + _loopSpecial = loop; + if (!wait) + _curLoop = -1; +} + +void VQAPlayer::setLoopDefault(int loop) +{ + _loopDefault = loop; +} + +}; // End of namespace BladeRunner diff --git a/engines/bladerunner/vqa_player.h b/engines/bladerunner/vqa_player.h new file mode 100644 index 0000000000..2d7d6822b3 --- /dev/null +++ b/engines/bladerunner/vqa_player.h @@ -0,0 +1,73 @@ +/* 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_PLAYER_H +#define BLADERUNNER_VQA_PLAYER_H + +#include "bladerunner/vqa_decoder.h" + +#include "audio/audiostream.h" + +#include "graphics/surface.h" + +namespace BladeRunner { + +class BladeRunnerEngine; + +class VQAPlayer { + BladeRunnerEngine *_vm; + Common::SeekableReadStream *_s; + VQADecoder _decoder; + Graphics::Surface *_surface; + Audio::QueuingAudioStream *_audioStream; + + int _curFrame; + int _curLoop; + int _loopSpecial; + int _loopDefault; + + uint32 _nextFrameTime; + +public: + + VQAPlayer(BladeRunnerEngine *vm, Graphics::Surface *surface) + : _vm(vm), + _s(nullptr), + _surface(surface), + _audioStream(nullptr), + _curFrame(-1), + _curLoop(-1), + _loopSpecial(-1), + _loopDefault(-1), + _nextFrameTime(0) + {} + + bool open(const Common::String &name); + int update(); + + void setLoopSpecial(int loop, bool wait); + void setLoopDefault(int loop); +}; + +}; // End of namespace BladeRunner + +#endif -- cgit v1.2.3