#include "core/rendering/render_info.hpp" #include #include #include #include "core/rendering/screen.hpp" #include "core/rendering/text.hpp" #include "core/resources/resource_cache.hpp" #include "game/options.hpp" #include "game/ui/ui_palette.hpp" #include "utils/defines.hpp" namespace { constexpr int TEXT_SIZE = 8; constexpr int PADDING_V = (RenderInfo::HEIGHT - TEXT_SIZE) / 2; auto prettify(std::string s) -> std::string { std::ranges::replace(s, '-', ' '); std::ranges::transform(s, s.begin(), [](unsigned char c) { return std::tolower(c); }); return s; } } // namespace auto RenderInfo::get() -> RenderInfo& { static RenderInfo instance_; return instance_; } RenderInfo::~RenderInfo() = default; void RenderInfo::init() { // El Director preloade la paleta "ui" i la surface "8bithud.gif"; ací // només construïm el Text. Així Notifier i altres HUDs comparteixen // recursos sense contenir la lògica de càrrega. auto font_surface = Resource::Cache::get().getSurface("8bithud.gif"); text_ = std::make_unique(font_surface, "data/font/8bithud.fnt"); // Restaura l'estat guardat a config.yaml (video.render_info). if (Options::video.render_info) { status_ = Status::ACTIVE; y_ = 0.0F; } } void RenderInfo::update(int delta_ms) { const float DT = static_cast(delta_ms) / 1000.0F; switch (status_) { case Status::RISING: y_ += SLIDE_SPEED * DT; if (y_ >= 0.0F) { y_ = 0.0F; status_ = Status::ACTIVE; } break; case Status::VANISHING: y_ -= SLIDE_SPEED * DT; if (y_ <= static_cast(-HEIGHT)) { y_ = static_cast(-HEIGHT); status_ = Status::HIDDEN; } break; default: break; } } void RenderInfo::render() { if (status_ == Status::HIDDEN || text_ == nullptr) { return; } std::string line = std::to_string(Screen::get().getLastFPS()) + " fps"; const auto& driver = Screen::get().getGPUDriver(); line += " | " + (driver.empty() ? std::string("sdl") : driver); if (Options::video.shader.enabled) { const std::string& shader = Options::video.shader.current_shader; const std::string& preset = (shader == "crtpi") ? Options::video.shader.current_crtpi_preset : Options::video.shader.current_postfx_preset; line += " | " + shader + " " + prettify(preset); } line = prettify(line); text_->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG, GameCanvas::CENTER_X, static_cast(y_) + PADDING_V, line, 1, UiColor::RENDER_INFO_TEXT); } void RenderInfo::toggle() { switch (status_) { case Status::HIDDEN: status_ = Status::RISING; Options::video.render_info = true; Options::saveToFile(); break; case Status::ACTIVE: status_ = Status::VANISHING; Options::video.render_info = false; Options::saveToFile(); break; default: break; } }