Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NTSC Integer scaling improvements #1453

Open
limi opened this issue Oct 2, 2024 · 7 comments
Open

NTSC Integer scaling improvements #1453

limi opened this issue Oct 2, 2024 · 7 comments
Assignees

Comments

@limi
Copy link

limi commented Oct 2, 2024

Collecting these here since they will disappear on Discord, where I first documented these.

Testing is done on a MacBook M1, running macOS 15 Sequoia. Native resolution on the laptop panel is 2880×1800, Retina doubled to 1440×900 effective resolution.

Display settings in Amiberry look like this:

image

Integer scaling on 1280×800 (16:10), Retina doubled to 2560×1600

Summary:

  1. NTSC always stretches to full width (16:10), no matter the resolution. (Low Res, High-Res Laced, High-Res Non-Laced)
  2. PAL gets the 4:3 aspect right, and integer scale looks perfect both in Hi-Res Non-Laced and Laced.

Screenshots of the above issues:

NTSC High Res Non-Laced — is stretched to full width instead of having left/right black borders:
image

NTSC High Res Laced — is stretched to full width instead of having left/right black borders:
image

NTSC Low Res Non-Laced — is stretched to full width instead of having left/right black borders:
image

PAL High Res Non-Laced — appears correct:
image

PAL High Res Laced — appears correct:
image

Integer scaling on 2880×1800 (16:10), Retina doubled to 1440×900 (native laptop display resolution)

  1. NTSC seems to integer scale perfectly.
  2. PAL seems to integer scale perfectly.

Integer scaling on 1920×1080 (16:9) external display, native resolution, no pixel doubling

Summary:

  1. NTSC Hi-Res — should be 1000px tall at 5× integer scale, isn’t.
  2. NTSC Hi-Res Laced — should also be 1000px tall, isn't — and has massive flickering and corruption.
  3. PAL Hi-Res — seems perfect.
  4. PAL Hi-Res Laced — seems perfect scaling-wise, but has the same flicker and corruption as NTSC.

"Remove Interlace Artifacts" did not help, tested with it both off and on.

Screenshots of the above issues:

NTSC Hi-Res (should be 1000px tall at 5× integer scale, isn’t):
image

NTSC Hi-Res Laced (should also be 1000px tall, isn't — and has massive flickering and corruption):
image

PAL Hi-Res (seems perfect):
image

PAL Hi-Res Laced (seems perfect scaling-wise, but has the same flicker and corruption as NTSC):
image

@midwan
Copy link
Collaborator

midwan commented Oct 3, 2024

I can't really recreate these here, using the latest (unreleased) version.
But I don't have a Retina display to test with, either.

I did some tests on an RPI5 connected to a 1080p display, using the latest RPI-OS (with Wayland).
No interlace artifacts, and no stretching of the NTSC modes. I didn't measure if the scaling is as much as it should be, but the aspect ratio seems correct.

Can you repeat your tests with the latest version from source?

@limi
Copy link
Author

limi commented Oct 3, 2024

I’m guessing at least some of the issues are HiDPI (Retina Display) related.

When I switch from 1280×800 (HiDPI doubled) — which is what I use on the laptop usually — to the native display resolution of 1440×900 (HiDPI doubled), it does not stretch my NTSC Workbench screen anymore. However, if I launch the game Airborne Ranger or Defender of the Crown (NTSC games), it does stretch it to the full 16:10, as before. Very curious.


Conversely, when I connect an external display with a native resolution of 1920×1080, it kind of does the opposite — the scaling of the Workbench screen is not 1000px tall (5×NTSC) like it should be. Instead, it is 800px tall (4×NTSC):

image

If I launch the game Airborne Ranger, it does scale it to 1000px tall (this is the correct scaling of NTSC — ignoring the 5:6 PAR for the sake of this bug report — it does 200×5=1000):

image

Launching Gods — a PAL game that only uses the top 200px — also scales correctly at 5×:

image

So it does seem like there is something going on specifically with Workbench, which is using the default NTSC High Res (Non-Laced) resolution — aka. Med Res — no overscan, no custom values.

Can you use my configuration and test with those games on your screens, also check out the Workbench, and see if you see the same result when using the AmigaVision setup?

default.uae.zip

@midwan
Copy link
Collaborator

midwan commented Oct 4, 2024

Isn't that correct though?

NTSC LowRes is 320x200, and it can go up to x5 scale and still fit in a 1080p resolution (320 x 5 = 1600 horizontal, 200 x 5 = 1000 vertical).

NTSC HighRes, which the Workbench uses, is 640x200. We cannot scale that up 5x in a 1080p display, as 640 x 5 would be 3200, exceeding the horizontal size available. And we always keep the aspect ratio, so it should not stretch it, meaning that it can only do a 4x scale in that case.

If you switch Workbench to NTSC LowRes, you should see the same results you have in the games.

@limi
Copy link
Author

limi commented Oct 4, 2024

Oh, excellent — then at least we are both seeing the same, unlike the HiDPI resolutions that seem harder to reproduce.

Yes, mathematically speaking you are of course correct by the strict interpretation of "integer" scaling as the zoom factor.

Let's clarify, since High Res resolutions probably requires a additional explanation, and Super Hi-Res too! 😄

"Integer" as used in this context just means to never divide a pixel on the boundary, never take (in the common case) a square low-res pixel (320×200/256) and render it at any other zoom level than 2×, 3×, 4×, 5×, etc.

Maybe one way of thinking about it is that integer scaling is about the output representing a whole pixel, not the scale factor being integer.

Horizontal scaling needs to be handled independently as far as scaling factors go. We can scale those with twice (or three times, in the case of Super High Res) the precision without "splitting the pixel", so to speak.

So, in the case of scaling "Med Res" (640×200/256) into a 1920×1080 frame, we can scale it by 5× on the vertical scale to get 1000px (NTSC), or 4× to get 1024 (PAL).

On the horizontal scale, we have double the pixels, so we scale it at 640×2.5 — this is still "integer scaling" in the sense that the output is always integer, which is what matters. There is no 641×200 resolution on the Amiga, but you can get e.g. 642×200 by using overscan.

With that in mind, there probably needs to be a special case for High Res and Super High Res (and possibly for Interlaced, since we are seeing weird issues there too?) resolutions, that uses .5× scale on those resolutions, or maybe a “pre-scaler” scaler that represents them as 2× or 3× internally before handing it off to the SDL2 scaler?

The resulting 4:3 outputs in a 16:9 1920×1080 frame would be:
(We use a 4× horizontal and 5× vertical multiplier for NTSC here to get as close to the 5:6 pixel aspect ratio as possible while maintaining integer scale)

Named resolution Input Horizontal Scale Vertical Scale Output
NTSC Low Res 320×200 1280×1000
NTSC Low Res Laced 320×400 2.5× 1280×1000
NTSC High Res 640×200 1280×1000
NTSC High Res Laced 640×400 2.5× 1280×1000
NTSC Super High Res 1280×200 1280×1000
NTSC Super High Res Laced 1280×400 2.5× 1280×1000
PAL Low Res 320×256 1280×1024
PAL Low Res Laced 320×512 1280×1024
PAL High Res 640×256 1280×1024
PAL High Res Laced 640×512 1280×1024
PAL Super High Res 1280×256 1280×1024
PAL Super High Res Laced 1280×512 1280×1024

Of course, the auto-crop complicates this, since you can end up with e.g. a PAL Low Res game being cropped to being 203 pixels tall, but 1600×1015 will fit in the 1920×1080 frame at 5×/5× scale, and won't drop to a 4× scale until it reaches a height of 205 pixels.

(In which case we could talk about "integer scale overscale" to keep it at 5× by cropping pixels that aren't critical to the game, like we do with our scale/crop offsets in AmigaVision on MiSTer — and some console emulators also let you do — but let's keep that out of this discussion for now!)

Hopefully @Optiroc can chime in with a better way of explaining this, and/or a model of how to represent it as general approach to scaling. On MiSTer, we end up with 1280×1000 in a 1920×1080 frame for NTSC Low Res. There's probably a reasonable way to make this generalizable with some sort of threshold system.

(Also, at lower resolutions than 1080p, there may be too few pixels to keep the NTSC 4:5 / 5:6 PAR, so integer scaling there probably just needs to revert to 1:1 PAR even for NTSC.)

With higher resolutions, we can get to the 5:6 PAR, e.g. with 1200px tall screens, NTSC Low Res becomes (320×5)×(200×6) = 1600×1200. We are looking for a pixel aspect ratio around 0.8 (4:5) to 0.8333 (5:6) for NTSC pixels when integer scaling.

@midwan midwan changed the title Integer scaling issues, especially with NTSC NTSC Integer scaling improvements Oct 11, 2024
@midwan
Copy link
Collaborator

midwan commented Oct 18, 2024

Just to summarize, after our discussion:

  • PAL resolutions are already working correctly with integer scaling, as they are scaled 1:1
  • NTSC resolutions need some improvements, and that's only for native resolutions from 1080p upwards. We don't have enough pixels in lower resolutions to scale them properly.

@limi
Copy link
Author

limi commented Oct 18, 2024

Indeed, and there are also still issues around HiDPI screens, scaling seems to break when you are not in the native-to-the-panel resolutions.

@limi
Copy link
Author

limi commented Oct 18, 2024

And I made a spreadsheet that I shared with @midwan to use as a reference for scaling on a set of common display sizes:

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants