[Scummvm-git-logs] scummvm master -> 00a1ba2ee875fb0421ab383a0148e9fdfa95d384
djsrv
dservilla at gmail.com
Wed Jul 28 02:56:32 UTC 2021
This automated email contains information about 5 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
8a9b1cd09c DIRECTOR: Give each window its own sound manager
a2e8da00e5 DIRECTOR: Don't render next frame if exitFrame stopped the movie
a16d823201 DIRECTOR: Improve puppetSound
ff16d808c7 DIRECTOR: LINGO: Play puppet sounds in updateStage
00a1ba2ee8 DIRECTOR: Disable puppet sounds when the movie changes
Commit: 8a9b1cd09cc9ee21a1da7a1d6b62a88b84ca88cf
https://github.com/scummvm/scummvm/commit/8a9b1cd09cc9ee21a1da7a1d6b62a88b84ca88cf
Author: djsrv (dservilla at gmail.com)
Date: 2021-07-27T22:42:09-04:00
Commit Message:
DIRECTOR: Give each window its own sound manager
This Should prevent conflicts between the sound channels of movies
running in parallel.
Changed paths:
engines/director/director.cpp
engines/director/director.h
engines/director/lingo/lingo-builtins.cpp
engines/director/lingo/lingo-funcs.cpp
engines/director/lingo/lingo-the.cpp
engines/director/lingo/xlibs/fplayxobj.cpp
engines/director/score.cpp
engines/director/sound.cpp
engines/director/sound.h
engines/director/window.cpp
engines/director/window.h
diff --git a/engines/director/director.cpp b/engines/director/director.cpp
index a0c49e867b..571185b788 100644
--- a/engines/director/director.cpp
+++ b/engines/director/director.cpp
@@ -68,7 +68,6 @@ DirectorEngine::DirectorEngine(OSystem *syst, const DirectorGameDescription *gam
// Load key codes
loadKeyCodes();
- _soundManager = nullptr;
_currentPalette = nullptr;
_currentPaletteLength = 0;
_stage = nullptr;
@@ -104,7 +103,6 @@ DirectorEngine::DirectorEngine(OSystem *syst, const DirectorGameDescription *gam
DirectorEngine::~DirectorEngine() {
delete _windowList;
- delete _soundManager;
delete _lingo;
delete _wm;
delete _surface;
@@ -148,8 +146,6 @@ Common::Error DirectorEngine::run() {
_currentPalette = nullptr;
- _soundManager = nullptr;
-
wmMode = debugChannelSet(-1, kDebugDesktop) ? wmModeDesktop : wmModeFullscreen;
if (debugChannelSet(-1, kDebug32bpp))
@@ -175,7 +171,6 @@ Common::Error DirectorEngine::run() {
_currentWindow = _stage;
_lingo = new Lingo(this);
- _soundManager = new DirectorSound(this);
if (getGameGID() == GID_TEST) {
_currentWindow->runTests();
diff --git a/engines/director/director.h b/engines/director/director.h
index f73bd9c73f..432bb0b4b9 100644
--- a/engines/director/director.h
+++ b/engines/director/director.h
@@ -190,7 +190,6 @@ public:
const char *getExtra();
Common::String getEXEName() const;
StartMovie getStartMovie() const;
- DirectorSound *getSoundManager() const { return _soundManager; }
Graphics::MacWindowManager *getMacWindowManager() const { return _wm; }
Archive *getMainArchive() const;
Lingo *getLingo() const { return _lingo; }
@@ -256,7 +255,6 @@ private:
const DirectorGameDescription *_gameDescription;
Common::FSNode _gameDataDir;
- DirectorSound *_soundManager;
byte *_currentPalette;
uint16 _currentPaletteLength;
Lingo *_lingo;
diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp
index 666c1279ff..b62b9b89ed 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -1928,7 +1928,7 @@ void LB::b_puppetSound(int nargs) {
return;
}
- DirectorSound *sound = g_director->getSoundManager();
+ DirectorSound *sound = g_director->getCurrentWindow()->getSoundManager();
Score *score = g_director->getCurrentMovie()->getScore();
if (!score) {
@@ -2402,6 +2402,8 @@ void LB::b_sound(int nargs) {
return;
}
+ DirectorSound *soundManager = g_director->getCurrentWindow()->getSoundManager();
+
if (verb.u.s->equalsIgnoreCase("close") || verb.u.s->equalsIgnoreCase("stop")) {
if (nargs != 2) {
warning("sound %s: expected 1 argument, got %d", verb.u.s->c_str(), nargs - 1);
@@ -2409,7 +2411,7 @@ void LB::b_sound(int nargs) {
}
TYPECHECK(firstArg, INT);
- g_director->getSoundManager()->stopSound(firstArg.u.i);
+ soundManager->stopSound(firstArg.u.i);
} else if (verb.u.s->equalsIgnoreCase("fadeIn")) {
if (nargs > 2) {
TYPECHECK(secondArg, INT);
@@ -2419,7 +2421,7 @@ void LB::b_sound(int nargs) {
}
TYPECHECK(firstArg, INT);
- g_director->getSoundManager()->registerFade(firstArg.u.i, true, ticks);
+ soundManager->registerFade(firstArg.u.i, true, ticks);
g_director->getCurrentMovie()->getScore()->_activeFade = firstArg.u.i;
return;
} else if (verb.u.s->equalsIgnoreCase("fadeOut")) {
@@ -2431,7 +2433,7 @@ void LB::b_sound(int nargs) {
}
TYPECHECK(firstArg, INT);
- g_director->getSoundManager()->registerFade(firstArg.u.i, false, ticks);
+ soundManager->registerFade(firstArg.u.i, false, ticks);
g_director->getCurrentMovie()->getScore()->_activeFade = firstArg.u.i;
return;
} else if (verb.u.s->equalsIgnoreCase("playFile")) {
@@ -2440,14 +2442,14 @@ void LB::b_sound(int nargs) {
TYPECHECK(firstArg, INT);
TYPECHECK(secondArg, STRING);
- g_director->getSoundManager()->playFile(pathMakeRelative(*secondArg.u.s), firstArg.u.i);
+ soundManager->playFile(pathMakeRelative(*secondArg.u.s), firstArg.u.i);
} else {
warning("b_sound: unknown verb %s", verb.u.s->c_str());
}
}
void LB::b_soundBusy(int nargs) {
- DirectorSound *sound = g_director->getSoundManager();
+ DirectorSound *sound = g_director->getCurrentWindow()->getSoundManager();
Datum whichChannel = g_lingo->pop();
TYPECHECK(whichChannel, INT);
diff --git a/engines/director/lingo/lingo-funcs.cpp b/engines/director/lingo/lingo-funcs.cpp
index 9a5b78781d..c87515f730 100644
--- a/engines/director/lingo/lingo-funcs.cpp
+++ b/engines/director/lingo/lingo-funcs.cpp
@@ -169,7 +169,7 @@ void Lingo::func_mci(const Common::String &name) {
uint32 from = strtol(params[1].c_str(), 0, 10);
uint32 to = strtol(params[2].c_str(), 0, 10);
- _vm->getSoundManager()->playMCI(*_audioAliases[params[0]], from, to);
+ _vm->getCurrentWindow()->getSoundManager()->playMCI(*_audioAliases[params[0]], from, to);
}
break;
default:
@@ -325,7 +325,7 @@ void Lingo::func_cursor(int cursorId) {
void Lingo::func_beep(int repeats) {
for (int r = 1; r <= repeats; r++) {
- _vm->getSoundManager()->systemBeep();
+ _vm->getCurrentWindow()->getSoundManager()->systemBeep();
if (r < repeats)
g_system->delayMillis(400);
}
diff --git a/engines/director/lingo/lingo-the.cpp b/engines/director/lingo/lingo-the.cpp
index 088df38f03..8462b8d9d3 100644
--- a/engines/director/lingo/lingo-the.cpp
+++ b/engines/director/lingo/lingo-the.cpp
@@ -748,14 +748,14 @@ Datum Lingo::getTheEntity(int entity, Datum &id, int field) {
break;
case kTheSoundEnabled:
d.type = INT;
- d.u.i = _vm->getSoundManager()->getSoundEnabled();
+ d.u.i = _vm->getCurrentWindow()->getSoundManager()->getSoundEnabled();
break;
case kTheSoundEntity:
{
switch (field) {
case kTheVolume:
{
- SoundChannel *chan = _vm->getSoundManager()->getChannel(id.asInt());
+ SoundChannel *chan = _vm->getCurrentWindow()->getSoundManager()->getChannel(id.asInt());
if (chan) {
d.type = INT;
d.u.i = (int)chan->volume;
@@ -771,7 +771,7 @@ Datum Lingo::getTheEntity(int entity, Datum &id, int field) {
case kTheSoundLevel:
// getting sound level of channel 1, maybe need to be amended in higher version
d.type = INT;
- d.u.i = _vm->getSoundManager()->getSoundLevel(1);
+ d.u.i = _vm->getCurrentWindow()->getSoundManager()->getSoundLevel(1);
break;
case kTheSprite:
d = getTheSprite(id, field);
@@ -1008,14 +1008,14 @@ void Lingo::setTheEntity(int entity, Datum &id, int field, Datum &d) {
}
break;
case kTheSoundEnabled:
- _vm->getSoundManager()->setSoundEnabled((bool)d.asInt());
+ _vm->getCurrentWindow()->getSoundManager()->setSoundEnabled((bool)d.asInt());
break;
case kTheSoundEntity:
{
switch (field) {
case kTheVolume:
{
- SoundChannel *chan = _vm->getSoundManager()->getChannel(id.asInt());
+ SoundChannel *chan = _vm->getCurrentWindow()->getSoundManager()->getChannel(id.asInt());
if (chan) {
chan->volume = (byte)d.asInt();
}
@@ -1029,7 +1029,7 @@ void Lingo::setTheEntity(int entity, Datum &id, int field, Datum &d) {
break;
case kTheSoundLevel:
// setting all of the channel for now
- _vm->getSoundManager()->setSouldLevel(-1, d.asInt());
+ _vm->getCurrentWindow()->getSoundManager()->setSouldLevel(-1, d.asInt());
break;
case kTheSprite:
setTheSprite(id, field, d);
diff --git a/engines/director/lingo/xlibs/fplayxobj.cpp b/engines/director/lingo/xlibs/fplayxobj.cpp
index 1a210e6993..fa2ddc7bc8 100644
--- a/engines/director/lingo/xlibs/fplayxobj.cpp
+++ b/engines/director/lingo/xlibs/fplayxobj.cpp
@@ -29,6 +29,7 @@
#include "director/director.h"
#include "director/sound.h"
+#include "director/window.h"
#include "director/lingo/lingo.h"
#include "director/lingo/xlibs/fplayxobj.h"
@@ -67,7 +68,7 @@ void FPlayXObj::b_fplay(int nargs) {
arr[i] = g_lingo->pop().asString();
}
- DirectorSound *sound = g_director->getSoundManager();
+ DirectorSound *sound = g_director->getCurrentWindow()->getSoundManager();
sound->playFPlaySound(arr);
}
@@ -107,7 +108,7 @@ void FPlayXObj::b_fsound(int nargs) {
g_lingo->dropStack(nargs);
}
- DirectorSound *sound = g_director->getSoundManager();
+ DirectorSound *sound = g_director->getCurrentWindow()->getSoundManager();
if (sound->isChannelActive(1)) {
g_lingo->push(Datum(sound->getCurrentSound()));
} else {
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index 530bfdfbbb..d4e78f3c7a 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -55,7 +55,7 @@ Score::Score(Movie *movie) {
_vm = _movie->getVM();
_lingo = _vm->getLingo();
- _soundManager = _vm->getSoundManager();
+ _soundManager = _window->getSoundManager();
_puppetTempo = 0x00;
_puppetPalette = false;
@@ -707,7 +707,7 @@ void Score::playSoundChannel(uint16 frameId) {
Frame *frame = _frames[frameId];
debugC(5, kDebugLoading, "playSoundChannel(): Sound1 %s Sound2 %s", frame->_sound1.asString().c_str(), frame->_sound2.asString().c_str());
- DirectorSound *sound = _vm->getSoundManager();
+ DirectorSound *sound = _window->getSoundManager();
// puppet sound will be controlled with lingo
if (sound->_puppet)
@@ -738,7 +738,7 @@ void Score::playSoundChannel(uint16 frameId) {
}
void Score::playQueuedSound() {
- DirectorSound *sound = _vm->getSoundManager();
+ DirectorSound *sound = _window->getSoundManager();
sound->playFPlaySound();
}
diff --git a/engines/director/sound.cpp b/engines/director/sound.cpp
index 3af480612c..8b1975429f 100644
--- a/engines/director/sound.cpp
+++ b/engines/director/sound.cpp
@@ -36,10 +36,11 @@
#include "director/movie.h"
#include "director/castmember.h"
#include "director/sound.h"
+#include "director/window.h"
namespace Director {
-DirectorSound::DirectorSound(DirectorEngine *vm) : _vm(vm) {
+DirectorSound::DirectorSound(Window *window) : _window(window) {
uint numChannels = 2;
if (g_director->getVersion() >= 400) {
numChannels = 4;
@@ -110,7 +111,7 @@ void DirectorSound::playCastMember(CastMemberID memberID, uint8 soundChannel, bo
if (memberID.member == 0) {
stopSound(soundChannel);
} else {
- CastMember *soundCast = _vm->getCurrentMovie()->getCastMember(memberID);
+ CastMember *soundCast = _window->getCurrentMovie()->getCastMember(memberID);
if (soundCast) {
if (soundCast->_type != kCastSound) {
warning("DirectorSound::playCastMember: attempted to play a non-SoundCastMember %s", memberID.asString().c_str());
@@ -195,7 +196,7 @@ void DirectorSound::registerFade(uint8 soundChannel, bool fadeIn, int ticks) {
int startVol = fadeIn ? 0 : _channels[soundChannel - 1].volume;
int targetVol = fadeIn ? _channels[soundChannel - 1].volume : 0;
- _channels[soundChannel - 1].fade = new FadeParams(startVol, targetVol, ticks, _vm->getMacTicks(), fadeIn);
+ _channels[soundChannel - 1].fade = new FadeParams(startVol, targetVol, ticks, _window->getVM()->getMacTicks(), fadeIn);
_mixer->setChannelVolume(_channels[soundChannel - 1].handle, startVol);
}
@@ -207,7 +208,7 @@ bool DirectorSound::fadeChannel(uint8 soundChannel) {
if (!fade)
return false;
- fade->lapsedTicks = _vm->getMacTicks() - fade->startTicks;
+ fade->lapsedTicks = _window->getVM()->getMacTicks() - fade->startTicks;
if (fade->lapsedTicks > fade->totalTicks) {
cancelFade(soundChannel);
return false;
diff --git a/engines/director/sound.h b/engines/director/sound.h
index 37d5519d51..d714ddaaa7 100644
--- a/engines/director/sound.h
+++ b/engines/director/sound.h
@@ -68,7 +68,7 @@ public:
bool _puppet;
private:
- DirectorEngine *_vm;
+ Window *_window;
Common::Array<SoundChannel> _channels;
Audio::SoundHandle _scriptSound;
Audio::Mixer *_mixer;
@@ -82,7 +82,7 @@ private:
bool _enable;
public:
- DirectorSound(DirectorEngine *vm);
+ DirectorSound(Window *window);
~DirectorSound();
SoundChannel *getChannel(uint8 soundChannel);
diff --git a/engines/director/window.cpp b/engines/director/window.cpp
index 2c03063478..22181a9ecd 100644
--- a/engines/director/window.cpp
+++ b/engines/director/window.cpp
@@ -36,6 +36,7 @@
#include "director/castmember.h"
#include "director/cursor.h"
#include "director/channel.h"
+#include "director/sound.h"
#include "director/sprite.h"
#include "director/util.h"
#include "director/sound.h"
@@ -48,6 +49,7 @@ Window::Window(int id, bool scrollable, bool resizable, bool editable, Graphics:
_isStage = isStage;
_stageColor = _wm->_colorBlack;
_puppetTransition = nullptr;
+ _soundManager = new DirectorSound(this);
_currentMovie = nullptr;
_mainArchive = nullptr;
@@ -507,7 +509,7 @@ bool Window::step() {
} else {
delete sharedCast;
}
- g_director->getSoundManager()->changingMovie();
+ _soundManager->changingMovie();
_nextMovie.movie.clear();
}
diff --git a/engines/director/window.h b/engines/director/window.h
index 7d8da5a219..1a07f85ffa 100644
--- a/engines/director/window.h
+++ b/engines/director/window.h
@@ -116,6 +116,7 @@ public:
Archive *getMainArchive() const { return _mainArchive; }
Movie *getCurrentMovie() const { return _currentMovie; }
Common::String getCurrentPath() const { return _currentPath; }
+ DirectorSound *getSoundManager() const { return _soundManager; }
virtual void setVisible(bool visible, bool silent = false) override;
bool setNextMovie(Common::String &movieFilenameRaw);
@@ -186,6 +187,7 @@ private:
uint32 _stageColor;
DirectorEngine *_vm;
+ DirectorSound *_soundManager;
bool _isStage;
Archive *_mainArchive;
Common::MacResManager *_macBinary;
Commit: a2e8da00e5f6924ce159b09450058418e1e42fc1
https://github.com/scummvm/scummvm/commit/a2e8da00e5f6924ce159b09450058418e1e42fc1
Author: djsrv (dservilla at gmail.com)
Date: 2021-07-27T22:42:09-04:00
Commit Message:
DIRECTOR: Don't render next frame if exitFrame stopped the movie
Changed paths:
engines/director/score.cpp
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index d4e78f3c7a..57314800ac 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -359,6 +359,12 @@ void Score::update() {
}
}
+ _vm->_skipFrameAdvance = false;
+
+ // the exitFrame event handler may have stopped this movie
+ if (_playState == kPlayStopped)
+ return;
+
if (_nextFrame)
_currentFrame = _nextFrame;
else if (!_window->_newMovieStarted)
@@ -366,8 +372,6 @@ void Score::update() {
_nextFrame = 0;
- _vm->_skipFrameAdvance = false;
-
if (_currentFrame >= _frames.size()) {
Window *window = _vm->getCurrentWindow();
if (!window->_movieStack.empty()) {
Commit: a16d823201282dfd882c1b583e32b35349d00046
https://github.com/scummvm/scummvm/commit/a16d823201282dfd882c1b583e32b35349d00046
Author: djsrv (dservilla at gmail.com)
Date: 2021-07-27T22:54:16-04:00
Commit Message:
DIRECTOR: Improve puppetSound
Most variants of puppetSounds don't actually start the sound immediately
but wait until the frame is updated. So I've created a SoundID struct
which stores a reference to a cast member or externals sound, and that
is used to store the puppetSound until it's actually supposed to start.
In addition, puppet status is now per-channel instead of a universal
flag.
Changed paths:
engines/director/lingo/lingo-builtins.cpp
engines/director/score.cpp
engines/director/score.h
engines/director/sound.cpp
engines/director/sound.h
diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp
index b62b9b89ed..5b7e405fcf 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -1936,32 +1936,36 @@ void LB::b_puppetSound(int nargs) {
return;
}
- sound->_puppet = true;
- if (nargs == 1 || g_director->getVersion() >= 400) {
- Datum castMember = g_lingo->pop();
+ // Most variants of puppetSound don't actually play the sound
+ // until the playback head moves or updateStage is called.
+ // So we'll just queue it to be played later.
- // in D2 manual p206, puppetSound 0 will turn off the puppet status of sound
- if (castMember.asInt() == 0)
- sound->_puppet = false;
-
- uint channel = 1;
- if (nargs == 2)
- channel = g_lingo->pop().asInt();
+ if (nargs == 1) {
+ CastMemberID castMember = g_lingo->pop().asMemberID();
- sound->playCastMember(castMember.asMemberID(), channel);
+ // in D2 manual p206, puppetSound 0 will turn off the puppet status of sound
+ sound->setPuppetSound(castMember, 1);
} else {
- // in D2/3/3.1 interactivity manual, 2 args represent the menu and submenu sounds
- uint submenu = g_lingo->pop().asInt();
- uint menu = g_lingo->pop().asInt();
+ if (g_director->getVersion() < 400) {
+ // in D2/3/3.1 interactivity manual, 2 args represent the menu and submenu sounds
+ int submenu = g_lingo->pop().asInt();
+ int menu = g_lingo->pop().asInt();
- if (menu <= 9 || menu >= 16)
- warning("LB::puppetSound: menu number is not available");
+ if (menu <= 9 || menu >= 16)
+ warning("LB::puppetSound: menu number is not available");
- if (score->_sampleSounds.empty())
- score->loadSampleSounds(menu);
-
- if (submenu <= score->_sampleSounds.size())
- sound->playExternalSound(score->_sampleSounds[submenu - 1], 1, submenu);
+ sound->setPuppetSound(SoundID(kSoundExternal, menu, submenu), 1);
+ } else {
+ // Two-argument puppetSound is undocumented in D4.
+ // It is however documented in the D5 Lingo dictionary.
+ CastMemberID castMember = g_lingo->pop().asMemberID();
+ int channel = g_lingo->pop().asInt();
+ sound->setPuppetSound(castMember, channel);
+
+ // The D4 two-arg variant of puppetSound plays
+ // immediately for some inexplicable reason.
+ sound->playPuppetSound(channel);
+ }
}
}
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index 57314800ac..09658daea5 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -92,9 +92,6 @@ Score::~Score() {
for (Common::SortedArray<Label *>::iterator it = _labels->begin(); it != _labels->end(); ++it)
delete *it;
- for (uint i = 0; i < _sampleSounds.size(); i++)
- delete _sampleSounds[i];
-
delete _labels;
}
@@ -713,32 +710,27 @@ void Score::playSoundChannel(uint16 frameId) {
debugC(5, kDebugLoading, "playSoundChannel(): Sound1 %s Sound2 %s", frame->_sound1.asString().c_str(), frame->_sound2.asString().c_str());
DirectorSound *sound = _window->getSoundManager();
- // puppet sound will be controlled with lingo
- if (sound->_puppet)
- return;
-
- // 0x0f represent sample sound
- if (frame->_soundType1 >= 10 && frame->_soundType1 <= 15) {
- if (_sampleSounds.empty())
- loadSampleSounds(frame->_soundType1);
-
- if ((uint)frame->_sound1.member <= _sampleSounds.size()) {
- sound->playExternalSound(_sampleSounds[frame->_sound1.member - 1], 1, frame->_sound1.member);
- }
+ if (sound->isChannelPuppet(1)) {
+ sound->playPuppetSound(1);
+ } else if (frame->_soundType1 >= 10 && frame->_soundType1 <= 15) { // 0x0f represent sample sound
+ sound->playExternalSound(frame->_soundType1, frame->_sound1.member, 1);
} else {
sound->playCastMember(frame->_sound1, 1, false);
}
- if (frame->_soundType2 >= 10 && frame->_soundType2 <= 15) {
- if (_sampleSounds.empty())
- loadSampleSounds(frame->_soundType2);
-
- if ((uint)frame->_sound2.member <= _sampleSounds.size()) {
- sound->playExternalSound(_sampleSounds[frame->_sound2.member - 1], 2, frame->_sound2.member);
- }
+ if (sound->isChannelPuppet(2)) {
+ sound->playPuppetSound(2);
+ } else if (frame->_soundType2 >= 10 && frame->_soundType2 <= 15) {
+ sound->playExternalSound(frame->_soundType2, frame->_sound2.member, 2);
} else {
sound->playCastMember(frame->_sound2, 2, false);
}
+
+ // Channels above 2 are only usable by Lingo.
+ if (g_director->getVersion() >= 400) {
+ sound->playPuppetSound(3);
+ sound->playPuppetSound(4);
+ }
}
void Score::playQueuedSound() {
@@ -746,53 +738,6 @@ void Score::playQueuedSound() {
sound->playFPlaySound();
}
-void Score::loadSampleSounds(uint type) {
- // trying to load external sample sounds
- // lazy loading
- uint32 tag = MKTAG('C', 'S', 'N', 'D');
- uint id = 0xFF;
- Archive *archive = nullptr;
-
- for (Common::HashMap<Common::String, Archive *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo>::iterator it = g_director->_openResFiles.begin(); it != g_director->_openResFiles.end(); ++it) {
- Common::Array<uint16> idList = it->_value->getResourceIDList(tag);
- for (uint j = 0; j < idList.size(); j++) {
- if ((idList[j] & 0xFF) == type) {
- id = idList[j];
- archive = it->_value;
- break;
- }
- }
- }
-
- if (id == 0xFF) {
- warning("Score::loadSampleSounds: can not find CSND resource with id %d", type);
- return;
- }
-
- Common::SeekableReadStreamEndian *csndData = archive->getResource(tag, id);
-
- /*uint32 flag = */ csndData->readUint32();
-
- // the flag should be 0x604E
- // i'm not sure what's that mean, but it occurs in those csnd files
-
- // contains how many csnd data
- uint16 num = csndData->readUint16();
-
- // read the offset first;
- Common::Array<uint32> offset(num);
- for (uint i = 0; i < num; i++)
- offset[i] = csndData->readUint32();
-
- for (uint i = 0; i < num; i++) {
- csndData->seek(offset[i]);
-
- SNDDecoder *ad = new SNDDecoder();
- ad->loadExternalSoundStream(*csndData);
- _sampleSounds.push_back(ad);
- }
-}
-
void Score::loadFrames(Common::SeekableReadStreamEndian &stream, uint16 version) {
debugC(1, kDebugLoading, "****** Loading frames VWSC");
diff --git a/engines/director/score.h b/engines/director/score.h
index a1d707a991..fc102d6cab 100644
--- a/engines/director/score.h
+++ b/engines/director/score.h
@@ -129,7 +129,6 @@ public:
Common::SortedArray<Label *> *_labels;
Common::HashMap<uint16, Common::String> _actions;
Common::HashMap<uint16, bool> _immediateActions;
- Common::Array<AudioDecoder *> _sampleSounds;
byte _currentFrameRate;
diff --git a/engines/director/sound.cpp b/engines/director/sound.cpp
index 8b1975429f..643ae36fbf 100644
--- a/engines/director/sound.cpp
+++ b/engines/director/sound.cpp
@@ -57,11 +57,11 @@ DirectorSound::DirectorSound(Window *window) : _window(window) {
&_pcSpeakerHandle, _speaker, -1, 50, 0, DisposeAfterUse::NO, true);
_enable = true;
- _puppet = false;
}
DirectorSound::~DirectorSound() {
this->stopSound();
+ unloadSampleSounds();
delete _speaker;
}
@@ -104,6 +104,17 @@ void DirectorSound::playStream(Audio::AudioStream &stream, uint8 soundChannel) {
_mixer->playStream(Audio::Mixer::kSFXSoundType, &_channels[soundChannel - 1].handle, &stream, -1, getChannelVolume(soundChannel));
}
+void DirectorSound::playSound(SoundID soundID, uint8 soundChannel) {
+ switch (soundID.type) {
+ case kSoundCast:
+ playCastMember(CastMemberID(soundID.u.cast.member, soundID.u.cast.castLib), soundChannel);
+ break;
+ case kSoundExternal:
+ playExternalSound(soundID.u.external.menu, soundID.u.external.submenu, soundChannel);
+ break;
+ }
+}
+
void DirectorSound::playCastMember(CastMemberID memberID, uint8 soundChannel, bool allowRepeat) {
if (!isChannelValid(soundChannel))
return;
@@ -116,7 +127,7 @@ void DirectorSound::playCastMember(CastMemberID memberID, uint8 soundChannel, bo
if (soundCast->_type != kCastSound) {
warning("DirectorSound::playCastMember: attempted to play a non-SoundCastMember %s", memberID.asString().c_str());
} else {
- if (!allowRepeat && checkLastPlayCast(soundChannel, memberID))
+ if (!allowRepeat && checkLastPlaySound(soundChannel, memberID))
return;
bool looping = ((SoundCastMember *)soundCast)->_looping;
AudioDecoder *ad = ((SoundCastMember *)soundCast)->_audio;
@@ -133,7 +144,7 @@ void DirectorSound::playCastMember(CastMemberID memberID, uint8 soundChannel, bo
return;
}
playStream(*as, soundChannel);
- setLastPlayCast(soundChannel, memberID);
+ setLastPlaySound(soundChannel, memberID);
}
} else {
warning("DirectorSound::playCastMember: couldn't find %s", memberID.asString().c_str());
@@ -251,31 +262,99 @@ bool DirectorSound::isChannelValid(uint8 soundChannel) {
return true;
}
-void DirectorSound::playExternalSound(AudioDecoder *ad, uint8 soundChannel, uint8 externalSoundID) {
+void DirectorSound::loadSampleSounds(uint type) {
+ if (_sampleSounds.contains(type))
+ return;
+
+ _sampleSounds[type] = Common::Array<AudioDecoder *>();
+
+ // trying to load external sample sounds
+ // lazy loading
+ uint32 tag = MKTAG('C', 'S', 'N', 'D');
+ uint id = 0xFF;
+ Archive *archive = nullptr;
+
+ for (Common::HashMap<Common::String, Archive *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo>::iterator it = g_director->_openResFiles.begin(); it != g_director->_openResFiles.end(); ++it) {
+ Common::Array<uint16> idList = it->_value->getResourceIDList(tag);
+ for (uint j = 0; j < idList.size(); j++) {
+ if ((idList[j] & 0xFF) == type) {
+ id = idList[j];
+ archive = it->_value;
+ break;
+ }
+ }
+ }
+
+ if (id == 0xFF) {
+ warning("Score::loadSampleSounds: can not find CSND resource with id %d", type);
+ return;
+ }
+
+ Common::SeekableReadStreamEndian *csndData = archive->getResource(tag, id);
+
+ /*uint32 flag = */ csndData->readUint32();
+
+ // the flag should be 0x604E
+ // i'm not sure what's that mean, but it occurs in those csnd files
+
+ // contains how many csnd data
+ uint16 num = csndData->readUint16();
+
+ // read the offset first;
+ Common::Array<uint32> offset(num);
+ for (uint i = 0; i < num; i++)
+ offset[i] = csndData->readUint32();
+
+ for (uint i = 0; i < num; i++) {
+ csndData->seek(offset[i]);
+
+ SNDDecoder *ad = new SNDDecoder();
+ ad->loadExternalSoundStream(*csndData);
+ _sampleSounds[type].push_back(ad);
+ }
+}
+
+void DirectorSound::unloadSampleSounds() {
+ for (Common::HashMap<uint, Common::Array<AudioDecoder *>>::iterator it = _sampleSounds.begin(); it != _sampleSounds.end(); ++it)
+ for (uint i = 0; i < it->_value.size(); i++)
+ delete it->_value[i];
+
+ _sampleSounds.clear();
+}
+
+void DirectorSound::playExternalSound(uint16 menu, uint16 submenu, uint8 soundChannel) {
if (!isChannelValid(soundChannel))
return;
- // use castMemberID info to check, castLib -1 represent for externalSound
- // this should be amended by some kind of union which contains CastMemberID and externalSound info
- if (isChannelActive(soundChannel) && checkLastPlayCast(soundChannel, CastMemberID(externalSoundID, -1)))
+ SoundID soundId(kSoundExternal, menu, submenu);
+ if (isChannelActive(soundChannel) && checkLastPlaySound(soundChannel, soundId))
return;
- playStream(*(ad->getAudioStream()), soundChannel);
- setLastPlayCast(soundChannel, CastMemberID(externalSoundID, -1));
+ if (!_sampleSounds.contains(menu))
+ loadSampleSounds(menu);
+
+ if ((uint)submenu<= _sampleSounds[menu].size()) {
+ playStream(*(_sampleSounds[menu][submenu - 1]->getAudioStream()), soundChannel);
+ setLastPlaySound(soundChannel, soundId);
+ } else {
+ warning("DirectorSound::playExternalSound: Could not find sound %d %d", menu, submenu);
+ }
}
void DirectorSound::changingMovie() {
- for (uint i = 0; i < _channels.size(); i++)
+ for (uint i = 0; i < _channels.size(); i++) {
_channels[i]._movieChanged = true;
+ }
+ unloadSampleSounds(); // TODO: we can possibly keep this between movies
}
-void DirectorSound::setLastPlayCast(uint8 soundChannel, CastMemberID castMemberId) {
- _channels[soundChannel - 1].lastPlayingCast = castMemberId;
+void DirectorSound::setLastPlaySound(uint8 soundChannel, SoundID soundId) {
+ _channels[soundChannel - 1].lastPlayingSound = soundId;
_channels[soundChannel - 1]._movieChanged = false;
}
-bool DirectorSound::checkLastPlayCast(uint8 soundChannel, const CastMemberID &castMemberId) {
- return !_channels[soundChannel - 1]._movieChanged && _channels[soundChannel - 1].lastPlayingCast == castMemberId;
+bool DirectorSound::checkLastPlaySound(uint8 soundChannel, const SoundID &soundId) {
+ return !_channels[soundChannel - 1]._movieChanged && _channels[soundChannel - 1].lastPlayingSound == soundId;
}
void DirectorSound::stopSound(uint8 soundChannel) {
@@ -284,7 +363,7 @@ void DirectorSound::stopSound(uint8 soundChannel) {
cancelFade(soundChannel);
_mixer->stopHandle(_channels[soundChannel - 1].handle);
- setLastPlayCast(soundChannel, CastMemberID(0, 0));
+ setLastPlaySound(soundChannel, SoundID());
return;
}
@@ -293,7 +372,7 @@ void DirectorSound::stopSound() {
cancelFade(i + 1);
_mixer->stopHandle(_channels[i].handle);
- setLastPlayCast(i + 1, CastMemberID(0, 0));
+ setLastPlaySound(i + 1, SoundID());
}
_mixer->stopHandle(_scriptSound);
@@ -304,6 +383,37 @@ void DirectorSound::systemBeep() {
_speaker->play(Audio::PCSpeaker::kWaveFormSquare, 500, 150);
}
+bool DirectorSound::isChannelPuppet(uint8 soundChannel) {
+ if (!isChannelValid(soundChannel))
+ return false;
+
+ // cast member ID 0 means "not a puppet"
+ if (_channels[soundChannel - 1].puppet.type == kSoundCast && _channels[soundChannel - 1].puppet.u.cast.member == 0)
+ return false;
+
+ return true;
+}
+
+void DirectorSound::setPuppetSound(SoundID soundId, uint8 soundChannel) {
+ if (!isChannelValid(soundChannel))
+ return;
+
+ _channels[soundChannel - 1].newPuppet = true;
+ _channels[soundChannel - 1].puppet = soundId;
+}
+
+void DirectorSound::playPuppetSound(uint8 soundChannel) {
+ if (!isChannelValid(soundChannel))
+ return;
+
+ // only play if the puppet was just set
+ if (!_channels[soundChannel - 1].newPuppet)
+ return;
+
+ _channels[soundChannel - 1].newPuppet = false;
+ playSound(_channels[soundChannel - 1].puppet, soundChannel);
+}
+
void DirectorSound::playFPlaySound() {
if (_fplayQueue.empty())
return;
diff --git a/engines/director/sound.h b/engines/director/sound.h
index d714ddaaa7..0aec657309 100644
--- a/engines/director/sound.h
+++ b/engines/director/sound.h
@@ -48,25 +48,100 @@ struct FadeParams {
startVol(sv), targetVol(tv), totalTicks(tt), startTicks(st), lapsedTicks(0), fadeIn(f) {}
};
+struct ExternalSoundID {
+ uint16 menu;
+ uint16 submenu;
+
+ ExternalSoundID() : menu(0), submenu(0) {}
+ ExternalSoundID(uint16 menuID, uint16 submenuID)
+ : menu(menuID), submenu(submenuID) {}
+
+ bool operator==(const ExternalSoundID &b) {
+ return menu == b.menu && submenu == b.submenu;
+ }
+ bool operator!=(const ExternalSoundID &b) {
+ return !(*this == b);
+ }
+};
+
+enum SoundIDType {
+ kSoundCast,
+ kSoundExternal
+};
+
+struct SoundID {
+ SoundIDType type;
+ union {
+ struct {
+ int member;
+ int castLib;
+ } cast;
+ struct {
+ uint16 menu;
+ uint16 submenu;
+ } external;
+ } u;
+
+ SoundID() {
+ type = kSoundCast;
+ u.cast.member = 0;
+ u.cast.castLib = 0;
+ }
+ SoundID(SoundIDType type_, int a, int b) {
+ type = type_;
+ switch (type) {
+ case kSoundCast:
+ u.cast.member = a;
+ u.cast.castLib = b;
+ break;
+ case kSoundExternal:
+ u.external.menu = a;
+ u.external.submenu = b;
+ }
+ }
+ SoundID(CastMemberID memberID) {
+ type = kSoundCast;
+ u.cast.member = memberID.member;
+ u.cast.castLib = memberID.castLib;
+ }
+
+ bool operator==(const SoundID &b) {
+ if (type != b.type)
+ return false;
+
+ switch (type) {
+ case kSoundCast:
+ return u.cast.member == b.u.cast.member && u.cast.castLib == b.u.cast.castLib;
+ case kSoundExternal:
+ return u.external.menu == b.u.external.menu && u.external.submenu == b.u.external.submenu;
+ }
+
+ return false;
+ }
+ bool operator!=(const SoundID &b) {
+ return !(*this == b);
+ }
+};
+
struct SoundChannel {
Audio::SoundHandle handle;
- CastMemberID lastPlayingCast;
+ SoundID lastPlayingSound;
byte volume;
FadeParams *fade;
+ // a non-zero sound ID if the channel is a puppet. i.e. it's controlled by lingo
+ SoundID puppet;
+ bool newPuppet;
+
// this indicate whether the sound is playing across the movie. Because the cast name may be the same while the actual sounds are changing.
// And we will override the sound when ever the sound is changing. thus we use a flag to indicate whether the movie is changed.
bool _movieChanged;
- SoundChannel(): handle(), volume(255), fade(nullptr), _movieChanged(false) {}
+ SoundChannel(): handle(), lastPlayingSound(SoundID()), volume(255), fade(nullptr), puppet(SoundID()), newPuppet(false), _movieChanged(false) {}
};
class DirectorSound {
-public:
- // whether the sound is puppet. i.e. it's controlled by lingo
- bool _puppet;
-
private:
Window *_window;
Common::Array<SoundChannel> _channels;
@@ -81,6 +156,8 @@ private:
bool _enable;
+ Common::HashMap<uint, Common::Array<AudioDecoder *>> _sampleSounds;
+
public:
DirectorSound(Window *window);
~DirectorSound();
@@ -89,8 +166,9 @@ public:
void playFile(Common::String filename, uint8 soundChannel);
void playMCI(Audio::AudioStream &stream, uint32 from, uint32 to);
void playStream(Audio::AudioStream &stream, uint8 soundChannel);
+ void playSound(SoundID soundId, uint8 soundChannel);
void playCastMember(CastMemberID memberID, uint8 soundChannel, bool allowRepeat = true);
- void playExternalSound(AudioDecoder *ad, uint8 soundChannel, uint8 externalSoundID);
+ void playExternalSound(uint16 menu, uint16 submenu, uint8 soundChannel);
void playFPlaySound(const Common::Array<Common::String> &fplayList);
void playFPlaySound();
void setSouldLevel(int channel, uint8 soundLevel);
@@ -99,8 +177,15 @@ public:
void systemBeep();
void changingMovie();
- void setLastPlayCast(uint8 soundChannel, CastMemberID castMemberId);
- bool checkLastPlayCast(uint8 soundChannel, const CastMemberID &castMemberId);
+ void loadSampleSounds(uint type);
+ void unloadSampleSounds();
+
+ void setLastPlaySound(uint8 soundChannel, SoundID soundId);
+ bool checkLastPlaySound(uint8 soundChannel, const SoundID &soundId);
+
+ bool isChannelPuppet(uint8 soundChannel);
+ void setPuppetSound(SoundID soundId, uint8 soundChannel);
+ void playPuppetSound(uint8 soundChannel);
bool getSoundEnabled() { return _enable; }
Commit: ff16d808c7cbb1aad84aae1999c60747ee66ae4b
https://github.com/scummvm/scummvm/commit/ff16d808c7cbb1aad84aae1999c60747ee66ae4b
Author: djsrv (dservilla at gmail.com)
Date: 2021-07-27T22:54:25-04:00
Commit Message:
DIRECTOR: LINGO: Play puppet sounds in updateStage
Changed paths:
engines/director/lingo/lingo-builtins.cpp
engines/director/score.h
diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp
index 5b7e405fcf..c9fc1d0d34 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -2232,6 +2232,9 @@ void LB::b_updateStage(int nargs) {
if (movie->getWindow()->render())
g_director->draw();
+ // play any puppet sounds that have been queued
+ score->playSoundChannel(score->getCurrentFrame());
+
if (debugChannelSet(-1, kDebugFewFramesOnly)) {
score->_framesRan++;
diff --git a/engines/director/score.h b/engines/director/score.h
index fc102d6cab..d34d3d03b5 100644
--- a/engines/director/score.h
+++ b/engines/director/score.h
@@ -113,10 +113,10 @@ public:
void renderCursor(Common::Point pos);
void renderVideo();
+ void playSoundChannel(uint16 frameId);
+
private:
void update();
-
- void playSoundChannel(uint16 frameId);
void playQueuedSound();
void screenShot();
Commit: 00a1ba2ee875fb0421ab383a0148e9fdfa95d384
https://github.com/scummvm/scummvm/commit/00a1ba2ee875fb0421ab383a0148e9fdfa95d384
Author: djsrv (dservilla at gmail.com)
Date: 2021-07-27T22:54:25-04:00
Commit Message:
DIRECTOR: Disable puppet sounds when the movie changes
Changed paths:
engines/director/sound.cpp
diff --git a/engines/director/sound.cpp b/engines/director/sound.cpp
index 643ae36fbf..c14bb633cb 100644
--- a/engines/director/sound.cpp
+++ b/engines/director/sound.cpp
@@ -343,6 +343,7 @@ void DirectorSound::playExternalSound(uint16 menu, uint16 submenu, uint8 soundCh
void DirectorSound::changingMovie() {
for (uint i = 0; i < _channels.size(); i++) {
+ setPuppetSound(SoundID(), i + 1); // disable puppet sound
_channels[i]._movieChanged = true;
}
unloadSampleSounds(); // TODO: we can possibly keep this between movies
More information about the Scummvm-git-logs
mailing list