2 * Copyright (c) 1998-2004 Lionel Ulmer
3 * Copyright (c) 2002-2005 Christian Costa
4 * Copyright (c) 2006 Stefan Dösinger
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 * IDirect3DDevice implementation, version 1, 2, 3 and 7. Rendering is relayed
21 * to WineD3D, some minimal DirectDraw specific management is handled here.
22 * The Direct3DDevice is NOT the parent of the WineD3DDevice, because d3d
23 * is initialized when DirectDraw creates the primary surface.
24 * Some type management is necessary, because some D3D types changed between
30 #include "wine/port.h"
38 #define NONAMELESSUNION
44 #include "wine/exception.h"
49 #include "ddraw_private.h"
50 #include "wine/debug.h"
52 WINE_DEFAULT_DEBUG_CHANNEL(d3d7);
53 WINE_DECLARE_DEBUG_CHANNEL(ddraw_thunk);
56 const GUID IID_D3DDEVICE_WineD3D = {
60 { 0xb7,0x98,0xc6,0x8a,0x77,0x2d,0x72,0x2a }
63 /*****************************************************************************
64 * IUnknown Methods. Common for Version 1, 2, 3 and 7
65 *****************************************************************************/
67 /*****************************************************************************
68 * IDirect3DDevice7::QueryInterface
70 * Used to query other interfaces from a Direct3DDevice interface.
71 * It can return interface pointers to all Direct3DDevice versions as well
72 * as IDirectDraw and IDirect3D. For a link to QueryInterface
73 * rules see ddraw.c, IDirectDraw7::QueryInterface
75 * Exists in Version 1, 2, 3 and 7
78 * refiid: Interface ID queried for
79 * obj: Used to return the interface pointer
82 * D3D_OK or E_NOINTERFACE
84 *****************************************************************************/
86 IDirect3DDeviceImpl_7_QueryInterface(IDirect3DDevice7 *iface,
90 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
91 TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(refiid), obj);
93 /* According to COM docs, if the QueryInterface fails, obj should be set to NULL */
97 return DDERR_INVALIDPARAMS;
99 if ( IsEqualGUID( &IID_IUnknown, refiid ) )
101 *obj = ICOM_INTERFACE(This, IDirect3DDevice7);
104 /* Check DirectDraw Interfac
\ 1s */
105 else if( IsEqualGUID( &IID_IDirectDraw7, refiid ) )
107 *obj = ICOM_INTERFACE(This->ddraw, IDirectDraw7);
108 TRACE("(%p) Returning IDirectDraw7 interface at %p\n", This, *obj);
110 else if ( IsEqualGUID( &IID_IDirectDraw4, refiid ) )
112 *obj = ICOM_INTERFACE(This->ddraw, IDirectDraw4);
113 TRACE("(%p) Returning IDirectDraw4 interface at %p\n", This, *obj);
115 else if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) )
117 *obj = ICOM_INTERFACE(This->ddraw, IDirectDraw2);
118 TRACE("(%p) Returning IDirectDraw2 interface at %p\n", This, *obj);
120 else if( IsEqualGUID( &IID_IDirectDraw, refiid ) )
122 *obj = ICOM_INTERFACE(This->ddraw, IDirectDraw);
123 TRACE("(%p) Returning IDirectDraw interface at %p\n", This, *obj);
127 else if ( IsEqualGUID( &IID_IDirect3D , refiid ) )
129 *obj = ICOM_INTERFACE(This->ddraw, IDirect3D);
130 TRACE("(%p) Returning IDirect3D interface at %p\n", This, *obj);
132 else if ( IsEqualGUID( &IID_IDirect3D2 , refiid ) )
134 *obj = ICOM_INTERFACE(This->ddraw, IDirect3D2);
135 TRACE("(%p) Returning IDirect3D2 interface at %p\n", This, *obj);
137 else if ( IsEqualGUID( &IID_IDirect3D3 , refiid ) )
139 *obj = ICOM_INTERFACE(This->ddraw, IDirect3D3);
140 TRACE("(%p) Returning IDirect3D3 interface at %p\n", This, *obj);
142 else if ( IsEqualGUID( &IID_IDirect3D7 , refiid ) )
144 *obj = ICOM_INTERFACE(This->ddraw, IDirect3D7);
145 TRACE("(%p) Returning IDirect3D7 interface at %p\n", This, *obj);
149 else if ( IsEqualGUID( &IID_IDirect3DDevice , refiid ) )
151 *obj = ICOM_INTERFACE(This, IDirect3DDevice);
152 TRACE("(%p) Returning IDirect3DDevice interface at %p\n", This, *obj);
154 else if ( IsEqualGUID( &IID_IDirect3DDevice2 , refiid ) ) {
155 *obj = ICOM_INTERFACE(This, IDirect3DDevice2);
156 TRACE("(%p) Returning IDirect3DDevice2 interface at %p\n", This, *obj);
158 else if ( IsEqualGUID( &IID_IDirect3DDevice3 , refiid ) ) {
159 *obj = ICOM_INTERFACE(This, IDirect3DDevice3);
160 TRACE("(%p) Returning IDirect3DDevice3 interface at %p\n", This, *obj);
162 else if ( IsEqualGUID( &IID_IDirect3DDevice7 , refiid ) ) {
163 *obj = ICOM_INTERFACE(This, IDirect3DDevice7);
164 TRACE("(%p) Returning IDirect3DDevice7 interface at %p\n", This, *obj);
167 /* Unknown interface */
170 ERR("(%p)->(%s, %p): No interface found\n", This, debugstr_guid(refiid), obj);
171 return E_NOINTERFACE;
174 /* AddRef the returned interface */
175 IUnknown_AddRef( (IUnknown *) *obj);
179 static HRESULT WINAPI
180 Thunk_IDirect3DDeviceImpl_3_QueryInterface(IDirect3DDevice3 *iface,
184 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
185 TRACE_(ddraw_thunk)("(%p)->(%s,%p) thunking to IDirect3DDevice7 interface.\n", This, debugstr_guid(riid), obj);
186 return IDirect3DDevice7_QueryInterface(ICOM_INTERFACE(This, IDirect3DDevice7),
191 static HRESULT WINAPI
192 Thunk_IDirect3DDeviceImpl_2_QueryInterface(IDirect3DDevice2 *iface,
196 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
197 TRACE_(ddraw_thunk)("(%p)->(%s,%p) thunking to IDirect3DDevice7 interface.\n", This, debugstr_guid(riid), obj);
198 return IDirect3DDevice7_QueryInterface(ICOM_INTERFACE(This, IDirect3DDevice7),
203 static HRESULT WINAPI
204 Thunk_IDirect3DDeviceImpl_1_QueryInterface(IDirect3DDevice *iface,
208 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
209 TRACE_(ddraw_thunk)("(%p)->(%s,%p) thunking to IDirect3DDevice7 interface.\n", This, debugstr_guid(riid), obp);
210 return IDirect3DDevice7_QueryInterface(ICOM_INTERFACE(This, IDirect3DDevice7),
215 /*****************************************************************************
216 * IDirect3DDevice7::AddRef
218 * Increases the refcount....
219 * The most exciting Method, definitely
221 * Exists in Version 1, 2, 3 and 7
226 *****************************************************************************/
228 IDirect3DDeviceImpl_7_AddRef(IDirect3DDevice7 *iface)
230 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
231 ULONG ref = InterlockedIncrement(&This->ref);
233 TRACE("(%p) : incrementing from %u.\n", This, ref -1);
239 Thunk_IDirect3DDeviceImpl_3_AddRef(IDirect3DDevice3 *iface)
241 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
242 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
243 return IDirect3DDevice7_AddRef(ICOM_INTERFACE(This, IDirect3DDevice7));
247 Thunk_IDirect3DDeviceImpl_2_AddRef(IDirect3DDevice2 *iface)
249 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
250 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
251 return IDirect3DDevice7_AddRef(ICOM_INTERFACE(This, IDirect3DDevice7));
255 Thunk_IDirect3DDeviceImpl_1_AddRef(IDirect3DDevice *iface)
257 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", iface);
258 return IDirect3DDevice7_AddRef(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice7, iface));
261 /*****************************************************************************
262 * IDirect3DDevice7::Release
264 * Decreases the refcount of the interface
265 * When the refcount is reduced to 0, the object is destroyed.
267 * Exists in Version 1, 2, 3 and 7
272 *****************************************************************************/
274 IDirect3DDeviceImpl_7_Release(IDirect3DDevice7 *iface)
276 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
277 ULONG ref = InterlockedDecrement(&This->ref);
279 TRACE("(%p)->() decrementing from %u.\n", This, ref +1);
281 /* This method doesn't destroy the WineD3DDevice, because it's still in use for
282 * 2D rendering. IDirectDrawSurface7::Release will destroy the WineD3DDevice
283 * when the render target is released
287 IParent *IndexBufferParent;
290 EnterCriticalSection(&ddraw_cs);
291 /* Free the index buffer. */
292 IWineD3DDevice_SetIndices(This->wineD3DDevice, NULL);
293 IWineD3DIndexBuffer_GetParent(This->indexbuffer,
294 (IUnknown **) &IndexBufferParent);
295 IParent_Release(IndexBufferParent); /* Once for the getParent */
296 if( IParent_Release(IndexBufferParent) != 0) /* And now to destroy it */
298 ERR(" (%p) Something is still holding the index buffer parent %p\n", This, IndexBufferParent);
301 /* There is no need to unset the vertex buffer here, IWineD3DDevice_Uninit3D will do that when
302 * destroying the primary stateblock. If a vertex buffer is destroyed while it is bound
303 * IDirect3DVertexBuffer::Release will unset it.
306 /* Restore the render targets */
307 if(This->OffScreenTarget)
313 vp.Width = This->ddraw->d3d_target->surface_desc.dwWidth;
314 vp.Height = This->ddraw->d3d_target->surface_desc.dwHeight;
317 IWineD3DDevice_SetViewport(This->wineD3DDevice,
320 /* Set the device up to render to the front buffer since the back buffer will
323 IWineD3DDevice_SetRenderTarget(This->wineD3DDevice, 0,
324 This->ddraw->d3d_target->WineD3DSurface);
325 /* This->target is the offscreen target.
326 * This->ddraw->d3d_target is the target used by DDraw
328 TRACE("(%p) Release: Using %p as front buffer, %p as back buffer\n", This, This->ddraw->d3d_target, NULL);
329 IWineD3DDevice_SetFrontBackBuffers(This->wineD3DDevice,
330 This->ddraw->d3d_target->WineD3DSurface,
334 /* Release the WineD3DDevice. This won't destroy it */
335 if(IWineD3DDevice_Release(This->wineD3DDevice) <= 0)
337 ERR(" (%p) The wineD3D device %p was destroyed unexpectadely. Prepare for trouble\n", This, This->wineD3DDevice);
340 /* The texture handles should be unset by now, but there might be some bits
341 * missing in our reference counting(needs test). Do a sanity check
343 for(i = 0; i < This->numHandles; i++)
345 if(This->Handles[i].ptr)
347 switch(This->Handles[i].type)
349 case DDrawHandle_Texture:
351 IDirectDrawSurfaceImpl *surf = (IDirectDrawSurfaceImpl *) This->Handles[i].ptr;
352 FIXME("Texture Handle %d not unset properly\n", i + 1);
357 case DDrawHandle_Material:
359 IDirect3DMaterialImpl *mat = (IDirect3DMaterialImpl *) This->Handles[i].ptr;
360 FIXME("Material handle %d not unset properly\n", i + 1);
365 case DDrawHandle_Matrix:
367 /* No fixme here because this might happen because of sloppy apps */
368 WARN("Leftover matrix handle %d, deleting\n", i + 1);
369 IDirect3DDevice_DeleteMatrix(ICOM_INTERFACE(This, IDirect3DDevice),
374 case DDrawHandle_StateBlock:
376 /* No fixme here because this might happen because of sloppy apps */
377 WARN("Leftover stateblock handle %d, deleting\n", i + 1);
378 IDirect3DDevice7_DeleteStateBlock(ICOM_INTERFACE(This, IDirect3DDevice7),
384 FIXME("Unknown handle %d not unset properly\n", i + 1);
389 HeapFree(GetProcessHeap(), 0, This->Handles);
391 TRACE("Releasing target %p %p\n", This->target, This->ddraw->d3d_target);
392 /* Release the render target and the WineD3D render target
393 * (See IDirect3D7::CreateDevice for more comments on this)
395 IDirectDrawSurface7_Release(ICOM_INTERFACE(This->target, IDirectDrawSurface7));
396 IDirectDrawSurface7_Release(ICOM_INTERFACE(This->ddraw->d3d_target,IDirectDrawSurface7));
397 TRACE("Target release done\n");
399 This->ddraw->d3ddevice = NULL;
401 /* Now free the structure */
402 HeapFree(GetProcessHeap(), 0, This);
403 LeaveCriticalSection(&ddraw_cs);
411 Thunk_IDirect3DDeviceImpl_3_Release(IDirect3DDevice3 *iface)
413 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
414 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
415 return IDirect3DDevice7_Release(ICOM_INTERFACE(This, IDirect3DDevice7));
419 Thunk_IDirect3DDeviceImpl_2_Release(IDirect3DDevice2 *iface)
421 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
422 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
423 return IDirect3DDevice7_Release(ICOM_INTERFACE(This, IDirect3DDevice7));
427 Thunk_IDirect3DDeviceImpl_1_Release(IDirect3DDevice *iface)
429 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
430 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
431 return IDirect3DDevice7_Release(ICOM_INTERFACE(This, IDirect3DDevice7));
434 /*****************************************************************************
435 * IDirect3DDevice Methods
436 *****************************************************************************/
438 /*****************************************************************************
439 * IDirect3DDevice::Initialize
441 * Initializes a Direct3DDevice. This implementation is a no-op, as all
442 * initialization is done at create time.
444 * Exists in Version 1
447 * No idea what they mean, as the MSDN page is gone
451 *****************************************************************************/
452 static HRESULT WINAPI
453 IDirect3DDeviceImpl_1_Initialize(IDirect3DDevice *iface,
454 IDirect3D *Direct3D, GUID *guid,
457 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
459 /* It shouldn't be crucial, but print a FIXME, I'm interested if
460 * any game calls it and when
462 FIXME("(%p)->(%p,%p,%p): No-op!\n", This, Direct3D, guid, Desc);
467 /*****************************************************************************
468 * IDirect3DDevice7::GetCaps
470 * Retrieves the device's capabilities
472 * This implementation is used for Version 7 only, the older versions have
473 * their own implementation.
476 * Desc: Pointer to a D3DDEVICEDESC7 structure to fill
480 * D3DERR_* if a problem occurs. See WineD3D
482 *****************************************************************************/
483 static HRESULT WINAPI
484 IDirect3DDeviceImpl_7_GetCaps(IDirect3DDevice7 *iface,
485 D3DDEVICEDESC7 *Desc)
487 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
488 D3DDEVICEDESC OldDesc;
489 TRACE("(%p)->(%p)\n", This, Desc);
491 /* Call the same function used by IDirect3D, this saves code */
492 return IDirect3DImpl_GetCaps(This->ddraw->wineD3D, &OldDesc, Desc);
495 /*****************************************************************************
496 * IDirect3DDevice3::GetCaps
498 * Retrieves the capabilities of the hardware device and the emulation
499 * device. For Wine, hardware and emulation are the same (it's all HW).
501 * This implementation is used for Version 1, 2, and 3. Version 7 has its own
504 * HWDesc: Structure to fill with the HW caps
505 * HelDesc: Structure to fill with the hardware emulation caps
509 * D3DERR_* if a problem occurs. See WineD3D
511 *****************************************************************************/
512 static HRESULT WINAPI
513 IDirect3DDeviceImpl_3_GetCaps(IDirect3DDevice3 *iface,
514 D3DDEVICEDESC *HWDesc,
515 D3DDEVICEDESC *HelDesc)
517 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
518 D3DDEVICEDESC7 newDesc;
520 TRACE("(%p)->(%p,%p)\n", iface, HWDesc, HelDesc);
522 hr = IDirect3DImpl_GetCaps(This->ddraw->wineD3D, HWDesc, &newDesc);
523 if(hr != D3D_OK) return hr;
529 static HRESULT WINAPI
530 Thunk_IDirect3DDeviceImpl_2_GetCaps(IDirect3DDevice2 *iface,
531 D3DDEVICEDESC *D3DHWDevDesc,
532 D3DDEVICEDESC *D3DHELDevDesc)
534 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
535 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice3 interface.\n", This, D3DHWDevDesc, D3DHELDevDesc);
536 return IDirect3DDevice3_GetCaps(ICOM_INTERFACE(This, IDirect3DDevice3),
541 static HRESULT WINAPI
542 Thunk_IDirect3DDeviceImpl_1_GetCaps(IDirect3DDevice *iface,
543 D3DDEVICEDESC *D3DHWDevDesc,
544 D3DDEVICEDESC *D3DHELDevDesc)
546 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
547 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice3 interface.\n", This, D3DHWDevDesc, D3DHELDevDesc);
548 return IDirect3DDevice3_GetCaps(ICOM_INTERFACE(This, IDirect3DDevice3),
553 /*****************************************************************************
554 * IDirect3DDevice2::SwapTextureHandles
556 * Swaps the texture handles of 2 Texture interfaces. Version 1 and 2
559 * Tex1, Tex2: The 2 Textures to swap
564 *****************************************************************************/
565 static HRESULT WINAPI
566 IDirect3DDeviceImpl_2_SwapTextureHandles(IDirect3DDevice2 *iface,
567 IDirect3DTexture2 *Tex1,
568 IDirect3DTexture2 *Tex2)
570 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
572 IDirectDrawSurfaceImpl *surf1 = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture2, Tex1);
573 IDirectDrawSurfaceImpl *surf2 = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture2, Tex2);
574 TRACE("(%p)->(%p,%p)\n", This, surf1, surf2);
576 EnterCriticalSection(&ddraw_cs);
577 This->Handles[surf1->Handle - 1].ptr = surf2;
578 This->Handles[surf2->Handle - 1].ptr = surf1;
580 swap = surf2->Handle;
581 surf2->Handle = surf1->Handle;
582 surf1->Handle = swap;
583 LeaveCriticalSection(&ddraw_cs);
588 static HRESULT WINAPI
589 Thunk_IDirect3DDeviceImpl_1_SwapTextureHandles(IDirect3DDevice *iface,
590 IDirect3DTexture *D3DTex1,
591 IDirect3DTexture *D3DTex2)
593 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
594 IDirectDrawSurfaceImpl *surf1 = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture, D3DTex1);
595 IDirectDrawSurfaceImpl *surf2 = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture, D3DTex2);
596 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice2 interface.\n", This, surf1, surf2);
597 return IDirect3DDevice2_SwapTextureHandles(ICOM_INTERFACE(This, IDirect3DDevice2),
598 ICOM_INTERFACE(surf1, IDirect3DTexture2),
599 ICOM_INTERFACE(surf2, IDirect3DTexture2));
602 /*****************************************************************************
603 * IDirect3DDevice3::GetStats
605 * This method seems to retrieve some stats from the device.
606 * The MSDN documentation doesn't exist any more, but the D3DSTATS
607 * structure suggests that the amount of drawn primitives and processed
608 * vertices is returned.
610 * Exists in Version 1, 2 and 3
613 * Stats: Pointer to a D3DSTATS structure to be filled
617 * DDERR_INVALIDPARAMS if Stats == NULL
619 *****************************************************************************/
620 static HRESULT WINAPI
621 IDirect3DDeviceImpl_3_GetStats(IDirect3DDevice3 *iface,
624 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
625 FIXME("(%p)->(%p): Stub!\n", This, Stats);
628 return DDERR_INVALIDPARAMS;
630 /* Fill the Stats with 0 */
631 Stats->dwTrianglesDrawn = 0;
632 Stats->dwLinesDrawn = 0;
633 Stats->dwPointsDrawn = 0;
634 Stats->dwSpansDrawn = 0;
635 Stats->dwVerticesProcessed = 0;
640 static HRESULT WINAPI
641 Thunk_IDirect3DDeviceImpl_2_GetStats(IDirect3DDevice2 *iface,
644 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
645 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, Stats);
646 return IDirect3DDevice3_GetStats(ICOM_INTERFACE(This, IDirect3DDevice3),
650 static HRESULT WINAPI
651 Thunk_IDirect3DDeviceImpl_1_GetStats(IDirect3DDevice *iface,
654 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
655 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, Stats);
656 return IDirect3DDevice3_GetStats(ICOM_INTERFACE(This, IDirect3DDevice3),
660 /*****************************************************************************
661 * IDirect3DDevice::CreateExecuteBuffer
663 * Creates an IDirect3DExecuteBuffer, used for rendering with a
669 * Desc: Buffer description
670 * ExecuteBuffer: Address to return the Interface pointer at
671 * UnkOuter: Must be NULL. Basically for aggregation, which ddraw doesn't
675 * CLASS_E_NOAGGREGATION if UnkOuter != NULL
676 * DDERR_OUTOFMEMORY if we ran out of memory
679 *****************************************************************************/
680 static HRESULT WINAPI
681 IDirect3DDeviceImpl_1_CreateExecuteBuffer(IDirect3DDevice *iface,
682 D3DEXECUTEBUFFERDESC *Desc,
683 IDirect3DExecuteBuffer **ExecuteBuffer,
686 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
687 IDirect3DExecuteBufferImpl* object;
688 TRACE("(%p)->(%p,%p,%p)!\n", This, Desc, ExecuteBuffer, UnkOuter);
691 return CLASS_E_NOAGGREGATION;
693 /* Allocate the new Execute Buffer */
694 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DExecuteBufferImpl));
697 ERR("Out of memory when allocating a IDirect3DExecuteBufferImpl structure\n");
698 return DDERR_OUTOFMEMORY;
701 ICOM_INIT_INTERFACE(object, IDirect3DExecuteBuffer, IDirect3DExecuteBuffer_Vtbl);
704 object->d3ddev = This;
706 /* Initializes memory */
707 memcpy(&object->desc, Desc, Desc->dwSize);
709 /* No buffer given */
710 if ((object->desc.dwFlags & D3DDEB_LPDATA) == 0)
711 object->desc.lpData = NULL;
713 /* No buffer size given */
714 if ((object->desc.dwFlags & D3DDEB_BUFSIZE) == 0)
715 object->desc.dwBufferSize = 0;
717 /* Create buffer if asked */
718 if ((object->desc.lpData == NULL) && (object->desc.dwBufferSize > 0))
720 object->need_free = TRUE;
721 object->desc.lpData = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,object->desc.dwBufferSize);
722 if(!object->desc.lpData)
724 ERR("Out of memory when allocating the execute buffer data\n");
725 HeapFree(GetProcessHeap(), 0, object);
726 return DDERR_OUTOFMEMORY;
731 object->need_free = FALSE;
734 /* No vertices for the moment */
735 object->vertex_data = NULL;
737 object->desc.dwFlags |= D3DDEB_LPDATA;
739 object->indices = NULL;
740 object->nb_indices = 0;
742 *ExecuteBuffer = ICOM_INTERFACE(object, IDirect3DExecuteBuffer);
744 TRACE(" Returning IDirect3DExecuteBuffer at %p, implementation is at %p\n", *ExecuteBuffer, object);
749 /*****************************************************************************
750 * IDirect3DDevice::Execute
752 * Executes all the stuff in an execute buffer.
755 * ExecuteBuffer: The buffer to execute
756 * Viewport: The viewport used for rendering
760 * DDERR_INVALIDPARAMS if ExecuteBuffer == NULL
763 *****************************************************************************/
764 static HRESULT WINAPI
765 IDirect3DDeviceImpl_1_Execute(IDirect3DDevice *iface,
766 IDirect3DExecuteBuffer *ExecuteBuffer,
767 IDirect3DViewport *Viewport,
770 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
771 IDirect3DExecuteBufferImpl *Direct3DExecuteBufferImpl = ICOM_OBJECT(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, ExecuteBuffer);
772 IDirect3DViewportImpl *Direct3DViewportImpl = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport);
774 TRACE("(%p)->(%p,%p,%08x)\n", This, Direct3DExecuteBufferImpl, Direct3DViewportImpl, Flags);
776 if(!Direct3DExecuteBufferImpl)
777 return DDERR_INVALIDPARAMS;
780 EnterCriticalSection(&ddraw_cs);
781 IDirect3DExecuteBufferImpl_Execute(Direct3DExecuteBufferImpl, This, Direct3DViewportImpl);
782 LeaveCriticalSection(&ddraw_cs);
787 /*****************************************************************************
788 * IDirect3DDevice3::AddViewport
790 * Add a Direct3DViewport to the device's viewport list. These viewports
791 * are wrapped to IDirect3DDevice7 viewports in viewport.c
793 * Exists in Version 1, 2 and 3. Note that IDirect3DViewport 1, 2 and 3
794 * are the same interfaces.
797 * Viewport: The viewport to add
800 * DDERR_INVALIDPARAMS if Viewport == NULL
803 *****************************************************************************/
804 static HRESULT WINAPI
805 IDirect3DDeviceImpl_3_AddViewport(IDirect3DDevice3 *iface,
806 IDirect3DViewport3 *Viewport)
808 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
809 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport);
811 TRACE("(%p)->(%p)\n", This, vp);
815 return DDERR_INVALIDPARAMS;
817 EnterCriticalSection(&ddraw_cs);
818 vp->next = This->viewport_list;
819 This->viewport_list = vp;
820 LeaveCriticalSection(&ddraw_cs);
825 static HRESULT WINAPI
826 Thunk_IDirect3DDeviceImpl_2_AddViewport(IDirect3DDevice2 *iface,
827 IDirect3DViewport2 *Direct3DViewport2)
829 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
830 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport2);
831 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
832 return IDirect3DDevice3_AddViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
833 ICOM_INTERFACE(vp, IDirect3DViewport3));
836 static HRESULT WINAPI
837 Thunk_IDirect3DDeviceImpl_1_AddViewport(IDirect3DDevice *iface,
838 IDirect3DViewport *Direct3DViewport)
840 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
841 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport);
842 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
843 return IDirect3DDevice3_AddViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
844 ICOM_INTERFACE(vp, IDirect3DViewport3));
847 /*****************************************************************************
848 * IDirect3DDevice3::DeleteViewport
850 * Deletes a Direct3DViewport from the device's viewport list.
852 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
856 * Viewport: The viewport to delete
860 * DDERR_INVALIDPARAMS if the viewport wasn't found in the list
862 *****************************************************************************/
863 static HRESULT WINAPI
864 IDirect3DDeviceImpl_3_DeleteViewport(IDirect3DDevice3 *iface,
865 IDirect3DViewport3 *Viewport)
867 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
868 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *) Viewport;
869 IDirect3DViewportImpl *cur_viewport, *prev_viewport = NULL;
871 TRACE("(%p)->(%p)\n", This, vp);
873 EnterCriticalSection(&ddraw_cs);
874 cur_viewport = This->viewport_list;
875 while (cur_viewport != NULL)
877 if (cur_viewport == vp)
879 if (prev_viewport == NULL) This->viewport_list = cur_viewport->next;
880 else prev_viewport->next = cur_viewport->next;
881 /* TODO : add desactivate of the viewport and all associated lights... */
882 LeaveCriticalSection(&ddraw_cs);
885 prev_viewport = cur_viewport;
886 cur_viewport = cur_viewport->next;
889 LeaveCriticalSection(&ddraw_cs);
890 return DDERR_INVALIDPARAMS;
893 static HRESULT WINAPI
894 Thunk_IDirect3DDeviceImpl_2_DeleteViewport(IDirect3DDevice2 *iface,
895 IDirect3DViewport2 *Direct3DViewport2)
897 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
898 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport2);
899 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
900 return IDirect3DDevice3_DeleteViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
901 ICOM_INTERFACE(vp, IDirect3DViewport3));
904 static HRESULT WINAPI
905 Thunk_IDirect3DDeviceImpl_1_DeleteViewport(IDirect3DDevice *iface,
906 IDirect3DViewport *Direct3DViewport)
908 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
909 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport);
910 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
911 return IDirect3DDevice3_DeleteViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
912 ICOM_INTERFACE(vp, IDirect3DViewport3));
915 /*****************************************************************************
916 * IDirect3DDevice3::NextViewport
918 * Returns a viewport from the viewport list, depending on the
919 * passed viewport and the flags.
921 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
925 * Viewport: Viewport to use for beginning the search
926 * Flags: D3DNEXT_NEXT, D3DNEXT_HEAD or D3DNEXT_TAIL
930 * DDERR_INVALIDPARAMS if the flags were wrong, or Viewport was NULL
932 *****************************************************************************/
933 static HRESULT WINAPI
934 IDirect3DDeviceImpl_3_NextViewport(IDirect3DDevice3 *iface,
935 IDirect3DViewport3 *Viewport3,
936 IDirect3DViewport3 **lplpDirect3DViewport3,
939 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
940 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport3);
941 IDirect3DViewportImpl *res = NULL;
943 TRACE("(%p)->(%p,%p,%08x)\n", This, vp, lplpDirect3DViewport3, Flags);
947 *lplpDirect3DViewport3 = NULL;
948 return DDERR_INVALIDPARAMS;
952 EnterCriticalSection(&ddraw_cs);
962 res = This->viewport_list;
967 IDirect3DViewportImpl *cur_viewport = This->viewport_list;
968 if (cur_viewport != NULL)
970 while (cur_viewport->next != NULL) cur_viewport = cur_viewport->next;
976 *lplpDirect3DViewport3 = NULL;
977 LeaveCriticalSection(&ddraw_cs);
978 return DDERR_INVALIDPARAMS;
981 *lplpDirect3DViewport3 = ICOM_INTERFACE(res, IDirect3DViewport3);
982 LeaveCriticalSection(&ddraw_cs);
986 static HRESULT WINAPI
987 Thunk_IDirect3DDeviceImpl_2_NextViewport(IDirect3DDevice2 *iface,
988 IDirect3DViewport2 *Viewport2,
989 IDirect3DViewport2 **lplpDirect3DViewport2,
992 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
993 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport2);
994 IDirect3DViewport3 *res;
996 TRACE_(ddraw_thunk)("(%p)->(%p,%p,%08x) thunking to IDirect3DDevice3 interface.\n", This, vp, lplpDirect3DViewport2, Flags);
997 hr = IDirect3DDevice3_NextViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
998 ICOM_INTERFACE(vp, IDirect3DViewport3),
1001 *lplpDirect3DViewport2 = (IDirect3DViewport2 *) COM_INTERFACE_CAST(IDirect3DViewportImpl, IDirect3DViewport3, IDirect3DViewport3, res);
1005 static HRESULT WINAPI
1006 Thunk_IDirect3DDeviceImpl_1_NextViewport(IDirect3DDevice *iface,
1007 IDirect3DViewport *Viewport,
1008 IDirect3DViewport **lplpDirect3DViewport,
1011 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1012 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport);
1013 IDirect3DViewport3 *res;
1015 TRACE_(ddraw_thunk)("(%p)->(%p,%p,%08x) thunking to IDirect3DDevice3 interface.\n", This, vp, lplpDirect3DViewport, Flags);
1016 hr = IDirect3DDevice3_NextViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
1017 ICOM_INTERFACE(vp, IDirect3DViewport3),
1020 *lplpDirect3DViewport = (IDirect3DViewport *) COM_INTERFACE_CAST(IDirect3DViewportImpl, IDirect3DViewport3, IDirect3DViewport3, res);
1024 /*****************************************************************************
1025 * IDirect3DDevice::Pick
1027 * Executes an execute buffer without performing rendering. Instead, a
1028 * list of primitives that intersect with (x1,y1) of the passed rectangle
1029 * is created. IDirect3DDevice::GetPickRecords can be used to retrieve
1035 * ExecuteBuffer: Buffer to execute
1036 * Viewport: Viewport to use for execution
1037 * Flags: None are defined, according to the SDK
1038 * Rect: Specifies the coordinates to be picked. Only x1 and y2 are used,
1039 * x2 and y2 are ignored.
1042 * D3D_OK because it's a stub
1044 *****************************************************************************/
1045 static HRESULT WINAPI
1046 IDirect3DDeviceImpl_1_Pick(IDirect3DDevice *iface,
1047 IDirect3DExecuteBuffer *ExecuteBuffer,
1048 IDirect3DViewport *Viewport,
1052 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1053 IDirect3DExecuteBufferImpl *execbuf = ICOM_OBJECT(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, ExecuteBuffer);
1054 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport);
1055 FIXME("(%p)->(%p,%p,%08x,%p): stub!\n", This, execbuf, vp, Flags, Rect);
1060 /*****************************************************************************
1061 * IDirect3DDevice::GetPickRecords
1063 * Retrieves the pick records generated by IDirect3DDevice::GetPickRecords
1068 * Count: Pointer to a DWORD containing the numbers of pick records to
1070 * D3DPickRec: Address to store the resulting D3DPICKRECORD array.
1073 * D3D_OK, because it's a stub
1075 *****************************************************************************/
1076 static HRESULT WINAPI
1077 IDirect3DDeviceImpl_1_GetPickRecords(IDirect3DDevice *iface,
1079 D3DPICKRECORD *D3DPickRec)
1081 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1082 FIXME("(%p)->(%p,%p): stub!\n", This, Count, D3DPickRec);
1087 /*****************************************************************************
1088 * IDirect3DDevice7::EnumTextureformats
1090 * Enumerates the supported texture formats. It has a list of all possible
1091 * formats and calls IWineD3D::CheckDeviceFormat for each format to see if
1092 * WineD3D supports it. If so, then it is passed to the app.
1094 * This is for Version 7 and 3, older versions have a different
1095 * callback function and their own implementation
1098 * Callback: Callback to call for each enumerated format
1099 * Arg: Argument to pass to the callback
1103 * DDERR_INVALIDPARAMS if Callback == NULL
1105 *****************************************************************************/
1106 static HRESULT WINAPI
1107 IDirect3DDeviceImpl_7_EnumTextureFormats(IDirect3DDevice7 *iface,
1108 LPD3DENUMPIXELFORMATSCALLBACK Callback,
1111 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1115 WINED3DFORMAT FormatList[] = {
1117 WINED3DFMT_A8R8G8B8,
1118 WINED3DFMT_X8R8G8B8,
1122 WINED3DFMT_A1R5G5B5,
1123 WINED3DFMT_A4R4G4B4,
1125 WINED3DFMT_X1R5G5B5,
1135 WINED3DFORMAT BumpFormatList[] = {
1138 WINED3DFMT_X8L8V8U8,
1139 WINED3DFMT_Q8W8V8U8,
1141 WINED3DFMT_W11V11U10,
1142 WINED3DFMT_A2W10V10U10
1145 TRACE("(%p)->(%p,%p): Relay\n", This, Callback, Arg);
1148 return DDERR_INVALIDPARAMS;
1150 EnterCriticalSection(&ddraw_cs);
1151 for(i = 0; i < sizeof(FormatList) / sizeof(WINED3DFORMAT); i++)
1153 hr = IWineD3D_CheckDeviceFormat(This->ddraw->wineD3D,
1156 0 /* AdapterFormat */,
1158 0 /* ResourceType */,
1162 DDPIXELFORMAT pformat;
1164 memset(&pformat, 0, sizeof(pformat));
1165 pformat.dwSize = sizeof(pformat);
1166 PixelFormat_WineD3DtoDD(&pformat, FormatList[i]);
1168 TRACE("Enumerating WineD3DFormat %d\n", FormatList[i]);
1169 hr = Callback(&pformat, Arg);
1170 if(hr != DDENUMRET_OK)
1172 TRACE("Format enumeration cancelled by application\n");
1173 LeaveCriticalSection(&ddraw_cs);
1179 for(i = 0; i < sizeof(BumpFormatList) / sizeof(WINED3DFORMAT); i++)
1181 hr = IWineD3D_CheckDeviceFormat(This->ddraw->wineD3D,
1184 0 /* AdapterFormat */,
1185 WINED3DUSAGE_QUERY_LEGACYBUMPMAP,
1186 0 /* ResourceType */,
1190 DDPIXELFORMAT pformat;
1192 memset(&pformat, 0, sizeof(pformat));
1193 pformat.dwSize = sizeof(pformat);
1194 PixelFormat_WineD3DtoDD(&pformat, BumpFormatList[i]);
1196 TRACE("Enumerating WineD3DFormat %d\n", BumpFormatList[i]);
1197 hr = Callback(&pformat, Arg);
1198 if(hr != DDENUMRET_OK)
1200 TRACE("Format enumeration cancelled by application\n");
1201 LeaveCriticalSection(&ddraw_cs);
1206 TRACE("End of enumeration\n");
1207 LeaveCriticalSection(&ddraw_cs);
1211 static HRESULT WINAPI
1212 Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats(IDirect3DDevice3 *iface,
1213 LPD3DENUMPIXELFORMATSCALLBACK Callback,
1216 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1217 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice7 interface.\n", This, Callback, Arg);
1218 return IDirect3DDevice7_EnumTextureFormats(ICOM_INTERFACE(This, IDirect3DDevice7),
1223 /*****************************************************************************
1224 * IDirect3DDevice2::EnumTextureformats
1226 * EnumTextureFormats for Version 1 and 2, see
1227 * IDirect3DDevice7::EnumTexureFormats for a more detailed description.
1229 * This version has a different callback and does not enumerate FourCC
1232 *****************************************************************************/
1233 static HRESULT WINAPI
1234 IDirect3DDeviceImpl_2_EnumTextureFormats(IDirect3DDevice2 *iface,
1235 LPD3DENUMTEXTUREFORMATSCALLBACK Callback,
1238 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1242 WINED3DFORMAT FormatList[] = {
1244 WINED3DFMT_A8R8G8B8,
1245 WINED3DFMT_X8R8G8B8,
1249 WINED3DFMT_A1R5G5B5,
1250 WINED3DFMT_A4R4G4B4,
1252 WINED3DFMT_X1R5G5B5,
1256 /* FOURCC codes - Not in this version*/
1259 TRACE("(%p)->(%p,%p): Relay\n", This, Callback, Arg);
1262 return DDERR_INVALIDPARAMS;
1264 EnterCriticalSection(&ddraw_cs);
1265 for(i = 0; i < sizeof(FormatList) / sizeof(WINED3DFORMAT); i++)
1267 hr = IWineD3D_CheckDeviceFormat(This->ddraw->wineD3D,
1270 0 /* AdapterFormat */,
1272 0 /* ResourceType */,
1276 DDSURFACEDESC sdesc;
1278 memset(&sdesc, 0, sizeof(sdesc));
1279 sdesc.dwSize = sizeof(sdesc);
1280 sdesc.dwFlags = DDSD_PIXELFORMAT | DDSD_CAPS;
1281 sdesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1282 sdesc.ddpfPixelFormat.dwSize = sizeof(sdesc.ddpfPixelFormat);
1283 PixelFormat_WineD3DtoDD(&sdesc.ddpfPixelFormat, FormatList[i]);
1285 TRACE("Enumerating WineD3DFormat %d\n", FormatList[i]);
1286 hr = Callback(&sdesc, Arg);
1287 if(hr != DDENUMRET_OK)
1289 TRACE("Format enumeration cancelled by application\n");
1290 LeaveCriticalSection(&ddraw_cs);
1295 TRACE("End of enumeration\n");
1296 LeaveCriticalSection(&ddraw_cs);
1300 static HRESULT WINAPI
1301 Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats(IDirect3DDevice *iface,
1302 LPD3DENUMTEXTUREFORMATSCALLBACK Callback,
1305 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1306 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice2 interface.\n", This, Callback, Arg);
1307 return IDirect3DDevice2_EnumTextureFormats(ICOM_INTERFACE(This, IDirect3DDevice2),
1312 /*****************************************************************************
1313 * IDirect3DDevice::CreateMatrix
1315 * Creates a matrix handle. A handle is created and memory for a D3DMATRIX is
1316 * allocated for the handle.
1321 * D3DMatHandle: Address to return the handle at
1325 * DDERR_INVALIDPARAMS if D3DMatHandle = NULL
1327 *****************************************************************************/
1328 static HRESULT WINAPI
1329 IDirect3DDeviceImpl_1_CreateMatrix(IDirect3DDevice *iface, D3DMATRIXHANDLE *D3DMatHandle)
1331 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1333 TRACE("(%p)->(%p)\n", This, D3DMatHandle);
1336 return DDERR_INVALIDPARAMS;
1338 Matrix = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(D3DMATRIX));
1341 ERR("Out of memory when allocating a D3DMATRIX\n");
1342 return DDERR_OUTOFMEMORY;
1345 EnterCriticalSection(&ddraw_cs);
1346 *D3DMatHandle = IDirect3DDeviceImpl_CreateHandle(This);
1347 if(!(*D3DMatHandle))
1349 ERR("Failed to create a matrix handle\n");
1350 HeapFree(GetProcessHeap(), 0, Matrix);
1351 LeaveCriticalSection(&ddraw_cs);
1352 return DDERR_OUTOFMEMORY;
1354 This->Handles[*D3DMatHandle - 1].ptr = Matrix;
1355 This->Handles[*D3DMatHandle - 1].type = DDrawHandle_Matrix;
1356 TRACE(" returning matrix handle %d\n", *D3DMatHandle);
1358 LeaveCriticalSection(&ddraw_cs);
1362 /*****************************************************************************
1363 * IDirect3DDevice::SetMatrix
1365 * Sets a matrix for a matrix handle. The matrix is copied into the memory
1366 * allocated for the handle
1371 * D3DMatHandle: Handle to set the matrix to
1372 * D3DMatrix: Matrix to set
1376 * DDERR_INVALIDPARAMS if the handle of the matrix is invalid or the matrix
1379 *****************************************************************************/
1380 static HRESULT WINAPI
1381 IDirect3DDeviceImpl_1_SetMatrix(IDirect3DDevice *iface,
1382 D3DMATRIXHANDLE D3DMatHandle,
1383 D3DMATRIX *D3DMatrix)
1385 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1386 TRACE("(%p)->(%08x,%p)\n", This, D3DMatHandle, D3DMatrix);
1388 if( (!D3DMatHandle) || (!D3DMatrix) )
1389 return DDERR_INVALIDPARAMS;
1391 EnterCriticalSection(&ddraw_cs);
1392 if(D3DMatHandle > This->numHandles)
1394 ERR("Handle %d out of range\n", D3DMatHandle);
1395 LeaveCriticalSection(&ddraw_cs);
1396 return DDERR_INVALIDPARAMS;
1398 else if(This->Handles[D3DMatHandle - 1].type != DDrawHandle_Matrix)
1400 ERR("Handle %d is not a matrix handle\n", D3DMatHandle);
1401 LeaveCriticalSection(&ddraw_cs);
1402 return DDERR_INVALIDPARAMS;
1406 dump_D3DMATRIX(D3DMatrix);
1408 *((D3DMATRIX *) This->Handles[D3DMatHandle - 1].ptr) = *D3DMatrix;
1410 if(This->world == D3DMatHandle)
1412 IWineD3DDevice_SetTransform(This->wineD3DDevice,
1413 WINED3DTS_WORLDMATRIX(0),
1414 (WINED3DMATRIX *) D3DMatrix);
1416 if(This->view == D3DMatHandle)
1418 IWineD3DDevice_SetTransform(This->wineD3DDevice,
1420 (WINED3DMATRIX *) D3DMatrix);
1422 if(This->proj == D3DMatHandle)
1424 IWineD3DDevice_SetTransform(This->wineD3DDevice,
1425 WINED3DTS_PROJECTION,
1426 (WINED3DMATRIX *) D3DMatrix);
1429 LeaveCriticalSection(&ddraw_cs);
1433 /*****************************************************************************
1434 * IDirect3DDevice::SetMatrix
1436 * Returns the content of a D3DMATRIX handle
1441 * D3DMatHandle: Matrix handle to read the content from
1442 * D3DMatrix: Address to store the content at
1446 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid or D3DMatrix is NULL
1448 *****************************************************************************/
1449 static HRESULT WINAPI
1450 IDirect3DDeviceImpl_1_GetMatrix(IDirect3DDevice *iface,
1451 D3DMATRIXHANDLE D3DMatHandle,
1452 D3DMATRIX *D3DMatrix)
1454 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1455 TRACE("(%p)->(%08x,%p)\n", This, D3DMatHandle, D3DMatrix);
1458 return DDERR_INVALIDPARAMS;
1460 return DDERR_INVALIDPARAMS;
1462 EnterCriticalSection(&ddraw_cs);
1463 if(D3DMatHandle > This->numHandles)
1465 ERR("Handle %d out of range\n", D3DMatHandle);
1466 LeaveCriticalSection(&ddraw_cs);
1467 return DDERR_INVALIDPARAMS;
1469 else if(This->Handles[D3DMatHandle - 1].type != DDrawHandle_Matrix)
1471 ERR("Handle %d is not a matrix handle\n", D3DMatHandle);
1472 LeaveCriticalSection(&ddraw_cs);
1473 return DDERR_INVALIDPARAMS;
1476 /* The handle is simply a pointer to a D3DMATRIX structure */
1477 *D3DMatrix = *((D3DMATRIX *) This->Handles[D3DMatHandle - 1].ptr);
1479 LeaveCriticalSection(&ddraw_cs);
1483 /*****************************************************************************
1484 * IDirect3DDevice::DeleteMatrix
1486 * Destroys a Matrix handle. Frees the memory and unsets the handle data
1491 * D3DMatHandle: Handle to destroy
1495 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid
1497 *****************************************************************************/
1498 static HRESULT WINAPI
1499 IDirect3DDeviceImpl_1_DeleteMatrix(IDirect3DDevice *iface,
1500 D3DMATRIXHANDLE D3DMatHandle)
1502 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1503 TRACE("(%p)->(%08x)\n", This, D3DMatHandle);
1506 return DDERR_INVALIDPARAMS;
1508 EnterCriticalSection(&ddraw_cs);
1509 if(D3DMatHandle > This->numHandles)
1511 ERR("Handle %d out of range\n", D3DMatHandle);
1512 LeaveCriticalSection(&ddraw_cs);
1513 return DDERR_INVALIDPARAMS;
1515 else if(This->Handles[D3DMatHandle - 1].type != DDrawHandle_Matrix)
1517 ERR("Handle %d is not a matrix handle\n", D3DMatHandle);
1518 LeaveCriticalSection(&ddraw_cs);
1519 return DDERR_INVALIDPARAMS;
1522 HeapFree(GetProcessHeap(), 0, This->Handles[D3DMatHandle - 1].ptr);
1523 This->Handles[D3DMatHandle - 1].ptr = NULL;
1524 This->Handles[D3DMatHandle - 1].type = DDrawHandle_Unknown;
1526 LeaveCriticalSection(&ddraw_cs);
1530 /*****************************************************************************
1531 * IDirect3DDevice7::BeginScene
1533 * This method must be called before any rendering is performed.
1534 * IDirect3DDevice::EndScene has to be called after the scene is complete
1536 * Version 1, 2, 3 and 7
1539 * D3D_OK on success, for details see IWineD3DDevice::BeginScene
1540 * D3DERR_SCENE_IN_SCENE if WineD3D returns an error(Only in case of an already
1543 *****************************************************************************/
1544 static HRESULT WINAPI
1545 IDirect3DDeviceImpl_7_BeginScene(IDirect3DDevice7 *iface)
1547 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1549 TRACE("(%p): Relay\n", This);
1551 EnterCriticalSection(&ddraw_cs);
1552 hr = IWineD3DDevice_BeginScene(This->wineD3DDevice);
1553 LeaveCriticalSection(&ddraw_cs);
1554 if(hr == WINED3D_OK) return D3D_OK;
1555 else return D3DERR_SCENE_IN_SCENE; /* TODO: Other possible causes of failure */
1558 static HRESULT WINAPI
1559 Thunk_IDirect3DDeviceImpl_3_BeginScene(IDirect3DDevice3 *iface)
1561 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1562 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1563 return IDirect3DDevice7_BeginScene(ICOM_INTERFACE(This, IDirect3DDevice7));
1566 static HRESULT WINAPI
1567 Thunk_IDirect3DDeviceImpl_2_BeginScene(IDirect3DDevice2 *iface)
1569 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1570 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1571 return IDirect3DDevice7_BeginScene(ICOM_INTERFACE(This, IDirect3DDevice7));
1574 static HRESULT WINAPI
1575 Thunk_IDirect3DDeviceImpl_1_BeginScene(IDirect3DDevice *iface)
1577 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1578 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1579 return IDirect3DDevice7_BeginScene(ICOM_INTERFACE(This, IDirect3DDevice7));
1582 /*****************************************************************************
1583 * IDirect3DDevice7::EndScene
1585 * Ends a scene that has been begun with IDirect3DDevice7::BeginScene.
1586 * This method must be called after rendering is finished.
1588 * Version 1, 2, 3 and 7
1591 * D3D_OK on success, for details see IWineD3DDevice::EndScene
1592 * D3DERR_SCENE_NOT_IN_SCENE is returned if WineD3D returns an error. It does
1593 * that only if the scene was already ended.
1595 *****************************************************************************/
1596 static HRESULT WINAPI
1597 IDirect3DDeviceImpl_7_EndScene(IDirect3DDevice7 *iface)
1599 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1601 TRACE("(%p): Relay\n", This);
1603 EnterCriticalSection(&ddraw_cs);
1604 hr = IWineD3DDevice_EndScene(This->wineD3DDevice);
1605 LeaveCriticalSection(&ddraw_cs);
1606 if(hr == WINED3D_OK) return D3D_OK;
1607 else return D3DERR_SCENE_NOT_IN_SCENE;
1610 static HRESULT WINAPI
1611 Thunk_IDirect3DDeviceImpl_3_EndScene(IDirect3DDevice3 *iface)
1613 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1614 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1615 return IDirect3DDevice7_EndScene(ICOM_INTERFACE(This, IDirect3DDevice7));
1618 static HRESULT WINAPI
1619 Thunk_IDirect3DDeviceImpl_2_EndScene(IDirect3DDevice2 *iface)
1621 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1622 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1623 return IDirect3DDevice7_EndScene(ICOM_INTERFACE(This, IDirect3DDevice7));
1626 static HRESULT WINAPI
1627 Thunk_IDirect3DDeviceImpl_1_EndScene(IDirect3DDevice *iface)
1629 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1630 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1631 return IDirect3DDevice7_EndScene(ICOM_INTERFACE(This, IDirect3DDevice7));
1634 /*****************************************************************************
1635 * IDirect3DDevice7::GetDirect3D
1637 * Returns the IDirect3D(= interface to the DirectDraw object) used to create
1641 * Direct3D7: Address to store the interface pointer at
1645 * DDERR_INVALIDPARAMS if Direct3D7 == NULL
1647 *****************************************************************************/
1648 static HRESULT WINAPI
1649 IDirect3DDeviceImpl_7_GetDirect3D(IDirect3DDevice7 *iface,
1650 IDirect3D7 **Direct3D7)
1652 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1653 TRACE("(%p)->(%p)\n", This, Direct3D7);
1656 return DDERR_INVALIDPARAMS;
1658 *Direct3D7 = ICOM_INTERFACE(This->ddraw, IDirect3D7);
1659 IDirect3D7_AddRef(*Direct3D7);
1661 TRACE(" returning interface %p\n", *Direct3D7);
1665 static HRESULT WINAPI
1666 Thunk_IDirect3DDeviceImpl_3_GetDirect3D(IDirect3DDevice3 *iface,
1667 IDirect3D3 **Direct3D3)
1669 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1671 IDirect3D7 *ret_ptr;
1673 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Direct3D3);
1674 ret = IDirect3DDevice7_GetDirect3D(ICOM_INTERFACE(This, IDirect3DDevice7),
1678 *Direct3D3 = COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D7, IDirect3D3, ret_ptr);
1679 TRACE(" returning interface %p\n", *Direct3D3);
1683 static HRESULT WINAPI
1684 Thunk_IDirect3DDeviceImpl_2_GetDirect3D(IDirect3DDevice2 *iface,
1685 IDirect3D2 **Direct3D2)
1687 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1689 IDirect3D7 *ret_ptr;
1691 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Direct3D2);
1692 ret = IDirect3DDevice7_GetDirect3D(ICOM_INTERFACE(This, IDirect3DDevice7),
1696 *Direct3D2 = COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D7, IDirect3D2, ret_ptr);
1697 TRACE(" returning interface %p\n", *Direct3D2);
1701 static HRESULT WINAPI
1702 Thunk_IDirect3DDeviceImpl_1_GetDirect3D(IDirect3DDevice *iface,
1703 IDirect3D **Direct3D)
1705 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1707 IDirect3D7 *ret_ptr;
1709 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Direct3D);
1710 ret = IDirect3DDevice7_GetDirect3D(ICOM_INTERFACE(This, IDirect3DDevice7),
1714 *Direct3D = COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D7, IDirect3D, ret_ptr);
1715 TRACE(" returning interface %p\n", *Direct3D);
1719 /*****************************************************************************
1720 * IDirect3DDevice3::SetCurrentViewport
1722 * Sets a Direct3DViewport as the current viewport.
1723 * For the thunks note that all viewport interface versions are equal
1726 * Direct3DViewport3: The viewport to set
1732 * (Is a NULL viewport valid?)
1734 *****************************************************************************/
1735 static HRESULT WINAPI
1736 IDirect3DDeviceImpl_3_SetCurrentViewport(IDirect3DDevice3 *iface,
1737 IDirect3DViewport3 *Direct3DViewport3)
1739 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1740 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport3);
1741 TRACE("(%p)->(%p)\n", This, Direct3DViewport3);
1743 EnterCriticalSection(&ddraw_cs);
1744 /* Do nothing if the specified viewport is the same as the current one */
1745 if (This->current_viewport == vp )
1747 LeaveCriticalSection(&ddraw_cs);
1751 /* Should check if the viewport was added or not */
1753 /* Release previous viewport and AddRef the new one */
1754 if (This->current_viewport)
1756 TRACE("ViewportImpl is at %p, interface is at %p\n", This->current_viewport, ICOM_INTERFACE(This->current_viewport, IDirect3DViewport3));
1757 IDirect3DViewport3_Release( ICOM_INTERFACE(This->current_viewport, IDirect3DViewport3) );
1759 IDirect3DViewport3_AddRef(Direct3DViewport3);
1761 /* Set this viewport as the current viewport */
1762 This->current_viewport = vp;
1764 /* Activate this viewport */
1765 This->current_viewport->active_device = This;
1766 This->current_viewport->activate(This->current_viewport);
1768 LeaveCriticalSection(&ddraw_cs);
1772 static HRESULT WINAPI
1773 Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport(IDirect3DDevice2 *iface,
1774 IDirect3DViewport2 *Direct3DViewport2)
1776 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1777 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport2);
1778 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
1779 return IDirect3DDevice3_SetCurrentViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
1780 ICOM_INTERFACE(vp, IDirect3DViewport3));
1783 /*****************************************************************************
1784 * IDirect3DDevice3::GetCurrentViewport
1786 * Returns the currently active viewport.
1791 * Direct3DViewport3: Address to return the interface pointer at
1795 * DDERR_INVALIDPARAMS if Direct3DViewport == NULL
1797 *****************************************************************************/
1798 static HRESULT WINAPI
1799 IDirect3DDeviceImpl_3_GetCurrentViewport(IDirect3DDevice3 *iface,
1800 IDirect3DViewport3 **Direct3DViewport3)
1802 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1803 TRACE("(%p)->(%p)\n", This, Direct3DViewport3);
1805 if(!Direct3DViewport3)
1806 return DDERR_INVALIDPARAMS;
1808 EnterCriticalSection(&ddraw_cs);
1809 *Direct3DViewport3 = ICOM_INTERFACE(This->current_viewport, IDirect3DViewport3);
1811 /* AddRef the returned viewport */
1812 if(*Direct3DViewport3) IDirect3DViewport3_AddRef(*Direct3DViewport3);
1814 TRACE(" returning interface %p\n", *Direct3DViewport3);
1816 LeaveCriticalSection(&ddraw_cs);
1820 static HRESULT WINAPI
1821 Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport(IDirect3DDevice2 *iface,
1822 IDirect3DViewport2 **Direct3DViewport2)
1824 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1826 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, Direct3DViewport2);
1827 hr = IDirect3DDevice3_GetCurrentViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
1828 (IDirect3DViewport3 **) Direct3DViewport2);
1829 if(hr != D3D_OK) return hr;
1830 *Direct3DViewport2 = (IDirect3DViewport2 *) COM_INTERFACE_CAST(IDirect3DViewportImpl, IDirect3DViewport3, IDirect3DViewport3, *Direct3DViewport2);
1834 /*****************************************************************************
1835 * IDirect3DDevice7::SetRenderTarget
1837 * Sets the render target for the Direct3DDevice.
1838 * For the thunks note that IDirectDrawSurface7 == IDirectDrawSurface4 and
1839 * IDirectDrawSurface3 == IDirectDrawSurface
1841 * Version 2, 3 and 7
1844 * NewTarget: Pointer to an IDirectDrawSurface7 interface to set as the new
1849 * D3D_OK on success, for details see IWineD3DDevice::SetRenderTarget
1851 *****************************************************************************/
1852 static HRESULT WINAPI
1853 IDirect3DDeviceImpl_7_SetRenderTarget(IDirect3DDevice7 *iface,
1854 IDirectDrawSurface7 *NewTarget,
1857 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1858 IDirectDrawSurfaceImpl *Target = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, NewTarget);
1860 TRACE("(%p)->(%p,%08x): Relay\n", This, NewTarget, Flags);
1862 EnterCriticalSection(&ddraw_cs);
1863 /* Flags: Not used */
1865 if(This->target == Target)
1867 TRACE("No-op SetRenderTarget operation, not doing anything\n");
1868 LeaveCriticalSection(&ddraw_cs);
1872 hr = IWineD3DDevice_SetRenderTarget(This->wineD3DDevice,
1874 Target ? Target->WineD3DSurface : NULL);
1877 LeaveCriticalSection(&ddraw_cs);
1880 IDirectDrawSurface7_AddRef(NewTarget);
1881 IDirectDrawSurface7_Release(ICOM_INTERFACE(This->target, IDirectDrawSurface7));
1882 This->target = Target;
1883 IDirect3DDeviceImpl_UpdateDepthStencil(This);
1884 LeaveCriticalSection(&ddraw_cs);
1888 static HRESULT WINAPI
1889 Thunk_IDirect3DDeviceImpl_3_SetRenderTarget(IDirect3DDevice3 *iface,
1890 IDirectDrawSurface4 *NewRenderTarget,
1893 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1894 IDirectDrawSurfaceImpl *Target = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, NewRenderTarget);
1895 TRACE_(ddraw_thunk)("(%p)->(%p,%08x) thunking to IDirect3DDevice7 interface.\n", This, Target, Flags);
1896 return IDirect3DDevice7_SetRenderTarget(ICOM_INTERFACE(This, IDirect3DDevice7),
1897 ICOM_INTERFACE(Target, IDirectDrawSurface7),
1901 static HRESULT WINAPI
1902 Thunk_IDirect3DDeviceImpl_2_SetRenderTarget(IDirect3DDevice2 *iface,
1903 IDirectDrawSurface *NewRenderTarget,
1906 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1907 IDirectDrawSurfaceImpl *Target = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface3, NewRenderTarget);
1908 TRACE_(ddraw_thunk)("(%p)->(%p,%08x) thunking to IDirect3DDevice7 interface.\n", This, Target, Flags);
1909 return IDirect3DDevice7_SetRenderTarget(ICOM_INTERFACE(This, IDirect3DDevice7),
1910 ICOM_INTERFACE(Target, IDirectDrawSurface7),
1914 /*****************************************************************************
1915 * IDirect3DDevice7::GetRenderTarget
1917 * Returns the current render target.
1918 * This is handled locally, because the WineD3D render target's parent
1921 * Version 2, 3 and 7
1924 * RenderTarget: Address to store the surface interface pointer
1928 * DDERR_INVALIDPARAMS if RenderTarget == NULL
1930 *****************************************************************************/
1931 static HRESULT WINAPI
1932 IDirect3DDeviceImpl_7_GetRenderTarget(IDirect3DDevice7 *iface,
1933 IDirectDrawSurface7 **RenderTarget)
1935 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1936 TRACE("(%p)->(%p): Relay\n", This, RenderTarget);
1939 return DDERR_INVALIDPARAMS;
1941 EnterCriticalSection(&ddraw_cs);
1942 *RenderTarget = ICOM_INTERFACE(This->target, IDirectDrawSurface7);
1943 IDirectDrawSurface7_AddRef(*RenderTarget);
1945 LeaveCriticalSection(&ddraw_cs);
1949 static HRESULT WINAPI
1950 Thunk_IDirect3DDeviceImpl_3_GetRenderTarget(IDirect3DDevice3 *iface,
1951 IDirectDrawSurface4 **RenderTarget)
1953 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1955 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, RenderTarget);
1956 hr = IDirect3DDevice7_GetRenderTarget(ICOM_INTERFACE(This, IDirect3DDevice7),
1957 (IDirectDrawSurface7 **) RenderTarget);
1958 if(hr != D3D_OK) return hr;
1959 *RenderTarget = (IDirectDrawSurface4 *) COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7, IDirectDrawSurface7, *RenderTarget);
1963 static HRESULT WINAPI
1964 Thunk_IDirect3DDeviceImpl_2_GetRenderTarget(IDirect3DDevice2 *iface,
1965 IDirectDrawSurface **RenderTarget)
1967 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1969 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, RenderTarget);
1970 hr = IDirect3DDevice7_GetRenderTarget(ICOM_INTERFACE(This, IDirect3DDevice7),
1971 (IDirectDrawSurface7 **) RenderTarget);
1972 if(hr != D3D_OK) return hr;
1973 *RenderTarget = (IDirectDrawSurface *) COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7, IDirectDrawSurface3, *RenderTarget);
1977 /*****************************************************************************
1978 * IDirect3DDevice3::Begin
1980 * Begins a description block of vertices. This is similar to glBegin()
1981 * and glEnd(). After a call to IDirect3DDevice3::End, the vertices
1982 * described with IDirect3DDevice::Vertex are drawn.
1987 * PrimitiveType: The type of primitives to draw
1988 * VertexTypeDesc: A flexible vertex format description of the vertices
1989 * Flags: Some flags..
1994 *****************************************************************************/
1995 static HRESULT WINAPI
1996 IDirect3DDeviceImpl_3_Begin(IDirect3DDevice3 *iface,
1997 D3DPRIMITIVETYPE PrimitiveType,
1998 DWORD VertexTypeDesc,
2001 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2002 TRACE("(%p)->(%d,%d,%08x)\n", This, PrimitiveType, VertexTypeDesc, Flags);
2004 EnterCriticalSection(&ddraw_cs);
2005 This->primitive_type = PrimitiveType;
2006 This->vertex_type = VertexTypeDesc;
2007 This->render_flags = Flags;
2008 This->vertex_size = get_flexible_vertex_size(This->vertex_type);
2009 This->nb_vertices = 0;
2010 LeaveCriticalSection(&ddraw_cs);
2015 static HRESULT WINAPI
2016 Thunk_IDirect3DDeviceImpl_2_Begin(IDirect3DDevice2 *iface,
2017 D3DPRIMITIVETYPE d3dpt,
2018 D3DVERTEXTYPE dwVertexTypeDesc,
2022 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2023 TRACE_(ddraw_thunk)("(%p/%p)->(%08x,%08x,%08x): Thunking to IDirect3DDevice3\n", This, iface, d3dpt, dwVertexTypeDesc, dwFlags);
2025 switch(dwVertexTypeDesc)
2027 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
2028 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
2029 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
2031 ERR("Unexpected vertex type %d\n", dwVertexTypeDesc);
2032 return DDERR_INVALIDPARAMS; /* Should never happen */
2035 return IDirect3DDevice3_Begin(ICOM_INTERFACE(This, IDirect3DDevice3),
2041 /*****************************************************************************
2042 * IDirect3DDevice3::BeginIndexed
2044 * Draws primitives based on vertices in a vertex array which are specified
2050 * PrimitiveType: Primitive type to draw
2051 * VertexType: A FVF description of the vertex format
2052 * Vertices: pointer to an array containing the vertices
2053 * NumVertices: The number of vertices in the vertex array
2054 * Flags: Some flags ...
2057 * D3D_OK, because it's a stub
2059 *****************************************************************************/
2060 static HRESULT WINAPI
2061 IDirect3DDeviceImpl_3_BeginIndexed(IDirect3DDevice3 *iface,
2062 D3DPRIMITIVETYPE PrimitiveType,
2068 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2069 FIXME("(%p)->(%08x,%08x,%p,%08x,%08x): stub!\n", This, PrimitiveType, VertexType, Vertices, NumVertices, Flags);
2074 static HRESULT WINAPI
2075 Thunk_IDirect3DDeviceImpl_2_BeginIndexed(IDirect3DDevice2 *iface,
2076 D3DPRIMITIVETYPE d3dptPrimitiveType,
2077 D3DVERTEXTYPE d3dvtVertexType,
2079 DWORD dwNumVertices,
2083 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2084 TRACE_(ddraw_thunk)("(%p/%p)->(%08x,%08x,%p,%08x,%08x): Thunking to IDirect3DDevice3\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwNumVertices, dwFlags);
2086 switch(d3dvtVertexType)
2088 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
2089 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
2090 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
2092 ERR("Unexpected vertex type %d\n", d3dvtVertexType);
2093 return DDERR_INVALIDPARAMS; /* Should never happen */
2096 return IDirect3DDevice3_BeginIndexed(ICOM_INTERFACE(This,IDirect3DDevice3),
2104 /*****************************************************************************
2105 * IDirect3DDevice3::Vertex
2107 * Draws a vertex as described by IDirect3DDevice3::Begin. It places all
2108 * drawn vertices in a vertex buffer. If the buffer is too small, its
2109 * size is increased.
2114 * Vertex: Pointer to the vertex
2117 * D3D_OK, on success
2118 * DDERR_INVALIDPARAMS if Vertex is NULL
2120 *****************************************************************************/
2121 static HRESULT WINAPI
2122 IDirect3DDeviceImpl_3_Vertex(IDirect3DDevice3 *iface,
2125 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2126 TRACE("(%p)->(%p)\n", This, Vertex);
2129 return DDERR_INVALIDPARAMS;
2131 EnterCriticalSection(&ddraw_cs);
2132 if ((This->nb_vertices+1)*This->vertex_size > This->buffer_size)
2135 This->buffer_size = This->buffer_size ? This->buffer_size * 2 : This->vertex_size * 3;
2136 old_buffer = This->vertex_buffer;
2137 This->vertex_buffer = HeapAlloc(GetProcessHeap(), 0, This->buffer_size);
2140 CopyMemory(This->vertex_buffer, old_buffer, This->nb_vertices * This->vertex_size);
2141 HeapFree(GetProcessHeap(), 0, old_buffer);
2145 CopyMemory(This->vertex_buffer + This->nb_vertices++ * This->vertex_size, Vertex, This->vertex_size);
2147 LeaveCriticalSection(&ddraw_cs);
2151 static HRESULT WINAPI
2152 Thunk_IDirect3DDeviceImpl_2_Vertex(IDirect3DDevice2 *iface,
2155 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2156 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, lpVertexType);
2157 return IDirect3DDevice3_Vertex(ICOM_INTERFACE(This, IDirect3DDevice3),
2161 /*****************************************************************************
2162 * IDirect3DDevice3::Index
2164 * Specifies an index to a vertex to be drawn. The vertex array has to
2165 * be specified with BeginIndexed first.
2168 * VertexIndex: The index of the vertex to draw
2171 * D3D_OK because it's a stub
2173 *****************************************************************************/
2174 static HRESULT WINAPI
2175 IDirect3DDeviceImpl_3_Index(IDirect3DDevice3 *iface,
2178 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2179 FIXME("(%p)->(%04x): stub!\n", This, VertexIndex);
2183 static HRESULT WINAPI
2184 Thunk_IDirect3DDeviceImpl_2_Index(IDirect3DDevice2 *iface,
2187 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2188 TRACE_(ddraw_thunk)("(%p)->(%04x) thunking to IDirect3DDevice3 interface.\n", This, wVertexIndex);
2189 return IDirect3DDevice3_Index(ICOM_INTERFACE(This, IDirect3DDevice3),
2193 /*****************************************************************************
2194 * IDirect3DDevice3::End
2196 * Ends a draw begun with IDirect3DDevice3::Begin or
2197 * IDirect3DDevice::BeginIndexed. The vertices specified with
2198 * IDirect3DDevice::Vertex or IDirect3DDevice::Index are drawn using
2199 * the IDirect3DDevice7::DrawPrimitive method. So far only
2200 * non-indexed mode is supported
2205 * Flags: Some flags, as usual. Don't know which are defined
2208 * The return value of IDirect3DDevice7::DrawPrimitive
2210 *****************************************************************************/
2211 static HRESULT WINAPI
2212 IDirect3DDeviceImpl_3_End(IDirect3DDevice3 *iface,
2215 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2216 TRACE("(%p)->(%08x)\n", This, Flags);
2218 return IDirect3DDevice7_DrawPrimitive(ICOM_INTERFACE(This, IDirect3DDevice7),
2219 This->primitive_type, This->vertex_type,
2220 This->vertex_buffer, This->nb_vertices,
2221 This->render_flags);
2224 static HRESULT WINAPI
2225 Thunk_IDirect3DDeviceImpl_2_End(IDirect3DDevice2 *iface,
2228 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2229 TRACE_(ddraw_thunk)("(%p)->(%08x) thunking to IDirect3DDevice3 interface.\n", This, dwFlags);
2230 return IDirect3DDevice3_End(ICOM_INTERFACE(This, IDirect3DDevice3),
2234 /*****************************************************************************
2235 * IDirect3DDevice7::GetRenderState
2237 * Returns the value of a render state. The possible render states are
2238 * defined in include/d3dtypes.h
2240 * Version 2, 3 and 7
2243 * RenderStateType: Render state to return the current setting of
2244 * Value: Address to store the value at
2247 * D3D_OK on success, for details see IWineD3DDevice::GetRenderState
2248 * DDERR_INVALIDPARAMS if Value == NULL
2250 *****************************************************************************/
2251 static HRESULT WINAPI
2252 IDirect3DDeviceImpl_7_GetRenderState(IDirect3DDevice7 *iface,
2253 D3DRENDERSTATETYPE RenderStateType,
2256 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
2258 TRACE("(%p)->(%08x,%p): Relay\n", This, RenderStateType, Value);
2261 return DDERR_INVALIDPARAMS;
2263 EnterCriticalSection(&ddraw_cs);
2264 switch(RenderStateType)
2266 case D3DRENDERSTATE_TEXTUREHANDLE:
2268 /* This state is wrapped to SetTexture in SetRenderState, so
2269 * it has to be wrapped to GetTexture here
2271 IWineD3DBaseTexture *tex = NULL;
2274 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice,
2278 if(hr == WINED3D_OK && tex)
2280 IDirectDrawSurface7 *parent = NULL;
2281 hr = IWineD3DBaseTexture_GetParent(tex,
2282 (IUnknown **) &parent);
2285 /* The parent of the texture is the IDirectDrawSurface7 interface
2286 * of the ddraw surface
2288 IDirectDrawSurfaceImpl *texImpl = ICOM_OBJECT(IDirectDrawSurfaceImpl,
2289 IDirectDrawSurface7,
2291 *Value = texImpl->Handle;
2292 IDirectDrawSurface7_Release(parent);
2294 IWineD3DBaseTexture_Release(tex);
2299 case D3DRENDERSTATE_TEXTUREMAG:
2301 WINED3DTEXTUREFILTERTYPE tex_mag;
2303 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2304 0, WINED3DSAMP_MAGFILTER,
2309 case WINED3DTEXF_POINT:
2310 *Value = D3DFILTER_NEAREST;
2312 case WINED3DTEXF_LINEAR:
2313 *Value = D3DFILTER_LINEAR;
2316 ERR("Unhandled texture mag %d !\n",tex_mag);
2322 case D3DRENDERSTATE_TEXTUREMIN:
2324 WINED3DTEXTUREFILTERTYPE tex_min;
2326 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2327 0, WINED3DSAMP_MINFILTER,
2332 case WINED3DTEXF_POINT:
2333 *Value = D3DFILTER_NEAREST;
2335 case WINED3DTEXF_LINEAR:
2336 *Value = D3DFILTER_LINEAR;
2339 ERR("Unhandled texture mag %d !\n",tex_min);
2345 case D3DRENDERSTATE_TEXTUREADDRESS:
2346 case D3DRENDERSTATE_TEXTUREADDRESSU:
2347 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2348 0, WINED3DSAMP_ADDRESSU,
2351 case D3DRENDERSTATE_TEXTUREADDRESSV:
2352 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2353 0, WINED3DSAMP_ADDRESSV,
2358 /* FIXME: Unhandled: D3DRENDERSTATE_STIPPLEPATTERN00 - 31 */
2359 hr = IWineD3DDevice_GetRenderState(This->wineD3DDevice,
2363 LeaveCriticalSection(&ddraw_cs);
2367 static HRESULT WINAPI
2368 Thunk_IDirect3DDeviceImpl_3_GetRenderState(IDirect3DDevice3 *iface,
2369 D3DRENDERSTATETYPE dwRenderStateType,
2370 DWORD *lpdwRenderState)
2372 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2373 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, dwRenderStateType, lpdwRenderState);
2374 return IDirect3DDevice7_GetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
2379 static HRESULT WINAPI
2380 IDirect3DDeviceImpl_2_GetRenderState(IDirect3DDevice2 *iface,
2381 D3DRENDERSTATETYPE dwRenderStateType,
2382 DWORD *lpdwRenderState)
2384 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2385 TRACE("(%p)->(%08x,%p): Relay\n", This, dwRenderStateType, lpdwRenderState);
2387 /* D3DRENDERSTATE_TEXTUREMAPBLEND is mapped to texture state stages in SetRenderState; reverse
2388 the mapping to get the value; other states relayed to IDirect3DDevice7::GetRenderState */
2389 switch(dwRenderStateType)
2391 case D3DRENDERSTATE_TEXTUREMAPBLEND:
2393 DWORD colorop, colorarg1, colorarg2;
2394 DWORD alphaop, alphaarg1, alphaarg2;
2396 EnterCriticalSection(&ddraw_cs);
2398 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, &colorop);
2399 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, &colorarg1);
2400 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, &colorarg2);
2401 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, &alphaop);
2402 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, &alphaarg1);
2403 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, &alphaarg2);
2405 if (colorop == WINED3DTOP_SELECTARG1 && colorarg1 == WINED3DTA_TEXTURE &&
2406 alphaop == WINED3DTOP_SELECTARG1 && alphaarg1 == WINED3DTA_TEXTURE)
2408 *lpdwRenderState = D3DTBLEND_DECAL;
2410 else if (colorop == WINED3DTOP_SELECTARG1 && colorarg1 == WINED3DTA_TEXTURE &&
2411 alphaop == WINED3DTOP_MODULATE && alphaarg1 == WINED3DTA_TEXTURE && alphaarg2 == WINED3DTA_CURRENT)
2413 *lpdwRenderState = D3DTBLEND_DECALALPHA;
2415 else if (colorop == WINED3DTOP_MODULATE && colorarg1 == WINED3DTA_TEXTURE && colorarg2 == WINED3DTA_CURRENT &&
2416 alphaop == WINED3DTOP_MODULATE && alphaarg1 == WINED3DTA_TEXTURE && alphaarg2 == WINED3DTA_CURRENT)
2418 *lpdwRenderState = D3DTBLEND_MODULATEALPHA;
2423 BOOL tex_alpha = FALSE;
2424 IWineD3DBaseTexture *tex = NULL;
2425 WINED3DSURFACE_DESC desc;
2427 DDPIXELFORMAT ddfmt;
2429 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice,
2433 if(hr == WINED3D_OK && tex)
2435 memset(&desc, 0, sizeof(desc));
2437 hr = IWineD3DTexture_GetLevelDesc((IWineD3DTexture*) tex, 0, &desc);
2440 ddfmt.dwSize = sizeof(ddfmt);
2441 PixelFormat_WineD3DtoDD(&ddfmt, fmt);
2442 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
2445 IWineD3DBaseTexture_Release(tex);
2448 if (!(colorop == WINED3DTOP_MODULATE && colorarg1 == WINED3DTA_TEXTURE && colorarg2 == WINED3DTA_CURRENT &&
2449 alphaop == WINED3DTOP_SELECTARG1 && alphaarg1 == (tex_alpha ? WINED3DTA_TEXTURE : WINED3DTA_CURRENT)))
2451 ERR("Unexpected texture stage state setup, returning D3DTBLEND_MODULATE - likely erroneous\n");
2454 *lpdwRenderState = D3DTBLEND_MODULATE;
2457 LeaveCriticalSection(&ddraw_cs);
2463 return IDirect3DDevice7_GetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
2469 /*****************************************************************************
2470 * IDirect3DDevice7::SetRenderState
2472 * Sets a render state. The possible render states are defined in
2473 * include/d3dtypes.h
2475 * Version 2, 3 and 7
2478 * RenderStateType: State to set
2479 * Value: Value to assign to that state
2482 * D3D_OK on success,
2483 * for details see IWineD3DDevice::SetRenderState
2485 *****************************************************************************/
2486 static HRESULT WINAPI
2487 IDirect3DDeviceImpl_7_SetRenderState(IDirect3DDevice7 *iface,
2488 D3DRENDERSTATETYPE RenderStateType,
2491 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
2493 TRACE("(%p)->(%08x,%d): Relay\n", This, RenderStateType, Value);
2495 EnterCriticalSection(&ddraw_cs);
2496 /* Some render states need special care */
2497 switch(RenderStateType)
2499 case D3DRENDERSTATE_TEXTUREHANDLE:
2503 hr = IWineD3DDevice_SetTexture(This->wineD3DDevice,
2509 if(Value > This->numHandles)
2511 FIXME("Specified handle %d out of range\n", Value);
2512 hr = DDERR_INVALIDPARAMS;
2515 if(This->Handles[Value - 1].type != DDrawHandle_Texture)
2517 FIXME("Handle %d isn't a texture handle\n", Value);
2518 hr = DDERR_INVALIDPARAMS;
2523 IDirectDrawSurfaceImpl *surf = (IDirectDrawSurfaceImpl *) This->Handles[Value - 1].ptr;
2524 hr = IWineD3DDevice_SetTexture(This->wineD3DDevice,
2526 surf->wineD3DTexture);
2531 case D3DRENDERSTATE_TEXTUREMAG:
2533 WINED3DTEXTUREFILTERTYPE tex_mag = WINED3DTEXF_NONE;
2535 switch ((D3DTEXTUREFILTER) Value)
2537 case D3DFILTER_NEAREST:
2538 case D3DFILTER_LINEARMIPNEAREST:
2539 tex_mag = WINED3DTEXF_POINT;
2541 case D3DFILTER_LINEAR:
2542 case D3DFILTER_LINEARMIPLINEAR:
2543 tex_mag = WINED3DTEXF_LINEAR;
2546 ERR("Unhandled texture mag %d !\n",Value);
2549 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2550 0, WINED3DSAMP_MAGFILTER,
2555 case D3DRENDERSTATE_TEXTUREMIN:
2557 WINED3DTEXTUREFILTERTYPE tex_min = WINED3DTEXF_NONE;
2558 WINED3DTEXTUREFILTERTYPE tex_mip = WINED3DTEXF_NONE;
2560 switch ((D3DTEXTUREFILTER) Value)
2562 case D3DFILTER_NEAREST:
2563 tex_min = WINED3DTEXF_POINT;
2565 case D3DFILTER_LINEAR:
2566 tex_min = WINED3DTEXF_LINEAR;
2568 case D3DFILTER_MIPNEAREST:
2569 tex_min = WINED3DTEXF_NONE;
2570 tex_mip = WINED3DTEXF_POINT;
2572 case D3DFILTER_MIPLINEAR:
2573 tex_min = WINED3DTEXF_NONE;
2574 tex_mip = WINED3DTEXF_LINEAR;
2576 case D3DFILTER_LINEARMIPNEAREST:
2577 tex_min = WINED3DTEXF_POINT;
2578 tex_mip = WINED3DTEXF_LINEAR;
2580 case D3DFILTER_LINEARMIPLINEAR:
2581 tex_min = WINED3DTEXF_LINEAR;
2582 tex_mip = WINED3DTEXF_LINEAR;
2586 ERR("Unhandled texture min %d !\n",Value);
2589 IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2590 0, WINED3DSAMP_MIPFILTER,
2592 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2593 0, WINED3DSAMP_MINFILTER,
2598 case D3DRENDERSTATE_TEXTUREADDRESS:
2599 IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2600 0, WINED3DSAMP_ADDRESSV,
2603 case D3DRENDERSTATE_TEXTUREADDRESSU:
2604 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2605 0, WINED3DSAMP_ADDRESSU,
2608 case D3DRENDERSTATE_TEXTUREADDRESSV:
2609 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2610 0, WINED3DSAMP_ADDRESSV,
2616 /* FIXME: Unhandled: D3DRENDERSTATE_STIPPLEPATTERN00 - 31 */
2618 hr = IWineD3DDevice_SetRenderState(This->wineD3DDevice,
2623 LeaveCriticalSection(&ddraw_cs);
2627 static HRESULT WINAPI
2628 Thunk_IDirect3DDeviceImpl_3_SetRenderState(IDirect3DDevice3 *iface,
2629 D3DRENDERSTATETYPE RenderStateType,
2632 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2633 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, RenderStateType, Value);
2634 return IDirect3DDevice7_SetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
2639 static HRESULT WINAPI
2640 IDirect3DDeviceImpl_2_SetRenderState(IDirect3DDevice2 *iface,
2641 D3DRENDERSTATETYPE RenderStateType,
2644 /* Note about D3DRENDERSTATE_TEXTUREMAPBLEND implementation: most of values
2645 for this state can be directly mapped to texture stage colorop and alphaop, but
2646 D3DTBLEND_MODULATE is tricky: it uses alpha from texture when available and alpha
2647 from diffuse otherwise. So changing the texture is monitored here to modify
2648 alphaarg when needed.
2650 Other states are relayed to IDirect3DDevice7
2652 Aliens vs Predator 1 depends on accurate D3DTBLEND_MODULATE emulation */
2655 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2656 TRACE("(%p)->(%08x,%d): Relay\n", This, RenderStateType, Value);
2658 switch(RenderStateType)
2660 case D3DRENDERSTATE_TEXTUREMAPBLEND:
2662 EnterCriticalSection(&ddraw_cs);
2664 switch ( (D3DTEXTUREBLEND) Value)
2666 case D3DTBLEND_MODULATE:
2668 BOOL tex_alpha = FALSE;
2669 IWineD3DBaseTexture *tex = NULL;
2670 WINED3DSURFACE_DESC desc;
2672 DDPIXELFORMAT ddfmt;
2674 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice,
2678 if(hr == WINED3D_OK && tex)
2680 memset(&desc, 0, sizeof(desc));
2682 hr = IWineD3DTexture_GetLevelDesc((IWineD3DTexture*) tex, 0, &desc);
2685 ddfmt.dwSize = sizeof(ddfmt);
2686 PixelFormat_WineD3DtoDD(&ddfmt, fmt);
2687 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
2690 IWineD3DBaseTexture_Release(tex);
2693 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG1);
2696 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2700 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_CURRENT);
2703 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2704 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2705 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_MODULATE);
2710 case D3DTBLEND_MODULATEALPHA:
2711 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2712 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2713 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2714 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
2715 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_MODULATE);
2716 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_MODULATE);
2719 case D3DTBLEND_DECAL:
2720 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2721 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2722 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_SELECTARG1);
2723 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG1);
2726 case D3DTBLEND_DECALALPHA:
2727 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2728 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2729 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
2730 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_SELECTARG1);
2731 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_MODULATE);
2735 ERR("Unhandled texture environment %d !\n",Value);
2738 LeaveCriticalSection(&ddraw_cs);
2744 case D3DRENDERSTATE_TEXTUREHANDLE:
2748 IDirect3DDevice2_GetRenderState(iface, D3DRENDERSTATE_TEXTUREMAPBLEND, &texmapblend);
2750 hr = IDirect3DDevice7_SetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
2751 D3DRENDERSTATE_TEXTUREHANDLE,
2754 if (texmapblend == D3DTBLEND_MODULATE)
2756 BOOL tex_alpha = FALSE;
2757 IWineD3DBaseTexture *tex = NULL;
2758 WINED3DSURFACE_DESC desc;
2760 DDPIXELFORMAT ddfmt;
2762 EnterCriticalSection(&ddraw_cs);
2764 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice,
2768 if(hr == WINED3D_OK && tex)
2770 memset(&desc, 0, sizeof(desc));
2772 hr = IWineD3DTexture_GetLevelDesc((IWineD3DTexture*) tex, 0, &desc);
2775 ddfmt.dwSize = sizeof(ddfmt);
2776 PixelFormat_WineD3DtoDD(&ddfmt, fmt);
2777 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
2780 IWineD3DBaseTexture_Release(tex);
2783 /* alphaop is WINED3DTOP_SELECTARG1 if it's D3DTBLEND_MODULATE, so only modify alphaarg1 */
2786 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2790 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_CURRENT);
2793 LeaveCriticalSection(&ddraw_cs);
2800 hr = IDirect3DDevice7_SetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
2809 /*****************************************************************************
2810 * Direct3DDevice3::SetLightState
2812 * Sets a light state for Direct3DDevice3 and Direct3DDevice2. The
2813 * light states are forwarded to Direct3DDevice7 render states
2818 * LightStateType: The light state to change
2819 * Value: The value to assign to that light state
2823 * DDERR_INVALIDPARAMS if the parameters were incorrect
2824 * Also check IDirect3DDevice7::SetRenderState
2826 *****************************************************************************/
2827 static HRESULT WINAPI
2828 IDirect3DDeviceImpl_3_SetLightState(IDirect3DDevice3 *iface,
2829 D3DLIGHTSTATETYPE LightStateType,
2832 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2835 TRACE("(%p)->(%08x,%08x)\n", This, LightStateType, Value);
2837 if (!LightStateType && (LightStateType > D3DLIGHTSTATE_COLORVERTEX))
2839 TRACE("Unexpected Light State Type\n");
2840 return DDERR_INVALIDPARAMS;
2843 EnterCriticalSection(&ddraw_cs);
2844 if (LightStateType == D3DLIGHTSTATE_MATERIAL /* 1 */)
2846 IDirect3DMaterialImpl *mat;
2848 if(Value == 0) mat = NULL;
2849 else if(Value > This->numHandles)
2851 ERR("Material handle out of range(%d)\n", Value);
2852 LeaveCriticalSection(&ddraw_cs);
2853 return DDERR_INVALIDPARAMS;
2855 else if(This->Handles[Value - 1].type != DDrawHandle_Material)
2857 ERR("Invalid handle %d\n", Value);
2858 LeaveCriticalSection(&ddraw_cs);
2859 return DDERR_INVALIDPARAMS;
2863 mat = (IDirect3DMaterialImpl *) This->Handles[Value - 1].ptr;
2868 TRACE(" activating material %p.\n", mat);
2873 FIXME(" D3DLIGHTSTATE_MATERIAL called with NULL material !!!\n");
2875 This->material = Value;
2877 else if (LightStateType == D3DLIGHTSTATE_COLORMODEL /* 3 */)
2882 ERR("DDCOLOR_MONO should not happen!\n");
2885 /* We are already in this mode */
2886 TRACE("Setting color model to RGB (no-op).\n");
2889 ERR("Unknown color model!\n");
2890 LeaveCriticalSection(&ddraw_cs);
2891 return DDERR_INVALIDPARAMS;
2896 D3DRENDERSTATETYPE rs;
2897 switch (LightStateType)
2899 case D3DLIGHTSTATE_AMBIENT: /* 2 */
2900 rs = D3DRENDERSTATE_AMBIENT;
2902 case D3DLIGHTSTATE_FOGMODE: /* 4 */
2903 rs = D3DRENDERSTATE_FOGVERTEXMODE;
2905 case D3DLIGHTSTATE_FOGSTART: /* 5 */
2906 rs = D3DRENDERSTATE_FOGSTART;
2908 case D3DLIGHTSTATE_FOGEND: /* 6 */
2909 rs = D3DRENDERSTATE_FOGEND;
2911 case D3DLIGHTSTATE_FOGDENSITY: /* 7 */
2912 rs = D3DRENDERSTATE_FOGDENSITY;
2914 case D3DLIGHTSTATE_COLORVERTEX: /* 8 */
2915 rs = D3DRENDERSTATE_COLORVERTEX;
2918 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType);
2919 LeaveCriticalSection(&ddraw_cs);
2920 return DDERR_INVALIDPARAMS;
2923 hr = IDirect3DDevice7_SetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
2926 LeaveCriticalSection(&ddraw_cs);
2930 LeaveCriticalSection(&ddraw_cs);
2934 static HRESULT WINAPI
2935 Thunk_IDirect3DDeviceImpl_2_SetLightState(IDirect3DDevice2 *iface,
2936 D3DLIGHTSTATETYPE LightStateType,
2939 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2940 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x) thunking to IDirect3DDevice3 interface.\n", This, LightStateType, Value);
2941 return IDirect3DDevice3_SetLightState(ICOM_INTERFACE(This, IDirect3DDevice3),
2946 /*****************************************************************************
2947 * IDirect3DDevice3::GetLightState
2949 * Returns the current setting of a light state. The state is read from
2950 * the Direct3DDevice7 render state.
2955 * LightStateType: The light state to return
2956 * Value: The address to store the light state setting at
2960 * DDDERR_INVALIDPARAMS if the parameters were incorrect
2961 * Also see IDirect3DDevice7::GetRenderState
2963 *****************************************************************************/
2964 static HRESULT WINAPI
2965 IDirect3DDeviceImpl_3_GetLightState(IDirect3DDevice3 *iface,
2966 D3DLIGHTSTATETYPE LightStateType,
2969 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2972 TRACE("(%p)->(%08x,%p)\n", This, LightStateType, Value);
2974 if (!LightStateType && (LightStateType > D3DLIGHTSTATE_COLORVERTEX))
2976 TRACE("Unexpected Light State Type\n");
2977 return DDERR_INVALIDPARAMS;
2981 return DDERR_INVALIDPARAMS;
2983 EnterCriticalSection(&ddraw_cs);
2984 if (LightStateType == D3DLIGHTSTATE_MATERIAL /* 1 */)
2986 *Value = This->material;
2988 else if (LightStateType == D3DLIGHTSTATE_COLORMODEL /* 3 */)
2990 *Value = D3DCOLOR_RGB;
2994 D3DRENDERSTATETYPE rs;
2995 switch (LightStateType)
2997 case D3DLIGHTSTATE_AMBIENT: /* 2 */
2998 rs = D3DRENDERSTATE_AMBIENT;
3000 case D3DLIGHTSTATE_FOGMODE: /* 4 */
3001 rs = D3DRENDERSTATE_FOGVERTEXMODE;
3003 case D3DLIGHTSTATE_FOGSTART: /* 5 */
3004 rs = D3DRENDERSTATE_FOGSTART;
3006 case D3DLIGHTSTATE_FOGEND: /* 6 */
3007 rs = D3DRENDERSTATE_FOGEND;
3009 case D3DLIGHTSTATE_FOGDENSITY: /* 7 */
3010 rs = D3DRENDERSTATE_FOGDENSITY;
3012 case D3DLIGHTSTATE_COLORVERTEX: /* 8 */
3013 rs = D3DRENDERSTATE_COLORVERTEX;
3016 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType);
3017 LeaveCriticalSection(&ddraw_cs);
3018 return DDERR_INVALIDPARAMS;
3021 hr = IDirect3DDevice7_GetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
3024 LeaveCriticalSection(&ddraw_cs);
3028 LeaveCriticalSection(&ddraw_cs);
3032 static HRESULT WINAPI
3033 Thunk_IDirect3DDeviceImpl_2_GetLightState(IDirect3DDevice2 *iface,
3034 D3DLIGHTSTATETYPE LightStateType,
3037 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3038 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice3 interface.\n", This, LightStateType, Value);
3039 return IDirect3DDevice3_GetLightState(ICOM_INTERFACE(This, IDirect3DDevice3),
3044 /*****************************************************************************
3045 * IDirect3DDevice7::SetTransform
3047 * Assigns a D3DMATRIX to a transform type. The transform types are defined
3048 * in include/d3dtypes.h.
3049 * The D3DTRANSFORMSTATE_WORLD (=1) is translated to D3DTS_WORLDMATRIX(0)
3050 * (=255) for wined3d, because the 1 transform state was removed in d3d8
3051 * and WineD3D already understands the replacement D3DTS_WORLDMATRIX(0)
3053 * Version 2, 3 and 7
3056 * TransformStateType: transform state to set
3057 * Matrix: Matrix to assign to the state
3061 * DDERR_INVALIDPARAMS if Matrix == NULL
3062 * For details see IWineD3DDevice::SetTransform
3064 *****************************************************************************/
3065 static HRESULT WINAPI
3066 IDirect3DDeviceImpl_7_SetTransform(IDirect3DDevice7 *iface,
3067 D3DTRANSFORMSTATETYPE TransformStateType,
3070 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3071 D3DTRANSFORMSTATETYPE type = TransformStateType;
3073 TRACE("(%p)->(%08x,%p): Relay\n", This, TransformStateType, Matrix);
3075 switch(TransformStateType)
3077 case D3DTRANSFORMSTATE_WORLD : type = WINED3DTS_WORLDMATRIX(0); break;
3078 case D3DTRANSFORMSTATE_WORLD1: type = WINED3DTS_WORLDMATRIX(1); break;
3079 case D3DTRANSFORMSTATE_WORLD2: type = WINED3DTS_WORLDMATRIX(2); break;
3080 case D3DTRANSFORMSTATE_WORLD3: type = WINED3DTS_WORLDMATRIX(3); break;
3081 default: type = TransformStateType;
3085 return DDERR_INVALIDPARAMS;
3087 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3088 EnterCriticalSection(&ddraw_cs);
3089 hr = IWineD3DDevice_SetTransform(This->wineD3DDevice,
3091 (WINED3DMATRIX*) Matrix);
3092 LeaveCriticalSection(&ddraw_cs);
3096 static HRESULT WINAPI
3097 Thunk_IDirect3DDeviceImpl_3_SetTransform(IDirect3DDevice3 *iface,
3098 D3DTRANSFORMSTATETYPE TransformStateType,
3099 D3DMATRIX *D3DMatrix)
3101 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3102 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3103 return IDirect3DDevice7_SetTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
3108 static HRESULT WINAPI
3109 Thunk_IDirect3DDeviceImpl_2_SetTransform(IDirect3DDevice2 *iface,
3110 D3DTRANSFORMSTATETYPE TransformStateType,
3111 D3DMATRIX *D3DMatrix)
3113 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3114 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3115 return IDirect3DDevice7_SetTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
3120 /*****************************************************************************
3121 * IDirect3DDevice7::GetTransform
3123 * Returns the matrix assigned to a transform state
3124 * D3DTRANSFORMSTATE_WORLD is translated to D3DTS_WORLDMATRIX(0), see
3128 * TransformStateType: State to read the matrix from
3129 * Matrix: Address to store the matrix at
3133 * DDERR_INVALIDPARAMS if Matrix == NULL
3134 * For details, see IWineD3DDevice::GetTransform
3136 *****************************************************************************/
3137 static HRESULT WINAPI
3138 IDirect3DDeviceImpl_7_GetTransform(IDirect3DDevice7 *iface,
3139 D3DTRANSFORMSTATETYPE TransformStateType,
3142 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3143 D3DTRANSFORMSTATETYPE type = TransformStateType;
3145 TRACE("(%p)->(%08x,%p): Relay\n", This, TransformStateType, Matrix);
3147 switch(TransformStateType)
3149 case D3DTRANSFORMSTATE_WORLD : type = WINED3DTS_WORLDMATRIX(0); break;
3150 case D3DTRANSFORMSTATE_WORLD1: type = WINED3DTS_WORLDMATRIX(1); break;
3151 case D3DTRANSFORMSTATE_WORLD2: type = WINED3DTS_WORLDMATRIX(2); break;
3152 case D3DTRANSFORMSTATE_WORLD3: type = WINED3DTS_WORLDMATRIX(3); break;
3153 default: type = TransformStateType;
3157 return DDERR_INVALIDPARAMS;
3159 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3160 EnterCriticalSection(&ddraw_cs);
3161 hr = IWineD3DDevice_GetTransform(This->wineD3DDevice, type, (WINED3DMATRIX*) Matrix);
3162 LeaveCriticalSection(&ddraw_cs);
3166 static HRESULT WINAPI
3167 Thunk_IDirect3DDeviceImpl_3_GetTransform(IDirect3DDevice3 *iface,
3168 D3DTRANSFORMSTATETYPE TransformStateType,
3169 D3DMATRIX *D3DMatrix)
3171 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3172 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3173 return IDirect3DDevice7_GetTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
3178 static HRESULT WINAPI
3179 Thunk_IDirect3DDeviceImpl_2_GetTransform(IDirect3DDevice2 *iface,
3180 D3DTRANSFORMSTATETYPE TransformStateType,
3181 D3DMATRIX *D3DMatrix)
3183 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3184 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3185 return IDirect3DDevice7_GetTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
3190 /*****************************************************************************
3191 * IDirect3DDevice7::MultiplyTransform
3193 * Multiplies the already-set transform matrix of a transform state
3194 * with another matrix. For the world matrix, see SetTransform
3196 * Version 2, 3 and 7
3199 * TransformStateType: Transform state to multiply
3200 * D3DMatrix Matrix to multiply with.
3204 * DDERR_INVALIDPARAMS if D3DMatrix is NULL
3205 * For details, see IWineD3DDevice::MultiplyTransform
3207 *****************************************************************************/
3208 static HRESULT WINAPI
3209 IDirect3DDeviceImpl_7_MultiplyTransform(IDirect3DDevice7 *iface,
3210 D3DTRANSFORMSTATETYPE TransformStateType,
3211 D3DMATRIX *D3DMatrix)
3213 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3215 D3DTRANSFORMSTATETYPE type;
3216 TRACE("(%p)->(%08x,%p): Relay\n", This, TransformStateType, D3DMatrix);
3218 switch(TransformStateType)
3220 case D3DTRANSFORMSTATE_WORLD : type = WINED3DTS_WORLDMATRIX(0); break;
3221 case D3DTRANSFORMSTATE_WORLD1: type = WINED3DTS_WORLDMATRIX(1); break;
3222 case D3DTRANSFORMSTATE_WORLD2: type = WINED3DTS_WORLDMATRIX(2); break;
3223 case D3DTRANSFORMSTATE_WORLD3: type = WINED3DTS_WORLDMATRIX(3); break;
3224 default: type = TransformStateType;
3227 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3228 EnterCriticalSection(&ddraw_cs);
3229 hr = IWineD3DDevice_MultiplyTransform(This->wineD3DDevice,
3231 (WINED3DMATRIX*) D3DMatrix);
3232 LeaveCriticalSection(&ddraw_cs);
3236 static HRESULT WINAPI
3237 Thunk_IDirect3DDeviceImpl_3_MultiplyTransform(IDirect3DDevice3 *iface,
3238 D3DTRANSFORMSTATETYPE TransformStateType,
3239 D3DMATRIX *D3DMatrix)
3241 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3242 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3243 return IDirect3DDevice7_MultiplyTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
3248 static HRESULT WINAPI
3249 Thunk_IDirect3DDeviceImpl_2_MultiplyTransform(IDirect3DDevice2 *iface,
3250 D3DTRANSFORMSTATETYPE TransformStateType,
3251 D3DMATRIX *D3DMatrix)
3253 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3254 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3255 return IDirect3DDevice7_MultiplyTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
3260 /*****************************************************************************
3261 * IDirect3DDevice7::DrawPrimitive
3263 * Draws primitives based on vertices in an application-provided pointer
3265 * Version 2, 3 and 7. The IDirect3DDevice2 thunk converts the fixed vertex type into
3266 * an FVF format for D3D7
3269 * PrimitiveType: The type of the primitives to draw
3270 * Vertex type: Flexible vertex format vertex description
3271 * Vertices: Pointer to the vertex array
3272 * VertexCount: The number of vertices to draw
3273 * Flags: As usual a few flags
3277 * DDERR_INVALIDPARAMS if Vertices is NULL
3278 * For details, see IWineD3DDevice::DrawPrimitiveUP
3280 *****************************************************************************/
3281 static HRESULT WINAPI
3282 IDirect3DDeviceImpl_7_DrawPrimitive(IDirect3DDevice7 *iface,
3283 D3DPRIMITIVETYPE PrimitiveType,
3289 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3290 UINT PrimitiveCount, stride;
3292 TRACE("(%p)->(%08x,%08x,%p,%08x,%08x): Relay!\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3295 return DDERR_INVALIDPARAMS;
3297 /* Get the vertex count */
3298 switch(PrimitiveType)
3300 case D3DPT_POINTLIST:
3301 PrimitiveCount = VertexCount;
3304 case D3DPT_LINELIST:
3305 PrimitiveCount = VertexCount / 2;
3308 case D3DPT_LINESTRIP:
3309 PrimitiveCount = VertexCount - 1;
3312 case D3DPT_TRIANGLELIST:
3313 PrimitiveCount = VertexCount / 3;
3316 case D3DPT_TRIANGLESTRIP:
3317 PrimitiveCount = VertexCount - 2;
3320 case D3DPT_TRIANGLEFAN:
3321 PrimitiveCount = VertexCount - 2;
3325 return DDERR_INVALIDPARAMS;
3328 /* Get the stride */
3329 stride = get_flexible_vertex_size(VertexType);
3332 EnterCriticalSection(&ddraw_cs);
3333 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
3334 IDirectDrawImpl_FindDecl(This->ddraw, VertexType));
3337 LeaveCriticalSection(&ddraw_cs);
3341 /* This method translates to the user pointer draw of WineD3D */
3342 hr = IWineD3DDevice_DrawPrimitiveUP(This->wineD3DDevice,
3347 LeaveCriticalSection(&ddraw_cs);
3351 static HRESULT WINAPI
3352 Thunk_IDirect3DDeviceImpl_3_DrawPrimitive(IDirect3DDevice3 *iface,
3353 D3DPRIMITIVETYPE PrimitiveType,
3359 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3360 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3361 return IDirect3DDevice7_DrawPrimitive(ICOM_INTERFACE(This, IDirect3DDevice7),
3369 static HRESULT WINAPI
3370 Thunk_IDirect3DDeviceImpl_2_DrawPrimitive(IDirect3DDevice2 *iface,
3371 D3DPRIMITIVETYPE PrimitiveType,
3372 D3DVERTEXTYPE VertexType,
3377 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3379 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3383 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
3384 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
3385 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
3387 ERR("Unexpected vertex type %d\n", VertexType);
3388 return DDERR_INVALIDPARAMS; /* Should never happen */
3391 return IDirect3DDevice7_DrawPrimitive(ICOM_INTERFACE(This, IDirect3DDevice7),
3399 /*****************************************************************************
3400 * IDirect3DDevice7::DrawIndexedPrimitive
3402 * Draws vertices from an application-provided pointer, based on the index
3403 * numbers in a WORD array.
3405 * Version 2, 3 and 7. The version 7 thunk translates the vertex type into
3406 * an FVF format for D3D7
3409 * PrimitiveType: The primitive type to draw
3410 * VertexType: The FVF vertex description
3411 * Vertices: Pointer to the vertex array
3413 * Indices: Pointer to the index array
3414 * IndexCount: Number of indices = Number of vertices to draw
3415 * Flags: As usual, some flags
3419 * DDERR_INVALIDPARAMS if Vertices or Indices is NULL
3420 * For details, see IWineD3DDevice::DrawIndexedPrimitiveUP
3422 *****************************************************************************/
3423 static HRESULT WINAPI
3424 IDirect3DDeviceImpl_7_DrawIndexedPrimitive(IDirect3DDevice7 *iface,
3425 D3DPRIMITIVETYPE PrimitiveType,
3433 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3434 UINT PrimitiveCount = 0;
3436 TRACE("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x): Relay!\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3438 /* Get the primitive number */
3439 switch(PrimitiveType)
3441 case D3DPT_POINTLIST:
3442 PrimitiveCount = IndexCount;
3445 case D3DPT_LINELIST:
3446 PrimitiveCount = IndexCount / 2;
3449 case D3DPT_LINESTRIP:
3450 PrimitiveCount = IndexCount - 1;
3453 case D3DPT_TRIANGLELIST:
3454 PrimitiveCount = IndexCount / 3;
3457 case D3DPT_TRIANGLESTRIP:
3458 PrimitiveCount = IndexCount - 2;
3461 case D3DPT_TRIANGLEFAN:
3462 PrimitiveCount = IndexCount - 2;
3466 return DDERR_INVALIDPARAMS;
3469 /* Set the D3DDevice's FVF */
3470 EnterCriticalSection(&ddraw_cs);
3471 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
3472 IDirectDrawImpl_FindDecl(This->ddraw, VertexType));
3475 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr);
3476 LeaveCriticalSection(&ddraw_cs);
3480 hr = IWineD3DDevice_DrawIndexedPrimitiveUP(This->wineD3DDevice,
3482 0 /* MinVertexIndex */,
3483 VertexCount /* UINT NumVertexIndex */,
3488 get_flexible_vertex_size(VertexType));
3489 LeaveCriticalSection(&ddraw_cs);
3493 static HRESULT WINAPI
3494 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive(IDirect3DDevice3 *iface,
3495 D3DPRIMITIVETYPE PrimitiveType,
3503 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3504 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3505 return IDirect3DDevice7_DrawIndexedPrimitive(ICOM_INTERFACE(This, IDirect3DDevice7),
3515 static HRESULT WINAPI
3516 Thunk_IDirect3DDeviceImpl_2_DrawIndexedPrimitive(IDirect3DDevice2 *iface,
3517 D3DPRIMITIVETYPE PrimitiveType,
3518 D3DVERTEXTYPE VertexType,
3526 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3527 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3531 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
3532 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
3533 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
3535 ERR("Unexpected vertex type %d\n", VertexType);
3536 return DDERR_INVALIDPARAMS; /* Should never happen */
3539 return IDirect3DDevice7_DrawIndexedPrimitive(ICOM_INTERFACE(This, IDirect3DDevice7),
3549 /*****************************************************************************
3550 * IDirect3DDevice7::SetClipStatus
3552 * Sets the clip status. This defines things as clipping conditions and
3553 * the extents of the clipping region.
3555 * Version 2, 3 and 7
3561 * D3D_OK because it's a stub
3562 * (DDERR_INVALIDPARAMS if ClipStatus == NULL)
3564 *****************************************************************************/
3565 static HRESULT WINAPI
3566 IDirect3DDeviceImpl_7_SetClipStatus(IDirect3DDevice7 *iface,
3567 D3DCLIPSTATUS *ClipStatus)
3569 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3570 FIXME("(%p)->(%p): Stub!\n", This, ClipStatus);
3572 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them
3573 * Perhaps this needs a new data type and an additional IWineD3DDevice method
3575 /* return IWineD3DDevice_SetClipStatus(This->wineD3DDevice, ClipStatus);*/
3579 static HRESULT WINAPI
3580 Thunk_IDirect3DDeviceImpl_3_SetClipStatus(IDirect3DDevice3 *iface,
3581 D3DCLIPSTATUS *ClipStatus)
3583 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3584 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3585 return IDirect3DDevice7_SetClipStatus(ICOM_INTERFACE(This, IDirect3DDevice7),
3589 static HRESULT WINAPI
3590 Thunk_IDirect3DDeviceImpl_2_SetClipStatus(IDirect3DDevice2 *iface,
3591 D3DCLIPSTATUS *ClipStatus)
3593 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3594 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3595 return IDirect3DDevice7_SetClipStatus(ICOM_INTERFACE(This, IDirect3DDevice7),
3599 /*****************************************************************************
3600 * IDirect3DDevice7::GetClipStatus
3602 * Returns the clip status
3605 * ClipStatus: Address to write the clip status to
3608 * D3D_OK because it's a stub
3610 *****************************************************************************/
3611 static HRESULT WINAPI
3612 IDirect3DDeviceImpl_7_GetClipStatus(IDirect3DDevice7 *iface,
3613 D3DCLIPSTATUS *ClipStatus)
3615 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3616 FIXME("(%p)->(%p): Stub!\n", This, ClipStatus);
3618 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them */
3619 /* return IWineD3DDevice_GetClipStatus(This->wineD3DDevice, ClipStatus);*/
3623 static HRESULT WINAPI
3624 Thunk_IDirect3DDeviceImpl_3_GetClipStatus(IDirect3DDevice3 *iface,
3625 D3DCLIPSTATUS *ClipStatus)
3627 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3628 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3629 return IDirect3DDevice7_GetClipStatus(ICOM_INTERFACE(This, IDirect3DDevice7),
3633 static HRESULT WINAPI
3634 Thunk_IDirect3DDeviceImpl_2_GetClipStatus(IDirect3DDevice2 *iface,
3635 D3DCLIPSTATUS *ClipStatus)
3637 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3638 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3639 return IDirect3DDevice7_GetClipStatus(ICOM_INTERFACE(This, IDirect3DDevice7),
3643 /*****************************************************************************
3644 * IDirect3DDevice::DrawPrimitiveStrided
3646 * Draws vertices described by a D3DDRAWPRIMITIVESTRIDEDDATA structure.
3651 * PrimitiveType: The primitive type to draw
3652 * VertexType: The FVF description of the vertices to draw (for the stride??)
3653 * D3DDrawPrimStrideData: A D3DDRAWPRIMITIVESTRIDEDDATA structure describing
3654 * the vertex data locations
3655 * VertexCount: The number of vertices to draw
3659 * D3D_OK, because it's a stub
3660 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
3661 * (For details, see IWineD3DDevice::DrawPrimitiveStrided)
3663 *****************************************************************************/
3664 static HRESULT WINAPI
3665 IDirect3DDeviceImpl_7_DrawPrimitiveStrided(IDirect3DDevice7 *iface,
3666 D3DPRIMITIVETYPE PrimitiveType,
3668 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3672 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3673 WineDirect3DVertexStridedData WineD3DStrided;
3675 UINT PrimitiveCount;
3678 TRACE("(%p)->(%08x,%08x,%p,%08x,%08x): stub!\n", This, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
3680 memset(&WineD3DStrided, 0, sizeof(WineD3DStrided));
3681 /* Get the strided data right. the wined3d structure is a bit bigger
3682 * Watch out: The contents of the strided data are determined by the fvf,
3683 * not by the members set in D3DDrawPrimStrideData. So it's valid
3684 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
3685 * not set in the fvf.
3687 if(VertexType & D3DFVF_POSITION_MASK)
3689 WineD3DStrided.u.s.position.lpData = D3DDrawPrimStrideData->position.lpvData;
3690 WineD3DStrided.u.s.position.dwStride = D3DDrawPrimStrideData->position.dwStride;
3691 WineD3DStrided.u.s.position.dwType = WINED3DDECLTYPE_FLOAT3;
3692 if (VertexType & D3DFVF_XYZRHW)
3694 WineD3DStrided.u.s.position.dwType = WINED3DDECLTYPE_FLOAT4;
3695 WineD3DStrided.u.s.position_transformed = TRUE;
3697 WineD3DStrided.u.s.position_transformed = FALSE;
3700 if(VertexType & D3DFVF_NORMAL)
3702 WineD3DStrided.u.s.normal.lpData = D3DDrawPrimStrideData->normal.lpvData;
3703 WineD3DStrided.u.s.normal.dwStride = D3DDrawPrimStrideData->normal.dwStride;
3704 WineD3DStrided.u.s.normal.dwType = WINED3DDECLTYPE_FLOAT3;
3707 if(VertexType & D3DFVF_DIFFUSE)
3709 WineD3DStrided.u.s.diffuse.lpData = D3DDrawPrimStrideData->diffuse.lpvData;
3710 WineD3DStrided.u.s.diffuse.dwStride = D3DDrawPrimStrideData->diffuse.dwStride;
3711 WineD3DStrided.u.s.diffuse.dwType = WINED3DDECLTYPE_D3DCOLOR;
3714 if(VertexType & D3DFVF_SPECULAR)
3716 WineD3DStrided.u.s.specular.lpData = D3DDrawPrimStrideData->specular.lpvData;
3717 WineD3DStrided.u.s.specular.dwStride = D3DDrawPrimStrideData->specular.dwStride;
3718 WineD3DStrided.u.s.specular.dwType = WINED3DDECLTYPE_D3DCOLOR;
3721 for( i = 0; i < GET_TEXCOUNT_FROM_FVF(VertexType); i++)
3723 WineD3DStrided.u.s.texCoords[i].lpData = D3DDrawPrimStrideData->textureCoords[i].lpvData;
3724 WineD3DStrided.u.s.texCoords[i].dwStride = D3DDrawPrimStrideData->textureCoords[i].dwStride;
3725 switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i))
3727 case 1: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT1; break;
3728 case 2: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT2; break;
3729 case 3: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT3; break;
3730 case 4: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT4; break;
3731 default: ERR("Unexpected texture coordinate size %d\n",
3732 GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i));
3736 /* Get the primitive count */
3737 switch(PrimitiveType)
3739 case D3DPT_POINTLIST:
3740 PrimitiveCount = VertexCount;
3743 case D3DPT_LINELIST:
3744 PrimitiveCount = VertexCount / 2;
3747 case D3DPT_LINESTRIP:
3748 PrimitiveCount = VertexCount - 1;
3751 case D3DPT_TRIANGLELIST:
3752 PrimitiveCount = VertexCount / 3;
3755 case D3DPT_TRIANGLESTRIP:
3756 PrimitiveCount = VertexCount - 2;
3759 case D3DPT_TRIANGLEFAN:
3760 PrimitiveCount = VertexCount - 2;
3763 default: return DDERR_INVALIDPARAMS;
3766 /* WineD3D doesn't need the FVF here */
3767 EnterCriticalSection(&ddraw_cs);
3768 hr = IWineD3DDevice_DrawPrimitiveStrided(This->wineD3DDevice,
3772 LeaveCriticalSection(&ddraw_cs);
3776 static HRESULT WINAPI
3777 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided(IDirect3DDevice3 *iface,
3778 D3DPRIMITIVETYPE PrimitiveType,
3780 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3784 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3785 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
3786 return IDirect3DDevice7_DrawPrimitiveStrided(ICOM_INTERFACE(This, IDirect3DDevice7),
3789 D3DDrawPrimStrideData,
3794 /*****************************************************************************
3795 * IDirect3DDevice7::DrawIndexedPrimitiveStrided
3797 * Draws primitives specified by strided data locations based on indices
3805 * D3D_OK, because it's a stub
3806 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
3807 * (DDERR_INVALIDPARAMS if Indices is NULL)
3808 * (For more details, see IWineD3DDevice::DrawIndexedPrimitiveStrided)
3810 *****************************************************************************/
3811 static HRESULT WINAPI
3812 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(IDirect3DDevice7 *iface,
3813 D3DPRIMITIVETYPE PrimitiveType,
3815 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3821 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3822 WineDirect3DVertexStridedData WineD3DStrided;
3824 UINT PrimitiveCount;
3827 TRACE("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x)\n", This, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
3829 memset(&WineD3DStrided, 0, sizeof(WineD3DStrided));
3830 /* Get the strided data right. the wined3d structure is a bit bigger
3831 * Watch out: The contents of the strided data are determined by the fvf,
3832 * not by the members set in D3DDrawPrimStrideData. So it's valid
3833 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
3834 * not set in the fvf.
3836 if(VertexType & D3DFVF_POSITION_MASK)
3838 WineD3DStrided.u.s.position.lpData = D3DDrawPrimStrideData->position.lpvData;
3839 WineD3DStrided.u.s.position.dwStride = D3DDrawPrimStrideData->position.dwStride;
3840 WineD3DStrided.u.s.position.dwType = WINED3DDECLTYPE_FLOAT3;
3841 if (VertexType & D3DFVF_XYZRHW)
3843 WineD3DStrided.u.s.position.dwType = WINED3DDECLTYPE_FLOAT4;
3844 WineD3DStrided.u.s.position_transformed = TRUE;
3846 WineD3DStrided.u.s.position_transformed = FALSE;
3849 if(VertexType & D3DFVF_NORMAL)
3851 WineD3DStrided.u.s.normal.lpData = D3DDrawPrimStrideData->normal.lpvData;
3852 WineD3DStrided.u.s.normal.dwStride = D3DDrawPrimStrideData->normal.dwStride;
3853 WineD3DStrided.u.s.normal.dwType = WINED3DDECLTYPE_FLOAT3;
3856 if(VertexType & D3DFVF_DIFFUSE)
3858 WineD3DStrided.u.s.diffuse.lpData = D3DDrawPrimStrideData->diffuse.lpvData;
3859 WineD3DStrided.u.s.diffuse.dwStride = D3DDrawPrimStrideData->diffuse.dwStride;
3860 WineD3DStrided.u.s.diffuse.dwType = WINED3DDECLTYPE_D3DCOLOR;
3863 if(VertexType & D3DFVF_SPECULAR)
3865 WineD3DStrided.u.s.specular.lpData = D3DDrawPrimStrideData->specular.lpvData;
3866 WineD3DStrided.u.s.specular.dwStride = D3DDrawPrimStrideData->specular.dwStride;
3867 WineD3DStrided.u.s.specular.dwType = WINED3DDECLTYPE_D3DCOLOR;
3870 for( i = 0; i < GET_TEXCOUNT_FROM_FVF(VertexType); i++)
3872 WineD3DStrided.u.s.texCoords[i].lpData = D3DDrawPrimStrideData->textureCoords[i].lpvData;
3873 WineD3DStrided.u.s.texCoords[i].dwStride = D3DDrawPrimStrideData->textureCoords[i].dwStride;
3874 switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i))
3876 case 1: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT1; break;
3877 case 2: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT2; break;
3878 case 3: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT3; break;
3879 case 4: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT4; break;
3880 default: ERR("Unexpected texture coordinate size %d\n",
3881 GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i));
3885 /* Get the primitive count */
3886 switch(PrimitiveType)
3888 case D3DPT_POINTLIST:
3889 PrimitiveCount = IndexCount;
3892 case D3DPT_LINELIST:
3893 PrimitiveCount = IndexCount / 2;
3896 case D3DPT_LINESTRIP:
3897 PrimitiveCount = IndexCount - 1;
3900 case D3DPT_TRIANGLELIST:
3901 PrimitiveCount = IndexCount / 3;
3904 case D3DPT_TRIANGLESTRIP:
3905 PrimitiveCount = IndexCount - 2;
3908 case D3DPT_TRIANGLEFAN:
3909 PrimitiveCount = IndexCount - 2;
3912 default: return DDERR_INVALIDPARAMS;
3915 /* WineD3D doesn't need the FVF here */
3916 EnterCriticalSection(&ddraw_cs);
3917 hr = IWineD3DDevice_DrawIndexedPrimitiveStrided(This->wineD3DDevice,
3923 WINED3DFMT_INDEX16);
3924 LeaveCriticalSection(&ddraw_cs);
3928 static HRESULT WINAPI
3929 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided(IDirect3DDevice3 *iface,
3930 D3DPRIMITIVETYPE PrimitiveType,
3932 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3938 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3939 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
3940 return IDirect3DDevice7_DrawIndexedPrimitiveStrided(ICOM_INTERFACE(This, IDirect3DDevice7),
3943 D3DDrawPrimStrideData,
3950 /*****************************************************************************
3951 * IDirect3DDevice7::DrawPrimitiveVB
3953 * Draws primitives from a vertex buffer to the screen.
3958 * PrimitiveType: Type of primitive to be rendered.
3959 * D3DVertexBuf: Source Vertex Buffer
3960 * StartVertex: Index of the first vertex from the buffer to be rendered
3961 * NumVertices: Number of vertices to be rendered
3962 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
3966 * DDERR_INVALIDPARAMS if D3DVertexBuf is NULL
3968 *****************************************************************************/
3969 static HRESULT WINAPI
3970 IDirect3DDeviceImpl_7_DrawPrimitiveVB(IDirect3DDevice7 *iface,
3971 D3DPRIMITIVETYPE PrimitiveType,
3972 IDirect3DVertexBuffer7 *D3DVertexBuf,
3977 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3978 IDirect3DVertexBufferImpl *vb = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, D3DVertexBuf);
3979 UINT PrimitiveCount;
3982 WINED3DVERTEXBUFFER_DESC Desc;
3984 TRACE("(%p)->(%08x,%p,%08x,%08x,%08x)\n", This, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags);
3989 ERR("(%p) No Vertex buffer specified\n", This);
3990 return DDERR_INVALIDPARAMS;
3993 /* Get the primitive count */
3994 switch(PrimitiveType)
3996 case D3DPT_POINTLIST:
3997 PrimitiveCount = NumVertices;
4000 case D3DPT_LINELIST:
4001 PrimitiveCount = NumVertices / 2;
4004 case D3DPT_LINESTRIP:
4005 PrimitiveCount = NumVertices - 1;
4008 case D3DPT_TRIANGLELIST:
4009 PrimitiveCount = NumVertices / 3;
4012 case D3DPT_TRIANGLESTRIP:
4013 PrimitiveCount = NumVertices - 2;
4016 case D3DPT_TRIANGLEFAN:
4017 PrimitiveCount = NumVertices - 2;
4021 return DDERR_INVALIDPARAMS;
4024 /* Get the FVF of the vertex buffer, and its stride */
4025 EnterCriticalSection(&ddraw_cs);
4026 hr = IWineD3DVertexBuffer_GetDesc(vb->wineD3DVertexBuffer,
4030 ERR("(%p) IWineD3DVertexBuffer::GetDesc failed with hr = %08x\n", This, hr);
4031 LeaveCriticalSection(&ddraw_cs);
4034 stride = get_flexible_vertex_size(Desc.FVF);
4036 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
4037 vb->wineD3DVertexDeclaration);
4040 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr);
4041 LeaveCriticalSection(&ddraw_cs);
4045 /* Set the vertex stream source */
4046 hr = IWineD3DDevice_SetStreamSource(This->wineD3DDevice,
4047 0 /* StreamNumber */,
4048 vb->wineD3DVertexBuffer,
4049 0 /* StartVertex - we pass this to DrawPrimitive */,
4053 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This, hr);
4054 LeaveCriticalSection(&ddraw_cs);
4058 /* Now draw the primitives */
4059 hr = IWineD3DDevice_DrawPrimitive(This->wineD3DDevice,
4063 LeaveCriticalSection(&ddraw_cs);
4067 static HRESULT WINAPI
4068 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB(IDirect3DDevice3 *iface,
4069 D3DPRIMITIVETYPE PrimitiveType,
4070 IDirect3DVertexBuffer *D3DVertexBuf,
4075 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4076 IDirect3DVertexBufferImpl *vb = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, D3DVertexBuf);
4077 TRACE_(ddraw_thunk)("(%p)->(%08x,%p,%08x,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, vb, StartVertex, NumVertices, Flags);
4078 return IDirect3DDevice7_DrawPrimitiveVB(ICOM_INTERFACE(This, IDirect3DDevice7),
4080 ICOM_INTERFACE(vb, IDirect3DVertexBuffer7),
4087 /*****************************************************************************
4088 * IDirect3DDevice7::DrawIndexedPrimitiveVB
4090 * Draws primitives from a vertex buffer to the screen
4093 * PrimitiveType: Type of primitive to be rendered.
4094 * D3DVertexBuf: Source Vertex Buffer
4095 * StartVertex: Index of the first vertex from the buffer to be rendered
4096 * NumVertices: Number of vertices to be rendered
4097 * Indices: Array of DWORDs used to index into the Vertices
4098 * IndexCount: Number of indices in Indices
4099 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4103 *****************************************************************************/
4104 static HRESULT WINAPI
4105 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(IDirect3DDevice7 *iface,
4106 D3DPRIMITIVETYPE PrimitiveType,
4107 IDirect3DVertexBuffer7 *D3DVertexBuf,
4114 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4115 IDirect3DVertexBufferImpl *vb = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, D3DVertexBuf);
4117 UINT PrimitiveCount;
4118 WORD *LockedIndices;
4120 WINED3DVERTEXBUFFER_DESC Desc;
4122 TRACE("(%p)->(%08x,%p,%d,%d,%p,%d,%08x)\n", This, PrimitiveType, vb, StartVertex, NumVertices, Indices, IndexCount, Flags);
4125 * 1) Calculate some things: Vertex count -> Primitive count, stride, ...
4126 * 2) Upload the Indices to the index buffer
4127 * 3) Set the index source
4128 * 4) Set the Vertex Buffer as the Stream source
4129 * 5) Call IWineD3DDevice::DrawIndexedPrimitive
4132 /* Get the primitive count */
4133 switch(PrimitiveType)
4135 case D3DPT_POINTLIST:
4136 PrimitiveCount = IndexCount;
4139 case D3DPT_LINELIST:
4140 PrimitiveCount = IndexCount / 2;
4143 case D3DPT_LINESTRIP:
4144 PrimitiveCount = IndexCount - 1;
4147 case D3DPT_TRIANGLELIST:
4148 PrimitiveCount = IndexCount / 3;
4151 case D3DPT_TRIANGLESTRIP:
4152 PrimitiveCount = IndexCount - 2;
4155 case D3DPT_TRIANGLEFAN:
4156 PrimitiveCount = IndexCount - 2;
4159 default: return DDERR_INVALIDPARAMS;
4162 EnterCriticalSection(&ddraw_cs);
4163 /* Get the FVF of the vertex buffer, and its stride */
4164 hr = IWineD3DVertexBuffer_GetDesc(vb->wineD3DVertexBuffer,
4168 ERR("(%p) IWineD3DVertexBuffer::GetDesc failed with hr = %08x\n", This, hr);
4169 LeaveCriticalSection(&ddraw_cs);
4172 stride = get_flexible_vertex_size(Desc.FVF);
4173 TRACE("Vertex buffer FVF = %08x, stride=%d\n", Desc.FVF, stride);
4175 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
4176 vb->wineD3DVertexDeclaration);
4179 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr);
4180 LeaveCriticalSection(&ddraw_cs);
4184 /* copy the index stream into the index buffer.
4185 * A new IWineD3DDevice method could be created
4186 * which takes an user pointer containing the indices
4187 * or a SetData-Method for the index buffer, which
4188 * overrides the index buffer data with our pointer.
4190 hr = IWineD3DIndexBuffer_Lock(This->indexbuffer,
4191 0 /* OffSetToLock */,
4192 IndexCount * sizeof(WORD),
4193 (BYTE **) &LockedIndices,
4195 assert(IndexCount < 0x100000);
4198 ERR("(%p) IWineD3DIndexBuffer::Lock failed with hr = %08x\n", This, hr);
4199 LeaveCriticalSection(&ddraw_cs);
4202 memcpy(LockedIndices, Indices, IndexCount * sizeof(WORD));
4203 hr = IWineD3DIndexBuffer_Unlock(This->indexbuffer);
4206 ERR("(%p) IWineD3DIndexBuffer::Unlock failed with hr = %08x\n", This, hr);
4207 LeaveCriticalSection(&ddraw_cs);
4211 /* Set the index stream */
4212 IWineD3DDevice_SetBaseVertexIndex(This->wineD3DDevice, StartVertex);
4213 hr = IWineD3DDevice_SetIndices(This->wineD3DDevice, This->indexbuffer);
4215 /* Set the vertex stream source */
4216 hr = IWineD3DDevice_SetStreamSource(This->wineD3DDevice,
4217 0 /* StreamNumber */,
4218 vb->wineD3DVertexBuffer,
4219 0 /* offset, we pass this to DrawIndexedPrimitive */,
4223 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This, hr);
4224 LeaveCriticalSection(&ddraw_cs);
4229 hr = IWineD3DDevice_DrawIndexedPrimitive(This->wineD3DDevice,
4236 LeaveCriticalSection(&ddraw_cs);
4240 static HRESULT WINAPI
4241 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB(IDirect3DDevice3 *iface,
4242 D3DPRIMITIVETYPE PrimitiveType,
4243 IDirect3DVertexBuffer *D3DVertexBuf,
4248 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4249 IDirect3DVertexBufferImpl *VB = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, D3DVertexBuf);
4250 TRACE_(ddraw_thunk)("(%p)->(%08x,%p,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VB, Indices, IndexCount, Flags);
4252 return IDirect3DDevice7_DrawIndexedPrimitiveVB(ICOM_INTERFACE(This, IDirect3DDevice7),
4254 ICOM_INTERFACE(VB, IDirect3DVertexBuffer7),
4262 /*****************************************************************************
4263 * IDirect3DDevice7::ComputeSphereVisibility
4265 * Calculates the visibility of spheres in the current viewport. The spheres
4266 * are passed in the Centers and Radii arrays, the results are passed back
4267 * in the ReturnValues array. Return values are either completely visible,
4268 * partially visible or completely invisible.
4269 * The return value consist of a combination of D3DCLIP_* flags, or it's
4270 * 0 if the sphere is completely visible(according to the SDK, not checked)
4272 * Sounds like an overdose of math ;)
4277 * Centers: Array containing the sphere centers
4278 * Radii: Array containing the sphere radii
4279 * NumSpheres: The number of centers and radii in the arrays
4281 * ReturnValues: Array to write the results to
4284 * D3D_OK because it's a stub
4285 * (DDERR_INVALIDPARAMS if Centers, Radii or ReturnValues are NULL)
4286 * (D3DERR_INVALIDMATRIX if the combined world, view and proj matrix
4289 *****************************************************************************/
4290 static HRESULT WINAPI
4291 IDirect3DDeviceImpl_7_ComputeSphereVisibility(IDirect3DDevice7 *iface,
4296 DWORD *ReturnValues)
4298 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4299 FIXME("(%p)->(%p,%p,%08x,%08x,%p): stub!\n", This, Centers, Radii, NumSpheres, Flags, ReturnValues);
4301 /* the DirectX 7 sdk says that the visibility is computed by
4302 * back-transforming the viewing frustum to model space
4303 * using the inverse of the combined world, view and projection
4304 * matrix. If the matrix can't be reversed, D3DERR_INVALIDMATRIX
4307 * Basic implementation idea:
4308 * 1) Check if the center is in the viewing frustum
4309 * 2) Cut the sphere with the planes of the viewing
4312 * ->Center inside the frustum, no intersections:
4314 * ->Center outside the frustum, no intersections:
4316 * ->Some intersections: Partially visible
4318 * Implement this call in WineD3D. Either implement the
4319 * matrix and vector stuff in WineD3D, or use some external
4326 static HRESULT WINAPI
4327 Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility(IDirect3DDevice3 *iface,
4332 DWORD *ReturnValues)
4334 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4335 TRACE_(ddraw_thunk)("(%p)->(%p,%p,%08x,%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, Centers, Radii, NumSpheres, Flags, ReturnValues);
4336 return IDirect3DDevice7_ComputeSphereVisibility(ICOM_INTERFACE(This, IDirect3DDevice7),
4344 /*****************************************************************************
4345 * IDirect3DDevice7::GetTexture
4347 * Returns the texture interface handle assigned to a texture stage.
4348 * The returned texture is AddRefed. This is taken from old ddraw,
4349 * not checked in Windows.
4354 * Stage: Texture stage to read the texture from
4355 * Texture: Address to store the interface pointer at
4359 * DDERR_INVALIDPARAMS if Texture is NULL
4360 * For details, see IWineD3DDevice::GetTexture
4362 *****************************************************************************/
4363 static HRESULT WINAPI
4364 IDirect3DDeviceImpl_7_GetTexture(IDirect3DDevice7 *iface,
4366 IDirectDrawSurface7 **Texture)
4368 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4369 IWineD3DBaseTexture *Surf;
4371 TRACE("(%p)->(%d,%p): Relay\n", This, Stage, Texture);
4375 TRACE("Texture == NULL, failing with DDERR_INVALIDPARAMS\n");
4376 return DDERR_INVALIDPARAMS;
4379 EnterCriticalSection(&ddraw_cs);
4380 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice, Stage, &Surf);
4381 if( (hr != D3D_OK) || (!Surf) )
4384 LeaveCriticalSection(&ddraw_cs);
4388 /* GetParent AddRef()s, which is perfectly OK.
4389 * We have passed the IDirectDrawSurface7 interface to WineD3D, so that's OK too.
4391 hr = IWineD3DBaseTexture_GetParent(Surf,
4392 (IUnknown **) Texture);
4393 LeaveCriticalSection(&ddraw_cs);
4397 static HRESULT WINAPI
4398 Thunk_IDirect3DDeviceImpl_3_GetTexture(IDirect3DDevice3 *iface,
4400 IDirect3DTexture2 **Texture2)
4402 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4404 IDirectDrawSurface7 *ret_val;
4406 TRACE_(ddraw_thunk)("(%p)->(%d,%p) thunking to IDirect3DDevice7 interface.\n", This, Stage, Texture2);
4407 ret = IDirect3DDevice7_GetTexture(ICOM_INTERFACE(This, IDirect3DDevice7),
4411 *Texture2 = COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7, IDirect3DTexture2, ret_val);
4413 TRACE_(ddraw_thunk)(" returning interface %p.\n", *Texture2);
4418 /*****************************************************************************
4419 * IDirect3DDevice7::SetTexture
4421 * Assigns a texture to a texture stage. Is the texture AddRef-ed?
4426 * Stage: The stage to assign the texture to
4427 * Texture: Interface pointer to the texture surface
4431 * For details, see IWineD3DDevice::SetTexture
4433 *****************************************************************************/
4434 static HRESULT WINAPI
4435 IDirect3DDeviceImpl_7_SetTexture(IDirect3DDevice7 *iface,
4437 IDirectDrawSurface7 *Texture)
4439 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4440 IDirectDrawSurfaceImpl *surf = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, Texture);
4442 TRACE("(%p)->(%08x,%p): Relay!\n", This, Stage, surf);
4444 /* Texture may be NULL here */
4445 EnterCriticalSection(&ddraw_cs);
4446 hr = IWineD3DDevice_SetTexture(This->wineD3DDevice,
4448 surf ? surf->wineD3DTexture : NULL);
4449 LeaveCriticalSection(&ddraw_cs);
4453 static HRESULT WINAPI
4454 Thunk_IDirect3DDeviceImpl_3_SetTexture(IDirect3DDevice3 *iface,
4456 IDirect3DTexture2 *Texture2)
4458 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4459 IDirectDrawSurfaceImpl *tex = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture2, Texture2);
4460 TRACE_(ddraw_thunk)("(%p)->(%d,%p) thunking to IDirect3DDevice7 interface.\n", This, Stage, tex);
4461 return IDirect3DDevice7_SetTexture(ICOM_INTERFACE(This, IDirect3DDevice7),
4463 ICOM_INTERFACE(tex, IDirectDrawSurface7));
4466 /*****************************************************************************
4467 * IDirect3DDevice7::GetTextureStageState
4469 * Retrieves a state from a texture stage.
4474 * Stage: The stage to retrieve the state from
4475 * TexStageStateType: The state type to retrieve
4476 * State: Address to store the state's value at
4480 * DDERR_INVALIDPARAMS if State is NULL
4481 * For details, see IWineD3DDevice::GetTextureStageState
4483 *****************************************************************************/
4484 static HRESULT WINAPI
4485 IDirect3DDeviceImpl_7_GetTextureStageState(IDirect3DDevice7 *iface,
4487 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4490 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4492 TRACE("(%p)->(%08x,%08x,%p): Relay!\n", This, Stage, TexStageStateType, State);
4495 return DDERR_INVALIDPARAMS;
4497 EnterCriticalSection(&ddraw_cs);
4498 switch(TexStageStateType)
4500 /* Mipfilter is a sampler state with different values */
4501 case D3DTSS_MIPFILTER:
4503 WINED3DTEXTUREFILTERTYPE value;
4505 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
4507 WINED3DSAMP_MIPFILTER,
4511 case WINED3DTEXF_NONE: *State = D3DTFP_NONE; break;
4512 case WINED3DTEXF_POINT: *State = D3DTFP_POINT; break;
4513 case WINED3DTEXF_LINEAR: *State = D3DTFP_LINEAR; break;
4515 ERR("Unexpected mipfilter value %d\n", value);
4516 *State = D3DTFP_NONE;
4521 /* Minfilter is a sampler state too, equal values */
4522 case D3DTSS_MINFILTER:
4523 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
4525 WINED3DSAMP_MINFILTER,
4529 /* Magfilter has slightly different values */
4530 case D3DTSS_MAGFILTER:
4532 WINED3DTEXTUREFILTERTYPE wined3dfilter;
4533 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
4535 WINED3DSAMP_MAGFILTER,
4537 switch(wined3dfilter)
4539 case WINED3DTEXF_POINT: *State = D3DTFG_POINT; break;
4540 case WINED3DTEXF_LINEAR: *State = D3DTFG_LINEAR; break;
4541 case WINED3DTEXF_ANISOTROPIC: *State = D3DTFG_ANISOTROPIC; break;
4542 case WINED3DTEXF_FLATCUBIC: *State = D3DTFG_FLATCUBIC; break;
4543 case WINED3DTEXF_GAUSSIANCUBIC: *State = D3DTFG_GAUSSIANCUBIC; break;
4545 ERR("Unexpected wined3d mag filter value %d\n", wined3dfilter);
4546 *State = D3DTFG_POINT;
4551 case D3DTSS_ADDRESS:
4552 case D3DTSS_ADDRESSU:
4553 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
4555 WINED3DSAMP_ADDRESSU,
4558 case D3DTSS_ADDRESSV:
4559 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
4561 WINED3DSAMP_ADDRESSV,
4565 hr = IWineD3DDevice_GetTextureStageState(This->wineD3DDevice,
4571 LeaveCriticalSection(&ddraw_cs);
4575 static HRESULT WINAPI
4576 Thunk_IDirect3DDeviceImpl_3_GetTextureStageState(IDirect3DDevice3 *iface,
4578 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4581 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4582 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, Stage, TexStageStateType, State);
4583 return IDirect3DDevice7_GetTextureStageState(ICOM_INTERFACE(This, IDirect3DDevice7),
4589 /*****************************************************************************
4590 * IDirect3DDevice7::SetTextureStageState
4592 * Sets a texture stage state. Some stage types need to be handled specially,
4593 * because they do not exist in WineD3D and were moved to another place
4598 * Stage: The stage to modify
4599 * TexStageStateType: The state to change
4600 * State: The new value for the state
4604 * For details, see IWineD3DDevice::SetTextureStageState
4606 *****************************************************************************/
4607 static HRESULT WINAPI
4608 IDirect3DDeviceImpl_7_SetTextureStageState(IDirect3DDevice7 *iface,
4610 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4613 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4615 TRACE("(%p)->(%08x,%08x,%08x): Relay!\n", This, Stage, TexStageStateType, State);
4617 EnterCriticalSection(&ddraw_cs);
4618 switch(TexStageStateType)
4620 /* Mipfilter is a sampler state with different values */
4621 case D3DTSS_MIPFILTER:
4623 WINED3DTEXTUREFILTERTYPE value;
4626 case D3DTFP_NONE: value = WINED3DTEXF_NONE; break;
4627 case D3DTFP_POINT: value = WINED3DTEXF_POINT; break;
4628 case 0: /* Unchecked */
4629 case D3DTFP_LINEAR: value = WINED3DTEXF_LINEAR; break;
4631 ERR("Unexpected mipfilter value %d\n", State);
4632 value = WINED3DTEXF_NONE;
4634 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
4636 WINED3DSAMP_MIPFILTER,
4641 /* Minfilter is a sampler state too, equal values */
4642 case D3DTSS_MINFILTER:
4643 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
4645 WINED3DSAMP_MINFILTER,
4649 /* Magfilter has slightly different values */
4650 case D3DTSS_MAGFILTER:
4652 WINED3DTEXTUREFILTERTYPE wined3dfilter;
4653 switch((D3DTEXTUREMAGFILTER) State)
4655 case D3DTFG_POINT: wined3dfilter = WINED3DTEXF_POINT; break;
4656 case D3DTFG_LINEAR: wined3dfilter = WINED3DTEXF_LINEAR; break;
4657 case D3DTFG_FLATCUBIC: wined3dfilter = WINED3DTEXF_FLATCUBIC; break;
4658 case D3DTFG_GAUSSIANCUBIC: wined3dfilter = WINED3DTEXF_GAUSSIANCUBIC; break;
4659 case D3DTFG_ANISOTROPIC: wined3dfilter = WINED3DTEXF_ANISOTROPIC; break;
4661 ERR("Unexpected d3d7 mag filter type %d\n", State);
4662 wined3dfilter = WINED3DTEXF_POINT;
4664 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
4666 WINED3DSAMP_MAGFILTER,
4671 case D3DTSS_ADDRESS:
4672 IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
4674 WINED3DSAMP_ADDRESSV,
4677 case D3DTSS_ADDRESSU:
4678 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
4680 WINED3DSAMP_ADDRESSU,
4684 case D3DTSS_ADDRESSV:
4685 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
4687 WINED3DSAMP_ADDRESSV,
4692 hr = IWineD3DDevice_SetTextureStageState(This->wineD3DDevice,
4698 LeaveCriticalSection(&ddraw_cs);
4702 static HRESULT WINAPI
4703 Thunk_IDirect3DDeviceImpl_3_SetTextureStageState(IDirect3DDevice3 *iface,
4705 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4708 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4709 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, Stage, TexStageStateType, State);
4710 return IDirect3DDevice7_SetTextureStageState(ICOM_INTERFACE(This, IDirect3DDevice7),
4716 /*****************************************************************************
4717 * IDirect3DDevice7::ValidateDevice
4719 * SDK: "Reports the device's ability to render the currently set
4720 * texture-blending operations in a single pass". Whatever that means
4726 * NumPasses: Address to write the number of necessary passes for the
4727 * desired effect to.
4731 * See IWineD3DDevice::ValidateDevice for more details
4733 *****************************************************************************/
4734 static HRESULT WINAPI
4735 IDirect3DDeviceImpl_7_ValidateDevice(IDirect3DDevice7 *iface,
4738 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4740 TRACE("(%p)->(%p): Relay\n", This, NumPasses);
4742 EnterCriticalSection(&ddraw_cs);
4743 hr = IWineD3DDevice_ValidateDevice(This->wineD3DDevice, NumPasses);
4744 LeaveCriticalSection(&ddraw_cs);
4748 static HRESULT WINAPI
4749 Thunk_IDirect3DDeviceImpl_3_ValidateDevice(IDirect3DDevice3 *iface,
4752 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4753 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Passes);
4754 return IDirect3DDevice7_ValidateDevice(ICOM_INTERFACE(This, IDirect3DDevice7),
4758 /*****************************************************************************
4759 * IDirect3DDevice7::Clear
4761 * Fills the render target, the z buffer and the stencil buffer with a
4762 * clear color / value
4767 * Count: Number of rectangles in Rects must be 0 if Rects is NULL
4768 * Rects: Rectangles to clear. If NULL, the whole surface is cleared
4769 * Flags: Some flags, as usual
4770 * Color: Clear color for the render target
4771 * Z: Clear value for the Z buffer
4772 * Stencil: Clear value to store in each stencil buffer entry
4776 * For details, see IWineD3DDevice::Clear
4778 *****************************************************************************/
4779 static HRESULT WINAPI
4780 IDirect3DDeviceImpl_7_Clear(IDirect3DDevice7 *iface,
4788 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4790 TRACE("(%p)->(%08x,%p,%08x,%08x,%f,%08x): Relay\n", This, Count, Rects, Flags, Color, Z, Stencil);
4792 /* Note; D3DRECT is compatible with WINED3DRECT */
4793 EnterCriticalSection(&ddraw_cs);
4794 hr = IWineD3DDevice_Clear(This->wineD3DDevice, Count, (WINED3DRECT*) Rects, Flags, Color, Z, Stencil);
4795 LeaveCriticalSection(&ddraw_cs);
4799 /*****************************************************************************
4800 * IDirect3DDevice7::SetViewport
4802 * Sets the current viewport.
4804 * Version 7 only, but IDirect3DViewport uses this call for older
4808 * Data: The new viewport to set
4812 * DDERR_INVALIDPARAMS if Data is NULL
4813 * For more details, see IWineDDDevice::SetViewport
4815 *****************************************************************************/
4816 static HRESULT WINAPI
4817 IDirect3DDeviceImpl_7_SetViewport(IDirect3DDevice7 *iface,
4820 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4822 TRACE("(%p)->(%p) Relay!\n", This, Data);
4825 return DDERR_INVALIDPARAMS;
4827 /* Note: D3DVIEWPORT7 is compatible with WINED3DVIEWPORT */
4828 EnterCriticalSection(&ddraw_cs);
4829 hr = IWineD3DDevice_SetViewport(This->wineD3DDevice,
4830 (WINED3DVIEWPORT*) Data);
4831 LeaveCriticalSection(&ddraw_cs);
4835 /*****************************************************************************
4836 * IDirect3DDevice::GetViewport
4838 * Returns the current viewport
4843 * Data: D3D7Viewport structure to write the viewport information to
4847 * DDERR_INVALIDPARAMS if Data is NULL
4848 * For more details, see IWineD3DDevice::GetViewport
4850 *****************************************************************************/
4851 static HRESULT WINAPI
4852 IDirect3DDeviceImpl_7_GetViewport(IDirect3DDevice7 *iface,
4855 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4857 TRACE("(%p)->(%p) Relay!\n", This, Data);
4860 return DDERR_INVALIDPARAMS;
4862 /* Note: D3DVIEWPORT7 is compatible with WINED3DVIEWPORT */
4863 EnterCriticalSection(&ddraw_cs);
4864 hr = IWineD3DDevice_GetViewport(This->wineD3DDevice,
4865 (WINED3DVIEWPORT*) Data);
4867 LeaveCriticalSection(&ddraw_cs);
4868 return hr_ddraw_from_wined3d(hr);
4871 /*****************************************************************************
4872 * IDirect3DDevice7::SetMaterial
4879 * Mat: The material to set
4883 * DDERR_INVALIDPARAMS if Mat is NULL.
4884 * For more details, see IWineD3DDevice::SetMaterial
4886 *****************************************************************************/
4887 static HRESULT WINAPI
4888 IDirect3DDeviceImpl_7_SetMaterial(IDirect3DDevice7 *iface,
4891 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4893 TRACE("(%p)->(%p): Relay!\n", This, Mat);
4895 /* Note: D3DMATERIAL7 is compatible with WINED3DMATERIAL */
4896 EnterCriticalSection(&ddraw_cs);
4897 hr = IWineD3DDevice_SetMaterial(This->wineD3DDevice,
4898 (WINED3DMATERIAL*) Mat);
4899 LeaveCriticalSection(&ddraw_cs);
4900 return hr_ddraw_from_wined3d(hr);
4903 /*****************************************************************************
4904 * IDirect3DDevice7::GetMaterial
4906 * Returns the current material
4911 * Mat: D3DMATERIAL7 structure to write the material parameters to
4915 * DDERR_INVALIDPARAMS if Mat is NULL
4916 * For more details, see IWineD3DDevice::GetMaterial
4918 *****************************************************************************/
4919 static HRESULT WINAPI
4920 IDirect3DDeviceImpl_7_GetMaterial(IDirect3DDevice7 *iface,
4923 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4925 TRACE("(%p)->(%p): Relay!\n", This, Mat);
4927 EnterCriticalSection(&ddraw_cs);
4928 /* Note: D3DMATERIAL7 is compatible with WINED3DMATERIAL */
4929 hr = IWineD3DDevice_GetMaterial(This->wineD3DDevice,
4930 (WINED3DMATERIAL*) Mat);
4931 LeaveCriticalSection(&ddraw_cs);
4932 return hr_ddraw_from_wined3d(hr);
4935 /*****************************************************************************
4936 * IDirect3DDevice7::SetLight
4938 * Assigns a light to a light index, but doesn't activate it yet.
4940 * Version 7, IDirect3DLight uses this method for older versions
4943 * LightIndex: The index of the new light
4944 * Light: A D3DLIGHT7 structure describing the light
4948 * For more details, see IWineD3DDevice::SetLight
4950 *****************************************************************************/
4951 static HRESULT WINAPI
4952 IDirect3DDeviceImpl_7_SetLight(IDirect3DDevice7 *iface,
4956 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4958 TRACE("(%p)->(%08x,%p): Relay!\n", This, LightIndex, Light);
4960 EnterCriticalSection(&ddraw_cs);
4961 /* Note: D3DLIGHT7 is compatible with WINED3DLIGHT */
4962 hr = IWineD3DDevice_SetLight(This->wineD3DDevice,
4964 (WINED3DLIGHT*) Light);
4965 LeaveCriticalSection(&ddraw_cs);
4966 return hr_ddraw_from_wined3d(hr);
4969 /*****************************************************************************
4970 * IDirect3DDevice7::GetLight
4972 * Returns the light assigned to a light index
4975 * Light: Structure to write the light information to
4979 * DDERR_INVALIDPARAMS if Light is NULL
4980 * For details, see IWineD3DDevice::GetLight
4982 *****************************************************************************/
4983 static HRESULT WINAPI
4984 IDirect3DDeviceImpl_7_GetLight(IDirect3DDevice7 *iface,
4988 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4990 TRACE("(%p)->(%08x,%p): Relay!\n", This, LightIndex, Light);
4992 EnterCriticalSection(&ddraw_cs);
4993 /* Note: D3DLIGHT7 is compatible with WINED3DLIGHT */
4994 rc = IWineD3DDevice_GetLight(This->wineD3DDevice,
4996 (WINED3DLIGHT*) Light);
4998 /* Translate the result. WineD3D returns other values than D3D7 */
4999 LeaveCriticalSection(&ddraw_cs);
5000 return hr_ddraw_from_wined3d(rc);
5003 /*****************************************************************************
5004 * IDirect3DDevice7::BeginStateBlock
5006 * Begins recording to a stateblock
5012 * For details see IWineD3DDevice::BeginStateBlock
5014 *****************************************************************************/
5015 static HRESULT WINAPI
5016 IDirect3DDeviceImpl_7_BeginStateBlock(IDirect3DDevice7 *iface)
5018 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5020 TRACE("(%p)->(): Relay!\n", This);
5022 EnterCriticalSection(&ddraw_cs);
5023 hr = IWineD3DDevice_BeginStateBlock(This->wineD3DDevice);
5024 LeaveCriticalSection(&ddraw_cs);
5025 return hr_ddraw_from_wined3d(hr);
5028 /*****************************************************************************
5029 * IDirect3DDevice7::EndStateBlock
5031 * Stops recording to a state block and returns the created stateblock
5037 * BlockHandle: Address to store the stateblock's handle to
5041 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5042 * See IWineD3DDevice::EndStateBlock for more details
5044 *****************************************************************************/
5045 static HRESULT WINAPI
5046 IDirect3DDeviceImpl_7_EndStateBlock(IDirect3DDevice7 *iface,
5049 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5051 TRACE("(%p)->(%p): Relay!\n", This, BlockHandle);
5055 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
5056 return DDERR_INVALIDPARAMS;
5059 EnterCriticalSection(&ddraw_cs);
5060 *BlockHandle = IDirect3DDeviceImpl_CreateHandle(This);
5063 ERR("Cannot get a handle number for the stateblock\n");
5064 LeaveCriticalSection(&ddraw_cs);
5065 return DDERR_OUTOFMEMORY;
5067 This->Handles[*BlockHandle - 1].type = DDrawHandle_StateBlock;
5068 hr = IWineD3DDevice_EndStateBlock(This->wineD3DDevice,
5069 (IWineD3DStateBlock **) &This->Handles[*BlockHandle - 1].ptr);
5070 LeaveCriticalSection(&ddraw_cs);
5071 return hr_ddraw_from_wined3d(hr);
5074 /*****************************************************************************
5075 * IDirect3DDevice7::PreLoad
5077 * Allows the app to signal that a texture will be used soon, to allow
5078 * the Direct3DDevice to load it to the video card in the meantime.
5083 * Texture: The texture to preload
5087 * DDERR_INVALIDPARAMS if Texture is NULL
5088 * See IWineD3DSurface::PreLoad for details
5090 *****************************************************************************/
5091 static HRESULT WINAPI
5092 IDirect3DDeviceImpl_7_PreLoad(IDirect3DDevice7 *iface,
5093 IDirectDrawSurface7 *Texture)
5095 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5096 IDirectDrawSurfaceImpl *surf = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, Texture);
5098 TRACE("(%p)->(%p): Relay!\n", This, surf);
5101 return DDERR_INVALIDPARAMS;
5103 EnterCriticalSection(&ddraw_cs);
5104 IWineD3DSurface_PreLoad(surf->WineD3DSurface);
5105 LeaveCriticalSection(&ddraw_cs);
5109 /*****************************************************************************
5110 * IDirect3DDevice7::ApplyStateBlock
5112 * Activates the state stored in a state block handle.
5115 * BlockHandle: The stateblock handle to activate
5119 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5121 *****************************************************************************/
5122 static HRESULT WINAPI
5123 IDirect3DDeviceImpl_7_ApplyStateBlock(IDirect3DDevice7 *iface,
5126 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5128 TRACE("(%p)->(%08x): Relay!\n", This, BlockHandle);
5130 EnterCriticalSection(&ddraw_cs);
5131 if(!BlockHandle || BlockHandle > This->numHandles)
5133 WARN("Out of range handle %d, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5134 LeaveCriticalSection(&ddraw_cs);
5135 return D3DERR_INVALIDSTATEBLOCK;
5137 if(This->Handles[BlockHandle - 1].type != DDrawHandle_StateBlock)
5139 WARN("Handle %d is not a stateblock, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5140 LeaveCriticalSection(&ddraw_cs);
5141 return D3DERR_INVALIDSTATEBLOCK;
5144 hr = IWineD3DStateBlock_Apply((IWineD3DStateBlock *) This->Handles[BlockHandle - 1].ptr);
5145 LeaveCriticalSection(&ddraw_cs);
5146 return hr_ddraw_from_wined3d(hr);
5149 /*****************************************************************************
5150 * IDirect3DDevice7::CaptureStateBlock
5152 * Updates a stateblock's values to the values currently set for the device
5157 * BlockHandle: Stateblock to update
5161 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5162 * See IWineD3DDevice::CaptureStateBlock for more details
5164 *****************************************************************************/
5165 static HRESULT WINAPI
5166 IDirect3DDeviceImpl_7_CaptureStateBlock(IDirect3DDevice7 *iface,
5169 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5171 TRACE("(%p)->(%08x): Relay!\n", This, BlockHandle);
5173 EnterCriticalSection(&ddraw_cs);
5174 if(BlockHandle == 0 || BlockHandle > This->numHandles)
5176 WARN("Out of range handle %d, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5177 LeaveCriticalSection(&ddraw_cs);
5178 return D3DERR_INVALIDSTATEBLOCK;
5180 if(This->Handles[BlockHandle - 1].type != DDrawHandle_StateBlock)
5182 WARN("Handle %d is not a stateblock, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5183 LeaveCriticalSection(&ddraw_cs);
5184 return D3DERR_INVALIDSTATEBLOCK;
5187 hr = IWineD3DStateBlock_Capture((IWineD3DStateBlock *) This->Handles[BlockHandle - 1].ptr);
5188 LeaveCriticalSection(&ddraw_cs);
5189 return hr_ddraw_from_wined3d(hr);
5192 /*****************************************************************************
5193 * IDirect3DDevice7::DeleteStateBlock
5195 * Deletes a stateblock handle. This means releasing the WineD3DStateBlock
5200 * BlockHandle: Stateblock handle to delete
5204 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is 0
5206 *****************************************************************************/
5207 static HRESULT WINAPI
5208 IDirect3DDeviceImpl_7_DeleteStateBlock(IDirect3DDevice7 *iface,
5211 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5213 TRACE("(%p)->(%08x): Relay!\n", This, BlockHandle);
5215 EnterCriticalSection(&ddraw_cs);
5216 if(BlockHandle == 0 || BlockHandle > This->numHandles)
5218 WARN("Out of range handle %d, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5219 LeaveCriticalSection(&ddraw_cs);
5220 return D3DERR_INVALIDSTATEBLOCK;
5222 if(This->Handles[BlockHandle - 1].type != DDrawHandle_StateBlock)
5224 WARN("Handle %d is not a stateblock, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5225 LeaveCriticalSection(&ddraw_cs);
5226 return D3DERR_INVALIDSTATEBLOCK;
5229 ref = IWineD3DStateBlock_Release((IWineD3DStateBlock *) This->Handles[BlockHandle - 1].ptr);
5232 ERR("Something is still holding the stateblock %p(Handle %d). Ref = %d\n", This->Handles[BlockHandle - 1].ptr, BlockHandle, ref);
5234 This->Handles[BlockHandle - 1].ptr = NULL;
5235 This->Handles[BlockHandle - 1].type = DDrawHandle_Unknown;
5237 LeaveCriticalSection(&ddraw_cs);
5241 /*****************************************************************************
5242 * IDirect3DDevice7::CreateStateBlock
5244 * Creates a new state block handle.
5249 * Type: The state block type
5250 * BlockHandle: Address to write the created handle to
5254 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5256 *****************************************************************************/
5257 static HRESULT WINAPI
5258 IDirect3DDeviceImpl_7_CreateStateBlock(IDirect3DDevice7 *iface,
5259 D3DSTATEBLOCKTYPE Type,
5262 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5264 TRACE("(%p)->(%08x,%p)!\n", This, Type, BlockHandle);
5268 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
5269 return DDERR_INVALIDPARAMS;
5271 if(Type != D3DSBT_ALL && Type != D3DSBT_PIXELSTATE &&
5272 Type != D3DSBT_VERTEXSTATE ) {
5273 WARN("Unexpected stateblock type, returning DDERR_INVALIDPARAMS\n");
5274 return DDERR_INVALIDPARAMS;
5277 EnterCriticalSection(&ddraw_cs);
5278 *BlockHandle = IDirect3DDeviceImpl_CreateHandle(This);
5281 ERR("Cannot get a handle number for the stateblock\n");
5282 LeaveCriticalSection(&ddraw_cs);
5283 return DDERR_OUTOFMEMORY;
5285 This->Handles[*BlockHandle - 1].type = DDrawHandle_StateBlock;
5287 /* The D3DSTATEBLOCKTYPE enum is fine here */
5288 hr = IWineD3DDevice_CreateStateBlock(This->wineD3DDevice,
5290 (IWineD3DStateBlock **) &This->Handles[*BlockHandle - 1].ptr,
5291 NULL /* Parent, hope that works */);
5292 LeaveCriticalSection(&ddraw_cs);
5293 return hr_ddraw_from_wined3d(hr);
5296 /*****************************************************************************
5297 * IDirect3DDevice7::Load
5299 * Loads a rectangular area from the source into the destination texture.
5300 * It can also copy the source to the faces of a cubic environment map
5305 * DestTex: Destination texture
5306 * DestPoint: Point in the destination where the source image should be
5308 * SrcTex: Source texture
5309 * SrcRect: Source rectangle
5314 * DDERR_INVALIDPARAMS if DestTex or SrcTex are NULL
5315 * See IDirect3DTexture2::Load for details
5317 *****************************************************************************/
5318 static HRESULT WINAPI
5319 IDirect3DDeviceImpl_7_Load(IDirect3DDevice7 *iface,
5320 IDirectDrawSurface7 *DestTex,
5322 IDirectDrawSurface7 *SrcTex,
5326 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5327 IDirectDrawSurfaceImpl *dest = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, DestTex);
5328 IDirectDrawSurfaceImpl *src = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, SrcTex);
5329 FIXME("(%p)->(%p,%p,%p,%p,%08x): Partially Implemented!\n", This, dest, DestPoint, src, SrcRect, Flags);
5331 if( (!src) || (!dest) )
5332 return DDERR_INVALIDPARAMS;
5334 IDirect3DTexture2_Load(ICOM_INTERFACE(dest, IDirect3DTexture2),
5335 ICOM_INTERFACE(src, IDirect3DTexture2));
5339 /*****************************************************************************
5340 * IDirect3DDevice7::LightEnable
5342 * Enables or disables a light
5344 * Version 7, IDirect3DLight uses this method too.
5347 * LightIndex: The index of the light to enable / disable
5348 * Enable: Enable or disable the light
5352 * For more details, see IWineD3DDevice::SetLightEnable
5354 *****************************************************************************/
5355 static HRESULT WINAPI
5356 IDirect3DDeviceImpl_7_LightEnable(IDirect3DDevice7 *iface,
5360 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5362 TRACE("(%p)->(%08x,%d): Relay!\n", This, LightIndex, Enable);
5364 EnterCriticalSection(&ddraw_cs);
5365 hr = IWineD3DDevice_SetLightEnable(This->wineD3DDevice, LightIndex, Enable);
5366 LeaveCriticalSection(&ddraw_cs);
5367 return hr_ddraw_from_wined3d(hr);
5370 /*****************************************************************************
5371 * IDirect3DDevice7::GetLightEnable
5373 * Retrieves if the light with the given index is enabled or not
5378 * LightIndex: Index of desired light
5379 * Enable: Pointer to a BOOL which contains the result
5383 * DDERR_INVALIDPARAMS if Enable is NULL
5384 * See IWineD3DDevice::GetLightEnable for more details
5386 *****************************************************************************/
5387 static HRESULT WINAPI
5388 IDirect3DDeviceImpl_7_GetLightEnable(IDirect3DDevice7 *iface,
5392 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5394 TRACE("(%p)->(%08x,%p): Relay\n", This, LightIndex, Enable);
5397 return DDERR_INVALIDPARAMS;
5399 EnterCriticalSection(&ddraw_cs);
5400 hr = IWineD3DDevice_GetLightEnable(This->wineD3DDevice, LightIndex, Enable);
5401 LeaveCriticalSection(&ddraw_cs);
5402 return hr_ddraw_from_wined3d(hr);
5405 /*****************************************************************************
5406 * IDirect3DDevice7::SetClipPlane
5408 * Sets custom clipping plane
5413 * Index: The index of the clipping plane
5414 * PlaneEquation: An equation defining the clipping plane
5418 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
5419 * See IWineD3DDevice::SetClipPlane for more details
5421 *****************************************************************************/
5422 static HRESULT WINAPI
5423 IDirect3DDeviceImpl_7_SetClipPlane(IDirect3DDevice7 *iface,
5425 D3DVALUE* PlaneEquation)
5427 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5429 TRACE("(%p)->(%08x,%p): Relay!\n", This, Index, PlaneEquation);
5432 return DDERR_INVALIDPARAMS;
5434 EnterCriticalSection(&ddraw_cs);
5435 hr = IWineD3DDevice_SetClipPlane(This->wineD3DDevice, Index, PlaneEquation);
5436 LeaveCriticalSection(&ddraw_cs);
5440 /*****************************************************************************
5441 * IDirect3DDevice7::GetClipPlane
5443 * Returns the clipping plane with a specific index
5446 * Index: The index of the desired plane
5447 * PlaneEquation: Address to store the plane equation to
5451 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
5452 * See IWineD3DDevice::GetClipPlane for more details
5454 *****************************************************************************/
5455 static HRESULT WINAPI
5456 IDirect3DDeviceImpl_7_GetClipPlane(IDirect3DDevice7 *iface,
5458 D3DVALUE* PlaneEquation)
5460 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5462 TRACE("(%p)->(%d,%p): Relay!\n", This, Index, PlaneEquation);
5465 return DDERR_INVALIDPARAMS;
5467 EnterCriticalSection(&ddraw_cs);
5468 hr = IWineD3DDevice_GetClipPlane(This->wineD3DDevice, Index, PlaneEquation);
5469 LeaveCriticalSection(&ddraw_cs);
5473 /*****************************************************************************
5474 * IDirect3DDevice7::GetInfo
5476 * Retrieves some information about the device. The DirectX sdk says that
5477 * this version returns S_FALSE for all retail builds of DirectX, that's what
5478 * this implementation does.
5481 * DevInfoID: Information type requested
5482 * DevInfoStruct: Pointer to a structure to store the info to
5483 * Size: Size of the structure
5486 * S_FALSE, because it's a non-debug driver
5488 *****************************************************************************/
5489 static HRESULT WINAPI
5490 IDirect3DDeviceImpl_7_GetInfo(IDirect3DDevice7 *iface,
5492 void *DevInfoStruct,
5495 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5496 TRACE("(%p)->(%08x,%p,%08x)\n", This, DevInfoID, DevInfoStruct, Size);
5500 TRACE(" info requested : ");
5503 case D3DDEVINFOID_TEXTUREMANAGER: TRACE("D3DDEVINFOID_TEXTUREMANAGER\n"); break;
5504 case D3DDEVINFOID_D3DTEXTUREMANAGER: TRACE("D3DDEVINFOID_D3DTEXTUREMANAGER\n"); break;
5505 case D3DDEVINFOID_TEXTURING: TRACE("D3DDEVINFOID_TEXTURING\n"); break;
5506 default: ERR(" invalid flag !!!\n"); return DDERR_INVALIDPARAMS;
5510 return S_FALSE; /* According to MSDN, this is valid for a non-debug driver */
5513 const IDirect3DDevice7Vtbl IDirect3DDevice7_Vtbl =
5515 /*** IUnknown Methods ***/
5516 IDirect3DDeviceImpl_7_QueryInterface,
5517 IDirect3DDeviceImpl_7_AddRef,
5518 IDirect3DDeviceImpl_7_Release,
5519 /*** IDirect3DDevice7 ***/
5520 IDirect3DDeviceImpl_7_GetCaps,
5521 IDirect3DDeviceImpl_7_EnumTextureFormats,
5522 IDirect3DDeviceImpl_7_BeginScene,
5523 IDirect3DDeviceImpl_7_EndScene,
5524 IDirect3DDeviceImpl_7_GetDirect3D,
5525 IDirect3DDeviceImpl_7_SetRenderTarget,
5526 IDirect3DDeviceImpl_7_GetRenderTarget,
5527 IDirect3DDeviceImpl_7_Clear,
5528 IDirect3DDeviceImpl_7_SetTransform,
5529 IDirect3DDeviceImpl_7_GetTransform,
5530 IDirect3DDeviceImpl_7_SetViewport,
5531 IDirect3DDeviceImpl_7_MultiplyTransform,
5532 IDirect3DDeviceImpl_7_GetViewport,
5533 IDirect3DDeviceImpl_7_SetMaterial,
5534 IDirect3DDeviceImpl_7_GetMaterial,
5535 IDirect3DDeviceImpl_7_SetLight,
5536 IDirect3DDeviceImpl_7_GetLight,
5537 IDirect3DDeviceImpl_7_SetRenderState,
5538 IDirect3DDeviceImpl_7_GetRenderState,
5539 IDirect3DDeviceImpl_7_BeginStateBlock,
5540 IDirect3DDeviceImpl_7_EndStateBlock,
5541 IDirect3DDeviceImpl_7_PreLoad,
5542 IDirect3DDeviceImpl_7_DrawPrimitive,
5543 IDirect3DDeviceImpl_7_DrawIndexedPrimitive,
5544 IDirect3DDeviceImpl_7_SetClipStatus,
5545 IDirect3DDeviceImpl_7_GetClipStatus,
5546 IDirect3DDeviceImpl_7_DrawPrimitiveStrided,
5547 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided,
5548 IDirect3DDeviceImpl_7_DrawPrimitiveVB,
5549 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB,
5550 IDirect3DDeviceImpl_7_ComputeSphereVisibility,
5551 IDirect3DDeviceImpl_7_GetTexture,
5552 IDirect3DDeviceImpl_7_SetTexture,
5553 IDirect3DDeviceImpl_7_GetTextureStageState,
5554 IDirect3DDeviceImpl_7_SetTextureStageState,
5555 IDirect3DDeviceImpl_7_ValidateDevice,
5556 IDirect3DDeviceImpl_7_ApplyStateBlock,
5557 IDirect3DDeviceImpl_7_CaptureStateBlock,
5558 IDirect3DDeviceImpl_7_DeleteStateBlock,
5559 IDirect3DDeviceImpl_7_CreateStateBlock,
5560 IDirect3DDeviceImpl_7_Load,
5561 IDirect3DDeviceImpl_7_LightEnable,
5562 IDirect3DDeviceImpl_7_GetLightEnable,
5563 IDirect3DDeviceImpl_7_SetClipPlane,
5564 IDirect3DDeviceImpl_7_GetClipPlane,
5565 IDirect3DDeviceImpl_7_GetInfo
5568 const IDirect3DDevice3Vtbl IDirect3DDevice3_Vtbl =
5570 /*** IUnknown Methods ***/
5571 Thunk_IDirect3DDeviceImpl_3_QueryInterface,
5572 Thunk_IDirect3DDeviceImpl_3_AddRef,
5573 Thunk_IDirect3DDeviceImpl_3_Release,
5574 /*** IDirect3DDevice3 ***/
5575 IDirect3DDeviceImpl_3_GetCaps,
5576 IDirect3DDeviceImpl_3_GetStats,
5577 IDirect3DDeviceImpl_3_AddViewport,
5578 IDirect3DDeviceImpl_3_DeleteViewport,
5579 IDirect3DDeviceImpl_3_NextViewport,
5580 Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats,
5581 Thunk_IDirect3DDeviceImpl_3_BeginScene,
5582 Thunk_IDirect3DDeviceImpl_3_EndScene,
5583 Thunk_IDirect3DDeviceImpl_3_GetDirect3D,
5584 IDirect3DDeviceImpl_3_SetCurrentViewport,
5585 IDirect3DDeviceImpl_3_GetCurrentViewport,
5586 Thunk_IDirect3DDeviceImpl_3_SetRenderTarget,
5587 Thunk_IDirect3DDeviceImpl_3_GetRenderTarget,
5588 IDirect3DDeviceImpl_3_Begin,
5589 IDirect3DDeviceImpl_3_BeginIndexed,
5590 IDirect3DDeviceImpl_3_Vertex,
5591 IDirect3DDeviceImpl_3_Index,
5592 IDirect3DDeviceImpl_3_End,
5593 Thunk_IDirect3DDeviceImpl_3_GetRenderState,
5594 Thunk_IDirect3DDeviceImpl_3_SetRenderState,
5595 IDirect3DDeviceImpl_3_GetLightState,
5596 IDirect3DDeviceImpl_3_SetLightState,
5597 Thunk_IDirect3DDeviceImpl_3_SetTransform,
5598 Thunk_IDirect3DDeviceImpl_3_GetTransform,
5599 Thunk_IDirect3DDeviceImpl_3_MultiplyTransform,
5600 Thunk_IDirect3DDeviceImpl_3_DrawPrimitive,
5601 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive,
5602 Thunk_IDirect3DDeviceImpl_3_SetClipStatus,
5603 Thunk_IDirect3DDeviceImpl_3_GetClipStatus,
5604 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided,
5605 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided,
5606 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB,
5607 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB,
5608 Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility,
5609 Thunk_IDirect3DDeviceImpl_3_GetTexture,
5610 Thunk_IDirect3DDeviceImpl_3_SetTexture,
5611 Thunk_IDirect3DDeviceImpl_3_GetTextureStageState,
5612 Thunk_IDirect3DDeviceImpl_3_SetTextureStageState,
5613 Thunk_IDirect3DDeviceImpl_3_ValidateDevice
5616 const IDirect3DDevice2Vtbl IDirect3DDevice2_Vtbl =
5618 /*** IUnknown Methods ***/
5619 Thunk_IDirect3DDeviceImpl_2_QueryInterface,
5620 Thunk_IDirect3DDeviceImpl_2_AddRef,
5621 Thunk_IDirect3DDeviceImpl_2_Release,
5622 /*** IDirect3DDevice2 ***/
5623 Thunk_IDirect3DDeviceImpl_2_GetCaps,
5624 IDirect3DDeviceImpl_2_SwapTextureHandles,
5625 Thunk_IDirect3DDeviceImpl_2_GetStats,
5626 Thunk_IDirect3DDeviceImpl_2_AddViewport,
5627 Thunk_IDirect3DDeviceImpl_2_DeleteViewport,
5628 Thunk_IDirect3DDeviceImpl_2_NextViewport,
5629 IDirect3DDeviceImpl_2_EnumTextureFormats,
5630 Thunk_IDirect3DDeviceImpl_2_BeginScene,
5631 Thunk_IDirect3DDeviceImpl_2_EndScene,
5632 Thunk_IDirect3DDeviceImpl_2_GetDirect3D,
5633 Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport,
5634 Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport,
5635 Thunk_IDirect3DDeviceImpl_2_SetRenderTarget,
5636 Thunk_IDirect3DDeviceImpl_2_GetRenderTarget,
5637 Thunk_IDirect3DDeviceImpl_2_Begin,
5638 Thunk_IDirect3DDeviceImpl_2_BeginIndexed,
5639 Thunk_IDirect3DDeviceImpl_2_Vertex,
5640 Thunk_IDirect3DDeviceImpl_2_Index,
5641 Thunk_IDirect3DDeviceImpl_2_End,
5642 IDirect3DDeviceImpl_2_GetRenderState,
5643 IDirect3DDeviceImpl_2_SetRenderState,
5644 Thunk_IDirect3DDeviceImpl_2_GetLightState,
5645 Thunk_IDirect3DDeviceImpl_2_SetLightState,
5646 Thunk_IDirect3DDeviceImpl_2_SetTransform,
5647 Thunk_IDirect3DDeviceImpl_2_GetTransform,
5648 Thunk_IDirect3DDeviceImpl_2_MultiplyTransform,
5649 Thunk_IDirect3DDeviceImpl_2_DrawPrimitive,
5650 Thunk_IDirect3DDeviceImpl_2_DrawIndexedPrimitive,
5651 Thunk_IDirect3DDeviceImpl_2_SetClipStatus,
5652 Thunk_IDirect3DDeviceImpl_2_GetClipStatus
5655 const IDirect3DDeviceVtbl IDirect3DDevice1_Vtbl =
5657 /*** IUnknown Methods ***/
5658 Thunk_IDirect3DDeviceImpl_1_QueryInterface,
5659 Thunk_IDirect3DDeviceImpl_1_AddRef,
5660 Thunk_IDirect3DDeviceImpl_1_Release,
5661 /*** IDirect3DDevice1 ***/
5662 IDirect3DDeviceImpl_1_Initialize,
5663 Thunk_IDirect3DDeviceImpl_1_GetCaps,
5664 Thunk_IDirect3DDeviceImpl_1_SwapTextureHandles,
5665 IDirect3DDeviceImpl_1_CreateExecuteBuffer,
5666 Thunk_IDirect3DDeviceImpl_1_GetStats,
5667 IDirect3DDeviceImpl_1_Execute,
5668 Thunk_IDirect3DDeviceImpl_1_AddViewport,
5669 Thunk_IDirect3DDeviceImpl_1_DeleteViewport,
5670 Thunk_IDirect3DDeviceImpl_1_NextViewport,
5671 IDirect3DDeviceImpl_1_Pick,
5672 IDirect3DDeviceImpl_1_GetPickRecords,
5673 Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats,
5674 IDirect3DDeviceImpl_1_CreateMatrix,
5675 IDirect3DDeviceImpl_1_SetMatrix,
5676 IDirect3DDeviceImpl_1_GetMatrix,
5677 IDirect3DDeviceImpl_1_DeleteMatrix,
5678 Thunk_IDirect3DDeviceImpl_1_BeginScene,
5679 Thunk_IDirect3DDeviceImpl_1_EndScene,
5680 Thunk_IDirect3DDeviceImpl_1_GetDirect3D
5683 /*****************************************************************************
5684 * IDirect3DDeviceImpl_CreateHandle
5686 * Not called from the VTable
5688 * Some older interface versions operate with handles, which are basically
5689 * DWORDs which identify an interface, for example
5690 * IDirect3DDevice::SetRenderState with DIRECT3DRENDERSTATE_TEXTUREHANDLE
5692 * Those handle could be just casts to the interface pointers or vice versa,
5693 * but that is not 64 bit safe and would mean blindly derefering a DWORD
5694 * passed by the app. Instead there is a dynamic array in the device which
5695 * keeps a DWORD to pointer information and a type for the handle.
5697 * Basically this array only grows, when a handle is freed its pointer is
5698 * just set to NULL. There will be much more reads from the array than
5699 * insertion operations, so a dynamic array is fine.
5702 * This: D3DDevice implementation for which this handle should be created
5705 * A free handle on success
5708 *****************************************************************************/
5710 IDirect3DDeviceImpl_CreateHandle(IDirect3DDeviceImpl *This)
5713 struct HandleEntry *oldHandles = This->Handles;
5715 TRACE("(%p)\n", This);
5717 for(i = 0; i < This->numHandles; i++)
5719 if(This->Handles[i].ptr == NULL &&
5720 This->Handles[i].type == DDrawHandle_Unknown)
5722 TRACE("Reusing freed handle %d\n", i + 1);
5727 TRACE("Growing the handle array\n");
5730 This->Handles = HeapAlloc(GetProcessHeap(), 0, sizeof(struct HandleEntry) * This->numHandles);
5733 ERR("Out of memory\n");
5734 This->Handles = oldHandles;
5740 memcpy(This->Handles, oldHandles, (This->numHandles - 1) * sizeof(struct HandleEntry));
5741 HeapFree(GetProcessHeap(), 0, oldHandles);
5744 TRACE("Returning %d\n", This->numHandles);
5745 return This->numHandles;
5748 /*****************************************************************************
5749 * IDirect3DDeviceImpl_UpdateDepthStencil
5751 * Checks the current render target for attached depth stencils and sets the
5752 * WineD3D depth stencil accordingly.
5755 * The depth stencil state to set if creating the device
5757 *****************************************************************************/
5759 IDirect3DDeviceImpl_UpdateDepthStencil(IDirect3DDeviceImpl *This)
5761 IDirectDrawSurface7 *depthStencil = NULL;
5762 IDirectDrawSurfaceImpl *dsi;
5763 static DDSCAPS2 depthcaps = { DDSCAPS_ZBUFFER, 0, 0, 0 };
5765 IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(This->target, IDirectDrawSurface7),
5770 TRACE("Setting wined3d depth stencil to NULL\n");
5771 IWineD3DDevice_SetDepthStencilSurface(This->wineD3DDevice,
5773 return WINED3DZB_FALSE;
5776 dsi = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, depthStencil);
5777 TRACE("Setting wined3d depth stencil to %p (wined3d %p)\n", dsi, dsi->WineD3DSurface);
5778 IWineD3DDevice_SetDepthStencilSurface(This->wineD3DDevice,
5779 dsi->WineD3DSurface);
5781 IDirectDrawSurface7_Release(depthStencil);
5782 return WINED3DZB_TRUE;