MOHAWK: Separate background sound handling from other sounds for Myst. Allow the scripts to change the background sound volume.
svn-id: r54953
This commit is contained in:
parent
41acf18a53
commit
c870bf22d1
8 changed files with 116 additions and 56 deletions
|
@ -215,8 +215,7 @@ bool MystConsole::Cmd_PlaySound(int argc, const char **argv) {
|
|||
return true;
|
||||
}
|
||||
|
||||
_vm->_sound->stopSound();
|
||||
_vm->_sound->playSound((uint16)atoi(argv[1]));
|
||||
_vm->_sound->replaceSound((uint16)atoi(argv[1]));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -453,6 +453,7 @@ void MohawkEngine_Myst::changeToStack(uint16 stack) {
|
|||
// Clear the resource cache and the image cache
|
||||
_cache.clear();
|
||||
_gfx->clearCache();
|
||||
_sound->stopBackground();
|
||||
}
|
||||
|
||||
uint16 MohawkEngine_Myst::getCardBackgroundId() {
|
||||
|
@ -521,27 +522,17 @@ void MohawkEngine_Myst::changeToCard(uint16 card, bool updateScreen) {
|
|||
soundActionVolume = _view.soundVolume;
|
||||
}
|
||||
|
||||
// NOTE: Mixer only has 8-bit channel volume granularity,
|
||||
// Myst uses 16-bit? Or is part of this balance?
|
||||
soundActionVolume = (byte)(soundActionVolume / 255);
|
||||
|
||||
if (soundAction == kMystSoundActionContinue)
|
||||
debug(2, "Continuing with current sound");
|
||||
else if (soundAction == kMystSoundActionChangeVolume) {
|
||||
debug(2, "Continuing with current sound, changing volume");
|
||||
// TODO: Implement Volume Control..
|
||||
_sound->changeBackgroundVolume(soundActionVolume);
|
||||
} else if (soundAction == kMystSoundActionStop) {
|
||||
debug(2, "Stopping sound");
|
||||
_sound->stopSound();
|
||||
_sound->stopBackground();
|
||||
} else if (soundAction > 0) {
|
||||
debug(2, "Playing new sound %d", soundAction);
|
||||
_sound->stopSound();
|
||||
// TODO: Need to keep sound handle and add function to change volume of
|
||||
// looped running sound for kMystSoundActionChangeVolume type
|
||||
|
||||
// NOTE: All sounds are looped when played via the sound section of the
|
||||
// VIEW resources.
|
||||
_sound->playSound(soundAction, soundActionVolume, true);
|
||||
_sound->replaceBackground(soundAction, soundActionVolume);
|
||||
} else {
|
||||
error("Unknown sound action %d", soundAction);
|
||||
}
|
||||
|
|
|
@ -171,14 +171,20 @@ MystResourceType6::MystResourceType6(MohawkEngine_Myst *vm, Common::SeekableRead
|
|||
_videoFile = convertMystVideoName(_videoFile);
|
||||
|
||||
// Position values require modulus 10000 to keep in sane range.
|
||||
_left = rlstStream->readUint16LE() % 10000;
|
||||
_top = rlstStream->readUint16LE() % 10000;
|
||||
_left = rlstStream->readSint16LE() % 10000;
|
||||
_top = rlstStream->readSint16LE() % 10000;
|
||||
_playOnCardChange = rlstStream->readUint16LE();
|
||||
_direction = rlstStream->readUint16LE();
|
||||
_playBlocking = rlstStream->readUint16LE();
|
||||
_loop = rlstStream->readUint16LE();
|
||||
_u3 = rlstStream->readUint16LE();
|
||||
|
||||
// TODO: Out of bound values should clip the movie
|
||||
if (_left < 0)
|
||||
_left = 0;
|
||||
if (_top < 0)
|
||||
_top = 0;
|
||||
|
||||
if (_direction != 1)
|
||||
warning("Type 6 _u0 != 1");
|
||||
if (_u3 != 0)
|
||||
|
@ -648,7 +654,7 @@ void MystResourceType10::updatePosition(const Common::Point &mouse) {
|
|||
}
|
||||
|
||||
if (positionChanged && _dragSound) {
|
||||
_vm->_sound->playSound(_dragSound);
|
||||
_vm->_sound->replaceSound(_dragSound);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -112,8 +112,8 @@ public:
|
|||
protected:
|
||||
static Common::String convertMystVideoName(Common::String name);
|
||||
Common::String _videoFile;
|
||||
uint16 _left;
|
||||
uint16 _top;
|
||||
int16 _left;
|
||||
int16 _top;
|
||||
uint16 _loop;
|
||||
uint16 _direction; // 1 => forward, -1 => backwards
|
||||
uint16 _playBlocking;
|
||||
|
|
|
@ -128,7 +128,7 @@ void MystScriptParser::setupCommonOpcodes() {
|
|||
OPCODE(27, o_playSoundBlocking);
|
||||
OPCODE(28, o_copyBackBufferToScreen);
|
||||
OPCODE(29, o_copyImageToBackBuffer);
|
||||
OPCODE(30, o_changeSound);
|
||||
OPCODE(30, o_changeBackgroundSound);
|
||||
OPCODE(31, o_soundPlaySwitch);
|
||||
OPCODE(32, o_soundResumeBackground);
|
||||
OPCODE(33, o_copyImageToScreen);
|
||||
|
@ -558,14 +558,14 @@ void MystScriptParser::o_playSound(uint16 op, uint16 var, uint16 argc, uint16 *a
|
|||
debugC(kDebugScript, "Opcode %d: playSound", op);
|
||||
debugC(kDebugScript, "\tsoundId: %d", soundId);
|
||||
|
||||
_vm->_sound->playSound(soundId);
|
||||
_vm->_sound->replaceSound(soundId);
|
||||
} else
|
||||
unknown(op, var, argc, argv);
|
||||
}
|
||||
|
||||
void MystScriptParser::o_stopSoundBackground(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
|
||||
debugC(kDebugScript, "Opcode %d: stopSoundBackground", op);
|
||||
//_vm->_sound->stopBackground();
|
||||
_vm->_sound->stopBackground();
|
||||
}
|
||||
|
||||
void MystScriptParser::o_playSoundBlocking(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
|
||||
|
@ -636,7 +636,7 @@ void MystScriptParser::o_copyImageToBackBuffer(uint16 op, uint16 var, uint16 arg
|
|||
// Current behaviour here and with VIEW sound block is not right as demonstrated
|
||||
// by Channelwood Card 3280 (Tank Valve) and water flow sound behaviour in pipe
|
||||
// on cards leading from shed...
|
||||
void MystScriptParser::o_changeSound(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
|
||||
void MystScriptParser::o_changeBackgroundSound(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
|
||||
varUnusedCheck(op, var);
|
||||
|
||||
int16 *soundList = NULL;
|
||||
|
@ -682,27 +682,20 @@ void MystScriptParser::o_changeSound(uint16 op, uint16 var, uint16 argc, uint16
|
|||
}
|
||||
}
|
||||
|
||||
// NOTE: Mixer only has 8-bit channel volume granularity,
|
||||
// Myst uses 16-bit? Or is part of this balance?
|
||||
soundVolume = (byte)(soundVolume / 255);
|
||||
|
||||
if (soundAction == kMystSoundActionContinue)
|
||||
debugC(kDebugScript, "Continue current sound");
|
||||
else if (soundAction == kMystSoundActionChangeVolume) {
|
||||
debugC(kDebugScript, "Continue current sound, change volume");
|
||||
debugC(kDebugScript, "\tVolume: %d", soundVolume);
|
||||
// TODO: Implement Volume Control..
|
||||
_vm->_sound->changeBackgroundVolume(soundVolume);
|
||||
} else if (soundAction == kMystSoundActionStop) {
|
||||
debugC(kDebugScript, "Stop sound");
|
||||
_vm->_sound->stopSound();
|
||||
_vm->_sound->stopBackground();
|
||||
} else if (soundAction > 0) {
|
||||
debugC(kDebugScript, "Play new Sound, change volume");
|
||||
debugC(kDebugScript, "\tSound: %d", soundAction);
|
||||
debugC(kDebugScript, "\tVolume: %d", soundVolume);
|
||||
_vm->_sound->stopSound();
|
||||
// TODO: Need to keep sound handle and add function to change volume of
|
||||
// looped running sound for kMystSoundActionChangeVolume type
|
||||
_vm->_sound->playSound(soundAction, soundVolume);
|
||||
_vm->_sound->replaceBackground(soundAction, soundVolume);
|
||||
} else {
|
||||
debugC(kDebugScript, "Unknown");
|
||||
warning("Unknown sound control value in opcode %d", op);
|
||||
|
@ -726,13 +719,13 @@ void MystScriptParser::o_soundPlaySwitch(uint16 op, uint16 var, uint16 argc, uin
|
|||
debugC(kDebugScript, "\tsoundId: %d", soundId);
|
||||
|
||||
if (soundId)
|
||||
_vm->_sound->playSound(soundId);
|
||||
_vm->_sound->replaceSound(soundId);
|
||||
}
|
||||
}
|
||||
|
||||
void MystScriptParser::o_soundResumeBackground(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
|
||||
debugC(kDebugScript, "Opcode %d: soundResumeBackground", op);
|
||||
//_vm->_sound->resumeBackground();
|
||||
_vm->_sound->resumeBackground();
|
||||
}
|
||||
|
||||
void MystScriptParser::o_copyImageToScreen(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
|
||||
|
@ -857,7 +850,7 @@ void MystScriptParser::o_changeStack(uint16 op, uint16 var, uint16 argc, uint16
|
|||
// wrong as you're not actually linking when using this opcode. The sounds are only
|
||||
// played for the full game linking.
|
||||
if (!_vm->_tweaksEnabled) {
|
||||
handle= _vm->_sound->playSound(soundIdLinkSrc);
|
||||
handle= _vm->_sound->replaceSound(soundIdLinkSrc);
|
||||
while (_vm->_mixer->isSoundHandleActive(*handle))
|
||||
_vm->_system->delayMillis(10);
|
||||
}
|
||||
|
@ -872,12 +865,12 @@ void MystScriptParser::o_changeStack(uint16 op, uint16 var, uint16 argc, uint16
|
|||
}
|
||||
|
||||
if (!_vm->_tweaksEnabled) {
|
||||
handle = _vm->_sound->playSound(soundIdLinkDst);
|
||||
handle = _vm->_sound->replaceSound(soundIdLinkDst);
|
||||
while (_vm->_mixer->isSoundHandleActive(*handle))
|
||||
_vm->_system->delayMillis(10);
|
||||
}
|
||||
} else {
|
||||
handle = _vm->_sound->playSound(soundIdLinkSrc);
|
||||
handle = _vm->_sound->replaceSound(soundIdLinkSrc);
|
||||
while (_vm->_mixer->isSoundHandleActive(*handle))
|
||||
_vm->_system->delayMillis(10);
|
||||
|
||||
|
@ -886,7 +879,7 @@ void MystScriptParser::o_changeStack(uint16 op, uint16 var, uint16 argc, uint16
|
|||
_vm->changeToStack(_stackMap[targetStack]);
|
||||
_vm->changeToCard(_startCard[targetStack], true);
|
||||
|
||||
handle = _vm->_sound->playSound(soundIdLinkDst);
|
||||
handle = _vm->_sound->replaceSound(soundIdLinkDst);
|
||||
while (_vm->_mixer->isSoundHandleActive(*handle))
|
||||
_vm->_system->delayMillis(10);
|
||||
}
|
||||
|
@ -908,7 +901,7 @@ void MystScriptParser::o_changeCardPlaySoundDirectional(uint16 op, uint16 var, u
|
|||
debugC(kDebugScript, "\tanimated update data size: %d", dataSize);
|
||||
|
||||
if (soundId)
|
||||
_vm->_sound->playSound(soundId);
|
||||
_vm->_sound->replaceSound(soundId);
|
||||
|
||||
_vm->changeToCard(cardId, false);
|
||||
|
||||
|
@ -927,7 +920,7 @@ void MystScriptParser::o_directionalUpdatePlaySound(uint16 op, uint16 var, uint1
|
|||
debugC(kDebugScript, "\tanimated update data size: %d", dataSize);
|
||||
|
||||
if (soundId)
|
||||
_vm->_sound->playSound(soundId);
|
||||
_vm->_sound->replaceSound(soundId);
|
||||
|
||||
animatedUpdate(dataSize, &argv[3], delayBetweenSteps);
|
||||
}
|
||||
|
|
|
@ -103,7 +103,7 @@ public:
|
|||
DECLARE_OPCODE(o_playSoundBlocking);
|
||||
DECLARE_OPCODE(o_copyBackBufferToScreen);
|
||||
DECLARE_OPCODE(o_copyImageToBackBuffer);
|
||||
DECLARE_OPCODE(o_changeSound);
|
||||
DECLARE_OPCODE(o_changeBackgroundSound);
|
||||
DECLARE_OPCODE(o_soundPlaySwitch);
|
||||
DECLARE_OPCODE(o_copyImageToScreen);
|
||||
DECLARE_OPCODE(o_soundResumeBackground);
|
||||
|
|
|
@ -70,9 +70,7 @@ void Sound::initMidi() {
|
|||
_midiParser->setTimerRate(_midiDriver->getBaseTempo());
|
||||
}
|
||||
|
||||
Audio::SoundHandle *Sound::playSound(uint16 id, byte volume, bool loop) {
|
||||
debug (0, "Playing sound %d", id);
|
||||
|
||||
Audio::AudioStream *Sound::makeAudioStream(uint16 id) {
|
||||
Audio::AudioStream *audStream = NULL;
|
||||
|
||||
switch (_vm->getGameType()) {
|
||||
|
@ -103,6 +101,14 @@ Audio::SoundHandle *Sound::playSound(uint16 id, byte volume, bool loop) {
|
|||
audStream = makeMohawkWaveStream(_vm->getResource(ID_TWAV, id));
|
||||
}
|
||||
|
||||
return audStream;
|
||||
}
|
||||
|
||||
Audio::SoundHandle *Sound::playSound(uint16 id, byte volume, bool loop) {
|
||||
debug (0, "Playing sound %d", id);
|
||||
|
||||
Audio::AudioStream *audStream = makeAudioStream(id);
|
||||
|
||||
if (audStream) {
|
||||
SndHandle *handle = getHandle();
|
||||
handle->type = kUsedHandle;
|
||||
|
@ -127,12 +133,11 @@ Audio::SoundHandle *Sound::replaceSound(uint16 id, byte volume, bool loop) {
|
|||
Common::String name = _vm->getResourceName(ID_MSND, id);
|
||||
|
||||
// Check if sound is already playing
|
||||
for (uint32 i = 0; i < _handles.size(); i++) {
|
||||
if (_vm->_mixer->isSoundHandleActive(_handles[i].handle)
|
||||
&& name.equals(_vm->getResourceName(ID_MSND, _handles[i].id))) {
|
||||
for (uint32 i = 0; i < _handles.size(); i++)
|
||||
if (_handles[i].type == kUsedHandle
|
||||
&& _vm->_mixer->isSoundHandleActive(_handles[i].handle)
|
||||
&& name.equals(_vm->getResourceName(ID_MSND, _handles[i].id)))
|
||||
return &_handles[i].handle;
|
||||
}
|
||||
}
|
||||
|
||||
stopSound();
|
||||
return playSound(id, volume, loop);
|
||||
|
@ -552,4 +557,66 @@ bool Sound::isPlaying(uint16 id) {
|
|||
return false;
|
||||
}
|
||||
|
||||
Audio::SoundHandle *Sound::replaceBackground(uint16 id, uint16 volume) {
|
||||
debug (0, "Replacing background %d", id);
|
||||
|
||||
//TODO: The original engine does fading
|
||||
|
||||
Common::String name = _vm->getResourceName(ID_MSND, id);
|
||||
|
||||
// Check if sound is already playing
|
||||
for (uint32 i = 0; i < _handles.size(); i++)
|
||||
if (_handles[i].type == kBackgroundHandle
|
||||
&& _vm->_mixer->isSoundHandleActive(_handles[i].handle)
|
||||
&& name.equals(_vm->getResourceName(ID_MSND, _handles[i].id)))
|
||||
return &_handles[i].handle;
|
||||
|
||||
// Stop old background sound
|
||||
stopBackground();
|
||||
|
||||
// Play new sound
|
||||
Audio::AudioStream *audStream = makeAudioStream(id);
|
||||
|
||||
if (audStream) {
|
||||
SndHandle *handle = getHandle();
|
||||
handle->type = kBackgroundHandle;
|
||||
handle->id = id;
|
||||
|
||||
// Set the stream to loop
|
||||
audStream = Audio::makeLoopingAudioStream((Audio::RewindableAudioStream *)audStream, 0);
|
||||
|
||||
_vm->_mixer->playStream(Audio::Mixer::kPlainSoundType, &handle->handle, audStream, -1, volume >> 8);
|
||||
return &handle->handle;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void Sound::stopBackground() {
|
||||
for (uint32 i = 0; i < _handles.size(); i++)
|
||||
if (_handles[i].type == kBackgroundHandle) {
|
||||
_vm->_mixer->stopHandle(_handles[i].handle);
|
||||
_handles[i].type = kFreeHandle;
|
||||
_handles[i].id = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Sound::pauseBackground() {
|
||||
for (uint32 i = 0; i < _handles.size(); i++)
|
||||
if (_handles[i].type == kBackgroundHandle)
|
||||
_vm->_mixer->pauseHandle(_handles[i].handle, true);
|
||||
}
|
||||
|
||||
void Sound::resumeBackground() {
|
||||
for (uint32 i = 0; i < _handles.size(); i++)
|
||||
if (_handles[i].type == kBackgroundHandle)
|
||||
_vm->_mixer->pauseHandle(_handles[i].handle, false);
|
||||
}
|
||||
|
||||
void Sound::changeBackgroundVolume(uint16 vol) {
|
||||
for (uint32 i = 0; i < _handles.size(); i++)
|
||||
if (_handles[i].type == kBackgroundHandle)
|
||||
_vm->_mixer->setChannelVolume(_handles[i].handle, vol >> 8);
|
||||
}
|
||||
|
||||
} // End of namespace Mohawk
|
||||
|
|
|
@ -59,7 +59,8 @@ struct SLSTRecord {
|
|||
|
||||
enum SndHandleType {
|
||||
kFreeHandle,
|
||||
kUsedHandle
|
||||
kUsedHandle,
|
||||
kBackgroundHandle
|
||||
};
|
||||
|
||||
struct SndHandle {
|
||||
|
@ -129,10 +130,12 @@ public:
|
|||
void resumeSound();
|
||||
bool isPlaying(uint16 id);
|
||||
|
||||
void pauseBackground() {} //TODO: implement
|
||||
void replaceBackground(uint16 id, uint16 volume) {}
|
||||
void resumeBackground() {}
|
||||
void stopBackground() {}
|
||||
// Myst background sound functions
|
||||
Audio::SoundHandle *replaceBackground(uint16 id, uint16 volume = 0xFFFF);
|
||||
void pauseBackground();
|
||||
void resumeBackground();
|
||||
void stopBackground();
|
||||
void changeBackgroundVolume(uint16 vol);
|
||||
|
||||
// Riven-specific
|
||||
void playSLST(uint16 index, uint16 card);
|
||||
|
@ -153,6 +156,7 @@ private:
|
|||
|
||||
Common::Array<SndHandle> _handles;
|
||||
SndHandle *getHandle();
|
||||
Audio::AudioStream *makeAudioStream(uint16 id);
|
||||
|
||||
// Riven-specific
|
||||
void playSLSTSound(uint16 index, bool fade, bool loop, uint16 volume, int16 balance);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue