diff options
Diffstat (limited to 'engines')
-rw-r--r-- | engines/zvision/scripting/actions.cpp | 35 | ||||
-rw-r--r-- | engines/zvision/scripting/actions.h | 4 | ||||
-rw-r--r-- | engines/zvision/scripting/sidefx/music_node.cpp | 56 | ||||
-rw-r--r-- | engines/zvision/scripting/sidefx/music_node.h | 55 |
4 files changed, 132 insertions, 18 deletions
diff --git a/engines/zvision/scripting/actions.cpp b/engines/zvision/scripting/actions.cpp index 839eb1f92c..2464f54861 100644 --- a/engines/zvision/scripting/actions.cpp +++ b/engines/zvision/scripting/actions.cpp @@ -313,21 +313,26 @@ ActionMusic::ActionMusic(ZVision *engine, int32 slotkey, const Common::String &l // type 4 are midi sound effect files if (type == 4) { - _soundType = Audio::Mixer::kSFXSoundType; - _fileName = Common::String::format("midi/%s/%u.wav", fileNameBuffer, loop); - _loop = false; + _midi = true; + int note; + int prog; + sscanf(line.c_str(), "%u %d %d %u", &type, &prog, ¬e, &volume); + _volume = volume; + _note = note; + _prog = prog; } else { - // TODO: See what the other types are so we can specify the correct Mixer::SoundType. In the meantime use kPlainSoundType - _soundType = Audio::Mixer::kPlainSoundType; + _midi = false; _fileName = Common::String(fileNameBuffer); _loop = loop == 1 ? true : false; - } - // Volume is optional. If it doesn't appear, assume full volume - if (volume != 255) { - // Volume in the script files is mapped to [0, 100], but the ScummVM mixer uses [0, 255] - _volume = volume * 255 / 100; + // Volume is optional. If it doesn't appear, assume full volume + if (volume != 255) { + // Volume in the script files is mapped to [0, 100], but the ScummVM mixer uses [0, 255] + _volume = volume * 255 / 100; + } } + + } ActionMusic::~ActionMusic() { @@ -339,10 +344,14 @@ bool ActionMusic::execute() { if (_engine->getScriptManager()->getSideFX(_slotkey)) return true; - if (!_engine->getSearchManager()->hasFile(_fileName)) - return true; + if (_midi) { + _engine->getScriptManager()->addSideFX(new MusicMidiNode(_engine, _slotkey, _prog, _note, _volume)); + } else { + if (!_engine->getSearchManager()->hasFile(_fileName)) + return true; - _engine->getScriptManager()->addSideFX(new MusicNode(_engine, _slotkey, _fileName, _loop, _volume)); + _engine->getScriptManager()->addSideFX(new MusicNode(_engine, _slotkey, _fileName, _loop, _volume)); + } return true; } diff --git a/engines/zvision/scripting/actions.h b/engines/zvision/scripting/actions.h index 5e34f6eaf0..b3c46d16ce 100644 --- a/engines/zvision/scripting/actions.h +++ b/engines/zvision/scripting/actions.h @@ -243,11 +243,13 @@ public: private: uint32 _key; - Audio::Mixer::SoundType _soundType; Common::String _fileName; bool _loop; byte _volume; bool _universe; + bool _midi; + int8 _note; + int8 _prog; }; class ActionPanTrack : public ResultAction { diff --git a/engines/zvision/scripting/sidefx/music_node.cpp b/engines/zvision/scripting/sidefx/music_node.cpp index 0351867dd9..4420da3e96 100644 --- a/engines/zvision/scripting/sidefx/music_node.cpp +++ b/engines/zvision/scripting/sidefx/music_node.cpp @@ -25,6 +25,7 @@ #include "zvision/scripting/sidefx/music_node.h" #include "zvision/zvision.h" +#include "zvision/core/midi.h" #include "zvision/scripting/script_manager.h" #include "zvision/graphics/render_manager.h" #include "zvision/sound/zork_raw.h" @@ -37,7 +38,7 @@ namespace ZVision { MusicNode::MusicNode(ZVision *engine, uint32 key, Common::String &filename, bool loop, int8 volume) - : SideFX(engine, key, SIDEFX_AUDIO) { + : MusicNode_BASE(engine, key, SIDEFX_AUDIO) { _loop = loop; _volume = volume; _crossfade = false; @@ -174,7 +175,7 @@ PanTrackNode::PanTrackNode(ZVision *engine, uint32 key, uint32 slot, int16 pos) SideFX *fx = _engine->getScriptManager()->getSideFX(slot); if (fx && fx->getType() == SIDEFX_AUDIO) { - MusicNode *mus = (MusicNode *)fx; + MusicNode_BASE *mus = (MusicNode_BASE *)fx; mus->setPanTrack(pos); } } @@ -182,9 +183,58 @@ PanTrackNode::PanTrackNode(ZVision *engine, uint32 key, uint32 slot, int16 pos) PanTrackNode::~PanTrackNode() { SideFX *fx = _engine->getScriptManager()->getSideFX(_slot); if (fx && fx->getType() == SIDEFX_AUDIO) { - MusicNode *mus = (MusicNode *)fx; + MusicNode_BASE *mus = (MusicNode_BASE *)fx; mus->unsetPanTrack(); } } + +MusicMidiNode::MusicMidiNode(ZVision *engine, uint32 key, int8 program, int8 note, int8 volume) + : MusicNode_BASE(engine, key, SIDEFX_AUDIO) { + _volume = volume; + _prog = program; + _noteNumber = note; + _pan = 0; + + _chan = _engine->getMidiManager()->getFreeChannel(); + + if (_chan >= 0) { + _engine->getMidiManager()->setVolume(_chan, _volume); + _engine->getMidiManager()->setPan(_chan, _pan); + _engine->getMidiManager()->setProgram(_chan, _prog); + _engine->getMidiManager()->noteOn(_chan, _noteNumber, _volume); + } + + if (_key != StateKey_NotSet) + _engine->getScriptManager()->setStateValue(_key, 1); +} + +MusicMidiNode::~MusicMidiNode() { + if (_chan >= 0) { + _engine->getMidiManager()->noteOff(_chan); + } + if (_key != StateKey_NotSet) + _engine->getScriptManager()->setStateValue(_key, 2); +} + +void MusicMidiNode::setPanTrack(int16 pos) { +} + +void MusicMidiNode::unsetPanTrack() { +} + +void MusicMidiNode::setFade(int32 time, uint8 target) { +} + +bool MusicMidiNode::process(uint32 deltaTimeInMillis) { + return false; +} + +void MusicMidiNode::setVolume(uint8 new_volume) { + if (_chan >= 0) { + _engine->getMidiManager()->setVolume(_chan, new_volume); + } + _volume = new_volume; +} + } // End of namespace ZVision diff --git a/engines/zvision/scripting/sidefx/music_node.h b/engines/zvision/scripting/sidefx/music_node.h index 066b8f80f4..262b13085e 100644 --- a/engines/zvision/scripting/sidefx/music_node.h +++ b/engines/zvision/scripting/sidefx/music_node.h @@ -32,7 +32,30 @@ class String; } namespace ZVision { -class MusicNode : public SideFX { + +class MusicNode_BASE : public SideFX { +public: + MusicNode_BASE(ZVision *engine, uint32 key, SideFXType type) : SideFX(engine, key, type) {} + ~MusicNode_BASE() {} + + /** + * Decrement the timer by the delta time. If the timer is finished, set the status + * in _globalState and let this node be deleted + * + * @param deltaTimeInMillis The number of milliseconds that have passed since last frame + * @return If true, the node can be deleted after process() finishes + */ + virtual bool process(uint32 deltaTimeInMillis) = 0; + + virtual void setVolume(uint8 volume) = 0; + + virtual void setPanTrack(int16 pos) = 0; + virtual void unsetPanTrack() = 0; + + virtual void setFade(int32 time, uint8 target) = 0; +}; + +class MusicNode : public MusicNode_BASE { public: MusicNode(ZVision *engine, uint32 key, Common::String &file, bool loop, int8 volume); ~MusicNode(); @@ -68,6 +91,36 @@ private: Subtitle *_sub; }; +class MusicMidiNode : public MusicNode_BASE { +public: + MusicMidiNode(ZVision *engine, uint32 key, int8 program, int8 note, int8 volume); + ~MusicMidiNode(); + + /** + * Decrement the timer by the delta time. If the timer is finished, set the status + * in _globalState and let this node be deleted + * + * @param deltaTimeInMillis The number of milliseconds that have passed since last frame + * @return If true, the node can be deleted after process() finishes + */ + bool process(uint32 deltaTimeInMillis); + + void setVolume(uint8 volume); + + void setPanTrack(int16 pos); + void unsetPanTrack(); + + void setFade(int32 time, uint8 target); + +private: + int8 _chan; + int8 _noteNumber; + int8 _velocity; + int8 _pan; + int8 _volume; + int8 _prog; +}; + class PanTrackNode : public SideFX { public: PanTrackNode(ZVision *engine, uint32 key, uint32 slot, int16 pos); |