Nvidia - How to create custom video modes
We all want our MAME games to look as original as possible. This
tutorial will tell you how to create video modes on your Nvidia Video
Card to match the original Arcade game. You must be using Windows
XP and current Nvidia drivers which are 81.98 as of this writing.
The purpose of creating custom video modes is to create the same video
scan lines and scaling as the original game. This means this info
only applies if you have a CRT based monitor and play the game in full
screen mode. For vertical games, I am assuming you will be
rotating the monitor 90 degrees on it's side. There is no point
in making custom modes for vertical games if you do not intend to do
this. Also there is no point in creating custom video modes if
you have an LCD display. You should run your LCD at it's native
resolution for best picture and tell MAME to scale the picture to fit.
If you have a plasma, what the hell are you burning games into
the screen for?
Low resolution video modes will be doubled in resolution when created,
but accessed at the size created. This means a video mode of
320x240 will actually use 640x480. You still draw to it in the
native 320x240 mode, but all pixels will be doubled. This means
you will always see 2 scan lines for each pixel. It is actually a
quite pleasant look. If only 1 scan line was used then the dark
space between visible lines would be excessive on computer monitors.
This is due to their smaller dot pitch compared to old arcade
monitors. The 320x240 mode is actually one of the modes created
by the default driver file.
Download the latest drivers from Nvidia. Use WinZip
or your favorite extractor to extract the files to a directory.
The easiest way is to right click on the driver file and select
WinZip -> Extract to xxx\. Open this directory and then open the
"nv4_disp.inf" file with you favorite text editor or use notepad.
Browse down about half way through the file until you see a section that looks like this:
[nv_SoftwareDeviceSettings]
HKR,, InstalledDisplayDrivers, %REG_MULTI_SZ%, nv4_disp
HKR,, VgaCompatible, %REG_DWORD%, 0
HKR,, MultiFunctionSupported, %REG_DWORD%, 1
HKR,, RotateFlag, %REG_DWORD%, 4
HKR,, NV_R&T, %REG_MULTI_SZ%, "R&T0000=*,*,*,*,*,IBM251F.VSC2F0C.VSC3411.VSC3E19,HDLK"
HKR,, NV_R&T, %REG_SZ_APPEND%,"R&T0001=1920,1080,*,30,*,CRTX,OEM,7425,2200,48,56,562,2,5,++I"
HKR,, NV_R&T, %REG_SZ_APPEND%,"R&T0002=1920,1080,*,60,*,BNQ766A,OEM,13850,2080,48,32,1111,3,5,+-"
HKR,, NV_R&T, %REG_SZ_APPEND%,"R&T0003=1920,1200,*,60,*,BNQ766A,OEM,15399,2080,48,32,1235,3,6,+-"
HKR,, NV_R&T, %REG_SZ_APPEND%,"R&T0004=1920,1200,*,60,009D,*,OEM,15399,2080,48,32,1235,3,6,+-"
HKR,, DevSwitchSuppressMask, %REG_DWORD%, 7
HKLM,"Software\NVIDIA Corporation\Global\NvSvc\OemConfigurations",LoadLimitedSID,%REG_SZ%,"S-1-5-11"
HKR,, "DefaultSettings.XResolution",%REG_DWORD%,800
HKR,, "DefaultSettings.YResolution",%REG_DWORD%,600
HKR,, NV_Modes, %REG_MULTI_SZ%, "{*}S 720x480 720x576=1;320x200 320x240 400x300 480x360 512x384 640x400=F;SHV 2048x1536x32=1;1920x1200x32 1920x1440x8,16=1D;640x480 800x600 1024x768 1280x768 1280x1024 1600x900 1600x1200 1920x1200x8,16=3D;1920x1440x32=9;1920x1080=C01E;2048x1536x8,16=D;{1A0}S 1920x1200x32 1920x1440x8,16 2048x1536x8,16=20;800x480=3D;{40-48,90-94,C0-C3,110-145,14F-1F0,210-334,341-34E}S 720x576=8032;{40-18B,1F0-34E}SHV 800x600=1DC2;848x480=1DFF;1920x1080x32=1F;640x480 1024x768x8,16=1FC2;"
HKR,, NV_Modes, %REG_SZ_APPEND%, "1600x1200x32 1920x1200 1920x1440 2048x1536x8,16=2;1280x768x32 1280x1024x32=2C2;1280x720x32 1280x800x32 1280x960x32 1360x768x32=2FF;1600x900x8,16=3C2;1600x1024x32 1920x1080x8,16=3F;1600x900x32 1600x1200x8,16=42;1152x864x32=6FF;1280x768x8,16 1280x1024x8,16=7C2;1600x1024x8,16=7F;1280x720x8,16 1280x800x8,16 1280x960x8,16 1360x768x8,16=7FF;960x600=DFF;1024x768x32=FC2;1152x864x8,16=FFF;{40-CE,140-165,1A0,200-242,301-34E}SHV 2048x1536x8,16=10;1920x1440x32 2048x1536x32=4;"
HKR,, NV_Modes, %REG_SZ_APPEND%, "{40-CE,140-165,200-242,258-25B,288-34E}SHV 960x600=1000;{40-CE,140-165,200-242,301-34E}SHV 1920x1440x32=10;1152x864x32 1280x720x32 1280x768x32 1280x800x32 1280x960x32 1280x1024x32 1360x768x32=100;2048x1536x32=1A;1088x612x8,16=1FFF;800x600 848x480 960x600=200;1088x612x32=FFF;{4D-4E,9D,CD-CE,14A-14E,200-203,258-25B,288-289,308-309,32A-32B,338-33F,34E}SH 960x1200=803D;{4D-4E,9D,CD-CE,14A-14E,200-203,338,33F}SHV 800x600 1024x768 1280x1024 1600x1200 1920x1154 1920x1200=8032;"
HKR,, NV_Modes, %REG_SZ_APPEND%, "{4D-4E,9D,CD-CE,14E,200-203,240,338,33F}SHV 800x600 1024x768 1280x1024 1600x1200 1920x1154 1920x1200=8032;"
[nv_WSApps_AddReg]
HKR,,"NvCplConfiguration",%REG_DWORD%,0x100000
The following section is that part that creates the video modes. How to create custom modes is explained in the Compressed Modes User's Guide available from Nvidia.
HKR,, NV_Modes, %REG_MULTI_SZ%, "{*}S 720x480 720x576=1;320x200 320x240 400x300 480x360 512x384 640x400=F;SHV 2048x1536x32=1;1920x1200x32 1920x1440x8,16=1D;640x480 800x600 1024x768 1280x768 1280x1024 1600x900 1600x1200 1920x1200x8,16=3D;1920x1440x32=9;1920x1080=C01E;2048x1536x8,16=D;{1A0}S 1920x1200x32 1920x1440x8,16 2048x1536x8,16=20;800x480=3D;{40-48,90-94,C0-C3,110-145,14F-1F0,210-334,341-34E}S 720x576=8032;{40-18B,1F0-34E}SHV 800x600=1DC2;848x480=1DFF;1920x1080x32=1F;640x480 1024x768x8,16=1FC2;"
HKR,, NV_Modes, %REG_SZ_APPEND%, "1600x1200x32 1920x1200 1920x1440 2048x1536x8,16=2;1280x768x32 1280x1024x32=2C2;1280x720x32 1280x800x32 1280x960x32 1360x768x32=2FF;1600x900x8,16=3C2;1600x1024x32 1920x1080x8,16=3F;1600x900x32 1600x1200x8,16=42;1152x864x32=6FF;1280x768x8,16 1280x1024x8,16=7C2;1600x1024x8,16=7F;1280x720x8,16 1280x800x8,16 1280x960x8,16 1360x768x8,16=7FF;960x600=DFF;1024x768x32=FC2;1152x864x8,16=FFF;{40-CE,140-165,1A0,200-242,301-34E}SHV 2048x1536x8,16=10;1920x1440x32 2048x1536x32=4;"
HKR,, NV_Modes, %REG_SZ_APPEND%, "{40-CE,140-165,200-242,258-25B,288-34E}SHV 960x600=1000;{40-CE,140-165,200-242,301-34E}SHV 1920x1440x32=10;1152x864x32 1280x720x32 1280x768x32 1280x800x32 1280x960x32 1280x1024x32 1360x768x32=100;2048x1536x32=1A;1088x612x8,16=1FFF;800x600 848x480 960x600=200;1088x612x32=FFF;{4D-4E,9D,CD-CE,14A-14E,200-203,258-25B,288-289,308-309,32A-32B,338-33F,34E}SH 960x1200=803D;{4D-4E,9D,CD-CE,14A-14E,200-203,338,33F}SHV 800x600 1024x768 1280x1024 1600x1200 1920x1154 1920x1200=8032;"
HKR,, NV_Modes, %REG_SZ_APPEND%, "{4D-4E,9D,CD-CE,14E,200-203,240,338,33F}SHV 800x600 1024x768 1280x1024 1600x1200 1920x1154 1920x1200=8032;"
What we want to do is append our modes onto the end. For MAME we
only need 16&32 bit colour video modes. We do not have to
worry about what our card is and what it really supports. This is
not a driver for the masses, so we are going to pretend that
all video boards support all features. Otherwise we would have to
figure out the hex id number for our card, when we really don't care.
Here is the line I use. Just paste it after the other video
modes above.
HKR,, NV_Modes, %REG_SZ_APPEND%, "{*}S 240x192x16,32 240x224x16,32 240x240x16,32 240x248x16,32 248x208x16,32 248x256x16,32 256x224x16,32 256x240x16,32 256x248x16,32 288x224x16,32 292x240x16,32 304x224x16,32 320x204x16,32 320x224x16,32 320x232x16,32 320x240x16,32 384x224x16,32 384x240x16,32 384x256x16,32 400x254x16,32 512x448x16,32 512x480x16,32=1fff;"
The "HKR,, NV_Modes, %REG_SZ_APPEND%, " part tells the driver to append
some more video modes. "{*}S" tells the driver that all cards
support these modes. "240x192x16,32 ...." are the video modes we
want to create. This is the section you can change to add whatever modes
you want. The "=1fff;" at the end of the line tells the driver
all refresh rates are supported.
Your card & monitor may not support all modes and refresh rates.
But at this
point we don't care. When you run a game hit "TAB" and select
"Game Information". This will tell you the resolution of the
game. For Phoenix it will say "248x208 (V)" so we create 16 &
32 bit modes by adding "248x208x16,32" as seen in the list above.
Be warned that for vertical games, MAME32's properties page will
show the resolution as 208 x 248, but we need to create the mode as
shown in the game information page in MAME.
Unfortunately not every mode can be created. For modes with a
vertical size less then about 400, the H&V sizes must be evenly
dividable by 4. Remember low res modes are created at 2x.
Modes greater then 400 vertical must be dividable by 8.
Always make sure you round up on the number of pixels. MAME will
center itself and ignore the few extra pixels.
Once you have the modes you want added, save the file and install the
driver by running the "setup.exe" file. Once the computer has
rebooted you are free to use the video modes in MAME.
The modes may not all show up in MAME32 or it's derivatives. In
that case you have to compile your own version. You need to edit
the src\ui\directdraw.h file. On line 18 you will see this.
#define MAXMODES 256 /* Maximum number of DirectDraw Display modes. */
Change the MAXMODES to a higher number. I use 1024. Then
recompile. If you have recently compiled MAME32 before making the
change, then you need to delete your obj\YOURMAME\ui directory, where
YOURMAME is the name of your compiled MAME32. Then recompile.
You should now be able to select all video modes and refresh
rates.
To see if the modes were created, right-click
on an empty spot of your desktop. Select NVIDIA Display -> and
then select your monitor. On the left side list, select
"Screen Resolutions & Refresh Rates". You should now see a window like
this:

You can now slide the Screen resolution slider through the various
modes. You can also see what refresh rates your
monitor supports for that mode. If you need a refresh rate
that is not listed, then you will have to read the Compressed Modes User's Guide to find out how.
Proper Display Settings
Before we go any further, you need to know the best video properties
settings for your card to work with MAME. We want the video to
display as fast as possible without any tearing caused by writing video
info while the screen is drawing or not blanking. So right-click
on an empty spot of your desktop. Select NVIDIA Display -> and
then select your monitor. On the left side list, select
"Performance & Quality Settings". You should now see a window like
this:

You want to set the "Global Driver Settings" so that "Vertical sync" is
set to "Application-Controlled". Select "Advanced settings" and
turn "Triple buffering" "On". If you don't like your global
settings set this way, then I will leave it to you to create a MAME
profile with those settings.
Doing this allows Triple buffering to work in MAME. This way you
can turn on Triple buffering and turn off wait for vsync in the MAME
options. This will give you your fastest game speed with no video
tearing. When you use a custom video mode that exactly matches
the game resolution, you need to turn off hardware stretching and you
should not use D3D.
Testing and Observations
These are the options you need when running a vertical game at it's
native resolution and refresh rate while being rotated as the original
would be.
mame firetrk -r 320x240 -refresh 60 -ror -tb -nowaitvsync -dd -nod3d -nohws -nowindow -noafs
This will allow Fire Truck to run full screen in it's native resolution
of 320x240 and orientated vertically. Let the game's demo run.
You will notice that the picture is crisp. The video runs
smoothly with no jitter. If you change the refresh from it's
native rate of 60 to 75, the video will not be as crisp and will no
longer scroll smoothly.
If we run it at twice it's native resolution (-refresh 120) using the
command below, it will scroll smoothly, but the edges of the video will
have a ghosting effect. Again let the demo run. Look at the
Fire Truck. It will look crisp because it is not moving.
Look at the lines at the edge of the road. The straight
lines look crisp, but the diagonals are a faded gray, when they were
crisp white at 60Hz refresh. Look at the leading in trailing
edges of the buildings as they scroll. You will also see a gray
ghosting effect that is not there at 60Hz. If you pause the game,
the edges will once again be clearly defined.
mame firetrk -r 320x240 -refresh 120 -ror -tb -nowaitvsync -dd -nod3d -nohws -nowindow -noafs
This is because the game is drawing the video at 60Hz and the video
board is drawing it at 120Hz. Or put another way, you are
suppling the video card with 60 frames of video every second, when it
wants 120. So the video board makes up the other 60 frames using
an average of 2 supplied frames.
If you tell firetruck to synchronize the game play to the 120Hz refresh
rate using the command below, the video will once again be as smooth as
it was using 60Hz, but the game speed will be twice as fast.
mame firetrk -r 320x240 -refresh 120 -ror -tb -nowaitvsync -dd -nod3d -nohws -nowindow -noafs -syncrefresh
If you want to try these tests out without creating the custom video
modes, you can change the resolution parameter from 320x240 to 640x480.
This will allow you to at least see the ghosting I am talking about.
What is needed is a way to tell MAME to draw the video twice as fast as
it is being created. Coding video is not my thing, so if anyone
knows how to make MAME draw the video at 2x the game's native refresh
rate, while still running the game at it's native refresh rate, please
let me know. This would be a nice feature to allow you to use a
higher refresh rate then the game original used, while keeping the
video crisp.
Why allow video to run 2x game rate?
Some games use a really low resolution. Phoenix for example.
It has a resolution of 248x208. So when the video card
creates it, it will double it to 496x416. Phoenix used a refresh
rate of 60Hz. This would give us horizontal scanning rate of
about 27kHz. Way lower then the 31kHz cut off of most monitors,
giving an out of sync range error on the monitor. If we run the
game at 2x 60Hz =120Hz, the horizontal scan rate would double to 54kHz.
This would now allow you to use the custom video mode to display
the actual game resolution. But you would have the ghosting
mentioned above. This would be noticeable on the edges of the
stars as they move.
So if there was an option in MAME to update the video 2x, Phoenix and
lots of other old games, would be able to be displayed on a CRT monitor
in their native resolution. They would look as close as possible
to the original game display, without any scanline creation video
tricks. They would have real scanlines created by the monitor.
The game would look crisp and smooth.
So if anyone knows how to create the 2x option, please let me know on the MAME forum.
Thanks,
D.
Monitor out of Sync Range? Where is the Picture? Why Does it Look Weird?
Now that we have created the modes, you will find that a lot of them
will not work unless you use a refresh rate of at least 70Hz. As
explained in the Phoenix example, this can not be helped. So
first try the game at it's native refresh rate. If you monitor
shuts down or displays an error, then select a higher refresh rate.
It is probably best to try a rate 2x the games native refresh
rate.
Because monitor manufacturers do not really expect you to create your
own video modes, your mileage may vary on how well they display.
You may not be able to fill the whole screen or get the
pincushion correct. In that case try a different refresh rate.
Setting up your game
Remember the purpose of doing all this is to run the game at the
original resolution and the original refresh rate if possible. This means no hardware stretching.
You do not need to stretch something that is already at the
proper size. You also do not need to stretch if you create modes
that are exact multiples of the original resolution, eg 2x, 3x...
And do not use scanlines or any effects.
Real scanlines will be created by the monitor. Lets dissect
the test line we used previously. This is current as of MAME 104.
mame firetrk -r 320x240 -refresh 60 -ror -tb -nowaitvsync -dd -nod3d -nohws -nowindow -noafs
mame = start mame.
firetrk = run Fire Truck ROM.
-r 320x240 = the exact resolution of the original game as specified by MAME.
-refresh 60 = the original
game's refresh rate. You may have to use a higher value to make
your monitor work. Try 2x game refresh rate.
- ror = rotate game
clockwise. Needed for vertical games . Turn your monitor on
it's side. Do not use this if game is horizontal.
-tb = triple buffer for tear free video.
-nowaitvsync = no need to wait for vsync if triple buffering works.
-dd = always need DirectDraw
-nod3d = D3D seems to be slower. It's my personal preference to turn D3D off when using exact modes.
-nohws = NO HARDWARE STRETCH. Why stretch something that is already the exact size?
-nowindow = Full Screen. The whole point was making full screen custom modes, remember.
-noafs = No auto frame skipping. If you can not run the game full speed, why go through all the effort of making video exact?
And for the command line impaired, here are the MAME32 settings.
Look closely at all settings. You can leave the Clean
Stretch at it's default Auto setting. It will be ignored anyways.



Vertical Games.
As I have stated a few times, the modes created for vertical games
require you to rotate the monitor on the side. Which is what I
do. This also requires you to degauss your monitor after
rotating. You should be able to do this from your monitor's menu.
Read your manual for further info.
There is a way to cheat and leave your monitor horizontal, if you do
not mind all your vertical games being fat and filling the whole
screen. Just swap the Horizontal and Vertical values when you
create the video mode. So for firetrk, instead of creating a
320x240 video mode. Create a 240x320 video mode. Now you
can use that mode and not have to turn the monitor. The game will
run fat and fill the screen. Remember, -ror is no longer
needed. For MAME32 users, set Rotation to none/default.
Turn off "Force Aspect Ratio" by using -nokeepaspect.
Another interesting way to play vertical games without rotating the
monitor is to keep them at the original aspect ratio. This
requires you to use 4/3*VxV. So for firetrk this is 4/3*320x320 =
426.667x320. Round up so the number is /4. Gives us
426.667/4 = 106.667. Rounds up to 107*4. So we create a
mode at 428x320. Now our 240x320 fits perfectly vertically
and will have the proper horizontal aspect. MAME will center the
240 horizontal game pixels inside the full 428 by padding 94 pixels on
either side. Make sure to turn on "Force Aspect Ratio" by using
-keepaspect.
Good luck. If you have questions, post them on the MAME forum.
There are other users there that use this method. So you
may get some more help. But be specific about what you tried and
how it does not work.