mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-17 07:07:10 +00:00
177 lines
4.8 KiB
C++
177 lines
4.8 KiB
C++
/* ScummVM - Graphic Adventure Engine
|
|
*
|
|
* ScummVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
* file distributed with this source distribution.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* 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.
|
|
*
|
|
*/
|
|
|
|
#include "common/scummsys.h"
|
|
|
|
#include "zvision/music_node.h"
|
|
|
|
#include "zvision/zvision.h"
|
|
#include "zvision/script_manager.h"
|
|
#include "zvision/render_manager.h"
|
|
#include "zvision/zork_raw.h"
|
|
|
|
#include "common/stream.h"
|
|
#include "common/file.h"
|
|
#include "audio/decoders/wave.h"
|
|
|
|
|
|
namespace ZVision {
|
|
|
|
MusicNode::MusicNode(ZVision *engine, uint32 key, Common::String &filename, bool loop, int8 volume)
|
|
: SideFX(engine, key, SIDEFX_AUDIO) {
|
|
_loop = loop;
|
|
_volume = volume;
|
|
_crossfade = false;
|
|
_crossfade_target = 0;
|
|
_crossfade_time = 0;
|
|
_attenuate = 0;
|
|
_pantrack = false;
|
|
_pantrack_X = 0;
|
|
|
|
Audio::RewindableAudioStream *audioStream;
|
|
|
|
if (filename.contains(".wav")) {
|
|
Common::File *file = new Common::File();
|
|
if (_engine->getSearchManager()->openFile(*file, filename)) {
|
|
audioStream = Audio::makeWAVStream(file, DisposeAfterUse::YES);
|
|
}
|
|
} else {
|
|
audioStream = makeRawZorkStream(filename, _engine);
|
|
}
|
|
|
|
_stereo = audioStream->isStereo();
|
|
|
|
if (_loop) {
|
|
Audio::LoopingAudioStream *loopingAudioStream = new Audio::LoopingAudioStream(audioStream, 0, DisposeAfterUse::YES);
|
|
_engine->_mixer->playStream(Audio::Mixer::kPlainSoundType, &_handle, loopingAudioStream, -1, _volume);
|
|
} else {
|
|
_engine->_mixer->playStream(Audio::Mixer::kPlainSoundType, &_handle, audioStream, -1, _volume);
|
|
}
|
|
|
|
if (_key != StateKey_NotSet)
|
|
_engine->getScriptManager()->setStateValue(_key, 1);
|
|
}
|
|
|
|
MusicNode::~MusicNode() {
|
|
_engine->_mixer->stopHandle(_handle);
|
|
if (_key != StateKey_NotSet)
|
|
_engine->getScriptManager()->setStateValue(_key, 2);
|
|
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);
|
|
}
|
|
|
|
void MusicNode::setFade(int32 time, uint8 target) {
|
|
_crossfade_target = target;
|
|
_crossfade_time = time;
|
|
_crossfade = true;
|
|
}
|
|
|
|
bool MusicNode::process(uint32 deltaTimeInMillis) {
|
|
if (! _engine->_mixer->isSoundHandleActive(_handle))
|
|
return stop();
|
|
else {
|
|
uint8 _newvol = _volume;
|
|
|
|
if (_crossfade) {
|
|
if (_crossfade_time > 0) {
|
|
if ((int32)deltaTimeInMillis > _crossfade_time)
|
|
deltaTimeInMillis = _crossfade_time;
|
|
_newvol += floor(((float)(_crossfade_target - _newvol) / (float)_crossfade_time)) * (float)deltaTimeInMillis;
|
|
_crossfade_time -= deltaTimeInMillis;
|
|
} else {
|
|
_crossfade = false;
|
|
_newvol = _crossfade_target;
|
|
}
|
|
}
|
|
|
|
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
|