I took Lionel's sugestions to heart and came up with a better fix for bug 829. This has a better check for defining when the corruption could occur and should be a little faster Change log: Fix screen corruption when source and destination are the same surface, both areas are the same size, and no flags are set. Added FIXME to warn user when flags are set. Tony Lambregts tony_lambregts@telusplanet.net
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 4 Jul 2002 13:58:35 -0000 @@ -351,6 +351,7 @@ int bpp, srcheight, srcwidth, dstheight, dstwidth, width; int x, y; LPBYTE dbuf, sbuf; + BOOL SameSurfaceOK = TRUE; TRACE("(%p)->(%p,%p,%p,%08lx,%p)\n", This,rdst,src,rsrc,dwFlags,lpbltfx); @@ -474,6 +475,7 @@ sbase = (BYTE*)sdesc.lpSurface+(xsrc.top*sdesc.u1.lPitch)+xsrc.left*bpp; xinc = (srcwidth << 16) / dstwidth; yinc = (srcheight << 16) / dstheight; + SameSurfaceOK = (!((src == iface)&&(sbase < dbuf)&&(xdst.top < xsrc.bottom)&&(xdst.left < xsrc.right))); if (!dwFlags) { /* No effects, we can cheat here */ @@ -482,11 +484,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 (SameSurfaceOK) { + for (y = 0; y < dstheight; y++) { + memcpy(dbuf, sbuf, width); + sbuf += sdesc.u1.lPitch; + dbuf += ddesc.u1.lPitch; + } + } else { + + sbuf += (sdesc.u1.lPitch*dstheight); + dbuf += (ddesc.u1.lPitch*dstheight); + + for (y = 0; y < dstheight; y++) { + sbuf -= sdesc.u1.lPitch; + dbuf -= ddesc.u1.lPitch; + memcpy(dbuf, sbuf, width); + } + } + } else { /* Stretching in Y direction only */ for (y = sy = 0; y < dstheight; y++, sy += yinc) { @@ -544,6 +559,10 @@ } } else if (dwFlags & (DDBLT_KEYSRC | DDBLT_KEYDEST | DDBLT_KEYSRCOVERRIDE | DDBLT_KEYDESTOVERRIDE)) { DWORD keylow, keyhigh; + + if (!SameSurfaceOK) { + FIXME("\tSoure and destination surfaces are the same and could cause display problems\n"); + } if (dwFlags & DDBLT_KEYSRC) { keylow = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;