diff options
-rw-r--r-- | res/slider_off.png | bin | 0 -> 111 bytes | |||
-rw-r--r-- | res/slider_on.png | bin | 0 -> 145 bytes | |||
-rw-r--r-- | src/input_system.cpp | 8 | ||||
-rw-r--r-- | src/menu.h | 26 | ||||
-rw-r--r-- | src/menu_system.cpp | 28 | ||||
-rw-r--r-- | src/menu_system.h | 4 | ||||
-rw-r--r-- | src/renderer.cpp | 55 |
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 @@ | |||
9 | class Game; | 9 | class Game; |
10 | 10 | ||
11 | enum class MenuType { | 11 | enum class MenuType { |
12 | Command | 12 | Command, |
13 | Slider | ||
13 | }; | 14 | }; |
14 | 15 | ||
15 | struct MenuItem { | 16 | struct 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 | ||
22 | class MenuBuilder { | 25 | class 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 | ||
131 | void 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 | |||
142 | void 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 | |||
125 | void MenuSystem::activateOption() { | 153 | void 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 | } |