diff --git a/source/ui/ui_manager.cpp b/source/ui/ui_manager.cpp index fda4c1a..7b5c544 100644 --- a/source/ui/ui_manager.cpp +++ b/source/ui/ui_manager.cpp @@ -13,6 +13,31 @@ #include "notifier.h" // for Notifier #include "help_overlay.h" // for HelpOverlay +// ============================================================================ +// HELPER: Obtener viewport en coordenadas físicas (no lógicas) +// ============================================================================ +// SDL_GetRenderViewport() devuelve coordenadas LÓGICAS cuando hay presentación +// lógica activa. Para obtener coordenadas FÍSICAS, necesitamos deshabilitar +// temporalmente la presentación lógica. +static SDL_Rect getPhysicalViewport(SDL_Renderer* renderer) { + // Guardar estado actual de presentación lógica + int logical_w = 0, logical_h = 0; + SDL_RendererLogicalPresentation presentation_mode; + SDL_GetRenderLogicalPresentation(renderer, &logical_w, &logical_h, &presentation_mode); + + // Deshabilitar presentación lógica temporalmente + SDL_SetRenderLogicalPresentation(renderer, 0, 0, SDL_LOGICAL_PRESENTATION_DISABLED); + + // Obtener viewport en coordenadas físicas (píxeles reales) + SDL_Rect physical_viewport; + SDL_GetRenderViewport(renderer, &physical_viewport); + + // Restaurar presentación lógica + SDL_SetRenderLogicalPresentation(renderer, logical_w, logical_h, presentation_mode); + + return physical_viewport; +} + UIManager::UIManager() : text_renderer_(nullptr) , text_renderer_debug_(nullptr) @@ -205,10 +230,11 @@ void UIManager::renderDebugHUD(const Engine* engine, int line_height = text_renderer_debug_->getTextHeight(); int margin = 8; // Margen constante en píxeles físicos - // Obtener viewport actual (en modo letterbox F3 tiene dimensiones más pequeñas) - // CRÍTICO: Usar dimensiones del VIEWPORT para alineación, no de la ventana física - SDL_Rect viewport; - SDL_GetRenderViewport(renderer_, &viewport); + // Obtener viewport FÍSICO (píxeles reales, no lógicos) + // CRÍTICO: En F3, SDL_GetRenderViewport() devuelve coordenadas LÓGICAS, + // pero printAbsolute() trabaja en píxeles FÍSICOS. Usar helper para obtener + // viewport en coordenadas físicas. + SDL_Rect physical_viewport = getPhysicalViewport(renderer_); // =========================== // COLUMNA LEFT (Sistema) @@ -312,7 +338,7 @@ void UIManager::renderDebugHUD(const Engine* engine, // FPS counter (esquina superior derecha) int fps_text_width = text_renderer_debug_->getTextWidthPhysical(fps_text_.c_str()); - int fps_x = viewport.w - fps_text_width - margin; + int fps_x = physical_viewport.w - fps_text_width - margin; text_renderer_debug_->printAbsolute(fps_x, right_y, fps_text_.c_str(), {255, 255, 0, 255}); // Amarillo right_y += line_height; @@ -323,47 +349,47 @@ void UIManager::renderDebugHUD(const Engine* engine, SDL_FRect pos = first_ball->getPosition(); std::string pos_text = "Pos: (" + std::to_string(static_cast(pos.x)) + ", " + std::to_string(static_cast(pos.y)) + ")"; int pos_width = text_renderer_debug_->getTextWidthPhysical(pos_text.c_str()); - text_renderer_debug_->printAbsolute(viewport.w - pos_width - margin, right_y, pos_text.c_str(), {255, 128, 128, 255}); // Rojo claro + text_renderer_debug_->printAbsolute(physical_viewport.w - pos_width - margin, right_y, pos_text.c_str(), {255, 128, 128, 255}); // Rojo claro right_y += line_height; // Velocidad X int vx_int = static_cast(first_ball->getVelocityX()); std::string vx_text = "VelX: " + std::to_string(vx_int); int vx_width = text_renderer_debug_->getTextWidthPhysical(vx_text.c_str()); - text_renderer_debug_->printAbsolute(viewport.w - vx_width - margin, right_y, vx_text.c_str(), {128, 255, 128, 255}); // Verde claro + text_renderer_debug_->printAbsolute(physical_viewport.w - vx_width - margin, right_y, vx_text.c_str(), {128, 255, 128, 255}); // Verde claro right_y += line_height; // Velocidad Y int vy_int = static_cast(first_ball->getVelocityY()); std::string vy_text = "VelY: " + std::to_string(vy_int); int vy_width = text_renderer_debug_->getTextWidthPhysical(vy_text.c_str()); - text_renderer_debug_->printAbsolute(viewport.w - vy_width - margin, right_y, vy_text.c_str(), {128, 255, 128, 255}); // Verde claro + text_renderer_debug_->printAbsolute(physical_viewport.w - vy_width - margin, right_y, vy_text.c_str(), {128, 255, 128, 255}); // Verde claro right_y += line_height; // Fuerza de gravedad int grav_int = static_cast(first_ball->getGravityForce()); std::string grav_text = "Gravity: " + std::to_string(grav_int); int grav_width = text_renderer_debug_->getTextWidthPhysical(grav_text.c_str()); - text_renderer_debug_->printAbsolute(viewport.w - grav_width - margin, right_y, grav_text.c_str(), {255, 255, 128, 255}); // Amarillo claro + text_renderer_debug_->printAbsolute(physical_viewport.w - grav_width - margin, right_y, grav_text.c_str(), {255, 255, 128, 255}); // Amarillo claro right_y += line_height; // Estado superficie std::string surface_text = first_ball->isOnSurface() ? "Surface: YES" : "Surface: NO"; int surface_width = text_renderer_debug_->getTextWidthPhysical(surface_text.c_str()); - text_renderer_debug_->printAbsolute(viewport.w - surface_width - margin, right_y, surface_text.c_str(), {255, 200, 128, 255}); // Naranja claro + text_renderer_debug_->printAbsolute(physical_viewport.w - surface_width - margin, right_y, surface_text.c_str(), {255, 200, 128, 255}); // Naranja claro right_y += line_height; // Coeficiente de rebote (loss) float loss_val = first_ball->getLossCoefficient(); std::string loss_text = "Loss: " + std::to_string(loss_val).substr(0, 4); int loss_width = text_renderer_debug_->getTextWidthPhysical(loss_text.c_str()); - text_renderer_debug_->printAbsolute(viewport.w - loss_width - margin, right_y, loss_text.c_str(), {255, 128, 255, 255}); // Magenta + text_renderer_debug_->printAbsolute(physical_viewport.w - loss_width - margin, right_y, loss_text.c_str(), {255, 128, 255, 255}); // Magenta right_y += line_height; // Dirección de gravedad std::string gravity_dir_text = "Dir: " + gravityDirectionToString(static_cast(scene_manager->getCurrentGravity())); int dir_width = text_renderer_debug_->getTextWidthPhysical(gravity_dir_text.c_str()); - text_renderer_debug_->printAbsolute(viewport.w - dir_width - margin, right_y, gravity_dir_text.c_str(), {128, 255, 255, 255}); // Cian claro + text_renderer_debug_->printAbsolute(physical_viewport.w - dir_width - margin, right_y, gravity_dir_text.c_str(), {128, 255, 255, 255}); // Cian claro right_y += line_height; } @@ -372,7 +398,7 @@ void UIManager::renderDebugHUD(const Engine* engine, int convergence_percent = static_cast(shape_convergence * 100.0f); std::string convergence_text = "Convergence: " + std::to_string(convergence_percent) + "%"; int conv_width = text_renderer_debug_->getTextWidthPhysical(convergence_text.c_str()); - text_renderer_debug_->printAbsolute(viewport.w - conv_width - margin, right_y, convergence_text.c_str(), {255, 128, 0, 255}); // Naranja + text_renderer_debug_->printAbsolute(physical_viewport.w - conv_width - margin, right_y, convergence_text.c_str(), {255, 128, 0, 255}); // Naranja right_y += line_height; } }