122 lines
4.3 KiB
C++
122 lines
4.3 KiB
C++
#include "core/rendering/render_info.hpp"
|
|
|
|
#include <SDL3/SDL.h>
|
|
|
|
#include <algorithm> // Para transform
|
|
#include <cmath> // Para round, floor
|
|
#include <iomanip> // Para setprecision
|
|
#include <sstream> // Para ostringstream
|
|
#include <string> // Para string
|
|
|
|
#include "core/rendering/screen.hpp" // Para Screen
|
|
#include "core/rendering/surface.hpp" // Para Surface
|
|
#include "core/rendering/text.hpp" // Para Text
|
|
#include "game/options.hpp" // Para Options
|
|
#include "game/ui/console.hpp" // Para Console
|
|
#include "game/ui/notifier.hpp" // Para Notifier
|
|
|
|
// [SINGLETON]
|
|
RenderInfo* RenderInfo::render_info = nullptr;
|
|
|
|
// [SINGLETON] Crearemos el objeto con esta función estática
|
|
void RenderInfo::init() {
|
|
RenderInfo::render_info = new RenderInfo();
|
|
}
|
|
|
|
// [SINGLETON] Destruiremos el objeto con esta función estática
|
|
void RenderInfo::destroy() {
|
|
delete RenderInfo::render_info;
|
|
RenderInfo::render_info = nullptr;
|
|
}
|
|
|
|
// [SINGLETON] Con este método obtenemos el objeto y podemos trabajar con él
|
|
auto RenderInfo::get() -> RenderInfo* {
|
|
return RenderInfo::render_info;
|
|
}
|
|
|
|
// Constructor: en DEBUG se activa inmediatamente (notifica a Notifier del offset)
|
|
RenderInfo::RenderInfo() {
|
|
#ifdef _DEBUG
|
|
toggle();
|
|
#endif
|
|
}
|
|
|
|
// Renderiza el overlay de información por pantalla
|
|
void RenderInfo::render() const {
|
|
if (!active_) { return; }
|
|
|
|
// FPS
|
|
std::string line = std::to_string(Screen::get()->getLastFPS()) + " fps";
|
|
|
|
// Driver GPU
|
|
const auto& driver = Screen::get()->getGPUDriver();
|
|
line += " | " + (driver.empty() ? std::string("sdl") : driver);
|
|
|
|
// Zoom calculado (alto físico / alto lógico), con coma decimal y sin ceros innecesarios
|
|
const float ROUNDED = std::round(Screen::get()->getZoomFactor() * 100.0F) / 100.0F;
|
|
std::string zoom_str;
|
|
if (ROUNDED == std::floor(ROUNDED)) {
|
|
zoom_str = std::to_string(static_cast<int>(ROUNDED));
|
|
} else {
|
|
std::ostringstream oss;
|
|
oss << std::fixed << std::setprecision(2) << ROUNDED;
|
|
zoom_str = oss.str();
|
|
if (zoom_str.back() == '0') { zoom_str.pop_back(); }
|
|
std::replace(zoom_str.begin(), zoom_str.end(), '.', ',');
|
|
}
|
|
line += " | " + zoom_str + "x";
|
|
|
|
// PostFX: muestra preset y supersampling, o nada si está desactivado
|
|
if (Options::video.postfx) {
|
|
std::string preset_name = "-";
|
|
if (!Options::postfx_presets.empty()) {
|
|
preset_name = Options::postfx_presets[static_cast<size_t>(Options::current_postfx_preset)].name;
|
|
}
|
|
line += " | " + preset_name + (Options::video.supersampling ? " (ss)" : "");
|
|
}
|
|
|
|
// Todo en lowercase
|
|
std::transform(line.begin(), line.end(), line.begin(), [](unsigned char c) { return std::tolower(c); });
|
|
|
|
// Constantes visuales (igual que Console)
|
|
static constexpr Uint8 BG_COLOR = 0; // PaletteColor::BLACK
|
|
static constexpr Uint8 BORDER_COLOR = 9; // PaletteColor::BRIGHT_GREEN
|
|
static constexpr Uint8 MSG_COLOR = 8; // PaletteColor::GREEN
|
|
static constexpr int TEXT_SIZE = 6;
|
|
static constexpr int PADDING_V = TEXT_SIZE / 2;
|
|
|
|
// Fuente: preferir la de la consola si está disponible
|
|
auto text_obj = (Console::get() != nullptr) ? Console::get()->getText() : Screen::get()->getText();
|
|
|
|
// Posición Y (debajo de la consola si está visible)
|
|
const int Y = (Console::get() != nullptr) ? Console::get()->getVisibleHeight() : 0;
|
|
|
|
// Rectángulo de fondo: ancho completo, alto ajustado al texto
|
|
const SDL_FRect RECT = {
|
|
.x = 0.0F,
|
|
.y = static_cast<float>(Y),
|
|
.w = Options::game.width,
|
|
.h = static_cast<float>(TEXT_SIZE + (PADDING_V * 2))};
|
|
|
|
auto game_surface = Screen::get()->getGameSurface();
|
|
game_surface->fillRect(&RECT, BG_COLOR);
|
|
game_surface->drawRectBorder(&RECT, BORDER_COLOR);
|
|
text_obj->writeDX(Text::CENTER_FLAG | Text::COLOR_FLAG,
|
|
static_cast<int>(Options::game.width / 2),
|
|
Y + PADDING_V,
|
|
line,
|
|
1,
|
|
MSG_COLOR);
|
|
}
|
|
|
|
// Activa o desactiva el overlay y notifica a Notifier del cambio de offset
|
|
void RenderInfo::toggle() {
|
|
active_ = !active_;
|
|
if (active_) {
|
|
Screen::get()->updateZoomFactor();
|
|
if (Notifier::get() != nullptr) { Notifier::get()->addYOffset(HEIGHT); }
|
|
} else {
|
|
if (Notifier::get() != nullptr) { Notifier::get()->removeYOffset(HEIGHT); }
|
|
}
|
|
}
|