static HRESULT WINAPI IDirectDrawSurfaceImpl_Blt(IDirectDrawSurface7 *iface, RECT *DestRect, IDirectDrawSurface7 *SrcSurface, RECT *SrcRect, DWORD Flags, DDBLTFX *DDBltFx) { ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface); IDirectDrawSurfaceImpl *Src = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, SrcSurface); HRESULT hrResult = DD_OK; RECT rectNewDest; /* Translated dest */ 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; } /* DirectDraw surfaces have their DestRect coordinates relative to screen; e.g. 0,0 is top left corner of the screen. D3D surface, which we relay to, however, has these coordinates target-relative. So we use clipper's data and do the translation */ if (DestRect) { memcpy(&rectNewDest, DestRect, sizeof(RECT)); if (This->clipper) { /* Assuming that having a clipper set means we're in windowed mode... */ HWND hWnd; hrResult = IDirectDrawClipper_GetHWnd((LPDIRECTDRAWCLIPPER)This->clipper, &hWnd); if (SUCCEEDED(hrResult)) { RGNDATA *pRgnData = NULL; DWORD dwDataSize = 0; hrResult = IDirectDrawClipper_GetClipList((LPDIRECTDRAWCLIPPER)This->clipper, DestRect, NULL, &dwDataSize); pRgnData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwDataSize); hrResult = IDirectDrawClipper_GetClipList((LPDIRECTDRAWCLIPPER)This->clipper, DestRect, pRgnData, &dwDataSize); if (SUCCEEDED(hrResult)) { RECT *pClipRect = (RECT *)pRgnData->Buffer; /* I guess we could just set left and top to 0,0 and be gone with it... but on the other hand, what would happen if Blt was done somewhere in the middle of drawing area? */ rectNewDest.left -= pClipRect->left; rectNewDest.top -= pClipRect->top; rectNewDest.right -= pClipRect->left; rectNewDest.bottom -= pClipRect->top; } else { WARN("Failed to get clip list from the clipper!\n"); } HeapFree(GetProcessHeap(), 0, pRgnData); } else { WARN("Failed to get hWnd the clipper!\n"); } } } return IWineD3DSurface_Blt(This->WineD3DSurface, DestRect ? &rectNewDest : NULL, Src ? Src->WineD3DSurface : NULL, SrcRect, Flags, DDBltFx); }