diff --git a/constants.hpp b/constants.hpp index 77bdf8b..18854ac 100644 --- a/constants.hpp +++ b/constants.hpp @@ -12,11 +12,24 @@ const int WALL_LIGHT_LEVEL = 3; const int WORLDBUILD_DIVISION = 4; const int WORLDBUILD_SHRINK = 2; const int WORLDBUILD_MAX_PATH = 200; -const int GAME_MAP_POS = 600; +const int VIDEO_WINDOW_X=1600; +const int VIDEO_WINDOW_Y=900; +const int UI_FONT_SIZE=30; +const int BASE_MAP_FONT_SIZE=90; +const int GAME_MAP_PIXEL_POS = 600; const int MAX_FONT_SIZE = 140; const int MIN_FONT_SIZE = 20; -const int SCREEN_WIDTH = 40; -const int SCREEN_HEIGHT = 30; +const int STATUS_UI_WIDTH = 40; +const int STATUS_UI_HEIGHT = 30; const float PERCENT = 0.01f; +const wchar_t BG_TILE = L'█'; +const wchar_t UI_BASE_CHAR = L'█'; +const int BG_BOX_OFFSET=5; +const int GAME_MAP_X=40; +const int GAME_MAP_Y=40; +const int INVENTORY_PIXEL_X=50; +const int INVENTORY_PIXEL_Y=50; +const int INVENTORY_WIDTH=99; +const int INVENTORY_HEIGHT=STATUS_UI_HEIGHT-3; #define FONT_FILE_NAME "./assets/text.otf" #define TILE_MAP_CONFIG "./assets/tiles.json" diff --git a/gui.cpp b/gui.cpp index 1d27c8c..70570ba 100644 --- a/gui.cpp +++ b/gui.cpp @@ -29,38 +29,13 @@ using namespace std::chrono_literals; using namespace ftxui; using namespace components; -const std::string modal_shader = R"( -uniform sampler2D source; -uniform sampler2D bloom; -uniform vec2 offsetFactor; -uniform float darkness; - -void main() -{ - vec2 textureCoordinates = gl_TexCoord[0].xy; - vec4 color = vec4(0.0); - color += texture2D(source, textureCoordinates - 4.0 * offsetFactor) * 0.0162162162; - color += texture2D(source, textureCoordinates - 3.0 * offsetFactor) * 0.0540540541; - color += texture2D(source, textureCoordinates - 2.0 * offsetFactor) * 0.1216216216; - color += texture2D(source, textureCoordinates - offsetFactor) * 0.1945945946; - color += texture2D(source, textureCoordinates) * 0.2270270270; - color += texture2D(source, textureCoordinates + offsetFactor) * 0.1945945946; - color += texture2D(source, textureCoordinates + 2.0 * offsetFactor) * 0.1216216216; - color += texture2D(source, textureCoordinates + 3.0 * offsetFactor) * 0.0540540541; - color += texture2D(source, textureCoordinates + 4.0 * offsetFactor) * 0.0162162162; - - vec4 sourceFragment = texture2D(source, gl_TexCoord[0].xy); - vec4 bloomFragment = texture2D(bloom, gl_TexCoord[0].xy); - gl_FragColor = color + sourceFragment - bloomFragment - darkness; -} -)"; - GUI::GUI(DinkyECS::World &world, Map& game_map) : $game_map(game_map), $log({{"Welcome to the game!"}}), - $status_ui(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), - $map_view(GAME_MAP_POS, 0, 0, 0, true), + $status_ui(0, 0, STATUS_UI_WIDTH, STATUS_UI_HEIGHT), + $map_view(GAME_MAP_PIXEL_POS, 0, 0, 0, true), + $inventory_ui(INVENTORY_PIXEL_X, INVENTORY_PIXEL_Y, INVENTORY_WIDTH, INVENTORY_HEIGHT), $lights(game_map.width(), game_map.height()), $world(world), $sounds("./assets"), @@ -72,8 +47,8 @@ GUI::GUI(DinkyECS::World &world, Map& game_map) : $sounds.load("combat_player_hit", "combat_player_hit.mp3"); $sounds.load("combat_enemy_hit", "combat_enemy_hit.mp3"); $sounds.load("combat_miss", "combat_miss.mp3"); - resize_map(MAX_FONT_SIZE); + init_shaders(); } void GUI::resize_map(int new_size) { @@ -96,27 +71,21 @@ void GUI::create_renderer() { return canvas($canvas); })); - auto modal_buttons = Container::Horizontal({ - Button("OK", [&]{ $show_modal = false; }), - Button("CANCEL", [&]{ $show_modal = false; }), - }); - - auto modal_test = Renderer([&, modal_buttons] { - return hbox({ - hflow( - vbox( - text("Hello!"), - modal_buttons->Render() - ))}) | border; - }); - modal_test->Add(modal_buttons); - auto test_button = Container::Horizontal({ - Button("Open Test Modal", [&]{ $show_modal = true; }), - Button("Close It", [&]{ $show_modal = false; }), + auto cell = [](const char* t) { return text(t) | border; }; + auto inventory_test = Renderer([cell] { + return hflow({ + gridbox({ + {cell("one"), cell("two"), cell("three")}, + {cell("four"), cell("five"), cell("six")}, + {cell("seven"), cell("eight"), cell("nine")}, + }) | yflex_grow, + separator() | yflex_grow, + paragraph("Item UI Goes Here") | yflex_grow + }) | border | flex; }); - auto status_rend = Renderer(test_button, [&, modal_test, test_button, player]{ + auto status_rend = Renderer([&, player]{ const auto& player_combat = $world.get(player.entity); const auto& inventory = $world.get(player.entity); $status_text = player_combat.hp > 0 ? "NOT DEAD" : "DEAD!!!!!!"; @@ -131,7 +100,6 @@ void GUI::create_renderer() { return hbox({ hflow( vbox( - test_button->Render(), text(format("HP: {: >3} GOLD: {: >3}", player_combat.hp, inventory.gold)) | border, text($status_text) | border, @@ -144,10 +112,8 @@ void GUI::create_renderer() { }); }); - status_rend |= Modal(modal_test, &$show_modal); - $status_ui.set_renderer(status_rend); - $status_ui.add(modal_test); + $inventory_ui.set_renderer(inventory_test); } void GUI::handle_world_events() { @@ -232,8 +198,13 @@ bool GUI::handle_ui_events() { auto &debug = $world.get_the(); debug.LIGHT = !debug.LIGHT; } else if(KB::isKeyPressed(KB::I)) { - create_modal(); - $show_modal = !$show_modal; + // yes, using an if to avoid double grabbing screen + if($show_modal) { + $show_modal = false; + } else { + pause_screen(); + $show_modal = true; + } } else if(KB::isKeyPressed(KB::P)) { auto &debug = $world.get_the(); debug.PATHS = !debug.PATHS; @@ -257,24 +228,24 @@ bool GUI::handle_ui_events() { return event_happened; } -void GUI::create_modal() { - println("CREATING MODAL"); +void GUI::init_shaders() { + auto& shader = $paused.load_shader("./shaders/modal.frag"); + shader.setUniform("offsetFactor", sf::Glsl::Vec2{0.001f, 0.001f}); + shader.setUniform("darkness", 0.05f); +} + +void GUI::pause_screen() { auto &window = $renderer.$window; auto size = window.getSize(); - paused_texture.create(size.x, size.y); - paused_texture.update(window); - bool good = paused_shader.loadFromMemory(modal_shader, sf::Shader::Fragment); - paused_shader.setUniform("offsetFactor", sf::Glsl::Vec2{0.001f, 0.001f}); - paused_shader.setUniform("darkness", 0.05f); - dbc::check(good, "shader could not be loaded"); - paused_sprite.setTexture(paused_texture); - paused_sprite.setPosition(0,0); + $paused.texture.create(size.x, size.y); + $paused.texture.update(window); + $paused.sprite.setTexture($paused.texture); + $paused.sprite.setPosition(0,0); } -void GUI::draw_modal() { - auto &window = $renderer.$window; - window.draw(paused_sprite, &paused_shader); +void GUI::draw_paused() { + $renderer.draw_sprite($paused.sprite, &$paused.shader); } void GUI::run_systems() { @@ -301,7 +272,9 @@ void GUI::render_scene() { $renderer.clear(); if($show_modal) { - draw_modal(); + draw_paused(); + $inventory_ui.render(); + $renderer.draw($inventory_ui); } else { $map_view.render(); $renderer.draw($map_view); diff --git a/gui.hpp b/gui.hpp index ffabab6..c9dba65 100644 --- a/gui.hpp +++ b/gui.hpp @@ -35,6 +35,18 @@ struct ActionLog { } }; +struct UnDumbTSS { + sf::Texture texture; + sf::Sprite sprite; + sf::Shader shader; + + + sf::Shader& load_shader(string filename) { + bool good = shader.loadFromFile(filename, sf::Shader::Fragment); + dbc::check(good, "shader could not be loaded"); + return shader; + } +}; class GUI { string $status_text = "NOT DEAD"; @@ -43,16 +55,14 @@ class GUI { ActionLog $log; Panel $status_ui; Panel $map_view; + Panel $inventory_ui; LightRender $lights; bool $show_modal = false; Component $test_button; DinkyECS::World& $world; SoundManager $sounds; SFMLRender $renderer; - - sf::Texture paused_texture; - sf::Sprite paused_sprite; - sf::Shader paused_shader; + UnDumbTSS $paused; public: GUI(DinkyECS::World& world, Map& game_map); @@ -69,7 +79,9 @@ public: void save_world(); void shake(); void shutdown(); - void create_modal(); - void draw_modal(); int main(bool run_once=false); + + void pause_screen(); + void draw_paused(); + void init_shaders(); }; diff --git a/main.cpp b/main.cpp index dcb171a..e91f2c6 100644 --- a/main.cpp +++ b/main.cpp @@ -3,6 +3,7 @@ #include "systems.hpp" #include "events.hpp" #include "components.hpp" +#include "constants.hpp" #include "dbc.hpp" #include "collider.hpp" #include "render.hpp" @@ -59,9 +60,6 @@ void configure_world(DinkyECS::World &world, Map &game_map) { world.set(wall_torch, {"☀"}); } -const int GAME_MAP_X = 40; -const int GAME_MAP_Y = 40; - int main(int argc, char *argv[]) { DinkyECS::World world; Map game_map(GAME_MAP_X, GAME_MAP_Y); diff --git a/render.cpp b/render.cpp index 292b0aa..faac88c 100644 --- a/render.cpp +++ b/render.cpp @@ -203,6 +203,10 @@ void SFMLRender::render_text(const std::wstring &text, sf::Color default_fg, sf: } } +void SFMLRender::draw_sprite(sf::Sprite &sprite, sf::Shader *shader) { + $window.draw(sprite, shader); +} + /* * Does not render the panel, you have to do that so you can control * when things render. diff --git a/render.hpp b/render.hpp index 4cfc843..92f7692 100644 --- a/render.hpp +++ b/render.hpp @@ -10,20 +10,23 @@ #include #include "ansi_parser.hpp" #include "panel.hpp" +#include "constants.hpp" using ftxui::Canvas, ftxui::Screen; - +/* + * BUG: This could be so much better. + */ 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; + int video_x = VIDEO_WINDOW_X; + int video_y = VIDEO_WINDOW_Y; + int ui_font_size=UI_FONT_SIZE; + int base_map_font_size=BASE_MAP_FONT_SIZE; + wchar_t bg_tile = BG_TILE; + wchar_t ui_base_char = UI_BASE_CHAR; + int bg_box_offset=BG_BOX_OFFSET; + int game_map_x=GAME_MAP_X; + int game_map_y=GAME_MAP_Y; }; struct SFMLRender { @@ -55,6 +58,7 @@ struct SFMLRender { void render_text(const std::wstring &text, sf::Color default_fg, sf::Color default_bg, float x, float y); void draw(Panel &panel, float x_offset=0.0f, float y_offset=0.0f); + void draw_sprite(sf::Sprite &sprite, sf::Shader *shader); bool poll_event(sf::Event &event) { return $window.pollEvent(event); diff --git a/shaders/modal.frag b/shaders/modal.frag new file mode 100644 index 0000000..9c1a9b2 --- /dev/null +++ b/shaders/modal.frag @@ -0,0 +1,23 @@ +uniform sampler2D source; +uniform sampler2D bloom; +uniform vec2 offsetFactor; +uniform float darkness; + +void main() +{ + vec2 textureCoordinates = gl_TexCoord[0].xy; + vec4 color = vec4(0.0); + color += texture2D(source, textureCoordinates - 4.0 * offsetFactor) * 0.0162162162; + color += texture2D(source, textureCoordinates - 3.0 * offsetFactor) * 0.0540540541; + color += texture2D(source, textureCoordinates - 2.0 * offsetFactor) * 0.1216216216; + color += texture2D(source, textureCoordinates - offsetFactor) * 0.1945945946; + color += texture2D(source, textureCoordinates) * 0.2270270270; + color += texture2D(source, textureCoordinates + offsetFactor) * 0.1945945946; + color += texture2D(source, textureCoordinates + 2.0 * offsetFactor) * 0.1216216216; + color += texture2D(source, textureCoordinates + 3.0 * offsetFactor) * 0.0540540541; + color += texture2D(source, textureCoordinates + 4.0 * offsetFactor) * 0.0162162162; + + vec4 sourceFragment = texture2D(source, gl_TexCoord[0].xy); + vec4 bloomFragment = texture2D(bloom, gl_TexCoord[0].xy); + gl_FragColor = color + sourceFragment - bloomFragment - darkness; +} diff --git a/status.txt b/status.txt index 1f02687..65f1b56 100644 --- a/status.txt +++ b/status.txt @@ -1,5 +1,6 @@ TODAY'S GOAL: +* Create a move function for iterators that recalculates their position to make it easy to move them inside the matrix. This can then be used in lighting. Just make an iterator once, and move it around after. * Components::Tile must also die. * MapConfig must die. * Tile component needs to go, use the Tiles from the json. diff --git a/tools/designer.cpp b/tools/designer.cpp index 1af6916..bf6c6be 100644 --- a/tools/designer.cpp +++ b/tools/designer.cpp @@ -138,8 +138,8 @@ class GUI { Component $bg_settings; GUI(string font_list) : - $font_view(GAME_MAP_POS, 0, GRID_SIZE.x, GRID_SIZE.y, true), - $status_ui(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), + $font_view(GAME_MAP_PIXEL_POS, 0, GRID_SIZE.x, GRID_SIZE.y, true), + $status_ui(0, 0, STATUS_UI_WIDTH, STATUS_UI_HEIGHT), $font_grid(font_list, GRID_SIZE.x, GRID_SIZE.y), $fg_color{.h=20, .s=50, .v=20}, $bg_color{.h=100, .s=100, .v=100}