aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/sound/soundcmd.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/sci/sound/soundcmd.cpp')
-rw-r--r--engines/sci/sound/soundcmd.cpp75
1 files changed, 50 insertions, 25 deletions
diff --git a/engines/sci/sound/soundcmd.cpp b/engines/sci/sound/soundcmd.cpp
index b0102a002b..ee5903fda2 100644
--- a/engines/sci/sound/soundcmd.cpp
+++ b/engines/sci/sound/soundcmd.cpp
@@ -8,12 +8,12 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
-
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
@@ -61,7 +61,7 @@ reg_t SoundCommandParser::kDoSoundInit(int argc, reg_t *argv, reg_t acc) {
}
int SoundCommandParser::getSoundResourceId(reg_t obj) {
- int resourceId = obj.getSegment() ? readSelectorValue(_segMan, obj, SELECTOR(number)) : -1;
+ int resourceId = obj.getSegment() ? (int)readSelectorValue(_segMan, obj, SELECTOR(number)) : -1;
// Modify the resourceId for the Windows versions that have an alternate MIDI soundtrack, like SSCI did.
if (g_sci && g_sci->_features->useAltWinGMSound()) {
// Check if the alternate MIDI song actually exists...
@@ -116,7 +116,10 @@ void SoundCommandParser::processInitSound(reg_t obj) {
newSound->resourceId = resourceId;
newSound->soundObj = obj;
newSound->loop = readSelectorValue(_segMan, obj, SELECTOR(loop));
- newSound->priority = readSelectorValue(_segMan, obj, SELECTOR(priority)) & 0xFF;
+ if (_soundVersion <= SCI_VERSION_0_LATE)
+ newSound->priority = readSelectorValue(_segMan, obj, SELECTOR(priority));
+ else
+ newSound->priority = readSelectorValue(_segMan, obj, SELECTOR(priority)) & 0xFF;
if (_soundVersion >= SCI_VERSION_1_EARLY)
newSound->volume = CLIP<int>(readSelectorValue(_segMan, obj, SELECTOR(vol)), 0, MUSIC_VOLUME_MAX);
newSound->reverb = -1; // initialize to SCI invalid, it'll be set correctly in soundInitSnd() below
@@ -139,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));
@@ -178,15 +184,26 @@ 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 = 0xFF;
+ if (musicSlot->soundRes)
+ 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);
@@ -428,7 +445,7 @@ reg_t SoundCommandParser::kDoSoundUpdate(int argc, reg_t *argv, reg_t acc) {
int16 objVol = CLIP<int>(readSelectorValue(_segMan, obj, SELECTOR(vol)), 0, 255);
if (objVol != musicSlot->volume)
_music->soundSetVolume(musicSlot, objVol);
- uint32 objPrio = readSelectorValue(_segMan, obj, SELECTOR(priority));
+ int16 objPrio = readSelectorValue(_segMan, obj, SELECTOR(priority));
if (objPrio != musicSlot->priority)
_music->soundSetPriority(musicSlot, objPrio);
return acc;
@@ -505,9 +522,19 @@ void SoundCommandParser::processUpdateCues(reg_t obj) {
// fireworks).
// It is also needed in other games, e.g. LSL6 when talking to the
// receptionist (bug #3192166).
- // CHECKME: At least kq5cd/win and kq6 set signal to 0xFE here, but
- // kq5cd/dos does not set signal at all. Needs more investigation.
- writeSelectorValue(_segMan, obj, SELECTOR(signal), SIGNAL_OFFSET);
+ // TODO: More thorougly check the different SCI version:
+ // * SCI1late sets signal to 0xFE here. (With signal 0xFF
+ // duplicate music plays in LauraBow2CD - bug #6462)
+ // SCI1middle LSL1 1.000.510 does not have the 0xFE;
+ // SCI1late CastleDrBrain demo 1.000.005 does have the 0xFE.
+ // * Other SCI1 games seem to rely on processStopSound to set the signal
+ // * Need to check SCI0 behaviour.
+ uint16 sig;
+ if (getSciVersion() >= SCI_VERSION_1_LATE)
+ sig = 0xFFFE;
+ else
+ sig = SIGNAL_OFFSET;
+ writeSelectorValue(_segMan, obj, SELECTOR(signal), sig);
if (_soundVersion <= SCI_VERSION_0_LATE) {
processStopSound(obj, false);
} else {
@@ -525,7 +552,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);
}
}
@@ -660,23 +687,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;
}
@@ -764,6 +787,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
@@ -772,7 +797,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) {