From a80a814234ed760108a87da48bbd25944883596d Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Wed, 10 Jul 2002 23:10:54 +0000 Subject: [PATCH] Fixed corruption when copying to the same surface (with the help of Tony Lambregts and Lionel Ulmer). --- dlls/ddraw/dsurface/dib.c | 40 +++++++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/dlls/ddraw/dsurface/dib.c b/dlls/ddraw/dsurface/dib.c index 9298ebcaa23..7a27f79ccda 100644 --- a/dlls/ddraw/dsurface/dib.c +++ b/dlls/ddraw/dsurface/dib.c @@ -482,11 +482,39 @@ DIB_DirectDrawSurface_Blt(LPDIRECTDRAWSURFACE7 iface, LPRECT rdst, /* 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; - } + + /* check for overlapping surfaces */ + if (src != iface || xdst.top < xsrc.top || + xdst.right <= xsrc.left || xsrc.right <= xdst.left) + { + /* no overlap, or dst above src, so copy from top downwards */ + for (y = 0; y < dstheight; y++) + { + memcpy(dbuf, sbuf, width); + sbuf += sdesc.u1.lPitch; + dbuf += ddesc.u1.lPitch; + } + } + else if (xdst.top > xsrc.top) /* copy from bottom upwards */ + { + 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 /* src and dst overlapping on the same line, use memmove */ + { + 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) { @@ -559,7 +587,7 @@ DIB_DirectDrawSurface_Blt(LPDIRECTDRAWSURFACE7 iface, LPRECT rdst, } else { keylow = lpbltfx->ddckDestColorkey.dwColorSpaceLowValue; keyhigh = lpbltfx->ddckDestColorkey.dwColorSpaceHighValue; - } + } for (y = sy = 0; y < dstheight; y++, sy += yinc) { sbuf = sbase + (sy >> 16) * sdesc.u1.lPitch;