notifications: en overscan, desplaca la Y a la primera fila visible del canvas segons aspect ratio finestra/canvas

This commit is contained in:
2026-05-19 20:48:26 +02:00
parent 74d96047c7
commit 73f210bc2c
2 changed files with 21 additions and 3 deletions
+19 -2
View File
@@ -508,14 +508,16 @@ void Screen::clearNotification() {
notification_message_.clear();
}
// Dibuja la notificación activa (si la hay) sobre el gameCanvas
// Dibuja la notificación activa (si la hay) sobre el gameCanvas. La Y es
// el `notification_y_` configurat, desplacat cap avall si en overscan part
// de la franja superior queda fora de pantalla.
void Screen::renderNotification() {
if (notification_text_ == nullptr || SDL_GetTicks() >= notification_end_time_) {
return;
}
notification_text_->writeDX(Text::FLAG_CENTER | Text::FLAG_COLOR | Text::FLAG_STROKE,
game_canvas_width_ / 2,
notification_y_,
notification_y_ + safeNotificationY(),
notification_message_,
1,
notification_text_color_,
@@ -523,6 +525,21 @@ void Screen::renderNotification() {
notification_outline_color_);
}
// Y minima del canvas visible. Solo no zero quan estem en overscan i l'aspect
// de finestra obliga a escalar mes ample que alt (el canvas vertical desborda
// i la franja superior es retalla). En cas contrari (qualsevol altre mode, o
// overscan amb retall horitzontal nomes), retorna 0.
auto Screen::safeNotificationY() const -> int {
if (Options::video.presentation_mode != Options::PresentationMode::OVERSCAN) { return 0; }
if (window_width_ <= 0 || window_height_ <= 0 || game_canvas_height_ <= 0) { return 0; }
const float CANVAS_RATIO = static_cast<float>(game_canvas_width_) / static_cast<float>(game_canvas_height_);
const float WINDOW_RATIO = static_cast<float>(window_width_) / static_cast<float>(window_height_);
if (WINDOW_RATIO < CANVAS_RATIO) { return 0; } // retall horitzontal nomes
const float OVERSCAN_SCALE = static_cast<float>(window_width_) / static_cast<float>(game_canvas_width_);
const float VH = static_cast<float>(game_canvas_height_) * OVERSCAN_SCALE;
return static_cast<int>(std::ceil((VH - static_cast<float>(window_height_)) / (2.0F * OVERSCAN_SCALE)));
}
// ============================================================================
// Emscripten — fix per a fullscreen/resize (veure el bloc de comentaris al
// principi del fitxer i l'anonymous namespace amb els callbacks natius).
+2 -1
View File
@@ -112,7 +112,8 @@ class Screen {
void registerEmscriptenEventCallbacks(); // Registra los callbacks nativos de Emscripten para fullscreenchange y orientationchange. No-op fuera de Emscripten
// Notificaciones
void renderNotification(); // Dibuja la notificación activa (si la hay) sobre el gameCanvas
void renderNotification(); // Dibuja la notificación activa (si la hay) sobre el gameCanvas
[[nodiscard]] auto safeNotificationY() const -> int; // Y minima dins del canvas que segueix sent visible en overscan (segons aspect ratio finestra/canvas)
#ifndef NO_SHADERS
// Aplica els paràmetres actuals del shader al backend segons options