Correcting scaling artifacts in lr-mame2003
-
@riverstorm @AndrewH is already making PRs to my repository - we are collaborating and that's awesome!
i don't really want to add anything else. i think you should wait until we're at a stable state with the code and then retest. i will announce it in the other thread when we're ready.
-
Shouldn't the screen be filled vertically or is the 120 pixels in the subjective range caver was mentioning. Both regular and wide produce the same results (because it's a widescreen game?)
For a horizontal game, with horizontal scanlines, setting the vertical scaling to an integer value should result in the 'clearest' representation. Non-integer values won't give the same problems as seen on the vertical games, but it's still less than ideal.
If you're up for some testing, you can try manually editing the file for one game to see whether the difference is acceptable to you. One great thing about the emulationstation - retroarch setup is that you only need to exit the game and restart it for any changes to take effect i.e. there's no need to restart emulationstation, so it's really quick.
Personally, I don't particularly notice the narrow black bars at this point.If accurate = false should both the y and x axis be multiplied by the intScaleFactor?
So, the way this is intended to work is as follows;
- The scaling factor is seldom an integer - it's likely to be 3.4 or 4.5 or whatever.
- For horizontal games we want to constrain the vertical scaling factor to the next lower integer value, but we're not so concerned about the horizontal scaling - we can allow the original scaling factor to be used. This will result in a display that's got a wider aspect ratio than the original game (to better fill the screen), but it shouldn't be by much.
- For vertical games, we want to constrain the horizontal scaling factor to an integer value, but we don't worry so much about vertical scaling, and again the aspect ratio may end up a bit different from the original.
- The 'accurate' flag is intended to be used if you want to more strictly preserve the aspect ratio, and can tolerate more of a black border around the viewport.
Using the game in your example above (Joust), the scaling factor is going to be 4.5 (1080/240 = 4.5)
We scale the viewport height by the integer value (4) to give 240 * 4 = 960
We only ever scale it vertically by an integer value for the reasons above.
For the viewport width, there are now the following options;accurate = false
Scale by the actual scaling factor of 4.5 --> 320 * 4.5 = 1440
The aspect ratio will now be 4.5:3, rather than the original 4:3accurate=true
Scale by the integer scaling factor of 4 --> 320 * 4 = 1280
This preserves the original aspect ratio, but the black bars on either side will now be 320 pixels wide, rather than 240.As for the rest, I'm honestly not too interested in getting embroiled in any controversy. I found a problem, and I set out to troubleshoot and understand it in order to provide the (hopefully) best quality of information to get it resolved. In the process, I learned a bit, and it was great to have others take interest. I don't consider my contributions significant enough to merit a lot of ego on my part, and I want to be respectful of the work that @dankcushions has already done.
While I have a small amount of prior 'programming' experience, it's taken a while to get to grips with Python, and then with Git, but as @dankcushions says, we're collaborating now and two things I worked on have already been incorporated into the original code (adding the helpful headers to the .cfg files, and making the display while the script runs a little nicer).
We'll see where we go with any further contributions. I have one or two more aspects of my 'test' script that I might contribute, but would need a bit more discussion about replacing the part that's doing the calculations.
-
@andrewh said in Correcting scaling artifacts in lr-mame2003:
accurate=trueScale by the integer scaling factor of 4 --> 320 * 4 = 1280
This preserves the original aspect ratio, but the black bars on either side will now be 320 pixels wide, rather than 240.in this case, you don't really need the script at all - just use integer scaling. i guess the script would give you the correct vertical/horizontal variant of the shader, but it could skip all the calculation parts to and just turn on integer_scale.
We'll see where we go with any further contributions. I have one or two more aspects of my 'test' script that I might contribute, but would need a bit more discussion about replacing the part that's doing the calculations.
i think in the context of a PR i'd be able to understand what you're doing differently more easily and be able to accept it. seeing the diff helps a lot for me!
the way i currently do it is really daft - looping through 99 possible scaling options every time rather than just calculating it up front. i was only interested in the cfgs so threw whatever "worked" at it ;)
-
@dankcushions said in Correcting scaling artifacts in lr-mame2003:
but it could skip all the calculation parts to and just turn on integer_scale.
I thought about that and wondering if it had any value. To actually have the integer scaled numbers in a config file or just remove that piece and use the built-in Retroarch integer scaling. I am not sure if you know that's an option already built-in Andrew?
I've been doing a hybrid where I use the script configs except where @UDb23 has created an overlay then I delete that config file and add shader support to the overlay config. I also tone down the brightness/opacity on each one so the game stands out a bit brighter then the overlay.
looping through 99 possible scaling options every time rather than just calculating it up front
I wondered about that and if it could be a smaller loop. I thought if you're integer scale value is 99 you have a very large display and I am coming over to your place to game! Ah well...99 bottles of beer on the wall, take one down... :)
We were up in the twin cities (Minneapolis/St. Paul) and they had a jumbo sized 8' x 6' Pac-Man & Galaga. It's was a nice bright LED screen. Very fun and impressive.
making the display while the script runs a little nicer).
I noticed that and I do like the dots vs. the scrolling ROM names.
Using the game in your example above (Joust), the scaling factor is going to be 4.5 (1080/240 = 4.5)
We scale the viewport height by the integer value (4) to give 240 * 4 = 960
We only ever scale it vertically by an integer value for the reasons above.
For the viewport width, there are now the following options;If you're up for some testing, you can try manually editing the file for one game to see whether the difference is acceptable to you.
I might be missing it here but those are the same numbers I came up with and it all worked out correctly but I thought the goal of the script was to fill the screen vertically (Y = 0) as in how Dank is calculating which would be what you're suggesting? Still using joust as the example.
Andrew calculations - Ratio .67
aspect_ratio_index = "22"
custom_viewport_width = "1440"
custom_viewport_height = "960"
custom_viewport_x = "240"
custom_viewport_y = "60"Dank's calculations - Ratio .74
aspect_ratio_index = "22"
custom_viewport_width = "1460"
custom_viewport_height = "1080"
custom_viewport_x = "230"
custom_viewport_y = "0"For a horizontal game, with horizontal scanlines,
That's a good point. Is there horizontal games with vertical scan lines (monitor rotated) and vice versa vertical games with horizontal scanlines (monitor rotated)?
I might be missing the whole goal here but I thought it was to fill the screen vertically and scaling the other axis? If you using int() for scaling then that's an option already built-into Retroarch.
-
@riverstorm said in Correcting scaling artifacts in lr-mame2003:
That's a good point. Is there horizontal games with vertical scan lines (monitor rotated) and vice versa vertical games with horizontal scanlines (monitor rotated)?
no, because by definition, if the game is vertical then the monitor is rotated :) at least, by mame's definitions.
I might be missing the whole goal here but I thought it was to fill the screen vertically and scaling the other axis? If you using int() for scaling then that's an option already built-into Retroarch.
i can't speak for Andrew's calculations, but for mine it (should) be always fill the screen along the Y axis...
i think the latter calcs don't work properly after my last tweaks but i will review them at some point.
-
@dankcushions said in Correcting scaling artifacts in lr-mame2003:
no, because by definition, if the game is vertical then the monitor is rotated :) at least, by mame's definitions.
Whew, that would just require more data and calculations. I was thinking like cocktail cabinets that would have to rotate the screen (to the side). Unless they stuck with vertical games only and flipped vertically for 1 and 2 players on the ends would make sense.
i will review them at some point.
Alright I'll just wait and see if what you come up with. If you need any help or testing just let me know. I am setup and streamlined with Notepad++ (Unix) for making changes and running the script.
-
@riverstorm said in Correcting scaling artifacts in lr-mame2003:
@dankcushions said in Correcting scaling artifacts in lr-mame2003:
no, because by definition, if the game is vertical then the monitor is rotated :) at least, by mame's definitions.
Whew, that would just require more data and calculations. I was thinking like cocktail cabinets that would have to rotate the screen (to the side). Unless they stuck with vertical games only and flipped vertically for 1 and 2 players on the ends would make sense.
so in terms of real CRT cocktail cabinets, the games are either vertical so are displaying like so:
or are horizontal, like so:
MAME has various "cocktail mode" settings letting you run horizontal games on a traditional cocktail cab, but my understanding is that they just dupe the image like the top right image (if that even work in retropie):
the shader wouldn't work properly with that kind of setup anyway, so it's not something the script caters for.
-
@dankcushions said in Correcting scaling artifacts in lr-mame2003:
the shader wouldn't work properly with that kind of setup anyway, so it's not something the script caters for.
Ok, thanks Dank. I don't have a cocktail cabinet by no means but I was just running through different scenarios in my head. I think I prefer what your script is doing by filling the screen vertically with the AR within a tolerance. I tried integer scaling for a while but I didn't care for the black borders all the way around the game screen on some games.
-
@riverstorm said in Correcting scaling artifacts in lr-mame2003:
I might be missing it here but those are the same numbers I came up with and it all worked out correctly but I thought the goal of the script was to fill the screen vertically (Y = 0) as in how Dank is calculating which would be what you're suggesting?
So.. that hadn't been my goal from the outset.
My assumption was that since we're striving for integer horizontal scaling for vertical games in order to make the scanline effect as clear as possible, it would make sense to also try to achieve the converse - namely integer vertical scaling for horizontal games.
Maybe it doesn't make such a huge difference, though. For horizontal games, the scaling factor will be higher than for vertical games (i.e. each original game pixel is represented by a larger number of onscreen pixels), so there's more area for the shader to be applied to.
Interestingly, though, if I remove the MAME 2003 directory entirely (i.e. remove all custom configs), and run the game as normal on my bartop (1280 x 1024 display), I get black bars at the top & bottom of horizontal format games. And that's with integer scaling turned off.
Also interesting is that if I run Dank's current script for my setup (1280 x 1024), I do get bars at the top and bottom - here's bubble bobble's config file, for example;
# Auto-generated crt-pi.glslp .cfg # Game Title : bublbobl , Width : 256, Height : 224, Aspect : 4:3 # Screen Width : 1280, Screen Height : 1024 # Place in /opt/retropie/configs/all/retroarch/config/MAME 2003/ video_shader_enable = "true" video_shader = "/opt/retropie/configs/all/retroarch/shaders/crt-pi.glslp" # To avoid horizontal rainbow artefacts, use integer scaling for the height aspect_ratio_index = "22" custom_viewport_width = "1280" custom_viewport_height = "896" custom_viewport_x = "0" custom_viewport_y = "64"
It's certainly food for further thought. One idea I'd had, but didn't get around to implementing, was to have the option to run the script only for vertical aspect ratio games, and leave the default scaling for the horizontal ones.
In the meantime, I'm going to submit my .csv log file as a Pull Request shortly, since reviewing that is a whole lot easier than individual scrutiny of the .cfg files, even with the additional header data.
-
@andrewh said in Correcting scaling artifacts in lr-mame2003:
was to have the option to run the script only for vertical aspect ratio games, and leave the default scaling for the horizontal ones.
I thought of doing this like a really dirty hack of the script appending "v" to the rom name and then stripping it with a file renamer tool to get the vertical games. I suppose just processing "v" games would be more efficient and strip the "h" pieces.
Interestingly, though, if I remove the MAME 2003 directory entirely (i.e. remove all custom configs), and run the game as normal on my bartop (1280 x 1024 display), I get black bars at the top & bottom of horizontal format games. And that's with integer scaling turned off.
I guess a guy would need to dig into the MAME code to see how it determines scaling and if the resolution viewport numbers break down to roughly the same as Dank's formula. Hopefully this hasn't been for naught.
That's almost confusing due to being run on a 5:4 monitor? I thought MAME would try and fill at least one axis (mainly vertical) since HD is 16:9 or 1.78:1 it fills vertically for 99% of games. When Udb creates overlays the games fit dead center while filling the screen vertically. I believe he develops them specifically for HD filling the negative space on either side perfectly.
I have to admit I am kind of confused. The math looks good, the formulas, the screenshots show a clear difference. If it's to much to explain I'm ok with that too but I am missing the 10,000 foot overview.
I think, maybe not, get Dank's idea. Fill the screen vertically then adjust the width resolution to target the correct AR, well as close as possible? Single axis scaling.
But you're not doing that? You're only doing a partial on both axis. Taking Joust for example it neither starts on the x or y axis at 0 so what is the goal? If you want a perfect aspect ratio just use integer scaling that's built-in with one command and it's perfect on both axis. But it's like your trying to do a partial adjust on both axis?
A perfect integer scale of 4x4 = 1280 x 960 but yours is 4.5 x 4 = 1440 x 960. What is corrected in those 160 extra pixels that looks better or is it just trying to use more screen to the tune of 160 pixels sacrificing the perfect AR? I am missing it I think. The key being you're not filling either axis. Which is integer scaling with partial numbers instead of whole.
I am starting to question pixelsquareness. Does MAME already make adjustments? It seems almost every game would display incorrect on an HD monitor without factoring that in before buffering to the screen.
Take AdvMAME for example (as an exception). I have one game that I need to use this command to get a proper display
display_mode generate-double-y
. I don't know if it's an extreme case game or an exception rather than rule but the game is very flat until I double the y axis. -
@riverstorm I think Blasteroids is an example of a double-y game. If you display it in native resolution, scaled or not, it is only half as high as it should be. The game designers were expecting this to be stretched across the whole CRT.
Since most arcade games were destined for cabinets with 4:3 or (3:4 when rotated vertical) CRTs, you can just set aside the idea of square pixels for most of them and consider that some stretching will be required in at least one dimension if you want games to look like they did in the arcades. Of course, today, we are almost always dealing with square pixels, not RGB triads on a CRT, so it becomes a struggle of how to accommodate the stretch for many games so that they display in a 4:3 AR versus how much distortion we are willing to live with to make our shaders look pretty.
-
@caver01 said in Correcting scaling artifacts in lr-mame2003:
so it becomes a struggle of how to accommodate the stretch for many games so that they display in a 4:3 AR versus how much distortion we are willing to live with to make our shaders look pretty.
That makes perfect sense ok maybe a 5,000 foot overview. I tweaked what I wrote above so it might help to reread it. I will throw it out there more rhetorical but if you understand that would be great.
So what is Andrew doing with integer scaling on both axis and filling neither which is like partial integer scaling or something. Where as Dank fills one axis which makes sense to me. I am afraid it's getting more confusing for me. The Joust example is below. Neither axis starts at 0. So that being said why not just use integer scaling if you don't mind black borders or what is gained from the 160 pixels (4.5 scale on the x axis) vs. just doing a 4 x 4 integer scale. Either way you have black borders but wouldn't the perfect integer scale look more correct?
aspect_ratio_index = "22" custom_viewport_width = "1440" custom_viewport_height = "960" custom_viewport_x = "240" custom_viewport_y = "60"
-
@caver01 said in Correcting scaling artifacts in lr-mame2003:
you can just set aside the idea of square pixels for most of them and consider that some stretching will be required in at least one dimension if you want games to look like they did in the arcades
That's my point if you displayed a game exactly with 224 x 320 pixels on a modern display I am guessing it would have improper proportions due to the pixel squareness of modern displays. Most MAME games seem to look fine hence the comment questioning is MAME accounting for and adjusting pixel squareness already and it doesn't need to be part of the calculation? A bit of rabbit hole...unless you're the guy programming it.
-
@riverstorm said in Correcting scaling artifacts in lr-mame2003:
So what is Andrew doing with integer scaling on both axis and filling neither which is like partial integer scaling or something. Where as Dank fills one axis which makes sense to me. I am afraid it's getting more confusing for me. The Joust example is below. Neither axis starts at 0. So that being said why not just use integer scaling if you don't mind black borders or what is gained from the 160 pixels (4.5 scale on the x axis) vs. just doing a 4 x 4 integer scale. Either way you have black borders but wouldn't the perfect integer scale look more correct?
I'm sorry if I haven't been clear enough with explanations up to this point... I'll try again;
For the vertical games, the original goal (of Dank's script) was to have integer scaling 'across' the scanlines in order to make them look their best and avoid artefacts.
In the work I'd done, my original idea was to extend this idea to the horizontal games - i.e. to have integer scaling 'across' the scanlines (in the vertical direction), but to leave the scaling as-was in the other direction. Following further testing, I now think that this is not necessary, and I'm hoping to shortly do a Pull Request on Dank's script to implement a new variant of the "math based scaling" in place of the existing approach of iterating through an array. At a high level, the following should give the best results (i.e. do the best job of filling the screen);
- Calculate the squareness of the pixels in the original game to get a 'corrected' game size
- Calculate horizontal and vertical scaling factors between the 'corrected' game and the target screen
- Use whichever scaling factor is the lower of the two
- For vertical games
- Set the vertical scale to the calculated scaling factor - this will ensure the game fills the screen vertically
- Set the horizontal scale to either the next lower or next higher integer value (using a "widen" option)
- For horizontal games
- Set vertical and horizontal scale to the same value - this will ensure the game fills the screen in at least one direction (depending on aspect ratio of the screen)
- If there are narrow black bars in one direction (less than a specified tolerance value), then stretch the game to fill those.
One thing that should be a big help in figuring all of this out is the last Pull Request I submitted, which creates a .csv log file and allows settings for all games to be reviewed in one place.
-
@riverstorm said in Correcting scaling artifacts in lr-mame2003:
@caver01 said in Correcting scaling artifacts in lr-mame2003:
you can just set aside the idea of square pixels for most of them and consider that some stretching will be required in at least one dimension if you want games to look like they did in the arcades
That's my point if you displayed a game exactly with 224 x 320 pixels on a modern display I am guessing it would have improper proportions due to the pixel squareness of modern displays. Most MAME games seem to look fine hence the comment questioning is MAME accounting for and adjusting pixel squareness already and it doesn't need to be part of the calculation? A bit of rabbit hole...unless you're the guy programming it.
yes, mame uses the exact aspect ratio every time, because it doesn't care about integer scaling. what mame does is say, "ok, this is a 4:3 game, so I will do a 4:3 image - i will simply stretch the tiny 320x240 (say) image to the biggest 4:3 image that fits on the screen"
this is generally fine on an HD screen (it's high enough resolution for the scaling to look good, mostly)... until you come to use a scanline shader. this is the fundamental problem that i wanted to solve, and i describe it in the original post: https://retropie.org.uk/forum/topic/4046/crt-pi-shader-users-reduce-scaling-artifacts-with-these-configs-in-lr-mame2003-lr-fbalpha-lr-nestopia-and-more-to-come.
-
please continue the discussion on the original thread https://retropie.org.uk/forum/topic/4046/crt-pi-shader-users-reduce-scaling-artifacts-with-these-configs-in-lr-mame2003-lr-fbalpha-lr-nestopia-and-more-to-come
Contributions to the project are always appreciated, so if you would like to support us with a donation you can do so here.
Hosting provided by Mythic-Beasts. See the Hosting Information page for more information.