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"
31 #include "wine/debug.h"
44 #include "wine/exception.h"
49 #include "ddraw_private.h"
51 WINE_DEFAULT_DEBUG_CHANNEL(d3d7);
52 WINE_DECLARE_DEBUG_CHANNEL(ddraw_thunk);
55 const GUID IID_D3DDEVICE_WineD3D = {
59 { 0xb7,0x98,0xc6,0x8a,0x77,0x2d,0x72,0x2a }
62 /*****************************************************************************
63 * IUnknown Methods. Common for Version 1, 2, 3 and 7
64 *****************************************************************************/
66 /*****************************************************************************
67 * IDirect3DDevice7::QueryInterface
69 * Used to query other interfaces from a Direct3DDevice interface.
70 * It can return interface pointers to all Direct3DDevice versions as well
71 * as IDirectDraw and IDirect3D. For a link to QueryInterface
72 * rules see ddraw.c, IDirectDraw7::QueryInterface
74 * Exists in Version 1, 2, 3 and 7
77 * refiid: Interface ID queried for
78 * obj: Used to return the interface pointer
81 * D3D_OK or E_NOINTERFACE
83 *****************************************************************************/
85 IDirect3DDeviceImpl_7_QueryInterface(IDirect3DDevice7 *iface,
89 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
90 TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(refiid), obj);
92 /* According to COM docs, if the QueryInterface fails, obj should be set to NULL */
96 return DDERR_INVALIDPARAMS;
98 if ( IsEqualGUID( &IID_IUnknown, refiid ) )
100 *obj = ICOM_INTERFACE(This, IDirect3DDevice7);
103 /* Check DirectDraw Interfac
\ 1s */
104 else if( IsEqualGUID( &IID_IDirectDraw7, refiid ) )
106 *obj = ICOM_INTERFACE(This->ddraw, IDirectDraw7);
107 TRACE("(%p) Returning IDirectDraw7 interface at %p\n", This, *obj);
109 else if ( IsEqualGUID( &IID_IDirectDraw4, refiid ) )
111 *obj = ICOM_INTERFACE(This->ddraw, IDirectDraw4);
112 TRACE("(%p) Returning IDirectDraw4 interface at %p\n", This, *obj);
114 else if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) )
116 *obj = ICOM_INTERFACE(This->ddraw, IDirectDraw2);
117 TRACE("(%p) Returning IDirectDraw2 interface at %p\n", This, *obj);
119 else if( IsEqualGUID( &IID_IDirectDraw, refiid ) )
121 *obj = ICOM_INTERFACE(This->ddraw, IDirectDraw);
122 TRACE("(%p) Returning IDirectDraw interface at %p\n", This, *obj);
126 else if ( IsEqualGUID( &IID_IDirect3D , refiid ) )
128 *obj = ICOM_INTERFACE(This->ddraw, IDirect3D);
129 TRACE("(%p) Returning IDirect3D interface at %p\n", This, *obj);
131 else if ( IsEqualGUID( &IID_IDirect3D2 , refiid ) )
133 *obj = ICOM_INTERFACE(This->ddraw, IDirect3D2);
134 TRACE("(%p) Returning IDirect3D2 interface at %p\n", This, *obj);
136 else if ( IsEqualGUID( &IID_IDirect3D3 , refiid ) )
138 *obj = ICOM_INTERFACE(This->ddraw, IDirect3D3);
139 TRACE("(%p) Returning IDirect3D3 interface at %p\n", This, *obj);
141 else if ( IsEqualGUID( &IID_IDirect3D7 , refiid ) )
143 *obj = ICOM_INTERFACE(This->ddraw, IDirect3D7);
144 TRACE("(%p) Returning IDirect3D7 interface at %p\n", This, *obj);
148 else if ( IsEqualGUID( &IID_IDirect3DDevice , refiid ) )
150 *obj = ICOM_INTERFACE(This, IDirect3DDevice);
151 TRACE("(%p) Returning IDirect3DDevice interface at %p\n", This, *obj);
153 else if ( IsEqualGUID( &IID_IDirect3DDevice2 , refiid ) ) {
154 *obj = ICOM_INTERFACE(This, IDirect3DDevice2);
155 TRACE("(%p) Returning IDirect3DDevice2 interface at %p\n", This, *obj);
157 else if ( IsEqualGUID( &IID_IDirect3DDevice3 , refiid ) ) {
158 *obj = ICOM_INTERFACE(This, IDirect3DDevice3);
159 TRACE("(%p) Returning IDirect3DDevice3 interface at %p\n", This, *obj);
161 else if ( IsEqualGUID( &IID_IDirect3DDevice7 , refiid ) ) {
162 *obj = ICOM_INTERFACE(This, IDirect3DDevice7);
163 TRACE("(%p) Returning IDirect3DDevice7 interface at %p\n", This, *obj);
166 /* Unknown interface */
169 ERR("(%p)->(%s, %p): No interface found\n", This, debugstr_guid(refiid), obj);
170 return E_NOINTERFACE;
173 /* AddRef the returned interface */
174 IUnknown_AddRef( (IUnknown *) *obj);
178 static HRESULT WINAPI
179 Thunk_IDirect3DDeviceImpl_3_QueryInterface(IDirect3DDevice3 *iface,
183 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
184 TRACE_(ddraw_thunk)("(%p)->(%s,%p) thunking to IDirect3DDevice7 interface.\n", This, debugstr_guid(riid), obj);
185 return IDirect3DDevice7_QueryInterface(ICOM_INTERFACE(This, IDirect3DDevice7),
190 static HRESULT WINAPI
191 Thunk_IDirect3DDeviceImpl_2_QueryInterface(IDirect3DDevice2 *iface,
195 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
196 TRACE_(ddraw_thunk)("(%p)->(%s,%p) thunking to IDirect3DDevice7 interface.\n", This, debugstr_guid(riid), obj);
197 return IDirect3DDevice7_QueryInterface(ICOM_INTERFACE(This, IDirect3DDevice7),
202 static HRESULT WINAPI
203 Thunk_IDirect3DDeviceImpl_1_QueryInterface(IDirect3DDevice *iface,
207 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
208 TRACE_(ddraw_thunk)("(%p)->(%s,%p) thunking to IDirect3DDevice7 interface.\n", This, debugstr_guid(riid), obp);
209 return IDirect3DDevice7_QueryInterface(ICOM_INTERFACE(This, IDirect3DDevice7),
214 /*****************************************************************************
215 * IDirect3DDevice7::AddRef
217 * Increases the refcount....
218 * The most exciting Method, definitely
220 * Exists in Version 1, 2, 3 and 7
225 *****************************************************************************/
227 IDirect3DDeviceImpl_7_AddRef(IDirect3DDevice7 *iface)
229 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
230 ULONG ref = InterlockedIncrement(&This->ref);
232 TRACE("(%p) : incrementing from %u.\n", This, ref -1);
238 Thunk_IDirect3DDeviceImpl_3_AddRef(IDirect3DDevice3 *iface)
240 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
241 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
242 return IDirect3DDevice7_AddRef(ICOM_INTERFACE(This, IDirect3DDevice7));
246 Thunk_IDirect3DDeviceImpl_2_AddRef(IDirect3DDevice2 *iface)
248 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
249 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
250 return IDirect3DDevice7_AddRef(ICOM_INTERFACE(This, IDirect3DDevice7));
254 Thunk_IDirect3DDeviceImpl_1_AddRef(IDirect3DDevice *iface)
256 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", iface);
257 return IDirect3DDevice7_AddRef(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice7, iface));
260 /*****************************************************************************
261 * IDirect3DDevice7::Release
263 * Decreases the refcount of the interface
264 * When the refcount is reduced to 0, the object is destroyed.
266 * Exists in Version 1, 2, 3 and 7
271 *****************************************************************************/
273 IDirect3DDeviceImpl_7_Release(IDirect3DDevice7 *iface)
275 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
276 ULONG ref = InterlockedDecrement(&This->ref);
278 TRACE("(%p)->() decrementing from %u.\n", This, ref +1);
280 /* This method doesn't destroy the WineD3DDevice, because it's still in use for
281 * 2D rendering. IDirectDrawSurface7::Release will destroy the WineD3DDevice
282 * when the render target is released
286 IParent *IndexBufferParent;
289 EnterCriticalSection(&ddraw_cs);
290 /* Free the index buffer. */
291 IWineD3DDevice_SetIndices(This->wineD3DDevice,
294 IWineD3DIndexBuffer_GetParent(This->indexbuffer,
295 (IUnknown **) &IndexBufferParent);
296 IParent_Release(IndexBufferParent); /* Once for the getParent */
297 if( IParent_Release(IndexBufferParent) != 0) /* And now to destroy it */
299 ERR(" (%p) Something is still holding the index buffer parent %p\n", This, IndexBufferParent);
302 /* There is no need to unset the vertex buffer here, IWineD3DDevice_Uninit3D will do that when
303 * destroying the primary stateblock. If a vertex buffer is destroyed while it is bound
304 * IDirect3DVertexBuffer::Release will unset it.
307 /* Restore the render targets */
308 if(This->OffScreenTarget)
314 vp.Width = This->ddraw->d3d_target->surface_desc.dwWidth;
315 vp.Height = This->ddraw->d3d_target->surface_desc.dwHeight;
318 IWineD3DDevice_SetViewport(This->wineD3DDevice,
321 /* Set the device up to render to the front buffer since the back buffer will
324 IWineD3DDevice_SetRenderTarget(This->wineD3DDevice, 0,
325 This->ddraw->d3d_target->WineD3DSurface);
326 /* This->target is the offscreen target.
327 * This->ddraw->d3d_target is the target used by DDraw
329 TRACE("(%p) Release: Using %p as front buffer, %p as back buffer\n", This, This->ddraw->d3d_target, NULL);
330 IWineD3DDevice_SetFrontBackBuffers(This->wineD3DDevice,
331 This->ddraw->d3d_target->WineD3DSurface,
335 /* Release the WineD3DDevice. This won't destroy it */
336 if(IWineD3DDevice_Release(This->wineD3DDevice) <= 0)
338 ERR(" (%p) The wineD3D device %p was destroyed unexpectadely. Prepare for trouble\n", This, This->wineD3DDevice);
341 /* The texture handles should be unset by now, but there might be some bits
342 * missing in our reference counting(needs test). Do a sanity check
344 for(i = 0; i < This->numHandles; i++)
346 if(This->Handles[i].ptr)
348 switch(This->Handles[i].type)
350 case DDrawHandle_Texture:
352 IDirectDrawSurfaceImpl *surf = (IDirectDrawSurfaceImpl *) This->Handles[i].ptr;
353 FIXME("Texture Handle %d not unset properly\n", i + 1);
358 case DDrawHandle_Material:
360 IDirect3DMaterialImpl *mat = (IDirect3DMaterialImpl *) This->Handles[i].ptr;
361 FIXME("Material handle %d not unset properly\n", i + 1);
366 case DDrawHandle_Matrix:
368 /* No fixme here because this might happen because of sloppy apps */
369 WARN("Leftover matrix handle %d, deleting\n", i + 1);
370 IDirect3DDevice_DeleteMatrix(ICOM_INTERFACE(This, IDirect3DDevice),
375 case DDrawHandle_StateBlock:
377 /* No fixme here because this might happen because of sloppy apps */
378 WARN("Leftover stateblock handle %d, deleting\n", i + 1);
379 IDirect3DDevice7_DeleteStateBlock(ICOM_INTERFACE(This, IDirect3DDevice7),
385 FIXME("Unknown handle %d not unset properly\n", i + 1);
390 HeapFree(GetProcessHeap(), 0, This->Handles);
392 TRACE("Releasing target %p %p\n", This->target, This->ddraw->d3d_target);
393 /* Release the render target and the WineD3D render target
394 * (See IDirect3D7::CreateDevice for more comments on this)
396 IDirectDrawSurface7_Release(ICOM_INTERFACE(This->target, IDirectDrawSurface7));
397 IDirectDrawSurface7_Release(ICOM_INTERFACE(This->ddraw->d3d_target,IDirectDrawSurface7));
398 TRACE("Target release done\n");
400 This->ddraw->d3ddevice = NULL;
402 /* Now free the structure */
403 HeapFree(GetProcessHeap(), 0, This);
404 LeaveCriticalSection(&ddraw_cs);
412 Thunk_IDirect3DDeviceImpl_3_Release(IDirect3DDevice3 *iface)
414 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
415 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
416 return IDirect3DDevice7_Release(ICOM_INTERFACE(This, IDirect3DDevice7));
420 Thunk_IDirect3DDeviceImpl_2_Release(IDirect3DDevice2 *iface)
422 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
423 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
424 return IDirect3DDevice7_Release(ICOM_INTERFACE(This, IDirect3DDevice7));
428 Thunk_IDirect3DDeviceImpl_1_Release(IDirect3DDevice *iface)
430 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
431 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
432 return IDirect3DDevice7_Release(ICOM_INTERFACE(This, IDirect3DDevice7));
435 /*****************************************************************************
436 * IDirect3DDevice Methods
437 *****************************************************************************/
439 /*****************************************************************************
440 * IDirect3DDevice::Initialize
442 * Initializes a Direct3DDevice. This implementation is a no-op, as all
443 * initialization is done at create time.
445 * Exists in Version 1
448 * No idea what they mean, as the MSDN page is gone
452 *****************************************************************************/
453 static HRESULT WINAPI
454 IDirect3DDeviceImpl_1_Initialize(IDirect3DDevice *iface,
455 IDirect3D *Direct3D, GUID *guid,
458 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
460 /* It shouldn't be crucial, but print a FIXME, I'm interested if
461 * any game calls it and when
463 FIXME("(%p)->(%p,%p,%p): No-op!\n", This, Direct3D, guid, Desc);
468 /*****************************************************************************
469 * IDirect3DDevice7::GetCaps
471 * Retrieves the device's capabilities
473 * This implementation is used for Version 7 only, the older versions have
474 * their own implementation.
477 * Desc: Pointer to a D3DDEVICEDESC7 structure to fill
481 * D3DERR_* if a problem occurs. See WineD3D
483 *****************************************************************************/
484 static HRESULT WINAPI
485 IDirect3DDeviceImpl_7_GetCaps(IDirect3DDevice7 *iface,
486 D3DDEVICEDESC7 *Desc)
488 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
489 D3DDEVICEDESC OldDesc;
490 TRACE("(%p)->(%p)\n", This, Desc);
492 /* Call the same function used by IDirect3D, this saves code */
493 return IDirect3DImpl_GetCaps(This->ddraw->wineD3D, &OldDesc, Desc);
496 /*****************************************************************************
497 * IDirect3DDevice3::GetCaps
499 * Retrieves the capabilities of the hardware device and the emulation
500 * device. For Wine, hardware and emulation are the same (it's all HW).
502 * This implementation is used for Version 1, 2, and 3. Version 7 has its own
505 * HWDesc: Structure to fill with the HW caps
506 * HelDesc: Structure to fill with the hardare emulation caps
510 * D3DERR_* if a problem occurs. See WineD3D
512 *****************************************************************************/
513 static HRESULT WINAPI
514 IDirect3DDeviceImpl_3_GetCaps(IDirect3DDevice3 *iface,
515 D3DDEVICEDESC *HWDesc,
516 D3DDEVICEDESC *HelDesc)
518 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
519 D3DDEVICEDESC7 newDesc;
521 TRACE("(%p)->(%p,%p)\n", iface, HWDesc, HelDesc);
523 hr = IDirect3DImpl_GetCaps(This->ddraw->wineD3D, HWDesc, &newDesc);
524 if(hr != D3D_OK) return hr;
530 static HRESULT WINAPI
531 Thunk_IDirect3DDeviceImpl_2_GetCaps(IDirect3DDevice2 *iface,
532 D3DDEVICEDESC *D3DHWDevDesc,
533 D3DDEVICEDESC *D3DHELDevDesc)
535 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
536 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice3 interface.\n", This, D3DHWDevDesc, D3DHELDevDesc);
537 return IDirect3DDevice3_GetCaps(ICOM_INTERFACE(This, IDirect3DDevice3),
542 static HRESULT WINAPI
543 Thunk_IDirect3DDeviceImpl_1_GetCaps(IDirect3DDevice *iface,
544 D3DDEVICEDESC *D3DHWDevDesc,
545 D3DDEVICEDESC *D3DHELDevDesc)
547 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
548 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice3 interface.\n", This, D3DHWDevDesc, D3DHELDevDesc);
549 return IDirect3DDevice3_GetCaps(ICOM_INTERFACE(This, IDirect3DDevice3),
554 /*****************************************************************************
555 * IDirect3DDevice2::SwapTextureHandles
557 * Swaps the texture handles of 2 Texture interfaces. Version 1 and 2
560 * Tex1, Tex2: The 2 Textures to swap
565 *****************************************************************************/
566 static HRESULT WINAPI
567 IDirect3DDeviceImpl_2_SwapTextureHandles(IDirect3DDevice2 *iface,
568 IDirect3DTexture2 *Tex1,
569 IDirect3DTexture2 *Tex2)
571 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
573 IDirectDrawSurfaceImpl *surf1 = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture2, Tex1);
574 IDirectDrawSurfaceImpl *surf2 = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture2, Tex2);
575 TRACE("(%p)->(%p,%p)\n", This, surf1, surf2);
577 EnterCriticalSection(&ddraw_cs);
578 This->Handles[surf1->Handle - 1].ptr = surf2;
579 This->Handles[surf2->Handle - 1].ptr = surf1;
581 swap = surf2->Handle;
582 surf2->Handle = surf1->Handle;
583 surf1->Handle = swap;
584 LeaveCriticalSection(&ddraw_cs);
589 static HRESULT WINAPI
590 Thunk_IDirect3DDeviceImpl_1_SwapTextureHandles(IDirect3DDevice *iface,
591 IDirect3DTexture *D3DTex1,
592 IDirect3DTexture *D3DTex2)
594 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
595 IDirectDrawSurfaceImpl *surf1 = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture, D3DTex1);
596 IDirectDrawSurfaceImpl *surf2 = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture, D3DTex2);
597 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice2 interface.\n", This, surf1, surf2);
598 return IDirect3DDevice2_SwapTextureHandles(ICOM_INTERFACE(This, IDirect3DDevice2),
599 ICOM_INTERFACE(surf1, IDirect3DTexture2),
600 ICOM_INTERFACE(surf2, IDirect3DTexture2));
603 /*****************************************************************************
604 * IDirect3DDevice3::GetStats
606 * This method seems to retrieve some stats from the device.
607 * The MSDN documentation doesn't exist any more, but the D3DSTATS
608 * structure suggests that the amout of drawn primitives and processed
609 * vertices is returned.
611 * Exists in Version 1, 2 and 3
614 * Stats: Pointer to a D3DSTATS structure to be filled
618 * DDERR_INVALIDPARAMS if Stats == NULL
620 *****************************************************************************/
621 static HRESULT WINAPI
622 IDirect3DDeviceImpl_3_GetStats(IDirect3DDevice3 *iface,
625 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
626 FIXME("(%p)->(%p): Stub!\n", This, Stats);
629 return DDERR_INVALIDPARAMS;
631 /* Fill the Stats with 0 */
632 Stats->dwTrianglesDrawn = 0;
633 Stats->dwLinesDrawn = 0;
634 Stats->dwPointsDrawn = 0;
635 Stats->dwSpansDrawn = 0;
636 Stats->dwVerticesProcessed = 0;
641 static HRESULT WINAPI
642 Thunk_IDirect3DDeviceImpl_2_GetStats(IDirect3DDevice2 *iface,
645 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
646 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, Stats);
647 return IDirect3DDevice3_GetStats(ICOM_INTERFACE(This, IDirect3DDevice3),
651 static HRESULT WINAPI
652 Thunk_IDirect3DDeviceImpl_1_GetStats(IDirect3DDevice *iface,
655 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
656 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, Stats);
657 return IDirect3DDevice3_GetStats(ICOM_INTERFACE(This, IDirect3DDevice3),
661 /*****************************************************************************
662 * IDirect3DDevice::CreateExecuteBuffer
664 * Creates an IDirect3DExecuteBuffer, used for rendering with a
670 * Desc: Buffer description
671 * ExecuteBuffer: Address to return the Interface pointer at
672 * UnkOuter: Must be NULL. Basically for aggregation, which ddraw doesn't
676 * CLASS_E_NOAGGREGATION if UnkOuter != NULL
677 * DDERR_OUTOFMEMORY if we ran out of memory
680 *****************************************************************************/
681 static HRESULT WINAPI
682 IDirect3DDeviceImpl_1_CreateExecuteBuffer(IDirect3DDevice *iface,
683 D3DEXECUTEBUFFERDESC *Desc,
684 IDirect3DExecuteBuffer **ExecuteBuffer,
687 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
688 IDirect3DExecuteBufferImpl* object;
689 TRACE("(%p)->(%p,%p,%p)!\n", This, Desc, ExecuteBuffer, UnkOuter);
692 return CLASS_E_NOAGGREGATION;
694 /* Allocate the new Execute Buffer */
695 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DExecuteBufferImpl));
698 ERR("Out of memory when allocating a IDirect3DExecuteBufferImpl structure\n");
699 return DDERR_OUTOFMEMORY;
702 ICOM_INIT_INTERFACE(object, IDirect3DExecuteBuffer, IDirect3DExecuteBuffer_Vtbl);
705 object->d3ddev = This;
707 /* Initializes memory */
708 memcpy(&object->desc, Desc, Desc->dwSize);
710 /* No buffer given */
711 if ((object->desc.dwFlags & D3DDEB_LPDATA) == 0)
712 object->desc.lpData = NULL;
714 /* No buffer size given */
715 if ((object->desc.dwFlags & D3DDEB_BUFSIZE) == 0)
716 object->desc.dwBufferSize = 0;
718 /* Create buffer if asked */
719 if ((object->desc.lpData == NULL) && (object->desc.dwBufferSize > 0))
721 object->need_free = TRUE;
722 object->desc.lpData = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,object->desc.dwBufferSize);
723 if(!object->desc.lpData)
725 ERR("Out of memory when allocating the execute buffer data\n");
726 HeapFree(GetProcessHeap(), 0, object);
727 return DDERR_OUTOFMEMORY;
732 object->need_free = FALSE;
735 /* No vertices for the moment */
736 object->vertex_data = NULL;
738 object->desc.dwFlags |= D3DDEB_LPDATA;
740 object->indices = NULL;
741 object->nb_indices = 0;
743 *ExecuteBuffer = ICOM_INTERFACE(object, IDirect3DExecuteBuffer);
745 TRACE(" Returning IDirect3DExecuteBuffer at %p, implementation is at %p\n", *ExecuteBuffer, object);
750 /*****************************************************************************
751 * IDirect3DDevice::Execute
753 * Executes all the stuff in an execute buffer.
756 * ExecuteBuffer: The buffer to execute
757 * Viewport: The viewport used for rendering
761 * DDERR_INVALIDPARAMS if ExecuteBuffer == NULL
764 *****************************************************************************/
765 static HRESULT WINAPI
766 IDirect3DDeviceImpl_1_Execute(IDirect3DDevice *iface,
767 IDirect3DExecuteBuffer *ExecuteBuffer,
768 IDirect3DViewport *Viewport,
771 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
772 IDirect3DExecuteBufferImpl *Direct3DExecuteBufferImpl = ICOM_OBJECT(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, ExecuteBuffer);
773 IDirect3DViewportImpl *Direct3DViewportImpl = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport);
775 TRACE("(%p)->(%p,%p,%08x)\n", This, Direct3DExecuteBufferImpl, Direct3DViewportImpl, Flags);
777 if(!Direct3DExecuteBufferImpl)
778 return DDERR_INVALIDPARAMS;
781 EnterCriticalSection(&ddraw_cs);
782 IDirect3DExecuteBufferImpl_Execute(Direct3DExecuteBufferImpl, This, Direct3DViewportImpl);
783 LeaveCriticalSection(&ddraw_cs);
788 /*****************************************************************************
789 * IDirect3DDevice3::AddViewport
791 * Add a Direct3DViewport to the device's viewport list. These viewports
792 * are wrapped to IDirect3DDevice7 viewports in viewport.c
794 * Exists in Version 1, 2 and 3. Note that IDirect3DViewport 1, 2 and 3
795 * are the same interfaces.
798 * Viewport: The viewport to add
801 * DDERR_INVALIDPARAMS if Viewport == NULL
804 *****************************************************************************/
805 static HRESULT WINAPI
806 IDirect3DDeviceImpl_3_AddViewport(IDirect3DDevice3 *iface,
807 IDirect3DViewport3 *Viewport)
809 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
810 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport);
812 TRACE("(%p)->(%p)\n", This, vp);
816 return DDERR_INVALIDPARAMS;
818 EnterCriticalSection(&ddraw_cs);
819 vp->next = This->viewport_list;
820 This->viewport_list = vp;
821 LeaveCriticalSection(&ddraw_cs);
826 static HRESULT WINAPI
827 Thunk_IDirect3DDeviceImpl_2_AddViewport(IDirect3DDevice2 *iface,
828 IDirect3DViewport2 *Direct3DViewport2)
830 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
831 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport2);
832 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
833 return IDirect3DDevice3_AddViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
834 ICOM_INTERFACE(vp, IDirect3DViewport3));
837 static HRESULT WINAPI
838 Thunk_IDirect3DDeviceImpl_1_AddViewport(IDirect3DDevice *iface,
839 IDirect3DViewport *Direct3DViewport)
841 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
842 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport);
843 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
844 return IDirect3DDevice3_AddViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
845 ICOM_INTERFACE(vp, IDirect3DViewport3));
848 /*****************************************************************************
849 * IDirect3DDevice3::DeleteViewport
851 * Deletes a Direct3DViewport from the device's viewport list.
853 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
857 * Viewport: The viewport to delete
861 * DDERR_INVALIDPARAMS if the viewport wasn't found in the list
863 *****************************************************************************/
864 static HRESULT WINAPI
865 IDirect3DDeviceImpl_3_DeleteViewport(IDirect3DDevice3 *iface,
866 IDirect3DViewport3 *Viewport)
868 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
869 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *) Viewport;
870 IDirect3DViewportImpl *cur_viewport, *prev_viewport = NULL;
872 TRACE("(%p)->(%p)\n", This, vp);
874 EnterCriticalSection(&ddraw_cs);
875 cur_viewport = This->viewport_list;
876 while (cur_viewport != NULL)
878 if (cur_viewport == vp)
880 if (prev_viewport == NULL) This->viewport_list = cur_viewport->next;
881 else prev_viewport->next = cur_viewport->next;
882 /* TODO : add desactivate of the viewport and all associated lights... */
883 LeaveCriticalSection(&ddraw_cs);
886 prev_viewport = cur_viewport;
887 cur_viewport = cur_viewport->next;
890 LeaveCriticalSection(&ddraw_cs);
891 return DDERR_INVALIDPARAMS;
894 static HRESULT WINAPI
895 Thunk_IDirect3DDeviceImpl_2_DeleteViewport(IDirect3DDevice2 *iface,
896 IDirect3DViewport2 *Direct3DViewport2)
898 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
899 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport2);
900 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
901 return IDirect3DDevice3_DeleteViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
902 ICOM_INTERFACE(vp, IDirect3DViewport3));
905 static HRESULT WINAPI
906 Thunk_IDirect3DDeviceImpl_1_DeleteViewport(IDirect3DDevice *iface,
907 IDirect3DViewport *Direct3DViewport)
909 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
910 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport);
911 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
912 return IDirect3DDevice3_DeleteViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
913 ICOM_INTERFACE(vp, IDirect3DViewport3));
916 /*****************************************************************************
917 * IDirect3DDevice3::NextViewport
919 * Returns a viewport from the viewport list, depending on the
920 * passed viewport and the flags.
922 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
926 * Viewport: Viewport to use for beginning the search
927 * Flags: D3DNEXT_NEXT, D3DNEXT_HEAD or D3DNEXT_TAIL
931 * DDERR_INVALIDPARAMS if the flags were wrong, or Viewport was NULL
933 *****************************************************************************/
934 static HRESULT WINAPI
935 IDirect3DDeviceImpl_3_NextViewport(IDirect3DDevice3 *iface,
936 IDirect3DViewport3 *Viewport3,
937 IDirect3DViewport3 **lplpDirect3DViewport3,
940 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
941 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport3);
942 IDirect3DViewportImpl *res = NULL;
944 TRACE("(%p)->(%p,%p,%08x)\n", This, vp, lplpDirect3DViewport3, Flags);
948 *lplpDirect3DViewport3 = NULL;
949 return DDERR_INVALIDPARAMS;
953 EnterCriticalSection(&ddraw_cs);
963 res = This->viewport_list;
968 IDirect3DViewportImpl *cur_viewport = This->viewport_list;
969 if (cur_viewport != NULL)
971 while (cur_viewport->next != NULL) cur_viewport = cur_viewport->next;
977 *lplpDirect3DViewport3 = NULL;
978 LeaveCriticalSection(&ddraw_cs);
979 return DDERR_INVALIDPARAMS;
982 *lplpDirect3DViewport3 = ICOM_INTERFACE(res, IDirect3DViewport3);
983 LeaveCriticalSection(&ddraw_cs);
987 static HRESULT WINAPI
988 Thunk_IDirect3DDeviceImpl_2_NextViewport(IDirect3DDevice2 *iface,
989 IDirect3DViewport2 *Viewport2,
990 IDirect3DViewport2 **lplpDirect3DViewport2,
993 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
994 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport2);
995 IDirect3DViewport3 *res;
997 TRACE_(ddraw_thunk)("(%p)->(%p,%p,%08x) thunking to IDirect3DDevice3 interface.\n", This, vp, lplpDirect3DViewport2, Flags);
998 hr = IDirect3DDevice3_NextViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
999 ICOM_INTERFACE(vp, IDirect3DViewport3),
1002 *lplpDirect3DViewport2 = (IDirect3DViewport2 *) COM_INTERFACE_CAST(IDirect3DViewportImpl, IDirect3DViewport3, IDirect3DViewport3, res);
1006 static HRESULT WINAPI
1007 Thunk_IDirect3DDeviceImpl_1_NextViewport(IDirect3DDevice *iface,
1008 IDirect3DViewport *Viewport,
1009 IDirect3DViewport **lplpDirect3DViewport,
1012 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1013 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport);
1014 IDirect3DViewport3 *res;
1016 TRACE_(ddraw_thunk)("(%p)->(%p,%p,%08x) thunking to IDirect3DDevice3 interface.\n", This, vp, lplpDirect3DViewport, Flags);
1017 hr = IDirect3DDevice3_NextViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
1018 ICOM_INTERFACE(vp, IDirect3DViewport3),
1021 *lplpDirect3DViewport = (IDirect3DViewport *) COM_INTERFACE_CAST(IDirect3DViewportImpl, IDirect3DViewport3, IDirect3DViewport3, res);
1025 /*****************************************************************************
1026 * IDirect3DDevice::Pick
1028 * Executes an execute buffer without performing rendering. Instead, a
1029 * list of primitives that intersect with (x1,y1) of the passed rectangle
1030 * is created. IDirect3DDevice::GetPickRecords can be used to retrieve
1036 * ExecuteBuffer: Buffer to execute
1037 * Viewport: Viewport to use for execution
1038 * Flags: None are defined, according to the SDK
1039 * Rect: Specifies the coordinates to be picked. Only x1 and y2 are used,
1040 * x2 and y2 are ignored.
1043 * D3D_OK because it's a stub
1045 *****************************************************************************/
1046 static HRESULT WINAPI
1047 IDirect3DDeviceImpl_1_Pick(IDirect3DDevice *iface,
1048 IDirect3DExecuteBuffer *ExecuteBuffer,
1049 IDirect3DViewport *Viewport,
1053 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1054 IDirect3DExecuteBufferImpl *execbuf = ICOM_OBJECT(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, ExecuteBuffer);
1055 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport);
1056 FIXME("(%p)->(%p,%p,%08x,%p): stub!\n", This, execbuf, vp, Flags, Rect);
1061 /*****************************************************************************
1062 * IDirect3DDevice::GetPickRecords
1064 * Retrieves the pick records generated by IDirect3DDevice::GetPickRecords
1069 * Count: Pointer to a DWORD containing the numbers of pick records to
1071 * D3DPickRec: Address to store the resulting D3DPICKRECORD arry.
1074 * D3D_OK, because it's a stub
1076 *****************************************************************************/
1077 static HRESULT WINAPI
1078 IDirect3DDeviceImpl_1_GetPickRecords(IDirect3DDevice *iface,
1080 D3DPICKRECORD *D3DPickRec)
1082 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1083 FIXME("(%p)->(%p,%p): stub!\n", This, Count, D3DPickRec);
1088 /*****************************************************************************
1089 * IDirect3DDevice7::EnumTextureformats
1091 * Enumerates the supported texture formats. It has a list of all possible
1092 * formats and calls IWineD3D::CheckDeviceFormat for each format to see if
1093 * WineD3D supports it. If so, then it is passed to the app.
1095 * This is for Version 7 and 3, older versions have a different
1096 * callback function and their own implementation
1099 * Callback: Callback to call for each enumerated format
1100 * Arg: Argument to pass to the callback
1104 * DDERR_INVALIDPARAMS if Callback == NULL
1106 *****************************************************************************/
1107 static HRESULT WINAPI
1108 IDirect3DDeviceImpl_7_EnumTextureFormats(IDirect3DDevice7 *iface,
1109 LPD3DENUMPIXELFORMATSCALLBACK Callback,
1112 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1116 WINED3DFORMAT FormatList[] = {
1118 WINED3DFMT_A8R8G8B8,
1119 WINED3DFMT_X8R8G8B8,
1123 WINED3DFMT_A1R5G5B5,
1124 WINED3DFMT_A4R4G4B4,
1126 WINED3DFMT_X1R5G5B5,
1136 WINED3DFORMAT BumpFormatList[] = {
1139 WINED3DFMT_X8L8V8U8,
1140 WINED3DFMT_Q8W8V8U8,
1142 WINED3DFMT_W11V11U10,
1143 WINED3DFMT_A2W10V10U10
1146 TRACE("(%p)->(%p,%p): Relay\n", This, Callback, Arg);
1149 return DDERR_INVALIDPARAMS;
1151 EnterCriticalSection(&ddraw_cs);
1152 for(i = 0; i < sizeof(FormatList) / sizeof(WINED3DFORMAT); i++)
1154 hr = IWineD3D_CheckDeviceFormat(This->ddraw->wineD3D,
1157 0 /* AdapterFormat */,
1159 0 /* ResourceType */,
1163 DDPIXELFORMAT pformat;
1165 memset(&pformat, 0, sizeof(pformat));
1166 pformat.dwSize = sizeof(pformat);
1167 PixelFormat_WineD3DtoDD(&pformat, FormatList[i]);
1169 TRACE("Enumerating WineD3DFormat %d\n", FormatList[i]);
1170 hr = Callback(&pformat, Arg);
1171 if(hr != DDENUMRET_OK)
1173 TRACE("Format enumeration cancelled by application\n");
1174 LeaveCriticalSection(&ddraw_cs);
1180 for(i = 0; i < sizeof(BumpFormatList) / sizeof(WINED3DFORMAT); i++)
1182 hr = IWineD3D_CheckDeviceFormat(This->ddraw->wineD3D,
1185 0 /* AdapterFormat */,
1186 WINED3DUSAGE_QUERY_LEGACYBUMPMAP,
1187 0 /* ResourceType */,
1191 DDPIXELFORMAT pformat;
1193 memset(&pformat, 0, sizeof(pformat));
1194 pformat.dwSize = sizeof(pformat);
1195 PixelFormat_WineD3DtoDD(&pformat, BumpFormatList[i]);
1197 TRACE("Enumerating WineD3DFormat %d\n", BumpFormatList[i]);
1198 hr = Callback(&pformat, Arg);
1199 if(hr != DDENUMRET_OK)
1201 TRACE("Format enumeration cancelled by application\n");
1202 LeaveCriticalSection(&ddraw_cs);
1207 TRACE("End of enumeration\n");
1208 LeaveCriticalSection(&ddraw_cs);
1212 static HRESULT WINAPI
1213 Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats(IDirect3DDevice3 *iface,
1214 LPD3DENUMPIXELFORMATSCALLBACK Callback,
1217 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1218 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice7 interface.\n", This, Callback, Arg);
1219 return IDirect3DDevice7_EnumTextureFormats(ICOM_INTERFACE(This, IDirect3DDevice7),
1224 /*****************************************************************************
1225 * IDirect3DDevice2::EnumTextureformats
1227 * EnumTextureFormats for Version 1 and 2, see
1228 * IDirect3DDevice7::EnumTexureFormats for a more detailed description.
1230 * This version has a different callback and does not enumerate FourCC
1233 *****************************************************************************/
1234 static HRESULT WINAPI
1235 IDirect3DDeviceImpl_2_EnumTextureFormats(IDirect3DDevice2 *iface,
1236 LPD3DENUMTEXTUREFORMATSCALLBACK Callback,
1239 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1243 WINED3DFORMAT FormatList[] = {
1245 WINED3DFMT_A8R8G8B8,
1246 WINED3DFMT_X8R8G8B8,
1250 WINED3DFMT_A1R5G5B5,
1251 WINED3DFMT_A4R4G4B4,
1253 WINED3DFMT_X1R5G5B5,
1257 /* FOURCC codes - Not in this version*/
1260 TRACE("(%p)->(%p,%p): Relay\n", This, Callback, Arg);
1263 return DDERR_INVALIDPARAMS;
1265 EnterCriticalSection(&ddraw_cs);
1266 for(i = 0; i < sizeof(FormatList) / sizeof(WINED3DFORMAT); i++)
1268 hr = IWineD3D_CheckDeviceFormat(This->ddraw->wineD3D,
1271 0 /* AdapterFormat */,
1273 0 /* ResourceType */,
1277 DDSURFACEDESC sdesc;
1279 memset(&sdesc, 0, sizeof(sdesc));
1280 sdesc.dwSize = sizeof(sdesc);
1281 sdesc.dwFlags = DDSD_PIXELFORMAT | DDSD_CAPS;
1282 sdesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1283 sdesc.ddpfPixelFormat.dwSize = sizeof(sdesc.ddpfPixelFormat);
1284 PixelFormat_WineD3DtoDD(&sdesc.ddpfPixelFormat, FormatList[i]);
1286 TRACE("Enumerating WineD3DFormat %d\n", FormatList[i]);
1287 hr = Callback(&sdesc, Arg);
1288 if(hr != DDENUMRET_OK)
1290 TRACE("Format enumeration cancelled by application\n");
1291 LeaveCriticalSection(&ddraw_cs);
1296 TRACE("End of enumeration\n");
1297 LeaveCriticalSection(&ddraw_cs);
1301 static HRESULT WINAPI
1302 Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats(IDirect3DDevice *iface,
1303 LPD3DENUMTEXTUREFORMATSCALLBACK Callback,
1306 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1307 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice2 interface.\n", This, Callback, Arg);
1308 return IDirect3DDevice2_EnumTextureFormats(ICOM_INTERFACE(This, IDirect3DDevice2),
1313 /*****************************************************************************
1314 * IDirect3DDevice::CreateMatrix
1316 * Creates a matrix handle. A handle is created and memory for a D3DMATRIX is
1317 * allocated for the handle.
1322 * D3DMatHandle: Address to return the handle at
1326 * DDERR_INVALIDPARAMS if D3DMatHandle = NULL
1328 *****************************************************************************/
1329 static HRESULT WINAPI
1330 IDirect3DDeviceImpl_1_CreateMatrix(IDirect3DDevice *iface, D3DMATRIXHANDLE *D3DMatHandle)
1332 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1334 TRACE("(%p)->(%p)\n", This, D3DMatHandle);
1337 return DDERR_INVALIDPARAMS;
1339 Matrix = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(D3DMATRIX));
1342 ERR("Out of memory when allocating a D3DMATRIX\n");
1343 return DDERR_OUTOFMEMORY;
1346 EnterCriticalSection(&ddraw_cs);
1347 *D3DMatHandle = IDirect3DDeviceImpl_CreateHandle(This);
1348 if(!(*D3DMatHandle))
1350 ERR("Failed to create a matrix handle\n");
1351 HeapFree(GetProcessHeap(), 0, Matrix);
1352 LeaveCriticalSection(&ddraw_cs);
1353 return DDERR_OUTOFMEMORY;
1355 This->Handles[(DWORD) *D3DMatHandle - 1].ptr = Matrix;
1356 This->Handles[(DWORD) *D3DMatHandle - 1].type = DDrawHandle_Matrix;
1357 TRACE(" returning matrix handle %d\n", *D3DMatHandle);
1359 LeaveCriticalSection(&ddraw_cs);
1363 /*****************************************************************************
1364 * IDirect3DDevice::SetMatrix
1366 * Sets a matrix for a matrix handle. The matrix is copied into the memory
1367 * allocated for the handle
1372 * D3DMatHandle: Handle to set the matrix to
1373 * D3DMatrix: Matrix to set
1377 * DDERR_INVALIDPARAMS if the handle of the matrix is invalid or the matrix
1380 *****************************************************************************/
1381 static HRESULT WINAPI
1382 IDirect3DDeviceImpl_1_SetMatrix(IDirect3DDevice *iface,
1383 D3DMATRIXHANDLE D3DMatHandle,
1384 D3DMATRIX *D3DMatrix)
1386 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1387 TRACE("(%p)->(%08x,%p)\n", This, (DWORD) D3DMatHandle, D3DMatrix);
1389 if( (!D3DMatHandle) || (!D3DMatrix) )
1390 return DDERR_INVALIDPARAMS;
1392 EnterCriticalSection(&ddraw_cs);
1393 if(D3DMatHandle > This->numHandles)
1395 ERR("Handle %d out of range\n", D3DMatHandle);
1396 LeaveCriticalSection(&ddraw_cs);
1397 return DDERR_INVALIDPARAMS;
1399 else if(This->Handles[D3DMatHandle - 1].type != DDrawHandle_Matrix)
1401 ERR("Handle %d is not a matrix handle\n", D3DMatHandle);
1402 LeaveCriticalSection(&ddraw_cs);
1403 return DDERR_INVALIDPARAMS;
1407 dump_D3DMATRIX(D3DMatrix);
1409 *((D3DMATRIX *) This->Handles[D3DMatHandle - 1].ptr) = *D3DMatrix;
1411 LeaveCriticalSection(&ddraw_cs);
1415 /*****************************************************************************
1416 * IDirect3DDevice::SetMatrix
1418 * Returns the content of a D3DMATRIX handle
1423 * D3DMatHandle: Matrix handle to read the content from
1424 * D3DMatrix: Address to store the content at
1428 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid or D3DMatrix is NULL
1430 *****************************************************************************/
1431 static HRESULT WINAPI
1432 IDirect3DDeviceImpl_1_GetMatrix(IDirect3DDevice *iface,
1433 D3DMATRIXHANDLE D3DMatHandle,
1434 D3DMATRIX *D3DMatrix)
1436 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1437 TRACE("(%p)->(%08x,%p)\n", This, (DWORD) D3DMatHandle, D3DMatrix);
1440 return DDERR_INVALIDPARAMS;
1442 return DDERR_INVALIDPARAMS;
1444 EnterCriticalSection(&ddraw_cs);
1445 if(D3DMatHandle > This->numHandles)
1447 ERR("Handle %d out of range\n", D3DMatHandle);
1448 LeaveCriticalSection(&ddraw_cs);
1449 return DDERR_INVALIDPARAMS;
1451 else if(This->Handles[D3DMatHandle - 1].type != DDrawHandle_Matrix)
1453 ERR("Handle %d is not a matrix handle\n", D3DMatHandle);
1454 LeaveCriticalSection(&ddraw_cs);
1455 return DDERR_INVALIDPARAMS;
1458 /* The handle is simply a pointer to a D3DMATRIX structure */
1459 *D3DMatrix = *((D3DMATRIX *) This->Handles[D3DMatHandle - 1].ptr);
1461 LeaveCriticalSection(&ddraw_cs);
1465 /*****************************************************************************
1466 * IDirect3DDevice::DeleteMatrix
1468 * Destroys a Matrix handle. Frees the memory and unsets the handle data
1473 * D3DMatHandle: Handle to destroy
1477 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid
1479 *****************************************************************************/
1480 static HRESULT WINAPI
1481 IDirect3DDeviceImpl_1_DeleteMatrix(IDirect3DDevice *iface,
1482 D3DMATRIXHANDLE D3DMatHandle)
1484 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1485 TRACE("(%p)->(%08x)\n", This, (DWORD) D3DMatHandle);
1488 return DDERR_INVALIDPARAMS;
1490 EnterCriticalSection(&ddraw_cs);
1491 if(D3DMatHandle > This->numHandles)
1493 ERR("Handle %d out of range\n", D3DMatHandle);
1494 LeaveCriticalSection(&ddraw_cs);
1495 return DDERR_INVALIDPARAMS;
1497 else if(This->Handles[D3DMatHandle - 1].type != DDrawHandle_Matrix)
1499 ERR("Handle %d is not a matrix handle\n", D3DMatHandle);
1500 LeaveCriticalSection(&ddraw_cs);
1501 return DDERR_INVALIDPARAMS;
1504 HeapFree(GetProcessHeap(), 0, This->Handles[D3DMatHandle - 1].ptr);
1505 This->Handles[D3DMatHandle - 1].ptr = NULL;
1506 This->Handles[D3DMatHandle - 1].type = DDrawHandle_Unknown;
1508 LeaveCriticalSection(&ddraw_cs);
1512 /*****************************************************************************
1513 * IDirect3DDevice7::BeginScene
1515 * This method must be called before any rendering is performed.
1516 * IDirect3DDevice::EndScene has to be called after the scene is complete
1518 * Version 1, 2, 3 and 7
1521 * D3D_OK on success, for details see IWineD3DDevice::BeginScene
1522 * D3DERR_SCENE_IN_SCENE if WineD3D returns an error(Only in case of an already
1525 *****************************************************************************/
1526 static HRESULT WINAPI
1527 IDirect3DDeviceImpl_7_BeginScene(IDirect3DDevice7 *iface)
1529 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1531 TRACE("(%p): Relay\n", This);
1533 EnterCriticalSection(&ddraw_cs);
1534 hr = IWineD3DDevice_BeginScene(This->wineD3DDevice);
1535 LeaveCriticalSection(&ddraw_cs);
1536 if(hr == WINED3D_OK) return D3D_OK;
1537 else return D3DERR_SCENE_IN_SCENE; /* TODO: Other possible causes of failure */
1540 static HRESULT WINAPI
1541 Thunk_IDirect3DDeviceImpl_3_BeginScene(IDirect3DDevice3 *iface)
1543 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1544 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1545 return IDirect3DDevice7_BeginScene(ICOM_INTERFACE(This, IDirect3DDevice7));
1548 static HRESULT WINAPI
1549 Thunk_IDirect3DDeviceImpl_2_BeginScene(IDirect3DDevice2 *iface)
1551 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1552 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1553 return IDirect3DDevice7_BeginScene(ICOM_INTERFACE(This, IDirect3DDevice7));
1556 static HRESULT WINAPI
1557 Thunk_IDirect3DDeviceImpl_1_BeginScene(IDirect3DDevice *iface)
1559 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1560 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1561 return IDirect3DDevice7_BeginScene(ICOM_INTERFACE(This, IDirect3DDevice7));
1564 /*****************************************************************************
1565 * IDirect3DDevice7::EndScene
1567 * Ends a scene that has been begun with IDirect3DDevice7::BeginScene.
1568 * This method must be called after rendering is finished.
1570 * Version 1, 2, 3 and 7
1573 * D3D_OK on success, for details see IWineD3DDevice::EndScene
1574 * D3DERR_SCENE_NOT_IN_SCENE is returned if WineD3D returns an error. It does
1575 * that only if the scene was already ended.
1577 *****************************************************************************/
1578 static HRESULT WINAPI
1579 IDirect3DDeviceImpl_7_EndScene(IDirect3DDevice7 *iface)
1581 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1583 TRACE("(%p): Relay\n", This);
1585 EnterCriticalSection(&ddraw_cs);
1586 hr = IWineD3DDevice_EndScene(This->wineD3DDevice);
1587 LeaveCriticalSection(&ddraw_cs);
1588 if(hr == WINED3D_OK) return D3D_OK;
1589 else return D3DERR_SCENE_NOT_IN_SCENE;
1592 static HRESULT WINAPI
1593 Thunk_IDirect3DDeviceImpl_3_EndScene(IDirect3DDevice3 *iface)
1595 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1596 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1597 return IDirect3DDevice7_EndScene(ICOM_INTERFACE(This, IDirect3DDevice7));
1600 static HRESULT WINAPI
1601 Thunk_IDirect3DDeviceImpl_2_EndScene(IDirect3DDevice2 *iface)
1603 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1604 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1605 return IDirect3DDevice7_EndScene(ICOM_INTERFACE(This, IDirect3DDevice7));
1608 static HRESULT WINAPI
1609 Thunk_IDirect3DDeviceImpl_1_EndScene(IDirect3DDevice *iface)
1611 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1612 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1613 return IDirect3DDevice7_EndScene(ICOM_INTERFACE(This, IDirect3DDevice7));
1616 /*****************************************************************************
1617 * IDirect3DDevice7::GetDirect3D
1619 * Returns the IDirect3D(= interface to the DirectDraw object) used to create
1623 * Direct3D7: Address to store the interface pointer at
1627 * DDERR_INVALIDPARAMS if Direct3D7 == NULL
1629 *****************************************************************************/
1630 static HRESULT WINAPI
1631 IDirect3DDeviceImpl_7_GetDirect3D(IDirect3DDevice7 *iface,
1632 IDirect3D7 **Direct3D7)
1634 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1635 TRACE("(%p)->(%p)\n", This, Direct3D7);
1638 return DDERR_INVALIDPARAMS;
1640 *Direct3D7 = ICOM_INTERFACE(This->ddraw, IDirect3D7);
1641 IDirect3D7_AddRef(*Direct3D7);
1643 TRACE(" returning interface %p\n", *Direct3D7);
1647 static HRESULT WINAPI
1648 Thunk_IDirect3DDeviceImpl_3_GetDirect3D(IDirect3DDevice3 *iface,
1649 IDirect3D3 **Direct3D3)
1651 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1653 IDirect3D7 *ret_ptr;
1655 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Direct3D3);
1656 ret = IDirect3DDevice7_GetDirect3D(ICOM_INTERFACE(This, IDirect3DDevice7),
1660 *Direct3D3 = COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D7, IDirect3D3, ret_ptr);
1661 TRACE(" returning interface %p\n", *Direct3D3);
1665 static HRESULT WINAPI
1666 Thunk_IDirect3DDeviceImpl_2_GetDirect3D(IDirect3DDevice2 *iface,
1667 IDirect3D2 **Direct3D2)
1669 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1671 IDirect3D7 *ret_ptr;
1673 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Direct3D2);
1674 ret = IDirect3DDevice7_GetDirect3D(ICOM_INTERFACE(This, IDirect3DDevice7),
1678 *Direct3D2 = COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D7, IDirect3D2, ret_ptr);
1679 TRACE(" returning interface %p\n", *Direct3D2);
1683 static HRESULT WINAPI
1684 Thunk_IDirect3DDeviceImpl_1_GetDirect3D(IDirect3DDevice *iface,
1685 IDirect3D **Direct3D)
1687 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1689 IDirect3D7 *ret_ptr;
1691 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Direct3D);
1692 ret = IDirect3DDevice7_GetDirect3D(ICOM_INTERFACE(This, IDirect3DDevice7),
1696 *Direct3D = COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D7, IDirect3D, ret_ptr);
1697 TRACE(" returning interface %p\n", *Direct3D);
1701 /*****************************************************************************
1702 * IDirect3DDevice3::SetCurrentViewport
1704 * Sets a Direct3DViewport as the current viewport.
1705 * For the thunks note that all viewport interface versions are equal
1708 * Direct3DViewport3: The viewport to set
1714 * (Is a NULL viewport valid?)
1716 *****************************************************************************/
1717 static HRESULT WINAPI
1718 IDirect3DDeviceImpl_3_SetCurrentViewport(IDirect3DDevice3 *iface,
1719 IDirect3DViewport3 *Direct3DViewport3)
1721 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1722 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport3);
1723 TRACE("(%p)->(%p)\n", This, Direct3DViewport3);
1725 EnterCriticalSection(&ddraw_cs);
1726 /* Do nothing if the specified viewport is the same as the current one */
1727 if (This->current_viewport == vp )
1729 LeaveCriticalSection(&ddraw_cs);
1733 /* Should check if the viewport was added or not */
1735 /* Release previous viewport and AddRef the new one */
1736 if (This->current_viewport)
1738 TRACE("ViewportImpl is at %p, interface is at %p\n", This->current_viewport, ICOM_INTERFACE(This->current_viewport, IDirect3DViewport3));
1739 IDirect3DViewport3_Release( ICOM_INTERFACE(This->current_viewport, IDirect3DViewport3) );
1741 IDirect3DViewport3_AddRef(Direct3DViewport3);
1743 /* Set this viewport as the current viewport */
1744 This->current_viewport = vp;
1746 /* Activate this viewport */
1747 This->current_viewport->active_device = This;
1748 This->current_viewport->activate(This->current_viewport);
1750 LeaveCriticalSection(&ddraw_cs);
1754 static HRESULT WINAPI
1755 Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport(IDirect3DDevice2 *iface,
1756 IDirect3DViewport2 *Direct3DViewport2)
1758 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1759 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport2);
1760 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
1761 return IDirect3DDevice3_SetCurrentViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
1762 ICOM_INTERFACE(vp, IDirect3DViewport3));
1765 /*****************************************************************************
1766 * IDirect3DDevice3::GetCurrentViewport
1768 * Returns the currently active viewport.
1773 * Direct3DViewport3: Address to return the interface pointer at
1777 * DDERR_INVALIDPARAMS if Direct3DViewport == NULL
1779 *****************************************************************************/
1780 static HRESULT WINAPI
1781 IDirect3DDeviceImpl_3_GetCurrentViewport(IDirect3DDevice3 *iface,
1782 IDirect3DViewport3 **Direct3DViewport3)
1784 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1785 TRACE("(%p)->(%p)\n", This, Direct3DViewport3);
1787 if(!Direct3DViewport3)
1788 return DDERR_INVALIDPARAMS;
1790 EnterCriticalSection(&ddraw_cs);
1791 *Direct3DViewport3 = ICOM_INTERFACE(This->current_viewport, IDirect3DViewport3);
1793 /* AddRef the returned viewport */
1794 if(*Direct3DViewport3) IDirect3DViewport3_AddRef(*Direct3DViewport3);
1796 TRACE(" returning interface %p\n", *Direct3DViewport3);
1798 LeaveCriticalSection(&ddraw_cs);
1802 static HRESULT WINAPI
1803 Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport(IDirect3DDevice2 *iface,
1804 IDirect3DViewport2 **Direct3DViewport2)
1806 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1808 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, Direct3DViewport2);
1809 hr = IDirect3DDevice3_GetCurrentViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
1810 (IDirect3DViewport3 **) Direct3DViewport2);
1811 if(hr != D3D_OK) return hr;
1812 *Direct3DViewport2 = (IDirect3DViewport2 *) COM_INTERFACE_CAST(IDirect3DViewportImpl, IDirect3DViewport3, IDirect3DViewport3, *Direct3DViewport2);
1816 /*****************************************************************************
1817 * IDirect3DDevice7::SetRenderTarget
1819 * Sets the render target for the Direct3DDevice.
1820 * For the thunks note that IDirectDrawSurface7 == IDirectDrawSurface4 and
1821 * IDirectDrawSurface3 == IDirectDrawSurface
1823 * Version 2, 3 and 7
1826 * NewTarget: Pointer to an IDirectDrawSurface7 interface to set as the new
1831 * D3D_OK on success, for details see IWineD3DDevice::SetRenderTarget
1833 *****************************************************************************/
1834 static HRESULT WINAPI
1835 IDirect3DDeviceImpl_7_SetRenderTarget(IDirect3DDevice7 *iface,
1836 IDirectDrawSurface7 *NewTarget,
1839 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1840 IDirectDrawSurfaceImpl *Target = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, NewTarget);
1842 TRACE("(%p)->(%p,%08x): Relay\n", This, NewTarget, Flags);
1844 EnterCriticalSection(&ddraw_cs);
1845 /* Flags: Not used */
1847 hr = IWineD3DDevice_SetRenderTarget(This->wineD3DDevice,
1849 Target ? Target->WineD3DSurface : NULL);
1852 LeaveCriticalSection(&ddraw_cs);
1855 IDirectDrawSurface7_AddRef(NewTarget);
1856 IDirectDrawSurface7_Release(ICOM_INTERFACE(This->target, IDirectDrawSurface7));
1857 This->target = Target;
1858 IDirect3DDeviceImpl_UpdateDepthStencil(This);
1859 LeaveCriticalSection(&ddraw_cs);
1863 static HRESULT WINAPI
1864 Thunk_IDirect3DDeviceImpl_3_SetRenderTarget(IDirect3DDevice3 *iface,
1865 IDirectDrawSurface4 *NewRenderTarget,
1868 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1869 IDirectDrawSurfaceImpl *Target = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, NewRenderTarget);
1870 TRACE_(ddraw_thunk)("(%p)->(%p,%08x) thunking to IDirect3DDevice7 interface.\n", This, Target, Flags);
1871 return IDirect3DDevice7_SetRenderTarget(ICOM_INTERFACE(This, IDirect3DDevice7),
1872 ICOM_INTERFACE(Target, IDirectDrawSurface7),
1876 static HRESULT WINAPI
1877 Thunk_IDirect3DDeviceImpl_2_SetRenderTarget(IDirect3DDevice2 *iface,
1878 IDirectDrawSurface *NewRenderTarget,
1881 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1882 IDirectDrawSurfaceImpl *Target = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface3, NewRenderTarget);
1883 TRACE_(ddraw_thunk)("(%p)->(%p,%08x) thunking to IDirect3DDevice7 interface.\n", This, Target, Flags);
1884 return IDirect3DDevice7_SetRenderTarget(ICOM_INTERFACE(This, IDirect3DDevice7),
1885 ICOM_INTERFACE(Target, IDirectDrawSurface7),
1889 /*****************************************************************************
1890 * IDirect3DDevice7::GetRenderTarget
1892 * Returns the current render target.
1893 * This is handled locally, because the WineD3D render target's parent
1896 * Version 2, 3 and 7
1899 * RenderTarget: Address to store the surface interface pointer
1903 * DDERR_INVALIDPARAMS if RenderTarget == NULL
1905 *****************************************************************************/
1906 static HRESULT WINAPI
1907 IDirect3DDeviceImpl_7_GetRenderTarget(IDirect3DDevice7 *iface,
1908 IDirectDrawSurface7 **RenderTarget)
1910 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1911 TRACE("(%p)->(%p): Relay\n", This, RenderTarget);
1914 return DDERR_INVALIDPARAMS;
1916 EnterCriticalSection(&ddraw_cs);
1917 *RenderTarget = ICOM_INTERFACE(This->target, IDirectDrawSurface7);
1918 IDirectDrawSurface7_AddRef(*RenderTarget);
1920 LeaveCriticalSection(&ddraw_cs);
1924 static HRESULT WINAPI
1925 Thunk_IDirect3DDeviceImpl_3_GetRenderTarget(IDirect3DDevice3 *iface,
1926 IDirectDrawSurface4 **RenderTarget)
1928 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1930 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, RenderTarget);
1931 hr = IDirect3DDevice7_GetRenderTarget(ICOM_INTERFACE(This, IDirect3DDevice7),
1932 (IDirectDrawSurface7 **) RenderTarget);
1933 if(hr != D3D_OK) return hr;
1934 *RenderTarget = (IDirectDrawSurface4 *) COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7, IDirectDrawSurface7, *RenderTarget);
1938 static HRESULT WINAPI
1939 Thunk_IDirect3DDeviceImpl_2_GetRenderTarget(IDirect3DDevice2 *iface,
1940 IDirectDrawSurface **RenderTarget)
1942 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1944 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, RenderTarget);
1945 hr = IDirect3DDevice7_GetRenderTarget(ICOM_INTERFACE(This, IDirect3DDevice7),
1946 (IDirectDrawSurface7 **) RenderTarget);
1947 if(hr != D3D_OK) return hr;
1948 *RenderTarget = (IDirectDrawSurface *) COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7, IDirectDrawSurface3, *RenderTarget);
1952 /*****************************************************************************
1953 * IDirect3DDevice3::Begin
1955 * Begins a description block of vertices. This is similar to glBegin()
1956 * and glEnd(). After a call to IDirect3DDevice3::End, the vertices
1957 * described with IDirect3DDevice::Vertex are drawn.
1962 * PrimitiveType: The type of primitives to draw
1963 * VertexTypeDesc: A flexible vertex format description of the vertices
1964 * Flags: Some flags..
1969 *****************************************************************************/
1970 static HRESULT WINAPI
1971 IDirect3DDeviceImpl_3_Begin(IDirect3DDevice3 *iface,
1972 D3DPRIMITIVETYPE PrimitiveType,
1973 DWORD VertexTypeDesc,
1976 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1977 TRACE("(%p)->(%d,%d,%08x)\n", This, PrimitiveType, VertexTypeDesc, Flags);
1979 EnterCriticalSection(&ddraw_cs);
1980 This->primitive_type = PrimitiveType;
1981 This->vertex_type = VertexTypeDesc;
1982 This->render_flags = Flags;
1983 This->vertex_size = get_flexible_vertex_size(This->vertex_type);
1984 This->nb_vertices = 0;
1985 LeaveCriticalSection(&ddraw_cs);
1990 static HRESULT WINAPI
1991 Thunk_IDirect3DDeviceImpl_2_Begin(IDirect3DDevice2 *iface,
1992 D3DPRIMITIVETYPE d3dpt,
1993 D3DVERTEXTYPE dwVertexTypeDesc,
1997 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1998 TRACE_(ddraw_thunk)("(%p/%p)->(%08x,%08x,%08x): Thunking to IDirect3DDevice3\n", This, iface, d3dpt, dwVertexTypeDesc, dwFlags);
2000 switch(dwVertexTypeDesc)
2002 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
2003 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
2004 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
2006 ERR("Unexpected vertex type %d\n", dwVertexTypeDesc);
2007 return DDERR_INVALIDPARAMS; /* Should never happen */
2010 return IDirect3DDevice3_Begin(ICOM_INTERFACE(This, IDirect3DDevice3),
2016 /*****************************************************************************
2017 * IDirect3DDevice3::BeginIndexed
2019 * Draws primitives based on vertices in a vertex array which are specified
2025 * PrimitiveType: Primitive type to draw
2026 * VertexType: A FVF description of the vertex format
2027 * Vertices: pointer to an array containing the vertices
2028 * NumVertices: The number of vertices in the vertex array
2029 * Flags: Some flags ...
2032 * D3D_OK, because it's a stub
2034 *****************************************************************************/
2035 static HRESULT WINAPI
2036 IDirect3DDeviceImpl_3_BeginIndexed(IDirect3DDevice3 *iface,
2037 D3DPRIMITIVETYPE PrimitiveType,
2043 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2044 FIXME("(%p)->(%08x,%08x,%p,%08x,%08x): stub!\n", This, PrimitiveType, VertexType, Vertices, NumVertices, Flags);
2049 static HRESULT WINAPI
2050 Thunk_IDirect3DDeviceImpl_2_BeginIndexed(IDirect3DDevice2 *iface,
2051 D3DPRIMITIVETYPE d3dptPrimitiveType,
2052 D3DVERTEXTYPE d3dvtVertexType,
2054 DWORD dwNumVertices,
2058 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2059 TRACE_(ddraw_thunk)("(%p/%p)->(%08x,%08x,%p,%08x,%08x): Thunking to IDirect3DDevice3\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwNumVertices, dwFlags);
2061 switch(d3dvtVertexType)
2063 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
2064 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
2065 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
2067 ERR("Unexpected vertex type %d\n", d3dvtVertexType);
2068 return DDERR_INVALIDPARAMS; /* Should never happen */
2071 return IDirect3DDevice3_BeginIndexed(ICOM_INTERFACE(This,IDirect3DDevice3),
2079 /*****************************************************************************
2080 * IDirect3DDevice3::Vertex
2082 * Draws a vertex as described by IDirect3DDevice3::Begin. It places all
2083 * drawn vertices in a vertex buffer. If the buffer is too small, its
2084 * size is increased.
2089 * Vertex: Pointer to the vertex
2092 * D3D_OK, on success
2093 * DDERR_INVALIDPARAMS if Vertex is NULL
2095 *****************************************************************************/
2096 static HRESULT WINAPI
2097 IDirect3DDeviceImpl_3_Vertex(IDirect3DDevice3 *iface,
2100 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2101 TRACE("(%p)->(%p)\n", This, Vertex);
2104 return DDERR_INVALIDPARAMS;
2106 EnterCriticalSection(&ddraw_cs);
2107 if ((This->nb_vertices+1)*This->vertex_size > This->buffer_size)
2110 This->buffer_size = This->buffer_size ? This->buffer_size * 2 : This->vertex_size * 3;
2111 old_buffer = This->vertex_buffer;
2112 This->vertex_buffer = HeapAlloc(GetProcessHeap(), 0, This->buffer_size);
2115 CopyMemory(This->vertex_buffer, old_buffer, This->nb_vertices * This->vertex_size);
2116 HeapFree(GetProcessHeap(), 0, old_buffer);
2120 CopyMemory(This->vertex_buffer + This->nb_vertices++ * This->vertex_size, Vertex, This->vertex_size);
2122 LeaveCriticalSection(&ddraw_cs);
2126 static HRESULT WINAPI
2127 Thunk_IDirect3DDeviceImpl_2_Vertex(IDirect3DDevice2 *iface,
2130 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2131 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, lpVertexType);
2132 return IDirect3DDevice3_Vertex(ICOM_INTERFACE(This, IDirect3DDevice3),
2136 /*****************************************************************************
2137 * IDirect3DDevice3::Index
2139 * Specifies an index to a vertex to be drawn. The vertex array has to
2140 * be specified with BeginIndexed first.
2143 * VertexIndex: The index of the vertex to draw
2146 * D3D_OK because it's a stub
2148 *****************************************************************************/
2149 static HRESULT WINAPI
2150 IDirect3DDeviceImpl_3_Index(IDirect3DDevice3 *iface,
2153 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2154 FIXME("(%p)->(%04x): stub!\n", This, VertexIndex);
2158 static HRESULT WINAPI
2159 Thunk_IDirect3DDeviceImpl_2_Index(IDirect3DDevice2 *iface,
2162 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2163 TRACE_(ddraw_thunk)("(%p)->(%04x) thunking to IDirect3DDevice3 interface.\n", This, wVertexIndex);
2164 return IDirect3DDevice3_Index(ICOM_INTERFACE(This, IDirect3DDevice3),
2168 /*****************************************************************************
2169 * IDirect3DDevice3::End
2171 * Ends a draw begun with IDirect3DDevice3::Begin or
2172 * IDirect3DDevice::BeginIndexed. The vertices specified with
2173 * IDirect3DDevice::Vertex or IDirect3DDevice::Index are drawn using
2174 * the IDirect3DDevice7::DrawPrimitive method. So far only
2175 * non-indexed mode is supported
2180 * Flags: Some flags, as usual. Don't know which are defined
2183 * The return value of IDirect3DDevice7::DrawPrimitive
2185 *****************************************************************************/
2186 static HRESULT WINAPI
2187 IDirect3DDeviceImpl_3_End(IDirect3DDevice3 *iface,
2190 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2191 TRACE("(%p)->(%08x)\n", This, Flags);
2193 return IDirect3DDevice7_DrawPrimitive(ICOM_INTERFACE(This, IDirect3DDevice7),
2194 This->primitive_type, This->vertex_type,
2195 This->vertex_buffer, This->nb_vertices,
2196 This->render_flags);
2199 static HRESULT WINAPI
2200 Thunk_IDirect3DDeviceImpl_2_End(IDirect3DDevice2 *iface,
2203 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2204 TRACE_(ddraw_thunk)("(%p)->(%08x) thunking to IDirect3DDevice3 interface.\n", This, dwFlags);
2205 return IDirect3DDevice3_End(ICOM_INTERFACE(This, IDirect3DDevice3),
2209 /*****************************************************************************
2210 * IDirect3DDevice7::GetRenderState
2212 * Returns the value of a render state. The possible render states are
2213 * defined in include/d3dtypes.h
2215 * Version 2, 3 and 7
2218 * RenderStateType: Render state to return the current setting of
2219 * Value: Address to store the value at
2222 * D3D_OK on success, for details see IWineD3DDevice::GetRenderState
2223 * DDERR_INVALIDPARAMS if Value == NULL
2225 *****************************************************************************/
2226 static HRESULT WINAPI
2227 IDirect3DDeviceImpl_7_GetRenderState(IDirect3DDevice7 *iface,
2228 D3DRENDERSTATETYPE RenderStateType,
2231 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
2233 TRACE("(%p)->(%08x,%p): Relay\n", This, RenderStateType, Value);
2236 return DDERR_INVALIDPARAMS;
2238 EnterCriticalSection(&ddraw_cs);
2239 switch(RenderStateType)
2241 case D3DRENDERSTATE_TEXTUREHANDLE:
2243 /* This state is wrapped to SetTexture in SetRenderState, so
2244 * it has to be wrapped to GetTexture here
2246 IWineD3DBaseTexture *tex = NULL;
2249 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice,
2253 if(hr == WINED3D_OK && tex)
2255 IDirectDrawSurface7 *parent = NULL;
2256 hr = IWineD3DBaseTexture_GetParent(tex,
2257 (IUnknown **) &parent);
2260 /* The parent of the texture is the IDirectDrawSurface7 interface
2261 * of the ddraw surface
2263 IDirectDrawSurfaceImpl *texImpl = ICOM_OBJECT(IDirectDrawSurfaceImpl,
2264 IDirectDrawSurface7,
2266 *Value = texImpl->Handle;
2267 IDirectDrawSurface7_Release(parent);
2269 IWineD3DBaseTexture_Release(tex);
2274 case D3DRENDERSTATE_TEXTUREMAG:
2276 WINED3DTEXTUREFILTERTYPE tex_mag;
2278 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2279 0, WINED3DSAMP_MAGFILTER,
2284 case WINED3DTEXF_POINT:
2285 *Value = D3DFILTER_NEAREST;
2287 case WINED3DTEXF_LINEAR:
2288 *Value = D3DFILTER_LINEAR;
2291 ERR("Unhandled texture mag %d !\n",tex_mag);
2297 case D3DRENDERSTATE_TEXTUREMIN:
2299 WINED3DTEXTUREFILTERTYPE tex_min;
2301 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2302 0, WINED3DSAMP_MINFILTER,
2307 case WINED3DTEXF_POINT:
2308 *Value = D3DFILTER_NEAREST;
2310 case WINED3DTEXF_LINEAR:
2311 *Value = D3DFILTER_LINEAR;
2314 ERR("Unhandled texture mag %d !\n",tex_min);
2320 case D3DRENDERSTATE_TEXTUREADDRESS:
2321 case D3DRENDERSTATE_TEXTUREADDRESSU:
2322 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2323 0, WINED3DSAMP_ADDRESSU,
2326 case D3DRENDERSTATE_TEXTUREADDRESSV:
2327 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2328 0, WINED3DSAMP_ADDRESSV,
2333 /* FIXME: Unhandled: D3DRENDERSTATE_STIPPLEPATTERN00 - 31 */
2334 hr = IWineD3DDevice_GetRenderState(This->wineD3DDevice,
2338 LeaveCriticalSection(&ddraw_cs);
2342 static HRESULT WINAPI
2343 Thunk_IDirect3DDeviceImpl_3_GetRenderState(IDirect3DDevice3 *iface,
2344 D3DRENDERSTATETYPE dwRenderStateType,
2345 DWORD *lpdwRenderState)
2347 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2348 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, dwRenderStateType, lpdwRenderState);
2349 return IDirect3DDevice7_GetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
2354 static HRESULT WINAPI
2355 Thunk_IDirect3DDeviceImpl_2_GetRenderState(IDirect3DDevice2 *iface,
2356 D3DRENDERSTATETYPE dwRenderStateType,
2357 DWORD *lpdwRenderState)
2359 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2360 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, dwRenderStateType, lpdwRenderState);
2361 return IDirect3DDevice7_GetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
2366 /*****************************************************************************
2367 * IDirect3DDevice7::SetRenderState
2369 * Sets a render state. The possible render states are defined in
2370 * include/d3dtypes.h
2372 * Version 2, 3 and 7
2375 * RenderStateType: State to set
2376 * Value: Value to assign to that state
2379 * D3D_OK on success,
2380 * for details see IWineD3DDevice::SetRenderState
2382 *****************************************************************************/
2383 static HRESULT WINAPI
2384 IDirect3DDeviceImpl_7_SetRenderState(IDirect3DDevice7 *iface,
2385 D3DRENDERSTATETYPE RenderStateType,
2388 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
2390 TRACE("(%p)->(%08x,%d): Relay\n", This, RenderStateType, Value);
2392 EnterCriticalSection(&ddraw_cs);
2393 /* Some render states need special care */
2394 switch(RenderStateType)
2396 case D3DRENDERSTATE_TEXTUREHANDLE:
2400 hr = IWineD3DDevice_SetTexture(This->wineD3DDevice,
2406 if(Value > This->numHandles)
2408 FIXME("Specified handle %d out of range\n", Value);
2409 hr = DDERR_INVALIDPARAMS;
2412 if(This->Handles[Value - 1].type != DDrawHandle_Texture)
2414 FIXME("Handle %d isn't a texture handle\n", Value);
2415 hr = DDERR_INVALIDPARAMS;
2420 IDirectDrawSurfaceImpl *surf = (IDirectDrawSurfaceImpl *) This->Handles[Value - 1].ptr;
2421 hr = IWineD3DDevice_SetTexture(This->wineD3DDevice,
2423 surf->wineD3DTexture);
2428 case D3DRENDERSTATE_TEXTUREMAG:
2430 WINED3DTEXTUREFILTERTYPE tex_mag = WINED3DTEXF_NONE;
2432 switch ((D3DTEXTUREFILTER) Value)
2434 case D3DFILTER_NEAREST:
2435 case D3DFILTER_LINEARMIPNEAREST:
2436 tex_mag = WINED3DTEXF_POINT;
2438 case D3DFILTER_LINEAR:
2439 case D3DFILTER_LINEARMIPLINEAR:
2440 tex_mag = WINED3DTEXF_LINEAR;
2443 ERR("Unhandled texture mag %d !\n",Value);
2446 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2447 0, WINED3DSAMP_MAGFILTER,
2452 case D3DRENDERSTATE_TEXTUREMIN:
2454 WINED3DTEXTUREFILTERTYPE tex_min = WINED3DTEXF_NONE;
2455 WINED3DTEXTUREFILTERTYPE tex_mip = WINED3DTEXF_NONE;
2457 switch ((D3DTEXTUREFILTER) Value)
2459 case D3DFILTER_NEAREST:
2460 tex_min = WINED3DTEXF_POINT;
2462 case D3DFILTER_LINEAR:
2463 tex_min = WINED3DTEXF_LINEAR;
2465 case D3DFILTER_MIPNEAREST:
2466 tex_min = WINED3DTEXF_NONE;
2467 tex_mip = WINED3DTEXF_POINT;
2469 case D3DFILTER_MIPLINEAR:
2470 tex_min = WINED3DTEXF_NONE;
2471 tex_mip = WINED3DTEXF_LINEAR;
2473 case D3DFILTER_LINEARMIPNEAREST:
2474 tex_min = WINED3DTEXF_POINT;
2475 tex_mip = WINED3DTEXF_LINEAR;
2477 case D3DFILTER_LINEARMIPLINEAR:
2478 tex_min = WINED3DTEXF_LINEAR;
2479 tex_mip = WINED3DTEXF_LINEAR;
2483 ERR("Unhandled texture min %d !\n",Value);
2486 IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2487 0, WINED3DSAMP_MIPFILTER,
2489 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2490 0, WINED3DSAMP_MINFILTER,
2495 case D3DRENDERSTATE_TEXTUREADDRESS:
2496 IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2497 0, WINED3DSAMP_ADDRESSV,
2500 case D3DRENDERSTATE_TEXTUREADDRESSU:
2501 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2502 0, WINED3DSAMP_ADDRESSU,
2505 case D3DRENDERSTATE_TEXTUREADDRESSV:
2506 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2507 0, WINED3DSAMP_ADDRESSV,
2511 case D3DRENDERSTATE_TEXTUREMAPBLEND:
2513 /* Old texture combine setup style, superseded by texture stage states
2514 * in D3D7. It is safe for us to wrap it to texture stage states.
2516 switch ( (D3DTEXTUREBLEND) Value)
2518 case D3DTBLEND_MODULATE:
2519 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2520 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2521 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2522 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_MODULATE);
2523 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG1);
2526 case D3DTBLEND_MODULATEALPHA:
2527 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2528 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2529 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2530 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
2531 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_MODULATE);
2532 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_MODULATE);
2535 case D3DTBLEND_DECAL:
2536 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2537 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2538 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_SELECTARG1);
2539 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG1);
2542 case D3DTBLEND_DECALALPHA:
2543 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2544 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2545 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
2546 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_SELECTARG1);
2547 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_MODULATE);
2551 ERR("Unhandled texture environment %d !\n",Value);
2559 /* FIXME: Unhandled: D3DRENDERSTATE_STIPPLEPATTERN00 - 31 */
2561 hr = IWineD3DDevice_SetRenderState(This->wineD3DDevice,
2566 LeaveCriticalSection(&ddraw_cs);
2570 static HRESULT WINAPI
2571 Thunk_IDirect3DDeviceImpl_3_SetRenderState(IDirect3DDevice3 *iface,
2572 D3DRENDERSTATETYPE RenderStateType,
2575 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2576 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, RenderStateType, Value);
2577 return IDirect3DDevice7_SetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
2582 static HRESULT WINAPI
2583 Thunk_IDirect3DDeviceImpl_2_SetRenderState(IDirect3DDevice2 *iface,
2584 D3DRENDERSTATETYPE RenderStateType,
2587 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2588 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, RenderStateType, Value);
2589 return IDirect3DDevice7_SetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
2594 /*****************************************************************************
2595 * Direct3DDevice3::SetLightState
2597 * Sets a light state for Direct3DDevice3 and Direct3DDevice2. The
2598 * light states are forwarded to Direct3DDevice7 render states
2603 * LightStateType: The light state to change
2604 * Value: The value to assign to that light state
2608 * DDERR_INVALIDPARAMS if the parameters were incorrect
2609 * Also check IDirect3DDevice7::SetRenderState
2611 *****************************************************************************/
2612 static HRESULT WINAPI
2613 IDirect3DDeviceImpl_3_SetLightState(IDirect3DDevice3 *iface,
2614 D3DLIGHTSTATETYPE LightStateType,
2617 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2620 TRACE("(%p)->(%08x,%08x)\n", This, LightStateType, Value);
2622 if (!LightStateType && (LightStateType > D3DLIGHTSTATE_COLORVERTEX))
2624 TRACE("Unexpected Light State Type\n");
2625 return DDERR_INVALIDPARAMS;
2628 EnterCriticalSection(&ddraw_cs);
2629 if (LightStateType == D3DLIGHTSTATE_MATERIAL /* 1 */)
2631 IDirect3DMaterialImpl *mat;
2633 if(Value == 0) mat = NULL;
2634 else if(Value > This->numHandles)
2636 ERR("Material handle out of range(%d)\n", Value);
2637 LeaveCriticalSection(&ddraw_cs);
2638 return DDERR_INVALIDPARAMS;
2640 else if(This->Handles[Value - 1].type != DDrawHandle_Material)
2642 ERR("Invalid handle %d\n", Value);
2643 LeaveCriticalSection(&ddraw_cs);
2644 return DDERR_INVALIDPARAMS;
2648 mat = (IDirect3DMaterialImpl *) This->Handles[Value - 1].ptr;
2653 TRACE(" activating material %p.\n", mat);
2658 FIXME(" D3DLIGHTSTATE_MATERIAL called with NULL material !!!\n");
2660 This->material = Value;
2662 else if (LightStateType == D3DLIGHTSTATE_COLORMODEL /* 3 */)
2667 ERR("DDCOLOR_MONO should not happen!\n");
2670 /* We are already in this mode */
2671 TRACE("Setting color model to RGB (no-op).\n");
2674 ERR("Unknown color model!\n");
2675 LeaveCriticalSection(&ddraw_cs);
2676 return DDERR_INVALIDPARAMS;
2681 D3DRENDERSTATETYPE rs;
2682 switch (LightStateType)
2684 case D3DLIGHTSTATE_AMBIENT: /* 2 */
2685 rs = D3DRENDERSTATE_AMBIENT;
2687 case D3DLIGHTSTATE_FOGMODE: /* 4 */
2688 rs = D3DRENDERSTATE_FOGVERTEXMODE;
2690 case D3DLIGHTSTATE_FOGSTART: /* 5 */
2691 rs = D3DRENDERSTATE_FOGSTART;
2693 case D3DLIGHTSTATE_FOGEND: /* 6 */
2694 rs = D3DRENDERSTATE_FOGEND;
2696 case D3DLIGHTSTATE_FOGDENSITY: /* 7 */
2697 rs = D3DRENDERSTATE_FOGDENSITY;
2699 case D3DLIGHTSTATE_COLORVERTEX: /* 8 */
2700 rs = D3DRENDERSTATE_COLORVERTEX;
2703 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType);
2704 LeaveCriticalSection(&ddraw_cs);
2705 return DDERR_INVALIDPARAMS;
2708 hr = IDirect3DDevice7_SetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
2711 LeaveCriticalSection(&ddraw_cs);
2715 LeaveCriticalSection(&ddraw_cs);
2719 static HRESULT WINAPI
2720 Thunk_IDirect3DDeviceImpl_2_SetLightState(IDirect3DDevice2 *iface,
2721 D3DLIGHTSTATETYPE LightStateType,
2724 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2725 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x) thunking to IDirect3DDevice3 interface.\n", This, LightStateType, Value);
2726 return IDirect3DDevice3_SetLightState(ICOM_INTERFACE(This, IDirect3DDevice3),
2731 /*****************************************************************************
2732 * IDirect3DDevice3::GetLightState
2734 * Returns the current setting of a light state. The state is read from
2735 * the Direct3DDevice7 render state.
2740 * LightStateType: The light state to return
2741 * Value: The address to store the light state setting at
2745 * DDDERR_INVALIDPARAMS if the parameters were incorrect
2746 * Also see IDirect3DDevice7::GetRenderState
2748 *****************************************************************************/
2749 static HRESULT WINAPI
2750 IDirect3DDeviceImpl_3_GetLightState(IDirect3DDevice3 *iface,
2751 D3DLIGHTSTATETYPE LightStateType,
2754 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2757 TRACE("(%p)->(%08x,%p)\n", This, LightStateType, Value);
2759 if (!LightStateType && (LightStateType > D3DLIGHTSTATE_COLORVERTEX))
2761 TRACE("Unexpected Light State Type\n");
2762 return DDERR_INVALIDPARAMS;
2766 return DDERR_INVALIDPARAMS;
2768 EnterCriticalSection(&ddraw_cs);
2769 if (LightStateType == D3DLIGHTSTATE_MATERIAL /* 1 */)
2771 *Value = This->material;
2773 else if (LightStateType == D3DLIGHTSTATE_COLORMODEL /* 3 */)
2775 *Value = D3DCOLOR_RGB;
2779 D3DRENDERSTATETYPE rs;
2780 switch (LightStateType)
2782 case D3DLIGHTSTATE_AMBIENT: /* 2 */
2783 rs = D3DRENDERSTATE_AMBIENT;
2785 case D3DLIGHTSTATE_FOGMODE: /* 4 */
2786 rs = D3DRENDERSTATE_FOGVERTEXMODE;
2788 case D3DLIGHTSTATE_FOGSTART: /* 5 */
2789 rs = D3DRENDERSTATE_FOGSTART;
2791 case D3DLIGHTSTATE_FOGEND: /* 6 */
2792 rs = D3DRENDERSTATE_FOGEND;
2794 case D3DLIGHTSTATE_FOGDENSITY: /* 7 */
2795 rs = D3DRENDERSTATE_FOGDENSITY;
2797 case D3DLIGHTSTATE_COLORVERTEX: /* 8 */
2798 rs = D3DRENDERSTATE_COLORVERTEX;
2801 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType);
2802 LeaveCriticalSection(&ddraw_cs);
2803 return DDERR_INVALIDPARAMS;
2806 hr = IDirect3DDevice7_GetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
2809 LeaveCriticalSection(&ddraw_cs);
2813 LeaveCriticalSection(&ddraw_cs);
2817 static HRESULT WINAPI
2818 Thunk_IDirect3DDeviceImpl_2_GetLightState(IDirect3DDevice2 *iface,
2819 D3DLIGHTSTATETYPE LightStateType,
2822 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2823 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice3 interface.\n", This, LightStateType, Value);
2824 return IDirect3DDevice3_GetLightState(ICOM_INTERFACE(This, IDirect3DDevice3),
2829 /*****************************************************************************
2830 * IDirect3DDevice7::SetTransform
2832 * Assigns a D3DMATRIX to a transform type. The transform types are defined
2833 * in include/d3dtypes.h.
2834 * The D3DTRANSFORMSTATE_WORLD (=1) is translated to D3DTS_WORLDMATRIX(0)
2835 * (=255) for wined3d, because the 1 transform state was removed in d3d8
2836 * and WineD3D already understands the replacement D3DTS_WORLDMATRIX(0)
2838 * Version 2, 3 and 7
2841 * TransformStateType: transform state to set
2842 * Matrix: Matrix to assign to the state
2846 * DDERR_INVALIDPARAMS if Matrix == NULL
2847 * For details see IWineD3DDevice::SetTransform
2849 *****************************************************************************/
2850 static HRESULT WINAPI
2851 IDirect3DDeviceImpl_7_SetTransform(IDirect3DDevice7 *iface,
2852 D3DTRANSFORMSTATETYPE TransformStateType,
2855 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
2856 D3DTRANSFORMSTATETYPE type = TransformStateType;
2858 TRACE("(%p)->(%08x,%p): Relay\n", This, TransformStateType, Matrix);
2860 switch(TransformStateType)
2862 case D3DTRANSFORMSTATE_WORLD : type = WINED3DTS_WORLDMATRIX(0); break;
2863 case D3DTRANSFORMSTATE_WORLD1: type = WINED3DTS_WORLDMATRIX(1); break;
2864 case D3DTRANSFORMSTATE_WORLD2: type = WINED3DTS_WORLDMATRIX(2); break;
2865 case D3DTRANSFORMSTATE_WORLD3: type = WINED3DTS_WORLDMATRIX(3); break;
2866 default: type = TransformStateType;
2870 return DDERR_INVALIDPARAMS;
2872 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
2873 EnterCriticalSection(&ddraw_cs);
2874 hr = IWineD3DDevice_SetTransform(This->wineD3DDevice,
2876 (WINED3DMATRIX*) Matrix);
2877 LeaveCriticalSection(&ddraw_cs);
2881 static HRESULT WINAPI
2882 Thunk_IDirect3DDeviceImpl_3_SetTransform(IDirect3DDevice3 *iface,
2883 D3DTRANSFORMSTATETYPE TransformStateType,
2884 D3DMATRIX *D3DMatrix)
2886 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2887 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
2888 return IDirect3DDevice7_SetTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
2893 static HRESULT WINAPI
2894 Thunk_IDirect3DDeviceImpl_2_SetTransform(IDirect3DDevice2 *iface,
2895 D3DTRANSFORMSTATETYPE TransformStateType,
2896 D3DMATRIX *D3DMatrix)
2898 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2899 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
2900 return IDirect3DDevice7_SetTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
2905 /*****************************************************************************
2906 * IDirect3DDevice7::GetTransform
2908 * Returns the matrix assigned to a transform state
2909 * D3DTRANSFORMSTATE_WORLD is translated to D3DTS_WORLDMATRIX(0), see
2913 * TransformStateType: State to read the matrix from
2914 * Matrix: Address to store the matrix at
2918 * DDERR_INVALIDPARAMS if Matrix == NULL
2919 * For details, see IWineD3DDevice::GetTransform
2921 *****************************************************************************/
2922 static HRESULT WINAPI
2923 IDirect3DDeviceImpl_7_GetTransform(IDirect3DDevice7 *iface,
2924 D3DTRANSFORMSTATETYPE TransformStateType,
2927 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
2928 D3DTRANSFORMSTATETYPE type = TransformStateType;
2930 TRACE("(%p)->(%08x,%p): Relay\n", This, TransformStateType, Matrix);
2932 switch(TransformStateType)
2934 case D3DTRANSFORMSTATE_WORLD : type = WINED3DTS_WORLDMATRIX(0); break;
2935 case D3DTRANSFORMSTATE_WORLD1: type = WINED3DTS_WORLDMATRIX(1); break;
2936 case D3DTRANSFORMSTATE_WORLD2: type = WINED3DTS_WORLDMATRIX(2); break;
2937 case D3DTRANSFORMSTATE_WORLD3: type = WINED3DTS_WORLDMATRIX(3); break;
2938 default: type = TransformStateType;
2942 return DDERR_INVALIDPARAMS;
2944 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
2945 EnterCriticalSection(&ddraw_cs);
2946 hr = IWineD3DDevice_GetTransform(This->wineD3DDevice, type, (WINED3DMATRIX*) Matrix);
2947 LeaveCriticalSection(&ddraw_cs);
2951 static HRESULT WINAPI
2952 Thunk_IDirect3DDeviceImpl_3_GetTransform(IDirect3DDevice3 *iface,
2953 D3DTRANSFORMSTATETYPE TransformStateType,
2954 D3DMATRIX *D3DMatrix)
2956 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2957 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
2958 return IDirect3DDevice7_GetTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
2963 static HRESULT WINAPI
2964 Thunk_IDirect3DDeviceImpl_2_GetTransform(IDirect3DDevice2 *iface,
2965 D3DTRANSFORMSTATETYPE TransformStateType,
2966 D3DMATRIX *D3DMatrix)
2968 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2969 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
2970 return IDirect3DDevice7_GetTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
2975 /*****************************************************************************
2976 * IDirect3DDevice7::MultiplyTransform
2978 * Multiplies the already-set transform matrix of a transform state
2979 * with another matrix. For the world matrix, see SetTransform
2981 * Version 2, 3 and 7
2984 * TransformStateType: Transform state to multiply
2985 * D3DMatrix Matrix to multiply with.
2989 * DDERR_INVALIDPARAMS if D3DMatrix is NULL
2990 * For details, see IWineD3DDevice::MultiplyTransform
2992 *****************************************************************************/
2993 static HRESULT WINAPI
2994 IDirect3DDeviceImpl_7_MultiplyTransform(IDirect3DDevice7 *iface,
2995 D3DTRANSFORMSTATETYPE TransformStateType,
2996 D3DMATRIX *D3DMatrix)
2998 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3000 D3DTRANSFORMSTATETYPE type;
3001 TRACE("(%p)->(%08x,%p): Relay\n", This, TransformStateType, D3DMatrix);
3003 switch(TransformStateType)
3005 case D3DTRANSFORMSTATE_WORLD : type = WINED3DTS_WORLDMATRIX(0); break;
3006 case D3DTRANSFORMSTATE_WORLD1: type = WINED3DTS_WORLDMATRIX(1); break;
3007 case D3DTRANSFORMSTATE_WORLD2: type = WINED3DTS_WORLDMATRIX(2); break;
3008 case D3DTRANSFORMSTATE_WORLD3: type = WINED3DTS_WORLDMATRIX(3); break;
3009 default: type = TransformStateType;
3012 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3013 EnterCriticalSection(&ddraw_cs);
3014 hr = IWineD3DDevice_MultiplyTransform(This->wineD3DDevice,
3016 (WINED3DMATRIX*) D3DMatrix);
3017 LeaveCriticalSection(&ddraw_cs);
3021 static HRESULT WINAPI
3022 Thunk_IDirect3DDeviceImpl_3_MultiplyTransform(IDirect3DDevice3 *iface,
3023 D3DTRANSFORMSTATETYPE TransformStateType,
3024 D3DMATRIX *D3DMatrix)
3026 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3027 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3028 return IDirect3DDevice7_MultiplyTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
3033 static HRESULT WINAPI
3034 Thunk_IDirect3DDeviceImpl_2_MultiplyTransform(IDirect3DDevice2 *iface,
3035 D3DTRANSFORMSTATETYPE TransformStateType,
3036 D3DMATRIX *D3DMatrix)
3038 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3039 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3040 return IDirect3DDevice7_MultiplyTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
3045 /*****************************************************************************
3046 * IDirect3DDevice7::DrawPrimitive
3048 * Draws primitives based on vertices in an application-provided pointer
3050 * Version 2, 3 and 7. The IDirect3DDevice2 thunk converts the fixed vertex type into
3051 * an FVF format for D3D7
3054 * PrimitiveType: The type of the primitives to draw
3055 * Vertex type: Flexible vertex format vertex description
3056 * Vertices: Pointer to the vertex array
3057 * VertexCount: The number of vertices to draw
3058 * Flags: As usual a few flags
3062 * DDERR_INVALIDPARAMS if Vertices is NULL
3063 * For details, see IWineD3DDevice::DrawPrimitiveUP
3065 *****************************************************************************/
3066 static HRESULT WINAPI
3067 IDirect3DDeviceImpl_7_DrawPrimitive(IDirect3DDevice7 *iface,
3068 D3DPRIMITIVETYPE PrimitiveType,
3074 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3075 UINT PrimitiveCount, stride;
3077 TRACE("(%p)->(%08x,%08x,%p,%08x,%08x): Relay!\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3080 return DDERR_INVALIDPARAMS;
3082 /* Get the vertex count */
3083 switch(PrimitiveType)
3085 case D3DPT_POINTLIST:
3086 PrimitiveCount = VertexCount;
3089 case D3DPT_LINELIST:
3090 PrimitiveCount = VertexCount / 2;
3093 case D3DPT_LINESTRIP:
3094 PrimitiveCount = VertexCount - 1;
3097 case D3DPT_TRIANGLELIST:
3098 PrimitiveCount = VertexCount / 3;
3101 case D3DPT_TRIANGLESTRIP:
3102 PrimitiveCount = VertexCount - 2;
3105 case D3DPT_TRIANGLEFAN:
3106 PrimitiveCount = VertexCount - 2;
3110 return DDERR_INVALIDPARAMS;
3113 /* Get the stride */
3114 stride = get_flexible_vertex_size(VertexType);
3117 EnterCriticalSection(&ddraw_cs);
3118 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
3119 IDirectDrawImpl_FindDecl(This->ddraw, VertexType));
3122 LeaveCriticalSection(&ddraw_cs);
3126 /* This method translates to the user pointer draw of WineD3D */
3127 hr = IWineD3DDevice_DrawPrimitiveUP(This->wineD3DDevice,
3132 LeaveCriticalSection(&ddraw_cs);
3136 static HRESULT WINAPI
3137 Thunk_IDirect3DDeviceImpl_3_DrawPrimitive(IDirect3DDevice3 *iface,
3138 D3DPRIMITIVETYPE PrimitiveType,
3144 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3145 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3146 return IDirect3DDevice7_DrawPrimitive(ICOM_INTERFACE(This, IDirect3DDevice7),
3154 static HRESULT WINAPI
3155 Thunk_IDirect3DDeviceImpl_2_DrawPrimitive(IDirect3DDevice2 *iface,
3156 D3DPRIMITIVETYPE PrimitiveType,
3157 D3DVERTEXTYPE VertexType,
3162 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3164 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3168 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
3169 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
3170 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
3172 ERR("Unexpected vertex type %d\n", VertexType);
3173 return DDERR_INVALIDPARAMS; /* Should never happen */
3176 return IDirect3DDevice7_DrawPrimitive(ICOM_INTERFACE(This, IDirect3DDevice7),
3184 /*****************************************************************************
3185 * IDirect3DDevice7::DrawIndexedPrimitive
3187 * Draws vertices from an application-provided pointer, based on the index
3188 * numbers in a WORD array.
3190 * Version 2, 3 and 7. The version 7 thunk translates the vertex type into
3191 * an FVF format for D3D7
3194 * PrimitiveType: The primitive type to draw
3195 * VertexType: The FVF vertex description
3196 * Vertices: Pointer to the vertex array
3198 * Indices: Pointer to the index array
3199 * IndexCount: Number of indices = Number of vertices to draw
3200 * Flags: As usual, some flags
3204 * DDERR_INVALIDPARAMS if Vertices or Indices is NULL
3205 * For details, see IWineD3DDevice::DrawIndexedPrimitiveUP
3207 *****************************************************************************/
3208 static HRESULT WINAPI
3209 IDirect3DDeviceImpl_7_DrawIndexedPrimitive(IDirect3DDevice7 *iface,
3210 D3DPRIMITIVETYPE PrimitiveType,
3218 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3219 UINT PrimitiveCount = 0;
3221 TRACE("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x): Relay!\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3223 /* Get the primitive number */
3224 switch(PrimitiveType)
3226 case D3DPT_POINTLIST:
3227 PrimitiveCount = IndexCount;
3230 case D3DPT_LINELIST:
3231 PrimitiveCount = IndexCount / 2;
3234 case D3DPT_LINESTRIP:
3235 PrimitiveCount = IndexCount - 1;
3238 case D3DPT_TRIANGLELIST:
3239 PrimitiveCount = IndexCount / 3;
3242 case D3DPT_TRIANGLESTRIP:
3243 PrimitiveCount = IndexCount - 2;
3246 case D3DPT_TRIANGLEFAN:
3247 PrimitiveCount = IndexCount - 2;
3251 return DDERR_INVALIDPARAMS;
3254 /* Set the D3DDevice's FVF */
3255 EnterCriticalSection(&ddraw_cs);
3256 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
3257 IDirectDrawImpl_FindDecl(This->ddraw, VertexType));
3260 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr);
3261 LeaveCriticalSection(&ddraw_cs);
3265 hr = IWineD3DDevice_DrawIndexedPrimitiveUP(This->wineD3DDevice,
3267 0 /* MinVertexIndex */,
3268 VertexCount /* UINT NumVertexIndex */,
3273 get_flexible_vertex_size(VertexType));
3274 LeaveCriticalSection(&ddraw_cs);
3278 static HRESULT WINAPI
3279 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive(IDirect3DDevice3 *iface,
3280 D3DPRIMITIVETYPE PrimitiveType,
3288 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3289 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3290 return IDirect3DDevice7_DrawIndexedPrimitive(ICOM_INTERFACE(This, IDirect3DDevice7),
3300 static HRESULT WINAPI
3301 Thunk_IDirect3DDeviceImpl_2_DrawIndexedPrimitive(IDirect3DDevice2 *iface,
3302 D3DPRIMITIVETYPE PrimitiveType,
3303 D3DVERTEXTYPE VertexType,
3311 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3312 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3316 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
3317 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
3318 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
3320 ERR("Unexpected vertex type %d\n", VertexType);
3321 return DDERR_INVALIDPARAMS; /* Should never happen */
3324 return IDirect3DDevice7_DrawIndexedPrimitive(ICOM_INTERFACE(This, IDirect3DDevice7),
3334 /*****************************************************************************
3335 * IDirect3DDevice7::SetClipStatus
3337 * Sets the clip status. This defines things as clipping conditions and
3338 * the extents of the clipping region.
3340 * Version 2, 3 and 7
3346 * D3D_OK because it's a stub
3347 * (DDERR_INVALIDPARAMS if ClipStatus == NULL)
3349 *****************************************************************************/
3350 static HRESULT WINAPI
3351 IDirect3DDeviceImpl_7_SetClipStatus(IDirect3DDevice7 *iface,
3352 D3DCLIPSTATUS *ClipStatus)
3354 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3355 FIXME("(%p)->(%p): Stub!\n", This, ClipStatus);
3357 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them
3358 * Perhaps this needs a new data type and an additional IWineD3DDevice method
3360 /* return IWineD3DDevice_SetClipStatus(This->wineD3DDevice, ClipStatus);*/
3364 static HRESULT WINAPI
3365 Thunk_IDirect3DDeviceImpl_3_SetClipStatus(IDirect3DDevice3 *iface,
3366 D3DCLIPSTATUS *ClipStatus)
3368 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3369 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3370 return IDirect3DDevice7_SetClipStatus(ICOM_INTERFACE(This, IDirect3DDevice7),
3374 static HRESULT WINAPI
3375 Thunk_IDirect3DDeviceImpl_2_SetClipStatus(IDirect3DDevice2 *iface,
3376 D3DCLIPSTATUS *ClipStatus)
3378 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3379 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3380 return IDirect3DDevice7_SetClipStatus(ICOM_INTERFACE(This, IDirect3DDevice7),
3384 /*****************************************************************************
3385 * IDirect3DDevice7::GetClipStatus
3387 * Returns the clip status
3390 * ClipStatus: Address to write the clip status to
3393 * D3D_OK because it's a stub
3395 *****************************************************************************/
3396 static HRESULT WINAPI
3397 IDirect3DDeviceImpl_7_GetClipStatus(IDirect3DDevice7 *iface,
3398 D3DCLIPSTATUS *ClipStatus)
3400 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3401 FIXME("(%p)->(%p): Stub!\n", This, ClipStatus);
3403 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them */
3404 /* return IWineD3DDevice_GetClipStatus(This->wineD3DDevice, ClipStatus);*/
3408 static HRESULT WINAPI
3409 Thunk_IDirect3DDeviceImpl_3_GetClipStatus(IDirect3DDevice3 *iface,
3410 D3DCLIPSTATUS *ClipStatus)
3412 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3413 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3414 return IDirect3DDevice7_GetClipStatus(ICOM_INTERFACE(This, IDirect3DDevice7),
3418 static HRESULT WINAPI
3419 Thunk_IDirect3DDeviceImpl_2_GetClipStatus(IDirect3DDevice2 *iface,
3420 D3DCLIPSTATUS *ClipStatus)
3422 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3423 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3424 return IDirect3DDevice7_GetClipStatus(ICOM_INTERFACE(This, IDirect3DDevice7),
3428 /*****************************************************************************
3429 * IDirect3DDevice::DrawPrimitiveStrided
3431 * Draws vertices described by a D3DDRAWPRIMITIVESTRIDEDDATA structure.
3436 * PrimitiveType: The primitive type to draw
3437 * VertexType: The FVF description of the vertices to draw (for the stride??)
3438 * D3DDrawPrimStrideData: A D3DDRAWPRIMITIVESTRIDEDDATA structure describing
3439 * the vertex data locations
3440 * VertexCount: The number of vertices to draw
3444 * D3D_OK, because it's a stub
3445 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
3446 * (For details, see IWineD3DDevice::DrawPrimitiveStrided)
3448 *****************************************************************************/
3449 static HRESULT WINAPI
3450 IDirect3DDeviceImpl_7_DrawPrimitiveStrided(IDirect3DDevice7 *iface,
3451 D3DPRIMITIVETYPE PrimitiveType,
3453 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3457 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3458 WineDirect3DVertexStridedData WineD3DStrided;
3460 UINT PrimitiveCount;
3463 TRACE("(%p)->(%08x,%08x,%p,%08x,%08x): stub!\n", This, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
3465 memset(&WineD3DStrided, 0, sizeof(WineD3DStrided));
3466 /* Get the strided data right. the wined3d structure is a bit bigger
3467 * Watch out: The contents of the strided data are determined by the fvf,
3468 * not by the members set in D3DDrawPrimStrideData. So it's valid
3469 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
3470 * not set in the fvf.
3472 if(VertexType & D3DFVF_POSITION_MASK)
3474 WineD3DStrided.u.s.position.lpData = D3DDrawPrimStrideData->position.lpvData;
3475 WineD3DStrided.u.s.position.dwStride = D3DDrawPrimStrideData->position.dwStride;
3476 WineD3DStrided.u.s.position.dwType = WINED3DDECLTYPE_FLOAT3;
3477 if (VertexType & D3DFVF_XYZRHW)
3479 WineD3DStrided.u.s.position.dwType = WINED3DDECLTYPE_FLOAT4;
3480 WineD3DStrided.u.s.position_transformed = TRUE;
3482 WineD3DStrided.u.s.position_transformed = FALSE;
3485 if(VertexType & D3DFVF_NORMAL)
3487 WineD3DStrided.u.s.normal.lpData = D3DDrawPrimStrideData->normal.lpvData;
3488 WineD3DStrided.u.s.normal.dwStride = D3DDrawPrimStrideData->normal.dwStride;
3489 WineD3DStrided.u.s.normal.dwType = WINED3DDECLTYPE_FLOAT3;
3492 if(VertexType & D3DFVF_DIFFUSE)
3494 WineD3DStrided.u.s.diffuse.lpData = D3DDrawPrimStrideData->diffuse.lpvData;
3495 WineD3DStrided.u.s.diffuse.dwStride = D3DDrawPrimStrideData->diffuse.dwStride;
3496 WineD3DStrided.u.s.diffuse.dwType = WINED3DDECLTYPE_SHORT4;
3499 if(VertexType & D3DFVF_SPECULAR)
3501 WineD3DStrided.u.s.specular.lpData = D3DDrawPrimStrideData->specular.lpvData;
3502 WineD3DStrided.u.s.specular.dwStride = D3DDrawPrimStrideData->specular.dwStride;
3503 WineD3DStrided.u.s.specular.dwType = WINED3DDECLTYPE_SHORT4;
3506 for( i = 0; i < GET_TEXCOUNT_FROM_FVF(VertexType); i++)
3508 WineD3DStrided.u.s.texCoords[i].lpData = D3DDrawPrimStrideData->textureCoords[i].lpvData;
3509 WineD3DStrided.u.s.texCoords[i].dwStride = D3DDrawPrimStrideData->textureCoords[i].dwStride;
3510 switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i))
3512 case 1: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT1; break;
3513 case 2: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT2; break;
3514 case 3: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT3; break;
3515 case 4: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT4; break;
3516 default: ERR("Unexpected texture coordinate size %d\n",
3517 GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i));
3521 /* Get the primitive count */
3522 switch(PrimitiveType)
3524 case D3DPT_POINTLIST:
3525 PrimitiveCount = VertexCount;
3528 case D3DPT_LINELIST:
3529 PrimitiveCount = VertexCount / 2;
3532 case D3DPT_LINESTRIP:
3533 PrimitiveCount = VertexCount - 1;
3536 case D3DPT_TRIANGLELIST:
3537 PrimitiveCount = VertexCount / 3;
3540 case D3DPT_TRIANGLESTRIP:
3541 PrimitiveCount = VertexCount - 2;
3544 case D3DPT_TRIANGLEFAN:
3545 PrimitiveCount = VertexCount - 2;
3548 default: return DDERR_INVALIDPARAMS;
3551 /* WineD3D doesn't need the FVF here */
3552 EnterCriticalSection(&ddraw_cs);
3553 hr = IWineD3DDevice_DrawPrimitiveStrided(This->wineD3DDevice,
3557 LeaveCriticalSection(&ddraw_cs);
3561 static HRESULT WINAPI
3562 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided(IDirect3DDevice3 *iface,
3563 D3DPRIMITIVETYPE PrimitiveType,
3565 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3569 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3570 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
3571 return IDirect3DDevice7_DrawPrimitiveStrided(ICOM_INTERFACE(This, IDirect3DDevice7),
3574 D3DDrawPrimStrideData,
3579 /*****************************************************************************
3580 * IDirect3DDevice7::DrawIndexedPrimitiveStrided
3582 * Draws primitives specified by strided data locations based on indices
3590 * D3D_OK, because it's a stub
3591 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
3592 * (DDERR_INVALIDPARAMS if Indices is NULL)
3593 * (For more details, see IWineD3DDevice::DrawIndexedPrimitiveStrided)
3595 *****************************************************************************/
3596 static HRESULT WINAPI
3597 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(IDirect3DDevice7 *iface,
3598 D3DPRIMITIVETYPE PrimitiveType,
3600 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3606 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3607 FIXME("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x): stub!\n", This, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
3609 /* I'll implement it as soon as I find a app to test it.
3610 * This needs an additional method in IWineD3DDevice.
3615 static HRESULT WINAPI
3616 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided(IDirect3DDevice3 *iface,
3617 D3DPRIMITIVETYPE PrimitiveType,
3619 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3625 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3626 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
3627 return IDirect3DDevice7_DrawIndexedPrimitiveStrided(ICOM_INTERFACE(This, IDirect3DDevice7),
3630 D3DDrawPrimStrideData,
3637 /*****************************************************************************
3638 * IDirect3DDevice7::DrawPrimitiveVB
3640 * Draws primitives from a vertex buffer to the screen.
3645 * PrimitiveType: Type of primitive to be rendered.
3646 * D3DVertexBuf: Source Vertex Buffer
3647 * StartVertex: Index of the first vertex from the buffer to be rendered
3648 * NumVertices: Number of vertices to be rendered
3649 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
3653 * DDERR_INVALIDPARAMS if D3DVertexBuf is NULL
3655 *****************************************************************************/
3656 static HRESULT WINAPI
3657 IDirect3DDeviceImpl_7_DrawPrimitiveVB(IDirect3DDevice7 *iface,
3658 D3DPRIMITIVETYPE PrimitiveType,
3659 IDirect3DVertexBuffer7 *D3DVertexBuf,
3664 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3665 IDirect3DVertexBufferImpl *vb = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, D3DVertexBuf);
3666 UINT PrimitiveCount;
3669 WINED3DVERTEXBUFFER_DESC Desc;
3671 TRACE("(%p)->(%08x,%p,%08x,%08x,%08x)\n", This, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags);
3676 ERR("(%p) No Vertex buffer specified\n", This);
3677 return DDERR_INVALIDPARAMS;
3680 /* Get the primitive count */
3681 switch(PrimitiveType)
3683 case D3DPT_POINTLIST:
3684 PrimitiveCount = NumVertices;
3687 case D3DPT_LINELIST:
3688 PrimitiveCount = NumVertices / 2;
3691 case D3DPT_LINESTRIP:
3692 PrimitiveCount = NumVertices - 1;
3695 case D3DPT_TRIANGLELIST:
3696 PrimitiveCount = NumVertices / 3;
3699 case D3DPT_TRIANGLESTRIP:
3700 PrimitiveCount = NumVertices - 2;
3703 case D3DPT_TRIANGLEFAN:
3704 PrimitiveCount = NumVertices - 2;
3708 return DDERR_INVALIDPARAMS;
3711 /* Get the FVF of the vertex buffer, and its stride */
3712 EnterCriticalSection(&ddraw_cs);
3713 hr = IWineD3DVertexBuffer_GetDesc(vb->wineD3DVertexBuffer,
3717 ERR("(%p) IWineD3DVertexBuffer::GetDesc failed with hr = %08x\n", This, hr);
3718 LeaveCriticalSection(&ddraw_cs);
3721 stride = get_flexible_vertex_size(Desc.FVF);
3723 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
3724 vb->wineD3DVertexDeclaration);
3727 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr);
3728 LeaveCriticalSection(&ddraw_cs);
3732 /* Set the vertex stream source */
3733 hr = IWineD3DDevice_SetStreamSource(This->wineD3DDevice,
3734 0 /* StreamNumber */,
3735 vb->wineD3DVertexBuffer,
3736 0 /* StartVertex - we pass this to DrawPrimitive */,
3740 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This, hr);
3741 LeaveCriticalSection(&ddraw_cs);
3745 /* Now draw the primitives */
3746 hr = IWineD3DDevice_DrawPrimitive(This->wineD3DDevice,
3750 LeaveCriticalSection(&ddraw_cs);
3754 static HRESULT WINAPI
3755 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB(IDirect3DDevice3 *iface,
3756 D3DPRIMITIVETYPE PrimitiveType,
3757 IDirect3DVertexBuffer *D3DVertexBuf,
3762 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3763 IDirect3DVertexBufferImpl *vb = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, D3DVertexBuf);
3764 TRACE_(ddraw_thunk)("(%p)->(%08x,%p,%08x,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, vb, StartVertex, NumVertices, Flags);
3765 return IDirect3DDevice7_DrawPrimitiveVB(ICOM_INTERFACE(This, IDirect3DDevice7),
3767 ICOM_INTERFACE(vb, IDirect3DVertexBuffer7),
3774 /*****************************************************************************
3775 * IDirect3DDevice7::DrawIndexedPrimitiveVB
3777 * Draws primitives from a vertex buffer to the screen
3780 * PrimitiveType: Type of primitive to be rendered.
3781 * D3DVertexBuf: Source Vertex Buffer
3782 * StartVertex: Index of the first vertex from the buffer to be rendered
3783 * NumVertices: Number of vertices to be rendered
3784 * Indices: Array of DWORDs used to index into the Vertices
3785 * IndexCount: Number of indices in Indices
3786 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
3790 *****************************************************************************/
3791 static HRESULT WINAPI
3792 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(IDirect3DDevice7 *iface,
3793 D3DPRIMITIVETYPE PrimitiveType,
3794 IDirect3DVertexBuffer7 *D3DVertexBuf,
3801 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3802 IDirect3DVertexBufferImpl *vb = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, D3DVertexBuf);
3804 UINT PrimitiveCount;
3805 WORD *LockedIndices;
3807 WINED3DVERTEXBUFFER_DESC Desc;
3809 TRACE("(%p)->(%08x,%p,%d,%d,%p,%d,%08x)\n", This, PrimitiveType, vb, StartVertex, NumVertices, Indices, IndexCount, Flags);
3812 * 1) Calculate some things: Vertex count -> Primitive count, stride, ...
3813 * 2) Upload the Indices to the index buffer
3814 * 3) Set the index source
3815 * 4) Set the Vertex Buffer as the Stream source
3816 * 5) Call IWineD3DDevice::DrawIndexedPrimitive
3819 /* Get the primitive count */
3820 switch(PrimitiveType)
3822 case D3DPT_POINTLIST:
3823 PrimitiveCount = IndexCount;
3826 case D3DPT_LINELIST:
3827 PrimitiveCount = IndexCount / 2;
3830 case D3DPT_LINESTRIP:
3831 PrimitiveCount = IndexCount - 1;
3834 case D3DPT_TRIANGLELIST:
3835 PrimitiveCount = IndexCount / 3;
3838 case D3DPT_TRIANGLESTRIP:
3839 PrimitiveCount = IndexCount - 2;
3842 case D3DPT_TRIANGLEFAN:
3843 PrimitiveCount = IndexCount - 2;
3846 default: return DDERR_INVALIDPARAMS;
3849 EnterCriticalSection(&ddraw_cs);
3850 /* Get the FVF of the vertex buffer, and its stride */
3851 hr = IWineD3DVertexBuffer_GetDesc(vb->wineD3DVertexBuffer,
3855 ERR("(%p) IWineD3DVertexBuffer::GetDesc failed with hr = %08x\n", This, hr);
3856 LeaveCriticalSection(&ddraw_cs);
3859 stride = get_flexible_vertex_size(Desc.FVF);
3860 TRACE("Vertex buffer FVF = %08x, stride=%d\n", Desc.FVF, stride);
3862 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
3863 vb->wineD3DVertexDeclaration);
3866 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr);
3867 LeaveCriticalSection(&ddraw_cs);
3871 /* copy the index stream into the index buffer.
3872 * A new IWineD3DDevice method could be created
3873 * which takes an user pointer containing the indices
3874 * or a SetData-Method for the index buffer, which
3875 * overrides the index buffer data with our pointer.
3877 hr = IWineD3DIndexBuffer_Lock(This->indexbuffer,
3878 0 /* OffSetToLock */,
3879 IndexCount * sizeof(WORD),
3880 (BYTE **) &LockedIndices,
3882 assert(IndexCount < 0x100000);
3885 ERR("(%p) IWineD3DIndexBuffer::Lock failed with hr = %08x\n", This, hr);
3886 LeaveCriticalSection(&ddraw_cs);
3889 memcpy(LockedIndices, Indices, IndexCount * sizeof(WORD));
3890 hr = IWineD3DIndexBuffer_Unlock(This->indexbuffer);
3893 ERR("(%p) IWineD3DIndexBuffer::Unlock failed with hr = %08x\n", This, hr);
3894 LeaveCriticalSection(&ddraw_cs);
3898 /* Set the index stream */
3899 hr = IWineD3DDevice_SetIndices(This->wineD3DDevice,
3903 /* Set the vertex stream source */
3904 hr = IWineD3DDevice_SetStreamSource(This->wineD3DDevice,
3905 0 /* StreamNumber */,
3906 vb->wineD3DVertexBuffer,
3907 0 /* offset, we pass this to DrawIndexedPrimitive */,
3911 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This, hr);
3912 LeaveCriticalSection(&ddraw_cs);
3917 hr = IWineD3DDevice_DrawIndexedPrimitive(This->wineD3DDevice,
3924 LeaveCriticalSection(&ddraw_cs);
3928 static HRESULT WINAPI
3929 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB(IDirect3DDevice3 *iface,
3930 D3DPRIMITIVETYPE PrimitiveType,
3931 IDirect3DVertexBuffer *D3DVertexBuf,
3936 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3937 IDirect3DVertexBufferImpl *VB = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, D3DVertexBuf);
3938 TRACE_(ddraw_thunk)("(%p)->(%08x,%p,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VB, Indices, IndexCount, Flags);
3940 return IDirect3DDevice7_DrawIndexedPrimitiveVB(ICOM_INTERFACE(This, IDirect3DDevice7),
3942 ICOM_INTERFACE(VB, IDirect3DVertexBuffer7),
3950 /*****************************************************************************
3951 * IDirect3DDevice7::ComputeSphereVisibility
3953 * Calculates the visibility of spheres in the current viewport. The spheres
3954 * are passed in the Centers and Radii arrays, the results are passed back
3955 * in the ReturnValues array. Return values are either completely visible,
3956 * partially visible or completely invisible.
3957 * The return value consist of a combination of D3DCLIP_* flags, or it's
3958 * 0 if the sphere is completely visible(according to the SDK, not checked)
3960 * Sounds like an overdose of math ;)
3965 * Centers: Array containing the sphere centers
3966 * Radii: Array containing the sphere radii
3967 * NumSpheres: The number of centers and radii in the arrays
3969 * ReturnValues: Array to write the results to
3972 * D3D_OK because it's a stub
3973 * (DDERR_INVALIDPARAMS if Centers, Radii or ReturnValues are NULL)
3974 * (D3DERR_INVALIDMATRIX if the combined world, view and proj matrix
3977 *****************************************************************************/
3978 static HRESULT WINAPI
3979 IDirect3DDeviceImpl_7_ComputeSphereVisibility(IDirect3DDevice7 *iface,
3984 DWORD *ReturnValues)
3986 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3987 FIXME("(%p)->(%p,%p,%08x,%08x,%p): stub!\n", This, Centers, Radii, NumSpheres, Flags, ReturnValues);
3989 /* the DirectX 7 sdk says that the visibility is computed by
3990 * back-transforming the viewing frustum to model space
3991 * using the inverse of the combined world, view and projection
3992 * matrix. If the matrix can't be reversed, D3DERR_INVALIDMATRIX
3995 * Basic implementation idea:
3996 * 1) Check if the center is in the viewing frustum
3997 * 2) Cut the sphere with the planes of the viewing
4000 * ->Center inside the frustum, no intersections:
4002 * ->Center outside the frustum, no intersections:
4004 * ->Some intersections: Partially visible
4006 * Implement this call in WineD3D. Either implement the
4007 * matrix and vector stuff in WineD3D, or use some external
4014 static HRESULT WINAPI
4015 Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility(IDirect3DDevice3 *iface,
4020 DWORD *ReturnValues)
4022 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4023 TRACE_(ddraw_thunk)("(%p)->(%p,%p,%08x,%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, Centers, Radii, NumSpheres, Flags, ReturnValues);
4024 return IDirect3DDevice7_ComputeSphereVisibility(ICOM_INTERFACE(This, IDirect3DDevice7),
4032 /*****************************************************************************
4033 * IDirect3DDevice7::GetTexture
4035 * Returns the texture interface handle assigned to a texture stage.
4036 * The returned texture is AddRefed. This is taken from old ddraw,
4037 * not checked in Windows.
4042 * Stage: Texture stage to read the texture from
4043 * Texture: Address to store the interface pointer at
4047 * DDERR_INVALIDPARAMS if Texture is NULL
4048 * For details, see IWineD3DDevice::GetTexture
4050 *****************************************************************************/
4051 static HRESULT WINAPI
4052 IDirect3DDeviceImpl_7_GetTexture(IDirect3DDevice7 *iface,
4054 IDirectDrawSurface7 **Texture)
4056 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4057 IWineD3DBaseTexture *Surf;
4059 TRACE("(%p)->(%d,%p): Relay\n", This, Stage, Texture);
4063 TRACE("Texture == NULL, failing with DDERR_INVALIDPARAMS\n");
4064 return DDERR_INVALIDPARAMS;
4067 EnterCriticalSection(&ddraw_cs);
4068 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice, Stage, (IWineD3DBaseTexture **) &Surf);
4069 if( (hr != D3D_OK) || (!Surf) )
4072 LeaveCriticalSection(&ddraw_cs);
4076 /* GetParent AddRef()s, which is perfectly OK.
4077 * We have passed the IDirectDrawSurface7 interface to WineD3D, so that's OK too.
4079 hr = IWineD3DBaseTexture_GetParent(Surf,
4080 (IUnknown **) Texture);
4081 LeaveCriticalSection(&ddraw_cs);
4085 static HRESULT WINAPI
4086 Thunk_IDirect3DDeviceImpl_3_GetTexture(IDirect3DDevice3 *iface,
4088 IDirect3DTexture2 **Texture2)
4090 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4092 IDirectDrawSurface7 *ret_val;
4094 TRACE_(ddraw_thunk)("(%p)->(%d,%p) thunking to IDirect3DDevice7 interface.\n", This, Stage, Texture2);
4095 ret = IDirect3DDevice7_GetTexture(ICOM_INTERFACE(This, IDirect3DDevice7),
4099 *Texture2 = COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7, IDirect3DTexture2, ret_val);
4101 TRACE_(ddraw_thunk)(" returning interface %p.\n", *Texture2);
4106 /*****************************************************************************
4107 * IDirect3DDevice7::SetTexture
4109 * Assigns a texture to a texture stage. Is the texture AddRef-ed?
4114 * Stage: The stage to assign the texture to
4115 * Texture: Interface pointer to the texture surface
4119 * For details, see IWineD3DDevice::SetTexture
4121 *****************************************************************************/
4122 static HRESULT WINAPI
4123 IDirect3DDeviceImpl_7_SetTexture(IDirect3DDevice7 *iface,
4125 IDirectDrawSurface7 *Texture)
4127 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4128 IDirectDrawSurfaceImpl *surf = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, Texture);
4130 TRACE("(%p)->(%08x,%p): Relay!\n", This, Stage, surf);
4132 /* Texture may be NULL here */
4133 EnterCriticalSection(&ddraw_cs);
4134 hr = IWineD3DDevice_SetTexture(This->wineD3DDevice,
4136 surf ? surf->wineD3DTexture : NULL);
4137 LeaveCriticalSection(&ddraw_cs);
4141 static HRESULT WINAPI
4142 Thunk_IDirect3DDeviceImpl_3_SetTexture(IDirect3DDevice3 *iface,
4144 IDirect3DTexture2 *Texture2)
4146 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4147 IDirectDrawSurfaceImpl *tex = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture2, Texture2);
4148 TRACE_(ddraw_thunk)("(%p)->(%d,%p) thunking to IDirect3DDevice7 interface.\n", This, Stage, tex);
4149 return IDirect3DDevice7_SetTexture(ICOM_INTERFACE(This, IDirect3DDevice7),
4151 ICOM_INTERFACE(tex, IDirectDrawSurface7));
4154 /*****************************************************************************
4155 * IDirect3DDevice7::GetTextureStageState
4157 * Retrieves a state from a texture stage.
4162 * Stage: The stage to retrieve the state from
4163 * TexStageStateType: The state type to retrieve
4164 * State: Address to store the state's value at
4168 * DDERR_INVALIDPARAMS if State is NULL
4169 * For details, see IWineD3DDevice::GetTextureStageState
4171 *****************************************************************************/
4172 static HRESULT WINAPI
4173 IDirect3DDeviceImpl_7_GetTextureStageState(IDirect3DDevice7 *iface,
4175 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4178 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4180 TRACE("(%p)->(%08x,%08x,%p): Relay!\n", This, Stage, TexStageStateType, State);
4183 return DDERR_INVALIDPARAMS;
4185 EnterCriticalSection(&ddraw_cs);
4186 switch(TexStageStateType)
4188 /* Mipfilter is a sampler state with different values */
4189 case D3DTSS_MIPFILTER:
4191 WINED3DTEXTUREFILTERTYPE value;
4193 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
4195 WINED3DSAMP_MIPFILTER,
4199 case WINED3DTEXF_NONE: *State = D3DTFP_NONE; break;
4200 case WINED3DTEXF_POINT: *State = D3DTFP_POINT; break;
4201 case WINED3DTEXF_LINEAR: *State = D3DTFP_LINEAR; break;
4203 ERR("Unexpected mipfilter value %d\n", value);
4204 *State = D3DTFP_NONE;
4209 /* Minfilter is a sampler state too, equal values */
4210 case D3DTSS_MINFILTER:
4211 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
4213 WINED3DSAMP_MINFILTER,
4217 /* Magfilter has slightly different values */
4218 case D3DTSS_MAGFILTER:
4220 WINED3DTEXTUREFILTERTYPE wined3dfilter;
4221 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
4223 WINED3DSAMP_MAGFILTER,
4225 switch(wined3dfilter)
4227 case WINED3DTEXF_POINT: *State = D3DTFG_POINT; break;
4228 case WINED3DTEXF_LINEAR: *State = D3DTFG_LINEAR; break;
4229 case WINED3DTEXF_ANISOTROPIC: *State = D3DTFG_ANISOTROPIC; break;
4230 case WINED3DTEXF_FLATCUBIC: *State = D3DTFG_FLATCUBIC; break;
4231 case WINED3DTEXF_GAUSSIANCUBIC: *State = D3DTFG_GAUSSIANCUBIC; break;
4233 ERR("Unexpected wined3d mag filter value %d\n", wined3dfilter);
4234 *State = D3DTFG_POINT;
4239 case D3DTSS_ADDRESS:
4240 case D3DTSS_ADDRESSU:
4241 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
4243 WINED3DSAMP_ADDRESSU,
4246 case D3DTSS_ADDRESSV:
4247 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
4249 WINED3DSAMP_ADDRESSV,
4253 hr = IWineD3DDevice_GetTextureStageState(This->wineD3DDevice,
4259 LeaveCriticalSection(&ddraw_cs);
4263 static HRESULT WINAPI
4264 Thunk_IDirect3DDeviceImpl_3_GetTextureStageState(IDirect3DDevice3 *iface,
4266 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4269 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4270 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, Stage, TexStageStateType, State);
4271 return IDirect3DDevice7_GetTextureStageState(ICOM_INTERFACE(This, IDirect3DDevice7),
4277 /*****************************************************************************
4278 * IDirect3DDevice7::SetTextureStageState
4280 * Sets a texture stage state. Some stage types need to be handled specially,
4281 * because they do not exist in WineD3D and were moved to another place
4286 * Stage: The stage to modify
4287 * TexStageStateType: The state to change
4288 * State: The new value for the state
4292 * For details, see IWineD3DDevice::SetTextureStageState
4294 *****************************************************************************/
4295 static HRESULT WINAPI
4296 IDirect3DDeviceImpl_7_SetTextureStageState(IDirect3DDevice7 *iface,
4298 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4301 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4303 TRACE("(%p)->(%08x,%08x,%08x): Relay!\n", This, Stage, TexStageStateType, State);
4305 EnterCriticalSection(&ddraw_cs);
4306 switch(TexStageStateType)
4308 /* Mipfilter is a sampler state with different values */
4309 case D3DTSS_MIPFILTER:
4311 WINED3DTEXTUREFILTERTYPE value;
4314 case D3DTFP_NONE: value = WINED3DTEXF_NONE; break;
4315 case D3DTFP_POINT: value = WINED3DTEXF_POINT; break;
4316 case 0: /* Unchecked */
4317 case D3DTFP_LINEAR: value = WINED3DTEXF_LINEAR; break;
4319 ERR("Unexpected mipfilter value %d\n", State);
4320 value = WINED3DTEXF_NONE;
4322 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
4324 WINED3DSAMP_MIPFILTER,
4329 /* Minfilter is a sampler state too, equal values */
4330 case D3DTSS_MINFILTER:
4331 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
4333 WINED3DSAMP_MINFILTER,
4337 /* Magfilter has slightly different values */
4338 case D3DTSS_MAGFILTER:
4340 WINED3DTEXTUREFILTERTYPE wined3dfilter;
4341 switch((D3DTEXTUREMAGFILTER) State)
4343 case D3DTFG_POINT: wined3dfilter = WINED3DTEXF_POINT; break;
4344 case D3DTFG_LINEAR: wined3dfilter = WINED3DTEXF_LINEAR; break;
4345 case D3DTFG_FLATCUBIC: wined3dfilter = WINED3DTEXF_FLATCUBIC; break;
4346 case D3DTFG_GAUSSIANCUBIC: wined3dfilter = WINED3DTEXF_GAUSSIANCUBIC; break;
4347 case D3DTFG_ANISOTROPIC: wined3dfilter = WINED3DTEXF_ANISOTROPIC; break;
4349 ERR("Unexpected d3d7 mag filter type %d\n", State);
4350 wined3dfilter = WINED3DTEXF_POINT;
4352 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
4354 WINED3DSAMP_MAGFILTER,
4359 case D3DTSS_ADDRESS:
4360 IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
4362 WINED3DSAMP_ADDRESSV,
4365 case D3DTSS_ADDRESSU:
4366 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
4368 WINED3DSAMP_ADDRESSU,
4372 case D3DTSS_ADDRESSV:
4373 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
4375 WINED3DSAMP_ADDRESSV,
4380 hr = IWineD3DDevice_SetTextureStageState(This->wineD3DDevice,
4386 LeaveCriticalSection(&ddraw_cs);
4390 static HRESULT WINAPI
4391 Thunk_IDirect3DDeviceImpl_3_SetTextureStageState(IDirect3DDevice3 *iface,
4393 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4396 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4397 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, Stage, TexStageStateType, State);
4398 return IDirect3DDevice7_SetTextureStageState(ICOM_INTERFACE(This, IDirect3DDevice7),
4404 /*****************************************************************************
4405 * IDirect3DDevice7::ValidateDevice
4407 * SDK: "Reports the device's ability to render the currently set
4408 * texture-blending operations in a single pass". Whatever that means
4414 * NumPasses: Address to write the number of necessary passes for the
4415 * desired effect to.
4419 * See IWineD3DDevice::ValidateDevice for more details
4421 *****************************************************************************/
4422 static HRESULT WINAPI
4423 IDirect3DDeviceImpl_7_ValidateDevice(IDirect3DDevice7 *iface,
4426 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4428 TRACE("(%p)->(%p): Relay\n", This, NumPasses);
4430 EnterCriticalSection(&ddraw_cs);
4431 hr = IWineD3DDevice_ValidateDevice(This->wineD3DDevice, NumPasses);
4432 LeaveCriticalSection(&ddraw_cs);
4436 static HRESULT WINAPI
4437 Thunk_IDirect3DDeviceImpl_3_ValidateDevice(IDirect3DDevice3 *iface,
4440 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4441 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Passes);
4442 return IDirect3DDevice7_ValidateDevice(ICOM_INTERFACE(This, IDirect3DDevice7),
4446 /*****************************************************************************
4447 * IDirect3DDevice7::Clear
4449 * Fills the render target, the z buffer and the stencil buffer with a
4450 * clear color / value
4455 * Count: Number of rectangles in Rects must be 0 if Rects is NULL
4456 * Rects: Rectangles to clear. If NULL, the whole surface is cleared
4457 * Flags: Some flags, as usual
4458 * Color: Clear color for the render target
4459 * Z: Clear value for the Z buffer
4460 * Stencil: Clear value to store in each stencil buffer entry
4464 * For details, see IWineD3DDevice::Clear
4466 *****************************************************************************/
4467 static HRESULT WINAPI
4468 IDirect3DDeviceImpl_7_Clear(IDirect3DDevice7 *iface,
4476 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4478 TRACE("(%p)->(%08x,%p,%08x,%08x,%f,%08x): Relay\n", This, Count, Rects, Flags, (DWORD) Color, Z, Stencil);
4480 /* Note; D3DRECT is compatible with WINED3DRECT */
4481 EnterCriticalSection(&ddraw_cs);
4482 hr = IWineD3DDevice_Clear(This->wineD3DDevice, Count, (WINED3DRECT*) Rects, Flags, Color, Z, Stencil);
4483 LeaveCriticalSection(&ddraw_cs);
4487 /*****************************************************************************
4488 * IDirect3DDevice7::SetViewport
4490 * Sets the current viewport.
4492 * Version 7 only, but IDirect3DViewport uses this call for older
4496 * Data: The new viewport to set
4500 * DDERR_INVALIDPARAMS if Data is NULL
4501 * For more details, see IWineDDDevice::SetViewport
4503 *****************************************************************************/
4504 static HRESULT WINAPI
4505 IDirect3DDeviceImpl_7_SetViewport(IDirect3DDevice7 *iface,
4508 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4510 TRACE("(%p)->(%p) Relay!\n", This, Data);
4513 return DDERR_INVALIDPARAMS;
4515 /* Note: D3DVIEWPORT7 is compatible with WINED3DVIEWPORT */
4516 EnterCriticalSection(&ddraw_cs);
4517 hr = IWineD3DDevice_SetViewport(This->wineD3DDevice,
4518 (WINED3DVIEWPORT*) Data);
4519 LeaveCriticalSection(&ddraw_cs);
4523 /*****************************************************************************
4524 * IDirect3DDevice::GetViewport
4526 * Returns the current viewport
4531 * Data: D3D7Viewport structure to write the viewport information to
4535 * DDERR_INVALIDPARAMS if Data is NULL
4536 * For more details, see IWineD3DDevice::GetViewport
4538 *****************************************************************************/
4539 static HRESULT WINAPI
4540 IDirect3DDeviceImpl_7_GetViewport(IDirect3DDevice7 *iface,
4543 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4545 TRACE("(%p)->(%p) Relay!\n", This, Data);
4548 return DDERR_INVALIDPARAMS;
4550 /* Note: D3DVIEWPORT7 is compatible with WINED3DVIEWPORT */
4551 EnterCriticalSection(&ddraw_cs);
4552 hr = IWineD3DDevice_GetViewport(This->wineD3DDevice,
4553 (WINED3DVIEWPORT*) Data);
4555 LeaveCriticalSection(&ddraw_cs);
4556 return hr_ddraw_from_wined3d(hr);
4559 /*****************************************************************************
4560 * IDirect3DDevice7::SetMaterial
4567 * Mat: The material to set
4571 * DDERR_INVALIDPARAMS if Mat is NULL.
4572 * For more details, see IWineD3DDevice::SetMaterial
4574 *****************************************************************************/
4575 static HRESULT WINAPI
4576 IDirect3DDeviceImpl_7_SetMaterial(IDirect3DDevice7 *iface,
4579 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4581 TRACE("(%p)->(%p): Relay!\n", This, Mat);
4583 /* Note: D3DMATERIAL7 is compatible with WINED3DMATERIAL */
4584 EnterCriticalSection(&ddraw_cs);
4585 hr = IWineD3DDevice_SetMaterial(This->wineD3DDevice,
4586 (WINED3DMATERIAL*) Mat);
4587 LeaveCriticalSection(&ddraw_cs);
4588 return hr_ddraw_from_wined3d(hr);
4591 /*****************************************************************************
4592 * IDirect3DDevice7::GetMaterial
4594 * Returns the current material
4599 * Mat: D3DMATERIAL7 structure to write the material parameters to
4603 * DDERR_INVALIDPARAMS if Mat is NULL
4604 * For more details, see IWineD3DDevice::GetMaterial
4606 *****************************************************************************/
4607 static HRESULT WINAPI
4608 IDirect3DDeviceImpl_7_GetMaterial(IDirect3DDevice7 *iface,
4611 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4613 TRACE("(%p)->(%p): Relay!\n", This, Mat);
4615 EnterCriticalSection(&ddraw_cs);
4616 /* Note: D3DMATERIAL7 is compatible with WINED3DMATERIAL */
4617 hr = IWineD3DDevice_GetMaterial(This->wineD3DDevice,
4618 (WINED3DMATERIAL*) Mat);
4619 LeaveCriticalSection(&ddraw_cs);
4620 return hr_ddraw_from_wined3d(hr);
4623 /*****************************************************************************
4624 * IDirect3DDevice7::SetLight
4626 * Assigns a light to a light index, but doesn't activate it yet.
4628 * Version 7, IDirect3DLight uses this method for older versions
4631 * LightIndex: The index of the new light
4632 * Light: A D3DLIGHT7 structure describing the light
4636 * For more details, see IWineD3DDevice::SetLight
4638 *****************************************************************************/
4639 static HRESULT WINAPI
4640 IDirect3DDeviceImpl_7_SetLight(IDirect3DDevice7 *iface,
4644 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4646 TRACE("(%p)->(%08x,%p): Relay!\n", This, LightIndex, Light);
4648 EnterCriticalSection(&ddraw_cs);
4649 /* Note: D3DLIGHT7 is compatible with WINED3DLIGHT */
4650 hr = IWineD3DDevice_SetLight(This->wineD3DDevice,
4652 (WINED3DLIGHT*) Light);
4653 LeaveCriticalSection(&ddraw_cs);
4654 return hr_ddraw_from_wined3d(hr);
4657 /*****************************************************************************
4658 * IDirect3DDevice7::GetLight
4660 * Returns the light assigned to a light index
4663 * Light: Structure to write the light information to
4667 * DDERR_INVALIDPARAMS if Light is NULL
4668 * For details, see IWineD3DDevice::GetLight
4670 *****************************************************************************/
4671 static HRESULT WINAPI
4672 IDirect3DDeviceImpl_7_GetLight(IDirect3DDevice7 *iface,
4676 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4678 TRACE("(%p)->(%08x,%p): Relay!\n", This, LightIndex, Light);
4680 EnterCriticalSection(&ddraw_cs);
4681 /* Note: D3DLIGHT7 is compatible with WINED3DLIGHT */
4682 rc = IWineD3DDevice_GetLight(This->wineD3DDevice,
4684 (WINED3DLIGHT*) Light);
4686 /* Translate the result. WineD3D returns other values than D3D7 */
4687 LeaveCriticalSection(&ddraw_cs);
4688 return hr_ddraw_from_wined3d(rc);
4691 /*****************************************************************************
4692 * IDirect3DDevice7::BeginStateBlock
4694 * Begins recording to a stateblock
4700 * For details see IWineD3DDevice::BeginStateBlock
4702 *****************************************************************************/
4703 static HRESULT WINAPI
4704 IDirect3DDeviceImpl_7_BeginStateBlock(IDirect3DDevice7 *iface)
4706 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4708 TRACE("(%p)->(): Relay!\n", This);
4710 EnterCriticalSection(&ddraw_cs);
4711 hr = IWineD3DDevice_BeginStateBlock(This->wineD3DDevice);
4712 LeaveCriticalSection(&ddraw_cs);
4713 return hr_ddraw_from_wined3d(hr);
4716 /*****************************************************************************
4717 * IDirect3DDevice7::EndStateBlock
4719 * Stops recording to a state block and returns the created stateblock
4725 * BlockHandle: Address to store the stateblock's handle to
4729 * DDERR_INVALIDPARAMS if BlockHandle is NULL
4730 * See IWineD3DDevice::EndStateBlock for more details
4732 *****************************************************************************/
4733 static HRESULT WINAPI
4734 IDirect3DDeviceImpl_7_EndStateBlock(IDirect3DDevice7 *iface,
4737 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4739 TRACE("(%p)->(%p): Relay!\n", This, BlockHandle);
4743 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
4744 return DDERR_INVALIDPARAMS;
4747 EnterCriticalSection(&ddraw_cs);
4748 *BlockHandle = IDirect3DDeviceImpl_CreateHandle(This);
4751 ERR("Cannot get a handle number for the stateblock\n");
4752 LeaveCriticalSection(&ddraw_cs);
4753 return DDERR_OUTOFMEMORY;
4755 This->Handles[*BlockHandle - 1].type = DDrawHandle_StateBlock;
4756 hr = IWineD3DDevice_EndStateBlock(This->wineD3DDevice,
4757 (IWineD3DStateBlock **) &This->Handles[*BlockHandle - 1].ptr);
4758 LeaveCriticalSection(&ddraw_cs);
4759 return hr_ddraw_from_wined3d(hr);
4762 /*****************************************************************************
4763 * IDirect3DDevice7::PreLoad
4765 * Allows the app to signal that a texture will be used soon, to allow
4766 * the Direct3DDevice to load it to the video card in the meantime.
4771 * Texture: The texture to preload
4775 * DDERR_INVALIDPARAMS if Texture is NULL
4776 * See IWineD3DSurface::PreLoad for details
4778 *****************************************************************************/
4779 static HRESULT WINAPI
4780 IDirect3DDeviceImpl_7_PreLoad(IDirect3DDevice7 *iface,
4781 IDirectDrawSurface7 *Texture)
4783 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4784 IDirectDrawSurfaceImpl *surf = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, Texture);
4786 TRACE("(%p)->(%p): Relay!\n", This, surf);
4789 return DDERR_INVALIDPARAMS;
4791 EnterCriticalSection(&ddraw_cs);
4792 IWineD3DSurface_PreLoad(surf->WineD3DSurface);
4793 LeaveCriticalSection(&ddraw_cs);
4797 /*****************************************************************************
4798 * IDirect3DDevice7::ApplyStateBlock
4800 * Activates the state stored in a state block handle.
4803 * BlockHandle: The stateblock handle to activate
4807 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
4809 *****************************************************************************/
4810 static HRESULT WINAPI
4811 IDirect3DDeviceImpl_7_ApplyStateBlock(IDirect3DDevice7 *iface,
4814 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4816 TRACE("(%p)->(%08x): Relay!\n", This, BlockHandle);
4818 EnterCriticalSection(&ddraw_cs);
4819 if(!BlockHandle || BlockHandle > This->numHandles)
4821 WARN("Out of range handle %d, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
4822 LeaveCriticalSection(&ddraw_cs);
4823 return D3DERR_INVALIDSTATEBLOCK;
4825 if(This->Handles[BlockHandle - 1].type != DDrawHandle_StateBlock)
4827 WARN("Handle %d is not a stateblock, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
4828 LeaveCriticalSection(&ddraw_cs);
4829 return D3DERR_INVALIDSTATEBLOCK;
4832 hr = IWineD3DStateBlock_Apply((IWineD3DStateBlock *) This->Handles[BlockHandle - 1].ptr);
4833 LeaveCriticalSection(&ddraw_cs);
4834 return hr_ddraw_from_wined3d(hr);
4837 /*****************************************************************************
4838 * IDirect3DDevice7::CaptureStateBlock
4840 * Updates a stateblock's values to the values currently set for the device
4845 * BlockHandle: Stateblock to update
4849 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
4850 * See IWineD3DDevice::CaptureStateBlock for more details
4852 *****************************************************************************/
4853 static HRESULT WINAPI
4854 IDirect3DDeviceImpl_7_CaptureStateBlock(IDirect3DDevice7 *iface,
4857 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4859 TRACE("(%p)->(%08x): Relay!\n", This, BlockHandle);
4861 EnterCriticalSection(&ddraw_cs);
4862 if(BlockHandle == 0 || BlockHandle > This->numHandles)
4864 WARN("Out of range handle %d, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
4865 LeaveCriticalSection(&ddraw_cs);
4866 return D3DERR_INVALIDSTATEBLOCK;
4868 if(This->Handles[BlockHandle - 1].type != DDrawHandle_StateBlock)
4870 WARN("Handle %d is not a stateblock, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
4871 LeaveCriticalSection(&ddraw_cs);
4872 return D3DERR_INVALIDSTATEBLOCK;
4875 hr = IWineD3DStateBlock_Capture((IWineD3DStateBlock *) This->Handles[BlockHandle - 1].ptr);
4876 LeaveCriticalSection(&ddraw_cs);
4877 return hr_ddraw_from_wined3d(hr);
4880 /*****************************************************************************
4881 * IDirect3DDevice7::DeleteStateBlock
4883 * Deletes a stateblock handle. This means releasing the WineD3DStateBlock
4888 * BlockHandle: Stateblock handle to delete
4892 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is 0
4894 *****************************************************************************/
4895 static HRESULT WINAPI
4896 IDirect3DDeviceImpl_7_DeleteStateBlock(IDirect3DDevice7 *iface,
4899 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4901 TRACE("(%p)->(%08x): Relay!\n", This, BlockHandle);
4903 EnterCriticalSection(&ddraw_cs);
4904 if(BlockHandle == 0 || BlockHandle > This->numHandles)
4906 WARN("Out of range handle %d, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
4907 LeaveCriticalSection(&ddraw_cs);
4908 return D3DERR_INVALIDSTATEBLOCK;
4910 if(This->Handles[BlockHandle - 1].type != DDrawHandle_StateBlock)
4912 WARN("Handle %d is not a stateblock, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
4913 LeaveCriticalSection(&ddraw_cs);
4914 return D3DERR_INVALIDSTATEBLOCK;
4917 ref = IWineD3DStateBlock_Release((IWineD3DStateBlock *) This->Handles[BlockHandle - 1].ptr);
4920 ERR("Something is still holding the stateblock %p(Handle %d). Ref = %d\n", This->Handles[BlockHandle - 1].ptr, BlockHandle, ref);
4922 This->Handles[BlockHandle - 1].ptr = NULL;
4923 This->Handles[BlockHandle - 1].type = DDrawHandle_Unknown;
4925 LeaveCriticalSection(&ddraw_cs);
4929 /*****************************************************************************
4930 * IDirect3DDevice7::CreateStateBlock
4932 * Creates a new state block handle.
4937 * Type: The state block type
4938 * BlockHandle: Address to write the created handle to
4942 * DDERR_INVALIDPARAMS if BlockHandle is NULL
4944 *****************************************************************************/
4945 static HRESULT WINAPI
4946 IDirect3DDeviceImpl_7_CreateStateBlock(IDirect3DDevice7 *iface,
4947 D3DSTATEBLOCKTYPE Type,
4950 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4952 TRACE("(%p)->(%08x,%p)!\n", This, Type, BlockHandle);
4956 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
4957 return DDERR_INVALIDPARAMS;
4960 EnterCriticalSection(&ddraw_cs);
4961 *BlockHandle = IDirect3DDeviceImpl_CreateHandle(This);
4964 ERR("Cannot get a handle number for the stateblock\n");
4965 LeaveCriticalSection(&ddraw_cs);
4966 return DDERR_OUTOFMEMORY;
4968 This->Handles[*BlockHandle - 1].type = DDrawHandle_StateBlock;
4970 /* The D3DSTATEBLOCKTYPE enum is fine here */
4971 hr = IWineD3DDevice_CreateStateBlock(This->wineD3DDevice,
4973 (IWineD3DStateBlock **) &This->Handles[*BlockHandle - 1].ptr,
4974 NULL /* Parent, hope that works */);
4975 LeaveCriticalSection(&ddraw_cs);
4976 return hr_ddraw_from_wined3d(hr);
4979 /*****************************************************************************
4980 * IDirect3DDevice7::Load
4982 * Loads a rectangular area from the source into the destination texture.
4983 * It can also copy the source to the faces of a cubic environment map
4988 * DestTex: Destination texture
4989 * DestPoint: Point in the destination where the source image should be
4991 * SrcTex: Source texture
4992 * SrcRect: Source rectangle
4997 * DDERR_INVALIDPARAMS if DestTex or SrcTex are NULL
4998 * See IDirect3DTexture2::Load for details
5000 *****************************************************************************/
5001 static HRESULT WINAPI
5002 IDirect3DDeviceImpl_7_Load(IDirect3DDevice7 *iface,
5003 IDirectDrawSurface7 *DestTex,
5005 IDirectDrawSurface7 *SrcTex,
5009 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5010 IDirectDrawSurfaceImpl *dest = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, DestTex);
5011 IDirectDrawSurfaceImpl *src = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, SrcTex);
5012 FIXME("(%p)->(%p,%p,%p,%p,%08x): Partially Implemented!\n", This, dest, DestPoint, src, SrcRect, Flags);
5014 if( (!src) || (!dest) )
5015 return DDERR_INVALIDPARAMS;
5017 IDirect3DTexture2_Load(ICOM_INTERFACE(dest, IDirect3DTexture2),
5018 ICOM_INTERFACE(src, IDirect3DTexture2));
5022 /*****************************************************************************
5023 * IDirect3DDevice7::LightEnable
5025 * Enables or disables a light
5027 * Version 7, IDirect3DLight uses this method too.
5030 * LightIndex: The index of the light to enable / disable
5031 * Enable: Enable or disable the light
5035 * For more details, see IWineD3DDevice::SetLightEnable
5037 *****************************************************************************/
5038 static HRESULT WINAPI
5039 IDirect3DDeviceImpl_7_LightEnable(IDirect3DDevice7 *iface,
5043 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5045 TRACE("(%p)->(%08x,%d): Relay!\n", This, LightIndex, Enable);
5047 EnterCriticalSection(&ddraw_cs);
5048 hr = IWineD3DDevice_SetLightEnable(This->wineD3DDevice, LightIndex, Enable);
5049 LeaveCriticalSection(&ddraw_cs);
5050 return hr_ddraw_from_wined3d(hr);
5053 /*****************************************************************************
5054 * IDirect3DDevice7::GetLightEnable
5056 * Retrieves if the light with the given index is enabled or not
5061 * LightIndex: Index of desired light
5062 * Enable: Pointer to a BOOL which contains the result
5066 * DDERR_INVALIDPARAMS if Enable is NULL
5067 * See IWineD3DDevice::GetLightEnable for more details
5069 *****************************************************************************/
5070 static HRESULT WINAPI
5071 IDirect3DDeviceImpl_7_GetLightEnable(IDirect3DDevice7 *iface,
5075 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5077 TRACE("(%p)->(%08x,%p): Relay\n", This, LightIndex, Enable);
5080 return DDERR_INVALIDPARAMS;
5082 EnterCriticalSection(&ddraw_cs);
5083 hr = IWineD3DDevice_GetLightEnable(This->wineD3DDevice, LightIndex, Enable);
5084 LeaveCriticalSection(&ddraw_cs);
5085 return hr_ddraw_from_wined3d(hr);
5088 /*****************************************************************************
5089 * IDirect3DDevice7::SetClipPlane
5091 * Sets custom clipping plane
5096 * Index: The index of the clipping plane
5097 * PlaneEquation: An equation defining the clipping plane
5101 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
5102 * See IWineD3DDevice::SetClipPlane for more details
5104 *****************************************************************************/
5105 static HRESULT WINAPI
5106 IDirect3DDeviceImpl_7_SetClipPlane(IDirect3DDevice7 *iface,
5108 D3DVALUE* PlaneEquation)
5110 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5112 TRACE("(%p)->(%08x,%p): Relay!\n", This, Index, PlaneEquation);
5115 return DDERR_INVALIDPARAMS;
5117 EnterCriticalSection(&ddraw_cs);
5118 hr = IWineD3DDevice_SetClipPlane(This->wineD3DDevice, Index, PlaneEquation);
5119 LeaveCriticalSection(&ddraw_cs);
5123 /*****************************************************************************
5124 * IDirect3DDevice7::GetClipPlane
5126 * Returns the clipping plane with a specific index
5129 * Index: The index of the desired plane
5130 * PlaneEquation: Address to store the plane equation to
5134 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
5135 * See IWineD3DDevice::GetClipPlane for more details
5137 *****************************************************************************/
5138 static HRESULT WINAPI
5139 IDirect3DDeviceImpl_7_GetClipPlane(IDirect3DDevice7 *iface,
5141 D3DVALUE* PlaneEquation)
5143 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5145 TRACE("(%p)->(%d,%p): Relay!\n", This, Index, PlaneEquation);
5148 return DDERR_INVALIDPARAMS;
5150 EnterCriticalSection(&ddraw_cs);
5151 hr = IWineD3DDevice_GetClipPlane(This->wineD3DDevice, Index, PlaneEquation);
5152 LeaveCriticalSection(&ddraw_cs);
5156 /*****************************************************************************
5157 * IDirect3DDevice7::GetInfo
5159 * Retrieves some information about the device. The DirectX sdk says that
5160 * this version returns S_FALSE for all retail builds of DirectX, that's what
5161 * this implementation does.
5164 * DevInfoID: Information type requested
5165 * DevInfoStruct: Pointer to a structure to store the info to
5166 * Size: Size of the structure
5169 * S_FALSE, because it's a non-debug driver
5171 *****************************************************************************/
5172 static HRESULT WINAPI
5173 IDirect3DDeviceImpl_7_GetInfo(IDirect3DDevice7 *iface,
5175 void *DevInfoStruct,
5178 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5179 TRACE("(%p)->(%08x,%p,%08x)\n", This, DevInfoID, DevInfoStruct, Size);
5183 TRACE(" info requested : ");
5186 case D3DDEVINFOID_TEXTUREMANAGER: TRACE("D3DDEVINFOID_TEXTUREMANAGER\n"); break;
5187 case D3DDEVINFOID_D3DTEXTUREMANAGER: TRACE("D3DDEVINFOID_D3DTEXTUREMANAGER\n"); break;
5188 case D3DDEVINFOID_TEXTURING: TRACE("D3DDEVINFOID_TEXTURING\n"); break;
5189 default: ERR(" invalid flag !!!\n"); return DDERR_INVALIDPARAMS;
5193 return S_FALSE; /* According to MSDN, this is valid for a non-debug driver */
5196 const IDirect3DDevice7Vtbl IDirect3DDevice7_Vtbl =
5198 /*** IUnknown Methods ***/
5199 IDirect3DDeviceImpl_7_QueryInterface,
5200 IDirect3DDeviceImpl_7_AddRef,
5201 IDirect3DDeviceImpl_7_Release,
5202 /*** IDirect3DDevice7 ***/
5203 IDirect3DDeviceImpl_7_GetCaps,
5204 IDirect3DDeviceImpl_7_EnumTextureFormats,
5205 IDirect3DDeviceImpl_7_BeginScene,
5206 IDirect3DDeviceImpl_7_EndScene,
5207 IDirect3DDeviceImpl_7_GetDirect3D,
5208 IDirect3DDeviceImpl_7_SetRenderTarget,
5209 IDirect3DDeviceImpl_7_GetRenderTarget,
5210 IDirect3DDeviceImpl_7_Clear,
5211 IDirect3DDeviceImpl_7_SetTransform,
5212 IDirect3DDeviceImpl_7_GetTransform,
5213 IDirect3DDeviceImpl_7_SetViewport,
5214 IDirect3DDeviceImpl_7_MultiplyTransform,
5215 IDirect3DDeviceImpl_7_GetViewport,
5216 IDirect3DDeviceImpl_7_SetMaterial,
5217 IDirect3DDeviceImpl_7_GetMaterial,
5218 IDirect3DDeviceImpl_7_SetLight,
5219 IDirect3DDeviceImpl_7_GetLight,
5220 IDirect3DDeviceImpl_7_SetRenderState,
5221 IDirect3DDeviceImpl_7_GetRenderState,
5222 IDirect3DDeviceImpl_7_BeginStateBlock,
5223 IDirect3DDeviceImpl_7_EndStateBlock,
5224 IDirect3DDeviceImpl_7_PreLoad,
5225 IDirect3DDeviceImpl_7_DrawPrimitive,
5226 IDirect3DDeviceImpl_7_DrawIndexedPrimitive,
5227 IDirect3DDeviceImpl_7_SetClipStatus,
5228 IDirect3DDeviceImpl_7_GetClipStatus,
5229 IDirect3DDeviceImpl_7_DrawPrimitiveStrided,
5230 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided,
5231 IDirect3DDeviceImpl_7_DrawPrimitiveVB,
5232 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB,
5233 IDirect3DDeviceImpl_7_ComputeSphereVisibility,
5234 IDirect3DDeviceImpl_7_GetTexture,
5235 IDirect3DDeviceImpl_7_SetTexture,
5236 IDirect3DDeviceImpl_7_GetTextureStageState,
5237 IDirect3DDeviceImpl_7_SetTextureStageState,
5238 IDirect3DDeviceImpl_7_ValidateDevice,
5239 IDirect3DDeviceImpl_7_ApplyStateBlock,
5240 IDirect3DDeviceImpl_7_CaptureStateBlock,
5241 IDirect3DDeviceImpl_7_DeleteStateBlock,
5242 IDirect3DDeviceImpl_7_CreateStateBlock,
5243 IDirect3DDeviceImpl_7_Load,
5244 IDirect3DDeviceImpl_7_LightEnable,
5245 IDirect3DDeviceImpl_7_GetLightEnable,
5246 IDirect3DDeviceImpl_7_SetClipPlane,
5247 IDirect3DDeviceImpl_7_GetClipPlane,
5248 IDirect3DDeviceImpl_7_GetInfo
5251 const IDirect3DDevice3Vtbl IDirect3DDevice3_Vtbl =
5253 /*** IUnknown Methods ***/
5254 Thunk_IDirect3DDeviceImpl_3_QueryInterface,
5255 Thunk_IDirect3DDeviceImpl_3_AddRef,
5256 Thunk_IDirect3DDeviceImpl_3_Release,
5257 /*** IDirect3DDevice3 ***/
5258 IDirect3DDeviceImpl_3_GetCaps,
5259 IDirect3DDeviceImpl_3_GetStats,
5260 IDirect3DDeviceImpl_3_AddViewport,
5261 IDirect3DDeviceImpl_3_DeleteViewport,
5262 IDirect3DDeviceImpl_3_NextViewport,
5263 Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats,
5264 Thunk_IDirect3DDeviceImpl_3_BeginScene,
5265 Thunk_IDirect3DDeviceImpl_3_EndScene,
5266 Thunk_IDirect3DDeviceImpl_3_GetDirect3D,
5267 IDirect3DDeviceImpl_3_SetCurrentViewport,
5268 IDirect3DDeviceImpl_3_GetCurrentViewport,
5269 Thunk_IDirect3DDeviceImpl_3_SetRenderTarget,
5270 Thunk_IDirect3DDeviceImpl_3_GetRenderTarget,
5271 IDirect3DDeviceImpl_3_Begin,
5272 IDirect3DDeviceImpl_3_BeginIndexed,
5273 IDirect3DDeviceImpl_3_Vertex,
5274 IDirect3DDeviceImpl_3_Index,
5275 IDirect3DDeviceImpl_3_End,
5276 Thunk_IDirect3DDeviceImpl_3_GetRenderState,
5277 Thunk_IDirect3DDeviceImpl_3_SetRenderState,
5278 IDirect3DDeviceImpl_3_GetLightState,
5279 IDirect3DDeviceImpl_3_SetLightState,
5280 Thunk_IDirect3DDeviceImpl_3_SetTransform,
5281 Thunk_IDirect3DDeviceImpl_3_GetTransform,
5282 Thunk_IDirect3DDeviceImpl_3_MultiplyTransform,
5283 Thunk_IDirect3DDeviceImpl_3_DrawPrimitive,
5284 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive,
5285 Thunk_IDirect3DDeviceImpl_3_SetClipStatus,
5286 Thunk_IDirect3DDeviceImpl_3_GetClipStatus,
5287 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided,
5288 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided,
5289 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB,
5290 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB,
5291 Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility,
5292 Thunk_IDirect3DDeviceImpl_3_GetTexture,
5293 Thunk_IDirect3DDeviceImpl_3_SetTexture,
5294 Thunk_IDirect3DDeviceImpl_3_GetTextureStageState,
5295 Thunk_IDirect3DDeviceImpl_3_SetTextureStageState,
5296 Thunk_IDirect3DDeviceImpl_3_ValidateDevice
5299 const IDirect3DDevice2Vtbl IDirect3DDevice2_Vtbl =
5301 /*** IUnknown Methods ***/
5302 Thunk_IDirect3DDeviceImpl_2_QueryInterface,
5303 Thunk_IDirect3DDeviceImpl_2_AddRef,
5304 Thunk_IDirect3DDeviceImpl_2_Release,
5305 /*** IDirect3DDevice2 ***/
5306 Thunk_IDirect3DDeviceImpl_2_GetCaps,
5307 IDirect3DDeviceImpl_2_SwapTextureHandles,
5308 Thunk_IDirect3DDeviceImpl_2_GetStats,
5309 Thunk_IDirect3DDeviceImpl_2_AddViewport,
5310 Thunk_IDirect3DDeviceImpl_2_DeleteViewport,
5311 Thunk_IDirect3DDeviceImpl_2_NextViewport,
5312 IDirect3DDeviceImpl_2_EnumTextureFormats,
5313 Thunk_IDirect3DDeviceImpl_2_BeginScene,
5314 Thunk_IDirect3DDeviceImpl_2_EndScene,
5315 Thunk_IDirect3DDeviceImpl_2_GetDirect3D,
5316 Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport,
5317 Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport,
5318 Thunk_IDirect3DDeviceImpl_2_SetRenderTarget,
5319 Thunk_IDirect3DDeviceImpl_2_GetRenderTarget,
5320 Thunk_IDirect3DDeviceImpl_2_Begin,
5321 Thunk_IDirect3DDeviceImpl_2_BeginIndexed,
5322 Thunk_IDirect3DDeviceImpl_2_Vertex,
5323 Thunk_IDirect3DDeviceImpl_2_Index,
5324 Thunk_IDirect3DDeviceImpl_2_End,
5325 Thunk_IDirect3DDeviceImpl_2_GetRenderState,
5326 Thunk_IDirect3DDeviceImpl_2_SetRenderState,
5327 Thunk_IDirect3DDeviceImpl_2_GetLightState,
5328 Thunk_IDirect3DDeviceImpl_2_SetLightState,
5329 Thunk_IDirect3DDeviceImpl_2_SetTransform,
5330 Thunk_IDirect3DDeviceImpl_2_GetTransform,
5331 Thunk_IDirect3DDeviceImpl_2_MultiplyTransform,
5332 Thunk_IDirect3DDeviceImpl_2_DrawPrimitive,
5333 Thunk_IDirect3DDeviceImpl_2_DrawIndexedPrimitive,
5334 Thunk_IDirect3DDeviceImpl_2_SetClipStatus,
5335 Thunk_IDirect3DDeviceImpl_2_GetClipStatus
5338 const IDirect3DDeviceVtbl IDirect3DDevice1_Vtbl =
5340 /*** IUnknown Methods ***/
5341 Thunk_IDirect3DDeviceImpl_1_QueryInterface,
5342 Thunk_IDirect3DDeviceImpl_1_AddRef,
5343 Thunk_IDirect3DDeviceImpl_1_Release,
5344 /*** IDirect3DDevice1 ***/
5345 IDirect3DDeviceImpl_1_Initialize,
5346 Thunk_IDirect3DDeviceImpl_1_GetCaps,
5347 Thunk_IDirect3DDeviceImpl_1_SwapTextureHandles,
5348 IDirect3DDeviceImpl_1_CreateExecuteBuffer,
5349 Thunk_IDirect3DDeviceImpl_1_GetStats,
5350 IDirect3DDeviceImpl_1_Execute,
5351 Thunk_IDirect3DDeviceImpl_1_AddViewport,
5352 Thunk_IDirect3DDeviceImpl_1_DeleteViewport,
5353 Thunk_IDirect3DDeviceImpl_1_NextViewport,
5354 IDirect3DDeviceImpl_1_Pick,
5355 IDirect3DDeviceImpl_1_GetPickRecords,
5356 Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats,
5357 IDirect3DDeviceImpl_1_CreateMatrix,
5358 IDirect3DDeviceImpl_1_SetMatrix,
5359 IDirect3DDeviceImpl_1_GetMatrix,
5360 IDirect3DDeviceImpl_1_DeleteMatrix,
5361 Thunk_IDirect3DDeviceImpl_1_EndScene,
5362 Thunk_IDirect3DDeviceImpl_1_BeginScene,
5363 Thunk_IDirect3DDeviceImpl_1_GetDirect3D
5366 /*****************************************************************************
5367 * IDirect3DDeviceImpl_CreateHandle
5369 * Not called from the VTable
5371 * Some older interface versions operate with handles, which are basically
5372 * DWORDs which identify an interface, for example
5373 * IDirect3DDevice::SetRenderState with DIRECT3DRENDERSTATE_TEXTUREHANDLE
5375 * Those handle could be just casts to the interface pointers or vice versa,
5376 * but that is not 64 bit safe and would mean blindly derefering a DWORD
5377 * passed by the app. Instead there is a dynamic array in the device which
5378 * keeps a DWORD to pointer information and a type for the handle.
5380 * Basically this array only grows, when a handle is freed its pointer is
5381 * just set to NULL. There will be much more reads from the array than
5382 * insertion operations, so a dynamic array is fine.
5385 * This: D3DDevice implementation for which this handle should be created
5388 * A free handle on success
5391 *****************************************************************************/
5393 IDirect3DDeviceImpl_CreateHandle(IDirect3DDeviceImpl *This)
5396 struct HandleEntry *oldHandles = This->Handles;
5398 TRACE("(%p)\n", This);
5400 for(i = 0; i < This->numHandles; i++)
5402 if(This->Handles[i].ptr == NULL &&
5403 This->Handles[i].type == DDrawHandle_Unknown)
5405 TRACE("Reusing freed handle %d\n", i + 1);
5410 TRACE("Growing the handle array\n");
5413 This->Handles = HeapAlloc(GetProcessHeap(), 0, sizeof(struct HandleEntry) * This->numHandles);
5416 ERR("Out of memory\n");
5417 This->Handles = oldHandles;
5423 memcpy(This->Handles, oldHandles, (This->numHandles - 1) * sizeof(struct HandleEntry));
5424 HeapFree(GetProcessHeap(), 0, oldHandles);
5427 TRACE("Returning %d\n", This->numHandles);
5428 return This->numHandles;
5431 /*****************************************************************************
5432 * IDirect3DDeviceImpl_UpdateDepthStencil
5434 * Checks the current render target for attached depth stencils and sets the
5435 * WineD3D depth stencil accordingly.
5438 * The depth stencil state to set if creating the device
5440 *****************************************************************************/
5442 IDirect3DDeviceImpl_UpdateDepthStencil(IDirect3DDeviceImpl *This)
5444 IDirectDrawSurface7 *depthStencil = NULL;
5445 IDirectDrawSurfaceImpl *dsi;
5446 static DDSCAPS2 depthcaps = { DDSCAPS_ZBUFFER, 0, 0, 0 };
5448 IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(This->target, IDirectDrawSurface7),
5453 TRACE("Setting wined3d depth stencil to NULL\n");
5454 IWineD3DDevice_SetDepthStencilSurface(This->wineD3DDevice,
5456 return WINED3DZB_FALSE;
5459 dsi = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, depthStencil);
5460 TRACE("Setting wined3d depth stencil to %p (wined3d %p)\n", dsi, dsi->WineD3DSurface);
5461 IWineD3DDevice_SetDepthStencilSurface(This->wineD3DDevice,
5462 dsi->WineD3DSurface);
5464 IDirectDrawSurface7_Release(depthStencil);
5465 return WINED3DZB_TRUE;