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

📄 main.c

📁 Wine-20031016
💻 C
📖 第 1 页 / 共 4 页
字号:
/*		DirectDraw IDirectDraw interface (generic) * * Copyright 1997-2000 Marcus Meissner * Copyright 1998-2000 Lionel Ulmer (most of Direct3D stuff) * 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 * * NOTES * * WINE currently implements a very basic set of the DirectDraw functionality * in graphics/ddraw.c. This implementation uses either the XFree86-DGA extension  * to get very fast access to the graphics card framebuffer and doublebuffering * features or Xlib, which is slower. * The implementation using XFree86-DGA is as fast as the MS equivalent for the * stuff that is implemented. * * Several applications already work, see below. * Problems of the implementation using XFree86-DGA: * *	- XFree86 cannot switch depth on the fly. *	  This is a problem with X and unavoidable. *	  Current solution is to pop up a MessageBox with an error for  *	  mismatched parameters and advice the user to restart the X server *	  with the specified depth. *	- The rest of the functionality that has to be implemented will have *	  to be done in software and will be very slow. *	- This requires WINE to be run as root user so XF86DGA can mmap the *	  framebuffer into the addressspace of the process. *	- Blocks all other X windowed applications. * * This file contains all the interface functions that are shared between * all interfaces. Or better, it is a "common stub" library for the * IDirectDraw* objects */#include "config.h"#include "wine/port.h"#include <assert.h>#include <stdarg.h>#include <string.h>#define NONAMELESSUNION#define NONAMELESSSTRUCT#include "winerror.h"#include "windef.h"#include "winbase.h"#include "wingdi.h"#include "ddraw.h"#include "d3d.h"#include "wine/debug.h"#include "ddraw_private.h"#include "mesa_private.h" /* To have the D3D creation function */#include "ddraw/main.h"#include "dclipper/main.h"#include "dpalette/main.h"#include "dsurface/main.h"#include "dsurface/dib.h"#include "dsurface/fakezbuffer.h"WINE_DEFAULT_DEBUG_CHANNEL(ddraw);extern ICOM_VTABLE(IDirectDraw) DDRAW_IDirectDraw_VTable;extern ICOM_VTABLE(IDirectDraw2) DDRAW_IDirectDraw2_VTable;extern ICOM_VTABLE(IDirectDraw4) DDRAW_IDirectDraw4_VTable;static void DDRAW_UnsubclassWindow(IDirectDrawImpl* This);static void Main_DirectDraw_DeleteSurfaces(IDirectDrawImpl* This);static void Main_DirectDraw_DeleteClippers(IDirectDrawImpl* This);static void Main_DirectDraw_DeletePalettes(IDirectDrawImpl* This);static void LosePrimarySurface(IDirectDrawImpl* This);static INT32 allocate_memory(IDirectDrawImpl *This, DWORD mem) ;static void free_memory(IDirectDrawImpl *This, DWORD mem) ;static const char ddProp[] = "WINE_DDRAW_Property";/* Not called from the vtable. */HRESULT Main_DirectDraw_Construct(IDirectDrawImpl *This, BOOL ex){    /* NOTE: The creator must use HEAP_ZERO_MEMORY or equivalent. */    This->ref = 1;    This->ex = ex;    if (ex) This->local.dwLocalFlags |= DDRAWILCL_DIRECTDRAW7;    This->local.dwProcessId = GetCurrentProcessId();    This->final_release = Main_DirectDraw_final_release;    This->create_palette = Main_DirectDrawPalette_Create;    This->create_offscreen = Main_create_offscreen;    This->create_texture   = Main_create_texture;    This->create_zbuffer   = Main_create_zbuffer;    /* There are no generic versions of create_{primary,backbuffer}. */    ICOM_INIT_INTERFACE(This, IDirectDraw,  DDRAW_IDirectDraw_VTable);    ICOM_INIT_INTERFACE(This, IDirectDraw2, DDRAW_IDirectDraw2_VTable);    ICOM_INIT_INTERFACE(This, IDirectDraw4, DDRAW_IDirectDraw4_VTable);    /* There is no generic implementation of IDD7 */    /* This is for the moment here... */    This->free_memory = free_memory;    This->allocate_memory = allocate_memory;    This->total_vidmem = 16 * 1024 * 1024;    This->available_vidmem = This->total_vidmem;          return DD_OK;}void Main_DirectDraw_final_release(IDirectDrawImpl* This){    if (IsWindow(This->window))    {	if (GetPropA(This->window, ddProp))	    DDRAW_UnsubclassWindow(This);	else	    FIXME("this shouldn't happen, right?\n");    }    Main_DirectDraw_DeleteSurfaces(This);    Main_DirectDraw_DeleteClippers(This);    Main_DirectDraw_DeletePalettes(This);    if (This->local.lpGbl && This->local.lpGbl->lpExclusiveOwner == &This->local)    {	This->local.lpGbl->lpExclusiveOwner = NULL;	if (This->set_exclusive_mode)	    This->set_exclusive_mode(This, FALSE);    }}/* There is no Main_DirectDraw_Create. */ULONG WINAPI Main_DirectDraw_AddRef(LPDIRECTDRAW7 iface) {    ICOM_THIS(IDirectDrawImpl,iface);    TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );    return ++This->ref;}ULONG WINAPI Main_DirectDraw_Release(LPDIRECTDRAW7 iface) {    ULONG ref;    ICOM_THIS(IDirectDrawImpl,iface);    TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );    ref = --This->ref;    if (ref == 0)    {	if (This->final_release != NULL)	    This->final_release(This);	/* We free the private. This is an artifact of the fact that I don't	 * have the destructors set up correctly. */	if (This->private != (This+1))	    HeapFree(GetProcessHeap(), 0, This->private);	HeapFree(GetProcessHeap(), 0, This);    }    return ref;}HRESULT WINAPI Main_DirectDraw_QueryInterface(    LPDIRECTDRAW7 iface,REFIID refiid,LPVOID *obj) {    ICOM_THIS(IDirectDrawImpl,iface);    TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(refiid), obj);    /* According to COM docs, if the QueryInterface fails, obj should be set to NULL */    *obj = NULL;        if ( IsEqualGUID( &IID_IUnknown, refiid )	 || IsEqualGUID( &IID_IDirectDraw7, refiid ) )    {	*obj = ICOM_INTERFACE(This, IDirectDraw7);    }    else if ( IsEqualGUID( &IID_IDirectDraw, refiid ) )    {	*obj = ICOM_INTERFACE(This, IDirectDraw);    }    else if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) )    {	*obj = ICOM_INTERFACE(This, IDirectDraw2);    }    else if ( IsEqualGUID( &IID_IDirectDraw4, refiid ) )    {	*obj = ICOM_INTERFACE(This, IDirectDraw4);    }#ifdef HAVE_OPENGL    else if ( IsEqualGUID( &IID_IDirect3D  , refiid ) ||	      IsEqualGUID( &IID_IDirect3D2 , refiid ) ||	      IsEqualGUID( &IID_IDirect3D3 , refiid ) ||	      IsEqualGUID( &IID_IDirect3D7 , refiid ) )    {        if (opengl_initialized) {	    HRESULT ret_value;	    ret_value = direct3d_create(This);	    if (FAILED(ret_value)) return ret_value;	    	    if ( IsEqualGUID( &IID_IDirect3D  , refiid ) ) {	        *obj = ICOM_INTERFACE(This, IDirect3D);		TRACE(" returning Direct3D interface at %p.\n", *obj);	    	    } else if ( IsEqualGUID( &IID_IDirect3D2  , refiid ) ) {	        *obj = ICOM_INTERFACE(This, IDirect3D2);		TRACE(" returning Direct3D2 interface at %p.\n", *obj);	    	    } else if ( IsEqualGUID( &IID_IDirect3D3  , refiid ) ) {	        *obj = ICOM_INTERFACE(This, IDirect3D3);		TRACE(" returning Direct3D3 interface at %p.\n", *obj);	    	    } else {	        *obj = ICOM_INTERFACE(This, IDirect3D7);		TRACE(" returning Direct3D7 interface at %p.\n", *obj);	    	    }	} else {	    ERR("Application requests a Direct3D interface but dynamic OpenGL support loading failed !\n");	    ERR("(%p)->(%s,%p): no interface\n",This,debugstr_guid(refiid),obj);	    return E_NOINTERFACE;	}    }#else    else if ( IsEqualGUID( &IID_IDirect3D  , refiid ) ||	      IsEqualGUID( &IID_IDirect3D2 , refiid ) ||	      IsEqualGUID( &IID_IDirect3D3 , refiid ) ||	      IsEqualGUID( &IID_IDirect3D7 , refiid ) )    {        ERR("Application requests a Direct3D interface but OpenGL support not built-in !\n");	ERR("(%p)->(%s,%p): no interface\n",This,debugstr_guid(refiid),obj);	return E_NOINTERFACE;    }#endif    else    {	FIXME("(%p)->(%s,%p): no interface\n",This,debugstr_guid(refiid),obj);	return E_NOINTERFACE;    }    IDirectDraw7_AddRef(iface);    return S_OK;}/* MSDN: "not currently implemented". */HRESULT WINAPI Main_DirectDraw_Compact(LPDIRECTDRAW7 iface){    TRACE("(%p)\n", iface);    return DD_OK;}HRESULT WINAPI Main_DirectDraw_CreateClipper(LPDIRECTDRAW7 iface,					     DWORD dwFlags,					     LPDIRECTDRAWCLIPPER *ppClipper,					     IUnknown *pUnkOuter){    ICOM_THIS(IDirectDrawImpl, iface);    HRESULT hr;    TRACE("(%p)->(0x%lx, %p, %p)\n", iface, dwFlags, ppClipper, pUnkOuter);    hr = DirectDrawCreateClipper(dwFlags, ppClipper, pUnkOuter);    if (FAILED(hr)) return hr;    /* dwFlags is passed twice, apparently an API wart. */    hr = IDirectDrawClipper_Initialize(*ppClipper,				       ICOM_INTERFACE(This, IDirectDraw),				       dwFlags);    if (FAILED(hr))    {	IDirectDrawClipper_Release(*ppClipper);	return hr;    }    return DD_OK;}HRESULT WINAPIMain_DirectDraw_CreatePalette(LPDIRECTDRAW7 iface, DWORD dwFlags,			      LPPALETTEENTRY palent,			      LPDIRECTDRAWPALETTE* ppPalette,			      LPUNKNOWN pUnknown){    ICOM_THIS(IDirectDrawImpl,iface);    LPDIRECTDRAWPALETTE pPalette;    HRESULT hr;    TRACE("(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ppPalette,pUnknown);    if (ppPalette == NULL) return E_POINTER; /* unchecked */    if (pUnknown != NULL) return CLASS_E_NOAGGREGATION; /* unchecked */    hr = This->create_palette(This, dwFlags, &pPalette, pUnknown);    if (FAILED(hr)) return hr;    hr = IDirectDrawPalette_SetEntries(pPalette, 0, 0,				       Main_DirectDrawPalette_Size(dwFlags),				       palent);    if (FAILED(hr))    {	IDirectDrawPalette_Release(pPalette);	return hr;    }    else    {	*ppPalette = pPalette;	return DD_OK;    }}HRESULTMain_create_offscreen(IDirectDrawImpl* This, const DDSURFACEDESC2* pDDSD,		      LPDIRECTDRAWSURFACE7* ppSurf, LPUNKNOWN pOuter){    assert(pOuter == NULL);    return DIB_DirectDrawSurface_Create(This, pDDSD, ppSurf, pOuter);}HRESULTMain_create_texture(IDirectDrawImpl* This, const DDSURFACEDESC2* pDDSD,		    LPDIRECTDRAWSURFACE7* ppSurf, LPUNKNOWN pOuter,		    DWORD dwMipMapLevel){    assert(pOuter == NULL);    return DIB_DirectDrawSurface_Create(This, pDDSD, ppSurf, pOuter);}HRESULTMain_create_zbuffer(IDirectDrawImpl* This, const DDSURFACEDESC2* pDDSD,		    LPDIRECTDRAWSURFACE7* ppSurf, LPUNKNOWN pOuter){    assert(pOuter == NULL);    return FakeZBuffer_DirectDrawSurface_Create(This, pDDSD, ppSurf, pOuter);}/* Does the texture surface described in pDDSD have any smaller mipmaps? */static BOOL more_mipmaps(const DDSURFACEDESC2 *pDDSD){    return ((pDDSD->dwFlags & DDSD_MIPMAPCOUNT) && pDDSD->u2.dwMipMapCount > 1	    && (pDDSD->dwWidth > 1 || pDDSD->dwHeight > 1));}/* Create a texture surface along with any of its mipmaps. */static HRESULTcreate_texture(IDirectDrawImpl* This, const DDSURFACEDESC2 *pDDSD,	       LPDIRECTDRAWSURFACE7* ppSurf, LPUNKNOWN pUnkOuter){    DDSURFACEDESC2 ddsd;    DWORD mipmap_level = 0;    HRESULT hr;    assert(pUnkOuter == NULL);    /* is this check right? (pixelformat can be copied from primary) */    if ((pDDSD->dwFlags&(DDSD_HEIGHT|DDSD_WIDTH)) != (DDSD_HEIGHT|DDSD_WIDTH))	return DDERR_INVALIDPARAMS;    ddsd.dwSize = sizeof(ddsd);    DD_STRUCT_COPY_BYSIZE((&ddsd),pDDSD);    if (!(ddsd.dwFlags & DDSD_PIXELFORMAT))    {	ddsd.u4.ddpfPixelFormat = This->pixelformat;    }    /* We do not support for now compressed texture formats... */    if (ddsd.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC)    {        return DDERR_INVALIDPIXELFORMAT;    }        if (!(ddsd.dwFlags & DDSD_PITCH))    {	ddsd.u1.lPitch = DDRAW_width_bpp_to_pitch(ddsd.dwWidth,						  GET_BPP(ddsd)*8);    }    /* Check also for the MIPMAP / MIPMAPCOUNT flags.       As checked on Windows, this is the right behaviour. No mipmaps seem to be generated. */    if (((ddsd.dwFlags & DDSD_MIPMAPCOUNT) == 0) &&	((ddsd.ddsCaps.dwCaps & DDSCAPS_MIPMAP) != 0)) {        ddsd.dwFlags |= DDSD_MIPMAPCOUNT;	ddsd.u2.dwMipMapCount = 1;    }        ddsd.dwFlags |= DDSD_PITCH | DDSD_PIXELFORMAT;    hr = This->create_texture(This, &ddsd, ppSurf, pUnkOuter, mipmap_level);    if (FAILED(hr)) return hr;    if (This->d3d_private) This->d3d_create_texture(This, ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, *ppSurf), TRUE, 						    ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, *ppSurf));

⌨️ 快捷键说明

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