summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--res/slider_off.pngbin0 -> 111 bytes
-rw-r--r--res/slider_on.pngbin0 -> 145 bytes
-rw-r--r--src/input_system.cpp8
-rw-r--r--src/menu.h26
-rw-r--r--src/menu_system.cpp28
-rw-r--r--src/menu_system.h4
-rw-r--r--src/renderer.cpp55
7 files changed, 117 insertions, 4 deletions
diff --git a/res/slider_off.png b/res/slider_off.png new file mode 100644 index 0000000..432c5ec --- /dev/null +++ b/res/slider_off.png
Binary files differ
diff --git a/res/slider_on.png b/res/slider_on.png new file mode 100644 index 0000000..eb67a43 --- /dev/null +++ b/res/slider_on.png
Binary files differ
diff --git a/src/input_system.cpp b/src/input_system.cpp index 25af7ed..3e4b679 100644 --- a/src/input_system.cpp +++ b/src/input_system.cpp
@@ -119,12 +119,20 @@ void InputSystem::tick(double dt) {
119 } 119 }
120 } 120 }
121 } else if (e.key.keysym.sym == SDLK_LEFT) { 121 } else if (e.key.keysym.sym == SDLK_LEFT) {
122 if (game_.getSystem<MenuSystem>().isMenuOpen()) {
123 game_.getSystem<MenuSystem>().pressedLeft();
124 }
125
122 if (game_.isGameplayPaused()) continue; 126 if (game_.isGameplayPaused()) continue;
123 127
124 if (game_.getSystem<MessageSystem>().isChoiceActive()) { 128 if (game_.getSystem<MessageSystem>().isChoiceActive()) {
125 game_.getSystem<MessageSystem>().selectFirstChoice(); 129 game_.getSystem<MessageSystem>().selectFirstChoice();
126 } 130 }
127 } else if (e.key.keysym.sym == SDLK_RIGHT) { 131 } else if (e.key.keysym.sym == SDLK_RIGHT) {
132 if (game_.getSystem<MenuSystem>().isMenuOpen()) {
133 game_.getSystem<MenuSystem>().pressedRight();
134 }
135
128 if (game_.isGameplayPaused()) continue; 136 if (game_.isGameplayPaused()) continue;
129 137
130 if (game_.getSystem<MessageSystem>().isChoiceActive()) { 138 if (game_.getSystem<MessageSystem>().isChoiceActive()) {
diff --git a/src/menu.h b/src/menu.h index 67c75c0..9ef94be 100644 --- a/src/menu.h +++ b/src/menu.h
@@ -9,14 +9,17 @@
9class Game; 9class Game;
10 10
11enum class MenuType { 11enum class MenuType {
12 Command 12 Command,
13 Slider
13}; 14};
14 15
15struct MenuItem { 16struct MenuItem {
16 MenuType type = MenuType::Command; 17 MenuType type = MenuType::Command;
17 std::string text; 18 std::string text;
18 std::function<void(Game&)> activationFunction; 19 std::function<void(Game&)> activationFunction;
19 bool playSfx = false; 20 bool playSfx = true;
21 int value = 0;
22 int maxValue = 0;
20}; 23};
21 24
22class MenuBuilder { 25class MenuBuilder {
@@ -25,7 +28,6 @@ public:
25 MenuBuilder& Command(std::string text) { 28 MenuBuilder& Command(std::string text) {
26 result_.type = MenuType::Command; 29 result_.type = MenuType::Command;
27 result_.text = std::move(text); 30 result_.text = std::move(text);
28 result_.playSfx = true;
29 return *this; 31 return *this;
30 } 32 }
31 33
@@ -39,6 +41,22 @@ public:
39 return *this; 41 return *this;
40 } 42 }
41 43
44 MenuBuilder& Slider(std::string text) {
45 result_.type = MenuType::Slider;
46 result_.text = std::move(text);
47 return *this;
48 }
49
50 MenuBuilder& InitialValue(int value) {
51 result_.value = value;
52 return *this;
53 }
54
55 MenuBuilder& MaxValue(int mv) {
56 result_.maxValue = mv;
57 return *this;
58 }
59
42 MenuItem Build() const { 60 MenuItem Build() const {
43 return result_; 61 return result_;
44 } 62 }
@@ -55,6 +73,8 @@ public:
55 73
56 const std::vector<MenuItem>& getItems() const { return items_; } 74 const std::vector<MenuItem>& getItems() const { return items_; }
57 75
76 std::vector<MenuItem>& getItems() { return items_; }
77
58 int getCursorPosition() const { return cursor_; } 78 int getCursorPosition() const { return cursor_; }
59 79
60 void moveCursorUp(); 80 void moveCursorUp();
diff --git a/src/menu_system.cpp b/src/menu_system.cpp index 7ac8af5..e1aca8d 100644 --- a/src/menu_system.cpp +++ b/src/menu_system.cpp
@@ -54,6 +54,12 @@ void MenuSystem::openPauseMenu() {
54 MenuBuilder().Command("Settings") 54 MenuBuilder().Command("Settings")
55 .ActivationFunction([this] (Game&) { 55 .ActivationFunction([this] (Game&) {
56 openSubmenu(Menu({ 56 openSubmenu(Menu({
57 MenuBuilder().Slider("Music Volume: ")
58 .InitialValue(10)
59 .MaxValue(10),
60 MenuBuilder().Slider("Sound Volume: ")
61 .InitialValue(10)
62 .MaxValue(10),
57 MenuBuilder().Command("Back") 63 MenuBuilder().Command("Back")
58 .ActivationFunction([this] (Game& game) { 64 .ActivationFunction([this] (Game& game) {
59 closePauseMenu(); 65 closePauseMenu();
@@ -122,6 +128,28 @@ void MenuSystem::pressedDown() {
122 game_.getMixer().playSound("../res/sfx/vertical_menu.wav"); 128 game_.getMixer().playSound("../res/sfx/vertical_menu.wav");
123} 129}
124 130
131void MenuSystem::pressedLeft() {
132 Menu& curMenu = menus_.back();
133 MenuItem& menuItem = curMenu.getItems()[curMenu.getCursorPosition()];
134
135 if (menuItem.type == MenuType::Slider && menuItem.value > 0) {
136 menuItem.value--;
137
138 game_.getMixer().playSound("../res/sfx/horizontal_menu.wav");
139 }
140}
141
142void MenuSystem::pressedRight() {
143 Menu& curMenu = menus_.back();
144 MenuItem& menuItem = curMenu.getItems()[curMenu.getCursorPosition()];
145
146 if (menuItem.type == MenuType::Slider && menuItem.value < menuItem.maxValue) {
147 menuItem.value++;
148
149 game_.getMixer().playSound("../res/sfx/horizontal_menu.wav");
150 }
151}
152
125void MenuSystem::activateOption() { 153void MenuSystem::activateOption() {
126 Menu& curMenu = menus_.back(); 154 Menu& curMenu = menus_.back();
127 const MenuItem& menuItem = curMenu.getItems()[curMenu.getCursorPosition()]; 155 const MenuItem& menuItem = curMenu.getItems()[curMenu.getCursorPosition()];
diff --git a/src/menu_system.h b/src/menu_system.h index c921d0b..71e2b39 100644 --- a/src/menu_system.h +++ b/src/menu_system.h
@@ -29,6 +29,10 @@ public:
29 29
30 void pressedDown(); 30 void pressedDown();
31 31
32 void pressedLeft();
33
34 void pressedRight();
35
32 void activateOption(); 36 void activateOption();
33 37
34 // Info 38 // Info
diff --git a/src/renderer.cpp b/src/renderer.cpp index f7644ca..b28e3cb 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp
@@ -1,4 +1,5 @@
1#include "renderer.h" 1#include "renderer.h"
2#include <deque>
2#include <iostream> 3#include <iostream>
3#include "consts.h" 4#include "consts.h"
4#include "game.h" 5#include "game.h"
@@ -570,11 +571,33 @@ void Renderer::renderMenu(Game& game, const Menu& menu) {
570 SDL_RenderFillRect(ren_.get(), nullptr); 571 SDL_RenderFillRect(ren_.get(), nullptr);
571 572
572 const int lineHeight = 16; 573 const int lineHeight = 16;
574 const int sliderBarWidth = 9;
573 int totalHeight = menu.getItems().size() * lineHeight; 575 int totalHeight = menu.getItems().size() * lineHeight;
574 std::vector<vec2i> positions; 576 std::vector<vec2i> positions;
577 std::deque<MessageCache> sliderText;
578 int maxSliderLineWidth = 0;
579 int sliderAlignX = 0;
575 580
581 // First, find all of the sliders so we can figure out how to align them.
582 for (const MenuItem& menuItem : menu.getItems()) {
583 if (menuItem.type == MenuType::Slider) {
584 MessageCache output;
585 renderMessageLine(output, menuItem.text, game);
586
587 int width = output.charIndexToWidth.back() + sliderBarWidth * menuItem.maxValue;
588 if (width > maxSliderLineWidth) {
589 maxSliderLineWidth = width;
590 sliderAlignX = (CANVAS_WIDTH - maxSliderLineWidth) / 2 + output.charIndexToWidth.back();
591 }
592
593 sliderText.push_back(std::move(output));
594 }
595 }
596
597 // Now, render all of the items.
576 int index = 0; 598 int index = 0;
577 for (const MenuItem& menuItem : menu.getItems()) { 599 for (const MenuItem& menuItem : menu.getItems()) {
600 int lineY = (CANVAS_HEIGHT - totalHeight) / 2 + lineHeight * index;
578 switch (menuItem.type) { 601 switch (menuItem.type) {
579 case MenuType::Command: { 602 case MenuType::Command: {
580 MessageCache output; 603 MessageCache output;
@@ -582,7 +605,24 @@ void Renderer::renderMenu(Game& game, const Menu& menu) {
582 605
583 SDL_Rect dest { 606 SDL_Rect dest {
584 (CANVAS_WIDTH - output.charIndexToWidth.back()) / 2, 607 (CANVAS_WIDTH - output.charIndexToWidth.back()) / 2,
585 (CANVAS_HEIGHT - totalHeight) / 2 + lineHeight * index, 608 lineY,
609 MESSAGE_TEXT_WIDTH,
610 game.getFont().getCharacterHeight()
611 };
612
613 SDL_SetRenderTarget(ren_.get(), menuTex_.get());
614 SDL_RenderCopy(ren_.get(), output.renderedTex.get(), nullptr, &dest);
615
616 positions.emplace_back(dest.x, dest.y);
617
618 break;
619 }
620 case MenuType::Slider: {
621 MessageCache& output = sliderText.front();
622
623 SDL_Rect dest {
624 sliderAlignX - output.charIndexToWidth.back(),
625 lineY,
586 MESSAGE_TEXT_WIDTH, 626 MESSAGE_TEXT_WIDTH,
587 game.getFont().getCharacterHeight() 627 game.getFont().getCharacterHeight()
588 }; 628 };
@@ -592,6 +632,19 @@ void Renderer::renderMenu(Game& game, const Menu& menu) {
592 632
593 positions.emplace_back(dest.x, dest.y); 633 positions.emplace_back(dest.x, dest.y);
594 634
635 for (int j = 0; j < menuItem.maxValue; j++) {
636 int boxTexId = menuItem.value > j ? loadImageFromFile("../res/slider_on.png") : loadImageFromFile("../res/slider_off.png");
637 const SDL_Rect boxDest {
638 sliderAlignX + j * sliderBarWidth,
639 lineY + 2,
640 8,
641 8 };
642 SDL_SetRenderTarget(ren_.get(), menuTex_.get());
643 SDL_RenderCopy(ren_.get(), textures_.at(boxTexId).get(), nullptr, &boxDest);
644 }
645
646 sliderText.pop_front();
647
595 break; 648 break;
596 } 649 }
597 } 650 }