PCSX2 / pcsx2

PCSX2 - The Playstation 2 Emulator
https://pcsx2.net
GNU General Public License v3.0
11.45k stars 1.59k forks source link

[Feature Request]: Full active area display mode option #5330

Open Zinfidel opened 2 years ago

Zinfidel commented 2 years ago

Description

This feature request is a little hard to describe concisely, so bear with me. By "active area" I am referring to an output mode representing the grid of samples that are defined by the PS2's current pixel clock, graphics mode, and the underlying signal (assume NTSC to simply for this description). So, for the PS2's 640x448 mode, which has a pixel clock of 13.5Mhz, on an NTSC signal, we would get an output resolution of 704x480† pixels, with the 640x448 framebuffer situated somewhere inside of that. It would just be letter-/pillar-boxed. The PS1 has registers that define where in the signal the framebuffer actually gets drawn and that determines the proportions of the borders, so I am assuming the PS2 operates in a similar fashion.

When the PS2 is in its 512px mode, the pixel clock is 10.8Mhz. This would give us an output resolution of 560x480‡ with the FB situated somewhere inside of that. The PS2 of course has many other modes, but I'll not list each of them for brevity of this post.

† The math actually produces 712x486, but considering 480 vs 486 lines, and clean vs production aperture, we get 704x480. ‡ Same as above, but 565x486.

Reason

The motivation for this request is PAR correction. By outputting these active area resolutions with the framebuffer situated inside of the signal however it is that the PS2 decides to place it, you can do a very convenient trick where you simply take the output resolution, stretch/squeeze the width such that you get a 4:3 image, and you will automatically get the correct PAR. The mednafen PS1 emulator actually does this already in its "Debug" output mode. This allows the emulator's frontend to just stretch the window using whatever scaling it likes to 4:3 to get the right PAR for any graphics mode, without knowing anything about what's going on under the hood.

This is also a really useful feature for capturing game footage from the emulator, as you don't need to know anything about what graphics mode the game is running in. For games that change graphics modes/resolutions, you don't need to worry about independent scaling of video segments, because they can all just get stretched to the same 4:3 resolution and have correct PAR. I come from the TAS community where we encode videos with PAR in mind, so this kind of thing is a big pain for us!

One reason why an output mode like this might be preferable to just doing the PAR correction directly is for those who want to have a high degree of control over the scaling (for instance, high quality encodes using very slow scaling algos).

Examples

An excellent example of the use of this trick can be seen in Armored Core: Nine Breaker. Here we have a direct capture from PCSX2 of the title screen: image Now, we place the framebuffer into the full active area (note: the actual proportions will be defined by how the PS2/game decides to position it, this is just an example) image Now, squeeze the horizontal dimension to form a 4:3 image, which for a height of 480 gives good ol' 640x480: image Now, what makes this a great example is the fact that the artist who designed this title screen was aware of the < 1.0 PAR of the PS2's 640px mode, and drew the circles such that they would appear perfectly circular and concentric with a PAR of 10:11 image

Zinfidel commented 2 years ago

I wanted to avoid making the request too bloated, and as a result I had to gloss over a LOT of math regarding getting these active areas. For now, I'm going to drop a few links that are quite useful here in case someone is masochistic/curious enough to follow the process:

I would also like to bring up the relationship to Rec.601 that the PS2 shares, in that its 640x448px mode has a pixel clock of 13.5Mhz which is exactly that of rec.601. This is quite convenient because it means that standard Rec.601 capture devices will spit out a 720x480px image for this resolution mode that theoretically will map directly to square pixels. Accounting for aperture, and 480 lines vs 486 assumed lines, for NTSC you just crop 720 to 704, and you end up with exactly the image that I am describing in this request.

lextra2 commented 2 years ago

sounds more like "stretch to custom aspect ratio" to me

Zinfidel commented 2 years ago

sounds more like "stretch to custom aspect ratio" to me

While the motivation for this request is ultimately aspect ratio correction, the request as I've written it specifically avoids any kind of stretching or AR correction. An imagined way this would work if implemented and the option turned on would be that PCSX2 would output a 704x480 image with black borders around the framebuffer for a game running in 640x448 mode. That would be the end of it as far as this request is concerned.

You could however then use that image for AR correction easily by setting the AR mode in PCSX2 to forced 4:3. The image would then have correct PAR as a result of the DAR adjustment. Direct PAR correction could also be implemented without worrying about active area, though I've asked for this particular way of doing it simply because it gives users more control for post-processing.

refractionpcsx2 commented 2 years ago

https://github.com/PCSX2/pcsx2/pull/5810 makes the 480p aspect correct as it seems to be a 3:2 aspect ratio, in my PR it will automatically select that mode when going in to 480P mode if you change your Aspect in the GS Window settings to the Automatic Standard setting. For best effect (and to get the borders as per the OP) you also need to enable "Screen Offsets" in the Graphics Settings to correct the aspect further.

Zinfidel commented 2 years ago

I don't fully understand how #5810 applies to this issue, but a lot of it is over my head. I think what I'm seeing though is that #5810 doesn't "enforce" the display parameters I've suggested here in this issue, but rather just makes it possible to replicate this setup?

There's some talk about 3:2 resolutions going around which I'm not so sure about: 720x480 is a pretty common resolution mentioned when talking about BT.601/13.5Mhz but that "resolution" is actually samples/lines, not square pixels. I assumed the PS2, in 480 mode, had a framebuffer that truly only offered 480 pixels of width, and that the 720 samples that came out of the wire was an adjustment made by other video hardware sampling the FB into a composite/progressive video signal.

Well in any case, maybe performing the same experiment that I did here in that PR could shed some light on this? I can't do it right now but I could try it out later after work if someone doesn't get to it first.

EDIT: wanna add that I don't mean to come off as combative here - I have a narrow view of the problem and I just want to ask the right questions to understand the solution!

refractionpcsx2 commented 2 years ago

It applies to this issue, because your original problem was the aspect ratio and display was incorrect in 480p mode, that PR corrects it and will achieve what you showed in your original post of the correct aspect ratios.

Zinfidel commented 2 years ago

I'll take your word for it and would like to add I appreciate the effort you've invested into this! I'll boot up Ninebreaker later after the CI is done and play with this.

refractionpcsx2 commented 2 years ago

Cool, thanks

Zinfidel commented 2 years ago

I tested the new changes, but they don't directly apply to this issue as far as I can tell.

It applies to this issue, because your original problem was the aspect ratio and display was incorrect in 480p mode, that PR corrects it and will achieve what you showed in your original post of the correct aspect ratios.

That's what #5842 is about, but this issue was not about progressive scan or even directly correcting AR actually. Ninebreaker doesn't have a progressive mode as far as I know. It was just about a display mode that exposed the full active "surface" of the signal rather than just the PS2's framebuffer, regardless of interlaced/progressive or resolution.

The way the progressive screenshots of the new 3:2 mode look in the PR are pretty much exactly what you would get from a BT.601 device (that doesn't automatically correct to 4:3) capturing from a PS2 over component cables, for both interlaced and progressive games. It's also exactly what the mode I'm asking for in this issue would look like, so it's really very close. If you took those 3:2 images and squished down to 4:3, you get what would show up on a CRT TV.

refractionpcsx2 commented 2 years ago

Alright, I've removed reference to this issue then. Sorry that I misunderstood you.

So what do you consider the full active "surface"? if you try to display more than what's in the framebuffer, 99% of the time you get garbage. What we display is all the data that is there.

Zinfidel commented 2 years ago

I'm afraid I can only answer this superficially based on observations. To try to be concise though, the rest of the surface wouldn't come from anywhere, it would just be padding applied to the FB. It's there in the active area because the video output circuits have to pick a time during each frame to start sampling the framebuffer into the signal, and there isn't enough data to fill the whole signal. The PS1 picks this point in time via the GP0 register, though I doubt it's so simple on the PS2.

For 480i/p modes for the PS2, the active area would be 720x480 if we just assume that BT.601 is the law here. 480 lines, with a nominal active period of 53.33μs for each line, divided/sampled by a pixel clock of 13.5Mhz gives 720 samples. The PS2 presumably has some way of deciding when/where to put the FB into this area in software or hardware. I have to disclaim now though that those nice round numbers are huge assumptions based on pretending that the PS2 actually cares about BT.601 (which doesn't apply to output devices anyway!).

Each resolution mode would have it's own individual active area based on pixel clock for that mode, so it would have to be something calculated based on PS2 hardware internals. That's where my knowledge here ends though. Actually implementing this definitely requires understanding of the PS2's video system that I don't have.

refractionpcsx2 commented 2 years ago

I believe it is the same as PS1 in that regard, there are DISPLAY registers which say where in the DISPLAY buffer the framebuffer is going to be drawn to, you get a width, height, magnification (for working out how to zoom the framebuffer to fit the screen) and a DX and DY which serve as offsets on to that DISPLAY to start the sampling, the base values for PAL are 652 and 50 respectively, I think... Numbers are unimportant but it doesn't matter.

What does matter is I don't know how big those Display rects are, at all.. I guess you can work it out from Mhz and all that, but that's beyond my current comprehension of CRT analogue signals.