summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorStar Rauchenberger <fefferburbia@gmail.com>2022-03-19 16:46:19 -0400
committerStar Rauchenberger <fefferburbia@gmail.com>2022-03-19 16:46:19 -0400
commitb2f0190f6b2a227a21dd4909476171f7cc371a2d (patch)
tree0b12cdc515198a6daf5d0a39ed40f581e410cfba /src
parent81e8c1dae2e7e4be632d6e81d765b5dd43ea3927 (diff)
downloadether-b2f0190f6b2a227a21dd4909476171f7cc371a2d.tar.gz
ether-b2f0190f6b2a227a21dd4909476171f7cc371a2d.tar.bz2
ether-b2f0190f6b2a227a21dd4909476171f7cc371a2d.zip
menu!
Diffstat (limited to 'src')
-rw-r--r--src/consts.h2
-rw-r--r--src/game.cpp34
-rw-r--r--src/game.h8
-rw-r--r--src/main.cpp15
-rw-r--r--src/menu.cpp109
-rw-r--r--src/menu.h42
-rw-r--r--src/renderer.cpp133
-rw-r--r--src/renderer.h12
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;
15constexpr int MESSAGE_MARGIN = 64; 15constexpr int MESSAGE_MARGIN = 64;
16constexpr int MESSAGE_TEXT_WIDTH = GAME_WIDTH - MESSAGE_MARGIN * 2; 16constexpr int MESSAGE_TEXT_WIDTH = GAME_WIDTH - MESSAGE_MARGIN * 2;
17constexpr int CHARS_PER_BEEP = 8; 17constexpr int CHARS_PER_BEEP = 8;
18constexpr int MENU_PADDING = 40;
19constexpr 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 @@
12Game::Game(std::mt19937& rng, Muxer& muxer, Renderer& renderer) : 12Game::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
1037void Game::update(size_t frameTime) { 1045void 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
16class Renderer; 17class 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
29struct Input { 31struct 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
113private: 119private:
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
5Menu::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
22void Menu::open(Game& game) {
23 menuState = MenuState::Opening;
24 menuDisplayProgress.start(200);
25 game.muxer.playSound("openmenu");
26}
27
28void Menu::close() {
29 menuState = MenuState::Closing;
30 menuDisplayProgress.start(200);
31}
32
33void 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
9class Game;
10
11enum class MenuState {
12 Closed,
13 Opening,
14 Open,
15 Closing
16};
17
18struct MenuItem {
19 std::string text;
20 std::function<void(Game&)> activationFunction;
21};
22
23class Menu {
24public:
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
37private:
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
594void 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
672void 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
168private: 170private:
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 */