From b2d0b0ee4c1c787ac0fd3a173c5ab79c2979f612 Mon Sep 17 00:00:00 2001 From: "Zed A. Shaw" Date: Wed, 9 Jul 2025 13:34:18 -0400 Subject: [PATCH] Map tiles are now correctly sized and positioned. Errors from before were due to floating point being used for positioning. --- Makefile | 5 ++++- assets/map_tiles.png | Bin 5647 -> 5769 bytes tests/map.cpp | 17 +++++++++++++++-- tools/icongen.cpp | 28 +++++++++++++++------------- 4 files changed, 34 insertions(+), 16 deletions(-) diff --git a/Makefile b/Makefile index 4384648..08c53ac 100644 --- a/Makefile +++ b/Makefile @@ -21,6 +21,9 @@ endif build: meson compile -j 10 -C $(ROOT_DIR)/builddir +asset_build: build + ./builddir/icongen + release_build: meson --wipe builddir -Db_ndebug=true --buildtype release meson compile -j 10 -C builddir @@ -33,7 +36,7 @@ tracy_build: meson setup --wipe builddir --buildtype debugoptimized -Dtracy_enable=true -Dtracy:on_demand=true meson compile -j 10 -C builddir -test: build +test: asset_build build ./builddir/runtests "[map-sprite]" run: build test diff --git a/assets/map_tiles.png b/assets/map_tiles.png index b024baaa028f27c38e8062a45ab0757e795285e2..aec7e89eb2ac21f0ff3bb3000eb229777f0642d6 100644 GIT binary patch literal 5769 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 literal 5647 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 X@`iZz&bjcS7fkquery([&](auto, auto &pos, auto &entity_glyph) { + REQUIRE(sprite_coord.contains(entity_glyph.display)); + auto coords = sprite_coord.at(entity_glyph.display); + sf::IntRect square{coords, {size.x, size.y}}; + sf::Sprite sprite{map_sprites, square}; + sprite.setColor({255,150,150,255}); + sprite.setPosition({float(pos.location.x * size.x), float(pos.location.y * size.y)}); + render.draw(sprite); + }); + render.display(); sf::Image out_img = render.getTexture().copyToImage(); bool worked = out_img.saveToFile("map_test.png"); diff --git a/tools/icongen.cpp b/tools/icongen.cpp index aaf2ca5..a06bb7a 100644 --- a/tools/icongen.cpp +++ b/tools/icongen.cpp @@ -33,26 +33,28 @@ struct MapTileBuilder { sf::Glyph $glyph; sf::Font $font{FONT_FILE_NAME}; std::shared_ptr $render = nullptr; - sf::Vector2u $size; - sf::Vector2u $image_size; + sf::Vector2i $size; + sf::Vector2i $image_size; sf::RenderTexture $temp_render; MapTileBuilder(size_t x, size_t y) : $size(x, y), $image_size($size.x * TILE_COUNT, $size.y * TILE_COUNT), - $temp_render($size) + $temp_render({(unsigned int)$size.x, (unsigned int)$size.y}) { $font.setSmooth(false); } - void best_size(wchar_t for_char) { + void best_size(wchar_t for_char, bool centered) { + float factor = centered ? 0.8f : 1.0f; + sf::Vector2i adjusted_size = {int($size.x * factor), int($size.y * factor)}; $font_size = 20; // reset the size // fit the glyph in our box height auto temp = $font.getGlyph(for_char, $font_size, false); auto temp_size = $font_size; - while(temp.textureRect.size.y < int($size.y) - && temp.textureRect.size.x < int($size.x)) + while(temp.textureRect.size.y <= adjusted_size.y + && temp.textureRect.size.x <= adjusted_size.x) { $glyph = temp; $font_size = temp_size; @@ -79,6 +81,7 @@ struct MapTileBuilder { void run(MapConfig& config) { sf::Vector2u crop{$size.x * (unsigned int)config.it.width, $size.y * (unsigned int)config.it.y}; $render = std::make_shared(crop); + $render->clear({0,0,0,0}); $render->setSmooth(false); sf::Vector2f cell_pos{0.0f,0.0f}; @@ -93,7 +96,7 @@ struct MapTileBuilder { wchar_t display_char = config.map[it.y][it.x]; std::wstring content{display_char}; - best_size(display_char); + best_size(display_char, is_centered); sf::Text icon{$font, content, $font_size}; icon.setFillColor({0, 0, 0, 255}); @@ -105,16 +108,15 @@ struct MapTileBuilder { sf::Sprite sprite{font_texture, $glyph.textureRect}; auto t_size = $glyph.textureRect.size; - dbc::check(int($size.x - t_size.x) > 0, "font too big on x"); - dbc::check(int($size.y - t_size.y) > 0, "font too big on y"); + dbc::check($size.x - t_size.x >= 0, "font too big on x"); + dbc::check($size.y - t_size.y >= 0, "font too big on y"); if(is_centered) { sf::Vector2f center{ - (float($size.x) - float(t_size.x)) / 2.0f, - (float($size.y) - float(t_size.y)) / 2.0f}; + float(($size.x - t_size.x) / 2), + float(($size.y - t_size.y) / 2)}; - sf::Vector2f scale{float($size.x) / float(t_size.x) * 0.8f, float($size.y) / float(t_size.y) * 0.8f}; - sprite.setScale(scale); + sprite.setScale({1.0f, 1.0f}); sprite.setPosition({cell_pos.x + center.x, cell_pos.y + center.y}); } else { sf::Vector2f scale{float($size.x) / float(t_size.x), float($size.y) / float(t_size.y)};