Renderer is now more standalone and doesn't try to protect against small maps, that's the GUI's job.

main
Zed A. Shaw 2 days ago
parent 19b8bf1850
commit 15a302d133
  1. 2
      Makefile
  2. 16
      gui.cpp
  3. 7
      gui.hpp
  4. 2
      main.cpp
  5. 8
      map.hpp
  6. 4
      panel.cpp
  7. 2
      panel.hpp
  8. 58
      render.cpp
  9. 25
      render.hpp
  10. 18
      scratchpad/img2ansi.cpp
  11. 3
      status.txt

@ -27,4 +27,4 @@ clean:
meson compile --clean -C builddir meson compile --clean -C builddir
debug: debug:
gdb --nx -x .gdbinit builddir/img2ansi.exe gdb --nx -x .gdbinit builddir/roguish.exe

@ -22,19 +22,20 @@
#include "render.hpp" #include "render.hpp"
#include "save.hpp" #include "save.hpp"
const int MAX_FONT_SIZE = 140;
const int MIN_FONT_SIZE = 20;
using std::string; using std::string;
using namespace fmt; using namespace fmt;
using namespace std::chrono_literals; using namespace std::chrono_literals;
using namespace ftxui; using namespace ftxui;
using namespace components; using namespace components;
GUI::GUI(DinkyECS::World &world, Map& game_map) : GUI::GUI(DinkyECS::World &world, Map& game_map) :
$game_map(game_map), $game_map(game_map),
$log({{"Welcome to the game!"}}), $log({{"Welcome to the game!"}}),
$status_ui(SCREEN_X, SCREEN_Y, 0, 0), $status_ui(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT),
$map_view(0, 0, GAME_MAP_POS, 0, true), $map_view(GAME_MAP_POS, 0, 0, 0, true),
$view_port{0,0},
$world(world), $world(world),
$sounds("./assets"), $sounds("./assets"),
$renderer() $renderer()
@ -49,10 +50,9 @@ GUI::GUI(DinkyECS::World &world, Map& game_map) :
} }
void GUI::resize_map(int new_size) { void GUI::resize_map(int new_size) {
if($renderer.resize_grid(new_size, $view_port)) { if($renderer.resize_grid(new_size, $map_view)) {
// set canvas to best size // set canvas to best size
$canvas = Canvas($view_port.x * 2, $view_port.y * 4); $canvas = Canvas($map_view.width * 2, $map_view.height * 4);
$map_view.resize($view_port.x, $view_port.y);
} }
} }
@ -66,7 +66,7 @@ void GUI::create_renderer() {
auto player = $world.get_the<Player>(); auto player = $world.get_the<Player>();
$map_view.set_renderer(Renderer([&] { $map_view.set_renderer(Renderer([&] {
System::draw_map($world, $game_map, $canvas, $view_port.x, $view_port.y); System::draw_map($world, $game_map, $canvas, $map_view.width, $map_view.height);
return canvas($canvas); return canvas($canvas);
})); }));

@ -22,8 +22,8 @@
using std::string; using std::string;
using ftxui::Canvas, ftxui::Component, ftxui::Screen, ftxui::Button; using ftxui::Canvas, ftxui::Component, ftxui::Screen, ftxui::Button;
constexpr int SCREEN_X = 40; constexpr int SCREEN_WIDTH = 40;
constexpr int SCREEN_Y = 30; constexpr int SCREEN_HEIGHT = 30;
struct ActionLog { struct ActionLog {
std::deque<std::string> messages; std::deque<std::string> messages;
@ -36,6 +36,8 @@ struct ActionLog {
} }
}; };
const int GAME_MAP_POS = 600;
class GUI { class GUI {
string $status_text = "NOT DEAD"; string $status_text = "NOT DEAD";
Canvas $canvas; Canvas $canvas;
@ -44,7 +46,6 @@ class GUI {
Panel $status_ui; Panel $status_ui;
Panel $map_view; Panel $map_view;
bool $show_modal = false; bool $show_modal = false;
Point $view_port;
Component $test_button; Component $test_button;
DinkyECS::World& $world; DinkyECS::World& $world;
SoundManager $sounds; SoundManager $sounds;

@ -53,6 +53,8 @@ void configure_world(DinkyECS::World &world, Map &game_map) {
world.set<Tile>(gold, {"$"}); world.set<Tile>(gold, {"$"});
} }
const int GAME_MAP_X = 40;
const int GAME_MAP_Y = 40;
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
#if defined(_WIN64) || defined(_WIN32) #if defined(_WIN64) || defined(_WIN32)

@ -13,9 +13,6 @@
#define WALL_VALUE 1 #define WALL_VALUE 1
#define SPACE_VALUE 0 #define SPACE_VALUE 0
constexpr int GAME_MAP_X = 40;
constexpr int GAME_MAP_Y = 40;
struct Room { struct Room {
size_t x = 0; size_t x = 0;
size_t y = 0; size_t y = 0;
@ -101,8 +98,9 @@ public:
int center_x = int(around.x - view_x / 2); int center_x = int(around.x - view_x / 2);
int center_y = int(around.y - view_y / 2); int center_y = int(around.y - view_y / 2);
size_t start_x = std::clamp(center_x, 0, high_x); // BUG: is clamp really the best thing here? this seems wrong.
size_t start_y = std::clamp(center_y, 0, high_y); size_t start_x = high_x > 0 ? std::clamp(center_x, 0, high_x) : 0;
size_t start_y = high_y > 0 ? std::clamp(center_y, 0, high_y) : 0;
return {start_x, start_y}; return {start_x, start_y};
} }

@ -1,7 +1,9 @@
#include "panel.hpp" #include "panel.hpp"
void Panel::resize(int width, int height) { void Panel::resize(int w, int h) {
$dirty = true; $dirty = true;
width = w;
height = h;
$screen = Screen(width, height); $screen = Screen(width, height);
} }

@ -33,7 +33,7 @@ struct Panel {
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> $converter; std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> $converter;
std::wstring $screenout; std::wstring $screenout;
Panel(int width, int height, int x, int y, bool is_grid=false) : Panel(int x, int y, int width, int height, bool is_grid=false) :
x(x), x(x),
y(y), y(y),
width(width), width(width),

@ -10,7 +10,7 @@
using namespace fmt; using namespace fmt;
SFMLRender::SFMLRender() : SFMLRender::SFMLRender() :
$window(sf::VideoMode(VIDEO_X,VIDEO_Y), "Roguish"), $window(sf::VideoMode($config.video_x,$config.video_y), "Roguish"),
$map_font_size(0), $map_font_size(0),
$line_spacing(0), $line_spacing(0),
$default_fg(color::LIGHT_MID), $default_fg(color::LIGHT_MID),
@ -22,9 +22,9 @@ SFMLRender::SFMLRender() :
$font.setSmooth(false); $font.setSmooth(false);
$ui_text.setFont($font); $ui_text.setFont($font);
$ui_text.setPosition(0,0); $ui_text.setPosition(0,0);
$ui_text.setCharacterSize(UI_FONT_SIZE); $ui_text.setCharacterSize($config.ui_font_size);
$ui_text.setFillColor(color::LIGHT_MID); $ui_text.setFillColor(color::LIGHT_MID);
sf::Glyph glyph = $font.getGlyph(UI_BASE_CHAR, UI_FONT_SIZE, false); sf::Glyph glyph = $font.getGlyph($config.ui_base_char, $config.ui_font_size, false);
$ui_bounds = glyph.bounds; $ui_bounds = glyph.bounds;
} }
@ -43,47 +43,21 @@ sf::Sprite &SFMLRender::get_text_sprite(wchar_t tile) {
return $sprites[tile]; return $sprites[tile];
} }
inline bool base_glyph_check(sf::Font &font, sf::Glyph &base_glyph, Point &view_port, int &font_size, int new_size) {
auto glyph = font.getGlyph(BG_TILE, new_size, false);
int view_x = std::ceil((VIDEO_X - GAME_MAP_POS) / glyph.bounds.width); bool SFMLRender::resize_grid(int new_size, Panel &panel_out) {
int view_y = std::ceil(VIDEO_Y / glyph.bounds.height); auto glyph = $font.getGlyph($config.bg_tile, new_size, false);
int view_x = std::ceil(($config.video_x - panel_out.x) / glyph.bounds.width);
int view_y = std::ceil(($config.video_y - panel_out.y) / glyph.bounds.height);
// don't allow resizing beyond/below game map size
if(view_x <= GAME_MAP_X && view_y <= GAME_MAP_Y) {
// looks good, set 'em all // looks good, set 'em all
base_glyph = glyph; $base_glyph = glyph;
view_port = {size_t(view_x), size_t(view_y)}; $map_font_size = new_size;
font_size = new_size;
return true;
} else {
println("VIEW TOO BIG, view={},{} MAP={},{}", view_x, view_y,
GAME_MAP_X, GAME_MAP_Y);
return false;
}
}
bool SFMLRender::resize_grid(int new_size, Point &view_port) {
if($map_font_size == new_size || new_size < MIN_FONT_SIZE || new_size > MAX_FONT_SIZE) {
println("invalid map font size {}, =={}, min={}, max={}",
new_size, $map_font_size, MIN_FONT_SIZE, MAX_FONT_SIZE);
return false;
} else {
println("NEW SIZE SELECTED {}", new_size);
}
if(base_glyph_check($font, $base_glyph, view_port, $map_font_size, new_size)) {
$sprites.clear(); // need to reset the sprites for the new size $sprites.clear(); // need to reset the sprites for the new size
$line_spacing = $font.getLineSpacing($map_font_size); $line_spacing = $font.getLineSpacing($map_font_size);
$bg_sprite = get_text_sprite(BG_TILE); $bg_sprite = get_text_sprite($config.bg_tile);
$bg_bounds = $bg_sprite.getLocalBounds(); $bg_bounds = $bg_sprite.getLocalBounds();
panel_out.resize(view_x, view_y);
return true; return true;
} else {
println("BASE GLYPH FAILED!");
// something else here
return false;
}
} }
inline void configure_tile(const sf::Sprite &sprite, sf::FloatRect &sp_bounds, sf::FloatRect bg_bounds, float &width_delta, float &height_delta) { inline void configure_tile(const sf::Sprite &sprite, sf::FloatRect &sp_bounds, sf::FloatRect bg_bounds, float &width_delta, float &height_delta) {
@ -143,7 +117,7 @@ void SFMLRender::render_grid(const std::wstring &text, float x, float y) {
inline sf::FloatRect draw_chunk(sf::RenderWindow& window, inline sf::FloatRect draw_chunk(sf::RenderWindow& window,
sf::FloatRect ui_bounds, sf::Text& text, sf::Color default_bg, sf::FloatRect ui_bounds, sf::Text& text, sf::Color default_bg,
sf::Color bgcolor, float x, float y, std::wstring &out) sf::Color bgcolor, int bg_box_offset, float x, float y, std::wstring &out)
{ {
text.setString(out); text.setString(out);
text.setPosition({x, y}); text.setPosition({x, y});
@ -152,7 +126,7 @@ inline sf::FloatRect draw_chunk(sf::RenderWindow& window,
if(default_bg != bgcolor) { if(default_bg != bgcolor) {
sf::RectangleShape backing({bounds.width, bounds.height}); sf::RectangleShape backing({bounds.width, bounds.height});
backing.setFillColor(bgcolor); backing.setFillColor(bgcolor);
backing.setPosition({bounds.left, bounds.top + BG_BOX_OFFSET}); backing.setPosition({bounds.left, bounds.top + bg_box_offset});
window.draw(backing); window.draw(backing);
} }
@ -175,7 +149,7 @@ void SFMLRender::render_text(const std::wstring &text, sf::Color default_bg, flo
if(out.size() > 0 ) { if(out.size() > 0 ) {
auto bounds = draw_chunk($window, auto bounds = draw_chunk($window,
$ui_bounds, $ui_text, $ui_bounds, $ui_text,
default_bg, cur_bg, x, y, out); default_bg, cur_bg, $config.bg_box_offset, x, y, out);
x += bounds.width; x += bounds.width;
} }
cur_bg = bg; cur_bg = bg;
@ -189,7 +163,7 @@ void SFMLRender::render_text(const std::wstring &text, sf::Color default_bg, flo
if(out.size() > 0) { if(out.size() > 0) {
bounds = draw_chunk($window, $ui_bounds, bounds = draw_chunk($window, $ui_bounds,
$ui_text, default_bg, cur_bg, x, y, out); $ui_text, default_bg, cur_bg, $config.bg_box_offset, x, y, out);
} else { } else {
bounds = $ui_text.getLocalBounds(); bounds = $ui_text.getLocalBounds();
} }
@ -206,7 +180,7 @@ void SFMLRender::render_text(const std::wstring &text, sf::Color default_bg, flo
); );
if(out.size() > 0) { if(out.size() > 0) {
draw_chunk($window, $ui_bounds, $ui_text, default_bg, cur_bg, x, y, out); draw_chunk($window, $ui_bounds, $ui_text, default_bg, cur_bg, $config.bg_box_offset, x, y, out);
} }
} }

@ -13,18 +13,21 @@
using ftxui::Canvas, ftxui::Screen; using ftxui::Canvas, ftxui::Screen;
const int VIDEO_X = 1600;
const int VIDEO_Y = 900; struct RenderConfig {
const int MIN_FONT_SIZE = 20; int video_x = 1600;
const int MAX_FONT_SIZE = 140; int video_y = 900;
const int GAME_MAP_POS = 600; int ui_font_size=30;
const int UI_FONT_SIZE=30; int base_map_font_size=90;
const int BASE_MAP_FONT_SIZE=90; wchar_t bg_tile = L'';
const wchar_t BG_TILE = L''; wchar_t ui_base_char = L'';
const wchar_t UI_BASE_CHAR = L''; int bg_box_offset=5;
const int BG_BOX_OFFSET=5; int game_map_x=40;
int game_map_y=40;
};
struct SFMLRender { struct SFMLRender {
RenderConfig $config;
sf::RenderWindow $window; sf::RenderWindow $window;
int $map_font_size; int $map_font_size;
float $line_spacing; float $line_spacing;
@ -47,7 +50,7 @@ struct SFMLRender {
SFMLRender(SFMLRender &other) = delete; SFMLRender(SFMLRender &other) = delete;
sf::Sprite &get_text_sprite(wchar_t tile); sf::Sprite &get_text_sprite(wchar_t tile);
bool resize_grid(int new_size, Point &view_port); bool resize_grid(int new_size, Panel &panel_out);
void render_grid(const std::wstring &text, float x, float y); void render_grid(const std::wstring &text, float x, float y);
void render_text(const std::wstring &text, sf::Color bgcolor, float x, float y); void render_text(const std::wstring &text, sf::Color bgcolor, float x, float y);

@ -81,11 +81,10 @@ int main(int argc, char *argv[]) {
// divide the image into cells // divide the image into cells
auto size = image.getSize(); auto size = image.getSize();
const int cell = 10; const int cell = 3;
// create a grid panel to hold the cells // create a grid panel to hold the cells
Panel panel(0, 0, GAME_MAP_POS, 0, true); Panel panel(0, 0, 0, 0, true);
Point view_port{0,0};
println("IMAGE SIZE {},{}", size.x, size.y); println("IMAGE SIZE {},{}", size.x, size.y);
RGBColor avg{0,0,0}; RGBColor avg{0,0,0};
@ -124,16 +123,11 @@ int main(int argc, char *argv[]) {
SFMLRender renderer; SFMLRender renderer;
// NEED TO RESIZE FOR IT TO SHOW
// this shows that I need more refinement on the renderer if(renderer.resize_grid(10, panel)) {
// for example, this won't let me do arbitrary resize and println("RESIZED: {},{}", panel.width, panel.height);
// is still locked to the map, but I need arbitrary for the
// scenes
if(renderer.resize_grid(50, view_port)) {
println("RESIZED: {},{}", view_port.x, view_port.y);
// set canvas to best size // set canvas to best size
drawing = Canvas(view_port.x * 2, view_port.y * 4); drawing = Canvas(panel.width * 2, panel.height * 4);
panel.resize(view_port.x, view_port.y);
} }
panel.set_renderer(Renderer([&]{ panel.set_renderer(Renderer([&]{

@ -1,7 +1,8 @@
TODAY'S GOAL: TODAY'S GOAL:
* panels and everything except renderer should use character coodinates
* Image -> Text converter. * Image -> Text converter.
* Renderer needs to not have fixed setting for its size from the map.
* Refactor out GAME_MAP_* to be a parameter.
TODO: TODO:

Loading…
Cancel
Save