N64 Graphics Plugin's "graphics resolution" shouldn't govern the size of the application Window
Summary
The N64 Graphics Plugin's "graphics resolution" shouldn't govern the size of the Application Window when launching an N64 ROM or rebooting the N64 emulation core. It should maintain the window size that was being used before emulation began.
The current behaviour is very annoying when using the Graphics Resolution setting as a form of Super Sample Anti Aliasing and configuring it in excess of the desktop resolution. For example: I set the Graphics Resolution to 3840x2160 (or 2560x1440) while my desktop resolution is 1920x1080, when I launch an N64 game the application window will suddenly exceed the boundaries of my monitor.
I have to Shift Right Click the Bizhawk program on the Taskbar and select "Size" or "Move" and tap the keyboard arrow keys to get an edge of the application in to view so that I can adjust the window size.
(If you think it's weird defining a widescreen resolution for N64 games, I have the GlideN64 graphics plugin configured to adjust the View Port to 16:9, some effects in games won't render along the left and right edge of the screen beyond the 4:3 space but most stuff will render fine)
Reproduction Steps
- Navigate to Config > Cores > N64 Video Plugin Settings > Global tab > Video Resolution
- Adjust this and then load an N64 ROM.
Maybe we could add an option to suppress automatic resizing of the window, maybe view > window size > auto resize (and default it to on)
I think we're simply giving users the wrong slider. They don't care how many times pixels are scaled up, they only care about the resulting window size and whether the game is legible without being too big.
I think we're simply giving users the wrong slider. They don't care how many times pixels are scaled up, they only care about the resulting window size and whether the game is legible without being too big.
I use it for Super Sample Anti Aliasing.
I think we're simply giving users the wrong slider. They don't care how many times pixels are scaled up, they only care about the resulting window size and whether the game is legible without being too big.
How do you know that? GUI size multiplier won't even get set if you try to go off-screen with it, the problem is only with N64 plugins forcing hawk to go off-screen (and that setting is in fact a list of resolutions).
Now I don't know if forcing the hawk window to remain in the same resolution (as the OP wants) should even be solved by GUI size multiplier. Anti-aliasing is a separate feature in N64 plugins and it doesn't affect window size. And N64 internal resolution is a setting similar to other 3D emulators. It's strange to expect the resolution setting to not affect the resolution.
If you want resolution to remain the same no matter what, we have that option in Config - Display - Aspect ratio correction - Use custom size. Tho it won't actually look all that good without enabling actual antialiasing, and with it enabled why do you even need to use internal resolution higher than your window resolution?
Increasing internal resolution also increasing window size does make sense-ish. If you shrink window size to something below internal resolution, you don't actually get any benefits when using higher internal resolutions.
In theory you can resolve this similarly to how I manage this in melonDS (and plan to with Citra), the internal resolution multiplier could increase the "buffer width/height" while the "virtual width/height" is maintained to be the same as 1x. Of course, this isn't great, as this solution only really works if we assume the user is responsible with choosing an internal resolution that is actually close to their window size (choosing something way higher than the window size is a giant waste), and it would fail spectacularly if aspect ratio correction is disabled (which case buffer width/height get used, which goes back to original issue). But it ultimately makes the default work more or less as "expected" compared to other emus and makes it so you usually don't have a situation where window grows past the bounds of the screen.
Now I don't know if forcing the hawk window to remain in the same resolution (as the OP wants) should even be solved by GUI size multiplier. Anti-aliasing is a separate feature in N64 plugins and it doesn't affect window size.
SSAA is not antialiasing per se, it's rendering at e.g. 2x and downscaling.
I maintain that Mupen64Plus and melonDS, by delegating layout and scaling to the unmanaged side, are special-cased, and so it's expected that some hacks would be used to bring them back in line with the rest of the cores. For the question of "internal resolution" specifically, we don't have an internal API for it so maybe that's a good place to start. I don't think it's a good idea to further overload the semantics of the IVideoProvider properties.
Fundamentally, there's nothing really wrong with IVideoProvider wrt "internal resolution." Internal resolution is the resolution the core is internally rendering as, ergo, BufferWidth/BufferHeight (this isn't something you can change fundementally anyways, if you downscale in the buffer you lose out on any upscaling improvements). You can then also define the "virtual resolution" (VirtualWidth/VirtualHeight) to be the 1x resolution, which makes it so window size (by default) matches up with other emulators behavior, which have their window size 1x according to the 1x resolution rather than the internal resolution (although, of course, users will probably be stupid if they set internal resolution way higher than their window resolution, but that's not really something "fixable" as this case / kind of a fundemental constant with the "internal resolution" question). I would suppose the disabling aspect ratio correction turning internal (aka buffer) resolution into virtual resolution would be odd but probably not a bug / is just a feature (the most problematic is just the window exceeding the monitor resolution, which is more analogical to the question of internal resolution).
by delegating [...] scaling to the unmanaged side, are special-cased
This just fundementally makes anything regarding the question of "internal resolution" to be ""special cased.""
SSAA is not antialiasing per se, it's rendering at e.g. 2x and downscaling.
It's bold to say that "supersampling anti-aliasing" is actually not anti-aliasing at all. Supersampling what then?
I maintain that Mupen64Plus and melonDS, by delegating layout and scaling to the unmanaged side, are special-cased, and so it's expected that some hacks would be used to bring them back in line with the rest of the cores.
Do you see visual improvements if you have SSAA disabled in N64 and make internal res higher than window res? Being in line with the rest of the cores means inability to increase internal res. Now if that hacky feature is there, how exactly does it help the end user if m64p's Video Resolution option stops affecting video resolution? What exactly are they trying to do when increasing it past hawk window res? How often is it a problem that the window goes off-screen when setting internal res? It looks like instead of making it not go off-screen anymore, we're trying to make it more complicated for people who do not tend to overshoot internal res. Again internal res affecting app res is standard behavior in all emulators where you can set the former.
In Desmume, Dolphin, Project64, PCSX2, RPCS3 etc. adjusting the Internal Rendering Resolution does not affect application window size. It just increases the rendering resolution and downscales to fit the current application window size.
Increasing the Internal Rendering Resolution greatly improves visual fidelity in games as it is effectively Super Sample Anti Aliasing. Some PC games will have either SSAA or a Resolution Scale setting (which can be set above 100%) that achieves the same thing.
It's logical both ways. If you order an emulator to be a bigger screen, you do that with full awareness. I disagree with "They don't care how many times pixels are scaled up". However the outcome of that can be absurd--only because bizhawk has a memory of window scaling factor. Arguably it could remember a size and try to fit when the emulated screen size changes, but the ship has sailed long ago. I would suggest a compromise is to simply stop bizhawk from ever resizing itself automatically to something exceeding the size of the "monitor" it's on, unless it's already larger than that monitor. Or, and I thought of this before I read the years-old backlog, an option that suppresses automatic resizing of the window altogether. I think anyone trying to contort bizhawk to do insane things with resolution and discovered that it's freaking out the window size will have seen the scaling menu and noticed there's an option that's basically "stop freaking out"
And as for user who wants to use billion x billion resolution and then scrunch the window down to a tiny fraction of that using whatever likely-to-be-assy downscaling we do (hint: define optimal; for whatever definition you have, bizhawk isn't doing that), I have no pity. It's a foolish desire.
Your idea sounds like a good stop-gap at the very least, but how would you implement it? Should the frontend cache the first values it gets for the buffer size and keep using those until core restart? I want to say that would fail on most N64 titles.
So Config - Display - Aspect ratio correction - Use custom size is absolutely not the right option for locking window size to some user defined value? Is the value really desired to be automatic?
I will maintain that the issue of window size exceeding montior size is analogical to the question of "internal resolution." The de facto issue is ultimately, if the IVideoProvider BufferWidth/BufferHeight/VirtualWidth/VirtualHeight exceeds the monitor's resolution, BizHawk may end up just resizing the window accordingly and you get a user with a window exceeding the monitor's resolution.
Of course, we can typically avoid this under the default settings by just setting VirtualWidth/VirtualHeight to the 1x resolution for these internal resolution cases, as the default settings will use those for the 1x window size, as that typically is not going to exceed the user's monitor resolution. However, if the user decides to go disable aspect ratio correction (or even just sets it to the 1:1 AR option), then that gets thrown out the window, and BufferWidth/BufferHeight will end up used, and BufferWidth/BufferHeight is not something you can just change (as that represents the actual video buffer dimensions, i.e. "internal resolution").
So Config - Display - Aspect ratio correction - Use custom size is absolutely not the right option for locking window size to some user defined value? Is the value really desired to be automatic?
That feature does work in every case, but it's not the nicest UX. It wouldn't be so bad if, when the window resizes due to the game changing scanline count or something, it was always an even scaling—that is, having the same aspect ratio as before—but it's not. (Obviously internal resolution options of 2x, 3x, etc. are, as are Mupen's options.) So a naive implementation of locking the window size would result in the picture being distorted sometimes. This leads me back to my suggestion of a "maximum window size".
The de facto issue is ultimately, if the IVideoProvider BufferWidth/BufferHeight/VirtualWidth/VirtualHeight exceeds the monitor's resolution, BizHawk may end up just resizing the window accordingly and you get a user with a window exceeding the monitor's resolution.
The window can also outgrow the display even with a reasonably-sized video buffer because of the window scale. Both that setting and Mupen's internal resolution setting are things explicitly chosen by the user yet still need additional checks to ensure the interface remains usable. But they are not analogous.
The window can also outgrow the display even with a reasonably-sized video buffer because of the window scale.
Is this speaking of something outside of BizHawk or are we talking about the Window Size 1x/2x/3x/etc fields we have? Those would already automatically limit themselves if they would exceed the monitor's resolution. Of course, that means nothing if 1x itself would exceed the monitor's resolution.
Yes, I was referring to View > Window Size, which does currently check the display size.