narzoul / DDrawCompat

DirectDraw and Direct3D 1-7 compatibility, performance and visual enhancements for Windows Vista, 7, 8, 10 and 11
BSD Zero Clause License
907 stars 69 forks source link

Does DDrawCompat support 32-bit colours? #111

Closed BEENNath58 closed 1 year ago

BEENNath58 commented 3 years ago

This is one of the piece of software which allows people to play Rainbow Six (although not perfect) on my PC. However, when I compare it with Windows' DirectX, the colours are a little different. wall1 wall2 Have a look at these images, wall1 is with this wrapper and wall2 with native Windows libraries. So is DDrawCompat limiting it to 16-bit/24-bit colours or is Windows applying some kind of filter on 16-bit/24-bit colours or is Windows rendering it on 32-bit colours which DDrawCompat cannot? Also this question arrives because the Title Bar with this uses the classic style resembling that of Windows 95 when AFAIK didn't have games using 32-bit colours.

narzoul commented 3 years ago

It does look like the native Windows DWM8And16BitMitigation shim renders 16 bit modes in 32 bit colour too nowadays. I seem to recall it wasn't like that before, maybe it's a recent change, or my memory is wrong.

Anyway, DDrawCompat renders with the same colour depth as the game requests, which in this case is 16 bit, so colour banding is the "correct" behaviour. It could be mitigated with dithering, but as far as I know, modern GPU drivers don't support that anymore, even if the application enables it.

I will add an option to override the rendering colour depth in the future. Maybe in the next release, but it's probably still a couple months away.

BEENNath58 commented 3 years ago

Well the question comes trying to run Icewind Dale II, as I see no visible difference running it on 16-bit colour or 32-bit colour on this or dgVoodoo2 (or 24-bit through DxWnd)

I imagined that it was stuck in 32-bit colour on Windows DX for some reason and there would be differences in 16-bit colour but it wasn't on any wrappers I tested. So I thought the opposite happened here, that it was playing on 16-bit colour and 32-bit colours weren't working. So I gave it to thought if DDrawCompat supported 32-bit colour

narzoul commented 3 years ago

It's not a bug, I assure you. You can see the display mode that the game sets if you search for ChangeDisplaySettings in the debug logs. It's right after the resolution values (if it's null, then it switches display mode back to the desktop's settings):

Rainbow Six:

1990 10:23:45.751   > ChangeDisplaySettingsExA(null, {640,480,16,144,0}, WND(null), 4, 00000000)
1990 10:23:46.120   < ChangeDisplaySettingsExA(null, {640,480,16,144,0}, WND(null), 4, 00000000) = 0
1990 10:24:09.154   > ChangeDisplaySettingsExA(null, null, WND(null), 4, 00000000)
1990 10:24:09.712   < ChangeDisplaySettingsExA(null, null, WND(null), 4, 00000000) = 0
1990 10:24:10.056   > ChangeDisplaySettingsExA(null, {1024,768,16,144,0}, WND(null), 4, 00000000)
1990 10:24:10.519   < ChangeDisplaySettingsExA(null, {1024,768,16,144,0}, WND(null), 4, 00000000) = 0
1990 10:24:27.244   > ChangeDisplaySettingsExA(null, null, WND(null), 4, 00000000)
1990 10:24:27.539   < ChangeDisplaySettingsExA(null, null, WND(null), 4, 00000000) = 0
1990 10:24:28.869   > ChangeDisplaySettingsExA(null, {640,480,16,144,0}, WND(null), 4, 00000000)
1990 10:24:29.381   < ChangeDisplaySettingsExA(null, {640,480,16,144,0}, WND(null), 4, 00000000) = 0
1990 10:24:33.989     > ChangeDisplaySettingsExA(null, null, WND(null), 4, 00000000)
1990 10:24:34.322     < ChangeDisplaySettingsExA(null, null, WND(null), 4, 00000000) = 0

Icewind Dale 2 (32 bit):

3190 10:30:30.487   > ChangeDisplaySettingsExA(null, {1024,768,32,60,0}, WND(null), 4, 00000000)
3190 10:30:31.643   < ChangeDisplaySettingsExA(null, {1024,768,32,60,0}, WND(null), 4, 00000000) = 0
3190 10:30:55.727   > ChangeDisplaySettingsExA(null, null, WND(null), 4, 00000000)
3190 10:30:56.718   < ChangeDisplaySettingsExA(null, null, WND(null), 4, 00000000) = 0

Icewind Dale 2 (16 bit):

3318 10:32:42.564   > ChangeDisplaySettingsExA(null, {1024,768,16,60,0}, WND(null), 4, 00000000)
3318 10:32:43.740   < ChangeDisplaySettingsExA(null, {1024,768,16,60,0}, WND(null), 4, 00000000) = 0
3318 10:32:59.948   > ChangeDisplaySettingsExA(null, null, WND(null), 4, 00000000)
3318 10:33:01.147   < ChangeDisplaySettingsExA(null, null, WND(null), 4, 00000000) = 0

In Rainbow Six the colour depth is not configurable (as far as I know) so it always runs in 16 bit display modes. So if you're getting images rendered at 32 bit colour depth, then it wasn't rendered at the requested colour depth. I'm pretty sure in Windows 7 and older it would work correctly, because the DWM8And16BitMitigation shims didn't exist back then, and 16 bit colour modes were still supported by Windows. I don't know why it's forced to render natively at 32 bit nowadays, maybe you have the Disable8And16BitD3D shim enabled, or it's the default behaviour in newer versions of Windows.

You can see for yourself that the native image you posted from Rainbow Six was rendered at 32 bits. Decrease the colour depth of the image to 16 bits in an image editor (I used Irfanview) and you'll get the expected colour banding there too: 129405577-3e6cba76-115c-42a8-a8e7-01335503aa3f-16bit

As for why you don't see a difference in IWD2, well probably because it's a bad example. It's a 2D game with pre-rendered assets, and those may have been pre-rendered at 16 bits to begin with, so there's no difference when displaying them in 32 bits (unless something like bilinear stretching is used in some cases, but IWD2 probably doesn't do that).

BEENNath58 commented 3 years ago

Using Microsoft ACT, I was surprised to see no shim installed for Rainbow Six, the only being Rainbow Six 3. So that should probably mean that the current ddraw.dll for Windows uses some kind of filter to obtain 32-bit colour or renders 32-bit colour directly. Same should apply to dgVoodoo2 too.

If possible, you could add dithering support to DDrawCompat. Only a handful games support it but its still worthy to check out as a feature.

Also do you have any plans for 24-bit colours?

narzoul commented 1 year ago

v0.4.0 adds a RenderColorDepth setting. I don't plan to add a separate dithering option, since it seems pretty redundant to me.