I am working on implementing the flags under DDBLTFX (Bug 841) and in order to do so I needed to understand how the current code worked. While researching this I came up with this patch for the flags DDBLT_KEYSRC/DDBLT_KEYDEST and company. This patch should be faster then the current code since the switch statement is outside the loop. It also adds support for 24bpp colour.
The problem that I have with this is that it assumes stretching in both the x and y directions but from what I understand stretching should only be done if the flag DDBLTFX is set and has the operation DDBLTFX_ARITHSTRETCHY in dwDDFX. Is that right or can Marcus Meissner or Lionel Ulmer explain this to me.
Change log: added support for 24bpp when the flags DDBLT_KEYSRC/DDBLT_KEYDEST and company 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 8 Jul 2002 19:02:35 -0000 @@ -561,28 +561,54 @@ keyhigh = lpbltfx->ddckDestColorkey.dwColorSpaceHighValue; }
- for (y = sy = 0; y < dstheight; y++, sy += yinc) { - sbuf = sbase + (sy >> 16) * sdesc.u1.lPitch;
#define COPYROW_COLORKEY(type) { \ - type *s = (type *) sbuf, *d = (type *) dbuf, tmp; \ - for (x = sx = 0; x < dstwidth; x++, sx += xinc) { \ - tmp = s[sx >> 16]; \ - if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \ - } \ - break; } + type *s = (type *) sbuf, *d = (type *) dbuf, tmp; \ + for (y = sy = 0; y < dstheight; y++, sy += yinc) { \ + (LPBYTE)s = sbase + (sy >> 16) * sdesc.u1.lPitch; \ + for (x = sx = 0; x < dstwidth; x++, sx += xinc) { \ + tmp = s[sx >> 16]; \ + if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \ + } \ + (LPBYTE)d += ddesc.u1.lPitch; \ + } \ + break; }
- switch (bpp) { - case 1: COPYROW_COLORKEY(BYTE) - case 2: COPYROW_COLORKEY(WORD) - case 4: COPYROW_COLORKEY(DWORD) - default: - FIXME("%s color-keyed blit not implemented for bpp %d!\n", - (dwFlags & DDBLT_KEYSRC) ? "Source" : "Destination", bpp*8); - ret = DDERR_UNSUPPORTED; - goto error; - } - dbuf += ddesc.u1.lPitch; + switch (bpp) { + case 1: COPYROW_COLORKEY(BYTE) + case 2: COPYROW_COLORKEY(WORD) + case 4: COPYROW_COLORKEY(DWORD) + case 3: { + int last_sy = -1; + for (y = sy = 0; y < dstheight; y++, sy += yinc) { + sbuf = sbase + (sy >> 16) * sdesc.u1.lPitch; + if ((sy >> 16) == (last_sy >> 16)) { + /* this sourcerow is the same as last sourcerow - + * copy already stretched row + */ + memcpy(dbuf, dbuf - ddesc.u1.lPitch, width); + } else { + LPBYTE s,d = dbuf; + for (x = sx = 0; x < dstwidth; x++, sx+= xinc) { + DWORD pixel; + + s = sbuf+3*(sx>>16); + pixel = (s[0]<<16)|(s[1]<<8)|s[2]; + d[0] = (pixel>>16)&0xff; + d[1] = (pixel>> 8)&0xff; + d[2] = (pixel )&0xff; + d+=3; + } + } + dbuf += ddesc.u1.lPitch; + last_sy = sy; + } + break;} + default: + FIXME("%s color-keyed blit not implemented for bpp %d!\n", + (dwFlags & DDBLT_KEYSRC) ? "Source" : "Destination", bpp*8); + ret = DDERR_UNSUPPORTED; + goto error; } #undef COPYROW_COLORKEY dwFlags &= ~(DDBLT_KEYSRC | DDBLT_KEYDEST | DDBLT_KEYSRCOVERRIDE | DDBLT_KEYDESTOVERRIDE);