diff --git a/source/core/rendering/sdl_manager.cpp b/source/core/rendering/sdl_manager.cpp index a28d693..7c87478 100644 --- a/source/core/rendering/sdl_manager.cpp +++ b/source/core/rendering/sdl_manager.cpp @@ -21,8 +21,10 @@ namespace { auto initWindowAndGpu(SDL_Window** out_window, Rendering::Renderer& gpu_renderer, int width, int height, bool fullscreen) -> bool { - // Construir título dinámico - const std::string TITLE = std::format("{} v{} ({})", Project::LONG_NAME, Project::VERSION, Project::COPYRIGHT); + // Título estático estilo CCAE. El FPS y el estado de VSync los muestra + // el DebugOverlay (toggle F11), no la barra de título. + const std::string TITLE = std::format("© 2026 {} — JailDesigner", + Project::LONG_NAME); SDL_WindowFlags flags = SDL_WINDOW_RESIZABLE; if (fullscreen) { @@ -62,9 +64,6 @@ auto initWindowAndGpu(SDL_Window** out_window, SDLManager::SDLManager() : finestra_(nullptr), - fps_accumulator_(0.0F), - fps_frame_count_(0), - fps_display_(0), current_width_(Defaults::Window::WIDTH), current_height_(Defaults::Window::HEIGHT), is_fullscreen_(false), @@ -95,9 +94,6 @@ SDLManager::SDLManager() SDLManager::SDLManager(int width, int height, bool fullscreen) : finestra_(nullptr), - fps_accumulator_(0.0F), - fps_frame_count_(0), - fps_display_(0), current_width_(width), current_height_(height), is_fullscreen_(fullscreen), @@ -334,47 +330,8 @@ void SDLManager::present() { gpu_renderer_.endFrame(); } -void SDLManager::updateColors(float delta_time) { - // No-op desde la migración a postpro. La oscilación de brillo y el pulso - // de fondo los aplica shaders/postfx.frag.glsl directamente sobre wall-clock. - (void)delta_time; -} - -void SDLManager::updateFPS(float delta_time) { - fps_accumulator_ += delta_time; - fps_frame_count_++; - - if (fps_accumulator_ >= 0.5F) { - fps_display_ = static_cast(fps_frame_count_ / fps_accumulator_); - fps_frame_count_ = 0; - fps_accumulator_ = 0.0F; - - std::string vsync_state = (Options::rendering.vsync == 1) ? "ON" : "OFF"; - std::string title = std::format("{} v{} ({}) - {} FPS - VSync: {}", - Project::LONG_NAME, - Project::VERSION, - Project::COPYRIGHT, - fps_display_, - vsync_state); - - if (finestra_ != nullptr) { - SDL_SetWindowTitle(finestra_, title.c_str()); - } - } -} - -void SDLManager::setWindowTitle(const std::string& title) { - if (finestra_ != nullptr) { - SDL_SetWindowTitle(finestra_, title.c_str()); - } -} - void SDLManager::toggleVSync() { Options::rendering.vsync = (Options::rendering.vsync == 1) ? 0 : 1; gpu_renderer_.setVSync(Options::rendering.vsync != 0); - - fps_accumulator_ = 0.0F; - fps_frame_count_ = 0; - Options::saveToFile(); } diff --git a/source/core/rendering/sdl_manager.hpp b/source/core/rendering/sdl_manager.hpp index 81ce63f..618d31d 100644 --- a/source/core/rendering/sdl_manager.hpp +++ b/source/core/rendering/sdl_manager.hpp @@ -11,7 +11,6 @@ #include #include -#include #include "core/rendering/render_context.hpp" @@ -36,21 +35,10 @@ class SDLManager { void clear(uint8_t r = 0, uint8_t g = 0, uint8_t b = 0); void present(); - // No-op desde la migración a postpro (la oscilación de brillo la - // gestiona el shader, no la CPU). Se mantiene la firma para no tocar - // los escenarios que la siguen invocando. - void updateColors(float delta_time); - - // [NUEVO] Actualitzar counter de FPS - void updateFPS(float delta_time); - // Getters auto getRenderer() -> Rendering::Renderer* { return &gpu_renderer_; } [[nodiscard]] auto getScaleFactor() const -> float { return zoom_factor_; } - // [NUEVO] Actualitzar título de la finestra - void setWindowTitle(const std::string& title); - // [NUEVO] Actualitzar context de renderizado (factor de scale global) void updateRenderingContext() const; @@ -58,11 +46,6 @@ class SDLManager { SDL_Window* finestra_; Rendering::Renderer gpu_renderer_; // GpuFrameRenderer (SDL3 GPU) - // [NUEVO] Variables FPS - float fps_accumulator_; - int fps_frame_count_; - int fps_display_; - // [NUEVO] Estat de la finestra int current_width_; // Mida física actual int current_height_; diff --git a/source/core/system/debug_overlay.cpp b/source/core/system/debug_overlay.cpp new file mode 100644 index 0000000..1dbc0ba --- /dev/null +++ b/source/core/system/debug_overlay.cpp @@ -0,0 +1,64 @@ +// debug_overlay.cpp - Implementación del overlay de debug. + +#include "core/system/debug_overlay.hpp" + +#include + +#include "core/types.hpp" +#include "game/options.hpp" + +namespace System { + +namespace { +// Posición y tamaño del overlay en coordenadas lógicas (1280×720). +constexpr float OVERLAY_X = 12.0F; +constexpr float OVERLAY_Y_FPS = 12.0F; +constexpr float OVERLAY_LINE_HEIGHT = 18.0F; // separación entre líneas (scale 0.4 → ~16 px alto) +constexpr float OVERLAY_SCALE = 0.4F; +constexpr float OVERLAY_SPACING = 2.0F; +constexpr float OVERLAY_BRIGHTNESS = 1.0F; + +// Cadencia de actualización del valor de FPS mostrado. +constexpr float FPS_UPDATE_INTERVAL = 0.5F; +} // namespace + +DebugOverlay::DebugOverlay(Rendering::Renderer* renderer) + : text_(renderer), +#ifdef _DEBUG + visible_(true), +#else + visible_(false), +#endif + fps_accumulator_(0.0F), + fps_frame_count_(0), + fps_display_(0) {} + +void DebugOverlay::update(float delta_time) { + fps_accumulator_ += delta_time; + fps_frame_count_++; + + if (fps_accumulator_ >= FPS_UPDATE_INTERVAL) { + fps_display_ = static_cast(fps_frame_count_ / fps_accumulator_); + fps_frame_count_ = 0; + fps_accumulator_ = 0.0F; + } +} + +void DebugOverlay::draw() const { + if (!visible_) { + return; + } + + const std::string FPS_TEXT = "FPS: " + std::to_string(fps_display_); + const std::string VSYNC_TEXT = std::string("VSYNC: ") + + (Options::rendering.vsync == 1 ? "ON" : "OFF"); + + text_.render(FPS_TEXT, + Vec2{.x = OVERLAY_X, .y = OVERLAY_Y_FPS}, + OVERLAY_SCALE, OVERLAY_SPACING, OVERLAY_BRIGHTNESS); + text_.render(VSYNC_TEXT, + Vec2{.x = OVERLAY_X, .y = OVERLAY_Y_FPS + OVERLAY_LINE_HEIGHT}, + OVERLAY_SCALE, OVERLAY_SPACING, OVERLAY_BRIGHTNESS); +} + +} // namespace System diff --git a/source/core/system/debug_overlay.hpp b/source/core/system/debug_overlay.hpp new file mode 100644 index 0000000..bb012b0 --- /dev/null +++ b/source/core/system/debug_overlay.hpp @@ -0,0 +1,38 @@ +// debug_overlay.hpp - Overlay de debug (FPS + VSync) toggleable con F11 +// © 2025 Orni Attack +// +// Sistema global propiedad del Director. Se actualiza y dibuja cada frame +// después de la escena (queda on top). En builds debug arranca visible, +// en release oculto. F11 alterna visibilidad. + +#pragma once + +#include "core/graphics/vector_text.hpp" +#include "core/rendering/render_context.hpp" + +namespace System { + +class DebugOverlay { + public: + explicit DebugOverlay(Rendering::Renderer* renderer); + + // Acumula FPS. Llamar una vez por frame con el delta del Director. + void update(float delta_time); + + // Pinta el overlay si está visible. Posición esquina sup-izq. + void draw() const; + + void toggle() { visible_ = !visible_; } + [[nodiscard]] auto isVisible() const -> bool { return visible_; } + + private: + Graphics::VectorText text_; + bool visible_; + + // FPS counter — se actualiza cada FPS_UPDATE_INTERVAL segundos. + float fps_accumulator_; + int fps_frame_count_; + int fps_display_; +}; + +} // namespace System diff --git a/source/core/system/director.cpp b/source/core/system/director.cpp index 0c794c7..43f8133 100644 --- a/source/core/system/director.cpp +++ b/source/core/system/director.cpp @@ -9,6 +9,7 @@ #include #include +#include "debug_overlay.hpp" #include "scene.hpp" #include "scene_context.hpp" #include "global_events.hpp" @@ -255,6 +256,10 @@ auto Director::run() -> int { context.setNextScene(SceneType::LOGO); #endif + // Overlay de debug (FPS + VSync). Vive en el Director porque es global + // a todas las escenas. Toggle con F11 (visible por defecto en _DEBUG). + System::DebugOverlay debug_overlay(sdl.getRenderer()); + // Bucle principal: construir escena → frame loop → destruir → siguiente. while (context.nextScene() != SceneType::EXIT) { SceneManager::actual = context.nextScene(); @@ -262,7 +267,7 @@ auto Director::run() -> int { if (!scene) { break; } - runFrameLoop(*scene, sdl, context); + runFrameLoop(*scene, sdl, context, debug_overlay); } SceneManager::actual = SceneType::EXIT; @@ -284,7 +289,8 @@ auto Director::buildScene(SceneType type, SDLManager& sdl, SceneContext& context } } -void Director::runFrameLoop(Scene& scene, SDLManager& sdl, SceneContext& context) { +void Director::runFrameLoop(Scene& scene, SDLManager& sdl, SceneContext& context, + System::DebugOverlay& debug_overlay) { SDL_Event event; Uint64 last_time = SDL_GetTicks(); @@ -295,11 +301,11 @@ void Director::runFrameLoop(Scene& scene, SDLManager& sdl, SceneContext& context last_time = NOW; delta_time = std::min(delta_time, 0.05F); - sdl.updateFPS(delta_time); Mouse::updateCursorVisibility(); Input::get()->update(); - // Event loop: primero ventana, después globales, después escena. + // Event loop: primero ventana, después globales, después F11 + // (toggle del overlay), después escena. while (SDL_PollEvent(&event)) { if (sdl.handleWindowEvent(event)) { continue; @@ -307,17 +313,22 @@ void Director::runFrameLoop(Scene& scene, SDLManager& sdl, SceneContext& context if (GlobalEvents::handle(event, sdl, context)) { continue; } + if (event.type == SDL_EVENT_KEY_DOWN + && event.key.scancode == SDL_SCANCODE_F11) { + debug_overlay.toggle(); + continue; + } scene.handleEvent(event); } scene.update(delta_time); + debug_overlay.update(delta_time); Audio::update(); - sdl.updateColors(delta_time); // no-op desde Fase 8c (oscilación en shader) sdl.clear(0, 0, 0); sdl.updateRenderingContext(); scene.draw(); - // Hook futuro: overlays globales aquí (FPS+VSync, profilers...). + debug_overlay.draw(); // siempre on top de la escena sdl.present(); } } diff --git a/source/core/system/director.hpp b/source/core/system/director.hpp index b71c257..9018f84 100644 --- a/source/core/system/director.hpp +++ b/source/core/system/director.hpp @@ -8,6 +8,7 @@ class Scene; class SDLManager; +namespace System { class DebugOverlay; } class Director { public: @@ -33,6 +34,8 @@ class Director { // Ejecuta el bucle de frames de UNA escena hasta que scene.isFinished() // sea true. Maneja delta_time, eventos (globales + escena), update y draw. + // El debug_overlay es global a todas las escenas; el Director lo posee. static void runFrameLoop(Scene& scene, SDLManager& sdl, - SceneManager::SceneContext& context); + SceneManager::SceneContext& context, + System::DebugOverlay& debug_overlay); };