Main > Software Forum
[Discontinued][17-09-22] RatRefresh - refresh rate switcher, stops LCD tearing
Rataplan626:
[Discontinued]
There have been issues for people using this with AMD or nVidia GPU's. It seems specific API calls are needed to do the trick. I don't have any AMD or nVidia GPU's anymore so I can't work on that anymore for now. For Intel iGPU's it works fine though, and it runs fine on my cabs. Also, since it's only been downloaded about 20 times in total, it has not found the 'success' I anticipated for it. If there still are issues on Intel iGPU's and RatRefresh, feel free to ask question. Apart from that, consider this tool discontinued.
Hi. I've been looking for a tool to automatically change refreshrates on my LCD corresponding the game I start. More like CRU does, but then automated for use with MAME and other emulators. I was unable to find something like that. So I wrote it myself.
I short: you can run 'RatRefresh.exe -file refreshrates.txt -get bublbobl;mame' to switch to the exact refresh rate for that game. Or you can use 'RatRefresh.exe -refresh 59.150' to switch to that refreshrate.
A little backstory
A few years ago I've build me an arcade-cabinet with a LCD screen. We all know that gives issues with refreshrates and tearing. (And I don't want to debate that - I know CRT is better for the true arcade experience). We also know we can use CRU or actually EDID overrides to setup custom refreshrates to solve that. But that's quite cumbersome if you need to switch refreshrates between games. Also until not too long ago you would need specific hardware for that, as only ATI and NVidia seem to support EDID override. But since 2017-ish Intel supports it too. The next step was to automate this, so when I select a game, the resolution automatically switches. For that exact reason I wrote:
RatRefresh
RatRefresh is a simple tool that updates the custom EDID information of the first custom resolution to match a given refreshrate. It's mainly intended to switch your display refreshrate to exactly match the MAME game you will play. It's quite universal, with both manual command line and input from a file with games/refreshrates in it. You could put anything you want in the inputfile with a specific refreshrate, and it can be picked up. So if you want to automate this to run your mediaplayer at 59.94Hz, you can.
Requirements
* .NET Framework 4.7.1 or higher (already installed on a default Windows 10 setup)
* Hardware that supports EDID override
* Windows Vista or higher, but only tested on Windows 10 (XP does not support EDID override)
* Admin permissions (more on that below)
Usage
* Unzip the RatRefresh zipfile to a folder on your system
* Run RatRefresh.exe -setup to have it detect your monitors and show some info. It will then ask you to select the monitor you want to change rereshrate for (some people might have more than one screen attached). This will create the needed edid.txt file, which simply contains the registry path to your monitor.
Basic setup is done now. You can now run RatRefresh as follows:
RatRefresh.exe -refresh 59.150
This will set the refresh rate of the display setup in edid.txt to 59.150. After it does that it will restart the displaydriver, more on that below.
You can supply -min or -max parameters to supply your monitors minimum and maximum supported refreshrates. If you don't supply them, the values provided by EDID are used. However, these are usually very restrictive. Your screen might report rates from 49 to 61 for example while it might be able to do 45 to 65. To find the limits, it'll be trial and error. You could try 'RatRefresh.exe -min 20 -max 100 -refresh 61.000', if that works try 'RatRefresh -min 20 -max 100 -refresh 62.000'. If that fails you'll probably have a black screen., Press up to get your previous command back, press backspace 5 times, and type 1.500 to get the command 'RatRefresh -min 20 -max 100 -refresh 61.500'. Test values until you find your monitors limit. Use those values with -min and -max in your command lines. It's not expected you kill anything, as every monitor has some detection of specs and most will even show an 'out of range' message when you go to high or low.
-norestart will prevent the videodriver to be restarted, but the custom EDID value will still be set.
-showmonitors will show you the detected monitors information
-debug (must be put as first parameter) will show additional information and wait for keypressess before quitting
Automate for MAME
As for now I merely run MAME on my cab, I wanted to automate that. MAME's XML file contains the refreshrates for all machines it supports. However parsing the almost 200MB and growing XML file takes quite a while, even on beefy PC's (using .NET libraries that is). So I wrote a little, not so smart mame.xml parser of my own, which generates a file containing a line for each game with it's refresh rate.
MameXMLParser.exe
MameXMLParser.exe takes a MAME xml file as input and outputs a plain textfile with the following structure:
<rom name>;mame;<refreshrate>
one rom per line. So you'll end up with a file with as many lines as MAME supports individual machines.
Usage:
* First create a MAME xml file by running 'MAME.exe -listxml > mame.xml'. If you run 64bit MAME it will be 'MAME64.exe -listxml > mame.xml'. If you use any other MAME distribution use it's executable name, I think all support the -listXML option.
* Find out your displays native default refreshrate. Not all MAME machines have a refreshrate set in MAME.XML, for example mechanicals. When no match is found your screen will still need a certain refreshrate :) Usually this is 60.000 or 75.000 but you can use whatever you want if your monitor supports it.
* Then run 'MameXMLParser.exe -input mame.xml -output refreshrates.txt -default 60.000'
This will generate rereshratex.txt with all needed info for MAME.
* Now you can use RatRefresh with this generated refreshrates.txt file:
RatRefresh.exe -file refreshrates.txt -get bublbobl;mame
This will search for the string 'bublbobl;mame' in 'refreshrates.txt' and set the corresponding refreshrate.
You could easily add roms for another emulator to this file with whatever name you want to call it, like
nes;nes;60.000
palgenesis;palgenesis;50.000
And then from your frontend call a batch file and run RatRefresh.exe -file refreshrates.txt -get nes;nes
or RatRefresh.exe -file refreshrates.txt -get palgenesis;palgenesis and so on.
When used together with a frontend, restarting the displaydriver will most likely crash the frontend, as it simply looses it's drawing port. So what I do is start a batchfile, which kills the frontend, runs RatRefresh, starts MAME and after that restart the frontend again. Attractmode luckily saves the last played game as soon as you select, so when I restart it, it comes back exactly where I left. My batch file content:
run-mame.bat
--- Code: ---@echo off
taskkill /im attract.exe
pushd "D:\Emulator\RatArcade_\RatRefresh"
RatRefresh -file refreshrates.txt -min 49 -max 62.4 -get %1;mame
IF NOT ERRORLEVEL 1 timeout 3
pushd d:\emulator\mame
mame %1
:: Everything below will run only when Mame has quit.
pushd "D:\Emulator\RatArcade_\AttractMode"
attract.exe
--- End code ---
Issues
* Frontends: huge issue for me personally: When an EDID resolution is added, it's only picked up when the displaybus is reset. This means restarting the displaydriver works, physically switching the display off and on works, and removing the cable and reconnecting it works. For now I can only do the first one, restarting the videodriver.
The issue with this is though that usually your frontend will crash. This makes sense as it looses its screen completely when running. However when switching the monitor off and on again or pluging the cable, the new refreshrate is picked up too. So I am still looking for a way to simulate that instead of restarting the whole videodriver.
Any suggestions to solving this are welcome!
* Admin permissions required. As the EDID value is stored in HKLM registry, you will need admin rights to modify them. This could be prevented by granting users write permissions to the EDID_OVERRIDE key. However, after that restarting the display driver requires admin permissions as well.
* I haven't done any testing at all on x86 machines, as I simply don't have x86 running anymore. Feel free to report!
Version history
v0.1
- initial release
v0.11 download (note it's usage is quite different from newer versions, please switch to newer version if you can)
- fixed: bug in calculating horizonatal blanking pixels - thanks to xxDaViDxx for reporting!
- Also switched back from using CRU's Restart64.exe to devcon64.exe, to be less dependant of CRU.
v0.12 download
- Build to .NET 4.7.2 target
- Added automatic refreshrate multipliers and deviders. If a game runs at 30Hz which your monitor can't display, it tries if *2, *3 or *4 is in range of your monitor. So in this case 60Hz would be chosen which still should leave you without tearing.
- Same the other way around, if a game runs at 120Hz, which your monitor doesn't support, it will be set to 60Hz.
- Removed devcon64.exe dependency.
- Added setup mode, no manual fiddling around with CRU anymore.
- Added showdisplays command
- Added API and WMI calls, and better interpretation of EDID values to get reported min and max frequencies for example.
- Removed the -edidfile parameter. Tool will use the edid.txt file in the same directory as the tool.
- Added elevated permissions check
v0.13 download
- Moved back to devcon again, as pnputil seems to have different version in different Windows releases. Not all support the restart-device switch.
v0.14 download
- Added -remove parameter to delete the EDID_OVERRIDE key
I this tool is useful for you, or you have questions or bugreports, feel free to respond. If you test it, please respond if it works for you. If something like this already exists and I am making a fuss out of nothing feel free to respond as well :) Happy gaming! :cheers:
Rataplan626:
reserved
buttersoft:
Wow, that's amazing. It's going to take me a while to think of everything i can do with this, but I can think of a few emulator uses already. Thank you!
xxDaViDxx:
First of all, thanks for the utility. I have something similar but with a batch file and reg files. I also use devcon.exe instead of restart64.exe
devcon.exe disable =display
timeout /t 1 /nobreak >nul
devcon.exe enable =display
You could give devcon a try, maybe it solves your problem with your frontend.
Also, I am experiencing some problems with my display and your tool. It seems that the hex introduced in the EDID is not the proper one, since it doesn't set the desired refresh rate. I have recorded a video showing the problem: https://www.screencast.com/t/BZdQGVAIRYG
Thanks again and regards,
David
Rataplan626:
--- Quote from: xxDaViDxx on January 23, 2017, 06:54:22 am ---First of all, thanks for the utility. I have something similar but with a batch file and reg files. I also use devcon.exe instead of restart64.exe
devcon.exe disable =display
timeout /t 1 /nobreak >nul
devcon.exe enable =display
You could give devcon a try, maybe it solves your problem with your frontend.
Also, I am experiencing some problems with my display and your tool. It seems that the hex introduced in the EDID is not the proper one, since it doesn't set the desired refresh rate. I have recorded a video showing the problem: https://www.screencast.com/t/BZdQGVAIRYG
Thanks again and regards,
David
--- End quote ---
Hi,
thanks for testing and reporting. And sorry for not replying erlier, it seems I don't get any notifications from this forum even if I have switched that on for specific threads. Will look into that.
About your issue, what I see is that the calculation / translation of the horizontal blanking pixels is wrong. The tool replies 4120 banking pixels, resulting is a (pseudo) resolution of 6040 x 1125. I think I know where that comes from, but if you can you can paste the edid value generated by CRU at 1920x1080 @ 60Hz with a pixelclock of 148.50, as you initially do in your screenshot, so I can verify that and make a fix.
About devcon, I have actually used that initially, but in the end that does the same. It disables the videodriver completely which I guess makes DirectX or GDI lose its marbels which makes sense. I just tried Restart64.exe hoping it might be 'smarter', but functionally that's exactly the same as devcon does. As it didn't make a difference I kept Restart64 in until I have a definitive fix. I've had a lot of reading about this. When I disconnect the DVI cable (or the monitors power cable, not just use its power button) the link re-initiates. The frontend then keeps running. That turns out to be a videodriver affair though, and not something in Windows functionality. That would mean that even if I was able to call the specific method from the videodriver, that could break with every videodriver update and also it would be specific to at least each videocard manufacturer, maybe even between models.
So for my own setup I am currently taking it a bit further. I ordered a DVI connector breakout box. When that is in I will just connect it completely through except pin 16 (out of my head) which I believe could make the system believe the cable is actually disconnected. If not I'll have to findout which wires do. I will then connect them through a USB controller relay, allowing me do 'disconnect and reconnect the DVI cable' progammatically. It's a bit of a hassle, but when I do that manually at least everything keeps running, and also it is a LOT faster to switch to the correct resolution as with disabling en enabling the driver again.
But I would love to be proven that there is a generic method to trigger this without hardware mods! Thank you so much for thinking with me.
Also I like your scripting style - it's how I would do it :) Use a command (net.exe in this example) to find out if you have admin permissions :) I like that creative scripting. :applaud:
Navigation
[0] Message Index
[#] Next page
Go to full version