296 lines
8.2 KiB
C++
296 lines
8.2 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 3 of the License, or
|
|
* 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, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
#include "audio/decoders/vorbis.h"
|
|
#include "common/util.h"
|
|
#include "ags/plugins/ags_waves/ags_waves.h"
|
|
#include "ags/shared/util/stdio_compat.h"
|
|
#include "ags/ags.h"
|
|
|
|
namespace AGS3 {
|
|
namespace Plugins {
|
|
namespace AGSWaves {
|
|
|
|
//const float PI = 3.14159265f;
|
|
|
|
void AGSWaves::SFX_Play(ScriptMethodParams ¶ms) {
|
|
PARAMS2(int, sfxNum, int, repeat);
|
|
|
|
SoundEffect &effect = SFX[sfxNum];
|
|
if (_mixer->isSoundHandleActive(effect._soundHandle)) {
|
|
if (effect._allow == 1) {
|
|
// In this case we should start the sound on a new channel, not stopping
|
|
// the one currently playing.
|
|
warning("TODO: play overlapping sound with SFX_Play");
|
|
}
|
|
return;
|
|
}
|
|
_mixer->stopHandle(effect._soundHandle);
|
|
|
|
Common::ArchiveMemberPtr member = getFile(Common::String::format("sounds/sound%d.sfx", sfxNum).c_str());
|
|
|
|
Audio::AudioStream *sound = loadOGG(member);
|
|
|
|
if (sound != nullptr) {
|
|
effect._volume = 255;
|
|
|
|
playStream(Audio::Mixer::kSFXSoundType, &effect._soundHandle, sound, repeat);
|
|
|
|
if (OGG_Filter && effect._filter && effect._volume > 1) {
|
|
warning("TODO: Mix_RegisterEffect(grabChan, LPEffect, NULL, NULL);");
|
|
}
|
|
|
|
effect._repeat = repeat;
|
|
} else {
|
|
debug(0, "AGSWaves::SFX_Play couldn't load sfx %d", sfxNum);
|
|
}
|
|
}
|
|
|
|
void AGSWaves::SFX_SetVolume(ScriptMethodParams ¶ms) {
|
|
PARAMS2(int, sfxNum, int, volume);
|
|
|
|
SoundEffect &effect = SFX[sfxNum];
|
|
_mixer->setChannelVolume(effect._soundHandle, volume);
|
|
effect._volume = volume;
|
|
}
|
|
|
|
void AGSWaves::SFX_GetVolume(ScriptMethodParams ¶ms) {
|
|
PARAMS1(int, sfxNum);
|
|
|
|
SoundEffect &effect = SFX[sfxNum];
|
|
params._result = _mixer->getChannelVolume(effect._soundHandle);
|
|
}
|
|
|
|
void AGSWaves::Music_Play(ScriptMethodParams ¶ms) {
|
|
PARAMS6(int, MFX, int, repeat, int, fadeinMS, int, fadeoutMS, int, Position, bool, fixclick);
|
|
MusicPlay(MFX, repeat, fadeinMS, fadeoutMS, Position, false, fixclick);
|
|
}
|
|
|
|
void AGSWaves::Music_SetVolume(ScriptMethodParams ¶ms) {
|
|
PARAMS1(int, volume);
|
|
_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, volume);
|
|
}
|
|
|
|
void AGSWaves::Music_GetVolume(ScriptMethodParams ¶ms) {
|
|
params._result = _mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType);
|
|
}
|
|
|
|
void AGSWaves::SFX_Stop(ScriptMethodParams ¶ms) {
|
|
PARAMS1(int, sfxNum); //, int, fademsOUT);
|
|
StopSFX(sfxNum);
|
|
}
|
|
|
|
void AGSWaves::SFX_SetPosition(ScriptMethodParams ¶ms) {
|
|
#if 0
|
|
PARAMS4(int, sfxNum, int, xS, int, yS, int, intensity);
|
|
|
|
SoundEffect &effect = SFX[sfxNum];
|
|
|
|
if (_mixer->isSoundHandleActive(effect._soundHandle)) {
|
|
int angle = 0;
|
|
int dist = 0;
|
|
|
|
if (xS != 0 && yS != 0) {
|
|
int pid = _engine->GetPlayerCharacter();
|
|
playerCharacter = _engine->GetCharacter(pid);
|
|
|
|
int x1 = Character_GetX((intptr_t)playerCharacter);
|
|
int y1 = Character_GetY((intptr_t)playerCharacter);
|
|
|
|
int x2 = xS;
|
|
int y2 = yS;
|
|
|
|
int defx = (x1 - x2) * (x1 - x2);
|
|
int defy = (y1 - y2) * (y1 - y2);
|
|
|
|
float SquareRoot = sqrt(float(defx + defy));
|
|
dist = int(SquareRoot) - intensity;
|
|
if (dist > 255) dist = 255;
|
|
if (dist < 0) dist = 0;
|
|
|
|
float xDiff = float(x2 - x1);
|
|
float yDiff = float(y2 - y1);
|
|
float at2 = atan2(yDiff, xDiff);
|
|
|
|
float angles = (at2 * 360.0 / PI);
|
|
angle = int(angles);//%360;
|
|
}
|
|
|
|
// TODO: Change Mix_SetPosition to ScummVM equivalent
|
|
//Mix_SetPosition(id, angle, dist);
|
|
(void)angle;
|
|
(void)dist;
|
|
}
|
|
#endif
|
|
debug(0, "TODO: SFX_Setposition positional sound not yet implemented");
|
|
}
|
|
|
|
void AGSWaves::SFX_SetGlobalVolume(ScriptMethodParams ¶ms) {
|
|
PARAMS1(int, volume);
|
|
_mixer->setVolumeForSoundType(Audio::Mixer::kPlainSoundType, volume);
|
|
}
|
|
|
|
void AGSWaves::Load_SFX(ScriptMethodParams ¶ms) {
|
|
// PARAMS1(int, sfxNum);
|
|
// LoadSFX(sfxNum);
|
|
}
|
|
|
|
void AGSWaves::Audio_Apply_Filter(ScriptMethodParams ¶ms) {
|
|
PARAMS1(int, Frequency);
|
|
|
|
GlitchFix();
|
|
ApplyFilter(Frequency);
|
|
}
|
|
|
|
void AGSWaves::Audio_Remove_Filter(ScriptMethodParams ¶ms) {
|
|
}
|
|
|
|
void AGSWaves::SFX_AllowOverlap(ScriptMethodParams ¶ms) {
|
|
PARAMS2(int, sfxNum, int, allow);
|
|
SFX[sfxNum]._allow = allow;
|
|
}
|
|
|
|
void AGSWaves::SFX_Filter(ScriptMethodParams ¶ms) {
|
|
PARAMS2(int, sfxNum, int, enable);
|
|
|
|
// THIS ENABLES/DISABLES the SFX LOW PASS FILTER,
|
|
// I think by default all sound effects are affected by low pass, but there are some that i've manually disabled from being affected by it with this command
|
|
SFX[sfxNum]._filter = enable;
|
|
}
|
|
|
|
Audio::AudioStream *AGSWaves::loadOGG(const Common::ArchiveMemberPtr &member) {
|
|
#ifdef USE_VORBIS
|
|
if (member) {
|
|
Audio::AudioStream *stream = Audio::makeVorbisStream(member->createReadStream(), DisposeAfterUse::YES);
|
|
return stream;
|
|
}
|
|
#endif
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
void AGSWaves::playStream(Audio::Mixer::SoundType type, Audio::SoundHandle *handle, Audio::AudioStream *stream, int repeat) {
|
|
if (!handle || !stream)
|
|
return;
|
|
|
|
if (repeat != 0) {
|
|
Audio::SeekableAudioStream *sas =
|
|
dynamic_cast<Audio::SeekableAudioStream *>(stream);
|
|
assert(sas);
|
|
|
|
// -1 for infinite, >0 number of successive repeats
|
|
Audio::LoopingAudioStream *las =
|
|
new Audio::LoopingAudioStream(sas, repeat + 1);
|
|
_mixer->playStream(type, handle, las);
|
|
} else {
|
|
_mixer->playStream(type, handle, stream);
|
|
}
|
|
}
|
|
|
|
void AGSWaves::StopSFX(int sfxNum) {
|
|
SoundEffect &effect = SFX[sfxNum];
|
|
_mixer->stopHandle(effect._soundHandle);
|
|
effect._playing = 0;
|
|
effect._repeat = 0;
|
|
effect._channel = -2;
|
|
}
|
|
|
|
void AGSWaves::stopAllSounds() {
|
|
for (int i = 0; i < 500; ++i)
|
|
StopSFX(i);
|
|
|
|
_mixer->stopHandle(MFXStream._soundHandle);
|
|
}
|
|
|
|
void AGSWaves::GlitchFix() {
|
|
// TODO: Implementation
|
|
}
|
|
|
|
void AGSWaves::ApplyFilter(int setFrequency) {
|
|
// THIS TURNS ON THE LOW PASS FILTER
|
|
OGG_Filter = true;
|
|
GeneralAudio.FilterFrequency = setFrequency;
|
|
SetFilterFrequency(setFrequency);
|
|
}
|
|
|
|
void AGSWaves::SetFilterFrequency(int setFrequency) {
|
|
// TODO: Implementation
|
|
}
|
|
|
|
void AGSWaves::MusicPlay(int MusicToPlay, int repeat, int fadeinMS, int fadeoutMS, int pos, bool forceplay, bool fixclick) {
|
|
if (GeneralAudio.Disabled) {
|
|
return;
|
|
}
|
|
|
|
// Stop any previous music
|
|
_mixer->stopHandle(MFXStream._soundHandle);
|
|
|
|
// Load OGG file for music
|
|
Common::ArchiveMemberPtr member = getFile(Common::String::format("music/music%d.mfx", MusicToPlay).c_str());
|
|
Audio::AudioStream *musicStream = loadOGG(member);
|
|
if (!musicStream)
|
|
return;
|
|
|
|
bool samefile = currentMusic != MusicToPlay;
|
|
if (forceplay)
|
|
samefile = true;
|
|
|
|
if (samefile) {
|
|
currentMusicRepeat = repeat;
|
|
currentMusicFadein = fadeinMS;
|
|
currentMusic = MusicToPlay;
|
|
|
|
if (!MFXStream.Switch) {
|
|
MFXStream.Channel = 0;
|
|
|
|
playStream(Audio::Mixer::kMusicSoundType,
|
|
&MFXStream._soundHandle, musicStream, repeat);
|
|
|
|
MFXStream.ID = MusicToPlay;
|
|
MFXStream.FadeTime = (fadeinMS / 1000) * 40;
|
|
MFXStream.FadeRate = (float)_mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType)
|
|
/ (float)MFXStream.FadeTime;
|
|
MFXStream.FadeVolume = 0.0;
|
|
MFXStream.HaltedZero = false;
|
|
//MusicVolCanBeAdjusted=true;
|
|
} else {
|
|
MFXStream.HaltedOne = false;
|
|
MFXStream.Channel = 1;
|
|
|
|
playStream(Audio::Mixer::kMusicSoundType,
|
|
&MFXStream._soundHandle, musicStream, repeat);
|
|
|
|
MFXStream.ID = MusicToPlay;
|
|
MFXStream.FadeTime = (fadeoutMS / 1000) * 40;
|
|
MFXStream.FadeVolume = 0.0;//float(MusicGetVolume());
|
|
MFXStream.FadeRate = (float)_mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType)
|
|
/ (float)MFXStream.FadeTime;
|
|
//MusicVolCanBeAdjusted=false;
|
|
}
|
|
|
|
MFXStream.Switch = !MFXStream.Switch;
|
|
}
|
|
}
|
|
|
|
} // namespace AGSWaves
|
|
} // namespace Plugins
|
|
} // namespace AGS3
|