diff options
author | Star Rauchenberger <fefferburbia@gmail.com> | 2022-03-19 16:46:19 -0400 |
---|---|---|
committer | Star Rauchenberger <fefferburbia@gmail.com> | 2022-03-19 16:46:19 -0400 |
commit | b2f0190f6b2a227a21dd4909476171f7cc371a2d (patch) | |
tree | 0b12cdc515198a6daf5d0a39ed40f581e410cfba /src | |
parent | 81e8c1dae2e7e4be632d6e81d765b5dd43ea3927 (diff) | |
download | ether-b2f0190f6b2a227a21dd4909476171f7cc371a2d.tar.gz ether-b2f0190f6b2a227a21dd4909476171f7cc371a2d.tar.bz2 ether-b2f0190f6b2a227a21dd4909476171f7cc371a2d.zip |
menu!
Diffstat (limited to 'src')
-rw-r--r-- | src/consts.h | 2 | ||||
-rw-r--r-- | src/game.cpp | 34 | ||||
-rw-r--r-- | src/game.h | 8 | ||||
-rw-r--r-- | src/main.cpp | 15 | ||||
-rw-r--r-- | src/menu.cpp | 109 | ||||
-rw-r--r-- | src/menu.h | 42 | ||||
-rw-r--r-- | src/renderer.cpp | 133 | ||||
-rw-r--r-- | src/renderer.h | 12 |
8 files changed, 334 insertions, 21 deletions
diff --git a/src/consts.h b/src/consts.h index ecb2306..4c69a58 100644 --- a/src/consts.h +++ b/src/consts.h | |||
@@ -15,5 +15,7 @@ constexpr int NUM_TITLES = 1; | |||
15 | constexpr int MESSAGE_MARGIN = 64; | 15 | constexpr int MESSAGE_MARGIN = 64; |
16 | constexpr int MESSAGE_TEXT_WIDTH = GAME_WIDTH - MESSAGE_MARGIN * 2; | 16 | constexpr int MESSAGE_TEXT_WIDTH = GAME_WIDTH - MESSAGE_MARGIN * 2; |
17 | constexpr int CHARS_PER_BEEP = 8; | 17 | constexpr int CHARS_PER_BEEP = 8; |
18 | constexpr int MENU_PADDING = 40; | ||
19 | constexpr int MENU_BORDER = 2; | ||
18 | 20 | ||
19 | #endif /* end of include guard: CONSTS_H_152EBF56 */ | 21 | #endif /* end of include guard: CONSTS_H_152EBF56 */ |
diff --git a/src/game.cpp b/src/game.cpp index f8508c2..501722d 100644 --- a/src/game.cpp +++ b/src/game.cpp | |||
@@ -12,6 +12,7 @@ | |||
12 | Game::Game(std::mt19937& rng, Muxer& muxer, Renderer& renderer) : | 12 | Game::Game(std::mt19937& rng, Muxer& muxer, Renderer& renderer) : |
13 | rng(rng), | 13 | rng(rng), |
14 | muxer(muxer), | 14 | muxer(muxer), |
15 | renderer(renderer), | ||
15 | sign(renderer.getFont()) | 16 | sign(renderer.getFont()) |
16 | { | 17 | { |
17 | losePopLampTimer.accumulate(losePopLampTimer.getDt()); | 18 | losePopLampTimer.accumulate(losePopLampTimer.getDt()); |
@@ -740,13 +741,7 @@ void Game::updatePlaying(size_t frameTime) { | |||
740 | { | 741 | { |
741 | if (e.type == SDL_QUIT) | 742 | if (e.type == SDL_QUIT) |
742 | { | 743 | { |
743 | if (losing != LoseState::None) | 744 | quit = true; |
744 | { | ||
745 | quit = true; | ||
746 | } else { | ||
747 | losing = LoseState::PoppingLamps; | ||
748 | muxer.stopMusic(); | ||
749 | } | ||
750 | } else if (e.type == SDL_KEYDOWN) | 745 | } else if (e.type == SDL_KEYDOWN) |
751 | { | 746 | { |
752 | switch (e.key.keysym.sym) | 747 | switch (e.key.keysym.sym) |
@@ -755,10 +750,13 @@ void Game::updatePlaying(size_t frameTime) { | |||
755 | { | 750 | { |
756 | if (losing != LoseState::None) | 751 | if (losing != LoseState::None) |
757 | { | 752 | { |
758 | quit = true; | 753 | if (quitting) { |
754 | quit = true; | ||
755 | } else { | ||
756 | losing = LoseState::Done; | ||
757 | } | ||
759 | } else { | 758 | } else { |
760 | losing = LoseState::PoppingLamps; | 759 | menu.open(*this); |
761 | muxer.stopMusic(); | ||
762 | } | 760 | } |
763 | 761 | ||
764 | break; | 762 | break; |
@@ -922,11 +920,21 @@ void Game::updatePlaying(size_t frameTime) { | |||
922 | { | 920 | { |
923 | if (numDust == 0) | 921 | if (numDust == 0) |
924 | { | 922 | { |
925 | quit = true; | 923 | if (quitting) { |
924 | quit = true; | ||
925 | } else { | ||
926 | losing = LoseState::Done; | ||
927 | } | ||
926 | } | 928 | } |
927 | 929 | ||
928 | break; | 930 | break; |
929 | } | 931 | } |
932 | |||
933 | case LoseState::Done: | ||
934 | { | ||
935 | // Do nothing. | ||
936 | break; | ||
937 | } | ||
930 | } | 938 | } |
931 | 939 | ||
932 | switch (signInstructionState) { | 940 | switch (signInstructionState) { |
@@ -1035,7 +1043,9 @@ void Game::updatePlaying(size_t frameTime) { | |||
1035 | } | 1043 | } |
1036 | 1044 | ||
1037 | void Game::update(size_t frameTime) { | 1045 | void Game::update(size_t frameTime) { |
1038 | if (sign.signDisplayState != SignInstructionState::Hidden) { | 1046 | if (menu.menuState != MenuState::Closed) { |
1047 | menu.update(frameTime, *this); | ||
1048 | } else if (sign.signDisplayState != SignInstructionState::Hidden) { | ||
1039 | sign.update(frameTime, *this); | 1049 | sign.update(frameTime, *this); |
1040 | } else { | 1050 | } else { |
1041 | updatePlaying(frameTime); | 1051 | updatePlaying(frameTime); |
diff --git a/src/game.h b/src/game.h index 5f13672..839be67 100644 --- a/src/game.h +++ b/src/game.h | |||
@@ -12,6 +12,7 @@ | |||
12 | #include "interpolation.h" | 12 | #include "interpolation.h" |
13 | #include "consts.h" | 13 | #include "consts.h" |
14 | #include "sign.h" | 14 | #include "sign.h" |
15 | #include "menu.h" | ||
15 | 16 | ||
16 | class Renderer; | 17 | class Renderer; |
17 | 18 | ||
@@ -23,7 +24,8 @@ enum class LoseState { | |||
23 | None, | 24 | None, |
24 | PoppingLamps, | 25 | PoppingLamps, |
25 | PoppingPlayer, | 26 | PoppingPlayer, |
26 | Outro | 27 | Outro, |
28 | Done | ||
27 | }; | 29 | }; |
28 | 30 | ||
29 | struct Input { | 31 | struct Input { |
@@ -60,8 +62,10 @@ public: | |||
60 | 62 | ||
61 | std::mt19937& rng; | 63 | std::mt19937& rng; |
62 | Muxer& muxer; | 64 | Muxer& muxer; |
65 | Renderer& renderer; | ||
63 | 66 | ||
64 | bool quit = false; | 67 | bool quit = false; |
68 | bool quitting = false; // <- whether we will quit after losing, vs starting a new game | ||
65 | LoseState losing = LoseState::None; | 69 | LoseState losing = LoseState::None; |
66 | 70 | ||
67 | Map map; | 71 | Map map; |
@@ -110,6 +114,8 @@ public: | |||
110 | Interpolation signFade; | 114 | Interpolation signFade; |
111 | Sign sign; | 115 | Sign sign; |
112 | 116 | ||
117 | Menu menu; | ||
118 | |||
113 | private: | 119 | private: |
114 | 120 | ||
115 | void tickDirty(bool onlyDark); | 121 | void tickDirty(bool onlyDark); |
diff --git a/src/main.cpp b/src/main.cpp index 2bd8f3c..ae64079 100644 --- a/src/main.cpp +++ b/src/main.cpp | |||
@@ -1,6 +1,7 @@ | |||
1 | #include <vector> | 1 | #include <vector> |
2 | #include <fov.h> | 2 | #include <fov.h> |
3 | #include <iostream> | 3 | #include <iostream> |
4 | #include <memory> | ||
4 | #include "util.h" | 5 | #include "util.h" |
5 | #include "game.h" | 6 | #include "game.h" |
6 | #include "renderer.h" | 7 | #include "renderer.h" |
@@ -21,7 +22,7 @@ int main(int, char**) | |||
21 | Renderer renderer; | 22 | Renderer renderer; |
22 | Muxer muxer; | 23 | Muxer muxer; |
23 | 24 | ||
24 | Game game(rng, muxer, renderer); | 25 | std::unique_ptr<Game> game = std::make_unique<Game>(rng, muxer, renderer); |
25 | 26 | ||
26 | constexpr int titleFadeLen = 2000; | 27 | constexpr int titleFadeLen = 2000; |
27 | bool doneTitles = false; | 28 | bool doneTitles = false; |
@@ -32,22 +33,26 @@ int main(int, char**) | |||
32 | titleFade.start(titleFadeLen); | 33 | titleFade.start(titleFadeLen); |
33 | 34 | ||
34 | size_t lastTime = SDL_GetTicks(); | 35 | size_t lastTime = SDL_GetTicks(); |
35 | while (!game.quit) | 36 | while (!game->quit) |
36 | { | 37 | { |
37 | size_t currentTime = SDL_GetTicks(); | 38 | size_t currentTime = SDL_GetTicks(); |
38 | size_t frameTime = currentTime - lastTime; | 39 | size_t frameTime = currentTime - lastTime; |
39 | lastTime = currentTime; | 40 | lastTime = currentTime; |
40 | 41 | ||
41 | if (doneTitles) { | 42 | if (doneTitles) { |
42 | game.update(frameTime); | 43 | game->update(frameTime); |
43 | renderer.renderGame(game, true); | 44 | renderer.renderGame(*game, true); |
44 | muxer.update(); | 45 | muxer.update(); |
46 | |||
47 | if (game->losing == LoseState::Done) { | ||
48 | game = std::make_unique<Game>(rng, muxer, renderer); | ||
49 | } | ||
45 | } else { | 50 | } else { |
46 | SDL_Event e; | 51 | SDL_Event e; |
47 | 52 | ||
48 | while (SDL_PollEvent(&e)) { | 53 | while (SDL_PollEvent(&e)) { |
49 | if (e.type == SDL_QUIT) { | 54 | if (e.type == SDL_QUIT) { |
50 | game.quit = true; | 55 | game->quit = true; |
51 | } | 56 | } |
52 | } | 57 | } |
53 | 58 | ||
diff --git a/src/menu.cpp b/src/menu.cpp new file mode 100644 index 0000000..b9a3ace --- /dev/null +++ b/src/menu.cpp | |||
@@ -0,0 +1,109 @@ | |||
1 | #include "menu.h" | ||
2 | #include "game.h" | ||
3 | #include "renderer.h" | ||
4 | |||
5 | Menu::Menu() { | ||
6 | items.push_back({.text = "New Game", .activationFunction = [this] (Game& game) { | ||
7 | close(); | ||
8 | game.losing = LoseState::PoppingLamps; | ||
9 | game.muxer.stopMusic(); | ||
10 | }}); | ||
11 | items.push_back({.text = "Toggle Fullscreen", .activationFunction = [] (Game& game) { | ||
12 | game.renderer.toggleFullscreen(); | ||
13 | }}); | ||
14 | items.push_back({.text = "Quit", .activationFunction = [this] (Game& game) { | ||
15 | close(); | ||
16 | game.losing = LoseState::PoppingLamps; | ||
17 | game.quitting = true; | ||
18 | game.muxer.stopMusic(); | ||
19 | }}); | ||
20 | } | ||
21 | |||
22 | void Menu::open(Game& game) { | ||
23 | menuState = MenuState::Opening; | ||
24 | menuDisplayProgress.start(200); | ||
25 | game.muxer.playSound("openmenu"); | ||
26 | } | ||
27 | |||
28 | void Menu::close() { | ||
29 | menuState = MenuState::Closing; | ||
30 | menuDisplayProgress.start(200); | ||
31 | } | ||
32 | |||
33 | void Menu::update(size_t dt, Game& game) { | ||
34 | if (menuState != MenuState::Open) { | ||
35 | SDL_Event e; | ||
36 | |||
37 | while (SDL_PollEvent(&e)) { | ||
38 | if (e.type == SDL_QUIT) { | ||
39 | game.quit = true; | ||
40 | } | ||
41 | } | ||
42 | } | ||
43 | |||
44 | switch (menuState) { | ||
45 | case MenuState::Closed: { | ||
46 | // Shouldn't happen. | ||
47 | break; | ||
48 | } | ||
49 | case MenuState::Opening: { | ||
50 | menuDisplayProgress.tick(dt); | ||
51 | if (menuDisplayProgress.isComplete()) { | ||
52 | menuState = MenuState::Open; | ||
53 | } | ||
54 | |||
55 | break; | ||
56 | } | ||
57 | case MenuState::Closing: { | ||
58 | menuDisplayProgress.tick(dt); | ||
59 | if (menuDisplayProgress.isComplete()) { | ||
60 | menuState = MenuState::Closed; | ||
61 | } | ||
62 | |||
63 | break; | ||
64 | } | ||
65 | case MenuState::Open: { | ||
66 | SDL_Event e; | ||
67 | |||
68 | while (SDL_PollEvent(&e)) { | ||
69 | if (e.type == SDL_QUIT) { | ||
70 | game.quit = true; | ||
71 | } else if (e.type == SDL_KEYDOWN) { | ||
72 | switch (e.key.keysym.sym) | ||
73 | { | ||
74 | case SDLK_ESCAPE: { | ||
75 | close(); | ||
76 | game.muxer.playSound("closemenu"); | ||
77 | break; | ||
78 | } | ||
79 | case SDLK_SPACE: { | ||
80 | items[cursor].activationFunction(game); | ||
81 | game.muxer.playSound("menuselect"); | ||
82 | break; | ||
83 | } | ||
84 | case SDLK_UP: | ||
85 | case SDLK_w: { | ||
86 | cursor--; | ||
87 | if (cursor < 0) { | ||
88 | cursor = items.size() - 1; | ||
89 | } | ||
90 | game.muxer.playSound("menucursor"); | ||
91 | break; | ||
92 | } | ||
93 | case SDLK_DOWN: | ||
94 | case SDLK_s: { | ||
95 | cursor++; | ||
96 | if (cursor >= items.size()) { | ||
97 | cursor = 0; | ||
98 | } | ||
99 | game.muxer.playSound("menucursor"); | ||
100 | break; | ||
101 | } | ||
102 | } | ||
103 | } | ||
104 | } | ||
105 | |||
106 | break; | ||
107 | } | ||
108 | } | ||
109 | } | ||
diff --git a/src/menu.h b/src/menu.h new file mode 100644 index 0000000..ac72999 --- /dev/null +++ b/src/menu.h | |||
@@ -0,0 +1,42 @@ | |||
1 | #ifndef MENU_H_61DBBF6A | ||
2 | #define MENU_H_61DBBF6A | ||
3 | |||
4 | #include <string> | ||
5 | #include <functional> | ||
6 | #include <vector> | ||
7 | #include "interpolation.h" | ||
8 | |||
9 | class Game; | ||
10 | |||
11 | enum class MenuState { | ||
12 | Closed, | ||
13 | Opening, | ||
14 | Open, | ||
15 | Closing | ||
16 | }; | ||
17 | |||
18 | struct MenuItem { | ||
19 | std::string text; | ||
20 | std::function<void(Game&)> activationFunction; | ||
21 | }; | ||
22 | |||
23 | class Menu { | ||
24 | public: | ||
25 | |||
26 | Menu(); | ||
27 | |||
28 | void update(size_t dt, Game& game); | ||
29 | |||
30 | void open(Game& game); | ||
31 | |||
32 | MenuState menuState = MenuState::Closed; | ||
33 | Interpolation menuDisplayProgress; | ||
34 | std::vector<MenuItem> items; | ||
35 | int cursor = 0; | ||
36 | |||
37 | private: | ||
38 | |||
39 | void close(); | ||
40 | }; | ||
41 | |||
42 | #endif /* end of include guard: MENU_H_61DBBF6A */ | ||
diff --git a/src/renderer.cpp b/src/renderer.cpp index b90372e..1aa5cbf 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp | |||
@@ -16,8 +16,6 @@ Renderer::Renderer() | |||
16 | GAME_HEIGHT, | 16 | GAME_HEIGHT, |
17 | SDL_WINDOW_SHOWN)); | 17 | SDL_WINDOW_SHOWN)); |
18 | 18 | ||
19 | //SDL_SetWindowFullscreen(win_.get(), SDL_WINDOW_FULLSCREEN_DESKTOP); | ||
20 | |||
21 | if (!win_) | 19 | if (!win_) |
22 | { | 20 | { |
23 | throw sdl_error(); | 21 | throw sdl_error(); |
@@ -111,6 +109,7 @@ Renderer::Renderer() | |||
111 | loadTextureFromFile("../res/runninbloods.png", tileset_); | 109 | loadTextureFromFile("../res/runninbloods.png", tileset_); |
112 | loadTextureFromFile("../res/lamp.png", lamp_); | 110 | loadTextureFromFile("../res/lamp.png", lamp_); |
113 | loadTextureFromFile("../res/read_instruction.png", readInstruction_); | 111 | loadTextureFromFile("../res/read_instruction.png", readInstruction_); |
112 | loadTextureFromFile("../res/menu.png", menuBg_); | ||
114 | 113 | ||
115 | loadTextureFromFile("../res/title0.png", titles_[0]); | 114 | loadTextureFromFile("../res/title0.png", titles_[0]); |
116 | SDL_QueryTexture(titles_[0].get(), nullptr, nullptr, &titleWidths_[0], &titleHeights_[0]); | 115 | SDL_QueryTexture(titles_[0].get(), nullptr, nullptr, &titleWidths_[0], &titleHeights_[0]); |
@@ -394,6 +393,20 @@ void Renderer::renderGame( | |||
394 | 393 | ||
395 | SDL_RenderCopy(ren_.get(), canvas.get(), &zoomRect, nullptr); | 394 | SDL_RenderCopy(ren_.get(), canvas.get(), &zoomRect, nullptr); |
396 | 395 | ||
396 | texture_ptr overlays( | ||
397 | SDL_CreateTexture( | ||
398 | ren_.get(), | ||
399 | SDL_PIXELFORMAT_RGBA8888, | ||
400 | SDL_TEXTUREACCESS_TARGET, | ||
401 | GAME_WIDTH, | ||
402 | GAME_HEIGHT)); | ||
403 | |||
404 | SDL_SetTextureBlendMode(overlays.get(), SDL_BLENDMODE_BLEND); | ||
405 | SDL_SetRenderTarget(ren_.get(), overlays.get()); | ||
406 | SDL_SetRenderDrawBlendMode(ren_.get(), SDL_BLENDMODE_BLEND); | ||
407 | SDL_SetRenderDrawColor(ren_.get(), 0, 0, 0, 0); | ||
408 | SDL_RenderClear(ren_.get()); | ||
409 | |||
397 | if (game.signInstructionState != SignInstructionState::Hidden) { | 410 | if (game.signInstructionState != SignInstructionState::Hidden) { |
398 | int instOpacity = 255; | 411 | int instOpacity = 255; |
399 | if (game.signInstructionState == SignInstructionState::FadingIn) { | 412 | if (game.signInstructionState == SignInstructionState::FadingIn) { |
@@ -444,7 +457,7 @@ void Renderer::renderGame( | |||
444 | srcRect.w, | 457 | srcRect.w, |
445 | srcRect.h }; | 458 | srcRect.h }; |
446 | 459 | ||
447 | SDL_SetRenderTarget(ren_.get(), nullptr); | 460 | SDL_SetRenderTarget(ren_.get(), overlays.get()); |
448 | SDL_RenderCopy(ren_.get(), messageLines_[lineIndex].renderedTex.get(), &srcRect, &destRect); | 461 | SDL_RenderCopy(ren_.get(), messageLines_[lineIndex].renderedTex.get(), &srcRect, &destRect); |
449 | //std::cout << line.charsRevealed << " (" << messageLines_[lineIndex].charIndexToWidth[line.charsRevealed] << "): " << messageLines_[lineIndex].line.substr(0,line.charsRevealed) << std::endl; | 462 | //std::cout << line.charsRevealed << " (" << messageLines_[lineIndex].charIndexToWidth[line.charsRevealed] << "): " << messageLines_[lineIndex].line.substr(0,line.charsRevealed) << std::endl; |
450 | } | 463 | } |
@@ -455,6 +468,34 @@ void Renderer::renderGame( | |||
455 | } | 468 | } |
456 | } | 469 | } |
457 | 470 | ||
471 | if (game.menu.menuState != MenuState::Closed) { | ||
472 | if (!menu_ || menuSelected_ != game.menu.cursor) { | ||
473 | renderMenu(game); | ||
474 | } | ||
475 | |||
476 | SDL_Rect rect { | ||
477 | 0, 0, GAME_WIDTH, GAME_HEIGHT | ||
478 | }; | ||
479 | |||
480 | int opacity = 128; | ||
481 | if (game.menu.menuState == MenuState::Opening) { | ||
482 | opacity = game.menu.menuDisplayProgress.getProgress(0, 128); | ||
483 | rect.y = game.menu.menuDisplayProgress.getProgress(-GAME_HEIGHT, 0); | ||
484 | } else if (game.menu.menuState == MenuState::Closing) { | ||
485 | opacity = game.menu.menuDisplayProgress.getProgress(128, 0); | ||
486 | rect.y = game.menu.menuDisplayProgress.getProgress(0, -GAME_HEIGHT); | ||
487 | } | ||
488 | |||
489 | SDL_SetRenderTarget(ren_.get(), overlays.get()); | ||
490 | SDL_SetRenderDrawBlendMode(ren_.get(), SDL_BLENDMODE_BLEND); | ||
491 | SDL_SetRenderDrawColor(ren_.get(), 0, 0, 0, opacity); | ||
492 | SDL_RenderFillRect(ren_.get(), nullptr); | ||
493 | |||
494 | SDL_RenderCopy(ren_.get(), menu_.get(), nullptr, &rect); | ||
495 | } | ||
496 | |||
497 | SDL_SetRenderTarget(ren_.get(), nullptr); | ||
498 | SDL_RenderCopy(ren_.get(), overlays.get(), nullptr, nullptr); | ||
458 | SDL_RenderPresent(ren_.get()); | 499 | SDL_RenderPresent(ren_.get()); |
459 | } | 500 | } |
460 | 501 | ||
@@ -550,3 +591,89 @@ void Renderer::renderMessageLine(MessageCache& line, const std::string& text, co | |||
550 | SDL_RenderCopy(ren_.get(), lineTex.get(), nullptr, &rect); | 591 | SDL_RenderCopy(ren_.get(), lineTex.get(), nullptr, &rect); |
551 | } | 592 | } |
552 | 593 | ||
594 | void Renderer::renderMenu(const Game& game) { | ||
595 | int maxTextWidth = 0; | ||
596 | for (const MenuItem& item : game.menu.items) { | ||
597 | int width = 0; | ||
598 | TTF_SizeText(font_.get(), item.text.c_str(), &width, nullptr); | ||
599 | if (width > maxTextWidth) { | ||
600 | maxTextWidth = width; | ||
601 | } | ||
602 | } | ||
603 | |||
604 | menuWidth_ = maxTextWidth + MENU_PADDING * 2; | ||
605 | menuHeight_ = (TTF_FontHeight(font_.get()) + 1) * game.menu.items.size() - 1 + MENU_PADDING * 2; | ||
606 | |||
607 | menu_.reset(SDL_CreateTexture( | ||
608 | ren_.get(), | ||
609 | SDL_PIXELFORMAT_RGBA8888, | ||
610 | SDL_TEXTUREACCESS_TARGET, | ||
611 | GAME_WIDTH, | ||
612 | GAME_HEIGHT)); | ||
613 | |||
614 | SDL_SetRenderTarget(ren_.get(), menu_.get()); | ||
615 | SDL_SetTextureBlendMode(menu_.get(), SDL_BLENDMODE_BLEND); | ||
616 | SDL_SetRenderDrawBlendMode(ren_.get(), SDL_BLENDMODE_BLEND); | ||
617 | SDL_SetRenderDrawColor(ren_.get(), 0, 0, 0, 0); | ||
618 | SDL_RenderClear(ren_.get()); | ||
619 | |||
620 | SDL_Color bgColor {.r = 55, .g = 55, .b = 87, .a = 255}; | ||
621 | SDL_Color fgColor {.r = 146, .g = 146, .b = 146, .a = 255}; | ||
622 | SDL_Color selectedColor {.r = 255, .g = 255, .b = 255, .a = 255}; | ||
623 | |||
624 | /*{ | ||
625 | SDL_Rect drawRect { | ||
626 | (GAME_WIDTH - menuWidth_) / 2 - MENU_BORDER, | ||
627 | (GAME_HEIGHT - menuHeight_) / 2 - MENU_BORDER, | ||
628 | menuWidth_ + MENU_BORDER * 2, | ||
629 | menuHeight_ + MENU_BORDER * 2 | ||
630 | }; | ||
631 | |||
632 | SDL_SetRenderDrawColor(ren_.get(), 200, 200, 200, 255); | ||
633 | SDL_RenderFillRect(ren_.get(), &drawRect); | ||
634 | } | ||
635 | |||
636 | { | ||
637 | SDL_Rect drawRect { | ||
638 | (GAME_WIDTH - menuWidth_) / 2, | ||
639 | (GAME_HEIGHT - menuHeight_) / 2, | ||
640 | menuWidth_, | ||
641 | menuHeight_ | ||
642 | }; | ||
643 | |||
644 | SDL_SetRenderDrawColor(ren_.get(), bgColor.r, bgColor.g, bgColor.b, 255); | ||
645 | SDL_RenderFillRect(ren_.get(), &drawRect); | ||
646 | |||
647 | std::cout << "(" << drawRect.x << "," << drawRect.y << "),(" << drawRect.w << "," << drawRect.h << ")" << std::endl; | ||
648 | }*/ | ||
649 | |||
650 | SDL_RenderCopy(ren_.get(), menuBg_.get(), nullptr, nullptr); | ||
651 | |||
652 | for (int i=0; i < game.menu.items.size(); i++) { | ||
653 | const MenuItem& item = game.menu.items.at(i); | ||
654 | int width = 0; | ||
655 | TTF_SizeText(font_.get(), item.text.c_str(), &width, nullptr); | ||
656 | |||
657 | surface_ptr lineSurf = surface_ptr(TTF_RenderText_Shaded(font_.get(), item.text.c_str(), game.menu.cursor == i ? selectedColor : fgColor, bgColor)); | ||
658 | texture_ptr lineTex = texture_ptr(SDL_CreateTextureFromSurface(ren_.get(), lineSurf.get())); | ||
659 | |||
660 | SDL_Rect drawRect { | ||
661 | (GAME_WIDTH - width) / 2, | ||
662 | (GAME_HEIGHT - menuHeight_) / 2 + MENU_PADDING + (TTF_FontHeight(font_.get()) + 1) * i, | ||
663 | width, | ||
664 | TTF_FontHeight(font_.get()) | ||
665 | }; | ||
666 | SDL_RenderCopy(ren_.get(), lineTex.get(), nullptr, &drawRect); | ||
667 | } | ||
668 | |||
669 | menuSelected_ = game.menu.cursor; | ||
670 | } | ||
671 | |||
672 | void Renderer::toggleFullscreen() { | ||
673 | isFullscreen = !isFullscreen; | ||
674 | if (isFullscreen) { | ||
675 | SDL_SetWindowFullscreen(win_.get(), SDL_WINDOW_FULLSCREEN_DESKTOP); | ||
676 | } else { | ||
677 | SDL_SetWindowFullscreen(win_.get(), 0); | ||
678 | } | ||
679 | } | ||
diff --git a/src/renderer.h b/src/renderer.h index ce2e7e1..8a74c3c 100644 --- a/src/renderer.h +++ b/src/renderer.h | |||
@@ -165,6 +165,8 @@ public: | |||
165 | 165 | ||
166 | TTF_Font* getFont() { return font_.get(); } | 166 | TTF_Font* getFont() { return font_.get(); } |
167 | 167 | ||
168 | void toggleFullscreen(); | ||
169 | |||
168 | private: | 170 | private: |
169 | 171 | ||
170 | void loadTextureFromFile(std::string_view path, texture_ptr& texture); | 172 | void loadTextureFromFile(std::string_view path, texture_ptr& texture); |
@@ -183,6 +185,7 @@ private: | |||
183 | texture_ptr tileset_; | 185 | texture_ptr tileset_; |
184 | texture_ptr lamp_; | 186 | texture_ptr lamp_; |
185 | texture_ptr readInstruction_; | 187 | texture_ptr readInstruction_; |
188 | texture_ptr menuBg_; | ||
186 | 189 | ||
187 | std::array<texture_ptr, NUM_TITLES> titles_; | 190 | std::array<texture_ptr, NUM_TITLES> titles_; |
188 | std::array<int, NUM_TITLES> titleWidths_; | 191 | std::array<int, NUM_TITLES> titleWidths_; |
@@ -199,6 +202,15 @@ private: | |||
199 | void renderMessageLine(MessageCache& line, const std::string& text, const Game& game); | 202 | void renderMessageLine(MessageCache& line, const std::string& text, const Game& game); |
200 | 203 | ||
201 | MessageCache messageLines_[2]; | 204 | MessageCache messageLines_[2]; |
205 | |||
206 | bool isFullscreen = false; | ||
207 | |||
208 | void renderMenu(const Game& game); | ||
209 | |||
210 | texture_ptr menu_; | ||
211 | int menuWidth_ = 0; | ||
212 | int menuHeight_ = 0; | ||
213 | int menuSelected_ = 0; | ||
202 | }; | 214 | }; |
203 | 215 | ||
204 | #endif /* end of include guard: RENDERER_H_6A58EC30 */ | 216 | #endif /* end of include guard: RENDERER_H_6A58EC30 */ |