Files
jaildoctors_dilemma/source/core/system/debug.cpp

181 lines
6.5 KiB
C++

#include "core/system/debug.hpp"
#ifdef _DEBUG
#include <algorithm> // Para max
#include <fstream> // Para ifstream, ofstream
#include <memory> // Para __shared_ptr_access, shared_ptr
#include "core/rendering/text.hpp" // Para Text
#include "core/resources/resource_cache.hpp" // Para Resource
#include "external/fkyaml_node.hpp" // Para fkyaml::node
#include "game/defaults.hpp" // Para Defaults::Game::*
#include "utils/defines.hpp" // Para Tile::SIZE
#include "utils/utils.hpp" // Para Color, Flip::
// [SINGLETON]
Debug* Debug::debug = nullptr;
// [SINGLETON] Crearemos el objeto con esta función estática
void Debug::init() {
Debug::debug = new Debug();
}
// [SINGLETON] Destruiremos el objeto con esta función estática
void Debug::destroy() {
delete Debug::debug;
}
// [SINGLETON] Con este método obtenemos el objeto y podemos trabajar con él
auto Debug::get() -> Debug* {
return Debug::debug;
}
// Dibuja en pantalla
void Debug::render() { // NOLINT(readability-make-member-function-const)
auto text = Resource::Cache::get()->getText("aseprite");
int y = y_;
int w = 0;
constexpr int DESP_Y = 7;
const int CHAR_SIZE = text->getCharacterSize();
// Watch window: valores persistentes (key: value)
for (const auto& [key, value] : watches_) {
const std::string LINE = key + ": " + value;
text->write(x_, y, LINE);
w = std::max(w, text->length(LINE));
y += DESP_Y;
if (y > 192 - CHAR_SIZE) {
y = y_;
x_ += w + 2;
w = 0;
}
}
// Slot one-shot: mensajes de un solo frame
for (const auto& s : slot_) {
text->write(x_, y, s);
w = std::max(w, text->length(s));
y += DESP_Y;
if (y > 192 - CHAR_SIZE) {
y = y_;
x_ += w + 2;
w = 0;
}
}
y = 0;
for (const auto& l : log_) {
text->writeColored(x_ + 10, y, l, static_cast<Uint8>(PaletteColor::WHITE));
y += CHAR_SIZE + 1;
}
}
// Establece/actualiza un valor persistente en el watch window
void Debug::set(const std::string& key, const std::string& value) {
watches_[key] = value;
}
// Elimina un valor del watch window
void Debug::unset(const std::string& key) {
watches_.erase(key);
}
// Establece la posición donde se colocará la información de debug
void Debug::setPos(SDL_FPoint p) {
x_ = p.x;
y_ = p.y;
}
// Establece la ruta del archivo debug.yaml
void Debug::setDebugFile(const std::string& path) {
debug_file_path_ = path;
}
// Convierte string a SceneManager::Scene (para debug.yaml)
static auto sceneFromString(const std::string& s) -> SceneManager::Scene {
if (s == "LOGO") { return SceneManager::Scene::LOGO; }
if (s == "LOADING") { return SceneManager::Scene::LOADING_SCREEN; }
if (s == "TITLE") { return SceneManager::Scene::TITLE; }
if (s == "CREDITS") { return SceneManager::Scene::CREDITS; }
if (s == "DEMO") { return SceneManager::Scene::DEMO; }
if (s == "ENDING") { return SceneManager::Scene::ENDING; }
if (s == "ENDING2") { return SceneManager::Scene::ENDING2; }
return SceneManager::Scene::GAME; // Fallback seguro
}
// Convierte SceneManager::Scene a string (para debug.yaml)
static auto sceneToString(SceneManager::Scene scene) -> std::string {
switch (scene) {
case SceneManager::Scene::LOGO: return "LOGO";
case SceneManager::Scene::LOADING_SCREEN: return "LOADING";
case SceneManager::Scene::TITLE: return "TITLE";
case SceneManager::Scene::CREDITS: return "CREDITS";
case SceneManager::Scene::DEMO: return "DEMO";
case SceneManager::Scene::ENDING: return "ENDING";
case SceneManager::Scene::ENDING2: return "ENDING2";
default: return "GAME";
}
}
// Carga la configuración de debug desde debug.yaml
void Debug::loadFromFile() {
// Inicializar con valores de release por defecto
spawn_settings_.room = Defaults::Game::Room::INITIAL;
spawn_settings_.spawn_x = Defaults::Game::Player::SPAWN_X;
spawn_settings_.spawn_y = Defaults::Game::Player::SPAWN_Y;
spawn_settings_.flip = Defaults::Game::Player::SPAWN_FLIP;
initial_scene_ = SceneManager::Scene::GAME;
std::ifstream file(debug_file_path_);
if (!file.good()) {
saveToFile(); // No existe: crear con valores por defecto
return;
}
std::string content((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
file.close();
try {
auto yaml = fkyaml::node::deserialize(content);
if (yaml.contains("room")) {
spawn_settings_.room = yaml["room"].get_value<std::string>();
}
if (yaml.contains("spawn_x")) {
spawn_settings_.spawn_x = yaml["spawn_x"].get_value<int>() * Tile::SIZE;
}
if (yaml.contains("spawn_y")) {
spawn_settings_.spawn_y = yaml["spawn_y"].get_value<int>() * Tile::SIZE;
}
if (yaml.contains("spawn_flip")) {
auto s = yaml["spawn_flip"].get_value<std::string>();
spawn_settings_.flip = (s == "right") ? Flip::RIGHT : Flip::LEFT;
}
if (yaml.contains("initial_scene")) {
initial_scene_ = sceneFromString(yaml["initial_scene"].get_value<std::string>());
}
} catch (...) {
// YAML inválido: resetear a defaults y sobreescribir
spawn_settings_.room = Defaults::Game::Room::INITIAL;
spawn_settings_.spawn_x = Defaults::Game::Player::SPAWN_X;
spawn_settings_.spawn_y = Defaults::Game::Player::SPAWN_Y;
spawn_settings_.flip = Defaults::Game::Player::SPAWN_FLIP;
initial_scene_ = SceneManager::Scene::GAME;
saveToFile();
}
}
// Guarda la configuración de debug en debug.yaml
void Debug::saveToFile() const {
std::ofstream file(debug_file_path_);
if (!file.is_open()) { return; }
file << "# JailDoctor's Dilemma - Debug Configuration\n";
file << "# Edita para cambiar la habitacion y spawn del jugador en builds debug.\n\n";
file << "room: \"" << spawn_settings_.room << "\"\n";
file << "spawn_x: " << (spawn_settings_.spawn_x / Tile::SIZE) << " # en tiles\n";
file << "spawn_y: " << (spawn_settings_.spawn_y / Tile::SIZE) << " # en tiles\n";
file << "spawn_flip: " << ((spawn_settings_.flip == Flip::RIGHT) ? "right" : "left") << "\n";
file << "initial_scene: " << sceneToString(initial_scene_) << "\n";
}
#endif // _DEBUG