diff options
author | Peter Kohaut | 2017-03-29 18:47:38 +0200 |
---|---|---|
committer | Peter Kohaut | 2017-03-29 18:48:46 +0200 |
commit | 5f36e65855458a7f146621d99ab09aa049cc6916 (patch) | |
tree | ea66de80170f133b7b34f157e0f4cddf0dd8c6e6 | |
parent | d4ff2ddf1073e13f42be8fd2918a83d198a8b00c (diff) | |
download | scummvm-rg350-5f36e65855458a7f146621d99ab09aa049cc6916.tar.gz scummvm-rg350-5f36e65855458a7f146621d99ab09aa049cc6916.tar.bz2 scummvm-rg350-5f36e65855458a7f146621d99ab09aa049cc6916.zip |
BLADERUNNER: zbuffer is now updated between scene changes
updated vqa player udpate code
fixed some warnings
audio preloading still needs some work
-rw-r--r-- | engines/bladerunner/actor.cpp | 4 | ||||
-rw-r--r-- | engines/bladerunner/bladerunner.cpp | 19 | ||||
-rw-r--r-- | engines/bladerunner/script/scene/rc01.cpp | 2 | ||||
-rw-r--r-- | engines/bladerunner/vqa_decoder.cpp | 27 | ||||
-rw-r--r-- | engines/bladerunner/vqa_decoder.h | 5 | ||||
-rw-r--r-- | engines/bladerunner/vqa_player.cpp | 176 | ||||
-rw-r--r-- | engines/bladerunner/vqa_player.h | 28 | ||||
-rw-r--r-- | engines/bladerunner/zbuffer.cpp | 8 |
8 files changed, 129 insertions, 140 deletions
diff --git a/engines/bladerunner/actor.cpp b/engines/bladerunner/actor.cpp index dd11967e4b..d4613c1be0 100644 --- a/engines/bladerunner/actor.cpp +++ b/engines/bladerunner/actor.cpp @@ -1163,9 +1163,9 @@ bool Actor::walkFindU2(Vector3 *newDestination, float targetWidth, int destinati bool Actor::walkToU(const Vector3 &destination, float distance) { Vector3 out; - bool isRunning; + bool flagIsRunning; if (_walkInfo->findU1(_id, destination, distance, &out)) { - loopWalk(out, 0, false, false, _position, 0.0f, 24.0f, false, &isRunning, false); + loopWalk(out, 0, false, false, _position, 0.0f, 24.0f, false, &flagIsRunning, false); return true; } return false; diff --git a/engines/bladerunner/bladerunner.cpp b/engines/bladerunner/bladerunner.cpp index b3885e8fb8..57159c22bb 100644 --- a/engines/bladerunner/bladerunner.cpp +++ b/engines/bladerunner/bladerunner.cpp @@ -605,23 +605,8 @@ void BladeRunnerEngine::gameTick() { } (void)backgroundChanged; _surface2.copyFrom(_surface1); - -#if 0 - { - for (int y = 0; y != 480; ++y) { - for (int x = 0; x != 640; ++x) { - if (_scene->_regions->getRegionAtXY(x, y) >= 0) { - uint16 *p = (uint16*)_surface2.getBasePtr(x, y); - *p = 0x7C00; - } - if (_scene->_exits->getRegionAtXY(x, y) >= 0) { - uint16 *p = (uint16*)_surface2.getBasePtr(x, y); - *p = 0x7C08; - } - } - } - } -#endif + // TODO: remove zbuffer draw + //_surface2.copyRectToSurface(_zbuffer->getData(), 1280, 0, 0, 640, 480); // TODO: Render overlays diff --git a/engines/bladerunner/script/scene/rc01.cpp b/engines/bladerunner/script/scene/rc01.cpp index 3df422563c..5ac89e8d85 100644 --- a/engines/bladerunner/script/scene/rc01.cpp +++ b/engines/bladerunner/script/scene/rc01.cpp @@ -27,7 +27,7 @@ namespace BladeRunner { void SceneScriptRC01::InitializeScene() { #if _DEBUG //TODO: not part of game, remove - Game_Flag_Set(24); // force skip intro + //Game_Flag_Set(24); // force skip intro #endif if (!Game_Flag_Query(24)) { diff --git a/engines/bladerunner/vqa_decoder.cpp b/engines/bladerunner/vqa_decoder.cpp index 1e22257843..01ccfd5874 100644 --- a/engines/bladerunner/vqa_decoder.cpp +++ b/engines/bladerunner/vqa_decoder.cpp @@ -208,7 +208,7 @@ void VQADecoder::decodeLights(Lights *lights) { _videoTrack->decodeLights(lights); } -void VQADecoder::readNextPacket() { +void VQADecoder::readPacket(int skipFlags) { IFFChunkHeader chd; if (remain(_s) < 8) { @@ -223,21 +223,20 @@ void VQADecoder::readNextPacket() { } bool rc = false; - switch (chd.id) { // Video track - case kAESC: rc = _videoTrack->readAESC(_s, chd.size); break; - case kLITE: rc = _videoTrack->readLITE(_s, chd.size); break; - case kVIEW: rc = _videoTrack->readVIEW(_s, chd.size); break; - case kVQFL: rc = _videoTrack->readVQFL(_s, chd.size); break; - case kVQFR: rc = _videoTrack->readVQFR(_s, chd.size); break; - case kZBUF: rc = _videoTrack->readZBUF(_s, chd.size); break; + switch (chd.id) { + case kAESC: rc = skipFlags & 1 ? _s->skip(roundup(chd.size)) : _videoTrack->readAESC(_s, chd.size); break; + case kLITE: rc = skipFlags & 1 ? _s->skip(roundup(chd.size)) : _videoTrack->readLITE(_s, chd.size); break; + case kVIEW: rc = skipFlags & 1 ? _s->skip(roundup(chd.size)) : _videoTrack->readVIEW(_s, chd.size); break; + case kVQFL: rc = skipFlags & 1 ? _s->skip(roundup(chd.size)) : _videoTrack->readVQFL(_s, chd.size); break; + case kVQFR: rc = skipFlags & 1 ? _s->skip(roundup(chd.size)) : _videoTrack->readVQFR(_s, chd.size); break; + case kZBUF: rc = skipFlags & 1 ? _s->skip(roundup(chd.size)) : _videoTrack->readZBUF(_s, chd.size); break; // Sound track - case kSN2J: rc = _audioTrack->readSN2J(_s, chd.size); break; - case kSND2: rc = _audioTrack->readSND2(_s, chd.size); break; - + case kSN2J: rc = skipFlags & 2 ? _s->skip(roundup(chd.size)) : _audioTrack->readSN2J(_s, chd.size); break; + case kSND2: rc = skipFlags & 2 ? _s->skip(roundup(chd.size)) : _audioTrack->readSND2(_s, chd.size); break; default: - _s->skip(roundup(chd.size)); rc = false; + _s->skip(roundup(chd.size)); } if (!rc) { @@ -247,14 +246,14 @@ void VQADecoder::readNextPacket() { } while (chd.id != kVQFR); } -void VQADecoder::readPacket(int frame) { +void VQADecoder::readFrame(int frame, int skipFlags) { if (frame < 0 || frame >= numFrames()) { error("frame %d out of bounds, frame count is %d", frame, numFrames()); } uint32 frameOffset = 2 * (_frameInfo[frame] & 0x0FFFFFFF); _s->seek(frameOffset); - readNextPacket(); + readPacket(skipFlags); } bool VQADecoder::readVQHD(Common::SeekableReadStream *s, uint32 size) { diff --git a/engines/bladerunner/vqa_decoder.h b/engines/bladerunner/vqa_decoder.h index fb81ef1dc3..a808543bec 100644 --- a/engines/bladerunner/vqa_decoder.h +++ b/engines/bladerunner/vqa_decoder.h @@ -49,8 +49,7 @@ public: bool loadStream(Common::SeekableReadStream *s); - void readNextPacket(); - void readPacket(int frame); + void readFrame(int frame, int skipFlags); const Graphics::Surface *decodeVideoFrame(); void decodeZBuffer(ZBuffer *zbuffer); @@ -141,6 +140,8 @@ private: VQAVideoTrack *_videoTrack; VQAAudioTrack *_audioTrack; + void readPacket(int skipFlags); + bool readVQHD(Common::SeekableReadStream *s, uint32 size); bool readMSCI(Common::SeekableReadStream *s, uint32 size); bool readMFCI(Common::SeekableReadStream *s, uint32 size); diff --git a/engines/bladerunner/vqa_player.cpp b/engines/bladerunner/vqa_player.cpp index 6018f40bab..da4749b532 100644 --- a/engines/bladerunner/vqa_player.cpp +++ b/engines/bladerunner/vqa_player.cpp @@ -47,10 +47,17 @@ bool VQAPlayer::open(const Common::String &name) { _audioStream = Audio::makeQueuingAudioStream(_decoder.frequency(), false); } + _repeatsCount = 0; + _loop = -1; + _frameBegin = -1; + _frameEnd = _decoder.numFrames() - 1; + _frameEndQueued = -1; + _repeatsCountQueued = -1; + if (_loopInitial >= 0) { - setLoop(_loopInitial, _repeatsCountInitial, 2, nullptr, nullptr); + setLoop(_loopInitial, _repeatsCountInitial, kLoopSetModeImmediate, nullptr, nullptr); } else { - setBeginAndEndFrame(0, _decoder.numFrames() - 1, 0, 0, nullptr, nullptr); + setBeginAndEndFrame(0, _frameEnd, 0, kLoopSetModeJustStart, nullptr, nullptr); } return true; @@ -65,46 +72,76 @@ void VQAPlayer::close() { int VQAPlayer::update() { uint32 now = 60 * _vm->_system->getMillis(); - if (_frameCurrent == -1) { - _frameCurrent = 0; - if (_frameCurrent >= 0) { - _decoder.readPacket(_frameCurrent); - if (_hasAudio) - queueAudioFrame(_decoder.decodeAudioFrame()); - _surface = _decoder.decodeVideoFrame(); - } + if (_frameNext < 0) { + _frameNext = _frameBegin; + } - _frameDecoded = calcNextFrame(_frameCurrent); - if (_frameDecoded >= 0) { - _decoder.readPacket(_frameDecoded); - if (_hasAudio) - queueAudioFrame(_decoder.decodeAudioFrame()); + if ((_repeatsCount > 0 || _repeatsCount == -1) && (_frameNext > _frameEnd)) { + int loopEndQueued = _frameEndQueued; + if (_frameEndQueued != -1) { + _frameEnd = _frameEndQueued; + _frameEndQueued = -1; + } + if (_frameNext != _frameBegin) { + _frameNext = _frameBegin; } - if (_hasAudio) { - _vm->_mixer->playStream(Audio::Mixer::kPlainSoundType, &_soundHandle, _audioStream); - _audioStarted = true; + if (loopEndQueued == -1) { + if (_repeatsCount != -1) { + _repeatsCount--; + } + //callback for repeat, it is not used in the blade runner + } else { + _repeatsCount = _repeatsCountQueued; + _repeatsCountQueued = -1; + + if (_callbackLoopEnded != nullptr) { + _callbackLoopEnded(_callbackData, 0, _loop); + } } + _surface = nullptr; + return -1; + } - _nextFrameTime = now + 60000 / 15; - return _frameCurrent; + if (_frameNext > _frameEnd) { + return -3; } - if (now >= _nextFrameTime) { - _frameCurrent = _frameDecoded; - if (_frameCurrent >= 0) { - _surface = _decoder.decodeVideoFrame(); - } - _frameDecoded = calcNextFrame(_frameCurrent); - if (_frameDecoded >= 0) { - _decoder.readPacket(_frameDecoded); - if (_hasAudio) - queueAudioFrame(_decoder.decodeAudioFrame()); +// TODO: preload audio +// int audioPreloadFrames = 1; + + if (now >= _frameNextTime) { + int frame = _frameNext; +// _decoder.readFrame(_frameNext, 0x2); + _decoder.readFrame(_frameNext, 0); + _surface = _decoder.decodeVideoFrame(); + + if (_hasAudio) { + queueAudioFrame(_decoder.decodeAudioFrame()); + if (!_audioStarted) { +// for (int i = 0; i < audioPreloadFrames; i++) { +// if (_frameNext + i < _frameEnd) { +// _decoder.readFrame(_frameNext + i, 0x1); +// queueAudioFrame(_decoder.decodeAudioFrame()); +// } +// } + _vm->_mixer->playStream(Audio::Mixer::kPlainSoundType, &_soundHandle, _audioStream); + _audioStarted = true; + } +// if (_frameNext + audioPreloadFrames < _frameEnd) { +// _decoder.readFrame(_frameNext + audioPreloadFrames, 0x1); +// queueAudioFrame(_decoder.decodeAudioFrame()); +// } + } + if (_frameNextTime == 0) { + _frameNextTime = now + 60000 / 15; + } else { + _frameNextTime += 60000 / 15; } - _nextFrameTime += 60000 / 15; - return _frameCurrent; + _frameNext++; + return frame; } _surface = nullptr; @@ -127,8 +164,8 @@ void VQAPlayer::updateLights(Lights *lights) { _decoder.decodeLights(lights); } -bool VQAPlayer::setLoop(int loop, int repeatsCount, int loopMode, void (*callback)(void *, int, int), void *callbackData) { -// debug("VQAPlayer::setBeginAndEndFrameFromLoop(%i, %i, %i, %x, %p), streamLoaded = %i", loop, repeatsCount, loopMode, (uint)callback, callbackData, _s != nullptr); +bool VQAPlayer::setLoop(int loop, int repeatsCount, int loopSetMode, void (*callback)(void *, int, int), void *callbackData) { + debug("VQAPlayer::setBeginAndEndFrameFromLoop(%i, %i, %i), streamLoaded = %i", loop, repeatsCount, loopSetMode, _s != nullptr); if (_s == nullptr) { _loopInitial = loop; _repeatsCountInitial = repeatsCount; @@ -139,41 +176,37 @@ bool VQAPlayer::setLoop(int loop, int repeatsCount, int loopMode, void (*callbac if (!_decoder.getLoopBeginAndEndFrame(loop, &begin, &end)) { return false; } - if (setBeginAndEndFrame(begin, end, repeatsCount, loopMode, callback, callbackData)) { + if (setBeginAndEndFrame(begin, end, repeatsCount, loopSetMode, callback, callbackData)) { _loop = loop; return true; } return false; } -bool VQAPlayer::setBeginAndEndFrame(int begin, int end, int repeatsCount, int loopMode, void (*callback)(void *, int, int), void *callbackData) { -// debug("VQAPlayer::setBeginAndEndFrame(%i, %i, %i, %i, %x, %p), streamLoaded = %i", begin, end, repeatsCount, loopMode, (uint)callback, callbackData, _s != nullptr); +bool VQAPlayer::setBeginAndEndFrame(int begin, int end, int repeatsCount, int loopSetMode, void (*callback)(void *, int, int), void *callbackData) { + debug("VQAPlayer::setBeginAndEndFrame(%i, %i, %i, %i), streamLoaded = %i", begin, end, repeatsCount, loopSetMode, _s != nullptr); if (repeatsCount < 0) { repeatsCount = -1; } - if (_repeatsCount == 0 && loopMode == 1) { - loopMode = 2; + if (_repeatsCount == 0 && loopSetMode == kLoopSetModeEnqueue) { + loopSetMode = kLoopSetModeImmediate; } //TODO: there is code in original game which deals with changing loop at start of loop, is it nescesarry? loc_46EA04 _frameBegin = begin; - if (loopMode == 1) { + if (loopSetMode == kLoopSetModeJustStart) { + _repeatsCount = repeatsCount; + } else if (loopSetMode == kLoopSetModeEnqueue) { _repeatsCountQueued = repeatsCount; _frameEndQueued = end; - } else if (loopMode == 2) { + } else if (loopSetMode == kLoopSetModeImmediate) { _repeatsCount = repeatsCount; _frameEnd = end; - _frameCurrent = begin; - //TODO: extract this to seek function - _decoder.readPacket(_frameCurrent); - _frameDecoded = _frameCurrent; - _nextFrameTime = 60 * _vm->_system->getMillis(); - } else if (loopMode == 0) { - _repeatsCount = repeatsCount; + seekToFrame(begin); } _callbackLoopEnded = callback; @@ -182,6 +215,12 @@ bool VQAPlayer::setBeginAndEndFrame(int begin, int end, int repeatsCount, int lo return true; } +bool VQAPlayer::seekToFrame(int frame) { + _frameNext = frame; + _frameNextTime = 60 * _vm->_system->getMillis(); + return true; +} + int VQAPlayer::getLoopBeginFrame(int loop) { int begin, end; if (!_decoder.getLoopBeginAndEndFrame(loop, &begin, &end)) { @@ -198,47 +237,6 @@ int VQAPlayer::getLoopEndFrame(int loop) { return end; } -int VQAPlayer::calcNextFrame(int frame) { - //TODO: needs a slight refactoring, because it is not only calculating the next frame - if (frame < 0) { - return -3; - } - - int frameNext = frame + 1; - - if ((_repeatsCount > 0 || _repeatsCount == -1) && (frameNext > _frameEnd)) { - int loopEndQueued = _frameEndQueued; - if (_frameEndQueued != -1) { - _frameEnd = _frameEndQueued; - _frameEndQueued = -1; - } - if (frameNext != _frameBegin) { - frameNext = _frameBegin; - } - - if (loopEndQueued == -1) { - if (_repeatsCount != -1) { - _repeatsCount--; - } - //callback for repeat, it is not used in the blade runner - } else { - _repeatsCount = _repeatsCountQueued; - _repeatsCountQueued = -1; - - if (_callbackLoopEnded != nullptr) { - _callbackLoopEnded(_callbackData, 0, _loop); - } - } - } - - //TODO: original game is using end of loop instead of count of frames - if (frameNext == _decoder.numFrames()) { - return -3; - } - - return frameNext; -} - void VQAPlayer::queueAudioFrame(Audio::AudioStream *audioStream) { int n = _audioStream->numQueuedStreams(); if (n == 0) diff --git a/engines/bladerunner/vqa_player.h b/engines/bladerunner/vqa_player.h index d0eb069969..8c2653ec85 100644 --- a/engines/bladerunner/vqa_player.h +++ b/engines/bladerunner/vqa_player.h @@ -32,6 +32,12 @@ namespace BladeRunner { +enum LoopSetModes { + kLoopSetModeJustStart = 0, + kLoopSetModeEnqueue = 1, + kLoopSetModeImmediate = 2 +}; + class BladeRunnerEngine; class View; class Lights; @@ -47,8 +53,7 @@ class VQAPlayer { const uint16 *_zBuffer; Audio::QueuingAudioStream *_audioStream; - int _frameCurrent; - int _frameDecoded; + int _frameNext; int _frameBegin; int _frameEnd; int _loop; @@ -60,7 +65,7 @@ class VQAPlayer { int _loopInitial; int _repeatsCountInitial; - uint32 _nextFrameTime; + uint32 _frameNextTime; bool _hasAudio; bool _audioStarted; Audio::SoundHandle _soundHandle; @@ -74,9 +79,9 @@ public: : _vm(vm), _s(nullptr), _surface(nullptr), + _zBuffer(nullptr), _audioStream(nullptr), - _frameCurrent(-1), - _frameDecoded(-1), + _frameNext(-1), _frameBegin(-1), _frameEnd(-1), _loop(-1), @@ -85,11 +90,11 @@ public: _frameEndQueued(-1), _loopInitial(-1), _repeatsCountInitial(-1), - _nextFrameTime(0), + _frameNextTime(0), _hasAudio(false), _audioStarted(false), - _callbackLoopEnded(nullptr) { - } + _callbackLoopEnded(nullptr), + _callbackData(nullptr) { } ~VQAPlayer() { close(); @@ -104,14 +109,15 @@ public: void updateView(View *view); void updateLights(Lights *lights); - bool setBeginAndEndFrame(int begin, int end, int repeatsCount, int loopMode, void(*callback)(void *, int, int), void *callbackData); - bool setLoop(int loop, int repeatsCount, int loopMode, void(*callback)(void*, int, int), void* callbackData); + bool setBeginAndEndFrame(int begin, int end, int repeatsCount, int loopSetMode, void(*callback)(void *, int, int), void *callbackData); + bool setLoop(int loop, int repeatsCount, int loopSetMode, void(*callback)(void*, int, int), void* callbackData); + + bool seekToFrame(int frame); int getLoopBeginFrame(int loop); int getLoopEndFrame(int loop); private: - int calcNextFrame(int frame); void queueAudioFrame(Audio::AudioStream *audioStream); }; diff --git a/engines/bladerunner/zbuffer.cpp b/engines/bladerunner/zbuffer.cpp index 76391f009f..3f2ed9abcc 100644 --- a/engines/bladerunner/zbuffer.cpp +++ b/engines/bladerunner/zbuffer.cpp @@ -93,9 +93,9 @@ static int decodePartialZBuffer(const uint8 *src, uint16 *curZBUF, uint32 srcLen uint32 dstRemain = dstSize; uint16 *curzp = curZBUF; - uint16 *inp = (uint16*)src; + const uint16 *inp = (const uint16*)src; - while (dstRemain && (inp - (uint16*)src) < (std::ptrdiff_t)srcLen) { + while (dstRemain && (inp - (const uint16*)src) < (std::ptrdiff_t)srcLen) { uint32 count = FROM_LE_16(*inp++); if (count & 0x8000) { @@ -129,12 +129,12 @@ bool ZBuffer::decodeData(const uint8 *data, int size) { return false; } - uint32 width, height, complete, unk0; + uint32 width, height, complete;// , unk0; width = READ_LE_UINT32(data + 0); height = READ_LE_UINT32(data + 4); complete = READ_LE_UINT32(data + 8); - unk0 = READ_LE_UINT32(data + 12); + /*unk0 =*/ READ_LE_UINT32(data + 12); if (width != (uint32)_width || height != (uint32)_height) { warning("zbuffer size mismatch (%d, %d) != (%d, %d)", _width, _height, width, height); |