Merge pull request 'BGMImpl' (#28) from BGMImpl into master

Reviewed-on: #28
pull/29/head
sigonasr2 11 months ago
commit e132eeab4e
  1. 13
      Adventures in Lestoria/AdventuresInLestoria.cpp
  2. 185
      Adventures in Lestoria/Audio.cpp
  3. 64
      Adventures in Lestoria/Audio.h
  4. 18
      Adventures in Lestoria/State_OverworldMap.cpp
  5. 6
      Adventures in Lestoria/TODO.txt
  6. 2
      Adventures in Lestoria/Version.h
  7. 60
      Adventures in Lestoria/assets/config/bgm/bgm.txt
  8. 4
      Adventures in Lestoria/assets/config/configuration.txt
  9. BIN
      Adventures in Lestoria/assets/music/foresty0.mp3
  10. BIN
      Adventures in Lestoria/assets/music/foresty0_alt.mp3

@ -137,8 +137,9 @@ AiL::AiL()
std::string ITEM_STATS_CONFIG = CONFIG_PATH + "item_stats_config"_S; std::string ITEM_STATS_CONFIG = CONFIG_PATH + "item_stats_config"_S;
utils::datafile::Read(DATA,ITEM_STATS_CONFIG); utils::datafile::Read(DATA,ITEM_STATS_CONFIG);
for(auto&[key,value]:DATA.GetProperty("ItemConfiguration").GetKeys()){ auto keys=DATA.GetProperty("ItemConfiguration");
std::string config = DATA["ItemConfiguration"][key].GetString(); for(auto&[key,value]:keys){
std::string config=DATA["ItemConfiguration"][key].GetString();
utils::datafile::Read(DATA,CONFIG_PATH + "item_directory"_S + config); utils::datafile::Read(DATA,CONFIG_PATH + "item_directory"_S + config);
} }
@ -150,6 +151,12 @@ AiL::AiL()
utils::datafile::Read(DATA,CONFIG_PATH + "class_directory"_S + cl + ".txt"); utils::datafile::Read(DATA,CONFIG_PATH + "class_directory"_S + cl + ".txt");
} }
std::string BGM_CONFIG = CONFIG_PATH + "bgm_config"_S;
utils::datafile::Read(DATA,BGM_CONFIG);
std::string BGM_EVENTS_CONFIG = CONFIG_PATH + "event_config"_S;
utils::datafile::Read(DATA,BGM_EVENTS_CONFIG);
utils::datafile::DEBUG_ACCESS_OPTIONS="debug_access_options"_I; utils::datafile::DEBUG_ACCESS_OPTIONS="debug_access_options"_I;
sAppName = "GAME_NAME"_S; sAppName = "GAME_NAME"_S;
@ -236,6 +243,8 @@ bool AiL::OnUserCreate(){
Stats::InitializeDamageReductionTable(); Stats::InitializeDamageReductionTable();
Audio::Initialize();
utils::datafile::INITIAL_SETUP_COMPLETE=true; utils::datafile::INITIAL_SETUP_COMPLETE=true;
ValidateGameStatus(); //Checks to make sure everything has been initialized properly. ValidateGameStatus(); //Checks to make sure everything has been initialized properly.

@ -40,21 +40,192 @@ All rights reserved.
#include "DEFINES.h" #include "DEFINES.h"
INCLUDE_game INCLUDE_game
INCLUDE_DATA
float Audio::defaultFadeTime;
void Audio::Initialize(){
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(){ MiniAudio&Audio::Engine(){
return game->audioEngine.audioEngine; return game->audioEngine.audioEngine;
} }
void Audio::Play(const std::string_view sound){ void Audio::Play(const std::string_view sound){
Engine().Play(std::string(sound)); Engine().Play(std::string(sound));
}; };
void Audio::PlayBGM(const std::string_view sound,const bool loop=true){ void Audio::PlayBGM(const std::string_view sound,const bool loop){
if(Engine().LoadS) BGM&track=Self().bgm[std::string(sound)];
Engine().Play(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&currentTrack=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&currentBgm=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){ std::string operator""_SFX(const char*key,size_t length){
return "sfx_directory"_S+std::string(key,length); return "sfx_directory"_S+std::string(key,length);
}
std::string operator""_BGM(const char*key,size_t length){
return "bgm_directory"_S+std::string(key,length);
} }

@ -38,20 +38,66 @@ All rights reserved.
#pragma once #pragma once
#include "olcPGEX_MiniAudio.h" #include "olcPGEX_MiniAudio.h"
#include "config.h" #include "config.h"
#include <set>
using SongName=std::string;
using Event=std::string;
using ChannelName=std::string;
using ChannelID=int;
using ChannelIDList=std::vector<ChannelID>;
using Volume=float;
using VolumeList=std::vector<Volume>;
class Audio{ class Audio{
class BGM{
std::vector<int>channels;
public:
Load();
Unload();
};
MiniAudio audioEngine;
public: public:
static Audio&Self();
static MiniAudio&Engine(); static MiniAudio&Engine();
static void Initialize();
static void Play(const std::string_view sound); static void Play(const std::string_view sound);
//Play a BGM given a name found in bgm.txt configuration file.
static void PlayBGM(const std::string_view sound,const bool loop=true); static void PlayBGM(const std::string_view sound,const bool loop=true);
static void StopBGM();
static const Event&GetAudioEvent();
static void SetAudioEvent(const Event&eventName);
static const bool BGMIsPlaying();
private:
class EventData{
public:
void AddEventInfo(const Event&eventName,const VolumeList&volumes);
const VolumeList&GetVolumes(const Event&event)const;
private:
std::map<Event,VolumeList>eventInfo;
};
class BGM{
public:
void Load();
const size_t GetChannelCount()const;
const std::vector<ChannelName>&GetChannels()const;
const SongName&GetName()const;
const Volume&GetVolume(const Event&eventName,const ChannelID&id)const;
void SetName(std::string_view name);
void SetFileName(std::string_view name);
void AddChannel(const ChannelName&name);
void AddEventVolumes(const Event&eventName,const VolumeList&volumes);
void SetFadeTime(const float fadeTime);
const ChannelID&GetChannelID(const int index);
const ChannelIDList&GetChannelIDs()const;
private:
std::string songName; //Name of the track.
std::string songFileName; //Name of the key in bgm.
ChannelIDList channels;
std::vector<ChannelName>channelNames;
EventData eventVolumes;
float fadeTime="BGM.Default Fade Time"_F;
void Unload();
};
private:
MiniAudio audioEngine;
SongName currentBGM="";
std::map<SongName,BGM>bgm;
std::set<Event>events;
static float defaultFadeTime;
Event currentAudioEvent="Default Volume";
}; };
std::string operator""_SFX(const char*key,size_t length); std::string operator""_SFX(const char*key,size_t length);
std::string operator""_BGM(const char*key,size_t length);

@ -109,6 +109,24 @@ void State_OverworldMap::OnUserUpdate(AiL*game){
if(game->GetKey(K1).bPressed){ if(game->GetKey(K1).bPressed){
Audio::Play("sfx100v2_loop_water_01.mp3"_SFX); Audio::Play("sfx100v2_loop_water_01.mp3"_SFX);
} }
if(game->GetKey(F1).bPressed){
Audio::PlayBGM("foresty1_1");
}else
if(game->GetKey(F2).bPressed){
Audio::PlayBGM("foresty0");
}
if(game->GetKey(K2).bPressed){
Audio::SetAudioEvent("Default Volume");
}
if(game->GetKey(K3).bPressed){
Audio::SetAudioEvent("LowHealth");
}
if(game->GetKey(K4).bPressed){
Audio::SetAudioEvent("InCombat");
}
if(game->GetKey(K5).bPressed){
Audio::SetAudioEvent("Underwater");
}
#pragma region Handle Connection Point Clicking and Movement #pragma region Handle Connection Point Clicking and Movement
for(ConnectionPoint&cp:connections){ for(ConnectionPoint&cp:connections){

@ -18,7 +18,7 @@ Settings Menu
-Upon pressing a key, check if the key is bound to another option, if so, -Upon pressing a key, check if the key is bound to another option, if so,
remove that bind from the list. Up to two keys may be binded per action. remove that bind from the list. Up to two keys may be binded per action.
-We have to save keybinds to the save file. -We have to save keybinds to the save file.
-Smooth Movement
January 31st January 31st
============ ============
@ -41,4 +41,6 @@ Story proofreading/correcting/storyboarding
- Loading Screen - Loading Screen
- Title Screen setpieces - Title Screen setpieces
- Export/Import Save Files Online/Offline - Export/Import Save Files Online/Offline
- Consider controls for fine-tuning music and how they sound during events.

@ -39,7 +39,7 @@ All rights reserved.
#define VERSION_MAJOR 0 #define VERSION_MAJOR 0
#define VERSION_MINOR 2 #define VERSION_MINOR 2
#define VERSION_PATCH 1 #define VERSION_PATCH 1
#define VERSION_BUILD 5353 #define VERSION_BUILD 5379
#define stringify(a) stringify_(a) #define stringify(a) stringify_(a)
#define stringify_(a) #a #define stringify_(a) #a

@ -1,25 +1,51 @@
#Song title followed by filenames for individual parts BGM
foresty1_1
{ {
# High Default Fade Time = 1.0
channel[0]=foresty1_1_1.mp3
# Low
channel[1]=foresty1_1_2.mp3
# Underwater High #Song title followed by filenames for individual parts
channel[2]=foresty1_1_alt1.mp3 foresty1_1
# Underwater Low {
channel[3]=foresty1_1_alt2.mp3 Track Name = Foresty
# High
channel[0]=foresty1_1_1.mp3
# Low
channel[1]=foresty1_1_2.mp3
Default Volume = 70%,50%,0%,0% # Underwater High
channel[2]=foresty1_1_alt1.mp3
# Underwater Low
channel[3]=foresty1_1_alt2.mp3
# Transition time between one phase to the next. Default Volume = 70%,50%,0%,0%
Fade Speed = 2.0
Events # Transition time between one phase to the next.
Fade Time = 2.0
Events
{
LowHealth = 50%,60%,20%,20%
InCombat = 90%,100%,0%,0%
Underwater = 0%,0%,100%,100%
}
}
foresty0
{ {
LowHealth = 50%,60%,20%,20% Track Name = Foresty Preview
InCombat = 90%,100%,0%,0%
Underwater = 0%,0%,100%,100% channel[0]=foresty0.mp3
channel[1]=foresty0_alt.mp3
Default Volume = 70%,0%
# Transition time between one phase to the next.
Fade Time = 2.0
Events
{
LowHealth = 50%,20%
InCombat = 100%,0%
Underwater = 0%,100%
}
} }
} }

@ -66,10 +66,10 @@ sfx_directory = assets/sounds/
bgm_directory = assets/music/ bgm_directory = assets/music/
# Path to bgm configuration # Path to bgm configuration
bgm_config = bgm.txt bgm_config = bgm/bgm.txt
# Path to bgm events configuration # Path to bgm events configuration
event_config = events.txt event_config = bgm/events.txt
# Path to character images # Path to character images
character_image_location = characters/ character_image_location = characters/

Loading…
Cancel
Save