diff options
author | Sven Hesse | 2007-03-31 15:25:54 +0000 |
---|---|---|
committer | Sven Hesse | 2007-03-31 15:25:54 +0000 |
commit | 375c63f7bc87c74f5ce34f7d90b8922ded861b39 (patch) | |
tree | 1bce64e8a312b1ebc18275af8ab800b06ef6d5c6 | |
parent | a08feb9f70d4ac8357db1df15950ff0067504d0d (diff) | |
download | scummvm-rg350-375c63f7bc87c74f5ce34f7d90b8922ded861b39.tar.gz scummvm-rg350-375c63f7bc87c74f5ce34f7d90b8922ded861b39.tar.bz2 scummvm-rg350-375c63f7bc87c74f5ce34f7d90b8922ded861b39.zip |
Changed waitEndSoundSlice() to react more dynamically to enforce audio/video sync
svn-id: r26332
-rw-r--r-- | engines/gob/imd.cpp | 49 | ||||
-rw-r--r-- | engines/gob/imd.h | 3 | ||||
-rw-r--r-- | engines/gob/init.cpp | 1 |
3 files changed, 40 insertions, 13 deletions
diff --git a/engines/gob/imd.cpp b/engines/gob/imd.cpp index 31e562681d..e2f98bfb38 100644 --- a/engines/gob/imd.cpp +++ b/engines/gob/imd.cpp @@ -60,6 +60,9 @@ ImdPlayer::ImdPlayer(GobEngine *vm) : _vm(vm) { _noSound = true; _soundBuffer = 0; + _soundWaited = 0; + _skipFrames = 0; + _soundFreq = 0; _soundSliceSize = 0; _soundSlicesCount = 0; @@ -185,9 +188,9 @@ ImdPlayer::Imd *ImdPlayer::loadImdFile(const char *path, SurfaceDesc *surfDesc, if (_soundSlicesCount < 0) _soundSlicesCount = -_soundSlicesCount - 1; - if (_soundSlicesCount >= 40) { + if (_soundSlicesCount > 40) { warning("%s: More than 40 sound slices found (%d)", - buf, _soundSlicesCount + 1); + buf, _soundSlicesCount); finishImd(imdPtr); return 0; } @@ -195,12 +198,14 @@ ImdPlayer::Imd *ImdPlayer::loadImdFile(const char *path, SurfaceDesc *surfDesc, _soundSliceLength = 1000 / (_soundFreq / _soundSliceSize); delete[] _soundBuffer; - _soundBuffer = new byte[_soundSliceSize * _soundSlicesCount]; + // Allocate one slice more than necessary so that the first one won't + // get overwritten too fast after starting the, initially full, buffer + _soundBuffer = new byte[_soundSliceSize * (_soundSlicesCount + 1)]; assert(_soundBuffer); - memset(_soundBuffer, 0, _soundSliceSize * _soundSlicesCount); + memset(_soundBuffer, 0, _soundSliceSize * (_soundSlicesCount + 1)); _soundDesc.set(SOUND_SND, SOUND_TOT, _soundBuffer, - _soundSliceSize * _soundSlicesCount); + _soundSliceSize * (_soundSlicesCount + 1)); _curSoundSlice = 0; _soundStage = 1; @@ -1106,7 +1111,7 @@ uint32 ImdPlayer::view(Imd *imdPtr, int16 frame) { memset(soundBuf, 0, _soundSliceSize); if (!hasNextCmd) - _curSoundSlice = (_curSoundSlice + 1) % _soundSlicesCount; + _curSoundSlice = (_curSoundSlice + 1) % (_soundSlicesCount + 1); } // Set palette @@ -1196,6 +1201,8 @@ uint32 ImdPlayer::view(Imd *imdPtr, int16 frame) { _vm->_snd->stopSound(0); _vm->_snd->playSample(_soundDesc, -1, _soundFreq); _soundStage = 2; + _soundWaited = imdPtr->curFrame * _soundSliceLength; + _skipFrames = 0; } imdPtr->x = xBak; @@ -1208,7 +1215,7 @@ uint32 ImdPlayer::view(Imd *imdPtr, int16 frame) { // Clear the remaining sound buffer if (_curSoundSlice > 0) memset(_soundBuffer + _curSoundSlice * _soundSliceSize, 0, - _soundSliceSize * _soundSlicesCount - + _soundSliceSize * (_soundSlicesCount + 1) - _curSoundSlice * _soundSliceSize); _vm->_snd->setRepeating(0); @@ -1219,13 +1226,29 @@ uint32 ImdPlayer::view(Imd *imdPtr, int16 frame) { } inline void ImdPlayer::waitEndSoundSlice() { - uint32 timeKey = _vm->_util->getTimeKey(); - int32 waitTime = _soundSliceLength; + if (_soundStage != 2) + return; + + if (_skipFrames == 0) { + uint32 timeKey = _vm->_util->getTimeKey(); + int32 waitTime = (_curImd->curFrame * _soundSliceLength) - _soundWaited; + + _vm->_video->retrace(); + waitTime -= _vm->_util->getTimeKey() - timeKey; - _vm->_video->retrace(); - waitTime -= _vm->_util->getTimeKey() - timeKey; - if (waitTime > 0) - _vm->_util->delay(waitTime); + if (waitTime > 0) { + timeKey = _vm->_util->getTimeKey(); + _vm->_util->delay(waitTime); + _soundWaited += _vm->_util->getTimeKey() - timeKey; + } else { + _skipFrames = -waitTime / _soundSliceLength; + _soundWaited = + ((_curImd->curFrame + _skipFrames) * _soundSliceLength) + + (-waitTime % _soundSliceLength); + warning("IMD A/V sync broken, skipping %d frame(s)", _skipFrames + 1); + } + } else + _skipFrames--; } } // End of namespace Gob diff --git a/engines/gob/imd.h b/engines/gob/imd.h index bf66136d58..0728666cc5 100644 --- a/engines/gob/imd.h +++ b/engines/gob/imd.h @@ -107,6 +107,9 @@ protected: bool _noSound; byte *_soundBuffer; + uint32 _soundWaited; + uint32 _skipFrames; + int16 _soundFreq; uint16 _soundSliceSize; int16 _soundSlicesCount; diff --git a/engines/gob/init.cpp b/engines/gob/init.cpp index 447b8c33e5..b712041254 100644 --- a/engines/gob/init.cpp +++ b/engines/gob/init.cpp @@ -163,6 +163,7 @@ void Init::initGame(char *totName) { if (imdHandle >= 0) { _vm->_dataIO->closeData(imdHandle); _vm->_draw->initScreen(); + _vm->_util->longDelay(200); // Letting everything settle _vm->_imdPlayer->play("coktel", -1, -1, true); _vm->_draw->closeScreen(); } |