⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dib.c

📁 Wine-20031016
💻 C
📖 第 1 页 / 共 3 页
字号:
/*		DIBSection DirectDrawSurface driver * * Copyright 1997-2000 Marcus Meissner * Copyright 1998-2000 Lionel Ulmer * Copyright 2000-2001 TransGaming Technologies Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#include "config.h"#include <assert.h>#include <stdlib.h>#include <string.h>#define NONAMELESSUNION#define NONAMELESSSTRUCT#include "winerror.h"#include "bitmap.h"#include "wine/debug.h"#include "ddraw_private.h"#include "dsurface/main.h"#include "dsurface/dib.h"WINE_DEFAULT_DEBUG_CHANNEL(ddraw);static ICOM_VTABLE(IDirectDrawSurface7) DIB_IDirectDrawSurface7_VTable;/* Return the width of a DIB bitmap in bytes. DIB bitmap data is 32-bit aligned. */inline static int get_dib_width_bytes( int width, int depth ){    int words;    switch(depth)    {    case 1:  words = (width + 31) / 32; break;    case 4:  words = (width + 7) / 8; break;    case 8:  words = (width + 3) / 4; break;    case 15:    case 16: words = (width + 1) / 2; break;    case 24: words = (width * 3 + 3)/4; break;    default:        WARN("(%d): Unsupported depth\n", depth );        /* fall through */    case 32: words = width; break;    }    return 4 * words;}static HRESULT create_dib(IDirectDrawSurfaceImpl* This){    BITMAPINFO* b_info;    UINT usage;    HDC ddc;    DIB_DirectDrawSurfaceImpl* priv = This->private;    assert(This->surface_desc.lpSurface != NULL);    switch (This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount)    {    case 16:    case 32:	/* Allocate extra space to store the RGB bit masks. */	b_info = (BITMAPINFO*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,					sizeof(BITMAPINFOHEADER)					+ 3 * sizeof(DWORD));	break;    case 24:	b_info = (BITMAPINFO*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,					sizeof(BITMAPINFOHEADER));	break;    default:	/* Allocate extra space for a palette. */	b_info = (BITMAPINFO*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,					sizeof(BITMAPINFOHEADER)					+ sizeof(RGBQUAD)					* (1 << This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount));	break;    }    b_info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);    b_info->bmiHeader.biWidth = This->surface_desc.dwWidth;    b_info->bmiHeader.biHeight = -This->surface_desc.dwHeight;    b_info->bmiHeader.biPlanes = 1;    b_info->bmiHeader.biBitCount = This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount;    if ((This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount != 16)	&& (This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount != 32))        b_info->bmiHeader.biCompression = BI_RGB;    else        b_info->bmiHeader.biCompression = BI_BITFIELDS;    b_info->bmiHeader.biSizeImage	= (This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount / 8)	* This->surface_desc.dwWidth * This->surface_desc.dwHeight;    b_info->bmiHeader.biXPelsPerMeter = 0;    b_info->bmiHeader.biYPelsPerMeter = 0;    b_info->bmiHeader.biClrUsed = 0;    b_info->bmiHeader.biClrImportant = 0;    if (!This->surface_desc.u1.lPitch) {	/* This can't happen, right? */	/* or use GDI_GetObj to get it from the created DIB? */	This->surface_desc.u1.lPitch = get_dib_width_bytes(b_info->bmiHeader.biWidth, b_info->bmiHeader.biBitCount);	This->surface_desc.dwFlags |= DDSD_PITCH;    }        switch (This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount)    {    case 16:    case 32:    {	DWORD *masks = (DWORD *) &(b_info->bmiColors);	usage = 0;	masks[0] = This->surface_desc.u4.ddpfPixelFormat.u2.dwRBitMask;	masks[1] = This->surface_desc.u4.ddpfPixelFormat.u3.dwGBitMask;	masks[2] = This->surface_desc.u4.ddpfPixelFormat.u4.dwBBitMask;    }    break;    case 24:	/* Nothing to do */	usage = DIB_RGB_COLORS;	break;    default:	/* Don't know palette */	usage = 0;	break;    }    ddc = CreateDCA("DISPLAY", NULL, NULL, NULL);    if (ddc == 0)    {	HeapFree(GetProcessHeap(), 0, b_info);	return HRESULT_FROM_WIN32(GetLastError());    }    priv->dib.DIBsection	= DIB_CreateDIBSection(ddc, b_info, usage, &(priv->dib.bitmap_data), 0,			       (DWORD)This->surface_desc.lpSurface,			       This->surface_desc.u1.lPitch);    DeleteDC(ddc);    if (!priv->dib.DIBsection) {	ERR("CreateDIBSection failed!\n");	HeapFree(GetProcessHeap(), 0, b_info);	return HRESULT_FROM_WIN32(GetLastError());    }    TRACE("DIBSection at : %p\n", priv->dib.bitmap_data);    if (!This->surface_desc.lpSurface) {	This->surface_desc.lpSurface = priv->dib.bitmap_data;	This->surface_desc.dwFlags |= DDSD_LPSURFACE;    }    HeapFree(GetProcessHeap(), 0, b_info);    /* I don't think it's worth checking for this. */    if (priv->dib.bitmap_data != This->surface_desc.lpSurface)	ERR("unexpected error creating DirectDrawSurface DIB section\n");    /* this seems like a good place to put the handle for HAL driver use */    This->global_more.hKernelSurface = (ULONG_PTR)priv->dib.DIBsection;    return S_OK;}void DIB_DirectDrawSurface_final_release(IDirectDrawSurfaceImpl* This){    DIB_DirectDrawSurfaceImpl* priv = This->private;    DeleteObject(priv->dib.DIBsection);    if (!priv->dib.client_memory)	VirtualFree(This->surface_desc.lpSurface, 0, MEM_RELEASE);    Main_DirectDrawSurface_final_release(This);}HRESULT DIB_DirectDrawSurface_duplicate_surface(IDirectDrawSurfaceImpl* This,						LPDIRECTDRAWSURFACE7* ppDup){    return DIB_DirectDrawSurface_Create(This->ddraw_owner,					&This->surface_desc, ppDup, NULL);}HRESULT DIB_DirectDrawSurface_Construct(IDirectDrawSurfaceImpl *This,					IDirectDrawImpl *pDD,					const DDSURFACEDESC2 *pDDSD){    HRESULT hr;    DIB_DirectDrawSurfaceImpl* priv = This->private;    TRACE("(%p)->(%p,%p)\n",This,pDD,pDDSD);    hr = Main_DirectDrawSurface_Construct(This, pDD, pDDSD);    if (FAILED(hr)) return hr;    ICOM_INIT_INTERFACE(This, IDirectDrawSurface7,			DIB_IDirectDrawSurface7_VTable);    This->final_release = DIB_DirectDrawSurface_final_release;    This->duplicate_surface = DIB_DirectDrawSurface_duplicate_surface;    This->flip_data = DIB_DirectDrawSurface_flip_data;    This->get_dc     = DIB_DirectDrawSurface_get_dc;    This->release_dc = DIB_DirectDrawSurface_release_dc;    This->hDC = NULL;    This->set_palette    = DIB_DirectDrawSurface_set_palette;    This->update_palette = DIB_DirectDrawSurface_update_palette;    TRACE("(%ldx%ld, pitch=%ld)\n",	  This->surface_desc.dwWidth, This->surface_desc.dwHeight,	  This->surface_desc.u1.lPitch);    /* XXX load dwWidth and dwHeight from pDD if they are not specified? */    if (This->surface_desc.dwFlags & DDSD_LPSURFACE)    {	/* "Client memory": it is managed by the application. */	/* XXX What if lPitch is not set? Use dwWidth or fail? */	priv->dib.client_memory = TRUE;    }    else    {	if (!(This->surface_desc.dwFlags & DDSD_PITCH))	{	    int pitch = This->surface_desc.u1.lPitch;	    if (pitch % 8 != 0)		pitch += 8 - (pitch % 8);	}	/* XXX else: how should lPitch be verified? */	This->surface_desc.dwFlags |= DDSD_PITCH|DDSD_LPSURFACE;	This->surface_desc.lpSurface	    = VirtualAlloc(NULL, This->surface_desc.u1.lPitch			   * This->surface_desc.dwHeight + 4, /* The + 4 here is for dumb games reading after the end of the surface								 when reading the last byte / half using word access */			   MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);	if (This->surface_desc.lpSurface == NULL)	{	    Main_DirectDrawSurface_final_release(This);	    return HRESULT_FROM_WIN32(GetLastError());	}	priv->dib.client_memory = FALSE;    }    hr = create_dib(This);    if (FAILED(hr))    {	if (!priv->dib.client_memory)	    VirtualFree(This->surface_desc.lpSurface, 0, MEM_RELEASE);	Main_DirectDrawSurface_final_release(This);	return hr;    }    return DD_OK;}/* Not an API */HRESULT DIB_DirectDrawSurface_Create(IDirectDrawImpl *pDD,				     const DDSURFACEDESC2 *pDDSD,				     LPDIRECTDRAWSURFACE7 *ppSurf,				     IUnknown *pUnkOuter){    IDirectDrawSurfaceImpl* This;    HRESULT hr;    assert(pUnkOuter == NULL);    This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,		     sizeof(*This) + sizeof(DIB_DirectDrawSurfaceImpl));    if (This == NULL) return E_OUTOFMEMORY;    This->private = (DIB_DirectDrawSurfaceImpl*)(This+1);    hr = DIB_DirectDrawSurface_Construct(This, pDD, pDDSD);    if (FAILED(hr))	HeapFree(GetProcessHeap(), 0, This);    else	*ppSurf = ICOM_INTERFACE(This, IDirectDrawSurface7);    return hr;}/* AddAttachedSurface: generic *//* AddOverlayDirtyRect: generic, unimplemented */static HRESULT _Blt_ColorFill(    LPBYTE buf, int width, int height, int bpp, LONG lPitch, DWORD color) {    int x, y;    LPBYTE first;    /* Do first row */#define COLORFILL_ROW(type) { \    type *d = (type *) buf; \    for (x = 0; x < width; x++) \	d[x] = (type) color; \    break; \}    switch(bpp) {    case 1: COLORFILL_ROW(BYTE)    case 2: COLORFILL_ROW(WORD)    case 3: { BYTE *d = (BYTE *) buf;              for (x = 0; x < width; x++,d+=3) {                d[0] = (color    ) & 0xFF;                d[1] = (color>> 8) & 0xFF;                d[2] = (color>>16) & 0xFF;              }              break;}    case 4: COLORFILL_ROW(DWORD)    default:	FIXME("Color fill not implemented for bpp %d!\n", bpp*8);	return DDERR_UNSUPPORTED;    }#undef COLORFILL_ROW    /* Now copy first row */    first = buf;    for (y = 1; y < height; y++) {	buf += lPitch;	memcpy(buf, first, width * bpp);    }    return DD_OK;}HRESULT WINAPIDIB_DirectDrawSurface_Blt(LPDIRECTDRAWSURFACE7 iface, LPRECT rdst,			  LPDIRECTDRAWSURFACE7 src, LPRECT rsrc,			  DWORD dwFlags, LPDDBLTFX lpbltfx){    ICOM_THIS(IDirectDrawSurfaceImpl,iface);    RECT		xdst,xsrc;    DDSURFACEDESC2	ddesc,sdesc;    HRESULT		ret = DD_OK;    int bpp, srcheight, srcwidth, dstheight, dstwidth, width;    int x, y;    LPBYTE dbuf, sbuf;    TRACE("(%p)->(%p,%p,%p,%08lx,%p)\n", This,rdst,src,rsrc,dwFlags,lpbltfx);    if (TRACE_ON(ddraw)) {	if (rdst) TRACE("\tdestrect :%ldx%ld-%ldx%ld\n",rdst->left,rdst->top,rdst->right,rdst->bottom);	if (rsrc) TRACE("\tsrcrect  :%ldx%ld-%ldx%ld\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);	TRACE("\tflags: ");	DDRAW_dump_DDBLT(dwFlags);	if (dwFlags & DDBLT_DDFX) {	    TRACE("\tblitfx: ");	    DDRAW_dump_DDBLTFX(lpbltfx->dwDDFX);	}    }    /* First, check if the possible override function handles this case */    if (This->aux_blt != NULL) {        if (This->aux_blt(This, rdst, src, rsrc, dwFlags, lpbltfx) == DD_OK) return DD_OK;    }    DD_STRUCT_INIT(&ddesc);    DD_STRUCT_INIT(&sdesc);    sdesc.dwSize = sizeof(sdesc);    if (src) IDirectDrawSurface7_Lock(src, NULL, &sdesc, DDLOCK_READONLY, 0);    ddesc.dwSize = sizeof(ddesc);    IDirectDrawSurface7_Lock(iface,NULL,&ddesc,DDLOCK_WRITEONLY,0);    if (rdst) {	memcpy(&xdst,rdst,sizeof(xdst));    } else {	xdst.top	= 0;	xdst.bottom	= ddesc.dwHeight;	xdst.left	= 0;	xdst.right	= ddesc.dwWidth;    }    if (rsrc) {	memcpy(&xsrc,rsrc,sizeof(xsrc));    } else {	if (src) {	    xsrc.top	= 0;	    xsrc.bottom	= sdesc.dwHeight;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -