fix: Notifier usa viewport físico en F3 (coordenadas reales)

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 <noreply@anthropic.com>
This commit is contained in:
2025-10-17 08:08:01 +02:00
parent 9b8afa1219
commit 399650f8da

View File

@@ -5,6 +5,31 @@
#include "../utils/easing_functions.h" #include "../utils/easing_functions.h"
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
// ============================================================================
// 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() Notifier::Notifier()
: renderer_(nullptr) : renderer_(nullptr)
, text_renderer_(nullptr) , text_renderer_(nullptr)
@@ -159,14 +184,14 @@ void Notifier::render() {
int bg_width = text_width + (NOTIFICATION_PADDING * 2); int bg_width = text_width + (NOTIFICATION_PADDING * 2);
int bg_height = text_height + (NOTIFICATION_PADDING * 2); int bg_height = text_height + (NOTIFICATION_PADDING * 2);
// Obtener viewport actual (en modo letterbox F3 tiene dimensiones más pequeñas) // Obtener viewport FÍSICO (píxeles reales, no lógicos)
// CRÍTICO: Centrar usando dimensiones del VIEWPORT, no de la ventana física // CRÍTICO: En F3, SDL_GetRenderViewport() devuelve coordenadas LÓGICAS,
// printAbsolute() aplicará el offset del viewport automáticamente // pero printAbsolute() trabaja en píxeles FÍSICOS. Usar helper para obtener
SDL_Rect viewport; // viewport en coordenadas físicas.
SDL_GetRenderViewport(renderer_, &viewport); SDL_Rect physical_viewport = getPhysicalViewport(renderer_);
// Centrar en el viewport (coordenadas relativas al viewport, no absolutas) // Centrar en el viewport físico (coordenadas relativas al viewport)
int x = (viewport.w / 2) - (bg_width / 2); int x = (physical_viewport.w / 2) - (bg_width / 2);
int y = NOTIFICATION_TOP_MARGIN + static_cast<int>(current_notification_->y_offset); int y = NOTIFICATION_TOP_MARGIN + static_cast<int>(current_notification_->y_offset);
// Renderizar fondo semitransparente (con bypass de presentación lógica) // Renderizar fondo semitransparente (con bypass de presentación lógica)