[DDRAW] Take RGB mask into account when doing color keying

Christian Costa titan.costa at wanadoo.fr
Tue Aug 16 15:49:11 CDT 2005


Hi,

This patch fixes transparency in Black Mirror demo.

Changelog:
Take RGB mask into account when doing color keying.
Add corresponding conformance test.

Christian Costa   titan.costa at wanadoo.fr

-------------- next part --------------
Index: dlls/ddraw/surface_dib.c
===================================================================
RCS file: /home/wine/wine/dlls/ddraw/surface_dib.c,v
retrieving revision 1.5
diff -u -r1.5 surface_dib.c
--- dlls/ddraw/surface_dib.c	3 Aug 2005 21:25:11 -0000	1.5
+++ dlls/ddraw/surface_dib.c	16 Aug 2005 19:29:15 -0000
@@ -819,7 +819,7 @@
 	    }
 	} else {
            LONG dstyinc = ddesc.u1.lPitch, dstxinc = bpp;
-           DWORD keylow = 0, keyhigh = 0;
+           DWORD keylow = 0, keyhigh = 0, keymask = 0;
            if (dwFlags & (DDBLT_KEYSRC | DDBLT_KEYDEST | DDBLT_KEYSRCOVERRIDE | DDBLT_KEYDESTOVERRIDE)) {
 
 	      if (dwFlags & DDBLT_KEYSRC) {
@@ -835,7 +835,8 @@
 		 keylow  = lpbltfx->ddckDestColorkey.dwColorSpaceLowValue;
 		 keyhigh = lpbltfx->ddckDestColorkey.dwColorSpaceHighValue;
 	      }
-              dwFlags &= ~(DDBLT_KEYSRC | DDBLT_KEYDEST | DDBLT_KEYSRCOVERRIDE | DDBLT_KEYDESTOVERRIDE);
+	      keymask = sdesc.u4.ddpfPixelFormat.u2.dwRBitMask | sdesc.u4.ddpfPixelFormat.u3.dwGBitMask | sdesc.u4.ddpfPixelFormat.u4.dwBBitMask;
+	      dwFlags &= ~(DDBLT_KEYSRC | DDBLT_KEYDEST | DDBLT_KEYSRCOVERRIDE | DDBLT_KEYDESTOVERRIDE);
            }
 
            if (dwFlags & DDBLT_DDFX)  {
@@ -919,7 +920,7 @@
                dx = d; \
 	       for (x = sx = 0; x < dstwidth; x++, sx += xinc) { \
 		  tmp = s[sx >> 16]; \
-		  if (tmp < keylow || tmp > keyhigh) dx[0] = tmp; \
+		  if ((tmp & keymask) < keylow || (tmp & keymask) > keyhigh) dx[0] = tmp; \
                   dx = (type*)(((LPBYTE)dx)+dstxinc); \
 	       } \
                d = (type*)(((LPBYTE)d)+dstyinc); \
@@ -938,7 +939,7 @@
 			DWORD pixel;
 			s = sbuf+3*(sx>>16);
 			pixel = s[0]|(s[1]<<8)|(s[2]<<16);
-                        if (pixel < keylow || pixel > keyhigh){
+                        if ((pixel & keymask) < keylow || (pixel & keymask) > keyhigh) {
 		            dx[0] = (pixel    )&0xff;
 			    dx[1] = (pixel>> 8)&0xff;
 			    dx[2] = (pixel>>16)&0xff;
Index: dlls/ddraw/tests/dsurface.c
===================================================================
RCS file: /home/wine/wine/dlls/ddraw/tests/dsurface.c,v
retrieving revision 1.4
diff -u -r1.4 dsurface.c
--- dlls/ddraw/tests/dsurface.c	20 Jun 2005 14:18:05 -0000	1.4
+++ dlls/ddraw/tests/dsurface.c	16 Aug 2005 19:29:33 -0000
@@ -2,6 +2,7 @@
  * Unit tests for (a few) ddraw surface functions
  *
  * Copyright (C) 2005 Antoine Chavasse (a.chavasse at gmail.com)
+ * Copyright (C) 2005 Christian Costa
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -153,10 +154,77 @@
     IDirectDrawSurface_Release(lpDDSMipMapTest);
 }
 
+static void SrcColorKey32BlitTest(void)
+{
+    LPDIRECTDRAWSURFACE lpSrc;
+    LPDIRECTDRAWSURFACE lpDst;
+    DDSURFACEDESC ddsd;
+    DDSURFACEDESC ddsd2;
+    LPDWORD lpData;
+    HRESULT rc;
+
+    ddsd2.dwSize = sizeof(ddsd2);
+    ddsd2.ddpfPixelFormat.dwSize = sizeof(ddsd2.ddpfPixelFormat);
+
+    ddsd.dwSize = sizeof(ddsd);
+    ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
+    ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
+    ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
+    ddsd.dwWidth = 800;
+    ddsd.dwHeight = 600;
+    ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
+    U1(ddsd.ddpfPixelFormat).dwRGBBitCount = 32;
+    U2(ddsd.ddpfPixelFormat).dwRBitMask = 0xFF0000;
+    U3(ddsd.ddpfPixelFormat).dwGBitMask = 0x00FF00;
+    U4(ddsd.ddpfPixelFormat).dwBBitMask = 0x0000FF;
+    rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpDst, NULL);
+    ok(rc==DD_OK,"CreateSurface returned: %lx\n",rc);
+
+    ddsd.dwFlags |= DDSD_CKSRCBLT;
+    ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = 0xFF00FF;
+    ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = 0xFF00FF;
+    rc = IDirectDraw_CreateSurface(lpDD, &ddsd, &lpSrc, NULL);
+    ok(rc==DD_OK,"CreateSurface returned: %lx\n",rc);
+    
+    rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
+    ok(rc==DD_OK,"Lock returned: %lx\n",rc);
+    lpData = (LPDWORD)ddsd2.lpSurface;
+    lpData[0] = 0xCCCCCCCC;
+    lpData[1] = 0xCCCCCCCC;
+    lpData[2] = 0xCCCCCCCC;
+    lpData[3] = 0xCCCCCCCC;
+    rc = IDirectDrawSurface_Unlock(lpDst, NULL);
+    ok(rc==DD_OK,"Unlock returned: %lx\n",rc);
+
+    rc = IDirectDrawSurface_Lock(lpSrc, NULL, &ddsd2, DDLOCK_WAIT, NULL);
+    ok(rc==DD_OK,"Lock returned: %lx\n",rc);
+    lpData = (LPDWORD)ddsd2.lpSurface;
+    lpData[0] = 0x77010203;
+    lpData[1] = 0x00010203;
+    lpData[2] = 0x77FF00FF;
+    lpData[3] = 0x00FF00FF;
+    rc = IDirectDrawSurface_Unlock(lpSrc, NULL);
+    ok(rc==DD_OK,"Unlock returned: %lx\n",rc);
+
+    IDirectDrawSurface_Blt(lpDst, NULL, lpSrc, NULL, DDBLT_KEYSRC, NULL);
+
+    rc = IDirectDrawSurface_Lock(lpDst, NULL, &ddsd2, DDLOCK_WAIT, NULL);
+    ok(rc==DD_OK,"Lock returned: %lx\n",rc);
+    lpData = (LPDWORD)ddsd2.lpSurface;
+    ok((lpData[0]==0x77010203)&&(lpData[1]==0x00010203)&&(lpData[2]==0xCCCCCCCC)&&(lpData[3]==0xCCCCCCCC),
+       "Destination data after blitting is not correct\n");
+    rc = IDirectDrawSurface_Unlock(lpDst, NULL);
+    ok(rc==DD_OK,"Unlock returned: %lx\n",rc);
+
+    IDirectDrawSurface_Release(lpSrc);
+    IDirectDrawSurface_Release(lpDst);
+}
+
 
 START_TEST(dsurface)
 {
     CreateDirectDraw();
     MipMapCreationTest();
+    SrcColorKey32BlitTest();
     ReleaseDirectDraw();
 }


More information about the wine-patches mailing list