From 400c6a782be0cda69fc41b47783693536e7265a3 Mon Sep 17 00:00:00 2001 From: NeilClack Date: Tue, 25 Aug 2026 10:54:35 -0500 Subject: [PATCH] Scroller: use full window height on rotated/tall displays Override the LETTERBOX logical presentation while the scroller is active so it renders into the full physical window. On a 1920x6480 rotated display the scroller now scrolls through all 6480 pixels of vertical space instead of being confined to the 1920x1080 letterbox region. Text scale is unchanged (same font size, same pixel rasterization); more lines are simply visible at once. - onPush: save current logical presentation, switch to DISABLED with real window dimensions - onPop: restore the saved LETTERBOX presentation - resize handler in main.cpp: skip re-apply while scroller is active (it owns its own presentation and restores on pop) --- src/main.cpp | 15 ++++++++++----- src/scroller_page.cpp | 43 ++++++++++++++++++++++++++++++++++++------- src/scroller_page.h | 4 ++++ 3 files changed, 50 insertions(+), 12 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index d5dfa55..7cee294 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -7,6 +7,7 @@ #include "logical_size.h" #include "logger/logger.h" #include "provisioning.h" +#include "scroller_page.h" namespace { // How long audio fades out before the app tears down on quit. Only applied @@ -201,11 +202,15 @@ SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) { std::to_string(event->window.data1) + "x" + std::to_string(event->window.data2)); // Logical presentation persists across resizes; re-apply defensively - // in case backend state was reset underneath us. - SDL_SetRenderLogicalPresentation(state.renderer, - radiantwave::kDesignWidth, - radiantwave::kDesignHeight, - SDL_LOGICAL_PRESENTATION_LETTERBOX); + // in case backend state was reset underneath us. Skip while the + // scroller is active — it owns its own presentation (NONE, full + // window) and restores LETTERBOX in onPop. + if (!dynamic_cast(state.pages.current())) { + SDL_SetRenderLogicalPresentation(state.renderer, + radiantwave::kDesignWidth, + radiantwave::kDesignHeight, + SDL_LOGICAL_PRESENTATION_LETTERBOX); + } } if (!state.keybinds.handleEvent(*event)) { diff --git a/src/scroller_page.cpp b/src/scroller_page.cpp index 3903e8e..6c6dc79 100644 --- a/src/scroller_page.cpp +++ b/src/scroller_page.cpp @@ -34,13 +34,37 @@ void ScrollerPage::onPush(AppState &state) { state_ = &state; - int winW = 0; - int winH = 0; - radiantwave::getLayoutSize(state.renderer, &winW, &winH); - screenW_ = static_cast(winW); - screenH_ = static_cast(winH); - // Lines are capped at the full screen width; the widest Fibonacci lines are - // sized to fill it with whole words (peak word count derived from the + // Save the current logical presentation (LETTERBOX at design resolution) + // and switch to NONE so we render into the full physical window. This + // lets the scroller scroll the entire vertical extent of tall/rotated + // displays while keeping text at the same pixel scale. onPop restores + // the original presentation for other pages. + SDL_GetRenderLogicalPresentation(state.renderer, &savedLogicalW_, + &savedLogicalH_, &savedMode_); + + SDL_Window *window = SDL_GetRenderWindow(state.renderer); + int windowW = 0; + int windowH = 0; + if (window) + { + SDL_GetWindowSize(window, &windowW, &windowH); + } + if (windowW <= 0) + { + windowW = radiantwave::kDesignWidth; + } + if (windowH <= 0) + { + windowH = radiantwave::kDesignHeight; + } + + SDL_SetRenderLogicalPresentation(state.renderer, windowW, windowH, + SDL_LOGICAL_PRESENTATION_DISABLED); + + screenW_ = static_cast(windowW); + screenH_ = static_cast(windowH); + // Lines are capped at the full screen width; the widest Fibonacci lines + // are sized to fill it with whole words (peak word count derived from the // screen), independent of resolution. maxLineWidth_ = screenW_; @@ -101,6 +125,11 @@ void ScrollerPage::onPause(AppState &state) void ScrollerPage::onPop(AppState &state) { + // Restore the original logical presentation so other pages (Home, + // Settings, etc.) render in the design-resolution LETTERBOX space. + SDL_SetRenderLogicalPresentation(state.renderer, savedLogicalW_, + savedLogicalH_, savedMode_); + state.audio.stopTrackFadeOut(kFadeSeconds); state.keybinds.unbindAll(); destroyResources(); diff --git a/src/scroller_page.h b/src/scroller_page.h index 4160cae..0ccd429 100644 --- a/src/scroller_page.h +++ b/src/scroller_page.h @@ -115,4 +115,8 @@ private: float velocityDelay_ = 2.5f; int velocityState_ = 0; float velocityTimer_ = 0.0f; + + int savedLogicalW_ = 0; + int savedLogicalH_ = 0; + SDL_RendererLogicalPresentation savedMode_ = SDL_LOGICAL_PRESENTATION_DISABLED; };