Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.Sign up
mGBA Wii NTSC Aspect Ratio Wrong in Pixel Accurate mode (?) #500
Comparing mGBA Wii vs RetroArch mGBA core I noticed that mGBA Wii aspect ratio is kinda off (vertically stretched). I configured RetroArch using this post (https://forums.libretro.com/t/recommendations-for-optimal-video-settings/1097) as a guide, and then compared the viewport sizes of both RetroArch and mGBA, but the "effect" can be viewed kinda clearly on Metroid Fusion logo (the round thing behind the title is kinda oval on mGBA vs RetroArch were it is perfectly round).
@endrift Sorry for the massive delay.
The things that are missing depend on how far you want to go in terms of the stupid nonsense in my previous comment.
I don't have any of my debugging stuff currently and I'm too incompetent to read code, so I'm purely eyeballing this, but it looks like mGBA runs with the framebuffer and video encoder both set to 640 pixels, which will result in a squished (thin/tall) image, horizontally, because of the Wii and GameCube's natural non-square, 10:11 pixels.
A game like Mario Kart: Super Circuit is good for quickly judging ratios because the game's menus are made almost entirely out of circles. Unscientific ruler math (I measured the image on my TV by hand) would seem to confirm that we're almost certainly looking at pixels that are 10:11.
If you just want to achieve square pixels and assuming my estimate of the framebuffer width is accurate, the quickest and cleanest fix would be to simply set the video encoder width to 704. You can probably stop reading this comment right here and close the issue.
Video widths in question
For anybody still reading, I'm gonna quickly get into the various widths we're looking at here and I apologize if it comes across as patronizing, I just want to get across all the terminology I'm (mis)using in this comment.
There are four different widths at play in mGBA on the Wii/GameCube:
The last one of these is what causes all our troubles really, the GameCube/Wii natively has these thin/tall pixels, so if we want square pixels in software running on these platforms, we have to make up the width by changing one of the first three.
Methods of correcting the pixel widths to square
Let's assume mGBA is running in the pixel-accurate screen mode with pixelated filtering, for a GBA image that's 480*360. The GameCube/Wii framebuffer is set at 640*480, the GameCube/Wii video encoder width at 640.
This is the current setup as far as I know. The GBA image is now displayed across 480 pixels in the center of the 720 pixel-wide video signal coming from the Wii, with its 10:11 shaped pixels. This makes the GBA pixels, and so the entire screen, thinner than they would be on a real GBA or on any normal platforms's emulator, with square pixels.
You could make up the difference in one of three different ways:
I would strongly suggest that the last of these is the best option. The video encoder's scaling is very clean, and this avoids doing any weird framebuffer widths or scaling to odd non-integer values within the emulator itself, and it's basically a set-it-and-forget-it approach which changes almost nothing about the way the emulator and its UI run. It's a single "fix everything" button.
This marks the end of everything in this comment I would consider to be a high priority for mGBA for Wii/GameCube, which would allow closing this issue as it resolves everything in the issue as it was filed.
What about that widescreen nonsense?
In my previous comment, I also talked about the possibility of a special widescreen mode for the Wii/GameCube port. This is the kind of stuff you can very freely ignore because it's just one person (me) going "I'd like this" that nobody else is really asking for.
All of the discussion above concerns how mGBA displays on 4:3 TVs (or in 4:3 mode on widescreen TVs). Obviously, there's no room in the framebuffer for a 3* scale of the GBA screen, at 720*480. Also, 4:3 TVs don't have the aspect ratio to display it even if the framebuffer could fit it.
The trick you can do on a widescreen TV though, is to stop targeting 1:1 square pixels entirely, and instead start targeting 0.75:1 pixels. Anamorphic widescreen will do the rest of the work for us from there, you can target 0.75:1 pixels and when stretched by the TV, the result will be 1:1 pixels.
How do we get there?
Let's pause here for a moment. We've currently got 20:33 pixels, or ~0.606:1. We're well short of 0.75 right now, and even if we push the video encoder way out to the maximum 720 pixels wide, we'd only make it up to 15:22, or ~0.682:1. We're targeting 3:4 or 0:75:1, so we need another push from somewhere else.
The GameCube/Wii video encoder can't display any wider, so we need to come from the other direction: make the framebuffer width smaller so that the video encoder is relatively scaling it up more to make up that last 10% or so of pixel width we need.
The result there is pixels that are square to within a tolerance of one 25839th of a pixel. I suspect differences in TVs and even Wiis at this point would have introduce a higher margin of error. The full equation there ultimately being:
Now, is 522 framebuffer and 646 video encoder the only option? Not really, it's just the squarest option. I know I said all those things about sacrificing framebuffer width earlier, but here I go suggesting exactly that. It's a while since I worked out the math on it, but there's probably any number of "good enough" combinations that preserve more of the framebuffer.
If you wanted to stick with the video encoder width of 704 at all times, you could try a framebuffer width of 568 in this special widescreen mode, for a pixel width of 640:639, or ~1.002:1. I wouldn't recommend going any higher than 704 in the video encoder, as you'd risk going into overscan, so that (an extra 46 pixels over my "optimal" suggestion) is probably about the most you could save in the framebuffer. This mostly matters for the sake of how much room the mGBA UI needs to remain legible.
I have no real opinion about this; if you did decide to implement a feature like this and you preferred the extra framebuffer room, that seems like a perfectly sensible approach and I doubt the difference of a few hundredths of a pixel width would be noticeable to anybody.
First off, set the video encoder width to 704 as a baseline setting. If square pixels are the entire goal here, you're done.
If you want to look at the nonsense stuff, I think the most logical way to do this in the UI if it were to be added would be to add it as a third option under "Screen mode". "Pixel-Accurate", "Stretched", and ... a better name than "Full Widescreen Pixel-Accurate".
When switching to Full Widescreen Pixel-Accurate, the framebuffer width would drop (to, e.g. 522 or 568) and the video encoder width would also be set to match that setting (e.g. 646 video encoder for 522 framebuffer, or simply remaining at 704 video encoder if you chose 568 framebuffer), the scaling would be forced to 480*480, and the "Horizontal stretch" and "Vertical stretch" settings would probably just be ignored entirely, in the same way that some of them are currently ignored in Pixel-Accurate mode. The "Filtering" setting would continue to function as normal.
Sorry this is so unreasonably long. I hope I got across everything I was trying to say.
Oh wow, that's huge. Thanks for the correction, @Extrems. I think on the whole you could be a lot more helpful on this subject than me if you're interested/willing. Most of what I "know" about the subject is bad guessing and trial and error; your expertise in this area would certainly be appreciated.
I unfortunately have no experience with the GameCube port, I just foolishly assumed it shared the same issue because of its similar (identical?) video hardware. Sorry about that. I hadn't realized that port was yours; I would certainly have known you'd gotten it right otherwise.