Now mostly working with GUECS but shaders are still busted. Have to find out why they stopped working.
This commit is contained in:
		
							parent
							
								
									a5f6a82611
								
							
						
					
					
						commit
						ac22a11c9f
					
				
					 27 changed files with 162 additions and 1210 deletions
				
			
		
							
								
								
									
										5
									
								
								Makefile
									
										
									
									
									
								
							
							
						
						
									
										5
									
								
								Makefile
									
										
									
									
									
								
							|  | @ -6,10 +6,7 @@ reset: | |||
| patch: | ||||
| 	powershell "cp ./patches/process.h ./subprojects/libgit2-1.9.0/src/util/process.h" | ||||
| 
 | ||||
| %.cpp : %.rl | ||||
| 	ragel -o $@ $< | ||||
| 
 | ||||
| build: lel_parser.cpp | ||||
| build: | ||||
| 	meson compile -C builddir | ||||
| 
 | ||||
| config: | ||||
|  |  | |||
							
								
								
									
										66
									
								
								backend.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								backend.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,66 @@ | |||
| #include "backend.hpp" | ||||
| #include "shaders.hpp" | ||||
| #include "sound.hpp" | ||||
| #include "textures.hpp" | ||||
| 
 | ||||
| namespace sfml { | ||||
|   guecs::SpriteTexture Backend::texture_get(const string& name) { | ||||
|     auto sp = textures::get(name); | ||||
|     return {sp.sprite, sp.texture}; | ||||
|   } | ||||
| 
 | ||||
|   Backend::Backend() { | ||||
|     sound::init(); | ||||
|     shaders::init(); | ||||
|     textures::init(); | ||||
|   } | ||||
| 
 | ||||
|   void Backend::sound_play(const string& name) { | ||||
|     sound::play(name); | ||||
|   } | ||||
| 
 | ||||
|   void Backend::sound_stop(const string& name) { | ||||
|     sound::stop(name); | ||||
|   } | ||||
| 
 | ||||
|   std::shared_ptr<sf::Shader> Backend::shader_get(const std::string& name) { | ||||
|     return shaders::get(name); | ||||
|   } | ||||
| 
 | ||||
|   bool Backend::shader_updated() { | ||||
|     if(shaders::updated($shaders_version)) { | ||||
|       $shaders_version = shaders::version(); | ||||
|       return true; | ||||
|     } else { | ||||
|       return false; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   guecs::Theme Backend::theme() { | ||||
|     guecs::Theme theme { | ||||
|       .BLACK={1, 4, 2}, | ||||
|       .DARK_DARK={9, 29, 16}, | ||||
|       .DARK_MID={14, 50, 26}, | ||||
|       .DARK_LIGHT={0, 109, 44}, | ||||
|       .MID={63, 171, 92}, | ||||
|       .LIGHT_DARK={161, 217, 155}, | ||||
|       .LIGHT_MID={199, 233, 192}, | ||||
|       .LIGHT_LIGHT={229, 245, 224}, | ||||
|       .WHITE={255, 255, 255}, | ||||
|       .TRANSPARENT = sf::Color::Transparent | ||||
|     }; | ||||
| 
 | ||||
|     theme.PADDING = 3; | ||||
|     theme.BORDER_PX = 1; | ||||
|     theme.TEXT_SIZE = 40; | ||||
|     theme.LABEL_SIZE = 40; | ||||
|     theme.FILL_COLOR = theme.DARK_DARK; | ||||
|     theme.TEXT_COLOR = theme.LIGHT_LIGHT; | ||||
|     theme.BG_COLOR = theme.MID; | ||||
|     theme.BORDER_COLOR = theme.LIGHT_DARK; | ||||
|     theme.BG_COLOR_DARK = theme.BLACK; | ||||
|     theme.FONT_FILE_NAME = "assets/text.ttf"; | ||||
| 
 | ||||
|     return theme; | ||||
|   } | ||||
| } | ||||
							
								
								
									
										19
									
								
								backend.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								backend.hpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,19 @@ | |||
| #include "guecs/ui.hpp" | ||||
| 
 | ||||
| namespace sfml { | ||||
|   using std::string; | ||||
| 
 | ||||
|   class Backend : public guecs::Backend { | ||||
|     int $shaders_version = 0; | ||||
| 
 | ||||
|   public: | ||||
| 
 | ||||
|     Backend(); | ||||
|     guecs::SpriteTexture texture_get(const string& name); | ||||
|     void sound_play(const string& name); | ||||
|     void sound_stop(const string& name); | ||||
|     std::shared_ptr<sf::Shader> shader_get(const std::string& name); | ||||
|     bool shader_updated(); | ||||
|     guecs::Theme theme(); | ||||
|   }; | ||||
| } | ||||
							
								
								
									
										15
									
								
								color.hpp
									
										
									
									
									
								
							
							
						
						
									
										15
									
								
								color.hpp
									
										
									
									
									
								
							|  | @ -1,15 +0,0 @@ | |||
| #pragma once | ||||
| #include <SFML/Graphics/Color.hpp> | ||||
| 
 | ||||
| namespace ColorValue { | ||||
|   const sf::Color BLACK{1, 4, 2}; | ||||
|   const sf::Color DARK_DARK{9, 29, 16}; | ||||
|   const sf::Color DARK_MID{14, 50, 26}; | ||||
|   const sf::Color DARK_LIGHT{0, 109, 44}; | ||||
|   const sf::Color MID{63, 171, 92}; | ||||
|   const sf::Color LIGHT_DARK{161, 217, 155}; | ||||
|   const sf::Color LIGHT_MID{199, 233, 192}; | ||||
|   const sf::Color LIGHT_LIGHT{229, 245, 224}; | ||||
|   const sf::Color WHITE{255, 255, 255}; | ||||
|   const sf::Color TRANSPARENT = sf::Color::Transparent; | ||||
| } | ||||
|  | @ -1,7 +1,6 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <string> | ||||
| #include "color.hpp" | ||||
| #include <array> | ||||
| 
 | ||||
| constexpr const int SCREEN_WIDTH= 1920 / 2; | ||||
|  | @ -10,15 +9,6 @@ constexpr const int SCREEN_HEIGHT= 1080 / 2; | |||
| constexpr const bool VSYNC=false; | ||||
| constexpr const int FRAME_LIMIT=60; | ||||
| 
 | ||||
| constexpr const int GUECS_PADDING = 3; | ||||
| constexpr const int GUECS_BORDER_PX = 1; | ||||
| constexpr const int GUECS_FONT_SIZE = 40; | ||||
| const sf::Color GUECS_FILL_COLOR = ColorValue::DARK_DARK; | ||||
| const sf::Color GUECS_TEXT_COLOR = ColorValue::LIGHT_LIGHT; | ||||
| const sf::Color GUECS_BG_COLOR = ColorValue::BLACK; | ||||
| const sf::Color GUECS_BORDER_COLOR = ColorValue::MID; | ||||
| constexpr const char *FONT_FILE_NAME="assets/text.ttf"; | ||||
| 
 | ||||
| #ifdef NDEBUG | ||||
| constexpr const bool DEBUG_BUILD=false; | ||||
| #else | ||||
|  |  | |||
							
								
								
									
										3
									
								
								dbc.hpp
									
										
									
									
									
								
							
							
						
						
									
										3
									
								
								dbc.hpp
									
										
									
									
									
								
							|  | @ -5,9 +5,10 @@ | |||
| #include <functional> | ||||
| #include <source_location> | ||||
| 
 | ||||
| using std::string; | ||||
| 
 | ||||
| namespace dbc { | ||||
|   using std::string; | ||||
| 
 | ||||
|   class Error { | ||||
|     public: | ||||
|       const string message; | ||||
|  |  | |||
|  | @ -12,8 +12,10 @@ const auto ERROR = fmt::emphasis::bold | fg(fmt::color::red); | |||
| 
 | ||||
| using namespace std; | ||||
| 
 | ||||
| GameEngine::GameEngine(int hp) : starting_hp(hp) { | ||||
|   hit_points = max_hp(); | ||||
| GameEngine::GameEngine(int hp, int max_hp) : | ||||
|   hit_points(hp), starting_hp(max_hp) | ||||
| { | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| int GameEngine::determine_damage(string &type) { | ||||
|  |  | |||
|  | @ -31,8 +31,8 @@ class GameEngine : DeadSimpleFSM<GameState, GameEvent> { | |||
|   }; | ||||
| 
 | ||||
|   public: | ||||
|   int starting_hp = 0; | ||||
|   int hit_points = 0; | ||||
|   int starting_hp = 0; | ||||
|   int hits_taken = 0; | ||||
|   int rounds = 0; | ||||
|   int deaths = 0; | ||||
|  | @ -40,7 +40,7 @@ class GameEngine : DeadSimpleFSM<GameState, GameEvent> { | |||
|   float hp_bonus = 1.0f; | ||||
|   bool free_death = false; | ||||
| 
 | ||||
|   GameEngine(int hp); | ||||
|   GameEngine(int hp, int max_hp); | ||||
| 
 | ||||
|   // FOUND BUG: I was accidentally copying this and shouldn't have been
 | ||||
|   GameEngine(GameEngine &g) = delete; | ||||
|  |  | |||
							
								
								
									
										316
									
								
								guecs.cpp
									
										
									
									
									
								
							
							
						
						
									
										316
									
								
								guecs.cpp
									
										
									
									
									
								
							|  | @ -1,316 +0,0 @@ | |||
| #include "guecs.hpp" | ||||
| #include "shaders.hpp" | ||||
| #include "sound.hpp" | ||||
| #include "config.hpp" | ||||
| 
 | ||||
| namespace guecs { | ||||
| 
 | ||||
|   void Textual::init(lel::Cell &cell, shared_ptr<sf::Font> font_ptr) { | ||||
|     dbc::check(font_ptr != nullptr, "you failed to initialize this WideText"); | ||||
|     if(font == nullptr) font = font_ptr; | ||||
|     if(text == nullptr) text = make_shared<sf::Text>(*font, content, size); | ||||
|     text->setFillColor(color); | ||||
| 
 | ||||
|     if(centered) { | ||||
|       auto bounds = text->getLocalBounds(); | ||||
|       auto text_cell = lel::center(bounds.size.x, bounds.size.y, cell); | ||||
|       // this stupid / 2 is because SFML renders from baseline rather than from the claimed bounding box
 | ||||
|       text->setPosition({float(text_cell.x), float(text_cell.y) - text_cell.h / 2}); | ||||
|     } else { | ||||
|       text->setPosition({float(cell.x + padding * 2), float(cell.y + padding * 2)}); | ||||
|     } | ||||
| 
 | ||||
|     text->setCharacterSize(size); | ||||
|   } | ||||
| 
 | ||||
|   void Textual::update(std::wstring& new_content) { | ||||
|     content = new_content; | ||||
|     text->setString(content); | ||||
|   } | ||||
| 
 | ||||
|   void Sprite::init(lel::Cell &cell) { | ||||
|     auto sprite_texture = textures::get(name); | ||||
| 
 | ||||
|     sprite = make_shared<sf::Sprite>( | ||||
|         *sprite_texture.texture, | ||||
|         sprite_texture.sprite->getTextureRect()); | ||||
| 
 | ||||
|     sprite->setPosition({ | ||||
|         float(cell.x + padding), | ||||
|         float(cell.y + padding)}); | ||||
| 
 | ||||
|     auto bounds = sprite->getLocalBounds(); | ||||
| 
 | ||||
|     sprite->setScale({ | ||||
|         float(cell.w - padding * 2) / bounds.size.x, | ||||
|         float(cell.h - padding * 2) / bounds.size.y}); | ||||
|   } | ||||
| 
 | ||||
|   void Rectangle::init(lel::Cell& cell) { | ||||
|     sf::Vector2f size{float(cell.w) - padding * 2, float(cell.h) - padding * 2}; | ||||
|     if(shape == nullptr) shape = make_shared<sf::RectangleShape>(size); | ||||
|     shape->setPosition({float(cell.x + padding), float(cell.y + padding)}); | ||||
|     shape->setFillColor(color); | ||||
|     shape->setOutlineColor(border_color); | ||||
|     shape->setOutlineThickness(border_px); | ||||
|   } | ||||
| 
 | ||||
| 
 | ||||
|   void Meter::init(lel::Cell& cell) { | ||||
|     bar.init(cell); | ||||
|   } | ||||
| 
 | ||||
|   void Sound::play(bool hover) { | ||||
|     if(!hover) { | ||||
|       sound::play(on_click); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   void Background::init() { | ||||
|     sf::Vector2f size{float(w), float(h)}; | ||||
|     if(shape == nullptr) shape = make_shared<sf::RectangleShape>(size); | ||||
|     shape->setPosition({float(x), float(y)}); | ||||
|     shape->setFillColor(color); | ||||
|   } | ||||
| 
 | ||||
|   void Effect::init(lel::Cell &cell) { | ||||
|     $shader_version = shaders::version(); | ||||
|     $shader = shaders::get(name); | ||||
|     $shader->setUniform("u_resolution", sf::Vector2f({float(cell.w), float(cell.h)})); | ||||
|     $clock = std::make_shared<sf::Clock>(); | ||||
|   } | ||||
| 
 | ||||
|   void Effect::step() { | ||||
|     sf::Time cur_time = $clock->getElapsedTime(); | ||||
|     float u_time = cur_time.asSeconds(); | ||||
| 
 | ||||
|     if(u_time < $u_time_end) { | ||||
|       $shader->setUniform("u_duration", duration); | ||||
|       $shader->setUniform("u_time_end", $u_time_end); | ||||
|       $shader->setUniform("u_time", u_time); | ||||
|     } else { | ||||
|       $active = false; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   void Effect::run() { | ||||
|     $active = true; | ||||
|     sf::Time u_time = $clock->getElapsedTime(); | ||||
|     $u_time_end = u_time.asSeconds() + duration; | ||||
|   } | ||||
| 
 | ||||
|   shared_ptr<sf::Shader> Effect::checkout_ptr() { | ||||
|     if(shaders::updated($shader_version)) { | ||||
|       $shader = shaders::get(name); | ||||
|       $shader_version = shaders::version(); | ||||
|     } | ||||
| 
 | ||||
|     return $shader; | ||||
|   } | ||||
| 
 | ||||
|   UI::UI() { | ||||
|     $font = make_shared<sf::Font>(Config::path_to(FONT_FILE_NAME)); | ||||
|   } | ||||
| 
 | ||||
|   void UI::position(int x, int y, int width, int height) { | ||||
|     $parser.position(x, y, width, height); | ||||
|   } | ||||
| 
 | ||||
|   void UI::layout(std::string grid) { | ||||
|     $grid = grid; | ||||
|     bool good = $parser.parse($grid); | ||||
|     dbc::check(good, "LEL parsing failed."); | ||||
| 
 | ||||
|     for(auto& [name, cell] : $parser.cells) { | ||||
|       auto ent = init_entity(name); | ||||
|       $world.set<lel::Cell>(ent, cell); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   DinkyECS::Entity UI::init_entity(std::string name) { | ||||
|     auto entity = $world.entity(); | ||||
|     // this lets you look up an entity by name
 | ||||
|     $name_ents.insert_or_assign(name, entity); | ||||
|     // this makes it easier to get the name during querying
 | ||||
|     $world.set<CellName>(entity, {name}); | ||||
|     return entity; | ||||
|   } | ||||
| 
 | ||||
|   DinkyECS::Entity UI::entity(std::string name) { | ||||
|     dbc::check($name_ents.contains(name), | ||||
|         fmt::format("GUECS entity {} does not exist. Forgot to init_entity?", name)); | ||||
|     return $name_ents.at(name); | ||||
|   } | ||||
| 
 | ||||
|   void UI::init() { | ||||
|     if($world.has_the<Background>()) { | ||||
|       auto& bg = $world.get_the<Background>(); | ||||
|       bg.init(); | ||||
|     } | ||||
| 
 | ||||
|     $world.query<Background>([](auto, auto& bg) { | ||||
|         bg.init(); | ||||
|     }); | ||||
| 
 | ||||
|     $world.query<lel::Cell, Rectangle>([](auto, auto& cell, auto& rect) { | ||||
|       rect.init(cell); | ||||
|     }); | ||||
| 
 | ||||
|     $world.query<lel::Cell, Effect>([](auto, auto& cell, auto& effect) { | ||||
|         effect.init(cell); | ||||
|     }); | ||||
| 
 | ||||
|     $world.query<Rectangle, Meter>([](auto, auto& bg, auto &) { | ||||
|         bg.shape->setFillColor(ColorValue::BLACK); | ||||
|     }); | ||||
| 
 | ||||
|     $world.query<lel::Cell, Meter>([](auto, auto &cell, auto& meter) { | ||||
|         meter.init(cell); | ||||
|     }); | ||||
| 
 | ||||
|     $world.query<lel::Cell, Textual>([this](auto, auto& cell, auto& text) { | ||||
|       text.init(cell, $font); | ||||
|     }); | ||||
| 
 | ||||
|     $world.query<lel::Cell, Label>([this](auto, auto& cell, auto& text) { | ||||
|       text.init(cell, $font); | ||||
|     }); | ||||
| 
 | ||||
|     $world.query<lel::Cell, Sprite>([&](auto, auto &cell, auto &sprite) { | ||||
|         sprite.init(cell); | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   void UI::debug_layout(sf::RenderWindow& window) { | ||||
|     $world.query<lel::Cell>([&](const auto, auto &cell) { | ||||
|         sf::RectangleShape rect{{float(cell.w), float(cell.h)}}; | ||||
|         rect.setPosition({float(cell.x), float(cell.y)}); | ||||
|         rect.setFillColor(sf::Color::Transparent); | ||||
|         rect.setOutlineColor(sf::Color::Red); | ||||
|         rect.setOutlineThickness(2.0f); | ||||
|         window.draw(rect); | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   void UI::render(sf::RenderWindow& window) { | ||||
|     if($world.has_the<Background>()) { | ||||
|       auto& bg = $world.get_the<Background>(); | ||||
|       window.draw(*bg.shape); | ||||
|     } | ||||
| 
 | ||||
|     $world.query<Effect>([&](auto, auto& shader) { | ||||
|       if(shader.$active) shader.step(); | ||||
|     }); | ||||
| 
 | ||||
|     $world.query<Rectangle>([&](auto ent, auto& rect) { | ||||
|         render_helper(window, ent, true, rect.shape); | ||||
|     }); | ||||
| 
 | ||||
|     $world.query<lel::Cell, Meter>([&](auto ent, auto& cell, const auto &meter) { | ||||
|         int pad = meter.bar.padding * 2; | ||||
|         float level = std::clamp(meter.percent, 0.0f, 1.0f) * float(cell.w - pad); | ||||
|         // ZED: this 6 is a border width, make it a thing
 | ||||
|         meter.bar.shape->setSize({std::max(level, 0.0f), float(cell.h - pad)}); | ||||
|         render_helper(window, ent, true, meter.bar.shape); | ||||
|     }); | ||||
| 
 | ||||
|     $world.query<Sprite>([&](auto ent, auto& sprite) { | ||||
|         render_helper(window, ent, false, sprite.sprite); | ||||
|     }); | ||||
| 
 | ||||
|     $world.query<Label>([&](auto ent, auto& text) { | ||||
|         render_helper(window, ent, false, text.text); | ||||
|     }); | ||||
| 
 | ||||
|     $world.query<Textual>([&](auto ent, auto& text) { | ||||
|         render_helper(window, ent, true, text.text); | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   bool UI::mouse(float x, float y, bool hover) { | ||||
|     int action_count = 0; | ||||
| 
 | ||||
|     $world.query<lel::Cell, Clickable>([&](auto ent, auto& cell, auto &clicked) { | ||||
|       if((x >= cell.x && x <= cell.x + cell.w) && | ||||
|           (y >= cell.y && y <= cell.y + cell.h)) | ||||
|       { | ||||
|         do_if<Effect>(ent, [hover](auto& effect) { | ||||
|           effect.$shader->setUniform("hover", hover); | ||||
|           effect.run(); | ||||
|         }); | ||||
| 
 | ||||
|         do_if<Sound>(ent, [hover](auto& sound) { | ||||
|             // here set that it played then only play once
 | ||||
|             sound.play(hover); | ||||
|         }); | ||||
| 
 | ||||
|         if(hover) return; // kinda gross
 | ||||
| 
 | ||||
|         if(auto action_data = get_if<ActionData>(ent)) { | ||||
|           clicked.action(ent, action_data->data); | ||||
|         } else { | ||||
|           clicked.action(ent, {}); | ||||
|         } | ||||
| 
 | ||||
|         action_count++; | ||||
|       } else { | ||||
|         // via ORBLISHJ
 | ||||
|         // just reset the hover trigger for all that aren't hit
 | ||||
|         // then in the ^^ positive branch play it and set it played
 | ||||
|       } | ||||
|     }); | ||||
| 
 | ||||
|     return action_count > 0; | ||||
|   } | ||||
| 
 | ||||
|   void UI::show_sprite(string region, string sprite_name) { | ||||
|     auto ent = entity(region); | ||||
| 
 | ||||
|     if(has<Sprite>(ent)) { | ||||
|       auto& to_show = get<Sprite>(ent); | ||||
|       auto sprite_texture = textures::get(sprite_name); | ||||
|       to_show.sprite->setTexture(*sprite_texture.texture); | ||||
|     } else { | ||||
|       Sprite to_show{sprite_name}; | ||||
|       auto& cell = cell_for(ent); | ||||
|       to_show.init(cell); | ||||
|       set<guecs::Sprite>(ent, to_show); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   void UI::show_text(string region, wstring content) { | ||||
|     auto ent = entity(region); | ||||
| 
 | ||||
|     if(auto text = get_if<Textual>(ent)) { | ||||
|       text->text->setString(content); | ||||
|     } else { | ||||
|       auto &cell = cell_for(ent); | ||||
|       Textual to_set{content, 20}; | ||||
|       to_set.init(cell, $font); | ||||
|       to_set.text->setFillColor(ColorValue::LIGHT_MID); | ||||
|       set<Textual>(ent, to_set); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   void UI::show_label(string region, wstring content) { | ||||
|     auto ent = entity(region); | ||||
| 
 | ||||
|     if(auto text = get_if<Label>(ent)) { | ||||
|       text->text->setString(content); | ||||
|     } else { | ||||
|       auto &cell = cell_for(ent); | ||||
|       Label to_set{content, 20}; | ||||
|       to_set.init(cell, $font); | ||||
|       to_set.text->setFillColor(ColorValue::LIGHT_MID); | ||||
|       set<Label>(ent, to_set); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   Clickable make_action(DinkyECS::World& target, Events::GUI event) { | ||||
|     return {[&, event](auto ent, auto data){ | ||||
|       // remember that ent is passed in from the UI::mouse handler
 | ||||
|       target.send<Events::GUI>(event, ent, data); | ||||
|     }}; | ||||
|   } | ||||
| 
 | ||||
| } | ||||
							
								
								
									
										233
									
								
								guecs.hpp
									
										
									
									
									
								
							
							
						
						
									
										233
									
								
								guecs.hpp
									
										
									
									
									
								
							|  | @ -1,233 +0,0 @@ | |||
| #pragma once | ||||
| #include "color.hpp" | ||||
| #include "dinkyecs.hpp" | ||||
| #include "lel.hpp" | ||||
| #include <string> | ||||
| #include <memory> | ||||
| #include <SFML/Graphics.hpp> | ||||
| #include "textures.hpp" | ||||
| #include <functional> | ||||
| #include "events.hpp" | ||||
| #include "constants.hpp" | ||||
| #include <any> | ||||
| #include "shaders.hpp" | ||||
| 
 | ||||
| namespace guecs { | ||||
|   using std::shared_ptr, std::make_shared, std::wstring, std::string; | ||||
| 
 | ||||
|   struct Textual { | ||||
|     std::wstring content; | ||||
|     unsigned int size = GUECS_FONT_SIZE; | ||||
|     sf::Color color = GUECS_TEXT_COLOR; | ||||
|     int padding = GUECS_PADDING; | ||||
|     bool centered = false; | ||||
|     shared_ptr<sf::Font> font = nullptr; | ||||
|     shared_ptr<sf::Text> text = nullptr; | ||||
| 
 | ||||
|     void init(lel::Cell &cell, shared_ptr<sf::Font> font_ptr); | ||||
|     void update(std::wstring& new_content); | ||||
|   }; | ||||
| 
 | ||||
|   struct Label : public Textual { | ||||
|     template<typename... Args> | ||||
|     Label(Args... args) : Textual(args...) | ||||
|     { | ||||
|       centered = true; | ||||
|     } | ||||
| 
 | ||||
|     Label() { | ||||
|       centered = true; | ||||
|     }; | ||||
|   }; | ||||
| 
 | ||||
|   struct Clickable { | ||||
|     /* This is actually called by UI::mouse and passed the entity ID of the
 | ||||
|      * button pressed so you can interact with it in the event handler. | ||||
|      */ | ||||
|     std::function<void(DinkyECS::Entity ent, std::any data)> action; | ||||
|   }; | ||||
| 
 | ||||
|   struct Sprite { | ||||
|     std::string name; | ||||
|     int padding = GUECS_PADDING; | ||||
|     std::shared_ptr<sf::Sprite> sprite = nullptr; | ||||
|     std::shared_ptr<sf::Texture> texture = nullptr; | ||||
| 
 | ||||
|     void init(lel::Cell &cell); | ||||
|   }; | ||||
| 
 | ||||
|   struct Rectangle { | ||||
|     int padding = GUECS_PADDING; | ||||
|     sf::Color color = GUECS_FILL_COLOR; | ||||
|     sf::Color border_color = GUECS_BORDER_COLOR; | ||||
|     int border_px = GUECS_BORDER_PX; | ||||
|     shared_ptr<sf::RectangleShape> shape = nullptr; | ||||
| 
 | ||||
|     void init(lel::Cell& cell); | ||||
|   }; | ||||
| 
 | ||||
|   struct Meter { | ||||
|     float percent = 1.0f; | ||||
|     Rectangle bar{}; | ||||
| 
 | ||||
|     void init(lel::Cell& cell); | ||||
|   }; | ||||
| 
 | ||||
|   struct ActionData { | ||||
|     std::any data; | ||||
|   }; | ||||
| 
 | ||||
|   struct CellName { | ||||
|     std::string name; | ||||
|   }; | ||||
| 
 | ||||
|   struct Effect { | ||||
|     float duration = 0.1f; | ||||
|     std::string name{"ui_shader"}; | ||||
|     float $u_time_end = 0.0; | ||||
|     bool $active = false; | ||||
|     std::shared_ptr<sf::Clock> $clock = nullptr; | ||||
|     std::shared_ptr<sf::Shader> $shader = nullptr; | ||||
|     int $shader_version = 0; | ||||
| 
 | ||||
|     void init(lel::Cell &cell); | ||||
|     void run(); | ||||
|     void step(); | ||||
|     shared_ptr<sf::Shader> checkout_ptr(); | ||||
|   }; | ||||
| 
 | ||||
|   struct Sound { | ||||
|     std::string on_click{"ui_click"}; | ||||
|     void play(bool hover); | ||||
|   }; | ||||
| 
 | ||||
|   struct Background { | ||||
|     float x = 0.0f; | ||||
|     float y = 0.0f; | ||||
|     float w = 0.0f; | ||||
|     float h = 0.0f; | ||||
|     sf::Color color = GUECS_BG_COLOR; | ||||
|     shared_ptr<sf::RectangleShape> shape = nullptr; | ||||
| 
 | ||||
|     Background(lel::Parser& parser, sf::Color bg_color=GUECS_BG_COLOR) : | ||||
|       x(parser.grid_x), | ||||
|       y(parser.grid_y), | ||||
|       w(parser.grid_w), | ||||
|       h(parser.grid_h), | ||||
|       color(bg_color) | ||||
|     {} | ||||
| 
 | ||||
|     Background() {} | ||||
| 
 | ||||
|     void init(); | ||||
|   }; | ||||
| 
 | ||||
|   class UI { | ||||
|     public: | ||||
|       DinkyECS::World $world; | ||||
|       std::unordered_map<std::string, DinkyECS::Entity> $name_ents; | ||||
|       shared_ptr<sf::Font> $font = nullptr; | ||||
|       lel::Parser $parser; | ||||
|       std::string $grid = ""; | ||||
| 
 | ||||
|       UI(); | ||||
| 
 | ||||
|       void position(int x, int y, int width, int height); | ||||
|       void layout(std::string grid); | ||||
|       DinkyECS::Entity init_entity(std::string name); | ||||
|       DinkyECS::Entity entity(std::string name); | ||||
| 
 | ||||
|       inline lel::CellMap& cells() { | ||||
|         return $parser.cells; | ||||
|       } | ||||
| 
 | ||||
|       inline DinkyECS::World& world() { | ||||
|         return $world; | ||||
|       } | ||||
| 
 | ||||
|       void init(); | ||||
|       void render(sf::RenderWindow& window); | ||||
|       bool mouse(float x, float y, bool hover); | ||||
|       void debug_layout(sf::RenderWindow& window); | ||||
| 
 | ||||
|       template <typename Comp> | ||||
|       void set(DinkyECS::Entity ent, Comp val) { | ||||
|         $world.set<Comp>(ent, val); | ||||
|       } | ||||
| 
 | ||||
|       template <typename Comp> | ||||
|       void set_init(DinkyECS::Entity ent, Comp val) { | ||||
|         dbc::check(has<lel::Cell>(ent),"WRONG! slot is missing its cell?!"); | ||||
|         auto& cell = get<lel::Cell>(ent); | ||||
|         val.init(cell); | ||||
|         $world.set<Comp>(ent, val); | ||||
|       } | ||||
| 
 | ||||
|       template <typename Comp> | ||||
|       void do_if(DinkyECS::Entity ent, std::function<void(Comp &)> cb) { | ||||
|         if($world.has<Comp>(ent)) { | ||||
|           cb($world.get<Comp>(ent)); | ||||
|         } | ||||
|       } | ||||
| 
 | ||||
|       lel::Cell& cell_for(DinkyECS::Entity ent) { | ||||
|         return $world.get<lel::Cell>(ent); | ||||
|       } | ||||
| 
 | ||||
|       lel::Cell& cell_for(std::string name) { | ||||
|         DinkyECS::Entity ent = entity(name); | ||||
|         return $world.get<lel::Cell>(ent); | ||||
|       } | ||||
| 
 | ||||
|       template <typename Comp> | ||||
|         Comp& get(DinkyECS::Entity entity) { | ||||
|           return $world.get<Comp>(entity); | ||||
|         } | ||||
| 
 | ||||
|       template <typename Comp> | ||||
|         std::optional<Comp> get_if(DinkyECS::Entity entity) { | ||||
|           return $world.get_if<Comp>(entity); | ||||
|         } | ||||
| 
 | ||||
|       template <typename Comp> | ||||
|         bool has(DinkyECS::Entity entity) { | ||||
|           return $world.has<Comp>(entity); | ||||
|         } | ||||
| 
 | ||||
|       template <typename Comp> | ||||
|         void remove(DinkyECS::Entity ent) { | ||||
|           $world.remove<Comp>(ent); | ||||
|         } | ||||
| 
 | ||||
|       template <typename Comp> | ||||
|       void close(string region) { | ||||
|         auto ent = entity(region); | ||||
|         remove<Comp>(ent); | ||||
|       } | ||||
| 
 | ||||
|       template<typename T> | ||||
|       void render_helper(sf::RenderWindow& window, DinkyECS::Entity ent, bool is_shape, T& target) { | ||||
|         sf::Shader *shader_ptr = nullptr; | ||||
| 
 | ||||
|         if($world.has<Effect>(ent)) { | ||||
|           auto& shader = $world.get<Effect>(ent); | ||||
| 
 | ||||
|           if(shader.$active) { | ||||
|             auto ptr = shader.checkout_ptr(); | ||||
|             ptr->setUniform("is_shape", is_shape); | ||||
|             // NOTE: this is needed because SFML doesn't handle shared_ptr
 | ||||
|             shader_ptr = ptr.get(); | ||||
|           } | ||||
|         } | ||||
| 
 | ||||
|         window.draw(*target, shader_ptr); | ||||
|       } | ||||
| 
 | ||||
|       void show_sprite(string region, string sprite_name); | ||||
|       void show_text(string region, wstring content); | ||||
|       void show_label(string region, wstring content); | ||||
|   }; | ||||
| 
 | ||||
|   Clickable make_action(DinkyECS::World& target, Events::GUI event); | ||||
| 
 | ||||
| } | ||||
							
								
								
									
										11
									
								
								gui.cpp
									
										
									
									
									
								
							
							
						
						
									
										11
									
								
								gui.cpp
									
										
									
									
									
								
							|  | @ -13,9 +13,12 @@ | |||
| #include <iostream> | ||||
| #include "sound.hpp" | ||||
| #include "shaders.hpp" | ||||
| #include "constants.hpp" | ||||
| #include "backend.hpp" | ||||
| 
 | ||||
| using std::string, std::vector; | ||||
| 
 | ||||
| 
 | ||||
| GUI::GUI(int timer_seconds, const std::wstring &g) : | ||||
|   $timer_seconds(timer_seconds), | ||||
|   $goal(g), | ||||
|  | @ -34,7 +37,7 @@ GUI::GUI(int timer_seconds, const std::wstring &g) : | |||
|      "[_|_|*%(300,100)clock|_|_]" | ||||
|      "[hp_bar]"); | ||||
| 
 | ||||
|   $gui.world().set_the<Background>({$gui.$parser, {0,0,0,0}}); | ||||
|   $gui.set<Background>($gui.MAIN, {$gui.$parser, {0,0,0,0}}); | ||||
| 
 | ||||
|   for(auto& [name, cell] : $gui.cells()) { | ||||
|     auto ent = $gui.entity(name); | ||||
|  | @ -54,17 +57,17 @@ GUI::GUI(int timer_seconds, const std::wstring &g) : | |||
| 
 | ||||
|   auto clock = $gui.entity("clock"); | ||||
|   auto& clock_rect = $gui.get<Rectangle>(clock); | ||||
|   clock_rect.color = ColorValue::BLACK; | ||||
|   clock_rect.color = THEME.BLACK; | ||||
|   $gui.set<Label>(clock, {L"00:00:00", 60}); | ||||
| 
 | ||||
|   auto goal = $gui.entity("goal"); | ||||
|   std::wstring msg = fmt::format(L"Complete '{}' in:", $goal); | ||||
|   auto& goal_rect = $gui.get<Rectangle>(goal); | ||||
|   goal_rect.color = ColorValue::BLACK; | ||||
|   goal_rect.color = THEME.BLACK; | ||||
|   $gui.set<Label>(goal, {msg, 30}); | ||||
| 
 | ||||
|   $hp_bar = $gui.entity("hp_bar"); | ||||
|   $gui.set<Meter>($hp_bar, {1.0f, {10, ColorValue::LIGHT_DARK}}); | ||||
|   $gui.set<Meter>($hp_bar, {}); | ||||
| 
 | ||||
|   $gui.init(); | ||||
| } | ||||
|  |  | |||
							
								
								
									
										6
									
								
								gui.hpp
									
										
									
									
									
								
							
							
						
						
									
										6
									
								
								gui.hpp
									
										
									
									
									
								
							|  | @ -2,7 +2,7 @@ | |||
| 
 | ||||
| #include <string> | ||||
| #include "game_engine.hpp" | ||||
| #include "guecs.hpp" | ||||
| #include <guecs/ui.hpp> | ||||
| 
 | ||||
| using std::string; | ||||
| 
 | ||||
|  | @ -14,8 +14,8 @@ class GUI { | |||
|   sf::RenderWindow $window; | ||||
|   guecs::UI $gui; | ||||
|   std::wstring $status; | ||||
|   DinkyECS::Entity $log; | ||||
|   DinkyECS::Entity $hp_bar; | ||||
|   guecs::Entity $log; | ||||
|   guecs::Entity $hp_bar; | ||||
|   bool $hit_error = false; | ||||
|   std::chrono::time_point<std::chrono::system_clock> $timer_end; | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										117
									
								
								lel.cpp
									
										
									
									
									
								
							
							
						
						
									
										117
									
								
								lel.cpp
									
										
									
									
									
								
							|  | @ -1,117 +0,0 @@ | |||
| #include "lel.hpp" | ||||
| #include <fmt/core.h> | ||||
| #include "dbc.hpp" | ||||
| #include <numeric> | ||||
| 
 | ||||
| #include "lel_parser.cpp" | ||||
| 
 | ||||
| namespace lel { | ||||
| 
 | ||||
|   Parser::Parser(int x, int y, int width, int height) : | ||||
|     grid_x(x), | ||||
|     grid_y(y), | ||||
|     grid_w(width), | ||||
|     grid_h(height), | ||||
|     cur(0, 0) | ||||
|   { | ||||
|   } | ||||
| 
 | ||||
|   Parser::Parser() : cur(0, 0) { } | ||||
| 
 | ||||
|   void Parser::position(int x, int y, int width, int height) { | ||||
|     grid_x = x; | ||||
|     grid_y = y; | ||||
|     grid_w = width; | ||||
|     grid_h = height; | ||||
|   } | ||||
| 
 | ||||
|   void Parser::id(std::string name) { | ||||
|     if(name != "_") { | ||||
|       dbc::check(!cells.contains(name), | ||||
|           fmt::format("duplicate cell name {}", name)); | ||||
|       cells.insert_or_assign(name, cur); | ||||
|     } | ||||
| 
 | ||||
|     cur = {cur.col + 1, cur.row}; | ||||
|     auto& row = grid.back(); | ||||
|     row.push_back(name); | ||||
|   } | ||||
| 
 | ||||
|   void Parser::finalize() { | ||||
|     size_t rows = grid.size(); | ||||
|     int cell_height = grid_h / rows; | ||||
| 
 | ||||
|     for(auto& row : grid) { | ||||
|       size_t columns = row.size(); | ||||
|       int cell_width = grid_w / columns; | ||||
|       dbc::check(cell_width > 0, "invalid cell width calc"); | ||||
|       dbc::check(cell_height > 0, "invalid cell height calc"); | ||||
| 
 | ||||
|       for(auto& name : row) { | ||||
|         if(name == "_") continue; | ||||
|         auto& cell = cells.at(name); | ||||
| 
 | ||||
|         // ZED: getting a bit hairy but this should work
 | ||||
|         if(cell.percent) { | ||||
|           // when percent mode we have to take unset to 100%
 | ||||
|           if(cell.max_w == 0) cell.max_w = 100; | ||||
|           if(cell.max_h == 0) cell.max_h = 100; | ||||
|           cell.max_w *= cell_width * 0.01; | ||||
|           cell.max_h *= cell_height * 0.01; | ||||
|         } else { | ||||
|           if(cell.max_w == 0) cell.max_w = cell_width; | ||||
|           if(cell.max_h == 0) cell.max_h = cell_height; | ||||
|         } | ||||
| 
 | ||||
|         cell.w = cell.expand ? std::min(cell.max_w, grid_w) : std::min(cell_width, cell.max_w); | ||||
|         cell.h = cell.expand ? std::min(cell.max_h, grid_h) : std::min(cell_height, cell.max_h); | ||||
| 
 | ||||
|         dbc::check(cell.h > 0, fmt::format("invalid height cell {}", name)); | ||||
|         dbc::check(cell.w > 0, fmt::format("invalid width cell {}", name)); | ||||
| 
 | ||||
|         cell.x = grid_x + (cell.col * cell_width); | ||||
|         cell.y = grid_y + (cell.row * cell_height); | ||||
| 
 | ||||
|         // keep the midpoint since it is used a lot
 | ||||
|         cell.mid_x = std::midpoint(cell.x, cell.x + cell.w); | ||||
|         cell.mid_y = std::midpoint(cell.y, cell.y + cell.h); | ||||
| 
 | ||||
|         // perform alignments
 | ||||
|         if(cell.right) cell.x += cell_width - cell.w; | ||||
|         if(cell.bottom) cell.y += cell_height - cell.h; | ||||
|         if(cell.center) { | ||||
|           cell.x = cell.mid_x - cell.w / 2; | ||||
|           cell.y = cell.mid_y - cell.h / 2; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   void Parser::reset() { | ||||
|     cur = {0, 0}; | ||||
|     grid.clear(); | ||||
|     cells.clear(); | ||||
|   } | ||||
| 
 | ||||
|   std::optional<std::string> Parser::hit(int x, int y) { | ||||
|     for(auto& [name, cell] : cells) { | ||||
|       if((x >= cell.x && x <= cell.x + cell.w) && | ||||
|           (y >= cell.y && y <= cell.y + cell.h)) { | ||||
|         return name; | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     return std::nullopt; | ||||
|   } | ||||
| 
 | ||||
|   Cell center(int width, int height, Cell &parent) { | ||||
|     Cell copy = parent; | ||||
| 
 | ||||
|     copy.x = parent.mid_x - width / 2; | ||||
|     copy.y = parent.mid_y - height / 2; | ||||
|     copy.w = width; | ||||
|     copy.h = height; | ||||
| 
 | ||||
|     return copy; | ||||
|   } | ||||
| } | ||||
							
								
								
									
										57
									
								
								lel.hpp
									
										
									
									
									
								
							
							
						
						
									
										57
									
								
								lel.hpp
									
										
									
									
									
								
							|  | @ -1,57 +0,0 @@ | |||
| #pragma once | ||||
| #include <string> | ||||
| #include <unordered_map> | ||||
| #include <functional> | ||||
| #include <optional> | ||||
| #include <vector> | ||||
| #include "dbc.hpp" | ||||
| 
 | ||||
| namespace lel { | ||||
| 
 | ||||
|   struct Cell { | ||||
|     int x = 0; | ||||
|     int y = 0; | ||||
|     int w = 0; | ||||
|     int h = 0; | ||||
|     int mid_x = 0; | ||||
|     int mid_y = 0; | ||||
|     int max_w = 0; | ||||
|     int max_h = 0; | ||||
|     int col = 0; | ||||
|     int row = 0; | ||||
|     bool right = false; | ||||
|     bool bottom = false; | ||||
|     bool expand = false; | ||||
|     bool center = false; | ||||
|     bool percent = false; | ||||
| 
 | ||||
|     Cell(int col, int row) : col(col), row(row) {} | ||||
|     Cell() {} | ||||
|   }; | ||||
| 
 | ||||
|   using Row = std::vector<std::string>; | ||||
|   using CellMap = std::unordered_map<std::string, Cell>; | ||||
| 
 | ||||
|   struct Parser { | ||||
|     int grid_x = 0; | ||||
|     int grid_y = 0; | ||||
|     int grid_w = 0; | ||||
|     int grid_h = 0; | ||||
|     Cell cur; | ||||
|     std::vector<Row> grid; | ||||
|     CellMap cells; | ||||
| 
 | ||||
|     Parser(int x, int y, int width, int height); | ||||
|     Parser(); | ||||
| 
 | ||||
|     void position(int x, int y, int width, int height); | ||||
|     void id(std::string name); | ||||
|     void reset(); | ||||
|     bool parse(std::string input); | ||||
|     void finalize(); | ||||
|     std::optional<std::string> hit(int x, int y); | ||||
|   }; | ||||
| 
 | ||||
| 
 | ||||
|   Cell center(int width, int height, Cell &parent); | ||||
| } | ||||
							
								
								
									
										263
									
								
								lel_parser.cpp
									
										
									
									
									
								
							
							
						
						
									
										263
									
								
								lel_parser.cpp
									
										
									
									
									
								
							|  | @ -1,263 +0,0 @@ | |||
| 
 | ||||
| #line 1 "lel_parser.rl" | ||||
| /***** !!!!!! THIS IS INCLUDED BY lel.cpp DO NOT PUT IN BUILD!!!!!! ******/ | ||||
| 
 | ||||
| #include "lel.hpp" | ||||
| #include <fmt/core.h> | ||||
| #include <iostream> | ||||
| 
 | ||||
| namespace lel { | ||||
| 
 | ||||
| 
 | ||||
| #line 42 "lel_parser.rl" | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| #line 12 "lel_parser.cpp" | ||||
| static const char _Parser_actions[] = { | ||||
| 	0, 1, 1, 1, 2, 1, 3, 1,  | ||||
| 	4, 1, 5, 1, 6, 1, 9, 1,  | ||||
| 	10, 1, 11, 1, 12, 1, 13, 2,  | ||||
| 	0, 7, 2, 0, 8, 2, 4, 1,  | ||||
| 	2, 4, 5 | ||||
| }; | ||||
| 
 | ||||
| static const char _Parser_key_offsets[] = { | ||||
| 	0, 0, 4, 20, 33, 35, 39, 41,  | ||||
| 	44, 56, 61 | ||||
| }; | ||||
| 
 | ||||
| static const char _Parser_trans_keys[] = { | ||||
| 	32, 91, 9, 13, 32, 37, 40, 42,  | ||||
| 	46, 61, 94, 95, 9, 13, 60, 62,  | ||||
| 	65, 90, 97, 122, 37, 40, 42, 46,  | ||||
| 	61, 94, 95, 60, 62, 65, 90, 97,  | ||||
| 	122, 48, 57, 41, 44, 48, 57, 48,  | ||||
| 	57, 41, 48, 57, 32, 93, 95, 124,  | ||||
| 	9, 13, 48, 57, 65, 90, 97, 122,  | ||||
| 	32, 93, 124, 9, 13, 32, 91, 9,  | ||||
| 	13, 0 | ||||
| }; | ||||
| 
 | ||||
| static const char _Parser_single_lengths[] = { | ||||
| 	0, 2, 8, 7, 0, 2, 0, 1,  | ||||
| 	4, 3, 2 | ||||
| }; | ||||
| 
 | ||||
| static const char _Parser_range_lengths[] = { | ||||
| 	0, 1, 4, 3, 1, 1, 1, 1,  | ||||
| 	4, 1, 1 | ||||
| }; | ||||
| 
 | ||||
| static const char _Parser_index_offsets[] = { | ||||
| 	0, 0, 4, 17, 28, 30, 34, 36,  | ||||
| 	39, 48, 53 | ||||
| }; | ||||
| 
 | ||||
| static const char _Parser_indicies[] = { | ||||
| 	0, 2, 0, 1, 3, 4, 5, 6,  | ||||
| 	7, 9, 7, 10, 3, 8, 10, 10,  | ||||
| 	1, 4, 5, 6, 7, 9, 7, 10,  | ||||
| 	8, 10, 10, 1, 11, 1, 12, 13,  | ||||
| 	14, 1, 15, 1, 16, 17, 1, 18,  | ||||
| 	20, 19, 21, 18, 19, 19, 19, 1,  | ||||
| 	22, 23, 24, 22, 1, 25, 2, 25,  | ||||
| 	1, 0 | ||||
| }; | ||||
| 
 | ||||
| static const char _Parser_trans_targs[] = { | ||||
| 	1, 0, 2, 2, 3, 4, 3, 3,  | ||||
| 	3, 3, 8, 5, 3, 6, 5, 7,  | ||||
| 	3, 7, 9, 8, 10, 2, 9, 10,  | ||||
| 	2, 10 | ||||
| }; | ||||
| 
 | ||||
| static const char _Parser_trans_actions[] = { | ||||
| 	0, 0, 3, 0, 17, 0, 13, 5,  | ||||
| 	11, 15, 21, 19, 23, 23, 0, 19,  | ||||
| 	26, 0, 7, 0, 32, 29, 0, 9,  | ||||
| 	1, 0 | ||||
| }; | ||||
| 
 | ||||
| static const int Parser_start = 1; | ||||
| static const int Parser_first_final = 10; | ||||
| static const int Parser_error = 0; | ||||
| 
 | ||||
| static const int Parser_en_main = 1; | ||||
| 
 | ||||
| 
 | ||||
| #line 45 "lel_parser.rl" | ||||
| 
 | ||||
| bool Parser::parse(std::string input) { | ||||
|   reset(); | ||||
|   int cs = 0; | ||||
|   const char *start = nullptr; | ||||
|   const char *begin = input.data(); | ||||
|   const char *p = input.data(); | ||||
|   const char *pe = p + input.size(); | ||||
|   std::string tk; | ||||
| 
 | ||||
|    | ||||
| #line 93 "lel_parser.cpp" | ||||
| 	{ | ||||
| 	cs = Parser_start; | ||||
| 	} | ||||
| 
 | ||||
| #line 56 "lel_parser.rl" | ||||
|    | ||||
| #line 96 "lel_parser.cpp" | ||||
| 	{ | ||||
| 	int _klen; | ||||
| 	unsigned int _trans; | ||||
| 	const char *_acts; | ||||
| 	unsigned int _nacts; | ||||
| 	const char *_keys; | ||||
| 
 | ||||
| 	if ( p == pe ) | ||||
| 		goto _test_eof; | ||||
| 	if ( cs == 0 ) | ||||
| 		goto _out; | ||||
| _resume: | ||||
| 	_keys = _Parser_trans_keys + _Parser_key_offsets[cs]; | ||||
| 	_trans = _Parser_index_offsets[cs]; | ||||
| 
 | ||||
| 	_klen = _Parser_single_lengths[cs]; | ||||
| 	if ( _klen > 0 ) { | ||||
| 		const char *_lower = _keys; | ||||
| 		const char *_mid; | ||||
| 		const char *_upper = _keys + _klen - 1; | ||||
| 		while (1) { | ||||
| 			if ( _upper < _lower ) | ||||
| 				break; | ||||
| 
 | ||||
| 			_mid = _lower + ((_upper-_lower) >> 1); | ||||
| 			if ( (*p) < *_mid ) | ||||
| 				_upper = _mid - 1; | ||||
| 			else if ( (*p) > *_mid ) | ||||
| 				_lower = _mid + 1; | ||||
| 			else { | ||||
| 				_trans += (unsigned int)(_mid - _keys); | ||||
| 				goto _match; | ||||
| 			} | ||||
| 		} | ||||
| 		_keys += _klen; | ||||
| 		_trans += _klen; | ||||
| 	} | ||||
| 
 | ||||
| 	_klen = _Parser_range_lengths[cs]; | ||||
| 	if ( _klen > 0 ) { | ||||
| 		const char *_lower = _keys; | ||||
| 		const char *_mid; | ||||
| 		const char *_upper = _keys + (_klen<<1) - 2; | ||||
| 		while (1) { | ||||
| 			if ( _upper < _lower ) | ||||
| 				break; | ||||
| 
 | ||||
| 			_mid = _lower + (((_upper-_lower) >> 1) & ~1); | ||||
| 			if ( (*p) < _mid[0] ) | ||||
| 				_upper = _mid - 2; | ||||
| 			else if ( (*p) > _mid[1] ) | ||||
| 				_lower = _mid + 2; | ||||
| 			else { | ||||
| 				_trans += (unsigned int)((_mid - _keys)>>1); | ||||
| 				goto _match; | ||||
| 			} | ||||
| 		} | ||||
| 		_trans += _klen; | ||||
| 	} | ||||
| 
 | ||||
| _match: | ||||
| 	_trans = _Parser_indicies[_trans]; | ||||
| 	cs = _Parser_trans_targs[_trans]; | ||||
| 
 | ||||
| 	if ( _Parser_trans_actions[_trans] == 0 ) | ||||
| 		goto _again; | ||||
| 
 | ||||
| 	_acts = _Parser_actions + _Parser_trans_actions[_trans]; | ||||
| 	_nacts = (unsigned int) *_acts++; | ||||
| 	while ( _nacts-- > 0 ) | ||||
| 	{ | ||||
| 		switch ( *_acts++ ) | ||||
| 		{ | ||||
| 	case 0: | ||||
| #line 13 "lel_parser.rl" | ||||
| 	{tk = input.substr(start - begin, p - start); } | ||||
| 	break; | ||||
| 	case 1: | ||||
| #line 15 "lel_parser.rl" | ||||
| 	{} | ||||
| 	break; | ||||
| 	case 2: | ||||
| #line 16 "lel_parser.rl" | ||||
| 	{ grid.push_back(Row()); } | ||||
| 	break; | ||||
| 	case 3: | ||||
| #line 17 "lel_parser.rl" | ||||
| 	{ cur.bottom = (*p) == '.'; } | ||||
| 	break; | ||||
| 	case 4: | ||||
| #line 18 "lel_parser.rl" | ||||
| 	{ id(input.substr(start - begin, p - start)); } | ||||
| 	break; | ||||
| 	case 5: | ||||
| #line 19 "lel_parser.rl" | ||||
| 	{ cur.col = 0; cur.row++; } | ||||
| 	break; | ||||
| 	case 6: | ||||
| #line 20 "lel_parser.rl" | ||||
| 	{ cur.right = (*p) == '>'; } | ||||
| 	break; | ||||
| 	case 7: | ||||
| #line 21 "lel_parser.rl" | ||||
| 	{cur.max_w = std::stoi(tk); } | ||||
| 	break; | ||||
| 	case 8: | ||||
| #line 22 "lel_parser.rl" | ||||
| 	{ cur.max_h = std::stoi(tk); } | ||||
| 	break; | ||||
| 	case 9: | ||||
| #line 23 "lel_parser.rl" | ||||
| 	{ cur.expand = true; } | ||||
| 	break; | ||||
| 	case 10: | ||||
| #line 24 "lel_parser.rl" | ||||
| 	{ cur.center = true; } | ||||
| 	break; | ||||
| 	case 11: | ||||
| #line 25 "lel_parser.rl" | ||||
| 	{ cur.percent = true; } | ||||
| 	break; | ||||
| 	case 12: | ||||
| #line 35 "lel_parser.rl" | ||||
| 	{ start = p; } | ||||
| 	break; | ||||
| 	case 13: | ||||
| #line 38 "lel_parser.rl" | ||||
| 	{start = p;} | ||||
| 	break; | ||||
| #line 211 "lel_parser.cpp" | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| _again: | ||||
| 	if ( cs == 0 ) | ||||
| 		goto _out; | ||||
| 	if ( ++p != pe ) | ||||
| 		goto _resume; | ||||
| 	_test_eof: {} | ||||
| 	_out: {} | ||||
| 	} | ||||
| 
 | ||||
| #line 57 "lel_parser.rl" | ||||
| 
 | ||||
|   bool good = pe - p == 0; | ||||
|   if(good) { | ||||
|     finalize(); | ||||
|   } else { | ||||
|     dbc::log("error at:"); | ||||
|     std::cout << p; | ||||
|   } | ||||
|   return good; | ||||
| } | ||||
| 
 | ||||
| } | ||||
|  | @ -1,68 +0,0 @@ | |||
| /***** !!!!!! THIS IS INCLUDED BY lel.cpp DO NOT PUT IN BUILD!!!!!! ******/ | ||||
| 
 | ||||
| #include "lel.hpp" | ||||
| #include <fmt/core.h> | ||||
| #include <iostream> | ||||
| 
 | ||||
| namespace lel { | ||||
| 
 | ||||
| %%{ | ||||
|   machine Parser; | ||||
|   alphtype char; | ||||
| 
 | ||||
|   action token {tk = input.substr(start - begin, fpc - start); } | ||||
| 
 | ||||
|   action col {} | ||||
|   action ltab { grid.push_back(Row()); } | ||||
|   action valign { cur.bottom = fc == '.'; } | ||||
|   action id { id(input.substr(start - begin, fpc - start)); } | ||||
|   action row { cur.col = 0; cur.row++; } | ||||
|   action align { cur.right = fc == '>'; } | ||||
|   action setwidth {cur.max_w = std::stoi(tk); } | ||||
|   action setheight { cur.max_h = std::stoi(tk); } | ||||
|   action expand { cur.expand = true; } | ||||
|   action center { cur.center = true; } | ||||
|   action percent { cur.percent = true; } | ||||
| 
 | ||||
|   col = "|" $col; | ||||
|   ltab = "[" $ltab; | ||||
|   rtab = "]" $row; | ||||
|   valign = ("^" | ".") $valign; | ||||
|   expand = "*" $expand; | ||||
|   center = "=" $center; | ||||
|   percent = "%" $percent; | ||||
|   halign = ("<" | ">") $align; | ||||
|   number =  digit+ >{ start = fpc; } %token; | ||||
|   setw = ("(" number %setwidth ("," number %setheight)? ")") ; | ||||
|   modifiers = (percent | center | expand | valign | halign | setw); | ||||
|   id = modifiers* ((alpha | '_')+ :>> (alnum | '_')*) >{start = fpc;} %id; | ||||
|   row = space* ltab space* id space* (col space* id space*)* space* rtab space*; | ||||
| 
 | ||||
|   main := row+; | ||||
| }%% | ||||
| 
 | ||||
| %% write data; | ||||
| 
 | ||||
| bool Parser::parse(std::string input) { | ||||
|   reset(); | ||||
|   int cs = 0; | ||||
|   const char *start = nullptr; | ||||
|   const char *begin = input.data(); | ||||
|   const char *p = input.data(); | ||||
|   const char *pe = p + input.size(); | ||||
|   std::string tk; | ||||
| 
 | ||||
|   %% write init; | ||||
|   %% write exec; | ||||
| 
 | ||||
|   bool good = pe - p == 0; | ||||
|   if(good) { | ||||
|     finalize(); | ||||
|   } else { | ||||
|     dbc::log("error at:"); | ||||
|     std::cout << p; | ||||
|   } | ||||
|   return good; | ||||
| } | ||||
| 
 | ||||
| } | ||||
							
								
								
									
										29
									
								
								main.cpp
									
										
									
									
									
								
							
							
						
						
									
										29
									
								
								main.cpp
									
										
									
									
									
								
							|  | @ -1,3 +1,5 @@ | |||
| #include "backend.hpp" | ||||
| #include "guecs/sfml/components.hpp" | ||||
| #include "builder.hpp" | ||||
| #include "gui.hpp" | ||||
| #include "config.hpp" | ||||
|  | @ -12,9 +14,11 @@ int main(int argc, char *argv[]) | |||
| { | ||||
|   int opt = 0; | ||||
|   int timer_seconds = 60 * 60; | ||||
|   int start_hp = 100; | ||||
|   int max_hp = 100; | ||||
|   std::wstring goal{L"No Goal"}; | ||||
| 
 | ||||
|   while((opt = getopt(argc, argv, "t:c:g:")) != -1) { | ||||
|   while((opt = getopt(argc, argv, "ht:c:g:H:M:")) != -1) { | ||||
|     switch(opt) { | ||||
|       case 't': | ||||
|         timer_seconds = atoi(optarg) * 60; | ||||
|  | @ -23,18 +27,27 @@ int main(int argc, char *argv[]) | |||
|       case 'c': | ||||
|         Config::set_base_dir(optarg); | ||||
|         break; | ||||
|       case 'g': | ||||
|         std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter; | ||||
|         goal = converter.from_bytes(optarg); | ||||
|       case 'g': { | ||||
|           std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter; | ||||
|           goal = converter.from_bytes(optarg); | ||||
|         } break; | ||||
|       case 'H': { | ||||
|           start_hp = std::atoi(optarg); | ||||
|         } break; | ||||
|       case 'M': { | ||||
|           max_hp = std::atoi(optarg); | ||||
|         } break; | ||||
|       case 'h': | ||||
|         fmt::println("USAGE: ttpit [-t time] [-c config_dir] [-g goal] [-H hp] [-M max_hp]"); | ||||
|         return 0; | ||||
|         break; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   sound::init(); | ||||
|   shaders::init(); | ||||
|   textures::init(); | ||||
|   sfml::Backend backend; | ||||
|   guecs::init(&backend); | ||||
| 
 | ||||
|   GameEngine game{100}; | ||||
|   GameEngine game{start_hp, max_hp}; | ||||
|   GUI gui(timer_seconds, goal); | ||||
|   auto builder = Builder(gui, game); | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										11
									
								
								meson.build
									
										
									
									
									
								
							
							
						
						
									
										11
									
								
								meson.build
									
										
									
									
									
								
							|  | @ -1,7 +1,7 @@ | |||
| # clang might need _LIBCPP_ENABLE_CXX26_REMOVED_CODECVT | ||||
| 
 | ||||
| project('turings-tarpit', 'cpp', | ||||
|   version: '0.1.0', | ||||
|   version: '0.2.0', | ||||
|   default_options: [ | ||||
|     'cpp_std=c++20', | ||||
|     'cpp_args=-D_GLIBCXX_DEBUG=1 -D_GLIBCXX_DEBUG_PEDANTIC=1', | ||||
|  | @ -69,6 +69,7 @@ sfml_network = dependency('sfml_network') | |||
| sfml_system = dependency('sfml_system') | ||||
| sfml_window = dependency('sfml_window', | ||||
|   default_options: ['default_library=shared']) | ||||
| lel_guecs = dependency('lel_guecs') | ||||
| 
 | ||||
| cmake = import('cmake') | ||||
| opts = cmake.subproject_options() | ||||
|  | @ -89,23 +90,22 @@ dependencies += [ | |||
|   flac, ogg, vorbis, vorbisfile, vorbisenc, | ||||
|   sfml_audio, sfml_graphics, | ||||
|   sfml_network, sfml_system, | ||||
|   sfml_window, libgit2package, efsw | ||||
|   sfml_window, libgit2package, efsw, lel_guecs | ||||
| ] | ||||
| 
 | ||||
| sources = [ | ||||
|     'builder.cpp', | ||||
|     'config.cpp', | ||||
|     'dbc.cpp', | ||||
|     'game_engine.cpp', | ||||
|     'guecs.cpp', | ||||
|     'gui.cpp', | ||||
|     'lel.cpp', | ||||
|     'matrix.cpp', | ||||
|     'rand.cpp', | ||||
|     'shaders.cpp', | ||||
|     'sound.cpp', | ||||
|     'dbc.cpp', | ||||
|     'textures.cpp', | ||||
|     'watcher.cpp', | ||||
|     'backend.cpp', | ||||
| ] | ||||
| 
 | ||||
| executable('ttpit', sources + [ | ||||
|  | @ -119,7 +119,6 @@ executable('ttpit', sources + [ | |||
| executable('runtests', sources + [ | ||||
|   'tests/game_engine.cpp', | ||||
|   'tests/fsm.cpp', | ||||
|   'tests/dbc.cpp', | ||||
|   ], | ||||
|   cpp_args: cpp_args, | ||||
|   link_args: link_args, | ||||
|  |  | |||
							
								
								
									
										10
									
								
								shaders.cpp
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								shaders.cpp
									
										
									
									
									
								
							|  | @ -1,8 +1,8 @@ | |||
| #include "shaders.hpp" | ||||
| #include <SFML/Graphics/Image.hpp> | ||||
| #include "guecs/sfml/shaders.hpp" | ||||
| #include "guecs/sfml/config.hpp" | ||||
| #include "dbc.hpp" | ||||
| #include <SFML/Graphics/Image.hpp> | ||||
| #include <fmt/core.h> | ||||
| #include "config.hpp" | ||||
| #include <memory> | ||||
| 
 | ||||
| namespace shaders { | ||||
|  | @ -18,10 +18,8 @@ namespace shaders { | |||
| 
 | ||||
|   bool load_shader(std::string name, nlohmann::json& settings) { | ||||
|     std::string file_name = settings["file_name"]; | ||||
| 
 | ||||
|     auto ptr = std::make_shared<sf::Shader>(); | ||||
|     bool good = ptr->loadFromFile(Config::path_to(file_name), | ||||
|         sf::Shader::Type::Fragment); | ||||
|     bool good = ptr->loadFromFile(file_name, sf::Shader::Type::Fragment); | ||||
| 
 | ||||
|     if(good) { | ||||
|       configure_shader_defaults(ptr); | ||||
|  |  | |||
|  | @ -5,7 +5,6 @@ | |||
| #include <SFML/Graphics.hpp> | ||||
| #include <unordered_map> | ||||
| #include <memory> | ||||
| #include "matrix.hpp" | ||||
| #include <nlohmann/json.hpp> | ||||
| 
 | ||||
| namespace shaders { | ||||
|  |  | |||
							
								
								
									
										11
									
								
								sound.cpp
									
										
									
									
									
								
							
							
						
						
									
										11
									
								
								sound.cpp
									
										
									
									
									
								
							|  | @ -1,7 +1,7 @@ | |||
| #include "sound.hpp" | ||||
| #include "guecs/sfml/sound.hpp" | ||||
| #include "guecs/sfml/config.hpp" | ||||
| #include "dbc.hpp" | ||||
| #include <fmt/core.h> | ||||
| #include "config.hpp" | ||||
| 
 | ||||
| namespace sound { | ||||
|   static SoundManager SMGR; | ||||
|  | @ -28,7 +28,7 @@ namespace sound { | |||
| 
 | ||||
|   void init() { | ||||
|     if(!initialized) { | ||||
|       Config assets("./assets/config.json"); | ||||
|       Config assets("assets/config.json"); | ||||
| 
 | ||||
|       for(auto& el : assets["sounds"].items()) { | ||||
|         load(el.key(), el.value()); | ||||
|  | @ -38,11 +38,10 @@ namespace sound { | |||
|   } | ||||
| 
 | ||||
|   void load(const std::string& name, const std::string& sound_path) { | ||||
|     dbc::check(fs::exists(Config::path_to(sound_path)), | ||||
|         fmt::format("sound file {} does not exist", sound_path)); | ||||
|     dbc::check(fs::exists(sound_path), fmt::format("sound file {} does not exist", sound_path)); | ||||
| 
 | ||||
|     // create the buffer and keep in the buffer map
 | ||||
|     auto buffer = make_shared<sf::SoundBuffer>(Config::path_to(sound_path)); | ||||
|     auto buffer = make_shared<sf::SoundBuffer>(sound_path); | ||||
| 
 | ||||
|     // set it on the sound and keep in the sound map
 | ||||
|     auto sound = make_shared<sf::Sound>(*buffer); | ||||
|  |  | |||
|  | @ -1,39 +0,0 @@ | |||
| #include <catch2/catch_test_macros.hpp> | ||||
| #include "dbc.hpp" | ||||
| 
 | ||||
| using namespace dbc; | ||||
| 
 | ||||
| TEST_CASE("basic feature tests", "[utils]") { | ||||
|   log("Logging a message."); | ||||
| 
 | ||||
|   try { | ||||
|     sentinel("This shouldn't happen."); | ||||
|   } catch(SentinelError) { | ||||
|     log("Sentinel happened."); | ||||
|   } | ||||
| 
 | ||||
|   pre("confirm positive cases work", 1 == 1); | ||||
|   pre("confirm positive lambda", [&]{ return 1 == 1;}); | ||||
|   post("confirm positive post", 1 == 1); | ||||
|   post("confirm postitive post with lamdba", [&]{ return 1 == 1;}); | ||||
| 
 | ||||
|   check(1 == 1, "one equals 1"); | ||||
| 
 | ||||
|   try { | ||||
|     check(1 == 2, "this should fail"); | ||||
|   } catch(CheckError err) { | ||||
|     log("check fail worked"); | ||||
|   } | ||||
| 
 | ||||
|   try { | ||||
|     pre("failing pre", 1 == 3); | ||||
|   } catch(PreCondError err) { | ||||
|     log("pre fail worked"); | ||||
|   } | ||||
| 
 | ||||
|   try { | ||||
|     post("failing post", 1 == 4); | ||||
|   } catch(PostCondError err) { | ||||
|     log("post faile worked"); | ||||
|   } | ||||
| } | ||||
|  | @ -6,7 +6,7 @@ using namespace fmt; | |||
| 
 | ||||
| TEST_CASE("game engine death cycle", "[game_engine]") { | ||||
|   // test fails on purpose right now
 | ||||
|   GameEngine game{4}; | ||||
|   GameEngine game{4, 4}; | ||||
| 
 | ||||
|   for(int i = 0; i < 4; i++) { | ||||
|     game.event(GameEvent::BUILD_START); | ||||
|  | @ -36,7 +36,7 @@ TEST_CASE("game engine death cycle", "[game_engine]") { | |||
| } | ||||
| 
 | ||||
| TEST_CASE("game can do success build", "[game_engine]") { | ||||
|   GameEngine game{10}; | ||||
|   GameEngine game{10, 10}; | ||||
| 
 | ||||
|   // test fails on purpose right now
 | ||||
|   for(int i = 0; i < 10; i++) { | ||||
|  |  | |||
							
								
								
									
										45
									
								
								textures.cpp
									
										
									
									
									
								
							
							
						
						
									
										45
									
								
								textures.cpp
									
										
									
									
									
								
							|  | @ -1,8 +1,8 @@ | |||
| #include "textures.hpp" | ||||
| #include <SFML/Graphics/Image.hpp> | ||||
| #include "dbc.hpp" | ||||
| #include <fmt/core.h> | ||||
| #include "textures.hpp" | ||||
| #include "config.hpp" | ||||
| #include <SFML/Graphics/Image.hpp> | ||||
| #include <fmt/core.h> | ||||
| #include <memory> | ||||
| 
 | ||||
| namespace textures { | ||||
|  | @ -15,7 +15,7 @@ namespace textures { | |||
|     Config assets("assets/config.json"); | ||||
| 
 | ||||
|     for(auto& [name, settings] : assets["sprites"].items()) { | ||||
|       auto texture = make_shared<sf::Texture>(Config::path_to(settings["path"])); | ||||
|       auto texture = make_shared<sf::Texture>(settings["path"]); | ||||
| 
 | ||||
|       texture->setSmooth(assets["graphics"]["smooth_textures"]); | ||||
|       auto sprite = make_shared<sf::Sprite>(*texture); | ||||
|  | @ -24,32 +24,18 @@ namespace textures { | |||
|       int height = settings["frame_height"]; | ||||
|       sprite->setTextureRect({{0,0}, {width, height}}); | ||||
| 
 | ||||
|       TMGR.sprite_textures.try_emplace(name, name, sprite, texture); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   void load_tiles() { | ||||
|     Config assets("assets/tiles.json"); | ||||
|     auto &tiles = assets.json(); | ||||
| 
 | ||||
|     for(auto &el : tiles.items()) { | ||||
|       auto &config = el.value(); | ||||
|       TMGR.surfaces.emplace_back(load_image(config["texture"])); | ||||
|       wchar_t tid = config["display"]; | ||||
|       int surface_i = TMGR.surfaces.size() - 1; | ||||
|       TMGR.char_to_texture[tid] = surface_i; | ||||
|       TMGR.sprite_textures.try_emplace(name, sprite, texture); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   void init() { | ||||
|     if(!initialized) { | ||||
|       load_tiles(); | ||||
|       load_sprites(); | ||||
|       initialized = true; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   SpriteTexture get(std::string name) { | ||||
|   SpriteTexture get(const std::string& name) { | ||||
|     dbc::check(initialized, "you forgot to call textures::init()"); | ||||
|     dbc::check(TMGR.sprite_textures.contains(name), | ||||
|         fmt::format("!!!!! texture pack does not contain {} sprite", name)); | ||||
|  | @ -64,25 +50,10 @@ namespace textures { | |||
|     return result; | ||||
|   } | ||||
| 
 | ||||
|   sf::Image load_image(std::string filename) { | ||||
|   sf::Image load_image(const std::string& filename) { | ||||
|     sf::Image texture; | ||||
|     bool good = texture.loadFromFile(Config::path_to(filename)); | ||||
|     bool good = texture.loadFromFile(filename); | ||||
|     dbc::check(good, fmt::format("failed to load {}", filename)); | ||||
|     return texture; | ||||
|   } | ||||
| 
 | ||||
|   const uint32_t* get_surface(size_t num) { | ||||
|     return (const uint32_t *)TMGR.surfaces[num].getPixelsPtr(); | ||||
|   } | ||||
| 
 | ||||
|   matrix::Matrix convert_char_to_texture(matrix::Matrix &tile_ids) { | ||||
|     auto result = matrix::make(matrix::width(tile_ids), matrix::height(tile_ids)); | ||||
| 
 | ||||
|     for(matrix::each_cell it(tile_ids); it.next();) { | ||||
|       wchar_t tid = tile_ids[it.y][it.x]; | ||||
|       result[it.y][it.x] = TMGR.char_to_texture.at(tid); | ||||
|     } | ||||
| 
 | ||||
|     return result; | ||||
|   } | ||||
| }; | ||||
|  |  | |||
							
								
								
									
										10
									
								
								textures.hpp
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								textures.hpp
									
										
									
									
									
								
							|  | @ -5,12 +5,10 @@ | |||
| #include <SFML/Graphics.hpp> | ||||
| #include <unordered_map> | ||||
| #include <memory> | ||||
| #include "matrix.hpp" | ||||
| 
 | ||||
| namespace textures { | ||||
| 
 | ||||
|   struct SpriteTexture { | ||||
|     std::string name; | ||||
|     std::shared_ptr<sf::Sprite> sprite = nullptr; | ||||
|     std::shared_ptr<sf::Texture> texture = nullptr; | ||||
|   }; | ||||
|  | @ -23,11 +21,7 @@ namespace textures { | |||
| 
 | ||||
|   void init(); | ||||
| 
 | ||||
|   SpriteTexture get(std::string name); | ||||
|   SpriteTexture get(const std::string& name); | ||||
| 
 | ||||
|   sf::Image load_image(std::string filename); | ||||
| 
 | ||||
|   const uint32_t* get_surface(size_t num); | ||||
| 
 | ||||
|   matrix::Matrix convert_char_to_texture(matrix::Matrix &from); | ||||
|   sf::Image load_image(const std::string& filename); | ||||
| } | ||||
|  |  | |||
							
								
								
									
										9
									
								
								wraps/lel-guecs.wrap
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								wraps/lel-guecs.wrap
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,9 @@ | |||
| [wrap-git] | ||||
| directory=lel-guecs-0.2.0 | ||||
| url=https://git.learnjsthehardway.com/learn-code-the-hard-way/lel-guecs.git | ||||
| revision=HEAD | ||||
| depth=1 | ||||
| method=meson | ||||
| 
 | ||||
| [provide] | ||||
| lel_guecs = lel_guecs_dep | ||||
|  | @ -1,7 +1,7 @@ | |||
| [wrap-git] | ||||
| directory=SFML-3.0.0 | ||||
| directory=SFML-3.0.1 | ||||
| url=https://github.com/SFML/SFML.git | ||||
| revision=3.0.0 | ||||
| revision=3.0.1 | ||||
| depth=1 | ||||
| method=cmake | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Zed A. Shaw
						Zed A. Shaw