The open source repository for the action RPG game in development by Sig Productions titled 'Adventures in Lestoria'!
https://forums.lestoria.net
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
236 lines
7.3 KiB
236 lines
7.3 KiB
#pragma region License
|
|
/*
|
|
License (OLC-3)
|
|
~~~~~~~~~~~~~~~
|
|
|
|
Copyright 2024 Joshua Sigona <sigonasr2@gmail.com>
|
|
|
|
Redistribution and use in source and binary forms, with or without modification,
|
|
are permitted provided that the following conditions are met:
|
|
|
|
1. Redistributions or derivations of source code must retain the above copyright
|
|
notice, this list of conditions and the following disclaimer.
|
|
|
|
2. Redistributions or derivative works in binary form must reproduce the above
|
|
copyright notice. This list of conditions and the following disclaimer must be
|
|
reproduced in the documentation and/or other materials provided with the distribution.
|
|
|
|
3. Neither the name of the copyright holder nor the names of its contributors may
|
|
be used to endorse or promote products derived from this software without specific
|
|
prior written permission.
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
|
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
|
SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
|
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
|
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
|
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
SUCH DAMAGE.
|
|
|
|
Portions of this software are copyright © 2023 The FreeType
|
|
Project (www.freetype.org). Please see LICENSE_FT.txt for more information.
|
|
All rights reserved.
|
|
*/
|
|
#pragma endregion
|
|
#include "Audio.h"
|
|
#include "AdventuresInLestoria.h"
|
|
#include "DEFINES.h"
|
|
|
|
INCLUDE_game
|
|
INCLUDE_DATA
|
|
|
|
float Audio::defaultFadeTime;
|
|
|
|
void Audio::Initialize(){
|
|
Engine().SetBackgroundPlay(true);
|
|
Self().events.insert("Default Volume");
|
|
for(auto&[key,data]:DATA["Events"]){
|
|
Self().events.insert(key);
|
|
}
|
|
for(auto&[songFileName,size]:DATA["BGM"]){
|
|
auto&data=DATA["BGM"][songFileName];
|
|
if(songFileName!="Default Fade Time"){
|
|
int channelCounter=0;
|
|
|
|
BGM&bgm=Self().bgm[songFileName];
|
|
|
|
bgm.SetFileName(songFileName);
|
|
bgm.SetName(data["Track Name"].GetString());
|
|
|
|
while(data.HasProperty(std::format("channel[{}]",channelCounter))){
|
|
std::string channelName=data[std::format("channel[{}]",channelCounter)].GetString();
|
|
if(!std::filesystem::exists("bgm_directory"_S+channelName))ERR(std::format("WARNING! Could not load file {} for track {}",channelName,songFileName));
|
|
bgm.AddChannel(channelName);
|
|
channelCounter++;
|
|
}
|
|
|
|
if(!data.HasProperty("Default Volume"))ERR(std::format("WARNING! Track {} does not have a Default Volume parameter!",bgm.GetName()));
|
|
if(data["Default Volume"].GetValueCount()!=bgm.GetChannelCount())ERR(std::format("WARNING! Default Volume parameters do not match channel count. {} != {}",data["Default Volume"].GetValueCount(),bgm.GetChannelCount()));
|
|
|
|
VolumeList volumes;
|
|
for(int i=0;i<data["Default Volume"].GetValueCount();i++){
|
|
volumes.push_back(data["Default Volume"].GetInt(i)/100.f);
|
|
}
|
|
bgm.AddEventVolumes("Default Volume",volumes);
|
|
|
|
if(data.HasProperty("Fade Time")){
|
|
bgm.SetFadeTime(data["Fade Time"].GetReal());
|
|
}else{
|
|
bgm.SetFadeTime(defaultFadeTime);
|
|
}
|
|
|
|
|
|
if(data.HasProperty("Events")){
|
|
for(auto&[eventName,size]:DATA["Events"]){
|
|
auto&eventData=data["Events"][eventName];
|
|
if(eventData.GetValueCount()!=bgm.GetChannelCount())ERR(std::format("WARNING! {} parameters do not match channel count. {} != {}",eventName,eventData.GetValueCount(),bgm.GetChannelCount()));
|
|
VolumeList volumes;
|
|
for(int i=0;i<eventData.GetValueCount();i++){
|
|
volumes.push_back(eventData.GetInt(i)/100.f);
|
|
}
|
|
bgm.AddEventVolumes(eventName,volumes);
|
|
}
|
|
}
|
|
}else{
|
|
defaultFadeTime=data.GetReal();
|
|
}
|
|
}
|
|
}
|
|
|
|
MiniAudio&Audio::Engine(){
|
|
return game->audioEngine.audioEngine;
|
|
}
|
|
void Audio::Play(const std::string_view sound){
|
|
Engine().Play(std::string(sound));
|
|
};
|
|
void Audio::PlayBGM(const std::string_view sound,const bool loop){
|
|
BGM&track=Self().bgm[std::string(sound)];
|
|
StopBGM(); //Stop any currently playing track.
|
|
track.Load();
|
|
for(int channelListIndex=0;int trackID:track.GetChannelIDs()){
|
|
Engine().SetVolume(trackID,track.GetVolume(Self().currentAudioEvent,channelListIndex));
|
|
Engine().Play(trackID,loop);
|
|
channelListIndex++;
|
|
}
|
|
};
|
|
|
|
void Audio::StopBGM(){
|
|
if(Self().BGMIsPlaying()){
|
|
BGM¤tTrack=Self().bgm[Self().currentBGM];
|
|
for(int trackID:currentTrack.GetChannelIDs()){
|
|
Engine().Stop(trackID);
|
|
}
|
|
}
|
|
}
|
|
|
|
const bool Audio::BGMIsPlaying(){
|
|
return Self().currentBGM.length()>0;
|
|
}
|
|
|
|
const Volume&Audio::BGM::GetVolume(const Event&eventName,const ChannelID&id)const{
|
|
return eventVolumes.GetVolumes(eventName).at(id);
|
|
}
|
|
|
|
void Audio::BGM::Load(){
|
|
BGM&bgm=Self().bgm[Self().currentBGM];
|
|
if(Self().BGMIsPlaying()){
|
|
bgm.Unload();
|
|
}
|
|
Self().currentBGM=songFileName;
|
|
BGM&newBgm=Self().bgm[songFileName];
|
|
if(newBgm.channels.size()>0)ERR(std::format("WARNING! The size of the channels list is greater than zero! Size: {}",bgm.channels.size()));
|
|
for(const ChannelName&channel:newBgm.GetChannels()){
|
|
ChannelID soundID=Engine().LoadSound("bgm_directory"_S+channel);
|
|
newBgm.channels.push_back(soundID);
|
|
}
|
|
}
|
|
|
|
void Audio::BGM::Unload(){
|
|
BGM&bgm=Self().bgm[Self().currentBGM];
|
|
for(const ChannelID&id:channels){
|
|
Engine().UnloadSound(id);
|
|
}
|
|
channels.clear();
|
|
Self().currentBGM="";
|
|
}
|
|
|
|
const ChannelID&Audio::BGM::GetChannelID(const int index){
|
|
return channels[index];
|
|
}
|
|
|
|
const ChannelIDList&Audio::BGM::GetChannelIDs()const{
|
|
return channels;
|
|
}
|
|
|
|
const std::vector<ChannelName>&Audio::BGM::GetChannels()const{
|
|
return channelNames;
|
|
}
|
|
|
|
void Audio::BGM::SetFadeTime(const float fadeTime){
|
|
this->fadeTime=fadeTime;
|
|
}
|
|
|
|
void Audio::BGM::AddEventVolumes(const Event&eventName,const VolumeList&volumes){
|
|
eventVolumes.AddEventInfo(eventName,volumes);
|
|
}
|
|
|
|
const size_t Audio::BGM::GetChannelCount()const{
|
|
return channelNames.size();
|
|
}
|
|
|
|
const SongName&Audio::BGM::GetName()const{
|
|
return songName;
|
|
}
|
|
|
|
void Audio::BGM::SetName(std::string_view name){
|
|
songName=name;
|
|
}
|
|
|
|
void Audio::BGM::SetFileName(std::string_view name){
|
|
songFileName=name;
|
|
}
|
|
|
|
void Audio::BGM::AddChannel(const ChannelName&name){
|
|
channelNames.push_back(name);
|
|
}
|
|
|
|
const VolumeList&Audio::EventData::GetVolumes(const Event&event)const{
|
|
if(eventInfo.find(event)!=eventInfo.end())return eventInfo.at(event);
|
|
return eventInfo.at("Default Volume");
|
|
}
|
|
|
|
void Audio::EventData::AddEventInfo(const Event&eventName,const VolumeList&volumes){
|
|
eventInfo[eventName]=volumes;
|
|
}
|
|
|
|
Audio&Audio::Self(){
|
|
return game->audioEngine;
|
|
}
|
|
|
|
const Event&Audio::GetAudioEvent(){
|
|
return Self().currentAudioEvent;
|
|
}
|
|
void Audio::SetAudioEvent(const Event&eventName){
|
|
if(Self().events.find(eventName)==Self().events.end())ERR(std::format("WARNING! cannot find event {}",eventName));
|
|
|
|
Self().currentAudioEvent=eventName;
|
|
|
|
if(Audio::BGMIsPlaying()){
|
|
BGM¤tBgm=Self().bgm[Self().currentBGM];
|
|
for(int currentTrackIndex=0;int trackID:currentBgm.GetChannelIDs()){
|
|
Engine().SetVolume(trackID,currentBgm.GetVolume(eventName,currentTrackIndex));
|
|
currentTrackIndex++;
|
|
}
|
|
}
|
|
}
|
|
|
|
std::string operator""_SFX(const char*key,size_t length){
|
|
return "sfx_directory"_S+std::string(key,length);
|
|
}
|
|
|
|
const SongName&Audio::GetTrackName(){
|
|
return Self().currentBGM;
|
|
} |