diff --git a/config/engine.toml b/config/engine.toml index b8e8403..5ff270d 100644 --- a/config/engine.toml +++ b/config/engine.toml @@ -1,6 +1,12 @@ [display] target_fps = 61 -show_fps = true window_width = 800 window_height = 600 -window_title = "Roguelike Algorithm Visualizer" \ No newline at end of file +window_title = "Roguelike Algorithm Visualizer" + +[overlay] +show_fps = true + +[font] +default_font_name = "Consolas-Regular" +default_font_size = 12 \ No newline at end of file diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index 658635c..e3f36e6 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -17,7 +17,7 @@ void Engine::start_loop() { if(renderer == nullptr) { throw MissingRendererException(); } - auto render_params = RendererParams{this->config.window_title, this->config.window_width, this->config.window_height}; + auto render_params = RendererParams{this->config.window_title, this->config.window_width, this->config.window_height, this->config.default_font}; renderer->initialize(render_params); renderer->flush(); auto game_params = GameInitArgs{this->config.target_fps, this->config.window_width, this->config.window_height}; @@ -47,12 +47,14 @@ Engine::Engine(std::unique_ptr game, std::unique_ptr renderer, this->input_processor = std::move(input_processor); EngineConfig new_config = EngineConfig(); load_config("engine.toml", [&new_config](const toml::table& table) { - new_config.show_fps = table["display"]["show_fps"].value_or(DEFAULT_SHOW_FPS); + new_config.show_fps = table["overlay"]["show_fps"].value_or(DEFAULT_SHOW_FPS); new_config.window_width = table["display"]["window_width"].value_or(DEFAULT_WINDOW_WIDTH); new_config.window_height = table["display"]["window_height"].value_or(DEFAULT_WINDOW_HEIGHT); new_config.target_fps = table["display"]["target_fps"].value_or(DEFAULT_TARGET_FPS); new_config.window_title = table["display"]["window_title"].value_or(DEFAULT_WINDOW_TITLE); - + auto default_font_path = fmt::format("fonts/{}.ttf", table["font"]["default_font_name"].value_or(DEFAULT_FONT_NAME)); + auto default_font_size = table["font"]["default_font_size"].value_or(DEFAULT_FONT_SIZE); + new_config.default_font = TextRenderDetails{default_font_path, default_font_size, COLOR_WHITE}; }); this->config = new_config; } @@ -64,7 +66,7 @@ Engine::render_fps(std::chrono::time_point end, std::chrono::duration dur = end - lastframe; if(this->config.show_fps) { //printf("fps: %f\n", frames/dur.count()); - this->renderer->draw_text(DEFAULT_FONT, fmt::format("{:.2f}", frames/dur.count()), 0, 0); + this->renderer->draw_text(std::nullopt, fmt::format("{:.2f}", frames/dur.count()), 0, 0); } return end; } diff --git a/src/engine/engine.hpp b/src/engine/engine.hpp index 4ae2e8a..4b8490a 100644 --- a/src/engine/engine.hpp +++ b/src/engine/engine.hpp @@ -22,12 +22,8 @@ #define DEFAULT_WINDOW_HEIGHT 600 #define DEFAULT_WINDOW_TITLE "RLEngine" #define DEFAULT_SHOW_FPS false - -static const TextRenderDetails DEFAULT_FONT = TextRenderDetails( - "fonts/Consolas-Regular.ttf", - 12, - COLOR_WHITE - ); +#define DEFAULT_FONT_NAME "Consolas-Regular" +#define DEFAULT_FONT_SIZE 12 struct EngineConfig { unsigned int target_fps; diff --git a/src/engine/rendering/renderer.hpp b/src/engine/rendering/renderer.hpp index 20b587a..4c91ba1 100644 --- a/src/engine/rendering/renderer.hpp +++ b/src/engine/rendering/renderer.hpp @@ -50,6 +50,7 @@ struct RendererParams { std::string title; int width; int height; + TextRenderDetails default_font; }; class Renderer { @@ -57,7 +58,7 @@ public: virtual void initialize(RendererParams params)=0; virtual void flush() = 0; virtual void draw_point(int x, int y, Color color) = 0; - virtual void draw_text(TextRenderDetails details, std::string text,int x, int y)=0; + virtual void draw_text(std::optional details, std::string text,int x, int y)=0; virtual void draw_sprite(Sprite sprite, int x, int y)=0; }; diff --git a/src/engine/rendering/sdl/sdlfontmanager.cpp b/src/engine/rendering/sdl/sdlfontmanager.cpp index e7794de..d6d1ef5 100644 --- a/src/engine/rendering/sdl/sdlfontmanager.cpp +++ b/src/engine/rendering/sdl/sdlfontmanager.cpp @@ -12,8 +12,7 @@ std::shared_ptr SdlFontManager::load_resource(SdlFontArgs args) { std::string path = get_resource_path(args.font_path); TTF_Font *font = TTF_OpenFont(path.c_str(), args.size); if(font == nullptr) { - printf("Could not load font: %s\n", TTF_GetError()); - return nullptr; + throw MissingFontException(path, TTF_GetError()); } return std::shared_ptr(font, TTF_CloseFont); } diff --git a/src/engine/rendering/sdl/sdlfontmanager.hpp b/src/engine/rendering/sdl/sdlfontmanager.hpp index 7fa886f..4d742db 100644 --- a/src/engine/rendering/sdl/sdlfontmanager.hpp +++ b/src/engine/rendering/sdl/sdlfontmanager.hpp @@ -25,4 +25,21 @@ class SdlFontManager : public ResourceManager, std::st }; + + +class MissingFontException : public std::exception { +private: + std::string msg; + +public: + [[nodiscard]] const char *what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_NOTHROW override { + return msg.c_str(); + } + + explicit MissingFontException(const std::string& missing_font, std::string reason) { + msg = fmt::format("Unable to load font [{}] because: {}", missing_font, reason); + } +}; + + #endif //RLA_IIPP_SDLFONTMANAGER_HPP diff --git a/src/engine/rendering/sdl/sdlrenderer.cpp b/src/engine/rendering/sdl/sdlrenderer.cpp index ec920ea..e6e8be0 100644 --- a/src/engine/rendering/sdl/sdlrenderer.cpp +++ b/src/engine/rendering/sdl/sdlrenderer.cpp @@ -47,9 +47,10 @@ void SdlRenderer::draw_point(int x, int y, Color color) { SDL_RenderDrawPoint(this->renderer.get(), x, y); } -void SdlRenderer::draw_text(TextRenderDetails details, std::string text, int x, int y) { - std::shared_ptr font = this->font_manager->fetch_resource(SdlFontArgs(details.size, details.font_path)); - std::shared_ptr texture = this->texture_manager->load_text_as_texture(text, font, details.color); +void SdlRenderer::draw_text(std::optional details, std::string text, int x, int y) { + TextRenderDetails unpacked_details = details.value_or(this->renderer_params.default_font); + std::shared_ptr font = this->font_manager->fetch_resource(SdlFontArgs(unpacked_details.size, unpacked_details.font_path)); + std::shared_ptr texture = this->texture_manager->load_text_as_texture(text, font, unpacked_details.color); render_texture(x, y, texture, nullptr); } diff --git a/src/engine/rendering/sdl/sdlrenderer.hpp b/src/engine/rendering/sdl/sdlrenderer.hpp index bac5fd4..ade2831 100644 --- a/src/engine/rendering/sdl/sdlrenderer.hpp +++ b/src/engine/rendering/sdl/sdlrenderer.hpp @@ -18,7 +18,7 @@ struct SDL_WindowDeleter { class SdlRenderer : public Renderer { public: ~SdlRenderer(); - void draw_text(TextRenderDetails details, std::string text, int x, int y) override; + void draw_text(std::optional details, std::string text, int x, int y) override; void initialize(RendererParams params) override; void flush() override; void draw_point(int x, int y, Color color) override; @@ -31,7 +31,6 @@ private: std::shared_ptr renderer = nullptr; std::unique_ptr texture_manager = nullptr; std::unique_ptr font_manager = nullptr; - void render_texture(int x, int y, const std::shared_ptr& texture, SDL_Rect *src); }; diff --git a/src/engine/rendering/sdl/sdltexturemanager.cpp b/src/engine/rendering/sdl/sdltexturemanager.cpp index 7b7c0e9..0c93ff5 100644 --- a/src/engine/rendering/sdl/sdltexturemanager.cpp +++ b/src/engine/rendering/sdl/sdltexturemanager.cpp @@ -16,7 +16,7 @@ std::shared_ptr SdlTextureManager::load_resource(TextureManagerFetc std::string full_path = get_resource_path(args.path); SDL_Surface* surface = load_surface(full_path); if(surface == nullptr) { - return nullptr; + throw MissingTextureException(full_path, SDL_GetError()); } if(args.color_key.has_value()) { Color color_key = args.color_key.value(); @@ -24,6 +24,9 @@ std::shared_ptr SdlTextureManager::load_resource(TextureManagerFetc } SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer.get(), surface); SDL_FreeSurface(surface); + if(texture == nullptr) { + throw MissingTextureException(full_path, SDL_GetError()); + } return std::shared_ptr(texture, SDL_DestroyTexture); } @@ -39,9 +42,12 @@ std::string SdlTextureManager::get_key(TextureManagerFetchArgs args) { std::shared_ptr SdlTextureManager::load_text_as_texture(const std::string& text, const std::shared_ptr& font, Color color) { SDL_Surface *surface = TTF_RenderText_Solid(font.get(), text.c_str(), {color.r, color.g, color.b}); if(surface == nullptr) { - return nullptr; + throw MissingTextureException("font", SDL_GetError()); } SDL_Texture *texture = SDL_CreateTextureFromSurface(this->renderer.get(), surface); SDL_FreeSurface(surface); + if(texture == nullptr) { + throw MissingTextureException("font", SDL_GetError()); + } return std::shared_ptr(texture, SDL_DestroyTexture); } diff --git a/src/engine/rendering/sdl/sdltexturemanager.hpp b/src/engine/rendering/sdl/sdltexturemanager.hpp index 0582b4f..1378b06 100644 --- a/src/engine/rendering/sdl/sdltexturemanager.hpp +++ b/src/engine/rendering/sdl/sdltexturemanager.hpp @@ -34,5 +34,18 @@ private: static SDL_Surface* load_surface(const std::string& path); }; +class MissingTextureException: public std::exception { +private: + std::string msg; +public: + [[nodiscard]] const char *what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_NOTHROW override { + return msg.c_str(); + } + + MissingTextureException(const std::string& path, const std::string& error) { + msg = fmt::format("Failed ot load texture at path [{}] because: {}", path, error); + } +}; + #endif //RLA_IIPP_SDLTEXTUREMANAGER_HPP