diff --git a/dlls/ddraw/Makefile.in b/dlls/ddraw/Makefile.in index 88a7ff4c95..3e4349170a 100644 --- a/dlls/ddraw/Makefile.in +++ b/dlls/ddraw/Makefile.in @@ -4,45 +4,31 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = ddraw.dll IMPORTLIB = libddraw.$(IMPLIBEXT) -IMPORTS = ole32 user32 gdi32 advapi32 kernel32 ntdll +IMPORTS = wined3d ole32 user32 gdi32 advapi32 kernel32 ntdll EXTRAINCL = @X_CFLAGS@ EXTRALIBS = -ldxguid -luuid @X_LIBS@ @X_PRE_LIBS@ @XLIB@ @X_EXTRA_LIBS@ -OPENGLFILES = \ - d3d_utils.c \ - device_main.c \ - device_opengl.c \ - direct3d_main.c \ - direct3d_opengl.c \ +C_SRCS = \ + clipper.c \ + ddraw.c \ + ddraw_thunks.c \ + device.c \ + direct3d.c \ executebuffer.c \ + gamma.c \ light.c \ + main.c \ material.c \ - opengl_utils.c \ + palette.c \ + parent.c \ + regsvr.c \ + surface.c \ + surface_thunks.c \ texture.c \ + utils.c \ vertexbuffer.c \ viewport.c -C_SRCS = \ - @OPENGLFILES@ \ - clipper.c \ - ddraw_hal.c \ - ddraw_main.c \ - ddraw_thunks.c \ - ddraw_user.c \ - ddraw_utils.c \ - main.c \ - palette_hal.c \ - palette_main.c \ - regsvr.c \ - surface_dib.c \ - surface_fakezbuffer.c \ - surface_gamma.c \ - surface_hal.c \ - surface_main.c \ - surface_thunks.c \ - surface_user.c \ - surface_wndproc.c - RC_SRCS = version.rc SUBDIRS = tests diff --git a/dlls/ddraw/clipper.c b/dlls/ddraw/clipper.c index 4f0f6b405c..9f643b43ab 100644 --- a/dlls/ddraw/clipper.c +++ b/dlls/ddraw/clipper.c @@ -1,7 +1,8 @@ -/* DirectDrawClipper implementation +/* DirectDrawClipper implementation * - * Copyright 2000 Marcus Meissner - * Copyright 2000 TransGaming Technologies Inc. + * Copyright 2000 (c) Marcus Meissner + * Copyright 2000 (c) TransGaming Technologies Inc. + * Copyright 2006 (c) Stefan Dösinger * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -36,52 +37,97 @@ WINE_DEFAULT_DEBUG_CHANNEL(ddraw); -/****************************************************************************** - * DirectDrawCreateClipper (DDRAW.@) - */ +/***************************************************************************** + * IUnknown methods + *****************************************************************************/ -static const IDirectDrawClipperVtbl DDRAW_Clipper_VTable; - -HRESULT WINAPI DirectDrawCreateClipper( - DWORD dwFlags, LPDIRECTDRAWCLIPPER *lplpDDClipper, LPUNKNOWN pUnkOuter +/***************************************************************************** + * IDirectDrawClipper::QueryInterface + * + * Can query the IUnknown and IDirectDrawClipper interface from a + * Clipper object. The IUnknown Interface is equal to the IDirectDrawClipper + * interface. Can't create other interfaces. + * + * Arguments: + * riid: Interface id asked for + * ppvObj: Returns the pointer to the interface + * + * Return values: + * DD_OK on success + * E_NOINTERFACE if the requested interface wasn't found. + * + *****************************************************************************/ +static HRESULT WINAPI IDirectDrawClipperImpl_QueryInterface( + LPDIRECTDRAWCLIPPER iface, REFIID riid, LPVOID* ppvObj ) { - IDirectDrawClipperImpl* This; - TRACE("(%08lx,%p,%p)\n", dwFlags, lplpDDClipper, pUnkOuter); + IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface; - if (pUnkOuter != NULL) return CLASS_E_NOAGGREGATION; - - This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof(IDirectDrawClipperImpl)); - if (This == NULL) return E_OUTOFMEMORY; - - ICOM_INIT_INTERFACE(This, IDirectDrawClipper, DDRAW_Clipper_VTable); - This->ref = 1; - This->hWnd = 0; - This->ddraw_owner = NULL; - - *lplpDDClipper = ICOM_INTERFACE(This, IDirectDrawClipper); - return DD_OK; + if (IsEqualGUID(&IID_IUnknown, riid) + || IsEqualGUID(&IID_IDirectDrawClipper, riid)) + { + *ppvObj = ICOM_INTERFACE(This, IDirectDrawClipper); + InterlockedIncrement(&This->ref); + return S_OK; + } + else + { + return E_NOINTERFACE; + } } -/* This is the classfactory implementation. */ -HRESULT DDRAW_CreateDirectDrawClipper(IUnknown* pUnkOuter, REFIID riid, - LPVOID* ppObj) +/***************************************************************************** + * IDirectDrawClipper::AddRef + * + * Increases the reference count of the interface, returns the new count + * + *****************************************************************************/ +static ULONG WINAPI IDirectDrawClipperImpl_AddRef( LPDIRECTDRAWCLIPPER iface ) { - HRESULT hr; - LPDIRECTDRAWCLIPPER pClip; + IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface; + ULONG ref = InterlockedIncrement(&This->ref); - hr = DirectDrawCreateClipper(0, &pClip, pUnkOuter); - if (FAILED(hr)) return hr; + TRACE("(%p)->() incrementing from %lu.\n", This, ref - 1); - hr = IDirectDrawClipper_QueryInterface(pClip, riid, ppObj); - IDirectDrawClipper_Release(pClip); - return hr; + return ref; } -/****************************************************************************** - * IDirectDrawClipper - */ -HRESULT WINAPI Main_DirectDrawClipper_SetHwnd( +/***************************************************************************** + * IDirectDrawClipper::Release + * + * Decreases the reference count of the interface, returns the new count + * If the refcount is decreased to 0, the interface is destroyed. + * + *****************************************************************************/ +static ULONG WINAPI IDirectDrawClipperImpl_Release(IDirectDrawClipper *iface) { + IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface; + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p)->() decrementing from %lu.\n", This, ref + 1); + + if (ref == 0) + { + HeapFree(GetProcessHeap(), 0, This); + return 0; + } + else return ref; +} + +/***************************************************************************** + * IDirectDrawClipper::SetHwnd + * + * Assigns a hWnd to the clipper interface. + * + * Arguments: + * Flags: Unsupported so far + * hWnd: The hWnd to set + * + * Return values: + * DD_OK on success + * DDERR_INVALIDPARAMS if Flags was != 0 + * + *****************************************************************************/ + +static HRESULT WINAPI IDirectDrawClipperImpl_SetHwnd( LPDIRECTDRAWCLIPPER iface, DWORD dwFlags, HWND hWnd ) { IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface; @@ -96,52 +142,25 @@ HRESULT WINAPI Main_DirectDrawClipper_SetHwnd( return DD_OK; } -static void Main_DirectDrawClipper_Destroy(IDirectDrawClipperImpl* This) -{ - if (This->ddraw_owner != NULL) - Main_DirectDraw_RemoveClipper(This->ddraw_owner, This); - - HeapFree(GetProcessHeap(), 0 ,This); -} - -void Main_DirectDrawClipper_ForceDestroy(IDirectDrawClipperImpl* This) -{ - WARN("deleting clipper %p with refcnt %lu\n", This, This->ref); - Main_DirectDrawClipper_Destroy(This); -} - -ULONG WINAPI Main_DirectDrawClipper_Release(LPDIRECTDRAWCLIPPER iface) { - IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface; - ULONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p)->() decrementing from %lu.\n", This, ref + 1); - - if (ref == 0) - { - Main_DirectDrawClipper_Destroy(This); - return 0; - } - else return ref; -} - -/*********************************************************************** -* IDirectDrawClipper::GetClipList -* -* Retrieve a copy of the clip list -* -* PARAMS -* lpRect Rectangle to be used to clip the clip list or NULL for the -* entire clip list -* lpClipList structure for the resulting copy of the clip list. - If NULL, fills lpdwSize up to the number of bytes necessary to hold - the entire clip. -* lpdwSize Size of resulting clip list; size of the buffer at lpClipList - or, if lpClipList is NULL, receives the required size of the buffer - in bytes -* RETURNS -* Either DD_OK or DDERR_* -*/ -HRESULT WINAPI Main_DirectDrawClipper_GetClipList( +/***************************************************************************** + * IDirectDrawClipper::GetClipList + * + * Retrieve a copy of the clip list + * + * Arguments: + * Rect: Rectangle to be used to clip the clip list or NULL for the + * entire clip list + * ClipList: structure for the resulting copy of the clip list. + * If NULL, fills Size up to the number of bytes necessary to hold + * the entire clip. + * Size: Size of resulting clip list; size of the buffer at ClipList + * or, if ClipList is NULL, receives the required size of the buffer + * in bytes + * + * RETURNS + * Either DD_OK or DDERR_* + ************************************************************************/ +static HRESULT WINAPI IDirectDrawClipperImpl_GetClipList( LPDIRECTDRAWCLIPPER iface, LPRECT lpRect, LPRGNDATA lpClipList, LPDWORD lpdwSize) { @@ -188,18 +207,21 @@ HRESULT WINAPI Main_DirectDrawClipper_GetClipList( } } -/*********************************************************************** -* IDirectDrawClipper::SetClipList -* -* Sets or deletes (if lprgn is NULL) the clip list -* -* PARAMS -* lprgn Pointer to a LRGNDATA structure or NULL -* dwFlags not used, must be 0 -* RETURNS -* Either DD_OK or DDERR_* -*/ -HRESULT WINAPI Main_DirectDrawClipper_SetClipList( +/***************************************************************************** + * IDirectDrawClipper::SetClipList + * + * Sets or deletes (if lprgn is NULL) the clip list + * + * This implementation is a stup and returns DD_OK always to make the app + * happy. + * + * PARAMS + * lprgn Pointer to a LRGNDATA structure or NULL + * dwFlags not used, must be 0 + * RETURNS + * Either DD_OK or DDERR_* + *****************************************************************************/ +static HRESULT WINAPI IDirectDrawClipperImpl_SetClipList( LPDIRECTDRAWCLIPPER iface,LPRGNDATA lprgn,DWORD dwFlag ) { IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface; @@ -209,35 +231,18 @@ HRESULT WINAPI Main_DirectDrawClipper_SetClipList( return DD_OK; } -HRESULT WINAPI Main_DirectDrawClipper_QueryInterface( - LPDIRECTDRAWCLIPPER iface, REFIID riid, LPVOID* ppvObj -) { - IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface; - - if (IsEqualGUID(&IID_IUnknown, riid) - || IsEqualGUID(&IID_IDirectDrawClipper, riid)) - { - *ppvObj = ICOM_INTERFACE(This, IDirectDrawClipper); - InterlockedIncrement(&This->ref); - return S_OK; - } - else - { - return E_NOINTERFACE; - } -} - -ULONG WINAPI Main_DirectDrawClipper_AddRef( LPDIRECTDRAWCLIPPER iface ) -{ - IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface; - ULONG ref = InterlockedIncrement(&This->ref); - - TRACE("(%p)->() incrementing from %lu.\n", This, ref - 1); - - return ref; -} - -HRESULT WINAPI Main_DirectDrawClipper_GetHWnd( +/***************************************************************************** + * IDirectDrawClipper::GetHwnd + * + * Returns the hwnd assigned with SetHwnd + * + * Arguments: + * hWndPtr: Address to store the HWND at + * + * Return values: + * Always returns DD_OK; + *****************************************************************************/ +static HRESULT WINAPI IDirectDrawClipperImpl_GetHWnd( LPDIRECTDRAWCLIPPER iface, HWND* hWndPtr ) { IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface; @@ -248,7 +253,21 @@ HRESULT WINAPI Main_DirectDrawClipper_GetHWnd( return DD_OK; } -HRESULT WINAPI Main_DirectDrawClipper_Initialize( +/***************************************************************************** + * IDirectDrawClipper::Initialize + * + * Initializes the interface. Well, there isn't much to do for this + * implementation, but it stores the DirectDraw Interface. + * + * Arguments: + * DD: Pointer to a IDirectDraw interface + * Flags: Unsupported by now + * + * Return values: + * DD_OK on success + * DDERR_ALREADYINITIALIZED if this interface isn't initialized allready + *****************************************************************************/ +static HRESULT WINAPI IDirectDrawClipperImpl_Initialize( LPDIRECTDRAWCLIPPER iface, LPDIRECTDRAW lpDD, DWORD dwFlags ) { IDirectDrawImpl* pOwner; @@ -259,12 +278,22 @@ HRESULT WINAPI Main_DirectDrawClipper_Initialize( pOwner = ICOM_OBJECT(IDirectDrawImpl, IDirectDraw, lpDD); This->ddraw_owner = pOwner; - Main_DirectDraw_AddClipper(pOwner, This); return DD_OK; } -HRESULT WINAPI Main_DirectDrawClipper_IsClipListChanged( +/***************************************************************************** + * IDirectDrawClipper::IsClipListChanged + * + * This function is a stub + * + * Arguments: + * Changed: + * + * Return values: + * DD_OK, because it's a stub + *****************************************************************************/ +static HRESULT WINAPI IDirectDrawClipperImpl_IsClipListChanged( LPDIRECTDRAWCLIPPER iface, BOOL* lpbChanged ) { IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface; @@ -276,15 +305,18 @@ HRESULT WINAPI Main_DirectDrawClipper_IsClipListChanged( return DD_OK; } -static const IDirectDrawClipperVtbl DDRAW_Clipper_VTable = +/***************************************************************************** + * The VTable + *****************************************************************************/ +const IDirectDrawClipperVtbl IDirectDrawClipper_Vtbl = { - Main_DirectDrawClipper_QueryInterface, - Main_DirectDrawClipper_AddRef, - Main_DirectDrawClipper_Release, - Main_DirectDrawClipper_GetClipList, - Main_DirectDrawClipper_GetHWnd, - Main_DirectDrawClipper_Initialize, - Main_DirectDrawClipper_IsClipListChanged, - Main_DirectDrawClipper_SetClipList, - Main_DirectDrawClipper_SetHwnd + IDirectDrawClipperImpl_QueryInterface, + IDirectDrawClipperImpl_AddRef, + IDirectDrawClipperImpl_Release, + IDirectDrawClipperImpl_GetClipList, + IDirectDrawClipperImpl_GetHWnd, + IDirectDrawClipperImpl_Initialize, + IDirectDrawClipperImpl_IsClipListChanged, + IDirectDrawClipperImpl_SetClipList, + IDirectDrawClipperImpl_SetHwnd }; diff --git a/dlls/ddraw/d3d_private.h b/dlls/ddraw/d3d_private.h deleted file mode 100644 index 727c3f593d..0000000000 --- a/dlls/ddraw/d3d_private.h +++ /dev/null @@ -1,1234 +0,0 @@ -/* - * Direct3D private include file - * - * Copyright (c) 1998-2004 Lionel Ulmer - * Copyright (c) 2002-2005 Christian Costa - * - * This file contains all the structure that are not exported - * through d3d.h and all common macros. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#ifndef __GRAPHICS_WINE_D3D_PRIVATE_H -#define __GRAPHICS_WINE_D3D_PRIVATE_H - -/* THIS FILE MUST NOT CONTAIN X11 or MESA DEFINES */ - -#include - -#include "windef.h" -#include "winbase.h" -#include "wingdi.h" -#include "d3d.h" - -#define MAX_TEXTURES 8 -#define MAX_LIGHTS 16 - -#define HIGHEST_RENDER_STATE 152 -#define HIGHEST_TEXTURE_STAGE_STATE 24 - -/***************************************************************************** - * Predeclare the interface implementation structures - */ -typedef struct IDirect3DLightImpl IDirect3DLightImpl; -typedef struct IDirect3DMaterialImpl IDirect3DMaterialImpl; -typedef struct IDirect3DViewportImpl IDirect3DViewportImpl; -typedef struct IDirect3DExecuteBufferImpl IDirect3DExecuteBufferImpl; -typedef struct IDirect3DVertexBufferImpl IDirect3DVertexBufferImpl; - -#include "ddraw_private.h" - -typedef struct STATEBLOCKFLAGS { - BOOL render_state[HIGHEST_RENDER_STATE]; - BOOL texture_stage_state[MAX_TEXTURES][HIGHEST_TEXTURE_STAGE_STATE]; -} STATEBLOCKFLAGS; - -typedef struct STATEBLOCK { - STATEBLOCKFLAGS set_flags; - DWORD render_state[HIGHEST_RENDER_STATE]; - DWORD texture_stage_state[MAX_TEXTURES][HIGHEST_TEXTURE_STAGE_STATE]; -} STATEBLOCK; - - -/***************************************************************************** - * IDirect3DLight implementation structure - */ -struct IDirect3DLightImpl -{ - ICOM_VFIELD_MULTI(IDirect3DLight); - LONG ref; - /* IDirect3DLight fields */ - IDirectDrawImpl *d3d; - /* If this light is active for one viewport, put the viewport here */ - IDirect3DViewportImpl *active_viewport; - - D3DLIGHT2 light; - D3DLIGHT7 light7; - - DWORD dwLightIndex; - - /* Chained list used for adding / removing from viewports */ - IDirect3DLightImpl *next; - - /* Activation function */ - void (*activate)(IDirect3DLightImpl*); - void (*desactivate)(IDirect3DLightImpl*); - void (*update)(IDirect3DLightImpl*); -}; - -/***************************************************************************** - * IDirect3DMaterial implementation structure - */ -struct IDirect3DMaterialImpl -{ - ICOM_VFIELD_MULTI(IDirect3DMaterial3); - ICOM_VFIELD_MULTI(IDirect3DMaterial2); - ICOM_VFIELD_MULTI(IDirect3DMaterial); - LONG ref; - /* IDirect3DMaterial2 fields */ - IDirectDrawImpl *d3d; - IDirect3DDeviceImpl *active_device; - - D3DMATERIAL mat; - - void (*activate)(IDirect3DMaterialImpl* this); -}; - -/***************************************************************************** - * IDirect3DViewport implementation structure - */ -struct IDirect3DViewportImpl -{ - ICOM_VFIELD_MULTI(IDirect3DViewport3); - LONG ref; - /* IDirect3DViewport fields */ - IDirectDrawImpl *d3d; - /* If this viewport is active for one device, put the device here */ - IDirect3DDeviceImpl *active_device; - - DWORD num_lights; - DWORD map_lights; - - int use_vp2; - union { - D3DVIEWPORT vp1; - D3DVIEWPORT2 vp2; - } viewports; - - /* Activation function */ - void (*activate)(IDirect3DViewportImpl*); - - /* Field used to chain viewports together */ - IDirect3DViewportImpl *next; - - /* Lights list */ - IDirect3DLightImpl *lights; - - /* Background material */ - IDirect3DMaterialImpl *background; -}; - -/***************************************************************************** - * IDirect3DExecuteBuffer implementation structure - */ -struct IDirect3DExecuteBufferImpl -{ - ICOM_VFIELD_MULTI(IDirect3DExecuteBuffer); - LONG ref; - /* IDirect3DExecuteBuffer fields */ - IDirectDrawImpl *d3d; - IDirect3DDeviceImpl* d3ddev; - - D3DEXECUTEBUFFERDESC desc; - D3DEXECUTEDATA data; - - /* This buffer will store the transformed vertices */ - void* vertex_data; - WORD* indices; - int nb_indices; - - /* This flags is set to TRUE if we allocated ourselves the - data buffer */ - BOOL need_free; - - void (*execute)(IDirect3DExecuteBufferImpl* this, - IDirect3DDeviceImpl* dev, - IDirect3DViewportImpl* vp); -}; - -/* Internal structure to store the state of the clipping planes */ -typedef struct d3d7clippingplane -{ - D3DVALUE plane[4]; -} d3d7clippingplane; - -/***************************************************************************** - * IDirect3DDevice implementation structure - */ - -#define WORLDMAT_CHANGED (0x00000001 << 0) -#define VIEWMAT_CHANGED (0x00000001 << 1) -#define PROJMAT_CHANGED (0x00000001 << 2) -#define TEXMAT0_CHANGED (0x00000001 << 3) -#define TEXMAT1_CHANGED (0x00000001 << 4) -#define TEXMAT2_CHANGED (0x00000001 << 5) -#define TEXMAT3_CHANGED (0x00000001 << 6) -#define TEXMAT4_CHANGED (0x00000001 << 7) -#define TEXMAT5_CHANGED (0x00000001 << 8) -#define TEXMAT6_CHANGED (0x00000001 << 9) -#define TEXMAT7_CHANGED (0x00000001 << 10) - -struct IDirect3DDeviceImpl -{ - ICOM_VFIELD_MULTI(IDirect3DDevice7); - ICOM_VFIELD_MULTI(IDirect3DDevice3); - ICOM_VFIELD_MULTI(IDirect3DDevice2); - ICOM_VFIELD_MULTI(IDirect3DDevice); - LONG ref; - - /* Version of the Direct3D object from which the device has been created */ - DWORD version; - - /* IDirect3DDevice fields */ - IDirectDrawImpl *d3d; - IDirectDrawSurfaceImpl *surface; - - IDirect3DViewportImpl *viewport_list; - IDirect3DViewportImpl *current_viewport; - D3DVIEWPORT7 active_viewport; - - IDirectDrawSurfaceImpl *current_texture[MAX_TEXTURES]; - IDirectDrawSurfaceImpl *current_zbuffer; - - /* Current transformation matrices */ - D3DMATRIX *world_mat; - D3DMATRIX *view_mat; - D3DMATRIX *proj_mat; - D3DMATRIX *tex_mat[MAX_TEXTURES]; - BOOLEAN tex_mat_is_identity[MAX_TEXTURES]; - - /* Current material used in D3D7 mode */ - D3DMATERIAL7 current_material; - - /* Light state */ - DWORD material; - - /* Light parameters */ - DWORD num_set_lights; - DWORD max_active_lights; - LPD3DLIGHT7 light_parameters; - DWORD *active_lights; - - /* Clipping planes */ - DWORD max_clipping_planes; - d3d7clippingplane *clipping_planes; - - void (*set_context)(IDirect3DDeviceImpl*); - HRESULT (*clear)(IDirect3DDeviceImpl *This, - DWORD dwCount, - LPD3DRECT lpRects, - DWORD dwFlags, - DWORD dwColor, - D3DVALUE dvZ, - DWORD dwStencil); - void (*matrices_updated)(IDirect3DDeviceImpl *This, DWORD matrices); - void (*set_matrices)(IDirect3DDeviceImpl *This, DWORD matrices, - D3DMATRIX *world_mat, D3DMATRIX *view_mat, D3DMATRIX *proj_mat); - void (*flush_to_framebuffer)(IDirect3DDeviceImpl *This, LPCRECT pRect, IDirectDrawSurfaceImpl *surf); - - STATEBLOCK state_block; - - /* Used to prevent locks and rendering to overlap */ - CRITICAL_SECTION crit; - - /* Rendering functions */ - D3DPRIMITIVETYPE primitive_type; - DWORD vertex_type; - DWORD render_flags; - DWORD nb_vertices; - LPBYTE vertex_buffer; - DWORD vertex_size; - DWORD buffer_size; -}; - -/***************************************************************************** - * IDirect3DVertexBuffer implementation structure - */ -struct IDirect3DVertexBufferImpl -{ - ICOM_VFIELD_MULTI(IDirect3DVertexBuffer7); - ICOM_VFIELD_MULTI(IDirect3DVertexBuffer); - LONG ref; - IDirectDrawImpl *d3d; - D3DVERTEXBUFFERDESC desc; - LPVOID *vertices; - DWORD vertex_buffer_size; - - BOOLEAN processed; -}; - -/* Various dump and helper functions */ -#define GET_TEXCOUNT_FROM_FVF(d3dvtVertexType) \ - (((d3dvtVertexType) & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT) - -#define GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, tex_num) \ - (((((d3dvtVertexType) >> (16 + (2 * (tex_num)))) + 1) & 0x03) + 1) - -extern const char *_get_renderstate(D3DRENDERSTATETYPE type); -extern void dump_D3DMATERIAL7(LPD3DMATERIAL7 lpMat); -extern void dump_D3DCOLORVALUE(D3DCOLORVALUE *lpCol); -extern void dump_D3DLIGHT7(LPD3DLIGHT7 lpLight); -extern void dump_DPFLAGS(DWORD dwFlags); -extern void dump_D3DMATRIX(D3DMATRIX *mat); -extern void dump_D3DVECTOR(D3DVECTOR *lpVec); -extern void dump_flexible_vertex(DWORD d3dvtVertexType); -extern DWORD get_flexible_vertex_size(DWORD d3dvtVertexType); -extern void convert_FVF_to_strided_data(DWORD d3dvtVertexType, LPVOID lpvVertices, D3DDRAWPRIMITIVESTRIDEDDATA *strided, DWORD dwStartVertex); -extern void dump_D3DVOP(DWORD dwVertexOp); -extern void dump_D3DPV(DWORD dwFlags); -extern void multiply_matrix(LPD3DMATRIX,LPD3DMATRIX,LPD3DMATRIX); -extern void InitDefaultStateBlock(STATEBLOCK* lpStateBlock, int version); - -extern const float id_mat[16]; - -/***************************************************************************** - * IDirect3D object methods - */ -HRESULT WINAPI -Main_IDirect3DImpl_7_EnumDevices(LPDIRECT3D7 iface, - LPD3DENUMDEVICESCALLBACK7 lpEnumDevicesCallback, - LPVOID lpUserArg); - -HRESULT WINAPI -Main_IDirect3DImpl_7_CreateDevice(LPDIRECT3D7 iface, - REFCLSID rclsid, - LPDIRECTDRAWSURFACE7 lpDDS, - LPDIRECT3DDEVICE7* lplpD3DDevice); - -HRESULT WINAPI -Main_IDirect3DImpl_7_3T_CreateVertexBuffer(LPDIRECT3D7 iface, - LPD3DVERTEXBUFFERDESC lpD3DVertBufDesc, - LPDIRECT3DVERTEXBUFFER7* lplpD3DVertBuf, - DWORD dwFlags); - -HRESULT WINAPI -Main_IDirect3DImpl_7_3T_EnumZBufferFormats(LPDIRECT3D7 iface, - REFCLSID riidDevice, - LPD3DENUMPIXELFORMATSCALLBACK lpEnumCallback, - LPVOID lpContext); - -HRESULT WINAPI -Main_IDirect3DImpl_7_3T_EvictManagedTextures(LPDIRECT3D7 iface); - -HRESULT WINAPI -Main_IDirect3DImpl_3_2T_1T_EnumDevices(LPDIRECT3D3 iface, - LPD3DENUMDEVICESCALLBACK lpEnumDevicesCallback, - LPVOID lpUserArg); - -HRESULT WINAPI -Main_IDirect3DImpl_3_2T_1T_CreateLight(LPDIRECT3D3 iface, - LPDIRECT3DLIGHT* lplpDirect3DLight, - IUnknown* pUnkOuter); - -HRESULT WINAPI -Main_IDirect3DImpl_3_2T_1T_CreateMaterial(LPDIRECT3D3 iface, - LPDIRECT3DMATERIAL3* lplpDirect3DMaterial3, - IUnknown* pUnkOuter); - -HRESULT WINAPI -Main_IDirect3DImpl_3_2T_1T_CreateViewport(LPDIRECT3D3 iface, - LPDIRECT3DVIEWPORT3* lplpD3DViewport3, - IUnknown* pUnkOuter); - -HRESULT WINAPI -Main_IDirect3DImpl_3_2T_1T_FindDevice(LPDIRECT3D3 iface, - LPD3DFINDDEVICESEARCH lpD3DDFS, - LPD3DFINDDEVICERESULT lpD3DFDR); - -HRESULT WINAPI -Main_IDirect3DImpl_3_CreateDevice(LPDIRECT3D3 iface, - REFCLSID rclsid, - LPDIRECTDRAWSURFACE4 lpDDS, - LPDIRECT3DDEVICE3* lplpD3DDevice3, - LPUNKNOWN lpUnk); - -HRESULT WINAPI -Thunk_IDirect3DImpl_3_CreateVertexBuffer(LPDIRECT3D3 iface, - LPD3DVERTEXBUFFERDESC lpD3DVertBufDesc, - LPDIRECT3DVERTEXBUFFER* lplpD3DVertBuf, - DWORD dwFlags, - LPUNKNOWN lpUnk); - -HRESULT WINAPI -Thunk_IDirect3DImpl_2_CreateMaterial(LPDIRECT3D2 iface, - LPDIRECT3DMATERIAL2* lplpDirect3DMaterial2, - IUnknown* pUnkOuter); - -HRESULT WINAPI -Thunk_IDirect3DImpl_2_CreateViewport(LPDIRECT3D2 iface, - LPDIRECT3DVIEWPORT2* lplpD3DViewport2, - IUnknown* pUnkOuter); - -HRESULT WINAPI -Main_IDirect3DImpl_2_CreateDevice(LPDIRECT3D2 iface, - REFCLSID rclsid, - LPDIRECTDRAWSURFACE lpDDS, - LPDIRECT3DDEVICE2* lplpD3DDevice2); - -HRESULT WINAPI -Main_IDirect3DImpl_1_Initialize(LPDIRECT3D iface, - REFIID riid); - -HRESULT WINAPI -Thunk_IDirect3DImpl_1_CreateMaterial(LPDIRECT3D iface, - LPDIRECT3DMATERIAL* lplpDirect3DMaterial, - IUnknown* pUnkOuter); - -HRESULT WINAPI -Thunk_IDirect3DImpl_1_CreateViewport(LPDIRECT3D iface, - LPDIRECT3DVIEWPORT* lplpD3DViewport, - IUnknown* pUnkOuter); - -HRESULT WINAPI -Main_IDirect3DImpl_1_FindDevice(LPDIRECT3D iface, - LPD3DFINDDEVICESEARCH lpD3DDFS, - LPD3DFINDDEVICERESULT lplpD3DDevice); - -HRESULT WINAPI -Thunk_IDirect3DImpl_7_QueryInterface(LPDIRECT3D7 iface, - REFIID riid, - LPVOID* obp); - -HRESULT WINAPI -Thunk_IDirect3DImpl_3_QueryInterface(LPDIRECT3D3 iface, - REFIID riid, - LPVOID* obp); - -HRESULT WINAPI -Thunk_IDirect3DImpl_2_QueryInterface(LPDIRECT3D2 iface, - REFIID riid, - LPVOID* obp); - -HRESULT WINAPI -Thunk_IDirect3DImpl_1_QueryInterface(LPDIRECT3D iface, - REFIID riid, - LPVOID* obp); - -ULONG WINAPI -Thunk_IDirect3DImpl_7_AddRef(LPDIRECT3D7 iface); - -ULONG WINAPI -Thunk_IDirect3DImpl_3_AddRef(LPDIRECT3D3 iface); - -ULONG WINAPI -Thunk_IDirect3DImpl_2_AddRef(LPDIRECT3D2 iface); - -ULONG WINAPI -Thunk_IDirect3DImpl_1_AddRef(LPDIRECT3D iface); - -ULONG WINAPI -Thunk_IDirect3DImpl_7_Release(LPDIRECT3D7 iface); - -ULONG WINAPI -Thunk_IDirect3DImpl_3_Release(LPDIRECT3D3 iface); - -ULONG WINAPI -Thunk_IDirect3DImpl_2_Release(LPDIRECT3D2 iface); - -ULONG WINAPI -Thunk_IDirect3DImpl_1_Release(LPDIRECT3D iface); - -HRESULT WINAPI -Thunk_IDirect3DImpl_3_EnumZBufferFormats(LPDIRECT3D3 iface, - REFCLSID riidDevice, - LPD3DENUMPIXELFORMATSCALLBACK lpEnumCallback, - LPVOID lpContext); - -HRESULT WINAPI -Thunk_IDirect3DImpl_3_EvictManagedTextures(LPDIRECT3D3 iface); - -HRESULT WINAPI -Thunk_IDirect3DImpl_2_EnumDevices(LPDIRECT3D2 iface, - LPD3DENUMDEVICESCALLBACK lpEnumDevicesCallback, - LPVOID lpUserArg); - -HRESULT WINAPI -Thunk_IDirect3DImpl_1_EnumDevices(LPDIRECT3D iface, - LPD3DENUMDEVICESCALLBACK lpEnumDevicesCallback, - LPVOID lpUserArg); - -HRESULT WINAPI -Thunk_IDirect3DImpl_2_CreateLight(LPDIRECT3D2 iface, - LPDIRECT3DLIGHT* lplpDirect3DLight, - IUnknown* pUnkOuter); - -HRESULT WINAPI -Thunk_IDirect3DImpl_1_CreateLight(LPDIRECT3D iface, - LPDIRECT3DLIGHT* lplpDirect3DLight, - IUnknown* pUnkOuter); - -HRESULT WINAPI -Thunk_IDirect3DImpl_1_FindDevice(LPDIRECT3D iface, - LPD3DFINDDEVICESEARCH lpD3DDFS, - LPD3DFINDDEVICERESULT lplpD3DDevice); - -HRESULT WINAPI -Thunk_IDirect3DImpl_2_FindDevice(LPDIRECT3D2 iface, - LPD3DFINDDEVICESEARCH lpD3DDFS, - LPD3DFINDDEVICERESULT lpD3DFDR); - -/***************************************************************************** - * IDirect3DDevice object methods - */ -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_3T_2T_1T_QueryInterface(LPDIRECT3DDEVICE7 iface, - REFIID riid, - LPVOID* obp); - -ULONG WINAPI -Main_IDirect3DDeviceImpl_7_3T_2T_1T_AddRef(LPDIRECT3DDEVICE7 iface); - -ULONG WINAPI -Main_IDirect3DDeviceImpl_7_3T_2T_1T_Release(LPDIRECT3DDEVICE7 iface); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_GetCaps(LPDIRECT3DDEVICE7 iface, - LPD3DDEVICEDESC7 lpD3DHELDevDesc); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_3T_EnumTextureFormats(LPDIRECT3DDEVICE7 iface, - LPD3DENUMPIXELFORMATSCALLBACK lpD3DEnumPixelProc, - LPVOID lpArg); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_3T_2T_1T_BeginScene(LPDIRECT3DDEVICE7 iface); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_3T_2T_1T_EndScene(LPDIRECT3DDEVICE7 iface); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_3T_2T_1T_GetDirect3D(LPDIRECT3DDEVICE7 iface, - LPDIRECT3D7* lplpDirect3D3); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_3T_2T_SetRenderTarget(LPDIRECT3DDEVICE7 iface, - LPDIRECTDRAWSURFACE7 lpNewRenderTarget, - DWORD dwFlags); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_3T_2T_GetRenderTarget(LPDIRECT3DDEVICE7 iface, - LPDIRECTDRAWSURFACE7* lplpRenderTarget); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_Clear(LPDIRECT3DDEVICE7 iface, - DWORD dwCount, - LPD3DRECT lpRects, - DWORD dwFlags, - D3DCOLOR dwColor, - D3DVALUE dvZ, - DWORD dwStencil); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_3T_2T_SetTransform(LPDIRECT3DDEVICE7 iface, - D3DTRANSFORMSTATETYPE dtstTransformStateType, - LPD3DMATRIX lpD3DMatrix); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_3T_2T_GetTransform(LPDIRECT3DDEVICE7 iface, - D3DTRANSFORMSTATETYPE dtstTransformStateType, - LPD3DMATRIX lpD3DMatrix); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_SetViewport(LPDIRECT3DDEVICE7 iface, - LPD3DVIEWPORT7 lpData); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_3T_2T_MultiplyTransform(LPDIRECT3DDEVICE7 iface, - D3DTRANSFORMSTATETYPE dtstTransformStateType, - LPD3DMATRIX lpD3DMatrix); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_GetViewport(LPDIRECT3DDEVICE7 iface, - LPD3DVIEWPORT7 lpData); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_SetMaterial(LPDIRECT3DDEVICE7 iface, - LPD3DMATERIAL7 lpMat); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_GetMaterial(LPDIRECT3DDEVICE7 iface, - LPD3DMATERIAL7 lpMat); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_SetLight(LPDIRECT3DDEVICE7 iface, - DWORD dwLightIndex, - LPD3DLIGHT7 lpLight); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_GetLight(LPDIRECT3DDEVICE7 iface, - DWORD dwLightIndex, - LPD3DLIGHT7 lpLight); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_3T_2T_SetRenderState(LPDIRECT3DDEVICE7 iface, - D3DRENDERSTATETYPE dwRenderStateType, - DWORD dwRenderState); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_3T_2T_GetRenderState(LPDIRECT3DDEVICE7 iface, - D3DRENDERSTATETYPE dwRenderStateType, - LPDWORD lpdwRenderState); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_BeginStateBlock(LPDIRECT3DDEVICE7 iface); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_EndStateBlock(LPDIRECT3DDEVICE7 iface, - LPDWORD lpdwBlockHandle); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_PreLoad(LPDIRECT3DDEVICE7 iface, - LPDIRECTDRAWSURFACE7 lpddsTexture); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_3T_DrawPrimitive(LPDIRECT3DDEVICE7 iface, - D3DPRIMITIVETYPE d3dptPrimitiveType, - DWORD d3dvtVertexType, - LPVOID lpvVertices, - DWORD dwVertexCount, - DWORD dwFlags); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitive(LPDIRECT3DDEVICE7 iface, - D3DPRIMITIVETYPE d3dptPrimitiveType, - DWORD d3dvtVertexType, - LPVOID lpvVertices, - DWORD dwVertexCount, - LPWORD dwIndices, - DWORD dwIndexCount, - DWORD dwFlags); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_3T_2T_SetClipStatus(LPDIRECT3DDEVICE7 iface, - LPD3DCLIPSTATUS lpD3DClipStatus); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_3T_2T_GetClipStatus(LPDIRECT3DDEVICE7 iface, - LPD3DCLIPSTATUS lpD3DClipStatus); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_3T_DrawPrimitiveStrided(LPDIRECT3DDEVICE7 iface, - D3DPRIMITIVETYPE d3dptPrimitiveType, - DWORD dwVertexType, - LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData, - DWORD dwVertexCount, - DWORD dwFlags); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveStrided(LPDIRECT3DDEVICE7 iface, - D3DPRIMITIVETYPE d3dptPrimitiveType, - DWORD dwVertexType, - LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData, - DWORD dwVertexCount, - LPWORD lpIndex, - DWORD dwIndexCount, - DWORD dwFlags); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_3T_DrawPrimitiveVB(LPDIRECT3DDEVICE7 iface, - D3DPRIMITIVETYPE d3dptPrimitiveType, - LPDIRECT3DVERTEXBUFFER7 lpD3DVertexBuf, - DWORD dwStartVertex, - DWORD dwNumVertices, - DWORD dwFlags); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveVB(LPDIRECT3DDEVICE7 iface, - D3DPRIMITIVETYPE d3dptPrimitiveType, - LPDIRECT3DVERTEXBUFFER7 lpD3DVertexBuf, - DWORD dwStartVertex, - DWORD dwNumVertices, - LPWORD lpwIndices, - DWORD dwIndexCount, - DWORD dwFlags); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_3T_ComputeSphereVisibility(LPDIRECT3DDEVICE7 iface, - LPD3DVECTOR lpCenters, - LPD3DVALUE lpRadii, - DWORD dwNumSpheres, - DWORD dwFlags, - LPDWORD lpdwReturnValues); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_3T_GetTexture(LPDIRECT3DDEVICE7 iface, - DWORD dwStage, - LPDIRECTDRAWSURFACE7* lpTexture); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_3T_SetTexture(LPDIRECT3DDEVICE7 iface, - DWORD dwStage, - LPDIRECTDRAWSURFACE7 lpTexture); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_3T_GetTextureStageState(LPDIRECT3DDEVICE7 iface, - DWORD dwStage, - D3DTEXTURESTAGESTATETYPE d3dTexStageStateType, - LPDWORD lpdwState); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_3T_SetTextureStageState(LPDIRECT3DDEVICE7 iface, - DWORD dwStage, - D3DTEXTURESTAGESTATETYPE d3dTexStageStateType, - DWORD dwState); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_3T_ValidateDevice(LPDIRECT3DDEVICE7 iface, - LPDWORD lpdwPasses); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_ApplyStateBlock(LPDIRECT3DDEVICE7 iface, - DWORD dwBlockHandle); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_CaptureStateBlock(LPDIRECT3DDEVICE7 iface, - DWORD dwBlockHandle); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_DeleteStateBlock(LPDIRECT3DDEVICE7 iface, - DWORD dwBlockHandle); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_CreateStateBlock(LPDIRECT3DDEVICE7 iface, - D3DSTATEBLOCKTYPE d3dsbType, - LPDWORD lpdwBlockHandle); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_Load(LPDIRECT3DDEVICE7 iface, - LPDIRECTDRAWSURFACE7 lpDestTex, - LPPOINT lpDestPoint, - LPDIRECTDRAWSURFACE7 lpSrcTex, - LPRECT lprcSrcRect, - DWORD dwFlags); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_LightEnable(LPDIRECT3DDEVICE7 iface, - DWORD dwLightIndex, - BOOL bEnable); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_GetLightEnable(LPDIRECT3DDEVICE7 iface, - DWORD dwLightIndex, - BOOL* pbEnable); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_SetClipPlane(LPDIRECT3DDEVICE7 iface, - DWORD dwIndex, - D3DVALUE* pPlaneEquation); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_GetClipPlane(LPDIRECT3DDEVICE7 iface, - DWORD dwIndex, - D3DVALUE* pPlaneEquation); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_GetInfo(LPDIRECT3DDEVICE7 iface, - DWORD dwDevInfoID, - LPVOID pDevInfoStruct, - DWORD dwSize); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_3_2T_1T_GetCaps(LPDIRECT3DDEVICE3 iface, - LPD3DDEVICEDESC lpD3DHWDevDesc, - LPD3DDEVICEDESC lpD3DHELDevDesc); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_3_2T_1T_GetStats(LPDIRECT3DDEVICE3 iface, - LPD3DSTATS lpD3DStats); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_3_2T_1T_AddViewport(LPDIRECT3DDEVICE3 iface, - LPDIRECT3DVIEWPORT3 lpDirect3DViewport3); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_3_2T_1T_DeleteViewport(LPDIRECT3DDEVICE3 iface, - LPDIRECT3DVIEWPORT3 lpDirect3DViewport3); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_3_2T_1T_NextViewport(LPDIRECT3DDEVICE3 iface, - LPDIRECT3DVIEWPORT3 lpDirect3DViewport3, - LPDIRECT3DVIEWPORT3* lplpDirect3DViewport3, - DWORD dwFlags); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_3_2T_SetCurrentViewport(LPDIRECT3DDEVICE3 iface, - LPDIRECT3DVIEWPORT3 lpDirect3DViewport3); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_3_2T_GetCurrentViewport(LPDIRECT3DDEVICE3 iface, - LPDIRECT3DVIEWPORT3* lplpDirect3DViewport3); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_3_Begin(LPDIRECT3DDEVICE3 iface, - D3DPRIMITIVETYPE d3dptPrimitiveType, - DWORD dwVertexTypeDesc, - DWORD dwFlags); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_3_BeginIndexed(LPDIRECT3DDEVICE3 iface, - D3DPRIMITIVETYPE d3dptPrimitiveType, - DWORD d3dvtVertexType, - LPVOID lpvVertices, - DWORD dwNumVertices, - DWORD dwFlags); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_3_2T_Vertex(LPDIRECT3DDEVICE3 iface, - LPVOID lpVertexType); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_3_2T_Index(LPDIRECT3DDEVICE3 iface, - WORD wVertexIndex); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_3_2T_End(LPDIRECT3DDEVICE3 iface, - DWORD dwFlags); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_3_2T_GetLightState(LPDIRECT3DDEVICE3 iface, - D3DLIGHTSTATETYPE dwLightStateType, - LPDWORD lpdwLightState); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_3_2T_SetLightState(LPDIRECT3DDEVICE3 iface, - D3DLIGHTSTATETYPE dwLightStateType, - DWORD dwLightState); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_2_1T_SwapTextureHandles(LPDIRECT3DDEVICE2 iface, - LPDIRECT3DTEXTURE2 lpD3DTex1, - LPDIRECT3DTEXTURE2 lpD3DTex2); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_2_1T_EnumTextureFormats(LPDIRECT3DDEVICE2 iface, - LPD3DENUMTEXTUREFORMATSCALLBACK lpD3DEnumTextureProc, - LPVOID lpArg); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_2_Begin(LPDIRECT3DDEVICE2 iface, - D3DPRIMITIVETYPE d3dpt, - D3DVERTEXTYPE dwVertexTypeDesc, - DWORD dwFlags); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_2_BeginIndexed(LPDIRECT3DDEVICE2 iface, - D3DPRIMITIVETYPE d3dptPrimitiveType, - D3DVERTEXTYPE d3dvtVertexType, - LPVOID lpvVertices, - DWORD dwNumVertices, - DWORD dwFlags); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_2_DrawPrimitive(LPDIRECT3DDEVICE2 iface, - D3DPRIMITIVETYPE d3dptPrimitiveType, - D3DVERTEXTYPE d3dvtVertexType, - LPVOID lpvVertices, - DWORD dwVertexCount, - DWORD dwFlags); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_2_DrawIndexedPrimitive(LPDIRECT3DDEVICE2 iface, - D3DPRIMITIVETYPE d3dptPrimitiveType, - D3DVERTEXTYPE d3dvtVertexType, - LPVOID lpvVertices, - DWORD dwVertexCount, - LPWORD dwIndices, - DWORD dwIndexCount, - DWORD dwFlags); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_1_Initialize(LPDIRECT3DDEVICE iface, - LPDIRECT3D lpDirect3D, - LPGUID lpGUID, - LPD3DDEVICEDESC lpD3DDVDesc); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_1_CreateExecuteBuffer(LPDIRECT3DDEVICE iface, - LPD3DEXECUTEBUFFERDESC lpDesc, - LPDIRECT3DEXECUTEBUFFER* lplpDirect3DExecuteBuffer, - IUnknown* pUnkOuter); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_1_Execute(LPDIRECT3DDEVICE iface, - LPDIRECT3DEXECUTEBUFFER lpDirect3DExecuteBuffer, - LPDIRECT3DVIEWPORT lpDirect3DViewport, - DWORD dwFlags); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_1_Pick(LPDIRECT3DDEVICE iface, - LPDIRECT3DEXECUTEBUFFER lpDirect3DExecuteBuffer, - LPDIRECT3DVIEWPORT lpDirect3DViewport, - DWORD dwFlags, - LPD3DRECT lpRect); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_1_GetPickRecords(LPDIRECT3DDEVICE iface, - LPDWORD lpCount, - LPD3DPICKRECORD lpD3DPickRec); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_1_CreateMatrix(LPDIRECT3DDEVICE iface, - LPD3DMATRIXHANDLE lpD3DMatHandle); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_1_SetMatrix(LPDIRECT3DDEVICE iface, - D3DMATRIXHANDLE D3DMatHandle, - LPD3DMATRIX lpD3DMatrix); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_1_GetMatrix(LPDIRECT3DDEVICE iface, - D3DMATRIXHANDLE D3DMatHandle, - LPD3DMATRIX lpD3DMatrix); - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_1_DeleteMatrix(LPDIRECT3DDEVICE iface, - D3DMATRIXHANDLE D3DMatHandle); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_3_QueryInterface(LPDIRECT3DDEVICE3 iface, - REFIID riid, - LPVOID* obp); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_2_QueryInterface(LPDIRECT3DDEVICE2 iface, - REFIID riid, - LPVOID* obp); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_1_QueryInterface(LPDIRECT3DDEVICE iface, - REFIID riid, - LPVOID* obp); - -ULONG WINAPI -Thunk_IDirect3DDeviceImpl_3_AddRef(LPDIRECT3DDEVICE3 iface); - -ULONG WINAPI -Thunk_IDirect3DDeviceImpl_2_AddRef(LPDIRECT3DDEVICE2 iface); - -ULONG WINAPI -Thunk_IDirect3DDeviceImpl_1_AddRef(LPDIRECT3DDEVICE iface); - -ULONG WINAPI -Thunk_IDirect3DDeviceImpl_3_Release(LPDIRECT3DDEVICE3 iface); - -ULONG WINAPI -Thunk_IDirect3DDeviceImpl_2_Release(LPDIRECT3DDEVICE2 iface); - -ULONG WINAPI -Thunk_IDirect3DDeviceImpl_1_Release(LPDIRECT3DDEVICE iface); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_2_AddViewport(LPDIRECT3DDEVICE2 iface, - LPDIRECT3DVIEWPORT2 lpDirect3DViewport2); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_1_AddViewport(LPDIRECT3DDEVICE iface, - LPDIRECT3DVIEWPORT lpDirect3DViewport); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_2_DeleteViewport(LPDIRECT3DDEVICE2 iface, - LPDIRECT3DVIEWPORT2 lpDirect3DViewport2); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_1_DeleteViewport(LPDIRECT3DDEVICE iface, - LPDIRECT3DVIEWPORT lpDirect3DViewport); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_2_NextViewport(LPDIRECT3DDEVICE2 iface, - LPDIRECT3DVIEWPORT2 lpDirect3DViewport2, - LPDIRECT3DVIEWPORT2* lplpDirect3DViewport2, - DWORD dwFlags); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_1_NextViewport(LPDIRECT3DDEVICE iface, - LPDIRECT3DVIEWPORT lpDirect3DViewport, - LPDIRECT3DVIEWPORT* lplpDirect3DViewport, - DWORD dwFlags); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_3_GetDirect3D(LPDIRECT3DDEVICE3 iface, - LPDIRECT3D3* lplpDirect3D3); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_2_GetDirect3D(LPDIRECT3DDEVICE2 iface, - LPDIRECT3D2* lplpDirect3D2); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_1_GetDirect3D(LPDIRECT3DDEVICE iface, - LPDIRECT3D* lplpDirect3D); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport(LPDIRECT3DDEVICE2 iface, - LPDIRECT3DVIEWPORT2 lpDirect3DViewport2); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport(LPDIRECT3DDEVICE2 iface, - LPDIRECT3DVIEWPORT2* lpDirect3DViewport2); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats(LPDIRECT3DDEVICE3 iface, - LPD3DENUMPIXELFORMATSCALLBACK lpD3DEnumPixelProc, - LPVOID lpArg); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_3_BeginScene(LPDIRECT3DDEVICE3 iface); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_2_BeginScene(LPDIRECT3DDEVICE2 iface); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_1_BeginScene(LPDIRECT3DDEVICE iface); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_3_EndScene(LPDIRECT3DDEVICE3 iface); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_2_EndScene(LPDIRECT3DDEVICE2 iface); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_1_EndScene(LPDIRECT3DDEVICE iface); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_3_SetTransform(LPDIRECT3DDEVICE3 iface, - D3DTRANSFORMSTATETYPE dtstTransformStateType, - LPD3DMATRIX lpD3DMatrix); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_2_SetTransform(LPDIRECT3DDEVICE2 iface, - D3DTRANSFORMSTATETYPE dtstTransformStateType, - LPD3DMATRIX lpD3DMatrix); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_3_GetTransform(LPDIRECT3DDEVICE3 iface, - D3DTRANSFORMSTATETYPE dtstTransformStateType, - LPD3DMATRIX lpD3DMatrix); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_2_GetTransform(LPDIRECT3DDEVICE2 iface, - D3DTRANSFORMSTATETYPE dtstTransformStateType, - LPD3DMATRIX lpD3DMatrix); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_3_MultiplyTransform(LPDIRECT3DDEVICE3 iface, - D3DTRANSFORMSTATETYPE dtstTransformStateType, - LPD3DMATRIX lpD3DMatrix); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_2_MultiplyTransform(LPDIRECT3DDEVICE2 iface, - D3DTRANSFORMSTATETYPE dtstTransformStateType, - LPD3DMATRIX lpD3DMatrix); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_3_SetRenderState(LPDIRECT3DDEVICE3 iface, - D3DRENDERSTATETYPE dwRenderStateType, - DWORD dwRenderState); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_2_SetRenderState(LPDIRECT3DDEVICE2 iface, - D3DRENDERSTATETYPE dwRenderStateType, - DWORD dwRenderState); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_3_GetRenderState(LPDIRECT3DDEVICE3 iface, - D3DRENDERSTATETYPE dwRenderStateType, - LPDWORD lpdwRenderState); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_2_GetRenderState(LPDIRECT3DDEVICE2 iface, - D3DRENDERSTATETYPE dwRenderStateType, - LPDWORD lpdwRenderState); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_3_DrawPrimitive(LPDIRECT3DDEVICE3 iface, - D3DPRIMITIVETYPE d3dptPrimitiveType, - DWORD d3dvtVertexType, - LPVOID lpvVertices, - DWORD dwVertexCount, - DWORD dwFlags); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive(LPDIRECT3DDEVICE3 iface, - D3DPRIMITIVETYPE d3dptPrimitiveType, - DWORD d3dvtVertexType, - LPVOID lpvVertices, - DWORD dwVertexCount, - LPWORD dwIndices, - DWORD dwIndexCount, - DWORD dwFlags); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_3_SetClipStatus(LPDIRECT3DDEVICE3 iface, - LPD3DCLIPSTATUS lpD3DClipStatus); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_2_SetClipStatus(LPDIRECT3DDEVICE2 iface, - LPD3DCLIPSTATUS lpD3DClipStatus); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_3_GetClipStatus(LPDIRECT3DDEVICE3 iface, - LPD3DCLIPSTATUS lpD3DClipStatus); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_2_GetClipStatus(LPDIRECT3DDEVICE2 iface, - LPD3DCLIPSTATUS lpD3DClipStatus); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided(LPDIRECT3DDEVICE3 iface, - D3DPRIMITIVETYPE d3dptPrimitiveType, - DWORD dwVertexType, - LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData, - DWORD dwVertexCount, - DWORD dwFlags); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided(LPDIRECT3DDEVICE3 iface, - D3DPRIMITIVETYPE d3dptPrimitiveType, - DWORD dwVertexType, - LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData, - DWORD dwVertexCount, - LPWORD lpIndex, - DWORD dwIndexCount, - DWORD dwFlags); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility(LPDIRECT3DDEVICE3 iface, - LPD3DVECTOR lpCenters, - LPD3DVALUE lpRadii, - DWORD dwNumSpheres, - DWORD dwFlags, - LPDWORD lpdwReturnValues); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_3_GetTextureStageState(LPDIRECT3DDEVICE3 iface, - DWORD dwStage, - D3DTEXTURESTAGESTATETYPE d3dTexStageStateType, - LPDWORD lpdwState); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_3_SetTextureStageState(LPDIRECT3DDEVICE3 iface, - DWORD dwStage, - D3DTEXTURESTAGESTATETYPE d3dTexStageStateType, - DWORD dwState); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_3_ValidateDevice(LPDIRECT3DDEVICE3 iface, - LPDWORD lpdwPasses); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_2_GetCaps(LPDIRECT3DDEVICE2 iface, - LPD3DDEVICEDESC lpD3DHWDevDesc, - LPD3DDEVICEDESC lpD3DHELDevDesc); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_1_GetCaps(LPDIRECT3DDEVICE iface, - LPD3DDEVICEDESC lpD3DHWDevDesc, - LPD3DDEVICEDESC lpD3DHELDevDesc); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_1_SwapTextureHandles(LPDIRECT3DDEVICE iface, - LPDIRECT3DTEXTURE lpD3Dtex1, - LPDIRECT3DTEXTURE lpD3DTex2); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_2_GetStats(LPDIRECT3DDEVICE2 iface, - LPD3DSTATS lpD3DStats); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_1_GetStats(LPDIRECT3DDEVICE iface, - LPD3DSTATS lpD3DStats); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_3_SetRenderTarget(LPDIRECT3DDEVICE3 iface, - LPDIRECTDRAWSURFACE4 lpNewRenderTarget, - DWORD dwFlags); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_3_GetRenderTarget(LPDIRECT3DDEVICE3 iface, - LPDIRECTDRAWSURFACE4* lplpRenderTarget); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_2_SetRenderTarget(LPDIRECT3DDEVICE2 iface, - LPDIRECTDRAWSURFACE lpNewRenderTarget, - DWORD dwFlags); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_2_GetRenderTarget(LPDIRECT3DDEVICE2 iface, - LPDIRECTDRAWSURFACE* lplpRenderTarget); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_2_Vertex(LPDIRECT3DDEVICE2 iface, - LPVOID lpVertexType); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_2_Index(LPDIRECT3DDEVICE2 iface, - WORD wVertexIndex); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_2_End(LPDIRECT3DDEVICE2 iface, - DWORD dwFlags); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_2_GetLightState(LPDIRECT3DDEVICE2 iface, - D3DLIGHTSTATETYPE dwLightStateType, - LPDWORD lpdwLightState); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_2_SetLightState(LPDIRECT3DDEVICE2 iface, - D3DLIGHTSTATETYPE dwLightStateType, - DWORD dwLightState); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats(LPDIRECT3DDEVICE iface, - LPD3DENUMTEXTUREFORMATSCALLBACK lpD3DEnumTextureProc, - LPVOID lpArg); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_3_SetTexture(LPDIRECT3DDEVICE3 iface, - DWORD dwStage, - LPDIRECT3DTEXTURE2 lpTexture2); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB(LPDIRECT3DDEVICE3 iface, - D3DPRIMITIVETYPE d3dptPrimitiveType, - LPDIRECT3DVERTEXBUFFER lpD3DVertexBuf, - DWORD dwStartVertex, - DWORD dwNumVertices, - DWORD dwFlags); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB(LPDIRECT3DDEVICE3 iface, - D3DPRIMITIVETYPE d3dptPrimitiveType, - LPDIRECT3DVERTEXBUFFER lpD3DVertexBuf, - LPWORD lpwIndices, - DWORD dwIndexCount, - DWORD dwFlags); - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_3_GetTexture(LPDIRECT3DDEVICE3 iface, - DWORD dwStage, - LPDIRECT3DTEXTURE2* lplpTexture2); - -#endif /* __GRAPHICS_WINE_D3D_PRIVATE_H */ diff --git a/dlls/ddraw/d3d_utils.c b/dlls/ddraw/d3d_utils.c deleted file mode 100644 index 27f2df3490..0000000000 --- a/dlls/ddraw/d3d_utils.c +++ /dev/null @@ -1,391 +0,0 @@ -/* Direct3D Common functions - * Copyright (c) 1998 Lionel ULMER - * - * This file contains all common miscellaneous code that spans - * different 'objects' - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include - -#define NONAMELESSUNION -#define NONAMELESSSTRUCT -#include "windef.h" -#include "winbase.h" -#include "objbase.h" -#include "wingdi.h" -#include "ddraw.h" -#include "d3d.h" -#include "wine/debug.h" - -#include "d3d_private.h" - -WINE_DEFAULT_DEBUG_CHANNEL(ddraw); - -const char *_get_renderstate(D3DRENDERSTATETYPE type) { - static const char * const states[] = { - "ERR", - "D3DRENDERSTATE_TEXTUREHANDLE", - "D3DRENDERSTATE_ANTIALIAS", - "D3DRENDERSTATE_TEXTUREADDRESS", - "D3DRENDERSTATE_TEXTUREPERSPECTIVE", - "D3DRENDERSTATE_WRAPU", - "D3DRENDERSTATE_WRAPV", - "D3DRENDERSTATE_ZENABLE", - "D3DRENDERSTATE_FILLMODE", - "D3DRENDERSTATE_SHADEMODE", - "D3DRENDERSTATE_LINEPATTERN", - "D3DRENDERSTATE_MONOENABLE", - "D3DRENDERSTATE_ROP2", - "D3DRENDERSTATE_PLANEMASK", - "D3DRENDERSTATE_ZWRITEENABLE", - "D3DRENDERSTATE_ALPHATESTENABLE", - "D3DRENDERSTATE_LASTPIXEL", - "D3DRENDERSTATE_TEXTUREMAG", - "D3DRENDERSTATE_TEXTUREMIN", - "D3DRENDERSTATE_SRCBLEND", - "D3DRENDERSTATE_DESTBLEND", - "D3DRENDERSTATE_TEXTUREMAPBLEND", - "D3DRENDERSTATE_CULLMODE", - "D3DRENDERSTATE_ZFUNC", - "D3DRENDERSTATE_ALPHAREF", - "D3DRENDERSTATE_ALPHAFUNC", - "D3DRENDERSTATE_DITHERENABLE", - "D3DRENDERSTATE_ALPHABLENDENABLE", - "D3DRENDERSTATE_FOGENABLE", - "D3DRENDERSTATE_SPECULARENABLE", - "D3DRENDERSTATE_ZVISIBLE", - "D3DRENDERSTATE_SUBPIXEL", - "D3DRENDERSTATE_SUBPIXELX", - "D3DRENDERSTATE_STIPPLEDALPHA", - "D3DRENDERSTATE_FOGCOLOR", - "D3DRENDERSTATE_FOGTABLEMODE", - "D3DRENDERSTATE_FOGTABLESTART", - "D3DRENDERSTATE_FOGTABLEEND", - "D3DRENDERSTATE_FOGTABLEDENSITY", - "D3DRENDERSTATE_STIPPLEENABLE", - "D3DRENDERSTATE_EDGEANTIALIAS", - "D3DRENDERSTATE_COLORKEYENABLE", - "ERR", - "D3DRENDERSTATE_BORDERCOLOR", - "D3DRENDERSTATE_TEXTUREADDRESSU", - "D3DRENDERSTATE_TEXTUREADDRESSV", - "D3DRENDERSTATE_MIPMAPLODBIAS", - "D3DRENDERSTATE_ZBIAS", - "D3DRENDERSTATE_RANGEFOGENABLE", - "D3DRENDERSTATE_ANISOTROPY", - "D3DRENDERSTATE_FLUSHBATCH", - "D3DRENDERSTATE_TRANSLUCENTSORTINDEPENDENT", - "D3DRENDERSTATE_STENCILENABLE", - "D3DRENDERSTATE_STENCILFAIL", - "D3DRENDERSTATE_STENCILZFAIL", - "D3DRENDERSTATE_STENCILPASS", - "D3DRENDERSTATE_STENCILFUNC", - "D3DRENDERSTATE_STENCILREF", - "D3DRENDERSTATE_STENCILMASK", - "D3DRENDERSTATE_STENCILWRITEMASK", - "D3DRENDERSTATE_TEXTUREFACTOR", - "ERR", - "ERR", - "ERR", - "D3DRENDERSTATE_STIPPLEPATTERN00", - "D3DRENDERSTATE_STIPPLEPATTERN01", - "D3DRENDERSTATE_STIPPLEPATTERN02", - "D3DRENDERSTATE_STIPPLEPATTERN03", - "D3DRENDERSTATE_STIPPLEPATTERN04", - "D3DRENDERSTATE_STIPPLEPATTERN05", - "D3DRENDERSTATE_STIPPLEPATTERN06", - "D3DRENDERSTATE_STIPPLEPATTERN07", - "D3DRENDERSTATE_STIPPLEPATTERN08", - "D3DRENDERSTATE_STIPPLEPATTERN09", - "D3DRENDERSTATE_STIPPLEPATTERN10", - "D3DRENDERSTATE_STIPPLEPATTERN11", - "D3DRENDERSTATE_STIPPLEPATTERN12", - "D3DRENDERSTATE_STIPPLEPATTERN13", - "D3DRENDERSTATE_STIPPLEPATTERN14", - "D3DRENDERSTATE_STIPPLEPATTERN15", - "D3DRENDERSTATE_STIPPLEPATTERN16", - "D3DRENDERSTATE_STIPPLEPATTERN17", - "D3DRENDERSTATE_STIPPLEPATTERN18", - "D3DRENDERSTATE_STIPPLEPATTERN19", - "D3DRENDERSTATE_STIPPLEPATTERN20", - "D3DRENDERSTATE_STIPPLEPATTERN21", - "D3DRENDERSTATE_STIPPLEPATTERN22", - "D3DRENDERSTATE_STIPPLEPATTERN23", - "D3DRENDERSTATE_STIPPLEPATTERN24", - "D3DRENDERSTATE_STIPPLEPATTERN25", - "D3DRENDERSTATE_STIPPLEPATTERN26", - "D3DRENDERSTATE_STIPPLEPATTERN27", - "D3DRENDERSTATE_STIPPLEPATTERN28", - "D3DRENDERSTATE_STIPPLEPATTERN29", - "D3DRENDERSTATE_STIPPLEPATTERN30", - "D3DRENDERSTATE_STIPPLEPATTERN31" - }; - static const char * const states_2[] = { - "D3DRENDERSTATE_WRAP0", - "D3DRENDERSTATE_WRAP1", - "D3DRENDERSTATE_WRAP2", - "D3DRENDERSTATE_WRAP3", - "D3DRENDERSTATE_WRAP4", - "D3DRENDERSTATE_WRAP5", - "D3DRENDERSTATE_WRAP6", - "D3DRENDERSTATE_WRAP7", - "D3DRENDERSTATE_CLIPPING", - "D3DRENDERSTATE_LIGHTING", - "D3DRENDERSTATE_EXTENTS", - "D3DRENDERSTATE_AMBIENT", - "D3DRENDERSTATE_FOGVERTEXMODE", - "D3DRENDERSTATE_COLORVERTEX", - "D3DRENDERSTATE_LOCALVIEWER", - "D3DRENDERSTATE_NORMALIZENORMALS", - "D3DRENDERSTATE_COLORKEYBLENDENABLE", - "D3DRENDERSTATE_DIFFUSEMATERIALSOURCE", - "D3DRENDERSTATE_SPECULARMATERIALSOURCE", - "D3DRENDERSTATE_AMBIENTMATERIALSOURCE", - "D3DRENDERSTATE_EMISSIVEMATERIALSOURCE", - "ERR", - "ERR", - "D3DRENDERSTATE_VERTEXBLEND", - "D3DRENDERSTATE_CLIPPLANEENABLE", - }; - if (type >= D3DRENDERSTATE_WRAP0) { - type -= D3DRENDERSTATE_WRAP0; - if (type >= (sizeof(states_2) / sizeof(states_2[0]))) return "ERR"; - return states_2[type]; - } - if (type >= (sizeof(states) / sizeof(states[0]))) return "ERR"; - return states[type]; -} - -void -dump_D3DCOLORVALUE(D3DCOLORVALUE *lpCol) -{ - DPRINTF("%f %f %f %f", lpCol->u1.r, lpCol->u2.g, lpCol->u3.b, lpCol->u4.a); -} - -void -dump_D3DVECTOR(D3DVECTOR *lpVec) -{ - DPRINTF("%f %f %f", lpVec->u1.x, lpVec->u2.y, lpVec->u3.z); -} - -void -dump_D3DMATERIAL7(LPD3DMATERIAL7 lpMat) -{ - DPRINTF(" - diffuse : "); dump_D3DCOLORVALUE(&(lpMat->u.diffuse)); DPRINTF("\n"); - DPRINTF(" - ambient : "); dump_D3DCOLORVALUE(&(lpMat->u1.ambient)); DPRINTF("\n"); - DPRINTF(" - specular : "); dump_D3DCOLORVALUE(&(lpMat->u2.specular)); DPRINTF("\n"); - DPRINTF(" - emissive : "); dump_D3DCOLORVALUE(&(lpMat->u3.emissive)); DPRINTF("\n"); - DPRINTF(" - power : %f\n", lpMat->u4.power); -} - -void -dump_D3DLIGHT7(LPD3DLIGHT7 lpLight) -{ - DPRINTF(" - light type : %s\n", (lpLight->dltType == D3DLIGHT_POINT ? "D3DLIGHT_POINT" : - (lpLight->dltType == D3DLIGHT_SPOT ? "D3DLIGHT_SPOT" : - (lpLight->dltType == D3DLIGHT_DIRECTIONAL ? "D3DLIGHT_DIRECTIONAL" : - "UNSUPPORTED")))); - DPRINTF(" - diffuse : "); dump_D3DCOLORVALUE(&(lpLight->dcvDiffuse)); DPRINTF("\n"); - DPRINTF(" - specular : "); dump_D3DCOLORVALUE(&(lpLight->dcvSpecular)); DPRINTF("\n"); - DPRINTF(" - ambient : "); dump_D3DCOLORVALUE(&(lpLight->dcvAmbient)); DPRINTF("\n"); - DPRINTF(" - position : "); dump_D3DVECTOR(&(lpLight->dvPosition)); DPRINTF("\n"); - DPRINTF(" - direction : "); dump_D3DVECTOR(&(lpLight->dvDirection)); DPRINTF("\n"); - DPRINTF(" - dvRange : %f\n", lpLight->dvRange); - DPRINTF(" - dvFalloff : %f\n", lpLight->dvFalloff); - DPRINTF(" - dvAttenuation : %f %f %f\n", lpLight->dvAttenuation0, lpLight->dvAttenuation1, lpLight->dvAttenuation2); - DPRINTF(" - dvTheta : %f\n", lpLight->dvTheta); - DPRINTF(" - dvPhi : %f\n", lpLight->dvPhi); -} - -void -dump_DPFLAGS(DWORD dwFlags) -{ - static const flag_info flags[] = - { - FE(D3DDP_WAIT), - FE(D3DDP_OUTOFORDER), - FE(D3DDP_DONOTCLIP), - FE(D3DDP_DONOTUPDATEEXTENTS), - FE(D3DDP_DONOTLIGHT) - }; - - DDRAW_dump_flags(dwFlags, flags, sizeof(flags)/sizeof(flags[0])); -} - -void -dump_D3DMATRIX(D3DMATRIX *mat) -{ - DPRINTF(" %f %f %f %f\n", mat->_11, mat->_12, mat->_13, mat->_14); - DPRINTF(" %f %f %f %f\n", mat->_21, mat->_22, mat->_23, mat->_24); - DPRINTF(" %f %f %f %f\n", mat->_31, mat->_32, mat->_33, mat->_34); - DPRINTF(" %f %f %f %f\n", mat->_41, mat->_42, mat->_43, mat->_44); -} - -DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) -{ - DWORD size = 0; - int i; - - if (d3dvtVertexType & D3DFVF_NORMAL) size += 3 * sizeof(D3DVALUE); - if (d3dvtVertexType & D3DFVF_DIFFUSE) size += sizeof(DWORD); - if (d3dvtVertexType & D3DFVF_SPECULAR) size += sizeof(DWORD); - if (d3dvtVertexType & D3DFVF_RESERVED1) size += sizeof(DWORD); - switch (d3dvtVertexType & D3DFVF_POSITION_MASK) { - case D3DFVF_XYZ: size += 3 * sizeof(D3DVALUE); break; - case D3DFVF_XYZRHW: size += 4 * sizeof(D3DVALUE); break; - default: TRACE(" matrix weighting not handled yet...\n"); - } - for (i = 0; i < GET_TEXCOUNT_FROM_FVF(d3dvtVertexType); i++) { - size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(D3DVALUE); - } - - return size; -} - -void dump_flexible_vertex(DWORD d3dvtVertexType) -{ - static const flag_info flags[] = { - FE(D3DFVF_NORMAL), - FE(D3DFVF_RESERVED1), - FE(D3DFVF_DIFFUSE), - FE(D3DFVF_SPECULAR) - }; - unsigned int i; - - if (d3dvtVertexType & D3DFVF_RESERVED0) DPRINTF("D3DFVF_RESERVED0 "); - switch (d3dvtVertexType & D3DFVF_POSITION_MASK) { -#define GEN_CASE(a) case a: DPRINTF(#a " "); break - GEN_CASE(D3DFVF_XYZ); - GEN_CASE(D3DFVF_XYZRHW); - GEN_CASE(D3DFVF_XYZB1); - GEN_CASE(D3DFVF_XYZB2); - GEN_CASE(D3DFVF_XYZB3); - GEN_CASE(D3DFVF_XYZB4); - GEN_CASE(D3DFVF_XYZB5); - } - DDRAW_dump_flags_(d3dvtVertexType, flags, sizeof(flags)/sizeof(flags[0]), FALSE); - switch (d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) { - GEN_CASE(D3DFVF_TEX0); - GEN_CASE(D3DFVF_TEX1); - GEN_CASE(D3DFVF_TEX2); - GEN_CASE(D3DFVF_TEX3); - GEN_CASE(D3DFVF_TEX4); - GEN_CASE(D3DFVF_TEX5); - GEN_CASE(D3DFVF_TEX6); - GEN_CASE(D3DFVF_TEX7); - GEN_CASE(D3DFVF_TEX8); - } -#undef GEN_CASE - for (i = 0; i < GET_TEXCOUNT_FROM_FVF(d3dvtVertexType); i++) { - DPRINTF(" T%d-s%ld", i + 1, GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i)); - } - DPRINTF("\n"); -} - -void -convert_FVF_to_strided_data(DWORD d3dvtVertexType, LPVOID lpvVertices, D3DDRAWPRIMITIVESTRIDEDDATA *strided, DWORD dwStartVertex) -{ - int current_offset = 0; - unsigned int tex_index; - int size = get_flexible_vertex_size(d3dvtVertexType); - - lpvVertices = ((BYTE *) lpvVertices) + (size * dwStartVertex); - - if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) { - strided->position.lpvData = lpvVertices; - current_offset += 3 * sizeof(D3DVALUE); - } else { - strided->position.lpvData = lpvVertices; - current_offset += 4 * sizeof(D3DVALUE); - } - if (d3dvtVertexType & D3DFVF_RESERVED1) { - current_offset += sizeof(DWORD); - } - if (d3dvtVertexType & D3DFVF_NORMAL) { - strided->normal.lpvData = ((char *) lpvVertices) + current_offset; - current_offset += 3 * sizeof(D3DVALUE); - } - if (d3dvtVertexType & D3DFVF_DIFFUSE) { - strided->diffuse.lpvData = ((char *) lpvVertices) + current_offset; - current_offset += sizeof(DWORD); - } - if (d3dvtVertexType & D3DFVF_SPECULAR) { - strided->specular.lpvData = ((char *) lpvVertices) + current_offset; - current_offset += sizeof(DWORD); - } - for (tex_index = 0; tex_index < GET_TEXCOUNT_FROM_FVF(d3dvtVertexType); tex_index++) { - strided->textureCoords[tex_index].lpvData = ((char *) lpvVertices) + current_offset; - current_offset += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, tex_index) * sizeof(D3DVALUE); - } - strided->position.dwStride = current_offset; - strided->normal.dwStride = current_offset; - strided->diffuse.dwStride = current_offset; - strided->specular.dwStride = current_offset; - for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) - strided->textureCoords[tex_index].dwStride = current_offset; -} - -void -dump_D3DVOP(DWORD dwVertexOp) -{ - static const flag_info flags[] = - { - FE(D3DVOP_LIGHT), - FE(D3DVOP_CLIP), - FE(D3DVOP_EXTENTS), - FE(D3DVOP_TRANSFORM) - }; - DDRAW_dump_flags(dwVertexOp, flags, sizeof(flags)/sizeof(flags[0])); -} - -void -dump_D3DPV(DWORD dwFlags) -{ - if (dwFlags == D3DPV_DONOTCOPYDATA) DPRINTF("D3DPV_DONOTCOPYDATA\n"); - else if (dwFlags != 0) DPRINTF("Unknown !!!\n"); - else DPRINTF("\n"); -} - -void multiply_matrix(LPD3DMATRIX dest, LPD3DMATRIX src1, LPD3DMATRIX src2) -{ - D3DMATRIX temp; - - /* Now do the multiplication 'by hand'. - I know that all this could be optimised, but this will be done later :-) */ - temp._11 = (src1->_11 * src2->_11) + (src1->_21 * src2->_12) + (src1->_31 * src2->_13) + (src1->_41 * src2->_14); - temp._21 = (src1->_11 * src2->_21) + (src1->_21 * src2->_22) + (src1->_31 * src2->_23) + (src1->_41 * src2->_24); - temp._31 = (src1->_11 * src2->_31) + (src1->_21 * src2->_32) + (src1->_31 * src2->_33) + (src1->_41 * src2->_34); - temp._41 = (src1->_11 * src2->_41) + (src1->_21 * src2->_42) + (src1->_31 * src2->_43) + (src1->_41 * src2->_44); - - temp._12 = (src1->_12 * src2->_11) + (src1->_22 * src2->_12) + (src1->_32 * src2->_13) + (src1->_42 * src2->_14); - temp._22 = (src1->_12 * src2->_21) + (src1->_22 * src2->_22) + (src1->_32 * src2->_23) + (src1->_42 * src2->_24); - temp._32 = (src1->_12 * src2->_31) + (src1->_22 * src2->_32) + (src1->_32 * src2->_33) + (src1->_42 * src2->_34); - temp._42 = (src1->_12 * src2->_41) + (src1->_22 * src2->_42) + (src1->_32 * src2->_43) + (src1->_42 * src2->_44); - - temp._13 = (src1->_13 * src2->_11) + (src1->_23 * src2->_12) + (src1->_33 * src2->_13) + (src1->_43 * src2->_14); - temp._23 = (src1->_13 * src2->_21) + (src1->_23 * src2->_22) + (src1->_33 * src2->_23) + (src1->_43 * src2->_24); - temp._33 = (src1->_13 * src2->_31) + (src1->_23 * src2->_32) + (src1->_33 * src2->_33) + (src1->_43 * src2->_34); - temp._43 = (src1->_13 * src2->_41) + (src1->_23 * src2->_42) + (src1->_33 * src2->_43) + (src1->_43 * src2->_44); - - temp._14 = (src1->_14 * src2->_11) + (src1->_24 * src2->_12) + (src1->_34 * src2->_13) + (src1->_44 * src2->_14); - temp._24 = (src1->_14 * src2->_21) + (src1->_24 * src2->_22) + (src1->_34 * src2->_23) + (src1->_44 * src2->_24); - temp._34 = (src1->_14 * src2->_31) + (src1->_24 * src2->_32) + (src1->_34 * src2->_33) + (src1->_44 * src2->_34); - temp._44 = (src1->_14 * src2->_41) + (src1->_24 * src2->_42) + (src1->_34 * src2->_43) + (src1->_44 * src2->_44); - - /* And copy the new matrix in the good storage.. */ - memcpy(dest, &temp, 16 * sizeof(D3DVALUE)); -} diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c new file mode 100644 index 0000000000..f86321e195 --- /dev/null +++ b/dlls/ddraw/ddraw.c @@ -0,0 +1,3046 @@ +/* + * Copyright 1997-2000 Marcus Meissner + * Copyright 1998-2000 Lionel Ulmer + * Copyright 2000-2001 TransGaming Technologies Inc. + * Copyright 2006 Stefan Dösinger + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include "wine/port.h" + +#include +#include +#include +#include + +#define COBJMACROS +#define NONAMELESSUNION + +#include "windef.h" +#include "winbase.h" +#include "winnls.h" +#include "winerror.h" +#include "wingdi.h" +#include "wine/exception.h" +#include "excpt.h" + +#include "ddraw.h" +#include "d3d.h" + +#include "ddraw_private.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(ddraw); + +static BOOL IDirectDrawImpl_DDSD_Match(const DDSURFACEDESC2* requested, const DDSURFACEDESC2* provided); +static HRESULT WINAPI IDirectDrawImpl_AttachD3DDevice(IDirectDrawImpl *This, IDirectDrawSurfaceImpl *primary); +static HRESULT WINAPI IDirectDrawImpl_CreateNewSurface(IDirectDrawImpl *This, DDSURFACEDESC2 *pDDSD, IDirectDrawSurfaceImpl **ppSurf, UINT level); + +/* Device identifier. Don't relay it to WineD3D */ +static const DDDEVICEIDENTIFIER2 deviceidentifier = +{ + "display", + "DirectDraw HAL", + { { 0x00010001, 0x00010001 } }, + 0, 0, 0, 0, + /* a8373c10-7ac4-4deb-849a-009844d08b2d */ + {0xa8373c10,0x7ac4,0x4deb, {0x84,0x9a,0x00,0x98,0x44,0xd0,0x8b,0x2d}}, + 0 +}; + +/* This is for cleanup if a broken app doesn't Release its objects */ +IDirectDrawImpl *ddraw_list; + +/***************************************************************************** + * IUnkown Methods + *****************************************************************************/ + +/***************************************************************************** + * IDirectDraw7::QueryInterface + * + * Queries different interfaces of the DirectDraw object. It can return + * IDirectDraw interfaces in version 1, 2, 4 and 7, and IDirect3D interfaces + * in version 1, 2, 3 and 7. An IDirect3DDevice can be created with this + * method. + * The returned interface is AddRef() before it's returned + * + * Rules for QueryInterface: + * http://msdn.microsoft.com/library/default.asp? \ + * url=/library/en-us/com/html/6db17ed8-06e4-4bae-bc26-113176cc7e0e.asp + * + * Used for version 1, 2, 4 and 7 + * + * Params: + * refiid: Interface ID asked for + * obj: Used to return the interface pointer + * + * Returns: + * S_OK if an interface was found + * E_NOINTERFACE if the requested interface wasn't found + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawImpl_QueryInterface(IDirectDraw7 *iface, + REFIID refiid, + void **obj) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, 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(!refiid) + return DDERR_INVALIDPARAMS; + + /* Check DirectDraw Interfaces */ + if ( IsEqualGUID( &IID_IUnknown, refiid ) || + IsEqualGUID( &IID_IDirectDraw7, refiid ) ) + { + *obj = ICOM_INTERFACE(This, IDirectDraw7); + TRACE("(%p) Returning IDirectDraw7 interface at %p\n", This, *obj); + } + else if ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) + { + *obj = ICOM_INTERFACE(This, IDirectDraw4); + TRACE("(%p) Returning IDirectDraw4 interface at %p\n", This, *obj); + } + else if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) ) + { + *obj = ICOM_INTERFACE(This, IDirectDraw2); + TRACE("(%p) Returning IDirectDraw2 interface at %p\n", This, *obj); + } + else if ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) + { + *obj = ICOM_INTERFACE(This, IDirectDraw); + TRACE("(%p) Returning IDirectDraw interface at %p\n", This, *obj); + } + + /* Direct3D */ + else if ( IsEqualGUID( &IID_IDirect3D , refiid ) || + IsEqualGUID( &IID_IDirect3D2 , refiid ) || + IsEqualGUID( &IID_IDirect3D3 , refiid ) || + IsEqualGUID( &IID_IDirect3D7 , refiid ) ) + { + /* Check the surface implementation */ + if(This->ImplType == SURFACE_UNKNOWN) + { + /* Apps may create the IDirect3D Interface before the primary surface. + * set the surface implementation */ + This->ImplType = SURFACE_OPENGL; + TRACE("(%p) Choosing OpenGL surfaces because a Direct3D interface was requested\n", This); + } + else if(This->ImplType != SURFACE_OPENGL && DefaultSurfaceType == SURFACE_UNKNOWN) + { + ERR("(%p) The App is requesting a D3D device, but a non-OpenGL surface type was choosen. Prepare for trouble!\n", This); + ERR(" (%p) You may want to contact wine-devel for help\n", This); + /* Should I assert(0) here??? */ + } + else if(This->ImplType != SURFACE_OPENGL) + { + WARN("The app requests a Direct3D interface, but non-opengl surfaces where set in winecfg\n"); + /* Do not abort here, only reject 3D Device creation */ + } + + 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 if(IsEqualGUID( &IID_IDirect3D7 , refiid )) + { + *obj = ICOM_INTERFACE(This, IDirect3D7); + TRACE(" returning Direct3D7 interface at %p.\n", *obj); + } + } + + /* Unknown interface */ + else + { + ERR("(%p)->(%s, %p): No interface found", This, debugstr_guid(refiid), obj); + return E_NOINTERFACE; + } + + IUnknown_AddRef( (IUnknown *) *obj ); + return S_OK; +} + +/***************************************************************************** + * IDirectDraw7::AddRef + * + * Increses the interfaces refcount. Used for version 1, 2, 4 and 7 + * + * Returns: The new refcount + *****************************************************************************/ +static ULONG WINAPI +IDirectDrawImpl_AddRef(IDirectDraw7 *iface) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface); + ULONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) : incrementing from %lu.\n", This, ref -1); + + return ref; +} + +/***************************************************************************** + * IDirectDrawImpl_Destroy + * + * Destroys a ddraw object. This is to share code between normal Release + * and the dll unload cleanup code + * + * Params: + * This: DirectDraw object to destroy + * + *****************************************************************************/ +void +IDirectDrawImpl_Destroy(IDirectDrawImpl *This) +{ + IDirectDrawImpl *prev; + + TRACE("(%p)\n", This); + + /* Destroy the device window if we created one */ + if(This->devicewindow != 0) + { + TRACE(" (%p) Destroying the device window %p\n", This, This->devicewindow); + DestroyWindow(This->devicewindow); + This->devicewindow = 0; + } + + /* Unregister the window class */ + UnregisterClassA(This->classname, 0); + + /* Unchain it from the ddraw list */ + if(ddraw_list == This) + { + ddraw_list = This->next; + /* No need to search for a predecessor here */ + } + else + { + for(prev = ddraw_list; prev; prev = prev->next) + if(prev->next == This) break; + + if(prev) + prev->next = This->next; + else + ERR("Didn't find the previous ddraw element in the list\n"); + } + + /* Release the attached WineD3D stuff */ + IWineD3DDevice_Release(This->wineD3DDevice); + IWineD3D_Release(This->wineD3D); + + /* Now free the object */ + HeapFree(GetProcessHeap(), 0, This); +} +/***************************************************************************** + * IDirectDraw7::Release + * + * Decreses the refcount. If the refcount falls to 0, the object is destroyed + * + * Returns: The new refcount + *****************************************************************************/ +static ULONG WINAPI +IDirectDrawImpl_Release(IDirectDraw7 *iface) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface); + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p)->() decrementing from %lu.\n", This, ref +1); + + if (ref == 0) + { + /* No need to restore the display mode - it's done by SetCooperativeLevel */ + + IDirectDraw7_SetCooperativeLevel(ICOM_INTERFACE(This, IDirectDraw7), + NULL, + DDSCL_NORMAL); + + /* This is for the dll cleanup code in DllMain() */ + if(!This->DoNotDestroy) + IDirectDrawImpl_Destroy(This); + } + + return ref; +} + +/***************************************************************************** + * IDirectDraw methods + *****************************************************************************/ + +/***************************************************************************** + * IDirectDrawImpl_SetupExclusiveWindow + * + * Helper function that modifies a HWND's Style and ExStyle for proper + * fullscreen use. + * + * Params: + * This: Pointer to the DirectDraw implementation + * HWND: Window to setup + * + *****************************************************************************/ +static void +IDirectDrawImpl_SetupFullscreenWindow(IDirectDrawImpl *This, + HWND window) +{ + LONG style, exStyle; + /* Don't do anything if an original style is stored. + * That shouldn't happen + */ + TRACE("(%p): Setting up window %p for exclusive mode\n", This, window); + if( (This->style != 0) && (This->exStyle != 0) ) + { + ERR("(%p) Want to change the window parameters of HWND %p, but \ + another style is stored for restauration afterwards\n", This, window); + } + + /* Get the parameters and save them */ + style = GetWindowLongW(window, GWL_STYLE); + exStyle = GetWindowLongW(window, GWL_EXSTYLE); + This->style = style; + This->exStyle = exStyle; + + /* Filter out window decorations */ + style &= ~WS_CAPTION; + style &= ~WS_THICKFRAME; + exStyle &= ~WS_EX_WINDOWEDGE; + exStyle &= ~WS_EX_CLIENTEDGE; + + /* Make sure the window is managed, otherwise we won't get keyboard input */ + style |= WS_POPUP | WS_SYSMENU; + + TRACE("Old style was %08lx,%08lx, setting to %08lx,%08lx\n", + This->style, This->exStyle, style, exStyle); + + SetWindowLongW(window, GWL_STYLE, style); + SetWindowLongW(window, GWL_EXSTYLE, exStyle); + + /* Inform the window about the update. + * TODO: Should I move it to 0/0 too? + */ + SetWindowPos(window, 0 /* InsertAfter, ignored */, + 0, 0, 0, 0, /* Pos, Size, igored */ + SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER); +} + +/***************************************************************************** + * IDirectDrawImpl_RestoreWindow + * + * Helper function that restores a windows' properties when taking it out + * of fullscreen mode + * + * Params: + * This: Pointer to the DirectDraw implementation + * HWND: Window to setup + * + *****************************************************************************/ +static void +IDirectDrawImpl_RestoreWindow(IDirectDrawImpl *This, + HWND window) +{ + if( (This->style == 0) && (This->exStyle == 0) ) + { + /* This could be a DDSCL_NORMAL -> DDSCL_NORMAL + * switch, do nothing + */ + return; + } + TRACE("(%p): Restoring window settings of window %p to %08lx, %08lx\n", + This, window, This->style, This->exStyle); + + SetWindowLongW(window, GWL_STYLE, This->style); + SetWindowLongW(window, GWL_EXSTYLE, This->exStyle); + + /* Delete the old values */ + This->style = 0; + This->exStyle = 0; + + /* Inform the window about the update */ + SetWindowPos(window, 0 /* InsertAfter, ignored */, + 0, 0, 0, 0, /* Pos, Size, igored */ + SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER); +} + +/***************************************************************************** + * IDirectDraw7::SetCooperativeLevel + * + * Sets the cooerative level for the DirectDraw object, and the window + * assigned to it. The cooperative level determines the general behavior + * of the DirectDraw application + * + * Warning: This is quite tricky, as it's not really documented which + * cooperative levels can be combined with each other. If a game fails + * after this function, try to check the cooperative levels passed on + * Windows, and if it returns something different. + * + * If you think that this function caused the failure because it writes a + * fixme, be sure to run again with a +ddraw trace. + * + * What is known about cooperative levels(See the ddraw modes test): + * DDSCL_EXCLUSIVE and DDSCL_FULLSCREEN must be used with each other + * DDSCL_NORMAL is not compatible with DDSCL_EXCLUSIVE or DDSCL_FULLSCREEN + * DDSCL_SETFOCUSWINDOW can be passed only in DDSCL_NORMAL mode, but after that + * DDSCL_FULLSCREEN can be activated + * DDSCL_SETFOCUSWINDOW may only be used with DDSCL_NOWINDOWCHANGES + * + * Handled flags: DDSCL_NORMAL, DDSCL_FULLSCREEN, DDSCL_EXCLUSIVE, + * DDSCL_SETFOCUSWINDOW(partially) + * + * Unhandled flags, which should be implemented + * DDSCL_SETDEVICEWINDOW: Sets a window specially used for rendering(I don't + * expect any difference to a normal window for wine) + * DDSCL_CREATEDEVICEWINDOW: Tells ddraw to create it's own window for + * rendering(Possible test case: Half-life) + * + * Unsure about these: DDSCL_FPUSETUP DDSCL_FPURESERVE + * + * These seem not really imporant for wine + * DDSCL_ALLOWREBOOT, DDSCL_NOWINDOWCHANGES, DDSCL_ALLOWMODEX, + * DDSCL_MULTITHREDED + * + * Returns: + * DD_OK if the cooperative level was set successfully + * DDERR_INVALIDPARAMS if the passed cooperative level combination is invalid + * DDERR_HWNDALLREADYSET if DDSCL_SETFOCUSWINDOW is passed in exclusive mode + * (Propably others too, have to investigate) + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawImpl_SetCooperativeLevel(IDirectDraw7 *iface, + HWND hwnd, + DWORD cooplevel) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface); + HWND window; + HRESULT hr; + + FIXME("(%p)->(%p,%08lx)\n",This,hwnd,cooplevel); + DDRAW_dump_cooperativelevel(cooplevel); + + /* Get the old window */ + hr = IWineD3DDevice_GetHWND(This->wineD3DDevice, &window); + if(hr != D3D_OK) + { + ERR("IWineD3DDevice::GetHWND failed, hr = %08lx\n", hr); + return hr; + } + + /* Tests suggest that we need one of them: */ + if(!(cooplevel & (DDSCL_SETFOCUSWINDOW | + DDSCL_NORMAL | + DDSCL_EXCLUSIVE ))) + { + TRACE("Incorrect cooplevel flags, returning DDERR_INVALIDPARAMS\n"); + return DDERR_INVALIDPARAMS; + } + + /* Handle those levels first which set varios hwnds */ + if(cooplevel & DDSCL_SETFOCUSWINDOW) + { + /* This isn't compatible with a lot of flags */ + if(cooplevel & ( DDSCL_MULTITHREADED | + DDSCL_FPUSETUP | + DDSCL_FPUPRESERVE | + DDSCL_ALLOWREBOOT | + DDSCL_ALLOWMODEX | + DDSCL_SETDEVICEWINDOW | + DDSCL_NORMAL | + DDSCL_EXCLUSIVE | + DDSCL_FULLSCREEN ) ) + { + TRACE("Called with incompatible flags, returning DDERR_INVALIDPARAMS\n"); + return DDERR_INVALIDPARAMS; + } + else if( (This->cooperative_level & DDSCL_FULLSCREEN) && window) + { + TRACE("Setting DDSCL_SETFOCUSWINDOW with an already set window, returning DDERR_HWNDALREADYSET\n"); + return DDERR_HWNDALREADYSET; + } + + This->focuswindow = hwnd; + /* Won't use the hwnd param for anything else */ + hwnd = NULL; + + /* Use the focus window for drawing too */ + IWineD3DDevice_SetHWND(This->wineD3DDevice, This->focuswindow); + + /* Destroy the device window, if we have one */ + if(This->devicewindow) + { + DestroyWindow(This->devicewindow); + This->devicewindow = NULL; + } + } + /* DDSCL_NORMAL or DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE */ + if(cooplevel & DDSCL_NORMAL) + { + /* Can't coexist with fullscreen or exclusive */ + if(cooplevel & (DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE) ) + { + TRACE("(%p) DDSCL_NORMAL is not compative with DDSCL_FULLSCREEN or DDSCL_EXCLUSIVE\n", This); + return DDERR_INVALIDPARAMS; + } + + /* Switching from fullscreen? */ + if(This->cooperative_level & DDSCL_FULLSCREEN) + { + /* Restore the display mode */ + IDirectDraw7_RestoreDisplayMode(iface); + + if(window) + IDirectDrawImpl_RestoreWindow(This, window); + + This->cooperative_level &= ~DDSCL_FULLSCREEN; + This->cooperative_level &= ~DDSCL_EXCLUSIVE; + This->cooperative_level &= ~DDSCL_ALLOWMODEX; + } + + /* Don't override focus windows or private device windows */ + if( hwnd && + !(This->focuswindow) && + !(This->devicewindow) && + (hwnd != window) ) + { + IWineD3DDevice_SetHWND(This->wineD3DDevice, hwnd); + } + } + else if(cooplevel & DDSCL_FULLSCREEN) + { + /* Needs DDSCL_EXCLUSIVE */ + if(!(cooplevel & DDSCL_EXCLUSIVE) ) + { + TRACE("(%p) DDSCL_FULLSCREEN needs DDSCL_EXCLUSIVE\n", This); + return DDERR_INVALIDPARAMS; + } + /* Need a HWND + if(hwnd == 0) + { + TRACE("(%p) DDSCL_FULLSCREEN needs a HWND\n", This); + return DDERR_INVALIDPARAMS; + } + */ + + /* Switch from normal to full screen mode? */ + if(This->cooperative_level & DDSCL_NORMAL) + { + This->cooperative_level &= ~DDSCL_NORMAL; + } + + /* Don't override focus windows or private device windows */ + if( hwnd && + !(This->focuswindow) && + !(This->devicewindow) && + (hwnd != window) ) + { + /* On a window change, restore the old window and set the new one */ + if(window != hwnd) + { + if(window) + IDirectDrawImpl_RestoreWindow(This, window); + IDirectDrawImpl_SetupFullscreenWindow(This, hwnd); + } + IWineD3DDevice_SetHWND(This->wineD3DDevice, hwnd); + } + } + else if(cooplevel & DDSCL_EXCLUSIVE) + { + TRACE("(%p) DDSCL_EXCLUSIVE needs DDSCL_FULLSCREEN\n", This); + return DDERR_INVALIDPARAMS; + } + + if(cooplevel & DDSCL_CREATEDEVICEWINDOW) + { + /* Don't create a device window if a focus window is set */ + if( !(This->focuswindow) ) + { + HWND devicewindow = CreateWindowExA(0, This->classname, "DDraw device window", + WS_POPUP, 0, 0, + GetSystemMetrics(SM_CXSCREEN), + GetSystemMetrics(SM_CYSCREEN), + NULL, NULL, GetModuleHandleA(0), NULL); + + ShowWindow(devicewindow, SW_SHOW); /* Just to be sure */ + TRACE("(%p) Created a DDraw device window. HWND=%p\n", This, devicewindow); + + IWineD3DDevice_SetHWND(This->wineD3DDevice, devicewindow); + This->devicewindow = devicewindow; + } + } + + /* Unhandled flags */ + if(cooplevel & DDSCL_ALLOWREBOOT) + WARN("(%p) Unhandled flag DDSCL_ALLOWREBOOT, harmless\n", This); + if(cooplevel & DDSCL_ALLOWMODEX) + WARN("(%p) Unhandled flag DDSCL_ALLOWMODEX, harmless\n", This); + if(cooplevel & DDSCL_MULTITHREADED) + FIXME("(%p) Unhandled flag DDSCL_MULTITHREADED, Uh Oh...\n", This); + if(cooplevel & DDSCL_FPUSETUP) + WARN("(%p) Unhandled flag DDSCL_FPUSETUP, harmless\n", This); + if(cooplevel & DDSCL_FPUPRESERVE) + WARN("(%p) Unhandled flag DDSCL_FPUPRESERVE, harmless\n", This); + + /* Store the cooperative_level */ + This->cooperative_level |= cooplevel; + TRACE("SetCooperativeLevel retuning DD_OK\n"); + return DD_OK; +} + +/***************************************************************************** + * IDirectDraw7::SetDisplayMode + * + * Sets the display screen resolution, color depth and refresh frequency + * when in fullscreen mode(in theory). + * Possible return values listed in the SDK suggest that this method fails + * when not in fullscreen mode, but this is wrong. Windows 2000 happily sets + * the display mode in DDSCL_NORMAL mode without an hwnd specified. + * It seems to be valid to pass 0 for With and Height, this has to be tested + * It could mean that the current video mode should be left as-is. (But why + * call it then?) + * + * Params: + * Height, Width: Screen dimension + * BPP: Color depth in Bits per pixel + * Refreshrate: Screen refresh rate + * Flags: Other stuff + * + * Returns + * DD_OK on success + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawImpl_SetDisplayMode(IDirectDraw7 *iface, + DWORD Width, + DWORD Height, + DWORD BPP, + DWORD RefreshRate, + DWORD Flags) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface); + WINED3DDISPLAYMODE Mode; + TRACE("(%p)->(%ld,%ld,%ld,%ld,%lx: Relay!\n", This, Width, Height, BPP, RefreshRate, Flags); + + if( !Width || !Height ) + { + ERR("Width=%ld, Height=%ld, what to do?\n", Width, Height); + /* It looks like Need for speed Posche Unleashed expects DD_OK here */ + return DD_OK; + } + + /* Check the exclusive mode + if(!(This->cooperative_level & DDSCL_EXCLUSIVE)) + return DDERR_NOEXCLUSIVEMODE; + * This is WRONG. Don't know if the SDK is completely + * wrong and if there are any coditions when DDERR_NOEXCLUSIVE + * is returned, but Half-Life 1.1.1.1(Steam version) + * depends on this + */ + + Mode.Width = Width; + Mode.Height = Height; + Mode.RefreshRate = RefreshRate; + switch(BPP) + { + case 8: Mode.Format = WINED3DFMT_P8; break; + case 15: Mode.Format = WINED3DFMT_X1R5G5B5; break; + case 16: Mode.Format = WINED3DFMT_R5G6B5; break; + case 24: Mode.Format = WINED3DFMT_R8G8B8; break; + case 32: Mode.Format = WINED3DFMT_A8R8G8B8; break; + } + + /* TODO: The possible return values from msdn suggest that + * the screen mode can't be changed if a surface is locked + * or some drawing is in progress + */ + + /* TODO: Lose the primary surface */ + return IWineD3DDevice_SetDisplayMode(This->wineD3DDevice, + 0, /* First swapchain */ + &Mode); + +} + +/***************************************************************************** + * IDirectDraw7::RestoreDisplayMode + * + * Restores the display mode to what it was at creation time. Basically. + * + * A problem arises when there are 2 DirectDraw objects using the same hwnd: + * -> DD_1 finds the screen at 1400x1050x32 when created, sets it to 640x480x16 + * -> DD_2 is created, finds the screen at 640x480x16, sets it to 1024x768x32 + * -> DD_1 is released. The screen should be left at 1024x768x32. + * -> DD_2 is released. The screen should be set to 1400x1050x32 + * This case is unhandled right now, but Empire Earth does it this way. + * (But perhaps there is something in SetCooperativeLevel to prevent this) + * + * The msdn says that this method resets the display mode to what it was before + * SetDisplayMode was called. What if SetDisplayModes is called 2 times?? + * + * Returns + * DD_OK on success + * DDERR_NOEXCLUSIVE mode if the device isn't in fullscreen mode + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawImpl_RestoreDisplayMode(IDirectDraw7 *iface) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface); + TRACE("(%p)\n", This); + + return IDirectDraw7_SetDisplayMode(ICOM_INTERFACE(This, IDirectDraw7), + This->orig_width, + This->orig_height, + This->orig_bpp, + 0, + 0); +} + +/***************************************************************************** + * IDirectDraw7::GetCaps + * + * Returns the drives capatiblities + * + * Used for version 1, 2, 4 and 7 + * + * Params: + * DriverCaps: Structure to write the Hardware accellerated caps to + * HelCaps: Structure to write the emulation caps to + * + * Returns + * This implementation returnd DD_OK only + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawImpl_GetCaps(IDirectDraw7 *iface, + DDCAPS *DriverCaps, + DDCAPS *HELCaps) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface); + TRACE("(%p)->(%p,%p)\n", This, DriverCaps, HELCaps); + + /* One structure must be != NULL */ + if( (!DriverCaps) && (!HELCaps) ) + { + ERR("(%p) Invalid params to IDirectDrawImpl_GetCaps\n", This); + return DDERR_INVALIDPARAMS; + } + + if(DriverCaps) + { + DD_STRUCT_COPY_BYSIZE(DriverCaps, &This->caps); + if (TRACE_ON(ddraw)) + { + TRACE("Driver Caps :\n"); + DDRAW_dump_DDCAPS(DriverCaps); + } + + } + if(HELCaps) + { + DD_STRUCT_COPY_BYSIZE(HELCaps, &This->caps); + if (TRACE_ON(ddraw)) + { + TRACE("HEL Caps :\n"); + DDRAW_dump_DDCAPS(HELCaps); + } + } + + return DD_OK; +} + +/***************************************************************************** + * IDirectDraw7::Compact + * + * No idea what it does, MSDN says it's not implemented. + * + * Returns + * DD_OK, but this is unchecked + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawImpl_Compact(IDirectDraw7 *iface) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface); + TRACE("(%p)\n", This); + + return DD_OK; +} + +/***************************************************************************** + * IDirectDraw7::GetDisplayMode + * + * Returns information about the current display mode + * + * Exists in Version 1, 2, 4 and 7 + * + * Params: + * DDSD: Address of a surface description structure to write the info to + * + * Returns + * DD_OK + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawImpl_GetDisplayMode(IDirectDraw7 *iface, + DDSURFACEDESC2 *DDSD) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface); + HRESULT hr; + WINED3DDISPLAYMODE Mode; + DWORD Size; + TRACE("(%p)->(%p): Relay\n", This, DDSD); + + /* This seems sane */ + if(!DDSD) + { + return DDERR_INVALIDPARAMS; + } + + /* The necessary members of LPDDSURFACEDESC and LPDDSURFACEDESC2 are equal, + * so one method can be used for all versions (Hopefully) + */ + hr = IWineD3DDevice_GetDisplayMode(This->wineD3DDevice, + 0 /* swapchain 0 */, + &Mode); + if( hr != D3D_OK ) + { + ERR(" (%p) IWineD3DDevice::GetDisplayMode returned %08lx\n", This, hr); + return hr; + } + + Size = DDSD->dwSize; + memset(DDSD, 0, Size); + + DDSD->dwSize = Size; + DDSD->dwFlags |= DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_PITCH | DDSD_REFRESHRATE; + DDSD->dwWidth = Mode.Width; + DDSD->dwHeight = Mode.Height; + DDSD->u2.dwRefreshRate = 60; + DDSD->ddsCaps.dwCaps = 0; + DDSD->u4.ddpfPixelFormat.dwSize = sizeof(DDSD->u4.ddpfPixelFormat); + PixelFormat_WineD3DtoDD(&DDSD->u4.ddpfPixelFormat, Mode.Format); + DDSD->u1.lPitch = Mode.Width * DDSD->u4.ddpfPixelFormat.u1.dwRGBBitCount / 8; + + if(TRACE_ON(ddraw)) + { + TRACE("Returning surface desc :\n"); + DDRAW_dump_surface_desc(DDSD); + } + + return DD_OK; +} + +/***************************************************************************** + * IDirectDraw7::GetFourCCCodes + * + * Returns an array of supported FourCC codes. + * + * Exists in Version 1, 2, 4 and 7 + * + * Params: + * NumCodes: Contains the number of Codes that Codes can carry. Returns the number + * of enumerated codes + * Codes: Pointer to an array of DWORDs where the supported codes are wriiten + * to + * + * Returns + * Always returns DD_OK, as it's a stub for now + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawImpl_GetFourCCCodes(IDirectDraw7 *iface, + DWORD *NumCodes, DWORD *Codes) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface); + FIXME("(%p)->(%p, %p): Stub!\n", This, NumCodes, Codes); + + if(NumCodes) *NumCodes = 0; + + return DD_OK; +} + +/***************************************************************************** + * IDirectDraw7::GetMonitorFrequency + * + * Returns the monitor's frequency + * + * Exists in Version 1, 2, 4 and 7 + * + * Params: + * Freq: Pointer to a DWORD to write the frequency to + * + * Returns + * Always returns DD_OK + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawImpl_GetMonitorFrequency(IDirectDraw7 *iface, + DWORD *Freq) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface); + TRACE("(%p)->(%p)\n", This, Freq); + + /* Ideally this should be in WineD3D, as it concernes the screen setup, + * but for now this should make the games happy + */ + *Freq = 60; + return DD_OK; +} + +/***************************************************************************** + * IDirectDraw7::GetVerticalBlankStatus + * + * Returns the Vertical blank status of the monitor. This should be in WineD3D + * too basically, but as it's a semi stub, I didn't create a function there + * + * Params: + * status: Pointer to a BOOL to be filled with the vertical blank status + * + * Returns + * DD_OK on success + * DDERR_INVALIDPARAMS if status is NULL + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawImpl_GetVerticalBlankStatus(IDirectDraw7 *iface, + BOOL *status) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface); + TRACE("(%p)->(%p)\n", This, status); + + /* This looks sane, the MSDN suggests it too */ + if(!status) return DDERR_INVALIDPARAMS; + + *status = This->fake_vblank; + This->fake_vblank = !This->fake_vblank; + return DD_OK; +} + +/***************************************************************************** + * IDirectDraw7::GetAvailableVidMem + * + * Returns the total and free video memory + * + * Params: + * Caps: Specifies the memory type asked for + * total: Pointer to a DWORD to be filled with the total memory + * free: Pointer to a DWORD to be filled with the free memory + * + * Returns + * DD_OK on success + * DDERR_INVALIDPARAMS of free and total are NULL + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawImpl_GetAvailableVidMem(IDirectDraw7 *iface, DDSCAPS2 *Caps, DWORD *total, DWORD *free) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface); + TRACE("(%p)->(%p, %p, %p)\n", This, Caps, total, free); + + if(TRACE_ON(ddraw)) + { + TRACE("(%p) Asked for memory with description: ", This); + DDRAW_dump_DDSCAPS2(Caps); + TRACE("\n"); + } + + /* Todo: System memory vs local video memory vs non-local video memory + * The MSDN also mentiones differences between texture memory and other + * resources, but that's not important + */ + + if( (!total) && (!free) ) return DDERR_INVALIDPARAMS; + + if(total) *total = This->total_vidmem; + if(free) *free = IWineD3DDevice_GetAvailableTextureMem(This->wineD3DDevice); + + return DD_OK; +} + +/***************************************************************************** + * IDirectDraw7::Initialize + * + * Initializes a DirectDraw interface. + * + * Params: + * GUID: Interface identifier. Well, don't know what this is really good + * for + * + * Returns + * Returns DD_OK on the first call, + * DDERR_ALREADYINITIALIZED on repeated calls + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawImpl_Initialize(IDirectDraw7 *iface, + GUID *Guid) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface); + TRACE("(%p)->(%s): No-op\n", This, debugstr_guid(Guid)); + + if(This->initialized) + { + return DDERR_ALREADYINITIALIZED; + } + else + { + return DD_OK; + } +} + +/***************************************************************************** + * IDirectDraw7::FlipToGDISurface + * + * "Makes the surface that the GDI writes to the primary surface" + * Looks like some windows specific thing we don't have to care about. + * According to MSDN it permits GDI dialog boxes in FULLSCREEN mode. Good to + * show error boxes ;) + * Well, just return DD_OK. + * + * Returns: + * Always returns DD_OK + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawImpl_FlipToGDISurface(IDirectDraw7 *iface) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface); + TRACE("(%p)\n", This); + + return DD_OK; +} + +/***************************************************************************** + * IDirectDraw7::WaitForVerticalBlank + * + * This method allows applications to get in sync with the vertical blank + * interval. + * The wormhole demo in the DirectX 7 sdk uses this call, and it doesn't + * redraw the screen, most likely because of this stub + * + * Parameters: + * Flags: one of DDWAITVB_BLOCKBEGIN, DDWAITVB_BLOCKBEGINEVENT + * or DDWAITVB_BLOCKEND + * h: Not used, according to MSDN + * + * Returns: + * Always returns DD_OK + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawImpl_WaitForVerticalBlank(IDirectDraw7 *iface, + DWORD Flags, + HANDLE h) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface); + FIXME("(%p)->(%lx,%p): Stub\n", This, Flags, h); + + /* MSDN says DDWAITVB_BLOCKBEGINEVENT is not supported */ + if(Flags & DDWAITVB_BLOCKBEGINEVENT) + return DDERR_UNSUPPORTED; /* unchecked */ + + return DD_OK; +} + +/***************************************************************************** + * IDirectDraw7::GetScanLine + * + * Returns the scan line that is beeing drawn on the monitor + * + * Parameters: + * Scanline: Address to write the scan line value to + * + * Returns: + * Always returns DD_OK + * + *****************************************************************************/ +static HRESULT WINAPI IDirectDrawImpl_GetScanLine(IDirectDraw7 *iface, DWORD *Scanline) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface); + static BOOL hide = FALSE; + WINED3DDISPLAYMODE Mode; + + /* This function is called often, so print the fixme only once */ + if(!hide) + { + FIXME("(%p)->(%p): Semi-Stub\n", This, Scanline); + hide = TRUE; + } + + IWineD3DDevice_GetDisplayMode(This->wineD3DDevice, + 0, + &Mode); + + /* Fake the line sweeping of the monitor */ + /* FIXME: We should synchronize with a source to keep the refresh rate */ + *Scanline = This->cur_scanline++; + /* Assume 20 scan lines in the vertical blank */ + if (This->cur_scanline >= Mode.Height + 20) + This->cur_scanline = 0; + + return DD_OK; +} + +/***************************************************************************** + * IDirectDraw7::TestCooperativeLevel + * + * Informs the application about the state of the video adapter, depending + * on the cooperative level + * + * Returns: + * DD_OK if the device is in a sane state + * DDERR_NOEXCLUSIVEMODE or DDERR_EXCLUSIVEMODEALREADYSET + * if the state is not correct(See below) + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawImpl_TestCooperativeLevel(IDirectDraw7 *iface) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface); + HRESULT hr; + TRACE("(%p)\n", This); + + /* Description from MSDN: + * For fullscreen apps return DDERR_NOEXCLUSIVEMODE if the user switched + * away from the app with e.g. alt-tab. Windowed apps receive + * DDERR_EXCLUSIVEMODEALREADYSET if another application created an + * DirectDraw object in exclusive mode. DDERR_WRONGMODE is returned, + * when the video mode has changed + */ + + hr = IWineD3DDevice_TestCooperativeLevel(This->wineD3DDevice); + + /* Fix the result value. These values are mapped from their + * d3d9 counterpart. + */ + switch(hr) + { + case WINED3DERR_DEVICELOST: + if(This->cooperative_level & DDSCL_EXCLUSIVE) + { + return DDERR_NOEXCLUSIVEMODE; + } + else + { + return DDERR_EXCLUSIVEMODEALREADYSET; + } + + case WINED3DERR_DEVICENOTRESET: + return DD_OK; + + case WINED3D_OK: + return DD_OK; + + case WINED3DERR_DRIVERINTERNALERROR: + default: + ERR("(%p) Unexpected return value %08lx from wineD3D, " \ + " returning DD_OK\n", This, hr); + } + + return DD_OK; +} + +/***************************************************************************** + * IDirectDraw7::GetGDISurface + * + * Returns the surface that GDI is treating as the primary surface. + * For Wine this is the front buffer + * + * Params: + * GDISurface: Address to write the surface pointer to + * + * Returns: + * DD_OK if the surface was found + * DDERR_NOTFOUND if the GDI surface wasn't found + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawImpl_GetGDISurface(IDirectDraw7 *iface, + IDirectDrawSurface7 **GDISurface) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface); + IWineD3DSurface *Surf; + IDirectDrawSurface7 *ddsurf; + HRESULT hr; + DDSCAPS2 ddsCaps; + TRACE("(%p)->(%p)\n", This, GDISurface); + + /* Get the back buffer from the wineD3DDevice and search it's + * attached surfaces for the front buffer + */ + hr = IWineD3DDevice_GetBackBuffer(This->wineD3DDevice, + 0, /* SwapChain */ + 0, /* first back buffer*/ + WINED3DBACKBUFFER_TYPE_MONO, + &Surf); + + if( (hr != D3D_OK) || + (!Surf) ) + { + ERR("IWineD3DDevice::GetBackBuffer failed\n"); + return DDERR_NOTFOUND; + } + + /* GetBackBuffer AddRef()ed the surface, release it */ + IWineD3DSurface_Release(Surf); + + IWineD3DSurface_GetParent(Surf, + (IUnknown **) &ddsurf); + IDirectDrawSurface7_Release(ddsurf); /* For the GetParent */ + + /* Find the front buffer */ + ddsCaps.dwCaps = DDSCAPS_FRONTBUFFER; + hr = IDirectDrawSurface7_GetAttachedSurface(ddsurf, + &ddsCaps, + GDISurface); + if(hr != DD_OK) + { + ERR("IDirectDrawSurface7::GetAttachedSurface failed, hr = %lx\n", hr); + } + + /* The AddRef is OK this time */ + return hr; +} + +/***************************************************************************** + * IDirectDrawImpl_EnumDisplayModesCB + * + * Callback function for IDirectDraw7::EnumDisplayModes. Translates + * the wineD3D values to ddraw values and calls the application callback + * + * Params: + * device: The IDirectDraw7 interface to the current device + * With, Height, Pixelformat, Refresh: Enumerated display mode + * context: the context pointer passed to IWineD3DDevice::EnumDisplayModes + * + * Returns: + * The return value from the application callback + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawImpl_EnumDisplayModesCB(IUnknown *pDevice, + UINT Width, + UINT Height, + WINED3DFORMAT Pixelformat, + FLOAT Refresh, + void *context) +{ + DDSURFACEDESC2 callback_sd; + EnumDisplayModesCBS *cbs = (EnumDisplayModesCBS *) context; + + memset(&callback_sd, 0, sizeof(callback_sd)); + callback_sd.dwSize = sizeof(callback_sd); + callback_sd.u4.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT); + + callback_sd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_PITCH; + if(Refresh > 0.0) + { + callback_sd.dwFlags |= DDSD_REFRESHRATE; + callback_sd.u2.dwRefreshRate = 60.0; + } + + callback_sd.dwHeight = Height; + callback_sd.dwWidth = Width; + + PixelFormat_WineD3DtoDD(&callback_sd.u4.ddpfPixelFormat, Pixelformat); + return cbs->callback(&callback_sd, cbs->context); +} + +/***************************************************************************** + * IDirectDraw7::EnumDisplayModes + * + * Enumerates the supported Display modes. The modes can be filtered with + * the DDSD paramter. + * + * Params: + * Flags: can be DDEDM_REFRESHRATES and DDEDM_STANDARDVGAMODES + * DDSD: Surface description to filter the modes + * Context: Pointer passed back to the callback function + * cb: Application-provided callback function + * + * Returns: + * DD_OK on success + * DDERR_INVALIDPARAMS if the callback wasn't set + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawImpl_EnumDisplayModes(IDirectDraw7 *iface, + DWORD Flags, + DDSURFACEDESC2 *DDSD, + void *Context, + LPDDENUMMODESCALLBACK2 cb) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface); + UINT Width = 0, Height = 0; + WINED3DFORMAT pixelformat = WINED3DFMT_UNKNOWN; + EnumDisplayModesCBS cbs; + + TRACE("(%p)->(%p,%p,%p): Relay\n", This, DDSD, Context, cb); + + /* This looks sane */ + if(!cb) return DDERR_INVALIDPARAMS; + + /* The private callback structure */ + cbs.callback = cb; + cbs.context = Context; + + if(DDSD) + { + if (DDSD->dwFlags & DDSD_WIDTH) + Width = DDSD->dwWidth; + if (DDSD->dwFlags & DDSD_HEIGHT) + Width = DDSD->dwHeight; + if ((DDSD->dwFlags & DDSD_PIXELFORMAT) && (DDSD->u4.ddpfPixelFormat.dwFlags & DDPF_RGB) ) + pixelformat = PixelFormat_DD2WineD3D(&DDSD->u4.ddpfPixelFormat); + } + + return IWineD3DDevice_EnumDisplayModes(This->wineD3DDevice, + Flags, + Width, Height, pixelformat, + &cbs, + IDirectDrawImpl_EnumDisplayModesCB); +} + +/***************************************************************************** + * IDirectDraw7::EvaluateMode + * + * Used with IDirectDraw7::StartModeTest to test video modes. + * EvaluateMode is used to pass or fail a mode, and continue with the next + * mode + * + * Params: + * Flags: DDEM_MODEPASSED or DDEM_MODEFAILED + * Timeout: Returns the amount of secounds left before the mode would have + * been failed automatically + * + * Returns: + * This implementation always DD_OK, because it's a stub + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawImpl_EvaluateMode(IDirectDraw7 *iface, + DWORD Flags, + DWORD *Timeout) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface); + FIXME("(%p)->(%ld,%p): Stub!\n", This, Flags, Timeout); + + /* When implementing this, implement it in WineD3D */ + + return DD_OK; +} + +/***************************************************************************** + * IDirectDraw7::GetDeviceIdentifier + * + * Returns the device identifier, which gives information about the driver + * Our device identifier is defined at the beginning of this file. + * + * Params: + * DDDI: Address for the returned structure + * Flags: Can be DDGDI_GETHOSTIDENTIFIER + * + * Returns: + * On success it returns DD_OK + * DDERR_INVALIDPARAMS if DDDI is NULL; + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawImpl_GetDeviceIdentifier(IDirectDraw7 *iface, + DDDEVICEIDENTIFIER2 *DDDI, + DWORD Flags) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface); + TRACE("(%p)->(%p,%08lx) \n", This, DDDI, Flags); + + if(!DDDI) + return DDERR_INVALIDPARAMS; + + /* The DDGDI_GETHOSTIDENTIFIER returns the information about the 2D + * host adapter, if there's a secondary 3D adapter. This doesn't apply + * to any modern hardware, nor is it interesting for Wine, so ignore it + */ + + *DDDI = deviceidentifier; + return DD_OK; +} + +/***************************************************************************** + * IDirectDraw7::GetSurfaceFromDC + * + * Returns the Surface for a GDI device context handle. + * Is this related to IDirectDrawSurface::GetDC ??? + * + * Params: + * hdc: hdc to return the surface for + * Surface: Address to write the surface pointer to + * + * Returns: + * Always returns DD_OK because it's a stub + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawImpl_GetSurfaceFromDC(IDirectDraw7 *iface, + HDC hdc, + IDirectDrawSurface7 **Surface) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface); + FIXME("(%p)->(%p,%p): Stub!\n", This, hdc, Surface); + + /* Implementation idea if needed: Loop through all surfaces and compare + * their hdc with hdc. Implement it in WineD3D! */ + return DDERR_NOTFOUND; +} + +/***************************************************************************** + * IDirectDraw7::RestoreAllSurfaces + * + * Calls the restore method of all surfaces + * + * Params: + * + * Returns: + * Always returns DD_OK because it's a stub + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawImpl_RestoreAllSurfaces(IDirectDraw7 *iface) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface); + FIXME("(%p): Stub\n", This); + + /* This isn't hard to implement: Enumerate all WineD3D surfaces, + * get their parent and call their restore method. Do not implement + * it in WineD3D, as restoring a surface means re-creating the + * WineD3DDSurface + */ + return DD_OK; +} + +/***************************************************************************** + * IDirectDraw7::StartModeTest + * + * Tests the specified video modes to update the system registry with + * refresh rate information. StartModeTest starts the mode test, + * EvaluateMode is used to fail or pass a mode. If EvaluateMode + * isn't called withhin 15 secounds, the mode is failed automatically + * + * As refresh rates are handled by the X server, I don't think this + * Methos is important + * + * Params: + * Modes: An array of mode specifications + * NumModes: The number of modes in Modes + * Flags: Some flags... + * + * Returns: + * Returns DDERR_TESTFINISHED if flags contains DDSMT_ISTESTREQUIRED, + * if no modes are passed, DDERR_INVALIDPARAMS is returned, + * otherwise DD_OK; + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawImpl_StartModeTest(IDirectDraw7 *iface, + SIZE *Modes, + DWORD NumModes, + DWORD Flags) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface); + WARN("(%p)->(%p, %ld, %lx): Semi-Stub, most likely harmless\n", This, Modes, NumModes, Flags); + + /* This looks sane */ + if( (!Modes) || (NumModes == 0) ) return DDERR_INVALIDPARAMS; + + /* DDSMT_ISTESTREQUIRED asks if a mode test is necessary. + * As it is not, DDERR_TESTFINISHED is returned + * (hopefully that's correct + * + if(Flags & DDSMT_ISTESTREQUIRED) return DDERR_TESTFINISHED; + * well, that value doesn't (yet) exist in the wine headers, so ignore it + */ + + return DD_OK; +} + +/***************************************************************************** + * IDirectDrawImpl_RecreateSurfacesCallback + * + * Enumeration callback for IDirectDrawImpl_RecreateAllSurfaces. + * It re-recreates the WineD3DSurface. It's pretty steightforward + * + *****************************************************************************/ +HRESULT WINAPI +IDirectDrawImpl_RecreateSurfacesCallback(IDirectDrawSurface7 *surf, + DDSURFACEDESC2 *desc, + void *Context) +{ + IDirectDrawSurfaceImpl *surfImpl = ICOM_OBJECT(IDirectDrawSurfaceImpl, + IDirectDrawSurface7, + surf); + IDirectDrawImpl *This = surfImpl->ddraw; + IUnknown *Parent; + IParentImpl *parImpl = NULL; + IWineD3DSurface *wineD3DSurface; + HRESULT hr; + void *tmp; + + WINED3DSURFACE_DESC Desc; + WINED3DFORMAT Format; + WINED3DRESOURCETYPE Type; + DWORD Usage; + WINED3DPOOL Pool; + UINT Size; + + WINED3DMULTISAMPLE_TYPE MultiSampleType; + DWORD MultiSampleQuality; + UINT Width; + UINT Height; + + TRACE("(%p): Enumerated Surface %p\n", This, surfImpl); + + /* For the enumeration */ + IDirectDrawSurface7_Release(surf); + + if(surfImpl->ImplType == This->ImplType) return DDENUMRET_OK; /* Continue */ + + /* Get the objects */ + wineD3DSurface = surfImpl->WineD3DSurface; + IWineD3DSurface_GetParent(wineD3DSurface, &Parent); + IUnknown_Release(Parent); /* For the getParent */ + + /* Is the parent an IParent interface? */ + if(IUnknown_QueryInterface(Parent, &IID_IParent, &tmp) == S_OK) + { + /* It is a IParent interface! */ + IUnknown_Release(Parent); /* For the QueryInterface */ + parImpl = ICOM_OBJECT(IParentImpl, IParent, Parent); + /* Release the reference the parent interface is holding */ + IWineD3DSurface_Release(wineD3DSurface); + } + + + /* Get the surface properties */ + Desc.Format = &Format; + Desc.Type = &Type; + Desc.Usage = &Usage; + Desc.Pool = &Pool; + Desc.Size = &Size; + Desc.MultiSampleType = &MultiSampleType; + Desc.MultiSampleQuality = &MultiSampleQuality; + Desc.Width = &Width; + Desc.Height = &Height; + + hr = IWineD3DSurface_GetDesc(wineD3DSurface, &Desc); + if(hr != D3D_OK) return hr; + + /* Create the new surface */ + hr = IWineD3DDevice_CreateSurface(This->wineD3DDevice, + Width, Height, Format, + TRUE /* Lockable */, + FALSE /* Discard */, + surfImpl->mipmap_level, + &surfImpl->WineD3DSurface, + Type, + Usage, + Pool, + MultiSampleType, + MultiSampleQuality, + 0 /* SharedHandle */, + This->ImplType, + Parent); + + if(hr != D3D_OK) + return hr; + + /* Update the IParent if it exists */ + if(parImpl) + { + parImpl->child = (IUnknown *) surfImpl->WineD3DSurface; + /* Add a reference for the IParent */ + IWineD3DSurface_AddRef(surfImpl->WineD3DSurface); + } + /* TODO: Copy the surface content, except for render targets */ + + if(IWineD3DSurface_Release(wineD3DSurface) == 0) + TRACE("Surface released successfull, next surface\n"); + else + ERR("Something's still holding the old WineD3DSurface\n"); + + surfImpl->ImplType = This->ImplType; + + return DDENUMRET_OK; +} + +/***************************************************************************** + * IDirectDrawImpl_RecreateAllSurfaces + * + * A function, that converts all wineD3DSurfaces to the new implementation type + * It enumerates all surfaces with IWineD3DDevice::EnumSurfaces, creates a + * new WineD3DSurface, copys the content and releases the old surface + * + *****************************************************************************/ +static HRESULT +IDirectDrawImpl_RecreateAllSurfaces(IDirectDrawImpl *This) +{ + DDSURFACEDESC2 desc; + TRACE("(%p): Switch to implementation %d\n", This, This->ImplType); + + if(This->ImplType != SURFACE_OPENGL && This->d3d_initialized) + { + /* Should happen almost never */ + FIXME("(%p) Switching to non-opengl surfaces with d3d started. Is this a bug?\n", This); + /* Shutdown d3d */ + IWineD3DDevice_Uninit3D(This->wineD3DDevice); + } + /* Contrary: D3D starting is handled by the caller, because it knows the render target */ + + memset(&desc, 0, sizeof(desc)); + desc.dwSize = sizeof(desc); + + return IDirectDraw7_EnumSurfaces(ICOM_INTERFACE(This, IDirectDraw7), + 0, + &desc, + This, + IDirectDrawImpl_RecreateSurfacesCallback); +} + +/***************************************************************************** + * D3D7CB_CreateSurface + * + * Callback function for IDirect3DDevice_CreateTexture. It searches for the + * correct mipmap sublevel, and returns it to WineD3D. + * The surfaces are created already by IDirectDraw7::CreateSurface + * + * Params: + * With, Height: With and height of the surface + * Format: The requested format + * Usage, Pool: D3DUSAGE and D3DPOOL of the surface + * level: The mipmap level + * Surface: Pointer to pass the created surface back at + * SharedHandle: NULL + * + * Returns: + * D3D_OK + * + *****************************************************************************/ +static HRESULT WINAPI +D3D7CB_CreateSurface(IUnknown *device, + UINT Width, UINT Height, + WINED3DFORMAT Format, + DWORD Usage, WINED3DPOOL Pool, UINT level, + IWineD3DSurface **Surface, + HANDLE *SharedHandle) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, device); + IDirectDrawSurfaceImpl *surf = This->tex_root; + int i; + TRACE("(%p) call back. surf=%p\n", device, surf); + + /* Find the wanted mipmap. There are enought mipmaps in the chain */ + for(i = 0; i < level; i++) + surf = surf->next_complex; + + /* Return the surface */ + *Surface = surf->WineD3DSurface; + + TRACE("Returning wineD3DSurface %p, it belongs to surface %p\n", *Surface, surf); + return D3D_OK; +} + +/***************************************************************************** + * IDirectDrawImpl_CreateNewSurface + * + * A helper function for IDirectDraw7::CreateSurface. It creates a new surface + * with the passed parameters. + * + * Params: + * DDSD: Description of the surface to create + * Surf: Address to store the interface pointer at + * + * Returns: + * DD_OK on success + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawImpl_CreateNewSurface(IDirectDrawImpl *This, + DDSURFACEDESC2 *pDDSD, + IDirectDrawSurfaceImpl **ppSurf, + UINT level) +{ + HRESULT hr; + UINT Width = 0, Height = 0; + WINED3DFORMAT Format = WINED3DFMT_UNKNOWN; + WINED3DRESOURCETYPE ResType = WINED3DRTYPE_SURFACE; + DWORD Usage = 0; + WINED3DSURFTYPE ImplType = This->ImplType; + WINED3DSURFACE_DESC Desc; + IUnknown *Parent; + IParentImpl *parImpl = NULL; + WINED3DPOOL Pool = WINED3DPOOL_DEFAULT; + + /* Dummies for GetDesc */ + WINED3DPOOL dummy_d3dpool; + WINED3DMULTISAMPLE_TYPE dummy_mst; + UINT dummy_uint; + DWORD dummy_dword; + + if (TRACE_ON(ddraw)) + { + TRACE(" (%p) Requesting surface desc :\n", This); + DDRAW_dump_surface_desc(pDDSD); + } + + /* Select the surface type, if it wasn't choosen yet */ + if(ImplType == SURFACE_UNKNOWN) + { + /* Use GL Surfaces if a D3DDEVICE Surface is requested */ + if(pDDSD->ddsCaps.dwCaps & DDSCAPS_3DDEVICE) + { + TRACE("(%p) Choosing GL surfaces because a 3DDEVICE Surface was requested\n", This); + ImplType = SURFACE_OPENGL; + } + + /* Otherwise use GDI surfaces for now */ + else + { + TRACE("(%p) Choosing GDI surfaces for 2D rendering\n", This); + ImplType = SURFACE_GDI; + } + + /* Policy if all surface implementations are available: + * First, check if a default type was set with winecfg. If not, + * try Xrender surfaces, and use them if they work. Next, check if + * accellerated OpenGL is available, and use GL surfaces in this + * case. If all fails, use GDI surfaces. If a 3DDEVICE surface + * was created, always use OpenGL surfaces. + * + * (Note: Xrender surfaces are not implemented by now, the + * unaccellerated implementation uses GDI to render in Software) + */ + + /* Store the type. If it needs to be changed, all WineD3DSurfaces have to + * be re-created. This could be done with IDirectDrawSurface7::Restore + */ + This->ImplType = ImplType; + } + else + { + if((pDDSD->ddsCaps.dwCaps & DDSCAPS_3DDEVICE ) && + (This->ImplType != SURFACE_OPENGL ) && DefaultSurfaceType == SURFACE_UNKNOWN) + { + /* We have to change to OpenGL, + * and re-create all WineD3DSurfaces + */ + ImplType = SURFACE_OPENGL; + This->ImplType = ImplType; + TRACE("(%p) Re-creating all surfaces\n", This); + IDirectDrawImpl_RecreateAllSurfaces(This); + TRACE("(%p) Done recreating all surfaces\n", This); + } + else if(This->ImplType != SURFACE_OPENGL) + { + WARN("The application requests a 3D capable surface, but a non-opengl surface was set in the registry\n"); + /* Do not fail surface creation, only fail 3D device creation */ + } + } + + /* Get the surface parameters */ + if ( pDDSD->dwFlags & DDSD_LPSURFACE) + { + ERR("(%p) Using a passed surface pointer is not yet supported\n", This); + assert(0); + } + + /* Get the correct wined3d usage */ + if (pDDSD->ddsCaps.dwCaps & (DDSCAPS_PRIMARYSURFACE | + DDSCAPS_BACKBUFFER | + DDSCAPS_3DDEVICE ) ) + { + Usage |= WINED3DUSAGE_RENDERTARGET; + } + if(This->depthstencil) + { + /* The depth stencil creation callback sets this flag. + * Set the WineD3D usage to let it know that it's a depth + * Stencil surface. + */ + Usage |= WINED3DUSAGE_DEPTHSTENCIL; + } + if(pDDSD->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY) + { + Pool = WINED3DPOOL_SYSTEMMEM; + } + + Format = PixelFormat_DD2WineD3D(&pDDSD->u4.ddpfPixelFormat); + if(Format == WINED3DFMT_UNKNOWN) + { + ERR("Unsupported / Unknown pixelformat\n"); + return DDERR_INVALIDPIXELFORMAT; + } + + /* Create the Surface object */ + *ppSurf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectDrawSurfaceImpl)); + if(!*ppSurf) + { + ERR("(%p) Error allocating memory for a surface\n", This); + return DDERR_OUTOFVIDEOMEMORY; + } + ICOM_INIT_INTERFACE(*ppSurf, IDirectDrawSurface7, IDirectDrawSurface7_Vtbl); + ICOM_INIT_INTERFACE(*ppSurf, IDirectDrawSurface3, IDirectDrawSurface3_Vtbl); + ICOM_INIT_INTERFACE(*ppSurf, IDirectDrawGammaControl, IDirectDrawGammaControl_Vtbl); + ICOM_INIT_INTERFACE(*ppSurf, IDirect3DTexture2, IDirect3DTexture2_Vtbl); + ICOM_INIT_INTERFACE(*ppSurf, IDirect3DTexture, IDirect3DTexture1_Vtbl); + (*ppSurf)->ref = 1; + (*ppSurf)->version = 7; + (*ppSurf)->ddraw = This; + (*ppSurf)->surface_desc.dwSize = sizeof(DDSURFACEDESC2); + (*ppSurf)->surface_desc.u4.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT); + DD_STRUCT_COPY_BYSIZE(&(*ppSurf)->surface_desc, pDDSD); + + /* Surface attachments */ + (*ppSurf)->next_attached = NULL; + (*ppSurf)->first_attached = *ppSurf; + + (*ppSurf)->next_complex = NULL; + (*ppSurf)->first_complex = *ppSurf; + + /* Needed to re-create the surface on an implementation change */ + (*ppSurf)->ImplType = ImplType; + + /* For D3DDevice creation */ + (*ppSurf)->isRenderTarget = FALSE; + + /* A trace message for debugging */ + TRACE("(%p) Created IDirectDrawSurface implementation structure at %p\n", This, *ppSurf); + + if(pDDSD->ddsCaps.dwCaps & ( DDSCAPS_PRIMARYSURFACE | DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE) ) + { + /* Render targets and textures need a IParent interface, + * because WineD3D will destroy them when the swapchain + * is released + */ + parImpl = HeapAlloc(GetProcessHeap(), 0, sizeof(IParentImpl)); + if(!parImpl) + { + ERR("Out of memory when allocating memory for a IParent implementation\n"); + return DDERR_OUTOFMEMORY; + } + parImpl->ref = 1; + ICOM_INIT_INTERFACE(parImpl, IParent, IParent_Vtbl); + Parent = (IUnknown *) ICOM_INTERFACE(parImpl, IParent); + TRACE("Using IParent interface %p as parent\n", parImpl); + } + else + { + /* Use the surface as parent */ + Parent = (IUnknown *) ICOM_INTERFACE(*ppSurf, IDirectDrawSurface7); + TRACE("Using Surface interface %p as parent\n", *ppSurf); + } + + /* Now create the WineD3D Surface */ + hr = IWineD3DDevice_CreateSurface(This->wineD3DDevice, + pDDSD->dwWidth, + pDDSD->dwHeight, + Format, + TRUE /* Lockable */, + FALSE /* Discard */, + level, + &(*ppSurf)->WineD3DSurface, + ResType, Usage, + Pool, + WINED3DMULTISAMPLE_NONE, + 0 /* MultiSampleQuality */, + 0 /* SharedHandle */, + ImplType, + Parent); + + if(hr != D3D_OK) + { + ERR("IWineD3DDevice::CreateSurface failed. hr = %08lx\n", hr); + return hr; + } + + /* Set the child of the parent implementation if it exists */ + if(parImpl) + { + parImpl->child = (IUnknown *) (*ppSurf)->WineD3DSurface; + /* The IParent releases the WineD3DSurface, and + * the ddraw surface does that too. Hold an reference + */ + IWineD3DSurface_AddRef((*ppSurf)->WineD3DSurface); + } + + /* Increase the surface counter, and attach the surface */ + InterlockedIncrement(&This->surfaces); + if(This->surface_list) + { + This->surface_list->prev = *ppSurf; + } + (*ppSurf)->next = This->surface_list; + This->surface_list = *ppSurf; + + /* Here we could store all created surfaces in the DirectDrawImpl structure, + * But this could also be delegated to WineDDraw, as it keeps track of all it's + * resources. Not implemented for now, as there are more important things ;) + */ + + /* Get the pixel format of the WineD3DSurface and store it. + * Don't use the Format choosen above, WineD3D might have + * changed it + */ + Desc.Format = &Format; + Desc.Type = &ResType; + Desc.Usage = &Usage; + Desc.Pool = &dummy_d3dpool; + Desc.Size = &dummy_uint; + Desc.MultiSampleType = &dummy_mst; + Desc.MultiSampleQuality = &dummy_dword; + Desc.Width = &Width; + Desc.Height = &Height; + + (*ppSurf)->surface_desc.dwFlags |= DDSD_PIXELFORMAT; + hr = IWineD3DSurface_GetDesc((*ppSurf)->WineD3DSurface, &Desc); + if(hr != D3D_OK) + { + ERR("IWineD3DSurface::GetDesc failed\n"); + IDirectDrawSurface7_Release( (IDirectDrawSurface7 *) *ppSurf); + return hr; + } + + if(Format == WINED3DFMT_UNKNOWN) + { + FIXME("IWineD3DSurface::GetDesc returned WINED3DFMT_UNKNOWN\n"); + } + PixelFormat_WineD3DtoDD( &(*ppSurf)->surface_desc.u4.ddpfPixelFormat, Format); + + /* Anno 1602 stores the pitch right after surface creation, so make sure it's there. + * I can't LockRect() the surface here because if OpenGL surfaces are in use, the + * WineD3DDevice might not be useable for 3D yet, so an extra method was created + */ + (*ppSurf)->surface_desc.dwFlags |= DDSD_PITCH; + (*ppSurf)->surface_desc.u1.lPitch = IWineD3DSurface_GetPitch((*ppSurf)->WineD3DSurface); + + /* Application passed a color key? Set it! */ + if(pDDSD->dwFlags & DDSD_CKDESTOVERLAY) + { + IWineD3DSurface_SetColorKey((*ppSurf)->WineD3DSurface, + DDCKEY_DESTOVERLAY, + &pDDSD->u3.ddckCKDestOverlay); + } + if(pDDSD->dwFlags & DDSD_CKDESTBLT) + { + IWineD3DSurface_SetColorKey((*ppSurf)->WineD3DSurface, + DDCKEY_DESTBLT, + &pDDSD->ddckCKDestBlt); + } + if(pDDSD->dwFlags & DDSD_CKSRCOVERLAY) + { + IWineD3DSurface_SetColorKey((*ppSurf)->WineD3DSurface, + DDCKEY_SRCOVERLAY, + &pDDSD->ddckCKSrcOverlay); + } + if(pDDSD->dwFlags & DDSD_CKSRCBLT) + { + IWineD3DSurface_SetColorKey((*ppSurf)->WineD3DSurface, + DDCKEY_SRCBLT, + &pDDSD->ddckCKSrcBlt); + } + + return DD_OK; +} + +/***************************************************************************** + * IDirectDraw7::CreateSurface + * + * Creates a new IDirectDrawSurface object and returns it's interface. + * + * The surface connections with wined3d are a bit tricky. Basically it works + * like this: + * + * |------------------------| |-----------------| + * | DDraw surface | | WineD3DSurface | + * | | | | + * | WineD3DSurface |-------------->| | + * | Child |<------------->| Parent | + * |------------------------| |-----------------| + * + * The DDraw surface is the parent of the wined3d surface, and it releases + * the WineD3DSurface when the ddraw surface is destroyed. + * + * However, for all surfaces which can be in a container in WineD3D, + * we have to do this. These surfaces are ususally compley surfaces, + * so this concernes primary surfaces with a front and a back buffer, + * and textures textures. + * + * |------------------------| |-----------------| + * | DDraw surface | | Containter | + * | | | | + * | Child |<------------->| Parent | + * | Texture |<------------->| | + * | WineD3DSurface |<----| | Levels |<--| + * | Complex connection | | | | | + * |------------------------| | |-----------------| | + * ^ | | + * | | | + * | | | + * | |------------------| | |-----------------| | + * | | IParent | |-------->| WineD3DSurface | | + * | | | | | | + * | | Child |<------------->| Parent | | + * | | | | Container |<--| + * | |------------------| |-----------------| | + * | | + * | |----------------------| | + * | | DDraw surface 2 | | + * | | | | + * |<->| Complex root Child | | + * | | Texture | | + * | | WineD3DSurface |<----| | + * | |----------------------| | | + * | | | + * | |---------------------| | |-----------------| | + * | | IParent | |----->| WineD3DSurface | | + * | | | | | | + * | | Child |<---------->| Parent | | + * | |---------------------| | Container |<--| + * | |-----------------| | + * | | + * | ---More surfaces can follow--- | + * + * The reason is that the IWineD3DSwapchain(render target container) + * and the IWineD3DTexure(Texture container) release the parents + * of their surface's children, but by releasing the complex root + * the surfaces which are complexly attached to it are destroyed + * too. See IDirectDrawSurface::Release for a more detailed + * explanation. + * + * Params: + * DDSD: Description of the surface to create + * Surf: Address to store the interface pointer at + * UnkOuter: Basically for aggregation support, but ddraw doesn't support + * aggregation, so it has to be NULL + * + * Returns: + * DD_OK on success + * CLASS_E_NOAGGREGATION if UnkOuter != NULL + * DDERR_* if an error occurs + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawImpl_CreateSurface(IDirectDraw7 *iface, + DDSURFACEDESC2 *DDSD, + IDirectDrawSurface7 **Surf, + IUnknown *UnkOuter) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface); + IDirectDrawSurfaceImpl *object = NULL; + HRESULT hr; + LONG extra_surfaces = 0, i; + DDSURFACEDESC2 desc2; + UINT level = 0; + WINED3DDISPLAYMODE Mode; + + TRACE("(%p)->(%p,%p,%p)\n", This, DDSD, Surf, UnkOuter); + + /* Some checks before we start */ + if (TRACE_ON(ddraw)) + { + TRACE(" (%p) Requesting surface desc :\n", This); + DDRAW_dump_surface_desc(DDSD); + } + + if (UnkOuter != NULL) + { + FIXME("(%p) : outer != NULL?\n", This); + return CLASS_E_NOAGGREGATION; /* unchecked */ + } + + if (!(DDSD->dwFlags & DDSD_CAPS)) + { + /* DVIDEO.DLL does forget the DDSD_CAPS flag ... *sigh* */ + DDSD->dwFlags |= DDSD_CAPS; + } + if (DDSD->ddsCaps.dwCaps == 0) + { + /* This has been checked on real Windows */ + DDSD->ddsCaps.dwCaps = DDSCAPS_LOCALVIDMEM | DDSCAPS_VIDEOMEMORY; + } + + if (DDSD->ddsCaps.dwCaps & DDSCAPS_ALLOCONLOAD) + { + /* If the surface is of the 'alloconload' type, ignore the LPSURFACE field */ + DDSD->dwFlags &= ~DDSD_LPSURFACE; + } + + if ((DDSD->dwFlags & DDSD_LPSURFACE) && (DDSD->lpSurface == NULL)) + { + /* Frank Herbert's Dune specifies a null pointer for the surface, ignore the LPSURFACE field */ + WARN("(%p) Null surface pointer specified, ignore it!\n", This); + DDSD->dwFlags &= ~DDSD_LPSURFACE; + } + + if (Surf == NULL) + { + FIXME("(%p) You want to get back a surface? Don't give NULL ptrs!\n", This); + return E_POINTER; /* unchecked */ + } + + /* Modify some flags */ + memset(&desc2, 0, sizeof(desc2)); + desc2.dwSize = sizeof(desc2); /*For the struct copy */ + DD_STRUCT_COPY_BYSIZE(&desc2, DDSD); + desc2.dwSize = sizeof(desc2); /* To override a possibly smaller size */ + desc2.u4.ddpfPixelFormat.dwSize=sizeof(DDPIXELFORMAT); /* Just to be sure */ + + /* Get the video mode from WineD3D - we will need it */ + hr = IWineD3DDevice_GetDisplayMode(This->wineD3DDevice, + 0, /* Swapchain 0 */ + &Mode); + if(FAILED(hr)) + { + ERR("Failed to read display mode from wined3d\n"); + switch(This->orig_bpp) + { + case 8: + Mode.Format = WINED3DFMT_P8; + break; + + case 15: + Mode.Format = WINED3DFMT_X1R5G5B5; + break; + + case 16: + Mode.Format = WINED3DFMT_R5G6B5; + break; + + case 24: + Mode.Format = WINED3DFMT_R8G8B8; + break; + + case 32: + Mode.Format = WINED3DFMT_X8R8G8B8; + break; + } + Mode.Width = This->orig_width; + Mode.Height = This->orig_height; + } + + /* No pixelformat given? Use the current screen format */ + if(!(desc2.dwFlags & DDSD_PIXELFORMAT)) + { + desc2.dwFlags |= DDSD_PIXELFORMAT; + desc2.u4.ddpfPixelFormat.dwSize=sizeof(DDPIXELFORMAT); + + /* Wait: It could be a Z buffer */ + if(desc2.ddsCaps.dwCaps & DDSCAPS_ZBUFFER) + { + switch(desc2.u2.dwMipMapCount) /* Who had this glourious idea? */ + { + case 15: + PixelFormat_WineD3DtoDD(&desc2.u4.ddpfPixelFormat, WINED3DFMT_D15S1); + break; + case 16: + PixelFormat_WineD3DtoDD(&desc2.u4.ddpfPixelFormat, WINED3DFMT_D16); + break; + case 24: + PixelFormat_WineD3DtoDD(&desc2.u4.ddpfPixelFormat, WINED3DFMT_D24X8); + break; + case 32: + PixelFormat_WineD3DtoDD(&desc2.u4.ddpfPixelFormat, WINED3DFMT_D32); + break; + default: + ERR("Unknown Z buffer bit depth\n"); + } + } + else + { + PixelFormat_WineD3DtoDD(&desc2.u4.ddpfPixelFormat, Mode.Format); + } + } + + /* No Width or no Height? Use the current window size or + * the original screen size + */ + if(!(desc2.dwFlags & DDSD_WIDTH) || + !(desc2.dwFlags & DDSD_HEIGHT) ) + { + HWND window; + + /* Fallback: From WineD3D / original mode */ + desc2.dwFlags |= DDSD_WIDTH | DDSD_HEIGHT; + desc2.dwWidth = Mode.Width; + desc2.dwHeight = Mode.Height; + + hr = IWineD3DDevice_GetHWND(This->wineD3DDevice, + &window); + if( (hr == D3D_OK) && (window != 0) ) + { + RECT rect; + if(GetWindowRect(window, &rect) ) + { + /* This is a hack until I find a better solution */ + if( (rect.right - rect.left) <= 1 || + (rect.bottom - rect.top) <= 1 ) + { + FIXME("Wanted to get surface dimensions from window %p, but it has only \ + a size of %ldx%ld. Using full screen dimensions\n", + window, rect.right - rect.left, rect.bottom - rect.top); + } + else + { + /* Not sure if this is correct */ + desc2.dwWidth = rect.right - rect.left; + desc2.dwHeight = rect.bottom - rect.top; + TRACE("Using window %p's dimensions: %ldx%ld\n", window, desc2.dwWidth, desc2.dwHeight); + } + } + } + } + + /* Mipmap count fixes */ + if(desc2.ddsCaps.dwCaps & DDSCAPS_MIPMAP) + { + if(desc2.ddsCaps.dwCaps & DDSCAPS_COMPLEX) + { + if(desc2.dwFlags & DDSD_MIPMAPCOUNT) + { + /* Mipmap count is given, nothing to do */ + } + else + { + /* Undocumented feature: Create sublevels until + * eighter the width or the height is 1 + */ + DWORD min = desc2.dwWidth < desc2.dwHeight ? + desc2.dwWidth : desc2.dwHeight; + desc2.u2.dwMipMapCount = 0; + while( min ) + { + desc2.u2.dwMipMapCount += 1; + min >>= 1; + } + } + } + else + { + /* Not-complex mipmap -> Mipmapcount = 1 */ + desc2.u2.dwMipMapCount = 1; + } + extra_surfaces = desc2.u2.dwMipMapCount - 1; + + /* There's a mipmap count in the created surface in any case */ + desc2.dwFlags |= DDSD_MIPMAPCOUNT; + } + /* If no mipmap is given, the texture has only one level */ + + /* The first surface is a front buffer, the back buffer is created afterwards */ + if( (desc2.dwFlags & DDSD_CAPS) && (desc2.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) ) + { + desc2.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER; + } + + /* Create the first surface */ + hr = IDirectDrawImpl_CreateNewSurface(This, &desc2, &object, 0); + if( hr != DD_OK) + { + ERR("IDirectDrawImpl_CreateNewSurface failed with %08lx\n", hr); + return hr; + } + + *Surf = ICOM_INTERFACE(object, IDirectDrawSurface7); + + /* Create Additional surfaces if necessary + * This applies to Primary surfaces which have a back buffer count + * set, but not to mipmap textures. In case of Mipmap textures, + * wineD3D takes care of the creation of additional surfaces + */ + if(DDSD->dwFlags & DDSD_BACKBUFFERCOUNT) + { + extra_surfaces = DDSD->dwBackBufferCount; + desc2.ddsCaps.dwCaps &= ~DDSCAPS_FRONTBUFFER; /* It's not a front buffer */ + desc2.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER; + } + + for(i = 0; i < extra_surfaces; i++) + { + IDirectDrawSurfaceImpl *object2 = NULL; + IDirectDrawSurfaceImpl *iterator; + + /* increase the mipmap level, but only if a mipmap is created + * In this case, also half the size + */ + if(DDSD->ddsCaps.dwCaps & DDSCAPS_MIPMAP) + { + level++; + desc2.dwWidth /= 2; + desc2.dwHeight /= 2; + } + + hr = IDirectDrawImpl_CreateNewSurface(This, + &desc2, + &object2, + level); + if(hr != DD_OK) + { + /* This destroys and possibly created surfaces too */ + IDirectDrawSurface_Release( ICOM_INTERFACE(object, IDirectDrawSurface7) ); + return hr; + } + + /* Add the new surface to the complex attachment list */ + object2->first_complex = object; + object2->next_complex = NULL; + iterator = object; + while(iterator->next_complex) iterator = iterator->next_complex; + iterator->next_complex = object2; + + /* Remove the (possible) back buffer cap from the new surface description, + * because only one surface in the flipping chain is a back buffer, one + * is a front buffer, the others are just primary surfaces. + */ + desc2.ddsCaps.dwCaps &= ~DDSCAPS_BACKBUFFER; + } + + /* Addref the ddraw interface to keep an reference for each surface */ + IDirectDraw7_AddRef(iface); + + /* If the implementation is OpenGL and there's no d3ddevice, attach a d3ddevice + * But attach the d3ddevice only if the currently created surface was + * a primary surface(2D app in 3D mode) or a 3DDEVICE surface(3D app) + * The only case I can think of where this doesn't apply is when a + * 2D app was configured by the user to run with OpenGL and it didn't create + * the render target as first surface. In this case the render target creation + * will cause the 3D init. + */ + if( (This->ImplType == SURFACE_OPENGL) && !(This->d3d_initialized) && + desc2.ddsCaps.dwCaps & (DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE) ) + { + IDirectDrawSurfaceImpl *target = This->surface_list; + + /* Search for the primary to use as render target */ + while(target) + { + if(target->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) + { + /* found */ + TRACE("Using primary %p as render target\n", target); + break; + } + target = target->next; + } + /* If it's not found, use the just created DDSCAPS_3DDEVICE surface */ + if(!target) + { + target = object; + } + + TRACE("(%p) Attaching a D3DDevice, rendertarget = %p\n", This, target); + hr = IDirectDrawImpl_AttachD3DDevice(This, target->first_complex); + if(hr != D3D_OK) + { + ERR("IDirectDrawImpl_AttachD3DDevice failed, hr = %lx\n", hr); + } + } + + /* Create a WineD3DTexture if a texture was requested */ + if(DDSD->ddsCaps.dwCaps & DDSCAPS_TEXTURE) + { + UINT levels; + WINED3DFORMAT Format; + WINED3DPOOL Pool = WINED3DPOOL_DEFAULT; + + This->tex_root = object; + + if(desc2.ddsCaps.dwCaps & DDSCAPS_MIPMAP) + { + /* a mipmap is created, create enought levels */ + levels = desc2.u2.dwMipMapCount; + } + else + { + /* No mipmap is created, create one level */ + levels = 1; + } + + /* DDSCAPS_SYSTEMMEMORY textures are in WINED3DPOOL_SYSTEMMEM */ + if(DDSD->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY) + { + Pool = WINED3DPOOL_SYSTEMMEM; + } + /* Should I forward the MANEGED cap to the managed pool ? */ + + /* Get the format. It's set already by CreateNewSurface */ + Format = PixelFormat_DD2WineD3D(&object->surface_desc.u4.ddpfPixelFormat); + + /* The surfaces are already created, the callback only + * passes the IWineD3DSurface to WineD3D + */ + hr = IWineD3DDevice_CreateTexture( This->wineD3DDevice, + DDSD->dwWidth, DDSD->dwHeight, + levels, /* MipMapCount = Levels */ + 0, /* usage */ + Format, + Pool, + &object->wineD3DTexture, + 0, /* SharedHandle */ + (IUnknown *) ICOM_INTERFACE(object, IDirectDrawSurface7), + D3D7CB_CreateSurface ); + This->tex_root = NULL; + } + + return hr; +} + +#define DDENUMSURFACES_SEARCHTYPE (DDENUMSURFACES_CANBECREATED|DDENUMSURFACES_DOESEXIST) +#define DDENUMSURFACES_MATCHTYPE (DDENUMSURFACES_ALL|DDENUMSURFACES_MATCH|DDENUMSURFACES_NOMATCH) + +static BOOL +Main_DirectDraw_DDPIXELFORMAT_Match(const DDPIXELFORMAT *requested, + const DDPIXELFORMAT *provided) +{ + /* Some flags must be present in both or neither for a match. */ + static const DWORD must_match = DDPF_PALETTEINDEXED1 | DDPF_PALETTEINDEXED2 + | DDPF_PALETTEINDEXED4 | DDPF_PALETTEINDEXED8 | DDPF_FOURCC + | DDPF_ZBUFFER | DDPF_STENCILBUFFER; + + if ((requested->dwFlags & provided->dwFlags) != requested->dwFlags) + return FALSE; + + if ((requested->dwFlags & must_match) != (provided->dwFlags & must_match)) + return FALSE; + + if (requested->dwFlags & DDPF_FOURCC) + if (requested->dwFourCC != provided->dwFourCC) + return FALSE; + + if (requested->dwFlags & (DDPF_RGB|DDPF_YUV|DDPF_ZBUFFER|DDPF_ALPHA + |DDPF_LUMINANCE|DDPF_BUMPDUDV)) + if (requested->u1.dwRGBBitCount != provided->u1.dwRGBBitCount) + return FALSE; + + if (requested->dwFlags & (DDPF_RGB|DDPF_YUV|DDPF_STENCILBUFFER + |DDPF_LUMINANCE|DDPF_BUMPDUDV)) + if (requested->u2.dwRBitMask != provided->u2.dwRBitMask) + return FALSE; + + if (requested->dwFlags & (DDPF_RGB|DDPF_YUV|DDPF_ZBUFFER|DDPF_BUMPDUDV)) + if (requested->u3.dwGBitMask != provided->u3.dwGBitMask) + return FALSE; + + /* I could be wrong about the bumpmapping. MSDN docs are vague. */ + if (requested->dwFlags & (DDPF_RGB|DDPF_YUV|DDPF_STENCILBUFFER + |DDPF_BUMPDUDV)) + if (requested->u4.dwBBitMask != provided->u4.dwBBitMask) + return FALSE; + + if (requested->dwFlags & (DDPF_ALPHAPIXELS|DDPF_ZPIXELS)) + if (requested->u5.dwRGBAlphaBitMask != provided->u5.dwRGBAlphaBitMask) + return FALSE; + + return TRUE; +} + +static BOOL +IDirectDrawImpl_DDSD_Match(const DDSURFACEDESC2* requested, + const DDSURFACEDESC2* provided) +{ + struct compare_info + { + DWORD flag; + ptrdiff_t offset; + size_t size; + }; + +#define CMP(FLAG, FIELD) \ + { DDSD_##FLAG, offsetof(DDSURFACEDESC2, FIELD), \ + sizeof(((DDSURFACEDESC2 *)(NULL))->FIELD) } + + static const struct compare_info compare[] = + { + CMP(ALPHABITDEPTH, dwAlphaBitDepth), + CMP(BACKBUFFERCOUNT, dwBackBufferCount), + CMP(CAPS, ddsCaps), + CMP(CKDESTBLT, ddckCKDestBlt), + CMP(CKDESTOVERLAY, u3 /* ddckCKDestOverlay */), + CMP(CKSRCBLT, ddckCKSrcBlt), + CMP(CKSRCOVERLAY, ddckCKSrcOverlay), + CMP(HEIGHT, dwHeight), + CMP(LINEARSIZE, u1 /* dwLinearSize */), + CMP(LPSURFACE, lpSurface), + CMP(MIPMAPCOUNT, u2 /* dwMipMapCount */), + CMP(PITCH, u1 /* lPitch */), + /* PIXELFORMAT: manual */ + CMP(REFRESHRATE, u2 /* dwRefreshRate */), + CMP(TEXTURESTAGE, dwTextureStage), + CMP(WIDTH, dwWidth), + /* ZBUFFERBITDEPTH: "obsolete" */ + }; + +#undef CMP + + unsigned int i; + + if ((requested->dwFlags & provided->dwFlags) != requested->dwFlags) + return FALSE; + + for (i=0; i < sizeof(compare)/sizeof(compare[0]); i++) + { + if (requested->dwFlags & compare[i].flag + && memcmp((const char *)provided + compare[i].offset, + (const char *)requested + compare[i].offset, + compare[i].size) != 0) + return FALSE; + } + + if (requested->dwFlags & DDSD_PIXELFORMAT) + { + if (!Main_DirectDraw_DDPIXELFORMAT_Match(&requested->u4.ddpfPixelFormat, + &provided->u4.ddpfPixelFormat)) + return FALSE; + } + + return TRUE; +} + +#undef DDENUMSURFACES_SEARCHTYPE +#undef DDENUMSURFACES_MATCHTYPE + +/***************************************************************************** + * IDirectDraw7::EnumSurfaces + * + * Loops through all surfaces attached to this device and calls the + * application callback. This can't be relayed to WineD3DDevice, + * because some WineD3DSurfaces' parents are IParent objects + * + * Params: + * Flags: Some filtering flags. See IDirectDrawImpl_EnumSurfacesCallback + * DDSD: Description to filter for + * Context: Application-provided pointer, it's passed unmodified to the + * Callback function + * Callback: Address to call for each surface + * + * Returns: + * DDERR_INVALIDPARAMS if the callback is NULL + * DD_OK on success + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawImpl_EnumSurfaces(IDirectDraw7 *iface, + DWORD Flags, + DDSURFACEDESC2 *DDSD, + void *Context, + LPDDENUMSURFACESCALLBACK7 Callback) +{ + /* The surface enumeration is handled by WineDDraw, + * because it keeps track of all surfaces attached to + * it. The filtering is done by our callback function, + * because WineDDraw doesn't handle ddraw-like surface + * caps structures + */ + ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface); + IDirectDrawSurfaceImpl *surf; + BOOL all, nomatch; + DDSURFACEDESC2 desc; + + all = Flags & DDENUMSURFACES_ALL; + nomatch = Flags & DDENUMSURFACES_NOMATCH; + + TRACE("(%p)->(%lx,%p,%p,%p)\n", This, Flags, DDSD, Context, Callback); + + if(!Callback) + return DDERR_INVALIDPARAMS; + + for(surf = This->surface_list; surf; surf = surf->next) + { + if (all || (nomatch != IDirectDrawImpl_DDSD_Match(DDSD, &surf->surface_desc))) + { + desc = surf->surface_desc; + IDirectDrawSurface7_AddRef(ICOM_INTERFACE(surf, IDirectDrawSurface7)); + if(Callback( ICOM_INTERFACE(surf, IDirectDrawSurface7), &desc, Context) != DDENUMRET_OK) + return DD_OK; + } + } + return DD_OK; +} + +/***************************************************************************** + * D3D7CB_CreateRenderTarget + * + * Callback called by WineD3D to create Surfaces for render target usage + * This function takes the D3D target from the IDirectDrawImpl structure, + * and returns the WineD3DSurface. To avoid double usage, the surface + * is marked as render target afterwards + * + * Params + * device: The WineD3DDevice's parent + * Width, Height, Format: Dimesions and pixelformat of the render target + * Ignored, because the surface already exists + * MultiSample, MultisampleQuality, Lockable: Ignored for the same reason + * Lockable: ignored + * ppSurface: Address to pass the surface pointer back at + * pSharedHandle: Ignored + * + * Returns: + * Always returns D3D_OK + * + *****************************************************************************/ +static HRESULT WINAPI +D3D7CB_CreateRenderTarget(IUnknown *device, UINT Width, UINT Height, + WINED3DFORMAT Format, + WINED3DMULTISAMPLE_TYPE MultiSample, + DWORD MultisampleQuality, + BOOL Lockable, + IWineD3DSurface** ppSurface, + HANDLE* pSharedHandle) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, device); + IDirectDrawSurfaceImpl *d3dSurface = (IDirectDrawSurfaceImpl *) This->d3d_target->first_complex; + TRACE("(%p) call back\n", device); + + /* Loop through the complex chain and try to find unused primary surfaces */ + while(d3dSurface->isRenderTarget) + { + d3dSurface = d3dSurface->next_complex; + if(!d3dSurface) break; + } + if(!d3dSurface) + { + d3dSurface = This->d3d_target; + ERR(" (%p) : No DirectDrawSurface found to create the back buffer. Using the front buffer as back buffer. Uncertain consequences\n", This); + } + + /* TODO: Return failure if the dimensions do not match, but this shouldn't happen */ + + *ppSurface = d3dSurface->WineD3DSurface; + d3dSurface->isRenderTarget = TRUE; + TRACE("Returning wineD3DSurface %p, it belongs to surface %p\n", *ppSurface, d3dSurface); + return D3D_OK; +} + +static HRESULT WINAPI +D3D7CB_CreateDepthStencilSurface(IUnknown *device, + UINT Width, + UINT Height, + WINED3DFORMAT Format, + WINED3DMULTISAMPLE_TYPE MultiSample, + DWORD MultisampleQuality, + BOOL Discard, + IWineD3DSurface** ppSurface, + HANDLE* pSharedHandle) +{ + /* Create a Depth Stencil surface to make WineD3D happy */ + HRESULT hr = D3D_OK; + ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, device); + DDSURFACEDESC2 ddsd; + + TRACE("(%p) call back\n", device); + + *ppSurface = NULL; + + /* Create a DirectDraw surface */ + memset(&ddsd, 0, sizeof(ddsd)); + ddsd.dwSize = sizeof(ddsd); + ddsd.u4.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT); + ddsd.dwFlags = DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS; + ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; + ddsd.dwHeight = Height; + ddsd.dwWidth = Width; + if(Format != 0) + { + PixelFormat_WineD3DtoDD(&ddsd.u4.ddpfPixelFormat, Format); + } + else + { + ddsd.dwFlags ^= DDSD_PIXELFORMAT; + } + + This->depthstencil = TRUE; + hr = IDirectDraw7_CreateSurface((IDirectDraw7 *) This, + &ddsd, + (IDirectDrawSurface7 **) &This->DepthStencilBuffer, + NULL); + This->depthstencil = FALSE; + if(FAILED(hr)) + { + ERR(" (%p) Creating a DepthStencil Surface failed, result = %lx\n", This, hr); + return hr; + } + *ppSurface = This->DepthStencilBuffer->WineD3DSurface; + return D3D_OK; +} + +/***************************************************************************** + * D3D7CB_CreateAdditionalSwapChain + * + * Callback function for WineD3D which creates a new WineD3DSwapchain + * interface. It also creates a IParent interface to store that pointer, + * so the WineD3DSwapchain has a parent and can be released when the D3D + * device is destroyed + *****************************************************************************/ +HRESULT WINAPI +D3D7CB_CreateAdditionalSwapChain(IUnknown *device, + WINED3DPRESENT_PARAMETERS* pPresentationParameters, + IWineD3DSwapChain ** ppSwapChain) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, device); + IParentImpl *object = NULL; + HRESULT res = D3D_OK; + IWineD3DSwapChain *swapchain; + TRACE("(%p) call back\n", device); + + object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IParentImpl)); + if (NULL == object) + { + FIXME("Allocation of memory failed\n"); + *ppSwapChain = NULL; + return DDERR_OUTOFVIDEOMEMORY; + } + + ICOM_INIT_INTERFACE(object, IParent, IParent_Vtbl); + object->ref = 1; + + res = IWineD3DDevice_CreateAdditionalSwapChain(This->wineD3DDevice, + pPresentationParameters, + &swapchain, + (IUnknown*) ICOM_INTERFACE(object, IParent), + D3D7CB_CreateRenderTarget, + D3D7CB_CreateDepthStencilSurface); + if (res != D3D_OK) + { + FIXME("(%p) call to IWineD3DDevice_CreateAdditionalSwapChain failed\n", This); + HeapFree(GetProcessHeap(), 0 , object); + *ppSwapChain = NULL; + } + else + { + *ppSwapChain = swapchain; + object->child = (IUnknown *) swapchain; + } + + return res; +} + +/***************************************************************************** + * IDirectDrawImpl_AttachD3DDevice + * + * Initializes the D3D capatiblities of WineD3D + * + * Params: + * primary: The primary surface for D3D + * + * Returns + * DD_OK on success, + * DDERR_* otherwise + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawImpl_AttachD3DDevice(IDirectDrawImpl *This, + IDirectDrawSurfaceImpl *primary) +{ + HRESULT hr; + UINT BackBufferCount = 0; + HWND window; + + WINED3DPRESENT_PARAMETERS localParameters; + BOOL isWindowed, EnableAutoDepthStencil; + WINED3DFORMAT AutoDepthStencilFormat; + WINED3DMULTISAMPLE_TYPE MultiSampleType; + WINED3DSWAPEFFECT SwapEffect; + DWORD Flags, MultiSampleQuality; + UINT FullScreen_RefreshRateInHz, PresentationInterval; + WINED3DDISPLAYMODE Mode; + + TRACE("(%p)->(%p)\n", This, primary); + + /* Get the window */ + hr = IWineD3DDevice_GetHWND(This->wineD3DDevice, + &window); + if(hr != D3D_OK) + { + ERR("IWineD3DDevice::GetHWND failed\n"); + return hr; + } + + /* If there's no window, create a hidden window. WineD3D needs it */ + if(window == 0) + { + window = CreateWindowExA(0, This->classname, "Hidden D3D Window", + WS_DISABLED, 0, 0, + GetSystemMetrics(SM_CXSCREEN), + GetSystemMetrics(SM_CYSCREEN), + NULL, NULL, GetModuleHandleA(0), NULL); + + ShowWindow(window, SW_HIDE); /* Just to be sure */ + WARN("(%p) No window for the Direct3DDevice, created a hidden window. HWND=%p\n", This, window); + This->d3d_window = window; + } + else + { + TRACE("(%p) Using existing window %p for Direct3D rendering\n", This, window); + } + + /* use the surface description for the device parameters, not the + * Device settings. The app might render to an offscreen surface + */ + Mode.Width = primary->surface_desc.dwWidth; + Mode.Height = primary->surface_desc.dwHeight; + Mode.Format = PixelFormat_DD2WineD3D(&primary->surface_desc.u4.ddpfPixelFormat); + + if(primary->surface_desc.dwFlags & DDSD_BACKBUFFERCOUNT) + { + BackBufferCount = primary->surface_desc.dwBackBufferCount; + } + + /* Store the future Render Target surface */ + This->d3d_target = primary; + + isWindowed = !(This->cooperative_level & DDSCL_FULLSCREEN); + EnableAutoDepthStencil = FALSE; + AutoDepthStencilFormat = WINED3DFMT_D16; + MultiSampleType = WINED3DMULTISAMPLE_NONE; + SwapEffect = WINED3DSWAPEFFECT_COPY; + Flags = 0; + MultiSampleQuality = 0; + FullScreen_RefreshRateInHz = WINED3DPRESENT_RATE_DEFAULT; /* Default rate: It's allready set */ + PresentationInterval = WINED3DPRESENT_INTERVAL_DEFAULT; + + TRACE("Passing mode %d\n", Mode.Format); + + localParameters.BackBufferWidth = &Mode.Width; + localParameters.BackBufferHeight = &Mode.Height; + localParameters.BackBufferFormat = (WINED3DFORMAT *) &Mode.Format; + localParameters.BackBufferCount = (UINT *) &BackBufferCount; + localParameters.MultiSampleType = &MultiSampleType; + localParameters.MultiSampleQuality = &MultiSampleQuality; + localParameters.SwapEffect = &SwapEffect; + localParameters.hDeviceWindow = &window; + localParameters.Windowed = &isWindowed; + localParameters.EnableAutoDepthStencil = &EnableAutoDepthStencil; + localParameters.AutoDepthStencilFormat = &AutoDepthStencilFormat; + localParameters.Flags = &Flags; + localParameters.FullScreen_RefreshRateInHz = &FullScreen_RefreshRateInHz; + localParameters.PresentationInterval = &PresentationInterval; + + /* Set this NOW, otherwise creating the depth stencil surface will cause an + * recursive loop until ram or emulated video memory is full + */ + This->d3d_initialized = TRUE; + + hr = IWineD3DDevice_Init3D(This->wineD3DDevice, + &localParameters, + D3D7CB_CreateAdditionalSwapChain); + if(FAILED(hr)) + { + This->wineD3DDevice = NULL; + return hr; + } + + /* Create an Index Buffer parent */ + TRACE("(%p) Successfully initialized 3D\n", This); + return DD_OK; +} + +/***************************************************************************** + * DirectDrawCreateClipper (DDRAW.@) + * + * Creates a new IDirectDrawClipper object. + * + * Params: + * Clipper: Address to write the interface pointer to + * UnkOuter: For aggregation support, which ddraw doesn't have. Has to be + * NULL + * + * Returns: + * CLASS_E_NOAGGREGATION if UnkOuter != NULL + * E_OUTOFMEMORY if allocating the object failed + * + *****************************************************************************/ +HRESULT WINAPI +DirectDrawCreateClipper(DWORD Flags, + IDirectDrawClipper **Clipper, + IUnknown *UnkOuter) +{ + IDirectDrawClipperImpl* object; + TRACE("(%08lx,%p,%p)\n", Flags, Clipper, UnkOuter); + + if (UnkOuter != NULL) return CLASS_E_NOAGGREGATION; + + object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + sizeof(IDirectDrawClipperImpl)); + if (object == NULL) return E_OUTOFMEMORY; + + ICOM_INIT_INTERFACE(object, IDirectDrawClipper, IDirectDrawClipper_Vtbl); + object->ref = 1; + object->hWnd = 0; + object->ddraw_owner = NULL; + + *Clipper = (IDirectDrawClipper *) object; + return DD_OK; +} + +/***************************************************************************** + * IDirectDraw7::CreateClipper + * + * Creates a DDraw clipper. See DirectDrawCreateClipper for details + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawImpl_CreateClipper(IDirectDraw7 *iface, + DWORD Flags, + IDirectDrawClipper **Clipper, + IUnknown *UnkOuter) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface); + TRACE("(%p)->(%lx,%p,%p)\n", This, Flags, Clipper, UnkOuter); + return DirectDrawCreateClipper(Flags, Clipper, UnkOuter); +} + +/***************************************************************************** + * IDirectDraw7::CreatePalette + * + * Creates a new IDirectDrawPalette object + * + * Params: + * Flags: The flags for the new clipper + * ColorTable: Color table to assign to the new clipper + * Palette: Address to write the interface pointer to + * UnkOuter: For aggregation support, which ddraw doesn't have. Has to be + * NULL + * + * Returns: + * CLASS_E_NOAGGREGATION if UnkOuter != NULL + * E_OUTOFMEMORY if allocating the object failed + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawImpl_CreatePalette(IDirectDraw7 *iface, + DWORD Flags, + PALETTEENTRY *ColorTable, + IDirectDrawPalette **Palette, + IUnknown *pUnkOuter) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface); + IDirectDrawPaletteImpl *object; + HRESULT hr = DDERR_GENERIC; + TRACE("(%p)->(%lx,%p,%p,%p)\n", This, Flags, ColorTable, Palette, pUnkOuter); + + if(pUnkOuter != NULL) return CLASS_E_NOAGGREGATION; /* unchecked */ + + object = HeapAlloc(GetProcessHeap(), 0, sizeof(IDirectDrawPaletteImpl)); + if(!object) return E_OUTOFMEMORY; + + ICOM_INIT_INTERFACE(object, IDirectDrawPalette, IDirectDrawPalette_Vtbl); + object->ref = 1; + + hr = IWineD3DDevice_CreatePalette(This->wineD3DDevice, Flags, ColorTable, &object->wineD3DPalette, (IUnknown *) ICOM_INTERFACE(object, IDirectDrawPalette) ); + if(hr != DD_OK) + { + HeapFree(GetProcessHeap(), 0, object); + return hr; + } + + *Palette = ICOM_INTERFACE(object, IDirectDrawPalette); + return DD_OK; +} + +/***************************************************************************** + * IDirectDraw7::DuplicateSurface + * + * Duplicates a surface. The surface memory points to the same memory as + * the original surface, and it's released when the last surface referring + * it is released. I guess that's beyond Wines surface management right now + * (Idea: create a new DDraw surface with the same WineD3DSurface. I need a + * test application to implement this) + * + * Params: + * Src: Address of the source surface + * Dest: Address to write the new surface pointer to + * + * Returns: + * See IDirectDraw7::CreateSurface + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawImpl_DuplicateSurface(IDirectDraw7 *iface, + IDirectDrawSurface7 *Src, + IDirectDrawSurface7 **Dest) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw7, iface); + IDirectDrawSurfaceImpl *Surf = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, Src); + + FIXME("(%p)->(%p,%p)\n", This, Surf, Dest); + + /* For now, simply create a new, independent surface */ + return IDirectDraw7_CreateSurface(iface, + &Surf->surface_desc, + Dest, + NULL); +} + +/***************************************************************************** + * IDirectDraw7 VTable + *****************************************************************************/ +const IDirectDraw7Vtbl IDirectDraw7_Vtbl = +{ + /*** IUnkown ***/ + IDirectDrawImpl_QueryInterface, + IDirectDrawImpl_AddRef, + IDirectDrawImpl_Release, + /*** IDirectDraw ***/ + IDirectDrawImpl_Compact, + IDirectDrawImpl_CreateClipper, + IDirectDrawImpl_CreatePalette, + IDirectDrawImpl_CreateSurface, + IDirectDrawImpl_DuplicateSurface, + IDirectDrawImpl_EnumDisplayModes, + IDirectDrawImpl_EnumSurfaces, + IDirectDrawImpl_FlipToGDISurface, + IDirectDrawImpl_GetCaps, + IDirectDrawImpl_GetDisplayMode, + IDirectDrawImpl_GetFourCCCodes, + IDirectDrawImpl_GetGDISurface, + IDirectDrawImpl_GetMonitorFrequency, + IDirectDrawImpl_GetScanLine, + IDirectDrawImpl_GetVerticalBlankStatus, + IDirectDrawImpl_Initialize, + IDirectDrawImpl_RestoreDisplayMode, + IDirectDrawImpl_SetCooperativeLevel, + IDirectDrawImpl_SetDisplayMode, + IDirectDrawImpl_WaitForVerticalBlank, + /*** IDirectDraw2 ***/ + IDirectDrawImpl_GetAvailableVidMem, + /*** IDirectDraw7 ***/ + IDirectDrawImpl_GetSurfaceFromDC, + IDirectDrawImpl_RestoreAllSurfaces, + IDirectDrawImpl_TestCooperativeLevel, + IDirectDrawImpl_GetDeviceIdentifier, + /*** IDirectDraw7 ***/ + IDirectDrawImpl_StartModeTest, + IDirectDrawImpl_EvaluateMode +}; diff --git a/dlls/ddraw/ddraw.spec b/dlls/ddraw/ddraw.spec index 75750910e4..0cd1d0f305 100644 --- a/dlls/ddraw/ddraw.spec +++ b/dlls/ddraw/ddraw.spec @@ -8,8 +8,8 @@ @ stdcall DirectDrawCreateEx(ptr ptr ptr ptr) @ stdcall DirectDrawEnumerateA(ptr ptr) @ stdcall DirectDrawEnumerateExA(ptr ptr long) -@ stdcall DirectDrawEnumerateExW(ptr ptr long) -@ stdcall DirectDrawEnumerateW(ptr ptr) +@ stub DirectDrawEnumerateExW +@ stub DirectDrawEnumerateW @ stdcall -private DllCanUnloadNow() @ stdcall -private DllGetClassObject(ptr ptr ptr) @ stdcall -private DllRegisterServer() diff --git a/dlls/ddraw/ddraw_hal.c b/dlls/ddraw/ddraw_hal.c deleted file mode 100644 index 59908a02d1..0000000000 --- a/dlls/ddraw/ddraw_hal.c +++ /dev/null @@ -1,578 +0,0 @@ -/* DirectDraw HAL driver - * - * Copyright 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "config.h" - -#include -#include -#include - -#include "wine/debug.h" -#include "windef.h" -#include "winbase.h" -#include "wingdi.h" -#include "ddraw.h" -#include "ddrawi.h" -#include "d3dhal.h" - -#include "ddraw_private.h" - -WINE_DEFAULT_DEBUG_CHANNEL(ddraw); - -static const IDirectDraw7Vtbl HAL_DirectDraw_VTable; - -static DDVERSIONDATA hal_version; -static DD32BITDRIVERDATA hal_driverdata; -static HINSTANCE hal_instance; - -static const DDDEVICEIDENTIFIER2 hal_device = -{ - "display", - "DirectDraw HAL", - { { 0x00010001, 0x00010001 } }, - 0, 0, 0, 0, - /* 40c1b248-9d7d-4a29-b7d7-4cd8109f3d5d */ - {0x40c1b248,0x9d7d,0x4a29,{0xd7,0xb7,0x4c,0xd8,0x10,0x9f,0x3d,0x5d}}, - 0 -}; - -HRESULT HAL_DirectDraw_Create(const GUID* pGUID, LPDIRECTDRAW7* pIface, - IUnknown* pUnkOuter, BOOL ex); -HRESULT HAL_DirectDraw_Initialize(IDirectDrawImpl*, const GUID*); - -static const ddraw_driver hal_driver = -{ - &hal_device, - 100, /* we prefer the HAL */ - HAL_DirectDraw_Create, - HAL_DirectDraw_Initialize -}; - -static DDHAL_CALLBACKS dd_cbs; -static DDRAWI_DIRECTDRAW_GBL dd_gbl; - -static D3DHAL_GLOBALDRIVERDATA d3d_hal_data; -static D3DHAL_D3DEXTENDEDCAPS d3d_hal_extcaps; -static D3DHAL_CALLBACKS d3d_hal_cbs1; -static D3DHAL_CALLBACKS2 d3d_hal_cbs2; - -/* in real windoze, these entry points are 16-bit, but we can work in 32-bit */ -static BOOL WINAPI set_hal_info(LPDDHALINFO lpDDHalInfo, BOOL reset) -{ - dd_cbs.HALDD = *lpDDHalInfo->lpDDCallbacks; - dd_cbs.HALDDSurface = *lpDDHalInfo->lpDDSurfaceCallbacks; - dd_cbs.HALDDPalette = *lpDDHalInfo->lpDDPaletteCallbacks; - if (lpDDHalInfo->lpDDExeBufCallbacks) - dd_cbs.HALDDExeBuf = *lpDDHalInfo->lpDDExeBufCallbacks; - - dd_gbl.lpDDCBtmp = &dd_cbs; - - dd_gbl.ddCaps = lpDDHalInfo->ddCaps; - dd_gbl.dwMonitorFrequency = lpDDHalInfo->dwMonitorFrequency; - dd_gbl.vmiData = lpDDHalInfo->vmiData; - dd_gbl.dwModeIndex = lpDDHalInfo->dwModeIndex; - dd_gbl.dwNumFourCC = lpDDHalInfo->ddCaps.dwNumFourCCCodes; - dd_gbl.lpdwFourCC = lpDDHalInfo->lpdwFourCC; - dd_gbl.dwNumModes = lpDDHalInfo->dwNumModes; - dd_gbl.lpModeInfo = lpDDHalInfo->lpModeInfo; - /* FIXME: dwFlags */ - dd_gbl.dwPDevice = (DWORD)lpDDHalInfo->lpPDevice; - dd_gbl.hInstance = lpDDHalInfo->hInstance; - /* DirectX 2 */ - if (lpDDHalInfo->lpD3DGlobalDriverData) - memcpy(&d3d_hal_data, (LPVOID)lpDDHalInfo->lpD3DGlobalDriverData, sizeof(D3DDEVICEDESC_V1)); - else - memset(&d3d_hal_data, 0, sizeof(D3DDEVICEDESC_V1)); - dd_gbl.lpD3DGlobalDriverData = (ULONG_PTR)&d3d_hal_data; - - if (lpDDHalInfo->lpD3DHALCallbacks) - memcpy(&d3d_hal_cbs1, (LPVOID)lpDDHalInfo->lpD3DHALCallbacks, sizeof(D3DHAL_CALLBACKS)); - else - memset(&d3d_hal_cbs1, 0, sizeof(D3DHAL_CALLBACKS)); - dd_gbl.lpD3DHALCallbacks = (ULONG_PTR)&d3d_hal_cbs1; - - if (lpDDHalInfo->dwFlags & DDHALINFO_GETDRIVERINFOSET) { - DDHAL_GETDRIVERINFODATA data; - data.dwSize = sizeof(DDHAL_GETDRIVERINFODATA); - data.dwFlags = 0; /* ? */ - data.dwContext = hal_driverdata.dwContext; /* ? */ - - data.guidInfo = GUID_D3DExtendedCaps; - data.dwExpectedSize = sizeof(D3DHAL_D3DEXTENDEDCAPS); - data.lpvData = &d3d_hal_extcaps; - data.dwActualSize = 0; - data.ddRVal = 0; - lpDDHalInfo->GetDriverInfo(&data); - d3d_hal_extcaps.dwSize = data.dwActualSize; - dd_gbl.lpD3DExtendedCaps = (ULONG_PTR)&d3d_hal_extcaps; - - data.guidInfo = GUID_D3DCallbacks2; - data.dwExpectedSize = sizeof(D3DHAL_CALLBACKS2); - data.lpvData = &d3d_hal_cbs2; - data.dwActualSize = 0; - data.ddRVal = 0; - lpDDHalInfo->GetDriverInfo(&data); - d3d_hal_cbs2.dwSize = data.dwActualSize; - dd_gbl.lpD3DHALCallbacks2 = (ULONG_PTR)&d3d_hal_cbs2; - } - - if( opengl_initialized && - (d3d_hal_data.hwCaps.dwFlags & D3DDD_WINE_OPENGL_DEVICE) ) { - /*GL_DirectDraw_Init(&dd_gbl);*/ - } - - return FALSE; -} - -static DDHALDDRAWFNS hal_funcs = { - sizeof(DDHALDDRAWFNS), - set_hal_info, - NULL, /* VidMemAlloc */ - NULL /* VidMemFree */ -}; - -/* Called from DllInit, which is synchronised so there are no threading - * concerns. */ -static BOOL initialize(void) -{ - DCICMD cmd; - INT ncmd = DCICOMMAND; - BOOL ret; - HDC dc = CreateDCA("DISPLAY", NULL, NULL, NULL); - INT ver = Escape(dc, QUERYESCSUPPORT, sizeof(ncmd), (LPVOID)&ncmd, NULL); - if (ver != DD_HAL_VERSION) { - DeleteDC(dc); - TRACE("DirectDraw HAL not available\n"); - return FALSE; - } - cmd.dwVersion = DD_VERSION; - cmd.dwReserved = 0; - - /* the DDNEWCALLBACKFNS is supposed to give the 16-bit driver entry points - * in ddraw16.dll, but since Wine doesn't have or use 16-bit display drivers, - * we'll just work in 32-bit, who'll notice... */ - cmd.dwCommand = DDNEWCALLBACKFNS; - cmd.dwParam1 = (DWORD)&hal_funcs; - ExtEscape(dc, DCICOMMAND, sizeof(cmd), (LPVOID)&cmd, 0, NULL); - - /* next, exchange version information */ - cmd.dwCommand = DDVERSIONINFO; - cmd.dwParam1 = DD_RUNTIME_VERSION; /* not sure what should *really* go here */ - ExtEscape(dc, DCICOMMAND, sizeof(cmd), (LPVOID)&cmd, sizeof(hal_version), (LPVOID)&hal_version); - - /* get 32-bit driver data (dll name and entry point) */ - cmd.dwCommand = DDGET32BITDRIVERNAME; - ExtEscape(dc, DCICOMMAND, sizeof(cmd), (LPVOID)&cmd, sizeof(hal_driverdata), (LPVOID)&hal_driverdata); - /* we're supposed to load the DLL in hal_driverdata.szName, then GetProcAddress - * the hal_driverdata.szEntryPoint, and call it with hal_driverdata.dwContext - * as a parameter... but since this is only more remains from the 16-bit world, - * we'll ignore it */ - - /* finally, initialize the driver object */ - cmd.dwCommand = DDCREATEDRIVEROBJECT; - ret = ExtEscape(dc, DCICOMMAND, sizeof(cmd), (LPVOID)&cmd, sizeof(hal_instance), (LPVOID)&hal_instance); - if (ret) { - /* the driver should have called our set_hal_info now */ - if (!dd_gbl.lpDDCBtmp) ret = FALSE; - } - - /* init done */ - DeleteDC(dc); - - TRACE("%s DirectDraw HAL\n", ret ? "enabling" : "disabling"); - - return ret; -} - -static void cleanup(void) -{ - DDHAL_DESTROYDRIVERDATA data; - - if (!dd_cbs.HALDD.DestroyDriver) return; - - data.lpDD = NULL; - data.ddRVal = 0; - data.DestroyDriver = dd_cbs.HALDD.DestroyDriver; - data.DestroyDriver(&data); -} - -static DWORD choose_mode(DWORD dwWidth, DWORD dwHeight, DWORD dwBPP, - DWORD dwRefreshRate, DWORD dwFlags) -{ - int best = -1; - unsigned int i; - - if (!dd_gbl.dwNumModes) return 0; - -/* let's support HALs that cannot switch depths (XVidMode), - * these should return dwBPP == 0 for all their resolutions */ -#define BPP_MATCH(dd, bpp) ((!(dd)) || ((dd) == bpp)) - -/* FIXME: we should try to match the refresh rate too */ - - /* Choose the smallest mode that is large enough. */ - for (i=0; i < dd_gbl.dwNumModes; i++) - { - if (dd_gbl.lpModeInfo[i].dwWidth >= dwWidth && - dd_gbl.lpModeInfo[i].dwHeight >= dwHeight && - BPP_MATCH(dd_gbl.lpModeInfo[i].dwBPP, dwBPP)) - { - if (best == -1) best = i; - else - { - if (dd_gbl.lpModeInfo[i].dwWidth < dd_gbl.lpModeInfo[best].dwWidth || - dd_gbl.lpModeInfo[i].dwHeight < dd_gbl.lpModeInfo[best].dwHeight) - best = i; - } - } - } - - if (best == -1) - { - TRACE("all modes too small\n"); - /* ok, let's use the largest */ - - for (i=0; i < dd_gbl.dwNumModes; i++) - { - if (BPP_MATCH(dd_gbl.lpModeInfo[i].dwBPP, dwBPP)) - { - if (best == -1) best = i; - else - { - if (dd_gbl.lpModeInfo[i].dwWidth > dd_gbl.lpModeInfo[best].dwWidth || - dd_gbl.lpModeInfo[i].dwHeight > dd_gbl.lpModeInfo[best].dwHeight) - best = i; - } - } - } - } -#undef BPP_MATCH - - if (best == -1) - { - ERR("requested color depth (%ld) not available, try reconfiguring X server\n", dwBPP); - return dd_gbl.dwModeIndex; - } - - TRACE("using mode %d\n", best); - - return best; -} - -static HRESULT set_mode(IDirectDrawImpl *This, DWORD dwMode) -{ - HRESULT hr = DD_OK; - - if (dwMode != dd_gbl.dwModeIndex) - { - DDHAL_SETMODEDATA data; - data.lpDD = &dd_gbl; - data.dwModeIndex = dwMode; - data.ddRVal = 0; - data.SetMode = dd_cbs.HALDD.SetMode; - data.inexcl = 0; - data.useRefreshRate = FALSE; - if (data.SetMode) - data.SetMode(&data); - hr = data.ddRVal; - if (SUCCEEDED(hr)) - dd_gbl.dwModeIndex = dwMode; - } - return hr; -} - -static HRESULT set_exclusive_mode(IDirectDrawImpl *This, DWORD dwEnterExcl) -{ - DDHAL_SETEXCLUSIVEMODEDATA data; - - data.lpDD = &dd_gbl; - data.dwEnterExcl = dwEnterExcl; - data.dwReserved = 0; - data.ddRVal = 0; - data.SetExclusiveMode = dd_cbs.HALDD.SetExclusiveMode; - if (data.SetExclusiveMode) - data.SetExclusiveMode(&data); - return data.ddRVal; -} - -BOOL DDRAW_HAL_Init(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv) -{ - if (fdwReason == DLL_PROCESS_ATTACH) - { - if (initialize()) - DDRAW_register_driver(&hal_driver); - } - else if (fdwReason == DLL_PROCESS_DETACH) - { - cleanup(); - } - - return TRUE; -} - -/* Not called from the vtable. */ -HRESULT HAL_DirectDraw_Construct(IDirectDrawImpl *This, BOOL ex) -{ - HRESULT hr; - - TRACE("(%p,%d)\n", This, ex); - - hr = User_DirectDraw_Construct(This, ex); - if (FAILED(hr)) return hr; - - This->local.lpGbl = &dd_gbl; - - This->final_release = HAL_DirectDraw_final_release; - This->set_exclusive_mode = set_exclusive_mode; - - This->create_palette = HAL_DirectDrawPalette_Create; - - This->create_primary = HAL_DirectDraw_create_primary; - This->create_backbuffer = HAL_DirectDraw_create_backbuffer; - This->create_texture = HAL_DirectDraw_create_texture; - - ICOM_INIT_INTERFACE(This, IDirectDraw7, HAL_DirectDraw_VTable); - - /* merge HAL caps */ - This->caps.dwCaps |= dd_gbl.ddCaps.dwCaps; - This->caps.dwCaps2 |= dd_gbl.ddCaps.dwCaps2; - This->caps.dwCKeyCaps |= dd_gbl.ddCaps.dwCKeyCaps; - This->caps.dwFXCaps |= dd_gbl.ddCaps.dwFXCaps; - This->caps.dwPalCaps |= dd_gbl.ddCaps.dwPalCaps; - /* FIXME: merge more caps */ - This->caps.ddsCaps.dwCaps |= dd_gbl.ddCaps.ddsCaps.dwCaps; - This->caps.ddsCaps.dwCaps2 |= dd_gbl.ddsCapsMore.dwCaps2; - This->caps.ddsCaps.dwCaps3 |= dd_gbl.ddsCapsMore.dwCaps3; - This->caps.ddsCaps.dwCaps4 |= dd_gbl.ddsCapsMore.dwCaps4; - This->caps.ddsOldCaps.dwCaps = This->caps.ddsCaps.dwCaps; - - return S_OK; -} - -/* This function is called from DirectDrawCreate(Ex) on the most-derived - * class to start construction. - * Not called from the vtable. */ -HRESULT HAL_DirectDraw_Create(const GUID* pGUID, LPDIRECTDRAW7* pIface, - IUnknown* pUnkOuter, BOOL ex) -{ - HRESULT hr; - IDirectDrawImpl* This; - - TRACE("\n"); - - assert(pUnkOuter == NULL); - - This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof(IDirectDrawImpl) - + sizeof(HAL_DirectDrawImpl)); - if (This == NULL) return E_OUTOFMEMORY; - - /* Note that this relation does *not* hold true if the DD object was - * CoCreateInstanced then Initialized. */ - This->private = (HAL_DirectDrawImpl *)(This+1); - - /* Initialize the DDCAPS structure */ - This->caps.dwSize = sizeof(This->caps); - - hr = HAL_DirectDraw_Construct(This, ex); - if (FAILED(hr)) - HeapFree(GetProcessHeap(), 0, This); - else - *pIface = ICOM_INTERFACE(This, IDirectDraw7); - - return hr; -} - -/* This function is called from Uninit_DirectDraw_Initialize on the - * most-derived-class to start initialization. - * Not called from the vtable. */ -HRESULT HAL_DirectDraw_Initialize(IDirectDrawImpl *This, const GUID* guid) -{ - HRESULT hr; - - TRACE("\n"); - - This->private = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof(HAL_DirectDrawImpl)); - if (This->private == NULL) return E_OUTOFMEMORY; - - /* Initialize the DDCAPS structure */ - This->caps.dwSize = sizeof(This->caps); - - hr = HAL_DirectDraw_Construct(This, TRUE); /* XXX ex? */ - if (FAILED(hr)) - { - HeapFree(GetProcessHeap(), 0, This->private); - return hr; - } - - return DD_OK; -} - -/* Called from an internal function pointer. */ -void HAL_DirectDraw_final_release(IDirectDrawImpl *This) -{ - if (dd_gbl.dwFlags & DDRAWI_MODECHANGED) set_mode(This, dd_gbl.dwModeIndexOrig); - User_DirectDraw_final_release(This); -} - -HRESULT HAL_DirectDraw_create_primary(IDirectDrawImpl* This, - const DDSURFACEDESC2* pDDSD, - LPDIRECTDRAWSURFACE7* ppSurf, - IUnknown* pUnkOuter) -{ - if (This->cooperative_level & DDSCL_EXCLUSIVE) - return HAL_DirectDrawSurface_Create(This, pDDSD, ppSurf, pUnkOuter); - else - return User_DirectDrawSurface_Create(This, pDDSD, ppSurf, pUnkOuter); -} - -HRESULT HAL_DirectDraw_create_backbuffer(IDirectDrawImpl* This, - const DDSURFACEDESC2* pDDSD, - LPDIRECTDRAWSURFACE7* ppSurf, - IUnknown* pUnkOuter, - IDirectDrawSurfaceImpl* primary) -{ - if (This->cooperative_level & DDSCL_EXCLUSIVE) - return HAL_DirectDrawSurface_Create(This, pDDSD, ppSurf, pUnkOuter); - else - return User_DirectDrawSurface_Create(This, pDDSD, ppSurf, pUnkOuter); -} - -HRESULT HAL_DirectDraw_create_texture(IDirectDrawImpl* This, - const DDSURFACEDESC2* pDDSD, - LPDIRECTDRAWSURFACE7* ppSurf, - LPUNKNOWN pOuter, - DWORD dwMipMapLevel) -{ - return HAL_DirectDrawSurface_Create(This, pDDSD, ppSurf, pOuter); -} - -HRESULT WINAPI -HAL_DirectDraw_GetDeviceIdentifier(LPDIRECTDRAW7 iface, - LPDDDEVICEIDENTIFIER2 pDDDI, - DWORD dwFlags) -{ - *pDDDI = hal_device; - return DD_OK; -} - -HRESULT WINAPI -HAL_DirectDraw_RestoreDisplayMode(LPDIRECTDRAW7 iface) -{ - IDirectDrawImpl *This = (IDirectDrawImpl *)iface; - HRESULT hr; - - TRACE("(%p)\n", iface); - - if (!(dd_gbl.dwFlags & DDRAWI_MODECHANGED)) return DD_OK; - - hr = Main_DirectDraw_RestoreDisplayMode(iface); - if (SUCCEEDED(hr)) { - hr = set_mode(This, dd_gbl.dwModeIndexOrig); - if (SUCCEEDED(hr)) dd_gbl.dwFlags &= ~DDRAWI_MODECHANGED; - } - - return hr; -} - -HRESULT WINAPI -HAL_DirectDraw_SetDisplayMode(LPDIRECTDRAW7 iface, DWORD dwWidth, - DWORD dwHeight, DWORD dwBPP, - DWORD dwRefreshRate, DWORD dwFlags) -{ - IDirectDrawImpl *This = (IDirectDrawImpl *)iface; - - HRESULT hr; - - TRACE("(%p)->(%ldx%ldx%ld,%ld Hz,%08lx)\n",This,dwWidth,dwHeight,dwBPP,dwRefreshRate,dwFlags); - hr = User_DirectDraw_SetDisplayMode(iface, dwWidth, dwHeight, dwBPP, - dwRefreshRate, dwFlags); - - if (SUCCEEDED(hr)) { - if (!(dd_gbl.dwFlags & DDRAWI_MODECHANGED)) dd_gbl.dwModeIndexOrig = dd_gbl.dwModeIndex; - hr = set_mode(This, choose_mode(dwWidth, dwHeight, dwBPP, dwRefreshRate, dwFlags)); - if (SUCCEEDED(hr)) dd_gbl.dwFlags |= DDRAWI_MODECHANGED; - } - - return hr; -} - -HRESULT WINAPI -HAL_DirectDraw_GetFourCCCodes(LPDIRECTDRAW7 iface, LPDWORD pNumCodes, - LPDWORD pCodes) -{ - unsigned int i; - IDirectDrawImpl *This = (IDirectDrawImpl *)iface; - if (*pNumCodes) - *pNumCodes=dd_gbl.dwNumFourCC; - if (pCodes && dd_gbl.dwNumFourCC) - memcpy(pCodes,dd_gbl.lpdwFourCC,sizeof(pCodes[0])*dd_gbl.dwNumFourCC); - FIXME("(%p,%p,%p)\n",This,pNumCodes,pCodes); - if (dd_gbl.dwNumFourCC) { - if (pCodes && FIXME_ON(ddraw)) { - FIXME("returning: "); - for (i=0;i -#include -#include - -#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 "opengl_private.h" /* To have the D3D creation function */ - -WINE_DEFAULT_DEBUG_CHANNEL(ddraw); - -extern const IDirectDrawVtbl DDRAW_IDirectDraw_VTable; -extern const IDirectDraw2Vtbl DDRAW_IDirectDraw2_VTable; -extern const IDirectDraw4Vtbl 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 = 64 * 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) { - IDirectDrawImpl *This = (IDirectDrawImpl *)iface; - ULONG ref = InterlockedIncrement(&This->ref); - - TRACE("(%p)->() incrementing from %lu.\n", This, ref -1); - - return ref; -} - -ULONG WINAPI Main_DirectDraw_Release(LPDIRECTDRAW7 iface) { - IDirectDrawImpl *This = (IDirectDrawImpl *)iface; - ULONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p)->() decrementing from %lu.\n", This, ref +1); - - 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 -) { - IDirectDrawImpl *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) -{ - IDirectDrawImpl *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 WINAPI -Main_DirectDraw_CreatePalette(LPDIRECTDRAW7 iface, DWORD dwFlags, - LPPALETTEENTRY palent, - LPDIRECTDRAWPALETTE* ppPalette, - LPUNKNOWN pUnknown) -{ - IDirectDrawImpl *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; - } -} - -HRESULT -Main_create_offscreen(IDirectDrawImpl* This, const DDSURFACEDESC2* pDDSD, - LPDIRECTDRAWSURFACE7* ppSurf, LPUNKNOWN pOuter) -{ - assert(pOuter == NULL); - - return DIB_DirectDrawSurface_Create(This, pDDSD, ppSurf, pOuter); -} - -HRESULT -Main_create_texture(IDirectDrawImpl* This, const DDSURFACEDESC2* pDDSD, - LPDIRECTDRAWSURFACE7* ppSurf, LPUNKNOWN pOuter, - DWORD dwMipMapLevel) -{ - assert(pOuter == NULL); - - return DIB_DirectDrawSurface_Create(This, pDDSD, ppSurf, pOuter); -} - -HRESULT -Main_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 HRESULT -create_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; - } - -#ifdef HAVE_OPENGL - /* We support for now only DXT1, DXT3 & DXT5 compressed texture formats... */ - if ((ddsd.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC) && - (ddsd.u4.ddpfPixelFormat.dwFourCC != MAKE_FOURCC('D','X','T','1')) && - (ddsd.u4.ddpfPixelFormat.dwFourCC != MAKE_FOURCC('D','X','T','3')) && - (ddsd.u4.ddpfPixelFormat.dwFourCC != MAKE_FOURCC('D','X','T','5')) ) - { - return DDERR_INVALIDPIXELFORMAT; - } - - /* Check if we can really support DXT1, DXT3 & DXT5 */ - if ((ddsd.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC) && - !GL_extensions.s3tc_compressed_texture && !s3tc_initialized) { - static BOOLEAN user_warned = 0; - if (user_warned == 0) { - ERR("Trying to create DXT1, DXT3 or DXT5 texture which is not supported by the video card!!!\n"); - ERR("However there is a library libtxc_dxtn.so that can be used to do the software decompression...\n"); - user_warned = 1; - } - return DDERR_INVALIDPIXELFORMAT; - } -#else - if (ddsd.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC) - { - return DDERR_INVALIDPIXELFORMAT; - } -#endif - - if ((ddsd.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC) && !(ddsd.dwFlags & DDSD_LINEARSIZE)) - { - int size = 0; - int width = ddsd.dwWidth; - int height = ddsd.dwHeight; - switch(ddsd.u4.ddpfPixelFormat.dwFourCC) { - case MAKE_FOURCC('D','X','T','1'): size = ((width+3)&~3) * ((height+3)&~3) / 16 * 8; break; - case MAKE_FOURCC('D','X','T','3'): size = ((width+3)&~3) * ((height+3)&~3) / 16 * 16; break; - case MAKE_FOURCC('D','X','T','5'): size = ((width+3)&~3) * ((height+3)&~3) / 16 * 16; break; - default: FIXME("FOURCC not supported\n"); break; - } - ddsd.u1.dwLinearSize = size; - ddsd.dwFlags |= DDSD_LINEARSIZE; - } else if (!(ddsd.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC) && !(ddsd.dwFlags & DDSD_PITCH)) { - ddsd.u1.lPitch = DDRAW_width_bpp_to_pitch(ddsd.dwWidth, GET_BPP(ddsd)*8); - ddsd.dwFlags |= DDSD_PITCH; - } - - if((ddsd.ddsCaps.dwCaps & DDSCAPS_MIPMAP) && - !(ddsd.dwFlags & DDSD_MIPMAPCOUNT)) - { - if(ddsd.ddsCaps.dwCaps & DDSCAPS_COMPLEX) - { - /* Undocumented feature: if DDSCAPS_MIPMAP and DDSCAPS_COMPLEX are - * both set, but mipmap count isn't given, as many mipmap levels - * as necessary are created to get down to a size where either - * the width or the height of the texture is 1. - * - * This is needed by Anarchy Online. */ - DWORD min = ddsd.dwWidth < ddsd.dwHeight ? - ddsd.dwWidth : ddsd.dwHeight; - ddsd.u2.dwMipMapCount = 0; - while( min ) - { - ddsd.u2.dwMipMapCount++; - min >>= 1; - } - } - else - /* Create a single mipmap. */ - ddsd.u2.dwMipMapCount = 1; - - ddsd.dwFlags |= DDSD_MIPMAPCOUNT; - } - - ddsd.dwFlags |= 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)); - - /* Create attached mipmaps if required. */ - if (more_mipmaps(&ddsd)) - { - LPDIRECTDRAWSURFACE7 mipmap; - LPDIRECTDRAWSURFACE7 prev_mipmap; - DDSURFACEDESC2 mipmap_surface_desc; - - prev_mipmap = *ppSurf; - IDirectDrawSurface7_AddRef(prev_mipmap); - mipmap_surface_desc = ddsd; - mipmap_surface_desc.ddsCaps.dwCaps2 |= DDSCAPS2_MIPMAPSUBLEVEL; - - while (more_mipmaps(&mipmap_surface_desc)) - { - IDirectDrawSurfaceImpl *mipmap_impl; - - mipmap_level++; - mipmap_surface_desc.u2.dwMipMapCount--; - - if (mipmap_surface_desc.dwWidth > 1) - mipmap_surface_desc.dwWidth /= 2; - - if (mipmap_surface_desc.dwHeight > 1) - mipmap_surface_desc.dwHeight /= 2; - - if (mipmap_surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC) { - int size = 0; - int width = mipmap_surface_desc.dwWidth; - int height = mipmap_surface_desc.dwHeight; - switch(mipmap_surface_desc.u4.ddpfPixelFormat.dwFourCC) { - case MAKE_FOURCC('D','X','T','1'): size = ((width+3)&~3) * ((height+3)&~3) / 16 * 8; break; - case MAKE_FOURCC('D','X','T','3'): size = ((width+3)&~3) * ((height+3)&~3) / 16 * 16; break; - case MAKE_FOURCC('D','X','T','5'): size = ((width+3)&~3) * ((height+3)&~3) / 16 * 16; break; - default: FIXME("FOURCC not supported\n"); break; - } - mipmap_surface_desc.u1.dwLinearSize = size; - } else { - ddsd.u1.lPitch = DDRAW_width_bpp_to_pitch(ddsd.dwWidth, GET_BPP(ddsd)*8); - mipmap_surface_desc.u1.lPitch - = DDRAW_width_bpp_to_pitch(mipmap_surface_desc.dwWidth, - GET_BPP(ddsd)*8); - } - - hr = This->create_texture(This, &mipmap_surface_desc, &mipmap, - pUnkOuter, mipmap_level); - if (FAILED(hr)) - { - IDirectDrawSurface7_Release(prev_mipmap); - IDirectDrawSurface7_Release(*ppSurf); - return hr; - } - - /* This is needed for delayed mipmap creation */ - mipmap_impl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, mipmap); - mipmap_impl->mip_main = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, *ppSurf); - mipmap_impl->mipmap_level = mipmap_level; - - if (This->d3d_private) This->d3d_create_texture(This, ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, mipmap), TRUE, - ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, *ppSurf)); - - IDirectDrawSurface7_AddAttachedSurface(prev_mipmap, mipmap); - IDirectDrawSurface7_Release(prev_mipmap); - prev_mipmap = mipmap; - } - - IDirectDrawSurface7_Release(prev_mipmap); - } - - return DD_OK; -} - -/* Creates a primary surface and any indicated backbuffers. */ -static HRESULT -create_primary(IDirectDrawImpl* This, LPDDSURFACEDESC2 pDDSD, - LPDIRECTDRAWSURFACE7* ppSurf, LPUNKNOWN pUnkOuter) -{ - DDSURFACEDESC2 ddsd; - HRESULT hr; - - assert(pUnkOuter == NULL); - - if (This->primary_surface != NULL) - return DDERR_PRIMARYSURFACEALREADYEXISTS; - - /* as documented (what about pitch?) */ - if (pDDSD->dwFlags & (DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT)) - return DDERR_INVALIDPARAMS; - - ddsd.dwSize = sizeof(ddsd); - DD_STRUCT_COPY_BYSIZE((&ddsd),pDDSD); - ddsd.dwFlags |= DDSD_HEIGHT | DDSD_WIDTH | DDSD_PITCH | DDSD_PIXELFORMAT; - ddsd.dwHeight = This->height; - ddsd.dwWidth = This->width; - ddsd.u1.lPitch = This->pitch; - ddsd.u4.ddpfPixelFormat = This->pixelformat; - ddsd.ddsCaps.dwCaps |= DDSCAPS_LOCALVIDMEM | DDSCAPS_VIDEOMEMORY - | DDSCAPS_VISIBLE | DDSCAPS_FRONTBUFFER; - - if ((ddsd.dwFlags & DDSD_BACKBUFFERCOUNT) && ddsd.dwBackBufferCount > 0) - ddsd.ddsCaps.dwCaps |= DDSCAPS_FLIP; - - hr = This->create_primary(This, &ddsd, ppSurf, pUnkOuter); - if (FAILED(hr)) return hr; - - if (ddsd.dwFlags & DDSD_BACKBUFFERCOUNT) - { - IDirectDrawSurfaceImpl* primary; - LPDIRECTDRAWSURFACE7 pPrev; - DWORD i; - - ddsd.dwFlags &= ~DDSD_BACKBUFFERCOUNT; - ddsd.ddsCaps.dwCaps &= ~(DDSCAPS_VISIBLE | DDSCAPS_PRIMARYSURFACE - | DDSCAPS_BACKBUFFER | DDSCAPS_FRONTBUFFER); - - primary = ICOM_OBJECT(IDirectDrawSurfaceImpl,IDirectDrawSurface7, - *ppSurf); - pPrev = *ppSurf; - IDirectDrawSurface7_AddRef(pPrev); - - for (i=0; i < ddsd.dwBackBufferCount; i++) - { - LPDIRECTDRAWSURFACE7 pBack; - - if (i == 0) - ddsd.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER; - else - ddsd.ddsCaps.dwCaps &= ~DDSCAPS_BACKBUFFER; - - hr = This->create_backbuffer(This, &ddsd, &pBack, pUnkOuter, - primary); - - if (FAILED(hr)) - { - IDirectDraw7_Release(pPrev); - IDirectDraw7_Release(*ppSurf); - return hr; - } - - IDirectDrawSurface7_AddAttachedSurface(pPrev, pBack); - IDirectDrawSurface7_Release(pPrev); - pPrev = pBack; - } - - IDirectDrawSurface7_Release(pPrev); - } - - This->primary_surface = (IDirectDrawSurfaceImpl *)*ppSurf; - - return DD_OK; -} - -static HRESULT -create_offscreen(IDirectDrawImpl* This, LPDDSURFACEDESC2 pDDSD, - LPDIRECTDRAWSURFACE7* ppSurf, LPUNKNOWN pUnkOuter) -{ - DDSURFACEDESC2 ddsd; - HRESULT hr; - - /* 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; - } - - if (!(ddsd.dwFlags & DDSD_PITCH)) - { - ddsd.u1.lPitch = DDRAW_width_bpp_to_pitch(ddsd.dwWidth, - GET_BPP(ddsd)*8); - } - - ddsd.dwFlags |= DDSD_PITCH | DDSD_PIXELFORMAT; - - hr = This->create_offscreen(This, &ddsd, ppSurf, pUnkOuter); - if (FAILED(hr)) return hr; - - return hr; -} - -HRESULT WINAPI -Main_DirectDraw_CreateSurface(LPDIRECTDRAW7 iface, LPDDSURFACEDESC2 pDDSD, - LPDIRECTDRAWSURFACE7 *ppSurf, - IUnknown *pUnkOuter) -{ - HRESULT hr; - IDirectDrawImpl *This = (IDirectDrawImpl *)iface; - - TRACE("(%p)->(%p,%p,%p)\n",This,pDDSD,ppSurf,pUnkOuter); - if (TRACE_ON(ddraw)) { - TRACE("Requesting surface desc :\n"); - DDRAW_dump_surface_desc(pDDSD); - } - - if (pUnkOuter != NULL) { - FIXME("outer != NULL?\n"); - return CLASS_E_NOAGGREGATION; /* unchecked */ - } - - if (!(pDDSD->dwFlags & DDSD_CAPS)) { - /* DVIDEO.DLL does forget the DDSD_CAPS flag ... *sigh* */ - pDDSD->dwFlags |= DDSD_CAPS; - } - if (pDDSD->ddsCaps.dwCaps == 0) { - /* This has been checked on real Windows */ - pDDSD->ddsCaps.dwCaps = DDSCAPS_LOCALVIDMEM | DDSCAPS_VIDEOMEMORY; - } - - if (pDDSD->ddsCaps.dwCaps & DDSCAPS_ALLOCONLOAD) { - /* If the surface is of the 'alloconload' type, ignore the LPSURFACE field */ - pDDSD->dwFlags &= ~DDSD_LPSURFACE; - } - - if ((pDDSD->dwFlags & DDSD_LPSURFACE) && (pDDSD->lpSurface == NULL)) { - /* Frank Herbert's Dune specifies a null pointer for the surface, ignore the LPSURFACE field */ - WARN("Null surface pointer specified, ignore it!\n"); - pDDSD->dwFlags &= ~DDSD_LPSURFACE; - } - - if (ppSurf == NULL) { - FIXME("You want to get back a surface? Don't give NULL ptrs!\n"); - return E_POINTER; /* unchecked */ - } - - if (pDDSD->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) - { - /* create primary surface & backbuffers */ - hr = create_primary(This, pDDSD, ppSurf, pUnkOuter); - } - else if (pDDSD->ddsCaps.dwCaps & DDSCAPS_BACKBUFFER) - { - /* create backbuffer surface */ - hr = This->create_backbuffer(This, pDDSD, ppSurf, pUnkOuter, NULL); - } - else if (pDDSD->ddsCaps.dwCaps & DDSCAPS_TEXTURE) - { - /* create texture */ - hr = create_texture(This, pDDSD, ppSurf, pUnkOuter); - } - else if ( (pDDSD->ddsCaps.dwCaps & DDSCAPS_ZBUFFER) && - !(pDDSD->ddsCaps.dwCaps & DDSCAPS_OFFSCREENPLAIN)) /* Support DDSCAPS_SYSTEMMEMORY */ - { - /* create z-buffer */ - hr = This->create_zbuffer(This, pDDSD, ppSurf, pUnkOuter); - } - else if ((pDDSD->ddsCaps.dwCaps & DDSCAPS_OFFSCREENPLAIN) || - (pDDSD->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY)) /* No difference in Wine right now */ - { - /* create offscreenplain surface */ - hr = create_offscreen(This, pDDSD, ppSurf, pUnkOuter); - } - else - { - /* Otherwise, assume offscreenplain surface */ - TRACE("App didn't request a valid surface type - assuming offscreenplain\n"); - hr = create_offscreen(This, pDDSD, ppSurf, pUnkOuter); - } - - if (FAILED(hr)) { - FIXME("failed surface creation with code 0x%08lx\n",hr); - return hr; - } - - return DD_OK; -} - -HRESULT WINAPI -Main_DirectDraw_DuplicateSurface(LPDIRECTDRAW7 iface, LPDIRECTDRAWSURFACE7 src, - LPDIRECTDRAWSURFACE7* dst) -{ - IDirectDrawImpl *This = (IDirectDrawImpl *)iface; - - IDirectDrawSurfaceImpl *pSrc = ICOM_OBJECT(IDirectDrawSurfaceImpl, - IDirectDrawSurface7, src); - - TRACE("(%p)->(%p,%p)\n",This,src,dst); - - return pSrc->duplicate_surface(pSrc, dst); -} - -/* EnumDisplayModes */ - -BOOL Main_DirectDraw_DDPIXELFORMAT_Match(const DDPIXELFORMAT *requested, - const DDPIXELFORMAT *provided) -{ - /* Some flags must be present in both or neither for a match. */ - static const DWORD must_match = DDPF_PALETTEINDEXED1 | DDPF_PALETTEINDEXED2 - | DDPF_PALETTEINDEXED4 | DDPF_PALETTEINDEXED8 | DDPF_FOURCC - | DDPF_ZBUFFER | DDPF_STENCILBUFFER; - - if ((requested->dwFlags & provided->dwFlags) != requested->dwFlags) - return FALSE; - - if ((requested->dwFlags & must_match) != (provided->dwFlags & must_match)) - return FALSE; - - if (requested->dwFlags & DDPF_FOURCC) - if (requested->dwFourCC != provided->dwFourCC) - return FALSE; - - if (requested->dwFlags & (DDPF_RGB|DDPF_YUV|DDPF_ZBUFFER|DDPF_ALPHA - |DDPF_LUMINANCE|DDPF_BUMPDUDV)) - if (requested->u1.dwRGBBitCount != provided->u1.dwRGBBitCount) - return FALSE; - - if (requested->dwFlags & (DDPF_RGB|DDPF_YUV|DDPF_STENCILBUFFER - |DDPF_LUMINANCE|DDPF_BUMPDUDV)) - if (requested->u2.dwRBitMask != provided->u2.dwRBitMask) - return FALSE; - - if (requested->dwFlags & (DDPF_RGB|DDPF_YUV|DDPF_ZBUFFER|DDPF_BUMPDUDV)) - if (requested->u3.dwGBitMask != provided->u3.dwGBitMask) - return FALSE; - - /* I could be wrong about the bumpmapping. MSDN docs are vague. */ - if (requested->dwFlags & (DDPF_RGB|DDPF_YUV|DDPF_STENCILBUFFER - |DDPF_BUMPDUDV)) - if (requested->u4.dwBBitMask != provided->u4.dwBBitMask) - return FALSE; - - if (requested->dwFlags & (DDPF_ALPHAPIXELS|DDPF_ZPIXELS)) - if (requested->u5.dwRGBAlphaBitMask != provided->u5.dwRGBAlphaBitMask) - return FALSE; - - return TRUE; -} - -BOOL Main_DirectDraw_DDSD_Match(const DDSURFACEDESC2* requested, - const DDSURFACEDESC2* provided) -{ - struct compare_info - { - DWORD flag; - ptrdiff_t offset; - size_t size; - }; - -#define CMP(FLAG, FIELD) \ - { DDSD_##FLAG, offsetof(DDSURFACEDESC2, FIELD), \ - sizeof(((DDSURFACEDESC2 *)(NULL))->FIELD) } - - static const struct compare_info compare[] = { - CMP(ALPHABITDEPTH, dwAlphaBitDepth), - CMP(BACKBUFFERCOUNT, dwBackBufferCount), - CMP(CAPS, ddsCaps), - CMP(CKDESTBLT, ddckCKDestBlt), - CMP(CKDESTOVERLAY, u3.ddckCKDestOverlay), - CMP(CKSRCBLT, ddckCKSrcBlt), - CMP(CKSRCOVERLAY, ddckCKSrcOverlay), - CMP(HEIGHT, dwHeight), - CMP(LINEARSIZE, u1.dwLinearSize), - CMP(LPSURFACE, lpSurface), - CMP(MIPMAPCOUNT, u2.dwMipMapCount), - CMP(PITCH, u1.lPitch), - /* PIXELFORMAT: manual */ - CMP(REFRESHRATE, u2.dwRefreshRate), - CMP(TEXTURESTAGE, dwTextureStage), - CMP(WIDTH, dwWidth), - /* ZBUFFERBITDEPTH: "obsolete" */ - }; - -#undef CMP - - unsigned int i; - - if ((requested->dwFlags & provided->dwFlags) != requested->dwFlags) - return FALSE; - - for (i=0; i < sizeof(compare)/sizeof(compare[0]); i++) - { - if (requested->dwFlags & compare[i].flag - && memcmp((const char *)provided + compare[i].offset, - (const char *)requested + compare[i].offset, - compare[i].size) != 0) - return FALSE; - } - - if (requested->dwFlags & DDSD_PIXELFORMAT) - { - if (!Main_DirectDraw_DDPIXELFORMAT_Match(&requested->u4.ddpfPixelFormat, - &provided->u4.ddpfPixelFormat)) - return FALSE; - } - - return TRUE; -} - -#define DDENUMSURFACES_SEARCHTYPE (DDENUMSURFACES_CANBECREATED|DDENUMSURFACES_DOESEXIST) -#define DDENUMSURFACES_MATCHTYPE (DDENUMSURFACES_ALL|DDENUMSURFACES_MATCH|DDENUMSURFACES_NOMATCH) - -/* This should be extended so that it can be used by - * IDirectDrawSurface7::EnumAttachedSurfaces. */ -HRESULT -Main_DirectDraw_EnumExistingSurfaces(IDirectDrawImpl *This, DWORD dwFlags, - LPDDSURFACEDESC2 lpDDSD2, LPVOID context, - LPDDENUMSURFACESCALLBACK7 callback) -{ - IDirectDrawSurfaceImpl *surf; - BOOL all, nomatch; - - /* A NULL lpDDSD2 is permitted if we are enumerating all surfaces anyway */ - if (lpDDSD2 == NULL && !(dwFlags & DDENUMSURFACES_ALL)) - return DDERR_INVALIDPARAMS; - - all = dwFlags & DDENUMSURFACES_ALL; - nomatch = dwFlags & DDENUMSURFACES_NOMATCH; - - for (surf = This->surfaces; surf != NULL; surf = surf->next_ddraw) - { - if (all - || (nomatch != Main_DirectDraw_DDSD_Match(lpDDSD2, - &surf->surface_desc))) - { - LPDIRECTDRAWSURFACE7 isurf = ICOM_INTERFACE(surf, IDirectDrawSurface7); - DDSURFACEDESC2 desc; - - if (TRACE_ON(ddraw)) { - TRACE(" => enumerating surface %p (priv. %p) with description:\n", isurf, surf); - DDRAW_dump_surface_desc(&surf->surface_desc); - } - - IDirectDrawSurface7_AddRef(isurf); - - desc = surf->surface_desc; - if (callback(isurf, &desc, context) == DDENUMRET_CANCEL) - break; - } - } - TRACE(" end of enumeration.\n"); - - return DD_OK; -} - -/* I really don't understand how this is supposed to work. - * We only consider dwHeight, dwWidth and ddpfPixelFormat.dwFlags. */ -HRESULT -Main_DirectDraw_EnumCreateableSurfaces(IDirectDrawImpl *This, DWORD dwFlags, - LPDDSURFACEDESC2 lpDDSD2, - LPVOID context, - LPDDENUMSURFACESCALLBACK7 callback) -{ - FIXME("This isn't going to work.\n"); - - if ((dwFlags & DDENUMSURFACES_MATCHTYPE) != DDENUMSURFACES_MATCH) - return DDERR_INVALIDPARAMS; - - /* TODO: implement this. - * Does this work before SCL is called? - * Does it only consider off-screen surfaces? - */ - - return E_FAIL; -} - -/* For unsigned x. 0 is not a power of 2. */ -#define IS_POW_2(x) (((x) & ((x) - 1)) == 0) - -HRESULT WINAPI -Main_DirectDraw_EnumSurfaces(LPDIRECTDRAW7 iface, DWORD dwFlags, - LPDDSURFACEDESC2 lpDDSD2, LPVOID context, - LPDDENUMSURFACESCALLBACK7 callback) -{ - IDirectDrawImpl *This = (IDirectDrawImpl *)iface; - TRACE("(%p)->(0x%lx, %p, %p, %p)\n", iface, dwFlags, lpDDSD2, context, - callback); - if (TRACE_ON(ddraw)) { - TRACE(" flags: "); DDRAW_dump_DDENUMSURFACES(dwFlags); - } - - if (callback == NULL) - return DDERR_INVALIDPARAMS; - - if (dwFlags & ~(DDENUMSURFACES_SEARCHTYPE|DDENUMSURFACES_MATCHTYPE)) - return DDERR_INVALIDPARAMS; - - if (!IS_POW_2(dwFlags & DDENUMSURFACES_SEARCHTYPE) - || !IS_POW_2(dwFlags & DDENUMSURFACES_MATCHTYPE)) - return DDERR_INVALIDPARAMS; - - if (dwFlags & DDENUMSURFACES_DOESEXIST) - { - return Main_DirectDraw_EnumExistingSurfaces(This, dwFlags, lpDDSD2, - context, callback); - } - else - { - return Main_DirectDraw_EnumCreateableSurfaces(This, dwFlags, lpDDSD2, - context, callback); - } -} - -HRESULT WINAPI -Main_DirectDraw_EvaluateMode(LPDIRECTDRAW7 iface,DWORD a,DWORD* b) -{ - IDirectDrawImpl *This = (IDirectDrawImpl *)iface; - FIXME("(%p)->() stub\n", This); - - return DD_OK; -} - -HRESULT WINAPI -Main_DirectDraw_FlipToGDISurface(LPDIRECTDRAW7 iface) -{ - IDirectDrawImpl *This = (IDirectDrawImpl *)iface; - TRACE("(%p)->()\n",This); - return DD_OK; -} - -HRESULT WINAPI -Main_DirectDraw_GetCaps(LPDIRECTDRAW7 iface, LPDDCAPS pDriverCaps, - LPDDCAPS pHELCaps) -{ - IDirectDrawImpl *This = (IDirectDrawImpl *)iface; - TRACE("(%p,%p,%p)\n",This,pDriverCaps,pHELCaps); - if (pDriverCaps != NULL) { - DD_STRUCT_COPY_BYSIZE(pDriverCaps,&This->caps); - if (TRACE_ON(ddraw)) { - TRACE("Driver Caps :\n"); - DDRAW_dump_DDCAPS(pDriverCaps); - } - } - if (pHELCaps != NULL) { - DD_STRUCT_COPY_BYSIZE(pHELCaps,&This->caps); - if (TRACE_ON(ddraw)) { - TRACE("HEL Caps :\n"); - DDRAW_dump_DDCAPS(pHELCaps); - } - } - return DD_OK; -} - -/* GetCaps */ -/* GetDeviceIdentifier */ -/* GetDIsplayMode */ - -HRESULT WINAPI -Main_DirectDraw_GetFourCCCodes(LPDIRECTDRAW7 iface, LPDWORD pNumCodes, - LPDWORD pCodes) -{ - IDirectDrawImpl *This = (IDirectDrawImpl *)iface; - if (*pNumCodes) { - *pNumCodes=0; - } - FIXME("(%p,%p,%p), stub\n",This,pNumCodes,pCodes); - return DD_OK; -} - -HRESULT WINAPI -Main_DirectDraw_GetGDISurface(LPDIRECTDRAW7 iface, - LPDIRECTDRAWSURFACE7 *lplpGDIDDSSurface) -{ - IDirectDrawImpl *This = (IDirectDrawImpl *)iface; - TRACE("(%p)->(%p)\n", This, lplpGDIDDSSurface); - TRACE("returning primary (%p)\n", This->primary_surface); - *lplpGDIDDSSurface = ICOM_INTERFACE(This->primary_surface, IDirectDrawSurface7); - if (*lplpGDIDDSSurface) - IDirectDrawSurface7_AddRef(*lplpGDIDDSSurface); - return DD_OK; -} - -HRESULT WINAPI -Main_DirectDraw_GetMonitorFrequency(LPDIRECTDRAW7 iface,LPDWORD freq) -{ - IDirectDrawImpl *This = (IDirectDrawImpl *)iface; - FIXME("(%p)->(%p) returns 60 Hz always\n",This,freq); - *freq = 60*100; /* 60 Hz */ - return DD_OK; -} - -HRESULT WINAPI -Main_DirectDraw_GetScanLine(LPDIRECTDRAW7 iface, LPDWORD lpdwScanLine) -{ - IDirectDrawImpl *This = (IDirectDrawImpl *)iface; - static BOOL hide; - - /* Since this method is called often, show the fixme only once */ - if (!hide) { - FIXME("(%p)->(%p) semi-stub\n", This, lpdwScanLine); - hide = TRUE; - } - - /* Fake the line sweeping of the monitor */ - /* FIXME: We should synchronize with a source to keep the refresh rate */ - *lpdwScanLine = This->cur_scanline++; - /* Assume 20 scan lines in the vertical blank */ - if (This->cur_scanline >= This->height + 20) - This->cur_scanline = 0; - - return DD_OK; -} - -HRESULT WINAPI -Main_DirectDraw_GetSurfaceFromDC(LPDIRECTDRAW7 iface, HDC hdc, - LPDIRECTDRAWSURFACE7 *lpDDS) -{ - IDirectDrawImpl *This = (IDirectDrawImpl *)iface; - FIXME("(%p)->(%p,%p)\n", This, hdc, lpDDS); - - return DD_OK; -} - -HRESULT WINAPI -Main_DirectDraw_GetVerticalBlankStatus(LPDIRECTDRAW7 iface, LPBOOL status) -{ - IDirectDrawImpl *This = (IDirectDrawImpl *)iface; - TRACE("(%p)->(%p)\n",This,status); - *status = This->fake_vblank; - This->fake_vblank = !This->fake_vblank; - return DD_OK; -} - -/* If we were not initialised then Uninit_Main_IDirectDraw7_Initialize would - * have been called instead. */ -HRESULT WINAPI -Main_DirectDraw_Initialize(LPDIRECTDRAW7 iface, LPGUID lpGuid) -{ - TRACE("(%p)->(%s)\n", iface, debugstr_guid(lpGuid)); - - return DDERR_ALREADYINITIALIZED; -} - -HRESULT WINAPI -Main_DirectDraw_RestoreAllSurfaces(LPDIRECTDRAW7 iface) -{ - IDirectDrawImpl *This = (IDirectDrawImpl *)iface; - IDirectDrawSurfaceImpl* surf; - - TRACE("(%p)->()\n", This); - - for (surf = This->surfaces; surf != NULL; surf = surf->next_ddraw) - IDirectDrawSurface7_Restore(ICOM_INTERFACE(surf, IDirectDrawSurface7)); - - return DD_OK; -} - -static void DDRAW_SubclassWindow(IDirectDrawImpl* This) -{ - /* Well we don't actually subclass the window yet. */ - SetPropA(This->window, ddProp, This); -} - -static void DDRAW_UnsubclassWindow(IDirectDrawImpl* This) -{ - RemovePropA(This->window, ddProp); -} - -HRESULT WINAPI -Main_DirectDraw_SetCooperativeLevel(LPDIRECTDRAW7 iface, HWND hwnd, - DWORD cooplevel) -{ - IDirectDrawImpl *This = (IDirectDrawImpl *)iface; - - FIXME("(%p)->(%p,%08lx)\n",This,hwnd,cooplevel); - DDRAW_dump_cooperativelevel(cooplevel); - - /* Makes realMYST test happy. */ - if (This->cooperative_level == cooplevel - && This->window == hwnd) - return DD_OK; - - /* XXX "It cannot be reset while the process has surfaces or palettes - * created." Otherwise the window can be changed??? - * - * This appears to be wrong - comment it out for now. - * This seems to be true at least for DDSCL_SETFOCUSWINDOW - * It looks like Windows doesn't store the HWND in all cases, - * probably if DDSCL_NORMAL is specified, but that's not sure - if (This->window) - return DDERR_HWNDALREADYSET; - */ - - /* DDSCL_EXCLUSIVE or DDSCL_NORMAL or DDSCL_SETFOCUSWINDOW must be given */ - if (!(cooplevel & (DDSCL_EXCLUSIVE|DDSCL_NORMAL|DDSCL_SETFOCUSWINDOW))) - { - ERR("(%p) : Call to SetCooperativeLevel failed: cooplevel != DDSCL_EXCLUSIVE|DDSCL_NORMAL|DDSCL_SETFOCUSWINDOW, returning DDERR_INVALIDPARAMS\n", This); - return DDERR_INVALIDPARAMS; - } - /* Device window and focus Window. They only really matter in a - * Multi-Monitor application, but some games specify them and we - * have to react correctly. */ - if(cooplevel & DDSCL_SETFOCUSWINDOW) - { - /* This flag is a biest: It is only valid when DDSCL_NORMAL has been set - * or no hwnd is set and no other flags are allowed, except DDSCL_NOWINDOWCHANGES - */ - if(This->window) - if(!(This->cooperative_level & DDSCL_NORMAL)) - { - ERR("(%p) : Call to SetCooperativeLevel failed: DDSCL_SETFOCUSWINDOW may not be used in Cooplevel %08lx, returning DDERR_HWNDALREADYSET\n", - This, This->cooperative_level); - return DDERR_HWNDALREADYSET; - } - if((cooplevel != DDSCL_SETFOCUSWINDOW)) - if(cooplevel != (DDSCL_SETFOCUSWINDOW | DDSCL_NOWINDOWCHANGES) ) - { - ERR("(%p) : Call to SetCooperativeLevel failed: Invalid use of DDSCL_SETFOCUSWINDOW, returning DDERR_INVALIDPARAMS\n", This); - return DDERR_INVALIDPARAMS; - } - - /* Don't know what exactly to do, but it's perfectly valid - * to pass DDSCL_SETFOCUSWINDOW only */ - FIXME("(%p) : Poorly handled flag DDSCL_SETFOCUSWINDOW\n", This); - - /* Store the flag in the cooperative level. I don't think that all other - * flags should be overwritten, so just add it - * (In the most cases this will be DDSCL_SETFOCUSWINDOW | DDSCL_NORMAL) */ - cooplevel |= DDSCL_SETFOCUSWINDOW; - - return DD_OK; - } - - /* DDSCL_EXCLUSE mode requires DDSCL_FULLSCREEN and vice versa */ - if((cooplevel & DDSCL_EXCLUSIVE) && !(cooplevel & DDSCL_FULLSCREEN)) - return DDERR_INVALIDPARAMS; - /* The other case is checked above */ - - /* Unhandled flags. Give a warning */ - if(cooplevel & DDSCL_SETDEVICEWINDOW) - FIXME("(%p) : Unhandled flag DDSCL_SETDEVICEWINDOW.\n", This); - if(cooplevel & DDSCL_CREATEDEVICEWINDOW) - FIXME("(%p) : Unhandled flag DDSCL_CREATEDEVICEWINDOW.\n", This); - - /* Perhaps the hwnd is only set in DDSCL_EXLUSIVE and DDSCL_FULLSCREEN mode. Not sure */ - This->window = hwnd; - This->cooperative_level = cooplevel; - - This->local.hWnd = (ULONG_PTR)hwnd; - This->local.dwLocalFlags |= DDRAWILCL_SETCOOPCALLED; - /* not entirely sure about these */ - if (cooplevel & DDSCL_EXCLUSIVE) This->local.dwLocalFlags |= DDRAWILCL_HASEXCLUSIVEMODE; - if (cooplevel & DDSCL_FULLSCREEN) This->local.dwLocalFlags |= DDRAWILCL_ISFULLSCREEN; - if (cooplevel & DDSCL_ALLOWMODEX) This->local.dwLocalFlags |= DDRAWILCL_ALLOWMODEX; - if (cooplevel & DDSCL_MULTITHREADED) This->local.dwLocalFlags |= DDRAWILCL_MULTITHREADED; - if (cooplevel & DDSCL_FPUSETUP) This->local.dwLocalFlags |= DDRAWILCL_FPUSETUP; - if (cooplevel & DDSCL_FPUPRESERVE) This->local.dwLocalFlags |= DDRAWILCL_FPUPRESERVE; - - if (This->local.lpGbl) { - /* assume that this app is the active app (in wine, there's - * probably only one app per global ddraw object anyway) */ - if (cooplevel & DDSCL_EXCLUSIVE) This->local.lpGbl->lpExclusiveOwner = &This->local; - else if (This->local.lpGbl->lpExclusiveOwner == &This->local) - This->local.lpGbl->lpExclusiveOwner = NULL; - if (This->set_exclusive_mode) - This->set_exclusive_mode(This, (cooplevel & DDSCL_EXCLUSIVE) != 0); - } - - ShowWindow(hwnd, SW_SHOW); - - DDRAW_SubclassWindow(This); - - /* TODO Does it also get resized to the current screen size? */ - - return DD_OK; -} - -HRESULT WINAPI -Main_DirectDraw_SetDisplayMode(LPDIRECTDRAW7 iface, DWORD dwWidth, - DWORD dwHeight, LONG lPitch, - DWORD dwRefreshRate, DWORD dwFlags, - const DDPIXELFORMAT* pixelformat) -{ - short screenX; - short screenY; - - IDirectDrawImpl *This = (IDirectDrawImpl *)iface; - - TRACE("(%p)->SetDisplayMode(%ld,%ld)\n",This,dwWidth,dwHeight); - - if (!(This->cooperative_level & DDSCL_EXCLUSIVE)) - return DDERR_NOEXCLUSIVEMODE; - - if (!IsWindow(This->window)) - return DDERR_GENERIC; /* unchecked */ - - LosePrimarySurface(This); - - screenX = GetSystemMetrics(SM_CXSCREEN); - screenY = GetSystemMetrics(SM_CYSCREEN); - - This->width = dwWidth; - This->height = dwHeight; - This->pitch = lPitch; - This->pixelformat = *pixelformat; - - /* Position the window in the center of the screen - don't center for now */ - /* MoveWindow(This->window, (screenX-dwWidth)/2, (screenY-dwHeight)/2, - dwWidth, dwHeight, TRUE);*/ - MoveWindow(This->window, 0, 0, dwWidth, dwHeight, TRUE); - - SetFocus(This->window); - - return DD_OK; -} - -HRESULT WINAPI -Main_DirectDraw_RestoreDisplayMode(LPDIRECTDRAW7 iface) -{ - IDirectDrawImpl *This = (IDirectDrawImpl *)iface; - - TRACE("(%p)\n",This); - if (!(This->cooperative_level & DDSCL_EXCLUSIVE)) - return DDERR_NOEXCLUSIVEMODE; - - /* Lose the primary surface if the resolution changes. */ - if (This->orig_width != This->width || This->orig_height != This->height - || This->orig_pitch != This->pitch - || This->orig_pixelformat.dwFlags != This->pixelformat.dwFlags - || !Main_DirectDraw_DDPIXELFORMAT_Match(&This->pixelformat, - &This->orig_pixelformat)) - { - LosePrimarySurface(This); - } - - /* TODO Move the window back where it belongs. */ - - return DD_OK; -} - -HRESULT WINAPI -Main_DirectDraw_WaitForVerticalBlank(LPDIRECTDRAW7 iface, DWORD dwFlags, - HANDLE h) -{ - IDirectDrawImpl *This = (IDirectDrawImpl *)iface; - FIXME("(%p)->(flags=0x%08lx,handle=%p)\n",This,dwFlags,h); - return DD_OK; -} - -HRESULT WINAPI -Main_DirectDraw_GetDisplayMode(LPDIRECTDRAW7 iface, LPDDSURFACEDESC2 pDDSD) -{ - IDirectDrawImpl *This = (IDirectDrawImpl *)iface; - TRACE("(%p)->GetDisplayMode(%p)\n",This,pDDSD); - - pDDSD->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_PIXELFORMAT|DDSD_REFRESHRATE; - pDDSD->dwHeight = This->height; - pDDSD->dwWidth = This->width; - pDDSD->u1.lPitch = This->pitch; - pDDSD->u2.dwRefreshRate = 60; - pDDSD->u4.ddpfPixelFormat = This->pixelformat; - pDDSD->ddsCaps.dwCaps = 0; - - return DD_OK; -} - -static INT32 allocate_memory(IDirectDrawImpl *This, DWORD mem) -{ - if (mem > This->available_vidmem) return -1; - This->available_vidmem -= mem; - return This->available_vidmem; -} - -static void free_memory(IDirectDrawImpl *This, DWORD mem) -{ - This->available_vidmem += mem; -} - -HRESULT WINAPI -Main_DirectDraw_GetAvailableVidMem(LPDIRECTDRAW7 iface, LPDDSCAPS2 ddscaps, - LPDWORD total, LPDWORD free) -{ - IDirectDrawImpl *This = (IDirectDrawImpl *)iface; - TRACE("(%p)->(%p,%p,%p)\n", This,ddscaps,total,free); - - if (TRACE_ON(ddraw)) { - TRACE(" Asking for memory of type : "); - DDRAW_dump_DDSCAPS2(ddscaps); TRACE("\n"); - } - - /* We have 16 MB videomemory */ - if (total) *total= This->total_vidmem; - if (free) *free = This->available_vidmem; - - TRACE(" returning (total) %ld / (free) %ld\n", - total != NULL ? *total : 0, - free != NULL ? *free : 0); - - return DD_OK; -} - -HRESULT WINAPI Main_DirectDraw_TestCooperativeLevel(LPDIRECTDRAW7 iface) { - IDirectDrawImpl *This = (IDirectDrawImpl *)iface; - TRACE("(%p)->(): stub\n", This); - - return DD_OK; -} - -HRESULT WINAPI -Main_DirectDraw_StartModeTest(LPDIRECTDRAW7 iface, LPSIZE pModes, - DWORD dwNumModes, DWORD dwFlags) -{ - IDirectDrawImpl *This = (IDirectDrawImpl *)iface; - FIXME("(%p)->() stub\n", This); - - return DD_OK; -} - -/*** Owned object management. */ - -void Main_DirectDraw_AddSurface(IDirectDrawImpl* This, - IDirectDrawSurfaceImpl* surface) -{ - assert(surface->ddraw_owner == NULL || surface->ddraw_owner == This); - - surface->ddraw_owner = This; - - /* where should it go? */ - surface->next_ddraw = This->surfaces; - surface->prev_ddraw = NULL; - if (This->surfaces) - This->surfaces->prev_ddraw = surface; - This->surfaces = surface; -} - -void Main_DirectDraw_RemoveSurface(IDirectDrawImpl* This, - IDirectDrawSurfaceImpl* surface) -{ - assert(surface->ddraw_owner == This); - - if (This->surfaces == surface) - This->surfaces = surface->next_ddraw; - - if (This->primary_surface == surface) - This->primary_surface = NULL; - - if (surface->next_ddraw) - surface->next_ddraw->prev_ddraw = surface->prev_ddraw; - if (surface->prev_ddraw) - surface->prev_ddraw->next_ddraw = surface->next_ddraw; -} - -static void Main_DirectDraw_DeleteSurfaces(IDirectDrawImpl* This) -{ - while (This->surfaces != NULL) - Main_DirectDrawSurface_ForceDestroy(This->surfaces); -} - -void Main_DirectDraw_AddClipper(IDirectDrawImpl* This, - IDirectDrawClipperImpl* clipper) -{ - assert(clipper->ddraw_owner == NULL || clipper->ddraw_owner == This); - - clipper->ddraw_owner = This; - - clipper->next_ddraw = This->clippers; - clipper->prev_ddraw = NULL; - if (This->clippers) - This->clippers->prev_ddraw = clipper; - This->clippers = clipper; -} - -void Main_DirectDraw_RemoveClipper(IDirectDrawImpl* This, - IDirectDrawClipperImpl* clipper) -{ - assert(clipper->ddraw_owner == This); - - if (This->clippers == clipper) - This->clippers = clipper->next_ddraw; - - if (clipper->next_ddraw) - clipper->next_ddraw->prev_ddraw = clipper->prev_ddraw; - if (clipper->prev_ddraw) - clipper->prev_ddraw->next_ddraw = clipper->next_ddraw; -} - -static void Main_DirectDraw_DeleteClippers(IDirectDrawImpl* This) -{ - while (This->clippers != NULL) - Main_DirectDrawClipper_ForceDestroy(This->clippers); -} - -void Main_DirectDraw_AddPalette(IDirectDrawImpl* This, - IDirectDrawPaletteImpl* palette) -{ - assert(palette->ddraw_owner == NULL || palette->ddraw_owner == This); - - palette->ddraw_owner = This; - - /* where should it go? */ - palette->next_ddraw = This->palettes; - palette->prev_ddraw = NULL; - if (This->palettes) - This->palettes->prev_ddraw = palette; - This->palettes = palette; -} - -void Main_DirectDraw_RemovePalette(IDirectDrawImpl* This, - IDirectDrawPaletteImpl* palette) -{ - IDirectDrawSurfaceImpl *surf; - - assert(palette->ddraw_owner == This); - - if (This->palettes == palette) - This->palettes = palette->next_ddraw; - - if (palette->next_ddraw) - palette->next_ddraw->prev_ddraw = palette->prev_ddraw; - if (palette->prev_ddraw) - palette->prev_ddraw->next_ddraw = palette->next_ddraw; - - /* Here we need also to remove tha palette from any surface which has it as the - * current palette (checked on Windows) - */ - for (surf = This->surfaces; surf != NULL; surf = surf->next_ddraw) { - if (surf->palette == palette) { - TRACE("Palette %p attached to surface %p.\n", palette, surf); - surf->palette = NULL; - surf->set_palette(surf, NULL); - } - } -} - -static void Main_DirectDraw_DeletePalettes(IDirectDrawImpl* This) -{ - while (This->palettes != NULL) - Main_DirectDrawPalette_ForceDestroy(This->palettes); -} - -/*** ??? */ - -static void -LoseSurface(IDirectDrawSurfaceImpl *surface) -{ - if (surface != NULL) surface->lose_surface(surface); -} - -static void -LosePrimarySurface(IDirectDrawImpl *This) -{ - /* MSDN: "If another application changes the display mode, the primary - * surface is lost, and the method returns DDERR_SURFACELOST until the - * primary surface is recreated to match the new display mode." - * - * We mark all the primary surfaces as lost as soon as the display - * mode is changed (by any application). */ - - LoseSurface(This->primary_surface); -} - -/****************************************************************************** - * Uninitialised DirectDraw functions - * - * This vtable is used when a DirectDraw object is created with - * CoCreateInstance. The only usable method is Initialize. - */ - -void Uninit_DirectDraw_final_release(IDirectDrawImpl *This) -{ - Main_DirectDraw_final_release(This); -} - -static const IDirectDraw7Vtbl Uninit_DirectDraw_VTable; - -/* Not called from the vtable. */ -HRESULT Uninit_DirectDraw_Construct(IDirectDrawImpl *This, BOOL ex) -{ - HRESULT hr; - - hr = Main_DirectDraw_Construct(This, ex); - if (FAILED(hr)) return hr; - - This->final_release = Uninit_DirectDraw_final_release; - ICOM_INIT_INTERFACE(This, IDirectDraw7, Uninit_DirectDraw_VTable); - - return S_OK; -} - -HRESULT Uninit_DirectDraw_Create(const GUID* pGUID, - LPDIRECTDRAW7* pIface, - IUnknown* pUnkOuter, BOOL ex) -{ - HRESULT hr; - IDirectDrawImpl* This; - - assert(pUnkOuter == NULL); /* XXX no: we must check this */ - - This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof(IDirectDrawImpl)); - if (This == NULL) return E_OUTOFMEMORY; - - hr = Uninit_DirectDraw_Construct(This, ex); - if (FAILED(hr)) - HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, This); - else - *pIface = ICOM_INTERFACE(This, IDirectDraw7); - - return hr; -} - -static HRESULT WINAPI -Uninit_DirectDraw_Initialize(LPDIRECTDRAW7 iface, LPGUID pDeviceGuid) -{ - const ddraw_driver* driver; - IDirectDrawImpl *This = (IDirectDrawImpl *)iface; - - TRACE("(%p)->(%p)\n", iface, pDeviceGuid); - - driver = DDRAW_FindDriver(pDeviceGuid); - /* XXX This return value is not documented. (Not checked.) */ - if (driver == NULL) return DDERR_INVALIDDIRECTDRAWGUID; - - return driver->init(This, pDeviceGuid); -} - -static HRESULT WINAPI -Uninit_DirectDraw_Compact(LPDIRECTDRAW7 iface) -{ - return DDERR_NOTINITIALIZED; -} - -static HRESULT WINAPI -Uninit_DirectDraw_CreateClipper(LPDIRECTDRAW7 iface, DWORD dwFlags, - LPDIRECTDRAWCLIPPER *lplpDDClipper, - IUnknown *pUnkOuter) - -{ - return DDERR_NOTINITIALIZED; -} - -static HRESULT WINAPI -Uninit_DirectDraw_CreatePalette(LPDIRECTDRAW7 iface, DWORD dwFlags, - LPPALETTEENTRY lpColorTable, - LPDIRECTDRAWPALETTE *lplpDDPalette, - IUnknown *pUnkOuter) -{ - return DDERR_NOTINITIALIZED; -} - -static HRESULT WINAPI -Uninit_DirectDraw_CreateSurface(LPDIRECTDRAW7 iface, - LPDDSURFACEDESC2 lpDDSurfaceDesc, - LPDIRECTDRAWSURFACE7 *lplpDDSurface, - IUnknown *pUnkOuter) -{ - return DDERR_NOTINITIALIZED; -} - -static HRESULT WINAPI -Uninit_DirectDraw_DuplicateSurface(LPDIRECTDRAW7 iface, - LPDIRECTDRAWSURFACE7 pSurf, - LPDIRECTDRAWSURFACE7 *pDupSurf) - -{ - return DDERR_NOTINITIALIZED; -} - -static HRESULT WINAPI -Uninit_DirectDraw_EnumDisplayModes(LPDIRECTDRAW7 iface, DWORD dwFlags, - LPDDSURFACEDESC2 lpDDSD, - LPVOID context, - LPDDENUMMODESCALLBACK2 cb) -{ - return DDERR_NOTINITIALIZED; -} - -static HRESULT WINAPI -Uninit_DirectDraw_EnumSurfaces(LPDIRECTDRAW7 iface, DWORD dwFlags, - LPDDSURFACEDESC2 pDDSD, LPVOID context, - LPDDENUMSURFACESCALLBACK7 cb) -{ - return DDERR_NOTINITIALIZED; -} - -static HRESULT WINAPI -Uninit_DirectDraw_FlipToGDISurface(LPDIRECTDRAW7 iface) -{ - return DDERR_NOTINITIALIZED; -} - -static HRESULT WINAPI -Uninit_DirectDraw_GetCaps(LPDIRECTDRAW7 iface, LPDDCAPS pDriverCaps, - LPDDCAPS pHELCaps) -{ - return DDERR_NOTINITIALIZED; -} - -static HRESULT WINAPI -Uninit_DirectDraw_GetDisplayMode(LPDIRECTDRAW7 iface, - LPDDSURFACEDESC2 pDDSD) -{ - return DDERR_NOTINITIALIZED; -} - -static HRESULT WINAPI -Uninit_DirectDraw_GetFourCCCodes(LPDIRECTDRAW7 iface, LPDWORD pNumCodes, - LPDWORD pCodes) -{ - return DDERR_NOTINITIALIZED; -} - -static HRESULT WINAPI -Uninit_DirectDraw_GetGDISurface(LPDIRECTDRAW7 iface, - LPDIRECTDRAWSURFACE7 *pGDISurf) -{ - return DDERR_NOTINITIALIZED; -} - -static HRESULT WINAPI -Uninit_DirectDraw_GetMonitorFrequency(LPDIRECTDRAW7 iface, LPDWORD pdwFreq) -{ - return DDERR_NOTINITIALIZED; -} - -static HRESULT WINAPI -Uninit_DirectDraw_GetScanLine(LPDIRECTDRAW7 iface, LPDWORD pdwScanLine) -{ - return DDERR_NOTINITIALIZED; -} - -static HRESULT WINAPI -Uninit_DirectDraw_GetVerticalBlankStatus(LPDIRECTDRAW7 iface, PBOOL pbIsInVB) -{ - return DDERR_NOTINITIALIZED; -} - -static HRESULT WINAPI -Uninit_DirectDraw_RestoreDisplayMode(LPDIRECTDRAW7 iface) -{ - return DDERR_NOTINITIALIZED; -} - -static HRESULT WINAPI -Uninit_DirectDraw_SetCooperativeLevel(LPDIRECTDRAW7 iface, HWND hWnd, - DWORD dwFlags) -{ - return DDERR_NOTINITIALIZED; -} - -static HRESULT WINAPI -Uninit_DirectDraw_SetDisplayMode(LPDIRECTDRAW7 iface, DWORD dwWidth, - DWORD dwHeight, DWORD dwBPP, - DWORD dwRefreshRate, DWORD dwFlags) -{ - return DDERR_NOTINITIALIZED; -} - -static HRESULT WINAPI -Uninit_DirectDraw_WaitForVerticalBlank(LPDIRECTDRAW7 iface, DWORD dwFlags, - HANDLE hEvent) -{ - return DDERR_NOTINITIALIZED; -} - -static HRESULT WINAPI -Uninit_DirectDraw_GetAvailableVidMem(LPDIRECTDRAW7 iface, LPDDSCAPS2 pDDCaps, - LPDWORD pdwTotal, LPDWORD pdwFree) -{ - return DDERR_NOTINITIALIZED; -} - -static HRESULT WINAPI -Uninit_DirectDraw_GetSurfaceFromDC(LPDIRECTDRAW7 iface, HDC hDC, - LPDIRECTDRAWSURFACE7 *pSurf) -{ - return DDERR_NOTINITIALIZED; -} - -static HRESULT WINAPI -Uninit_DirectDraw_RestoreAllSurfaces(LPDIRECTDRAW7 iface) -{ - return DDERR_NOTINITIALIZED; -} - -static HRESULT WINAPI -Uninit_DirectDraw_TestCooperativeLevel(LPDIRECTDRAW7 iface) -{ - return DDERR_NOTINITIALIZED; -} - -static HRESULT WINAPI -Uninit_DirectDraw_GetDeviceIdentifier(LPDIRECTDRAW7 iface, - LPDDDEVICEIDENTIFIER2 pDDDI, - DWORD dwFlags) -{ - return DDERR_NOTINITIALIZED; -} - -static HRESULT WINAPI -Uninit_DirectDraw_StartModeTest(LPDIRECTDRAW7 iface, LPSIZE pszModes, - DWORD cModes, DWORD dwFlags) -{ - return DDERR_NOTINITIALIZED; -} - -static HRESULT WINAPI -Uninit_DirectDraw_EvaluateMode(LPDIRECTDRAW7 iface, DWORD dwFlags, - LPDWORD pTimeout) -{ - return DDERR_NOTINITIALIZED; -} - -static const IDirectDraw7Vtbl Uninit_DirectDraw_VTable = -{ - Main_DirectDraw_QueryInterface, - Main_DirectDraw_AddRef, - Main_DirectDraw_Release, - Uninit_DirectDraw_Compact, - Uninit_DirectDraw_CreateClipper, - Uninit_DirectDraw_CreatePalette, - Uninit_DirectDraw_CreateSurface, - Uninit_DirectDraw_DuplicateSurface, - Uninit_DirectDraw_EnumDisplayModes, - Uninit_DirectDraw_EnumSurfaces, - Uninit_DirectDraw_FlipToGDISurface, - Uninit_DirectDraw_GetCaps, - Uninit_DirectDraw_GetDisplayMode, - Uninit_DirectDraw_GetFourCCCodes, - Uninit_DirectDraw_GetGDISurface, - Uninit_DirectDraw_GetMonitorFrequency, - Uninit_DirectDraw_GetScanLine, - Uninit_DirectDraw_GetVerticalBlankStatus, - Uninit_DirectDraw_Initialize, - Uninit_DirectDraw_RestoreDisplayMode, - Uninit_DirectDraw_SetCooperativeLevel, - Uninit_DirectDraw_SetDisplayMode, - Uninit_DirectDraw_WaitForVerticalBlank, - Uninit_DirectDraw_GetAvailableVidMem, - Uninit_DirectDraw_GetSurfaceFromDC, - Uninit_DirectDraw_RestoreAllSurfaces, - Uninit_DirectDraw_TestCooperativeLevel, - Uninit_DirectDraw_GetDeviceIdentifier, - Uninit_DirectDraw_StartModeTest, - Uninit_DirectDraw_EvaluateMode -}; diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h index a35ba6bff9..66ce1664c7 100644 --- a/dlls/ddraw/ddraw_private.h +++ b/dlls/ddraw/ddraw_private.h @@ -1,5 +1,5 @@ /* - * Copyright 2000-2001 TransGaming Technologies Inc. + * Copyright 2006 Stefan Dösinger * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -30,54 +30,57 @@ #include "wingdi.h" #include "winuser.h" #include "ddraw.h" -#include "d3d.h" -#include "ddcomimpl.h" #include "ddrawi.h" +#include "d3d.h" -/* XXX Put this somewhere proper. */ -#define DD_STRUCT_INIT(x) \ - do { \ - memset((x), 0, sizeof(*(x))); \ - (x)->dwSize = sizeof(*x); \ - } while (0) +#include "ddcomimpl.h" -#define DD_STRUCT_COPY_BYSIZE(to,from) \ - do { \ - DWORD __size = (to)->dwSize; \ - DWORD __copysize = __size; \ - DWORD __resetsize = __size; \ - assert(to != from); \ - if (__resetsize > sizeof(*to)) \ - __resetsize = sizeof(*to); \ - memset(to,0,__resetsize); \ - if ((from)->dwSize < __size) \ - __copysize = (from)->dwSize; \ - memcpy(to,from,__copysize); \ - (to)->dwSize = __size;/*restore size*/ \ - } while (0) +#include "wine/wined3d_interface.h" -#define MAKE_FOURCC(a,b,c,d) ((a << 0) | (b << 8) | (c << 16) | (d << 24)) +/***************************************************************************** + * IParent - a helper interface + *****************************************************************************/ +DEFINE_GUID(IID_IParent, 0xc20e4c88, 0x74e7, 0x4940, 0xba, 0x9f, 0x2e, 0x32, 0x3f, 0x9d, 0xc9, 0x81); +typedef struct IParent *LPPARENT, *PPARENT; + +#define INTERFACE IParent +DECLARE_INTERFACE_(IParent,IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; +}; +#undef INTERFACE + +#if !defined(__cplusplus) || defined(CINTERFACE) +/*** IUnknown methods ***/ +#define IParent_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IParent_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IParent_Release(p) (p)->lpVtbl->Release(p) +#endif + + +/* Typdef the interfaces */ +typedef struct IDirectDrawImpl IDirectDrawImpl; +typedef struct IDirectDrawSurfaceImpl IDirectDrawSurfaceImpl; +typedef struct IDirectDrawClipperImpl IDirectDrawClipperImpl; +typedef struct IDirectDrawPaletteImpl IDirectDrawPaletteImpl; +typedef struct IDirect3DDeviceImpl IDirect3DDeviceImpl; +typedef struct IDirect3DLightImpl IDirect3DLightImpl; +typedef struct IDirect3DViewportImpl IDirect3DViewportImpl; +typedef struct IDirect3DMaterialImpl IDirect3DMaterialImpl; +typedef struct IDirect3DExecuteBufferImpl IDirect3DExecuteBufferImpl; +typedef struct IDirect3DVertexBufferImpl IDirect3DVertexBufferImpl; +typedef struct IParentImpl IParentImpl; /***************************************************************************** * IDirectDraw implementation structure - */ - -typedef struct IDirectDrawImpl IDirectDrawImpl; -typedef struct IDirectDrawPaletteImpl IDirectDrawPaletteImpl; -typedef struct IDirectDrawClipperImpl IDirectDrawClipperImpl; -typedef struct IDirectDrawSurfaceImpl IDirectDrawSurfaceImpl; -typedef struct IDirect3DDeviceImpl IDirect3DDeviceImpl; - -typedef void (*pixel_convert_func)(void *src, void *dst, DWORD width, - DWORD height, LONG pitch, - IDirectDrawPaletteImpl *palette); - -typedef void (*palette_convert_func)(LPPALETTEENTRY palent, - void *screen_palette, DWORD start, - DWORD count); + *****************************************************************************/ struct IDirectDrawImpl { + /* IUnknown fields */ ICOM_VFIELD_MULTI(IDirectDraw7); ICOM_VFIELD_MULTI(IDirectDraw4); ICOM_VFIELD_MULTI(IDirectDraw2); @@ -87,144 +90,256 @@ struct IDirectDrawImpl ICOM_VFIELD_MULTI(IDirect3D2); ICOM_VFIELD_MULTI(IDirect3D); - LONG ref; + LONG ref; - /* TRUE if created via DirectDrawCreateEx or CoCreateInstance, - * FALSE if created via DirectDrawCreate. */ - BOOL ex; + /* WineD3D linkage */ + IWineD3D *wineD3D; + IWineD3DDevice *wineD3DDevice; + IDirectDrawSurfaceImpl *DepthStencilBuffer; + BOOL d3d_initialized; - /* Linked list of surfaces, joined by next_ddraw in IDirectSurfaceImpl. */ - IDirectDrawSurfaceImpl* surfaces; - /* Linked list of palettes, joined by next_ddraw. */ - IDirectDrawPaletteImpl* palettes; - /* Linked list of clippers, joined by next_ddraw. */ - IDirectDrawClipperImpl* clippers; + /* misc ddraw fields */ + UINT total_vidmem; + DWORD cur_scanline; + BOOL fake_vblank; + BOOL initialized; - IDirectDrawSurfaceImpl* primary_surface; + /* DirectDraw things, which are not handled by WineD3D */ + DWORD cooperative_level; - DDRAWI_DIRECTDRAW_LCL local; - DDCAPS caps; + DWORD orig_width, orig_height; + DWORD orig_bpp; - HWND window; - DWORD cooperative_level; - WNDPROC original_wndproc; + DDCAPS caps; - DWORD width, height; - LONG pitch; - DDPIXELFORMAT pixelformat; - DWORD cur_scanline; + LONG style; + LONG exStyle; - BOOL fake_vblank; - - /* Should each of these go into some structure? */ - DWORD orig_width, orig_height; - LONG orig_pitch; - DDPIXELFORMAT orig_pixelformat; + /* D3D things */ + IDirectDrawSurfaceImpl *d3d_target; + HWND d3d_window; + IDirect3DDeviceImpl *d3ddevice; - /* Called when the refcount goes to 0. */ - void (*final_release)(IDirectDrawImpl *This); + /* Varios HWNDs */ + HWND focuswindow; + HWND devicewindow; - HRESULT (*set_exclusive_mode)(IDirectDrawImpl *This, DWORD dwExcl); + /* The surface type to request */ + WINED3DSURFTYPE ImplType; - HRESULT (*create_palette)(IDirectDrawImpl* This, DWORD dwFlags, - LPDIRECTDRAWPALETTE* ppPalette, - LPUNKNOWN pUnkOuter); + /* The surface list - can't relay this to WineD3D + * because of IParent + */ + IDirectDrawSurfaceImpl *surface_list; - /* Surface creation functions. For all of these, pOuter == NULL. */ + /* Our private window class */ + char classname[32]; + WNDCLASSA wnd_class; - /* Do not create any backbuffers or the flipping chain. */ - HRESULT (*create_primary)(IDirectDrawImpl* This, - const DDSURFACEDESC2* pDDSD, - LPDIRECTDRAWSURFACE7* ppSurf, LPUNKNOWN pOuter); + /* Helpers for surface creation */ + IDirectDrawSurfaceImpl *tex_root; + BOOL depthstencil; - /* Primary may be NULL if we are creating an unattached backbuffer. */ - HRESULT (*create_backbuffer)(IDirectDrawImpl* This, - const DDSURFACEDESC2* pDDSD, - LPDIRECTDRAWSURFACE7* ppSurf, - LPUNKNOWN pOuter, - IDirectDrawSurfaceImpl* primary); + /* For the dll unload cleanup code */ + IDirectDrawImpl *next; + BOOL DoNotDestroy; + LONG surfaces; +}; - /* shiny happy offscreenplain surfaces */ - HRESULT (*create_offscreen)(IDirectDrawImpl* This, - const DDSURFACEDESC2* pDDSD, - LPDIRECTDRAWSURFACE7* ppSurf, - LPUNKNOWN pOuter); +/* Declare the VTables. They can be found ddraw.c */ +const IDirectDraw7Vtbl IDirectDraw7_Vtbl; +const IDirectDraw4Vtbl IDirectDraw4_Vtbl; +const IDirectDraw2Vtbl IDirectDraw2_Vtbl; +const IDirectDrawVtbl IDirectDraw1_Vtbl; - /* dwMipMapLevel is specified as per OpenGL. (i.e. 0 is base) */ - HRESULT (*create_texture)(IDirectDrawImpl* This, - const DDSURFACEDESC2* pDDSD, - LPDIRECTDRAWSURFACE7* ppSurf, LPUNKNOWN pOuter, - DWORD dwMipMapLevel); +/* Helper structures */ +typedef struct EnumDisplayModesCBS +{ + void *context; + LPDDENUMMODESCALLBACK2 callback; +} EnumDisplayModesCBS; - HRESULT (*create_zbuffer)(IDirectDrawImpl* This, - const DDSURFACEDESC2* pDDSD, - LPDIRECTDRAWSURFACE7* ppSurf, LPUNKNOWN pOuter); +typedef struct EnumSurfacesCBS +{ + void *context; + LPDDENUMSURFACESCALLBACK7 callback; + LPDDSURFACEDESC2 pDDSD; + DWORD Flags; +} EnumSurfacesCBS; - LPVOID private; +/* Utility functions */ +void +DDRAW_Convert_DDSCAPS_1_To_2(const DDSCAPS* pIn, + DDSCAPS2* pOut); +void +DDRAW_Convert_DDDEVICEIDENTIFIER_2_To_1(const DDDEVICEIDENTIFIER2* pIn, + DDDEVICEIDENTIFIER* pOut); +void +IDirectDrawImpl_Destroy(IDirectDrawImpl *This); - /* Everything below here is still questionable. */ +HRESULT WINAPI +IDirectDrawImpl_RecreateSurfacesCallback(IDirectDrawSurface7 *surf, + DDSURFACEDESC2 *desc, + void *Context); +/* The cleanup list */ +extern IDirectDrawImpl *ddraw_list; - DDPIXELFORMAT screen_pixelformat; +/* The default surface type */ +extern WINED3DSURFTYPE DefaultSurfaceType; - int pixmap_depth; - pixel_convert_func pixel_convert; - palette_convert_func palette_convert; +/***************************************************************************** + * IDirectDrawSurface implementation structure + *****************************************************************************/ - /* Use to fool some too strict games */ - INT32 (*allocate_memory)(IDirectDrawImpl *This, DWORD mem); - void (*free_memory)(IDirectDrawImpl *This, DWORD mem); - DWORD total_vidmem, available_vidmem; - - /* IDirect3D fields */ - LPVOID d3d_private; +struct IDirectDrawSurfaceImpl +{ + /* IUnknown fields */ + ICOM_VFIELD_MULTI(IDirectDrawSurface7); + ICOM_VFIELD_MULTI(IDirectDrawSurface3); + ICOM_VFIELD_MULTI(IDirectDrawGammaControl); + ICOM_VFIELD_MULTI(IDirect3DTexture2); + ICOM_VFIELD_MULTI(IDirect3DTexture); - /* Used as a callback function to create a texture */ - HRESULT (*d3d_create_texture)(IDirectDrawImpl *d3d, IDirectDrawSurfaceImpl *tex, BOOLEAN at_creation, IDirectDrawSurfaceImpl *main); + LONG ref; - /* Used as a callback for Devices to tell to the D3D object it's been created */ - HRESULT (*d3d_added_device)(IDirectDrawImpl *d3d, IDirect3DDeviceImpl *device); - HRESULT (*d3d_removed_device)(IDirectDrawImpl *d3d, IDirect3DDeviceImpl *device); + int version; - /* This is needed for delayed texture creation and Z buffer blits */ - IDirect3DDeviceImpl *current_device; + /* Connections to other Objects */ + IDirectDrawImpl *ddraw; + IWineD3DSurface *WineD3DSurface; + IWineD3DTexture *wineD3DTexture; - /* This is for the fake mainWindow */ - ATOM winclass; - PAINTSTRUCT ps; - BOOL paintable; + /* This implementation handles attaching surfaces to other surfaces */ + IDirectDrawSurfaceImpl *next_attached; + IDirectDrawSurfaceImpl *first_attached; + IDirectDrawSurfaceImpl *next_complex; + IDirectDrawSurfaceImpl *first_complex; + + /* Surface description, for GetAttachedSurface */ + DDSURFACEDESC2 surface_desc; + + /* Misc things */ + DWORD uniqueness_value; + UINT mipmap_level; + WINED3DSURFTYPE ImplType; + + /* For D3DDevice creation */ + BOOL isRenderTarget; + + /* Clipper objects */ + IDirectDrawClipperImpl *clipper; + + /* For the ddraw surface list */ + IDirectDrawSurfaceImpl *next; + IDirectDrawSurfaceImpl *prev; +}; + +/* VTable declaration. It's located in surface.c / surface_thunks.c */ +const IDirectDrawSurface7Vtbl IDirectDrawSurface7_Vtbl; +const IDirectDrawSurface3Vtbl IDirectDrawSurface3_Vtbl; +const IDirectDrawGammaControlVtbl IDirectDrawGammaControl_Vtbl; +const IDirect3DTexture2Vtbl IDirect3DTexture2_Vtbl; +const IDirect3DTextureVtbl IDirect3DTexture1_Vtbl; + +/* Get the number of bytes per pixel for a given surface */ +#define PFGET_BPP(pf) (pf.dwFlags&DDPF_PALETTEINDEXED8?1:((pf.dwRGBBitCount+7)/8)) +#define GET_BPP(desc) PFGET_BPP(desc.ddpfPixelFormat) + +/***************************************************************************** + * IParent Implementation + *****************************************************************************/ +struct IParentImpl +{ + /* IUnknown fields */ + ICOM_VFIELD_MULTI(IParent); + LONG ref; + + /* IParentImpl fields */ + IUnknown *child; + +}; + +const IParentVtbl IParent_Vtbl; + +/***************************************************************************** + * IDirect3DDevice implementation + *****************************************************************************/ +struct IDirect3DDeviceImpl +{ + /* IUnknown */ + ICOM_VFIELD_MULTI(IDirect3DDevice7); + ICOM_VFIELD_MULTI(IDirect3DDevice3); + ICOM_VFIELD_MULTI(IDirect3DDevice2); + ICOM_VFIELD_MULTI(IDirect3DDevice); + LONG ref; + + /* Other object connections */ + IWineD3DDevice *wineD3DDevice; + IDirectDrawImpl *ddraw; + IWineD3DIndexBuffer *indexbuffer; + IDirectDrawSurfaceImpl *target; + BOOL OffScreenTarget; + + /* Viewport management */ + IDirect3DViewportImpl *viewport_list; + IDirect3DViewportImpl *current_viewport; + D3DVIEWPORT7 active_viewport; + + /* Light state */ + DWORD material; + + /* Rendering functions to wrap D3D(1-3) to D3D7 */ + D3DPRIMITIVETYPE primitive_type; + DWORD vertex_type; + DWORD render_flags; + DWORD nb_vertices; + LPBYTE vertex_buffer; + DWORD vertex_size; + DWORD buffer_size; +}; + +/* Vtables in various versions */ +const IDirect3DDevice7Vtbl IDirect3DDevice7_Vtbl; +const IDirect3DDevice3Vtbl IDirect3DDevice3_Vtbl; +const IDirect3DDevice2Vtbl IDirect3DDevice2_Vtbl; +const IDirect3DDeviceVtbl IDirect3DDevice1_Vtbl; + +/* The IID */ +const GUID IID_D3DDEVICE_WineD3D; + +/* Helper functions */ +HRESULT IDirect3DImpl_GetCaps(IWineD3D *WineD3D, D3DDEVICEDESC *Desc123, D3DDEVICEDESC7 *Desc7); + +/* Structures */ +struct EnumTextureFormatsCBS +{ + LPD3DENUMTEXTUREFORMATSCALLBACK cbv2; + LPD3DENUMPIXELFORMATSCALLBACK cbv7; + void *Context; }; /***************************************************************************** - * IDirectDrawPalette implementation structure - */ -struct IDirectDrawPaletteImpl + * IDirect3D implementation + *****************************************************************************/ + +/* No implementation structure as this is only another interface to DirectDraw */ + +/* the Vtables */ +const IDirect3DVtbl IDirect3D1_Vtbl; +const IDirect3D2Vtbl IDirect3D2_Vtbl; +const IDirect3D3Vtbl IDirect3D3_Vtbl; +const IDirect3D7Vtbl IDirect3D7_Vtbl; + +/* Structure for EnumZBufferFormats */ +struct EnumZBufferFormatsData { - /* IUnknown fields */ - ICOM_VFIELD_MULTI(IDirectDrawPalette); - LONG ref; - - DDRAWI_DDRAWPALETTE_LCL local; - DDRAWI_DDRAWPALETTE_GBL global; - - /* IDirectDrawPalette fields */ - HPALETTE hpal; - WORD palVersion, palNumEntries; /* LOGPALETTE */ - PALETTEENTRY palents[256]; - /* This is to store the palette in 'screen format' */ - int screen_palents[256]; - - VOID (*final_release)(IDirectDrawPaletteImpl* This); - - IDirectDrawImpl* ddraw_owner; - IDirectDrawPaletteImpl* prev_ddraw; - IDirectDrawPaletteImpl* next_ddraw; - - LPVOID private; + LPD3DENUMPIXELFORMATSCALLBACK Callback; + void *Context; }; /***************************************************************************** * IDirectDrawClipper implementation structure - */ + *****************************************************************************/ struct IDirectDrawClipperImpl { /* IUnknown fields */ @@ -235,191 +350,235 @@ struct IDirectDrawClipperImpl HWND hWnd; IDirectDrawImpl* ddraw_owner; - IDirectDrawClipperImpl* prev_ddraw; - IDirectDrawClipperImpl* next_ddraw; + struct IDirectDrawClipperImpl* prev_ddraw; + struct IDirectDrawClipperImpl* next_ddraw; }; -/***************************************************************************** - * IDirectDrawSurface implementation structure - */ +const IDirectDrawClipperVtbl IDirectDrawClipper_Vtbl; -struct IDirectDrawSurfaceImpl +/***************************************************************************** + * IDirectDrawPalette implementation structure + *****************************************************************************/ +struct IDirectDrawPaletteImpl { /* IUnknown fields */ - ICOM_VFIELD_MULTI(IDirectDrawSurface7); - ICOM_VFIELD_MULTI(IDirectDrawSurface3); - ICOM_VFIELD_MULTI(IDirectDrawGammaControl); - ICOM_VFIELD_MULTI(IDirect3DTexture2); - ICOM_VFIELD_MULTI(IDirect3DTexture); + ICOM_VFIELD_MULTI(IDirectDrawPalette); LONG ref; - struct IDirectDrawSurfaceImpl* attached; /* attached surfaces */ + /* WineD3D uplink */ + IWineD3DPalette *wineD3DPalette; - struct IDirectDrawSurfaceImpl* next_ddraw; /* ddraw surface chain */ - struct IDirectDrawSurfaceImpl* prev_ddraw; - struct IDirectDrawSurfaceImpl* next_attached; /* attached surface chain */ - struct IDirectDrawSurfaceImpl* prev_attached; + /* IDirectDrawPalette fields */ + IDirectDrawImpl *ddraw_owner; +}; +const IDirectDrawPaletteVtbl IDirectDrawPalette_Vtbl; - IDirectDrawImpl* ddraw_owner; - IDirectDrawSurfaceImpl* surface_owner; +/****************************************************************************** + * DirectDraw ClassFactory Implementation - incomplete + ******************************************************************************/ +typedef struct +{ + ICOM_VFIELD_MULTI(IClassFactory); - IDirectDrawPaletteImpl* palette; /* strong ref */ - IDirectDrawClipperImpl* clipper; /* strong ref */ + LONG ref; + HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, REFIID iid, LPVOID *ppObj); +} IClassFactoryImpl; - DDRAWI_DDRAWSURFACE_LCL local; - DDRAWI_DDRAWSURFACE_MORE more; - /* FIXME: since Flip should swap the GBL structures, they should - * probably not be embedded into the IDirectDrawSurfaceImpl structure... */ - LPDDRAWI_DDRAWSURFACE_GBL_MORE gmore; - DDRAWI_DDRAWSURFACE_GBL global; - DDRAWI_DDRAWSURFACE_GBL_MORE global_more; - - DDSURFACEDESC2 surface_desc; - - HDC hDC; - RECT lastlockrect; - DWORD lastlocktype; - BOOL dc_in_use; - BOOL locked; - - HRESULT (*duplicate_surface)(IDirectDrawSurfaceImpl* src, - LPDIRECTDRAWSURFACE7* dst); - void (*final_release)(IDirectDrawSurfaceImpl *This); - HRESULT (*late_allocate)(IDirectDrawSurfaceImpl *This); - BOOL (*attach)(IDirectDrawSurfaceImpl *This, IDirectDrawSurfaceImpl *to); - BOOL (*detach)(IDirectDrawSurfaceImpl *This); - void (*lock_update)(IDirectDrawSurfaceImpl* This, LPCRECT pRect, DWORD dwFlags); - void (*unlock_update)(IDirectDrawSurfaceImpl* This, LPCRECT pRect); - void (*lose_surface)(IDirectDrawSurfaceImpl* This); - BOOL (*flip_data)(IDirectDrawSurfaceImpl* front, - IDirectDrawSurfaceImpl* back, - DWORD dwFlags); - void (*flip_update)(IDirectDrawSurfaceImpl* front, DWORD dwFlags); - HRESULT (*get_dc)(IDirectDrawSurfaceImpl* This, HDC* phDC); - HRESULT (*release_dc)(IDirectDrawSurfaceImpl* This, HDC hDC); - void (*set_palette)(IDirectDrawSurfaceImpl* This, IDirectDrawPaletteImpl* pal); - void (*update_palette)(IDirectDrawSurfaceImpl* This, IDirectDrawPaletteImpl* pal, - DWORD dwStart, DWORD dwCount, LPPALETTEENTRY palent); - HWND (*get_display_window)(IDirectDrawSurfaceImpl *This); - HRESULT (*get_gamma_ramp)(IDirectDrawSurfaceImpl *This, DWORD dwFlags, LPDDGAMMARAMP lpGammaRamp); - HRESULT (*set_gamma_ramp)(IDirectDrawSurfaceImpl *This, DWORD dwFlags, LPDDGAMMARAMP lpGammaRamp); - - struct PrivateData* private_data; - - DWORD max_lod; - DWORD priority; - - BOOL lost; - - DWORD uniqueness_value; - - LPVOID private; - - /* Everything below here is dodgy. */ - /* For Direct3D use */ - LPVOID aux_ctx, aux_data; - void (*aux_release)(LPVOID ctx, LPVOID data); - BOOL (*aux_flip)(LPVOID ctx, LPVOID data); - void (*aux_unlock)(LPVOID ctx, LPVOID data, LPRECT lpRect); - HRESULT (*aux_blt)(struct IDirectDrawSurfaceImpl *This, LPRECT rdst, LPDIRECTDRAWSURFACE7 src, LPRECT rsrc, DWORD dwFlags, LPDDBLTFX lpbltfx); - HRESULT (*aux_bltfast)(struct IDirectDrawSurfaceImpl *This, DWORD dstx, DWORD dsty, LPDIRECTDRAWSURFACE7 src, LPRECT rsrc, DWORD trans); - HRESULT (*aux_setcolorkey_cb)(struct IDirectDrawSurfaceImpl *texture, DWORD dwFlags, LPDDCOLORKEY ckey ); - /* This is to get the D3DDevice object associated to this surface */ - struct IDirect3DDeviceImpl *d3ddevice; - /* This is for texture */ - IDirectDrawSurfaceImpl *mip_main; - int mipmap_level; - LPVOID tex_private; - void (*lock_update_prev)(IDirectDrawSurfaceImpl* This, LPCRECT pRect, DWORD dwFlags); - void (*unlock_update_prev)(IDirectDrawSurfaceImpl* This, LPCRECT pRect); - BOOLEAN (*get_dirty_status)(IDirectDrawSurfaceImpl* This, LPCRECT pRect); +/* Helper structures */ +struct object_creation_info +{ + const CLSID *clsid; + HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, REFIID riid, + void **ppObj); }; +/****************************************************************************** + * IDirect3DLight implementation structure - Wraps to D3D7 + ******************************************************************************/ +struct IDirect3DLightImpl +{ + ICOM_VFIELD_MULTI(IDirect3DLight); + LONG ref; + + /* IDirect3DLight fields */ + IDirectDrawImpl *ddraw; + + /* If this light is active for one viewport, put the viewport here */ + IDirect3DViewportImpl *active_viewport; + + D3DLIGHT2 light; + D3DLIGHT7 light7; + + DWORD dwLightIndex; + + /* Chained list used for adding / removing from viewports */ + IDirect3DLightImpl *next; + + /* Activation function */ + void (*activate)(IDirect3DLightImpl*); + void (*desactivate)(IDirect3DLightImpl*); + void (*update)(IDirect3DLightImpl*); +}; + +/* Vtable */ +const IDirect3DLightVtbl IDirect3DLight_Vtbl; + +/* Helper functions */ +void light_update(IDirect3DLightImpl* This); +void light_activate(IDirect3DLightImpl* This); +void light_desactivate(IDirect3DLightImpl* This); + +/****************************************************************************** + * IDirect3DMaterial implementation structure - Wraps to D3D7 + ******************************************************************************/ +struct IDirect3DMaterialImpl +{ + ICOM_VFIELD_MULTI(IDirect3DMaterial3); + ICOM_VFIELD_MULTI(IDirect3DMaterial2); + ICOM_VFIELD_MULTI(IDirect3DMaterial); + LONG ref; + + /* IDirect3DMaterial2 fields */ + IDirectDrawImpl *ddraw; + IDirect3DDeviceImpl *active_device; + + D3DMATERIAL mat; + + void (*activate)(IDirect3DMaterialImpl* this); +}; + +/* VTables in varios versions */ +const IDirect3DMaterialVtbl IDirect3DMaterial_Vtbl; +const IDirect3DMaterial2Vtbl IDirect3DMaterial2_Vtbl; +const IDirect3DMaterial3Vtbl IDirect3DMaterial3_Vtbl; + +/* Helper functions */ +void material_activate(IDirect3DMaterialImpl* This); + /***************************************************************************** - * Driver initialisation functions. - */ -BOOL DDRAW_HAL_Init(HINSTANCE, DWORD, LPVOID); -BOOL DDRAW_User_Init(HINSTANCE, DWORD, LPVOID); + * IDirect3DViewport - Wraps to D3D7 + *****************************************************************************/ +struct IDirect3DViewportImpl +{ + ICOM_VFIELD_MULTI(IDirect3DViewport3); + LONG ref; -typedef struct { - const DDDEVICEIDENTIFIER2* info; - int preference; /* how good we are. dga might get 100, xlib 50*/ - HRESULT (*create)(const GUID*, LPDIRECTDRAW7*, LPUNKNOWN, BOOL ex); + /* IDirect3DViewport fields */ + IDirectDrawImpl *ddraw; - /* For IDirectDraw7::Initialize. */ - HRESULT (*init)(IDirectDrawImpl *, const GUID*); -} ddraw_driver; + /* If this viewport is active for one device, put the device here */ + IDirect3DDeviceImpl *active_device; -void DDRAW_register_driver(const ddraw_driver*); + DWORD num_lights; + DWORD map_lights; -const ddraw_driver* DDRAW_FindDriver(const GUID* guid); + int use_vp2; -/****************************************************************************** - * Random utilities - */ + union + { + D3DVIEWPORT vp1; + D3DVIEWPORT2 vp2; + } viewports; -/* Get DDSCAPS of surface (shortcutmacro) */ -#define SDDSCAPS(iface) ((iface)->s.surface_desc.ddsCaps.dwCaps) -/* Get the number of bytes per pixel for a given surface */ -#define PFGET_BPP(pf) (pf.dwFlags&DDPF_PALETTEINDEXED8?1:((pf.u1.dwRGBBitCount+7)/8)) -#define GET_BPP(desc) PFGET_BPP(desc.u4.ddpfPixelFormat) + /* Activation function */ + void (*activate)(IDirect3DViewportImpl*); -LONG DDRAW_width_bpp_to_pitch(DWORD width, DWORD bpp); + /* Field used to chain viewports together */ + IDirect3DViewportImpl *next; -typedef struct { - unsigned short bpp,depth; - unsigned int rmask,gmask,bmask; -} ConvertMode; + /* Lights list */ + IDirect3DLightImpl *lights; -typedef struct { - void (*pixel_convert)(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette); - void (*palette_convert)(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count); -} ConvertFuncs; + /* Background material */ + IDirect3DMaterialImpl *background; +}; -typedef struct { - ConvertMode screen, dest; - ConvertFuncs funcs; -} Convert; +/* Vtable */ +const IDirect3DViewport3Vtbl IDirect3DViewport3_Vtbl; -extern Convert ModeEmulations[8]; -extern int _common_depth_to_pixelformat(DWORD depth,LPDIRECTDRAW ddraw); -extern BOOL opengl_initialized; -extern BOOL s3tc_initialized; +/* Helper functions */ +void viewport_activate(IDirect3DViewportImpl* This); -typedef void (*FUNC_FETCH_2D_TEXEL_RGBA_DXT1)(int srcRowStride, const BYTE *pixdata, int i, int j, void *texel); -typedef void (*FUNC_FETCH_2D_TEXEL_RGBA_DXT3)(int srcRowStride, const BYTE *pixdata, int i, int j, void *texel); -typedef void (*FUNC_FETCH_2D_TEXEL_RGBA_DXT5)(int srcRowStride, const BYTE *pixdata, int i, int j, void *texel); +/***************************************************************************** + * IDirect3DExecuteBuffer - Wraps to D3D7 + *****************************************************************************/ +struct IDirect3DExecuteBufferImpl +{ + /* IUnknown */ + ICOM_VFIELD_MULTI(IDirect3DExecuteBuffer); + LONG ref; -extern FUNC_FETCH_2D_TEXEL_RGBA_DXT1 fetch_2d_texel_rgba_dxt1; -extern FUNC_FETCH_2D_TEXEL_RGBA_DXT3 fetch_2d_texel_rgba_dxt3; -extern FUNC_FETCH_2D_TEXEL_RGBA_DXT5 fetch_2d_texel_rgba_dxt5; + /* IDirect3DExecuteBuffer fields */ + IDirectDrawImpl *ddraw; + IDirect3DDeviceImpl *d3ddev; -/****************************************************************************** - * Structure conversion (for thunks) - */ -void DDRAW_Convert_DDSCAPS_1_To_2(const DDSCAPS* pIn, DDSCAPS2* pOut); -void DDRAW_Convert_DDDEVICEIDENTIFIER_2_To_1(const DDDEVICEIDENTIFIER2* pIn, - DDDEVICEIDENTIFIER* pOut); + D3DEXECUTEBUFFERDESC desc; + D3DEXECUTEDATA data; -/****************************************************************************** - * Debugging / Flags output functions - */ -extern void DDRAW_dump_DDBLTFX(DWORD flagmask); -extern void DDRAW_dump_DDBLTFAST(DWORD flagmask); -extern void DDRAW_dump_DDBLT(DWORD flagmask); -extern void DDRAW_dump_DDSCAPS(const DDSCAPS *in); -extern void DDRAW_dump_DDSCAPS2(const DDSCAPS2 *in); -extern void DDRAW_dump_pixelformat_flag(DWORD flagmask); -extern void DDRAW_dump_paletteformat(DWORD dwFlags); -extern void DDRAW_dump_pixelformat(const DDPIXELFORMAT *in); -extern void DDRAW_dump_colorkeyflag(DWORD ck); -extern void DDRAW_dump_surface_desc(const DDSURFACEDESC2 *lpddsd); -extern void DDRAW_dump_cooperativelevel(DWORD cooplevel); -extern void DDRAW_dump_lockflag(DWORD lockflag); -extern void DDRAW_dump_DDCOLORKEY(const DDCOLORKEY *in); -extern void DDRAW_dump_DDCAPS(const DDCAPS *lpcaps); -extern void DDRAW_dump_DDENUMSURFACES(DWORD flagmask); -extern void DDRAW_dump_surface_to_disk(IDirectDrawSurfaceImpl *surface, FILE *f, int scale) ; + /* This buffer will store the transformed vertices */ + void *vertex_data; + WORD *indices; + int nb_indices; + + /* This flags is set to TRUE if we allocated ourselves the + * data buffer + */ + BOOL need_free; +}; + +/* The VTable */ +const IDirect3DExecuteBufferVtbl IDirect3DExecuteBuffer_Vtbl; + +/* The execute function */ +void +IDirect3DExecuteBufferImpl_Execute(IDirect3DExecuteBufferImpl *This, + IDirect3DDeviceImpl *Device, + IDirect3DViewportImpl *ViewportImpl); + +/***************************************************************************** + * IDirect3DVertexBuffer + *****************************************************************************/ +struct IDirect3DVertexBufferImpl +{ + /*** IUnknown Methods ***/ + ICOM_VFIELD_MULTI(IDirect3DVertexBuffer7); + ICOM_VFIELD_MULTI(IDirect3DVertexBuffer); + LONG ref; + + /*** WineD3D link ***/ + IWineD3DVertexBuffer *wineD3DVertexBuffer; + + /*** Storage for D3D7 specific things ***/ + DWORD Caps; +}; + +/* The Vtables */ +const IDirect3DVertexBuffer7Vtbl IDirect3DVertexBuffer7_Vtbl; +const IDirect3DVertexBufferVtbl IDirect3DVertexBuffer1_Vtbl; + +/***************************************************************************** + * Helper functions from utils.c + *****************************************************************************/ + +#define GET_TEXCOUNT_FROM_FVF(d3dvtVertexType) \ + (((d3dvtVertexType) & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT) + +#define GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, tex_num) \ + (((((d3dvtVertexType) >> (16 + (2 * (tex_num)))) + 1) & 0x03) + 1) + +void PixelFormat_WineD3DtoDD(DDPIXELFORMAT *DDPixelFormat, WINED3DFORMAT WineD3DFormat); +WINED3DFORMAT PixelFormat_DD2WineD3D(DDPIXELFORMAT *DDPixelFormat); +void DDRAW_dump_surface_desc(const DDSURFACEDESC2 *lpddsd); +void DDRAW_dump_pixelformat(const DDPIXELFORMAT *PixelFormat); +void dump_D3DMATRIX(D3DMATRIX *mat); +void DDRAW_dump_DDCAPS(const DDCAPS *lpcaps); +DWORD get_flexible_vertex_size(DWORD d3dvtVertexType); +void DDRAW_dump_DDSCAPS2(const DDSCAPS2 *in); +void DDRAW_dump_cooperativelevel(DWORD cooplevel); + +/* This only needs to be here as long the processvertices functionality of + * IDirect3DExecuteBuffer isn't in WineD3D */ +void multiply_matrix(LPD3DMATRIX dest, LPD3DMATRIX src1, LPD3DMATRIX src2); /* Used for generic dumping */ typedef struct @@ -438,701 +597,26 @@ typedef struct ptrdiff_t offset; } member_info; +/* Structure copy */ #define DDRAW_dump_flags(flags,names,num_names) DDRAW_dump_flags_(flags, names, num_names, 1) #define ME(x,f,e) { x, #x, (void (*)(const void *))(f), offsetof(STRUCT, e) } -extern void DDRAW_dump_flags_(DWORD flags, const flag_info* names, size_t num_names, int newline); -extern void DDRAW_dump_members(DWORD flags, const void* data, const member_info* mems, size_t num_mems); - -void DirectDrawSurface_RegisterClass(void); -void DirectDrawSurface_UnregisterClass(void); - -extern const IDirectDrawSurface3Vtbl DDRAW_IDDS3_Thunk_VTable; - -/***************************************************************************** - * IDirectDrawClipper declarations - */ -HRESULT DDRAW_CreateClipper(IUnknown* pUnkOuter, REFIID riid, LPVOID* ppObj); -void Main_DirectDrawClipper_ForceDestroy(IDirectDrawClipperImpl* This); - -HRESULT WINAPI -Main_DirectDrawClipper_SetHwnd(LPDIRECTDRAWCLIPPER iface, DWORD dwFlags, - HWND hWnd); -ULONG WINAPI Main_DirectDrawClipper_Release(LPDIRECTDRAWCLIPPER iface); -HRESULT WINAPI -Main_DirectDrawClipper_GetClipList(LPDIRECTDRAWCLIPPER iface, LPRECT lpRect, - LPRGNDATA lpClipList, LPDWORD lpdwSize); -HRESULT WINAPI -Main_DirectDrawClipper_SetClipList(LPDIRECTDRAWCLIPPER iface,LPRGNDATA lprgn, - DWORD dwFlag); -HRESULT WINAPI -Main_DirectDrawClipper_QueryInterface(LPDIRECTDRAWCLIPPER iface, REFIID riid, - LPVOID* ppvObj); -ULONG WINAPI Main_DirectDrawClipper_AddRef( LPDIRECTDRAWCLIPPER iface ); -HRESULT WINAPI -Main_DirectDrawClipper_GetHWnd(LPDIRECTDRAWCLIPPER iface, HWND* hWndPtr); -HRESULT WINAPI -Main_DirectDrawClipper_Initialize(LPDIRECTDRAWCLIPPER iface, LPDIRECTDRAW lpDD, - DWORD dwFlags); -HRESULT WINAPI -Main_DirectDrawClipper_IsClipListChanged(LPDIRECTDRAWCLIPPER iface, - BOOL* lpbChanged); - -/***************************************************************************** - * IDirectDrawPalette MAIN declarations - */ -HRESULT Main_DirectDrawPalette_Construct(IDirectDrawPaletteImpl* This, - IDirectDrawImpl* pDD, DWORD dwFlags); -void Main_DirectDrawPalette_final_release(IDirectDrawPaletteImpl* This); - -HRESULT Main_DirectDrawPalette_Create(IDirectDrawImpl* pDD, DWORD dwFlags, - LPDIRECTDRAWPALETTE* ppPalette, - LPUNKNOWN pUnkOuter); -void Main_DirectDrawPalette_ForceDestroy(IDirectDrawPaletteImpl* This); - -DWORD Main_DirectDrawPalette_Size(DWORD dwFlags); - -HRESULT WINAPI -Main_DirectDrawPalette_GetEntries(LPDIRECTDRAWPALETTE iface, DWORD dwFlags, - DWORD dwStart, DWORD dwCount, - LPPALETTEENTRY palent); -HRESULT WINAPI -Main_DirectDrawPalette_SetEntries(LPDIRECTDRAWPALETTE iface, DWORD dwFlags, - DWORD dwStart, DWORD dwCount, - LPPALETTEENTRY palent); -ULONG WINAPI -Main_DirectDrawPalette_Release(LPDIRECTDRAWPALETTE iface); -ULONG WINAPI Main_DirectDrawPalette_AddRef(LPDIRECTDRAWPALETTE iface); -HRESULT WINAPI -Main_DirectDrawPalette_Initialize(LPDIRECTDRAWPALETTE iface, - LPDIRECTDRAW ddraw, DWORD dwFlags, - LPPALETTEENTRY palent); -HRESULT WINAPI -Main_DirectDrawPalette_GetCaps(LPDIRECTDRAWPALETTE iface, LPDWORD lpdwCaps); -HRESULT WINAPI -Main_DirectDrawPalette_QueryInterface(LPDIRECTDRAWPALETTE iface, - REFIID refiid, LPVOID *obj); - -/***************************************************************************** - * IDirectDrawPalette HAL declarations - */ -HRESULT HAL_DirectDrawPalette_Construct(IDirectDrawPaletteImpl* This, - IDirectDrawImpl* pDD, DWORD dwFlags); -void HAL_DirectDrawPalette_final_release(IDirectDrawPaletteImpl* This); - -HRESULT HAL_DirectDrawPalette_Create(IDirectDrawImpl* pDD, DWORD dwFlags, - LPDIRECTDRAWPALETTE* ppPalette, - LPUNKNOWN pUnkOuter); - -HRESULT WINAPI -HAL_DirectDrawPalette_SetEntries(LPDIRECTDRAWPALETTE iface, DWORD dwFlags, - DWORD dwStart, DWORD dwCount, - LPPALETTEENTRY palent); - -/***************************************************************************** - * IDirectDraw MAIN declarations - */ -/* internal virtual functions */ -void Main_DirectDraw_final_release(IDirectDrawImpl* This); -HRESULT Main_create_offscreen(IDirectDrawImpl* This, const DDSURFACEDESC2 *pDDSD, - LPDIRECTDRAWSURFACE7* ppSurf, LPUNKNOWN pOuter); -HRESULT Main_create_texture(IDirectDrawImpl* This, const DDSURFACEDESC2 *pDDSD, - LPDIRECTDRAWSURFACE7* ppSurf, LPUNKNOWN pOuter, - DWORD dwMipMapLevel); -HRESULT Main_create_zbuffer(IDirectDrawImpl* This, const DDSURFACEDESC2 *pDDSD, - LPDIRECTDRAWSURFACE7* ppSurf, LPUNKNOWN pOuter); - -/* internal functions */ -HRESULT Main_DirectDraw_Construct(IDirectDrawImpl *This, BOOL ex); -void Main_DirectDraw_AddSurface(IDirectDrawImpl* This, - IDirectDrawSurfaceImpl* surface); -void Main_DirectDraw_RemoveSurface(IDirectDrawImpl* This, - IDirectDrawSurfaceImpl* surface); -void Main_DirectDraw_AddClipper(IDirectDrawImpl* This, - IDirectDrawClipperImpl* clipper); -void Main_DirectDraw_RemoveClipper(IDirectDrawImpl* This, - IDirectDrawClipperImpl* clipper); -void Main_DirectDraw_AddPalette(IDirectDrawImpl* This, - IDirectDrawPaletteImpl* palette); -void Main_DirectDraw_RemovePalette(IDirectDrawImpl* This, - IDirectDrawPaletteImpl* palette); - -/* interface functions */ -ULONG WINAPI Main_DirectDraw_AddRef(LPDIRECTDRAW7 iface); -ULONG WINAPI Main_DirectDraw_Release(LPDIRECTDRAW7 iface); -HRESULT WINAPI Main_DirectDraw_QueryInterface(LPDIRECTDRAW7 iface, - REFIID refiid,LPVOID *obj); -HRESULT WINAPI Main_DirectDraw_Compact(LPDIRECTDRAW7 iface); -HRESULT WINAPI Main_DirectDraw_CreateClipper(LPDIRECTDRAW7 iface, - DWORD dwFlags, - LPDIRECTDRAWCLIPPER *ppClipper, - IUnknown *pUnkOuter); -HRESULT WINAPI -Main_DirectDraw_CreatePalette(LPDIRECTDRAW7 iface, DWORD dwFlags, - LPPALETTEENTRY palent, - LPDIRECTDRAWPALETTE* ppPalette, - LPUNKNOWN pUnknown); -HRESULT WINAPI -Main_DirectDraw_CreateSurface(LPDIRECTDRAW7 iface, LPDDSURFACEDESC2 pDDSD, - LPDIRECTDRAWSURFACE7 *ppSurf, - IUnknown *pUnkOuter); -HRESULT WINAPI -Main_DirectDraw_DuplicateSurface(LPDIRECTDRAW7 iface, LPDIRECTDRAWSURFACE7 src, - LPDIRECTDRAWSURFACE7* dst); -HRESULT WINAPI -Main_DirectDraw_EnumSurfaces(LPDIRECTDRAW7 iface, DWORD dwFlags, - LPDDSURFACEDESC2 lpDDSD2, LPVOID context, - LPDDENUMSURFACESCALLBACK7 callback); -HRESULT WINAPI -Main_DirectDraw_EvaluateMode(LPDIRECTDRAW7 iface,DWORD a,DWORD* b); -HRESULT WINAPI Main_DirectDraw_FlipToGDISurface(LPDIRECTDRAW7 iface); -HRESULT WINAPI -Main_DirectDraw_GetCaps(LPDIRECTDRAW7 iface, LPDDCAPS pDriverCaps, - LPDDCAPS pHELCaps); -HRESULT WINAPI -Main_DirectDraw_GetFourCCCodes(LPDIRECTDRAW7 iface, LPDWORD pNumCodes, - LPDWORD pCodes); -HRESULT WINAPI -Main_DirectDraw_GetGDISurface(LPDIRECTDRAW7 iface, - LPDIRECTDRAWSURFACE7 *lplpGDIDDSSurface); -HRESULT WINAPI -Main_DirectDraw_GetMonitorFrequency(LPDIRECTDRAW7 iface,LPDWORD freq); -HRESULT WINAPI -Main_DirectDraw_GetScanLine(LPDIRECTDRAW7 iface, LPDWORD lpdwScanLine); -HRESULT WINAPI -Main_DirectDraw_GetSurfaceFromDC(LPDIRECTDRAW7 iface, HDC hdc, - LPDIRECTDRAWSURFACE7 *lpDDS); -HRESULT WINAPI -Main_DirectDraw_GetVerticalBlankStatus(LPDIRECTDRAW7 iface, LPBOOL status); -HRESULT WINAPI -Main_DirectDraw_Initialize(LPDIRECTDRAW7 iface, LPGUID lpGuid); -HRESULT WINAPI Main_DirectDraw_RestoreAllSurfaces(LPDIRECTDRAW7 iface); -HRESULT WINAPI -Main_DirectDraw_SetCooperativeLevel(LPDIRECTDRAW7 iface, HWND hwnd, - DWORD cooplevel); -HRESULT WINAPI -Main_DirectDraw_SetDisplayMode(LPDIRECTDRAW7 iface, DWORD dwWidth, - DWORD dwHeight, LONG lPitch, - DWORD dwRefreshRate, DWORD dwFlags, - const DDPIXELFORMAT* pixelformat); -HRESULT WINAPI Main_DirectDraw_RestoreDisplayMode(LPDIRECTDRAW7 iface); -HRESULT WINAPI -Main_DirectDraw_WaitForVerticalBlank(LPDIRECTDRAW7 iface, DWORD dwFlags, - HANDLE h); -HRESULT WINAPI -Main_DirectDraw_GetDisplayMode(LPDIRECTDRAW7 iface, LPDDSURFACEDESC2 pDDSD); -HRESULT WINAPI -Main_DirectDraw_GetAvailableVidMem(LPDIRECTDRAW7 iface,LPDDSCAPS2 ddscaps, - LPDWORD total, LPDWORD free); -HRESULT WINAPI Main_DirectDraw_TestCooperativeLevel(LPDIRECTDRAW7 iface); -HRESULT WINAPI -Main_DirectDraw_StartModeTest(LPDIRECTDRAW7 iface, LPSIZE pModes, - DWORD dwNumModes, DWORD dwFlags); - -/***************************************************************************** - * IDirectDraw USER object declarations - */ -#define USER_DDRAW_PRIV(ddraw) ((User_DirectDrawImpl*)((ddraw)->private)) -#define USER_DDRAW_PRIV_VAR(name,ddraw) \ - User_DirectDrawImpl* name = USER_DDRAW_PRIV(ddraw) - -typedef struct -{ - int empty; - /* empty */ -} User_DirectDrawImpl_Part; - -typedef struct -{ - User_DirectDrawImpl_Part user; -} User_DirectDrawImpl; - -void User_DirectDraw_final_release(IDirectDrawImpl* This); -HRESULT User_DirectDraw_create_primary(IDirectDrawImpl* This, - const DDSURFACEDESC2* pDDSD, - LPDIRECTDRAWSURFACE7* ppSurf, - LPUNKNOWN pOuter); -HRESULT User_DirectDraw_create_backbuffer(IDirectDrawImpl* This, - const DDSURFACEDESC2* pDDSD, - LPDIRECTDRAWSURFACE7* ppSurf, - LPUNKNOWN pOuter, - IDirectDrawSurfaceImpl* primary); -HRESULT User_DirectDraw_Construct(IDirectDrawImpl *This, BOOL ex); -HRESULT User_DirectDraw_Create(const GUID* pGUID, LPDIRECTDRAW7* pIface, - IUnknown* pUnkOuter, BOOL ex); - -HRESULT WINAPI -User_DirectDraw_EnumDisplayModes(LPDIRECTDRAW7 iface, DWORD dwFlags, - LPDDSURFACEDESC2 pDDSD, LPVOID context, - LPDDENUMMODESCALLBACK2 callback); -HRESULT WINAPI -User_DirectDraw_GetDeviceIdentifier(LPDIRECTDRAW7 iface, - LPDDDEVICEIDENTIFIER2 pDDDI, - DWORD dwFlags); -HRESULT WINAPI -User_DirectDraw_SetDisplayMode(LPDIRECTDRAW7 iface, DWORD dwWidth, - DWORD dwHeight, DWORD dwBPP, - DWORD dwRefreshRate, DWORD dwFlags); - -/***************************************************************************** - * IDirectDraw HAL declarations - */ -#define HAL_DDRAW_PRIV(ddraw) \ - ((HAL_DirectDrawImpl*)((ddraw)->private)) -#define HAL_DDRAW_PRIV_VAR(name,ddraw) \ - HAL_DirectDrawImpl* name = HAL_DDRAW_PRIV(ddraw) - -typedef struct -{ - DWORD next_vofs; -} HAL_DirectDrawImpl_Part; - -typedef struct -{ - User_DirectDrawImpl_Part user; - HAL_DirectDrawImpl_Part hal; -} HAL_DirectDrawImpl; - -void HAL_DirectDraw_final_release(IDirectDrawImpl* This); -HRESULT HAL_DirectDraw_create_primary(IDirectDrawImpl* This, - const DDSURFACEDESC2* pDDSD, - LPDIRECTDRAWSURFACE7* ppSurf, - LPUNKNOWN pOuter); -HRESULT HAL_DirectDraw_create_backbuffer(IDirectDrawImpl* This, - const DDSURFACEDESC2* pDDSD, - LPDIRECTDRAWSURFACE7* ppSurf, - LPUNKNOWN pOuter, - IDirectDrawSurfaceImpl* primary); -HRESULT HAL_DirectDraw_create_texture(IDirectDrawImpl* This, - const DDSURFACEDESC2* pDDSD, - LPDIRECTDRAWSURFACE7* ppSurf, - LPUNKNOWN pOuter, - DWORD dwMipMapLevel); - -HRESULT HAL_DirectDraw_Construct(IDirectDrawImpl *This, BOOL ex); -HRESULT HAL_DirectDraw_Create(const GUID* pGUID, LPDIRECTDRAW7* pIface, - IUnknown* pUnkOuter, BOOL ex); - -HRESULT WINAPI -HAL_DirectDraw_GetDeviceIdentifier(LPDIRECTDRAW7 iface, - LPDDDEVICEIDENTIFIER2 pDDDI, - DWORD dwFlags); -HRESULT WINAPI -HAL_DirectDraw_SetDisplayMode(LPDIRECTDRAW7 iface, DWORD dwWidth, - DWORD dwHeight, DWORD dwBPP, - DWORD dwRefreshRate, DWORD dwFlags); -HRESULT WINAPI HAL_DirectDraw_RestoreDisplayMode(LPDIRECTDRAW7 iface); - -/***************************************************************************** - * IDirectDrawSurface MAIN declarations - */ -/* Support for IDirectDrawSurface7::Set/Get/FreePrivateData. I don't think - * anybody uses it for much so a good implementation is optional. */ -typedef struct PrivateData -{ - struct PrivateData* next; - struct PrivateData* prev; - - GUID tag; - DWORD flags; /* DDSPD_* */ - DWORD uniqueness_value; - - union - { - LPVOID data; - LPUNKNOWN object; - } ptr; - - DWORD size; -} PrivateData; - -extern const IDirectDrawGammaControlVtbl DDRAW_IDDGC_VTable; - -/* Non-interface functions */ -HRESULT Main_DirectDrawSurface_Construct(IDirectDrawSurfaceImpl* This, - IDirectDrawImpl* pDD, - const DDSURFACEDESC2* pDDSD); -void Main_DirectDrawSurface_ForceDestroy(IDirectDrawSurfaceImpl* This); - -void Main_DirectDrawSurface_final_release(IDirectDrawSurfaceImpl* This); -HRESULT Main_DirectDrawSurface_late_allocate(IDirectDrawSurfaceImpl* This); -BOOL Main_DirectDrawSurface_attach(IDirectDrawSurfaceImpl *This, - IDirectDrawSurfaceImpl *to); -BOOL Main_DirectDrawSurface_detach(IDirectDrawSurfaceImpl *This); -void Main_DirectDrawSurface_lock_update(IDirectDrawSurfaceImpl* This, - LPCRECT pRect, DWORD dwFlags); -void Main_DirectDrawSurface_unlock_update(IDirectDrawSurfaceImpl* This, - LPCRECT pRect); -void Main_DirectDrawSurface_lose_surface(IDirectDrawSurfaceImpl* This); -void Main_DirectDrawSurface_set_palette(IDirectDrawSurfaceImpl* This, - IDirectDrawPaletteImpl* pal); -void Main_DirectDrawSurface_update_palette(IDirectDrawSurfaceImpl* This, - IDirectDrawPaletteImpl* pal, - DWORD dwStart, DWORD dwCount, - LPPALETTEENTRY palent); -HWND Main_DirectDrawSurface_get_display_window(IDirectDrawSurfaceImpl* This); - -HRESULT Main_DirectDrawSurface_get_gamma_ramp(IDirectDrawSurfaceImpl* This, - DWORD dwFlags, - LPDDGAMMARAMP lpGammaRamp); -HRESULT Main_DirectDrawSurface_set_gamma_ramp(IDirectDrawSurfaceImpl* This, - DWORD dwFlags, - LPDDGAMMARAMP lpGammaRamp); - -BOOL Main_DirectDrawSurface_flip_data(IDirectDrawSurfaceImpl* front, - IDirectDrawSurfaceImpl* back, - DWORD dwFlags); - -#define CHECK_LOST(This) \ - do { \ - if (This->lost) return DDERR_SURFACELOST; \ - } while (0) - -#define CHECK_TEXTURE(This) \ - do { \ - if (!(This->surface_desc.ddsCaps.dwCaps2 \ - & DDSCAPS2_TEXTUREMANAGE)) \ - return DDERR_INVALIDOBJECT; \ - } while (0) - -#define LOCK_OBJECT(This) do { } while (0) -#define UNLOCK_OBJECT(This) do { } while (0) - -/* IDirectDrawSurface7 (partial) implementation */ -ULONG WINAPI Main_DirectDrawSurface_AddRef(LPDIRECTDRAWSURFACE7 iface); -ULONG WINAPI Main_DirectDrawSurface_Release(LPDIRECTDRAWSURFACE7 iface); -HRESULT WINAPI -Main_DirectDrawSurface_QueryInterface(LPDIRECTDRAWSURFACE7 iface, REFIID riid, - LPVOID* ppObj); -HRESULT WINAPI -Main_DirectDrawSurface_AddAttachedSurface(LPDIRECTDRAWSURFACE7 iface, - LPDIRECTDRAWSURFACE7 pAttach); -HRESULT WINAPI -Main_DirectDrawSurface_AddOverlayDirtyRect(LPDIRECTDRAWSURFACE7 iface, - LPRECT pRect); -HRESULT WINAPI -Main_DirectDrawSurface_BltBatch(LPDIRECTDRAWSURFACE7 iface, - LPDDBLTBATCH pBatch, DWORD dwCount, - DWORD dwFlags); -HRESULT WINAPI -Main_DirectDrawSurface_ChangeUniquenessValue(LPDIRECTDRAWSURFACE7 iface); -HRESULT WINAPI -Main_DirectDrawSurface_DeleteAttachedSurface(LPDIRECTDRAWSURFACE7 iface, - DWORD dwFlags, - LPDIRECTDRAWSURFACE7 pAttach); -HRESULT WINAPI -Main_DirectDrawSurface_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE7 iface, - LPVOID context, - LPDDENUMSURFACESCALLBACK7 cb); -HRESULT WINAPI -Main_DirectDrawSurface_EnumOverlayZOrders(LPDIRECTDRAWSURFACE7 iface, - DWORD dwFlags, LPVOID context, - LPDDENUMSURFACESCALLBACK7 cb); -HRESULT WINAPI -Main_DirectDrawSurface_Flip(LPDIRECTDRAWSURFACE7 iface, - LPDIRECTDRAWSURFACE7 override, DWORD dwFlags); -HRESULT WINAPI -Main_DirectDrawSurface_FreePrivateData(LPDIRECTDRAWSURFACE7 iface, - REFGUID tag); -HRESULT WINAPI -Main_DirectDrawSurface_GetAttachedSurface(LPDIRECTDRAWSURFACE7 iface, - LPDDSCAPS2 pCaps, - LPDIRECTDRAWSURFACE7* ppSurface); -HRESULT WINAPI -Main_DirectDrawSurface_GetBltStatus(LPDIRECTDRAWSURFACE7 iface, - DWORD dwFlags); -HRESULT WINAPI -Main_DirectDrawSurface_GetCaps(LPDIRECTDRAWSURFACE7 iface, - LPDDSCAPS2 pCaps); -HRESULT WINAPI -Main_DirectDrawSurface_GetClipper(LPDIRECTDRAWSURFACE7 iface, - LPDIRECTDRAWCLIPPER* ppClipper); -HRESULT WINAPI -Main_DirectDrawSurface_GetColorKey(LPDIRECTDRAWSURFACE7 iface, - DWORD dwFlags, LPDDCOLORKEY pCKey); -HRESULT WINAPI -Main_DirectDrawSurface_GetDC(LPDIRECTDRAWSURFACE7 iface, HDC *phDC); -HRESULT WINAPI -Main_DirectDrawSurface_GetDDInterface(LPDIRECTDRAWSURFACE7 iface, - LPVOID* pDD); -HRESULT WINAPI -Main_DirectDrawSurface_GetFlipStatus(LPDIRECTDRAWSURFACE7 iface, - DWORD dwFlags); -HRESULT WINAPI -Main_DirectDrawSurface_GetLOD(LPDIRECTDRAWSURFACE7 iface, - LPDWORD pdwMaxLOD); -HRESULT WINAPI -Main_DirectDrawSurface_GetOverlayPosition(LPDIRECTDRAWSURFACE7 iface, - LPLONG pX, LPLONG pY); -HRESULT WINAPI -Main_DirectDrawSurface_GetPalette(LPDIRECTDRAWSURFACE7 iface, - LPDIRECTDRAWPALETTE* ppPalette); -HRESULT WINAPI -Main_DirectDrawSurface_GetPixelFormat(LPDIRECTDRAWSURFACE7 iface, - LPDDPIXELFORMAT pDDPixelFormat); -HRESULT WINAPI -Main_DirectDrawSurface_GetPriority(LPDIRECTDRAWSURFACE7 iface, - LPDWORD pdwPriority); -HRESULT WINAPI -Main_DirectDrawSurface_GetPrivateData(LPDIRECTDRAWSURFACE7 iface, REFGUID tag, - LPVOID pBuffer, LPDWORD pcbBufferSize); -HRESULT WINAPI -Main_DirectDrawSurface_GetSurfaceDesc(LPDIRECTDRAWSURFACE7 iface, - LPDDSURFACEDESC2 pDDSD); -HRESULT WINAPI -Main_DirectDrawSurface_GetUniquenessValue(LPDIRECTDRAWSURFACE7 iface, - LPDWORD pValue); -HRESULT WINAPI -Main_DirectDrawSurface_Initialize(LPDIRECTDRAWSURFACE7 iface, - LPDIRECTDRAW pDD, LPDDSURFACEDESC2 pDDSD); -HRESULT WINAPI -Main_DirectDrawSurface_IsLost(LPDIRECTDRAWSURFACE7 iface); -HRESULT WINAPI -Main_DirectDrawSurface_Lock(LPDIRECTDRAWSURFACE7 iface, LPRECT prect, - LPDDSURFACEDESC2 pDDSD, DWORD flags, HANDLE h); -HRESULT WINAPI -Main_DirectDrawSurface_PageLock(LPDIRECTDRAWSURFACE7 iface, DWORD dwFlags); -HRESULT WINAPI -Main_DirectDrawSurface_PageUnlock(LPDIRECTDRAWSURFACE7 iface, DWORD dwFlags); -HRESULT WINAPI -Main_DirectDrawSurface_ReleaseDC(LPDIRECTDRAWSURFACE7 iface, HDC hDC); -HRESULT WINAPI -Main_DirectDrawSurface_SetClipper(LPDIRECTDRAWSURFACE7 iface, - LPDIRECTDRAWCLIPPER pDDClipper); -HRESULT WINAPI -Main_DirectDrawSurface_SetColorKey(LPDIRECTDRAWSURFACE7 iface, - DWORD dwFlags, LPDDCOLORKEY pCKey); -HRESULT WINAPI -Main_DirectDrawSurface_SetLOD(LPDIRECTDRAWSURFACE7 iface, DWORD dwMaxLOD); -HRESULT WINAPI -Main_DirectDrawSurface_SetOverlayPosition(LPDIRECTDRAWSURFACE7 iface, - LONG X, LONG Y); -HRESULT WINAPI -Main_DirectDrawSurface_SetPalette(LPDIRECTDRAWSURFACE7 iface, - LPDIRECTDRAWPALETTE pPalette); -HRESULT WINAPI -Main_DirectDrawSurface_SetPriority(LPDIRECTDRAWSURFACE7 iface, - DWORD dwPriority); -HRESULT WINAPI -Main_DirectDrawSurface_SetPrivateData(LPDIRECTDRAWSURFACE7 iface, - REFGUID tag, LPVOID pData, - DWORD cbSize, DWORD dwFlags); -HRESULT WINAPI -Main_DirectDrawSurface_Unlock(LPDIRECTDRAWSURFACE7 iface, LPRECT pRect); -HRESULT WINAPI -Main_DirectDrawSurface_UpdateOverlay(LPDIRECTDRAWSURFACE7 iface, - LPRECT pSrcRect, - LPDIRECTDRAWSURFACE7 pDstSurface, - LPRECT pDstRect, DWORD dwFlags, - LPDDOVERLAYFX pFX); -HRESULT WINAPI -Main_DirectDrawSurface_UpdateOverlayDisplay(LPDIRECTDRAWSURFACE7 iface, - DWORD dwFlags); -HRESULT WINAPI -Main_DirectDrawSurface_UpdateOverlayZOrder(LPDIRECTDRAWSURFACE7 iface, - DWORD dwFlags, - LPDIRECTDRAWSURFACE7 pDDSRef); - -/***************************************************************************** - * IDirectDrawSurface DIB declarations - */ -#define DIB_PRIV(surf) ((DIB_DirectDrawSurfaceImpl*)((surf)->private)) - -#define DIB_PRIV_VAR(name, surf) \ - DIB_DirectDrawSurfaceImpl* name = DIB_PRIV(surf) - -struct DIB_DirectDrawSurfaceImpl_Part -{ - HBITMAP DIBsection; - void* bitmap_data; - HGDIOBJ holdbitmap; - BOOL client_memory; - DWORD d3d_data[4]; /* room for Direct3D driver data */ -}; - -typedef struct -{ - struct DIB_DirectDrawSurfaceImpl_Part dib; -} DIB_DirectDrawSurfaceImpl; - -HRESULT -DIB_DirectDrawSurface_Construct(IDirectDrawSurfaceImpl *This, - IDirectDrawImpl *pDD, - const DDSURFACEDESC2 *pDDSD); -HRESULT -DIB_DirectDrawSurface_Create(IDirectDrawImpl *pDD, - const DDSURFACEDESC2 *pDDSD, - LPDIRECTDRAWSURFACE7 *ppSurf, - IUnknown *pUnkOuter); - -void DIB_DirectDrawSurface_final_release(IDirectDrawSurfaceImpl* This); -BOOL DIB_DirectDrawSurface_flip_data(IDirectDrawSurfaceImpl* front, - IDirectDrawSurfaceImpl* back, - DWORD dwFlags); - -void DIB_DirectDrawSurface_set_palette(IDirectDrawSurfaceImpl* This, - IDirectDrawPaletteImpl* pal); -void DIB_DirectDrawSurface_update_palette(IDirectDrawSurfaceImpl* This, - IDirectDrawPaletteImpl* pal, - DWORD dwStart, DWORD dwCount, - LPPALETTEENTRY palent); - -HRESULT DIB_DirectDrawSurface_get_dc(IDirectDrawSurfaceImpl* This, HDC* phDC); -HRESULT DIB_DirectDrawSurface_release_dc(IDirectDrawSurfaceImpl* This,HDC hDC); - -HRESULT DIB_DirectDrawSurface_alloc_dc(IDirectDrawSurfaceImpl* This,HDC* phDC); -HRESULT DIB_DirectDrawSurface_free_dc(IDirectDrawSurfaceImpl* This, HDC hDC); - -HRESULT WINAPI -DIB_DirectDrawSurface_Blt(LPDIRECTDRAWSURFACE7 iface, LPRECT prcDest, - LPDIRECTDRAWSURFACE7 pSrcSurf, LPRECT prcSrc, - DWORD dwFlags, LPDDBLTFX pBltFx); -HRESULT WINAPI -DIB_DirectDrawSurface_BltFast(LPDIRECTDRAWSURFACE7 iface, DWORD dwX, - DWORD dwY, LPDIRECTDRAWSURFACE7 pSrcSurf, - LPRECT prcSrc, DWORD dwTrans); -HRESULT WINAPI DIB_DirectDrawSurface_Restore(LPDIRECTDRAWSURFACE7 iface); -HRESULT WINAPI -DIB_DirectDrawSurface_SetSurfaceDesc(LPDIRECTDRAWSURFACE7 iface, - LPDDSURFACEDESC2 pDDSD, DWORD dwFlags); - -/***************************************************************************** - * IDirectDrawSurface USER declarations - */ -#define USER_PRIV(surf) ((User_DirectDrawSurfaceImpl*)((surf)->private)) - -#define USER_PRIV_VAR(name,surf) \ - User_DirectDrawSurfaceImpl* name = USER_PRIV(surf) - -struct User_DirectDrawSurfaceImpl_Part -{ - HWND window; - HDC cached_dc; - HANDLE update_thread, update_event, refresh_event; - volatile int wait_count, in_refresh; - CRITICAL_SECTION crit; -}; - -typedef struct -{ - struct DIB_DirectDrawSurfaceImpl_Part dib; - struct User_DirectDrawSurfaceImpl_Part user; -} User_DirectDrawSurfaceImpl; - -HRESULT User_DirectDrawSurface_Construct(IDirectDrawSurfaceImpl* This, - IDirectDrawImpl* pDD, - const DDSURFACEDESC2* pDDSD); - -HRESULT User_DirectDrawSurface_Create(IDirectDrawImpl *pDD, - const DDSURFACEDESC2 *pDDSD, - LPDIRECTDRAWSURFACE7 *ppSurf, - IUnknown *pUnkOuter); - -void User_DirectDrawSurface_final_release(IDirectDrawSurfaceImpl* This); - -void User_DirectDrawSurface_lock_update(IDirectDrawSurfaceImpl* This, - LPCRECT pRect, DWORD dwFlags); -void User_DirectDrawSurface_unlock_update(IDirectDrawSurfaceImpl* This, - LPCRECT pRect); -void User_DirectDrawSurface_set_palette(IDirectDrawSurfaceImpl* This, - IDirectDrawPaletteImpl* pal); -void User_DirectDrawSurface_update_palette(IDirectDrawSurfaceImpl* This, - IDirectDrawPaletteImpl* pal, - DWORD dwStart, DWORD dwCount, - LPPALETTEENTRY palent); -HRESULT User_DirectDrawSurface_duplicate_surface(IDirectDrawSurfaceImpl* This, - LPDIRECTDRAWSURFACE7* ppDup); -BOOL User_DirectDrawSurface_flip_data(IDirectDrawSurfaceImpl* front, - IDirectDrawSurfaceImpl* back, - DWORD dwFlags); -void User_DirectDrawSurface_flip_update(IDirectDrawSurfaceImpl* This, - DWORD dwFlags); -HWND User_DirectDrawSurface_get_display_window(IDirectDrawSurfaceImpl* This); - -HRESULT User_DirectDrawSurface_get_dc(IDirectDrawSurfaceImpl* This, HDC* phDC); -HRESULT User_DirectDrawSurface_release_dc(IDirectDrawSurfaceImpl* This, - HDC hDC); - -HRESULT User_DirectDrawSurface_get_gamma_ramp(IDirectDrawSurfaceImpl* This, - DWORD dwFlags, - LPDDGAMMARAMP lpGammaRamp); -HRESULT User_DirectDrawSurface_set_gamma_ramp(IDirectDrawSurfaceImpl* This, - DWORD dwFlags, - LPDDGAMMARAMP lpGammaRamp); - -/***************************************************************************** - * IDirectDrawSurface HAL declarations - */ -#define HAL_PRIV(surf) ((HAL_DirectDrawSurfaceImpl*)((surf)->private)) - -#define HAL_PRIV_VAR(name,surf) \ - HAL_DirectDrawSurfaceImpl* name = HAL_PRIV(surf) - -struct HAL_DirectDrawSurfaceImpl_Part -{ - DWORD need_late; - LPVOID fb_addr; - DWORD fb_pitch, fb_vofs; -}; - -typedef struct -{ - struct DIB_DirectDrawSurfaceImpl_Part dib; - struct User_DirectDrawSurfaceImpl_Part user; - struct HAL_DirectDrawSurfaceImpl_Part hal; -} HAL_DirectDrawSurfaceImpl; - -HRESULT HAL_DirectDrawSurface_Construct(IDirectDrawSurfaceImpl* This, - IDirectDrawImpl* pDD, - const DDSURFACEDESC2* pDDSD); - -HRESULT HAL_DirectDrawSurface_Create(IDirectDrawImpl *pDD, - const DDSURFACEDESC2 *pDDSD, - LPDIRECTDRAWSURFACE7 *ppSurf, - IUnknown *pUnkOuter); - -void HAL_DirectDrawSurface_final_release(IDirectDrawSurfaceImpl* This); -HRESULT HAL_DirectDrawSurface_late_allocate(IDirectDrawSurfaceImpl* This); - -void HAL_DirectDrawSurface_set_palette(IDirectDrawSurfaceImpl* This, - IDirectDrawPaletteImpl* pal); -void HAL_DirectDrawSurface_update_palette(IDirectDrawSurfaceImpl* This, - IDirectDrawPaletteImpl* pal, - DWORD dwStart, DWORD dwCount, - LPPALETTEENTRY palent); -HRESULT HAL_DirectDrawSurface_duplicate_surface(IDirectDrawSurfaceImpl* This, - LPDIRECTDRAWSURFACE7* ppDup); -void HAL_DirectDrawSurface_lock_update(IDirectDrawSurfaceImpl* This, - LPCRECT pRect, DWORD dwFlags); -void HAL_DirectDrawSurface_unlock_update(IDirectDrawSurfaceImpl* This, - LPCRECT pRect); -BOOL HAL_DirectDrawSurface_flip_data(IDirectDrawSurfaceImpl* front, - IDirectDrawSurfaceImpl* back, - DWORD dwFlags); -void HAL_DirectDrawSurface_flip_update(IDirectDrawSurfaceImpl* This, - DWORD dwFlags); -HWND HAL_DirectDrawSurface_get_display_window(IDirectDrawSurfaceImpl* This); - -/***************************************************************************** - * IDirectDrawSurface FAKEZBUFFER declarations - */ -typedef struct -{ - BOOLEAN in_memory; -} FakeZBuffer_DirectDrawSurfaceImpl; - -HRESULT FakeZBuffer_DirectDrawSurface_Construct(IDirectDrawSurfaceImpl* This, - IDirectDrawImpl* pDD, - const DDSURFACEDESC2* pDDSD); - -HRESULT FakeZBuffer_DirectDrawSurface_Create(IDirectDrawImpl* pDD, - const DDSURFACEDESC2* pDDSD, - LPDIRECTDRAWSURFACE7* ppSurf, - IUnknown* pUnkOuter); - -void FakeZBuffer_DirectDrawSurface_final_release(IDirectDrawSurfaceImpl* This); - -HRESULT FakeZBuffer_DirectDrawSurface_duplicate_surface(IDirectDrawSurfaceImpl* This, - LPDIRECTDRAWSURFACE7* ppDup); - -#endif /* __WINE_DLLS_DDRAW_DDRAW_PRIVATE_H */ +#define DD_STRUCT_COPY_BYSIZE(to,from) \ + do { \ + DWORD __size = (to)->dwSize; \ + DWORD __copysize = __size; \ + DWORD __resetsize = __size; \ + assert(to != from); \ + if (__resetsize > sizeof(*to)) \ + __resetsize = sizeof(*to); \ + memset(to,0,__resetsize); \ + if ((from)->dwSize < __size) \ + __copysize = (from)->dwSize; \ + memcpy(to,from,__copysize); \ + (to)->dwSize = __size;/*restore size*/ \ + } while (0) + + +#endif + +HRESULT hr_ddraw_from_wined3d(HRESULT hr); diff --git a/dlls/ddraw/ddraw_thunks.c b/dlls/ddraw/ddraw_thunks.c index ac93f72713..883411310d 100644 --- a/dlls/ddraw/ddraw_thunks.c +++ b/dlls/ddraw/ddraw_thunks.c @@ -15,6 +15,9 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ + +#include "config.h" + #include #include "windef.h" @@ -205,6 +208,7 @@ IDirectDrawImpl_CreateSurface(LPDIRECTDRAW This, LPDDSURFACEDESC pSDesc, IUnknown *pUnkOuter) { LPDIRECTDRAWSURFACE7 pSurface7; + IDirectDrawSurfaceImpl *impl; HRESULT hr; /* the LPDDSURFACEDESC -> LPDDSURFACEDESC2 conversion should be ok, @@ -221,6 +225,12 @@ IDirectDrawImpl_CreateSurface(LPDIRECTDRAW This, LPDDSURFACEDESC pSDesc, IDirectDrawSurface7, IDirectDrawSurface3, pSurface7); + impl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, pSurface7); + if(impl) + { + impl->version = 1; + } + return hr; } @@ -230,6 +240,7 @@ IDirectDraw2Impl_CreateSurface(LPDIRECTDRAW2 This, LPDDSURFACEDESC pSDesc, IUnknown *pUnkOuter) { LPDIRECTDRAWSURFACE7 pSurface7; + IDirectDrawSurfaceImpl *impl; HRESULT hr; hr = IDirectDraw7_CreateSurface(COM_INTERFACE_CAST(IDirectDrawImpl, @@ -244,6 +255,12 @@ IDirectDraw2Impl_CreateSurface(LPDIRECTDRAW2 This, LPDDSURFACEDESC pSDesc, IDirectDrawSurface7, IDirectDrawSurface3, pSurface7); + impl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, pSurface7); + if(impl) + { + impl->version = 2; + } + return hr; } @@ -252,13 +269,22 @@ IDirectDraw4Impl_CreateSurface(LPDIRECTDRAW4 This, LPDDSURFACEDESC2 pSDesc, LPDIRECTDRAWSURFACE4 *ppSurface, IUnknown *pUnkOuter) { - return IDirectDraw7_CreateSurface(COM_INTERFACE_CAST(IDirectDrawImpl, - IDirectDraw4, - IDirectDraw7, - This), - pSDesc, - (LPDIRECTDRAWSURFACE7 *)ppSurface, - pUnkOuter); + HRESULT hr; + IDirectDrawSurfaceImpl *impl; + + hr = IDirectDraw7_CreateSurface(COM_INTERFACE_CAST(IDirectDrawImpl, + IDirectDraw4, + IDirectDraw7, + This), + pSDesc, + (LPDIRECTDRAWSURFACE7 *)ppSurface, + pUnkOuter); + impl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, *ppSurface); + if(impl) + { + impl->version = 4; + } + return hr; } static HRESULT WINAPI @@ -709,10 +735,7 @@ IDirectDrawImpl_Initialize(LPDIRECTDRAW iface, LPGUID pGUID) HRESULT ret_value; ret_value = IDirectDraw7_Initialize(ICOM_INTERFACE(This, IDirectDraw7), pGUID); - - /* Overwrite the falsely set 'DIRECTDRAW7' flag */ - This->local.dwLocalFlags &= ~DDRAWILCL_DIRECTDRAW7; - + return ret_value; } @@ -721,12 +744,9 @@ IDirectDraw2Impl_Initialize(LPDIRECTDRAW2 iface, LPGUID pGUID) { ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw2, iface); HRESULT ret_value; - + ret_value = IDirectDraw7_Initialize(ICOM_INTERFACE(This, IDirectDraw7), pGUID); - /* Overwrite the falsely set 'DIRECTDRAW7' flag */ - This->local.dwLocalFlags &= ~DDRAWILCL_DIRECTDRAW7; - return ret_value; } @@ -735,12 +755,9 @@ IDirectDraw4Impl_Initialize(LPDIRECTDRAW4 iface, LPGUID pGUID) { ICOM_THIS_FROM(IDirectDrawImpl, IDirectDraw4, iface); HRESULT ret_value; - + ret_value = IDirectDraw7_Initialize(ICOM_INTERFACE(This, IDirectDraw7), pGUID); - - /* Overwrite the falsely set 'DIRECTDRAW7' flag */ - This->local.dwLocalFlags &= ~DDRAWILCL_DIRECTDRAW7; - + return ret_value; } @@ -942,7 +959,7 @@ IDirectDraw4Impl_GetDeviceIdentifier(LPDIRECTDRAW4 This, return hr; } -const IDirectDrawVtbl DDRAW_IDirectDraw_VTable = +const IDirectDrawVtbl IDirectDraw1_Vtbl = { IDirectDrawImpl_QueryInterface, IDirectDrawImpl_AddRef, @@ -969,7 +986,7 @@ const IDirectDrawVtbl DDRAW_IDirectDraw_VTable = IDirectDrawImpl_WaitForVerticalBlank, }; -const IDirectDraw2Vtbl DDRAW_IDirectDraw2_VTable = +const IDirectDraw2Vtbl IDirectDraw2_Vtbl = { IDirectDraw2Impl_QueryInterface, IDirectDraw2Impl_AddRef, @@ -997,7 +1014,7 @@ const IDirectDraw2Vtbl DDRAW_IDirectDraw2_VTable = IDirectDraw2Impl_GetAvailableVidMem }; -const IDirectDraw4Vtbl DDRAW_IDirectDraw4_VTable = +const IDirectDraw4Vtbl IDirectDraw4_Vtbl = { IDirectDraw4Impl_QueryInterface, IDirectDraw4Impl_AddRef, diff --git a/dlls/ddraw/ddraw_user.c b/dlls/ddraw/ddraw_user.c deleted file mode 100644 index ddf3d6c40d..0000000000 --- a/dlls/ddraw/ddraw_user.c +++ /dev/null @@ -1,575 +0,0 @@ -/* DirectDraw driver for User-based primary surfaces - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "config.h" - -#include -#include -#include - -#define NONAMELESSUNION -#define NONAMELESSSTRUCT - -#include "windef.h" -#include "winbase.h" -#include "wingdi.h" -#include "winuser.h" -#include "ddraw.h" -#include "ddraw_private.h" -#include "wine/debug.h" - -WINE_DEFAULT_DEBUG_CHANNEL(ddraw); - -static const IDirectDraw7Vtbl User_DirectDraw_VTable; - -static const DDDEVICEIDENTIFIER2 user_device = -{ - "display", - "User (and GDI)", - { { 0x00010001, 0x00010001 } }, - 0, 0, 0, 0, - /* fe38440c-8969-4283-bc73-749e7bc3c2eb */ - {0xfe38440c,0x8969,0x428e, {0x73,0xbc,0x74,0x9e,0x7b,0xc3,0xc2,0xeb}}, - 0 -}; - -static const DDPIXELFORMAT pixelformats[] = -{ - /* 8bpp paletted */ - { sizeof(DDPIXELFORMAT), DDPF_RGB|DDPF_PALETTEINDEXED8, 0, { 8 } }, - /* 15bpp 5/5/5 */ - { sizeof(DDPIXELFORMAT), DDPF_RGB, 0, { 16 }, { 0x7C00 }, { 0x3E0 }, - { 0x1F } }, - /* 16bpp 5/6/5 */ - { sizeof(DDPIXELFORMAT), DDPF_RGB, 0, { 16 }, { 0xF800 }, { 0x7E0 }, - { 0x1F } }, - /* 24bpp 8/8/8 */ - { sizeof(DDPIXELFORMAT), DDPF_RGB, 0, { 24 }, { 0xFF0000 }, - { 0x00FF00 }, { 0x0000FF } }, - /* 32bpp 8/8/8 */ - { sizeof(DDPIXELFORMAT), DDPF_RGB, 0, { 32 }, { 0xFF0000 }, - { 0x00FF00 }, { 0x0000FF } } -}; - -HRESULT User_DirectDraw_Create(const GUID* pGUID, LPDIRECTDRAW7* pIface, - IUnknown* pUnkOuter, BOOL ex); -HRESULT User_DirectDraw_Initialize(IDirectDrawImpl*, const GUID*); - -static const ddraw_driver user_driver = -{ - &user_device, - 10, - User_DirectDraw_Create, - User_DirectDraw_Initialize -}; - -BOOL DDRAW_User_Init(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv) -{ - if (fdwReason == DLL_PROCESS_ATTACH) - DDRAW_register_driver(&user_driver); - - return TRUE; -} - -static const DDPIXELFORMAT* pixelformat_for_depth(DWORD depth) -{ - switch (depth) - { - case 8: return pixelformats + 0; - case 15: return pixelformats + 1; - case 16: return pixelformats + 2; - case 24: return pixelformats + 3; - case 32: return pixelformats + 4; - default: return NULL; - } -} - -/* Not called from the vtable. */ -HRESULT User_DirectDraw_Construct(IDirectDrawImpl *This, BOOL ex) -{ - HRESULT hr; - DWORD depth; - HDC hDC; - - TRACE("(%p,%d)\n",This,ex); - - hr = Main_DirectDraw_Construct(This, ex); - if (FAILED(hr)) return hr; - - This->final_release = User_DirectDraw_final_release; - - This->create_primary = User_DirectDraw_create_primary; - This->create_backbuffer = User_DirectDraw_create_backbuffer; - - hDC = CreateDCA("DISPLAY", NULL, NULL, NULL); - depth = GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES); - DeleteDC(hDC); - - This->width = GetSystemMetrics(SM_CXSCREEN); - This->height = GetSystemMetrics(SM_CYSCREEN); - This->pitch = DDRAW_width_bpp_to_pitch(This->width, depth); - This->pixelformat = *pixelformat_for_depth(depth); - - This->orig_width = This->width; - This->orig_height = This->height; - This->orig_pitch = This->pitch; - This->orig_pixelformat = This->pixelformat; - - ICOM_INIT_INTERFACE(This, IDirectDraw7, User_DirectDraw_VTable); - - /* capabilities */ -#define BLIT_CAPS (DDCAPS_BLT | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL \ - | DDCAPS_BLTSTRETCH | DDCAPS_CANBLTSYSMEM | DDCAPS_CANCLIP \ - | DDCAPS_CANCLIPSTRETCHED | DDCAPS_COLORKEY \ - | DDCAPS_COLORKEYHWASSIST | DDCAPS_OVERLAY | DDCAPS_OVERLAYSTRETCH) -#define CKEY_CAPS (DDCKEYCAPS_DESTBLT | DDCKEYCAPS_SRCBLT) -#define FX_CAPS (DDFXCAPS_BLTALPHA | DDFXCAPS_BLTMIRRORLEFTRIGHT \ - | DDFXCAPS_BLTMIRRORUPDOWN | DDFXCAPS_BLTROTATION90 \ - | DDFXCAPS_BLTSHRINKX | DDFXCAPS_BLTSHRINKXN \ - | DDFXCAPS_BLTSHRINKY | DDFXCAPS_BLTSHRINKXN \ - | DDFXCAPS_BLTSTRETCHX | DDFXCAPS_BLTSTRETCHXN \ - | DDFXCAPS_BLTSTRETCHY | DDFXCAPS_BLTSTRETCHYN) - This->caps.dwCaps |= DDCAPS_GDI | DDCAPS_PALETTE | BLIT_CAPS; - if( opengl_initialized ) - { - /* Hack for D3D code */ - This->caps.dwCaps |= DDCAPS_3D; - } - This->caps.dwCaps2 |= DDCAPS2_CERTIFIED | DDCAPS2_NOPAGELOCKREQUIRED | - DDCAPS2_PRIMARYGAMMA | DDCAPS2_WIDESURFACES; - This->caps.dwCKeyCaps |= CKEY_CAPS; - This->caps.dwFXCaps |= FX_CAPS; - This->caps.dwPalCaps |= DDPCAPS_8BIT | DDPCAPS_PRIMARYSURFACE; - This->caps.dwVidMemTotal = 16*1024*1024; - This->caps.dwVidMemFree = 16*1024*1024; - This->caps.dwSVBCaps |= BLIT_CAPS; - This->caps.dwSVBCKeyCaps |= CKEY_CAPS; - This->caps.dwSVBFXCaps |= FX_CAPS; - This->caps.dwVSBCaps |= BLIT_CAPS; - This->caps.dwVSBCKeyCaps |= CKEY_CAPS; - This->caps.dwVSBFXCaps |= FX_CAPS; - This->caps.dwSSBCaps |= BLIT_CAPS; - This->caps.dwSSBCKeyCaps |= CKEY_CAPS; - This->caps.dwSSBFXCaps |= FX_CAPS; - This->caps.ddsCaps.dwCaps |= DDSCAPS_ALPHA | DDSCAPS_BACKBUFFER | - DDSCAPS_FLIP | DDSCAPS_FRONTBUFFER | - DDSCAPS_OFFSCREENPLAIN | DDSCAPS_PALETTE | - DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY | - DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE; - if( opengl_initialized ) - { - /* Hacks for D3D code */ - This->caps.ddsCaps.dwCaps |= DDSCAPS_3DDEVICE | DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_ZBUFFER; - } - - This->caps.ddsOldCaps.dwCaps = This->caps.ddsCaps.dwCaps; -#undef BLIT_CAPS -#undef CKEY_CAPS -#undef FX_CAPS - - return S_OK; -} - -/* This function is called from DirectDrawCreate(Ex) on the most-derived - * class to start construction. - * Not called from the vtable. */ -HRESULT User_DirectDraw_Create(const GUID* pGUID, LPDIRECTDRAW7* pIface, - IUnknown* pUnkOuter, BOOL ex) -{ - HRESULT hr; - IDirectDrawImpl* This; - - assert(pUnkOuter == NULL); - - This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof(IDirectDrawImpl) + sizeof(User_DirectDrawImpl)); - if (This == NULL) return E_OUTOFMEMORY; - - /* Note that this relation does *not* hold true if the DD object was - * CoCreateInstanced then Initialized. */ - This->private = (User_DirectDrawImpl *)(This+1); - - /* Initialize the DDCAPS structure */ - This->caps.dwSize = sizeof(This->caps); - - hr = User_DirectDraw_Construct(This, ex); - if (FAILED(hr)) - HeapFree(GetProcessHeap(), 0, This); - else - *pIface = ICOM_INTERFACE(This, IDirectDraw7); - - return hr; -} - -/* This function is called from Uninit_DirectDraw_Initialize on the - * most-derived-class to start initialization. - * Not called from the vtable. */ -HRESULT User_DirectDraw_Initialize(IDirectDrawImpl *This, const GUID* guid) -{ - HRESULT hr; - This->private = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof(User_DirectDrawImpl)); - if (This->private == NULL) return E_OUTOFMEMORY; - - /* Initialize the DDCAPS structure */ - This->caps.dwSize = sizeof(This->caps); - - hr = User_DirectDraw_Construct(This, TRUE); /* XXX ex? */ - if (FAILED(hr)) - { - HeapFree(GetProcessHeap(), 0, This->private); - return hr; - } - - return DD_OK; -} - -/* Called from an internal function pointer. */ -void User_DirectDraw_final_release(IDirectDrawImpl *This) -{ - Main_DirectDraw_final_release(This); -} - -/* Compact: generic */ -/* CreateClipper: generic */ -/* CreatePalette: generic (with callback) */ -/* CreateSurface: generic (with callbacks) */ - -HRESULT -User_DirectDraw_create_primary(IDirectDrawImpl* This, - const DDSURFACEDESC2* pDDSD, - LPDIRECTDRAWSURFACE7* ppSurf, - IUnknown* pUnkOuter) -{ - return User_DirectDrawSurface_Create(This, pDDSD, ppSurf, pUnkOuter); -} - -HRESULT -User_DirectDraw_create_backbuffer(IDirectDrawImpl* This, - const DDSURFACEDESC2* pDDSD, - LPDIRECTDRAWSURFACE7* ppSurf, - IUnknown* pUnkOuter, - IDirectDrawSurfaceImpl* primary) -{ - return User_DirectDrawSurface_Create(This, pDDSD, ppSurf, pUnkOuter); -} - -/* DuplicateSurface: generic */ - -/* Originally derived from Xlib_IDirectDraw2Impl_EnumDisplayModes. - * - * The depths are whatever DIBsections support on the client side. - * Should they be limited by screen depth? - */ -HRESULT WINAPI -User_DirectDraw_EnumDisplayModes(LPDIRECTDRAW7 iface, DWORD dwFlags, - LPDDSURFACEDESC2 pDDSD, LPVOID context, - LPDDENUMMODESCALLBACK2 callback) -{ - DDSURFACEDESC2 callback_sd; - DEVMODEW DevModeW; - const DDPIXELFORMAT* pixelformat; - - int i; - - TRACE("(%p)->(0x%08lx,%p,%p,%p)\n",iface,dwFlags,pDDSD,context,callback); - - if (pDDSD && TRACE_ON(ddraw)) - { - TRACE("Enumerate modes matching:\n"); - DDRAW_dump_surface_desc(pDDSD); - } - - ZeroMemory(&callback_sd, sizeof(callback_sd)); - callback_sd.dwSize = sizeof(callback_sd); - - callback_sd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_CAPS - | DDSD_PITCH; - - if (dwFlags & DDEDM_REFRESHRATES) - callback_sd.dwFlags |= DDSD_REFRESHRATE; - - callback_sd.u2.dwRefreshRate = 60.0; - - for (i = 0; EnumDisplaySettingsExW(NULL, i, &DevModeW, 0); i++) - { - if (pDDSD) - { - if ((pDDSD->dwFlags & DDSD_WIDTH) && (pDDSD->dwWidth != DevModeW.dmPelsWidth)) - continue; - if ((pDDSD->dwFlags & DDSD_HEIGHT) && (pDDSD->dwHeight != DevModeW.dmPelsHeight)) - continue; - if ((pDDSD->dwFlags & DDSD_PIXELFORMAT) && (pDDSD->u4.ddpfPixelFormat.dwFlags & DDPF_RGB) && - (pDDSD->u4.ddpfPixelFormat.u1.dwRGBBitCount != DevModeW.dmBitsPerPel)) - continue; - } - - callback_sd.dwHeight = DevModeW.dmPelsHeight; - callback_sd.dwWidth = DevModeW.dmPelsWidth; - if (DevModeW.dmFields & DM_DISPLAYFREQUENCY) - { - callback_sd.u2.dwRefreshRate = DevModeW.dmDisplayFrequency; - } - - TRACE("- mode: %ldx%ld\n", callback_sd.dwWidth, callback_sd.dwHeight); - - pixelformat = pixelformat_for_depth(DevModeW.dmBitsPerPel); - callback_sd.u1.lPitch - = DDRAW_width_bpp_to_pitch(DevModeW.dmPelsWidth, - pixelformat->u1.dwRGBBitCount); - - callback_sd.u4.ddpfPixelFormat = *pixelformat; - - callback_sd.ddsCaps.dwCaps = 0; - if (pixelformat->dwFlags & DDPF_PALETTEINDEXED8) /* ick */ - callback_sd.ddsCaps.dwCaps |= DDSCAPS_PALETTE; - - TRACE(" - %2ld bpp, R=%08lx G=%08lx B=%08lx\n", - callback_sd.u4.ddpfPixelFormat.u1.dwRGBBitCount, - callback_sd.u4.ddpfPixelFormat.u2.dwRBitMask, - callback_sd.u4.ddpfPixelFormat.u3.dwGBitMask, - callback_sd.u4.ddpfPixelFormat.u4.dwBBitMask); - if (callback(&callback_sd, context) == DDENUMRET_CANCEL) - return DD_OK; - } - - return DD_OK; -} - -/* EnumSurfaces: generic */ -/* FlipToGDISurface: ??? */ - -#if 0 -HRESULT WINAPI -User_DirectDraw_GetCaps(LPDIRECTDRAW7 iface, LPDDCAPS pDriverCaps, - LPDDCAPS pHELCaps) -{ -/* Based on my guesses for what is appropriate with some clues from the - * NVidia driver. Not everything is actually implemented yet. - * NV has but we don't: Overlays, Video Ports, DDCAPS_READSCANLINE, - * DDCAPS2_CERTIFIED (heh), DDSCAPS2_NONLOCALVIDMEM, DDSCAPS2_COPYFOURCC. - * It actually has no FX alpha caps. - * Oddly, it doesn't list DDPCAPS_PRIMARYSURFACE. - * And the HEL caps make little sense. - */ -#define BLIT_CAPS (DDCAPS_BLT | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL \ - | DDCAPS_BLTSTRETCH | DDCAPS_CANBLTSYSMEM | DDCAPS_CANCLIP \ - | DDCAPS_CANCLIPSTRETCHED | DDCAPS_COLORKEY \ - | DDCAPS_COLORKEYHWASSIST | DDCAPS_OVERLAY | DDCAPS_OVERLAYSTRETCH) - -#define CKEY_CAPS (DDCKEYCAPS_DESTBLT | DDCKEYCAPS_SRCBLT) - -#define FX_CAPS (DDFXCAPS_BLTALPHA | DDFXCAPS_BLTMIRRORLEFTRIGHT \ - | DDFXCAPS_BLTMIRRORUPDOWN | DDFXCAPS_BLTROTATION90 \ - | DDFXCAPS_BLTSHRINKX | DDFXCAPS_BLTSHRINKXN \ - | DDFXCAPS_BLTSHRINKY | DDFXCAPS_BLTSHRINKXN \ - | DDFXCAPS_BLTSTRETCHX | DDFXCAPS_BLTSTRETCHXN \ - | DDFXCAPS_BLTSTRETCHY | DDFXCAPS_BLTSTRETCHYN) - -#if 0 -#define ROPS { SRCCOPY, SRCPAINT, SRCAND, SRCINVERT, SRCERASE, NOTSRCCOPY, \ - NOTSRCERASE, MERGEPAINT, BLACKNESS, WHITENESS, } -#else -#define ROPS { 0, } -#endif - - static const DDCAPS caps = - { sizeof(DDCAPS), - DDCAPS_3D | DDCAPS_GDI | DDCAPS_PALETTE | BLIT_CAPS, - DDCAPS2_CANMANAGETEXTURE | DDCAPS2_CANRENDERWINDOWED | DDCAPS2_CERTIFIED - | DDCAPS2_NOPAGELOCKREQUIRED | DDCAPS2_PRIMARYGAMMA - | DDCAPS2_WIDESURFACES, - CKEY_CAPS, - FX_CAPS, - 0, /* dwFXAlphaCaps */ - DDPCAPS_8BIT | DDPCAPS_PRIMARYSURFACE, - 0, /* dwSVCaps */ - 0, /* ? dwAlphaBitConstBitDepths */ - 0, /* ? dwAlphaBitPixelPitDepths */ - 0, /* ? dwAlphaBltSurfaceBitDepths */ - 0, /* ? dwAlphaOverlayConstBitDepths */ - 0, /* ? dwAlphaOverlayPixelBitDepths */ - 0, /* ? dwAlphaOverlaySurfaceBitDepths */ - DDBD_16, /* ? dwZBufferBitDepths */ - 16*1024*1024, /* dwVidMemTotal */ - 16*1024*1024, /* dwVidMemFree */ - 0, /* dwMaxVisibleOverlays */ - 0, /* dwCurrVisibleOverlays */ - 0, /* dwNumFourCCCodes */ - 0, /* dwAlignBoundarySrc */ - 0, /* dwAlignSizeSrc */ - 0, /* dwAlignBoundaryDest */ - 0, /* dwAlignSizeDest */ - 0, /* dwAlignStrideAlign */ - ROPS, /* XXX dwRops[DD_ROP_SPACE] */ - { 0, }, /* XXX ddsOldCaps */ - 1000, /* dwMinOverlayStretch */ - 1000, /* dwMaxOverlayStretch */ - 1000, /* dwMinLiveVideoStretch */ - 1000, /* dwMaxLiveVideoStretch */ - 1000, /* dwMinHwCodecStretch */ - 1000, /* dwMaxHwCodecStretch */ - 0, 0, 0, /* dwReserved1, 2, 3 */ - BLIT_CAPS, /* dwSVBCaps */ - CKEY_CAPS, /* dwSVBCKeyCaps */ - FX_CAPS, /* dwSVBFXCaps */ - ROPS, /* dwSVBRops */ - BLIT_CAPS, /* dwVSBCaps */ - CKEY_CAPS, /* dwVSBCKeyCaps */ - FX_CAPS, /* dwVSBFXCaps */ - ROPS, /* dwVSBRops */ - BLIT_CAPS, /* dwSSBCaps */ - CKEY_CAPS, /* dwSSBCKeyCaps */ - FX_CAPS, /* dwSSBFXCaps */ - ROPS, /* dwSSBRops */ - 0, /* dwMaxVideoPorts */ - 0, /* dwCurrVideoPorts */ - 0, /* ? dwSVBCaps2 */ - BLIT_CAPS, /* ? dwNLVBCaps */ - 0, /* ? dwNLVBCaps2 */ - CKEY_CAPS, /* dwNLVBCKeyCaps */ - FX_CAPS, /* dwNLVBFXCaps */ - ROPS, /* dwNLVBRops */ - { /* ddsCaps */ - DDSCAPS_3DDEVICE | DDSCAPS_ALPHA | DDSCAPS_BACKBUFFER | DDSCAPS_FLIP - | DDSCAPS_FRONTBUFFER | DDSCAPS_MIPMAP | DDSCAPS_OFFSCREENPLAIN - | DDSCAPS_PALETTE | DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY - | DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE - | DDSCAPS_ZBUFFER, - DDSCAPS2_CUBEMAP, - 0, - 0 - } - }; - -#undef BLIT_CAPS -#undef CKEY_CAPS -#undef FX_CAPS -#undef ROPS - - IDirectDrawImpl *This = (IDirectDrawImpl *)iface; - - TRACE("(%p)->(%p,%p)\n",This,pDriverCaps,pHELCaps); - - if (pDriverCaps != NULL) - DD_STRUCT_COPY_BYSIZE(pDriverCaps,&caps); - - if (pHELCaps != NULL) - DD_STRUCT_COPY_BYSIZE(pHELCaps,&caps); - - return DD_OK; -} -#endif - -HRESULT WINAPI -User_DirectDraw_GetDeviceIdentifier(LPDIRECTDRAW7 iface, - LPDDDEVICEIDENTIFIER2 pDDDI, - DWORD dwFlags) -{ - TRACE("(%p)->(%p,%08lx)\n",iface,pDDDI,dwFlags); - *pDDDI = user_device; - return DD_OK; -} - -/* GetDisplayMode: generic */ -/* GetFourCCCodes: generic */ -/* GetGDISurface: ??? */ -/* GetMonitorFrequency: generic */ -/* GetScanLine: generic */ -/* GetSurfaceFromDC: generic */ -/* GetVerticalBlankStatus: generic */ -/* Initialize: generic */ -/* RestoreAllSurfaces: generic */ -/* RestoreDisplayMode: generic */ -/* SetCooperativeLevel: ??? */ - -HRESULT WINAPI -User_DirectDraw_SetDisplayMode(LPDIRECTDRAW7 iface, DWORD dwWidth, - DWORD dwHeight, DWORD dwBPP, - DWORD dwRefreshRate, DWORD dwFlags) -{ - IDirectDrawImpl *This = (IDirectDrawImpl *)iface; - - const DDPIXELFORMAT* pixelformat; - DEVMODEW devmode; - LONG pitch; - - TRACE("(%p)->(%ldx%ldx%ld,%ld Hz,%08lx)\n",This,dwWidth,dwHeight,dwBPP,dwRefreshRate,dwFlags); - devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; - devmode.dmBitsPerPel = dwBPP; - devmode.dmPelsWidth = dwWidth; - devmode.dmPelsHeight = dwHeight; - /* '0' means default frequency */ - if (dwRefreshRate != 0) - { - devmode.dmFields |= DM_DISPLAYFREQUENCY; - devmode.dmDisplayFrequency = dwRefreshRate; - } - if (ChangeDisplaySettingsExW(NULL, &devmode, NULL, CDS_FULLSCREEN, NULL) != DISP_CHANGE_SUCCESSFUL) - return DDERR_INVALIDMODE; - - pixelformat = pixelformat_for_depth(dwBPP); - if (pixelformat == NULL) - { - assert(0); - return DDERR_GENERIC; - } - - pitch = DDRAW_width_bpp_to_pitch(dwWidth, dwBPP); - return Main_DirectDraw_SetDisplayMode(iface, dwWidth, dwHeight, pitch, - dwRefreshRate, dwFlags, pixelformat); -} - -/* StartModeTest: ??? */ -/* TestCooperativeLevel: generic? */ -/* WaitForVerticalBlank: ??? */ - -static const IDirectDraw7Vtbl User_DirectDraw_VTable = -{ - Main_DirectDraw_QueryInterface, - Main_DirectDraw_AddRef, - Main_DirectDraw_Release, - Main_DirectDraw_Compact, - Main_DirectDraw_CreateClipper, - Main_DirectDraw_CreatePalette, - Main_DirectDraw_CreateSurface, - Main_DirectDraw_DuplicateSurface, - User_DirectDraw_EnumDisplayModes, - Main_DirectDraw_EnumSurfaces, - Main_DirectDraw_FlipToGDISurface, - Main_DirectDraw_GetCaps, - Main_DirectDraw_GetDisplayMode, - Main_DirectDraw_GetFourCCCodes, - Main_DirectDraw_GetGDISurface, - Main_DirectDraw_GetMonitorFrequency, - Main_DirectDraw_GetScanLine, - Main_DirectDraw_GetVerticalBlankStatus, - Main_DirectDraw_Initialize, - Main_DirectDraw_RestoreDisplayMode, - Main_DirectDraw_SetCooperativeLevel, - User_DirectDraw_SetDisplayMode, - Main_DirectDraw_WaitForVerticalBlank, - Main_DirectDraw_GetAvailableVidMem, - Main_DirectDraw_GetSurfaceFromDC, - Main_DirectDraw_RestoreAllSurfaces, - Main_DirectDraw_TestCooperativeLevel, - User_DirectDraw_GetDeviceIdentifier, - Main_DirectDraw_StartModeTest, - Main_DirectDraw_EvaluateMode -}; diff --git a/dlls/ddraw/ddraw_utils.c b/dlls/ddraw/ddraw_utils.c deleted file mode 100644 index 327dd2feda..0000000000 --- a/dlls/ddraw/ddraw_utils.c +++ /dev/null @@ -1,951 +0,0 @@ -/* - * DirectDraw helper functions - * - * Copyright 1997-2000 Marcus Meissner - * Copyright 1998 Lionel Ulmer (most of Direct3D stuff) - * Copyright 2000 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#define NONAMELESSUNION -#define NONAMELESSSTRUCT - -#include "wine/debug.h" - -#include -#include -#include -#include - -#include "windef.h" -#include "winbase.h" -#include "wingdi.h" -#include "ddraw.h" - -#include "ddraw_private.h" - -WINE_DEFAULT_DEBUG_CHANNEL(ddraw); - -/* ************************************* - 16 / 15 bpp to palettized 8 bpp - ************************************* */ -static void pixel_convert_16_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) { - unsigned char *c_src = (unsigned char *) src; - unsigned short *c_dst = (unsigned short *) dst; - int y; - - if (palette != NULL) { - const unsigned int * pal = (unsigned int *) palette->screen_palents; - - for (y = height; y--; ) { -#if defined(__i386__) && defined(__GNUC__) - /* gcc generates slightly inefficient code for the the copy/lookup, - * it generates one excess memory access (to pal) per pixel. Since - * we know that pal is not modified by the memory write we can - * put it into a register and reduce the number of memory accesses - * from 4 to 3 pp. There are two xor eax,eax to avoid pipeline - * stalls. (This is not guaranteed to be the fastest method.) - */ - __asm__ __volatile__( - "xor %%eax,%%eax\n" - "1:\n" - " lodsb\n" - " movw (%%edx,%%eax,4),%%ax\n" - " stosw\n" - " xor %%eax,%%eax\n" - " loop 1b\n" - : "=S" (c_src), "=D" (c_dst) - : "S" (c_src), "D" (c_dst) , "c" (width), "d" (pal) - : "eax", "cc", "memory" - ); - c_src+=(pitch-width); -#else - unsigned char * srclineend = c_src+width; - while (c_src < srclineend) - *c_dst++ = pal[*c_src++]; - c_src+=(pitch-width); -#endif - } - } else { - FIXME("No palette set...\n"); - memset(dst, 0, width * height * 2); - } -} -static void palette_convert_16_to_8( - LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count -) { - unsigned int i; - unsigned int *pal = (unsigned int *) screen_palette; - - for (i = 0; i < count; i++) - pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 8) | - ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) | - ((((unsigned short) palent[i].peGreen) & 0xFC) << 3)); -} - -static void palette_convert_15_to_8( - LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count -) { - unsigned int i; - unsigned int *pal = (unsigned int *) screen_palette; - - for (i = 0; i < count; i++) - pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 7) | - ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) | - ((((unsigned short) palent[i].peGreen) & 0xF8) << 2)); -} - -/* ************************************* - 24 to palettized 8 bpp - ************************************* */ -static void pixel_convert_24_to_8( - void *src, void *dst, DWORD width, DWORD height, LONG pitch, - IDirectDrawPaletteImpl* palette -) { - unsigned char *c_src = (unsigned char *) src; - unsigned char *c_dst = (unsigned char *) dst; - int y; - - if (palette != NULL) { - const unsigned int *pal = (unsigned int *) palette->screen_palents; - - for (y = height; y--; ) { - unsigned char * srclineend = c_src+width; - while (c_src < srclineend ) { - register long pixel = pal[*c_src++]; - *c_dst++ = pixel; - *c_dst++ = pixel>>8; - *c_dst++ = pixel>>16; - } - c_src+=(pitch-width); - } - } else { - FIXME("No palette set...\n"); - memset(dst, 0, width * height * 3); - } -} - -/* ************************************* - 32 bpp to palettized 8 bpp - ************************************* */ -static void pixel_convert_32_to_8( - void *src, void *dst, DWORD width, DWORD height, LONG pitch, - IDirectDrawPaletteImpl* palette -) { - unsigned char *c_src = (unsigned char *) src; - unsigned int *c_dst = (unsigned int *) dst; - int y; - - if (palette != NULL) { - const unsigned int *pal = (unsigned int *) palette->screen_palents; - - for (y = height; y--; ) { -#if defined(__i386__) && defined(__GNUC__) - /* See comment in pixel_convert_16_to_8 */ - __asm__ __volatile__( - "xor %%eax,%%eax\n" - "1:\n" - " lodsb\n" - " movl (%%edx,%%eax,4),%%eax\n" - " stosl\n" - " xor %%eax,%%eax\n" - " loop 1b\n" - : "=S" (c_src), "=D" (c_dst) - : "S" (c_src), "D" (c_dst) , "c" (width), "d" (pal) - : "eax", "cc", "memory" - ); - c_src+=(pitch-width); -#else - unsigned char * srclineend = c_src+width; - while (c_src < srclineend ) - *c_dst++ = pal[*c_src++]; - c_src+=(pitch-width); -#endif - } - } else { - FIXME("No palette set...\n"); - memset(dst, 0, width * height * 4); - } -} - -static void palette_convert_24_to_8( - LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count -) { - unsigned int i; - unsigned int *pal = (unsigned int *) screen_palette; - - for (i = 0; i < count; i++) - pal[start + i] = ((((unsigned int) palent[i].peRed) << 16) | - (((unsigned int) palent[i].peGreen) << 8) | - ((unsigned int) palent[i].peBlue)); -} - -/* ************************************* - 16 bpp to 15 bpp - ************************************* */ -static void pixel_convert_15_to_16( - void *src, void *dst, DWORD width, DWORD height, LONG pitch, - IDirectDrawPaletteImpl* palette -) { - unsigned short *c_src = (unsigned short *) src; - unsigned short *c_dst = (unsigned short *) dst; - int y; - - for (y = height; y--; ) { - unsigned short * srclineend = c_src+width; - while (c_src < srclineend ) { - unsigned short val = *c_src++; - *c_dst++=((val&0xFFC0)>>1)|(val&0x001f); - } - c_src+=((pitch/2)-width); - } -} - -/* ************************************* - 32 bpp to 16 bpp - ************************************* */ -static void pixel_convert_32_to_16( - void *src, void *dst, DWORD width, DWORD height, LONG pitch, - IDirectDrawPaletteImpl* palette -) { - unsigned short *c_src = (unsigned short *) src; - unsigned int *c_dst = (unsigned int *) dst; - int y; - - for (y = height; y--; ) { - unsigned short * srclineend = c_src+width; - while (c_src < srclineend ) { - *c_dst++ = (((*c_src & 0xF800) << 8) | - ((*c_src & 0x07E0) << 5) | - ((*c_src & 0x001F) << 3)); - c_src++; - } - c_src+=((pitch/2)-width); - } -} - -/* ************************************* - 32 bpp to 24 bpp - ************************************* */ -static void pixel_convert_32_to_24( - void *src, void *dst, DWORD width, DWORD height, LONG pitch, - IDirectDrawPaletteImpl* palette -) { - unsigned char *c_src = (unsigned char *) src; - unsigned int *c_dst = (unsigned int *) dst; - int y; - - for (y = height; y--; ) { - unsigned char * srclineend = c_src+width*3; - while (c_src < srclineend ) { - /* FIXME: wrong for big endian */ - memcpy(c_dst,c_src,3); - c_src+=3; - c_dst++; - } - c_src+=pitch-width*3; - } -} - -/* ************************************* - 16 bpp to 32 bpp - ************************************* */ -static void pixel_convert_16_to_32( - void *src, void *dst, DWORD width, DWORD height, LONG pitch, - IDirectDrawPaletteImpl* palette -) { - unsigned int *c_src = (unsigned int *) src; - unsigned short *c_dst = (unsigned short *) dst; - int y; - - for (y = height; y--; ) { - unsigned int * srclineend = c_src+width; - while (c_src < srclineend ) { - *c_dst++ = (((*c_src & 0xF80000) >> 8) | - ((*c_src & 0x00FC00) >> 5) | - ((*c_src & 0x0000F8) >> 3)); - c_src++; - } - c_src+=((pitch/4)-width); - } -} - -Convert ModeEmulations[8] = { - { { 32, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, { 24, 24, 0xFF0000, 0x00FF00, 0x0000FF }, { pixel_convert_32_to_24, NULL } }, - { { 32, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, { 16, 16, 0xF800, 0x07E0, 0x001F }, { pixel_convert_32_to_16, NULL } }, - { { 32, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_32_to_8, palette_convert_24_to_8 } }, - { { 24, 24, 0xFF0000, 0x00FF00, 0x0000FF }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_24_to_8, palette_convert_24_to_8 } }, - { { 16, 15, 0x7C00, 0x03E0, 0x001F }, { 16,16, 0xf800, 0x07e0, 0x001f }, { pixel_convert_15_to_16, NULL } }, - { { 16, 16, 0xF800, 0x07E0, 0x001F }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_16_to_8, palette_convert_16_to_8 } }, - { { 16, 15, 0x7C00, 0x03E0, 0x001F }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_16_to_8, palette_convert_15_to_8 } }, - { { 16, 16, 0xF800, 0x07E0, 0x001F }, { 32, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, { pixel_convert_16_to_32, NULL } } -}; - -void DDRAW_Convert_DDSCAPS_1_To_2(const DDSCAPS* pIn, DDSCAPS2* pOut) -{ - /* 2 adds three additional caps fields to the end. Both versions - * are unversioned. */ - pOut->dwCaps = pIn->dwCaps; - pOut->dwCaps2 = 0; - pOut->dwCaps3 = 0; - pOut->dwCaps4 = 0; -} - -void DDRAW_Convert_DDDEVICEIDENTIFIER_2_To_1(const DDDEVICEIDENTIFIER2* pIn, - DDDEVICEIDENTIFIER* pOut) -{ - /* 2 adds a dwWHQLLevel field to the end. Both structures are - * unversioned. */ - memcpy(pOut, pIn, sizeof(*pOut)); -} - -/****************************************************************************** - * debug output functions - */ -void DDRAW_dump_flags_(DWORD flags, const flag_info* names, - size_t num_names, int newline) -{ - unsigned int i; - - for (i=0; i < num_names; i++) - if ((flags & names[i].val) || /* standard flag value */ - ((!flags) && (!names[i].val))) /* zero value only */ - DPRINTF("%s ", names[i].name); - - if (newline) - DPRINTF("\n"); -} - -void DDRAW_dump_members(DWORD flags, const void* data, - const member_info* mems, size_t num_mems) -{ - unsigned int i; - - for (i=0; i < num_mems; i++) - { - if (mems[i].val & flags) - { - DPRINTF(" - %s : ", mems[i].name); - mems[i].func((const char *)data + mems[i].offset); - DPRINTF("\n"); - } - } -} - -void DDRAW_dump_DDBLTFX(DWORD flagmask) -{ - static const flag_info flags[] = - { - FE(DDBLTFX_ARITHSTRETCHY), - FE(DDBLTFX_MIRRORLEFTRIGHT), - FE(DDBLTFX_MIRRORUPDOWN), - FE(DDBLTFX_NOTEARING), - FE(DDBLTFX_ROTATE180), - FE(DDBLTFX_ROTATE270), - FE(DDBLTFX_ROTATE90), - FE(DDBLTFX_ZBUFFERRANGE), - FE(DDBLTFX_ZBUFFERBASEDEST) - }; - - DDRAW_dump_flags(flagmask, flags, sizeof(flags)/sizeof(flags[0])); -} - -void DDRAW_dump_DDBLTFAST(DWORD flagmask) -{ - static const flag_info flags[] = - { - FE(DDBLTFAST_NOCOLORKEY), - FE(DDBLTFAST_SRCCOLORKEY), - FE(DDBLTFAST_DESTCOLORKEY), - FE(DDBLTFAST_WAIT) - }; - - DDRAW_dump_flags(flagmask, flags, sizeof(flags)/sizeof(flags[0])); -} - -void DDRAW_dump_DDBLT(DWORD flagmask) -{ - static const flag_info flags[] = - { - FE(DDBLT_ALPHADEST), - FE(DDBLT_ALPHADESTCONSTOVERRIDE), - FE(DDBLT_ALPHADESTNEG), - FE(DDBLT_ALPHADESTSURFACEOVERRIDE), - FE(DDBLT_ALPHAEDGEBLEND), - FE(DDBLT_ALPHASRC), - FE(DDBLT_ALPHASRCCONSTOVERRIDE), - FE(DDBLT_ALPHASRCNEG), - FE(DDBLT_ALPHASRCSURFACEOVERRIDE), - FE(DDBLT_ASYNC), - FE(DDBLT_COLORFILL), - FE(DDBLT_DDFX), - FE(DDBLT_DDROPS), - FE(DDBLT_KEYDEST), - FE(DDBLT_KEYDESTOVERRIDE), - FE(DDBLT_KEYSRC), - FE(DDBLT_KEYSRCOVERRIDE), - FE(DDBLT_ROP), - FE(DDBLT_ROTATIONANGLE), - FE(DDBLT_ZBUFFER), - FE(DDBLT_ZBUFFERDESTCONSTOVERRIDE), - FE(DDBLT_ZBUFFERDESTOVERRIDE), - FE(DDBLT_ZBUFFERSRCCONSTOVERRIDE), - FE(DDBLT_ZBUFFERSRCOVERRIDE), - FE(DDBLT_WAIT), - FE(DDBLT_DEPTHFILL), - FE(DDBLT_DONOTWAIT) - }; - - DDRAW_dump_flags(flagmask, flags, sizeof(flags)/sizeof(flags[0])); -} - -void DDRAW_dump_DDSCAPS2(const DDSCAPS2 *in) -{ - static const flag_info flags[] = { - FE(DDSCAPS_RESERVED1), - FE(DDSCAPS_ALPHA), - FE(DDSCAPS_BACKBUFFER), - FE(DDSCAPS_COMPLEX), - FE(DDSCAPS_FLIP), - FE(DDSCAPS_FRONTBUFFER), - FE(DDSCAPS_OFFSCREENPLAIN), - FE(DDSCAPS_OVERLAY), - FE(DDSCAPS_PALETTE), - FE(DDSCAPS_PRIMARYSURFACE), - FE(DDSCAPS_PRIMARYSURFACELEFT), - FE(DDSCAPS_SYSTEMMEMORY), - FE(DDSCAPS_TEXTURE), - FE(DDSCAPS_3DDEVICE), - FE(DDSCAPS_VIDEOMEMORY), - FE(DDSCAPS_VISIBLE), - FE(DDSCAPS_WRITEONLY), - FE(DDSCAPS_ZBUFFER), - FE(DDSCAPS_OWNDC), - FE(DDSCAPS_LIVEVIDEO), - FE(DDSCAPS_HWCODEC), - FE(DDSCAPS_MODEX), - FE(DDSCAPS_MIPMAP), - FE(DDSCAPS_RESERVED2), - FE(DDSCAPS_ALLOCONLOAD), - FE(DDSCAPS_VIDEOPORT), - FE(DDSCAPS_LOCALVIDMEM), - FE(DDSCAPS_NONLOCALVIDMEM), - FE(DDSCAPS_STANDARDVGAMODE), - FE(DDSCAPS_OPTIMIZED) - }; - static const flag_info flags2[] = { - FE(DDSCAPS2_HARDWAREDEINTERLACE), - FE(DDSCAPS2_HINTDYNAMIC), - FE(DDSCAPS2_HINTSTATIC), - FE(DDSCAPS2_TEXTUREMANAGE), - FE(DDSCAPS2_RESERVED1), - FE(DDSCAPS2_RESERVED2), - FE(DDSCAPS2_OPAQUE), - FE(DDSCAPS2_HINTANTIALIASING), - FE(DDSCAPS2_CUBEMAP), - FE(DDSCAPS2_CUBEMAP_POSITIVEX), - FE(DDSCAPS2_CUBEMAP_NEGATIVEX), - FE(DDSCAPS2_CUBEMAP_POSITIVEY), - FE(DDSCAPS2_CUBEMAP_NEGATIVEY), - FE(DDSCAPS2_CUBEMAP_POSITIVEZ), - FE(DDSCAPS2_CUBEMAP_NEGATIVEZ), - FE(DDSCAPS2_MIPMAPSUBLEVEL), - FE(DDSCAPS2_D3DTEXTUREMANAGE), - FE(DDSCAPS2_DONOTPERSIST), - FE(DDSCAPS2_STEREOSURFACELEFT) - }; - - DDRAW_dump_flags_(in->dwCaps, flags, sizeof(flags)/sizeof(flags[0]), 0); - DDRAW_dump_flags_(in->dwCaps2, flags2, sizeof(flags2)/sizeof(flags2[0]), 0); -} - -void DDRAW_dump_DDSCAPS(const DDSCAPS *in) { - DDSCAPS2 in_bis; - - in_bis.dwCaps = in->dwCaps; - in_bis.dwCaps2 = 0; - in_bis.dwCaps3 = 0; - in_bis.dwCaps4 = 0; - - DDRAW_dump_DDSCAPS2(&in_bis); -} - -void DDRAW_dump_pixelformat_flag(DWORD flagmask) -{ - static const flag_info flags[] = - { - FE(DDPF_ALPHAPIXELS), - FE(DDPF_ALPHA), - FE(DDPF_FOURCC), - FE(DDPF_PALETTEINDEXED4), - FE(DDPF_PALETTEINDEXEDTO8), - FE(DDPF_PALETTEINDEXED8), - FE(DDPF_RGB), - FE(DDPF_COMPRESSED), - FE(DDPF_RGBTOYUV), - FE(DDPF_YUV), - FE(DDPF_ZBUFFER), - FE(DDPF_PALETTEINDEXED1), - FE(DDPF_PALETTEINDEXED2), - FE(DDPF_ZPIXELS) - }; - - DDRAW_dump_flags_(flagmask, flags, sizeof(flags)/sizeof(flags[0]), 0); -} - -void DDRAW_dump_paletteformat(DWORD dwFlags) -{ - static const flag_info flags[] = - { - FE(DDPCAPS_4BIT), - FE(DDPCAPS_8BITENTRIES), - FE(DDPCAPS_8BIT), - FE(DDPCAPS_INITIALIZE), - FE(DDPCAPS_PRIMARYSURFACE), - FE(DDPCAPS_PRIMARYSURFACELEFT), - FE(DDPCAPS_ALLOW256), - FE(DDPCAPS_VSYNC), - FE(DDPCAPS_1BIT), - FE(DDPCAPS_2BIT), - FE(DDPCAPS_ALPHA) - }; - - DDRAW_dump_flags(dwFlags, flags, sizeof(flags)/sizeof(flags[0])); -} - -void DDRAW_dump_pixelformat(const DDPIXELFORMAT *pf) { - DPRINTF("( "); - DDRAW_dump_pixelformat_flag(pf->dwFlags); - if (pf->dwFlags & DDPF_FOURCC) { - DPRINTF(", dwFourCC code '%c%c%c%c' (0x%08lx) - %ld bits per pixel", - (unsigned char)( pf->dwFourCC &0xff), - (unsigned char)((pf->dwFourCC>> 8)&0xff), - (unsigned char)((pf->dwFourCC>>16)&0xff), - (unsigned char)((pf->dwFourCC>>24)&0xff), - pf->dwFourCC, - pf->u1.dwYUVBitCount - ); - } - if (pf->dwFlags & DDPF_RGB) { - const char *cmd; - DPRINTF(", RGB bits: %ld, ", pf->u1.dwRGBBitCount); - switch (pf->u1.dwRGBBitCount) { - case 4: cmd = "%1lx"; break; - case 8: cmd = "%02lx"; break; - case 16: cmd = "%04lx"; break; - case 24: cmd = "%06lx"; break; - case 32: cmd = "%08lx"; break; - default: ERR("Unexpected bit depth !\n"); cmd = "%d"; break; - } - DPRINTF(" R "); DPRINTF(cmd, pf->u2.dwRBitMask); - DPRINTF(" G "); DPRINTF(cmd, pf->u3.dwGBitMask); - DPRINTF(" B "); DPRINTF(cmd, pf->u4.dwBBitMask); - if (pf->dwFlags & DDPF_ALPHAPIXELS) { - DPRINTF(" A "); DPRINTF(cmd, pf->u5.dwRGBAlphaBitMask); - } - if (pf->dwFlags & DDPF_ZPIXELS) { - DPRINTF(" Z "); DPRINTF(cmd, pf->u5.dwRGBZBitMask); - } - } - if (pf->dwFlags & DDPF_ZBUFFER) { - DPRINTF(", Z bits : %ld", pf->u1.dwZBufferBitDepth); - } - if (pf->dwFlags & DDPF_ALPHA) { - DPRINTF(", Alpha bits : %ld", pf->u1.dwAlphaBitDepth); - } - DPRINTF(")"); -} - -void DDRAW_dump_colorkeyflag(DWORD ck) -{ - static const flag_info flags[] = - { - FE(DDCKEY_COLORSPACE), - FE(DDCKEY_DESTBLT), - FE(DDCKEY_DESTOVERLAY), - FE(DDCKEY_SRCBLT), - FE(DDCKEY_SRCOVERLAY) - }; - - DDRAW_dump_flags(ck, flags, sizeof(flags)/sizeof(flags[0])); -} - -void DDRAW_dump_lockflag(DWORD lockflag) -{ - static const flag_info flags[] = - { - FE(DDLOCK_SURFACEMEMORYPTR), - FE(DDLOCK_WAIT), - FE(DDLOCK_EVENT), - FE(DDLOCK_READONLY), - FE(DDLOCK_WRITEONLY), - FE(DDLOCK_NOSYSLOCK), - FE(DDLOCK_DISCARDCONTENTS), - FE(DDLOCK_NOOVERWRITE) - }; - - DDRAW_dump_flags(lockflag, flags, sizeof(flags)/sizeof(flags[0])); -} - -static void DDRAW_dump_DWORD(const void *in) { - DPRINTF("%ld", *((const DWORD *) in)); -} -static void DDRAW_dump_PTR(const void *in) { - DPRINTF("%p", *((const void * const*) in)); -} -void DDRAW_dump_DDCOLORKEY(const DDCOLORKEY *ddck) { - DPRINTF(" Low : %ld - High : %ld", ddck->dwColorSpaceLowValue, ddck->dwColorSpaceHighValue); -} - -void DDRAW_dump_surface_desc(const DDSURFACEDESC2 *lpddsd) -{ -#define STRUCT DDSURFACEDESC2 - static const member_info members[] = - { - ME(DDSD_HEIGHT, DDRAW_dump_DWORD, dwHeight), - ME(DDSD_WIDTH, DDRAW_dump_DWORD, dwWidth), - ME(DDSD_PITCH, DDRAW_dump_DWORD, u1.lPitch), - ME(DDSD_LINEARSIZE, DDRAW_dump_DWORD, u1.dwLinearSize), - ME(DDSD_BACKBUFFERCOUNT, DDRAW_dump_DWORD, dwBackBufferCount), - ME(DDSD_MIPMAPCOUNT, DDRAW_dump_DWORD, u2.dwMipMapCount), - ME(DDSD_ZBUFFERBITDEPTH, DDRAW_dump_DWORD, u2.dwMipMapCount), /* This is for 'old-style' D3D */ - ME(DDSD_REFRESHRATE, DDRAW_dump_DWORD, u2.dwRefreshRate), - ME(DDSD_ALPHABITDEPTH, DDRAW_dump_DWORD, dwAlphaBitDepth), - ME(DDSD_LPSURFACE, DDRAW_dump_PTR, lpSurface), - ME(DDSD_CKDESTOVERLAY, DDRAW_dump_DDCOLORKEY, u3.ddckCKDestOverlay), - ME(DDSD_CKDESTBLT, DDRAW_dump_DDCOLORKEY, ddckCKDestBlt), - ME(DDSD_CKSRCOVERLAY, DDRAW_dump_DDCOLORKEY, ddckCKSrcOverlay), - ME(DDSD_CKSRCBLT, DDRAW_dump_DDCOLORKEY, ddckCKSrcBlt), - ME(DDSD_PIXELFORMAT, DDRAW_dump_pixelformat, u4.ddpfPixelFormat) - }; - static const member_info members_caps[] = - { - ME(DDSD_CAPS, DDRAW_dump_DDSCAPS, ddsCaps) - }; - static const member_info members_caps2[] = - { - ME(DDSD_CAPS, DDRAW_dump_DDSCAPS2, ddsCaps) - }; -#undef STRUCT - - if (NULL == lpddsd) { - DPRINTF("(null)\n"); - } else { - if (lpddsd->dwSize >= sizeof(DDSURFACEDESC2)) { - DDRAW_dump_members(lpddsd->dwFlags, lpddsd, members_caps2, 1); - } else { - DDRAW_dump_members(lpddsd->dwFlags, lpddsd, members_caps, 1); - } - DDRAW_dump_members(lpddsd->dwFlags, lpddsd, members, - sizeof(members)/sizeof(members[0])); - } -} - -void DDRAW_dump_cooperativelevel(DWORD cooplevel) -{ - static const flag_info flags[] = - { - FE(DDSCL_FULLSCREEN), - FE(DDSCL_ALLOWREBOOT), - FE(DDSCL_NOWINDOWCHANGES), - FE(DDSCL_NORMAL), - FE(DDSCL_ALLOWMODEX), - FE(DDSCL_EXCLUSIVE), - FE(DDSCL_SETFOCUSWINDOW), - FE(DDSCL_SETDEVICEWINDOW), - FE(DDSCL_CREATEDEVICEWINDOW) - }; - - if (TRACE_ON(ddraw)) - { - DPRINTF(" - "); - DDRAW_dump_flags(cooplevel, flags, sizeof(flags)/sizeof(flags[0])); - } -} - -void DDRAW_dump_DDCAPS(const DDCAPS *lpcaps) { - static const flag_info flags1[] = { - FE(DDCAPS_3D), - FE(DDCAPS_ALIGNBOUNDARYDEST), - FE(DDCAPS_ALIGNSIZEDEST), - FE(DDCAPS_ALIGNBOUNDARYSRC), - FE(DDCAPS_ALIGNSIZESRC), - FE(DDCAPS_ALIGNSTRIDE), - FE(DDCAPS_BLT), - FE(DDCAPS_BLTQUEUE), - FE(DDCAPS_BLTFOURCC), - FE(DDCAPS_BLTSTRETCH), - FE(DDCAPS_GDI), - FE(DDCAPS_OVERLAY), - FE(DDCAPS_OVERLAYCANTCLIP), - FE(DDCAPS_OVERLAYFOURCC), - FE(DDCAPS_OVERLAYSTRETCH), - FE(DDCAPS_PALETTE), - FE(DDCAPS_PALETTEVSYNC), - FE(DDCAPS_READSCANLINE), - FE(DDCAPS_STEREOVIEW), - FE(DDCAPS_VBI), - FE(DDCAPS_ZBLTS), - FE(DDCAPS_ZOVERLAYS), - FE(DDCAPS_COLORKEY), - FE(DDCAPS_ALPHA), - FE(DDCAPS_COLORKEYHWASSIST), - FE(DDCAPS_NOHARDWARE), - FE(DDCAPS_BLTCOLORFILL), - FE(DDCAPS_BANKSWITCHED), - FE(DDCAPS_BLTDEPTHFILL), - FE(DDCAPS_CANCLIP), - FE(DDCAPS_CANCLIPSTRETCHED), - FE(DDCAPS_CANBLTSYSMEM) - }; - static const flag_info flags2[] = { - FE(DDCAPS2_CERTIFIED), - FE(DDCAPS2_NO2DDURING3DSCENE), - FE(DDCAPS2_VIDEOPORT), - FE(DDCAPS2_AUTOFLIPOVERLAY), - FE(DDCAPS2_CANBOBINTERLEAVED), - FE(DDCAPS2_CANBOBNONINTERLEAVED), - FE(DDCAPS2_COLORCONTROLOVERLAY), - FE(DDCAPS2_COLORCONTROLPRIMARY), - FE(DDCAPS2_CANDROPZ16BIT), - FE(DDCAPS2_NONLOCALVIDMEM), - FE(DDCAPS2_NONLOCALVIDMEMCAPS), - FE(DDCAPS2_NOPAGELOCKREQUIRED), - FE(DDCAPS2_WIDESURFACES), - FE(DDCAPS2_CANFLIPODDEVEN), - FE(DDCAPS2_CANBOBHARDWARE), - FE(DDCAPS2_COPYFOURCC), - FE(DDCAPS2_PRIMARYGAMMA), - FE(DDCAPS2_CANRENDERWINDOWED), - FE(DDCAPS2_CANCALIBRATEGAMMA), - FE(DDCAPS2_FLIPINTERVAL), - FE(DDCAPS2_FLIPNOVSYNC), - FE(DDCAPS2_CANMANAGETEXTURE), - FE(DDCAPS2_TEXMANINNONLOCALVIDMEM), - FE(DDCAPS2_STEREO), - FE(DDCAPS2_SYSTONONLOCAL_AS_SYSTOLOCAL) - }; - static const flag_info flags3[] = { - FE(DDCKEYCAPS_DESTBLT), - FE(DDCKEYCAPS_DESTBLTCLRSPACE), - FE(DDCKEYCAPS_DESTBLTCLRSPACEYUV), - FE(DDCKEYCAPS_DESTBLTYUV), - FE(DDCKEYCAPS_DESTOVERLAY), - FE(DDCKEYCAPS_DESTOVERLAYCLRSPACE), - FE(DDCKEYCAPS_DESTOVERLAYCLRSPACEYUV), - FE(DDCKEYCAPS_DESTOVERLAYONEACTIVE), - FE(DDCKEYCAPS_DESTOVERLAYYUV), - FE(DDCKEYCAPS_SRCBLT), - FE(DDCKEYCAPS_SRCBLTCLRSPACE), - FE(DDCKEYCAPS_SRCBLTCLRSPACEYUV), - FE(DDCKEYCAPS_SRCBLTYUV), - FE(DDCKEYCAPS_SRCOVERLAY), - FE(DDCKEYCAPS_SRCOVERLAYCLRSPACE), - FE(DDCKEYCAPS_SRCOVERLAYCLRSPACEYUV), - FE(DDCKEYCAPS_SRCOVERLAYONEACTIVE), - FE(DDCKEYCAPS_SRCOVERLAYYUV), - FE(DDCKEYCAPS_NOCOSTOVERLAY) - }; - static const flag_info flags4[] = { - FE(DDFXCAPS_BLTALPHA), - FE(DDFXCAPS_OVERLAYALPHA), - FE(DDFXCAPS_BLTARITHSTRETCHYN), - FE(DDFXCAPS_BLTARITHSTRETCHY), - FE(DDFXCAPS_BLTMIRRORLEFTRIGHT), - FE(DDFXCAPS_BLTMIRRORUPDOWN), - FE(DDFXCAPS_BLTROTATION), - FE(DDFXCAPS_BLTROTATION90), - FE(DDFXCAPS_BLTSHRINKX), - FE(DDFXCAPS_BLTSHRINKXN), - FE(DDFXCAPS_BLTSHRINKY), - FE(DDFXCAPS_BLTSHRINKYN), - FE(DDFXCAPS_BLTSTRETCHX), - FE(DDFXCAPS_BLTSTRETCHXN), - FE(DDFXCAPS_BLTSTRETCHY), - FE(DDFXCAPS_BLTSTRETCHYN), - FE(DDFXCAPS_OVERLAYARITHSTRETCHY), - FE(DDFXCAPS_OVERLAYARITHSTRETCHYN), - FE(DDFXCAPS_OVERLAYSHRINKX), - FE(DDFXCAPS_OVERLAYSHRINKXN), - FE(DDFXCAPS_OVERLAYSHRINKY), - FE(DDFXCAPS_OVERLAYSHRINKYN), - FE(DDFXCAPS_OVERLAYSTRETCHX), - FE(DDFXCAPS_OVERLAYSTRETCHXN), - FE(DDFXCAPS_OVERLAYSTRETCHY), - FE(DDFXCAPS_OVERLAYSTRETCHYN), - FE(DDFXCAPS_OVERLAYMIRRORLEFTRIGHT), - FE(DDFXCAPS_OVERLAYMIRRORUPDOWN) - }; - static const flag_info flags5[] = { - FE(DDFXALPHACAPS_BLTALPHAEDGEBLEND), - FE(DDFXALPHACAPS_BLTALPHAPIXELS), - FE(DDFXALPHACAPS_BLTALPHAPIXELSNEG), - FE(DDFXALPHACAPS_BLTALPHASURFACES), - FE(DDFXALPHACAPS_BLTALPHASURFACESNEG), - FE(DDFXALPHACAPS_OVERLAYALPHAEDGEBLEND), - FE(DDFXALPHACAPS_OVERLAYALPHAPIXELS), - FE(DDFXALPHACAPS_OVERLAYALPHAPIXELSNEG), - FE(DDFXALPHACAPS_OVERLAYALPHASURFACES), - FE(DDFXALPHACAPS_OVERLAYALPHASURFACESNEG) - }; - static const flag_info flags6[] = { - FE(DDPCAPS_4BIT), - FE(DDPCAPS_8BITENTRIES), - FE(DDPCAPS_8BIT), - FE(DDPCAPS_INITIALIZE), - FE(DDPCAPS_PRIMARYSURFACE), - FE(DDPCAPS_PRIMARYSURFACELEFT), - FE(DDPCAPS_ALLOW256), - FE(DDPCAPS_VSYNC), - FE(DDPCAPS_1BIT), - FE(DDPCAPS_2BIT), - FE(DDPCAPS_ALPHA), - }; - static const flag_info flags7[] = { - FE(DDSVCAPS_RESERVED1), - FE(DDSVCAPS_RESERVED2), - FE(DDSVCAPS_RESERVED3), - FE(DDSVCAPS_RESERVED4), - FE(DDSVCAPS_STEREOSEQUENTIAL), - }; - - DPRINTF(" - dwSize : %ld\n", lpcaps->dwSize); - DPRINTF(" - dwCaps : "); DDRAW_dump_flags(lpcaps->dwCaps, flags1, sizeof(flags1)/sizeof(flags1[0])); - DPRINTF(" - dwCaps2 : "); DDRAW_dump_flags(lpcaps->dwCaps2, flags2, sizeof(flags2)/sizeof(flags2[0])); - DPRINTF(" - dwCKeyCaps : "); DDRAW_dump_flags(lpcaps->dwCKeyCaps, flags3, sizeof(flags3)/sizeof(flags3[0])); - DPRINTF(" - dwFXCaps : "); DDRAW_dump_flags(lpcaps->dwFXCaps, flags4, sizeof(flags4)/sizeof(flags4[0])); - DPRINTF(" - dwFXAlphaCaps : "); DDRAW_dump_flags(lpcaps->dwFXAlphaCaps, flags5, sizeof(flags5)/sizeof(flags5[0])); - DPRINTF(" - dwPalCaps : "); DDRAW_dump_flags(lpcaps->dwPalCaps, flags6, sizeof(flags6)/sizeof(flags6[0])); - DPRINTF(" - dwSVCaps : "); DDRAW_dump_flags(lpcaps->dwSVCaps, flags7, sizeof(flags7)/sizeof(flags7[0])); - DPRINTF("...\n"); - DPRINTF(" - dwNumFourCCCodes : %ld\n", lpcaps->dwNumFourCCCodes); - DPRINTF(" - dwCurrVisibleOverlays : %ld\n", lpcaps->dwCurrVisibleOverlays); - DPRINTF(" - dwMinOverlayStretch : %ld\n", lpcaps->dwMinOverlayStretch); - DPRINTF(" - dwMaxOverlayStretch : %ld\n", lpcaps->dwMaxOverlayStretch); - DPRINTF("...\n"); - DPRINTF(" - ddsCaps : "); DDRAW_dump_DDSCAPS2(&lpcaps->ddsCaps); DPRINTF("\n"); -} - -void DDRAW_dump_DDENUMSURFACES(DWORD flagmask) -{ - static const flag_info flags[] = - { - FE(DDENUMSURFACES_ALL), - FE(DDENUMSURFACES_MATCH), - FE(DDENUMSURFACES_NOMATCH), - FE(DDENUMSURFACES_CANBECREATED), - FE(DDENUMSURFACES_DOESEXIST) - }; - DDRAW_dump_flags(flagmask, flags, sizeof(flags)/sizeof(flags[0])); -} - -/* Debug function that can be helpful to debug various surface-related problems */ -static int get_shift(DWORD color_mask) { - int shift = 0; - while (color_mask > 0xFF) { - color_mask >>= 1; - shift += 1; - } - while ((color_mask & 0x80) == 0) { - color_mask <<= 1; - shift -= 1; - } - return shift; -} - -void DDRAW_dump_surface_to_disk(IDirectDrawSurfaceImpl *surface, FILE *f, int scale) -{ - int rwidth, rheight, x, y; - static char *output = NULL; - static int size = 0; - - rwidth = (surface->surface_desc.dwWidth + scale - 1) / scale; - rheight = (surface->surface_desc.dwHeight + scale - 1) / scale; - - if (rwidth > size) { - output = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, rwidth * 3); - size = rwidth; - } - - fprintf(f, "P6\n%d %d\n255\n", rwidth, rheight); - - if (surface->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) { - unsigned char table[256][3]; - int i; - - if (surface->palette == NULL) { - fclose(f); - return; - } - for (i = 0; i < 256; i++) { - table[i][0] = surface->palette->palents[i].peRed; - table[i][1] = surface->palette->palents[i].peGreen; - table[i][2] = surface->palette->palents[i].peBlue; - } - for (y = 0; y < rheight; y++) { - unsigned char *src = (unsigned char *) surface->surface_desc.lpSurface + (y * scale * surface->surface_desc.u1.lPitch); - for (x = 0; x < rwidth; x++) { - unsigned char color = *src; - src += scale; - - output[3 * x + 0] = table[color][0]; - output[3 * x + 1] = table[color][1]; - output[3 * x + 2] = table[color][2]; - } - fwrite(output, 3 * rwidth, 1, f); - } - } else if (surface->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_RGB) { - int red_shift, green_shift, blue_shift, pix_width; - - if (surface->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 8) { - pix_width = 1; - } else if (surface->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 16) { - pix_width = 2; - } else if (surface->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 32) { - pix_width = 4; - } else { - pix_width = 3; - } - - red_shift = get_shift(surface->surface_desc.u4.ddpfPixelFormat.u2.dwRBitMask); - green_shift = get_shift(surface->surface_desc.u4.ddpfPixelFormat.u3.dwGBitMask); - blue_shift = get_shift(surface->surface_desc.u4.ddpfPixelFormat.u4.dwBBitMask); - - for (y = 0; y < rheight; y++) { - unsigned char *src = (unsigned char *) surface->surface_desc.lpSurface + (y * scale * surface->surface_desc.u1.lPitch); - for (x = 0; x < rwidth; x++) { - unsigned int color; - unsigned int comp; - int i; - - color = 0; - for (i = 0; i < pix_width; i++) { - color |= src[i] << (8 * i); - } - src += scale * pix_width; - - comp = color & surface->surface_desc.u4.ddpfPixelFormat.u2.dwRBitMask; - output[3 * x + 0] = red_shift > 0 ? comp >> red_shift : comp << -red_shift; - comp = color & surface->surface_desc.u4.ddpfPixelFormat.u3.dwGBitMask; - output[3 * x + 1] = green_shift > 0 ? comp >> green_shift : comp << -green_shift; - comp = color & surface->surface_desc.u4.ddpfPixelFormat.u4.dwBBitMask; - output[3 * x + 2] = blue_shift > 0 ? comp >> blue_shift : comp << -blue_shift; - } - fwrite(output, 3 * rwidth, 1, f); - } - } - fclose(f); -} diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c new file mode 100644 index 0000000000..f0eb86cfdb --- /dev/null +++ b/dlls/ddraw/device.c @@ -0,0 +1,4574 @@ +/* + * Copyright (c) 1998-2004 Lionel Ulmer + * Copyright (c) 2002-2005 Christian Costa + * Copyright (c) 2006 Stefan Dösinger + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + * IDirect3DDevice implementation, version 1, 2, 3 and 7. Rendering is relayed + * to WineD3D, some minimal DirectDraw specific management is handled here. + * The Direct3DDevice is NOT the parent of the WineD3DDevice, because d3d + * is initialized when DirectDraw creates the primary surface. + * Some type management is necessary, because some D3D types changed between + * D3D7 and D3D9. + * + */ + +#include "config.h" +#include "wine/port.h" +#include "wine/debug.h" + +#include +#include +#include +#include + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "winnls.h" +#include "winerror.h" +#include "wingdi.h" +#include "wine/exception.h" +#include "excpt.h" + +#include "ddraw.h" +#include "d3d.h" + +#include "ddraw_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d3d7); +WINE_DECLARE_DEBUG_CHANNEL(ddraw_thunk); + +/* The device ID */ +const GUID IID_D3DDEVICE_WineD3D = { + 0xaef72d43, + 0xb09a, + 0x4b7b, + { 0xb7,0x98,0xc6,0x8a,0x77,0x2d,0x72,0x2a } +}; + +/***************************************************************************** + * IUnknown Methods. Common for Version 1, 2, 3 and 7 + *****************************************************************************/ + +/***************************************************************************** + * IDirect3DDevice7::QueryInterface + * + * Used to query other interfaces from a Direct3DDevice interface. + * It can return interface pointers to all Direct3DDevice versions as well + * as IDirectDraw and IDirect3D. For a link for QueryInterface + * rules see ddraw.c, IDirectDraw7::QueryInterface + * + * Exists in Version 1, 2, 3 and 7 + * + * Params: + * refiid: Interface ID queried for + * obj: Used to return the interface pointer + * + * Returns: + * D3D_OK or E_NOINTERFACE + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_7_QueryInterface(IDirect3DDevice7 *iface, + REFIID refiid, + void **obj) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, 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(!refiid) + return DDERR_INVALIDPARAMS; + + if ( IsEqualGUID( &IID_IUnknown, refiid ) ) + { + *obj = ICOM_INTERFACE(This, IDirect3DDevice7); + } + + /* Check DirectDraw Interfacs */ + else if( IsEqualGUID( &IID_IDirectDraw7, refiid ) ) + { + *obj = ICOM_INTERFACE(This->ddraw, IDirectDraw7); + TRACE("(%p) Returning IDirectDraw7 interface at %p\n", This, *obj); + } + else if ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) + { + *obj = ICOM_INTERFACE(This->ddraw, IDirectDraw4); + TRACE("(%p) Returning IDirectDraw4 interface at %p\n", This, *obj); + } + else if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) ) + { + *obj = ICOM_INTERFACE(This->ddraw, IDirectDraw2); + TRACE("(%p) Returning IDirectDraw2 interface at %p\n", This, *obj); + } + else if( IsEqualGUID( &IID_IDirectDraw, refiid ) ) + { + *obj = ICOM_INTERFACE(This->ddraw, IDirectDraw); + TRACE("(%p) Returning IDirectDraw interface at %p\n", This, *obj); + } + + /* Direct3D */ + else if ( IsEqualGUID( &IID_IDirect3D , refiid ) ) + { + *obj = ICOM_INTERFACE(This->ddraw, IDirect3D); + TRACE("(%p) Returning IDirect3D interface at %p\n", This, *obj); + } + else if ( IsEqualGUID( &IID_IDirect3D2 , refiid ) ) + { + *obj = ICOM_INTERFACE(This->ddraw, IDirect3D2); + TRACE("(%p) Returning IDirect3D2 interface at %p\n", This, *obj); + } + else if ( IsEqualGUID( &IID_IDirect3D3 , refiid ) ) + { + *obj = ICOM_INTERFACE(This->ddraw, IDirect3D3); + TRACE("(%p) Returning IDirect3D3 interface at %p\n", This, *obj); + } + else if ( IsEqualGUID( &IID_IDirect3D7 , refiid ) ) + { + *obj = ICOM_INTERFACE(This->ddraw, IDirect3D7); + TRACE("(%p) Returning IDirect3D7 interface at %p\n", This, *obj); + } + + /* Direct3DDevice */ + else if ( IsEqualGUID( &IID_IDirect3DDevice , refiid ) ) + { + *obj = ICOM_INTERFACE(This, IDirect3DDevice); + TRACE("(%p) Returning IDirect3DDevice interface at %p\n", This, *obj); + } + else if ( IsEqualGUID( &IID_IDirect3DDevice2 , refiid ) ) { + *obj = ICOM_INTERFACE(This, IDirect3DDevice2); + TRACE("(%p) Returning IDirect3DDevice2 interface at %p\n", This, *obj); + } + else if ( IsEqualGUID( &IID_IDirect3DDevice3 , refiid ) ) { + *obj = ICOM_INTERFACE(This, IDirect3DDevice3); + TRACE("(%p) Returning IDirect3DDevice3 interface at %p\n", This, *obj); + } + else if ( IsEqualGUID( &IID_IDirect3DDevice7 , refiid ) ) { + *obj = ICOM_INTERFACE(This, IDirect3DDevice7); + TRACE("(%p) Returning IDirect3DDevice7 interface at %p\n", This, *obj); + } + + /* Unknown interface */ + else + { + ERR("(%p)->(%s, %p): No interface found", This, debugstr_guid(refiid), obj); + return E_NOINTERFACE; + } + + /* AddRef the returned interface */ + IUnknown_AddRef( (IUnknown *) *obj); + return D3D_OK; +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_3_QueryInterface(IDirect3DDevice3 *iface, + REFIID riid, + void **obj) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); + TRACE_(ddraw_thunk)("(%p)->(%s,%p) thunking to IDirect3DDevice7 interface.\n", This, debugstr_guid(riid), obj); + return IDirect3DDevice7_QueryInterface(ICOM_INTERFACE(This, IDirect3DDevice7), + riid, + obj); +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_2_QueryInterface(IDirect3DDevice2 *iface, + REFIID riid, + void **obj) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface); + TRACE_(ddraw_thunk)("(%p)->(%s,%p) thunking to IDirect3DDevice7 interface.\n", This, debugstr_guid(riid), obj); + return IDirect3DDevice7_QueryInterface(ICOM_INTERFACE(This, IDirect3DDevice7), + riid, + obj); +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_1_QueryInterface(IDirect3DDevice *iface, + REFIID riid, + void **obp) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface); + TRACE_(ddraw_thunk)("(%p)->(%s,%p) thunking to IDirect3DDevice7 interface.\n", This, debugstr_guid(riid), obp); + return IDirect3DDevice7_QueryInterface(ICOM_INTERFACE(This, IDirect3DDevice7), + riid, + obp); +} + +/***************************************************************************** + * IDirect3DDevice7::AddRef + * + * Increases the refcount.... + * The most exciting Method, definitly + * + * Exists in Version 1, 2, 3 and 7 + * + * Returns: + * The new refcount + * + *****************************************************************************/ +static ULONG WINAPI +IDirect3DDeviceImpl_7_AddRef(IDirect3DDevice7 *iface) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); + ULONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) : incrementing from %lu.\n", This, ref -1); + + return ref; +} + +static ULONG WINAPI +Thunk_IDirect3DDeviceImpl_3_AddRef(IDirect3DDevice3 *iface) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); + TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This); + return IDirect3DDevice7_AddRef(ICOM_INTERFACE(This, IDirect3DDevice7)); +} + +static ULONG WINAPI +Thunk_IDirect3DDeviceImpl_2_AddRef(IDirect3DDevice2 *iface) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface); + TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This); + return IDirect3DDevice7_AddRef(ICOM_INTERFACE(This, IDirect3DDevice7)); +} + +static ULONG WINAPI +Thunk_IDirect3DDeviceImpl_1_AddRef(IDirect3DDevice *iface) +{ + TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", iface); + return IDirect3DDevice7_AddRef(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice7, iface)); +} + +/***************************************************************************** + * IDirect3DDevice7::Release + * + * Decreases the refcount of the interface + * When the refcount is reduced to 0, the object is destroyed. + * + * Exists in Version 1, 2, 3 and 7 + * + * Returns:d + * The new refcount + * + *****************************************************************************/ +static ULONG WINAPI +IDirect3DDeviceImpl_7_Release(IDirect3DDevice7 *iface) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p)->() decrementing from %lu.\n", This, ref +1); + + /* This method doesn't destroy the WineD3DDevice, because it's still in use for + * 2D rendering. IDirectDrawSurface7::Release will destroy the WineD3DDevice + * when the render target is released + */ + if (ref == 0) + { + IParent *IndexBufferParent; + /* Free the index buffer */ + IWineD3DDevice_SetIndices(This->wineD3DDevice, + NULL, + 0); + IWineD3DIndexBuffer_GetParent(This->indexbuffer, + (IUnknown **) &IndexBufferParent); + IParent_Release(IndexBufferParent); /* Once for the getParent */ + if( IParent_Release(IndexBufferParent) != 0) /* And now to destroy it */ + { + ERR(" (%p) Something is still holding the index buffer parent %p\n", This, IndexBufferParent); + } + + /* Restore the render targets */ + if(This->OffScreenTarget) + { + /* This->target is the offscreen target. + * This->ddraw->d3d_target is the target used by DDraw + */ + TRACE("(%p) Release: Using %p as front buffer, %p as back buffer\n", This, This->ddraw->d3d_target, NULL); + IWineD3DDevice_SetFrontBackBuffers(This->wineD3DDevice, + This->ddraw->d3d_target->WineD3DSurface, + NULL); + } + + /* Release the WineD3DDevice. This won't destroy it */ + if(IWineD3DDevice_Release(This->wineD3DDevice) <= 0) + { + ERR(" (%p) The wineD3D device %p was destroyed unexpectadely. Prepare for trouble\n", This, This->wineD3DDevice); + } + + /* Release the render target and the WineD3D render target + * (See IDirect3D7::CreateDevice for more comments on this) + */ + IDirectDrawSurface7_Release(ICOM_INTERFACE(This->target, IDirectDrawSurface7)); + IDirectDrawSurface7_Release(ICOM_INTERFACE(This->ddraw->d3d_target,IDirectDrawSurface7)); + + This->ddraw->d3ddevice = NULL; + + /* Now free the structure */ + HeapFree(GetProcessHeap(), 0, This); + } + + return ref; +} + +static ULONG WINAPI +Thunk_IDirect3DDeviceImpl_3_Release(IDirect3DDevice3 *iface) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); + TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This); + return IDirect3DDevice7_Release(ICOM_INTERFACE(This, IDirect3DDevice7)); +} + +static ULONG WINAPI +Thunk_IDirect3DDeviceImpl_2_Release(IDirect3DDevice2 *iface) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface); + TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This); + return IDirect3DDevice7_Release(ICOM_INTERFACE(This, IDirect3DDevice7)); +} + +static ULONG WINAPI +Thunk_IDirect3DDeviceImpl_1_Release(IDirect3DDevice *iface) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface); + TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This); + return IDirect3DDevice7_Release(ICOM_INTERFACE(This, IDirect3DDevice7)); +} + +/***************************************************************************** + * IDirect3DDevice Methods + *****************************************************************************/ + +/***************************************************************************** + * IDirect3DDevice::Initialize + * + * Initializes a Direct3DDevice. This implementation is a no-op, as all + * initialization is done at create time. + * + * Exists in Version 1 + * + * Parameters: + * No idea what they mean, as the MSDN page is gone + * + * Returns: DD_OK + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_1_Initialize(IDirect3DDevice *iface, + IDirect3D *Direct3D, GUID *guid, + D3DDEVICEDESC *Desc) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface); + + /* It shouldn't be crucial, but print a FIXME, I'm interested if + * any game calls it and when + */ + FIXME("(%p)->(%p,%p,%p): No-op!\n", This, Direct3D, guid, Desc); + + return D3D_OK; +} + +/***************************************************************************** + * IDirect3DDevice7::GetCaps + * + * Retrieves the device's capatiblities + * + * This implementation is used for Version 7 only, the older versions have + * their own implementation. + * + * Parameters: + * Desc: Pointer to a D3DDEVICEDESC7 structure to fill + * + * Returns: + * D3D_OK on success + * D3DERR_* if a problem occurs. See WineD3D + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_7_GetCaps(IDirect3DDevice7 *iface, + D3DDEVICEDESC7 *Desc) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); + D3DDEVICEDESC OldDesc; + TRACE("(%p)->(%p)\n", This, Desc); + + /* Call the same function used by IDirect3D, this saves code */ + return IDirect3DImpl_GetCaps(This->ddraw->wineD3D, &OldDesc, Desc); +} + +/***************************************************************************** + * IDirect3DDevice3::GetCaps + * + * Retrieves the capatiblities of the hardware device and the emulation + * device. For Wine, hardware and emulation are the same(it's all HW). + * + * This implementation is used for Version 1, 2, and 3. Version 7 has its own + * + * Parameters: + * HWDesc: Structure to fill with the HW caps + * HelDesc: Structure to fill with the hardare emulation caps + * + * Returns: + * D3D_OK on success + * D3DERR_* if a problem occurs. See WineD3D + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_3_GetCaps(IDirect3DDevice3 *iface, + D3DDEVICEDESC *HWDesc, + D3DDEVICEDESC *HelDesc) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); + D3DDEVICEDESC7 newDesc; + HRESULT hr; + TRACE("(%p)->(%p,%p)\n", iface, HWDesc, HelDesc); + + hr = IDirect3DImpl_GetCaps(This->ddraw->wineD3D, HWDesc, &newDesc); + if(hr != D3D_OK) return hr; + + *HelDesc = *HWDesc; + return D3D_OK; +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_2_GetCaps(IDirect3DDevice2 *iface, + D3DDEVICEDESC *D3DHWDevDesc, + D3DDEVICEDESC *D3DHELDevDesc) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface); + TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice3 interface.\n", This, D3DHWDevDesc, D3DHELDevDesc); + return IDirect3DDevice3_GetCaps(ICOM_INTERFACE(This, IDirect3DDevice3), + D3DHWDevDesc, + D3DHELDevDesc); +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_1_GetCaps(IDirect3DDevice *iface, + D3DDEVICEDESC *D3DHWDevDesc, + D3DDEVICEDESC *D3DHELDevDesc) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface); + TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice3 interface.\n", This, D3DHWDevDesc, D3DHELDevDesc); + return IDirect3DDevice3_GetCaps(ICOM_INTERFACE(This, IDirect3DDevice3), + D3DHWDevDesc, + D3DHELDevDesc); +} + +/***************************************************************************** + * IDirect3DDevice2::SwapTextureHandles + * + * Swaps the texture handles of 2 Texture interfaces. Version 1 and 2 + * + * Parameters: + * Tex1, Tex2: The 2 Textures to swap + * + * Returns: + * D3D_OK + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_2_SwapTextureHandles(IDirect3DDevice2 *iface, + IDirect3DTexture2 *Tex1, + IDirect3DTexture2 *Tex2) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface); + IWineD3DTexture *tmp; + IDirectDrawSurfaceImpl *surf1 = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture2, Tex1); + IDirectDrawSurfaceImpl *surf2 = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture2, Tex2); + FIXME("(%p)->(%p,%p)\n", This, surf1, surf2); + + + /* The texture handle is simply the interface address of the WineD3DTexture + * interface. Swap the interface pointers. + */ + tmp = surf1->wineD3DTexture; + surf1->wineD3DTexture = surf2->wineD3DTexture; + surf2->wineD3DTexture = tmp; + + /* What about the parent? Does it have to change too? This could cause a + * problem when Releasing the surfaces, Therefore the fixme + */ + + return D3D_OK; +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_1_SwapTextureHandles(IDirect3DDevice *iface, + IDirect3DTexture *D3DTex1, + IDirect3DTexture *D3DTex2) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface); + IDirectDrawSurfaceImpl *surf1 = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture, D3DTex1); + IDirectDrawSurfaceImpl *surf2 = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture, D3DTex2); + TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice2 interface.\n", This, surf1, surf2); + return IDirect3DDevice2_SwapTextureHandles(ICOM_INTERFACE(This, IDirect3DDevice2), + ICOM_INTERFACE(surf1, IDirect3DTexture2), + ICOM_INTERFACE(surf2, IDirect3DTexture2)); +} + +/***************************************************************************** + * IDirect3DDevice3::GetStats + * + * This method seems to retrieve some stats from the device. + * The MSDN documentation doesn't exist any more, but the D3DSTATS + * structure suggests that the amout of drawn primitives and processed + * vertices is returned. + * + * Exists in Version 1, 2 and 3 + * + * Parameters: + * Stats: Pointer to a D3DSTATS structure to be filled + * + * Returns: + * D3D_OK on success + * DDERR_INVALIDPARAMS if Stats == NULL + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_3_GetStats(IDirect3DDevice3 *iface, + D3DSTATS *Stats) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); + FIXME("(%p)->(%p): Stub!\n", This, Stats); + + if(!Stats) + return DDERR_INVALIDPARAMS; + + /* Fill the Stats with 0 */ + Stats->dwTrianglesDrawn = 0; + Stats->dwLinesDrawn = 0; + Stats->dwPointsDrawn = 0; + Stats->dwSpansDrawn = 0; + Stats->dwVerticesProcessed = 0; + + return D3D_OK; +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_2_GetStats(IDirect3DDevice2 *iface, + D3DSTATS *Stats) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface); + TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, Stats); + return IDirect3DDevice3_GetStats(ICOM_INTERFACE(This, IDirect3DDevice3), + Stats); +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_1_GetStats(IDirect3DDevice *iface, + D3DSTATS *Stats) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface); + TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, Stats); + return IDirect3DDevice3_GetStats(ICOM_INTERFACE(This, IDirect3DDevice3), + Stats); +} + +/***************************************************************************** + * IDirect3DDevice::CreateExecuteBuffer + * + * Creates an IDirect3DExecuteBuffer, used for rendering with a + * Direct3DDevice. + * + * Version 1 only. + * + * Params: + * Desc: Buffer description + * ExecuteBuffer: Address to return the Interface pointer at + * UnkOuter: Must be NULL. Basically for aggreation, which ddraw doesn't + * support + * + * Returns: + * CLASS_E_NOAGGREGATION if UnkOuter != NULL + * DDERR_OUTOFMEMORY if we ran out of memory + * D3D_OK on success + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_1_CreateExecuteBuffer(IDirect3DDevice *iface, + D3DEXECUTEBUFFERDESC *Desc, + IDirect3DExecuteBuffer **ExecuteBuffer, + IUnknown *UnkOuter) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface); + IDirect3DExecuteBufferImpl* object; + TRACE("(%p)->(%p,%p,%p)!\n", This, Desc, ExecuteBuffer, UnkOuter); + + if(UnkOuter) + return CLASS_E_NOAGGREGATION; + + /* Allocate the new Execute Buffer */ + object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DExecuteBufferImpl)); + if(!object) + { + ERR("Out of memory when allocating a IDirect3DExecuteBufferImpl structure\n"); + return DDERR_OUTOFMEMORY; + } + + ICOM_INIT_INTERFACE(object, IDirect3DExecuteBuffer, IDirect3DExecuteBuffer_Vtbl); + + object->ref = 1; + object->d3ddev = This; + + /* Initializes memory */ + memcpy(&object->desc, Desc, Desc->dwSize); + + /* No buffer given */ + if ((object->desc.dwFlags & D3DDEB_LPDATA) == 0) + object->desc.lpData = NULL; + + /* No buffer size given */ + if ((object->desc.dwFlags & D3DDEB_BUFSIZE) == 0) + object->desc.dwBufferSize = 0; + + /* Create buffer if asked */ + if ((object->desc.lpData == NULL) && (object->desc.dwBufferSize > 0)) + { + object->need_free = TRUE; + object->desc.lpData = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,object->desc.dwBufferSize); + if(!object->desc.lpData) + { + ERR("Out of memory when allocating the execute buffer data\n"); + HeapFree(GetProcessHeap(), 0, object); + return DDERR_OUTOFMEMORY; + } + } + else + { + object->need_free = FALSE; + } + + /* No vertices for the moment */ + object->vertex_data = NULL; + + object->desc.dwFlags |= D3DDEB_LPDATA; + + object->indices = NULL; + object->nb_indices = 0; + + *ExecuteBuffer = ICOM_INTERFACE(object, IDirect3DExecuteBuffer); + + TRACE(" Returning IDirect3DExecuteBuffer at %p, implementation is at %p\n", *ExecuteBuffer, object); + + return D3D_OK; +} + +/***************************************************************************** + * IDirect3DDevice::Execute + * + * Executes all the stuff in an execute buffer. + * + * Params: + * ExecuteBuffer: The buffer to execute + * Viewport: The viewport used for rendering + * Flags: Some flags + * + * Returns: + * DDERR_INVALIDPARAMS if ExecuteBuffer == NULL + * D3D_OK on sucess + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_1_Execute(IDirect3DDevice *iface, + IDirect3DExecuteBuffer *ExecuteBuffer, + IDirect3DViewport *Viewport, + DWORD Flags) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface); + IDirect3DExecuteBufferImpl *Direct3DExecuteBufferImpl = ICOM_OBJECT(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, ExecuteBuffer); + IDirect3DViewportImpl *Direct3DViewportImpl = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport); + + TRACE("(%p)->(%p,%p,%08lx)\n", This, Direct3DExecuteBufferImpl, Direct3DViewportImpl, Flags); + + if(!Direct3DExecuteBufferImpl) + return DDERR_INVALIDPARAMS; + + /* Execute... */ + IDirect3DExecuteBufferImpl_Execute(Direct3DExecuteBufferImpl, This, Direct3DViewportImpl); + + return D3D_OK; +} + +/***************************************************************************** + * IDirect3DDevice3::AddViewport + * + * Add a Direct3DViewport to the device's viewport list. These viewports + * are wrapped to IDirect3DDevice7 viewports in viewport.c + * + * Exists in Version 1, 2 and 3. Note that IDirect3DViewport 1, 2 and 3 + * are the same interfaces. + * + * Params: + * Viewport: The viewport to add + * + * Returns: + * DDERR_INVALIDPARAMS if Viewport == NULL + * D3D_OK on success + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_3_AddViewport(IDirect3DDevice3 *iface, + IDirect3DViewport3 *Viewport) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); + IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport); + + TRACE("(%p)->(%p)\n", This, vp); + + /* Sanity check */ + if(!vp) + return DDERR_INVALIDPARAMS; + + vp->next = This->viewport_list; + This->viewport_list = vp; + + return D3D_OK; +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_2_AddViewport(IDirect3DDevice2 *iface, + IDirect3DViewport2 *Direct3DViewport2) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface); + IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport2); + TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp); + return IDirect3DDevice3_AddViewport(ICOM_INTERFACE(This, IDirect3DDevice3), + ICOM_INTERFACE(vp, IDirect3DViewport3)); +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_1_AddViewport(IDirect3DDevice *iface, + IDirect3DViewport *Direct3DViewport) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface); + IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport); + TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp); + return IDirect3DDevice3_AddViewport(ICOM_INTERFACE(This, IDirect3DDevice3), + ICOM_INTERFACE(vp, IDirect3DViewport3)); +} + +/***************************************************************************** + * IDirect3DDevice3::DeleteViewport + * + * Deletes a Direct3DViewport from the device's viewport list. + * + * Exists in Version 1, 2 and 3. Note that all Viewport interface versions + * are equal. + * + * Params: + * Viewport: The viewport to delete + * + * Returns: + * D3D_OK on success + * DDERR_INVALIDPARAMS if the viewport wasn't found in the list + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_3_DeleteViewport(IDirect3DDevice3 *iface, + IDirect3DViewport3 *Viewport) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); + IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *) Viewport; + IDirect3DViewportImpl *cur_viewport, *prev_viewport = NULL; + + TRACE("(%p)->(%p)\n", This, vp); + + cur_viewport = This->viewport_list; + while (cur_viewport != NULL) + { + if (cur_viewport == vp) + { + if (prev_viewport == NULL) This->viewport_list = cur_viewport->next; + else prev_viewport->next = cur_viewport->next; + /* TODO : add desactivate of the viewport and all associated lights... */ + return D3D_OK; + } + prev_viewport = cur_viewport; + cur_viewport = cur_viewport->next; + } + + return DDERR_INVALIDPARAMS; +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_2_DeleteViewport(IDirect3DDevice2 *iface, + IDirect3DViewport2 *Direct3DViewport2) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface); + IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport2); + TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp); + return IDirect3DDevice3_DeleteViewport(ICOM_INTERFACE(This, IDirect3DDevice3), + ICOM_INTERFACE(vp, IDirect3DViewport3)); +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_1_DeleteViewport(IDirect3DDevice *iface, + IDirect3DViewport *Direct3DViewport2) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface); + IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport2); + TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp); + return IDirect3DDevice3_DeleteViewport(ICOM_INTERFACE(This, IDirect3DDevice3), + ICOM_INTERFACE(vp, IDirect3DViewport3)); +} + +/***************************************************************************** + * IDirect3DDevice3::NextViewport + * + * Returns an viewport from the viewport list, depending on the + * passed viewport and the flags. + * + * Exists in Version 1, 2 and 3. Note that all Viewport interface versions + * are equal. + * + * Params: + * Viewport: Viewport to use for beginning the search + * Flags: D3DNEXT_NEXT, D3DNEXT_HEAD or D3DNEXT_TAIL + * + * Returns: + * D3D_OK on success + * DDERR_INVALIDPARAMS if the flags were wrong, ir Viewport was NULL + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_3_NextViewport(IDirect3DDevice3 *iface, + IDirect3DViewport3 *Viewport3, + IDirect3DViewport3 **lplpDirect3DViewport3, + DWORD Flags) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); + IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport3); + IDirect3DViewportImpl *res = NULL; + + TRACE("(%p)->(%p,%p,%08lx)\n", This, vp, lplpDirect3DViewport3, Flags); + + if(!vp) + { + return DDERR_INVALIDPARAMS; + *lplpDirect3DViewport3 = NULL; + } + + + switch (Flags) + { + case D3DNEXT_NEXT: + { + res = vp->next; + } + break; + case D3DNEXT_HEAD: + { + res = This->viewport_list; + } + break; + case D3DNEXT_TAIL: + { + IDirect3DViewportImpl *cur_viewport = This->viewport_list; + if (cur_viewport != NULL) + { + while (cur_viewport->next != NULL) cur_viewport = cur_viewport->next; + } + res = cur_viewport; + } + break; + default: + *lplpDirect3DViewport3 = NULL; + return DDERR_INVALIDPARAMS; + } + + *lplpDirect3DViewport3 = ICOM_INTERFACE(res, IDirect3DViewport3); + return D3D_OK; +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_2_NextViewport(IDirect3DDevice2 *iface, + IDirect3DViewport2 *Viewport2, + IDirect3DViewport2 **lplpDirect3DViewport2, + DWORD Flags) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface); + IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport2); + IDirect3DViewport3 *res; + HRESULT hr; + TRACE_(ddraw_thunk)("(%p)->(%p,%p,%08lx) thunking to IDirect3DDevice3 interface.\n", This, vp, lplpDirect3DViewport2, Flags); + hr = IDirect3DDevice3_NextViewport(ICOM_INTERFACE(This, IDirect3DDevice3), + ICOM_INTERFACE(vp, IDirect3DViewport3), + &res, + Flags); + *lplpDirect3DViewport2 = (IDirect3DViewport2 *) COM_INTERFACE_CAST(IDirect3DViewportImpl, IDirect3DViewport3, IDirect3DViewport3, res); + return hr; +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_1_NextViewport(IDirect3DDevice *iface, + IDirect3DViewport *Viewport, + IDirect3DViewport **lplpDirect3DViewport, + DWORD Flags) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface); + IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport); + IDirect3DViewport3 *res; + HRESULT hr; + TRACE_(ddraw_thunk)("(%p)->(%p,%p,%08lx) thunking to IDirect3DDevice3 interface.\n", This, vp, lplpDirect3DViewport, Flags); + hr = IDirect3DDevice3_NextViewport(ICOM_INTERFACE(This, IDirect3DDevice3), + ICOM_INTERFACE(vp, IDirect3DViewport3), + &res, + Flags); + *lplpDirect3DViewport = (IDirect3DViewport *) COM_INTERFACE_CAST(IDirect3DViewportImpl, IDirect3DViewport3, IDirect3DViewport3, res); + return hr; +} + +/***************************************************************************** + * IDirect3DDevice::Pick + * + * Executes an execute buffer without performing rendering. Instead, a + * list of primitives that intersect with (x1,y1) of the passed rectangle + * is created. IDirect3DDevice::GetPickRecords can be used to retrieve + * this list. + * + * Version 1 only + * + * Params: + * ExecuteBuffer: Buffer to execute + * Viewport: Viewport to use for execution + * Flags: None are defined, according to the SDK + * Rect: Specifies the coordinates to be picked. Only x1 and y2 are used, + * x2 and y2 are ignored. + * + * Returns: + * D3D_OK because it's a stub + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_1_Pick(IDirect3DDevice *iface, + IDirect3DExecuteBuffer *ExecuteBuffer, + IDirect3DViewport *Viewport, + DWORD Flags, + D3DRECT *Rect) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface); + IDirect3DExecuteBufferImpl *execbuf = ICOM_OBJECT(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, ExecuteBuffer); + IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport); + FIXME("(%p)->(%p,%p,%08lx,%p): stub!\n", This, execbuf, vp, Flags, Rect); + + return D3D_OK; +} + +/***************************************************************************** + * IDirect3DDevice::GetPickRecords + * + * Retrieves the pick records generated by IDirect3DDevice::GetPickRecords + * + * Version 1 only + * + * Params: + * Count: Pointer to a DWORD containing the numbers of pick records to + * retrieve + * D3DPickRec: Address to store the resulting D3DPICKRECORD arry. + * + * Returns: + * D3D_OK, because it's a stub + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_1_GetPickRecords(IDirect3DDevice *iface, + DWORD *Count, + D3DPICKRECORD *D3DPickRec) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface); + FIXME("(%p)->(%p,%p): stub!\n", This, Count, D3DPickRec); + + return D3D_OK; +} + +/***************************************************************************** + * EnumTextureFormatsCB + * + * Callback called by WineD3D for each enumerated Texture format. It + * translates the WineD3DFormat into a ddraw pixel format and calls + * the application callback + * + * Params: + * Device: The WineD3DDevice's parents = The IDirect3DDevice7 interface + * of our device + * fmt: An enumerated pixel format + * Context: Data pointer passed to WineD3D by + * IDirect3DDevice7::EnumTexureformats + * + * Returns: + * The return value of the application-provided callback + * + *****************************************************************************/ +static HRESULT WINAPI +EnumTextureFormatsCB(IUnknown *Device, + WINED3DFORMAT fmt, + void *Context) +{ + struct EnumTextureFormatsCBS *cbs = (struct EnumTextureFormatsCBS *) Context; + + DDSURFACEDESC sdesc; + DDPIXELFORMAT *pformat; + + memset(&sdesc, 0, sizeof(DDSURFACEDESC)); + sdesc.dwSize = sizeof(DDSURFACEDESC); + sdesc.dwFlags = DDSD_PIXELFORMAT | DDSD_CAPS; + sdesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE; + pformat = &(sdesc.ddpfPixelFormat); + pformat->dwSize = sizeof(DDPIXELFORMAT); + + PixelFormat_WineD3DtoDD(pformat, fmt); + + if( ( fmt == WINED3DFMT_UYVY) || + ( fmt == WINED3DFMT_YUY2) || + ( fmt == WINED3DFMT_DXT1) || + ( fmt == WINED3DFMT_DXT2) || + ( fmt == WINED3DFMT_DXT3) || + ( fmt == WINED3DFMT_DXT4) || + ( fmt == WINED3DFMT_DXT5) || + ( fmt == WINED3DFMT_MULTI2_ARGB) || + ( fmt == WINED3DFMT_G8R8_G8B8) || + ( fmt == WINED3DFMT_R8G8_B8G8) || + ( fmt == WINED3DFMT_L8) || + ( fmt == WINED3DFMT_A8L8) || + ( fmt == WINED3DFMT_A4L4) || + ( fmt == WINED3DFMT_V8U8) || + ( fmt == WINED3DFMT_L6V5U5) ) + { + /* These formats exist exist in D3D3 and D3D7 only, + * so do not call the older callback + */ + if(cbs->cbv7) return cbs->cbv7(pformat, cbs->Context); + } + else + { + /* Only one of these should be passed */ + if(cbs->cbv2) return cbs->cbv2(&sdesc, cbs->Context); + if(cbs->cbv7) return cbs->cbv7(pformat, cbs->Context); + } + + return DDENUMRET_OK; +} + +/***************************************************************************** + * IDirect3DDevice7::EnumTextureformats + * + * Enumerates the supported texture formats. This is relayed to WineD3D, + * and a EnumTextureFormatsCB translated the WineD3DFormats to DDraw + * formats and calls the application callback. + * + * This is for Version 7 and 3, the older versions have a different + * callback function and their own implementation + * + * Params: + * Callback: Callback to call for each enumerated format + * Arg: Argument to pass to the callback + * + * Returns: + * D3D_OK on success + * DDERR_INVALIDPARAMS if Callback == NULL + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_7_EnumTextureFormats(IDirect3DDevice7 *iface, + LPD3DENUMPIXELFORMATSCALLBACK Callback, + void *Arg) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); + HRESULT hr; + struct EnumTextureFormatsCBS cbs = { NULL, Callback, Arg }; + TRACE("(%p)->(%p,%p): Relay\n", This, Callback, Arg); + + if(!Callback) + return DDERR_INVALIDPARAMS; + + hr = IWineD3DDevice_EnumTextureFormats(This->wineD3DDevice, + EnumTextureFormatsCB, + &cbs); + return hr_ddraw_from_wined3d(hr); +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats(IDirect3DDevice3 *iface, + LPD3DENUMPIXELFORMATSCALLBACK Callback, + void *Arg) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); + TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice7 interface.\n", This, Callback, Arg); + return IDirect3DDevice7_EnumTextureFormats(ICOM_INTERFACE(This, IDirect3DDevice7), + Callback, + Arg); +} + +/***************************************************************************** + * IDirect3DDevice2::EnumTextureformats + * + * EnumTextureFormats for Version 1 and 2, see + * IDirect3DDevice7::EnumTexureFormats for a more detailed description + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_2_EnumTextureFormats(IDirect3DDevice2 *iface, + LPD3DENUMTEXTUREFORMATSCALLBACK Callback, + void *Arg) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface); + HRESULT hr; + struct EnumTextureFormatsCBS cbs = { Callback, NULL, Arg }; + TRACE("(%p)->(%p,%p): Relay\n", This, Callback, Arg); + + hr = IWineD3DDevice_EnumTextureFormats(This->wineD3DDevice, + EnumTextureFormatsCB, + &cbs); + return hr_ddraw_from_wined3d(hr); +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats(IDirect3DDevice *iface, + LPD3DENUMTEXTUREFORMATSCALLBACK Callback, + void *Arg) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface); + TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice2 interface.\n", This, Callback, Arg); + return IDirect3DDevice2_EnumTextureFormats(ICOM_INTERFACE(This, IDirect3DDevice2), + Callback, + Arg); +} + +/***************************************************************************** + * IDirect3DDevice::CreateMatrix + * + * Creates a matrix handle. In Wine, Matrix handles are simply pointers + * to a D3DMATRIX structure + * + * Version 1 only + * + * Params + * D3DMatHandle: Address to return the handle at + * + * Returns: + * D3D_OK on success + * DDERR_INVALIDPARAMS if D3DMatHandle = NULL + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_1_CreateMatrix(IDirect3DDevice *iface, D3DMATRIXHANDLE *D3DMatHandle) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface); + TRACE("(%p)->(%p)\n", This, D3DMatHandle); + + if(!D3DMatHandle) + return DDERR_INVALIDPARAMS; + + *D3DMatHandle = (D3DMATRIXHANDLE) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(D3DMATRIX)); + TRACE(" returning matrix handle %p\n", (void *) *D3DMatHandle); + + return D3D_OK; +} + +/***************************************************************************** + * IDirect3DDevice::SetMatrix + * + * Sets a matrix for a matrix handle. As matrix handles are pointers to + * a D3DMATRIX structure, the matrix is simply copied into the allocated + * memory. + * + * Version 1 only + * + * Params: + * D3DMatHandle: Handle to set the matrix to + * D3DMatrix: Matrix to set + * + * Returns: + * D3D_OK on success + * DDERR_INVALIDPARAMS if the handle of the matrix is NULL + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_1_SetMatrix(IDirect3DDevice *iface, + D3DMATRIXHANDLE D3DMatHandle, + D3DMATRIX *D3DMatrix) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface); + TRACE("(%p)->(%08lx,%p)\n", This, (DWORD) D3DMatHandle, D3DMatrix); + + if( (!D3DMatHandle) || (!D3DMatrix) ) + return DDERR_INVALIDPARAMS; + + if (TRACE_ON(d3d7)) + dump_D3DMATRIX(D3DMatrix); + + *((D3DMATRIX *) D3DMatHandle) = *D3DMatrix; + + return D3D_OK; +} + +/***************************************************************************** + * IDirect3DDevice::SetMatrix + * + * Returns the content of a D3DMATRIX handle + * + * Version 1 only + * + * Params: + * D3DMatHandle: Matrix handle to read the content from + * D3DMatrix: Address to store the content at + * + * Returns: + * D3D_OK on success + * DDERR_INVALIDPARAMS if D3DMatHandle or D3DMatrix are NULL + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_1_GetMatrix(IDirect3DDevice *iface, + D3DMATRIXHANDLE D3DMatHandle, + D3DMATRIX *D3DMatrix) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface); + TRACE("(%p)->(%08lx,%p)\n", This, (DWORD) D3DMatHandle, D3DMatrix); + + if(!D3DMatrix) + return DDERR_INVALIDPARAMS; + if(!(D3DMATRIX *) D3DMatHandle) + return DDERR_INVALIDPARAMS; + + /* The handle is simply a pointer to a D3DMATRIX structure */ + *D3DMatrix = *((D3DMATRIX *) D3DMatHandle); + + return D3D_OK; +} + +/***************************************************************************** + * IDirect3DDevice::DeleteMatrix + * + * Destroys a Matrix handle. + * + * Version 1 only + * + * Params: + * D3DMatHandle: Handle to destroy + * + * Returns: + * D3D_OK on success + * DDERR_INVALIDPARAMS if D3DMatHandle is NULL + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_1_DeleteMatrix(IDirect3DDevice *iface, + D3DMATRIXHANDLE D3DMatHandle) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface); + TRACE("(%p)->(%08lx)\n", This, (DWORD) D3DMatHandle); + + if(!(D3DMATRIX *) D3DMatHandle) + return DDERR_INVALIDPARAMS; + + HeapFree(GetProcessHeap(), 0, (void *) D3DMatHandle); + + return D3D_OK; +} + +/***************************************************************************** + * IDirect3DDevice7::BeginScene + * + * This method must be called before any rendering is performed. + * IDirect3DDevice::EndScene has to be called after the scene is complete + * + * Version 1, 2, 3 and 7 + * + * Returns: + * D3D_OK on sucess, for details see IWineD3DDevice::BeginScene + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_7_BeginScene(IDirect3DDevice7 *iface) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); + TRACE("(%p): Relay\n", This); + + return IWineD3DDevice_BeginScene(This->wineD3DDevice); +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_3_BeginScene(IDirect3DDevice3 *iface) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); + TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This); + return IDirect3DDevice7_BeginScene(ICOM_INTERFACE(This, IDirect3DDevice7)); +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_2_BeginScene(IDirect3DDevice2 *iface) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface); + TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This); + return IDirect3DDevice7_BeginScene(ICOM_INTERFACE(This, IDirect3DDevice7)); +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_1_BeginScene(IDirect3DDevice *iface) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface); + TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This); + return IDirect3DDevice7_BeginScene(ICOM_INTERFACE(This, IDirect3DDevice7)); +} + +/***************************************************************************** + * IDirect3DDevice7::EndScene + * + * Ends a scene that has been begun with IDirect3DDevice7::BeginScene. + * This method must be called after rendering is finished. + * + * Version 1, 2, 3 and 7 + * + * Returns: + * D3D_OK on success, for details see IWineD3DDevice::EndScene + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_7_EndScene(IDirect3DDevice7 *iface) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); + TRACE("(%p): Relay\n", This); + + IWineD3DDevice_EndScene(This->wineD3DDevice); + return D3D_OK; +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_3_EndScene(IDirect3DDevice3 *iface) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); + TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This); + return IDirect3DDevice7_EndScene(ICOM_INTERFACE(This, IDirect3DDevice7)); +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_2_EndScene(IDirect3DDevice2 *iface) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface); + TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This); + return IDirect3DDevice7_EndScene(ICOM_INTERFACE(This, IDirect3DDevice7)); +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_1_EndScene(IDirect3DDevice *iface) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface); + TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This); + return IDirect3DDevice7_EndScene(ICOM_INTERFACE(This, IDirect3DDevice7)); +} + +/***************************************************************************** + * IDirect3DDevice7::GetDirect3D + * + * Returns the IDirect3D(= interface to the DirectDraw object) used to create + * this device. + * + * Params: + * Direct3D7: Address to store the interface pointer at + * + * Returns: + * D3D_OK on success + * DDERR_INVALIDPARAMS if Direct3D7 == NULL + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_7_GetDirect3D(IDirect3DDevice7 *iface, + IDirect3D7 **Direct3D7) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); + TRACE("(%p)->(%p)\n", This, Direct3D7); + + if(!Direct3D7) + return DDERR_INVALIDPARAMS; + + *Direct3D7 = ICOM_INTERFACE(This->ddraw, IDirect3D7); + IDirect3D7_AddRef(*Direct3D7); + + TRACE(" returning interface %p\n", *Direct3D7); + return D3D_OK; +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_3_GetDirect3D(IDirect3DDevice3 *iface, + IDirect3D3 **Direct3D3) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); + HRESULT ret; + IDirect3D7 *ret_ptr; + + TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Direct3D3); + ret = IDirect3DDevice7_GetDirect3D(ICOM_INTERFACE(This, IDirect3DDevice7), + &ret_ptr); + if(ret != D3D_OK) + return ret; + *Direct3D3 = COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D7, IDirect3D3, ret_ptr); + TRACE(" returning interface %p\n", *Direct3D3); + return D3D_OK; +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_2_GetDirect3D(IDirect3DDevice2 *iface, + IDirect3D2 **Direct3D2) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface); + HRESULT ret; + IDirect3D7 *ret_ptr; + + TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Direct3D2); + ret = IDirect3DDevice7_GetDirect3D(ICOM_INTERFACE(This, IDirect3DDevice7), + &ret_ptr); + if(ret != D3D_OK) + return ret; + *Direct3D2 = COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D7, IDirect3D2, ret_ptr); + TRACE(" returning interface %p\n", *Direct3D2); + return D3D_OK; +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_1_GetDirect3D(IDirect3DDevice *iface, + IDirect3D **Direct3D) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface); + HRESULT ret; + IDirect3D7 *ret_ptr; + + TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Direct3D); + ret = IDirect3DDevice7_GetDirect3D(ICOM_INTERFACE(This, IDirect3DDevice7), + &ret_ptr); + if(ret != D3D_OK) + return ret; + *Direct3D = COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D7, IDirect3D, ret_ptr); + TRACE(" returning interface %p\n", *Direct3D); + return D3D_OK; +} + +/***************************************************************************** + * IDirect3DDevice3::SetCurrentViewport + * + * Sets a Direct3DViewport as the current viewport. + * For the thunks note that all viewport interface versions are equal + * + * Params: + * Direct3DViewport3: The viewport to set + * + * Version 2 and 3 + * + * Returns: + * D3D_OK on success + * (Is a NULL viewport valid?) + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_3_SetCurrentViewport(IDirect3DDevice3 *iface, + IDirect3DViewport3 *Direct3DViewport3) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); + IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport3); + TRACE("(%p)->(%p)\n", This, Direct3DViewport3); + + /* Do nothing if the specified viewport is the same as the current one */ + if (This->current_viewport == vp ) + return D3D_OK; + + /* Should check if the viewport was added or not */ + + /* Release previous viewport and AddRef the new one */ + if (This->current_viewport) + { + TRACE("ViewportImpl is at %p, interface is at %p\n", This->current_viewport, ICOM_INTERFACE(This->current_viewport, IDirect3DViewport3)); + IDirect3DViewport3_Release( ICOM_INTERFACE(This->current_viewport, IDirect3DViewport3) ); + } + IDirect3DViewport3_AddRef(Direct3DViewport3); + + /* Set this viewport as the current viewport */ + This->current_viewport = vp; + + /* Activate this viewport */ + This->current_viewport->active_device = This; + This->current_viewport->activate(This->current_viewport); + + return D3D_OK; +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport(IDirect3DDevice2 *iface, + IDirect3DViewport2 *Direct3DViewport2) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface); + IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport2); + TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp); + return IDirect3DDevice3_SetCurrentViewport(ICOM_INTERFACE(This, IDirect3DDevice3), + ICOM_INTERFACE(vp, IDirect3DViewport3)); +} + +/***************************************************************************** + * IDirect3DDevice3::GetCurrentViewport + * + * Returns the currently active viewport. + * + * Version 2 and 3 + * + * Params: + * Direct3DViewport3: Address to return the interface pointer at + * + * Returns: + * D3D_OK on success + * DDERR_INVALIDPARAMS if Direct3DViewport == NULL + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_3_GetCurrentViewport(IDirect3DDevice3 *iface, + IDirect3DViewport3 **Direct3DViewport3) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); + TRACE("(%p)->(%p)\n", This, Direct3DViewport3); + + if(!Direct3DViewport3) + return DDERR_INVALIDPARAMS; + + *Direct3DViewport3 = ICOM_INTERFACE(This->current_viewport, IDirect3DViewport3); + + /* AddRef the returned viewport */ + IDirect3DViewport3_AddRef(*Direct3DViewport3); + + TRACE(" returning interface %p\n", *Direct3DViewport3); + + return D3D_OK; +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport(IDirect3DDevice2 *iface, + IDirect3DViewport2 **Direct3DViewport2) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); + HRESULT hr; + TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, Direct3DViewport2); + hr = IDirect3DDevice3_GetCurrentViewport(ICOM_INTERFACE(This, IDirect3DDevice3), + (IDirect3DViewport3 **) Direct3DViewport2); + if(hr != D3D_OK) return hr; + *Direct3DViewport2 = (IDirect3DViewport2 *) COM_INTERFACE_CAST(IDirect3DViewportImpl, IDirect3DViewport3, IDirect3DViewport3, Direct3DViewport2); + return D3D_OK; +} + +/***************************************************************************** + * IDirect3DDevice7::SetRenderTarget + * + * Sets the render target for the Direct3DDevice. + * For the thunks note that IDirectDrawSurface7 == IDirectDrawSurface4 and + * IDirectDrawSurface3 == IDirectDrawSurface + * + * Version 2, 3 and 7 + * + * Params: + * NewTarget: Pointer to an IDirectDrawSurface7 interface to set as the new + * render target + * Flags: Some flags + * + * Returns: + * D3D_OK on success, for details see IWineD3DDevice::SetRenderTarget + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_7_SetRenderTarget(IDirect3DDevice7 *iface, + IDirectDrawSurface7 *NewTarget, + DWORD Flags) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); + IDirectDrawSurfaceImpl *Target = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, NewTarget); + TRACE("(%p)->(%p,%08lx): Relay\n", This, NewTarget, Flags); + + /* Flags: Not used */ + + return IWineD3DDevice_SetRenderTarget(This->wineD3DDevice, + 0, + Target ? Target->WineD3DSurface : NULL); +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_3_SetRenderTarget(IDirect3DDevice3 *iface, + IDirectDrawSurface4 *NewRenderTarget, + DWORD Flags) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); + IDirectDrawSurfaceImpl *Target = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, NewRenderTarget); + TRACE_(ddraw_thunk)("(%p)->(%p,%08lx) thunking to IDirect3DDevice7 interface.\n", This, Target, Flags); + return IDirect3DDevice7_SetRenderTarget(ICOM_INTERFACE(This, IDirect3DDevice7), + ICOM_INTERFACE(Target, IDirectDrawSurface7), + Flags); +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_2_SetRenderTarget(IDirect3DDevice2 *iface, + IDirectDrawSurface *NewRenderTarget, + DWORD Flags) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface); + IDirectDrawSurfaceImpl *Target = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface3, NewRenderTarget); + TRACE_(ddraw_thunk)("(%p)->(%p,%08lx) thunking to IDirect3DDevice7 interface.\n", This, Target, Flags); + return IDirect3DDevice7_SetRenderTarget(ICOM_INTERFACE(This, IDirect3DDevice7), + ICOM_INTERFACE(Target, IDirectDrawSurface7), + Flags); +} + +/***************************************************************************** + * IDirect3DDevice7::GetRenderTarget + * + * Returns the current render target. + * This is handled locally, because the WineD3D render target's parent + * is an IParent + * + * Version 2, 3 and 7 + * + * Params: + * RenderTarget: Address to store the surface interface pointer + * + * Returns: + * D3D_OK on success + * DDERR_INVALIDPARAMS if RenderTarget == NULL + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_7_GetRenderTarget(IDirect3DDevice7 *iface, + IDirectDrawSurface7 **RenderTarget) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); + TRACE("(%p)->(%p): Relay\n", This, RenderTarget); + + if(!RenderTarget) + return DDERR_INVALIDPARAMS; + + *RenderTarget = ICOM_INTERFACE(This->target, IDirectDrawSurface7); + IDirectDrawSurface7_AddRef(*RenderTarget); + + return D3D_OK; +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_3_GetRenderTarget(IDirect3DDevice3 *iface, + IDirectDrawSurface4 **RenderTarget) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); + HRESULT hr; + TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, RenderTarget); + hr = IDirect3DDevice7_GetRenderTarget(ICOM_INTERFACE(This, IDirect3DDevice7), + (IDirectDrawSurface7 **) RenderTarget); + if(hr != D3D_OK) return hr; + *RenderTarget = (IDirectDrawSurface4 *) COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7, IDirectDrawSurface7, RenderTarget); + return D3D_OK; +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_2_GetRenderTarget(IDirect3DDevice2 *iface, + IDirectDrawSurface **RenderTarget) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface); + HRESULT hr; + TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, RenderTarget); + hr = IDirect3DDevice7_GetRenderTarget(ICOM_INTERFACE(This, IDirect3DDevice7), + (IDirectDrawSurface7 **) RenderTarget); + if(hr != D3D_OK) return hr; + *RenderTarget = (IDirectDrawSurface *) COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7, IDirectDrawSurface3, RenderTarget); + return D3D_OK; +} + +/***************************************************************************** + * IDirect3DDevice3::Begin + * + * Begins a description block of vertices. This is simmilar to glBegin() + * and glEnd(). After a call to IDirect3DDevice3::End, the vertices + * described with IDirect3DDevice::Vertex are drawn. + * + * Version 2 and 3 + * + * Params: + * PrimitiveType: The type of primitives to draw + * VertexTypeDesc: A flexible vertex format description of the vertices + * Flags: Some flags.. + * + * Returns: + * D3D_OK on success + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_3_Begin(IDirect3DDevice3 *iface, + D3DPRIMITIVETYPE PrimitiveType, + DWORD VertexTypeDesc, + DWORD Flags) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); + TRACE("(%p)->(%d,%ld,%08lx)\n", This, PrimitiveType, VertexTypeDesc, Flags); + + This->primitive_type = PrimitiveType; + This->vertex_type = VertexTypeDesc; + This->render_flags = Flags; + This->vertex_size = get_flexible_vertex_size(This->vertex_type); + This->nb_vertices = 0; + + return D3D_OK; +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_2_Begin(IDirect3DDevice2 *iface, + D3DPRIMITIVETYPE d3dpt, + D3DVERTEXTYPE dwVertexTypeDesc, + DWORD dwFlags) +{ + DWORD FVF; + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface); + TRACE_(ddraw_thunk)("(%p/%p)->(%08x,%08x,%08lx): Thunking to IDirect3DDevice3\n", This, iface, d3dpt, dwVertexTypeDesc, dwFlags); + + switch(dwVertexTypeDesc) + { + case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break; + case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break; + case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break; + default: + assert(0); /* Should never happen */ + }; + + return IDirect3DDevice3_Begin(ICOM_INTERFACE(This, IDirect3DDevice3), + d3dpt, + FVF, + dwFlags); +} + +/***************************************************************************** + * IDirect3DDevice3::BeginIndexed + * + * Draws primitives based on vertices in a vertex array which are specified + * by indices. + * + * Version 2 and 3 + * + * Params: + * PrimitiveType: Primitive type to draw + * VertexType: A FVF description of the vertex format + * Vertices: pointer to an array containg the vertices + * NumVertices: The number of vertices in the vertex array + * Flags: Some flags ... + * + * Returns: + * D3D_OK, because it's a stub + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_3_BeginIndexed(IDirect3DDevice3 *iface, + D3DPRIMITIVETYPE PrimitiveType, + DWORD VertexType, + void *Vertices, + DWORD NumVertices, + DWORD Flags) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); + FIXME("(%p)->(%08x,%08lx,%p,%08lx,%08lx): stub!\n", This, PrimitiveType, VertexType, Vertices, NumVertices, Flags); + return D3D_OK; +} + + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_2_BeginIndexed(IDirect3DDevice2 *iface, + D3DPRIMITIVETYPE d3dptPrimitiveType, + D3DVERTEXTYPE d3dvtVertexType, + void *lpvVertices, + DWORD dwNumVertices, + DWORD dwFlags) +{ + DWORD FVF; + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface); + TRACE_(ddraw_thunk)("(%p/%p)->(%08x,%08x,%p,%08lx,%08lx): Thunking to IDirect3DDevice3\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwNumVertices, dwFlags); + + switch(d3dvtVertexType) + { + case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break; + case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break; + case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break; + default: + assert(0); /* Should never happen */ + }; + + return IDirect3DDevice3_BeginIndexed(ICOM_INTERFACE(This,IDirect3DDevice3), + d3dptPrimitiveType, + FVF, + lpvVertices, + dwNumVertices, + dwFlags); +} + +/***************************************************************************** + * IDirect3DDevice3::Vertex + * + * Draws a vertex as described by IDirect3DDevice3::Begin. It places all + * drawn vertices in an vertex buffer. If the buffer is to small, its + * size is increased. + * + * Version 2 and 3 + * + * Params: + * Vertex: Pointer to the vertex + * + * Returns: + * D3D_OK, on success + * DDERR_INVALIDPARAMS if Vertex is NULL + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_3_Vertex(IDirect3DDevice3 *iface, + void *Vertex) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); + TRACE("(%p)->(%p)\n", This, Vertex); + + if(!Vertex) + return DDERR_INVALIDPARAMS; + + if ((This->nb_vertices+1)*This->vertex_size > This->buffer_size) + { + BYTE *old_buffer; + This->buffer_size = This->buffer_size ? This->buffer_size * 2 : This->vertex_size * 3; + old_buffer = This->vertex_buffer; + This->vertex_buffer = HeapAlloc(GetProcessHeap(), 0, This->buffer_size); + if (old_buffer) + { + CopyMemory(This->vertex_buffer, old_buffer, This->nb_vertices * This->vertex_size); + HeapFree(GetProcessHeap(), 0, old_buffer); + } + } + + CopyMemory(This->vertex_buffer + This->nb_vertices++ * This->vertex_size, Vertex, This->vertex_size); + + return D3D_OK; +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_2_Vertex(IDirect3DDevice2 *iface, + void *lpVertexType) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface); + TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, lpVertexType); + return IDirect3DDevice3_Vertex(ICOM_INTERFACE(This, IDirect3DDevice3), + lpVertexType); +} + +/***************************************************************************** + * IDirect3DDevice3::Index + * + * Specifies an index to an vertex to be drawn. The vertex array has to + * be specified with BeginIndexed first. + * + * Parameters: + * VertexIndex: The index of the vertex to draw + * + * Returns: + * D3D_OK because it's a stub + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_3_Index(IDirect3DDevice3 *iface, + WORD VertexIndex) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); + FIXME("(%p)->(%04x): stub!\n", This, VertexIndex); + return D3D_OK; +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_2_Index(IDirect3DDevice2 *iface, + WORD wVertexIndex) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface); + TRACE_(ddraw_thunk)("(%p)->(%04x) thunking to IDirect3DDevice3 interface.\n", This, wVertexIndex); + return IDirect3DDevice3_Index(ICOM_INTERFACE(This, IDirect3DDevice3), + wVertexIndex); +} + +/***************************************************************************** + * IDirect3DDevice3::End + * + * Ends a draw begun with IDirect3DDevice3::Begin or + * IDirect3DDevice::BeginIndexed. The vertices specified with + * IDirect3DDevice::Vertex or IDirect3DDevice::Index are drawn using + * the IDirect3DDevice7::DrawPrimitive method. So far only + * non-indexed mode is supported + * + * Version 2 and 3 + * + * Params: + * Flags: Some flags, as usual. Don't know which are defined + * + * Returns: + * The return value of IDirect3DDevice7::DrawPrimitive + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_3_End(IDirect3DDevice3 *iface, + DWORD Flags) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); + TRACE("(%p)->(%08lx)\n", This, Flags); + + return IDirect3DDevice7_DrawPrimitive(ICOM_INTERFACE(This, IDirect3DDevice7), + This->primitive_type, This->vertex_type, + This->vertex_buffer, This->nb_vertices, + This->render_flags); +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_2_End(IDirect3DDevice2 *iface, + DWORD dwFlags) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface); + TRACE_(ddraw_thunk)("(%p)->(%08lx) thunking to IDirect3DDevice3 interface.\n", This, dwFlags); + return IDirect3DDevice3_End(ICOM_INTERFACE(This, IDirect3DDevice3), + dwFlags); +} + +/***************************************************************************** + * IDirect3DDevice7::GetRenderState + * + * Returns the value of a render state. The possible render states are + * defined in include/d3dtypes.h + * + * Version 2, 3 and 7 + * + * Params: + * RenderStateType: Render state to return the current setting of + * Value: Address to store the value at + * + * Returns: + * D3D_OK on success, for details see IWineD3DDevice::GetRenderState + * DDERR_INVALIDPARAMS if Value == NULL + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_7_GetRenderState(IDirect3DDevice7 *iface, + D3DRENDERSTATETYPE RenderStateType, + DWORD *Value) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); + TRACE("(%p)->(%08x,%p): Relay\n", This, RenderStateType, Value); + + if(!Value) + return DDERR_INVALIDPARAMS; + + return IWineD3DDevice_GetRenderState(This->wineD3DDevice, + RenderStateType, + Value); +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_3_GetRenderState(IDirect3DDevice3 *iface, + D3DRENDERSTATETYPE dwRenderStateType, + DWORD *lpdwRenderState) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); + TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, dwRenderStateType, lpdwRenderState); + return IDirect3DDevice7_GetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7), + dwRenderStateType, + lpdwRenderState); +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_2_GetRenderState(IDirect3DDevice2 *iface, + D3DRENDERSTATETYPE dwRenderStateType, + DWORD *lpdwRenderState) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface); + TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, dwRenderStateType, lpdwRenderState); + return IDirect3DDevice7_GetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7), + dwRenderStateType, + lpdwRenderState); +} + +/***************************************************************************** + * IDirect3DDevice7::SetRenderState + * + * Sets a render state. The possible render states are defined in + * include/d3dtypes.h + * + * Version 2, 3 and 7 + * + * Params: + * RenderStateType: State to set + * Value: Value to assign to that state + * + * Returns: + * D3D_OK on success, + * for details see IWineD3DDevice::SetRenderState + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_7_SetRenderState(IDirect3DDevice7 *iface, + D3DRENDERSTATETYPE RenderStateType, + DWORD Value) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); + TRACE("(%p)->(%08x,%ld): Relay\n", This, RenderStateType, Value); + + /* Some render states need special care */ + switch(RenderStateType) + { + case D3DRENDERSTATE_TEXTUREHANDLE: + return IWineD3DDevice_SetTexture(This->wineD3DDevice, + 0, + (IWineD3DBaseTexture *) Value); + + case D3DRENDERSTATE_TEXTUREMAG: + { + WINED3DTEXTUREFILTERTYPE tex_mag = WINED3DTEXF_NONE; + + switch ((D3DTEXTUREFILTER) Value) + { + case D3DFILTER_NEAREST: + tex_mag = WINED3DTEXF_POINT; + break; + case D3DFILTER_LINEAR: + tex_mag = WINED3DTEXF_LINEAR; + break; + default: + ERR("Unhandled texture mag %ld !\n",Value); + } + + return IWineD3DDevice_SetSamplerState(This->wineD3DDevice, + 0, WINED3DSAMP_MAGFILTER, + tex_mag); + } + + case D3DRENDERSTATE_TEXTUREMIN: + { + WINED3DTEXTUREFILTERTYPE tex_min = WINED3DTEXF_NONE; + + switch ((D3DTEXTUREFILTER) Value) + { + case D3DFILTER_NEAREST: + tex_min = WINED3DTEXF_POINT; + break; + case D3DFILTER_LINEAR: + tex_min = WINED3DTEXF_LINEAR; + break; + default: + ERR("Unhandled texture mag %ld !\n",Value); + } + + return IWineD3DDevice_SetSamplerState(This->wineD3DDevice, + 0, WINED3DSAMP_MINFILTER, + tex_min); + } + + case D3DRENDERSTATE_TEXTUREADDRESSU: + case D3DRENDERSTATE_TEXTUREADDRESSV: + case D3DRENDERSTATE_TEXTUREADDRESS: + { + WINED3DTEXTURESTAGESTATETYPE TexStageStateType; + + if (RenderStateType == D3DRENDERSTATE_TEXTUREADDRESS) + { + TexStageStateType = WINED3DTSS_ADDRESS; + } + else if (RenderStateType == D3DRENDERSTATE_TEXTUREADDRESSU) + { + TexStageStateType = WINED3DTSS_ADDRESSU; + } + else + { + TexStageStateType = WINED3DTSS_ADDRESSV; + } + + return IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, + 0, TexStageStateType, + Value); + } + + default: + return IWineD3DDevice_SetRenderState(This->wineD3DDevice, + RenderStateType, + Value); + } +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_3_SetRenderState(IDirect3DDevice3 *iface, + D3DRENDERSTATETYPE RenderStateType, + DWORD Value) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); + TRACE_(ddraw_thunk)("(%p)->(%08x,%08lx) thunking to IDirect3DDevice7 interface.\n", This, RenderStateType, Value); + return IDirect3DDevice7_SetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7), + RenderStateType, + Value); +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_2_SetRenderState(IDirect3DDevice2 *iface, + D3DRENDERSTATETYPE RenderStateType, + DWORD Value) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface); + TRACE_(ddraw_thunk)("(%p)->(%08x,%08lx) thunking to IDirect3DDevice7 interface.\n", This, RenderStateType, Value); + return IDirect3DDevice7_SetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7), + RenderStateType, + Value); +} + +/***************************************************************************** + * Direct3DDevice3::SetLightState + * + * Sets a light state for Direct3DDevice3 and Direct3DDevice2. The + * light states are forwarded to Direct3DDevice7 render states + * + * Version 2 and 3 + * + * Params: + * LightStateType: The light state to change + * Value: The value to assign to that light state + * + * Returns: + * D3D_OK on success + * DDERR_INVALIDPARAMS if the paramters were incorrect + * Also check IDirect3DDevice7::SetRenderState + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_3_SetLightState(IDirect3DDevice3 *iface, + D3DLIGHTSTATETYPE LightStateType, + DWORD Value) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); + + TRACE("(%p)->(%08x,%08lx)\n", This, LightStateType, Value); + + if (!LightStateType && (LightStateType > D3DLIGHTSTATE_COLORVERTEX)) + { + TRACE("Unexpected Light State Type\n"); + return DDERR_INVALIDPARAMS; + } + + if (LightStateType == D3DLIGHTSTATE_MATERIAL /* 1 */) + { + IDirect3DMaterialImpl *mat = (IDirect3DMaterialImpl *) Value; + + if (mat != NULL) + { + TRACE(" activating material %p.\n", mat); + mat->activate(mat); + } + else + { + FIXME(" D3DLIGHTSTATE_MATERIAL called with NULL material !!!\n"); + } + This->material = Value; + } + else if (LightStateType == D3DLIGHTSTATE_COLORMODEL /* 3 */) + { + switch (Value) + { + case D3DCOLOR_MONO: + ERR("DDCOLOR_MONO should not happen!\n"); + break; + case D3DCOLOR_RGB: + /* We are already in this mode */ + TRACE("Setting color model to RGB (no-op).\n"); + break; + default: + ERR("Unknown color model!\n"); + return DDERR_INVALIDPARAMS; + } + } + else + { + D3DRENDERSTATETYPE rs; + switch (LightStateType) + { + case D3DLIGHTSTATE_AMBIENT: /* 2 */ + rs = D3DRENDERSTATE_AMBIENT; + break; + case D3DLIGHTSTATE_FOGMODE: /* 4 */ + rs = D3DRENDERSTATE_FOGVERTEXMODE; + break; + case D3DLIGHTSTATE_FOGSTART: /* 5 */ + rs = D3DRENDERSTATE_FOGSTART; + break; + case D3DLIGHTSTATE_FOGEND: /* 6 */ + rs = D3DRENDERSTATE_FOGEND; + break; + case D3DLIGHTSTATE_FOGDENSITY: /* 7 */ + rs = D3DRENDERSTATE_FOGDENSITY; + break; + case D3DLIGHTSTATE_COLORVERTEX: /* 8 */ + rs = D3DRENDERSTATE_COLORVERTEX; + break; + default: + ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType); + return DDERR_INVALIDPARAMS; + } + + return IDirect3DDevice7_SetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7), + rs, + Value); + } + + return D3D_OK; +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_2_SetLightState(IDirect3DDevice2 *iface, + D3DLIGHTSTATETYPE LightStateType, + DWORD Value) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface); + TRACE_(ddraw_thunk)("(%p)->(%08x,%08lx) thunking to IDirect3DDevice3 interface.\n", This, LightStateType, Value); + return IDirect3DDevice3_SetLightState(ICOM_INTERFACE(This, IDirect3DDevice3), + LightStateType, + Value); +} + +/***************************************************************************** + * IDirect3DDevice3::GetLightState + * + * Returns the current setting of a light state. The state is read from + * the Direct3DDevice7 render state. + * + * Version 2 and 3 + * + * Params: + * LightStateType: The light state to return + * Value: The address to store the light state setting at + * + * Returns: + * D3D_OK on success + * DDDERR_INVALIDPARAMS if the parameters were incorrect + * Also see IDirect3DDevice7::GetRenderState + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_3_GetLightState(IDirect3DDevice3 *iface, + D3DLIGHTSTATETYPE LightStateType, + DWORD *Value) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); + + TRACE("(%p)->(%08x,%p)\n", This, LightStateType, Value); + + if (!LightStateType && (LightStateType > D3DLIGHTSTATE_COLORVERTEX)) + { + TRACE("Unexpected Light State Type\n"); + return DDERR_INVALIDPARAMS; + } + + if(!Value) + return DDERR_INVALIDPARAMS; + + if (LightStateType == D3DLIGHTSTATE_MATERIAL /* 1 */) + { + *Value = This->material; + } + else if (LightStateType == D3DLIGHTSTATE_COLORMODEL /* 3 */) + { + *Value = D3DCOLOR_RGB; + } + else + { + D3DRENDERSTATETYPE rs; + switch (LightStateType) + { + case D3DLIGHTSTATE_AMBIENT: /* 2 */ + rs = D3DRENDERSTATE_AMBIENT; + break; + case D3DLIGHTSTATE_FOGMODE: /* 4 */ + rs = D3DRENDERSTATE_FOGVERTEXMODE; + break; + case D3DLIGHTSTATE_FOGSTART: /* 5 */ + rs = D3DRENDERSTATE_FOGSTART; + break; + case D3DLIGHTSTATE_FOGEND: /* 6 */ + rs = D3DRENDERSTATE_FOGEND; + break; + case D3DLIGHTSTATE_FOGDENSITY: /* 7 */ + rs = D3DRENDERSTATE_FOGDENSITY; + break; + case D3DLIGHTSTATE_COLORVERTEX: /* 8 */ + rs = D3DRENDERSTATE_COLORVERTEX; + break; + default: + ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType); + return DDERR_INVALIDPARAMS; + } + + return IDirect3DDevice7_GetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7), + rs, + Value); + } + + return D3D_OK; +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_2_GetLightState(IDirect3DDevice2 *iface, + D3DLIGHTSTATETYPE LightStateType, + DWORD *Value) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface); + TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice3 interface.\n", This, LightStateType, Value); + return IDirect3DDevice3_GetLightState(ICOM_INTERFACE(This, IDirect3DDevice3), + LightStateType, + Value); +} + +/***************************************************************************** + * IDirect3DDevice7::SetTransform + * + * Assignes a D3DMATRIX to a transform type. The transform types are defined + * in include/d3dtypes.h. + * The D3DTRANSFORMSTATE_WORLD (=1) is translated to D3DTS_WORLDMATRIX(0) + * (=255) for wined3d, because the 1 transform state was removed in d3d8 + * and WineD3D allready understands the replacement D3DTS_WORLDMATRIX(0) + * + * Version 2, 3 and 7 + * + * Params: + * TransformStateType: transform state to set + * Matrix: Matrix to assign to the state + * + * Returns: + * D3D_OK on success + * DDERR_INVALIDPARAMS if Matrix == NULL + * For details see IWineD3DDevice::SetTransform + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_7_SetTransform(IDirect3DDevice7 *iface, + D3DTRANSFORMSTATETYPE TransformStateType, + D3DMATRIX *Matrix) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); + D3DTRANSFORMSTATETYPE type = TransformStateType; + TRACE("(%p)->(%08x,%p): Relay\n", This, TransformStateType, Matrix); + + if(!Matrix) + return DDERR_INVALIDPARAMS; + + /* D3DTRANSFORMSTATE_WORLD doesn't exist in WineD3D, + * use D3DTS_WORLDMATRIX(0) instead + * D3DTS_WORLDMATRIX(index) is (D3DTRANSFORMSTATETYPE)(index + 256) + */ + if(TransformStateType == D3DTRANSFORMSTATE_WORLD) + type = (D3DTRANSFORMSTATETYPE)(0 + 256); + + return IWineD3DDevice_SetTransform(This->wineD3DDevice, + type, + Matrix); +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_3_SetTransform(IDirect3DDevice3 *iface, + D3DTRANSFORMSTATETYPE TransformStateType, + D3DMATRIX *D3DMatrix) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); + TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix); + return IDirect3DDevice7_SetTransform(ICOM_INTERFACE(This, IDirect3DDevice7), + TransformStateType, + D3DMatrix); +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_2_SetTransform(IDirect3DDevice2 *iface, + D3DTRANSFORMSTATETYPE TransformStateType, + D3DMATRIX *D3DMatrix) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface); + TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix); + return IDirect3DDevice7_SetTransform(ICOM_INTERFACE(This, IDirect3DDevice7), + TransformStateType, + D3DMatrix); +} + +/***************************************************************************** + * IDirect3DDevice7::GetTransform + * + * Returns the matrix assigned to a transform state + * D3DTRANSFORMSTATE_WORLD is translated to D3DTS_WORLDMATRIX(0), see + * SetTransform + * + * Params: + * TransformStateType: State to read the matrix from + * Matrix: Address to store the matrix at + * + * Returns: + * D3D_OK on success + * DDERR_INVALIDPARAMS if Matrix == NULL + * For details, see IWineD3DDevice::GetTransform + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_7_GetTransform(IDirect3DDevice7 *iface, + D3DTRANSFORMSTATETYPE TransformStateType, + D3DMATRIX *Matrix) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); + D3DTRANSFORMSTATETYPE type = TransformStateType; + TRACE("(%p)->(%08x,%p): Relay\n", This, TransformStateType, Matrix); + + if(!Matrix) + return DDERR_INVALIDPARAMS; + + /* D3DTRANSFORMSTATE_WORLD doesn't exist in WineD3D, + * use D3DTS_WORLDMATRIX(0) instead + * D3DTS_WORLDMATRIX(index) is (D3DTRANSFORMSTATETYPE)(index + 256) + */ + if(TransformStateType == D3DTRANSFORMSTATE_WORLD) + type = (D3DTRANSFORMSTATETYPE)(0 + 256); + + return IWineD3DDevice_GetTransform(This->wineD3DDevice, type, Matrix); +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_3_GetTransform(IDirect3DDevice3 *iface, + D3DTRANSFORMSTATETYPE TransformStateType, + D3DMATRIX *D3DMatrix) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); + TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix); + return IDirect3DDevice7_GetTransform(ICOM_INTERFACE(This, IDirect3DDevice7), + TransformStateType, + D3DMatrix); +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_2_GetTransform(IDirect3DDevice2 *iface, + D3DTRANSFORMSTATETYPE TransformStateType, + D3DMATRIX *D3DMatrix) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface); + TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix); + return IDirect3DDevice7_GetTransform(ICOM_INTERFACE(This, IDirect3DDevice7), + TransformStateType, + D3DMatrix); +} + +/***************************************************************************** + * IDirect3DDevice7::MultiplyTransform + * + * Multiplies the already-set transform matrix of a transform state + * with another matrix. For the world matrix, see SetTransform + * + * Version 2, 3 and 7 + * + * Params: + * TransformStateType: Transform state to multiply + * D3DMatrix Matrix to multiply with. + * + * Returns + * D3D_OK on success + * DDERR_INVALIDPARAMS if D3DMatrix is NULL + * For details, see IWineD3DDevice::MultiplyTransform + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_7_MultiplyTransform(IDirect3DDevice7 *iface, + D3DTRANSFORMSTATETYPE TransformStateType, + D3DMATRIX *D3DMatrix) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); + TRACE("(%p)->(%08x,%p): Relay\n", This, TransformStateType, D3DMatrix); + + /* D3DTRANSFORMSTATE_WORLD doesn't exist in WineD3D, + * use D3DTS_WORLDMATRIX(0) instead + * D3DTS_WORLDMATRIX(index) is (D3DTRANSFORMSTATETYPE)(index + 256) + */ + if(TransformStateType == D3DTRANSFORMSTATE_WORLD) + TransformStateType = (D3DTRANSFORMSTATETYPE)(0 + 256); + + return IWineD3DDevice_MultiplyTransform(This->wineD3DDevice, + TransformStateType, + D3DMatrix); +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_3_MultiplyTransform(IDirect3DDevice3 *iface, + D3DTRANSFORMSTATETYPE TransformStateType, + D3DMATRIX *D3DMatrix) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); + TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix); + return IDirect3DDevice7_MultiplyTransform(ICOM_INTERFACE(This, IDirect3DDevice7), + TransformStateType, + D3DMatrix); +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_2_MultiplyTransform(IDirect3DDevice2 *iface, + D3DTRANSFORMSTATETYPE TransformStateType, + D3DMATRIX *D3DMatrix) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface); + TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix); + return IDirect3DDevice7_MultiplyTransform(ICOM_INTERFACE(This, IDirect3DDevice7), + TransformStateType, + D3DMatrix); +} + +/***************************************************************************** + * IDirect3DDevice7::DrawPrimitive + * + * Draws primitves based on vertices in an application-provided pointer + * + * Version 2, 3 and 7. The IDirect3DDevice2 thunk converts the fixed vertex type into + * an FVF format for D3D7 + * + * Params: + * PrimitiveType: The type of the primitives to draw + * Vertex type: Flexible vertex format vertex description + * Vertices: Pointer to the vertex array + * VertexCount: The number of vertices to draw + * Flags: As usual a few flags + * + * Returns: + * D3D_OK on success + * DDERR_INVALIDPARAMS if Vertices is NULL + * For details, see IWineD3DDevice::DrawPrimitiveUP + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_7_DrawPrimitive(IDirect3DDevice7 *iface, + D3DPRIMITIVETYPE PrimitiveType, + DWORD VertexType, + void *Vertices, + DWORD VertexCount, + DWORD Flags) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); + UINT PrimitiveCount, stride; + HRESULT hr; + TRACE("(%p)->(%08x,%08lx,%p,%08lx,%08lx): Relay!\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Flags); + + if(!Vertices) + return DDERR_INVALIDPARAMS; + + /* Get the vertex count */ + switch(PrimitiveType) + { + case D3DPT_POINTLIST: + PrimitiveCount = VertexCount; + break; + + case D3DPT_LINELIST: + PrimitiveCount = VertexCount / 2; + break; + + case D3DPT_LINESTRIP: + PrimitiveCount = VertexCount - 1; + break; + + case D3DPT_TRIANGLELIST: + PrimitiveCount = VertexCount / 3; + break; + + case D3DPT_TRIANGLESTRIP: + PrimitiveCount = VertexCount - 2; + break; + + case D3DPT_TRIANGLEFAN: + PrimitiveCount = VertexCount - 2; + break; + + default: return DDERR_INVALIDPARAMS; + } + + /* Get the stride */ + stride = get_flexible_vertex_size(VertexType); + + /* Set the FVF */ + hr = IWineD3DDevice_SetFVF(This->wineD3DDevice, VertexType); + if(hr != D3D_OK) return hr; + + /* This method translates to the user pointer draw of WineD3D */ + return IWineD3DDevice_DrawPrimitiveUP(This->wineD3DDevice, + PrimitiveType, + PrimitiveCount, + Vertices, + stride); +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_3_DrawPrimitive(IDirect3DDevice3 *iface, + D3DPRIMITIVETYPE PrimitiveType, + DWORD VertexType, + void *Vertices, + DWORD VertexCount, + DWORD Flags) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); + TRACE_(ddraw_thunk)("(%p)->(%08x,%08lx,%p,%08lx,%08lx) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Flags); + return IDirect3DDevice7_DrawPrimitive(ICOM_INTERFACE(This, IDirect3DDevice7), + PrimitiveType, + VertexType, + Vertices, + VertexCount, + Flags); +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_2_DrawPrimitive(IDirect3DDevice2 *iface, + D3DPRIMITIVETYPE PrimitiveType, + D3DVERTEXTYPE VertexType, + void *Vertices, + DWORD VertexCount, + DWORD Flags) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface); + DWORD FVF; + TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08lx,%08lx) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Flags); + + switch(VertexType) + { + case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break; + case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break; + case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break; + default: + assert(0); /* Should never happen */ + } + + return IDirect3DDevice7_DrawPrimitive(ICOM_INTERFACE(This, IDirect3DDevice7), + PrimitiveType, + FVF, + Vertices, + VertexCount, + Flags); +} + +/***************************************************************************** + * IDirect3DDevice7::DrawIndexedPrimitive + * + * Draws vertices from an application-provided pointer, based on the index + * numbers in a WORD array. + * + * Version 2, 3 and 7. The version 7 thunk translates the vertex type into + * an FVF format for D3D7 + * + * Params: + * PrimitiveType: The primitive type to draw + * VertexType: The FVF vertex description + * Vertices: Pointer to the vertex array + * VertexCount: ? + * Indices: Pointer to the index array + * IndexCount: Number of indices = Number of vertices to draw + * Flags: As usual, some flags + * + * Returns: + * D3D_OK on success + * DDERR_INVALIDPARAMS if Vertices or Indices is NULL + * For details, see IWineD3DDevice::DrawIndexedPrimitiveUP + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_7_DrawIndexedPrimitive(IDirect3DDevice7 *iface, + D3DPRIMITIVETYPE PrimitiveType, + DWORD VertexType, + void *Vertices, + DWORD VertexCount, + WORD *Indices, + DWORD IndexCount, + DWORD Flags) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); + UINT PrimitiveCount = 0; + HRESULT hr; + TRACE("(%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx): Relay!\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags); + /* Get the primitive number */ + switch(PrimitiveType) + { + case D3DPT_POINTLIST: + PrimitiveCount = IndexCount; + break; + + case D3DPT_LINELIST: + PrimitiveCount = IndexCount / 2; + break; + + case D3DPT_LINESTRIP: + PrimitiveCount = IndexCount - 1; + break; + + case D3DPT_TRIANGLELIST: + PrimitiveCount = IndexCount / 3; + break; + + case D3DPT_TRIANGLESTRIP: + PrimitiveCount = IndexCount - 2; + break; + + case D3DPT_TRIANGLEFAN: + PrimitiveCount = IndexCount - 2; + break; + + default: return DDERR_INVALIDPARAMS; + } + + /* Set the D3DDevice's FVF */ + hr = IWineD3DDevice_SetFVF(This->wineD3DDevice, VertexType); + if(FAILED(hr)) + { + ERR(" (%p) Setting the FVF failed, hr = %lx!\n", This, hr); + return hr; + } + + return IWineD3DDevice_DrawIndexedPrimitiveUP(This->wineD3DDevice, + PrimitiveType, + 0 /* MinVertexIndex */, + VertexCount /* UINT NumVertexIndex */, + PrimitiveCount, + Indices, + WINED3DFMT_INDEX16, + Vertices, + get_flexible_vertex_size(VertexType)); +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive(IDirect3DDevice3 *iface, + D3DPRIMITIVETYPE PrimitiveType, + DWORD VertexType, + void *Vertices, + DWORD VertexCount, + WORD *Indices, + DWORD IndexCount, + DWORD Flags) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); + TRACE_(ddraw_thunk)("(%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags); + return IDirect3DDevice7_DrawIndexedPrimitive(ICOM_INTERFACE(This, IDirect3DDevice7), + PrimitiveType, + VertexType, + Vertices, + VertexCount, + Indices, + IndexCount, + Flags); +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_2_DrawIndexedPrimitive(IDirect3DDevice2 *iface, + D3DPRIMITIVETYPE PrimitiveType, + D3DVERTEXTYPE VertexType, + void *Vertices, + DWORD VertexCount, + WORD *Indices, + DWORD IndexCount, + DWORD Flags) +{ + DWORD FVF; + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface); + TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08lx,%p,%08lx,%08lx) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags); + + switch(VertexType) + { + case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break; + case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break; + case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break; + default: + assert(0); /* Should never happen */ + } + + return IDirect3DDevice7_DrawIndexedPrimitive(ICOM_INTERFACE(This, IDirect3DDevice7), + PrimitiveType, + FVF, + Vertices, + VertexCount, + Indices, + IndexCount, + Flags); +} + +/***************************************************************************** + * IDirect3DDevice7::SetClipStatus + * + * Sets the clip status. This defines things as clipping conditions and + * the extents of the clipping region. + * + * Version 2, 3 and 7 + * + * Params: + * ClipStatus: + * + * Returns: + * D3D_OK because it's a stub + * (DDERR_INVALIDPARAMS if ClipStatus == NULL) + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_7_SetClipStatus(IDirect3DDevice7 *iface, + D3DCLIPSTATUS *ClipStatus) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); + FIXME("(%p)->(%p): Stub!\n", This, ClipStatus); + + /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them + * Perhaps this needs a new data type and an additional IWineD3DDevice method + */ + /* return IWineD3DDevice_SetClipStatus(This->wineD3DDevice, ClipStatus);*/ + return D3D_OK; +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_3_SetClipStatus(IDirect3DDevice3 *iface, + D3DCLIPSTATUS *ClipStatus) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); + TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus); + return IDirect3DDevice7_SetClipStatus(ICOM_INTERFACE(This, IDirect3DDevice7), + ClipStatus); +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_2_SetClipStatus(IDirect3DDevice2 *iface, + D3DCLIPSTATUS *ClipStatus) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface); + TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus); + return IDirect3DDevice7_SetClipStatus(ICOM_INTERFACE(This, IDirect3DDevice7), + ClipStatus); +} + +/***************************************************************************** + * IDirect3DDevice7::GetClipStatus + * + * Returns the clip status + * + * Params: + * ClipStatus: Address to write the clip status to + * + * Returns: + * D3D_OK because it's a stub + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_7_GetClipStatus(IDirect3DDevice7 *iface, + D3DCLIPSTATUS *ClipStatus) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); + FIXME("(%p)->(%p): Stub!\n", This, ClipStatus); + + /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them */ + /* return IWineD3DDevice_GetClipStatus(This->wineD3DDevice, ClipStatus);*/ + return D3D_OK; +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_3_GetClipStatus(IDirect3DDevice3 *iface, + D3DCLIPSTATUS *ClipStatus) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); + TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus); + return IDirect3DDevice7_GetClipStatus(ICOM_INTERFACE(This, IDirect3DDevice7), + ClipStatus); +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_2_GetClipStatus(IDirect3DDevice2 *iface, + D3DCLIPSTATUS *ClipStatus) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface); + TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus); + return IDirect3DDevice7_GetClipStatus(ICOM_INTERFACE(This, IDirect3DDevice7), + ClipStatus); +} + +/***************************************************************************** + * IDirect3DDevice::DrawPrimitiveStrided + * + * Draws vertices described by a D3DDRAWPRIMITIVESTRIDEDDATA structure. + * + * Version 3 and 7 + * + * Params: + * PrimitiveType: The primitive type to draw + * VertexType: The FVF description of the vertices to draw(for the stride??) + * D3DDrawPrimStrideData: A D3DDRAWPRIMITIVESTRIDEDDATA structure describing + * the vertex data locations + * VertexCount: The number of vertices to draw + * Flags: Some flags + * + * Returns: + * D3D_OK, because it's a stub + * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL) + * (For details, see IWineD3DDevice::DrawPrimitiveStrided) + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_7_DrawPrimitiveStrided(IDirect3DDevice7 *iface, + D3DPRIMITIVETYPE PrimitiveType, + DWORD VertexType, + D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData, + DWORD VertexCount, + DWORD Flags) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); + WineDirect3DVertexStridedData WineD3DStrided; + int i; + UINT PrimitiveCount; + + TRACE("(%p)->(%08x,%08lx,%p,%08lx,%08lx): stub!\n", This, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags); + + /* Get the strided data right. the wined3d structure is a bit bigger + * Watch out: The contents of the strided data are determined by the fvf, + * not by the members set in D3DDrawPrimStrideData. So it's valid + * to have diffuse.lpvData set to 0xdeadbeef and not setting the diffuse + * flag in the fvf. + */ + if(VertexType & D3DFVF_POSITION_MASK) + { + memset(&WineD3DStrided, 0, sizeof(WineD3DStrided)); + WineD3DStrided.u.s.position.lpData = D3DDrawPrimStrideData->position.lpvData; + WineD3DStrided.u.s.position.dwStride = D3DDrawPrimStrideData->position.dwStride; + WineD3DStrided.u.s.position.dwType = WINED3DDECLTYPE_FLOAT3; + if (VertexType & D3DFVF_XYZRHW) + { + WineD3DStrided.u.s.position.dwType = WINED3DDECLTYPE_FLOAT4; + } + } + + if(VertexType & D3DFVF_NORMAL) + { + WineD3DStrided.u.s.normal.lpData = D3DDrawPrimStrideData->normal.lpvData; + WineD3DStrided.u.s.normal.dwStride = D3DDrawPrimStrideData->normal.dwStride; + WineD3DStrided.u.s.normal.dwType = WINED3DDECLTYPE_FLOAT3; + } + + if(VertexType & D3DFVF_DIFFUSE) + { + WineD3DStrided.u.s.diffuse.lpData = D3DDrawPrimStrideData->diffuse.lpvData; + WineD3DStrided.u.s.diffuse.dwStride = D3DDrawPrimStrideData->diffuse.dwStride; + WineD3DStrided.u.s.diffuse.dwType = WINED3DDECLTYPE_SHORT4; + } + + if(VertexType & D3DFVF_SPECULAR) + { + WineD3DStrided.u.s.specular.lpData = D3DDrawPrimStrideData->specular.lpvData; + WineD3DStrided.u.s.specular.dwStride = D3DDrawPrimStrideData->specular.dwStride; + WineD3DStrided.u.s.specular.dwType = WINED3DDECLTYPE_SHORT4; + } + + for( i = 0; i < GET_TEXCOUNT_FROM_FVF(VertexType); i++) + { + WineD3DStrided.u.s.texCoords[i].lpData = D3DDrawPrimStrideData->textureCoords[i].lpvData; + WineD3DStrided.u.s.texCoords[i].dwStride = D3DDrawPrimStrideData->textureCoords[i].dwStride; + switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i)) + { + case 1: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT1; break; + case 2: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT2; break; + case 3: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT3; break; + case 4: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT4; break; + default: ERR("Unexpected texture coordinate size %ld\n", + GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i)); + } + } + + /* Get the primitive count */ + switch(PrimitiveType) + { + case D3DPT_POINTLIST: + PrimitiveCount = VertexCount; + break; + + case D3DPT_LINELIST: + PrimitiveCount = VertexCount / 2; + break; + + case D3DPT_LINESTRIP: + PrimitiveCount = VertexCount - 1; + break; + + case D3DPT_TRIANGLELIST: + PrimitiveCount = VertexCount / 3; + break; + + case D3DPT_TRIANGLESTRIP: + PrimitiveCount = VertexCount - 2; + break; + + case D3DPT_TRIANGLEFAN: + PrimitiveCount = VertexCount - 2; + break; + + default: return DDERR_INVALIDPARAMS; + } + + IWineD3DDevice_SetFVF(This->wineD3DDevice, + VertexType); + + return IWineD3DDevice_DrawPrimitiveStrided(This->wineD3DDevice, + PrimitiveType, + PrimitiveCount, + &WineD3DStrided); +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided(IDirect3DDevice3 *iface, + D3DPRIMITIVETYPE PrimitiveType, + DWORD VertexType, + D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData, + DWORD VertexCount, + DWORD Flags) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); + TRACE_(ddraw_thunk)("(%p)->(%08x,%08lx,%p,%08lx,%08lx) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags); + return IDirect3DDevice7_DrawPrimitiveStrided(ICOM_INTERFACE(This, IDirect3DDevice7), + PrimitiveType, + VertexType, + D3DDrawPrimStrideData, + VertexCount, + Flags); +} + +/***************************************************************************** + * IDirect3DDevice7::DrawIndexedPrimitiveStrided + * + * Draws primitives specified by strided data locations based on indices + * + * Version 3 and 7 + * + * Params: + * PrimitiveType: + * + * Returns: + * D3D_OK, because it's a stub + * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL) + * (DDERR_INVALIDPARAMS if Indices is NULL) + * (For more details, see IWineD3DDevice::DrawIndexedPrimitiveStrided) + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(IDirect3DDevice7 *iface, + D3DPRIMITIVETYPE PrimitiveType, + DWORD VertexType, + D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData, + DWORD VertexCount, + WORD *Indices, + DWORD IndexCount, + DWORD Flags) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); + FIXME("(%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx): stub!\n", This, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags); + + /* I'll implement it as soon as I find a app to test it. + * This needs an additional method in IWineD3DDevice. + */ + return D3D_OK; +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided(IDirect3DDevice3 *iface, + D3DPRIMITIVETYPE PrimitiveType, + DWORD VertexType, + D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData, + DWORD VertexCount, + WORD *Indices, + DWORD IndexCount, + DWORD Flags) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); + TRACE_(ddraw_thunk)("(%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx) thunking to IDirect3DDevice7 interface.\n", iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags); + return IDirect3DDevice7_DrawIndexedPrimitiveStrided(ICOM_INTERFACE(This, IDirect3DDevice7), + PrimitiveType, + VertexType, + D3DDrawPrimStrideData, + VertexCount, + Indices, + IndexCount, + Flags); +} + +/***************************************************************************** + * IDirect3DDevice7::DrawPrimitiveVB + * + * Draws primitives from a vertex buffer to the screen. + * + * Version 3 and 7 + * + * Params: + * PrimitiveType: Type of primitive to be rendered. + * D3DVertexBuf: Source Vertex Buffer + * StartVertex: Index of the first vertex from the buffer to be rendered + * NumVertices: Number of vertices to be rendered + * Flags: Can be D3DDP_WAIT to wait until rendering has finished + * + * Return values + * D3D_OK on success + * DDERR_INVALIDPARAMS if D3DVertexBuf is NULL + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_7_DrawPrimitiveVB(IDirect3DDevice7 *iface, + D3DPRIMITIVETYPE PrimitiveType, + IDirect3DVertexBuffer7 *D3DVertexBuf, + DWORD StartVertex, + DWORD NumVertices, + DWORD Flags) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); + IDirect3DVertexBufferImpl *vb = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, D3DVertexBuf); + UINT PrimitiveCount; + HRESULT hr; + DWORD stride; + WINED3DVERTEXBUFFER_DESC Desc; + + TRACE("(%p)->(%08x,%p,%08lx,%08lx,%08lx)\n", This, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags); + + /* Sanity checks */ + if(!vb) + { + ERR("(%p) No Vertex buffer specified\n", This); + return DDERR_INVALIDPARAMS; + } + + /* Get the primitive count */ + switch(PrimitiveType) + { + case D3DPT_POINTLIST: + PrimitiveCount = NumVertices; + break; + + case D3DPT_LINELIST: + PrimitiveCount = NumVertices / 2; + break; + + case D3DPT_LINESTRIP: + PrimitiveCount = NumVertices - 1; + break; + + case D3DPT_TRIANGLELIST: + PrimitiveCount = NumVertices / 3; + break; + + case D3DPT_TRIANGLESTRIP: + PrimitiveCount = NumVertices - 2; + break; + + case D3DPT_TRIANGLEFAN: + PrimitiveCount = NumVertices - 2; + break; + + default: return DDERR_INVALIDPARAMS; + } + + /* Get the FVF of the vertex buffer, and its stride */ + hr = IWineD3DVertexBuffer_GetDesc(vb->wineD3DVertexBuffer, + &Desc); + if(hr != D3D_OK) + { + ERR("(%p) IWineD3DVertexBuffer::GetDesc failed with hr = %08lx\n", This, hr); + return hr; + } + stride = get_flexible_vertex_size(Desc.FVF); + + hr = IWineD3DDevice_SetFVF(This->wineD3DDevice, Desc.FVF); + if(FAILED(hr)) + { + ERR(" (%p) Setting the FVF failed, hr = %lx!\n", This, hr); + return hr; + } + + /* Set the vertex stream souce */ + hr = IWineD3DDevice_SetStreamSource(This->wineD3DDevice, + 0 /* StreamNumber */, + vb->wineD3DVertexBuffer, + 0 /* StartVertex - we pass this to DrawPrimitive */, + stride); + if(hr != D3D_OK) + { + ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08lx\n", This, hr); + return hr; + } + + /* Now draw the primitives */ + return IWineD3DDevice_DrawPrimitive(This->wineD3DDevice, + PrimitiveType, + StartVertex, + PrimitiveCount); +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB(IDirect3DDevice3 *iface, + D3DPRIMITIVETYPE PrimitiveType, + IDirect3DVertexBuffer *D3DVertexBuf, + DWORD StartVertex, + DWORD NumVertices, + DWORD Flags) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); + IDirect3DVertexBufferImpl *vb = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, D3DVertexBuf); + TRACE_(ddraw_thunk)("(%p)->(%08x,%p,%08lx,%08lx,%08lx) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, vb, StartVertex, NumVertices, Flags); + return IDirect3DDevice7_DrawPrimitiveVB(ICOM_INTERFACE(This, IDirect3DDevice7), + PrimitiveType, + ICOM_INTERFACE(vb, IDirect3DVertexBuffer7), + StartVertex, + NumVertices, + Flags); +} + + +/***************************************************************************** + * IDirect3DDevice7::DrawIndexedPrimitiveVB + * + * Draws primitives from a vertex buffer to the screen + * + * Params: + * PrimitiveType: Type of primitive to be rendered. + * D3DVertexBuf: Source Vertex Buffer + * StartVertex: Index of the first vertex from the buffer to be rendered + * NumVertices: Number of vertices to be rendered + * Indices: Array of DWORDs used to index into the Vertices + * IndexCount: Number of indices in Indices + * Flags: Can be D3DDP_WAIT to wait until rendering has finished + * + * Return values + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(IDirect3DDevice7 *iface, + D3DPRIMITIVETYPE PrimitiveType, + IDirect3DVertexBuffer7 *D3DVertexBuf, + DWORD StartVertex, + DWORD NumVertices, + WORD *Indices, + DWORD IndexCount, + DWORD Flags) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); + IDirect3DVertexBufferImpl *vb = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, D3DVertexBuf); + DWORD stride; + UINT PrimitiveCount; + WORD *LockedIndices; + HRESULT hr; + WINED3DVERTEXBUFFER_DESC Desc; + + TRACE("(%p)->(%08x,%p,%ld,%ld,%p,%ld,%08lx)\n", This, PrimitiveType, vb, StartVertex, NumVertices, Indices, IndexCount, Flags); + + /* Steps: + * 1) Calculate some things: Vertex count -> Primitive count, stride, ... + * 2) Upload the Indices to the index buffer + * 3) Set the index source + * 4) Set the Vertex Buffer as the Stream source + * 5) Call IWineD3DDevice::DrawIndexedPrimitive + */ + + /* Get the primitive count */ + switch(PrimitiveType) + { + case D3DPT_POINTLIST: + PrimitiveCount = IndexCount; + break; + + case D3DPT_LINELIST: + PrimitiveCount = IndexCount / 2; + break; + + case D3DPT_LINESTRIP: + PrimitiveCount = IndexCount - 1; + break; + + case D3DPT_TRIANGLELIST: + PrimitiveCount = IndexCount / 3; + break; + + case D3DPT_TRIANGLESTRIP: + PrimitiveCount = IndexCount - 2; + break; + + case D3DPT_TRIANGLEFAN: + PrimitiveCount = IndexCount - 2; + break; + + default: return DDERR_INVALIDPARAMS; + } + + /* Get the FVF of the vertex buffer, and its stride */ + hr = IWineD3DVertexBuffer_GetDesc(vb->wineD3DVertexBuffer, + &Desc); + if(hr != D3D_OK) + { + ERR("(%p) IWineD3DVertexBuffer::GetDesc failed with hr = %08lx\n", This, hr); + return hr; + } + stride = get_flexible_vertex_size(Desc.FVF); + TRACE("Vertex buffer FVF = %08lx, stride=%ld\n", Desc.FVF, stride); + + hr = IWineD3DDevice_SetFVF(This->wineD3DDevice, Desc.FVF); + if(FAILED(hr)) + { + ERR(" (%p) Setting the FVF failed, hr = %lx!\n", This, hr); + return hr; + } + + /* copy the index stream into the index buffer. + * A new IWineD3DDevice method could be created + * which takes an user pointer containing the indices + * or a SetData-Method for the index buffer, which + * overrides the index buffer data with our pointer. + */ + hr = IWineD3DIndexBuffer_Lock(This->indexbuffer, + 0 /* OffSetToLock */, + 0 /* SizeToLock - doesn't matter */, + (BYTE **) &LockedIndices, + 0 /* Flags */); + assert(IndexCount < 0x100000); + if(hr != D3D_OK) + { + ERR("(%p) IWineD3DIndexBuffer::Lock failed with hr = %08lx\n", This, hr); + return hr; + } + memcpy(LockedIndices, Indices, IndexCount * sizeof(WORD)); + hr = IWineD3DIndexBuffer_Unlock(This->indexbuffer); + if(hr != D3D_OK) + { + ERR("(%p) IWineD3DIndexBuffer::Unlock failed with hr = %08lx\n", This, hr); + return hr; + } + + /* Set the index stream */ + hr = IWineD3DDevice_SetIndices(This->wineD3DDevice, + This->indexbuffer, + 0); + + /* Set the vertex stream souce */ + hr = IWineD3DDevice_SetStreamSource(This->wineD3DDevice, + 0 /* StreamNumber */, + vb->wineD3DVertexBuffer, + 0 /* offset, we pass this to DrawIndexedPrimitive */, + stride); + if(hr != D3D_OK) + { + ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08lx\n", This, hr); + return hr; + } + + + hr = IWineD3DDevice_DrawIndexedPrimitive(This->wineD3DDevice, + PrimitiveType, + StartVertex, + 0 /* minIndex */, + NumVertices, + 0 /* StartIndex */, + PrimitiveCount); + + return D3D_OK; +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB(IDirect3DDevice3 *iface, + D3DPRIMITIVETYPE PrimitiveType, + IDirect3DVertexBuffer *D3DVertexBuf, + WORD *Indices, + DWORD IndexCount, + DWORD Flags) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); + IDirect3DVertexBufferImpl *VB = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, D3DVertexBuf); + TRACE_(ddraw_thunk)("(%p)->(%08x,%p,%p,%08lx,%08lx) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VB, Indices, IndexCount, Flags); + + return IDirect3DDevice7_DrawIndexedPrimitiveVB(ICOM_INTERFACE(This, IDirect3DDevice7), + PrimitiveType, + ICOM_INTERFACE(VB, IDirect3DVertexBuffer7), + 0, + IndexCount, + Indices, + IndexCount, + Flags); +} + +/***************************************************************************** + * IDirect3DDevice7::ComputeSphereVisibility + * + * Calculates the visibility of spheres in the current viewport. The spheres + * are passed in the Centers and Radii arrays, the results are passed back + * in the ReturnValues array. Return values are eighter completely visible, + * partially visible or completely invisible. + * The return value consist of a combination of D3DCLIP_* flags, or it's + * 0 if the sphere is completely visible(according to the SDK, not checked) + * + * Sounds like an overdose math ;) + * + * Version 3 and 7 + * + * Params: + * Centers: Array containing the sphere centers + * Radii: Array containing the sphere radis + * NumSpheres: The number of centers and radiis in the arrays + * Flags: Some flags + * ReturnValues: Array to write the results to + * + * Returns: + * D3D_OK because it's a stub + * (DDERR_INVALIDPARAMS if Centers, Radii or ReturnValues are NULL) + * (D3DERR_INVALIDMATRIX if the combined world, view and proj matrix + * is singular) + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_7_ComputeSphereVisibility(IDirect3DDevice7 *iface, + D3DVECTOR *Centers, + D3DVALUE *Radii, + DWORD NumSpheres, + DWORD Flags, + DWORD *ReturnValues) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); + FIXME("(%p)->(%p,%p,%08lx,%08lx,%p): stub!\n", This, Centers, Radii, NumSpheres, Flags, ReturnValues); + + /* the DirectX 7 sdk says that the visibility is computed by + * back-transforming the viewing frustum to model space + * using the inverse of the combined world, view and projection + * matrix. If the matrix can't be reversed, D3DERR_INVALIDMATRIX + * is returned. + * + * Basic implementation idea: + * 1) Check if the center is in the viewing frustum + * 2) Cut the sphere with the planes of the viewing + * frustum + * + * ->Center inside the frustum, no intersections: + * Fully visible + * ->Center outside the frustum, no intersections: + * Not visible + * ->Some intersections: Partially visible + * + * Implement this call in WineD3D. Eighter implement the + * matrix and vector stuff in WineD3D, or use some external + * math library. + */ + + return D3D_OK; +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility(IDirect3DDevice3 *iface, + D3DVECTOR *Centers, + D3DVALUE *Radii, + DWORD NumSpheres, + DWORD Flags, + DWORD *ReturnValues) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); + TRACE_(ddraw_thunk)("(%p)->(%p,%p,%08lx,%08lx,%p) thunking to IDirect3DDevice7 interface.\n", This, Centers, Radii, NumSpheres, Flags, ReturnValues); + return IDirect3DDevice7_ComputeSphereVisibility(ICOM_INTERFACE(This, IDirect3DDevice7), + Centers, + Radii, + NumSpheres, + Flags, + ReturnValues); +} + +/***************************************************************************** + * IDirect3DDevice7::GetTexture + * + * Returns the texture interface handle assigned to a texture stage. + * The returned texture is AddRefed. This is taken from old ddraw, + * not checked in Windows. + * + * Version 3 and 7 + * + * Params: + * Stage: Texture stage to read the texture from + * Texture: Address to store the interface pointer at + * + * Returns: + * D3D_OK on success + * DDERR_INVALIDPARAMS if Texture is NULL + * For details, see IWineD3DDevice::GetTexture + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_7_GetTexture(IDirect3DDevice7 *iface, + DWORD Stage, + IDirectDrawSurface7 **Texture) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); + IWineD3DBaseTexture *Surf; + HRESULT hr; + TRACE("(%p)->(%ld,%p): Relay\n", This, Stage, Texture); + + if(!Texture) + { + TRACE("Texture == NULL, failing with DDERR_INVALIDPARAMS\n"); + return DDERR_INVALIDPARAMS; + } + + hr = IWineD3DDevice_GetTexture(This->wineD3DDevice, Stage, (IWineD3DBaseTexture **) &Surf); + if( (hr != D3D_OK) || (!Surf) ) + { + *Texture = NULL; + return hr; + } + + /* GetParent AddRef()s, which is perfectly OK. + * We have passed the IDirectDrawSurface7 interface to WineD3D, so that's OK too. + */ + return IWineD3DBaseTexture_GetParent(Surf, + (IUnknown **) Texture); +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_3_GetTexture(IDirect3DDevice3 *iface, + DWORD Stage, + IDirect3DTexture2 **Texture2) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); + HRESULT ret; + IDirectDrawSurface7 *ret_val; + + TRACE_(ddraw_thunk)("(%p)->(%ld,%p) thunking to IDirect3DDevice7 interface.\n", This, Stage, Texture2); + ret = IDirect3DDevice7_GetTexture(ICOM_INTERFACE(This, IDirect3DDevice7), + Stage, + &ret_val); + + *Texture2 = COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7, IDirect3DTexture2, ret_val); + + TRACE_(ddraw_thunk)(" returning interface %p.\n", *Texture2); + + return ret; +} + +/***************************************************************************** + * IDirect3DDevice7::SetTexture + * + * Assignes a texture to a texture stage. Is the texture AddRefed? + * + * Version 3 and 7 + * + * Params: + * Stage: The stage to assign the texture to + * Texture: Interface pointer to the texture surface + * + * Returns + * D3D_OK on success + * For details, see IWineD3DDevice::SetTexture + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_7_SetTexture(IDirect3DDevice7 *iface, + DWORD Stage, + IDirectDrawSurface7 *Texture) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); + IDirectDrawSurfaceImpl *surf = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, Texture); + TRACE("(%p)->(%08lx,%p): Relay!\n", This, Stage, surf); + + /* Texture may be NULL here */ + return IWineD3DDevice_SetTexture(This->wineD3DDevice, + Stage, + surf ? (IWineD3DBaseTexture * ) surf->wineD3DTexture : NULL); +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_3_SetTexture(IDirect3DDevice3 *iface, + DWORD Stage, + IDirect3DTexture2 *Texture2) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); + IDirectDrawSurfaceImpl *tex = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture2, Texture2); + TRACE_(ddraw_thunk)("(%p)->(%ld,%p) thunking to IDirect3DDevice7 interface.\n", This, Stage, tex); + return IDirect3DDevice7_SetTexture(ICOM_INTERFACE(This, IDirect3DDevice7), + Stage, + ICOM_INTERFACE(tex, IDirectDrawSurface7)); +} + +/***************************************************************************** + * IDirect3DDevice7::GetTextureStageState + * + * Retrieves a state from a texture stage. + * + * Version 3 and 7 + * + * Params: + * Stage: The stage to retrieve the state from + * TexStageStateType: The state type to retrieve + * State: Address to store the state's value at + * + * Returns: + * D3D_OK on success + * DDERR_INVALIDPARAMS if State is NULL + * For details, see IWineD3DDevice::GetTextureStageState + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_7_GetTextureStageState(IDirect3DDevice7 *iface, + DWORD Stage, + D3DTEXTURESTAGESTATETYPE TexStageStateType, + DWORD *State) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); + TRACE("(%p)->(%08lx,%08x,%p): Relay!\n", This, Stage, TexStageStateType, State); + + if(!State) + return DDERR_INVALIDPARAMS; + + return IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, + Stage, + TexStageStateType, + State); +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_3_GetTextureStageState(IDirect3DDevice3 *iface, + DWORD Stage, + D3DTEXTURESTAGESTATETYPE TexStageStateType, + DWORD *State) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); + TRACE_(ddraw_thunk)("(%p)->(%08lx,%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, Stage, TexStageStateType, State); + return IDirect3DDevice7_GetTextureStageState(ICOM_INTERFACE(This, IDirect3DDevice7), + Stage, + TexStageStateType, + State); +} + +/***************************************************************************** + * IDirect3DDevice7::SetTextureStageState + * + * Sets a texture stage state. Some stage types need to be handled specially, + * because they do not exist in WineD3D and were moved to another place + * + * Version 3 and 7 + * + * Params: + * Stage: The stage to modify + * TexStageStateType: The state to change + * State: The new value for the state + * + * Returns: + * D3D_OK on success + * For details, see IWineD3DDevice::SetTextureStageState + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_7_SetTextureStageState(IDirect3DDevice7 *iface, + DWORD Stage, + D3DTEXTURESTAGESTATETYPE TexStageStateType, + DWORD State) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); + TRACE("(%p)->(%08lx,%08x,%08lx): Relay!\n", This, Stage, TexStageStateType, State); + switch(TexStageStateType) + { + /* Mipfilter is a sampler state with different values */ + case D3DTSS_MIPFILTER: + { + WINED3DTEXTUREFILTERTYPE value; + switch(State) + { + case D3DTFP_NONE: value = WINED3DTEXF_NONE; break; + case D3DTFP_POINT: value = WINED3DTEXF_POINT; break; + case 0: /* Unchecked */ + case D3DTFP_LINEAR: value = WINED3DTEXF_LINEAR; break; + default: + ERR("Unexpected mipfilter value %ld\n", State); + value = WINED3DTEXF_NONE; + } + return IWineD3DDevice_SetSamplerState(This->wineD3DDevice, + Stage, + WINED3DSAMP_MIPFILTER, + value); + } + + /* Minfilter is a sampler state too, equal values */ + case D3DTSS_MINFILTER: + return IWineD3DDevice_SetSamplerState(This->wineD3DDevice, + Stage, + WINED3DSAMP_MINFILTER, + State); + /* Same for MAGFILTER */ + case D3DTSS_MAGFILTER: + return IWineD3DDevice_SetSamplerState(This->wineD3DDevice, + Stage, + WINED3DSAMP_MAGFILTER, + State); + + default: + + return IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, + Stage, + TexStageStateType, + State); + } +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_3_SetTextureStageState(IDirect3DDevice3 *iface, + DWORD Stage, + D3DTEXTURESTAGESTATETYPE TexStageStateType, + DWORD State) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); + TRACE_(ddraw_thunk)("(%p)->(%08lx,%08x,%08lx) thunking to IDirect3DDevice7 interface.\n", This, Stage, TexStageStateType, State); + return IDirect3DDevice7_SetTextureStageState(ICOM_INTERFACE(This, IDirect3DDevice7), + Stage, + TexStageStateType, + State); +} + +/***************************************************************************** + * IDirect3DDevice7::ValidateDevice + * + * SDK: "Reports the device's ability to render the currently set + * texture-blending operations in a single pass". Whatever that means + * exactly... + * + * Version 3 and 7 + * + * Params: + * NumPasses: Address to write the number of neccessary passes for the + * desired effect to. + * + * Returns: + * D3D_OK on success + * See IWineD3DDevice::ValidateDevice for more details + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_7_ValidateDevice(IDirect3DDevice7 *iface, + DWORD *NumPasses) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); + TRACE("(%p)->(%p): Relay\n", This, NumPasses); + + return IWineD3DDevice_ValidateDevice(This->wineD3DDevice, NumPasses); +} + +static HRESULT WINAPI +Thunk_IDirect3DDeviceImpl_3_ValidateDevice(IDirect3DDevice3 *iface, + DWORD *Passes) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); + TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Passes); + return IDirect3DDevice7_ValidateDevice(ICOM_INTERFACE(This, IDirect3DDevice7), + Passes); +} + +/***************************************************************************** + * IDirect3DDevice7::Clear + * + * Fills the render target, the z buffer and the stencil buffer with a + * clear color / value + * + * Version 7 only + * + * Params: + * Count: Number of rectangles in Rects must be 0 if Rects is NULL + * Rects: Rectangles to clear. If NULL, the whole surface is cleared + * Flags: Some flags, as usual + * Color: Clear color for the render target + * Z: Clear value for the Z buffer + * Stencil: Clear value to store in each stencil buffer entry + * + * Returns: + * D3D_OK on success + * For details, see IWineD3DDevice::Clear + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_7_Clear(IDirect3DDevice7 *iface, + DWORD Count, + D3DRECT *Rects, + DWORD Flags, + D3DCOLOR Color, + D3DVALUE Z, + DWORD Stencil) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); + TRACE("(%p)->(%08lx,%p,%08lx,%08lx,%f,%08lx): Relay\n", This, Count, Rects, Flags, (DWORD) Color, Z, Stencil); + + return IWineD3DDevice_Clear(This->wineD3DDevice, Count, Rects, Flags, Color, Z, Stencil); +} + +/***************************************************************************** + * IDirect3DDevice7::SetViewport + * + * Sets the current viewport. + * + * Version 7 only, but IDirect3DViewport uses this call for older + * versions + * + * Params: + * Data: The new viewport to set + * + * Returns: + * D3D_OK on success + * DDERR_INVALIDPARAMS if Data is NULL + * For more details, see IWineDDDevice::SetViewport + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_7_SetViewport(IDirect3DDevice7 *iface, + D3DVIEWPORT7 *Data) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); + TRACE("(%p)->(%p) Relay!\n", This, Data); + + if(!Data) + return DDERR_INVALIDPARAMS; + + return IWineD3DDevice_SetViewport(This->wineD3DDevice, + Data); +} + +/***************************************************************************** + * IDirect3DDevice::GetViewport + * + * Returns the current viewport + * + * Version 7 + * + * Params: + * Data: D3D7Viewport structure to write the viewport information to + * + * Returns: + * D3D_OK on success + * DDERR_INVALIDPARAMS if Data is NULL + * For more details, see IWineD3DDevice::GetViewport + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_7_GetViewport(IDirect3DDevice7 *iface, + D3DVIEWPORT7 *Data) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); + HRESULT hr; + TRACE("(%p)->(%p) Relay!\n", This, Data); + + if(!Data) + return DDERR_INVALIDPARAMS; + + hr = IWineD3DDevice_GetViewport(This->wineD3DDevice, + Data); + return hr_ddraw_from_wined3d(hr); +} + +/***************************************************************************** + * IDirect3DDevice7::SetMaterial + * + * Sets the Material + * + * Version 7 + * + * Params: + * Mat: The material to set + * + * Returns: + * D3D_OK on success + * DDERR_INVALIDPARAMS if Mat is NULL. + * For more details, see IWineD3DDevice::SetMaterial + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_7_SetMaterial(IDirect3DDevice7 *iface, + D3DMATERIAL7 *Mat) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); + HRESULT hr; + TRACE("(%p)->(%p): Relay!\n", This, Mat); + + hr = IWineD3DDevice_SetMaterial(This->wineD3DDevice, + Mat); + return hr_ddraw_from_wined3d(hr); +} + +/***************************************************************************** + * IDirect3DDevice7::GetMaterial + * + * Returns the current material + * + * Version 7 + * + * Params: + * Mat: D3DMATERIAL7 structure to write the material paramters to + * + * Returns: + * D3D_OK on success + * DDERR_INVALIDPARAMS if Mat is NULL + * For more details, see IWineD3DDevice::GetMaterial + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_7_GetMaterial(IDirect3DDevice7 *iface, + D3DMATERIAL7 *Mat) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); + HRESULT hr; + TRACE("(%p)->(%p): Relay!\n", This, Mat); + + hr = IWineD3DDevice_GetMaterial(This->wineD3DDevice, + Mat); + return hr_ddraw_from_wined3d(hr); +} + +/***************************************************************************** + * IDirect3DDevice7::SetLight + * + * Assigns a light to a light index, but doesn't activate it yet. + * + * Version 7, IDirect3DLight uses this method for older versions + * + * Params: + * LightIndex: The index of the new light + * Light: A D3DLIGHT7 structure describing the light + * + * Returns: + * D3D_OK on success + * For more details, see IWineD3DDevice::SetLight + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_7_SetLight(IDirect3DDevice7 *iface, + DWORD LightIndex, + D3DLIGHT7 *Light) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); + HRESULT hr; + TRACE("(%p)->(%08lx,%p): Relay!\n", This, LightIndex, Light); + + hr = IWineD3DDevice_SetLight(This->wineD3DDevice, + LightIndex, + Light); + return hr_ddraw_from_wined3d(hr); +} + +/***************************************************************************** + * IDirect3DDevice7::GetLight + * + * Returns the light assigned to a light index + * + * Params: + * Light: Structure to write the light information to + * + * Returns: + * D3D_OK on success + * DDERR_INVALIDPARAMS if Light is NULL + * For details, see IWineD3DDevice::GetLight + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_7_GetLight(IDirect3DDevice7 *iface, + DWORD LightIndex, + D3DLIGHT7 *Light) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); + HRESULT rc; + TRACE("(%p)->(%08lx,%p): Relay!\n", This, LightIndex, Light); + + rc = IWineD3DDevice_GetLight(This->wineD3DDevice, + LightIndex, + Light); + + /* Translate the result. WineD3D returns other values than D3D7 */ + return hr_ddraw_from_wined3d(rc); +} + +/***************************************************************************** + * IDirect3DDevice7::BeginStateBlock + * + * Begins recording to a stateblock + * + * Version 7 + * + * Returns: + * D3D_OK on success + * For details see IWineD3DDevice::BeginStateBlock + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_7_BeginStateBlock(IDirect3DDevice7 *iface) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); + HRESULT hr; + TRACE("(%p)->(): Relay!\n", This); + + hr = IWineD3DDevice_BeginStateBlock(This->wineD3DDevice); + return hr_ddraw_from_wined3d(hr); +} + +/***************************************************************************** + * IDirect3DDevice7::EndStateBlock + * + * Stops recording to a state block and returns the created stateblock + * handle. The d3d7 stateblock handles are the interface pointers of the + * IWineD3DStateBlock interface + * + * Version 7 + * + * Params: + * BlockHandle: Address to store the stateblock's handle to + * + * Returns: + * D3D_OK on success + * DDERR_INVALIDPARAMS if BlockHandle is NULL + * See IWineD3DDevice::EndStateBlock for more details + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_7_EndStateBlock(IDirect3DDevice7 *iface, + DWORD *BlockHandle) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); + HRESULT hr; + TRACE("(%p)->(%p): Relay!\n", This, BlockHandle); + + if(!BlockHandle) + return DDERR_INVALIDPARAMS; + + hr = IWineD3DDevice_EndStateBlock(This->wineD3DDevice, + (IWineD3DStateBlock **) BlockHandle); + return hr_ddraw_from_wined3d(hr); +} + +/***************************************************************************** + * IDirect3DDevice7::PreLoad + * + * Allows the app to signal that a texture will be used soon, to allow + * the Direct3DDevice to load it to the video card in the meantime. + * + * Version 7 + * + * Params: + * Texture: The texture to preload + * + * Returns: + * D3D_OK on success + * DDERR_INVALIDPARAMS if Texture is NULL + * See IWineD3DSurface::PreLoad for details + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_7_PreLoad(IDirect3DDevice7 *iface, + IDirectDrawSurface7 *Texture) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); + IDirectDrawSurfaceImpl *surf = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, Texture); + + TRACE("(%p)->(%p): Relay!\n", This, surf); + + if(!Texture) + return DDERR_INVALIDPARAMS; + + IWineD3DSurface_PreLoad(surf->WineD3DSurface); + return D3D_OK; +} + +/***************************************************************************** + * IDirect3DDevice7::ApplyStateBlock + * + * Activates the state stored in a state block handle. + * + * Params: + * BlockHandle: The stateblock handle to activate + * + * Returns: + * D3D_OK on success + * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_7_ApplyStateBlock(IDirect3DDevice7 *iface, + DWORD BlockHandle) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); + HRESULT hr; + TRACE("(%p)->(%08lx): Relay!\n", This, BlockHandle); + + if(!BlockHandle) + return D3DERR_INVALIDSTATEBLOCK; + + hr = IWineD3DStateBlock_Apply((IWineD3DStateBlock *) BlockHandle); + return hr_ddraw_from_wined3d(hr); +} + +/***************************************************************************** + * IDirect3DDevice7::CaptureStateBlock + * + * Updates a stateblock's values to the values currently set for the device + * + * Version 7 + * + * Params: + * BlockHandle: Stateblock to update + * + * Returns: + * D3D_OK on success + * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL + * See IWineD3DDevice::CaptureStateBlock for more details + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_7_CaptureStateBlock(IDirect3DDevice7 *iface, + DWORD BlockHandle) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); + HRESULT hr; + TRACE("(%p)->(%08lx): Relay!\n", This, BlockHandle); + + if(BlockHandle == 0) + return D3DERR_INVALIDSTATEBLOCK; + + hr = IWineD3DStateBlock_Capture((IWineD3DStateBlock *) BlockHandle); + return hr_ddraw_from_wined3d(hr); +} + +/***************************************************************************** + * IDirect3DDevice7::DeleteStateBlock + * + * Deletes a stateblock handle. This means releasing the WineD3DStateBlock + * + * Version 7 + * + * Params: + * BlockHandle: Stateblock handle to delete + * + * Returns: + * D3D_OK on success + * D3DERR_INVALIDSTATEBLOCK if BlockHandle is 0 + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_7_DeleteStateBlock(IDirect3DDevice7 *iface, + DWORD BlockHandle) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); + TRACE("(%p)->(%08lx): Relay!\n", This, BlockHandle); + + if(BlockHandle == 0) + return D3DERR_INVALIDSTATEBLOCK; + + IWineD3DStateBlock_Release((IWineD3DStateBlock *) BlockHandle); + + return D3D_OK; +} + +/***************************************************************************** + * IDirect3DDevice7::CreateStateBlock + * + * Creates a new state block handle. + * + * Version 7 + * + * Params: + * Type: The state block type + * BlockHandle: Address to write the created handle to + * + * Returns: + * D3D_OK on success + * DDERR_INVALIDPARAMS if BlockHandle is NULL + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_7_CreateStateBlock(IDirect3DDevice7 *iface, + D3DSTATEBLOCKTYPE Type, + DWORD *BlockHandle) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); + HRESULT hr; + TRACE("(%p)->(%08x,%p)!\n", This, Type, BlockHandle); + + if(!BlockHandle) + return DDERR_INVALIDPARAMS; + + /* The D3DSTATEBLOCKTYPE enum is fine here */ + hr = IWineD3DDevice_CreateStateBlock(This->wineD3DDevice, + Type, + (IWineD3DStateBlock **) BlockHandle, + NULL /* Parent, hope that works */); + return hr_ddraw_from_wined3d(hr); +} + +/***************************************************************************** + * IDirect3DDevice7::Load + * + * Loads an rectangular area from the source into the destination texture. + * It can also copy the source to the faces of a cubic environment map + * + * Version 7 + * + * Params: + * DestTex: Destination texture + * DestPoint: Point in the destination where the source image should be + * written to + * SrcTex: Source texture + * SrcRect: Source rectangle + * Flags: Some flags + * + * Returns: + * D3D_OK on success + * DDERR_INVALIDPARAMS if DestTex or SrcTex are NULL + * See IDirect3DTexture2::Load for details + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_7_Load(IDirect3DDevice7 *iface, + IDirectDrawSurface7 *DestTex, + POINT *DestPoint, + IDirectDrawSurface7 *SrcTex, + RECT *SrcRect, + DWORD Flags) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); + IDirectDrawSurfaceImpl *dest = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, DestTex); + IDirectDrawSurfaceImpl *src = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, SrcTex); + FIXME("(%p)->(%p,%p,%p,%p,%08lx): Partially Implemented!\n", This, dest, DestPoint, src, SrcRect, Flags); + + if( (!src) || (!dest) ) + return DDERR_INVALIDPARAMS; + + IDirect3DTexture2_Load(ICOM_INTERFACE(dest, IDirect3DTexture2), + ICOM_INTERFACE(src, IDirect3DTexture2)); + return D3D_OK; +} + +/***************************************************************************** + * IDirect3DDevice7::LightEnable + * + * Enables or disables a light + * + * Version 7, IDirect3DLight uses this method too. + * + * Params: + * LightIndex: The index of the light to enable / disable + * Enable: Enable or disable the light + * + * Returns: + * D3D_OK on success + * For more details, see IWineD3DDevice::SetLightEnable + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_7_LightEnable(IDirect3DDevice7 *iface, + DWORD LightIndex, + BOOL Enable) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); + HRESULT hr; + TRACE("(%p)->(%08lx,%d): Relay!\n", This, LightIndex, Enable); + + hr = IWineD3DDevice_SetLightEnable(This->wineD3DDevice, LightIndex, Enable); + return hr_ddraw_from_wined3d(hr); +} + +/***************************************************************************** + * IDirect3DDevice7::GetLightEnable + * + * Retrieves if the light with the given index is enables or not + * + * Version 7 + * + * Params: + * LightIndex: Index of desired light + * Enable: Pointer to a BOOL which contains the result + * + * Returns: + * D3D_OK on success + * DDERR_INVALIDPARAMS if Enable is NULL + * See IWineD3DDevice::GetLightEnable for more details + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_7_GetLightEnable(IDirect3DDevice7 *iface, + DWORD LightIndex, + BOOL* Enable) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); + HRESULT hr; + TRACE("(%p)->(%08lx,%p): Relay\n", This, LightIndex, Enable); + + if(!Enable) + return DDERR_INVALIDPARAMS; + + hr = IWineD3DDevice_GetLightEnable(This->wineD3DDevice, LightIndex, Enable); + return hr_ddraw_from_wined3d(hr); +} + +/***************************************************************************** + * IDirect3DDevice7::SetClipPlane + * + * Sets custom clipping plane + * + * Version 7 + * + * Params: + * Index: The index of the clipping plane + * PlaneEquation: An equation defining the clipping plane + * + * Returns: + * D3D_OK on success + * DDERR_INVALIDPARAMS if PlaneEquation is NULL + * See IWineD3DDevice::SetClipPlane for more details + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_7_SetClipPlane(IDirect3DDevice7 *iface, + DWORD Index, + D3DVALUE* PlaneEquation) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); + TRACE("(%p)->(%08lx,%p): Relay!\n", This, Index, PlaneEquation); + + if(!PlaneEquation) + return DDERR_INVALIDPARAMS; + + return IWineD3DDevice_SetClipPlane(This->wineD3DDevice, Index, PlaneEquation); +} + +/***************************************************************************** + * IDirect3DDevice7::GetClipPlane + * + * Returns the clipping plane with a specific index + * + * Params: + * Index: The index of the desired plane + * PlaneEquation: Address to store the plane equation to + * + * Returns: + * D3D_OK on success + * DDERR_INVALIDPARAMS if PlaneEquation is NULL + * See IWineD3DDevice::GetClipPlane for more details + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_7_GetClipPlane(IDirect3DDevice7 *iface, + DWORD Index, + D3DVALUE* PlaneEquation) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); + TRACE("(%p)->(%ld,%p): Relay!\n", This, Index, PlaneEquation); + + if(!PlaneEquation) + return DDERR_INVALIDPARAMS; + + return IWineD3DDevice_GetClipPlane(This->wineD3DDevice, Index, PlaneEquation); +} + +/***************************************************************************** + * IDirect3DDevice7::GetInfo + * + * Retrieves some information about the device. The DirectX sdk says that + * this version returnes S_FALSE for all retail build of DirectX, that's + * this implementation does. + * + * Params: + * DevInfoID: Information type requested + * DevInfoStruct: Pointer to a structure to store the info to + * Size: Size of the structure + * + * Returns: + * S_FALSE, because it's a non-debug driver + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DDeviceImpl_7_GetInfo(IDirect3DDevice7 *iface, + DWORD DevInfoID, + void *DevInfoStruct, + DWORD Size) +{ + ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); + TRACE("(%p)->(%08lx,%p,%08lx)\n", This, DevInfoID, DevInfoStruct, Size); + + if (TRACE_ON(d3d7)) + { + TRACE(" info requested : "); + switch (DevInfoID) + { + case D3DDEVINFOID_TEXTUREMANAGER: TRACE("D3DDEVINFOID_TEXTUREMANAGER\n"); break; + case D3DDEVINFOID_D3DTEXTUREMANAGER: TRACE("D3DDEVINFOID_D3DTEXTUREMANAGER\n"); break; + case D3DDEVINFOID_TEXTURING: TRACE("D3DDEVINFOID_TEXTURING\n"); break; + default: ERR(" invalid flag !!!\n"); return DDERR_INVALIDPARAMS; + } + } + + return S_FALSE; /* According to MSDN, this is valid for a non-debug driver */ +} + +const IDirect3DDevice7Vtbl IDirect3DDevice7_Vtbl = +{ + /*** IUnknown Methods ***/ + IDirect3DDeviceImpl_7_QueryInterface, + IDirect3DDeviceImpl_7_AddRef, + IDirect3DDeviceImpl_7_Release, + /*** IDirect3DDevice7 ***/ + IDirect3DDeviceImpl_7_GetCaps, + IDirect3DDeviceImpl_7_EnumTextureFormats, + IDirect3DDeviceImpl_7_BeginScene, + IDirect3DDeviceImpl_7_EndScene, + IDirect3DDeviceImpl_7_GetDirect3D, + IDirect3DDeviceImpl_7_SetRenderTarget, + IDirect3DDeviceImpl_7_GetRenderTarget, + IDirect3DDeviceImpl_7_Clear, + IDirect3DDeviceImpl_7_SetTransform, + IDirect3DDeviceImpl_7_GetTransform, + IDirect3DDeviceImpl_7_SetViewport, + IDirect3DDeviceImpl_7_MultiplyTransform, + IDirect3DDeviceImpl_7_GetViewport, + IDirect3DDeviceImpl_7_SetMaterial, + IDirect3DDeviceImpl_7_GetMaterial, + IDirect3DDeviceImpl_7_SetLight, + IDirect3DDeviceImpl_7_GetLight, + IDirect3DDeviceImpl_7_SetRenderState, + IDirect3DDeviceImpl_7_GetRenderState, + IDirect3DDeviceImpl_7_BeginStateBlock, + IDirect3DDeviceImpl_7_EndStateBlock, + IDirect3DDeviceImpl_7_PreLoad, + IDirect3DDeviceImpl_7_DrawPrimitive, + IDirect3DDeviceImpl_7_DrawIndexedPrimitive, + IDirect3DDeviceImpl_7_SetClipStatus, + IDirect3DDeviceImpl_7_GetClipStatus, + IDirect3DDeviceImpl_7_DrawPrimitiveStrided, + IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided, + IDirect3DDeviceImpl_7_DrawPrimitiveVB, + IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB, + IDirect3DDeviceImpl_7_ComputeSphereVisibility, + IDirect3DDeviceImpl_7_GetTexture, + IDirect3DDeviceImpl_7_SetTexture, + IDirect3DDeviceImpl_7_GetTextureStageState, + IDirect3DDeviceImpl_7_SetTextureStageState, + IDirect3DDeviceImpl_7_ValidateDevice, + IDirect3DDeviceImpl_7_ApplyStateBlock, + IDirect3DDeviceImpl_7_CaptureStateBlock, + IDirect3DDeviceImpl_7_DeleteStateBlock, + IDirect3DDeviceImpl_7_CreateStateBlock, + IDirect3DDeviceImpl_7_Load, + IDirect3DDeviceImpl_7_LightEnable, + IDirect3DDeviceImpl_7_GetLightEnable, + IDirect3DDeviceImpl_7_SetClipPlane, + IDirect3DDeviceImpl_7_GetClipPlane, + IDirect3DDeviceImpl_7_GetInfo +}; + +const IDirect3DDevice3Vtbl IDirect3DDevice3_Vtbl = +{ + /*** IUnknown Methods ***/ + Thunk_IDirect3DDeviceImpl_3_QueryInterface, + Thunk_IDirect3DDeviceImpl_3_AddRef, + Thunk_IDirect3DDeviceImpl_3_Release, + /*** IDirect3DDevice3 ***/ + IDirect3DDeviceImpl_3_GetCaps, + IDirect3DDeviceImpl_3_GetStats, + IDirect3DDeviceImpl_3_AddViewport, + IDirect3DDeviceImpl_3_DeleteViewport, + IDirect3DDeviceImpl_3_NextViewport, + Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats, + Thunk_IDirect3DDeviceImpl_3_BeginScene, + Thunk_IDirect3DDeviceImpl_3_EndScene, + Thunk_IDirect3DDeviceImpl_3_GetDirect3D, + IDirect3DDeviceImpl_3_SetCurrentViewport, + IDirect3DDeviceImpl_3_GetCurrentViewport, + Thunk_IDirect3DDeviceImpl_3_SetRenderTarget, + Thunk_IDirect3DDeviceImpl_3_GetRenderTarget, + IDirect3DDeviceImpl_3_Begin, + IDirect3DDeviceImpl_3_BeginIndexed, + IDirect3DDeviceImpl_3_Vertex, + IDirect3DDeviceImpl_3_Index, + IDirect3DDeviceImpl_3_End, + Thunk_IDirect3DDeviceImpl_3_GetRenderState, + Thunk_IDirect3DDeviceImpl_3_SetRenderState, + IDirect3DDeviceImpl_3_GetLightState, + IDirect3DDeviceImpl_3_SetLightState, + Thunk_IDirect3DDeviceImpl_3_SetTransform, + Thunk_IDirect3DDeviceImpl_3_GetTransform, + Thunk_IDirect3DDeviceImpl_3_MultiplyTransform, + Thunk_IDirect3DDeviceImpl_3_DrawPrimitive, + Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive, + Thunk_IDirect3DDeviceImpl_3_SetClipStatus, + Thunk_IDirect3DDeviceImpl_3_GetClipStatus, + Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided, + Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided, + Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB, + Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB, + Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility, + Thunk_IDirect3DDeviceImpl_3_GetTexture, + Thunk_IDirect3DDeviceImpl_3_SetTexture, + Thunk_IDirect3DDeviceImpl_3_GetTextureStageState, + Thunk_IDirect3DDeviceImpl_3_SetTextureStageState, + Thunk_IDirect3DDeviceImpl_3_ValidateDevice +}; + +const IDirect3DDevice2Vtbl IDirect3DDevice2_Vtbl = +{ + /*** IUnknown Methods ***/ + Thunk_IDirect3DDeviceImpl_2_QueryInterface, + Thunk_IDirect3DDeviceImpl_2_AddRef, + Thunk_IDirect3DDeviceImpl_2_Release, + /*** IDirect3DDevice2 ***/ + Thunk_IDirect3DDeviceImpl_2_GetCaps, + IDirect3DDeviceImpl_2_SwapTextureHandles, + Thunk_IDirect3DDeviceImpl_2_GetStats, + Thunk_IDirect3DDeviceImpl_2_AddViewport, + Thunk_IDirect3DDeviceImpl_2_DeleteViewport, + Thunk_IDirect3DDeviceImpl_2_NextViewport, + IDirect3DDeviceImpl_2_EnumTextureFormats, + Thunk_IDirect3DDeviceImpl_2_BeginScene, + Thunk_IDirect3DDeviceImpl_2_EndScene, + Thunk_IDirect3DDeviceImpl_2_GetDirect3D, + Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport, + Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport, + Thunk_IDirect3DDeviceImpl_2_SetRenderTarget, + Thunk_IDirect3DDeviceImpl_2_GetRenderTarget, + Thunk_IDirect3DDeviceImpl_2_Begin, + Thunk_IDirect3DDeviceImpl_2_BeginIndexed, + Thunk_IDirect3DDeviceImpl_2_Vertex, + Thunk_IDirect3DDeviceImpl_2_Index, + Thunk_IDirect3DDeviceImpl_2_End, + Thunk_IDirect3DDeviceImpl_2_GetRenderState, + Thunk_IDirect3DDeviceImpl_2_SetRenderState, + Thunk_IDirect3DDeviceImpl_2_GetLightState, + Thunk_IDirect3DDeviceImpl_2_SetLightState, + Thunk_IDirect3DDeviceImpl_2_SetTransform, + Thunk_IDirect3DDeviceImpl_2_GetTransform, + Thunk_IDirect3DDeviceImpl_2_MultiplyTransform, + Thunk_IDirect3DDeviceImpl_2_DrawPrimitive, + Thunk_IDirect3DDeviceImpl_2_DrawIndexedPrimitive, + Thunk_IDirect3DDeviceImpl_2_SetClipStatus, + Thunk_IDirect3DDeviceImpl_2_GetClipStatus +}; + +const IDirect3DDeviceVtbl IDirect3DDevice1_Vtbl = +{ + /*** IUnknown Methods ***/ + Thunk_IDirect3DDeviceImpl_1_QueryInterface, + Thunk_IDirect3DDeviceImpl_1_AddRef, + Thunk_IDirect3DDeviceImpl_1_Release, + /*** IDirect3DDevice1 ***/ + IDirect3DDeviceImpl_1_Initialize, + Thunk_IDirect3DDeviceImpl_1_GetCaps, + Thunk_IDirect3DDeviceImpl_1_SwapTextureHandles, + IDirect3DDeviceImpl_1_CreateExecuteBuffer, + Thunk_IDirect3DDeviceImpl_1_GetStats, + IDirect3DDeviceImpl_1_Execute, + Thunk_IDirect3DDeviceImpl_1_AddViewport, + Thunk_IDirect3DDeviceImpl_1_DeleteViewport, + Thunk_IDirect3DDeviceImpl_1_NextViewport, + IDirect3DDeviceImpl_1_Pick, + IDirect3DDeviceImpl_1_GetPickRecords, + Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats, + IDirect3DDeviceImpl_1_CreateMatrix, + IDirect3DDeviceImpl_1_SetMatrix, + IDirect3DDeviceImpl_1_GetMatrix, + IDirect3DDeviceImpl_1_DeleteMatrix, + Thunk_IDirect3DDeviceImpl_1_EndScene, + Thunk_IDirect3DDeviceImpl_1_BeginScene, + Thunk_IDirect3DDeviceImpl_1_GetDirect3D +}; diff --git a/dlls/ddraw/device_main.c b/dlls/ddraw/device_main.c deleted file mode 100644 index 55ee51f521..0000000000 --- a/dlls/ddraw/device_main.c +++ /dev/null @@ -1,2241 +0,0 @@ -/* - * Direct3D Device - * - * Copyright (c) 1998-2004 Lionel Ulmer - * Copyright (c) 2002-2005 Christian Costa - * - * This file contains all the common stuff for D3D devices. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "config.h" - -#include -#include - -#include "windef.h" -#include "winbase.h" -#include "winerror.h" -#include "objbase.h" -#include "wingdi.h" -#include "ddraw.h" -#include "d3d.h" -#include "wine/debug.h" - -#include "d3d_private.h" - -WINE_DEFAULT_DEBUG_CHANNEL(ddraw); - -DWORD InitRenderStateTab[] = { - D3DRENDERSTATE_TEXTUREHANDLE, (DWORD)NULL, - D3DRENDERSTATE_ANTIALIAS, D3DANTIALIAS_NONE, - /* FIXME: D3DRENDERSTATE_TEXTUREADDRESS */ - D3DRENDERSTATE_TEXTUREPERSPECTIVE, TRUE, - /* FIXME: D3DRENDERSTATE_WRAPU */ - /* FIXME: D3DRENDERSTATE_WRAPV */ - D3DRENDERSTATE_ZENABLE, D3DZB_TRUE, /* This needs to be set differently according to the Z buffer status */ - D3DRENDERSTATE_FILLMODE, D3DFILL_SOLID, - D3DRENDERSTATE_SHADEMODE, D3DSHADE_GOURAUD, - D3DRENDERSTATE_LINEPATTERN, 0, - D3DRENDERSTATE_MONOENABLE, FALSE, - D3DRENDERSTATE_ROP2, R2_COPYPEN, - D3DRENDERSTATE_PLANEMASK, 0xFFFFFFFF, - D3DRENDERSTATE_ZWRITEENABLE, TRUE, - D3DRENDERSTATE_ALPHATESTENABLE, FALSE, - D3DRENDERSTATE_LASTPIXEL, TRUE, - D3DRENDERSTATE_TEXTUREMAG, D3DFILTER_NEAREST, - D3DRENDERSTATE_TEXTUREMIN, D3DFILTER_NEAREST, - D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE, - D3DRENDERSTATE_DESTBLEND, D3DBLEND_ZERO, - D3DRENDERSTATE_TEXTUREMAPBLEND, D3DTBLEND_MODULATE, - D3DRENDERSTATE_CULLMODE, D3DCULL_CCW, - D3DRENDERSTATE_ZFUNC, D3DCMP_LESSEQUAL, - D3DRENDERSTATE_ALPHAREF, 0, - D3DRENDERSTATE_ALPHAFUNC, D3DCMP_ALWAYS, - D3DRENDERSTATE_DITHERENABLE, FALSE, - D3DRENDERSTATE_ALPHABLENDENABLE, FALSE, - D3DRENDERSTATE_FOGENABLE, FALSE, - D3DRENDERSTATE_SPECULARENABLE, FALSE, - D3DRENDERSTATE_ZVISIBLE, FALSE, - D3DRENDERSTATE_SUBPIXEL, FALSE, - D3DRENDERSTATE_SUBPIXELX, FALSE, - D3DRENDERSTATE_STIPPLEDALPHA, FALSE, - D3DRENDERSTATE_FOGCOLOR, D3DRGBA(0,0,0,0), - D3DRENDERSTATE_FOGTABLEMODE, D3DFOG_NONE, - /* FIXME: D3DRENDERSTATE_FOGTABLESTART (same as D3DRENDERSTATE_FOGSTART) */ - /* FIXME: D3DRENDERSTATE_FOGTABLEEND (same as D3DRENDERSTATE_FOGEND) */ - D3DRENDERSTATE_FOGTABLEDENSITY, 0x3F80000, /* 1.0f (same as D3DRENDERSTATE_FOGDENSITY) */ - /* FIXME: D3DRENDERSTATE_STIPPLEENABLE */ - D3DRENDERSTATE_EDGEANTIALIAS, FALSE, - D3DRENDERSTATE_COLORKEYENABLE, FALSE, - /* FIXME: D3DRENDERSTATE_BORDERCOLOR */ - D3DRENDERSTATE_TEXTUREADDRESSU, D3DTADDRESS_WRAP, - D3DRENDERSTATE_TEXTUREADDRESSV, D3DTADDRESS_WRAP, - D3DRENDERSTATE_MIPMAPLODBIAS, 0x00000000, /* 0.0f */ - D3DRENDERSTATE_ZBIAS, 0, - D3DRENDERSTATE_RANGEFOGENABLE, FALSE, - /* FIXME: D3DRENDERSTATE_ANISOTROPY */ - /* FIXME: D3DRENDERSTATE_FLUSHBATCH */ - /* FIXME: D3DRENDERSTATE_TRANSLUCENTSORTINDEPENDENT */ - D3DRENDERSTATE_STENCILENABLE, FALSE, - D3DRENDERSTATE_STENCILFAIL, D3DSTENCILOP_KEEP, - D3DRENDERSTATE_STENCILZFAIL, D3DSTENCILOP_KEEP, - D3DRENDERSTATE_STENCILPASS, D3DSTENCILOP_KEEP, - D3DRENDERSTATE_STENCILFUNC, D3DCMP_ALWAYS, - D3DRENDERSTATE_STENCILREF, 0, - D3DRENDERSTATE_STENCILMASK, 0xFFFFFFFF, - D3DRENDERSTATE_STENCILWRITEMASK, 0xFFFFFFFF, - /* FIXME: D3DRENDERSTATE_TEXTUREFACTOR */ - /* FIXME: D3DRENDERSTATE_STIPPLEPATTERN00..31 */ - D3DRENDERSTATE_WRAP0, 0, - D3DRENDERSTATE_WRAP1, 0, - D3DRENDERSTATE_WRAP2, 0, - D3DRENDERSTATE_WRAP3, 0, - D3DRENDERSTATE_WRAP4, 0, - D3DRENDERSTATE_WRAP5, 0, - D3DRENDERSTATE_WRAP6, 0, - D3DRENDERSTATE_WRAP7, 0, - D3DRENDERSTATE_CLIPPING, FALSE, - D3DRENDERSTATE_LIGHTING, TRUE, - D3DRENDERSTATE_EXTENTS, FALSE, - D3DRENDERSTATE_AMBIENT, D3DRGBA(0,0,0,0), - D3DRENDERSTATE_FOGVERTEXMODE, D3DFOG_NONE, - D3DRENDERSTATE_COLORVERTEX, TRUE, - D3DRENDERSTATE_LOCALVIEWER, TRUE, - D3DRENDERSTATE_NORMALIZENORMALS, FALSE, - /* FIXME: D3DRENDER_STATE_COLORKEYBLENDENABLE */ - D3DRENDERSTATE_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1, - D3DRENDERSTATE_SPECULARMATERIALSOURCE, D3DMCS_COLOR2, - D3DRENDERSTATE_AMBIENTMATERIALSOURCE, D3DMCS_COLOR2, - D3DRENDERSTATE_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL, - D3DRENDERSTATE_VERTEXBLEND, D3DVBLEND_DISABLE, - D3DRENDERSTATE_CLIPPLANEENABLE, 0 -}; - -DWORD InitLightStateTab[] = { - D3DLIGHTSTATE_MATERIAL, (DWORD)NULL, - D3DLIGHTSTATE_AMBIENT, D3DRGBA(0,0,0,0), - D3DLIGHTSTATE_COLORMODEL, D3DCOLOR_RGB, - D3DLIGHTSTATE_FOGMODE, D3DFOG_NONE, - D3DLIGHTSTATE_FOGSTART, 0x3F80000, /* 1.0f */ - D3DLIGHTSTATE_FOGEND, 0x42C8000, /* 100.0f */ - D3DLIGHTSTATE_FOGDENSITY, 0x3F80000 /* 1.0f */ - /* FIXME: D3DLIGHTSTATE_COLORVERTEX */ -}; - -DWORD InitTextureStageStateTab[] = { - D3DTSS_COLOROP, D3DTOP_DISABLE, /* Note, it's manually set for stage 0 */ - D3DTSS_COLORARG1, D3DTA_TEXTURE, - D3DTSS_COLORARG2, D3DTA_CURRENT, - D3DTSS_ALPHAOP, D3DTOP_DISABLE, /* Note, it's manually set for stage 0 */ - D3DTSS_ALPHAARG1, D3DTA_TEXTURE, - D3DTSS_ALPHAARG2, D3DTA_CURRENT, - /* FIXME: D3DTSS_BUMPENVMAT00,01,10,11 */ - /* D3DTSS_TEXCOORDINDEX is set manually */ - D3DTSS_ADDRESS, D3DTADDRESS_WRAP, - D3DTSS_ADDRESSU, D3DTADDRESS_WRAP, - D3DTSS_ADDRESSV, D3DTADDRESS_WRAP, - D3DTSS_BORDERCOLOR, 0x00000000, - D3DTSS_MAGFILTER, D3DTFG_POINT, - D3DTSS_MINFILTER, D3DTFN_POINT, - D3DTSS_MIPFILTER, D3DTFP_NONE, - D3DTSS_MIPMAPLODBIAS, 0x00000000, /* 0.0f */ - D3DTSS_MAXMIPLEVEL, 0, - /* D3DTSS_MAXANISOTROPY, 1, */ /* This is to prevent warnings :-) */ - /* FIXME: D3DTSS_BUMPENVLSCALE */ - /* FIXME: D3DTSS_NUMPENVLOFFSET */ - /* FIXME: D3DTSS_TEXTURETRANSFORMFLAGS */ -}; - - -void InitDefaultStateBlock(STATEBLOCK* lpStateBlock, int version) -{ - unsigned int i, j; - TRACE("(%p,%d)\n", lpStateBlock, version); - memset(lpStateBlock, 0, sizeof(STATEBLOCK)); - - /* Initialize render states */ - for (i = 0; i < sizeof(InitRenderStateTab) / sizeof(InitRenderStateTab[0]); i += 2) - { - lpStateBlock->render_state[InitRenderStateTab[i] - 1] = InitRenderStateTab[i + 1]; - lpStateBlock->set_flags.render_state[InitRenderStateTab[i] - 1] = TRUE; - } - - /* Initialize texture stages states */ - for (i = 0; i < MAX_TEXTURES; i++) - { - for (j = 0; j < sizeof(InitTextureStageStateTab) / sizeof(InitTextureStageStateTab[0]); j += 2) - { - lpStateBlock->texture_stage_state[i][InitTextureStageStateTab[j] - 1] = InitTextureStageStateTab[j + 1]; - lpStateBlock->set_flags.texture_stage_state[i][InitTextureStageStateTab[j] - 1] = TRUE; - } - /* Map texture coords 0 to stage 0, 1 to stage 1, etc... */ - lpStateBlock->texture_stage_state[i][D3DTSS_TEXCOORDINDEX - 1] = i; - lpStateBlock->set_flags.texture_stage_state[i][D3DTSS_TEXCOORDINDEX - 1] = TRUE; - } - - /* The first texture is particular, update it consequently */ - lpStateBlock->texture_stage_state[0][D3DTSS_COLOROP - 1] = D3DTOP_MODULATE; - lpStateBlock->texture_stage_state[0][D3DTSS_ALPHAOP - 1] = D3DTOP_SELECTARG1; - lpStateBlock->texture_stage_state[0][D3DTSS_COLORARG2 - 1] = D3DTA_DIFFUSE; - lpStateBlock->texture_stage_state[0][D3DTSS_ALPHAARG2 - 1] = D3DTA_DIFFUSE; - - /* Updates for particular versions */ - if ((version == 1) || (version==2)) - lpStateBlock->render_state[D3DRENDERSTATE_SPECULARENABLE - 1] = TRUE; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_3T_2T_1T_QueryInterface(LPDIRECT3DDEVICE7 iface, - REFIID riid, - LPVOID* obp) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - TRACE("(%p/%p)->(%s,%p)\n", This, iface, debugstr_guid(riid), obp); - - *obp = NULL; - - /* Note: We cannot get an interface whose version is higher than the - * Direct3D object that created the device */ - - if ( IsEqualGUID( &IID_IUnknown, riid ) ) { - IDirect3DDevice7_AddRef(ICOM_INTERFACE(This, IDirect3DDevice7)); - *obp = iface; - TRACE(" Creating IUnknown interface at %p.\n", *obp); - return S_OK; - } - if ( IsEqualGUID( &IID_IDirect3DDevice, riid ) ) { - IDirect3DDevice7_AddRef(ICOM_INTERFACE(This, IDirect3DDevice7)); - *obp = ICOM_INTERFACE(This, IDirect3DDevice); - TRACE(" Creating IDirect3DDevice interface %p\n", *obp); - return S_OK; - } - if ( IsEqualGUID( &IID_IDirect3DDevice2, riid ) && (This->version >= 2)) { - IDirect3DDevice7_AddRef(ICOM_INTERFACE(This, IDirect3DDevice7)); - *obp = ICOM_INTERFACE(This, IDirect3DDevice2); - TRACE(" Creating IDirect3DDevice2 interface %p\n", *obp); - return S_OK; - } - if ( IsEqualGUID( &IID_IDirect3DDevice3, riid ) && (This->version >= 3)) { - IDirect3DDevice7_AddRef(ICOM_INTERFACE(This, IDirect3DDevice7)); - *obp = ICOM_INTERFACE(This, IDirect3DDevice3); - TRACE(" Creating IDirect3DDevice3 interface %p\n", *obp); - return S_OK; - } - if ( IsEqualGUID( &IID_IDirect3DDevice7, riid ) && (This->version >= 7)) { - IDirect3DDevice7_AddRef(ICOM_INTERFACE(This, IDirect3DDevice7)); - *obp = ICOM_INTERFACE(This, IDirect3DDevice7); - TRACE(" Creating IDirect3DDevice7 interface %p\n", *obp); - return S_OK; - } - if ( IsEqualGUID( &IID_IDirectDrawSurface, riid ) || - IsEqualGUID( &IID_IDirectDrawSurface2, riid ) || - IsEqualGUID( &IID_IDirectDrawSurface3, riid ) ) { - IDirectDrawSurface7_AddRef(ICOM_INTERFACE(This->surface, IDirectDrawSurface7)); - *obp = ICOM_INTERFACE(This->surface, IDirectDrawSurface3); - TRACE(" Return IDirectDrawSurface3 interface %p\n", *obp); - return S_OK; - } - if ( IsEqualGUID( &IID_IDirectDrawSurface4, riid ) || - IsEqualGUID( &IID_IDirectDrawSurface7, riid ) ) { - IDirectDrawSurface7_AddRef(ICOM_INTERFACE(This->surface, IDirectDrawSurface7)); - *obp = ICOM_INTERFACE(This->surface, IDirectDrawSurface7); - TRACE(" Return IDirectDrawSurface7 interface %p\n", *obp); - return S_OK; - } - FIXME("(%p): interface for IID %s NOT found!\n", This, debugstr_guid(riid)); - return OLE_E_ENUM_NOMORE; -} - -ULONG WINAPI -Main_IDirect3DDeviceImpl_7_3T_2T_1T_AddRef(LPDIRECT3DDEVICE7 iface) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - ULONG ref = InterlockedIncrement(&This->ref); - - TRACE("(%p/%p)->() incrementing from %lu.\n", This, iface, ref - 1); - - return ref; -} - -ULONG WINAPI -Main_IDirect3DDeviceImpl_7_3T_2T_1T_Release(LPDIRECT3DDEVICE7 iface) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - ULONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p/%p)->() decrementing from %lu.\n", This, iface, ref + 1); - - if (!ref) { - int i; - /* Release texture associated with the device */ - for (i = 0; i < MAX_TEXTURES; i++) { - if (This->current_texture[i] != NULL) - IDirect3DTexture2_Release(ICOM_INTERFACE(This->current_texture[i], IDirect3DTexture2)); - } - HeapFree(GetProcessHeap(), 0, This->vertex_buffer); - HeapFree(GetProcessHeap(), 0, This); - return 0; - } - return ref; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_GetCaps(LPDIRECT3DDEVICE7 iface, - LPD3DDEVICEDESC7 lpD3DHELDevDesc) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpD3DHELDevDesc); - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_3T_EnumTextureFormats(LPDIRECT3DDEVICE7 iface, - LPD3DENUMPIXELFORMATSCALLBACK lpD3DEnumPixelProc, - LPVOID lpArg) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lpD3DEnumPixelProc, lpArg); - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_3T_2T_1T_BeginScene(LPDIRECT3DDEVICE7 iface) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - TRACE("(%p/%p)->()\n", This, iface); - /* Nothing to do */ - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_3T_2T_1T_EndScene(LPDIRECT3DDEVICE7 iface) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - TRACE("(%p/%p)->()\n", This, iface); - /* Nothing to do */ - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_3T_2T_1T_GetDirect3D(LPDIRECT3DDEVICE7 iface, - LPDIRECT3D7* lplpDirect3D7) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - TRACE("(%p/%p)->(%p)\n", This, iface, lplpDirect3D7); - - *lplpDirect3D7 = ICOM_INTERFACE(This->d3d, IDirect3D7); - IDirect3D7_AddRef(ICOM_INTERFACE(This->d3d, IDirect3D7)); - - TRACE(" returning interface %p\n", *lplpDirect3D7); - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_3T_2T_SetRenderTarget(LPDIRECT3DDEVICE7 iface, - LPDIRECTDRAWSURFACE7 lpNewRenderTarget, - DWORD dwFlags) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - IDirectDrawSurfaceImpl *target_impl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, lpNewRenderTarget); - - TRACE("(%p/%p)->(%p,%08lx)\n", This, iface, lpNewRenderTarget, dwFlags); - if (target_impl != This->surface) { - WARN(" Change of rendering target not handled yet !\n"); - } - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_3T_2T_GetRenderTarget(LPDIRECT3DDEVICE7 iface, - LPDIRECTDRAWSURFACE7* lplpRenderTarget) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - TRACE("(%p/%p)->(%p)\n", This, iface, lplpRenderTarget); - - *lplpRenderTarget = ICOM_INTERFACE(This->surface, IDirectDrawSurface7); - IDirectDrawSurface7_AddRef(ICOM_INTERFACE(This->surface, IDirectDrawSurface7)); - - TRACE(" returning surface at %p.\n", *lplpRenderTarget); - - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_Clear(LPDIRECT3DDEVICE7 iface, - DWORD dwCount, - LPD3DRECT lpRects, - DWORD dwFlags, - D3DCOLOR dwColor, - D3DVALUE dvZ, - DWORD dwStencil) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - TRACE("(%p/%p)->(%08lx,%p,%08lx,%08lx,%f,%08lx)\n", This, iface, dwCount, lpRects, dwFlags, (DWORD) dwColor, dvZ, dwStencil); - return This->clear(This, dwCount, lpRects, dwFlags, dwColor, dvZ, dwStencil); -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_3T_2T_SetTransform(LPDIRECT3DDEVICE7 iface, - D3DTRANSFORMSTATETYPE dtstTransformStateType, - LPD3DMATRIX lpD3DMatrix) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - DWORD matrix_changed = 0x00000000; - - TRACE("(%p/%p)->(%08x,%p)\n", This, iface, dtstTransformStateType, lpD3DMatrix); - - switch (dtstTransformStateType) { - case D3DTRANSFORMSTATE_WORLD: { - if (TRACE_ON(ddraw)) { - TRACE(" D3DTRANSFORMSTATE_WORLD :\n"); dump_D3DMATRIX(lpD3DMatrix); - } - memcpy(This->world_mat, lpD3DMatrix, 16 * sizeof(float)); - matrix_changed = WORLDMAT_CHANGED; - } break; - - case D3DTRANSFORMSTATE_VIEW: { - if (TRACE_ON(ddraw)) { - TRACE(" D3DTRANSFORMSTATE_VIEW :\n"); dump_D3DMATRIX(lpD3DMatrix); - } - memcpy(This->view_mat, lpD3DMatrix, 16 * sizeof(float)); - matrix_changed = VIEWMAT_CHANGED; - } break; - - case D3DTRANSFORMSTATE_PROJECTION: { - if (TRACE_ON(ddraw)) { - TRACE(" D3DTRANSFORMSTATE_PROJECTION :\n"); dump_D3DMATRIX(lpD3DMatrix); - } - memcpy(This->proj_mat, lpD3DMatrix, 16 * sizeof(float)); - matrix_changed = PROJMAT_CHANGED; - } break; - - case D3DTRANSFORMSTATE_TEXTURE0: - case D3DTRANSFORMSTATE_TEXTURE1: - case D3DTRANSFORMSTATE_TEXTURE2: - case D3DTRANSFORMSTATE_TEXTURE3: - case D3DTRANSFORMSTATE_TEXTURE4: - case D3DTRANSFORMSTATE_TEXTURE5: - case D3DTRANSFORMSTATE_TEXTURE6: - case D3DTRANSFORMSTATE_TEXTURE7: { - DWORD mat_num = dtstTransformStateType - D3DTRANSFORMSTATE_TEXTURE0; - if (TRACE_ON(ddraw)) { - TRACE(" D3DTRANSFORMSTATE_TEXTURE%ld :\n", mat_num); dump_D3DMATRIX(lpD3DMatrix); - } - memcpy(This->tex_mat[mat_num], lpD3DMatrix, 16 * sizeof(float)); - matrix_changed = TEXMAT0_CHANGED << mat_num; - } break; - - default: - ERR("Unknown transform type %08x !!!\n", dtstTransformStateType); - break; - } - - if (matrix_changed != 0x00000000) This->matrices_updated(This, matrix_changed); - - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_3T_2T_GetTransform(LPDIRECT3DDEVICE7 iface, - D3DTRANSFORMSTATETYPE dtstTransformStateType, - LPD3DMATRIX lpD3DMatrix) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - TRACE("(%p/%p)->(%08x,%p)\n", This, iface, dtstTransformStateType, lpD3DMatrix); - - switch (dtstTransformStateType) { - case D3DTRANSFORMSTATE_WORLD: { - memcpy(lpD3DMatrix, This->world_mat, 16 * sizeof(D3DVALUE)); - if (TRACE_ON(ddraw)) { - TRACE(" returning D3DTRANSFORMSTATE_WORLD :\n"); - dump_D3DMATRIX(lpD3DMatrix); - } - } break; - - case D3DTRANSFORMSTATE_VIEW: { - memcpy(lpD3DMatrix, This->view_mat, 16 * sizeof(D3DVALUE)); - if (TRACE_ON(ddraw)) { - TRACE(" returning D3DTRANSFORMSTATE_VIEW :\n"); - dump_D3DMATRIX(lpD3DMatrix); - } - } break; - - case D3DTRANSFORMSTATE_PROJECTION: { - memcpy(lpD3DMatrix, This->proj_mat, 16 * sizeof(D3DVALUE)); - if (TRACE_ON(ddraw)) { - TRACE(" returning D3DTRANSFORMSTATE_PROJECTION :\n"); - dump_D3DMATRIX(lpD3DMatrix); - } - } break; - - case D3DTRANSFORMSTATE_TEXTURE0: - case D3DTRANSFORMSTATE_TEXTURE1: - case D3DTRANSFORMSTATE_TEXTURE2: - case D3DTRANSFORMSTATE_TEXTURE3: - case D3DTRANSFORMSTATE_TEXTURE4: - case D3DTRANSFORMSTATE_TEXTURE5: - case D3DTRANSFORMSTATE_TEXTURE6: - case D3DTRANSFORMSTATE_TEXTURE7: { - DWORD mat_num = dtstTransformStateType - D3DTRANSFORMSTATE_TEXTURE0; - memcpy(lpD3DMatrix, This->tex_mat[mat_num], 16 * sizeof(D3DVALUE)); - if (TRACE_ON(ddraw)) { - TRACE(" returning D3DTRANSFORMSTATE_TEXTURE%ld :\n", mat_num); - dump_D3DMATRIX(lpD3DMatrix); - } - } break; - - default: - ERR("Unknown transform type %08x !!!\n", dtstTransformStateType); - return DDERR_INVALIDPARAMS; - } - - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_3T_2T_MultiplyTransform(LPDIRECT3DDEVICE7 iface, - D3DTRANSFORMSTATETYPE dtstTransformStateType, - LPD3DMATRIX lpD3DMatrix) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - LPD3DMATRIX mat; - DWORD matrix_changed = 0x00000000; - - TRACE("(%p/%p)->(%08x,%p)\n", This, iface, dtstTransformStateType, lpD3DMatrix); - - if (TRACE_ON(ddraw)) { - TRACE(" Multiplying by :\n"); dump_D3DMATRIX(lpD3DMatrix); - } - - switch (dtstTransformStateType) { - case D3DTRANSFORMSTATE_WORLD: { - if (TRACE_ON(ddraw)) { - TRACE(" Resulting D3DTRANSFORMSTATE_WORLD matrix is :\n"); - } - mat = This->world_mat; - matrix_changed = WORLDMAT_CHANGED; - } break; - - case D3DTRANSFORMSTATE_VIEW: { - if (TRACE_ON(ddraw)) { - TRACE(" Resulting D3DTRANSFORMSTATE_VIEW matrix is :\n"); - } - mat = This->view_mat; - matrix_changed = VIEWMAT_CHANGED; - } break; - - case D3DTRANSFORMSTATE_PROJECTION: { - if (TRACE_ON(ddraw)) { - TRACE(" Resulting D3DTRANSFORMSTATE_PROJECTION matrix is :\n"); - } - mat = This->proj_mat; - matrix_changed = PROJMAT_CHANGED; - } break; - - case D3DTRANSFORMSTATE_TEXTURE0: - case D3DTRANSFORMSTATE_TEXTURE1: - case D3DTRANSFORMSTATE_TEXTURE2: - case D3DTRANSFORMSTATE_TEXTURE3: - case D3DTRANSFORMSTATE_TEXTURE4: - case D3DTRANSFORMSTATE_TEXTURE5: - case D3DTRANSFORMSTATE_TEXTURE6: - case D3DTRANSFORMSTATE_TEXTURE7: { - DWORD mat_num = dtstTransformStateType - D3DTRANSFORMSTATE_TEXTURE0; - if (TRACE_ON(ddraw)) { - TRACE(" Resulting D3DTRANSFORMSTATE_TEXTURE%ld matrix is :\n", mat_num); - } - mat = This->tex_mat[mat_num]; - matrix_changed = TEXMAT0_CHANGED << mat_num; - } break; - - default: - ERR("Unknown transform type %08x !!!\n", dtstTransformStateType); - return DDERR_INVALIDPARAMS; - } - - multiply_matrix(mat,mat,lpD3DMatrix); - - if (TRACE_ON(ddraw)) { - dump_D3DMATRIX(mat); - } - - if (matrix_changed != 0x00000000) This->matrices_updated(This, matrix_changed); - - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_GetViewport(LPDIRECT3DDEVICE7 iface, - LPD3DVIEWPORT7 lpData) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - TRACE("(%p/%p)->(%p)\n", This, iface, lpData); - - *lpData = This->active_viewport; - - if (TRACE_ON(ddraw)) { - TRACE(" returning viewport :\n"); - TRACE(" - dwX = %ld dwY = %ld\n", - lpData->dwX, lpData->dwY); - TRACE(" - dwWidth = %ld dwHeight = %ld\n", - lpData->dwWidth, lpData->dwHeight); - TRACE(" - dvMinZ = %f dvMaxZ = %f\n", - lpData->dvMinZ, lpData->dvMaxZ); - } - - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_SetMaterial(LPDIRECT3DDEVICE7 iface, - LPD3DMATERIAL7 lpMat) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpMat); - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_GetMaterial(LPDIRECT3DDEVICE7 iface, - LPD3DMATERIAL7 lpMat) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - TRACE("(%p/%p)->(%p)\n", This, iface, lpMat); - - *lpMat = This->current_material; - - if (TRACE_ON(ddraw)) { - TRACE(" returning material :\n"); - dump_D3DMATERIAL7(lpMat); - } - - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_SetLight(LPDIRECT3DDEVICE7 iface, - DWORD dwLightIndex, - LPD3DLIGHT7 lpLight) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - FIXME("(%p/%p)->(%08lx,%p): stub!\n", This, iface, dwLightIndex, lpLight); - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_GetLight(LPDIRECT3DDEVICE7 iface, - DWORD dwLightIndex, - LPD3DLIGHT7 lpLight) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - TRACE("(%p/%p)->(%08lx,%p)\n", This, iface, dwLightIndex, lpLight); - - if (dwLightIndex >= This->num_set_lights) - return DDERR_INVALIDPARAMS; - - *lpLight = This->light_parameters[dwLightIndex]; - - /* If dltType is zero, then this light has never been set, either - by calling SetLight or implicitely by calling EnableLight without - calling SetLight first. */ - if (lpLight->dltType == 0) - return DDERR_INVALIDPARAMS; - - if (TRACE_ON(ddraw)) { - TRACE(" returning light :\n"); - dump_D3DLIGHT7(lpLight); - } - - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_3T_2T_SetRenderState(LPDIRECT3DDEVICE7 iface, - D3DRENDERSTATETYPE dwRenderStateType, - DWORD dwRenderState) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - FIXME("(%p/%p)->(%08x,%08lx): stub!\n", This, iface, dwRenderStateType, dwRenderState); - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_3T_2T_GetRenderState(LPDIRECT3DDEVICE7 iface, - D3DRENDERSTATETYPE dwRenderStateType, - LPDWORD lpdwRenderState) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - FIXME("(%p/%p)->(%08x,%p): stub!\n", This, iface, dwRenderStateType, lpdwRenderState); - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_BeginStateBlock(LPDIRECT3DDEVICE7 iface) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - FIXME("(%p/%p)->(): stub!\n", This, iface); - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_EndStateBlock(LPDIRECT3DDEVICE7 iface, - LPDWORD lpdwBlockHandle) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpdwBlockHandle); - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_PreLoad(LPDIRECT3DDEVICE7 iface, - LPDIRECTDRAWSURFACE7 lpddsTexture) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpddsTexture); - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_3T_DrawPrimitive(LPDIRECT3DDEVICE7 iface, - D3DPRIMITIVETYPE d3dptPrimitiveType, - DWORD d3dvtVertexType, - LPVOID lpvVertices, - DWORD dwVertexCount, - DWORD dwFlags) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - FIXME("(%p/%p)->(%08x,%08lx,%p,%08lx,%08lx): stub!\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwFlags); - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitive(LPDIRECT3DDEVICE7 iface, - D3DPRIMITIVETYPE d3dptPrimitiveType, - DWORD d3dvtVertexType, - LPVOID lpvVertices, - DWORD dwVertexCount, - LPWORD dwIndices, - DWORD dwIndexCount, - DWORD dwFlags) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - FIXME("(%p/%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx): stub!\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwIndices, dwIndexCount, dwFlags); - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_3T_2T_SetClipStatus(LPDIRECT3DDEVICE7 iface, - LPD3DCLIPSTATUS lpD3DClipStatus) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpD3DClipStatus); - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_3T_2T_GetClipStatus(LPDIRECT3DDEVICE7 iface, - LPD3DCLIPSTATUS lpD3DClipStatus) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpD3DClipStatus); - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_3T_DrawPrimitiveStrided(LPDIRECT3DDEVICE7 iface, - D3DPRIMITIVETYPE d3dptPrimitiveType, - DWORD dwVertexType, - LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData, - DWORD dwVertexCount, - DWORD dwFlags) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - FIXME("(%p/%p)->(%08x,%08lx,%p,%08lx,%08lx): stub!\n", This, iface, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, dwVertexCount, dwFlags); - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveStrided(LPDIRECT3DDEVICE7 iface, - D3DPRIMITIVETYPE d3dptPrimitiveType, - DWORD dwVertexType, - LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData, - DWORD dwVertexCount, - LPWORD lpIndex, - DWORD dwIndexCount, - DWORD dwFlags) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - FIXME("(%p/%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx): stub!\n", This, iface, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, dwVertexCount, lpIndex, dwIndexCount, dwFlags); - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_3T_DrawPrimitiveVB(LPDIRECT3DDEVICE7 iface, - D3DPRIMITIVETYPE d3dptPrimitiveType, - LPDIRECT3DVERTEXBUFFER7 lpD3DVertexBuf, - DWORD dwStartVertex, - DWORD dwNumVertices, - DWORD dwFlags) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - FIXME("(%p/%p)->(%08x,%p,%08lx,%08lx,%08lx): stub!\n", This, iface, d3dptPrimitiveType, lpD3DVertexBuf, dwStartVertex, dwNumVertices, dwFlags); - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveVB(LPDIRECT3DDEVICE7 iface, - D3DPRIMITIVETYPE d3dptPrimitiveType, - LPDIRECT3DVERTEXBUFFER7 lpD3DVertexBuf, - DWORD dwStartVertex, - DWORD dwNumVertices, - LPWORD lpwIndices, - DWORD dwIndexCount, - DWORD dwFlags) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - FIXME("(%p/%p)->(%08x,%p,%08lx,%08lx,%p,%08lx,%08lx): stub!\n", This, iface, d3dptPrimitiveType, lpD3DVertexBuf, dwStartVertex, dwNumVertices, lpwIndices, dwIndexCount, dwFlags); - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_3T_ComputeSphereVisibility(LPDIRECT3DDEVICE7 iface, - LPD3DVECTOR lpCenters, - LPD3DVALUE lpRadii, - DWORD dwNumSpheres, - DWORD dwFlags, - LPDWORD lpdwReturnValues) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - FIXME("(%p/%p)->(%p,%p,%08lx,%08lx,%p): stub!\n", This, iface, lpCenters, lpRadii, dwNumSpheres, dwFlags, lpdwReturnValues); - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_3T_GetTexture(LPDIRECT3DDEVICE7 iface, - DWORD dwStage, - LPDIRECTDRAWSURFACE7* lpTexture) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - TRACE("(%p/%p)->(%08lx,%p)\n", This, iface, dwStage, lpTexture); - - if (This->current_texture[dwStage] != NULL) { - *lpTexture = ICOM_INTERFACE(This->current_texture[dwStage], IDirectDrawSurface7); - IDirectDrawSurface7_AddRef(*lpTexture); - } else { - *lpTexture = NULL; - } - - TRACE(" returning interface at %p (for implementation at %p).\n", *lpTexture, This->current_texture[dwStage]); - - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_3T_SetTexture(LPDIRECT3DDEVICE7 iface, - DWORD dwStage, - LPDIRECTDRAWSURFACE7 lpTexture) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - FIXME("(%p/%p)->(%08lx,%p): stub!\n", This, iface, dwStage, lpTexture); - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_3T_GetTextureStageState(LPDIRECT3DDEVICE7 iface, - DWORD dwStage, - D3DTEXTURESTAGESTATETYPE d3dTexStageStateType, - LPDWORD lpdwState) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - TRACE("(%p/%p)->(%08lx,%08x,%p)\n", This, iface, dwStage, d3dTexStageStateType, lpdwState); - if (lpdwState && (dwStage < 8) && d3dTexStageStateType && (d3dTexStageStateType <= HIGHEST_TEXTURE_STAGE_STATE) ) { - *lpdwState = This->state_block.texture_stage_state[dwStage][d3dTexStageStateType-1]; - return DD_OK; - } - return DDERR_INVALIDPARAMS; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_3T_SetTextureStageState(LPDIRECT3DDEVICE7 iface, - DWORD dwStage, - D3DTEXTURESTAGESTATETYPE d3dTexStageStateType, - DWORD dwState) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - FIXME("(%p/%p)->(%08lx,%08x,%08lx): stub!\n", This, iface, dwStage, d3dTexStageStateType, dwState); - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_3T_ValidateDevice(LPDIRECT3DDEVICE7 iface, - LPDWORD lpdwPasses) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - FIXME("(%p/%p)->(%p): semi-stub!\n", This, iface, lpdwPasses); - - /* For the moment, we have a VERY good hardware which does everything in one pass :-) */ - *lpdwPasses = 1; - - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_ApplyStateBlock(LPDIRECT3DDEVICE7 iface, - DWORD dwBlockHandle) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - FIXME("(%p/%p)->(%08lx): stub!\n", This, iface, dwBlockHandle); - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_CaptureStateBlock(LPDIRECT3DDEVICE7 iface, - DWORD dwBlockHandle) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - FIXME("(%p/%p)->(%08lx): stub!\n", This, iface, dwBlockHandle); - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_DeleteStateBlock(LPDIRECT3DDEVICE7 iface, - DWORD dwBlockHandle) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - FIXME("(%p/%p)->(%08lx): stub!\n", This, iface, dwBlockHandle); - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_CreateStateBlock(LPDIRECT3DDEVICE7 iface, - D3DSTATEBLOCKTYPE d3dsbType, - LPDWORD lpdwBlockHandle) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - FIXME("(%p/%p)->(%08x,%p): stub!\n", This, iface, d3dsbType, lpdwBlockHandle); - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_Load(LPDIRECT3DDEVICE7 iface, - LPDIRECTDRAWSURFACE7 lpDestTex, - LPPOINT lpDestPoint, - LPDIRECTDRAWSURFACE7 lpSrcTex, - LPRECT lprcSrcRect, - DWORD dwFlags) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - FIXME("(%p/%p)->(%p,%p,%p,%p,%08lx): Partially Implemented!\n", This, iface, lpDestTex, lpDestPoint, lpSrcTex, lprcSrcRect, dwFlags); - IDirect3DTexture2_Load(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7, IDirect3DTexture2, lpDestTex), - COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7, IDirect3DTexture2, lpSrcTex)); - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_LightEnable(LPDIRECT3DDEVICE7 iface, - DWORD dwLightIndex, - BOOL bEnable) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - FIXME("(%p/%p)->(%08lx,%d): stub!\n", This, iface, dwLightIndex, bEnable); - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_GetLightEnable(LPDIRECT3DDEVICE7 iface, - DWORD dwLightIndex, - BOOL* pbEnable) -{ - int i; - - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - TRACE("(%p/%p)->(%08lx,%p)\n", This, iface, dwLightIndex, pbEnable); - - *pbEnable = 0; - if (dwLightIndex >= This->num_set_lights) - return DDERR_INVALIDPARAMS; - - /* If dltType is zero, then this light has never been set, either - by calling SetLight or implicitely by calling EnableLight without - calling SetLight first. */ - if (This->light_parameters[dwLightIndex].dltType == 0) - return DDERR_INVALIDPARAMS; - - for (i = 0; i < This->max_active_lights; i++) - if (This->active_lights[i] == dwLightIndex) - *pbEnable = TRUE; - - TRACE(" returning %d.\n", *pbEnable); - - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_SetClipPlane(LPDIRECT3DDEVICE7 iface, - DWORD dwIndex, - D3DVALUE* pPlaneEquation) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - FIXME("(%p/%p)->(%08lx,%p): stub!\n", This, iface, dwIndex, pPlaneEquation); - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_GetClipPlane(LPDIRECT3DDEVICE7 iface, DWORD dwIndex, D3DVALUE* pPlaneEquation) -{ - IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface; - - TRACE("(%p)->(%ld,%p)\n", This, dwIndex, pPlaneEquation); - - if (dwIndex>=This->max_clipping_planes) { - return DDERR_INVALIDPARAMS; - } - - memcpy( pPlaneEquation, This->clipping_planes[dwIndex].plane, sizeof(D3DVALUE[4])); - - return D3D_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_7_GetInfo(LPDIRECT3DDEVICE7 iface, - DWORD dwDevInfoID, - LPVOID pDevInfoStruct, - DWORD dwSize) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - TRACE("(%p/%p)->(%08lx,%p,%08lx)\n", This, iface, dwDevInfoID, pDevInfoStruct, dwSize); - - if (TRACE_ON(ddraw)) { - TRACE(" info requested : "); - switch (dwDevInfoID) { - case D3DDEVINFOID_TEXTUREMANAGER: TRACE("D3DDEVINFOID_TEXTUREMANAGER\n"); break; - case D3DDEVINFOID_D3DTEXTUREMANAGER: TRACE("D3DDEVINFOID_D3DTEXTUREMANAGER\n"); break; - case D3DDEVINFOID_TEXTURING: TRACE("D3DDEVINFOID_TEXTURING\n"); break; - default: ERR(" invalid flag !!!\n"); return DDERR_INVALIDPARAMS; - } - } - - return S_FALSE; /* According to MSDN, this is valid for a non-debug driver */ -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_3_2T_1T_GetCaps(LPDIRECT3DDEVICE3 iface, - LPD3DDEVICEDESC lpD3DHWDevDesc, - LPD3DDEVICEDESC lpD3DHELDevDesc) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); - FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lpD3DHWDevDesc, lpD3DHELDevDesc); - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_3_2T_1T_GetStats(LPDIRECT3DDEVICE3 iface, - LPD3DSTATS lpD3DStats) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); - FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpD3DStats); - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_3_2T_1T_AddViewport(LPDIRECT3DDEVICE3 iface, - LPDIRECT3DVIEWPORT3 lpDirect3DViewport3) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); - IDirect3DViewportImpl *lpDirect3DViewportImpl = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, lpDirect3DViewport3); - - TRACE("(%p/%p)->(%p)\n", This, iface, lpDirect3DViewport3); - - lpDirect3DViewportImpl->next = This->viewport_list; - This->viewport_list = lpDirect3DViewportImpl; - - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_3_2T_1T_DeleteViewport(LPDIRECT3DDEVICE3 iface, - LPDIRECT3DVIEWPORT3 lpDirect3DViewport3) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); - IDirect3DViewportImpl *lpDirect3DViewportImpl = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, lpDirect3DViewport3); - IDirect3DViewportImpl *cur_viewport, *prev_viewport = NULL; - - TRACE("(%p/%p)->(%p)\n", This, iface, lpDirect3DViewport3); - - cur_viewport = This->viewport_list; - while (cur_viewport != NULL) { - if (cur_viewport == lpDirect3DViewportImpl) { - if (prev_viewport == NULL) This->viewport_list = cur_viewport->next; - else prev_viewport->next = cur_viewport->next; - /* TODO : add desactivate of the viewport and all associated lights... */ - return DD_OK; - } - prev_viewport = cur_viewport; - cur_viewport = cur_viewport->next; - } - - return DDERR_INVALIDPARAMS; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_3_2T_1T_NextViewport(LPDIRECT3DDEVICE3 iface, - LPDIRECT3DVIEWPORT3 lpDirect3DViewport3, - LPDIRECT3DVIEWPORT3* lplpDirect3DViewport3, - DWORD dwFlags) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); - IDirect3DViewportImpl *res = NULL; - - TRACE("(%p/%p)->(%p,%p,%08lx)\n", This, iface, lpDirect3DViewport3, lplpDirect3DViewport3, dwFlags); - - switch (dwFlags) { - case D3DNEXT_NEXT: { - IDirect3DViewportImpl *lpDirect3DViewportImpl = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, lpDirect3DViewport3); - res = lpDirect3DViewportImpl->next; - } break; - case D3DNEXT_HEAD: { - res = This->viewport_list; - } break; - case D3DNEXT_TAIL: { - IDirect3DViewportImpl *cur_viewport = This->viewport_list; - if (cur_viewport != NULL) { - while (cur_viewport->next != NULL) cur_viewport = cur_viewport->next; - } - res = cur_viewport; - } break; - default: - *lplpDirect3DViewport3 = NULL; - return DDERR_INVALIDPARAMS; - } - *lplpDirect3DViewport3 = ICOM_INTERFACE(res, IDirect3DViewport3); - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_3_2T_SetCurrentViewport(LPDIRECT3DDEVICE3 iface, - LPDIRECT3DVIEWPORT3 lpDirect3DViewport3) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); - TRACE("(%p/%p)->(%p)\n", This, iface, lpDirect3DViewport3); - - /* Do nothing if the specified viewport is the same as the current one */ - if (This->current_viewport == ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, lpDirect3DViewport3)) - return DD_OK; - - /* Should check if the viewport was added or not */ - - /* Release previous viewport and AddRef the new one */ - if (This->current_viewport) - IDirect3DViewport3_Release(ICOM_INTERFACE(This->current_viewport, IDirect3DViewport3)); - IDirect3DViewport3_AddRef(lpDirect3DViewport3); - - /* Set this viewport as the current viewport */ - This->current_viewport = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, lpDirect3DViewport3); - - /* Activate this viewport */ - This->current_viewport->active_device = This; - This->current_viewport->activate(This->current_viewport); - - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_3_2T_GetCurrentViewport(LPDIRECT3DDEVICE3 iface, - LPDIRECT3DVIEWPORT3* lplpDirect3DViewport3) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); - TRACE("(%p/%p)->(%p)\n", This, iface, lplpDirect3DViewport3); - - *lplpDirect3DViewport3 = ICOM_INTERFACE(This->current_viewport, IDirect3DViewport3); - - /* AddRef the returned viewport */ - IDirect3DViewport3_AddRef(*lplpDirect3DViewport3); - - TRACE(" returning interface %p\n", *lplpDirect3DViewport3); - - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_3_Begin(LPDIRECT3DDEVICE3 iface, - D3DPRIMITIVETYPE d3dptPrimitiveType, - DWORD dwVertexTypeDesc, - DWORD dwFlags) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); - TRACE("(%p/%p)->(%08x,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, dwVertexTypeDesc, dwFlags); - - This->primitive_type = d3dptPrimitiveType; - This->vertex_type = dwVertexTypeDesc; - This->render_flags = dwFlags; - This->vertex_size = get_flexible_vertex_size(This->vertex_type); - This->nb_vertices = 0; - - return D3D_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_3_BeginIndexed(LPDIRECT3DDEVICE3 iface, - D3DPRIMITIVETYPE d3dptPrimitiveType, - DWORD d3dvtVertexType, - LPVOID lpvVertices, - DWORD dwNumVertices, - DWORD dwFlags) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); - FIXME("(%p/%p)->(%08x,%08lx,%p,%08lx,%08lx): stub!\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwNumVertices, dwFlags); - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_3_2T_Vertex(LPDIRECT3DDEVICE3 iface, - LPVOID lpVertexType) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); - TRACE("(%p/%p)->(%p)\n", This, iface, lpVertexType); - - if ((This->nb_vertices+1)*This->vertex_size > This->buffer_size) - { - LPBYTE old_buffer; - This->buffer_size = This->buffer_size ? This->buffer_size * 2 : This->vertex_size * 3; - old_buffer = This->vertex_buffer; - This->vertex_buffer = HeapAlloc(GetProcessHeap(), 0, This->buffer_size); - if (old_buffer) - { - CopyMemory(This->vertex_buffer, old_buffer, This->nb_vertices * This->vertex_size); - HeapFree(GetProcessHeap(), 0, old_buffer); - } - } - - CopyMemory(This->vertex_buffer + This->nb_vertices++ * This->vertex_size, lpVertexType, This->vertex_size); - - return D3D_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_3_2T_Index(LPDIRECT3DDEVICE3 iface, - WORD wVertexIndex) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); - FIXME("(%p/%p)->(%04x): stub!\n", This, iface, wVertexIndex); - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_3_2T_End(LPDIRECT3DDEVICE3 iface, - DWORD dwFlags) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); - TRACE("(%p/%p)->(%08lx)\n", This, iface, dwFlags); - - IDirect3DDevice3_DrawPrimitive(iface, This->primitive_type, This->vertex_type, This->vertex_buffer, This->nb_vertices, This->render_flags); - - return D3D_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_3_2T_GetLightState(LPDIRECT3DDEVICE3 iface, - D3DLIGHTSTATETYPE dwLightStateType, - LPDWORD lpdwLightState) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); - FIXME("(%p/%p)->(%08x,%p): stub !\n", This, iface, dwLightStateType, lpdwLightState); - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_3_2T_SetLightState(LPDIRECT3DDEVICE3 iface, - D3DLIGHTSTATETYPE dwLightStateType, - DWORD dwLightState) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); - FIXME("(%p/%p)->(%08x,%08lx): stub!\n", This, iface, dwLightStateType, dwLightState); - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_2_1T_SwapTextureHandles(LPDIRECT3DDEVICE2 iface, - LPDIRECT3DTEXTURE2 lpD3DTex1, - LPDIRECT3DTEXTURE2 lpD3DTex2) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface); - IDirectDrawSurfaceImpl tmp,*surf1,*surf2; - TRACE("(%p/%p)->(%p,%p):\n", This, iface, lpD3DTex1, lpD3DTex2); - - surf1 = ICOM_OBJECT(IDirectDrawSurfaceImpl,IDirect3DTexture2,lpD3DTex1); - surf2 = ICOM_OBJECT(IDirectDrawSurfaceImpl,IDirect3DTexture2,lpD3DTex2); - tmp = *surf1; - *surf1 = *surf2; - *surf2 = tmp; - - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_2_NextViewport(LPDIRECT3DDEVICE2 iface, - LPDIRECT3DVIEWPORT2 lpDirect3DViewport2, - LPDIRECT3DVIEWPORT2* lplpDirect3DViewport2, - DWORD dwFlags) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface); - FIXME("(%p/%p)->(%p,%p,%08lx): stub!\n", This, iface, lpDirect3DViewport2, lplpDirect3DViewport2, dwFlags); - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_2_1T_EnumTextureFormats(LPDIRECT3DDEVICE2 iface, - LPD3DENUMTEXTUREFORMATSCALLBACK lpD3DEnumTextureProc, - LPVOID lpArg) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface); - FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lpD3DEnumTextureProc, lpArg); - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_2_Begin(LPDIRECT3DDEVICE2 iface, - D3DPRIMITIVETYPE d3dpt, - D3DVERTEXTYPE dwVertexTypeDesc, - DWORD dwFlags) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface); - FIXME("(%p/%p)->(%08x,%08x,%08lx): stub!\n", This, iface, d3dpt, dwVertexTypeDesc, dwFlags); - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_2_BeginIndexed(LPDIRECT3DDEVICE2 iface, - D3DPRIMITIVETYPE d3dptPrimitiveType, - D3DVERTEXTYPE d3dvtVertexType, - LPVOID lpvVertices, - DWORD dwNumVertices, - DWORD dwFlags) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface); - FIXME("(%p/%p)->(%08x,%08x,%p,%08lx,%08lx): stub!\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwNumVertices, dwFlags); - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_2_DrawPrimitive(LPDIRECT3DDEVICE2 iface, - D3DPRIMITIVETYPE d3dptPrimitiveType, - D3DVERTEXTYPE d3dvtVertexType, - LPVOID lpvVertices, - DWORD dwVertexCount, - DWORD dwFlags) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface); - FIXME("(%p/%p)->(%08x,%08x,%p,%08lx,%08lx): stub!\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwFlags); - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_2_DrawIndexedPrimitive(LPDIRECT3DDEVICE2 iface, - D3DPRIMITIVETYPE d3dptPrimitiveType, - D3DVERTEXTYPE d3dvtVertexType, - LPVOID lpvVertices, - DWORD dwVertexCount, - LPWORD dwIndices, - DWORD dwIndexCount, - DWORD dwFlags) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface); - FIXME("(%p/%p)->(%08x,%08x,%p,%08lx,%p,%08lx,%08lx): stub!\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwIndices, dwIndexCount, dwFlags); - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_1_Initialize(LPDIRECT3DDEVICE iface, - LPDIRECT3D lpDirect3D, - LPGUID lpGUID, - LPD3DDEVICEDESC lpD3DDVDesc) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface); - FIXME("(%p/%p)->(%p,%p,%p): stub!\n", This, iface, lpDirect3D, lpGUID, lpD3DDVDesc); - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_1_CreateExecuteBuffer(LPDIRECT3DDEVICE iface, - LPD3DEXECUTEBUFFERDESC lpDesc, - LPDIRECT3DEXECUTEBUFFER* lplpDirect3DExecuteBuffer, - IUnknown* pUnkOuter) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface); - FIXME("(%p/%p)->(%p,%p,%p): stub!\n", This, iface, lpDesc, lplpDirect3DExecuteBuffer, pUnkOuter); - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_1_Execute(LPDIRECT3DDEVICE iface, - LPDIRECT3DEXECUTEBUFFER lpDirect3DExecuteBuffer, - LPDIRECT3DVIEWPORT lpDirect3DViewport, - DWORD dwFlags) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface); - IDirect3DExecuteBufferImpl *lpDirect3DExecuteBufferImpl = ICOM_OBJECT(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, lpDirect3DExecuteBuffer); - IDirect3DViewportImpl *lpDirect3DViewportImpl = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, lpDirect3DViewport); - - TRACE("(%p/%p)->(%p,%p,%08lx)\n", This, iface, lpDirect3DExecuteBuffer, lpDirect3DViewport, dwFlags); - - /* Put this as the default context */ - - /* Execute... */ - lpDirect3DExecuteBufferImpl->execute(lpDirect3DExecuteBufferImpl, This, lpDirect3DViewportImpl); - - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_1_NextViewport(LPDIRECT3DDEVICE iface, - LPDIRECT3DVIEWPORT lpDirect3DViewport, - LPDIRECT3DVIEWPORT* lplpDirect3DViewport, - DWORD dwFlags) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface); - FIXME("(%p/%p)->(%p,%p,%08lx): stub!\n", This, iface, lpDirect3DViewport, lplpDirect3DViewport, dwFlags); - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_1_Pick(LPDIRECT3DDEVICE iface, - LPDIRECT3DEXECUTEBUFFER lpDirect3DExecuteBuffer, - LPDIRECT3DVIEWPORT lpDirect3DViewport, - DWORD dwFlags, - LPD3DRECT lpRect) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface); - FIXME("(%p/%p)->(%p,%p,%08lx,%p): stub!\n", This, iface, lpDirect3DExecuteBuffer, lpDirect3DViewport, dwFlags, lpRect); - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_1_GetPickRecords(LPDIRECT3DDEVICE iface, - LPDWORD lpCount, - LPD3DPICKRECORD lpD3DPickRec) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface); - FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lpCount, lpD3DPickRec); - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_1_CreateMatrix(LPDIRECT3DDEVICE iface, - LPD3DMATRIXHANDLE lpD3DMatHandle) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface); - TRACE("(%p/%p)->(%p)\n", This, iface, lpD3DMatHandle); - - *lpD3DMatHandle = (D3DMATRIXHANDLE) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(D3DMATRIX)); - TRACE(" returning matrix handle %p\n", (void *) *lpD3DMatHandle); - - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_1_SetMatrix(LPDIRECT3DDEVICE iface, - D3DMATRIXHANDLE D3DMatHandle, - LPD3DMATRIX lpD3DMatrix) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface); - TRACE("(%p/%p)->(%08lx,%p)\n", This, iface, (DWORD) D3DMatHandle, lpD3DMatrix); - - if (TRACE_ON(ddraw)) { - dump_D3DMATRIX(lpD3DMatrix); - } - *((D3DMATRIX *) D3DMatHandle) = *lpD3DMatrix; - - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_1_GetMatrix(LPDIRECT3DDEVICE iface, - D3DMATRIXHANDLE D3DMatHandle, - LPD3DMATRIX lpD3DMatrix) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface); - TRACE("(%p/%p)->(%08lx,%p)\n", This, iface, (DWORD) D3DMatHandle, lpD3DMatrix); - - *lpD3DMatrix = *((D3DMATRIX *) D3DMatHandle); - - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DDeviceImpl_1_DeleteMatrix(LPDIRECT3DDEVICE iface, - D3DMATRIXHANDLE D3DMatHandle) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface); - TRACE("(%p/%p)->(%08lx)\n", This, iface, (DWORD) D3DMatHandle); - - HeapFree(GetProcessHeap(), 0, (void *) D3DMatHandle); - - return DD_OK; -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_3_QueryInterface(LPDIRECT3DDEVICE3 iface, - REFIID riid, - LPVOID* obp) -{ - TRACE("(%p)->(%s,%p) thunking to IDirect3DDevice7 interface.\n", iface, debugstr_guid(riid), obp); - return IDirect3DDevice7_QueryInterface(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface), - riid, - obp); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_2_QueryInterface(LPDIRECT3DDEVICE2 iface, - REFIID riid, - LPVOID* obp) -{ - TRACE("(%p)->(%s,%p) thunking to IDirect3DDevice7 interface.\n", iface, debugstr_guid(riid), obp); - return IDirect3DDevice7_QueryInterface(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice7, iface), - riid, - obp); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_1_QueryInterface(LPDIRECT3DDEVICE iface, - REFIID riid, - LPVOID* obp) -{ - TRACE("(%p)->(%s,%p) thunking to IDirect3DDevice7 interface.\n", iface, debugstr_guid(riid), obp); - return IDirect3DDevice7_QueryInterface(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice7, iface), - riid, - obp); -} - -ULONG WINAPI -Thunk_IDirect3DDeviceImpl_3_AddRef(LPDIRECT3DDEVICE3 iface) -{ - TRACE("(%p)->() thunking to IDirect3DDevice7 interface.\n", iface); - return IDirect3DDevice7_AddRef(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface)); -} - -ULONG WINAPI -Thunk_IDirect3DDeviceImpl_2_AddRef(LPDIRECT3DDEVICE2 iface) -{ - TRACE("(%p)->() thunking to IDirect3DDevice7 interface.\n", iface); - return IDirect3DDevice7_AddRef(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice7, iface)); -} - -ULONG WINAPI -Thunk_IDirect3DDeviceImpl_1_AddRef(LPDIRECT3DDEVICE iface) -{ - TRACE("(%p)->() thunking to IDirect3DDevice7 interface.\n", iface); - return IDirect3DDevice7_AddRef(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice7, iface)); -} - -ULONG WINAPI -Thunk_IDirect3DDeviceImpl_3_Release(LPDIRECT3DDEVICE3 iface) -{ - TRACE("(%p)->() thunking to IDirect3DDevice7 interface.\n", iface); - return IDirect3DDevice7_Release(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface)); -} - -ULONG WINAPI -Thunk_IDirect3DDeviceImpl_2_Release(LPDIRECT3DDEVICE2 iface) -{ - TRACE("(%p)->() thunking to IDirect3DDevice7 interface.\n", iface); - return IDirect3DDevice7_Release(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice7, iface)); -} - -ULONG WINAPI -Thunk_IDirect3DDeviceImpl_1_Release(LPDIRECT3DDEVICE iface) -{ - TRACE("(%p)->() thunking to IDirect3DDevice7 interface.\n", iface); - return IDirect3DDevice7_Release(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice7, iface)); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_2_AddViewport(LPDIRECT3DDEVICE2 iface, - LPDIRECT3DVIEWPORT2 lpDirect3DViewport2) -{ - TRACE("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", iface, lpDirect3DViewport2); - return IDirect3DDevice3_AddViewport(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice3, iface), - (LPDIRECT3DVIEWPORT3) lpDirect3DViewport2 /* No need to cast here as all interfaces are equivalent */); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_1_AddViewport(LPDIRECT3DDEVICE iface, - LPDIRECT3DVIEWPORT lpDirect3DViewport) -{ - TRACE("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", iface, lpDirect3DViewport); - return IDirect3DDevice3_AddViewport(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice3, iface), - (LPDIRECT3DVIEWPORT3) lpDirect3DViewport /* No need to cast here as all interfaces are equivalent */); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_2_DeleteViewport(LPDIRECT3DDEVICE2 iface, - LPDIRECT3DVIEWPORT2 lpDirect3DViewport2) -{ - TRACE("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", iface, lpDirect3DViewport2); - return IDirect3DDevice3_DeleteViewport(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice3, iface), - (LPDIRECT3DVIEWPORT3) lpDirect3DViewport2 /* No need to cast here as all interfaces are equivalent */); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_1_DeleteViewport(LPDIRECT3DDEVICE iface, - LPDIRECT3DVIEWPORT lpDirect3DViewport) -{ - TRACE("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", iface, lpDirect3DViewport); - return IDirect3DDevice3_DeleteViewport(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice3, iface), - (LPDIRECT3DVIEWPORT3) lpDirect3DViewport /* No need to cast here as all interfaces are equivalent */); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_2_NextViewport(LPDIRECT3DDEVICE2 iface, - LPDIRECT3DVIEWPORT2 lpDirect3DViewport2, - LPDIRECT3DVIEWPORT2* lplpDirect3DViewport2, - DWORD dwFlags) -{ - TRACE("(%p)->(%p,%p,%08lx) thunking to IDirect3DDevice3 interface.\n", iface, lpDirect3DViewport2, lplpDirect3DViewport2, dwFlags); - return IDirect3DDevice3_NextViewport(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice3, iface), - (LPDIRECT3DVIEWPORT3) lpDirect3DViewport2 /* No need to cast here as all interfaces are equivalent */, - (LPDIRECT3DVIEWPORT3*) lplpDirect3DViewport2, - dwFlags); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_1_NextViewport(LPDIRECT3DDEVICE iface, - LPDIRECT3DVIEWPORT lpDirect3DViewport, - LPDIRECT3DVIEWPORT* lplpDirect3DViewport, - DWORD dwFlags) -{ - TRACE("(%p)->(%p,%p,%08lx) thunking to IDirect3DDevice3 interface.\n", iface, lpDirect3DViewport, lplpDirect3DViewport, dwFlags); - return IDirect3DDevice3_NextViewport(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice3, iface), - (LPDIRECT3DVIEWPORT3) lpDirect3DViewport /* No need to cast here as all interfaces are equivalent */, - (LPDIRECT3DVIEWPORT3*) lplpDirect3DViewport, - dwFlags); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_3_GetDirect3D(LPDIRECT3DDEVICE3 iface, - LPDIRECT3D3* lplpDirect3D3) -{ - HRESULT ret; - LPDIRECT3D7 ret_ptr; - - TRACE("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", iface, lplpDirect3D3); - ret = IDirect3DDevice7_GetDirect3D(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface), - &ret_ptr); - *lplpDirect3D3 = COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D7, IDirect3D3, ret_ptr); - TRACE(" returning interface %p\n", *lplpDirect3D3); - return ret; -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_2_GetDirect3D(LPDIRECT3DDEVICE2 iface, - LPDIRECT3D2* lplpDirect3D2) -{ - HRESULT ret; - LPDIRECT3D7 ret_ptr; - - TRACE("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", iface, lplpDirect3D2); - ret = IDirect3DDevice7_GetDirect3D(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice7, iface), - &ret_ptr); - *lplpDirect3D2 = COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D7, IDirect3D2, ret_ptr); - TRACE(" returning interface %p\n", *lplpDirect3D2); - return ret; -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_1_GetDirect3D(LPDIRECT3DDEVICE iface, - LPDIRECT3D* lplpDirect3D) -{ - HRESULT ret; - LPDIRECT3D7 ret_ptr; - - TRACE("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", iface, lplpDirect3D); - ret = IDirect3DDevice7_GetDirect3D(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice7, iface), - &ret_ptr); - *lplpDirect3D = COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D7, IDirect3D, ret_ptr); - TRACE(" returning interface %p\n", *lplpDirect3D); - return ret; -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport(LPDIRECT3DDEVICE2 iface, - LPDIRECT3DVIEWPORT2 lpDirect3DViewport2) -{ - TRACE("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", iface, lpDirect3DViewport2); - return IDirect3DDevice3_SetCurrentViewport(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice3, iface), - (LPDIRECT3DVIEWPORT3) lpDirect3DViewport2 /* No need to cast here as all interfaces are equivalent */); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport(LPDIRECT3DDEVICE2 iface, - LPDIRECT3DVIEWPORT2* lplpDirect3DViewport2) -{ - TRACE("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", iface, lplpDirect3DViewport2); - return IDirect3DDevice3_GetCurrentViewport(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice3, iface), - (LPDIRECT3DVIEWPORT3*) lplpDirect3DViewport2 /* No need to cast here as all interfaces are equivalent */); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats(LPDIRECT3DDEVICE3 iface, - LPD3DENUMPIXELFORMATSCALLBACK lpD3DEnumPixelProc, - LPVOID lpArg) -{ - TRACE("(%p)->(%p,%p) thunking to IDirect3DDevice7 interface.\n", iface, lpD3DEnumPixelProc, lpArg); - return IDirect3DDevice7_EnumTextureFormats(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface), - lpD3DEnumPixelProc, - lpArg); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_3_BeginScene(LPDIRECT3DDEVICE3 iface) -{ - TRACE("(%p)->() thunking to IDirect3DDevice7 interface.\n", iface); - return IDirect3DDevice7_BeginScene(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface)); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_2_BeginScene(LPDIRECT3DDEVICE2 iface) -{ - TRACE("(%p)->() thunking to IDirect3DDevice7 interface.\n", iface); - return IDirect3DDevice7_BeginScene(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice7, iface)); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_1_BeginScene(LPDIRECT3DDEVICE iface) -{ - TRACE("(%p)->() thunking to IDirect3DDevice7 interface.\n", iface); - return IDirect3DDevice7_BeginScene(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice7, iface)); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_3_EndScene(LPDIRECT3DDEVICE3 iface) -{ - TRACE("(%p)->() thunking to IDirect3DDevice7 interface.\n", iface); - return IDirect3DDevice7_EndScene(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface)); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_2_EndScene(LPDIRECT3DDEVICE2 iface) -{ - TRACE("(%p)->() thunking to IDirect3DDevice7 interface.\n", iface); - return IDirect3DDevice7_EndScene(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice7, iface)); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_1_EndScene(LPDIRECT3DDEVICE iface) -{ - TRACE("(%p)->() thunking to IDirect3DDevice7 interface.\n", iface); - return IDirect3DDevice7_EndScene(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice7, iface)); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_3_SetTransform(LPDIRECT3DDEVICE3 iface, - D3DTRANSFORMSTATETYPE dtstTransformStateType, - LPD3DMATRIX lpD3DMatrix) -{ - TRACE("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", iface, dtstTransformStateType, lpD3DMatrix); - return IDirect3DDevice7_SetTransform(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface), - dtstTransformStateType, - lpD3DMatrix); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_2_SetTransform(LPDIRECT3DDEVICE2 iface, - D3DTRANSFORMSTATETYPE dtstTransformStateType, - LPD3DMATRIX lpD3DMatrix) -{ - TRACE("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", iface, dtstTransformStateType, lpD3DMatrix); - return IDirect3DDevice7_SetTransform(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice7, iface), - dtstTransformStateType, - lpD3DMatrix); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_3_GetTransform(LPDIRECT3DDEVICE3 iface, - D3DTRANSFORMSTATETYPE dtstTransformStateType, - LPD3DMATRIX lpD3DMatrix) -{ - TRACE("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", iface, dtstTransformStateType, lpD3DMatrix); - return IDirect3DDevice7_GetTransform(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface), - dtstTransformStateType, - lpD3DMatrix); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_2_GetTransform(LPDIRECT3DDEVICE2 iface, - D3DTRANSFORMSTATETYPE dtstTransformStateType, - LPD3DMATRIX lpD3DMatrix) -{ - TRACE("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", iface, dtstTransformStateType, lpD3DMatrix); - return IDirect3DDevice7_GetTransform(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice7, iface), - dtstTransformStateType, - lpD3DMatrix); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_3_MultiplyTransform(LPDIRECT3DDEVICE3 iface, - D3DTRANSFORMSTATETYPE dtstTransformStateType, - LPD3DMATRIX lpD3DMatrix) -{ - TRACE("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", iface, dtstTransformStateType, lpD3DMatrix); - return IDirect3DDevice7_MultiplyTransform(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface), - dtstTransformStateType, - lpD3DMatrix); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_2_MultiplyTransform(LPDIRECT3DDEVICE2 iface, - D3DTRANSFORMSTATETYPE dtstTransformStateType, - LPD3DMATRIX lpD3DMatrix) -{ - TRACE("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", iface, dtstTransformStateType, lpD3DMatrix); - return IDirect3DDevice7_MultiplyTransform(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice7, iface), - dtstTransformStateType, - lpD3DMatrix); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_3_SetRenderState(LPDIRECT3DDEVICE3 iface, - D3DRENDERSTATETYPE dwRenderStateType, - DWORD dwRenderState) -{ - TRACE("(%p)->(%08x,%08lx) thunking to IDirect3DDevice7 interface.\n", iface, dwRenderStateType, dwRenderState); - return IDirect3DDevice7_SetRenderState(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface), - dwRenderStateType, - dwRenderState); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_2_SetRenderState(LPDIRECT3DDEVICE2 iface, - D3DRENDERSTATETYPE dwRenderStateType, - DWORD dwRenderState) -{ - TRACE("(%p)->(%08x,%08lx) thunking to IDirect3DDevice7 interface.\n", iface, dwRenderStateType, dwRenderState); - return IDirect3DDevice7_SetRenderState(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice7, iface), - dwRenderStateType, - dwRenderState); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_3_GetRenderState(LPDIRECT3DDEVICE3 iface, - D3DRENDERSTATETYPE dwRenderStateType, - LPDWORD lpdwRenderState) -{ - TRACE("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", iface, dwRenderStateType, lpdwRenderState); - return IDirect3DDevice7_GetRenderState(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface), - dwRenderStateType, - lpdwRenderState); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_2_GetRenderState(LPDIRECT3DDEVICE2 iface, - D3DRENDERSTATETYPE dwRenderStateType, - LPDWORD lpdwRenderState) -{ - TRACE("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", iface, dwRenderStateType, lpdwRenderState); - return IDirect3DDevice7_GetRenderState(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice7, iface), - dwRenderStateType, - lpdwRenderState); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_3_DrawPrimitive(LPDIRECT3DDEVICE3 iface, - D3DPRIMITIVETYPE d3dptPrimitiveType, - DWORD d3dvtVertexType, - LPVOID lpvVertices, - DWORD dwVertexCount, - DWORD dwFlags) -{ - TRACE("(%p)->(%08x,%08lx,%p,%08lx,%08lx) thunking to IDirect3DDevice7 interface.\n", iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwFlags); - return IDirect3DDevice7_DrawPrimitive(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface), - d3dptPrimitiveType, - d3dvtVertexType, - lpvVertices, - dwVertexCount, - dwFlags); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive(LPDIRECT3DDEVICE3 iface, - D3DPRIMITIVETYPE d3dptPrimitiveType, - DWORD d3dvtVertexType, - LPVOID lpvVertices, - DWORD dwVertexCount, - LPWORD dwIndices, - DWORD dwIndexCount, - DWORD dwFlags) -{ - TRACE("(%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx) thunking to IDirect3DDevice7 interface.\n", iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwIndices, dwIndexCount, dwFlags); - return IDirect3DDevice7_DrawIndexedPrimitive(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface), - d3dptPrimitiveType, - d3dvtVertexType, - lpvVertices, - dwVertexCount, - dwIndices, - dwIndexCount, - dwFlags); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_3_SetClipStatus(LPDIRECT3DDEVICE3 iface, - LPD3DCLIPSTATUS lpD3DClipStatus) -{ - TRACE("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", iface, lpD3DClipStatus); - return IDirect3DDevice7_SetClipStatus(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface), - lpD3DClipStatus); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_2_SetClipStatus(LPDIRECT3DDEVICE2 iface, - LPD3DCLIPSTATUS lpD3DClipStatus) -{ - TRACE("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", iface, lpD3DClipStatus); - return IDirect3DDevice7_SetClipStatus(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice7, iface), - lpD3DClipStatus); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_3_GetClipStatus(LPDIRECT3DDEVICE3 iface, - LPD3DCLIPSTATUS lpD3DClipStatus) -{ - TRACE("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", iface, lpD3DClipStatus); - return IDirect3DDevice7_GetClipStatus(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface), - lpD3DClipStatus); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_2_GetClipStatus(LPDIRECT3DDEVICE2 iface, - LPD3DCLIPSTATUS lpD3DClipStatus) -{ - TRACE("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", iface, lpD3DClipStatus); - return IDirect3DDevice7_GetClipStatus(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice7, iface), - lpD3DClipStatus); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided(LPDIRECT3DDEVICE3 iface, - D3DPRIMITIVETYPE d3dptPrimitiveType, - DWORD dwVertexType, - LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData, - DWORD dwVertexCount, - DWORD dwFlags) -{ - TRACE("(%p)->(%08x,%08lx,%p,%08lx,%08lx) thunking to IDirect3DDevice7 interface.\n", iface, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, dwVertexCount, dwFlags); - return IDirect3DDevice7_DrawPrimitiveStrided(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface), - d3dptPrimitiveType, - dwVertexType, - lpD3DDrawPrimStrideData, - dwVertexCount, - dwFlags); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided(LPDIRECT3DDEVICE3 iface, - D3DPRIMITIVETYPE d3dptPrimitiveType, - DWORD dwVertexType, - LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData, - DWORD dwVertexCount, - LPWORD lpIndex, - DWORD dwIndexCount, - DWORD dwFlags) -{ - TRACE("(%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx) thunking to IDirect3DDevice7 interface.\n", iface, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, dwVertexCount, lpIndex, dwIndexCount, dwFlags); - return IDirect3DDevice7_DrawIndexedPrimitiveStrided(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface), - d3dptPrimitiveType, - dwVertexType, - lpD3DDrawPrimStrideData, - dwVertexCount, - lpIndex, - dwIndexCount, - dwFlags); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility(LPDIRECT3DDEVICE3 iface, - LPD3DVECTOR lpCenters, - LPD3DVALUE lpRadii, - DWORD dwNumSpheres, - DWORD dwFlags, - LPDWORD lpdwReturnValues) -{ - TRACE("(%p)->(%p,%p,%08lx,%08lx,%p) thunking to IDirect3DDevice7 interface.\n", iface, lpCenters, lpRadii, dwNumSpheres, dwFlags, lpdwReturnValues); - return IDirect3DDevice7_ComputeSphereVisibility(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface), - lpCenters, - lpRadii, - dwNumSpheres, - dwFlags, - lpdwReturnValues); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_3_GetTextureStageState(LPDIRECT3DDEVICE3 iface, - DWORD dwStage, - D3DTEXTURESTAGESTATETYPE d3dTexStageStateType, - LPDWORD lpdwState) -{ - TRACE("(%p)->(%08lx,%08x,%p) thunking to IDirect3DDevice7 interface.\n", iface, dwStage, d3dTexStageStateType, lpdwState); - return IDirect3DDevice7_GetTextureStageState(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface), - dwStage, - d3dTexStageStateType, - lpdwState); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_3_SetTextureStageState(LPDIRECT3DDEVICE3 iface, - DWORD dwStage, - D3DTEXTURESTAGESTATETYPE d3dTexStageStateType, - DWORD dwState) -{ - TRACE("(%p)->(%08lx,%08x,%08lx) thunking to IDirect3DDevice7 interface.\n", iface, dwStage, d3dTexStageStateType, dwState); - return IDirect3DDevice7_SetTextureStageState(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface), - dwStage, - d3dTexStageStateType, - dwState); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_3_ValidateDevice(LPDIRECT3DDEVICE3 iface, - LPDWORD lpdwPasses) -{ - TRACE("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", iface, lpdwPasses); - return IDirect3DDevice7_ValidateDevice(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface), - lpdwPasses); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_2_GetCaps(LPDIRECT3DDEVICE2 iface, - LPD3DDEVICEDESC lpD3DHWDevDesc, - LPD3DDEVICEDESC lpD3DHELDevDesc) -{ - TRACE("(%p)->(%p,%p) thunking to IDirect3DDevice3 interface.\n", iface, lpD3DHWDevDesc, lpD3DHELDevDesc); - return IDirect3DDevice3_GetCaps(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice3, iface), - lpD3DHWDevDesc, - lpD3DHELDevDesc); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_1_GetCaps(LPDIRECT3DDEVICE iface, - LPD3DDEVICEDESC lpD3DHWDevDesc, - LPD3DDEVICEDESC lpD3DHELDevDesc) -{ - TRACE("(%p)->(%p,%p) thunking to IDirect3DDevice3 interface.\n", iface, lpD3DHWDevDesc, lpD3DHELDevDesc); - return IDirect3DDevice3_GetCaps(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice3, iface), - lpD3DHWDevDesc, - lpD3DHELDevDesc); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_1_SwapTextureHandles(LPDIRECT3DDEVICE iface, - LPDIRECT3DTEXTURE lpD3DTex1, - LPDIRECT3DTEXTURE lpD3DTex2) -{ - TRACE("(%p)->(%p,%p) thunking to IDirect3DDevice2 interface.\n", iface, lpD3DTex1, lpD3DTex2); - return IDirect3DDevice2_SwapTextureHandles(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice2, iface), - COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirect3DTexture2, lpD3DTex1), - COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirect3DTexture2, lpD3DTex2)); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_2_GetStats(LPDIRECT3DDEVICE2 iface, - LPD3DSTATS lpD3DStats) -{ - TRACE("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", iface, lpD3DStats); - return IDirect3DDevice3_GetStats(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice3, iface), - lpD3DStats); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_1_GetStats(LPDIRECT3DDEVICE iface, - LPD3DSTATS lpD3DStats) -{ - TRACE("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", iface, lpD3DStats); - return IDirect3DDevice3_GetStats(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice3, iface), - lpD3DStats); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_3_SetRenderTarget(LPDIRECT3DDEVICE3 iface, - LPDIRECTDRAWSURFACE4 lpNewRenderTarget, - DWORD dwFlags) -{ - TRACE("(%p)->(%p,%08lx) thunking to IDirect3DDevice7 interface.\n", iface, lpNewRenderTarget, dwFlags); - return IDirect3DDevice7_SetRenderTarget(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface), - (LPDIRECTDRAWSURFACE7) lpNewRenderTarget /* No cast needed as DSurf4 == DSurf7 */, - dwFlags); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_3_GetRenderTarget(LPDIRECT3DDEVICE3 iface, - LPDIRECTDRAWSURFACE4* lplpRenderTarget) -{ - TRACE("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", iface, lplpRenderTarget); - return IDirect3DDevice7_GetRenderTarget(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface), - (LPDIRECTDRAWSURFACE7*) lplpRenderTarget /* No cast needed as DSurf4 == DSurf7 */); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_2_SetRenderTarget(LPDIRECT3DDEVICE2 iface, - LPDIRECTDRAWSURFACE lpNewRenderTarget, - DWORD dwFlags) -{ - TRACE("(%p)->(%p,%08lx) thunking to IDirect3DDevice7 interface.\n", iface, lpNewRenderTarget, dwFlags); - return IDirect3DDevice7_SetRenderTarget(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice7, iface), - COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface3, IDirectDrawSurface7, lpNewRenderTarget), - dwFlags); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_2_GetRenderTarget(LPDIRECT3DDEVICE2 iface, - LPDIRECTDRAWSURFACE* lplpRenderTarget) -{ - HRESULT ret; - LPDIRECTDRAWSURFACE7 ret_val; - - TRACE("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", iface, lplpRenderTarget); - ret = IDirect3DDevice7_GetRenderTarget(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice7, iface), - &ret_val); - *lplpRenderTarget = (LPDIRECTDRAWSURFACE) COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7, IDirectDrawSurface3, ret_val); - TRACE(" returning interface %p\n", *lplpRenderTarget); - return ret; -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_2_Vertex(LPDIRECT3DDEVICE2 iface, - LPVOID lpVertexType) -{ - TRACE("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", iface, lpVertexType); - return IDirect3DDevice3_Vertex(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice3, iface), - lpVertexType); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_2_Index(LPDIRECT3DDEVICE2 iface, - WORD wVertexIndex) -{ - TRACE("(%p)->(%04x) thunking to IDirect3DDevice3 interface.\n", iface, wVertexIndex); - return IDirect3DDevice3_Index(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice3, iface), - wVertexIndex); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_2_End(LPDIRECT3DDEVICE2 iface, - DWORD dwFlags) -{ - TRACE("(%p)->(%08lx) thunking to IDirect3DDevice3 interface.\n", iface, dwFlags); - return IDirect3DDevice3_End(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice3, iface), - dwFlags); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_2_GetLightState(LPDIRECT3DDEVICE2 iface, - D3DLIGHTSTATETYPE dwLightStateType, - LPDWORD lpdwLightState) -{ - TRACE("(%p)->(%08x,%p) thunking to IDirect3DDevice3 interface.\n", iface, dwLightStateType, lpdwLightState); - return IDirect3DDevice3_GetLightState(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice3, iface), - dwLightStateType, - lpdwLightState); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_2_SetLightState(LPDIRECT3DDEVICE2 iface, - D3DLIGHTSTATETYPE dwLightStateType, - DWORD dwLightState) -{ - TRACE("(%p)->(%08x,%08lx) thunking to IDirect3DDevice3 interface.\n", iface, dwLightStateType, dwLightState); - return IDirect3DDevice3_SetLightState(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice3, iface), - dwLightStateType, - dwLightState); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats(LPDIRECT3DDEVICE iface, - LPD3DENUMTEXTUREFORMATSCALLBACK lpD3DEnumTextureProc, - LPVOID lpArg) -{ - TRACE("(%p)->(%p,%p) thunking to IDirect3DDevice2 interface.\n", iface, lpD3DEnumTextureProc, lpArg); - return IDirect3DDevice2_EnumTextureFormats(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice2, iface), - lpD3DEnumTextureProc, - lpArg); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_3_SetTexture(LPDIRECT3DDEVICE3 iface, - DWORD dwStage, - LPDIRECT3DTEXTURE2 lpTexture2) -{ - TRACE("(%p)->(%ld,%p) thunking to IDirect3DDevice7 interface.\n", iface, dwStage, lpTexture2); - return IDirect3DDevice7_SetTexture(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface), - dwStage, - COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture2, IDirectDrawSurface7, lpTexture2)); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB(LPDIRECT3DDEVICE3 iface, - D3DPRIMITIVETYPE d3dptPrimitiveType, - LPDIRECT3DVERTEXBUFFER lpD3DVertexBuf, - DWORD dwStartVertex, - DWORD dwNumVertices, - DWORD dwFlags) -{ - TRACE("(%p)->(%08x,%p,%08lx,%08lx,%08lx) thunking to IDirect3DDevice7 interface.\n", iface, - d3dptPrimitiveType, lpD3DVertexBuf, dwStartVertex, dwNumVertices, dwFlags); - return IDirect3DDevice7_DrawPrimitiveVB(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface), - d3dptPrimitiveType, - COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, lpD3DVertexBuf), - dwStartVertex, - dwNumVertices, - dwFlags); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB(LPDIRECT3DDEVICE3 iface, - D3DPRIMITIVETYPE d3dptPrimitiveType, - LPDIRECT3DVERTEXBUFFER lpD3DVertexBuf, - LPWORD lpwIndices, - DWORD dwIndexCount, - DWORD dwFlags) -{ - TRACE("(%p)->(%08x,%p,%p,%08lx,%08lx) thunking to IDirect3DDevice7 interface.\n", iface, - d3dptPrimitiveType, lpD3DVertexBuf, lpwIndices, dwIndexCount, dwFlags); - return IDirect3DDevice7_DrawIndexedPrimitiveVB(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface), - d3dptPrimitiveType, - COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, lpD3DVertexBuf), - 0, - dwIndexCount, - lpwIndices, - dwIndexCount, - dwFlags); -} - -HRESULT WINAPI -Thunk_IDirect3DDeviceImpl_3_GetTexture(LPDIRECT3DDEVICE3 iface, - DWORD dwStage, - LPDIRECT3DTEXTURE2* lplpTexture2) -{ - HRESULT ret; - LPDIRECTDRAWSURFACE7 ret_val; - - TRACE("(%p)->(%ld,%p) thunking to IDirect3DDevice7 interface.\n", iface, dwStage, lplpTexture2); - ret = IDirect3DDevice7_GetTexture(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, iface), - dwStage, - &ret_val); - - *lplpTexture2 = COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7, IDirect3DTexture2, ret_val); - - TRACE(" returning interface %p.\n", *lplpTexture2); - - return ret; -} diff --git a/dlls/ddraw/device_opengl.c b/dlls/ddraw/device_opengl.c deleted file mode 100644 index d19996eff9..0000000000 --- a/dlls/ddraw/device_opengl.c +++ /dev/null @@ -1,4450 +0,0 @@ -/* - * Direct3D Device - * - * Copyright (c) 1998-2004 Lionel Ulmer - * Copyright (c) 2002-2005 Christian Costa - * - * This file contains the MESA implementation of all the D3D devices that - * Wine supports. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "config.h" -#include "wine/port.h" - -#include -#include -#include - -#define NONAMELESSUNION -#define NONAMELESSSTRUCT - -#include "windef.h" -#include "winbase.h" -#include "winerror.h" -#include "objbase.h" -#include "wingdi.h" -#include "ddraw.h" -#include "d3d.h" -#include "wine/debug.h" -#include "wine/library.h" - -#include "d3d_private.h" -#include "opengl_private.h" - -WINE_DEFAULT_DEBUG_CHANNEL(ddraw); -WINE_DECLARE_DEBUG_CHANNEL(ddraw_geom); - -/* x11drv GDI escapes */ -#define X11DRV_ESCAPE 6789 -enum x11drv_escape_codes -{ - X11DRV_GET_DISPLAY, /* get X11 display for a DC */ - X11DRV_GET_DRAWABLE, /* get current drawable for a DC */ - X11DRV_GET_FONT, /* get current X font for a DC */ -}; - -/* They are non-static as they are used by Direct3D in the creation function */ -const GUID IID_D3DDEVICE_OpenGL = { - 0x31416d44, - 0x86ae, - 0x11d2, - { 0x82,0x2d,0xa8,0xd5,0x31,0x87,0xca,0xfa } -}; - -const float id_mat[16] = { - 1.0, 0.0, 0.0, 0.0, - 0.0, 1.0, 0.0, 0.0, - 0.0, 0.0, 1.0, 0.0, - 0.0, 0.0, 0.0, 1.0 -}; - -/* This is filled at DLL loading time */ -static D3DDEVICEDESC7 opengl_device_caps; -GL_EXTENSIONS_LIST GL_extensions; - -static void draw_primitive_strided(IDirect3DDeviceImpl *This, - D3DPRIMITIVETYPE d3dptPrimitiveType, - DWORD d3dvtVertexType, - LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData, - DWORD dwVertexCount, - LPWORD dwIndices, - DWORD dwIndexCount, - DWORD dwFlags) ; - -static DWORD draw_primitive_handle_textures(IDirect3DDeviceImpl *This); - -/* retrieve the X display to use on a given DC */ -inline static Display *get_display( HDC hdc ) -{ - Display *display; - enum x11drv_escape_codes escape = X11DRV_GET_DISPLAY; - - if (!ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape, - sizeof(display), (LPSTR)&display )) display = NULL; - - return display; -} - -#define UNLOCK_TEX_SIZE 256 - -#define DEPTH_RANGE_BIT (0x00000001 << 0) -#define VIEWPORT_BIT (0x00000001 << 1) - -static DWORD d3ddevice_set_state_for_flush(IDirect3DDeviceImpl *d3d_dev, LPCRECT pRect, BOOLEAN use_alpha, BOOLEAN *initial) { - IDirect3DDeviceGLImpl* gl_d3d_dev = (IDirect3DDeviceGLImpl*) d3d_dev; - DWORD opt_bitmap = 0x00000000; - - if ((gl_d3d_dev->current_bound_texture[1] != NULL) && - ((d3d_dev->state_block.texture_stage_state[1][D3DTSS_COLOROP - 1] != D3DTOP_DISABLE))) { - if (gl_d3d_dev->current_active_tex_unit != GL_TEXTURE1_WINE) { - GL_extensions.glActiveTexture(GL_TEXTURE1_WINE); - gl_d3d_dev->current_active_tex_unit = GL_TEXTURE1_WINE; - } - /* Disable multi-texturing for level 1 to disable all others */ - glDisable(GL_TEXTURE_2D); - } - if (gl_d3d_dev->current_active_tex_unit != GL_TEXTURE0_WINE) { - GL_extensions.glActiveTexture(GL_TEXTURE0_WINE); - gl_d3d_dev->current_active_tex_unit = GL_TEXTURE0_WINE; - } - if ((gl_d3d_dev->current_bound_texture[0] == NULL) || - (d3d_dev->state_block.texture_stage_state[0][D3DTSS_COLOROP - 1] == D3DTOP_DISABLE)) - glEnable(GL_TEXTURE_2D); - if (gl_d3d_dev->unlock_tex == 0) { - glGenTextures(1, &gl_d3d_dev->unlock_tex); - glBindTexture(GL_TEXTURE_2D, gl_d3d_dev->unlock_tex); - *initial = TRUE; - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - } else { - glBindTexture(GL_TEXTURE_2D, gl_d3d_dev->unlock_tex); - *initial = FALSE; - } - if (d3d_dev->tex_mat_is_identity[0] == FALSE) { - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); - } - - if (gl_d3d_dev->transform_state != GL_TRANSFORM_ORTHO) { - gl_d3d_dev->transform_state = GL_TRANSFORM_ORTHO; - d3ddevice_set_ortho(d3d_dev); - } - - if (gl_d3d_dev->depth_test != FALSE) glDisable(GL_DEPTH_TEST); - glEnable(GL_SCISSOR_TEST); - if ((d3d_dev->active_viewport.dvMinZ != 0.0) || - (d3d_dev->active_viewport.dvMaxZ != 1.0)) { - glDepthRange(0.0, 1.0); - opt_bitmap |= DEPTH_RANGE_BIT; - } - if ((d3d_dev->active_viewport.dwX != 0) || - (d3d_dev->active_viewport.dwY != 0) || - (d3d_dev->active_viewport.dwWidth != d3d_dev->surface->surface_desc.dwWidth) || - (d3d_dev->active_viewport.dwHeight != d3d_dev->surface->surface_desc.dwHeight)) { - glViewport(0, 0, d3d_dev->surface->surface_desc.dwWidth, d3d_dev->surface->surface_desc.dwHeight); - opt_bitmap |= VIEWPORT_BIT; - } - glScissor(pRect->left, d3d_dev->surface->surface_desc.dwHeight - pRect->bottom, - pRect->right - pRect->left, pRect->bottom - pRect->top); - if (gl_d3d_dev->lighting != FALSE) glDisable(GL_LIGHTING); - if (gl_d3d_dev->cull_face != FALSE) glDisable(GL_CULL_FACE); - if (use_alpha) { - if (gl_d3d_dev->alpha_test == FALSE) glEnable(GL_ALPHA_TEST); - if ((gl_d3d_dev->current_alpha_test_func != GL_NOTEQUAL) || (gl_d3d_dev->current_alpha_test_ref != 0.0)) - glAlphaFunc(GL_NOTEQUAL, 0.0); - } else { - if (gl_d3d_dev->alpha_test != FALSE) glDisable(GL_ALPHA_TEST); - } - if (gl_d3d_dev->stencil_test != FALSE) glDisable(GL_STENCIL_TEST); - if (gl_d3d_dev->blending != FALSE) glDisable(GL_BLEND); - if (gl_d3d_dev->fogging != FALSE) glDisable(GL_FOG); - if (gl_d3d_dev->current_tex_env != GL_REPLACE) - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - - return opt_bitmap; -} - -static void d3ddevice_restore_state_after_flush(IDirect3DDeviceImpl *d3d_dev, DWORD opt_bitmap, BOOLEAN use_alpha) { - IDirect3DDeviceGLImpl* gl_d3d_dev = (IDirect3DDeviceGLImpl*) d3d_dev; - - /* And restore all the various states modified by this code */ - if (gl_d3d_dev->depth_test != 0) glEnable(GL_DEPTH_TEST); - if (gl_d3d_dev->lighting != 0) glEnable(GL_LIGHTING); - if ((gl_d3d_dev->alpha_test != 0) && (use_alpha == 0)) - glEnable(GL_ALPHA_TEST); - else if ((gl_d3d_dev->alpha_test == 0) && (use_alpha != 0)) - glDisable(GL_ALPHA_TEST); - if (use_alpha) { - if ((gl_d3d_dev->current_alpha_test_func != GL_NOTEQUAL) || (gl_d3d_dev->current_alpha_test_ref != 0.0)) - glAlphaFunc(gl_d3d_dev->current_alpha_test_func, gl_d3d_dev->current_alpha_test_ref); - } - if (gl_d3d_dev->stencil_test != 0) glEnable(GL_STENCIL_TEST); - if (gl_d3d_dev->cull_face != 0) glEnable(GL_CULL_FACE); - if (gl_d3d_dev->blending != 0) glEnable(GL_BLEND); - if (gl_d3d_dev->fogging != 0) glEnable(GL_FOG); - glDisable(GL_SCISSOR_TEST); - if (opt_bitmap & DEPTH_RANGE_BIT) { - glDepthRange(d3d_dev->active_viewport.dvMinZ, d3d_dev->active_viewport.dvMaxZ); - } - if (opt_bitmap & VIEWPORT_BIT) { - glViewport(d3d_dev->active_viewport.dwX, - d3d_dev->surface->surface_desc.dwHeight - (d3d_dev->active_viewport.dwHeight + d3d_dev->active_viewport.dwY), - d3d_dev->active_viewport.dwWidth, d3d_dev->active_viewport.dwHeight); - } - if (d3d_dev->tex_mat_is_identity[0] == FALSE) { - d3d_dev->matrices_updated(d3d_dev, TEXMAT0_CHANGED); - } - - if (gl_d3d_dev->current_active_tex_unit != GL_TEXTURE0_WINE) { - GL_extensions.glActiveTexture(GL_TEXTURE0_WINE); - gl_d3d_dev->current_active_tex_unit = GL_TEXTURE0_WINE; - } - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, gl_d3d_dev->current_tex_env); - /* Note that here we could directly re-bind the previous texture... But it would in some case be a spurious - bind if ever the game changes the texture just after. - - So choose 0x00000001 to postpone the binding to the next time we draw something on screen. */ - gl_d3d_dev->current_bound_texture[0] = (IDirectDrawSurfaceImpl *) 0x00000001; - if (d3d_dev->state_block.texture_stage_state[0][D3DTSS_COLOROP - 1] == D3DTOP_DISABLE) glDisable(GL_TEXTURE_2D); - - /* And re-enabled if needed texture level 1 */ - if ((gl_d3d_dev->current_bound_texture[1] != NULL) && - (d3d_dev->state_block.texture_stage_state[1][D3DTSS_COLOROP - 1] != D3DTOP_DISABLE)) { - if (gl_d3d_dev->current_active_tex_unit != GL_TEXTURE1_WINE) { - GL_extensions.glActiveTexture(GL_TEXTURE1_WINE); - gl_d3d_dev->current_active_tex_unit = GL_TEXTURE1_WINE; - } - glEnable(GL_TEXTURE_2D); - } -} - -/* retrieve the X drawable to use on a given DC */ -inline static Drawable get_drawable( HDC hdc ) -{ - Drawable drawable; - enum x11drv_escape_codes escape = X11DRV_GET_DRAWABLE; - - if (!ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape, - sizeof(drawable), (LPSTR)&drawable )) drawable = 0; - - return drawable; -} - -static BOOL opengl_flip( LPVOID dev, LPVOID drawable) -{ - IDirect3DDeviceImpl *d3d_dev = (IDirect3DDeviceImpl *) dev; - IDirect3DDeviceGLImpl *gl_d3d_dev = (IDirect3DDeviceGLImpl *) dev; - - TRACE("(%p, %ld)\n", gl_d3d_dev->display,(Drawable)drawable); - ENTER_GL(); - if (gl_d3d_dev->state[WINE_GL_BUFFER_BACK] == SURFACE_MEMORY_DIRTY) { - d3d_dev->flush_to_framebuffer(d3d_dev, &(gl_d3d_dev->lock_rect[WINE_GL_BUFFER_BACK]), gl_d3d_dev->lock_surf[WINE_GL_BUFFER_BACK]); - } - gl_d3d_dev->state[WINE_GL_BUFFER_BACK] = SURFACE_GL; - gl_d3d_dev->state[WINE_GL_BUFFER_FRONT] = SURFACE_GL; - glXSwapBuffers(gl_d3d_dev->display, (Drawable)drawable); - LEAVE_GL(); - - return TRUE; -} - - -/******************************************************************************* - * OpenGL static functions - */ -static void set_context(IDirect3DDeviceImpl* This) -{ - IDirect3DDeviceGLImpl* glThis = (IDirect3DDeviceGLImpl*) This; - - TRACE("glxMakeCurrent %p, %ld, %p\n",glThis->display,glThis->drawable, glThis->gl_context); - ENTER_GL(); - if (glXMakeCurrent(glThis->display, glThis->drawable, glThis->gl_context) == False) { - ERR("Error in setting current context (context %p drawable %ld)!\n", - glThis->gl_context, glThis->drawable); - } - LEAVE_GL(); -} - -static void fill_opengl_caps(D3DDEVICEDESC *d1) -{ - d1->dwSize = sizeof(*d1); - d1->dwFlags = D3DDD_COLORMODEL | D3DDD_DEVCAPS | D3DDD_TRANSFORMCAPS | D3DDD_BCLIPPING | D3DDD_LIGHTINGCAPS | - D3DDD_LINECAPS | D3DDD_TRICAPS | D3DDD_DEVICERENDERBITDEPTH | D3DDD_DEVICEZBUFFERBITDEPTH | - D3DDD_MAXBUFFERSIZE | D3DDD_MAXVERTEXCOUNT; - d1->dcmColorModel = D3DCOLOR_RGB; - d1->dwDevCaps = opengl_device_caps.dwDevCaps; - d1->dtcTransformCaps.dwSize = sizeof(D3DTRANSFORMCAPS); - d1->dtcTransformCaps.dwCaps = D3DTRANSFORMCAPS_CLIP; - d1->bClipping = TRUE; - d1->dlcLightingCaps.dwSize = sizeof(D3DLIGHTINGCAPS); - d1->dlcLightingCaps.dwCaps = D3DLIGHTCAPS_DIRECTIONAL | D3DLIGHTCAPS_PARALLELPOINT | D3DLIGHTCAPS_POINT | D3DLIGHTCAPS_SPOT; - d1->dlcLightingCaps.dwLightingModel = D3DLIGHTINGMODEL_RGB; - d1->dlcLightingCaps.dwNumLights = opengl_device_caps.dwMaxActiveLights; - d1->dpcLineCaps = opengl_device_caps.dpcLineCaps; - d1->dpcTriCaps = opengl_device_caps.dpcTriCaps; - d1->dwDeviceRenderBitDepth = opengl_device_caps.dwDeviceRenderBitDepth; - d1->dwDeviceZBufferBitDepth = opengl_device_caps.dwDeviceZBufferBitDepth; - d1->dwMaxBufferSize = 0; - d1->dwMaxVertexCount = 65536; - d1->dwMinTextureWidth = opengl_device_caps.dwMinTextureWidth; - d1->dwMinTextureHeight = opengl_device_caps.dwMinTextureHeight; - d1->dwMaxTextureWidth = opengl_device_caps.dwMaxTextureWidth; - d1->dwMaxTextureHeight = opengl_device_caps.dwMaxTextureHeight; - d1->dwMinStippleWidth = 1; - d1->dwMinStippleHeight = 1; - d1->dwMaxStippleWidth = 32; - d1->dwMaxStippleHeight = 32; - d1->dwMaxTextureRepeat = opengl_device_caps.dwMaxTextureRepeat; - d1->dwMaxTextureAspectRatio = opengl_device_caps.dwMaxTextureAspectRatio; - d1->dwMaxAnisotropy = opengl_device_caps.dwMaxAnisotropy; - d1->dvGuardBandLeft = opengl_device_caps.dvGuardBandLeft; - d1->dvGuardBandRight = opengl_device_caps.dvGuardBandRight; - d1->dvGuardBandTop = opengl_device_caps.dvGuardBandTop; - d1->dvGuardBandBottom = opengl_device_caps.dvGuardBandBottom; - d1->dvExtentsAdjust = opengl_device_caps.dvExtentsAdjust; - d1->dwStencilCaps = opengl_device_caps.dwStencilCaps; - d1->dwFVFCaps = opengl_device_caps.dwFVFCaps; - d1->dwTextureOpCaps = opengl_device_caps.dwTextureOpCaps; - d1->wMaxTextureBlendStages = opengl_device_caps.wMaxTextureBlendStages; - d1->wMaxSimultaneousTextures = opengl_device_caps.wMaxSimultaneousTextures; -} - -static void fill_opengl_caps_7(D3DDEVICEDESC7 *d) -{ - *d = opengl_device_caps; -} - -HRESULT d3ddevice_enumerate(LPD3DENUMDEVICESCALLBACK cb, LPVOID context, DWORD version) -{ - D3DDEVICEDESC dref, d1, d2; - HRESULT ret_value; - - /* Some games (Motoracer 2 demo) have the bad idea to modify the device name string. - Let's put the string in a sufficiently sized array in writable memory. */ - char device_name[50]; - strcpy(device_name,"direct3d"); - - fill_opengl_caps(&dref); - - if (version > 1) { - /* It seems that enumerating the reference IID on Direct3D 1 games (AvP / Motoracer2) breaks them */ - char interface_name[] = "WINE Reference Direct3DX using OpenGL"; - TRACE(" enumerating OpenGL D3DDevice interface using reference IID (IID %s).\n", debugstr_guid(&IID_IDirect3DRefDevice)); - d1 = dref; - d2 = dref; - ret_value = cb((LPIID) &IID_IDirect3DRefDevice, interface_name, device_name, &d1, &d2, context); - if (ret_value != D3DENUMRET_OK) - return ret_value; - } - - { - char interface_name[] = "WINE Direct3DX using OpenGL"; - TRACE(" enumerating OpenGL D3DDevice interface (IID %s).\n", debugstr_guid(&IID_D3DDEVICE_OpenGL)); - d1 = dref; - d2 = dref; - ret_value = cb((LPIID) &IID_D3DDEVICE_OpenGL, interface_name, device_name, &d1, &d2, context); - if (ret_value != D3DENUMRET_OK) - return ret_value; - } - - return D3DENUMRET_OK; -} - -HRESULT d3ddevice_enumerate7(LPD3DENUMDEVICESCALLBACK7 cb, LPVOID context) -{ - D3DDEVICEDESC7 ddesc; - char interface_name[] = "WINE Direct3D7 using OpenGL"; - char device_name[] = "Wine D3D7 device"; - - fill_opengl_caps_7(&ddesc); - - TRACE(" enumerating OpenGL D3DDevice7 interface.\n"); - - return cb(interface_name, device_name, &ddesc, context); -} - -static ULONG WINAPI -GL_IDirect3DDeviceImpl_7_3T_2T_1T_Release(LPDIRECT3DDEVICE7 iface) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This; - ULONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p/%p)->() decrementing from %lu.\n", This, iface, ref + 1); - - if (!ref) { - int i; - IDirectDrawSurfaceImpl *surface = This->surface, *surf; - - /* Release texture associated with the device */ - for (i = 0; i < MAX_TEXTURES; i++) { - if (This->current_texture[i] != NULL) - IDirectDrawSurface7_Release(ICOM_INTERFACE(This->current_texture[i], IDirectDrawSurface7)); - HeapFree(GetProcessHeap(), 0, This->tex_mat[i]); - } - - /* Look for the front buffer and override its surface's Flip method (if in double buffering) */ - for (surf = surface; surf != NULL; surf = surf->surface_owner) { - if ((surf->surface_desc.ddsCaps.dwCaps&(DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER)) == (DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER)) { - surf->aux_ctx = NULL; - surf->aux_data = NULL; - surf->aux_flip = NULL; - break; - } - } - for (surf = surface; surf != NULL; surf = surf->surface_owner) { - IDirectDrawSurfaceImpl *surf2; - for (surf2 = surf; surf2->prev_attached != NULL; surf2 = surf2->prev_attached) ; - for (; surf2 != NULL; surf2 = surf2->next_attached) { - if (((surf2->surface_desc.ddsCaps.dwCaps & (DDSCAPS_3DDEVICE)) == (DDSCAPS_3DDEVICE)) && - ((surf2->surface_desc.ddsCaps.dwCaps & (DDSCAPS_ZBUFFER)) != (DDSCAPS_ZBUFFER))) { - /* Override the Lock / Unlock function for all these surfaces */ - surf2->lock_update = surf2->lock_update_prev; - surf2->unlock_update = surf2->unlock_update_prev; - /* And install also the blt / bltfast overrides */ - surf2->aux_blt = NULL; - surf2->aux_bltfast = NULL; - } - surf2->d3ddevice = NULL; - } - } - - /* And warn the D3D object that this device is no longer active... */ - This->d3d->d3d_removed_device(This->d3d, This); - - /* Free light arrays */ - HeapFree(GetProcessHeap(), 0, This->light_parameters); - HeapFree(GetProcessHeap(), 0, This->active_lights); - - HeapFree(GetProcessHeap(), 0, This->world_mat); - HeapFree(GetProcessHeap(), 0, This->view_mat); - HeapFree(GetProcessHeap(), 0, This->proj_mat); - - HeapFree(GetProcessHeap(), 0, glThis->surface_ptr); - - DeleteCriticalSection(&(This->crit)); - - ENTER_GL(); - if (glThis->unlock_tex) - glDeleteTextures(1, &(glThis->unlock_tex)); - glXDestroyContext(glThis->display, glThis->gl_context); - LEAVE_GL(); - HeapFree(GetProcessHeap(), 0, This->clipping_planes); - HeapFree(GetProcessHeap(), 0, This->vertex_buffer); - - HeapFree(GetProcessHeap(), 0, This); - return 0; - } - return ref; -} - -HRESULT WINAPI -GL_IDirect3DDeviceImpl_3_2T_1T_GetCaps(LPDIRECT3DDEVICE3 iface, - LPD3DDEVICEDESC lpD3DHWDevDesc, - LPD3DDEVICEDESC lpD3DHELDevDesc) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); - D3DDEVICEDESC desc; - DWORD dwSize; - - TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpD3DHWDevDesc, lpD3DHELDevDesc); - - fill_opengl_caps(&desc); - dwSize = lpD3DHWDevDesc->dwSize; - memset(lpD3DHWDevDesc, 0, dwSize); - memcpy(lpD3DHWDevDesc, &desc, (dwSize <= desc.dwSize ? dwSize : desc.dwSize)); - - dwSize = lpD3DHELDevDesc->dwSize; - memset(lpD3DHELDevDesc, 0, dwSize); - memcpy(lpD3DHELDevDesc, &desc, (dwSize <= desc.dwSize ? dwSize : desc.dwSize)); - - TRACE(" returning caps : (no dump function yet)\n"); - - return DD_OK; -} - -static HRESULT enum_texture_format_OpenGL(LPD3DENUMTEXTUREFORMATSCALLBACK cb_1, - LPD3DENUMPIXELFORMATSCALLBACK cb_2, - LPVOID context, int version) -{ - DDSURFACEDESC sdesc; - LPDDPIXELFORMAT pformat; - - /* Do the texture enumeration */ - sdesc.dwSize = sizeof(DDSURFACEDESC); - sdesc.dwFlags = DDSD_PIXELFORMAT | DDSD_CAPS; - sdesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE; - pformat = &(sdesc.ddpfPixelFormat); - pformat->dwSize = sizeof(DDPIXELFORMAT); - pformat->dwFourCC = 0; - - TRACE("Enumerating GL_RGBA unpacked (32)\n"); - pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS; - pformat->u1.dwRGBBitCount = 32; - pformat->u2.dwRBitMask = 0x00FF0000; - pformat->u3.dwGBitMask = 0x0000FF00; - pformat->u4.dwBBitMask = 0x000000FF; - pformat->u5.dwRGBAlphaBitMask = 0xFF000000; - if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK; - if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK; - - TRACE("Enumerating GL_RGB unpacked (32)\n"); - pformat->dwFlags = DDPF_RGB; - pformat->u1.dwRGBBitCount = 32; - pformat->u2.dwRBitMask = 0x00FF0000; - pformat->u3.dwGBitMask = 0x0000FF00; - pformat->u4.dwBBitMask = 0x000000FF; - pformat->u5.dwRGBAlphaBitMask = 0x00000000; - if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK; - if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK; - - TRACE("Enumerating GL_RGB unpacked (24)\n"); - pformat->dwFlags = DDPF_RGB; - pformat->u1.dwRGBBitCount = 24; - pformat->u2.dwRBitMask = 0x00FF0000; - pformat->u3.dwGBitMask = 0x0000FF00; - pformat->u4.dwBBitMask = 0x000000FF; - pformat->u5.dwRGBAlphaBitMask = 0x00000000; - if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK; - if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK; - - /* Note : even if this is an 'emulated' texture format, it needs to be first - as some dumb applications seem to rely on that. */ - TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_1_5_5_5 (ARGB) (16)\n"); - pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS; - pformat->u1.dwRGBBitCount = 16; - pformat->u2.dwRBitMask = 0x00007C00; - pformat->u3.dwGBitMask = 0x000003E0; - pformat->u4.dwBBitMask = 0x0000001F; - pformat->u5.dwRGBAlphaBitMask = 0x00008000; - if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK; - if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK; - - TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_4_4_4_4 (ARGB) (16)\n"); - pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS; - pformat->u1.dwRGBBitCount = 16; - pformat->u2.dwRBitMask = 0x00000F00; - pformat->u3.dwGBitMask = 0x000000F0; - pformat->u4.dwBBitMask = 0x0000000F; - pformat->u5.dwRGBAlphaBitMask = 0x0000F000; - if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK; - if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK; - - TRACE("Enumerating GL_RGB packed GL_UNSIGNED_SHORT_5_6_5 (16)\n"); - pformat->dwFlags = DDPF_RGB; - pformat->u1.dwRGBBitCount = 16; - pformat->u2.dwRBitMask = 0x0000F800; - pformat->u3.dwGBitMask = 0x000007E0; - pformat->u4.dwBBitMask = 0x0000001F; - pformat->u5.dwRGBAlphaBitMask = 0x00000000; - if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK; - if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK; - - TRACE("Enumerating GL_RGB packed GL_UNSIGNED_SHORT_5_5_5 (16)\n"); - pformat->dwFlags = DDPF_RGB; - pformat->u1.dwRGBBitCount = 16; - pformat->u2.dwRBitMask = 0x00007C00; - pformat->u3.dwGBitMask = 0x000003E0; - pformat->u4.dwBBitMask = 0x0000001F; - pformat->u5.dwRGBAlphaBitMask = 0x00000000; - if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK; - if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK; - -#if 0 - /* This is a compromise : some games choose the first 16 bit texture format with alpha they - find enumerated, others the last one. And both want to have the ARGB one. - - So basically, forget our OpenGL roots and do not even enumerate our RGBA ones. - */ - /* See argument about the RGBA format for 'packed' texture formats */ - TRACE("Enumerating GL_RGBA unpacked (32)\n"); - pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS; - pformat->u1.dwRGBBitCount = 32; - pformat->u2.dwRBitMask = 0xFF000000; - pformat->u3.dwGBitMask = 0x00FF0000; - pformat->u4.dwBBitMask = 0x0000FF00; - pformat->u5.dwRGBAlphaBitMask = 0x000000FF; - if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK; - if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK; - - TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_4_4_4_4 (16)\n"); - pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS; - pformat->u1.dwRGBBitCount = 16; - pformat->u2.dwRBitMask = 0x0000F000; - pformat->u3.dwGBitMask = 0x00000F00; - pformat->u4.dwBBitMask = 0x000000F0; - pformat->u5.dwRGBAlphaBitMask = 0x0000000F; - if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK; - if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK; - - TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_5_5_5_1 (16)\n"); - pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS; - pformat->u1.dwRGBBitCount = 16; - pformat->u2.dwRBitMask = 0x0000F800; - pformat->u3.dwGBitMask = 0x000007C0; - pformat->u4.dwBBitMask = 0x0000003E; - pformat->u5.dwRGBAlphaBitMask = 0x00000001; - if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK; - if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK; -#endif - - TRACE("Enumerating GL_RGB packed GL_UNSIGNED_BYTE_3_3_2 (8)\n"); - pformat->dwFlags = DDPF_RGB; - pformat->u1.dwRGBBitCount = 8; - pformat->u2.dwRBitMask = 0x000000E0; - pformat->u3.dwGBitMask = 0x0000001C; - pformat->u4.dwBBitMask = 0x00000003; - pformat->u5.dwRGBAlphaBitMask = 0x00000000; - if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK; - if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK; - - TRACE("Enumerating Paletted (8)\n"); - pformat->dwFlags = DDPF_PALETTEINDEXED8; - pformat->u1.dwRGBBitCount = 8; - pformat->u2.dwRBitMask = 0x00000000; - pformat->u3.dwGBitMask = 0x00000000; - pformat->u4.dwBBitMask = 0x00000000; - pformat->u5.dwRGBAlphaBitMask = 0x00000000; - if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK; - if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK; - - /* DXT textures only exist for devices created from IDirect3D3 and above */ - if ((version >= 3) && GL_extensions.s3tc_compressed_texture) { - TRACE("Enumerating DXT1\n"); - pformat->dwFlags = DDPF_FOURCC; - pformat->dwFourCC = MAKE_FOURCC('D','X','T','1'); - if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK; - if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK; - - TRACE("Enumerating DXT3\n"); - pformat->dwFlags = DDPF_FOURCC; - pformat->dwFourCC = MAKE_FOURCC('D','X','T','3'); - if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK; - if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK; - - TRACE("Enumerating DXT5\n"); - pformat->dwFlags = DDPF_FOURCC; - pformat->dwFourCC = MAKE_FOURCC('D','X','T','5'); - if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK; - if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK; - } - - TRACE("End of enumeration\n"); - return DD_OK; -} - - -HRESULT -d3ddevice_find(IDirectDrawImpl *d3d, - LPD3DFINDDEVICESEARCH lpD3DDFS, - LPD3DFINDDEVICERESULT lplpD3DDevice) -{ - D3DDEVICEDESC desc; - - if ((lpD3DDFS->dwFlags & D3DFDS_COLORMODEL) && - (lpD3DDFS->dcmColorModel != D3DCOLOR_RGB)) { - TRACE(" trying to request a non-RGB D3D color model. Not supported.\n"); - return DDERR_INVALIDPARAMS; /* No real idea what to return here :-) */ - } - if (lpD3DDFS->dwFlags & D3DFDS_GUID) { - TRACE(" trying to match guid %s.\n", debugstr_guid(&(lpD3DDFS->guid))); - if ((IsEqualGUID(&IID_D3DDEVICE_OpenGL, &(lpD3DDFS->guid)) == 0) && - (IsEqualGUID(&IID_IDirect3DHALDevice, &(lpD3DDFS->guid)) == 0) && - (IsEqualGUID(&IID_IDirect3DRefDevice, &(lpD3DDFS->guid)) == 0)) { - TRACE(" no match for this GUID.\n"); - return DDERR_INVALIDPARAMS; - } - } - - /* Now return our own GUID */ - lplpD3DDevice->guid = IID_D3DDEVICE_OpenGL; - fill_opengl_caps(&desc); - lplpD3DDevice->ddHwDesc = desc; - lplpD3DDevice->ddSwDesc = desc; - - TRACE(" returning Wine's OpenGL device with (undumped) capabilities\n"); - - return D3D_OK; -} - -HRESULT WINAPI -GL_IDirect3DDeviceImpl_2_1T_EnumTextureFormats(LPDIRECT3DDEVICE2 iface, - LPD3DENUMTEXTUREFORMATSCALLBACK lpD3DEnumTextureProc, - LPVOID lpArg) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface); - TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpD3DEnumTextureProc, lpArg); - return enum_texture_format_OpenGL(lpD3DEnumTextureProc, NULL, lpArg, This->version); -} - -static HRESULT WINAPI -GL_IDirect3DDeviceImpl_7_3T_EnumTextureFormats(LPDIRECT3DDEVICE7 iface, - LPD3DENUMPIXELFORMATSCALLBACK lpD3DEnumPixelProc, - LPVOID lpArg) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpD3DEnumPixelProc, lpArg); - return enum_texture_format_OpenGL(NULL, lpD3DEnumPixelProc, lpArg, This->version); -} - -static HRESULT WINAPI -GL_IDirect3DDeviceImpl_7_3T_2T_SetRenderState(LPDIRECT3DDEVICE7 iface, - D3DRENDERSTATETYPE dwRenderStateType, - DWORD dwRenderState) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - TRACE("(%p/%p)->(%08x,%08lx)\n", This, iface, dwRenderStateType, dwRenderState); - - /* Call the render state functions */ - store_render_state(This, dwRenderStateType, dwRenderState, &This->state_block); - set_render_state(This, dwRenderStateType, &This->state_block); - - return DD_OK; -} - -static HRESULT WINAPI -GL_IDirect3DDeviceImpl_7_3T_2T_GetRenderState(LPDIRECT3DDEVICE7 iface, - D3DRENDERSTATETYPE dwRenderStateType, - LPDWORD lpdwRenderState) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - TRACE("(%p/%p)->(%08x,%p)\n", This, iface, dwRenderStateType, lpdwRenderState); - - /* Call the render state functions */ - get_render_state(This, dwRenderStateType, lpdwRenderState, &This->state_block); - - TRACE(" - asked for rendering state : %s, returning value %08lx.\n", _get_renderstate(dwRenderStateType), *lpdwRenderState); - - return DD_OK; -} - -static HRESULT WINAPI -GL_IDirect3DDeviceImpl_3_2T_GetLightState(LPDIRECT3DDEVICE3 iface, - D3DLIGHTSTATETYPE dwLightStateType, - LPDWORD lpdwLightState) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); - - TRACE("(%p/%p)->(%08x,%p)\n", This, iface, dwLightStateType, lpdwLightState); - - if (!dwLightStateType && (dwLightStateType > D3DLIGHTSTATE_COLORVERTEX)) { - TRACE("Unexpected Light State Type\n"); - return DDERR_INVALIDPARAMS; - } - - if (dwLightStateType == D3DLIGHTSTATE_MATERIAL /* 1 */) { - *lpdwLightState = This->material; - } else if (dwLightStateType == D3DLIGHTSTATE_COLORMODEL /* 3 */) { - *lpdwLightState = D3DCOLOR_RGB; - } else { - D3DRENDERSTATETYPE rs; - switch (dwLightStateType) { - case D3DLIGHTSTATE_AMBIENT: /* 2 */ - rs = D3DRENDERSTATE_AMBIENT; - break; - case D3DLIGHTSTATE_FOGMODE: /* 4 */ - rs = D3DRENDERSTATE_FOGVERTEXMODE; - break; - case D3DLIGHTSTATE_FOGSTART: /* 5 */ - rs = D3DRENDERSTATE_FOGSTART; - break; - case D3DLIGHTSTATE_FOGEND: /* 6 */ - rs = D3DRENDERSTATE_FOGEND; - break; - case D3DLIGHTSTATE_FOGDENSITY: /* 7 */ - rs = D3DRENDERSTATE_FOGDENSITY; - break; - case D3DLIGHTSTATE_COLORVERTEX: /* 8 */ - rs = D3DRENDERSTATE_COLORVERTEX; - break; - default: - ERR("Unknown D3DLIGHTSTATETYPE %d.\n", dwLightStateType); - return DDERR_INVALIDPARAMS; - } - - IDirect3DDevice7_GetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7), - rs,lpdwLightState); - } - - return DD_OK; -} - -static HRESULT WINAPI -GL_IDirect3DDeviceImpl_3_2T_SetLightState(LPDIRECT3DDEVICE3 iface, - D3DLIGHTSTATETYPE dwLightStateType, - DWORD dwLightState) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface); - - TRACE("(%p/%p)->(%08x,%08lx)\n", This, iface, dwLightStateType, dwLightState); - - if (!dwLightStateType && (dwLightStateType > D3DLIGHTSTATE_COLORVERTEX)) { - TRACE("Unexpected Light State Type\n"); - return DDERR_INVALIDPARAMS; - } - - if (dwLightStateType == D3DLIGHTSTATE_MATERIAL /* 1 */) { - IDirect3DMaterialImpl *mat = (IDirect3DMaterialImpl *) dwLightState; - - if (mat != NULL) { - TRACE(" activating material %p.\n", mat); - mat->activate(mat); - } else { - FIXME(" D3DLIGHTSTATE_MATERIAL called with NULL material !!!\n"); - } - This->material = dwLightState; - } else if (dwLightStateType == D3DLIGHTSTATE_COLORMODEL /* 3 */) { - switch (dwLightState) { - case D3DCOLOR_MONO: - ERR("DDCOLOR_MONO should not happen!\n"); - break; - case D3DCOLOR_RGB: - /* We are already in this mode */ - TRACE("Setting color model to RGB (no-op).\n"); - break; - default: - ERR("Unknown color model!\n"); - return DDERR_INVALIDPARAMS; - } - } else { - D3DRENDERSTATETYPE rs; - switch (dwLightStateType) { - case D3DLIGHTSTATE_AMBIENT: /* 2 */ - rs = D3DRENDERSTATE_AMBIENT; - break; - case D3DLIGHTSTATE_FOGMODE: /* 4 */ - rs = D3DRENDERSTATE_FOGVERTEXMODE; - break; - case D3DLIGHTSTATE_FOGSTART: /* 5 */ - rs = D3DRENDERSTATE_FOGSTART; - break; - case D3DLIGHTSTATE_FOGEND: /* 6 */ - rs = D3DRENDERSTATE_FOGEND; - break; - case D3DLIGHTSTATE_FOGDENSITY: /* 7 */ - rs = D3DRENDERSTATE_FOGDENSITY; - break; - case D3DLIGHTSTATE_COLORVERTEX: /* 8 */ - rs = D3DRENDERSTATE_COLORVERTEX; - break; - default: - ERR("Unknown D3DLIGHTSTATETYPE %d.\n", dwLightStateType); - return DDERR_INVALIDPARAMS; - } - - IDirect3DDevice7_SetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7), - rs,dwLightState); - } - - return DD_OK; -} - -static GLenum convert_D3D_ptype_to_GL(D3DPRIMITIVETYPE d3dpt) -{ - switch (d3dpt) { - case D3DPT_POINTLIST: - TRACE(" primitive type is POINTS\n"); - return GL_POINTS; - - case D3DPT_LINELIST: - TRACE(" primitive type is LINES\n"); - return GL_LINES; - - case D3DPT_LINESTRIP: - TRACE(" primitive type is LINE_STRIP\n"); - return GL_LINE_STRIP; - - case D3DPT_TRIANGLELIST: - TRACE(" primitive type is TRIANGLES\n"); - return GL_TRIANGLES; - - case D3DPT_TRIANGLESTRIP: - TRACE(" primitive type is TRIANGLE_STRIP\n"); - return GL_TRIANGLE_STRIP; - - case D3DPT_TRIANGLEFAN: - TRACE(" primitive type is TRIANGLE_FAN\n"); - return GL_TRIANGLE_FAN; - - default: - FIXME("Unhandled primitive %08x\n", d3dpt); - return GL_POINTS; - } -} - -/* This function calculate the Z coordinate from Zproj */ -static float ZfromZproj(IDirect3DDeviceImpl *This, D3DVALUE Zproj) -{ - float a,b,c,d; - /* Assume that X = Y = 0 and W = 1 */ - a = This->proj_mat->_33; - b = This->proj_mat->_34; - c = This->proj_mat->_43; - d = This->proj_mat->_44; - /* We have in homogenous coordinates Z' = a * Z + c and W' = b * Z + d - * So in non homogenous coordinates we have Zproj = (a * Z + c) / (b * Z + d) - * And finally Z = (d * Zproj - c) / (a - b * Zproj) - */ - return (d*Zproj - c) / (a - b*Zproj); -} - -static void build_fog_table(BYTE *fog_table, DWORD fog_color) { - int i; - - TRACE(" rebuilding fog table (%06lx)...\n", fog_color & 0x00FFFFFF); - - for (i = 0; i < 3; i++) { - BYTE fog_color_component = (fog_color >> (8 * i)) & 0xFF; - DWORD elt; - for (elt = 0; elt < 0x10000; elt++) { - /* We apply the fog transformation and cache the result */ - DWORD fog_intensity = elt & 0xFF; - DWORD vertex_color = (elt >> 8) & 0xFF; - fog_table[(i * 0x10000) + elt] = ((fog_intensity * vertex_color) + ((0xFF - fog_intensity) * fog_color_component)) / 0xFF; - } - } -} - -static void draw_primitive_handle_GL_state(IDirect3DDeviceImpl *This, - BOOLEAN vertex_transformed, - BOOLEAN vertex_lit) { - IDirect3DDeviceGLImpl* glThis = (IDirect3DDeviceGLImpl*) This; - - /* Puts GL in the correct lighting / transformation mode */ - if ((vertex_transformed == FALSE) && - (glThis->transform_state != GL_TRANSFORM_NORMAL)) { - /* Need to put the correct transformation again if we go from Transformed - vertices to non-transformed ones. - */ - This->set_matrices(This, VIEWMAT_CHANGED|WORLDMAT_CHANGED|PROJMAT_CHANGED, - This->world_mat, This->view_mat, This->proj_mat); - glThis->transform_state = GL_TRANSFORM_NORMAL; - - } else if (vertex_transformed && - (glThis->transform_state != GL_TRANSFORM_ORTHO)) { - /* Set our orthographic projection */ - if (glThis->transform_state != GL_TRANSFORM_ORTHO) { - glThis->transform_state = GL_TRANSFORM_ORTHO; - d3ddevice_set_ortho(This); - } - } - - /* TODO: optimize this to not always reset all the fog stuff on all DrawPrimitive call - if no fogging state change occurred */ - if (This->state_block.render_state[D3DRENDERSTATE_FOGENABLE - 1]) { - if (vertex_transformed) { - if (glThis->fogging != 0) { - glDisable(GL_FOG); - glThis->fogging = 0; - } - /* Now check if our fog_table still corresponds to the current vertex color. - Element '0x..00' is always the fog color as it corresponds to maximum fog intensity */ - if ((glThis->fog_table[0 * 0x10000 + 0x0000] != ((This->state_block.render_state[D3DRENDERSTATE_FOGCOLOR - 1] >> 0) & 0xFF)) || - (glThis->fog_table[1 * 0x10000 + 0x0000] != ((This->state_block.render_state[D3DRENDERSTATE_FOGCOLOR - 1] >> 8) & 0xFF)) || - (glThis->fog_table[2 * 0x10000 + 0x0000] != ((This->state_block.render_state[D3DRENDERSTATE_FOGCOLOR - 1] >> 16) & 0xFF))) { - /* We need to rebuild our fog table.... */ - build_fog_table(glThis->fog_table, This->state_block.render_state[D3DRENDERSTATE_FOGCOLOR - 1]); - } - } else { - if (This->state_block.render_state[D3DRENDERSTATE_FOGTABLEMODE - 1] != D3DFOG_NONE) { - switch (This->state_block.render_state[D3DRENDERSTATE_FOGTABLEMODE - 1]) { - case D3DFOG_LINEAR: glFogi(GL_FOG_MODE, GL_LINEAR); break; - case D3DFOG_EXP: glFogi(GL_FOG_MODE, GL_EXP); break; - case D3DFOG_EXP2: glFogi(GL_FOG_MODE, GL_EXP2); break; - } - if (vertex_lit == FALSE) { - glFogf(GL_FOG_START, *(float*)&This->state_block.render_state[D3DRENDERSTATE_FOGSTART - 1]); - glFogf(GL_FOG_END, *(float*)&This->state_block.render_state[D3DRENDERSTATE_FOGEND - 1]); - } else { - /* Special case of 'pixel fog' */ - glFogf(GL_FOG_START, ZfromZproj(This, *(float*)&This->state_block.render_state[D3DRENDERSTATE_FOGSTART - 1])); - glFogf(GL_FOG_END, ZfromZproj(This, *(float*)&This->state_block.render_state[D3DRENDERSTATE_FOGEND - 1])); - } - if (glThis->fogging == 0) { - glEnable(GL_FOG); - glThis->fogging = 1; - } - } else { - if (glThis->fogging != 0) { - glDisable(GL_FOG); - glThis->fogging = 0; - } - } - } - } else { - if (glThis->fogging != 0) { - glDisable(GL_FOG); - glThis->fogging = 0; - } - } - - /* Handle the 'no-normal' case */ - if ((vertex_lit == FALSE) && This->state_block.render_state[D3DRENDERSTATE_LIGHTING - 1]) { - if (glThis->lighting == 0) { - glEnable(GL_LIGHTING); - glThis->lighting = 1; - } - } else { - if (glThis->lighting != 0) { - glDisable(GL_LIGHTING); - glThis->lighting = 0; - } - } - - /* Handle the code for pre-vertex material properties */ - if (vertex_transformed == FALSE) { - if (This->state_block.render_state[D3DRENDERSTATE_LIGHTING - 1] && - This->state_block.render_state[D3DRENDERSTATE_COLORVERTEX - 1]) { - if ((This->state_block.render_state[D3DRENDERSTATE_DIFFUSEMATERIALSOURCE - 1] != D3DMCS_MATERIAL) || - (This->state_block.render_state[D3DRENDERSTATE_AMBIENTMATERIALSOURCE - 1] != D3DMCS_MATERIAL) || - (This->state_block.render_state[D3DRENDERSTATE_EMISSIVEMATERIALSOURCE - 1] != D3DMCS_MATERIAL) || - (This->state_block.render_state[D3DRENDERSTATE_SPECULARMATERIALSOURCE - 1] != D3DMCS_MATERIAL)) { - glEnable(GL_COLOR_MATERIAL); - } - } - } -} - - -inline static void draw_primitive(IDirect3DDeviceImpl *This, DWORD maxvert, WORD *index, - D3DVERTEXTYPE d3dvt, D3DPRIMITIVETYPE d3dpt, void *lpvertex) -{ - D3DDRAWPRIMITIVESTRIDEDDATA strided; - - switch (d3dvt) { - case D3DVT_VERTEX: { - strided.position.lpvData = &((D3DVERTEX *) lpvertex)->u1.x; - strided.position.dwStride = sizeof(D3DVERTEX); - strided.normal.lpvData = &((D3DVERTEX *) lpvertex)->u4.nx; - strided.normal.dwStride = sizeof(D3DVERTEX); - strided.textureCoords[0].lpvData = &((D3DVERTEX *) lpvertex)->u7.tu; - strided.textureCoords[0].dwStride = sizeof(D3DVERTEX); - draw_primitive_strided(This, d3dpt, D3DFVF_VERTEX, &strided, 0 /* Unused */, index, maxvert, 0 /* Unused */); - } break; - - case D3DVT_LVERTEX: { - strided.position.lpvData = &((D3DLVERTEX *) lpvertex)->u1.x; - strided.position.dwStride = sizeof(D3DLVERTEX); - strided.diffuse.lpvData = &((D3DLVERTEX *) lpvertex)->u4.color; - strided.diffuse.dwStride = sizeof(D3DLVERTEX); - strided.specular.lpvData = &((D3DLVERTEX *) lpvertex)->u5.specular; - strided.specular.dwStride = sizeof(D3DLVERTEX); - strided.textureCoords[0].lpvData = &((D3DLVERTEX *) lpvertex)->u6.tu; - strided.textureCoords[0].dwStride = sizeof(D3DLVERTEX); - draw_primitive_strided(This, d3dpt, D3DFVF_LVERTEX, &strided, 0 /* Unused */, index, maxvert, 0 /* Unused */); - } break; - - case D3DVT_TLVERTEX: { - strided.position.lpvData = &((D3DTLVERTEX *) lpvertex)->u1.sx; - strided.position.dwStride = sizeof(D3DTLVERTEX); - strided.diffuse.lpvData = &((D3DTLVERTEX *) lpvertex)->u5.color; - strided.diffuse.dwStride = sizeof(D3DTLVERTEX); - strided.specular.lpvData = &((D3DTLVERTEX *) lpvertex)->u6.specular; - strided.specular.dwStride = sizeof(D3DTLVERTEX); - strided.textureCoords[0].lpvData = &((D3DTLVERTEX *) lpvertex)->u7.tu; - strided.textureCoords[0].dwStride = sizeof(D3DTLVERTEX); - draw_primitive_strided(This, d3dpt, D3DFVF_TLVERTEX, &strided, 0 /* Unused */, index, maxvert, 0 /* Unused */); - } break; - - default: - FIXME("Unhandled vertex type %08x\n", d3dvt); - break; - } -} - -HRESULT WINAPI -GL_IDirect3DDeviceImpl_2_DrawPrimitive(LPDIRECT3DDEVICE2 iface, - D3DPRIMITIVETYPE d3dptPrimitiveType, - D3DVERTEXTYPE d3dvtVertexType, - LPVOID lpvVertices, - DWORD dwVertexCount, - DWORD dwFlags) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface); - - TRACE("(%p/%p)->(%08x,%08x,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwFlags); - if (TRACE_ON(ddraw)) { - TRACE(" - flags : "); dump_DPFLAGS(dwFlags); - } - - draw_primitive(This, dwVertexCount, NULL, d3dvtVertexType, d3dptPrimitiveType, lpvVertices); - - return DD_OK; -} - -HRESULT WINAPI -GL_IDirect3DDeviceImpl_2_DrawIndexedPrimitive(LPDIRECT3DDEVICE2 iface, - D3DPRIMITIVETYPE d3dptPrimitiveType, - D3DVERTEXTYPE d3dvtVertexType, - LPVOID lpvVertices, - DWORD dwVertexCount, - LPWORD dwIndices, - DWORD dwIndexCount, - DWORD dwFlags) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface); - TRACE("(%p/%p)->(%08x,%08x,%p,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwIndices, dwIndexCount, dwFlags); - if (TRACE_ON(ddraw)) { - TRACE(" - flags : "); dump_DPFLAGS(dwFlags); - } - - draw_primitive(This, dwIndexCount, dwIndices, d3dvtVertexType, d3dptPrimitiveType, lpvVertices); - - return DD_OK; -} - -HRESULT WINAPI -GL_IDirect3DDeviceImpl_1_CreateExecuteBuffer(LPDIRECT3DDEVICE iface, - LPD3DEXECUTEBUFFERDESC lpDesc, - LPDIRECT3DEXECUTEBUFFER* lplpDirect3DExecuteBuffer, - IUnknown* pUnkOuter) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface); - IDirect3DExecuteBufferImpl *ret; - HRESULT ret_value; - - TRACE("(%p/%p)->(%p,%p,%p)\n", This, iface, lpDesc, lplpDirect3DExecuteBuffer, pUnkOuter); - - ret_value = d3dexecutebuffer_create(&ret, This->d3d, This, lpDesc); - *lplpDirect3DExecuteBuffer = ICOM_INTERFACE(ret, IDirect3DExecuteBuffer); - - TRACE(" returning %p.\n", *lplpDirect3DExecuteBuffer); - - return ret_value; -} - -static void flush_zbuffer_to_GL(IDirect3DDeviceImpl *d3d_dev, LPCRECT pRect, IDirectDrawSurfaceImpl *surf) { - static BOOLEAN first = TRUE; - IDirect3DDeviceGLImpl* gl_d3d_dev = (IDirect3DDeviceGLImpl*) d3d_dev; - unsigned int row; - GLenum type; - - if (first) { - MESSAGE("Warning : application does direct locking of ZBuffer - expect slowdowns on many GL implementations :-)\n"); - first = FALSE; - } - - TRACE("flushing ZBuffer back to GL\n"); - - if (gl_d3d_dev->transform_state != GL_TRANSFORM_ORTHO) { - gl_d3d_dev->transform_state = GL_TRANSFORM_ORTHO; - d3ddevice_set_ortho(d3d_dev); - } - - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - if (gl_d3d_dev->depth_test == 0) glEnable(GL_DEPTH_TEST); - if (d3d_dev->state_block.render_state[D3DRENDERSTATE_ZFUNC - 1] != D3DCMP_ALWAYS) glDepthFunc(GL_ALWAYS); - glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - - /* This loop here is to prevent using PixelZoom that may be unoptimized for the 1.0 / -1.0 case - in some drivers... - */ - switch (surf->surface_desc.u4.ddpfPixelFormat.u1.dwZBufferBitDepth) { - case 16: type = GL_UNSIGNED_SHORT; break; - case 32: type = GL_UNSIGNED_INT; break; - default: FIXME("Unhandled ZBuffer format !\n"); goto restore_state; - } - - for (row = 0; row < surf->surface_desc.dwHeight; row++) { - /* glRasterPos3d(0.0, row + 1.0, 0.5); */ - glRasterPos2i(0, row + 1); - glDrawPixels(surf->surface_desc.dwWidth, 1, GL_DEPTH_COMPONENT, type, - ((unsigned char *) surf->surface_desc.lpSurface) + (row * surf->surface_desc.u1.lPitch)); - } - - restore_state: - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - if (d3d_dev->state_block.render_state[D3DRENDERSTATE_ZFUNC - 1] != D3DCMP_ALWAYS) - glDepthFunc(convert_D3D_compare_to_GL(d3d_dev->state_block.render_state[D3DRENDERSTATE_ZFUNC - 1])); - if (gl_d3d_dev->depth_test == 0) glDisable(GL_DEPTH_TEST); -} - -/* These are the various handler used in the generic path */ -inline static void handle_xyz(D3DVALUE *coords) { - glVertex3fv(coords); -} -inline static void handle_xyzrhw(D3DVALUE *coords) { - if ((coords[3] < 1e-8) && (coords[3] > -1e-8)) - glVertex3fv(coords); - else { - GLfloat w = 1.0 / coords[3]; - - glVertex4f(coords[0] * w, - coords[1] * w, - coords[2] * w, - w); - } -} -inline static void handle_normal(D3DVALUE *coords) { - glNormal3fv(coords); -} - -inline static void handle_diffuse_base(STATEBLOCK *sb, DWORD *color) { - if (sb->render_state[D3DRENDERSTATE_ALPHATESTENABLE - 1] || - sb->render_state[D3DRENDERSTATE_ALPHABLENDENABLE - 1]) { - glColor4ub((*color >> 16) & 0xFF, - (*color >> 8) & 0xFF, - (*color >> 0) & 0xFF, - (*color >> 24) & 0xFF); - } else { - glColor3ub((*color >> 16) & 0xFF, - (*color >> 8) & 0xFF, - (*color >> 0) & 0xFF); - } -} - -inline static void handle_specular_base(STATEBLOCK *sb, DWORD *color) { - glColor4ub((*color >> 16) & 0xFF, - (*color >> 8) & 0xFF, - (*color >> 0) & 0xFF, - (*color >> 24) & 0xFF); /* No idea if the alpha field is really used.. */ -} - -inline static void handle_diffuse(STATEBLOCK *sb, DWORD *color, BOOLEAN lighted) { - if ((lighted == FALSE) && - sb->render_state[D3DRENDERSTATE_LIGHTING - 1] && - sb->render_state[D3DRENDERSTATE_COLORVERTEX - 1]) { - if (sb->render_state[D3DRENDERSTATE_DIFFUSEMATERIALSOURCE - 1] == D3DMCS_COLOR1) { - glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); - handle_diffuse_base(sb, color); - } - if (sb->render_state[D3DRENDERSTATE_AMBIENTMATERIALSOURCE - 1] == D3DMCS_COLOR1) { - glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT); - handle_diffuse_base(sb, color); - } - if ((sb->render_state[D3DRENDERSTATE_SPECULARMATERIALSOURCE - 1] == D3DMCS_COLOR1) && - sb->render_state[D3DRENDERSTATE_SPECULARENABLE - 1]) { - glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR); - handle_diffuse_base(sb, color); - } - if (sb->render_state[D3DRENDERSTATE_EMISSIVEMATERIALSOURCE - 1] == D3DMCS_COLOR1) { - glColorMaterial(GL_FRONT_AND_BACK, GL_EMISSION); - handle_diffuse_base(sb, color); - } - } else { - handle_diffuse_base(sb, color); - } -} - -inline static void handle_specular(STATEBLOCK *sb, DWORD *color, BOOLEAN lighted) { - if ((lighted == FALSE) && - sb->render_state[D3DRENDERSTATE_LIGHTING - 1] && - sb->render_state[D3DRENDERSTATE_COLORVERTEX - 1]) { - if (sb->render_state[D3DRENDERSTATE_DIFFUSEMATERIALSOURCE - 1] == D3DMCS_COLOR2) { - glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); - handle_specular_base(sb, color); - } - if (sb->render_state[D3DRENDERSTATE_AMBIENTMATERIALSOURCE - 1] == D3DMCS_COLOR2) { - glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT); - handle_specular_base(sb, color); - } - if ((sb->render_state[D3DRENDERSTATE_SPECULARMATERIALSOURCE - 1] == D3DMCS_COLOR2) && - sb->render_state[D3DRENDERSTATE_SPECULARENABLE - 1]) { - glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR); - handle_specular_base(sb, color); - } - if (sb->render_state[D3DRENDERSTATE_EMISSIVEMATERIALSOURCE - 1] == D3DMCS_COLOR2) { - glColorMaterial(GL_FRONT_AND_BACK, GL_EMISSION); - handle_specular_base(sb, color); - } - } - /* No else here as we do not know how to handle 'specular' on its own in any case.. */ -} - -inline static void handle_diffuse_and_specular(STATEBLOCK *sb, BYTE *fog_table, DWORD *color_d, DWORD *color_s, BOOLEAN lighted) { - if (lighted) { - DWORD color = *color_d; - if (sb->render_state[D3DRENDERSTATE_FOGENABLE - 1]) { - /* Special case where the specular value is used to do fogging */ - BYTE fog_intensity = *color_s >> 24; /* The alpha value of the specular component is the fog 'intensity' for this vertex */ - color &= 0xFF000000; /* Only keep the alpha component */ - color |= fog_table[((*color_d >> 0) & 0xFF) << 8 | fog_intensity] << 0; - color |= fog_table[((*color_d >> 8) & 0xFF) << 8 | fog_intensity] << 8; - color |= fog_table[((*color_d >> 16) & 0xFF) << 8 | fog_intensity] << 16; - } - if (sb->render_state[D3DRENDERSTATE_SPECULARENABLE - 1]) { - /* Standard specular value in transformed mode. TODO */ - } - handle_diffuse_base(sb, &color); - } else { - if (sb->render_state[D3DRENDERSTATE_LIGHTING - 1]) { - handle_diffuse(sb, color_d, FALSE); - handle_specular(sb, color_s, FALSE); - } else { - /* In that case, only put the diffuse color... */ - handle_diffuse_base(sb, color_d); - } - } -} - -static void handle_texture(DWORD size, const D3DVALUE *coords) { - switch (size) { - case 1: glTexCoord1fv(coords); break; - case 2: glTexCoord2fv(coords); break; - case 3: glTexCoord3fv(coords); break; - case 4: glTexCoord4fv(coords); break; - } -} - -inline static void handle_textures(DWORD size, const D3DVALUE *coords, int tex_stage) { - if (GL_extensions.max_texture_units > 0) { - GL_extensions.glMultiTexCoord[size - 1](GL_TEXTURE0_WINE + tex_stage, coords); - } else { - if (tex_stage == 0) handle_texture(size, coords); - } -} - -static void draw_primitive_strided(IDirect3DDeviceImpl *This, - D3DPRIMITIVETYPE d3dptPrimitiveType, - DWORD d3dvtVertexType, - LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData, - DWORD dwVertexCount, - LPWORD dwIndices, - DWORD dwIndexCount, - DWORD dwFlags) -{ - BOOLEAN vertex_lighted = FALSE; - IDirect3DDeviceGLImpl* glThis = (IDirect3DDeviceGLImpl*) This; - int num_active_stages = 0; - int num_tex_index = GET_TEXCOUNT_FROM_FVF(d3dvtVertexType); - BOOL reenable_depth_test = FALSE; - - /* I put the trace before the various locks... So as to better understand where locks occur :-) */ - if (TRACE_ON(ddraw)) { - TRACE(" Vertex format : "); dump_flexible_vertex(d3dvtVertexType); - } - - /* This is to prevent 'thread contention' between a thread locking the device and another - doing 3D display on it... */ - EnterCriticalSection(&(This->crit)); - - ENTER_GL(); - if (glThis->state[WINE_GL_BUFFER_BACK] == SURFACE_MEMORY_DIRTY) { - This->flush_to_framebuffer(This, &(glThis->lock_rect[WINE_GL_BUFFER_BACK]), glThis->lock_surf[WINE_GL_BUFFER_BACK]); - } - glThis->state[WINE_GL_BUFFER_BACK] = SURFACE_GL; - - if (This->current_zbuffer == NULL) { - /* Search for an attached ZBuffer */ - static const DDSCAPS2 zbuf_caps = { DDSCAPS_ZBUFFER, 0, 0, 0 }; - LPDIRECTDRAWSURFACE7 zbuf; - HRESULT hr; - - hr = IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(This->surface, IDirectDrawSurface7), - (DDSCAPS2 *) &zbuf_caps, &zbuf); - if (SUCCEEDED(hr)) { - This->current_zbuffer = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, zbuf); - IDirectDrawSurface7_Release(zbuf); - } else if (glThis->depth_test) { - glDisable(GL_DEPTH_TEST); - reenable_depth_test = TRUE; - } - } - if (This->current_zbuffer != NULL) { - if (This->current_zbuffer->get_dirty_status(This->current_zbuffer, NULL)) { - flush_zbuffer_to_GL(This, NULL, This->current_zbuffer); - } - } - - if ( ((d3dvtVertexType & D3DFVF_POSITION_MASK) != D3DFVF_XYZ) || - ((d3dvtVertexType & D3DFVF_NORMAL) == 0) ) - vertex_lighted = TRUE; - - /* Compute the number of active texture stages and set the various texture parameters */ - num_active_stages = draw_primitive_handle_textures(This); - - /* And restore to handle '0' in the case we use glTexCoord calls */ - if (glThis->current_active_tex_unit != GL_TEXTURE0_WINE) { - GL_extensions.glActiveTexture(GL_TEXTURE0_WINE); - glThis->current_active_tex_unit = GL_TEXTURE0_WINE; - } - - draw_primitive_handle_GL_state(This, - (d3dvtVertexType & D3DFVF_POSITION_MASK) != D3DFVF_XYZ, - vertex_lighted); - - /* First, see if we can use the OpenGL vertex arrays... This is very limited - for now to some 'special' cases where we can do a direct mapping between D3D - types and GL types. - - Note: in the future all calls will go through vertex arrays but the arrays - will be generated by this function. - - Note2: colours cannot be mapped directly because they are stored as BGRA in memory - (ie not as an array of R, G, B, A as OpenGL does it but as a LWORD 0xAARRGGBB - which, as we are little indian, gives a B, G, R, A storage in memory. - */ - if (((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) && /* Standard XYZ vertices */ - ((d3dvtVertexType & (D3DFVF_DIFFUSE|D3DFVF_SPECULAR)) == 0)) { - int tex_stage; - TRACE(" using GL vertex arrays for performance !\n"); - /* First, the vertices (we are sure we have some :-) */ - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, lpD3DDrawPrimStrideData->position.dwStride, lpD3DDrawPrimStrideData->position.lpvData); - /* Then the normals */ - if (d3dvtVertexType & D3DFVF_NORMAL) { - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(GL_FLOAT, lpD3DDrawPrimStrideData->normal.dwStride, lpD3DDrawPrimStrideData->normal.lpvData); - } - /* Then the diffuse colour */ - if (d3dvtVertexType & D3DFVF_DIFFUSE) { - glEnableClientState(GL_COLOR_ARRAY); - glColorPointer(3, GL_UNSIGNED_BYTE, lpD3DDrawPrimStrideData->normal.dwStride, - ((char *) lpD3DDrawPrimStrideData->diffuse.lpvData)); - } - /* Then the various textures */ - for (tex_stage = 0; tex_stage < num_active_stages; tex_stage++) { - int tex_index = This->state_block.texture_stage_state[tex_stage][D3DTSS_TEXCOORDINDEX - 1] & 0x0000FFFF; - if (tex_index >= num_tex_index) { - WARN("Default texture coordinate not handled in the vertex array path !!!\n"); - tex_index = num_tex_index - 1; - } - if (GL_extensions.glClientActiveTexture) { - GL_extensions.glClientActiveTexture(GL_TEXTURE0_WINE + tex_stage); - } - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, tex_index), GL_FLOAT, lpD3DDrawPrimStrideData->textureCoords[tex_index].dwStride, - lpD3DDrawPrimStrideData->textureCoords[tex_index].lpvData); - } - if (dwIndices != NULL) { - glDrawElements(convert_D3D_ptype_to_GL(d3dptPrimitiveType), dwIndexCount, GL_UNSIGNED_SHORT, dwIndices); - } else { - glDrawArrays(convert_D3D_ptype_to_GL(d3dptPrimitiveType), 0, dwIndexCount); - } - glDisableClientState(GL_VERTEX_ARRAY); - if (d3dvtVertexType & D3DFVF_NORMAL) { - glDisableClientState(GL_NORMAL_ARRAY); - } - if (d3dvtVertexType & D3DFVF_DIFFUSE) { - glDisableClientState(GL_COLOR_ARRAY); - } - for (tex_stage = 0; tex_stage < num_active_stages; tex_stage++) { - if (GL_extensions.glClientActiveTexture) { - GL_extensions.glClientActiveTexture(GL_TEXTURE0_WINE + tex_stage); - } - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - } - } else { - glBegin(convert_D3D_ptype_to_GL(d3dptPrimitiveType)); - - /* Some fast paths first before the generic case.... */ - if ((d3dvtVertexType == D3DFVF_VERTEX) && (num_active_stages <= 1)) { - unsigned int index; - - for (index = 0; index < dwIndexCount; index++) { - int i = (dwIndices == NULL) ? index : dwIndices[index]; - D3DVALUE *normal = - (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->normal.lpvData) + i * lpD3DDrawPrimStrideData->normal.dwStride); - D3DVALUE *tex_coord = - (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[0].lpvData) + i * lpD3DDrawPrimStrideData->textureCoords[0].dwStride); - D3DVALUE *position = - (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride); - - handle_normal(normal); - handle_texture(2, tex_coord); - handle_xyz(position); - - TRACE_(ddraw_geom)(" %f %f %f / %f %f %f (%f %f)\n", - position[0], position[1], position[2], - normal[0], normal[1], normal[2], - tex_coord[0], tex_coord[1]); - } - } else if ((d3dvtVertexType == D3DFVF_TLVERTEX) && (num_active_stages <= 1)) { - unsigned int index; - - for (index = 0; index < dwIndexCount; index++) { - int i = (dwIndices == NULL) ? index : dwIndices[index]; - DWORD *color_d = - (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride); - DWORD *color_s = - (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride); - D3DVALUE *tex_coord = - (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[0].lpvData) + i * lpD3DDrawPrimStrideData->textureCoords[0].dwStride); - D3DVALUE *position = - (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride); - - handle_diffuse_and_specular(&(This->state_block), glThis->fog_table, color_d, color_s, TRUE); - handle_texture(2, tex_coord); - handle_xyzrhw(position); - - TRACE_(ddraw_geom)(" %f %f %f %f / %02lx %02lx %02lx %02lx - %02lx %02lx %02lx %02lx (%f %f)\n", - position[0], position[1], position[2], position[3], - (*color_d >> 16) & 0xFF, - (*color_d >> 8) & 0xFF, - (*color_d >> 0) & 0xFF, - (*color_d >> 24) & 0xFF, - (*color_s >> 16) & 0xFF, - (*color_s >> 8) & 0xFF, - (*color_s >> 0) & 0xFF, - (*color_s >> 24) & 0xFF, - tex_coord[0], tex_coord[1]); - } - } else if (((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) || - ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW)) { - /* This is the 'slow path' but that should support all possible vertex formats out there... - Note that people should write a fast path for all vertex formats out there... - */ - unsigned int index; - /* static const D3DVALUE no_index[] = { 0.0, 0.0, 0.0, 0.0 }; */ - - for (index = 0; index < dwIndexCount; index++) { - int i = (dwIndices == NULL) ? index : dwIndices[index]; - int tex_stage; - - if (d3dvtVertexType & D3DFVF_NORMAL) { - D3DVALUE *normal = - (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->normal.lpvData) + i * lpD3DDrawPrimStrideData->normal.dwStride); - handle_normal(normal); - } - if ((d3dvtVertexType & (D3DFVF_DIFFUSE|D3DFVF_SPECULAR)) == (D3DFVF_DIFFUSE|D3DFVF_SPECULAR)) { - DWORD *color_d = - (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride); - DWORD *color_s = - (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride); - handle_diffuse_and_specular(&(This->state_block), glThis->fog_table, color_d, color_s, vertex_lighted); - } else { - if (d3dvtVertexType & D3DFVF_SPECULAR) { - DWORD *color_s = - (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride); - handle_specular(&(This->state_block), color_s, vertex_lighted); - } else if (d3dvtVertexType & D3DFVF_DIFFUSE) { - DWORD *color_d = - (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride); - handle_diffuse(&(This->state_block), color_d, vertex_lighted); - } - } - - for (tex_stage = 0; tex_stage < num_active_stages; tex_stage++) { - int tex_index = This->state_block.texture_stage_state[tex_stage][D3DTSS_TEXCOORDINDEX - 1] & 0x0000FFFF; - D3DVALUE *tex_coord; - - if (tex_index >= num_tex_index) { - /* This will have to be checked on Windows. RealMYST uses this feature and I would find it more - * logical to re-use the index of the previous stage than a default index of '0'. - */ - - /* handle_textures((const D3DVALUE *) no_index, tex_stage); */ - tex_index = num_tex_index - 1; - } - tex_coord = (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[tex_index].lpvData) + - i * lpD3DDrawPrimStrideData->textureCoords[tex_index].dwStride); - handle_textures(GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, tex_index), tex_coord, tex_stage); - } - - if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) { - D3DVALUE *position = - (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride); - handle_xyz(position); - } else if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW) { - D3DVALUE *position = - (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride); - handle_xyzrhw(position); - } - - if (TRACE_ON(ddraw_geom)) { - unsigned int tex_index; - - if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) { - D3DVALUE *position = - (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride); - TRACE_(ddraw_geom)(" %f %f %f", position[0], position[1], position[2]); - } else if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW) { - D3DVALUE *position = - (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->position.lpvData) + i * lpD3DDrawPrimStrideData->position.dwStride); - TRACE_(ddraw_geom)(" %f %f %f %f", position[0], position[1], position[2], position[3]); - } - if (d3dvtVertexType & D3DFVF_NORMAL) { - D3DVALUE *normal = - (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->normal.lpvData) + i * lpD3DDrawPrimStrideData->normal.dwStride); - TRACE_(ddraw_geom)(" / %f %f %f", normal[0], normal[1], normal[2]); - } - if (d3dvtVertexType & D3DFVF_DIFFUSE) { - DWORD *color_d = - (DWORD *) (((char *) lpD3DDrawPrimStrideData->diffuse.lpvData) + i * lpD3DDrawPrimStrideData->diffuse.dwStride); - TRACE_(ddraw_geom)(" / %02lx %02lx %02lx %02lx", - (*color_d >> 16) & 0xFF, - (*color_d >> 8) & 0xFF, - (*color_d >> 0) & 0xFF, - (*color_d >> 24) & 0xFF); - } - if (d3dvtVertexType & D3DFVF_SPECULAR) { - DWORD *color_s = - (DWORD *) (((char *) lpD3DDrawPrimStrideData->specular.lpvData) + i * lpD3DDrawPrimStrideData->specular.dwStride); - TRACE_(ddraw_geom)(" / %02lx %02lx %02lx %02lx", - (*color_s >> 16) & 0xFF, - (*color_s >> 8) & 0xFF, - (*color_s >> 0) & 0xFF, - (*color_s >> 24) & 0xFF); - } - for (tex_index = 0; tex_index < GET_TEXCOUNT_FROM_FVF(d3dvtVertexType); tex_index++) { - D3DVALUE *tex_coord = - (D3DVALUE *) (((char *) lpD3DDrawPrimStrideData->textureCoords[tex_index].lpvData) + - i * lpD3DDrawPrimStrideData->textureCoords[tex_index].dwStride); - switch (GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, tex_index)) { - case 1: TRACE_(ddraw_geom)(" / %f", tex_coord[0]); break; - case 2: TRACE_(ddraw_geom)(" / %f %f", tex_coord[0], tex_coord[1]); break; - case 3: TRACE_(ddraw_geom)(" / %f %f %f", tex_coord[0], tex_coord[1], tex_coord[2]); break; - case 4: TRACE_(ddraw_geom)(" / %f %f %f %f", tex_coord[0], tex_coord[1], tex_coord[2], tex_coord[3]); break; - default: TRACE_(ddraw_geom)("Invalid texture size (%ld) !!!", GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, tex_index)); break; - } - } - TRACE_(ddraw_geom)("\n"); - } - } - } else { - ERR(" matrix weighting not handled yet....\n"); - } - - glEnd(); - } - - /* Whatever the case, disable the color material stuff */ - glDisable(GL_COLOR_MATERIAL); - - if (reenable_depth_test) - glEnable(GL_DEPTH_TEST); - - LEAVE_GL(); - TRACE("End\n"); - - LeaveCriticalSection(&(This->crit)); -} - -HRESULT WINAPI -GL_IDirect3DDeviceImpl_7_3T_DrawPrimitive(LPDIRECT3DDEVICE7 iface, - D3DPRIMITIVETYPE d3dptPrimitiveType, - DWORD d3dvtVertexType, - LPVOID lpvVertices, - DWORD dwVertexCount, - DWORD dwFlags) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - D3DDRAWPRIMITIVESTRIDEDDATA strided; - - TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwFlags); - if (TRACE_ON(ddraw)) { - TRACE(" - flags : "); dump_DPFLAGS(dwFlags); - } - - convert_FVF_to_strided_data(d3dvtVertexType, lpvVertices, &strided, 0); - draw_primitive_strided(This, d3dptPrimitiveType, d3dvtVertexType, &strided, dwVertexCount, NULL, dwVertexCount, dwFlags); - - return DD_OK; -} - -HRESULT WINAPI -GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitive(LPDIRECT3DDEVICE7 iface, - D3DPRIMITIVETYPE d3dptPrimitiveType, - DWORD d3dvtVertexType, - LPVOID lpvVertices, - DWORD dwVertexCount, - LPWORD dwIndices, - DWORD dwIndexCount, - DWORD dwFlags) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - D3DDRAWPRIMITIVESTRIDEDDATA strided; - - TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwIndices, dwIndexCount, dwFlags); - if (TRACE_ON(ddraw)) { - TRACE(" - flags : "); dump_DPFLAGS(dwFlags); - } - - convert_FVF_to_strided_data(d3dvtVertexType, lpvVertices, &strided, 0); - draw_primitive_strided(This, d3dptPrimitiveType, d3dvtVertexType, &strided, dwVertexCount, dwIndices, dwIndexCount, dwFlags); - - return DD_OK; -} - -HRESULT WINAPI -GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveStrided(LPDIRECT3DDEVICE7 iface, - D3DPRIMITIVETYPE d3dptPrimitiveType, - DWORD dwVertexType, - LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData, - DWORD dwVertexCount, - DWORD dwFlags) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - - TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, dwVertexCount, dwFlags); - if (TRACE_ON(ddraw)) { - TRACE(" - flags : "); dump_DPFLAGS(dwFlags); - } - draw_primitive_strided(This, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, dwVertexCount, NULL, dwVertexCount, dwFlags); - - return DD_OK; -} - -HRESULT WINAPI -GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveStrided(LPDIRECT3DDEVICE7 iface, - D3DPRIMITIVETYPE d3dptPrimitiveType, - DWORD dwVertexType, - LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData, - DWORD dwVertexCount, - LPWORD lpIndex, - DWORD dwIndexCount, - DWORD dwFlags) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - - TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, dwVertexCount, lpIndex, dwIndexCount, dwFlags); - if (TRACE_ON(ddraw)) { - TRACE(" - flags : "); dump_DPFLAGS(dwFlags); - } - - draw_primitive_strided(This, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, dwVertexCount, lpIndex, dwIndexCount, dwFlags); - - return DD_OK; -} - -HRESULT WINAPI -GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveVB(LPDIRECT3DDEVICE7 iface, - D3DPRIMITIVETYPE d3dptPrimitiveType, - LPDIRECT3DVERTEXBUFFER7 lpD3DVertexBuf, - DWORD dwStartVertex, - DWORD dwNumVertices, - DWORD dwFlags) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - IDirect3DVertexBufferImpl *vb_impl = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, lpD3DVertexBuf); - D3DDRAWPRIMITIVESTRIDEDDATA strided; - - TRACE("(%p/%p)->(%08x,%p,%08lx,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, lpD3DVertexBuf, dwStartVertex, dwNumVertices, dwFlags); - if (TRACE_ON(ddraw)) { - TRACE(" - flags : "); dump_DPFLAGS(dwFlags); - } - - if (vb_impl->processed) { - IDirect3DVertexBufferGLImpl *vb_glimp = (IDirect3DVertexBufferGLImpl *) vb_impl; - IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This; - - glThis->transform_state = GL_TRANSFORM_VERTEXBUFFER; - This->set_matrices(This, VIEWMAT_CHANGED|WORLDMAT_CHANGED|PROJMAT_CHANGED, - &(vb_glimp->world_mat), &(vb_glimp->view_mat), &(vb_glimp->proj_mat)); - - convert_FVF_to_strided_data(vb_glimp->dwVertexTypeDesc, vb_glimp->vertices, &strided, dwStartVertex); - draw_primitive_strided(This, d3dptPrimitiveType, vb_glimp->dwVertexTypeDesc, &strided, dwNumVertices, NULL, dwNumVertices, dwFlags); - - } else { - convert_FVF_to_strided_data(vb_impl->desc.dwFVF, vb_impl->vertices, &strided, dwStartVertex); - draw_primitive_strided(This, d3dptPrimitiveType, vb_impl->desc.dwFVF, &strided, dwNumVertices, NULL, dwNumVertices, dwFlags); - } - - return DD_OK; -} - -HRESULT WINAPI -GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveVB(LPDIRECT3DDEVICE7 iface, - D3DPRIMITIVETYPE d3dptPrimitiveType, - LPDIRECT3DVERTEXBUFFER7 lpD3DVertexBuf, - DWORD dwStartVertex, - DWORD dwNumVertices, - LPWORD lpwIndices, - DWORD dwIndexCount, - DWORD dwFlags) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - IDirect3DVertexBufferImpl *vb_impl = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, lpD3DVertexBuf); - D3DDRAWPRIMITIVESTRIDEDDATA strided; - - TRACE("(%p/%p)->(%08x,%p,%08lx,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, lpD3DVertexBuf, dwStartVertex, dwNumVertices, lpwIndices, dwIndexCount, dwFlags); - if (TRACE_ON(ddraw)) { - TRACE(" - flags : "); dump_DPFLAGS(dwFlags); - } - - if (vb_impl->processed) { - IDirect3DVertexBufferGLImpl *vb_glimp = (IDirect3DVertexBufferGLImpl *) vb_impl; - IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This; - - glThis->transform_state = GL_TRANSFORM_VERTEXBUFFER; - This->set_matrices(This, VIEWMAT_CHANGED|WORLDMAT_CHANGED|PROJMAT_CHANGED, - &(vb_glimp->world_mat), &(vb_glimp->view_mat), &(vb_glimp->proj_mat)); - - convert_FVF_to_strided_data(vb_glimp->dwVertexTypeDesc, vb_glimp->vertices, &strided, dwStartVertex); - draw_primitive_strided(This, d3dptPrimitiveType, vb_glimp->dwVertexTypeDesc, &strided, dwNumVertices, lpwIndices, dwIndexCount, dwFlags); - - } else { - convert_FVF_to_strided_data(vb_impl->desc.dwFVF, vb_impl->vertices, &strided, dwStartVertex); - draw_primitive_strided(This, d3dptPrimitiveType, vb_impl->desc.dwFVF, &strided, dwNumVertices, lpwIndices, dwIndexCount, dwFlags); - } - - return DD_OK; -} - -/* We need a static function for that to handle the 'special' case of 'SELECT_ARG2' */ -static BOOLEAN -handle_color_alpha_args(IDirect3DDeviceImpl *This, DWORD dwStage, D3DTEXTURESTAGESTATETYPE d3dTexStageStateType, DWORD dwState, D3DTEXTUREOP tex_op) -{ - BOOLEAN is_complement = FALSE; - BOOLEAN is_alpha_replicate = FALSE; - BOOLEAN handled = TRUE; - GLenum src; - BOOLEAN is_color = ((d3dTexStageStateType == D3DTSS_COLORARG1) || (d3dTexStageStateType == D3DTSS_COLORARG2)); - int num; - - if (is_color) { - if (d3dTexStageStateType == D3DTSS_COLORARG1) num = 0; - else if (d3dTexStageStateType == D3DTSS_COLORARG2) num = 1; - else { - handled = FALSE; - num = 0; - } - if (tex_op == D3DTOP_SELECTARG2) { - num = 1 - num; - } - } else { - if (d3dTexStageStateType == D3DTSS_ALPHAARG1) num = 0; - else if (d3dTexStageStateType == D3DTSS_ALPHAARG2) num = 1; - else { - handled = FALSE; - num = 0; - } - if (tex_op == D3DTOP_SELECTARG2) { - num = 1 - num; - } - } - - if (dwState & D3DTA_COMPLEMENT) { - is_complement = TRUE; - } - if (dwState & D3DTA_ALPHAREPLICATE) { - is_alpha_replicate = TRUE; - } - dwState &= D3DTA_SELECTMASK; - if ((dwStage == 0) && (dwState == D3DTA_CURRENT)) { - dwState = D3DTA_DIFFUSE; - } - - switch (dwState) { - case D3DTA_CURRENT: src = GL_PREVIOUS_EXT; break; - case D3DTA_DIFFUSE: src = GL_PRIMARY_COLOR_EXT; break; - case D3DTA_TEXTURE: src = GL_TEXTURE; break; - case D3DTA_TFACTOR: { - /* Get the constant value from the current rendering state */ - GLfloat color[4]; - DWORD col = This->state_block.render_state[D3DRENDERSTATE_TEXTUREFACTOR - 1]; - - color[0] = ((col >> 16) & 0xFF) / 255.0f; - color[1] = ((col >> 8) & 0xFF) / 255.0f; - color[2] = ((col >> 0) & 0xFF) / 255.0f; - color[3] = ((col >> 24) & 0xFF) / 255.0f; - glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color); - - src = GL_CONSTANT_EXT; - } break; - default: src = GL_TEXTURE; handled = FALSE; break; - } - - if (is_color) { - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT + num, src); - if (is_alpha_replicate) { - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT + num, is_complement ? GL_ONE_MINUS_SRC_ALPHA : GL_SRC_ALPHA); - } else { - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT + num, is_complement ? GL_ONE_MINUS_SRC_COLOR : GL_SRC_COLOR); - } - } else { - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT + num, src); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_EXT + num, is_complement ? GL_ONE_MINUS_SRC_ALPHA : GL_SRC_ALPHA); - } - - return handled; -} - -HRESULT WINAPI -GL_IDirect3DDeviceImpl_7_3T_SetTextureStageState(LPDIRECT3DDEVICE7 iface, - DWORD dwStage, - D3DTEXTURESTAGESTATETYPE d3dTexStageStateType, - DWORD dwState) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This; - const char *type; - DWORD prev_state; - GLenum unit; - - TRACE("(%p/%p)->(%08lx,%08x,%08lx)\n", This, iface, dwStage, d3dTexStageStateType, dwState); - - if (((GL_extensions.max_texture_units == 0) && (dwStage > 0)) || - ((GL_extensions.max_texture_units != 0) && (dwStage >= GL_extensions.max_texture_units))) { - return DD_OK; - } - - unit = GL_TEXTURE0_WINE + dwStage; - if (unit != glThis->current_active_tex_unit) { - GL_extensions.glActiveTexture(unit); - glThis->current_active_tex_unit = unit; - } - - switch (d3dTexStageStateType) { -#define GEN_CASE(a) case a: type = #a; break - GEN_CASE(D3DTSS_COLOROP); - GEN_CASE(D3DTSS_COLORARG1); - GEN_CASE(D3DTSS_COLORARG2); - GEN_CASE(D3DTSS_ALPHAOP); - GEN_CASE(D3DTSS_ALPHAARG1); - GEN_CASE(D3DTSS_ALPHAARG2); - GEN_CASE(D3DTSS_BUMPENVMAT00); - GEN_CASE(D3DTSS_BUMPENVMAT01); - GEN_CASE(D3DTSS_BUMPENVMAT10); - GEN_CASE(D3DTSS_BUMPENVMAT11); - GEN_CASE(D3DTSS_TEXCOORDINDEX); - GEN_CASE(D3DTSS_ADDRESS); - GEN_CASE(D3DTSS_ADDRESSU); - GEN_CASE(D3DTSS_ADDRESSV); - GEN_CASE(D3DTSS_BORDERCOLOR); - GEN_CASE(D3DTSS_MAGFILTER); - GEN_CASE(D3DTSS_MINFILTER); - GEN_CASE(D3DTSS_MIPFILTER); - GEN_CASE(D3DTSS_MIPMAPLODBIAS); - GEN_CASE(D3DTSS_MAXMIPLEVEL); - GEN_CASE(D3DTSS_MAXANISOTROPY); - GEN_CASE(D3DTSS_BUMPENVLSCALE); - GEN_CASE(D3DTSS_BUMPENVLOFFSET); - GEN_CASE(D3DTSS_TEXTURETRANSFORMFLAGS); -#undef GEN_CASE - default: type = "UNKNOWN"; - } - - /* Store the values in the state array */ - prev_state = This->state_block.texture_stage_state[dwStage][d3dTexStageStateType - 1]; - This->state_block.texture_stage_state[dwStage][d3dTexStageStateType - 1] = dwState; - /* Some special cases when one state modifies more than one... */ - if (d3dTexStageStateType == D3DTSS_ADDRESS) { - This->state_block.texture_stage_state[dwStage][D3DTSS_ADDRESSU - 1] = dwState; - This->state_block.texture_stage_state[dwStage][D3DTSS_ADDRESSV - 1] = dwState; - } - - ENTER_GL(); - - switch (d3dTexStageStateType) { - case D3DTSS_MINFILTER: - case D3DTSS_MIPFILTER: - if (TRACE_ON(ddraw)) { - if (d3dTexStageStateType == D3DTSS_MINFILTER) { - switch ((D3DTEXTUREMINFILTER) dwState) { - case D3DTFN_POINT: TRACE(" Stage type is : D3DTSS_MINFILTER => D3DTFN_POINT\n"); break; - case D3DTFN_LINEAR: TRACE(" Stage type is : D3DTSS_MINFILTER => D3DTFN_LINEAR\n"); break; - default: FIXME(" Unhandled stage type : D3DTSS_MINFILTER => %08lx\n", dwState); break; - } - } else { - switch ((D3DTEXTUREMIPFILTER) dwState) { - case D3DTFP_NONE: TRACE(" Stage type is : D3DTSS_MIPFILTER => D3DTFP_NONE\n"); break; - case D3DTFP_POINT: TRACE(" Stage type is : D3DTSS_MIPFILTER => D3DTFP_POINT\n"); break; - case D3DTFP_LINEAR: TRACE(" Stage type is : D3DTSS_MIPFILTER => D3DTFP_LINEAR\n"); break; - default: FIXME(" Unhandled stage type : D3DTSS_MIPFILTER => %08lx\n", dwState); break; - } - } - } - break; - - case D3DTSS_MAGFILTER: - if (TRACE_ON(ddraw)) { - switch ((D3DTEXTUREMAGFILTER) dwState) { - case D3DTFG_POINT: TRACE(" Stage type is : D3DTSS_MAGFILTER => D3DTFG_POINT\n"); break; - case D3DTFG_LINEAR: TRACE(" Stage type is : D3DTSS_MAGFILTER => D3DTFG_LINEAR\n"); break; - default: FIXME(" Unhandled stage type : D3DTSS_MAGFILTER => %08lx\n", dwState); break; - } - } - break; - - case D3DTSS_ADDRESS: - case D3DTSS_ADDRESSU: - case D3DTSS_ADDRESSV: { - switch ((D3DTEXTUREADDRESS) dwState) { - case D3DTADDRESS_WRAP: TRACE(" Stage type is : %s => D3DTADDRESS_WRAP\n", type); break; - case D3DTADDRESS_CLAMP: TRACE(" Stage type is : %s => D3DTADDRESS_CLAMP\n", type); break; - case D3DTADDRESS_BORDER: TRACE(" Stage type is : %s => D3DTADDRESS_BORDER\n", type); break; - case D3DTADDRESS_MIRROR: - if (GL_extensions.mirrored_repeat) { - TRACE(" Stage type is : %s => D3DTADDRESS_MIRROR\n", type); - } else { - FIXME(" Stage type is : %s => D3DTADDRESS_MIRROR - not supported by GL !\n", type); - } - break; - default: FIXME(" Unhandled stage type : %s => %08lx\n", type, dwState); break; - } - } break; - - case D3DTSS_ALPHAOP: - case D3DTSS_COLOROP: { - int scale = 1; - GLenum parm = (d3dTexStageStateType == D3DTSS_ALPHAOP) ? GL_COMBINE_ALPHA_EXT : GL_COMBINE_RGB_EXT; - const char *value; - int handled = 1; - - switch (dwState) { -#define GEN_CASE(a) case a: value = #a; break - GEN_CASE(D3DTOP_DISABLE); - GEN_CASE(D3DTOP_SELECTARG1); - GEN_CASE(D3DTOP_SELECTARG2); - GEN_CASE(D3DTOP_MODULATE); - GEN_CASE(D3DTOP_MODULATE2X); - GEN_CASE(D3DTOP_MODULATE4X); - GEN_CASE(D3DTOP_ADD); - GEN_CASE(D3DTOP_ADDSIGNED); - GEN_CASE(D3DTOP_ADDSIGNED2X); - GEN_CASE(D3DTOP_SUBTRACT); - GEN_CASE(D3DTOP_ADDSMOOTH); - GEN_CASE(D3DTOP_BLENDDIFFUSEALPHA); - GEN_CASE(D3DTOP_BLENDTEXTUREALPHA); - GEN_CASE(D3DTOP_BLENDFACTORALPHA); - GEN_CASE(D3DTOP_BLENDTEXTUREALPHAPM); - GEN_CASE(D3DTOP_BLENDCURRENTALPHA); - GEN_CASE(D3DTOP_PREMODULATE); - GEN_CASE(D3DTOP_MODULATEALPHA_ADDCOLOR); - GEN_CASE(D3DTOP_MODULATECOLOR_ADDALPHA); - GEN_CASE(D3DTOP_MODULATEINVALPHA_ADDCOLOR); - GEN_CASE(D3DTOP_MODULATEINVCOLOR_ADDALPHA); - GEN_CASE(D3DTOP_BUMPENVMAP); - GEN_CASE(D3DTOP_BUMPENVMAPLUMINANCE); - GEN_CASE(D3DTOP_DOTPRODUCT3); - GEN_CASE(D3DTOP_FORCE_DWORD); -#undef GEN_CASE - default: value = "UNKNOWN"; - } - - if ((d3dTexStageStateType == D3DTSS_COLOROP) && (dwState == D3DTOP_DISABLE)) { - glDisable(GL_TEXTURE_2D); - TRACE(" disabling 2D texturing.\n"); - } else { - /* Re-enable texturing only if COLOROP was not already disabled... */ - if ((glThis->current_bound_texture[dwStage] != NULL) && - (This->state_block.texture_stage_state[dwStage][D3DTSS_COLOROP - 1] != D3DTOP_DISABLE)) { - glEnable(GL_TEXTURE_2D); - TRACE(" enabling 2D texturing.\n"); - } - - /* Re-Enable GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT */ - if ((dwState != D3DTOP_DISABLE) && - (This->state_block.texture_stage_state[dwStage][D3DTSS_COLOROP - 1] != D3DTOP_DISABLE)) { - if (glThis->current_tex_env != GL_COMBINE_EXT) { - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT); - glThis->current_tex_env = GL_COMBINE_EXT; - } - } - - /* Now set up the operand correctly */ - switch (dwState) { - case D3DTOP_DISABLE: - /* Contrary to the docs, alpha can be disabled when colorop is enabled - and it works, so ignore this op */ - TRACE(" Note : disable ALPHAOP but COLOROP enabled!\n"); - break; - - case D3DTOP_SELECTARG1: - case D3DTOP_SELECTARG2: - glTexEnvi(GL_TEXTURE_ENV, parm, GL_REPLACE); - break; - - case D3DTOP_MODULATE4X: - scale = scale * 2; /* Drop through */ - case D3DTOP_MODULATE2X: - scale = scale * 2; /* Drop through */ - case D3DTOP_MODULATE: - glTexEnvi(GL_TEXTURE_ENV, parm, GL_MODULATE); - break; - - case D3DTOP_ADD: - glTexEnvi(GL_TEXTURE_ENV, parm, GL_ADD); - break; - - case D3DTOP_ADDSIGNED2X: - scale = scale * 2; /* Drop through */ - case D3DTOP_ADDSIGNED: - glTexEnvi(GL_TEXTURE_ENV, parm, GL_ADD_SIGNED_EXT); - break; - - /* For the four blending modes, use the Arg2 parameter */ - case D3DTOP_BLENDDIFFUSEALPHA: - case D3DTOP_BLENDTEXTUREALPHA: - case D3DTOP_BLENDFACTORALPHA: - case D3DTOP_BLENDCURRENTALPHA: { - GLenum src = GL_PRIMARY_COLOR_EXT; /* Just to prevent a compiler warning.. */ - - switch (dwState) { - case D3DTOP_BLENDDIFFUSEALPHA: src = GL_PRIMARY_COLOR_EXT; - case D3DTOP_BLENDTEXTUREALPHA: src = GL_TEXTURE; - case D3DTOP_BLENDFACTORALPHA: src = GL_CONSTANT_EXT; - case D3DTOP_BLENDCURRENTALPHA: src = GL_PREVIOUS_EXT; - } - - glTexEnvi(GL_TEXTURE_ENV, parm, GL_INTERPOLATE_EXT); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_EXT, src); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT, GL_SRC_ALPHA); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_EXT, src); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_EXT, GL_SRC_ALPHA); - } break; - - default: - handled = FALSE; - break; - } - } - - if (((prev_state == D3DTOP_SELECTARG2) && (dwState != D3DTOP_SELECTARG2)) || - ((dwState == D3DTOP_SELECTARG2) && (prev_state != D3DTOP_SELECTARG2))) { - /* Switch the arguments if needed... */ - if (d3dTexStageStateType == D3DTSS_COLOROP) { - handle_color_alpha_args(This, dwStage, D3DTSS_COLORARG1, - This->state_block.texture_stage_state[dwStage][D3DTSS_COLORARG1 - 1], - dwState); - handle_color_alpha_args(This, dwStage, D3DTSS_COLORARG2, - This->state_block.texture_stage_state[dwStage][D3DTSS_COLORARG2 - 1], - dwState); - } else { - handle_color_alpha_args(This, dwStage, D3DTSS_ALPHAARG1, - This->state_block.texture_stage_state[dwStage][D3DTSS_ALPHAARG1 - 1], - dwState); - handle_color_alpha_args(This, dwStage, D3DTSS_ALPHAARG2, - This->state_block.texture_stage_state[dwStage][D3DTSS_ALPHAARG2 - 1], - dwState); - } - } - - if (handled) { - if (d3dTexStageStateType == D3DTSS_ALPHAOP) { - glTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, scale); - } else { - glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, scale); - } - TRACE(" Stage type is : %s => %s\n", type, value); - } else { - FIXME(" Unhandled stage type is : %s => %s\n", type, value); - } - } break; - - case D3DTSS_COLORARG1: - case D3DTSS_COLORARG2: - case D3DTSS_ALPHAARG1: - case D3DTSS_ALPHAARG2: { - const char *value, *value_comp = "", *value_alpha = ""; - BOOLEAN handled; - D3DTEXTUREOP tex_op; - - switch (dwState & D3DTA_SELECTMASK) { -#define GEN_CASE(a) case a: value = #a; break - GEN_CASE(D3DTA_DIFFUSE); - GEN_CASE(D3DTA_CURRENT); - GEN_CASE(D3DTA_TEXTURE); - GEN_CASE(D3DTA_TFACTOR); - GEN_CASE(D3DTA_SPECULAR); -#undef GEN_CASE - default: value = "UNKNOWN"; - } - if (dwState & D3DTA_COMPLEMENT) { - value_comp = " | D3DTA_COMPLEMENT"; - } - if (dwState & D3DTA_ALPHAREPLICATE) { - value_alpha = " | D3DTA_ALPHAREPLICATE"; - } - - if ((d3dTexStageStateType == D3DTSS_COLORARG1) || (d3dTexStageStateType == D3DTSS_COLORARG2)) { - tex_op = This->state_block.texture_stage_state[dwStage][D3DTSS_COLOROP - 1]; - } else { - tex_op = This->state_block.texture_stage_state[dwStage][D3DTSS_ALPHAOP - 1]; - } - - handled = handle_color_alpha_args(This, dwStage, d3dTexStageStateType, dwState, tex_op); - - if (handled) { - TRACE(" Stage type : %s => %s%s%s\n", type, value, value_comp, value_alpha); - } else { - FIXME(" Unhandled stage type : %s => %s%s%s\n", type, value, value_comp, value_alpha); - } - } break; - - case D3DTSS_MIPMAPLODBIAS: { - D3DVALUE value = *((D3DVALUE *) &dwState); - BOOLEAN handled = TRUE; - - if ((value != 0.0) && (GL_extensions.mipmap_lodbias == FALSE)) - handled = FALSE; - - if (handled) { - TRACE(" Stage type : D3DTSS_MIPMAPLODBIAS => %f\n", value); - glTexEnvf(GL_TEXTURE_FILTER_CONTROL_WINE, GL_TEXTURE_LOD_BIAS_WINE, value); - } else { - FIXME(" Unhandled stage type : D3DTSS_MIPMAPLODBIAS => %f\n", value); - } - } break; - - case D3DTSS_MAXMIPLEVEL: - TRACE(" Stage type : D3DTSS_MAXMIPLEVEL => %ld\n", dwState); - break; - - case D3DTSS_BORDERCOLOR: - TRACE(" Stage type : D3DTSS_BORDERCOLOR => %02lx %02lx %02lx %02lx (RGBA)\n", - ((dwState >> 16) & 0xFF), - ((dwState >> 8) & 0xFF), - ((dwState >> 0) & 0xFF), - ((dwState >> 24) & 0xFF)); - break; - - case D3DTSS_TEXCOORDINDEX: { - BOOLEAN handled = TRUE; - const char *value; - - switch (dwState & 0xFFFF0000) { -#define GEN_CASE(a) case a: value = #a; break - GEN_CASE(D3DTSS_TCI_PASSTHRU); - GEN_CASE(D3DTSS_TCI_CAMERASPACENORMAL); - GEN_CASE(D3DTSS_TCI_CAMERASPACEPOSITION); - GEN_CASE(D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR); -#undef GEN_CASE - default: value = "UNKNOWN"; - } - if ((dwState & 0xFFFF0000) != D3DTSS_TCI_PASSTHRU) - handled = FALSE; - - if (handled) { - TRACE(" Stage type : D3DTSS_TEXCOORDINDEX => %ld | %s\n", dwState & 0x0000FFFF, value); - } else { - FIXME(" Unhandled stage type : D3DTSS_TEXCOORDINDEX => %ld | %s\n", dwState & 0x0000FFFF, value); - } - } break; - - case D3DTSS_TEXTURETRANSFORMFLAGS: { - const char *projected = "", *value; - BOOLEAN handled = TRUE; - switch (dwState & 0xFF) { -#define GEN_CASE(a) case a: value = #a; break - GEN_CASE(D3DTTFF_DISABLE); - GEN_CASE(D3DTTFF_COUNT1); - GEN_CASE(D3DTTFF_COUNT2); - GEN_CASE(D3DTTFF_COUNT3); - GEN_CASE(D3DTTFF_COUNT4); -#undef GEN_CASE - default: value = "UNKNOWN"; - } - if (dwState & D3DTTFF_PROJECTED) { - projected = " | D3DTTFF_PROJECTED"; - handled = FALSE; - } - - if ((dwState & 0xFF) != D3DTTFF_DISABLE) { - This->matrices_updated(This, TEXMAT0_CHANGED << dwStage); - } - - if (handled) { - TRACE(" Stage type : D3DTSS_TEXTURETRANSFORMFLAGS => %s%s\n", value, projected); - } else { - FIXME(" Unhandled stage type : D3DTSS_TEXTURETRANSFORMFLAGS => %s%s\n", value, projected); - } - } break; - - default: - FIXME(" Unhandled stage type : %s => %08lx\n", type, dwState); - break; - } - - LEAVE_GL(); - - return DD_OK; -} - -static DWORD -draw_primitive_handle_textures(IDirect3DDeviceImpl *This) -{ - IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This; - DWORD stage; - BOOLEAN enable_colorkey = FALSE; - - for (stage = 0; stage < MAX_TEXTURES; stage++) { - IDirectDrawSurfaceImpl *surf_ptr = This->current_texture[stage]; - GLenum unit; - - /* If this stage is disabled, no need to go further... */ - if (This->state_block.texture_stage_state[stage][D3DTSS_COLOROP - 1] == D3DTOP_DISABLE) - break; - - /* First check if we need to bind any other texture for this stage */ - if (This->current_texture[stage] != glThis->current_bound_texture[stage]) { - if (This->current_texture[stage] == NULL) { - TRACE(" disabling 2D texturing for stage %ld.\n", stage); - - unit = GL_TEXTURE0_WINE + stage; - if (unit != glThis->current_active_tex_unit) { - GL_extensions.glActiveTexture(unit); - glThis->current_active_tex_unit = unit; - } - glBindTexture(GL_TEXTURE_2D, 0); - glDisable(GL_TEXTURE_2D); - } else { - GLenum tex_name = gltex_get_tex_name(surf_ptr); - - unit = GL_TEXTURE0_WINE + stage; - if (unit != glThis->current_active_tex_unit) { - GL_extensions.glActiveTexture(unit); - glThis->current_active_tex_unit = unit; - } - - if (glThis->current_bound_texture[stage] == NULL) { - if (This->state_block.texture_stage_state[stage][D3DTSS_COLOROP - 1] != D3DTOP_DISABLE) { - TRACE(" enabling 2D texturing and"); - glEnable(GL_TEXTURE_2D); - } - } - TRACE(" activating OpenGL texture id %d for stage %ld.\n", tex_name, stage); - glBindTexture(GL_TEXTURE_2D, tex_name); - } - - glThis->current_bound_texture[stage] = This->current_texture[stage]; - } else { - if (glThis->current_bound_texture[stage] == NULL) { - TRACE(" displaying without texturing activated for stage %ld.\n", stage); - } else { - TRACE(" using already bound texture id %d for stage %ld.\n", - ((IDirect3DTextureGLImpl *) (glThis->current_bound_texture[stage])->tex_private)->tex_name, stage); - } - } - - /* If no texure valid for this stage, go out of the loop */ - if (This->current_texture[stage] == NULL) break; - - /* Then check if we need to flush this texture to GL or not (ie did it change) ?. - This will also update the various texture parameters if needed. - */ - gltex_upload_texture(surf_ptr, This, stage); - - /* And finally check for color-keying (only on first stage) */ - if (This->current_texture[stage]->surface_desc.dwFlags & DDSD_CKSRCBLT) { - if (stage == 0) { - enable_colorkey = TRUE; - } else { - static BOOL warn = FALSE; - if (warn == FALSE) { - warn = TRUE; - WARN(" Surface has color keying on stage different from 0 (%ld) !", stage); - } - } - } else { - if (stage == 0) { - enable_colorkey = FALSE; - } - } - } - - /* Apparently, whatever the state of BLEND, color keying is always activated for 'old' D3D versions */ - if (((This->state_block.render_state[D3DRENDERSTATE_COLORKEYENABLE - 1]) || - (glThis->parent.version == 1)) && - (enable_colorkey)) { - TRACE(" colorkey activated.\n"); - - if (glThis->alpha_test == FALSE) { - glEnable(GL_ALPHA_TEST); - glThis->alpha_test = TRUE; - } - if ((glThis->current_alpha_test_func != GL_NOTEQUAL) || (glThis->current_alpha_test_ref != 0.0)) { - if (This->state_block.render_state[D3DRENDERSTATE_ALPHATESTENABLE - 1]) { - static BOOL warn = FALSE; - if (warn == FALSE) { - warn = TRUE; - WARN(" Overriding application-given alpha test values - some graphical glitches may appear !\n"); - } - } - glThis->current_alpha_test_func = GL_NOTEQUAL; - glThis->current_alpha_test_ref = 0.0; - glAlphaFunc(GL_NOTEQUAL, 0.0); - } - /* Some sanity checks should be added here if a game mixes alphatest + color keying... - Only one has been found for now, and the ALPHAFUNC is 'Always' so it works :-) */ - } else { - if (This->state_block.render_state[D3DRENDERSTATE_ALPHATESTENABLE - 1] == FALSE) { - glDisable(GL_ALPHA_TEST); - glThis->alpha_test = FALSE; - } - /* Maybe we should restore here the application-given alpha test states ? */ - } - - return stage; -} - -HRESULT WINAPI -GL_IDirect3DDeviceImpl_7_3T_SetTexture(LPDIRECT3DDEVICE7 iface, - DWORD dwStage, - LPDIRECTDRAWSURFACE7 lpTexture2) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - - TRACE("(%p/%p)->(%08lx,%p)\n", This, iface, dwStage, lpTexture2); - - if (((GL_extensions.max_texture_units == 0) && (dwStage > 0)) || - ((GL_extensions.max_texture_units != 0) && (dwStage >= GL_extensions.max_texture_units))) { - if (lpTexture2 != NULL) { - WARN(" setting a texture to a non-supported texture stage !\n"); - } - return DD_OK; - } - - if (This->current_texture[dwStage] != NULL) { - IDirectDrawSurface7_Release(ICOM_INTERFACE(This->current_texture[dwStage], IDirectDrawSurface7)); - } - - if (lpTexture2 == NULL) { - This->current_texture[dwStage] = NULL; - } else { - IDirectDrawSurfaceImpl *tex_impl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, lpTexture2); - IDirectDrawSurface7_AddRef(ICOM_INTERFACE(tex_impl, IDirectDrawSurface7)); - This->current_texture[dwStage] = tex_impl; - } - - return DD_OK; -} - -static HRESULT WINAPI -GL_IDirect3DDeviceImpl_7_GetCaps(LPDIRECT3DDEVICE7 iface, - LPD3DDEVICEDESC7 lpD3DHELDevDesc) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - TRACE("(%p/%p)->(%p)\n", This, iface, lpD3DHELDevDesc); - - fill_opengl_caps_7(lpD3DHELDevDesc); - - TRACE(" returning caps : no dump function yet.\n"); - - return DD_OK; -} - -HRESULT WINAPI -GL_IDirect3DDeviceImpl_7_SetMaterial(LPDIRECT3DDEVICE7 iface, - LPD3DMATERIAL7 lpMat) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - TRACE("(%p/%p)->(%p)\n", This, iface, lpMat); - - if (TRACE_ON(ddraw)) { - TRACE(" material is :\n"); - dump_D3DMATERIAL7(lpMat); - } - - This->current_material = *lpMat; - - ENTER_GL(); - glMaterialfv(GL_FRONT_AND_BACK, - GL_DIFFUSE, - (float *) &(This->current_material.u.diffuse)); - glMaterialfv(GL_FRONT_AND_BACK, - GL_AMBIENT, - (float *) &(This->current_material.u1.ambient)); - glMaterialfv(GL_FRONT_AND_BACK, - GL_SPECULAR, - (float *) &(This->current_material.u2.specular)); - glMaterialfv(GL_FRONT_AND_BACK, - GL_EMISSION, - (float *) &(This->current_material.u3.emissive)); - glMaterialf(GL_FRONT_AND_BACK, - GL_SHININESS, - This->current_material.u4.power); /* Not sure about this... */ - LEAVE_GL(); - - return DD_OK; -} - -static LPD3DLIGHT7 get_light(IDirect3DDeviceImpl *This, DWORD dwLightIndex) -{ - if (dwLightIndex >= This->num_set_lights) - { - /* Extend, or allocate the light parameters array. */ - DWORD newlightnum = dwLightIndex + 1; - LPD3DLIGHT7 newarrayptr = NULL; - - if (This->light_parameters) - newarrayptr = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - This->light_parameters, newlightnum * sizeof(D3DLIGHT7)); - else - newarrayptr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - newlightnum * sizeof(D3DLIGHT7)); - - if (!newarrayptr) - return NULL; - - This->light_parameters = newarrayptr; - This->num_set_lights = newlightnum; - } - - return &This->light_parameters[dwLightIndex]; -} - -HRESULT WINAPI -GL_IDirect3DDeviceImpl_7_SetLight(LPDIRECT3DDEVICE7 iface, - DWORD dwLightIndex, - LPD3DLIGHT7 lpLight) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This; - LPD3DLIGHT7 lpdestlight = get_light( This, dwLightIndex ); - - TRACE("(%p/%p)->(%08lx,%p)\n", This, iface, dwLightIndex, lpLight); - - if (TRACE_ON(ddraw)) { - TRACE(" setting light :\n"); - dump_D3DLIGHT7(lpLight); - } - - /* DirectX7 documentation states that this function can return - DDERR_OUTOFMEMORY, so we do just that in case of an allocation - error (which is the only reason why get_light() can fail). */ - if( !lpdestlight ) - return DDERR_OUTOFMEMORY; - - *lpdestlight = *lpLight; - - /* Some checks to print out nice warnings :-) */ - switch (lpLight->dltType) { - case D3DLIGHT_DIRECTIONAL: - case D3DLIGHT_POINT: - /* These are handled properly... */ - break; - - case D3DLIGHT_SPOT: - if ((lpLight->dvTheta != 0.0) || - (lpLight->dvTheta != lpLight->dvPhi)) { - ERR("dvTheta not fully supported yet !\n"); - } - break; - - default: - ERR("Light type not handled yet : %08x !\n", lpLight->dltType); - } - - /* This will force the Light setting on next drawing of primitives */ - glThis->transform_state = GL_TRANSFORM_NONE; - - return DD_OK; -} - -HRESULT WINAPI -GL_IDirect3DDeviceImpl_7_LightEnable(LPDIRECT3DDEVICE7 iface, - DWORD dwLightIndex, - BOOL bEnable) -{ - int lightslot = -1, i; - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - LPD3DLIGHT7 lpdestlight = get_light(This, dwLightIndex); - - TRACE("(%p/%p)->(%08lx,%d)\n", This, iface, dwLightIndex, bEnable); - - /* The DirectX doc isn't as explicit as for SetLight as whether we can - return this from this function, but it doesn't state otherwise. */ - if (!lpdestlight) - return DDERR_OUTOFMEMORY; - - /* If this light hasn't been set, initialise it with default values. */ - if (lpdestlight->dltType == 0) - { - TRACE("setting default light parameters\n"); - - /* We always use HEAP_ZERO_MEMORY when allocating the light_parameters - array, so we only have to setup anything that shoud not be zero. */ - lpdestlight->dltType = D3DLIGHT_DIRECTIONAL; - lpdestlight->dcvDiffuse.u1.r = 1.f; - lpdestlight->dcvDiffuse.u2.g = 1.f; - lpdestlight->dcvDiffuse.u3.b = 1.f; - lpdestlight->dvDirection.u3.z = 1.f; - } - - /* Look for this light in the active lights array. */ - for (i = 0; i < This->max_active_lights; i++) - if (This->active_lights[i] == dwLightIndex) - { - lightslot = i; - break; - } - - /* If we didn't find it, let's find the first available slot, if any. */ - if (lightslot == -1) - for (i = 0; i < This->max_active_lights; i++) - if (This->active_lights[i] == ~0) - { - lightslot = i; - break; - } - - ENTER_GL(); - if (bEnable) { - if (lightslot == -1) - { - /* This means that the app is trying to enable more lights than - the maximum possible indicated in the caps. - - Windows actually let you do this, and disable one of the - previously enabled lights to let you enable this one. - - It's not documented and I'm not sure how windows pick which light - to disable to make room for this one. */ - FIXME("Enabling more light than the maximum is not supported yet."); - return D3D_OK; - } - - glEnable(GL_LIGHT0 + lightslot); - - - if (This->active_lights[lightslot] == ~0) - { - /* This light gets active... Need to update its parameters to GL before the next drawing */ - IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This; - - This->active_lights[lightslot] = dwLightIndex; - glThis->transform_state = GL_TRANSFORM_NONE; - } - } else { - glDisable(GL_LIGHT0 + lightslot); - This->active_lights[lightslot] = ~0; - } - - LEAVE_GL(); - return DD_OK; -} - -HRESULT WINAPI -GL_IDirect3DDeviceImpl_7_SetClipPlane(LPDIRECT3DDEVICE7 iface, DWORD dwIndex, D3DVALUE* pPlaneEquation) -{ - IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface; - IDirect3DDeviceGLImpl* glThis = (IDirect3DDeviceGLImpl*) This; - - TRACE("(%p)->(%ld,%p)\n", This, dwIndex, pPlaneEquation); - - if (dwIndex >= This->max_clipping_planes) { - return DDERR_INVALIDPARAMS; - } - - TRACE(" clip plane %ld : %f %f %f %f\n", dwIndex, pPlaneEquation[0], pPlaneEquation[1], pPlaneEquation[2], pPlaneEquation[3] ); - - memcpy(This->clipping_planes[dwIndex].plane, pPlaneEquation, sizeof(D3DVALUE[4])); - - /* This is to force the reset of the transformation matrices on the next drawing. - * This is needed to use the correct matrices for the various clipping planes. - */ - glThis->transform_state = GL_TRANSFORM_NONE; - - return D3D_OK; -} - -static HRESULT WINAPI -GL_IDirect3DDeviceImpl_7_SetViewport(LPDIRECT3DDEVICE7 iface, - LPD3DVIEWPORT7 lpData) -{ - ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - TRACE("(%p/%p)->(%p)\n", This, iface, lpData); - - if (TRACE_ON(ddraw)) { - TRACE(" viewport is :\n"); - TRACE(" - dwX = %ld dwY = %ld\n", - lpData->dwX, lpData->dwY); - TRACE(" - dwWidth = %ld dwHeight = %ld\n", - lpData->dwWidth, lpData->dwHeight); - TRACE(" - dvMinZ = %f dvMaxZ = %f\n", - lpData->dvMinZ, lpData->dvMaxZ); - } - ENTER_GL(); - - /* Set the viewport */ - if ((lpData->dvMinZ != This->active_viewport.dvMinZ) || - (lpData->dvMaxZ != This->active_viewport.dvMaxZ)) { - glDepthRange(lpData->dvMinZ, lpData->dvMaxZ); - } - if ((lpData->dwX != This->active_viewport.dwX) || - (lpData->dwY != This->active_viewport.dwY) || - (lpData->dwWidth != This->active_viewport.dwWidth) || - (lpData->dwHeight != This->active_viewport.dwHeight)) { - glViewport(lpData->dwX, - This->surface->surface_desc.dwHeight - (lpData->dwHeight + lpData->dwY), - lpData->dwWidth, lpData->dwHeight); - } - - LEAVE_GL(); - - This->active_viewport = *lpData; - - return DD_OK; -} - -#if !defined(__STRICT_ANSI__) && defined(__GNUC__) -# define XCAST(fun) (typeof(VTABLE_IDirect3DDevice7.fun)) -#else -# define XCAST(fun) (void*) -#endif - -static const IDirect3DDevice7Vtbl VTABLE_IDirect3DDevice7 = -{ - XCAST(QueryInterface) Main_IDirect3DDeviceImpl_7_3T_2T_1T_QueryInterface, - XCAST(AddRef) Main_IDirect3DDeviceImpl_7_3T_2T_1T_AddRef, - XCAST(Release) GL_IDirect3DDeviceImpl_7_3T_2T_1T_Release, - XCAST(GetCaps) GL_IDirect3DDeviceImpl_7_GetCaps, - XCAST(EnumTextureFormats) GL_IDirect3DDeviceImpl_7_3T_EnumTextureFormats, - XCAST(BeginScene) Main_IDirect3DDeviceImpl_7_3T_2T_1T_BeginScene, - XCAST(EndScene) Main_IDirect3DDeviceImpl_7_3T_2T_1T_EndScene, - XCAST(GetDirect3D) Main_IDirect3DDeviceImpl_7_3T_2T_1T_GetDirect3D, - XCAST(SetRenderTarget) Main_IDirect3DDeviceImpl_7_3T_2T_SetRenderTarget, - XCAST(GetRenderTarget) Main_IDirect3DDeviceImpl_7_3T_2T_GetRenderTarget, - XCAST(Clear) Main_IDirect3DDeviceImpl_7_Clear, - XCAST(SetTransform) Main_IDirect3DDeviceImpl_7_3T_2T_SetTransform, - XCAST(GetTransform) Main_IDirect3DDeviceImpl_7_3T_2T_GetTransform, - XCAST(SetViewport) GL_IDirect3DDeviceImpl_7_SetViewport, - XCAST(MultiplyTransform) Main_IDirect3DDeviceImpl_7_3T_2T_MultiplyTransform, - XCAST(GetViewport) Main_IDirect3DDeviceImpl_7_GetViewport, - XCAST(SetMaterial) GL_IDirect3DDeviceImpl_7_SetMaterial, - XCAST(GetMaterial) Main_IDirect3DDeviceImpl_7_GetMaterial, - XCAST(SetLight) GL_IDirect3DDeviceImpl_7_SetLight, - XCAST(GetLight) Main_IDirect3DDeviceImpl_7_GetLight, - XCAST(SetRenderState) GL_IDirect3DDeviceImpl_7_3T_2T_SetRenderState, - XCAST(GetRenderState) GL_IDirect3DDeviceImpl_7_3T_2T_GetRenderState, - XCAST(BeginStateBlock) Main_IDirect3DDeviceImpl_7_BeginStateBlock, - XCAST(EndStateBlock) Main_IDirect3DDeviceImpl_7_EndStateBlock, - XCAST(PreLoad) Main_IDirect3DDeviceImpl_7_PreLoad, - XCAST(DrawPrimitive) GL_IDirect3DDeviceImpl_7_3T_DrawPrimitive, - XCAST(DrawIndexedPrimitive) GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitive, - XCAST(SetClipStatus) Main_IDirect3DDeviceImpl_7_3T_2T_SetClipStatus, - XCAST(GetClipStatus) Main_IDirect3DDeviceImpl_7_3T_2T_GetClipStatus, - XCAST(DrawPrimitiveStrided) GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveStrided, - XCAST(DrawIndexedPrimitiveStrided) GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveStrided, - XCAST(DrawPrimitiveVB) GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveVB, - XCAST(DrawIndexedPrimitiveVB) GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveVB, - XCAST(ComputeSphereVisibility) Main_IDirect3DDeviceImpl_7_3T_ComputeSphereVisibility, - XCAST(GetTexture) Main_IDirect3DDeviceImpl_7_3T_GetTexture, - XCAST(SetTexture) GL_IDirect3DDeviceImpl_7_3T_SetTexture, - XCAST(GetTextureStageState) Main_IDirect3DDeviceImpl_7_3T_GetTextureStageState, - XCAST(SetTextureStageState) GL_IDirect3DDeviceImpl_7_3T_SetTextureStageState, - XCAST(ValidateDevice) Main_IDirect3DDeviceImpl_7_3T_ValidateDevice, - XCAST(ApplyStateBlock) Main_IDirect3DDeviceImpl_7_ApplyStateBlock, - XCAST(CaptureStateBlock) Main_IDirect3DDeviceImpl_7_CaptureStateBlock, - XCAST(DeleteStateBlock) Main_IDirect3DDeviceImpl_7_DeleteStateBlock, - XCAST(CreateStateBlock) Main_IDirect3DDeviceImpl_7_CreateStateBlock, - XCAST(Load) Main_IDirect3DDeviceImpl_7_Load, - XCAST(LightEnable) GL_IDirect3DDeviceImpl_7_LightEnable, - XCAST(GetLightEnable) Main_IDirect3DDeviceImpl_7_GetLightEnable, - XCAST(SetClipPlane) GL_IDirect3DDeviceImpl_7_SetClipPlane, - XCAST(GetClipPlane) Main_IDirect3DDeviceImpl_7_GetClipPlane, - XCAST(GetInfo) Main_IDirect3DDeviceImpl_7_GetInfo, -}; - -#if !defined(__STRICT_ANSI__) && defined(__GNUC__) -#undef XCAST -#endif - - -#if !defined(__STRICT_ANSI__) && defined(__GNUC__) -# define XCAST(fun) (typeof(VTABLE_IDirect3DDevice3.fun)) -#else -# define XCAST(fun) (void*) -#endif - -static const IDirect3DDevice3Vtbl VTABLE_IDirect3DDevice3 = -{ - XCAST(QueryInterface) Thunk_IDirect3DDeviceImpl_3_QueryInterface, - XCAST(AddRef) Thunk_IDirect3DDeviceImpl_3_AddRef, - XCAST(Release) Thunk_IDirect3DDeviceImpl_3_Release, - XCAST(GetCaps) GL_IDirect3DDeviceImpl_3_2T_1T_GetCaps, - XCAST(GetStats) Main_IDirect3DDeviceImpl_3_2T_1T_GetStats, - XCAST(AddViewport) Main_IDirect3DDeviceImpl_3_2T_1T_AddViewport, - XCAST(DeleteViewport) Main_IDirect3DDeviceImpl_3_2T_1T_DeleteViewport, - XCAST(NextViewport) Main_IDirect3DDeviceImpl_3_2T_1T_NextViewport, - XCAST(EnumTextureFormats) Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats, - XCAST(BeginScene) Thunk_IDirect3DDeviceImpl_3_BeginScene, - XCAST(EndScene) Thunk_IDirect3DDeviceImpl_3_EndScene, - XCAST(GetDirect3D) Thunk_IDirect3DDeviceImpl_3_GetDirect3D, - XCAST(SetCurrentViewport) Main_IDirect3DDeviceImpl_3_2T_SetCurrentViewport, - XCAST(GetCurrentViewport) Main_IDirect3DDeviceImpl_3_2T_GetCurrentViewport, - XCAST(SetRenderTarget) Thunk_IDirect3DDeviceImpl_3_SetRenderTarget, - XCAST(GetRenderTarget) Thunk_IDirect3DDeviceImpl_3_GetRenderTarget, - XCAST(Begin) Main_IDirect3DDeviceImpl_3_Begin, - XCAST(BeginIndexed) Main_IDirect3DDeviceImpl_3_BeginIndexed, - XCAST(Vertex) Main_IDirect3DDeviceImpl_3_2T_Vertex, - XCAST(Index) Main_IDirect3DDeviceImpl_3_2T_Index, - XCAST(End) Main_IDirect3DDeviceImpl_3_2T_End, - XCAST(GetRenderState) Thunk_IDirect3DDeviceImpl_3_GetRenderState, - XCAST(SetRenderState) Thunk_IDirect3DDeviceImpl_3_SetRenderState, - XCAST(GetLightState) GL_IDirect3DDeviceImpl_3_2T_GetLightState, - XCAST(SetLightState) GL_IDirect3DDeviceImpl_3_2T_SetLightState, - XCAST(SetTransform) Thunk_IDirect3DDeviceImpl_3_SetTransform, - XCAST(GetTransform) Thunk_IDirect3DDeviceImpl_3_GetTransform, - XCAST(MultiplyTransform) Thunk_IDirect3DDeviceImpl_3_MultiplyTransform, - XCAST(DrawPrimitive) Thunk_IDirect3DDeviceImpl_3_DrawPrimitive, - XCAST(DrawIndexedPrimitive) Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive, - XCAST(SetClipStatus) Thunk_IDirect3DDeviceImpl_3_SetClipStatus, - XCAST(GetClipStatus) Thunk_IDirect3DDeviceImpl_3_GetClipStatus, - XCAST(DrawPrimitiveStrided) Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided, - XCAST(DrawIndexedPrimitiveStrided) Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided, - XCAST(DrawPrimitiveVB) Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB, - XCAST(DrawIndexedPrimitiveVB) Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB, - XCAST(ComputeSphereVisibility) Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility, - XCAST(GetTexture) Thunk_IDirect3DDeviceImpl_3_GetTexture, - XCAST(SetTexture) Thunk_IDirect3DDeviceImpl_3_SetTexture, - XCAST(GetTextureStageState) Thunk_IDirect3DDeviceImpl_3_GetTextureStageState, - XCAST(SetTextureStageState) Thunk_IDirect3DDeviceImpl_3_SetTextureStageState, - XCAST(ValidateDevice) Thunk_IDirect3DDeviceImpl_3_ValidateDevice, -}; - -#if !defined(__STRICT_ANSI__) && defined(__GNUC__) -#undef XCAST -#endif - - -#if !defined(__STRICT_ANSI__) && defined(__GNUC__) -# define XCAST(fun) (typeof(VTABLE_IDirect3DDevice2.fun)) -#else -# define XCAST(fun) (void*) -#endif - -static const IDirect3DDevice2Vtbl VTABLE_IDirect3DDevice2 = -{ - XCAST(QueryInterface) Thunk_IDirect3DDeviceImpl_2_QueryInterface, - XCAST(AddRef) Thunk_IDirect3DDeviceImpl_2_AddRef, - XCAST(Release) Thunk_IDirect3DDeviceImpl_2_Release, - XCAST(GetCaps) Thunk_IDirect3DDeviceImpl_2_GetCaps, - XCAST(SwapTextureHandles) Main_IDirect3DDeviceImpl_2_1T_SwapTextureHandles, - XCAST(GetStats) Thunk_IDirect3DDeviceImpl_2_GetStats, - XCAST(AddViewport) Thunk_IDirect3DDeviceImpl_2_AddViewport, - XCAST(DeleteViewport) Thunk_IDirect3DDeviceImpl_2_DeleteViewport, - XCAST(NextViewport) Thunk_IDirect3DDeviceImpl_2_NextViewport, - XCAST(EnumTextureFormats) GL_IDirect3DDeviceImpl_2_1T_EnumTextureFormats, - XCAST(BeginScene) Thunk_IDirect3DDeviceImpl_2_BeginScene, - XCAST(EndScene) Thunk_IDirect3DDeviceImpl_2_EndScene, - XCAST(GetDirect3D) Thunk_IDirect3DDeviceImpl_2_GetDirect3D, - XCAST(SetCurrentViewport) Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport, - XCAST(GetCurrentViewport) Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport, - XCAST(SetRenderTarget) Thunk_IDirect3DDeviceImpl_2_SetRenderTarget, - XCAST(GetRenderTarget) Thunk_IDirect3DDeviceImpl_2_GetRenderTarget, - XCAST(Begin) Main_IDirect3DDeviceImpl_2_Begin, - XCAST(BeginIndexed) Main_IDirect3DDeviceImpl_2_BeginIndexed, - XCAST(Vertex) Thunk_IDirect3DDeviceImpl_2_Vertex, - XCAST(Index) Thunk_IDirect3DDeviceImpl_2_Index, - XCAST(End) Thunk_IDirect3DDeviceImpl_2_End, - XCAST(GetRenderState) Thunk_IDirect3DDeviceImpl_2_GetRenderState, - XCAST(SetRenderState) Thunk_IDirect3DDeviceImpl_2_SetRenderState, - XCAST(GetLightState) Thunk_IDirect3DDeviceImpl_2_GetLightState, - XCAST(SetLightState) Thunk_IDirect3DDeviceImpl_2_SetLightState, - XCAST(SetTransform) Thunk_IDirect3DDeviceImpl_2_SetTransform, - XCAST(GetTransform) Thunk_IDirect3DDeviceImpl_2_GetTransform, - XCAST(MultiplyTransform) Thunk_IDirect3DDeviceImpl_2_MultiplyTransform, - XCAST(DrawPrimitive) GL_IDirect3DDeviceImpl_2_DrawPrimitive, - XCAST(DrawIndexedPrimitive) GL_IDirect3DDeviceImpl_2_DrawIndexedPrimitive, - XCAST(SetClipStatus) Thunk_IDirect3DDeviceImpl_2_SetClipStatus, - XCAST(GetClipStatus) Thunk_IDirect3DDeviceImpl_2_GetClipStatus, -}; - -#if !defined(__STRICT_ANSI__) && defined(__GNUC__) -#undef XCAST -#endif - - -#if !defined(__STRICT_ANSI__) && defined(__GNUC__) -# define XCAST(fun) (typeof(VTABLE_IDirect3DDevice.fun)) -#else -# define XCAST(fun) (void*) -#endif - -static const IDirect3DDeviceVtbl VTABLE_IDirect3DDevice = -{ - XCAST(QueryInterface) Thunk_IDirect3DDeviceImpl_1_QueryInterface, - XCAST(AddRef) Thunk_IDirect3DDeviceImpl_1_AddRef, - XCAST(Release) Thunk_IDirect3DDeviceImpl_1_Release, - XCAST(Initialize) Main_IDirect3DDeviceImpl_1_Initialize, - XCAST(GetCaps) Thunk_IDirect3DDeviceImpl_1_GetCaps, - XCAST(SwapTextureHandles) Thunk_IDirect3DDeviceImpl_1_SwapTextureHandles, - XCAST(CreateExecuteBuffer) GL_IDirect3DDeviceImpl_1_CreateExecuteBuffer, - XCAST(GetStats) Thunk_IDirect3DDeviceImpl_1_GetStats, - XCAST(Execute) Main_IDirect3DDeviceImpl_1_Execute, - XCAST(AddViewport) Thunk_IDirect3DDeviceImpl_1_AddViewport, - XCAST(DeleteViewport) Thunk_IDirect3DDeviceImpl_1_DeleteViewport, - XCAST(NextViewport) Thunk_IDirect3DDeviceImpl_1_NextViewport, - XCAST(Pick) Main_IDirect3DDeviceImpl_1_Pick, - XCAST(GetPickRecords) Main_IDirect3DDeviceImpl_1_GetPickRecords, - XCAST(EnumTextureFormats) Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats, - XCAST(CreateMatrix) Main_IDirect3DDeviceImpl_1_CreateMatrix, - XCAST(SetMatrix) Main_IDirect3DDeviceImpl_1_SetMatrix, - XCAST(GetMatrix) Main_IDirect3DDeviceImpl_1_GetMatrix, - XCAST(DeleteMatrix) Main_IDirect3DDeviceImpl_1_DeleteMatrix, - XCAST(BeginScene) Thunk_IDirect3DDeviceImpl_1_BeginScene, - XCAST(EndScene) Thunk_IDirect3DDeviceImpl_1_EndScene, - XCAST(GetDirect3D) Thunk_IDirect3DDeviceImpl_1_GetDirect3D, -}; - -#if !defined(__STRICT_ANSI__) && defined(__GNUC__) -#undef XCAST -#endif - -static HRESULT d3ddevice_clear(IDirect3DDeviceImpl *This, - WINE_GL_BUFFER_TYPE buffer_type, - DWORD dwCount, - LPD3DRECT lpRects, - DWORD dwFlags, - DWORD dwColor, - D3DVALUE dvZ, - DWORD dwStencil) -{ - IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This; - GLbitfield bitfield = 0; - D3DRECT rect; - unsigned int i; - - TRACE("(%p)->(%08lx,%p,%08lx,%08lx,%f,%08lx)\n", This, dwCount, lpRects, dwFlags, dwColor, dvZ, dwStencil); - if (TRACE_ON(ddraw)) { - if (dwCount > 0) { - unsigned int i; - TRACE(" rectangles :\n"); - for (i = 0; i < dwCount; i++) { - TRACE(" - %ld x %ld %ld x %ld\n", lpRects[i].u1.x1, lpRects[i].u2.y1, lpRects[i].u3.x2, lpRects[i].u4.y2); - } - } - } - - if (dwCount == 0) { - dwCount = 1; - rect.u1.x1 = 0; - rect.u2.y1 = 0; - rect.u3.x2 = This->surface->surface_desc.dwWidth; - rect.u4.y2 = This->surface->surface_desc.dwHeight; - lpRects = ▭ - } - - /* Clears the screen */ - ENTER_GL(); - - if (dwFlags & D3DCLEAR_TARGET) { - if (glThis->state[buffer_type] == SURFACE_MEMORY_DIRTY) { - /* TODO: optimize here the case where Clear changes all the screen... */ - This->flush_to_framebuffer(This, &(glThis->lock_rect[buffer_type]), glThis->lock_surf[buffer_type]); - } - glThis->state[buffer_type] = SURFACE_GL; - } - - if (dwFlags & D3DCLEAR_ZBUFFER) { - bitfield |= GL_DEPTH_BUFFER_BIT; - if (glThis->depth_mask == FALSE) { - glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */ - } - if (dvZ != glThis->prev_clear_Z) { - glClearDepth(dvZ); - glThis->prev_clear_Z = dvZ; - } - TRACE(" depth value : %f\n", dvZ); - } - if (dwFlags & D3DCLEAR_STENCIL) { - bitfield |= GL_STENCIL_BUFFER_BIT; - if (dwStencil != glThis->prev_clear_stencil) { - glClearStencil(dwStencil); - glThis->prev_clear_stencil = dwStencil; - } - TRACE(" stencil value : %ld\n", dwStencil); - } - if (dwFlags & D3DCLEAR_TARGET) { - bitfield |= GL_COLOR_BUFFER_BIT; - if (dwColor != glThis->prev_clear_color) { - glClearColor(((dwColor >> 16) & 0xFF) / 255.0, - ((dwColor >> 8) & 0xFF) / 255.0, - ((dwColor >> 0) & 0xFF) / 255.0, - ((dwColor >> 24) & 0xFF) / 255.0); - glThis->prev_clear_color = dwColor; - } - TRACE(" color value (ARGB) : %08lx\n", dwColor); - } - - glEnable(GL_SCISSOR_TEST); - for (i = 0; i < dwCount; i++) { - glScissor(lpRects[i].u1.x1, This->surface->surface_desc.dwHeight - lpRects[i].u4.y2, - lpRects[i].u3.x2 - lpRects[i].u1.x1, lpRects[i].u4.y2 - lpRects[i].u2.y1); - glClear(bitfield); - } - glDisable(GL_SCISSOR_TEST); - - if (dwFlags & D3DCLEAR_ZBUFFER) { - if (glThis->depth_mask == FALSE) glDepthMask(GL_FALSE); - } - - LEAVE_GL(); - - return DD_OK; -} - -static HRESULT d3ddevice_clear_back(IDirect3DDeviceImpl *This, - DWORD dwCount, - LPD3DRECT lpRects, - DWORD dwFlags, - DWORD dwColor, - D3DVALUE dvZ, - DWORD dwStencil) -{ - return d3ddevice_clear(This, WINE_GL_BUFFER_BACK, dwCount, lpRects, dwFlags, dwColor, dvZ, dwStencil); -} - -static HRESULT -setup_rect_and_surface_for_blt(IDirectDrawSurfaceImpl *This, - WINE_GL_BUFFER_TYPE *buffer_type_p, D3DRECT *rect) -{ - IDirect3DDeviceGLImpl *gl_d3d_dev = (IDirect3DDeviceGLImpl *) This->d3ddevice; - WINE_GL_BUFFER_TYPE buffer_type; - - /* First check if we BLT to the backbuffer... */ - if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_BACKBUFFER)) != 0) { - buffer_type = WINE_GL_BUFFER_BACK; - } else if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER|DDSCAPS_PRIMARYSURFACE)) != 0) { - buffer_type = WINE_GL_BUFFER_FRONT; - } else { - ERR("Only BLT override to front or back-buffer is supported for now !\n"); - return DDERR_INVALIDPARAMS; - } - - if ((gl_d3d_dev->state[buffer_type] == SURFACE_MEMORY_DIRTY) && - (rect->u1.x1 >= gl_d3d_dev->lock_rect[buffer_type].left) && - (rect->u2.y1 >= gl_d3d_dev->lock_rect[buffer_type].top) && - (rect->u3.x2 <= gl_d3d_dev->lock_rect[buffer_type].right) && - (rect->u4.y2 <= gl_d3d_dev->lock_rect[buffer_type].bottom)) { - /* If the memory zone is already dirty, use the standard 'in memory' blit operations and not - * GL to do it. - */ - return DDERR_INVALIDPARAMS; - } - *buffer_type_p = buffer_type; - - return DD_OK; -} - -HRESULT -d3ddevice_blt(IDirectDrawSurfaceImpl *This, LPRECT rdst, - LPDIRECTDRAWSURFACE7 src, LPRECT rsrc, - DWORD dwFlags, LPDDBLTFX lpbltfx) -{ - WINE_GL_BUFFER_TYPE buffer_type; - D3DRECT rect; - - if (rdst) { - rect.u1.x1 = rdst->left; - rect.u2.y1 = rdst->top; - rect.u3.x2 = rdst->right; - rect.u4.y2 = rdst->bottom; - } else { - rect.u1.x1 = 0; - rect.u2.y1 = 0; - rect.u3.x2 = This->surface_desc.dwWidth; - rect.u4.y2 = This->surface_desc.dwHeight; - } - - if (setup_rect_and_surface_for_blt(This, &buffer_type, &rect) != DD_OK) return DDERR_INVALIDPARAMS; - - if (dwFlags & DDBLT_COLORFILL) { - /* This is easy to handle for the D3D Device... */ - DWORD color; - GLint prev_draw; - - /* The color as given in the Blt function is in the format of the frame-buffer... - * 'clear' expect it in ARGB format => we need to do some conversion :-) - */ - if (This->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) { - if (This->palette) { - color = ((0xFF000000) | - (This->palette->palents[lpbltfx->u5.dwFillColor].peRed << 16) | - (This->palette->palents[lpbltfx->u5.dwFillColor].peGreen << 8) | - (This->palette->palents[lpbltfx->u5.dwFillColor].peBlue)); - } else { - color = 0xFF000000; - } - } else if ((This->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_RGB) && - (((This->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_ALPHAPIXELS) == 0) || - (This->surface_desc.u4.ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000000))) { - if ((This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 16) && - (This->surface_desc.u4.ddpfPixelFormat.u2.dwRBitMask == 0xF800) && - (This->surface_desc.u4.ddpfPixelFormat.u3.dwGBitMask == 0x07E0) && - (This->surface_desc.u4.ddpfPixelFormat.u4.dwBBitMask == 0x001F)) { - if (lpbltfx->u5.dwFillColor == 0xFFFF) { - color = 0xFFFFFFFF; - } else { - color = ((0xFF000000) | - ((lpbltfx->u5.dwFillColor & 0xF800) << 8) | - ((lpbltfx->u5.dwFillColor & 0x07E0) << 5) | - ((lpbltfx->u5.dwFillColor & 0x001F) << 3)); - } - } else if (((This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 32) || - (This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 24)) && - (This->surface_desc.u4.ddpfPixelFormat.u2.dwRBitMask == 0x00FF0000) && - (This->surface_desc.u4.ddpfPixelFormat.u3.dwGBitMask == 0x0000FF00) && - (This->surface_desc.u4.ddpfPixelFormat.u4.dwBBitMask == 0x000000FF)) { - color = 0xFF000000 | lpbltfx->u5.dwFillColor; - } else { - ERR("Wrong surface type for BLT override (unknown RGB format) !\n"); - return DDERR_INVALIDPARAMS; - } - } else { - ERR("Wrong surface type for BLT override !\n"); - return DDERR_INVALIDPARAMS; - } - - TRACE(" executing D3D Device override.\n"); - - ENTER_GL(); - - glGetIntegerv(GL_DRAW_BUFFER, &prev_draw); - if (buffer_type == WINE_GL_BUFFER_FRONT) - glDrawBuffer(GL_FRONT); - else - glDrawBuffer(GL_BACK); - - d3ddevice_clear(This->d3ddevice, buffer_type, 1, &rect, D3DCLEAR_TARGET, color, 0.0, 0x00000000); - - if (((buffer_type == WINE_GL_BUFFER_FRONT) && (prev_draw == GL_BACK)) || - ((buffer_type == WINE_GL_BUFFER_BACK) && (prev_draw == GL_FRONT))) - glDrawBuffer(prev_draw); - - LEAVE_GL(); - - return DD_OK; - } else if ((dwFlags & (~(DDBLT_KEYSRC|DDBLT_WAIT|DDBLT_ASYNC))) == 0) { - /* Normal blit without any special case... */ - if (src != NULL) { - /* And which has a SRC surface */ - IDirectDrawSurfaceImpl *src_impl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, src); - - if ((src_impl->surface_desc.ddsCaps.dwCaps & DDSCAPS_3DDEVICE) && - (src_impl->d3ddevice == This->d3ddevice) && - ((dwFlags & DDBLT_KEYSRC) == 0)) { - /* Both are 3D devices and using the same GL device and the Blt is without color-keying */ - D3DRECT src_rect; - int width, height; - GLint prev_draw; - WINE_GL_BUFFER_TYPE src_buffer_type; - IDirect3DDeviceGLImpl *gl_d3d_dev = (IDirect3DDeviceGLImpl *) This->d3ddevice; - BOOLEAN initial; - DWORD opt_bitmap; - int x, y; - - if (rsrc) { - src_rect.u1.x1 = rsrc->left; - src_rect.u2.y1 = rsrc->top; - src_rect.u3.x2 = rsrc->right; - src_rect.u4.y2 = rsrc->bottom; - } else { - src_rect.u1.x1 = 0; - src_rect.u2.y1 = 0; - src_rect.u3.x2 = src_impl->surface_desc.dwWidth; - src_rect.u4.y2 = src_impl->surface_desc.dwHeight; - } - - width = src_rect.u3.x2 - src_rect.u1.x1; - height = src_rect.u4.y2 - src_rect.u2.y1; - - if ((width != (rect.u3.x2 - rect.u1.x1)) || - (height != (rect.u4.y2 - rect.u2.y1))) { - FIXME(" buffer to buffer copy not supported with stretching yet !\n"); - return DDERR_INVALIDPARAMS; - } - - /* First check if we BLT from the backbuffer... */ - if ((src_impl->surface_desc.ddsCaps.dwCaps & (DDSCAPS_BACKBUFFER)) != 0) { - src_buffer_type = WINE_GL_BUFFER_BACK; - } else if ((src_impl->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER|DDSCAPS_PRIMARYSURFACE)) != 0) { - src_buffer_type = WINE_GL_BUFFER_FRONT; - } else { - ERR("Unexpected case in direct buffer to buffer copy !\n"); - return DDERR_INVALIDPARAMS; - } - - TRACE(" using direct buffer to buffer copy.\n"); - - ENTER_GL(); - - opt_bitmap = d3ddevice_set_state_for_flush(This->d3ddevice, (LPCRECT) &rect, FALSE, &initial); - - if (upload_surface_to_tex_memory_init(This, 0, &gl_d3d_dev->current_internal_format, - initial, FALSE, UNLOCK_TEX_SIZE, UNLOCK_TEX_SIZE) != DD_OK) { - ERR(" unsupported pixel format at direct buffer to buffer copy.\n"); - LEAVE_GL(); - return DDERR_INVALIDPARAMS; - } - - glGetIntegerv(GL_DRAW_BUFFER, &prev_draw); - if (buffer_type == WINE_GL_BUFFER_FRONT) - glDrawBuffer(GL_FRONT); - else - glDrawBuffer(GL_BACK); - - if (src_buffer_type == WINE_GL_BUFFER_FRONT) - glReadBuffer(GL_FRONT); - else - glReadBuffer(GL_BACK); - - /* Now the serious stuff happens. Basically, we copy from the source buffer to the texture memory. - And directly re-draws this on the destination buffer. */ - for (y = 0; y < height; y += UNLOCK_TEX_SIZE) { - int get_height; - - if ((src_rect.u2.y1 + y + UNLOCK_TEX_SIZE) > src_impl->surface_desc.dwHeight) - get_height = src_impl->surface_desc.dwHeight - (src_rect.u2.y1 + y); - else - get_height = UNLOCK_TEX_SIZE; - - for (x = 0; x < width; x += UNLOCK_TEX_SIZE) { - int get_width; - - if ((src_rect.u1.x1 + x + UNLOCK_TEX_SIZE) > src_impl->surface_desc.dwWidth) - get_width = src_impl->surface_desc.dwWidth - (src_rect.u1.x1 + x); - else - get_width = UNLOCK_TEX_SIZE; - - glCopyTexSubImage2D(GL_TEXTURE_2D, 0, - 0, UNLOCK_TEX_SIZE - get_height, - src_rect.u1.x1 + x, src_impl->surface_desc.dwHeight - (src_rect.u2.y1 + y + get_height), - get_width, get_height); - - glBegin(GL_QUADS); - glTexCoord2f(0.0, 0.0); - glVertex3d(rect.u1.x1 + x, - rect.u2.y1 + y + UNLOCK_TEX_SIZE, - 0.5); - glTexCoord2f(1.0, 0.0); - glVertex3d(rect.u1.x1 + x + UNLOCK_TEX_SIZE, - rect.u2.y1 + y + UNLOCK_TEX_SIZE, - 0.5); - glTexCoord2f(1.0, 1.0); - glVertex3d(rect.u1.x1 + x + UNLOCK_TEX_SIZE, - rect.u2.y1 + y, - 0.5); - glTexCoord2f(0.0, 1.0); - glVertex3d(rect.u1.x1 + x, - rect.u2.y1 + y, - 0.5); - glEnd(); - } - } - - upload_surface_to_tex_memory_release(); - d3ddevice_restore_state_after_flush(This->d3ddevice, opt_bitmap, FALSE); - - if (((buffer_type == WINE_GL_BUFFER_FRONT) && (prev_draw == GL_BACK)) || - ((buffer_type == WINE_GL_BUFFER_BACK) && (prev_draw == GL_FRONT))) - glDrawBuffer(prev_draw); - - LEAVE_GL(); - - return DD_OK; - } else { - /* This is the normal 'with source' Blit. Use the texture engine to do the Blt for us - (this prevents calling glReadPixels) */ - D3DRECT src_rect; - int width, height; - GLint prev_draw; - IDirect3DDeviceGLImpl *gl_d3d_dev = (IDirect3DDeviceGLImpl *) This->d3ddevice; - BOOLEAN initial; - DWORD opt_bitmap; - int x, y; - double x_stretch, y_stretch; - - if (rsrc) { - src_rect.u1.x1 = rsrc->left; - src_rect.u2.y1 = rsrc->top; - src_rect.u3.x2 = rsrc->right; - src_rect.u4.y2 = rsrc->bottom; - } else { - src_rect.u1.x1 = 0; - src_rect.u2.y1 = 0; - src_rect.u3.x2 = src_impl->surface_desc.dwWidth; - src_rect.u4.y2 = src_impl->surface_desc.dwHeight; - } - - width = src_rect.u3.x2 - src_rect.u1.x1; - height = src_rect.u4.y2 - src_rect.u2.y1; - - x_stretch = (double) (rect.u3.x2 - rect.u1.x1) / (double) width; - y_stretch = (double) (rect.u4.y2 - rect.u2.y1) / (double) height; - - TRACE(" using memory to buffer Blt override.\n"); - - ENTER_GL(); - - opt_bitmap = d3ddevice_set_state_for_flush(This->d3ddevice, (LPCRECT) &rect, ((dwFlags & DDBLT_KEYSRC) != 0), &initial); - - if (upload_surface_to_tex_memory_init(src_impl, 0, &gl_d3d_dev->current_internal_format, - initial, ((dwFlags & DDBLT_KEYSRC) != 0), UNLOCK_TEX_SIZE, UNLOCK_TEX_SIZE) != DD_OK) { - ERR(" unsupported pixel format at memory to buffer Blt override.\n"); - LEAVE_GL(); - return DDERR_INVALIDPARAMS; - } - - glGetIntegerv(GL_DRAW_BUFFER, &prev_draw); - if (buffer_type == WINE_GL_BUFFER_FRONT) - glDrawBuffer(GL_FRONT); - else - glDrawBuffer(GL_BACK); - - /* Now the serious stuff happens. This is basically the same code as for the memory - flush to frame buffer ... with stretching and different rectangles added :-) */ - for (y = 0; y < height; y += UNLOCK_TEX_SIZE) { - RECT flush_rect; - - flush_rect.top = src_rect.u2.y1 + y; - flush_rect.bottom = ((src_rect.u2.y1 + y + UNLOCK_TEX_SIZE > src_rect.u4.y2) ? - src_rect.u4.y2 : - (src_rect.u2.y1 + y + UNLOCK_TEX_SIZE)); - - for (x = 0; x < width; x += UNLOCK_TEX_SIZE) { - flush_rect.left = src_rect.u1.x1 + x; - flush_rect.right = ((src_rect.u1.x1 + x + UNLOCK_TEX_SIZE > src_rect.u3.x2) ? - src_rect.u3.x2 : - (src_rect.u1.x1 + x + UNLOCK_TEX_SIZE)); - - upload_surface_to_tex_memory(&flush_rect, 0, 0, &(gl_d3d_dev->surface_ptr)); - - glBegin(GL_QUADS); - glTexCoord2f(0.0, 0.0); - glVertex3d(rect.u1.x1 + (x * x_stretch), - rect.u2.y1 + (y * y_stretch), - 0.5); - glTexCoord2f(1.0, 0.0); - glVertex3d(rect.u1.x1 + ((x + UNLOCK_TEX_SIZE) * x_stretch), - rect.u2.y1 + (y * y_stretch), - 0.5); - glTexCoord2f(1.0, 1.0); - glVertex3d(rect.u1.x1 + ((x + UNLOCK_TEX_SIZE) * x_stretch), - rect.u2.y1 + ((y + UNLOCK_TEX_SIZE) * y_stretch), - 0.5); - glTexCoord2f(0.0, 1.0); - glVertex3d(rect.u1.x1 + (x * x_stretch), - rect.u2.y1 + ((y + UNLOCK_TEX_SIZE) * y_stretch), - 0.5); - glEnd(); - } - } - - upload_surface_to_tex_memory_release(); - d3ddevice_restore_state_after_flush(This->d3ddevice, opt_bitmap, ((dwFlags & DDBLT_KEYSRC) != 0)); - - if (((buffer_type == WINE_GL_BUFFER_FRONT) && (prev_draw == GL_BACK)) || - ((buffer_type == WINE_GL_BUFFER_BACK) && (prev_draw == GL_FRONT))) - glDrawBuffer(prev_draw); - - LEAVE_GL(); - - return DD_OK; - } - } - } - return DDERR_INVALIDPARAMS; -} - -HRESULT -d3ddevice_bltfast(IDirectDrawSurfaceImpl *This, DWORD dstx, - DWORD dsty, LPDIRECTDRAWSURFACE7 src, - LPRECT rsrc, DWORD trans) -{ - RECT rsrc2; - RECT rdst; - IDirectDrawSurfaceImpl *src_impl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, src); - IDirect3DDeviceGLImpl *gl_d3d_dev = (IDirect3DDeviceGLImpl *) This->d3ddevice; - WINE_GL_BUFFER_TYPE buffer_type; - GLint prev_draw; - DWORD opt_bitmap; - BOOLEAN initial; - int width, height, x, y; - - /* Cannot support DSTCOLORKEY blitting... */ - if ((trans & DDBLTFAST_DESTCOLORKEY) != 0) return DDERR_INVALIDPARAMS; - - if (rsrc == NULL) { - WARN("rsrc is NULL - getting the whole surface !!\n"); - rsrc = &rsrc2; - rsrc->left = rsrc->top = 0; - rsrc->right = src_impl->surface_desc.dwWidth; - rsrc->bottom = src_impl->surface_desc.dwHeight; - } else { - rsrc2 = *rsrc; - rsrc = &rsrc2; - } - - rdst.left = dstx; - rdst.top = dsty; - rdst.right = dstx + (rsrc->right - rsrc->left); - if (rdst.right > This->surface_desc.dwWidth) { - rsrc->right -= (This->surface_desc.dwWidth - rdst.right); - rdst.right = This->surface_desc.dwWidth; - } - rdst.bottom = dsty + (rsrc->bottom - rsrc->top); - if (rdst.bottom > This->surface_desc.dwHeight) { - rsrc->bottom -= (This->surface_desc.dwHeight - rdst.bottom); - rdst.bottom = This->surface_desc.dwHeight; - } - - width = rsrc->right - rsrc->left; - height = rsrc->bottom - rsrc->top; - - if (setup_rect_and_surface_for_blt(This, &buffer_type, (D3DRECT *) &rdst) != DD_OK) return DDERR_INVALIDPARAMS; - - TRACE(" using BltFast memory to frame buffer override.\n"); - - ENTER_GL(); - - opt_bitmap = d3ddevice_set_state_for_flush(This->d3ddevice, &rdst, (trans & DDBLTFAST_SRCCOLORKEY) != 0, &initial); - - if (upload_surface_to_tex_memory_init(src_impl, 0, &gl_d3d_dev->current_internal_format, - initial, (trans & DDBLTFAST_SRCCOLORKEY) != 0, - UNLOCK_TEX_SIZE, UNLOCK_TEX_SIZE) != DD_OK) { - ERR(" unsupported pixel format at memory to buffer Blt override.\n"); - LEAVE_GL(); - return DDERR_INVALIDPARAMS; - } - - glGetIntegerv(GL_DRAW_BUFFER, &prev_draw); - if (buffer_type == WINE_GL_BUFFER_FRONT) - glDrawBuffer(GL_FRONT); - else - glDrawBuffer(GL_BACK); - - /* Now the serious stuff happens. This is basically the same code that for the memory - flush to frame buffer but with different rectangles for source and destination :-) */ - for (y = 0; y < height; y += UNLOCK_TEX_SIZE) { - RECT flush_rect; - - flush_rect.top = rsrc->top + y; - flush_rect.bottom = ((rsrc->top + y + UNLOCK_TEX_SIZE > rsrc->bottom) ? - rsrc->bottom : - (rsrc->top + y + UNLOCK_TEX_SIZE)); - - for (x = 0; x < width; x += UNLOCK_TEX_SIZE) { - flush_rect.left = rsrc->left + x; - flush_rect.right = ((rsrc->left + x + UNLOCK_TEX_SIZE > rsrc->right) ? - rsrc->right : - (rsrc->left + x + UNLOCK_TEX_SIZE)); - - upload_surface_to_tex_memory(&flush_rect, 0, 0, &(gl_d3d_dev->surface_ptr)); - - glBegin(GL_QUADS); - glTexCoord2f(0.0, 0.0); - glVertex3d(rdst.left + x, - rdst.top + y, - 0.5); - glTexCoord2f(1.0, 0.0); - glVertex3d(rdst.left + (x + UNLOCK_TEX_SIZE), - rdst.top + y, - 0.5); - glTexCoord2f(1.0, 1.0); - glVertex3d(rdst.left + (x + UNLOCK_TEX_SIZE), - rdst.top + (y + UNLOCK_TEX_SIZE), - 0.5); - glTexCoord2f(0.0, 1.0); - glVertex3d(rdst.left + x, - rdst.top + (y + UNLOCK_TEX_SIZE), - 0.5); - glEnd(); - } - } - - upload_surface_to_tex_memory_release(); - d3ddevice_restore_state_after_flush(This->d3ddevice, opt_bitmap, (trans & DDBLTFAST_SRCCOLORKEY) != 0); - - if (((buffer_type == WINE_GL_BUFFER_FRONT) && (prev_draw == GL_BACK)) || - ((buffer_type == WINE_GL_BUFFER_BACK) && (prev_draw == GL_FRONT))) - glDrawBuffer(prev_draw); - - LEAVE_GL(); - - return DD_OK; -} - -void -d3ddevice_set_ortho(IDirect3DDeviceImpl *This) -{ - GLfloat height, width; - GLfloat trans_mat[16]; - - TRACE("(%p)\n", This); - - width = This->surface->surface_desc.dwWidth; - height = This->surface->surface_desc.dwHeight; - - /* The X axis is straighforward.. For the Y axis, we need to convert 'D3D' screen coordinates - * to OpenGL screen coordinates (ie the upper left corner is not the same). - */ - trans_mat[ 0] = 2.0 / width; trans_mat[ 4] = 0.0; trans_mat[ 8] = 0.0; trans_mat[12] = -1.0; - trans_mat[ 1] = 0.0; trans_mat[ 5] = -2.0 / height; trans_mat[ 9] = 0.0; trans_mat[13] = 1.0; -#if 0 - /* It has been checked that in Messiah, which mixes XYZ and XYZRHZ vertex format in the same scene, - * that the Z coordinate needs to be given to GL unchanged. - */ - trans_mat[ 2] = 0.0; trans_mat[ 6] = 0.0; trans_mat[10] = 2.0; trans_mat[14] = -1.0; -#endif - trans_mat[ 2] = 0.0; trans_mat[ 6] = 0.0; trans_mat[10] = 1.0; trans_mat[14] = 0.0; - trans_mat[ 3] = 0.0; trans_mat[ 7] = 0.0; trans_mat[11] = 0.0; trans_mat[15] = 1.0; - - ENTER_GL(); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - /* See the OpenGL Red Book for an explanation of the following translation (in the OpenGL - Correctness Tips section). - - Basically, from what I understood, if the game does not filter the font texture, - as the 'real' pixel will lie at the middle of the two texels, OpenGL may choose the wrong - one and we will have strange artifacts (as the rounding and stuff may give different results - for different pixels, ie sometimes take the left pixel, sometimes the right). - */ - glTranslatef(0.375, 0.375, 0); - glMatrixMode(GL_PROJECTION); - glLoadMatrixf(trans_mat); - LEAVE_GL(); -} - -void -d3ddevice_set_matrices(IDirect3DDeviceImpl *This, DWORD matrices, - D3DMATRIX *world_mat, D3DMATRIX *view_mat, D3DMATRIX *proj_mat) -{ - TRACE("(%p,%08lx,%p,%p,%p)\n", This, matrices, world_mat, view_mat, proj_mat); - - ENTER_GL(); - if ((matrices & (VIEWMAT_CHANGED|WORLDMAT_CHANGED)) != 0) { - glMatrixMode(GL_MODELVIEW); - glLoadMatrixf((float *) view_mat); - - /* Now also re-loads all the Lights and Clipping Planes using the new matrices */ - if (This->state_block.render_state[D3DRENDERSTATE_CLIPPING - 1] != FALSE) { - GLint i; - DWORD runner; - for (i = 0, runner = 0x00000001; i < This->max_clipping_planes; i++, runner <<= 1) { - if (runner & This->state_block.render_state[D3DRENDERSTATE_CLIPPLANEENABLE - 1]) { - GLdouble plane[4]; - - plane[0] = This->clipping_planes[i].plane[0]; - plane[1] = This->clipping_planes[i].plane[1]; - plane[2] = This->clipping_planes[i].plane[2]; - plane[3] = This->clipping_planes[i].plane[3]; - - glClipPlane( GL_CLIP_PLANE0 + i, (const GLdouble*) (&plane) ); - } - } - } - if (This->state_block.render_state[D3DRENDERSTATE_LIGHTING - 1] != FALSE) { - GLint i; - - for (i = 0; i < This->max_active_lights; i++ ) - { - DWORD dwLightIndex = This->active_lights[i]; - if (dwLightIndex != ~0) - { - LPD3DLIGHT7 pLight = &This->light_parameters[dwLightIndex]; - switch (pLight->dltType) - { - case D3DLIGHT_DIRECTIONAL: { - float direction[4]; - float cut_off = 180.0; - - glLightfv(GL_LIGHT0 + i, GL_AMBIENT, (float *) &pLight->dcvAmbient); - glLightfv(GL_LIGHT0 + i, GL_DIFFUSE, (float *) &pLight->dcvDiffuse); - glLightfv(GL_LIGHT0 + i, GL_SPECULAR, (float *) &pLight->dcvSpecular); - glLightfv(GL_LIGHT0 + i, GL_SPOT_CUTOFF, &cut_off); - - direction[0] = pLight->dvDirection.u1.x; - direction[1] = pLight->dvDirection.u2.y; - direction[2] = pLight->dvDirection.u3.z; - direction[3] = 0.0; - glLightfv(GL_LIGHT0 + i, GL_POSITION, (float *) direction); - } break; - - case D3DLIGHT_POINT: { - float position[4]; - float cut_off = 180.0; - - glLightfv(GL_LIGHT0 + i, GL_AMBIENT, (float *) &pLight->dcvAmbient); - glLightfv(GL_LIGHT0 + i, GL_DIFFUSE, (float *) &pLight->dcvDiffuse); - glLightfv(GL_LIGHT0 + i, GL_SPECULAR, (float *) &pLight->dcvSpecular); - position[0] = pLight->dvPosition.u1.x; - position[1] = pLight->dvPosition.u2.y; - position[2] = pLight->dvPosition.u3.z; - position[3] = 1.0; - glLightfv(GL_LIGHT0 + i, GL_POSITION, (float *) position); - glLightfv(GL_LIGHT0 + i, GL_CONSTANT_ATTENUATION, &pLight->dvAttenuation0); - glLightfv(GL_LIGHT0 + i, GL_LINEAR_ATTENUATION, &pLight->dvAttenuation1); - glLightfv(GL_LIGHT0 + i, GL_QUADRATIC_ATTENUATION, &pLight->dvAttenuation2); - glLightfv(GL_LIGHT0 + i, GL_SPOT_CUTOFF, &cut_off); - } break; - - case D3DLIGHT_SPOT: { - float direction[4]; - float position[4]; - float cut_off = 90.0 * (This->light_parameters[i].dvPhi / M_PI); - - glLightfv(GL_LIGHT0 + i, GL_AMBIENT, (float *) &pLight->dcvAmbient); - glLightfv(GL_LIGHT0 + i, GL_DIFFUSE, (float *) &pLight->dcvDiffuse); - glLightfv(GL_LIGHT0 + i, GL_SPECULAR, (float *) &pLight->dcvSpecular); - - direction[0] = pLight->dvDirection.u1.x; - direction[1] = pLight->dvDirection.u2.y; - direction[2] = pLight->dvDirection.u3.z; - direction[3] = 0.0; - glLightfv(GL_LIGHT0 + i, GL_SPOT_DIRECTION, (float *) direction); - position[0] = pLight->dvPosition.u1.x; - position[1] = pLight->dvPosition.u2.y; - position[2] = pLight->dvPosition.u3.z; - position[3] = 1.0; - glLightfv(GL_LIGHT0 + i, GL_POSITION, (float *) position); - glLightfv(GL_LIGHT0 + i, GL_CONSTANT_ATTENUATION, &pLight->dvAttenuation0); - glLightfv(GL_LIGHT0 + i, GL_LINEAR_ATTENUATION, &pLight->dvAttenuation1); - glLightfv(GL_LIGHT0 + i, GL_QUADRATIC_ATTENUATION, &pLight->dvAttenuation2); - glLightfv(GL_LIGHT0 + i, GL_SPOT_CUTOFF, &cut_off); - glLightfv(GL_LIGHT0 + i, GL_SPOT_EXPONENT, &pLight->dvFalloff); - } break; - - default: - /* No warning here as it's already done at light setting */ - break; - } - } - } - } - - glMultMatrixf((float *) world_mat); - } - if ((matrices & PROJMAT_CHANGED) != 0) { - glMatrixMode(GL_PROJECTION); - glLoadMatrixf((float *) proj_mat); - } - LEAVE_GL(); -} - -void -d3ddevice_matrices_updated(IDirect3DDeviceImpl *This, DWORD matrices) -{ - IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This; - DWORD tex_mat, tex_stage; - - TRACE("(%p,%08lx)\n", This, matrices); - - if (matrices & (VIEWMAT_CHANGED|WORLDMAT_CHANGED|PROJMAT_CHANGED)) { - if (glThis->transform_state == GL_TRANSFORM_NORMAL) { - /* This will force an update of the transform state at the next drawing. */ - glThis->transform_state = GL_TRANSFORM_NONE; - } - } - if (matrices & (TEXMAT0_CHANGED|TEXMAT1_CHANGED|TEXMAT2_CHANGED|TEXMAT3_CHANGED| - TEXMAT4_CHANGED|TEXMAT5_CHANGED|TEXMAT6_CHANGED|TEXMAT7_CHANGED)) - { - ENTER_GL(); - for (tex_mat = TEXMAT0_CHANGED, tex_stage = 0; tex_mat <= TEXMAT7_CHANGED; tex_mat <<= 1, tex_stage++) { - GLenum unit = GL_TEXTURE0_WINE + tex_stage; - if (matrices & tex_mat) { - if (This->state_block.texture_stage_state[tex_stage][D3DTSS_TEXTURETRANSFORMFLAGS - 1] != D3DTTFF_DISABLE) { - int is_identity = (memcmp(This->tex_mat[tex_stage], id_mat, 16 * sizeof(D3DVALUE)) != 0); - - if (This->tex_mat_is_identity[tex_stage] != is_identity) { - if (glThis->current_active_tex_unit != unit) { - GL_extensions.glActiveTexture(unit); - glThis->current_active_tex_unit = unit; - } - glMatrixMode(GL_TEXTURE); - glLoadMatrixf((float *) This->tex_mat[tex_stage]); - } - This->tex_mat_is_identity[tex_stage] = is_identity; - } else { - if (This->tex_mat_is_identity[tex_stage] == FALSE) { - if (glThis->current_active_tex_unit != unit) { - GL_extensions.glActiveTexture(unit); - glThis->current_active_tex_unit = unit; - } - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); - This->tex_mat_is_identity[tex_stage] = TRUE; - } - } - } - } - LEAVE_GL(); - } -} - -/* TODO for both these functions : - - change / restore OpenGL parameters for pictures transfers in case they are ever modified - by other OpenGL code in D3D - - handle the case where no 'Begin / EndScene' was done between two locks - - handle the rectangles in the unlock too - - handle pitch correctly... -*/ -static void d3ddevice_lock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect, DWORD dwFlags) -{ - IDirect3DDeviceImpl *d3d_dev = This->d3ddevice; - IDirect3DDeviceGLImpl* gl_d3d_dev = (IDirect3DDeviceGLImpl*) d3d_dev; - WINE_GL_BUFFER_TYPE buffer_type; - RECT loc_rect; - - if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER|DDSCAPS_PRIMARYSURFACE)) != 0) { - buffer_type = WINE_GL_BUFFER_FRONT; - if ((gl_d3d_dev->state[WINE_GL_BUFFER_FRONT] != SURFACE_GL) && - (gl_d3d_dev->lock_surf[WINE_GL_BUFFER_FRONT] != This)) { - ERR("Change of front buffer.. Expect graphic corruptions !\n"); - } - gl_d3d_dev->lock_surf[WINE_GL_BUFFER_FRONT] = This; - } else if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_BACKBUFFER)) == (DDSCAPS_BACKBUFFER)) { - buffer_type = WINE_GL_BUFFER_BACK; - if ((gl_d3d_dev->state[WINE_GL_BUFFER_BACK] != SURFACE_GL) && - (gl_d3d_dev->lock_surf[WINE_GL_BUFFER_BACK] != This)) { - ERR("Change of back buffer.. Expect graphic corruptions !\n"); - } - gl_d3d_dev->lock_surf[WINE_GL_BUFFER_BACK] = This; - } else { - ERR("Wrong surface type for locking !\n"); - return; - } - - if (pRect == NULL) { - loc_rect.top = 0; - loc_rect.left = 0; - loc_rect.bottom = This->surface_desc.dwHeight; - loc_rect.right = This->surface_desc.dwWidth; - pRect = &loc_rect; - } - - /* Try to acquire the device critical section */ - EnterCriticalSection(&(d3d_dev->crit)); - - if (gl_d3d_dev->lock_rect_valid[buffer_type]) { - ERR("Two consecutive locks on %s buffer... Expect problems !\n", - (buffer_type == WINE_GL_BUFFER_BACK ? "back" : "front")); - } - gl_d3d_dev->lock_rect_valid[buffer_type] = TRUE; - - if (gl_d3d_dev->state[buffer_type] != SURFACE_GL) { - /* Check if the new rectangle is in the previous one or not. - If it is not, flush first the previous locks on screen. - */ - if ((pRect->top < gl_d3d_dev->lock_rect[buffer_type].top) || - (pRect->left < gl_d3d_dev->lock_rect[buffer_type].left) || - (pRect->right > gl_d3d_dev->lock_rect[buffer_type].right) || - (pRect->bottom > gl_d3d_dev->lock_rect[buffer_type].bottom)) { - if (gl_d3d_dev->state[buffer_type] == SURFACE_MEMORY_DIRTY) { - TRACE(" flushing back to %s buffer as new rect : (%ldx%ld) - (%ldx%ld) not included in old rect : (%ldx%ld) - (%ldx%ld)\n", - (buffer_type == WINE_GL_BUFFER_BACK ? "back" : "front"), - pRect->left, pRect->top, pRect->right, pRect->bottom, - gl_d3d_dev->lock_rect[buffer_type].left, gl_d3d_dev->lock_rect[buffer_type].top, - gl_d3d_dev->lock_rect[buffer_type].right, gl_d3d_dev->lock_rect[buffer_type].bottom); - d3d_dev->flush_to_framebuffer(d3d_dev, &(gl_d3d_dev->lock_rect[buffer_type]), gl_d3d_dev->lock_surf[buffer_type]); - } - gl_d3d_dev->state[buffer_type] = SURFACE_GL; - gl_d3d_dev->lock_rect[buffer_type] = *pRect; - } - /* In the other case, do not upgrade the locking rectangle as it's no need... */ - } else { - gl_d3d_dev->lock_rect[buffer_type] = *pRect; - } - - if (gl_d3d_dev->state[buffer_type] == SURFACE_GL) { - /* If the surface is already in memory, no need to do anything here... */ - GLenum buffer_format; - GLenum buffer_color; - int y; - char *dst; - - TRACE(" copying %s buffer to main memory with rectangle (%ldx%ld) - (%ldx%ld).\n", (buffer_type == WINE_GL_BUFFER_BACK ? "back" : "front"), - pRect->left, pRect->top, pRect->right, pRect->bottom); - - /* Note that here we cannot do 'optmizations' about the WriteOnly flag... Indeed, a game - may only write to the device... But when we will blit it back to the screen, we need - also to blit correctly the parts the application did not overwrite... */ - - if (((This->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_RGB) != 0) && - (((This->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_ALPHAPIXELS) == 0) || - (This->surface_desc.u4.ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000000))) { - if ((This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 16) && - (This->surface_desc.u4.ddpfPixelFormat.u2.dwRBitMask == 0xF800) && - (This->surface_desc.u4.ddpfPixelFormat.u3.dwGBitMask == 0x07E0) && - (This->surface_desc.u4.ddpfPixelFormat.u4.dwBBitMask == 0x001F)) { - buffer_format = GL_UNSIGNED_SHORT_5_6_5; - buffer_color = GL_RGB; - } else if ((This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 24) && - (This->surface_desc.u4.ddpfPixelFormat.u2.dwRBitMask == 0xFF0000) && - (This->surface_desc.u4.ddpfPixelFormat.u3.dwGBitMask == 0x00FF00) && - (This->surface_desc.u4.ddpfPixelFormat.u4.dwBBitMask == 0x0000FF)) { - buffer_format = GL_UNSIGNED_BYTE; - buffer_color = GL_RGB; - } else if ((This->surface_desc.u4.ddpfPixelFormat.u1.dwRGBBitCount == 32) && - (This->surface_desc.u4.ddpfPixelFormat.u2.dwRBitMask == 0x00FF0000) && - (This->surface_desc.u4.ddpfPixelFormat.u3.dwGBitMask == 0x0000FF00) && - (This->surface_desc.u4.ddpfPixelFormat.u4.dwBBitMask == 0x000000FF)) { - buffer_format = GL_UNSIGNED_INT_8_8_8_8_REV; - buffer_color = GL_BGRA; - } else { - ERR(" unsupported pixel format at device locking.\n"); - return; - } - } else { - ERR(" unsupported pixel format at device locking - alpha on frame buffer.\n"); - return; - } - - ENTER_GL(); - - if (buffer_type == WINE_GL_BUFFER_FRONT) - /* Application wants to lock the front buffer */ - glReadBuffer(GL_FRONT); - else - /* Application wants to lock the back buffer */ - glReadBuffer(GL_BACK); - - dst = ((char *)This->surface_desc.lpSurface) + - (pRect->top * This->surface_desc.u1.lPitch) + (pRect->left * GET_BPP(This->surface_desc)); - - if (This->surface_desc.u1.lPitch != (GET_BPP(This->surface_desc) * This->surface_desc.dwWidth)) { - /* Slow-path in case of 'odd' surfaces. This could be fixed using some GL options, but I - * could not be bothered considering the rare cases where it may be useful :-) - */ - for (y = (This->surface_desc.dwHeight - pRect->top - 1); - y >= ((int) This->surface_desc.dwHeight - (int) pRect->bottom); - y--) { - glReadPixels(pRect->left, y, - pRect->right - pRect->left, 1, - buffer_color, buffer_format, dst); - dst += This->surface_desc.u1.lPitch; - } - } else { - /* Faster path for surface copy. Note that I can use static variables here as I am - * protected by the OpenGL critical section so this function won't be called by - * two threads at the same time. - */ - static char *buffer = NULL; - static int buffer_width = 0; - char *dst2 = dst + ((pRect->bottom - pRect->top) - 1) * This->surface_desc.u1.lPitch; - int current_width = (pRect->right - pRect->left) * GET_BPP(This->surface_desc); - - glReadPixels(pRect->left, ((int) This->surface_desc.dwHeight - (int) pRect->bottom), - pRect->right - pRect->left, pRect->bottom - pRect->top, - buffer_color, buffer_format, dst); - - if (current_width > buffer_width) { - HeapFree(GetProcessHeap(), 0, buffer); - buffer_width = current_width; - buffer = HeapAlloc(GetProcessHeap(), 0, buffer_width); - } - for (y = 0; y < ((pRect->bottom - pRect->top) / 2); y++) { - memcpy(buffer, dst, current_width); - memcpy(dst, dst2, current_width); - memcpy(dst2, buffer, current_width); - dst += This->surface_desc.u1.lPitch; - dst2 -= This->surface_desc.u1.lPitch; - } - } - - gl_d3d_dev->state[buffer_type] = SURFACE_MEMORY; - -#if 0 - /* I keep this code here as it's very useful to debug :-) */ - { - static int flush_count = 0; - char buf[128]; - FILE *f; - - if ((++flush_count % 50) == 0) { - sprintf(buf, "lock_%06d.pnm", flush_count); - f = fopen(buf, "wb"); - DDRAW_dump_surface_to_disk(This, f); - } - } -#endif - - LEAVE_GL(); - } -} - -static void d3ddevice_flush_to_frame_buffer(IDirect3DDeviceImpl *d3d_dev, LPCRECT pRect, IDirectDrawSurfaceImpl *surf) { - RECT loc_rect; - IDirect3DDeviceGLImpl* gl_d3d_dev = (IDirect3DDeviceGLImpl*) d3d_dev; - int x, y; - BOOLEAN initial; - DWORD opt_bitmap; - - /* Note : no need here to lock the 'device critical section' as we are already protected by - the GL critical section. */ - - if (pRect == NULL) { - loc_rect.top = 0; - loc_rect.left = 0; - loc_rect.bottom = d3d_dev->surface->surface_desc.dwHeight; - loc_rect.right = d3d_dev->surface->surface_desc.dwWidth; - pRect = &loc_rect; - } - - TRACE(" flushing memory back to screen memory (%ld,%ld) x (%ld,%ld).\n", pRect->top, pRect->left, pRect->right, pRect->bottom); - - opt_bitmap = d3ddevice_set_state_for_flush(d3d_dev, pRect, FALSE, &initial); - - if (upload_surface_to_tex_memory_init(surf, 0, &gl_d3d_dev->current_internal_format, - initial, FALSE, UNLOCK_TEX_SIZE, UNLOCK_TEX_SIZE) != DD_OK) { - ERR(" unsupported pixel format at frame buffer flush.\n"); - return; - } - - for (y = pRect->top; y < pRect->bottom; y += UNLOCK_TEX_SIZE) { - RECT flush_rect; - - flush_rect.top = y; - flush_rect.bottom = (y + UNLOCK_TEX_SIZE > pRect->bottom) ? pRect->bottom : (y + UNLOCK_TEX_SIZE); - - for (x = pRect->left; x < pRect->right; x += UNLOCK_TEX_SIZE) { - /* First, upload the texture... */ - flush_rect.left = x; - flush_rect.right = (x + UNLOCK_TEX_SIZE > pRect->right) ? pRect->right : (x + UNLOCK_TEX_SIZE); - - upload_surface_to_tex_memory(&flush_rect, 0, 0, &(gl_d3d_dev->surface_ptr)); - - glBegin(GL_QUADS); - glTexCoord2f(0.0, 0.0); - glVertex3d(x, y, 0.5); - glTexCoord2f(1.0, 0.0); - glVertex3d(x + UNLOCK_TEX_SIZE, y, 0.5); - glTexCoord2f(1.0, 1.0); - glVertex3d(x + UNLOCK_TEX_SIZE, y + UNLOCK_TEX_SIZE, 0.5); - glTexCoord2f(0.0, 1.0); - glVertex3d(x, y + UNLOCK_TEX_SIZE, 0.5); - glEnd(); - } - } - - upload_surface_to_tex_memory_release(); - d3ddevice_restore_state_after_flush(d3d_dev, opt_bitmap, FALSE); - -#if 0 - /* I keep this code here as it's very useful to debug :-) */ - { - static int flush_count = 0; - char buf[128]; - FILE *f; - - if ((++flush_count % 50) == 0) { - sprintf(buf, "flush_%06d.pnm", flush_count); - f = fopen(buf, "wb"); - DDRAW_dump_surface_to_disk(surf, f); - } - } -#endif -} - -static void d3ddevice_unlock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect) -{ - WINE_GL_BUFFER_TYPE buffer_type; - IDirect3DDeviceImpl *d3d_dev = This->d3ddevice; - IDirect3DDeviceGLImpl* gl_d3d_dev = (IDirect3DDeviceGLImpl*) d3d_dev; - - if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER|DDSCAPS_PRIMARYSURFACE)) != 0) { - buffer_type = WINE_GL_BUFFER_FRONT; - } else if ((This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_BACKBUFFER)) == (DDSCAPS_BACKBUFFER)) { - buffer_type = WINE_GL_BUFFER_BACK; - } else { - ERR("Wrong surface type for locking !\n"); - return; - } - - if (gl_d3d_dev->lock_rect_valid[buffer_type] == FALSE) { - ERR("Unlock without prior lock on %s buffer... Expect problems !\n", - (buffer_type == WINE_GL_BUFFER_BACK ? "back" : "front")); - } - gl_d3d_dev->lock_rect_valid[buffer_type] = FALSE; - - /* First, check if we need to do anything. For the backbuffer, flushing is done at the next 3D activity. */ - if ((This->lastlocktype & DDLOCK_READONLY) == 0) { - if (buffer_type == WINE_GL_BUFFER_FRONT) { - GLint prev_draw; - - TRACE(" flushing front buffer immediately on screen.\n"); - - ENTER_GL(); - glGetIntegerv(GL_DRAW_BUFFER, &prev_draw); - glDrawBuffer(GL_FRONT); - /* Note: we do not use the application provided lock rectangle but our own stored at - lock time. This is because in old D3D versions, the 'lock' parameter did not - exist. - */ - d3d_dev->flush_to_framebuffer(d3d_dev, &(gl_d3d_dev->lock_rect[WINE_GL_BUFFER_FRONT]), gl_d3d_dev->lock_surf[WINE_GL_BUFFER_FRONT]); - glDrawBuffer(prev_draw); - LEAVE_GL(); - } else { - gl_d3d_dev->state[WINE_GL_BUFFER_BACK] = SURFACE_MEMORY_DIRTY; - } - } - - /* And 'frees' the device critical section */ - LeaveCriticalSection(&(d3d_dev->crit)); -} - -static void -apply_texture_state(IDirect3DDeviceImpl *This) -{ - int stage, state; - - /* Initialize texture stages states */ - for (stage = 0; stage < MAX_TEXTURES; stage++) { - for (state = 0; state < HIGHEST_TEXTURE_STAGE_STATE; state += 1) { - if (This->state_block.set_flags.texture_stage_state[stage][state]) { - IDirect3DDevice7_SetTextureStageState(ICOM_INTERFACE(This, IDirect3DDevice7), - stage, state + 1, This->state_block.texture_stage_state[stage][state]); - } - } - } -} - -HRESULT -d3ddevice_create(IDirect3DDeviceImpl **obj, IDirectDrawImpl *d3d, IDirectDrawSurfaceImpl *surface, int version) -{ - IDirect3DDeviceImpl *object; - IDirect3DDeviceGLImpl *gl_object; - IDirectDrawSurfaceImpl *surf; - HDC device_context; - XVisualInfo *vis; - int num; - int tex_num; - XVisualInfo template; - GLenum buffer = GL_FRONT; - int light; - - object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DDeviceGLImpl)); - if (object == NULL) return DDERR_OUTOFMEMORY; - - gl_object = (IDirect3DDeviceGLImpl *) object; - - object->ref = 1; - object->d3d = d3d; - object->surface = surface; - object->set_context = set_context; - object->clear = d3ddevice_clear_back; - object->set_matrices = d3ddevice_set_matrices; - object->matrices_updated = d3ddevice_matrices_updated; - object->flush_to_framebuffer = d3ddevice_flush_to_frame_buffer; - object->version = version; - - TRACE(" creating OpenGL device for surface = %p, d3d = %p\n", surface, d3d); - - InitializeCriticalSection(&(object->crit)); - - TRACE(" device critical section : %p\n", &(object->crit)); - - device_context = GetDC(surface->ddraw_owner->window); - gl_object->display = get_display(device_context); - gl_object->drawable = get_drawable(device_context); - ReleaseDC(surface->ddraw_owner->window,device_context); - - ENTER_GL(); - template.visualid = (VisualID)GetPropA( GetDesktopWindow(), "__wine_x11_visual_id" ); - vis = XGetVisualInfo(gl_object->display, VisualIDMask, &template, &num); - if (vis == NULL) { - HeapFree(GetProcessHeap(), 0, object); - ERR("No visual found !\n"); - LEAVE_GL(); - return DDERR_INVALIDPARAMS; - } else { - TRACE(" visual found\n"); - } - - gl_object->gl_context = glXCreateContext(gl_object->display, vis, - NULL, GL_TRUE); - - if (gl_object->gl_context == NULL) { - HeapFree(GetProcessHeap(), 0, object); - ERR("Error in context creation !\n"); - LEAVE_GL(); - return DDERR_INVALIDPARAMS; - } else { - TRACE(" context created (%p)\n", gl_object->gl_context); - } - - /* Look for the front buffer and override its surface's Flip method (if in double buffering) */ - for (surf = surface; surf != NULL; surf = surf->surface_owner) { - if ((surf->surface_desc.ddsCaps.dwCaps&(DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER)) == (DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER)) { - surf->aux_ctx = (LPVOID) object; - surf->aux_data = (LPVOID) gl_object->drawable; - surf->aux_flip = opengl_flip; - buffer = GL_BACK; - break; - } - } - /* We are not doing any double buffering.. Then force OpenGL to draw on the front buffer */ - if (surf == NULL) { - TRACE(" no double buffering : drawing on the front buffer\n"); - buffer = GL_FRONT; - } - - for (surf = surface; surf != NULL; surf = surf->surface_owner) { - IDirectDrawSurfaceImpl *surf2; - for (surf2 = surf; surf2->prev_attached != NULL; surf2 = surf2->prev_attached) ; - for (; surf2 != NULL; surf2 = surf2->next_attached) { - TRACE(" checking surface %p :", surf2); - if (((surf2->surface_desc.ddsCaps.dwCaps & (DDSCAPS_3DDEVICE)) == (DDSCAPS_3DDEVICE)) && - ((surf2->surface_desc.ddsCaps.dwCaps & (DDSCAPS_ZBUFFER)) != (DDSCAPS_ZBUFFER))) { - /* Override the Lock / Unlock function for all these surfaces */ - surf2->lock_update_prev = surf2->lock_update; - surf2->lock_update = d3ddevice_lock_update; - surf2->unlock_update_prev = surf2->unlock_update; - surf2->unlock_update = d3ddevice_unlock_update; - /* And install also the blt / bltfast overrides */ - surf2->aux_blt = d3ddevice_blt; - surf2->aux_bltfast = d3ddevice_bltfast; - - TRACE(" overriding direct surface access.\n"); - } else { - TRACE(" no override.\n"); - } - surf2->d3ddevice = object; - } - } - - /* Set the various light parameters */ - object->num_set_lights = 0; - object->max_active_lights = opengl_device_caps.dwMaxActiveLights; - object->light_parameters = NULL; - object->active_lights = HeapAlloc(GetProcessHeap(), 0, - object->max_active_lights * sizeof(object->active_lights[0])); - /* Fill the active light array with ~0, which is used to indicate an - invalid light index. We don't use 0, because it's a valid light index. */ - for (light=0; light < object->max_active_lights; light++) - object->active_lights[light] = ~0; - - - /* Allocate memory for the matrices */ - object->world_mat = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float)); - object->view_mat = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float)); - object->proj_mat = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float)); - memcpy(object->world_mat, id_mat, 16 * sizeof(float)); - memcpy(object->view_mat , id_mat, 16 * sizeof(float)); - memcpy(object->proj_mat , id_mat, 16 * sizeof(float)); - for (tex_num = 0; tex_num < MAX_TEXTURES; tex_num++) { - object->tex_mat[tex_num] = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float)); - memcpy(object->tex_mat[tex_num], id_mat, 16 * sizeof(float)); - object->tex_mat_is_identity[tex_num] = TRUE; - } - - /* Initialisation */ - TRACE(" setting current context\n"); - object->set_context(object); - TRACE(" current context set\n"); - - /* allocate the clipping planes */ - object->max_clipping_planes = opengl_device_caps.wMaxUserClipPlanes; - object->clipping_planes = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->max_clipping_planes * sizeof(d3d7clippingplane)); - - glHint(GL_FOG_HINT,GL_NICEST); - - /* Initialize the various GL contexts to be in sync with what we store locally */ - glClearDepth(0.0); - glClearStencil(0); - glClearColor(0.0, 0.0, 0.0, 0.0); - glDepthMask(GL_TRUE); - gl_object->depth_mask = TRUE; - glEnable(GL_DEPTH_TEST); - gl_object->depth_test = TRUE; - glDisable(GL_ALPHA_TEST); - glDisable(GL_STENCIL_TEST); - glDisable(GL_CULL_FACE); - glDisable(GL_LIGHTING); - glDisable(GL_BLEND); - glDisable(GL_FOG); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - gl_object->current_tex_env = GL_REPLACE; - gl_object->current_active_tex_unit = GL_TEXTURE0_WINE; - if (GL_extensions.glActiveTexture != NULL) { - GL_extensions.glActiveTexture(GL_TEXTURE0_WINE); - } - gl_object->current_alpha_test_ref = 0.0; - gl_object->current_alpha_test_func = GL_ALWAYS; - glAlphaFunc(GL_ALWAYS, 0.0); - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - glDrawBuffer(buffer); - glReadBuffer(buffer); - /* glDisable(GL_DEPTH_TEST); Need here to check for the presence of a ZBuffer and to reenable it when the ZBuffer is attached */ - LEAVE_GL(); - - gl_object->state[WINE_GL_BUFFER_BACK] = SURFACE_GL; - gl_object->state[WINE_GL_BUFFER_FRONT] = SURFACE_GL; - - /* fill_device_capabilities(d3d->ddraw); */ - - ICOM_INIT_INTERFACE(object, IDirect3DDevice, VTABLE_IDirect3DDevice); - ICOM_INIT_INTERFACE(object, IDirect3DDevice2, VTABLE_IDirect3DDevice2); - ICOM_INIT_INTERFACE(object, IDirect3DDevice3, VTABLE_IDirect3DDevice3); - ICOM_INIT_INTERFACE(object, IDirect3DDevice7, VTABLE_IDirect3DDevice7); - - *obj = object; - - TRACE(" creating implementation at %p.\n", *obj); - - /* And finally warn D3D that this device is now present */ - object->d3d->d3d_added_device(object->d3d, object); - - InitDefaultStateBlock(&object->state_block, object->version); - /* Apply default render state and texture stage state values */ - apply_render_state(object, &object->state_block); - apply_texture_state(object); - - /* And fill the fog table with the default fog value */ - build_fog_table(gl_object->fog_table, object->state_block.render_state[D3DRENDERSTATE_FOGCOLOR - 1]); - - return DD_OK; -} - -static void fill_opengl_primcaps(D3DPRIMCAPS *pc) -{ - pc->dwSize = sizeof(*pc); - pc->dwMiscCaps = D3DPMISCCAPS_CONFORMANT | D3DPMISCCAPS_CULLCCW | D3DPMISCCAPS_CULLCW | - D3DPMISCCAPS_LINEPATTERNREP | D3DPMISCCAPS_MASKPLANES | D3DPMISCCAPS_MASKZ; - pc->dwRasterCaps = D3DPRASTERCAPS_DITHER | D3DPRASTERCAPS_FOGRANGE | D3DPRASTERCAPS_FOGTABLE | - D3DPRASTERCAPS_FOGVERTEX | D3DPRASTERCAPS_STIPPLE | D3DPRASTERCAPS_ZBIAS | D3DPRASTERCAPS_ZTEST | D3DPRASTERCAPS_SUBPIXEL | - D3DPRASTERCAPS_ZFOG; - if (GL_extensions.mipmap_lodbias) { - pc->dwRasterCaps |= D3DPRASTERCAPS_MIPMAPLODBIAS; - } - pc->dwZCmpCaps = D3DPCMPCAPS_ALWAYS | D3DPCMPCAPS_EQUAL | D3DPCMPCAPS_GREATER | D3DPCMPCAPS_GREATEREQUAL | - D3DPCMPCAPS_LESS | D3DPCMPCAPS_LESSEQUAL | D3DPCMPCAPS_NEVER | D3DPCMPCAPS_NOTEQUAL; - pc->dwSrcBlendCaps = D3DPBLENDCAPS_ZERO | D3DPBLENDCAPS_ONE | D3DPBLENDCAPS_DESTCOLOR | D3DPBLENDCAPS_INVDESTCOLOR | - D3DPBLENDCAPS_SRCALPHA | D3DPBLENDCAPS_INVSRCALPHA | D3DPBLENDCAPS_DESTALPHA | D3DPBLENDCAPS_INVDESTALPHA | D3DPBLENDCAPS_SRCALPHASAT | - D3DPBLENDCAPS_BOTHSRCALPHA | D3DPBLENDCAPS_BOTHINVSRCALPHA; - pc->dwDestBlendCaps = D3DPBLENDCAPS_ZERO | D3DPBLENDCAPS_ONE | D3DPBLENDCAPS_SRCCOLOR | D3DPBLENDCAPS_INVSRCCOLOR | - D3DPBLENDCAPS_SRCALPHA | D3DPBLENDCAPS_INVSRCALPHA | D3DPBLENDCAPS_DESTALPHA | D3DPBLENDCAPS_INVDESTALPHA | D3DPBLENDCAPS_SRCALPHASAT | - D3DPBLENDCAPS_BOTHSRCALPHA | D3DPBLENDCAPS_BOTHINVSRCALPHA; - pc->dwAlphaCmpCaps = D3DPCMPCAPS_ALWAYS | D3DPCMPCAPS_EQUAL | D3DPCMPCAPS_GREATER | D3DPCMPCAPS_GREATEREQUAL | - D3DPCMPCAPS_LESS | D3DPCMPCAPS_LESSEQUAL | D3DPCMPCAPS_NEVER | D3DPCMPCAPS_NOTEQUAL; - pc->dwShadeCaps = D3DPSHADECAPS_ALPHAFLATBLEND | D3DPSHADECAPS_ALPHAGOURAUDBLEND | D3DPSHADECAPS_COLORFLATRGB | D3DPSHADECAPS_COLORGOURAUDRGB | - D3DPSHADECAPS_FOGFLAT | D3DPSHADECAPS_FOGGOURAUD | D3DPSHADECAPS_SPECULARFLATRGB | D3DPSHADECAPS_SPECULARGOURAUDRGB; - pc->dwTextureCaps = D3DPTEXTURECAPS_ALPHA | D3DPTEXTURECAPS_ALPHAPALETTE | D3DPTEXTURECAPS_BORDER | D3DPTEXTURECAPS_PERSPECTIVE | - D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_TRANSPARENCY; - pc->dwTextureFilterCaps = D3DPTFILTERCAPS_LINEAR | D3DPTFILTERCAPS_LINEARMIPLINEAR | D3DPTFILTERCAPS_LINEARMIPNEAREST | - D3DPTFILTERCAPS_MIPLINEAR | D3DPTFILTERCAPS_MIPNEAREST | D3DPTFILTERCAPS_NEAREST | D3DPTFILTERCAPS_MAGFLINEAR | - D3DPTFILTERCAPS_MAGFPOINT | D3DPTFILTERCAPS_MINFLINEAR | D3DPTFILTERCAPS_MINFPOINT | D3DPTFILTERCAPS_MIPFLINEAR | - D3DPTFILTERCAPS_MIPFPOINT; - pc->dwTextureBlendCaps = D3DPTBLENDCAPS_ADD | D3DPTBLENDCAPS_COPY | D3DPTBLENDCAPS_DECAL | D3DPTBLENDCAPS_DECALALPHA | D3DPTBLENDCAPS_DECALMASK | - D3DPTBLENDCAPS_MODULATE | D3DPTBLENDCAPS_MODULATEALPHA | D3DPTBLENDCAPS_MODULATEMASK; - pc->dwTextureAddressCaps = D3DPTADDRESSCAPS_BORDER | D3DPTADDRESSCAPS_CLAMP | D3DPTADDRESSCAPS_WRAP | D3DPTADDRESSCAPS_INDEPENDENTUV; - if (GL_extensions.mirrored_repeat) { - pc->dwTextureAddressCaps |= D3DPTADDRESSCAPS_MIRROR; - } - pc->dwStippleWidth = 32; - pc->dwStippleHeight = 32; -} - -static void fill_caps(void) -{ - GLint max_clip_planes; - GLint depth_bits; - - /* Fill first all the fields with default values which will be overriden later on with - correct ones from the GL code - */ - opengl_device_caps.dwDevCaps = D3DDEVCAPS_CANRENDERAFTERFLIP | D3DDEVCAPS_DRAWPRIMTLVERTEX | D3DDEVCAPS_EXECUTESYSTEMMEMORY | - D3DDEVCAPS_EXECUTEVIDEOMEMORY | D3DDEVCAPS_FLOATTLVERTEX | D3DDEVCAPS_TEXTURENONLOCALVIDMEM | D3DDEVCAPS_TEXTURESYSTEMMEMORY | - D3DDEVCAPS_TEXTUREVIDEOMEMORY | D3DDEVCAPS_TLVERTEXSYSTEMMEMORY | D3DDEVCAPS_TLVERTEXVIDEOMEMORY | - /* D3D 7 capabilities */ - D3DDEVCAPS_DRAWPRIMITIVES2 /*| D3DDEVCAPS_HWTRANSFORMANDLIGHT*/ | D3DDEVCAPS_HWRASTERIZATION | D3DDEVCAPS_DRAWPRIMITIVES2EX; - fill_opengl_primcaps(&(opengl_device_caps.dpcLineCaps)); - fill_opengl_primcaps(&(opengl_device_caps.dpcTriCaps)); - opengl_device_caps.dwDeviceRenderBitDepth = DDBD_16|DDBD_24|DDBD_32; - opengl_device_caps.dwMinTextureWidth = 1; - opengl_device_caps.dwMinTextureHeight = 1; - opengl_device_caps.dwMaxTextureWidth = 1024; - opengl_device_caps.dwMaxTextureHeight = 1024; - opengl_device_caps.dwMaxTextureRepeat = 16; - opengl_device_caps.dwMaxTextureAspectRatio = 1024; - opengl_device_caps.dwMaxAnisotropy = 0; - opengl_device_caps.dvGuardBandLeft = 0.0; - opengl_device_caps.dvGuardBandRight = 0.0; - opengl_device_caps.dvGuardBandTop = 0.0; - opengl_device_caps.dvGuardBandBottom = 0.0; - opengl_device_caps.dvExtentsAdjust = 0.0; - opengl_device_caps.dwStencilCaps = D3DSTENCILCAPS_DECRSAT | D3DSTENCILCAPS_INCRSAT | D3DSTENCILCAPS_INVERT | D3DSTENCILCAPS_KEEP | - D3DSTENCILCAPS_REPLACE | D3DSTENCILCAPS_ZERO; - opengl_device_caps.dwTextureOpCaps = D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_SELECTARG2 | D3DTEXOPCAPS_MODULATE4X | - D3DTEXOPCAPS_MODULATE2X | D3DTEXOPCAPS_MODULATE | D3DTEXOPCAPS_ADD | D3DTEXOPCAPS_ADDSIGNED2X | D3DTEXOPCAPS_ADDSIGNED | - D3DTEXOPCAPS_BLENDDIFFUSEALPHA | D3DTEXOPCAPS_BLENDTEXTUREALPHA | D3DTEXOPCAPS_BLENDFACTORALPHA | D3DTEXOPCAPS_BLENDCURRENTALPHA; - if (GL_extensions.max_texture_units != 0) { - opengl_device_caps.wMaxTextureBlendStages = GL_extensions.max_texture_units; - opengl_device_caps.wMaxSimultaneousTextures = GL_extensions.max_texture_units; - opengl_device_caps.dwFVFCaps = D3DFVFCAPS_DONOTSTRIPELEMENTS | GL_extensions.max_texture_units; - } else { - opengl_device_caps.wMaxTextureBlendStages = 1; - opengl_device_caps.wMaxSimultaneousTextures = 1; - opengl_device_caps.dwFVFCaps = D3DFVFCAPS_DONOTSTRIPELEMENTS | 1; - } - opengl_device_caps.dwMaxActiveLights = 16; - opengl_device_caps.dvMaxVertexW = 100000000.0; /* No idea exactly what to put here... */ - opengl_device_caps.deviceGUID = IID_IDirect3DTnLHalDevice; - opengl_device_caps.wMaxUserClipPlanes = 1; - opengl_device_caps.wMaxVertexBlendMatrices = 0; - opengl_device_caps.dwVertexProcessingCaps = D3DVTXPCAPS_TEXGEN | D3DVTXPCAPS_MATERIALSOURCE7 | D3DVTXPCAPS_VERTEXFOG | - D3DVTXPCAPS_DIRECTIONALLIGHTS | D3DVTXPCAPS_POSITIONALLIGHTS | D3DVTXPCAPS_LOCALVIEWER; - opengl_device_caps.dwReserved1 = 0; - opengl_device_caps.dwReserved2 = 0; - opengl_device_caps.dwReserved3 = 0; - opengl_device_caps.dwReserved4 = 0; - - /* And now some GL overrides :-) */ - glGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint *) &opengl_device_caps.dwMaxTextureWidth); - opengl_device_caps.dwMaxTextureHeight = opengl_device_caps.dwMaxTextureWidth; - opengl_device_caps.dwMaxTextureAspectRatio = opengl_device_caps.dwMaxTextureWidth; - TRACE(": max texture size = %ld\n", opengl_device_caps.dwMaxTextureWidth); - - glGetIntegerv(GL_MAX_LIGHTS, (GLint *) &opengl_device_caps.dwMaxActiveLights); - TRACE(": max active lights = %ld\n", opengl_device_caps.dwMaxActiveLights); - - glGetIntegerv(GL_MAX_CLIP_PLANES, &max_clip_planes); - opengl_device_caps.wMaxUserClipPlanes = max_clip_planes; - TRACE(": max clipping planes = %d\n", opengl_device_caps.wMaxUserClipPlanes); - - glGetIntegerv(GL_DEPTH_BITS, &depth_bits); - TRACE(": Z bits = %d\n", depth_bits); - switch (depth_bits) { - case 16: opengl_device_caps.dwDeviceZBufferBitDepth = DDBD_16; break; - case 24: opengl_device_caps.dwDeviceZBufferBitDepth = DDBD_16|DDBD_24; break; - case 32: - default: opengl_device_caps.dwDeviceZBufferBitDepth = DDBD_16|DDBD_24|DDBD_32; break; - } -} - -BOOL -d3ddevice_init_at_startup(void *gl_handle) -{ - XVisualInfo template; - XVisualInfo *vis; - HDC device_context; - Display *display; - Visual *visual; - Drawable drawable = (Drawable) GetPropA(GetDesktopWindow(), "__wine_x11_whole_window"); - XWindowAttributes win_attr; - GLXContext gl_context; - int num; - const char *glExtensions; - const char *glVersion; - const char *glXExtensions = NULL; - const void *(*pglXGetProcAddressARB)(const GLubyte *) = NULL; - int major, minor, patch, num_parsed; - - TRACE("Initializing GL...\n"); - - if (!drawable) - { - WARN("x11drv not loaded - D3D support disabled!\n"); - return FALSE; - } - - /* Get a default rendering context to have the 'caps' function query some info from GL */ - device_context = GetDC(0); - display = get_display(device_context); - ReleaseDC(0, device_context); - - ENTER_GL(); - if (XGetWindowAttributes(display, drawable, &win_attr)) { - visual = win_attr.visual; - } else { - visual = DefaultVisual(display, DefaultScreen(display)); - } - template.visualid = XVisualIDFromVisual(visual); - vis = XGetVisualInfo(display, VisualIDMask, &template, &num); - if (vis == NULL) { - LEAVE_GL(); - WARN("Error creating visual info for capabilities initialization - D3D support disabled !\n"); - return FALSE; - } - gl_context = glXCreateContext(display, vis, NULL, GL_TRUE); - XFree(vis); - - if (gl_context == NULL) { - LEAVE_GL(); - WARN("Error creating default context for capabilities initialization - D3D support disabled !\n"); - return FALSE; - } - if (glXMakeCurrent(display, drawable, gl_context) == False) { - glXDestroyContext(display, gl_context); - LEAVE_GL(); - WARN("Error setting default context as current for capabilities initialization - D3D support disabled !\n"); - return FALSE; - } - - /* Then, query all extensions */ - glXExtensions = glXQueryExtensionsString(display, DefaultScreen(display)); /* Note: not used right now but will for PBuffers */ - glExtensions = (const char *) glGetString(GL_EXTENSIONS); - glVersion = (const char *) glGetString(GL_VERSION); - if (gl_handle != NULL) { - pglXGetProcAddressARB = wine_dlsym(gl_handle, "glXGetProcAddressARB", NULL, 0); - } - - /* Parse the GL version string */ - num_parsed = sscanf(glVersion, "%d.%d.%d", &major, &minor, &patch); - if (num_parsed == 1) { - minor = 0; - patch = 0; - } else if (num_parsed == 2) { - patch = 0; - } - TRACE("GL version %d.%d.%d\n", major, minor, patch); - - /* And starts to fill the extension context properly */ - memset(&GL_extensions, 0, sizeof(GL_extensions)); - TRACE("GL supports following extensions used by Wine :\n"); - - /* Mirrored Repeat extension : - - GL_ARB_texture_mirrored_repeat - - GL_IBM_texture_mirrored_repeat - - GL >= 1.4 - */ - if ((strstr(glExtensions, "GL_ARB_texture_mirrored_repeat")) || - (strstr(glExtensions, "GL_IBM_texture_mirrored_repeat")) || - (major > 1) || - ((major == 1) && (minor >= 4))) { - TRACE(" - mirrored repeat\n"); - GL_extensions.mirrored_repeat = TRUE; - } - - /* Texture LOD Bias : - - GL_EXT_texture_lod_bias - */ - if (strstr(glExtensions, "GL_EXT_texture_lod_bias")) { - TRACE(" - texture lod bias\n"); - GL_extensions.mipmap_lodbias = TRUE; - } - - /* For all subsequent extensions, we need glXGetProcAddress */ - if (pglXGetProcAddressARB != NULL) { - /* Multi-texturing : - - GL_ARB_multitexture - - GL >= 1.2.1 - */ - if ((strstr(glExtensions, "GL_ARB_multitexture")) || - (major > 1) || - ((major == 1) && (minor > 2)) || - ((major == 1) && (minor == 2) && (patch >= 1))) { - glGetIntegerv(GL_MAX_TEXTURE_UNITS_WINE, &(GL_extensions.max_texture_units)); - TRACE(" - multi-texturing (%d stages)\n", GL_extensions.max_texture_units); - /* We query the ARB version to be the most portable we can... */ - GL_extensions.glActiveTexture = pglXGetProcAddressARB( (const GLubyte *) "glActiveTextureARB"); - GL_extensions.glMultiTexCoord[0] = pglXGetProcAddressARB( (const GLubyte *) "glMultiTexCoord1fvARB"); - GL_extensions.glMultiTexCoord[1] = pglXGetProcAddressARB( (const GLubyte *) "glMultiTexCoord2fvARB"); - GL_extensions.glMultiTexCoord[2] = pglXGetProcAddressARB( (const GLubyte *) "glMultiTexCoord3fvARB"); - GL_extensions.glMultiTexCoord[3] = pglXGetProcAddressARB( (const GLubyte *) "glMultiTexCoord4fvARB"); - GL_extensions.glClientActiveTexture = pglXGetProcAddressARB( (const GLubyte *) "glClientActiveTextureARB"); - } else { - GL_extensions.max_texture_units = 0; - } - - if (strstr(glExtensions, "GL_EXT_texture_compression_s3tc")) { - TRACE(" - S3TC compression supported\n"); - GL_extensions.s3tc_compressed_texture = TRUE; - GL_extensions.glCompressedTexImage2D = pglXGetProcAddressARB( (const GLubyte *) "glCompressedTexImage2DARB"); - GL_extensions.glCompressedTexSubImage2D = pglXGetProcAddressARB( (const GLubyte *) "glCompressedTexSubImage2DARB"); - } - } - - /* Fill the D3D capabilities according to what GL tells us... */ - fill_caps(); - - /* And frees this now-useless context */ - glXMakeCurrent(display, None, NULL); - glXDestroyContext(display, gl_context); - LEAVE_GL(); - - return TRUE; -} diff --git a/dlls/ddraw/direct3d.c b/dlls/ddraw/direct3d.c new file mode 100644 index 0000000000..4691ebf144 --- /dev/null +++ b/dlls/ddraw/direct3d.c @@ -0,0 +1,1394 @@ +/* + * Copyright (c) 2006 Stefan Dösinger + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include "wine/port.h" +#include "wine/debug.h" + +#include +#include +#include +#include + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "winnls.h" +#include "winerror.h" +#include "wingdi.h" +#include "wine/exception.h" +#include "excpt.h" + +#include "ddraw.h" +#include "d3d.h" + +#include "ddraw_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d3d7); + +/***************************************************************************** + * IUnknown Methods. Common for Version 1, 2, 3 and 7 + * + * These are thunks which relay to IDirectDraw. See ddraw.c for + * details + * + *****************************************************************************/ +static HRESULT WINAPI +Thunk_IDirect3DImpl_7_QueryInterface(IDirect3D7 *iface, + REFIID refiid, + void **obj) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D7, iface); + TRACE("(%p)->(%s,%p): Thunking to IDirectDraw7\n", This, debugstr_guid(refiid), obj); + + return IDirectDraw7_QueryInterface(ICOM_INTERFACE(This, IDirectDraw7), + refiid, + obj); +} + +static HRESULT WINAPI +Thunk_IDirect3DImpl_3_QueryInterface(IDirect3D3 *iface, + REFIID refiid, + void **obj) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface); + TRACE("(%p)->(%s,%p): Thunking to IDirectDraw7\n", This, debugstr_guid(refiid), obj); + + return IDirectDraw7_QueryInterface(ICOM_INTERFACE(This, IDirectDraw7), + refiid, + obj); +} + +static HRESULT WINAPI +Thunk_IDirect3DImpl_2_QueryInterface(IDirect3D2 *iface, + REFIID refiid, + void **obj) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D2, iface); + TRACE("(%p)->(%s,%p): Thunking to IDirectDraw7\n", This, debugstr_guid(refiid), obj); + + return IDirectDraw7_QueryInterface(ICOM_INTERFACE(This, IDirectDraw7), + refiid, + obj); +} + +static HRESULT WINAPI +Thunk_IDirect3DImpl_1_QueryInterface(IDirect3D *iface, + REFIID refiid, + void **obj) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D, iface); + TRACE("(%p)->(%s,%p): Thunking to IDirectDraw7\n", This, debugstr_guid(refiid), obj); + + return IDirectDraw7_QueryInterface(ICOM_INTERFACE(This, IDirectDraw7), + refiid, + obj); +} + +static ULONG WINAPI +Thunk_IDirect3DImpl_7_AddRef(IDirect3D7 *iface) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D7, iface); + TRACE("(%p) : Thunking to IDirectDraw7\n", This); + + return IDirectDraw7_AddRef(ICOM_INTERFACE(This, IDirectDraw7)); +} + +static ULONG WINAPI +Thunk_IDirect3DImpl_3_AddRef(IDirect3D3 *iface) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface); + TRACE("(%p) : Thunking to IDirectDraw7\n", This); + + return IDirectDraw7_AddRef(ICOM_INTERFACE(This, IDirectDraw7)); +} + +static ULONG WINAPI +Thunk_IDirect3DImpl_2_AddRef(IDirect3D2 *iface) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D2, iface); + TRACE("(%p) : Thunking to IDirectDraw7\n", This); + + return IDirectDraw7_AddRef(ICOM_INTERFACE(This, IDirectDraw7)); +} + +static ULONG WINAPI +Thunk_IDirect3DImpl_1_AddRef(IDirect3D *iface) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D, iface); + TRACE("(%p) : Thunking to IDirectDraw7\n", This); + + return IDirectDraw7_AddRef(ICOM_INTERFACE(This, IDirectDraw7)); +} + +static ULONG WINAPI +Thunk_IDirect3DImpl_7_Release(IDirect3D7 *iface) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D7, iface); + TRACE("(%p) : Thunking to IDirectDraw7", This); + + return IDirectDraw7_Release(ICOM_INTERFACE(This, IDirectDraw7)); +} + +static ULONG WINAPI +Thunk_IDirect3DImpl_3_Release(IDirect3D3 *iface) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface); + TRACE("(%p) : Thunking to IDirectDraw7", This); + + return IDirectDraw7_Release(ICOM_INTERFACE(This, IDirectDraw7)); +} + +static ULONG WINAPI +Thunk_IDirect3DImpl_2_Release(IDirect3D2 *iface) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D2, iface); + TRACE("(%p) : Thunking to IDirectDraw7", This); + + return IDirectDraw7_Release(ICOM_INTERFACE(This, IDirectDraw7)); +} + +static ULONG WINAPI +Thunk_IDirect3DImpl_1_Release(IDirect3D *iface) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D, iface); + TRACE("(%p) : Thunking to IDirectDraw7", This); + + return IDirectDraw7_Release(ICOM_INTERFACE(This, IDirectDraw7)); +} + +/***************************************************************************** + * IDirect3D Methods + *****************************************************************************/ + +/***************************************************************************** + * IDirect3D::Initialize + * + * Initializes the IDirect3D interface. This is a no-op implementation, + * as all initialization is done at create time. + * + * Version 1 + * + * Params: + * refiid: ? + * + * Returns: + * D3D_OK, because it's a no-op + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DImpl_1_Initialize(IDirect3D *iface, + REFIID refiid) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D, iface); + + TRACE("(%p)->(%s) no-op...\n", This, debugstr_guid(refiid)); + return D3D_OK; +} + +/***************************************************************************** + * IDirect3D7::EnumDevices + * + * The EnumDevices method for IDirect3D7. It enumerates all supported + * D3D7 devices. Currently there's only one. + * + * Params: + * Callback: Function to call for each enumerated device + * Context: Pointer to pass back to the app + * + * Returns: + * D3D_OK, or the return value of the GetCaps call + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DImpl_7_EnumDevices(IDirect3D7 *iface, + LPD3DENUMDEVICESCALLBACK7 Callback, + void *Context) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D7, iface); + char interface_name[] = "WINE Direct3D7 using WineD3D"; + char device_name[] = "Wine D3D7 device"; + D3DDEVICEDESC7 ddesc; + D3DDEVICEDESC oldDesc; + HRESULT hr; + + TRACE("(%p)->(%p,%p)\n", This, Callback, Context); + + TRACE("(%p) Enumerating WineD3D D3Device7 interface\n", This); + hr = IDirect3DImpl_GetCaps(This->wineD3D, &oldDesc, &ddesc); + if(hr != D3D_OK) return hr; + Callback(interface_name, device_name, &ddesc, Context); + + TRACE("(%p) End of enumeration\n", This); + return D3D_OK; +} + +/***************************************************************************** + * IDirect3D3::EnumDevices + * + * Enumerates all supported Direct3DDevice interfaces. This is the + * implementation for Direct3D 1 to Direc3D 3, Version 7 has it's own. + * + * Version 1, 2 and 3 + * + * Params: + * Callback: Application-provided routine to call for each enumerated device + * Context: Pointer to pass to the callback + * + * Returns: + * D3D_OK on success, + * The result of IDirect3DImpl_GetCaps if it failed + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DImpl_3_EnumDevices(IDirect3D3 *iface, + LPD3DENUMDEVICESCALLBACK Callback, + void *Context) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface); + D3DDEVICEDESC dref, d1, d2; + D3DDEVICEDESC7 newDesc; + HRESULT hr; + + /* Some games (Motoracer 2 demo) have the bad idea to modify the device name string. + Let's put the string in a sufficiently sized array in writable memory. */ + char device_name[50]; + strcpy(device_name,"direct3d"); + + TRACE("(%p)->(%p,%p)\n", This, Callback, Context); + + hr = IDirect3DImpl_GetCaps(This->wineD3D, &dref, &newDesc); + if(hr != D3D_OK) return hr; + + /* Do I have to enumerate the reference id? I try without. Note from old d3d7: + * "It seems that enumerating the reference IID on Direct3D 1 games + * (AvP / Motoracer2) breaks them". So do not enumerate this iid in V1 + * + * There's a registry key HKLM\Software\Microsoft\Direct3D\Drivers, EnumReference + * which enables / disables enumerating the reference rasterizer. It's a DWORD, + * 0 means disabled, 2 means enabled. The enablerefrast.reg and disablerefrast.reg + * files in the DirectX 7.0 sdk demo directory suggest this. + */ + + TRACE("(%p) Enumerating WineD3D D3DDevice interface\n", This); + d1 = dref; + d2 = dref; + Callback( (LPIID) &IID_D3DDEVICE_WineD3D, "Wine D3DDevice using WineD3D and OpenGL", device_name, &d1, &d2, Context); + TRACE("(%p) End of enumeration\n", This); + if(hr != D3DENUMRET_OK) return D3D_OK; + + return D3D_OK; +} + +static HRESULT WINAPI +Thunk_IDirect3DImpl_2_EnumDevices(IDirect3D2 *iface, + LPD3DENUMDEVICESCALLBACK Callback, + void *Context) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D2, iface); + TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", This, Callback, Context); + return IDirect3D3_EnumDevices(ICOM_INTERFACE(This, IDirect3D3), + Callback, + Context); +} + +static HRESULT WINAPI +Thunk_IDirect3DImpl_1_EnumDevices(IDirect3D *iface, + LPD3DENUMDEVICESCALLBACK Callback, + void *Context) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D, iface); + TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", This, Callback, Context); + return IDirect3D3_EnumDevices(ICOM_INTERFACE(This, IDirect3D3), + Callback, + Context); +} + +/***************************************************************************** + * IDirect3D3::CreateLight + * + * Creates an IDirect3DLight interface. This interface is used in + * Direct3D3 or earlier for lighting. In Direct3D7 it has been replaced + * by the DIRECT3DLIGHT7 structure. Wine's Direct3DLight implementation + * uses the IDirect3DDevice7 interface with D3D7 lights. + * + * Version 1, 2 and 3 + * + * Params: + * Light: Address to store the new interface pointer + * UnkOuter: Basically for aggregation, but ddraw doesn't support it. + * Must be NULL + * + * Returns: + * D3D_OK on success + * DDERR_OUTOFMEMORY if memory allocation failed + * CLASS_E_NOAGGREGATION if UnkOuter != NULL + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DImpl_3_CreateLight(IDirect3D3 *iface, + IDirect3DLight **Light, + IUnknown *UnkOuter ) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface); + IDirect3DLightImpl *object; + + TRACE("(%p)->(%p,%p)\n", This, Light, UnkOuter); + + if(UnkOuter) + return CLASS_E_NOAGGREGATION; + + object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DLightImpl)); + if (object == NULL) + return DDERR_OUTOFMEMORY; + + ICOM_INIT_INTERFACE(object, IDirect3DLight, IDirect3DLight_Vtbl); + object->ref = 1; + object->ddraw = This; + object->next = NULL; + object->active_viewport = NULL; + + /* Update functions */ + object->activate = light_update; + object->desactivate = light_activate; + object->update = light_desactivate; + object->active_viewport = NULL; + + *Light = ICOM_INTERFACE(object, IDirect3DLight); + + TRACE("(%p) creating implementation at %p.\n", This, object); + + return D3D_OK; +} + +static HRESULT WINAPI +Thunk_IDirect3DImpl_2_CreateLight(IDirect3D2 *iface, + IDirect3DLight **Direct3DLight, + IUnknown *UnkOuter) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D2, iface); + TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", This, Direct3DLight, UnkOuter); + return IDirect3D3_CreateLight(ICOM_INTERFACE(This, IDirect3D3), + Direct3DLight, + UnkOuter); +} + +static HRESULT WINAPI +Thunk_IDirect3DImpl_1_CreateLight(IDirect3D *iface, + IDirect3DLight **Direct3DLight, + IUnknown *UnkOuter) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D, iface); + TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", This, Direct3DLight, UnkOuter); + return IDirect3D3_CreateLight(ICOM_INTERFACE(This, IDirect3D3), + Direct3DLight, + UnkOuter); +} + +/***************************************************************************** + * IDirect3D3::CreateMaterial + * + * Creates an IDirect3DMaterial interface. This interface is used by Direct3D3 + * and older versions. The IDirect3DMaterial implementation wraps it's + * functionality to IDirect3DDevice7::SetMaterial and friends. + * + * Version 1, 2 and 3 + * + * Params: + * Material: Address to store the new interface's pointer to + * UnkOuter: Basically for aggregation, but ddraw doesn't support it. + * Must be NULL + * + * Returns: + * D3D_OK on success + * DDERR_OUTOFMEMORY if memory allocation failed + * CLASS_E_NOAGGREGATION if UnkOuter != NULL + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DImpl_3_CreateMaterial(IDirect3D3 *iface, + IDirect3DMaterial3 **Material, + IUnknown *UnkOuter ) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface); + IDirect3DMaterialImpl *object; + + TRACE("(%p)->(%p,%p)\n", This, Material, UnkOuter); + + if(UnkOuter) + return CLASS_E_NOAGGREGATION; + + object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DMaterialImpl)); + if (object == NULL) + return DDERR_OUTOFMEMORY; + + ICOM_INIT_INTERFACE(object, IDirect3DMaterial3, IDirect3DMaterial3_Vtbl); + ICOM_INIT_INTERFACE(object, IDirect3DMaterial2, IDirect3DMaterial2_Vtbl); + ICOM_INIT_INTERFACE(object, IDirect3DMaterial, IDirect3DMaterial_Vtbl); + object->ref = 1; + object->ddraw = This; + object->activate = material_activate; + + *Material = ICOM_INTERFACE(object, IDirect3DMaterial3); + + TRACE("(%p) creating implementation at %p.\n", This, object); + + return D3D_OK; +} + +static HRESULT WINAPI +Thunk_IDirect3DImpl_2_CreateMaterial(IDirect3D2 *iface, + IDirect3DMaterial2 **Direct3DMaterial, + IUnknown* UnkOuter) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D2, iface); + HRESULT ret; + IDirect3DMaterial3 *ret_val; + + TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", This, Direct3DMaterial, UnkOuter); + ret = IDirect3D3_CreateMaterial(ICOM_INTERFACE(This, IDirect3D3), + &ret_val, + UnkOuter); + + *Direct3DMaterial = COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial3, IDirect3DMaterial2, ret_val); + + TRACE(" returning interface %p.\n", *Direct3DMaterial); + + return ret; +} + +static HRESULT WINAPI +Thunk_IDirect3DImpl_1_CreateMaterial(IDirect3D *iface, + IDirect3DMaterial **Direct3DMaterial, + IUnknown* UnkOuter) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D, iface); + HRESULT ret; + LPDIRECT3DMATERIAL3 ret_val; + + TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", This, Direct3DMaterial, UnkOuter); + ret = IDirect3D3_CreateMaterial(ICOM_INTERFACE(This, IDirect3D3), + &ret_val, + UnkOuter); + + *Direct3DMaterial = COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial3, IDirect3DMaterial, ret_val); + + TRACE(" returning interface %p.\n", *Direct3DMaterial); + + return ret; +} + +/***************************************************************************** + * IDirect3D3::CreateViewport + * + * Creates an IDirect3DViewport interface. This interface is used + * by Direct3D and earlier versions for Viewport management. In Direct3D7 + * it has been replaced by a viewport structure and + * IDirect3DDevice7::*Viewport. Wine's IDirect3DViewport implementation + * uses the IDirect3DDevice7 methods for it's functionality + * + * Params: + * Viewport: Address to store the new interface pointer + * UnkOuter: Basically for aggregation, but ddraw doesn't support it. + * Must be NULL + * + * Returns: + * D3D_OK on success + * DDERR_OUTOFMEMORY if memory allocation failed + * CLASS_E_NOAGGREGATION if UnkOuter != NULL + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DImpl_3_CreateViewport(IDirect3D3 *iface, + IDirect3DViewport3 **Viewport, + IUnknown *UnkOuter ) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface); + IDirect3DViewportImpl *object; + + if(UnkOuter) + return CLASS_E_NOAGGREGATION; + + object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DViewportImpl)); + if (object == NULL) + return DDERR_OUTOFMEMORY; + + ICOM_INIT_INTERFACE(object, IDirect3DViewport3, IDirect3DViewport3_Vtbl); + object->ref = 1; + object->ddraw = This; + object->activate = viewport_activate; + object->use_vp2 = 0xFF; + object->next = NULL; + object->lights = NULL; + object->num_lights = 0; + object->map_lights = 0; + + *Viewport = ICOM_INTERFACE(object, IDirect3DViewport3); + + TRACE("(%p) creating implementation at %p.\n",This, object); + + return D3D_OK; +} + +static HRESULT WINAPI +Thunk_IDirect3DImpl_2_CreateViewport(IDirect3D2 *iface, + IDirect3DViewport2 **D3DViewport2, + IUnknown *UnkOuter) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D2, iface); + TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", This, D3DViewport2, UnkOuter); + + return IDirect3D3_CreateViewport(ICOM_INTERFACE(This, IDirect3D3), + (IDirect3DViewport3 **) D3DViewport2 /* No need to cast here */, + UnkOuter); +} + +static HRESULT WINAPI +Thunk_IDirect3DImpl_1_CreateViewport(IDirect3D *iface, + IDirect3DViewport **D3DViewport, + IUnknown* UnkOuter) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D, iface); + TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", This, D3DViewport, UnkOuter); + + return IDirect3D3_CreateViewport(ICOM_INTERFACE(This, IDirect3D3), + (IDirect3DViewport3 **) D3DViewport /* No need to cast here */, + UnkOuter); +} + +/***************************************************************************** + * IDirect3D3::FindDevice + * + * This method finds a device with the requested properties and returns a + * device description + * + * Verion 1, 2 and 3 + * Params: + * D3DDFS: Describes the requested device charakteristics + * D3DFDR: Returns the device description + * + * Returns: + * D3D_OK on success + * DDERR_INVALIDPARAMS if no device was found + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DImpl_3_FindDevice(IDirect3D3 *iface, + D3DFINDDEVICESEARCH *D3DDFS, + D3DFINDDEVICERESULT *D3DFDR) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface); + D3DDEVICEDESC desc; + D3DDEVICEDESC7 newDesc; + HRESULT hr; + + TRACE("(%p)->(%p,%p)\n", This, D3DDFS, D3DFDR); + + if ((D3DDFS->dwFlags & D3DFDS_COLORMODEL) && + (D3DDFS->dcmColorModel != D3DCOLOR_RGB)) + { + TRACE(" trying to request a non-RGB D3D color model. Not supported.\n"); + return DDERR_INVALIDPARAMS; /* No real idea what to return here :-) */ + } + if (D3DDFS->dwFlags & D3DFDS_GUID) + { + TRACE(" trying to match guid %s.\n", debugstr_guid(&(D3DDFS->guid))); + if ((IsEqualGUID(&IID_D3DDEVICE_WineD3D, &(D3DDFS->guid)) == 0) && + (IsEqualGUID(&IID_IDirect3DHALDevice, &(D3DDFS->guid)) == 0) && + (IsEqualGUID(&IID_IDirect3DRefDevice, &(D3DDFS->guid)) == 0)) + { + TRACE(" no match for this GUID.\n"); + return DDERR_INVALIDPARAMS; + } + } + + /* Get the caps */ + hr = IDirect3DImpl_GetCaps(This->wineD3D, &desc, &newDesc); + if(hr != D3D_OK) return hr; + + /* Now return our own GUID */ + D3DFDR->guid = IID_D3DDEVICE_WineD3D; + D3DFDR->ddHwDesc = desc; + D3DFDR->ddSwDesc = desc; + + TRACE(" returning Wine's WineD3D device with (undumped) capabilities\n"); + + return D3D_OK; +} + +static HRESULT WINAPI +Thunk_IDirect3DImpl_2_FindDevice(IDirect3D2 *iface, + D3DFINDDEVICESEARCH *D3DDFS, + D3DFINDDEVICERESULT *D3DFDR) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D2, iface); + TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", iface, D3DDFS, D3DFDR); + return IDirect3D3_FindDevice(ICOM_INTERFACE(This, IDirect3D3), + D3DDFS, + D3DFDR); +} + +static HRESULT WINAPI +Thunk_IDirect3DImpl_1_FindDevice(IDirect3D *iface, + D3DFINDDEVICESEARCH *D3DDFS, + D3DFINDDEVICERESULT *D3DDevice) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D, iface); + TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", This, D3DDFS, D3DDevice); + return IDirect3D3_FindDevice(ICOM_INTERFACE(This, IDirect3D3), + D3DDFS, + D3DDevice); +} + +/***************************************************************************** + * IDirect3D7::CreateDevice + * + * Creates an IDirect3DDevice7 interface. + * + * Version 2, 3 and 7. IDirect3DDevice 1 interfaces are interfaces to + * DirectDraw surfaces and are created with + * IDirectDrawSurface::QueryInterface. This method uses CreateDevice to + * create the device object and QueryInterfaces for IDirect3DDevice + * + * Params: + * refiid: IID of the device to create + * Surface: Inititial rendertarget + * Device: Address to return the interface pointer + * + * Returns: + * D3D_OK on success + * DDERR_OUTOFMEMORY if memory allocation failed + * DDERR_INVALIDPARAMS if a device exists already + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DImpl_7_CreateDevice(IDirect3D7 *iface, + REFCLSID refiid, + IDirectDrawSurface7 *Surface, + IDirect3DDevice7 **Device) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D7, iface); + IDirect3DDeviceImpl *object; + IParentImpl *IndexBufferParent; + HRESULT hr; + IDirectDrawSurfaceImpl *target = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, Surface); + TRACE("(%p)->(%s,%p,%p)\n", iface, debugstr_guid(refiid), Surface, Device); + + *Device = NULL; + + /* Fail device creation if non-opengl surfaces are used */ + if(This->ImplType != SURFACE_OPENGL) + { + ERR("The application wants to create a Direct3D device, but non-opengl surfaces are set in the registry. Please set the surface implementation to opengl or autodetection to allow 3D rendering\n"); + + /* We only hit this path if a default surface is set in the registry. Incorrect autodetection + * is caught in CreateSurface or QueryInterface + */ + return DDERR_NO3D; + } + + /* So far we can only create one device per ddraw object */ + if(This->d3ddevice) + { + FIXME("(%p): Only one Direct3D device per DirectDraw object supported\n", This); + return DDERR_INVALIDPARAMS; + } + + object = HeapAlloc(GetProcessHeap(), 0, sizeof(IDirect3DDeviceImpl)); + if(!object) + { + ERR("Out of memory when allocating a IDirect3DDevice implementation\n"); + return DDERR_OUTOFMEMORY; + } + + ICOM_INIT_INTERFACE(object, IDirect3DDevice7, IDirect3DDevice7_Vtbl); + ICOM_INIT_INTERFACE(object, IDirect3DDevice3, IDirect3DDevice3_Vtbl); + ICOM_INIT_INTERFACE(object, IDirect3DDevice2, IDirect3DDevice2_Vtbl); + ICOM_INIT_INTERFACE(object, IDirect3DDevice, IDirect3DDevice1_Vtbl); + + object->ref = 1; + object->ddraw = This; + object->viewport_list = NULL; + object->current_viewport = NULL; + object->material = 0; + object->target = target; + + /* This is for convenience */ + object->wineD3DDevice = This->wineD3DDevice; + + /* Create an index buffer, it's needed for indexed drawing */ + IndexBufferParent = HeapAlloc(GetProcessHeap(), 0, sizeof(IParentImpl *)); + if(!IndexBufferParent) + { + ERR("Allocating memory for an index buffer parent failed\n"); + HeapFree(GetProcessHeap(), 0, object); + return DDERR_OUTOFMEMORY; + } + ICOM_INIT_INTERFACE(IndexBufferParent, IParent, IParent_Vtbl); + IndexBufferParent->ref = 1; + + /* Create an Index Buffer. WineD3D needs one for Drawing indexed primitives + * Create a (hopefully) long enought buffer, and copy the indices into it + * Ideally, a IWineD3DIndexBuffer::SetData method could be created, which + * takes the pointer and avoids the memcpy + */ + hr = IWineD3DDevice_CreateIndexBuffer(This->wineD3DDevice, + 0x40000, /* Lenght. Don't know how long it should be */ + 0, /* Usage */ + WINED3DFMT_INDEX16, /* Format. D3D7 uses WORDS */ + WINED3DPOOL_DEFAULT, + &object->indexbuffer, + 0 /* Handle */, + (IUnknown *) ICOM_INTERFACE(IndexBufferParent, IParent)); + + if(FAILED(hr)) + { + ERR("Failed to create an index buffer\n"); + HeapFree(GetProcessHeap(), 0, object); + return hr; + } + IndexBufferParent->child = (IUnknown *) object->indexbuffer; + + /* No need to set the indices, it's done when necessary */ + + /* AddRef the WineD3D Device */ + IWineD3DDevice_AddRef(This->wineD3DDevice); + + /* Don't forget to return the interface ;) */ + *Device = ICOM_INTERFACE(object, IDirect3DDevice7); + + TRACE(" (%p) Created an IDirect3DDeviceImpl object at %p\n", This, object); + + /* This is for apps which create a non-flip, non-d3d primary surface + * and an offscreen D3DDEVICE surface, then render to the offscreen surface + * and do a Blt from the offscreen to the primary surface. + * + * Set the offscreen D3DDDEVICE surface(=target) as the back buffer, + * and the primary surface(=This->d3d_target) as the front buffer. + * + * This way the app will render to the D3DDEVICE surface and WineD3D + * will catch the Blt was Back Buffer -> Front buffer blt and perform + * a flip instead. This way we don't have to deal with a mixed GL / GDI + * environment. + * + * This should be checked against windowed apps. The only app tested with + * this is moto racer 2 during the loading screen. + */ + TRACE("Isrendertarget: %s, d3d_target=%p\n", target->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE ? "true" : "false", This->d3d_target); + if(!(target->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) && + (This->d3d_target != target)) + { + TRACE("(%p) Using %p as front buffer, %p as back buffer\n", This, This->d3d_target, target); + hr = IWineD3DDevice_SetFrontBackBuffers(This->wineD3DDevice, + This->d3d_target->WineD3DSurface, + target->WineD3DSurface); + if(hr != D3D_OK) + ERR("(%p) Error %08lx setting the front and back buffer\n", This, hr); + + object->OffScreenTarget = TRUE; + } + else + { + object->OffScreenTarget = FALSE; + } + + /* AddRef the render target. Also AddRef the render target from ddraw, + * because if it released before the app releases the D3D device, the D3D capatiblities + * of WineD3D will be uninitialized, which has bad effects. + * + * In most cases, those surfaces are the surfaces are the same anyway, but this will simply + * add another ref which is released when the device is destroyed. + */ + IDirectDrawSurface7_AddRef(Surface); + IDirectDrawSurface7_AddRef(ICOM_INTERFACE(This->d3d_target, IDirectDrawSurface7)); + + This->d3ddevice = object; + + return D3D_OK; +} + +static HRESULT WINAPI +Thunk_IDirect3DImpl_3_CreateDevice(IDirect3D3 *iface, + REFCLSID refiid, + IDirectDrawSurface4 *Surface, + IDirect3DDevice3 **Device, + IUnknown *UnkOuter) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface); + HRESULT hr; + TRACE("(%p)->(%s,%p,%p,%p): Thunking to IDirect3D7\n", This, debugstr_guid(refiid), Surface, Device, UnkOuter); + + if(UnkOuter != NULL) + return CLASS_E_NOAGGREGATION; + + hr = IDirect3D7_CreateDevice(ICOM_INTERFACE(This, IDirect3D7), + refiid, + (IDirectDrawSurface7 *) Surface /* Same VTables */, + (IDirect3DDevice7 **) Device); + + *Device = COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice7, IDirect3DDevice3, *Device); + return hr; +} + +static HRESULT WINAPI +Thunk_IDirect3DImpl_2_CreateDevice(IDirect3D2 *iface, + REFCLSID refiid, + IDirectDrawSurface *Surface, + IDirect3DDevice2 **Device) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D2, iface); + HRESULT hr; + TRACE("(%p)->(%s,%p,%p): Thunking to IDirect3D7\n", This, debugstr_guid(refiid), Surface, Device); + + hr = IDirect3D7_CreateDevice(ICOM_INTERFACE(This, IDirect3D7), + refiid, + COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface3, IDirectDrawSurface7, Surface), + (IDirect3DDevice7 **) Device); + + *Device = COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice7, IDirect3DDevice2, *Device); + return hr; +} + +/***************************************************************************** + * IDirect3D7::CreateVertexBuffer + * + * Creates a new vertex buffer object and returns a IDirect3DVertexBuffer7 + * interface. + * + * Version 3 and 7 + * + * Params: + * Desc: Requested Vertex buffer properties + * VertexBuffer: Address to return the interface pointer at + * Flags: Some flags, must be 0 + * + * Returns + * D3D_OK on success + * DDERR_OUTOFMEMORY if memory allocation failed + * The return value of IWineD3DDevice::CreateVertexBuffer if this call fails + * DDERR_INVALIDPARAMS if Desc or VertexBuffer are NULL, or Flags != 0 + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DImpl_7_CreateVertexBuffer(IDirect3D7 *iface, + D3DVERTEXBUFFERDESC *Desc, + IDirect3DVertexBuffer7 **VertexBuffer, + DWORD Flags) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D7, iface); + IDirect3DVertexBufferImpl *object; + HRESULT hr; + TRACE("(%p)->(%p,%p,%08lx)\n", This, Desc, VertexBuffer, Flags); + + TRACE("(%p) Vertex buffer description: \n", This); + TRACE("(%p) dwSize=%ld\n", This, Desc->dwSize); + TRACE("(%p) dwCaps=%08lx\n", This, Desc->dwCaps); + TRACE("(%p) FVF=%08lx\n", This, Desc->dwFVF); + TRACE("(%p) dwNumVertices=%ld\n", This, Desc->dwNumVertices); + + /* D3D7 SDK: "No Flags are currently defined for this method. This + * parameter must be 0" + * + * Never trust the documentation - this is wrong + if(Flags != 0) + { + ERR("(%p) Flags is %08lx, returning DDERR_INVALIDPARAMS\n", This, Flags); + return DDERR_INVALIDPARAMS; + } + */ + + /* Well, this sounds sane */ + if( (!VertexBuffer) || (!Desc) ) + return DDERR_INVALIDPARAMS; + + /* Now create the vertex buffer */ + object = HeapAlloc(GetProcessHeap(), 0, sizeof(IDirect3DVertexBufferImpl)); + if(!object) + { + ERR("(%p) Out of memory when allocating a IDirect3DVertexBufferImpl structure\n", This); + return DDERR_OUTOFMEMORY; + } + + object->ref = 1; + ICOM_INIT_INTERFACE(object, IDirect3DVertexBuffer7, IDirect3DVertexBuffer7_Vtbl); + ICOM_INIT_INTERFACE(object, IDirect3DVertexBuffer, IDirect3DVertexBuffer1_Vtbl); + + object->Caps = Desc->dwCaps; + + hr = IWineD3DDevice_CreateVertexBuffer(This->wineD3DDevice, + get_flexible_vertex_size(Desc->dwFVF) * Desc->dwNumVertices, + Desc->dwCaps & D3DVBCAPS_WRITEONLY ? WINED3DUSAGE_WRITEONLY : 0, + Desc->dwFVF, + Desc->dwCaps & D3DVBCAPS_SYSTEMMEMORY ? WINED3DPOOL_SYSTEMMEM : WINED3DPOOL_DEFAULT, + &object->wineD3DVertexBuffer, + 0 /* SharedHandle */, + (IUnknown *) ICOM_INTERFACE(object, IDirect3DVertexBuffer7)); + if(hr != D3D_OK) + { + ERR("(%p) IWineD3DDevice::CreateVertexBuffer failed with hr=%08lx\n", This, hr); + HeapFree(GetProcessHeap(), 0, object); + return hr; + } + + /* Return the interface */ + *VertexBuffer = ICOM_INTERFACE(object, IDirect3DVertexBuffer7); + + TRACE("(%p) Created new vertex buffer implementation at %p, returning interface at %p\n", This, object, *VertexBuffer); + return D3D_OK; +} + +static HRESULT WINAPI +Thunk_IDirect3DImpl_3_CreateVertexBuffer(IDirect3D3 *iface, + D3DVERTEXBUFFERDESC *Desc, + IDirect3DVertexBuffer **VertexBuffer, + DWORD Flags, + IUnknown *UnkOuter) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface); + HRESULT hr; + TRACE("(%p)->(%p,%p,%08lx,%p): Relaying to IDirect3D7\n", This, Desc, VertexBuffer, Flags, UnkOuter); + + if(UnkOuter != NULL) return CLASS_E_NOAGGREGATION; + + hr = IDirect3D7_CreateVertexBuffer(ICOM_INTERFACE(This, IDirect3D7), + Desc, + (IDirect3DVertexBuffer7 **) VertexBuffer, + Flags); + + *VertexBuffer = COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, IDirect3DVertexBuffer, *VertexBuffer); + return hr; +} + +/***************************************************************************** + * EnumZBufferFormatsCB + * + * Helper function for IDirect3D7::EnumZBufferFormats. Converts + * the WINED3DFORMAT into a DirectDraw pixelformat and calls the application + * callback + * + * Version 3 and 7 + * + * Parameters: + * Device: Parent of the IWineD3DDevice, our IDirectDraw7 interface + * fmt: The enumerated pixel format + * Context: Context passed to IWineD3DDevice::EnumZBufferFormat + * + * Returns: + * The return value of the application-provided callback + * + *****************************************************************************/ +static HRESULT WINAPI +EnumZBufferFormatsCB(IUnknown *Device, + WINED3DFORMAT fmt, + void *Context) +{ + struct EnumZBufferFormatsData *cbdata = (struct EnumZBufferFormatsData *) Context; + DDPIXELFORMAT pformat; + + memset(&pformat, 0, sizeof(DDPIXELFORMAT)); + pformat.dwSize=sizeof(DDPIXELFORMAT); + PixelFormat_WineD3DtoDD(&pformat, fmt); + return cbdata->Callback(&pformat, cbdata->Context); +} + +/***************************************************************************** + * IDirect3D7::EnumZBufferFormats + * + * Enumerates all supported Z buffer pixel formats + * + * Version 3 and 7 + * + * Params: + * refiidDevice: + * Callback: Callback to call for each pixel format + * Context: Pointer to pass back to the callback + * + * Returns: + * D3D_OK on success + * DDERR_INVALIDPARAMS if Callback is NULL + * For details, see IWineD3DDevice::EnumZBufferFormats + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DImpl_7_EnumZBufferFormats(IDirect3D7 *iface, + REFCLSID refiidDevice, + LPD3DENUMPIXELFORMATSCALLBACK Callback, + void *Context) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D7, iface); + struct EnumZBufferFormatsData cbdata = { Callback, Context }; + TRACE("(%p)->(%s,%p,%p): Relay\n", iface, debugstr_guid(refiidDevice), Callback, Context); + + if(!Callback) + return DDERR_INVALIDPARAMS; + + return IWineD3DDevice_EnumZBufferFormats(This->wineD3DDevice, EnumZBufferFormatsCB, &cbdata); +} + +static HRESULT WINAPI +Thunk_IDirect3DImpl_3_EnumZBufferFormats(IDirect3D3 *iface, + REFCLSID riidDevice, + LPD3DENUMPIXELFORMATSCALLBACK Callback, + void *Context) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface); + TRACE("(%p)->(%s,%p,%p) thunking to IDirect3D7 interface.\n", This, debugstr_guid(riidDevice), Callback, Context); + return IDirect3D7_EnumZBufferFormats(ICOM_INTERFACE(This, IDirect3D7), + riidDevice, + Callback, + Context); +} + +/***************************************************************************** + * IDirect3D7::EvictManagedTextures + * + * Removes all managed textures(=surfaces with DDSCAPS2_TEXTUREMANAGE or + * DDSCAPS2_D3DTEXTUREMANAGE caps) to be removed from video memory. + * + * Version 3 and 7 + * + * Returns: + * D3D_OK, because it's a stub + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DImpl_7_EvictManagedTextures(IDirect3D7 *iface) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D7, iface); + FIXME("(%p): Stub!\n", This); + + /* Implementation idea: + * Add an IWineD3DSurface method which sets the opengl texture + * priority low or even removes the opengl texture. + */ + + return D3D_OK; +} + +static HRESULT WINAPI +Thunk_IDirect3DImpl_3_EvictManagedTextures(IDirect3D3 *iface) +{ + ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface); + TRACE("(%p)->() thunking to IDirect3D7 interface.\n", This); + return IDirect3D7_EvictManagedTextures(ICOM_INTERFACE(This, IDirect3D7)); +} + +/***************************************************************************** + * IDirect3DImpl_GetCaps + * + * This function retrieves the device caps from wined3d + * and converts it into a D3D7 and D3D - D3D3 structure + * This is a helper function called from various places in ddraw + * + * Params: + * WineD3D: The interface to get the caps from + * Desc123: Old D3D <3 structure to fill(needed) + * Desc7: D3D7 device desc structure to fill(needed) + * + * Returns + * D3D_OK on success, or the return value of IWineD3D::GetCaps + * + *****************************************************************************/ +HRESULT +IDirect3DImpl_GetCaps(IWineD3D *WineD3D, + D3DDEVICEDESC *Desc123, + D3DDEVICEDESC7 *Desc7) +{ + WINED3DCAPS WCaps; + HRESULT hr; + + /* Some Variables to asign to the pointers in WCaps */ + WINED3DDEVTYPE DevType; + UINT dummy_uint; + float dummy_float; + DWORD dummy_dword, MaxTextureBlendStages, MaxSimultaneousTextures; + DWORD MaxUserClipPlanes, MaxVertexBlendMatrices; + + TRACE("()->(%p,%p,%p\n", WineD3D, Desc123, Desc7); + + /* Asign the pointers in WCaps */ + WCaps.DeviceType = &DevType; + WCaps.AdapterOrdinal = &dummy_uint; + + WCaps.Caps = &dummy_dword; + WCaps.Caps2 = &dummy_dword; + WCaps.Caps3 = &dummy_dword; + WCaps.PresentationIntervals = &dummy_dword; + + WCaps.CursorCaps = &dummy_dword; + + WCaps.DevCaps = &Desc7->dwDevCaps; + WCaps.PrimitiveMiscCaps = &dummy_dword; + WCaps.RasterCaps = &Desc7->dpcLineCaps.dwRasterCaps; + WCaps.ZCmpCaps = &Desc7->dpcLineCaps.dwZCmpCaps; + WCaps.SrcBlendCaps = &Desc7->dpcLineCaps.dwSrcBlendCaps; + WCaps.DestBlendCaps = &Desc7->dpcLineCaps.dwDestBlendCaps; + WCaps.AlphaCmpCaps = &Desc7->dpcLineCaps.dwAlphaCmpCaps; + WCaps.ShadeCaps = &Desc7->dpcLineCaps.dwShadeCaps; + WCaps.TextureCaps = &Desc7->dpcLineCaps.dwTextureCaps; + WCaps.TextureFilterCaps = &Desc7->dpcLineCaps.dwTextureFilterCaps; + WCaps.CubeTextureFilterCaps = &dummy_dword; + WCaps.VolumeTextureFilterCaps = &dummy_dword; + WCaps.TextureAddressCaps = &Desc7->dpcLineCaps.dwTextureAddressCaps; + WCaps.VolumeTextureAddressCaps = &dummy_dword; + + WCaps.LineCaps = &dummy_dword; + WCaps.MaxTextureWidth = &Desc7->dwMaxTextureWidth; + WCaps.MaxTextureHeight = &Desc7->dwMaxTextureHeight; + WCaps.MaxVolumeExtent = &dummy_dword; + + WCaps.MaxTextureRepeat = &Desc7->dwMaxTextureRepeat; + WCaps.MaxTextureAspectRatio = &Desc7->dwMaxTextureAspectRatio; + WCaps.MaxAnisotropy = &Desc7->dwMaxAnisotropy; + WCaps.MaxVertexW = &Desc7->dvMaxVertexW; + + WCaps.GuardBandLeft = &Desc7->dvGuardBandLeft; + WCaps.GuardBandTop = &Desc7->dvGuardBandTop; + WCaps.GuardBandRight = &Desc7->dvGuardBandRight; + WCaps.GuardBandBottom = &Desc7->dvGuardBandBottom; + + WCaps.ExtentsAdjust = &Desc7->dvExtentsAdjust; + WCaps.StencilCaps = &Desc7->dwStencilCaps; + + WCaps.FVFCaps = &Desc7->dwFVFCaps; + WCaps.TextureOpCaps = &Desc7->dwTextureOpCaps; + WCaps.MaxTextureBlendStages = &MaxTextureBlendStages; + WCaps.MaxSimultaneousTextures = &MaxSimultaneousTextures; + + WCaps.VertexProcessingCaps = &Desc7->dwVertexProcessingCaps; + WCaps.MaxActiveLights = &Desc7->dwMaxActiveLights; + WCaps.MaxUserClipPlanes = &MaxUserClipPlanes; + WCaps.MaxVertexBlendMatrices = &MaxVertexBlendMatrices; + WCaps.MaxVertexBlendMatrixIndex = &dummy_dword; + + WCaps.MaxPointSize = &dummy_float; + WCaps.MaxPrimitiveCount = &dummy_dword; + WCaps.MaxVertexIndex = &dummy_dword; + WCaps.MaxStreams = &dummy_dword; + WCaps.MaxStreamStride = &dummy_dword; + + WCaps.VertexShaderVersion = &dummy_dword; + WCaps.MaxVertexShaderConst = &dummy_dword; + + WCaps.PixelShaderVersion = &dummy_dword; + WCaps.PixelShader1xMaxValue = &dummy_float; + + /* These are dx9 only, set them to NULL */ + WCaps.DevCaps2 = NULL; + WCaps.MaxNpatchTessellationLevel = NULL; + WCaps.Reserved5 = NULL; + WCaps.MasterAdapterOrdinal = NULL; + WCaps.AdapterOrdinalInGroup = NULL; + WCaps.NumberOfAdaptersInGroup = NULL; + WCaps.DeclTypes = NULL; + WCaps.NumSimultaneousRTs = NULL; + WCaps.StretchRectFilterCaps = NULL; + /* WCaps.VS20Caps = NULL; */ + /* WCaps.PS20Caps = NULL; */ + WCaps.VertexTextureFilterCaps = NULL; + WCaps.MaxVShaderInstructionsExecuted = NULL; + WCaps.MaxPShaderInstructionsExecuted = NULL; + WCaps.MaxVertexShader30InstructionSlots = NULL; + WCaps.MaxPixelShader30InstructionSlots = NULL; + WCaps.Reserved2 = NULL; + WCaps.Reserved3 = NULL; + + /* Now get the caps */ + hr = IWineD3D_GetDeviceCaps(WineD3D, 0, WINED3DDEVTYPE_HAL, &WCaps); + if(hr != D3D_OK) return hr; + + /* Fill the missing members, and do some fixup */ + Desc7->dpcLineCaps.dwSize = sizeof(Desc7->dpcLineCaps); + Desc7->dpcLineCaps.dwTextureBlendCaps = D3DPTBLENDCAPS_ADD | D3DPTBLENDCAPS_MODULATEMASK | + D3DPTBLENDCAPS_COPY | D3DPTBLENDCAPS_DECAL | + D3DPTBLENDCAPS_DECALALPHA | D3DPTBLENDCAPS_DECALMASK | + D3DPTBLENDCAPS_MODULATE | D3DPTBLENDCAPS_MODULATEALPHA; + Desc7->dpcLineCaps.dwStippleWidth = 32; + Desc7->dpcLineCaps.dwStippleHeight = 32; + /* Use the same for the TriCaps */ + Desc7->dpcTriCaps = Desc7->dpcLineCaps; + + Desc7->dwDeviceRenderBitDepth = DDBD_16 | DDBD_24 | DDBD_32; + Desc7->dwDeviceZBufferBitDepth = DDBD_16 | DDBD_24; + Desc7->dwMinTextureWidth = 1; + Desc7->dwMinTextureHeight = 1; + + /* Convert DWORDs safely to WORDs */ + if(MaxTextureBlendStages > 65535) Desc7->wMaxTextureBlendStages = 65535; + else Desc7->wMaxTextureBlendStages = (WORD) MaxTextureBlendStages; + if(MaxSimultaneousTextures > 65535) Desc7->wMaxSimultaneousTextures = 65535; + else Desc7->wMaxSimultaneousTextures = (WORD) MaxSimultaneousTextures; + + if(MaxUserClipPlanes > 65535) Desc7->wMaxUserClipPlanes = 65535; + else Desc7->wMaxUserClipPlanes = (WORD) MaxUserClipPlanes; + if(MaxVertexBlendMatrices > 65535) Desc7->wMaxVertexBlendMatrices = 65535; + else Desc7->wMaxVertexBlendMatrices = (WORD) MaxVertexBlendMatrices; + + Desc7->deviceGUID = IID_IDirect3DTnLHalDevice; + + Desc7->dwReserved1 = 0; + Desc7->dwReserved2 = 0; + Desc7->dwReserved3 = 0; + Desc7->dwReserved4 = 0; + + /* Fill the old structure */ + memset(Desc123, 0x0, sizeof(D3DDEVICEDESC)); + Desc123->dwSize = sizeof(D3DDEVICEDESC); + Desc123->dwFlags = D3DDD_COLORMODEL | + D3DDD_DEVCAPS | + D3DDD_TRANSFORMCAPS | + D3DDD_BCLIPPING | + D3DDD_LIGHTINGCAPS | + D3DDD_LINECAPS | + D3DDD_TRICAPS | + D3DDD_DEVICERENDERBITDEPTH | + D3DDD_DEVICEZBUFFERBITDEPTH | + D3DDD_MAXBUFFERSIZE | + D3DDD_MAXVERTEXCOUNT; + Desc123->dcmColorModel = D3DCOLOR_RGB; + Desc123->dwDevCaps = Desc7->dwDevCaps; + Desc123->dtcTransformCaps.dwSize = sizeof(D3DTRANSFORMCAPS); + Desc123->dtcTransformCaps.dwCaps = D3DTRANSFORMCAPS_CLIP; + Desc123->bClipping = TRUE; + Desc123->dlcLightingCaps.dwSize = sizeof(D3DLIGHTINGCAPS); + Desc123->dlcLightingCaps.dwCaps = D3DLIGHTCAPS_DIRECTIONAL | D3DLIGHTCAPS_PARALLELPOINT | D3DLIGHTCAPS_POINT | D3DLIGHTCAPS_SPOT; + Desc123->dlcLightingCaps.dwLightingModel = D3DLIGHTINGMODEL_RGB; + Desc123->dlcLightingCaps.dwNumLights = Desc7->dwMaxActiveLights; + + Desc123->dpcLineCaps.dwSize = sizeof(D3DPRIMCAPS); + Desc123->dpcLineCaps.dwMiscCaps = Desc7->dpcLineCaps.dwMiscCaps; + Desc123->dpcLineCaps.dwRasterCaps = Desc7->dpcLineCaps.dwRasterCaps; + Desc123->dpcLineCaps.dwZCmpCaps = Desc7->dpcLineCaps.dwZCmpCaps; + Desc123->dpcLineCaps.dwSrcBlendCaps = Desc7->dpcLineCaps.dwSrcBlendCaps; + Desc123->dpcLineCaps.dwDestBlendCaps = Desc7->dpcLineCaps.dwDestBlendCaps; + Desc123->dpcLineCaps.dwShadeCaps = Desc7->dpcLineCaps.dwShadeCaps; + Desc123->dpcLineCaps.dwTextureCaps = Desc7->dpcLineCaps.dwTextureCaps; + Desc123->dpcLineCaps.dwTextureFilterCaps = Desc7->dpcLineCaps.dwTextureFilterCaps; + Desc123->dpcLineCaps.dwTextureBlendCaps = Desc7->dpcLineCaps.dwTextureBlendCaps; + Desc123->dpcLineCaps.dwTextureAddressCaps = Desc7->dpcLineCaps.dwTextureAddressCaps; + Desc123->dpcLineCaps.dwStippleWidth = Desc7->dpcLineCaps.dwStippleWidth; + Desc123->dpcLineCaps.dwAlphaCmpCaps = Desc7->dpcLineCaps.dwAlphaCmpCaps; + + Desc123->dpcTriCaps.dwSize = sizeof(D3DPRIMCAPS); + Desc123->dpcTriCaps.dwMiscCaps = Desc7->dpcTriCaps.dwMiscCaps; + Desc123->dpcTriCaps.dwRasterCaps = Desc7->dpcTriCaps.dwRasterCaps; + Desc123->dpcTriCaps.dwZCmpCaps = Desc7->dpcTriCaps.dwZCmpCaps; + Desc123->dpcTriCaps.dwSrcBlendCaps = Desc7->dpcTriCaps.dwSrcBlendCaps; + Desc123->dpcTriCaps.dwDestBlendCaps = Desc7->dpcTriCaps.dwDestBlendCaps; + Desc123->dpcTriCaps.dwShadeCaps = Desc7->dpcTriCaps.dwShadeCaps; + Desc123->dpcTriCaps.dwTextureCaps = Desc7->dpcTriCaps.dwTextureCaps; + Desc123->dpcTriCaps.dwTextureFilterCaps = Desc7->dpcTriCaps.dwTextureFilterCaps; + Desc123->dpcTriCaps.dwTextureBlendCaps = Desc7->dpcTriCaps.dwTextureBlendCaps; + Desc123->dpcTriCaps.dwTextureAddressCaps = Desc7->dpcTriCaps.dwTextureAddressCaps; + Desc123->dpcTriCaps.dwStippleWidth = Desc7->dpcTriCaps.dwStippleWidth; + Desc123->dpcTriCaps.dwAlphaCmpCaps = Desc7->dpcTriCaps.dwAlphaCmpCaps; + + Desc123->dwDeviceRenderBitDepth = Desc7->dwDeviceRenderBitDepth; + Desc123->dwDeviceZBufferBitDepth = Desc7->dwDeviceZBufferBitDepth; + Desc123->dwMaxBufferSize = 0; + Desc123->dwMaxVertexCount = 65536; + Desc123->dwMinTextureWidth = Desc7->dwMinTextureWidth; + Desc123->dwMinTextureHeight = Desc7->dwMinTextureHeight; + Desc123->dwMaxTextureWidth = Desc7->dwMaxTextureWidth; + Desc123->dwMaxTextureHeight = Desc7->dwMaxTextureHeight; + Desc123->dwMinStippleWidth = 1; + Desc123->dwMinStippleHeight = 1; + Desc123->dwMaxStippleWidth = 32; + Desc123->dwMaxStippleHeight = 32; + Desc123->dwMaxTextureRepeat = Desc7->dwMaxTextureRepeat; + Desc123->dwMaxTextureAspectRatio = Desc7->dwMaxTextureAspectRatio; + Desc123->dwMaxAnisotropy = Desc7->dwMaxAnisotropy; + Desc123->dvGuardBandLeft = Desc7->dvGuardBandLeft; + Desc123->dvGuardBandRight = Desc7->dvGuardBandRight; + Desc123->dvGuardBandTop = Desc7->dvGuardBandTop; + Desc123->dvGuardBandBottom = Desc7->dvGuardBandBottom; + Desc123->dvExtentsAdjust = Desc7->dvExtentsAdjust; + Desc123->dwStencilCaps = Desc7->dwStencilCaps; + Desc123->dwFVFCaps = Desc7->dwFVFCaps; + Desc123->dwTextureOpCaps = Desc7->dwTextureOpCaps; + Desc123->wMaxTextureBlendStages = Desc7->wMaxTextureBlendStages; + Desc123->wMaxSimultaneousTextures = Desc7->wMaxSimultaneousTextures; + + return DD_OK; +} +/***************************************************************************** + * IDirect3D vtables in various versions + *****************************************************************************/ + +const IDirect3DVtbl IDirect3D1_Vtbl = +{ + /*** IUnknown methods ***/ + Thunk_IDirect3DImpl_1_QueryInterface, + Thunk_IDirect3DImpl_1_AddRef, + Thunk_IDirect3DImpl_1_Release, + /*** IDirect3D methods ***/ + IDirect3DImpl_1_Initialize, + Thunk_IDirect3DImpl_1_EnumDevices, + Thunk_IDirect3DImpl_1_CreateLight, + Thunk_IDirect3DImpl_1_CreateMaterial, + Thunk_IDirect3DImpl_1_CreateViewport, + Thunk_IDirect3DImpl_1_FindDevice +}; + +const IDirect3D2Vtbl IDirect3D2_Vtbl = +{ + /*** IUnknown methods ***/ + Thunk_IDirect3DImpl_2_QueryInterface, + Thunk_IDirect3DImpl_2_AddRef, + Thunk_IDirect3DImpl_2_Release, + /*** IDirect3D2 methods ***/ + Thunk_IDirect3DImpl_2_EnumDevices, + Thunk_IDirect3DImpl_2_CreateLight, + Thunk_IDirect3DImpl_2_CreateMaterial, + Thunk_IDirect3DImpl_2_CreateViewport, + Thunk_IDirect3DImpl_2_FindDevice, + Thunk_IDirect3DImpl_2_CreateDevice +}; + +const IDirect3D3Vtbl IDirect3D3_Vtbl = +{ + /*** IUnknown methods ***/ + Thunk_IDirect3DImpl_3_QueryInterface, + Thunk_IDirect3DImpl_3_AddRef, + Thunk_IDirect3DImpl_3_Release, + /*** IDirect3D3 methods ***/ + IDirect3DImpl_3_EnumDevices, + IDirect3DImpl_3_CreateLight, + IDirect3DImpl_3_CreateMaterial, + IDirect3DImpl_3_CreateViewport, + IDirect3DImpl_3_FindDevice, + Thunk_IDirect3DImpl_3_CreateDevice, + Thunk_IDirect3DImpl_3_CreateVertexBuffer, + Thunk_IDirect3DImpl_3_EnumZBufferFormats, + Thunk_IDirect3DImpl_3_EvictManagedTextures +}; + +const IDirect3D7Vtbl IDirect3D7_Vtbl = +{ + /*** IUnknown methods ***/ + Thunk_IDirect3DImpl_7_QueryInterface, + Thunk_IDirect3DImpl_7_AddRef, + Thunk_IDirect3DImpl_7_Release, + /*** IDirect3D7 methods ***/ + IDirect3DImpl_7_EnumDevices, + IDirect3DImpl_7_CreateDevice, + IDirect3DImpl_7_CreateVertexBuffer, + IDirect3DImpl_7_EnumZBufferFormats, + IDirect3DImpl_7_EvictManagedTextures +}; diff --git a/dlls/ddraw/direct3d_main.c b/dlls/ddraw/direct3d_main.c deleted file mode 100644 index 7f15d9fc03..0000000000 --- a/dlls/ddraw/direct3d_main.c +++ /dev/null @@ -1,439 +0,0 @@ -/* - * Copyright 2000 Marcus Meissner - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "config.h" - -#include -#ifdef HAVE_UNISTD_H -# include -#endif -#include -#include -#include -#include - -#include "winerror.h" -#include "windef.h" -#include "winbase.h" -#include "wingdi.h" -#include "ddraw.h" -#include "d3d.h" -#include "wine/debug.h" - -#include "d3d_private.h" - -WINE_DEFAULT_DEBUG_CHANNEL(ddraw); - - -HRESULT WINAPI -Main_IDirect3DImpl_1_Initialize(LPDIRECT3D iface, - REFIID riid) -{ - ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D, iface); - TRACE("(%p/%p)->(%s) no-op...\n", This, iface, debugstr_guid(riid)); - return D3D_OK; -} - -HRESULT WINAPI -Main_IDirect3DImpl_3_2T_1T_EnumDevices(LPDIRECT3D3 iface, - LPD3DENUMDEVICESCALLBACK lpEnumDevicesCallback, - LPVOID lpUserArg) -{ - ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface); - FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lpEnumDevicesCallback, lpUserArg); - return D3D_OK; -} - -HRESULT WINAPI -Main_IDirect3DImpl_3_2T_1T_CreateLight(LPDIRECT3D3 iface, - LPDIRECT3DLIGHT* lplpDirect3DLight, - IUnknown* pUnkOuter) -{ - ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface); - FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lplpDirect3DLight, pUnkOuter); - return D3D_OK; -} - -HRESULT WINAPI -Main_IDirect3DImpl_3_2T_1T_CreateMaterial(LPDIRECT3D3 iface, - LPDIRECT3DMATERIAL3* lplpDirect3DMaterial3, - IUnknown* pUnkOuter) -{ - ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface); - FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lplpDirect3DMaterial3, pUnkOuter); - return D3D_OK; -} - -HRESULT WINAPI -Main_IDirect3DImpl_3_2T_1T_CreateViewport(LPDIRECT3D3 iface, - LPDIRECT3DVIEWPORT3* lplpD3DViewport3, - IUnknown* pUnkOuter) -{ - ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface); - FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lplpD3DViewport3, pUnkOuter); - return D3D_OK; -} - -HRESULT WINAPI -Main_IDirect3DImpl_3_2T_1T_FindDevice(LPDIRECT3D3 iface, - LPD3DFINDDEVICESEARCH lpD3DDFS, - LPD3DFINDDEVICERESULT lpD3DFDR) -{ - ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface); - FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lpD3DDFS, lpD3DFDR); - return D3D_OK; -} - -HRESULT WINAPI -Main_IDirect3DImpl_2_CreateDevice(LPDIRECT3D2 iface, - REFCLSID rclsid, - LPDIRECTDRAWSURFACE lpDDS, - LPDIRECT3DDEVICE2* lplpD3DDevice2) -{ - ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D2, iface); - FIXME("(%p/%p)->(%s,%p,%p): stub!\n", This, iface, debugstr_guid(rclsid), lpDDS, lplpD3DDevice2); - return D3D_OK; -} - -HRESULT WINAPI -Main_IDirect3DImpl_3_CreateDevice(LPDIRECT3D3 iface, - REFCLSID rclsid, - LPDIRECTDRAWSURFACE4 lpDDS, - LPDIRECT3DDEVICE3* lplpD3DDevice3, - LPUNKNOWN lpUnk) -{ - ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface); - FIXME("(%p/%p)->(%s,%p,%p,%p): stub!\n", This, iface, debugstr_guid(rclsid), lpDDS, lplpD3DDevice3, lpUnk); - return D3D_OK; -} - -HRESULT WINAPI -Main_IDirect3DImpl_7_3T_EnumZBufferFormats(LPDIRECT3D7 iface, - REFCLSID riidDevice, - LPD3DENUMPIXELFORMATSCALLBACK lpEnumCallback, - LPVOID lpContext) -{ - ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D7, iface); - FIXME("(%p/%p)->(%s,%p,%p): stub!\n", This, iface, debugstr_guid(riidDevice), lpEnumCallback, lpContext); - return D3D_OK; -} - -HRESULT WINAPI -Main_IDirect3DImpl_7_3T_EvictManagedTextures(LPDIRECT3D7 iface) -{ - ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D7, iface); - FIXME("(%p/%p)->(): stub!\n", This, iface); - return D3D_OK; -} - -HRESULT WINAPI -Main_IDirect3DImpl_7_EnumDevices(LPDIRECT3D7 iface, - LPD3DENUMDEVICESCALLBACK7 lpEnumDevicesCallback, - LPVOID lpUserArg) -{ - ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D7, iface); - FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lpEnumDevicesCallback, lpUserArg); - return D3D_OK; -} - -HRESULT WINAPI -Main_IDirect3DImpl_7_CreateDevice(LPDIRECT3D7 iface, - REFCLSID rclsid, - LPDIRECTDRAWSURFACE7 lpDDS, - LPDIRECT3DDEVICE7* lplpD3DDevice) -{ - ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D7, iface); - FIXME("(%p/%p)->(%s,%p,%p): stub!\n", This, iface, debugstr_guid(rclsid), lpDDS, lplpD3DDevice); - return D3D_OK; -} - -HRESULT WINAPI -Main_IDirect3DImpl_7_3T_CreateVertexBuffer(LPDIRECT3D7 iface, - LPD3DVERTEXBUFFERDESC lpD3DVertBufDesc, - LPDIRECT3DVERTEXBUFFER7* lplpD3DVertBuf, - DWORD dwFlags) -{ - ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D7, iface); - FIXME("(%p/%p)->(%p,%p,%08lx): stub!\n", This, iface, lpD3DVertBufDesc, lplpD3DVertBuf, dwFlags); - return D3D_OK; -} - -HRESULT WINAPI -Thunk_IDirect3DImpl_7_QueryInterface(LPDIRECT3D7 iface, - REFIID riid, - LPVOID* obp) -{ - TRACE("(%p)->(%s,%p) thunking to IDirectDraw7 interface.\n", iface, debugstr_guid(riid), obp); - return IDirectDraw7_QueryInterface(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D7, IDirectDraw7, iface), - riid, - obp); -} - -HRESULT WINAPI -Thunk_IDirect3DImpl_3_QueryInterface(LPDIRECT3D3 iface, - REFIID riid, - LPVOID* obp) -{ - TRACE("(%p)->(%s,%p) thunking to IDirectDraw7 interface.\n", iface, debugstr_guid(riid), obp); - return IDirectDraw7_QueryInterface(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D3, IDirectDraw7, iface), - riid, - obp); -} - -HRESULT WINAPI -Thunk_IDirect3DImpl_2_QueryInterface(LPDIRECT3D2 iface, - REFIID riid, - LPVOID* obp) -{ - TRACE("(%p)->(%s,%p) thunking to IDirectDraw7 interface.\n", iface, debugstr_guid(riid), obp); - return IDirectDraw7_QueryInterface(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D2, IDirectDraw7, iface), - riid, - obp); -} - -HRESULT WINAPI -Thunk_IDirect3DImpl_1_QueryInterface(LPDIRECT3D iface, - REFIID riid, - LPVOID* obp) -{ - TRACE("(%p)->(%s,%p) thunking to IDirectDraw7 interface.\n", iface, debugstr_guid(riid), obp); - return IDirectDraw7_QueryInterface(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D, IDirectDraw7, iface), - riid, - obp); -} - -ULONG WINAPI -Thunk_IDirect3DImpl_7_AddRef(LPDIRECT3D7 iface) -{ - TRACE("(%p)->() thunking to IDirectDraw7 interface.\n", iface); - return IDirectDraw7_AddRef(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D7, IDirectDraw7, iface)); -} - -ULONG WINAPI -Thunk_IDirect3DImpl_3_AddRef(LPDIRECT3D3 iface) -{ - TRACE("(%p)->() thunking to IDirectDraw7 interface.\n", iface); - return IDirectDraw7_AddRef(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D3, IDirectDraw7, iface)); -} - -ULONG WINAPI -Thunk_IDirect3DImpl_2_AddRef(LPDIRECT3D2 iface) -{ - TRACE("(%p)->() thunking to IDirectDraw7 interface.\n", iface); - return IDirectDraw7_AddRef(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D2, IDirectDraw7, iface)); -} - -ULONG WINAPI -Thunk_IDirect3DImpl_1_AddRef(LPDIRECT3D iface) -{ - TRACE("(%p)->() thunking to IDirectDraw7 interface.\n", iface); - return IDirectDraw7_AddRef(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D, IDirectDraw7, iface)); -} - -ULONG WINAPI -Thunk_IDirect3DImpl_7_Release(LPDIRECT3D7 iface) -{ - TRACE("(%p)->() thunking to IDirectDraw7 interface.\n", iface); - return IDirectDraw7_Release(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D7, IDirectDraw7, iface)); -} - -ULONG WINAPI -Thunk_IDirect3DImpl_3_Release(LPDIRECT3D3 iface) -{ - TRACE("(%p)->() thunking to IDirectDraw7 interface.\n", iface); - return IDirectDraw7_Release(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D3, IDirectDraw7, iface)); -} - -ULONG WINAPI -Thunk_IDirect3DImpl_2_Release(LPDIRECT3D2 iface) -{ - TRACE("(%p)->() thunking to IDirectDraw7 interface.\n", iface); - return IDirectDraw7_Release(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D2, IDirectDraw7, iface)); -} - -ULONG WINAPI -Thunk_IDirect3DImpl_1_Release(LPDIRECT3D iface) -{ - TRACE("(%p)->() thunking to IDirectDraw7 interface.\n", iface); - return IDirectDraw7_Release(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D, IDirectDraw7, iface)); -} - -HRESULT WINAPI -Thunk_IDirect3DImpl_3_EnumZBufferFormats(LPDIRECT3D3 iface, - REFCLSID riidDevice, - LPD3DENUMPIXELFORMATSCALLBACK lpEnumCallback, - LPVOID lpContext) -{ - TRACE("(%p)->(%s,%p,%p) thunking to IDirect3D7 interface.\n", iface, debugstr_guid(riidDevice), lpEnumCallback, lpContext); - return IDirect3D7_EnumZBufferFormats(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D3, IDirect3D7, iface), - riidDevice, - lpEnumCallback, - lpContext); -} - -HRESULT WINAPI -Thunk_IDirect3DImpl_3_EvictManagedTextures(LPDIRECT3D3 iface) -{ - TRACE("(%p)->() thunking to IDirect3D7 interface.\n", iface); - return IDirect3D7_EvictManagedTextures(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D3, IDirect3D7, iface)); -} - -HRESULT WINAPI -Thunk_IDirect3DImpl_2_EnumDevices(LPDIRECT3D2 iface, - LPD3DENUMDEVICESCALLBACK lpEnumDevicesCallback, - LPVOID lpUserArg) -{ - TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", iface, lpEnumDevicesCallback, lpUserArg); - return IDirect3D3_EnumDevices(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D2, IDirect3D3, iface), - lpEnumDevicesCallback, - lpUserArg); -} - -HRESULT WINAPI -Thunk_IDirect3DImpl_2_CreateLight(LPDIRECT3D2 iface, - LPDIRECT3DLIGHT* lplpDirect3DLight, - IUnknown* pUnkOuter) -{ - TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", iface, lplpDirect3DLight, pUnkOuter); - return IDirect3D3_CreateLight(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D2, IDirect3D3, iface), - lplpDirect3DLight, - pUnkOuter); -} - -HRESULT WINAPI -Thunk_IDirect3DImpl_1_CreateLight(LPDIRECT3D iface, - LPDIRECT3DLIGHT* lplpDirect3DLight, - IUnknown* pUnkOuter) -{ - TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", iface, lplpDirect3DLight, pUnkOuter); - return IDirect3D3_CreateLight(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D, IDirect3D3, iface), - lplpDirect3DLight, - pUnkOuter); -} - -HRESULT WINAPI -Thunk_IDirect3DImpl_1_CreateMaterial(LPDIRECT3D iface, - LPDIRECT3DMATERIAL* lplpDirect3DMaterial, - IUnknown* pUnkOuter) -{ - HRESULT ret; - LPDIRECT3DMATERIAL3 ret_val; - - TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", iface, lplpDirect3DMaterial, pUnkOuter); - ret = IDirect3D3_CreateMaterial(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D, IDirect3D3, iface), - &ret_val, - pUnkOuter); - - *lplpDirect3DMaterial = COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial3, IDirect3DMaterial, ret_val); - - TRACE(" returning interface %p.\n", *lplpDirect3DMaterial); - - return ret; -} - -HRESULT WINAPI -Thunk_IDirect3DImpl_1_CreateViewport(LPDIRECT3D iface, - LPDIRECT3DVIEWPORT* lplpD3DViewport, - IUnknown* pUnkOuter) -{ - TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", iface, lplpD3DViewport, pUnkOuter); - return IDirect3D3_CreateViewport(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D, IDirect3D3, iface), - (LPDIRECT3DVIEWPORT3 *) lplpD3DViewport /* No need to cast here */, - pUnkOuter); -} - -HRESULT WINAPI -Thunk_IDirect3DImpl_2_CreateMaterial(LPDIRECT3D2 iface, - LPDIRECT3DMATERIAL2* lplpDirect3DMaterial2, - IUnknown* pUnkOuter) -{ - HRESULT ret; - LPDIRECT3DMATERIAL3 ret_val; - - TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", iface, lplpDirect3DMaterial2, pUnkOuter); - ret = IDirect3D3_CreateMaterial(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D2, IDirect3D3, iface), - &ret_val, - pUnkOuter); - - *lplpDirect3DMaterial2 = COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial3, IDirect3DMaterial2, ret_val); - - TRACE(" returning interface %p.\n", *lplpDirect3DMaterial2); - - return ret; -} - -HRESULT WINAPI -Thunk_IDirect3DImpl_2_CreateViewport(LPDIRECT3D2 iface, - LPDIRECT3DVIEWPORT2* lplpD3DViewport2, - IUnknown* pUnkOuter) -{ - TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", iface, lplpD3DViewport2, pUnkOuter); - return IDirect3D3_CreateViewport(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D2, IDirect3D3, iface), - (LPDIRECT3DVIEWPORT3 *) lplpD3DViewport2 /* No need to cast here */, - pUnkOuter); -} - - -HRESULT WINAPI -Thunk_IDirect3DImpl_3_CreateVertexBuffer(LPDIRECT3D3 iface, - LPD3DVERTEXBUFFERDESC lpD3DVertBufDesc, - LPDIRECT3DVERTEXBUFFER* lplpD3DVertBuf, - DWORD dwFlags, - LPUNKNOWN lpUnk) -{ - HRESULT ret; - LPDIRECT3DVERTEXBUFFER7 ret_val; - - TRACE("(%p)->(%p,%p,%08lx,%p) thunking to IDirect3D7 interface.\n", iface, lpD3DVertBufDesc, lplpD3DVertBuf, dwFlags, lpUnk); - - /* dwFlags is not used in the D3D7 interface, use the vertex buffer description instead */ - if (dwFlags & D3DDP_DONOTCLIP) lpD3DVertBufDesc->dwCaps |= D3DVBCAPS_DONOTCLIP; - - ret = IDirect3D7_CreateVertexBuffer(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D3, IDirect3D7, iface), - lpD3DVertBufDesc, - &ret_val, - dwFlags); - - *lplpD3DVertBuf = COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, IDirect3DVertexBuffer, ret_val); - - TRACE(" returning interface %p.\n", *lplpD3DVertBuf); - - return ret; -} - -HRESULT WINAPI -Thunk_IDirect3DImpl_1_FindDevice(LPDIRECT3D iface, - LPD3DFINDDEVICESEARCH lpD3DDFS, - LPD3DFINDDEVICERESULT lplpD3DDevice) -{ - TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", iface, lpD3DDFS, lplpD3DDevice); - return IDirect3D3_FindDevice(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D, IDirect3D3, iface), - lpD3DDFS, - lplpD3DDevice); -} - -HRESULT WINAPI -Thunk_IDirect3DImpl_2_FindDevice(LPDIRECT3D2 iface, - LPD3DFINDDEVICESEARCH lpD3DDFS, - LPD3DFINDDEVICERESULT lpD3DFDR) -{ - TRACE("(%p)->(%p,%p) thunking to IDirect3D3 interface.\n", iface, lpD3DDFS, lpD3DFDR); - return IDirect3D3_FindDevice(COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D2, IDirect3D3, iface), - lpD3DDFS, - lpD3DFDR); -} diff --git a/dlls/ddraw/direct3d_opengl.c b/dlls/ddraw/direct3d_opengl.c deleted file mode 100644 index dfe79a82ec..0000000000 --- a/dlls/ddraw/direct3d_opengl.c +++ /dev/null @@ -1,445 +0,0 @@ -/* - * Copyright 2000 Marcus Meissner - * Copyright 2000 Peter Hunnisett - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "config.h" - -#include -#ifdef HAVE_UNISTD_H -# include -#endif -#include -#include -#include -#include - -#define NONAMELESSUNION -#define NONAMELESSSTRUCT - -#include "windef.h" -#include "winbase.h" -#include "wingdi.h" -#include "d3d.h" -#include "ddraw.h" -#include "winerror.h" - -#include "ddraw_private.h" -#include "d3d_private.h" -#include "opengl_private.h" - -#include "wine/debug.h" - -WINE_DEFAULT_DEBUG_CHANNEL(ddraw); - -HRESULT WINAPI -GL_IDirect3DImpl_1_EnumDevices(LPDIRECT3D iface, - LPD3DENUMDEVICESCALLBACK lpEnumDevicesCallback, - LPVOID lpUserArg) -{ - ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D, iface); - TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpEnumDevicesCallback, lpUserArg); - - /* Call functions defined in d3ddevices.c */ - if (d3ddevice_enumerate(lpEnumDevicesCallback, lpUserArg, 1) != D3DENUMRET_OK) - return D3D_OK; - - return D3D_OK; -} - -HRESULT WINAPI -GL_IDirect3DImpl_2_EnumDevices(LPDIRECT3D2 iface, - LPD3DENUMDEVICESCALLBACK lpEnumDevicesCallback, - LPVOID lpUserArg) -{ - ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D2, iface); - TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpEnumDevicesCallback, lpUserArg); - - /* Call functions defined in d3ddevices.c */ - if (d3ddevice_enumerate(lpEnumDevicesCallback, lpUserArg, 2) != D3DENUMRET_OK) - return D3D_OK; - - return D3D_OK; -} - -HRESULT WINAPI -GL_IDirect3DImpl_3_EnumDevices(LPDIRECT3D3 iface, - LPD3DENUMDEVICESCALLBACK lpEnumDevicesCallback, - LPVOID lpUserArg) -{ - ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface); - TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpEnumDevicesCallback, lpUserArg); - - /* Call functions defined in d3ddevices.c */ - if (d3ddevice_enumerate(lpEnumDevicesCallback, lpUserArg, 3) != D3DENUMRET_OK) - return D3D_OK; - - return D3D_OK; -} - -HRESULT WINAPI -GL_IDirect3DImpl_3_2T_1T_CreateLight(LPDIRECT3D3 iface, - LPDIRECT3DLIGHT* lplpDirect3DLight, - IUnknown* pUnkOuter) -{ - ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface); - IDirect3DLightImpl *d3dlimpl; - HRESULT ret_value; - - TRACE("(%p/%p)->(%p,%p)\n", This, iface, lplpDirect3DLight, pUnkOuter); - - ret_value = d3dlight_create(&d3dlimpl, This); - *lplpDirect3DLight = ICOM_INTERFACE(d3dlimpl, IDirect3DLight); - - return ret_value; -} - -HRESULT WINAPI -GL_IDirect3DImpl_3_2T_1T_CreateMaterial(LPDIRECT3D3 iface, - LPDIRECT3DMATERIAL3* lplpDirect3DMaterial3, - IUnknown* pUnkOuter) -{ - IDirect3DMaterialImpl *D3Dmat_impl; - HRESULT ret_value; - ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface); - - TRACE("(%p/%p)->(%p,%p)\n", This, iface, lplpDirect3DMaterial3, pUnkOuter); - ret_value = d3dmaterial_create(&D3Dmat_impl, This); - - *lplpDirect3DMaterial3 = ICOM_INTERFACE(D3Dmat_impl, IDirect3DMaterial3); - - return ret_value; -} - -HRESULT WINAPI -GL_IDirect3DImpl_3_2T_1T_CreateViewport(LPDIRECT3D3 iface, - LPDIRECT3DVIEWPORT3* lplpD3DViewport3, - IUnknown* pUnkOuter) -{ - IDirect3DViewportImpl *D3Dvp_impl; - HRESULT ret_value; - ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface); - - TRACE("(%p/%p)->(%p,%p)\n", This, iface, lplpD3DViewport3, pUnkOuter); - ret_value = d3dviewport_create(&D3Dvp_impl, This); - - *lplpD3DViewport3 = ICOM_INTERFACE(D3Dvp_impl, IDirect3DViewport3); - - return ret_value; -} - -static HRESULT -create_device_helper(IDirectDrawImpl *This, - REFCLSID iid, - IDirectDrawSurfaceImpl *lpDDS, - void **obj, - int version) { - IDirect3DDeviceImpl *lpd3ddev; - HRESULT ret_value; - - ret_value = d3ddevice_create(&lpd3ddev, This, lpDDS, version); - if (FAILED(ret_value)) return ret_value; - - if ((iid == NULL) || - (IsEqualGUID(&IID_D3DDEVICE_OpenGL, iid)) || - (IsEqualGUID(&IID_IDirect3DHALDevice, iid)) || - (IsEqualGUID(&IID_IDirect3DTnLHalDevice, iid)) || - (IsEqualGUID(&IID_IDirect3DRGBDevice, iid)) || - (IsEqualGUID(&IID_IDirect3DRefDevice, iid))) { - switch (version) { - case 1: - *obj = ICOM_INTERFACE(lpd3ddev, IDirect3DDevice); - TRACE(" returning OpenGL D3DDevice %p.\n", *obj); - return D3D_OK; - - case 2: - *obj = ICOM_INTERFACE(lpd3ddev, IDirect3DDevice2); - TRACE(" returning OpenGL D3DDevice2 %p.\n", *obj); - return D3D_OK; - - case 3: - *obj = ICOM_INTERFACE(lpd3ddev, IDirect3DDevice3); - TRACE(" returning OpenGL D3DDevice3 %p.\n", *obj); - return D3D_OK; - - case 7: - *obj = ICOM_INTERFACE(lpd3ddev, IDirect3DDevice7); - TRACE(" returning OpenGL D3DDevice7 %p.\n", *obj); - return D3D_OK; - } - } - - *obj = NULL; - ERR(" Interface unknown when creating D3DDevice (%s)\n", debugstr_guid(iid)); - IDirect3DDevice7_Release(ICOM_INTERFACE(lpd3ddev, IDirect3DDevice7)); - return DDERR_INVALIDPARAMS; -} - - -HRESULT WINAPI -GL_IDirect3DImpl_2_CreateDevice(LPDIRECT3D2 iface, - REFCLSID rclsid, - LPDIRECTDRAWSURFACE lpDDS, - LPDIRECT3DDEVICE2* lplpD3DDevice2) -{ - ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D2, iface); - IDirectDrawSurfaceImpl *ddsurfaceimpl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface3, lpDDS); - TRACE("(%p/%p)->(%s,%p,%p)\n", This, iface, debugstr_guid(rclsid), lpDDS, lplpD3DDevice2); - return create_device_helper(This, rclsid, ddsurfaceimpl, (void **) lplpD3DDevice2, 2); -} - -HRESULT WINAPI -GL_IDirect3DImpl_3_CreateDevice(LPDIRECT3D3 iface, - REFCLSID rclsid, - LPDIRECTDRAWSURFACE4 lpDDS, - LPDIRECT3DDEVICE3* lplpD3DDevice3, - LPUNKNOWN lpUnk) -{ - ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface); - IDirectDrawSurfaceImpl *ddsurfaceimpl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, lpDDS); - TRACE("(%p/%p)->(%s,%p,%p)\n", This, iface, debugstr_guid(rclsid), lpDDS, lplpD3DDevice3); - return create_device_helper(This, rclsid, ddsurfaceimpl, (void **) lplpD3DDevice3, 3); -} - -HRESULT WINAPI -GL_IDirect3DImpl_3_2T_1T_FindDevice(LPDIRECT3D3 iface, - LPD3DFINDDEVICESEARCH lpD3DDFS, - LPD3DFINDDEVICERESULT lpD3DFDR) -{ - ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D3, iface); - TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpD3DDFS, lpD3DFDR); - return d3ddevice_find(This, lpD3DDFS, lpD3DFDR); -} - -HRESULT WINAPI -GL_IDirect3DImpl_7_3T_EnumZBufferFormats(LPDIRECT3D7 iface, - REFCLSID riidDevice, - LPD3DENUMPIXELFORMATSCALLBACK lpEnumCallback, - LPVOID lpContext) -{ - ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D7, iface); - DDPIXELFORMAT pformat; - - TRACE("(%p/%p)->(%s,%p,%p)\n", This, iface, debugstr_guid(riidDevice), lpEnumCallback, lpContext); - - memset(&pformat, 0, sizeof(pformat)); - pformat.dwSize = sizeof(DDPIXELFORMAT); - pformat.dwFourCC = 0; - TRACE("Enumerating dummy ZBuffer format (16 bits)\n"); - pformat.dwFlags = DDPF_ZBUFFER; - pformat.u1.dwZBufferBitDepth = 16; - pformat.u3.dwZBitMask = 0x0000FFFF; - pformat.u5.dwRGBZBitMask = 0x0000FFFF; - - /* Whatever the return value, stop here.. */ - lpEnumCallback(&pformat, lpContext); - - return D3D_OK; -} - -HRESULT WINAPI -GL_IDirect3DImpl_7_EnumDevices(LPDIRECT3D7 iface, - LPD3DENUMDEVICESCALLBACK7 lpEnumDevicesCallback, - LPVOID lpUserArg) -{ - ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D7, iface); - TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpEnumDevicesCallback, lpUserArg); - - if (d3ddevice_enumerate7(lpEnumDevicesCallback, lpUserArg) != D3DENUMRET_OK) - return D3D_OK; - - return D3D_OK; -} - -HRESULT WINAPI -GL_IDirect3DImpl_7_CreateDevice(LPDIRECT3D7 iface, - REFCLSID rclsid, - LPDIRECTDRAWSURFACE7 lpDDS, - LPDIRECT3DDEVICE7* lplpD3DDevice) -{ - ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D7, iface); - IDirectDrawSurfaceImpl *ddsurfaceimpl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, lpDDS); - TRACE("(%p/%p)->(%s,%p,%p)\n", This, iface, debugstr_guid(rclsid), lpDDS, lplpD3DDevice); - return create_device_helper(This, rclsid, ddsurfaceimpl, (void **) lplpD3DDevice, 7); -} - -HRESULT WINAPI -GL_IDirect3DImpl_7_3T_CreateVertexBuffer(LPDIRECT3D7 iface, - LPD3DVERTEXBUFFERDESC lpD3DVertBufDesc, - LPDIRECT3DVERTEXBUFFER7* lplpD3DVertBuf, - DWORD dwFlags) -{ - ICOM_THIS_FROM(IDirectDrawImpl, IDirect3D7, iface); - IDirect3DVertexBufferImpl *vbimpl; - HRESULT res; - - TRACE("(%p/%p)->(%p,%p,%08lx)\n", This, iface, lpD3DVertBufDesc, lplpD3DVertBuf, dwFlags); - - res = d3dvertexbuffer_create(&vbimpl, This, lpD3DVertBufDesc, dwFlags); - - *lplpD3DVertBuf = ICOM_INTERFACE(vbimpl, IDirect3DVertexBuffer7); - - return res; -} - -#if !defined(__STRICT_ANSI__) && defined(__GNUC__) -# define XCAST(fun) (typeof(VTABLE_IDirect3D7.fun)) -#else -# define XCAST(fun) (void*) -#endif - -static const IDirect3D7Vtbl VTABLE_IDirect3D7 = -{ - XCAST(QueryInterface) Thunk_IDirect3DImpl_7_QueryInterface, - XCAST(AddRef) Thunk_IDirect3DImpl_7_AddRef, - XCAST(Release) Thunk_IDirect3DImpl_7_Release, - XCAST(EnumDevices) GL_IDirect3DImpl_7_EnumDevices, - XCAST(CreateDevice) GL_IDirect3DImpl_7_CreateDevice, - XCAST(CreateVertexBuffer) GL_IDirect3DImpl_7_3T_CreateVertexBuffer, - XCAST(EnumZBufferFormats) GL_IDirect3DImpl_7_3T_EnumZBufferFormats, - XCAST(EvictManagedTextures) Main_IDirect3DImpl_7_3T_EvictManagedTextures, -}; - -#if !defined(__STRICT_ANSI__) && defined(__GNUC__) -#undef XCAST -#endif - - -#if !defined(__STRICT_ANSI__) && defined(__GNUC__) -# define XCAST(fun) (typeof(VTABLE_IDirect3D3.fun)) -#else -# define XCAST(fun) (void*) -#endif - -static const IDirect3D3Vtbl VTABLE_IDirect3D3 = -{ - XCAST(QueryInterface) Thunk_IDirect3DImpl_3_QueryInterface, - XCAST(AddRef) Thunk_IDirect3DImpl_3_AddRef, - XCAST(Release) Thunk_IDirect3DImpl_3_Release, - XCAST(EnumDevices) GL_IDirect3DImpl_3_EnumDevices, - XCAST(CreateLight) GL_IDirect3DImpl_3_2T_1T_CreateLight, - XCAST(CreateMaterial) GL_IDirect3DImpl_3_2T_1T_CreateMaterial, - XCAST(CreateViewport) GL_IDirect3DImpl_3_2T_1T_CreateViewport, - XCAST(FindDevice) GL_IDirect3DImpl_3_2T_1T_FindDevice, - XCAST(CreateDevice) GL_IDirect3DImpl_3_CreateDevice, - XCAST(CreateVertexBuffer) Thunk_IDirect3DImpl_3_CreateVertexBuffer, - XCAST(EnumZBufferFormats) Thunk_IDirect3DImpl_3_EnumZBufferFormats, - XCAST(EvictManagedTextures) Thunk_IDirect3DImpl_3_EvictManagedTextures, -}; - -#if !defined(__STRICT_ANSI__) && defined(__GNUC__) -#undef XCAST -#endif - - -#if !defined(__STRICT_ANSI__) && defined(__GNUC__) -# define XCAST(fun) (typeof(VTABLE_IDirect3D2.fun)) -#else -# define XCAST(fun) (void*) -#endif - -static const IDirect3D2Vtbl VTABLE_IDirect3D2 = -{ - XCAST(QueryInterface) Thunk_IDirect3DImpl_2_QueryInterface, - XCAST(AddRef) Thunk_IDirect3DImpl_2_AddRef, - XCAST(Release) Thunk_IDirect3DImpl_2_Release, - XCAST(EnumDevices) GL_IDirect3DImpl_2_EnumDevices, - XCAST(CreateLight) Thunk_IDirect3DImpl_2_CreateLight, - XCAST(CreateMaterial) Thunk_IDirect3DImpl_2_CreateMaterial, - XCAST(CreateViewport) Thunk_IDirect3DImpl_2_CreateViewport, - XCAST(FindDevice) Thunk_IDirect3DImpl_2_FindDevice, - XCAST(CreateDevice) GL_IDirect3DImpl_2_CreateDevice, -}; - -#if !defined(__STRICT_ANSI__) && defined(__GNUC__) -#undef XCAST -#endif - - -#if !defined(__STRICT_ANSI__) && defined(__GNUC__) -# define XCAST(fun) (typeof(VTABLE_IDirect3D.fun)) -#else -# define XCAST(fun) (void*) -#endif - -static const IDirect3DVtbl VTABLE_IDirect3D = -{ - XCAST(QueryInterface) Thunk_IDirect3DImpl_1_QueryInterface, - XCAST(AddRef) Thunk_IDirect3DImpl_1_AddRef, - XCAST(Release) Thunk_IDirect3DImpl_1_Release, - XCAST(Initialize) Main_IDirect3DImpl_1_Initialize, - XCAST(EnumDevices) GL_IDirect3DImpl_1_EnumDevices, - XCAST(CreateLight) Thunk_IDirect3DImpl_1_CreateLight, - XCAST(CreateMaterial) Thunk_IDirect3DImpl_1_CreateMaterial, - XCAST(CreateViewport) Thunk_IDirect3DImpl_1_CreateViewport, - XCAST(FindDevice) Thunk_IDirect3DImpl_1_FindDevice, -}; - -#if !defined(__STRICT_ANSI__) && defined(__GNUC__) -#undef XCAST -#endif - -static HRESULT d3d_add_device(IDirectDrawImpl *This, IDirect3DDeviceImpl *device) -{ - if (This->current_device == NULL) { - /* Create delayed textures now that we have an OpenGL context... - For that, go through all surface attached to our DDraw object and create - OpenGL textures for all textures.. */ - IDirectDrawSurfaceImpl *surf = This->surfaces; - - while (surf != NULL) { - if (surf->surface_desc.ddsCaps.dwCaps & DDSCAPS_TEXTURE) { - /* Found a texture.. Now create the OpenGL part */ - d3dtexture_create(This, surf, FALSE, surf->mip_main); - } - surf = surf->next_ddraw; - } - } - /* For the moment, only one device 'supported'... */ - This->current_device = device; - - return DD_OK; -} - -static HRESULT d3d_remove_device(IDirectDrawImpl *This, IDirect3DDeviceImpl *device) -{ - This->current_device = NULL; - return DD_OK; -} - -HRESULT direct3d_create(IDirectDrawImpl *This) -{ - IDirect3DGLImpl *globject; - - globject = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DGLImpl)); - if (globject == NULL) return DDERR_OUTOFMEMORY; - - This->d3d_create_texture = d3dtexture_create; - This->d3d_added_device = d3d_add_device; - This->d3d_removed_device = d3d_remove_device; - - ICOM_INIT_INTERFACE(This, IDirect3D, VTABLE_IDirect3D); - ICOM_INIT_INTERFACE(This, IDirect3D2, VTABLE_IDirect3D2); - ICOM_INIT_INTERFACE(This, IDirect3D3, VTABLE_IDirect3D3); - ICOM_INIT_INTERFACE(This, IDirect3D7, VTABLE_IDirect3D7); - - This->d3d_private = globject; - - TRACE(" creating OpenGL private storage at %p.\n", globject); - - return D3D_OK; -} diff --git a/dlls/ddraw/executebuffer.c b/dlls/ddraw/executebuffer.c index 274c2a0baf..683ffe30c3 100644 --- a/dlls/ddraw/executebuffer.c +++ b/dlls/ddraw/executebuffer.c @@ -1,8 +1,9 @@ /* Direct3D ExecuteBuffer * Copyright (c) 1998-2004 Lionel ULMER * Copyright (c) 2002-2004 Christian Costa + * Copyright (c) 2006 Stefan Dösinger * - * This file contains the implementation of Direct3DExecuteBuffer. + * This file contains the implementation of IDirect3DExecuteBuffer. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,38 +21,45 @@ */ #include "config.h" +#include "wine/port.h" +#include #include #include +#include +#define COBJMACROS #define NONAMELESSUNION -#define NONAMELESSSTRUCT #include "windef.h" #include "winbase.h" +#include "winnls.h" #include "winerror.h" -#include "objbase.h" #include "wingdi.h" +#include "wine/exception.h" +#include "excpt.h" + #include "ddraw.h" #include "d3d.h" + +#include "ddraw_private.h" #include "wine/debug.h" -#include "d3d_private.h" -#include "opengl_private.h" +WINE_DEFAULT_DEBUG_CHANNEL(d3d7); -WINE_DEFAULT_DEBUG_CHANNEL(ddraw); -WINE_DECLARE_DEBUG_CHANNEL(ddraw_geom); - -static void _dump_d3dstatus(LPD3DSTATUS lpStatus) { - -} +/***************************************************************************** + * _dump_executedata + * _dump_D3DEXECUTEBUFFERDESC + * + * Debug functions which write the executebuffer data to the console + * + *****************************************************************************/ static void _dump_executedata(LPD3DEXECUTEDATA lpData) { DPRINTF("dwSize : %ld\n", lpData->dwSize); DPRINTF("Vertex Offset : %ld Count : %ld\n", lpData->dwVertexOffset, lpData->dwVertexCount); DPRINTF("Instruction Offset : %ld Length : %ld\n", lpData->dwInstructionOffset, lpData->dwInstructionLength); DPRINTF("HVertex Offset : %ld\n", lpData->dwHVertexOffset); - _dump_d3dstatus(&(lpData->dsStatus)); } static void _dump_D3DEXECUTEBUFFERDESC(LPD3DEXECUTEBUFFERDESC lpDesc) { @@ -62,9 +70,28 @@ static void _dump_D3DEXECUTEBUFFERDESC(LPD3DEXECUTEBUFFERDESC lpDesc) { DPRINTF("lpData : %p\n", lpDesc->lpData); } -static void execute(IDirect3DExecuteBufferImpl *This, - IDirect3DDeviceImpl *lpDevice, - IDirect3DViewportImpl *lpViewport) +/***************************************************************************** + * IDirect3DExecuteBufferImpl_Execute + * + * The main functionality of the execute buffer + * It transforms the vertices if necessary, and calls IDirect3DDevice7 + * for drawing the vertices. It is called from + * IDirect3DDevice::Execute + * + * TODO: Perhaps some comments about the varios opcodes wouldn't hurt + * + * Don't declare this static, as it's called from device.c, + * IDirect3DDevice::Execute + * + * Params: + * Device: 3D Device associated to use for drawing + * Viewport: Viewport for this operation + * + *****************************************************************************/ +void +IDirect3DExecuteBufferImpl_Execute(IDirect3DExecuteBufferImpl *This, + IDirect3DDeviceImpl *lpDevice, + IDirect3DViewportImpl *lpViewport) { /* DWORD bs = This->desc.dwBufferSize; */ DWORD vs = This->data.dwVertexOffset; @@ -81,7 +108,7 @@ static void execute(IDirect3DExecuteBufferImpl *This, lpViewport->activate(lpViewport); TRACE("ExecuteData :\n"); - if (TRACE_ON(ddraw)) + if (TRACE_ON(d3d7)) _dump_executedata(&(This->data)); while (1) { @@ -117,32 +144,39 @@ static void execute(IDirect3DExecuteBufferImpl *This, for (i = 0; i < count; i++) { LPD3DTRIANGLE ci = (LPD3DTRIANGLE) instr; - TRACE_(ddraw_geom)(" v1: %d v2: %d v3: %d\n",ci->u1.v1, ci->u2.v2, ci->u3.v3); - TRACE_(ddraw_geom)(" Flags : "); - if (TRACE_ON(ddraw)) { + TRACE_(d3d7)(" v1: %d v2: %d v3: %d\n",ci->u1.v1, ci->u2.v2, ci->u3.v3); + TRACE_(d3d7)(" Flags : "); + if (TRACE_ON(d3d7)) { /* Wireframe */ if (ci->wFlags & D3DTRIFLAG_EDGEENABLE1) - TRACE_(ddraw_geom)("EDGEENABLE1 "); + TRACE_(d3d7)("EDGEENABLE1 "); if (ci->wFlags & D3DTRIFLAG_EDGEENABLE2) - TRACE_(ddraw_geom)("EDGEENABLE2 "); + TRACE_(d3d7)("EDGEENABLE2 "); if (ci->wFlags & D3DTRIFLAG_EDGEENABLE1) - TRACE_(ddraw_geom)("EDGEENABLE3 "); + TRACE_(d3d7)("EDGEENABLE3 "); /* Strips / Fans */ if (ci->wFlags == D3DTRIFLAG_EVEN) - TRACE_(ddraw_geom)("EVEN "); + TRACE_(d3d7)("EVEN "); if (ci->wFlags == D3DTRIFLAG_ODD) - TRACE_(ddraw_geom)("ODD "); + TRACE_(d3d7)("ODD "); if (ci->wFlags == D3DTRIFLAG_START) - TRACE_(ddraw_geom)("START "); + TRACE_(d3d7)("START "); if ((ci->wFlags > 0) && (ci->wFlags < 30)) - TRACE_(ddraw_geom)("STARTFLAT(%d) ", ci->wFlags); - TRACE_(ddraw_geom)("\n"); + TRACE_(d3d7)("STARTFLAT(%d) ", ci->wFlags); + TRACE_(d3d7)("\n"); } This->indices[(i * 3) ] = ci->u1.v1; This->indices[(i * 3) + 1] = ci->u2.v2; This->indices[(i * 3) + 2] = ci->u3.v3; instr += size; } + /* IDirect3DDevices have color keying always enabled - + * enable it before drawing. This overwrites any ALPHA* + * render state + */ + IWineD3DDevice_SetRenderState(lpDevice->wineD3DDevice, + WINED3DRS_COLORKEYENABLE, + 1); IDirect3DDevice7_DrawIndexedPrimitive(ICOM_INTERFACE(lpDevice,IDirect3DDevice7), D3DPT_TRIANGLELIST,D3DFVF_TLVERTEX,tl_vx,0,This->indices,count*3,0); } break; @@ -264,9 +298,27 @@ static void execute(IDirect3DExecuteBufferImpl *This, } } break; - case D3DOP_PROCESSVERTICES: { - int i; - TRACE("PROCESSVERTICES (%d)\n", count); + case D3DOP_PROCESSVERTICES: + { + /* TODO: Share code with IDirect3DVertexBuffer::ProcessVertices and / or + * IWineD3DDevice::ProcessVertices + */ + int i; + D3DMATRIX view_mat, world_mat, proj_mat; + TRACE("PROCESSVERTICES (%d)\n", count); + + /* Get the transform and world matrix */ + IWineD3DDevice_GetTransform(lpDevice->wineD3DDevice, + D3DTRANSFORMSTATE_VIEW, + &view_mat); + + IWineD3DDevice_GetTransform(lpDevice->wineD3DDevice, + D3DTRANSFORMSTATE_PROJECTION, + &proj_mat); + + IWineD3DDevice_GetTransform(lpDevice->wineD3DDevice, + D3DTRANSFORMSTATE_WORLD, + &world_mat); for (i = 0; i < count; i++) { LPD3DPROCESSVERTICES ci = (LPD3DPROCESSVERTICES) instr; @@ -274,7 +326,7 @@ static void execute(IDirect3DExecuteBufferImpl *This, TRACE(" Start : %d Dest : %d Count : %ld\n", ci->wStart, ci->wDest, ci->dwCount); TRACE(" Flags : "); - if (TRACE_ON(ddraw)) { + if (TRACE_ON(d3d7)) { if (ci->dwFlags & D3DPROCESSVERTICES_COPY) TRACE("COPY "); if (ci->dwFlags & D3DPROCESSVERTICES_NOCOLOR) @@ -321,22 +373,22 @@ static void execute(IDirect3DExecuteBufferImpl *This, unsigned int nb; D3DVERTEX *src = ((LPD3DVERTEX) ((char *)This->desc.lpData + vs)) + ci->wStart; D3DTLVERTEX *dst = ((LPD3DTLVERTEX) (This->vertex_data)) + ci->wDest; - D3DMATRIX *mat2 = lpDevice->world_mat; + D3DMATRIX *mat2 = &world_mat; D3DMATRIX mat; D3DVALUE nx,ny,nz; D3DVIEWPORT* Viewport = &lpViewport->viewports.vp1; - if (TRACE_ON(ddraw)) { - TRACE(" Projection Matrix : (%p)\n", lpDevice->proj_mat); - dump_D3DMATRIX(lpDevice->proj_mat); - TRACE(" View Matrix : (%p)\n", lpDevice->view_mat); - dump_D3DMATRIX(lpDevice->view_mat); - TRACE(" World Matrix : (%p)\n", lpDevice->world_mat); - dump_D3DMATRIX(lpDevice->world_mat); + if (TRACE_ON(d3d7)) { + TRACE(" Projection Matrix : (%p)\n", &proj_mat); + dump_D3DMATRIX(&proj_mat); + TRACE(" View Matrix : (%p)\n", &view_mat); + dump_D3DMATRIX(&view_mat); + TRACE(" World Matrix : (%p)\n", &world_mat); + dump_D3DMATRIX(&world_mat); } - multiply_matrix(&mat,lpDevice->view_mat,lpDevice->world_mat); - multiply_matrix(&mat,lpDevice->proj_mat,&mat); + multiply_matrix(&mat,&view_mat,&world_mat); + multiply_matrix(&mat,&proj_mat,&mat); for (nb = 0; nb < ci->dwCount; nb++) { /* Normals transformation */ @@ -375,17 +427,17 @@ static void execute(IDirect3DExecuteBufferImpl *This, D3DMATRIX mat; D3DVIEWPORT* Viewport = &lpViewport->viewports.vp1; - if (TRACE_ON(ddraw)) { - TRACE(" Projection Matrix : (%p)\n", lpDevice->proj_mat); - dump_D3DMATRIX(lpDevice->proj_mat); - TRACE(" View Matrix : (%p)\n", lpDevice->view_mat); - dump_D3DMATRIX(lpDevice->view_mat); + if (TRACE_ON(d3d7)) { + TRACE(" Projection Matrix : (%p)\n", &proj_mat); + dump_D3DMATRIX(&proj_mat); + TRACE(" View Matrix : (%p)\n",&view_mat); + dump_D3DMATRIX(&view_mat); TRACE(" World Matrix : (%p)\n", &mat); dump_D3DMATRIX(&mat); } - multiply_matrix(&mat,lpDevice->view_mat,lpDevice->world_mat); - multiply_matrix(&mat,lpDevice->proj_mat,&mat); + multiply_matrix(&mat,&view_mat,&world_mat); + multiply_matrix(&mat,&proj_mat,&mat); for (nb = 0; nb < ci->dwCount; nb++) { dst->u5.color = src->u4.color; @@ -490,50 +542,85 @@ end_of_buffer: ; } -HRESULT WINAPI -Main_IDirect3DExecuteBufferImpl_1_QueryInterface(LPDIRECT3DEXECUTEBUFFER iface, - REFIID riid, - LPVOID* obp) +/***************************************************************************** + * IDirect3DExecuteBuffer::QueryInterface + * + * Well, a usual QueryInterface function. Don't know fur sure which + * interfaces it can Query. + * + * Params: + * riid: The interface ID queried for + * obj: Address to return the interface pointer at + * + * Returns: + * D3D_OK in case of a success (S_OK? Think it's the same) + * OLE_E_ENUM_NOMORE if the interface wasn't found. + * (E_NOINTERFACE?? Don't know what I really need) + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DExecuteBufferImpl_QueryInterface(IDirect3DExecuteBuffer *iface, + REFIID riid, + void **obj) { ICOM_THIS_FROM(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, iface); - TRACE("(%p/%p)->(%s,%p)\n", This, iface, debugstr_guid(riid), obp); + TRACE("(%p/%p)->(%s,%p)\n", This, iface, debugstr_guid(riid), obj); - *obp = NULL; + *obj = NULL; if ( IsEqualGUID( &IID_IUnknown, riid ) ) { IDirect3DExecuteBuffer_AddRef(ICOM_INTERFACE(This, IDirect3DExecuteBuffer)); - *obp = iface; - TRACE(" Creating IUnknown interface at %p.\n", *obp); + *obj = iface; + TRACE(" Creating IUnknown interface at %p.\n", *obj); return S_OK; } if ( IsEqualGUID( &IID_IDirect3DMaterial, riid ) ) { IDirect3DExecuteBuffer_AddRef(ICOM_INTERFACE(This, IDirect3DExecuteBuffer)); - *obp = ICOM_INTERFACE(This, IDirect3DExecuteBuffer); - TRACE(" Creating IDirect3DExecuteBuffer interface %p\n", *obp); + *obj = ICOM_INTERFACE(This, IDirect3DExecuteBuffer); + TRACE(" Creating IDirect3DExecuteBuffer interface %p\n", *obj); return S_OK; } FIXME("(%p): interface for IID %s NOT found!\n", This, debugstr_guid(riid)); - return OLE_E_ENUM_NOMORE; + return E_NOINTERFACE; } -ULONG WINAPI -Main_IDirect3DExecuteBufferImpl_1_AddRef(LPDIRECT3DEXECUTEBUFFER iface) + +/***************************************************************************** + * IDirect3DExecuteBuffer::AddRef + * + * A normal AddRef method, nothing special + * + * Returns: + * The new refcount + * + *****************************************************************************/ +static ULONG WINAPI +IDirect3DExecuteBufferImpl_AddRef(IDirect3DExecuteBuffer *iface) { ICOM_THIS_FROM(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, iface); ULONG ref = InterlockedIncrement(&This->ref); - FIXME("(%p/%p)->()incrementing from %lu.\n", This, iface, ref - 1); + FIXME("(%p)->()incrementing from %lu.\n", This, ref - 1); return ref; } -ULONG WINAPI -Main_IDirect3DExecuteBufferImpl_1_Release(LPDIRECT3DEXECUTEBUFFER iface) +/***************************************************************************** + * IDirect3DExecuteBuffer::Release + * + * A normal Release method, nothing special + * + * Returns: + * The new refcount + * + *****************************************************************************/ +static ULONG WINAPI +IDirect3DExecuteBufferImpl_Release(IDirect3DExecuteBuffer *iface) { ICOM_THIS_FROM(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p/%p)->()decrementing from %lu.\n", This, iface, ref + 1); + TRACE("(%p)->()decrementing from %lu.\n", This, ref + 1); if (!ref) { if (This->need_free) @@ -547,50 +634,96 @@ Main_IDirect3DExecuteBufferImpl_1_Release(LPDIRECT3DEXECUTEBUFFER iface) return ref; } -HRESULT WINAPI -Main_IDirect3DExecuteBufferImpl_1_Initialize(LPDIRECT3DEXECUTEBUFFER iface, - LPDIRECT3DDEVICE lpDirect3DDevice, - LPD3DEXECUTEBUFFERDESC lpDesc) +/***************************************************************************** + * IDirect3DExecuteBuffer::Initialize + * + * Initializes the Execute Buffer. This method exists for COM compliance + * Nothing to do here. + * + * Returns: + * D3D_OK + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DExecuteBufferImpl_Initialize(IDirect3DExecuteBuffer *iface, + IDirect3DDevice *lpDirect3DDevice, + D3DEXECUTEBUFFERDESC *lpDesc) { ICOM_THIS_FROM(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, iface); - TRACE("(%p/%p)->(%p,%p) no-op....\n", This, iface, lpDirect3DDevice, lpDesc); - return DD_OK; + TRACE("(%p)->(%p,%p) no-op....\n", This, lpDirect3DDevice, lpDesc); + return D3D_OK; } -HRESULT WINAPI -Main_IDirect3DExecuteBufferImpl_1_Lock(LPDIRECT3DEXECUTEBUFFER iface, - LPD3DEXECUTEBUFFERDESC lpDesc) +/***************************************************************************** + * IDirect3DExecuteBuffer::Lock + * + * Locks the buffer, so the app can write into it. + * + * Params: + * Desc: Pointer to return the buffer description. This Description contains + * a pointer to the buffer data. + * + * Returns: + * This implementation always returns D3D_OK + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DExecuteBufferImpl_Lock(IDirect3DExecuteBuffer *iface, + D3DEXECUTEBUFFERDESC *lpDesc) { ICOM_THIS_FROM(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, iface); DWORD dwSize; - TRACE("(%p/%p)->(%p)\n", This, iface, lpDesc); + TRACE("(%p)->(%p)\n", This, lpDesc); dwSize = lpDesc->dwSize; memset(lpDesc, 0, dwSize); memcpy(lpDesc, &This->desc, dwSize); - if (TRACE_ON(ddraw)) { + if (TRACE_ON(d3d7)) { TRACE(" Returning description :\n"); _dump_D3DEXECUTEBUFFERDESC(lpDesc); } - return DD_OK; + return D3D_OK; } -HRESULT WINAPI -Main_IDirect3DExecuteBufferImpl_1_Unlock(LPDIRECT3DEXECUTEBUFFER iface) +/***************************************************************************** + * IDirect3DExecuteBuffer::Unlock + * + * Unlocks the buffer. We don't have anything to do here + * + * Returns: + * This implementation always returns D3D_OK + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DExecuteBufferImpl_Unlock(IDirect3DExecuteBuffer *iface) { ICOM_THIS_FROM(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, iface); - TRACE("(%p/%p)->() no-op...\n", This, iface); - return DD_OK; + TRACE("(%p)->() no-op...\n", This); + return D3D_OK; } -HRESULT WINAPI -Main_IDirect3DExecuteBufferImpl_1_SetExecuteData(LPDIRECT3DEXECUTEBUFFER iface, - LPD3DEXECUTEDATA lpData) +/***************************************************************************** + * IDirect3DExecuteBuffer::SetExecuteData + * + * Sets the execute data. This data is used to describe the buffer's content + * + * Params: + * Data: Pointer to a D3DEXECUTEDATA structure containing the data to + * assign + * + * Returns: + * D3D_OK on success + * DDERR_OUTOFMEMORY if the vertex buffer allocation failed + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DExecuteBufferImpl_SetExecuteData(IDirect3DExecuteBuffer *iface, + D3DEXECUTEDATA *lpData) { ICOM_THIS_FROM(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, iface); DWORD nbvert; - TRACE("(%p/%p)->(%p)\n", This, iface, lpData); + TRACE("(%p)->(%p)\n", This, lpData); memcpy(&This->data, lpData, lpData->dwSize); @@ -601,26 +734,38 @@ Main_IDirect3DExecuteBufferImpl_1_SetExecuteData(LPDIRECT3DEXECUTEBUFFER iface, HeapFree(GetProcessHeap(), 0, This->vertex_data); This->vertex_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nbvert * sizeof(D3DTLVERTEX)); - if (TRACE_ON(ddraw)) { + if (TRACE_ON(d3d7)) { _dump_executedata(lpData); } - return DD_OK; + return D3D_OK; } -HRESULT WINAPI -Main_IDirect3DExecuteBufferImpl_1_GetExecuteData(LPDIRECT3DEXECUTEBUFFER iface, - LPD3DEXECUTEDATA lpData) +/***************************************************************************** + * IDirect3DExecuteBuffer::GetExecuteData + * + * Returns the data in the execute buffer + * + * Params: + * Data: Pointer to a D3DEXECUTEDATA structure used to return data + * + * Returns: + * D3D_OK on success + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DExecuteBufferImpl_GetExecuteData(IDirect3DExecuteBuffer *iface, + D3DEXECUTEDATA *lpData) { ICOM_THIS_FROM(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, iface); DWORD dwSize; - TRACE("(%p/%p)->(%p): stub!\n", This, iface, lpData); + TRACE("(%p)->(%p): stub!\n", This, lpData); dwSize = lpData->dwSize; memset(lpData, 0, dwSize); memcpy(lpData, &This->data, dwSize); - if (TRACE_ON(ddraw)) { + if (TRACE_ON(d3d7)) { TRACE("Returning data :\n"); _dump_executedata(lpData); } @@ -628,96 +773,63 @@ Main_IDirect3DExecuteBufferImpl_1_GetExecuteData(LPDIRECT3DEXECUTEBUFFER iface, return DD_OK; } -HRESULT WINAPI -Main_IDirect3DExecuteBufferImpl_1_Validate(LPDIRECT3DEXECUTEBUFFER iface, - LPDWORD lpdwOffset, - LPD3DVALIDATECALLBACK lpFunc, - LPVOID lpUserArg, - DWORD dwReserved) +/***************************************************************************** + * IDirect3DExecuteBuffer::Validate + * + * DirectX 5 SDK: "The IDirect3DExecuteBuffer::Validate method is not + * currently implemented" + * + * Params: + * ? + * + * Returns: + * DDERR_UNSUPPORTED, because it's not implemented in Windows. + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DExecuteBufferImpl_Validate(IDirect3DExecuteBuffer *iface, + DWORD *Offset, + LPD3DVALIDATECALLBACK Func, + void *UserArg, + DWORD Reserved) { ICOM_THIS_FROM(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, iface); - FIXME("(%p/%p)->(%p,%p,%p,%08lx): stub!\n", This, iface, lpdwOffset, lpFunc, lpUserArg, dwReserved); - return DD_OK; + TRACE("(%p)->(%p,%p,%p,%08lx): Unimplemented!\n", This, Offset, Func, UserArg, Reserved); + return DDERR_UNSUPPORTED; /* Unchecked */ } -HRESULT WINAPI -Main_IDirect3DExecuteBufferImpl_1_Optimize(LPDIRECT3DEXECUTEBUFFER iface, - DWORD dwDummy) +/***************************************************************************** + * IDirect3DExecuteBuffer::Optimize + * + * DirectX5 SDK: "The IDirect3DExecuteBuffer::Optimize method is not + * currently supported" + * + * Params: + * Dummy: Seems to be an unused dummy ;) + * + * Returns: + * DDERR_UNSUPPORTED, because it's not implemented in Windows. + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DExecuteBufferImpl_Optimize(IDirect3DExecuteBuffer *iface, + DWORD Dummy) { ICOM_THIS_FROM(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, iface); - TRACE("(%p/%p)->(%08lx) no-op...\n", This, iface, dwDummy); - return DD_OK; + TRACE("(%p)->(%08lx): Unimplemented\n", This, Dummy); + return DDERR_UNSUPPORTED; /* Unchecked */ } -#if !defined(__STRICT_ANSI__) && defined(__GNUC__) -# define XCAST(fun) (typeof(VTABLE_IDirect3DExecuteBuffer.fun)) -#else -# define XCAST(fun) (void*) -#endif - -static const IDirect3DExecuteBufferVtbl VTABLE_IDirect3DExecuteBuffer = +const IDirect3DExecuteBufferVtbl IDirect3DExecuteBuffer_Vtbl = { - XCAST(QueryInterface) Main_IDirect3DExecuteBufferImpl_1_QueryInterface, - XCAST(AddRef) Main_IDirect3DExecuteBufferImpl_1_AddRef, - XCAST(Release) Main_IDirect3DExecuteBufferImpl_1_Release, - XCAST(Initialize) Main_IDirect3DExecuteBufferImpl_1_Initialize, - XCAST(Lock) Main_IDirect3DExecuteBufferImpl_1_Lock, - XCAST(Unlock) Main_IDirect3DExecuteBufferImpl_1_Unlock, - XCAST(SetExecuteData) Main_IDirect3DExecuteBufferImpl_1_SetExecuteData, - XCAST(GetExecuteData) Main_IDirect3DExecuteBufferImpl_1_GetExecuteData, - XCAST(Validate) Main_IDirect3DExecuteBufferImpl_1_Validate, - XCAST(Optimize) Main_IDirect3DExecuteBufferImpl_1_Optimize, + IDirect3DExecuteBufferImpl_QueryInterface, + IDirect3DExecuteBufferImpl_AddRef, + IDirect3DExecuteBufferImpl_Release, + IDirect3DExecuteBufferImpl_Initialize, + IDirect3DExecuteBufferImpl_Lock, + IDirect3DExecuteBufferImpl_Unlock, + IDirect3DExecuteBufferImpl_SetExecuteData, + IDirect3DExecuteBufferImpl_GetExecuteData, + IDirect3DExecuteBufferImpl_Validate, + IDirect3DExecuteBufferImpl_Optimize, }; - -#if !defined(__STRICT_ANSI__) && defined(__GNUC__) -#undef XCAST -#endif - - -HRESULT d3dexecutebuffer_create(IDirect3DExecuteBufferImpl **obj, IDirectDrawImpl *d3d, IDirect3DDeviceImpl *d3ddev, LPD3DEXECUTEBUFFERDESC lpDesc) -{ - IDirect3DExecuteBufferImpl* object; - - object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DExecuteBufferImpl)); - - ICOM_INIT_INTERFACE(object, IDirect3DExecuteBuffer, VTABLE_IDirect3DExecuteBuffer); - - object->ref = 1; - object->d3d = d3d; - object->d3ddev = d3ddev; - - /* Initializes memory */ - memcpy(&object->desc, lpDesc, lpDesc->dwSize); - - /* No buffer given */ - if ((object->desc.dwFlags & D3DDEB_LPDATA) == 0) - object->desc.lpData = NULL; - - /* No buffer size given */ - if ((lpDesc->dwFlags & D3DDEB_BUFSIZE) == 0) - object->desc.dwBufferSize = 0; - - /* Create buffer if asked */ - if ((object->desc.lpData == NULL) && (object->desc.dwBufferSize > 0)) { - object->need_free = TRUE; - object->desc.lpData = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,object->desc.dwBufferSize); - } else { - object->need_free = FALSE; - } - - /* No vertices for the moment */ - object->vertex_data = NULL; - - object->desc.dwFlags |= D3DDEB_LPDATA; - - object->execute = execute; - - object->indices = NULL; - object->nb_indices = 0; - - *obj = object; - - TRACE(" creating implementation at %p.\n", *obj); - - return DD_OK; -} diff --git a/dlls/ddraw/gamma.c b/dlls/ddraw/gamma.c new file mode 100644 index 0000000000..0f3692b685 --- /dev/null +++ b/dlls/ddraw/gamma.c @@ -0,0 +1,213 @@ +/* DirectDrawGammaControl implementation + * + * Copyright 2001 TransGaming Technologies Inc. + * Copyright 2006 Stefan Dösinger + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include "wine/port.h" +#include "wine/debug.h" + +#include +#include +#include +#include + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "winnls.h" +#include "winerror.h" +#include "wingdi.h" +#include "wine/exception.h" +#include "excpt.h" + +#include "ddraw.h" +#include "d3d.h" + +#include "ddraw_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(ddraw); +WINE_DECLARE_DEBUG_CHANNEL(ddraw_thunk); + +/********************************************************** + * IUnkown parts follow + **********************************************************/ + +/********************************************************** + * IDirectDrawGammaControl::QueryInterface + * + * QueryInterface, thunks to IDirectDrawSurface + * + * Params: + * riid: Interface id queried for + * obj: Returns the interface pointer + * + * Returns: + * S_OK or E_NOINTERFACE: See IDirectDrawSurface7::QueryInterface + * + **********************************************************/ +static HRESULT WINAPI +IDirectDrawGammaControlImpl_QueryInterface(IDirectDrawGammaControl *iface, REFIID riid, + void **obj) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawGammaControl, iface); + TRACE_(ddraw_thunk)("(%p)->(%s,%p): Thunking to IDirectDrawSurface7\n", This, debugstr_guid(riid), obj); + + return IDirectDrawSurface7_QueryInterface(ICOM_INTERFACE(This, IDirectDrawSurface7), + riid, + obj); +} + +/********************************************************** + * IDirectDrawGammaControl::AddRef + * + * Addref, thunks to IDirectDrawSurface + * + * Returns: + * The new refcount + * + **********************************************************/ +static ULONG WINAPI +IDirectDrawGammaControlImpl_AddRef(IDirectDrawGammaControl *iface) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawGammaControl, iface); + TRACE_(ddraw_thunk)("(%p)->() Thunking to IDirectDrawSurface7\n", This); + + return IDirectDrawSurface7_AddRef(ICOM_INTERFACE(This, IDirectDrawSurface7)); +} + +/********************************************************** + * IDirectDrawGammaControl::Release + * + * Release, thunks to IDirectDrawSurface + * + * Returns: + * The new refcount + * + **********************************************************/ +static ULONG WINAPI +IDirectDrawGammaControlImpl_Release(IDirectDrawGammaControl *iface) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawGammaControl, iface); + TRACE_(ddraw_thunk)("(%p)->() Thunking to IDirectDrawSurface7\n", This); + + return IDirectDrawSurface7_Release(ICOM_INTERFACE(This, IDirectDrawSurface7)); +} + +/********************************************************** + * IDirectDrawGammaControl + **********************************************************/ + +/********************************************************** + * IDirectDrawGammaControl::GetGammaRamp + * + * Returns the current gamma ramp for a surface + * + * Params: + * Flags: Ignored + * GammaRamp: Address to write the ramp to + * + * Returns: + * DD_OK on success + * DDERR_INVALIDPARAMS if GammaRamp is NULL + * + **********************************************************/ +static HRESULT WINAPI +IDirectDrawGammaControlImpl_GetGammaRamp(IDirectDrawGammaControl *iface, + DWORD Flags, + DDGAMMARAMP *GammaRamp) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawGammaControl, iface); + TRACE("(%p)->(%08lx,%p)\n", This,Flags,GammaRamp); + + /* This looks sane */ + if(!GammaRamp) + { + ERR("(%p) GammaRamp is NULL, returning DDERR_INVALIDPARAMS\n", This); + return DDERR_INVALIDPARAMS; + } + + if(This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) + { + /* This returns a void */ + IWineD3DDevice_GetGammaRamp(This->ddraw->wineD3DDevice, + 0 /* Swapchain */, + (WINED3DGAMMARAMP *) GammaRamp); + } + else + { + ERR("(%p) Unimplemented for non-primary surfaces\n", This); + } + + return DD_OK; +} + +/********************************************************** + * IDirectDrawGammaControl::SetGammaRamp + * + * Sets the red, green and blue gamma ramps for + * + * Params: + * Flags: Can be DDSGR_CALIBRATE to request calibration + * GammaRamp: Structure containing the new gamma ramp + * + * Returns: + * DD_OK on success + * DDERR_INVALIDPARAMS if GammaRamp is NULL + * + **********************************************************/ +static HRESULT WINAPI +IDirectDrawGammaControlImpl_SetGammaRamp(IDirectDrawGammaControl *iface, + DWORD Flags, + DDGAMMARAMP *GammaRamp) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawGammaControl, iface); + TRACE("(%p)->(%08lx,%p)\n", This,Flags,GammaRamp); + + /* This looks sane */ + if(!GammaRamp) + { + ERR("(%p) GammaRamp is NULL, returning DDERR_INVALIDPARAMS\n", This); + return DDERR_INVALIDPARAMS; + } + + if(This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) + { + /* This returns a void */ + IWineD3DDevice_SetGammaRamp(This->ddraw->wineD3DDevice, + 0 /* Swapchain */, + Flags, + (WINED3DGAMMARAMP *) GammaRamp); + } + else + { + ERR("(%p) Unimplemented for non-primary surfaces\n", This); + } + + return DD_OK; +} + +const IDirectDrawGammaControlVtbl IDirectDrawGammaControl_Vtbl = +{ + IDirectDrawGammaControlImpl_QueryInterface, + IDirectDrawGammaControlImpl_AddRef, + IDirectDrawGammaControlImpl_Release, + IDirectDrawGammaControlImpl_GetGammaRamp, + IDirectDrawGammaControlImpl_SetGammaRamp +}; diff --git a/dlls/ddraw/gl_api.h b/dlls/ddraw/gl_api.h deleted file mode 100644 index 05735e452d..0000000000 --- a/dlls/ddraw/gl_api.h +++ /dev/null @@ -1,125 +0,0 @@ -/* GL API list - * Copyright (c) 2003 Lionel Ulmer / Mike McCormack - * - * This file contains all structures that are not exported - * through d3d.h and all common macros. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -/* Note : this file is NOT protected against double-inclusion for pretty good - reasons :-) */ - -#ifndef GL_API_FUNCTION -#error "This file should be included with GL_API_FUNCTION defined !" -#endif - -GL_API_FUNCTION(glAlphaFunc) -GL_API_FUNCTION(glBegin) -GL_API_FUNCTION(glBindTexture) -GL_API_FUNCTION(glBlendFunc) -GL_API_FUNCTION(glClear) -GL_API_FUNCTION(glClearColor) -GL_API_FUNCTION(glClearDepth) -GL_API_FUNCTION(glClearStencil) -GL_API_FUNCTION(glClipPlane) -GL_API_FUNCTION(glColor3f) -GL_API_FUNCTION(glColor3ub) -GL_API_FUNCTION(glColor4ub) -GL_API_FUNCTION(glColorMask) -GL_API_FUNCTION(glColorMaterial) -GL_API_FUNCTION(glColorPointer) -GL_API_FUNCTION(glCopyPixels) -GL_API_FUNCTION(glCopyTexSubImage2D) -GL_API_FUNCTION(glCullFace) -GL_API_FUNCTION(glDeleteTextures) -GL_API_FUNCTION(glDepthFunc) -GL_API_FUNCTION(glDepthMask) -GL_API_FUNCTION(glDepthRange) -GL_API_FUNCTION(glDisable) -GL_API_FUNCTION(glDisableClientState) -GL_API_FUNCTION(glDrawArrays) -GL_API_FUNCTION(glDrawBuffer) -GL_API_FUNCTION(glDrawElements) -GL_API_FUNCTION(glDrawPixels) -GL_API_FUNCTION(glEnable) -GL_API_FUNCTION(glEnableClientState) -GL_API_FUNCTION(glEnd) -GL_API_FUNCTION(glFlush) -GL_API_FUNCTION(glFogf) -GL_API_FUNCTION(glFogfv) -GL_API_FUNCTION(glFogi) -GL_API_FUNCTION(glFrontFace) -GL_API_FUNCTION(glGenTextures) -GL_API_FUNCTION(glGetBooleanv) -GL_API_FUNCTION(glGetError) -GL_API_FUNCTION(glGetFloatv) -GL_API_FUNCTION(glGetIntegerv) -GL_API_FUNCTION(glGetString) -GL_API_FUNCTION(glGetTexEnviv) -GL_API_FUNCTION(glGetTexParameteriv) -GL_API_FUNCTION(glHint) -GL_API_FUNCTION(glLightModelfv) -GL_API_FUNCTION(glLightModeli) -GL_API_FUNCTION(glLightfv) -GL_API_FUNCTION(glLoadIdentity) -GL_API_FUNCTION(glLoadMatrixf) -GL_API_FUNCTION(glMaterialf) -GL_API_FUNCTION(glMaterialfv) -GL_API_FUNCTION(glMatrixMode) -GL_API_FUNCTION(glMultMatrixf) -GL_API_FUNCTION(glNormal3f) -GL_API_FUNCTION(glNormal3fv) -GL_API_FUNCTION(glNormalPointer) -GL_API_FUNCTION(glOrtho) -GL_API_FUNCTION(glPixelStorei) -GL_API_FUNCTION(glPolygonMode) -GL_API_FUNCTION(glPolygonOffset) -GL_API_FUNCTION(glPopMatrix) -GL_API_FUNCTION(glPushMatrix) -GL_API_FUNCTION(glRasterPos2i) -GL_API_FUNCTION(glRasterPos3d) -GL_API_FUNCTION(glReadBuffer) -GL_API_FUNCTION(glReadPixels) -GL_API_FUNCTION(glScissor) -GL_API_FUNCTION(glShadeModel) -GL_API_FUNCTION(glStencilFunc) -GL_API_FUNCTION(glStencilMask) -GL_API_FUNCTION(glStencilOp) -GL_API_FUNCTION(glTexCoord1fv) -GL_API_FUNCTION(glTexCoord2f) -GL_API_FUNCTION(glTexCoord2fv) -GL_API_FUNCTION(glTexCoord3fv) -GL_API_FUNCTION(glTexCoord4fv) -GL_API_FUNCTION(glTexCoordPointer) -GL_API_FUNCTION(glTexEnvf) -GL_API_FUNCTION(glTexEnvfv) -GL_API_FUNCTION(glTexEnvi) -GL_API_FUNCTION(glTexImage2D) -GL_API_FUNCTION(glTexParameteri) -GL_API_FUNCTION(glTexParameterfv) -GL_API_FUNCTION(glTexSubImage2D) -GL_API_FUNCTION(glTranslatef) -GL_API_FUNCTION(glVertex3d) -GL_API_FUNCTION(glVertex3f) -GL_API_FUNCTION(glVertex3fv) -GL_API_FUNCTION(glVertex4f) -GL_API_FUNCTION(glVertexPointer) -GL_API_FUNCTION(glViewport) -GL_API_FUNCTION(glXCreateContext) -GL_API_FUNCTION(glXDestroyContext) -GL_API_FUNCTION(glXMakeCurrent) -GL_API_FUNCTION(glXQueryExtensionsString) -GL_API_FUNCTION(glXSwapBuffers) diff --git a/dlls/ddraw/gl_private.h b/dlls/ddraw/gl_private.h deleted file mode 100644 index 7b9daca9e6..0000000000 --- a/dlls/ddraw/gl_private.h +++ /dev/null @@ -1,174 +0,0 @@ -/* GL 'hack' private include file - * Copyright (c) 2003 Lionel Ulmer / Mike McCormack - * - * This file contains all structures that are not exported - * through d3d.h and all common macros. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#ifndef __GRAPHICS_WINE_GL_PRIVATE_H -#define __GRAPHICS_WINE_GL_PRIVATE_H - -#ifdef HAVE_OPENGL - -#undef APIENTRY -#undef CALLBACK -#undef WINAPI - -#define XMD_H /* This is to prevent the Xmd.h inclusion bug :-/ */ -#include -#include -#ifdef HAVE_GL_GLEXT_H -# include -#endif -#undef XMD_H - -#undef APIENTRY -#undef CALLBACK -#undef WINAPI - -/* Redefines the constants */ -#define CALLBACK __stdcall -#define WINAPI __stdcall -#define APIENTRY WINAPI - -#define GL_API_FUNCTION(f) extern typeof(f) * p##f; -#include "gl_api.h" -#undef GL_API_FUNCTION - -/* This is also where I store our private extension defines... - I know that Raphael won't like it, but well, I prefer doing that than battling 10 different headers :-) - - Note: this is perfectly 'legal' as the three variants of the enum have exactly the same value -*/ -#define GL_MIRRORED_REPEAT_WINE 0x8370 -#define GL_TEXTURE_FILTER_CONTROL_WINE 0x8500 -#define GL_TEXTURE_LOD_BIAS_WINE 0x8501 -#define GL_TEXTURE0_WINE 0x84C0 -#define GL_TEXTURE1_WINE 0x84C1 -#define GL_TEXTURE2_WINE 0x84C2 -#define GL_TEXTURE3_WINE 0x84C3 -#define GL_TEXTURE4_WINE 0x84C4 -#define GL_TEXTURE5_WINE 0x84C5 -#define GL_TEXTURE6_WINE 0x84C6 -#define GL_TEXTURE7_WINE 0x84C7 -#define GL_MAX_TEXTURE_UNITS_WINE 0x84E2 - -#ifndef GLPRIVATE_NO_REDEFINE - -#define glAlphaFunc pglAlphaFunc -#define glBegin pglBegin -#define glBindTexture pglBindTexture -#define glBlendFunc pglBlendFunc -#define glClear pglClear -#define glClearColor pglClearColor -#define glClearDepth pglClearDepth -#define glClearStencil pglClearStencil -#define glClipPlane pglClipPlane -#define glColor3f pglColor3f -#define glColor3ub pglColor3ub -#define glColor4ub pglColor4ub -#define glColorMask pglColorMask -#define glColorPointer pglColorPointer -#define glCopyPixels pglCopyPixels -#define glCopyTexSubImage2D pglCopyTexSubImage2D -#define glColorMaterial pglColorMaterial -#define glCullFace pglCullFace -#define glDeleteTextures pglDeleteTextures -#define glDepthFunc pglDepthFunc -#define glDepthMask pglDepthMask -#define glDepthRange pglDepthRange -#define glDisable pglDisable -#define glDisableClientState pglDisableClientState -#define glDrawArrays pglDrawArrays -#define glDrawBuffer pglDrawBuffer -#define glDrawElements pglDrawElements -#define glDrawPixels pglDrawPixels -#define glEnable pglEnable -#define glEnableClientState pglEnableClientState -#define glEnd pglEnd -#define glFlush pglFlush -#define glFogf pglFogf -#define glFogfv pglFogfv -#define glFogi pglFogi -#define glFrontFace pglFrontFace -#define glGenTextures pglGenTextures -#define glGetBooleanv pglGetBooleanv -#define glGetError pglGetError -#define glGetFloatv pglGetFloatv -#define glGetIntegerv pglGetIntegerv -#define glGetString pglGetString -#define glGetTexEnviv pglGetTexEnviv -#define glGetTexParameteriv pglGetTexParameteriv -#define glHint pglHint -#define glLightModelfv pglLightModelfv -#define glLightModeli pglLightModeli -#define glLightfv pglLightfv -#define glLoadIdentity pglLoadIdentity -#define glLoadMatrixf pglLoadMatrixf -#define glMaterialf pglMaterialf -#define glMaterialfv pglMaterialfv -#define glMatrixMode pglMatrixMode -#define glMultMatrixf pglMultMatrixf -#define glNormal3f pglNormal3f -#define glNormal3fv pglNormal3fv -#define glNormalPointer pglNormalPointer -#define glOrtho pglOrtho -#define glPixelStorei pglPixelStorei -#define glPolygonMode pglPolygonMode -#define glPolygonOffset pglPolygonOffset -#define glPopMatrix pglPopMatrix -#define glPushMatrix pglPushMatrix -#define glRasterPos2i pglRasterPos2i -#define glRasterPos3d pglRasterPos3d -#define glReadBuffer pglReadBuffer -#define glReadPixels pglReadPixels -#define glScissor pglScissor -#define glShadeModel pglShadeModel -#define glStencilFunc pglStencilFunc -#define glStencilMask pglStencilMask -#define glStencilOp pglStencilOp -#define glTexCoord1fv pglTexCoord1fv -#define glTexCoord2f pglTexCoord2f -#define glTexCoord2fv pglTexCoord2fv -#define glTexCoord3fv pglTexCoord3fv -#define glTexCoord4fv pglTexCoord4fv -#define glTexCoordPointer pglTexCoordPointer -#define glTexEnvf pglTexEnvf -#define glTexEnvfv pglTexEnvfv -#define glTexEnvi pglTexEnvi -#define glTexImage2D pglTexImage2D -#define glTexParameteri pglTexParameteri -#define glTexParameterfv pglTexParameterfv -#define glTexSubImage2D pglTexSubImage2D -#define glTranslatef pglTranslatef -#define glVertex3d pglVertex3d -#define glVertex3f pglVertex3f -#define glVertex3fv pglVertex3fv -#define glVertex4f pglVertex4f -#define glVertexPointer pglVertexPointer -#define glViewport pglViewport -#define glXCreateContext pglXCreateContext -#define glXDestroyContext pglXDestroyContext -#define glXMakeCurrent pglXMakeCurrent -#define glXQueryExtensionsString pglXQueryExtensionsString -#define glXSwapBuffers pglXSwapBuffers - -#endif /* GLPRIVATE_NO_REDEFINE */ - -#endif /* HAVE_OPENGL */ - -#endif /* __GRAPHICS_WINE_GL_PRIVATE_H */ diff --git a/dlls/ddraw/light.c b/dlls/ddraw/light.c index 82484e6e36..d5b7dd689c 100644 --- a/dlls/ddraw/light.c +++ b/dlls/ddraw/light.c @@ -1,5 +1,6 @@ /* Direct3D Light * Copyright (c) 1998 / 2002 Lionel ULMER + * Copyright (c) 2006 Stefan DÖSINGER * * This file contains the implementation of Direct3DLight. * @@ -19,55 +20,96 @@ */ #include "config.h" +#include "wine/port.h" +#include "wine/debug.h" +#include #include +#include +#include -#define NONAMELESSUNION -#define NONAMELESSSTRUCT +#define COBJMACROS #include "windef.h" #include "winbase.h" +#include "winnls.h" #include "winerror.h" -#include "objbase.h" #include "wingdi.h" +#include "wine/exception.h" +#include "excpt.h" + #include "ddraw.h" #include "d3d.h" -#include "wine/debug.h" -#include "d3d_private.h" -#include "opengl_private.h" +#include "ddraw_private.h" -WINE_DEFAULT_DEBUG_CHANNEL(ddraw); +WINE_DEFAULT_DEBUG_CHANNEL(d3d7); -/* First, the 'main' interface... */ -HRESULT WINAPI -Main_IDirect3DLightImpl_1_QueryInterface(LPDIRECT3DLIGHT iface, - REFIID riid, - LPVOID* obp) +/***************************************************************************** + * IUnknown Methods. + *****************************************************************************/ + +/***************************************************************************** + * IDirect3DLight::QueryInterface + * + * Queries the object for different interfaces. Unimplemented for this + * object at the moment + * + * Params: + * riid: Interface id asked for + * obj: Address to return the resulting pointer at. + * + * Returns: + * E_NOINTERFACE, because it's a stub + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DLightImpl_QueryInterface(IDirect3DLight *iface, + REFIID riid, + void **obp) { ICOM_THIS_FROM(IDirect3DLightImpl, IDirect3DLight, iface); - FIXME("(%p/%p)->(%s,%p): stub!\n", This, iface, debugstr_guid(riid), obp); - return DD_OK; + FIXME("(%p)->(%s,%p): stub!\n", This, debugstr_guid(riid), obp); + *obp = NULL; + return E_NOINTERFACE; } -ULONG WINAPI -Main_IDirect3DLightImpl_1_AddRef(LPDIRECT3DLIGHT iface) +/***************************************************************************** + * IDirect3DLight::AddRef + * + * Increases the refcount by 1 + * + * Returns: + * The new refcount + * + *****************************************************************************/ +static ULONG WINAPI +IDirect3DLightImpl_AddRef(IDirect3DLight *iface) { ICOM_THIS_FROM(IDirect3DLightImpl, IDirect3DLight, iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p/%p)->() incrementing from %lu.\n", This, iface, ref - 1); + TRACE("(%p)->() incrementing from %lu.\n", This, ref - 1); return ref; } -ULONG WINAPI -Main_IDirect3DLightImpl_1_Release(LPDIRECT3DLIGHT iface) +/***************************************************************************** + * IDirect3DLight::Release + * + * Reduces the refcount by one. If the refcount falls to 0, the object + * is destroyed + * + * Returns: + * The new refcount + * + *****************************************************************************/ +static ULONG WINAPI +IDirect3DLightImpl_Release(IDirect3DLight *iface) { ICOM_THIS_FROM(IDirect3DLightImpl, IDirect3DLight, iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p/%p)->() decrementing from %lu.\n", This, iface, ref + 1); + TRACE("(%p)->() decrementing from %lu.\n", This, ref + 1); if (!ref) { HeapFree(GetProcessHeap(), 0, This); @@ -76,16 +118,46 @@ Main_IDirect3DLightImpl_1_Release(LPDIRECT3DLIGHT iface) return ref; } -HRESULT WINAPI -Main_IDirect3DLightImpl_1_Initialize(LPDIRECT3DLIGHT iface, - LPDIRECT3D lpDirect3D) +/***************************************************************************** + * IDirect3DLight Methods. + *****************************************************************************/ + +/***************************************************************************** + * IDirect3DLight::Initialize + * + * Initializes the interface. This implementation is a no-op, because + * initialization takes place at creation time + * + * Params: + * Direct3D: Pointer to an IDirect3D interface. + * + * Returns: + * D3D_OK + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DLightImpl_Initialize(IDirect3DLight *iface, + IDirect3D *lpDirect3D) { ICOM_THIS_FROM(IDirect3DLightImpl, IDirect3DLight, iface); - TRACE("(%p/%p)->(%p) no-op...\n", This, iface, lpDirect3D); - return DD_OK; + IDirectDrawImpl *d3d = ICOM_OBJECT(IDirectDrawImpl, IDirect3D, lpDirect3D); + TRACE("(%p)->(%p) no-op...\n", This, d3d); + return D3D_OK; } -/*** IDirect3DLight methods ***/ +/***************************************************************************** + * IDirect3DLight::SetLight + * + * Assigns a lighting value to this object + * + * Params: + * Light: Lighting parametes to set + * + * Returns: + * D3D_OK on success + * DDERR_INVALIDPARAMS if Light is NULL + * + *****************************************************************************/ static void dump_light(LPD3DLIGHT2 light) { DPRINTF(" - dwSize : %ld\n", light->dwSize); @@ -95,14 +167,14 @@ static const float zero_value[] = { 0.0, 0.0, 0.0, 0.0 }; -HRESULT WINAPI -Main_IDirect3DLightImpl_1_SetLight(LPDIRECT3DLIGHT iface, - LPD3DLIGHT lpLight) +static HRESULT WINAPI +IDirect3DLightImpl_SetLight(IDirect3DLight *iface, + D3DLIGHT *lpLight) { ICOM_THIS_FROM(IDirect3DLightImpl, IDirect3DLight, iface); LPD3DLIGHT7 light7 = &(This->light7); - TRACE("(%p/%p)->(%p)\n", This, iface, lpLight); - if (TRACE_ON(ddraw)) { + TRACE("(%p)->(%p)\n", This, lpLight); + if (TRACE_ON(d3d7)) { TRACE(" Light definition :\n"); dump_light((LPD3DLIGHT2) lpLight); } @@ -135,16 +207,28 @@ Main_IDirect3DLightImpl_1_SetLight(LPDIRECT3DLIGHT iface, if ((This->light.dwFlags & D3DLIGHT_ACTIVE) != 0) { This->update(This); } - return DD_OK; + return D3D_OK; } -HRESULT WINAPI -Main_IDirect3DLightImpl_1_GetLight(LPDIRECT3DLIGHT iface, - LPD3DLIGHT lpLight) +/***************************************************************************** + * IDirect3DLight::GetLight + * + * Returns the parameters currently assigned to the IDirect3DLight object + * + * Params: + * Light: Pointer to an D3DLIGHT structure to store the parameters + * + * Returns: + * D3D_OK on success + * DDERR_INVALIDPARAMS if Light is NULL + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DLightImpl_GetLight(IDirect3DLight *iface, + D3DLIGHT *lpLight) { ICOM_THIS_FROM(IDirect3DLightImpl, IDirect3DLight, iface); TRACE("(%p/%p)->(%p)\n", This, iface, lpLight); - if (TRACE_ON(ddraw)) { + if (TRACE_ON(d3d7)) { TRACE(" Returning light definition :\n"); dump_light(&This->light); } @@ -152,11 +236,13 @@ Main_IDirect3DLightImpl_1_GetLight(LPDIRECT3DLIGHT iface, return DD_OK; } -/******************************************************************************* - * Light static functions - */ - -static void update(IDirect3DLightImpl* This) +/***************************************************************************** + * light_update + * + * Updates the Direct3DDevice7 lighting parameters + * + *****************************************************************************/ +void light_update(IDirect3DLightImpl* This) { IDirect3DDeviceImpl* device; @@ -169,7 +255,13 @@ static void update(IDirect3DLightImpl* This) IDirect3DDevice7_SetLight(ICOM_INTERFACE(device,IDirect3DDevice7), This->dwLightIndex, &(This->light7)); } -static void activate(IDirect3DLightImpl* This) +/***************************************************************************** + * light_activate + * + * Uses the Direct3DDevice7::LightEnable method to active the light + * + *****************************************************************************/ +void light_activate(IDirect3DLightImpl* This) { IDirect3DDeviceImpl* device; @@ -179,7 +271,7 @@ static void activate(IDirect3DLightImpl* This) return; device = This->active_viewport->active_device; - update(This); + light_update(This); /* If was not active, activate it */ if ((This->light.dwFlags & D3DLIGHT_ACTIVE) == 0) { IDirect3DDevice7_LightEnable(ICOM_INTERFACE(device,IDirect3DDevice7), This->dwLightIndex, TRUE); @@ -187,7 +279,14 @@ static void activate(IDirect3DLightImpl* This) } } -static void desactivate(IDirect3DLightImpl* This) +/***************************************************************************** + * + * light_desactivate + * + * Uses the Direct3DDevice7::LightEnable method to deactivate the light + * + *****************************************************************************/ +void light_desactivate(IDirect3DLightImpl* This) { IDirect3DDeviceImpl* device; @@ -204,64 +303,14 @@ static void desactivate(IDirect3DLightImpl* This) } } -ULONG WINAPI -GL_IDirect3DLightImpl_1_Release(LPDIRECT3DLIGHT iface) +const IDirect3DLightVtbl IDirect3DLight_Vtbl = { - ICOM_THIS_FROM(IDirect3DLightImpl, IDirect3DLight, iface); - ULONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p/%p)->() decrementing from %lu.\n", This, iface, ref + 1); - - if (!ref) { - HeapFree(GetProcessHeap(), 0, This); - return 0; - } - return ref; -} - -#if !defined(__STRICT_ANSI__) && defined(__GNUC__) -# define XCAST(fun) (typeof(VTABLE_IDirect3DLight.fun)) -#else -# define XCAST(fun) (void*) -#endif - -static const IDirect3DLightVtbl VTABLE_IDirect3DLight = -{ - XCAST(QueryInterface) Main_IDirect3DLightImpl_1_QueryInterface, - XCAST(AddRef) Main_IDirect3DLightImpl_1_AddRef, - XCAST(Release) GL_IDirect3DLightImpl_1_Release, - XCAST(Initialize) Main_IDirect3DLightImpl_1_Initialize, - XCAST(SetLight) Main_IDirect3DLightImpl_1_SetLight, - XCAST(GetLight) Main_IDirect3DLightImpl_1_GetLight, + /*** IUnknown Methods ***/ + IDirect3DLightImpl_QueryInterface, + IDirect3DLightImpl_AddRef, + IDirect3DLightImpl_Release, + /*** IDirect3DLight Methods ***/ + IDirect3DLightImpl_Initialize, + IDirect3DLightImpl_SetLight, + IDirect3DLightImpl_GetLight }; - -#if !defined(__STRICT_ANSI__) && defined(__GNUC__) -#undef XCAST -#endif - - - - -HRESULT d3dlight_create(IDirect3DLightImpl **obj, IDirectDrawImpl *d3d) -{ - IDirect3DLightImpl *object; - - object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DLightImpl)); - if (object == NULL) return DDERR_OUTOFMEMORY; - - object->ref = 1; - object->d3d = d3d; - object->next = NULL; - object->activate = activate; - object->desactivate = desactivate; - object->update = update; - object->active_viewport = NULL; - - ICOM_INIT_INTERFACE(object, IDirect3DLight, VTABLE_IDirect3DLight); - - *obj = object; - - TRACE(" creating implementation at %p.\n", *obj); - - return D3D_OK; -} diff --git a/dlls/ddraw/main.c b/dlls/ddraw/main.c index 96b7568f7a..84f8823823 100644 --- a/dlls/ddraw/main.c +++ b/dlls/ddraw/main.c @@ -1,8 +1,9 @@ -/* DirectDraw Base Functions +/* DirectDraw Base Functions * * Copyright 1997-1999 Marcus Meissner - * Copyright 1998 Lionel Ulmer (most of Direct3D stuff) + * Copyright 1998 Lionel Ulmer * Copyright 2000-2001 TransGaming Technologies Inc. + * Copyright 2006 Stefan Dösinger * * This file contains the (internal) driver registration functions, * driver enumeration APIs and DirectDraw creation functions. @@ -22,10 +23,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#define GLPRIVATE_NO_REDEFINE - #include "config.h" #include "wine/port.h" +#include "wine/debug.h" #include #include @@ -41,518 +41,603 @@ #include "wingdi.h" #include "wine/exception.h" #include "excpt.h" +#include "winreg.h" #include "ddraw.h" #include "d3d.h" -/* This for all the enumeration and creation of D3D-related objects */ #include "ddraw_private.h" -#include "wine/debug.h" -#include "wine/library.h" - -#include "gl_private.h" - -#undef GLPRIVATE_NO_REDEFINE - -#define MAX_DDRAW_DRIVERS 3 -static const ddraw_driver* DDRAW_drivers[MAX_DDRAW_DRIVERS]; -static int DDRAW_num_drivers; /* = 0 */ -static int DDRAW_default_driver; - -void (*wine_tsx11_lock_ptr)(void) = NULL; -void (*wine_tsx11_unlock_ptr)(void) = NULL; WINE_DEFAULT_DEBUG_CHANNEL(ddraw); -/**********************************************************************/ +/* The driver's guid */ +GUID guid = {0x40c1b248,0x9d7d,0x4a29,{0xd7,0xb7,0x4c,0xd8,0x10,0x9f,0x3d,0x5d}}; -typedef struct { - LPVOID lpCallback; - LPVOID lpContext; -} DirectDrawEnumerateProcData; +/* The configured default surface */ +WINED3DSURFTYPE DefaultSurfaceType = SURFACE_UNKNOWN; -BOOL opengl_initialized = 0; - -#ifdef HAVE_OPENGL - -#include "opengl_private.h" - -static void *gl_handle = NULL; - -#define GL_API_FUNCTION(f) typeof(f) * p##f; -#include "gl_api.h" -#undef GL_API_FUNCTION - -#ifndef SONAME_LIBGL -#define SONAME_LIBGL "libGL.so" -#endif - -static BOOL DDRAW_bind_to_opengl( void ) -{ - const char *glname = SONAME_LIBGL; - - gl_handle = wine_dlopen(glname, RTLD_NOW, NULL, 0); - if (!gl_handle) { - WARN("Wine cannot find the OpenGL graphics library (%s).\n",glname); - return FALSE; - } - -#define GL_API_FUNCTION(f) \ - if((p##f = wine_dlsym(gl_handle, #f, NULL, 0)) == NULL) \ - { \ - WARN("Can't find symbol %s\n", #f); \ - goto sym_not_found; \ - } -#include "gl_api.h" -#undef GL_API_FUNCTION - - /* And now calls the function to initialize the various fields for the rendering devices */ - return d3ddevice_init_at_startup(gl_handle); - -sym_not_found: - WARN("Wine cannot find certain functions that it needs inside the OpenGL\n" - "graphics library. To enable Wine to use OpenGL please upgrade\n" - "your OpenGL libraries\n"); - wine_dlclose(gl_handle, NULL, 0); - gl_handle = NULL; - return FALSE; -} - -#endif /* HAVE_OPENGL */ - -BOOL s3tc_initialized = 0; - -static void *s3tc_handle = NULL; - -FUNC_FETCH_2D_TEXEL_RGBA_DXT1 fetch_2d_texel_rgba_dxt1; -FUNC_FETCH_2D_TEXEL_RGBA_DXT3 fetch_2d_texel_rgba_dxt3; -FUNC_FETCH_2D_TEXEL_RGBA_DXT5 fetch_2d_texel_rgba_dxt5; - -#ifndef SONAME_LIBTXC_DXTN -#define SONAME_LIBTXC_DXTN "libtxc_dxtn.so" -#endif - -static BOOL DDRAW_bind_to_s3tc( void ) -{ - const char * const s3tcname = SONAME_LIBTXC_DXTN; - - s3tc_handle = wine_dlopen(s3tcname, RTLD_NOW, NULL, 0); - if (!s3tc_handle) { - TRACE("No S3TC software decompression library seems to be present (%s).\n",s3tcname); - return FALSE; - } - TRACE("Found S3TC software decompression library (%s).\n",s3tcname); - -#define API_FUNCTION(f) \ - if((f = wine_dlsym(s3tc_handle, #f, NULL, 0)) == NULL) \ - { \ - WARN("Can't find symbol %s\n", #f); \ - goto sym_not_found; \ - } - API_FUNCTION(fetch_2d_texel_rgba_dxt1); - API_FUNCTION(fetch_2d_texel_rgba_dxt3); - API_FUNCTION(fetch_2d_texel_rgba_dxt5); -#undef API_FUNCTION - - return TRUE; - -sym_not_found: - WARN("Wine cannot find functions that are necessary for S3TC software decompression\n"); - wine_dlclose(s3tc_handle, NULL, 0); - s3tc_handle = NULL; - return FALSE; -} - -/******************************************************************************* - * DirectDrawEnumerateExA (DDRAW.@) +/*********************************************************************** * - * Enumerates all DirectDraw devices installed on the system. + * Helper function for DirectDrawCreate and friends + * Creates a new DDraw interface with the given REFIID * - * PARAMS - * lpCallback [I] DDEnumCallbackEx function to be called with a description of - * each enumerated HAL. - * lpContext [I] application-defined value to be passed to the callback. - * dwFlags [I] Specifies the enumeration scope. see msdn. + * Interfaces that can be created: + * IDirectDraw, IDirectDraw2, IDirectDraw4, IDirectDraw7 + * IDirect3D, IDirect3D2, IDirect3D3, IDirect3D7. (Does Windows return + * IDirect3D interfaces?) * - * RETURNS - * Success: DD_OK. - * Failure: DDERR_INVALIDPARAMS - */ -HRESULT WINAPI DirectDrawEnumerateExA( - LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags) + * Arguments: + * guid: ID of the requested driver, NULL for the default driver. + * The GUID can be queried with DirectDrawEnumerate(Ex)A/W + * DD: Used to return the pointer to the created object + * UnkOuter: For aggregation, which is unsupported. Must be NULL + * iid: requested version ID. + * + * Returns: + * DD_OK if the Interface was created sucessfully + * CLASS_E_NOAGGREGATION if UnkOuter is not NULL + * E_OUTOFMEMORY if some allocation failed + * + ***********************************************************************/ +static HRESULT +DDRAW_Create(GUID *guid, + void **DD, + IUnknown *UnkOuter, + REFIID iid) { - int i; - BOOL stop = FALSE; - TRACE("(%p,%p, %08lx)\n", lpCallback, lpContext, dwFlags); + IDirectDrawImpl *This = NULL; + HRESULT hr; + IWineD3D *wineD3D = NULL; + IWineD3DDevice *wineD3DDevice = NULL; + HDC hDC; + WINED3DDEVTYPE devicetype; - if (TRACE_ON(ddraw)) { - TRACE(" Flags : "); - if (dwFlags & DDENUM_ATTACHEDSECONDARYDEVICES) - TRACE("DDENUM_ATTACHEDSECONDARYDEVICES "); - if (dwFlags & DDENUM_DETACHEDSECONDARYDEVICES) - TRACE("DDENUM_DETACHEDSECONDARYDEVICES "); - if (dwFlags & DDENUM_NONDISPLAYDEVICES) - TRACE("DDENUM_NONDISPLAYDEVICES "); - TRACE("\n"); - } + TRACE("(%s,%p,%p)\n", debugstr_guid(guid), DD, UnkOuter); - for (i=0; iinfo->szDriver, - DDRAW_drivers[i]->info->szDescription); - - /* We have to pass NULL from the primary display device. - * RoadRage chapter 6's enumeration routine expects it. */ - __TRY - { - if (!lpCallback((DDRAW_default_driver == i) ? NULL - :(LPGUID)&DDRAW_drivers[i]->info->guidDeviceIdentifier, - (LPSTR)DDRAW_drivers[i]->info->szDescription, - (LPSTR)DDRAW_drivers[i]->info->szDriver, - lpContext, 0)) - stop = TRUE; - } - __EXCEPT_PAGE_FAULT - { - return E_INVALIDARG; - } - __ENDTRY - if (stop) return DD_OK; + /* Use the reference device id. This doesn't actually change anything, + * WineD3D always uses OpenGL for D3D rendering. One could make it request + * indirect rendering + */ + devicetype = WINED3DDEVTYPE_REF; + } + else if(guid == (GUID *) DDCREATE_HARDWAREONLY) + { + devicetype = WINED3DDEVTYPE_HAL; + } + else + { + devicetype = 0; } - /* Unsupported flags */ - if (dwFlags & DDENUM_NONDISPLAYDEVICES) { - FIXME("no non-display devices supported.\n"); - } - if (dwFlags & DDENUM_DETACHEDSECONDARYDEVICES) { - FIXME("no detached secondary devices supported.\n"); + /* DDraw doesn't support aggreation, according to msdn */ + if (UnkOuter != NULL) + return CLASS_E_NOAGGREGATION; + + /* DirectDraw creation comes here */ + This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectDrawImpl)); + if(!This) + { + ERR("Out of memory when creating DirectDraw\n"); + return E_OUTOFMEMORY; } + /* The interfaces: + * IDirectDraw and IDirect3D are the same object, + * QueryInterface is used to get other interfaces. + */ + ICOM_INIT_INTERFACE(This, IDirectDraw, IDirectDraw1_Vtbl); + ICOM_INIT_INTERFACE(This, IDirectDraw2, IDirectDraw2_Vtbl); + ICOM_INIT_INTERFACE(This, IDirectDraw4, IDirectDraw4_Vtbl); + ICOM_INIT_INTERFACE(This, IDirectDraw7, IDirectDraw7_Vtbl); + ICOM_INIT_INTERFACE(This, IDirect3D, IDirect3D1_Vtbl); + ICOM_INIT_INTERFACE(This, IDirect3D2, IDirect3D2_Vtbl); + ICOM_INIT_INTERFACE(This, IDirect3D3, IDirect3D3_Vtbl); + ICOM_INIT_INTERFACE(This, IDirect3D7, IDirect3D7_Vtbl); + This->ref = 1; + + /* See comments in IDirectDrawImpl_CreateNewSurface for a description + * of this member. + * Read from a registry key, should add a winecfg option later + */ + This->ImplType = DefaultSurfaceType; + + /* Get the current screen settings */ + hDC = CreateDCA("DISPLAY", NULL, NULL, NULL); + This->orig_bpp = GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES); + DeleteDC(hDC); + This->orig_width = GetSystemMetrics(SM_CXSCREEN); + This->orig_height = GetSystemMetrics(SM_CYSCREEN); + + /* Initialize WineD3D + * + * All Rendering (2D and 3D) is relayed to WineD3D, + * but DirectDraw specific management, like DDSURFACEDESC and DDPIXELFORMAT + * structure handling is handled in this lib. + */ + wineD3D = WineDirect3DCreate(0 /* SDKVersion */, 7 /* DXVersion */, (IUnknown *) This /* Parent */); + if(!wineD3D) + { + ERR("Failed to initialise WineD3D\n"); + hr = E_OUTOFMEMORY; + goto err_out; + } + This->wineD3D = wineD3D; + TRACE("WineD3D created at %p\n", wineD3D); + + /* Initialized member... + * + * It is set to false at creation time, and set to true in + * IDirectDraw7::Initialize. It's sole purpose is to return DD_OK on + * initialize only once + */ + This->initialized = FALSE; + + /* Initialize WineD3DDevice + * + * It is used for screen setup, surface and palette creation + * When a Direct3DDevice7 is created, the D3D capatiblities of WineD3D are + * initialized + */ + hr = IWineD3D_CreateDevice(wineD3D, + 0 /*D3D_ADAPTER_DEFAULT*/, + devicetype, + NULL, /* FocusWindow, don't know yet */ + 0, /* BehaviorFlags */ + &wineD3DDevice, + (IUnknown *) ICOM_INTERFACE(This, IDirectDraw7)); + if(FAILED(hr)) + { + ERR("Failed to create a wineD3DDevice, result = %lx\n", hr); + goto err_out; + } + This->wineD3DDevice = wineD3DDevice; + TRACE("wineD3DDevice created at %p\n", This->wineD3DDevice); + + /* Register the window class + * + * It is used to create a hidden window for D3D + * rendering, if the application didn't pass one. + * It can also be used for Creating a device window + * from SetCooperativeLevel + * + * The name: DDRAW_
. The classname is + * 32 bit long, so a 64 bit address will fit nicely + * (Will this be compiled for 64 bit anyway?) + * + */ + sprintf(This->classname, "DDRAW_%p", This); + + memset(&This->wnd_class, 0, sizeof(This->wnd_class)); + This->wnd_class.style = CS_HREDRAW | CS_VREDRAW; + This->wnd_class.lpfnWndProc = DefWindowProcA; + This->wnd_class.cbClsExtra = 0; + This->wnd_class.cbWndExtra = 0; + This->wnd_class.hInstance = GetModuleHandleA(0); + This->wnd_class.hIcon = 0; + This->wnd_class.hCursor = 0; + This->wnd_class.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH); + This->wnd_class.lpszMenuName = NULL; + This->wnd_class.lpszClassName = This->classname; + if(!RegisterClassA(&This->wnd_class)) + { + ERR("RegisterClassA failed!\n"); + goto err_out; + } + + /* Get the amount of video memory */ + This->total_vidmem = IWineD3DDevice_GetAvailableTextureMem(This->wineD3DDevice); + + /* Initialize the caps */ + This->caps.dwSize = sizeof(This->caps); +#define BLIT_CAPS (DDCAPS_BLT | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL \ + | DDCAPS_BLTSTRETCH | DDCAPS_CANBLTSYSMEM | DDCAPS_CANCLIP \ + | DDCAPS_CANCLIPSTRETCHED | DDCAPS_COLORKEY \ + | DDCAPS_COLORKEYHWASSIST | DDCAPS_OVERLAY | DDCAPS_OVERLAYSTRETCH |DDCAPS_ALIGNBOUNDARYSRC ) +#define CKEY_CAPS (DDCKEYCAPS_DESTBLT | DDCKEYCAPS_SRCBLT) +#define FX_CAPS (DDFXCAPS_BLTALPHA | DDFXCAPS_BLTMIRRORLEFTRIGHT \ + | DDFXCAPS_BLTMIRRORUPDOWN | DDFXCAPS_BLTROTATION90 \ + | DDFXCAPS_BLTSHRINKX | DDFXCAPS_BLTSHRINKXN \ + | DDFXCAPS_BLTSHRINKY | DDFXCAPS_BLTSHRINKXN \ + | DDFXCAPS_BLTSTRETCHX | DDFXCAPS_BLTSTRETCHXN \ + | DDFXCAPS_BLTSTRETCHY | DDFXCAPS_BLTSTRETCHYN) + This->caps.dwCaps |= DDCAPS_GDI | DDCAPS_PALETTE | BLIT_CAPS; + + This->caps.dwCaps2 |= DDCAPS2_CERTIFIED | DDCAPS2_NOPAGELOCKREQUIRED | + DDCAPS2_PRIMARYGAMMA | DDCAPS2_WIDESURFACES | + DDCAPS2_CANRENDERWINDOWED; + This->caps.dwCKeyCaps |= CKEY_CAPS; + This->caps.dwFXCaps |= FX_CAPS; + This->caps.dwPalCaps |= DDPCAPS_8BIT | DDPCAPS_PRIMARYSURFACE; + This->caps.dwVidMemTotal = This->total_vidmem; + This->caps.dwVidMemFree = This->total_vidmem; + This->caps.dwSVBCaps |= BLIT_CAPS; + This->caps.dwSVBCKeyCaps |= CKEY_CAPS; + This->caps.dwSVBFXCaps |= FX_CAPS; + This->caps.dwVSBCaps |= BLIT_CAPS; + This->caps.dwVSBCKeyCaps |= CKEY_CAPS; + This->caps.dwVSBFXCaps |= FX_CAPS; + This->caps.dwSSBCaps |= BLIT_CAPS; + This->caps.dwSSBCKeyCaps |= CKEY_CAPS; + This->caps.dwSSBFXCaps |= FX_CAPS; + This->caps.ddsCaps.dwCaps |= DDSCAPS_ALPHA | DDSCAPS_BACKBUFFER | + DDSCAPS_FLIP | DDSCAPS_FRONTBUFFER | + DDSCAPS_OFFSCREENPLAIN | DDSCAPS_PALETTE | + DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY | + DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE; + /* Hacks for D3D code */ + /* TODO: Check if WineD3D has 3D enabled + Need opengl surfaces or auto for 3D + */ + if(This->ImplType == 0 || This->ImplType == SURFACE_OPENGL) + { + This->caps.dwCaps |= DDCAPS_3D; + This->caps.ddsCaps.dwCaps |= DDSCAPS_3DDEVICE | DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_ZBUFFER; + } + This->caps.ddsOldCaps.dwCaps = This->caps.ddsCaps.dwCaps; + +#undef BLIT_CAPS +#undef CKEY_CAPS +#undef FX_CAPS + + /* Add the object to the ddraw cleanup list */ + This->next = ddraw_list; + ddraw_list = This; + + /* Call QueryInterface to get the pointer to the requested interface */ + hr = IDirectDraw7_QueryInterface( ICOM_INTERFACE(This, IDirectDraw7), iid, DD); + IDirectDraw7_Release( ICOM_INTERFACE(This, IDirectDraw7) ); + if(SUCCEEDED(hr)) return DD_OK; + +err_out: + /* Let's hope we never need this ;) */ + if(wineD3DDevice) IWineD3DDevice_Release(wineD3DDevice); + if(wineD3D) IWineD3D_Release(wineD3D); + if(This) HeapFree(GetProcessHeap(), 0, This); + return hr; +} + +/*********************************************************************** + * DirectDrawCreate (DDRAW.@) + * + * Creates legacy DirectDraw Interfaces. Can't create IDirectDraw7 + * interfaces in theory + * + * Arguments, return values: See DDRAW_Create + * + ***********************************************************************/ +HRESULT WINAPI +DirectDrawCreate(GUID *GUID, + IDirectDraw **DD, + IUnknown *UnkOuter) +{ + TRACE("(%s,%p,%p)\n", debugstr_guid(GUID), DD, UnkOuter); + + return DDRAW_Create(GUID, (void **) DD, UnkOuter, &IID_IDirectDraw); +} + +/*********************************************************************** + * DirectDrawCreateEx (DDRAW.@) + * + * Only creates new IDirectDraw7 interfaces, supposed to fail if legacy + * interfaces are requested. + * + * Arguments, return values: See DDRAW_Create + * + ***********************************************************************/ +HRESULT WINAPI +DirectDrawCreateEx(GUID *GUID, + void **DD, + REFIID iid, + IUnknown *UnkOuter) +{ + TRACE("(%s,%p,%s,%p)\n", debugstr_guid(GUID), DD, debugstr_guid(iid), UnkOuter); + + if (!IsEqualGUID(iid, &IID_IDirectDraw7)) + return DDERR_INVALIDPARAMS; + + return DDRAW_Create(GUID, DD, UnkOuter, iid); +} + +/*********************************************************************** + * DirectDrawEnumerateA (DDRAW.@) + * + * Enumerates legacy ddraw drivers, ascii version. We only have one + * driver, which relays to WineD3D. If we were sufficiently cool, + * we could offer various interfaces, which use a different default surface + * implementation, but I think it's better to offer this choice in + * winecfg, because some apps use the default driver, so we would need + * a winecfg option anyway, and there shouldn't be 2 ways to set one setting + * + * Arguments: + * Callback: Callback function from the app + * Context: Argument to the call back. + * + * Returns: + * DD_OK on success + * E_INVALIDARG if the Callback caused a page fault + * + * + ***********************************************************************/ +HRESULT WINAPI +DirectDrawEnumerateA(LPDDENUMCALLBACKA Callback, + void *Context) +{ + BOOL stop = FALSE; + + TRACE(" Enumerating default DirectDraw HAL interface\n"); + /* We only have one driver */ + __TRY + { + stop = !Callback(NULL, "DirectDraw HAL", "display", Context); + } + __EXCEPT_PAGE_FAULT + { + return E_INVALIDARG; + } + __ENDTRY + + TRACE(" End of enumeration\n"); return DD_OK; } -/******************************************************************************* +/*********************************************************************** + * DirectDrawEnumerateExA (DDRAW.@) + * + * Enumerates DirectDraw7 drivers, ascii version. See + * the comments above DirectDrawEnumerateA for more details. + * + * The Flag member is not supported right now. + * + ***********************************************************************/ +HRESULT WINAPI +DirectDrawEnumerateExA(LPDDENUMCALLBACKEXA Callback, + void *Context, + DWORD Flags) +{ + BOOL stop = FALSE; + TRACE("Enumerating default DirectDraw HAL interface\n"); + + /* We only have one driver by now */ + __TRY + { + /* QuickTime expects the description "DirectDraw HAL" */ + stop = !Callback(NULL, "DirectDraw HAL", "display", Context, 0); + } + __EXCEPT_PAGE_FAULT + { + return E_INVALIDARG; + } + __ENDTRY; + + TRACE("End of enumeration\n"); + return DD_OK; +} + +/*********************************************************************** + * DirectDrawEnumerateW (DDRAW.@) + * + * Enumerates legacy drivers, unicode version. See + * the comments above DirectDrawEnumerateA for more details. + * + * The Flag member is not supported right now. + * + ***********************************************************************/ + +/*********************************************************************** * DirectDrawEnumerateExW (DDRAW.@) - */ - -static BOOL CALLBACK DirectDrawEnumerateExProcW( - GUID *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName, - LPVOID lpContext, HMONITOR hm) -{ - INT len; - BOOL bResult; - LPWSTR lpDriverDescriptionW, lpDriverNameW; - DirectDrawEnumerateProcData *pEPD = (DirectDrawEnumerateProcData*)lpContext; - - len = MultiByteToWideChar( CP_ACP, 0, lpDriverDescription, -1, NULL, 0 ); - lpDriverDescriptionW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ); - MultiByteToWideChar( CP_ACP, 0, lpDriverDescription, -1, lpDriverDescriptionW, len ); - - len = MultiByteToWideChar( CP_ACP, 0, lpDriverName, -1, NULL, 0 ); - lpDriverNameW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ); - MultiByteToWideChar( CP_ACP, 0, lpDriverName, -1, lpDriverNameW, len ); - - bResult = (*(LPDDENUMCALLBACKEXW *) pEPD->lpCallback)(lpGUID, lpDriverDescriptionW, - lpDriverNameW, pEPD->lpContext, hm); - - HeapFree(GetProcessHeap(), 0, lpDriverDescriptionW); - HeapFree(GetProcessHeap(), 0, lpDriverNameW); - return bResult; -} - -HRESULT WINAPI DirectDrawEnumerateExW( - LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags) -{ - DirectDrawEnumerateProcData epd; - epd.lpCallback = (LPVOID) lpCallback; - epd.lpContext = lpContext; - - return DirectDrawEnumerateExA(DirectDrawEnumerateExProcW, (LPVOID) &epd, 0); -} + * + * Enumerates DirectDraw7 drivers, unicode version. See + * the comments above DirectDrawEnumerateA for more details. + * + * The Flag member is not supported right now. + * + ***********************************************************************/ /*********************************************************************** - * DirectDrawEnumerateA (DDRAW.@) - */ - -static BOOL CALLBACK DirectDrawEnumerateProcA( - GUID *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName, - LPVOID lpContext, HMONITOR hm) -{ - DirectDrawEnumerateProcData *pEPD = (DirectDrawEnumerateProcData*)lpContext; - - return ((LPDDENUMCALLBACKA) pEPD->lpCallback)( - lpGUID, lpDriverDescription, lpDriverName, pEPD->lpContext); -} - -HRESULT WINAPI DirectDrawEnumerateA( - LPDDENUMCALLBACKA lpCallback, LPVOID lpContext) -{ - DirectDrawEnumerateProcData epd; - epd.lpCallback = (LPVOID) lpCallback; - epd.lpContext = lpContext; - - return DirectDrawEnumerateExA(DirectDrawEnumerateProcA, (LPVOID) &epd, 0); -} + * Classfactory implementation. + ***********************************************************************/ /*********************************************************************** - * DirectDrawEnumerateW (DDRAW.@) - */ - -static BOOL WINAPI DirectDrawEnumerateProcW( - GUID *lpGUID, LPWSTR lpDriverDescription, LPWSTR lpDriverName, - LPVOID lpContext, HMONITOR hm) + * CF_CreateDirectDraw + * + * DDraw creation function for the class factory + * + * Params: + * UnkOuter: Set to NULL + * iid: ID of the wanted interface + * obj: Address to pass the interface pointer back + * + * Returns + * DD_OK / DDERR*, see DDRAW_Create + * + ***********************************************************************/ +static HRESULT +CF_CreateDirectDraw(IUnknown* UnkOuter, REFIID iid, + void **obj) { - DirectDrawEnumerateProcData *pEPD = (DirectDrawEnumerateProcData*)lpContext; - - return ((LPDDENUMCALLBACKW) pEPD->lpCallback)( - lpGUID, lpDriverDescription, lpDriverName, pEPD->lpContext); -} - -HRESULT WINAPI DirectDrawEnumerateW( - LPDDENUMCALLBACKW lpCallback, LPVOID lpContext) -{ - DirectDrawEnumerateProcData epd; - epd.lpCallback = (LPVOID) lpCallback; - epd.lpContext = lpContext; - - return DirectDrawEnumerateExW(DirectDrawEnumerateProcW, (LPVOID) &epd, 0); -} - -/*********************************************************************** - * DirectDrawCreate (DDRAW.@) - */ - -const ddraw_driver* DDRAW_FindDriver(const GUID* pGUID) -{ - static const GUID zeroGUID; /* gets zero-inited */ - - TRACE("(%s)\n", pGUID ? debugstr_guid(pGUID) : "(null)"); - - if (DDRAW_num_drivers == 0) return NULL; - - if (pGUID == (LPGUID)DDCREATE_EMULATIONONLY - || pGUID == (LPGUID)DDCREATE_HARDWAREONLY) - pGUID = NULL; - - if (pGUID == NULL || memcmp(pGUID, &zeroGUID, sizeof(GUID)) == 0) - { - /* Use the default driver. */ - return DDRAW_drivers[DDRAW_default_driver]; - } - else - { - /* Look for a matching GUID. */ - - int i; - for (i=0; i < DDRAW_num_drivers; i++) - { - if (IsEqualGUID(pGUID, - &DDRAW_drivers[i]->info->guidDeviceIdentifier)) - break; - } - - if (i < DDRAW_num_drivers) - { - return DDRAW_drivers[i]; - } - else - { - ERR("(%s): did not recognize requested GUID.\n",debugstr_guid(pGUID)); - return NULL; - } - } -} - -static HRESULT DDRAW_Create( - LPGUID lpGUID, LPVOID *lplpDD, LPUNKNOWN pUnkOuter, REFIID iid, BOOL ex -) { - const ddraw_driver* driver; - LPDIRECTDRAW7 pDD; HRESULT hr; - TRACE("(%s,%p,%p,%d)\n", debugstr_guid(lpGUID), lplpDD, pUnkOuter, ex); + TRACE("(%p,%s,%p)\n", UnkOuter, debugstr_guid(iid), obj); - if (DDRAW_num_drivers == 0) - { - WARN("no DirectDraw drivers registered\n"); - return DDERR_INVALIDDIRECTDRAWGUID; - } - - if (lpGUID == (LPGUID)DDCREATE_EMULATIONONLY - || lpGUID == (LPGUID)DDCREATE_HARDWAREONLY) - lpGUID = NULL; - - if (pUnkOuter != NULL) - return DDERR_INVALIDPARAMS; /* CLASS_E_NOAGGREGATION? */ - - driver = DDRAW_FindDriver(lpGUID); - if (driver == NULL) return DDERR_INVALIDDIRECTDRAWGUID; - - hr = driver->create(lpGUID, &pDD, pUnkOuter, ex); - if (FAILED(hr)) return hr; - - hr = IDirectDraw7_QueryInterface(pDD, iid, lplpDD); - IDirectDraw7_Release(pDD); + hr = DDRAW_Create(NULL, obj, UnkOuter, iid); return hr; } /*********************************************************************** - * DirectDrawCreate (DDRAW.@) + * CF_CreateDirectDraw * - * Only creates legacy IDirectDraw interfaces. - * Cannot create IDirectDraw7 interfaces. - * In theory. - */ -HRESULT WINAPI DirectDrawCreate( - LPGUID lpGUID, LPDIRECTDRAW* lplpDD, LPUNKNOWN pUnkOuter -) { - TRACE("(%s,%p,%p)\n", debugstr_guid(lpGUID), lplpDD, pUnkOuter); - return DDRAW_Create(lpGUID, (LPVOID*) lplpDD, pUnkOuter, &IID_IDirectDraw, FALSE); -} - -/*********************************************************************** - * DirectDrawCreateEx (DDRAW.@) + * Clipper creation function for the class factory * - * Only creates new IDirectDraw7 interfaces. - * Supposed to fail if legacy interfaces are requested. - * In theory. - */ -HRESULT WINAPI DirectDrawCreateEx( - LPGUID lpGUID, LPVOID* lplpDD, REFIID iid, LPUNKNOWN pUnkOuter -) { - TRACE("(%s,%p,%s,%p)\n", debugstr_guid(lpGUID), lplpDD, debugstr_guid(iid), pUnkOuter); - - if (!IsEqualGUID(iid, &IID_IDirectDraw7)) - return DDERR_INVALIDPARAMS; - - return DDRAW_Create(lpGUID, lplpDD, pUnkOuter, iid, TRUE); -} - -extern HRESULT Uninit_DirectDraw_Create(const GUID*, LPDIRECTDRAW7*, - LPUNKNOWN, BOOL); - -/* This is for the class factory. */ -static HRESULT DDRAW_CreateDirectDraw(IUnknown* pUnkOuter, REFIID iid, - LPVOID* ppObj) + * Params: + * UnkOuter: Set to NULL + * iid: ID of the wanted interface + * obj: Address to pass the interface pointer back + * + * Returns + * DD_OK / DDERR*, see DDRAW_Create + * + ***********************************************************************/ +static HRESULT +CF_CreateDirectDrawClipper(IUnknown* UnkOuter, REFIID riid, + void **obj) { - LPDIRECTDRAW7 pDD; HRESULT hr; - BOOL ex; + IDirectDrawClipper *Clip; - TRACE("(%p,%s,%p)\n", pUnkOuter, debugstr_guid(iid), ppObj); - - /* This is a mighty hack :-) */ - if (IsEqualGUID(iid, &IID_IDirectDraw7)) - ex = TRUE; - else - ex = FALSE; - - hr = Uninit_DirectDraw_Create(NULL, &pDD, pUnkOuter, ex); - if (FAILED(hr)) return hr; + hr = DirectDrawCreateClipper(0, &Clip, UnkOuter); + if (hr != DD_OK) return hr; - hr = IDirectDraw7_QueryInterface(pDD, iid, ppObj); - IDirectDraw_Release(pDD); + hr = IDirectDrawClipper_QueryInterface(Clip, riid, obj); + IDirectDrawClipper_Release(Clip); return hr; } -/****************************************************************************** - * DirectDraw ClassFactory - */ -typedef struct { - ICOM_VFIELD_MULTI(IClassFactory); - - LONG ref; - HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, REFIID iid, - LPVOID *ppObj); -} IClassFactoryImpl; - -struct object_creation_info -{ - const CLSID *clsid; - HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, REFIID riid, - LPVOID *ppObj); -}; - -/* There should be more, but these are the only ones listed in the header - * file. */ -extern HRESULT DDRAW_CreateDirectDrawClipper(IUnknown *pUnkOuter, REFIID riid, - LPVOID *ppObj); - static const struct object_creation_info object_creation[] = { - { &CLSID_DirectDraw, DDRAW_CreateDirectDraw }, - { &CLSID_DirectDraw7, DDRAW_CreateDirectDraw }, - { &CLSID_DirectDrawClipper, DDRAW_CreateDirectDrawClipper } + { &CLSID_DirectDraw, CF_CreateDirectDraw }, + { &CLSID_DirectDraw7, CF_CreateDirectDraw }, + { &CLSID_DirectDrawClipper, CF_CreateDirectDrawClipper } }; +/******************************************************************************* + * IDirectDrawClassFactory::QueryInterface + * + * QueryInterface for the class factory + * + * PARAMS + * riid Reference to identifier of queried interface + * ppv Address to return the interface pointer at + * + * RETURNS + * Success: S_OK + * Failure: E_NOINTERFACE + * + *******************************************************************************/ static HRESULT WINAPI -DDCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) +IDirectDrawClassFactoryImpl_QueryInterface(IClassFactory *iface, + REFIID riid, + void **obj) { - IClassFactoryImpl *This = (IClassFactoryImpl *)iface; + ICOM_THIS_FROM(IClassFactoryImpl, IClassFactory, iface); + + TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(riid), obj); - TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(riid), ppobj); - if (IsEqualGUID(riid, &IID_IUnknown) - || IsEqualGUID(riid, &IID_IClassFactory)) + || IsEqualGUID(riid, &IID_IClassFactory)) { - IClassFactory_AddRef(iface); - *ppobj = This; - return S_OK; + IClassFactory_AddRef(iface); + *obj = This; + return S_OK; } - WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj); + WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),obj); return E_NOINTERFACE; } -static ULONG WINAPI DDCF_AddRef(LPCLASSFACTORY iface) +/******************************************************************************* + * IDirectDrawClassFactory::AddRef + * + * AddRef for the class factory + * + * RETURNS + * The new refcount + * + *******************************************************************************/ +static ULONG WINAPI +IDirectDrawClassFactoryImpl_AddRef(IClassFactory *iface) { - IClassFactoryImpl *This = (IClassFactoryImpl *)iface; + ICOM_THIS_FROM(IClassFactoryImpl, IClassFactory, iface); ULONG ref = InterlockedIncrement(&This->ref); TRACE("(%p)->() incrementing from %ld.\n", This, ref - 1); - + return ref; } -static ULONG WINAPI DDCF_Release(LPCLASSFACTORY iface) +/******************************************************************************* + * IDirectDrawClassFactory::Release + * + * Release for the class factory. If the refcount falls to 0, the object + * is destroyed + * + * RETURNS + * The new refcount + * + *******************************************************************************/ +static ULONG WINAPI +IDirectDrawClassFactoryImpl_Release(IClassFactory *iface) { - IClassFactoryImpl *This = (IClassFactoryImpl *)iface; + ICOM_THIS_FROM(IClassFactoryImpl, IClassFactory, iface); ULONG ref = InterlockedDecrement(&This->ref); TRACE("(%p)->() decrementing from %ld.\n", This, ref+1); if (ref == 0) - HeapFree(GetProcessHeap(), 0, This); + HeapFree(GetProcessHeap(), 0, This); return ref; } -static HRESULT WINAPI DDCF_CreateInstance( - LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj -) +/******************************************************************************* + * IDirectDrawClassFactory::CreateInstance + * + * What is this? Seems to create DirectDraw objects... + * + * Params + * The ususal things??? + * + * RETURNS + * ??? + * + *******************************************************************************/ +static HRESULT WINAPI +IDirectDrawClassFactoryImpl_CreateInstance(IClassFactory *iface, + IUnknown *UnkOuter, + REFIID riid, + void **obj) { - IClassFactoryImpl *This = (IClassFactoryImpl *)iface; + ICOM_THIS_FROM(IClassFactoryImpl, IClassFactory, iface); - TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,debugstr_guid(riid),ppobj); + TRACE("(%p)->(%p,%s,%p)\n",This,UnkOuter,debugstr_guid(riid),obj); - return This->pfnCreateInstance(pOuter, riid, ppobj); + return This->pfnCreateInstance(UnkOuter, riid, obj); } -static HRESULT WINAPI DDCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) +/******************************************************************************* + * IDirectDrawClassFactory::LockServer + * + * What is this? + * + * Params + * ??? + * + * RETURNS + * S_OK, because it's a stub + * + *******************************************************************************/ +static HRESULT WINAPI +IDirectDrawClassFactoryImpl_LockServer(IClassFactory *iface,BOOL dolock) { - IClassFactoryImpl *This = (IClassFactoryImpl *)iface; + ICOM_THIS_FROM(IClassFactoryImpl, IClassFactory, iface); FIXME("(%p)->(%d),stub!\n",This,dolock); return S_OK; } -static const IClassFactoryVtbl DDCF_Vtbl = +/******************************************************************************* + * The class factory VTable + *******************************************************************************/ +static const IClassFactoryVtbl IClassFactory_Vtbl = { - DDCF_QueryInterface, - DDCF_AddRef, - DDCF_Release, - DDCF_CreateInstance, - DDCF_LockServer + IDirectDrawClassFactoryImpl_QueryInterface, + IDirectDrawClassFactoryImpl_AddRef, + IDirectDrawClassFactoryImpl_Release, + IDirectDrawClassFactoryImpl_CreateInstance, + IDirectDrawClassFactoryImpl_LockServer }; /******************************************************************************* @@ -595,10 +680,10 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) return CLASS_E_CLASSNOTAVAILABLE; } - factory = HeapAlloc(GetProcessHeap(), 0, sizeof(*factory)); + factory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*factory)); if (factory == NULL) return E_OUTOFMEMORY; - ICOM_INIT_INTERFACE(factory, IClassFactory, DDCF_Vtbl); + ICOM_INIT_INTERFACE(factory, IClassFactory, IClassFactory_Vtbl); factory->ref = 1; factory->pfnCreateInstance = object_creation[i].pfnCreateInstance; @@ -621,103 +706,190 @@ HRESULT WINAPI DllCanUnloadNow(void) return S_FALSE; } -/****************************************************************************** - * Initialisation - */ - -/* Choose which driver is considered the primary display driver. It will - * be created when we get a NULL guid for the DirectDrawCreate(Ex). */ -static int DDRAW_ChooseDefaultDriver(void) +/******************************************************************************* + * DestroyCallback + * + * Callback function for the EnumSurfaces call in DllMain. + * Dumps some surface info and releases the surface + * + * Params: + * surf: The enumerated surface + * desc: it's description + * context: Pointer to the ddraw impl + * + * Returns: + * DDENUMRET_OK; + *******************************************************************************/ +HRESULT WINAPI +DestroyCallback(IDirectDrawSurface7 *surf, + DDSURFACEDESC2 *desc, + void *context) { - int i; - int best = 0; - int best_score = 0; + IDirectDrawSurfaceImpl *Impl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, surf); + IDirectDrawImpl *ddraw = (IDirectDrawImpl *) context; + ULONG ref; - assert(DDRAW_num_drivers > 0); + ref = IDirectDrawSurface7_Release(surf); /* For the EnumSurfaces */ + WARN("Surface %p has an reference count of %ld\n", Impl, ref); - /* This algorithm is really stupid. */ - for (i=0; i < DDRAW_num_drivers; i++) - { - if (DDRAW_drivers[i]->preference > best_score) - { - best_score = DDRAW_drivers[i]->preference; - best = i; - } - } + /* Skip surfaces which are attached somewhere or which are + * part of a complex compound. They will get released when destroying + * the root + */ + if( (Impl->first_complex != Impl) || (Impl->first_attached != Impl) ) + return DDENUMRET_OK; + /* Skip our depth stencil surface, it will be released with the render target */ + if( Impl == ddraw->DepthStencilBuffer) + return DDENUMRET_OK; - assert(best_score > 0); + /* Destroy the surface */ + while(ref) ref = IDirectDrawSurface7_Release(surf); - return best; + return DDENUMRET_OK; } /*********************************************************************** - * DllMain (DDRAW.0) - */ -BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv) + * get_config_key + * + * Reads a config key from the registry. Taken from WineD3D + * + ***********************************************************************/ +inline static DWORD get_config_key(HKEY defkey, HKEY appkey, const char* name, char* buffer, DWORD size) { - /* If we were sufficiently cool, DDraw drivers would just be COM - * objects, registered with a particular component category. */ + if (0 != appkey && !RegQueryValueExA( appkey, name, 0, NULL, (LPBYTE) buffer, &size )) return 0; + if (0 != defkey && !RegQueryValueExA( defkey, name, 0, NULL, (LPBYTE) buffer, &size )) return 0; + return ERROR_FILE_NOT_FOUND; +} - DDRAW_HAL_Init(hInstDLL, fdwReason, lpv); - DDRAW_User_Init(hInstDLL, fdwReason, lpv); +/*********************************************************************** + * DllMain (DDRAW.0) + * + * Could be used to register DirectDraw drivers, if we have more than + * one. Also used to destroy any objects left at unload if the + * app didn't release them properly(Gothic 2, Diablo 2, Moto racer, ...) + * + ***********************************************************************/ +BOOL WINAPI +DllMain(HINSTANCE hInstDLL, + DWORD Reason, + void *lpv) +{ + static LONG counter = 0; - if (fdwReason == DLL_PROCESS_ATTACH) + TRACE("(%p,%lx,%p)\n", hInstDLL, Reason, lpv); + if (Reason == DLL_PROCESS_ATTACH) { - HMODULE mod; + char buffer[MAX_PATH+10]; + DWORD size = sizeof(buffer); + HKEY hkey = 0; + HKEY appkey = 0; + DWORD len; + + /* @@ Wine registry key: HKCU\Software\Wine\Direct3D */ + if ( RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\Direct3D", &hkey ) ) hkey = 0; + + len = GetModuleFileNameA( 0, buffer, MAX_PATH ); + if (len && len < MAX_PATH) + { + HKEY tmpkey; + /* @@ Wine registry key: HKCU\Software\Wine\AppDefaults\app.exe\Direct3D */ + if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\AppDefaults", &tmpkey )) + { + char *p, *appname = buffer; + if ((p = strrchr( appname, '/' ))) appname = p + 1; + if ((p = strrchr( appname, '\\' ))) appname = p + 1; + strcat( appname, "\\Direct3D" ); + TRACE("appname = [%s]\n", appname); + if (RegOpenKeyA( tmpkey, appname, &appkey )) appkey = 0; + RegCloseKey( tmpkey ); + } + } + + if ( 0 != hkey || 0 != appkey ) + { + if ( !get_config_key( hkey, appkey, "DirectDrawRenderer", buffer, size) ) + { + if (!strcmp(buffer,"gdi")) + { + TRACE("Defaulting to GDI surfaces\n"); + DefaultSurfaceType = SURFACE_GDI; + } + else if (!strcmp(buffer,"opengl")) + { + TRACE("Defaulting to opengl surfaces\n"); + DefaultSurfaceType = SURFACE_OPENGL; + } + else + { + ERR("Unknown default surface type. Supported are:\n gdi, opengl"); + } + } + } DisableThreadLibraryCalls(hInstDLL); + TRACE("Attach counter: %ld\n", InterlockedIncrement(&counter)); + } + else if (Reason == DLL_PROCESS_DETACH) + { + TRACE("Attach counter: %ld\n", InterlockedDecrement(&counter)); - mod = GetModuleHandleA( "winex11.drv" ); - if (mod) + if(counter == 0) { - wine_tsx11_lock_ptr = (void *)GetProcAddress( mod, "wine_tsx11_lock" ); - wine_tsx11_unlock_ptr = (void *)GetProcAddress( mod, "wine_tsx11_unlock" ); - } -#ifdef HAVE_OPENGL - opengl_initialized = DDRAW_bind_to_opengl(); -#endif /* HAVE_OPENGL */ - s3tc_initialized = DDRAW_bind_to_s3tc(); + if(ddraw_list) + { + IDirectDrawImpl *ddraw; + WARN("There are still existing DirectDraw interfaces. Wine bug or buggy application?\n"); - if (DDRAW_num_drivers > 0) - DDRAW_default_driver = DDRAW_ChooseDefaultDriver(); + for(ddraw = ddraw_list; ddraw; ddraw = ddraw->next) + { + HRESULT hr; + DDSURFACEDESC2 desc; + int i; + + WARN("DDraw %p has a refcount of %ld\n", ddraw, ddraw->ref); + + ddraw->DoNotDestroy = TRUE; /* Avoid to destroy the object too early */ + + /* Does a D3D device exist? Destroy it + * TODO: Destroy all Vertex buffers, Lights, Materials + * and execture buffers too + */ + if(ddraw->d3ddevice) + { + WARN("DDraw %p has d3ddevice %p attached\n", ddraw, ddraw->d3ddevice); + while(IDirect3DDevice7_Release(ICOM_INTERFACE(ddraw->d3ddevice, IDirect3DDevice7))); + } + + /* Try to release the objects + * Do an EnumSurfaces to find any hanging surfaces + */ + memset(&desc, 0, sizeof(desc)); + desc.dwSize = sizeof(desc); + for(i = 0; i <= 1; i++) + { + hr = IDirectDraw7_EnumSurfaces(ICOM_INTERFACE(ddraw, IDirectDraw7), + DDENUMSURFACES_ALL, + &desc, + (void *) ddraw, + DestroyCallback); + if(hr != D3D_OK) + ERR("(%p) EnumSurfaces failed, prepare for trouble\n", ddraw); + } + + /* Check the surface count */ + if(ddraw->surfaces > 0) + ERR("DDraw %p still has %ld surfaces attached\n", ddraw, ddraw->surfaces); + + /* Restore the cooperative level */ + IDirectDraw7_SetCooperativeLevel(ICOM_INTERFACE(ddraw, IDirectDraw7), + NULL, + DDSCL_NORMAL); + ddraw->DoNotDestroy = FALSE; + IDirectDrawImpl_Destroy(ddraw); + } + } + } } return TRUE; } - -/* Register a direct draw driver. This should be called from your init - * function. (That's why there is no locking: your init func is called from - * our DllInit, which is serialised.) */ -void DDRAW_register_driver(const ddraw_driver *driver) -{ - int i; - - for (i = 0; i < DDRAW_num_drivers; i++) - { - if (DDRAW_drivers[i] == driver) - { - ERR("Driver reregistering %p\n", driver); - return; - } - } - - if (DDRAW_num_drivers == sizeof(DDRAW_drivers)/sizeof(DDRAW_drivers[0])) - { - ERR("too many DDRAW drivers\n"); - return; - } - - DDRAW_drivers[DDRAW_num_drivers++] = driver; -} - -/* This totally doesn't belong here. */ -LONG DDRAW_width_bpp_to_pitch(DWORD width, DWORD bpp) -{ - LONG pitch; - - assert(bpp != 0); /* keeps happening... */ - - if (bpp == 15) bpp = 16; - pitch = width * (bpp / 8); - return pitch + (8 - (pitch % 8)) % 8; -} diff --git a/dlls/ddraw/material.c b/dlls/ddraw/material.c index 5ddd20d593..df5783d1cf 100644 --- a/dlls/ddraw/material.c +++ b/dlls/ddraw/material.c @@ -1,5 +1,6 @@ /* Direct3D Material * Copyright (c) 2002 Lionel ULMER + * Copyright (c) 2006 Stefan DÖSINGER * * This file contains the implementation of Direct3DMaterial. * @@ -19,38 +20,64 @@ */ #include "config.h" +#include "wine/port.h" +#include #include +#include +#include +#define COBJMACROS #define NONAMELESSUNION -#define NONAMELESSSTRUCT #include "windef.h" #include "winbase.h" +#include "winnls.h" #include "winerror.h" -#include "objbase.h" #include "wingdi.h" +#include "wine/exception.h" +#include "excpt.h" + #include "ddraw.h" #include "d3d.h" + +#include "ddraw_private.h" #include "wine/debug.h" -#include "d3d_private.h" -#include "opengl_private.h" - -WINE_DEFAULT_DEBUG_CHANNEL(ddraw); +WINE_DEFAULT_DEBUG_CHANNEL(d3d7); +WINE_DECLARE_DEBUG_CHANNEL(ddraw_thunk); static void dump_material(LPD3DMATERIAL mat) { DPRINTF(" dwSize : %ld\n", mat->dwSize); } -HRESULT WINAPI -Main_IDirect3DMaterialImpl_3_2T_1T_QueryInterface(LPDIRECT3DMATERIAL3 iface, - REFIID riid, - LPVOID* obp) +/***************************************************************************** + * IUnknown Methods. + *****************************************************************************/ + +/***************************************************************************** + * IDirect3DMaterial3::QueryInterface + * + * QueryInterface for IDirect3DMaterial. Can query all IDirect3DMaterial + * versions. + * + * Params: + * riid: Interface id queried for + * obj: Address to pass the interface pointer back + * + * Returns: + * S_OK on success + * E_NOINTERFACE if the requested interface wasn't found + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DMaterialImpl_QueryInterface(IDirect3DMaterial3 *iface, + REFIID riid, + LPVOID* obp) { ICOM_THIS_FROM(IDirect3DMaterialImpl, IDirect3DMaterial3, iface); - TRACE("(%p/%p)->(%s,%p)\n", This, iface, debugstr_guid(riid), obp); + TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(riid), obp); *obp = NULL; @@ -79,27 +106,46 @@ Main_IDirect3DMaterialImpl_3_2T_1T_QueryInterface(LPDIRECT3DMATERIAL3 iface, return S_OK; } FIXME("(%p): interface for IID %s NOT found!\n", This, debugstr_guid(riid)); - return OLE_E_ENUM_NOMORE; + return E_NOINTERFACE; } -ULONG WINAPI -Main_IDirect3DMaterialImpl_3_2T_1T_AddRef(LPDIRECT3DMATERIAL3 iface) +/***************************************************************************** + * IDirect3DMaterial3::AddRef + * + * Increases the refcount. + * + * Returns: + * The new refcount + * + *****************************************************************************/ +static ULONG WINAPI +IDirect3DMaterialImpl_AddRef(IDirect3DMaterial3 *iface) { ICOM_THIS_FROM(IDirect3DMaterialImpl, IDirect3DMaterial3, iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p/%p)->() incrementing from %lu.\n", This, iface, ref - 1); + TRACE("(%p)->() incrementing from %lu.\n", This, ref - 1); return ref; } -ULONG WINAPI -Main_IDirect3DMaterialImpl_3_2T_1T_Release(LPDIRECT3DMATERIAL3 iface) +/***************************************************************************** + * IDirect3DMaterial3::Release + * + * Reduces the refcount by one. If the refcount falls to 0, the object + * is destroyed + * + * Returns: + * The new refcount + * + *****************************************************************************/ +static ULONG WINAPI +IDirect3DMaterialImpl_Release(IDirect3DMaterial3 *iface) { ICOM_THIS_FROM(IDirect3DMaterialImpl, IDirect3DMaterial3, iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p/%p)->() decrementing from %lu.\n", This, iface, ref + 1); + TRACE("(%p)->() decrementing from %lu.\n", This, ref + 1); if (!ref) { HeapFree(GetProcessHeap(), 0, This); @@ -108,38 +154,90 @@ Main_IDirect3DMaterialImpl_3_2T_1T_Release(LPDIRECT3DMATERIAL3 iface) return ref; } -HRESULT WINAPI -Main_IDirect3DMaterialImpl_1_Initialize(LPDIRECT3DMATERIAL iface, - LPDIRECT3D lpDirect3D) +/***************************************************************************** + * IDirect3DMaterial Methods + *****************************************************************************/ + +/***************************************************************************** + * IDirect3DMaterial::Initialize + * + * A no-op initialization + * + * Params: + * Direct3D: Pointer to a Direct3D interface + * + * Returns: + * D3D_OK + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DMaterialImpl_Initialize(IDirect3DMaterial *iface, + IDirect3D *Direct3D) { ICOM_THIS_FROM(IDirect3DMaterialImpl, IDirect3DMaterial, iface); - TRACE("(%p/%p)->(%p) no-op...!\n", This, iface, lpDirect3D); - return DD_OK; + + TRACE("(%p)->(%p) no-op...!\n", This, Direct3D); + + return D3D_OK; } -HRESULT WINAPI -Main_IDirect3DMaterialImpl_1_Reserve(LPDIRECT3DMATERIAL iface) +/***************************************************************************** + * IDirect3DMaterial::Reserve + * + * DirectX 5 sdk: "The IDirect3DMaterial2::Reserve method is not implemented" + * Odd. They seem to have mixed their interfaces. + * + * Returns: + * DDERR_UNSUPPORTED + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DMaterialImpl_Reserve(IDirect3DMaterial *iface) { ICOM_THIS_FROM(IDirect3DMaterialImpl, IDirect3DMaterial, iface); - TRACE("(%p/%p)->() not implemented.\n", This, iface); - return DD_OK; + TRACE("(%p)->() not implemented\n", This); + + return DDERR_UNSUPPORTED; } -HRESULT WINAPI -Main_IDirect3DMaterialImpl_1_Unreserve(LPDIRECT3DMATERIAL iface) +/***************************************************************************** + * IDirect3DMaterial::Unreserve + * + * Not supported too + * + * Returns: + * DDERR_UNSUPPORTED + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DMaterialImpl_Unreserve(IDirect3DMaterial *iface) { ICOM_THIS_FROM(IDirect3DMaterialImpl, IDirect3DMaterial, iface); - FIXME("(%p/%p)->() not implemented.\n", This, iface); - return DD_OK; + TRACE("(%p)->() not implemented.\n", This); + + return DDERR_UNSUPPORTED; } -HRESULT WINAPI -Main_IDirect3DMaterialImpl_3_2T_1T_SetMaterial(LPDIRECT3DMATERIAL3 iface, - LPD3DMATERIAL lpMat) +/***************************************************************************** + * IDirect3DMaterial3::SetMaterial + * + * Sets the material description + * + * Params: + * Mat: Material to set + * + * Returns: + * D3D_OK on success + * DDERR_INVALIDPARAMS if Mat is NULL + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DMaterialImpl_SetMaterial(IDirect3DMaterial3 *iface, + D3DMATERIAL *lpMat) { ICOM_THIS_FROM(IDirect3DMaterialImpl, IDirect3DMaterial3, iface); - TRACE("(%p/%p)->(%p)\n", This, iface, lpMat); - if (TRACE_ON(ddraw)) + TRACE("(%p)->(%p)\n", This, lpMat); + if (TRACE_ON(d3d7)) dump_material(lpMat); /* Stores the material */ @@ -149,14 +247,27 @@ Main_IDirect3DMaterialImpl_3_2T_1T_SetMaterial(LPDIRECT3DMATERIAL3 iface, return DD_OK; } -HRESULT WINAPI -Main_IDirect3DMaterialImpl_3_2T_1T_GetMaterial(LPDIRECT3DMATERIAL3 iface, - LPD3DMATERIAL lpMat) +/***************************************************************************** + * IDirect3DMaterial3::GetMaterial + * + * Returns the material assigned to this interface + * + * Params: + * Mat: Pointer to a D3DMATERIAL structure to store the material description + * + * Returns: + * D3D_OK on success + * DDERR_INVALIDPARAMS if Mat is NULL + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DMaterialImpl_GetMaterial(IDirect3DMaterial3 *iface, + D3DMATERIAL *lpMat) { ICOM_THIS_FROM(IDirect3DMaterialImpl, IDirect3DMaterial3, iface); DWORD dwSize; - TRACE("(%p/%p)->(%p)\n", This, iface, lpMat); - if (TRACE_ON(ddraw)) { + TRACE("(%p)->(%p)\n", This, lpMat); + if (TRACE_ON(d3d7)) { TRACE(" Returning material : "); dump_material(&This->mat); } @@ -169,10 +280,25 @@ Main_IDirect3DMaterialImpl_3_2T_1T_GetMaterial(LPDIRECT3DMATERIAL3 iface, return DD_OK; } -HRESULT WINAPI -Main_IDirect3DMaterialImpl_3_2T_1T_GetHandle(LPDIRECT3DMATERIAL3 iface, - LPDIRECT3DDEVICE3 lpDirect3DDevice3, - LPD3DMATERIALHANDLE lpHandle) +/***************************************************************************** + * IDirect3DMaterial3::GetHandle + * + * Returns a handle for the material interface. The handle is simply a + * pointer to the material implementation + * + * Params: + * Direct3DDevice3: The device this handle is assigned to + * Handle: Address to write the handle to + * + * Returns: + * D3D_OK on success + * DDERR_INVALIDPARAMS if Handle is NULL + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DMaterialImpl_GetHandle(IDirect3DMaterial3 *iface, + IDirect3DDevice3 *lpDirect3DDevice3, + D3DMATERIALHANDLE *lpHandle) { ICOM_THIS_FROM(IDirect3DMaterialImpl, IDirect3DMaterial3, iface); TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpDirect3DDevice3, lpHandle); @@ -191,7 +317,7 @@ Thunk_IDirect3DMaterialImpl_2_GetHandle(LPDIRECT3DMATERIAL2 iface, LPDIRECT3DDEVICE2 lpDirect3DDevice2, LPD3DMATERIALHANDLE lpHandle) { - TRACE("(%p)->(%p,%p) thunking to IDirect3DMaterial3 interface.\n", iface, lpDirect3DDevice2, lpHandle); + TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DMaterial3 interface.\n", iface, lpDirect3DDevice2, lpHandle); return IDirect3DMaterial3_GetHandle(COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial2, IDirect3DMaterial3, iface), COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice2, IDirect3DDevice3, lpDirect3DDevice2), lpHandle); @@ -202,7 +328,7 @@ Thunk_IDirect3DMaterialImpl_1_GetHandle(LPDIRECT3DMATERIAL iface, LPDIRECT3DDEVICE lpDirect3DDevice, LPD3DMATERIALHANDLE lpHandle) { - TRACE("(%p)->(%p,%p) thunking to IDirect3DMaterial3 interface.\n", iface, lpDirect3DDevice, lpHandle); + TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DMaterial3 interface.\n", iface, lpDirect3DDevice, lpHandle); return IDirect3DMaterial3_GetHandle(COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial, IDirect3DMaterial3, iface), COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice3, lpDirect3DDevice), lpHandle); @@ -213,7 +339,7 @@ Thunk_IDirect3DMaterialImpl_2_QueryInterface(LPDIRECT3DMATERIAL2 iface, REFIID riid, LPVOID* obp) { - TRACE("(%p)->(%s,%p) thunking to IDirect3DMaterial3 interface.\n", iface, debugstr_guid(riid), obp); + TRACE_(ddraw_thunk)("(%p)->(%s,%p) thunking to IDirect3DMaterial3 interface.\n", iface, debugstr_guid(riid), obp); return IDirect3DMaterial3_QueryInterface(COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial2, IDirect3DMaterial3, iface), riid, obp); @@ -224,195 +350,136 @@ Thunk_IDirect3DMaterialImpl_1_QueryInterface(LPDIRECT3DMATERIAL iface, REFIID riid, LPVOID* obp) { - TRACE("(%p)->(%s,%p) thunking to IDirect3DMaterial3 interface.\n", iface, debugstr_guid(riid), obp); + TRACE_(ddraw_thunk)("(%p)->(%s,%p) thunking to IDirect3DMaterial3 interface.\n", iface, debugstr_guid(riid), obp); return IDirect3DMaterial3_QueryInterface(COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial, IDirect3DMaterial3, iface), riid, obp); } -ULONG WINAPI +static ULONG WINAPI Thunk_IDirect3DMaterialImpl_2_AddRef(LPDIRECT3DMATERIAL2 iface) { - TRACE("(%p)->() thunking to IDirect3DMaterial3 interface.\n", iface); + TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DMaterial3 interface.\n", iface); return IDirect3DMaterial3_AddRef(COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial2, IDirect3DMaterial3, iface)); } -ULONG WINAPI +static ULONG WINAPI Thunk_IDirect3DMaterialImpl_1_AddRef(LPDIRECT3DMATERIAL iface) { - TRACE("(%p)->() thunking to IDirect3DMaterial3 interface.\n", iface); + TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DMaterial3 interface.\n", iface); return IDirect3DMaterial3_AddRef(COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial, IDirect3DMaterial3, iface)); } -ULONG WINAPI +static ULONG WINAPI Thunk_IDirect3DMaterialImpl_2_Release(LPDIRECT3DMATERIAL2 iface) { - TRACE("(%p)->() thunking to IDirect3DMaterial3 interface.\n", iface); + TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DMaterial3 interface.\n", iface); return IDirect3DMaterial3_Release(COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial2, IDirect3DMaterial3, iface)); } -ULONG WINAPI +static ULONG WINAPI Thunk_IDirect3DMaterialImpl_1_Release(LPDIRECT3DMATERIAL iface) { - TRACE("(%p)->() thunking to IDirect3DMaterial3 interface.\n", iface); + TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DMaterial3 interface.\n", iface); return IDirect3DMaterial3_Release(COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial, IDirect3DMaterial3, iface)); } -HRESULT WINAPI +static HRESULT WINAPI Thunk_IDirect3DMaterialImpl_2_SetMaterial(LPDIRECT3DMATERIAL2 iface, LPD3DMATERIAL lpMat) { - TRACE("(%p)->(%p) thunking to IDirect3DMaterial3 interface.\n", iface, lpMat); + TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DMaterial3 interface.\n", iface, lpMat); return IDirect3DMaterial3_SetMaterial(COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial2, IDirect3DMaterial3, iface), lpMat); } -HRESULT WINAPI +static HRESULT WINAPI Thunk_IDirect3DMaterialImpl_1_SetMaterial(LPDIRECT3DMATERIAL iface, LPD3DMATERIAL lpMat) { - TRACE("(%p)->(%p) thunking to IDirect3DMaterial3 interface.\n", iface, lpMat); + TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DMaterial3 interface.\n", iface, lpMat); return IDirect3DMaterial3_SetMaterial(COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial, IDirect3DMaterial3, iface), lpMat); } -HRESULT WINAPI +static HRESULT WINAPI Thunk_IDirect3DMaterialImpl_2_GetMaterial(LPDIRECT3DMATERIAL2 iface, LPD3DMATERIAL lpMat) { - TRACE("(%p)->(%p) thunking to IDirect3DMaterial3 interface.\n", iface, lpMat); + TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DMaterial3 interface.\n", iface, lpMat); return IDirect3DMaterial3_GetMaterial(COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial2, IDirect3DMaterial3, iface), lpMat); } -HRESULT WINAPI +static HRESULT WINAPI Thunk_IDirect3DMaterialImpl_1_GetMaterial(LPDIRECT3DMATERIAL iface, LPD3DMATERIAL lpMat) { - TRACE("(%p)->(%p) thunking to IDirect3DMaterial3 interface.\n", iface, lpMat); + TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DMaterial3 interface.\n", iface, lpMat); return IDirect3DMaterial3_GetMaterial(COM_INTERFACE_CAST(IDirect3DMaterialImpl, IDirect3DMaterial, IDirect3DMaterial3, iface), lpMat); } -/******************************************************************************* - * Matrial2 static functions - */ -static void activate(IDirect3DMaterialImpl* This) { + +/***************************************************************************** + * material_activate + * + * Uses IDirect3DDevice7::SetMaterial to activate the material + * + * Params: + * This: Pointer to the material implementation to activate + * + *****************************************************************************/ +void material_activate(IDirect3DMaterialImpl* This) +{ + D3DMATERIAL7 d3d7mat; + TRACE("Activating material %p\n", This); + d3d7mat.u.diffuse = This->mat.u.diffuse; + d3d7mat.u1.ambient = This->mat.u1.ambient; + d3d7mat.u2.specular = This->mat.u2.specular; + d3d7mat.u3.emissive = This->mat.u3.emissive; + d3d7mat.u4.power = This->mat.u4.power; - /* Set the current Material */ - ENTER_GL(); - glMaterialfv(GL_FRONT_AND_BACK, - GL_DIFFUSE, - (float *) &(This->mat.u.diffuse)); - glMaterialfv(GL_FRONT_AND_BACK, - GL_AMBIENT, - (float *) &(This->mat.u1.ambient)); - glMaterialfv(GL_FRONT_AND_BACK, - GL_SPECULAR, - (float *) &(This->mat.u2.specular)); - glMaterialfv(GL_FRONT_AND_BACK, - GL_EMISSION, - (float *) &(This->mat.u3.emissive)); - LEAVE_GL(); - - if (TRACE_ON(ddraw)) { - DPRINTF(" - size : %ld\n", This->mat.dwSize); - DPRINTF(" - diffuse : "); dump_D3DCOLORVALUE(&(This->mat.u.diffuse)); DPRINTF("\n"); - DPRINTF(" - ambient : "); dump_D3DCOLORVALUE(&(This->mat.u1.ambient)); DPRINTF("\n"); - DPRINTF(" - specular: "); dump_D3DCOLORVALUE(&(This->mat.u2.specular)); DPRINTF("\n"); - DPRINTF(" - emissive: "); dump_D3DCOLORVALUE(&(This->mat.u3.emissive)); DPRINTF("\n"); - DPRINTF(" - power : %f\n", This->mat.u4.power); - DPRINTF(" - texture handle : %08lx\n", (DWORD)This->mat.hTexture); - } + IDirect3DDevice7_SetMaterial(ICOM_INTERFACE(This->active_device, IDirect3DDevice7), + &d3d7mat); } -#if !defined(__STRICT_ANSI__) && defined(__GNUC__) -# define XCAST(fun) (typeof(VTABLE_IDirect3DMaterial3.fun)) -#else -# define XCAST(fun) (void*) -#endif - -static const IDirect3DMaterial3Vtbl VTABLE_IDirect3DMaterial3 = +const IDirect3DMaterial3Vtbl IDirect3DMaterial3_Vtbl = { - XCAST(QueryInterface) Main_IDirect3DMaterialImpl_3_2T_1T_QueryInterface, - XCAST(AddRef) Main_IDirect3DMaterialImpl_3_2T_1T_AddRef, - XCAST(Release) Main_IDirect3DMaterialImpl_3_2T_1T_Release, - XCAST(SetMaterial) Main_IDirect3DMaterialImpl_3_2T_1T_SetMaterial, - XCAST(GetMaterial) Main_IDirect3DMaterialImpl_3_2T_1T_GetMaterial, - XCAST(GetHandle) Main_IDirect3DMaterialImpl_3_2T_1T_GetHandle, + /*** IUnknown Methods ***/ + IDirect3DMaterialImpl_QueryInterface, + IDirect3DMaterialImpl_AddRef, + IDirect3DMaterialImpl_Release, + /*** IDirect3DMaterial3 Methods ***/ + IDirect3DMaterialImpl_SetMaterial, + IDirect3DMaterialImpl_GetMaterial, + IDirect3DMaterialImpl_GetHandle, }; -#if !defined(__STRICT_ANSI__) && defined(__GNUC__) -#undef XCAST -#endif - - -#if !defined(__STRICT_ANSI__) && defined(__GNUC__) -# define XCAST(fun) (typeof(VTABLE_IDirect3DMaterial2.fun)) -#else -# define XCAST(fun) (void*) -#endif - -static const IDirect3DMaterial2Vtbl VTABLE_IDirect3DMaterial2 = +const IDirect3DMaterial2Vtbl IDirect3DMaterial2_Vtbl = { - XCAST(QueryInterface) Thunk_IDirect3DMaterialImpl_2_QueryInterface, - XCAST(AddRef) Thunk_IDirect3DMaterialImpl_2_AddRef, - XCAST(Release) Thunk_IDirect3DMaterialImpl_2_Release, - XCAST(SetMaterial) Thunk_IDirect3DMaterialImpl_2_SetMaterial, - XCAST(GetMaterial) Thunk_IDirect3DMaterialImpl_2_GetMaterial, - XCAST(GetHandle) Thunk_IDirect3DMaterialImpl_2_GetHandle, + /*** IUnknown Methods ***/ + Thunk_IDirect3DMaterialImpl_2_QueryInterface, + Thunk_IDirect3DMaterialImpl_2_AddRef, + Thunk_IDirect3DMaterialImpl_2_Release, + /*** IDirect3DMaterial2 Methods ***/ + Thunk_IDirect3DMaterialImpl_2_SetMaterial, + Thunk_IDirect3DMaterialImpl_2_GetMaterial, + Thunk_IDirect3DMaterialImpl_2_GetHandle, }; -#if !defined(__STRICT_ANSI__) && defined(__GNUC__) -#undef XCAST -#endif - - -#if !defined(__STRICT_ANSI__) && defined(__GNUC__) -# define XCAST(fun) (typeof(VTABLE_IDirect3DMaterial.fun)) -#else -# define XCAST(fun) (void*) -#endif - -static const IDirect3DMaterialVtbl VTABLE_IDirect3DMaterial = +const IDirect3DMaterialVtbl IDirect3DMaterial_Vtbl = { - XCAST(QueryInterface) Thunk_IDirect3DMaterialImpl_1_QueryInterface, - XCAST(AddRef) Thunk_IDirect3DMaterialImpl_1_AddRef, - XCAST(Release) Thunk_IDirect3DMaterialImpl_1_Release, - XCAST(Initialize) Main_IDirect3DMaterialImpl_1_Initialize, - XCAST(SetMaterial) Thunk_IDirect3DMaterialImpl_1_SetMaterial, - XCAST(GetMaterial) Thunk_IDirect3DMaterialImpl_1_GetMaterial, - XCAST(GetHandle) Thunk_IDirect3DMaterialImpl_1_GetHandle, - XCAST(Reserve) Main_IDirect3DMaterialImpl_1_Reserve, - XCAST(Unreserve) Main_IDirect3DMaterialImpl_1_Unreserve, + /*** IUnknown Methods ***/ + Thunk_IDirect3DMaterialImpl_1_QueryInterface, + Thunk_IDirect3DMaterialImpl_1_AddRef, + Thunk_IDirect3DMaterialImpl_1_Release, + /*** IDirect3DMaterial1 Methods ***/ + IDirect3DMaterialImpl_Initialize, + Thunk_IDirect3DMaterialImpl_1_SetMaterial, + Thunk_IDirect3DMaterialImpl_1_GetMaterial, + Thunk_IDirect3DMaterialImpl_1_GetHandle, + IDirect3DMaterialImpl_Reserve, + IDirect3DMaterialImpl_Unreserve }; - -#if !defined(__STRICT_ANSI__) && defined(__GNUC__) -#undef XCAST -#endif - - - - -HRESULT d3dmaterial_create(IDirect3DMaterialImpl **obj, IDirectDrawImpl *d3d) -{ - IDirect3DMaterialImpl *object; - - object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DMaterialImpl)); - if (object == NULL) return DDERR_OUTOFMEMORY; - - object->ref = 1; - object->d3d = d3d; - object->activate = activate; - - ICOM_INIT_INTERFACE(object, IDirect3DMaterial, VTABLE_IDirect3DMaterial); - ICOM_INIT_INTERFACE(object, IDirect3DMaterial2, VTABLE_IDirect3DMaterial2); - ICOM_INIT_INTERFACE(object, IDirect3DMaterial3, VTABLE_IDirect3DMaterial3); - - *obj = object; - - TRACE(" creating implementation at %p.\n", *obj); - - return D3D_OK; -} diff --git a/dlls/ddraw/opengl_private.h b/dlls/ddraw/opengl_private.h deleted file mode 100644 index e29afd460c..0000000000 --- a/dlls/ddraw/opengl_private.h +++ /dev/null @@ -1,222 +0,0 @@ -/* MESA private include file - * Copyright (c) 1998 Lionel ULMER - * - * This file contains all structures that are not exported - * through d3d.h and all common macros. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#ifndef __GRAPHICS_WINE_MESA_PRIVATE_H -#define __GRAPHICS_WINE_MESA_PRIVATE_H - -#include "d3d_private.h" - -#ifdef HAVE_OPENGL - -#include "gl_private.h" - -/* X11 locking */ - -extern void (*wine_tsx11_lock_ptr)(void); -extern void (*wine_tsx11_unlock_ptr)(void); - -/* As GLX relies on X, this is needed */ -#define ENTER_GL() wine_tsx11_lock_ptr() -#define LEAVE_GL() wine_tsx11_unlock_ptr() - -extern const GUID IID_D3DDEVICE_OpenGL; - -typedef enum { - SURFACE_GL, - SURFACE_MEMORY, - SURFACE_MEMORY_DIRTY -} SURFACE_STATE; - -/* This structure is used for the 'd3d_private' field of the IDirectDraw structure */ -typedef struct IDirect3DGLImpl -{ - int dummy; /* Empty for the moment */ -} IDirect3DGLImpl; - -/* This structure is used for the 'private' field of the IDirectDrawSurfaceImpl structure */ -typedef struct IDirect3DTextureGLImpl -{ - GLuint tex_name; - BOOLEAN loaded; /* For the moment, this is here.. Should be part of surface management though */ - IDirectDrawSurfaceImpl *main; /* Pointer to the 'main' surface of the mip-map set */ - - /* Texture upload management */ - BOOLEAN initial_upload_done; - SURFACE_STATE dirty_flag; - - /* This is used to optimize dirty checking in case of mipmapping. - Note that a bitmap could have been used but it was not worth the pain as it will be very rare - to have only one mipmap level change... - - The __global_dirty_flag will only be set for the main mipmap level. - */ - SURFACE_STATE __global_dirty_flag; - SURFACE_STATE *global_dirty_flag; - - /* This is to optimize the 'per-texture' parameters. */ - DWORD *tex_parameters; - - /* Surface optimization */ - void *surface_ptr; - - /* Used to detect a change in internal format when going from non-CK texture to CK-ed texture */ - GLenum current_internal_format; - - /* This is for now used to override 'standard' surface stuff to be as transparent as possible */ - void (*final_release)(struct IDirectDrawSurfaceImpl *This); - void (*lock_update)(IDirectDrawSurfaceImpl* This, LPCRECT pRect, DWORD dwFlags); - void (*unlock_update)(IDirectDrawSurfaceImpl* This, LPCRECT pRect); - void (*set_palette)(IDirectDrawSurfaceImpl* This, IDirectDrawPaletteImpl* pal); -} IDirect3DTextureGLImpl; - -typedef enum { - GL_TRANSFORM_NONE = 0, - GL_TRANSFORM_ORTHO, - GL_TRANSFORM_NORMAL, - GL_TRANSFORM_VERTEXBUFFER -} GL_TRANSFORM_STATE; - -typedef enum { - WINE_GL_BUFFER_BACK = 0, - WINE_GL_BUFFER_FRONT -} WINE_GL_BUFFER_TYPE; - -typedef struct IDirect3DDeviceGLImpl -{ - struct IDirect3DDeviceImpl parent; - - GLXContext gl_context; - - /* This stores the textures which are actually bound to the GL context */ - IDirectDrawSurfaceImpl *current_bound_texture[MAX_TEXTURES]; - - /* The last type of vertex drawn */ - GL_TRANSFORM_STATE transform_state; - - /* Used to handle fogging faster... */ - BYTE fog_table[3 * 0x10000]; /* 3 is for R, G and B - 0x10000 is 0xFF for the vertex color and - 0xFF for the fog intensity */ - - Display *display; - Drawable drawable; - - /* Variables used for the flush to frame-buffer code using the texturing code */ - GLuint unlock_tex; - void *surface_ptr; - GLenum current_internal_format; - - /* 0 is back-buffer, 1 is front-buffer */ - SURFACE_STATE state[2]; - IDirectDrawSurfaceImpl *lock_surf[2]; - RECT lock_rect[2]; - /* This is just here to print-out a nice warning if we have two successive locks */ - BOOLEAN lock_rect_valid[2]; - - /* This is used to optimize some stuff */ - DWORD prev_clear_color; - DWORD prev_clear_stencil; - D3DVALUE prev_clear_Z; - BOOLEAN depth_mask, depth_test, alpha_test, stencil_test, cull_face, lighting, blending, fogging; - GLenum current_alpha_test_func; - GLclampf current_alpha_test_ref; - GLenum current_tex_env; - GLenum current_active_tex_unit; -} IDirect3DDeviceGLImpl; - -/* This is for the OpenGL additions... */ -typedef struct { - struct IDirect3DVertexBufferImpl parent; - - DWORD dwVertexTypeDesc; - D3DMATRIX world_mat, view_mat, proj_mat; - LPVOID vertices; -} IDirect3DVertexBufferGLImpl; - -/* This is for GL extension support. - - This can contain either only a boolean if no function pointer exists or a set - of function pointers. -*/ -typedef struct { - /* Mirrored Repeat */ - BOOLEAN mirrored_repeat; - /* Mipmap lod-bias */ - BOOLEAN mipmap_lodbias; - /* Multi-texturing */ - GLint max_texture_units; - void (*glActiveTexture)(GLenum texture); - void (*glMultiTexCoord[4])(GLenum target, const GLfloat *v); - void (*glClientActiveTexture)(GLenum texture); - /* S3TC/DXTN compressed texture */ - BOOLEAN s3tc_compressed_texture; - void (*glCompressedTexImage2D)(GLenum target, GLint level, GLenum internalformat, GLsizei width, - GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); - void (*glCompressedTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, - GLsizei width, GLsizei height, GLsizei imageSize, const GLvoid *data); -} GL_EXTENSIONS_LIST; -extern GL_EXTENSIONS_LIST GL_extensions; - -/* All non-static functions 'exported' by various sub-objects */ -extern HRESULT direct3d_create(IDirectDrawImpl *This); -extern HRESULT d3dtexture_create(IDirectDrawImpl *d3d, IDirectDrawSurfaceImpl *surf, BOOLEAN at_creation, IDirectDrawSurfaceImpl *main_surf); -extern HRESULT d3dlight_create(IDirect3DLightImpl **obj, IDirectDrawImpl *d3d); -extern HRESULT d3dexecutebuffer_create(IDirect3DExecuteBufferImpl **obj, IDirectDrawImpl *d3d, IDirect3DDeviceImpl *d3ddev, LPD3DEXECUTEBUFFERDESC lpDesc); -extern HRESULT d3dmaterial_create(IDirect3DMaterialImpl **obj, IDirectDrawImpl *d3d); -extern HRESULT d3dviewport_create(IDirect3DViewportImpl **obj, IDirectDrawImpl *d3d); -extern HRESULT d3dvertexbuffer_create(IDirect3DVertexBufferImpl **obj, IDirectDrawImpl *d3d, LPD3DVERTEXBUFFERDESC lpD3DVertBufDesc, DWORD dwFlags); -extern HRESULT d3ddevice_create(IDirect3DDeviceImpl **obj, IDirectDrawImpl *d3d, IDirectDrawSurfaceImpl *surface, int version); - -/* Used for Direct3D to request the device to enumerate itself */ -extern HRESULT d3ddevice_enumerate(LPD3DENUMDEVICESCALLBACK cb, LPVOID context, DWORD version) ; -extern HRESULT d3ddevice_enumerate7(LPD3DENUMDEVICESCALLBACK7 cb, LPVOID context) ; -extern HRESULT d3ddevice_find(IDirectDrawImpl *d3d, LPD3DFINDDEVICESEARCH lpD3DDFS, LPD3DFINDDEVICERESULT lplpD3DDevice); - -/* Used by the DLL init routine to set-up the GL context and stuff properly */ -extern BOOL d3ddevice_init_at_startup(void *gl_handle); - -/* Used to upload the texture */ -extern HRESULT gltex_upload_texture(IDirectDrawSurfaceImpl *This, IDirect3DDeviceImpl *d3ddev, DWORD stage) ; - -/* Used to get the texture name */ -extern GLuint gltex_get_tex_name(IDirectDrawSurfaceImpl *This) ; - -/* Used to set-up our orthographic projection */ -extern void d3ddevice_set_ortho(IDirect3DDeviceImpl *This) ; - -/* Rendering state management functions */ -extern void set_render_state(IDirect3DDeviceImpl* This, D3DRENDERSTATETYPE dwRenderStateType, STATEBLOCK *lpStateBlock); -extern void store_render_state(IDirect3DDeviceImpl *This, D3DRENDERSTATETYPE dwRenderStateType, DWORD dwRenderState, STATEBLOCK* lpStateBlock); -extern void get_render_state(IDirect3DDeviceImpl *This, D3DRENDERSTATETYPE dwRenderStateType, LPDWORD lpdwRenderState, STATEBLOCK* lpStateBlock); -extern void apply_render_state(IDirect3DDeviceImpl* This, STATEBLOCK* lpStateBlock); - -/* Memory to texture conversion code. Split in three functions to do some optimizations. */ -extern HRESULT upload_surface_to_tex_memory_init(IDirectDrawSurfaceImpl *surface, GLuint level, GLenum *prev_internal_format, - BOOLEAN need_to_alloc, BOOLEAN need_alpha_ck, DWORD tex_width, DWORD tex_height); -extern HRESULT upload_surface_to_tex_memory(RECT *rect, DWORD xoffset, DWORD yoffset, void **temp_buffer); -extern HRESULT upload_surface_to_tex_memory_release(void); - -/* Some utilities functions needed to be shared.. */ -extern GLenum convert_D3D_compare_to_GL(D3DCMPFUNC dwRenderState) ; - -#endif /* HAVE_OPENGL */ - -#endif /* __GRAPHICS_WINE_MESA_PRIVATE_H */ diff --git a/dlls/ddraw/opengl_utils.c b/dlls/ddraw/opengl_utils.c deleted file mode 100644 index a2b021985a..0000000000 --- a/dlls/ddraw/opengl_utils.c +++ /dev/null @@ -1,1326 +0,0 @@ -/* Direct3D Common functions - * Copyright (c) 1998 Lionel ULMER - * - * This file contains all MESA common code - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "config.h" - -#include - -#define NONAMELESSUNION -#define NONAMELESSSTRUCT -#include "windef.h" -#include "winbase.h" -#include "objbase.h" -#include "wingdi.h" -#include "ddraw.h" -#include "d3d.h" -#include "wine/debug.h" - -#include "opengl_private.h" - -WINE_DEFAULT_DEBUG_CHANNEL(ddraw); - -GLenum convert_D3D_compare_to_GL(D3DCMPFUNC dwRenderState) -{ - switch (dwRenderState) { - case D3DCMP_NEVER: return GL_NEVER; - case D3DCMP_LESS: return GL_LESS; - case D3DCMP_EQUAL: return GL_EQUAL; - case D3DCMP_LESSEQUAL: return GL_LEQUAL; - case D3DCMP_GREATER: return GL_GREATER; - case D3DCMP_NOTEQUAL: return GL_NOTEQUAL; - case D3DCMP_GREATEREQUAL: return GL_GEQUAL; - case D3DCMP_ALWAYS: return GL_ALWAYS; - default: ERR("Unexpected compare type %d !\n", dwRenderState); - } - return GL_ALWAYS; -} - -GLenum convert_D3D_stencilop_to_GL(D3DSTENCILOP dwRenderState) -{ - switch (dwRenderState) { - case D3DSTENCILOP_KEEP: return GL_KEEP; - case D3DSTENCILOP_ZERO: return GL_ZERO; - case D3DSTENCILOP_REPLACE: return GL_REPLACE; - case D3DSTENCILOP_INCRSAT: return GL_INCR; - case D3DSTENCILOP_DECRSAT: return GL_DECR; - case D3DSTENCILOP_INVERT: return GL_INVERT; - case D3DSTENCILOP_INCR: WARN("D3DSTENCILOP_INCR not properly handled !\n"); return GL_INCR; - case D3DSTENCILOP_DECR: WARN("D3DSTENCILOP_DECR not properly handled !\n"); return GL_DECR; - default: ERR("Unexpected compare type %d !\n", dwRenderState); - } - return GL_KEEP; -} - -GLenum convert_D3D_blendop_to_GL(D3DBLEND dwRenderState) -{ - switch ((D3DBLEND) dwRenderState) { - case D3DBLEND_ZERO: return GL_ZERO; - case D3DBLEND_ONE: return GL_ONE; - case D3DBLEND_SRCALPHA: return GL_SRC_ALPHA; - case D3DBLEND_INVSRCALPHA: return GL_ONE_MINUS_SRC_ALPHA; - case D3DBLEND_DESTALPHA: return GL_DST_ALPHA; - case D3DBLEND_INVDESTALPHA: return GL_ONE_MINUS_DST_ALPHA; - case D3DBLEND_DESTCOLOR: return GL_DST_COLOR; - case D3DBLEND_INVDESTCOLOR: return GL_ONE_MINUS_DST_COLOR; - case D3DBLEND_SRCALPHASAT: return GL_SRC_ALPHA_SATURATE; - case D3DBLEND_SRCCOLOR: return GL_SRC_COLOR; - case D3DBLEND_INVSRCCOLOR: return GL_ONE_MINUS_SRC_COLOR; - default: ERR("Unhandled blend mode %d !\n", dwRenderState); return GL_ZERO; - } -} - -void set_render_state(IDirect3DDeviceImpl* This, - D3DRENDERSTATETYPE dwRenderStateType, STATEBLOCK *lpStateBlock) -{ - DWORD dwRenderState = lpStateBlock->render_state[dwRenderStateType - 1]; - IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This; - - TRACE("%s = %08lx\n", _get_renderstate(dwRenderStateType), dwRenderState); - - /* First, all the stipple patterns */ - if ((dwRenderStateType >= D3DRENDERSTATE_STIPPLEPATTERN00) && - (dwRenderStateType <= D3DRENDERSTATE_STIPPLEPATTERN31)) { - ERR("Unhandled dwRenderStateType stipple %d!\n",dwRenderStateType); - } else { - ENTER_GL(); - - /* All others state variables */ - switch (dwRenderStateType) { - case D3DRENDERSTATE_TEXTUREHANDLE: { /* 1 */ - IDirectDrawSurfaceImpl *tex = (IDirectDrawSurfaceImpl*) dwRenderState; - - IDirect3DDevice7_SetTexture(ICOM_INTERFACE(This, IDirect3DDevice7), - 0, - ICOM_INTERFACE(tex, IDirectDrawSurface7)); - } break; - - case D3DRENDERSTATE_ANTIALIAS: /* 2 */ - if (dwRenderState) - ERR("D3DRENDERSTATE_ANTIALIAS not supported yet !\n"); - break; - - case D3DRENDERSTATE_TEXTUREADDRESSU: /* 44 */ - case D3DRENDERSTATE_TEXTUREADDRESSV: /* 45 */ - case D3DRENDERSTATE_TEXTUREADDRESS: { /* 3 */ - D3DTEXTURESTAGESTATETYPE d3dTexStageStateType; - - if (dwRenderStateType == D3DRENDERSTATE_TEXTUREADDRESS) d3dTexStageStateType = D3DTSS_ADDRESS; - else if (dwRenderStateType == D3DRENDERSTATE_TEXTUREADDRESSU) d3dTexStageStateType = D3DTSS_ADDRESSU; - else d3dTexStageStateType = D3DTSS_ADDRESSV; - - IDirect3DDevice7_SetTextureStageState(ICOM_INTERFACE(This, IDirect3DDevice7), - 0, d3dTexStageStateType, - dwRenderState); - } break; - - case D3DRENDERSTATE_TEXTUREPERSPECTIVE: /* 4 */ - if (dwRenderState) - glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); - else - glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); - break; - - case D3DRENDERSTATE_WRAPU: /* 5 */ - case D3DRENDERSTATE_WRAPV: /* 6 */ - case D3DRENDERSTATE_WRAP0: /* 128 */ - case D3DRENDERSTATE_WRAP1: /* 129 */ - case D3DRENDERSTATE_WRAP2: /* 130 */ - case D3DRENDERSTATE_WRAP3: /* 131 */ - case D3DRENDERSTATE_WRAP4: /* 132 */ - case D3DRENDERSTATE_WRAP5: /* 133 */ - case D3DRENDERSTATE_WRAP6: /* 134 */ - case D3DRENDERSTATE_WRAP7: /* 135 */ - if (dwRenderState) - ERR("Texture WRAP modes unsupported by OpenGL.. Expect graphical glitches !\n"); - break; - - case D3DRENDERSTATE_ZENABLE: /* 7 */ - /* To investigate : in OpenGL, if we disable the depth test, the Z buffer will NOT be - updated either.. No idea about what happens in D3D. - - Maybe replacing the Z function by ALWAYS would be a better idea. */ - if (dwRenderState == D3DZB_TRUE) { - if (glThis->depth_test == FALSE) { - glEnable(GL_DEPTH_TEST); - glThis->depth_test = TRUE; - } - } else if (dwRenderState == D3DZB_FALSE) { - if (glThis->depth_test) { - glDisable(GL_DEPTH_TEST); - glThis->depth_test = FALSE; - } - } else { - if (glThis->depth_test == FALSE) { - glEnable(GL_DEPTH_TEST); - glThis->depth_test = TRUE; - } - WARN(" w-buffering not supported.\n"); - } - break; - - case D3DRENDERSTATE_FILLMODE: /* 8 */ - switch ((D3DFILLMODE) dwRenderState) { - case D3DFILL_POINT: - glPolygonMode(GL_FRONT_AND_BACK,GL_POINT); - break; - case D3DFILL_WIREFRAME: - glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); - break; - case D3DFILL_SOLID: - glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); - break; - default: - ERR("Unhandled fill mode %ld !\n",dwRenderState); - } - break; - - case D3DRENDERSTATE_SHADEMODE: /* 9 */ - switch ((D3DSHADEMODE) dwRenderState) { - case D3DSHADE_FLAT: - glShadeModel(GL_FLAT); - break; - case D3DSHADE_GOURAUD: - glShadeModel(GL_SMOOTH); - break; - default: - ERR("Unhandled shade mode %ld !\n",dwRenderState); - } - break; - - case D3DRENDERSTATE_ZWRITEENABLE: /* 14 */ - if ((dwRenderState != FALSE) && (glThis->depth_mask == FALSE)) - glDepthMask(GL_TRUE); - else if ((dwRenderState == FALSE) && (glThis->depth_mask != FALSE)) - glDepthMask(GL_FALSE); - glThis->depth_mask = dwRenderState; - break; - - case D3DRENDERSTATE_ALPHATESTENABLE: /* 15 */ - if ((dwRenderState != 0) && (glThis->alpha_test == FALSE)) - glEnable(GL_ALPHA_TEST); - else if ((dwRenderState == 0) && (glThis->alpha_test != FALSE)) - glDisable(GL_ALPHA_TEST); - glThis->alpha_test = dwRenderState; - break; - - case D3DRENDERSTATE_TEXTUREMAG: { /* 17 */ - DWORD tex_mag = 0xFFFFFFFF; - - switch ((D3DTEXTUREFILTER) dwRenderState) { - case D3DFILTER_NEAREST: - tex_mag = D3DTFG_POINT; - break; - case D3DFILTER_LINEAR: - tex_mag = D3DTFG_LINEAR; - break; - default: - ERR("Unhandled texture mag %ld !\n",dwRenderState); - } - - if (tex_mag != 0xFFFFFFFF) { - IDirect3DDevice7_SetTextureStageState(ICOM_INTERFACE(This, IDirect3DDevice7), 0, D3DTSS_MAGFILTER, tex_mag); - } - } break; - - case D3DRENDERSTATE_TEXTUREMIN: { /* 18 */ - DWORD tex_min = 0xFFFFFFFF; - - switch ((D3DTEXTUREFILTER) dwRenderState) { - case D3DFILTER_NEAREST: - tex_min = D3DTFN_POINT; - break; - case D3DFILTER_LINEAR: - tex_min = D3DTFN_LINEAR; - break; - default: - ERR("Unhandled texture min %ld !\n",dwRenderState); - } - - if (tex_min != 0xFFFFFFFF) { - IDirect3DDevice7_SetTextureStageState(ICOM_INTERFACE(This, IDirect3DDevice7), 0, D3DTSS_MINFILTER, tex_min); - } - } break; - - case D3DRENDERSTATE_SRCBLEND: /* 19 */ - case D3DRENDERSTATE_DESTBLEND: /* 20 */ - glBlendFunc(convert_D3D_blendop_to_GL(lpStateBlock->render_state[D3DRENDERSTATE_SRCBLEND - 1]), - convert_D3D_blendop_to_GL(lpStateBlock->render_state[D3DRENDERSTATE_DESTBLEND - 1])); - break; - - case D3DRENDERSTATE_TEXTUREMAPBLEND: { /* 21 */ - IDirect3DDevice7 *d3ddev = ICOM_INTERFACE(This, IDirect3DDevice7); - - switch ((D3DTEXTUREBLEND) dwRenderState) { - case D3DTBLEND_DECAL: - if (glThis->current_tex_env != GL_REPLACE) { - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - glThis->current_tex_env = GL_REPLACE; - } - break; - case D3DTBLEND_DECALALPHA: - if (glThis->current_tex_env != GL_REPLACE) { - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); - glThis->current_tex_env = GL_DECAL; - } - break; - case D3DTBLEND_MODULATE: - if (glThis->current_tex_env != GL_MODULATE) { - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glThis->current_tex_env = GL_MODULATE; - } - break; - case D3DTBLEND_MODULATEALPHA: - IDirect3DDevice7_SetTextureStageState(d3ddev, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE); - IDirect3DDevice7_SetTextureStageState(d3ddev, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); - IDirect3DDevice7_SetTextureStageState(d3ddev, 0, D3DTSS_COLORARG2, D3DTA_CURRENT); - IDirect3DDevice7_SetTextureStageState(d3ddev, 0, D3DTSS_ALPHAARG2, D3DTA_CURRENT); - IDirect3DDevice7_SetTextureStageState(d3ddev, 0, D3DTSS_COLOROP, D3DTOP_MODULATE); - IDirect3DDevice7_SetTextureStageState(d3ddev, 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); - break; - default: - ERR("Unhandled texture environment %ld !\n",dwRenderState); - } - } break; - - case D3DRENDERSTATE_CULLMODE: /* 22 */ - switch ((D3DCULL) dwRenderState) { - case D3DCULL_NONE: - if (glThis->cull_face != 0) { - glDisable(GL_CULL_FACE); - glThis->cull_face = 0; - } - break; - case D3DCULL_CW: - if (glThis->cull_face == 0) { - glEnable(GL_CULL_FACE); - glThis->cull_face = 1; - } - glFrontFace(GL_CCW); - glCullFace(GL_BACK); - break; - case D3DCULL_CCW: - if (glThis->cull_face == 0) { - glEnable(GL_CULL_FACE); - glThis->cull_face = 1; - } - glFrontFace(GL_CW); - glCullFace(GL_BACK); - break; - default: - ERR("Unhandled cull mode %ld !\n",dwRenderState); - } - break; - - case D3DRENDERSTATE_ZFUNC: /* 23 */ - glDepthFunc(convert_D3D_compare_to_GL(dwRenderState)); - break; - - case D3DRENDERSTATE_ALPHAREF: /* 24 */ - case D3DRENDERSTATE_ALPHAFUNC: { /* 25 */ - GLenum func = convert_D3D_compare_to_GL(lpStateBlock->render_state[D3DRENDERSTATE_ALPHAFUNC - 1]); - GLclampf ref = (lpStateBlock->render_state[D3DRENDERSTATE_ALPHAREF - 1] & 0x000000FF) / 255.0; - - if ((func != glThis->current_alpha_test_func) || (ref != glThis->current_alpha_test_ref)) { - glAlphaFunc(func, ref); - glThis->current_alpha_test_func = func; - glThis->current_alpha_test_ref = ref; - } - } - break; - - case D3DRENDERSTATE_DITHERENABLE: /* 26 */ - if (dwRenderState) - glEnable(GL_DITHER); - else - glDisable(GL_DITHER); - break; - - case D3DRENDERSTATE_ALPHABLENDENABLE: /* 27 */ - if ((dwRenderState != 0) && (glThis->blending == 0)) { - glEnable(GL_BLEND); - } else if ((dwRenderState == 0) && (glThis->blending != 0)) { - glDisable(GL_BLEND); - } - glThis->blending = dwRenderState; - - /* Hack for some old games ... */ - if (glThis->parent.version == 1) { - lpStateBlock->render_state[D3DRENDERSTATE_COLORKEYENABLE - 1] = dwRenderState; - } - break; - - case D3DRENDERSTATE_FOGENABLE: /* 28 */ - /* Nothing to do here. Only the storage matters :-) */ - break; - - case D3DRENDERSTATE_SPECULARENABLE: /* 29 */ - if (dwRenderState) - ERR(" Specular Lighting not supported yet.\n"); - break; - - case D3DRENDERSTATE_SUBPIXEL: /* 31 */ - case D3DRENDERSTATE_SUBPIXELX: /* 32 */ - /* We do not support this anyway, so why protest :-) */ - break; - - case D3DRENDERSTATE_STIPPLEDALPHA: /* 33 */ - if (dwRenderState) - ERR(" Stippled Alpha not supported yet.\n"); - break; - - case D3DRENDERSTATE_FOGCOLOR: { /* 34 */ - GLfloat color[4]; - color[0] = ((dwRenderState >> 16) & 0xFF)/255.0f; - color[1] = ((dwRenderState >> 8) & 0xFF)/255.0f; - color[2] = ((dwRenderState >> 0) & 0xFF)/255.0f; - color[3] = ((dwRenderState >> 24) & 0xFF)/255.0f; - glFogfv(GL_FOG_COLOR,color); - /* Note: glFogiv does not seem to work */ - } break; - - case D3DRENDERSTATE_FOGTABLEMODE: /* 35 */ - case D3DRENDERSTATE_FOGVERTEXMODE: /* 140 */ - case D3DRENDERSTATE_FOGSTART: /* 36 */ - case D3DRENDERSTATE_FOGEND: /* 37 */ - /* Nothing to do here. Only the storage matters :-) */ - break; - - case D3DRENDERSTATE_FOGDENSITY: /* 38 */ - glFogi(GL_FOG_DENSITY,*(float*)&dwRenderState); - break; - - case D3DRENDERSTATE_COLORKEYENABLE: /* 41 */ - /* Nothing done here, only storage matters. */ - break; - - case D3DRENDERSTATE_MIPMAPLODBIAS: /* 46 */ - IDirect3DDevice7_SetTextureStageState(ICOM_INTERFACE(This, IDirect3DDevice7), - 0, D3DTSS_MIPMAPLODBIAS, - dwRenderState); - break; - - case D3DRENDERSTATE_ZBIAS: /* 47 */ - /* This is a tad bit hacky.. But well, no idea how to do it better in OpenGL :-/ */ - if (dwRenderState == 0) { - glDisable(GL_POLYGON_OFFSET_FILL); - glDisable(GL_POLYGON_OFFSET_LINE); - glDisable(GL_POLYGON_OFFSET_POINT); - } else { - glEnable(GL_POLYGON_OFFSET_FILL); - glEnable(GL_POLYGON_OFFSET_LINE); - glEnable(GL_POLYGON_OFFSET_POINT); - glPolygonOffset(1.0, dwRenderState * 1.0); - } - break; - - case D3DRENDERSTATE_FLUSHBATCH: /* 50 */ - break; - - case D3DRENDERSTATE_STENCILENABLE: /* 52 */ - if ((dwRenderState != 0) && (glThis->stencil_test == 0)) - glEnable(GL_STENCIL_TEST); - else if ((dwRenderState == 0) && (glThis->stencil_test != 0)) - glDisable(GL_STENCIL_TEST); - glThis->stencil_test = dwRenderState; - break; - - case D3DRENDERSTATE_STENCILFAIL: /* 53 */ - case D3DRENDERSTATE_STENCILZFAIL: /* 54 */ - case D3DRENDERSTATE_STENCILPASS: /* 55 */ - glStencilOp(convert_D3D_stencilop_to_GL(lpStateBlock->render_state[D3DRENDERSTATE_STENCILFAIL - 1]), - convert_D3D_stencilop_to_GL(lpStateBlock->render_state[D3DRENDERSTATE_STENCILZFAIL - 1]), - convert_D3D_stencilop_to_GL(lpStateBlock->render_state[D3DRENDERSTATE_STENCILPASS - 1])); - break; - - case D3DRENDERSTATE_STENCILFUNC: /* 56 */ - case D3DRENDERSTATE_STENCILREF: /* 57 */ - case D3DRENDERSTATE_STENCILMASK: /* 58 */ - glStencilFunc(convert_D3D_compare_to_GL(lpStateBlock->render_state[D3DRENDERSTATE_STENCILFUNC - 1]), - lpStateBlock->render_state[D3DRENDERSTATE_STENCILREF - 1], - lpStateBlock->render_state[D3DRENDERSTATE_STENCILMASK - 1]); - break; - - case D3DRENDERSTATE_STENCILWRITEMASK: /* 59 */ - glStencilMask(dwRenderState); - break; - - case D3DRENDERSTATE_TEXTUREFACTOR: /* 60 */ - /* Only the storage matters... */ - break; - - case D3DRENDERSTATE_CLIPPING: /* 136 */ - case D3DRENDERSTATE_CLIPPLANEENABLE: { /* 152 */ - GLint i; - DWORD mask, runner; - - if (dwRenderStateType == D3DRENDERSTATE_CLIPPING) { - mask = ((dwRenderState) ? - (This->state_block.render_state[D3DRENDERSTATE_CLIPPLANEENABLE - 1]) : (0x00000000)); - } else { - mask = dwRenderState; - } - for (i = 0, runner = 0x00000001; i < This->max_clipping_planes; i++, runner = (runner << 1)) { - if (mask & runner) { - GLint enabled; - glGetIntegerv(GL_CLIP_PLANE0 + i, &enabled); - if (enabled == GL_FALSE) { - glEnable(GL_CLIP_PLANE0 + i); - /* Need to force a transform change so that this clipping plane parameters are sent - * properly to GL. - */ - glThis->transform_state = GL_TRANSFORM_NONE; - } - } else { - glDisable(GL_CLIP_PLANE0 + i); - } - } - } - break; - - case D3DRENDERSTATE_LIGHTING: /* 137 */ - /* Nothing to do, only storage matters... */ - break; - - case D3DRENDERSTATE_AMBIENT: { /* 139 */ - float light[4]; - - light[0] = ((dwRenderState >> 16) & 0xFF) / 255.0; - light[1] = ((dwRenderState >> 8) & 0xFF) / 255.0; - light[2] = ((dwRenderState >> 0) & 0xFF) / 255.0; - light[3] = ((dwRenderState >> 24) & 0xFF) / 255.0; - glLightModelfv(GL_LIGHT_MODEL_AMBIENT, (float *) light); - } break; - - case D3DRENDERSTATE_COLORVERTEX: /* 141 */ - /* Nothing to do here.. Only storage matters */ - break; - - case D3DRENDERSTATE_LOCALVIEWER: /* 142 */ - if (dwRenderState) - glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE); - else - glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_FALSE); - break; - - case D3DRENDERSTATE_NORMALIZENORMALS: /* 143 */ - if (dwRenderState) { - glEnable(GL_NORMALIZE); - glEnable(GL_RESCALE_NORMAL); - } else { - glDisable(GL_NORMALIZE); - glDisable(GL_RESCALE_NORMAL); - } - break; - - case D3DRENDERSTATE_DIFFUSEMATERIALSOURCE: /* 145 */ - case D3DRENDERSTATE_SPECULARMATERIALSOURCE: /* 146 */ - case D3DRENDERSTATE_AMBIENTMATERIALSOURCE: /* 147 */ - case D3DRENDERSTATE_EMISSIVEMATERIALSOURCE: /* 148 */ - /* Nothing to do here. Only the storage matters :-) */ - break; - - default: - ERR("Unhandled dwRenderStateType %s (%08x) value : %08lx !\n", - _get_renderstate(dwRenderStateType), dwRenderStateType, dwRenderState); - } - LEAVE_GL(); - } -} - -void store_render_state(IDirect3DDeviceImpl *This, - D3DRENDERSTATETYPE dwRenderStateType, DWORD dwRenderState, STATEBLOCK *lpStateBlock) -{ - TRACE("%s = %08lx\n", _get_renderstate(dwRenderStateType), dwRenderState); - - /* Some special cases first.. */ - if (dwRenderStateType == D3DRENDERSTATE_SRCBLEND) { - if (dwRenderState == D3DBLEND_BOTHSRCALPHA) { - lpStateBlock->render_state[D3DRENDERSTATE_SRCBLEND - 1] = D3DBLEND_SRCALPHA; - lpStateBlock->render_state[D3DRENDERSTATE_DESTBLEND - 1] = D3DBLEND_INVSRCALPHA; - return; - } else if (dwRenderState == D3DBLEND_BOTHINVSRCALPHA) { - lpStateBlock->render_state[D3DRENDERSTATE_SRCBLEND - 1] = D3DBLEND_INVSRCALPHA; - lpStateBlock->render_state[D3DRENDERSTATE_DESTBLEND - 1] = D3DBLEND_SRCALPHA; - return; - } - } else if (dwRenderStateType == D3DRENDERSTATE_TEXTUREADDRESS) { - lpStateBlock->render_state[D3DRENDERSTATE_TEXTUREADDRESSU - 1] = dwRenderState; - lpStateBlock->render_state[D3DRENDERSTATE_TEXTUREADDRESSV - 1] = dwRenderState; - } else if (dwRenderStateType == D3DRENDERSTATE_WRAPU) { - if (dwRenderState) - lpStateBlock->render_state[D3DRENDERSTATE_WRAP0] |= D3DWRAP_U; - else - lpStateBlock->render_state[D3DRENDERSTATE_WRAP0] &= ~D3DWRAP_U; - } else if (dwRenderStateType == D3DRENDERSTATE_WRAPV) { - if (dwRenderState) - lpStateBlock->render_state[D3DRENDERSTATE_WRAP0] |= D3DWRAP_V; - else - lpStateBlock->render_state[D3DRENDERSTATE_WRAP0] &= ~D3DWRAP_V; - } - - /* Default case */ - lpStateBlock->render_state[dwRenderStateType - 1] = dwRenderState; -} - -void get_render_state(IDirect3DDeviceImpl *This, - D3DRENDERSTATETYPE dwRenderStateType, LPDWORD lpdwRenderState, STATEBLOCK *lpStateBlock) -{ - *lpdwRenderState = lpStateBlock->render_state[dwRenderStateType - 1]; - if (TRACE_ON(ddraw)) - TRACE("%s = %08lx\n", _get_renderstate(dwRenderStateType), *lpdwRenderState); -} - -void apply_render_state(IDirect3DDeviceImpl *This, STATEBLOCK *lpStateBlock) -{ - DWORD i; - TRACE("(%p,%p)\n", This, lpStateBlock); - for(i = 0; i < HIGHEST_RENDER_STATE; i++) - if (lpStateBlock->set_flags.render_state[i]) - set_render_state(This, i + 1, lpStateBlock); -} - - -/* Texture management code. - - - upload_surface_to_tex_memory_init initialize the code and computes the GL formats - according to the surface description. - - - upload_surface_to_tex_memory does the real upload. If one buffer is split over - multiple textures, this can be called multiple times after the '_init' call. 'rect' - can be NULL if the whole buffer needs to be upload. - - - upload_surface_to_tex_memory_release does the clean-up. - - These functions are called in the following cases : - - texture management (ie to upload a D3D texture to GL when it changes). - - flush of the 'in-memory' frame buffer to the GL frame buffer using the texture - engine. - - use of the texture engine to simulate Blits to the 3D Device. -*/ -typedef enum { - NO_CONVERSION, - CONVERT_PALETTED, - CONVERT_CK_565, - CONVERT_CK_5551, - CONVERT_CK_4444, - CONVERT_CK_4444_ARGB, - CONVERT_CK_1555, - CONVERT_555, - CONVERT_CK_RGB24, - CONVERT_CK_8888, - CONVERT_CK_8888_ARGB, - CONVERT_RGB32_888 -} CONVERT_TYPES; - -/* Note : we suppose that all the code calling this is protected by the GL lock... Otherwise bad things - may happen :-) */ -static GLenum current_format; -static GLenum current_pixel_format; -static CONVERT_TYPES convert_type; -static IDirectDrawSurfaceImpl *current_surface; -static GLuint current_level; -static DWORD current_tex_width; -static DWORD current_tex_height; -static GLuint current_alignement_constraints; -static int current_storage_width; - -HRESULT upload_surface_to_tex_memory_init(IDirectDrawSurfaceImpl *surf_ptr, GLuint level, GLenum *current_internal_format, - BOOLEAN need_to_alloc, BOOLEAN need_alpha_ck, DWORD tex_width, DWORD tex_height) -{ - const DDPIXELFORMAT * const src_pf = &(surf_ptr->surface_desc.u4.ddpfPixelFormat); - BOOL error = FALSE; - BOOL colorkey_active = need_alpha_ck && (surf_ptr->surface_desc.dwFlags & DDSD_CKSRCBLT); - GLenum internal_format = GL_LUMINANCE; /* A bogus value to be sure to have a nice Mesa warning :-) */ - BYTE bpp = GET_BPP(surf_ptr->surface_desc); - BOOL sub_texture = TRUE; - - current_surface = surf_ptr; - current_level = level; - - if (src_pf->dwFlags & DDPF_FOURCC) { - GLenum retVal; - int size = surf_ptr->surface_desc.u1.dwLinearSize; - int width = surf_ptr->surface_desc.dwWidth; - int height = surf_ptr->surface_desc.dwHeight; - LPVOID buffer = surf_ptr->surface_desc.lpSurface; - - switch (src_pf->dwFourCC) { - case MAKE_FOURCC('D','X','T','1'): retVal = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; break; - case MAKE_FOURCC('D','X','T','3'): retVal = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; break; - case MAKE_FOURCC('D','X','T','5'): retVal = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; break; - default: - FIXME("FourCC Not supported\n"); - return DD_OK; - } - - if (GL_extensions.s3tc_compressed_texture) { - GL_extensions.glCompressedTexImage2D(GL_TEXTURE_2D, current_level, retVal, width, height, 0, size, buffer); - } else - ERR("Trying to upload S3TC texture whereas the device does not have support for it\n"); - - return DD_OK; - } - - /* First, do some sanity checks ... */ - if ((surf_ptr->surface_desc.u1.lPitch % bpp) != 0) { - FIXME("Warning : pitch is not a multiple of BPP - not supported yet !\n"); - } else { - /* In that case, no need to have any alignement constraints... */ - if (current_alignement_constraints != 1) { - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - current_alignement_constraints = 1; - } - } - - /* Note: we only check width here as you cannot have width non-zero while height is set to zero */ - if (tex_width == 0) { - sub_texture = FALSE; - - tex_width = surf_ptr->surface_desc.dwWidth; - tex_height = surf_ptr->surface_desc.dwHeight; - } - - current_tex_width = tex_width; - current_tex_height = tex_height; - - if (src_pf->dwFlags & DDPF_PALETTEINDEXED8) { - /* **************** - Paletted Texture - **************** */ - current_format = GL_RGBA; - internal_format = GL_RGBA; - current_pixel_format = GL_UNSIGNED_BYTE; - convert_type = CONVERT_PALETTED; - } else if (src_pf->dwFlags & DDPF_RGB) { - /* ************ - RGB Textures - ************ */ - if (src_pf->u1.dwRGBBitCount == 8) { - if ((src_pf->dwFlags & DDPF_ALPHAPIXELS) && - (src_pf->u5.dwRGBAlphaBitMask != 0x00)) { - error = TRUE; - } else { - if ((src_pf->u2.dwRBitMask == 0xE0) && - (src_pf->u3.dwGBitMask == 0x1C) && - (src_pf->u4.dwBBitMask == 0x03)) { - /* ********************** - GL_UNSIGNED_BYTE_3_3_2 - ********************** */ - if (colorkey_active) { - /* This texture format will never be used.. So do not care about color keying - up until the point in time it will be needed :-) */ - FIXME(" ColorKeying not supported in the RGB 332 format !\n"); - } - current_format = GL_RGB; - internal_format = GL_RGB; - current_pixel_format = GL_UNSIGNED_BYTE_3_3_2; - convert_type = NO_CONVERSION; - } else { - error = TRUE; - } - } - } else if (src_pf->u1.dwRGBBitCount == 16) { - if ((src_pf->dwFlags & DDPF_ALPHAPIXELS) && - (src_pf->u5.dwRGBAlphaBitMask != 0x0000)) { - if ((src_pf->u2.dwRBitMask == 0xF800) && - (src_pf->u3.dwGBitMask == 0x07C0) && - (src_pf->u4.dwBBitMask == 0x003E) && - (src_pf->u5.dwRGBAlphaBitMask == 0x0001)) { - current_format = GL_RGBA; - internal_format = GL_RGBA; - current_pixel_format = GL_UNSIGNED_SHORT_5_5_5_1; - if (colorkey_active) { - convert_type = CONVERT_CK_5551; - } else { - convert_type = NO_CONVERSION; - } - } else if ((src_pf->u2.dwRBitMask == 0xF000) && - (src_pf->u3.dwGBitMask == 0x0F00) && - (src_pf->u4.dwBBitMask == 0x00F0) && - (src_pf->u5.dwRGBAlphaBitMask == 0x000F)) { - current_format = GL_RGBA; - internal_format = GL_RGBA; - current_pixel_format = GL_UNSIGNED_SHORT_4_4_4_4; - if (colorkey_active) { - convert_type = CONVERT_CK_4444; - } else { - convert_type = NO_CONVERSION; - } - } else if ((src_pf->u2.dwRBitMask == 0x0F00) && - (src_pf->u3.dwGBitMask == 0x00F0) && - (src_pf->u4.dwBBitMask == 0x000F) && - (src_pf->u5.dwRGBAlphaBitMask == 0xF000)) { - if (colorkey_active) { - convert_type = CONVERT_CK_4444_ARGB; - current_format = GL_RGBA; - internal_format = GL_RGBA; - current_pixel_format = GL_UNSIGNED_SHORT_4_4_4_4; - } else { - convert_type = NO_CONVERSION; - current_format = GL_BGRA; - internal_format = GL_RGBA; - current_pixel_format = GL_UNSIGNED_SHORT_4_4_4_4_REV; - } - } else if ((src_pf->u2.dwRBitMask == 0x7C00) && - (src_pf->u3.dwGBitMask == 0x03E0) && - (src_pf->u4.dwBBitMask == 0x001F) && - (src_pf->u5.dwRGBAlphaBitMask == 0x8000)) { - if (colorkey_active) { - convert_type = CONVERT_CK_1555; - current_format = GL_RGBA; - internal_format = GL_RGBA; - current_pixel_format = GL_UNSIGNED_SHORT_5_5_5_1; - } else { - convert_type = NO_CONVERSION; - current_format = GL_BGRA; - internal_format = GL_RGBA; - current_pixel_format = GL_UNSIGNED_SHORT_1_5_5_5_REV; - } - } else { - error = TRUE; - } - } else { - if ((src_pf->u2.dwRBitMask == 0xF800) && - (src_pf->u3.dwGBitMask == 0x07E0) && - (src_pf->u4.dwBBitMask == 0x001F)) { - if (colorkey_active) { - convert_type = CONVERT_CK_565; - current_format = GL_RGBA; - internal_format = GL_RGBA; - current_pixel_format = GL_UNSIGNED_SHORT_5_5_5_1; - } else { - convert_type = NO_CONVERSION; - current_format = GL_RGB; - internal_format = GL_RGB; - current_pixel_format = GL_UNSIGNED_SHORT_5_6_5; - } - } else if ((src_pf->u2.dwRBitMask == 0x7C00) && - (src_pf->u3.dwGBitMask == 0x03E0) && - (src_pf->u4.dwBBitMask == 0x001F)) { - convert_type = CONVERT_555; - current_format = GL_RGBA; - internal_format = GL_RGBA; - current_pixel_format = GL_UNSIGNED_SHORT_5_5_5_1; - } else { - error = TRUE; - } - } - } else if (src_pf->u1.dwRGBBitCount == 24) { - if ((src_pf->dwFlags & DDPF_ALPHAPIXELS) && - (src_pf->u5.dwRGBAlphaBitMask != 0x000000)) { - error = TRUE; - } else { - if ((src_pf->u2.dwRBitMask == 0xFF0000) && - (src_pf->u3.dwGBitMask == 0x00FF00) && - (src_pf->u4.dwBBitMask == 0x0000FF)) { - if (colorkey_active) { - convert_type = CONVERT_CK_RGB24; - current_format = GL_RGBA; - internal_format = GL_RGBA; - current_pixel_format = GL_UNSIGNED_INT_8_8_8_8; - } else { - convert_type = NO_CONVERSION; - current_format = GL_BGR; - internal_format = GL_RGB; - current_pixel_format = GL_UNSIGNED_BYTE; - } - } else { - error = TRUE; - } - } - } else if (src_pf->u1.dwRGBBitCount == 32) { - if ((src_pf->dwFlags & DDPF_ALPHAPIXELS) && - (src_pf->u5.dwRGBAlphaBitMask != 0x00000000)) { - if ((src_pf->u2.dwRBitMask == 0xFF000000) && - (src_pf->u3.dwGBitMask == 0x00FF0000) && - (src_pf->u4.dwBBitMask == 0x0000FF00) && - (src_pf->u5.dwRGBAlphaBitMask == 0x000000FF)) { - if (colorkey_active) { - convert_type = CONVERT_CK_8888; - } else { - convert_type = NO_CONVERSION; - } - current_format = GL_RGBA; - internal_format = GL_RGBA; - current_pixel_format = GL_UNSIGNED_INT_8_8_8_8; - } else if ((src_pf->u2.dwRBitMask == 0x00FF0000) && - (src_pf->u3.dwGBitMask == 0x0000FF00) && - (src_pf->u4.dwBBitMask == 0x000000FF) && - (src_pf->u5.dwRGBAlphaBitMask == 0xFF000000)) { - if (colorkey_active) { - convert_type = CONVERT_CK_8888_ARGB; - current_format = GL_RGBA; - internal_format = GL_RGBA; - current_pixel_format = GL_UNSIGNED_INT_8_8_8_8; - } else { - convert_type = NO_CONVERSION; - current_format = GL_BGRA; - internal_format = GL_RGBA; - current_pixel_format = GL_UNSIGNED_INT_8_8_8_8_REV; - } - } else { - error = TRUE; - } - } else { - if ((src_pf->u2.dwRBitMask == 0x00FF0000) && - (src_pf->u3.dwGBitMask == 0x0000FF00) && - (src_pf->u4.dwBBitMask == 0x000000FF)) { - if (need_alpha_ck) { - convert_type = CONVERT_RGB32_888; - current_format = GL_RGBA; - internal_format = GL_RGBA; - current_pixel_format = GL_UNSIGNED_INT_8_8_8_8; - } else { - convert_type = NO_CONVERSION; - current_format = GL_BGRA; - internal_format = GL_RGBA; - current_pixel_format = GL_UNSIGNED_INT_8_8_8_8_REV; - } - } else { - error = TRUE; - } - } - } else { - error = TRUE; - } - } else { - error = TRUE; - } - - if (error) { - ERR("Unsupported pixel format for textures :\n"); - if (ERR_ON(ddraw)) { - DDRAW_dump_pixelformat(src_pf); - } - return DDERR_INVALIDPIXELFORMAT; - } else { - if ((need_to_alloc) || - (internal_format != *current_internal_format)) { - glTexImage2D(GL_TEXTURE_2D, level, internal_format, - tex_width, tex_height, 0, - current_format, current_pixel_format, NULL); - *current_internal_format = internal_format; - } - } - - if (sub_texture && (convert_type == NO_CONVERSION)) { - current_storage_width = surf_ptr->surface_desc.u1.lPitch / bpp; - } else { - if (surf_ptr->surface_desc.u1.lPitch == (surf_ptr->surface_desc.dwWidth * bpp)) { - current_storage_width = 0; - } else { - current_storage_width = surf_ptr->surface_desc.u1.lPitch / bpp; - } - } - glPixelStorei(GL_UNPACK_ROW_LENGTH, current_storage_width); - - TRACE(" initialized texture upload for level %d with conversion %d.\n", current_level, convert_type); - - return DD_OK; -} - -HRESULT upload_surface_to_tex_memory(RECT *rect, DWORD xoffset, DWORD yoffset, void **temp_buffer) -{ - const DDSURFACEDESC * const src_d = (DDSURFACEDESC *)&(current_surface->surface_desc); - void *surf_buffer = NULL; - RECT lrect; - DWORD width, height; - BYTE bpp = GET_BPP(current_surface->surface_desc); - int line_increase; - - if (rect == NULL) { - lrect.top = 0; - lrect.left = 0; - lrect.bottom = current_tex_height; - lrect.right = current_tex_width; - rect = &lrect; - } - - width = rect->right - rect->left; - height = rect->bottom - rect->top; - - if (current_surface->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC) { - GLint retVal; - int size = current_surface->surface_desc.u1.dwLinearSize; - int width_ = current_surface->surface_desc.dwWidth; - int height_ = current_surface->surface_desc.dwHeight; - LPVOID buffer = current_surface->surface_desc.lpSurface; - - switch (current_surface->surface_desc.u4.ddpfPixelFormat.dwFourCC) { - case MAKE_FOURCC('D','X','T','1'): retVal = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; break; - case MAKE_FOURCC('D','X','T','3'): retVal = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; break; - case MAKE_FOURCC('D','X','T','5'): retVal = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; break; - default: - FIXME("Not supported\n"); - return DD_OK; - } - - if (GL_extensions.s3tc_compressed_texture) { - /* GL_extensions.glCompressedTexSubImage2D(GL_TEXTURE_2D, current_level, xoffset, yoffset, width, height, retVal, (unsigned char*)temp_buffer); */ - GL_extensions.glCompressedTexImage2D(GL_TEXTURE_2D, current_level, retVal, width_, height_, 0, size, buffer); - } else - ERR("Trying to upload S3TC texture whereas the device does not have support for it\n"); - - return DD_OK; - } - - /* Used when converting stuff */ - line_increase = src_d->u1.lPitch - (width * bpp); - - switch (convert_type) { - case CONVERT_PALETTED: { - IDirectDrawPaletteImpl* pal = current_surface->palette; - BYTE table[256][4]; - unsigned int i; - unsigned int x, y; - BYTE *src = (BYTE *) (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top)), *dst; - - if (pal == NULL) { - /* Upload a black texture. The real one will be uploaded on palette change */ - WARN("Palettized texture Loading with a NULL palette !\n"); - memset(table, 0, 256 * 4); - } else { - /* Get the surface's palette */ - for (i = 0; i < 256; i++) { - table[i][0] = pal->palents[i].peRed; - table[i][1] = pal->palents[i].peGreen; - table[i][2] = pal->palents[i].peBlue; - if ((src_d->dwFlags & DDSD_CKSRCBLT) && - (i >= src_d->ddckCKSrcBlt.dwColorSpaceLowValue) && - (i <= src_d->ddckCKSrcBlt.dwColorSpaceHighValue)) - /* We should maybe here put a more 'neutral' color than the standard bright purple - one often used by application to prevent the nice purple borders when bi-linear - filtering is on */ - table[i][3] = 0x00; - else - table[i][3] = 0xFF; - } - } - - if (*temp_buffer == NULL) - *temp_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - current_tex_width * current_tex_height * sizeof(DWORD)); - dst = (BYTE *) *temp_buffer; - - for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) { - BYTE color = *src++; - *dst++ = table[color][0]; - *dst++ = table[color][1]; - *dst++ = table[color][2]; - *dst++ = table[color][3]; - } - src += line_increase; - } - } break; - - case CONVERT_CK_565: { - /* Converting the 565 format in 5551 packed to emulate color-keying. - - Note : in all these conversion, it would be best to average the averaging - pixels to get the color of the pixel that will be color-keyed to - prevent 'color bleeding'. This will be done later on if ever it is - too visible. - - Note2: when using color-keying + alpha, are the alpha bits part of the - color-space or not ? - */ - unsigned int x, y; - WORD *src = (WORD *) (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top)), *dst; - - if (*temp_buffer == NULL) - *temp_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - current_tex_width * current_tex_height * sizeof(WORD)); - dst = (WORD *) *temp_buffer; - - for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) { - WORD color = *src++; - *dst = ((color & 0xFFC0) | ((color & 0x1F) << 1)); - if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) || - (color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue)) - *dst |= 0x0001; - dst++; - } - src = (WORD *) (((BYTE *) src) + line_increase); - } - } break; - - case CONVERT_CK_5551: { - /* Change the alpha value of the color-keyed pixels to emulate color-keying. */ - unsigned int x, y; - WORD *src = (WORD *) (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top)), *dst; - - if (*temp_buffer == NULL) - *temp_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - current_tex_width * current_tex_height * sizeof(WORD)); - dst = (WORD *) *temp_buffer; - - for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) { - WORD color = *src++; - *dst = color & 0xFFFE; - if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) || - (color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue)) - *dst |= color & 0x0001; - dst++; - } - src = (WORD *) (((BYTE *) src) + line_increase); - } - } break; - - case CONVERT_CK_4444: { - /* Change the alpha value of the color-keyed pixels to emulate color-keying. */ - unsigned int x, y; - WORD *src = (WORD *) (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top)), *dst; - - if (*temp_buffer == NULL) - *temp_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - current_tex_width * current_tex_height * sizeof(WORD)); - dst = (WORD *) *temp_buffer; - - for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) { - WORD color = *src++; - *dst = color & 0xFFF0; - if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) || - (color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue)) - *dst |= color & 0x000F; - dst++; - } - src = (WORD *) (((BYTE *) src) + line_increase); - } - } break; - - case CONVERT_CK_4444_ARGB: { - /* Move the four Alpha bits... */ - unsigned int x, y; - WORD *src = (WORD *) (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top)), *dst; - - if (*temp_buffer == NULL) - *temp_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - current_tex_width * current_tex_height * sizeof(WORD)); - dst = (WORD *) *temp_buffer; - - for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) { - WORD color = *src++; - *dst = (color & 0x0FFF) << 4; - if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) || - (color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue)) - *dst |= (color & 0xF000) >> 12; - dst++; - } - src = (WORD *) (((BYTE *) src) + line_increase); - } - } break; - - case CONVERT_CK_1555: { - unsigned int x, y; - WORD *src = (WORD *) (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top)), *dst; - - if (*temp_buffer == NULL) - *temp_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - current_tex_width * current_tex_height * sizeof(WORD)); - dst = (WORD *) *temp_buffer; - - for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) { - WORD color = *src++; - *dst = (color & 0x7FFF) << 1; - if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) || - (color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue)) - *dst |= (color & 0x8000) >> 15; - dst++; - } - src = (WORD *) (((BYTE *) src) + line_increase); - } - } break; - - case CONVERT_555: { - /* Converting the 0555 format in 5551 packed */ - unsigned int x, y; - WORD *src = (WORD *) (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top)), *dst; - - if (*temp_buffer == NULL) - *temp_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - current_tex_width * current_tex_height * sizeof(WORD)); - dst = (WORD *) *temp_buffer; - - if (src_d->dwFlags & DDSD_CKSRCBLT) { - for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) { - WORD color = *src++; - *dst = (color & 0x7FFF) << 1; - if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) || - (color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue)) - *dst |= 0x0001; - dst++; - } - src = (WORD *) (((BYTE *) src) + line_increase); - } - } else { - for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) { - WORD color = *src++; - *dst++ = ((color & 0x7FFF) << 1) | 0x0001; - } - src = (WORD *) (((BYTE *) src) + line_increase); - } - } - - } break; - - case CONVERT_CK_RGB24: { - /* This is a pain :-) */ - unsigned int x, y; - BYTE *src = (BYTE *) (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top)); - DWORD *dst; - - if (*temp_buffer == NULL) - *temp_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - current_tex_width * current_tex_height * sizeof(DWORD)); - dst = (DWORD *) *temp_buffer; - - for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) { - DWORD color = *((DWORD *) src) & 0x00FFFFFF; - src += 3; - *dst = color << 8; - if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) || - (color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue)) - *dst |= 0xFF; - dst++; - } - src += line_increase; - } - } break; - - case CONVERT_CK_8888: { - /* Just use the alpha component to handle color-keying... */ - unsigned int x, y; - DWORD *src = (DWORD *) (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top)), *dst; - - if (*temp_buffer == NULL) - *temp_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - current_tex_width * current_tex_height * sizeof(DWORD)); - dst = (DWORD *) *temp_buffer; - - for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) { - DWORD color = *src++; - *dst = color & 0xFFFFFF00; - if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) || - (color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue)) - *dst |= color & 0x000000FF; - dst++; - } - src = (DWORD *) (((BYTE *) src) + line_increase); - } - } break; - - case CONVERT_CK_8888_ARGB: { - unsigned int x, y; - DWORD *src = (DWORD *) (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top)), *dst; - - if (*temp_buffer == NULL) - *temp_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - current_tex_width * current_tex_height * sizeof(DWORD)); - dst = (DWORD *) *temp_buffer; - - for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) { - DWORD color = *src++; - *dst = (color & 0x00FFFFFF) << 8; - if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) || - (color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue)) - *dst |= (color & 0xFF000000) >> 24; - dst++; - } - src = (DWORD *) (((BYTE *) src) + line_increase); - } - } break; - - case CONVERT_RGB32_888: { - /* Just add an alpha component and handle color-keying... */ - unsigned int x, y; - DWORD *src = (DWORD *) (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top)), *dst; - - if (*temp_buffer == NULL) - *temp_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - current_tex_width * current_tex_height * sizeof(DWORD)); - dst = (DWORD *) *temp_buffer; - - if (src_d->dwFlags & DDSD_CKSRCBLT) { - for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) { - DWORD color = *src++; - *dst = color << 8; - if ((color < src_d->ddckCKSrcBlt.dwColorSpaceLowValue) || - (color > src_d->ddckCKSrcBlt.dwColorSpaceHighValue)) - *dst |= 0xFF; - dst++; - } - src = (DWORD *) (((BYTE *) src) + line_increase); - } - } else { - for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) { - *dst++ = (*src++ << 8) | 0xFF; - } - src = (DWORD *) (((BYTE *) src) + line_increase); - } - } - } break; - - case NO_CONVERSION: - /* Nothing to do here as the name suggests... Just set-up the buffer correctly */ - surf_buffer = (((BYTE *) src_d->lpSurface) + (bpp * rect->left) + (src_d->u1.lPitch * rect->top)); - break; - } - - if (convert_type != NO_CONVERSION) { - /* When doing conversion, the storage is always of width 'width' as there will never - be any Pitch issue... For now :-) - */ - surf_buffer = *temp_buffer; - if (width != current_storage_width) { - glPixelStorei(GL_UNPACK_ROW_LENGTH, width); - current_storage_width = width; - } - } - - glTexSubImage2D(GL_TEXTURE_2D, - current_level, - xoffset, yoffset, - width, height, - current_format, - current_pixel_format, - surf_buffer); - - return DD_OK; -} - -HRESULT upload_surface_to_tex_memory_release(void) -{ - current_surface = NULL; - - return DD_OK; -} diff --git a/dlls/ddraw/palette.c b/dlls/ddraw/palette.c new file mode 100644 index 0000000000..66b8844b64 --- /dev/null +++ b/dlls/ddraw/palette.c @@ -0,0 +1,240 @@ +/* DirectDraw - IDirectPalette base interface + * + * Copyright 2006 Stefan Dösinger + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include "winerror.h" +#include "wine/debug.h" + +#include +#include + +#include "ddraw_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(ddraw); + +/***************************************************************************** + * IDirectDrawPalette::QueryInterface + * + * A usual QueryInterface implementation. Can only Query IUnknown and + * IDirectDrawPalette + * + * Params: + * refiid: The interface id queried for + * obj: Address to return the interface pointer at + * + * Returns: + * S_OK on success + * E_NOINTERFACE if the requested interface wasn't found + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawPaletteImpl_QueryInterface(IDirectDrawPalette *iface, + REFIID refiid, + void **obj) +{ + ICOM_THIS_FROM(IDirectDrawPaletteImpl, IDirectDrawPalette, iface); + TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj); + + if (IsEqualGUID(refiid, &IID_IUnknown) + || IsEqualGUID(refiid, &IID_IDirectDrawPalette)) + { + *obj = iface; + IDirectDrawPalette_AddRef(iface); + return S_OK; + } + else + { + *obj = NULL; + return E_NOINTERFACE; + } +} + +/***************************************************************************** + * IDirectDrawPaletteImpl::AddRef + * + * Increases the refcount. + * + * Returns: + * The new refcount + * + *****************************************************************************/ +static ULONG WINAPI +IDirectDrawPaletteImpl_AddRef(IDirectDrawPalette *iface) +{ + ICOM_THIS_FROM(IDirectDrawPaletteImpl, IDirectDrawPalette, iface); + ULONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p)->() incrementing from %lu.\n", This, ref - 1); + + return ref; +} + +/***************************************************************************** + * IDirectDrawPaletteImpl::Release + * + * Reduces the refcount. If the refcount falls to 0, the object is destroyed + * + * Returns: + * The new refcount + * + *****************************************************************************/ +static ULONG WINAPI +IDirectDrawPaletteImpl_Release(IDirectDrawPalette *iface) +{ + ICOM_THIS_FROM(IDirectDrawPaletteImpl, IDirectDrawPalette, iface); + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p)->() decrementing from %lu.\n", This, ref + 1); + + if (ref == 0) + { + IWineD3DPalette_Release(This->wineD3DPalette); + HeapFree(GetProcessHeap(), 0, This); + } + + return ref; +} + +/***************************************************************************** + * IDirectDrawPalette::Initialize + * + * Initializes the palette. As we start initialized, return + * DDERR_ALREADYINITIALIZED + * + * Params: + * DD: DirectDraw interface this palette is asigned to + * Flags: Some flags, as usual + * ColorTable: The startup color table + * + * Returns: + * DDERR_ALREADYINITIALIZED + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawPaletteImpl_Initialize(IDirectDrawPalette *iface, + IDirectDraw *DD, + DWORD Flags, + PALETTEENTRY *ColorTable) +{ + TRACE("(%p)->(%p,%lx,%p)\n", iface, DD, Flags, ColorTable); + return DDERR_ALREADYINITIALIZED; +} + +/***************************************************************************** + * IDirectDrawPalette::GetCaps + * + * Returns the palette description + * + * Params: + * Caps: Address to store the caps at + * + * Returns: + * D3D_OK on success + * DDERR_INVALIDPARAMS if Caps is NULL + * For more details, see IWineD3DPalette::GetCaps + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawPaletteImpl_GetCaps(IDirectDrawPalette *iface, + DWORD *Caps) +{ + ICOM_THIS_FROM(IDirectDrawPaletteImpl, IDirectDrawPalette, iface); + TRACE("(%p)->(%p): Relay\n", This, Caps); + + return IWineD3DPalette_GetCaps(This->wineD3DPalette, Caps); +} + +/***************************************************************************** + * IDirectDrawPalette::SetEntries + * + * Sets the palette entries from a PALETTEENTRY structure. WineD3D takes + * care for updating the surface. + * + * Params: + * Flags: Flags, as usual + * Start: First palette entry to set + * Count: Number of entries to set + * PalEnt: Source entries + * + * Returns: + * D3D_OK on success + * DDERR_INVALIDPARAMS if PalEnt is NULL + * For details, see IWineD3DDevice::SetEntries + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawPaletteImpl_SetEntries(IDirectDrawPalette *iface, + DWORD Flags, + DWORD Start, + DWORD Count, + PALETTEENTRY *PalEnt) +{ + ICOM_THIS_FROM(IDirectDrawPaletteImpl, IDirectDrawPalette, iface); + TRACE("(%p)->(%lx,%ld,%ld,%p): Relay\n", This, Flags, Start, Count, PalEnt); + + if(!PalEnt) + return DDERR_INVALIDPARAMS; + + return IWineD3DPalette_SetEntries(This->wineD3DPalette, Flags, Start, Count, PalEnt); +} + +/***************************************************************************** + * IDirectDrawPalette::GetEntries + * + * Returns the entries stored in this interface. + * + * Params: + * Flags: Flags :) + * Start: First entry to return + * Count: The number of entries to return + * PalEnt: PALETTEENTRY structure to write the entries to + * + * Returns: + * D3D_OK on success + * DDERR_INVALIDPARAMS if PalEnt is NULL + * For details, see IWineD3DDevice::SetEntries + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawPaletteImpl_GetEntries(IDirectDrawPalette *iface, + DWORD Flags, + DWORD Start, + DWORD Count, + PALETTEENTRY *PalEnt) +{ + ICOM_THIS_FROM(IDirectDrawPaletteImpl, IDirectDrawPalette, iface); + TRACE("(%p)->(%lx,%ld,%ld,%p): Relay\n", This, Flags, Start, Count, PalEnt); + + if(!PalEnt) + return DDERR_INVALIDPARAMS; + + return IWineD3DPalette_GetEntries(This->wineD3DPalette, Flags, Start, Count, PalEnt); +} + +const IDirectDrawPaletteVtbl IDirectDrawPalette_Vtbl = +{ + /*** IUnknown ***/ + IDirectDrawPaletteImpl_QueryInterface, + IDirectDrawPaletteImpl_AddRef, + IDirectDrawPaletteImpl_Release, + /*** IDirectDrawPalette ***/ + IDirectDrawPaletteImpl_GetCaps, + IDirectDrawPaletteImpl_GetEntries, + IDirectDrawPaletteImpl_Initialize, + IDirectDrawPaletteImpl_SetEntries +}; diff --git a/dlls/ddraw/palette_hal.c b/dlls/ddraw/palette_hal.c deleted file mode 100644 index 070642a49a..0000000000 --- a/dlls/ddraw/palette_hal.c +++ /dev/null @@ -1,134 +0,0 @@ -/* DirectDrawPalette HAL driver - * - * Copyright 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "config.h" -#include "winerror.h" -#include "wine/debug.h" - -#include -#include - -#include "ddraw_private.h" - -WINE_DEFAULT_DEBUG_CHANNEL(ddraw); - -static const IDirectDrawPaletteVtbl DDRAW_HAL_Palette_VTable; - -/****************************************************************************** - * IDirectDrawPalette - */ -HRESULT HAL_DirectDrawPalette_Construct(IDirectDrawPaletteImpl* This, - IDirectDrawImpl* pDD, DWORD dwFlags) -{ - LPDDRAWI_DIRECTDRAW_GBL dd_gbl = pDD->local.lpGbl; - DDHAL_CREATEPALETTEDATA data; - HRESULT hr; - - hr = Main_DirectDrawPalette_Construct(This, pDD, dwFlags); - if (FAILED(hr)) return hr; - - This->final_release = HAL_DirectDrawPalette_final_release; - ICOM_INIT_INTERFACE(This, IDirectDrawPalette, DDRAW_HAL_Palette_VTable); - - /* initialize HAL palette */ - data.lpDD = dd_gbl; - data.lpDDPalette = &This->global; - data.lpColorTable = NULL; - data.ddRVal = 0; - data.CreatePalette = dd_gbl->lpDDCBtmp->HALDD.CreatePalette; - if (data.CreatePalette) - data.CreatePalette(&data); - - return DD_OK; -} - -HRESULT -HAL_DirectDrawPalette_Create(IDirectDrawImpl* pDD, DWORD dwFlags, - LPDIRECTDRAWPALETTE* ppPalette, - LPUNKNOWN pUnkOuter) -{ - IDirectDrawPaletteImpl* This; - HRESULT hr; - - if (pUnkOuter != NULL) - return CLASS_E_NOAGGREGATION; /* unchecked */ - - This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*This)); - if (This == NULL) return E_OUTOFMEMORY; - - hr = HAL_DirectDrawPalette_Construct(This, pDD, dwFlags); - if (FAILED(hr)) - HeapFree(GetProcessHeap(), 0, This); - else - *ppPalette = ICOM_INTERFACE(This, IDirectDrawPalette); - - return hr; -} - -HRESULT WINAPI -HAL_DirectDrawPalette_SetEntries(LPDIRECTDRAWPALETTE iface, DWORD dwFlags, - DWORD dwStart, DWORD dwCount, - LPPALETTEENTRY palent) -{ - IDirectDrawPaletteImpl *This = (IDirectDrawPaletteImpl *)iface; - LPDDRAWI_DIRECTDRAW_GBL dd_gbl = This->local.lpDD_lcl->lpGbl; - DDHAL_SETENTRIESDATA data; - - TRACE("(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",This,dwFlags,dwStart,dwCount, - palent); - - data.lpDD = dd_gbl; - data.lpDDPalette = &This->global; - data.dwBase = dwStart; - data.dwNumEntries = dwCount; - data.lpEntries = palent; - data.ddRVal = 0; - data.SetEntries = dd_gbl->lpDDCBtmp->HALDDPalette.SetEntries; - if (data.SetEntries) - data.SetEntries(&data); - - return Main_DirectDrawPalette_SetEntries(iface, dwFlags, dwStart, dwCount, palent); -} - -void HAL_DirectDrawPalette_final_release(IDirectDrawPaletteImpl* This) -{ - LPDDRAWI_DIRECTDRAW_GBL dd_gbl = This->local.lpDD_lcl->lpGbl; - DDHAL_DESTROYPALETTEDATA data; - - /* destroy HAL palette */ - data.lpDD = dd_gbl; - data.lpDDPalette = &This->global; - data.ddRVal = 0; - data.DestroyPalette = dd_gbl->lpDDCBtmp->HALDDPalette.DestroyPalette; - if (data.DestroyPalette) - data.DestroyPalette(&data); - - Main_DirectDrawPalette_final_release(This); -} - -static const IDirectDrawPaletteVtbl DDRAW_HAL_Palette_VTable = -{ - Main_DirectDrawPalette_QueryInterface, - Main_DirectDrawPalette_AddRef, - Main_DirectDrawPalette_Release, - Main_DirectDrawPalette_GetCaps, - Main_DirectDrawPalette_GetEntries, - Main_DirectDrawPalette_Initialize, - HAL_DirectDrawPalette_SetEntries -}; diff --git a/dlls/ddraw/palette_main.c b/dlls/ddraw/palette_main.c deleted file mode 100644 index 50fb0de6fe..0000000000 --- a/dlls/ddraw/palette_main.c +++ /dev/null @@ -1,281 +0,0 @@ -/* DirectDraw - IDirectPalette base interface - * - * Copyright 1997-2000 Marcus Meissner - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "config.h" -#include "winerror.h" -#include "wine/debug.h" - -#include -#include - -#include "ddraw_private.h" - -WINE_DEFAULT_DEBUG_CHANNEL(ddraw); - -#define SIZE_BITS (DDPCAPS_1BIT | DDPCAPS_2BIT | DDPCAPS_4BIT | DDPCAPS_8BIT) - -/* For unsigned x. 0 is not a power of 2. */ -#define IS_POW_2(x) (((x) & ((x) - 1)) == 0) - -static const IDirectDrawPaletteVtbl DDRAW_Main_Palette_VTable; - -/****************************************************************************** - * IDirectDrawPalette - */ -HRESULT Main_DirectDrawPalette_Construct(IDirectDrawPaletteImpl* This, - IDirectDrawImpl* pDD, DWORD dwFlags) -{ - if (!IS_POW_2(dwFlags & SIZE_BITS)) return DDERR_INVALIDPARAMS; - - if (dwFlags & DDPCAPS_8BITENTRIES) - WARN("creating palette with 8 bit entries\n"); - - This->palNumEntries = Main_DirectDrawPalette_Size(dwFlags); - This->ref = 1; - - This->local.lpGbl = &This->global; - This->local.lpDD_lcl = &pDD->local; - This->global.lpDD_lcl = &pDD->local; - This->global.dwProcessId = GetCurrentProcessId(); - This->global.dwFlags = dwFlags; - - This->final_release = Main_DirectDrawPalette_final_release; - ICOM_INIT_INTERFACE(This, IDirectDrawPalette, DDRAW_Main_Palette_VTable); - - /* we could defer hpal creation until we need it, - * but does anyone have a case where it would be useful? */ - This->hpal = CreatePalette((const LOGPALETTE*)&(This->palVersion)); - - Main_DirectDraw_AddPalette(pDD, This); - - return DD_OK; -} - -HRESULT -Main_DirectDrawPalette_Create(IDirectDrawImpl* pDD, DWORD dwFlags, - LPDIRECTDRAWPALETTE* ppPalette, - LPUNKNOWN pUnkOuter) -{ - IDirectDrawPaletteImpl* This; - HRESULT hr; - - if (pUnkOuter != NULL) - return CLASS_E_NOAGGREGATION; /* unchecked */ - - This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*This)); - if (This == NULL) return E_OUTOFMEMORY; - - hr = Main_DirectDrawPalette_Construct(This, pDD, dwFlags); - if (FAILED(hr)) - HeapFree(GetProcessHeap(), 0, This); - else - *ppPalette = ICOM_INTERFACE(This, IDirectDrawPalette); - - return hr; -} - -DWORD Main_DirectDrawPalette_Size(DWORD dwFlags) -{ - switch (dwFlags & SIZE_BITS) - { - case DDPCAPS_1BIT: return 2; - case DDPCAPS_2BIT: return 4; - case DDPCAPS_4BIT: return 16; - case DDPCAPS_8BIT: return 256; - default: assert(0); return 256; - } -} - -HRESULT WINAPI -Main_DirectDrawPalette_GetEntries(LPDIRECTDRAWPALETTE iface, DWORD dwFlags, - DWORD dwStart, DWORD dwCount, - LPPALETTEENTRY palent) -{ - IDirectDrawPaletteImpl *This = (IDirectDrawPaletteImpl *)iface; - - TRACE("(%p)->GetEntries(%08lx,%ld,%ld,%p)\n",This,dwFlags,dwStart,dwCount, - palent); - - if (dwFlags != 0) return DDERR_INVALIDPARAMS; /* unchecked */ - if (dwStart + dwCount > Main_DirectDrawPalette_Size(This->global.dwFlags)) - return DDERR_INVALIDPARAMS; - - if (This->global.dwFlags & DDPCAPS_8BITENTRIES) - { - unsigned int i; - LPBYTE entry = (LPBYTE)palent; - - for (i=dwStart; i < dwCount+dwStart; i++) - *entry++ = This->palents[i].peRed; - } - else - memcpy(palent, This->palents+dwStart, dwCount * sizeof(PALETTEENTRY)); - - return DD_OK; -} - -HRESULT WINAPI -Main_DirectDrawPalette_SetEntries(LPDIRECTDRAWPALETTE iface, DWORD dwFlags, - DWORD dwStart, DWORD dwCount, - LPPALETTEENTRY palent) -{ - IDirectDrawPaletteImpl *This = (IDirectDrawPaletteImpl *)iface; - - TRACE("(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",This,dwFlags,dwStart,dwCount, - palent); - - if (This->global.dwFlags & DDPCAPS_8BITENTRIES) - { - unsigned int i; - const BYTE* entry = (const BYTE*)palent; - - for (i=dwStart; i < dwCount+dwStart; i++) - This->palents[i].peRed = *entry++; - } - else { - memcpy(This->palents+dwStart, palent, dwCount * sizeof(PALETTEENTRY)); - - if (This->hpal) - SetPaletteEntries(This->hpal, dwStart, dwCount, This->palents+dwStart); - - if (This->global.dwFlags & DDPCAPS_PRIMARYSURFACE) { - /* update physical palette */ - LPDIRECTDRAWSURFACE7 psurf = NULL; - IDirectDraw7_GetGDISurface(ICOM_INTERFACE(This->ddraw_owner,IDirectDraw7), &psurf); - if (psurf) { - IDirectDrawSurfaceImpl *surf = ICOM_OBJECT(IDirectDrawSurfaceImpl, - IDirectDrawSurface7, psurf); - surf->update_palette(surf, This, dwStart, dwCount, palent); - IDirectDrawSurface7_Release(psurf); - } - else ERR("can't find GDI surface!!\n"); - } - } - -#if 0 - /* Now, if we are in 'depth conversion mode', update the screen palette */ - /* FIXME: we need to update the image or we won't get palette fading. */ - if (This->ddraw->d->palette_convert != NULL) - This->ddraw->d->palette_convert(palent,This->screen_palents,start,count); -#endif - - return DD_OK; -} - -void Main_DirectDrawPalette_final_release(IDirectDrawPaletteImpl* This) -{ - Main_DirectDraw_RemovePalette(This->ddraw_owner, This); - - if (This->hpal) DeleteObject(This->hpal); -} - -static void Main_DirectDrawPalette_Destroy(IDirectDrawPaletteImpl* This) -{ - This->final_release(This); - - if (This->private != This+1) - HeapFree(GetProcessHeap(), 0, This->private); - - HeapFree(GetProcessHeap(),0,This); -} - -void Main_DirectDrawPalette_ForceDestroy(IDirectDrawPaletteImpl* This) -{ - WARN("deleting palette %p with refcnt %lu\n", This, This->ref); - Main_DirectDrawPalette_Destroy(This); -} - -ULONG WINAPI -Main_DirectDrawPalette_Release(LPDIRECTDRAWPALETTE iface) -{ - IDirectDrawPaletteImpl *This = (IDirectDrawPaletteImpl *)iface; - ULONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p)->() decrementing from %lu.\n", This, ref + 1); - - if (!ref) - { - Main_DirectDrawPalette_Destroy(This); - return 0; - } - - return ref; -} - -ULONG WINAPI Main_DirectDrawPalette_AddRef(LPDIRECTDRAWPALETTE iface) { - IDirectDrawPaletteImpl *This = (IDirectDrawPaletteImpl *)iface; - ULONG ref = InterlockedIncrement(&This->ref); - - TRACE("(%p)->() incrementing from %lu.\n", This, ref - 1); - - return ref; -} - -HRESULT WINAPI -Main_DirectDrawPalette_Initialize(LPDIRECTDRAWPALETTE iface, - LPDIRECTDRAW ddraw, DWORD dwFlags, - LPPALETTEENTRY palent) -{ - IDirectDrawPaletteImpl *This = (IDirectDrawPaletteImpl *)iface; - TRACE("(%p)->(%p,%ld,%p)\n", This, ddraw, dwFlags, palent); - return DDERR_ALREADYINITIALIZED; -} - -HRESULT WINAPI -Main_DirectDrawPalette_GetCaps(LPDIRECTDRAWPALETTE iface, LPDWORD lpdwCaps) -{ - IDirectDrawPaletteImpl *This = (IDirectDrawPaletteImpl *)iface; - TRACE("(%p)->(%p)\n",This,lpdwCaps); - - *lpdwCaps = This->global.dwFlags; - - return DD_OK; -} - -HRESULT WINAPI -Main_DirectDrawPalette_QueryInterface(LPDIRECTDRAWPALETTE iface, - REFIID refiid, LPVOID *obj) -{ - IDirectDrawPaletteImpl *This = (IDirectDrawPaletteImpl *)iface; - TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj); - - if (IsEqualGUID(refiid, &IID_IUnknown) - || IsEqualGUID(refiid, &IID_IDirectDrawPalette)) - { - *obj = iface; - IDirectDrawPalette_AddRef(iface); - return S_OK; - } - else - { - return E_NOINTERFACE; - } -} - -static const IDirectDrawPaletteVtbl DDRAW_Main_Palette_VTable = -{ - Main_DirectDrawPalette_QueryInterface, - Main_DirectDrawPalette_AddRef, - Main_DirectDrawPalette_Release, - Main_DirectDrawPalette_GetCaps, - Main_DirectDrawPalette_GetEntries, - Main_DirectDrawPalette_Initialize, - Main_DirectDrawPalette_SetEntries -}; diff --git a/dlls/ddraw/parent.c b/dlls/ddraw/parent.c new file mode 100644 index 0000000000..3b7b3d8ab4 --- /dev/null +++ b/dlls/ddraw/parent.c @@ -0,0 +1,152 @@ +/* + * IParent implementation + * + * Copyright (c) 2006 Stefan Dösinger + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + * A universal parent interface for everything in WineD3D that doesn't have + * a DDraw counterpart + */ + +#include "config.h" +#include "wine/port.h" +#include "wine/debug.h" + +#include +#include +#include +#include + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "winnls.h" +#include "winerror.h" +#include "wingdi.h" +#include "wine/exception.h" +#include "excpt.h" + +#include "ddraw.h" +#include "d3d.h" + +#include "ddraw_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(ddraw); + +const GUID IID_IParent = {0xc20e4c88, 0x74e7, 0x4940, {0xba, 0x9f, 0x2e, 0x32, 0x3f, 0x9d, 0xc9, 0x81}}; + +/***************************************************************************** + * IUnknown methods + *****************************************************************************/ + +/***************************************************************************** + * IParent::Queryinterface + * + * It can't query any interfaces, and it's not used for anything. So + * it just returns E_NOINTERFACE + * + * Params: + * riid: guid of queried interface + * obj: returns a pointer to the interface + * + * Return values + * This implementation always returns E_NOINTERFACE and NULL + * + *****************************************************************************/ +static HRESULT WINAPI +IParentImpl_QueryInterface(IParent *iface, + REFIID riid, + void **obj) +{ + ICOM_THIS_FROM(IParentImpl, IParent, iface); + TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(riid), obj); + + *obj = NULL; + if ( IsEqualGUID( &IID_IUnknown, riid ) || + IsEqualGUID( &IID_IParent, riid ) ) + { + *obj = ICOM_INTERFACE(This, IParent); + IParent_AddRef(ICOM_INTERFACE(This, IParent)); + return DD_OK; + } + return E_NOINTERFACE; +} + +/***************************************************************************** + * IParent::AddRef + * + * Increases the refcount + * + * Params: + * + * Return values + * The new refcount + * + *****************************************************************************/ +static ULONG WINAPI +IParentImpl_AddRef(IParent *iface) +{ + ICOM_THIS_FROM(IParentImpl, IParent, iface); + ULONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) : AddRef from %ld\n", This, ref - 1); + + return ref; +} + + +/***************************************************************************** + * IParent::Release + * + * Releases the refcount, and destroys the object if the refcount falls to 0 + * Also releases the child object, if destroyed. That's almost the whole sense + * of this interface. + * + * Params: + * + * Return values + * The new refcount + * + *****************************************************************************/ +static ULONG WINAPI +IParentImpl_Release(IParent *iface) +{ + ICOM_THIS_FROM(IParentImpl, IParent, iface); + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) : ReleaseRef to %ld\n", This, ref); + + if (ref == 0) + { + TRACE("(%p) Releasing child at %p\n", This, This->child); + if(This->child) + IUnknown_Release(This->child); + HeapFree(GetProcessHeap(), 0, This); + TRACE("Released\n"); + } + return ref; +} + +/***************************************************************************** + * The VTable + *****************************************************************************/ +const IParentVtbl IParent_Vtbl = +{ + IParentImpl_QueryInterface, + IParentImpl_AddRef, + IParentImpl_Release, +}; diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c new file mode 100644 index 0000000000..113ec5f6ee --- /dev/null +++ b/dlls/ddraw/surface.c @@ -0,0 +1,2091 @@ +/* DirectDraw Surface Implementation + * + * Copyright (c) 1997-2000 Marcus Meissner + * Copyright (c) 1998-2000 Lionel Ulmer + * Copyright (c) 2000-2001 TransGaming Technologies Inc. + * Copyright (c) 2006 Stefan Dösinger + * + * This file contains the (internal) driver registration functions, + * driver enumeration APIs and DirectDraw creation functions. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include "wine/port.h" + +#include +#include +#include +#include + +#define COBJMACROS +#define NONAMELESSUNION + +#include "windef.h" +#include "winbase.h" +#include "winnls.h" +#include "winerror.h" +#include "wingdi.h" +#include "wine/exception.h" +#include "excpt.h" + +#include "ddraw.h" +#include "d3d.h" + +#include "ddraw_private.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(ddraw); + +/***************************************************************************** + * IUnkown parts follow + *****************************************************************************/ + +/***************************************************************************** + * IDirectDrawSurface7::QueryInterface + * + * A normal QueryInterface implementation. For QueryInterface rules + * see ddraw.c, IDirectDraw7::QueryInterface. This method + * can Query IDirectDrawSurface interfaces in all version, IDirect3DTexture + * in all versions, the IDirectDrawGammaControl interface and it can + * create an IDirect3DDevice. (Uses IDirect3D7::CreateDevice) + * + * Params: + * riid: The interface id queried for + * obj: Address to write the pointer to + * + * Returns: + * S_OK on success + * E_NOINTERFACE if the requested interface wasn't found + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawSurfaceImpl_QueryInterface(IDirectDrawSurface7 *iface, + REFIID riid, + void **obj) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface); + + /* According to COM docs, if the QueryInterface fails, obj should be set to NULL */ + *obj = NULL; + + if(!riid) + return DDERR_INVALIDPARAMS; + + TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),obj); + if (IsEqualGUID(riid, &IID_IUnknown) + || IsEqualGUID(riid, &IID_IDirectDrawSurface7) + || IsEqualGUID(riid, &IID_IDirectDrawSurface4) ) + { + IUnknown_AddRef(iface); + *obj = ICOM_INTERFACE(This, IDirectDrawSurface7); + TRACE("(%p) returning IDirectDrawSurface7 interface at %p\n", This, *obj); + return S_OK; + } + else if( IsEqualGUID(riid, &IID_IDirectDrawSurface3) + || IsEqualGUID(riid, &IID_IDirectDrawSurface2) + || IsEqualGUID(riid, &IID_IDirectDrawSurface) ) + { + IUnknown_AddRef(iface); + *obj = ICOM_INTERFACE(This, IDirectDrawSurface3); + TRACE("(%p) returning IDirectDrawSurface3 interface at %p\n", This, *obj); + return S_OK; + } + else if( IsEqualGUID(riid, &IID_IDirectDrawGammaControl) ) + { + IUnknown_AddRef(iface); + *obj = ICOM_INTERFACE(This, IDirectDrawGammaControl); + TRACE("(%p) returning IDirectDrawGammaControl interface at %p\n", This, *obj); + return S_OK; + } + else if( IsEqualGUID(riid, &IID_D3DDEVICE_WineD3D) || + IsEqualGUID(riid, &IID_IDirect3DHALDevice) ) + { + IDirect3DDevice7 *d3d; + + /* Call into IDirect3D7 for creation */ + IDirect3D7_CreateDevice(ICOM_INTERFACE(This->ddraw, IDirect3D7), + riid, + ICOM_INTERFACE(This, IDirectDrawSurface7), + &d3d); + + *obj = COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice7, IDirect3DDevice, d3d); + TRACE("(%p) Returning IDirect3DDevice interface at %p\n", This, *obj); + + return S_OK; + } + else if (IsEqualGUID( &IID_IDirect3DTexture, riid ) || + IsEqualGUID( &IID_IDirect3DTexture2, riid )) + { + if (IsEqualGUID( &IID_IDirect3DTexture, riid )) + { + *obj = ICOM_INTERFACE(This, IDirect3DTexture); + TRACE(" returning Direct3DTexture interface at %p.\n", *obj); + } + else + { + *obj = ICOM_INTERFACE(This, IDirect3DTexture2); + TRACE(" returning Direct3DTexture2 interface at %p.\n", *obj); + } + IUnknown_AddRef( (IUnknown *) *obj); + return S_OK; + } + + ERR("No interface\n"); + return E_NOINTERFACE; +} + +/***************************************************************************** + * IDirectDrawSurface7::AddRef + * + * A normal addref implementation + * + * Returns: + * The new refcount + * + *****************************************************************************/ +static ULONG WINAPI +IDirectDrawSurfaceImpl_AddRef(IDirectDrawSurface7 *iface) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface); + ULONG refCount = InterlockedIncrement(&This->ref); + + TRACE("(%p) : AddRef increasing from %ld\n", This, refCount - 1); + return refCount; +} + +/***************************************************************************** + * IDirectDrawSurfaceImpl_Destroy + * + * A helper function for IDirectDrawSurface7::Release + * + * Frees the surface, regardless of it's refcount. + * See IDirectDrawSurface7::Release for more information + * + * Params: + * This: Surface to free + * + *****************************************************************************/ +static void IDirectDrawSurfaceImpl_Destroy(IDirectDrawSurfaceImpl *This) +{ + TRACE("(%p)\n", This); + + /* Check the refcount and give a warning */ + if(This->ref > 1) + { + /* This can happen when a complex surface is destroyed, + * because the 2nd surface was addref()ed when the app + * called GetAttachedSurface + */ + WARN("(%p): Destroying surface with refount %ld\n", This, This->ref); + } + + /* Check for attached surfaces and detach them */ + if(This->first_attached != This) + { + /* Well, this shouldn't happen: The surface beeing attached is addref()ed + * in AddAttachedSurface, so it shouldn't be released until DeleteAttachedSurface + * is called, because the refcount is hold. It looks like the app released() + * it often enought to force this + */ + IDirectDrawSurface7 *root = ICOM_INTERFACE(This->first_attached, IDirectDrawSurface7); + IDirectDrawSurface7 *detach = ICOM_INTERFACE(This, IDirectDrawSurface7); + + FIXME("(%p) Freeing a surface that is attached to surface %p\n", This, This->first_attached); + + /* The refcount will drop to -1 here */ + if(IDirectDrawSurface7_DeleteAttachedSurface(root, 0, detach) != DD_OK) + { + ERR("(%p) DeleteAttachedSurface failed!\n", This); + } + } + + while(This->next_attached != NULL) + { + IDirectDrawSurface7 *root = ICOM_INTERFACE(This, IDirectDrawSurface7); + IDirectDrawSurface7 *detach = ICOM_INTERFACE(This->next_attached, IDirectDrawSurface7); + + if(IDirectDrawSurface7_DeleteAttachedSurface(root, 0, detach) != DD_OK) + { + ERR("(%p) DeleteAttachedSurface failed!\n", This); + assert(0); + } + } + + /* Now destroy the surface. Wait: It could have been released if we are a texture */ + if(This->WineD3DSurface) + IWineD3DSurface_Release(This->WineD3DSurface); + + /* Reduce the ddraw surface count */ + InterlockedDecrement(&This->ddraw->surfaces); + if(This->prev) + This->prev->next = This->next; + else + { + assert(This->ddraw->surface_list == This); + This->ddraw->surface_list = This->next; + } + if(This->next) + This->next->prev = This->prev; + + HeapFree(GetProcessHeap(), 0, This); +} + +/***************************************************************************** + * IDirectDrawSurface7::Release + * + * Reduces the surface's refcount by 1. If the refcount falls to 0, the + * surface is destroyed. + * + * Destroying the surface is a bit tricky. For the connection between + * WineD3DSurfaces and DirectDrawSurfaces see IDirectDraw7::CreateSurface + * It has a nice graph explaining the connection. + * + * What happens here is basically this: + * When a surface is destroyed, it's WineD3DSurface is released, + * and the refcount of the DirectDraw interface is reduced by 1. If it has + * complex surfaces attached to it, then these surfaces are destroyed too, + * regardless of their refcount. If any surface beeing destroyed has another + * surface attached to it(with a "soft" attachment, not complex), then + * this surface is detached with DeleteAttachedSurface. + * + * When the surface is a texture, the WineD3DTexture is released. + * If the surface is the Direct3D render target, then the D3D + * capatiblities of the WineD3DDevice are uninitialized, which causes the + * swapchain to be released. + * + * Returns: + * The new refcount + * + *****************************************************************************/ +static ULONG WINAPI +IDirectDrawSurfaceImpl_Release(IDirectDrawSurface7 *iface) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface); + ULONG ref; + TRACE("(%p) : Releasing from %ld\n", This, This->ref); + ref = InterlockedDecrement(&This->ref); + + if (ref == 0) + { + + IDirectDrawSurfaceImpl *surf; + IDirectDrawImpl *ddraw; + + /* Destroy all complex attached surfaces + * Therefore, start with the first surface, + * except for textures. Not entirely sure what has + * to happen exactly in this case + */ + if( (This->first_complex != This) && !(This->surface_desc.ddsCaps.dwCaps & DDSCAPS_TEXTURE)) + { + FIXME("(%p) Destroying a surface which is a attached to a complex root %p\n", This, This->first_complex); + } + ddraw = This->ddraw; + + /* If it's a texture, destroy the WineD3DTexture. + * WineD3D will destroy the IParent interfaces + * of the sublevels, which destroys the WineD3DSurfaces. + * Set the surfaces to NULL to avoid destroying them again later + */ + if(This->wineD3DTexture) + { + IWineD3DTexture_Release(This->wineD3DTexture); + } + /* If it's the RenderTarget, destroy the d3ddevice */ + else if( (ddraw->d3d_initialized) && (This == ddraw->d3d_target)) + { + TRACE("(%p) Destroying the render target, uninitializing D3D\n", This); + + /* Unset any index buffer, just to be sure */ + IWineD3DDevice_SetIndices(ddraw->wineD3DDevice, NULL, 0); + + if(IWineD3DDevice_Uninit3D(ddraw->wineD3DDevice) != D3D_OK) + { + /* Not good */ + ERR("(%p) Failed to uninit 3D\n", This); + } + else + { + /* Free the d3d window if one was created */ + if(ddraw->d3d_window != 0) + { + TRACE(" (%p) Destroying the hidden render window %p\n", This, ddraw->d3d_window); + DestroyWindow(ddraw->d3d_window); + ddraw->d3d_window = 0; + } + /* Unset the pointers */ + } + + ddraw->d3d_initialized = FALSE; + ddraw->d3d_target = NULL; + + /* Write a trace because D3D unloading was the reason for many + * crashes during development. + */ + TRACE("(%p) D3D unloaded\n", This); + } + else if(This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_PRIMARYSURFACE | + DDSCAPS_3DDEVICE | + DDSCAPS_TEXTURE ) ) + { + /* It's a render target, but no swapchain was created. + * The IParent interfaces have to be released manually. + * The same applies for textures without an + * IWineD3DTexture object attached + */ + surf = This; + while(surf) + { + IParent *Parent; + + IWineD3DSurface_GetParent(surf->WineD3DSurface, + (IUnknown **) &Parent); + IParent_Release(Parent); /* For the getParent */ + IParent_Release(Parent); /* To release it */ + surf = surf->next_complex; + } + } + + /* Loop through all complex attached surfaces, + * and destroy them + */ + while( (surf = This->next_complex) ) + { + This->next_complex = surf->next_complex; /* Unchain it from the complex listing */ + IDirectDrawSurfaceImpl_Destroy(surf); /* Destroy it */ + } + + /* Destroy the surface. + */ + IDirectDrawSurfaceImpl_Destroy(This); + + /* Reduce the ddraw refcount */ + IDirectDraw7_Release(ICOM_INTERFACE(ddraw, IDirectDraw7)); + } + + return ref; +} + +/***************************************************************************** + * IDirectDrawSurface7::GetAttachedSurface + * + * Returns an attached surface with the requested caps. Surface attchment + * and complex surfaces are not clearly described by the MSDN or sdk, + * so this method is tricky and likely to contain problems. + * This implementation searches the complex chain first, then the + * attachment chain, and then it checks if the caps match to itself. + * + * The chains are searched from This down to the last surface in the chain, + * not from the first element in the chain. The first surface found is + * returned. The MSDN says that this method fails if more than one surface + * matches the caps, but apparently this is incorrect. + * + * The found surface is AddRefed before it's returned. + * + * Params: + * Caps: Pointer to a DDCAPS2 structure describing the caps asked for + * Surface: Address to store the found surface + * + * Returns: + * DD_OK on success + * DDERR_INVALIDPARAMS if Caps or Surface is NULL + * DDERR_NOTFOUND if no surface was found + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawSurfaceImpl_GetAttachedSurface(IDirectDrawSurface7 *iface, + DDSCAPS2 *Caps, + IDirectDrawSurface7 **Surface) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface); + IDirectDrawSurfaceImpl *surf; + DDSCAPS2 our_caps; + + TRACE("(%p)->(%p,%p)\n", This, Caps, Surface); + + our_caps = *Caps; + + if(This->version < 7) + { + /* Earlier dx apps put garbage into these members, clear them */ + our_caps.dwCaps2 = 0; + our_caps.dwCaps3 = 0; + our_caps.dwCaps4 = 0; + } + + TRACE("(%p): Looking for caps: %lx,%lx,%lx,%lx\n", This, our_caps.dwCaps, our_caps.dwCaps2, our_caps.dwCaps3, our_caps.dwCaps4); /* FIXME: Better debugging */ + + /* First, look at the complex chain */ + surf = This; + + while( (surf = surf->next_complex) ) + { + if (TRACE_ON(ddraw)) + { + TRACE("Surface: (%p) caps: %lx,%lx,%lx,%lx\n", surf, + surf->surface_desc.ddsCaps.dwCaps, + surf->surface_desc.ddsCaps.dwCaps2, + surf->surface_desc.ddsCaps.dwCaps3, + surf->surface_desc.ddsCaps.dwCaps4); + } + + if (((surf->surface_desc.ddsCaps.dwCaps & our_caps.dwCaps) == our_caps.dwCaps) && + ((surf->surface_desc.ddsCaps.dwCaps2 & our_caps.dwCaps2) == our_caps.dwCaps2)) { + + /* MSDN: "This method fails if more than one surface is attached + * that matches the capabilities requested." + * + * The mipmap demo of the DirectX7 sdk shows what to do here: + * aparently apps expect the first found surface to be returned. + */ + + TRACE("(%p): Returning surface %p\n", This, surf); + TRACE("(%p): mipmapcount=%d\n", This, surf->mipmap_level); + *Surface = ICOM_INTERFACE(surf, IDirectDrawSurface7); + IDirectDrawSurface7_AddRef(*Surface); + return DD_OK; + } + } + + /* Next, look at the attachment chain */ + surf = This; + + while( (surf = surf->next_attached) ) + { + if (TRACE_ON(ddraw)) + { + TRACE("Surface: (%p) caps: %lx,%lx,%lx,%lx\n", surf, + surf->surface_desc.ddsCaps.dwCaps, + surf->surface_desc.ddsCaps.dwCaps2, + surf->surface_desc.ddsCaps.dwCaps3, + surf->surface_desc.ddsCaps.dwCaps4); + } + + if (((surf->surface_desc.ddsCaps.dwCaps & our_caps.dwCaps) == our_caps.dwCaps) && + ((surf->surface_desc.ddsCaps.dwCaps2 & our_caps.dwCaps2) == our_caps.dwCaps2)) { + + /* MSDN: "This method fails if more than one surface is attached + * that matches the capabilities requested." + * + * The mipmap demo of the DirectX7 sdk shows what to do here: + * aparently apps expect the first found surface to be returned. + */ + + TRACE("(%p): Returning surface %p\n", This, surf); + *Surface = ICOM_INTERFACE(surf, IDirectDrawSurface7); + IDirectDrawSurface7_AddRef(*Surface); + return DD_OK; + } + } + + /* Is this valid? */ +#if 0 + if (((This->surface_desc.ddsCaps.dwCaps & our_caps.dwCaps) == our_caps.dwCaps) && + ((This->surface_desc.ddsCaps.dwCaps2 & our_caps.dwCaps2) == our_caps.dwCaps2) && + This == This->first_complex) + { + + TRACE("(%p): Returning surface %p\n", This, This); + *Surface = ICOM_INTERFACE(This, IDirectDrawSurface7); + IDirectDrawSurface7_AddRef(*Surface); + return DD_OK; + } +#endif + + /* What to do here? Continue with the surface root?? */ + + TRACE("(%p) Didn't find a valid surface\n", This); + return DDERR_NOTFOUND; +} + +/***************************************************************************** + * IDirectDrawSurface7::Lock + * + * Locks the surface and returnes a pointer to the surface's memory + * + * Params: + * Rect: Rectangle to lock. If NULL, the whole surface is locked + * DDSD: Pointer to a DDSURFACEDESC2 which shall receive the surface's desc. + * Flags: Locking flags, e.g Read only or write only + * h: An event handle that's not used and must be NULL + * + * Returns: + * DD_OK on success + * DDERR_INVALIDPARAMS if DDSD is NULL + * For more details, see IWineD3DSurface::LockRect + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawSurfaceImpl_Lock(IDirectDrawSurface7 *iface, + RECT *Rect, + DDSURFACEDESC2 *DDSD, + DWORD Flags, + HANDLE h) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface); + WINED3DLOCKED_RECT LockedRect; + HRESULT hr; + TRACE("(%p)->(%p,%p,%lx,%p)\n", This, Rect, DDSD, Flags, h); + + if(!DDSD) + return DDERR_INVALIDPARAMS; + + /* Should I check for the handle to be NULL? + * + * The DDLOCK flags and the D3DLOCK flags are equal + * for the supported values. The others are ignored by WineD3D + */ + + /* Hmm. Anarchy online passes an uninitialized surface descriptor, + * that means it doesn't have dwSize set. Init it to some sane + * value + */ + if(DDSD->dwSize <= sizeof(DDSURFACEDESC)) + { + DDSD->dwSize = sizeof(DDSURFACEDESC); + } + else + { + DDSD->dwSize = sizeof(DDSURFACEDESC2); + } + + DD_STRUCT_COPY_BYSIZE(DDSD,&(This->surface_desc)); + hr = IWineD3DSurface_LockRect(This->WineD3DSurface, + &LockedRect, + Rect, + Flags); + if(hr != D3D_OK) return hr; + + /* Override the memory area and the pitch */ + DDSD->dwFlags |= DDSD_LPSURFACE; + DDSD->lpSurface = LockedRect.pBits; + DDSD->dwFlags |= DDSD_PITCH; + DDSD->u1.lPitch = LockedRect.Pitch; + + TRACE("locked surface returning description :\n"); + if (TRACE_ON(ddraw)) DDRAW_dump_surface_desc(DDSD); + + return DD_OK; +} + +/***************************************************************************** + * IDirectDrawSurface7::Unlock + * + * Unlocks an locked surface + * + * Params: + * Rect: Not used by this implementation + * + * Returns: + * D3D_OK on success + * For more details, see IWineD3DSurface::UnlockRect + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawSurfaceImpl_Unlock(IDirectDrawSurface7 *iface, + RECT *pRect) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface); + TRACE("(%p)->(%p)\n", This, pRect); + + return IWineD3DSurface_UnlockRect(This->WineD3DSurface); +} + +/***************************************************************************** + * IDirectDrawSurface7::Flip + * + * Flips a surface with the DDSCAPS_FLIP flag. The flip is relayed to + * IWineD3DSurface::Flip. Because WineD3D doesn't handle attached surfaces, + * the flip target is passed to WineD3D, even if the app didn't specify one + * + * Params: + * DestOverride: Specifies the surface that will become the new front + * buffer. If NULL, the current back buffer is used + * Flags: some DirectDraw flags, see include/ddraw.h + * + * Returns: + * DD_OK on success + * DDERR_NOTFLIPPABLE if no flip target could be found + * DDERR_INVALIDOBJECT if the surface isn't a front buffer + * For more details, see IWineD3DSurface::Flip + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawSurfaceImpl_Flip(IDirectDrawSurface7 *iface, + IDirectDrawSurface7 *DestOverride, + DWORD Flags) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface); + IDirectDrawSurfaceImpl *Override = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, DestOverride); + IDirectDrawSurface7 *Override7; + HRESULT hr; + TRACE("(%p)->(%p,%lx)\n", This, DestOverride, Flags); + + /* Flip has to be called from a front buffer + * What about overlay surfaces, AFAIK they can flip too? + */ + if( !(This->surface_desc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER) ) + return DDERR_INVALIDOBJECT; /* Unckecked */ + + /* WineD3D doesn't keep track of attached surface, so find the target */ + if(!Override) + { + DDSCAPS2 Caps; + + memset(&Caps, 0, sizeof(Caps)); + Caps.dwCaps |= DDSCAPS_BACKBUFFER; + hr = IDirectDrawSurface7_GetAttachedSurface(iface, &Caps, &Override7); + if(hr != DD_OK) + { + ERR("Can't find a flip target\n"); + return DDERR_NOTFLIPPABLE; /* Unchecked */ + } + Override = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, Override7); + + /* For the GetAttachedSurface */ + IDirectDrawSurface7_Release(Override7); + } + + return IWineD3DSurface_Flip(This->WineD3DSurface, + Override->WineD3DSurface, + Flags); +} + +/***************************************************************************** + * IDirectDrawSurface7::Blt + * + * Performs a blit on the surface + * + * Params: + * DestRect: Destination rectangle, can be NULL + * SrcSurface: Source surface, can be NULL + * SrcRect: Source rectange, can be NULL + * Flags: Blt flags + * DDBltFx: Some extended blt parameters, connected to the flags + * + * Returns: + * D3D_OK on success + * See IWineD3DSurface::Blt for more details + * + *****************************************************************************/ +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); + TRACE("(%p)->(%p,%p,%p,%lx,%p)\n", This, DestRect, Src, SrcRect, Flags, DDBltFx); + + return IWineD3DSurface_Blt(This->WineD3DSurface, + DestRect, + Src ? Src->WineD3DSurface : NULL, + SrcRect, + Flags, + DDBltFx); +} + +/***************************************************************************** + * IDirectDrawSurface7::AddAttachedSurface + * + * Attaches an surface to another surface. Surface attachments are + * incorrectly described in the SDK and the MSDN, and this method + * is prone to bugs. The surface that is attached is AddRefed. + * + * The attachment list consists of a first surface(first_attached) and + * for each surface a pointer to the next attached surface (next_attached). + * For the first surface, and a surface that has no attachments + * first_attached points to the surface itself. A surface that has + * no successors in the chain has next_attached set to NULL. + * + * Newly attached surfaces are attached right after the root surface. The + * complex chains are handled seperately in a simmilar chain, with + * first_complex and next_complex. If a surface is attached to a complex + * surface compound, it's attached to the surface that the app requested, + * not the complex root. See GetAttachedSurface for a description + * how surfaces are found. + * + * This is how the current implementation works, and it was coded by looking + * at the needs of the applications. + * + * So far only Z-Buffer attachments are tested, but there's no code yet + * to activate them. Mipmaps could be tricky to activate in WineD3D. + * Back buffers should work in 2D mode, but they are not tested. + * Rendering to the primary surface and switching between that and + * double buffering is not yet implemented in WineD3D, so for 3D it might + * have unexpected results. + * + * Params: + * Attach: Surface to attach to iface + * + * Returns: + * DD_OK on success + * DDERR_CANNOTATTACHSURFACE if the surface can't be attached for some reason + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawSurfaceImpl_AddAttachedSurface(IDirectDrawSurface7 *iface, + IDirectDrawSurface7 *Attach) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface); + IDirectDrawSurfaceImpl *Surf = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, Attach); + TRACE("(%p)->(%p)\n", This, Surf); + + /* Should I make sure to add it to the first complex surface? */ + + if(Surf == This) + return DDERR_CANNOTATTACHSURFACE; /* unchecked */ + + /* TODO MSDN: "You can attach only z-buffer surfaces with this method." + * But apparently backbuffers and mipmaps can be attached too. */ + + /* Set MIPMAPSUBLEVEL if this seems to be one */ + if (This->surface_desc.ddsCaps.dwCaps & + Surf->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) + { + Surf->surface_desc.ddsCaps.dwCaps2 |= DDSCAPS2_MIPMAPSUBLEVEL; + /* FIXME: we should probably also add to dwMipMapCount of this + * and all parent surfaces (update create_texture if you do) */ + } + + /* Check if the surface is already attached somewhere */ + if( (Surf->next_attached != NULL) || + (Surf->first_attached != Surf) ) + { + ERR("(%p) The Surface %p is already attached somewhere else: next_attached = %p, first_attached = %p, can't handle by now\n", This, Surf, Surf->next_attached, Surf->first_attached); + return DDERR_CANNOTATTACHSURFACE; + } + + /* This inserts the new surface at the 2nd position in the chain, right after the root surface */ + Surf->next_attached = This->next_attached; + Surf->first_attached = This->first_attached; + This->next_attached = Surf; + + /* MSDN: + * "This method increments the reference count of the surface being attached." + */ + IDirectDrawSurface7_AddRef(Attach); + return DD_OK; +} + +/***************************************************************************** + * IDirectDrawSurface7::DeleteAttachedSurface + * + * Removes a surface from the attachment chain. The surface's refcount + * is decreased by one after it has been removed + * + * Params: + * Flags: Some flags, not used by this implementation + * Attach: Surface to detach + * + * Returns: + * DD_OK on success + * DDERR_SURFACENOTATTACHED if the surface isn't attached to + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawSurfaceImpl_DeleteAttachedSurface(IDirectDrawSurface7 *iface, + DWORD Flags, + IDirectDrawSurface7 *Attach) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface); + IDirectDrawSurfaceImpl *Surf = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, Attach); + IDirectDrawSurfaceImpl *Prev = This; + TRACE("(%p)->(%08lx,%p)\n", This, Flags, Surf); + + if (!Surf || (Surf->first_attached != This) || (Surf == This) ) + return DDERR_SURFACENOTATTACHED; /* unchecked */ + + /* Remove MIPMAPSUBLEVEL if this seemed to be one */ + if (This->surface_desc.ddsCaps.dwCaps & + Surf->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) + { + Surf->surface_desc.ddsCaps.dwCaps2 &= ~DDSCAPS2_MIPMAPSUBLEVEL; + /* FIXME: we should probably also subtract from dwMipMapCount of this + * and all parent surfaces */ + } + + /* Find the Precessor of the detached surface */ + while(Prev) + { + if(Prev->next_attached == Surf) break; + Prev = Prev->next_attached; + } + + /* There must be a surface, otherwise there's a bug */ + assert(Prev != NULL); + + /* Unchain the surface */ + Prev->next_attached = Surf->next_attached; + Surf->next_attached = NULL; + Surf->first_attached = Surf; + + IDirectDrawSurface7_Release(Attach); + return DD_OK; +} + +/***************************************************************************** + * IDirectDrawSurface7::AddOverlayDirtyRect + * + * "This method is not currently implemented" + * + * Params: + * Rect: ? + * + * Returns: + * DDERR_UNSUPPORTED + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawSurfaceImpl_AddOverlayDirtyRect(IDirectDrawSurface7 *iface, + LPRECT Rect) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface); + TRACE("(%p)->(%p)\n",This,Rect); + + /* MSDN says it's not implemented. I could forward it to WineD3D, + * then we'd implement it, but I don't think that's a good idea + * (Stefan Dösinger) + */ +#if 0 + return IWineD3DSurface_AddOverlayDirtyRect(This->WineD3DSurface, pRect); +#endif + return DDERR_UNSUPPORTED; /* unchecked */ +} + +/***************************************************************************** + * IDirectDrawSurface7::GetDC + * + * Returns a GDI device context for the surface + * + * Params: + * hdc: Address of a HDC variable to store the dc to + * + * Returns: + * DD_OK on success + * DDERR_INVALIDPARAMS if hdc is NULL + * For details, see IWineD3DSurface::GetDC + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawSurfaceImpl_GetDC(IDirectDrawSurface7 *iface, + HDC *hdc) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface); + TRACE("(%p)->(%p): Relay\n", This, hdc); + + if(!hdc) + return DDERR_INVALIDPARAMS; + + return IWineD3DSurface_GetDC(This->WineD3DSurface, + hdc); +} + +/***************************************************************************** + * IDirectDrawSurface7::ReleaseDC + * + * Releases the DC that was constructed with GetDC + * + * Params: + * hdc: HDC to release + * + * Returns: + * DD_OK on success + * For more details, see IWineD3DSurface::ReleaseDC + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawSurfaceImpl_ReleaseDC(IDirectDrawSurface7 *iface, + HDC hdc) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface); + TRACE("(%p)->(%p): Relay\n", This, hdc); + + return IWineD3DSurface_ReleaseDC(This->WineD3DSurface, hdc); +} + +/***************************************************************************** + * IDirectDrawSurface7::GetCaps + * + * Returns the surface's caps + * + * Params: + * Caps: Address to write the caps to + * + * Returns: + * DD_OK on success + * DDERR_INVALIDPARAMS if Caps is NULL + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawSurfaceImpl_GetCaps(IDirectDrawSurface7 *iface, + DDSCAPS2 *Caps) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface); + TRACE("(%p)->(%p)\n",This,Caps); + + if(!Caps) + return DDERR_INVALIDPARAMS; + + *Caps = This->surface_desc.ddsCaps; + return DD_OK; +} + +/***************************************************************************** + * IDirectDrawSurface7::SetPriority + * + * Sets a texture priority for managed textures. + * + * Params: + * Priority: The new priority + * + * Returns: + * DD_OK on success + * For more details, see IWineD3DSurface::SetPriority + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawSurfaceImpl_SetPriority(IDirectDrawSurface7 *iface, DWORD Priority) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface); + TRACE("(%p)->(%ld): Relay!\n",This,Priority); + + return IWineD3DSurface_SetPriority(This->WineD3DSurface, Priority); +} + +/***************************************************************************** + * IDirectDrawSurface7::GetPriority + * + * Returns the surface's priority + * + * Params: + * Priority: Address of a variable to write the priority to + * + * Returns: + * D3D_OK on success + * DDERR_INVALIDPARAMS if Priority == NULL + * For more details, see IWineD3DSurface::GetPriority + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawSurfaceImpl_GetPriority(IDirectDrawSurface7 *iface, + DWORD *Priority) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface); + TRACE("(%p)->(%p): Relay\n",This,Priority); + + if(!Priority) + return DDERR_INVALIDPARAMS; + + *Priority = IWineD3DSurface_GetPriority(This->WineD3DSurface); + return DD_OK; +} + +/***************************************************************************** + * IDirectDrawSurface7::SetPrivateData + * + * Stores some data in the surface that is intended for the application's + * use. + * + * Params: + * tag: GUID that identifies the data + * Data: Pointer to the private data + * Size: Size of the private data + * Flags: Some flags + * + * Returns: + * D3D_OK on success + * For more details, see IWineD3DSurface::SetPrivateData + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawSurfaceImpl_SetPrivateData(IDirectDrawSurface7 *iface, + REFGUID tag, + void *Data, + DWORD Size, + DWORD Flags) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface); + TRACE("(%p)->(%s,%p,%ld,%lx): Relay\n", This, debugstr_guid(tag), Data, Size, Flags); + + return IWineD3DSurface_SetPrivateData(This->WineD3DSurface, + tag, + Data, + Size, + Flags); +} + +/***************************************************************************** + * IDirectDrawSurface7::GetPrivateData + * + * Returnes the private data set with IDirectDrawSurface7::SetPrivateData + * + * Params: + * tag: GUID of the data to return + * Data: Address where to write the data to + * Size: Size of the buffer at Data + * + * Returns: + * DD_OK on success + * DDERR_INVALIDPARAMS if Data is NULL + * For more details, see IWineD3DSurface::GetPrivateData + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawSurfaceImpl_GetPrivateData(IDirectDrawSurface7 *iface, + REFGUID tag, + void *Data, + DWORD *Size) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface); + TRACE("(%p)->(%s,%p,%p): Relay\n", This, debugstr_guid(tag), Data, Size); + + if(!Data) + return DDERR_INVALIDPARAMS; + + return IWineD3DSurface_GetPrivateData(This->WineD3DSurface, + tag, + Data, + Size); +} + +/***************************************************************************** + * IDirectDrawSurface7::FreePrivateData + * + * Frees private stored in the surface + * + * Params: + * tag: Tag of the data to free + * + * Returns: + * D3D_OK on success + * For more details, see IWineD3DSurface::FreePrivateData + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawSurfaceImpl_FreePrivateData(IDirectDrawSurface7 *iface, + REFGUID tag) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface); + TRACE("(%p)->(%s): Relay\n", This, debugstr_guid(tag)); + + return IWineD3DSurface_FreePrivateData(This->WineD3DSurface, tag); +} + +/***************************************************************************** + * IDirectDrawSurface7::PageLock + * + * Prevents a sysmem surface from being paged out + * + * Params: + * Flags: Not used, must be 0(unchecked) + * + * Returns: + * DD_OK, because it's a stub + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawSurfaceImpl_PageLock(IDirectDrawSurface7 *iface, + DWORD Flags) +{ + TRACE("(%p)->(%lx)\n", iface, Flags); + + /* This is Windows memory management related - we don't need this */ + return DD_OK; +} + +/***************************************************************************** + * IDirectDrawSurface7::PageUnlock + * + * Allows a sysmem surface to be paged out + * + * Params: + * Flags: Not used, must be 0(unckeched) + * + * Returns: + * DD_OK, because it's a stub + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawSurfaceImpl_PageUnlock(IDirectDrawSurface7 *iface, + DWORD Flags) +{ + TRACE("(%p)->(%lx)\n", iface, Flags); + + return DD_OK; +} + +/***************************************************************************** + * IDirectDrawSurface7::BltBatch + * + * An unimplemented function + * + * Params: + * ? + * + * Returns: + * DDERR_UNSUPPORTED + * + *****************************************************************************/ +HRESULT WINAPI IDirectDrawSurfaceImpl_BltBatch(IDirectDrawSurface7 *iface, DDBLTBATCH *Batch, DWORD Count, DWORD Flags) +{ + TRACE("(%p)->(%p,%ld,%08lx)\n",iface,Batch,Count,Flags); + + /* MSDN: "not currently implemented" */ + return DDERR_UNSUPPORTED; +} + +/***************************************************************************** + * IDirectDrawSurface7::EnumAttachedSurfaces + * + * Enumerates all surfaces attached to this surface + * + * Params: + * context: Pointer to pass unmodified to the callback + * cb: Callback function to call for each surface + * + * Returns: + * DD_OK on success + * DDERR_INVALIDPARAMS if cb is NULL + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawSurfaceImpl_EnumAttachedSurfaces(IDirectDrawSurface7 *iface, + void *context, + LPDDENUMSURFACESCALLBACK7 cb) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface); + IDirectDrawSurfaceImpl *surf; + DDSURFACEDESC2 desc; + + /* Attached surfaces aren't handled in WineD3D */ + TRACE("(%p)->(%p,%p)\n",This,context,cb); + + if(!cb) + return DDERR_INVALIDPARAMS; + + for (surf = This->next_complex; surf != NULL; surf = surf->next_complex) + { + IDirectDrawSurface7_AddRef(ICOM_INTERFACE(surf, IDirectDrawSurface7)); + desc = surf->surface_desc; + /* check: != DDENUMRET_OK or == DDENUMRET_CANCEL? */ + if (cb(ICOM_INTERFACE(surf, IDirectDrawSurface7), &desc, context) == DDENUMRET_CANCEL) + return DD_OK; + } + + for (surf = This->next_attached; surf != NULL; surf = surf->next_attached) + { + IDirectDrawSurface7_AddRef(ICOM_INTERFACE(surf, IDirectDrawSurface7)); + desc = surf->surface_desc; + /* check: != DDENUMRET_OK or == DDENUMRET_CANCEL? */ + if (cb( ICOM_INTERFACE(surf, IDirectDrawSurface7), &desc, context) == DDENUMRET_CANCEL) + return DD_OK; + } + + TRACE(" end of enumeration.\n"); + + return DD_OK; +} + +/***************************************************************************** + * IDirectDrawSurface7::EnumOverlayZOrders + * + * "Enumerates the overlay surfaces on the specified destination" + * + * Params: + * Flags: DDENUMOVERLAYZ_BACKTOFRONT or DDENUMOVERLAYZ_FRONTTOBACK + * context: context to pass back to the callback + * cb: callback function to call for each enumerated surface + * + * Returns: + * DD_OK, because it's a stub + * + *****************************************************************************/ +HRESULT WINAPI +IDirectDrawSurfaceImpl_EnumOverlayZOrders(IDirectDrawSurface7 *iface, + DWORD Flags, + void *context, + LPDDENUMSURFACESCALLBACK7 cb) +{ + FIXME("(%p)->(%lx,%p,%p): Stub!\n", iface, Flags, context, cb); + + return DD_OK; +} + +/***************************************************************************** + * IDirectDrawSurface7::GetBltStatus + * + * Returns the blitting status + * + * Params: + * Flags: DDGBS_CANBLT or DDGBS_ISBLTDONE + * + * Returns: + * See IWineD3DSurface::Blt + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawSurfaceImpl_GetBltStatus(IDirectDrawSurface7 *iface, + DWORD Flags) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface); + TRACE("(%p)->(%lx): Relay\n", This, Flags); + + return IWineD3DSurface_GetBltStatus(This->WineD3DSurface, Flags); +} + +/***************************************************************************** + * IDirectDrawSurface7::GetColorKey + * + * Returns the color key assigned to the surface + * + * Params: + * Flags: Some flags + * CKey: Address to store the key to + * + * Returns: + * DD_OK on success + * DDERR_INVALIDPARAMS if CKey is NULL + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawSurfaceImpl_GetColorKey(IDirectDrawSurface7 *iface, + DWORD Flags, + DDCOLORKEY *CKey) +{ + /* There is a DDERR_NOCOLORKEY error, but how do we know if a color key + * isn't there? That's like saying that an int isn't there. (Which MS + * has done in other docs.) */ + + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface); + + if(!CKey) + return DDERR_INVALIDPARAMS; + + switch (Flags) + { + case DDCKEY_DESTBLT: + *CKey = This->surface_desc.ddckCKDestBlt; + break; + + case DDCKEY_DESTOVERLAY: + *CKey = This->surface_desc.u3.ddckCKDestOverlay; + break; + + case DDCKEY_SRCBLT: + *CKey = This->surface_desc.ddckCKSrcBlt; + break; + + case DDCKEY_SRCOVERLAY: + *CKey = This->surface_desc.ddckCKSrcOverlay; + break; + + default: + return DDERR_INVALIDPARAMS; + } + + return DD_OK; +} + +/***************************************************************************** + * IDirectDrawSurface7::GetFlipStatus + * + * Returns the flipping status of the surface + * + * Params: + * Flags: DDGFS_CANFLIP of DDGFS_ISFLIPDONE + * + * Returns: + * See IWineD3DSurface::GetFlipStatus + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawSurfaceImpl_GetFlipStatus(IDirectDrawSurface7 *iface, + DWORD Flags) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface); + TRACE("(%p)->(%lx): Relay\n", This, Flags); + + return IWineD3DSurface_GetFlipStatus(This->WineD3DSurface, Flags); +} + +/***************************************************************************** + * IDirectDrawSurface7::GetOverlayPosition + * + * Returns the display coordinates of a visible and active overlay surface + * + * Params: + * X + * Y + * + * Returns: + * DDERR_NOTAOVERLAYSURFACE, because it's a stub + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawSurfaceImpl_GetOverlayPosition(IDirectDrawSurface7 *iface, + LONG *X, + LONG *Y) { + FIXME("(%p)->(%p,%p): Stub!\n", iface, X, Y); + + return DDERR_NOTAOVERLAYSURFACE; +} + +/***************************************************************************** + * IDirectDrawSurface7::GetPixelFormat + * + * Returns the pixel format of the Surface + * + * Params: + * PixelFormat: Pointer to a DDPIXELFORMAT structure to which the pixel + * format should be written + * + * Returns: + * DD_OK on success + * DDERR_INVALIDPARAMS if PixelFormat is NULL + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawSurfaceImpl_GetPixelFormat(IDirectDrawSurface7 *iface, + DDPIXELFORMAT *PixelFormat) +{ + /* What is DDERR_INVALIDSURFACETYPE for here? */ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface); + TRACE("(%p)->(%p)\n",This,PixelFormat); + + if(!PixelFormat) + return DDERR_INVALIDPARAMS; + + DD_STRUCT_COPY_BYSIZE(PixelFormat,&This->surface_desc.u4.ddpfPixelFormat); + + return DD_OK; +} + + +/***************************************************************************** + * IDirectDrawSurface7::GetSurfaceDesc + * + * Returns the description of this surface + * + * Params: + * DDSD: Address of a DDSURFACEDESC2 structure that is to be filled with the + * surface desc + * + * Returns: + * DD_OK on success + * DDERR_INVALIDPARAMS if DDSD is NULL + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawSurfaceImpl_GetSurfaceDesc(IDirectDrawSurface7 *iface, + DDSURFACEDESC2 *DDSD) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface); + + TRACE("(%p)->(%p)\n",This,DDSD); + + if(!DDSD) + return DDERR_INVALIDPARAMS; + + if ((DDSD->dwSize < sizeof(DDSURFACEDESC)) || + (DDSD->dwSize > sizeof(DDSURFACEDESC2))) + { + ERR("Impossible/Strange struct size %ld.\n",DDSD->dwSize); + return DDERR_GENERIC; + } + + DD_STRUCT_COPY_BYSIZE(DDSD,&This->surface_desc); + TRACE("Returning surface desc:\n"); + if (TRACE_ON(ddraw)) DDRAW_dump_surface_desc(DDSD); + + return DD_OK; +} + +/***************************************************************************** + * IDirectDrawSurface7::Initialize + * + * Initializes the surface. This is a no-op in Wine + * + * Params: + * DD: Pointer to an DirectDraw interface + * DDSD: Surface description for initialization + * + * Returns: + * DDERR_ALREADYINITIALIZED + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawSurfaceImpl_Initialize(IDirectDrawSurface7 *iface, + IDirectDraw *DD, + DDSURFACEDESC2 *DDSD) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface); + IDirectDrawImpl *ddimpl = ICOM_OBJECT(IDirectDrawImpl, IDirectDraw, DD); + TRACE("(%p)->(%p,%p)\n",This,ddimpl,DDSD); + + return DDERR_ALREADYINITIALIZED; +} + +/***************************************************************************** + * IDirectDrawSurface7::IsLost + * + * Checks if the surface is lost + * + * Returns: + * DD_OK, if the surface is useable + * DDERR_ISLOST if the surface is lost + * See IWineD3DSurface::IsLost for more details + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawSurfaceImpl_IsLost(IDirectDrawSurface7 *iface) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface); + TRACE("(%p)\n", This); + + /* We lose the surface if the implementation was changed */ + if(This->ImplType != This->ddraw->ImplType) + { + /* But this shouldn't happen. When we change the implementation, + * all surfaces are re-created automatically, and their content + * is copied + */ + ERR(" (%p) Implementation was changed from %d to %d\n", This, This->ImplType, This->ddraw->ImplType); + return DDERR_SURFACELOST; + } + + return IWineD3DSurface_IsLost(This->WineD3DSurface); +} + +/***************************************************************************** + * IDirectDrawSurface7::Restore + * + * Restores a lost surface. This makes the surface usable again, but + * doesn't reload its old contents + * + * Returns: + * DD_OK on success + * See IWineD3DSurface::Restore for more details + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawSurfaceImpl_Restore(IDirectDrawSurface7 *iface) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface); + TRACE("(%p)\n", This); + + if(This->ImplType != This->ddraw->ImplType) + { + /* Call the recreation callback. Make sure to AddRef first */ + IDirectDrawSurface_AddRef(iface); + IDirectDrawImpl_RecreateSurfacesCallback(iface, + &This->surface_desc, + NULL /* Not needed */); + } + return IWineD3DSurface_Restore(This->WineD3DSurface); +} + +/***************************************************************************** + * IDirectDrawSurface7::SetOverlayPosition + * + * Changes the display coordinates of an overlay surface + * + * Params: + * X: + * Y: + * + * Returns: + * DDERR_NOTAOVERLAYSURFACE, because we don't support overlays right now + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawSurfaceImpl_SetOverlayPosition(IDirectDrawSurface7 *iface, + LONG X, + LONG Y) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface); + FIXME("(%p)->(%ld,%ld): Stub!\n", This, X, Y); + return DDERR_NOTAOVERLAYSURFACE; +} + +/***************************************************************************** + * IDirectDrawSurface7::UpdateOverlay + * + * Modifies the attributes of an overlay surface. + * + * Params: + * SrcRect: The section of the source being used for the overlay + * DstSurface: Address of the surface that is overlaid + * DstRect: Place of the overlay + * Flags: some DDOVER_* flags + * + * Returns: + * DDERR_UNSUPPORTED, because we don't support overlays + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawSurfaceImpl_UpdateOverlay(IDirectDrawSurface7 *iface, + LPRECT SrcRect, + IDirectDrawSurface7 *DstSurface, + LPRECT DstRect, + DWORD Flags, + LPDDOVERLAYFX FX) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface); + IDirectDrawSurfaceImpl *Dst = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, DstSurface); + FIXME("(%p)->(%p,%p,%p,%lx,%p): Stub!\n", This, SrcRect, Dst, DstRect, Flags, FX); + return DDERR_UNSUPPORTED; +} + +/***************************************************************************** + * IDirectDrawSurface7::UpdateOverlayDisplay + * + * The DX7 sdk says that it's not implemented + * + * Params: + * Flags: ? + * + * Returns: DDERR_UNSUPPORTED, because we don't support overlays + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawSurfaceImpl_UpdateOverlayDisplay(IDirectDrawSurface7 *iface, + DWORD Flags) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface); + TRACE("(%p)->(%lx)\n", This, Flags); + return DDERR_UNSUPPORTED; +} + +/***************************************************************************** + * IDirectDrawSurface7::UpdateOverlayZOrder + * + * Sets an overlay's Z order + * + * Params: + * Flags: DDOVERZ_* flags + * DDSRef: Defines the relative position in the overlay chain + * + * Returns: + * DDERR_NOTOVERLAYSURFACE, because we don't support overlays + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawSurfaceImpl_UpdateOverlayZOrder(IDirectDrawSurface7 *iface, + DWORD Flags, + IDirectDrawSurface7 *DDSRef) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface); + IDirectDrawSurfaceImpl *Ref = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, DDSRef); + FIXME("(%p)->(%lx,%p)\n", This, Flags, Ref); + return DDERR_NOTAOVERLAYSURFACE; +} + +/***************************************************************************** + * IDirectDrawSurface7::GetDDInterface + * + * Returns the IDirectDraw7 interface pointer of the DirectDraw object this + * surface belongs to + * + * Params: + * DD: Address to write the interface pointer to + * + * Returns: + * DD_OK on success + * DDERR_INVALIDPARAMS if DD is NULL + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawSurfaceImpl_GetDDInterface(IDirectDrawSurface7 *iface, + void **DD) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface); + + TRACE("(%p)->(%p)\n",This,DD); + + if(!DD) + return DDERR_INVALIDPARAMS; + + *((IDirectDraw7 **) DD) = ICOM_INTERFACE(This->ddraw, IDirectDraw7); + IDirectDraw7_AddRef( (IDirectDraw7 *) *DD); + + return DD_OK; +} + +/* This seems also windows implementation specific - I don't think WineD3D needs this */ +HRESULT WINAPI IDirectDrawSurfaceImpl_ChangeUniquenessValue(IDirectDrawSurface7 *iface) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface); + volatile IDirectDrawSurfaceImpl* vThis = This; + + TRACE("(%p)\n",This); + /* A uniquness value of 0 is apparently special. + * This needs to be checked. */ + while (1) { + DWORD old_uniqueness_value = vThis->uniqueness_value; + DWORD new_uniqueness_value = old_uniqueness_value+1; + + if (old_uniqueness_value == 0) break; + if (new_uniqueness_value == 0) new_uniqueness_value = 1; + + if (InterlockedCompareExchange((LONG*)&vThis->uniqueness_value, + old_uniqueness_value, + new_uniqueness_value) + == old_uniqueness_value) + break; + } + + return DD_OK; +} + +HRESULT WINAPI IDirectDrawSurfaceImpl_GetUniquenessValue(IDirectDrawSurface7 *iface, LPDWORD pValue) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface); + + TRACE("(%p)->(%p)\n",This,pValue); + *pValue = This->uniqueness_value; + return DD_OK; +} + +/***************************************************************************** + * IDirectDrawSurface7::SetLOD + * + * Sets the level of detail of a texture + * + * Params: + * MaxLOD: LOD to set + * + * Returns: + * DD_OK on success + * DDERR_INVALIDOBJECT if the surface is invalid for this method + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawSurfaceImpl_SetLOD(IDirectDrawSurface7 *iface, + DWORD MaxLOD) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface); + TRACE("(%p)->(%ld)\n", This, MaxLOD); + + if (!(This->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_TEXTUREMANAGE)) + return DDERR_INVALIDOBJECT; + + if(!This->wineD3DTexture) + { + ERR("(%p) The DirectDraw texture has no WineD3DTexture!\n", This); + return DDERR_INVALIDOBJECT; + } + + return IWineD3DTexture_SetLOD(This->wineD3DTexture, + MaxLOD); +} + +/***************************************************************************** + * IDirectDrawSurface7::GetLOD + * + * Returns the level of detail of a Direct3D texture + * + * Params: + * MaxLOD: Address to write the LOD to + * + * Returns: + * DD_OK on success + * DDERR_INVALIDPARAMS if MaxLOD is NULL + * DDERR_INVALIDOBJECT if the surface is invalid for this method + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawSurfaceImpl_GetLOD(IDirectDrawSurface7 *iface, + DWORD *MaxLOD) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface); + TRACE("(%p)->(%p)\n", This, MaxLOD); + + if(!MaxLOD) + return DDERR_INVALIDPARAMS; + + if (!(This->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_TEXTUREMANAGE)) + return DDERR_INVALIDOBJECT; + + *MaxLOD = IWineD3DTexture_GetLOD(This->wineD3DTexture); + return DD_OK; +} + +/***************************************************************************** + * IDirectDrawSurface7::BltFast + * + * Performs a fast Blit. + * + * Params: + * dstx: The x coordinate to blit to on the destination + * dsty: The y coordinate to blit to on the destination + * Source: The source surface + * rsrc: The source rectangle + * trans: Type of transfer. Some DDBLTFAST_* flags + * + * Returns: + * DD_OK on success + * For more details, see IWineD3DSurface::BltFast + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawSurfaceImpl_BltFast(IDirectDrawSurface7 *iface, + DWORD dstx, + DWORD dsty, + IDirectDrawSurface7 *Source, + RECT *rsrc, + DWORD trans) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface); + IDirectDrawSurfaceImpl *src = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, Source); + TRACE("(%p)->(%ld,%ld,%p,%p,%ld): Relay\n", This, dstx, dsty, Source, rsrc, trans); + + return IWineD3DSurface_BltFast(This->WineD3DSurface, + dstx, dsty, + src ? src->WineD3DSurface : NULL, + rsrc, + trans); +} + +/***************************************************************************** + * IDirectDrawSurface7::GetClipper + * + * Returns the IDirectDrawClipper interface of the clipper assigned to this + * surface + * + * Params: + * Clipper: Address to store the interface pointer at + * + * Returns: + * DD_OK on success + * DDERR_INVALIDPARAMS if Clipper is NULL + * DDERR_NOCLIPPERATTACHED if there's no clipper attached + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawSurfaceImpl_GetClipper(IDirectDrawSurface7 *iface, + IDirectDrawClipper **Clipper) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface); + TRACE("(%p)->(%p)\n", This, Clipper); + + if(!Clipper) + return DDERR_INVALIDPARAMS; + + if(This->clipper == NULL) + return DDERR_NOCLIPPERATTACHED; + + *Clipper = ICOM_INTERFACE(This->clipper, IDirectDrawClipper); + IDirectDrawClipper_AddRef(*Clipper); + return DD_OK; +} + +/***************************************************************************** + * IDirectDrawSurface7::SetClipper + * + * Sets a clipper for the surface + * + * Params: + * Clipper: IDirectDrawClipper interface of the clipper to set + * + * Returns: + * DD_OK on success + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawSurfaceImpl_SetClipper(IDirectDrawSurface7 *iface, + IDirectDrawClipper *Clipper) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface); + + TRACE("(%p)->(%p)\n",This,Clipper); + if (ICOM_OBJECT(IDirectDrawClipperImpl, IDirectDrawClipper, Clipper) == This->clipper) + return DD_OK; + + if (This->clipper != NULL) + IDirectDrawClipper_Release(ICOM_INTERFACE(This->clipper, IDirectDrawClipper) ); + + This->clipper = ICOM_OBJECT(IDirectDrawClipperImpl, IDirectDrawClipper, Clipper); + if (Clipper != NULL) + IDirectDrawClipper_AddRef(Clipper); + + return DD_OK; +} + +/***************************************************************************** + * IDirectDrawSurface7::SetSurfaceDesc + * + * Sets the surface description. It can override the pixel format, the surface + * memory, ... + * It's not really tested. + * + * Params: + * DDSD: Pointer to the new surface description to set + * Flags: Some flags + * + * Returns: + * DD_OK on success + * DDERR_INVALIDPARAMS if DDSD is NULL + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawSurfaceImpl_SetSurfaceDesc(IDirectDrawSurface7 *iface, + DDSURFACEDESC2 *DDSD, + DWORD Flags) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface); + BYTE *newSurface = NULL; + DWORD newSize = 0; + WINED3DFORMAT newFormat = WINED3DFMT_UNKNOWN; + HRESULT hr; + FIXME("(%p)->(%p,%lx)\n", This, DDSD, Flags); + assert(0); + + if(!DDSD) + return DDERR_INVALIDPARAMS; + + if (DDSD->dwFlags & DDSD_PIXELFORMAT) + { + newFormat = PixelFormat_DD2WineD3D(&DDSD->u4.ddpfPixelFormat); + } + if (DDSD->dwFlags & DDSD_LPSURFACE) + { + newSurface = DDSD->lpSurface; + newSize = DDSD->u1.dwLinearSize; + /* to avoid unpredictable things */ + assert(newSize != 0); + } + + /* Better: Use SetFormat */ + hr = IWineD3DSurface_SetPixelFormat(This->WineD3DSurface, + newFormat, + newSurface, + newSize); + if(hr != DD_OK) return hr; + + /* Store the new data. Not really necessary, as WineD3D stores it too, + * but for completeness + */ + if(newFormat != WINED3DFMT_UNKNOWN) + { + This->surface_desc.dwFlags |= DDSD_PIXELFORMAT; + This->surface_desc.u4.ddpfPixelFormat = DDSD->u4.ddpfPixelFormat; + } + if(newSurface != NULL) + { + This->surface_desc.lpSurface = newSurface; + This->surface_desc.u1.dwLinearSize = newSize; + } + + return DD_OK; +} + +/***************************************************************************** + * IDirectDrawSurface7::GetPalette + * + * Returns the IDirectDrawPalette interface of the palette currently assigned + * to the surface + * + * Params: + * Pal: Address to write the interface pointer to + * + * Returns: + * DD_OK on success + * DDERR_INVALIDPARAMS if Pal is NULL + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawSurfaceImpl_GetPalette(IDirectDrawSurface7 *iface, + IDirectDrawPalette **Pal) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface); + IWineD3DPalette *wPal; + HRESULT hr; + TRACE("(%p)->(%p): Relay\n", This, Pal); + + if(!Pal) + return DDERR_INVALIDPARAMS; + + hr = IWineD3DSurface_GetPalette(This->WineD3DSurface, &wPal); + if(hr != DD_OK) return hr; + + if(wPal) + { + hr = IWineD3DPalette_GetParent(wPal, (IUnknown **) Pal); + } + else + { + *Pal = NULL; + } + + return hr; +} + +/***************************************************************************** + * IDirectDrawSurface7::SetColorKey + * + * Sets the color keying options for the surface. Observations showed that + * in case of complex surfaces the color key has to be assigned to all + * sublevels. + * + * Params: + * Flags: DDCKEY_* + * CKey: The new color key + * + * Returns: + * DD_OK on success + * See IWineD3DSurface::SetColorKey for details + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawSurfaceImpl_SetColorKey(IDirectDrawSurface7 *iface, + DWORD Flags, + DDCOLORKEY *CKey) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface); + IDirectDrawSurfaceImpl *surf; + HRESULT hr; + TRACE("(%p)->(%lx,%p)\n", This, Flags, CKey); + + for(surf = This->first_complex; surf; surf = surf->next_complex) + { + hr = IWineD3DSurface_SetColorKey(surf->WineD3DSurface, + Flags, + CKey); + if(FAILED(hr)) + { + WARN("IWineD3DSurface::SetColorKey for surface %p failed with hr=%08lx\n", + surf->WineD3DSurface, hr); + return hr; + } + } + return DD_OK; +} + +/***************************************************************************** + * IDirectDrawSurface7::SetPalette + * + * Assigns a DirectDrawPalette object to the surface + * + * Params: + * Pal: Interface to the palette to set + * + * Returns: + * DD_OK on success + * + *****************************************************************************/ +static HRESULT WINAPI +IDirectDrawSurfaceImpl_SetPalette(IDirectDrawSurface7 *iface, + IDirectDrawPalette *Pal) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawSurface7, iface); + IDirectDrawPalette *oldPal; + IDirectDrawSurfaceImpl *surf; + IDirectDrawPaletteImpl *PalImpl = ICOM_OBJECT(IDirectDrawPaletteImpl, IDirectDrawPalette, Pal); + HRESULT hr; + TRACE("(%p)->(%p)\n", This, Pal); + + /* Find the old palette */ + hr = IDirectDrawSurface_GetPalette(iface, &oldPal); + if(hr != DD_OK) return hr; + if(oldPal) IDirectDrawPalette_Release(oldPal); /* For the GetPalette */ + + /* Set the new Palette */ + IWineD3DSurface_SetPalette(This->WineD3DSurface, + PalImpl ? PalImpl->wineD3DPalette : NULL); + /* AddRef the Palette */ + if(Pal) IDirectDrawPalette_AddRef(Pal); + + /* Release the old palette */ + if(oldPal) IDirectDrawPalette_Release(oldPal); + + /* If this is a front buffer, also update the back buffers */ + if(This->surface_desc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER) + { + for(surf = This->next_complex; surf != NULL; surf = surf->next_complex) + { + IDirectDrawSurface7_SetPalette(ICOM_INTERFACE(surf, IDirectDrawSurface7), + Pal); + } + } + + return DD_OK; +} + +/***************************************************************************** + * The VTable + *****************************************************************************/ + +const IDirectDrawSurface7Vtbl IDirectDrawSurface7_Vtbl = +{ + /*** IUnknown ***/ + IDirectDrawSurfaceImpl_QueryInterface, + IDirectDrawSurfaceImpl_AddRef, + IDirectDrawSurfaceImpl_Release, + /*** IDirectDrawSurface ***/ + IDirectDrawSurfaceImpl_AddAttachedSurface, + IDirectDrawSurfaceImpl_AddOverlayDirtyRect, + IDirectDrawSurfaceImpl_Blt, + IDirectDrawSurfaceImpl_BltBatch, + IDirectDrawSurfaceImpl_BltFast, + IDirectDrawSurfaceImpl_DeleteAttachedSurface, + IDirectDrawSurfaceImpl_EnumAttachedSurfaces, + IDirectDrawSurfaceImpl_EnumOverlayZOrders, + IDirectDrawSurfaceImpl_Flip, + IDirectDrawSurfaceImpl_GetAttachedSurface, + IDirectDrawSurfaceImpl_GetBltStatus, + IDirectDrawSurfaceImpl_GetCaps, + IDirectDrawSurfaceImpl_GetClipper, + IDirectDrawSurfaceImpl_GetColorKey, + IDirectDrawSurfaceImpl_GetDC, + IDirectDrawSurfaceImpl_GetFlipStatus, + IDirectDrawSurfaceImpl_GetOverlayPosition, + IDirectDrawSurfaceImpl_GetPalette, + IDirectDrawSurfaceImpl_GetPixelFormat, + IDirectDrawSurfaceImpl_GetSurfaceDesc, + IDirectDrawSurfaceImpl_Initialize, + IDirectDrawSurfaceImpl_IsLost, + IDirectDrawSurfaceImpl_Lock, + IDirectDrawSurfaceImpl_ReleaseDC, + IDirectDrawSurfaceImpl_Restore, + IDirectDrawSurfaceImpl_SetClipper, + IDirectDrawSurfaceImpl_SetColorKey, + IDirectDrawSurfaceImpl_SetOverlayPosition, + IDirectDrawSurfaceImpl_SetPalette, + IDirectDrawSurfaceImpl_Unlock, + IDirectDrawSurfaceImpl_UpdateOverlay, + IDirectDrawSurfaceImpl_UpdateOverlayDisplay, + IDirectDrawSurfaceImpl_UpdateOverlayZOrder, + /*** IDirectDrawSurface2 ***/ + IDirectDrawSurfaceImpl_GetDDInterface, + IDirectDrawSurfaceImpl_PageLock, + IDirectDrawSurfaceImpl_PageUnlock, + /*** IDirectDrawSurface3 ***/ + IDirectDrawSurfaceImpl_SetSurfaceDesc, + /*** IDirectDrawSurface4 ***/ + IDirectDrawSurfaceImpl_SetPrivateData, + IDirectDrawSurfaceImpl_GetPrivateData, + IDirectDrawSurfaceImpl_FreePrivateData, + IDirectDrawSurfaceImpl_GetUniquenessValue, + IDirectDrawSurfaceImpl_ChangeUniquenessValue, + /*** IDirectDrawSurface7 ***/ + IDirectDrawSurfaceImpl_SetPriority, + IDirectDrawSurfaceImpl_GetPriority, + IDirectDrawSurfaceImpl_SetLOD, + IDirectDrawSurfaceImpl_GetLOD +}; diff --git a/dlls/ddraw/surface_dib.c b/dlls/ddraw/surface_dib.c deleted file mode 100644 index c3a8ab1e05..0000000000 --- a/dlls/ddraw/surface_dib.c +++ /dev/null @@ -1,1483 +0,0 @@ -/* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "config.h" -#include "wine/port.h" - -#include -#include -#include - -#define NONAMELESSUNION -#define NONAMELESSSTRUCT - -#include "winerror.h" -#include "wine/debug.h" -#include "ddraw_private.h" -#include "d3d_private.h" - -WINE_DEFAULT_DEBUG_CHANNEL(ddraw); - -/* FIXME */ -extern HBITMAP DIB_CreateDIBSection( HDC hdc, const BITMAPINFO *bmi, UINT usage, VOID **bits, - HANDLE section, DWORD offset, DWORD ovr_pitch ); - -static const IDirectDrawSurface7Vtbl 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 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof(BITMAPINFOHEADER) + 3 * sizeof(DWORD)); - break; - - case 24: - b_info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof(BITMAPINFOHEADER)); - break; - - default: - /* Allocate extra space for a palette. */ - b_info = 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_LPSURFACE; - - /* Ensure that DDSD_PITCH is respected for DDPF_FOURCC surfaces too */ - if (This->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC && !(This->surface_desc.dwFlags & DDSD_PITCH)) { - This->surface_desc.lpSurface - = VirtualAlloc(NULL, This->surface_desc.u1.dwLinearSize, MEM_COMMIT, PAGE_READWRITE); - This->surface_desc.dwFlags |= DDSD_LINEARSIZE; - } else { - 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_COMMIT, PAGE_READWRITE); - This->surface_desc.dwFlags |= DDSD_PITCH; - } - - 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; -} - -static void ComputeShifts(DWORD mask, DWORD* lshift, DWORD* rshift) -{ - int pos = 0; - int bits = 0; - *lshift = 0; - *rshift = 0; - - if (!mask) - return; - - while(!(mask & (1 << pos))) - pos++; - - while(mask & (1 << (pos+bits))) - bits++; - - *lshift = pos; - *rshift = 8 - bits; -} - -/* This is used to factorize the decompression between the Blt and BltFast code */ -static void DoDXTCDecompression(const DDSURFACEDESC2 *sdesc, const DDSURFACEDESC2 *ddesc) -{ - DWORD rs,rb,rm; - DWORD gs,gb,gm; - DWORD bs,bb,bm; - DWORD as,ab,am; - - if (!s3tc_initialized) { - /* FIXME: We may fake this by rendering the texture into the framebuffer using OpenGL functions and reading back - * the framebuffer. This will be slow and somewhat ugly. */ - FIXME("Manual S3TC decompression is not supported in native mode\n"); - return; - } - - rm = ddesc->u4.ddpfPixelFormat.u2.dwRBitMask; - ComputeShifts(rm, &rs, &rb); - gm = ddesc->u4.ddpfPixelFormat.u3.dwGBitMask; - ComputeShifts(gm, &gs, &gb); - bm = ddesc->u4.ddpfPixelFormat.u4.dwBBitMask; - ComputeShifts(bm, &bs, &bb); - am = ddesc->u4.ddpfPixelFormat.u5.dwRGBAlphaBitMask; - ComputeShifts(am, &as, &ab); - if (sdesc->u4.ddpfPixelFormat.dwFourCC == MAKE_FOURCC('D','X','T','1')) { - int is16 = ddesc->u4.ddpfPixelFormat.u1.dwRGBBitCount == 16; - int pitch = ddesc->u1.lPitch; - int width = ddesc->dwWidth; - int height = ddesc->dwHeight; - int x,y; - unsigned char* dst = (unsigned char*) ddesc->lpSurface; - unsigned char* src = (unsigned char*) sdesc->lpSurface; - for (x = 0; x < width; x++) - for (y =0; y < height; y++) { - DWORD pixel = 0; - BYTE data[4]; - (*fetch_2d_texel_rgba_dxt1)(width, src, x, y, data); - pixel = 0; - pixel |= ((data[0] >> rb) << rs) & rm; - pixel |= ((data[1] >> gb) << gs) & gm; - pixel |= ((data[2] >> bb) << bs) & bm; - pixel |= ((data[3] >> ab) << as) & am; - if (is16) - *((WORD*)(dst+y*pitch+x*(is16?2:4))) = pixel; - else - *((DWORD*)(dst+y*pitch+x*(is16?2:4))) = pixel; - } - } else if (sdesc->u4.ddpfPixelFormat.dwFourCC == MAKE_FOURCC('D','X','T','3')) { - int is16 = ddesc->u4.ddpfPixelFormat.u1.dwRGBBitCount == 16; - int pitch = ddesc->u1.lPitch; - int width = ddesc->dwWidth; - int height = ddesc->dwHeight; - int x,y; - unsigned char* dst = (unsigned char*) ddesc->lpSurface; - unsigned char* src = (unsigned char*) sdesc->lpSurface; - for (x = 0; x < width; x++) - for (y =0; y < height; y++) { - DWORD pixel = 0; - BYTE data[4]; - (*fetch_2d_texel_rgba_dxt3)(width, src, x, y, data); - pixel = 0; - pixel |= ((data[0] >> rb) << rs) & rm; - pixel |= ((data[1] >> gb) << gs) & gm; - pixel |= ((data[2] >> bb) << bs) & bm; - pixel |= ((data[3] >> ab) << as) & am; - if (is16) - *((WORD*)(dst+y*pitch+x*(is16?2:4))) = pixel; - else - *((DWORD*)(dst+y*pitch+x*(is16?2:4))) = pixel; - } - } else if (sdesc->u4.ddpfPixelFormat.dwFourCC == MAKE_FOURCC('D','X','T','5')) { - int is16 = ddesc->u4.ddpfPixelFormat.u1.dwRGBBitCount == 16; - int pitch = ddesc->u1.lPitch; - int width = ddesc->dwWidth; - int height = ddesc->dwHeight; - int x,y; - unsigned char* dst = (unsigned char*) ddesc->lpSurface; - unsigned char* src = (unsigned char*) sdesc->lpSurface; - for (x = 0; x < width; x++) - for (y =0; y < height; y++) { - DWORD pixel = 0; - BYTE data[4]; - (*fetch_2d_texel_rgba_dxt5)(width, src, x, y, data); - pixel = 0; - pixel |= ((data[0] >> rb) << rs) & rm; - pixel |= ((data[1] >> gb) << gs) & gm; - pixel |= ((data[2] >> bb) << bs) & bm; - pixel |= ((data[3] >> ab) << as) & am; - if (is16) - *((WORD*)(dst+y*pitch+x*(is16?2:4))) = pixel; - else - *((DWORD*)(dst+y*pitch+x*(is16?2:4))) = pixel; - } - } -#if 0 /* Useful for debugging */ - { - static int idx; - char texname[255]; - FILE* f; - sprintf(texname, "dxt_%d.pnm", idx++); - f = fopen(texname,"w"); - DDRAW_dump_surface_to_disk(This, f, 1); - fclose(f); - } -#endif -} - -HRESULT WINAPI -DIB_DirectDrawSurface_Blt(LPDIRECTDRAWSURFACE7 iface, LPRECT rdst, - LPDIRECTDRAWSURFACE7 src, LPRECT rsrc, - DWORD dwFlags, LPDDBLTFX lpbltfx) -{ - IDirectDrawSurfaceImpl *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); - } - } - - if ((This->locked) || ((src != NULL) && (((IDirectDrawSurfaceImpl *)src)->locked))) { - WARN(" Surface is busy, returning DDERR_SURFACEBUSY\n"); - return DDERR_SURFACEBUSY; - } - - /* 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); - ddesc.dwSize = sizeof(ddesc); - - if (src == iface) { - IDirectDrawSurface7_Lock(iface, NULL, &ddesc, 0, 0); - DD_STRUCT_COPY_BYSIZE(&sdesc, &ddesc); - } else { - if (src) IDirectDrawSurface7_Lock(src, NULL, &sdesc, DDLOCK_READONLY, 0); - IDirectDrawSurface7_Lock(iface,NULL,&ddesc,DDLOCK_WRITEONLY,0); - } - - if (!lpbltfx || !(lpbltfx->dwDDFX)) dwFlags &= ~DDBLT_DDFX; - - if ((sdesc.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC) && - (ddesc.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC)) { - if (sdesc.u4.ddpfPixelFormat.dwFourCC != sdesc.u4.ddpfPixelFormat.dwFourCC) { - FIXME("FOURCC->FOURCC copy only supported for the same type of surface\n"); - ret = DDERR_INVALIDPIXELFORMAT; - goto release; - } - memcpy(ddesc.lpSurface, sdesc.lpSurface, ddesc.u1.dwLinearSize); - goto release; - } - - if ((sdesc.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC) && - (!(ddesc.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC))) { - DoDXTCDecompression(&sdesc, &ddesc); - goto release; - } - - 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; - xsrc.left = 0; - xsrc.right = sdesc.dwWidth; - } else { - memset(&xsrc,0,sizeof(xsrc)); - } - } - - /* First check for the validity of source / destination rectangles. This was - verified using a test application + by MSDN. - */ - if ((src != NULL) && - ((xsrc.bottom > sdesc.dwHeight) || (xsrc.bottom < 0) || - (xsrc.top > sdesc.dwHeight) || (xsrc.top < 0) || - (xsrc.left > sdesc.dwWidth) || (xsrc.left < 0) || - (xsrc.right > sdesc.dwWidth) || (xsrc.right < 0) || - (xsrc.right < xsrc.left) || (xsrc.bottom < xsrc.top))) { - WARN("Application gave us bad source rectangle for Blt.\n"); - ret = DDERR_INVALIDRECT; - goto release; - } - /* For the Destination rect, it can be out of bounds on the condition that a clipper - is set for the given surface. - */ - if ((This->clipper == NULL) && - ((xdst.bottom > ddesc.dwHeight) || (xdst.bottom < 0) || - (xdst.top > ddesc.dwHeight) || (xdst.top < 0) || - (xdst.left > ddesc.dwWidth) || (xdst.left < 0) || - (xdst.right > ddesc.dwWidth) || (xdst.right < 0) || - (xdst.right < xdst.left) || (xdst.bottom < xdst.top))) { - WARN("Application gave us bad destination rectangle for Blt without a clipper set.\n"); - ret = DDERR_INVALIDRECT; - goto release; - } - - /* Now handle negative values in the rectangles. Warning: only supported for now - in the 'simple' cases (ie not in any stretching / rotation cases). - - First, the case where nothing is to be done. - */ - if (((xdst.bottom <= 0) || (xdst.right <= 0) || (xdst.top >= (int) ddesc.dwHeight) || (xdst.left >= (int) ddesc.dwWidth)) || - ((src != NULL) && - ((xsrc.bottom <= 0) || (xsrc.right <= 0) || (xsrc.top >= (int) sdesc.dwHeight) || (xsrc.left >= (int) sdesc.dwWidth)))) - { - TRACE("Nothing to be done !\n"); - goto release; - } - - /* The easy case : the source-less blits.... */ - if (src == NULL) { - RECT full_rect; - RECT temp_rect; /* No idea if intersect rect can be the same as one of the source rect */ - - full_rect.left = 0; - full_rect.top = 0; - full_rect.right = ddesc.dwWidth; - full_rect.bottom = ddesc.dwHeight; - IntersectRect(&temp_rect, &full_rect, &xdst); - xdst = temp_rect; - } else { - /* Only handle clipping on the destination rectangle */ - int clip_horiz = (xdst.left < 0) || (xdst.right > (int) ddesc.dwWidth ); - int clip_vert = (xdst.top < 0) || (xdst.bottom > (int) ddesc.dwHeight); - if (clip_vert || clip_horiz) { - /* Now check if this is a special case or not... */ - if ((((xdst.bottom - xdst.top ) != (xsrc.bottom - xsrc.top )) && clip_vert ) || - (((xdst.right - xdst.left) != (xsrc.right - xsrc.left)) && clip_horiz) || - (dwFlags & DDBLT_DDFX)) { - WARN("Out of screen rectangle in special case. Not handled right now.\n"); - goto release; - } - - if (clip_horiz) { - if (xdst.left < 0) { xsrc.left -= xdst.left; xdst.left = 0; } - if (xdst.right > ddesc.dwWidth) { xsrc.right -= (xdst.right - (int) ddesc.dwWidth); xdst.right = (int) ddesc.dwWidth; } - } - if (clip_vert) { - if (xdst.top < 0) { xsrc.top -= xdst.top; xdst.top = 0; } - if (xdst.bottom > ddesc.dwHeight) { xsrc.bottom -= (xdst.bottom - (int) ddesc.dwHeight); xdst.bottom = (int) ddesc.dwHeight; } - } - /* And check if after clipping something is still to be done... */ - if ((xdst.bottom <= 0) || (xdst.right <= 0) || (xdst.top >= (int) ddesc.dwHeight) || (xdst.left >= (int) ddesc.dwWidth) || - (xsrc.bottom <= 0) || (xsrc.right <= 0) || (xsrc.top >= (int) sdesc.dwHeight) || (xsrc.left >= (int) sdesc.dwWidth)) { - TRACE("Nothing to be done after clipping !\n"); - goto release; - } - } - } - - bpp = GET_BPP(ddesc); - srcheight = xsrc.bottom - xsrc.top; - srcwidth = xsrc.right - xsrc.left; - dstheight = xdst.bottom - xdst.top; - dstwidth = xdst.right - xdst.left; - width = (xdst.right - xdst.left) * bpp; - - assert(width <= ddesc.u1.lPitch); - - dbuf = (BYTE*)ddesc.lpSurface+(xdst.top*ddesc.u1.lPitch)+(xdst.left*bpp); - - if (dwFlags & DDBLT_WAIT) { - static BOOL displayed = FALSE; - if (!displayed) - FIXME("Can't handle DDBLT_WAIT flag right now.\n"); - displayed = TRUE; - dwFlags &= ~DDBLT_WAIT; - } - if (dwFlags & DDBLT_ASYNC) { - static BOOL displayed = FALSE; - if (!displayed) - FIXME("Can't handle DDBLT_ASYNC flag right now.\n"); - displayed = TRUE; - dwFlags &= ~DDBLT_ASYNC; - } - if (dwFlags & DDBLT_DONOTWAIT) { - /* DDBLT_DONOTWAIT appeared in DX7 */ - static BOOL displayed = FALSE; - if (!displayed) - FIXME("Can't handle DDBLT_DONOTWAIT flag right now.\n"); - displayed = TRUE; - dwFlags &= ~DDBLT_DONOTWAIT; - } - - /* First, all the 'source-less' blits */ - if (dwFlags & DDBLT_COLORFILL) { - ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, - ddesc.u1.lPitch, lpbltfx->u5.dwFillColor); - dwFlags &= ~DDBLT_COLORFILL; - } - - if (dwFlags & DDBLT_DEPTHFILL) - FIXME("DDBLT_DEPTHFILL needs to be implemented!\n"); - if (dwFlags & DDBLT_ROP) { - /* Catch some degenerate cases here */ - switch(lpbltfx->dwROP) { - case BLACKNESS: - ret = _Blt_ColorFill(dbuf,dstwidth,dstheight,bpp,ddesc.u1.lPitch,0); - break; - case 0xAA0029: /* No-op */ - break; - case WHITENESS: - ret = _Blt_ColorFill(dbuf,dstwidth,dstheight,bpp,ddesc.u1.lPitch,~0); - break; - case SRCCOPY: /* well, we do that below ? */ - break; - default: - FIXME("Unsupported raster op: %08lx Pattern: %p\n", lpbltfx->dwROP, lpbltfx->u5.lpDDSPattern); - goto error; - } - dwFlags &= ~DDBLT_ROP; - } - if (dwFlags & DDBLT_DDROPS) { - FIXME("\tDdraw Raster Ops: %08lx Pattern: %p\n", lpbltfx->dwDDROP, lpbltfx->u5.lpDDSPattern); - } - /* Now the 'with source' blits */ - if (src) { - LPBYTE sbase; - int sx, xinc, sy, yinc; - - if (!dstwidth || !dstheight) /* hmm... stupid program ? */ - goto release; - sbase = (BYTE*)sdesc.lpSurface+(xsrc.top*sdesc.u1.lPitch)+xsrc.left*bpp; - xinc = (srcwidth << 16) / dstwidth; - yinc = (srcheight << 16) / dstheight; - - if (!dwFlags) { - /* No effects, we can cheat here */ - if (dstwidth == srcwidth) { - if (dstheight == srcheight) { - /* No stretching in either direction. This needs to be as - * fast as possible */ - sbuf = sbase; - - /* check for overlapping surfaces */ - if (src != iface || xdst.top < xsrc.top || - xdst.right <= xsrc.left || xsrc.right <= xdst.left) - { - /* no overlap, or dst above src, so copy from top downwards */ - for (y = 0; y < dstheight; y++) - { - memcpy(dbuf, sbuf, width); - sbuf += sdesc.u1.lPitch; - dbuf += ddesc.u1.lPitch; - } - } - else if (xdst.top > xsrc.top) /* copy from bottom upwards */ - { - sbuf += (sdesc.u1.lPitch*dstheight); - dbuf += (ddesc.u1.lPitch*dstheight); - for (y = 0; y < dstheight; y++) - { - sbuf -= sdesc.u1.lPitch; - dbuf -= ddesc.u1.lPitch; - memcpy(dbuf, sbuf, width); - } - } - else /* src and dst overlapping on the same line, use memmove */ - { - for (y = 0; y < dstheight; y++) - { - memmove(dbuf, sbuf, width); - sbuf += sdesc.u1.lPitch; - dbuf += ddesc.u1.lPitch; - } - } - } else { - /* Stretching in Y direction only */ - for (y = sy = 0; y < dstheight; y++, sy += yinc) { - sbuf = sbase + (sy >> 16) * sdesc.u1.lPitch; - memcpy(dbuf, sbuf, width); - dbuf += ddesc.u1.lPitch; - } - } - } else { - /* Stretching in X direction */ - int last_sy = -1; - for (y = sy = 0; y < dstheight; y++, sy += yinc) { - sbuf = sbase + (sy >> 16) * sdesc.u1.lPitch; - - if ((sy >> 16) == (last_sy >> 16)) { - /* this sourcerow is the same as last sourcerow - - * copy already stretched row - */ - memcpy(dbuf, dbuf - ddesc.u1.lPitch, width); - } else { -#define STRETCH_ROW(type) { \ - type *s = (type *) sbuf, *d = (type *) dbuf; \ - for (x = sx = 0; x < dstwidth; x++, sx += xinc) \ - d[x] = s[sx >> 16]; \ - break; } - - switch(bpp) { - case 1: STRETCH_ROW(BYTE) - case 2: STRETCH_ROW(WORD) - case 4: STRETCH_ROW(DWORD) - case 3: { - LPBYTE s,d = dbuf; - for (x = sx = 0; x < dstwidth; x++, sx+= xinc) { - DWORD pixel; - - s = sbuf+3*(sx>>16); - pixel = s[0]|(s[1]<<8)|(s[2]<<16); - d[0] = (pixel )&0xff; - d[1] = (pixel>> 8)&0xff; - d[2] = (pixel>>16)&0xff; - d+=3; - } - break; - } - default: - FIXME("Stretched blit not implemented for bpp %d!\n", bpp*8); - ret = DDERR_UNSUPPORTED; - goto error; - } -#undef STRETCH_ROW - } - dbuf += ddesc.u1.lPitch; - last_sy = sy; - } - } - } else { - LONG dstyinc = ddesc.u1.lPitch, dstxinc = bpp; - DWORD keylow = 0xFFFFFFFF, keyhigh = 0, keymask = 0xFFFFFFFF; - if (dwFlags & (DDBLT_KEYSRC | DDBLT_KEYDEST | DDBLT_KEYSRCOVERRIDE | DDBLT_KEYDESTOVERRIDE)) { - - if (dwFlags & DDBLT_KEYSRC) { - keylow = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue; - keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue; - } else if (dwFlags & DDBLT_KEYDEST){ - keylow = ddesc.ddckCKDestBlt.dwColorSpaceLowValue; - keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue; - } else if (dwFlags & DDBLT_KEYSRCOVERRIDE) { - keylow = lpbltfx->ddckSrcColorkey.dwColorSpaceLowValue; - keyhigh = lpbltfx->ddckSrcColorkey.dwColorSpaceHighValue; - } else { - keylow = lpbltfx->ddckDestColorkey.dwColorSpaceLowValue; - keyhigh = lpbltfx->ddckDestColorkey.dwColorSpaceHighValue; - } - - if(bpp == 1) - keymask = 0xff; - else - keymask = sdesc.u4.ddpfPixelFormat.u2.dwRBitMask | sdesc.u4.ddpfPixelFormat.u3.dwGBitMask | - sdesc.u4.ddpfPixelFormat.u4.dwBBitMask; - - dwFlags &= ~(DDBLT_KEYSRC | DDBLT_KEYDEST | DDBLT_KEYSRCOVERRIDE | DDBLT_KEYDESTOVERRIDE); - } - - if (dwFlags & DDBLT_DDFX) { - LPBYTE dTopLeft, dTopRight, dBottomLeft, dBottomRight, tmp; - LONG tmpxy; - dTopLeft = dbuf; - dTopRight = dbuf+((dstwidth-1)*bpp); - dBottomLeft = dTopLeft+((dstheight-1)*ddesc.u1.lPitch); - dBottomRight = dBottomLeft+((dstwidth-1)*bpp); - - if (lpbltfx->dwDDFX & DDBLTFX_ARITHSTRETCHY){ - /* I don't think we need to do anything about this flag */ - WARN("dwflags=DDBLT_DDFX nothing done for DDBLTFX_ARITHSTRETCHY\n"); - } - if (lpbltfx->dwDDFX & DDBLTFX_MIRRORLEFTRIGHT) { - tmp = dTopRight; - dTopRight = dTopLeft; - dTopLeft = tmp; - tmp = dBottomRight; - dBottomRight = dBottomLeft; - dBottomLeft = tmp; - dstxinc = dstxinc *-1; - } - if (lpbltfx->dwDDFX & DDBLTFX_MIRRORUPDOWN) { - tmp = dTopLeft; - dTopLeft = dBottomLeft; - dBottomLeft = tmp; - tmp = dTopRight; - dTopRight = dBottomRight; - dBottomRight = tmp; - dstyinc = dstyinc *-1; - } - if (lpbltfx->dwDDFX & DDBLTFX_NOTEARING) { - /* I don't think we need to do anything about this flag */ - WARN("dwflags=DDBLT_DDFX nothing done for DDBLTFX_NOTEARING\n"); - } - if (lpbltfx->dwDDFX & DDBLTFX_ROTATE180) { - tmp = dBottomRight; - dBottomRight = dTopLeft; - dTopLeft = tmp; - tmp = dBottomLeft; - dBottomLeft = dTopRight; - dTopRight = tmp; - dstxinc = dstxinc * -1; - dstyinc = dstyinc * -1; - } - if (lpbltfx->dwDDFX & DDBLTFX_ROTATE270) { - tmp = dTopLeft; - dTopLeft = dBottomLeft; - dBottomLeft = dBottomRight; - dBottomRight = dTopRight; - dTopRight = tmp; - tmpxy = dstxinc; - dstxinc = dstyinc; - dstyinc = tmpxy; - dstxinc = dstxinc * -1; - } - if (lpbltfx->dwDDFX & DDBLTFX_ROTATE90) { - tmp = dTopLeft; - dTopLeft = dTopRight; - dTopRight = dBottomRight; - dBottomRight = dBottomLeft; - dBottomLeft = tmp; - tmpxy = dstxinc; - dstxinc = dstyinc; - dstyinc = tmpxy; - dstyinc = dstyinc * -1; - } - if (lpbltfx->dwDDFX & DDBLTFX_ZBUFFERBASEDEST) { - /* I don't think we need to do anything about this flag */ - WARN("dwflags=DDBLT_DDFX nothing done for DDBLTFX_ZBUFFERBASEDEST\n"); - } - dbuf = dTopLeft; - dwFlags &= ~(DDBLT_DDFX); - } - -#define COPY_COLORKEY_FX(type) { \ - type *s, *d = (type *) dbuf, *dx, tmp; \ - for (y = sy = 0; y < dstheight; y++, sy += yinc) { \ - s = (type*)(sbase + (sy >> 16) * sdesc.u1.lPitch); \ - dx = d; \ - for (x = sx = 0; x < dstwidth; x++, sx += xinc) { \ - tmp = s[sx >> 16]; \ - if ((tmp & keymask) < keylow || (tmp & keymask) > keyhigh) dx[0] = tmp; \ - dx = (type*)(((LPBYTE)dx)+dstxinc); \ - } \ - d = (type*)(((LPBYTE)d)+dstyinc); \ - } \ - break; } - - switch (bpp) { - case 1: COPY_COLORKEY_FX(BYTE) - case 2: COPY_COLORKEY_FX(WORD) - case 4: COPY_COLORKEY_FX(DWORD) - case 3: {LPBYTE s,d = dbuf, dx; - for (y = sy = 0; y < dstheight; y++, sy += yinc) { - sbuf = sbase + (sy >> 16) * sdesc.u1.lPitch; - dx = d; - for (x = sx = 0; x < dstwidth; x++, sx+= xinc) { - DWORD pixel; - s = sbuf+3*(sx>>16); - pixel = s[0]|(s[1]<<8)|(s[2]<<16); - if ((pixel & keymask) < keylow || (pixel & keymask) > keyhigh) { - dx[0] = (pixel )&0xff; - dx[1] = (pixel>> 8)&0xff; - dx[2] = (pixel>>16)&0xff; - } - dx+= dstxinc; - } - d += dstyinc; - } - break;} - default: - FIXME("%s color-keyed blit not implemented for bpp %d!\n", - (dwFlags & DDBLT_KEYSRC) ? "Source" : "Destination", bpp*8); - ret = DDERR_UNSUPPORTED; - goto error; -#undef COPY_COLORKEY_FX - } - } - } - -error: - if (dwFlags && FIXME_ON(ddraw)) { - FIXME("\tUnsupported flags: "); - DDRAW_dump_DDBLT(dwFlags); - } - -release: - IDirectDrawSurface7_Unlock(iface,NULL); - if (src && src != iface) IDirectDrawSurface7_Unlock(src,NULL); - return ret; -} - -/* BltBatch: generic, unimplemented */ - -HRESULT WINAPI -DIB_DirectDrawSurface_BltFast(LPDIRECTDRAWSURFACE7 iface, DWORD dstx, - DWORD dsty, LPDIRECTDRAWSURFACE7 src, - LPRECT rsrc, DWORD trans) -{ - IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface; - int bpp, w, h, x, y; - DDSURFACEDESC2 ddesc,sdesc; - HRESULT ret = DD_OK; - LPBYTE sbuf, dbuf; - RECT rsrc2; - RECT lock_src, lock_dst, lock_union; - - 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"); - } - - if ((This->locked) || ((src != NULL) && (((IDirectDrawSurfaceImpl *)src)->locked))) { - WARN(" Surface is busy, returning DDERR_SURFACEBUSY\n"); - return DDERR_SURFACEBUSY; - } - - /* 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; - } - - /* Check source rect for validity. Copied from normal Blt. Fixes Baldur's Gate.*/ - if ((rsrc->bottom > sdesc.dwHeight) || (rsrc->bottom < 0) || - (rsrc->top > sdesc.dwHeight) || (rsrc->top < 0) || - (rsrc->left > sdesc.dwWidth) || (rsrc->left < 0) || - (rsrc->right > sdesc.dwWidth) || (rsrc->right < 0) || - (rsrc->right < rsrc->left) || (rsrc->bottom < rsrc->top)) { - WARN("Application gave us bad source rectangle for BltFast.\n"); - return DDERR_INVALIDRECT; - } - - 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; - - bpp = GET_BPP(This->surface_desc); - - /* We need to lock the surfaces, or we won't get refreshes when done. */ - if (src == iface) { - int pitch; - - UnionRect(&lock_union, &lock_src, &lock_dst); - - /* Lock the union of the two rectangles */ - IDirectDrawSurface7_Lock(iface, &lock_union, &ddesc, 0, 0); - - pitch = This->surface_desc.u1.lPitch; - - /* Since sdesc was originally copied from this surface's description, we can just reuse it */ - sdesc.lpSurface = (BYTE *)This->surface_desc.lpSurface + lock_src.top * pitch + lock_src.left * bpp; - ddesc.lpSurface = (BYTE *)This->surface_desc.lpSurface + lock_dst.top * pitch + lock_dst.left * bpp; - } else { - 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); - } - - /* Handle first the FOURCC surfaces... */ - if ((sdesc.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC) && (ddesc.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC)) { - if (trans) - FIXME("trans arg not supported when a FOURCC surface is involved\n"); - if (dstx || dsty) - FIXME("offset for destination surface is not supported\n"); - if (sdesc.u4.ddpfPixelFormat.dwFourCC != sdesc.u4.ddpfPixelFormat.dwFourCC) { - FIXME("FOURCC->FOURCC copy only supported for the same type of surface\n"); - ret = DDERR_INVALIDPIXELFORMAT; - goto error; - } - memcpy(ddesc.lpSurface, sdesc.lpSurface, ddesc.u1.dwLinearSize); - goto error; - } - if ((sdesc.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC) && - (!(ddesc.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC))) { - DoDXTCDecompression(&sdesc, &ddesc); - goto error; - } - - 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; \ - } \ - s = (type *)((BYTE *)s + sdesc.u1.lPitch); \ - d = (type *)((BYTE *)d + ddesc.u1.lPitch); \ - } \ - break; \ - } - - switch (bpp) { - case 1: COPYBOX_COLORKEY(BYTE) - case 2: COPYBOX_COLORKEY(WORD) - case 4: COPYBOX_COLORKEY(DWORD) - case 3: - { - BYTE *d, *s; - DWORD tmp; - s = (BYTE *) sdesc.lpSurface; - d = (BYTE *) ddesc.lpSurface; - for (y = 0; y < h; y++) { - for (x = 0; x < w * 3; x += 3) { - tmp = (DWORD)s[x] + ((DWORD)s[x + 1] << 8) + ((DWORD)s[x + 2] << 16); - if (tmp < keylow || tmp > keyhigh) { - d[x + 0] = s[x + 0]; - d[x + 1] = s[x + 1]; - d[x + 2] = s[x + 2]; - } - } - s += sdesc.u1.lPitch; - d += ddesc.u1.lPitch; - } - break; - } - 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: - if (src == iface) { - IDirectDrawSurface7_Unlock(iface, &lock_union); - } else { - 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 WINAPI -DIB_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]; - unsigned int n; - HDC dc; - - TRACE("updating primary palette\n"); - for (n=0; nget_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 WINAPI -DIB_DirectDrawSurface_SetSurfaceDesc(LPDIRECTDRAWSURFACE7 iface, - LPDDSURFACEDESC2 pDDSD, DWORD dwFlags) -{ - IDirectDrawSurfaceImpl *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 const IDirectDrawSurface7Vtbl DIB_IDirectDrawSurface7_VTable = -{ - 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 -}; diff --git a/dlls/ddraw/surface_fakezbuffer.c b/dlls/ddraw/surface_fakezbuffer.c deleted file mode 100644 index e021bb1d26..0000000000 --- a/dlls/ddraw/surface_fakezbuffer.c +++ /dev/null @@ -1,312 +0,0 @@ -/* DirectDraw/Direct3D Z-Buffer stand in - * - * Copyright 2000 TransGaming Technologies Inc. - * - * This class provides a DirectDrawSurface implementation that represents - * a Z-Buffer surface. However it does not store an image and does not - * support Lock/Unlock or GetDC. It is merely a placeholder required by the - * Direct3D architecture. - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "config.h" - -#include -#include -#include - -#define NONAMELESSUNION -#define NONAMELESSSTRUCT - -#include "windef.h" -#include "winbase.h" -#include "wingdi.h" -#include "ddraw.h" -#include "d3d.h" - -#include "wine/debug.h" - -#include "ddcomimpl.h" -#include "ddraw_private.h" -#include "d3d_private.h" - -WINE_DEFAULT_DEBUG_CHANNEL(ddraw); - -static const IDirectDrawSurface7Vtbl FakeZBuffer_IDirectDrawSurface7_VTable; - -#ifdef HAVE_OPENGL -static void zbuffer_lock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect, DWORD dwFlags) -{ - /* Note that this does not do anything for now... At least it's not needed for Grim Fandango :-) */ -} - -static void zbuffer_unlock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect) -{ - ((FakeZBuffer_DirectDrawSurfaceImpl *) This->private)->in_memory = TRUE; -} - -static BOOLEAN zbuffer_get_dirty_status(IDirectDrawSurfaceImpl* This, LPCRECT pRect) -{ - if (((FakeZBuffer_DirectDrawSurfaceImpl *) This->private)->in_memory) { - ((FakeZBuffer_DirectDrawSurfaceImpl *) This->private)->in_memory = FALSE; - return TRUE; - } - return FALSE; -} -#endif - -HRESULT FakeZBuffer_DirectDrawSurface_Construct(IDirectDrawSurfaceImpl *This, - IDirectDrawImpl *pDD, - const DDSURFACEDESC2 *pDDSD) -{ - HRESULT hr; - BYTE zdepth = 16; /* Default value.. Should use the one from GL */ - - assert(pDDSD->ddsCaps.dwCaps & DDSCAPS_ZBUFFER); - - hr = Main_DirectDrawSurface_Construct(This, pDD, pDDSD); - if (FAILED(hr)) return hr; - - ICOM_INIT_INTERFACE(This, IDirectDrawSurface7, - FakeZBuffer_IDirectDrawSurface7_VTable); - - This->final_release = FakeZBuffer_DirectDrawSurface_final_release; - This->duplicate_surface = FakeZBuffer_DirectDrawSurface_duplicate_surface; - -#ifdef HAVE_OPENGL - if (opengl_initialized) { - This->lock_update = zbuffer_lock_update; - This->unlock_update = zbuffer_unlock_update; - This->get_dirty_status = zbuffer_get_dirty_status; - } -#endif - - - /* Beginning of some D3D hacks :-) */ - if (This->surface_desc.dwFlags & DDSD_ZBUFFERBITDEPTH) { - zdepth = This->surface_desc.u2.dwMipMapCount; /* This is where the Z buffer depth is stored in 'old' versions */ - } - - if ((This->surface_desc.dwFlags & DDSD_PIXELFORMAT) == 0) { - This->surface_desc.dwFlags |= DDSD_PIXELFORMAT; - This->surface_desc.u4.ddpfPixelFormat.dwSize = sizeof(This->surface_desc.u4.ddpfPixelFormat); - This->surface_desc.u4.ddpfPixelFormat.dwFlags = DDPF_ZBUFFER; - This->surface_desc.u4.ddpfPixelFormat.u1.dwZBufferBitDepth = zdepth; - } - if ((This->surface_desc.dwFlags & DDSD_PITCH) == 0) { - This->surface_desc.dwFlags |= DDSD_PITCH; - This->surface_desc.u1.lPitch = ((zdepth + 7) / 8) * This->surface_desc.dwWidth; - } - This->surface_desc.lpSurface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - This->surface_desc.u1.lPitch * This->surface_desc.dwHeight); - - return DD_OK; -} - -/* Not an API */ -HRESULT FakeZBuffer_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(FakeZBuffer_DirectDrawSurfaceImpl)); - if (This == NULL) return E_OUTOFMEMORY; - - This->private = (FakeZBuffer_DirectDrawSurfaceImpl*)(This+1); - - hr = FakeZBuffer_DirectDrawSurface_Construct(This, pDD, pDDSD); - if (FAILED(hr)) - HeapFree(GetProcessHeap(), 0, This); - else - *ppSurf = ICOM_INTERFACE(This, IDirectDrawSurface7); - - return hr; -} - -void -FakeZBuffer_DirectDrawSurface_final_release(IDirectDrawSurfaceImpl* This) -{ - Main_DirectDrawSurface_final_release(This); -} - -HRESULT -FakeZBuffer_DirectDrawSurface_duplicate_surface(IDirectDrawSurfaceImpl* This, - LPDIRECTDRAWSURFACE7* ppDup) -{ - return FakeZBuffer_DirectDrawSurface_Create(This->ddraw_owner, - &This->surface_desc, ppDup, - NULL); -} - -/* put your breakpoint/abort call here */ -static HRESULT cant_do_that(const char *s) -{ - FIXME("attempt to %s fake z-buffer\n", s); - return DDERR_UNSUPPORTED; -} - -HRESULT WINAPI -FakeZBuffer_DirectDrawSurface_Blt(LPDIRECTDRAWSURFACE7 iface, LPRECT rdst, - LPDIRECTDRAWSURFACE7 src, LPRECT rsrc, - DWORD dwFlags, LPDDBLTFX lpbltfx) -{ - IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface; - - if (TRACE_ON(ddraw)) { - TRACE("(%p)->(%p,%p,%p,%08lx,%p)\n", This,rdst,src,rsrc,dwFlags,lpbltfx); - 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); - } - } - - /* We only support the BLT with DEPTH_FILL for now */ - if ((dwFlags & DDBLT_DEPTHFILL) && (This->ddraw_owner->d3d_private != NULL)) { - if (This->ddraw_owner->current_device != NULL) { - D3DRECT rect; - if (rdst) { - rect.u1.x1 = rdst->left; - rect.u2.y1 = rdst->top; - rect.u3.x2 = rdst->right; - rect.u4.y2 = rdst->bottom; - } - This->ddraw_owner->current_device->clear(This->ddraw_owner->current_device, - (rdst == NULL ? 0 : 1), &rect, - D3DCLEAR_ZBUFFER, - 0x00000000, - ((double) lpbltfx->u5.dwFillDepth) / 4294967295.0, - 0x00000000); - return DD_OK; - } - } - - return cant_do_that("blt to a"); -} - -HRESULT WINAPI -FakeZBuffer_DirectDrawSurface_BltFast(LPDIRECTDRAWSURFACE7 iface, DWORD dstx, - DWORD dsty, LPDIRECTDRAWSURFACE7 src, - LPRECT rsrc, DWORD trans) -{ - IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface; - - if (TRACE_ON(ddraw)) { - FIXME("(%p)->(%ld,%ld,%p,%p,%08lx)\n", - This,dstx,dsty,src,rsrc,trans - ); - FIXME("\ttrans:"); - if (FIXME_ON(ddraw)) - DDRAW_dump_DDBLTFAST(trans); - if (rsrc) - FIXME("\tsrcrect: %ldx%ld-%ldx%ld\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom); - else - FIXME(" srcrect: NULL\n"); - } - - return cant_do_that("bltfast to a"); -} - -HRESULT WINAPI -FakeZBuffer_DirectDrawSurface_GetDC(LPDIRECTDRAWSURFACE7 iface, HDC *phDC) -{ - return cant_do_that("get a DC for a"); -} - -HRESULT WINAPI -FakeZBuffer_DirectDrawSurface_ReleaseDC(LPDIRECTDRAWSURFACE7 iface, HDC hDC) -{ - return cant_do_that("release a DC for a"); -} - -HRESULT WINAPI -FakeZBuffer_DirectDrawSurface_Restore(LPDIRECTDRAWSURFACE7 iface) -{ - return DD_OK; -} - -HRESULT WINAPI -FakeZBuffer_DirectDrawSurface_SetSurfaceDesc(LPDIRECTDRAWSURFACE7 iface, - LPDDSURFACEDESC2 pDDSD, - DWORD dwFlags) -{ - /* XXX */ - abort(); - return E_FAIL; -} - - -static const IDirectDrawSurface7Vtbl FakeZBuffer_IDirectDrawSurface7_VTable= -{ - Main_DirectDrawSurface_QueryInterface, - Main_DirectDrawSurface_AddRef, - Main_DirectDrawSurface_Release, - Main_DirectDrawSurface_AddAttachedSurface, - Main_DirectDrawSurface_AddOverlayDirtyRect, - FakeZBuffer_DirectDrawSurface_Blt, - Main_DirectDrawSurface_BltBatch, - FakeZBuffer_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, - FakeZBuffer_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, - FakeZBuffer_DirectDrawSurface_ReleaseDC, - FakeZBuffer_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, - FakeZBuffer_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 -}; diff --git a/dlls/ddraw/surface_gamma.c b/dlls/ddraw/surface_gamma.c deleted file mode 100644 index 4e5f16cde6..0000000000 --- a/dlls/ddraw/surface_gamma.c +++ /dev/null @@ -1,79 +0,0 @@ -/* DirectDrawGammaControl implementation - * - * Copyright 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "config.h" -#include "winerror.h" - -#include -#include - -#include "wine/debug.h" -#include "ddraw_private.h" - -WINE_DEFAULT_DEBUG_CHANNEL(ddraw); - -#define CONVERT(pddgc) COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, \ - IDirectDrawGammaControl, \ - IDirectDrawSurface7, \ - (pddgc)) - -static HRESULT WINAPI -DirectDrawGammaControl_QueryInterface(LPDIRECTDRAWGAMMACONTROL iface, REFIID riid, - LPVOID *ppObj) -{ - TRACE("(%p)->(%s,%p)\n", iface, debugstr_guid(riid), ppObj); - return E_NOINTERFACE; -} - -static ULONG WINAPI -DirectDrawGammaControl_AddRef(LPDIRECTDRAWGAMMACONTROL iface) -{ - return IDirectDrawSurface7_AddRef(CONVERT(iface)); -} - -static ULONG WINAPI -DirectDrawGammaControl_Release(LPDIRECTDRAWGAMMACONTROL iface) -{ - return IDirectDrawSurface7_Release(CONVERT(iface)); -} - -static HRESULT WINAPI -DirectDrawGammaControl_GetGammaRamp(LPDIRECTDRAWGAMMACONTROL iface, DWORD dwFlags, LPDDGAMMARAMP lpGammaRamp) -{ - ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawGammaControl, iface); - TRACE("(%p)->(%08lx,%p)\n", iface,dwFlags,lpGammaRamp); - return This->get_gamma_ramp(This, dwFlags, lpGammaRamp); -} - -static HRESULT WINAPI -DirectDrawGammaControl_SetGammaRamp(LPDIRECTDRAWGAMMACONTROL iface, DWORD dwFlags, LPDDGAMMARAMP lpGammaRamp) -{ - ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirectDrawGammaControl, iface); - TRACE("(%p)->(%08lx,%p)\n", iface,dwFlags,lpGammaRamp); - return This->set_gamma_ramp(This, dwFlags, lpGammaRamp); -} - -const IDirectDrawGammaControlVtbl DDRAW_IDDGC_VTable = -{ - DirectDrawGammaControl_QueryInterface, - DirectDrawGammaControl_AddRef, - DirectDrawGammaControl_Release, - DirectDrawGammaControl_GetGammaRamp, - DirectDrawGammaControl_SetGammaRamp -}; diff --git a/dlls/ddraw/surface_hal.c b/dlls/ddraw/surface_hal.c deleted file mode 100644 index 1cd9455448..0000000000 --- a/dlls/ddraw/surface_hal.c +++ /dev/null @@ -1,411 +0,0 @@ -/* DirectDrawSurface HAL driver - * - * Copyright 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "config.h" - -#include -#include - -#define NONAMELESSUNION -#define NONAMELESSSTRUCT - -#include "wine/debug.h" -#include "ddraw_private.h" - -WINE_DEFAULT_DEBUG_CHANNEL(ddraw); - -static const IDirectDrawSurface7Vtbl HAL_IDirectDrawSurface7_VTable; - -static HRESULT HAL_DirectDrawSurface_create_surface(IDirectDrawSurfaceImpl* This, - IDirectDrawImpl* pDD) -{ - HAL_PRIV_VAR(priv, This); - HAL_DDRAW_PRIV_VAR(ddpriv, pDD); - LPDDRAWI_DIRECTDRAW_GBL dd_gbl = pDD->local.lpGbl; - LPDDRAWI_DDRAWSURFACE_LCL local = &This->local; - DDHAL_CREATESURFACEDATA data; - HRESULT hr; - - data.lpDD = dd_gbl; - data.lpDDSurfaceDesc = (LPDDSURFACEDESC)&This->surface_desc; - data.lplpSList = &local; - data.dwSCnt = 1; - data.ddRVal = 0; - data.CreateSurface = dd_gbl->lpDDCBtmp->HALDD.CreateSurface; - hr = data.CreateSurface(&data); - - if (hr == DDHAL_DRIVER_HANDLED) { - if (This->global.fpVidMem < 4) { - /* grab framebuffer data from current_mode */ - priv->hal.fb_pitch = dd_gbl->vmiData.lDisplayPitch; - priv->hal.fb_vofs = ddpriv->hal.next_vofs; - priv->hal.fb_addr = ((LPBYTE)dd_gbl->vmiData.fpPrimary) + - dd_gbl->vmiData.lDisplayPitch * priv->hal.fb_vofs; - TRACE("vofs=%ld, addr=%p\n", priv->hal.fb_vofs, priv->hal.fb_addr); - ddpriv->hal.next_vofs += This->surface_desc.dwHeight; - - This->global.fpVidMem = (FLATPTR)priv->hal.fb_addr; - This->global.u4.lPitch = priv->hal.fb_pitch; - } - This->surface_desc.lpSurface = (LPVOID)This->global.fpVidMem; - This->surface_desc.dwFlags |= DDSD_LPSURFACE; - if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_EXECUTEBUFFER) { - This->surface_desc.u1.dwLinearSize = This->global.u4.dwLinearSize; - This->surface_desc.dwFlags |= DDSD_LINEARSIZE; - } else { - This->surface_desc.u1.lPitch = This->global.u4.lPitch; - This->surface_desc.dwFlags |= DDSD_PITCH; - } - } - else priv->hal.need_late = TRUE; - - return data.ddRVal; -} - -static inline BOOL HAL_IsUser(IDirectDrawSurfaceImpl* This) -{ - HAL_PRIV_VAR(priv, This); - if (This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_TEXTURE | DDSCAPS_EXECUTEBUFFER)) - return FALSE; - if (priv->hal.fb_addr) - return FALSE; - return TRUE; -} - -HRESULT -HAL_DirectDrawSurface_Construct(IDirectDrawSurfaceImpl* This, - IDirectDrawImpl* pDD, - const DDSURFACEDESC2* pDDSD) -{ - HAL_PRIV_VAR(priv, This); - LPDDRAWI_DIRECTDRAW_GBL dd_gbl = pDD->local.lpGbl; - HRESULT hr; - - TRACE("(%p,%p,%p)\n",This,pDD,pDDSD); - - /* copy surface_desc, we may want to modify it before DIB construction */ - This->surface_desc = *pDDSD; - - /* the driver may want to dereference these pointers */ - This->local.lpSurfMore = &This->more; - This->local.lpGbl = &This->global; - This->gmore = &This->global_more; - - if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_TEXTURE) { - hr = HAL_DirectDrawSurface_create_surface(This, pDD); - if (FAILED(hr)) return hr; - - hr = DIB_DirectDrawSurface_Construct(This, pDD, &This->surface_desc); - if (FAILED(hr)) return hr; - } - else if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_EXECUTEBUFFER) { - FIXME("create execute buffer\n"); - return DDERR_GENERIC; - } - else { - if (!(dd_gbl->dwFlags & DDRAWI_MODECHANGED)) { - /* force a mode set (HALs like DGA may need it) */ - hr = HAL_DirectDraw_SetDisplayMode(ICOM_INTERFACE(pDD, IDirectDraw7), - pDD->width, pDD->height, - pDD->pixelformat.u1.dwRGBBitCount, - 0, 0); - if (FAILED(hr)) return hr; - } - - if (dd_gbl->vmiData.fpPrimary) { - hr = HAL_DirectDrawSurface_create_surface(This, pDD); - if (FAILED(hr)) return hr; - - if (priv->hal.need_late) { - /* this doesn't make sense... driver error? */ - ERR("driver failed to create framebuffer surface\n"); - return DDERR_GENERIC; - } - - hr = DIB_DirectDrawSurface_Construct(This, pDD, &This->surface_desc); - if (FAILED(hr)) return hr; - } else { - /* no framebuffer, construct User-based primary */ - hr = User_DirectDrawSurface_Construct(This, pDD, pDDSD); - if (FAILED(hr)) return hr; - - /* must notify HAL *after* creating User-based primary */ - /* (or use CreateSurfaceEx, which we don't yet) */ - hr = HAL_DirectDrawSurface_create_surface(This, pDD); - if (FAILED(hr)) return hr; - - priv->hal.need_late = FALSE; - } - } - - ICOM_INIT_INTERFACE(This, IDirectDrawSurface7, - HAL_IDirectDrawSurface7_VTable); - - This->final_release = HAL_DirectDrawSurface_final_release; - This->late_allocate = HAL_DirectDrawSurface_late_allocate; - This->duplicate_surface = HAL_DirectDrawSurface_duplicate_surface; - - This->flip_data = HAL_DirectDrawSurface_flip_data; - This->flip_update = HAL_DirectDrawSurface_flip_update; - - This->set_palette = HAL_DirectDrawSurface_set_palette; - - This->get_display_window = HAL_DirectDrawSurface_get_display_window; - - return DD_OK; -} - -HRESULT -HAL_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(HAL_DirectDrawSurfaceImpl)); - if (This == NULL) return E_OUTOFMEMORY; - - This->private = (HAL_DirectDrawSurfaceImpl*)(This+1); - - hr = HAL_DirectDrawSurface_Construct(This, pDD, pDDSD); - if (FAILED(hr)) - HeapFree(GetProcessHeap(), 0, This); - else - *ppSurf = ICOM_INTERFACE(This, IDirectDrawSurface7); - - return hr; -} - -void HAL_DirectDrawSurface_final_release(IDirectDrawSurfaceImpl* This) -{ - LPDDRAWI_DIRECTDRAW_GBL dd_gbl = This->more.lpDD_lcl->lpGbl; - DDHAL_DESTROYSURFACEDATA data; - - /* destroy HAL surface */ - data.lpDD = dd_gbl; - data.lpDDSurface = &This->local; - data.ddRVal = 0; - data.DestroySurface = dd_gbl->lpDDCBtmp->HALDDSurface.DestroySurface; - data.DestroySurface(&data); - - if (HAL_IsUser(This)) { - User_DirectDrawSurface_final_release(This); - } else { - DIB_DirectDrawSurface_final_release(This); - } -} - -HRESULT HAL_DirectDrawSurface_late_allocate(IDirectDrawSurfaceImpl* This) -{ - HAL_PRIV_VAR(priv, This); - if (priv->hal.need_late) { - priv->hal.need_late = FALSE; - return HAL_DirectDrawSurface_create_surface(This, This->ddraw_owner); - } - return DD_OK; -} - -void HAL_DirectDrawSurface_set_palette(IDirectDrawSurfaceImpl* This, - IDirectDrawPaletteImpl* pal) -{ - LPDDRAWI_DIRECTDRAW_GBL dd_gbl = This->more.lpDD_lcl->lpGbl; - DDHAL_SETPALETTEDATA data; - - DIB_DirectDrawSurface_set_palette(This, pal); - data.lpDD = dd_gbl; - data.lpDDSurface = &This->local; - data.lpDDPalette = (pal != NULL ? &pal->global : NULL); - data.ddRVal = 0; - data.Attach = TRUE; /* what's this? */ - data.SetPalette = dd_gbl->lpDDCBtmp->HALDDSurface.SetPalette; - if (data.SetPalette) - data.SetPalette(&data); -} - -HRESULT HAL_DirectDrawSurface_duplicate_surface(IDirectDrawSurfaceImpl* This, - LPDIRECTDRAWSURFACE7* ppDup) -{ - return HAL_DirectDrawSurface_Create(This->ddraw_owner, - &This->surface_desc, ppDup, NULL); -} - -void HAL_DirectDrawSurface_lock_update(IDirectDrawSurfaceImpl* This, - LPCRECT pRect, DWORD dwFlags) -{ - LPDDRAWI_DIRECTDRAW_GBL dd_gbl = This->more.lpDD_lcl->lpGbl; - DDHAL_LOCKDATA data; - - data.lpDD = dd_gbl; - data.lpDDSurface = &This->local; - data.ddRVal = 0; - data.lpSurfData = This->surface_desc.lpSurface; /* FIXME: correct? */ - if (pRect) { - data.rArea.top = pRect->top; - data.rArea.bottom = pRect->bottom; - data.rArea.left = pRect->left; - data.rArea.right = pRect->right; - data.bHasRect = TRUE; - } else { - data.bHasRect = FALSE; - } - data.dwFlags = dwFlags; - - data.Lock = dd_gbl->lpDDCBtmp->HALDDSurface.Lock; - if (data.Lock && (data.Lock(&data) == DDHAL_DRIVER_HANDLED)) - return; - - if (HAL_IsUser(This)) { - User_DirectDrawSurface_lock_update(This, pRect, dwFlags); - } else { - Main_DirectDrawSurface_lock_update(This, pRect, dwFlags); - } -} - -void HAL_DirectDrawSurface_unlock_update(IDirectDrawSurfaceImpl* This, - LPCRECT pRect) -{ - LPDDRAWI_DIRECTDRAW_GBL dd_gbl = This->more.lpDD_lcl->lpGbl; - DDHAL_UNLOCKDATA data; - - data.lpDD = dd_gbl; - data.lpDDSurface = &This->local; - data.ddRVal = 0; - data.Unlock = dd_gbl->lpDDCBtmp->HALDDSurface.Unlock; - if (data.Unlock && (data.Unlock(&data) == DDHAL_DRIVER_HANDLED)) - return; - - if (HAL_IsUser(This)) { - User_DirectDrawSurface_unlock_update(This, pRect); - } else { - Main_DirectDrawSurface_unlock_update(This, pRect); - } -} - -BOOL HAL_DirectDrawSurface_flip_data(IDirectDrawSurfaceImpl* front, - IDirectDrawSurfaceImpl* back, - DWORD dwFlags) -{ - HAL_PRIV_VAR(front_priv, front); - HAL_PRIV_VAR(back_priv, back); - LPDDRAWI_DIRECTDRAW_GBL dd_gbl = front->more.lpDD_lcl->lpGbl; - DDHAL_FLIPDATA data; - BOOL ret; - - { - DWORD tmp; - tmp = front_priv->hal.fb_vofs; - front_priv->hal.fb_vofs = back_priv->hal.fb_vofs; - back_priv->hal.fb_vofs = tmp; - } - { - LPVOID tmp; - tmp = front_priv->hal.fb_addr; - front_priv->hal.fb_addr = back_priv->hal.fb_addr; - back_priv->hal.fb_addr = tmp; - } - - if (HAL_IsUser(front)) { - ret = User_DirectDrawSurface_flip_data(front, back, dwFlags); - } else { - ret = DIB_DirectDrawSurface_flip_data(front, back, dwFlags); - } - - TRACE("(%p,%p)\n",front,back); - data.lpDD = dd_gbl; - data.lpSurfCurr = &front->local; - data.lpSurfTarg = &back->local; - data.lpSurfCurrLeft = NULL; - data.lpSurfTargLeft = NULL; - data.dwFlags = dwFlags; - data.ddRVal = 0; - data.Flip = dd_gbl->lpDDCBtmp->HALDDSurface.Flip; - if (data.Flip) - if (data.Flip(&data) == DDHAL_DRIVER_HANDLED) ret = FALSE; - - return ret; -} - -void HAL_DirectDrawSurface_flip_update(IDirectDrawSurfaceImpl* This, DWORD dwFlags) -{ - if (HAL_IsUser(This)) { - User_DirectDrawSurface_flip_update(This, dwFlags); - } -} - -HWND HAL_DirectDrawSurface_get_display_window(IDirectDrawSurfaceImpl* This) -{ - return 0; -} - -static const IDirectDrawSurface7Vtbl HAL_IDirectDrawSurface7_VTable = -{ - 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 -}; diff --git a/dlls/ddraw/surface_main.c b/dlls/ddraw/surface_main.c deleted file mode 100644 index 7045a99615..0000000000 --- a/dlls/ddraw/surface_main.c +++ /dev/null @@ -1,1516 +0,0 @@ -/* DirectDrawSurface base implementation - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ -#include "config.h" -#include "wine/port.h" - -#include -#include - -#define COBJMACROS -#define NONAMELESSUNION -#define NONAMELESSSTRUCT - -#include "winerror.h" -#include "wine/debug.h" -#include "ddraw_private.h" -#include "opengl_private.h" - -WINE_DEFAULT_DEBUG_CHANNEL(ddraw); -WINE_DECLARE_DEBUG_CHANNEL(ddraw_flip); -WINE_DECLARE_DEBUG_CHANNEL(ddraw_fps); - -/** Creation/Destruction functions */ - -HRESULT -Main_DirectDrawSurface_Construct(IDirectDrawSurfaceImpl *This, - IDirectDrawImpl *pDD, - const DDSURFACEDESC2 *pDDSD) -{ - TRACE("(%p)->(%p,%p)\n", This, pDD, pDDSD); - - if (pDDSD != &This->surface_desc) { - This->surface_desc.dwSize = sizeof(This->surface_desc); - DD_STRUCT_COPY_BYSIZE(&(This->surface_desc),pDDSD); - } - This->uniqueness_value = 1; /* unchecked */ - This->ref = 1; - - This->local.lpSurfMore = &This->more; - This->local.lpGbl = &This->global; - This->local.dwProcessId = GetCurrentProcessId(); - This->local.dwFlags = 0; /* FIXME */ - This->local.ddsCaps.dwCaps = This->surface_desc.ddsCaps.dwCaps; - /* FIXME: more local stuff */ - This->more.lpDD_lcl = &pDD->local; - This->more.ddsCapsEx.dwCaps2 = This->surface_desc.ddsCaps.dwCaps2; - This->more.ddsCapsEx.dwCaps3 = This->surface_desc.ddsCaps.dwCaps3; - This->more.ddsCapsEx.dwCaps4 = This->surface_desc.ddsCaps.dwCaps4; - /* FIXME: more more stuff */ - This->gmore = &This->global_more; - This->global.u3.lpDD = pDD->local.lpGbl; - /* FIXME: more global stuff */ - - This->final_release = Main_DirectDrawSurface_final_release; - This->late_allocate = Main_DirectDrawSurface_late_allocate; - This->attach = Main_DirectDrawSurface_attach; - This->detach = Main_DirectDrawSurface_detach; - This->lock_update = Main_DirectDrawSurface_lock_update; - This->unlock_update = Main_DirectDrawSurface_unlock_update; - This->lose_surface = Main_DirectDrawSurface_lose_surface; - This->set_palette = Main_DirectDrawSurface_set_palette; - This->update_palette = Main_DirectDrawSurface_update_palette; - This->get_display_window = Main_DirectDrawSurface_get_display_window; - This->get_gamma_ramp = Main_DirectDrawSurface_get_gamma_ramp; - This->set_gamma_ramp = Main_DirectDrawSurface_set_gamma_ramp; - - ICOM_INIT_INTERFACE(This, IDirectDrawSurface3, - DDRAW_IDDS3_Thunk_VTable); - ICOM_INIT_INTERFACE(This, IDirectDrawGammaControl, - DDRAW_IDDGC_VTable); - - /* There is no generic implementation of IDDS7 or texture */ - - Main_DirectDraw_AddSurface(pDD, This); - return DD_OK; -} - -void Main_DirectDrawSurface_final_release(IDirectDrawSurfaceImpl* This) -{ - Main_DirectDraw_RemoveSurface(This->ddraw_owner, This); -} - -HRESULT Main_DirectDrawSurface_late_allocate(IDirectDrawSurfaceImpl* This) -{ - return DD_OK; -} - -static void Main_DirectDrawSurface_Destroy(IDirectDrawSurfaceImpl* This) -{ - if (This->palette) { - IDirectDrawPalette_Release(ICOM_INTERFACE(This->palette, IDirectDrawPalette)); - This->palette = NULL; - } - This->final_release(This); - if (This->private != This+1) HeapFree(GetProcessHeap(), 0, This->private); - HeapFree(GetProcessHeap(), 0, This->tex_private); - HeapFree(GetProcessHeap(), 0, This); -} - -void Main_DirectDrawSurface_ForceDestroy(IDirectDrawSurfaceImpl* This) -{ - WARN("destroying surface %p with refcnt %lu\n", This, This->ref); - Main_DirectDrawSurface_Destroy(This); -} - -ULONG WINAPI Main_DirectDrawSurface_Release(LPDIRECTDRAWSURFACE7 iface) -{ - IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface; - ULONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p)->(): decreasing from %ld\n", This, ref + 1); - - if (ref == 0) - { - if (This->aux_release) - This->aux_release(This->aux_ctx, This->aux_data); - Main_DirectDrawSurface_Destroy(This); - - TRACE("released surface %p\n", This); - - return 0; - } - - return ref; -} - -ULONG WINAPI Main_DirectDrawSurface_AddRef(LPDIRECTDRAWSURFACE7 iface) -{ - IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface; - ULONG ref = InterlockedIncrement(&This->ref); - - TRACE("(%p)->(): increasing from %ld\n", This, ref - 1); - - return ref; -} - -HRESULT WINAPI -Main_DirectDrawSurface_QueryInterface(LPDIRECTDRAWSURFACE7 iface, REFIID riid, - LPVOID* ppObj) -{ - IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface; - TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(riid), ppObj); - - *ppObj = NULL; - - if(!riid) - return DDERR_INVALIDPARAMS; - - if (IsEqualGUID(&IID_IUnknown, riid) - || IsEqualGUID(&IID_IDirectDrawSurface7, riid) - || IsEqualGUID(&IID_IDirectDrawSurface4, riid)) - { - InterlockedIncrement(&This->ref); - *ppObj = ICOM_INTERFACE(This, IDirectDrawSurface7); - return S_OK; - } - else if (IsEqualGUID(&IID_IDirectDrawSurface, riid) - || IsEqualGUID(&IID_IDirectDrawSurface2, riid) - || IsEqualGUID(&IID_IDirectDrawSurface3, riid)) - { - InterlockedIncrement(&This->ref); - *ppObj = ICOM_INTERFACE(This, IDirectDrawSurface3); - return S_OK; - } - else if (IsEqualGUID(&IID_IDirectDrawGammaControl, riid)) - { - InterlockedIncrement(&This->ref); - *ppObj = ICOM_INTERFACE(This, IDirectDrawGammaControl); - return S_OK; - } -#ifdef HAVE_OPENGL - /* interfaces following here require OpenGL */ - if( !opengl_initialized ) - return E_NOINTERFACE; - - if ( IsEqualGUID( &IID_D3DDEVICE_OpenGL, riid ) || - IsEqualGUID( &IID_IDirect3DHALDevice, riid) ) - { - IDirect3DDeviceImpl *d3ddevimpl; - HRESULT ret_value; - - ret_value = d3ddevice_create(&d3ddevimpl, This->ddraw_owner, This, 1); - if (FAILED(ret_value)) return ret_value; - - *ppObj = ICOM_INTERFACE(d3ddevimpl, IDirect3DDevice); - TRACE(" returning Direct3DDevice interface at %p.\n", *ppObj); - - InterlockedIncrement(&This->ref); /* No idea if this is correct.. Need to check using real Windows */ - return ret_value; - } - else if (IsEqualGUID( &IID_IDirect3DTexture, riid ) || - IsEqualGUID( &IID_IDirect3DTexture2, riid )) - { - HRESULT ret_value = S_OK; - - /* Note: this is not exactly how Windows does it... But this seems not to hurt the only - application I know creating a texture without this flag set and it will prevent - bugs in other parts of Wine. - */ - This->surface_desc.ddsCaps.dwCaps |= DDSCAPS_TEXTURE; - - /* In case the texture surface was created before the D3D creation */ - if (This->tex_private == NULL) { - if (This->ddraw_owner->d3d_private == NULL) { - ERR("Texture created with no D3D object yet.. Not supported !\n"); - return E_NOINTERFACE; - } - - ret_value = This->ddraw_owner->d3d_create_texture(This->ddraw_owner, This, FALSE, This->mip_main); - if (FAILED(ret_value)) return ret_value; - } - if (IsEqualGUID( &IID_IDirect3DTexture, riid )) { - *ppObj = ICOM_INTERFACE(This, IDirect3DTexture); - TRACE(" returning Direct3DTexture interface at %p.\n", *ppObj); - } else { - *ppObj = ICOM_INTERFACE(This, IDirect3DTexture2); - TRACE(" returning Direct3DTexture2 interface at %p.\n", *ppObj); - } - InterlockedIncrement(&This->ref); - return ret_value; - } -#endif - - return E_NOINTERFACE; -} - -/*** Callbacks */ - -BOOL -Main_DirectDrawSurface_attach(IDirectDrawSurfaceImpl *This, - IDirectDrawSurfaceImpl *to) -{ - return TRUE; -} - -BOOL Main_DirectDrawSurface_detach(IDirectDrawSurfaceImpl *This) -{ - return TRUE; -} - -void -Main_DirectDrawSurface_lock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect, - DWORD dwFlags) -{ -} - -void -Main_DirectDrawSurface_unlock_update(IDirectDrawSurfaceImpl* This, - LPCRECT pRect) -{ -} - -void -Main_DirectDrawSurface_lose_surface(IDirectDrawSurfaceImpl* This) -{ -} - -void -Main_DirectDrawSurface_set_palette(IDirectDrawSurfaceImpl* This, - IDirectDrawPaletteImpl* pal) -{ -} - -void -Main_DirectDrawSurface_update_palette(IDirectDrawSurfaceImpl* This, - IDirectDrawPaletteImpl* pal, - DWORD dwStart, DWORD dwCount, - LPPALETTEENTRY palent) -{ -} - -HWND -Main_DirectDrawSurface_get_display_window(IDirectDrawSurfaceImpl* This) -{ - return 0; -} - -HRESULT -Main_DirectDrawSurface_get_gamma_ramp(IDirectDrawSurfaceImpl* This, - DWORD dwFlags, - LPDDGAMMARAMP lpGammaRamp) -{ - HDC hDC; - HRESULT hr; - hr = This->get_dc(This, &hDC); - if (FAILED(hr)) return hr; - hr = GetDeviceGammaRamp(hDC, lpGammaRamp) ? DD_OK : DDERR_UNSUPPORTED; - This->release_dc(This, hDC); - return hr; -} - -HRESULT -Main_DirectDrawSurface_set_gamma_ramp(IDirectDrawSurfaceImpl* This, - DWORD dwFlags, - LPDDGAMMARAMP lpGammaRamp) -{ - HDC hDC; - HRESULT hr; - hr = This->get_dc(This, &hDC); - if (FAILED(hr)) return hr; - hr = SetDeviceGammaRamp(hDC, lpGammaRamp) ? DD_OK : DDERR_UNSUPPORTED; - This->release_dc(This, hDC); - return hr; -} - - -/*** Interface functions */ - -HRESULT WINAPI -Main_DirectDrawSurface_AddAttachedSurface(LPDIRECTDRAWSURFACE7 iface, - LPDIRECTDRAWSURFACE7 pAttach) -{ - IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface; - IDirectDrawSurfaceImpl* surf = ICOM_OBJECT(IDirectDrawSurfaceImpl, - IDirectDrawSurface7, pAttach); - - TRACE("(%p)->(%p)\n",This,pAttach); - - /* Does windows check this? */ - if (surf == This) - return DDERR_CANNOTATTACHSURFACE; /* unchecked */ - - /* Does windows check this? */ - if (surf->ddraw_owner != This->ddraw_owner) - return DDERR_CANNOTATTACHSURFACE; /* unchecked */ - - if (surf->surface_owner != NULL) - return DDERR_SURFACEALREADYATTACHED; /* unchecked */ - - /* TODO MSDN: "You can attach only z-buffer surfaces with this method." - * But apparently backbuffers and mipmaps can be attached too. */ - - /* Set MIPMAPSUBLEVEL if this seems to be one */ - if (This->surface_desc.ddsCaps.dwCaps & - surf->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) { - surf->surface_desc.ddsCaps.dwCaps2 |= DDSCAPS2_MIPMAPSUBLEVEL; - /* FIXME: we should probably also add to dwMipMapCount of this - * and all parent surfaces (update create_texture if you do) */ - } - - /* Callback to allow the surface to do something special now that it is - * attached. (e.g. maybe the Z-buffer tells the renderer to use it.) */ - if (!surf->attach(surf, This)) - return DDERR_CANNOTATTACHSURFACE; - - /* check: Where should it go in the chain? This puts it on the head. */ - if (This->attached) - This->attached->prev_attached = surf; - surf->next_attached = This->attached; - surf->prev_attached = NULL; - This->attached = surf; - surf->surface_owner = This; - - IDirectDrawSurface7_AddRef(pAttach); - - return DD_OK; -} - -/* MSDN: "not currently implemented." */ -HRESULT WINAPI -Main_DirectDrawSurface_AddOverlayDirtyRect(LPDIRECTDRAWSURFACE7 iface, - LPRECT pRect) -{ - TRACE("(%p)->(%p)\n",iface,pRect); - return DDERR_UNSUPPORTED; /* unchecked */ -} - -/* MSDN: "not currently implemented." */ -HRESULT WINAPI -Main_DirectDrawSurface_BltBatch(LPDIRECTDRAWSURFACE7 iface, - LPDDBLTBATCH pBatch, DWORD dwCount, - DWORD dwFlags) -{ - TRACE("(%p)->(%p,%ld,%08lx)\n",iface,pBatch,dwCount,dwFlags); - return DDERR_UNSUPPORTED; /* unchecked */ -} - -HRESULT WINAPI -Main_DirectDrawSurface_ChangeUniquenessValue(LPDIRECTDRAWSURFACE7 iface) -{ - IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface; - volatile IDirectDrawSurfaceImpl* vThis = This; - - TRACE("(%p)\n",This); - /* A uniquness value of 0 is apparently special. - * This needs to be checked. */ - while (1) - { - DWORD old_uniqueness_value = vThis->uniqueness_value; - DWORD new_uniqueness_value = old_uniqueness_value+1; - - if (old_uniqueness_value == 0) break; - if (new_uniqueness_value == 0) new_uniqueness_value = 1; - - if (InterlockedCompareExchange((LONG*)&vThis->uniqueness_value, - old_uniqueness_value, - new_uniqueness_value) - == old_uniqueness_value) - break; - } - - return DD_OK; -} - -HRESULT WINAPI -Main_DirectDrawSurface_DeleteAttachedSurface(LPDIRECTDRAWSURFACE7 iface, - DWORD dwFlags, - LPDIRECTDRAWSURFACE7 pAttach) -{ - IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface; - IDirectDrawSurfaceImpl* surf = ICOM_OBJECT(IDirectDrawSurfaceImpl, - IDirectDrawSurface7, pAttach); - - TRACE("(%p)->(%08lx,%p)\n",This,dwFlags,pAttach); - - if (!surf || (surf->surface_owner != This)) - return DDERR_SURFACENOTATTACHED; /* unchecked */ - - surf->detach(surf); - - /* Remove MIPMAPSUBLEVEL if this seemed to be one */ - if (This->surface_desc.ddsCaps.dwCaps & - surf->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) { - surf->surface_desc.ddsCaps.dwCaps2 &= ~DDSCAPS2_MIPMAPSUBLEVEL; - /* FIXME: we should probably also subtract from dwMipMapCount of this - * and all parent surfaces */ - } - - if (surf->next_attached) - surf->next_attached->prev_attached = surf->prev_attached; - if (surf->prev_attached) - surf->prev_attached->next_attached = surf->next_attached; - if (This->attached == surf) - This->attached = surf->next_attached; - - IDirectDrawSurface7_Release(pAttach); - - return DD_OK; -} - -HRESULT WINAPI -Main_DirectDrawSurface_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE7 iface, - LPVOID context, - LPDDENUMSURFACESCALLBACK7 cb) -{ - IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface; - IDirectDrawSurfaceImpl* surf; - DDSURFACEDESC2 desc; - - TRACE("(%p)->(%p,%p)\n",This,context,cb); - - for (surf = This->attached; surf != NULL; surf = surf->next_attached) - { - LPDIRECTDRAWSURFACE7 isurf = ICOM_INTERFACE(surf, IDirectDrawSurface7); - - if (TRACE_ON(ddraw)) { - TRACE(" => enumerating surface %p (priv. %p) with description:\n", isurf, surf); - DDRAW_dump_surface_desc(&surf->surface_desc); - } - - IDirectDrawSurface7_AddRef(isurf); - desc = surf->surface_desc; - /* check: != DDENUMRET_OK or == DDENUMRET_CANCEL? */ - if (cb(isurf, &desc, context) == DDENUMRET_CANCEL) - break; - } - - TRACE(" end of enumeration.\n"); - - return DD_OK; -} - -HRESULT WINAPI -Main_DirectDrawSurface_EnumOverlayZOrders(LPDIRECTDRAWSURFACE7 iface, - DWORD dwFlags, LPVOID context, - LPDDENUMSURFACESCALLBACK7 cb) -{ - TRACE("(%p)->(%08lx,%p,%p)\n",iface,dwFlags,context,cb); - return DD_OK; -} - -BOOL Main_DirectDrawSurface_flip_data(IDirectDrawSurfaceImpl* front, - IDirectDrawSurfaceImpl* back, - DWORD dwFlags) -{ - /* uniqueness_value? */ - /* This is necessary. But is it safe? */ - { - HDC tmp = front->hDC; - front->hDC = back->hDC; - back->hDC = tmp; - } - - { - BOOL tmp = front->dc_in_use; - front->dc_in_use = back->dc_in_use; - back->dc_in_use = tmp; - } - - { - FLATPTR tmp = front->global.fpVidMem; - front->global.fpVidMem = back->global.fpVidMem; - back->global.fpVidMem = tmp; - } - - { - ULONG_PTR tmp = front->global_more.hKernelSurface; - front->global_more.hKernelSurface = back->global_more.hKernelSurface; - back->global_more.hKernelSurface = tmp; - } - - return TRUE; -} - -/* This is unnecessarely complicated :-) */ -#define MEASUREMENT_WINDOW 5 -#define NUMBER_OF_WINDOWS 10 - -static LONGLONG perf_freq; -static LONGLONG perf_storage[NUMBER_OF_WINDOWS]; -static LONGLONG prev_time = 0; -static unsigned int current_window; -static unsigned int measurements_in_window; -static unsigned int valid_windows; - -HRESULT WINAPI -Main_DirectDrawSurface_Flip(LPDIRECTDRAWSURFACE7 iface, - LPDIRECTDRAWSURFACE7 override, DWORD dwFlags) -{ - IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface; - IDirectDrawSurfaceImpl* target; - HRESULT hr; - - TRACE("(%p)->(%p,%08lx)\n",This,override,dwFlags); - - if (TRACE_ON(ddraw_fps)) { - LONGLONG current_time; - LONGLONG frame_duration; - QueryPerformanceCounter((LARGE_INTEGER *) ¤t_time); - - if (prev_time != 0) { - LONGLONG total_time = 0; - int tot_meas; - - frame_duration = current_time - prev_time; - prev_time = current_time; - - perf_storage[current_window] += frame_duration; - measurements_in_window++; - - if (measurements_in_window >= MEASUREMENT_WINDOW) { - current_window++; - valid_windows++; - - if (valid_windows < NUMBER_OF_WINDOWS) { - unsigned int i; - tot_meas = valid_windows * MEASUREMENT_WINDOW; - for (i = 0; i < valid_windows; i++) { - total_time += perf_storage[i]; - } - } else { - int i; - tot_meas = NUMBER_OF_WINDOWS * MEASUREMENT_WINDOW; - for (i = 0; i < NUMBER_OF_WINDOWS; i++) { - total_time += perf_storage[i]; - } - } - - TRACE_(ddraw_fps)(" %9.5f\n", (double) (perf_freq * tot_meas) / (double) total_time); - - if (current_window >= NUMBER_OF_WINDOWS) { - current_window = 0; - } - perf_storage[current_window] = 0; - measurements_in_window = 0; - } - } else { - prev_time = current_time; - memset(perf_storage, 0, sizeof(perf_storage)); - current_window = 0; - valid_windows = 0; - measurements_in_window = 0; - QueryPerformanceFrequency((LARGE_INTEGER *) &perf_freq); - } - } - - /* MSDN: "This method can be called only for a surface that has the - * DDSCAPS_FLIP and DDSCAPS_FRONTBUFFER capabilities." */ - if ((This->surface_desc.ddsCaps.dwCaps&(DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER)) - != (DDSCAPS_FLIP|DDSCAPS_FRONTBUFFER)) - return DDERR_NOTFLIPPABLE; - - if (This->aux_flip) - if (This->aux_flip(This->aux_ctx, This->aux_data)) - return DD_OK; - - /* 1. find the flip target */ - /* XXX I don't think this algorithm works for more than 1 backbuffer. */ - if (override == NULL) - { - static DDSCAPS2 back_caps = { DDSCAPS_BACKBUFFER }; - LPDIRECTDRAWSURFACE7 tgt; - - hr = IDirectDrawSurface7_GetAttachedSurface(iface, &back_caps, &tgt); - if (FAILED(hr)) return DDERR_NOTFLIPPABLE; /* unchecked */ - - target = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, - tgt); - IDirectDrawSurface7_Release(tgt); - } - else - { - BOOL on_chain = FALSE; - IDirectDrawSurfaceImpl* surf; - - /* MSDN: "The method fails if the specified [override] surface is not - * a member of the flipping chain." */ - - /* Verify that override is on this flip chain. We assume that - * surf is the head of the flipping chain, because it's the front - * buffer. */ - target = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, - override); - - /* Either target is (indirectly) attached to This or This is - * (indirectly) attached to target. */ - for (surf = target; surf != NULL; surf = surf->surface_owner) - { - if (surf == This) - { - on_chain = TRUE; - break; - } - } - - if (!on_chain) - return DDERR_INVALIDPARAMS; /* unchecked */ - } - - TRACE("flip to backbuffer: %p\n",target); - if (TRACE_ON(ddraw_flip)) { - static unsigned int flip_count = 0; - IDirectDrawPaletteImpl *palette; - char buf[32]; - FILE *f; - - /* Hack for paletted games... */ - palette = target->palette; - target->palette = This->palette; - - sprintf(buf, "flip_%08d.ppm", flip_count++); - TRACE_(ddraw_flip)("Dumping file %s to disk.\n", buf); - f = fopen(buf, "wb"); - DDRAW_dump_surface_to_disk(target, f, 8); - target->palette = palette; - } - - if (This->flip_data(This, target, dwFlags)) - This->flip_update(This, dwFlags); - - return DD_OK; -} - -static PrivateData* find_private_data(IDirectDrawSurfaceImpl *This, - REFGUID tag) -{ - PrivateData* data; - for (data = This->private_data; data != NULL; data = data->next) - { - if (IsEqualGUID(&data->tag, tag)) break; - } - - return data; -} - -HRESULT WINAPI -Main_DirectDrawSurface_FreePrivateData(LPDIRECTDRAWSURFACE7 iface, REFGUID tag) -{ - IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface; - PrivateData *data; - - data = find_private_data(This, tag); - if (data == NULL) return DDERR_NOTFOUND; - - if (data->prev) - data->prev->next = data->next; - if (data->next) - data->next->prev = data->prev; - - if (data->flags & DDSPD_IUNKNOWNPTR) - { - if (data->ptr.object != NULL) - IUnknown_Release(data->ptr.object); - } - else - HeapFree(GetProcessHeap(), 0, data->ptr.data); - - HeapFree(GetProcessHeap(), 0, data); - - return DD_OK; -} - -HRESULT WINAPI -Main_DirectDrawSurface_GetAttachedSurface(LPDIRECTDRAWSURFACE7 iface, - LPDDSCAPS2 pCaps, - LPDIRECTDRAWSURFACE7* ppSurface) -{ - IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface; - IDirectDrawSurfaceImpl* surf; - IDirectDrawSurfaceImpl* found = NULL; - DDSCAPS2 our_caps; - - if (TRACE_ON(ddraw)) { - TRACE("(%p)->Looking for caps: %lx,%lx,%lx,%lx output: %p\n",This,pCaps->dwCaps, pCaps->dwCaps2, - pCaps->dwCaps3, pCaps->dwCaps4, ppSurface); - TRACE(" Caps are : "); DDRAW_dump_DDSCAPS2(pCaps); TRACE("\n"); - } - - our_caps = *pCaps; - if ((This->ddraw_owner->local.dwLocalFlags & DDRAWILCL_DIRECTDRAW7) == 0) { - /* As this is not a DirectDraw7 application, remove the garbage that some games - put in the new fields of the DDSCAPS2 structure. */ - our_caps.dwCaps2 = 0; - our_caps.dwCaps3 = 0; - our_caps.dwCaps4 = 0; - if (TRACE_ON(ddraw)) { - TRACE(" Real caps are : "); DDRAW_dump_DDSCAPS2(&our_caps); TRACE("\n"); - } - } - - for (surf = This->attached; surf != NULL; surf = surf->next_attached) - { - if (TRACE_ON(ddraw)) { - TRACE("Surface: (%p) caps: %lx,%lx,%lx,%lx\n", surf, - surf->surface_desc.ddsCaps.dwCaps, - surf->surface_desc.ddsCaps.dwCaps2, - surf->surface_desc.ddsCaps.dwCaps3, - surf->surface_desc.ddsCaps.dwCaps4); - TRACE(" Surface caps are : "); DDRAW_dump_DDSCAPS2(&(surf->surface_desc.ddsCaps)); TRACE("\n"); - } - if (((surf->surface_desc.ddsCaps.dwCaps & our_caps.dwCaps) == our_caps.dwCaps) && - ((surf->surface_desc.ddsCaps.dwCaps2 & our_caps.dwCaps2) == our_caps.dwCaps2)) - { - /* MSDN: "This method fails if more than one surface is attached - * that matches the capabilities requested." */ - if (found != NULL) - { - FIXME("More than one attached surface matches requested caps. What should we do here?\n"); - /* Previous code returned 'DDERR_NOTFOUND'. That appears not - to be correct, given what 3DMark expects from MipMapped surfaces. - We shall just continue instead. */ - } - - found = surf; - } - } - - if (found == NULL) { - TRACE("Did not find any valid surface\n"); - return DDERR_NOTFOUND; - } - - *ppSurface = ICOM_INTERFACE(found, IDirectDrawSurface7); - - if (TRACE_ON(ddraw)) { - TRACE("Returning surface %p with description :\n", *ppSurface); - DDRAW_dump_surface_desc(&(found->surface_desc)); - } - - /* XXX d3dframe.cpp sometimes AddRefs things that it gets from us. */ - IDirectDrawSurface7_AddRef(ICOM_INTERFACE(found, IDirectDrawSurface7)); - return DD_OK; -} - -HRESULT WINAPI -Main_DirectDrawSurface_GetBltStatus(LPDIRECTDRAWSURFACE7 iface, DWORD dwFlags) -{ - TRACE("(%p)->(%08lx)\n",iface,dwFlags); - - switch (dwFlags) - { - case DDGBS_CANBLT: - case DDGBS_ISBLTDONE: - return DD_OK; - - default: - return DDERR_INVALIDPARAMS; - } -} - -HRESULT WINAPI -Main_DirectDrawSurface_GetCaps(LPDIRECTDRAWSURFACE7 iface, LPDDSCAPS2 pCaps) -{ - IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface; - - TRACE("(%p)->(%p)\n",This,pCaps); - *pCaps = This->surface_desc.ddsCaps; - return DD_OK; -} - -HRESULT WINAPI -Main_DirectDrawSurface_GetClipper(LPDIRECTDRAWSURFACE7 iface, - LPDIRECTDRAWCLIPPER* ppClipper) -{ - IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface; - - TRACE("(%p)->(%p)\n",This,ppClipper); - if (This->clipper == NULL) - return DDERR_NOCLIPPERATTACHED; - - *ppClipper = ICOM_INTERFACE(This->clipper, IDirectDrawClipper); - IDirectDrawClipper_AddRef(ICOM_INTERFACE(This->clipper, - IDirectDrawClipper)); - return DD_OK; -} - -HRESULT WINAPI -Main_DirectDrawSurface_GetColorKey(LPDIRECTDRAWSURFACE7 iface, DWORD dwFlags, - LPDDCOLORKEY pCKey) -{ - /* There is a DDERR_NOCOLORKEY error, but how do we know if a color key - * isn't there? That's like saying that an int isn't there. (Which MS - * has done in other docs.) */ - - IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface; - - TRACE("(%p)->(%08lx,%p)\n",This,dwFlags,pCKey); - if (TRACE_ON(ddraw)) { - TRACE(" - colorkey flags : "); - DDRAW_dump_colorkeyflag(dwFlags); - } - - switch (dwFlags) - { - case DDCKEY_DESTBLT: - *pCKey = This->surface_desc.ddckCKDestBlt; - break; - - case DDCKEY_DESTOVERLAY: - *pCKey = This->surface_desc.u3.ddckCKDestOverlay; - break; - - case DDCKEY_SRCBLT: - *pCKey = This->surface_desc.ddckCKSrcBlt; - break; - - case DDCKEY_SRCOVERLAY: - *pCKey = This->surface_desc.ddckCKSrcOverlay; - break; - - default: - return DDERR_INVALIDPARAMS; - } - - return DD_OK; -} - -/* XXX We need to do something with the DC if the surface gets lost. */ -HRESULT WINAPI -Main_DirectDrawSurface_GetDC(LPDIRECTDRAWSURFACE7 iface, HDC *phDC) -{ - DDSURFACEDESC2 ddsd; - HRESULT hr; - IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface; - - TRACE("(%p)->(%p)\n",This,phDC); - CHECK_LOST(This); - - LOCK_OBJECT(This); - - if (This->dc_in_use) - { - UNLOCK_OBJECT(This); - return DDERR_DCALREADYCREATED; - } - - /* Lock as per MSDN. - * Strange: Lock lists DDERR_SURFACEBUSY as an error, meaning that another - * thread has it locked, but GetDC does not. */ - ddsd.dwSize = sizeof(ddsd); - hr = IDirectDrawSurface7_Lock(iface, NULL, &ddsd, 0, 0); - if (FAILED(hr)) - { - UNLOCK_OBJECT(This); - return hr; - } - - hr = This->get_dc(This, &This->hDC); - - if ((This->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) && - (This->palette == NULL)) { - IDirectDrawImpl *ddraw = This->ddraw_owner; - IDirectDrawSurfaceImpl *surf; - - for (surf = ddraw->surfaces; surf != NULL; surf = surf->next_ddraw) { - if (((surf->surface_desc.ddsCaps.dwCaps & (DDSCAPS_PRIMARYSURFACE | DDSCAPS_FRONTBUFFER)) == (DDSCAPS_PRIMARYSURFACE | DDSCAPS_FRONTBUFFER)) && - (surf->palette != NULL)) { - RGBQUAD col[256]; - IDirectDrawPaletteImpl *pal = surf->palette; - unsigned int n; - for (n=0; n<256; n++) { - col[n].rgbRed = pal->palents[n].peRed; - col[n].rgbGreen = pal->palents[n].peGreen; - col[n].rgbBlue = pal->palents[n].peBlue; - col[n].rgbReserved = 0; - } - SetDIBColorTable(This->hDC, 0, 256, col); - break; - } - } - - } - - if (SUCCEEDED(hr)) - { - TRACE("returning %p\n",This->hDC); - - *phDC = This->hDC; - This->dc_in_use = TRUE; - } - else WARN("No DC! Prepare for trouble\n"); - - UNLOCK_OBJECT(This); - return hr; -} - -HRESULT WINAPI -Main_DirectDrawSurface_GetDDInterface(LPDIRECTDRAWSURFACE7 iface, LPVOID* pDD) -{ - IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface; - - TRACE("(%p)->(%p)\n",This,pDD); - *pDD = ICOM_INTERFACE(This->ddraw_owner, IDirectDraw7); - IDirectDraw7_AddRef(ICOM_INTERFACE(This->ddraw_owner, IDirectDraw7)); - return DD_OK; -} - -HRESULT WINAPI -Main_DirectDrawSurface_GetFlipStatus(LPDIRECTDRAWSURFACE7 iface, DWORD dwFlags) -{ - /* XXX: DDERR_INVALIDSURFACETYPE */ - - TRACE("(%p)->(%08lx)\n",iface,dwFlags); - switch (dwFlags) - { - case DDGFS_CANFLIP: - case DDGFS_ISFLIPDONE: - return DD_OK; - - default: - return DDERR_INVALIDPARAMS; - } -} - -HRESULT WINAPI -Main_DirectDrawSurface_GetLOD(LPDIRECTDRAWSURFACE7 iface, LPDWORD pdwMaxLOD) -{ - IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface; - - TRACE("(%p)->(%p)\n",This,pdwMaxLOD); - CHECK_TEXTURE(This); - - *pdwMaxLOD = This->max_lod; - return DD_OK; -} - -HRESULT WINAPI -Main_DirectDrawSurface_GetOverlayPosition(LPDIRECTDRAWSURFACE7 iface, - LPLONG pX, LPLONG pY) -{ - return DDERR_NOTAOVERLAYSURFACE; -} - -HRESULT WINAPI -Main_DirectDrawSurface_GetPalette(LPDIRECTDRAWSURFACE7 iface, - LPDIRECTDRAWPALETTE* ppPalette) -{ - IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface; - - TRACE("(%p)->(%p)\n",This,ppPalette); - if (This->palette == NULL) - return DDERR_NOPALETTEATTACHED; - - *ppPalette = ICOM_INTERFACE(This->palette, IDirectDrawPalette); - IDirectDrawPalette_AddRef(ICOM_INTERFACE(This->palette, - IDirectDrawPalette)); - return DD_OK; -} - -HRESULT WINAPI -Main_DirectDrawSurface_GetPixelFormat(LPDIRECTDRAWSURFACE7 iface, - LPDDPIXELFORMAT pDDPixelFormat) -{ - /* What is DDERR_INVALIDSURFACETYPE for here? */ - IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface; - - TRACE("(%p)->(%p)\n",This,pDDPixelFormat); - DD_STRUCT_COPY_BYSIZE(pDDPixelFormat,&This->surface_desc.u4.ddpfPixelFormat); - return DD_OK; -} - -HRESULT WINAPI -Main_DirectDrawSurface_GetPriority(LPDIRECTDRAWSURFACE7 iface, - LPDWORD pdwPriority) -{ - IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface; - - TRACE("(%p)->(%p)\n",This,pdwPriority); - CHECK_TEXTURE(This); - - *pdwPriority = This->priority; - return DD_OK; -} - -HRESULT WINAPI -Main_DirectDrawSurface_GetPrivateData(LPDIRECTDRAWSURFACE7 iface, - REFGUID tag, LPVOID pBuffer, - LPDWORD pcbBufferSize) -{ - IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface; - PrivateData* data; - - TRACE("(%p)->(%p), size = %ld\n", This, pBuffer, *pcbBufferSize); - - data = find_private_data(This, tag); - if (data == NULL) return DDERR_NOTFOUND; - - /* This may not be right. */ - if ((data->flags & DDSPD_VOLATILE) - && data->uniqueness_value != This->uniqueness_value) - return DDERR_EXPIRED; - - if (*pcbBufferSize < data->size) - { - *pcbBufferSize = data->size; - return DDERR_MOREDATA; - } - - if (data->flags & DDSPD_IUNKNOWNPTR) - { - *(LPUNKNOWN *)pBuffer = data->ptr.object; - IUnknown_AddRef(data->ptr.object); - } - else - { - memcpy(pBuffer, data->ptr.data, data->size); - } - - return DD_OK; -} - -HRESULT WINAPI -Main_DirectDrawSurface_GetSurfaceDesc(LPDIRECTDRAWSURFACE7 iface, - LPDDSURFACEDESC2 pDDSD) -{ - IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface; - - TRACE("(%p)->(%p)\n",This,pDDSD); - if ((pDDSD->dwSize < sizeof(DDSURFACEDESC)) || - (pDDSD->dwSize > sizeof(DDSURFACEDESC2))) { - ERR("Impossible/Strange struct size %ld.\n",pDDSD->dwSize); - return DDERR_GENERIC; - } - - DD_STRUCT_COPY_BYSIZE(pDDSD,&This->surface_desc); - if (TRACE_ON(ddraw)) { - DDRAW_dump_surface_desc(pDDSD); - } - return DD_OK; -} - -HRESULT WINAPI -Main_DirectDrawSurface_GetUniquenessValue(LPDIRECTDRAWSURFACE7 iface, - LPDWORD pValue) -{ - IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface; - - TRACE("(%p)->(%p)\n",This,pValue); - *pValue = This->uniqueness_value; - return DD_OK; -} - -HRESULT WINAPI -Main_DirectDrawSurface_Initialize(LPDIRECTDRAWSURFACE7 iface, - LPDIRECTDRAW pDD, LPDDSURFACEDESC2 pDDSD) -{ - TRACE("(%p)->(%p,%p)\n",iface,pDD,pDDSD); - return DDERR_ALREADYINITIALIZED; -} - -HRESULT WINAPI -Main_DirectDrawSurface_IsLost(LPDIRECTDRAWSURFACE7 iface) -{ - IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface; - - TRACE("(%p) is%s lost\n",This, (This->lost ? "" : " not")); - return This->lost ? DDERR_SURFACELOST : DD_OK; -} - - -/* XXX This doesn't actually do any locking or keep track of the locked - * rectangles. The behaviour is poorly documented. */ -HRESULT WINAPI -Main_DirectDrawSurface_Lock(LPDIRECTDRAWSURFACE7 iface, LPRECT prect, - LPDDSURFACEDESC2 pDDSD, DWORD flags, HANDLE h) -{ - IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface; - - if (TRACE_ON(ddraw)) { - TRACE("(%p)->Lock(%p,%p,%08lx,%p)\n",This,prect,pDDSD,flags,h); - TRACE(" - locking flags : "); DDRAW_dump_lockflag(flags); - } - if (WARN_ON(ddraw)) { - if (flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY)) { - WARN(" - unsupported locking flag : "); DDRAW_dump_lockflag(flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY)); - } - } - if (NULL != h) { - return DDERR_INVALIDPARAMS; - } - if (NULL == pDDSD) { - return DDERR_INVALIDPARAMS; - } - - /* If the surface is already locked, return busy */ - if (This->locked) { - WARN(" Surface is busy, returning DDERR_SURFACEBUSY\n"); - return DDERR_SURFACEBUSY; - } - - /* First, copy the Surface description */ - DD_STRUCT_COPY_BYSIZE(pDDSD,&(This->surface_desc)); - - /* Used to optimize the D3D Device locking */ - This->lastlocktype = flags & (DDLOCK_READONLY|DDLOCK_WRITEONLY); - - /* If asked only for a part, change the surface pointer. - * (Not documented.) */ - if (prect != NULL) { - TRACE(" lprect: %ldx%ld-%ldx%ld\n", - prect->left,prect->top,prect->right,prect->bottom); - /* First do some sanity checkings on the rectangle we receive. - DungeonSiege seems to gives us once a very bad rectangle for example */ - if ((prect->top < 0) || - (prect->left < 0) || - (prect->bottom < 0) || - (prect->right < 0) || - (prect->left >= prect->right) || - (prect->top >= prect->bottom) || - (prect->left >= This->surface_desc.dwWidth) || - (prect->right > This->surface_desc.dwWidth) || - (prect->top >= This->surface_desc.dwHeight) || - (prect->bottom > This->surface_desc.dwHeight)) { - ERR(" Invalid values in LPRECT !!!\n"); - return DDERR_INVALIDPARAMS; - } - - This->lock_update(This, prect, flags); - - if (pDDSD->u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC) { - int blksize; - switch(pDDSD->u4.ddpfPixelFormat.dwFourCC) { - case MAKE_FOURCC('D','X','T','1') : blksize = 8; break; - case MAKE_FOURCC('D','X','T','3') : blksize = 16; break; - case MAKE_FOURCC('D','X','T','5') : blksize = 16; break; - default: return DDERR_INVALIDPIXELFORMAT; - } - pDDSD->lpSurface = (char *)This->surface_desc.lpSurface - + prect->top/4 * (pDDSD->dwWidth+3)/4 * blksize - + prect->left/4 * blksize; - } else - pDDSD->lpSurface = (char *)This->surface_desc.lpSurface - + prect->top * This->surface_desc.u1.lPitch - + prect->left * GET_BPP(This->surface_desc); - } else { - This->lock_update(This, NULL, flags); - } - - This->locked = TRUE; - - TRACE("locked surface returning description :\n"); - if (TRACE_ON(ddraw)) DDRAW_dump_surface_desc(pDDSD); - - return DD_OK; -} - -HRESULT WINAPI -Main_DirectDrawSurface_PageLock(LPDIRECTDRAWSURFACE7 iface, DWORD dwFlags) -{ - /* Some surface types should return DDERR_CANTPAGELOCK. */ - return DD_OK; -} - -HRESULT WINAPI -Main_DirectDrawSurface_PageUnlock(LPDIRECTDRAWSURFACE7 iface, DWORD dwFlags) -{ - /* Some surface types should return DDERR_CANTPAGEUNLOCK, and we should - * keep track so we can return DDERR_NOTPAGELOCKED as appropriate. */ - return DD_OK; -} - -HRESULT WINAPI -Main_DirectDrawSurface_ReleaseDC(LPDIRECTDRAWSURFACE7 iface, HDC hDC) -{ - HRESULT hr; - IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface; - - TRACE("(%p)->(%p)\n",This,hDC); - - if (!This->dc_in_use || This->hDC != hDC) - return DDERR_INVALIDPARAMS; - - This->release_dc(This, hDC); - - hr = IDirectDrawSurface7_Unlock(iface, NULL); - if (FAILED(hr)) return hr; - - This->dc_in_use = FALSE; - This->hDC = 0; - - return DD_OK; -} - -/* Restore */ - -HRESULT WINAPI -Main_DirectDrawSurface_SetClipper(LPDIRECTDRAWSURFACE7 iface, - LPDIRECTDRAWCLIPPER pDDClipper) -{ - IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface; - - TRACE("(%p)->(%p)\n",This,pDDClipper); - if (pDDClipper == ICOM_INTERFACE(This->clipper, IDirectDrawClipper)) - return DD_OK; - - if (This->clipper != NULL) - IDirectDrawClipper_Release(ICOM_INTERFACE(This->clipper, - IDirectDrawClipper)); - - This->clipper = ICOM_OBJECT(IDirectDrawClipperImpl, IDirectDrawClipper, - pDDClipper); - if (pDDClipper != NULL) - IDirectDrawClipper_AddRef(pDDClipper); - - return DD_OK; -} - -HRESULT WINAPI -Main_DirectDrawSurface_SetColorKey(LPDIRECTDRAWSURFACE7 iface, - DWORD dwFlags, LPDDCOLORKEY pCKey) -{ - IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface; - - TRACE("(%p)->(%08lx,%p)\n",This,dwFlags,pCKey); - - if (TRACE_ON(ddraw)) { - TRACE(" - colorkey flags : "); - DDRAW_dump_colorkeyflag(dwFlags); - } - - if ((dwFlags & DDCKEY_COLORSPACE) != 0) { - FIXME(" colorkey value not supported (%08lx) !\n", dwFlags); - return DDERR_INVALIDPARAMS; - } - - /* TODO: investigate if this function can take multiple bits set at the same - time (ie setting multiple colorkey values at the same time with only - one API call). - */ - if (pCKey) { - switch (dwFlags & ~DDCKEY_COLORSPACE) { - case DDCKEY_DESTBLT: - This->surface_desc.ddckCKDestBlt = *pCKey; - This->surface_desc.dwFlags |= DDSD_CKDESTBLT; - break; - - case DDCKEY_DESTOVERLAY: - This->surface_desc.u3.ddckCKDestOverlay = *pCKey; - This->surface_desc.dwFlags |= DDSD_CKDESTOVERLAY; - break; - - case DDCKEY_SRCOVERLAY: - This->surface_desc.ddckCKSrcOverlay = *pCKey; - This->surface_desc.dwFlags |= DDSD_CKSRCOVERLAY; - break; - - case DDCKEY_SRCBLT: - This->surface_desc.ddckCKSrcBlt = *pCKey; - This->surface_desc.dwFlags |= DDSD_CKSRCBLT; - break; - - default: - return DDERR_INVALIDPARAMS; - } - } else { - switch (dwFlags & ~DDCKEY_COLORSPACE) { - case DDCKEY_DESTBLT: - This->surface_desc.dwFlags &= ~DDSD_CKDESTBLT; - break; - - case DDCKEY_DESTOVERLAY: - This->surface_desc.dwFlags &= ~DDSD_CKDESTOVERLAY; - break; - - case DDCKEY_SRCOVERLAY: - This->surface_desc.dwFlags &= ~DDSD_CKSRCOVERLAY; - break; - - case DDCKEY_SRCBLT: - This->surface_desc.dwFlags &= ~DDSD_CKSRCBLT; - break; - - default: - return DDERR_INVALIDPARAMS; - } - } - - if (This->aux_setcolorkey_cb) This->aux_setcolorkey_cb(This, dwFlags, pCKey); - - return DD_OK; -} - -HRESULT WINAPI -Main_DirectDrawSurface_SetLOD(LPDIRECTDRAWSURFACE7 iface, DWORD dwMaxLOD) -{ - IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface; - - TRACE("(%p)->(%08lx)\n",This,dwMaxLOD); - CHECK_TEXTURE(This); - - This->max_lod = dwMaxLOD; - return DD_OK; -} - -HRESULT WINAPI -Main_DirectDrawSurface_SetOverlayPosition(LPDIRECTDRAWSURFACE7 iface, - LONG X, LONG Y) -{ - return DDERR_NOTAOVERLAYSURFACE; -} - -HRESULT WINAPI -Main_DirectDrawSurface_SetPalette(LPDIRECTDRAWSURFACE7 iface, - LPDIRECTDRAWPALETTE pPalette) -{ - IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface; - IDirectDrawPalette *pal_to_rel = NULL; - - TRACE("(%p)->(%p)\n",This,pPalette); - if (pPalette == ICOM_INTERFACE(This->palette, IDirectDrawPalette)) - return DD_OK; - - if (This->palette != NULL) { - if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) - This->palette->global.dwFlags &= ~DDPCAPS_PRIMARYSURFACE; - pal_to_rel = ICOM_INTERFACE(This->palette, IDirectDrawPalette); - } - - This->palette = ICOM_OBJECT(IDirectDrawPaletteImpl, IDirectDrawPalette, - pPalette); - if (pPalette != NULL) { - IDirectDrawPalette_AddRef(pPalette); - if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) - This->palette->global.dwFlags |= DDPCAPS_PRIMARYSURFACE; - } - - This->set_palette(This, This->palette); - - /* Do the palette release at the end to prevent doing some 'loop' when removing - * the surface maintaining the last reference on a palette. - */ - if (pal_to_rel != NULL) - IDirectDrawPalette_Release(pal_to_rel); - - return DD_OK; -} - -HRESULT WINAPI -Main_DirectDrawSurface_SetPriority(LPDIRECTDRAWSURFACE7 iface, - DWORD dwPriority) -{ - IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface; - - TRACE("(%p)->(%08lx)\n",This,dwPriority); - CHECK_TEXTURE(This); - - This->priority = dwPriority; - return DD_OK; -} - -/* Be careful when locking this: it is risky to call the object's AddRef - * or Release holding a lock. */ -HRESULT WINAPI -Main_DirectDrawSurface_SetPrivateData(LPDIRECTDRAWSURFACE7 iface, - REFGUID tag, LPVOID pData, - DWORD cbSize, DWORD dwFlags) -{ - PrivateData* data; - IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface; - - TRACE("(%p)->(%p), size=%ld\n", This, pData, cbSize); - - data = find_private_data(This, tag); - if (data == NULL) - { - data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*data)); - if (data == NULL) return DDERR_OUTOFMEMORY; - - data->tag = *tag; - data->flags = dwFlags; - data->uniqueness_value = This->uniqueness_value; - - if (dwFlags & DDSPD_IUNKNOWNPTR) - { - data->ptr.object = (LPUNKNOWN)pData; - data->size = sizeof(LPUNKNOWN); - IUnknown_AddRef(data->ptr.object); - } - else - { - data->ptr.data = HeapAlloc(GetProcessHeap(), 0, cbSize); - if (data->ptr.data == NULL) - { - HeapFree(GetProcessHeap(), 0, data); - return DDERR_OUTOFMEMORY; - } - - data->size = cbSize; - memcpy(data->ptr.data, pData, data->size); - } - - /* link it in */ - data->next = This->private_data; - data->prev = NULL; - if (This->private_data) - This->private_data->prev = data; - This->private_data = data; - - return DD_OK; - } - else - { - /* I don't actually know how windows handles this case. The only - * reason I don't just call FreePrivateData is because I want to - * guarantee SetPrivateData working when using LPUNKNOWN or data - * that is no larger than the old data. */ - - FIXME("Replacing existing private data not implemented yet.\n"); - return E_FAIL; - } -} - -/* SetSurfaceDesc */ - -HRESULT WINAPI -Main_DirectDrawSurface_Unlock(LPDIRECTDRAWSURFACE7 iface, LPRECT pRect) -{ - IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)iface; - - TRACE("(%p)->Unlock(%p)\n",This,pRect); - - if (!This->locked) { - WARN("Surface not locked - returing DDERR_NOTLOCKED\n"); - return DDERR_NOTLOCKED; - } - - This->locked = FALSE; - This->unlock_update(This, pRect); - if (This->aux_unlock) - This->aux_unlock(This->aux_ctx, This->aux_data, pRect); - - return DD_OK; -} - -HRESULT WINAPI -Main_DirectDrawSurface_UpdateOverlay(LPDIRECTDRAWSURFACE7 iface, - LPRECT pSrcRect, - LPDIRECTDRAWSURFACE7 pDstSurface, - LPRECT pDstRect, DWORD dwFlags, - LPDDOVERLAYFX pFX) -{ - return DDERR_UNSUPPORTED; -} - -/* MSDN: "not currently implemented." */ -HRESULT WINAPI -Main_DirectDrawSurface_UpdateOverlayDisplay(LPDIRECTDRAWSURFACE7 iface, - DWORD dwFlags) -{ - return DDERR_UNSUPPORTED; -} - -HRESULT WINAPI -Main_DirectDrawSurface_UpdateOverlayZOrder(LPDIRECTDRAWSURFACE7 iface, - DWORD dwFlags, - LPDIRECTDRAWSURFACE7 pDDSRef) -{ - return DDERR_NOTAOVERLAYSURFACE; -} diff --git a/dlls/ddraw/surface_thunks.c b/dlls/ddraw/surface_thunks.c index 7a9861c836..bba49bd375 100644 --- a/dlls/ddraw/surface_thunks.c +++ b/dlls/ddraw/surface_thunks.c @@ -17,6 +17,8 @@ */ #include "config.h" +#include "wine/port.h" +#include "wine/debug.h" #include #include "windef.h" @@ -38,6 +40,8 @@ IDirectDrawSurface3, \ (pdds)) +WINE_DEFAULT_DEBUG_CHANNEL(ddraw_thunk); + static HRESULT WINAPI IDirectDrawSurface3Impl_QueryInterface(LPDIRECTDRAWSURFACE3 This, REFIID iid, LPVOID *ppObj) @@ -52,9 +56,11 @@ IDirectDrawSurface3Impl_AddRef(LPDIRECTDRAWSURFACE3 This) } static ULONG WINAPI -IDirectDrawSurface3Impl_Release(LPDIRECTDRAWSURFACE3 This) +IDirectDrawSurface3Impl_Release(LPDIRECTDRAWSURFACE3 iface) { - return IDirectDrawSurface7_Release(CONVERT(This)); + ICOM_THIS_FROM( IDirectDrawSurfaceImpl, IDirectDrawSurface3, iface); + TRACE("(%p)\n", This); + return IDirectDrawSurface7_Release(CONVERT(iface)); } static HRESULT WINAPI @@ -389,7 +395,7 @@ IDirectDrawSurface3Impl_SetSurfaceDesc(LPDIRECTDRAWSURFACE3 This, dwFlags); } -const IDirectDrawSurface3Vtbl DDRAW_IDDS3_Thunk_VTable = +const IDirectDrawSurface3Vtbl IDirectDrawSurface3_Vtbl = { IDirectDrawSurface3Impl_QueryInterface, IDirectDrawSurface3Impl_AddRef, diff --git a/dlls/ddraw/surface_user.c b/dlls/ddraw/surface_user.c deleted file mode 100644 index 86f6088905..0000000000 --- a/dlls/ddraw/surface_user.c +++ /dev/null @@ -1,675 +0,0 @@ -/* User-based primary surface driver - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "config.h" - -#include -#include -#include - -#include "winerror.h" -#include "wine/debug.h" -#include "ddraw_private.h" - -WINE_DEFAULT_DEBUG_CHANNEL(ddraw); - -/* if you use OWN_WINDOW, don't use SYNC_UPDATE, or you may get trouble */ -/* #define SYNC_UPDATE */ -/* - * FIXME: This does not work any more because the created window has its own - * thread queue that cannot be manipulated by application threads. - * #define OWN_WINDOW - */ - -#ifdef OWN_WINDOW -static void User_create_own_window(IDirectDrawSurfaceImpl* This); -static void User_destroy_own_window(IDirectDrawSurfaceImpl* This); -#endif -#ifndef SYNC_UPDATE -static DWORD CALLBACK User_update_thread(LPVOID); -#endif -static void User_copy_to_screen(IDirectDrawSurfaceImpl* This, LPCRECT rc); - -static HWND get_display_window(IDirectDrawSurfaceImpl* This, LPPOINT pt); - -static const IDirectDrawSurface7Vtbl User_IDirectDrawSurface7_VTable; - -HRESULT -User_DirectDrawSurface_Construct(IDirectDrawSurfaceImpl* This, - IDirectDrawImpl* pDD, - const DDSURFACEDESC2* pDDSD) -{ - USER_PRIV_VAR(priv, This); - HRESULT hr; - - TRACE("(%p,%p,%p)\n",This,pDD,pDDSD); - hr = DIB_DirectDrawSurface_Construct(This, pDD, pDDSD); - if (FAILED(hr)) return hr; - - ICOM_INIT_INTERFACE(This, IDirectDrawSurface7, - User_IDirectDrawSurface7_VTable); - - This->final_release = User_DirectDrawSurface_final_release; - This->duplicate_surface = User_DirectDrawSurface_duplicate_surface; - - This->lock_update = User_DirectDrawSurface_lock_update; - This->unlock_update = User_DirectDrawSurface_unlock_update; - - This->flip_data = User_DirectDrawSurface_flip_data; - This->flip_update = User_DirectDrawSurface_flip_update; - - This->get_dc = User_DirectDrawSurface_get_dc; - This->release_dc = User_DirectDrawSurface_release_dc; - - This->set_palette = User_DirectDrawSurface_set_palette; - This->update_palette = User_DirectDrawSurface_update_palette; - - This->get_gamma_ramp = User_DirectDrawSurface_get_gamma_ramp; - This->set_gamma_ramp = User_DirectDrawSurface_set_gamma_ramp; - - This->get_display_window = User_DirectDrawSurface_get_display_window; - - if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) - { -#ifdef OWN_WINDOW - DirectDrawSurface_RegisterClass(); -#endif -#ifndef SYNC_UPDATE - InitializeCriticalSection(&priv->user.crit); - priv->user.refresh_event = CreateEventW(NULL, TRUE, FALSE, NULL); - priv->user.update_event = CreateEventW(NULL, FALSE, FALSE, NULL); - priv->user.update_thread = CreateThread(NULL, 0, User_update_thread, This, 0, NULL); -#ifdef OWN_WINDOW - if (This->ddraw_owner->cooperative_level & DDSCL_FULLSCREEN) { - /* wait for window creation (or update thread destruction) */ - while (WaitForMultipleObjects(1, &priv->user.update_thread, FALSE, 100) == WAIT_TIMEOUT) - if (This->more.lpDDRAWReserved) break; - if (!This->more.lpDDRAWReserved) { - ERR("window creation failed\n"); - } - } -#endif -#else -#ifdef OWN_WINDOW - User_create_own_window(This); -#endif -#endif - if (!This->more.lpDDRAWReserved) - This->more.lpDDRAWReserved = (LPVOID)pDD->window; - } - - return DIB_DirectDrawSurface_alloc_dc(This, &priv->user.cached_dc); -} - -HRESULT -User_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(User_DirectDrawSurfaceImpl)); - if (This == NULL) return E_OUTOFMEMORY; - - This->private = (User_DirectDrawSurfaceImpl*)(This+1); - - hr = User_DirectDrawSurface_Construct(This, pDD, pDDSD); - if (FAILED(hr)) - HeapFree(GetProcessHeap(), 0, This); - else - *ppSurf = ICOM_INTERFACE(This, IDirectDrawSurface7); - - return hr; -} - -void User_DirectDrawSurface_final_release(IDirectDrawSurfaceImpl* This) -{ - USER_PRIV_VAR(priv, This); - - if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) - { -#ifndef SYNC_UPDATE - HANDLE event = priv->user.update_event; - priv->user.update_event = 0; - SetEvent(event); - TRACE("waiting for update thread to terminate...\n"); -#ifdef OWN_WINDOW - /* dispatch any waiting sendmessages */ - { - MSG msg; - PeekMessageA(&msg, 0, 0, 0, PM_NOREMOVE); - } - /* to avoid deadlocks, allow SendMessages from update thread - * through while we wait for it */ - while (MsgWaitForMultipleObjects(1, &priv->user.update_thread, FALSE, - INFINITE, QS_SENDMESSAGE) == WAIT_OBJECT_0+1) - { - MSG msg; - PeekMessageA(&msg, 0, 0, 0, PM_NOREMOVE); - } -#else - WaitForSingleObject(priv->user.update_thread,INFINITE); -#endif - TRACE("update thread terminated\n"); - CloseHandle(event); - CloseHandle(priv->user.update_thread); - CloseHandle(priv->user.refresh_event); - DeleteCriticalSection(&priv->user.crit); -#else -#ifdef OWN_WINDOW - User_destroy_own_window(This); -#endif -#endif - This->more.lpDDRAWReserved = 0; -#ifdef OWN_WINDOW - DirectDrawSurface_UnregisterClass(); -#endif - } - DIB_DirectDrawSurface_free_dc(This, priv->user.cached_dc); - DIB_DirectDrawSurface_final_release(This); -} - -static int User_DirectDrawSurface_init_wait(IDirectDrawSurfaceImpl* This) -{ - USER_PRIV_VAR(priv, This); - int need_wait; - EnterCriticalSection(&priv->user.crit); - priv->user.wait_count++; - need_wait = priv->user.in_refresh; - LeaveCriticalSection(&priv->user.crit); - return need_wait; -} - -static void User_DirectDrawSurface_end_wait(IDirectDrawSurfaceImpl* This) -{ - USER_PRIV_VAR(priv, This); - EnterCriticalSection(&priv->user.crit); - if (!--priv->user.wait_count) - ResetEvent(priv->user.refresh_event); - LeaveCriticalSection(&priv->user.crit); -} - -static void User_DirectDrawSurface_wait_update(IDirectDrawSurfaceImpl* This) -{ - USER_PRIV_VAR(priv, This); - if (priv->user.in_refresh) { - if (User_DirectDrawSurface_init_wait(This)) - WaitForSingleObject(priv->user.refresh_event, 2); - User_DirectDrawSurface_end_wait(This); - } -} - -void User_DirectDrawSurface_lock_update(IDirectDrawSurfaceImpl* This, - LPCRECT pRect, DWORD dwFlags) -{ -#if 0 - if (!(dwFlags & DDLOCK_WRITEONLY)) - User_copy_from_screen(This, pRect); -#endif - if (dwFlags & DDLOCK_WAIT) User_DirectDrawSurface_wait_update(This); - - if (pRect) { - This->lastlockrect = *pRect; - } else { - This->lastlockrect.left = This->lastlockrect.right = 0; - } -} - -void User_DirectDrawSurface_unlock_update(IDirectDrawSurfaceImpl* This, - LPCRECT pRect) -{ - if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) - { -#ifdef SYNC_UPDATE - User_copy_to_screen(This, pRect); -#else - USER_PRIV_VAR(priv, This); - SetEvent(priv->user.update_event); -#endif - } -} - -void User_DirectDrawSurface_set_palette(IDirectDrawSurfaceImpl* This, - IDirectDrawPaletteImpl* pal) -{ - USER_PRIV_VAR(priv, This); - - if (!pal) { - FIXME("selecting null palette\n"); - /* I don't think selecting GDI object 0 will work, we should select - * the original palette, returned by the first SelectPalette */ - SelectPalette(priv->user.cached_dc, 0, FALSE); - return; - } - - SelectPalette(priv->user.cached_dc, pal->hpal, FALSE); - - DIB_DirectDrawSurface_set_palette(This, pal); -} - -void User_DirectDrawSurface_update_palette(IDirectDrawSurfaceImpl* This, - IDirectDrawPaletteImpl* pal, - DWORD dwStart, DWORD dwCount, - LPPALETTEENTRY palent) -{ -#ifndef SYNC_UPDATE - USER_PRIV_VAR(priv, This); -#endif - - DIB_DirectDrawSurface_update_palette(This, pal, dwStart, dwCount, palent); - /* FIXME: realize palette on display window */ - -#ifndef SYNC_UPDATE - /* with async updates, it's probably cool to force an update */ - SetEvent(priv->user.update_event); -#endif -} - -HRESULT User_DirectDrawSurface_duplicate_surface(IDirectDrawSurfaceImpl* This, - LPDIRECTDRAWSURFACE7* ppDup) -{ - return User_DirectDrawSurface_Create(This->ddraw_owner, - &This->surface_desc, ppDup, NULL); -} - -BOOL User_DirectDrawSurface_flip_data(IDirectDrawSurfaceImpl* front, - IDirectDrawSurfaceImpl* back, - DWORD dwFlags) -{ - USER_PRIV_VAR(front_priv, front); - USER_PRIV_VAR(back_priv, back); - - { - HDC tmp; - tmp = front_priv->user.cached_dc; - front_priv->user.cached_dc = back_priv->user.cached_dc; - back_priv->user.cached_dc = tmp; - } - - return DIB_DirectDrawSurface_flip_data(front, back, dwFlags); -} - -void User_DirectDrawSurface_flip_update(IDirectDrawSurfaceImpl* This, DWORD dwFlags) -{ -#ifdef SYNC_UPDATE - This->lastlockrect.left = This->lastlockrect.right = 0; - assert(This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE); - User_copy_to_screen(This,NULL); -#else - USER_PRIV_VAR(priv, This); - assert(This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE); - if (dwFlags & DDFLIP_WAIT) User_DirectDrawSurface_wait_update(This); - This->lastlockrect.left = This->lastlockrect.right = 0; - SetEvent(priv->user.update_event); -#endif -} - -HRESULT User_DirectDrawSurface_get_dc(IDirectDrawSurfaceImpl* This, HDC* phDC) -{ - USER_PRIV_VAR(priv, This); - - *phDC = priv->user.cached_dc; - return S_OK; -} - -HRESULT User_DirectDrawSurface_release_dc(IDirectDrawSurfaceImpl* This, - HDC hDC) -{ - return S_OK; -} - -HRESULT User_DirectDrawSurface_get_gamma_ramp(IDirectDrawSurfaceImpl* This, - DWORD dwFlags, - LPDDGAMMARAMP lpGammaRamp) -{ - if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) - { - POINT offset; - HWND hDisplayWnd; - HDC hDisplayDC; - HRESULT hr; - hDisplayWnd = get_display_window(This, &offset); - hDisplayDC = GetDCEx(hDisplayWnd, 0, DCX_CLIPSIBLINGS|DCX_CACHE); - hr = GetDeviceGammaRamp(hDisplayDC, lpGammaRamp) ? DD_OK : DDERR_UNSUPPORTED; - ReleaseDC(hDisplayWnd, hDisplayDC); - return hr; - } - return Main_DirectDrawSurface_get_gamma_ramp(This, dwFlags, lpGammaRamp); -} - -HRESULT User_DirectDrawSurface_set_gamma_ramp(IDirectDrawSurfaceImpl* This, - DWORD dwFlags, - LPDDGAMMARAMP lpGammaRamp) -{ - if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) - { - POINT offset; - HWND hDisplayWnd; - HDC hDisplayDC; - HRESULT hr; - hDisplayWnd = get_display_window(This, &offset); - hDisplayDC = GetDCEx(hDisplayWnd, 0, DCX_CLIPSIBLINGS|DCX_CACHE); - hr = SetDeviceGammaRamp(hDisplayDC, lpGammaRamp) ? DD_OK : DDERR_UNSUPPORTED; - ReleaseDC(hDisplayWnd, hDisplayDC); - return hr; - } - return Main_DirectDrawSurface_set_gamma_ramp(This, dwFlags, lpGammaRamp); -} - -/* Returns the window that hosts the display. - * *pt is set to the upper left position of the window relative to the - * upper left corner of the surface. */ -static HWND get_display_window(IDirectDrawSurfaceImpl* This, LPPOINT pt) -{ - memset(pt, 0, sizeof(*pt)); - - if (This->ddraw_owner->cooperative_level & DDSCL_FULLSCREEN) - { -#ifdef OWN_WINDOW - USER_PRIV_VAR(priv, This); -#if 1 - SetWindowPos(priv->user.window, HWND_TOP, 0, 0, 0, 0, - SWP_DEFERERASE|SWP_NOACTIVATE|SWP_NOCOPYBITS|SWP_NOMOVE| - SWP_NOREDRAW|SWP_NOSENDCHANGING|SWP_NOSIZE); -#endif - return priv->user.window; -#else - return This->ddraw_owner->window; -#endif - } - else - { - if (This->clipper != NULL) - { - /* looks silly, but since we don't have the clipper locked */ - HWND hWnd = This->clipper->hWnd; - - if (hWnd != 0) - { - ClientToScreen(hWnd, pt); - return hWnd; - } - else - { - static BOOL warn = 0; - if (!warn++) FIXME("clipper clip lists not supported\n"); - - return GetDesktopWindow(); - } - } - else - { - static BOOL warn = 0; - if (!warn++) WARN("hosting on root\n"); - - return GetDesktopWindow(); - } - } -} - -HWND User_DirectDrawSurface_get_display_window(IDirectDrawSurfaceImpl* This) -{ - POINT offset; - return get_display_window(This, &offset); -} - -#ifdef OWN_WINDOW -static void User_create_own_window(IDirectDrawSurfaceImpl* This) -{ - USER_PRIV_VAR(priv, This); - - if (This->ddraw_owner->cooperative_level & DDSCL_FULLSCREEN) - { - priv->user.window = CreateWindowExA(WS_EX_TOPMOST | - WS_EX_LAYERED | - WS_EX_TRANSPARENT, - "WINE_DDRAW", "DirectDraw", - WS_POPUP, - 0, 0, - This->surface_desc.dwWidth, - This->surface_desc.dwHeight, - GetDesktopWindow(), - 0, 0, This); - This->more.lpDDRAWReserved = (LPVOID)priv->user.window; - SetWindowPos(priv->user.window, HWND_TOP, 0, 0, 0, 0, - SWP_DEFERERASE|SWP_NOACTIVATE|SWP_NOCOPYBITS|SWP_NOMOVE| - SWP_NOREDRAW|SWP_NOSENDCHANGING|SWP_NOSIZE|SWP_SHOWWINDOW); - UpdateWindow(priv->user.window); - } -} - -static void User_destroy_own_window(IDirectDrawSurfaceImpl* This) -{ - USER_PRIV_VAR(priv, This); - - if (priv->user.window) - { - SetWindowPos(priv->user.window, 0, 0, 0, 0, 0, - SWP_DEFERERASE|SWP_NOACTIVATE|SWP_NOCOPYBITS|SWP_NOMOVE|SWP_NOZORDER| - SWP_NOREDRAW|SWP_NOSENDCHANGING|SWP_NOSIZE|SWP_HIDEWINDOW); - This->more.lpDDRAWReserved = NULL; - DestroyWindow(priv->user.window); - priv->user.window = 0; - } -} -#endif - -#ifndef SYNC_UPDATE -static DWORD CALLBACK User_update_thread(LPVOID arg) -{ - IDirectDrawSurfaceImpl *This = (IDirectDrawSurfaceImpl *)arg; - USER_PRIV_VAR(priv, This); - volatile HANDLE *pActive = (volatile HANDLE *)&priv->user.update_event; - HANDLE event = *pActive; - -#ifdef OWN_WINDOW - User_create_own_window(This); -#endif - - /* the point of this is that many games lock the primary surface - * multiple times per frame; this thread will then simply copy as - * often as it can without keeping the main thread waiting for - * each unlock, thus keeping the frame rate high */ - do { -#ifdef OWN_WINDOW - DWORD ret = MsgWaitForMultipleObjects(1, &event, FALSE, INFINITE, QS_ALLINPUT); - MSG msg; - - while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) - { - switch (msg.message) { - case WM_PAINT: - DispatchMessageA(&msg); - break; - default: - /* since we risk getting keyboard messages posted to us, - * repost posted messages to cooperative window */ - PostMessageA(This->ddraw_owner->window, msg.message, msg.wParam, msg.lParam); - } - } -#else - DWORD ret = WaitForSingleObject(event, INFINITE); -#endif - if (ret == WAIT_OBJECT_0) - { - if (*pActive) { - priv->user.in_refresh = TRUE; - User_copy_to_screen(This, NULL); - EnterCriticalSection(&priv->user.crit); - priv->user.in_refresh = FALSE; - if (priv->user.wait_count) - SetEvent(priv->user.refresh_event); - LeaveCriticalSection(&priv->user.crit); - } else - break; - } - else if (ret != WAIT_OBJECT_0+1) break; - } while (TRUE); - - SetEvent(priv->user.refresh_event); -#ifdef OWN_WINDOW - User_destroy_own_window(This); -#endif - - return 0; -} -#endif - -static void User_copy_to_screen(IDirectDrawSurfaceImpl* This, LPCRECT rc) -{ - if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) - { - POINT offset; - HWND hDisplayWnd; - HDC hDisplayDC; - HDC hSurfaceDC; - RECT drawrect; - - if (FAILED(This->get_dc(This, &hSurfaceDC))) - return; - - hDisplayWnd = get_display_window(This, &offset); - hDisplayDC = GetDCEx(hDisplayWnd, 0, DCX_CLIPSIBLINGS|DCX_CACHE); -#if 0 - /* FIXME: this doesn't work... if users really want to run - * X in 8bpp, then we need to call directly into display.drv - * (or Wine's equivalent), and force a private colormap - * without default entries. */ - if (This->palette) { - SelectPalette(hDisplayDC, This->palette->hpal, FALSE); - RealizePalette(hDisplayDC); /* sends messages => deadlocks */ - } -#endif - drawrect.left = 0; - drawrect.right = This->surface_desc.dwWidth; - drawrect.top = 0; - drawrect.bottom = This->surface_desc.dwHeight; - - if (This->clipper) { - RECT xrc; - HWND hwnd = This->clipper->hWnd; - if (hwnd && GetClientRect(hwnd,&xrc)) { - OffsetRect(&xrc,offset.x,offset.y); - IntersectRect(&drawrect,&drawrect,&xrc); - } - } - if (rc) - IntersectRect(&drawrect,&drawrect,rc); - else { - /* Only use this if the caller did not pass a rectangle, since - * due to double locking this could be the wrong one ... */ - if (This->lastlockrect.left != This->lastlockrect.right) - IntersectRect(&drawrect,&drawrect,&This->lastlockrect); - } - BitBlt(hDisplayDC, - drawrect.left-offset.x, drawrect.top-offset.y, - drawrect.right-drawrect.left, drawrect.bottom-drawrect.top, - hSurfaceDC, - drawrect.left, drawrect.top, - SRCCOPY - ); - ReleaseDC(hDisplayWnd, hDisplayDC); - } -} - -#if 0 -static void User_copy_from_screen(IDirectDrawSurfaceImpl* This, LPCRECT rc) -{ - if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) - { - POINT offset; - HWND hDisplayWnd = get_display_window(This, &offset); - HDC hDisplayDC = GetDC(hDisplayWnd); - RECT drawrect; - - drawrect.left = 0; - drawrect.right = This->surface_desc.dwWidth; - drawrect.top = 0; - drawrect.bottom = This->surface_desc.dwHeight; - if (rc) - IntersectRect(&drawrect,&drawrect,rc); - - BitBlt(This->hDC, - drawrect.left, drawrect.top, - drawrect.right-drawrect.left, drawrect.bottom-drawrect.top, - hDisplayDC, - drawrect.left+offset.x, drawrect.top+offset.y, - SRCCOPY - ); - ReleaseDC(hDisplayWnd, hDisplayDC); - } -} -#endif - -static const IDirectDrawSurface7Vtbl User_IDirectDrawSurface7_VTable = -{ - 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 -}; diff --git a/dlls/ddraw/surface_wndproc.c b/dlls/ddraw/surface_wndproc.c deleted file mode 100644 index cc36c48d18..0000000000 --- a/dlls/ddraw/surface_wndproc.c +++ /dev/null @@ -1,104 +0,0 @@ -/* User-based primary surface driver - * - * Copyright 2000 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "config.h" - -#include -#include -#include - -#include "winerror.h" - -#include "ddraw_private.h" - -#include "wine/debug.h" - -WINE_DEFAULT_DEBUG_CHANNEL(ddraw); - -static LRESULT WINAPI DirectDrawSurface_WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); - -void DirectDrawSurface_RegisterClass(void) -{ - WNDCLASSA wc; - memset(&wc, 0, sizeof(wc)); - wc.lpfnWndProc = DirectDrawSurface_WndProc; - wc.cbWndExtra = sizeof(IDirectDrawSurfaceImpl*); - wc.hCursor = (HCURSOR)IDC_ARROW; - wc.lpszClassName = "WINE_DDRAW"; - RegisterClassA(&wc); -} - -void DirectDrawSurface_UnregisterClass(void) -{ - UnregisterClassA("WINE_DDRAW", 0); -} - -static LRESULT WINAPI DirectDrawSurface_WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - IDirectDrawSurfaceImpl *This; - LRESULT ret; - - This = (IDirectDrawSurfaceImpl *)GetWindowLongPtrA(hwnd, 0); - if (This) { - HWND window = This->ddraw_owner->window; - - switch (msg) { - case WM_DESTROY: - case WM_NCDESTROY: - case WM_SHOWWINDOW: - case WM_WINDOWPOSCHANGING: - case WM_WINDOWPOSCHANGED: - case WM_SIZE: - case WM_MOVE: - case WM_ERASEBKGND: - case WM_SYNCPAINT: - /* since we're pretending fullscreen, - * let's not pass these on to the app */ - ret = DefWindowProcA(hwnd, msg, wParam, lParam); - break; - case WM_NCHITTEST: - ret = HTCLIENT; - break; - case WM_MOUSEACTIVATE: - ret = MA_NOACTIVATE; - break; - case WM_PAINT: - { - PAINTSTRUCT ps; - HDC dc; - dc = BeginPaint(hwnd, &ps); - /* call User_copy_to_screen? */ - EndPaint(hwnd, &ps); - ret = 0; - } - break; - default: - ret = window ? SendMessageA(window, msg, wParam, lParam) - : DefWindowProcA(hwnd, msg, wParam, lParam); - } - } else { - if (msg == WM_CREATE) { - CREATESTRUCTA *cs = (CREATESTRUCTA *)lParam; - This = (IDirectDrawSurfaceImpl *)cs->lpCreateParams; - SetWindowLongPtrA(hwnd, 0, (LONG_PTR)This); - } - ret = DefWindowProcA(hwnd, msg, wParam, lParam); - } - return ret; -} diff --git a/dlls/ddraw/tests/d3d.c b/dlls/ddraw/tests/d3d.c index def3fae0b1..87f0231d63 100644 --- a/dlls/ddraw/tests/d3d.c +++ b/dlls/ddraw/tests/d3d.c @@ -320,53 +320,29 @@ static void ProcessVerticesTest() if(!out) goto out; /* Check the results */ - if( !comparefloat(out[0].x, 128.0 ) || - !comparefloat(out[0].y, 128.0 ) || - !comparefloat(out[0].z, 0.0 ) || - !comparefloat(out[0].rhw, 1.0 )) - { - todo_wine ok(FALSE, "Output 0 vertex is (%f , %f , %f , %f)\n", out[0].x, out[0].y, out[0].z, out[0].rhw); - } - else - { - todo_wine ok(TRUE, "Output 0 vertex is (%f , %f , %f , %f)\n", out[0].x, out[0].y, out[0].z, out[0].rhw); - } + ok( comparefloat(out[0].x, 128.0 ) && + comparefloat(out[0].y, 128.0 ) && + comparefloat(out[0].z, 0.0 ) && + comparefloat(out[0].rhw, 1.0 ), + "Output 0 vertex is (%f , %f , %f , %f)\n", out[0].x, out[0].y, out[0].z, out[0].rhw); - if( !comparefloat(out[1].x, 256.0 ) || - !comparefloat(out[1].y, 0.0 ) || - !comparefloat(out[1].z, 1.0 ) || - !comparefloat(out[1].rhw, 1.0 )) - { - todo_wine ok(FALSE, "Output 1 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw); - } - else - { - todo_wine ok(TRUE, "Output 1 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw); - } + ok( comparefloat(out[1].x, 256.0 ) && + comparefloat(out[1].y, 0.0 ) && + comparefloat(out[1].z, 1.0 ) && + comparefloat(out[1].rhw, 1.0 ), + "Output 1 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw); - if( !comparefloat(out[2].x, 0.0 ) || - !comparefloat(out[2].y, 256.0 ) || - !comparefloat(out[2].z, 0.5 ) || - !comparefloat(out[2].rhw, 1.0 )) - { - todo_wine ok(FALSE, "Output 2 vertex is (%f , %f , %f , %f)\n", out[2].x, out[2].y, out[2].z, out[2].rhw); - } - else - { - todo_wine ok(TRUE, "Output 2 vertex is (%f , %f , %f , %f)\n", out[2].x, out[2].y, out[2].z, out[2].rhw); - } + ok( comparefloat(out[2].x, 0.0 ) && + comparefloat(out[2].y, 256.0 ) && + comparefloat(out[2].z, 0.5 ) && + comparefloat(out[2].rhw, 1.0 ), + "Output 2 vertex is (%f , %f , %f , %f)\n", out[2].x, out[2].y, out[2].z, out[2].rhw); - if( !comparefloat(out[3].x, 192.0 ) || - !comparefloat(out[3].y, 192.0 ) || - !comparefloat(out[3].z, 0.25 ) || - !comparefloat(out[3].rhw, 1.0 )) - { - todo_wine ok(FALSE, "Output 3 vertex is (%f , %f , %f , %f)\n", out[3].x, out[3].y, out[3].z, out[3].rhw); - } - else - { - todo_wine ok(TRUE, "Output 3 vertex is (%f , %f , %f , %f)\n", out[3].x, out[3].y, out[3].z, out[3].rhw); - } + ok( comparefloat(out[3].x, 192.0 ) && + comparefloat(out[3].y, 192.0 ) && + comparefloat(out[3].z, 0.25 ) && + comparefloat(out[3].rhw, 1.0 ), + "Output 3 vertex is (%f , %f , %f , %f)\n", out[3].x, out[3].y, out[3].z, out[3].rhw); rc = IDirect3DVertexBuffer7_Unlock(lpVBufDest1); ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %lx\n", rc); @@ -379,16 +355,10 @@ static void ProcessVerticesTest() * so let's check for it: If the output vertex buffer has to RHW value, * The RHW value of the last vertex is written into the next vertex */ - if( !comparefloat(out2[4].x, 1.0 ) || - !comparefloat(out2[4].y, 0.0 ) || - !comparefloat(out2[4].z, 0.0 ) ) - { - todo_wine ok(FALSE, "Output 4 vertex is (%f , %f , %f)\n", out2[4].x, out2[4].y, out2[4].z); - } - else - { - todo_wine ok(TRUE, "Output 4 vertex is (%f , %f , %f)\n", out2[4].x, out2[4].y, out2[4].z); - } + ok( comparefloat(out2[4].x, 1.0 ) && + comparefloat(out2[4].y, 0.0 ) && + comparefloat(out2[4].z, 0.0 ), + "Output 4 vertex is (%f , %f , %f)\n", out2[4].x, out2[4].y, out2[4].z); rc = IDirect3DVertexBuffer7_Unlock(lpVBufDest2); ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %lx\n", rc); @@ -414,53 +384,29 @@ static void ProcessVerticesTest() if(!out) goto out; /* Check the results */ - if( !comparefloat(out[0].x, 133.0 ) || - !comparefloat(out[0].y, 70.0 ) || - !comparefloat(out[0].z, -2.0 ) || - !comparefloat(out[0].rhw, 1.0 )) - { - todo_wine ok(FALSE, "Output 0 vertex is (%f , %f , %f , %f)\n", out[0].x, out[0].y, out[0].z, out[0].rhw); - } - else - { - todo_wine ok(TRUE, "Output 0 vertex is (%f , %f , %f , %f)\n", out[0].x, out[0].y, out[0].z, out[0].rhw); - } + ok( comparefloat(out[0].x, 133.0 ) && + comparefloat(out[0].y, 70.0 ) && + comparefloat(out[0].z, -2.0 ) && + comparefloat(out[0].rhw, 1.0 ), + "Output 0 vertex is (%f , %f , %f , %f)\n", out[0].x, out[0].y, out[0].z, out[0].rhw); - if( !comparefloat(out[1].x, 256.0 ) || - !comparefloat(out[1].y, 5.0 ) || - !comparefloat(out[1].z, 4.0 ) || - !comparefloat(out[1].rhw, 1.0 )) - { - todo_wine ok(FALSE, "Output 1 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw); - } - else - { - todo_wine ok(TRUE, "Output 1 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw); - } + ok( comparefloat(out[1].x, 256.0 ) && + comparefloat(out[1].y, 5.0 ) && + comparefloat(out[1].z, 4.0 ) && + comparefloat(out[1].rhw, 1.0 ), + "Output 1 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw); - if( !comparefloat(out[2].x, 10.0 ) || - !comparefloat(out[2].y, 135.0 ) || - !comparefloat(out[2].z, 1.0 ) || - !comparefloat(out[2].rhw, 1.0 )) - { - todo_wine ok(FALSE, "Output 2 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw); - } - else - { - todo_wine ok(TRUE, "Output 2 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw); - } + ok( comparefloat(out[2].x, 10.0 ) && + comparefloat(out[2].y, 135.0 ) && + comparefloat(out[2].z, 1.0 ) && + comparefloat(out[2].rhw, 1.0 ), + "Output 2 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw); - if( !comparefloat(out[3].x, 194.5 ) || - !comparefloat(out[3].y, 102.5 ) || - !comparefloat(out[3].z, -0.5 ) || - !comparefloat(out[3].rhw, 1.0 )) - { - todo_wine ok(FALSE, "Output 3 vertex is (%f , %f , %f , %f)\n", out[3].x, out[3].y, out[3].z, out[3].rhw); - } - else - { - todo_wine ok(TRUE, "Output 3 vertex is (%f , %f , %f , %f)\n", out[3].x, out[3].y, out[3].z, out[3].rhw); - } + ok( comparefloat(out[3].x, 194.5 ) && + comparefloat(out[3].y, 102.5 ) && + comparefloat(out[3].z, -0.5 ) && + comparefloat(out[3].rhw, 1.0 ), + "Output 3 vertex is (%f , %f , %f , %f)\n", out[3].x, out[3].y, out[3].z, out[3].rhw); rc = IDirect3DVertexBuffer7_Unlock(lpVBufDest1); ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %lx\n", rc); @@ -495,53 +441,29 @@ static void ProcessVerticesTest() ok(rc==D3D_OK, "IDirect3DDevice7_SetViewport failed\n"); /* Check the results */ - if( !comparefloat(out[0].x, 256.0 ) || /* X coordinate is cut at the surface edges */ - !comparefloat(out[0].y, 70.0 ) || - !comparefloat(out[0].z, -2.0 ) || - !comparefloat(out[0].rhw, (1.0 / 3.0))) - { - todo_wine ok(FALSE, "Output 0 vertex is (%f , %f , %f , %f)\n", out[0].x, out[0].y, out[0].z, out[0].rhw); - } - else - { - todo_wine ok(TRUE, "Output 0 vertex is (%f , %f , %f , %f)\n", out[0].x, out[0].y, out[0].z, out[0].rhw); - } + ok( comparefloat(out[0].x, 256.0 ) && /* X coordinate is cut at the surface edges */ + comparefloat(out[0].y, 70.0 ) && + comparefloat(out[0].z, -2.0 ) && + comparefloat(out[0].rhw, (1.0 / 3.0)), + "Output 0 vertex is (%f , %f , %f , %f)\n", out[0].x, out[0].y, out[0].z, out[0].rhw); - if( !comparefloat(out[1].x, 256.0 ) || - !comparefloat(out[1].y, 78.125000 ) || - !comparefloat(out[1].z, -2.750000 ) || - !comparefloat(out[1].rhw, 0.125000 )) - { - todo_wine ok(FALSE, "Output 1 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw); - } - else - { - todo_wine ok(TRUE, "Output 1 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw); - } + ok( comparefloat(out[1].x, 256.0 ) && + comparefloat(out[1].y, 78.125000 ) && + comparefloat(out[1].z, -2.750000 ) && + comparefloat(out[1].rhw, 0.125000 ), + "Output 1 vertex is (%f , %f , %f , %f)\n", out[1].x, out[1].y, out[1].z, out[1].rhw); - if( !comparefloat(out[2].x, 256.0 ) || - !comparefloat(out[2].y, 44.000000 ) || - !comparefloat(out[2].z, 0.400000 ) || - !comparefloat(out[2].rhw, 0.400000 )) - { - todo_wine ok(FALSE, "Output 2 vertex is (%f , %f , %f , %f)\n", out[2].x, out[2].y, out[2].z, out[2].rhw); - } - else - { - todo_wine ok(TRUE, "Output 2 vertex is (%f , %f , %f , %f)\n", out[2].x, out[2].y, out[2].z, out[2].rhw); - } + ok( comparefloat(out[2].x, 256.0 ) && + comparefloat(out[2].y, 44.000000 ) && + comparefloat(out[2].z, 0.400000 ) && + comparefloat(out[2].rhw, 0.400000 ), + "Output 2 vertex is (%f , %f , %f , %f)\n", out[2].x, out[2].y, out[2].z, out[2].rhw); - if( !comparefloat(out[3].x, 256.0 ) || - !comparefloat(out[3].y, 81.818184 ) || - !comparefloat(out[3].z, -3.090909 ) || - !comparefloat(out[3].rhw, 0.363636 )) - { - todo_wine ok(FALSE, "Output 3 vertex is (%f , %f , %f , %f)\n", out[3].x, out[3].y, out[3].z, out[3].rhw); - } - else - { - todo_wine ok(TRUE, "Output 3 vertex is (%f , %f , %f , %f)\n", out[3].x, out[3].y, out[3].z, out[3].rhw); - } + ok( comparefloat(out[3].x, 256.0 ) && + comparefloat(out[3].y, 81.818184 ) && + comparefloat(out[3].z, -3.090909 ) && + comparefloat(out[3].rhw, 0.363636 ), + "Output 3 vertex is (%f , %f , %f , %f)\n", out[3].x, out[3].y, out[3].z, out[3].rhw); rc = IDirect3DVertexBuffer7_Unlock(lpVBufDest1); ok(rc==D3D_OK , "IDirect3DVertexBuffer::Unlock returned: %lx\n", rc); diff --git a/dlls/ddraw/texture.c b/dlls/ddraw/texture.c index 66c07f3664..07b5edb376 100644 --- a/dlls/ddraw/texture.c +++ b/dlls/ddraw/texture.c @@ -1,5 +1,6 @@ /* Direct3D Texture * Copyright (c) 1998 Lionel ULMER + * Copyright (c) 2006 Stefan DÖSINGER * * This file contains the implementation of interface Direct3DTexture2. * @@ -21,42 +22,238 @@ #include "config.h" #include "wine/port.h" +#include #include #include +#include +#define COBJMACROS #define NONAMELESSUNION -#define NONAMELESSSTRUCT #include "windef.h" #include "winbase.h" +#include "winnls.h" #include "winerror.h" -#include "objbase.h" #include "wingdi.h" +#include "wine/exception.h" +#include "excpt.h" + #include "ddraw.h" #include "d3d.h" + +#include "ddraw_private.h" #include "wine/debug.h" -#include "opengl_private.h" +WINE_DEFAULT_DEBUG_CHANNEL(d3d7); -WINE_DEFAULT_DEBUG_CHANNEL(ddraw); -WINE_DECLARE_DEBUG_CHANNEL(ddraw_tex); - -#include - -static void -snoop_texture(IDirectDrawSurfaceImpl *This) { - IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private; - char buf[128]; - FILE *f; - - TRACE_(ddraw_tex)("Dumping surface id (%5d) level (%2d) : \n", glThis->tex_name, This->mipmap_level); - DDRAW_dump_surface_desc(&(This->surface_desc)); - - sprintf(buf, "tex_%05d_%02d.pnm", glThis->tex_name, This->mipmap_level); - f = fopen(buf, "wb"); - DDRAW_dump_surface_to_disk(This, f, 1); +/***************************************************************************** + * IUnknown interfaces. They are thunks to IDirectDrawSurface7 + *****************************************************************************/ +static HRESULT WINAPI +Thunk_IDirect3DTextureImpl_2_QueryInterface(IDirect3DTexture2 *iface, + REFIID riid, + void **obj) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture2, iface); + TRACE("(%p)->(%s,%p) thunking to IDirectDrawSurface7 interface.\n", This, debugstr_guid(riid), obj); + return IDirectDrawSurface7_QueryInterface(ICOM_INTERFACE(This, IDirectDrawSurface7), + riid, + obj); } +static HRESULT WINAPI +Thunk_IDirect3DTextureImpl_1_QueryInterface(IDirect3DTexture *iface, + REFIID riid, + void **obj) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture, iface); + TRACE("(%p)->(%s,%p) thunking to IDirectDrawSurface7 interface.\n", This, debugstr_guid(riid), obj); + + return IDirectDrawSurface7_QueryInterface(ICOM_INTERFACE(This, IDirectDrawSurface7), + riid, + obj); +} + +static ULONG WINAPI +Thunk_IDirect3DTextureImpl_2_AddRef(IDirect3DTexture2 *iface) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture2, iface); + TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", This); + + return IDirectDrawSurface7_AddRef(ICOM_INTERFACE(This, IDirectDrawSurface7)); +} + +static ULONG WINAPI +Thunk_IDirect3DTextureImpl_1_AddRef(IDirect3DTexture *iface) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture, iface); + TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", This); + + return IDirectDrawSurface7_AddRef(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirectDrawSurface7, iface)); +} + +static ULONG WINAPI +Thunk_IDirect3DTextureImpl_2_Release(IDirect3DTexture2 *iface) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture2, iface); + TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", This); + + return IDirectDrawSurface7_Release(ICOM_INTERFACE(This, IDirectDrawSurface7)); +} + + +static ULONG WINAPI +Thunk_IDirect3DTextureImpl_1_Release(IDirect3DTexture *iface) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture, iface); + TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", This); + + return IDirectDrawSurface7_Release(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirectDrawSurface7, iface)); +} + +/***************************************************************************** + * IDirect3DTexture interface + *****************************************************************************/ + +/***************************************************************************** + * IDirect3DTexture1::Initialize + * + * The sdk says it's not implemented + * + * Params: + * ? + * + * Returns + * DDERR_UNSUPPORTED + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DTextureImpl_1_Initialize(IDirect3DTexture *iface, + IDirect3DDevice *Direct3DDevice, + IDirectDrawSurface *DDSurface) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture, iface); + IDirect3DDeviceImpl *d3d = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice, Direct3DDevice); + IDirectDrawSurfaceImpl *surf = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface3, DDSurface); + TRACE("(%p)->(%p,%p) Not implemented\n", This, d3d, surf); + return DDERR_UNSUPPORTED; /* Unchecked */ +} + +/***************************************************************************** + * IDirect3DTexture2::PaletteChanged + * + * Informs the texture about a palette change + * + * Params: + * Start: Start index of the change + * Count: The number of changed entries + * + * Returns + * D3D_OK, because it's a stub + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DTextureImpl_PaletteChanged(IDirect3DTexture2 *iface, + DWORD Start, + DWORD Count) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture2, iface); + FIXME("(%p)->(%08lx,%08lx): stub!\n", This, Start, Count); + return D3D_OK; +} + +static HRESULT WINAPI +Thunk_IDirect3DTextureImpl_1_PaletteChanged(IDirect3DTexture *iface, + DWORD Start, + DWORD Count) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture, iface); + TRACE("(%p)->(%08lx,%08lx) thunking to IDirect3DTexture2 interface.\n", This, Start, Count); + + return IDirect3DTexture2_PaletteChanged(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirect3DTexture2, iface), + Start, + Count); +} + + +/***************************************************************************** + * IDirect3DTexture::Unload + * + * DX5 SDK: "The IDirect3DTexture2::Unload method is not implemented + * + * + * Returns: + * DDERR_UNSUPPORTED + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DTextureImpl_1_Unload(IDirect3DTexture *iface) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture, iface); + TRACE("(%p)->(): not implemented!\n", This); + return DDERR_UNSUPPORTED; +} + +/***************************************************************************** + * IDirect3DTexture2::GetHandle + * + * Returns handle for the texture. At the moment, the interface + * to the IWineD3DTexture is used. + * + * Params: + * Direct3DDevice2: Device this handle is assigned to + * Handle: Address to store the handle at. + * + * Returns: + * D3D_OK + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DTextureImpl_GetHandle(IDirect3DTexture2 *iface, + IDirect3DDevice2 *Direct3DDevice2, + D3DTEXTUREHANDLE *lpHandle) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture2, iface); + IDirect3DDeviceImpl *d3d = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice2, Direct3DDevice2); + + TRACE("(%p)->(%p,%p)\n", This, d3d, lpHandle); + + /* The handle is the WineD3DTexture interface. SetRenderState depends on this */ + if(This->ddraw->wineD3DDevice) + *lpHandle = (D3DTEXTUREHANDLE) This->wineD3DTexture; + else + { + /* This is to fool applications which create a texture without a D3DDevice */ + *lpHandle = (D3DTEXTUREHANDLE) This; + } + + TRACE(" returning handle %08lx.\n", *lpHandle); + + return D3D_OK; +} + +static HRESULT WINAPI +Thunk_IDirect3DTextureImpl_1_GetHandle(IDirect3DTexture *iface, + LPDIRECT3DDEVICE lpDirect3DDevice, + LPD3DTEXTUREHANDLE lpHandle) +{ + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture, iface); + TRACE("(%p)->(%p,%p) thunking to IDirect3DTexture2 interface.\n", This, lpDirect3DDevice, lpHandle); + + return IDirect3DTexture2_GetHandle(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirect3DTexture2, iface), + COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice2, lpDirect3DDevice), + lpHandle); +} + + +/***************************************************************************** + * get_sub_mimaplevel + * + * Helper function that returns the next mipmap level + * + * tex_ptr: Surface of which to return the next level + * + *****************************************************************************/ static IDirectDrawSurfaceImpl * get_sub_mimaplevel(IDirectDrawSurfaceImpl *tex_ptr) { @@ -65,873 +262,245 @@ get_sub_mimaplevel(IDirectDrawSurfaceImpl *tex_ptr) LPDIRECTDRAWSURFACE7 next_level; IDirectDrawSurfaceImpl *surf_ptr; HRESULT hr; - + hr = IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(tex_ptr, IDirectDrawSurface7), - (DDSCAPS2 *) &mipmap_caps, &next_level); + (DDSCAPS2 *) &mipmap_caps, &next_level); if (FAILED(hr)) return NULL; - + surf_ptr = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, next_level); IDirectDrawSurface7_Release(next_level); - + return surf_ptr; } -/******************************************************************************* - * IDirectSurface callback methods - */ - -HRESULT -gltex_download_texture(IDirectDrawSurfaceImpl *surf_ptr) { - IDirect3DTextureGLImpl *gl_surf_ptr = (IDirect3DTextureGLImpl *) surf_ptr->tex_private; - - FIXME("This is not supported yet... Expect some graphical glitches !!!\n"); - - /* GL and memory are in sync again ... - No need to change the 'global' flag as it only handles the 'MEMORY_DIRTY' case. - */ - gl_surf_ptr->dirty_flag = SURFACE_MEMORY; - - return DD_OK; -} - -static GLenum -convert_min_filter_to_GL(D3DTEXTUREMINFILTER dwMinState, D3DTEXTUREMIPFILTER dwMipState) -{ - GLenum gl_state; - - if (dwMipState == D3DTFP_NONE) { - switch (dwMinState) { - case D3DTFN_POINT: gl_state = GL_NEAREST; break; - case D3DTFN_LINEAR: gl_state = GL_LINEAR; break; - default: gl_state = GL_LINEAR; break; - } - } else if (dwMipState == D3DTFP_POINT) { - switch (dwMinState) { - case D3DTFN_POINT: gl_state = GL_NEAREST_MIPMAP_NEAREST; break; - case D3DTFN_LINEAR: gl_state = GL_LINEAR_MIPMAP_NEAREST; break; - default: gl_state = GL_LINEAR_MIPMAP_NEAREST; break; - } - } else { - switch (dwMinState) { - case D3DTFN_POINT: gl_state = GL_NEAREST_MIPMAP_LINEAR; break; - case D3DTFN_LINEAR: gl_state = GL_LINEAR_MIPMAP_LINEAR; break; - default: gl_state = GL_LINEAR_MIPMAP_LINEAR; break; - } - } - return gl_state; -} - -static GLenum -convert_mag_filter_to_GL(D3DTEXTUREMAGFILTER dwState) -{ - GLenum gl_state; - - switch (dwState) { - case D3DTFG_POINT: - gl_state = GL_NEAREST; - break; - case D3DTFG_LINEAR: - gl_state = GL_LINEAR; - break; - default: - gl_state = GL_LINEAR; - break; - } - return gl_state; -} - -static GLenum -convert_tex_address_to_GL(D3DTEXTUREADDRESS dwState) -{ - GLenum gl_state; - switch (dwState) { - case D3DTADDRESS_WRAP: gl_state = GL_REPEAT; break; - case D3DTADDRESS_CLAMP: gl_state = GL_CLAMP; break; - case D3DTADDRESS_BORDER: gl_state = GL_CLAMP_TO_EDGE; break; - case D3DTADDRESS_MIRROR: - if (GL_extensions.mirrored_repeat) { - gl_state = GL_MIRRORED_REPEAT_WINE; - } else { - gl_state = GL_REPEAT; - /* This is a TRACE instead of a FIXME as the FIXME was already printed when the game - actually set D3DTADDRESS_MIRROR. - */ - TRACE(" setting GL_REPEAT instead of GL_MIRRORED_REPEAT.\n"); - } - break; - default: gl_state = GL_REPEAT; break; - } - return gl_state; -} - -HRESULT -gltex_upload_texture(IDirectDrawSurfaceImpl *surf_ptr, IDirect3DDeviceImpl *d3ddev, DWORD stage) { - IDirect3DTextureGLImpl *gl_surf_ptr = (IDirect3DTextureGLImpl *) surf_ptr->tex_private; - IDirect3DDeviceGLImpl *gl_d3ddev = (IDirect3DDeviceGLImpl *) d3ddev; - BOOLEAN changed = FALSE; - GLenum unit = GL_TEXTURE0_WINE + stage; - - if (surf_ptr->mipmap_level != 0) { - WARN(" application activating a sub-level of the mipmapping chain (level %d) !\n", surf_ptr->mipmap_level); - } - - /* Now check if the texture parameters for this texture are still in-line with what D3D expect - us to do.. - - NOTE: there is no check for the situation where the same texture is bound to multiple stage - but with different parameters per stage. - */ - if ((gl_surf_ptr->tex_parameters == NULL) || - (gl_surf_ptr->tex_parameters[D3DTSS_MAXMIPLEVEL - D3DTSS_ADDRESSU] != - d3ddev->state_block.texture_stage_state[stage][D3DTSS_MAXMIPLEVEL - 1])) { - DWORD max_mip_level; - - if ((surf_ptr->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) == 0) { - max_mip_level = 0; - } else { - max_mip_level = surf_ptr->surface_desc.u2.dwMipMapCount - 1; - if (d3ddev->state_block.texture_stage_state[stage][D3DTSS_MAXMIPLEVEL - 1] != 0) { - if (max_mip_level >= d3ddev->state_block.texture_stage_state[stage][D3DTSS_MAXMIPLEVEL - 1]) { - max_mip_level = d3ddev->state_block.texture_stage_state[stage][D3DTSS_MAXMIPLEVEL - 1] - 1; - } - } - } - if (unit != gl_d3ddev->current_active_tex_unit) { - GL_extensions.glActiveTexture(unit); - gl_d3ddev->current_active_tex_unit = unit; - } - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, max_mip_level); - changed = TRUE; - } - - if ((gl_surf_ptr->tex_parameters == NULL) || - (gl_surf_ptr->tex_parameters[D3DTSS_MAGFILTER - D3DTSS_ADDRESSU] != - d3ddev->state_block.texture_stage_state[stage][D3DTSS_MAGFILTER - 1])) { - if (unit != gl_d3ddev->current_active_tex_unit) { - GL_extensions.glActiveTexture(unit); - gl_d3ddev->current_active_tex_unit = unit; - } - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, - convert_mag_filter_to_GL(d3ddev->state_block.texture_stage_state[stage][D3DTSS_MAGFILTER - 1])); - changed = TRUE; - } - if ((gl_surf_ptr->tex_parameters == NULL) || - (gl_surf_ptr->tex_parameters[D3DTSS_MINFILTER - D3DTSS_ADDRESSU] != - d3ddev->state_block.texture_stage_state[stage][D3DTSS_MINFILTER - 1]) || - (gl_surf_ptr->tex_parameters[D3DTSS_MIPFILTER - D3DTSS_ADDRESSU] != - d3ddev->state_block.texture_stage_state[stage][D3DTSS_MIPFILTER - 1])) { - if (unit != gl_d3ddev->current_active_tex_unit) { - GL_extensions.glActiveTexture(unit); - gl_d3ddev->current_active_tex_unit = unit; - } - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, - convert_min_filter_to_GL(d3ddev->state_block.texture_stage_state[stage][D3DTSS_MINFILTER - 1], - d3ddev->state_block.texture_stage_state[stage][D3DTSS_MIPFILTER - 1])); - changed = TRUE; - } - if ((gl_surf_ptr->tex_parameters == NULL) || - (gl_surf_ptr->tex_parameters[D3DTSS_ADDRESSU - D3DTSS_ADDRESSU] != - d3ddev->state_block.texture_stage_state[stage][D3DTSS_ADDRESSU - 1])) { - if (unit != gl_d3ddev->current_active_tex_unit) { - GL_extensions.glActiveTexture(unit); - gl_d3ddev->current_active_tex_unit = unit; - } - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, - convert_tex_address_to_GL(d3ddev->state_block.texture_stage_state[stage][D3DTSS_ADDRESSU - 1])); - changed = TRUE; - } - if ((gl_surf_ptr->tex_parameters == NULL) || - (gl_surf_ptr->tex_parameters[D3DTSS_ADDRESSV - D3DTSS_ADDRESSU] != - d3ddev->state_block.texture_stage_state[stage][D3DTSS_ADDRESSV - 1])) { - if (unit != gl_d3ddev->current_active_tex_unit) { - GL_extensions.glActiveTexture(unit); - gl_d3ddev->current_active_tex_unit = unit; - } - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, - convert_tex_address_to_GL(d3ddev->state_block.texture_stage_state[stage][D3DTSS_ADDRESSV - 1])); - changed = TRUE; - } - if ((gl_surf_ptr->tex_parameters == NULL) || - (gl_surf_ptr->tex_parameters[D3DTSS_BORDERCOLOR - D3DTSS_ADDRESSU] != - d3ddev->state_block.texture_stage_state[stage][D3DTSS_BORDERCOLOR - 1])) { - GLfloat color[4]; - - color[0] = ((d3ddev->state_block.texture_stage_state[stage][D3DTSS_BORDERCOLOR - 1] >> 16) & 0xFF) / 255.0; - color[1] = ((d3ddev->state_block.texture_stage_state[stage][D3DTSS_BORDERCOLOR - 1] >> 8) & 0xFF) / 255.0; - color[2] = ((d3ddev->state_block.texture_stage_state[stage][D3DTSS_BORDERCOLOR - 1] >> 0) & 0xFF) / 255.0; - color[3] = ((d3ddev->state_block.texture_stage_state[stage][D3DTSS_BORDERCOLOR - 1] >> 24) & 0xFF) / 255.0; - if (unit != gl_d3ddev->current_active_tex_unit) { - GL_extensions.glActiveTexture(unit); - gl_d3ddev->current_active_tex_unit = unit; - } - glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, color); - changed = TRUE; - } - - if (changed) { - if (gl_surf_ptr->tex_parameters == NULL) { - gl_surf_ptr->tex_parameters = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof(DWORD) * (D3DTSS_MAXMIPLEVEL + 1 - D3DTSS_ADDRESSU)); - } - memcpy(gl_surf_ptr->tex_parameters, &(d3ddev->state_block.texture_stage_state[stage][D3DTSS_ADDRESSU - 1]), - sizeof(DWORD) * (D3DTSS_MAXMIPLEVEL + 1 - D3DTSS_ADDRESSU)); - } - - if (*(gl_surf_ptr->global_dirty_flag) != SURFACE_MEMORY_DIRTY) { - TRACE(" nothing to do - memory copy and GL state in synch for all texture levels.\n"); - return DD_OK; - } - - while (surf_ptr != NULL) { - IDirect3DTextureGLImpl *gl_surf_ptr = (IDirect3DTextureGLImpl *) surf_ptr->tex_private; - - if (gl_surf_ptr->dirty_flag != SURFACE_MEMORY_DIRTY) { - TRACE(" - level %d already uploaded.\n", surf_ptr->mipmap_level); - } else { - TRACE(" - uploading texture level %d (initial done = %d).\n", - surf_ptr->mipmap_level, gl_surf_ptr->initial_upload_done); - - /* Texture snooping for the curious :-) */ - if (TRACE_ON(ddraw_tex)) { - snoop_texture(surf_ptr); - } - - if (unit != gl_d3ddev->current_active_tex_unit) { - GL_extensions.glActiveTexture(unit); - gl_d3ddev->current_active_tex_unit = unit; - } - - if (upload_surface_to_tex_memory_init(surf_ptr, surf_ptr->mipmap_level, &(gl_surf_ptr->current_internal_format), - gl_surf_ptr->initial_upload_done == FALSE, TRUE, 0, 0) == DD_OK) { - upload_surface_to_tex_memory(NULL, 0, 0, &(gl_surf_ptr->surface_ptr)); - upload_surface_to_tex_memory_release(); - gl_surf_ptr->dirty_flag = SURFACE_MEMORY; - gl_surf_ptr->initial_upload_done = TRUE; - } else { - ERR("Problem for upload of texture %d (level = %d / initial done = %d).\n", - gl_surf_ptr->tex_name, surf_ptr->mipmap_level, gl_surf_ptr->initial_upload_done); - } - } - - if (surf_ptr->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) { - surf_ptr = get_sub_mimaplevel(surf_ptr); - } else { - surf_ptr = NULL; - } - } - - *(gl_surf_ptr->global_dirty_flag) = SURFACE_MEMORY; - - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DTextureImpl_1_Initialize(LPDIRECT3DTEXTURE iface, - LPDIRECT3DDEVICE lpDirect3DDevice, - LPDIRECTDRAWSURFACE lpDDSurface) -{ - ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture, iface); - FIXME("(%p/%p)->(%p,%p) no-op...\n", This, iface, lpDirect3DDevice, lpDDSurface); - return DD_OK; -} - -static HRESULT -gltex_setcolorkey_cb(IDirectDrawSurfaceImpl *This, DWORD dwFlags, LPDDCOLORKEY ckey ) -{ - IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private; - - if (glThis->dirty_flag == SURFACE_GL) { - GLint cur_tex; - - TRACE(" flushing GL texture back to memory.\n"); - - ENTER_GL(); - glGetIntegerv(GL_TEXTURE_BINDING_2D, &cur_tex); - glBindTexture(GL_TEXTURE_2D, glThis->tex_name); - gltex_download_texture(This); - glBindTexture(GL_TEXTURE_2D, cur_tex); - LEAVE_GL(); - } - - glThis->dirty_flag = SURFACE_MEMORY_DIRTY; - *(glThis->global_dirty_flag) = SURFACE_MEMORY_DIRTY; - /* TODO: check color-keying on mipmapped surfaces... */ - - return DD_OK; -} - -HRESULT -gltex_blt(IDirectDrawSurfaceImpl *This, LPRECT rdst, - LPDIRECTDRAWSURFACE7 src, LPRECT rsrc, - DWORD dwFlags, LPDDBLTFX lpbltfx) -{ - if (src != NULL) { - IDirectDrawSurfaceImpl *src_ptr = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, src); - if (src_ptr->surface_desc.ddsCaps.dwCaps & DDSCAPS_3DDEVICE) { - FIXME("Blt from framebuffer to texture - unsupported now, please report !\n"); - } - } - return DDERR_INVALIDPARAMS; -} - -HRESULT -gltex_bltfast(IDirectDrawSurfaceImpl *surf_ptr, DWORD dstx, - DWORD dsty, LPDIRECTDRAWSURFACE7 src, - LPRECT rsrc, DWORD trans) -{ - if (src != NULL) { - IDirectDrawSurfaceImpl *src_ptr = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, src); - - if ((src_ptr->surface_desc.ddsCaps.dwCaps & DDSCAPS_3DDEVICE) && - ((trans & (DDBLTFAST_SRCCOLORKEY | DDBLTFAST_DESTCOLORKEY)) == 0)) { - /* This is a blt without color keying... We can use the direct copy. */ - RECT rsrc2; - DWORD width, height; - GLint cur_tex; - IDirect3DTextureGLImpl *gl_surf_ptr = surf_ptr->tex_private; - int y; - - if (rsrc == NULL) { - WARN("rsrc is NULL\n"); - rsrc = &rsrc2; - - rsrc->left = 0; - rsrc->top = 0; - rsrc->right = src_ptr->surface_desc.dwWidth; - rsrc->bottom = src_ptr->surface_desc.dwHeight; - } - - width = rsrc->right - rsrc->left; - height = rsrc->bottom - rsrc->top; - - if (((dstx + width) > surf_ptr->surface_desc.dwWidth) || - ((dsty + height) > surf_ptr->surface_desc.dwHeight)) { - FIXME("Does not handle clipping yet in FB => Texture blits !\n"); - return DDERR_INVALIDPARAMS; - } - - if ((width == 0) || (height == 0)) { - return DD_OK; - } - - TRACE(" direct frame buffer => texture BltFast override.\n"); - - ENTER_GL(); - - glGetIntegerv(GL_TEXTURE_BINDING_2D, &cur_tex); - /* This call is to create the actual texture name in GL (as we do 'late' ID creation) */ - gltex_get_tex_name(surf_ptr); - glBindTexture(GL_TEXTURE_2D, gl_surf_ptr->tex_name); - - if ((gl_surf_ptr->dirty_flag == SURFACE_MEMORY_DIRTY) && - !((dstx == 0) && (dsty == 0) && - (width == surf_ptr->surface_desc.dwWidth) && (height == surf_ptr->surface_desc.dwHeight))) { - /* If not 'full size' and the surface is dirty, first flush it to GL before doing the copy. */ - if (upload_surface_to_tex_memory_init(surf_ptr, surf_ptr->mipmap_level, &(gl_surf_ptr->current_internal_format), - gl_surf_ptr->initial_upload_done == FALSE, TRUE, 0, 0) == DD_OK) { - upload_surface_to_tex_memory(NULL, 0, 0, &(gl_surf_ptr->surface_ptr)); - upload_surface_to_tex_memory_release(); - gl_surf_ptr->dirty_flag = SURFACE_MEMORY; - gl_surf_ptr->initial_upload_done = TRUE; - } else { - glBindTexture(GL_TEXTURE_2D, cur_tex); - LEAVE_GL(); - ERR("Error at texture upload !\n"); - return DDERR_INVALIDPARAMS; - } - } - - /* This is a hack and would need some clean-up :-) */ - if (gl_surf_ptr->initial_upload_done == FALSE) { - if (upload_surface_to_tex_memory_init(surf_ptr, surf_ptr->mipmap_level, &(gl_surf_ptr->current_internal_format), - TRUE, TRUE, 0, 0) == DD_OK) { - upload_surface_to_tex_memory(NULL, 0, 0, &(gl_surf_ptr->surface_ptr)); - upload_surface_to_tex_memory_release(); - gl_surf_ptr->dirty_flag = SURFACE_MEMORY; - gl_surf_ptr->initial_upload_done = TRUE; - } else { - glBindTexture(GL_TEXTURE_2D, cur_tex); - LEAVE_GL(); - ERR("Error at texture upload (initial case) !\n"); - return DDERR_INVALIDPARAMS; - } - } - - if ((src_ptr->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER|DDSCAPS_PRIMARYSURFACE)) != 0) - glReadBuffer(GL_FRONT); - else if ((src_ptr->surface_desc.ddsCaps.dwCaps & (DDSCAPS_BACKBUFFER)) == (DDSCAPS_BACKBUFFER)) - glReadBuffer(GL_BACK); - else { - ERR("Wrong surface type for locking !\n"); - glBindTexture(GL_TEXTURE_2D, cur_tex); - LEAVE_GL(); - return DDERR_INVALIDPARAMS; - } - - for (y = (src_ptr->surface_desc.dwHeight - rsrc->top - 1); - y >= (src_ptr->surface_desc.dwHeight - (rsrc->top + height)); - y--) { - glCopyTexSubImage2D(GL_TEXTURE_2D, surf_ptr->mipmap_level, - dstx, dsty, - rsrc->left, y, - width, 1); - dsty++; - } - - glBindTexture(GL_TEXTURE_2D, cur_tex); - LEAVE_GL(); - - /* The SURFACE_GL case is not handled by the 'global' dirty flag */ - gl_surf_ptr->dirty_flag = SURFACE_GL; - - return DD_OK; - } - } - return DDERR_INVALIDPARAMS; -} - -HRESULT WINAPI -Main_IDirect3DTextureImpl_2_1T_PaletteChanged(LPDIRECT3DTEXTURE2 iface, - DWORD dwStart, - DWORD dwCount) +/***************************************************************************** + * IDirect3DTexture2::Load + * + * Loads a texture created with the DDSCAPS_ALLOCONLOAD + * + * This function isn't relayed to WineD3D because the whole interface is + * implemented in DDraw only. For speed improvements a implementation which + * takes OpenGL more into account could be placed into WineD3D. + * + * Params: + * D3DTexture2: Address of the texture to load + * + * Returns: + * D3D_OK on success + * D3DERR_TEXTURE_LOAD_FAILED. + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DTextureImpl_Load(IDirect3DTexture2 *iface, + IDirect3DTexture2 *D3DTexture2) { ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture2, iface); - FIXME("(%p/%p)->(%08lx,%08lx): stub!\n", This, iface, dwStart, dwCount); - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DTextureImpl_1_Unload(LPDIRECT3DTEXTURE iface) -{ - ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture, iface); - FIXME("(%p/%p)->(): stub!\n", This, iface); - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DTextureImpl_2_1T_GetHandle(LPDIRECT3DTEXTURE2 iface, - LPDIRECT3DDEVICE2 lpDirect3DDevice2, - LPD3DTEXTUREHANDLE lpHandle) -{ - ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture2, iface); - IDirect3DDeviceImpl *lpDeviceImpl = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice2, lpDirect3DDevice2); - - TRACE("(%p/%p)->(%p,%p)\n", This, iface, lpDirect3DDevice2, lpHandle); - - /* The handle is simply the pointer to the implementation structure */ - *lpHandle = (D3DTEXTUREHANDLE) This; - - TRACE(" returning handle %08lx.\n", *lpHandle); - - /* Now set the device for this texture */ - This->d3ddevice = lpDeviceImpl; - - return D3D_OK; -} - -HRESULT WINAPI -Main_IDirect3DTextureImpl_2_1T_Load(LPDIRECT3DTEXTURE2 iface, - LPDIRECT3DTEXTURE2 lpD3DTexture2) -{ - ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture2, iface); - FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpD3DTexture2); - return DD_OK; -} - -static void gltex_set_palette(IDirectDrawSurfaceImpl* This, IDirectDrawPaletteImpl* pal) -{ - IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private; - - if (glThis->dirty_flag == SURFACE_GL) { - GLint cur_tex; - - TRACE(" flushing GL texture back to memory.\n"); - - ENTER_GL(); - glGetIntegerv(GL_TEXTURE_BINDING_2D, &cur_tex); - glBindTexture(GL_TEXTURE_2D, glThis->tex_name); - gltex_download_texture(This); - glBindTexture(GL_TEXTURE_2D, cur_tex); - LEAVE_GL(); - } - - /* First call the previous set_palette function */ - glThis->set_palette(This, pal); - - /* And set the dirty flag */ - glThis->dirty_flag = SURFACE_MEMORY_DIRTY; - *(glThis->global_dirty_flag) = SURFACE_MEMORY_DIRTY; - - /* TODO: check palette on mipmapped surfaces... - TODO: do we need to re-upload in case of usage of the paletted texture extension ? */ -} - -static void -gltex_final_release(IDirectDrawSurfaceImpl *This) -{ - IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private; - DWORD mem_used; - int i; - - TRACE(" deleting texture with GL id %d.\n", glThis->tex_name); - - /* And delete texture handle */ - ENTER_GL(); - if (glThis->tex_name != 0) - glDeleteTextures(1, &(glThis->tex_name)); - LEAVE_GL(); - - HeapFree(GetProcessHeap(), 0, glThis->surface_ptr); - - /* And if this texture was the current one, remove it at the device level */ - if (This->d3ddevice != NULL) - for (i = 0; i < MAX_TEXTURES; i++) - if (This->d3ddevice->current_texture[i] == This) - This->d3ddevice->current_texture[i] = NULL; - - /* All this should be part of main surface management not just a hack for texture.. */ - if (glThis->loaded) { - mem_used = This->surface_desc.dwHeight * - This->surface_desc.u1.lPitch; - This->ddraw_owner->free_memory(This->ddraw_owner, mem_used); - } - - glThis->final_release(This); -} - -static void -gltex_lock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect, DWORD dwFlags) -{ - IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private; - - glThis->lock_update(This, pRect, dwFlags); -} - -static void -gltex_unlock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect) -{ - IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private; - - glThis->unlock_update(This, pRect); - - /* Set the dirty flag according to the lock type */ - if ((This->lastlocktype & DDLOCK_READONLY) == 0) { - glThis->dirty_flag = SURFACE_MEMORY_DIRTY; - *(glThis->global_dirty_flag) = SURFACE_MEMORY_DIRTY; - } -} - -HRESULT WINAPI -GL_IDirect3DTextureImpl_2_1T_Load(LPDIRECT3DTEXTURE2 iface, - LPDIRECT3DTEXTURE2 lpD3DTexture2) -{ - ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture2, iface); - IDirectDrawSurfaceImpl *src_ptr = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture2, lpD3DTexture2); - IDirectDrawSurfaceImpl *dst_ptr = This; + IDirectDrawSurfaceImpl *src_ptr = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture2, D3DTexture2); + IWineD3DPalette *wine_pal, *wine_pal_src; + IDirectDrawPalette *pal = NULL, *pal_src = NULL; + IDirectDrawPaletteImpl *pal_impl, *pal_impl_src; HRESULT ret_value = D3D_OK; - - TRACE("(%p/%p)->(%p)\n", This, iface, lpD3DTexture2); - if (((src_ptr->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) != (dst_ptr->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP)) || - (src_ptr->surface_desc.u2.dwMipMapCount != dst_ptr->surface_desc.u2.dwMipMapCount)) { + TRACE("(%p)->(%p)\n", This, src_ptr); + + if (((src_ptr->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) != (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP)) || + (src_ptr->surface_desc.u2.dwMipMapCount != This->surface_desc.u2.dwMipMapCount)) + { ERR("Trying to load surfaces with different mip-map counts !\n"); } - /* Now loop through all mipmap levels and load all of them... */ - while (1) { - IDirect3DTextureGLImpl *gl_dst_ptr = (IDirect3DTextureGLImpl *) dst_ptr->tex_private; - DDSURFACEDESC *src_d, *dst_d; - - if (gl_dst_ptr != NULL) { - if (gl_dst_ptr->loaded == FALSE) { - /* Only check memory for not already loaded texture... */ - DWORD mem_used; - if (dst_ptr->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC) - mem_used = dst_ptr->surface_desc.u1.dwLinearSize; - else - mem_used = dst_ptr->surface_desc.dwHeight * dst_ptr->surface_desc.u1.lPitch; - if (This->ddraw_owner->allocate_memory(This->ddraw_owner, mem_used) < 0) { - TRACE(" out of virtual memory... Warning application.\n"); - return D3DERR_TEXTURE_LOAD_FAILED; - } - } - gl_dst_ptr->loaded = TRUE; - } - - TRACE(" copying surface %p to surface %p (mipmap level %d)\n", src_ptr, dst_ptr, src_ptr->mipmap_level); + while(1) + { + DDSURFACEDESC *src_d, *dst_d; - if ( dst_ptr->surface_desc.ddsCaps.dwCaps & DDSCAPS_ALLOCONLOAD ) - /* If the surface is not allocated and its location is not yet specified, - force it to video memory */ - if ( !(dst_ptr->surface_desc.ddsCaps.dwCaps & (DDSCAPS_SYSTEMMEMORY|DDSCAPS_VIDEOMEMORY)) ) - dst_ptr->surface_desc.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY; + TRACE(" copying surface %p to surface %p (mipmap level %d)\n", src_ptr, This, src_ptr->mipmap_level); - /* Suppress the ALLOCONLOAD flag */ - dst_ptr->surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_ALLOCONLOAD; - - /* After seeing some logs, not sure at all about this... */ - if (dst_ptr->palette == NULL) { - dst_ptr->palette = src_ptr->palette; - if (src_ptr->palette != NULL) IDirectDrawPalette_AddRef(ICOM_INTERFACE(src_ptr->palette, IDirectDrawPalette)); - } else { - if (src_ptr->palette != NULL) { - PALETTEENTRY palent[256]; - IDirectDrawPalette_GetEntries(ICOM_INTERFACE(src_ptr->palette, IDirectDrawPalette), - 0, 0, 256, palent); - IDirectDrawPalette_SetEntries(ICOM_INTERFACE(dst_ptr->palette, IDirectDrawPalette), - 0, 0, 256, palent); - } - } - - /* Copy one surface on the other */ - dst_d = (DDSURFACEDESC *)&(dst_ptr->surface_desc); - src_d = (DDSURFACEDESC *)&(src_ptr->surface_desc); + if ( This->surface_desc.ddsCaps.dwCaps & DDSCAPS_ALLOCONLOAD ) + /* If the surface is not allocated and its location is not yet specified, + force it to video memory */ + if ( !(This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_SYSTEMMEMORY|DDSCAPS_VIDEOMEMORY)) ) + This->surface_desc.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY; - if ((src_d->dwWidth != dst_d->dwWidth) || (src_d->dwHeight != dst_d->dwHeight)) { - /* Should also check for same pixel format, u1.lPitch, ... */ - ERR("Error in surface sizes\n"); - return D3DERR_TEXTURE_LOAD_FAILED; - } else { - /* LPDIRECT3DDEVICE2 d3dd = (LPDIRECT3DDEVICE2) This->D3Ddevice; */ - /* I should put a macro for the calculus of bpp */ - - /* Copy also the ColorKeying stuff */ - if (src_d->dwFlags & DDSD_CKSRCBLT) { - dst_d->dwFlags |= DDSD_CKSRCBLT; - dst_d->ddckCKSrcBlt.dwColorSpaceLowValue = src_d->ddckCKSrcBlt.dwColorSpaceLowValue; - dst_d->ddckCKSrcBlt.dwColorSpaceHighValue = src_d->ddckCKSrcBlt.dwColorSpaceHighValue; - } + /* Suppress the ALLOCONLOAD flag */ + This->surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_ALLOCONLOAD; - /* Copy the main memory texture into the surface that corresponds to the OpenGL - texture object. */ - if (dst_ptr->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC) - memcpy(dst_d->lpSurface, src_d->lpSurface, src_ptr->surface_desc.u1.dwLinearSize); - else - memcpy(dst_d->lpSurface, src_d->lpSurface, src_d->u1.lPitch * src_d->dwHeight); + /* Get the palettes */ + ret_value = IWineD3DSurface_GetPalette(This->WineD3DSurface, &wine_pal); + if( ret_value != D3D_OK) + { + ERR("IWineD3DSurface::GetPalette failed! This is unexpected\n"); + return D3DERR_TEXTURE_LOAD_FAILED; + } + if(wine_pal) + { + ret_value = IWineD3DPalette_GetParent(wine_pal, (IUnknown **) &pal); + if(ret_value != D3D_OK) + { + ERR("IWineD3DPalette::GetParent failed! This is unexpected\n"); + return D3DERR_TEXTURE_LOAD_FAILED; + } + pal_impl = ICOM_OBJECT(IDirectDrawPaletteImpl, IDirectDrawPalette, pal); + } + else + { + pal_impl = NULL; + } - if (gl_dst_ptr != NULL) { - /* Set this texture as dirty */ - gl_dst_ptr->dirty_flag = SURFACE_MEMORY_DIRTY; - *(gl_dst_ptr->global_dirty_flag) = SURFACE_MEMORY_DIRTY; - } - } + ret_value = IWineD3DSurface_GetPalette(src_ptr->WineD3DSurface, &wine_pal_src); + if( ret_value != D3D_OK) + { + ERR("IWineD3DSurface::GetPalette failed! This is unexpected\n"); + return D3DERR_TEXTURE_LOAD_FAILED; + } + if(wine_pal_src) + { + ret_value = IWineD3DPalette_GetParent(wine_pal_src, (IUnknown **) &pal_src); + if(ret_value != D3D_OK) + { + ERR("IWineD3DPalette::GetParent failed! This is unexpected\n"); + return D3DERR_TEXTURE_LOAD_FAILED; + } + pal_impl_src = ICOM_OBJECT(IDirectDrawPaletteImpl, IDirectDrawPalette, pal_src); + } + else + { + pal_impl_src = NULL; + } - if (src_ptr->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) { - src_ptr = get_sub_mimaplevel(src_ptr); - } else { - src_ptr = NULL; - } - if (dst_ptr->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) { - dst_ptr = get_sub_mimaplevel(dst_ptr); - } else { - dst_ptr = NULL; - } + /* After seeing some logs, not sure at all about this... */ + if (pal_impl == NULL) + { + IWineD3DSurface_SetPalette(This->WineD3DSurface, wine_pal); + if (pal_impl_src != NULL) IDirectDrawPalette_AddRef(ICOM_INTERFACE(pal_impl_src, IDirectDrawPalette)); + } + else + { + if (pal_impl_src != NULL) + { + PALETTEENTRY palent[256]; + IDirectDrawPalette_GetEntries(ICOM_INTERFACE(pal_impl_src, IDirectDrawPalette), + 0, 0, 256, palent); + IDirectDrawPalette_SetEntries(ICOM_INTERFACE(pal_impl, IDirectDrawPalette), + 0, 0, 256, palent); + } + } - if ((src_ptr == NULL) || (dst_ptr == NULL)) { - if (src_ptr != dst_ptr) { - ERR(" Loading surface with different mipmap structure !!!\n"); - } - break; - } + /* Copy one surface on the other */ + dst_d = (DDSURFACEDESC *)&(This->surface_desc); + src_d = (DDSURFACEDESC *)&(src_ptr->surface_desc); + + if ((src_d->dwWidth != dst_d->dwWidth) || (src_d->dwHeight != dst_d->dwHeight)) + { + /* Should also check for same pixel format, u1.lPitch, ... */ + ERR("Error in surface sizes\n"); + return D3DERR_TEXTURE_LOAD_FAILED; + } + else + { + WINED3DLOCKED_RECT pSrcRect, pDstRect; + + /* LPDIRECT3DDEVICE2 d3dd = (LPDIRECT3DDEVICE2) This->D3Ddevice; */ + /* I should put a macro for the calculus of bpp */ + + /* Copy also the ColorKeying stuff */ + if (src_d->dwFlags & DDSD_CKSRCBLT) + { + dst_d->dwFlags |= DDSD_CKSRCBLT; + dst_d->ddckCKSrcBlt.dwColorSpaceLowValue = src_d->ddckCKSrcBlt.dwColorSpaceLowValue; + dst_d->ddckCKSrcBlt.dwColorSpaceHighValue = src_d->ddckCKSrcBlt.dwColorSpaceHighValue; + } + + /* Copy the main memory texture into the surface that corresponds to the OpenGL + texture object. */ + + ret_value = IWineD3DSurface_LockRect(src_ptr->WineD3DSurface, &pSrcRect, NULL, 0); + if(ret_value != D3D_OK) + { + ERR(" (%p) Locking the source surface failed\n", This); + return D3DERR_TEXTURE_LOAD_FAILED; + } + + ret_value = IWineD3DSurface_LockRect(This->WineD3DSurface, &pDstRect, NULL, 0); + if(ret_value != D3D_OK) + { + ERR(" (%p) Locking the destination surface failed\n", This); + IWineD3DSurface_UnlockRect(src_ptr->WineD3DSurface); + return D3DERR_TEXTURE_LOAD_FAILED; + } + + if (This->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC) + memcpy(pDstRect.pBits, pSrcRect.pBits, src_ptr->surface_desc.u1.dwLinearSize); + else + memcpy(pDstRect.pBits, pSrcRect.pBits, pSrcRect.Pitch * src_d->dwHeight); + + IWineD3DSurface_UnlockRect(src_ptr->WineD3DSurface); + IWineD3DSurface_UnlockRect(This->WineD3DSurface); + } + + if (src_ptr->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) + { + src_ptr = get_sub_mimaplevel(src_ptr); + } + else + { + src_ptr = NULL; + } + if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) + { + This = get_sub_mimaplevel(This); + } + else + { + This = NULL; + } + + if ((src_ptr == NULL) || (This == NULL)) + { + if (src_ptr != This) + { + ERR(" Loading surface with different mipmap structure !!!\n"); + } + break; + } } return ret_value; } -HRESULT WINAPI -Thunk_IDirect3DTextureImpl_2_QueryInterface(LPDIRECT3DTEXTURE2 iface, - REFIID riid, - LPVOID* obp) +static HRESULT WINAPI +Thunk_IDirect3DTextureImpl_1_Load(IDirect3DTexture *iface, + IDirect3DTexture *D3DTexture) { - TRACE("(%p)->(%s,%p) thunking to IDirectDrawSurface7 interface.\n", iface, debugstr_guid(riid), obp); - return IDirectDrawSurface7_QueryInterface(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture2, IDirectDrawSurface7, iface), - riid, - obp); -} + ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture, iface); + IDirectDrawSurfaceImpl *Texture = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture, D3DTexture); + TRACE("(%p)->(%p) thunking to IDirect3DTexture2 interface.\n", This, Texture); -ULONG WINAPI -Thunk_IDirect3DTextureImpl_2_AddRef(LPDIRECT3DTEXTURE2 iface) -{ - TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", iface); - return IDirectDrawSurface7_AddRef(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture2, IDirectDrawSurface7, iface)); -} - -ULONG WINAPI -Thunk_IDirect3DTextureImpl_2_Release(LPDIRECT3DTEXTURE2 iface) -{ - TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", iface); - return IDirectDrawSurface7_Release(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture2, IDirectDrawSurface7, iface)); -} - -HRESULT WINAPI -Thunk_IDirect3DTextureImpl_1_QueryInterface(LPDIRECT3DTEXTURE iface, - REFIID riid, - LPVOID* obp) -{ - TRACE("(%p)->(%s,%p) thunking to IDirectDrawSurface7 interface.\n", iface, debugstr_guid(riid), obp); - return IDirectDrawSurface7_QueryInterface(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirectDrawSurface7, iface), - riid, - obp); -} - -ULONG WINAPI -Thunk_IDirect3DTextureImpl_1_AddRef(LPDIRECT3DTEXTURE iface) -{ - TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", iface); - return IDirectDrawSurface7_AddRef(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirectDrawSurface7, iface)); -} - -ULONG WINAPI -Thunk_IDirect3DTextureImpl_1_Release(LPDIRECT3DTEXTURE iface) -{ - TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", iface); - return IDirectDrawSurface7_Release(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirectDrawSurface7, iface)); -} - -HRESULT WINAPI -Thunk_IDirect3DTextureImpl_1_PaletteChanged(LPDIRECT3DTEXTURE iface, - DWORD dwStart, - DWORD dwCount) -{ - TRACE("(%p)->(%08lx,%08lx) thunking to IDirect3DTexture2 interface.\n", iface, dwStart, dwCount); - return IDirect3DTexture2_PaletteChanged(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirect3DTexture2, iface), - dwStart, - dwCount); -} - -HRESULT WINAPI -Thunk_IDirect3DTextureImpl_1_GetHandle(LPDIRECT3DTEXTURE iface, - LPDIRECT3DDEVICE lpDirect3DDevice, - LPD3DTEXTUREHANDLE lpHandle) -{ - TRACE("(%p)->(%p,%p) thunking to IDirect3DTexture2 interface.\n", iface, lpDirect3DDevice, lpHandle); - return IDirect3DTexture2_GetHandle(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirect3DTexture2, iface), - COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice2, lpDirect3DDevice), - lpHandle); -} - -HRESULT WINAPI -Thunk_IDirect3DTextureImpl_1_Load(LPDIRECT3DTEXTURE iface, - LPDIRECT3DTEXTURE lpD3DTexture) -{ - TRACE("(%p)->(%p) thunking to IDirect3DTexture2 interface.\n", iface, lpD3DTexture); return IDirect3DTexture2_Load(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirect3DTexture2, iface), - COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirect3DTexture2, lpD3DTexture)); + COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirect3DTexture2, D3DTexture)); } -#if !defined(__STRICT_ANSI__) && defined(__GNUC__) -# define XCAST(fun) (typeof(VTABLE_IDirect3DTexture2.fun)) -#else -# define XCAST(fun) (void*) -#endif - -static const IDirect3DTexture2Vtbl VTABLE_IDirect3DTexture2 = +/***************************************************************************** + * The VTables + *****************************************************************************/ +const IDirect3DTexture2Vtbl IDirect3DTexture2_Vtbl = { - XCAST(QueryInterface) Thunk_IDirect3DTextureImpl_2_QueryInterface, - XCAST(AddRef) Thunk_IDirect3DTextureImpl_2_AddRef, - XCAST(Release) Thunk_IDirect3DTextureImpl_2_Release, - XCAST(GetHandle) Main_IDirect3DTextureImpl_2_1T_GetHandle, - XCAST(PaletteChanged) Main_IDirect3DTextureImpl_2_1T_PaletteChanged, - XCAST(Load) GL_IDirect3DTextureImpl_2_1T_Load, + Thunk_IDirect3DTextureImpl_2_QueryInterface, + Thunk_IDirect3DTextureImpl_2_AddRef, + Thunk_IDirect3DTextureImpl_2_Release, + IDirect3DTextureImpl_GetHandle, + IDirect3DTextureImpl_PaletteChanged, + IDirect3DTextureImpl_Load, }; -#if !defined(__STRICT_ANSI__) && defined(__GNUC__) -#undef XCAST -#endif - -#if !defined(__STRICT_ANSI__) && defined(__GNUC__) -# define XCAST(fun) (typeof(VTABLE_IDirect3DTexture.fun)) -#else -# define XCAST(fun) (void*) -#endif - -static const IDirect3DTextureVtbl VTABLE_IDirect3DTexture = +const IDirect3DTextureVtbl IDirect3DTexture1_Vtbl = { - XCAST(QueryInterface) Thunk_IDirect3DTextureImpl_1_QueryInterface, - XCAST(AddRef) Thunk_IDirect3DTextureImpl_1_AddRef, - XCAST(Release) Thunk_IDirect3DTextureImpl_1_Release, - XCAST(Initialize) Main_IDirect3DTextureImpl_1_Initialize, - XCAST(GetHandle) Thunk_IDirect3DTextureImpl_1_GetHandle, - XCAST(PaletteChanged) Thunk_IDirect3DTextureImpl_1_PaletteChanged, - XCAST(Load) Thunk_IDirect3DTextureImpl_1_Load, - XCAST(Unload) Main_IDirect3DTextureImpl_1_Unload, + Thunk_IDirect3DTextureImpl_1_QueryInterface, + Thunk_IDirect3DTextureImpl_1_AddRef, + Thunk_IDirect3DTextureImpl_1_Release, + IDirect3DTextureImpl_1_Initialize, + Thunk_IDirect3DTextureImpl_1_GetHandle, + Thunk_IDirect3DTextureImpl_1_PaletteChanged, + Thunk_IDirect3DTextureImpl_1_Load, + IDirect3DTextureImpl_1_Unload, }; - -#if !defined(__STRICT_ANSI__) && defined(__GNUC__) -#undef XCAST -#endif - -HRESULT d3dtexture_create(IDirectDrawImpl *d3d, IDirectDrawSurfaceImpl *surf, BOOLEAN at_creation, - IDirectDrawSurfaceImpl *main) -{ - /* First, initialize the texture vtables... */ - ICOM_INIT_INTERFACE(surf, IDirect3DTexture, VTABLE_IDirect3DTexture); - ICOM_INIT_INTERFACE(surf, IDirect3DTexture2, VTABLE_IDirect3DTexture2); - - /* Only create all the private stuff if we actually have an OpenGL context.. */ - if (d3d->current_device != NULL) { - IDirect3DTextureGLImpl *private; - - private = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DTextureGLImpl)); - if (private == NULL) return DDERR_OUTOFMEMORY; - - surf->tex_private = private; - - private->final_release = surf->final_release; - private->lock_update = surf->lock_update; - private->unlock_update = surf->unlock_update; - private->set_palette = surf->set_palette; - - /* If at creation, we can optimize stuff and wait the first 'unlock' to upload a valid stuff to OpenGL. - Otherwise, it will be uploaded here (and may be invalid). */ - surf->final_release = gltex_final_release; - surf->lock_update = gltex_lock_update; - surf->unlock_update = gltex_unlock_update; - surf->aux_setcolorkey_cb = gltex_setcolorkey_cb; - surf->set_palette = gltex_set_palette; - - /* We are the only one to use the aux_blt and aux_bltfast overrides, so no need - to save those... */ - surf->aux_blt = gltex_blt; - surf->aux_bltfast = gltex_bltfast; - - TRACE(" GL texture created for surface %p (private data at %p)\n", surf, private); - - /* Do not create the OpenGL texture id here as some game generate textures from a different thread which - cause problems.. */ - private->tex_name = 0; - if (surf->mipmap_level == 0) { - private->main = NULL; - private->__global_dirty_flag = SURFACE_MEMORY_DIRTY; - private->global_dirty_flag = &(private->__global_dirty_flag); - } else { - private->main = main; - private->global_dirty_flag = &(((IDirect3DTextureGLImpl *) (private->main->tex_private))->__global_dirty_flag); - } - private->initial_upload_done = FALSE; - private->dirty_flag = SURFACE_MEMORY_DIRTY; - } - - return D3D_OK; -} - -GLuint gltex_get_tex_name(IDirectDrawSurfaceImpl *surf) -{ - IDirect3DTextureGLImpl *private = (IDirect3DTextureGLImpl *) (surf->tex_private); - - if (private->tex_name == 0) { - /* The texture was not created yet... */ - ENTER_GL(); - if (surf->mipmap_level == 0) { - glGenTextures(1, &(private->tex_name)); - if (private->tex_name == 0) ERR("Error at creation of OpenGL texture ID !\n"); - TRACE(" GL texture id is : %d.\n", private->tex_name); - } else { - private->tex_name = gltex_get_tex_name(private->main); - TRACE(" GL texture id reusing id %d from surface %p (private at %p)).\n", private->tex_name, private->main, private->main->tex_private); - } - LEAVE_GL(); - } - return ((IDirect3DTextureGLImpl *) (surf->tex_private))->tex_name; -} diff --git a/dlls/ddraw/utils.c b/dlls/ddraw/utils.c new file mode 100644 index 0000000000..2ffd51b5d9 --- /dev/null +++ b/dlls/ddraw/utils.c @@ -0,0 +1,1171 @@ +/* + * DirectDraw helper functions + * + * Copyright (c) 1997-2000 Marcus Meissner + * Copyright (c) 1998 Lionel Ulmer + * Copyright (c) 2000 TransGaming Technologies Inc. + * Copyright (c) 2006 Stefan Dösinger + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" + +#define NONAMELESSUNION + +#include "ddraw_private.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(ddraw); + +void DDRAW_dump_flags_(DWORD flags, const flag_info* names, size_t num_names, int newline); + +/***************************************************************************** + * PixelFormat_WineD3DtoDD + * + * Converts an WINED3DFORMAT value into a DDPIXELFORMAT structure + * + * Params: + * DDPixelFormat: Address of the structure to write the pixel format to + * WineD3DFormat: Source format + * + *****************************************************************************/ +void +PixelFormat_WineD3DtoDD(DDPIXELFORMAT *DDPixelFormat, + WINED3DFORMAT WineD3DFormat) +{ + DWORD Size = DDPixelFormat->dwSize; + TRACE("Converting WINED3DFORMAT %d to DDRAW\n", WineD3DFormat); + + if(Size==0) return; + + memset(DDPixelFormat, 0x00, Size); + DDPixelFormat->dwSize = Size; + switch(WineD3DFormat) + { + case WINED3DFMT_R8G8B8: + DDPixelFormat->dwFlags = DDPF_RGB; + DDPixelFormat->dwFourCC = 0; + DDPixelFormat->u1.dwRGBBitCount = 24; + DDPixelFormat->u2.dwRBitMask = 0x00ff0000; + DDPixelFormat->u3.dwGBitMask = 0x0000ff00; + DDPixelFormat->u4.dwBBitMask = 0x000000ff; + DDPixelFormat->u5.dwRGBAlphaBitMask = 0x0; + break; + + case WINED3DFMT_A8R8G8B8: + DDPixelFormat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS; + DDPixelFormat->dwFourCC = 0; + DDPixelFormat->u1.dwRGBBitCount = 32; + DDPixelFormat->u2.dwRBitMask = 0x00ff0000; + DDPixelFormat->u3.dwGBitMask = 0x0000ff00; + DDPixelFormat->u4.dwBBitMask = 0x000000ff; + DDPixelFormat->u5.dwRGBAlphaBitMask = 0xff000000; + break; + + case WINED3DFMT_X8R8G8B8: + DDPixelFormat->dwFlags = DDPF_RGB; + DDPixelFormat->dwFourCC = 0; + DDPixelFormat->u1.dwRGBBitCount = 32; + DDPixelFormat->u2.dwRBitMask = 0x00ff0000; + DDPixelFormat->u3.dwGBitMask = 0x0000ff00; + DDPixelFormat->u4.dwBBitMask = 0x000000ff; + DDPixelFormat->u5.dwRGBAlphaBitMask = 0x0; + break; + + case WINED3DFMT_X8B8G8R8: + DDPixelFormat->dwFlags = DDPF_RGB; + DDPixelFormat->dwFourCC = 0; + DDPixelFormat->u1.dwRGBBitCount = 32; + DDPixelFormat->u2.dwRBitMask = 0x000000ff; + DDPixelFormat->u3.dwGBitMask = 0x0000ff00; + DDPixelFormat->u4.dwBBitMask = 0x00ff0000; + DDPixelFormat->u5.dwRGBAlphaBitMask = 0x0; + break; + + case WINED3DFMT_R5G6B5: + DDPixelFormat->dwFlags = DDPF_RGB; + DDPixelFormat->dwFourCC = 0; + DDPixelFormat->u1.dwRGBBitCount = 16; + DDPixelFormat->u2.dwRBitMask = 0xF800; + DDPixelFormat->u3.dwGBitMask = 0x07E0; + DDPixelFormat->u4.dwBBitMask = 0x001F; + DDPixelFormat->u5.dwRGBAlphaBitMask = 0x0; + break; + + case WINED3DFMT_X1R5G5B5: + DDPixelFormat->dwFlags = DDPF_RGB; + DDPixelFormat->dwFourCC = 0; + DDPixelFormat->u1.dwRGBBitCount = 16; + DDPixelFormat->u2.dwRBitMask = 0x7C00; + DDPixelFormat->u3.dwGBitMask = 0x03E0; + DDPixelFormat->u4.dwBBitMask = 0x001F; + DDPixelFormat->u5.dwRGBAlphaBitMask = 0x0; + break; + + case WINED3DFMT_A1R5G5B5: + DDPixelFormat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS; + DDPixelFormat->dwFourCC = 0; + DDPixelFormat->u1.dwRGBBitCount = 16; + DDPixelFormat->u2.dwRBitMask = 0x7C00; + DDPixelFormat->u3.dwGBitMask = 0x03E0; + DDPixelFormat->u4.dwBBitMask = 0x001F; + DDPixelFormat->u5.dwRGBAlphaBitMask = 0x8000; + break; + + case WINED3DFMT_A4R4G4B4: + DDPixelFormat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS; + DDPixelFormat->dwFourCC = 0; + DDPixelFormat->u1.dwRGBBitCount = 16; + DDPixelFormat->u2.dwRBitMask = 0x0F00; + DDPixelFormat->u3.dwGBitMask = 0x00F0; + DDPixelFormat->u4.dwBBitMask = 0x000F; + DDPixelFormat->u5.dwRGBAlphaBitMask = 0xF000; + break; + + case WINED3DFMT_R3G3B2: + DDPixelFormat->dwFlags = DDPF_RGB; + DDPixelFormat->dwFourCC = 0; + DDPixelFormat->u1.dwRGBBitCount = 8; + DDPixelFormat->u2.dwRBitMask = 0xE0; + DDPixelFormat->u3.dwGBitMask = 0x1C; + DDPixelFormat->u4.dwBBitMask = 0x03; + DDPixelFormat->u5.dwLuminanceAlphaBitMask = 0x0; + break; + + case WINED3DFMT_P8: + DDPixelFormat->dwFlags = DDPF_PALETTEINDEXED8 | DDPF_RGB; + DDPixelFormat->dwFourCC = 0; + DDPixelFormat->u1.dwRGBBitCount = 8; + DDPixelFormat->u2.dwRBitMask = 0x00; + DDPixelFormat->u3.dwGBitMask = 0x00; + DDPixelFormat->u4.dwBBitMask = 0x00; + break; + + case WINED3DFMT_A8: + DDPixelFormat->dwFlags = DDPF_ALPHA; + DDPixelFormat->dwFourCC = 0; + DDPixelFormat->u1.dwAlphaBitDepth = 8; + DDPixelFormat->u2.dwRBitMask = 0x0; + DDPixelFormat->u3.dwZBitMask = 0x0; + DDPixelFormat->u4.dwStencilBitMask = 0x0; + DDPixelFormat->u5.dwLuminanceAlphaBitMask = 0x0; + break; + + case WINED3DFMT_A8R3G3B2: + DDPixelFormat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS; + DDPixelFormat->dwFourCC = 0; + DDPixelFormat->u1.dwRGBBitCount = 16; + DDPixelFormat->u2.dwRBitMask = 0x00E0; + DDPixelFormat->u3.dwGBitMask = 0x001C; + DDPixelFormat->u4.dwBBitMask = 0x0003; + DDPixelFormat->u5.dwRGBAlphaBitMask = 0xF000; + break; + + case WINED3DFMT_X4R4G4B4: + DDPixelFormat->dwFlags = DDPF_RGB; + DDPixelFormat->dwFourCC = 0; + DDPixelFormat->u1.dwRGBBitCount = 16; + DDPixelFormat->u2.dwRBitMask = 0x0F00; + DDPixelFormat->u3.dwGBitMask = 0x00F0; + DDPixelFormat->u4.dwBBitMask = 0x000F; + DDPixelFormat->u5.dwRGBAlphaBitMask = 0x0; + return; + + /* How are Z buffer bit depth and Stencil buffer bit depth related? + */ + case WINED3DFMT_D16: + DDPixelFormat->dwFlags = DDPF_ZBUFFER; + DDPixelFormat->dwFourCC = 0; + DDPixelFormat->u1.dwZBufferBitDepth = 16; + DDPixelFormat->u2.dwStencilBitDepth = 0; + DDPixelFormat->u3.dwZBitMask = 0x0000FFFF; + DDPixelFormat->u4.dwStencilBitMask = 0x0; + DDPixelFormat->u5.dwRGBZBitMask = 0x0000FFFF; + break; + + case WINED3DFMT_D32: + DDPixelFormat->dwFlags = DDPF_ZBUFFER; + DDPixelFormat->dwFourCC = 0; + DDPixelFormat->u1.dwZBufferBitDepth = 32; + DDPixelFormat->u2.dwStencilBitDepth = 0; + DDPixelFormat->u3.dwZBitMask = 0xFFFFFFFF; + DDPixelFormat->u4.dwStencilBitMask = 0x0; + DDPixelFormat->u5.dwRGBZBitMask = 0xFFFFFFFF; + break; + + case WINED3DFMT_D24X4S4: + DDPixelFormat->dwFlags = DDPF_ZBUFFER | DDPF_STENCILBUFFER; + DDPixelFormat->dwFourCC = 0; + /* Should I set dwZBufferBitDepth to 32 here? */ + DDPixelFormat->u1.dwZBufferBitDepth = 24; + DDPixelFormat->u2.dwStencilBitDepth = 4; + DDPixelFormat->u3.dwZBitMask = 0x0; + DDPixelFormat->u4.dwStencilBitMask = 0x0; + DDPixelFormat->u5.dwRGBAlphaBitMask = 0x0; + break; + + case WINED3DFMT_D24S8: + DDPixelFormat->dwFlags = DDPF_ZBUFFER | DDPF_STENCILBUFFER; + DDPixelFormat->dwFourCC = 0; + /* Should I set dwZBufferBitDepth to 32 here? */ + DDPixelFormat->u1.dwZBufferBitDepth = 24; + DDPixelFormat->u2.dwStencilBitDepth = 8; + DDPixelFormat->u3.dwZBitMask = 0x0; + DDPixelFormat->u4.dwStencilBitMask = 0x0; + DDPixelFormat->u5.dwRGBAlphaBitMask = 0x0; + break; + + case WINED3DFMT_D24X8: + DDPixelFormat->dwFlags = DDPF_ZBUFFER; + DDPixelFormat->dwFourCC = 0; + DDPixelFormat->u1.dwZBufferBitDepth = 24; + DDPixelFormat->u2.dwStencilBitDepth = 8; + DDPixelFormat->u3.dwZBitMask = 0x0; + DDPixelFormat->u4.dwStencilBitMask = 0x0; + DDPixelFormat->u5.dwRGBAlphaBitMask = 0x0; + + break; + case WINED3DFMT_D15S1: + DDPixelFormat->dwFlags = DDPF_ZBUFFER | DDPF_STENCILBUFFER; + DDPixelFormat->dwFourCC = 0; + /* Should I set dwZBufferBitDepth to 16 here? */ + DDPixelFormat->u1.dwZBufferBitDepth = 15; + DDPixelFormat->u2.dwStencilBitDepth = 1; + DDPixelFormat->u3.dwZBitMask = 0x0; + DDPixelFormat->u4.dwStencilBitMask = 0x0; + DDPixelFormat->u5.dwRGBAlphaBitMask = 0x0; + break; + + case WINED3DFMT_UYVY: + case WINED3DFMT_YUY2: + case WINED3DFMT_DXT1: + case WINED3DFMT_DXT2: + case WINED3DFMT_DXT3: + case WINED3DFMT_DXT4: + case WINED3DFMT_DXT5: + case WINED3DFMT_MULTI2_ARGB: + case WINED3DFMT_G8R8_G8B8: + case WINED3DFMT_R8G8_B8G8: + DDPixelFormat->dwFlags = DDPF_FOURCC; + DDPixelFormat->dwFourCC = WineD3DFormat; + break; + + /* Luminance */ + case WINED3DFMT_L8: + DDPixelFormat->dwFlags = DDPF_LUMINANCE; + DDPixelFormat->dwFourCC = 0; + DDPixelFormat->u1.dwLuminanceBitCount = 8; + DDPixelFormat->u2.dwLuminanceBitMask = 0xff; + DDPixelFormat->u3.dwBumpDvBitMask = 0x0; + DDPixelFormat->u4.dwBumpLuminanceBitMask = 0x0; + DDPixelFormat->u5.dwLuminanceAlphaBitMask = 0x0; + break; + + case WINED3DFMT_A4L4: + DDPixelFormat->dwFlags = DDPF_ALPHAPIXELS | DDPF_LUMINANCE; + DDPixelFormat->dwFourCC = 0; + DDPixelFormat->u1.dwLuminanceBitCount = 4; + DDPixelFormat->u2.dwLuminanceBitMask = 0x0f; + DDPixelFormat->u3.dwBumpDvBitMask = 0x0; + DDPixelFormat->u4.dwBumpLuminanceBitMask = 0x0; + DDPixelFormat->u5.dwLuminanceAlphaBitMask = 0xf0; + break; + + case WINED3DFMT_A8L8: + DDPixelFormat->dwFlags = DDPF_ALPHAPIXELS | DDPF_LUMINANCE; + DDPixelFormat->dwFourCC = 0; + DDPixelFormat->u1.dwLuminanceBitCount = 16; + DDPixelFormat->u2.dwLuminanceBitMask = 0x00ff; + DDPixelFormat->u3.dwBumpDvBitMask = 0x0; + DDPixelFormat->u4.dwBumpLuminanceBitMask = 0x0; + DDPixelFormat->u5.dwLuminanceAlphaBitMask = 0xff00; + break; + + /* Bump mapping */ + case WINED3DFMT_V8U8: + DDPixelFormat->dwFlags = DDPF_BUMPDUDV; + DDPixelFormat->dwFourCC = 0; + DDPixelFormat->u1.dwBumpBitCount = 16; + DDPixelFormat->u2.dwBumpDuBitMask = 0x000000ff; + DDPixelFormat->u3.dwBumpDvBitMask = 0x0000ff00; + DDPixelFormat->u4.dwBumpLuminanceBitMask = 0x00000000; + DDPixelFormat->u5.dwLuminanceAlphaBitMask = 0x00000000; + break; + + case WINED3DFMT_L6V5U5: + DDPixelFormat->dwFlags = DDPF_BUMPDUDV; + DDPixelFormat->dwFourCC = 0; + DDPixelFormat->u1.dwBumpBitCount = 16; + DDPixelFormat->u2.dwBumpDuBitMask = 0x0000001f; + DDPixelFormat->u3.dwBumpDvBitMask = 0x000003e0; + DDPixelFormat->u4.dwBumpLuminanceBitMask = 0x0000fc00; + DDPixelFormat->u5.dwLuminanceAlphaBitMask = 0x00000000; + break; + + default: + ERR("Can't translate this Pixelformat %d\n", WineD3DFormat); + } + + if(TRACE_ON(ddraw)) { + TRACE("Returning: "); + DDRAW_dump_pixelformat(DDPixelFormat); + TRACE("\n"); + } +} +/***************************************************************************** + * PixelFormat_DD2WineD3D + * + * Reads a DDPIXELFORMAT structure and returns the equal WINED3DFORMAT + * + * Params: + * DDPixelFormat: The source format + * + * Returns: + * The WINED3DFORMAT equal to the DDraw format + * WINED3DFMT_UNKNOWN if a matching format wasn't found + *****************************************************************************/ +WINED3DFORMAT +PixelFormat_DD2WineD3D(DDPIXELFORMAT *DDPixelFormat) +{ + TRACE("Convert a DirectDraw Pixelformat to a WineD3D Pixelformat\n"); + if(TRACE_ON(ddraw)) + { + DDRAW_dump_pixelformat(DDPixelFormat); + TRACE("\n"); + } + + if(DDPixelFormat->dwFlags & DDPF_PALETTEINDEXED8) + { + return WINED3DFMT_P8; + } + else if(DDPixelFormat->dwFlags & (DDPF_PALETTEINDEXED1 | DDPF_PALETTEINDEXED2 | DDPF_PALETTEINDEXED4) ) + { + FIXME("DDPF_PALETTEINDEXED1 to DDPF_PALETTEINDEXED4 are not supported by WineD3D (yet). Returning WINED3DFMT_P8\n"); + return WINED3DFMT_P8; + } + else if(DDPixelFormat->dwFlags & DDPF_RGB) + { + switch(DDPixelFormat->u1.dwRGBBitCount) + { + case 8: + /* This is the only format that can match here */ + return WINED3DFMT_R3G3B2; + + case 16: + /* Read the Color masks */ + if( (DDPixelFormat->u2.dwRBitMask == 0xF800) && + (DDPixelFormat->u3.dwGBitMask == 0x07E0) && + (DDPixelFormat->u4.dwBBitMask == 0x001F) ) + { + return WINED3DFMT_R5G6B5; + } + + if( (DDPixelFormat->u2.dwRBitMask == 0x7C00) && + (DDPixelFormat->u3.dwGBitMask == 0x03E0) && + (DDPixelFormat->u4.dwBBitMask == 0x001F) ) + { + if( (DDPixelFormat->dwFlags & DDPF_ALPHAPIXELS) && + (DDPixelFormat->u5.dwRGBAlphaBitMask == 0x8000)) + return WINED3DFMT_A1R5G5B5; + else + return WINED3DFMT_X1R5G5B5; + } + + if( (DDPixelFormat->u2.dwRBitMask == 0x0F00) && + (DDPixelFormat->u3.dwGBitMask == 0x00F0) && + (DDPixelFormat->u4.dwBBitMask == 0x000F) ) + { + if( (DDPixelFormat->dwFlags & DDPF_ALPHAPIXELS) && + (DDPixelFormat->u5.dwRGBAlphaBitMask == 0xF000)) + return WINED3DFMT_A4R4G4B4; + else + return WINED3DFMT_X4R4G4B4; + } + + if( (DDPixelFormat->dwFlags & DDPF_ALPHAPIXELS) && + (DDPixelFormat->u5.dwRGBAlphaBitMask == 0xFF00) && + (DDPixelFormat->u2.dwRBitMask == 0x00E0) && + (DDPixelFormat->u3.dwGBitMask == 0x001C) && + (DDPixelFormat->u4.dwBBitMask == 0x0003) ) + { + return WINED3DFMT_A8R3G3B2; + } + ERR("16 bit RGB Pixel format does not match\n"); + return WINED3DFMT_UNKNOWN; + + case 24: + return WINED3DFMT_R8G8B8; + + case 32: + /* Read the Color masks */ + if( (DDPixelFormat->u2.dwRBitMask == 0x00FF0000) && + (DDPixelFormat->u3.dwGBitMask == 0x0000FF00) && + (DDPixelFormat->u4.dwBBitMask == 0x000000FF) ) + { + if( (DDPixelFormat->dwFlags & DDPF_ALPHAPIXELS) && + (DDPixelFormat->u5.dwRGBAlphaBitMask == 0xFF000000)) + return WINED3DFMT_A8R8G8B8; + else + return WINED3DFMT_X8R8G8B8; + + } + ERR("32 bit RGB pixel format does not match\n"); + + default: + ERR("Invalid dwRGBBitCount in Pixelformat structure\n"); + return WINED3DFMT_UNKNOWN; + } + } + else if( (DDPixelFormat->dwFlags & DDPF_ALPHA) ) + { + /* Alpha only Pixelformat */ + switch(DDPixelFormat->u1.dwAlphaBitDepth) + { + case 1: + case 2: + case 4: + ERR("Unsupported Alpha-Only bit depth 0x%lx\n", DDPixelFormat->u1.dwAlphaBitDepth); + case 8: + return WINED3DFMT_A8; + + default: + ERR("Invalid AlphaBitDepth in Alpha-Only Pixelformat\n"); + return WINED3DFMT_UNKNOWN; + } + } + else if(DDPixelFormat->dwFlags & DDPF_LUMINANCE) + { + /* Luminance-only or luminance-alpha */ + if(DDPixelFormat->dwFlags & DDPF_ALPHAPIXELS) + { + /* Luminance with Alpha */ + switch(DDPixelFormat->u1.dwLuminanceBitCount) + { + case 4: + if(DDPixelFormat->u1.dwAlphaBitDepth == 4) + return WINED3DFMT_A4L4; + ERR("Unknown Alpha / Luminance bit depth combination\n"); + return WINED3DFMT_UNKNOWN; + + case 6: + ERR("A luminance Pixelformat shouldn't have 6 luminance bits. Returning D3DFMT_L6V5U5 for now!!\n"); + return WINED3DFMT_L6V5U5; + + case 8: + if(DDPixelFormat->u1.dwAlphaBitDepth == 8) + return WINED3DFMT_A8L8; + ERR("Unkown Alpha / Lumincase bit depth combination\n"); + return WINED3DFMT_UNKNOWN; + } + } + else + { + /* Luminance-only */ + switch(DDPixelFormat->u1.dwLuminanceBitCount) + { + case 6: + ERR("A luminance Pixelformat shouldn't have 6 luminance bits. Returning D3DFMT_L6V5U5 for now!!\n"); + return WINED3DFMT_L6V5U5; + + case 8: + return WINED3DFMT_L8; + + default: + ERR("Unkown luminance-only bit depth 0x%lx\n", DDPixelFormat->u1.dwLuminanceBitCount); + return WINED3DFMT_UNKNOWN; + } + } + } + else if(DDPixelFormat->dwFlags & DDPF_ZBUFFER) + { + /* Z buffer */ + if(DDPixelFormat->dwFlags & DDPF_STENCILBUFFER) + { + switch(DDPixelFormat->u1.dwZBufferBitDepth) + { + case 8: + ERR("8 Bits Z+Stencil buffer pixelformat is not supported. Returning WINED3DFMT_UNKOWN\n"); + return WINED3DFMT_UNKNOWN; + + case 15: + case 16: + if(DDPixelFormat->u2.dwStencilBitDepth == 1) + return WINED3DFMT_D15S1; + + ERR("Don't know how to handle a 16 bit Z buffer with %ld bit stencil buffer pixelformat\n", DDPixelFormat->u2.dwStencilBitDepth); + return WINED3DFMT_UNKNOWN; + + case 24: + ERR("Don't know how to handle a 24 bit depth buffer with stencil bits\n"); + return WINED3DFMT_D24S8; + + case 32: + if(DDPixelFormat->u2.dwStencilBitDepth == 8) + return WINED3DFMT_D24S8; + else + return WINED3DFMT_D24X4S4; + + default: + ERR("Unkown Z buffer depth %ld\n", DDPixelFormat->u1.dwZBufferBitDepth); + return WINED3DFMT_UNKNOWN; + } + } + else + { + switch(DDPixelFormat->u1.dwZBufferBitDepth) + { + case 8: + ERR("8 Bit Z buffers are not supported. Trying a 16 Bit one\n"); + return WINED3DFMT_D16; + + case 16: + return WINED3DFMT_D16; + + case 24: + return WINED3DFMT_D24X8; + + case 32: + return WINED3DFMT_D32; + + default: + ERR("Unsupported Z buffer depth %ld\n", DDPixelFormat->u1.dwZBufferBitDepth); + return WINED3DFMT_UNKNOWN; + } + } + } + else if(DDPixelFormat->dwFlags & DDPF_FOURCC) + { + if(DDPixelFormat->dwFourCC == MAKEFOURCC('U', 'Y', 'V', 'Y')) + { + return WINED3DFMT_UYVY; + } + if(DDPixelFormat->dwFourCC == MAKEFOURCC('Y', 'U', 'Y', '2')) + { + return WINED3DFMT_YUY2; + } + if(DDPixelFormat->dwFourCC == MAKEFOURCC('D', 'X', 'T', '1')) + { + return WINED3DFMT_DXT1; + } + if(DDPixelFormat->dwFourCC == MAKEFOURCC('D', 'X', 'T', '2')) + { + return WINED3DFMT_DXT2; + } + if(DDPixelFormat->dwFourCC == MAKEFOURCC('D', 'X', 'T', '3')) + { + return WINED3DFMT_DXT3; + } + if(DDPixelFormat->dwFourCC == MAKEFOURCC('D', 'X', 'T', '4')) + { + return WINED3DFMT_DXT4; + } + if(DDPixelFormat->dwFourCC == MAKEFOURCC('D', 'X', 'T', '5')) + { + return WINED3DFMT_DXT5; + } + if(DDPixelFormat->dwFourCC == MAKEFOURCC('G', 'R', 'G', 'B')) + { + return WINED3DFMT_G8R8_G8B8; + } + if(DDPixelFormat->dwFourCC == MAKEFOURCC('R', 'G', 'B', 'G')) + { + return WINED3DFMT_R8G8_B8G8; + } + return WINED3DFMT_UNKNOWN; /* Abuse this as a error value */ + } + else if(DDPixelFormat->dwFlags & DDPF_BUMPDUDV) + { + if( (DDPixelFormat->u1.dwBumpBitCount == 16 ) && + (DDPixelFormat->u2.dwBumpDuBitMask == 0x000000ff) && + (DDPixelFormat->u3.dwBumpDvBitMask == 0x0000ff00) && + (DDPixelFormat->u4.dwBumpLuminanceBitMask == 0x00000000) ) + { + return WINED3DFMT_V8U8; + } + else if ( (DDPixelFormat->u1.dwBumpBitCount == 16 ) && + (DDPixelFormat->u2.dwBumpDuBitMask == 0x0000001f) && + (DDPixelFormat->u3.dwBumpDvBitMask == 0x000003e0) && + (DDPixelFormat->u4.dwBumpLuminanceBitMask == 0x0000fc00) ) + { + return WINED3DFMT_L6V5U5; + } + } + + ERR("Unknown Pixelformat!\n"); + return WINED3DFMT_UNKNOWN; +} + +/***************************************************************************** + * Various dumping functions. + * + * They write the contents of a specific function to a DPRINTF. + * + *****************************************************************************/ +static void +DDRAW_dump_DWORD(const void *in) +{ + DPRINTF("%ld", *((const DWORD *) in)); +} +static void +DDRAW_dump_PTR(const void *in) +{ + DPRINTF("%p", *((const void * const*) in)); +} +void +DDRAW_dump_DDCOLORKEY(const DDCOLORKEY *ddck) +{ + DPRINTF(" Low : %ld - High : %ld", ddck->dwColorSpaceLowValue, ddck->dwColorSpaceHighValue); +} +void DDRAW_dump_DDSCAPS2(const DDSCAPS2 *in) +{ + static const flag_info flags[] = { + FE(DDSCAPS_RESERVED1), + FE(DDSCAPS_ALPHA), + FE(DDSCAPS_BACKBUFFER), + FE(DDSCAPS_COMPLEX), + FE(DDSCAPS_FLIP), + FE(DDSCAPS_FRONTBUFFER), + FE(DDSCAPS_OFFSCREENPLAIN), + FE(DDSCAPS_OVERLAY), + FE(DDSCAPS_PALETTE), + FE(DDSCAPS_PRIMARYSURFACE), + FE(DDSCAPS_PRIMARYSURFACELEFT), + FE(DDSCAPS_SYSTEMMEMORY), + FE(DDSCAPS_TEXTURE), + FE(DDSCAPS_3DDEVICE), + FE(DDSCAPS_VIDEOMEMORY), + FE(DDSCAPS_VISIBLE), + FE(DDSCAPS_WRITEONLY), + FE(DDSCAPS_ZBUFFER), + FE(DDSCAPS_OWNDC), + FE(DDSCAPS_LIVEVIDEO), + FE(DDSCAPS_HWCODEC), + FE(DDSCAPS_MODEX), + FE(DDSCAPS_MIPMAP), + FE(DDSCAPS_RESERVED2), + FE(DDSCAPS_ALLOCONLOAD), + FE(DDSCAPS_VIDEOPORT), + FE(DDSCAPS_LOCALVIDMEM), + FE(DDSCAPS_NONLOCALVIDMEM), + FE(DDSCAPS_STANDARDVGAMODE), + FE(DDSCAPS_OPTIMIZED) + }; + static const flag_info flags2[] = { + FE(DDSCAPS2_HARDWAREDEINTERLACE), + FE(DDSCAPS2_HINTDYNAMIC), + FE(DDSCAPS2_HINTSTATIC), + FE(DDSCAPS2_TEXTUREMANAGE), + FE(DDSCAPS2_RESERVED1), + FE(DDSCAPS2_RESERVED2), + FE(DDSCAPS2_OPAQUE), + FE(DDSCAPS2_HINTANTIALIASING), + FE(DDSCAPS2_CUBEMAP), + FE(DDSCAPS2_CUBEMAP_POSITIVEX), + FE(DDSCAPS2_CUBEMAP_NEGATIVEX), + FE(DDSCAPS2_CUBEMAP_POSITIVEY), + FE(DDSCAPS2_CUBEMAP_NEGATIVEY), + FE(DDSCAPS2_CUBEMAP_POSITIVEZ), + FE(DDSCAPS2_CUBEMAP_NEGATIVEZ), + FE(DDSCAPS2_MIPMAPSUBLEVEL), + FE(DDSCAPS2_D3DTEXTUREMANAGE), + FE(DDSCAPS2_DONOTPERSIST), + FE(DDSCAPS2_STEREOSURFACELEFT) + }; + + DDRAW_dump_flags_(in->dwCaps, flags, sizeof(flags)/sizeof(flags[0]), 0); + DDRAW_dump_flags_(in->dwCaps2, flags2, sizeof(flags2)/sizeof(flags2[0]), 0); +} + +void +DDRAW_dump_DDSCAPS(const DDSCAPS *in) +{ + DDSCAPS2 in_bis; + + in_bis.dwCaps = in->dwCaps; + in_bis.dwCaps2 = 0; + in_bis.dwCaps3 = 0; + in_bis.dwCaps4 = 0; + + DDRAW_dump_DDSCAPS2(&in_bis); +} + +void +DDRAW_dump_flags_(DWORD flags, + const flag_info* names, + size_t num_names, + int newline) +{ + unsigned int i; + + for (i=0; i < num_names; i++) + if ((flags & names[i].val) || /* standard flag value */ + ((!flags) && (!names[i].val))) /* zero value only */ + DPRINTF("%s ", names[i].name); + + if (newline) + DPRINTF("\n"); +} + +void +DDRAW_dump_pixelformat_flag(DWORD flagmask) +{ + static const flag_info flags[] = + { + FE(DDPF_ALPHAPIXELS), + FE(DDPF_ALPHA), + FE(DDPF_FOURCC), + FE(DDPF_PALETTEINDEXED4), + FE(DDPF_PALETTEINDEXEDTO8), + FE(DDPF_PALETTEINDEXED8), + FE(DDPF_RGB), + FE(DDPF_COMPRESSED), + FE(DDPF_RGBTOYUV), + FE(DDPF_YUV), + FE(DDPF_ZBUFFER), + FE(DDPF_PALETTEINDEXED1), + FE(DDPF_PALETTEINDEXED2), + FE(DDPF_ZPIXELS) + }; + + DDRAW_dump_flags_(flagmask, flags, sizeof(flags)/sizeof(flags[0]), 0); +} + +void +DDRAW_dump_members(DWORD flags, + const void* data, + const member_info* mems, + size_t num_mems) +{ + unsigned int i; + + for (i=0; i < num_mems; i++) + { + if (mems[i].val & flags) + { + DPRINTF(" - %s : ", mems[i].name); + mems[i].func((const char *)data + mems[i].offset); + DPRINTF("\n"); + } + } +} + +void +DDRAW_dump_pixelformat(const DDPIXELFORMAT *pf) +{ + DPRINTF("( "); + DDRAW_dump_pixelformat_flag(pf->dwFlags); + if (pf->dwFlags & DDPF_FOURCC) + { + DPRINTF(", dwFourCC code '%c%c%c%c' (0x%08lx) - %ld bits per pixel", + (unsigned char)( pf->dwFourCC &0xff), + (unsigned char)((pf->dwFourCC>> 8)&0xff), + (unsigned char)((pf->dwFourCC>>16)&0xff), + (unsigned char)((pf->dwFourCC>>24)&0xff), + pf->dwFourCC, + pf->u1.dwYUVBitCount + ); + } + if (pf->dwFlags & DDPF_RGB) + { + const char *cmd; + DPRINTF(", RGB bits: %ld, ", pf->u1.dwRGBBitCount); + switch (pf->u1.dwRGBBitCount) + { + case 4: cmd = "%1lx"; break; + case 8: cmd = "%02lx"; break; + case 16: cmd = "%04lx"; break; + case 24: cmd = "%06lx"; break; + case 32: cmd = "%08lx"; break; + default: ERR("Unexpected bit depth !\n"); cmd = "%d"; break; + } + DPRINTF(" R "); DPRINTF(cmd, pf->u2.dwRBitMask); + DPRINTF(" G "); DPRINTF(cmd, pf->u3.dwGBitMask); + DPRINTF(" B "); DPRINTF(cmd, pf->u4.dwBBitMask); + if (pf->dwFlags & DDPF_ALPHAPIXELS) + { + DPRINTF(" A "); DPRINTF(cmd, pf->u5.dwRGBAlphaBitMask); + } + if (pf->dwFlags & DDPF_ZPIXELS) + { + DPRINTF(" Z "); DPRINTF(cmd, pf->u5.dwRGBZBitMask); + } + } + if (pf->dwFlags & DDPF_ZBUFFER) + { + DPRINTF(", Z bits : %ld", pf->u1.dwZBufferBitDepth); + } + if (pf->dwFlags & DDPF_ALPHA) + { + DPRINTF(", Alpha bits : %ld", pf->u1.dwAlphaBitDepth); + } + if (pf->dwFlags & DDPF_BUMPDUDV) + { + const char *cmd = "%08lx"; + DPRINTF(", Bump bits: %ld, ", pf->u1.dwBumpBitCount); + DPRINTF(" U "); DPRINTF(cmd, pf->u2.dwBumpDuBitMask); + DPRINTF(" V "); DPRINTF(cmd, pf->u3.dwBumpDvBitMask); + DPRINTF(" L "); DPRINTF(cmd, pf->u4.dwBumpLuminanceBitMask); + } + DPRINTF(")"); +} + +void DDRAW_dump_surface_desc(const DDSURFACEDESC2 *lpddsd) +{ +#define STRUCT DDSURFACEDESC2 + static const member_info members[] = + { + ME(DDSD_HEIGHT, DDRAW_dump_DWORD, dwHeight), + ME(DDSD_WIDTH, DDRAW_dump_DWORD, dwWidth), + ME(DDSD_PITCH, DDRAW_dump_DWORD, u1 /* lPitch */), + ME(DDSD_LINEARSIZE, DDRAW_dump_DWORD, u1 /* dwLinearSize */), + ME(DDSD_BACKBUFFERCOUNT, DDRAW_dump_DWORD, dwBackBufferCount), + ME(DDSD_MIPMAPCOUNT, DDRAW_dump_DWORD, u2 /* dwMipMapCount */), + ME(DDSD_ZBUFFERBITDEPTH, DDRAW_dump_DWORD, u2 /* dwZBufferBitDepth */), /* This is for 'old-style' D3D */ + ME(DDSD_REFRESHRATE, DDRAW_dump_DWORD, u2 /* dwRefreshRate */), + ME(DDSD_ALPHABITDEPTH, DDRAW_dump_DWORD, dwAlphaBitDepth), + ME(DDSD_LPSURFACE, DDRAW_dump_PTR, lpSurface), + ME(DDSD_CKDESTOVERLAY, DDRAW_dump_DDCOLORKEY, u3 /* ddckCKDestOverlay */), + ME(DDSD_CKDESTBLT, DDRAW_dump_DDCOLORKEY, ddckCKDestBlt), + ME(DDSD_CKSRCOVERLAY, DDRAW_dump_DDCOLORKEY, ddckCKSrcOverlay), + ME(DDSD_CKSRCBLT, DDRAW_dump_DDCOLORKEY, ddckCKSrcBlt), + ME(DDSD_PIXELFORMAT, DDRAW_dump_pixelformat, u4 /* ddpfPixelFormat */) + }; + static const member_info members_caps[] = + { + ME(DDSD_CAPS, DDRAW_dump_DDSCAPS, ddsCaps) + }; + static const member_info members_caps2[] = + { + ME(DDSD_CAPS, DDRAW_dump_DDSCAPS2, ddsCaps) + }; +#undef STRUCT + + if (NULL == lpddsd) + { + DPRINTF("(null)\n"); + } + else + { + if (lpddsd->dwSize >= sizeof(DDSURFACEDESC2)) + { + DDRAW_dump_members(lpddsd->dwFlags, lpddsd, members_caps2, 1); + } + else + { + DDRAW_dump_members(lpddsd->dwFlags, lpddsd, members_caps, 1); + } + DDRAW_dump_members(lpddsd->dwFlags, lpddsd, members, + sizeof(members)/sizeof(members[0])); + } +} + +void +dump_D3DMATRIX(D3DMATRIX *mat) +{ + DPRINTF(" %f %f %f %f\n", mat->_11, mat->_12, mat->_13, mat->_14); + DPRINTF(" %f %f %f %f\n", mat->_21, mat->_22, mat->_23, mat->_24); + DPRINTF(" %f %f %f %f\n", mat->_31, mat->_32, mat->_33, mat->_34); + DPRINTF(" %f %f %f %f\n", mat->_41, mat->_42, mat->_43, mat->_44); +} + +DWORD +get_flexible_vertex_size(DWORD d3dvtVertexType) +{ + DWORD size = 0; + int i; + + if (d3dvtVertexType & D3DFVF_NORMAL) size += 3 * sizeof(D3DVALUE); + if (d3dvtVertexType & D3DFVF_DIFFUSE) size += sizeof(DWORD); + if (d3dvtVertexType & D3DFVF_SPECULAR) size += sizeof(DWORD); + if (d3dvtVertexType & D3DFVF_RESERVED1) size += sizeof(DWORD); + switch (d3dvtVertexType & D3DFVF_POSITION_MASK) + { + case D3DFVF_XYZ: size += 3 * sizeof(D3DVALUE); break; + case D3DFVF_XYZRHW: size += 4 * sizeof(D3DVALUE); break; + default: TRACE(" matrix weighting not handled yet...\n"); + } + for (i = 0; i < GET_TEXCOUNT_FROM_FVF(d3dvtVertexType); i++) + { + size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(D3DVALUE); + } + + return size; +} + +void DDRAW_Convert_DDSCAPS_1_To_2(const DDSCAPS* pIn, DDSCAPS2* pOut) +{ + /* 2 adds three additional caps fields to the end. Both versions + * are unversioned. */ + pOut->dwCaps = pIn->dwCaps; + pOut->dwCaps2 = 0; + pOut->dwCaps3 = 0; + pOut->dwCaps4 = 0; +} + +void DDRAW_Convert_DDDEVICEIDENTIFIER_2_To_1(const DDDEVICEIDENTIFIER2* pIn, DDDEVICEIDENTIFIER* pOut) +{ + /* 2 adds a dwWHQLLevel field to the end. Both structures are + * unversioned. */ + memcpy(pOut, pIn, sizeof(*pOut)); +} + +void DDRAW_dump_cooperativelevel(DWORD cooplevel) +{ + static const flag_info flags[] = + { + FE(DDSCL_FULLSCREEN), + FE(DDSCL_ALLOWREBOOT), + FE(DDSCL_NOWINDOWCHANGES), + FE(DDSCL_NORMAL), + FE(DDSCL_ALLOWMODEX), + FE(DDSCL_EXCLUSIVE), + FE(DDSCL_SETFOCUSWINDOW), + FE(DDSCL_SETDEVICEWINDOW), + FE(DDSCL_CREATEDEVICEWINDOW) + }; + + if (TRACE_ON(ddraw)) + { + DPRINTF(" - "); + DDRAW_dump_flags(cooplevel, flags, sizeof(flags)/sizeof(flags[0])); + } +} + +void DDRAW_dump_DDCAPS(const DDCAPS *lpcaps) +{ + static const flag_info flags1[] = + { + FE(DDCAPS_3D), + FE(DDCAPS_ALIGNBOUNDARYDEST), + FE(DDCAPS_ALIGNSIZEDEST), + FE(DDCAPS_ALIGNBOUNDARYSRC), + FE(DDCAPS_ALIGNSIZESRC), + FE(DDCAPS_ALIGNSTRIDE), + FE(DDCAPS_BLT), + FE(DDCAPS_BLTQUEUE), + FE(DDCAPS_BLTFOURCC), + FE(DDCAPS_BLTSTRETCH), + FE(DDCAPS_GDI), + FE(DDCAPS_OVERLAY), + FE(DDCAPS_OVERLAYCANTCLIP), + FE(DDCAPS_OVERLAYFOURCC), + FE(DDCAPS_OVERLAYSTRETCH), + FE(DDCAPS_PALETTE), + FE(DDCAPS_PALETTEVSYNC), + FE(DDCAPS_READSCANLINE), + FE(DDCAPS_STEREOVIEW), + FE(DDCAPS_VBI), + FE(DDCAPS_ZBLTS), + FE(DDCAPS_ZOVERLAYS), + FE(DDCAPS_COLORKEY), + FE(DDCAPS_ALPHA), + FE(DDCAPS_COLORKEYHWASSIST), + FE(DDCAPS_NOHARDWARE), + FE(DDCAPS_BLTCOLORFILL), + FE(DDCAPS_BANKSWITCHED), + FE(DDCAPS_BLTDEPTHFILL), + FE(DDCAPS_CANCLIP), + FE(DDCAPS_CANCLIPSTRETCHED), + FE(DDCAPS_CANBLTSYSMEM) + }; + static const flag_info flags2[] = + { + FE(DDCAPS2_CERTIFIED), + FE(DDCAPS2_NO2DDURING3DSCENE), + FE(DDCAPS2_VIDEOPORT), + FE(DDCAPS2_AUTOFLIPOVERLAY), + FE(DDCAPS2_CANBOBINTERLEAVED), + FE(DDCAPS2_CANBOBNONINTERLEAVED), + FE(DDCAPS2_COLORCONTROLOVERLAY), + FE(DDCAPS2_COLORCONTROLPRIMARY), + FE(DDCAPS2_CANDROPZ16BIT), + FE(DDCAPS2_NONLOCALVIDMEM), + FE(DDCAPS2_NONLOCALVIDMEMCAPS), + FE(DDCAPS2_NOPAGELOCKREQUIRED), + FE(DDCAPS2_WIDESURFACES), + FE(DDCAPS2_CANFLIPODDEVEN), + FE(DDCAPS2_CANBOBHARDWARE), + FE(DDCAPS2_COPYFOURCC), + FE(DDCAPS2_PRIMARYGAMMA), + FE(DDCAPS2_CANRENDERWINDOWED), + FE(DDCAPS2_CANCALIBRATEGAMMA), + FE(DDCAPS2_FLIPINTERVAL), + FE(DDCAPS2_FLIPNOVSYNC), + FE(DDCAPS2_CANMANAGETEXTURE), + FE(DDCAPS2_TEXMANINNONLOCALVIDMEM), + FE(DDCAPS2_STEREO), + FE(DDCAPS2_SYSTONONLOCAL_AS_SYSTOLOCAL) + }; + static const flag_info flags3[] = + { + FE(DDCKEYCAPS_DESTBLT), + FE(DDCKEYCAPS_DESTBLTCLRSPACE), + FE(DDCKEYCAPS_DESTBLTCLRSPACEYUV), + FE(DDCKEYCAPS_DESTBLTYUV), + FE(DDCKEYCAPS_DESTOVERLAY), + FE(DDCKEYCAPS_DESTOVERLAYCLRSPACE), + FE(DDCKEYCAPS_DESTOVERLAYCLRSPACEYUV), + FE(DDCKEYCAPS_DESTOVERLAYONEACTIVE), + FE(DDCKEYCAPS_DESTOVERLAYYUV), + FE(DDCKEYCAPS_SRCBLT), + FE(DDCKEYCAPS_SRCBLTCLRSPACE), + FE(DDCKEYCAPS_SRCBLTCLRSPACEYUV), + FE(DDCKEYCAPS_SRCBLTYUV), + FE(DDCKEYCAPS_SRCOVERLAY), + FE(DDCKEYCAPS_SRCOVERLAYCLRSPACE), + FE(DDCKEYCAPS_SRCOVERLAYCLRSPACEYUV), + FE(DDCKEYCAPS_SRCOVERLAYONEACTIVE), + FE(DDCKEYCAPS_SRCOVERLAYYUV), + FE(DDCKEYCAPS_NOCOSTOVERLAY) + }; + static const flag_info flags4[] = + { + FE(DDFXCAPS_BLTALPHA), + FE(DDFXCAPS_OVERLAYALPHA), + FE(DDFXCAPS_BLTARITHSTRETCHYN), + FE(DDFXCAPS_BLTARITHSTRETCHY), + FE(DDFXCAPS_BLTMIRRORLEFTRIGHT), + FE(DDFXCAPS_BLTMIRRORUPDOWN), + FE(DDFXCAPS_BLTROTATION), + FE(DDFXCAPS_BLTROTATION90), + FE(DDFXCAPS_BLTSHRINKX), + FE(DDFXCAPS_BLTSHRINKXN), + FE(DDFXCAPS_BLTSHRINKY), + FE(DDFXCAPS_BLTSHRINKYN), + FE(DDFXCAPS_BLTSTRETCHX), + FE(DDFXCAPS_BLTSTRETCHXN), + FE(DDFXCAPS_BLTSTRETCHY), + FE(DDFXCAPS_BLTSTRETCHYN), + FE(DDFXCAPS_OVERLAYARITHSTRETCHY), + FE(DDFXCAPS_OVERLAYARITHSTRETCHYN), + FE(DDFXCAPS_OVERLAYSHRINKX), + FE(DDFXCAPS_OVERLAYSHRINKXN), + FE(DDFXCAPS_OVERLAYSHRINKY), + FE(DDFXCAPS_OVERLAYSHRINKYN), + FE(DDFXCAPS_OVERLAYSTRETCHX), + FE(DDFXCAPS_OVERLAYSTRETCHXN), + FE(DDFXCAPS_OVERLAYSTRETCHY), + FE(DDFXCAPS_OVERLAYSTRETCHYN), + FE(DDFXCAPS_OVERLAYMIRRORLEFTRIGHT), + FE(DDFXCAPS_OVERLAYMIRRORUPDOWN) + }; + static const flag_info flags5[] = + { + FE(DDFXALPHACAPS_BLTALPHAEDGEBLEND), + FE(DDFXALPHACAPS_BLTALPHAPIXELS), + FE(DDFXALPHACAPS_BLTALPHAPIXELSNEG), + FE(DDFXALPHACAPS_BLTALPHASURFACES), + FE(DDFXALPHACAPS_BLTALPHASURFACESNEG), + FE(DDFXALPHACAPS_OVERLAYALPHAEDGEBLEND), + FE(DDFXALPHACAPS_OVERLAYALPHAPIXELS), + FE(DDFXALPHACAPS_OVERLAYALPHAPIXELSNEG), + FE(DDFXALPHACAPS_OVERLAYALPHASURFACES), + FE(DDFXALPHACAPS_OVERLAYALPHASURFACESNEG) + }; + static const flag_info flags6[] = + { + FE(DDPCAPS_4BIT), + FE(DDPCAPS_8BITENTRIES), + FE(DDPCAPS_8BIT), + FE(DDPCAPS_INITIALIZE), + FE(DDPCAPS_PRIMARYSURFACE), + FE(DDPCAPS_PRIMARYSURFACELEFT), + FE(DDPCAPS_ALLOW256), + FE(DDPCAPS_VSYNC), + FE(DDPCAPS_1BIT), + FE(DDPCAPS_2BIT), + FE(DDPCAPS_ALPHA), + }; + static const flag_info flags7[] = + { + FE(DDSVCAPS_RESERVED1), + FE(DDSVCAPS_RESERVED2), + FE(DDSVCAPS_RESERVED3), + FE(DDSVCAPS_RESERVED4), + FE(DDSVCAPS_STEREOSEQUENTIAL), + }; + + DPRINTF(" - dwSize : %ld\n", lpcaps->dwSize); + DPRINTF(" - dwCaps : "); DDRAW_dump_flags(lpcaps->dwCaps, flags1, sizeof(flags1)/sizeof(flags1[0])); + DPRINTF(" - dwCaps2 : "); DDRAW_dump_flags(lpcaps->dwCaps2, flags2, sizeof(flags2)/sizeof(flags2[0])); + DPRINTF(" - dwCKeyCaps : "); DDRAW_dump_flags(lpcaps->dwCKeyCaps, flags3, sizeof(flags3)/sizeof(flags3[0])); + DPRINTF(" - dwFXCaps : "); DDRAW_dump_flags(lpcaps->dwFXCaps, flags4, sizeof(flags4)/sizeof(flags4[0])); + DPRINTF(" - dwFXAlphaCaps : "); DDRAW_dump_flags(lpcaps->dwFXAlphaCaps, flags5, sizeof(flags5)/sizeof(flags5[0])); + DPRINTF(" - dwPalCaps : "); DDRAW_dump_flags(lpcaps->dwPalCaps, flags6, sizeof(flags6)/sizeof(flags6[0])); + DPRINTF(" - dwSVCaps : "); DDRAW_dump_flags(lpcaps->dwSVCaps, flags7, sizeof(flags7)/sizeof(flags7[0])); + DPRINTF("...\n"); + DPRINTF(" - dwNumFourCCCodes : %ld\n", lpcaps->dwNumFourCCCodes); + DPRINTF(" - dwCurrVisibleOverlays : %ld\n", lpcaps->dwCurrVisibleOverlays); + DPRINTF(" - dwMinOverlayStretch : %ld\n", lpcaps->dwMinOverlayStretch); + DPRINTF(" - dwMaxOverlayStretch : %ld\n", lpcaps->dwMaxOverlayStretch); + DPRINTF("...\n"); + DPRINTF(" - ddsCaps : "); DDRAW_dump_DDSCAPS2(&lpcaps->ddsCaps); DPRINTF("\n"); +} + +/***************************************************************************** + * multiply_matrix + * + * Multiplies 2 4x4 matrices src1 and src2, and stores the result in dest. + * + * Params: + * dest: Pointer to the destination matrix + * src1: Pointer to the first source matrix + * src2: Pointer to the secound source matrix + * + *****************************************************************************/ +void +multiply_matrix(D3DMATRIX *dest, + D3DMATRIX *src1, + D3DMATRIX *src2) +{ + D3DMATRIX temp; + + /* Now do the multiplication 'by hand'. + I know that all this could be optimised, but this will be done later :-) */ + temp._11 = (src1->_11 * src2->_11) + (src1->_21 * src2->_12) + (src1->_31 * src2->_13) + (src1->_41 * src2->_14); + temp._21 = (src1->_11 * src2->_21) + (src1->_21 * src2->_22) + (src1->_31 * src2->_23) + (src1->_41 * src2->_24); + temp._31 = (src1->_11 * src2->_31) + (src1->_21 * src2->_32) + (src1->_31 * src2->_33) + (src1->_41 * src2->_34); + temp._41 = (src1->_11 * src2->_41) + (src1->_21 * src2->_42) + (src1->_31 * src2->_43) + (src1->_41 * src2->_44); + + temp._12 = (src1->_12 * src2->_11) + (src1->_22 * src2->_12) + (src1->_32 * src2->_13) + (src1->_42 * src2->_14); + temp._22 = (src1->_12 * src2->_21) + (src1->_22 * src2->_22) + (src1->_32 * src2->_23) + (src1->_42 * src2->_24); + temp._32 = (src1->_12 * src2->_31) + (src1->_22 * src2->_32) + (src1->_32 * src2->_33) + (src1->_42 * src2->_34); + temp._42 = (src1->_12 * src2->_41) + (src1->_22 * src2->_42) + (src1->_32 * src2->_43) + (src1->_42 * src2->_44); + + temp._13 = (src1->_13 * src2->_11) + (src1->_23 * src2->_12) + (src1->_33 * src2->_13) + (src1->_43 * src2->_14); + temp._23 = (src1->_13 * src2->_21) + (src1->_23 * src2->_22) + (src1->_33 * src2->_23) + (src1->_43 * src2->_24); + temp._33 = (src1->_13 * src2->_31) + (src1->_23 * src2->_32) + (src1->_33 * src2->_33) + (src1->_43 * src2->_34); + temp._43 = (src1->_13 * src2->_41) + (src1->_23 * src2->_42) + (src1->_33 * src2->_43) + (src1->_43 * src2->_44); + + temp._14 = (src1->_14 * src2->_11) + (src1->_24 * src2->_12) + (src1->_34 * src2->_13) + (src1->_44 * src2->_14); + temp._24 = (src1->_14 * src2->_21) + (src1->_24 * src2->_22) + (src1->_34 * src2->_23) + (src1->_44 * src2->_24); + temp._34 = (src1->_14 * src2->_31) + (src1->_24 * src2->_32) + (src1->_34 * src2->_33) + (src1->_44 * src2->_34); + temp._44 = (src1->_14 * src2->_41) + (src1->_24 * src2->_42) + (src1->_34 * src2->_43) + (src1->_44 * src2->_44); + + /* And copy the new matrix in the good storage.. */ + memcpy(dest, &temp, 16 * sizeof(D3DVALUE)); +} + + +HRESULT +hr_ddraw_from_wined3d(HRESULT hr) +{ + switch(hr) + { + case WINED3DERR_INVALIDCALL: return DDERR_INVALIDPARAMS; + default: return hr; + } +} diff --git a/dlls/ddraw/vertexbuffer.c b/dlls/ddraw/vertexbuffer.c index f4142c5845..05140384bb 100644 --- a/dlls/ddraw/vertexbuffer.c +++ b/dlls/ddraw/vertexbuffer.c @@ -1,5 +1,6 @@ -/* Direct3D Viewport +/* Direct3D Vertex Buffer * Copyright (c) 2002 Lionel ULMER + * Copyright (c) 2006 Stefan DÖSINGER * * This file contains the implementation of Direct3DVertexBuffer COM object * @@ -19,58 +20,112 @@ */ #include "config.h" +#include "wine/port.h" +#include "wine/debug.h" + +#include #include +#include +#include + +#define COBJMACROS #include "windef.h" #include "winbase.h" +#include "winnls.h" #include "winerror.h" -#include "objbase.h" #include "wingdi.h" +#include "wine/exception.h" +#include "excpt.h" + #include "ddraw.h" #include "d3d.h" -#include "wine/debug.h" -#include "d3d_private.h" -#include "opengl_private.h" +#include "ddraw_private.h" -WINE_DEFAULT_DEBUG_CHANNEL(ddraw); -WINE_DECLARE_DEBUG_CHANNEL(ddraw_geom); +WINE_DEFAULT_DEBUG_CHANNEL(d3d7); +WINE_DECLARE_DEBUG_CHANNEL(ddraw_thunk); -HRESULT WINAPI -Main_IDirect3DVertexBufferImpl_7_1T_QueryInterface(LPDIRECT3DVERTEXBUFFER7 iface, - REFIID riid, - LPVOID* obp) + +/***************************************************************************** + * IUnknown Methods + *****************************************************************************/ + +/***************************************************************************** + * IDirect3DVertexBuffer7::QueryInterface + * + * The QueryInterface Method for Vertex Buffers + * For a link to QueryInterface rules, see IDirectDraw7::QueryInterface + * + * Params + * riid: Queryied Interface id + * obj: Address to return the interface pointer + * + * Returns: + * S_OK on success + * E_NOINTERFACE if the interface wasn't found + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DVertexBufferImpl_QueryInterface(IDirect3DVertexBuffer7 *iface, + REFIID riid, + void **obj) { ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface); - TRACE("(%p/%p)->(%s,%p)\n", This, iface, debugstr_guid(riid), obp); + TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(riid), obj); /* By default, set the object pointer to NULL */ - *obp = NULL; - - if ( IsEqualGUID( &IID_IUnknown, riid ) ) { + *obj = NULL; + + if ( IsEqualGUID( &IID_IUnknown, riid ) ) + { IDirect3DVertexBuffer7_AddRef(ICOM_INTERFACE(This,IDirect3DVertexBuffer7)); - *obp = iface; - TRACE(" Creating IUnknown interface at %p.\n", *obp); - return S_OK; + *obj = iface; + TRACE(" Creating IUnknown interface at %p.\n", *obj); + return S_OK; } - if ( IsEqualGUID( &IID_IDirect3DVertexBuffer, riid ) ) { + if ( IsEqualGUID( &IID_IDirect3DVertexBuffer, riid ) ) + { IDirect3DVertexBuffer7_AddRef(ICOM_INTERFACE(This,IDirect3DVertexBuffer7)); - *obp = ICOM_INTERFACE(This, IDirect3DVertexBuffer); - TRACE(" Creating IDirect3DVertexBuffer interface %p\n", *obp); - return S_OK; + *obj = ICOM_INTERFACE(This, IDirect3DVertexBuffer); + TRACE(" Creating IDirect3DVertexBuffer interface %p\n", *obj); + return S_OK; } - if ( IsEqualGUID( &IID_IDirect3DVertexBuffer7, riid ) ) { + if ( IsEqualGUID( &IID_IDirect3DVertexBuffer7, riid ) ) + { IDirect3DVertexBuffer7_AddRef(ICOM_INTERFACE(This,IDirect3DVertexBuffer7)); - *obp = ICOM_INTERFACE(This, IDirect3DVertexBuffer7); - TRACE(" Creating IDirect3DVertexBuffer7 interface %p\n", *obp); - return S_OK; + *obj = ICOM_INTERFACE(This, IDirect3DVertexBuffer7); + TRACE(" Creating IDirect3DVertexBuffer7 interface %p\n", *obj); + return S_OK; } FIXME("(%p): interface for IID %s NOT found!\n", This, debugstr_guid(riid)); - return OLE_E_ENUM_NOMORE; + return E_NOINTERFACE; } +static HRESULT WINAPI +Thunk_IDirect3DVertexBufferImpl_1_QueryInterface(IDirect3DVertexBuffer *iface, + REFIID riid, + void **obj) +{ + ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, iface); + TRACE_(ddraw_thunk)("(%p)->(%s,%p) thunking to IDirect3DVertexBuffer7 interface.\n", This, debugstr_guid(riid), obj); + + return IDirect3DVertexBuffer7_QueryInterface(ICOM_INTERFACE(This, IDirect3DVertexBuffer7), + riid, + obj); +} + +/***************************************************************************** + * IDirect3DVertexBuffer7::AddRef + * + * AddRef for Vertex Buffers + * + * Returns: + * The new refcount + * + *****************************************************************************/ ULONG WINAPI -Main_IDirect3DVertexBufferImpl_7_1T_AddRef(LPDIRECT3DVERTEXBUFFER7 iface) +IDirect3DVertexBufferImpl_AddRef(IDirect3DVertexBuffer7 *iface) { ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface); ULONG ref = InterlockedIncrement(&This->ref); @@ -81,477 +136,426 @@ Main_IDirect3DVertexBufferImpl_7_1T_AddRef(LPDIRECT3DVERTEXBUFFER7 iface) } ULONG WINAPI -Main_IDirect3DVertexBufferImpl_7_1T_Release(LPDIRECT3DVERTEXBUFFER7 iface) +Thunk_IDirect3DVertexBufferImpl_1_AddRef(IDirect3DVertexBuffer *iface) +{ + ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, iface); + TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DVertexBuffer7 interface.\n", This); + + return IDirect3DVertexBuffer7_AddRef(ICOM_INTERFACE(This, IDirect3DVertexBuffer7)); +} + + +/***************************************************************************** + * IDirect3DVertexBuffer7::Release + * + * Release for Vertex Buffers + * + * Returns: + * The new refcount + * + *****************************************************************************/ +ULONG WINAPI +IDirect3DVertexBufferImpl_Release(IDirect3DVertexBuffer7 *iface) { ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p/%p)->() decrementing from %lu.\n", This, iface, ref + 1); + TRACE("(%p)->() decrementing from %lu.\n", This, ref + 1); - if (ref == 0) { - HeapFree(GetProcessHeap(), 0, This->vertices); - HeapFree(GetProcessHeap(), 0, This); - return 0; + if (ref == 0) + { + IWineD3DVertexBuffer_Release(This->wineD3DVertexBuffer); + HeapFree(GetProcessHeap(), 0, This); + return 0; } return ref; } -HRESULT WINAPI -Main_IDirect3DVertexBufferImpl_7_1T_Lock(LPDIRECT3DVERTEXBUFFER7 iface, - DWORD dwFlags, - LPVOID* lplpData, - LPDWORD lpdwSize) -{ - ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface); - TRACE("(%p/%p)->(%08lx,%p,%p)\n", This, iface, dwFlags, lplpData, lpdwSize); - - if (TRACE_ON(ddraw)) { - TRACE(" lock flags : "); - DDRAW_dump_lockflag(dwFlags); - } - - if (This->processed) { - WARN(" application does a Lock on a vertex buffer resulting from a ProcessVertices call. Expect problems !\n"); - } - - if (This->desc.dwCaps & D3DVBCAPS_OPTIMIZED) return D3DERR_VERTEXBUFFEROPTIMIZED; - - if (lpdwSize != NULL) *lpdwSize = This->vertex_buffer_size; - *lplpData = This->vertices; - - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DVertexBufferImpl_7_1T_Unlock(LPDIRECT3DVERTEXBUFFER7 iface) -{ - ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface); - TRACE("(%p/%p)->()\n", This, iface); - /* Nothing to do here for now. Maybe some optimizations if ever we want to do some :-) */ - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DVertexBufferImpl_7_1T_ProcessVertices(LPDIRECT3DVERTEXBUFFER7 iface, - DWORD dwVertexOp, - DWORD dwDestIndex, - DWORD dwCount, - LPDIRECT3DVERTEXBUFFER7 lpSrcBuffer, - DWORD dwSrcIndex, - LPDIRECT3DDEVICE7 lpD3DDevice, - DWORD dwFlags) -{ - ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface); - FIXME("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx): stub!\n", This, iface, dwVertexOp, dwDestIndex, dwCount, lpSrcBuffer, dwSrcIndex, lpD3DDevice, dwFlags); - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DVertexBufferImpl_7_1T_GetVertexBufferDesc(LPDIRECT3DVERTEXBUFFER7 iface, - LPD3DVERTEXBUFFERDESC lpD3DVertexBufferDesc) -{ - DWORD size; - ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface); - - TRACE("(%p/%p)->(%p)\n", This, iface, lpD3DVertexBufferDesc); - - size = lpD3DVertexBufferDesc->dwSize; - memset(lpD3DVertexBufferDesc, 0, size); - memcpy(lpD3DVertexBufferDesc, &This->desc, - (size < This->desc.dwSize) ? size : This->desc.dwSize); - - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DVertexBufferImpl_7_1T_Optimize(LPDIRECT3DVERTEXBUFFER7 iface, - LPDIRECT3DDEVICE7 lpD3DDevice, - DWORD dwFlags) -{ - ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface); - FIXME("(%p/%p)->(%p,%08lx): stub!\n", This, iface, lpD3DDevice, dwFlags); - - This->desc.dwCaps |= D3DVBCAPS_OPTIMIZED; - - return DD_OK; -} - -HRESULT WINAPI -Main_IDirect3DVertexBufferImpl_7_ProcessVerticesStrided(LPDIRECT3DVERTEXBUFFER7 iface, - DWORD dwVertexOp, - DWORD dwDestIndex, - DWORD dwCount, - LPD3DDRAWPRIMITIVESTRIDEDDATA lpStrideData, - DWORD dwVertexTypeDesc, - LPDIRECT3DDEVICE7 lpD3DDevice, - DWORD dwFlags) -{ - ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface); - FIXME("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx): stub!\n", This, iface, dwVertexOp, dwDestIndex, dwCount, lpStrideData, dwVertexTypeDesc, lpD3DDevice, dwFlags); - return DD_OK; -} - -HRESULT WINAPI -Thunk_IDirect3DVertexBufferImpl_1_ProcessVertices(LPDIRECT3DVERTEXBUFFER iface, - DWORD dwVertexOp, - DWORD dwDestIndex, - DWORD dwCount, - LPDIRECT3DVERTEXBUFFER lpSrcBuffer, - DWORD dwSrcIndex, - LPDIRECT3DDEVICE3 lpD3DDevice, - DWORD dwFlags) -{ - TRACE("(%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx) thunking to IDirect3DVertexBuffer7 interface.\n", iface, - dwVertexOp, dwDestIndex, dwCount, lpSrcBuffer, dwSrcIndex, lpD3DDevice, dwFlags); - return IDirect3DVertexBuffer7_ProcessVertices(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface), - dwVertexOp, - dwDestIndex, - dwCount, - COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, lpSrcBuffer), - dwSrcIndex, - COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, lpD3DDevice), - dwFlags); -} - -HRESULT WINAPI -Thunk_IDirect3DVertexBufferImpl_1_Optimize(LPDIRECT3DVERTEXBUFFER iface, - LPDIRECT3DDEVICE3 lpD3DDevice, - DWORD dwFlags) -{ - TRACE("(%p)->(%p,%08lx) thunking to IDirect3DVertexBuffer7 interface.\n", iface, lpD3DDevice, dwFlags); - return IDirect3DVertexBuffer7_Optimize(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface), - COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, lpD3DDevice), - dwFlags); -} - -HRESULT WINAPI -Thunk_IDirect3DVertexBufferImpl_1_QueryInterface(LPDIRECT3DVERTEXBUFFER iface, - REFIID riid, - LPVOID* obp) -{ - TRACE("(%p)->(%s,%p) thunking to IDirect3DVertexBuffer7 interface.\n", iface, debugstr_guid(riid), obp); - return IDirect3DVertexBuffer7_QueryInterface(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface), - riid, - obp); -} - ULONG WINAPI -Thunk_IDirect3DVertexBufferImpl_1_AddRef(LPDIRECT3DVERTEXBUFFER iface) +Thunk_IDirect3DVertexBufferImpl_1_Release(IDirect3DVertexBuffer *iface) { - TRACE("(%p)->() thunking to IDirect3DVertexBuffer7 interface.\n", iface); - return IDirect3DVertexBuffer7_AddRef(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface)); + ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, iface); + TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DVertexBuffer7 interface.\n", This); + + return IDirect3DVertexBuffer7_Release(ICOM_INTERFACE(This, IDirect3DVertexBuffer7)); } -ULONG WINAPI -Thunk_IDirect3DVertexBufferImpl_1_Release(LPDIRECT3DVERTEXBUFFER iface) -{ - TRACE("(%p)->() thunking to IDirect3DVertexBuffer7 interface.\n", iface); - return IDirect3DVertexBuffer7_Release(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface)); -} +/***************************************************************************** + * IDirect3DVertexBuffer Methods + *****************************************************************************/ -HRESULT WINAPI -Thunk_IDirect3DVertexBufferImpl_1_Lock(LPDIRECT3DVERTEXBUFFER iface, - DWORD dwFlags, - LPVOID* lplpData, - LPDWORD lpdwSize) -{ - TRACE("(%p)->(%08lx,%p,%p) thunking to IDirect3DVertexBuffer7 interface.\n", iface, dwFlags, lplpData, lpdwSize); - return IDirect3DVertexBuffer7_Lock(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface), - dwFlags, - lplpData, - lpdwSize); -} - -HRESULT WINAPI -Thunk_IDirect3DVertexBufferImpl_1_Unlock(LPDIRECT3DVERTEXBUFFER iface) -{ - TRACE("(%p)->() thunking to IDirect3DVertexBuffer7 interface.\n", iface); - return IDirect3DVertexBuffer7_Unlock(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface)); -} - -HRESULT WINAPI -Thunk_IDirect3DVertexBufferImpl_1_GetVertexBufferDesc(LPDIRECT3DVERTEXBUFFER iface, - LPD3DVERTEXBUFFERDESC lpD3DVertexBufferDesc) -{ - TRACE("(%p)->(%p) thunking to IDirect3DVertexBuffer7 interface.\n", iface, lpD3DVertexBufferDesc); - return IDirect3DVertexBuffer7_GetVertexBufferDesc(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface), - lpD3DVertexBufferDesc); -} - -#define copy_and_next(dest, src, size) memcpy(dest, src, size); dest += (size) - -static HRESULT -process_vertices_strided(IDirect3DVertexBufferImpl *This, - DWORD dwVertexOp, - DWORD dwDestIndex, - DWORD dwCount, - LPD3DDRAWPRIMITIVESTRIDEDDATA lpStrideData, - DWORD dwVertexTypeDesc, - IDirect3DDeviceImpl *device_impl, - DWORD dwFlags) -{ - IDirect3DVertexBufferGLImpl *glThis = (IDirect3DVertexBufferGLImpl *) This; - DWORD size = get_flexible_vertex_size(dwVertexTypeDesc); - char *dest_ptr; - unsigned int i; - - This->processed = TRUE; - - /* For the moment, the trick is to save the transform and lighting state at process - time to restore them at drawing time. - - The BIG problem with this method is nothing prevents D3D to do dirty tricks like - processing two different sets of vertices with two different rendering parameters - and then to display them using the same DrawPrimitive call. - - It would be nice to check for such code here (but well, even this is not trivial - to do). - - This is exactly what the TWIST.EXE demo does but using the same kind of ugly stuff - in the D3DExecuteBuffer code. I really wonder why Microsoft went back in time when - implementing this mostly useless (IMHO) API. - */ - glThis->dwVertexTypeDesc = dwVertexTypeDesc; - - if (dwVertexTypeDesc & D3DFVF_NORMAL) { - WARN(" lighting state not saved yet... Some strange stuff may happen !\n"); - } - - if (glThis->vertices == NULL) { - glThis->vertices = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size * This->desc.dwNumVertices); - } - dest_ptr = ((char *) glThis->vertices) + dwDestIndex * size; - - memcpy(&(glThis->world_mat), device_impl->world_mat, sizeof(D3DMATRIX)); - memcpy(&(glThis->view_mat), device_impl->view_mat, sizeof(D3DMATRIX)); - memcpy(&(glThis->proj_mat), device_impl->proj_mat, sizeof(D3DMATRIX)); - - for (i = 0; i < dwCount; i++) { - unsigned int tex_index; - - if ((dwVertexTypeDesc & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) { - D3DVALUE *position = - (D3DVALUE *) (((char *) lpStrideData->position.lpvData) + i * lpStrideData->position.dwStride); - copy_and_next(dest_ptr, position, 3 * sizeof(D3DVALUE)); - } else if ((dwVertexTypeDesc & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW) { - D3DVALUE *position = - (D3DVALUE *) (((char *) lpStrideData->position.lpvData) + i * lpStrideData->position.dwStride); - copy_and_next(dest_ptr, position, 4 * sizeof(D3DVALUE)); - } - if (dwVertexTypeDesc & D3DFVF_RESERVED1) { - dest_ptr += sizeof(DWORD); - } - if (dwVertexTypeDesc & D3DFVF_NORMAL) { - D3DVALUE *normal = - (D3DVALUE *) (((char *) lpStrideData->normal.lpvData) + i * lpStrideData->normal.dwStride); - copy_and_next(dest_ptr, normal, 3 * sizeof(D3DVALUE)); - } - if (dwVertexTypeDesc & D3DFVF_DIFFUSE) { - DWORD *color_d = - (DWORD *) (((char *) lpStrideData->diffuse.lpvData) + i * lpStrideData->diffuse.dwStride); - copy_and_next(dest_ptr, color_d, sizeof(DWORD)); - } - if (dwVertexTypeDesc & D3DFVF_SPECULAR) { - DWORD *color_s = - (DWORD *) (((char *) lpStrideData->specular.lpvData) + i * lpStrideData->specular.dwStride); - copy_and_next(dest_ptr, color_s, sizeof(DWORD)); - } - for (tex_index = 0; tex_index < GET_TEXCOUNT_FROM_FVF(dwVertexTypeDesc); tex_index++) { - D3DVALUE *tex_coord = - (D3DVALUE *) (((char *) lpStrideData->textureCoords[tex_index].lpvData) + - i * lpStrideData->textureCoords[tex_index].dwStride); - copy_and_next(dest_ptr, tex_coord, GET_TEXCOORD_SIZE_FROM_FVF(dwVertexTypeDesc, tex_index) * sizeof(D3DVALUE)); - } - - if (TRACE_ON(ddraw_geom)) { - if ((dwVertexTypeDesc & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) { - D3DVALUE *position = - (D3DVALUE *) (((char *) lpStrideData->position.lpvData) + i * lpStrideData->position.dwStride); - TRACE_(ddraw_geom)(" %f %f %f", position[0], position[1], position[2]); - } else if ((dwVertexTypeDesc & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW) { - D3DVALUE *position = - (D3DVALUE *) (((char *) lpStrideData->position.lpvData) + i * lpStrideData->position.dwStride); - TRACE_(ddraw_geom)(" %f %f %f %f", position[0], position[1], position[2], position[3]); - } - if (dwVertexTypeDesc & D3DFVF_NORMAL) { - D3DVALUE *normal = - (D3DVALUE *) (((char *) lpStrideData->normal.lpvData) + i * lpStrideData->normal.dwStride); - TRACE_(ddraw_geom)(" / %f %f %f", normal[0], normal[1], normal[2]); - } - if (dwVertexTypeDesc & D3DFVF_DIFFUSE) { - DWORD *color_d = - (DWORD *) (((char *) lpStrideData->diffuse.lpvData) + i * lpStrideData->diffuse.dwStride); - TRACE_(ddraw_geom)(" / %02lx %02lx %02lx %02lx", - (*color_d >> 16) & 0xFF, - (*color_d >> 8) & 0xFF, - (*color_d >> 0) & 0xFF, - (*color_d >> 24) & 0xFF); - } - if (dwVertexTypeDesc & D3DFVF_SPECULAR) { - DWORD *color_s = - (DWORD *) (((char *) lpStrideData->specular.lpvData) + i * lpStrideData->specular.dwStride); - TRACE_(ddraw_geom)(" / %02lx %02lx %02lx %02lx", - (*color_s >> 16) & 0xFF, - (*color_s >> 8) & 0xFF, - (*color_s >> 0) & 0xFF, - (*color_s >> 24) & 0xFF); - } - for (tex_index = 0; tex_index < GET_TEXCOUNT_FROM_FVF(dwVertexTypeDesc); tex_index++) { - D3DVALUE *tex_coord = - (D3DVALUE *) (((char *) lpStrideData->textureCoords[tex_index].lpvData) + - i * lpStrideData->textureCoords[tex_index].dwStride); - switch (GET_TEXCOORD_SIZE_FROM_FVF(dwVertexTypeDesc, tex_index)) { - case 1: TRACE_(ddraw_geom)(" / %f", tex_coord[0]); break; - case 2: TRACE_(ddraw_geom)(" / %f %f", tex_coord[0], tex_coord[1]); break; - case 3: TRACE_(ddraw_geom)(" / %f %f %f", tex_coord[0], tex_coord[1], tex_coord[2]); break; - case 4: TRACE_(ddraw_geom)(" / %f %f %f %f", tex_coord[0], tex_coord[1], tex_coord[2], tex_coord[3]); break; - default: TRACE_(ddraw_geom)("Invalid texture size (%ld) !!!", GET_TEXCOORD_SIZE_FROM_FVF(dwVertexTypeDesc, tex_index)); break; - } - } - TRACE_(ddraw_geom)("\n"); - } - } - - return DD_OK; -} - -#undef copy_and_next - -HRESULT WINAPI -GL_IDirect3DVertexBufferImpl_7_1T_ProcessVertices(LPDIRECT3DVERTEXBUFFER7 iface, - DWORD dwVertexOp, - DWORD dwDestIndex, - DWORD dwCount, - LPDIRECT3DVERTEXBUFFER7 lpSrcBuffer, - DWORD dwSrcIndex, - LPDIRECT3DDEVICE7 lpD3DDevice, - DWORD dwFlags) +/***************************************************************************** + * IDirect3DVertexBuffer7::Lock + * + * Locks the vertex buffer and returns a pointer to the vertex data + * Locking vertex buffers is simmilar to locking surfaces, because Windows + * uses surfaces to store vertex data internally(According to the DX sdk) + * + * Params: + * Flags: Locking flags. Relevant here are DDLOCK_READONLY, DDLOCK_WRITEONLY, + * DDLOCK_DISCARDCONTENTS and DDLOCK_NOOVERWRITE. + * Data: Returns a pointer to the vertex data + * Size: Returns the size of the buffer if not NULL + * + * Returns: + * D3D_OK on success + * DDERR_INVALIDPARAMS if Data is NULL + * D3DERR_VERTEXBUFFEROPTIMIZED if called on an optimized buffer(WineD3D) + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DVertexBufferImpl_Lock(IDirect3DVertexBuffer7 *iface, + DWORD Flags, + void **Data, + DWORD *Size) { ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface); - IDirect3DVertexBufferImpl *src_impl = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, lpSrcBuffer); - IDirect3DDeviceImpl *device_impl = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice7, lpD3DDevice); - D3DDRAWPRIMITIVESTRIDEDDATA strided; + WINED3DVERTEXBUFFER_DESC Desc; + HRESULT hr; + TRACE("(%p)->(%08lx,%p,%p)\n", This, Flags, Data, Size); + + /* Get the size, for returning it, and for locking */ + hr = IWineD3DVertexBuffer_GetDesc(This->wineD3DVertexBuffer, + &Desc); + if(hr != D3D_OK) + { + ERR("(%p) IWineD3DVertexBuffer::GetDesc failed with hr=%08lx\n", This, hr); + return hr; + } + + if(Size) *Size = Desc.Size; + + return IWineD3DVertexBuffer_Lock(This->wineD3DVertexBuffer, + 0 /* OffsetToLock */, + Desc.Size, + (BYTE **) Data, + Flags); +} + +static HRESULT WINAPI +Thunk_IDirect3DVertexBufferImpl_1_Lock(IDirect3DVertexBuffer *iface, + DWORD Flags, + void **Data, + DWORD *Size) +{ + ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, iface); + TRACE_(ddraw_thunk)("(%p)->(%08lx,%p,%p) thunking to IDirect3DVertexBuffer7 interface.\n", This, Flags, Data, Size); + + return IDirect3DVertexBuffer7_Lock(ICOM_INTERFACE(This, IDirect3DVertexBuffer7), + Flags, + Data, + Size); +} + +/***************************************************************************** + * IDirect3DVertexBuffer7::Unlock + * + * Unlocks a vertex Buffer + * + * Returns: + * D3D_OK on success + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DVertexBufferImpl_Unlock(IDirect3DVertexBuffer7 *iface) +{ + ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface); + TRACE("(%p)->()\n", This); + + /* This is easy :) */ + return IWineD3DVertexBuffer_Unlock(This->wineD3DVertexBuffer); +} + +static HRESULT WINAPI +Thunk_IDirect3DVertexBufferImpl_1_Unlock(IDirect3DVertexBuffer *iface) +{ + ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, iface); + TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DVertexBuffer7 interface.\n", This); + + return IDirect3DVertexBuffer7_Unlock(ICOM_INTERFACE(This, IDirect3DVertexBuffer7)); +} + + +/***************************************************************************** + * IDirect3DVertexBuffer7::ProcessVertices + * + * Processes untransformed Vertices into a transformed or optimized vertex + * buffer. It can also perform other operations, such as lighting or clipping + * + * Params + * VertexOp: Operation(s) to perform: D3DVOP_CLIP, _EXTENTS, _LIGHT, _TRANSFORM + * DestIndex: Index in the destination buffer(This), where the vertices are + * placed + * Count: Number of Vertices in the Source buffer to process + * SrcBuffer: Source vertex buffer + * SrcIndex: Index of the first vertex in the src buffer to process + * D3DDevice: Device to use for transformation + * Flags: 0 for default, D3DPV_DONOTCOPYDATA to prevent copying + * unchaned vertices + * + * Returns: + * D3D_OK on success + * DDERR_INVALIDPARAMS If D3DVOP_TRANSFORM wasn't passed + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DVertexBufferImpl_ProcessVertices(IDirect3DVertexBuffer7 *iface, + DWORD VertexOp, + DWORD DestIndex, + DWORD Count, + IDirect3DVertexBuffer7 *SrcBuffer, + DWORD SrcIndex, + IDirect3DDevice7 *D3DDevice, + DWORD Flags) +{ + ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface); + IDirect3DVertexBufferImpl *Src = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, SrcBuffer); + IDirect3DDeviceImpl *D3D = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice7, D3DDevice); + BOOL oldClip, doClip; + HRESULT hr; + + TRACE("(%p)->(%08lx,%ld,%ld,%p,%ld,%p,%08lx)\n", This, VertexOp, DestIndex, Count, Src, SrcIndex, D3D, Flags); + + /* Vertex operations: + * D3DVOP_CLIP: Clips vertices outside the viewing frustrum. Needs clipping information + * in the vertex buffer (Buffer may not be created with D3DVBCAPS_DONOTCLIP) + * D3DVOP_EXTENTS: Causes the screen extents to be updated when rendering the vertices + * D3DVOP_LIGHT: Lights the vertices + * D3DVOP_TRANSFORM: Transform the vertices. This flag is necessary + * + * WineD3D only transforms and clips the vertices by now, so EXTENTS and LIGHT + * are not implemented. Clipping is disabled ATM, because of unsure conditions. + */ + if( !(VertexOp & D3DVOP_TRANSFORM) ) return DDERR_INVALIDPARAMS; + + /* WineD3D doesn't know d3d7 vertex operation, it uses + * render states instead. Set the render states according to + * the vertex ops + */ + doClip = VertexOp & D3DVOP_CLIP ? TRUE : FALSE; + IWineD3DDevice_GetRenderState(D3D->wineD3DDevice, + WINED3DRS_CLIPPING, + (DWORD *) &oldClip); + if(doClip != oldClip) + { + IWineD3DDevice_SetRenderState(D3D->wineD3DDevice, + WINED3DRS_CLIPPING, + doClip); + } + + + hr = IWineD3DDevice_ProcessVertices(D3D->wineD3DDevice, + SrcIndex, + DestIndex, + Count, + This->wineD3DVertexBuffer, + Src->wineD3DVertexBuffer, + Flags); + + /* Restore the states if needed */ + if(doClip != oldClip) + IWineD3DDevice_SetRenderState(D3D->wineD3DDevice, + WINED3DRS_CLIPPING, + oldClip); + return hr; +} + +static HRESULT WINAPI +Thunk_IDirect3DVertexBufferImpl_1_ProcessVertices(IDirect3DVertexBuffer *iface, + DWORD VertexOp, + DWORD DestIndex, + DWORD Count, + IDirect3DVertexBuffer *SrcBuffer, + DWORD SrcIndex, + IDirect3DDevice3 *D3DDevice, + DWORD Flags) +{ + ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, iface); + IDirect3DVertexBufferImpl *Src = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, SrcBuffer); + IDirect3DDeviceImpl *D3D = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice3, D3DDevice); + + TRACE_(ddraw_thunk)("(%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx) thunking to IDirect3DVertexBuffer7 interface.\n", This, VertexOp, DestIndex, Count, Src, SrcIndex, D3D, Flags); + + return IDirect3DVertexBuffer7_ProcessVertices(ICOM_INTERFACE(This, IDirect3DVertexBuffer7), + VertexOp, + DestIndex, + Count, + ICOM_INTERFACE(Src, IDirect3DVertexBuffer7), + SrcIndex, + ICOM_INTERFACE(D3D, IDirect3DDevice7), + Flags); +} + +/***************************************************************************** + * IDirect3DVertexBuffer7::GetVertexBufferDesc + * + * Returns the description of a vertex buffer + * + * Params: + * Desc: Address to write the description to + * + * Returns + * DDERR_INVALIDPARAMS if Desc is NULL + * D3D_OK on success + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DVertexBufferImpl_GetVertexBufferDesc(IDirect3DVertexBuffer7 *iface, + D3DVERTEXBUFFERDESC *Desc) +{ + ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface); + WINED3DVERTEXBUFFER_DESC WDesc; + HRESULT hr; DWORD size; + TRACE("(%p)->(%p)\n", This, Desc); - TRACE("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx)\n", This, iface, dwVertexOp, dwDestIndex, dwCount, lpSrcBuffer, dwSrcIndex, lpD3DDevice, dwFlags); + if(!Desc) return DDERR_INVALIDPARAMS; - if (TRACE_ON(ddraw)) { - TRACE(" - vertex operations : "); dump_D3DVOP(dwVertexOp); - TRACE(" - flags : "); dump_D3DPV(dwFlags); + hr = IWineD3DVertexBuffer_GetDesc(This->wineD3DVertexBuffer, + &WDesc); + if(hr != D3D_OK) + { + ERR("(%p) IWineD3DVertexBuffer::GetDesc failed with hr=%08lx\n", This, hr); + return hr; } - if ((dwVertexOp & D3DVOP_TRANSFORM) == 0) return DDERR_INVALIDPARAMS; + /* Clear the return value of garbage */ + size = Desc->dwSize; + memset(Desc, 0, size); - size = get_flexible_vertex_size(src_impl->desc.dwFVF); - convert_FVF_to_strided_data(src_impl->desc.dwFVF, ((char *) src_impl->vertices) + dwSrcIndex * size, &strided, 0); + /* Now fill the Desc structure */ + Desc->dwSize = size; + Desc->dwCaps = This->Caps; + Desc->dwFVF = WDesc.FVF; + Desc->dwNumVertices = WDesc.Size / get_flexible_vertex_size(WDesc.FVF); - return process_vertices_strided(This, dwVertexOp, dwDestIndex, dwCount, &strided, src_impl->desc.dwFVF, device_impl, dwFlags); -} - -HRESULT WINAPI -GL_IDirect3DVertexBufferImpl_7_ProcessVerticesStrided(LPDIRECT3DVERTEXBUFFER7 iface, - DWORD dwVertexOp, - DWORD dwDestIndex, - DWORD dwCount, - LPD3DDRAWPRIMITIVESTRIDEDDATA lpStrideData, - DWORD dwVertexTypeDesc, - LPDIRECT3DDEVICE7 lpD3DDevice, - DWORD dwFlags) -{ - ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface); - IDirect3DDeviceImpl *device_impl = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice7, lpD3DDevice); - - TRACE("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx)\n", This, iface, dwVertexOp, dwDestIndex, dwCount, lpStrideData, dwVertexTypeDesc, lpD3DDevice, dwFlags); - if (TRACE_ON(ddraw)) { - TRACE(" - vertex operations : "); dump_D3DVOP(dwVertexOp); - TRACE(" - flags : "); dump_D3DPV(dwFlags); - TRACE(" - vertex format : "); dump_flexible_vertex(dwVertexTypeDesc); - } - - if ((dwVertexOp & D3DVOP_TRANSFORM) == 0) return DDERR_INVALIDPARAMS; - - return process_vertices_strided(This, dwVertexOp, dwDestIndex, dwCount, lpStrideData, dwVertexTypeDesc, device_impl, dwFlags); -} - - - -#if !defined(__STRICT_ANSI__) && defined(__GNUC__) -# define XCAST(fun) (typeof(VTABLE_IDirect3DVertexBuffer7.fun)) -#else -# define XCAST(fun) (void*) -#endif - -static const IDirect3DVertexBuffer7Vtbl VTABLE_IDirect3DVertexBuffer7 = -{ - XCAST(QueryInterface) Main_IDirect3DVertexBufferImpl_7_1T_QueryInterface, - XCAST(AddRef) Main_IDirect3DVertexBufferImpl_7_1T_AddRef, - XCAST(Release) Main_IDirect3DVertexBufferImpl_7_1T_Release, - XCAST(Lock) Main_IDirect3DVertexBufferImpl_7_1T_Lock, - XCAST(Unlock) Main_IDirect3DVertexBufferImpl_7_1T_Unlock, - XCAST(ProcessVertices) GL_IDirect3DVertexBufferImpl_7_1T_ProcessVertices, - XCAST(GetVertexBufferDesc) Main_IDirect3DVertexBufferImpl_7_1T_GetVertexBufferDesc, - XCAST(Optimize) Main_IDirect3DVertexBufferImpl_7_1T_Optimize, - XCAST(ProcessVerticesStrided) GL_IDirect3DVertexBufferImpl_7_ProcessVerticesStrided -}; - -#if !defined(__STRICT_ANSI__) && defined(__GNUC__) -#undef XCAST -#endif - - -#if !defined(__STRICT_ANSI__) && defined(__GNUC__) -# define XCAST(fun) (typeof(VTABLE_IDirect3DVertexBuffer.fun)) -#else -# define XCAST(fun) (void*) -#endif - -static const IDirect3DVertexBufferVtbl VTABLE_IDirect3DVertexBuffer = -{ - XCAST(QueryInterface) Thunk_IDirect3DVertexBufferImpl_1_QueryInterface, - XCAST(AddRef) Thunk_IDirect3DVertexBufferImpl_1_AddRef, - XCAST(Release) Thunk_IDirect3DVertexBufferImpl_1_Release, - XCAST(Lock) Thunk_IDirect3DVertexBufferImpl_1_Lock, - XCAST(Unlock) Thunk_IDirect3DVertexBufferImpl_1_Unlock, - XCAST(ProcessVertices) Thunk_IDirect3DVertexBufferImpl_1_ProcessVertices, - XCAST(GetVertexBufferDesc) Thunk_IDirect3DVertexBufferImpl_1_GetVertexBufferDesc, - XCAST(Optimize) Thunk_IDirect3DVertexBufferImpl_1_Optimize -}; - -#if !defined(__STRICT_ANSI__) && defined(__GNUC__) -#undef XCAST -#endif - -HRESULT d3dvertexbuffer_create(IDirect3DVertexBufferImpl **obj, IDirectDrawImpl *d3d, LPD3DVERTEXBUFFERDESC lpD3DVertBufDesc, DWORD dwFlags) -{ - IDirect3DVertexBufferImpl *object; - static const flag_info flags[] = { - FE(D3DVBCAPS_DONOTCLIP), - FE(D3DVBCAPS_OPTIMIZED), - FE(D3DVBCAPS_SYSTEMMEMORY), - FE(D3DVBCAPS_WRITEONLY) - }; - - object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVertexBufferGLImpl)); - if (object == NULL) return DDERR_OUTOFMEMORY; - - object->ref = 1; - object->d3d = d3d; - object->desc = *lpD3DVertBufDesc; - object->vertex_buffer_size = get_flexible_vertex_size(lpD3DVertBufDesc->dwFVF) * lpD3DVertBufDesc->dwNumVertices; - object->vertices = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->vertex_buffer_size); - - ICOM_INIT_INTERFACE(object, IDirect3DVertexBuffer, VTABLE_IDirect3DVertexBuffer); - ICOM_INIT_INTERFACE(object, IDirect3DVertexBuffer7, VTABLE_IDirect3DVertexBuffer7); - - *obj = object; - - if (TRACE_ON(ddraw)) { - TRACE(" creating implementation at %p with description :\n", *obj); - TRACE(" flags : "); DDRAW_dump_flags_(lpD3DVertBufDesc->dwCaps, flags, sizeof(flags)/sizeof(flags[0]), TRUE); - TRACE(" vertex type : "); dump_flexible_vertex(lpD3DVertBufDesc->dwFVF); - TRACE(" num vertices : %ld\n", lpD3DVertBufDesc->dwNumVertices); - } - - return D3D_OK; } + +static HRESULT WINAPI +Thunk_IDirect3DVertexBufferImpl_1_GetVertexBufferDesc(IDirect3DVertexBuffer *iface, + D3DVERTEXBUFFERDESC *Desc) +{ + ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, iface); + TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DVertexBuffer7 interface.\n", This, Desc); + + return IDirect3DVertexBuffer7_GetVertexBufferDesc(ICOM_INTERFACE(This, IDirect3DVertexBuffer7), + Desc); +} + + +/***************************************************************************** + * IDirect3DVertexBuffer7::Optimize + * + * Converts an unoptimized vertex buffer into an optimized buffer + * + * Params: + * D3DDevice: Device for which this buffer is optimized + * Flags: Not used, should be set to 0 + * + * Returns + * D3D_OK, because it's a stub + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DVertexBufferImpl_Optimize(IDirect3DVertexBuffer7 *iface, + IDirect3DDevice7 *D3DDevice, + DWORD Flags) +{ + ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface); + IDirect3DDeviceImpl *D3D = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice7, D3DDevice); + FIXME("(%p)->(%p,%08lx): stub!\n", This, D3D, Flags); + + /* We could forward this call to WineD3D and take advantage + * of it once we use OpenGL vertex buffers + */ + This->Caps |= D3DVBCAPS_OPTIMIZED; + + return DD_OK; +} + +static HRESULT WINAPI +Thunk_IDirect3DVertexBufferImpl_1_Optimize(IDirect3DVertexBuffer *iface, + IDirect3DDevice3 *D3DDevice, + DWORD Flags) +{ + ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, iface); + IDirect3DDeviceImpl *D3D = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice3, D3DDevice); + TRACE_(ddraw_thunk)("(%p)->(%p,%08lx) thunking to IDirect3DVertexBuffer7 interface.\n", This, D3D, Flags); + + return IDirect3DVertexBuffer7_Optimize(ICOM_INTERFACE(This, IDirect3DVertexBuffer7), + ICOM_INTERFACE(D3D, IDirect3DDevice7), + Flags); +} + +/***************************************************************************** + * IDirect3DVertexBuffer7::ProcessVerticesStrided + * + * This method processes untransformed strided vertices into a processed + * or optimized vertex buffer. + * + * For more details on the parameters, see + * IDirect3DVertexBuffer7::ProcessVertices + * + * Params: + * VertexOp: Operations to perform + * DestIndex: Destination index to write the vertices to + * Count: Number of input vertices + * StrideData: Array containing the input vertices + * VertexTypeDesc: Vertex Description or source index????????? + * D3DDevice: IDirect3DDevice7 to use for processing + * Flags: Can be D3DPV_DONOTCOPYDATA to avoid copying unmodified vertices + * + * Returns + * D3D_OK on success, or DDERR_* + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DVertexBufferImpl_ProcessVerticesStrided(IDirect3DVertexBuffer7 *iface, + DWORD VertexOp, + DWORD DestIndex, + DWORD Count, + D3DDRAWPRIMITIVESTRIDEDDATA *StrideData, + DWORD VertexTypeDesc, + IDirect3DDevice7 *D3DDevice, + DWORD Flags) +{ + ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface); + IDirect3DDeviceImpl *D3D = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice7, D3DDevice); + FIXME("(%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx): stub!\n", This, VertexOp, DestIndex, Count, StrideData, VertexTypeDesc, D3D, Flags); + return DD_OK; +} + +/***************************************************************************** + * The VTables + *****************************************************************************/ + +const IDirect3DVertexBuffer7Vtbl IDirect3DVertexBuffer7_Vtbl = +{ + /*** IUnknown Methods ***/ + IDirect3DVertexBufferImpl_QueryInterface, + IDirect3DVertexBufferImpl_AddRef, + IDirect3DVertexBufferImpl_Release, + /*** IDirect3DVertexBuffer Methods ***/ + IDirect3DVertexBufferImpl_Lock, + IDirect3DVertexBufferImpl_Unlock, + IDirect3DVertexBufferImpl_ProcessVertices, + IDirect3DVertexBufferImpl_GetVertexBufferDesc, + IDirect3DVertexBufferImpl_Optimize, + /*** IDirect3DVertexBuffer7 Methods ***/ + IDirect3DVertexBufferImpl_ProcessVerticesStrided +}; + +const IDirect3DVertexBufferVtbl IDirect3DVertexBuffer1_Vtbl = +{ + /*** IUnknown Methods ***/ + Thunk_IDirect3DVertexBufferImpl_1_QueryInterface, + Thunk_IDirect3DVertexBufferImpl_1_AddRef, + Thunk_IDirect3DVertexBufferImpl_1_Release, + /*** IDirect3DVertexBuffer Methods ***/ + Thunk_IDirect3DVertexBufferImpl_1_Lock, + Thunk_IDirect3DVertexBufferImpl_1_Unlock, + Thunk_IDirect3DVertexBufferImpl_1_ProcessVertices, + Thunk_IDirect3DVertexBufferImpl_1_GetVertexBufferDesc, + Thunk_IDirect3DVertexBufferImpl_1_Optimize +}; diff --git a/dlls/ddraw/viewport.c b/dlls/ddraw/viewport.c index 4b83f59283..ab06eceb78 100644 --- a/dlls/ddraw/viewport.c +++ b/dlls/ddraw/viewport.c @@ -1,5 +1,6 @@ /* Direct3D Viewport * Copyright (c) 1998 Lionel ULMER + * Copyright (c) 2006 Stefan DÖSINGER * * This file contains the implementation of Direct3DViewport2. * @@ -19,26 +20,43 @@ */ #include "config.h" +#include "wine/port.h" +#include #include +#include +#include +#define COBJMACROS #define NONAMELESSUNION -#define NONAMELESSSTRUCT #include "windef.h" #include "winbase.h" +#include "winnls.h" #include "winerror.h" -#include "objbase.h" #include "wingdi.h" +#include "wine/exception.h" +#include "excpt.h" + #include "ddraw.h" #include "d3d.h" + +#include "ddraw_private.h" #include "wine/debug.h" -#include "d3d_private.h" +WINE_DEFAULT_DEBUG_CHANNEL(d3d7); -WINE_DEFAULT_DEBUG_CHANNEL(ddraw); +/***************************************************************************** + * Helper functions + *****************************************************************************/ -static void activate(IDirect3DViewportImpl* This) { +/***************************************************************************** + * viewport_activate + * + * activates the viewport using IDirect3DDevice7::SetViewport + * + *****************************************************************************/ +void viewport_activate(IDirect3DViewportImpl* This) { IDirect3DLightImpl* light; D3DVIEWPORT7 vp; @@ -71,7 +89,12 @@ static void activate(IDirect3DViewportImpl* This) { IDirect3DDevice7_SetViewport(ICOM_INTERFACE(This->active_device, IDirect3DDevice7), &vp); } - +/***************************************************************************** + * _dump_D3DVIEWPORT, _dump_D3DVIEWPORT2 + * + * Writes viewport information to TRACE + * + *****************************************************************************/ static void _dump_D3DVIEWPORT(D3DVIEWPORT *lpvp) { TRACE(" - dwSize = %ld dwX = %ld dwY = %ld\n", @@ -100,13 +123,33 @@ static void _dump_D3DVIEWPORT2(D3DVIEWPORT2 *lpvp) lpvp->dvMinZ, lpvp->dvMaxZ); } -HRESULT WINAPI -Main_IDirect3DViewportImpl_3_2_1_QueryInterface(LPDIRECT3DVIEWPORT3 iface, - REFIID riid, - LPVOID* obp) +/***************************************************************************** + * IUnknown Methods. + *****************************************************************************/ + +/***************************************************************************** + * IDirect3DViewport3::QueryInterface + * + * A normal QueryInterface. Can query all interface versions and the + * IUnknown interface. The VTables of the different versions + * are equal + * + * Params: + * refiid: Interface id queried for + * obj: Address to write the interface pointer to + * + * Returns: + * S_OK on success. + * E_NOINTERFACE if the requested interface wasn't found + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DViewportImpl_QueryInterface(IDirect3DViewport3 *iface, + REFIID riid, + void **obp) { ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface); - TRACE("(%p/%p)->(%s,%p)\n", This, iface, debugstr_guid(riid), obp); + TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(riid), obp); *obp = NULL; @@ -120,27 +163,45 @@ Main_IDirect3DViewportImpl_3_2_1_QueryInterface(LPDIRECT3DVIEWPORT3 iface, return S_OK; } FIXME("(%p): interface for IID %s NOT found!\n", This, debugstr_guid(riid)); - return OLE_E_ENUM_NOMORE; + return E_NOINTERFACE; } -ULONG WINAPI -Main_IDirect3DViewportImpl_3_2_1_AddRef(LPDIRECT3DVIEWPORT3 iface) +/***************************************************************************** + * IDirect3DViewport3::AddRef + * + * Increases the refcount. + * + * Returns: + * The new refcount + * + *****************************************************************************/ +static ULONG WINAPI +IDirect3DViewportImpl_AddRef(IDirect3DViewport3 *iface) { ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p/%p)->() incrementing from %lu.\n", This, iface, ref - 1); + TRACE("(%p)->() incrementing from %lu.\n", This, ref - 1); return ref; } -ULONG WINAPI -Main_IDirect3DViewportImpl_3_2_1_Release(LPDIRECT3DVIEWPORT3 iface) +/***************************************************************************** + * IDirect3DViewport3::Release + * + * Reduces the refcount. If it falls to 0, the interface is released + * + * Returns: + * The new refcount + * + *****************************************************************************/ +static ULONG WINAPI +IDirect3DViewportImpl_Release(IDirect3DViewport3 *iface) { ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface); ULONG ref = InterlockedDecrement(&This->ref); - TRACE("(%p/%p)->() decrementing from %lu.\n", This, iface, ref + 1); + TRACE("(%p)->() decrementing from %lu.\n", This, ref + 1); if (!ref) { HeapFree(GetProcessHeap(), 0, This); @@ -149,19 +210,46 @@ Main_IDirect3DViewportImpl_3_2_1_Release(LPDIRECT3DVIEWPORT3 iface) return ref; } +/***************************************************************************** + * IDirect3DViewport Methods. + *****************************************************************************/ -HRESULT WINAPI -Main_IDirect3DViewportImpl_3_2_1_Initialize(LPDIRECT3DVIEWPORT3 iface, - LPDIRECT3D lpDirect3D) +/***************************************************************************** + * IDirect3DViewport3::Initialize + * + * No-op initialization. + * + * Params: + * Direct3D: The direct3D device this viewport is assigned to + * + * Returns: + * DDERR_ALREADYINITIALIZED + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DViewportImpl_Initialize(IDirect3DViewport3 *iface, + IDirect3D *Direct3D) { - ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface); - TRACE("(%p/%p)->(%p) no-op...\n", This, iface, lpDirect3D); - return DD_OK; + TRACE("(%p)->(%p) no-op...\n", iface, Direct3D); + return DDERR_ALREADYINITIALIZED; } -HRESULT WINAPI -Main_IDirect3DViewportImpl_3_2_1_GetViewport(LPDIRECT3DVIEWPORT3 iface, - LPD3DVIEWPORT lpData) +/***************************************************************************** + * IDirect3DViewport3::GetViewport + * + * Returns the viewport data assigned to this viewport interface + * + * Params: + * Data: Address to store the data + * + * Returns: + * D3D_OK on success + * DDERR_INVALIDPARAMS if Data is NULL + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DViewportImpl_GetViewport(IDirect3DViewport3 *iface, + D3DVIEWPORT *lpData) { ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface); DWORD dwSize; @@ -174,7 +262,7 @@ Main_IDirect3DViewportImpl_3_2_1_GetViewport(LPDIRECT3DVIEWPORT3 iface, memset(lpData, 0, dwSize); memcpy(lpData, &(This->viewports.vp1), dwSize); - if (TRACE_ON(ddraw)) { + if (TRACE_ON(d3d7)) { TRACE(" returning D3DVIEWPORT :\n"); _dump_D3DVIEWPORT(lpData); } @@ -182,15 +270,28 @@ Main_IDirect3DViewportImpl_3_2_1_GetViewport(LPDIRECT3DVIEWPORT3 iface, return DD_OK; } +/***************************************************************************** + * IDirect3DViewport3::SetViewport + * + * Sets the viewport information for this interface + * + * Params: + * lpData: Viewport to set + * + * Returns: + * D3D_OK on succes + * DDERR_INVALIDPARAMS if Data is NULL + * + *****************************************************************************/ HRESULT WINAPI -Main_IDirect3DViewportImpl_3_2_1_SetViewport(LPDIRECT3DVIEWPORT3 iface, - LPD3DVIEWPORT lpData) +IDirect3DViewportImpl_SetViewport(IDirect3DViewport3 *iface, + D3DVIEWPORT *lpData) { ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface); LPDIRECT3DVIEWPORT3 current_viewport; TRACE("(%p/%p)->(%p)\n", This, iface, lpData); - if (TRACE_ON(ddraw)) { + if (TRACE_ON(d3d7)) { TRACE(" getting D3DVIEWPORT :\n"); _dump_D3DVIEWPORT(lpData); } @@ -215,36 +316,75 @@ Main_IDirect3DViewportImpl_3_2_1_SetViewport(LPDIRECT3DVIEWPORT3 iface, return DD_OK; } -HRESULT WINAPI -Main_IDirect3DViewportImpl_3_2_1_TransformVertices(LPDIRECT3DVIEWPORT3 iface, - DWORD dwVertexCount, - LPD3DTRANSFORMDATA lpData, - DWORD dwFlags, - LPDWORD lpOffScreen) +/***************************************************************************** + * IDirect3DViewport3::TransformVertices + * + * Transforms vertices by the transformation matrix. + * + * Params: + * dwVertexCount: The number of vertices to be transformed + * lpData: Pointer to the vertex data + * dwFlags: D3DTRANSFORM_CLIPPED or D3DTRANSFORM_UNCLIPPED + * lpOffScreen: Is set to nonzero if all vertices are off-screen + * + * Returns: + * D3D_OK because it's a stub + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DViewportImpl_TransformVertices(IDirect3DViewport3 *iface, + DWORD dwVertexCount, + D3DTRANSFORMDATA *lpData, + DWORD dwFlags, + DWORD *lpOffScreen) { ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface); - FIXME("(%p/%p)->(%08lx,%p,%08lx,%p): stub!\n", This, iface, dwVertexCount, lpData, dwFlags, lpOffScreen); + FIXME("(%p)->(%08lx,%p,%08lx,%p): stub!\n", This, dwVertexCount, lpData, dwFlags, lpOffScreen); if (lpOffScreen) *lpOffScreen = 0; return DD_OK; } -HRESULT WINAPI -Main_IDirect3DViewportImpl_3_2_1_LightElements(LPDIRECT3DVIEWPORT3 iface, - DWORD dwElementCount, - LPD3DLIGHTDATA lpData) +/***************************************************************************** + * IDirect3DViewport3::LightElements + * + * The DirectX 5.0 sdk says that it's not implemented + * + * Params: + * ? + * + * Returns: + * DDERR_UNSUPPORTED + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DViewportImpl_LightElements(IDirect3DViewport3 *iface, + DWORD dwElementCount, + LPD3DLIGHTDATA lpData) { ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface); - FIXME("(%p/%p)->(%08lx,%p): stub!\n", This, iface, dwElementCount, lpData); - return DD_OK; + TRACE("(%p)->(%08lx,%p): Unimplemented!\n", This, dwElementCount, lpData); + return DDERR_UNSUPPORTED; } -HRESULT WINAPI -Main_IDirect3DViewportImpl_3_2_1_SetBackground(LPDIRECT3DVIEWPORT3 iface, - D3DMATERIALHANDLE hMat) +/***************************************************************************** + * IDirect3DViewport3::SetBackground + * + * Sets tje background material + * + * Params: + * hMat: Handle from a IDirect3DMaterial interface + * + * Returns: + * D3D_OK on success + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DViewportImpl_SetBackground(IDirect3DViewport3 *iface, + D3DMATERIALHANDLE hMat) { ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface); - TRACE("(%p/%p)->(%08lx)\n", This, iface, (DWORD) hMat); + TRACE("(%p)->(%08lx)\n", This, (DWORD) hMat); This->background = (IDirect3DMaterialImpl *) hMat; TRACE(" setting background color : %f %f %f %f\n", @@ -253,43 +393,100 @@ Main_IDirect3DViewportImpl_3_2_1_SetBackground(LPDIRECT3DVIEWPORT3 iface, This->background->mat.u.diffuse.u3.b, This->background->mat.u.diffuse.u4.a); - return DD_OK; + return D3D_OK; } -HRESULT WINAPI -Main_IDirect3DViewportImpl_3_2_1_GetBackground(LPDIRECT3DVIEWPORT3 iface, - LPD3DMATERIALHANDLE lphMat, - LPBOOL lpValid) +/***************************************************************************** + * IDirect3DViewport3::GetBackground + * + * Returns the material handle assigned to the background of the viewport + * + * Params: + * lphMat: Address to store the handle + * lpValid: is set to FALSE if no background is set, TRUE if one is set + * + * Returns: + * D3D_OK, because it's a stub + * (DDERR_INVALIDPARAMS if Mat or Valid is NULL) + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DViewportImpl_GetBackground(IDirect3DViewport3 *iface, + D3DMATERIALHANDLE *lphMat, + BOOL *lpValid) { ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface); - FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lphMat, lpValid); - return DD_OK; + FIXME("(%p)->(%p,%p): stub!\n", This, lphMat, lpValid); + return D3D_OK; } -HRESULT WINAPI -Main_IDirect3DViewportImpl_3_2_1_SetBackgroundDepth(LPDIRECT3DVIEWPORT3 iface, - LPDIRECTDRAWSURFACE lpDDSurface) +/***************************************************************************** + * IDirect3DViewport3::SetBackgroundDepth + * + * Sets a surface that represents the background depth. It's contents are + * used to set the depth buffer in IDirect3DViewport3::Clear + * + * Params: + * lpDDSurface: Surface to set + * + * Returns: D3D_OK, because it's a stub + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DViewportImpl_SetBackgroundDepth(IDirect3DViewport3 *iface, + IDirectDrawSurface *lpDDSurface) { ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface); - FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpDDSurface); - return DD_OK; + FIXME("(%p)->(%p): stub!\n", This, lpDDSurface); + return D3D_OK; } -HRESULT WINAPI -Main_IDirect3DViewportImpl_3_2_1_GetBackgroundDepth(LPDIRECT3DVIEWPORT3 iface, - LPDIRECTDRAWSURFACE* lplpDDSurface, - LPBOOL lpValid) +/***************************************************************************** + * IDirect3DViewport3::GetBackgroundDepth + * + * Returns the surface that represents the depth field + * + * Params: + * lplpDDSurface: Address to store the interface pointer + * lpValid: Set to TRUE if a depth is asigned, FALSE otherwise + * + * Returns: + * D3D_OK, because it's a stub + * (DDERR_INVALIDPARAMS if DDSurface of Valid is NULL) + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DViewportImpl_GetBackgroundDepth(IDirect3DViewport3 *iface, + IDirectDrawSurface **lplpDDSurface, + LPBOOL lpValid) { ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface); - FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lplpDDSurface, lpValid); + FIXME("(%p)->(%p,%p): stub!\n", This, lplpDDSurface, lpValid); return DD_OK; } -HRESULT WINAPI -Main_IDirect3DViewportImpl_3_2_1_Clear(LPDIRECT3DVIEWPORT3 iface, - DWORD dwCount, - LPD3DRECT lpRects, - DWORD dwFlags) +/***************************************************************************** + * IDirect3DViewport3::Clear + * + * Clears the render target and / or the z buffer + * + * Params: + * dwCount: The amount of rectangles to clear. If 0, the whole buffer is + * cleared + * lpRects: Pointer to the array of rectangles. If NULL, Count must be 0 + * dwFlags: D3DCLEAR_ZBUFFER and / or D3DCLEAR_TARGET + * + * Returns: + * D3D_OK on success + * D3DERR_VIEWPORTHASNODEVICE if there's no active device + * The return value of IDirect3DDevice7::Clear + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DViewportImpl_Clear(IDirect3DViewport3 *iface, + DWORD dwCount, + D3DRECT *lpRects, + DWORD dwFlags) { ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface); DWORD color = 0x00000000; @@ -310,21 +507,40 @@ Main_IDirect3DViewportImpl_3_2_1_Clear(LPDIRECT3DVIEWPORT3 iface, ((int) ((This->background->mat.u.diffuse.u4.a) * 255) << 24); } } - return This->active_device->clear(This->active_device, dwCount, lpRects, - dwFlags & (D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET), - color, 1.0, 0x00000000); + + return IDirect3DDevice7_Clear(ICOM_INTERFACE(This->active_device, IDirect3DDevice7), + dwCount, + lpRects, + dwFlags & (D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET), + color, + 1.0, + 0x00000000); } -HRESULT WINAPI -Main_IDirect3DViewportImpl_3_2_1_AddLight(LPDIRECT3DVIEWPORT3 iface, - LPDIRECT3DLIGHT lpDirect3DLight) +/***************************************************************************** + * IDirect3DViewport3::AddLight + * + * Adds an light to the viewport + * + * Params: + * lpDirect3DLight: Interface of the light to add + * + * Returns: + * D3D_OK on success + * DDERR_INVALIDPARAMS if Direct3DLight is NULL + * DDERR_INVALIDPARAMS if there are 8 lights or more + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DViewportImpl_AddLight(IDirect3DViewport3 *iface, + IDirect3DLight *lpDirect3DLight) { ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface); IDirect3DLightImpl *lpDirect3DLightImpl = ICOM_OBJECT(IDirect3DLightImpl, IDirect3DLight, lpDirect3DLight); DWORD i = 0; DWORD map = This->map_lights; - TRACE("(%p/%p)->(%p)\n", This, iface, lpDirect3DLight); + TRACE("(%p)->(%p)\n", This, lpDirect3DLight); if (This->num_lights >= 8) return DDERR_INVALIDPARAMS; @@ -350,18 +566,31 @@ Main_IDirect3DViewportImpl_3_2_1_AddLight(LPDIRECT3DVIEWPORT3 iface, lpDirect3DLightImpl->activate(lpDirect3DLightImpl); } - return DD_OK; + return D3D_OK; } -HRESULT WINAPI -Main_IDirect3DViewportImpl_3_2_1_DeleteLight(LPDIRECT3DVIEWPORT3 iface, - LPDIRECT3DLIGHT lpDirect3DLight) +/***************************************************************************** + * IDirect3DViewport3::DeleteLight + * + * Deletes a light from the viewports' light list + * + * Params: + * lpDirect3DLight: Light to delete + * + * Returns: + * D3D_OK on success + * DDERR_INVALIDPARAMS if the light wasn't found + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DViewportImpl_DeleteLight(IDirect3DViewport3 *iface, + IDirect3DLight *lpDirect3DLight) { ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface); IDirect3DLightImpl *lpDirect3DLightImpl = ICOM_OBJECT(IDirect3DLightImpl, IDirect3DLight, lpDirect3DLight); IDirect3DLightImpl *cur_light, *prev_light = NULL; - TRACE("(%p/%p)->(%p)\n", This, iface, lpDirect3DLight); + TRACE("(%p)->(%p)\n", This, lpDirect3DLight); cur_light = This->lights; while (cur_light != NULL) { if (cur_light == lpDirect3DLightImpl) { @@ -372,7 +601,7 @@ Main_IDirect3DViewportImpl_3_2_1_DeleteLight(LPDIRECT3DVIEWPORT3 iface, cur_light->active_viewport = NULL; This->num_lights--; This->map_lights &= ~(1<dwLightIndex); - return DD_OK; + return D3D_OK; } prev_light = cur_light; cur_light = cur_light->next; @@ -380,24 +609,57 @@ Main_IDirect3DViewportImpl_3_2_1_DeleteLight(LPDIRECT3DVIEWPORT3 iface, return DDERR_INVALIDPARAMS; } -HRESULT WINAPI -Main_IDirect3DViewportImpl_3_2_1_NextLight(LPDIRECT3DVIEWPORT3 iface, - LPDIRECT3DLIGHT lpDirect3DLight, - LPDIRECT3DLIGHT* lplpDirect3DLight, - DWORD dwFlags) +/***************************************************************************** + * IDirect3DViewport::NextLight + * + * Enumerates the lights associated with the viewport + * + * Params: + * lpDirect3DLight: Light to start with + * lplpDirect3DLight: Address to store the successor to + * + * Returns: + * D3D_OK, because it's a stub + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DViewportImpl_NextLight(IDirect3DViewport3 *iface, + IDirect3DLight *lpDirect3DLight, + IDirect3DLight **lplpDirect3DLight, + DWORD dwFlags) { ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface); - FIXME("(%p/%p)->(%p,%p,%08lx): stub!\n", This, iface, lpDirect3DLight, lplpDirect3DLight, dwFlags); - return DD_OK; + FIXME("(%p)->(%p,%p,%08lx): stub!\n", This, lpDirect3DLight, lplpDirect3DLight, dwFlags); + return D3D_OK; } -HRESULT WINAPI -Main_IDirect3DViewportImpl_3_2_GetViewport2(LPDIRECT3DVIEWPORT3 iface, - LPD3DVIEWPORT2 lpData) +/***************************************************************************** + * IDirect3DViewport2 Methods. + *****************************************************************************/ + +/***************************************************************************** + * IDirect3DViewport3::GetViewport2 + * + * Returns the currently set viewport in a D3DVIEWPORT2 structure. + * Simmilar to IDirect3DViewport3::GetViewport + * + * Params: + * lpData: Pointer to the structure to fill + * + * Returns: + * D3D_OK on success + * DDERR_INVALIDPARAMS if the viewport was set with + * IDirect3DViewport3::SetViewport + * DDERR_INVALIDPARAMS if Data is NULL + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DViewportImpl_GetViewport2(IDirect3DViewport3 *iface, + D3DVIEWPORT2 *lpData) { ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface); DWORD dwSize; - TRACE("(%p/%p)->(%p)\n", This, iface, lpData); + TRACE("(%p)->(%p)\n", This, lpData); if (This->use_vp2 != 1) { ERR(" Requesting to get a D3DVIEWPORT2 struct where a D3DVIEWPORT was set !\n"); return DDERR_INVALIDPARAMS; @@ -406,23 +668,35 @@ Main_IDirect3DViewportImpl_3_2_GetViewport2(LPDIRECT3DVIEWPORT3 iface, memset(lpData, 0, dwSize); memcpy(lpData, &(This->viewports.vp2), dwSize); - if (TRACE_ON(ddraw)) { + if (TRACE_ON(d3d7)) { TRACE(" returning D3DVIEWPORT2 :\n"); _dump_D3DVIEWPORT2(lpData); } - return DD_OK; + return D3D_OK; } -HRESULT WINAPI -Main_IDirect3DViewportImpl_3_2_SetViewport2(LPDIRECT3DVIEWPORT3 iface, - LPD3DVIEWPORT2 lpData) +/***************************************************************************** + * IDirect3DViewport3::SetViewport2 + * + * Sets the viewport from a D3DVIEWPORT2 structure + * + * Params: + * lpData: Viewport to set + * + * Returns: + * D3D_OK on success + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DViewportImpl_SetViewport2(IDirect3DViewport3 *iface, + D3DVIEWPORT2 *lpData) { ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface); LPDIRECT3DVIEWPORT3 current_viewport; TRACE("(%p/%p)->(%p)\n", This, iface, lpData); - if (TRACE_ON(ddraw)) { + if (TRACE_ON(d3d7)) { TRACE(" getting D3DVIEWPORT2 :\n"); _dump_D3DVIEWPORT2(lpData); } @@ -438,105 +712,126 @@ Main_IDirect3DViewportImpl_3_2_SetViewport2(LPDIRECT3DVIEWPORT3 iface, IDirect3DViewport3_Release(current_viewport); } - return DD_OK; + return D3D_OK; } -HRESULT WINAPI -Main_IDirect3DViewportImpl_3_SetBackgroundDepth2(LPDIRECT3DVIEWPORT3 iface, - LPDIRECTDRAWSURFACE4 lpDDS) +/***************************************************************************** + * IDirect3DViewport3 Methods. + *****************************************************************************/ + +/***************************************************************************** + * IDirect3DViewport3::SetBackgroundDepth2 + * + * Sets a IDirectDrawSurface4 surface as the background depth surface + * + * Params: + * lpDDS: Surface to set + * + * Returns: + * D3D_OK, because it's stub + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DViewportImpl_SetBackgroundDepth2(IDirect3DViewport3 *iface, + IDirectDrawSurface4 *lpDDS) { ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface); - FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpDDS); - return DD_OK; + FIXME("(%p)->(%p): stub!\n", This, lpDDS); + return D3D_OK; } -HRESULT WINAPI -Main_IDirect3DViewportImpl_3_GetBackgroundDepth2(LPDIRECT3DVIEWPORT3 iface, - LPDIRECTDRAWSURFACE4* lplpDDS, - LPBOOL lpValid) +/***************************************************************************** + * IDirect3DViewport3::GetBackgroundDepth2 + * + * Returns the IDirect3DSurface4 interface to the background depth surface + * + * Params: + * lplpDDS: Address to store the interface pointer at + * lpValid: Set to true if a surface is assigned + * + * Returns: + * D3D_OK because it's a stub + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DViewportImpl_GetBackgroundDepth2(IDirect3DViewport3 *iface, + IDirectDrawSurface4 **lplpDDS, + BOOL *lpValid) { ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface); FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lplpDDS, lpValid); - return DD_OK; + return D3D_OK; } -HRESULT WINAPI -Main_IDirect3DViewportImpl_3_Clear2(LPDIRECT3DVIEWPORT3 iface, - DWORD dwCount, - LPD3DRECT lpRects, - DWORD dwFlags, - DWORD dwColor, - D3DVALUE dvZ, - DWORD dwStencil) +/***************************************************************************** + * IDirect3DViewport3::Clear2 + * + * Another clearing method + * + * Params: + * Count: Number of rectangles to clear + * Rects: Rectangle array to clear + * Flags: Some flags :) + * Color: Color to fill the render target with + * Z: Value to fill the depth buffer with + * Stencil: Value to fill the stencil bits with + * + * Returns: + * + *****************************************************************************/ +static HRESULT WINAPI +IDirect3DViewportImpl_Clear2(IDirect3DViewport3 *iface, + DWORD dwCount, + LPD3DRECT lpRects, + DWORD dwFlags, + DWORD dwColor, + D3DVALUE dvZ, + DWORD dwStencil) { ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface); - TRACE("(%p/%p)->(%08lx,%p,%08lx,%08lx,%f,%08lx)\n", This, iface, dwCount, lpRects, dwFlags, dwColor, dvZ, dwStencil); + TRACE("(%p)->(%08lx,%p,%08lx,%08lx,%f,%08lx)\n", This, dwCount, lpRects, dwFlags, dwColor, dvZ, dwStencil); if (This->active_device == NULL) { ERR(" Trying to clear a viewport not attached to a device !\n"); return D3DERR_VIEWPORTHASNODEVICE; } - return This->active_device->clear(This->active_device, dwCount, lpRects, dwFlags, dwColor, dvZ, dwStencil); + return IDirect3DDevice7_Clear(ICOM_INTERFACE(This->active_device, IDirect3DDevice7), + dwCount, + lpRects, + dwFlags, + dwColor, + dvZ, + dwStencil); } -#if !defined(__STRICT_ANSI__) && defined(__GNUC__) -# define XCAST(fun) (typeof(VTABLE_IDirect3DViewport3.fun)) -#else -# define XCAST(fun) (void*) -#endif +/***************************************************************************** + * The VTable + *****************************************************************************/ -static const IDirect3DViewport3Vtbl VTABLE_IDirect3DViewport3 = +const IDirect3DViewport3Vtbl IDirect3DViewport3_Vtbl = { - XCAST(QueryInterface) Main_IDirect3DViewportImpl_3_2_1_QueryInterface, - XCAST(AddRef) Main_IDirect3DViewportImpl_3_2_1_AddRef, - XCAST(Release) Main_IDirect3DViewportImpl_3_2_1_Release, - XCAST(Initialize) Main_IDirect3DViewportImpl_3_2_1_Initialize, - XCAST(GetViewport) Main_IDirect3DViewportImpl_3_2_1_GetViewport, - XCAST(SetViewport) Main_IDirect3DViewportImpl_3_2_1_SetViewport, - XCAST(TransformVertices) Main_IDirect3DViewportImpl_3_2_1_TransformVertices, - XCAST(LightElements) Main_IDirect3DViewportImpl_3_2_1_LightElements, - XCAST(SetBackground) Main_IDirect3DViewportImpl_3_2_1_SetBackground, - XCAST(GetBackground) Main_IDirect3DViewportImpl_3_2_1_GetBackground, - XCAST(SetBackgroundDepth) Main_IDirect3DViewportImpl_3_2_1_SetBackgroundDepth, - XCAST(GetBackgroundDepth) Main_IDirect3DViewportImpl_3_2_1_GetBackgroundDepth, - XCAST(Clear) Main_IDirect3DViewportImpl_3_2_1_Clear, - XCAST(AddLight) Main_IDirect3DViewportImpl_3_2_1_AddLight, - XCAST(DeleteLight) Main_IDirect3DViewportImpl_3_2_1_DeleteLight, - XCAST(NextLight) Main_IDirect3DViewportImpl_3_2_1_NextLight, - XCAST(GetViewport2) Main_IDirect3DViewportImpl_3_2_GetViewport2, - XCAST(SetViewport2) Main_IDirect3DViewportImpl_3_2_SetViewport2, - XCAST(SetBackgroundDepth2) Main_IDirect3DViewportImpl_3_SetBackgroundDepth2, - XCAST(GetBackgroundDepth2) Main_IDirect3DViewportImpl_3_GetBackgroundDepth2, - XCAST(Clear2) Main_IDirect3DViewportImpl_3_Clear2, + /*** IUnknown Methods ***/ + IDirect3DViewportImpl_QueryInterface, + IDirect3DViewportImpl_AddRef, + IDirect3DViewportImpl_Release, + /*** IDirect3DViewport Methods */ + IDirect3DViewportImpl_Initialize, + IDirect3DViewportImpl_GetViewport, + IDirect3DViewportImpl_SetViewport, + IDirect3DViewportImpl_TransformVertices, + IDirect3DViewportImpl_LightElements, + IDirect3DViewportImpl_SetBackground, + IDirect3DViewportImpl_GetBackground, + IDirect3DViewportImpl_SetBackgroundDepth, + IDirect3DViewportImpl_GetBackgroundDepth, + IDirect3DViewportImpl_Clear, + IDirect3DViewportImpl_AddLight, + IDirect3DViewportImpl_DeleteLight, + IDirect3DViewportImpl_NextLight, + /*** IDirect3DViewport2 Methods ***/ + IDirect3DViewportImpl_GetViewport2, + IDirect3DViewportImpl_SetViewport2, + /*** IDirect3DViewport3 Methods ***/ + IDirect3DViewportImpl_SetBackgroundDepth2, + IDirect3DViewportImpl_GetBackgroundDepth2, + IDirect3DViewportImpl_Clear2, }; - -#if !defined(__STRICT_ANSI__) && defined(__GNUC__) -#undef XCAST -#endif - - - - -HRESULT d3dviewport_create(IDirect3DViewportImpl **obj, IDirectDrawImpl *d3d) -{ - IDirect3DViewportImpl *object; - - object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DViewportImpl)); - if (object == NULL) return DDERR_OUTOFMEMORY; - - object->ref = 1; - object->d3d = d3d; - object->activate = activate; - object->use_vp2 = 0xFF; - object->next = NULL; - object->lights = NULL; - object->num_lights = 0; - object->map_lights = 0; - - ICOM_INIT_INTERFACE(object, IDirect3DViewport3, VTABLE_IDirect3DViewport3); - - *obj = object; - - TRACE(" creating implementation at %p.\n", *obj); - - return D3D_OK; -}