schellingb / dosbox-pure

DOSBox Pure is a new fork of DOSBox built for RetroArch/Libretro aiming for simplicity and ease of use.
GNU General Public License v2.0
731 stars 61 forks source link

Text mode with aspect correction on a VGA monitor looks... bad. #507

Open chinagreenelvis opened 3 weeks ago

chinagreenelvis commented 3 weeks ago

I've been trying for weeks to figure out a solution to this problem. I'm trying to emulate DOS games as close to the original experience as possible using an HP vx74 connected through VGA. I've tried using HDMI to VGA adapters and now I'm trying a Radeon 5450 as output.

The only way I've found to get text mode games, 320x200 games, and 640x480 games all scaled properly is by using high resolutions with scaling and bi-linear filtering, but this destroys the crisp image and high refresh rates of the lower native resolutions and just about defeats the purpose of using a VGA monitor. No matter what settings I use, if I try to run everything at 640x480 with aspect ratio correction, the scaling looks terrible. Zork becomes an ugly mess and even the scaling on DOOM isn't great.

I can pull this off easily in regular DOSBox with the right conf file, but loading that conf file into DOSBox Pure actually looks worse, presumably since it's squeezing the 740x400 pixels in even more. I also obviously prefer Pure for all of the bells and whistles, save states, ease of control, etc. Plus I prefer to keep Retroarch as my front-end.

Why is the scaling so bad? Is there a solution that I'm missing?

schellingb commented 3 weeks ago

Doesn't CRT switchres of RetroArch work in this scenario? It really should just be the default settings, where the core renders the game at its native resolution and then RetroArch does the rest by requesting the monitor to be in the exact resolution as the game.

chinagreenelvis commented 3 weeks ago

I haven't been able to find an answer on that one, but I'm experimenting with CRTEmudriver to try to get the proper custom resolutions to come out through the Radeon. The only comprehensive tutorials I've found on it are specifically for setting up other consoles with arcade monitors and television sets. My first test on a secondary system just resulted in Retroarch crashing when Switchres was used. By default it doesn't do anything except prevent aspect ratio correction.

I'm not able to create any threads on the Libretro forums about it but I'm planning to ask in the Discord with zero hopes of getting much of an answer since there aren't many CRT enthusiasts who aren't just using regular DOSBox.

chinagreenelvis commented 3 weeks ago

Is it possible that the content isn't asking Retoarch for those resolutions?

chinagreenelvis commented 3 weeks ago

Alright after some extensive testing and finally getting Switchres to work properly with super resolutions, I'm convinced that DOSBox-Pure is not asking Retroarch to display at the original resolutions; it seems to be always asking for 640x480. This is obviously okay for the majority of games, but I'm a stickler for original resolutions.

My testing was as follows:

Connected an SVGA monitor (HP vx74) to a DVI to VGA adapter through an RTX 3080, Windows 10. Set it as primary and to 1024x768.

Fired up a clean DOSBox, tested the command line, Zork I, and Doom.

dosbox.conf:

fullscreen=true fulldouble=false fullresolution=original output=ddraw machine=vgaonly aspect=false scaler=none

The command line and Zork request a resolution of 800x600 for some reason. Doom requests 640x480. As expected, everything is vertically squished.

Used CRU to add some new resolutions: 720x400 @ 70Hz and 640x400 @ 70Hz. Command line and Zork now request 720x400 and Doom requests 640x400. Everything is aspect corrected directly through the custom resolutions, no need for .conf file changes.

Now onto DOSBox-Pure and CRT Switchres:

I couldn't get Switchres to work with DBP using the "Native" resolution setting, which seemed to suggest that DBP was not requesting the proper resolutions, but I still had not gotten Switchres to work with anything else, either. I also set DBP to be VGA instead of SVGA, no difference.

Clean installation of the latest version of RA, the DBP core, and the Nestopia core, with "rgui" as the menu driver. Used CRU to add two super resolutions: 2560x224 and 2560x240.

In switchres.ini, I set the monitor to pc_31_120 and user_mode to 2560x0.

Turning on Switchres made RA go straight into 2560x240. Booting up Mega Man 2 on Netsopia switched it right to 2560x224, exactly as it should; so now I know I've got switchres working finally.

I added two more resolutions with CRU: 2560x400 and 2560x480. RA now wants to default to 2560x480, and opening any content with DBP or just starting the core keeps it at 2560x480, even if I switch back to 2560x240. This means that Switchres is still working, but DBP only ever requests the equivalent of 640x480.

This wouldn't be quite as bad if the low-resolution scaling of text-mode games weren't so awful, or if somehow they could be excluded from scaling, but there's no way to do that without making individual .conf files for every one of those games - even in normal DOSBox.

I don't know how you can go about making sure that DOSBox-Pure at least has the option of always demanding from RetroArch the native resolution of the original content (and its menu should be requesting text mode 720x400, just as the command line in normal DOSBox does), but it would go a long way towards being able to make it playable on a CRT. (Obviously none of this matters much on LCD displays at high enough resolutions where everything can properly scale, but as an enthusiast of trying to reproduce the original experience, I really hate to go back to using the default eXoDOS setup primarily because of DBP's ease of use and extra features.

Other cores definitely are able to request different resolutions even in-game and the original DOSBox does it natively, so you're probably the only one who would know where this mechanism is getting lost in translation.

schellingb commented 3 weeks ago

There's two ways you can check what resolution the core is requesting from RetroArch.

One way to see the emulated resolution is via Core Options -> "Emulation" and set "Show Performance Statistics" to "Detailed information". That will make the core show the emulated monitor mode at the top (i.e. 640x400@70.09fps while in the command line).

Another is by going to RetroArch's Settings -> "User Interface" -> "On-Screen Notifications" -> "Notification Visibility" and set "Display Statistics" to "ON". Then with the menu closed it will show all kinds of information including under "CORE AV_INFO" you have the "Size" which is the requested resolution and "FPS" which is the requested frame rate or monitor frequency. Below that you'll have the information how RetroArch is outputting video which includes the viewport and refresh rate. The core can only affect what is under "CORE AV_INFO", RetroArch will then do the rest based on its settings.

Can you confirm via the "Display Statistics" overlay if what you get is due to the core or due to RetroArch? Maybe the requested aspect ratio is preventing something from working as it should? There is a core option "Video" -> "Aspect Ratio Correction", but I'm not sure if that has an influence on crt switchres.

chinagreenelvis commented 3 weeks ago

Wow, that's an extremely useful feature that I didn't know about - thanks for mentioning it - and I think it turns out that the core is asking for those resolutions after all. In VGA mode, the menu, command line, and text-mode games all show a core resolution of 720x400. Space Quest VI shows 640x480. Interestingly, Space Quest IV shows 320x200 and not 640x400, and Doom shows 320x400 (I have no idea what's going on with that, in SVGA it's 320x200 again).

I really now have no idea why I was unable to get Switchres going with it, since it clearly works with at least one other core.

Thanks for the response, this information will go a long way I hope to figuring it out, and I'll post back here if I get it working as intended...

schellingb commented 3 weeks ago

huh, I'm quite perplexed how you're getting these weird resolutions. DOOM rendering to 320x400 would look absolutely bonkers. DOOM is my go to test for this core and I've never seen it output anything but 320x200 at 70 hz. This is what I get with aspect ratio correction off (left) and on (right): image

chinagreenelvis commented 3 weeks ago

Doom seemed like it was reporting the wrong resolution, but it was presenting at the 320x200 aspect ratio; try again but set the video to VGA instead of SVGA and you might see the same anomaly. I had aspect ratio correction off, but obviously that makes no difference in the numbers on screen.

schellingb commented 3 weeks ago

You're absolutely right. Forcing the graphics chip to VGA does make the emulator come to that resolution in DOOM. The core then fixes up the aspect ratio so it goes back to be as close as possible to match a 4:3 monitor by doubling or halving the height, so 320x400 ends up again with 1.6 / 1.333 and a regular (non-crt) output gets corrected by RetroArch.

Hmm, it's not like DOOM supports SVGA modes in any way so I'm not sure why it ends up like that. I need to look at regular DOSBox versions to see if that also happens there (I'd guess because DOSBox Pure doesn't have changes regarding the video card emulation). If DOS/DOSBox really fills out 400 lines then the core can't really do much. I'm not sure if that's a bug in the VGA mode or if that perhaps is just how a certain VGA graphics chip would have worked? The command line being in 720x400 doesn't seem to weird for a VGA graphics chip (just from 3 minutes of googling).

schellingb commented 3 weeks ago

So here's what I'm getting in regular DOSBox (with scaler=none) With SVGA (machine=svga_s3):

With VGA (machine=vgaonly)

So regular DOSBox does internal line doubling depending on certain video modes. That's how it ends up changing the 640x200 to 640x400. DOSBox Pure on the other hand keeps the raw video as is and uses the aspect ratio to let the frontend handle the correction, this helps with performance because the frontend does the scaling on the GPU while DOSBox did it in software. But of course that doesn't work with CRT switchres (which ignores the aspect ratio).

I'll have to look into this. Maybe we can bring back the line doubling without too much performance loss? It seems that the line doubling on real hardware was done by the graphics chip (as opposed to the monitor) so it makes sense that the emulator does it before handing the image off to the frontend.

chinagreenelvis commented 3 weeks ago

I was wondering at what stage the traditional doubling had been happening on the original hardware. Still, I would think I would be able to get Switchres to produce some kind of result even if it came back with some wrong ones. My only other thought is that it was never designed to be used for PC modes (basically just console and arcade CRTs) but I'm having a hard time finding anyone who knows enough to tell. But if this leads to anything worthwhile I'll be glad to have stumbled on it.

chinagreenelvis commented 3 weeks ago

DOOM VGA: image

DOOM SVGA: image

So we're still getting different results there, not sure why. The reported VGA resolution on my end is weird.

Edit: Tried it with GL as the renderer and same thing.

schellingb commented 3 weeks ago

But that matches with original DOSBox and other variants (like DOSBox-X). It ends up with a video mode of 640 pixel wide when using VGA (which the underlying setting in DOSBox is machine=vgaonly) and 320 pixels wide with the default SVGA (which is machine=svga_s3 in DOSBox). I can bring back the line doubling (which would make DOOM under vgaonly run in 640x400 instead of 640x200) but I don't think I can change the underlying video card emulation as such that it outputs only 320 pixels wide with the vgaonly machine.

chinagreenelvis commented 3 weeks ago

I've only been using VGA mode for testing, I think most people (myself included) will keep it on SVGA since it's compatible with everything but requires normal2x at the lowest possible resolutions.

I know that in regular DOSBox, 640x480 won't attempt to correct the vertical resolution of text-mode even when aspect is set to true - which is good because it would look really bad and text mode games actually look mostly fine without the scaling (just slightly horizontally squished from 720 to 640 which removes some of the spaces between characters), even if they're not accurate. The way I see it, the in-core option of aspect correction should work the same way, and text-mode scaling should only be affected by the Retroarch option for correction that's in the video settings menu. That way text-mode won't look awful at 640x480 but basically every graphics game will be fine.

If it's as simple as bringing back line-doubling to achieve that, I think I'd give that idea a +1.

I have no idea if any of this has anything to do with RA apparently not getting resolution change requests from it, but getting Switchres working would make it irrelevant since a user adding two custom resolutions on their display (720x400 and 640x400) would make any aspect ratio correction unnecessary for the vast majority of games. This is obviously only for someone trying to play it on an SVGA monitor (IE me lol).

I'm going to do some more testing to see if I can get Switchres to work with the current build, but do you think that the stage at which you're making scaling happen is the cause, or is that just a maybe?

schellingb commented 3 weeks ago

To reiterate, the core is not doing any scaling of any sort. DOSBox used to have all kinds of scaling algorithms built in but I removed them all to just give the frontend (RetroArch) the raw framebuffer and let it handle all scaling. RetroArch does it on the GPU so it is faster than anything DOSBox does so we gain a decent amount of time each frame to emulate more cycles per second.

The only problem I see with this approach and CRT switchres is that we can end up with resolutions as weird as 640x200 which normal RetroArch without CRT-switchres happily deals with (it applies the 1.333 aspect ratio so it shows as 640x480 on screen). I won't bring back the software scalers like 2x because I don't think it makes sense for a libretro core. Doing line doubling again is something I can look at. It should be quite simple probably with no (measurable) performance loss if done right.

chinagreenelvis commented 3 weeks ago

I think I understand; the line-doubling would make sure that incorrect ratio resolutions aren't requested.

RetroArch does it on the GPU so it is faster than anything DOSBox does so we gain a decent amount of time each frame to emulate more cycles per second.

I see, so this would mean that returning to an ability to avoid scaling text-mode isn't possible (unless you do it manually, of course - shame there isn't a hotkey for toggling it, I don't think), which means that the command prompt and text-mode games are always going to look bad in RA if they're aspect-corrected at low resolutions (such as 640x480). This means my only solution to getting them to look pretty on a CRT is to either 1) run everything at the highest resolution possible for the CRT (the best workaround I came up with was creating a custom resolution of 1600x1200 that ran over a 1280x1024 signal, totally playable and better than an LCD but there's a distinct clarity loss) or 2) getting Switchres working, which is currently my goal.

Thanks for all the feedback and consideration so far!

chinagreenelvis commented 3 weeks ago

I GOT IT WORKING. MOSTLY.

Using RA 1.19.1 and following the CRTEmudriver instructions with my secondary Radeon 5450 up until the point of substituting the user_modes.ini with a version that contained all of the desired DOS resolutions and refresh rates. I need to repeat the process but possibly also adding in my custom modelines file, because instead of generating 70Hz refresh rates, it created 65Hz rates which makes modes like 640x400 produce square pixels instead of stretching the full height of the screen.

I'm nearly there and hopefully will figure out how to get them at a proper 70Hz. If I do, I will write up a tutorial somewhere since the process from start to finish is a lot less complicated than I've been making it.

The lack of line-doubling seems irrelevant as well, since Switchres is taking the requests of 320x200 and returning the proper resolution of 640x400 (because there is no modeline present for 320x200 as it would be incompatible with the monitor anyhow). That also goes for the weird mismatched resolution in DOOM in VGA mode. So in order to solve my particular problem, it seems reintroducing it is not necessary, but you may have other reasons to look into that still.

schellingb commented 3 weeks ago

Oh, that sounds like great news!

I have no means of testing any of this, so I'm happy to hear your report. Writing up a tutorial of some sort sounds like good idea. If you have some good advice on how to use DOS/computer cores in RetroArch with an analog monitor, we maybe could add a section to the core's documentation on the RetroArch homepage.

My worry was that switchres was giving up when it encounters a weird or unknown resolution but it sounds like it has some logic to choose the next best one?

chinagreenelvis commented 3 weeks ago

Got it licked, everything running as it should with 70Hz rates.

My worry was that switchres was giving up when it encounters a weird or unknown resolution but it sounds like it has some logic to choose the next best one?

I'm not exactly sure what the logic is or if it just picks the closest resolution available to it, but I figured out that the problem was ultimately that specific crt_range entries need to be defined. The 15/30 kHz CRT presets were clearly never meant for anything but console and arcade gaming because they don't cover the necessary values for the few necessary DOS or Windows resolutions.

I also found that I was able to achieve this without an extra video card and CRTEmudriver, although that method is definitely needed for TV monitor/console/arcade emulation. So the DOS Switchres can be done either way, but a cheap HDMI or DisplayPort to VGA adapter works great.

The simpler way was to just leave DOSBox-Pure in SVGA mode and create one custom resolution through the NVidia control panel:

image

Since SVGA mode only requests 640x400 for text-mode and has greater compatibility, it's probably not necessary to make the 720x400 VGA or 700x400 CGA custom resolutions.

Literally the only other thing necessary to do with a fresh install of RetroArch 1.19.1 and DOSBox-Pure 0.9.9 is

1) create a switchres.ini (either in the root directory or as a core override .\config\DOSBox-pure\DOSBox-pure.switchres.ini) and change the following lines:

monitor                   custom

    crt_range0                30000-70000, 50.00-70.00, 0.578, 3.466, 1.733, 0.318, 0.064, 1.049, 0, 1, 400, 400, 0, 0
    crt_range1                30000-70000, 50.00-60.00, 0.635, 3.810, 1.905, 0.317, 0.063, 1.048, 0, 0, 480, 480, 0, 0
    crt_range2                30000-70000, 50.00-70.00, 0.635, 3.813, 1.906, 0.318, 0.064, 1.112, 0, 1, 400, 400, 0, 0
    crt_range3                30000-70000, 50.00-60.00, 1.000, 3.200, 2.200, 0.026, 0.106, 0.607, 1, 1, 600, 600, 0, 0
    crt_range4                30000-70000, 50.00-60.00, 0.369, 2.092, 2.462, 0.062, 0.124, 0.600, 0, 0, 768, 768, 0, 0
    crt_range5                30000-70000, 50.00-60.00, 0.444, 1.037, 2.296, 0.016, 0.047, 0.594, 1, 1, 1024, 1024, 0, 0
    crt_range6                30000-70000, 50.00-70.00, 0.578, 3.466, 2.455, 0.381, 0.064, 1.112, 0, 1, 400, 400, 0, 0

2) set the following in retroarch.cfg:

crt_switch_resolution = "4"
crt_switch_resolution_super = "0"
video_aspect_ratio = "8.000000"
video_fullscreen = "true"
input_auto_game_focus = "1"

These exact modelines aren't guaranteed to work with every monitor, but I would hazard a guess they'd have a high compatibility. Mine is an SVGA HP vx74, and I've used them to create a monitor.ini preset entry for VMM which was then successful at both generating resolutions from the following user_mode.ini:

## DESKTOP ##

 800 x 600 @ 60.000000 desktop
 1024 x 768 @ 60.000000 desktop
 1280 x 1024 @ 60.000000 desktop

## DOS ##

 640 x 480 @ 60.000000 dos
 640 x 400 @ 70.000000 dos
 720 x 400 @ 70.000000 dos

## CGA ##

 700 x 400 @ 70.000000 cga

and also the following modelines.txt:

modeline "720x400_70 31.47KHz 70.11Hz" 27.70 720 736 832 880 400 412 414 449 -hsync +vsync
modeline "640x480_60 31.50KHz 60.00Hz" 25.20 640 656 752 800 480 490 492 525 -hsync -vsync
modeline "640x400_70 31.48KHz 70.10Hz" 25.18 640 656 752 800 400 412 414 449 -hsync +vsync 
modeline "800x600_60 37.88KHz 60.32Hz" 40.00 800 840 968 1056 600 601 605 628 +hsync +vsync 
modeline "1024x768_60 48.36KHz 60.00Hz" 65.00 1024 1048 1184 1344 768 771 777 806 -hsync -vsync
modeline "1280x1024_60 63.98KHz 60.02Hz" 108.00 1280 1328 1440 1688 1024 1025 1028 1066 +hsync +vsync 
modeline "700x400_70 31.48KHz 70.11Hz" 27.70 700 716 812 880 400 412 414 449 -hsync +vsync 

Again, though, the CRTEmudriver route (the downside being needing to put Windows into Test Mode) really isn't necessary if you can successfully add the custom resolution of 640x400@70Hz to your display. The modelines are only really then important for RetroArch's Switchres.ini file, which was really the key to the whole thing.

I think this just about covers it! Time to celebrate by playing some... modern PC games that don't need an emulator!

chinagreenelvis commented 2 weeks ago

For anyone interested, I got my starting point info for modelines from a document I copied and am sharing here:

https://docs.google.com/spreadsheets/d/1Wz4aE7kM2UUJ_nSUYI405g4I7pS0_fzXOtP600fTZXQ/edit?usp=sharing

And in the process of trying to understand the relationships between the numbers involved, I whipped up a crt_range and modeline calculator here:

https://docs.google.com/spreadsheets/d/1wxiqKLD39P8Eg98md3et3fTV6UC_01XrUUF98EPHgwg/edit?usp=sharing

alexb3d commented 1 day ago

The resolution 320x200 256 colors is the famous 13h mode, also known as 'game mode', because it was used by the vast majority of DOS games. Even used on consoles, games like Sonic are 320x200, widescreen 16:10.

I have noticed that the standalone adapters behave in a "particular" way, the VGA adapter should be compatible with 320x200 but I have a sneaking suspicion it is something more like the output than the adapter, because it doubles the vertical resolution to adapt to 640x400 progressive.

For most VGA/EGA/CGA games, it is not recommended to change the SVGA adapter. There are few games where you need to pre-select the adapter to be able to choose the video mode, e.g. Lemmings.

CRT switchres is a new implementation, no need to create modlines, just activate it, take the resolution declared by the core and configure everything by magic.
It works with any video card and nothing special is needed, in Linux nothing and in Windows CRT Emudrive is recommended.

In a flat monitor, when the aspect ratio 4:3 is activated, it is normal that the letters are broken, it is breaking the proportion of the pixels, this I correct it with a shader or I activate the bilinear filter that is in configuration of the main menu.

In a CRT monitor it is not recommended to activate the 4:3 because it deforms the pixels.