From 6ec870303ff3532873f652fb1a565d72b0079645 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Wed, 20 May 2009 10:43:18 +0000 Subject: [PATCH] - Reverted commit #40730, as it introduced rounding errors - Properly fixed the FLIC player - The sound chunk tag of DXA files is now read by the DXADecoder's loadFile() method svn-id: r40736 --- engines/agos/animation.cpp | 9 ++++----- engines/sword1/animation.cpp | 12 ++---------- engines/sword2/animation.cpp | 13 ++----------- graphics/video/dxa_player.cpp | 12 ++++++++---- graphics/video/dxa_player.h | 6 ++++++ graphics/video/flic_player.cpp | 10 ++++++---- graphics/video/smk_player.cpp | 12 ++++++------ graphics/video/video_player.cpp | 4 ++-- graphics/video/video_player.h | 18 ++++++------------ 9 files changed, 42 insertions(+), 54 deletions(-) diff --git a/engines/agos/animation.cpp b/engines/agos/animation.cpp index c73f46fa930..3be552a0833 100644 --- a/engines/agos/animation.cpp +++ b/engines/agos/animation.cpp @@ -273,10 +273,9 @@ void MoviePlayerDXA::stopVideo() { void MoviePlayerDXA::startSound() { byte *buffer; - uint32 offset, size, tag; + uint32 offset, size; - tag = _fileStream->readUint32BE(); - if (tag == MKID_BE('WAVE')) { + if (getSoundTag() == MKID_BE('WAVE')) { size = _fileStream->readUint32BE(); if (_sequenceNum) { @@ -322,7 +321,7 @@ void MoviePlayerDXA::nextFrame() { } if (_vm->_interactiveVideo == TYPE_LOOPING && getCurFrame() == getFrameCount()) { - _fileStream->seek(_videoInfo.frameOffs); + _fileStream->seek(_videoInfo.firstframeOffset); _videoInfo.currentFrame = 0; startSound(); } @@ -445,7 +444,7 @@ void MoviePlayerSMK::handleNextFrame() { void MoviePlayerSMK::nextFrame() { if (_vm->_interactiveVideo == TYPE_LOOPING && getCurFrame() == getFrameCount()) { - _fileStream->seek(_videoInfo.frameOffs); + _fileStream->seek(_videoInfo.firstframeOffset); _videoInfo.currentFrame = 0; } diff --git a/engines/sword1/animation.cpp b/engines/sword1/animation.cpp index c97d04d1d9a..2d0d081ef62 100644 --- a/engines/sword1/animation.cpp +++ b/engines/sword1/animation.cpp @@ -144,15 +144,7 @@ bool MoviePlayer::load(uint32 id) { break; } - if (_decoder->loadFile(filename)) { - // The DXA animations in the Broken Sword games always use external audio tracks. - if (_decoderType == kVideoDecoderDXA && _decoder->readSoundHeader() != MKID_BE('NULL')) - return false; - } else { - return false; - } - - return true; + return _decoder->loadFile(filename); } void MoviePlayer::play(void) { @@ -244,7 +236,7 @@ int32 DXADecoderWithSound::getAudioLag() { int32 videoTime = _videoInfo.currentFrame * frameDelay; int32 audioTime; - audioTime = (int32) _mixer->getSoundElapsedTime(*_bgSoundHandle); + audioTime = (((int32) _mixer->getSoundElapsedTime(*_bgSoundHandle)) * 100); return videoTime - audioTime; } diff --git a/engines/sword2/animation.cpp b/engines/sword2/animation.cpp index 56f369a3ebd..e0b8bcbe522 100644 --- a/engines/sword2/animation.cpp +++ b/engines/sword2/animation.cpp @@ -80,16 +80,7 @@ bool MoviePlayer::load(const char *name) { break; } - if (_decoder->loadFile(filename)) { - // The DXA animations in the Broken Sword games always use external audio tracks, - // if they have any sound at all. - if (_decoderType == kVideoDecoderDXA && _decoder->readSoundHeader() != MKID_BE('NULL')) - return false; - } else { - return false; - } - - return true; + return _decoder->loadFile(filename); } void MoviePlayer::play(MovieText *movieTexts, uint32 numMovieTexts, uint32 leadIn, uint32 leadOut) { @@ -280,7 +271,7 @@ int32 DXADecoderWithSound::getAudioLag() { int32 videoTime = _videoInfo.currentFrame * frameDelay; int32 audioTime; - audioTime = (int32) _mixer->getSoundElapsedTime(*_bgSoundHandle); + audioTime = (((int32) _mixer->getSoundElapsedTime(*_bgSoundHandle)) * 100); return videoTime - audioTime; } diff --git a/graphics/video/dxa_player.cpp b/graphics/video/dxa_player.cpp index 55fe869fc41..d0d4d1c67b7 100644 --- a/graphics/video/dxa_player.cpp +++ b/graphics/video/dxa_player.cpp @@ -86,13 +86,13 @@ bool DXADecoder::loadFile(const char *fileName) { if (frameRate > 0) { _videoInfo.frameRate = 1000 / frameRate; - _videoInfo.frameDelay = frameRate; + _videoInfo.frameDelay = frameRate * 100; } else if (frameRate < 0) { _videoInfo.frameRate = 100000 / (-frameRate); - _videoInfo.frameDelay = -frameRate / 100; + _videoInfo.frameDelay = -frameRate; } else { _videoInfo.frameRate = 10; - _videoInfo.frameDelay = 100; + _videoInfo.frameDelay = 10000; } _videoInfo.width = _fileStream->readUint16BE(); @@ -155,9 +155,13 @@ bool DXADecoder::loadFile(const char *fileName) { } while (tag != 0); } #endif + + // Read the sound header + _soundTag = _fileStream->readUint32BE(); + _videoInfo.currentFrame = 0; - _videoInfo.frameOffs = _fileStream->pos(); + _videoInfo.firstframeOffset = _fileStream->pos(); return true; } diff --git a/graphics/video/dxa_player.h b/graphics/video/dxa_player.h index 15fb4aa1680..384a057c3f4 100644 --- a/graphics/video/dxa_player.h +++ b/graphics/video/dxa_player.h @@ -55,6 +55,11 @@ public: bool decodeNextFrame(); + /** + * Get the sound chunk tag of the loaded DXA file + */ + uint32 getSoundTag() { return _soundTag; } + private: void decodeZlib(byte *data, int size, int totalSize); void decode12(int size); @@ -76,6 +81,7 @@ private: uint16 _curHeight; uint32 _frameSize; ScaleMode _scaleMode; + uint32 _soundTag; }; } // End of namespace Graphics diff --git a/graphics/video/flic_player.cpp b/graphics/video/flic_player.cpp index 29c83e9d0ea..e58cf0bdbc5 100644 --- a/graphics/video/flic_player.cpp +++ b/graphics/video/flic_player.cpp @@ -72,8 +72,9 @@ bool FlicDecoder::loadFile(const char *fileName) { } _fileStream->readUint16LE(); // flags // Note: The normal delay is a 32-bit integer (dword), whereas the overriden delay is a 16-bit integer (word) - _videoInfo.frameDelay = _fileStream->readUint32LE(); // frameDelay is the FLIC "speed", in milliseconds - _videoInfo.frameRate = 1000 / _videoInfo.frameDelay; + // frameDelay is the FLIC "speed", in milliseconds. Our frameDelay is calculated in 1/100 ms, so we convert it here + _videoInfo.frameDelay = 100 * _fileStream->readUint32LE(); + _videoInfo.frameRate = 100 * 1000 / _videoInfo.frameDelay; _fileStream->seek(80); _offsetFrame1 = _fileStream->readUint32LE(); @@ -206,10 +207,11 @@ bool FlicDecoder::decodeNextFrame() { case FRAME_TYPE: { chunkCount = _fileStream->readUint16LE(); // Note: The overriden delay is a 16-bit integer (word), whereas the normal delay is a 32-bit integer (dword) + // frameDelay is the FLIC "speed", in milliseconds. Our frameDelay is calculated in 1/100 ms, so we convert it here uint16 newFrameDelay = _fileStream->readUint16LE(); // "speed", in milliseconds if (newFrameDelay > 0) { - _videoInfo.frameDelay = newFrameDelay; - _videoInfo.frameRate = 1000 / _videoInfo.frameDelay; + _videoInfo.frameDelay = 100 * newFrameDelay; + _videoInfo.frameRate = 100 * 1000 / _videoInfo.frameDelay; } _fileStream->readUint16LE(); // reserved, always 0 uint16 newWidth = _fileStream->readUint16LE(); diff --git a/graphics/video/smk_player.cpp b/graphics/video/smk_player.cpp index 9ed8e9902f4..ebbf61d25a2 100644 --- a/graphics/video/smk_player.cpp +++ b/graphics/video/smk_player.cpp @@ -344,9 +344,9 @@ int32 SmackerDecoder::getAudioLag() { and how much time *should* have passed. */ - audioTime = g_system->getMillis() - _videoInfo.startTime; + audioTime = (g_system->getMillis() - _videoInfo.startTime) * 100; } else - audioTime = (int32) _mixer->getSoundElapsedTime(_audioHandle); + audioTime = (((int32) _mixer->getSoundElapsedTime(_audioHandle)) * 100); return videoTime - audioTime; } @@ -380,13 +380,13 @@ bool SmackerDecoder::loadFile(const char *fileName) { if (frameRate > 0) { _videoInfo.frameRate = 1000 / frameRate; - _videoInfo.frameDelay = frameRate; + _videoInfo.frameDelay = frameRate * 100; } else if (frameRate < 0) { _videoInfo.frameRate = 100000 / (-frameRate); - _videoInfo.frameDelay = -frameRate / 100; + _videoInfo.frameDelay = -frameRate; } else { _videoInfo.frameRate = 10; - _videoInfo.frameDelay = 100; + _videoInfo.frameDelay = 10000; } // Flags are determined by which bit is set, which can be one of the following: @@ -473,7 +473,7 @@ bool SmackerDecoder::loadFile(const char *fileName) { _palette = (byte *)malloc(3 * 256); memset(_palette, 0, 3 * 256); - _videoInfo.frameOffs = _fileStream->pos(); + _videoInfo.firstframeOffset = _fileStream->pos(); return true; } diff --git a/graphics/video/video_player.cpp b/graphics/video/video_player.cpp index b77cb3b7f73..81c025d22fa 100644 --- a/graphics/video/video_player.cpp +++ b/graphics/video/video_player.cpp @@ -88,14 +88,14 @@ int32 VideoDecoder::getAudioLag() { Calculate the lag by how much time has gone by since the first frame and how much time *should* have passed. */ - int32 audioTime = g_system->getMillis() - _videoInfo.startTime; + int32 audioTime = (g_system->getMillis() - _videoInfo.startTime) * 100; int32 videoTime = _videoInfo.currentFrame * getFrameDelay(); return videoTime - audioTime; } uint32 VideoDecoder::getFrameWaitTime() { - int32 waitTime = getFrameDelay() + getAudioLag(); + int32 waitTime = (getFrameDelay() + getAudioLag()) / 100; if (waitTime < 0) return 0; diff --git a/graphics/video/video_player.h b/graphics/video/video_player.h index ef878aa61bb..eb02032b500 100644 --- a/graphics/video/video_player.h +++ b/graphics/video/video_player.h @@ -75,16 +75,16 @@ public: virtual int32 getFrameRate(); /** - * Returns the time to wait for each frame in ms - * @return the time to wait for each frame in ms + * Returns the time to wait for each frame in 1/100 ms (to avoid rounding errors) + * @return the time to wait for each frame in 1/100 ms (to avoid rounding errors) */ virtual int32 getFrameDelay(); /** - * Returns the current A/V lag in ms + * Returns the current A/V lag in 1/100 ms (to avoid rounding errors) * If > 0, audio lags behind * If < 0, video lags behind - * @return the current A/V lag in ms + * @return the current A/V lag in 1/100 ms (to avoid rounding errors) */ virtual int32 getAudioLag(); @@ -158,20 +158,14 @@ public: */ virtual bool decodeNextFrame() = 0; - /** - * Used to read the sound header from DXA files. It's not pretty, - * but it's slightly better than exposing _fileStream - */ - uint32 readSoundHeader() { return _fileStream->readUint32BE(); } - protected: struct { uint32 width; uint32 height; uint32 frameCount; int32 frameRate; - int32 frameDelay; // ms - uint32 frameOffs; + int32 frameDelay; // 1/100 ms (to avoid rounding errors) + uint32 firstframeOffset; uint32 currentFrame; uint32 startTime; } _videoInfo;