Main Restorations Software Audio/Jukebox/MP3 Everything Else Buy/Sell/Trade
Project Announcements Monitor/Video GroovyMAME Merit/JVL Touchscreen Meet Up Retail Vendors
Driving & Racing Woodworking Software Support Forums Consoles Project Arcade Reviews
Automated Projects Artwork Frontend Support Forums Pinball Forum Discussion Old Boards
Raspberry Pi & Dev Board controls.dat Linux Miscellaneous Arcade Wiki Discussion Old Archives
Lightguns Arcade1Up --- Bug Reports --- Site News

Unread posts | New Replies | Recent posts | Rules | Chatroom | Wiki | File Repository | RSS | Submit news

  

Author Topic: [17-09-22] RatRefresh 0.14 - refresh rate switcher, stops LCD tearing  (Read 34763 times)

0 Members and 1 Guest are viewing this topic.

Rataplan626

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 60
  • Last login:Yesterday at 01:36:22 pm
  • I want to build my own arcade controls!
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: [Select]
@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




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:
« Last Edit: September 17, 2022, 05:27:48 am by Rataplan626 »

Rataplan626

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 60
  • Last login:Yesterday at 01:36:22 pm
  • I want to build my own arcade controls!
Re: RatRefresh - play your games on their native refresh rate on LCD
« Reply #1 on: January 10, 2017, 10:16:15 am »
reserved

buttersoft

  • Trade Count: (+1)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 1601
  • Last login:Today at 12:48:43 am
  • Is running at 15kHz
Re: RatRefresh - Automated EDID updater for MAME and others
« Reply #2 on: January 11, 2017, 06:48:14 am »
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

  • Trade Count: (0)
  • Jr. Member
  • **
  • Offline Offline
  • Posts: 3
  • Last login:February 21, 2021, 02:07:49 pm
  • I want to build my own arcade controls!
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

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 60
  • Last login:Yesterday at 01:36:22 pm
  • I want to build my own arcade controls!
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

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:

matsadona

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 760
  • Last login:February 03, 2022, 12:14:31 pm
This is indeed interesting. I need to read more carefully when I'm back home.
Building, collecting and playing arcade machines :)

xxDaViDxx

  • Trade Count: (0)
  • Jr. Member
  • **
  • Offline Offline
  • Posts: 3
  • Last login:February 21, 2021, 02:07:49 pm
  • I want to build my own arcade controls!
Hi Rataplan626, thanks for look at this.

I paste the requested value:

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\DISPLAY\DEL4073\4&1de3fe18&0&UID200195\Device Parameters\EDID_OVERRIDE]
"0"=hex:00,ff,ff,ff,ff,ff,ff,00,10,ac,73,40,00,00,00,00,09,16,01,04,a5,33,1d,\
  78,3a,6e,a5,a3,54,4f,9f,26,11,50,54,25,4b,00,71,4f,81,80,d1,c0,01,01,01,01,\
  01,01,01,01,01,01,02,3a,80,18,71,38,2d,40,58,2c,45,00,e0,0e,11,00,00,1e,00,\
  00,00,fc,00,44,45,4c,4c,20,55,32,33,31,32,48,4d,0a,00,00,00,10,00,00,00,00,\
  00,00,00,00,00,00,00,00,00,00,00,00,00,10,00,00,00,00,00,00,00,00,00,00,00,\
  00,00,00,01,43
"CRU_Name"=hex:01,44,45,4c,4c,20,55,32,33,31,32,48,4d
"CRU_Serial_Number"=hex:00,35,39,44,4a,50,32,32,53,42,44,30,4c
"CRU_Range_Limits"=hex:00,00,38,00,4c,00,1e,00,53,00,aa
"1"=hex:02,03,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,\
  00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,\
  00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,\
  00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,\
  00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,\
  00,00,00,00,fb

Rataplan626

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 60
  • Last login:Yesterday at 01:36:22 pm
  • I want to build my own arcade controls!
Hi Rataplan626, thanks for look at this.

I paste the requested value:

<registry>

Try version 0.11 from https://goo.gl/TY1irh. The error was in the calculation of the horizontal blanking pixels. One specific byte of the EDID contains values for both the horizontal blanking pixels and the actual horizontal resolution. Bits 74   are the 4 most significant bits of the horizontal active pixels, bits 30 are the 4 most significant bits for the horizontal blanking pixels. I just copied the code for the active pixels to the blanking pixels calculation but that's not correct; as for the active resolution I have to mask bit 3-0 and then reverse the value. But for the blanking I have to mask 7-4 and NOT reverse. I reversed them which is wrong. In my case though, both systems I've tested on had 00 in that whole byte so it didn't trigger the bug there :)

Also I've switched back to devconx64 now, which I have included. That might be just a bit more 'clean' than relying on CRU. Please let me know if this works for you now.

headkaze

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 2943
  • Last login:April 24, 2022, 02:38:27 pm
  • 0x2b|~0x2b?
Just some ideas on improving the automation process a bit to save your users playing around with the registry.

I found this post on how to retrieve the EDID data for a monitor.

Also you could use System.IO.Process to launch the MAME exe with the -listxml parameter and redirect its output to capture it. Then you can just have a textbox and button for the user to browse to the MAME exe's path.
« Last Edit: February 02, 2017, 07:02:12 am by headkaze »

Rataplan626

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 60
  • Last login:Yesterday at 01:36:22 pm
  • I want to build my own arcade controls!
Just some ideas on improving the automation process a bit to save your users playing around with the registry.

I found this post on how to retrieve the EDID data for a monitor.

Also you could use System.IO.Process to launch the MAME exe with the -listxml parameter and redirect its output to capture it. Then you can just have a textbox and button for the user to browse to the MAME exe's path.

I will look into that at some point. So far I've had 4 (count 'em  ;)) downloads, so the interest is a bit less than I had anticipated honestly. Still for the people that do use it, I'd like to give them the best possible experience. About the GUI thing, you are talking about the MameXMLParser.exe here? I could sure do a GUI there (although personally I like the commandline stuff more). Finding out where the EDID data is is indeed not too hard, until more than one screen is attached. What's the screen your emulator will run on / refreshrate needs to be changed for? That's hard to tell. Still, if people want that I'll get it in.
For me the main issue now is getting the new resolution / refreshrate picked up without restarting the videodriver as that breaks at least everything DirectX has open.

headkaze

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 2943
  • Last login:April 24, 2022, 02:38:27 pm
  • 0x2b|~0x2b?
For me the main issue now is getting the new resolution / refreshrate picked up without restarting the videodriver as that breaks at least everything DirectX has open.

If you add a custom resolution with the new refresh rate via the Intel Graphics Control Panel can you change the resolution without restarting the driver?


xxDaViDxx

  • Trade Count: (0)
  • Jr. Member
  • **
  • Offline Offline
  • Posts: 3
  • Last login:February 21, 2021, 02:07:49 pm
  • I want to build my own arcade controls!
Thanks Rataplan626, 0.11 works like a charm! You have saved me to buy a G-Sync monitor for my arcade cabinet.

Don't get disappointed about the little welcome the app has had. There are several people asking for a command line CRU, and as they start googling about that, they will reach this post in the same way I did.

With a feature to get the displays ( something like the -listmonitors of http://12noon.com/?page_id=80 ) just to be able to pass the name or id substring as a parameter instead of going through CRU and then regedit, it would be great.
Also, if the new refresh rate is the same than the defined one, don't make the driver refresh.

Thanks once more time.
« Last Edit: February 03, 2017, 09:42:40 am by xxDaViDxx »

Rataplan626

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 60
  • Last login:Yesterday at 01:36:22 pm
  • I want to build my own arcade controls!
Quote
Also, if the new refresh rate is the same than the defined one, don't make the driver refresh.

That's already how it should work. If the wanted refresh rate is the same as the actual, it just quits. If not, please report :) Also I will definitely look into making it easier to use, by implementing  some way to easily detect your monitor / display. Thanks for the suggestion.

Sidenote: If you are into a even better, more lag-free experience, update to mame 0.182. It now has a portaudio driver which brings down the audio latency even more. Enable it in your mame.ini with
sound                     portaudio
audio_latency             1

« Last Edit: February 06, 2017, 02:55:33 am by Rataplan626 »

Rataplan626

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 60
  • Last login:Yesterday at 01:36:22 pm
  • I want to build my own arcade controls!
Quote
If you add a custom resolution with the new refresh rate via the Intel Graphics Control Panel can you change the resolution without restarting the driver?

Hi headkaze, thanks for thinking along! Yes, both Intels own custom resolution creator and NVidia's make the new resolutions available without a reboot. On both the screen goes blank for a few seconds though, so somehow they trigger a 'resync' or restart or something like that as well I guess. They do not restart the whole display driver though. However, I have tried to find out, using process monitor, if they call a specific api or function or something, but I was unable to find that. Unfortunately I'm not enough of a reverse-engineer for this. If anyone has the ability to find that out, or point me to the tools to find that out, it would be of great help! I am a bit afraid though that this is vendor-specific and built into the driver, rather than it's a Windows function. That would mean I'd have to implement it for each individual videocard-brand / driver branch (which aren't too many anymore) but also that it can potentially break with each driver release. Also I think if it was 'that easy' CRU wouldn't need a reboot / driver restart either :)

This weekend I build a DVI extension cable, by cutting a DVI cable in two, and connecting the wires to the corresponing terminators on a DVI breakout connector. I can't get an image though, not even on the lowest possible resolution. That means either I've done something wrong, or the interference of the 4-5 centimeters without shielding is already too much. Bummer, as I wanted to fix this issue mechanically in my cab until I have a better solution.
« Last Edit: February 06, 2017, 07:58:40 am by Rataplan626 »

headkaze

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 2943
  • Last login:April 24, 2022, 02:38:27 pm
  • 0x2b|~0x2b?
My guess is the Intel Graphics Control Panel adds the resolution to the registry and then it becomes available to the usual Win32 API's that enumerate available screen resolutions. ie. EnumDisplaySettings to get the available resolutions and ChangeDisplaySettings to set the resolution/refresh rate.

It's not vendor specific because I recently released an updated Resolution Changer utility and as soon as you add a custom resolution in Intel Graphics Control Panel it becomes available to the utility to set the new resolution.

So if you find out what keys it writes to (using Process Monitor should do it) then my guess is you could change the refresh rate without restarting the driver.
« Last Edit: February 07, 2017, 07:57:31 am by headkaze »

Howard_Casto

  • Idiot Police
  • Trade Count: (+1)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 19388
  • Last login:Yesterday at 09:49:28 pm
  • Your Post's Soul is MINE!!! .......Again??
    • The Dragon King
What he said.  Resolution stuff has been intrinsically linked with the registry, for whatever reason, since win 9x days.  Like the serial port it will never die.  ;)

Lots of utilities like powerstrip just edit the registry. 

Rataplan626

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 60
  • Last login:Yesterday at 01:36:22 pm
  • I want to build my own arcade controls!
I know it's all stored in registry. I've looked quite a bit into this stuff, and I believe its not THAT easy  :)
At first, I think there is a difference between custom resolutions saved by at least Intel vs a regular EDID override. EDID overrides go into HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\DISPLAY\DEL4073\4&1de3fe18&0&UID200195\Device Parameters\EDID_OVERRIDE\0, of course substituted to your own hardware GUIDs. The (buggy) Custom Resolutions panel that's in the Intel driver panel, writes values to another place. That writes to HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Video\{02DB5D2E-E25D-4F8D-98FC-B83D51AFABBA}\0000\C_MODES_DFP_fb. That's been in there for ages, but that's NOT a 'proper' EDID override. Now I don't care where the registry goes as long as I can introduce my custom refresh rates. The proper universal EDID override support though is what Intel is including in their drivers right now, after years and years of lobbying.

Now I don't care where I have to write for this to work, so I've tested with the Intel panel as well. When I save the registry of a custom resolution added by Intel, then remove that resolution through the Intel panel, and then import the registry again, that resolution does NOT come available until I manually restart the videodriver. Also when just adding the registry, the Intel control panel does not show that custom resolution, again until I restart the driver. Even when I change resolution to for example 800x600 or another default available resolution, after that switch the custom resolution still isn't available.

When I add a custom resolution through Intel's panel or Nvidia's panel, when I click OK the screen goes blank for a few seconds. That makes me think they both restart or resync some stuff from within the driver, rather than restarting the whole driver. But anyway AFTER that screen blanking the resolution IS available. But the crux is that we do not want to use the vendors control panel :)


My guess is the Intel Graphics Control Panel adds the resolution to the registry and then it becomes available to the usual Win32 API's that enumerate available screen resolutions. ie. EnumDisplaySettings to get the available resolutions and ChangeDisplaySettings to set the resolution/refresh rate.

It's not vendor specific because I recently released an updated Resolution Changer utility and as soon as you add a custom resolution in Intel Graphics Control Panel it becomes available to the utility to set the new resolution.

So if you find out what keys it writes to (using Process Monitor should do it) then my guess is you could change the refresh rate without restarting the driver.

True, when I use the Intel control panel to add a resolution I have no issues switching to that either. But I invite you to test your tool by only changing the registry and then see if your tool picks it up. If yes, then we are onto something cool :)

I've tried several tools to capture API calls to see what happens even beyond procmon but so far I've not been able to get that.


Like the serial port it will never die.  ;)

Hehe indeed. I've bought a few new Brocade fibrechannel switches last year for my company, and I still need my good 'ol laptop or a USB-Serial converter in order to set them up :)
« Last Edit: February 08, 2017, 05:56:00 am by Rataplan626 »

headkaze

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 2943
  • Last login:April 24, 2022, 02:38:27 pm
  • 0x2b|~0x2b?
Check out this post. Apparently you can set any resolution using ChangeDisplaySettingsEx.

Rataplan626

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 60
  • Last login:Yesterday at 01:36:22 pm
  • I want to build my own arcade controls!
Check out this post. Apparently you can set any resolution using ChangeDisplaySettingsEx.

I know, but again, only resolutions known to the system. I am currently looking into http://stackoverflow.com/questions/26169268/disconnect-and-reconnect-displays-programmatically which seems to be more what I need. With a fellow who actually is a programmer (I'm certainly not) I've looked into hooking API's yesterday, but we were unable to fetch something interesting except of hundreds of EnumDisplayDevices calls.

Still working on it :)

headkaze

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 2943
  • Last login:April 24, 2022, 02:38:27 pm
  • 0x2b|~0x2b?
I think you should look at this post again. You can set a custom resolution using ChangeDisplaySettingsEx. Try it with CDS_ENABLE_UNSAFE_MODES, CDS_UPDATEREGISTRY and perhaps CDS_GLOBAL.

BTW Before I found this Win32 API function I had a look at the source for Intel HD Graphics Control Panel (it's written in .NET 4.0) in .NET Reflector. It basically calls a method in igfxDHLib.dll called set_AddCustomMode. So I basically extracted the code necessary to add a custom mode, added a reference to igfxDHLib.dll and created a little command line tool for adding a resolution. It works :)

But... I really think ChangeDisplaySettingsEx will do what you want. So if you give it a try and you can't get any joy I will post my "IntelAddCustomMode" tool. Additionally if it works then you wont need to find another solution for nVidia and ATI cards.

Rataplan626

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 60
  • Last login:Yesterday at 01:36:22 pm
  • I want to build my own arcade controls!
You clearly took it a bit further already than I did :) I hadn't though about decompiling the intel software. Nor have I even done such thing before. But you only know what you can achieve after you've tried :)
I have a little spare time today, I will try to work with ChangeDisplaySettingsEx. Thanks so far headkase! I might call on your expertise again.

However now I think of it, I wonder if that's what I had in mind. It might achieve the same goal, but I think using this method doesn't use EDID at all. I'll see if I can get it to work :)
« Last Edit: February 09, 2017, 08:12:49 am by Rataplan626 »

Rataplan626

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 60
  • Last login:Yesterday at 01:36:22 pm
  • I want to build my own arcade controls!
I've had a look, and while I don't have a working test yet, I still have my thoughts. ChangeDisplaySettingsEx can indeed be used to set a specific resolution and sort of a specific refresh rate. However, in the DEVMODE structure which holds the display settings, the refreshrate is defined in Hertz, and as a word or dword (integer or long in my VB.net case) making it impossible to set something like 59.150 Hertz.
However, when you create a custom resolution with a decimal refresh rate in the Intel panel, it becomes available as the nearest rounded number in terms of Hertz. When I create a custom resolution of 59.150Hz, I can switch to that with whatever resolution switching method by switching to 59Hz. (Check it - when you do so, even in the Windows resolution switcher a new refresh rate of 59Hz is available which is in fact the 59.150 Hz one just created). So despite the fact I'll  have to fiddle out what format they use in those registry values (they sure have a different format than the EDID I am using so far) I am quite afraid that that is not enough. As I've tested before, just having the registry there is not enough at least for all resolution switchers I've tested so far to be able to switch to that resolution, until the videodriver is restarted.

Headkaze, with your extracted Intel dll utility, when you add a resolution, does it 'reset' the screen for a moment - ie. does it go blank for a little?

headkaze

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 2943
  • Last login:April 24, 2022, 02:38:27 pm
  • 0x2b|~0x2b?
Headkaze, with your extracted Intel dll utility, when you add a resolution, does it 'reset' the screen for a moment - ie. does it go blank for a little?

Yes it does. Right now though I have only implemented "Basic Mode" which will only accept an integer for refresh rate (dwRR) just like the Intel Control Panel.

Code: [Select]
    [StructLayout(LayoutKind.Sequential, Pack=4)]
    public struct _CUI_BASIC_MODE
    {
        public uint dwColor;
        public int bScanType;
        public uint dwRR;
        public uint dwHActive;
        public uint dwVActive;
        public uint dwTimingAlgo;
        public uint dwUnderscan;
        public uint dwHEffective;
        public uint dwVEffective;
        public int bIsValid;
    }

Advanced mode on the other hand does accept a "double" value for dwVScanRate. If you want me to implement the Advanced Mode then I need to know how it automatically calculates the following values; "Pixel Clock" (dwPixelClock), "Horizontal Scan Rate" (dwHScanRate), "Horizontal Total" (dwHTotal) and "Vertical Total" (dwVTotal).

Code: [Select]
    [StructLayout(LayoutKind.Sequential, Pack=8)]
    public struct _CUI_ADV_MODE
    {
        public uint dwColor;
        public int bScanType;
        public uint dwHActive;
        public uint dwHFrontPorch;
        public uint dwHBackPorch;
        public uint dwHSyncWidth;
        public int bHSyncPolarity;
        public double dwHScanRate;
        public uint dwVActive;
        public uint dwVFrontPorch;
        public uint dwVBackPorch;
        public uint dwVSyncWidth;
        public int bVSyncPolarity;
        public double dwVScanRate;
        public uint dwHTotal;
        public uint dwVTotal;
        public double dwPixelClock;
        public int bIsValid;
    }
« Last Edit: February 09, 2017, 02:33:43 pm by headkaze »

Rataplan626

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 60
  • Last login:Yesterday at 01:36:22 pm
  • I want to build my own arcade controls!
I was just looking into the advanced mode. In the Intel panel I cannot supply a decimal in the scan-rate field. So with that I still can't do 59.150 for example, but that doesn't mean the function inside the Intel dll doesn't support it since it accepts a double.

Horizontal total = front porch + back porch + sync width + active
Same for vertical, just add the values up for the total vertical
pixelclock is horizontal total * vertical total * refresh rate / 1000000 (as it's handled in MHz)
horizontal scanrate = vertical total * refresh rate

I'm now checking what format is used to store the custom resolutions from the Intel panel, and wheter that can be used on other brand cards as well.

headkaze

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 2943
  • Last login:April 24, 2022, 02:38:27 pm
  • 0x2b|~0x2b?
Okay I added an "Advanced Mode" to my utility which uses those calculations. I parse "vscanrate" as a double and pass it to set_AddCustomMode without modification. Sorry but I have not tested "Advanced Mode" yet. Also you need to have Intel HD Graphics Control Panel installed for this to work as I do not include igfxDHLib.dll or any other library this app may depend on.

Code: [Select]
IntelAddCustomMode v1.1 - by headkaze

USAGE: IntelAddCustomMode.exe mode=basic|adv|list|remove [options]

General Options:

verbose=true                            Verbose Output

Basic Options:

width=n                                 Width
height=n                                Height
refreshrate=n                           Refresh Rate
interlaced=true|false                   Interlaced Mode
underscan=n                             Underscan Percentage
timing=gtf|cvt|cvtrb|cea861             Timing standard

Example: IntelAddCustomMode mode=basic width=800 height=600 refreshrate=60

Advanced Options:

interlaced=true|false                   Interlaced Mode
hactive=n                               Active (Horizontal)
hfrontporch=n                           Front Porch (Horizontal)
hbackporch=n                            Back Porch (Horizontal)
hsyncwidth=n                            Sync Width (Horizontal)
hsyncpolarity=+|-                       Sync Polarity (Horizontal)
vactive=n                               Active (Vertical)
vfrontporch=n                           Front Porch (Vertical)
vbackporch=n                            Back Porch (Vertical)
vsyncwidth=n                            Sync Width (Vertical)
vsyncpolarity=+|-                       Sync Polarity (Vertical)
vscanrate=n                             Scan Rate (Vertical) in Hz

Remove Options:

index=n                                 Index of the Mode to Remove (from mode=list)

Download IntelAddCustomMode.zip
« Last Edit: March 01, 2017, 06:35:09 am by headkaze »

Rataplan626

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 60
  • Last login:Yesterday at 01:36:22 pm
  • I want to build my own arcade controls!
Thank you very much for the effort and insight! I'll take a look at it as soon as I have spare time again. If this works for Intel, this could easily be used as an alternative for my own tool. And you wrote it in a fraction of the time :D but in the for me most important thing is people can have a tearingless experience on their lcd-cab.

Howard_Casto

  • Idiot Police
  • Trade Count: (+1)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 19388
  • Last login:Yesterday at 09:49:28 pm
  • Your Post's Soul is MINE!!! .......Again??
    • The Dragon King
I can confirm that it works.  The changedisplaysettingsex api is what I used a few years ago to help rotate the taito type x games.  It is a bit fiddly though... what works for one video card may not work for another.

headkaze

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 2943
  • Last login:April 24, 2022, 02:38:27 pm
  • 0x2b|~0x2b?
If this works for Intel, this could easily be used as an alternative for my own tool.

You will still need to read the MAME xml and then add the appropriate resolution/refresh rate by calling my tool. We still don't know if it will set a valid floating point refresh rate so it might turn out to be useless.

Finally we still need ways for adding resolutions for nVidia and AMD. Well according to this article AMD may be as simple as setting a registry key. That leaves nVidia.

Howard_Casto

  • Idiot Police
  • Trade Count: (+1)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 19388
  • Last login:Yesterday at 09:49:28 pm
  • Your Post's Soul is MINE!!! .......Again??
    • The Dragon King
I've been using AMD/ATI cards for years and for every one I've had at least, I can confirm that registry hacks are generally all you need to add resolutions.  Of course my newest card is now a couple of years old, so YMMV. 

Rataplan626

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 60
  • Last login:Yesterday at 01:36:22 pm
  • I want to build my own arcade controls!
Howard, did that include floating point refreshrates? Looking at the article it looks like its all just x-y resolutions rather than floaing point refreshrates as well.
I've had no time at all this week to work on my own idea. Still have some ideas if that doesn't work out.

Rataplan626

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 60
  • Last login:Yesterday at 01:36:22 pm
  • I want to build my own arcade controls!
Okay I added an "Advanced Mode" to my utility which uses those calculations. I parse "vscanrate" as a double and pass it to set_AddCustomMode without modification. Sorry but I have not tested "Advanced Mode" yet. Also you need to have Intel HD Graphics Control Panel installed for this to work as I do not include igfxDHLib.dll or any other library this app may depend on.

Code: [Select]
IntelAddCustomMode v1.0 - by headkaze

USAGE: IntelAddCustomMode.exe mode=<basic|adv|list|remove> [options]

Basic Options:

[width=n]                               Width
[height=n]                              Height
[refreshrate=n]                         Refresh Rate
[interlaced=true|false]                 Interlaced Mode
[underscan=n]                           Underscan Percentage
[timing=gtf|cvt|cvtrb|cea861]           Timing standard

Example: IntelAddCustomMode mode=basic width=800 height=600 refreshrate=60

Advanced Options:

[interlaced=true|false]                 Interlaced Mode
[hactive=n]                             Active (Horizontal)
[hfrontporch=n]                         Front Porch (Horizontal)
[hbackporch=n]                          Back Porch (Horizontal)
[hsyncwidth=n]                          Sync Width (Horizontal)
[hsyncpolarity=+|-]                     Sync Polarity (Horizontal)
[vactive=n]                             Active (Vertical)
[vfrontporch=n]                         Front Porch (Vertical)
[vbackporch=n]                          Back Porch (Vertical)
[vsyncwidth=n]                          Sync Width (Vertical)
[vsyncpolarity=+|-]                     Sync Polarity (Vertical)
[vscanrate=n]                           Scan Rate (Vertical) in Hz

Remove Options:

[index=n]                               Index of the Mode to Remove (from mode=list)

Download IntelAddCustomMode.zip

I've finally had time to test it. In basic mode it works - it adds a resolution 'intel-wise'. In advanced mode it doesn't work for me though:

C:\Users\Rataplan_\Desktop\IntelAddCustomMode\IntelAddCustomMode>IntelAddCustomMode.exe mode=adv hactive=1920 hfrontporch=48 hbackporch=80 hsynchwidth=32 hsyncpolarity=+ vactive=1200 vfrontporch=3 vbackporch=26 vsyncwidth=6 vscanrate=59.150
Setting DELL U2412M (256) to 2048 x 1235 59150 Hz. Success


It doesn't end up in the custom resolutions though, as it does in basic mode. Also when I supply an integer-like refreshrate like 59 it doesn't seem to add it.

Howard_Casto

  • Idiot Police
  • Trade Count: (+1)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 19388
  • Last login:Yesterday at 09:49:28 pm
  • Your Post's Soul is MINE!!! .......Again??
    • The Dragon King
Howard, did that include floating point refreshrates? Looking at the article it looks like its all just x-y resolutions rather than floaing point refreshrates as well.
I've had no time at all this week to work on my own idea. Still have some ideas if that doesn't work out.

I'm not 100% sure.  I only used it for nonstandard (vertical) resolutions and didn't really mess with the refresh rate.  I know that powerstrip handled custom resolutions with most of my cards very well so perhaps you could look and see if it has source code available?

headkaze

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 2943
  • Last login:April 24, 2022, 02:38:27 pm
  • 0x2b|~0x2b?
C:\Users\Rataplan_\Desktop\IntelAddCustomMode\IntelAddCustomMode>IntelAddCustomMode.exe mode=adv hactive=1920 hfrontporch=48 hbackporch=80 hsynchwidth=32 hsyncpolarity=+ vactive=1200 vfrontporch=3 vbackporch=26 vsyncwidth=6 vscanrate=59.150

First of all it should be "hsyncwidth" but I still noticed a discrepancy with the calculations I'm using based on your algorithm.

I'm using:
Code: [Select]
hTotal = hFrontPorch + hBackPorch + hSyncWidth + hActive;
vTotal = vFrontPorch + vBackPorch + vSyncWidth + vActive;
hScanRate = vTotal * vScanRate;
pixelClock = hTotal * vTotal * vScanRate / 1000000.0;

The values I'm getting are:
Code: [Select]
hTotal: 2080 vTotal: 1235 hScanRate: 73050.25 pixelClock: 151.94452
But entering these values into the Intel HD Graphics Control Panel I get: hTotal: 2080 vTotal: 1258  hScanRate: 74.222 pixelClock: 154.38176

So obviously there is some miscalculation here.
« Last Edit: March 01, 2017, 04:40:24 am by headkaze »

djrobx

  • Trade Count: (0)
  • Jr. Member
  • **
  • Offline Offline
  • Posts: 8
  • Last login:April 08, 2017, 02:26:48 am
  • I want to build my own arcade controls!
Interesting tool!

Since you've brought up the Intel driver, I wanted to point out something that I have observed setting up a new cab over the last week or so.   I've been using a collection of my favorite emulators for years with VSYNC without any issues.   But on this machine, it seemed like I was having trouble with every emulator I tried.   Whenever I used vsync I'd get distorted audio.   If I enabled autoframeskipping the result was super choppy performance.   Testing my CPU showed utilization was sub-10% and it's a relatively new machine so that shouldn't be a problem.   After scratching my head I stumbled across this:

http://forum.arcadecontrols.com/index.php?topic=135230.0

FreqTool - A tool that checks the actual refresh rate.  I ran it on my system and discovered that "60hz" was more like 59.4hz.  Then the light bulb went off in my head.

Most emulators support auto-frameskipping in conjunction with Vsync.   However, if your actual refresh rate is *SLOWER* than the sound card rate, you will get into a very rough loop frequent frame skips as the next frame is likely going to have to be skipped since the machine is always "behind" where it should be by the next video frame.  And if you disallow frameskips, your audio buffer will be starved for sure.    So I set a custom resolution of 61hz, and everything started working better.    That tested at "60.7" which is still too fast, but the result is FAR more pleasant - sound no longer stutters, and there are some very infrequent, barely perceptible video skips.

My built in Realtek tested at very close to the expected 48khz rate.   It's the Intel video that's way off.    I will try using your tool to see if I can dial in a rate that's closer to actual 60hz.

Moral-TL;DR: Err on the side of a faster refresh rate.   If it's picking up refresh rates from a XML file it might even be a good idea to be able to specify an offset.

As for your registry settings, have you checked to see if you need to broadcast a message to get Windows to pick up your settings?  I recall doing something similar with joystick calibration values, and needing to send WM_SETTINGCHANGE to get the system to pick it up.

https://msdn.microsoft.com/en-us/library/windows/desktop/ms725497(v=vs.85).aspx

Jakobud

  • Trade Count: (+1)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 1940
  • Last login:March 28, 2023, 10:36:00 am
    • jakobud.com
Any thoughts on putting this on Github?
Jakobud 
Arcade Cabinet Plans and Dimensions http://jakobud.com

Rataplan626

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 60
  • Last login:Yesterday at 01:36:22 pm
  • I want to build my own arcade controls!
Hi, I've been very busy lately, we are about to remodel the house and add a few meters as well. So we are busy with constructors and the like. Also it's carnaval here  :cheers:

In the next few days I'll try to work on the tool again. Currently I've implemented a way allowing you to select a monitor and it'll read the edid and modify it, whichs means you don't need the edid file and registry. I'm not too fond of it though, so I'll redo that I suppose :)

headkaze

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 2943
  • Last login:April 24, 2022, 02:38:27 pm
  • 0x2b|~0x2b?
Rataplan626: I got advanced mode working in IntelAddCustomMode. I don't think it's adding the decimal part of the refresh rate but give it a try anyway and let me know your results.

You can cut/paste this command line:
Code: [Select]
IntelAddCustomMode.exe mode=adv verbose=true hactive=1920 hfrontporch=48 hbackporch=80 hsyncwidth=32 vactive=1200 vfrontporch=3 vbackporch=26 vsyncwidth=6 vscanrate=59.150
« Last Edit: March 01, 2017, 06:38:10 am by headkaze »

tspeirs

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 129
  • Last login:July 23, 2020, 07:44:52 am
  • I want to build my own arcade controls!
Thanks for this. I've been taking a look and can confirm it works perfectly as intended.

I was able to get games to launch at the correct refresh with GameEx and MAME for every game I tried.

Unfortunately GameEx will not reinitialize the direct3d device after return from a game. It produces an out of memory exception. It does not like the device being enabled/disabled and I was unable to work around this.

Still, very nice work and again I can confirm it does work for me.

A couple of thoughts on other options rather than resetting the video.
1. Try putting the monitor into powersave mode.
2. Try resetting the actual specific device rather than the whole video system.
« Last Edit: March 13, 2017, 12:41:48 pm by tspeirs »

Rataplan626

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 60
  • Last login:Yesterday at 01:36:22 pm
  • I want to build my own arcade controls!
@tspeirs; thanks for the reply, glad to hear it works. I am currently working on the tool again, I've had a couple of really rough weeks and haven't had any free time at all. I'm still working to get it to read the new edid values without restarting the driver, and I am implementing a better way to select the wanted display from commandline, rather than supplying that EDID file (which will always be optional, as one might just have some different edid, who knows).

Metalhammer

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 19
  • Last login:September 11, 2018, 08:05:47 am
  • I want to build my own arcade controls!
Hi Rataplan626,

I've been extensively searching through the web for something similar to what you seem to have achieved  ;)

... and to be honest, the main reason for me to join this forum was to be able to speak with you  :)

Since I cannot (maybe because I'm new) leave you a pm, I'll ask you something right here:

- first of all, is it safe to run a 'custom' non standard refresh rate on a general LCD monitor ?
... as far as I know, on digital hw, worse case scenario is the monitor not picking up the correct synch ... but I could be wrong  :-\

- second, what is the granularity/stability achievable when dealing with refresh rates ?
... I mean, if my hw says it can go from 30Hz to 60Hz what are the chances I can go 59.59hz stable, for example ?

- third: how much all the above is hw dependant ?
In other words, is it possible a specific monitor/brand won't allow me to play around at all ?

Cheers  :)