agg23 / openfpga-SNES

SNES for the Analogue Pocket
GNU General Public License v3.0
383 stars 16 forks source link

The 4:3 display aspect ratio is not correct. #36

Closed RaspberryAlpine closed 1 year ago

RaspberryAlpine commented 1 year ago

Currently the 4:3 Display Aspect Ratio (DAR) is inaccurate to what a NTSC SNES’s video outputs. It should be 64:49 for games that have a vertical resolution of 224

Like the NES the SNES’s Pixel Aspect Ratio (PAR) is 8:7 in 256 horizontal resolution modes. The pixels are cut in half vertically in the high resolution 512 horizontal resolution modes - this give a PAR of 4:7.

(PAR)x(horizontal resolution/vertical resolution)=DAR

(8/7)x(256/224)=64/49

(4/7)x(512/224)=64/49

SegaSnatcher commented 1 year ago

I'm pretty sure you can change this in the video.json file if you wish.

HMPoweredMan commented 1 year ago

Yes this was very obvious to me when I first loaded up the core. You can see it clearly in 240p test suite as well. As mentioned aboved can we get precicely the json update to apply and still get proper integer scaled?

agg23 commented 1 year ago

I've been meaning to come back to this for a while. Ultimately I don't really understand how the PAR/DAR/etc works out.

So, the two modes are 8:7 (the internal PAR), and 4:3 (what displays look like). @RaspberryAlpine is saying that the calculation for each of the resolutions (considering 256 wide, not 512):

240px high

8/7 256/240 = 128/105 4/3 256/240 = 64/45

224px high

8/7 256/224 = 64/49 4/3 256/224 = 32/21

Is this correct? The 8:7 values match up with what I have in the NES core, which makes some sense. If this is correct, I think I understand better. Somehow the formula hadn't made sense to me before now.

RaspberryAlpine commented 1 year ago

my calculation:

(Pixel Aspect Ratio)x(horizontal resolution/vertical resolution)=(Display Aspect Ratio)

The Display Aspect Ratio of 8:7 (for most games) has the Pixel Aspect Ratio is 1:1 (in other words square pixels).

For a 224 high (1/1)x(256/224)=(8/7)

for 240 high (1/1)x(256/240)=(16/15)

Early SNES emulators used this for a few reasons: it was easy (1 to 1 scaling), it created a sharp image (no interpretation), and non integer scaling is difficult at low resolutions (for example 640 by 480 computer monitor).

Some people like 8:7 today because of nostalgia of old software emulators and because it has a sharp image.

The NTSC SNES’s pixels were not square and had a Pixel Aspect Ratio of 8:7 (for 256 wide resolutions) and 4:7 (for 512 wide resolutions)

for 224 high (8/7)x(256/224)=64/49 (4/7)x(512/224)=64/49

for 240 high (8/7)x(256/240)=128/105 (4/7)x(512/240)=128/105

SNES has more resolutions than the ones listed above but the formula can be applied to all of them.

The SNES had non-square pixels for a few reasons: the lower resolution (lower than 320) was less resource intensive, wide pixels got the display aspect ratio close to CRT’s display aspect ratio, and most precisely the SNES’s refresh rate combined with its pixel length matched up with the NTSC’s color burst frequency so composite output looked good.

I don’t mind people using aspect ratios other than the SNES’s native aspect ratio but I think the native aspect ratio should at least be an option and probably be the default.

agg23 commented 1 year ago

Your post has just confused me more. Are you confirming the numbers I listed?

RaspberryAlpine commented 1 year ago

For 1:1 pixels { "width": 512, "height": 224, "aspect_w": 8, "aspect_h": 7, "rotation": 0, "mirror": 0 }, { "width": 512, "height": 240, "aspect_w": 16, "aspect_h": 15, "rotation": 0, "mirror": 0 }

for the SNES’s native pixel aspect ratio, 8:7 { "width": 512, "height": 224, "aspect_w": 64, "aspect_h": 49, "rotation": 0, "mirror": 0 }, { "width": 512, "height": 240, "aspect_w": 128, "aspect_h": 105, "rotation": 0, "mirror": 0 }

ifighftdragons commented 1 year ago

Is this supposed to be the same for the NES and PC Engine core as well?

In short, all retro consoles meant to hook up to a CRT TV should be 64:49 ?

If so, shouldn't the other cores be updated as well? Namely: NES, PC Engine, Genesis

agg23 commented 1 year ago

Released in 0.4.1

agg23 commented 1 year ago

@ifighftdragons wrong repo, but both NES and PC Engine should have the correct DARs, I believe. SNES was my first, and I never went back to fix it.

RaspberryAlpine commented 1 year ago

Your post has just confused me more. Are you confirming the numbers I listed?

While you got it right for the native pixel aspect ratio 8:7, the other aspect ratio is weird. You used a pixel aspect of 4:3 instead of 1:1.

agg23 commented 1 year ago

I don't care about 1:1. It seems objectively wrong, and if someone wants it, they can change the video.json themselves. Some SNES games are designed for 4:3 (and some people just want it), so the PARs supported are 8:7 and 4:3.

RaspberryAlpine commented 1 year ago

Do you mean a display aspect ratio of 4:3 or a pixel aspect ratio of 4:3? Because I have never heard of anyone wanting a pixel aspect ratio of 4:3.

If you want a display aspect ratio of 4:3 then the pixel aspect ratio should be 7:6

(7/6)x(256/224)=(4/3) (3.5/6)x(512/224)=(4/3)

(7/6)x(256/240)=(56/45) (3.5/6)x(512/240)=(56/45)

agg23 commented 1 year ago

Ahhhh, you're right. Shouldn't it be 4:3 at 240p, not at 224p?

Sorry. Like I said, very confusing to me.

RaspberryAlpine commented 1 year ago

224p because the overscan of the crt would cut off the resolution with more lines than that.

Besides that I find DAR of 4:3 to be just as invalid as a DAR 8:7 (PAR of 1:1). When someone says the art was meant for 4:3, I assume they mean how it was originally displayed on a CRT (native pixel aspect ratio of 8:7, display aspect ratio of 64:49, etc). Since CRT are often said to have a DAR of 4:3.

agg23 commented 1 year ago

So you're saying the actual options I should have are between 1:1 and 8:7, because some games use square pixels, and others use wide pixels? Then 4:3 doesn't come into consideration at all, which also doesn't seem right.

In doing some more reading, it looks like maybe the options should be square pixels (1:1 PAR, 8:7 DAR), and stretched for 4:3 (which is what you would see, so maybe the 7:6 PAR you mentioned above, 4:3 DAR). That means the 8:7 PAR, 64:49 DAR isn't actually used, unless you're saying there should be a third option... 8:7 PAR wouldn't ever be seen, because it's not square pixels (a possible way of the art to be drawn), nor is it a 4:3 DAR (what practically all end users saw).

Why must this be so difficult 🤔

RaspberryAlpine commented 1 year ago

If you had to only pick one, then have a PAR 8:7 (DAR 64:49, ect) because that is what an actual snes outputs. CRTs have an approximate display aspect ratio of 4:3 but what is actually displayed is based completely on what is being inputted into the CRT.

If you want a second (and it is debatable if this is needed), then add PAR 1:1 (DAR 8:7). The reason one would want this is because of a sharp image, nostalgia for old emulators, and some small sprites are circular with this aspect ratio (example: Samus as a morph ball in Super Metroid).

I personally don’t like DAR 4:3 because it adds to the confusion and was never correct (even on a 4:3 CRT). To add to the confusion of its validity, Nintendo’s SNES Classic Mini had a 4:3 DAR option. Some of the images that come up with a google search about this are from the SNES Classic Mini.

So I think a DAR of 4:3 or any other DAR, the user should be instructed to edit the video.json file. Maybe Analogue will add framework to let the user change the scaling directly on the Pocket, like they do for their other consoles.

agg23 commented 1 year ago

I personally don’t like DAR 4:3 because it adds to the confusion and was never correct (even on a 4:3 CRT). What is correct for a 4:3 CRT then? I personally don't like the existence of the 4:3 option, but people have complained and asked for that option.

It's sounding like maybe I should just drop the 4:3 option

agg23 commented 1 year ago

Thanks for all of the help @RaspberryAlpine. I ended up going with the options of PAR 8:7 and 1:1. The Square Pixels setting switches to 1:1 PAR

HMPoweredMan commented 1 year ago

Great work, thanks!