diff --git a/Adventures in Lestoria/AdventuresInLestoria.cpp b/Adventures in Lestoria/AdventuresInLestoria.cpp index 554d86ed..6d13e98c 100644 --- a/Adventures in Lestoria/AdventuresInLestoria.cpp +++ b/Adventures in Lestoria/AdventuresInLestoria.cpp @@ -4447,11 +4447,8 @@ void AiL::GlobalGameUpdates(){ Audio::Engine().SetVolume(GetPlayer()->cooldownSoundInstance,Audio::GetCalculatedSFXVolume("Audio.Casting Sound Volume"_F/100.f)); } - if(!GamePaused()){ - GameState::STATE->OnUserUpdate(this); - }else{ - ClearTimedOutGarbage(); - } + if(!GamePaused())GameState::STATE->OnUserUpdate(this); + else ClearTimedOutGarbage(); } diff --git a/Adventures in Lestoria/AdventuresInLestoria.h b/Adventures in Lestoria/AdventuresInLestoria.h index 0562ff6e..5ab777b4 100644 --- a/Adventures in Lestoria/AdventuresInLestoria.h +++ b/Adventures in Lestoria/AdventuresInLestoria.h @@ -95,6 +95,7 @@ class AiL : public olc::PixelGameEngine friend class sig::Animation; friend class Audio; friend class Minimap; + friend class MiniAudio; std::unique_ptrplayer; SplashScreen splash; public: diff --git a/Adventures in Lestoria/Audio.cpp b/Adventures in Lestoria/Audio.cpp index bad98ab5..5c0ebde0 100644 --- a/Adventures in Lestoria/Audio.cpp +++ b/Adventures in Lestoria/Audio.cpp @@ -71,6 +71,9 @@ void Audio::Initialize(){ 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)); + if(!game->gamepack.Loaded()&&"GENERATE_GAMEPACK"_B){ + game->gamepack.AddFile("bgm_directory"_S+channelName); + } bgm.AddChannel(channelName); channelCounter++; } @@ -121,8 +124,8 @@ MiniAudio&Audio::Engine(){ void Audio::Play(const std::string_view sound){ Engine().Play(std::string(sound)); }; -const size_t Audio::LoadAndPlay(const std::string_view sound,const bool loop){ - size_t soundID=Engine().LoadSound(std::string(sound)); +const size_t Audio::LoadAndPlaySFX(const std::string_view sound,const bool loop){ + size_t soundID=Engine().LoadSound(std::string(sound),MiniAudio::SFX); Engine().Play(soundID,loop); return soundID; }; diff --git a/Adventures in Lestoria/Audio.h b/Adventures in Lestoria/Audio.h index 2e0b9155..973fde8d 100644 --- a/Adventures in Lestoria/Audio.h +++ b/Adventures in Lestoria/Audio.h @@ -59,7 +59,7 @@ public: static void UpdateLoop(); static void Play(const std::string_view sound); [[nodiscard]] - static const size_t LoadAndPlay(const std::string_view sound,const bool loop=true); + static const size_t LoadAndPlaySFX(const std::string_view sound,const bool loop=true); //Prepares a BGM for loading. This means we call UpdateLoop() repeatedly until the loading of the music is complete. Names are found in bgm.txt configuration file. static void PrepareBGM(const std::string_view sound,const bool loop=true); //Play immediately a BGM given a name found in bgm.txt configuration file. diff --git a/Adventures in Lestoria/EnvironmentalAudio.cpp b/Adventures in Lestoria/EnvironmentalAudio.cpp index f5bb8ca0..6c5ad619 100644 --- a/Adventures in Lestoria/EnvironmentalAudio.cpp +++ b/Adventures in Lestoria/EnvironmentalAudio.cpp @@ -67,7 +67,7 @@ void EnvironmentalAudio::SetAudioName(const std::string_view audioName){ } void EnvironmentalAudio::Activate(){ if(activated)return; - soundInstance=Audio::LoadAndPlay(operator""_SFX(SOUND_DATA[audioName].file.c_str(),SOUND_DATA[audioName].file.length()),true); + soundInstance=Audio::LoadAndPlaySFX(operator""_SFX(SOUND_DATA[audioName].file.c_str(),SOUND_DATA[audioName].file.length()),true); activated=true; } void EnvironmentalAudio::Deactivate(){ diff --git a/Adventures in Lestoria/Player.cpp b/Adventures in Lestoria/Player.cpp index c160b191..ae52533e 100644 --- a/Adventures in Lestoria/Player.cpp +++ b/Adventures in Lestoria/Player.cpp @@ -115,7 +115,7 @@ void Player::Initialize(){ SetBaseStat("HP Recovery %",0); SetBaseStat("Damage Reduction",0); SetBaseStat("Attack Spd",0); - cooldownSoundInstance=Audio::Engine().LoadSound("spell_cast.ogg"_SFX); + cooldownSoundInstance=Audio::Engine().LoadSound("spell_cast.ogg"_SFX,MiniAudio::SFX); afterImage.Create(24,24); for(Pixel&p:afterImage.Sprite()->pColData){ p.a=0; diff --git a/Adventures in Lestoria/SoundEffect.cpp b/Adventures in Lestoria/SoundEffect.cpp index 44db324c..34363ecc 100644 --- a/Adventures in Lestoria/SoundEffect.cpp +++ b/Adventures in Lestoria/SoundEffect.cpp @@ -115,7 +115,7 @@ void SoundEffect::PlaySFX(const std::string&eventName,const vf2d&pos){ size_t SoundEffect::PlayLoopingSFX(const std::string&eventName,const vf2d&pos){ if(game->TestingModeEnabled()||eventName.length()==0)return 0U; const SoundEffect&sfx=GetRandomSFXFromFile(eventName); - const size_t id=Audio::Engine().LoadSound(operator""_SFX(sfx.filename.c_str(),sfx.filename.length())); + const size_t id=Audio::Engine().LoadSound(operator""_SFX(sfx.filename.c_str(),sfx.filename.length()),MiniAudio::SFX); RepeatingSoundEffect::playingSoundEffects.insert(id); Audio::Engine().Play(id,true); return id; diff --git a/Adventures in Lestoria/State_LevelComplete.cpp b/Adventures in Lestoria/State_LevelComplete.cpp index b6c8252d..a3ed8290 100644 --- a/Adventures in Lestoria/State_LevelComplete.cpp +++ b/Adventures in Lestoria/State_LevelComplete.cpp @@ -51,7 +51,7 @@ INCLUDE_game void State_LevelComplete::OnStateChange(GameState*prevState){ if(xpGainSound==std::numeric_limits::max()){ - xpGainSound=Audio::LoadAndPlay("xpgain.ogg"_SFX,true); + xpGainSound=Audio::LoadAndPlaySFX("xpgain.ogg"_SFX,true); Audio::Engine().SetVolume(xpGainSound,0.f); } if(Menu::IsMenuOpen()){ diff --git a/Adventures in Lestoria/TODO.txt b/Adventures in Lestoria/TODO.txt index 620c7276..fd565549 100644 --- a/Adventures in Lestoria/TODO.txt +++ b/Adventures in Lestoria/TODO.txt @@ -17,7 +17,10 @@ New Monster Sound Effects Add a Helper Function: Change proximity knockback checks regardless of player/monster friendliness to be a function call instead. -Add rectangular hitbox posssibility to the game for monsters. (specifically for use with pillars) +Add rectangular hitbox possibility to the game for monsters. (specifically for use with pillars) + +Fanfare -> Post boss song + DEMO ==== diff --git a/Adventures in Lestoria/Version.h b/Adventures in Lestoria/Version.h index 0d1f8c99..b24b55af 100644 --- a/Adventures in Lestoria/Version.h +++ b/Adventures in Lestoria/Version.h @@ -39,7 +39,7 @@ All rights reserved. #define VERSION_MAJOR 1 #define VERSION_MINOR 2 #define VERSION_PATCH 5 -#define VERSION_BUILD 11508 +#define VERSION_BUILD 11523 #define stringify(a) stringify_(a) #define stringify_(a) #a diff --git a/Adventures in Lestoria/assets/gamepack.pak b/Adventures in Lestoria/assets/gamepack.pak index 65411c7b..1e92678f 100644 Binary files a/Adventures in Lestoria/assets/gamepack.pak and b/Adventures in Lestoria/assets/gamepack.pak differ diff --git a/Adventures in Lestoria/olcPGEX_MiniAudio.h b/Adventures in Lestoria/olcPGEX_MiniAudio.h index 44608b93..9fe8cb95 100644 --- a/Adventures in Lestoria/olcPGEX_MiniAudio.h +++ b/Adventures in Lestoria/olcPGEX_MiniAudio.h @@ -81,8 +81,13 @@ namespace olc // set whether audio will continue playing when the app has lost focus void SetBackgroundPlay(bool state); - public: // LOADING ROUTINES - const size_t LoadSound(const std::string& path); + public: // LOADING ROUTINES + enum SoundEffectFlag{ + SFX, + BGM, + }; + const size_t LoadSound(const std::string& path,const SoundEffectFlag soundType=BGM); //Setting sound effect to true avoids loading it from a resource pack. + const size_t LoadResource(const std::string& path); void UnloadSound(const int id); public: // PLAYBACK CONTROLS @@ -153,6 +158,7 @@ namespace olc // this is where the sounds are kept std::vector vecSounds; std::vector vecOneOffSounds; + std::vector>vecResourcePackBuffers; }; /** @@ -200,6 +206,10 @@ namespace olc #ifdef OLC_PGEX_MINIAUDIO #undef OLC_PGEX_MINIAUDIO +#include "AdventuresInLestoria.h" +INCLUDE_game + + namespace olc { bool MiniAudio::backgroundPlay = false; @@ -290,28 +300,45 @@ namespace olc MiniAudio::backgroundPlay = state; } - const size_t MiniAudio::LoadSound(const std::string& path) + const size_t MiniAudio::LoadSound(const std::string& path,const SoundEffectFlag soundType) { // create the sound ma_sound* sound = new ma_sound(); + + // assume no empty slots... + size_t id = vecSounds.size(); - // load it from the file and decode it - if(ma_sound_init_from_file(&engine, path.c_str(), MA_SOUND_FLAG_DECODE | MA_SOUND_FLAG_ASYNC, NULL, NULL, sound) != MA_SUCCESS) - throw MiniAudioSoundException(); - + bool foundSound{false}; // attempt to re-use an empty slot for(int i = 0; i < vecSounds.size(); i++) { if(vecSounds.at(i) == nullptr) { vecSounds.at(i) = sound; - return i; + id=i; + foundSound=true; + break; } } - - // no empty slots, make more room! - const size_t id = vecSounds.size(); - vecSounds.push_back(sound); + + if(!foundSound)vecSounds.emplace_back(sound); + + if(soundType==BGM){ + ma_audio_buffer newBuffer{}; + ResourceBuffer rb{game->gamepack.GetFileBuffer(path)}; + short*decodedOggFile; + int numSamples{stb_vorbis_decode_memory((const unsigned char*)(rb.vMemory.data()),rb.vMemory.size(),(int*)(&device.playback.channels),(int*)(&device.sampleRate),&decodedOggFile)}; + if(numSamples==-1)ERR(std::format("Failed to decode Ogg Vorbis file! {}",path)); + LOG(std::format("Samples: {}, Channels: {}, Sample Rate: {}",numSamples,device.playback.channels,device.sampleRate)); + ma_audio_buffer_config config{ma_audio_buffer_config_init(device.playback.format,device.playback.channels,numSamples,decodedOggFile,nullptr)}; + if(ma_audio_buffer_init(&config,&newBuffer)!=MA_SUCCESS)ERR(std::format("WARNING! Failed to load audio buffer~! {}",path)); + if(ma_sound_init_from_data_source(&engine,&newBuffer,MA_SOUND_FLAG_DECODE|MA_SOUND_FLAG_ASYNC,nullptr,sound)!=MA_SUCCESS)ERR(std::format("Could not initialize sound! {}",path)); + vecResourcePackBuffers.emplace_back(std::pair{id,newBuffer}); + }else{ //Sound effects + // load it from the file and decode it + if(ma_sound_init_from_file(&engine, path.c_str(), MA_SOUND_FLAG_DECODE | MA_SOUND_FLAG_ASYNC, NULL, NULL, sound) != MA_SUCCESS) + throw MiniAudioSoundException(); + } return id; } @@ -321,6 +348,7 @@ namespace olc ma_sound_uninit(vecSounds.at(id)); delete vecSounds.at(id); vecSounds.at(id) = nullptr; + std::erase_if(vecResourcePackBuffers,[&id](const std::pair&bufferData){return id==bufferData.first;}); } void MiniAudio::Play(const int id, const bool loop) diff --git a/Adventures in Lestoria/pixelGameEngine.cpp b/Adventures in Lestoria/pixelGameEngine.cpp index 89336772..b27e7ce3 100644 --- a/Adventures in Lestoria/pixelGameEngine.cpp +++ b/Adventures in Lestoria/pixelGameEngine.cpp @@ -51,9 +51,9 @@ All rights reserved. #include "TMXParser.h" #define TSX_PARSER_SETUP #include "TSXParser.h" -#define OLC_PGEX_MINIAUDIO -#include "olcPGEX_MiniAudio.h" #define OLC_PGEX_SPLASHSCREEN #include "olcPGEX_SplashScreen.h" #define OLC_PGE_GAMEPAD -#include "olcPGEX_Gamepad.h" \ No newline at end of file +#include "olcPGEX_Gamepad.h" +#define OLC_PGEX_MINIAUDIO +#include "olcPGEX_MiniAudio.h" \ No newline at end of file diff --git a/x64/Release/Adventures in Lestoria.exe b/x64/Release/Adventures in Lestoria.exe index 9c205c98..c9e40011 100644 Binary files a/x64/Release/Adventures in Lestoria.exe and b/x64/Release/Adventures in Lestoria.exe differ