From 9bc9c9007f8a433d5c0ac9e05093ee0d21d92724 Mon Sep 17 00:00:00 2001 From: "Zed A. Shaw" Date: Mon, 11 Nov 2024 12:23:40 -0500 Subject: [PATCH] Now have a nice panel to hold all the UI panels we'll use later. --- ansi_parser.cpp | 52 +++++++++++++++++++------------------------ ansi_parser.hpp | 1 - ansi_parser.rl | 6 ----- gui.cpp | 35 +++++++++-------------------- gui.hpp | 8 +++---- meson.build | 2 ++ panel.cpp | 24 ++++++++++++++++++++ panel.hpp | 39 ++++++++++++++++++++++++++++++++ render.cpp | 26 +++++++++++----------- render.hpp | 7 +++--- status.txt | 1 + tests/ansi_parser.cpp | 5 ++++- 12 files changed, 123 insertions(+), 83 deletions(-) create mode 100644 panel.cpp create mode 100644 panel.hpp diff --git a/ansi_parser.cpp b/ansi_parser.cpp index 49de455..d33c9e5 100644 --- a/ansi_parser.cpp +++ b/ansi_parser.cpp @@ -2,7 +2,6 @@ #line 1 "ansi_parser.rl" #include #include -#include #include "dbc.hpp" #include #include "ansi_parser.hpp" @@ -10,11 +9,11 @@ using namespace fmt; -#line 81 "ansi_parser.rl" +#line 80 "ansi_parser.rl" -#line 13 "ansi_parser.cpp" +#line 12 "ansi_parser.cpp" static const char _foo_actions[] = { 0, 1, 0, 1, 3, 1, 4, 1, 5, 1, 6, 1, 7, 1, 11, 1, @@ -85,7 +84,7 @@ static const int foo_error = 0; static const int foo_en_main = 19; -#line 84 "ansi_parser.rl" +#line 83 "ansi_parser.rl" #include @@ -99,11 +98,6 @@ ANSIParser::ANSIParser(sf::Color default_fg, sf::Color default_bg) : } } -bool ANSIParser::parse(const std::string &screen, WriteCB write) { - std::wstring screen_utf8 = $converter.from_bytes(screen); - return parse(screen_utf8, write); -} - bool ANSIParser::parse(std::wstring_view codes, WriteCB write) { const wchar_t *start = NULL; int cs = 0; @@ -116,14 +110,14 @@ bool ANSIParser::parse(std::wstring_view codes, WriteCB write) { sf::Color &target = color; -#line 111 "ansi_parser.cpp" +#line 105 "ansi_parser.cpp" { cs = foo_start; } -#line 114 "ansi_parser.rl" +#line 108 "ansi_parser.rl" -#line 114 "ansi_parser.cpp" +#line 108 "ansi_parser.cpp" { int _klen; unsigned int _trans; @@ -197,13 +191,13 @@ _match: switch ( *_acts++ ) { case 0: -#line 14 "ansi_parser.rl" +#line 13 "ansi_parser.rl" { start = p; } break; case 1: -#line 18 "ansi_parser.rl" +#line 17 "ansi_parser.rl" { value = 0; size_t len = p - start; @@ -227,56 +221,56 @@ _match: } break; case 2: -#line 40 "ansi_parser.rl" +#line 39 "ansi_parser.rl" { } break; case 3: -#line 41 "ansi_parser.rl" +#line 40 "ansi_parser.rl" { target = color; } break; case 4: -#line 44 "ansi_parser.rl" +#line 43 "ansi_parser.rl" { target = bgcolor; } break; case 5: -#line 48 "ansi_parser.rl" +#line 47 "ansi_parser.rl" { write(bgcolor, color, (*p)); } break; case 6: -#line 52 "ansi_parser.rl" +#line 51 "ansi_parser.rl" { color = $default_fg; } break; case 7: -#line 53 "ansi_parser.rl" +#line 52 "ansi_parser.rl" { bgcolor = $default_bg; } break; case 8: -#line 55 "ansi_parser.rl" +#line 54 "ansi_parser.rl" { target.r = value; } break; case 9: -#line 56 "ansi_parser.rl" +#line 55 "ansi_parser.rl" { target.g = value; } break; case 10: -#line 57 "ansi_parser.rl" +#line 56 "ansi_parser.rl" { target.b = value; } break; case 11: -#line 58 "ansi_parser.rl" +#line 57 "ansi_parser.rl" { value = 0; } break; case 12: -#line 59 "ansi_parser.rl" +#line 58 "ansi_parser.rl" { } break; -#line 253 "ansi_parser.cpp" +#line 247 "ansi_parser.cpp" } } @@ -293,10 +287,10 @@ _again: while ( __nacts-- > 0 ) { switch ( *__acts++ ) { case 12: -#line 59 "ansi_parser.rl" +#line 58 "ansi_parser.rl" { } break; -#line 271 "ansi_parser.cpp" +#line 265 "ansi_parser.cpp" } } } @@ -304,7 +298,7 @@ _again: _out: {} } -#line 115 "ansi_parser.rl" +#line 109 "ansi_parser.rl" return p - pe == 0; } diff --git a/ansi_parser.hpp b/ansi_parser.hpp index b3239d9..77755c7 100644 --- a/ansi_parser.hpp +++ b/ansi_parser.hpp @@ -16,6 +16,5 @@ public: // disable copying ANSIParser(ANSIParser& ap) = delete; - bool parse(const std::string &screen, WriteCB write); bool parse(std::wstring_view codes, WriteCB write); }; diff --git a/ansi_parser.rl b/ansi_parser.rl index 7ba283f..21d7174 100644 --- a/ansi_parser.rl +++ b/ansi_parser.rl @@ -1,6 +1,5 @@ #include #include -#include #include "dbc.hpp" #include #include "ansi_parser.hpp" @@ -94,11 +93,6 @@ ANSIParser::ANSIParser(sf::Color default_fg, sf::Color default_bg) : } } -bool ANSIParser::parse(const std::string &screen, WriteCB write) { - std::wstring screen_utf8 = $converter.from_bytes(screen); - return parse(screen_utf8, write); -} - bool ANSIParser::parse(std::wstring_view codes, WriteCB write) { const wchar_t *start = NULL; int cs = 0; diff --git a/gui.cpp b/gui.cpp index d49776a..3b1b2de 100644 --- a/gui.cpp +++ b/gui.cpp @@ -32,9 +32,9 @@ using namespace components; GUI::GUI(DinkyECS::World &world, Map& game_map) : $game_map(game_map), $log({{"Welcome to the game!"}}), + $status_ui(SCREEN_X, SCREEN_Y, 0, 0), + $map_view(0, 0, GAME_MAP_POS, 0, false), $view_port{0,0}, - $status_screen(SCREEN_X, SCREEN_Y), - $map_screen(0,0), $world(world), $sounds("./assets"), $renderer() @@ -52,7 +52,7 @@ void GUI::resize_map(int new_size) { if($renderer.resize_map(new_size, $view_port)) { // set canvas to best size $canvas = Canvas($view_port.x * 2, $view_port.y * 4); - $map_screen = Screen($view_port.x, $view_port.y); + $map_view.resize($view_port.x, $view_port.y); } } @@ -65,17 +65,12 @@ void GUI::create_renderer() { Terminal::SetColorSupport(Terminal::Color::TrueColor); auto player = $world.get_the(); - $map_view = Renderer([&] { + $map_view.set_renderer([&] { System::draw_map($world, $game_map, $canvas, $view_port.x, $view_port.y); return canvas($canvas); }); - $prompt = Renderer([&] { - return hbox({hflow(vbox(text("HELLO!")))}) | border; - }); - - - $status_ui = Renderer([&, player]{ + $status_ui.set_renderer([&, player]{ const auto& player_combat = $world.get(player.entity); const auto& inventory = $world.get(player.entity); $status_text = player_combat.hp > 0 ? "NOT DEAD" : "DEAD!!!!!!"; @@ -194,10 +189,10 @@ void GUI::run_systems() { void GUI::shake() { for(int i = 0; i < 10; ++i) { - int x = Random::uniform(-10,10); - int y = Random::uniform(-10,10); + int x = Random::uniform(-20,20); + int y = Random::uniform(-20,20); // add x/y back to draw screen - $renderer.draw_screen($map_screen, x, y); + $renderer.draw_screen($map_view, x, y); std::this_thread::sleep_for(1ms); } } @@ -205,18 +200,8 @@ void GUI::shake() { void GUI::render_scene() { $renderer.clear(); - $status_screen.Clear(); - Render($status_screen, $status_ui->Render()); - $renderer.draw_text_ui($status_screen, 0, 0); - - Render($map_screen, $map_view->Render()); - $renderer.draw_screen($map_screen); - - /* - Screen prompt_screen(30,10); - Render(prompt_screen, $prompt->Render()); - $renderer.draw_text_ui(prompt_screen, 700, 300); - */ + $renderer.draw_text_ui($status_ui); + $renderer.draw_screen($map_view); $renderer.display(); } diff --git a/gui.hpp b/gui.hpp index c11f5a0..4716cb9 100644 --- a/gui.hpp +++ b/gui.hpp @@ -14,6 +14,7 @@ #include "components.hpp" #include "sound.hpp" #include "render.hpp" +#include "panel.hpp" using std::string; using ftxui::Canvas, ftxui::Component, ftxui::Screen; @@ -35,14 +36,11 @@ struct ActionLog { class GUI { string $status_text = "NOT DEAD"; Canvas $canvas; - Component $status_ui; - Component $prompt; - Component $map_view; Map& $game_map; ActionLog $log; + Panel $status_ui; + Panel $map_view; Point $view_port; - Screen $status_screen; - Screen $map_screen; DinkyECS::World& $world; SoundManager $sounds; SFMLRender $renderer; diff --git a/meson.build b/meson.build index 57d6711..43c835e 100644 --- a/meson.build +++ b/meson.build @@ -22,6 +22,7 @@ runtests = executable('runtests', [ 'ansi_parser.cpp', 'config.cpp', 'save.cpp', + 'panel.cpp', 'tests/fsm.cpp', 'tests/dbc.cpp', 'tests/map.cpp', @@ -48,6 +49,7 @@ roguish = executable('roguish', [ 'render.cpp', 'config.cpp', 'save.cpp', + 'panel.cpp', ], dependencies: dependencies) diff --git a/panel.cpp b/panel.cpp new file mode 100644 index 0000000..8069dbc --- /dev/null +++ b/panel.cpp @@ -0,0 +1,24 @@ +#include "panel.hpp" + +void Panel::resize(int width, int height) { + $screen = Screen(width, height); +} + +void Panel::set_renderer(std::function< Element()> render) { + $component = Renderer(render); +} + +Screen &Panel::render() { + if($must_clear) $screen.Clear(); + Render($screen, $component->Render()); + return $screen; +} + +std::wstring Panel::to_string() { + std::string screenout = $screen.ToString(); + return $converter.from_bytes(screenout); +} + +Screen &Panel::screen() { + return $screen; +} diff --git a/panel.hpp b/panel.hpp new file mode 100644 index 0000000..5e64ca2 --- /dev/null +++ b/panel.hpp @@ -0,0 +1,39 @@ +#pragma once +#include // for Render +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using ftxui::Renderer, ftxui::Component, ftxui::Element, ftxui::Screen; + +struct Panel { + int x; + int y; + int width; + int height; + Component $component; + Screen $screen; + bool $must_clear = true; + std::wstring_convert> $converter; + + Panel(int width, int height, int x, int y, bool must_clear=true) : + x(x), + y(y), + width(width), + height(height), + $screen(width, height), + $must_clear(must_clear) + {}; + + void resize(int width, int height); + void set_renderer(std::function< Element()> render); + Screen &render(); + std::wstring to_string(); + Screen &screen(); +}; diff --git a/render.cpp b/render.cpp index 875bdba..c4f8058 100644 --- a/render.cpp +++ b/render.cpp @@ -104,7 +104,7 @@ inline void configure_tile(const sf::Sprite &sprite, sf::FloatRect &sp_bounds, height_delta = bg_bounds.height > sp_bounds.width ? (bg_bounds.height - sp_bounds.height) / 2 : 0; } -void SFMLRender::render_text(std::string &text, float x, float y) { +void SFMLRender::render_text(std::wstring &text, float x, float y) { wchar_t last_tile = '#'; sf::FloatRect sp_bounds; float width_delta = 0; @@ -141,24 +141,24 @@ void SFMLRender::render_text(std::string &text, float x, float y) { }); } -void SFMLRender::draw_text_ui(Screen &screen, float x, float y) { +void SFMLRender::draw_text_ui(Panel &panel) { sf::RectangleShape backing( - sf::Vector2f($ui_bounds.width * screen.dimx(), - $ui_bounds.height * screen.dimy())); + sf::Vector2f($ui_bounds.width * panel.width, + $ui_bounds.height * panel.height)); backing.setFillColor(sf::Color(0, 0, 0)); - backing.setPosition(x, y); + backing.setPosition(panel.x, panel.y); $window.draw(backing); - std::string screenout = screen.ToString(); - std::wstring main_screen_utf8 = $converter.from_bytes(screenout); - - $ui_text.setPosition(x, y); - $ui_text.setString(main_screen_utf8); + panel.render(); + std::wstring panelout = panel.to_string(); + $ui_text.setPosition(panel.x, panel.y); + $ui_text.setString(panelout); $window.draw($ui_text); } -void SFMLRender::draw_screen(Screen &screen, float x, float y) { - std::string screenout = screen.ToString(); - render_text(screenout, GAME_MAP_POS+x, y); +void SFMLRender::draw_screen(Panel &panel, float x, float y) { + panel.render(); + std::wstring panelout = panel.to_string(); + render_text(panelout, panel.x + x, panel.y + y); } diff --git a/render.hpp b/render.hpp index cb4ea53..8719863 100644 --- a/render.hpp +++ b/render.hpp @@ -9,6 +9,7 @@ #include "point.hpp" #include #include "ansi_parser.hpp" +#include "panel.hpp" using ftxui::Canvas, ftxui::Screen; @@ -54,9 +55,9 @@ struct SFMLRender { sf::Color color(Value val); sf::Sprite &get_text_sprite(wchar_t tile); bool resize_map(int new_size, Point &view_port); - void render_text(std::string &text, float x, float y); - void draw_text_ui(Screen &screen, float x, float y); - void draw_screen(Screen &screen, float map_off_x=0.0f, float map_off_y=0.0f); + void render_text(std::wstring &text, float x, float y); + void draw_text_ui(Panel &panel); + void draw_screen(Panel &panel, float map_off_x=0.0f, float map_off_y=0.0f); bool poll_event(sf::Event &event) { return $window.pollEvent(event); diff --git a/status.txt b/status.txt index 0e0fea7..00b1fd2 100644 --- a/status.txt +++ b/status.txt @@ -2,6 +2,7 @@ NOTES: TODO: +* camera shake broken * draw_screen doesn't do x axis offset render * Can std::any be defaulted to a noop in the events? * Save file isn't saving gold. diff --git a/tests/ansi_parser.cpp b/tests/ansi_parser.cpp index f882487..7cf84e5 100644 --- a/tests/ansi_parser.cpp +++ b/tests/ansi_parser.cpp @@ -56,11 +56,14 @@ TEST_CASE("test out ragel parser", "[gui]") { // this sets the Truecolor so need to do it first ANSIParser ansi(default_fg, default_bg); + std::wstring_convert> $converter; std::string colors = generate_colors(); + std::wstring colors_utf = $converter.from_bytes(colors); + std::cout << colors; - bool good = ansi.parse(colors, [&](sf::Color bgcolor, sf::Color color, wchar_t ch) { + bool good = ansi.parse(colors_utf, [&](sf::Color bgcolor, sf::Color color, wchar_t ch) { bool correct_char = ch == '#' || ch == ' ' || ch == '\n' || ch == '\r'; REQUIRE(correct_char); });