From e57a13846f24fcc7c03489a78dacfa980f8096bf Mon Sep 17 00:00:00 2001 From: "Zed A. Shaw" Date: Mon, 21 Oct 2024 22:43:34 -0400 Subject: [PATCH] A bit more caching and optimization then determine how to center glyphs in the center of the background if it fits. --- gui.cpp | 89 ++++++++++++++++++++++++++++++++++----------------------- gui.hpp | 4 ++- 2 files changed, 57 insertions(+), 36 deletions(-) diff --git a/gui.cpp b/gui.cpp index 7fec19a..c279663 100644 --- a/gui.cpp +++ b/gui.cpp @@ -55,7 +55,9 @@ GUI::GUI() : $window(sf::VideoMode(VIDEO_X,VIDEO_Y), "Roguish"), $screen(SCREEN_X, SCREEN_Y), $map_screen(0,0), - $map_font_size(BASE_MAP_FONT_SIZE) + $view_port{0,0}, + $map_font_size(BASE_MAP_FONT_SIZE), + $line_spacing(0) { $font.loadFromFile("./assets/text.otf"); resize_map(BASE_MAP_FONT_SIZE); @@ -131,7 +133,6 @@ bool GUI::handle_events() { sf::Sprite &GUI::get_text_sprite(wchar_t tile) { if(!$sprites.contains(tile)) { - $sprites.clear(); sf::Glyph glyph = $font.getGlyph(tile, $map_font_size, false); // WARNING! we actually have to do this here because SFML caches // the glyphs on the font texture, so this gets loaded each time @@ -154,9 +155,11 @@ void GUI::run_systems() { void GUI::resize_map(int new_size) { if(MIN_FONT_SIZE < new_size && new_size < MAX_FONT_SIZE) { + $sprites.clear(); // need to reset the sprites for the new size $map_font_size = new_size; - sf::Glyph base_glyph = $font.getGlyph(L'█', $map_font_size, false); - auto bounds = base_glyph.bounds; + $base_glyph = $font.getGlyph(L'█', $map_font_size, false); + auto bounds = $base_glyph.bounds; + $line_spacing = $font.getLineSpacing($map_font_size); $view_port = { size_t(std::ceil((VIDEO_X - GAME_MAP_POS) / bounds.width)), size_t(std::ceil(VIDEO_Y / bounds.height)) @@ -179,48 +182,64 @@ void GUI::draw_screen(bool clear, float map_off_x, float map_off_y) { float y = 0.0f; float x = GAME_MAP_POS; - const float line_spacing = $font.getLineSpacing($map_font_size); - sf::Glyph base_glyph = $font.getGlyph(L'█', $map_font_size, false); + // make a copy so we don't modify the cached one auto bg_sprite = get_text_sprite(L'█'); + auto bg_bounds = bg_sprite.getLocalBounds(); bg_sprite.setColor(sf::Color(20,20,20)); auto add_sprite = get_text_sprite(L'!'); bool has_add = false; for(size_t i = 0; i < map_screen_utf8.size(); i++) { wchar_t tile = map_screen_utf8[i]; - sf::Sprite &sprite = get_text_sprite(tile); - sprite.setPosition({x, y}); - bg_sprite.setPosition({x, y}); - - if(tile == L'█') { - sprite.setColor(sf::Color(80,80,80)); - } else if(tile == L'☺') { - sprite.setColor(sf::Color::Blue); - } else if(tile == L'Ω') { - sprite.setColor(sf::Color::Red); - add_sprite.setColor(sf::Color::Red); - add_sprite.setPosition({x-3,y-3}); - has_add = true; - } else if(tile == L'#') { - sprite.setColor(sf::Color(5,5,5)); - } else if(tile == L'\r') { - continue; // skip these, just windows junk - } else if(tile == L'\n') { - // newline - y += line_spacing; + + if(tile == L'\n') { + // don't bother processing newlines, just skip + y += $line_spacing; x = GAME_MAP_POS; - continue; + } else if(tile == L'\r') { + continue; // skip these, just windows junk } else { - sprite.setColor(color(Value::MID)); - } + // it's a visual cell + bg_sprite.setPosition({x, y}); + sf::Sprite &sprite = get_text_sprite(tile); + + // should look into caching all this instead of calcing it each time + auto sp_bounds = sprite.getLocalBounds(); + + // calculate where to center the sprite, but only if it's smaller + auto width_delta = bg_bounds.width > sp_bounds.width ? (bg_bounds.width - sp_bounds.width) / 2 : 0; + auto height_delta = bg_bounds.height > sp_bounds.width ? (bg_bounds.height - sp_bounds.height) / 2 : 0; + + // TODO: need to center it inside the bg_sprite + sprite.setPosition({x+width_delta, y+height_delta}); + + if(tile == L'█') { + sprite.setColor(sf::Color(80,80,80)); + } else if(tile == L'☺') { + sprite.setColor(sf::Color::Blue); + } else if(tile == L'Ω') { + sprite.setColor(sf::Color::Red); + // HACK: just playing with adding multiple characters for drawing + add_sprite.setColor(sf::Color::Red); + add_sprite.setPosition({x-3,y-3}); + has_add = true; + } else if(tile == L'#') { + sprite.setColor(sf::Color(5,5,5)); + } else { + sprite.setColor(color(Value::MID)); + } - $window.draw(bg_sprite); - $window.draw(sprite); - if(has_add) { - $window.draw(add_sprite); - has_add = false; + // now draw the background sprite and sprite + // TODO: this can become a standard sprite description + $window.draw(bg_sprite); + $window.draw(sprite); + if(has_add) { + $window.draw(add_sprite); + has_add = false; + } + // next cell + x += $base_glyph.advance; } - x += base_glyph.advance; } $window.display(); diff --git a/gui.hpp b/gui.hpp index 1e77333..a5458ba 100644 --- a/gui.hpp +++ b/gui.hpp @@ -52,8 +52,10 @@ class GUI { DinkyECS::World $world; sf::Texture $font_texture; std::unordered_map $sprites; - Point $view_port = {0,0}; + Point $view_port; int $map_font_size; + sf::Glyph $base_glyph; + float $line_spacing; public: GUI();