libretro / parallel-n64

Optimized/rewritten Nintendo 64 emulator made specifically for Libretro. Originally based on Mupen64 Plus.
328 stars 128 forks source link

Automatically detect and set resolution a game requests #403

Open madig opened 8 years ago

madig commented 8 years ago

The default in GLupen is 320x240, but e.g. Perfect Dark won't start unless you set 640x480 or above. Some games can change the resolution (and aspect ratio) in-game. I'd like to have an "automatic" option for the resolution that adjusts resolution and aspect ratio according to what the game requests. Increasing the internal resolution would be to change a multiplier in the options menu, just how Dolphin and mednafen-psx do it. Dolphin also has done the work to detect the precise aspect ratio and compensate if necessary: https://dolphin-emu.org/blog/2015/08/01/dolphin-progress-report-july-2015/#40-7133-automatically-detect-gamecube-aspect-ratios-by-phire. Maybe it can be appropriated for use in N64 games.

loganmc10 commented 8 years ago

Are you sure Perfect Dark won't launch at 320x240? I'm almost 100% certain I've played it at that resolution.

madig commented 8 years ago

Oh, it works now. Maybe a bug a few commits back. Still, PD seems to use a higher resolution natively. Would be nice to set the resolution the game wants.

cxd4 commented 8 years ago

It uses 640x480 interlaced.

I highly doubt there will be a feature to automatically resize the emulation screen to the native resolution of the game's CPU frame buffer. I had enough trouble implementing a rough approximation of that in my fork of angrylion's plugin. It's certainly guesswork, as there is no way to know the video frame buffer height without making assumptions about what the VI's active video projection value for that register rounds it off to. (Bandwidth usually cuts it off to 320x237 instead of 320x240.)

madig commented 8 years ago

Interesting. By the way, I noticed that ParaLLEl sets a higher resolution for PD. Maybe the algorithm/heuristic it uses is close enough?

AmbientMalice commented 8 years ago

It uses 640x480 interlaced.

Perfect Dark always outputs at 320x240, as far as I'm aware. It's one of the only N64 games that deliberately outputs a higher resolution framebuffer into a fixed low resolution output.

cxd4 commented 7 years ago

The output resolution isn't less than the frame buffer resolution and is always 480i for any NTSC.

AmbientMalice commented 7 years ago

The output resolution isn't less than the frame buffer resolution and is always 480i for any NTSC.

Perfect Dark does not use interlaced output in high resolution mode. It's possibly the only N64 game that behaves this way.

cxd4 commented 7 years ago

The output resolution is in 480i. Perfect Dark itself is not using interlacing, no, but the frame buffer resolution at the start-up copyright screen is definitely wider than 320 pixels in pitch. I can't really get in-game enough to dump the RDRAM though because right now the Linux port of the plugin crashes.

AmbientMalice commented 7 years ago

The output resolution is in 480i. Perfect Dark itself is not using interlacing, no, but the frame buffer resolution at the start-up copyright screen is definitely wider than 320 pixels in pitch.

GLideN64 believes the intro logo is 576x480, and the ingame resolution is 640x222. This is for the American version in high resolution mode, of course. PAL uses somewhat different resolutions.

To my knowledge, the N64 hardware can only output at 640x480 in interlaced mode. Since Perfect Dark does not use interlacing, it never raises the output resolution beyond 320x240. Other N64 games bump the output to 640x480i and render internally at 480x360 and stuff like that. Perfect Dark instead scales a higher resolution framebuffer into a 320x240 output. Framemeister units report the game as outputting at 320x240, for example.

cxd4 commented 7 years ago

No because the DAC outputs at 640 * usually 480 for NTSC. It would be 640x240 without interlacing but technically you have the alternating odd and even scan-lines the same in an interlaced view, so it's the same as 640x480 because you double each scan-line without interlacing to achieve the result of intertwined lines.

GLideN64 believes the intro logo is 576x480, and the ingame resolution is 640x222. This is for the American version in high resolution mode, of course. PAL uses somewhat different resolutions.

That sounds more accurate than 320x240, yes.

I got a partial frame buffer dump so didn't see the full results with the crash in this version, but it would have been 576xsomething yeah.

Perfect Dark instead scales a higher resolution framebuffer into a 320x240 output.

You're not making sense here. There's no such feature to do that in the N64 system.

The closest thing I can think to understand what you're saying is that it has one frame buffer at high res and a second frame buffer to use even extra memory, storing the same screen shrunken down to 320x240, which would be redundant.

If you're trying to say it outputs to a VI DAC resolution of 320x240 then you're making even less sense because that's impossible. The built-in hardware result is always 640x480 or 640x240 if you will, because sometimes the 640x240 is used intermittently with a pair of 240 more scan-lines to interlace with them to create the 640x480 effect that way.

cxd4 commented 7 years ago

Framemeister units report the game as outputting at 320x240, for example.

Framemeister sounds like a nub lol and he needs to get his censors upgraded mk?

Probably because you have RetroArch configured to 320x240 so it reports that. As if it's possible for some external utility like that to detect system-level details about the N64 VI registers...?

AmbientMalice commented 7 years ago

If you're trying to say it outputs to a VI DAC resolution of 320x240 then you're making even less sense because that's impossible. The built-in hardware result is always 640x480 or 640x240 if you will, because sometimes the 640x240 is used intermittently with a pair of 240 more scan-lines to interlace with them to create the 640x480 effect that way.

So you're saying the American N64 can only output at 640x240p or 640x480i. Okay. That does make sense.

As if it's possible for some external utility like that to detect system-level details about the N64 VI registers...?

Framemeister is a hardware scaler. Very commonly used for retro consoles. It thinks N64 output is 320x240, but that's likely just an oversight, probably. If 640x240 is the NTSC standard, does that mean that the SNES outputs at 640x240, too? Or is it more flexible.

cxd4 commented 7 years ago

So you're saying the American N64 can only output at 640x240p or 640x480i. Okay. That does make sense.

Any NTSC game has 240 half-fields. If it's a PAL game it's more like 640x576i or something like that.

It's more of a TV thing than a "Perfect Dark is configured to output at X resolution" thing because the resolution is otherwise the same every time for any game anyway. For stuff like Super Mario it's 320x240.

The only other resolution is the software resolution the game is choosing to generate the screen size at or a.k.a. the frame buffer resolution.

Framemeister is a hardware scaler. Very commonly used for retro consoles. It thinks N64 output is 320x240, but that's likely just an oversight, probably.

So you're using Framemeister with a physical N64 console and not an emulator? That makes a little more sense then but the 320x240 it claims sounds kinda assumed.

Well when the real hardware DAC's the frame buffer image to fit a TV screen it always filters the frame buffer to 640 pixels wide on any system or ROM, so 320 * anything is automatically the incorrect answer there already.

If 640x240 is the NTSC standard, does that mean that the SNES outputs at 640x240, too? Or is it more flexible.

Dunno. SNES likely doesn't do any wacky filtering like the N64 does to hide low-color-quality 3-D primitives since SNES games are supposed to look pixilated even on the TV, so maybe it's not 640xanything. Or maybe the TV requires it; dunno I'm not a TV hardware guy.

madig commented 7 years ago

So do I understand correctly: it's hard to determine the actual resolution of the frame buffer a game renders into but it should be 320x240 or thereabouts for most games most of the time. That frambuffer is then handed to the DAC that turns it into 640x*. No?

Rare games like to render at a higher resolution on title screens and menus it seems. And paraLLEl seems to set the framebuffer according to what the game wants. So there apparently is a way to detect the resolution of the frame buffer in general.

hizzlekizzle commented 7 years ago

CRT TVs don't care about framebuffer sizes or anything like that. They're remarkably simple machines that don't really have a native horizontal resolution or a concept of "pixels". The SNES spits out 256 px or 512 px or whatever, and the N64 spits out 320 px or 640 px or whatever but they all take the same amount time to sweep the electron beam across the horizontal space of the screen, so it all ends up looking the same on the TV. I think Framemeisters do something similar, since they don't need to re-sync on horizontal resolution changes but they do on vertical resolution changes (e.g., switching from "240p"/non-interlaced to 480i for menus).

I don't know why they would report an incorrect horizontal resolution, but I would make sure you're testing with games that are capable of actually putting out 640x480 (like, via the enhanced resolution options from a memory pack, etc.) vs something basic like Mario64.

cxd4 commented 7 years ago

And paraLLEl seems to set the framebuffer according to what the game wants.

Dunno what that is, but if it's anything Glide64-based (or basically any old plugin) then it doesn't do it correctly.

Plugins like those only give you 320x240 because it's rounded up to 240 from something like 237.

So there apparently is a way to detect the resolution of the frame buffer in general.

There is no way to do it correctly and completely.

The only thing you can really get is the frame buffer width using VI_H_VIDEO_REG, which is always less than if not the same as VI_WIDTH_REG. You can see that it's 320 pixels wide; you can't see that it's 240 pixels tall because that's client-side information to the game, which the RCP has no pinpointed access to. The only thing the DP needs to know is that there are 237 of the 240 scan-lines which are active in the video DAC, so it only reads that many of the 240.

madig commented 7 years ago

It just occured to me that ParaLLEl might simply default to 320x240 and switch to 640x480 if the game switches to interlaced mode. At least the higher resolution usually goes hand-in-hand with a squeezed and/or shifted screen ± garbling and I read somewhere that ParaLLEl has problems with interlaced mode, so...

cxd4 commented 7 years ago

Frame buffer size can be greater than 320x240 without being interlaced.

You do not need interlaced mode to achieve resolutions like 400x300, for example, as some games do.

retrorepair commented 5 years ago

I think this would be great to revisit now that CRT resolution switching is in. It'd likely be the most accurate emulation of n64 on the planet, seeing you could play in in it's original format on a CRT TV.

I do seem to recall until recently that it did work when setting 320x240 (actually output VI resolution as opposed to 320x240) or am I dreaming this?