[Scummvm-git-logs] scummvm master -> a7a4d9f1207ab0822a1f83ca26662831da44ad73
AndywinXp
noreply at scummvm.org
Tue Oct 4 09:36:06 UTC 2022
This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
6ad5ed0b92 SCUMM: DiMUSE: Solve very rare deadlocks caused by two different mutex objects
a7a4d9f120 SCUMM: DiMUSE: Implement antiskip system for devices with slow load times
Commit: 6ad5ed0b928f8acc352fc668fce4caf1c9e335bc
https://github.com/scummvm/scummvm/commit/6ad5ed0b928f8acc352fc668fce4caf1c9e335bc
Author: Andrea Boscarino (andywinxp at gmail.com)
Date: 2022-10-04T11:33:26+02:00
Commit Message:
SCUMM: DiMUSE: Solve very rare deadlocks caused by two different mutex objects
Changed paths:
engines/scumm/imuse_digi/dimuse_dispatch.cpp
engines/scumm/imuse_digi/dimuse_engine.cpp
engines/scumm/imuse_digi/dimuse_engine.h
engines/scumm/imuse_digi/dimuse_streamer.cpp
engines/scumm/imuse_digi/dimuse_tracks.cpp
engines/scumm/imuse_digi/dimuse_wave.cpp
engines/scumm/imuse_digi/dimuse_waveout.cpp
engines/scumm/scumm.cpp
diff --git a/engines/scumm/imuse_digi/dimuse_dispatch.cpp b/engines/scumm/imuse_digi/dimuse_dispatch.cpp
index 97a31fdff4f..c7a82a091bf 100644
--- a/engines/scumm/imuse_digi/dimuse_dispatch.cpp
+++ b/engines/scumm/imuse_digi/dimuse_dispatch.cpp
@@ -812,7 +812,7 @@ void IMuseDigital::dispatchProcessDispatches(IMuseDigiTrack *trackPtr, int feedS
}
void IMuseDigital::dispatchPredictFirstStream() {
- Common::StackLock lock(_mutex);
+ Common::StackLock lock(*_mutex);
for (int i = 0; i < _trackCount; i++) {
if (_dispatches[i].trackPtr->soundId && _dispatches[i].streamPtr && _dispatches[i].streamZoneList)
diff --git a/engines/scumm/imuse_digi/dimuse_engine.cpp b/engines/scumm/imuse_digi/dimuse_engine.cpp
index 76948da8ce5..9277afb1ab2 100644
--- a/engines/scumm/imuse_digi/dimuse_engine.cpp
+++ b/engines/scumm/imuse_digi/dimuse_engine.cpp
@@ -41,8 +41,8 @@ void IMuseDigital::timer_handler(void *refCon) {
diMUSE->callback();
}
-IMuseDigital::IMuseDigital(ScummEngine_v7 *scumm, Audio::Mixer *mixer)
- : _vm(scumm), _mixer(mixer) {
+IMuseDigital::IMuseDigital(ScummEngine_v7 *scumm, Audio::Mixer *mixer, Common::Mutex *mutex)
+ : _vm(scumm), _mixer(mixer), _mutex(mutex) {
assert(_vm);
assert(mixer);
@@ -284,7 +284,7 @@ static void skipLegacyTrackEntry(Common::Serializer &s) {
}
void IMuseDigital::saveLoadEarly(Common::Serializer &s) {
- Common::StackLock lock(_mutex, "IMuseDigital::saveLoadEarly()");
+ Common::StackLock lock(*_mutex, "IMuseDigital::saveLoadEarly()");
if (s.isLoading()) {
diMUSEStopAllSounds();
diff --git a/engines/scumm/imuse_digi/dimuse_engine.h b/engines/scumm/imuse_digi/dimuse_engine.h
index efe1e36cad1..7ffdaedca99 100644
--- a/engines/scumm/imuse_digi/dimuse_engine.h
+++ b/engines/scumm/imuse_digi/dimuse_engine.h
@@ -67,7 +67,7 @@ struct IMuseDigiStreamZone;
class IMuseDigital : public MusicEngine {
private:
- Common::Mutex _mutex;
+ Common::Mutex *_mutex;
ScummEngine_v7 *_vm;
Audio::Mixer *_mixer;
SmushPlayer *_splayer;
@@ -302,7 +302,7 @@ private:
byte waveOutGetStreamFlags();
public:
- IMuseDigital(ScummEngine_v7 *scumm, Audio::Mixer *mixer);
+ IMuseDigital(ScummEngine_v7 *scumm, Audio::Mixer *mixer, Common::Mutex *mutex);
~IMuseDigital() override;
// Wrapper functions used by the main engine
diff --git a/engines/scumm/imuse_digi/dimuse_streamer.cpp b/engines/scumm/imuse_digi/dimuse_streamer.cpp
index 6c5d9bc7ec3..69bcf80628a 100644
--- a/engines/scumm/imuse_digi/dimuse_streamer.cpp
+++ b/engines/scumm/imuse_digi/dimuse_streamer.cpp
@@ -335,9 +335,9 @@ int IMuseDigital::streamerFetchData(IMuseDigiStream *streamPtr) {
_streamerBailFlag = 0;
- Common::StackLock lock(_mutex);
+ _mutex->lock();
actualAmount = _filesHandler->read(streamPtr->soundId, &streamPtr->buf[streamPtr->loadIndex], requestedAmount, streamPtr->bufId);
- Common::StackLock unlock(_mutex);
+ _mutex->unlock();
// FT has no bailFlag
if (!_isEarlyDiMUSE && _streamerBailFlag)
diff --git a/engines/scumm/imuse_digi/dimuse_tracks.cpp b/engines/scumm/imuse_digi/dimuse_tracks.cpp
index 407cccfc5ba..388b6ec83a0 100644
--- a/engines/scumm/imuse_digi/dimuse_tracks.cpp
+++ b/engines/scumm/imuse_digi/dimuse_tracks.cpp
@@ -71,7 +71,7 @@ void IMuseDigital::tracksResume() {
}
void IMuseDigital::tracksSaveLoad(Common::Serializer &ser) {
- Common::StackLock lock(_mutex);
+ Common::StackLock lock(*_mutex);
dispatchSaveLoad(ser);
for (int l = 0; l < _trackCount; l++) {
@@ -150,8 +150,6 @@ void IMuseDigital::tracksCallback() {
_tracksPauseTimer = 3;
}
- Common::StackLock lock(_mutex);
-
// If we leave the number of queued streams unbounded, we fill the queue with streams faster than
// we can play them: this leads to a very noticeable audio latency and desync with the graphics.
if ((int)_internalMixer->_stream->numQueuedStreams() < _maxQueuedStreams) {
@@ -228,9 +226,9 @@ int IMuseDigital::tracksStartSound(int soundId, int tryPriority, int group) {
return -1;
}
- Common::StackLock lock(_mutex);
+ _mutex->lock();
addTrackToList(&_trackList, allocatedTrack);
- Common::StackLock unlock(_mutex);
+ _mutex->unlock();
return 0;
}
@@ -254,7 +252,7 @@ int IMuseDigital::tracksStopSound(int soundId) {
}
int IMuseDigital::tracksStopAllSounds() {
- Common::StackLock lock(_mutex);
+ Common::StackLock lock(*_mutex);
IMuseDigiTrack *nextTrack = _trackList;
IMuseDigiTrack *curTrack;
diff --git a/engines/scumm/imuse_digi/dimuse_wave.cpp b/engines/scumm/imuse_digi/dimuse_wave.cpp
index c8574259846..ce8ea6e73dd 100644
--- a/engines/scumm/imuse_digi/dimuse_wave.cpp
+++ b/engines/scumm/imuse_digi/dimuse_wave.cpp
@@ -34,39 +34,39 @@ int IMuseDigital::waveTerminate() {
}
int IMuseDigital::wavePause() {
- Common::StackLock lock(_mutex);
+ Common::StackLock lock(*_mutex);
tracksPause();
return 0;
}
int IMuseDigital::waveResume() {
- Common::StackLock lock(_mutex);
+ Common::StackLock lock(*_mutex);
tracksResume();
return 0;
}
void IMuseDigital::waveSaveLoad(Common::Serializer &ser) {
- Common::StackLock lock(_mutex);
+ Common::StackLock lock(*_mutex);
tracksSaveLoad(ser);
}
void IMuseDigital::waveUpdateGroupVolumes() {
- Common::StackLock lock(_mutex);
+ Common::StackLock lock(*_mutex);
tracksSetGroupVol();
}
int IMuseDigital::waveStartSound(int soundId, int priority) {
- Common::StackLock lock(_mutex);
+ Common::StackLock lock(*_mutex);
return tracksStartSound(soundId, priority, 0);
}
int IMuseDigital::waveStopSound(int soundId) {
- Common::StackLock lock(_mutex);
+ Common::StackLock lock(*_mutex);
return tracksStopSound(soundId);
}
int IMuseDigital::waveStopAllSounds() {
- Common::StackLock lock(_mutex);
+ Common::StackLock lock(*_mutex);
return tracksStopAllSounds();
}
@@ -75,12 +75,12 @@ int IMuseDigital::waveGetNextSound(int soundId) {
}
int IMuseDigital::waveSetParam(int soundId, int opcode, int value) {
- Common::StackLock lock(_mutex);
+ Common::StackLock lock(*_mutex);
return tracksSetParam(soundId, opcode, value);
}
int IMuseDigital::waveGetParam(int soundId, int opcode) {
- Common::StackLock lock(_mutex);
+ Common::StackLock lock(*_mutex);
return tracksGetParam(soundId, opcode);
}
@@ -96,32 +96,32 @@ int IMuseDigital::waveStartStream(int soundId, int priority, int bufferId) {
if (soundId == 0)
return -1;
- Common::StackLock lock(_mutex);
+ Common::StackLock lock(*_mutex);
return tracksStartSound(soundId, priority, bufferId);
}
int IMuseDigital::waveSwitchStream(int oldSoundId, int newSoundId, int fadeLengthMs, int fadeSyncFlag2, int fadeSyncFlag1) {
- Common::StackLock lock(_mutex);
+ Common::StackLock lock(*_mutex);
return dispatchSwitchStream(oldSoundId, newSoundId, fadeLengthMs, fadeSyncFlag2, fadeSyncFlag1);
}
int IMuseDigital::waveSwitchStream(int oldSoundId, int newSoundId, uint8 *crossfadeBuffer, int crossfadeBufferSize, int vocLoopFlag) {
- Common::StackLock lock(_mutex);
+ Common::StackLock lock(*_mutex);
return dispatchSwitchStream(oldSoundId, newSoundId, crossfadeBuffer, crossfadeBufferSize, vocLoopFlag);
}
int IMuseDigital::waveProcessStreams() {
- Common::StackLock lock(_mutex);
+ Common::StackLock lock(*_mutex);
return streamerProcessStreams();
}
void IMuseDigital::waveQueryStream(int soundId, int32 &bufSize, int32 &criticalSize, int32 &freeSpace, int &paused) {
- Common::StackLock lock(_mutex);
tracksQueryStream(soundId, bufSize, criticalSize, freeSpace, paused);
+ Common::StackLock lock(*_mutex);
}
int IMuseDigital::waveFeedStream(int soundId, uint8 *srcBuf, int32 sizeToFeed, int paused) {
- Common::StackLock lock(_mutex);
+ Common::StackLock lock(*_mutex);
return tracksFeedStream(soundId, srcBuf, sizeToFeed, paused);
}
diff --git a/engines/scumm/imuse_digi/dimuse_waveout.cpp b/engines/scumm/imuse_digi/dimuse_waveout.cpp
index 7311ad9b8f9..d3433c31996 100644
--- a/engines/scumm/imuse_digi/dimuse_waveout.cpp
+++ b/engines/scumm/imuse_digi/dimuse_waveout.cpp
@@ -87,7 +87,7 @@ int IMuseDigital::waveOutDeinit() {
}
void IMuseDigital::waveOutCallback() {
- Common::StackLock lock(_mutex);
+ Common::StackLock lock(*_mutex);
tracksCallback();
}
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index 34dd82ea92c..2da35837065 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -1435,7 +1435,7 @@ void ScummEngine_v7::setupScumm(const Common::String &macResourceFile) {
filesAreCompressed |= _sound->isSfxFileCompressed();
}
- _musicEngine = _imuseDigital = new IMuseDigital(this, _mixer);
+ _musicEngine = _imuseDigital = new IMuseDigital(this, _mixer, &_resourceAccessMutex);
if (filesAreCompressed) {
GUI::MessageDialog dialog(_(
Commit: a7a4d9f1207ab0822a1f83ca26662831da44ad73
https://github.com/scummvm/scummvm/commit/a7a4d9f1207ab0822a1f83ca26662831da44ad73
Author: AndywinXp (andywinxp at gmail.com)
Date: 2022-10-04T11:34:14+02:00
Commit Message:
SCUMM: DiMUSE: Implement antiskip system for devices with slow load times
This code is present in all the original interpreters using Digital iMUSE, and it was implemented
in order to allow slower CD drives to fetch new data without having music skipping during load times.
This works by basically flooding the music buffer with data whenever a big resource, a voice file, or
a SMUSH movie is loaded.
Arguably this is not needed for devices using SSD drives, but since this change had its benefits on a
quite old laptop of mine, and since the memory overhead is very minimal, I have decided to implement it.
Changed paths:
engines/scumm/imuse_digi/dimuse_engine.cpp
engines/scumm/imuse_digi/dimuse_engine.h
engines/scumm/imuse_digi/dimuse_streamer.cpp
engines/scumm/imuse_digi/dimuse_tracks.cpp
engines/scumm/imuse_digi/dimuse_wave.cpp
engines/scumm/resource.cpp
engines/scumm/smush/smush_player.cpp
diff --git a/engines/scumm/imuse_digi/dimuse_engine.cpp b/engines/scumm/imuse_digi/dimuse_engine.cpp
index 9277afb1ab2..f8423c15c1b 100644
--- a/engines/scumm/imuse_digi/dimuse_engine.cpp
+++ b/engines/scumm/imuse_digi/dimuse_engine.cpp
@@ -188,6 +188,8 @@ int IMuseDigital::startVoice(int soundId, const char *soundName, byte speakingAc
if (fileDoesNotExist)
return 1;
+ fillStreamsWhileMusicCritical(5);
+
// WORKAROUND for this particular sound file not playing (this is a bug in the original):
// this is happening because the sound buffer responsible for speech
// is still busy with the previous speech file playing during the SAN
@@ -337,6 +339,10 @@ void IMuseDigital::saveLoadEarly(Common::Serializer &s) {
diMUSESetSFXGroupVol(diMUSEGetSFXGroupVol());
}
}
+
+ if (_vm->_game.id == GID_CMI && s.isLoading()) {
+ fillStreamsWhileMusicCritical(10);
+ }
}
void IMuseDigital::refreshScripts() {
@@ -678,6 +684,67 @@ void IMuseDigital::receiveAudioFromSMUSH(uint8 *srcBuf, int32 inFrameCount, int3
_internalMixer->mix(srcBuf, inFrameCount, 8, 1, feedSize, mixBufStartIndex, volume, pan, is11025Hz);
}
+void IMuseDigital::floodMusicBuffer() {
+ while (!isMusicStreamIdle()) {
+ diMUSEProcessStreams();
+ }
+}
+
+void IMuseDigital::fillStreamsWhileMusicCritical(int fillTimesAfter) {
+ if (!isFTSoundEngine()) {
+ while (isMusicCritical()) {
+ diMUSEProcessStreams();
+ }
+ }
+
+ for (int i = 0; i < fillTimesAfter; i++) {
+ diMUSEProcessStreams();
+ }
+}
+
+bool IMuseDigital::isMusicStreamIdle() {
+ int bufSize, criticalSize, freeSpace, paused;
+ IMuseDigiSndBuffer *bufInfo = _filesHandler->getBufInfo(DIMUSE_BUFFER_MUSIC);
+
+ if (!queryNextSoundFile(bufSize, criticalSize, freeSpace, paused))
+ return true;
+ return paused || (bufSize - bufInfo->loadSize < freeSpace);
+}
+
+bool IMuseDigital::isMusicCritical() {
+ int bufSize, criticalSize, freeSpace, paused;
+
+ if (!queryNextSoundFile(bufSize, criticalSize, freeSpace, paused))
+ return false;
+ return !paused && freeSpace <= criticalSize;
+}
+
+bool IMuseDigital::queryNextSoundFile(int &bufSize, int &criticalSize, int &freeSpace, int &paused) {
+ int soundId;
+ if (isFTSoundEngine()) {
+ soundId = diMUSEQueryStream(0, bufSize, criticalSize, freeSpace, paused);
+ if (soundId) {
+ while (freeSpace >= criticalSize) {
+ soundId = diMUSEQueryStream(soundId, bufSize, criticalSize, freeSpace, paused);
+ if (!soundId)
+ return false;
+ }
+ return true;
+ }
+ } else {
+ soundId = diMUSEGetNextSound(0);
+ while (soundId) {
+ if (diMUSEGetParam(soundId, DIMUSE_P_SND_HAS_STREAM) &&
+ (diMUSEGetParam(soundId, DIMUSE_P_GROUP) == DIMUSE_GROUP_MUSIC || diMUSEGetParam(soundId, DIMUSE_P_GROUP) == DIMUSE_GROUP_MUSICEFF)) {
+ diMUSEQueryStream(soundId, bufSize, criticalSize, freeSpace, paused);
+ return true;
+ }
+ soundId = diMUSEGetNextSound(soundId);
+ }
+ }
+ return false;
+}
+
void IMuseDigital::parseScriptCmds(int cmd, int soundId, int sub_cmd, int d, int e, int f, int g, int h, int i, int j, int k, int l, int m, int n, int o, int p) {
int b = soundId;
int c = sub_cmd;
@@ -829,8 +896,8 @@ int IMuseDigital::diMUSEProcessStreams() {
return cmdsHandleCmd(DIMUSE_C_PROCESS_STREAMS);
}
-void IMuseDigital::diMUSEQueryStream(int soundId, int32 &bufSize, int32 &criticalSize, int32 &freeSpace, int &paused) {
- waveQueryStream(soundId, bufSize, criticalSize, freeSpace, paused);
+int IMuseDigital::diMUSEQueryStream(int soundId, int32 &bufSize, int32 &criticalSize, int32 &freeSpace, int &paused) {
+ return waveQueryStream(soundId, bufSize, criticalSize, freeSpace, paused);
}
int IMuseDigital::diMUSEFeedStream(int soundId, uint8 *srcBuf, int32 sizeToFeed, int paused) {
diff --git a/engines/scumm/imuse_digi/dimuse_engine.h b/engines/scumm/imuse_digi/dimuse_engine.h
index 7ffdaedca99..91d21eeb1b5 100644
--- a/engines/scumm/imuse_digi/dimuse_engine.h
+++ b/engines/scumm/imuse_digi/dimuse_engine.h
@@ -127,6 +127,8 @@ private:
void playComiMusic(const char *songName, const imuseComiTable *table, int attribPos, bool sequence);
void playComiDemoMusic(const char *songName, const imuseComiTable *table, int attribPos, bool sequence);
int getSoundIdByName(const char *soundName);
+ bool isMusicStreamIdle();
+ bool isMusicCritical();
// Script
int scriptParse(int cmd, int a, int b);
@@ -173,7 +175,7 @@ private:
int streamerSetLoadIndex(IMuseDigiStream *streamPtr, int offset);
int streamerGetFreeBufferAmount(IMuseDigiStream *streamPtr);
int streamerSetSoundToStreamFromOffset(IMuseDigiStream *streamPtr, int soundId, int32 offset);
- int streamerQueryStream(IMuseDigiStream *streamPtr, int32 &bufSize, int32 &criticalSize, int32 &freeSpace, int &paused);
+ void streamerQueryStream(IMuseDigiStream *streamPtr, int32 &bufSize, int32 &criticalSize, int32 &freeSpace, int &paused);
int streamerFeedStream(IMuseDigiStream *streamPtr, uint8 *srcBuf, int32 sizeToFeed, int paused);
int streamerFetchData(IMuseDigiStream *streamPtr);
void streamerSetLoopFlag(IMuseDigiStream *streamPtr, int offset);
@@ -198,7 +200,7 @@ private:
int tracksStopSound(int soundId);
int tracksStopAllSounds();
int tracksGetNextSound(int soundId);
- void tracksQueryStream(int soundId, int32 &bufSize, int32 &criticalSize, int32 &freeSpace, int &paused);
+ int tracksQueryStream(int soundId, int32 &bufSize, int32 &criticalSize, int32 &freeSpace, int &paused);
int tracksFeedStream(int soundId, uint8 *srcBuf, int32 sizeToFeed, int paused);
void tracksClear(IMuseDigiTrack *trackPtr);
int tracksSetParam(int soundId, int opcode, int value);
@@ -276,7 +278,7 @@ private:
int waveSwitchStream(int oldSoundId, int newSoundId, int fadeLengthMs, int fadeSyncFlag2, int fadeSyncFlag1);
int waveSwitchStream(int oldSoundId, int newSoundId, uint8 *crossfadeBuffer, int crossfadeBufferSize, int vocLoopFlag);
int waveProcessStreams();
- void waveQueryStream(int soundId, int32 &bufSize, int32 &criticalSize, int32 &freeSpace, int &paused);
+ int waveQueryStream(int soundId, int32 &bufSize, int32 &criticalSize, int32 &freeSpace, int &paused);
int waveFeedStream(int soundId, uint8 *srcBuf, int32 sizeToFeed, int paused);
int waveLipSync(int soundId, int syncId, int msPos, int32 &width, int32 &height);
@@ -335,6 +337,9 @@ public:
void stopSMUSHAudio();
void receiveAudioFromSMUSH(uint8 *srcBuf, int32 inFrameCount, int32 feedSize, int32 mixBufStartIndex, int volume, int pan, bool is11025Hz);
void setSmushPlayer(SmushPlayer *splayer);
+ void floodMusicBuffer();
+ void fillStreamsWhileMusicCritical(int fillTimesAfter);
+ bool queryNextSoundFile(int &bufSize, int &criticalSize, int &freeSpace, int &paused);
bool isFTSoundEngine(); // Used in the handlers to check if we're using the FT version of the engine
@@ -372,7 +377,7 @@ public:
int diMUSESwitchStream(int oldSoundId, int newSoundId, int fadeDelay, int fadeSyncFlag2, int fadeSyncFlag1);
int diMUSESwitchStream(int oldSoundId, int newSoundId, uint8 *crossfadeBuffer, int crossfadeBufferSize, int vocLoopFlag);
int diMUSEProcessStreams();
- void diMUSEQueryStream(int soundId, int32 &bufSize, int32 &criticalSize, int32 &freeSpace, int &paused);
+ int diMUSEQueryStream(int soundId, int32 &bufSize, int32 &criticalSize, int32 &freeSpace, int &paused);
int diMUSEFeedStream(int soundId, uint8 *srcBuf, int32 sizeToFeed, int paused);
int diMUSELipSync(int soundId, int syncId, int msPos, int32 &width, int32 &height);
int diMUSEGetMusicGroupVol();
diff --git a/engines/scumm/imuse_digi/dimuse_streamer.cpp b/engines/scumm/imuse_digi/dimuse_streamer.cpp
index 69bcf80628a..169258dcbf0 100644
--- a/engines/scumm/imuse_digi/dimuse_streamer.cpp
+++ b/engines/scumm/imuse_digi/dimuse_streamer.cpp
@@ -226,13 +226,14 @@ int IMuseDigital::streamerSetSoundToStreamFromOffset(IMuseDigiStream *streamPtr,
return 0;
}
-int IMuseDigital::streamerQueryStream(IMuseDigiStream *streamPtr, int32 &bufSize, int32 &criticalSize, int32 &freeSpace, int &paused) {
- dispatchPredictFirstStream();
+void IMuseDigital::streamerQueryStream(IMuseDigiStream *streamPtr, int32 &bufSize, int32 &criticalSize, int32 &freeSpace, int &paused) {
+ if (!isFTSoundEngine())
+ dispatchPredictFirstStream();
+
bufSize = streamPtr->bufFreeSize;
- criticalSize = streamPtr->criticalSize;
+ criticalSize = (isFTSoundEngine() && streamPtr->paused) ? 0 : streamPtr->criticalSize;
freeSpace = streamerGetFreeBufferAmount(streamPtr);
paused = streamPtr->paused;
- return 0;
}
int IMuseDigital::streamerFeedStream(IMuseDigiStream *streamPtr, uint8 *srcBuf, int32 sizeToFeed, int paused) {
diff --git a/engines/scumm/imuse_digi/dimuse_tracks.cpp b/engines/scumm/imuse_digi/dimuse_tracks.cpp
index 388b6ec83a0..3d3cc0e23bd 100644
--- a/engines/scumm/imuse_digi/dimuse_tracks.cpp
+++ b/engines/scumm/imuse_digi/dimuse_tracks.cpp
@@ -282,22 +282,42 @@ int IMuseDigital::tracksGetNextSound(int soundId) {
return foundSoundId;
}
-void IMuseDigital::tracksQueryStream(int soundId, int32 &bufSize, int32 &criticalSize, int32 &freeSpace, int &paused) {
- if (!_trackList)
+int IMuseDigital::tracksQueryStream(int soundId, int32 &bufSize, int32 &criticalSize, int32 &freeSpace, int &paused) {
+ if (!_trackList) {
debug(5, "IMuseDigital::tracksQueryStream(): WARNING: empty trackList, ignoring call...");
+ return isFTSoundEngine() ? 0 : -1;
+ }
IMuseDigiTrack *track = _trackList;
- do {
- if (track->soundId) {
- if (soundId == track->soundId && track->dispatchPtr->streamPtr) {
- streamerQueryStream(track->dispatchPtr->streamPtr, bufSize, criticalSize, freeSpace, paused);
- return;
+ if (isFTSoundEngine()) {
+ IMuseDigiTrack *chosenTrack = nullptr;
+
+ do {
+ if (track->soundId > soundId && (!chosenTrack || track->soundId < chosenTrack->soundId)) {
+ if (track->dispatchPtr->streamPtr)
+ chosenTrack = track;
}
- }
- track = track->next;
- } while (track);
+ track = track->next;
+ } while (track);
- debug(5, "IMuseDigital::tracksQueryStream(): WARNING: couldn't find sound %d in trackList, ignoring call...", soundId);
+ if (!chosenTrack)
+ return 0;
+ streamerQueryStream(chosenTrack->dispatchPtr->streamPtr, bufSize, criticalSize, freeSpace, paused);
+ return chosenTrack->soundId;
+ } else {
+ do {
+ if (track->soundId) {
+ if (soundId == track->soundId && track->dispatchPtr->streamPtr) {
+ streamerQueryStream(track->dispatchPtr->streamPtr, bufSize, criticalSize, freeSpace, paused);
+ return 0;
+ }
+ }
+ track = track->next;
+ } while (track);
+
+ debug(5, "IMuseDigital::tracksQueryStream(): WARNING: couldn't find sound %d in trackList, ignoring call...", soundId);
+ return -1;
+ }
}
int IMuseDigital::tracksFeedStream(int soundId, uint8 *srcBuf, int32 sizeToFeed, int paused) {
diff --git a/engines/scumm/imuse_digi/dimuse_wave.cpp b/engines/scumm/imuse_digi/dimuse_wave.cpp
index ce8ea6e73dd..ce435474fa6 100644
--- a/engines/scumm/imuse_digi/dimuse_wave.cpp
+++ b/engines/scumm/imuse_digi/dimuse_wave.cpp
@@ -115,9 +115,9 @@ int IMuseDigital::waveProcessStreams() {
return streamerProcessStreams();
}
-void IMuseDigital::waveQueryStream(int soundId, int32 &bufSize, int32 &criticalSize, int32 &freeSpace, int &paused) {
- tracksQueryStream(soundId, bufSize, criticalSize, freeSpace, paused);
+int IMuseDigital::waveQueryStream(int soundId, int32 &bufSize, int32 &criticalSize, int32 &freeSpace, int &paused) {
Common::StackLock lock(*_mutex);
+ return tracksQueryStream(soundId, bufSize, criticalSize, freeSpace, paused);
}
int IMuseDigital::waveFeedStream(int soundId, uint8 *srcBuf, int32 sizeToFeed, int paused) {
diff --git a/engines/scumm/resource.cpp b/engines/scumm/resource.cpp
index 1cfd1ede7b3..38e8a806600 100644
--- a/engines/scumm/resource.cpp
+++ b/engines/scumm/resource.cpp
@@ -593,6 +593,8 @@ void ScummEngine::nukeCharset(int i) {
}
void ScummEngine::ensureResourceLoaded(ResType type, ResId idx) {
+ Common::StackLock lock(_resourceAccessMutex);
+
debugC(DEBUG_RESOURCE, "ensureResourceLoaded(%s,%d)", nameOfResType(type), idx);
if ((type == rtRoom) && idx > 0x7F && _game.version < 7 && _game.heversion <= 71) {
@@ -616,6 +618,21 @@ void ScummEngine::ensureResourceLoaded(ResType type, ResId idx) {
if (idx <= _res->_types[type].size() && _res->_types[type][idx]._address)
return;
+ #ifdef ENABLE_SCUMM_7_8
+ _resourceAccessMutex.unlock();
+
+ if (_imuseDigital) {
+ int bufSize, criticalSize, freeSpace, paused;
+ if (_imuseDigital->isFTSoundEngine() && _imuseDigital->queryNextSoundFile(bufSize, criticalSize, freeSpace, paused)) {
+ _imuseDigital->fillStreamsWhileMusicCritical(5);
+ } else {
+ _imuseDigital->fillStreamsWhileMusicCritical(_game.id == GID_DIG ? 30 : 20);
+ }
+ }
+
+ _resourceAccessMutex.lock();
+#endif
+
loadResource(type, idx);
if (_game.version == 5 && type == rtRoom && (int)idx == _roomResource)
diff --git a/engines/scumm/smush/smush_player.cpp b/engines/scumm/smush/smush_player.cpp
index 57b5d7a2b22..589500c6e61 100644
--- a/engines/scumm/smush/smush_player.cpp
+++ b/engines/scumm/smush/smush_player.cpp
@@ -1194,6 +1194,15 @@ void SmushPlayer::play(const char *filename, int32 speed, int32 offset, int32 st
_pauseTime = 0;
+ // This piece of code is used to ensure there are
+ // no audio hiccups while loading the SMUSH video;
+ // Each version of the engine does it in its own way.
+ if (_imuseDigital->isFTSoundEngine()) {
+ _imuseDigital->fillStreamsWhileMusicCritical(20);
+ } else {
+ _imuseDigital->floodMusicBuffer();
+ }
+
int skipped = 0;
for (;;) {
More information about the Scummvm-git-logs
mailing list