aboutsummaryrefslogtreecommitdiff
path: root/engines/zvision
diff options
context:
space:
mode:
Diffstat (limited to 'engines/zvision')
-rw-r--r--engines/zvision/actions.cpp24
-rw-r--r--engines/zvision/actions.h11
-rw-r--r--engines/zvision/music_node.cpp75
-rw-r--r--engines/zvision/music_node.h19
-rw-r--r--engines/zvision/scr_file_handling.cpp2
5 files changed, 126 insertions, 5 deletions
diff --git a/engines/zvision/actions.cpp b/engines/zvision/actions.cpp
index ccae6fd47c..3eec70d1ba 100644
--- a/engines/zvision/actions.cpp
+++ b/engines/zvision/actions.cpp
@@ -313,6 +313,30 @@ bool ActionMusic::execute() {
return true;
}
+//////////////////////////////////////////////////////////////////////////////
+// ActionPanTrack
+//////////////////////////////////////////////////////////////////////////////
+
+ActionPanTrack::ActionPanTrack(ZVision *engine, int32 slotkey, const Common::String &line) :
+ ResultAction(engine, slotkey),
+ _pos(0),
+ _mus_slot(0) {
+
+ sscanf(line.c_str(), "%u %d", &_mus_slot, &_pos);
+}
+
+ActionPanTrack::~ActionPanTrack() {
+ _engine->getScriptManager()->killSideFx(_slotkey);
+}
+
+bool ActionPanTrack::execute() {
+ if (_engine->getScriptManager()->getSideFX(_slotkey))
+ return true;
+
+ _engine->getScriptManager()->addSideFX(new PanTrackNode(_engine, _slotkey, _mus_slot, _pos));
+
+ return true;
+}
//////////////////////////////////////////////////////////////////////////////
// ActionPreloadAnimation
diff --git a/engines/zvision/actions.h b/engines/zvision/actions.h
index aadb97fc9b..417c1ada1a 100644
--- a/engines/zvision/actions.h
+++ b/engines/zvision/actions.h
@@ -247,6 +247,17 @@ private:
bool _universe;
};
+class ActionPanTrack : public ResultAction {
+public:
+ ActionPanTrack(ZVision *engine, int32 slotkey, const Common::String &line);
+ ~ActionPanTrack();
+ bool execute();
+
+private:
+ int32 _pos;
+ uint32 _mus_slot;
+};
+
class ActionPlayAnimation : public ResultAction {
public:
ActionPlayAnimation(ZVision *engine, int32 slotkey, const Common::String &line);
diff --git a/engines/zvision/music_node.cpp b/engines/zvision/music_node.cpp
index 709b554823..081c9dbcca 100644
--- a/engines/zvision/music_node.cpp
+++ b/engines/zvision/music_node.cpp
@@ -26,6 +26,7 @@
#include "zvision/zvision.h"
#include "zvision/script_manager.h"
+#include "zvision/render_manager.h"
#include "zvision/zork_raw.h"
#include "common/stream.h"
@@ -40,7 +41,7 @@ MusicNode::MusicNode(ZVision *engine, uint32 key, Common::String &filename, bool
_loop = loop;
_volume = volume;
_crossfade = false;
- _crossfade_delta = 0;
+ _crossfade_target = 0;
_crossfade_time = 0;
_attenuate = 0;
_pantrack = false;
@@ -57,6 +58,7 @@ MusicNode::MusicNode(ZVision *engine, uint32 key, Common::String &filename, bool
audioStream = makeRawZorkStream(filename, _engine);
}
+ _stereo = audioStream->isStereo();
if (_loop) {
Audio::LoopingAudioStream *loopingAudioStream = new Audio::LoopingAudioStream(audioStream, 0, DisposeAfterUse::YES);
@@ -76,10 +78,81 @@ MusicNode::~MusicNode() {
debug(1, "MusicNode: %d destroyed\n", _key);
}
+void MusicNode::setPanTrack(int16 pos) {
+ if (!_stereo) {
+ _pantrack = true;
+ _pantrack_X = pos;
+ setVolume(_volume);
+ }
+}
+
+void MusicNode::unsetPanTrack() {
+ _pantrack = false;
+ setVolume(_volume);
+}
+
bool MusicNode::process(uint32 deltaTimeInMillis) {
if (! _engine->_mixer->isSoundHandleActive(_handle))
return stop();
+ else {
+ uint8 _newvol = _volume;
+
+ if (_pantrack || _volume != _newvol)
+ setVolume(_newvol);
+ }
return false;
}
+void MusicNode::setVolume(uint8 new_volume) {
+ if (_pantrack) {
+ int cur_x = _engine->getScriptManager()->getStateValue(StateKey_ViewPos);
+ cur_x -= _pantrack_X;
+ int32 _width = _engine->getRenderManager()->getBkgSize().x;
+ if (cur_x < (-_width) / 2)
+ cur_x += _width;
+ else if (cur_x >= _width / 2)
+ cur_x -= _width;
+
+ float norm = (float)cur_x / ((float)_width / 2.0);
+ float lvl = fabs(norm);
+ if (lvl > 0.5)
+ lvl = (lvl - 0.5) * 1.7;
+ else
+ lvl = 1.0;
+
+ float bal = sin(-norm * 3.1415926) * 127.0;
+
+ if (_engine->_mixer->isSoundHandleActive(_handle)) {
+ _engine->_mixer->setChannelBalance(_handle, bal);
+ _engine->_mixer->setChannelVolume(_handle, new_volume * lvl);
+ }
+ } else {
+ if (_engine->_mixer->isSoundHandleActive(_handle)) {
+ _engine->_mixer->setChannelBalance(_handle, 0);
+ _engine->_mixer->setChannelVolume(_handle, new_volume);
+ }
+ }
+
+ _volume = new_volume;
+}
+
+PanTrackNode::PanTrackNode(ZVision *engine, uint32 key, uint32 slot, int16 pos)
+ : SideFX(engine, key, SIDEFX_PANTRACK) {
+ _slot = slot;
+
+ SideFX *fx = _engine->getScriptManager()->getSideFX(slot);
+ if (fx && fx->getType() == SIDEFX_AUDIO) {
+ MusicNode *mus = (MusicNode *)fx;
+ mus->setPanTrack(pos);
+ }
+}
+
+PanTrackNode::~PanTrackNode() {
+ SideFX *fx = _engine->getScriptManager()->getSideFX(_slot);
+ if (fx && fx->getType() == SIDEFX_AUDIO) {
+ MusicNode *mus = (MusicNode *)fx;
+ mus->unsetPanTrack();
+ }
+}
+
} // End of namespace ZVision
diff --git a/engines/zvision/music_node.h b/engines/zvision/music_node.h
index 973feaf175..9ccf9ab657 100644
--- a/engines/zvision/music_node.h
+++ b/engines/zvision/music_node.h
@@ -45,20 +45,33 @@ public:
*/
bool process(uint32 deltaTimeInMillis);
+ void setVolume(uint8 volume);
+
+ void setPanTrack(int16 pos);
+ void unsetPanTrack();
private:
int32 _timeLeft;
bool _pantrack;
int32 _pantrack_X;
int32 _attenuate;
- int8 _volume;
- int32 _id;
+ uint8 _volume;
bool _loop;
bool _crossfade;
- int32 _crossfade_delta;
+ uint8 _crossfade_target;
int32 _crossfade_time;
+ bool _stereo;
Audio::SoundHandle _handle;
};
+class PanTrackNode : public SideFX {
+public:
+ PanTrackNode(ZVision *engine, uint32 key, uint32 slot, int16 pos);
+ ~PanTrackNode();
+
+private:
+ uint32 _slot;
+};
+
} // End of namespace ZVision
#endif
diff --git a/engines/zvision/scr_file_handling.cpp b/engines/zvision/scr_file_handling.cpp
index 4f1c3631bd..83f25a8954 100644
--- a/engines/zvision/scr_file_handling.cpp
+++ b/engines/zvision/scr_file_handling.cpp
@@ -248,7 +248,7 @@ void ScriptManager::parseResults(Common::SeekableReadStream &stream, Common::Lis
} else if (act.matchString("music", true)) {
actionList.push_back(new ActionMusic(_engine, slot, args, false));
} else if (act.matchString("pan_track", true)) {
- // TODO: Implement ActionPanTrack
+ actionList.push_back(new ActionPanTrack(_engine, slot, args));
} else if (act.matchString("playpreload", true)) {
actionList.push_back(new ActionPlayPreloadAnimation(_engine, slot, args));
} else if (act.matchString("preferences", true)) {