diff --git a/source/core/system/debug.cpp b/source/core/system/debug.cpp index 6dfc566..8b0974f 100644 --- a/source/core/system/debug.cpp +++ b/source/core/system/debug.cpp @@ -36,24 +36,51 @@ 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, (int)s.length())); - y += text->getCharacterSize() + 1; - if (y > 192 - text->getCharacterSize()) { + w = std::max(w, text->length(s)); + y += DESP_Y; + if (y > 192 - CHAR_SIZE) { y = y_; - x_ += (w * text->getCharacterSize()) + 2; + x_ += w + 2; + w = 0; } } y = 0; for (const auto& l : log_) { text->writeColored(x_ + 10, y, l, static_cast(PaletteColor::WHITE)); - y += text->getCharacterSize() + 1; + 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; diff --git a/source/core/system/debug.hpp b/source/core/system/debug.hpp index fb1b2e4..cc200db 100644 --- a/source/core/system/debug.hpp +++ b/source/core/system/debug.hpp @@ -4,6 +4,7 @@ #include +#include // Para map #include // Para string #include // Para vector @@ -27,10 +28,13 @@ class Debug { [[nodiscard]] auto isEnabled() const -> bool { return enabled_; } // Obtiene si el debug está activo - void add(const std::string& text) { slot_.push_back(text); } // Añade texto al slot de debug - void clear() { slot_.clear(); } // Limpia el slot de debug - void addToLog(const std::string& text) { log_.push_back(text); } // Añade texto al log - void clearLog() { log_.clear(); } // Limpia el log + void add(const std::string& text) { slot_.push_back(text); } // Añade texto one-shot al slot (se limpia cada frame) + void clear() { slot_.clear(); } // Limpia el slot one-shot (no afecta a watches) + void addToLog(const std::string& text) { log_.push_back(text); } // Añade texto al log + void clearLog() { log_.clear(); } // Limpia el log + void set(const std::string& key, const std::string& value); // Establece/actualiza un valor persistente en el watch window + void unset(const std::string& key); // Elimina un valor del watch window + void clearWatches() { watches_.clear(); } // Limpia todos los watches void setEnabled(bool value) { enabled_ = value; } // Establece si el debug está activo void toggleEnabled() { enabled_ = !enabled_; } // Alterna el estado del debug @@ -47,8 +51,9 @@ class Debug { ~Debug() = default; // Destructor // Variables - std::vector slot_; // Vector con los textos a escribir - std::vector log_; // Vector con los textos a escribir + std::map watches_; // Watch window: valores persistentes (key→value) + std::vector slot_; // One-shot: textos que se limpian cada frame + std::vector log_; // Log persistente int x_ = 0; // Posicion donde escribir el texto de debug int y_ = 0; // Posición donde escribir el texto de debug bool enabled_ = false; // Indica si esta activo el modo debug diff --git a/source/game/entities/player.cpp b/source/game/entities/player.cpp index 12557ad..b8c79ac 100644 --- a/source/game/entities/player.cpp +++ b/source/game/entities/player.cpp @@ -84,21 +84,21 @@ void Player::move(float delta_time) { } syncSpriteAndCollider(); // Actualiza la posición del sprite y las colisiones #ifdef _DEBUG - Debug::get()->add(std::string("X : " + std::to_string(static_cast(x_)))); - Debug::get()->add(std::string("Y : " + std::to_string(static_cast(y_)))); - Debug::get()->add(std::string("LGP: " + std::to_string(last_grounded_position_))); + Debug::get()->set("P.X", std::to_string(static_cast(x_))); + Debug::get()->set("P.Y", std::to_string(static_cast(y_))); + Debug::get()->set("P.LGP", std::to_string(last_grounded_position_)); switch (state_) { case State::ON_GROUND: - Debug::get()->add(std::string("ON_GROUND")); + Debug::get()->set("P.STATE", "ON_GROUND"); break; case State::ON_SLOPE: - Debug::get()->add(std::string("ON_SLOPE")); + Debug::get()->set("P.STATE", "ON_SLOPE"); break; case State::JUMPING: - Debug::get()->add(std::string("JUMPING")); + Debug::get()->set("P.STATE", "JUMPING"); break; case State::FALLING: - Debug::get()->add(std::string("FALLING")); + Debug::get()->set("P.STATE", "FALLING"); break; } #endif @@ -235,6 +235,9 @@ void Player::moveOnGround(float delta_time) { y_ = SLOPE_Y - HEIGHT; transitionToState(State::ON_SLOPE); } +#ifdef _DEBUG + Debug::get()->set("sl.detect_y", SLOPE_Y != Collision::NONE ? std::to_string(SLOPE_Y) : "-"); +#endif // Comprueba si está sobre una rampa if (isOnSlope()) { transitionToState(State::ON_SLOPE); } @@ -279,12 +282,21 @@ void Player::moveOnSlope(float delta_time) { const int MAX_X = std::max(current_slope_->x1, current_slope_->x2); const bool OUT_OF_BOUNDS = (X < MIN_X) || (X > MAX_X); +#ifdef _DEBUG + Debug::get()->set("sl.foot", std::to_string(X)); + Debug::get()->set("sl.y_c", std::to_string(static_cast(y_))); + Debug::get()->set("sl.oob", OUT_OF_BOUNDS ? "YES" : "ok"); +#endif + if (OUT_OF_BOUNDS) { // Determinar si estamos saliendo por arriba o por abajo de la rampa const bool EXITING_DOWNWARD = (X > current_slope_->x2 && IS_LEFT_SLOPE) || (X < current_slope_->x1 && !IS_LEFT_SLOPE); const bool EXITING_UPWARD = (X < current_slope_->x1 && IS_LEFT_SLOPE) || (X > current_slope_->x2 && !IS_LEFT_SLOPE); +#ifdef _DEBUG + Debug::get()->set("sl.oob", EXITING_DOWNWARD ? "DOWN" : "UP"); +#endif if (EXITING_DOWNWARD) { // Salida por abajo: no hacer nada @@ -576,18 +588,17 @@ void Player::updateCurrentSlope() { } } - // Debug output - /* +#ifdef _DEBUG if (current_slope_ != nullptr) { - const char* TYPE = isLeftSlope() ? "Left \\" : "Right /"; - std::cout << "[SLOPE] " << TYPE - << " from (" << current_slope_->x1 << "," << current_slope_->y1 << ")" - << " to (" << current_slope_->x2 << "," << current_slope_->y2 << ")\n"; - + Debug::get()->set("sl.type", isLeftSlope() ? "L\\" : "R/"); + Debug::get()->set("sl.p1", std::to_string(current_slope_->x1) + "," + std::to_string(current_slope_->y1)); + Debug::get()->set("sl.p2", std::to_string(current_slope_->x2) + "," + std::to_string(current_slope_->y2)); } else { - std::cout << "[SLOPE] nullptr\n"; + Debug::get()->set("sl.type", "null"); + Debug::get()->unset("sl.p1"); + Debug::get()->unset("sl.p2"); } - */ +#endif } // Comprueba que el jugador no toque ningun tile de los que matan diff --git a/source/game/gameplay/collision_map.cpp b/source/game/gameplay/collision_map.cpp index aa509cf..bd9dfe8 100644 --- a/source/game/gameplay/collision_map.cpp +++ b/source/game/gameplay/collision_map.cpp @@ -79,25 +79,25 @@ auto CollisionMap::getSlopeHeight(SDL_FPoint p, Tile slope) -> int { // Calcula la base del tile int base = ((p.y / TILE_SIZE) * TILE_SIZE) + TILE_SIZE; #ifdef _DEBUG - Debug::get()->add("BASE = " + std::to_string(base)); + Debug::get()->set("slope.BASE", std::to_string(base)); #endif // Calcula cuanto se ha entrado en el tile horizontalmente const int POS = (static_cast(p.x) % TILE_SIZE); // Esto da un valor entre 0 y 7 #ifdef _DEBUG - Debug::get()->add("POS = " + std::to_string(POS)); + Debug::get()->set("slope.POS", std::to_string(POS)); #endif // Se resta a la base la cantidad de pixeles pos en funcion de la rampa if (slope == Tile::SLOPE_R) { base -= POS + 1; #ifdef _DEBUG - Debug::get()->add("BASE_R = " + std::to_string(base)); + Debug::get()->set("slope.result", "BASE_R=" + std::to_string(base)); #endif } else { base -= (TILE_SIZE - POS); #ifdef _DEBUG - Debug::get()->add("BASE_L = " + std::to_string(base)); + Debug::get()->set("slope.result", "BASE_L=" + std::to_string(base)); #endif } diff --git a/source/game/scenes/game.cpp b/source/game/scenes/game.cpp index 35dacf1..1569241 100644 --- a/source/game/scenes/game.cpp +++ b/source/game/scenes/game.cpp @@ -90,7 +90,7 @@ Game::Game(Mode mode) auto ss = Debug::get()->getSpawnSettings(); ss.spawn_x = tile_x * Tile::SIZE; ss.spawn_y = tile_y * Tile::SIZE; - ss.flip = player_->getSpawnParams().flip; + ss.flip = player_->getSpawnParams().flip; Debug::get()->setSpawnSettings(ss); Debug::get()->saveToFile(); return "Pos:" + std::to_string(tile_x) + "," + std::to_string(tile_y); @@ -109,7 +109,7 @@ Game::~Game() { GameControl::refresh_player_color = nullptr; GameControl::toggle_debug_mode = nullptr; GameControl::set_initial_room = nullptr; - GameControl::set_initial_pos = nullptr; + GameControl::set_initial_pos = nullptr; #endif } @@ -207,10 +207,6 @@ void Game::update() { Audio::update(); // Actualiza el objeto Audio Screen::get()->update(DELTA_TIME); // Actualiza el objeto Screen - -#ifdef _DEBUG - updateDebugInfo(); -#endif } // Actualiza el juego en estado PLAYING @@ -432,18 +428,9 @@ static void toggleCheat(Options::Cheat::State& cheat, const std::string& label) Notifier::get()->show({label + (ENABLED ? Locale::get()->get("game.enabled") : Locale::get()->get("game.disabled"))}, Notifier::Style::DEFAULT, -1, true); // NOLINT(readability-static-accessed-through-instance) } -// Pasa la información de debug -void Game::updateDebugInfo() { - // Debug::get()->add("X = " + std::to_string(static_cast(player_->x_)) + ", Y = " + std::to_string(static_cast(player_->y_))); - // Debug::get()->add("VX = " + std::to_string(player_->vx_).substr(0, 4) + ", VY = " + std::to_string(player_->vy_).substr(0, 4)); - // Debug::get()->add("STATE = " + std::to_string(static_cast(player_->state_))); -} - // Pone la información de debug en pantalla void Game::renderDebugInfo() { - if (!Debug::get()->isEnabled()) { - return; - } + if (!Debug::get()->isEnabled()) { return; } auto surface = Screen::get()->getRendererSurface(); @@ -589,8 +576,8 @@ void Game::handleDebugMouseDrag(float delta_time) { } debug_dragging_player_ = true; - Debug::get()->add(std::string("X : " + std::to_string(static_cast(player_rect.x)))); - Debug::get()->add(std::string("Y : " + std::to_string(static_cast(player_rect.y)))); + Debug::get()->set("drag.x", std::to_string(static_cast(player_rect.x))); + Debug::get()->set("drag.y", std::to_string(static_cast(player_rect.y))); } else if (debug_dragging_player_) { // Botón soltado después de arrastrar: finalizar teleport player_->finalizeDebugTeleport(); diff --git a/source/game/scenes/game.hpp b/source/game/scenes/game.hpp index 4416da7..32b6de5 100644 --- a/source/game/scenes/game.hpp +++ b/source/game/scenes/game.hpp @@ -92,7 +92,6 @@ class Game { void demoInit(); // DEMO MODE: Inicializa las variables para el modo demo void demoCheckRoomChange(float delta_time); // DEMO MODE: Comprueba si se ha de cambiar de habitación #ifdef _DEBUG - void updateDebugInfo(); // Pone la información de debug en pantalla static void renderDebugInfo(); // Pone la información de debug en pantalla void handleDebugEvents(const SDL_Event& event); // Comprueba los eventos void handleDebugMouseDrag(float delta_time); // Maneja el arrastre del jugador con el ratón (debug)