From 399650f8da6e81cc23a2db97b0993d6244c0de49 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Fri, 17 Oct 2025 08:08:01 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20Notifier=20usa=20viewport=20f=C3=ADsico?= =?UTF-8?q?=20en=20F3=20(coordenadas=20reales)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Problema: - En modo F3 (letterbox/integer scale), las notificaciones se pintaban fuera del área de juego (en las barras negras) - SDL_GetRenderViewport() devuelve coordenadas LÓGICAS cuando hay presentación lógica activa - printAbsolute() trabaja en píxeles FÍSICOS - Mismatch de coordenadas causaba centrado incorrecto Solución: - Nuevo helper getPhysicalViewport() que: 1. Guarda estado de presentación lógica 2. Deshabilita presentación lógica temporalmente 3. Obtiene viewport en coordenadas físicas 4. Restaura presentación lógica 5. Retorna viewport físico - Notifier::render() ahora usa physical_viewport.w para centrado Resultado: - Notificaciones centradas correctamente en F3 letterbox - Notificaciones centradas correctamente en F4 integer scale - Modo ventana sigue funcionando correctamente 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- source/ui/notifier.cpp | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/source/ui/notifier.cpp b/source/ui/notifier.cpp index cea140a..05118e7 100644 --- a/source/ui/notifier.cpp +++ b/source/ui/notifier.cpp @@ -5,6 +5,31 @@ #include "../utils/easing_functions.h" #include +// ============================================================================ +// 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; +} + Notifier::Notifier() : renderer_(nullptr) , text_renderer_(nullptr) @@ -159,14 +184,14 @@ void Notifier::render() { int bg_width = text_width + (NOTIFICATION_PADDING * 2); int bg_height = text_height + (NOTIFICATION_PADDING * 2); - // Obtener viewport actual (en modo letterbox F3 tiene dimensiones más pequeñas) - // CRÍTICO: Centrar usando dimensiones del VIEWPORT, no de la ventana física - // printAbsolute() aplicará el offset del viewport automáticamente - 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_); - // Centrar en el viewport (coordenadas relativas al viewport, no absolutas) - int x = (viewport.w / 2) - (bg_width / 2); + // Centrar en el viewport físico (coordenadas relativas al viewport) + int x = (physical_viewport.w / 2) - (bg_width / 2); int y = NOTIFICATION_TOP_MARGIN + static_cast(current_notification_->y_offset); // Renderizar fondo semitransparente (con bypass de presentación lógica)