mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-09 11:20:56 +00:00
BLADERUNNER: zbuffer is now updated between scene changes
updated vqa player udpate code fixed some warnings audio preloading still needs some work
This commit is contained in:
parent
d4ff2ddf10
commit
5f36e65855
@ -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;
|
||||
|
@ -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
|
||||
|
||||
|
@ -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)) {
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
_frameDecoded = calcNextFrame(_frameCurrent);
|
||||
if (_frameDecoded >= 0) {
|
||||
_decoder.readPacket(_frameDecoded);
|
||||
if (_hasAudio)
|
||||
queueAudioFrame(_decoder.decodeAudioFrame());
|
||||
}
|
||||
|
||||
if (_hasAudio) {
|
||||
_vm->_mixer->playStream(Audio::Mixer::kPlainSoundType, &_soundHandle, _audioStream);
|
||||
_audioStarted = true;
|
||||
}
|
||||
|
||||
_nextFrameTime = now + 60000 / 15;
|
||||
return _frameCurrent;
|
||||
if (_frameNext < 0) {
|
||||
_frameNext = _frameBegin;
|
||||
}
|
||||
|
||||
if (now >= _nextFrameTime) {
|
||||
_frameCurrent = _frameDecoded;
|
||||
if (_frameCurrent >= 0) {
|
||||
_surface = _decoder.decodeVideoFrame();
|
||||
if ((_repeatsCount > 0 || _repeatsCount == -1) && (_frameNext > _frameEnd)) {
|
||||
int loopEndQueued = _frameEndQueued;
|
||||
if (_frameEndQueued != -1) {
|
||||
_frameEnd = _frameEndQueued;
|
||||
_frameEndQueued = -1;
|
||||
}
|
||||
if (_frameNext != _frameBegin) {
|
||||
_frameNext = _frameBegin;
|
||||
}
|
||||
|
||||
_frameDecoded = calcNextFrame(_frameCurrent);
|
||||
if (_frameDecoded >= 0) {
|
||||
_decoder.readPacket(_frameDecoded);
|
||||
if (_hasAudio)
|
||||
queueAudioFrame(_decoder.decodeAudioFrame());
|
||||
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;
|
||||
}
|
||||
|
||||
if (_frameNext > _frameEnd) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
|
||||
// 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)
|
||||
|
@ -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);
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user