All pastes #384169 Raw Edit

Untitled

public text v1 · immutable
·published 2007-03-06 21:35 UTC
rendered paste body
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);
}