aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
Diffstat (limited to 'engines')
-rw-r--r--engines/sci/console.cpp8
-rw-r--r--engines/sci/engine/kernel_tables.h4
-rw-r--r--engines/sci/engine/savegame.cpp18
-rw-r--r--engines/sci/engine/savegame.h4
-rw-r--r--engines/sci/resource.h2
-rw-r--r--engines/sci/resource_audio.cpp4
-rw-r--r--engines/sci/sound/midiparser_sci.cpp17
-rw-r--r--engines/sci/sound/music.cpp100
-rw-r--r--engines/sci/sound/music.h14
-rw-r--r--engines/sci/sound/soundcmd.cpp44
-rw-r--r--engines/sci/sound/soundcmd.h2
11 files changed, 157 insertions, 60 deletions
diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp
index e233c4cba4..a3abf606d0 100644
--- a/engines/sci/console.cpp
+++ b/engines/sci/console.cpp
@@ -2172,6 +2172,7 @@ bool Console::cmdStartSound(int argc, const char **argv) {
return true;
}
+ // TODO: Maybe also add a playBed option.
g_sci->_soundCmd->startNewSound(number);
return cmdExit(0, 0);
}
@@ -2198,9 +2199,10 @@ bool Console::cmdToggleSound(int argc, const char **argv) {
Common::String newState = argv[2];
newState.toLowercase();
- if (newState == "play")
- g_sci->_soundCmd->processPlaySound(id);
- else if (newState == "stop")
+ if (newState == "play") {
+ // Maybe also have a 'playbed' option. (Second argument to processPlaySound.)
+ g_sci->_soundCmd->processPlaySound(id, false);
+ } else if (newState == "stop")
g_sci->_soundCmd->processStopSound(id, false);
else
debugPrintf("New state can either be 'play' or 'stop'");
diff --git a/engines/sci/engine/kernel_tables.h b/engines/sci/engine/kernel_tables.h
index 0c2fd4e3ea..2cbd79366d 100644
--- a/engines/sci/engine/kernel_tables.h
+++ b/engines/sci/engine/kernel_tables.h
@@ -105,10 +105,6 @@ static const SciKernelMapSubEntry kDoSound_subops[] = {
{ SIG_SOUNDSCI1EARLY, 5, MAP_CALL(DoSoundInit), NULL, NULL },
{ SIG_SOUNDSCI1EARLY, 6, MAP_CALL(DoSoundDispose), NULL, NULL },
{ SIG_SOUNDSCI1EARLY, 7, MAP_CALL(DoSoundPlay), "oi", NULL },
- // ^^ TODO: In SCI1-SCI1.1 DoSound (play) is called by 2 methods of the Sound object: play and
- // playBed. The methods are the same, apart from the second integer parameter: it's 0 in
- // play and 1 in playBed, to distinguish the caller. It's passed on, we should find out what
- // it actually does internally
{ SIG_SOUNDSCI1EARLY, 8, MAP_CALL(DoSoundStop), NULL, NULL },
{ SIG_SOUNDSCI1EARLY, 9, MAP_CALL(DoSoundPause), "[o0]i", NULL },
{ SIG_SOUNDSCI1EARLY, 10, MAP_CALL(DoSoundFade), "oiiii", kDoSoundFade_workarounds },
diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp
index 0b55425406..61f8058e45 100644
--- a/engines/sci/engine/savegame.cpp
+++ b/engines/sci/engine/savegame.cpp
@@ -617,6 +617,14 @@ void MusicEntry::saveLoadWithSerializer(Common::Serializer &s) {
s.syncAsSint32LE(fadeTicker);
s.syncAsSint32LE(fadeTickerStep);
s.syncAsByte(status);
+ if (s.getVersion() >= 32)
+ s.syncAsByte(playBed);
+ else if (s.isLoading())
+ playBed = false;
+ if (s.getVersion() >= 33)
+ s.syncAsByte(overridePriority);
+ else if (s.isLoading())
+ overridePriority = false;
// pMidiParser and pStreamAud will be initialized when the
// sound list is reconstructed in gamestate_restore()
@@ -635,8 +643,12 @@ void SoundCommandParser::syncPlayList(Common::Serializer &s) {
void SoundCommandParser::reconstructPlayList() {
Common::StackLock lock(_music->_mutex);
- const MusicList::iterator end = _music->getPlayListEnd();
- for (MusicList::iterator i = _music->getPlayListStart(); i != end; ++i) {
+ // We store all songs here because starting songs may re-shuffle their order
+ MusicList songs;
+ for (MusicList::iterator i = _music->getPlayListStart(); i != _music->getPlayListEnd(); ++i)
+ songs.push_back(*i);
+
+ for (MusicList::iterator i = songs.begin(); i != songs.end(); ++i) {
initSoundResource(*i);
if ((*i)->status == kSoundPlaying) {
@@ -650,7 +662,7 @@ void SoundCommandParser::reconstructPlayList() {
if (_soundVersion >= SCI_VERSION_1_EARLY)
writeSelectorValue(_segMan, (*i)->soundObj, SELECTOR(vol), (*i)->volume);
- processPlaySound((*i)->soundObj);
+ processPlaySound((*i)->soundObj, (*i)->playBed);
}
}
}
diff --git a/engines/sci/engine/savegame.h b/engines/sci/engine/savegame.h
index 8f2835654b..7f482ed0a1 100644
--- a/engines/sci/engine/savegame.h
+++ b/engines/sci/engine/savegame.h
@@ -37,6 +37,8 @@ struct EngineState;
*
* Version - new/changed feature
* =============================
+ * 33 - new overridePriority flag in MusicEntry
+ * 32 - new playBed flag in MusicEntry
* 31 - priority for sound effects/music is now a signed int16, instead of a byte
* 30 - synonyms
* 29 - system strings
@@ -56,7 +58,7 @@ struct EngineState;
*/
enum {
- CURRENT_SAVEGAME_VERSION = 31,
+ CURRENT_SAVEGAME_VERSION = 33,
MINIMUM_SAVEGAME_VERSION = 14
};
diff --git a/engines/sci/resource.h b/engines/sci/resource.h
index 62f3c584ac..ef48998b04 100644
--- a/engines/sci/resource.h
+++ b/engines/sci/resource.h
@@ -596,6 +596,7 @@ public:
Track *getDigitalTrack();
int getChannelFilterMask(int hardwareMask, bool wantsRhythm);
byte getInitialVoiceCount(byte channel);
+ byte getSoundPriority() const { return _soundPriority; }
private:
SciVersion _soundVersion;
@@ -603,6 +604,7 @@ private:
Track *_tracks;
Resource *_innerResource;
ResourceManager *_resMan;
+ byte _soundPriority;
};
} // End of namespace Sci
diff --git a/engines/sci/resource_audio.cpp b/engines/sci/resource_audio.cpp
index c775f502c5..3a43774492 100644
--- a/engines/sci/resource_audio.cpp
+++ b/engines/sci/resource_audio.cpp
@@ -579,6 +579,7 @@ SoundResource::SoundResource(uint32 resourceNr, ResourceManager *resMan, SciVers
return;
_innerResource = resource;
+ _soundPriority = 0xFF;
byte *data, *data2;
byte *dataEnd;
@@ -725,6 +726,9 @@ SoundResource::SoundResource(uint32 resourceNr, ResourceManager *resMan, SciVers
data += 6;
}
} else {
+ // The first byte of the 0xF0 track's channel list is priority
+ _soundPriority = *data;
+
// Skip over digital track
data += 6;
}
diff --git a/engines/sci/sound/midiparser_sci.cpp b/engines/sci/sound/midiparser_sci.cpp
index c0b4f3122e..25facacced 100644
--- a/engines/sci/sound/midiparser_sci.cpp
+++ b/engines/sci/sound/midiparser_sci.cpp
@@ -360,6 +360,13 @@ void MidiParser_SCI::sendInitCommands() {
sendToDriver(0xB0 | i, 0x4B, voiceCount);
}
}
+ } else {
+ for (int i = 0; i < _track->channelCount; ++i) {
+ byte voiceCount = _track->channels[i].poly;
+ byte num = _track->channels[i].number;
+ // TODO: Should we skip the control channel?
+ sendToDriver(0xB0 | num, 0x4B, voiceCount);
+ }
}
}
@@ -480,6 +487,11 @@ void MidiParser_SCI::trackState(uint32 b) {
s._sustain = (op2 != 0);
break;
case 0x4B: // voices
+ if (s._voices != op2) {
+ // CHECKME: Should we directly call remapChannels() if _mainThreadCalled?
+ debugC(2, kDebugLevelSound, "Dynamic voice change (%d to %d)", s._voices, op2);
+ _music->needsRemap();
+ }
s._voices = op2;
_pSnd->_chan[channel]._voices = op2; // Also sync our MusicEntry
break;
@@ -491,8 +503,9 @@ void MidiParser_SCI::trackState(uint32 b) {
bool m = op2;
if (_pSnd->_chan[channel]._mute != m) {
_pSnd->_chan[channel]._mute = m;
- // TODO: If muting/unmuting a channel, remap channels.
- warning("Mute change without immediate remapping (mainThread = %d)", _mainThreadCalled);
+ // CHECKME: Should we directly call remapChannels() if _mainThreadCalled?
+ _music->needsRemap();
+ debugC(2, kDebugLevelSound, "Dynamic mute change (mainThread = %d)", _mainThreadCalled);
}
}
break;
diff --git a/engines/sci/sound/music.cpp b/engines/sci/sound/music.cpp
index 7a6eaf62b4..7156e3c099 100644
--- a/engines/sci/sound/music.cpp
+++ b/engines/sci/sound/music.cpp
@@ -144,6 +144,8 @@ void SciMusic::init() {
_globalReverb = _pMidiDrv->getReverb(); // Init global reverb for SCI0
_currentlyPlayingSample = NULL;
+ _timeCounter = 0;
+ _needsRemap = false;
}
void SciMusic::miditimerCallback(void *p) {
@@ -158,6 +160,11 @@ void SciMusic::onTimer() {
// sending out queued commands that were "sent" via main thread
sendMidiCommandsFromQueue();
+ // remap channels, if requested
+ if (_needsRemap)
+ remapChannels(false);
+ _needsRemap = false;
+
for (MusicList::iterator i = _playList.begin(); i != end; ++i)
(*i)->onTimer();
}
@@ -285,8 +292,10 @@ byte SciMusic::getCurrentReverb() {
return _pMidiDrv->getReverb();
}
+// A larger priority value has higher priority. For equal priority values,
+// songs that have been added later have higher priority.
static bool musicEntryCompare(const MusicEntry *l, const MusicEntry *r) {
- return (l->priority > r->priority);
+ return (l->priority > r->priority) || (l->priority == r->priority && l->time > r->time);
}
void SciMusic::sortPlayList() {
@@ -317,6 +326,8 @@ void SciMusic::soundInitSnd(MusicEntry *pSnd) {
track = digital;
}
+ pSnd->time = ++_timeCounter;
+
if (track) {
// Play digital sample
if (track->digitalChannelNr != -1) {
@@ -334,6 +345,8 @@ void SciMusic::soundInitSnd(MusicEntry *pSnd) {
pSnd->pLoopStream = 0;
pSnd->soundType = Audio::Mixer::kSFXSoundType;
pSnd->hCurrentAud = Audio::SoundHandle();
+ pSnd->playBed = false;
+ pSnd->overridePriority = false;
} else {
// play MIDI track
Common::StackLock lock(_mutex);
@@ -380,6 +393,8 @@ void SciMusic::soundInitSnd(MusicEntry *pSnd) {
int16 prevHold = pSnd->hold;
pSnd->loop = 0;
pSnd->hold = -1;
+ pSnd->playBed = false;
+ pSnd->overridePriority = false;
pSnd->pMidiParser->loadMusic(track, pSnd, channelFilterMask, _soundVersion);
pSnd->reverb = pSnd->pMidiParser->getSongReverb();
@@ -395,6 +410,23 @@ void SciMusic::soundInitSnd(MusicEntry *pSnd) {
void SciMusic::soundPlay(MusicEntry *pSnd) {
_mutex.lock();
+ if (_soundVersion <= SCI_VERSION_1_EARLY && pSnd->playBed) {
+ // If pSnd->playBed, and version <= SCI1_EARLY, then kill
+ // existing sounds with playBed enabled.
+
+ uint playListCount = _playList.size();
+ for (uint i = 0; i < playListCount; i++) {
+ if (_playList[i] != pSnd && _playList[i]->playBed) {
+ debugC(2, kDebugLevelSound, "Automatically stopping old playBed song from soundPlay");
+ MusicEntry *old = _playList[i];
+ _mutex.unlock();
+ soundStop(old);
+ _mutex.lock();
+ break;
+ }
+ }
+ }
+
uint playListCount = _playList.size();
uint playListNo = playListCount;
MusicEntry *alreadyPlaying = NULL;
@@ -408,9 +440,11 @@ void SciMusic::soundPlay(MusicEntry *pSnd) {
}
if (playListNo == playListCount) { // not found
_playList.push_back(pSnd);
- sortPlayList();
}
+ pSnd->time = ++_timeCounter;
+ sortPlayList();
+
_mutex.unlock(); // unlock to perform mixer-related calls
if (pSnd->pMidiParser) {
@@ -554,6 +588,7 @@ void SciMusic::soundSetPriority(MusicEntry *pSnd, byte prio) {
Common::StackLock lock(_mutex);
pSnd->priority = prio;
+ pSnd->time = ++_timeCounter;
sortPlayList();
}
@@ -905,12 +940,12 @@ int ChannelRemapping::lowestPrio() const {
}
-void SciMusic::remapChannels() {
+void SciMusic::remapChannels(bool mainThread) {
if (_soundVersion <= SCI_VERSION_0_LATE)
return;
- // NB: This function should only be called from the main thread,
- // with _mutex locked
+ // NB: This function should only be called with _mutex locked
+ // Make sure to set the mainThread argument correctly.
ChannelRemapping *map = determineChannelMap();
@@ -963,9 +998,9 @@ void SciMusic::remapChannels() {
for (int j = 0; j < 16; ++j) {
if (!channelMapped[j]) {
- song->pMidiParser->mainThreadBegin();
+ if (mainThread) song->pMidiParser->mainThreadBegin();
song->pMidiParser->remapChannel(j, -1);
- song->pMidiParser->mainThreadEnd();
+ if (mainThread) song->pMidiParser->mainThreadEnd();
#ifdef DEBUG_REMAP
if (channelUsed[j])
debug(" Unmapping song %d, channel %d", songIndex, j);
@@ -997,9 +1032,9 @@ void SciMusic::remapChannels() {
#ifdef DEBUG_REMAP
debug(" Mapping (dontRemap) song %d, channel %d to device channel %d", songIndex, _channelMap[i]._channel, i);
#endif
- _channelMap[i]._song->pMidiParser->mainThreadBegin();
+ if (mainThread) _channelMap[i]._song->pMidiParser->mainThreadBegin();
_channelMap[i]._song->pMidiParser->remapChannel(_channelMap[i]._channel, i);
- _channelMap[i]._song->pMidiParser->mainThreadEnd();
+ if (mainThread) _channelMap[i]._song->pMidiParser->mainThreadEnd();
}
}
@@ -1052,9 +1087,9 @@ void SciMusic::remapChannels() {
#ifdef DEBUG_REMAP
debug(" Mapping song %d, channel %d to device channel %d", songIndex, _channelMap[j]._channel, j);
#endif
- _channelMap[j]._song->pMidiParser->mainThreadBegin();
+ if (mainThread) _channelMap[j]._song->pMidiParser->mainThreadBegin();
_channelMap[j]._song->pMidiParser->remapChannel(_channelMap[j]._channel, j);
- _channelMap[j]._song->pMidiParser->mainThreadEnd();
+ if (mainThread) _channelMap[j]._song->pMidiParser->mainThreadEnd();
break;
}
}
@@ -1062,9 +1097,9 @@ void SciMusic::remapChannels() {
}
// And finally, stop any empty channels
- for (int i = _driverFirstChannel; i <= _driverLastChannel; ++i) {
- if (!_channelMap[i]._song)
- resetDeviceChannel(i);
+ for (int i = _driverLastChannel; i >= _driverFirstChannel; --i) {
+ if (!_channelMap[i]._song && currentMap[i]._song)
+ resetDeviceChannel(i, mainThread);
}
delete map;
@@ -1105,7 +1140,8 @@ ChannelRemapping *SciMusic::determineChannelMap() {
#ifdef DEBUG_REMAP
- debug(" Song %d (%p), prio %d", songIndex, (void*)song, song->priority);
+ const char* name = g_sci->getEngineState()->_segMan->getObjectName(song->soundObj);
+ debug(" Song %d (%p) [%s], prio %d%s", songIndex, (void*)song, name, song->priority, song->playBed ? ", bed" : "");
#endif
// Store backup. If we fail to map this song, we will revert to this.
@@ -1123,8 +1159,10 @@ ChannelRemapping *SciMusic::determineChannelMap() {
if (channel._mute)
continue;
+ bool dontRemap = channel._dontRemap || song->playBed;
+
#ifdef DEBUG_REMAP
- debug(" Channel %d: prio %d, %d voice%s%s", c, channel._prio, channel._voices, channel._voices == 1 ? "" : "s", channel._dontRemap ? ", dontRemap" : "" );
+ debug(" Channel %d: prio %d, %d voice%s%s", c, channel._prio, channel._voices, channel._voices == 1 ? "" : "s", dontRemap ? ", dontRemap" : "" );
#endif
DeviceChannelUsage dc = { song, c };
@@ -1132,7 +1170,7 @@ ChannelRemapping *SciMusic::determineChannelMap() {
// our target
int devChannel = -1;
- if (channel._dontRemap && map->_map[c]._song == 0) {
+ if (dontRemap && map->_map[c]._song == 0) {
// unremappable channel, with channel still free
devChannel = c;
}
@@ -1192,8 +1230,12 @@ ChannelRemapping *SciMusic::determineChannelMap() {
int neededVoices = channel._voices;
// do we have enough free voices?
if (map->_freeVoices < neededVoices) {
- // We only care for essential channels
- if (prio > 0) {
+ // We only care for essential channels.
+ // Note: In early SCI1 interpreters, a song started by 'playBed'
+ // would not be skipped even if some channels couldn't be
+ // mapped due to voice limits. So, we treat all channels as
+ // non-essential here for playBed songs.
+ if (prio > 0 || (song->playBed && _soundVersion <= SCI_VERSION_1_EARLY)) {
#ifdef DEBUG_REMAP
debug(" not enough voices; need %d, have %d. Skipping this channel.", neededVoices, map->_freeVoices);
#endif
@@ -1229,10 +1271,10 @@ ChannelRemapping *SciMusic::determineChannelMap() {
map->_map[devChannel] = dc;
map->_voices[devChannel] = neededVoices;
map->_prio[devChannel] = prio;
- map->_dontRemap[devChannel] = channel._dontRemap;
+ map->_dontRemap[devChannel] = dontRemap;
map->_freeVoices -= neededVoices;
- if (!channel._dontRemap || devChannel == c) {
+ if (!dontRemap || devChannel == c) {
// If this channel fits here, we're done.
#ifdef DEBUG_REMAP
debug(" OK");
@@ -1285,14 +1327,18 @@ ChannelRemapping *SciMusic::determineChannelMap() {
return map;
}
-void SciMusic::resetDeviceChannel(int devChannel) {
- // NB: This function should only be called from the main thread
-
+void SciMusic::resetDeviceChannel(int devChannel, bool mainThread) {
assert(devChannel >= 0 && devChannel <= 0x0F);
- putMidiCommandInQueue(0x0040B0 | devChannel); // sustain off
- putMidiCommandInQueue(0x007BB0 | devChannel); // notes off
- putMidiCommandInQueue(0x004BB0 | devChannel); // release voices
+ if (mainThread) {
+ putMidiCommandInQueue(0x0040B0 | devChannel); // sustain off
+ putMidiCommandInQueue(0x007BB0 | devChannel); // notes off
+ putMidiCommandInQueue(0x004BB0 | devChannel); // release voices
+ } else {
+ _pMidiDrv->send(0x0040B0 | devChannel); // sustain off
+ _pMidiDrv->send(0x007BB0 | devChannel); // notes off
+ _pMidiDrv->send(0x004BB0 | devChannel); // release voices
+ }
}
diff --git a/engines/sci/sound/music.h b/engines/sci/sound/music.h
index 4e44074630..a610f32d89 100644
--- a/engines/sci/sound/music.h
+++ b/engines/sci/sound/music.h
@@ -75,6 +75,8 @@ public:
SoundResource *soundRes;
uint16 resourceId;
+ int time; // "tim"estamp to indicate in which order songs have been added
+
bool isQueued; // for SCI0 only!
uint16 dataInc;
@@ -85,6 +87,8 @@ public:
int16 volume;
int16 hold;
int8 reverb;
+ bool playBed;
+ bool overridePriority; // Use soundObj's priority instead of resource's
int16 pauseCounter;
uint sampleLoopCounter;
@@ -224,6 +228,8 @@ public:
byte getCurrentReverb();
+ void needsRemap() { _needsRemap = true; }
+
virtual void saveLoadWithSerializer(Common::Serializer &ser);
// Mutex for music code. Used to guard access to the song playlist, to the
@@ -245,9 +251,9 @@ protected:
bool _useDigitalSFX;
// remapping:
- void remapChannels();
+ void remapChannels(bool mainThread = true);
ChannelRemapping *determineChannelMap();
- void resetDeviceChannel(int devChannel);
+ void resetDeviceChannel(int devChannel, bool mainThread);
private:
MusicList _playList;
@@ -256,6 +262,7 @@ private:
MusicEntry *_usedChannel[16];
int8 _channelRemap[16];
int8 _globalReverb;
+ bool _needsRemap;
DeviceChannelUsage _channelMap[16];
@@ -266,6 +273,9 @@ private:
int _driverLastChannel;
MusicEntry *_currentlyPlayingSample;
+
+ int _timeCounter; // Used to keep track of the order in which MusicEntries
+ // are added, for priority purposes.
};
} // End of namespace Sci
diff --git a/engines/sci/sound/soundcmd.cpp b/engines/sci/sound/soundcmd.cpp
index 73e0a23a6a..64991cbf5c 100644
--- a/engines/sci/sound/soundcmd.cpp
+++ b/engines/sci/sound/soundcmd.cpp
@@ -142,11 +142,14 @@ void SoundCommandParser::processInitSound(reg_t obj) {
reg_t SoundCommandParser::kDoSoundPlay(int argc, reg_t *argv, reg_t acc) {
debugC(kDebugLevelSound, "kDoSound(play): %04x:%04x", PRINT_REG(argv[0]));
- processPlaySound(argv[0]);
+ bool playBed = false;
+ if (argc >= 2 && !argv[1].isNull())
+ playBed = true;
+ processPlaySound(argv[0], playBed);
return acc;
}
-void SoundCommandParser::processPlaySound(reg_t obj) {
+void SoundCommandParser::processPlaySound(reg_t obj, bool playBed) {
MusicEntry *musicSlot = _music->getSlot(obj);
if (!musicSlot) {
warning("kDoSound(play): Slot not found (%04x:%04x), initializing it manually", PRINT_REG(obj));
@@ -181,15 +184,24 @@ void SoundCommandParser::processPlaySound(reg_t obj) {
}
musicSlot->loop = readSelectorValue(_segMan, obj, SELECTOR(loop));
- musicSlot->priority = readSelectorValue(_segMan, obj, SELECTOR(priority));
+
+ // Get song priority from either obj or soundRes
+ byte resourcePriority = musicSlot->soundRes->getSoundPriority();
+ if (!musicSlot->overridePriority && resourcePriority != 0xFF) {
+ musicSlot->priority = resourcePriority;
+ } else {
+ musicSlot->priority = readSelectorValue(_segMan, obj, SELECTOR(priority));
+ }
+
// Reset hold when starting a new song. kDoSoundSetHold is always called after
// kDoSoundPlay to set it properly, if needed. Fixes bug #3413589.
musicSlot->hold = -1;
+ musicSlot->playBed = playBed;
if (_soundVersion >= SCI_VERSION_1_EARLY)
musicSlot->volume = readSelectorValue(_segMan, obj, SELECTOR(vol));
- debugC(kDebugLevelSound, "kDoSound(play): %04x:%04x number %d, loop %d, prio %d, vol %d", PRINT_REG(obj),
- resourceId, musicSlot->loop, musicSlot->priority, musicSlot->volume);
+ debugC(kDebugLevelSound, "kDoSound(play): %04x:%04x number %d, loop %d, prio %d, vol %d, bed %d", PRINT_REG(obj),
+ resourceId, musicSlot->loop, musicSlot->priority, musicSlot->volume, playBed ? 1 : 0);
_music->soundPlay(musicSlot);
@@ -538,7 +550,7 @@ void SoundCommandParser::processUpdateCues(reg_t obj) {
if (_soundVersion >= SCI_VERSION_1_EARLY) {
writeSelectorValue(_segMan, obj, SELECTOR(min), musicSlot->ticker / 3600);
writeSelectorValue(_segMan, obj, SELECTOR(sec), musicSlot->ticker % 3600 / 60);
- writeSelectorValue(_segMan, obj, SELECTOR(frame), musicSlot->ticker);
+ writeSelectorValue(_segMan, obj, SELECTOR(frame), musicSlot->ticker % 60 / 2);
}
}
@@ -673,23 +685,19 @@ reg_t SoundCommandParser::kDoSoundSetPriority(int argc, reg_t *argv, reg_t acc)
}
if (value == -1) {
- uint16 resourceId = musicSlot->resourceId;
+ musicSlot->overridePriority = false;
+ musicSlot->priority = 0;
- // Set priority from the song data
- Resource *song = _resMan->findResource(ResourceId(kResourceTypeSound, resourceId), 0);
- if (song->data[0] == 0xf0)
- _music->soundSetPriority(musicSlot, song->data[1]);
- else
- warning("kDoSound(setPriority): Attempt to unset song priority when there is no built-in value");
+ // NB: It seems SSCI doesn't actually reset the priority here.
- //pSnd->prio=0;field_15B=0
writeSelectorValue(_segMan, obj, SELECTOR(flags), readSelectorValue(_segMan, obj, SELECTOR(flags)) & 0xFD);
} else {
// Scripted priority
+ musicSlot->overridePriority = true;
- //pSnd->field_15B=1;
writeSelectorValue(_segMan, obj, SELECTOR(flags), readSelectorValue(_segMan, obj, SELECTOR(flags)) | 2);
- //DoSOund(0xF,hobj,w)
+
+ _music->soundSetPriority(musicSlot, value);
}
return acc;
}
@@ -777,6 +785,8 @@ void SoundCommandParser::stopAllSounds() {
}
void SoundCommandParser::startNewSound(int number) {
+ // NB: This is only used by the debugging console.
+
Common::StackLock lock(_music->_mutex);
// Overwrite the first sound in the playlist
@@ -785,7 +795,7 @@ void SoundCommandParser::startNewSound(int number) {
processDisposeSound(soundObj);
writeSelectorValue(_segMan, soundObj, SELECTOR(number), number);
processInitSound(soundObj);
- processPlaySound(soundObj);
+ processPlaySound(soundObj, false);
}
void SoundCommandParser::setMasterVolume(int vol) {
diff --git a/engines/sci/sound/soundcmd.h b/engines/sci/sound/soundcmd.h
index 4effda68e4..5bb7cf2cb1 100644
--- a/engines/sci/sound/soundcmd.h
+++ b/engines/sci/sound/soundcmd.h
@@ -63,7 +63,7 @@ public:
void printPlayList(Console *con);
void printSongInfo(reg_t obj, Console *con);
- void processPlaySound(reg_t obj);
+ void processPlaySound(reg_t obj, bool playBed);
void processStopSound(reg_t obj, bool sampleFinishedPlaying);
void initSoundResource(MusicEntry *newSound);