From 56d9971b0e546e70335d03c657ea8976b14de265 Mon Sep 17 00:00:00 2001 From: Cyd Date: Sun, 26 Jul 2026 02:58:34 -0500 Subject: [PATCH] -fit: pin the backbuffer to the CANVAS, not the client (the display was wrong) Field report with a screenshot: `btl4.exe -fit` renders tiny MFDs hugging the corners, an over-wide world view, and a horizontally squashed scene. CAUSE. L4VIDEO pins the windowed backbuffer to the CLIENT RECT (Gitea #56, so a device Reset cannot silently re-derive it). That is correct precisely while client == canvas -- true on a normal boot, and FALSE under -fit, which sizes the window to the whole monitor BEFORE the device exists. The backbuffer came out 3440x1440 against a 1452x1059 canvas, and everything downstream disagreed: - BTApplyWorldViewport and BTDrawCockpitPanels lay out from the BACKBUFFER, so the canvas they drew was 3440 wide: bands unchanged, MFDs still 320x240 (hence tiny), view rect 2888x881 instead of 900x500; - the world projection used the aspect of the INTENDED view (1.8) inside a 3.28 viewport, stretching the scene; - Present then scaled that oversized backbuffer into the 1974x1440 letterbox, squashing it horizontally by 0.574; - and every button was hit-tested through gBTCockpitCanvasW/H while being drawn in backbuffer space -- the exact #50 divergence the pinning comment warns about, unnoticed because nothing had clicked under -fit. FIX: when the cockpit surround is up, the backbuffer IS the canvas, whatever the window is doing. Pin to gBTCockpitCanvasW/H and let the letterbox do the scaling -- which is what the rest of the design already assumed. Drag-resize was always right for this reason (the device is created while client == canvas and a later resize does not recreate it); only -fit, which changes the client first, exposed it. MY EARLIER VERIFICATION WAS WRONG. I called -fit good from a screenshot that was centred and letterboxed, without checking that the backbuffer matched the canvas or that a single button could be clicked. Both are checked now. Verified: -fit on 3440x1440 renders correct proportions (captured), and 72/72 buttons dispatch under -fit; surround/exploded/dock/pod/dev all boot and simulate with zero faults. Co-Authored-By: Claude Opus 5 (1M context) --- engine/MUNGA_L4/L4VIDEO.cpp | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/engine/MUNGA_L4/L4VIDEO.cpp b/engine/MUNGA_L4/L4VIDEO.cpp index 58a3083..43ddfb9 100644 --- a/engine/MUNGA_L4/L4VIDEO.cpp +++ b/engine/MUNGA_L4/L4VIDEO.cpp @@ -3490,8 +3490,30 @@ DPLRenderer::DPLRenderer( // while the cockpit-surround window is sized independently -- pinning to them // would shrink the backbuffer and break the composite.) // + // + // COCKPIT SURROUND: the backbuffer IS THE CANVAS, whatever the window + // happens to be (2026-07-26). Everything downstream assumes it -- + // BTApplyWorldViewport and BTDrawCockpitPanels lay out from the + // BACKBUFFER size, while the letterbox and the mouse hit-test map + // through gBTCockpitCanvasW/H. Pinning to the client instead is fine + // only while client == canvas, which is true for a normal boot and + // FALSE for -fit: the window is the whole monitor before the device + // exists, so the backbuffer came out 3440x1440 against a 1452x1059 + // canvas. Field report: tiny MFDs hugging the corners, an over-wide + // world view, the scene squashed horizontally as Present scaled the + // oversized backbuffer into the letterbox -- and, unseen, every button + // hit-tested in a different space from the one it was drawn in (the + // exact #50 divergence the note above warns about). + // + extern int gBTGaugeCockpit; + extern int gBTCockpitCanvasW, gBTCockpitCanvasH; RECT rc; - if (hWnd != NULL && GetClientRect(hWnd, &rc) + if (gBTGaugeCockpit && gBTCockpitCanvasW > 0 && gBTCockpitCanvasH > 0) + { + mPresentParams.BackBufferWidth = (UINT)gBTCockpitCanvasW; + mPresentParams.BackBufferHeight = (UINT)gBTCockpitCanvasH; + } + else if (hWnd != NULL && GetClientRect(hWnd, &rc) && rc.right > rc.left && rc.bottom > rc.top) { mPresentParams.BackBufferWidth = (UINT)(rc.right - rc.left);