[Scummvm-git-logs] scummvm branch-3-0 -> 021792ffcf3f979ec4025142e8acf3306a1cc2c3
sluicebox
noreply at scummvm.org
Wed Dec 17 08:19:34 UTC 2025
This automated email contains information about 3 new commits which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
8020f66841 PRIVATE: Move subtitle destruction into function
977b7403a7 PRIVATE: Allow blocking sounds to be interrupted
021792ffcf PRIVATE: Allow multiple foreground sounds
Commit: 8020f6684196e6f820d6913611f41d9c7edb9950
https://github.com/scummvm/scummvm/commit/8020f6684196e6f820d6913611f41d9c7edb9950
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2025-12-17T00:17:55-08:00
Commit Message:
PRIVATE: Move subtitle destruction into function
Changed paths:
engines/private/private.cpp
engines/private/private.h
diff --git a/engines/private/private.cpp b/engines/private/private.cpp
index caed5bb27e2..3be8f925177 100644
--- a/engines/private/private.cpp
+++ b/engines/private/private.cpp
@@ -461,11 +461,7 @@ Common::Error PrivateEngine::run() {
if (_videoDecoder->endOfVideo()) {
delete _videoDecoder;
_videoDecoder = nullptr;
- if (_subtitles != nullptr) {
- delete _subtitles;
- _subtitles = nullptr;
- _system->hideOverlay();
- }
+ destroySubtitles();
_currentMovie = "";
} else if (!_videoDecoder->needsUpdate() && mouseMoved) {
_system->updateScreen();
@@ -507,9 +503,7 @@ Common::Error PrivateEngine::run() {
if (_mixer->isSoundHandleActive(_fgSoundHandle)) {
_subtitles->drawSubtitle(_mixer->getElapsedTime(_fgSoundHandle).msecs(), false, _sfxSubtitles);
} else {
- delete _subtitles;
- _subtitles = nullptr;
- _system->hideOverlay();
+ destroySubtitles();
}
}
}
@@ -2401,11 +2395,7 @@ void PrivateEngine::loadSubtitles(const Common::Path &path) {
subPath = subPath.appendComponent(subPathStr);
debugC(1, kPrivateDebugFunction, "Loading subtitles from %s", subPath.toString().c_str());
- if (_subtitles != nullptr) {
- delete _subtitles;
- _subtitles = nullptr;
- _system->hideOverlay();
- }
+ destroySubtitles();
_subtitles = new Video::Subtitles();
_subtitles->loadSRTFile(subPath);
@@ -2419,6 +2409,15 @@ void PrivateEngine::loadSubtitles(const Common::Path &path) {
_system->clearOverlay();
adjustSubtitleSize();
}
+
+void PrivateEngine::destroySubtitles() {
+ if (_subtitles != nullptr) {
+ delete _subtitles;
+ _subtitles = nullptr;
+ _system->hideOverlay();
+ }
+}
+
void PrivateEngine::playVideo(const Common::String &name) {
debugC(1, kPrivateDebugFunction, "%s(%s)", __FUNCTION__, name.c_str());
//stopSound(true);
@@ -2495,11 +2494,7 @@ void PrivateEngine::skipVideo() {
delete _videoDecoder;
_videoDecoder = nullptr;
- if (_subtitles != nullptr) {
- delete _subtitles;
- _subtitles = nullptr;
- _system->hideOverlay();
- }
+ destroySubtitles();
_currentMovie = "";
}
@@ -2510,11 +2505,7 @@ void PrivateEngine::destroyVideo() {
delete _videoDecoder;
_videoDecoder = nullptr;
_pausedVideo = nullptr;
- if (_subtitles != nullptr) {
- delete _subtitles;
- _subtitles = nullptr;
- _system->hideOverlay();
- }
+ destroySubtitles();
}
void PrivateEngine::stopSound(bool all) {
diff --git a/engines/private/private.h b/engines/private/private.h
index 24539fd2633..cd8581b9898 100644
--- a/engines/private/private.h
+++ b/engines/private/private.h
@@ -299,6 +299,7 @@ public:
void destroyVideo();
void loadSubtitles(const Common::Path &path);
+ void destroySubtitles();
void adjustSubtitleSize();
Video::Subtitles *_subtitles;
bool _useSubtitles;
Commit: 977b7403a74b30978940619e1b751acb83d22afc
https://github.com/scummvm/scummvm/commit/977b7403a74b30978940619e1b751acb83d22afc
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2025-12-17T00:18:18-08:00
Commit Message:
PRIVATE: Allow blocking sounds to be interrupted
Blocking sounds can now be interrupted by the engine quitting or the
user pressing Escape (kActionSkip)
Changed paths:
engines/private/funcs.cpp
engines/private/private.cpp
engines/private/private.h
diff --git a/engines/private/funcs.cpp b/engines/private/funcs.cpp
index 0139cf9375c..e07257e975c 100644
--- a/engines/private/funcs.cpp
+++ b/engines/private/funcs.cpp
@@ -182,7 +182,7 @@ static void fSyncSound(ArgArray args) {
g_private->drawScreen();
g_private->playSound(s, 1, true, false);
- g_private->waitForSoundToStop();
+ g_private->waitForSoundsToStop();
}
}
diff --git a/engines/private/private.cpp b/engines/private/private.cpp
index 3be8f925177..9ff25bd54c1 100644
--- a/engines/private/private.cpp
+++ b/engines/private/private.cpp
@@ -510,13 +510,6 @@ Common::Error PrivateEngine::run() {
return Common::kNoError;
}
-void PrivateEngine::ignoreEvents() {
- Common::Event event;
- _system->getEventManager()->pollEvent(event);
- _system->updateScreen();
- _system->delayMillis(10);
-}
-
void PrivateEngine::initFuncs() {
for (const Private::FuncTable *fnc = funcTable; fnc->name; fnc++) {
Common::String name(fnc->name);
@@ -642,7 +635,7 @@ void PrivateEngine::completePoliceBust() {
Common::String s("global/transiti/audio/spoc02VO.wav");
playSound(s, 1, true, false);
changeCursor("default");
- waitForSoundToStop();
+ waitForSoundsToStop();
}
// Cycle to the next movie and wrap around
@@ -2322,13 +2315,50 @@ bool PrivateEngine::isSoundActive() {
return _mixer->isSoundIDActive(-1);
}
-void PrivateEngine::waitForSoundToStop() {
- while (isSoundActive())
- ignoreEvents();
+void PrivateEngine::waitForSoundsToStop() {
+ while (isSoundActive()) {
+ if (consumeEvents()) {
+ stopSound(true);
+ return;
+ }
+ }
uint32 i = 100;
- while (i--) // one second extra
- ignoreEvents();
+ while (i--) { // one second extra
+ if (consumeEvents()) {
+ stopSound(true);
+ return;
+ }
+ }
+}
+
+// returns true if interrupted by user or engine quitting
+bool PrivateEngine::consumeEvents() {
+ if (shouldQuit()) {
+ return true;
+ }
+
+ Common::Event event;
+ while (_system->getEventManager()->pollEvent(event)) {
+ switch (event.type) {
+ case Common::EVENT_RETURN_TO_LAUNCHER:
+ case Common::EVENT_QUIT:
+ return true;
+
+ case Common::EVENT_CUSTOM_ENGINE_ACTION_START:
+ if (event.customType == kActionSkip) {
+ return true;
+ }
+ break;
+
+ default:
+ break;;
+ }
+ }
+
+ _system->updateScreen();
+ _system->delayMillis(10);
+ return false;
}
void PrivateEngine::adjustSubtitleSize() {
diff --git a/engines/private/private.h b/engines/private/private.h
index cd8581b9898..6bdff2268b4 100644
--- a/engines/private/private.h
+++ b/engines/private/private.h
@@ -288,7 +288,6 @@ public:
return true;
}
- void ignoreEvents();
Common::Error loadGameStream(Common::SeekableReadStream *stream) override;
Common::Error saveGameStream(Common::WriteStream *stream, bool isAutosave = false) override;
@@ -444,7 +443,8 @@ public:
void playPhoneCallSound();
void stopSound(bool);
bool isSoundActive();
- void waitForSoundToStop();
+ void waitForSoundsToStop();
+ bool consumeEvents();
bool _noStopSounds;
Common::String _backgroundSound;
Common::String _pausedBackgroundSound;
Commit: 021792ffcf3f979ec4025142e8acf3306a1cc2c3
https://github.com/scummvm/scummvm/commit/021792ffcf3f979ec4025142e8acf3306a1cc2c3
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2025-12-17T00:19:05-08:00
Commit Message:
PRIVATE: Allow multiple foreground sounds
- Police siren no longer interrupted by other sounds
- Wall safe alarm no longer interrupted by other sounds
- Marlowe's speech now plays when taking bag of drugs
- Radios can now be turned off when playing, as in the original
- Many misc sounds are no longer interrupted
Changed paths:
engines/private/funcs.cpp
engines/private/private.cpp
engines/private/private.h
engines/private/savegame.h
diff --git a/engines/private/funcs.cpp b/engines/private/funcs.cpp
index e07257e975c..5b0f99712b4 100644
--- a/engines/private/funcs.cpp
+++ b/engines/private/funcs.cpp
@@ -70,7 +70,7 @@ static void fChgMode(ArgArray args) {
if (g_private->_noStopSounds) {
g_private->_noStopSounds = false;
} else {
- g_private->stopSound(true);
+ g_private->stopSounds();
}
}
}
@@ -181,7 +181,8 @@ static void fSyncSound(ArgArray args) {
if (s != "\"\"") {
g_private->drawScreen();
- g_private->playSound(s, 1, true, false);
+ g_private->stopSounds();
+ g_private->playForegroundSound(s);
g_private->waitForSoundsToStop();
}
}
@@ -433,11 +434,10 @@ static void fInventory(ArgArray args) {
g_private->_toTake = true;
Common::String sound(snd.u.str);
- if (sound != "\"\"") {
- g_private->playSound(sound, 1, false, false);
- } else {
- g_private->playSound(g_private->getTakeLeaveSound(), 1, false, false);
+ if (sound == "\"\"") {
+ sound = g_private->getTakeLeaveSound();
}
+ g_private->playForegroundSound(g_private->_takeLeaveSound, sound);
} else {
Common::String flag;
if (v1.type == NAME) {
@@ -500,7 +500,7 @@ static void fSetModifiedFlag(ArgArray args) {
static void fPaperShuffleSound(ArgArray args) {
assert(args.size() == 0);
debugC(1, kPrivateDebugScript, "PaperShuffleSound()");
- g_private->playSound(g_private->getPaperShuffleSound(), 1, false, false);
+ g_private->playForegroundSound(g_private->getPaperShuffleSound());
}
static void fSoundEffect(ArgArray args) {
@@ -508,9 +508,9 @@ static void fSoundEffect(ArgArray args) {
debugC(1, kPrivateDebugScript, "SoundEffect(%s)", args[0].u.str);
Common::String s(args[0].u.str);
if (s != "\"\"") {
- g_private->playSound(s, 1, false, false);
+ g_private->playForegroundSound(s);
} else {
- g_private->stopSound(true);
+ g_private->stopSounds();
}
}
@@ -523,18 +523,18 @@ static void fSound(ArgArray args) {
int c = args[3].u.val;
if (!b1 && !b2 && c == 1) {
- g_private->stopSound(true);
+ g_private->stopSounds();
} else if (!b1 && !b2 && c == 2) {
- g_private->stopSound(false);
+ g_private->stopForegroundSounds();
} else
assert(0);
}
Common::String s(args[0].u.str);
if (s != "\"\"") {
- g_private->playSound(s, 1, false, false);
+ g_private->playForegroundSound(s);
} else {
- g_private->stopSound(true);
+ g_private->stopSounds();
}
}
@@ -545,9 +545,9 @@ static void fLoopedSound(ArgArray args) {
Common::String s(args[0].u.str);
if (s != "\"\"") {
- g_private->playSound(s, 0, false, true);
+ g_private->playBackgroundSound(s);
} else {
- g_private->stopSound(true);
+ g_private->stopSounds();
}
}
diff --git a/engines/private/private.cpp b/engines/private/private.cpp
index 9ff25bd54c1..535bbd02fc9 100644
--- a/engines/private/private.cpp
+++ b/engines/private/private.cpp
@@ -55,7 +55,7 @@ PrivateEngine::PrivateEngine(OSystem *syst, const ADGameDescription *gd)
: Engine(syst), _gameDescription(gd), _image(nullptr), _videoDecoder(nullptr),
_compositeSurface(nullptr), _transparentColor(0), _frameImage(nullptr),
_framePalette(nullptr),
- _subtitles(nullptr), _sfxSubtitles(false), _useSubtitles(false),
+ _subtitles(nullptr), _subtitledSound(nullptr), _sfxSubtitles(false), _useSubtitles(false),
_defaultCursor(nullptr),
_screenW(640), _screenH(480) {
_highlightMasks = false;
@@ -99,9 +99,10 @@ PrivateEngine::PrivateEngine(OSystem *syst, const ADGameDescription *gd)
_AMRadioArea.clear();
_phoneArea.clear();
_AMRadio.path = "inface/radio/comm_/";
+ _AMRadio.sound = &_AMRadioSound;
_policeRadio.path = "inface/radio/police/";
+ _policeRadio.sound = &_policeRadioSound;
_phonePrefix = "inface/telephon/";
- _phoneCallSound = "phone.wav";
// Dossiers
_dossierPage = 0;
@@ -455,7 +456,7 @@ Common::Error PrivateEngine::run() {
if (_videoDecoder && !_videoDecoder->isPaused()) {
if (_videoDecoder->getCurFrame() == 0) {
- stopSound(true);
+ stopSounds();
}
if (_videoDecoder->endOfVideo()) {
@@ -500,8 +501,8 @@ Common::Error PrivateEngine::run() {
_system->updateScreen();
_system->delayMillis(10);
if (_subtitles != nullptr) {
- if (_mixer->isSoundHandleActive(_fgSoundHandle)) {
- _subtitles->drawSubtitle(_mixer->getElapsedTime(_fgSoundHandle).msecs(), false, _sfxSubtitles);
+ if (_subtitledSound != nullptr && isSoundPlaying(*_subtitledSound)) {
+ _subtitles->drawSubtitle(_mixer->getElapsedTime(_subtitledSound->handle).msecs(), false, _sfxSubtitles);
} else {
destroySubtitles();
}
@@ -633,7 +634,8 @@ void PrivateEngine::completePoliceBust() {
// Play audio on the second bust movie
if (kPoliceBustVideos[_policeBustMovieIndex] == 2) {
Common::String s("global/transiti/audio/spoc02VO.wav");
- playSound(s, 1, true, false);
+ stopSounds();
+ playForegroundSound(s);
changeCursor("default");
waitForSoundsToStop();
}
@@ -659,8 +661,7 @@ void PrivateEngine::checkPoliceBust() {
if (!_policeSirenPlayed) {
// Play siren
- stopSound(true);
- playSound(_sirenSound, 1, false, false);
+ playForegroundSound(_sirenSound);
_policeSirenPlayed = true;
_numberOfClicks = _numberClicksAfterSiren;
@@ -901,7 +902,7 @@ void PrivateEngine::selectPauseGame(Common::Point mousePos) {
_pausedVideo = _videoDecoder;
}
- _pausedBackgroundSound = _backgroundSound;
+ _pausedBackgroundSoundName = _bgSound.name;
_compositeSurface->fillRect(_screenRect, 0);
_compositeSurface->setPalette(_framePalette, 0, 256);
@@ -929,9 +930,9 @@ void PrivateEngine::resumeGame() {
_needToDrawScreenFrame = true;
}
- if (!_pausedBackgroundSound.empty()) {
- playSound(_pausedBackgroundSound, 0, false, true);
- _pausedBackgroundSound.clear();
+ if (!_pausedBackgroundSoundName.empty()) {
+ playBackgroundSound(_pausedBackgroundSoundName);
+ _pausedBackgroundSoundName.clear();
}
}
@@ -950,7 +951,7 @@ bool PrivateEngine::selectExit(Common::Point mousePos) {
if (cs < rs && !e.nextSetting.empty()) { // TODO: check this
// an item was not taken
if (_toTake) {
- playSound(getLeaveSound(), 1, false, false);
+ playForegroundSound(_takeLeaveSound, getLeaveSound());
_toTake = false;
}
@@ -987,7 +988,7 @@ bool PrivateEngine::selectMask(Common::Point mousePos) {
// an item was taken
if (_toTake) {
addInventory(m.inventoryItem, *(m.flag1->name));
- playSound(getTakeSound(), 1, false, false);
+ playForegroundSound(_takeLeaveSound, getTakeSound());
_toTake = false;
_haveTakenItem = true;
}
@@ -1056,7 +1057,7 @@ bool PrivateEngine::selectDiaryNextPage(Common::Point mousePos) {
_currentDiaryPage++;
_nextSetting = _diaryNextPageExit.nextSetting;
- playSound(getPaperShuffleSound(), 1, false, false);
+ playForegroundSound(getPaperShuffleSound());
return true;
}
@@ -1073,7 +1074,7 @@ bool PrivateEngine::selectDiaryPrevPage(Common::Point mousePos) {
_currentDiaryPage--;
_nextSetting = _diaryPrevPageExit.nextSetting;
- playSound(getPaperShuffleSound(), 1, false, false);
+ playForegroundSound(getPaperShuffleSound());
return true;
}
@@ -1338,7 +1339,7 @@ bool PrivateEngine::selectDossierNextSuspect(Common::Point mousePos) {
if (inMask(_dossierNextSuspectMask.surf, mousePos)) {
if ((_dossierSuspect + 1) < _dossiers.size()) {
- playSound(getPaperShuffleSound(), 1, false, false);
+ playForegroundSound(getPaperShuffleSound());
_dossierSuspect++;
_dossierPage = 0;
@@ -1356,7 +1357,7 @@ bool PrivateEngine::selectDossierPrevSheet(Common::Point mousePos) {
if (inMask(_dossierPrevSheetMask.surf, mousePos)) {
if (_dossierPage == 1) {
- playSound(getPaperShuffleSound(), 1, false, false);
+ playForegroundSound(getPaperShuffleSound());
_dossierPage = 0;
// reload kDossierOpen
@@ -1374,7 +1375,7 @@ bool PrivateEngine::selectDossierNextSheet(Common::Point mousePos) {
if (inMask(_dossierNextSheetMask.surf, mousePos)) {
DossierInfo m = _dossiers[_dossierSuspect];
if (_dossierPage == 0 && !m.page2.empty()) {
- playSound(getPaperShuffleSound(), 1, false, false);
+ playForegroundSound(getPaperShuffleSound());
_dossierPage = 1;
// reload kDossierOpen
@@ -1391,7 +1392,7 @@ bool PrivateEngine::selectDossierPrevSuspect(Common::Point mousePos) {
if (inMask(_dossierPrevSuspectMask.surf, mousePos)) {
if (_dossierSuspect > 0) {
- playSound(getPaperShuffleSound(), 1, false, false);
+ playForegroundSound(getPaperShuffleSound());
_dossierSuspect--;
_dossierPage = 0;
@@ -1581,6 +1582,12 @@ void PrivateEngine::disableRadioClips(Radio &radio, int priority) {
}
void PrivateEngine::playRadio(Radio &radio, bool randomlyDisableClips) {
+ // if radio is already playing then turn it off
+ if (isSoundPlaying(*(radio.sound))) {
+ stopForegroundSounds();
+ return;
+ }
+
// search channels for first available clip
for (uint i = 0; i < ARRAYSIZE(radio.channels); i++) {
// skip empty channels
@@ -1606,7 +1613,8 @@ void PrivateEngine::playRadio(Radio &radio, bool randomlyDisableClips) {
// play the clip
Common::String sound = radio.path + clip.name + ".wav";
- playSound(sound, 1, false, false);
+ stopForegroundSounds();
+ playForegroundSound(*(radio.sound), sound);
clip.played = true;
if (!clip.flagName.empty()) {
Symbol *flag = maps.lookupVariable(&(clip.flagName));
@@ -1616,7 +1624,8 @@ void PrivateEngine::playRadio(Radio &radio, bool randomlyDisableClips) {
}
// play default radio sound
- playSound("inface/radio/radio.wav", 1, false, false);
+ stopForegroundSounds();
+ playForegroundSound(*(radio.sound), "inface/radio/radio.wav");
}
void PrivateEngine::addPhone(const Common::String &name, bool once, int startIndex, int endIndex, const Common::String &flagName, int flagValue) {
@@ -1691,7 +1700,7 @@ void PrivateEngine::checkPhoneCall() {
return;
}
- if (isSoundActive()) {
+ if (isSoundPlaying()) {
return;
}
@@ -1718,7 +1727,7 @@ void PrivateEngine::checkPhoneCall() {
phone->status = kPhoneStatusCalling;
phone->callCount++;
- playPhoneCallSound();
+ playForegroundSound(_phoneCallSound, _phonePrefix + "phone.wav");
}
bool PrivateEngine::cursorPhoneArea(Common::Point mousePos) {
@@ -1726,7 +1735,7 @@ bool PrivateEngine::cursorPhoneArea(Common::Point mousePos) {
return false;
}
- if (!_mixer->isSoundHandleActive(_phoneCallSoundHandle)) {
+ if (!isSoundPlaying(_phoneCallSound)) {
return false;
}
@@ -1743,7 +1752,7 @@ bool PrivateEngine::selectPhoneArea(Common::Point mousePos) {
return false;
}
- if (!_mixer->isSoundHandleActive(_phoneCallSoundHandle)) {
+ if (!isSoundPlaying(_phoneCallSound)) {
return false;
}
@@ -1773,8 +1782,10 @@ bool PrivateEngine::selectPhoneArea(Common::Point mousePos) {
setSymbol(flag, phone->flagValue);
}
- playSound(sound, 1, true, false);
+ stopForegroundSounds(); // stop phone ringing
+ playForegroundSound(sound);
_nextSetting = getListenToPhoneSetting();
+ changeCursor("default");
return true;
}
return false;
@@ -1909,8 +1920,7 @@ void PrivateEngine::restartGame() {
_AMRadio.clear();
_policeRadio.clear();
_phones.clear();
- _backgroundSound.clear();
- _pausedBackgroundSound.clear();
+ _pausedBackgroundSoundName.clear();
// Movies
_repeatedMovieExit = "";
@@ -1932,7 +1942,7 @@ void PrivateEngine::restartGame() {
Common::Error PrivateEngine::loadGameStream(Common::SeekableReadStream *stream) {
// We don't want to continue with any sound or videos from a previous game
- stopSound(true);
+ stopSounds();
destroyVideo();
debugC(1, kPrivateDebugFunction, "loadGameStream");
@@ -2093,9 +2103,9 @@ Common::Error PrivateEngine::loadGameStream(Common::SeekableReadStream *stream)
// Sounds
if (meta.version >= 4) {
- _pausedBackgroundSound = stream->readString();
+ _pausedBackgroundSoundName = stream->readString();
} else {
- _pausedBackgroundSound.clear();
+ _pausedBackgroundSoundName.clear();
}
return Common::kNoError;
@@ -2245,7 +2255,7 @@ Common::Error PrivateEngine::saveGameStream(Common::WriteStream *stream, bool is
stream->writeUint32LE(0);
// Sounds
- stream->writeString(_pausedBackgroundSound);
+ stream->writeString(_pausedBackgroundSoundName);
stream->writeByte(0);
return Common::kNoError;
@@ -2269,56 +2279,84 @@ Common::Path PrivateEngine::convertPath(const Common::String &name) {
return Common::Path(path);
}
-void PrivateEngine::playSound(const Common::String &name, uint loops, bool stopOthers, bool background) {
- debugC(1, kPrivateDebugFunction, "%s(%s,%d,%d,%d)", __FUNCTION__, name.c_str(), loops, stopOthers, background);
-
- Common::Path path = convertPath(name);
- Common::SeekableReadStream *file = Common::MacResManager::openFileOrDataFork(path);
-
- if (!file)
- error("unable to find sound file %s", path.toString().c_str());
+void PrivateEngine::playBackgroundSound(const Common::String &name) {
+ playSound(_bgSound, name, true);
+}
- Audio::LoopingAudioStream *stream;
- stream = new Audio::LoopingAudioStream(Audio::makeWAVStream(file, DisposeAfterUse::YES), loops);
- if (stopOthers) {
- stopSound(true);
+void PrivateEngine::playForegroundSound(const Common::String &name) {
+ // stop sound if already playing. for example, the wall safe alarm.
+ for (uint i = 0; i < ARRAYSIZE(_fgSounds); i++) {
+ if (_fgSounds[i].name == name) {
+ if (isSoundPlaying(_fgSounds[i])) {
+ stopSound(_fgSounds[i]);
+ break;
+ }
+ }
}
- Audio::SoundHandle *sh = nullptr;
- if (background) {
- _mixer->stopHandle(_bgSoundHandle);
- sh = &_bgSoundHandle;
- _backgroundSound = name;
- } else {
- _mixer->stopHandle(_fgSoundHandle);
- _mixer->stopHandle(_phoneCallSoundHandle);
- sh = &_fgSoundHandle;
+ // play using the first available sound
+ for (uint i = 0; i < ARRAYSIZE(_fgSounds); i++) {
+ if (!isSoundPlaying(_fgSounds[i])) {
+ playSound(_fgSounds[i], name, false);
+ break;
+ }
}
+}
- _mixer->playStream(Audio::Mixer::kSFXSoundType, sh, stream, -1, Audio::Mixer::kMaxChannelVolume);
- loadSubtitles(path);
+void PrivateEngine::playForegroundSound(Sound &sound, const Common::String &name) {
+ playSound(sound, name, false);
}
-void PrivateEngine::playPhoneCallSound() {
- debugC(1, kPrivateDebugFunction, "%s()", __FUNCTION__);
+void PrivateEngine::playSound(Sound &sound, const Common::String &name, bool loop) {
+ sound.name = name;
- Common::Path path = convertPath(_phonePrefix + _phoneCallSound);
+ Common::Path path = convertPath(name);
Common::SeekableReadStream *file = Common::MacResManager::openFileOrDataFork(path);
- if (!file) {
+
+ if (file == nullptr) {
error("unable to find sound file %s", path.toString().c_str());
}
- Audio::SeekableAudioStream *audioStream = Audio::makeWAVStream(file, DisposeAfterUse::YES);
- _mixer->playStream(Audio::Mixer::kSFXSoundType, &_phoneCallSoundHandle, audioStream, -1, Audio::Mixer::kMaxChannelVolume);
+
+ Audio::LoopingAudioStream *stream = new Audio::LoopingAudioStream(Audio::makeWAVStream(file, DisposeAfterUse::YES), loop ? 0 : 1);
+
+ _mixer->stopHandle(sound.handle);
+ _mixer->playStream(Audio::Mixer::kSFXSoundType, &sound.handle, stream, -1, Audio::Mixer::kMaxChannelVolume);
+
+ loadSubtitles(path, &sound);
+}
+
+void PrivateEngine::stopForegroundSounds() {
+ for (uint i = 0; i < ARRAYSIZE(_fgSounds); i++) {
+ stopSound(_fgSounds[i]);
+ }
+ stopSound(_phoneCallSound);
+ stopSound(_AMRadioSound);
+ stopSound(_policeRadioSound);
+ stopSound(_takeLeaveSound);
+}
+
+void PrivateEngine::stopSounds() {
+ stopSound(_bgSound);
+ stopForegroundSounds();
+}
+
+void PrivateEngine::stopSound(Sound &sound) {
+ _mixer->stopHandle(sound.handle);
+ sound.name.clear();
}
-bool PrivateEngine::isSoundActive() {
+bool PrivateEngine::isSoundPlaying() {
return _mixer->isSoundIDActive(-1);
}
+bool PrivateEngine::isSoundPlaying(Sound &sound) {
+ return _mixer->isSoundHandleActive(sound.handle);
+}
+
void PrivateEngine::waitForSoundsToStop() {
- while (isSoundActive()) {
+ while (isSoundPlaying()) {
if (consumeEvents()) {
- stopSound(true);
+ stopSounds();
return;
}
}
@@ -2326,7 +2364,7 @@ void PrivateEngine::waitForSoundsToStop() {
uint32 i = 100;
while (i--) { // one second extra
if (consumeEvents()) {
- stopSound(true);
+ stopSounds();
return;
}
}
@@ -2408,7 +2446,7 @@ void PrivateEngine::adjustSubtitleSize() {
}
}
-void PrivateEngine::loadSubtitles(const Common::Path &path) {
+void PrivateEngine::loadSubtitles(const Common::Path &path, Sound *sound) {
debugC(1, kPrivateDebugFunction, "%s(%s)", __FUNCTION__, path.toString().c_str());
if (!_useSubtitles)
return;
@@ -2435,6 +2473,8 @@ void PrivateEngine::loadSubtitles(const Common::Path &path) {
return;
}
+ _subtitledSound = sound;
+
_system->showOverlay(false);
_system->clearOverlay();
adjustSubtitleSize();
@@ -2445,12 +2485,13 @@ void PrivateEngine::destroySubtitles() {
delete _subtitles;
_subtitles = nullptr;
_system->hideOverlay();
+ _subtitledSound = nullptr;
}
}
void PrivateEngine::playVideo(const Common::String &name) {
debugC(1, kPrivateDebugFunction, "%s(%s)", __FUNCTION__, name.c_str());
- //stopSound(true);
+
Common::Path path = convertPath(name);
Common::SeekableReadStream *file = Common::MacResManager::openFileOrDataFork(path);
@@ -2538,18 +2579,6 @@ void PrivateEngine::destroyVideo() {
destroySubtitles();
}
-void PrivateEngine::stopSound(bool all) {
- debugC(1, kPrivateDebugFunction, "%s(%d)", __FUNCTION__, all);
-
- _mixer->stopHandle(_fgSoundHandle);
- _mixer->stopHandle(_phoneCallSoundHandle);
-
- if (all) {
- _mixer->stopHandle(_bgSoundHandle);
- _backgroundSound.clear();
- }
-}
-
Graphics::Surface *PrivateEngine::decodeImage(const Common::String &name, byte **palette, bool *isNewPalette) {
debugC(1, kPrivateDebugFunction, "%s(%s)", __FUNCTION__, name.c_str());
Common::Path path = convertPath(name);
diff --git a/engines/private/private.h b/engines/private/private.h
index 6bdff2268b4..adc95c61988 100644
--- a/engines/private/private.h
+++ b/engines/private/private.h
@@ -126,6 +126,11 @@ enum PhoneStatus : byte {
kPhoneStatusAnswered
};
+typedef struct Sound {
+ Common::String name;
+ Audio::SoundHandle handle;
+} Sound;
+
typedef struct PhoneInfo {
Common::String name;
bool once;
@@ -153,10 +158,11 @@ typedef struct RadioClip {
typedef struct Radio {
Common::String path;
+ Sound *sound;
Common::Array<RadioClip> clips;
int channels[3];
- Radio() {
+ Radio() : sound(nullptr) {
clear();
}
@@ -244,9 +250,6 @@ public:
SymbolMaps maps;
- Audio::SoundHandle _fgSoundHandle;
- Audio::SoundHandle _bgSoundHandle;
- Audio::SoundHandle _phoneCallSoundHandle;
Video::SmackerDecoder *_videoDecoder;
Video::SmackerDecoder *_pausedVideo;
@@ -297,10 +300,11 @@ public:
void skipVideo();
void destroyVideo();
- void loadSubtitles(const Common::Path &path);
+ void loadSubtitles(const Common::Path &path, Sound *sound = nullptr);
void destroySubtitles();
void adjustSubtitleSize();
Video::Subtitles *_subtitles;
+ Sound *_subtitledSound;
bool _useSubtitles;
bool _sfxSubtitles;
@@ -439,15 +443,25 @@ public:
MaskList _masks;
// Sounds
- void playSound(const Common::String &, uint, bool, bool);
- void playPhoneCallSound();
- void stopSound(bool);
- bool isSoundActive();
+ void playBackgroundSound(const Common::String &name);
+ void playForegroundSound(const Common::String &name);
+ void playForegroundSound(Sound &sound, const Common::String &name);
+ void playSound(Sound &sound, const Common::String &name, bool loop);
+ void stopForegroundSounds();
+ void stopSounds();
+ void stopSound(Sound &sound);
+ bool isSoundPlaying();
+ bool isSoundPlaying(Sound &sound);
void waitForSoundsToStop();
bool consumeEvents();
+ Sound _bgSound;
+ Sound _fgSounds[4];
+ Sound _phoneCallSound;
+ Sound _AMRadioSound;
+ Sound _policeRadioSound;
+ Sound _takeLeaveSound;
bool _noStopSounds;
- Common::String _backgroundSound;
- Common::String _pausedBackgroundSound;
+ Common::String _pausedBackgroundSoundName;
Common::String getPaperShuffleSound();
Common::String _globalAudioPath;
@@ -477,7 +491,6 @@ public:
// Phone
MaskInfo _phoneArea;
Common::String _phonePrefix;
- Common::String _phoneCallSound;
PhoneList _phones;
void addPhone(const Common::String &name, bool once, int startIndex, int endIndex, const Common::String &flagName, int flagValue);
void initializePhoneOnDesktop();
diff --git a/engines/private/savegame.h b/engines/private/savegame.h
index a6f59d437d3..eeccd27b82c 100644
--- a/engines/private/savegame.h
+++ b/engines/private/savegame.h
@@ -36,7 +36,7 @@ namespace Private {
//
// Version - new/changed feature
// =============================
-// 4 - _pausedBackgroundSound (December 2025)
+// 4 - _pausedBackgroundSoundName (December 2025)
// 3 - Radio detailed state (December 2025)
// 2 - Phone clip detailed state (December 2025)
// 1 - Metadata header and more game state (November 2025)
More information about the Scummvm-git-logs
mailing list