Added bgm and sfx sliders.

pull/35/head
sigonasr2 10 months ago
parent 2bbd5e9ee4
commit 2b34cbbeac
  1. 26
      Adventures in Lestoria/Audio.cpp
  2. 6
      Adventures in Lestoria/Audio.h
  3. 2
      Adventures in Lestoria/MonsterAttribute.h
  4. 26
      Adventures in Lestoria/SettingsWindow.cpp
  5. 40
      Adventures in Lestoria/Slider.h
  6. 4
      Adventures in Lestoria/SoundEffect.cpp
  7. 4
      Adventures in Lestoria/TODO.txt
  8. 2
      Adventures in Lestoria/Version.h
  9. 5
      Adventures in Lestoria/assets/config/audio/events.txt
  10. BIN
      Adventures in Lestoria/assets/sounds/changevolume.ogg
  11. BIN
      x64/Release/Adventures in Lestoria.exe

@ -43,7 +43,9 @@ All rights reserved.
INCLUDE_game
INCLUDE_DATA
float Audio::defaultFadeTime;
float Audio::defaultFadeTime=0.f;
float Audio::sfxVol=1.f;
float Audio::bgmVol=1.f;
void Audio::Initialize(){
Engine().SetBackgroundPlay(true);
@ -265,7 +267,7 @@ void Audio::Update(){
float channelVol=track.GetVolume(Self().currentAudioEvent,channelListIndex);
Self().prevVolumes.push_back(channelVol);
Self().targetVolumes.push_back(channelVol);
Engine().SetVolume(trackID,channelVol);
Engine().SetVolume(trackID,channelVol*GetBGMVolume());
Engine().Play(trackID,Self().playParams.loop);
channelListIndex++;
}
@ -277,7 +279,7 @@ void Audio::Update(){
Self().fadeToTargetVolumeTime=std::max(0.f,Self().fadeToTargetVolumeTime-game->GetElapsedTime());
for(int counter=0;float&vol:Self().prevVolumes){
const BGM&currentBgm=Self().bgm[Self().currentBGM];
Engine().SetVolume(currentBgm.GetChannelIDs()[counter],util::lerp(vol,Self().targetVolumes[counter],1-(Self().fadeToTargetVolumeTime/currentBgm.GetFadeTime())));
Engine().SetVolume(currentBgm.GetChannelIDs()[counter],util::lerp(vol,Self().targetVolumes[counter],1-(Self().fadeToTargetVolumeTime/currentBgm.GetFadeTime()))*GetBGMVolume());
counter++;
}
}
@ -290,3 +292,21 @@ const bool Audio::BGMFullyLoaded(){
const float&Audio::BGM::GetFadeTime()const{
return fadeTime;
}
void Audio::SetBGMVolume(float vol){
bgmVol=vol;
BGM&track=Self().bgm[Self().playParams.sound];
for(int channelListIndex=0;int trackID:track.GetChannelIDs()){
float channelVol=track.GetVolume(Self().currentAudioEvent,channelListIndex);
Engine().SetVolume(trackID,channelVol*GetBGMVolume());
}
}
void Audio::SetSFXVolume(float vol){
sfxVol=vol;
}
float&Audio::GetBGMVolume(){
return bgmVol;
}
float&Audio::GetSFXVolume(){
return sfxVol;
}

@ -67,6 +67,10 @@ public:
static void SetAudioEvent(const Event&eventName);
static const bool BGMIsPlaying();
static const bool BGMFullyLoaded(); //Fully loaded means when the audio buffer has finished filling up, which means sound is now playing.
static void SetBGMVolume(float vol);
static void SetSFXVolume(float vol);
static float&GetBGMVolume();
static float&GetSFXVolume();
private:
struct BGMPlayParams{
std::string sound;
@ -79,6 +83,8 @@ private:
private:
std::map<Event,VolumeList>eventInfo;
};
static float bgmVol;
static float sfxVol;
class BGM{
public:
void Load();

@ -93,4 +93,6 @@ enum class Attribute{
BEAR_STOMP_COUNT,
PREVIOUS_PHASE,
COLLIDED_WITH_PLAYER, //A boolean flag that is set to true when an enemy makes contact with the player.
LAST_BGM_VOLUME,
LAST_SFX_VOLUME,
};

@ -44,22 +44,46 @@ All rights reserved.
#include "olcUTIL_DataFile.h"
#include "Unlock.h"
#include "State_OverworldMap.h"
#include "MenuLabel.h"
#include "Slider.h"
INCLUDE_DATA
INCLUDE_game
INCLUDE_WINDOW_SIZE
using A=Attribute;
void Menu::InitializeSettingsWindow(){
vf2d windowSize=WINDOW_SIZE-vf2d{28,28};
Menu*settingsWindow=CreateMenu(SETTINGS,CENTERED,windowSize);
settingsWindow->ADD("Unlock All Button",MenuComponent)(geom2d::rect<float>{{4,4},{72,12}},"Unlock All",[](MenuFuncData data){
settingsWindow->ADD("Unlock All Button",MenuComponent)(geom2d::rect<float>{{4,windowSize.y-12},{72,12}},"Unlock All",[](MenuFuncData data){
for(auto&cp:State_OverworldMap::connections){
Unlock::UnlockArea(cp.map);
}
SoundEffect::PlaySFX("Buy Item",SoundEffect::CENTERED);
return true;
})END;
settingsWindow->ADD("Settings Label",MenuLabel)(geom2d::rect<float>{{4,4},vf2d{windowSize.x-8,24}},"Game Settings",2.f,ComponentAttr::BACKGROUND|ComponentAttr::OUTLINE|ComponentAttr::SHADOW)END;
settingsWindow->F(A::LAST_BGM_VOLUME)=1.f;
settingsWindow->F(A::LAST_SFX_VOLUME)=1.f;
settingsWindow->ADD("BGM Slider",Slider)(geom2d::rect<float>{vf2d{windowSize.x/2-64,44},{172,16}},"BGM Volume:",Audio::GetBGMVolume(),[](float val){
if(abs(Menu::menus[SETTINGS]->F(A::LAST_BGM_VOLUME)-val)>=0.04f){
SoundEffect::PlaySFX("Change Volume",SoundEffect::CENTERED);
Menu::menus[SETTINGS]->F(A::LAST_BGM_VOLUME)=val;
}
Audio::SetBGMVolume(val);
})END;
settingsWindow->ADD("SFX Slider",Slider)(geom2d::rect<float>{vf2d{windowSize.x/2-64,64},{172,16}},"SFX Volume:",Audio::GetSFXVolume(),[](float val){
if(abs(Menu::menus[SETTINGS]->F(A::LAST_SFX_VOLUME)-val)>=0.04f){
SoundEffect::PlaySFX("Change Volume",SoundEffect::CENTERED);
Menu::menus[SETTINGS]->F(A::LAST_SFX_VOLUME)=val;
}
})END;
settingsWindow->ADD("Go Back",MenuComponent)(geom2d::rect<float>{windowSize/2-vf2d{36,16},{72,12}},"Go Back",[](MenuFuncData data){
Menu::CloseMenu();
return true;

@ -47,23 +47,27 @@ INCLUDE_GFX
class Slider:public MenuComponent{
bool dragging=false;
float&val; //0.f-1.f
float prevVal=0.f;
std::pair<int,int>minMaxDisplayValues;
std::function<void(float)>onValChange;
public:
//A slider component with a right-aligned label to the left, and a value display on the right-hand side.
//valRef is between 0-1.
//minMaxDisplayValues are visual only.
inline Slider(const geom2d::rect<float>&rect,const std::string&label,float&valRef,const std::pair<int,int>&minMaxDisplayValues={0,100},const ButtonAttr&attributes=ButtonAttr::NONE)
:MenuComponent(rect,label,DO_NOTHING,attributes),val(valRef),minMaxDisplayValues(minMaxDisplayValues){
:Slider(rect,label,valRef,[](float val){},minMaxDisplayValues,attributes){}
inline Slider(const geom2d::rect<float>&rect,const std::string&label,float&valRef,std::function<void(float)>onValChange,const std::pair<int,int>&minMaxDisplayValues={0,100},const ButtonAttr&attributes=ButtonAttr::NONE)
:MenuComponent(rect,label,DO_NOTHING,attributes),val(valRef),minMaxDisplayValues(minMaxDisplayValues),prevVal(valRef),onValChange(onValChange){
if(minMaxDisplayValues.first>minMaxDisplayValues.second)ERR(std::format("WARNING! The first value provided for component {} is greater than the second! {} > {}",name,minMaxDisplayValues.first,minMaxDisplayValues.second));
}
//Gets the absolute X position of the slider.
float GetSliderX(){
return rect.pos.x+rect.size.x*val;
return rect.pos.x+4+(rect.size.x-8)*val;
}
float GetSliderVal(float x){
return (x-rect.pos.x)/rect.size.x;
return (x-rect.pos.x+4)/(rect.size.x-8);
}
int GetValueDisplay(){
@ -81,7 +85,7 @@ class Slider:public MenuComponent{
if(dragging){
if(Menu::UsingMouseNavigation()){
val=GetSliderVal(game->GetMouseX());
val=GetSliderVal(game->GetMouseX()-Menu::menus[parentMenu]->pos.x-8);
}else{
if(game->KEY_LEFT.Held()){
val-=1.f*game->GetElapsedTime();
@ -91,6 +95,10 @@ class Slider:public MenuComponent{
}
}
val=std::clamp(val,0.f,1.f);
if(abs(prevVal-val)>=0.01f){
onValChange(int(val*100)/100.f);
prevVal=val;
}
if(game->KEY_CONFIRM.Released()||game->GetMouse(Mouse::LEFT).bReleased){
dragging=false;
@ -105,16 +113,24 @@ class Slider:public MenuComponent{
}
vf2d labelSize=game->GetTextSizeProp(label);
window.DrawShadowStringPropDecal({rect.pos.x-2-labelSize.x,rect.pos.y+rect.size.y/2-labelSize.y/2},label);
window.DrawShadowStringPropDecal(vf2d{rect.pos.x-8-labelSize.x,rect.pos.y+rect.size.y/2-labelSize.y/2},label);
window.FillRectDecal({rect.pos.x,rect.pos.y+rect.size.y/2-1},{rect.size.x,2});
window.FillRectDecal(vf2d{rect.pos.x+4,rect.pos.y+rect.size.y/2-1}+vf2d{0.f,1.f},{rect.size.x-8,2},BLACK);
window.FillRectDecal(vf2d{rect.pos.x+4,rect.pos.y+rect.size.y/2-1},{rect.size.x-8,2});
window.DrawRotatedDecal({GetSliderX(),rect.pos.y+rect.size.y/2},GFX["circle.png"].Decal(),0.f,vf2d(GFX["circle.png"].Sprite()->Size())/2.f,{2.f,2.f},backCol);
window.DrawRotatedDecal(vf2d{GetSliderX(),rect.pos.y+rect.size.y/2},GFX["circle.png"].Decal(),0.f,vf2d(GFX["circle.png"].Sprite()->Size())/2.f,{5.f,5.f},BLACK);
window.DrawRotatedDecal(vf2d{GetSliderX(),rect.pos.y+rect.size.y/2},GFX["circle.png"].Decal(),0.f,vf2d(GFX["circle.png"].Sprite()->Size())/2.f,{4.f,4.f},backCol);
std::string valDisplayText=std::to_string(GetValueDisplay());
vf2d valDisplayTextSize=game->GetTextSize(valDisplayText);
vf2d valDisplayTextSize=game->GetTextSize(std::to_string(minMaxDisplayValues.second));
vf2d valDisplayOutlinePos={rect.pos.x+rect.size.x+2,rect.pos.y};
window.DrawRectDecal(valDisplayOutlinePos,valDisplayTextSize+vf2d{4,4});
window.DrawShadowStringDecal(valDisplayOutlinePos+vf2d{2,2},valDisplayText);
Pixel valueBackCol=Menu::themes[Menu::themeSelection].GetButtonCol();
Pixel valueTextCol=WHITE;
if(grayedOut){
valueBackCol=GREY;
valueTextCol=VERY_DARK_GREY;
}
window.FillRectDecal(valDisplayOutlinePos+vf2d{7.f,1.f},valDisplayTextSize+vf2d{4,4},valueBackCol);
window.DrawShadowStringDecal(valDisplayOutlinePos+vf2d{9.f,3.f},std::format("{:03}",GetValueDisplay()),valueTextCol);
}
};

@ -88,7 +88,7 @@ void SoundEffect::PlaySFX(const std::string_view eventName,const vf2d&pos){
float pitch=util::random(pitchDiff)+sfx.minPitch;
if(pos==CENTERED){
Audio::Engine().Play(operator""_SFX(sfx.filename.c_str(),sfx.filename.length()),sfx.vol,0.0f,pitch);
Audio::Engine().Play(operator""_SFX(sfx.filename.c_str(),sfx.filename.length()),sfx.vol*Audio::GetSFXVolume(),0.0f,pitch);
}else{
const float soundActivationRange="Audio.Environmental Audio Activation Range"_F;
@ -97,7 +97,7 @@ void SoundEffect::PlaySFX(const std::string_view eventName,const vf2d&pos){
float distRatio=1-distanceFromPlayer/soundActivationRange; //0-1 where 1 is full volume.
float xDistRatio=(pos.x-game->GetPlayer()->GetX())/soundActivationRange; //0-1 where 1 is full volume.
float vol=distRatio*sfx.vol;
float vol=distRatio*sfx.vol*Audio::GetSFXVolume();
float pan=xDistRatio;
Audio::Engine().Play(operator""_SFX(sfx.filename.c_str(),sfx.filename.length()),vol,pan,pitch);
}

@ -3,13 +3,15 @@ January 1st
Settings Menu
- Any settings should be saved to the save file!
- Volume Controls
- Play Sound in Background
- Play Sound in Background (Sound while Focused)
- Keyboard aim assist (When playing w/keyboard, have the game auto fire for players that don't want to use mouse or cannot)
- Terrain Collision Boxes
- 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.
- XP Bar
- Implement escape menu during gameplay.

@ -39,7 +39,7 @@ All rights reserved.
#define VERSION_MAJOR 0
#define VERSION_MINOR 3
#define VERSION_PATCH 0
#define VERSION_BUILD 6718
#define VERSION_BUILD 6743
#define stringify(a) stringify_(a)
#define stringify_(a) #a

@ -17,6 +17,11 @@ Events
# Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%)
File[0] = button_click2.ogg, 40%
}
Change Volume
{
# Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%)
File[0] = changevolume.ogg, 50%, 60%, 60%
}
Consume Potion
{
# Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%)

Loading…
Cancel
Save