diff options
-rw-r--r-- | engines/mohawk/console.cpp | 3 | ||||
-rw-r--r-- | engines/mohawk/myst.cpp | 17 | ||||
-rw-r--r-- | engines/mohawk/myst_areas.cpp | 12 | ||||
-rw-r--r-- | engines/mohawk/myst_areas.h | 4 | ||||
-rw-r--r-- | engines/mohawk/myst_scripts.cpp | 37 | ||||
-rw-r--r-- | engines/mohawk/myst_scripts.h | 2 | ||||
-rw-r--r-- | engines/mohawk/sound.cpp | 83 | ||||
-rw-r--r-- | engines/mohawk/sound.h | 14 |
8 files changed, 116 insertions, 56 deletions
diff --git a/engines/mohawk/console.cpp b/engines/mohawk/console.cpp index d406d7575c..bf1d9b02ce 100644 --- a/engines/mohawk/console.cpp +++ b/engines/mohawk/console.cpp @@ -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; } diff --git a/engines/mohawk/myst.cpp b/engines/mohawk/myst.cpp index 15232966dd..be3a776b60 100644 --- a/engines/mohawk/myst.cpp +++ b/engines/mohawk/myst.cpp @@ -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); } diff --git a/engines/mohawk/myst_areas.cpp b/engines/mohawk/myst_areas.cpp index 5b27a69ab9..6377f3255c 100644 --- a/engines/mohawk/myst_areas.cpp +++ b/engines/mohawk/myst_areas.cpp @@ -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); } } diff --git a/engines/mohawk/myst_areas.h b/engines/mohawk/myst_areas.h index 0aa5f082f6..6e84747fe4 100644 --- a/engines/mohawk/myst_areas.h +++ b/engines/mohawk/myst_areas.h @@ -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; diff --git a/engines/mohawk/myst_scripts.cpp b/engines/mohawk/myst_scripts.cpp index 279de90226..bf1aadcea0 100644 --- a/engines/mohawk/myst_scripts.cpp +++ b/engines/mohawk/myst_scripts.cpp @@ -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); } diff --git a/engines/mohawk/myst_scripts.h b/engines/mohawk/myst_scripts.h index f455daf66d..f16c4fcbd9 100644 --- a/engines/mohawk/myst_scripts.h +++ b/engines/mohawk/myst_scripts.h @@ -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); diff --git a/engines/mohawk/sound.cpp b/engines/mohawk/sound.cpp index 29a097e591..aec01dcdd5 100644 --- a/engines/mohawk/sound.cpp +++ b/engines/mohawk/sound.cpp @@ -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 diff --git a/engines/mohawk/sound.h b/engines/mohawk/sound.h index 2d3edad557..daadd765eb 100644 --- a/engines/mohawk/sound.h +++ b/engines/mohawk/sound.h @@ -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); |