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
Site News

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


  

Author Topic: RatRefresh - Automated EDID updater for MAME and others - no more LCD tearing  (Read 6224 times)

0 Members and 1 Guest are viewing this topic.

Rataplan626

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 31
  • 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. I was unable to find something like that. So I wrote it myself.

I short: you can run 'RatRefresh.exe -edidfile edid.txt -file refreshrates.txt -get bublbobl;mame' to switch to the exact refresh rate for that game.

A little backstory
Last year 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 arcade gaming). 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 a short while ago you would need specific hardware for that, as only ATI and NVidia seem to support EDID override. As my cab uses its Intel Core i3 6300 build in GPU I was out of luck anyway. Until a short while ago when Intel finally released a testdriver with EDID override support. Check https://communities.intel.com/thread/25904?start=150&tstart=0 for more info, and https://downloadcenter.intel.com/download/26504/Intel-Graphics-Test-Driver for that actual driver download. It will relatively soon come out of test and from then on the official Intel driver will probably support EDID override as well. This testdriver was only supposed to support 4th and 5th gen iGPU's with internal panels only. Still I took the plunge and what do you know? It worked! Using CRU I was now able to do custom resolutions and refreshrates on my Intel GPU! If you use that with MAME's -syncrefresh option, it will give you a completely tearing-free experience at the correct game-speed.

The next step was to automate this, so when I select a game, the resolution automatically switches. No tool as such found, so I wrote:

RatRefresh

RatRefresh is a simple tool that updates the 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. I've given it some thoughts but for now I've made it 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.

Note that this is currently more or less a testbuild.

Requirements

I use .NET Studio to program. For now though this means .NET 4.5.1 is required. Most of you will already have that on your systems anyway. However this whole tool could have been created in a rather simple VBScript as well, but for now this tool will be written and updated in .NET only.
Reason for only one custom resolution: Windows will automatically switch to the first custom resolution if only one is there, which means no manual resolution-switching is needed after that.

Usage
There are a few initial manual steps involved. As I want to keep it versatile I will keep it that way for now.

  • Unzip the RatRefresh zipfile to a folder on your system
  • Start CRU and create ONE custom resolution for your display. Use whatever resolution you want to play your games in, I use the native resolution of my screen which is 1920x1200@60Hz. If a custom resolution is already there, delete it and recreate to make sure the registry keys are setup correctly. If multiple custom resolutions are there delete all but one. Example:



  • Now start regedit.exe and find the the path to the EDID_OVERRIDE key + value. It is located in "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\DISPLAY" and then some subkey for your  GPU / display. You could search for 'EDID_OVERRIDE' or look for the value 'CRU_Name'. In that key you will probably two REG_BINARY values, 0 and 1. These correspond to the monitor number (I think) and on all my systems this is 0.
    Now right-click the EDID_OVERRIDE key in the left-pane and click 'Copy Key Name'. Then open notepad and paste that key. Now add \ and the monitor number behind that, for example \0.
    It should look like this, but probably with differend ID's in:



    save that file to the RatRefresh folder as edid.txt, or another name if you want, like monitor_1.txt

Basic setup is done now. You can now run RatRefresh as follows (I use edid.txt here):

RatRefresh -edidfile edid.txt -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 run devcon64.exe to restart the displaydriver, more on that below.


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). When using the regular XML tooling available in .NET memory usage grows beyond 2GB when processing mame.xml. My cab has 8GB of RAM, but I know there are a lot of machines with maybe only 1GB. So I wrote a little, not so smart mame.xml parser of my own, which is way faster and uses a fraction of the memory. But it might be buggy. Still this would take way too long to do with each game you select, so I went another route.

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. To fetch a game out of that file takes a fraction of a second even on the slowest and worst piece of cr@p pc I have still lying around, which is a Intel Atom N330 based netbook.

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 -edidfile edid.txt -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


When used together with a frontend (more on that below) it can usually supply you the emulator / system name you are starting a game for to use in a commandline.


Issues
  • I have put some error-checking in, but certainly not excessive. Using wrong combinations of commandlines or inputfiles will probably result in a nice errormessage. Read the help again and try again.
  • 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 (DVI at least) cable and reconnecting it works. For now I can only do the first one, restarting the videodriver.
    The issue with this is though that the frontend I use on my cab, AttractMode, crashes. 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.
    For now that means I am personally only using it from commandline. I haven't tested other frontends though.
    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. Those permissions can also be granted to users, but as I am still looking for a better way to have the EDID values reloaded. For now I use devcon to restart the display driver.
  • 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 download
initial release


v0.11 download
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.



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: February 06, 2017, 05:32:48 am by Rataplan626 »

Rataplan626

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 31
  • 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: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 359
  • 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
  • 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: 31
  • 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: 728
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
  • 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: 31
  • 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: 2931
  • 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: 31
  • 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: 2931
  • 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
  • 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: 31
  • 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: 31
  • 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: 2931
  • 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: 15798
  • 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: 31
  • 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: 2931
  • 0x2b|~0x2b?
Check out this post. Apparently you can set any resolution using ChangeDisplaySettingsEx.

Rataplan626

  • Trade Count: (0)
  • Full Member
  • ***
  • Offline Offline
  • Posts: 31
  • 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: 2931
  • 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: 31
  • 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: 31
  • 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: 2931
  • 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: 31
  • 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: 2931
  • 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: 31
  • 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: 15798
  • 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: 2931
  • 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: 15798
  • 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: 31
  • 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: 31
  • 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: 15798
  • 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: 2931
  • 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
  • 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: 1886
    • 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: 31
  • 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: 2931
  • 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: 127
  • 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: 31
  • 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: 18
  • 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  :)

  
 

Sitemap 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31