2 * Copyright (c) 1998-2004 Lionel Ulmer
3 * Copyright (c) 2002-2005 Christian Costa
4 * Copyright (c) 2006 Stefan Dösinger
5 * Copyright (c) 2008 Alexander Dorofeyev
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 * IDirect3DDevice implementation, version 1, 2, 3 and 7. Rendering is relayed
22 * to WineD3D, some minimal DirectDraw specific management is handled here.
23 * The Direct3DDevice is NOT the parent of the WineD3DDevice, because d3d
24 * is initialized when DirectDraw creates the primary surface.
25 * Some type management is necessary, because some D3D types changed between
31 #include "wine/port.h"
39 #define NONAMELESSUNION
45 #include "wine/exception.h"
50 #include "ddraw_private.h"
51 #include "wine/debug.h"
53 WINE_DEFAULT_DEBUG_CHANNEL(d3d7);
54 WINE_DECLARE_DEBUG_CHANNEL(ddraw_thunk);
57 const GUID IID_D3DDEVICE_WineD3D = {
61 { 0xb7,0x98,0xc6,0x8a,0x77,0x2d,0x72,0x2a }
64 /*****************************************************************************
65 * IUnknown Methods. Common for Version 1, 2, 3 and 7
66 *****************************************************************************/
68 /*****************************************************************************
69 * IDirect3DDevice7::QueryInterface
71 * Used to query other interfaces from a Direct3DDevice interface.
72 * It can return interface pointers to all Direct3DDevice versions as well
73 * as IDirectDraw and IDirect3D. For a link to QueryInterface
74 * rules see ddraw.c, IDirectDraw7::QueryInterface
76 * Exists in Version 1, 2, 3 and 7
79 * refiid: Interface ID queried for
80 * obj: Used to return the interface pointer
83 * D3D_OK or E_NOINTERFACE
85 *****************************************************************************/
87 IDirect3DDeviceImpl_7_QueryInterface(IDirect3DDevice7 *iface,
91 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
92 TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(refiid), obj);
94 /* According to COM docs, if the QueryInterface fails, obj should be set to NULL */
98 return DDERR_INVALIDPARAMS;
100 if ( IsEqualGUID( &IID_IUnknown, refiid ) )
102 *obj = ICOM_INTERFACE(This, IDirect3DDevice7);
105 /* Check DirectDraw Interfac
\ 1s */
106 else if( IsEqualGUID( &IID_IDirectDraw7, refiid ) )
108 *obj = ICOM_INTERFACE(This->ddraw, IDirectDraw7);
109 TRACE("(%p) Returning IDirectDraw7 interface at %p\n", This, *obj);
111 else if ( IsEqualGUID( &IID_IDirectDraw4, refiid ) )
113 *obj = ICOM_INTERFACE(This->ddraw, IDirectDraw4);
114 TRACE("(%p) Returning IDirectDraw4 interface at %p\n", This, *obj);
116 else if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) )
118 *obj = ICOM_INTERFACE(This->ddraw, IDirectDraw2);
119 TRACE("(%p) Returning IDirectDraw2 interface at %p\n", This, *obj);
121 else if( IsEqualGUID( &IID_IDirectDraw, refiid ) )
123 *obj = ICOM_INTERFACE(This->ddraw, IDirectDraw);
124 TRACE("(%p) Returning IDirectDraw interface at %p\n", This, *obj);
128 else if ( IsEqualGUID( &IID_IDirect3D , refiid ) )
130 *obj = ICOM_INTERFACE(This->ddraw, IDirect3D);
131 TRACE("(%p) Returning IDirect3D interface at %p\n", This, *obj);
133 else if ( IsEqualGUID( &IID_IDirect3D2 , refiid ) )
135 *obj = ICOM_INTERFACE(This->ddraw, IDirect3D2);
136 TRACE("(%p) Returning IDirect3D2 interface at %p\n", This, *obj);
138 else if ( IsEqualGUID( &IID_IDirect3D3 , refiid ) )
140 *obj = ICOM_INTERFACE(This->ddraw, IDirect3D3);
141 TRACE("(%p) Returning IDirect3D3 interface at %p\n", This, *obj);
143 else if ( IsEqualGUID( &IID_IDirect3D7 , refiid ) )
145 *obj = ICOM_INTERFACE(This->ddraw, IDirect3D7);
146 TRACE("(%p) Returning IDirect3D7 interface at %p\n", This, *obj);
150 else if ( IsEqualGUID( &IID_IDirect3DDevice , refiid ) )
152 *obj = ICOM_INTERFACE(This, IDirect3DDevice);
153 TRACE("(%p) Returning IDirect3DDevice interface at %p\n", This, *obj);
155 else if ( IsEqualGUID( &IID_IDirect3DDevice2 , refiid ) ) {
156 *obj = ICOM_INTERFACE(This, IDirect3DDevice2);
157 TRACE("(%p) Returning IDirect3DDevice2 interface at %p\n", This, *obj);
159 else if ( IsEqualGUID( &IID_IDirect3DDevice3 , refiid ) ) {
160 *obj = ICOM_INTERFACE(This, IDirect3DDevice3);
161 TRACE("(%p) Returning IDirect3DDevice3 interface at %p\n", This, *obj);
163 else if ( IsEqualGUID( &IID_IDirect3DDevice7 , refiid ) ) {
164 *obj = ICOM_INTERFACE(This, IDirect3DDevice7);
165 TRACE("(%p) Returning IDirect3DDevice7 interface at %p\n", This, *obj);
168 /* Unknown interface */
171 ERR("(%p)->(%s, %p): No interface found\n", This, debugstr_guid(refiid), obj);
172 return E_NOINTERFACE;
175 /* AddRef the returned interface */
176 IUnknown_AddRef( (IUnknown *) *obj);
180 static HRESULT WINAPI
181 Thunk_IDirect3DDeviceImpl_3_QueryInterface(IDirect3DDevice3 *iface,
185 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
186 TRACE_(ddraw_thunk)("(%p)->(%s,%p) thunking to IDirect3DDevice7 interface.\n", This, debugstr_guid(riid), obj);
187 return IDirect3DDevice7_QueryInterface(ICOM_INTERFACE(This, IDirect3DDevice7),
192 static HRESULT WINAPI
193 Thunk_IDirect3DDeviceImpl_2_QueryInterface(IDirect3DDevice2 *iface,
197 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
198 TRACE_(ddraw_thunk)("(%p)->(%s,%p) thunking to IDirect3DDevice7 interface.\n", This, debugstr_guid(riid), obj);
199 return IDirect3DDevice7_QueryInterface(ICOM_INTERFACE(This, IDirect3DDevice7),
204 static HRESULT WINAPI
205 Thunk_IDirect3DDeviceImpl_1_QueryInterface(IDirect3DDevice *iface,
209 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
210 TRACE_(ddraw_thunk)("(%p)->(%s,%p) thunking to IDirect3DDevice7 interface.\n", This, debugstr_guid(riid), obp);
211 return IDirect3DDevice7_QueryInterface(ICOM_INTERFACE(This, IDirect3DDevice7),
216 /*****************************************************************************
217 * IDirect3DDevice7::AddRef
219 * Increases the refcount....
220 * The most exciting Method, definitely
222 * Exists in Version 1, 2, 3 and 7
227 *****************************************************************************/
229 IDirect3DDeviceImpl_7_AddRef(IDirect3DDevice7 *iface)
231 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
232 ULONG ref = InterlockedIncrement(&This->ref);
234 TRACE("(%p) : incrementing from %u.\n", This, ref -1);
240 Thunk_IDirect3DDeviceImpl_3_AddRef(IDirect3DDevice3 *iface)
242 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
243 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
244 return IDirect3DDevice7_AddRef(ICOM_INTERFACE(This, IDirect3DDevice7));
248 Thunk_IDirect3DDeviceImpl_2_AddRef(IDirect3DDevice2 *iface)
250 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
251 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
252 return IDirect3DDevice7_AddRef(ICOM_INTERFACE(This, IDirect3DDevice7));
256 Thunk_IDirect3DDeviceImpl_1_AddRef(IDirect3DDevice *iface)
258 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", iface);
259 return IDirect3DDevice7_AddRef(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice7, iface));
262 /*****************************************************************************
263 * IDirect3DDevice7::Release
265 * Decreases the refcount of the interface
266 * When the refcount is reduced to 0, the object is destroyed.
268 * Exists in Version 1, 2, 3 and 7
273 *****************************************************************************/
275 IDirect3DDeviceImpl_7_Release(IDirect3DDevice7 *iface)
277 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
278 ULONG ref = InterlockedDecrement(&This->ref);
280 TRACE("(%p)->() decrementing from %u.\n", This, ref +1);
282 /* This method doesn't destroy the WineD3DDevice, because it's still in use for
283 * 2D rendering. IDirectDrawSurface7::Release will destroy the WineD3DDevice
284 * when the render target is released
288 IParent *IndexBufferParent;
291 EnterCriticalSection(&ddraw_cs);
292 /* Free the index buffer. */
293 IWineD3DDevice_SetIndices(This->wineD3DDevice, NULL);
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 unexpectedly. 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 hardware 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, IDirect3DDevice, 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 amount 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 vp->active_device = This; /* Viewport must be usable for Clear() after AddViewport,
822 so set active_device here. */
823 LeaveCriticalSection(&ddraw_cs);
828 static HRESULT WINAPI
829 Thunk_IDirect3DDeviceImpl_2_AddViewport(IDirect3DDevice2 *iface,
830 IDirect3DViewport2 *Direct3DViewport2)
832 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
833 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport2);
834 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
835 return IDirect3DDevice3_AddViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
836 ICOM_INTERFACE(vp, IDirect3DViewport3));
839 static HRESULT WINAPI
840 Thunk_IDirect3DDeviceImpl_1_AddViewport(IDirect3DDevice *iface,
841 IDirect3DViewport *Direct3DViewport)
843 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
844 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport);
845 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
846 return IDirect3DDevice3_AddViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
847 ICOM_INTERFACE(vp, IDirect3DViewport3));
850 /*****************************************************************************
851 * IDirect3DDevice3::DeleteViewport
853 * Deletes a Direct3DViewport from the device's viewport list.
855 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
859 * Viewport: The viewport to delete
863 * DDERR_INVALIDPARAMS if the viewport wasn't found in the list
865 *****************************************************************************/
866 static HRESULT WINAPI
867 IDirect3DDeviceImpl_3_DeleteViewport(IDirect3DDevice3 *iface,
868 IDirect3DViewport3 *Viewport)
870 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
871 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *) Viewport;
872 IDirect3DViewportImpl *cur_viewport, *prev_viewport = NULL;
874 TRACE("(%p)->(%p)\n", This, vp);
876 EnterCriticalSection(&ddraw_cs);
877 cur_viewport = This->viewport_list;
878 while (cur_viewport != NULL)
880 if (cur_viewport == vp)
882 if (prev_viewport == NULL) This->viewport_list = cur_viewport->next;
883 else prev_viewport->next = cur_viewport->next;
884 /* TODO : add desactivate of the viewport and all associated lights... */
885 LeaveCriticalSection(&ddraw_cs);
888 prev_viewport = cur_viewport;
889 cur_viewport = cur_viewport->next;
892 LeaveCriticalSection(&ddraw_cs);
893 return DDERR_INVALIDPARAMS;
896 static HRESULT WINAPI
897 Thunk_IDirect3DDeviceImpl_2_DeleteViewport(IDirect3DDevice2 *iface,
898 IDirect3DViewport2 *Direct3DViewport2)
900 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
901 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport2);
902 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
903 return IDirect3DDevice3_DeleteViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
904 ICOM_INTERFACE(vp, IDirect3DViewport3));
907 static HRESULT WINAPI
908 Thunk_IDirect3DDeviceImpl_1_DeleteViewport(IDirect3DDevice *iface,
909 IDirect3DViewport *Direct3DViewport)
911 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
912 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport);
913 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
914 return IDirect3DDevice3_DeleteViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
915 ICOM_INTERFACE(vp, IDirect3DViewport3));
918 /*****************************************************************************
919 * IDirect3DDevice3::NextViewport
921 * Returns a viewport from the viewport list, depending on the
922 * passed viewport and the flags.
924 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
928 * Viewport: Viewport to use for beginning the search
929 * Flags: D3DNEXT_NEXT, D3DNEXT_HEAD or D3DNEXT_TAIL
933 * DDERR_INVALIDPARAMS if the flags were wrong, or Viewport was NULL
935 *****************************************************************************/
936 static HRESULT WINAPI
937 IDirect3DDeviceImpl_3_NextViewport(IDirect3DDevice3 *iface,
938 IDirect3DViewport3 *Viewport3,
939 IDirect3DViewport3 **lplpDirect3DViewport3,
942 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
943 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport3);
944 IDirect3DViewportImpl *res = NULL;
946 TRACE("(%p)->(%p,%p,%08x)\n", This, vp, lplpDirect3DViewport3, Flags);
950 *lplpDirect3DViewport3 = NULL;
951 return DDERR_INVALIDPARAMS;
955 EnterCriticalSection(&ddraw_cs);
965 res = This->viewport_list;
970 IDirect3DViewportImpl *cur_viewport = This->viewport_list;
971 if (cur_viewport != NULL)
973 while (cur_viewport->next != NULL) cur_viewport = cur_viewport->next;
979 *lplpDirect3DViewport3 = NULL;
980 LeaveCriticalSection(&ddraw_cs);
981 return DDERR_INVALIDPARAMS;
984 *lplpDirect3DViewport3 = ICOM_INTERFACE(res, IDirect3DViewport3);
985 LeaveCriticalSection(&ddraw_cs);
989 static HRESULT WINAPI
990 Thunk_IDirect3DDeviceImpl_2_NextViewport(IDirect3DDevice2 *iface,
991 IDirect3DViewport2 *Viewport2,
992 IDirect3DViewport2 **lplpDirect3DViewport2,
995 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
996 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport2);
997 IDirect3DViewport3 *res;
999 TRACE_(ddraw_thunk)("(%p)->(%p,%p,%08x) thunking to IDirect3DDevice3 interface.\n", This, vp, lplpDirect3DViewport2, Flags);
1000 hr = IDirect3DDevice3_NextViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
1001 ICOM_INTERFACE(vp, IDirect3DViewport3),
1004 *lplpDirect3DViewport2 = (IDirect3DViewport2 *) COM_INTERFACE_CAST(IDirect3DViewportImpl, IDirect3DViewport3, IDirect3DViewport3, res);
1008 static HRESULT WINAPI
1009 Thunk_IDirect3DDeviceImpl_1_NextViewport(IDirect3DDevice *iface,
1010 IDirect3DViewport *Viewport,
1011 IDirect3DViewport **lplpDirect3DViewport,
1014 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1015 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport);
1016 IDirect3DViewport3 *res;
1018 TRACE_(ddraw_thunk)("(%p)->(%p,%p,%08x) thunking to IDirect3DDevice3 interface.\n", This, vp, lplpDirect3DViewport, Flags);
1019 hr = IDirect3DDevice3_NextViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
1020 ICOM_INTERFACE(vp, IDirect3DViewport3),
1023 *lplpDirect3DViewport = (IDirect3DViewport *) COM_INTERFACE_CAST(IDirect3DViewportImpl, IDirect3DViewport3, IDirect3DViewport3, res);
1027 /*****************************************************************************
1028 * IDirect3DDevice::Pick
1030 * Executes an execute buffer without performing rendering. Instead, a
1031 * list of primitives that intersect with (x1,y1) of the passed rectangle
1032 * is created. IDirect3DDevice::GetPickRecords can be used to retrieve
1038 * ExecuteBuffer: Buffer to execute
1039 * Viewport: Viewport to use for execution
1040 * Flags: None are defined, according to the SDK
1041 * Rect: Specifies the coordinates to be picked. Only x1 and y2 are used,
1042 * x2 and y2 are ignored.
1045 * D3D_OK because it's a stub
1047 *****************************************************************************/
1048 static HRESULT WINAPI
1049 IDirect3DDeviceImpl_1_Pick(IDirect3DDevice *iface,
1050 IDirect3DExecuteBuffer *ExecuteBuffer,
1051 IDirect3DViewport *Viewport,
1055 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1056 IDirect3DExecuteBufferImpl *execbuf = ICOM_OBJECT(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, ExecuteBuffer);
1057 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport);
1058 FIXME("(%p)->(%p,%p,%08x,%p): stub!\n", This, execbuf, vp, Flags, Rect);
1063 /*****************************************************************************
1064 * IDirect3DDevice::GetPickRecords
1066 * Retrieves the pick records generated by IDirect3DDevice::GetPickRecords
1071 * Count: Pointer to a DWORD containing the numbers of pick records to
1073 * D3DPickRec: Address to store the resulting D3DPICKRECORD array.
1076 * D3D_OK, because it's a stub
1078 *****************************************************************************/
1079 static HRESULT WINAPI
1080 IDirect3DDeviceImpl_1_GetPickRecords(IDirect3DDevice *iface,
1082 D3DPICKRECORD *D3DPickRec)
1084 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1085 FIXME("(%p)->(%p,%p): stub!\n", This, Count, D3DPickRec);
1090 /*****************************************************************************
1091 * IDirect3DDevice7::EnumTextureformats
1093 * Enumerates the supported texture formats. It has a list of all possible
1094 * formats and calls IWineD3D::CheckDeviceFormat for each format to see if
1095 * WineD3D supports it. If so, then it is passed to the app.
1097 * This is for Version 7 and 3, older versions have a different
1098 * callback function and their own implementation
1101 * Callback: Callback to call for each enumerated format
1102 * Arg: Argument to pass to the callback
1106 * DDERR_INVALIDPARAMS if Callback == NULL
1108 *****************************************************************************/
1109 static HRESULT WINAPI
1110 IDirect3DDeviceImpl_7_EnumTextureFormats(IDirect3DDevice7 *iface,
1111 LPD3DENUMPIXELFORMATSCALLBACK Callback,
1114 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1118 WINED3DFORMAT FormatList[] = {
1120 WINED3DFMT_A8R8G8B8,
1121 WINED3DFMT_X8R8G8B8,
1125 WINED3DFMT_A1R5G5B5,
1126 WINED3DFMT_A4R4G4B4,
1128 WINED3DFMT_X1R5G5B5,
1138 WINED3DFORMAT BumpFormatList[] = {
1141 WINED3DFMT_X8L8V8U8,
1142 WINED3DFMT_Q8W8V8U8,
1144 WINED3DFMT_W11V11U10,
1145 WINED3DFMT_A2W10V10U10
1148 TRACE("(%p)->(%p,%p): Relay\n", This, Callback, Arg);
1151 return DDERR_INVALIDPARAMS;
1153 EnterCriticalSection(&ddraw_cs);
1154 for(i = 0; i < sizeof(FormatList) / sizeof(WINED3DFORMAT); i++)
1156 hr = IWineD3D_CheckDeviceFormat(This->ddraw->wineD3D,
1159 0 /* AdapterFormat */,
1161 0 /* ResourceType */,
1165 DDPIXELFORMAT pformat;
1167 memset(&pformat, 0, sizeof(pformat));
1168 pformat.dwSize = sizeof(pformat);
1169 PixelFormat_WineD3DtoDD(&pformat, FormatList[i]);
1171 TRACE("Enumerating WineD3DFormat %d\n", FormatList[i]);
1172 hr = Callback(&pformat, Arg);
1173 if(hr != DDENUMRET_OK)
1175 TRACE("Format enumeration cancelled by application\n");
1176 LeaveCriticalSection(&ddraw_cs);
1182 for(i = 0; i < sizeof(BumpFormatList) / sizeof(WINED3DFORMAT); i++)
1184 hr = IWineD3D_CheckDeviceFormat(This->ddraw->wineD3D,
1187 0 /* AdapterFormat */,
1188 WINED3DUSAGE_QUERY_LEGACYBUMPMAP,
1189 0 /* ResourceType */,
1193 DDPIXELFORMAT pformat;
1195 memset(&pformat, 0, sizeof(pformat));
1196 pformat.dwSize = sizeof(pformat);
1197 PixelFormat_WineD3DtoDD(&pformat, BumpFormatList[i]);
1199 TRACE("Enumerating WineD3DFormat %d\n", BumpFormatList[i]);
1200 hr = Callback(&pformat, Arg);
1201 if(hr != DDENUMRET_OK)
1203 TRACE("Format enumeration cancelled by application\n");
1204 LeaveCriticalSection(&ddraw_cs);
1209 TRACE("End of enumeration\n");
1210 LeaveCriticalSection(&ddraw_cs);
1214 static HRESULT WINAPI
1215 Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats(IDirect3DDevice3 *iface,
1216 LPD3DENUMPIXELFORMATSCALLBACK Callback,
1219 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1220 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice7 interface.\n", This, Callback, Arg);
1221 return IDirect3DDevice7_EnumTextureFormats(ICOM_INTERFACE(This, IDirect3DDevice7),
1226 /*****************************************************************************
1227 * IDirect3DDevice2::EnumTextureformats
1229 * EnumTextureFormats for Version 1 and 2, see
1230 * IDirect3DDevice7::EnumTexureFormats for a more detailed description.
1232 * This version has a different callback and does not enumerate FourCC
1235 *****************************************************************************/
1236 static HRESULT WINAPI
1237 IDirect3DDeviceImpl_2_EnumTextureFormats(IDirect3DDevice2 *iface,
1238 LPD3DENUMTEXTUREFORMATSCALLBACK Callback,
1241 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1245 WINED3DFORMAT FormatList[] = {
1247 WINED3DFMT_A8R8G8B8,
1248 WINED3DFMT_X8R8G8B8,
1252 WINED3DFMT_A1R5G5B5,
1253 WINED3DFMT_A4R4G4B4,
1255 WINED3DFMT_X1R5G5B5,
1259 /* FOURCC codes - Not in this version*/
1262 TRACE("(%p)->(%p,%p): Relay\n", This, Callback, Arg);
1265 return DDERR_INVALIDPARAMS;
1267 EnterCriticalSection(&ddraw_cs);
1268 for(i = 0; i < sizeof(FormatList) / sizeof(WINED3DFORMAT); i++)
1270 hr = IWineD3D_CheckDeviceFormat(This->ddraw->wineD3D,
1273 0 /* AdapterFormat */,
1275 0 /* ResourceType */,
1279 DDSURFACEDESC sdesc;
1281 memset(&sdesc, 0, sizeof(sdesc));
1282 sdesc.dwSize = sizeof(sdesc);
1283 sdesc.dwFlags = DDSD_PIXELFORMAT | DDSD_CAPS;
1284 sdesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1285 sdesc.ddpfPixelFormat.dwSize = sizeof(sdesc.ddpfPixelFormat);
1286 PixelFormat_WineD3DtoDD(&sdesc.ddpfPixelFormat, FormatList[i]);
1288 TRACE("Enumerating WineD3DFormat %d\n", FormatList[i]);
1289 hr = Callback(&sdesc, Arg);
1290 if(hr != DDENUMRET_OK)
1292 TRACE("Format enumeration cancelled by application\n");
1293 LeaveCriticalSection(&ddraw_cs);
1298 TRACE("End of enumeration\n");
1299 LeaveCriticalSection(&ddraw_cs);
1303 static HRESULT WINAPI
1304 Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats(IDirect3DDevice *iface,
1305 LPD3DENUMTEXTUREFORMATSCALLBACK Callback,
1308 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1309 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice2 interface.\n", This, Callback, Arg);
1310 return IDirect3DDevice2_EnumTextureFormats(ICOM_INTERFACE(This, IDirect3DDevice2),
1315 /*****************************************************************************
1316 * IDirect3DDevice::CreateMatrix
1318 * Creates a matrix handle. A handle is created and memory for a D3DMATRIX is
1319 * allocated for the handle.
1324 * D3DMatHandle: Address to return the handle at
1328 * DDERR_INVALIDPARAMS if D3DMatHandle = NULL
1330 *****************************************************************************/
1331 static HRESULT WINAPI
1332 IDirect3DDeviceImpl_1_CreateMatrix(IDirect3DDevice *iface, D3DMATRIXHANDLE *D3DMatHandle)
1334 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1336 TRACE("(%p)->(%p)\n", This, D3DMatHandle);
1339 return DDERR_INVALIDPARAMS;
1341 Matrix = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(D3DMATRIX));
1344 ERR("Out of memory when allocating a D3DMATRIX\n");
1345 return DDERR_OUTOFMEMORY;
1348 EnterCriticalSection(&ddraw_cs);
1349 *D3DMatHandle = IDirect3DDeviceImpl_CreateHandle(This);
1350 if(!(*D3DMatHandle))
1352 ERR("Failed to create a matrix handle\n");
1353 HeapFree(GetProcessHeap(), 0, Matrix);
1354 LeaveCriticalSection(&ddraw_cs);
1355 return DDERR_OUTOFMEMORY;
1357 This->Handles[*D3DMatHandle - 1].ptr = Matrix;
1358 This->Handles[*D3DMatHandle - 1].type = DDrawHandle_Matrix;
1359 TRACE(" returning matrix handle %d\n", *D3DMatHandle);
1361 LeaveCriticalSection(&ddraw_cs);
1365 /*****************************************************************************
1366 * IDirect3DDevice::SetMatrix
1368 * Sets a matrix for a matrix handle. The matrix is copied into the memory
1369 * allocated for the handle
1374 * D3DMatHandle: Handle to set the matrix to
1375 * D3DMatrix: Matrix to set
1379 * DDERR_INVALIDPARAMS if the handle of the matrix is invalid or the matrix
1382 *****************************************************************************/
1383 static HRESULT WINAPI
1384 IDirect3DDeviceImpl_1_SetMatrix(IDirect3DDevice *iface,
1385 D3DMATRIXHANDLE D3DMatHandle,
1386 D3DMATRIX *D3DMatrix)
1388 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1389 TRACE("(%p)->(%08x,%p)\n", This, D3DMatHandle, D3DMatrix);
1391 if( (!D3DMatHandle) || (!D3DMatrix) )
1392 return DDERR_INVALIDPARAMS;
1394 EnterCriticalSection(&ddraw_cs);
1395 if(D3DMatHandle > This->numHandles)
1397 ERR("Handle %d out of range\n", D3DMatHandle);
1398 LeaveCriticalSection(&ddraw_cs);
1399 return DDERR_INVALIDPARAMS;
1401 else if(This->Handles[D3DMatHandle - 1].type != DDrawHandle_Matrix)
1403 ERR("Handle %d is not a matrix handle\n", D3DMatHandle);
1404 LeaveCriticalSection(&ddraw_cs);
1405 return DDERR_INVALIDPARAMS;
1409 dump_D3DMATRIX(D3DMatrix);
1411 *((D3DMATRIX *) This->Handles[D3DMatHandle - 1].ptr) = *D3DMatrix;
1413 if(This->world == D3DMatHandle)
1415 IWineD3DDevice_SetTransform(This->wineD3DDevice,
1416 WINED3DTS_WORLDMATRIX(0),
1417 (WINED3DMATRIX *) D3DMatrix);
1419 if(This->view == D3DMatHandle)
1421 IWineD3DDevice_SetTransform(This->wineD3DDevice,
1423 (WINED3DMATRIX *) D3DMatrix);
1425 if(This->proj == D3DMatHandle)
1427 IWineD3DDevice_SetTransform(This->wineD3DDevice,
1428 WINED3DTS_PROJECTION,
1429 (WINED3DMATRIX *) D3DMatrix);
1432 LeaveCriticalSection(&ddraw_cs);
1436 /*****************************************************************************
1437 * IDirect3DDevice::SetMatrix
1439 * Returns the content of a D3DMATRIX handle
1444 * D3DMatHandle: Matrix handle to read the content from
1445 * D3DMatrix: Address to store the content at
1449 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid or D3DMatrix is NULL
1451 *****************************************************************************/
1452 static HRESULT WINAPI
1453 IDirect3DDeviceImpl_1_GetMatrix(IDirect3DDevice *iface,
1454 D3DMATRIXHANDLE D3DMatHandle,
1455 D3DMATRIX *D3DMatrix)
1457 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1458 TRACE("(%p)->(%08x,%p)\n", This, D3DMatHandle, D3DMatrix);
1461 return DDERR_INVALIDPARAMS;
1463 return DDERR_INVALIDPARAMS;
1465 EnterCriticalSection(&ddraw_cs);
1466 if(D3DMatHandle > This->numHandles)
1468 ERR("Handle %d out of range\n", D3DMatHandle);
1469 LeaveCriticalSection(&ddraw_cs);
1470 return DDERR_INVALIDPARAMS;
1472 else if(This->Handles[D3DMatHandle - 1].type != DDrawHandle_Matrix)
1474 ERR("Handle %d is not a matrix handle\n", D3DMatHandle);
1475 LeaveCriticalSection(&ddraw_cs);
1476 return DDERR_INVALIDPARAMS;
1479 /* The handle is simply a pointer to a D3DMATRIX structure */
1480 *D3DMatrix = *((D3DMATRIX *) This->Handles[D3DMatHandle - 1].ptr);
1482 LeaveCriticalSection(&ddraw_cs);
1486 /*****************************************************************************
1487 * IDirect3DDevice::DeleteMatrix
1489 * Destroys a Matrix handle. Frees the memory and unsets the handle data
1494 * D3DMatHandle: Handle to destroy
1498 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid
1500 *****************************************************************************/
1501 static HRESULT WINAPI
1502 IDirect3DDeviceImpl_1_DeleteMatrix(IDirect3DDevice *iface,
1503 D3DMATRIXHANDLE D3DMatHandle)
1505 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1506 TRACE("(%p)->(%08x)\n", This, D3DMatHandle);
1509 return DDERR_INVALIDPARAMS;
1511 EnterCriticalSection(&ddraw_cs);
1512 if(D3DMatHandle > This->numHandles)
1514 ERR("Handle %d out of range\n", D3DMatHandle);
1515 LeaveCriticalSection(&ddraw_cs);
1516 return DDERR_INVALIDPARAMS;
1518 else if(This->Handles[D3DMatHandle - 1].type != DDrawHandle_Matrix)
1520 ERR("Handle %d is not a matrix handle\n", D3DMatHandle);
1521 LeaveCriticalSection(&ddraw_cs);
1522 return DDERR_INVALIDPARAMS;
1525 HeapFree(GetProcessHeap(), 0, This->Handles[D3DMatHandle - 1].ptr);
1526 This->Handles[D3DMatHandle - 1].ptr = NULL;
1527 This->Handles[D3DMatHandle - 1].type = DDrawHandle_Unknown;
1529 LeaveCriticalSection(&ddraw_cs);
1533 /*****************************************************************************
1534 * IDirect3DDevice7::BeginScene
1536 * This method must be called before any rendering is performed.
1537 * IDirect3DDevice::EndScene has to be called after the scene is complete
1539 * Version 1, 2, 3 and 7
1542 * D3D_OK on success, for details see IWineD3DDevice::BeginScene
1543 * D3DERR_SCENE_IN_SCENE if WineD3D returns an error(Only in case of an already
1546 *****************************************************************************/
1547 static HRESULT WINAPI
1548 IDirect3DDeviceImpl_7_BeginScene(IDirect3DDevice7 *iface)
1550 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1552 TRACE("(%p): Relay\n", This);
1554 EnterCriticalSection(&ddraw_cs);
1555 hr = IWineD3DDevice_BeginScene(This->wineD3DDevice);
1556 LeaveCriticalSection(&ddraw_cs);
1557 if(hr == WINED3D_OK) return D3D_OK;
1558 else return D3DERR_SCENE_IN_SCENE; /* TODO: Other possible causes of failure */
1561 static HRESULT WINAPI
1562 Thunk_IDirect3DDeviceImpl_3_BeginScene(IDirect3DDevice3 *iface)
1564 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1565 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1566 return IDirect3DDevice7_BeginScene(ICOM_INTERFACE(This, IDirect3DDevice7));
1569 static HRESULT WINAPI
1570 Thunk_IDirect3DDeviceImpl_2_BeginScene(IDirect3DDevice2 *iface)
1572 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1573 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1574 return IDirect3DDevice7_BeginScene(ICOM_INTERFACE(This, IDirect3DDevice7));
1577 static HRESULT WINAPI
1578 Thunk_IDirect3DDeviceImpl_1_BeginScene(IDirect3DDevice *iface)
1580 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1581 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1582 return IDirect3DDevice7_BeginScene(ICOM_INTERFACE(This, IDirect3DDevice7));
1585 /*****************************************************************************
1586 * IDirect3DDevice7::EndScene
1588 * Ends a scene that has been begun with IDirect3DDevice7::BeginScene.
1589 * This method must be called after rendering is finished.
1591 * Version 1, 2, 3 and 7
1594 * D3D_OK on success, for details see IWineD3DDevice::EndScene
1595 * D3DERR_SCENE_NOT_IN_SCENE is returned if WineD3D returns an error. It does
1596 * that only if the scene was already ended.
1598 *****************************************************************************/
1599 static HRESULT WINAPI
1600 IDirect3DDeviceImpl_7_EndScene(IDirect3DDevice7 *iface)
1602 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1604 TRACE("(%p): Relay\n", This);
1606 EnterCriticalSection(&ddraw_cs);
1607 hr = IWineD3DDevice_EndScene(This->wineD3DDevice);
1608 LeaveCriticalSection(&ddraw_cs);
1609 if(hr == WINED3D_OK) return D3D_OK;
1610 else return D3DERR_SCENE_NOT_IN_SCENE;
1613 static HRESULT WINAPI
1614 Thunk_IDirect3DDeviceImpl_3_EndScene(IDirect3DDevice3 *iface)
1616 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1617 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1618 return IDirect3DDevice7_EndScene(ICOM_INTERFACE(This, IDirect3DDevice7));
1621 static HRESULT WINAPI
1622 Thunk_IDirect3DDeviceImpl_2_EndScene(IDirect3DDevice2 *iface)
1624 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1625 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1626 return IDirect3DDevice7_EndScene(ICOM_INTERFACE(This, IDirect3DDevice7));
1629 static HRESULT WINAPI
1630 Thunk_IDirect3DDeviceImpl_1_EndScene(IDirect3DDevice *iface)
1632 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1633 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1634 return IDirect3DDevice7_EndScene(ICOM_INTERFACE(This, IDirect3DDevice7));
1637 /*****************************************************************************
1638 * IDirect3DDevice7::GetDirect3D
1640 * Returns the IDirect3D(= interface to the DirectDraw object) used to create
1644 * Direct3D7: Address to store the interface pointer at
1648 * DDERR_INVALIDPARAMS if Direct3D7 == NULL
1650 *****************************************************************************/
1651 static HRESULT WINAPI
1652 IDirect3DDeviceImpl_7_GetDirect3D(IDirect3DDevice7 *iface,
1653 IDirect3D7 **Direct3D7)
1655 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1656 TRACE("(%p)->(%p)\n", This, Direct3D7);
1659 return DDERR_INVALIDPARAMS;
1661 *Direct3D7 = ICOM_INTERFACE(This->ddraw, IDirect3D7);
1662 IDirect3D7_AddRef(*Direct3D7);
1664 TRACE(" returning interface %p\n", *Direct3D7);
1668 static HRESULT WINAPI
1669 Thunk_IDirect3DDeviceImpl_3_GetDirect3D(IDirect3DDevice3 *iface,
1670 IDirect3D3 **Direct3D3)
1672 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1674 IDirect3D7 *ret_ptr;
1676 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Direct3D3);
1677 ret = IDirect3DDevice7_GetDirect3D(ICOM_INTERFACE(This, IDirect3DDevice7),
1681 *Direct3D3 = COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D7, IDirect3D3, ret_ptr);
1682 TRACE(" returning interface %p\n", *Direct3D3);
1686 static HRESULT WINAPI
1687 Thunk_IDirect3DDeviceImpl_2_GetDirect3D(IDirect3DDevice2 *iface,
1688 IDirect3D2 **Direct3D2)
1690 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1692 IDirect3D7 *ret_ptr;
1694 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Direct3D2);
1695 ret = IDirect3DDevice7_GetDirect3D(ICOM_INTERFACE(This, IDirect3DDevice7),
1699 *Direct3D2 = COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D7, IDirect3D2, ret_ptr);
1700 TRACE(" returning interface %p\n", *Direct3D2);
1704 static HRESULT WINAPI
1705 Thunk_IDirect3DDeviceImpl_1_GetDirect3D(IDirect3DDevice *iface,
1706 IDirect3D **Direct3D)
1708 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1710 IDirect3D7 *ret_ptr;
1712 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Direct3D);
1713 ret = IDirect3DDevice7_GetDirect3D(ICOM_INTERFACE(This, IDirect3DDevice7),
1717 *Direct3D = COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D7, IDirect3D, ret_ptr);
1718 TRACE(" returning interface %p\n", *Direct3D);
1722 /*****************************************************************************
1723 * IDirect3DDevice3::SetCurrentViewport
1725 * Sets a Direct3DViewport as the current viewport.
1726 * For the thunks note that all viewport interface versions are equal
1729 * Direct3DViewport3: The viewport to set
1735 * (Is a NULL viewport valid?)
1737 *****************************************************************************/
1738 static HRESULT WINAPI
1739 IDirect3DDeviceImpl_3_SetCurrentViewport(IDirect3DDevice3 *iface,
1740 IDirect3DViewport3 *Direct3DViewport3)
1742 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1743 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport3);
1744 TRACE("(%p)->(%p)\n", This, Direct3DViewport3);
1746 EnterCriticalSection(&ddraw_cs);
1747 /* Do nothing if the specified viewport is the same as the current one */
1748 if (This->current_viewport == vp )
1750 LeaveCriticalSection(&ddraw_cs);
1754 /* Should check if the viewport was added or not */
1756 /* Release previous viewport and AddRef the new one */
1757 if (This->current_viewport)
1759 TRACE("ViewportImpl is at %p, interface is at %p\n", This->current_viewport, ICOM_INTERFACE(This->current_viewport, IDirect3DViewport3));
1760 IDirect3DViewport3_Release( ICOM_INTERFACE(This->current_viewport, IDirect3DViewport3) );
1762 IDirect3DViewport3_AddRef(Direct3DViewport3);
1764 /* Set this viewport as the current viewport */
1765 This->current_viewport = vp;
1767 /* Activate this viewport */
1768 This->current_viewport->active_device = This;
1769 This->current_viewport->activate(This->current_viewport, FALSE);
1771 LeaveCriticalSection(&ddraw_cs);
1775 static HRESULT WINAPI
1776 Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport(IDirect3DDevice2 *iface,
1777 IDirect3DViewport2 *Direct3DViewport2)
1779 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1780 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport2);
1781 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
1782 return IDirect3DDevice3_SetCurrentViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
1783 ICOM_INTERFACE(vp, IDirect3DViewport3));
1786 /*****************************************************************************
1787 * IDirect3DDevice3::GetCurrentViewport
1789 * Returns the currently active viewport.
1794 * Direct3DViewport3: Address to return the interface pointer at
1798 * DDERR_INVALIDPARAMS if Direct3DViewport == NULL
1800 *****************************************************************************/
1801 static HRESULT WINAPI
1802 IDirect3DDeviceImpl_3_GetCurrentViewport(IDirect3DDevice3 *iface,
1803 IDirect3DViewport3 **Direct3DViewport3)
1805 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1806 TRACE("(%p)->(%p)\n", This, Direct3DViewport3);
1808 if(!Direct3DViewport3)
1809 return DDERR_INVALIDPARAMS;
1811 EnterCriticalSection(&ddraw_cs);
1812 *Direct3DViewport3 = ICOM_INTERFACE(This->current_viewport, IDirect3DViewport3);
1814 /* AddRef the returned viewport */
1815 if(*Direct3DViewport3) IDirect3DViewport3_AddRef(*Direct3DViewport3);
1817 TRACE(" returning interface %p\n", *Direct3DViewport3);
1819 LeaveCriticalSection(&ddraw_cs);
1823 static HRESULT WINAPI
1824 Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport(IDirect3DDevice2 *iface,
1825 IDirect3DViewport2 **Direct3DViewport2)
1827 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1829 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, Direct3DViewport2);
1830 hr = IDirect3DDevice3_GetCurrentViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
1831 (IDirect3DViewport3 **) Direct3DViewport2);
1832 if(hr != D3D_OK) return hr;
1833 *Direct3DViewport2 = (IDirect3DViewport2 *) COM_INTERFACE_CAST(IDirect3DViewportImpl, IDirect3DViewport3, IDirect3DViewport3, *Direct3DViewport2);
1837 /*****************************************************************************
1838 * IDirect3DDevice7::SetRenderTarget
1840 * Sets the render target for the Direct3DDevice.
1841 * For the thunks note that IDirectDrawSurface7 == IDirectDrawSurface4 and
1842 * IDirectDrawSurface3 == IDirectDrawSurface
1844 * Version 2, 3 and 7
1847 * NewTarget: Pointer to an IDirectDrawSurface7 interface to set as the new
1852 * D3D_OK on success, for details see IWineD3DDevice::SetRenderTarget
1854 *****************************************************************************/
1855 static HRESULT WINAPI
1856 IDirect3DDeviceImpl_7_SetRenderTarget(IDirect3DDevice7 *iface,
1857 IDirectDrawSurface7 *NewTarget,
1860 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1861 IDirectDrawSurfaceImpl *Target = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, NewTarget);
1863 TRACE("(%p)->(%p,%08x): Relay\n", This, NewTarget, Flags);
1865 EnterCriticalSection(&ddraw_cs);
1866 /* Flags: Not used */
1868 if(This->target == Target)
1870 TRACE("No-op SetRenderTarget operation, not doing anything\n");
1871 LeaveCriticalSection(&ddraw_cs);
1875 hr = IWineD3DDevice_SetRenderTarget(This->wineD3DDevice,
1877 Target ? Target->WineD3DSurface : NULL);
1880 LeaveCriticalSection(&ddraw_cs);
1883 IDirectDrawSurface7_AddRef(NewTarget);
1884 IDirectDrawSurface7_Release(ICOM_INTERFACE(This->target, IDirectDrawSurface7));
1885 This->target = Target;
1886 IDirect3DDeviceImpl_UpdateDepthStencil(This);
1887 LeaveCriticalSection(&ddraw_cs);
1891 static HRESULT WINAPI
1892 Thunk_IDirect3DDeviceImpl_3_SetRenderTarget(IDirect3DDevice3 *iface,
1893 IDirectDrawSurface4 *NewRenderTarget,
1896 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1897 IDirectDrawSurfaceImpl *Target = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, NewRenderTarget);
1898 TRACE_(ddraw_thunk)("(%p)->(%p,%08x) thunking to IDirect3DDevice7 interface.\n", This, Target, Flags);
1899 return IDirect3DDevice7_SetRenderTarget(ICOM_INTERFACE(This, IDirect3DDevice7),
1900 ICOM_INTERFACE(Target, IDirectDrawSurface7),
1904 static HRESULT WINAPI
1905 Thunk_IDirect3DDeviceImpl_2_SetRenderTarget(IDirect3DDevice2 *iface,
1906 IDirectDrawSurface *NewRenderTarget,
1909 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1910 IDirectDrawSurfaceImpl *Target = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface3, NewRenderTarget);
1911 TRACE_(ddraw_thunk)("(%p)->(%p,%08x) thunking to IDirect3DDevice7 interface.\n", This, Target, Flags);
1912 return IDirect3DDevice7_SetRenderTarget(ICOM_INTERFACE(This, IDirect3DDevice7),
1913 ICOM_INTERFACE(Target, IDirectDrawSurface7),
1917 /*****************************************************************************
1918 * IDirect3DDevice7::GetRenderTarget
1920 * Returns the current render target.
1921 * This is handled locally, because the WineD3D render target's parent
1924 * Version 2, 3 and 7
1927 * RenderTarget: Address to store the surface interface pointer
1931 * DDERR_INVALIDPARAMS if RenderTarget == NULL
1933 *****************************************************************************/
1934 static HRESULT WINAPI
1935 IDirect3DDeviceImpl_7_GetRenderTarget(IDirect3DDevice7 *iface,
1936 IDirectDrawSurface7 **RenderTarget)
1938 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1939 TRACE("(%p)->(%p): Relay\n", This, RenderTarget);
1942 return DDERR_INVALIDPARAMS;
1944 EnterCriticalSection(&ddraw_cs);
1945 *RenderTarget = ICOM_INTERFACE(This->target, IDirectDrawSurface7);
1946 IDirectDrawSurface7_AddRef(*RenderTarget);
1948 LeaveCriticalSection(&ddraw_cs);
1952 static HRESULT WINAPI
1953 Thunk_IDirect3DDeviceImpl_3_GetRenderTarget(IDirect3DDevice3 *iface,
1954 IDirectDrawSurface4 **RenderTarget)
1956 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1958 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, RenderTarget);
1959 hr = IDirect3DDevice7_GetRenderTarget(ICOM_INTERFACE(This, IDirect3DDevice7),
1960 (IDirectDrawSurface7 **) RenderTarget);
1961 if(hr != D3D_OK) return hr;
1962 *RenderTarget = (IDirectDrawSurface4 *) COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7, IDirectDrawSurface7, *RenderTarget);
1966 static HRESULT WINAPI
1967 Thunk_IDirect3DDeviceImpl_2_GetRenderTarget(IDirect3DDevice2 *iface,
1968 IDirectDrawSurface **RenderTarget)
1970 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1972 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, RenderTarget);
1973 hr = IDirect3DDevice7_GetRenderTarget(ICOM_INTERFACE(This, IDirect3DDevice7),
1974 (IDirectDrawSurface7 **) RenderTarget);
1975 if(hr != D3D_OK) return hr;
1976 *RenderTarget = (IDirectDrawSurface *) COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7, IDirectDrawSurface3, *RenderTarget);
1980 /*****************************************************************************
1981 * IDirect3DDevice3::Begin
1983 * Begins a description block of vertices. This is similar to glBegin()
1984 * and glEnd(). After a call to IDirect3DDevice3::End, the vertices
1985 * described with IDirect3DDevice::Vertex are drawn.
1990 * PrimitiveType: The type of primitives to draw
1991 * VertexTypeDesc: A flexible vertex format description of the vertices
1992 * Flags: Some flags..
1997 *****************************************************************************/
1998 static HRESULT WINAPI
1999 IDirect3DDeviceImpl_3_Begin(IDirect3DDevice3 *iface,
2000 D3DPRIMITIVETYPE PrimitiveType,
2001 DWORD VertexTypeDesc,
2004 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2005 TRACE("(%p)->(%d,%d,%08x)\n", This, PrimitiveType, VertexTypeDesc, Flags);
2007 EnterCriticalSection(&ddraw_cs);
2008 This->primitive_type = PrimitiveType;
2009 This->vertex_type = VertexTypeDesc;
2010 This->render_flags = Flags;
2011 This->vertex_size = get_flexible_vertex_size(This->vertex_type);
2012 This->nb_vertices = 0;
2013 LeaveCriticalSection(&ddraw_cs);
2018 static HRESULT WINAPI
2019 Thunk_IDirect3DDeviceImpl_2_Begin(IDirect3DDevice2 *iface,
2020 D3DPRIMITIVETYPE d3dpt,
2021 D3DVERTEXTYPE dwVertexTypeDesc,
2025 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2026 TRACE_(ddraw_thunk)("(%p/%p)->(%08x,%08x,%08x): Thunking to IDirect3DDevice3\n", This, iface, d3dpt, dwVertexTypeDesc, dwFlags);
2028 switch(dwVertexTypeDesc)
2030 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
2031 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
2032 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
2034 ERR("Unexpected vertex type %d\n", dwVertexTypeDesc);
2035 return DDERR_INVALIDPARAMS; /* Should never happen */
2038 return IDirect3DDevice3_Begin(ICOM_INTERFACE(This, IDirect3DDevice3),
2044 /*****************************************************************************
2045 * IDirect3DDevice3::BeginIndexed
2047 * Draws primitives based on vertices in a vertex array which are specified
2053 * PrimitiveType: Primitive type to draw
2054 * VertexType: A FVF description of the vertex format
2055 * Vertices: pointer to an array containing the vertices
2056 * NumVertices: The number of vertices in the vertex array
2057 * Flags: Some flags ...
2060 * D3D_OK, because it's a stub
2062 *****************************************************************************/
2063 static HRESULT WINAPI
2064 IDirect3DDeviceImpl_3_BeginIndexed(IDirect3DDevice3 *iface,
2065 D3DPRIMITIVETYPE PrimitiveType,
2071 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2072 FIXME("(%p)->(%08x,%08x,%p,%08x,%08x): stub!\n", This, PrimitiveType, VertexType, Vertices, NumVertices, Flags);
2077 static HRESULT WINAPI
2078 Thunk_IDirect3DDeviceImpl_2_BeginIndexed(IDirect3DDevice2 *iface,
2079 D3DPRIMITIVETYPE d3dptPrimitiveType,
2080 D3DVERTEXTYPE d3dvtVertexType,
2082 DWORD dwNumVertices,
2086 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2087 TRACE_(ddraw_thunk)("(%p/%p)->(%08x,%08x,%p,%08x,%08x): Thunking to IDirect3DDevice3\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwNumVertices, dwFlags);
2089 switch(d3dvtVertexType)
2091 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
2092 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
2093 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
2095 ERR("Unexpected vertex type %d\n", d3dvtVertexType);
2096 return DDERR_INVALIDPARAMS; /* Should never happen */
2099 return IDirect3DDevice3_BeginIndexed(ICOM_INTERFACE(This,IDirect3DDevice3),
2107 /*****************************************************************************
2108 * IDirect3DDevice3::Vertex
2110 * Draws a vertex as described by IDirect3DDevice3::Begin. It places all
2111 * drawn vertices in a vertex buffer. If the buffer is too small, its
2112 * size is increased.
2117 * Vertex: Pointer to the vertex
2120 * D3D_OK, on success
2121 * DDERR_INVALIDPARAMS if Vertex is NULL
2123 *****************************************************************************/
2124 static HRESULT WINAPI
2125 IDirect3DDeviceImpl_3_Vertex(IDirect3DDevice3 *iface,
2128 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2129 TRACE("(%p)->(%p)\n", This, Vertex);
2132 return DDERR_INVALIDPARAMS;
2134 EnterCriticalSection(&ddraw_cs);
2135 if ((This->nb_vertices+1)*This->vertex_size > This->buffer_size)
2138 This->buffer_size = This->buffer_size ? This->buffer_size * 2 : This->vertex_size * 3;
2139 old_buffer = This->vertex_buffer;
2140 This->vertex_buffer = HeapAlloc(GetProcessHeap(), 0, This->buffer_size);
2143 CopyMemory(This->vertex_buffer, old_buffer, This->nb_vertices * This->vertex_size);
2144 HeapFree(GetProcessHeap(), 0, old_buffer);
2148 CopyMemory(This->vertex_buffer + This->nb_vertices++ * This->vertex_size, Vertex, This->vertex_size);
2150 LeaveCriticalSection(&ddraw_cs);
2154 static HRESULT WINAPI
2155 Thunk_IDirect3DDeviceImpl_2_Vertex(IDirect3DDevice2 *iface,
2158 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2159 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, lpVertexType);
2160 return IDirect3DDevice3_Vertex(ICOM_INTERFACE(This, IDirect3DDevice3),
2164 /*****************************************************************************
2165 * IDirect3DDevice3::Index
2167 * Specifies an index to a vertex to be drawn. The vertex array has to
2168 * be specified with BeginIndexed first.
2171 * VertexIndex: The index of the vertex to draw
2174 * D3D_OK because it's a stub
2176 *****************************************************************************/
2177 static HRESULT WINAPI
2178 IDirect3DDeviceImpl_3_Index(IDirect3DDevice3 *iface,
2181 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2182 FIXME("(%p)->(%04x): stub!\n", This, VertexIndex);
2186 static HRESULT WINAPI
2187 Thunk_IDirect3DDeviceImpl_2_Index(IDirect3DDevice2 *iface,
2190 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2191 TRACE_(ddraw_thunk)("(%p)->(%04x) thunking to IDirect3DDevice3 interface.\n", This, wVertexIndex);
2192 return IDirect3DDevice3_Index(ICOM_INTERFACE(This, IDirect3DDevice3),
2196 /*****************************************************************************
2197 * IDirect3DDevice3::End
2199 * Ends a draw begun with IDirect3DDevice3::Begin or
2200 * IDirect3DDevice::BeginIndexed. The vertices specified with
2201 * IDirect3DDevice::Vertex or IDirect3DDevice::Index are drawn using
2202 * the IDirect3DDevice7::DrawPrimitive method. So far only
2203 * non-indexed mode is supported
2208 * Flags: Some flags, as usual. Don't know which are defined
2211 * The return value of IDirect3DDevice7::DrawPrimitive
2213 *****************************************************************************/
2214 static HRESULT WINAPI
2215 IDirect3DDeviceImpl_3_End(IDirect3DDevice3 *iface,
2218 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2219 TRACE("(%p)->(%08x)\n", This, Flags);
2221 return IDirect3DDevice7_DrawPrimitive(ICOM_INTERFACE(This, IDirect3DDevice7),
2222 This->primitive_type, This->vertex_type,
2223 This->vertex_buffer, This->nb_vertices,
2224 This->render_flags);
2227 static HRESULT WINAPI
2228 Thunk_IDirect3DDeviceImpl_2_End(IDirect3DDevice2 *iface,
2231 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2232 TRACE_(ddraw_thunk)("(%p)->(%08x) thunking to IDirect3DDevice3 interface.\n", This, dwFlags);
2233 return IDirect3DDevice3_End(ICOM_INTERFACE(This, IDirect3DDevice3),
2237 /*****************************************************************************
2238 * IDirect3DDevice7::GetRenderState
2240 * Returns the value of a render state. The possible render states are
2241 * defined in include/d3dtypes.h
2243 * Version 2, 3 and 7
2246 * RenderStateType: Render state to return the current setting of
2247 * Value: Address to store the value at
2250 * D3D_OK on success, for details see IWineD3DDevice::GetRenderState
2251 * DDERR_INVALIDPARAMS if Value == NULL
2253 *****************************************************************************/
2254 static HRESULT WINAPI
2255 IDirect3DDeviceImpl_7_GetRenderState(IDirect3DDevice7 *iface,
2256 D3DRENDERSTATETYPE RenderStateType,
2259 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
2261 TRACE("(%p)->(%08x,%p): Relay\n", This, RenderStateType, Value);
2264 return DDERR_INVALIDPARAMS;
2266 EnterCriticalSection(&ddraw_cs);
2267 switch(RenderStateType)
2269 case D3DRENDERSTATE_TEXTUREMAG:
2271 WINED3DTEXTUREFILTERTYPE tex_mag;
2273 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2274 0, WINED3DSAMP_MAGFILTER,
2279 case WINED3DTEXF_POINT:
2280 *Value = D3DFILTER_NEAREST;
2282 case WINED3DTEXF_LINEAR:
2283 *Value = D3DFILTER_LINEAR;
2286 ERR("Unhandled texture mag %d !\n",tex_mag);
2292 case D3DRENDERSTATE_TEXTUREMIN:
2294 WINED3DTEXTUREFILTERTYPE tex_min;
2296 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2297 0, WINED3DSAMP_MINFILTER,
2302 case WINED3DTEXF_POINT:
2303 *Value = D3DFILTER_NEAREST;
2305 case WINED3DTEXF_LINEAR:
2306 *Value = D3DFILTER_LINEAR;
2309 ERR("Unhandled texture mag %d !\n",tex_min);
2315 case D3DRENDERSTATE_TEXTUREADDRESS:
2316 case D3DRENDERSTATE_TEXTUREADDRESSU:
2317 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2318 0, WINED3DSAMP_ADDRESSU,
2321 case D3DRENDERSTATE_TEXTUREADDRESSV:
2322 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2323 0, WINED3DSAMP_ADDRESSV,
2328 /* FIXME: Unhandled: D3DRENDERSTATE_STIPPLEPATTERN00 - 31 */
2329 hr = IWineD3DDevice_GetRenderState(This->wineD3DDevice,
2333 LeaveCriticalSection(&ddraw_cs);
2337 static HRESULT WINAPI
2338 IDirect3DDeviceImpl_3_GetRenderState(IDirect3DDevice3 *iface,
2339 D3DRENDERSTATETYPE dwRenderStateType,
2340 DWORD *lpdwRenderState)
2342 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2344 TRACE("(%p)->(%08x,%p)\n", This, dwRenderStateType, lpdwRenderState);
2346 switch(dwRenderStateType)
2348 case D3DRENDERSTATE_TEXTUREHANDLE:
2350 /* This state is wrapped to SetTexture in SetRenderState, so
2351 * it has to be wrapped to GetTexture here
2353 IWineD3DBaseTexture *tex = NULL;
2354 *lpdwRenderState = 0;
2356 EnterCriticalSection(&ddraw_cs);
2358 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice,
2362 if(hr == WINED3D_OK && tex)
2364 IDirectDrawSurface7 *parent = NULL;
2365 hr = IWineD3DBaseTexture_GetParent(tex,
2366 (IUnknown **) &parent);
2369 /* The parent of the texture is the IDirectDrawSurface7 interface
2370 * of the ddraw surface
2372 IDirectDrawSurfaceImpl *texImpl = ICOM_OBJECT(IDirectDrawSurfaceImpl,
2373 IDirectDrawSurface7,
2375 *lpdwRenderState = texImpl->Handle;
2376 IDirectDrawSurface7_Release(parent);
2378 IWineD3DBaseTexture_Release(tex);
2381 LeaveCriticalSection(&ddraw_cs);
2386 case D3DRENDERSTATE_TEXTUREMAPBLEND:
2388 /* D3DRENDERSTATE_TEXTUREMAPBLEND is mapped to texture state stages in SetRenderState; reverse
2389 the mapping to get the value. */
2390 DWORD colorop, colorarg1, colorarg2;
2391 DWORD alphaop, alphaarg1, alphaarg2;
2393 EnterCriticalSection(&ddraw_cs);
2395 This->legacyTextureBlending = TRUE;
2397 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, &colorop);
2398 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, &colorarg1);
2399 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, &colorarg2);
2400 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, &alphaop);
2401 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, &alphaarg1);
2402 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, &alphaarg2);
2404 if (colorop == WINED3DTOP_SELECTARG1 && colorarg1 == WINED3DTA_TEXTURE &&
2405 alphaop == WINED3DTOP_SELECTARG1 && alphaarg1 == WINED3DTA_TEXTURE)
2407 *lpdwRenderState = D3DTBLEND_DECAL;
2409 else if (colorop == WINED3DTOP_SELECTARG1 && colorarg1 == WINED3DTA_TEXTURE &&
2410 alphaop == WINED3DTOP_MODULATE && alphaarg1 == WINED3DTA_TEXTURE && alphaarg2 == WINED3DTA_CURRENT)
2412 *lpdwRenderState = D3DTBLEND_DECALALPHA;
2414 else if (colorop == WINED3DTOP_MODULATE && colorarg1 == WINED3DTA_TEXTURE && colorarg2 == WINED3DTA_CURRENT &&
2415 alphaop == WINED3DTOP_MODULATE && alphaarg1 == WINED3DTA_TEXTURE && alphaarg2 == WINED3DTA_CURRENT)
2417 *lpdwRenderState = D3DTBLEND_MODULATEALPHA;
2422 BOOL tex_alpha = FALSE;
2423 IWineD3DBaseTexture *tex = NULL;
2424 WINED3DSURFACE_DESC desc;
2426 DDPIXELFORMAT ddfmt;
2428 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice,
2432 if(hr == WINED3D_OK && tex)
2434 memset(&desc, 0, sizeof(desc));
2436 hr = IWineD3DTexture_GetLevelDesc((IWineD3DTexture*) tex, 0, &desc);
2439 ddfmt.dwSize = sizeof(ddfmt);
2440 PixelFormat_WineD3DtoDD(&ddfmt, fmt);
2441 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
2444 IWineD3DBaseTexture_Release(tex);
2447 if (!(colorop == WINED3DTOP_MODULATE && colorarg1 == WINED3DTA_TEXTURE && colorarg2 == WINED3DTA_CURRENT &&
2448 alphaop == WINED3DTOP_SELECTARG1 && alphaarg1 == (tex_alpha ? WINED3DTA_TEXTURE : WINED3DTA_CURRENT)))
2450 ERR("Unexpected texture stage state setup, returning D3DTBLEND_MODULATE - likely erroneous\n");
2453 *lpdwRenderState = D3DTBLEND_MODULATE;
2456 LeaveCriticalSection(&ddraw_cs);
2462 return IDirect3DDevice7_GetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
2468 static HRESULT WINAPI
2469 Thunk_IDirect3DDeviceImpl_2_GetRenderState(IDirect3DDevice2 *iface,
2470 D3DRENDERSTATETYPE dwRenderStateType,
2471 DWORD *lpdwRenderState)
2473 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2474 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice3 interface.\n", This, dwRenderStateType, lpdwRenderState);
2475 return IDirect3DDevice3_GetRenderState(ICOM_INTERFACE(This, IDirect3DDevice3),
2480 /*****************************************************************************
2481 * IDirect3DDevice7::SetRenderState
2483 * Sets a render state. The possible render states are defined in
2484 * include/d3dtypes.h
2486 * Version 2, 3 and 7
2489 * RenderStateType: State to set
2490 * Value: Value to assign to that state
2493 * D3D_OK on success,
2494 * for details see IWineD3DDevice::SetRenderState
2496 *****************************************************************************/
2497 static HRESULT WINAPI
2498 IDirect3DDeviceImpl_7_SetRenderState(IDirect3DDevice7 *iface,
2499 D3DRENDERSTATETYPE RenderStateType,
2502 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
2504 TRACE("(%p)->(%08x,%d): Relay\n", This, RenderStateType, Value);
2506 EnterCriticalSection(&ddraw_cs);
2507 /* Some render states need special care */
2508 switch(RenderStateType)
2510 case D3DRENDERSTATE_TEXTUREMAG:
2512 WINED3DTEXTUREFILTERTYPE tex_mag = WINED3DTEXF_NONE;
2514 switch ((D3DTEXTUREFILTER) Value)
2516 case D3DFILTER_NEAREST:
2517 case D3DFILTER_LINEARMIPNEAREST:
2518 tex_mag = WINED3DTEXF_POINT;
2520 case D3DFILTER_LINEAR:
2521 case D3DFILTER_LINEARMIPLINEAR:
2522 tex_mag = WINED3DTEXF_LINEAR;
2525 ERR("Unhandled texture mag %d !\n",Value);
2528 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2529 0, WINED3DSAMP_MAGFILTER,
2534 case D3DRENDERSTATE_TEXTUREMIN:
2536 WINED3DTEXTUREFILTERTYPE tex_min = WINED3DTEXF_NONE;
2537 WINED3DTEXTUREFILTERTYPE tex_mip = WINED3DTEXF_NONE;
2539 switch ((D3DTEXTUREFILTER) Value)
2541 case D3DFILTER_NEAREST:
2542 tex_min = WINED3DTEXF_POINT;
2544 case D3DFILTER_LINEAR:
2545 tex_min = WINED3DTEXF_LINEAR;
2547 case D3DFILTER_MIPNEAREST:
2548 tex_min = WINED3DTEXF_NONE;
2549 tex_mip = WINED3DTEXF_POINT;
2551 case D3DFILTER_MIPLINEAR:
2552 tex_min = WINED3DTEXF_NONE;
2553 tex_mip = WINED3DTEXF_LINEAR;
2555 case D3DFILTER_LINEARMIPNEAREST:
2556 tex_min = WINED3DTEXF_POINT;
2557 tex_mip = WINED3DTEXF_LINEAR;
2559 case D3DFILTER_LINEARMIPLINEAR:
2560 tex_min = WINED3DTEXF_LINEAR;
2561 tex_mip = WINED3DTEXF_LINEAR;
2565 ERR("Unhandled texture min %d !\n",Value);
2568 IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2569 0, WINED3DSAMP_MIPFILTER,
2571 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2572 0, WINED3DSAMP_MINFILTER,
2577 case D3DRENDERSTATE_TEXTUREADDRESS:
2578 IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2579 0, WINED3DSAMP_ADDRESSV,
2582 case D3DRENDERSTATE_TEXTUREADDRESSU:
2583 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2584 0, WINED3DSAMP_ADDRESSU,
2587 case D3DRENDERSTATE_TEXTUREADDRESSV:
2588 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2589 0, WINED3DSAMP_ADDRESSV,
2595 /* FIXME: Unhandled: D3DRENDERSTATE_STIPPLEPATTERN00 - 31 */
2597 hr = IWineD3DDevice_SetRenderState(This->wineD3DDevice,
2602 LeaveCriticalSection(&ddraw_cs);
2606 static HRESULT WINAPI
2607 IDirect3DDeviceImpl_3_SetRenderState(IDirect3DDevice3 *iface,
2608 D3DRENDERSTATETYPE RenderStateType,
2611 /* Note about D3DRENDERSTATE_TEXTUREMAPBLEND implementation: most of values
2612 for this state can be directly mapped to texture stage colorop and alphaop, but
2613 D3DTBLEND_MODULATE is tricky: it uses alpha from texture when available and alpha
2614 from diffuse otherwise. So changing the texture must be monitored in SetTexture to modify
2615 alphaarg when needed.
2617 Aliens vs Predator 1 depends on accurate D3DTBLEND_MODULATE emulation
2619 Legacy texture blending (TEXTUREMAPBLEND) and texture stage states: directx6 docs state that
2620 TEXTUREMAPBLEND is deprecated, yet can still be used. Games must not use both or results
2621 are undefined. D3DTBLEND_MODULATE mode in particular is dependent on texture pixel format and
2622 requires fixup of stage 0 texture states when texture changes, but this fixup can interfere
2623 with games not using this deprecated state. So a flag 'legacyTextureBlending' has to be kept
2624 in device - TRUE if the app is using TEXTUREMAPBLEND.
2626 Tests show that setting TEXTUREMAPBLEND on native doesn't seem to change values returned by
2627 GetTextureStageState and vice versa. Not so on Wine, but it is 'undefined' anyway so, probably, ok,
2628 unless some broken game will be found that cares. */
2631 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2632 TRACE("(%p)->(%08x,%d)\n", This, RenderStateType, Value);
2634 EnterCriticalSection(&ddraw_cs);
2636 switch(RenderStateType)
2638 case D3DRENDERSTATE_TEXTUREHANDLE:
2642 hr = IWineD3DDevice_SetTexture(This->wineD3DDevice,
2648 if(Value > This->numHandles)
2650 FIXME("Specified handle %d out of range\n", Value);
2651 hr = DDERR_INVALIDPARAMS;
2654 if(This->Handles[Value - 1].type != DDrawHandle_Texture)
2656 FIXME("Handle %d isn't a texture handle\n", Value);
2657 hr = DDERR_INVALIDPARAMS;
2662 IDirectDrawSurfaceImpl *surf = (IDirectDrawSurfaceImpl *) This->Handles[Value - 1].ptr;
2663 hr = IDirect3DDevice3_SetTexture(iface, 0, ICOM_INTERFACE(surf, IDirect3DTexture2));
2668 case D3DRENDERSTATE_TEXTUREMAPBLEND:
2670 This->legacyTextureBlending = TRUE;
2672 switch ( (D3DTEXTUREBLEND) Value)
2674 case D3DTBLEND_MODULATE:
2676 BOOL tex_alpha = FALSE;
2677 IWineD3DBaseTexture *tex = NULL;
2678 WINED3DSURFACE_DESC desc;
2680 DDPIXELFORMAT ddfmt;
2682 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice,
2686 if(hr == WINED3D_OK && tex)
2688 memset(&desc, 0, sizeof(desc));
2690 hr = IWineD3DTexture_GetLevelDesc((IWineD3DTexture*) tex, 0, &desc);
2693 ddfmt.dwSize = sizeof(ddfmt);
2694 PixelFormat_WineD3DtoDD(&ddfmt, fmt);
2695 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
2698 IWineD3DBaseTexture_Release(tex);
2701 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG1);
2704 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2708 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_CURRENT);
2711 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2712 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2713 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_MODULATE);
2719 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_ADD);
2720 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2721 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2722 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG2);
2723 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
2726 case D3DTBLEND_MODULATEALPHA:
2727 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2728 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2729 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2730 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
2731 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_MODULATE);
2732 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_MODULATE);
2735 case D3DTBLEND_COPY:
2736 case D3DTBLEND_DECAL:
2737 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2738 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2739 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_SELECTARG1);
2740 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG1);
2743 case D3DTBLEND_DECALALPHA:
2744 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_BLENDTEXTUREALPHA);
2745 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2746 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2747 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG2);
2748 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
2752 ERR("Unhandled texture environment %d !\n",Value);
2760 hr = IDirect3DDevice7_SetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
2766 LeaveCriticalSection(&ddraw_cs);
2771 static HRESULT WINAPI
2772 Thunk_IDirect3DDeviceImpl_2_SetRenderState(IDirect3DDevice2 *iface,
2773 D3DRENDERSTATETYPE RenderStateType,
2776 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2777 TRACE_(ddraw_thunk)("(%p)->(%08x,%d) thunking to IDirect3DDevice3 interface.\n", This, RenderStateType, Value);
2778 return IDirect3DDevice3_SetRenderState(ICOM_INTERFACE(This, IDirect3DDevice3), RenderStateType, Value);
2781 /*****************************************************************************
2782 * Direct3DDevice3::SetLightState
2784 * Sets a light state for Direct3DDevice3 and Direct3DDevice2. The
2785 * light states are forwarded to Direct3DDevice7 render states
2790 * LightStateType: The light state to change
2791 * Value: The value to assign to that light state
2795 * DDERR_INVALIDPARAMS if the parameters were incorrect
2796 * Also check IDirect3DDevice7::SetRenderState
2798 *****************************************************************************/
2799 static HRESULT WINAPI
2800 IDirect3DDeviceImpl_3_SetLightState(IDirect3DDevice3 *iface,
2801 D3DLIGHTSTATETYPE LightStateType,
2804 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2807 TRACE("(%p)->(%08x,%08x)\n", This, LightStateType, Value);
2809 if (!LightStateType && (LightStateType > D3DLIGHTSTATE_COLORVERTEX))
2811 TRACE("Unexpected Light State Type\n");
2812 return DDERR_INVALIDPARAMS;
2815 EnterCriticalSection(&ddraw_cs);
2816 if (LightStateType == D3DLIGHTSTATE_MATERIAL /* 1 */)
2818 IDirect3DMaterialImpl *mat;
2820 if(Value == 0) mat = NULL;
2821 else if(Value > This->numHandles)
2823 ERR("Material handle out of range(%d)\n", Value);
2824 LeaveCriticalSection(&ddraw_cs);
2825 return DDERR_INVALIDPARAMS;
2827 else if(This->Handles[Value - 1].type != DDrawHandle_Material)
2829 ERR("Invalid handle %d\n", Value);
2830 LeaveCriticalSection(&ddraw_cs);
2831 return DDERR_INVALIDPARAMS;
2835 mat = (IDirect3DMaterialImpl *) This->Handles[Value - 1].ptr;
2840 TRACE(" activating material %p.\n", mat);
2845 FIXME(" D3DLIGHTSTATE_MATERIAL called with NULL material !!!\n");
2847 This->material = Value;
2849 else if (LightStateType == D3DLIGHTSTATE_COLORMODEL /* 3 */)
2854 ERR("DDCOLOR_MONO should not happen!\n");
2857 /* We are already in this mode */
2858 TRACE("Setting color model to RGB (no-op).\n");
2861 ERR("Unknown color model!\n");
2862 LeaveCriticalSection(&ddraw_cs);
2863 return DDERR_INVALIDPARAMS;
2868 D3DRENDERSTATETYPE rs;
2869 switch (LightStateType)
2871 case D3DLIGHTSTATE_AMBIENT: /* 2 */
2872 rs = D3DRENDERSTATE_AMBIENT;
2874 case D3DLIGHTSTATE_FOGMODE: /* 4 */
2875 rs = D3DRENDERSTATE_FOGVERTEXMODE;
2877 case D3DLIGHTSTATE_FOGSTART: /* 5 */
2878 rs = D3DRENDERSTATE_FOGSTART;
2880 case D3DLIGHTSTATE_FOGEND: /* 6 */
2881 rs = D3DRENDERSTATE_FOGEND;
2883 case D3DLIGHTSTATE_FOGDENSITY: /* 7 */
2884 rs = D3DRENDERSTATE_FOGDENSITY;
2886 case D3DLIGHTSTATE_COLORVERTEX: /* 8 */
2887 rs = D3DRENDERSTATE_COLORVERTEX;
2890 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType);
2891 LeaveCriticalSection(&ddraw_cs);
2892 return DDERR_INVALIDPARAMS;
2895 hr = IDirect3DDevice7_SetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
2898 LeaveCriticalSection(&ddraw_cs);
2902 LeaveCriticalSection(&ddraw_cs);
2906 static HRESULT WINAPI
2907 Thunk_IDirect3DDeviceImpl_2_SetLightState(IDirect3DDevice2 *iface,
2908 D3DLIGHTSTATETYPE LightStateType,
2911 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2912 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x) thunking to IDirect3DDevice3 interface.\n", This, LightStateType, Value);
2913 return IDirect3DDevice3_SetLightState(ICOM_INTERFACE(This, IDirect3DDevice3),
2918 /*****************************************************************************
2919 * IDirect3DDevice3::GetLightState
2921 * Returns the current setting of a light state. The state is read from
2922 * the Direct3DDevice7 render state.
2927 * LightStateType: The light state to return
2928 * Value: The address to store the light state setting at
2932 * DDDERR_INVALIDPARAMS if the parameters were incorrect
2933 * Also see IDirect3DDevice7::GetRenderState
2935 *****************************************************************************/
2936 static HRESULT WINAPI
2937 IDirect3DDeviceImpl_3_GetLightState(IDirect3DDevice3 *iface,
2938 D3DLIGHTSTATETYPE LightStateType,
2941 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2944 TRACE("(%p)->(%08x,%p)\n", This, LightStateType, Value);
2946 if (!LightStateType && (LightStateType > D3DLIGHTSTATE_COLORVERTEX))
2948 TRACE("Unexpected Light State Type\n");
2949 return DDERR_INVALIDPARAMS;
2953 return DDERR_INVALIDPARAMS;
2955 EnterCriticalSection(&ddraw_cs);
2956 if (LightStateType == D3DLIGHTSTATE_MATERIAL /* 1 */)
2958 *Value = This->material;
2960 else if (LightStateType == D3DLIGHTSTATE_COLORMODEL /* 3 */)
2962 *Value = D3DCOLOR_RGB;
2966 D3DRENDERSTATETYPE rs;
2967 switch (LightStateType)
2969 case D3DLIGHTSTATE_AMBIENT: /* 2 */
2970 rs = D3DRENDERSTATE_AMBIENT;
2972 case D3DLIGHTSTATE_FOGMODE: /* 4 */
2973 rs = D3DRENDERSTATE_FOGVERTEXMODE;
2975 case D3DLIGHTSTATE_FOGSTART: /* 5 */
2976 rs = D3DRENDERSTATE_FOGSTART;
2978 case D3DLIGHTSTATE_FOGEND: /* 6 */
2979 rs = D3DRENDERSTATE_FOGEND;
2981 case D3DLIGHTSTATE_FOGDENSITY: /* 7 */
2982 rs = D3DRENDERSTATE_FOGDENSITY;
2984 case D3DLIGHTSTATE_COLORVERTEX: /* 8 */
2985 rs = D3DRENDERSTATE_COLORVERTEX;
2988 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType);
2989 LeaveCriticalSection(&ddraw_cs);
2990 return DDERR_INVALIDPARAMS;
2993 hr = IDirect3DDevice7_GetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
2996 LeaveCriticalSection(&ddraw_cs);
3000 LeaveCriticalSection(&ddraw_cs);
3004 static HRESULT WINAPI
3005 Thunk_IDirect3DDeviceImpl_2_GetLightState(IDirect3DDevice2 *iface,
3006 D3DLIGHTSTATETYPE LightStateType,
3009 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3010 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice3 interface.\n", This, LightStateType, Value);
3011 return IDirect3DDevice3_GetLightState(ICOM_INTERFACE(This, IDirect3DDevice3),
3016 /*****************************************************************************
3017 * IDirect3DDevice7::SetTransform
3019 * Assigns a D3DMATRIX to a transform type. The transform types are defined
3020 * in include/d3dtypes.h.
3021 * The D3DTRANSFORMSTATE_WORLD (=1) is translated to D3DTS_WORLDMATRIX(0)
3022 * (=255) for wined3d, because the 1 transform state was removed in d3d8
3023 * and WineD3D already understands the replacement D3DTS_WORLDMATRIX(0)
3025 * Version 2, 3 and 7
3028 * TransformStateType: transform state to set
3029 * Matrix: Matrix to assign to the state
3033 * DDERR_INVALIDPARAMS if Matrix == NULL
3034 * For details see IWineD3DDevice::SetTransform
3036 *****************************************************************************/
3037 static HRESULT WINAPI
3038 IDirect3DDeviceImpl_7_SetTransform(IDirect3DDevice7 *iface,
3039 D3DTRANSFORMSTATETYPE TransformStateType,
3042 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3043 D3DTRANSFORMSTATETYPE type = TransformStateType;
3045 TRACE("(%p)->(%08x,%p): Relay\n", This, TransformStateType, Matrix);
3047 switch(TransformStateType)
3049 case D3DTRANSFORMSTATE_WORLD : type = WINED3DTS_WORLDMATRIX(0); break;
3050 case D3DTRANSFORMSTATE_WORLD1: type = WINED3DTS_WORLDMATRIX(1); break;
3051 case D3DTRANSFORMSTATE_WORLD2: type = WINED3DTS_WORLDMATRIX(2); break;
3052 case D3DTRANSFORMSTATE_WORLD3: type = WINED3DTS_WORLDMATRIX(3); break;
3053 default: type = TransformStateType;
3057 return DDERR_INVALIDPARAMS;
3059 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3060 EnterCriticalSection(&ddraw_cs);
3061 hr = IWineD3DDevice_SetTransform(This->wineD3DDevice,
3063 (WINED3DMATRIX*) Matrix);
3064 LeaveCriticalSection(&ddraw_cs);
3068 static HRESULT WINAPI
3069 Thunk_IDirect3DDeviceImpl_3_SetTransform(IDirect3DDevice3 *iface,
3070 D3DTRANSFORMSTATETYPE TransformStateType,
3071 D3DMATRIX *D3DMatrix)
3073 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3074 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3075 return IDirect3DDevice7_SetTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
3080 static HRESULT WINAPI
3081 Thunk_IDirect3DDeviceImpl_2_SetTransform(IDirect3DDevice2 *iface,
3082 D3DTRANSFORMSTATETYPE TransformStateType,
3083 D3DMATRIX *D3DMatrix)
3085 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3086 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3087 return IDirect3DDevice7_SetTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
3092 /*****************************************************************************
3093 * IDirect3DDevice7::GetTransform
3095 * Returns the matrix assigned to a transform state
3096 * D3DTRANSFORMSTATE_WORLD is translated to D3DTS_WORLDMATRIX(0), see
3100 * TransformStateType: State to read the matrix from
3101 * Matrix: Address to store the matrix at
3105 * DDERR_INVALIDPARAMS if Matrix == NULL
3106 * For details, see IWineD3DDevice::GetTransform
3108 *****************************************************************************/
3109 static HRESULT WINAPI
3110 IDirect3DDeviceImpl_7_GetTransform(IDirect3DDevice7 *iface,
3111 D3DTRANSFORMSTATETYPE TransformStateType,
3114 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3115 D3DTRANSFORMSTATETYPE type = TransformStateType;
3117 TRACE("(%p)->(%08x,%p): Relay\n", This, TransformStateType, Matrix);
3119 switch(TransformStateType)
3121 case D3DTRANSFORMSTATE_WORLD : type = WINED3DTS_WORLDMATRIX(0); break;
3122 case D3DTRANSFORMSTATE_WORLD1: type = WINED3DTS_WORLDMATRIX(1); break;
3123 case D3DTRANSFORMSTATE_WORLD2: type = WINED3DTS_WORLDMATRIX(2); break;
3124 case D3DTRANSFORMSTATE_WORLD3: type = WINED3DTS_WORLDMATRIX(3); break;
3125 default: type = TransformStateType;
3129 return DDERR_INVALIDPARAMS;
3131 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3132 EnterCriticalSection(&ddraw_cs);
3133 hr = IWineD3DDevice_GetTransform(This->wineD3DDevice, type, (WINED3DMATRIX*) Matrix);
3134 LeaveCriticalSection(&ddraw_cs);
3138 static HRESULT WINAPI
3139 Thunk_IDirect3DDeviceImpl_3_GetTransform(IDirect3DDevice3 *iface,
3140 D3DTRANSFORMSTATETYPE TransformStateType,
3141 D3DMATRIX *D3DMatrix)
3143 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3144 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3145 return IDirect3DDevice7_GetTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
3150 static HRESULT WINAPI
3151 Thunk_IDirect3DDeviceImpl_2_GetTransform(IDirect3DDevice2 *iface,
3152 D3DTRANSFORMSTATETYPE TransformStateType,
3153 D3DMATRIX *D3DMatrix)
3155 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3156 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3157 return IDirect3DDevice7_GetTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
3162 /*****************************************************************************
3163 * IDirect3DDevice7::MultiplyTransform
3165 * Multiplies the already-set transform matrix of a transform state
3166 * with another matrix. For the world matrix, see SetTransform
3168 * Version 2, 3 and 7
3171 * TransformStateType: Transform state to multiply
3172 * D3DMatrix Matrix to multiply with.
3176 * DDERR_INVALIDPARAMS if D3DMatrix is NULL
3177 * For details, see IWineD3DDevice::MultiplyTransform
3179 *****************************************************************************/
3180 static HRESULT WINAPI
3181 IDirect3DDeviceImpl_7_MultiplyTransform(IDirect3DDevice7 *iface,
3182 D3DTRANSFORMSTATETYPE TransformStateType,
3183 D3DMATRIX *D3DMatrix)
3185 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3187 D3DTRANSFORMSTATETYPE type;
3188 TRACE("(%p)->(%08x,%p): Relay\n", This, TransformStateType, D3DMatrix);
3190 switch(TransformStateType)
3192 case D3DTRANSFORMSTATE_WORLD : type = WINED3DTS_WORLDMATRIX(0); break;
3193 case D3DTRANSFORMSTATE_WORLD1: type = WINED3DTS_WORLDMATRIX(1); break;
3194 case D3DTRANSFORMSTATE_WORLD2: type = WINED3DTS_WORLDMATRIX(2); break;
3195 case D3DTRANSFORMSTATE_WORLD3: type = WINED3DTS_WORLDMATRIX(3); break;
3196 default: type = TransformStateType;
3199 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3200 EnterCriticalSection(&ddraw_cs);
3201 hr = IWineD3DDevice_MultiplyTransform(This->wineD3DDevice,
3203 (WINED3DMATRIX*) D3DMatrix);
3204 LeaveCriticalSection(&ddraw_cs);
3208 static HRESULT WINAPI
3209 Thunk_IDirect3DDeviceImpl_3_MultiplyTransform(IDirect3DDevice3 *iface,
3210 D3DTRANSFORMSTATETYPE TransformStateType,
3211 D3DMATRIX *D3DMatrix)
3213 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3214 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3215 return IDirect3DDevice7_MultiplyTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
3220 static HRESULT WINAPI
3221 Thunk_IDirect3DDeviceImpl_2_MultiplyTransform(IDirect3DDevice2 *iface,
3222 D3DTRANSFORMSTATETYPE TransformStateType,
3223 D3DMATRIX *D3DMatrix)
3225 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3226 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3227 return IDirect3DDevice7_MultiplyTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
3232 /*****************************************************************************
3233 * IDirect3DDevice7::DrawPrimitive
3235 * Draws primitives based on vertices in an application-provided pointer
3237 * Version 2, 3 and 7. The IDirect3DDevice2 thunk converts the fixed vertex type into
3238 * an FVF format for D3D7
3241 * PrimitiveType: The type of the primitives to draw
3242 * Vertex type: Flexible vertex format vertex description
3243 * Vertices: Pointer to the vertex array
3244 * VertexCount: The number of vertices to draw
3245 * Flags: As usual a few flags
3249 * DDERR_INVALIDPARAMS if Vertices is NULL
3250 * For details, see IWineD3DDevice::DrawPrimitiveUP
3252 *****************************************************************************/
3253 static HRESULT WINAPI
3254 IDirect3DDeviceImpl_7_DrawPrimitive(IDirect3DDevice7 *iface,
3255 D3DPRIMITIVETYPE PrimitiveType,
3261 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3262 UINT PrimitiveCount, stride;
3264 TRACE("(%p)->(%08x,%08x,%p,%08x,%08x): Relay!\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3267 return DDERR_INVALIDPARAMS;
3269 /* Get the vertex count */
3270 switch(PrimitiveType)
3272 case D3DPT_POINTLIST:
3273 PrimitiveCount = VertexCount;
3276 case D3DPT_LINELIST:
3277 PrimitiveCount = VertexCount / 2;
3280 case D3DPT_LINESTRIP:
3281 PrimitiveCount = VertexCount - 1;
3284 case D3DPT_TRIANGLELIST:
3285 PrimitiveCount = VertexCount / 3;
3288 case D3DPT_TRIANGLESTRIP:
3289 PrimitiveCount = VertexCount - 2;
3292 case D3DPT_TRIANGLEFAN:
3293 PrimitiveCount = VertexCount - 2;
3297 return DDERR_INVALIDPARAMS;
3300 /* Get the stride */
3301 stride = get_flexible_vertex_size(VertexType);
3304 EnterCriticalSection(&ddraw_cs);
3305 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
3306 IDirectDrawImpl_FindDecl(This->ddraw, VertexType));
3309 LeaveCriticalSection(&ddraw_cs);
3313 /* This method translates to the user pointer draw of WineD3D */
3314 hr = IWineD3DDevice_DrawPrimitiveUP(This->wineD3DDevice,
3319 LeaveCriticalSection(&ddraw_cs);
3323 static HRESULT WINAPI
3324 Thunk_IDirect3DDeviceImpl_3_DrawPrimitive(IDirect3DDevice3 *iface,
3325 D3DPRIMITIVETYPE PrimitiveType,
3331 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3332 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3333 return IDirect3DDevice7_DrawPrimitive(ICOM_INTERFACE(This, IDirect3DDevice7),
3341 static HRESULT WINAPI
3342 Thunk_IDirect3DDeviceImpl_2_DrawPrimitive(IDirect3DDevice2 *iface,
3343 D3DPRIMITIVETYPE PrimitiveType,
3344 D3DVERTEXTYPE VertexType,
3349 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3351 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3355 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
3356 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
3357 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
3359 ERR("Unexpected vertex type %d\n", VertexType);
3360 return DDERR_INVALIDPARAMS; /* Should never happen */
3363 return IDirect3DDevice7_DrawPrimitive(ICOM_INTERFACE(This, IDirect3DDevice7),
3371 /*****************************************************************************
3372 * IDirect3DDevice7::DrawIndexedPrimitive
3374 * Draws vertices from an application-provided pointer, based on the index
3375 * numbers in a WORD array.
3377 * Version 2, 3 and 7. The version 7 thunk translates the vertex type into
3378 * an FVF format for D3D7
3381 * PrimitiveType: The primitive type to draw
3382 * VertexType: The FVF vertex description
3383 * Vertices: Pointer to the vertex array
3385 * Indices: Pointer to the index array
3386 * IndexCount: Number of indices = Number of vertices to draw
3387 * Flags: As usual, some flags
3391 * DDERR_INVALIDPARAMS if Vertices or Indices is NULL
3392 * For details, see IWineD3DDevice::DrawIndexedPrimitiveUP
3394 *****************************************************************************/
3395 static HRESULT WINAPI
3396 IDirect3DDeviceImpl_7_DrawIndexedPrimitive(IDirect3DDevice7 *iface,
3397 D3DPRIMITIVETYPE PrimitiveType,
3405 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3406 UINT PrimitiveCount = 0;
3408 TRACE("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x): Relay!\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3410 /* Get the primitive number */
3411 switch(PrimitiveType)
3413 case D3DPT_POINTLIST:
3414 PrimitiveCount = IndexCount;
3417 case D3DPT_LINELIST:
3418 PrimitiveCount = IndexCount / 2;
3421 case D3DPT_LINESTRIP:
3422 PrimitiveCount = IndexCount - 1;
3425 case D3DPT_TRIANGLELIST:
3426 PrimitiveCount = IndexCount / 3;
3429 case D3DPT_TRIANGLESTRIP:
3430 PrimitiveCount = IndexCount - 2;
3433 case D3DPT_TRIANGLEFAN:
3434 PrimitiveCount = IndexCount - 2;
3438 return DDERR_INVALIDPARAMS;
3441 /* Set the D3DDevice's FVF */
3442 EnterCriticalSection(&ddraw_cs);
3443 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
3444 IDirectDrawImpl_FindDecl(This->ddraw, VertexType));
3447 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr);
3448 LeaveCriticalSection(&ddraw_cs);
3452 hr = IWineD3DDevice_DrawIndexedPrimitiveUP(This->wineD3DDevice,
3454 0 /* MinVertexIndex */,
3455 VertexCount /* UINT NumVertexIndex */,
3460 get_flexible_vertex_size(VertexType));
3461 LeaveCriticalSection(&ddraw_cs);
3465 static HRESULT WINAPI
3466 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive(IDirect3DDevice3 *iface,
3467 D3DPRIMITIVETYPE PrimitiveType,
3475 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3476 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3477 return IDirect3DDevice7_DrawIndexedPrimitive(ICOM_INTERFACE(This, IDirect3DDevice7),
3487 static HRESULT WINAPI
3488 Thunk_IDirect3DDeviceImpl_2_DrawIndexedPrimitive(IDirect3DDevice2 *iface,
3489 D3DPRIMITIVETYPE PrimitiveType,
3490 D3DVERTEXTYPE VertexType,
3498 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3499 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3503 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
3504 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
3505 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
3507 ERR("Unexpected vertex type %d\n", VertexType);
3508 return DDERR_INVALIDPARAMS; /* Should never happen */
3511 return IDirect3DDevice7_DrawIndexedPrimitive(ICOM_INTERFACE(This, IDirect3DDevice7),
3521 /*****************************************************************************
3522 * IDirect3DDevice7::SetClipStatus
3524 * Sets the clip status. This defines things as clipping conditions and
3525 * the extents of the clipping region.
3527 * Version 2, 3 and 7
3533 * D3D_OK because it's a stub
3534 * (DDERR_INVALIDPARAMS if ClipStatus == NULL)
3536 *****************************************************************************/
3537 static HRESULT WINAPI
3538 IDirect3DDeviceImpl_7_SetClipStatus(IDirect3DDevice7 *iface,
3539 D3DCLIPSTATUS *ClipStatus)
3541 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3542 FIXME("(%p)->(%p): Stub!\n", This, ClipStatus);
3544 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them
3545 * Perhaps this needs a new data type and an additional IWineD3DDevice method
3547 /* return IWineD3DDevice_SetClipStatus(This->wineD3DDevice, ClipStatus);*/
3551 static HRESULT WINAPI
3552 Thunk_IDirect3DDeviceImpl_3_SetClipStatus(IDirect3DDevice3 *iface,
3553 D3DCLIPSTATUS *ClipStatus)
3555 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3556 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3557 return IDirect3DDevice7_SetClipStatus(ICOM_INTERFACE(This, IDirect3DDevice7),
3561 static HRESULT WINAPI
3562 Thunk_IDirect3DDeviceImpl_2_SetClipStatus(IDirect3DDevice2 *iface,
3563 D3DCLIPSTATUS *ClipStatus)
3565 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3566 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3567 return IDirect3DDevice7_SetClipStatus(ICOM_INTERFACE(This, IDirect3DDevice7),
3571 /*****************************************************************************
3572 * IDirect3DDevice7::GetClipStatus
3574 * Returns the clip status
3577 * ClipStatus: Address to write the clip status to
3580 * D3D_OK because it's a stub
3582 *****************************************************************************/
3583 static HRESULT WINAPI
3584 IDirect3DDeviceImpl_7_GetClipStatus(IDirect3DDevice7 *iface,
3585 D3DCLIPSTATUS *ClipStatus)
3587 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3588 FIXME("(%p)->(%p): Stub!\n", This, ClipStatus);
3590 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them */
3591 /* return IWineD3DDevice_GetClipStatus(This->wineD3DDevice, ClipStatus);*/
3595 static HRESULT WINAPI
3596 Thunk_IDirect3DDeviceImpl_3_GetClipStatus(IDirect3DDevice3 *iface,
3597 D3DCLIPSTATUS *ClipStatus)
3599 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3600 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3601 return IDirect3DDevice7_GetClipStatus(ICOM_INTERFACE(This, IDirect3DDevice7),
3605 static HRESULT WINAPI
3606 Thunk_IDirect3DDeviceImpl_2_GetClipStatus(IDirect3DDevice2 *iface,
3607 D3DCLIPSTATUS *ClipStatus)
3609 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3610 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3611 return IDirect3DDevice7_GetClipStatus(ICOM_INTERFACE(This, IDirect3DDevice7),
3615 /*****************************************************************************
3616 * IDirect3DDevice::DrawPrimitiveStrided
3618 * Draws vertices described by a D3DDRAWPRIMITIVESTRIDEDDATA structure.
3623 * PrimitiveType: The primitive type to draw
3624 * VertexType: The FVF description of the vertices to draw (for the stride??)
3625 * D3DDrawPrimStrideData: A D3DDRAWPRIMITIVESTRIDEDDATA structure describing
3626 * the vertex data locations
3627 * VertexCount: The number of vertices to draw
3631 * D3D_OK, because it's a stub
3632 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
3633 * (For details, see IWineD3DDevice::DrawPrimitiveStrided)
3635 *****************************************************************************/
3636 static HRESULT WINAPI
3637 IDirect3DDeviceImpl_7_DrawPrimitiveStrided(IDirect3DDevice7 *iface,
3638 D3DPRIMITIVETYPE PrimitiveType,
3640 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3644 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3645 WineDirect3DVertexStridedData WineD3DStrided;
3647 UINT PrimitiveCount;
3650 TRACE("(%p)->(%08x,%08x,%p,%08x,%08x): stub!\n", This, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
3652 memset(&WineD3DStrided, 0, sizeof(WineD3DStrided));
3653 /* Get the strided data right. the wined3d structure is a bit bigger
3654 * Watch out: The contents of the strided data are determined by the fvf,
3655 * not by the members set in D3DDrawPrimStrideData. So it's valid
3656 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
3657 * not set in the fvf.
3659 if(VertexType & D3DFVF_POSITION_MASK)
3661 WineD3DStrided.u.s.position.lpData = D3DDrawPrimStrideData->position.lpvData;
3662 WineD3DStrided.u.s.position.dwStride = D3DDrawPrimStrideData->position.dwStride;
3663 WineD3DStrided.u.s.position.dwType = WINED3DDECLTYPE_FLOAT3;
3664 if (VertexType & D3DFVF_XYZRHW)
3666 WineD3DStrided.u.s.position.dwType = WINED3DDECLTYPE_FLOAT4;
3667 WineD3DStrided.u.s.position_transformed = TRUE;
3669 WineD3DStrided.u.s.position_transformed = FALSE;
3672 if(VertexType & D3DFVF_NORMAL)
3674 WineD3DStrided.u.s.normal.lpData = D3DDrawPrimStrideData->normal.lpvData;
3675 WineD3DStrided.u.s.normal.dwStride = D3DDrawPrimStrideData->normal.dwStride;
3676 WineD3DStrided.u.s.normal.dwType = WINED3DDECLTYPE_FLOAT3;
3679 if(VertexType & D3DFVF_DIFFUSE)
3681 WineD3DStrided.u.s.diffuse.lpData = D3DDrawPrimStrideData->diffuse.lpvData;
3682 WineD3DStrided.u.s.diffuse.dwStride = D3DDrawPrimStrideData->diffuse.dwStride;
3683 WineD3DStrided.u.s.diffuse.dwType = WINED3DDECLTYPE_D3DCOLOR;
3686 if(VertexType & D3DFVF_SPECULAR)
3688 WineD3DStrided.u.s.specular.lpData = D3DDrawPrimStrideData->specular.lpvData;
3689 WineD3DStrided.u.s.specular.dwStride = D3DDrawPrimStrideData->specular.dwStride;
3690 WineD3DStrided.u.s.specular.dwType = WINED3DDECLTYPE_D3DCOLOR;
3693 for( i = 0; i < GET_TEXCOUNT_FROM_FVF(VertexType); i++)
3695 WineD3DStrided.u.s.texCoords[i].lpData = D3DDrawPrimStrideData->textureCoords[i].lpvData;
3696 WineD3DStrided.u.s.texCoords[i].dwStride = D3DDrawPrimStrideData->textureCoords[i].dwStride;
3697 switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i))
3699 case 1: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT1; break;
3700 case 2: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT2; break;
3701 case 3: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT3; break;
3702 case 4: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT4; break;
3703 default: ERR("Unexpected texture coordinate size %d\n",
3704 GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i));
3708 /* Get the primitive count */
3709 switch(PrimitiveType)
3711 case D3DPT_POINTLIST:
3712 PrimitiveCount = VertexCount;
3715 case D3DPT_LINELIST:
3716 PrimitiveCount = VertexCount / 2;
3719 case D3DPT_LINESTRIP:
3720 PrimitiveCount = VertexCount - 1;
3723 case D3DPT_TRIANGLELIST:
3724 PrimitiveCount = VertexCount / 3;
3727 case D3DPT_TRIANGLESTRIP:
3728 PrimitiveCount = VertexCount - 2;
3731 case D3DPT_TRIANGLEFAN:
3732 PrimitiveCount = VertexCount - 2;
3735 default: return DDERR_INVALIDPARAMS;
3738 /* WineD3D doesn't need the FVF here */
3739 EnterCriticalSection(&ddraw_cs);
3740 hr = IWineD3DDevice_DrawPrimitiveStrided(This->wineD3DDevice,
3744 LeaveCriticalSection(&ddraw_cs);
3748 static HRESULT WINAPI
3749 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided(IDirect3DDevice3 *iface,
3750 D3DPRIMITIVETYPE PrimitiveType,
3752 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3756 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3757 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
3758 return IDirect3DDevice7_DrawPrimitiveStrided(ICOM_INTERFACE(This, IDirect3DDevice7),
3761 D3DDrawPrimStrideData,
3766 /*****************************************************************************
3767 * IDirect3DDevice7::DrawIndexedPrimitiveStrided
3769 * Draws primitives specified by strided data locations based on indices
3777 * D3D_OK, because it's a stub
3778 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
3779 * (DDERR_INVALIDPARAMS if Indices is NULL)
3780 * (For more details, see IWineD3DDevice::DrawIndexedPrimitiveStrided)
3782 *****************************************************************************/
3783 static HRESULT WINAPI
3784 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(IDirect3DDevice7 *iface,
3785 D3DPRIMITIVETYPE PrimitiveType,
3787 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3793 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3794 WineDirect3DVertexStridedData WineD3DStrided;
3796 UINT PrimitiveCount;
3799 TRACE("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x)\n", This, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
3801 memset(&WineD3DStrided, 0, sizeof(WineD3DStrided));
3802 /* Get the strided data right. the wined3d structure is a bit bigger
3803 * Watch out: The contents of the strided data are determined by the fvf,
3804 * not by the members set in D3DDrawPrimStrideData. So it's valid
3805 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
3806 * not set in the fvf.
3808 if(VertexType & D3DFVF_POSITION_MASK)
3810 WineD3DStrided.u.s.position.lpData = D3DDrawPrimStrideData->position.lpvData;
3811 WineD3DStrided.u.s.position.dwStride = D3DDrawPrimStrideData->position.dwStride;
3812 WineD3DStrided.u.s.position.dwType = WINED3DDECLTYPE_FLOAT3;
3813 if (VertexType & D3DFVF_XYZRHW)
3815 WineD3DStrided.u.s.position.dwType = WINED3DDECLTYPE_FLOAT4;
3816 WineD3DStrided.u.s.position_transformed = TRUE;
3818 WineD3DStrided.u.s.position_transformed = FALSE;
3821 if(VertexType & D3DFVF_NORMAL)
3823 WineD3DStrided.u.s.normal.lpData = D3DDrawPrimStrideData->normal.lpvData;
3824 WineD3DStrided.u.s.normal.dwStride = D3DDrawPrimStrideData->normal.dwStride;
3825 WineD3DStrided.u.s.normal.dwType = WINED3DDECLTYPE_FLOAT3;
3828 if(VertexType & D3DFVF_DIFFUSE)
3830 WineD3DStrided.u.s.diffuse.lpData = D3DDrawPrimStrideData->diffuse.lpvData;
3831 WineD3DStrided.u.s.diffuse.dwStride = D3DDrawPrimStrideData->diffuse.dwStride;
3832 WineD3DStrided.u.s.diffuse.dwType = WINED3DDECLTYPE_D3DCOLOR;
3835 if(VertexType & D3DFVF_SPECULAR)
3837 WineD3DStrided.u.s.specular.lpData = D3DDrawPrimStrideData->specular.lpvData;
3838 WineD3DStrided.u.s.specular.dwStride = D3DDrawPrimStrideData->specular.dwStride;
3839 WineD3DStrided.u.s.specular.dwType = WINED3DDECLTYPE_D3DCOLOR;
3842 for( i = 0; i < GET_TEXCOUNT_FROM_FVF(VertexType); i++)
3844 WineD3DStrided.u.s.texCoords[i].lpData = D3DDrawPrimStrideData->textureCoords[i].lpvData;
3845 WineD3DStrided.u.s.texCoords[i].dwStride = D3DDrawPrimStrideData->textureCoords[i].dwStride;
3846 switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i))
3848 case 1: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT1; break;
3849 case 2: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT2; break;
3850 case 3: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT3; break;
3851 case 4: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT4; break;
3852 default: ERR("Unexpected texture coordinate size %d\n",
3853 GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i));
3857 /* Get the primitive count */
3858 switch(PrimitiveType)
3860 case D3DPT_POINTLIST:
3861 PrimitiveCount = IndexCount;
3864 case D3DPT_LINELIST:
3865 PrimitiveCount = IndexCount / 2;
3868 case D3DPT_LINESTRIP:
3869 PrimitiveCount = IndexCount - 1;
3872 case D3DPT_TRIANGLELIST:
3873 PrimitiveCount = IndexCount / 3;
3876 case D3DPT_TRIANGLESTRIP:
3877 PrimitiveCount = IndexCount - 2;
3880 case D3DPT_TRIANGLEFAN:
3881 PrimitiveCount = IndexCount - 2;
3884 default: return DDERR_INVALIDPARAMS;
3887 /* WineD3D doesn't need the FVF here */
3888 EnterCriticalSection(&ddraw_cs);
3889 hr = IWineD3DDevice_DrawIndexedPrimitiveStrided(This->wineD3DDevice,
3895 WINED3DFMT_INDEX16);
3896 LeaveCriticalSection(&ddraw_cs);
3900 static HRESULT WINAPI
3901 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided(IDirect3DDevice3 *iface,
3902 D3DPRIMITIVETYPE PrimitiveType,
3904 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3910 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3911 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
3912 return IDirect3DDevice7_DrawIndexedPrimitiveStrided(ICOM_INTERFACE(This, IDirect3DDevice7),
3915 D3DDrawPrimStrideData,
3922 /*****************************************************************************
3923 * IDirect3DDevice7::DrawPrimitiveVB
3925 * Draws primitives from a vertex buffer to the screen.
3930 * PrimitiveType: Type of primitive to be rendered.
3931 * D3DVertexBuf: Source Vertex Buffer
3932 * StartVertex: Index of the first vertex from the buffer to be rendered
3933 * NumVertices: Number of vertices to be rendered
3934 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
3938 * DDERR_INVALIDPARAMS if D3DVertexBuf is NULL
3940 *****************************************************************************/
3941 static HRESULT WINAPI
3942 IDirect3DDeviceImpl_7_DrawPrimitiveVB(IDirect3DDevice7 *iface,
3943 D3DPRIMITIVETYPE PrimitiveType,
3944 IDirect3DVertexBuffer7 *D3DVertexBuf,
3949 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3950 IDirect3DVertexBufferImpl *vb = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, D3DVertexBuf);
3951 UINT PrimitiveCount;
3954 WINED3DVERTEXBUFFER_DESC Desc;
3956 TRACE("(%p)->(%08x,%p,%08x,%08x,%08x)\n", This, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags);
3961 ERR("(%p) No Vertex buffer specified\n", This);
3962 return DDERR_INVALIDPARAMS;
3965 /* Get the primitive count */
3966 switch(PrimitiveType)
3968 case D3DPT_POINTLIST:
3969 PrimitiveCount = NumVertices;
3972 case D3DPT_LINELIST:
3973 PrimitiveCount = NumVertices / 2;
3976 case D3DPT_LINESTRIP:
3977 PrimitiveCount = NumVertices - 1;
3980 case D3DPT_TRIANGLELIST:
3981 PrimitiveCount = NumVertices / 3;
3984 case D3DPT_TRIANGLESTRIP:
3985 PrimitiveCount = NumVertices - 2;
3988 case D3DPT_TRIANGLEFAN:
3989 PrimitiveCount = NumVertices - 2;
3993 return DDERR_INVALIDPARAMS;
3996 /* Get the FVF of the vertex buffer, and its stride */
3997 EnterCriticalSection(&ddraw_cs);
3998 hr = IWineD3DVertexBuffer_GetDesc(vb->wineD3DVertexBuffer,
4002 ERR("(%p) IWineD3DVertexBuffer::GetDesc failed with hr = %08x\n", This, hr);
4003 LeaveCriticalSection(&ddraw_cs);
4006 stride = get_flexible_vertex_size(Desc.FVF);
4008 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
4009 vb->wineD3DVertexDeclaration);
4012 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr);
4013 LeaveCriticalSection(&ddraw_cs);
4017 /* Set the vertex stream source */
4018 hr = IWineD3DDevice_SetStreamSource(This->wineD3DDevice,
4019 0 /* StreamNumber */,
4020 vb->wineD3DVertexBuffer,
4021 0 /* StartVertex - we pass this to DrawPrimitive */,
4025 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This, hr);
4026 LeaveCriticalSection(&ddraw_cs);
4030 /* Now draw the primitives */
4031 hr = IWineD3DDevice_DrawPrimitive(This->wineD3DDevice,
4035 LeaveCriticalSection(&ddraw_cs);
4039 static HRESULT WINAPI
4040 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB(IDirect3DDevice3 *iface,
4041 D3DPRIMITIVETYPE PrimitiveType,
4042 IDirect3DVertexBuffer *D3DVertexBuf,
4047 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4048 IDirect3DVertexBufferImpl *vb = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, D3DVertexBuf);
4049 TRACE_(ddraw_thunk)("(%p)->(%08x,%p,%08x,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, vb, StartVertex, NumVertices, Flags);
4050 return IDirect3DDevice7_DrawPrimitiveVB(ICOM_INTERFACE(This, IDirect3DDevice7),
4052 ICOM_INTERFACE(vb, IDirect3DVertexBuffer7),
4059 /*****************************************************************************
4060 * IDirect3DDevice7::DrawIndexedPrimitiveVB
4062 * Draws primitives from a vertex buffer to the screen
4065 * PrimitiveType: Type of primitive to be rendered.
4066 * D3DVertexBuf: Source Vertex Buffer
4067 * StartVertex: Index of the first vertex from the buffer to be rendered
4068 * NumVertices: Number of vertices to be rendered
4069 * Indices: Array of DWORDs used to index into the Vertices
4070 * IndexCount: Number of indices in Indices
4071 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4075 *****************************************************************************/
4076 static HRESULT WINAPI
4077 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(IDirect3DDevice7 *iface,
4078 D3DPRIMITIVETYPE PrimitiveType,
4079 IDirect3DVertexBuffer7 *D3DVertexBuf,
4086 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4087 IDirect3DVertexBufferImpl *vb = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, D3DVertexBuf);
4089 UINT PrimitiveCount;
4090 WORD *LockedIndices;
4092 WINED3DVERTEXBUFFER_DESC Desc;
4094 TRACE("(%p)->(%08x,%p,%d,%d,%p,%d,%08x)\n", This, PrimitiveType, vb, StartVertex, NumVertices, Indices, IndexCount, Flags);
4097 * 1) Calculate some things: Vertex count -> Primitive count, stride, ...
4098 * 2) Upload the Indices to the index buffer
4099 * 3) Set the index source
4100 * 4) Set the Vertex Buffer as the Stream source
4101 * 5) Call IWineD3DDevice::DrawIndexedPrimitive
4104 /* Get the primitive count */
4105 switch(PrimitiveType)
4107 case D3DPT_POINTLIST:
4108 PrimitiveCount = IndexCount;
4111 case D3DPT_LINELIST:
4112 PrimitiveCount = IndexCount / 2;
4115 case D3DPT_LINESTRIP:
4116 PrimitiveCount = IndexCount - 1;
4119 case D3DPT_TRIANGLELIST:
4120 PrimitiveCount = IndexCount / 3;
4123 case D3DPT_TRIANGLESTRIP:
4124 PrimitiveCount = IndexCount - 2;
4127 case D3DPT_TRIANGLEFAN:
4128 PrimitiveCount = IndexCount - 2;
4131 default: return DDERR_INVALIDPARAMS;
4134 EnterCriticalSection(&ddraw_cs);
4135 /* Get the FVF of the vertex buffer, and its stride */
4136 hr = IWineD3DVertexBuffer_GetDesc(vb->wineD3DVertexBuffer,
4140 ERR("(%p) IWineD3DVertexBuffer::GetDesc failed with hr = %08x\n", This, hr);
4141 LeaveCriticalSection(&ddraw_cs);
4144 stride = get_flexible_vertex_size(Desc.FVF);
4145 TRACE("Vertex buffer FVF = %08x, stride=%d\n", Desc.FVF, stride);
4147 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
4148 vb->wineD3DVertexDeclaration);
4151 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr);
4152 LeaveCriticalSection(&ddraw_cs);
4156 /* copy the index stream into the index buffer.
4157 * A new IWineD3DDevice method could be created
4158 * which takes an user pointer containing the indices
4159 * or a SetData-Method for the index buffer, which
4160 * overrides the index buffer data with our pointer.
4162 hr = IWineD3DIndexBuffer_Lock(This->indexbuffer,
4163 0 /* OffSetToLock */,
4164 IndexCount * sizeof(WORD),
4165 (BYTE **) &LockedIndices,
4167 assert(IndexCount < 0x100000);
4170 ERR("(%p) IWineD3DIndexBuffer::Lock failed with hr = %08x\n", This, hr);
4171 LeaveCriticalSection(&ddraw_cs);
4174 memcpy(LockedIndices, Indices, IndexCount * sizeof(WORD));
4175 hr = IWineD3DIndexBuffer_Unlock(This->indexbuffer);
4178 ERR("(%p) IWineD3DIndexBuffer::Unlock failed with hr = %08x\n", This, hr);
4179 LeaveCriticalSection(&ddraw_cs);
4183 /* Set the index stream */
4184 IWineD3DDevice_SetBaseVertexIndex(This->wineD3DDevice, StartVertex);
4185 hr = IWineD3DDevice_SetIndices(This->wineD3DDevice, This->indexbuffer);
4187 /* Set the vertex stream source */
4188 hr = IWineD3DDevice_SetStreamSource(This->wineD3DDevice,
4189 0 /* StreamNumber */,
4190 vb->wineD3DVertexBuffer,
4191 0 /* offset, we pass this to DrawIndexedPrimitive */,
4195 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This, hr);
4196 LeaveCriticalSection(&ddraw_cs);
4201 hr = IWineD3DDevice_DrawIndexedPrimitive(This->wineD3DDevice,
4208 LeaveCriticalSection(&ddraw_cs);
4212 static HRESULT WINAPI
4213 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB(IDirect3DDevice3 *iface,
4214 D3DPRIMITIVETYPE PrimitiveType,
4215 IDirect3DVertexBuffer *D3DVertexBuf,
4220 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4221 IDirect3DVertexBufferImpl *VB = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, D3DVertexBuf);
4222 TRACE_(ddraw_thunk)("(%p)->(%08x,%p,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VB, Indices, IndexCount, Flags);
4224 return IDirect3DDevice7_DrawIndexedPrimitiveVB(ICOM_INTERFACE(This, IDirect3DDevice7),
4226 ICOM_INTERFACE(VB, IDirect3DVertexBuffer7),
4234 /*****************************************************************************
4235 * IDirect3DDevice7::ComputeSphereVisibility
4237 * Calculates the visibility of spheres in the current viewport. The spheres
4238 * are passed in the Centers and Radii arrays, the results are passed back
4239 * in the ReturnValues array. Return values are either completely visible,
4240 * partially visible or completely invisible.
4241 * The return value consist of a combination of D3DCLIP_* flags, or it's
4242 * 0 if the sphere is completely visible(according to the SDK, not checked)
4244 * Sounds like an overdose of math ;)
4249 * Centers: Array containing the sphere centers
4250 * Radii: Array containing the sphere radii
4251 * NumSpheres: The number of centers and radii in the arrays
4253 * ReturnValues: Array to write the results to
4256 * D3D_OK because it's a stub
4257 * (DDERR_INVALIDPARAMS if Centers, Radii or ReturnValues are NULL)
4258 * (D3DERR_INVALIDMATRIX if the combined world, view and proj matrix
4261 *****************************************************************************/
4262 static HRESULT WINAPI
4263 IDirect3DDeviceImpl_7_ComputeSphereVisibility(IDirect3DDevice7 *iface,
4268 DWORD *ReturnValues)
4270 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4271 FIXME("(%p)->(%p,%p,%08x,%08x,%p): stub!\n", This, Centers, Radii, NumSpheres, Flags, ReturnValues);
4273 /* the DirectX 7 sdk says that the visibility is computed by
4274 * back-transforming the viewing frustum to model space
4275 * using the inverse of the combined world, view and projection
4276 * matrix. If the matrix can't be reversed, D3DERR_INVALIDMATRIX
4279 * Basic implementation idea:
4280 * 1) Check if the center is in the viewing frustum
4281 * 2) Cut the sphere with the planes of the viewing
4284 * ->Center inside the frustum, no intersections:
4286 * ->Center outside the frustum, no intersections:
4288 * ->Some intersections: Partially visible
4290 * Implement this call in WineD3D. Either implement the
4291 * matrix and vector stuff in WineD3D, or use some external
4298 static HRESULT WINAPI
4299 Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility(IDirect3DDevice3 *iface,
4304 DWORD *ReturnValues)
4306 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4307 TRACE_(ddraw_thunk)("(%p)->(%p,%p,%08x,%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, Centers, Radii, NumSpheres, Flags, ReturnValues);
4308 return IDirect3DDevice7_ComputeSphereVisibility(ICOM_INTERFACE(This, IDirect3DDevice7),
4316 /*****************************************************************************
4317 * IDirect3DDevice7::GetTexture
4319 * Returns the texture interface handle assigned to a texture stage.
4320 * The returned texture is AddRefed. This is taken from old ddraw,
4321 * not checked in Windows.
4326 * Stage: Texture stage to read the texture from
4327 * Texture: Address to store the interface pointer at
4331 * DDERR_INVALIDPARAMS if Texture is NULL
4332 * For details, see IWineD3DDevice::GetTexture
4334 *****************************************************************************/
4335 static HRESULT WINAPI
4336 IDirect3DDeviceImpl_7_GetTexture(IDirect3DDevice7 *iface,
4338 IDirectDrawSurface7 **Texture)
4340 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4341 IWineD3DBaseTexture *Surf;
4343 TRACE("(%p)->(%d,%p): Relay\n", This, Stage, Texture);
4347 TRACE("Texture == NULL, failing with DDERR_INVALIDPARAMS\n");
4348 return DDERR_INVALIDPARAMS;
4351 EnterCriticalSection(&ddraw_cs);
4352 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice, Stage, &Surf);
4353 if( (hr != D3D_OK) || (!Surf) )
4356 LeaveCriticalSection(&ddraw_cs);
4360 /* GetParent AddRef()s, which is perfectly OK.
4361 * We have passed the IDirectDrawSurface7 interface to WineD3D, so that's OK too.
4363 hr = IWineD3DBaseTexture_GetParent(Surf,
4364 (IUnknown **) Texture);
4365 LeaveCriticalSection(&ddraw_cs);
4369 static HRESULT WINAPI
4370 Thunk_IDirect3DDeviceImpl_3_GetTexture(IDirect3DDevice3 *iface,
4372 IDirect3DTexture2 **Texture2)
4374 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4376 IDirectDrawSurface7 *ret_val;
4378 TRACE_(ddraw_thunk)("(%p)->(%d,%p) thunking to IDirect3DDevice7 interface.\n", This, Stage, Texture2);
4379 ret = IDirect3DDevice7_GetTexture(ICOM_INTERFACE(This, IDirect3DDevice7),
4383 *Texture2 = COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7, IDirect3DTexture2, ret_val);
4385 TRACE_(ddraw_thunk)(" returning interface %p.\n", *Texture2);
4390 /*****************************************************************************
4391 * IDirect3DDevice7::SetTexture
4393 * Assigns a texture to a texture stage. Is the texture AddRef-ed?
4398 * Stage: The stage to assign the texture to
4399 * Texture: Interface pointer to the texture surface
4403 * For details, see IWineD3DDevice::SetTexture
4405 *****************************************************************************/
4406 static HRESULT WINAPI
4407 IDirect3DDeviceImpl_7_SetTexture(IDirect3DDevice7 *iface,
4409 IDirectDrawSurface7 *Texture)
4411 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4412 IDirectDrawSurfaceImpl *surf = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, Texture);
4414 TRACE("(%p)->(%08x,%p): Relay!\n", This, Stage, surf);
4416 /* Texture may be NULL here */
4417 EnterCriticalSection(&ddraw_cs);
4418 hr = IWineD3DDevice_SetTexture(This->wineD3DDevice,
4420 surf ? surf->wineD3DTexture : NULL);
4421 LeaveCriticalSection(&ddraw_cs);
4425 static HRESULT WINAPI
4426 IDirect3DDeviceImpl_3_SetTexture(IDirect3DDevice3 *iface,
4428 IDirect3DTexture2 *Texture2)
4430 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4431 IDirectDrawSurfaceImpl *tex = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture2, Texture2);
4434 TRACE("(%p)->(%d,%p)\n", This, Stage, tex);
4436 EnterCriticalSection(&ddraw_cs);
4438 if (This->legacyTextureBlending)
4439 IDirect3DDevice3_GetRenderState(iface, D3DRENDERSTATE_TEXTUREMAPBLEND, &texmapblend);
4441 hr = IDirect3DDevice7_SetTexture(ICOM_INTERFACE(This, IDirect3DDevice7),
4443 ICOM_INTERFACE(tex, IDirectDrawSurface7));
4445 if (This->legacyTextureBlending && texmapblend == D3DTBLEND_MODULATE)
4447 /* This fixup is required by the way D3DTBLEND_MODULATE maps to texture stage states.
4448 See IDirect3DDeviceImpl_3_SetRenderState for details. */
4449 BOOL tex_alpha = FALSE;
4450 IWineD3DBaseTexture *tex = NULL;
4451 WINED3DSURFACE_DESC desc;
4453 DDPIXELFORMAT ddfmt;
4456 result = IWineD3DDevice_GetTexture(This->wineD3DDevice,
4460 if(result == WINED3D_OK && tex)
4462 memset(&desc, 0, sizeof(desc));
4464 result = IWineD3DTexture_GetLevelDesc((IWineD3DTexture*) tex, 0, &desc);
4465 if (SUCCEEDED(result))
4467 ddfmt.dwSize = sizeof(ddfmt);
4468 PixelFormat_WineD3DtoDD(&ddfmt, fmt);
4469 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
4472 IWineD3DBaseTexture_Release(tex);
4475 /* alphaop is WINED3DTOP_SELECTARG1 if it's D3DTBLEND_MODULATE, so only modify alphaarg1 */
4478 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
4482 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_CURRENT);
4486 LeaveCriticalSection(&ddraw_cs);
4491 /*****************************************************************************
4492 * IDirect3DDevice7::GetTextureStageState
4494 * Retrieves a state from a texture stage.
4499 * Stage: The stage to retrieve the state from
4500 * TexStageStateType: The state type to retrieve
4501 * State: Address to store the state's value at
4505 * DDERR_INVALIDPARAMS if State is NULL
4506 * For details, see IWineD3DDevice::GetTextureStageState
4508 *****************************************************************************/
4509 static HRESULT WINAPI
4510 IDirect3DDeviceImpl_7_GetTextureStageState(IDirect3DDevice7 *iface,
4512 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4515 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4517 TRACE("(%p)->(%08x,%08x,%p): Relay!\n", This, Stage, TexStageStateType, State);
4520 return DDERR_INVALIDPARAMS;
4522 EnterCriticalSection(&ddraw_cs);
4523 switch(TexStageStateType)
4525 /* Mipfilter is a sampler state with different values */
4526 case D3DTSS_MIPFILTER:
4528 WINED3DTEXTUREFILTERTYPE value;
4530 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
4532 WINED3DSAMP_MIPFILTER,
4536 case WINED3DTEXF_NONE: *State = D3DTFP_NONE; break;
4537 case WINED3DTEXF_POINT: *State = D3DTFP_POINT; break;
4538 case WINED3DTEXF_LINEAR: *State = D3DTFP_LINEAR; break;
4540 ERR("Unexpected mipfilter value %d\n", value);
4541 *State = D3DTFP_NONE;
4546 /* Minfilter is a sampler state too, equal values */
4547 case D3DTSS_MINFILTER:
4548 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
4550 WINED3DSAMP_MINFILTER,
4554 /* Magfilter has slightly different values */
4555 case D3DTSS_MAGFILTER:
4557 WINED3DTEXTUREFILTERTYPE wined3dfilter;
4558 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
4560 WINED3DSAMP_MAGFILTER,
4562 switch(wined3dfilter)
4564 case WINED3DTEXF_POINT: *State = D3DTFG_POINT; break;
4565 case WINED3DTEXF_LINEAR: *State = D3DTFG_LINEAR; break;
4566 case WINED3DTEXF_ANISOTROPIC: *State = D3DTFG_ANISOTROPIC; break;
4567 case WINED3DTEXF_FLATCUBIC: *State = D3DTFG_FLATCUBIC; break;
4568 case WINED3DTEXF_GAUSSIANCUBIC: *State = D3DTFG_GAUSSIANCUBIC; break;
4570 ERR("Unexpected wined3d mag filter value %d\n", wined3dfilter);
4571 *State = D3DTFG_POINT;
4576 case D3DTSS_ADDRESS:
4577 case D3DTSS_ADDRESSU:
4578 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
4580 WINED3DSAMP_ADDRESSU,
4583 case D3DTSS_ADDRESSV:
4584 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
4586 WINED3DSAMP_ADDRESSV,
4590 hr = IWineD3DDevice_GetTextureStageState(This->wineD3DDevice,
4596 LeaveCriticalSection(&ddraw_cs);
4600 static HRESULT WINAPI
4601 Thunk_IDirect3DDeviceImpl_3_GetTextureStageState(IDirect3DDevice3 *iface,
4603 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4606 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4607 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, Stage, TexStageStateType, State);
4608 return IDirect3DDevice7_GetTextureStageState(ICOM_INTERFACE(This, IDirect3DDevice7),
4614 /*****************************************************************************
4615 * IDirect3DDevice7::SetTextureStageState
4617 * Sets a texture stage state. Some stage types need to be handled specially,
4618 * because they do not exist in WineD3D and were moved to another place
4623 * Stage: The stage to modify
4624 * TexStageStateType: The state to change
4625 * State: The new value for the state
4629 * For details, see IWineD3DDevice::SetTextureStageState
4631 *****************************************************************************/
4632 static HRESULT WINAPI
4633 IDirect3DDeviceImpl_7_SetTextureStageState(IDirect3DDevice7 *iface,
4635 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4638 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4640 TRACE("(%p)->(%08x,%08x,%08x): Relay!\n", This, Stage, TexStageStateType, State);
4642 EnterCriticalSection(&ddraw_cs);
4643 switch(TexStageStateType)
4645 /* Mipfilter is a sampler state with different values */
4646 case D3DTSS_MIPFILTER:
4648 WINED3DTEXTUREFILTERTYPE value;
4651 case D3DTFP_NONE: value = WINED3DTEXF_NONE; break;
4652 case D3DTFP_POINT: value = WINED3DTEXF_POINT; break;
4653 case 0: /* Unchecked */
4654 case D3DTFP_LINEAR: value = WINED3DTEXF_LINEAR; break;
4656 ERR("Unexpected mipfilter value %d\n", State);
4657 value = WINED3DTEXF_NONE;
4659 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
4661 WINED3DSAMP_MIPFILTER,
4666 /* Minfilter is a sampler state too, equal values */
4667 case D3DTSS_MINFILTER:
4668 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
4670 WINED3DSAMP_MINFILTER,
4674 /* Magfilter has slightly different values */
4675 case D3DTSS_MAGFILTER:
4677 WINED3DTEXTUREFILTERTYPE wined3dfilter;
4678 switch((D3DTEXTUREMAGFILTER) State)
4680 case D3DTFG_POINT: wined3dfilter = WINED3DTEXF_POINT; break;
4681 case D3DTFG_LINEAR: wined3dfilter = WINED3DTEXF_LINEAR; break;
4682 case D3DTFG_FLATCUBIC: wined3dfilter = WINED3DTEXF_FLATCUBIC; break;
4683 case D3DTFG_GAUSSIANCUBIC: wined3dfilter = WINED3DTEXF_GAUSSIANCUBIC; break;
4684 case D3DTFG_ANISOTROPIC: wined3dfilter = WINED3DTEXF_ANISOTROPIC; break;
4686 ERR("Unexpected d3d7 mag filter type %d\n", State);
4687 wined3dfilter = WINED3DTEXF_POINT;
4689 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
4691 WINED3DSAMP_MAGFILTER,
4696 case D3DTSS_ADDRESS:
4697 IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
4699 WINED3DSAMP_ADDRESSV,
4702 case D3DTSS_ADDRESSU:
4703 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
4705 WINED3DSAMP_ADDRESSU,
4709 case D3DTSS_ADDRESSV:
4710 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
4712 WINED3DSAMP_ADDRESSV,
4717 hr = IWineD3DDevice_SetTextureStageState(This->wineD3DDevice,
4723 LeaveCriticalSection(&ddraw_cs);
4727 static HRESULT WINAPI
4728 Thunk_IDirect3DDeviceImpl_3_SetTextureStageState(IDirect3DDevice3 *iface,
4730 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4733 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4734 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, Stage, TexStageStateType, State);
4735 return IDirect3DDevice7_SetTextureStageState(ICOM_INTERFACE(This, IDirect3DDevice7),
4741 /*****************************************************************************
4742 * IDirect3DDevice7::ValidateDevice
4744 * SDK: "Reports the device's ability to render the currently set
4745 * texture-blending operations in a single pass". Whatever that means
4751 * NumPasses: Address to write the number of necessary passes for the
4752 * desired effect to.
4756 * See IWineD3DDevice::ValidateDevice for more details
4758 *****************************************************************************/
4759 static HRESULT WINAPI
4760 IDirect3DDeviceImpl_7_ValidateDevice(IDirect3DDevice7 *iface,
4763 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4765 TRACE("(%p)->(%p): Relay\n", This, NumPasses);
4767 EnterCriticalSection(&ddraw_cs);
4768 hr = IWineD3DDevice_ValidateDevice(This->wineD3DDevice, NumPasses);
4769 LeaveCriticalSection(&ddraw_cs);
4773 static HRESULT WINAPI
4774 Thunk_IDirect3DDeviceImpl_3_ValidateDevice(IDirect3DDevice3 *iface,
4777 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4778 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Passes);
4779 return IDirect3DDevice7_ValidateDevice(ICOM_INTERFACE(This, IDirect3DDevice7),
4783 /*****************************************************************************
4784 * IDirect3DDevice7::Clear
4786 * Fills the render target, the z buffer and the stencil buffer with a
4787 * clear color / value
4792 * Count: Number of rectangles in Rects must be 0 if Rects is NULL
4793 * Rects: Rectangles to clear. If NULL, the whole surface is cleared
4794 * Flags: Some flags, as usual
4795 * Color: Clear color for the render target
4796 * Z: Clear value for the Z buffer
4797 * Stencil: Clear value to store in each stencil buffer entry
4801 * For details, see IWineD3DDevice::Clear
4803 *****************************************************************************/
4804 static HRESULT WINAPI
4805 IDirect3DDeviceImpl_7_Clear(IDirect3DDevice7 *iface,
4813 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4815 TRACE("(%p)->(%08x,%p,%08x,%08x,%f,%08x): Relay\n", This, Count, Rects, Flags, Color, Z, Stencil);
4817 /* Note; D3DRECT is compatible with WINED3DRECT */
4818 EnterCriticalSection(&ddraw_cs);
4819 hr = IWineD3DDevice_Clear(This->wineD3DDevice, Count, (WINED3DRECT*) Rects, Flags, Color, Z, Stencil);
4820 LeaveCriticalSection(&ddraw_cs);
4824 /*****************************************************************************
4825 * IDirect3DDevice7::SetViewport
4827 * Sets the current viewport.
4829 * Version 7 only, but IDirect3DViewport uses this call for older
4833 * Data: The new viewport to set
4837 * DDERR_INVALIDPARAMS if Data is NULL
4838 * For more details, see IWineDDDevice::SetViewport
4840 *****************************************************************************/
4841 static HRESULT WINAPI
4842 IDirect3DDeviceImpl_7_SetViewport(IDirect3DDevice7 *iface,
4845 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4847 TRACE("(%p)->(%p) Relay!\n", This, Data);
4850 return DDERR_INVALIDPARAMS;
4852 /* Note: D3DVIEWPORT7 is compatible with WINED3DVIEWPORT */
4853 EnterCriticalSection(&ddraw_cs);
4854 hr = IWineD3DDevice_SetViewport(This->wineD3DDevice,
4855 (WINED3DVIEWPORT*) Data);
4856 LeaveCriticalSection(&ddraw_cs);
4860 /*****************************************************************************
4861 * IDirect3DDevice::GetViewport
4863 * Returns the current viewport
4868 * Data: D3D7Viewport structure to write the viewport information to
4872 * DDERR_INVALIDPARAMS if Data is NULL
4873 * For more details, see IWineD3DDevice::GetViewport
4875 *****************************************************************************/
4876 static HRESULT WINAPI
4877 IDirect3DDeviceImpl_7_GetViewport(IDirect3DDevice7 *iface,
4880 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4882 TRACE("(%p)->(%p) Relay!\n", This, Data);
4885 return DDERR_INVALIDPARAMS;
4887 /* Note: D3DVIEWPORT7 is compatible with WINED3DVIEWPORT */
4888 EnterCriticalSection(&ddraw_cs);
4889 hr = IWineD3DDevice_GetViewport(This->wineD3DDevice,
4890 (WINED3DVIEWPORT*) Data);
4892 LeaveCriticalSection(&ddraw_cs);
4893 return hr_ddraw_from_wined3d(hr);
4896 /*****************************************************************************
4897 * IDirect3DDevice7::SetMaterial
4904 * Mat: The material to set
4908 * DDERR_INVALIDPARAMS if Mat is NULL.
4909 * For more details, see IWineD3DDevice::SetMaterial
4911 *****************************************************************************/
4912 static HRESULT WINAPI
4913 IDirect3DDeviceImpl_7_SetMaterial(IDirect3DDevice7 *iface,
4916 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4918 TRACE("(%p)->(%p): Relay!\n", This, Mat);
4920 /* Note: D3DMATERIAL7 is compatible with WINED3DMATERIAL */
4921 EnterCriticalSection(&ddraw_cs);
4922 hr = IWineD3DDevice_SetMaterial(This->wineD3DDevice,
4923 (WINED3DMATERIAL*) Mat);
4924 LeaveCriticalSection(&ddraw_cs);
4925 return hr_ddraw_from_wined3d(hr);
4928 /*****************************************************************************
4929 * IDirect3DDevice7::GetMaterial
4931 * Returns the current material
4936 * Mat: D3DMATERIAL7 structure to write the material parameters to
4940 * DDERR_INVALIDPARAMS if Mat is NULL
4941 * For more details, see IWineD3DDevice::GetMaterial
4943 *****************************************************************************/
4944 static HRESULT WINAPI
4945 IDirect3DDeviceImpl_7_GetMaterial(IDirect3DDevice7 *iface,
4948 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4950 TRACE("(%p)->(%p): Relay!\n", This, Mat);
4952 EnterCriticalSection(&ddraw_cs);
4953 /* Note: D3DMATERIAL7 is compatible with WINED3DMATERIAL */
4954 hr = IWineD3DDevice_GetMaterial(This->wineD3DDevice,
4955 (WINED3DMATERIAL*) Mat);
4956 LeaveCriticalSection(&ddraw_cs);
4957 return hr_ddraw_from_wined3d(hr);
4960 /*****************************************************************************
4961 * IDirect3DDevice7::SetLight
4963 * Assigns a light to a light index, but doesn't activate it yet.
4965 * Version 7, IDirect3DLight uses this method for older versions
4968 * LightIndex: The index of the new light
4969 * Light: A D3DLIGHT7 structure describing the light
4973 * For more details, see IWineD3DDevice::SetLight
4975 *****************************************************************************/
4976 static HRESULT WINAPI
4977 IDirect3DDeviceImpl_7_SetLight(IDirect3DDevice7 *iface,
4981 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4983 TRACE("(%p)->(%08x,%p): Relay!\n", This, LightIndex, Light);
4985 EnterCriticalSection(&ddraw_cs);
4986 /* Note: D3DLIGHT7 is compatible with WINED3DLIGHT */
4987 hr = IWineD3DDevice_SetLight(This->wineD3DDevice,
4989 (WINED3DLIGHT*) Light);
4990 LeaveCriticalSection(&ddraw_cs);
4991 return hr_ddraw_from_wined3d(hr);
4994 /*****************************************************************************
4995 * IDirect3DDevice7::GetLight
4997 * Returns the light assigned to a light index
5000 * Light: Structure to write the light information to
5004 * DDERR_INVALIDPARAMS if Light is NULL
5005 * For details, see IWineD3DDevice::GetLight
5007 *****************************************************************************/
5008 static HRESULT WINAPI
5009 IDirect3DDeviceImpl_7_GetLight(IDirect3DDevice7 *iface,
5013 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5015 TRACE("(%p)->(%08x,%p): Relay!\n", This, LightIndex, Light);
5017 EnterCriticalSection(&ddraw_cs);
5018 /* Note: D3DLIGHT7 is compatible with WINED3DLIGHT */
5019 rc = IWineD3DDevice_GetLight(This->wineD3DDevice,
5021 (WINED3DLIGHT*) Light);
5023 /* Translate the result. WineD3D returns other values than D3D7 */
5024 LeaveCriticalSection(&ddraw_cs);
5025 return hr_ddraw_from_wined3d(rc);
5028 /*****************************************************************************
5029 * IDirect3DDevice7::BeginStateBlock
5031 * Begins recording to a stateblock
5037 * For details see IWineD3DDevice::BeginStateBlock
5039 *****************************************************************************/
5040 static HRESULT WINAPI
5041 IDirect3DDeviceImpl_7_BeginStateBlock(IDirect3DDevice7 *iface)
5043 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5045 TRACE("(%p)->(): Relay!\n", This);
5047 EnterCriticalSection(&ddraw_cs);
5048 hr = IWineD3DDevice_BeginStateBlock(This->wineD3DDevice);
5049 LeaveCriticalSection(&ddraw_cs);
5050 return hr_ddraw_from_wined3d(hr);
5053 /*****************************************************************************
5054 * IDirect3DDevice7::EndStateBlock
5056 * Stops recording to a state block and returns the created stateblock
5062 * BlockHandle: Address to store the stateblock's handle to
5066 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5067 * See IWineD3DDevice::EndStateBlock for more details
5069 *****************************************************************************/
5070 static HRESULT WINAPI
5071 IDirect3DDeviceImpl_7_EndStateBlock(IDirect3DDevice7 *iface,
5074 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5076 TRACE("(%p)->(%p): Relay!\n", This, BlockHandle);
5080 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
5081 return DDERR_INVALIDPARAMS;
5084 EnterCriticalSection(&ddraw_cs);
5085 *BlockHandle = IDirect3DDeviceImpl_CreateHandle(This);
5088 ERR("Cannot get a handle number for the stateblock\n");
5089 LeaveCriticalSection(&ddraw_cs);
5090 return DDERR_OUTOFMEMORY;
5092 This->Handles[*BlockHandle - 1].type = DDrawHandle_StateBlock;
5093 hr = IWineD3DDevice_EndStateBlock(This->wineD3DDevice,
5094 (IWineD3DStateBlock **) &This->Handles[*BlockHandle - 1].ptr);
5095 LeaveCriticalSection(&ddraw_cs);
5096 return hr_ddraw_from_wined3d(hr);
5099 /*****************************************************************************
5100 * IDirect3DDevice7::PreLoad
5102 * Allows the app to signal that a texture will be used soon, to allow
5103 * the Direct3DDevice to load it to the video card in the meantime.
5108 * Texture: The texture to preload
5112 * DDERR_INVALIDPARAMS if Texture is NULL
5113 * See IWineD3DSurface::PreLoad for details
5115 *****************************************************************************/
5116 static HRESULT WINAPI
5117 IDirect3DDeviceImpl_7_PreLoad(IDirect3DDevice7 *iface,
5118 IDirectDrawSurface7 *Texture)
5120 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5121 IDirectDrawSurfaceImpl *surf = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, Texture);
5123 TRACE("(%p)->(%p): Relay!\n", This, surf);
5126 return DDERR_INVALIDPARAMS;
5128 EnterCriticalSection(&ddraw_cs);
5129 IWineD3DSurface_PreLoad(surf->WineD3DSurface);
5130 LeaveCriticalSection(&ddraw_cs);
5134 /*****************************************************************************
5135 * IDirect3DDevice7::ApplyStateBlock
5137 * Activates the state stored in a state block handle.
5140 * BlockHandle: The stateblock handle to activate
5144 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5146 *****************************************************************************/
5147 static HRESULT WINAPI
5148 IDirect3DDeviceImpl_7_ApplyStateBlock(IDirect3DDevice7 *iface,
5151 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5153 TRACE("(%p)->(%08x): Relay!\n", This, BlockHandle);
5155 EnterCriticalSection(&ddraw_cs);
5156 if(!BlockHandle || BlockHandle > This->numHandles)
5158 WARN("Out of range handle %d, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5159 LeaveCriticalSection(&ddraw_cs);
5160 return D3DERR_INVALIDSTATEBLOCK;
5162 if(This->Handles[BlockHandle - 1].type != DDrawHandle_StateBlock)
5164 WARN("Handle %d is not a stateblock, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5165 LeaveCriticalSection(&ddraw_cs);
5166 return D3DERR_INVALIDSTATEBLOCK;
5169 hr = IWineD3DStateBlock_Apply((IWineD3DStateBlock *) This->Handles[BlockHandle - 1].ptr);
5170 LeaveCriticalSection(&ddraw_cs);
5171 return hr_ddraw_from_wined3d(hr);
5174 /*****************************************************************************
5175 * IDirect3DDevice7::CaptureStateBlock
5177 * Updates a stateblock's values to the values currently set for the device
5182 * BlockHandle: Stateblock to update
5186 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5187 * See IWineD3DDevice::CaptureStateBlock for more details
5189 *****************************************************************************/
5190 static HRESULT WINAPI
5191 IDirect3DDeviceImpl_7_CaptureStateBlock(IDirect3DDevice7 *iface,
5194 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5196 TRACE("(%p)->(%08x): Relay!\n", This, BlockHandle);
5198 EnterCriticalSection(&ddraw_cs);
5199 if(BlockHandle == 0 || BlockHandle > This->numHandles)
5201 WARN("Out of range handle %d, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5202 LeaveCriticalSection(&ddraw_cs);
5203 return D3DERR_INVALIDSTATEBLOCK;
5205 if(This->Handles[BlockHandle - 1].type != DDrawHandle_StateBlock)
5207 WARN("Handle %d is not a stateblock, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5208 LeaveCriticalSection(&ddraw_cs);
5209 return D3DERR_INVALIDSTATEBLOCK;
5212 hr = IWineD3DStateBlock_Capture((IWineD3DStateBlock *) This->Handles[BlockHandle - 1].ptr);
5213 LeaveCriticalSection(&ddraw_cs);
5214 return hr_ddraw_from_wined3d(hr);
5217 /*****************************************************************************
5218 * IDirect3DDevice7::DeleteStateBlock
5220 * Deletes a stateblock handle. This means releasing the WineD3DStateBlock
5225 * BlockHandle: Stateblock handle to delete
5229 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is 0
5231 *****************************************************************************/
5232 static HRESULT WINAPI
5233 IDirect3DDeviceImpl_7_DeleteStateBlock(IDirect3DDevice7 *iface,
5236 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5238 TRACE("(%p)->(%08x): Relay!\n", This, BlockHandle);
5240 EnterCriticalSection(&ddraw_cs);
5241 if(BlockHandle == 0 || BlockHandle > This->numHandles)
5243 WARN("Out of range handle %d, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5244 LeaveCriticalSection(&ddraw_cs);
5245 return D3DERR_INVALIDSTATEBLOCK;
5247 if(This->Handles[BlockHandle - 1].type != DDrawHandle_StateBlock)
5249 WARN("Handle %d is not a stateblock, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5250 LeaveCriticalSection(&ddraw_cs);
5251 return D3DERR_INVALIDSTATEBLOCK;
5254 ref = IWineD3DStateBlock_Release((IWineD3DStateBlock *) This->Handles[BlockHandle - 1].ptr);
5257 ERR("Something is still holding the stateblock %p(Handle %d). Ref = %d\n", This->Handles[BlockHandle - 1].ptr, BlockHandle, ref);
5259 This->Handles[BlockHandle - 1].ptr = NULL;
5260 This->Handles[BlockHandle - 1].type = DDrawHandle_Unknown;
5262 LeaveCriticalSection(&ddraw_cs);
5266 /*****************************************************************************
5267 * IDirect3DDevice7::CreateStateBlock
5269 * Creates a new state block handle.
5274 * Type: The state block type
5275 * BlockHandle: Address to write the created handle to
5279 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5281 *****************************************************************************/
5282 static HRESULT WINAPI
5283 IDirect3DDeviceImpl_7_CreateStateBlock(IDirect3DDevice7 *iface,
5284 D3DSTATEBLOCKTYPE Type,
5287 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5289 TRACE("(%p)->(%08x,%p)!\n", This, Type, BlockHandle);
5293 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
5294 return DDERR_INVALIDPARAMS;
5296 if(Type != D3DSBT_ALL && Type != D3DSBT_PIXELSTATE &&
5297 Type != D3DSBT_VERTEXSTATE ) {
5298 WARN("Unexpected stateblock type, returning DDERR_INVALIDPARAMS\n");
5299 return DDERR_INVALIDPARAMS;
5302 EnterCriticalSection(&ddraw_cs);
5303 *BlockHandle = IDirect3DDeviceImpl_CreateHandle(This);
5306 ERR("Cannot get a handle number for the stateblock\n");
5307 LeaveCriticalSection(&ddraw_cs);
5308 return DDERR_OUTOFMEMORY;
5310 This->Handles[*BlockHandle - 1].type = DDrawHandle_StateBlock;
5312 /* The D3DSTATEBLOCKTYPE enum is fine here */
5313 hr = IWineD3DDevice_CreateStateBlock(This->wineD3DDevice,
5315 (IWineD3DStateBlock **) &This->Handles[*BlockHandle - 1].ptr,
5316 NULL /* Parent, hope that works */);
5317 LeaveCriticalSection(&ddraw_cs);
5318 return hr_ddraw_from_wined3d(hr);
5321 /* Helper function for IDirect3DDeviceImpl_7_Load. */
5322 static BOOL is_mip_level_subset(IDirectDrawSurfaceImpl *dest,
5323 IDirectDrawSurfaceImpl *src)
5325 IDirectDrawSurfaceImpl *src_level, *dest_level;
5326 IDirectDrawSurface7 *temp;
5327 DDSURFACEDESC2 ddsd;
5328 BOOL levelFound; /* at least one suitable sublevel in dest found */
5330 /* To satisfy "destination is mip level subset of source" criteria (regular texture counts as 1 level),
5331 * 1) there must be at least one mip level in destination that matched dimensions of some mip level in source and
5332 * 2) there must be no destination levels that don't match any levels in source. Otherwise it's INVALIDPARAMS.
5339 for (;src_level && dest_level;)
5341 if (src_level->surface_desc.dwWidth == dest_level->surface_desc.dwWidth &&
5342 src_level->surface_desc.dwHeight == dest_level->surface_desc.dwHeight)
5346 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
5347 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
5348 IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(dest_level, IDirectDrawSurface7), &ddsd.ddsCaps, &temp);
5350 if (dest_level != dest) IDirectDrawSurface7_Release(ICOM_INTERFACE(dest_level, IDirectDrawSurface7));
5352 dest_level = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, temp);
5355 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
5356 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
5357 IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(src_level, IDirectDrawSurface7), &ddsd.ddsCaps, &temp);
5359 if (src_level != src) IDirectDrawSurface7_Release(ICOM_INTERFACE(src_level, IDirectDrawSurface7));
5361 src_level = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, temp);
5364 if (src_level && src_level != src) IDirectDrawSurface7_Release(ICOM_INTERFACE(src_level, IDirectDrawSurface7));
5365 if (dest_level && dest_level != dest) IDirectDrawSurface7_Release(ICOM_INTERFACE(dest_level, IDirectDrawSurface7));
5367 return !dest_level && levelFound;
5370 /* Helper function for IDirect3DDeviceImpl_7_Load. */
5371 static void copy_mipmap_chain(IDirect3DDeviceImpl *device,
5372 IDirectDrawSurfaceImpl *dest,
5373 IDirectDrawSurfaceImpl *src,
5377 IDirectDrawSurfaceImpl *src_level, *dest_level;
5378 IDirectDrawSurface7 *temp;
5379 DDSURFACEDESC2 ddsd;
5383 IDirectDrawPalette *pal = NULL, *pal_src = NULL;
5393 for (;src_level && dest_level;)
5395 if (src_level->surface_desc.dwWidth == dest_level->surface_desc.dwWidth &&
5396 src_level->surface_desc.dwHeight == dest_level->surface_desc.dwHeight)
5398 /* Try UpdateSurface that may perform a more direct opengl loading. */
5399 hr = IWineD3DDevice_UpdateSurface(device->wineD3DDevice, src_level->WineD3DSurface, &rect, dest_level->WineD3DSurface,
5403 /* UpdateSurface may fail e.g. if dest is in system memory. Fall back to BltFast that is less strict. */
5404 IWineD3DSurface_BltFast(dest_level->WineD3DSurface,
5406 src_level->WineD3DSurface, &rect, 0);
5409 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
5410 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
5411 IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(dest_level, IDirectDrawSurface7), &ddsd.ddsCaps, &temp);
5413 if (dest_level != dest) IDirectDrawSurface7_Release(ICOM_INTERFACE(dest_level, IDirectDrawSurface7));
5415 dest_level = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, temp);
5418 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
5419 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
5420 IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(src_level, IDirectDrawSurface7), &ddsd.ddsCaps, &temp);
5422 if (src_level != src) IDirectDrawSurface7_Release(ICOM_INTERFACE(src_level, IDirectDrawSurface7));
5424 src_level = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, temp);
5431 rect.right = (rect.right + 1) / 2;
5432 rect.bottom = (rect.bottom + 1) / 2;
5435 if (src_level && src_level != src) IDirectDrawSurface7_Release(ICOM_INTERFACE(src_level, IDirectDrawSurface7));
5436 if (dest_level && dest_level != dest) IDirectDrawSurface7_Release(ICOM_INTERFACE(dest_level, IDirectDrawSurface7));
5438 /* Copy palette, if possible. */
5439 IDirectDrawSurface7_GetPalette(ICOM_INTERFACE(src, IDirectDrawSurface7), &pal_src);
5440 IDirectDrawSurface7_GetPalette(ICOM_INTERFACE(dest, IDirectDrawSurface7), &pal);
5442 if (pal_src != NULL && pal != NULL)
5444 PALETTEENTRY palent[256];
5446 IDirectDrawPalette_GetEntries(pal_src, 0, 0, 256, palent);
5447 IDirectDrawPalette_SetEntries(pal, 0, 0, 256, palent);
5450 if (pal) IDirectDrawPalette_Release(pal);
5451 if (pal_src) IDirectDrawPalette_Release(pal_src);
5453 /* Copy colorkeys, if present. */
5454 for (ckeyflag = DDCKEY_DESTBLT; ckeyflag <= DDCKEY_SRCOVERLAY; ckeyflag <<= 1)
5456 hr = IDirectDrawSurface7_GetColorKey(ICOM_INTERFACE(src, IDirectDrawSurface7), ckeyflag, &ddckey);
5460 IDirectDrawSurface7_SetColorKey(ICOM_INTERFACE(dest, IDirectDrawSurface7), ckeyflag, &ddckey);
5465 /*****************************************************************************
5466 * IDirect3DDevice7::Load
5468 * Loads a rectangular area from the source into the destination texture.
5469 * It can also copy the source to the faces of a cubic environment map
5474 * DestTex: Destination texture
5475 * DestPoint: Point in the destination where the source image should be
5477 * SrcTex: Source texture
5478 * SrcRect: Source rectangle
5479 * Flags: Cubemap faces to load (DDSCAPS2_CUBEMAP_ALLFACES, DDSCAPS2_CUBEMAP_POSITIVEX,
5480 * DDSCAPS2_CUBEMAP_NEGATIVEX, DDSCAPS2_CUBEMAP_POSITIVEY, DDSCAPS2_CUBEMAP_NEGATIVEY,
5481 * DDSCAPS2_CUBEMAP_POSITIVEZ, DDSCAPS2_CUBEMAP_NEGATIVEZ)
5485 * DDERR_INVALIDPARAMS if DestTex or SrcTex are NULL, broken coordinates or anything unexpected.
5488 *****************************************************************************/
5490 static HRESULT WINAPI
5491 IDirect3DDeviceImpl_7_Load(IDirect3DDevice7 *iface,
5492 IDirectDrawSurface7 *DestTex,
5494 IDirectDrawSurface7 *SrcTex,
5498 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5499 IDirectDrawSurfaceImpl *dest = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, DestTex);
5500 IDirectDrawSurfaceImpl *src = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, SrcTex);
5503 TRACE("(%p)->(%p,%p,%p,%p,%08x)\n", This, dest, DestPoint, src, SrcRect, Flags);
5505 if( (!src) || (!dest) )
5506 return DDERR_INVALIDPARAMS;
5508 EnterCriticalSection(&ddraw_cs);
5510 if (SrcRect) srcrect = *SrcRect;
5513 srcrect.left = srcrect.top = 0;
5514 srcrect.right = src->surface_desc.dwWidth;
5515 srcrect.bottom = src->surface_desc.dwHeight;
5518 if (DestPoint) destpoint = *DestPoint;
5521 destpoint.x = destpoint.y = 0;
5523 /* Check bad dimensions. DestPoint is validated against src, not dest, because
5524 * destination can be a subset of mip levels, in which case actual coordinates used
5525 * for it may be divided. If any dimension of dest is larger than source, it can't be
5526 * mip level subset, so an error can be returned early.
5528 if (srcrect.left >= srcrect.right || srcrect.top >= srcrect.bottom ||
5529 srcrect.right > src->surface_desc.dwWidth ||
5530 srcrect.bottom > src->surface_desc.dwHeight ||
5531 destpoint.x + srcrect.right - srcrect.left > src->surface_desc.dwWidth ||
5532 destpoint.y + srcrect.bottom - srcrect.top > src->surface_desc.dwHeight ||
5533 dest->surface_desc.dwWidth > src->surface_desc.dwWidth ||
5534 dest->surface_desc.dwHeight > src->surface_desc.dwHeight)
5536 LeaveCriticalSection(&ddraw_cs);
5537 return DDERR_INVALIDPARAMS;
5540 /* Must be top level surfaces. */
5541 if (src->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_MIPMAPSUBLEVEL ||
5542 dest->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_MIPMAPSUBLEVEL)
5544 LeaveCriticalSection(&ddraw_cs);
5545 return DDERR_INVALIDPARAMS;
5548 if (src->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP)
5550 DWORD src_face_flag, dest_face_flag;
5551 IDirectDrawSurfaceImpl *src_face, *dest_face;
5552 IDirectDrawSurface7 *temp;
5553 DDSURFACEDESC2 ddsd;
5556 if (!(dest->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP))
5558 LeaveCriticalSection(&ddraw_cs);
5559 return DDERR_INVALIDPARAMS;
5562 /* Iterate through cube faces 2 times. First time is just to check INVALIDPARAMS conditions, second
5563 * time it's actual surface loading. */
5564 for (i = 0; i < 2; i++)
5569 for (;dest_face && src_face;)
5571 src_face_flag = src_face->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP_ALLFACES;
5572 dest_face_flag = dest_face->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP_ALLFACES;
5574 if (src_face_flag == dest_face_flag)
5578 /* Destination mip levels must be subset of source mip levels. */
5579 if (!is_mip_level_subset(dest_face, src_face))
5581 LeaveCriticalSection(&ddraw_cs);
5582 return DDERR_INVALIDPARAMS;
5585 else if (Flags & dest_face_flag)
5587 copy_mipmap_chain(This, dest_face, src_face, &destpoint, &srcrect);
5590 if (src_face_flag < DDSCAPS2_CUBEMAP_NEGATIVEZ)
5592 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
5593 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | (src_face_flag << 1);
5594 IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(src, IDirectDrawSurface7), &ddsd.ddsCaps, &temp);
5596 if (src_face != src) IDirectDrawSurface7_Release(ICOM_INTERFACE(src_face, IDirectDrawSurface7));
5598 src_face = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, temp);
5602 if (src_face != src) IDirectDrawSurface7_Release(ICOM_INTERFACE(src_face, IDirectDrawSurface7));
5608 if (dest_face_flag < DDSCAPS2_CUBEMAP_NEGATIVEZ)
5610 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
5611 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | (dest_face_flag << 1);
5612 IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(dest, IDirectDrawSurface7), &ddsd.ddsCaps, &temp);
5614 if (dest_face != dest) IDirectDrawSurface7_Release(ICOM_INTERFACE(dest_face, IDirectDrawSurface7));
5616 dest_face = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, temp);
5620 if (dest_face != dest) IDirectDrawSurface7_Release(ICOM_INTERFACE(dest_face, IDirectDrawSurface7));
5628 /* Native returns error if src faces are not subset of dest faces. */
5631 LeaveCriticalSection(&ddraw_cs);
5632 return DDERR_INVALIDPARAMS;
5637 LeaveCriticalSection(&ddraw_cs);
5640 else if (dest->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP)
5642 LeaveCriticalSection(&ddraw_cs);
5643 return DDERR_INVALIDPARAMS;
5646 /* Handle non cube map textures. */
5648 /* Destination mip levels must be subset of source mip levels. */
5649 if (!is_mip_level_subset(dest, src))
5651 LeaveCriticalSection(&ddraw_cs);
5652 return DDERR_INVALIDPARAMS;
5655 copy_mipmap_chain(This, dest, src, &destpoint, &srcrect);
5657 LeaveCriticalSection(&ddraw_cs);
5661 /*****************************************************************************
5662 * IDirect3DDevice7::LightEnable
5664 * Enables or disables a light
5666 * Version 7, IDirect3DLight uses this method too.
5669 * LightIndex: The index of the light to enable / disable
5670 * Enable: Enable or disable the light
5674 * For more details, see IWineD3DDevice::SetLightEnable
5676 *****************************************************************************/
5677 static HRESULT WINAPI
5678 IDirect3DDeviceImpl_7_LightEnable(IDirect3DDevice7 *iface,
5682 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5684 TRACE("(%p)->(%08x,%d): Relay!\n", This, LightIndex, Enable);
5686 EnterCriticalSection(&ddraw_cs);
5687 hr = IWineD3DDevice_SetLightEnable(This->wineD3DDevice, LightIndex, Enable);
5688 LeaveCriticalSection(&ddraw_cs);
5689 return hr_ddraw_from_wined3d(hr);
5692 /*****************************************************************************
5693 * IDirect3DDevice7::GetLightEnable
5695 * Retrieves if the light with the given index is enabled or not
5700 * LightIndex: Index of desired light
5701 * Enable: Pointer to a BOOL which contains the result
5705 * DDERR_INVALIDPARAMS if Enable is NULL
5706 * See IWineD3DDevice::GetLightEnable for more details
5708 *****************************************************************************/
5709 static HRESULT WINAPI
5710 IDirect3DDeviceImpl_7_GetLightEnable(IDirect3DDevice7 *iface,
5714 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5716 TRACE("(%p)->(%08x,%p): Relay\n", This, LightIndex, Enable);
5719 return DDERR_INVALIDPARAMS;
5721 EnterCriticalSection(&ddraw_cs);
5722 hr = IWineD3DDevice_GetLightEnable(This->wineD3DDevice, LightIndex, Enable);
5723 LeaveCriticalSection(&ddraw_cs);
5724 return hr_ddraw_from_wined3d(hr);
5727 /*****************************************************************************
5728 * IDirect3DDevice7::SetClipPlane
5730 * Sets custom clipping plane
5735 * Index: The index of the clipping plane
5736 * PlaneEquation: An equation defining the clipping plane
5740 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
5741 * See IWineD3DDevice::SetClipPlane for more details
5743 *****************************************************************************/
5744 static HRESULT WINAPI
5745 IDirect3DDeviceImpl_7_SetClipPlane(IDirect3DDevice7 *iface,
5747 D3DVALUE* PlaneEquation)
5749 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5751 TRACE("(%p)->(%08x,%p): Relay!\n", This, Index, PlaneEquation);
5754 return DDERR_INVALIDPARAMS;
5756 EnterCriticalSection(&ddraw_cs);
5757 hr = IWineD3DDevice_SetClipPlane(This->wineD3DDevice, Index, PlaneEquation);
5758 LeaveCriticalSection(&ddraw_cs);
5762 /*****************************************************************************
5763 * IDirect3DDevice7::GetClipPlane
5765 * Returns the clipping plane with a specific index
5768 * Index: The index of the desired plane
5769 * PlaneEquation: Address to store the plane equation to
5773 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
5774 * See IWineD3DDevice::GetClipPlane for more details
5776 *****************************************************************************/
5777 static HRESULT WINAPI
5778 IDirect3DDeviceImpl_7_GetClipPlane(IDirect3DDevice7 *iface,
5780 D3DVALUE* PlaneEquation)
5782 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5784 TRACE("(%p)->(%d,%p): Relay!\n", This, Index, PlaneEquation);
5787 return DDERR_INVALIDPARAMS;
5789 EnterCriticalSection(&ddraw_cs);
5790 hr = IWineD3DDevice_GetClipPlane(This->wineD3DDevice, Index, PlaneEquation);
5791 LeaveCriticalSection(&ddraw_cs);
5795 /*****************************************************************************
5796 * IDirect3DDevice7::GetInfo
5798 * Retrieves some information about the device. The DirectX sdk says that
5799 * this version returns S_FALSE for all retail builds of DirectX, that's what
5800 * this implementation does.
5803 * DevInfoID: Information type requested
5804 * DevInfoStruct: Pointer to a structure to store the info to
5805 * Size: Size of the structure
5808 * S_FALSE, because it's a non-debug driver
5810 *****************************************************************************/
5811 static HRESULT WINAPI
5812 IDirect3DDeviceImpl_7_GetInfo(IDirect3DDevice7 *iface,
5814 void *DevInfoStruct,
5817 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5818 TRACE("(%p)->(%08x,%p,%08x)\n", This, DevInfoID, DevInfoStruct, Size);
5822 TRACE(" info requested : ");
5825 case D3DDEVINFOID_TEXTUREMANAGER: TRACE("D3DDEVINFOID_TEXTUREMANAGER\n"); break;
5826 case D3DDEVINFOID_D3DTEXTUREMANAGER: TRACE("D3DDEVINFOID_D3DTEXTUREMANAGER\n"); break;
5827 case D3DDEVINFOID_TEXTURING: TRACE("D3DDEVINFOID_TEXTURING\n"); break;
5828 default: ERR(" invalid flag !!!\n"); return DDERR_INVALIDPARAMS;
5832 return S_FALSE; /* According to MSDN, this is valid for a non-debug driver */
5835 const IDirect3DDevice7Vtbl IDirect3DDevice7_Vtbl =
5837 /*** IUnknown Methods ***/
5838 IDirect3DDeviceImpl_7_QueryInterface,
5839 IDirect3DDeviceImpl_7_AddRef,
5840 IDirect3DDeviceImpl_7_Release,
5841 /*** IDirect3DDevice7 ***/
5842 IDirect3DDeviceImpl_7_GetCaps,
5843 IDirect3DDeviceImpl_7_EnumTextureFormats,
5844 IDirect3DDeviceImpl_7_BeginScene,
5845 IDirect3DDeviceImpl_7_EndScene,
5846 IDirect3DDeviceImpl_7_GetDirect3D,
5847 IDirect3DDeviceImpl_7_SetRenderTarget,
5848 IDirect3DDeviceImpl_7_GetRenderTarget,
5849 IDirect3DDeviceImpl_7_Clear,
5850 IDirect3DDeviceImpl_7_SetTransform,
5851 IDirect3DDeviceImpl_7_GetTransform,
5852 IDirect3DDeviceImpl_7_SetViewport,
5853 IDirect3DDeviceImpl_7_MultiplyTransform,
5854 IDirect3DDeviceImpl_7_GetViewport,
5855 IDirect3DDeviceImpl_7_SetMaterial,
5856 IDirect3DDeviceImpl_7_GetMaterial,
5857 IDirect3DDeviceImpl_7_SetLight,
5858 IDirect3DDeviceImpl_7_GetLight,
5859 IDirect3DDeviceImpl_7_SetRenderState,
5860 IDirect3DDeviceImpl_7_GetRenderState,
5861 IDirect3DDeviceImpl_7_BeginStateBlock,
5862 IDirect3DDeviceImpl_7_EndStateBlock,
5863 IDirect3DDeviceImpl_7_PreLoad,
5864 IDirect3DDeviceImpl_7_DrawPrimitive,
5865 IDirect3DDeviceImpl_7_DrawIndexedPrimitive,
5866 IDirect3DDeviceImpl_7_SetClipStatus,
5867 IDirect3DDeviceImpl_7_GetClipStatus,
5868 IDirect3DDeviceImpl_7_DrawPrimitiveStrided,
5869 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided,
5870 IDirect3DDeviceImpl_7_DrawPrimitiveVB,
5871 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB,
5872 IDirect3DDeviceImpl_7_ComputeSphereVisibility,
5873 IDirect3DDeviceImpl_7_GetTexture,
5874 IDirect3DDeviceImpl_7_SetTexture,
5875 IDirect3DDeviceImpl_7_GetTextureStageState,
5876 IDirect3DDeviceImpl_7_SetTextureStageState,
5877 IDirect3DDeviceImpl_7_ValidateDevice,
5878 IDirect3DDeviceImpl_7_ApplyStateBlock,
5879 IDirect3DDeviceImpl_7_CaptureStateBlock,
5880 IDirect3DDeviceImpl_7_DeleteStateBlock,
5881 IDirect3DDeviceImpl_7_CreateStateBlock,
5882 IDirect3DDeviceImpl_7_Load,
5883 IDirect3DDeviceImpl_7_LightEnable,
5884 IDirect3DDeviceImpl_7_GetLightEnable,
5885 IDirect3DDeviceImpl_7_SetClipPlane,
5886 IDirect3DDeviceImpl_7_GetClipPlane,
5887 IDirect3DDeviceImpl_7_GetInfo
5890 const IDirect3DDevice3Vtbl IDirect3DDevice3_Vtbl =
5892 /*** IUnknown Methods ***/
5893 Thunk_IDirect3DDeviceImpl_3_QueryInterface,
5894 Thunk_IDirect3DDeviceImpl_3_AddRef,
5895 Thunk_IDirect3DDeviceImpl_3_Release,
5896 /*** IDirect3DDevice3 ***/
5897 IDirect3DDeviceImpl_3_GetCaps,
5898 IDirect3DDeviceImpl_3_GetStats,
5899 IDirect3DDeviceImpl_3_AddViewport,
5900 IDirect3DDeviceImpl_3_DeleteViewport,
5901 IDirect3DDeviceImpl_3_NextViewport,
5902 Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats,
5903 Thunk_IDirect3DDeviceImpl_3_BeginScene,
5904 Thunk_IDirect3DDeviceImpl_3_EndScene,
5905 Thunk_IDirect3DDeviceImpl_3_GetDirect3D,
5906 IDirect3DDeviceImpl_3_SetCurrentViewport,
5907 IDirect3DDeviceImpl_3_GetCurrentViewport,
5908 Thunk_IDirect3DDeviceImpl_3_SetRenderTarget,
5909 Thunk_IDirect3DDeviceImpl_3_GetRenderTarget,
5910 IDirect3DDeviceImpl_3_Begin,
5911 IDirect3DDeviceImpl_3_BeginIndexed,
5912 IDirect3DDeviceImpl_3_Vertex,
5913 IDirect3DDeviceImpl_3_Index,
5914 IDirect3DDeviceImpl_3_End,
5915 IDirect3DDeviceImpl_3_GetRenderState,
5916 IDirect3DDeviceImpl_3_SetRenderState,
5917 IDirect3DDeviceImpl_3_GetLightState,
5918 IDirect3DDeviceImpl_3_SetLightState,
5919 Thunk_IDirect3DDeviceImpl_3_SetTransform,
5920 Thunk_IDirect3DDeviceImpl_3_GetTransform,
5921 Thunk_IDirect3DDeviceImpl_3_MultiplyTransform,
5922 Thunk_IDirect3DDeviceImpl_3_DrawPrimitive,
5923 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive,
5924 Thunk_IDirect3DDeviceImpl_3_SetClipStatus,
5925 Thunk_IDirect3DDeviceImpl_3_GetClipStatus,
5926 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided,
5927 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided,
5928 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB,
5929 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB,
5930 Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility,
5931 Thunk_IDirect3DDeviceImpl_3_GetTexture,
5932 IDirect3DDeviceImpl_3_SetTexture,
5933 Thunk_IDirect3DDeviceImpl_3_GetTextureStageState,
5934 Thunk_IDirect3DDeviceImpl_3_SetTextureStageState,
5935 Thunk_IDirect3DDeviceImpl_3_ValidateDevice
5938 const IDirect3DDevice2Vtbl IDirect3DDevice2_Vtbl =
5940 /*** IUnknown Methods ***/
5941 Thunk_IDirect3DDeviceImpl_2_QueryInterface,
5942 Thunk_IDirect3DDeviceImpl_2_AddRef,
5943 Thunk_IDirect3DDeviceImpl_2_Release,
5944 /*** IDirect3DDevice2 ***/
5945 Thunk_IDirect3DDeviceImpl_2_GetCaps,
5946 IDirect3DDeviceImpl_2_SwapTextureHandles,
5947 Thunk_IDirect3DDeviceImpl_2_GetStats,
5948 Thunk_IDirect3DDeviceImpl_2_AddViewport,
5949 Thunk_IDirect3DDeviceImpl_2_DeleteViewport,
5950 Thunk_IDirect3DDeviceImpl_2_NextViewport,
5951 IDirect3DDeviceImpl_2_EnumTextureFormats,
5952 Thunk_IDirect3DDeviceImpl_2_BeginScene,
5953 Thunk_IDirect3DDeviceImpl_2_EndScene,
5954 Thunk_IDirect3DDeviceImpl_2_GetDirect3D,
5955 Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport,
5956 Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport,
5957 Thunk_IDirect3DDeviceImpl_2_SetRenderTarget,
5958 Thunk_IDirect3DDeviceImpl_2_GetRenderTarget,
5959 Thunk_IDirect3DDeviceImpl_2_Begin,
5960 Thunk_IDirect3DDeviceImpl_2_BeginIndexed,
5961 Thunk_IDirect3DDeviceImpl_2_Vertex,
5962 Thunk_IDirect3DDeviceImpl_2_Index,
5963 Thunk_IDirect3DDeviceImpl_2_End,
5964 Thunk_IDirect3DDeviceImpl_2_GetRenderState,
5965 Thunk_IDirect3DDeviceImpl_2_SetRenderState,
5966 Thunk_IDirect3DDeviceImpl_2_GetLightState,
5967 Thunk_IDirect3DDeviceImpl_2_SetLightState,
5968 Thunk_IDirect3DDeviceImpl_2_SetTransform,
5969 Thunk_IDirect3DDeviceImpl_2_GetTransform,
5970 Thunk_IDirect3DDeviceImpl_2_MultiplyTransform,
5971 Thunk_IDirect3DDeviceImpl_2_DrawPrimitive,
5972 Thunk_IDirect3DDeviceImpl_2_DrawIndexedPrimitive,
5973 Thunk_IDirect3DDeviceImpl_2_SetClipStatus,
5974 Thunk_IDirect3DDeviceImpl_2_GetClipStatus
5977 const IDirect3DDeviceVtbl IDirect3DDevice1_Vtbl =
5979 /*** IUnknown Methods ***/
5980 Thunk_IDirect3DDeviceImpl_1_QueryInterface,
5981 Thunk_IDirect3DDeviceImpl_1_AddRef,
5982 Thunk_IDirect3DDeviceImpl_1_Release,
5983 /*** IDirect3DDevice1 ***/
5984 IDirect3DDeviceImpl_1_Initialize,
5985 Thunk_IDirect3DDeviceImpl_1_GetCaps,
5986 Thunk_IDirect3DDeviceImpl_1_SwapTextureHandles,
5987 IDirect3DDeviceImpl_1_CreateExecuteBuffer,
5988 Thunk_IDirect3DDeviceImpl_1_GetStats,
5989 IDirect3DDeviceImpl_1_Execute,
5990 Thunk_IDirect3DDeviceImpl_1_AddViewport,
5991 Thunk_IDirect3DDeviceImpl_1_DeleteViewport,
5992 Thunk_IDirect3DDeviceImpl_1_NextViewport,
5993 IDirect3DDeviceImpl_1_Pick,
5994 IDirect3DDeviceImpl_1_GetPickRecords,
5995 Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats,
5996 IDirect3DDeviceImpl_1_CreateMatrix,
5997 IDirect3DDeviceImpl_1_SetMatrix,
5998 IDirect3DDeviceImpl_1_GetMatrix,
5999 IDirect3DDeviceImpl_1_DeleteMatrix,
6000 Thunk_IDirect3DDeviceImpl_1_BeginScene,
6001 Thunk_IDirect3DDeviceImpl_1_EndScene,
6002 Thunk_IDirect3DDeviceImpl_1_GetDirect3D
6005 /*****************************************************************************
6006 * IDirect3DDeviceImpl_CreateHandle
6008 * Not called from the VTable
6010 * Some older interface versions operate with handles, which are basically
6011 * DWORDs which identify an interface, for example
6012 * IDirect3DDevice::SetRenderState with DIRECT3DRENDERSTATE_TEXTUREHANDLE
6014 * Those handle could be just casts to the interface pointers or vice versa,
6015 * but that is not 64 bit safe and would mean blindly derefering a DWORD
6016 * passed by the app. Instead there is a dynamic array in the device which
6017 * keeps a DWORD to pointer information and a type for the handle.
6019 * Basically this array only grows, when a handle is freed its pointer is
6020 * just set to NULL. There will be much more reads from the array than
6021 * insertion operations, so a dynamic array is fine.
6024 * This: D3DDevice implementation for which this handle should be created
6027 * A free handle on success
6030 *****************************************************************************/
6032 IDirect3DDeviceImpl_CreateHandle(IDirect3DDeviceImpl *This)
6035 struct HandleEntry *oldHandles = This->Handles;
6037 TRACE("(%p)\n", This);
6039 for(i = 0; i < This->numHandles; i++)
6041 if(This->Handles[i].ptr == NULL &&
6042 This->Handles[i].type == DDrawHandle_Unknown)
6044 TRACE("Reusing freed handle %d\n", i + 1);
6049 TRACE("Growing the handle array\n");
6052 This->Handles = HeapAlloc(GetProcessHeap(), 0, sizeof(struct HandleEntry) * This->numHandles);
6055 ERR("Out of memory\n");
6056 This->Handles = oldHandles;
6062 memcpy(This->Handles, oldHandles, (This->numHandles - 1) * sizeof(struct HandleEntry));
6063 HeapFree(GetProcessHeap(), 0, oldHandles);
6066 TRACE("Returning %d\n", This->numHandles);
6067 return This->numHandles;
6070 /*****************************************************************************
6071 * IDirect3DDeviceImpl_UpdateDepthStencil
6073 * Checks the current render target for attached depth stencils and sets the
6074 * WineD3D depth stencil accordingly.
6077 * The depth stencil state to set if creating the device
6079 *****************************************************************************/
6081 IDirect3DDeviceImpl_UpdateDepthStencil(IDirect3DDeviceImpl *This)
6083 IDirectDrawSurface7 *depthStencil = NULL;
6084 IDirectDrawSurfaceImpl *dsi;
6085 static DDSCAPS2 depthcaps = { DDSCAPS_ZBUFFER, 0, 0, 0 };
6087 IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(This->target, IDirectDrawSurface7),
6092 TRACE("Setting wined3d depth stencil to NULL\n");
6093 IWineD3DDevice_SetDepthStencilSurface(This->wineD3DDevice,
6095 return WINED3DZB_FALSE;
6098 dsi = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, depthStencil);
6099 TRACE("Setting wined3d depth stencil to %p (wined3d %p)\n", dsi, dsi->WineD3DSurface);
6100 IWineD3DDevice_SetDepthStencilSurface(This->wineD3DDevice,
6101 dsi->WineD3DSurface);
6103 IDirectDrawSurface7_Release(depthStencil);
6104 return WINED3DZB_TRUE;