commit 517ed886
New volume controls
Changed files
| M | source/code/MenuSystem.cpp before |
| M | source/code/MenuSystem.h before |
| M | source/code/menudef.cpp before |
diff --git a/source/code/MenuSystem.cpp b/source/code/MenuSystem.cpp
index c0361b2..191df06 100644
--- a/source/code/MenuSystem.cpp
+++ b/source/code/MenuSystem.cpp
@@ -118,6 +118,58 @@ static void drawToScreen(const Button& b) {
sago::SagoTextField::Alignment::center, sago::SagoTextField::VerticalAlignment::center, &globalData.logicalResize);
}
+void Button::drawToScreen(SDL_Renderer* target) const {
+ ::drawToScreen(*this);
+}
+
+void ButtonWithAdjustment::drawToScreen(SDL_Renderer* target) const {
+ // Draw the main button
+ if (marked) {
+ globalData.spriteHolder->GetSprite(standardButton.menu_marked).Draw(globalData.screen, SDL_GetTicks(), x, y, &globalData.logicalResize);
+ }
+ else {
+ globalData.spriteHolder->GetSprite(standardButton.menu_unmarked).Draw(globalData.screen, SDL_GetTicks(), x, y, &globalData.logicalResize);
+ }
+
+ standardButton.getLabel(getLabel(), marked)->Draw(globalData.screen, x+standardButton.xsize/2, y+standardButton.ysize/2,
+ sago::SagoTextField::Alignment::center, sago::SagoTextField::VerticalAlignment::center, &globalData.logicalResize);
+
+ // Draw left adjustment button (down arrow)
+ int adjustSize = getAdjustButtonSize();
+ int leftX = x - adjustSize - 10;
+ int leftY = y + (standardButton.ysize - adjustSize) / 2; // Vertically center the small button
+ globalData.spriteHolder->GetSprite("menu_unmarked").DrawScaled(globalData.screen, SDL_GetTicks(), leftX, leftY, adjustSize, adjustSize, &globalData.logicalResize);
+ standardButton.getLabel("\u25c0", false)->Draw(globalData.screen, leftX+adjustSize/2, leftY+adjustSize/2,
+ sago::SagoTextField::Alignment::center, sago::SagoTextField::VerticalAlignment::center, &globalData.logicalResize);
+
+ // Draw right adjustment button (up arrow)
+ int rightX = x + standardButton.xsize + 10;
+ int rightY = y + (standardButton.ysize - adjustSize) / 2; // Vertically center the small button
+ globalData.spriteHolder->GetSprite("menu_unmarked").DrawScaled(globalData.screen, SDL_GetTicks(), rightX, rightY, adjustSize, adjustSize, &globalData.logicalResize);
+ standardButton.getLabel("\u25b6", false)->Draw(globalData.screen, rightX+adjustSize/2, rightY+adjustSize/2,
+ sago::SagoTextField::Alignment::center, sago::SagoTextField::VerticalAlignment::center, &globalData.logicalResize);
+}
+
+bool ButtonWithAdjustment::isClickedAdjustLeft(int mx, int my) const {
+ int adjustSize = getAdjustButtonSize();
+ int leftX = x - adjustSize - 10;
+ int leftY = y + (standardButton.ysize - adjustSize) / 2;
+ if (mx >= leftX && my >= leftY && mx <= leftX + adjustSize && my <= leftY + adjustSize) {
+ return true;
+ }
+ return false;
+}
+
+bool ButtonWithAdjustment::isClickedAdjustRight(int mx, int my) const {
+ int adjustSize = getAdjustButtonSize();
+ int rightX = x + standardButton.xsize + 10;
+ int rightY = y + (standardButton.ysize - adjustSize) / 2;
+ if (mx >= rightX && my >= rightY && mx <= rightX + adjustSize && my <= rightY + adjustSize) {
+ return true;
+ }
+ return false;
+}
+
static bool isClicked(const Button& b, int x,int y) {
if ( x >= b.x && y >= b.y && x<= b.x+b.standardButton.xsize && y <= b.y + b.standardButton.ysize) {
@@ -129,9 +181,9 @@ static bool isClicked(const Button& b, int x,int y) {
void Menu::drawSelf(SDL_Renderer* target) {
DrawBackground(target);
for (const Button* b : buttons) {
- drawToScreen(*b);
+ b->drawToScreen(target);
}
- drawToScreen(exit);
+ exit.drawToScreen(target);
exit.standardButton.getLabel(title, false)->Draw(target, 50, 50, sago::SagoTextField::Alignment::left, sago::SagoTextField::VerticalAlignment::top, &globalData.logicalResize);
}
@@ -140,10 +192,12 @@ void Menu::placeButtons() {
int nextY = 100;
int X = 50;
for (Button* it : buttons) {
- X = (globalData.xsize - it->standardButton.xsize)/2;
- it->x = X;
+ // For all buttons, center based on the main button width to keep them aligned
+ int centerX = (globalData.xsize - it->standardButton.xsize)/2;
+ it->x = centerX;
it->y = nextY;
nextY += it->standardButton.ysize+10;
+ X = it->x;
}
exit.x = X;
exit.y = nextY;
@@ -300,6 +354,20 @@ void Menu::ProcessInput(const SDL_Event& event, bool& processed) {
processed = true;
}
+ if (isLeftEvent(event)) {
+ if (marked < (int)buttons.size()) {
+ buttons.at(marked)->doLeft();
+ }
+ processed = true;
+ }
+
+ if (isRightEvent(event)) {
+ if (marked < (int)buttons.size()) {
+ buttons.at(marked)->doRight();
+ }
+ processed = true;
+ }
+
if (isEscapeEvent(event) && isSubmenu) {
running = false;
processed = true;
@@ -351,6 +419,16 @@ void Menu::Update() {
if ( (buttonState&SDL_BUTTON(1) )==SDL_BUTTON(1) && bMouseUp) {
bMouseUp = false;
for (int i=0; i< (int)buttons.size(); ++i) {
+ // Check for adjustment button clicks first
+ if (buttons.at(i)->isClickedAdjustLeft(mousex, mousey)) {
+ buttons.at(i)->doLeft();
+ return;
+ }
+ if (buttons.at(i)->isClickedAdjustRight(mousex, mousey)) {
+ buttons.at(i)->doRight();
+ return;
+ }
+ // Then check for main button click
if (isClicked(*buttons.at(i), mousex, mousey)) {
buttons.at(i)->doAction();
if (buttons.at(i)->isPopOnRun()) {
diff --git a/source/code/MenuSystem.h b/source/code/MenuSystem.h
index 8be082d..5defe0c 100644
--- a/source/code/MenuSystem.h
+++ b/source/code/MenuSystem.h
@@ -81,14 +81,40 @@ public:
void setAction(void (*action2run)(void));
virtual void doAction(); //Run the callback function
+ virtual void doLeft() {}; //Handle left input (for adjustment buttons)
+ virtual void doRight() {}; //Handle right input (for adjustment buttons)
void setPopOnRun(bool popOnRun);
bool isPopOnRun() const;
virtual const std::string& getLabel() const {return this->label; };
+ virtual bool hasAdjustmentButtons() const { return false; };
+ virtual void drawToScreen(SDL_Renderer* target) const;
+ virtual bool isClickedAdjustLeft(int /*x*/, int /*y*/) const { return false; };
+ virtual bool isClickedAdjustRight(int /*x*/, int /*y*/) const { return false; };
+ virtual int getTotalWidth() const { return standardButton.xsize; };
//May hold any other information the callback might need
int iGeneric1 = 0;
};
+//A button with left/right adjustment controls
+class ButtonWithAdjustment : public Button
+{
+public:
+ ButtonWithAdjustment() = default;
+ virtual ~ButtonWithAdjustment() = default;
+
+ virtual bool hasAdjustmentButtons() const override { return true; };
+ virtual void drawToScreen(SDL_Renderer* target) const override;
+ virtual bool isClickedAdjustLeft(int x, int y) const override;
+ virtual bool isClickedAdjustRight(int x, int y) const override;
+ virtual int getTotalWidth() const override {
+ int adjustSize = getAdjustButtonSize();
+ return adjustSize + 10 + standardButton.xsize + 10 + adjustSize;
+ };
+
+ int getAdjustButtonSize() const { return standardButton.ysize / 2; };
+};
+
class Menu : public sago::GameStateInterface
{
diff --git a/source/code/menudef.cpp b/source/code/menudef.cpp
index eeaf85e..58eb7bf 100644
--- a/source/code/menudef.cpp
+++ b/source/code/menudef.cpp
@@ -218,6 +218,102 @@ void Button_testMusic::doAction() {
Mix_PlayMusic(bgMusic.get(), -1);
}
+// Sound volume button with adjustment controls
+class Button_soundVolume : public ButtonWithAdjustment {
+private:
+ mutable std::string volumeLabel;
+ int incrementValue = 5;
+public:
+ Button_soundVolume();
+ virtual void doAction() override;
+ virtual void doLeft() override;
+ virtual void doRight() override;
+ virtual const std::string& getLabel() const override;
+};
+
+Button_soundVolume::Button_soundVolume() {
+ standardButton.setSurfaces();
+}
+
+void Button_soundVolume::doAction() {
+ // Test sound
+ sago::SoundHandler testSound = globalData.spriteHolder->GetDataHolder().getSoundHandler("pop");
+ Mix_VolumeChunk(testSound.get(), Config::getInstance()->getInt("volume_sound"));
+ Mix_PlayChannel(1, testSound.get(), 0);
+}
+
+void Button_soundVolume::doLeft() {
+ // Decrease volume
+ int newValue = Config::getInstance()->getInt("volume_sound") - incrementValue;
+ if (newValue < 0) {
+ newValue = 0;
+ }
+ Config::getInstance()->setInt("volume_sound", newValue);
+}
+
+void Button_soundVolume::doRight() {
+ // Increase volume
+ int newValue = Config::getInstance()->getInt("volume_sound") + incrementValue;
+ if (newValue > MIX_MAX_VOLUME) {
+ newValue = MIX_MAX_VOLUME;
+ }
+ Config::getInstance()->setInt("volume_sound", newValue);
+}
+
+const std::string& Button_soundVolume::getLabel() const {
+ int volumePct = Config::getInstance()->getInt("volume_sound")*100.0/MIX_MAX_VOLUME;
+ volumeLabel = fmt::format(_("Sound: {}"), volumePct)+"%";
+ return volumeLabel;
+}
+
+// Music volume button with adjustment controls
+class Button_musicVolume : public ButtonWithAdjustment {
+private:
+ mutable std::string volumeLabel;
+ int incrementValue = 5;
+public:
+ Button_musicVolume();
+ virtual void doAction() override;
+ virtual void doLeft() override;
+ virtual void doRight() override;
+ virtual const std::string& getLabel() const override;
+};
+
+Button_musicVolume::Button_musicVolume() {
+ standardButton.setSurfaces();
+}
+
+void Button_musicVolume::doAction() {
+ // Test music
+ Mix_VolumeMusic(Config::getInstance()->getInt("volume_music"));
+ sago::MusicHandler bgMusic = globalData.spriteHolder->GetDataHolder().getMusicHandler("bgmusic");
+ Mix_PlayMusic(bgMusic.get(), -1);
+}
+
+void Button_musicVolume::doLeft() {
+ // Decrease volume
+ int newValue = Config::getInstance()->getInt("volume_music") - incrementValue;
+ if (newValue < 0) {
+ newValue = 0;
+ }
+ Config::getInstance()->setInt("volume_music", newValue);
+}
+
+void Button_musicVolume::doRight() {
+ // Increase volume
+ int newValue = Config::getInstance()->getInt("volume_music") + incrementValue;
+ if (newValue > MIX_MAX_VOLUME) {
+ newValue = MIX_MAX_VOLUME;
+ }
+ Config::getInstance()->setInt("volume_music", newValue);
+}
+
+const std::string& Button_musicVolume::getLabel() const {
+ int volumePct = Config::getInstance()->getInt("volume_music")*100.0/MIX_MAX_VOLUME;
+ volumeLabel = fmt::format(_("Music: {}"), volumePct)+"%";
+ return volumeLabel;
+}
+
static void runSinglePlayerEndless0() {
runGame(Gametype::SinglePlayerEndless, 0);
@@ -453,8 +549,8 @@ static void PlayerConfigMenu() {
static void ConfigureMenu() {
Menu cm(globalData.screen,_("Configuration"),true);
AlwaysSoftwareRenderButton bSoftware;
- MusicButton bMusic;
- SoundButton bSound;
+ Button_musicVolume bMusic;
+ Button_soundVolume bSound;
FullscreenButton buttonFullscreen;
BlockVariantButton bBlockVariant;
Button bPlayerConfig;
@@ -464,8 +560,6 @@ static void ConfigureMenu() {
bThemes.setLabel(_("Themes"));
bThemes.setAction(OpenThemesMenu);
SetAlwaysSoftwareLabel(&bSoftware);
- SetMusicLabel(&bMusic);
- SetSoundLabel(&bSound);
SetFullscreenLabel(&buttonFullscreen);
SetBlockVariationLabel(&bBlockVariant);
cm.addButton(&bMusic);