Skip to content

Add a square-pixel presentation option ([display] pixel_aspect)#80

Merged
LinuxJedi merged 1 commit into
mainfrom
feature/pixel-aspect-option
Jul 1, 2026
Merged

Add a square-pixel presentation option ([display] pixel_aspect)#80
LinuxJedi merged 1 commit into
mainfrom
feature/pixel-aspect-option

Conversation

@LinuxJedi

Copy link
Copy Markdown
Owner

Summary

A user doing side-by-side video comparison with WinUAE noticed that a 320x256 screen does not present as an exact 2x2 (640x512). That is by design: Copperline presents the field with the non-square pixel aspect of a 4:3 CRT (the 570 woven scanlines map onto a 537-row canvas, so the vertical scale is ~1.88x while horizontal is exactly 2x). WinUAE's default presentation uses square pixels, hence the difference. The status bar is additive and takes nothing from the picture.

This adds an opt-in square-pixel presentation for pixel-exact comparisons:

  • [display] pixel_aspect = "tv" (default, byte-identical to today) or "square" (one host row per woven scanline; a 320x256 PAL screen occupies precisely 640x512 output pixels).
  • COPPERLINE_PIXEL_ASPECT=tv|square env override for a single run, mirroring COPPERLINE_OVERSCAN.
  • A new Pixel Aspect menu item toggles the mode live: the backing textures (main window and open tool windows) are rebuilt like a DPI change and the window is resized. Refused while a video recording is running, since the encoder frame size is fixed at start.
  • A Pixel aspect cycle row on the launcher's A/V & Emu tab, round-tripped into the saved config.

Implementation: the fixed PRESENT_HEIGHT constant becomes a runtime video::present_height() (537 or 570). Screenshots and --dump-frames follow the mode in full-overscan view (716x537 vs 716x570); the TV-aperture screenshot stays the 1:1 692x540 crop in both modes. In the square TV-aperture window view the 540-row cutout is centred between black bezel bands (the vertical counterpart of the existing side bands) instead of being squashed.

Docs updated (configuration.md, ui.md, headless.md, example config) and the menu preview image regenerated.

Verification

  • cargo test: 1248 passed, 0 failed; cargo clippy / cargo fmt --check clean.
  • New unit tests: square canvas maps woven rows 1:1, TV-aperture row mapping (bezel padding + unchanged 4:3 cover), config parsing, menu label fit across all modes.
  • Byte-identity gate: KS2.05 boot screenshots from clean main vs this branch are byte-identical in the default mode, in both overscan = "tv" and "full" views.
  • Square-mode screenshot measured: the boot-screen graphic (140 scanlines) renders exactly 280 rows (2x), width unchanged.

The presentation has always mapped the 570 woven scanlines of a standard
field onto a 537-row 4:3 canvas, reproducing the non-square pixel aspect
of a real CRT; a 320x256 PAL screen therefore spans about 640x482 window
pixels rather than an exact 2x2. That is correct for a TV, but useless
for pixel-exact side-by-side comparison with square-pixel emulators.

Add [display] pixel_aspect = "tv" (default, unchanged) or "square": one
host row per woven scanline, so a 320x256 screen occupies precisely
640x512 output pixels. The canvas height becomes a runtime value
(video::present_height(), 537 or 570); the window, backing textures,
status-bar layout, screenshots, and recordings all follow it. In the
square TV-aperture view the 540-row cutout is centred between black
bezel bands instead of being squashed.

The mode is switchable three ways: the config field, a new "Pixel
Aspect" menu item that toggles it live (rebuilding the main and tool
window textures like a DPI change; refused while a video recording is
running, since the encoder frame size is fixed at start), and a "Pixel
aspect" row on the launcher's A/V & Emu tab. COPPERLINE_PIXEL_ASPECT
overrides the config for one run, mirroring COPPERLINE_OVERSCAN.

Default-mode output is byte-identical to the previous presentation
(verified against KS2.05 boot screenshots in both overscan modes).
@LinuxJedi LinuxJedi mentioned this pull request Jul 1, 2026
@LinuxJedi LinuxJedi merged commit 019d25f into main Jul 1, 2026
7 checks passed
@LinuxJedi LinuxJedi deleted the feature/pixel-aspect-option branch July 1, 2026 21:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant