Fix for [bug 829] DIB_DirectDrawSurface_Blt same src./dest. surface = screen corruption

Tony Lambregts tony_lambregts at telusplanet.net
Tue Jul 2 17:57:04 CDT 2002


Change log:  Fix screen corruption when source and destination are the 
same surface and areas are the same size.

Tony Lambregts  tony_lambregts at telusplanet.net


-------------- next part --------------
Index: dib.c
===================================================================
RCS file: /home/wine/wine/dlls/ddraw/dsurface/dib.c,v
retrieving revision 1.11
diff -u -r1.11 dib.c
--- dib.c	28 Jun 2002 17:32:25 -0000	1.11
+++ dib.c	2 Jul 2002 23:53:43 -0000
@@ -351,6 +351,9 @@
     int bpp, srcheight, srcwidth, dstheight, dstwidth, width;
     int x, y;
     LPBYTE dbuf, sbuf;
+    BOOL SameSurface = FALSE;
+
+    if (src == iface) SameSurface = TRUE;
 
     TRACE("(%p)->(%p,%p,%p,%08lx,%p)\n", This,rdst,src,rsrc,dwFlags,lpbltfx);
 
@@ -475,6 +478,17 @@
 	xinc = (srcwidth << 16) / dstwidth;
 	yinc = (srcheight << 16) / dstheight;
 
+        if (SameSurface)
+        {
+	   static BOOL WarnSurface = FALSE;
+	   if (!WarnSurface)
+	      {
+              FIXME("\tSame source and destination could cause display problems\n");
+              WarnSurface = TRUE;
+              }
+	}
+
+
 	if (!dwFlags) {
 	    /* No effects, we can cheat here */
 	    if (dstwidth == srcwidth) {
@@ -482,11 +496,24 @@
 		    /* No stretching in either direction. This needs to be as
 		     * fast as possible */
 		    sbuf = sbase;
-		    for (y = 0; y < dstheight; y++) {
-			memcpy(dbuf, sbuf, width);
-			sbuf += sdesc.u1.lPitch;
-			dbuf += ddesc.u1.lPitch;
-		    }
+                    if ((SameSurface) && (sbuf <= dbuf)) {
+
+                       sbuf += (sdesc.u1.lPitch*dstheight);
+                       dbuf += (ddesc.u1.lPitch*dstheight);
+
+		       for (y = 0; y < dstheight; y++) {
+			   sbuf -= sdesc.u1.lPitch;
+			   dbuf -= ddesc.u1.lPitch;
+			   memmove(dbuf, sbuf, width);
+		       }
+                    } else {
+                       for (y = 0; y < dstheight; y++) {
+                          memmove(dbuf, sbuf, width);
+                          sbuf += sdesc.u1.lPitch;
+                          dbuf += ddesc.u1.lPitch;
+                       }
+                     }
+
 		} else {
 		    /* Stretching in Y direction only */
 		    for (y = sy = 0; y < dstheight; y++, sy += yinc) {


More information about the wine-patches mailing list