DIRECTOR: Allow multiple concurrent sound fades

Fixes collecting the orange heart in The Seven Colors.
This commit is contained in:
Scott Percival 2024-03-21 02:45:10 +08:00 committed by Eugene Sandulenko
parent 637caad1c3
commit 12cf67948d
5 changed files with 35 additions and 44 deletions

View File

@ -3123,7 +3123,7 @@ void LB::b_sound(int nargs) {
TYPECHECK(firstArg, INT);
soundManager->registerFade(firstArg.u.i, true, ticks);
score->_activeFade = firstArg.u.i;
score->_activeFade = true;
return;
} else if (verb.u.s->equalsIgnoreCase("fadeOut")) {
if (nargs > 2) {
@ -3135,7 +3135,7 @@ void LB::b_sound(int nargs) {
TYPECHECK2(firstArg, INT, FLOAT);
soundManager->registerFade(firstArg.asInt(), false, ticks);
score->_activeFade = firstArg.u.i;
score->_activeFade = true;
return;
} else if (verb.u.s->equalsIgnoreCase("playFile")) {
ARGNUMCHECK(3)

View File

@ -79,7 +79,7 @@ Score::Score(Movie *movie) {
_cursorDirty = false;
_waitForClick = false;
_waitForClickCursor = false;
_activeFade = 0;
_activeFade = false;
_playState = kPlayNotStarted;
_numChannelsDisplayed = 0;
@ -490,8 +490,7 @@ void Score::updateNextFrameTime() {
void Score::update() {
if (_activeFade) {
if (!_soundManager->fadeChannel(_activeFade))
_activeFade = 0;
_activeFade = _soundManager->fadeChannels();
}
if (!debugChannelSet(-1, kDebugFast)) {
@ -825,8 +824,7 @@ bool Score::renderPrePaletteCycle(RenderMode mode) {
g_director->setPalette(calcPal, 256);
g_director->draw();
if (_activeFade) {
if (!_soundManager->fadeChannel(_activeFade))
_activeFade = 0;
_activeFade = _soundManager->fadeChannels();
}
// On click, stop loop and reset palette
if (_vm->processEvents(true)) {
@ -869,8 +867,7 @@ bool Score::renderPrePaletteCycle(RenderMode mode) {
g_director->setPalette(calcPal, 256);
g_director->draw();
if (_activeFade) {
if (!_soundManager->fadeChannel(_activeFade))
_activeFade = 0;
_activeFade = _soundManager->fadeChannels();
}
// On click, stop loop and reset palette
if (_vm->processEvents(true)) {
@ -986,8 +983,7 @@ void Score::renderPaletteCycle(RenderMode mode) {
g_director->shiftPalette(firstColor, lastColor, false);
g_director->draw();
if (_activeFade) {
if (!_soundManager->fadeChannel(_activeFade))
_activeFade = 0;
_activeFade = _soundManager->fadeChannels();
}
// On click, stop loop and reset palette
if (_vm->processEvents(true)) {
@ -1004,8 +1000,7 @@ void Score::renderPaletteCycle(RenderMode mode) {
g_director->shiftPalette(firstColor, lastColor, true);
g_director->draw();
if (_activeFade) {
if (!_soundManager->fadeChannel(_activeFade))
_activeFade = 0;
_activeFade = _soundManager->fadeChannels();
}
// On click, stop loop and reset palette
if (_vm->processEvents(true)) {
@ -1126,8 +1121,7 @@ void Score::renderPaletteCycle(RenderMode mode) {
for (int i = 0; i < kFadeColorWait; i++) {
uint32 startTime = g_system->getMillis();
if (_activeFade) {
if (!_soundManager->fadeChannel(_activeFade))
_activeFade = 0;
_activeFade = _soundManager->fadeChannels();
}
// On click, stop loop and reset palette
if (_vm->processEvents(true)) {
@ -1154,8 +1148,7 @@ void Score::renderPaletteCycle(RenderMode mode) {
g_director->setPalette(calcPal, 256);
g_director->draw();
if (_activeFade) {
if (!_soundManager->fadeChannel(_activeFade))
_activeFade = 0;
_activeFade = _soundManager->fadeChannels();
}
// On click, stop loop and reset palette
if (_vm->processEvents(true)) {

View File

@ -181,7 +181,7 @@ public:
bool _waitForClick;
bool _waitForClickCursor;
bool _cursorDirty;
int _activeFade;
bool _activeFade;
Cursor _defaultCursor;
CursorRef _currentCursor;
bool _skipTransition;

View File

@ -278,35 +278,33 @@ void DirectorSound::registerFade(uint8 soundChannel, bool fadeIn, int ticks) {
_channels[soundChannel]->volume = startVol;
}
bool DirectorSound::fadeChannel(uint8 soundChannel) {
if (!assertChannel(soundChannel))
return false;
bool DirectorSound::fadeChannels() {
bool ongoing = false;
if (!_mixer->isSoundHandleActive(_channels[soundChannel]->handle))
return false;
for (auto &it : _channels) {
FadeParams *fade = it._value->fade;
if (!fade)
continue;
FadeParams *fade = _channels[soundChannel]->fade;
if (!fade)
return false;
fade->lapsedTicks = _window->getVM()->getMacTicks() - fade->startTicks;
if (fade->lapsedTicks > fade->totalTicks) {
continue;
}
fade->lapsedTicks = _window->getVM()->getMacTicks() - fade->startTicks;
if (fade->lapsedTicks > fade->totalTicks) {
return false;
int fadeVol;
if (fade->fadeIn) {
fadeVol = MIN(fade->lapsedTicks * ((float)fade->targetVol / fade->totalTicks), (float)Audio::Mixer::kMaxChannelVolume);
} else {
fadeVol = MAX((fade->totalTicks - fade->lapsedTicks) * ((float)fade->startVol / fade->totalTicks), (float)0);
}
debugC(5, kDebugSound, "DirectorSound::fadeChannel(): fading channel %d volume to %d", it._key, fadeVol);
_mixer->setChannelVolume(it._value->handle, fadeVol);
it._value->volume = fadeVol;
ongoing = true;
}
int fadeVol;
if (fade->fadeIn) {
fadeVol = MIN(fade->lapsedTicks * ((float)fade->targetVol / fade->totalTicks), (float)Audio::Mixer::kMaxChannelVolume);
} else {
fadeVol = MAX((fade->totalTicks - fade->lapsedTicks) * ((float)fade->startVol / fade->totalTicks), (float)0);
}
debugC(5, kDebugSound, "DirectorSound::fadeChannel(): fading channel %d volume to %d", soundChannel, fadeVol);
_mixer->setChannelVolume(_channels[soundChannel]->handle, fadeVol);
_channels[soundChannel]->volume = fadeVol;
return true;
return ongoing;
}
void DirectorSound::cancelFade(uint8 soundChannel) {

View File

@ -201,7 +201,7 @@ public:
Common::String getCurrentSound() { return _currentSoundName; }
void registerFade(uint8 soundChannel, bool fadeIn, int ticks);
bool fadeChannel(uint8 soundChannel);
bool fadeChannels();
bool isChannelActive(uint8 soundChannel);
uint8 getChannelVolume(uint8 soundChannel);