From 15ea25fe715f9610ab99cd1afc5a5ec55605d7b8 Mon Sep 17 00:00:00 2001
From: sigonasr2 <sigonasr2@gmail.com>
Date: Sat, 6 Jan 2024 04:26:01 -0600
Subject: [PATCH] Mitigate audio stuttering during emscripten audio file loads.
 Fix bug with remote loading not working when zero files are present.

---
 .../AdventuresInLestoria.cpp                  |  1 +
 Adventures in Lestoria/Audio.cpp              | 23 ++++++---
 Adventures in Lestoria/Audio.h                |  8 ++++
 Adventures in Lestoria/SaveFile.cpp           |  3 +-
 CMakeLists.txt                                |  4 ++
 .../7bc3a296f298485445fd98097212ba0/TODO.txt  | 47 -------------------
 6 files changed, 32 insertions(+), 54 deletions(-)
 delete mode 100644 enc_temp_folder/7bc3a296f298485445fd98097212ba0/TODO.txt

diff --git a/Adventures in Lestoria/AdventuresInLestoria.cpp b/Adventures in Lestoria/AdventuresInLestoria.cpp
index 19c8ffe3..14bb6c8c 100644
--- a/Adventures in Lestoria/AdventuresInLestoria.cpp	
+++ b/Adventures in Lestoria/AdventuresInLestoria.cpp	
@@ -260,6 +260,7 @@ bool AiL::OnUserUpdate(float fElapsedTime){
 	if(!GamePaused()){
 		GameState::STATE->OnUserUpdate(this);
 	}
+	Audio::Update();
 	RenderWorld(GetElapsedTime());
 	GameState::STATE->Draw(this);
 	RenderMenu();
diff --git a/Adventures in Lestoria/Audio.cpp b/Adventures in Lestoria/Audio.cpp
index 0e96de4b..7f113b92 100644
--- a/Adventures in Lestoria/Audio.cpp	
+++ b/Adventures in Lestoria/Audio.cpp	
@@ -109,12 +109,8 @@ void Audio::Play(const std::string_view 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++;
-	}
+	Self().playParams={std::string(sound),loop};
+	Self().playBGMWaitTime=0.7f;
 };
 
 void Audio::StopBGM(){
@@ -233,4 +229,19 @@ std::string operator""_SFX(const char*key,size_t length){
 
 const SongName&Audio::GetTrackName(){
 	return Self().currentBGM;
+}
+
+void Audio::Update(){
+	if(Self().playBGMWaitTime>0.f){
+		Self().playBGMWaitTime=std::max(Self().playBGMWaitTime-game->GetElapsedTime(),0.f);
+		if(Self().playBGMWaitTime==0.f){
+			BGM&track=Self().bgm[Self().playParams.sound];
+			track.Load();
+			for(int channelListIndex=0;int trackID:track.GetChannelIDs()){
+				Engine().SetVolume(trackID,track.GetVolume(Self().currentAudioEvent,channelListIndex));
+				Engine().Play(trackID,Self().playParams.loop);
+				channelListIndex++;
+			}
+		}
+	}
 }
\ No newline at end of file
diff --git a/Adventures in Lestoria/Audio.h b/Adventures in Lestoria/Audio.h
index 30b82b5e..2e481745 100644
--- a/Adventures in Lestoria/Audio.h	
+++ b/Adventures in Lestoria/Audio.h	
@@ -53,6 +53,7 @@ public:
 	static Audio&Self();
 	static MiniAudio&Engine();
 	static void Initialize();
+	static void Update();
 	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);
@@ -62,6 +63,10 @@ public:
 	static void SetAudioEvent(const Event&eventName);
 	static const bool BGMIsPlaying();
 private:
+	struct BGMPlayParams{
+		std::string sound;
+		bool loop;
+	};
 	class EventData{
 	public:
 		void AddEventInfo(const Event&eventName,const VolumeList&volumes);
@@ -99,6 +104,9 @@ private:
 	std::set<Event>events;
 	static float defaultFadeTime;
 	Event currentAudioEvent="Default Volume";
+
+	float playBGMWaitTime=0.0f;
+	BGMPlayParams playParams;
 };
 
 std::string operator""_SFX(const char*key,size_t length);
\ No newline at end of file
diff --git a/Adventures in Lestoria/SaveFile.cpp b/Adventures in Lestoria/SaveFile.cpp
index 4472965d..eb4ef523 100644
--- a/Adventures in Lestoria/SaveFile.cpp	
+++ b/Adventures in Lestoria/SaveFile.cpp	
@@ -53,6 +53,7 @@ std::string SaveFile::saveFileName="";
 std::string SaveFile::username="";
 
 const size_t SaveFile::GetSaveFileCount(){
+	std::filesystem::create_directories("save_file_path"_S);
 	size_t count=0;
 	if(std::filesystem::exists("save_file_path"_S+"metadata.dat")){
 		utils::datafile metadata;
@@ -130,6 +131,7 @@ const void SaveFile::SaveGame(){
 }
 
 const void SaveFile::LoadGame(){
+	std::filesystem::create_directories("save_file_path"_S);
 	auto LoadFile=[&](){
 		utils::datafile loadFile;
 		if(std::filesystem::exists("save_file_path"_S+std::format("save.{:04}",saveFileID))){
@@ -191,7 +193,6 @@ const void SaveFile::LoadGame(){
 			}
 		});
 	#else
-		std::filesystem::create_directories("save_file_path"_S);
 		LoadFile();
 	#endif
 }
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5fa39c12..b93890b4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -352,14 +352,18 @@ endif()
 
 set(DATA_OUTPUT_DIR ${CMAKE_BINARY_DIR}/bin/${ASSETS_DIR})
 
+set (EXCLUDE_DIR "/assets/saves/")
 file(GLOB_RECURSE src_data_files
     RELATIVE ${SOURCE_DATA_DIR}/ "${SOURCE_DATA_DIR}/*.*" "${SOURCE_DATA_DIR}/*")
 foreach(fn ${src_data_files})
+    string (FIND ${fn} ${EXCLUDE_DIR} EXCLUDE_DIR_FOUND)
+    if (NOT ${EXCLUDE_DIR_FOUND} EQUAL -1)
     add_custom_command(
         OUTPUT ${DATA_OUTPUT_DIR}/${fn}
         COMMAND ${CMAKE_COMMAND} -E copy ${SOURCE_DATA_DIR}/${fn} ${DATA_OUTPUT_DIR}/${fn}
         MAIN_DEPENDENCY ${SOURCE_DATA_DIR}/${fn})
     list(APPEND out_data_files ${DATA_OUTPUT_DIR}/${fn})
+    endif()
 endforeach()
 
 add_custom_target(copy_data DEPENDS ${out_data_files})
diff --git a/enc_temp_folder/7bc3a296f298485445fd98097212ba0/TODO.txt b/enc_temp_folder/7bc3a296f298485445fd98097212ba0/TODO.txt
deleted file mode 100644
index 7402165e..00000000
--- a/enc_temp_folder/7bc3a296f298485445fd98097212ba0/TODO.txt
+++ /dev/null
@@ -1,47 +0,0 @@
-January 1st
-===========
-The Hub / NPC Interactions
-Save/Load Game
-	EMSCRIPTEN Version: ???
-		NEW GAME -> Ask for a User ID -> Ask for a Save File Name -> Saves the Game -> Starts the Game
-		LOAD GAME -> Ask for a User ID -> Shows Available Files -> Click to Load -> Start Game
-
-Audio Engine
-	- Audio Ambience Zones
-	- Menu Sound Effects
-	- Attack / Enemy Sound Effects
-	- Music Loading/Looping
-Settings Menu
-	- Any settings should be saved to the save file!
-	- Volume Controls
-	- Play Sound in Background
-	- Key Configuration
-		-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.
-		-We have to save keybinds to the save file.
--Smooth Movement
-
-January 31st
-============
-Implement the rest of the enemy types:
-- Baby Wolf
-- Wolf
-- Wolf Leader
-- Baby Bear
-- Brown Bear
-- Green Frog
-- Red Frog
-- Orange Frog
-- Blue Frog
-Implement Ursule, Mother of Bears Boss
-Story proofreading/correcting/storyboarding
-- Add a command to play sound effects/music.
-- Fix Keyboard/Controller Menu Navigation (Need clearly defined rules)
-- Game Controller Support
-	- Should use the Keybind structure that already exists.
-- Loading Screen
-- Title Screen setpieces
-
-- Export/Import Save Files Online/Offline
-
-- Consider controls for fine-tuning music and how they sound during events.
\ No newline at end of file