VOGONS

Common searches


VIDEO Patch for pixel-perfect scaling (SDL1)

Topic actions

First post, by Ant_222

User metadata
Rank Oldbie
Rank
Oldbie

Patch status:
This patch is currently abandoned. Having grown tired of keeping the patch in sync with the official SVN, I have decided to work on similar functionality in unofficial forks of DOSBox.

DOSBox forks containing the patch:

Compatibility problems:

  • Incompatible with munt's MT32 patch on the level of an automake script. Here is a fixed version by marooned_on_mars.

Build notes:

  • Whereas the patch implements a single-threaded software-based scaler, it is inherently slow, with performance decreasing in quadratic proportion to the output resolution. To make the most out of it, compile the file src/gui/pixelscale.cpp with a sufficiently high optimization level. For GCC on my system (AMD A4-3400 APU) it is -O3, which is one level higher than the setting used in the default DOSBox configuration. Please, use the test program to determine your best compiler settings.

Projected featrues:

  • If pixel-perfect correction is unsatisfactory, either because of a large aspect-ratio error or because of insufficient magnification, fall-back to a simpler scaling mode, such as nearest-neighbor. The secondary scaling mode and the exact criterium for the fallback may be specified in the config file.—lukeman3000

Other implementations of pixel-perfect scaling in DOSBox:

  1. DOSBox for pixel purists by bladeSk uses nearest-neighbor interpolation already available via the openglnb output mode confining the output to an area calculated to result in integer scaling with optional aspect-ratio correction. This fork also adds V-Sync on Windows Vista and later by emulating full-screen mode as a borderless window.

See also:

  1. Clint of sierrawallpaper.com applies pixel-perfect correction to his screenshots in exactly the same way as this patch does. Look for images marked ARC (for aspect-ratio corrected).
  2. No, MS-DOS games weren't widescreen: Tips on correcting aspect ratio, by Felipe Pepe.
  3. Nonblurry integer-ratio scaling by Marat Tanalin.

Change log:

  • Uploading the Windows binary and the diff patch. The algorithm now respects the aspect setting.
  • This was required to play games whose native pixel aspect ratio is different from the one DOSBox assumes. Lure of the Temptress seems one of them.
  • If there be a place for credits in DOSBox, then let me thank Peter Karpov, known on Reddit as inversed, for the idea of the heuristic algorithm for the calculation of optimal scaling factors.
  • Fixed the patch. It had been generated incorrectly.
  • Fixed an error in the source which prevented compiling with Direct-Draw support enabled.
  • Fixed the patch. It was malformed.
  • Added a missing curly bracket.
  • Fixed a typo in code for DirectDraw output.
  • Uploaded a win32 build with the alpha 4 patch.
  • [2016-09-18] Uploaded the alpha 4 patch.
  • [2016-09-19] Fixed the alpha 4 patch
  • [2016-10-12] Uploaded the alpha 5 patch, which now extends the surface output type.
  • [2016-10-12] Added missing DLLs to the binary archive.
  • Uploaded the alpha 6 patch, which fixes a bug which broke the surface output type and has improved handling of the doubleheight and doublewidth flags.
  • [2016-10-13] Uploaded the alpha 7 patch, which fixes errors with the blitting output mode.
  • [2016-10-14] Uploaded the alpha 8 patch with performance improvements.
  • [2016-11-04] Uploaded the alpha 9 patch with new defaults and minor tweaks.
  • [2016-11-07] Alpha 10 is out. It fixes a typo which disabled the overlay output and corrects the upscaling of update rectangles.
  • [2016-11-19] Fixed errors in alpha10 when compiling on Linux with newer versions of gcc.
  • [2016-11-21] Added munt's MT32 patch fixed to be compatible with the pixel-perfect patch.
  • [2017-01-28] Uploaded alpha 12, which fixes an error in the calculation of the "perfect" scale. Special thanks to KainXVIII for extensive testing.
  • [2017-08-25] Releasing alpha 13, in which:
    1. the scaling algorithm is optimised and performs about 25-40% faster, depending on the CPU,
    2. different layouts of RGB data within 4-byte blocks are now taken into account,
    3. a rounding error fixed which sometimes caused incorrect scaling.
  • [2017-09-01] Alpha 14: A better correction of the rounding error.
  • [2017-11-04] Alpha 14 fixed for compatibility with revision 4063 (by Yesterplay80).
  • [2018-04-19] Alpha 14 fixed for compatibility with revision 4095 (thanks to Yesterplay80).
  • [2018-07-15] Alpha 14 fixed for compatibility with revision 4132 (fix by Yesterplay80).
  • [2018-09-02] Alpha 14 fixed for compatibility with revision 4157.
  • [2018-09-22] Alpha 14 fixed for compatibility with revision 4163, and an missing return reinstated (thanks to aaronp)
  • [2019-01-07] Alpha 15 allocates intermediate memory globally rather than for each frame and restores compatibility after rev. 4178.
  • [2019-01-19] Alpha 16 adds a hardware-accelerated mode for pixel-perfect scaling—openglpp.
  • [2019-01-20] Alpha 17 fixes some unusual cases of aspect-ratio correction (e.g. the dial9 demo).
  • [2019-01-21] Alpha 18 turns on V-Sync for OpenGL output.
  • [2019-01-22] Alpha 19 adds an option to turn V-Sync on and off for OpenGL output.
  • [2019-01-26] Alpha 20 adds an option to emulate fullscreen mode as a borderless window (thanks to bladeSk for the idea) [deleted because of a bug]
  • [2019-01-30] Alpha 21 fixes the screen clearing bug in alpha 20.
  • [2019-02-03] Alpha 21 fixed for compatibility with revision 4185.
  • [2019-02-07] Alpha 22 fixed a bug (a function with a non-void return type not returning anything)—thanks to aaronp.
  • [2019-02-02] Alpha 23 fixes another bug, this time in the handling of non-fixed resolutions—thanks again to aaronp.
  • [2019-07-28] Incorporate revisions 4228-2449 into alpha 23. It now works with rev. 4253.
  • [2019-07-28] Alpha 24 fixes a bug with non-integer scaling modes surfacenb and surfacenp.

Original message:
I can't seem to find the code responsible for the stretching of the image to the display dimensions in full-screen mode, and neither do I see any invocations of SDL scaling functions. Where is does it happen?

Attachments

Last edited by Ant_222 on 2023-07-26, 18:11. Edited 100 times in total.

Reply 1 of 733, by Qbix

User metadata
Rank DOSBox Author
Rank
DOSBox Author

sdlmain.cpp and render.cpp are responsible for the stuff you want.

Good luck digging around.

Water flows down the stream
How to ask questions the smart way!

Reply 2 of 733, by Ant_222

User metadata
Rank Oldbie
Rank
Oldbie

Thanks. I had already read those files, but it is hardware scaling that I am talking about, and I can't find where in the code it is performed or enabled. It depends on the type of the output surface, but where is this dependency expressed?

Reply 3 of 733, by ripa

User metadata
Rank Oldbie
Rank
Oldbie

For example, sdlmain.cpp GFX_EndUpdate:

#if (HAVE_DDRAW_H) && defined(WIN32)
case SCREEN_SURFACE_DDRAW:
SDL_UnlockSurface(sdl.blit.surface);
ret=IDirectDrawSurface3_Blt(
sdl.surface->hwdata->dd_writebuf,&sdl.blit.rect,
sdl.blit.surface->hwdata->dd_surface,0,
DDBLT_WAIT, NULL);

DirectDraw does the HW scaling when source and destination surfaces have different dimensions.

Reply 4 of 733, by Ant_222

User metadata
Rank Oldbie
Rank
Oldbie

Thank you, ripa. That's what I mean by implicit. The same thing seems to take place with YUV overlays. I am trying to implement pixel-perfect integer scaling for full-screen mode, and I fear I shall have manually to convert the source image into an overlay or source surface with the dimensions equal to those of the target surface. That is going to be a relatively slow operation, but nothing better seems possible in SDL older than v. 2.

Reply 5 of 733, by ripa

User metadata
Rank Oldbie
Rank
Oldbie

There's output=openglnb which does not use filtering, so it's "pixel perfect", but if the destination dimensions aren't integer multiples of the source's, the pixels will be "uneven". There's also normal2x and normal3x software scalers which you can use in conjunction with output=surface which does not do scaling. So you'll be implementing something like normal4x (because there's already a patch for that somewhere)? Or normal3x2y or something like that (different x and y scaling factors)?

Reply 6 of 733, by Ant_222

User metadata
Rank Oldbie
Rank
Oldbie

In other words, openglnb is not pixel-perfect at non-integer scales, which is almost always the case in full-screen mode. The 'normal' scalers produce pixel-perfect image only with the 'surface' output device, and even then they don't always work (e.g. with double-height modes such as used in Romance of the Three Kingdoms). The very design of those scalers is wrong because new ones should be added manually as new resolutions appear. For example, "The Lure of the Temptress" running at 320x200 requires a 5x upscaling on my 1680x1050 display.

In my modification the best integer scale is calculated automatically, and I think I will manage to implement automatic pixel-perfect aspect correction as well. Here are screenshots from "Lure of the Temptress" and "Romance of the Three Kingdoms" running in fullscreen in the modified DOSBox with scaler=none and output=overlay.

I believe pixel-perfect scaling with aspect correction should be implemented in a general way as in my modification instead of hard-coding every one of them. Will such a patch be accepted?

Last edited by Ant_222 on 2016-07-31, 18:46. Edited 1 time in total.

Reply 7 of 733, by KainXVIII

User metadata
Rank Member
Rank
Member

Nice work!
I still use old stable ykhwong build for pixel-perfect scaling (direct3d, bilinear.fx and normal5x scaler), maybe your method will be much better..

Reply 8 of 733, by Ant_222

User metadata
Rank Oldbie
Rank
Oldbie
KainXVIII wrote:

Nice work!
I still use old stable ykhwong build for pixel-perfect scaling (direct3d, bilinear.fx and normal5x scaler), maybe your method will be much better..

Thanks. It depends on how ykhwong implemented the scaling. Is it generic or does it have hard-coded integer scales? I didn't understand the "direct3d, bilinear.fx" part. Why are there different builds and patches scattered around but none of them included in the release?

Reply 9 of 733, by Scali

User metadata
Rank l33t
Rank
l33t
Ant_222 wrote:

In other words, openglnb is not pixel-perfect at non-integer scales

Well, it's pretty much a given that if you don't scale with integers, you can't have pixel-perfect stretching, that's by definition 😀
But I suppose you mean to say you want to have a 'nearest integer fit'.
How do you intend to handle differences in aspect ratio though? There are various different video modes in CGA/EGA/VGA/SVGA, and they can have different aspect ratios.
So in the cases where your fullscreen mode's aspect ratio does not match the aspect ratio of the emulated video mode, you can at best have a 'nearest integer fit' only in one direction, either X or Y.
Alternatively, you can have integer scaling for both, but you will distort the aspect ratio.

So how do you intend to handle that case?

http://scalibq.wordpress.com/just-keeping-it- … ro-programming/

Reply 10 of 733, by Ant_222

User metadata
Rank Oldbie
Rank
Oldbie
Scali wrote:

Well, it's pretty much a given that if you don't scale with integers, you can't have pixel-perfect stretching, that's by definition :)
But I suppose you mean to say you want to have a 'nearest integer fit'.

I simply find the largest integer scale that keeps the image within the display. For example, if I need to scale a 320x200 image to my 1680x1050 monitor, I use a scale of 5 and get a 1600x1000 image with think black borders (as shown above).

Scali wrote:

How do you intend to handle differences in aspect ratio though? There are various different video modes in CGA/EGA/VGA/SVGA, and they can have different aspect ratios.

You mean non-square pixels? I plan to approximate them by representing each pixel on the display as an m-by-n rectangle, where m and n are small natural numbers.

Scali wrote:

So in the cases where your fullscreen mode's aspect ratio does not match the aspect ratio of the emulated video mode, you can at best have a 'nearest integer fit' only in one direction, either X or Y.
Alternatively, you can have integer scaling for both, but you will distort the aspect ratio.

That's right. The current version only supports uniform scaling, but I do plan to implement the nearest integer fit also. My algorithm already uses separate x and y scales, but I have yet to pass to it the necessary parameters to calculate them depending on the original aspect ratio.

Reply 11 of 733, by KainXVIII

User metadata
Rank Member
Rank
Member
Ant_222 wrote:
KainXVIII wrote:

Nice work!
I still use old stable ykhwong build for pixel-perfect scaling (direct3d, bilinear.fx and normal5x scaler), maybe your method will be much better..

Thanks. It depends on how ykhwong implemented the scaling. Is it generic or does it have hard-coded integer scales? I didn't understand the "direct3d, bilinear.fx" part. Why are there different builds and patches scattered around but none of them included in the release?

Sorry, i don't know what method he uses, but its works

"direct3d, bilinear.fx" part

Its dosbox.conf settings for pixel perfect scaling which i use

output=direct3d pixelshader=bilinear.fx aspect=true scaler=normal5x […]
Show full quote

output=direct3d
pixelshader=bilinear.fx
aspect=true
scaler=normal5x

Reply 13 of 733, by KainXVIII

User metadata
Rank Member
Rank
Member
Ant_222 wrote:

KainXVIII, could you post screenshots of "Lure of the Temptress" and "Romance of the Three Kingdoms" running in full-screen on your DOSBox so that I might compare them with mine?

Here LOT and SQ3 (ROTK is harder to get =) )
PS - maybe not so perfect as i think..

Attachments

  • lurafalse.png
    Filename
    lurafalse.png
    File size
    283.21 KiB
    Views
    19397 views
    File license
    Fair use/fair dealing exception
  • sq3.png
    Filename
    sq3.png
    File size
    47.11 KiB
    Views
    19398 views
    File license
    Fair use/fair dealing exception
  • lure.png
    Filename
    lure.png
    File size
    214.19 KiB
    Views
    19401 views
    File license
    Fair use/fair dealing exception
Last edited by KainXVIII on 2016-07-31, 19:43. Edited 2 times in total.

Reply 16 of 733, by Ant_222

User metadata
Rank Oldbie
Rank
Oldbie
KainXVIII wrote:
Ant_222 wrote:

KainXVIII, could you post screenshots of "Lure of the Temptress" and "Romance of the Three Kingdoms" running in full-screen on your DOSBox so that I might compare them with mine?

Here LOT and SQ3 (ROTK is harder to get =) )
PS - maybe not so perfect as i think..

Woops — Neither of them is pixel-perfect. Here's an 8x-magnified fragment of LOT. You can see that it is blurry.

Reply 17 of 733, by KainXVIII

User metadata
Rank Member
Rank
Member
Ant_222 wrote:
KainXVIII wrote:
Ant_222 wrote:

KainXVIII, could you post screenshots of "Lure of the Temptress" and "Romance of the Three Kingdoms" running in full-screen on your DOSBox so that I might compare them with mine?

Here LOT and SQ3 (ROTK is harder to get =) )
PS - maybe not so perfect as i think..

Woops — Neither of them is pixel-perfect. Here's an 8x-magnified fragment of LOT. You can see that it is blurry.

Welp 😢