📄 dib.c
字号:
DDSURFACEDESC2 ddesc,sdesc; HRESULT ret = DD_OK; LPBYTE sbuf, dbuf; RECT rsrc2; RECT lock_src, lock_dst; if (TRACE_ON(ddraw)) { TRACE("(%p)->(%ld,%ld,%p,%p,%08lx)\n", This,dstx,dsty,src,rsrc,trans ); TRACE("\ttrans:"); if (FIXME_ON(ddraw)) DDRAW_dump_DDBLTFAST(trans); if (rsrc) TRACE("\tsrcrect: %ldx%ld-%ldx%ld\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom); else TRACE(" srcrect: NULL\n"); } /* First, check if the possible override function handles this case */ if (This->aux_bltfast != NULL) { if (This->aux_bltfast(This, dstx, dsty, src, rsrc, trans) == DD_OK) return DD_OK; } /* Get the surface description without locking to first compute the width / height */ ddesc = This->surface_desc; sdesc = (ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, src))->surface_desc; if (!rsrc) { WARN("rsrc is NULL!\n"); rsrc = &rsrc2; rsrc->left = rsrc->top = 0; rsrc->right = sdesc.dwWidth; rsrc->bottom = sdesc.dwHeight; } h=rsrc->bottom-rsrc->top; if (h>ddesc.dwHeight-dsty) h=ddesc.dwHeight-dsty; if (h>sdesc.dwHeight-rsrc->top) h=sdesc.dwHeight-rsrc->top; if (h<=0) return DDERR_INVALIDRECT; w=rsrc->right-rsrc->left; if (w>ddesc.dwWidth-dstx) w=ddesc.dwWidth-dstx; if (w>sdesc.dwWidth-rsrc->left) w=sdesc.dwWidth-rsrc->left; if (w<=0) return DDERR_INVALIDRECT; /* Now compute the locking rectangle... */ lock_src.left = rsrc->left; lock_src.top = rsrc->top; lock_src.right = lock_src.left + w; lock_src.bottom = lock_src.top + h; lock_dst.left = dstx; lock_dst.top = dsty; lock_dst.right = dstx + w; lock_dst.bottom = dsty + h; /* We need to lock the surfaces, or we won't get refreshes when done. */ sdesc.dwSize = sizeof(sdesc); IDirectDrawSurface7_Lock(src, &lock_src, &sdesc, DDLOCK_READONLY, 0); ddesc.dwSize = sizeof(ddesc); IDirectDrawSurface7_Lock(iface, &lock_dst, &ddesc, DDLOCK_WRITEONLY, 0); bpp = GET_BPP(This->surface_desc); sbuf = (BYTE *) sdesc.lpSurface; dbuf = (BYTE *) ddesc.lpSurface; if (trans & (DDBLTFAST_SRCCOLORKEY | DDBLTFAST_DESTCOLORKEY)) { DWORD keylow, keyhigh; if (trans & DDBLTFAST_SRCCOLORKEY) { keylow = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue; keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue; } else { /* I'm not sure if this is correct */ FIXME("DDBLTFAST_DESTCOLORKEY not fully supported yet.\n"); keylow = ddesc.ddckCKDestBlt.dwColorSpaceLowValue; keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue; }#define COPYBOX_COLORKEY(type) { \ type *d, *s, tmp; \ s = (type *) sdesc.lpSurface; \ d = (type *) ddesc.lpSurface; \ for (y = 0; y < h; y++) { \ for (x = 0; x < w; x++) { \ tmp = s[x]; \ if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \ } \ (LPBYTE)s += sdesc.u1.lPitch; \ (LPBYTE)d += ddesc.u1.lPitch; \ } \ break; \ } switch (bpp) { case 1: COPYBOX_COLORKEY(BYTE) case 2: COPYBOX_COLORKEY(WORD) case 4: COPYBOX_COLORKEY(DWORD) default: FIXME("Source color key blitting not supported for bpp %d\n",bpp*8); ret = DDERR_UNSUPPORTED; goto error; }#undef COPYBOX_COLORKEY } else { int width = w * bpp; for (y = 0; y < h; y++) { memcpy(dbuf, sbuf, width); sbuf += sdesc.u1.lPitch; dbuf += ddesc.u1.lPitch; } } error: IDirectDrawSurface7_Unlock(iface, &lock_dst); IDirectDrawSurface7_Unlock(src, &lock_src); return ret;}/* ChangeUniquenessValue: generic *//* DeleteAttachedSurface: generic *//* EnumAttachedSurfaces: generic *//* EnumOverlayZOrders: generic, unimplemented */BOOL DIB_DirectDrawSurface_flip_data(IDirectDrawSurfaceImpl* front, IDirectDrawSurfaceImpl* back, DWORD dwFlags){ DIB_DirectDrawSurfaceImpl* front_priv = front->private; DIB_DirectDrawSurfaceImpl* back_priv = back->private; TRACE("(%p,%p)\n",front,back); { HBITMAP tmp; tmp = front_priv->dib.DIBsection; front_priv->dib.DIBsection = back_priv->dib.DIBsection; back_priv->dib.DIBsection = tmp; } { void* tmp; tmp = front_priv->dib.bitmap_data; front_priv->dib.bitmap_data = back_priv->dib.bitmap_data; back_priv->dib.bitmap_data = tmp; tmp = front->surface_desc.lpSurface; front->surface_desc.lpSurface = back->surface_desc.lpSurface; back->surface_desc.lpSurface = tmp; } /* client_memory should not be different, but just in case */ { BOOL tmp; tmp = front_priv->dib.client_memory; front_priv->dib.client_memory = back_priv->dib.client_memory; back_priv->dib.client_memory = tmp; } return Main_DirectDrawSurface_flip_data(front, back, dwFlags);}/* Flip: generic *//* FreePrivateData: generic *//* GetAttachedSurface: generic *//* GetBltStatus: generic *//* GetCaps: generic (Returns the caps from This->surface_desc.) *//* GetClipper: generic *//* GetColorKey: generic */HRESULT DIB_DirectDrawSurface_alloc_dc(IDirectDrawSurfaceImpl* This, HDC* phDC){ DIB_PRIV_VAR(priv, This); HDC hDC; TRACE("Grabbing a DC for surface: %p\n", This); hDC = CreateCompatibleDC(0); priv->dib.holdbitmap = SelectObject(hDC, priv->dib.DIBsection); if (This->palette) SelectPalette(hDC, This->palette->hpal, FALSE); *phDC = hDC; return S_OK;}HRESULT DIB_DirectDrawSurface_free_dc(IDirectDrawSurfaceImpl* This, HDC hDC){ DIB_PRIV_VAR(priv, This); TRACE("Releasing DC for surface: %p\n", This); SelectObject(hDC, priv->dib.holdbitmap); DeleteDC(hDC); return S_OK;}HRESULT DIB_DirectDrawSurface_get_dc(IDirectDrawSurfaceImpl* This, HDC* phDC){ return DIB_DirectDrawSurface_alloc_dc(This, phDC);}HRESULT DIB_DirectDrawSurface_release_dc(IDirectDrawSurfaceImpl* This, HDC hDC){ return DIB_DirectDrawSurface_free_dc(This, hDC);}/* GetDDInterface: generic *//* GetFlipStatus: generic *//* GetLOD: generic *//* GetOverlayPosition: generic *//* GetPalette: generic *//* GetPixelFormat: generic *//* GetPriority: generic *//* GetPrivateData: generic *//* GetSurfaceDesc: generic *//* GetUniquenessValue: generic *//* Initialize: generic *//* IsLost: generic *//* Lock: generic with callback? *//* PageLock: generic *//* PageUnlock: generic */HRESULT WINAPIDIB_DirectDrawSurface_Restore(LPDIRECTDRAWSURFACE7 iface){ TRACE("(%p)\n",iface); return DD_OK; /* ??? */}/* SetClipper: generic *//* SetColorKey: generic *//* SetLOD: generic *//* SetOverlayPosition: generic */void DIB_DirectDrawSurface_set_palette(IDirectDrawSurfaceImpl* This, IDirectDrawPaletteImpl* pal){ if (!pal) return; if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) This->update_palette(This, pal, 0, pal->palNumEntries, pal->palents);}void DIB_DirectDrawSurface_update_palette(IDirectDrawSurfaceImpl* This, IDirectDrawPaletteImpl* pal, DWORD dwStart, DWORD dwCount, LPPALETTEENTRY palent){ RGBQUAD col[256]; int n; HDC dc; TRACE("updating primary palette\n"); for (n=0; n<dwCount; n++) { col[n].rgbRed = palent[n].peRed; col[n].rgbGreen = palent[n].peGreen; col[n].rgbBlue = palent[n].peBlue; col[n].rgbReserved = 0; } This->get_dc(This, &dc); SetDIBColorTable(dc, dwStart, dwCount, col); This->release_dc(This, dc); /* Propagate change to backbuffers if there are any */ /* Basically this is a modification of the Flip code to find the backbuffer */ /* and duplicate the palette update there as well */ if ((This->surface_desc.ddsCaps.dwCaps&(DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER)) == (DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER)) { static DDSCAPS2 back_caps = { DDSCAPS_BACKBUFFER }; LPDIRECTDRAWSURFACE7 tgt; HRESULT hr = IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(This,IDirectDrawSurface7), &back_caps, &tgt); if (!FAILED(hr)) { IDirectDrawSurfaceImpl* target = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7,tgt); IDirectDrawSurface7_Release(tgt); target->get_dc(target, &dc); SetDIBColorTable(dc, dwStart, dwCount, col); target->release_dc(target, dc); } }}/* SetPalette: generic *//* SetPriority: generic *//* SetPrivateData: generic */HRESULT WINAPIDIB_DirectDrawSurface_SetSurfaceDesc(LPDIRECTDRAWSURFACE7 iface, LPDDSURFACEDESC2 pDDSD, DWORD dwFlags){ ICOM_THIS(IDirectDrawSurfaceImpl,iface); DIB_PRIV_VAR(priv, This); HRESULT hr = DD_OK; DWORD flags = pDDSD->dwFlags; if (TRACE_ON(ddraw)) { TRACE("(%p)->(%p,%08lx)\n",iface,pDDSD,dwFlags); DDRAW_dump_surface_desc(pDDSD); } if (pDDSD->dwFlags & DDSD_PIXELFORMAT) { flags &= ~DDSD_PIXELFORMAT; if (flags & DDSD_LPSURFACE) { This->surface_desc.u4.ddpfPixelFormat = pDDSD->u4.ddpfPixelFormat; } else { FIXME("Change of pixel format without surface re-allocation is not supported !\n"); } } if (pDDSD->dwFlags & DDSD_LPSURFACE) { HBITMAP oldbmp = priv->dib.DIBsection; LPVOID oldsurf = This->surface_desc.lpSurface; BOOL oldc = priv->dib.client_memory; flags &= ~DDSD_LPSURFACE; TRACE("new lpSurface=%p\n",pDDSD->lpSurface); This->surface_desc.lpSurface = pDDSD->lpSurface; priv->dib.client_memory = TRUE; hr = create_dib(This); if (FAILED(hr)) { priv->dib.DIBsection = oldbmp; This->surface_desc.lpSurface = oldsurf; priv->dib.client_memory = oldc; return hr; } DeleteObject(oldbmp); if (!oldc) VirtualFree(oldsurf, 0, MEM_RELEASE); } if (flags) { WARN("Unhandled flags : %08lx\n", flags); } return hr;}/* Unlock: ???, need callback *//* UpdateOverlay: generic *//* UpdateOverlayDisplay: generic *//* UpdateOverlayZOrder: generic */static ICOM_VTABLE(IDirectDrawSurface7) DIB_IDirectDrawSurface7_VTable ={ ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE Main_DirectDrawSurface_QueryInterface, Main_DirectDrawSurface_AddRef, Main_DirectDrawSurface_Release, Main_DirectDrawSurface_AddAttachedSurface, Main_DirectDrawSurface_AddOverlayDirtyRect, DIB_DirectDrawSurface_Blt, Main_DirectDrawSurface_BltBatch, DIB_DirectDrawSurface_BltFast, Main_DirectDrawSurface_DeleteAttachedSurface, Main_DirectDrawSurface_EnumAttachedSurfaces, Main_DirectDrawSurface_EnumOverlayZOrders, Main_DirectDrawSurface_Flip, Main_DirectDrawSurface_GetAttachedSurface, Main_DirectDrawSurface_GetBltStatus, Main_DirectDrawSurface_GetCaps, Main_DirectDrawSurface_GetClipper, Main_DirectDrawSurface_GetColorKey, Main_DirectDrawSurface_GetDC, Main_DirectDrawSurface_GetFlipStatus, Main_DirectDrawSurface_GetOverlayPosition, Main_DirectDrawSurface_GetPalette, Main_DirectDrawSurface_GetPixelFormat, Main_DirectDrawSurface_GetSurfaceDesc, Main_DirectDrawSurface_Initialize, Main_DirectDrawSurface_IsLost, Main_DirectDrawSurface_Lock, Main_DirectDrawSurface_ReleaseDC, DIB_DirectDrawSurface_Restore, Main_DirectDrawSurface_SetClipper, Main_DirectDrawSurface_SetColorKey, Main_DirectDrawSurface_SetOverlayPosition, Main_DirectDrawSurface_SetPalette, Main_DirectDrawSurface_Unlock, Main_DirectDrawSurface_UpdateOverlay, Main_DirectDrawSurface_UpdateOverlayDisplay, Main_DirectDrawSurface_UpdateOverlayZOrder, Main_DirectDrawSurface_GetDDInterface, Main_DirectDrawSurface_PageLock, Main_DirectDrawSurface_PageUnlock, DIB_DirectDrawSurface_SetSurfaceDesc, Main_DirectDrawSurface_SetPrivateData, Main_DirectDrawSurface_GetPrivateData, Main_DirectDrawSurface_FreePrivateData, Main_DirectDrawSurface_GetUniquenessValue, Main_DirectDrawSurface_ChangeUniquenessValue, Main_DirectDrawSurface_SetPriority, Main_DirectDrawSurface_GetPriority, Main_DirectDrawSurface_SetLOD, Main_DirectDrawSurface_GetLOD};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -