a bilinear filter for old ddraw games?

1 2 > >> (Page 1 of 2)
  • gsky916

    gsky916 - 2014-07-10

    I am glad to post some interesting topic rather than issue reports :D
    Yesterday when i was searching on the Internet, i found a project called ddhack(http://sol.gfxile.net/ddhack/). I think you could already known the author jarikomppa.

    I found he implemented a bilinear filter for old ddraw games in this tiny wrapper dll.
    See this:

    Curiously, how this works.
    People would glad to see their old games with lots of pixel blocks get a better graphic.

  • gho

    gho - 2014-07-10

    I already contacted Jari Komppa, who very kindly said he had nothing against learning from his ddhack and copy ideas and source code into DxWnd.
    As a matter of fact, I believe at least a couple of tricks come from his work.
    About bilinear filtering, I did not copy that idea because DxWnd uses ddraw blitting to stretch from the emulated surface to the real one, and this is supposed to be handled by ddraw, that is by hardware, in a more efficient way and with all the filtering that your card is able to support.
    The only drawback is that apparently there's no way to control this and ask for a better algorythm. But ddraw hardware acceleration is normally adequate, and the sort of pictures you get form a low resolution game stretched to fullscreen usually show clearly that filtering is used.
    There must be here somewhere an old post already (who knows when and by who...) talking about the same issue.

  • gsky916

    gsky916 - 2014-07-11

    Thanks for the explanation!

  • gsky916

    gsky916 - 2014-07-13

    I saw several blogs claim that set StretchBlt to Halftone mode will give you a much better graphic(bilinear like result), is that true?

    • gho

      gho - 2014-07-16

      It's possible ....
      I'll test this sooner or later. The problem is that StretchBlt can be used as a replacement of GDI BitBlt, that is horrible, and totally abandoned by modern games. So, it can't be an improvement for directdraw games, that in my opinion are using a better blitter already.

      • gsky916

        gsky916 - 2014-07-17

        Thanks for the reply.

        Sorry for that i can not follow your mind, would you clarify:
        1.Why StretchBlt is horrible?
        2.What kind of stretch method are dxwnd dealing with directdraw games?(I saw StretchBlt are using in dxwnd source code)

        P.S. I think directdraw games are using nearest-neighbor by default?

        • gho

          gho - 2014-07-17
          1. Wait until I find some screenshots of scaled StretchBlt pictures and you'll see... maybe in halftone it's much better. I'll try.
          2. Actually I don't know.... it seems there's no way to TELL directdraw to use a particular stretching filter programmatically (some cards allow you to configure it via their configuration tools). If you know how to do that, please share...
          • gsky916

            gsky916 - 2014-07-18

            Sorry i made it wrong, I supposed dxwnd are using StretchBlt to stretch the window(I saw it in the source code), that's why i made the previous post.

            If we don't know what kind of method are directdraw using, there is no way to do the investigation.

            Last edit: gsky916 2014-07-18
  • aqrit

    aqrit - 2014-07-13

    DXGL allows custom shaders?

    I've been hoping to see a standard shader format emerge...
    so a user could use a shader with SDL2, dosbox, scummvm, snes emu, etc.

    an eye on the future... "emulate primary surface" -> upload to OpenGL -> custom shader -> to screen

  • gho

    gho - 2014-07-16

    Despite the fact that I thought directdraw was making its best to scale a surface, I tried just for fun to implement the dumbest possible bilinear filter, the one that splits one pixel in 4, each one being the average between itself and the adiacent pixels (left, bottom, bottom left).
    The result is somehow surprisingly good, even if above 640x480 the whole thing becomes rapidly useless and very heavy.
    Here are the results. Judge by yourself. screenshots _a.png are without filtering, the _b.png ones are filtered. You need to enlarge the pictures to see the difference.


    I noticed that there must be something wrong in the simplified filtering because the filtering of even / odd lines is not smooth (notice a vertical saw-teeth effect...). Hopefully, it should disappear as soon as I'll have some more time to think about it...

    Last edit: gho 2014-07-17
  • gho

    gho - 2014-07-17

    A preliminary bilinear filtering is now available in new DxWnd release v2.02.86.

    It works only on palettized 8BPP directdraw games, and it is more efficient and performant for low resolution games (let's say, below 640 x 480 !)

    gsky916: I had to translate "bilinearfiltering" to chinese using google translator. Feel free to propose a better translation...

    here come some screenshots.

    • gsky916

      gsky916 - 2014-07-18

      Very well translation :)

  • gsky916

    gsky916 - 2014-09-14

    Hi, gho, i decide to move a previous post to here, can you help to delete the previous one?
    I should not mess up the aero topic(too excited yesterday):
    I dont know if this suggestion has possibility, need your evaluation, but i hope it will not give you more pressure.

    I just get some new thought, I decide to make following suggestion:

    That is could dxwnd provide 3 different mode for bilinear filter?

    1280x960 backbuffer for large screen (1920x1080) (Now we are using)
    1024x768 backbuffer for medium screen (between 1366x768 - 1920x1080)
    800x600 backfuffer for small screen (less than 1366x768)

    These are the three mostly common used window size in now times.

    The backfuffer size should be a static value, so no dynamic value need to be calculate.
    Not like a dynamic scaled bilinear filter, it just provide 2 more static bilinear filter!
    Algorithm may be the same, only some parameter need to be changed to fit the specific mode?
    I dont know if this still need floating point calculations?
    You can let user to specify the mode by editing the ini file with a parameter(like the hot key).

    The Benefit is:

    1) Performance
    People who only need a small window don't need to use a 1280x960 backbuffer to process bilinear filter, then scale down, it could be a waste of performance.

    2) Better graphic quality
    A 1280x960 bilinear graphic scale down to a lower size will make the graphic over blur, pixel overlapped together.

    3) fps/time on overlay
    After scale down lower size, fps/time on overlay will become too small to clearly see the figure.

    • gho

      gho - 2014-09-14

      The simple fact is that you can multiply or divide by 2 by a bit shifting operation, while any other operation requires longer calculations.
      But I must admit that my concerns about performances were almost wiped away simply placing all surfaces in system memory! So maybe it's worth a try...
      But it's not as simple as it seems. I'll see what I will be able to do...

  • gsky916

    gsky916 - 2014-09-30

    Hi, gho.

    Thanks to the coming national holiday, i finally get some time to re-consider this suggestion.
    I must admit i didn't study the algorithm before i made the above suggestion, so it is not really a scientific thought, more like an imagination..sigh...

    After search on the Internet to get some more information about bilinear filter,i found the following piece of code for C/C++ (Visual Studio):


    This one is generally a 2x2 bilinear interpolation code, contains schema for downsize sampling and a MMX optimization(30% performance boost), all with clear comments!

    I didn't read the bilinear source of dxwnd(don't know where it located), so I'm not sure if you would get some reference from this piece... I hope so...

    I would be glad to hear from you!

  • gsky916

    gsky916 - 2014-09-30

    Interesting...Why the Post need moderation?
    Gho, is that you added this moderation system, or SourceForge?

    In case my post can not pass the moderation, I'd like to attached a copy of my post here(use the txt file), please check, thanks in advance!

    Last edit: gsky916 2014-09-30
    • gho

      gho - 2014-09-30

      The moderation comes (by default, I guess...) from sourceforge and for sure it is also buggy (it keeps telling me I have 1 message to moderate, but I can't read it!).
      I don't know how how to operate with it so I generally avoid even entering the function. In any case, your post is here above, so it's sort of a happy ending, isn't it?
      Thank you for the bilinear source code: after I discovered that most of emulation inefficiency was blown away by means of a proper use of DDSCAPS_SYSTEMMEMORY attribute, I was reconsidering all my plans and thinking to evaluate a full bilinear blit integrated in DxWnd. This code could be very useful.

      You'll get some news from me soon, because I'm adding extra flags (and translations!) to next DxWnd release.

      bye ;)

      Last edit: gho 2014-09-30
  • ivdok

    ivdok - 2014-09-30

    I like the idea for 3 different backbuffers for blurring/filtering, but I also hope that this would be toggleable. Because, well, I have 1280x1024 resolution and a decent enough PC, so I'd like to stay with 1280x960 - small stretches at up&down don't bother me. They never did, in fact - I frequently use Wine that way.

    • gho

      gho - 2014-09-30

      Oh, my! If you go through all the mess of DxWnd configurable menus, checkboxes, radiobuttons and fields, I think that "lack of toggleability" would be the very last of the possible critics that could came to your mind...
      But yes, if it will ever happens, each new feature will be toggleable, I promise!

  • gho

    gho - 2014-09-30

    Hi, gsky916.
    I promised some news, and I think this is a very good one!
    Here are the screenshots from a very preliminary integration of the source code you handed me and DxWnd. The three screenshots are from Age of Empires 2, in 3 different modes:

    o dx: the default ddraw stretching filter
    o gho: my 2x stretching filter already integrated in DxWnd
    o custom: the new one

    the exciting thing is that the new algorythm has better quality, but also seems quicker than mine and also quicker than the defaul ddraw one! It could be enough to throw all others away, but we'll see...
    Take a look: to appreciate the differences, of course you need to enlarge the pictures, or pick a small piece.

    • gho

      gho - 2014-10-01

      A small update: three smaller pics to make the differences more evident. Same naming convention.
      The improvement in text readability (see for instance the "Microsoft" black text on the banner) is impressive.

      Last edit: gho 2014-10-01
  • gsky916

    gsky916 - 2014-10-01

    Haha, sorry for the delay, today is quite a busy day ;)
    I just get a little time and finished the translation task firstly :D

    I think this piece of code had been rewrite and tested for several times(just like the author said), so i was expected this could give you some reasonable reference, but I must say the result is really surprising, i didn't expect that good! Quicker than the default ddraw one, better quality than yours!

    It's very inspiring when compare between the snapshots!
    In fact I'm eager to see some real effect on PC, but I should not give you pressure :D

    It's quite late now, some sleep is needed, see you tomorrow~

  • gho

    gho - 2014-10-01

    The bilinear filtering integration proceeds quite smoothly.
    I fixed a first problem about scaling to odd sized surfaces.
    Now at least two remain:
    1) handling bilinear blitting to partial rectangles: unfortunately, not all games performs a full surface blit or flip operation. See attached screenshot
    2) porting the algorythm to 16BPP surfaces (if anyone is still interested...)

    One note: I was somehow deceived in my first speed impression. Measured results make a little more sense. Here are some FPS values taken from Warcraft II main menu screen scaled to the full desktop area of my pc (1920 x 1080)

    bilinear filtering: 8 FPS
    my 2x simplified filtering: 16 FPS
    no bilinear filtering, just dx default stretching: 42 FPS

    likely, all three options will stay in DxWnd, to let anyone to make his choice about speed vs. quality.

    Last edit: gho 2014-10-01
  • gsky916

    gsky916 - 2014-10-02

    Please add 16BPP support.
    Till now the performance conclusion is not that clear...Seems there is big difference under different cases( games/resolutions)

    • gho

      gho - 2014-10-02

      Sure I will do.
      But the missing 16BPP support in NOT needed for 16BPP games (their output is virtualized to 32BPP screen already, so for instance WFSP that runs natively on 16BPP is supported already - I must remember to send you a preview of the beauty screenshots with this new algorythm) but only for desktops set to 16BPP, that is a configuration that Win7 scarcely supports and Win8 supports no longer. And if one doesn't have a powerful machine to support 32BPP, I doubt he has enough CPU power to appreciate bilinear filtering! So, this should not be a big loss for anyone.

      Now I'm busy about an interface update for the bilinear filter that will take a while, but will fix a lot of troubles. The problem is that the algorithm operates on a contiguous pixel matrix that has a structure similar to the pixel disposition on a memory surface, but not identical: one difference is when the size of the rectangle is odd: ddraw organizes the space rounding the rows to the closest even size, but the filter doesn't know that. Also, the filter can't operate on a rectangular area contained within a surface (see the fifa 99 screenshot above). Currently, I made workarounds to handle these problems, but the implementation is more cumbersome and less efficient. So I need a little calm to modify the procedure to handle ddraw surfaces properly.

      About performances: don't take my figures too seriously: I may even have made something wrong on the handling of the surface type. Let's see. But consider that there could be a reason for variable performance ratios: my 2x bilinear filter in practice scales for a x2 factor and then stretches to the desired screen size, so the filtering itself is absolutely independent from the target size. On the contrary, the new bilinear filter scales to the actual window size, so its performances are heavily affected from this parameter. In conclusion, there is a reasonable possibility that the two algorithms are more or less efficient depending on target size. Also, the 8FPS figure I reported is taken in a very heavy condition (1920 x 1080 pixels!) and from a not very powerful pc. But don't worry: in a short while you'll be able to judge by yourself... ;)

1 2 > >> (Page 1 of 2)

Log in to post a comment.