crt-pi shader users - reduce scaling artifacts with these configs in lr-mame2003, lr-fbalpha, lr-nestopia (and more to come)
-
@riverstorm said in crt-pi shader users - reduce scaling artifacts with these configs in lr-mame2003, lr-fbalpha, lr-nestopia (and more to come):
@dankcushions said in crt-pi shader users - reduce scaling artifacts with these configs in lr-mame2003, lr-fbalpha, lr-nestopia (and more to come):
i had a limited goal for the script and i reached that
That will teach them for using old school monitors and true CRTs for retro gaming! Traditional vs contemporary! :)
It's about 13% of the games that will be off, hopefully none of the major ones. I imagine Andrew has the issue so well defined he can, well has, already hacked the script and fixed the issue.
it's not CRTs - if you're using a CRT you should be using native 240p or whatever so you get natural scanlines. you don't need a shader!
~4:3 monitors, sure. there appears to be an issue there. PRs welcome!
-
@dankcushions said in crt-pi shader users - reduce scaling artifacts with these configs in lr-mame2003, lr-fbalpha, lr-nestopia (and more to come):
~4:3 monitors, sure. there appears to be an issue there.
4:3 and 4:5 monitors so far.
PRs welcome!
Just doing a quick look through the script. That looks like a full blown programming language. You wrote that whole thing yourself? I'm impressed. I think that it would take me several weeks looking up & fighting with syntax of commands let alone concepts of the script. Writing & knowing the code intimately I take it you figure the issue is harder to solve then a quick 1 or 2 line tweak.
There's a lot of programming concepts that most (non-programmers) wouldn't understand or even make sense that require some study to understand. Maybe a quick reference guide for commands & syntax might help or I guess nowadays Google handy on the left. It's slow going when first learning a language but having any programming experience sure expedites the process as the fundamentals are the same it's just knowing the syntax.
It doesn't affect me at all so I am happy how it is too! It sounds like Caver don't use the script either so it depends if Andrew feels like forking and fixing! ;)
Actually I think Andrew would get to the heart of the issue quicker if it's worth fixing and is a hacking maniac but if he needs help with anything I will do what I can. It's been a while since I did any true programming like COBOL, RPG, Fortran, BASIC and some C when I was with the public school systems & then UPS like 20 odd years ago (mostly stuff no-one uses anymore) but the script doesn't look to bad.
-
@riverstorm I looked at the script too and I think I see where the potential issue is. There is a conditional—the place where it says that we like to expand wider more than we like to be narrower. It is here that it does the tolerance comparison that @AndrewH cited above. The first problem is that it needs an additional condition—one that checks to see if the recalculated viewport width (gameWidth * (scaleX +1)) would exceed screenWidth before proceeding. That would solve the viewport cropping.
The second issue is that it simply favors any version of the AR that is wider (within tolerance, of course), even though the narrower factor might come within a few pixels of a perfect aspect ratio. It seems like the tolerance should be compared against the narrow version, not the wide one. And yet, I still think there is an element of subjectivity here. I might even be willing to add some black bars to the border (again, within a certain tolerance) if it let me avoid heavy distortion.
I think the real benefit here was that @dankcushions realized that you can eliminate shader artifacts by forcing integer scaling in one dimension only. We always knew that full integer scaling would solve both AR and shader issues, but being able to live with some distorition in one dimension to take advantage of more screen area was a fantastic insight. But as always with our build projects, one size rarely fits all.
-
@caver01 said in crt-pi shader users - reduce scaling artifacts with these configs in lr-mame2003, lr-fbalpha, lr-nestopia (and more to come):
@riverstorm I looked at the script too and I think I see where the potential issue is. There is a conditional—the place where it says that we like to expand wider more than we like to be narrower. It is here that it does the tolerance comparison that @AndrewH cited above. The first problem is that it needs an additional condition—one that checks to see if the recalculated viewport width (gameWidth * (scaleX +1)) would exceed screenWidth before proceeding. That would solve the viewport cropping.
The second issue is that it simply favors any version of the AR that is wider (within tolerance, of course), even though the narrower factor might come within a few pixels of a perfect aspect ratio. It seems like the tolerance should be compared against the narrow version, not the wide one. And yet, I still think there is an element of subjectivity here. I might even be willing to add some black bars to the border (again, within a certain tolerance) if it let me avoid heavy distortion.
I think the real benefit here was that @dankcushions realized that you can eliminate shader artifacts by forcing integer scaling in one dimension only. We always knew that full integer scaling would solve both AR and shader issues, but being able to live with some distorition in one dimension to take advantage of more screen area was a fantastic insight. But as always with our build projects, one size rarely fits all.
I agree this is an incredible insight doing single axis scaling to correct the rainbow effects. I don't mean to be to open or blunt as I tend to be.
They way I understand it after this discussion is there's a few pieces of key information. The original DAR (resolution), the aspect ratio, orientation & target DAR (resolution).
It seems the PAR can be calculated from the resolution and aspect ratio. Similar to a TV. The PAR is used to calculate a "modified" height/width that is used to fit the target DAR. Without taking the original PAR into account some games (that aren't 1:1) are going to be off visually on a modern display with square pixels.
A quick look through the script it doesn't look like the PAR isn't taken into account at all? It's calculating scaling from 1 to 99 in both dimensions and then goes through comparing all of them looking for the best aspect ratio within the tolerance. It's very well written.
The use of the key function (lambda), data structures ( aspectRatios = []), reverse method (aspectRatios.reverse()), absolute function, etc. just seems like this is an incredibly efficient and well written script I was just wondering if it was a collaboration with someone that knows a bit of programming or just natural talent.
If @AndrewH maybe shares an example or two of negative offsets I think that will help.
-
@riverstorm said in crt-pi shader users - reduce scaling artifacts with these configs in lr-mame2003, lr-fbalpha, lr-nestopia (and more to come):
If @AndrewH maybe shares an example or two of negative offsets I think that will help.
I do plan to put some more work into this, ultimately with the goal of making a proper contribution to the script. But I'm kinda learning Python as I go here.
Of the 361 games that go beyond the vertical screen area (for 1600 x 1200 screen), 346 of them are horizontal and 15 are vertical. The 15 vertical would be an easy fix, but the horizontal ones need to use the next scaling factor below what's currently being computed by Dank's method, and I'm not sure how to do that at the moment.
Here are some examples where, even with a tolerance of 0, the viewport size is set beyond the screen area;
Tolerance : 0 Name X Y Orientation Aspect1 Aspect2 ViewportWidth ViewportHeight HorizontalOffset VerticalOffset ace 336 304 H 4 3 1600 1216 0 -8 aceattac 320 224 V 4 3 1600 1280 0 -40 acedrvrw 640 480 H 4 3 1600 1440 0 -120 afighter 320 224 V 4 3 1600 1280 0 -40 airco22b 640 480 H 4 3 1600 1440 0 -120 aircombj 496 480 H 4 3 1600 1440 0 -120 aircombu 496 480 H 4 3 1600 1440 0 -120 alpinerc 640 480 H 4 3 1600 1440 0 -120 alpinerd 640 480 H 4 3 1600 1440 0 -120 amerdart 322 241 H 4 3 1600 1205 0 -2 aquarium 320 256 H 4 3 1600 1280 0 -40 aquarush 640 480 H 4 3 1600 1440 0 -120 archriv2 512 480 H 4 3 1600 1440 0 -120 archrivl 512 480 H 4 3 1600 1440 0 -120 ashnojoe 288 208 H 4 3 1600 1248 0 -24 athena 288 216 H 4 3 1600 1296 0 -48 battlera 1088 242 H 4 3 1600 1210 0 -5 bchopper 384 256 H 4 3 1600 1280 0 -40 bcrusher 240 256 H 4 3 1600 1280 0 -40 beaminv 248 216 V 4 3 1600 1240 0 -20 beastrzb 640 480 H 4 3 1600 1440 0 -120
-
@dankcushions, I've done a (fair) bit more work and created an alternative version of your script - was wondering whether you'd consider including it in your git project.
Main features;- Checks for Python 3 and exits if not found
- Creates a .csv 'log' file showing the viewport size and position created for each game (handy to check for odd values)
- Includes additional information in the header of each .cfg generated, with details of game name, original resolution, aspect ratio, and whether either of the two new options detailed below were enabled. Also includes the target screen resolution.
- Adds two new optional command line arguments which can be used individually or together;
- w - widen vertical games scaling factor by 1
- a - use only integer scaling on both axes
- It also uses the approach that I had outlined previously (calculating the scale factors directly, rather than indexing them)
I've tested it pretty extensively using the more common resolutions - both widescreen and non-, and I'm happy enough with the output and stability.
crt_pi_configs_alt.py
# creates cfg files for crt-pi # params are: # * core (eg mame2003 or fbalpha) # * screen width (eg 1920) OR curvature # * screen height (eg 1080) # * optional flags (w: widen, a: accurate) - use either or both, with no space between # widen : Increase horizontal scaling of vertical games by 1 # accurate : Use only integer scaling for both horizontal and vertical dimensions # example usage: # python crt_pi_configs_alt.py mame2003 1920 1080 # python crt_pi_configs_alt.py fbalpha 1920 1080 # python crt_pi_configs_alt.py consoles 1920 1080 # python -c "import crt_pi_configs_alt; crt_pi_configs_alt.createZip(False,1920,1080)" import sys import os import shutil def generateConfigs(arg1, arg2, arg3, arg4): console = False if "mame2003" in arg1: fileName = "resolution_db/mame2003.txt" coreName = "MAME 2003" elif "fbalpha" in arg1: fileName = "resolution_db/fbalpha.txt" coreName = "FB Alpha" elif "consoles" in arg1: fileName = "resolution_db/consoles.txt" coreName = "Console" console = True if "w" in arg4: widen = "true" print("Widening of vertical games enabled") else: widen = "false" if "a" in arg4: accurate = "true" print("Accurate scaling enabled (may lead to black borders)") else: accurate = "false" if "curvature" in arg2: curvature = True else: curvature = False screenWidth = int(arg2) screenHeight = int(arg3) screenAspectRatio = screenWidth / screenHeight resolution = str(screenWidth) + "x" + str(screenHeight) outputLogFile = open(coreName + "-" + resolution + arg4 + ".csv", "w") outputLogFile.write("Widen : ,{}\n".format(widen)) outputLogFile.write("Accurate : ,{}\n".format(accurate)) outputLogFile.write("Name,X,Y,Orientation,Aspect1,Aspect2,ViewportWidth,ViewportHeight,HorizontalOffset,VerticalOffset\n") resolutionDbFile = open(fileName, "r" ) print("opened database file {}".format(fileName)) if not curvature: print("created log file {}".format(outputLogFile.name)) # print('[', end='', flush=True) sys.stdout.write('[') sys.stdout.flush() gameCount = 0 for gameInfo in resolutionDbFile: gameCount = gameCount+1 # strip line breaks gameInfo = gameInfo.rstrip() # parse info gameInfo = gameInfo.split(",") gameName = gameInfo[0] gameOrientation = gameInfo[3] gameWidth = int(gameInfo[1]) gameHeight = int(gameInfo[2]) aspectRatio = int(gameInfo[9]) / int(gameInfo[10]) gameType = gameInfo[4] #integerWidth = int(gameInfo[7]) #integerHeight = int(gameInfo[8]) if console: coreName = gameName cfgFileName = gameName + ".cfg" # Create directory for cfgs, if it doesn"t already exist if curvature: path = "curvature" + "/" + coreName else: path = resolution + "/" + coreName if not os.path.isdir(path): os.makedirs (path) # create cfg file # print("creating {}/{}".format(path,cfgFileName)) if (gameCount%100 == 0): # print('.', end='', flush=True) sys.stdout.write('.') sys.stdout.flush() newCfgFile = open(path + "/" + cfgFileName, "w") if "V" in gameType: # Vector games shouldn"t use shaders, so clear it out newCfgFile.write("# Auto-generated vector .cfg\n") newCfgFile.write("# Place in /opt/retropie/configs/all/retroarch/config/{}/\n".format(coreName)) newCfgFile.write("video_shader_enable = \"false\"\n") else: if "V" in gameOrientation: if curvature: shader = "crt-pi-curvature-vertical.glslp" else: shader = "crt-pi-vertical.glslp" # flip vertical games gameWidth = int(gameInfo[2]) gameHeight = int(gameInfo[1]) # Calculate pixel 'squareness' and adjust gameHeight figure to make them square (keeping Width as-was to avoid scaling artifacts) pixelSquareness = ((gameWidth/gameHeight)/aspectRatio) gameHeight = int(gameHeight * pixelSquareness) elif "H" in gameOrientation: if curvature: shader = "crt-pi-curvature.glslp" else: shader = "crt-pi.glslp" # Calculate pixel 'squareness' and adjust gameWidth figure to make them square (keeping Height as-was) pixelSquareness = ((gameWidth/gameHeight)/aspectRatio) gameWidth = int(gameWidth / pixelSquareness) newCfgFile.write("# Auto-generated {} .cfg\n".format(shader)) newCfgFile.write("# Game : {} , Width : {}, Height : {}, Aspect : {}:{}, Widen : {}, Accurate : {}\n".format(gameName, gameWidth, gameHeight, int(gameInfo[9]), int(gameInfo[10]), widen, accurate)) if not curvature: newCfgFile.write("# Screen Width : {}, Screen Height : {}\n".format(screenWidth, screenHeight)) newCfgFile.write("# Place in /opt/retropie/configs/all/retroarch/config/{}/\n".format(coreName)) newCfgFile.write("video_shader_enable = \"true\"\n") newCfgFile.write("video_shader = \"/opt/retropie/configs/all/retroarch/shaders/{}\"\n".format(shader)) if not curvature: # Check scale factor in horizontal and vertical directions vScaling = screenHeight/gameHeight hScaling = screenWidth/gameWidth # Keep whichever scaling factor is smaller. Also get the integer of that scaling factor. if vScaling < hScaling: intScaleFactor = int(vScaling) scaleFactor = vScaling else: intScaleFactor = int(hScaling) scaleFactor = hScaling # For vertical format games, width multiplies by an integer scale factor, height can multiply by the actual scale factor. # For horizontal games height multiplies by the integer scale factor, and width multiplies by the actual scale factor, # but gets rounded up to the screen width if close enough. if "V" in gameOrientation: if widen == "true": viewportWidth = gameWidth * (intScaleFactor + 1) else: viewportWidth = gameWidth * intScaleFactor if accurate == "true": viewportHeight = gameHeight * intScaleFactor else: viewportHeight = screenHeight newCfgFile.write("# To avoid horizontal rainbow artefacts, use integer scaling for the width\n") else: if accurate == "true": viewportWidth = gameWidth * intScaleFactor else: viewportWidth = int(gameWidth * scaleFactor) if screenWidth - viewportWidth < 10: viewportWidth = screenWidth viewportHeight = gameHeight * intScaleFactor newCfgFile.write("# To avoid horizontal rainbow artefacts, use integer scaling for the height\n") viewportX = int((screenWidth - viewportWidth) / 2) viewportY = int((screenHeight - viewportHeight) / 2) newCfgFile.write("aspect_ratio_index = \"22\"\n") newCfgFile.write("custom_viewport_width = \"{}\"\n".format(viewportWidth)) newCfgFile.write("custom_viewport_height = \"{}\"\n".format(viewportHeight)) newCfgFile.write("custom_viewport_x = \"{}\"\n".format(viewportX)) newCfgFile.write("custom_viewport_y = \"{}\"\n".format(viewportY)) outputLogFile.write("{},{},{},{},{},{},{},{},{},{}\n".format(gameInfo[0],gameInfo[1],gameInfo[2],gameInfo[3],gameInfo[9],gameInfo[10],viewportWidth,viewportHeight,viewportX,viewportY)) newCfgFile.close() resolutionDbFile.close() if not curvature: outputLogFile.close() print("]\n") print("Done!") def createZip(curvature=False, screenWidth=0, screenHeight=0): if curvature: outputFileName = "crt-pi-curvature_configs" path = "curvature" else: resolution = str(screenWidth) + "x" + str(screenHeight) outputFileName = "crt-pi_configs_" + resolution path = resolution outputFileName = outputFileName.replace(" ", "") outputFileName = outputFileName.lower() print("Creating zipfile {}".format(outputFileName)) shutil.make_archive(outputFileName, "zip", path) # now delete config dirs print("Deleting temp directory: {}".format(path)) shutil.rmtree(path) if __name__ == "__main__": if sys.version_info[0] < 3: print ("\n\n*** This script must be run using Python 3 ***\n\n") exit() if len(sys.argv) < 5: adjust = "" else: adjust = sys.argv[4] generateConfigs(sys.argv[1], sys.argv[2], sys.argv[3], adjust)
-
@andrewh i think i fixed it now, and possibly broke other things!
-
@andrewh said in crt-pi shader users - reduce scaling artifacts with these configs in lr-mame2003, lr-fbalpha, lr-nestopia (and more to come):
@dankcushions, I've done a (fair) bit more work and created an alternative version of your script - was wondering whether you'd consider including it in your git project.
Main features;- Checks for Python 3 and exits if not found
- Creates a .csv 'log' file showing the viewport size and position created for each game (handy to check for odd values)
- Includes additional information in the header of each .cfg generated, with details of game name, original resolution, aspect ratio, and whether either of the two new options detailed below were enabled. Also includes the target screen resolution.
- Adds two new optional command line arguments which can be used individually or together;
- w - widen vertical games scaling factor by 1
- a - use only integer scaling on both axes
- It also uses the approach that I had outlined previously (calculating the scale factors directly, rather than indexing them)
I've tested it pretty extensively using the more common resolutions - both widescreen and non-, and I'm happy enough with the output and stability.
crt_pi_configs_alt.py
# creates cfg files for crt-pi # params are: # * core (eg mame2003 or fbalpha) # * screen width (eg 1920) OR curvature # * screen height (eg 1080) # * optional flags (w: widen, a: accurate) - use either or both, with no space between # widen : Increase horizontal scaling of vertical games by 1 # accurate : Use only integer scaling for both horizontal and vertical dimensions # example usage: # python crt_pi_configs_alt.py mame2003 1920 1080 # python crt_pi_configs_alt.py fbalpha 1920 1080 # python crt_pi_configs_alt.py consoles 1920 1080 # python -c "import crt_pi_configs_alt; crt_pi_configs_alt.createZip(False,1920,1080)" import sys import os import shutil def generateConfigs(arg1, arg2, arg3, arg4): console = False if "mame2003" in arg1: fileName = "resolution_db/mame2003.txt" coreName = "MAME 2003" elif "fbalpha" in arg1: fileName = "resolution_db/fbalpha.txt" coreName = "FB Alpha" elif "consoles" in arg1: fileName = "resolution_db/consoles.txt" coreName = "Console" console = True if "w" in arg4: widen = "true" print("Widening of vertical games enabled") else: widen = "false" if "a" in arg4: accurate = "true" print("Accurate scaling enabled (may lead to black borders)") else: accurate = "false" if "curvature" in arg2: curvature = True else: curvature = False screenWidth = int(arg2) screenHeight = int(arg3) screenAspectRatio = screenWidth / screenHeight resolution = str(screenWidth) + "x" + str(screenHeight) outputLogFile = open(coreName + "-" + resolution + arg4 + ".csv", "w") outputLogFile.write("Widen : ,{}\n".format(widen)) outputLogFile.write("Accurate : ,{}\n".format(accurate)) outputLogFile.write("Name,X,Y,Orientation,Aspect1,Aspect2,ViewportWidth,ViewportHeight,HorizontalOffset,VerticalOffset\n") resolutionDbFile = open(fileName, "r" ) print("opened database file {}".format(fileName)) if not curvature: print("created log file {}".format(outputLogFile.name)) # print('[', end='', flush=True) sys.stdout.write('[') sys.stdout.flush() gameCount = 0 for gameInfo in resolutionDbFile: gameCount = gameCount+1 # strip line breaks gameInfo = gameInfo.rstrip() # parse info gameInfo = gameInfo.split(",") gameName = gameInfo[0] gameOrientation = gameInfo[3] gameWidth = int(gameInfo[1]) gameHeight = int(gameInfo[2]) aspectRatio = int(gameInfo[9]) / int(gameInfo[10]) gameType = gameInfo[4] #integerWidth = int(gameInfo[7]) #integerHeight = int(gameInfo[8]) if console: coreName = gameName cfgFileName = gameName + ".cfg" # Create directory for cfgs, if it doesn"t already exist if curvature: path = "curvature" + "/" + coreName else: path = resolution + "/" + coreName if not os.path.isdir(path): os.makedirs (path) # create cfg file # print("creating {}/{}".format(path,cfgFileName)) if (gameCount%100 == 0): # print('.', end='', flush=True) sys.stdout.write('.') sys.stdout.flush() newCfgFile = open(path + "/" + cfgFileName, "w") if "V" in gameType: # Vector games shouldn"t use shaders, so clear it out newCfgFile.write("# Auto-generated vector .cfg\n") newCfgFile.write("# Place in /opt/retropie/configs/all/retroarch/config/{}/\n".format(coreName)) newCfgFile.write("video_shader_enable = \"false\"\n") else: if "V" in gameOrientation: if curvature: shader = "crt-pi-curvature-vertical.glslp" else: shader = "crt-pi-vertical.glslp" # flip vertical games gameWidth = int(gameInfo[2]) gameHeight = int(gameInfo[1]) # Calculate pixel 'squareness' and adjust gameHeight figure to make them square (keeping Width as-was to avoid scaling artifacts) pixelSquareness = ((gameWidth/gameHeight)/aspectRatio) gameHeight = int(gameHeight * pixelSquareness) elif "H" in gameOrientation: if curvature: shader = "crt-pi-curvature.glslp" else: shader = "crt-pi.glslp" # Calculate pixel 'squareness' and adjust gameWidth figure to make them square (keeping Height as-was) pixelSquareness = ((gameWidth/gameHeight)/aspectRatio) gameWidth = int(gameWidth / pixelSquareness) newCfgFile.write("# Auto-generated {} .cfg\n".format(shader)) newCfgFile.write("# Game : {} , Width : {}, Height : {}, Aspect : {}:{}, Widen : {}, Accurate : {}\n".format(gameName, gameWidth, gameHeight, int(gameInfo[9]), int(gameInfo[10]), widen, accurate)) if not curvature: newCfgFile.write("# Screen Width : {}, Screen Height : {}\n".format(screenWidth, screenHeight)) newCfgFile.write("# Place in /opt/retropie/configs/all/retroarch/config/{}/\n".format(coreName)) newCfgFile.write("video_shader_enable = \"true\"\n") newCfgFile.write("video_shader = \"/opt/retropie/configs/all/retroarch/shaders/{}\"\n".format(shader)) if not curvature: # Check scale factor in horizontal and vertical directions vScaling = screenHeight/gameHeight hScaling = screenWidth/gameWidth # Keep whichever scaling factor is smaller. Also get the integer of that scaling factor. if vScaling < hScaling: intScaleFactor = int(vScaling) scaleFactor = vScaling else: intScaleFactor = int(hScaling) scaleFactor = hScaling # For vertical format games, width multiplies by an integer scale factor, height can multiply by the actual scale factor. # For horizontal games height multiplies by the integer scale factor, and width multiplies by the actual scale factor, # but gets rounded up to the screen width if close enough. if "V" in gameOrientation: if widen == "true": viewportWidth = gameWidth * (intScaleFactor + 1) else: viewportWidth = gameWidth * intScaleFactor if accurate == "true": viewportHeight = gameHeight * intScaleFactor else: viewportHeight = screenHeight newCfgFile.write("# To avoid horizontal rainbow artefacts, use integer scaling for the width\n") else: if accurate == "true": viewportWidth = gameWidth * intScaleFactor else: viewportWidth = int(gameWidth * scaleFactor) if screenWidth - viewportWidth < 10: viewportWidth = screenWidth viewportHeight = gameHeight * intScaleFactor newCfgFile.write("# To avoid horizontal rainbow artefacts, use integer scaling for the height\n") viewportX = int((screenWidth - viewportWidth) / 2) viewportY = int((screenHeight - viewportHeight) / 2) newCfgFile.write("aspect_ratio_index = \"22\"\n") newCfgFile.write("custom_viewport_width = \"{}\"\n".format(viewportWidth)) newCfgFile.write("custom_viewport_height = \"{}\"\n".format(viewportHeight)) newCfgFile.write("custom_viewport_x = \"{}\"\n".format(viewportX)) newCfgFile.write("custom_viewport_y = \"{}\"\n".format(viewportY)) outputLogFile.write("{},{},{},{},{},{},{},{},{},{}\n".format(gameInfo[0],gameInfo[1],gameInfo[2],gameInfo[3],gameInfo[9],gameInfo[10],viewportWidth,viewportHeight,viewportX,viewportY)) newCfgFile.close() resolutionDbFile.close() if not curvature: outputLogFile.close() print("]\n") print("Done!") def createZip(curvature=False, screenWidth=0, screenHeight=0): if curvature: outputFileName = "crt-pi-curvature_configs" path = "curvature" else: resolution = str(screenWidth) + "x" + str(screenHeight) outputFileName = "crt-pi_configs_" + resolution path = resolution outputFileName = outputFileName.replace(" ", "") outputFileName = outputFileName.lower() print("Creating zipfile {}".format(outputFileName)) shutil.make_archive(outputFileName, "zip", path) # now delete config dirs print("Deleting temp directory: {}".format(path)) shutil.rmtree(path) if __name__ == "__main__": if sys.version_info[0] < 3: print ("\n\n*** This script must be run using Python 3 ***\n\n") exit() if len(sys.argv) < 5: adjust = "" else: adjust = sys.argv[4] generateConfigs(sys.argv[1], sys.argv[2], sys.argv[3], adjust)
oh, nice! unfortunately i was already fixing it myself!
as for the rest, well i'm afraid that i'm not too interested in new features - like i said, this script had a goal and i think i reached that. i don't want to maintain a bunch of extra stuff i didn't design.
i would have been happy to consider any fixes/improvements to current master if you submit via git (not here), so i can see the diffs and provide feedback, but generally each PR should be one change, not a whole re-write like this. but yeah i am not sold on new features. sorry!
-
@andrewh said in crt-pi shader users - reduce scaling artifacts with these configs in lr-mame2003, lr-fbalpha, lr-nestopia (and more to come):
I've done a (fair) bit more work and created an alternative version of your script - was wondering whether you'd consider including it in your git project.
I think considering Dank's script complete is respectful as to keep it to one task it was meant to do and it does it well. It's what I currently use.
I would definitely be interested in using/testing the script with the expanded feature set. It would also be handy & welcome to have that additional information in the config header for quick reference if troubleshooting an odd resolution, PAR or what not. Do you have a Github account? It might be worth considering a new project or at least a new thread to start out so as to not muddy up this one with an alternate script.
I don't know if it's how you explained it or it's what I learned first but I follow the logic a little easier. I think a bit part is breaking down the scaling calculations from the original & also factoring the pixelSquareness.
-
@dankcushions said in crt-pi shader users - reduce scaling artifacts with these configs in lr-mame2003, lr-fbalpha, lr-nestopia (and more to come):
as for the rest, well i'm afraid that i'm not too interested in new features - like i said, this script had a goal and i think i reached that. i don't want to maintain a bunch of extra stuff i didn't design.
No worries - it's your project after all :-)
It's been an interesting journey figuring out what the deal was with the 1600 x 1200 output, and it seems to have spurred some interest from a few other members too, which is nice.
If I do spin off a separate project, are you ok with me using the resolution_db and re-used parts of your script?@riverstorm said in crt-pi shader users - reduce scaling artifacts with these configs in lr-mame2003, lr-fbalpha, lr-nestopia (and more to come):
It might be worth considering a new project or at least a new thread to start out so as to not muddy up this one with an alternate script.
I've got a git account, but have absolutely no idea how it's all meant to work. But if I get time over the next week or two, I'll try to put something together, and rework it to be distinct enough not to cause confusion (hopefully).
-
@andrewh i wouldn't really like another project re-writing my idea, no ;)
but if you get git and do each feature/improvement as separate PRs to my repo i'm sure i can be convinced :) at least that way you can get credit for the bits you add, rather than me just copy/pasting code. let's collaborate!
git is a pain at first but there's lots of great guides out there, like http://rogerdudler.github.io/git-guide/.
-
@dankcushions alright then...
I'm not sure my scaling method can easily exist alongside yours in the same script, but I'd be happy to commit a couple of the other changes in the hope that they're useful.
Plus, if anyone really wants to give my script a go, it's in this thread..
-
@andrewh said in crt-pi shader users - reduce scaling artifacts with these configs in lr-mame2003, lr-fbalpha, lr-nestopia (and more to come):
Plus, if anyone really wants to give my script a go, it's in this thread..
I grabbed a copy at work tonight to test next week. I was hoping you didn't decide to remove the post. We are heading out of town in the morning so the wife can take a medical class in another city while I go out sight seeing.
Honestly I almost look at it as a fork. Development is complete and it was clearly stated several times no further development would be done (unless others are doing the changes through PR's).
You rewrote the code making some fundamental computational changes, added features and corrections. It also gives you a chance to further develop it exactly like you want. It's not much different then MAME or any other open source software fork. The data is freely available as it's all data the MAME team compiled through the years. MAME is open source and can be forked anyway you can imagine and has been. This is the whole point. Creative freedom.
You rewrote it because you were reminded the project scope is complete and take it like it is or make the changes yourself if you don't like it and well you did! Any changes are coming from you anyway on a completed project. It just doesn't make sense to not setup your own project now and run with it. I think you have to give yourself the opportunity.
I'm not trying to be negative but I think Andrew already implemented some nice features and I'd love to see where he goes with it. I think you would be doing yourself a disservice to not at least try.
Eventually it will boil down to maintaining two scripts your own and adding features to an existing as your reply seems to indicate. I have no idea but I would take that bet your going to maintain your own script anyway and that would be a shame to be pressured into hiding it and sending small PR changes when you really feel like developing it your own way anyway.
-
@riverstorm you're injecting yourself into this conversation and i don't appreciate it.
open source development isn't just about forking whenever you want. you can do that, of course, but it's the nuclear option. i am happy to collaborate!
i changed my mind about introducing new features - i made the comment flippantly after being overwhelmed with the waffle in this thread. this script was a simple, fun thing for me to attempt some (terrible) python, that is definitely not the last word in scaling (actually i think the last word would be introducing better options in retroarch's aspect ratio settings... that's on my list). however i can't just copy and paste a complete re-write of my code - features have to be submitted as single PRs so i can understand them and evaluate them individually. that's the same for ALL open source projects.
in that context i would be likely to accept re-writes of the old scaling algorithm and all the rest - just one at a time :)
i'm going to lock this thread for a while because there's nothing more to say - @AndrewH, please don't take this to be anything about your work which is cool and I appreciate it! i'll see you on git! i'll unlock when we have something to show.
-
@dankcusions - 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"
@AndrewH - It's not that you're not explaining yourself well it's my lack of understanding. I have little loose ends that probably aren't related but I feel it helps in understanding but also keeps me going in circles. I just need time to process the information. Let that subconscious do the work. :) I was up way to late reading. One thing drifted to another.
With that thought (Dank's comment above) it would be safe to say 100% of arcade games (due to lack of PAR calculations in upscaling) are stretched on x, y or both and we've just become accustomed or consider it correct because it's close enough for our memories?
If not integer scaling what is the MAME/Retroarch(?) process to stretch the image resolution to max 4:3 aspect ratio on modern displays (that have different resolutions)?
With integer scaling off and no custom config. How is MAME (set to defaults) filling the screen? This seems important to know what it does with no modifications. Basically what the developers decided for default settings.
I think of integer scaling as multiplying the original resolution by whole numbers (no fractions) until either the x or y exceeds the display resolution then it backs down 1 to fit the screen. Hence almost always leaving black borders all the way around the play area.
I know more pixels allow the shader to look better. Is it pixel density or an evenly divisible x scale (y on horizontal games) that is more important to looking better?
An observation is with Dank's script I didn't think he was taking pixel squareness into account and Andrew's does. What I find interesting is when using Andrews's "wide" flag both Dank's and Andrew's scripts produce the same viewport dimensions. How is that possible? (If Dank's isn't doing pixel squareness calculations). I just don't quite understand the sort array in Dank's script so maybe there's more happening there than I understand?
I was on one thread last night that was having Donkey Kong discussion that one guy said it was actually a 9:6, another guy said it was a 8:7, a 3rd guy says if you fill the screen horizontally (with h-sync?) it's 8:7 or if adjusted down a bit it's 9:6 so it can be either depending on the arcade operator settings, then a 4th guy says it's what you're used to and by changing what you're used to it can take hours to re-acclimate with the springs (elevators at higher levels) when changing the aspect ratio to something you're not used to playing on.
Others were deep into 31 to 15Khz conversions from hardware to software, display cards, etc. to get proper looking games. It kind of goes on and on.
I look forward to how the scripts turn out.
-
Just found these cfg's, thanks for posting them! I placed them in the correct directory and they work fine. I also added a line of code to specify a bezel. I was curious to see what would happen if I made any changes through the RGUI so I changed the shader to the curvature variant for the game sf2 and then did a save game override. I then opened sf2.cfg in notepad++ and noticed the code wasn't right and my line specifying the bezel was gone. Any idea why this happens? I was expecting to see the change to the curvature shader with nothing else changed.
-
@riverstorm said in crt-pi shader users - reduce scaling artifacts with these configs in lr-mame2003, lr-fbalpha, lr-nestopia (and more to come):
@dankcusions - 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"
With that thought (Dank's comment above) it would be safe to say 100% of arcade games (due to lack of PAR calculations in upscaling) are stretched on x, y or both and we've just become accustomed or consider it correct because it's close enough for our memories?
PAR isn't neccesarily correct to the original, though. DAR is correct, but to get from original game image to display via DAR, you have to stretch.
if you run our example 320x224 image on a 1080p display, by default it will be 1440x1080 (4:3). 320 isn't an integer factor of 1440, nor is 224 an integer factor of 1080, so if you zoomed in you would see that (for example) the grid of 320x224 pixels from the original game are blurred slightly during the scaling process. you don't get clean edges. however, the aspect ratio of the image will be correct (4:3).
the blurring ("scaling artefacts") aren't usually a problem on a HD screen viewed at distance, but they are a problem if you use a scanline shader.
that's what the script tries to solve - it compromises on aspect ratio but reduces scaling artefacts. if you want to have a precise aspect ratio, don't use these .cfgs. don't do anything!
If not integer scaling what is the MAME/Retroarch(?) process to stretch the image resolution to max 4:3 aspect ratio on modern displays (that have different resolutions)?
it's bilinear, i believe.
I think of integer scaling as multiplying the original resolution by whole numbers (no fractions) until either the x or y exceeds the display resolution then it backs down 1 to fit the screen. Hence almost always leaving black borders all the way around the play area.
actually retroarch doesn't quite do it like that. it is mindful of the intended aspect ratio, so it will scale by whole numbers to get at close to the target aspect ratio as possible. so it might end up with something like X axis * 5, Y axis * 4, or whatever.
I know more pixels allow the shader to look better. Is it pixel density or an evenly divisible x scale (y on horizontal games) that is more important to looking better?
well, ideally you'd have an evenly divisible scale, but since retro gaming has so many different resolutions, that's impossible for one digital display. however, once you start going into 4k, then the pixels are so small that the artefacts are essentially invisible.
An observation is with Dank's script I didn't think he was taking pixel squareness into account and Andrew's does.
i do take it into account. it's just a different approach.
I was on one thread last night that was having Donkey Kong discussion that one guy said it was actually a 9:6, another guy said it was a 8:7, a 3rd guy says if you fill the screen horizontally (with h-sync?) it's 8:7 or if adjusted down a bit it's 9:6 so it can be either depending on the arcade operator settings, then a 4th guy says it's what you're used to and by changing what you're used to it can take hours to re-acclimate with the springs (elevators at higher levels) when changing the aspect ratio to something you're not used to playing on.
Others were deep into 31 to 15Khz conversions from hardware to software, display cards, etc. to get proper looking games. It kind of goes on and on.
i defer to what mame use in their drivers, here.
-
@yardley said in crt-pi shader users - reduce scaling artifacts with these configs in lr-mame2003, lr-fbalpha, lr-nestopia (and more to come):
Just found these cfg's, thanks for posting them! I placed them in the correct directory and they work fine. I also added a line of code to specify a bezel. I was curious to see what would happen if I made any changes through the RGUI so I changed the shader to the curvature variant for the game sf2 and then did a save game override. I then opened sf2.cfg in notepad++ and noticed the code wasn't right and my line specifying the bezel was gone. Any idea why this happens? I was expecting to see the change to the curvature shader with nothing else changed.
i already created curvature cfgs in the original post, so i would just use those as a base :) retroarch does strange things with regard to saving overrides, so i can't really guess the problem here.
-
@dankcushions said in crt-pi shader users - reduce scaling artifacts with these configs in lr-mame2003, lr-fbalpha, lr-nestopia (and more to come):
PAR isn't neccesarily correct to the original, though. DAR is correct, but to get from original game image to display via DAR, you have to stretch.
I am not sure I am explaining myself correctly but this seems not quite what I was trying to say. If you have a 3:4 ratio and a resolution of 224 x 298 and another game that is a ratio of 3:4 and a resolution of 253 x 310. I thought the difference is the PAR not the DAR. They are both 3:4 DAR but the pixel width vs. height is what not the same between the two games.
The thought is most arcades games do not use square pixels. So when you display the original game on a modern display and force it to use square pixels it would be squished or stretched due forcing the pixels to be square.
it's bilinear, i believe.
I thought bilinear is a smoothing technique not scaling.
actually retroarch doesn't quite do it like that. it is mindful of the intended aspect ratio, so it will scale by whole numbers to get at close to the target aspect ratio as possible. so it might end up with something like X axis * 5, Y axis * 4, or whatever.
So integer scaling is per axis? If you have (x * 5 ) & (y * 4) wouldn't you destroy you 3:4 aspect ratio? I thought both axis where scaled by the same number and it has to be whole numbers or you will create an uneven stretch in pixel dimensions. To me doing it like that would be completely opposite of what it's trying to achieve?
i do take it into account. it's just a different approach.
Can you explain that a little more?
-
@riverstorm said in crt-pi shader users - reduce scaling artifacts with these configs in lr-mame2003, lr-fbalpha, lr-nestopia (and more to come):
@dankcushions said in crt-pi shader users - reduce scaling artifacts with these configs in lr-mame2003, lr-fbalpha, lr-nestopia (and more to come):
PAR isn't neccesarily correct to the original, though. DAR is correct, but to get from original game image to display via DAR, you have to stretch.
I am not sure I am explaining myself correctly but this seems not quite what I was trying to say. If you have a 3:4 ratio and a resolution of 224 x 298 and another game that is a ratio of 3:4 and a resolution of 253 x 310. I thought the difference is the PAR not the DAR. They are both 3:4 DAR but the pixel width vs. height is what not the same between the two games.
The thought is most arcades games do not use square pixels. So when you display the original game on a modern display and force it to use square pixels it would be squished or stretched due forcing the pixels to be square.
it’s stretched either way. either you’re stretching the raw image from its PAR (“square pixels”) to DAR (the correct aspect ratio), or you’re stretching away from the DAR to make your pixels square (PAR)
mame is DAR by default. the aspect ratio is right, but to get there it gets scaling artefacts.
it's bilinear, i believe.
I thought bilinear is a smoothing technique not scaling.
they’re the same thing. if you can’t apply an integer scale and still hit 4:3 with no (top and bottom) borders, then you have to use a scaling algorithm. bilinear or nearest neighbour are most common. even integer scaling is a scaling algorithm, i suppose - just a very ‘brute force’ one.
actually retroarch doesn't quite do it like that. it is mindful of the intended aspect ratio, so it will scale by whole numbers to get at close to the target aspect ratio as possible. so it might end up with something like X axis * 5, Y axis * 4, or whatever.
So integer scaling is per axis? If you have (x * 5 ) & (y * 4) wouldn't you destroy you 3:4 aspect ratio?
that depends on the raw image. street fighter 2 is a great example of this. if you scaled both axis by the same number, it will be the wrong aspect ratio (fat ryu).
I thought both axis where scaled by the same number and it has to be whole numbers or you will create an uneven stretch in pixel dimensions. To me doing it like that would be completely opposite of what it's trying to achieve?
not at all. again the raw pixel image does not have a direct connection to the aspect ratio on the CRT. CRTs don’t need square pixels. if you integer scale up from the raw pixel image you will often be off from the proper aspect ratio.
i do take it into account. it's just a different approach.
Can you explain that a little more?
it’s just fundamental. you must know the difference between your DAR and PAR to generate the CFGs
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.