Renderer is now more standalone and doesn't try to protect against small maps, that's the GUI's job.
This commit is contained in:
parent
19b8bf1850
commit
15a302d133
11 changed files with 65 additions and 90 deletions
2
Makefile
2
Makefile
|
@ -27,4 +27,4 @@ clean:
|
|||
meson compile --clean -C builddir
|
||||
|
||||
debug:
|
||||
gdb --nx -x .gdbinit builddir/img2ansi.exe
|
||||
gdb --nx -x .gdbinit builddir/roguish.exe
|
||||
|
|
16
gui.cpp
16
gui.cpp
|
@ -22,19 +22,20 @@
|
|||
#include "render.hpp"
|
||||
#include "save.hpp"
|
||||
|
||||
const int MAX_FONT_SIZE = 140;
|
||||
const int MIN_FONT_SIZE = 20;
|
||||
|
||||
using std::string;
|
||||
using namespace fmt;
|
||||
using namespace std::chrono_literals;
|
||||
using namespace ftxui;
|
||||
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, true),
|
||||
$view_port{0,0},
|
||||
$status_ui(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT),
|
||||
$map_view(GAME_MAP_POS, 0, 0, 0, true),
|
||||
$world(world),
|
||||
$sounds("./assets"),
|
||||
$renderer()
|
||||
|
@ -49,10 +50,9 @@ GUI::GUI(DinkyECS::World &world, Map& game_map) :
|
|||
}
|
||||
|
||||
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
|
||||
$canvas = Canvas($view_port.x * 2, $view_port.y * 4);
|
||||
$map_view.resize($view_port.x, $view_port.y);
|
||||
$canvas = Canvas($map_view.width * 2, $map_view.height * 4);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -66,7 +66,7 @@ void GUI::create_renderer() {
|
|||
auto player = $world.get_the<Player>();
|
||||
|
||||
$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);
|
||||
}));
|
||||
|
||||
|
|
7
gui.hpp
7
gui.hpp
|
@ -22,8 +22,8 @@
|
|||
using std::string;
|
||||
using ftxui::Canvas, ftxui::Component, ftxui::Screen, ftxui::Button;
|
||||
|
||||
constexpr int SCREEN_X = 40;
|
||||
constexpr int SCREEN_Y = 30;
|
||||
constexpr int SCREEN_WIDTH = 40;
|
||||
constexpr int SCREEN_HEIGHT = 30;
|
||||
|
||||
struct ActionLog {
|
||||
std::deque<std::string> messages;
|
||||
|
@ -36,6 +36,8 @@ struct ActionLog {
|
|||
}
|
||||
};
|
||||
|
||||
const int GAME_MAP_POS = 600;
|
||||
|
||||
class GUI {
|
||||
string $status_text = "NOT DEAD";
|
||||
Canvas $canvas;
|
||||
|
@ -44,7 +46,6 @@ class GUI {
|
|||
Panel $status_ui;
|
||||
Panel $map_view;
|
||||
bool $show_modal = false;
|
||||
Point $view_port;
|
||||
Component $test_button;
|
||||
DinkyECS::World& $world;
|
||||
SoundManager $sounds;
|
||||
|
|
2
main.cpp
2
main.cpp
|
@ -53,6 +53,8 @@ void configure_world(DinkyECS::World &world, Map &game_map) {
|
|||
world.set<Tile>(gold, {"$"});
|
||||
}
|
||||
|
||||
const int GAME_MAP_X = 40;
|
||||
const int GAME_MAP_Y = 40;
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
#if defined(_WIN64) || defined(_WIN32)
|
||||
|
|
8
map.hpp
8
map.hpp
|
@ -13,9 +13,6 @@
|
|||
#define WALL_VALUE 1
|
||||
#define SPACE_VALUE 0
|
||||
|
||||
constexpr int GAME_MAP_X = 40;
|
||||
constexpr int GAME_MAP_Y = 40;
|
||||
|
||||
struct Room {
|
||||
size_t x = 0;
|
||||
size_t y = 0;
|
||||
|
@ -101,8 +98,9 @@ public:
|
|||
int center_x = int(around.x - view_x / 2);
|
||||
int center_y = int(around.y - view_y / 2);
|
||||
|
||||
size_t start_x = std::clamp(center_x, 0, high_x);
|
||||
size_t start_y = std::clamp(center_y, 0, high_y);
|
||||
// BUG: is clamp really the best thing here? this seems wrong.
|
||||
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};
|
||||
}
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
#include "panel.hpp"
|
||||
|
||||
void Panel::resize(int width, int height) {
|
||||
void Panel::resize(int w, int h) {
|
||||
$dirty = true;
|
||||
width = w;
|
||||
height = h;
|
||||
$screen = Screen(width, height);
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ struct Panel {
|
|||
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> $converter;
|
||||
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),
|
||||
y(y),
|
||||
width(width),
|
||||
|
|
58
render.cpp
58
render.cpp
|
@ -10,7 +10,7 @@
|
|||
using namespace fmt;
|
||||
|
||||
SFMLRender::SFMLRender() :
|
||||
$window(sf::VideoMode(VIDEO_X,VIDEO_Y), "Roguish"),
|
||||
$window(sf::VideoMode($config.video_x,$config.video_y), "Roguish"),
|
||||
$map_font_size(0),
|
||||
$line_spacing(0),
|
||||
$default_fg(color::LIGHT_MID),
|
||||
|
@ -22,9 +22,9 @@ SFMLRender::SFMLRender() :
|
|||
$font.setSmooth(false);
|
||||
$ui_text.setFont($font);
|
||||
$ui_text.setPosition(0,0);
|
||||
$ui_text.setCharacterSize(UI_FONT_SIZE);
|
||||
$ui_text.setCharacterSize($config.ui_font_size);
|
||||
$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;
|
||||
}
|
||||
|
||||
|
@ -43,47 +43,21 @@ sf::Sprite &SFMLRender::get_text_sprite(wchar_t 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);
|
||||
int view_y = std::ceil(VIDEO_Y / glyph.bounds.height);
|
||||
bool SFMLRender::resize_grid(int new_size, Panel &panel_out) {
|
||||
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
|
||||
base_glyph = glyph;
|
||||
view_port = {size_t(view_x), size_t(view_y)};
|
||||
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)) {
|
||||
$base_glyph = glyph;
|
||||
$map_font_size = new_size;
|
||||
$sprites.clear(); // need to reset the sprites for the new 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();
|
||||
panel_out.resize(view_x, view_y);
|
||||
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) {
|
||||
|
@ -143,7 +117,7 @@ void SFMLRender::render_grid(const std::wstring &text, float x, float y) {
|
|||
|
||||
inline sf::FloatRect draw_chunk(sf::RenderWindow& window,
|
||||
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.setPosition({x, y});
|
||||
|
@ -152,7 +126,7 @@ inline sf::FloatRect draw_chunk(sf::RenderWindow& window,
|
|||
if(default_bg != bgcolor) {
|
||||
sf::RectangleShape backing({bounds.width, bounds.height});
|
||||
backing.setFillColor(bgcolor);
|
||||
backing.setPosition({bounds.left, bounds.top + BG_BOX_OFFSET});
|
||||
backing.setPosition({bounds.left, bounds.top + bg_box_offset});
|
||||
window.draw(backing);
|
||||
}
|
||||
|
||||
|
@ -175,7 +149,7 @@ void SFMLRender::render_text(const std::wstring &text, sf::Color default_bg, flo
|
|||
if(out.size() > 0 ) {
|
||||
auto bounds = draw_chunk($window,
|
||||
$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;
|
||||
}
|
||||
cur_bg = bg;
|
||||
|
@ -189,7 +163,7 @@ void SFMLRender::render_text(const std::wstring &text, sf::Color default_bg, flo
|
|||
|
||||
if(out.size() > 0) {
|
||||
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 {
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
25
render.hpp
25
render.hpp
|
@ -13,18 +13,21 @@
|
|||
|
||||
using ftxui::Canvas, ftxui::Screen;
|
||||
|
||||
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;
|
||||
|
||||
struct RenderConfig {
|
||||
int video_x = 1600;
|
||||
int video_y = 900;
|
||||
int ui_font_size=30;
|
||||
int base_map_font_size=90;
|
||||
wchar_t bg_tile = L'█';
|
||||
wchar_t ui_base_char = L'█';
|
||||
int bg_box_offset=5;
|
||||
int game_map_x=40;
|
||||
int game_map_y=40;
|
||||
};
|
||||
|
||||
struct SFMLRender {
|
||||
RenderConfig $config;
|
||||
sf::RenderWindow $window;
|
||||
int $map_font_size;
|
||||
float $line_spacing;
|
||||
|
@ -47,7 +50,7 @@ struct SFMLRender {
|
|||
SFMLRender(SFMLRender &other) = delete;
|
||||
|
||||
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_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
|
||||
auto size = image.getSize();
|
||||
|
||||
const int cell = 10;
|
||||
const int cell = 3;
|
||||
|
||||
// create a grid panel to hold the cells
|
||||
Panel panel(0, 0, GAME_MAP_POS, 0, true);
|
||||
Point view_port{0,0};
|
||||
Panel panel(0, 0, 0, 0, true);
|
||||
|
||||
println("IMAGE SIZE {},{}", size.x, size.y);
|
||||
RGBColor avg{0,0,0};
|
||||
|
@ -124,16 +123,11 @@ int main(int argc, char *argv[]) {
|
|||
|
||||
|
||||
SFMLRender renderer;
|
||||
// NEED TO RESIZE FOR IT TO SHOW
|
||||
// this shows that I need more refinement on the renderer
|
||||
// for example, this won't let me do arbitrary resize and
|
||||
// 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);
|
||||
|
||||
if(renderer.resize_grid(10, panel)) {
|
||||
println("RESIZED: {},{}", panel.width, panel.height);
|
||||
// set canvas to best size
|
||||
drawing = Canvas(view_port.x * 2, view_port.y * 4);
|
||||
panel.resize(view_port.x, view_port.y);
|
||||
drawing = Canvas(panel.width * 2, panel.height * 4);
|
||||
}
|
||||
|
||||
panel.set_renderer(Renderer([&]{
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
TODAY'S GOAL:
|
||||
|
||||
* panels and everything except renderer should use character coodinates
|
||||
* 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:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue