VOGONS


Vertical retrace sync patch

Topic actions

First post, by augnober

User metadata
Rank Member
Rank
Member

Hey.. A while ago, I started posting somewhere on the forums about the possibility of syncing dosbox's vsync to the host display in cases where the host and virtual display Hz is sufficiently similar to get supersmooth scrolling in certain apps, demos, whatever.

I got a preliminary version of the simplest sort going on my machine. You won't be impressed, because it's simple work and somewhat of a hassle for the user -- but it's cross-platform and gets some nice smooth results, so I'll explain it. It's certainly not in releasable form, but it's enough to be a toy.

SDL doesn't have access functions for this kind of information. I didn't change SDL. So how do I get this information on all platforms? I momentarily thought of using a webcam or interference in the soundcard -- anything to automatically grab the timings -- but that's not very feasible.. So I decided to use the users' eyes with a manual calibration process. I made a small COM file which runs in DOSBox, showing the worst tearing/shearing possible. The user needs to adjust the refresh timing using the keys to figure out what their refresh rate is (by stabilizing the shear -- this value will be common across runs with appropriate fullfixed setting), and then uses another key to shift the shear line off the screen (adjustment to the timing offset, via a one-refresh-only time tweak -- unfortunately, this would need to be adjusted every time except on Windows).

Anyway.. looks great in some programs, though I'm forcing them to sync to 75Hz (My LCD will only give me 60Hz or 75Hz... Though my driver keeps teasing me by saying it's at other speeds, the vsync's stuck at those speeds nonetheless). I wish I could run at 70Hz, since that's what apparently lots of demos are at, and some of them seem to perhaps have their own timing routines to aid in the vsync handling (in a small number of apps, rather than run fast, things run kind of weird). With a CRT, it would be possible to keep switching the host refresh rate while running, and have knowledge of the timings available stored. I know it's possible to automate this on Windows without giving the user hassle, but having to adjust the shear offset at every mode switch on other platforms would be too annoying, I think.

Last edited by augnober on 2005-12-16, 10:59. Edited 1 time in total.

Reply 1 of 35, by augnober

User metadata
Rank Member
Rank
Member

Right now in the calibration, I'm just using a timer value rather than cycling through standard refresh rates, so I'm assuming that in order to get an accurate enough timing this would need to be matched up against a list. In some way or another, the user or dosbox would need to guess what the true refresh rate is in order for this to work over a long run without the user needing to occasionally to shove the shear line off the screen again. Switching to/from desktop could put the shearline in a bad place too.. 😀

Reply 2 of 35, by `Moe`

User metadata
Rank Oldbie
Rank
Oldbie

How about handling the frame issue by running at 75 Hz and displaying every 15th frame twice? How noticeably would that be in animations, videos or action games? Alternatively, run at 60Hz and drop the occasional frame?

Reply 3 of 35, by augnober

User metadata
Rank Member
Rank
Member

Yeah, I actually thought of something like that as I walked out for dinner tonight 😀 It reminded me of a bunch of filters and stuff a friend of mine was doing for dvd software (rather different though, because of interlacing in that case). Anyway, I think something like that has some potential, though I bet any simple solution will look worse than just allowing it to shear (dosbox's usual way).

Reply 4 of 35, by Srecko

User metadata
Rank Member
Rank
Member

Not just interlacing, it does shifting of framerates from NTSC 30 Hz(or 29.975) back to movie 24 Hz (or only to 23.975 Hz). Process is called "inverse telecine" and it also involves deinterlacing of part of frames.

Telecine is the opposite equvalent, a process of doing partial interlacing to convert 24 fps movies to NTSC framerate.

Reply 5 of 35, by augnober

User metadata
Rank Member
Rank
Member

I haven't had much time to work on it, but I did a quick test of the 'displaying every 15th frame twice' sort of method. All I did was make the vsync take twice as long whenever necessary, calculated based on the the user-supplied (host) and virtual refresh. That's just a test because it's bound to have problems in certain cases -- it'd be better to use doublebuffering to avoid messing around too much with the internal emulation. Anyway, as expected, it looked a little annoying in my test/calibration app because there's a regular short stutter every second. However, it actually looked quite good in most games and didn't cause problems. The stutter's mostly only significant if there's supposed to be some really smooth scrolling at a regular pace. As for things not running correctly, out of the small number of things I tested, the only thing I found that really got broken by it was Second Reality by Future Crew (it ran slowly). Demos were giving me the most trouble with the 75Hz before too -- they can be pretty fragile it seems.

Edit: I had a bug -- behaviour has improved now. See posts below.

Last edited by augnober on 2005-12-19, 07:46. Edited 1 time in total.

Reply 6 of 35, by augnober

User metadata
Rank Member
Rank
Member

Experimenting with this a bit more, I've noticed that it has.. improved (or at least changed) the compatibility with Panic by Future Crew. Compatibility's only improved when I do the "skip every 15th frame" kind of correction. Without my changes, I can't get the thing to run past the "PANIC" title screen. Supposedly, people had gotten it working in 0.63, but I can't get it running in either latest cvs or gulikoza's built. If my display was actually at 70Hz rather than 75Hz, I wouldn't expect any different operation... so I seem to be having some dumb luck. It still seems the demo doesn't like a certain range of cycles -- up to about 5500 is fine for me, and then it break down for a bit, then becomes workable again at about 10000 cycles. Without the change, I can't find any working range. Altogether, speed issues, etc. are better without the stuff I've changed (it wasn't supposed to work anyway), but it's sort of interesting.

Reply 7 of 35, by augnober

User metadata
Rank Member
Rank
Member

Ok. I had some bugs. I was accidentally setting the vsyncend value (vga.draw.delay.vend's counterpart) to much too long in the correction frame. Fixed it now.. Now looks great (your suggestion was great Moe 😀).

I'm playing with it with the 'jolt' key to shift the shear line off the screen when things go bad (I'm still not keeping my own timer through the duration of the program, so emulation modesets are killing it -- I should add my own). It looks good, and I'm a little startled in watching demos, since some of the fancier colour-hackery looks perfect since it's in sync now. Anyway, it looks worth working on, so I'll keep at it 😀

A funny bit about this is... The bug I had is what made Panic work. Fixing the bug broke Panic again. My theory now is that Panic is making a graphics mode change at that "PANIC" title screen, and needs the display's retrace register to stop behaving during the mode switch so that it can remain in the vsync wait loop for a longer duration. I think dosbox's retrace register doesn't become unresponsive for long enough on a mode change. (again, this is a theory -- I don't have enough info to back this up)

Edit: My theory about the "PANIC" title screen was wrong. There's no modeswitch there. I don't know why it freezes there.

Edit2: Another possible cause of the Panic issue might be some sensitivity with the SB timing. Mindlessly changing the DMA timings was able to improve things with the same effect. I also noticed that a file open occurs at that time, so that's another variable to consider. Anyway.. seems that demo is really sensitive to timing, and may be a pain to understand what's really happening.

Last edited by augnober on 2005-12-19, 10:55. Edited 3 times in total.

Reply 8 of 35, by `Moe`

User metadata
Rank Oldbie
Rank
Oldbie

I remember the old VGA-Copy _shareware_ version having a nice exit screen with cool colour effects (background changed so fast that it looked as if coloured bars moved behind the text). Does it work with your patch? (Check www.vgasoft.de to see if it's still available for download)

The freeware or registered versions don't have that exit screen, so they are of no help.

Reply 9 of 35, by augnober

User metadata
Rank Member
Rank
Member

I remember the old VGA-Copy _shareware_ version having a nice exit screen with cool colour effects (background changed so fast that it looked as if coloured bars moved behind the text). Does it work with your patch? (Check www.vgasoft.de to see if it's still available for download)

The freeware or registered versions don't have that exit screen, so they are of no help.

The version up on that page is the freeware one unfortunately (no fun stuff on exit). If you can find the shareware, I'll try it out. It sounds like you're talking about rasterbars. I think those were already usually working in DOSBox (I think horizontal sync is handled well enough internally). It's not synced with the host display's vertical refresh though, so in special cases it may look bad.

Edit: Qbix pointed out to me on irc that horizontal retrace is handled by a hack which doesn't really involve timing. I guess this is something else for me to look at changing if I'm going to decide to try to increase support for demos.

Reply 10 of 35, by der_ton

User metadata
Rank Newbie
Rank
Newbie

Just wanted to reply saying I'm following what you're doing here and I'm looking forward to see your progess because I'm an eager demowatcher and fan of flickerfree-scrolling myself. Thanks for your efforts!

Reply 11 of 35, by wd

User metadata
Rank DOSBox Author
Rank
DOSBox Author

I remember them as copperbars, not sure if they (all) really work in dosbox.

Reply 12 of 35, by `Moe`

User metadata
Rank Oldbie
Rank
Oldbie

I've just phoned the author, and he told me that he might have the sources for the copperbar effect lying around somewhere should anyone need it for our purposes. Moreover, google for vgacp623.zip or get it from simtel.net, that's the shareware version. The copperbar effect doesn't work (nothing at all happens with the background) in CVS.

Reply 13 of 35, by Harekiet

User metadata
Rank DOSBox Author
Rank
DOSBox Author

well that's no surprise since there is totally no handling for any of the requirements needed for those copperbars, you'd have to do all the drawing of single lines on timers. Still it could be done as some kind of optional vga switch.

Reply 14 of 35, by augnober

User metadata
Rank Member
Rank
Member

Glad to see someone's interested 😉

I'll take a bit of a break from this for Xmas/Xmas travel. Lately, I added the persistent timing that I mentioned earlier.. so you don't have to keep resyncing every time there's a change of the emulated gfx mode. Just have to do it once on startup, and have set your vsync rate once ever. I run with fullfixed=true and there's no gfx mode switch when I switch between fullscreen and windowed, so this works fine for me.

I noticed though.. I'd been running all tests on my LCD with ddraw output. This keeps the correct aspect (basically), so there are thin black bars at the top and bottom of the screen. Later, I patched my stuff with gulikoza's direct3d patch.. and noticed that if I allow the view to fill the screen, you can always see a bit of wobbly shearing at the top or bottom of the screen (your choice), or a tiny bit at both the top and bottom. This is because DOSBox's timer isn't very accurate. SDL's timer stuff is based on milliseconds, and vsync deals with numbers on the order of 15ms. I believe the non-visible time is something like 1ms... so, in order to fully fix the problem, I need to use a more accurate timer. If I can't do this, then you'll need to set your scaling to preserve some empty space at the top and/or bottom to hold the shear 😀 Running in a window can solve this too (keep it away from the edge). Anyway, this is totally solveable on Windows (QueryPerformanceCounter or better yet.. can even query the actual scanline/vsync status 😀) to make some people happy.. but SDL doesn't have the solution available. I found a more accurate cross-platform timing implementation in glfw... but that's something we'd want to get added into SDL.

One thing I want to do before making any kind of patch is.. Get the calibration tool to modify dosbox conf values. This is to avoid wasting precious hotkeys. That'll be funny.. I see no reason why executing a batch file from the program which does it wouldn't work.

blah blah blah.. Anyway, I'll be taking a break for a bit.

Reply 15 of 35, by Srecko

User metadata
Rank Member
Rank
Member

I read somewhere a tutorial which, amongst others, explains copperbars.
I think it was written bz denthor of asphyxia (demo group)

IIRC, they change palette on every hsync(end of horizontal retrace), while video memory if prepared for that before, every line has different palette color (probably sequential 8-bit values, e.g first line 0, second 1, third 2, etc.). Result is that bars appear to be scrolling.

Reply 16 of 35, by augnober

User metadata
Rank Member
Rank
Member

Thanks for the research, etc. Moe.

Don't worry about the rasterbar stuff. I remember how to do that (mostly from times I wanted to add some fun to textmode accounting-type apps for school..) I actually went through the asphyxia tutorials at that time and the rest of the PCGPE stuff. It was very useful 😀. The vsync calibration app is compiling and running, so I've got a framework to make it too. It's almost like a vsync test, except you test bit0 instead of bit3, and check for just the end of the trace instead of checking for the beginning and end (anyway, I do that part by trial and error -- can use a windows dosbox for that, assuming my app runs in one). Can do that each scanline and mess with the palette to make the changes visible. Anyway, that stuff will be a nuisance to get working in dosbox, so it'll be a while before that. I was a little confused about dosbox's ability earlier.. because Cronologia by Cascada seems to display copperbars already... but, I guess that demo's doing something different.

Reply 17 of 35, by augnober

User metadata
Rank Member
Rank
Member

I mentioned before something about not having proper stuff for testing. I forgot that I have a laptop which has a 60Hz refresh 😅 . It's slow, but I can try some things out on that. 320x240 modes tend to run at that.. and a few other things.

Reply 18 of 35, by augnober

User metadata
Rank Member
Rank
Member

Hey. Here's my first patch to add the ability to sync dosbox's emulated vsync to the host display so that you can get smooth scrolling or whatever. It's still in a development stage and isn't user friendly, I'd say.. but it's useful for some games and apps, and it may be good to get suggestions and/or feedback now. You can also make your own modifications and post them if you'd like. There's not much to it, and even then, most code could be chopped out without breaking the core functionality. There was some discussion about this earlier here:
syncing vsync to the host display

This patch can be applied over the CVS from 2005-12-20. Hopefully not much has changed since then.

The zip contains the diff file, as well as the first version of a VSYNC calibration tool to run within DOSBox (and the Watcom C source for it). The tool currently has no interaction with any settings, but it does shear a lot so it's a good program for testing your current settings.

The two new dosbox.conf values are vsyncmode and vsyncrate. After writing out your conf file, you'll see that vsyncmode can be set to "off", "on", or "force". "off" gives you regular dosbox behaviour. "on" makes dosbox's emulated vsync timer use the value that you selected, but also syncs up with the emulated gfxmode's vsync via doubling the vsync duration whenever necessary for sync. "force" will use the rate you selected, and will not bother to sync up with the emulated gfxmode's sync. Both "on" and "force" have their benefits, and "off" is of course still available (it has its benefits as well). I'm currently also overriding CTRL-F8 (unfortunately-- you can change the source to override something else if you like) and using it tweak the vsync timing offset. After enabling vsync and selecting your timing, you will need to adjust this offset on each run using CTRL-F8. Basically, use trial and error to find an accurate timing value. You'll know it's right when the shear in VSYNC.COM is stabilized. This only needs to be done once, and you can put the value in your conf file. Then press CTRL-F8 until it disappears or is at it's best -- this part must be done each run if you don't want a shear line. Or... because the hotkey is hooked up, you can press CTRL-F8 anytime, though this may not always be the case in the future. I recommend fullfixed=true so that the vsync offset won't move when you switch between windowed/fullscreen.

Probably, your display is around 60Hz, 70Hz, or 75Hz. Hopefully you have a way of selecting this (personally, I don't because my drivers don't allow it). The default is the nice round number of 75.023426, because that happens to work best on my LCD. You'll need to do some tedious trial and error -- this is still in development stage. It's best to have your display's refresh rate the same as the app you're running... and if you can't do that, then it's best to set it higher, because that's currently the only way the code is capable of properly readjusting.

Some nice tests for this are pinball games, some demos, or whatever you like. Anything where the shear may bother you, or where you feel like adjusting the emulated vsync timing.

One more thing to mention: Be aware that vsync may be enabled in your display driver (nVidia or whatever). Having driver vsync enabled will conflict with the vsync code and give you confusing and/or bad results. If you've got it in your driver, it's most likely best to disable it. Driver vsync tends to harm performance because it's done blindly and can block sound processing, etc. The vsync code doesn't have that problem and should provide better performance.

Reply 19 of 35, by augnober

User metadata
Rank Member
Rank
Member

In certain cases, you may also find that forcing sync to a value other than your host sync improves performance of an app. For example, setting sync to about 60Hz before running Crystal Dream 2 removes the flicker. This isn't very common, but could be of use to someone after video capture is added.

Speaking of flicker.. if any flicker in textmode bothers you after applying this patch, you can change the #define VGA_PARTS to 1. On my machine, I sometimes get slight flicker on vsync readjustment, but I don't care much so I leave it at the CVS value of 4.