Commit 8b8e30b1 authored by Stefan Dösinger's avatar Stefan Dösinger Committed by Alexandre Julliard

ddraw, wined3d: Color keying tests and fixes.

parent ccd2772e
......@@ -696,6 +696,24 @@ IDirectDrawSurfaceImpl_Blt(IDirectDrawSurface7 *iface,
IDirectDrawSurfaceImpl *Src = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, SrcSurface);
TRACE("(%p)->(%p,%p,%p,%x,%p)\n", This, DestRect, Src, SrcRect, Flags, DDBltFx);
/* Check for validity of the flags here. WineD3D Has the software-opengl selection path and would have
* to check at 2 places, and sometimes do double checks. This also saves the call to wined3d :-)
*/
if((Flags & DDBLT_KEYSRCOVERRIDE) && (!DDBltFx || Flags & DDBLT_KEYSRC)) {
WARN("Invalid source color key parameters, returning DDERR_INVALIDPARAMS\n");
return DDERR_INVALIDPARAMS;
}
if((Flags & DDBLT_KEYDESTOVERRIDE) && (!DDBltFx || Flags & DDBLT_KEYDEST)) {
WARN("Invalid destination color key parameters, returning DDERR_INVALIDPARAMS\n");
return DDERR_INVALIDPARAMS;
}
if(Flags & DDBLT_KEYSRC && (!Src || !(Src->surface_desc.dwFlags & DDSD_CKSRCBLT))) {
WARN("DDBLT_KEYDEST blit without color key in surface, returning DDERR_INVALIDPARAMS\n");
return DDERR_INVALIDPARAMS;
}
return IWineD3DSurface_Blt(This->WineD3DSurface,
DestRect,
Src ? Src->WineD3DSurface : NULL,
......
......@@ -2362,6 +2362,13 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, RECT *
return WINED3DERR_INVALIDCALL;
}
/* No destination color keying supported */
if(Flags & (DDBLT_KEYDEST | DDBLT_KEYDESTOVERRIDE)) {
/* Can we support that with glBlendFunc if blitting to the frame buffer? */
TRACE("Destination color key not supported in accelerated Blit, falling back to software\n");
return WINED3DERR_INVALIDCALL;
}
if (DestRect) {
rect.x1 = DestRect->left;
rect.y1 = DestRect->top;
......@@ -2442,6 +2449,12 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, RECT *
WINED3DRECT srect;
BOOL upsideDown, stretchx;
if(Flags & (DDBLT_KEYSRC | DDBLT_KEYSRCOVERRIDE)) {
TRACE("Color keying not supported by frame buffer to texture blit\n");
return WINED3DERR_INVALIDCALL;
/* Destination color key is checked above */
}
/* Call preload for the surface to make sure it isn't dirty */
IWineD3DSurface_PreLoad((IWineD3DSurface *) This);
......@@ -2514,8 +2527,8 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, RECT *
} else if(Src) {
/* Blit from offscreen surface to render target */
float glTexCoord[4];
DWORD oldCKey;
DDCOLORKEY oldBltCKey = {0,0};
DWORD oldCKeyFlags = Src->CKeyFlags;
DDCOLORKEY oldBltCKey = This->SrcBltCKey;
RECT SourceRectangle;
GLint oldDraw;
......@@ -2543,26 +2556,22 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, RECT *
/* Color keying: Check if we have to do a color keyed blt,
* and if not check if a color key is activated.
*
* Just modify the color keying parameters in the surface and restore them afterwards
* The surface keeps track of the color key last used to load the opengl surface.
* PreLoad will catch the change to the flags and color key and reload if neccessary.
*/
oldCKey = Src->CKeyFlags;
if(!(Flags & DDBLT_KEYSRC) &&
Src->CKeyFlags & DDSD_CKSRCBLT) {
/* Ok, the surface has a color key, but we shall not use it -
* Deactivate it for now, LoadTexture will catch this
*/
if(Flags & DDBLT_KEYSRC) {
/* Use color key from surface */
} else if(Flags & DDBLT_KEYSRCOVERRIDE) {
/* Use color key from DDBltFx */
Src->CKeyFlags |= DDSD_CKSRCBLT;
This->SrcBltCKey = DDBltFx->ddckSrcColorkey;
} else {
/* Do not use color key */
Src->CKeyFlags &= ~DDSD_CKSRCBLT;
}
/* Color keying */
if(Flags & DDBLT_KEYDEST) {
oldBltCKey = This->SrcBltCKey;
/* Temporary replace the source color key with the destination one. We do this because the color conversion code which
* is in the end called from LoadTexture works with the source color. At the end of this function we restore the color key.
*/
This->SrcBltCKey = This->DestBltCKey;
} else if (Flags & DDBLT_KEYSRC)
oldBltCKey = This->SrcBltCKey;
/* Now load the surface */
IWineD3DSurface_PreLoad((IWineD3DSurface *) Src);
......@@ -2595,7 +2604,7 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, RECT *
checkGLcall("glTexEnvi");
/* This is for color keying */
if(Flags & DDBLT_KEYSRC) {
if(Flags & (DDBLT_KEYSRC | DDBLT_KEYSRCOVERRIDE)) {
glEnable(GL_ALPHA_TEST);
checkGLcall("glEnable GL_ALPHA_TEST");
glAlphaFunc(GL_NOTEQUAL, 0.0);
......@@ -2637,15 +2646,9 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, RECT *
if(This == (IWineD3DSurfaceImpl *) dstSwapchain->frontBuffer && oldDraw == GL_BACK) {
glDrawBuffer(oldDraw);
}
/* Restore the color key flags */
if(oldCKey != Src->CKeyFlags) {
Src->CKeyFlags = oldCKey;
}
/* Restore the old color key */
if (Flags & (DDBLT_KEYSRC | DDBLT_KEYDEST))
This->SrcBltCKey = oldBltCKey;
/* Restore the color key parameters */
Src->CKeyFlags = oldCKeyFlags;
This->SrcBltCKey = oldBltCKey;
LEAVE_GL();
......
......@@ -911,29 +911,33 @@ IWineGDISurfaceImpl_Blt(IWineD3DSurface *iface,
{
LONG dstyinc = dlock.Pitch, dstxinc = bpp;
DWORD keylow = 0xFFFFFFFF, keyhigh = 0, keymask = 0xFFFFFFFF;
DWORD destkeylow = 0x0, destkeyhigh = 0xFFFFFFFF, destkeymask = 0xFFFFFFFF;
if (Flags & (DDBLT_KEYSRC | DDBLT_KEYDEST | DDBLT_KEYSRCOVERRIDE | DDBLT_KEYDESTOVERRIDE))
{
/* The color keying flags are checked for correctness in ddraw */
if (Flags & DDBLT_KEYSRC)
{
keylow = Src->SrcBltCKey.dwColorSpaceLowValue;
keyhigh = Src->SrcBltCKey.dwColorSpaceHighValue;
}
else if (Flags & DDBLT_KEYDEST)
{
keylow = This->DestBltCKey.dwColorSpaceLowValue;
keyhigh = This->DestBltCKey.dwColorSpaceHighValue;
}
else if (Flags & DDBLT_KEYSRCOVERRIDE)
else if (Flags & DDBLT_KEYSRCOVERRIDE)
{
keylow = DDBltFx->ddckSrcColorkey.dwColorSpaceLowValue;
keyhigh = DDBltFx->ddckSrcColorkey.dwColorSpaceHighValue;
}
else
if (Flags & DDBLT_KEYDEST)
{
/* Destination color keys are taken from the source surface ! */
destkeylow = Src->DestBltCKey.dwColorSpaceLowValue;
destkeyhigh = Src->DestBltCKey.dwColorSpaceHighValue;
}
else if (Flags & DDBLT_KEYDESTOVERRIDE)
{
keylow = DDBltFx->ddckDestColorkey.dwColorSpaceLowValue;
keyhigh = DDBltFx->ddckDestColorkey.dwColorSpaceHighValue;
destkeylow = DDBltFx->ddckDestColorkey.dwColorSpaceLowValue;
destkeyhigh = DDBltFx->ddckDestColorkey.dwColorSpaceHighValue;
}
if(bpp == 1)
{
keymask = 0xff;
......@@ -1037,7 +1041,10 @@ IWineGDISurfaceImpl_Blt(IWineD3DSurface *iface,
dx = d; \
for (x = sx = 0; x < dstwidth; x++, sx += xinc) { \
tmp = s[sx >> 16]; \
if ((tmp & keymask) < keylow || (tmp & keymask) > keyhigh) dx[0] = tmp; \
if (((tmp & keymask) < keylow || (tmp & keymask) > keyhigh) && \
((dx[0] & destkeymask) >= destkeylow && (dx[0] & destkeymask) <= destkeyhigh)) { \
dx[0] = tmp; \
} \
dx = (type*)(((LPBYTE)dx)+dstxinc); \
} \
d = (type*)(((LPBYTE)d)+dstyinc); \
......@@ -1057,10 +1064,12 @@ IWineGDISurfaceImpl_Blt(IWineD3DSurface *iface,
dx = d;
for (x = sx = 0; x < dstwidth; x++, sx+= xinc)
{
DWORD pixel;
DWORD pixel, dpixel = 0;
s = sbuf+3*(sx>>16);
pixel = s[0]|(s[1]<<8)|(s[2]<<16);
if ((pixel & keymask) < keylow || (pixel & keymask) > keyhigh)
dpixel = dx[0]|(dx[1]<<8)|(dx[2]<<16);
if (((pixel & keymask) < keylow || (pixel & keymask) > keyhigh) &&
((dpixel & keymask) >= destkeylow || (dpixel & keymask) <= keyhigh))
{
dx[0] = (pixel )&0xff;
dx[1] = (pixel>> 8)&0xff;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment