aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorSven Hesse2007-03-31 15:25:54 +0000
committerSven Hesse2007-03-31 15:25:54 +0000
commit375c63f7bc87c74f5ce34f7d90b8922ded861b39 (patch)
tree1bce64e8a312b1ebc18275af8ab800b06ef6d5c6 /engines
parenta08feb9f70d4ac8357db1df15950ff0067504d0d (diff)
downloadscummvm-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
Diffstat (limited to 'engines')
-rw-r--r--engines/gob/imd.cpp49
-rw-r--r--engines/gob/imd.h3
-rw-r--r--engines/gob/init.cpp1
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();
}