diff --git a/ansi_parser.cpp b/ansi_parser.cpp index e490c63..4934304 100644 --- a/ansi_parser.cpp +++ b/ansi_parser.cpp @@ -10,7 +10,7 @@ using namespace fmt; -#line 105 "ansi_parser.rl" +#line 107 "ansi_parser.rl" @@ -96,7 +96,7 @@ static const int foo_error = 0; static const int foo_en_main = 23; -#line 108 "ansi_parser.rl" +#line 110 "ansi_parser.rl" #include @@ -127,7 +127,7 @@ bool ANSIParser::parse(std::wstring_view codes, ColorCB color_cb, WriteCB write_ cs = foo_start; } -#line 133 "ansi_parser.rl" +#line 135 "ansi_parser.rl" #line 120 "ansi_parser.cpp" { @@ -267,8 +267,8 @@ _match: case 8: #line 56 "ansi_parser.rl" { - color = {100,100,100}; // UNDO THIS - bgcolor = $default_bg; // THIS TOO + color = $default_bg; + bgcolor = $default_fg; color_cb(color, bgcolor); } break; @@ -283,29 +283,31 @@ _match: case 10: #line 66 "ansi_parser.rl" { + color = sf::Color(100,100,100); + color_cb(color, bgcolor); } break; case 11: -#line 69 "ansi_parser.rl" +#line 71 "ansi_parser.rl" { target.r = value; } break; case 12: -#line 70 "ansi_parser.rl" +#line 72 "ansi_parser.rl" { target.g = value; } break; case 13: -#line 71 "ansi_parser.rl" +#line 73 "ansi_parser.rl" { target.b = value; } break; case 14: -#line 72 "ansi_parser.rl" +#line 74 "ansi_parser.rl" { value = 0; } break; case 15: -#line 73 "ansi_parser.rl" +#line 75 "ansi_parser.rl" {} break; -#line 279 "ansi_parser.cpp" +#line 281 "ansi_parser.cpp" } } @@ -322,10 +324,10 @@ _again: while ( __nacts-- > 0 ) { switch ( *__acts++ ) { case 15: -#line 73 "ansi_parser.rl" +#line 75 "ansi_parser.rl" {} break; -#line 297 "ansi_parser.cpp" +#line 299 "ansi_parser.cpp" } } } @@ -333,7 +335,7 @@ _again: _out: {} } -#line 134 "ansi_parser.rl" +#line 136 "ansi_parser.rl" bool good = p - pe == 0; diff --git a/ansi_parser.rl b/ansi_parser.rl index 4327cbb..cbe829d 100644 --- a/ansi_parser.rl +++ b/ansi_parser.rl @@ -54,8 +54,8 @@ using namespace fmt; action reset_fg { color = $default_fg; } action reset_bg { bgcolor = $default_bg; } action invert { - color = {100,100,100}; // UNDO THIS - bgcolor = $default_bg; // THIS TOO + color = $default_bg; + bgcolor = $default_fg; color_cb(color, bgcolor); } action reset_invert { @@ -64,6 +64,8 @@ using namespace fmt; color_cb(color, bgcolor); } action half_bright { + color = sf::Color(100,100,100); + color_cb(color, bgcolor); } action red { target.r = value; } diff --git a/render.cpp b/render.cpp index 0ca52a0..3346e39 100644 --- a/render.cpp +++ b/render.cpp @@ -43,7 +43,7 @@ SFMLRender::SFMLRender() : $ui_text.setPosition(0,0); $ui_text.setCharacterSize(UI_FONT_SIZE); $ui_text.setFillColor(color(Value::LIGHT_MID)); - sf::Glyph glyph = $font.getGlyph(L'█', UI_FONT_SIZE, false); + sf::Glyph glyph = $font.getGlyph(UI_BASE_CHAR, UI_FONT_SIZE, false); $ui_bounds = glyph.bounds; } @@ -148,11 +148,22 @@ void SFMLRender::render_grid(const std::wstring &text, float x, float y) { }); } -inline sf::FloatRect draw_chunk(sf::RenderWindow& window, sf::Text& text, float x, float y, std::wstring &out) { +inline sf::FloatRect draw_chunk(sf::RenderWindow& window, + sf::FloatRect ui_bounds, sf::Text& text, + sf::Color bgcolor, float x, float y, std::wstring &out) +{ text.setString(out); - text.setPosition(x, y); - sf::FloatRect bounds = text.getLocalBounds(); - // need left,top,width,height for box to be accurate + text.setPosition({x, y}); + // get a base character for the cell size + sf::FloatRect bounds(x, y, ui_bounds.width * out.size(), ui_bounds.height); + sf::RectangleShape backing({bounds.width, bounds.height}); + backing.setFillColor(bgcolor); + backing.setPosition({bounds.left, bounds.top + BG_BOX_OFFSET}); +#ifdef DEBUG + backing.setOutlineColor(int(y) % 4 ? sf::Color::Red : sf::Color::Yellow); + backing.setOutlineThickness(1); +#endif + window.draw(backing); window.draw(text); out.clear(); return bounds; @@ -162,10 +173,7 @@ void SFMLRender::render_text(const std::wstring &text, float start_x, float star std::wstring out; float x = start_x; float y = start_y; - enum State { START=1, BUILDING=2 }; - enum Event { NL=1, CHAR=3, SKIP=5 }; - State state = START; - Event event = CHAR; + sf::Color bgcolor = $default_bg; // start with the default_fg until it's changed $ui_text.setFillColor($default_fg); @@ -173,42 +181,38 @@ void SFMLRender::render_text(const std::wstring &text, float start_x, float star $ansi.parse(text, [&](sf::Color fg, sf::Color bg){ if(out.size() > 0 ) { - auto bounds = draw_chunk($window, $ui_text, x, y, out); + auto bounds = draw_chunk($window, $ui_bounds, $ui_text, bgcolor, x, y, out); x += bounds.width; } + bgcolor = bg; $ui_text.setFillColor(fg); }, [&](wchar_t tile) { - if(tile == '\r') event = SKIP; - else if(tile == '\n') event = NL; - else event = CHAR; - - switch(event) { - case SKIP: break; // ignore it - case NL: { - if(state == START) { - state = BUILDING; - } else if(state == BUILDING) { - sf::FloatRect bounds; - - if(out.size() > 0) { - bounds = draw_chunk($window, $ui_text, x, y, out); - } else { - bounds = $ui_text.getLocalBounds(); - } - - y += bounds.height; - x = start_x; // reset to the original position + switch(tile) { + case '\r': break; // ignore it + case '\n': { + sf::FloatRect bounds; + + if(out.size() > 0) { + bounds = draw_chunk($window, $ui_bounds, $ui_text, bgcolor, x, y, out); + } else { + bounds = $ui_text.getLocalBounds(); } + + y += bounds.height; + x = start_x; // reset to the original position } break; - case CHAR: - state = BUILDING; + default: out += tile; break; } } ); + + if(out.size() > 0) { + draw_chunk($window, $ui_bounds, $ui_text, bgcolor, x, y, out); + } } void SFMLRender::draw_text(Panel &panel, bool with_border) { diff --git a/render.hpp b/render.hpp index d0f6f21..e0bbcab 100644 --- a/render.hpp +++ b/render.hpp @@ -13,15 +13,16 @@ using ftxui::Canvas, ftxui::Screen; -#define BG_TILE L'█' - -constexpr int VIDEO_X = 1600; -constexpr int VIDEO_Y = 900; -constexpr int MIN_FONT_SIZE = 20; -constexpr int MAX_FONT_SIZE = 140; -constexpr int GAME_MAP_POS = 600; -constexpr int UI_FONT_SIZE=30; -constexpr int BASE_MAP_FONT_SIZE=90; +const int VIDEO_X = 1600; +const int VIDEO_Y = 900; +const int MIN_FONT_SIZE = 20; +const int MAX_FONT_SIZE = 140; +const int GAME_MAP_POS = 600; +const int UI_FONT_SIZE=30; +const int BASE_MAP_FONT_SIZE=90; +const wchar_t BG_TILE = L'█'; +const wchar_t UI_BASE_CHAR = L'█'; +const int BG_BOX_OFFSET=5; enum class Value { BLACK=0, DARK_DARK, DARK_MID,