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 static inline void set_fpu_control_word(WORD fpucw
)
66 #if defined(__i386__) && defined(__GNUC__)
67 __asm__
volatile ("fldcw %0" : : "m" (fpucw
));
68 #elif defined(__i386__) && defined(_MSC_VER)
73 static inline WORD
d3d_fpu_setup(void)
77 #if defined(__i386__) && defined(__GNUC__)
78 __asm__
volatile ("fnstcw %0" : "=m" (oldcw
));
79 #elif defined(__i386__) && defined(_MSC_VER)
82 static BOOL warned
= FALSE
;
85 FIXME("FPUPRESERVE not implemented for this platform / compiler\n");
91 set_fpu_control_word(0x37f);
96 /*****************************************************************************
97 * IUnknown Methods. Common for Version 1, 2, 3 and 7
98 *****************************************************************************/
100 /*****************************************************************************
101 * IDirect3DDevice7::QueryInterface
103 * Used to query other interfaces from a Direct3DDevice interface.
104 * It can return interface pointers to all Direct3DDevice versions as well
105 * as IDirectDraw and IDirect3D. For a link to QueryInterface
106 * rules see ddraw.c, IDirectDraw7::QueryInterface
108 * Exists in Version 1, 2, 3 and 7
111 * refiid: Interface ID queried for
112 * obj: Used to return the interface pointer
115 * D3D_OK or E_NOINTERFACE
117 *****************************************************************************/
118 static HRESULT WINAPI
119 IDirect3DDeviceImpl_7_QueryInterface(IDirect3DDevice7
*iface
,
123 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
124 TRACE("(%p)->(%s,%p)\n", This
, debugstr_guid(refiid
), obj
);
126 /* According to COM docs, if the QueryInterface fails, obj should be set to NULL */
130 return DDERR_INVALIDPARAMS
;
132 if ( IsEqualGUID( &IID_IUnknown
, refiid
) )
137 /* Check DirectDraw Interfac\x01s */
138 else if( IsEqualGUID( &IID_IDirectDraw7
, refiid
) )
141 TRACE("(%p) Returning IDirectDraw7 interface at %p\n", This
, *obj
);
143 else if ( IsEqualGUID( &IID_IDirectDraw4
, refiid
) )
145 *obj
= &This
->ddraw
->IDirectDraw4_vtbl
;
146 TRACE("(%p) Returning IDirectDraw4 interface at %p\n", This
, *obj
);
148 else if ( IsEqualGUID( &IID_IDirectDraw2
, refiid
) )
150 *obj
= &This
->ddraw
->IDirectDraw2_vtbl
;
151 TRACE("(%p) Returning IDirectDraw2 interface at %p\n", This
, *obj
);
153 else if( IsEqualGUID( &IID_IDirectDraw
, refiid
) )
155 *obj
= &This
->ddraw
->IDirectDraw_vtbl
;
156 TRACE("(%p) Returning IDirectDraw interface at %p\n", This
, *obj
);
160 else if ( IsEqualGUID( &IID_IDirect3D
, refiid
) )
162 *obj
= &This
->ddraw
->IDirect3D_vtbl
;
163 TRACE("(%p) Returning IDirect3D interface at %p\n", This
, *obj
);
165 else if ( IsEqualGUID( &IID_IDirect3D2
, refiid
) )
167 *obj
= &This
->ddraw
->IDirect3D2_vtbl
;
168 TRACE("(%p) Returning IDirect3D2 interface at %p\n", This
, *obj
);
170 else if ( IsEqualGUID( &IID_IDirect3D3
, refiid
) )
172 *obj
= &This
->ddraw
->IDirect3D3_vtbl
;
173 TRACE("(%p) Returning IDirect3D3 interface at %p\n", This
, *obj
);
175 else if ( IsEqualGUID( &IID_IDirect3D7
, refiid
) )
177 *obj
= &This
->ddraw
->IDirect3D7_vtbl
;
178 TRACE("(%p) Returning IDirect3D7 interface at %p\n", This
, *obj
);
182 else if ( IsEqualGUID( &IID_IDirect3DDevice
, refiid
) )
184 *obj
= &This
->IDirect3DDevice_vtbl
;
185 TRACE("(%p) Returning IDirect3DDevice interface at %p\n", This
, *obj
);
187 else if ( IsEqualGUID( &IID_IDirect3DDevice2
, refiid
) ) {
188 *obj
= &This
->IDirect3DDevice2_vtbl
;
189 TRACE("(%p) Returning IDirect3DDevice2 interface at %p\n", This
, *obj
);
191 else if ( IsEqualGUID( &IID_IDirect3DDevice3
, refiid
) ) {
192 *obj
= &This
->IDirect3DDevice3_vtbl
;
193 TRACE("(%p) Returning IDirect3DDevice3 interface at %p\n", This
, *obj
);
195 else if ( IsEqualGUID( &IID_IDirect3DDevice7
, refiid
) ) {
197 TRACE("(%p) Returning IDirect3DDevice7 interface at %p\n", This
, *obj
);
200 /* Unknown interface */
203 ERR("(%p)->(%s, %p): No interface found\n", This
, debugstr_guid(refiid
), obj
);
204 return E_NOINTERFACE
;
207 /* AddRef the returned interface */
208 IUnknown_AddRef( (IUnknown
*) *obj
);
212 static HRESULT WINAPI
213 Thunk_IDirect3DDeviceImpl_3_QueryInterface(IDirect3DDevice3
*iface
,
217 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
218 TRACE_(ddraw_thunk
)("(%p)->(%s,%p) thunking to IDirect3DDevice7 interface.\n", This
, debugstr_guid(riid
), obj
);
219 return IDirect3DDevice7_QueryInterface((IDirect3DDevice7
*)This
, riid
, obj
);
222 static HRESULT WINAPI
223 Thunk_IDirect3DDeviceImpl_2_QueryInterface(IDirect3DDevice2
*iface
,
227 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
228 TRACE_(ddraw_thunk
)("(%p)->(%s,%p) thunking to IDirect3DDevice7 interface.\n", This
, debugstr_guid(riid
), obj
);
229 return IDirect3DDevice7_QueryInterface((IDirect3DDevice7
*)This
, riid
, obj
);
232 static HRESULT WINAPI
233 Thunk_IDirect3DDeviceImpl_1_QueryInterface(IDirect3DDevice
*iface
,
237 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
238 TRACE_(ddraw_thunk
)("(%p)->(%s,%p) thunking to IDirect3DDevice7 interface.\n", This
, debugstr_guid(riid
), obp
);
239 return IDirect3DDevice7_QueryInterface((IDirect3DDevice7
*)This
, riid
, obp
);
242 /*****************************************************************************
243 * IDirect3DDevice7::AddRef
245 * Increases the refcount....
246 * The most exciting Method, definitely
248 * Exists in Version 1, 2, 3 and 7
253 *****************************************************************************/
255 IDirect3DDeviceImpl_7_AddRef(IDirect3DDevice7
*iface
)
257 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
258 ULONG ref
= InterlockedIncrement(&This
->ref
);
260 TRACE("(%p) : incrementing from %u.\n", This
, ref
-1);
266 Thunk_IDirect3DDeviceImpl_3_AddRef(IDirect3DDevice3
*iface
)
268 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
269 TRACE_(ddraw_thunk
)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This
);
270 return IDirect3DDevice7_AddRef((IDirect3DDevice7
*)This
);
274 Thunk_IDirect3DDeviceImpl_2_AddRef(IDirect3DDevice2
*iface
)
276 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
277 TRACE_(ddraw_thunk
)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This
);
278 return IDirect3DDevice7_AddRef((IDirect3DDevice7
*)This
);
282 Thunk_IDirect3DDeviceImpl_1_AddRef(IDirect3DDevice
*iface
)
284 TRACE_(ddraw_thunk
)("(%p)->() thunking to IDirect3DDevice7 interface.\n", iface
);
285 return IDirect3DDevice7_AddRef((IDirect3DDevice7
*)device_from_device1(iface
));
288 /*****************************************************************************
289 * IDirect3DDevice7::Release
291 * Decreases the refcount of the interface
292 * When the refcount is reduced to 0, the object is destroyed.
294 * Exists in Version 1, 2, 3 and 7
299 *****************************************************************************/
301 IDirect3DDeviceImpl_7_Release(IDirect3DDevice7
*iface
)
303 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
304 ULONG ref
= InterlockedDecrement(&This
->ref
);
306 TRACE("(%p)->() decrementing from %u.\n", This
, ref
+1);
308 /* This method doesn't destroy the WineD3DDevice, because it's still in use for
309 * 2D rendering. IDirectDrawSurface7::Release will destroy the WineD3DDevice
310 * when the render target is released
314 IParent
*IndexBufferParent
;
317 EnterCriticalSection(&ddraw_cs
);
318 /* Free the index buffer. */
319 IWineD3DDevice_SetIndices(This
->wineD3DDevice
, NULL
);
320 IWineD3DIndexBuffer_GetParent(This
->indexbuffer
,
321 (IUnknown
**) &IndexBufferParent
);
322 IParent_Release(IndexBufferParent
); /* Once for the getParent */
323 if( IParent_Release(IndexBufferParent
) != 0) /* And now to destroy it */
325 ERR(" (%p) Something is still holding the index buffer parent %p\n", This
, IndexBufferParent
);
328 /* There is no need to unset the vertex buffer here, IWineD3DDevice_Uninit3D will do that when
329 * destroying the primary stateblock. If a vertex buffer is destroyed while it is bound
330 * IDirect3DVertexBuffer::Release will unset it.
333 /* Restore the render targets */
334 if(This
->OffScreenTarget
)
340 vp
.Width
= This
->ddraw
->d3d_target
->surface_desc
.dwWidth
;
341 vp
.Height
= This
->ddraw
->d3d_target
->surface_desc
.dwHeight
;
344 IWineD3DDevice_SetViewport(This
->wineD3DDevice
,
347 /* Set the device up to render to the front buffer since the back buffer will
350 IWineD3DDevice_SetRenderTarget(This
->wineD3DDevice
, 0,
351 This
->ddraw
->d3d_target
->WineD3DSurface
);
352 /* This->target is the offscreen target.
353 * This->ddraw->d3d_target is the target used by DDraw
355 TRACE("(%p) Release: Using %p as front buffer, %p as back buffer\n", This
, This
->ddraw
->d3d_target
, NULL
);
356 IWineD3DDevice_SetFrontBackBuffers(This
->wineD3DDevice
,
357 This
->ddraw
->d3d_target
->WineD3DSurface
,
361 /* Release the WineD3DDevice. This won't destroy it */
362 if(IWineD3DDevice_Release(This
->wineD3DDevice
) <= 0)
364 ERR(" (%p) The wineD3D device %p was destroyed unexpectedly. Prepare for trouble\n", This
, This
->wineD3DDevice
);
367 /* The texture handles should be unset by now, but there might be some bits
368 * missing in our reference counting(needs test). Do a sanity check
370 for(i
= 0; i
< This
->numHandles
; i
++)
372 if(This
->Handles
[i
].ptr
)
374 switch(This
->Handles
[i
].type
)
376 case DDrawHandle_Texture
:
378 IDirectDrawSurfaceImpl
*surf
= This
->Handles
[i
].ptr
;
379 FIXME("Texture Handle %d not unset properly\n", i
+ 1);
384 case DDrawHandle_Material
:
386 IDirect3DMaterialImpl
*mat
= This
->Handles
[i
].ptr
;
387 FIXME("Material handle %d not unset properly\n", i
+ 1);
392 case DDrawHandle_Matrix
:
394 /* No fixme here because this might happen because of sloppy apps */
395 WARN("Leftover matrix handle %d, deleting\n", i
+ 1);
396 IDirect3DDevice_DeleteMatrix((IDirect3DDevice
*)&This
->IDirect3DDevice_vtbl
, i
+ 1);
400 case DDrawHandle_StateBlock
:
402 /* No fixme here because this might happen because of sloppy apps */
403 WARN("Leftover stateblock handle %d, deleting\n", i
+ 1);
404 IDirect3DDevice7_DeleteStateBlock((IDirect3DDevice7
*)This
, i
+ 1);
409 FIXME("Unknown handle %d not unset properly\n", i
+ 1);
414 HeapFree(GetProcessHeap(), 0, This
->Handles
);
416 TRACE("Releasing target %p %p\n", This
->target
, This
->ddraw
->d3d_target
);
417 /* Release the render target and the WineD3D render target
418 * (See IDirect3D7::CreateDevice for more comments on this)
420 IDirectDrawSurface7_Release((IDirectDrawSurface7
*)This
->target
);
421 IDirectDrawSurface7_Release((IDirectDrawSurface7
*)This
->ddraw
->d3d_target
);
422 TRACE("Target release done\n");
424 This
->ddraw
->d3ddevice
= NULL
;
426 /* Now free the structure */
427 HeapFree(GetProcessHeap(), 0, This
);
428 LeaveCriticalSection(&ddraw_cs
);
436 Thunk_IDirect3DDeviceImpl_3_Release(IDirect3DDevice3
*iface
)
438 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
439 TRACE_(ddraw_thunk
)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This
);
440 return IDirect3DDevice7_Release((IDirect3DDevice7
*)This
);
444 Thunk_IDirect3DDeviceImpl_2_Release(IDirect3DDevice2
*iface
)
446 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
447 TRACE_(ddraw_thunk
)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This
);
448 return IDirect3DDevice7_Release((IDirect3DDevice7
*)This
);
452 Thunk_IDirect3DDeviceImpl_1_Release(IDirect3DDevice
*iface
)
454 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
455 TRACE_(ddraw_thunk
)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This
);
456 return IDirect3DDevice7_Release((IDirect3DDevice7
*)This
);
459 /*****************************************************************************
460 * IDirect3DDevice Methods
461 *****************************************************************************/
463 /*****************************************************************************
464 * IDirect3DDevice::Initialize
466 * Initializes a Direct3DDevice. This implementation is a no-op, as all
467 * initialization is done at create time.
469 * Exists in Version 1
472 * No idea what they mean, as the MSDN page is gone
476 *****************************************************************************/
477 static HRESULT WINAPI
478 IDirect3DDeviceImpl_1_Initialize(IDirect3DDevice
*iface
,
479 IDirect3D
*Direct3D
, GUID
*guid
,
482 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
484 /* It shouldn't be crucial, but print a FIXME, I'm interested if
485 * any game calls it and when
487 FIXME("(%p)->(%p,%p,%p): No-op!\n", This
, Direct3D
, guid
, Desc
);
492 /*****************************************************************************
493 * IDirect3DDevice7::GetCaps
495 * Retrieves the device's capabilities
497 * This implementation is used for Version 7 only, the older versions have
498 * their own implementation.
501 * Desc: Pointer to a D3DDEVICEDESC7 structure to fill
505 * D3DERR_* if a problem occurs. See WineD3D
507 *****************************************************************************/
509 IDirect3DDeviceImpl_7_GetCaps(IDirect3DDevice7
*iface
,
510 D3DDEVICEDESC7
*Desc
)
512 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
513 D3DDEVICEDESC OldDesc
;
514 TRACE("(%p)->(%p)\n", This
, Desc
);
516 /* Call the same function used by IDirect3D, this saves code */
517 return IDirect3DImpl_GetCaps(This
->ddraw
->wineD3D
, &OldDesc
, Desc
);
520 static HRESULT WINAPI
521 IDirect3DDeviceImpl_7_GetCaps_FPUSetup(IDirect3DDevice7
*iface
,
522 D3DDEVICEDESC7
*Desc
)
524 return IDirect3DDeviceImpl_7_GetCaps(iface
, Desc
);
527 static HRESULT WINAPI
528 IDirect3DDeviceImpl_7_GetCaps_FPUPreserve(IDirect3DDevice7
*iface
,
529 D3DDEVICEDESC7
*Desc
)
534 old_fpucw
= d3d_fpu_setup();
535 hr
= IDirect3DDeviceImpl_7_GetCaps(iface
, Desc
);
536 set_fpu_control_word(old_fpucw
);
540 /*****************************************************************************
541 * IDirect3DDevice3::GetCaps
543 * Retrieves the capabilities of the hardware device and the emulation
544 * device. For Wine, hardware and emulation are the same (it's all HW).
546 * This implementation is used for Version 1, 2, and 3. Version 7 has its own
549 * HWDesc: Structure to fill with the HW caps
550 * HelDesc: Structure to fill with the hardware emulation caps
554 * D3DERR_* if a problem occurs. See WineD3D
556 *****************************************************************************/
557 static HRESULT WINAPI
558 IDirect3DDeviceImpl_3_GetCaps(IDirect3DDevice3
*iface
,
559 D3DDEVICEDESC
*HWDesc
,
560 D3DDEVICEDESC
*HelDesc
)
562 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
563 D3DDEVICEDESC7 newDesc
;
565 TRACE("(%p)->(%p,%p)\n", iface
, HWDesc
, HelDesc
);
567 hr
= IDirect3DImpl_GetCaps(This
->ddraw
->wineD3D
, HWDesc
, &newDesc
);
568 if(hr
!= D3D_OK
) return hr
;
574 static HRESULT WINAPI
575 Thunk_IDirect3DDeviceImpl_2_GetCaps(IDirect3DDevice2
*iface
,
576 D3DDEVICEDESC
*D3DHWDevDesc
,
577 D3DDEVICEDESC
*D3DHELDevDesc
)
579 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
580 TRACE_(ddraw_thunk
)("(%p)->(%p,%p) thunking to IDirect3DDevice3 interface.\n", This
, D3DHWDevDesc
, D3DHELDevDesc
);
581 return IDirect3DDevice3_GetCaps((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, D3DHWDevDesc
, D3DHELDevDesc
);
584 static HRESULT WINAPI
585 Thunk_IDirect3DDeviceImpl_1_GetCaps(IDirect3DDevice
*iface
,
586 D3DDEVICEDESC
*D3DHWDevDesc
,
587 D3DDEVICEDESC
*D3DHELDevDesc
)
589 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
590 TRACE_(ddraw_thunk
)("(%p)->(%p,%p) thunking to IDirect3DDevice3 interface.\n", This
, D3DHWDevDesc
, D3DHELDevDesc
);
591 return IDirect3DDevice3_GetCaps((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, D3DHWDevDesc
, D3DHELDevDesc
);
594 /*****************************************************************************
595 * IDirect3DDevice2::SwapTextureHandles
597 * Swaps the texture handles of 2 Texture interfaces. Version 1 and 2
600 * Tex1, Tex2: The 2 Textures to swap
605 *****************************************************************************/
606 static HRESULT WINAPI
607 IDirect3DDeviceImpl_2_SwapTextureHandles(IDirect3DDevice2
*iface
,
608 IDirect3DTexture2
*Tex1
,
609 IDirect3DTexture2
*Tex2
)
611 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
613 IDirectDrawSurfaceImpl
*surf1
= surface_from_texture2(Tex1
);
614 IDirectDrawSurfaceImpl
*surf2
= surface_from_texture2(Tex2
);
615 TRACE("(%p)->(%p,%p)\n", This
, surf1
, surf2
);
617 EnterCriticalSection(&ddraw_cs
);
618 This
->Handles
[surf1
->Handle
- 1].ptr
= surf2
;
619 This
->Handles
[surf2
->Handle
- 1].ptr
= surf1
;
621 swap
= surf2
->Handle
;
622 surf2
->Handle
= surf1
->Handle
;
623 surf1
->Handle
= swap
;
624 LeaveCriticalSection(&ddraw_cs
);
629 static HRESULT WINAPI
630 Thunk_IDirect3DDeviceImpl_1_SwapTextureHandles(IDirect3DDevice
*iface
,
631 IDirect3DTexture
*D3DTex1
,
632 IDirect3DTexture
*D3DTex2
)
634 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
635 IDirectDrawSurfaceImpl
*surf1
= surface_from_texture1(D3DTex1
);
636 IDirectDrawSurfaceImpl
*surf2
= surface_from_texture1(D3DTex2
);
637 IDirect3DTexture2
*t1
= surf1
? (IDirect3DTexture2
*)&surf1
->IDirect3DTexture2_vtbl
: NULL
;
638 IDirect3DTexture2
*t2
= surf2
? (IDirect3DTexture2
*)&surf2
->IDirect3DTexture2_vtbl
: NULL
;
639 TRACE_(ddraw_thunk
)("(%p)->(%p,%p) thunking to IDirect3DDevice2 interface.\n", This
, surf1
, surf2
);
640 return IDirect3DDevice2_SwapTextureHandles((IDirect3DDevice2
*)&This
->IDirect3DDevice2_vtbl
, t1
, t2
);
643 /*****************************************************************************
644 * IDirect3DDevice3::GetStats
646 * This method seems to retrieve some stats from the device.
647 * The MSDN documentation doesn't exist any more, but the D3DSTATS
648 * structure suggests that the amount of drawn primitives and processed
649 * vertices is returned.
651 * Exists in Version 1, 2 and 3
654 * Stats: Pointer to a D3DSTATS structure to be filled
658 * DDERR_INVALIDPARAMS if Stats == NULL
660 *****************************************************************************/
661 static HRESULT WINAPI
662 IDirect3DDeviceImpl_3_GetStats(IDirect3DDevice3
*iface
,
665 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
666 FIXME("(%p)->(%p): Stub!\n", This
, Stats
);
669 return DDERR_INVALIDPARAMS
;
671 /* Fill the Stats with 0 */
672 Stats
->dwTrianglesDrawn
= 0;
673 Stats
->dwLinesDrawn
= 0;
674 Stats
->dwPointsDrawn
= 0;
675 Stats
->dwSpansDrawn
= 0;
676 Stats
->dwVerticesProcessed
= 0;
681 static HRESULT WINAPI
682 Thunk_IDirect3DDeviceImpl_2_GetStats(IDirect3DDevice2
*iface
,
685 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
686 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This
, Stats
);
687 return IDirect3DDevice3_GetStats((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, Stats
);
690 static HRESULT WINAPI
691 Thunk_IDirect3DDeviceImpl_1_GetStats(IDirect3DDevice
*iface
,
694 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
695 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This
, Stats
);
696 return IDirect3DDevice3_GetStats((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, Stats
);
699 /*****************************************************************************
700 * IDirect3DDevice::CreateExecuteBuffer
702 * Creates an IDirect3DExecuteBuffer, used for rendering with a
708 * Desc: Buffer description
709 * ExecuteBuffer: Address to return the Interface pointer at
710 * UnkOuter: Must be NULL. Basically for aggregation, which ddraw doesn't
714 * CLASS_E_NOAGGREGATION if UnkOuter != NULL
715 * DDERR_OUTOFMEMORY if we ran out of memory
718 *****************************************************************************/
719 static HRESULT WINAPI
720 IDirect3DDeviceImpl_1_CreateExecuteBuffer(IDirect3DDevice
*iface
,
721 D3DEXECUTEBUFFERDESC
*Desc
,
722 IDirect3DExecuteBuffer
**ExecuteBuffer
,
725 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
726 IDirect3DExecuteBufferImpl
* object
;
727 TRACE("(%p)->(%p,%p,%p)!\n", This
, Desc
, ExecuteBuffer
, UnkOuter
);
730 return CLASS_E_NOAGGREGATION
;
732 /* Allocate the new Execute Buffer */
733 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirect3DExecuteBufferImpl
));
736 ERR("Out of memory when allocating a IDirect3DExecuteBufferImpl structure\n");
737 return DDERR_OUTOFMEMORY
;
740 object
->lpVtbl
= &IDirect3DExecuteBuffer_Vtbl
;
742 object
->d3ddev
= This
;
744 /* Initializes memory */
745 memcpy(&object
->desc
, Desc
, Desc
->dwSize
);
747 /* No buffer given */
748 if ((object
->desc
.dwFlags
& D3DDEB_LPDATA
) == 0)
749 object
->desc
.lpData
= NULL
;
751 /* No buffer size given */
752 if ((object
->desc
.dwFlags
& D3DDEB_BUFSIZE
) == 0)
753 object
->desc
.dwBufferSize
= 0;
755 /* Create buffer if asked */
756 if ((object
->desc
.lpData
== NULL
) && (object
->desc
.dwBufferSize
> 0))
758 object
->need_free
= TRUE
;
759 object
->desc
.lpData
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,object
->desc
.dwBufferSize
);
760 if(!object
->desc
.lpData
)
762 ERR("Out of memory when allocating the execute buffer data\n");
763 HeapFree(GetProcessHeap(), 0, object
);
764 return DDERR_OUTOFMEMORY
;
769 object
->need_free
= FALSE
;
772 /* No vertices for the moment */
773 object
->vertex_data
= NULL
;
775 object
->desc
.dwFlags
|= D3DDEB_LPDATA
;
777 object
->indices
= NULL
;
778 object
->nb_indices
= 0;
780 *ExecuteBuffer
= (IDirect3DExecuteBuffer
*)object
;
782 TRACE(" Returning IDirect3DExecuteBuffer at %p, implementation is at %p\n", *ExecuteBuffer
, object
);
787 /*****************************************************************************
788 * IDirect3DDevice::Execute
790 * Executes all the stuff in an execute buffer.
793 * ExecuteBuffer: The buffer to execute
794 * Viewport: The viewport used for rendering
798 * DDERR_INVALIDPARAMS if ExecuteBuffer == NULL
801 *****************************************************************************/
802 static HRESULT WINAPI
803 IDirect3DDeviceImpl_1_Execute(IDirect3DDevice
*iface
,
804 IDirect3DExecuteBuffer
*ExecuteBuffer
,
805 IDirect3DViewport
*Viewport
,
808 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
809 IDirect3DExecuteBufferImpl
*Direct3DExecuteBufferImpl
= (IDirect3DExecuteBufferImpl
*)ExecuteBuffer
;
810 IDirect3DViewportImpl
*Direct3DViewportImpl
= (IDirect3DViewportImpl
*)Viewport
;
812 TRACE("(%p)->(%p,%p,%08x)\n", This
, Direct3DExecuteBufferImpl
, Direct3DViewportImpl
, Flags
);
814 if(!Direct3DExecuteBufferImpl
)
815 return DDERR_INVALIDPARAMS
;
818 EnterCriticalSection(&ddraw_cs
);
819 IDirect3DExecuteBufferImpl_Execute(Direct3DExecuteBufferImpl
, This
, Direct3DViewportImpl
);
820 LeaveCriticalSection(&ddraw_cs
);
825 /*****************************************************************************
826 * IDirect3DDevice3::AddViewport
828 * Add a Direct3DViewport to the device's viewport list. These viewports
829 * are wrapped to IDirect3DDevice7 viewports in viewport.c
831 * Exists in Version 1, 2 and 3. Note that IDirect3DViewport 1, 2 and 3
832 * are the same interfaces.
835 * Viewport: The viewport to add
838 * DDERR_INVALIDPARAMS if Viewport == NULL
841 *****************************************************************************/
842 static HRESULT WINAPI
843 IDirect3DDeviceImpl_3_AddViewport(IDirect3DDevice3
*iface
,
844 IDirect3DViewport3
*Viewport
)
846 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
847 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*)Viewport
;
849 TRACE("(%p)->(%p)\n", This
, vp
);
853 return DDERR_INVALIDPARAMS
;
855 EnterCriticalSection(&ddraw_cs
);
856 vp
->next
= This
->viewport_list
;
857 This
->viewport_list
= vp
;
858 vp
->active_device
= This
; /* Viewport must be usable for Clear() after AddViewport,
859 so set active_device here. */
860 LeaveCriticalSection(&ddraw_cs
);
865 static HRESULT WINAPI
866 Thunk_IDirect3DDeviceImpl_2_AddViewport(IDirect3DDevice2
*iface
,
867 IDirect3DViewport2
*Direct3DViewport2
)
869 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
870 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*)Direct3DViewport2
;
871 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This
, vp
);
872 return IDirect3DDevice3_AddViewport((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, (IDirect3DViewport3
*)vp
);
875 static HRESULT WINAPI
876 Thunk_IDirect3DDeviceImpl_1_AddViewport(IDirect3DDevice
*iface
,
877 IDirect3DViewport
*Direct3DViewport
)
879 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
880 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*)Direct3DViewport
;
881 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This
, vp
);
882 return IDirect3DDevice3_AddViewport((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, (IDirect3DViewport3
*)vp
);
885 /*****************************************************************************
886 * IDirect3DDevice3::DeleteViewport
888 * Deletes a Direct3DViewport from the device's viewport list.
890 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
894 * Viewport: The viewport to delete
898 * DDERR_INVALIDPARAMS if the viewport wasn't found in the list
900 *****************************************************************************/
901 static HRESULT WINAPI
902 IDirect3DDeviceImpl_3_DeleteViewport(IDirect3DDevice3
*iface
,
903 IDirect3DViewport3
*Viewport
)
905 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
906 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*) Viewport
;
907 IDirect3DViewportImpl
*cur_viewport
, *prev_viewport
= NULL
;
909 TRACE("(%p)->(%p)\n", This
, vp
);
911 EnterCriticalSection(&ddraw_cs
);
912 cur_viewport
= This
->viewport_list
;
913 while (cur_viewport
!= NULL
)
915 if (cur_viewport
== vp
)
917 if (prev_viewport
== NULL
) This
->viewport_list
= cur_viewport
->next
;
918 else prev_viewport
->next
= cur_viewport
->next
;
919 /* TODO : add desactivate of the viewport and all associated lights... */
920 LeaveCriticalSection(&ddraw_cs
);
923 prev_viewport
= cur_viewport
;
924 cur_viewport
= cur_viewport
->next
;
927 LeaveCriticalSection(&ddraw_cs
);
928 return DDERR_INVALIDPARAMS
;
931 static HRESULT WINAPI
932 Thunk_IDirect3DDeviceImpl_2_DeleteViewport(IDirect3DDevice2
*iface
,
933 IDirect3DViewport2
*Direct3DViewport2
)
935 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
936 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*)Direct3DViewport2
;
937 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This
, vp
);
938 return IDirect3DDevice3_DeleteViewport((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, (IDirect3DViewport3
*)vp
);
941 static HRESULT WINAPI
942 Thunk_IDirect3DDeviceImpl_1_DeleteViewport(IDirect3DDevice
*iface
,
943 IDirect3DViewport
*Direct3DViewport
)
945 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
946 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*)Direct3DViewport
;
947 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This
, vp
);
948 return IDirect3DDevice3_DeleteViewport((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, (IDirect3DViewport3
*)vp
);
951 /*****************************************************************************
952 * IDirect3DDevice3::NextViewport
954 * Returns a viewport from the viewport list, depending on the
955 * passed viewport and the flags.
957 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
961 * Viewport: Viewport to use for beginning the search
962 * Flags: D3DNEXT_NEXT, D3DNEXT_HEAD or D3DNEXT_TAIL
966 * DDERR_INVALIDPARAMS if the flags were wrong, or Viewport was NULL
968 *****************************************************************************/
969 static HRESULT WINAPI
970 IDirect3DDeviceImpl_3_NextViewport(IDirect3DDevice3
*iface
,
971 IDirect3DViewport3
*Viewport3
,
972 IDirect3DViewport3
**lplpDirect3DViewport3
,
975 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
976 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*)Viewport3
;
977 IDirect3DViewportImpl
*res
= NULL
;
979 TRACE("(%p)->(%p,%p,%08x)\n", This
, vp
, lplpDirect3DViewport3
, Flags
);
983 *lplpDirect3DViewport3
= NULL
;
984 return DDERR_INVALIDPARAMS
;
988 EnterCriticalSection(&ddraw_cs
);
998 res
= This
->viewport_list
;
1003 IDirect3DViewportImpl
*cur_viewport
= This
->viewport_list
;
1004 if (cur_viewport
!= NULL
)
1006 while (cur_viewport
->next
!= NULL
) cur_viewport
= cur_viewport
->next
;
1012 *lplpDirect3DViewport3
= NULL
;
1013 LeaveCriticalSection(&ddraw_cs
);
1014 return DDERR_INVALIDPARAMS
;
1017 *lplpDirect3DViewport3
= (IDirect3DViewport3
*)res
;
1018 LeaveCriticalSection(&ddraw_cs
);
1022 static HRESULT WINAPI
1023 Thunk_IDirect3DDeviceImpl_2_NextViewport(IDirect3DDevice2
*iface
,
1024 IDirect3DViewport2
*Viewport2
,
1025 IDirect3DViewport2
**lplpDirect3DViewport2
,
1028 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
1029 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*)Viewport2
;
1030 IDirect3DViewport3
*res
;
1032 TRACE_(ddraw_thunk
)("(%p)->(%p,%p,%08x) thunking to IDirect3DDevice3 interface.\n", This
, vp
, lplpDirect3DViewport2
, Flags
);
1033 hr
= IDirect3DDevice3_NextViewport((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
,
1034 (IDirect3DViewport3
*)vp
, &res
, Flags
);
1035 *lplpDirect3DViewport2
= (IDirect3DViewport2
*)res
;
1039 static HRESULT WINAPI
1040 Thunk_IDirect3DDeviceImpl_1_NextViewport(IDirect3DDevice
*iface
,
1041 IDirect3DViewport
*Viewport
,
1042 IDirect3DViewport
**lplpDirect3DViewport
,
1045 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
1046 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*)Viewport
;
1047 IDirect3DViewport3
*res
;
1049 TRACE_(ddraw_thunk
)("(%p)->(%p,%p,%08x) thunking to IDirect3DDevice3 interface.\n", This
, vp
, lplpDirect3DViewport
, Flags
);
1050 hr
= IDirect3DDevice3_NextViewport((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
,
1051 (IDirect3DViewport3
*)vp
, &res
, Flags
);
1052 *lplpDirect3DViewport
= (IDirect3DViewport
*)res
;
1056 /*****************************************************************************
1057 * IDirect3DDevice::Pick
1059 * Executes an execute buffer without performing rendering. Instead, a
1060 * list of primitives that intersect with (x1,y1) of the passed rectangle
1061 * is created. IDirect3DDevice::GetPickRecords can be used to retrieve
1067 * ExecuteBuffer: Buffer to execute
1068 * Viewport: Viewport to use for execution
1069 * Flags: None are defined, according to the SDK
1070 * Rect: Specifies the coordinates to be picked. Only x1 and y2 are used,
1071 * x2 and y2 are ignored.
1074 * D3D_OK because it's a stub
1076 *****************************************************************************/
1077 static HRESULT WINAPI
1078 IDirect3DDeviceImpl_1_Pick(IDirect3DDevice
*iface
,
1079 IDirect3DExecuteBuffer
*ExecuteBuffer
,
1080 IDirect3DViewport
*Viewport
,
1084 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
1085 IDirect3DExecuteBufferImpl
*execbuf
= (IDirect3DExecuteBufferImpl
*)ExecuteBuffer
;
1086 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*)Viewport
;
1087 FIXME("(%p)->(%p,%p,%08x,%p): stub!\n", This
, execbuf
, vp
, Flags
, Rect
);
1092 /*****************************************************************************
1093 * IDirect3DDevice::GetPickRecords
1095 * Retrieves the pick records generated by IDirect3DDevice::GetPickRecords
1100 * Count: Pointer to a DWORD containing the numbers of pick records to
1102 * D3DPickRec: Address to store the resulting D3DPICKRECORD array.
1105 * D3D_OK, because it's a stub
1107 *****************************************************************************/
1108 static HRESULT WINAPI
1109 IDirect3DDeviceImpl_1_GetPickRecords(IDirect3DDevice
*iface
,
1111 D3DPICKRECORD
*D3DPickRec
)
1113 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
1114 FIXME("(%p)->(%p,%p): stub!\n", This
, Count
, D3DPickRec
);
1119 /*****************************************************************************
1120 * IDirect3DDevice7::EnumTextureformats
1122 * Enumerates the supported texture formats. It has a list of all possible
1123 * formats and calls IWineD3D::CheckDeviceFormat for each format to see if
1124 * WineD3D supports it. If so, then it is passed to the app.
1126 * This is for Version 7 and 3, older versions have a different
1127 * callback function and their own implementation
1130 * Callback: Callback to call for each enumerated format
1131 * Arg: Argument to pass to the callback
1135 * DDERR_INVALIDPARAMS if Callback == NULL
1137 *****************************************************************************/
1139 IDirect3DDeviceImpl_7_EnumTextureFormats(IDirect3DDevice7
*iface
,
1140 LPD3DENUMPIXELFORMATSCALLBACK Callback
,
1143 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
1145 WINED3DDISPLAYMODE mode
;
1148 WINED3DFORMAT FormatList
[] = {
1150 WINED3DFMT_A8R8G8B8
,
1151 WINED3DFMT_X8R8G8B8
,
1155 WINED3DFMT_A1R5G5B5
,
1156 WINED3DFMT_A4R4G4B4
,
1158 WINED3DFMT_X1R5G5B5
,
1168 WINED3DFORMAT BumpFormatList
[] = {
1169 WINED3DFMT_R8G8_SNORM
,
1171 WINED3DFMT_X8L8V8U8
,
1172 WINED3DFMT_R8G8B8A8_SNORM
,
1173 WINED3DFMT_R16G16_SNORM
,
1174 WINED3DFMT_W11V11U10
,
1175 WINED3DFMT_A2W10V10U10
1178 TRACE("(%p)->(%p,%p): Relay\n", This
, Callback
, Arg
);
1181 return DDERR_INVALIDPARAMS
;
1183 EnterCriticalSection(&ddraw_cs
);
1185 memset(&mode
, 0, sizeof(mode
));
1186 hr
= IWineD3DDevice_GetDisplayMode(This
->ddraw
->wineD3DDevice
,
1190 LeaveCriticalSection(&ddraw_cs
);
1191 WARN("Cannot get the current adapter format\n");
1195 for(i
= 0; i
< sizeof(FormatList
) / sizeof(WINED3DFORMAT
); i
++)
1197 hr
= IWineD3D_CheckDeviceFormat(This
->ddraw
->wineD3D
,
1198 WINED3DADAPTER_DEFAULT
,
1202 WINED3DRTYPE_TEXTURE
,
1207 DDPIXELFORMAT pformat
;
1209 memset(&pformat
, 0, sizeof(pformat
));
1210 pformat
.dwSize
= sizeof(pformat
);
1211 PixelFormat_WineD3DtoDD(&pformat
, FormatList
[i
]);
1213 TRACE("Enumerating WineD3DFormat %d\n", FormatList
[i
]);
1214 hr
= Callback(&pformat
, Arg
);
1215 if(hr
!= DDENUMRET_OK
)
1217 TRACE("Format enumeration cancelled by application\n");
1218 LeaveCriticalSection(&ddraw_cs
);
1224 for(i
= 0; i
< sizeof(BumpFormatList
) / sizeof(WINED3DFORMAT
); i
++)
1226 hr
= IWineD3D_CheckDeviceFormat(This
->ddraw
->wineD3D
,
1227 WINED3DADAPTER_DEFAULT
,
1230 WINED3DUSAGE_QUERY_LEGACYBUMPMAP
,
1231 WINED3DRTYPE_TEXTURE
,
1236 DDPIXELFORMAT pformat
;
1238 memset(&pformat
, 0, sizeof(pformat
));
1239 pformat
.dwSize
= sizeof(pformat
);
1240 PixelFormat_WineD3DtoDD(&pformat
, BumpFormatList
[i
]);
1242 TRACE("Enumerating WineD3DFormat %d\n", BumpFormatList
[i
]);
1243 hr
= Callback(&pformat
, Arg
);
1244 if(hr
!= DDENUMRET_OK
)
1246 TRACE("Format enumeration cancelled by application\n");
1247 LeaveCriticalSection(&ddraw_cs
);
1252 TRACE("End of enumeration\n");
1253 LeaveCriticalSection(&ddraw_cs
);
1257 static HRESULT WINAPI
1258 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUSetup(IDirect3DDevice7
*iface
,
1259 LPD3DENUMPIXELFORMATSCALLBACK Callback
,
1262 return IDirect3DDeviceImpl_7_EnumTextureFormats(iface
, Callback
, Arg
);
1265 static HRESULT WINAPI
1266 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUPreserve(IDirect3DDevice7
*iface
,
1267 LPD3DENUMPIXELFORMATSCALLBACK Callback
,
1273 old_fpucw
= d3d_fpu_setup();
1274 hr
= IDirect3DDeviceImpl_7_EnumTextureFormats(iface
, Callback
, Arg
);
1275 set_fpu_control_word(old_fpucw
);
1280 static HRESULT WINAPI
1281 Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats(IDirect3DDevice3
*iface
,
1282 LPD3DENUMPIXELFORMATSCALLBACK Callback
,
1285 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
1286 TRACE_(ddraw_thunk
)("(%p)->(%p,%p) thunking to IDirect3DDevice7 interface.\n", This
, Callback
, Arg
);
1287 return IDirect3DDevice7_EnumTextureFormats((IDirect3DDevice7
*)This
, Callback
, Arg
);
1290 /*****************************************************************************
1291 * IDirect3DDevice2::EnumTextureformats
1293 * EnumTextureFormats for Version 1 and 2, see
1294 * IDirect3DDevice7::EnumTexureFormats for a more detailed description.
1296 * This version has a different callback and does not enumerate FourCC
1299 *****************************************************************************/
1300 static HRESULT WINAPI
1301 IDirect3DDeviceImpl_2_EnumTextureFormats(IDirect3DDevice2
*iface
,
1302 LPD3DENUMTEXTUREFORMATSCALLBACK Callback
,
1305 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
1308 WINED3DDISPLAYMODE mode
;
1310 WINED3DFORMAT FormatList
[] = {
1312 WINED3DFMT_A8R8G8B8
,
1313 WINED3DFMT_X8R8G8B8
,
1317 WINED3DFMT_A1R5G5B5
,
1318 WINED3DFMT_A4R4G4B4
,
1320 WINED3DFMT_X1R5G5B5
,
1324 /* FOURCC codes - Not in this version*/
1327 TRACE("(%p)->(%p,%p): Relay\n", This
, Callback
, Arg
);
1330 return DDERR_INVALIDPARAMS
;
1332 EnterCriticalSection(&ddraw_cs
);
1334 memset(&mode
, 0, sizeof(mode
));
1335 hr
= IWineD3DDevice_GetDisplayMode(This
->ddraw
->wineD3DDevice
,
1339 LeaveCriticalSection(&ddraw_cs
);
1340 WARN("Cannot get the current adapter format\n");
1344 for(i
= 0; i
< sizeof(FormatList
) / sizeof(WINED3DFORMAT
); i
++)
1346 hr
= IWineD3D_CheckDeviceFormat(This
->ddraw
->wineD3D
,
1351 WINED3DRTYPE_TEXTURE
,
1356 DDSURFACEDESC sdesc
;
1358 memset(&sdesc
, 0, sizeof(sdesc
));
1359 sdesc
.dwSize
= sizeof(sdesc
);
1360 sdesc
.dwFlags
= DDSD_PIXELFORMAT
| DDSD_CAPS
;
1361 sdesc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1362 sdesc
.ddpfPixelFormat
.dwSize
= sizeof(sdesc
.ddpfPixelFormat
);
1363 PixelFormat_WineD3DtoDD(&sdesc
.ddpfPixelFormat
, FormatList
[i
]);
1365 TRACE("Enumerating WineD3DFormat %d\n", FormatList
[i
]);
1366 hr
= Callback(&sdesc
, Arg
);
1367 if(hr
!= DDENUMRET_OK
)
1369 TRACE("Format enumeration cancelled by application\n");
1370 LeaveCriticalSection(&ddraw_cs
);
1375 TRACE("End of enumeration\n");
1376 LeaveCriticalSection(&ddraw_cs
);
1380 static HRESULT WINAPI
1381 Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats(IDirect3DDevice
*iface
,
1382 LPD3DENUMTEXTUREFORMATSCALLBACK Callback
,
1385 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
1386 TRACE_(ddraw_thunk
)("(%p)->(%p,%p) thunking to IDirect3DDevice2 interface.\n", This
, Callback
, Arg
);
1387 return IDirect3DDevice2_EnumTextureFormats((IDirect3DDevice2
*)&This
->IDirect3DDevice2_vtbl
, Callback
, Arg
);
1390 /*****************************************************************************
1391 * IDirect3DDevice::CreateMatrix
1393 * Creates a matrix handle. A handle is created and memory for a D3DMATRIX is
1394 * allocated for the handle.
1399 * D3DMatHandle: Address to return the handle at
1403 * DDERR_INVALIDPARAMS if D3DMatHandle = NULL
1405 *****************************************************************************/
1406 static HRESULT WINAPI
1407 IDirect3DDeviceImpl_1_CreateMatrix(IDirect3DDevice
*iface
, D3DMATRIXHANDLE
*D3DMatHandle
)
1409 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
1411 TRACE("(%p)->(%p)\n", This
, D3DMatHandle
);
1414 return DDERR_INVALIDPARAMS
;
1416 Matrix
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(D3DMATRIX
));
1419 ERR("Out of memory when allocating a D3DMATRIX\n");
1420 return DDERR_OUTOFMEMORY
;
1423 EnterCriticalSection(&ddraw_cs
);
1424 *D3DMatHandle
= IDirect3DDeviceImpl_CreateHandle(This
);
1425 if(!(*D3DMatHandle
))
1427 ERR("Failed to create a matrix handle\n");
1428 HeapFree(GetProcessHeap(), 0, Matrix
);
1429 LeaveCriticalSection(&ddraw_cs
);
1430 return DDERR_OUTOFMEMORY
;
1432 This
->Handles
[*D3DMatHandle
- 1].ptr
= Matrix
;
1433 This
->Handles
[*D3DMatHandle
- 1].type
= DDrawHandle_Matrix
;
1434 TRACE(" returning matrix handle %d\n", *D3DMatHandle
);
1436 LeaveCriticalSection(&ddraw_cs
);
1440 /*****************************************************************************
1441 * IDirect3DDevice::SetMatrix
1443 * Sets a matrix for a matrix handle. The matrix is copied into the memory
1444 * allocated for the handle
1449 * D3DMatHandle: Handle to set the matrix to
1450 * D3DMatrix: Matrix to set
1454 * DDERR_INVALIDPARAMS if the handle of the matrix is invalid or the matrix
1457 *****************************************************************************/
1458 static HRESULT WINAPI
1459 IDirect3DDeviceImpl_1_SetMatrix(IDirect3DDevice
*iface
,
1460 D3DMATRIXHANDLE D3DMatHandle
,
1461 D3DMATRIX
*D3DMatrix
)
1463 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
1464 TRACE("(%p)->(%08x,%p)\n", This
, D3DMatHandle
, D3DMatrix
);
1466 if( (!D3DMatHandle
) || (!D3DMatrix
) )
1467 return DDERR_INVALIDPARAMS
;
1469 EnterCriticalSection(&ddraw_cs
);
1470 if(D3DMatHandle
> This
->numHandles
)
1472 ERR("Handle %d out of range\n", D3DMatHandle
);
1473 LeaveCriticalSection(&ddraw_cs
);
1474 return DDERR_INVALIDPARAMS
;
1476 else if(This
->Handles
[D3DMatHandle
- 1].type
!= DDrawHandle_Matrix
)
1478 ERR("Handle %d is not a matrix handle\n", D3DMatHandle
);
1479 LeaveCriticalSection(&ddraw_cs
);
1480 return DDERR_INVALIDPARAMS
;
1484 dump_D3DMATRIX(D3DMatrix
);
1486 *((D3DMATRIX
*) This
->Handles
[D3DMatHandle
- 1].ptr
) = *D3DMatrix
;
1488 if(This
->world
== D3DMatHandle
)
1490 IWineD3DDevice_SetTransform(This
->wineD3DDevice
,
1491 WINED3DTS_WORLDMATRIX(0),
1492 (WINED3DMATRIX
*) D3DMatrix
);
1494 if(This
->view
== D3DMatHandle
)
1496 IWineD3DDevice_SetTransform(This
->wineD3DDevice
,
1498 (WINED3DMATRIX
*) D3DMatrix
);
1500 if(This
->proj
== D3DMatHandle
)
1502 IWineD3DDevice_SetTransform(This
->wineD3DDevice
,
1503 WINED3DTS_PROJECTION
,
1504 (WINED3DMATRIX
*) D3DMatrix
);
1507 LeaveCriticalSection(&ddraw_cs
);
1511 /*****************************************************************************
1512 * IDirect3DDevice::SetMatrix
1514 * Returns the content of a D3DMATRIX handle
1519 * D3DMatHandle: Matrix handle to read the content from
1520 * D3DMatrix: Address to store the content at
1524 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid or D3DMatrix is NULL
1526 *****************************************************************************/
1527 static HRESULT WINAPI
1528 IDirect3DDeviceImpl_1_GetMatrix(IDirect3DDevice
*iface
,
1529 D3DMATRIXHANDLE D3DMatHandle
,
1530 D3DMATRIX
*D3DMatrix
)
1532 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
1533 TRACE("(%p)->(%08x,%p)\n", This
, D3DMatHandle
, D3DMatrix
);
1536 return DDERR_INVALIDPARAMS
;
1538 return DDERR_INVALIDPARAMS
;
1540 EnterCriticalSection(&ddraw_cs
);
1541 if(D3DMatHandle
> This
->numHandles
)
1543 ERR("Handle %d out of range\n", D3DMatHandle
);
1544 LeaveCriticalSection(&ddraw_cs
);
1545 return DDERR_INVALIDPARAMS
;
1547 else if(This
->Handles
[D3DMatHandle
- 1].type
!= DDrawHandle_Matrix
)
1549 ERR("Handle %d is not a matrix handle\n", D3DMatHandle
);
1550 LeaveCriticalSection(&ddraw_cs
);
1551 return DDERR_INVALIDPARAMS
;
1554 /* The handle is simply a pointer to a D3DMATRIX structure */
1555 *D3DMatrix
= *((D3DMATRIX
*) This
->Handles
[D3DMatHandle
- 1].ptr
);
1557 LeaveCriticalSection(&ddraw_cs
);
1561 /*****************************************************************************
1562 * IDirect3DDevice::DeleteMatrix
1564 * Destroys a Matrix handle. Frees the memory and unsets the handle data
1569 * D3DMatHandle: Handle to destroy
1573 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid
1575 *****************************************************************************/
1576 static HRESULT WINAPI
1577 IDirect3DDeviceImpl_1_DeleteMatrix(IDirect3DDevice
*iface
,
1578 D3DMATRIXHANDLE D3DMatHandle
)
1580 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
1581 TRACE("(%p)->(%08x)\n", This
, D3DMatHandle
);
1584 return DDERR_INVALIDPARAMS
;
1586 EnterCriticalSection(&ddraw_cs
);
1587 if(D3DMatHandle
> This
->numHandles
)
1589 ERR("Handle %d out of range\n", D3DMatHandle
);
1590 LeaveCriticalSection(&ddraw_cs
);
1591 return DDERR_INVALIDPARAMS
;
1593 else if(This
->Handles
[D3DMatHandle
- 1].type
!= DDrawHandle_Matrix
)
1595 ERR("Handle %d is not a matrix handle\n", D3DMatHandle
);
1596 LeaveCriticalSection(&ddraw_cs
);
1597 return DDERR_INVALIDPARAMS
;
1600 HeapFree(GetProcessHeap(), 0, This
->Handles
[D3DMatHandle
- 1].ptr
);
1601 This
->Handles
[D3DMatHandle
- 1].ptr
= NULL
;
1602 This
->Handles
[D3DMatHandle
- 1].type
= DDrawHandle_Unknown
;
1604 LeaveCriticalSection(&ddraw_cs
);
1608 /*****************************************************************************
1609 * IDirect3DDevice7::BeginScene
1611 * This method must be called before any rendering is performed.
1612 * IDirect3DDevice::EndScene has to be called after the scene is complete
1614 * Version 1, 2, 3 and 7
1617 * D3D_OK on success, for details see IWineD3DDevice::BeginScene
1618 * D3DERR_SCENE_IN_SCENE if WineD3D returns an error(Only in case of an already
1621 *****************************************************************************/
1623 IDirect3DDeviceImpl_7_BeginScene(IDirect3DDevice7
*iface
)
1625 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
1627 TRACE("(%p): Relay\n", This
);
1629 EnterCriticalSection(&ddraw_cs
);
1630 hr
= IWineD3DDevice_BeginScene(This
->wineD3DDevice
);
1631 LeaveCriticalSection(&ddraw_cs
);
1632 if(hr
== WINED3D_OK
) return D3D_OK
;
1633 else return D3DERR_SCENE_IN_SCENE
; /* TODO: Other possible causes of failure */
1636 static HRESULT WINAPI
1637 IDirect3DDeviceImpl_7_BeginScene_FPUSetup(IDirect3DDevice7
*iface
)
1639 return IDirect3DDeviceImpl_7_BeginScene(iface
);
1642 static HRESULT WINAPI
1643 IDirect3DDeviceImpl_7_BeginScene_FPUPreserve(IDirect3DDevice7
*iface
)
1648 old_fpucw
= d3d_fpu_setup();
1649 hr
= IDirect3DDeviceImpl_7_BeginScene(iface
);
1650 set_fpu_control_word(old_fpucw
);
1655 static HRESULT WINAPI
1656 Thunk_IDirect3DDeviceImpl_3_BeginScene(IDirect3DDevice3
*iface
)
1658 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
1659 TRACE_(ddraw_thunk
)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This
);
1660 return IDirect3DDevice7_BeginScene((IDirect3DDevice7
*)This
);
1663 static HRESULT WINAPI
1664 Thunk_IDirect3DDeviceImpl_2_BeginScene(IDirect3DDevice2
*iface
)
1666 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
1667 TRACE_(ddraw_thunk
)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This
);
1668 return IDirect3DDevice7_BeginScene((IDirect3DDevice7
*)This
);
1671 static HRESULT WINAPI
1672 Thunk_IDirect3DDeviceImpl_1_BeginScene(IDirect3DDevice
*iface
)
1674 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
1675 TRACE_(ddraw_thunk
)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This
);
1676 return IDirect3DDevice7_BeginScene((IDirect3DDevice7
*)This
);
1679 /*****************************************************************************
1680 * IDirect3DDevice7::EndScene
1682 * Ends a scene that has been begun with IDirect3DDevice7::BeginScene.
1683 * This method must be called after rendering is finished.
1685 * Version 1, 2, 3 and 7
1688 * D3D_OK on success, for details see IWineD3DDevice::EndScene
1689 * D3DERR_SCENE_NOT_IN_SCENE is returned if WineD3D returns an error. It does
1690 * that only if the scene was already ended.
1692 *****************************************************************************/
1694 IDirect3DDeviceImpl_7_EndScene(IDirect3DDevice7
*iface
)
1696 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
1698 TRACE("(%p): Relay\n", This
);
1700 EnterCriticalSection(&ddraw_cs
);
1701 hr
= IWineD3DDevice_EndScene(This
->wineD3DDevice
);
1702 LeaveCriticalSection(&ddraw_cs
);
1703 if(hr
== WINED3D_OK
) return D3D_OK
;
1704 else return D3DERR_SCENE_NOT_IN_SCENE
;
1707 static HRESULT WINAPI
1708 IDirect3DDeviceImpl_7_EndScene_FPUSetup(IDirect3DDevice7
*iface
)
1710 return IDirect3DDeviceImpl_7_EndScene(iface
);
1713 static HRESULT WINAPI
1714 IDirect3DDeviceImpl_7_EndScene_FPUPreserve(IDirect3DDevice7
*iface
)
1719 old_fpucw
= d3d_fpu_setup();
1720 hr
= IDirect3DDeviceImpl_7_EndScene(iface
);
1721 set_fpu_control_word(old_fpucw
);
1726 static HRESULT WINAPI
1727 Thunk_IDirect3DDeviceImpl_3_EndScene(IDirect3DDevice3
*iface
)
1729 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
1730 TRACE_(ddraw_thunk
)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This
);
1731 return IDirect3DDevice7_EndScene((IDirect3DDevice7
*)This
);
1734 static HRESULT WINAPI
1735 Thunk_IDirect3DDeviceImpl_2_EndScene(IDirect3DDevice2
*iface
)
1737 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
1738 TRACE_(ddraw_thunk
)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This
);
1739 return IDirect3DDevice7_EndScene((IDirect3DDevice7
*)This
);
1742 static HRESULT WINAPI
1743 Thunk_IDirect3DDeviceImpl_1_EndScene(IDirect3DDevice
*iface
)
1745 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
1746 TRACE_(ddraw_thunk
)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This
);
1747 return IDirect3DDevice7_EndScene((IDirect3DDevice7
*)This
);
1750 /*****************************************************************************
1751 * IDirect3DDevice7::GetDirect3D
1753 * Returns the IDirect3D(= interface to the DirectDraw object) used to create
1757 * Direct3D7: Address to store the interface pointer at
1761 * DDERR_INVALIDPARAMS if Direct3D7 == NULL
1763 *****************************************************************************/
1764 static HRESULT WINAPI
1765 IDirect3DDeviceImpl_7_GetDirect3D(IDirect3DDevice7
*iface
,
1766 IDirect3D7
**Direct3D7
)
1768 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
1769 TRACE("(%p)->(%p)\n", This
, Direct3D7
);
1772 return DDERR_INVALIDPARAMS
;
1774 *Direct3D7
= (IDirect3D7
*)&This
->ddraw
->IDirect3D7_vtbl
;
1775 IDirect3D7_AddRef(*Direct3D7
);
1777 TRACE(" returning interface %p\n", *Direct3D7
);
1781 static HRESULT WINAPI
1782 Thunk_IDirect3DDeviceImpl_3_GetDirect3D(IDirect3DDevice3
*iface
,
1783 IDirect3D3
**Direct3D3
)
1785 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
1787 IDirect3D7
*ret_ptr
;
1789 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This
, Direct3D3
);
1790 ret
= IDirect3DDevice7_GetDirect3D((IDirect3DDevice7
*)This
, &ret_ptr
);
1793 *Direct3D3
= ret_ptr
? (IDirect3D3
*)&ddraw_from_d3d7(ret_ptr
)->IDirect3D3_vtbl
: NULL
;
1794 TRACE(" returning interface %p\n", *Direct3D3
);
1798 static HRESULT WINAPI
1799 Thunk_IDirect3DDeviceImpl_2_GetDirect3D(IDirect3DDevice2
*iface
,
1800 IDirect3D2
**Direct3D2
)
1802 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
1804 IDirect3D7
*ret_ptr
;
1806 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This
, Direct3D2
);
1807 ret
= IDirect3DDevice7_GetDirect3D((IDirect3DDevice7
*)This
, &ret_ptr
);
1810 *Direct3D2
= ret_ptr
? (IDirect3D2
*)&ddraw_from_d3d7(ret_ptr
)->IDirect3D2_vtbl
: NULL
;
1811 TRACE(" returning interface %p\n", *Direct3D2
);
1815 static HRESULT WINAPI
1816 Thunk_IDirect3DDeviceImpl_1_GetDirect3D(IDirect3DDevice
*iface
,
1817 IDirect3D
**Direct3D
)
1819 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
1821 IDirect3D7
*ret_ptr
;
1823 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This
, Direct3D
);
1824 ret
= IDirect3DDevice7_GetDirect3D((IDirect3DDevice7
*)This
, &ret_ptr
);
1827 *Direct3D
= ret_ptr
? (IDirect3D
*)&ddraw_from_d3d7(ret_ptr
)->IDirect3D_vtbl
: NULL
;
1828 TRACE(" returning interface %p\n", *Direct3D
);
1832 /*****************************************************************************
1833 * IDirect3DDevice3::SetCurrentViewport
1835 * Sets a Direct3DViewport as the current viewport.
1836 * For the thunks note that all viewport interface versions are equal
1839 * Direct3DViewport3: The viewport to set
1845 * (Is a NULL viewport valid?)
1847 *****************************************************************************/
1848 static HRESULT WINAPI
1849 IDirect3DDeviceImpl_3_SetCurrentViewport(IDirect3DDevice3
*iface
,
1850 IDirect3DViewport3
*Direct3DViewport3
)
1852 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
1853 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*)Direct3DViewport3
;
1854 TRACE("(%p)->(%p)\n", This
, Direct3DViewport3
);
1856 EnterCriticalSection(&ddraw_cs
);
1857 /* Do nothing if the specified viewport is the same as the current one */
1858 if (This
->current_viewport
== vp
)
1860 LeaveCriticalSection(&ddraw_cs
);
1864 /* Should check if the viewport was added or not */
1866 /* Release previous viewport and AddRef the new one */
1867 if (This
->current_viewport
)
1869 TRACE("ViewportImpl is at %p, interface is at %p\n", This
->current_viewport
,
1870 (IDirect3DViewport3
*)This
->current_viewport
);
1871 IDirect3DViewport3_Release((IDirect3DViewport3
*)This
->current_viewport
);
1873 IDirect3DViewport3_AddRef(Direct3DViewport3
);
1875 /* Set this viewport as the current viewport */
1876 This
->current_viewport
= vp
;
1878 /* Activate this viewport */
1879 This
->current_viewport
->active_device
= This
;
1880 This
->current_viewport
->activate(This
->current_viewport
, FALSE
);
1882 LeaveCriticalSection(&ddraw_cs
);
1886 static HRESULT WINAPI
1887 Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport(IDirect3DDevice2
*iface
,
1888 IDirect3DViewport2
*Direct3DViewport2
)
1890 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
1891 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*)Direct3DViewport2
;
1892 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This
, vp
);
1893 return IDirect3DDevice3_SetCurrentViewport((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
,
1894 (IDirect3DViewport3
*)vp
);
1897 /*****************************************************************************
1898 * IDirect3DDevice3::GetCurrentViewport
1900 * Returns the currently active viewport.
1905 * Direct3DViewport3: Address to return the interface pointer at
1909 * DDERR_INVALIDPARAMS if Direct3DViewport == NULL
1911 *****************************************************************************/
1912 static HRESULT WINAPI
1913 IDirect3DDeviceImpl_3_GetCurrentViewport(IDirect3DDevice3
*iface
,
1914 IDirect3DViewport3
**Direct3DViewport3
)
1916 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
1917 TRACE("(%p)->(%p)\n", This
, Direct3DViewport3
);
1919 if(!Direct3DViewport3
)
1920 return DDERR_INVALIDPARAMS
;
1922 EnterCriticalSection(&ddraw_cs
);
1923 *Direct3DViewport3
= (IDirect3DViewport3
*)This
->current_viewport
;
1925 /* AddRef the returned viewport */
1926 if(*Direct3DViewport3
) IDirect3DViewport3_AddRef(*Direct3DViewport3
);
1928 TRACE(" returning interface %p\n", *Direct3DViewport3
);
1930 LeaveCriticalSection(&ddraw_cs
);
1934 static HRESULT WINAPI
1935 Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport(IDirect3DDevice2
*iface
,
1936 IDirect3DViewport2
**Direct3DViewport2
)
1938 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
1940 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This
, Direct3DViewport2
);
1941 hr
= IDirect3DDevice3_GetCurrentViewport((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
,
1942 (IDirect3DViewport3
**)Direct3DViewport2
);
1943 if(hr
!= D3D_OK
) return hr
;
1947 /*****************************************************************************
1948 * IDirect3DDevice7::SetRenderTarget
1950 * Sets the render target for the Direct3DDevice.
1951 * For the thunks note that IDirectDrawSurface7 == IDirectDrawSurface4 and
1952 * IDirectDrawSurface3 == IDirectDrawSurface
1954 * Version 2, 3 and 7
1957 * NewTarget: Pointer to an IDirectDrawSurface7 interface to set as the new
1962 * D3D_OK on success, for details see IWineD3DDevice::SetRenderTarget
1964 *****************************************************************************/
1966 IDirect3DDeviceImpl_7_SetRenderTarget(IDirect3DDevice7
*iface
,
1967 IDirectDrawSurface7
*NewTarget
,
1970 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
1971 IDirectDrawSurfaceImpl
*Target
= (IDirectDrawSurfaceImpl
*)NewTarget
;
1973 TRACE("(%p)->(%p,%08x): Relay\n", This
, NewTarget
, Flags
);
1975 EnterCriticalSection(&ddraw_cs
);
1976 /* Flags: Not used */
1978 if(This
->target
== Target
)
1980 TRACE("No-op SetRenderTarget operation, not doing anything\n");
1981 LeaveCriticalSection(&ddraw_cs
);
1985 hr
= IWineD3DDevice_SetRenderTarget(This
->wineD3DDevice
,
1987 Target
? Target
->WineD3DSurface
: NULL
);
1990 LeaveCriticalSection(&ddraw_cs
);
1993 IDirectDrawSurface7_AddRef(NewTarget
);
1994 IDirectDrawSurface7_Release((IDirectDrawSurface7
*)This
->target
);
1995 This
->target
= Target
;
1996 IDirect3DDeviceImpl_UpdateDepthStencil(This
);
1997 LeaveCriticalSection(&ddraw_cs
);
2001 static HRESULT WINAPI
2002 IDirect3DDeviceImpl_7_SetRenderTarget_FPUSetup(IDirect3DDevice7
*iface
,
2003 IDirectDrawSurface7
*NewTarget
,
2006 return IDirect3DDeviceImpl_7_SetRenderTarget(iface
, NewTarget
, Flags
);
2009 static HRESULT WINAPI
2010 IDirect3DDeviceImpl_7_SetRenderTarget_FPUPreserve(IDirect3DDevice7
*iface
,
2011 IDirectDrawSurface7
*NewTarget
,
2017 old_fpucw
= d3d_fpu_setup();
2018 hr
= IDirect3DDeviceImpl_7_SetRenderTarget(iface
, NewTarget
, Flags
);
2019 set_fpu_control_word(old_fpucw
);
2024 static HRESULT WINAPI
2025 Thunk_IDirect3DDeviceImpl_3_SetRenderTarget(IDirect3DDevice3
*iface
,
2026 IDirectDrawSurface4
*NewRenderTarget
,
2029 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
2030 IDirectDrawSurfaceImpl
*Target
= (IDirectDrawSurfaceImpl
*)NewRenderTarget
;
2031 TRACE_(ddraw_thunk
)("(%p)->(%p,%08x) thunking to IDirect3DDevice7 interface.\n", This
, Target
, Flags
);
2032 return IDirect3DDevice7_SetRenderTarget((IDirect3DDevice7
*)This
, (IDirectDrawSurface7
*)Target
, Flags
);
2035 static HRESULT WINAPI
2036 Thunk_IDirect3DDeviceImpl_2_SetRenderTarget(IDirect3DDevice2
*iface
,
2037 IDirectDrawSurface
*NewRenderTarget
,
2040 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
2041 IDirectDrawSurfaceImpl
*Target
= (IDirectDrawSurfaceImpl
*)NewRenderTarget
;
2042 TRACE_(ddraw_thunk
)("(%p)->(%p,%08x) thunking to IDirect3DDevice7 interface.\n", This
, Target
, Flags
);
2043 return IDirect3DDevice7_SetRenderTarget((IDirect3DDevice7
*)This
, (IDirectDrawSurface7
*)Target
, Flags
);
2046 /*****************************************************************************
2047 * IDirect3DDevice7::GetRenderTarget
2049 * Returns the current render target.
2050 * This is handled locally, because the WineD3D render target's parent
2053 * Version 2, 3 and 7
2056 * RenderTarget: Address to store the surface interface pointer
2060 * DDERR_INVALIDPARAMS if RenderTarget == NULL
2062 *****************************************************************************/
2063 static HRESULT WINAPI
2064 IDirect3DDeviceImpl_7_GetRenderTarget(IDirect3DDevice7
*iface
,
2065 IDirectDrawSurface7
**RenderTarget
)
2067 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
2068 TRACE("(%p)->(%p): Relay\n", This
, RenderTarget
);
2071 return DDERR_INVALIDPARAMS
;
2073 EnterCriticalSection(&ddraw_cs
);
2074 *RenderTarget
= (IDirectDrawSurface7
*)This
->target
;
2075 IDirectDrawSurface7_AddRef(*RenderTarget
);
2077 LeaveCriticalSection(&ddraw_cs
);
2081 static HRESULT WINAPI
2082 Thunk_IDirect3DDeviceImpl_3_GetRenderTarget(IDirect3DDevice3
*iface
,
2083 IDirectDrawSurface4
**RenderTarget
)
2085 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
2087 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This
, RenderTarget
);
2088 hr
= IDirect3DDevice7_GetRenderTarget((IDirect3DDevice7
*)This
, (IDirectDrawSurface7
**)RenderTarget
);
2089 if(hr
!= D3D_OK
) return hr
;
2093 static HRESULT WINAPI
2094 Thunk_IDirect3DDeviceImpl_2_GetRenderTarget(IDirect3DDevice2
*iface
,
2095 IDirectDrawSurface
**RenderTarget
)
2097 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
2099 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This
, RenderTarget
);
2100 hr
= IDirect3DDevice7_GetRenderTarget((IDirect3DDevice7
*)This
, (IDirectDrawSurface7
**)RenderTarget
);
2101 if(hr
!= D3D_OK
) return hr
;
2102 *RenderTarget
= *RenderTarget
?
2103 (IDirectDrawSurface
*)&((IDirectDrawSurfaceImpl
*)*RenderTarget
)->IDirectDrawSurface3_vtbl
: NULL
;
2107 /*****************************************************************************
2108 * IDirect3DDevice3::Begin
2110 * Begins a description block of vertices. This is similar to glBegin()
2111 * and glEnd(). After a call to IDirect3DDevice3::End, the vertices
2112 * described with IDirect3DDevice::Vertex are drawn.
2117 * PrimitiveType: The type of primitives to draw
2118 * VertexTypeDesc: A flexible vertex format description of the vertices
2119 * Flags: Some flags..
2124 *****************************************************************************/
2125 static HRESULT WINAPI
2126 IDirect3DDeviceImpl_3_Begin(IDirect3DDevice3
*iface
,
2127 D3DPRIMITIVETYPE PrimitiveType
,
2128 DWORD VertexTypeDesc
,
2131 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
2132 TRACE("(%p)->(%d,%d,%08x)\n", This
, PrimitiveType
, VertexTypeDesc
, Flags
);
2134 EnterCriticalSection(&ddraw_cs
);
2135 This
->primitive_type
= PrimitiveType
;
2136 This
->vertex_type
= VertexTypeDesc
;
2137 This
->render_flags
= Flags
;
2138 This
->vertex_size
= get_flexible_vertex_size(This
->vertex_type
);
2139 This
->nb_vertices
= 0;
2140 LeaveCriticalSection(&ddraw_cs
);
2145 static HRESULT WINAPI
2146 Thunk_IDirect3DDeviceImpl_2_Begin(IDirect3DDevice2
*iface
,
2147 D3DPRIMITIVETYPE d3dpt
,
2148 D3DVERTEXTYPE dwVertexTypeDesc
,
2152 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
2153 TRACE_(ddraw_thunk
)("(%p/%p)->(%08x,%08x,%08x): Thunking to IDirect3DDevice3\n", This
, iface
, d3dpt
, dwVertexTypeDesc
, dwFlags
);
2155 switch(dwVertexTypeDesc
)
2157 case D3DVT_VERTEX
: FVF
= D3DFVF_VERTEX
; break;
2158 case D3DVT_LVERTEX
: FVF
= D3DFVF_LVERTEX
; break;
2159 case D3DVT_TLVERTEX
: FVF
= D3DFVF_TLVERTEX
; break;
2161 ERR("Unexpected vertex type %d\n", dwVertexTypeDesc
);
2162 return DDERR_INVALIDPARAMS
; /* Should never happen */
2165 return IDirect3DDevice3_Begin((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, d3dpt
, FVF
, dwFlags
);
2168 /*****************************************************************************
2169 * IDirect3DDevice3::BeginIndexed
2171 * Draws primitives based on vertices in a vertex array which are specified
2177 * PrimitiveType: Primitive type to draw
2178 * VertexType: A FVF description of the vertex format
2179 * Vertices: pointer to an array containing the vertices
2180 * NumVertices: The number of vertices in the vertex array
2181 * Flags: Some flags ...
2184 * D3D_OK, because it's a stub
2186 *****************************************************************************/
2187 static HRESULT WINAPI
2188 IDirect3DDeviceImpl_3_BeginIndexed(IDirect3DDevice3
*iface
,
2189 D3DPRIMITIVETYPE PrimitiveType
,
2195 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
2196 FIXME("(%p)->(%08x,%08x,%p,%08x,%08x): stub!\n", This
, PrimitiveType
, VertexType
, Vertices
, NumVertices
, Flags
);
2201 static HRESULT WINAPI
2202 Thunk_IDirect3DDeviceImpl_2_BeginIndexed(IDirect3DDevice2
*iface
,
2203 D3DPRIMITIVETYPE d3dptPrimitiveType
,
2204 D3DVERTEXTYPE d3dvtVertexType
,
2206 DWORD dwNumVertices
,
2210 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
2211 TRACE_(ddraw_thunk
)("(%p/%p)->(%08x,%08x,%p,%08x,%08x): Thunking to IDirect3DDevice3\n", This
, iface
, d3dptPrimitiveType
, d3dvtVertexType
, lpvVertices
, dwNumVertices
, dwFlags
);
2213 switch(d3dvtVertexType
)
2215 case D3DVT_VERTEX
: FVF
= D3DFVF_VERTEX
; break;
2216 case D3DVT_LVERTEX
: FVF
= D3DFVF_LVERTEX
; break;
2217 case D3DVT_TLVERTEX
: FVF
= D3DFVF_TLVERTEX
; break;
2219 ERR("Unexpected vertex type %d\n", d3dvtVertexType
);
2220 return DDERR_INVALIDPARAMS
; /* Should never happen */
2223 return IDirect3DDevice3_BeginIndexed((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
,
2224 d3dptPrimitiveType
, FVF
, lpvVertices
, dwNumVertices
, dwFlags
);
2227 /*****************************************************************************
2228 * IDirect3DDevice3::Vertex
2230 * Draws a vertex as described by IDirect3DDevice3::Begin. It places all
2231 * drawn vertices in a vertex buffer. If the buffer is too small, its
2232 * size is increased.
2237 * Vertex: Pointer to the vertex
2240 * D3D_OK, on success
2241 * DDERR_INVALIDPARAMS if Vertex is NULL
2243 *****************************************************************************/
2244 static HRESULT WINAPI
2245 IDirect3DDeviceImpl_3_Vertex(IDirect3DDevice3
*iface
,
2248 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
2249 TRACE("(%p)->(%p)\n", This
, Vertex
);
2252 return DDERR_INVALIDPARAMS
;
2254 EnterCriticalSection(&ddraw_cs
);
2255 if ((This
->nb_vertices
+1)*This
->vertex_size
> This
->buffer_size
)
2258 This
->buffer_size
= This
->buffer_size
? This
->buffer_size
* 2 : This
->vertex_size
* 3;
2259 old_buffer
= This
->vertex_buffer
;
2260 This
->vertex_buffer
= HeapAlloc(GetProcessHeap(), 0, This
->buffer_size
);
2263 CopyMemory(This
->vertex_buffer
, old_buffer
, This
->nb_vertices
* This
->vertex_size
);
2264 HeapFree(GetProcessHeap(), 0, old_buffer
);
2268 CopyMemory(This
->vertex_buffer
+ This
->nb_vertices
++ * This
->vertex_size
, Vertex
, This
->vertex_size
);
2270 LeaveCriticalSection(&ddraw_cs
);
2274 static HRESULT WINAPI
2275 Thunk_IDirect3DDeviceImpl_2_Vertex(IDirect3DDevice2
*iface
,
2278 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
2279 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This
, lpVertexType
);
2280 return IDirect3DDevice3_Vertex((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, lpVertexType
);
2283 /*****************************************************************************
2284 * IDirect3DDevice3::Index
2286 * Specifies an index to a vertex to be drawn. The vertex array has to
2287 * be specified with BeginIndexed first.
2290 * VertexIndex: The index of the vertex to draw
2293 * D3D_OK because it's a stub
2295 *****************************************************************************/
2296 static HRESULT WINAPI
2297 IDirect3DDeviceImpl_3_Index(IDirect3DDevice3
*iface
,
2300 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
2301 FIXME("(%p)->(%04x): stub!\n", This
, VertexIndex
);
2305 static HRESULT WINAPI
2306 Thunk_IDirect3DDeviceImpl_2_Index(IDirect3DDevice2
*iface
,
2309 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
2310 TRACE_(ddraw_thunk
)("(%p)->(%04x) thunking to IDirect3DDevice3 interface.\n", This
, wVertexIndex
);
2311 return IDirect3DDevice3_Index((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, wVertexIndex
);
2314 /*****************************************************************************
2315 * IDirect3DDevice3::End
2317 * Ends a draw begun with IDirect3DDevice3::Begin or
2318 * IDirect3DDevice::BeginIndexed. The vertices specified with
2319 * IDirect3DDevice::Vertex or IDirect3DDevice::Index are drawn using
2320 * the IDirect3DDevice7::DrawPrimitive method. So far only
2321 * non-indexed mode is supported
2326 * Flags: Some flags, as usual. Don't know which are defined
2329 * The return value of IDirect3DDevice7::DrawPrimitive
2331 *****************************************************************************/
2332 static HRESULT WINAPI
2333 IDirect3DDeviceImpl_3_End(IDirect3DDevice3
*iface
,
2336 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
2337 TRACE("(%p)->(%08x)\n", This
, Flags
);
2339 return IDirect3DDevice7_DrawPrimitive((IDirect3DDevice7
*)This
, This
->primitive_type
,
2340 This
->vertex_type
, This
->vertex_buffer
, This
->nb_vertices
, This
->render_flags
);
2343 static HRESULT WINAPI
2344 Thunk_IDirect3DDeviceImpl_2_End(IDirect3DDevice2
*iface
,
2347 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
2348 TRACE_(ddraw_thunk
)("(%p)->(%08x) thunking to IDirect3DDevice3 interface.\n", This
, dwFlags
);
2349 return IDirect3DDevice3_End((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, dwFlags
);
2352 /*****************************************************************************
2353 * IDirect3DDevice7::GetRenderState
2355 * Returns the value of a render state. The possible render states are
2356 * defined in include/d3dtypes.h
2358 * Version 2, 3 and 7
2361 * RenderStateType: Render state to return the current setting of
2362 * Value: Address to store the value at
2365 * D3D_OK on success, for details see IWineD3DDevice::GetRenderState
2366 * DDERR_INVALIDPARAMS if Value == NULL
2368 *****************************************************************************/
2370 IDirect3DDeviceImpl_7_GetRenderState(IDirect3DDevice7
*iface
,
2371 D3DRENDERSTATETYPE RenderStateType
,
2374 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
2376 TRACE("(%p)->(%08x,%p): Relay\n", This
, RenderStateType
, Value
);
2379 return DDERR_INVALIDPARAMS
;
2381 EnterCriticalSection(&ddraw_cs
);
2382 switch(RenderStateType
)
2384 case D3DRENDERSTATE_TEXTUREMAG
:
2386 WINED3DTEXTUREFILTERTYPE tex_mag
;
2388 hr
= IWineD3DDevice_GetSamplerState(This
->wineD3DDevice
,
2389 0, WINED3DSAMP_MAGFILTER
,
2394 case WINED3DTEXF_POINT
:
2395 *Value
= D3DFILTER_NEAREST
;
2397 case WINED3DTEXF_LINEAR
:
2398 *Value
= D3DFILTER_LINEAR
;
2401 ERR("Unhandled texture mag %d !\n",tex_mag
);
2407 case D3DRENDERSTATE_TEXTUREMIN
:
2409 WINED3DTEXTUREFILTERTYPE tex_min
;
2411 hr
= IWineD3DDevice_GetSamplerState(This
->wineD3DDevice
,
2412 0, WINED3DSAMP_MINFILTER
,
2417 case WINED3DTEXF_POINT
:
2418 *Value
= D3DFILTER_NEAREST
;
2420 case WINED3DTEXF_LINEAR
:
2421 *Value
= D3DFILTER_LINEAR
;
2424 ERR("Unhandled texture mag %d !\n",tex_min
);
2430 case D3DRENDERSTATE_TEXTUREADDRESS
:
2431 case D3DRENDERSTATE_TEXTUREADDRESSU
:
2432 hr
= IWineD3DDevice_GetSamplerState(This
->wineD3DDevice
,
2433 0, WINED3DSAMP_ADDRESSU
,
2436 case D3DRENDERSTATE_TEXTUREADDRESSV
:
2437 hr
= IWineD3DDevice_GetSamplerState(This
->wineD3DDevice
,
2438 0, WINED3DSAMP_ADDRESSV
,
2443 /* FIXME: Unhandled: D3DRENDERSTATE_STIPPLEPATTERN00 - 31 */
2444 hr
= IWineD3DDevice_GetRenderState(This
->wineD3DDevice
,
2448 LeaveCriticalSection(&ddraw_cs
);
2452 static HRESULT WINAPI
2453 IDirect3DDeviceImpl_7_GetRenderState_FPUSetup(IDirect3DDevice7
*iface
,
2454 D3DRENDERSTATETYPE RenderStateType
,
2457 return IDirect3DDeviceImpl_7_GetRenderState(iface
, RenderStateType
, Value
);
2460 static HRESULT WINAPI
2461 IDirect3DDeviceImpl_7_GetRenderState_FPUPreserve(IDirect3DDevice7
*iface
,
2462 D3DRENDERSTATETYPE RenderStateType
,
2468 old_fpucw
= d3d_fpu_setup();
2469 hr
= IDirect3DDeviceImpl_7_GetRenderState(iface
, RenderStateType
, Value
);
2470 set_fpu_control_word(old_fpucw
);
2475 static HRESULT WINAPI
2476 IDirect3DDeviceImpl_3_GetRenderState(IDirect3DDevice3
*iface
,
2477 D3DRENDERSTATETYPE dwRenderStateType
,
2478 DWORD
*lpdwRenderState
)
2480 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
2482 TRACE("(%p)->(%08x,%p)\n", This
, dwRenderStateType
, lpdwRenderState
);
2484 switch(dwRenderStateType
)
2486 case D3DRENDERSTATE_TEXTUREHANDLE
:
2488 /* This state is wrapped to SetTexture in SetRenderState, so
2489 * it has to be wrapped to GetTexture here
2491 IWineD3DBaseTexture
*tex
= NULL
;
2492 *lpdwRenderState
= 0;
2494 EnterCriticalSection(&ddraw_cs
);
2496 hr
= IWineD3DDevice_GetTexture(This
->wineD3DDevice
,
2500 if(hr
== WINED3D_OK
&& tex
)
2502 IDirectDrawSurface7
*parent
= NULL
;
2503 hr
= IWineD3DBaseTexture_GetParent(tex
,
2504 (IUnknown
**) &parent
);
2507 /* The parent of the texture is the IDirectDrawSurface7 interface
2508 * of the ddraw surface
2510 IDirectDrawSurfaceImpl
*texImpl
= (IDirectDrawSurfaceImpl
*)parent
;
2511 *lpdwRenderState
= texImpl
->Handle
;
2512 IDirectDrawSurface7_Release(parent
);
2514 IWineD3DBaseTexture_Release(tex
);
2517 LeaveCriticalSection(&ddraw_cs
);
2522 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2524 /* D3DRENDERSTATE_TEXTUREMAPBLEND is mapped to texture state stages in SetRenderState; reverse
2525 the mapping to get the value. */
2526 DWORD colorop
, colorarg1
, colorarg2
;
2527 DWORD alphaop
, alphaarg1
, alphaarg2
;
2529 EnterCriticalSection(&ddraw_cs
);
2531 This
->legacyTextureBlending
= TRUE
;
2533 IWineD3DDevice_GetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLOROP
, &colorop
);
2534 IWineD3DDevice_GetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG1
, &colorarg1
);
2535 IWineD3DDevice_GetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG2
, &colorarg2
);
2536 IWineD3DDevice_GetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAOP
, &alphaop
);
2537 IWineD3DDevice_GetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG1
, &alphaarg1
);
2538 IWineD3DDevice_GetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG2
, &alphaarg2
);
2540 if (colorop
== WINED3DTOP_SELECTARG1
&& colorarg1
== WINED3DTA_TEXTURE
&&
2541 alphaop
== WINED3DTOP_SELECTARG1
&& alphaarg1
== WINED3DTA_TEXTURE
)
2543 *lpdwRenderState
= D3DTBLEND_DECAL
;
2545 else if (colorop
== WINED3DTOP_SELECTARG1
&& colorarg1
== WINED3DTA_TEXTURE
&&
2546 alphaop
== WINED3DTOP_MODULATE
&& alphaarg1
== WINED3DTA_TEXTURE
&& alphaarg2
== WINED3DTA_CURRENT
)
2548 *lpdwRenderState
= D3DTBLEND_DECALALPHA
;
2550 else if (colorop
== WINED3DTOP_MODULATE
&& colorarg1
== WINED3DTA_TEXTURE
&& colorarg2
== WINED3DTA_CURRENT
&&
2551 alphaop
== WINED3DTOP_MODULATE
&& alphaarg1
== WINED3DTA_TEXTURE
&& alphaarg2
== WINED3DTA_CURRENT
)
2553 *lpdwRenderState
= D3DTBLEND_MODULATEALPHA
;
2558 BOOL tex_alpha
= FALSE
;
2559 IWineD3DBaseTexture
*tex
= NULL
;
2560 WINED3DSURFACE_DESC desc
;
2562 DDPIXELFORMAT ddfmt
;
2564 hr
= IWineD3DDevice_GetTexture(This
->wineD3DDevice
,
2568 if(hr
== WINED3D_OK
&& tex
)
2570 memset(&desc
, 0, sizeof(desc
));
2572 hr
= IWineD3DTexture_GetLevelDesc((IWineD3DTexture
*) tex
, 0, &desc
);
2575 ddfmt
.dwSize
= sizeof(ddfmt
);
2576 PixelFormat_WineD3DtoDD(&ddfmt
, fmt
);
2577 if (ddfmt
.u5
.dwRGBAlphaBitMask
) tex_alpha
= TRUE
;
2580 IWineD3DBaseTexture_Release(tex
);
2583 if (!(colorop
== WINED3DTOP_MODULATE
&& colorarg1
== WINED3DTA_TEXTURE
&& colorarg2
== WINED3DTA_CURRENT
&&
2584 alphaop
== WINED3DTOP_SELECTARG1
&& alphaarg1
== (tex_alpha
? WINED3DTA_TEXTURE
: WINED3DTA_CURRENT
)))
2586 ERR("Unexpected texture stage state setup, returning D3DTBLEND_MODULATE - likely erroneous\n");
2589 *lpdwRenderState
= D3DTBLEND_MODULATE
;
2592 LeaveCriticalSection(&ddraw_cs
);
2598 return IDirect3DDevice7_GetRenderState((IDirect3DDevice7
*)This
, dwRenderStateType
, lpdwRenderState
);
2602 static HRESULT WINAPI
2603 Thunk_IDirect3DDeviceImpl_2_GetRenderState(IDirect3DDevice2
*iface
,
2604 D3DRENDERSTATETYPE dwRenderStateType
,
2605 DWORD
*lpdwRenderState
)
2607 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
2608 TRACE_(ddraw_thunk
)("(%p)->(%08x,%p) thunking to IDirect3DDevice3 interface.\n", This
, dwRenderStateType
, lpdwRenderState
);
2609 return IDirect3DDevice3_GetRenderState((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
,
2610 dwRenderStateType
, lpdwRenderState
);
2613 /*****************************************************************************
2614 * IDirect3DDevice7::SetRenderState
2616 * Sets a render state. The possible render states are defined in
2617 * include/d3dtypes.h
2619 * Version 2, 3 and 7
2622 * RenderStateType: State to set
2623 * Value: Value to assign to that state
2626 * D3D_OK on success,
2627 * for details see IWineD3DDevice::SetRenderState
2629 *****************************************************************************/
2631 IDirect3DDeviceImpl_7_SetRenderState(IDirect3DDevice7
*iface
,
2632 D3DRENDERSTATETYPE RenderStateType
,
2635 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
2637 TRACE("(%p)->(%08x,%d): Relay\n", This
, RenderStateType
, Value
);
2639 EnterCriticalSection(&ddraw_cs
);
2640 /* Some render states need special care */
2641 switch(RenderStateType
)
2643 case D3DRENDERSTATE_TEXTUREMAG
:
2645 WINED3DTEXTUREFILTERTYPE tex_mag
= WINED3DTEXF_NONE
;
2647 switch ((D3DTEXTUREFILTER
) Value
)
2649 case D3DFILTER_NEAREST
:
2650 case D3DFILTER_LINEARMIPNEAREST
:
2651 tex_mag
= WINED3DTEXF_POINT
;
2653 case D3DFILTER_LINEAR
:
2654 case D3DFILTER_LINEARMIPLINEAR
:
2655 tex_mag
= WINED3DTEXF_LINEAR
;
2658 ERR("Unhandled texture mag %d !\n",Value
);
2661 hr
= IWineD3DDevice_SetSamplerState(This
->wineD3DDevice
,
2662 0, WINED3DSAMP_MAGFILTER
,
2667 case D3DRENDERSTATE_TEXTUREMIN
:
2669 WINED3DTEXTUREFILTERTYPE tex_min
= WINED3DTEXF_NONE
;
2670 WINED3DTEXTUREFILTERTYPE tex_mip
= WINED3DTEXF_NONE
;
2672 switch ((D3DTEXTUREFILTER
) Value
)
2674 case D3DFILTER_NEAREST
:
2675 tex_min
= WINED3DTEXF_POINT
;
2677 case D3DFILTER_LINEAR
:
2678 tex_min
= WINED3DTEXF_LINEAR
;
2680 case D3DFILTER_MIPNEAREST
:
2681 tex_min
= WINED3DTEXF_NONE
;
2682 tex_mip
= WINED3DTEXF_POINT
;
2684 case D3DFILTER_MIPLINEAR
:
2685 tex_min
= WINED3DTEXF_NONE
;
2686 tex_mip
= WINED3DTEXF_LINEAR
;
2688 case D3DFILTER_LINEARMIPNEAREST
:
2689 tex_min
= WINED3DTEXF_POINT
;
2690 tex_mip
= WINED3DTEXF_LINEAR
;
2692 case D3DFILTER_LINEARMIPLINEAR
:
2693 tex_min
= WINED3DTEXF_LINEAR
;
2694 tex_mip
= WINED3DTEXF_LINEAR
;
2698 ERR("Unhandled texture min %d !\n",Value
);
2701 IWineD3DDevice_SetSamplerState(This
->wineD3DDevice
,
2702 0, WINED3DSAMP_MIPFILTER
,
2704 hr
= IWineD3DDevice_SetSamplerState(This
->wineD3DDevice
,
2705 0, WINED3DSAMP_MINFILTER
,
2710 case D3DRENDERSTATE_TEXTUREADDRESS
:
2711 IWineD3DDevice_SetSamplerState(This
->wineD3DDevice
,
2712 0, WINED3DSAMP_ADDRESSV
,
2715 case D3DRENDERSTATE_TEXTUREADDRESSU
:
2716 hr
= IWineD3DDevice_SetSamplerState(This
->wineD3DDevice
,
2717 0, WINED3DSAMP_ADDRESSU
,
2720 case D3DRENDERSTATE_TEXTUREADDRESSV
:
2721 hr
= IWineD3DDevice_SetSamplerState(This
->wineD3DDevice
,
2722 0, WINED3DSAMP_ADDRESSV
,
2728 /* FIXME: Unhandled: D3DRENDERSTATE_STIPPLEPATTERN00 - 31 */
2730 hr
= IWineD3DDevice_SetRenderState(This
->wineD3DDevice
,
2735 LeaveCriticalSection(&ddraw_cs
);
2739 static HRESULT WINAPI
2740 IDirect3DDeviceImpl_7_SetRenderState_FPUSetup(IDirect3DDevice7
*iface
,
2741 D3DRENDERSTATETYPE RenderStateType
,
2744 return IDirect3DDeviceImpl_7_SetRenderState(iface
, RenderStateType
, Value
);
2747 static HRESULT WINAPI
2748 IDirect3DDeviceImpl_7_SetRenderState_FPUPreserve(IDirect3DDevice7
*iface
,
2749 D3DRENDERSTATETYPE RenderStateType
,
2755 old_fpucw
= d3d_fpu_setup();
2756 hr
= IDirect3DDeviceImpl_7_SetRenderState(iface
, RenderStateType
, Value
);
2757 set_fpu_control_word(old_fpucw
);
2762 static HRESULT WINAPI
2763 IDirect3DDeviceImpl_3_SetRenderState(IDirect3DDevice3
*iface
,
2764 D3DRENDERSTATETYPE RenderStateType
,
2767 /* Note about D3DRENDERSTATE_TEXTUREMAPBLEND implementation: most of values
2768 for this state can be directly mapped to texture stage colorop and alphaop, but
2769 D3DTBLEND_MODULATE is tricky: it uses alpha from texture when available and alpha
2770 from diffuse otherwise. So changing the texture must be monitored in SetTexture to modify
2771 alphaarg when needed.
2773 Aliens vs Predator 1 depends on accurate D3DTBLEND_MODULATE emulation
2775 Legacy texture blending (TEXTUREMAPBLEND) and texture stage states: directx6 docs state that
2776 TEXTUREMAPBLEND is deprecated, yet can still be used. Games must not use both or results
2777 are undefined. D3DTBLEND_MODULATE mode in particular is dependent on texture pixel format and
2778 requires fixup of stage 0 texture states when texture changes, but this fixup can interfere
2779 with games not using this deprecated state. So a flag 'legacyTextureBlending' has to be kept
2780 in device - TRUE if the app is using TEXTUREMAPBLEND.
2782 Tests show that setting TEXTUREMAPBLEND on native doesn't seem to change values returned by
2783 GetTextureStageState and vice versa. Not so on Wine, but it is 'undefined' anyway so, probably, ok,
2784 unless some broken game will be found that cares. */
2787 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
2788 TRACE("(%p)->(%08x,%d)\n", This
, RenderStateType
, Value
);
2790 EnterCriticalSection(&ddraw_cs
);
2792 switch(RenderStateType
)
2794 case D3DRENDERSTATE_TEXTUREHANDLE
:
2798 hr
= IWineD3DDevice_SetTexture(This
->wineD3DDevice
,
2804 if(Value
> This
->numHandles
)
2806 FIXME("Specified handle %d out of range\n", Value
);
2807 hr
= DDERR_INVALIDPARAMS
;
2810 if(This
->Handles
[Value
- 1].type
!= DDrawHandle_Texture
)
2812 FIXME("Handle %d isn't a texture handle\n", Value
);
2813 hr
= DDERR_INVALIDPARAMS
;
2818 IDirectDrawSurfaceImpl
*surf
= This
->Handles
[Value
- 1].ptr
;
2819 IDirect3DTexture2
*tex
= surf
? (IDirect3DTexture2
*)&surf
->IDirect3DTexture2_vtbl
: NULL
;
2820 hr
= IDirect3DDevice3_SetTexture(iface
, 0, tex
);
2825 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2827 This
->legacyTextureBlending
= TRUE
;
2829 switch ( (D3DTEXTUREBLEND
) Value
)
2831 case D3DTBLEND_MODULATE
:
2833 BOOL tex_alpha
= FALSE
;
2834 IWineD3DBaseTexture
*tex
= NULL
;
2835 WINED3DSURFACE_DESC desc
;
2837 DDPIXELFORMAT ddfmt
;
2839 hr
= IWineD3DDevice_GetTexture(This
->wineD3DDevice
,
2843 if(hr
== WINED3D_OK
&& tex
)
2845 memset(&desc
, 0, sizeof(desc
));
2847 hr
= IWineD3DTexture_GetLevelDesc((IWineD3DTexture
*) tex
, 0, &desc
);
2850 ddfmt
.dwSize
= sizeof(ddfmt
);
2851 PixelFormat_WineD3DtoDD(&ddfmt
, fmt
);
2852 if (ddfmt
.u5
.dwRGBAlphaBitMask
) tex_alpha
= TRUE
;
2855 IWineD3DBaseTexture_Release(tex
);
2858 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG1
);
2861 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG1
, WINED3DTA_TEXTURE
);
2865 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG1
, WINED3DTA_CURRENT
);
2868 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG1
, WINED3DTA_TEXTURE
);
2869 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG2
, WINED3DTA_CURRENT
);
2870 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLOROP
, WINED3DTOP_MODULATE
);
2876 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLOROP
, WINED3DTOP_ADD
);
2877 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG1
, WINED3DTA_TEXTURE
);
2878 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG2
, WINED3DTA_CURRENT
);
2879 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG2
);
2880 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG2
, WINED3DTA_CURRENT
);
2883 case D3DTBLEND_MODULATEALPHA
:
2884 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG1
, WINED3DTA_TEXTURE
);
2885 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG1
, WINED3DTA_TEXTURE
);
2886 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG2
, WINED3DTA_CURRENT
);
2887 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG2
, WINED3DTA_CURRENT
);
2888 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLOROP
, WINED3DTOP_MODULATE
);
2889 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_MODULATE
);
2892 case D3DTBLEND_COPY
:
2893 case D3DTBLEND_DECAL
:
2894 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG1
, WINED3DTA_TEXTURE
);
2895 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG1
, WINED3DTA_TEXTURE
);
2896 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLOROP
, WINED3DTOP_SELECTARG1
);
2897 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG1
);
2900 case D3DTBLEND_DECALALPHA
:
2901 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLOROP
, WINED3DTOP_BLENDTEXTUREALPHA
);
2902 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG1
, WINED3DTA_TEXTURE
);
2903 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG2
, WINED3DTA_CURRENT
);
2904 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG2
);
2905 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG2
, WINED3DTA_CURRENT
);
2909 ERR("Unhandled texture environment %d !\n",Value
);
2917 hr
= IDirect3DDevice7_SetRenderState((IDirect3DDevice7
*)This
, RenderStateType
, Value
);
2921 LeaveCriticalSection(&ddraw_cs
);
2926 static HRESULT WINAPI
2927 Thunk_IDirect3DDeviceImpl_2_SetRenderState(IDirect3DDevice2
*iface
,
2928 D3DRENDERSTATETYPE RenderStateType
,
2931 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
2932 TRACE_(ddraw_thunk
)("(%p)->(%08x,%d) thunking to IDirect3DDevice3 interface.\n", This
, RenderStateType
, Value
);
2933 return IDirect3DDevice3_SetRenderState((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, RenderStateType
, Value
);
2936 /*****************************************************************************
2937 * Direct3DDevice3::SetLightState
2939 * Sets a light state for Direct3DDevice3 and Direct3DDevice2. The
2940 * light states are forwarded to Direct3DDevice7 render states
2945 * LightStateType: The light state to change
2946 * Value: The value to assign to that light state
2950 * DDERR_INVALIDPARAMS if the parameters were incorrect
2951 * Also check IDirect3DDevice7::SetRenderState
2953 *****************************************************************************/
2954 static HRESULT WINAPI
2955 IDirect3DDeviceImpl_3_SetLightState(IDirect3DDevice3
*iface
,
2956 D3DLIGHTSTATETYPE LightStateType
,
2959 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
2962 TRACE("(%p)->(%08x,%08x)\n", This
, LightStateType
, Value
);
2964 if (!LightStateType
&& (LightStateType
> D3DLIGHTSTATE_COLORVERTEX
))
2966 TRACE("Unexpected Light State Type\n");
2967 return DDERR_INVALIDPARAMS
;
2970 EnterCriticalSection(&ddraw_cs
);
2971 if (LightStateType
== D3DLIGHTSTATE_MATERIAL
/* 1 */)
2973 IDirect3DMaterialImpl
*mat
;
2975 if(Value
== 0) mat
= NULL
;
2976 else if(Value
> This
->numHandles
)
2978 ERR("Material handle out of range(%d)\n", Value
);
2979 LeaveCriticalSection(&ddraw_cs
);
2980 return DDERR_INVALIDPARAMS
;
2982 else if(This
->Handles
[Value
- 1].type
!= DDrawHandle_Material
)
2984 ERR("Invalid handle %d\n", Value
);
2985 LeaveCriticalSection(&ddraw_cs
);
2986 return DDERR_INVALIDPARAMS
;
2990 mat
= This
->Handles
[Value
- 1].ptr
;
2995 TRACE(" activating material %p.\n", mat
);
3000 FIXME(" D3DLIGHTSTATE_MATERIAL called with NULL material !!!\n");
3002 This
->material
= Value
;
3004 else if (LightStateType
== D3DLIGHTSTATE_COLORMODEL
/* 3 */)
3009 ERR("DDCOLOR_MONO should not happen!\n");
3012 /* We are already in this mode */
3013 TRACE("Setting color model to RGB (no-op).\n");
3016 ERR("Unknown color model!\n");
3017 LeaveCriticalSection(&ddraw_cs
);
3018 return DDERR_INVALIDPARAMS
;
3023 D3DRENDERSTATETYPE rs
;
3024 switch (LightStateType
)
3026 case D3DLIGHTSTATE_AMBIENT
: /* 2 */
3027 rs
= D3DRENDERSTATE_AMBIENT
;
3029 case D3DLIGHTSTATE_FOGMODE
: /* 4 */
3030 rs
= D3DRENDERSTATE_FOGVERTEXMODE
;
3032 case D3DLIGHTSTATE_FOGSTART
: /* 5 */
3033 rs
= D3DRENDERSTATE_FOGSTART
;
3035 case D3DLIGHTSTATE_FOGEND
: /* 6 */
3036 rs
= D3DRENDERSTATE_FOGEND
;
3038 case D3DLIGHTSTATE_FOGDENSITY
: /* 7 */
3039 rs
= D3DRENDERSTATE_FOGDENSITY
;
3041 case D3DLIGHTSTATE_COLORVERTEX
: /* 8 */
3042 rs
= D3DRENDERSTATE_COLORVERTEX
;
3045 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType
);
3046 LeaveCriticalSection(&ddraw_cs
);
3047 return DDERR_INVALIDPARAMS
;
3050 hr
= IDirect3DDevice7_SetRenderState((IDirect3DDevice7
*)This
, rs
, Value
);
3051 LeaveCriticalSection(&ddraw_cs
);
3055 LeaveCriticalSection(&ddraw_cs
);
3059 static HRESULT WINAPI
3060 Thunk_IDirect3DDeviceImpl_2_SetLightState(IDirect3DDevice2
*iface
,
3061 D3DLIGHTSTATETYPE LightStateType
,
3064 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
3065 TRACE_(ddraw_thunk
)("(%p)->(%08x,%08x) thunking to IDirect3DDevice3 interface.\n", This
, LightStateType
, Value
);
3066 return IDirect3DDevice3_SetLightState((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, LightStateType
, Value
);
3069 /*****************************************************************************
3070 * IDirect3DDevice3::GetLightState
3072 * Returns the current setting of a light state. The state is read from
3073 * the Direct3DDevice7 render state.
3078 * LightStateType: The light state to return
3079 * Value: The address to store the light state setting at
3083 * DDDERR_INVALIDPARAMS if the parameters were incorrect
3084 * Also see IDirect3DDevice7::GetRenderState
3086 *****************************************************************************/
3087 static HRESULT WINAPI
3088 IDirect3DDeviceImpl_3_GetLightState(IDirect3DDevice3
*iface
,
3089 D3DLIGHTSTATETYPE LightStateType
,
3092 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
3095 TRACE("(%p)->(%08x,%p)\n", This
, LightStateType
, Value
);
3097 if (!LightStateType
&& (LightStateType
> D3DLIGHTSTATE_COLORVERTEX
))
3099 TRACE("Unexpected Light State Type\n");
3100 return DDERR_INVALIDPARAMS
;
3104 return DDERR_INVALIDPARAMS
;
3106 EnterCriticalSection(&ddraw_cs
);
3107 if (LightStateType
== D3DLIGHTSTATE_MATERIAL
/* 1 */)
3109 *Value
= This
->material
;
3111 else if (LightStateType
== D3DLIGHTSTATE_COLORMODEL
/* 3 */)
3113 *Value
= D3DCOLOR_RGB
;
3117 D3DRENDERSTATETYPE rs
;
3118 switch (LightStateType
)
3120 case D3DLIGHTSTATE_AMBIENT
: /* 2 */
3121 rs
= D3DRENDERSTATE_AMBIENT
;
3123 case D3DLIGHTSTATE_FOGMODE
: /* 4 */
3124 rs
= D3DRENDERSTATE_FOGVERTEXMODE
;
3126 case D3DLIGHTSTATE_FOGSTART
: /* 5 */
3127 rs
= D3DRENDERSTATE_FOGSTART
;
3129 case D3DLIGHTSTATE_FOGEND
: /* 6 */
3130 rs
= D3DRENDERSTATE_FOGEND
;
3132 case D3DLIGHTSTATE_FOGDENSITY
: /* 7 */
3133 rs
= D3DRENDERSTATE_FOGDENSITY
;
3135 case D3DLIGHTSTATE_COLORVERTEX
: /* 8 */
3136 rs
= D3DRENDERSTATE_COLORVERTEX
;
3139 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType
);
3140 LeaveCriticalSection(&ddraw_cs
);
3141 return DDERR_INVALIDPARAMS
;
3144 hr
= IDirect3DDevice7_GetRenderState((IDirect3DDevice7
*)This
, rs
, Value
);
3145 LeaveCriticalSection(&ddraw_cs
);
3149 LeaveCriticalSection(&ddraw_cs
);
3153 static HRESULT WINAPI
3154 Thunk_IDirect3DDeviceImpl_2_GetLightState(IDirect3DDevice2
*iface
,
3155 D3DLIGHTSTATETYPE LightStateType
,
3158 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
3159 TRACE_(ddraw_thunk
)("(%p)->(%08x,%p) thunking to IDirect3DDevice3 interface.\n", This
, LightStateType
, Value
);
3160 return IDirect3DDevice3_GetLightState((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, LightStateType
, Value
);
3163 /*****************************************************************************
3164 * IDirect3DDevice7::SetTransform
3166 * Assigns a D3DMATRIX to a transform type. The transform types are defined
3167 * in include/d3dtypes.h.
3168 * The D3DTRANSFORMSTATE_WORLD (=1) is translated to D3DTS_WORLDMATRIX(0)
3169 * (=255) for wined3d, because the 1 transform state was removed in d3d8
3170 * and WineD3D already understands the replacement D3DTS_WORLDMATRIX(0)
3172 * Version 2, 3 and 7
3175 * TransformStateType: transform state to set
3176 * Matrix: Matrix to assign to the state
3180 * DDERR_INVALIDPARAMS if Matrix == NULL
3181 * For details see IWineD3DDevice::SetTransform
3183 *****************************************************************************/
3185 IDirect3DDeviceImpl_7_SetTransform(IDirect3DDevice7
*iface
,
3186 D3DTRANSFORMSTATETYPE TransformStateType
,
3189 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
3190 D3DTRANSFORMSTATETYPE type
;
3192 TRACE("(%p)->(%08x,%p): Relay\n", This
, TransformStateType
, Matrix
);
3194 switch(TransformStateType
)
3196 case D3DTRANSFORMSTATE_WORLD
: type
= WINED3DTS_WORLDMATRIX(0); break;
3197 case D3DTRANSFORMSTATE_WORLD1
: type
= WINED3DTS_WORLDMATRIX(1); break;
3198 case D3DTRANSFORMSTATE_WORLD2
: type
= WINED3DTS_WORLDMATRIX(2); break;
3199 case D3DTRANSFORMSTATE_WORLD3
: type
= WINED3DTS_WORLDMATRIX(3); break;
3200 default: type
= TransformStateType
;
3204 return DDERR_INVALIDPARAMS
;
3206 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3207 EnterCriticalSection(&ddraw_cs
);
3208 hr
= IWineD3DDevice_SetTransform(This
->wineD3DDevice
,
3210 (WINED3DMATRIX
*) Matrix
);
3211 LeaveCriticalSection(&ddraw_cs
);
3215 static HRESULT WINAPI
3216 IDirect3DDeviceImpl_7_SetTransform_FPUSetup(IDirect3DDevice7
*iface
,
3217 D3DTRANSFORMSTATETYPE TransformStateType
,
3220 return IDirect3DDeviceImpl_7_SetTransform(iface
, TransformStateType
, Matrix
);
3223 static HRESULT WINAPI
3224 IDirect3DDeviceImpl_7_SetTransform_FPUPreserve(IDirect3DDevice7
*iface
,
3225 D3DTRANSFORMSTATETYPE TransformStateType
,
3231 old_fpucw
= d3d_fpu_setup();
3232 hr
= IDirect3DDeviceImpl_7_SetTransform(iface
, TransformStateType
, Matrix
);
3233 set_fpu_control_word(old_fpucw
);
3238 static HRESULT WINAPI
3239 Thunk_IDirect3DDeviceImpl_3_SetTransform(IDirect3DDevice3
*iface
,
3240 D3DTRANSFORMSTATETYPE TransformStateType
,
3241 D3DMATRIX
*D3DMatrix
)
3243 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
3244 TRACE_(ddraw_thunk
)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This
, TransformStateType
, D3DMatrix
);
3245 return IDirect3DDevice7_SetTransform((IDirect3DDevice7
*)This
, TransformStateType
, D3DMatrix
);
3248 static HRESULT WINAPI
3249 Thunk_IDirect3DDeviceImpl_2_SetTransform(IDirect3DDevice2
*iface
,
3250 D3DTRANSFORMSTATETYPE TransformStateType
,
3251 D3DMATRIX
*D3DMatrix
)
3253 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
3254 TRACE_(ddraw_thunk
)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This
, TransformStateType
, D3DMatrix
);
3255 return IDirect3DDevice7_SetTransform((IDirect3DDevice7
*)This
, TransformStateType
, D3DMatrix
);
3258 /*****************************************************************************
3259 * IDirect3DDevice7::GetTransform
3261 * Returns the matrix assigned to a transform state
3262 * D3DTRANSFORMSTATE_WORLD is translated to D3DTS_WORLDMATRIX(0), see
3266 * TransformStateType: State to read the matrix from
3267 * Matrix: Address to store the matrix at
3271 * DDERR_INVALIDPARAMS if Matrix == NULL
3272 * For details, see IWineD3DDevice::GetTransform
3274 *****************************************************************************/
3276 IDirect3DDeviceImpl_7_GetTransform(IDirect3DDevice7
*iface
,
3277 D3DTRANSFORMSTATETYPE TransformStateType
,
3280 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
3281 D3DTRANSFORMSTATETYPE type
;
3283 TRACE("(%p)->(%08x,%p): Relay\n", This
, TransformStateType
, Matrix
);
3285 switch(TransformStateType
)
3287 case D3DTRANSFORMSTATE_WORLD
: type
= WINED3DTS_WORLDMATRIX(0); break;
3288 case D3DTRANSFORMSTATE_WORLD1
: type
= WINED3DTS_WORLDMATRIX(1); break;
3289 case D3DTRANSFORMSTATE_WORLD2
: type
= WINED3DTS_WORLDMATRIX(2); break;
3290 case D3DTRANSFORMSTATE_WORLD3
: type
= WINED3DTS_WORLDMATRIX(3); break;
3291 default: type
= TransformStateType
;
3295 return DDERR_INVALIDPARAMS
;
3297 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3298 EnterCriticalSection(&ddraw_cs
);
3299 hr
= IWineD3DDevice_GetTransform(This
->wineD3DDevice
, type
, (WINED3DMATRIX
*) Matrix
);
3300 LeaveCriticalSection(&ddraw_cs
);
3304 static HRESULT WINAPI
3305 IDirect3DDeviceImpl_7_GetTransform_FPUSetup(IDirect3DDevice7
*iface
,
3306 D3DTRANSFORMSTATETYPE TransformStateType
,
3309 return IDirect3DDeviceImpl_7_GetTransform(iface
, TransformStateType
, Matrix
);
3312 static HRESULT WINAPI
3313 IDirect3DDeviceImpl_7_GetTransform_FPUPreserve(IDirect3DDevice7
*iface
,
3314 D3DTRANSFORMSTATETYPE TransformStateType
,
3320 old_fpucw
= d3d_fpu_setup();
3321 hr
= IDirect3DDeviceImpl_7_GetTransform(iface
, TransformStateType
, Matrix
);
3322 set_fpu_control_word(old_fpucw
);
3327 static HRESULT WINAPI
3328 Thunk_IDirect3DDeviceImpl_3_GetTransform(IDirect3DDevice3
*iface
,
3329 D3DTRANSFORMSTATETYPE TransformStateType
,
3330 D3DMATRIX
*D3DMatrix
)
3332 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
3333 TRACE_(ddraw_thunk
)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This
, TransformStateType
, D3DMatrix
);
3334 return IDirect3DDevice7_GetTransform((IDirect3DDevice7
*)This
, TransformStateType
, D3DMatrix
);
3337 static HRESULT WINAPI
3338 Thunk_IDirect3DDeviceImpl_2_GetTransform(IDirect3DDevice2
*iface
,
3339 D3DTRANSFORMSTATETYPE TransformStateType
,
3340 D3DMATRIX
*D3DMatrix
)
3342 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
3343 TRACE_(ddraw_thunk
)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This
, TransformStateType
, D3DMatrix
);
3344 return IDirect3DDevice7_GetTransform((IDirect3DDevice7
*)This
, TransformStateType
, D3DMatrix
);
3347 /*****************************************************************************
3348 * IDirect3DDevice7::MultiplyTransform
3350 * Multiplies the already-set transform matrix of a transform state
3351 * with another matrix. For the world matrix, see SetTransform
3353 * Version 2, 3 and 7
3356 * TransformStateType: Transform state to multiply
3357 * D3DMatrix Matrix to multiply with.
3361 * DDERR_INVALIDPARAMS if D3DMatrix is NULL
3362 * For details, see IWineD3DDevice::MultiplyTransform
3364 *****************************************************************************/
3366 IDirect3DDeviceImpl_7_MultiplyTransform(IDirect3DDevice7
*iface
,
3367 D3DTRANSFORMSTATETYPE TransformStateType
,
3368 D3DMATRIX
*D3DMatrix
)
3370 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
3372 D3DTRANSFORMSTATETYPE type
;
3373 TRACE("(%p)->(%08x,%p): Relay\n", This
, TransformStateType
, D3DMatrix
);
3375 switch(TransformStateType
)
3377 case D3DTRANSFORMSTATE_WORLD
: type
= WINED3DTS_WORLDMATRIX(0); break;
3378 case D3DTRANSFORMSTATE_WORLD1
: type
= WINED3DTS_WORLDMATRIX(1); break;
3379 case D3DTRANSFORMSTATE_WORLD2
: type
= WINED3DTS_WORLDMATRIX(2); break;
3380 case D3DTRANSFORMSTATE_WORLD3
: type
= WINED3DTS_WORLDMATRIX(3); break;
3381 default: type
= TransformStateType
;
3384 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3385 EnterCriticalSection(&ddraw_cs
);
3386 hr
= IWineD3DDevice_MultiplyTransform(This
->wineD3DDevice
,
3388 (WINED3DMATRIX
*) D3DMatrix
);
3389 LeaveCriticalSection(&ddraw_cs
);
3393 static HRESULT WINAPI
3394 IDirect3DDeviceImpl_7_MultiplyTransform_FPUSetup(IDirect3DDevice7
*iface
,
3395 D3DTRANSFORMSTATETYPE TransformStateType
,
3396 D3DMATRIX
*D3DMatrix
)
3398 return IDirect3DDeviceImpl_7_MultiplyTransform(iface
, TransformStateType
, D3DMatrix
);
3401 static HRESULT WINAPI
3402 IDirect3DDeviceImpl_7_MultiplyTransform_FPUPreserve(IDirect3DDevice7
*iface
,
3403 D3DTRANSFORMSTATETYPE TransformStateType
,
3404 D3DMATRIX
*D3DMatrix
)
3409 old_fpucw
= d3d_fpu_setup();
3410 hr
= IDirect3DDeviceImpl_7_MultiplyTransform(iface
, TransformStateType
, D3DMatrix
);
3411 set_fpu_control_word(old_fpucw
);
3416 static HRESULT WINAPI
3417 Thunk_IDirect3DDeviceImpl_3_MultiplyTransform(IDirect3DDevice3
*iface
,
3418 D3DTRANSFORMSTATETYPE TransformStateType
,
3419 D3DMATRIX
*D3DMatrix
)
3421 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
3422 TRACE_(ddraw_thunk
)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This
, TransformStateType
, D3DMatrix
);
3423 return IDirect3DDevice7_MultiplyTransform((IDirect3DDevice7
*)This
, TransformStateType
, D3DMatrix
);
3426 static HRESULT WINAPI
3427 Thunk_IDirect3DDeviceImpl_2_MultiplyTransform(IDirect3DDevice2
*iface
,
3428 D3DTRANSFORMSTATETYPE TransformStateType
,
3429 D3DMATRIX
*D3DMatrix
)
3431 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
3432 TRACE_(ddraw_thunk
)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This
, TransformStateType
, D3DMatrix
);
3433 return IDirect3DDevice7_MultiplyTransform((IDirect3DDevice7
*)This
, TransformStateType
, D3DMatrix
);
3436 /*****************************************************************************
3437 * IDirect3DDevice7::DrawPrimitive
3439 * Draws primitives based on vertices in an application-provided pointer
3441 * Version 2, 3 and 7. The IDirect3DDevice2 thunk converts the fixed vertex type into
3442 * an FVF format for D3D7
3445 * PrimitiveType: The type of the primitives to draw
3446 * Vertex type: Flexible vertex format vertex description
3447 * Vertices: Pointer to the vertex array
3448 * VertexCount: The number of vertices to draw
3449 * Flags: As usual a few flags
3453 * DDERR_INVALIDPARAMS if Vertices is NULL
3454 * For details, see IWineD3DDevice::DrawPrimitiveUP
3456 *****************************************************************************/
3458 IDirect3DDeviceImpl_7_DrawPrimitive(IDirect3DDevice7
*iface
,
3459 D3DPRIMITIVETYPE PrimitiveType
,
3465 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
3466 UINT PrimitiveCount
, stride
;
3468 TRACE("(%p)->(%08x,%08x,%p,%08x,%08x): Relay!\n", This
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3471 return DDERR_INVALIDPARAMS
;
3473 /* Get the vertex count */
3474 switch(PrimitiveType
)
3476 case D3DPT_POINTLIST
:
3477 PrimitiveCount
= VertexCount
;
3480 case D3DPT_LINELIST
:
3481 PrimitiveCount
= VertexCount
/ 2;
3484 case D3DPT_LINESTRIP
:
3485 PrimitiveCount
= VertexCount
- 1;
3488 case D3DPT_TRIANGLELIST
:
3489 PrimitiveCount
= VertexCount
/ 3;
3492 case D3DPT_TRIANGLESTRIP
:
3493 PrimitiveCount
= VertexCount
- 2;
3496 case D3DPT_TRIANGLEFAN
:
3497 PrimitiveCount
= VertexCount
- 2;
3501 return DDERR_INVALIDPARAMS
;
3504 /* Get the stride */
3505 stride
= get_flexible_vertex_size(VertexType
);
3508 EnterCriticalSection(&ddraw_cs
);
3509 hr
= IWineD3DDevice_SetVertexDeclaration(This
->wineD3DDevice
,
3510 IDirectDrawImpl_FindDecl(This
->ddraw
, VertexType
));
3513 LeaveCriticalSection(&ddraw_cs
);
3517 /* This method translates to the user pointer draw of WineD3D */
3518 hr
= IWineD3DDevice_DrawPrimitiveUP(This
->wineD3DDevice
,
3523 LeaveCriticalSection(&ddraw_cs
);
3527 static HRESULT WINAPI
3528 IDirect3DDeviceImpl_7_DrawPrimitive_FPUSetup(IDirect3DDevice7
*iface
,
3529 D3DPRIMITIVETYPE PrimitiveType
,
3535 return IDirect3DDeviceImpl_7_DrawPrimitive(iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3538 static HRESULT WINAPI
3539 IDirect3DDeviceImpl_7_DrawPrimitive_FPUPreserve(IDirect3DDevice7
*iface
,
3540 D3DPRIMITIVETYPE PrimitiveType
,
3549 old_fpucw
= d3d_fpu_setup();
3550 hr
= IDirect3DDeviceImpl_7_DrawPrimitive(iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3551 set_fpu_control_word(old_fpucw
);
3556 static HRESULT WINAPI
3557 Thunk_IDirect3DDeviceImpl_3_DrawPrimitive(IDirect3DDevice3
*iface
,
3558 D3DPRIMITIVETYPE PrimitiveType
,
3564 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
3565 TRACE_(ddraw_thunk
)("(%p)->(%08x,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3566 return IDirect3DDevice7_DrawPrimitive((IDirect3DDevice7
*)This
,
3567 PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3570 static HRESULT WINAPI
3571 Thunk_IDirect3DDeviceImpl_2_DrawPrimitive(IDirect3DDevice2
*iface
,
3572 D3DPRIMITIVETYPE PrimitiveType
,
3573 D3DVERTEXTYPE VertexType
,
3578 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
3580 TRACE_(ddraw_thunk
)("(%p)->(%08x,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3584 case D3DVT_VERTEX
: FVF
= D3DFVF_VERTEX
; break;
3585 case D3DVT_LVERTEX
: FVF
= D3DFVF_LVERTEX
; break;
3586 case D3DVT_TLVERTEX
: FVF
= D3DFVF_TLVERTEX
; break;
3588 ERR("Unexpected vertex type %d\n", VertexType
);
3589 return DDERR_INVALIDPARAMS
; /* Should never happen */
3592 return IDirect3DDevice7_DrawPrimitive((IDirect3DDevice7
*)This
, PrimitiveType
, FVF
, Vertices
, VertexCount
, Flags
);
3595 /*****************************************************************************
3596 * IDirect3DDevice7::DrawIndexedPrimitive
3598 * Draws vertices from an application-provided pointer, based on the index
3599 * numbers in a WORD array.
3601 * Version 2, 3 and 7. The version 7 thunk translates the vertex type into
3602 * an FVF format for D3D7
3605 * PrimitiveType: The primitive type to draw
3606 * VertexType: The FVF vertex description
3607 * Vertices: Pointer to the vertex array
3609 * Indices: Pointer to the index array
3610 * IndexCount: Number of indices = Number of vertices to draw
3611 * Flags: As usual, some flags
3615 * DDERR_INVALIDPARAMS if Vertices or Indices is NULL
3616 * For details, see IWineD3DDevice::DrawIndexedPrimitiveUP
3618 *****************************************************************************/
3620 IDirect3DDeviceImpl_7_DrawIndexedPrimitive(IDirect3DDevice7
*iface
,
3621 D3DPRIMITIVETYPE PrimitiveType
,
3629 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
3630 UINT PrimitiveCount
= 0;
3632 TRACE("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x): Relay!\n", This
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3634 /* Get the primitive number */
3635 switch(PrimitiveType
)
3637 case D3DPT_POINTLIST
:
3638 PrimitiveCount
= IndexCount
;
3641 case D3DPT_LINELIST
:
3642 PrimitiveCount
= IndexCount
/ 2;
3645 case D3DPT_LINESTRIP
:
3646 PrimitiveCount
= IndexCount
- 1;
3649 case D3DPT_TRIANGLELIST
:
3650 PrimitiveCount
= IndexCount
/ 3;
3653 case D3DPT_TRIANGLESTRIP
:
3654 PrimitiveCount
= IndexCount
- 2;
3657 case D3DPT_TRIANGLEFAN
:
3658 PrimitiveCount
= IndexCount
- 2;
3662 return DDERR_INVALIDPARAMS
;
3665 /* Set the D3DDevice's FVF */
3666 EnterCriticalSection(&ddraw_cs
);
3667 hr
= IWineD3DDevice_SetVertexDeclaration(This
->wineD3DDevice
,
3668 IDirectDrawImpl_FindDecl(This
->ddraw
, VertexType
));
3671 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This
, hr
);
3672 LeaveCriticalSection(&ddraw_cs
);
3676 hr
= IWineD3DDevice_DrawIndexedPrimitiveUP(This
->wineD3DDevice
, PrimitiveType
, 0 /* MinVertexIndex */,
3677 VertexCount
/* UINT NumVertexIndex */, PrimitiveCount
, Indices
, WINED3DFMT_R16_UINT
, Vertices
,
3678 get_flexible_vertex_size(VertexType
));
3679 LeaveCriticalSection(&ddraw_cs
);
3683 static HRESULT WINAPI
3684 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUSetup(IDirect3DDevice7
*iface
,
3685 D3DPRIMITIVETYPE PrimitiveType
,
3693 return IDirect3DDeviceImpl_7_DrawIndexedPrimitive(iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3696 static HRESULT WINAPI
3697 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUPreserve(IDirect3DDevice7
*iface
,
3698 D3DPRIMITIVETYPE PrimitiveType
,
3709 old_fpucw
= d3d_fpu_setup();
3710 hr
= IDirect3DDeviceImpl_7_DrawIndexedPrimitive(iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3711 set_fpu_control_word(old_fpucw
);
3716 static HRESULT WINAPI
3717 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive(IDirect3DDevice3
*iface
,
3718 D3DPRIMITIVETYPE PrimitiveType
,
3726 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
3727 TRACE_(ddraw_thunk
)("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3728 return IDirect3DDevice7_DrawIndexedPrimitive((IDirect3DDevice7
*)This
,
3729 PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3732 static HRESULT WINAPI
3733 Thunk_IDirect3DDeviceImpl_2_DrawIndexedPrimitive(IDirect3DDevice2
*iface
,
3734 D3DPRIMITIVETYPE PrimitiveType
,
3735 D3DVERTEXTYPE VertexType
,
3743 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
3744 TRACE_(ddraw_thunk
)("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3748 case D3DVT_VERTEX
: FVF
= D3DFVF_VERTEX
; break;
3749 case D3DVT_LVERTEX
: FVF
= D3DFVF_LVERTEX
; break;
3750 case D3DVT_TLVERTEX
: FVF
= D3DFVF_TLVERTEX
; break;
3752 ERR("Unexpected vertex type %d\n", VertexType
);
3753 return DDERR_INVALIDPARAMS
; /* Should never happen */
3756 return IDirect3DDevice7_DrawIndexedPrimitive((IDirect3DDevice7
*)This
,
3757 PrimitiveType
, FVF
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3760 /*****************************************************************************
3761 * IDirect3DDevice7::SetClipStatus
3763 * Sets the clip status. This defines things as clipping conditions and
3764 * the extents of the clipping region.
3766 * Version 2, 3 and 7
3772 * D3D_OK because it's a stub
3773 * (DDERR_INVALIDPARAMS if ClipStatus == NULL)
3775 *****************************************************************************/
3776 static HRESULT WINAPI
3777 IDirect3DDeviceImpl_7_SetClipStatus(IDirect3DDevice7
*iface
,
3778 D3DCLIPSTATUS
*ClipStatus
)
3780 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
3781 FIXME("(%p)->(%p): Stub!\n", This
, ClipStatus
);
3783 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them
3784 * Perhaps this needs a new data type and an additional IWineD3DDevice method
3786 /* return IWineD3DDevice_SetClipStatus(This->wineD3DDevice, ClipStatus);*/
3790 static HRESULT WINAPI
3791 Thunk_IDirect3DDeviceImpl_3_SetClipStatus(IDirect3DDevice3
*iface
,
3792 D3DCLIPSTATUS
*ClipStatus
)
3794 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
3795 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This
, ClipStatus
);
3796 return IDirect3DDevice7_SetClipStatus((IDirect3DDevice7
*)This
, ClipStatus
);
3799 static HRESULT WINAPI
3800 Thunk_IDirect3DDeviceImpl_2_SetClipStatus(IDirect3DDevice2
*iface
,
3801 D3DCLIPSTATUS
*ClipStatus
)
3803 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
3804 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This
, ClipStatus
);
3805 return IDirect3DDevice7_SetClipStatus((IDirect3DDevice7
*)This
, ClipStatus
);
3808 /*****************************************************************************
3809 * IDirect3DDevice7::GetClipStatus
3811 * Returns the clip status
3814 * ClipStatus: Address to write the clip status to
3817 * D3D_OK because it's a stub
3819 *****************************************************************************/
3820 static HRESULT WINAPI
3821 IDirect3DDeviceImpl_7_GetClipStatus(IDirect3DDevice7
*iface
,
3822 D3DCLIPSTATUS
*ClipStatus
)
3824 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
3825 FIXME("(%p)->(%p): Stub!\n", This
, ClipStatus
);
3827 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them */
3828 /* return IWineD3DDevice_GetClipStatus(This->wineD3DDevice, ClipStatus);*/
3832 static HRESULT WINAPI
3833 Thunk_IDirect3DDeviceImpl_3_GetClipStatus(IDirect3DDevice3
*iface
,
3834 D3DCLIPSTATUS
*ClipStatus
)
3836 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
3837 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This
, ClipStatus
);
3838 return IDirect3DDevice7_GetClipStatus((IDirect3DDevice7
*)This
, ClipStatus
);
3841 static HRESULT WINAPI
3842 Thunk_IDirect3DDeviceImpl_2_GetClipStatus(IDirect3DDevice2
*iface
,
3843 D3DCLIPSTATUS
*ClipStatus
)
3845 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
3846 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This
, ClipStatus
);
3847 return IDirect3DDevice7_GetClipStatus((IDirect3DDevice7
*)This
, ClipStatus
);
3850 /*****************************************************************************
3851 * IDirect3DDevice::DrawPrimitiveStrided
3853 * Draws vertices described by a D3DDRAWPRIMITIVESTRIDEDDATA structure.
3858 * PrimitiveType: The primitive type to draw
3859 * VertexType: The FVF description of the vertices to draw (for the stride??)
3860 * D3DDrawPrimStrideData: A D3DDRAWPRIMITIVESTRIDEDDATA structure describing
3861 * the vertex data locations
3862 * VertexCount: The number of vertices to draw
3866 * D3D_OK, because it's a stub
3867 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
3868 * (For details, see IWineD3DDevice::DrawPrimitiveStrided)
3870 *****************************************************************************/
3872 IDirect3DDeviceImpl_7_DrawPrimitiveStrided(IDirect3DDevice7
*iface
,
3873 D3DPRIMITIVETYPE PrimitiveType
,
3875 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
3879 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
3880 WineDirect3DVertexStridedData WineD3DStrided
;
3882 UINT PrimitiveCount
;
3885 TRACE("(%p)->(%08x,%08x,%p,%08x,%08x): stub!\n", This
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
3887 memset(&WineD3DStrided
, 0, sizeof(WineD3DStrided
));
3888 /* Get the strided data right. the wined3d structure is a bit bigger
3889 * Watch out: The contents of the strided data are determined by the fvf,
3890 * not by the members set in D3DDrawPrimStrideData. So it's valid
3891 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
3892 * not set in the fvf.
3894 if(VertexType
& D3DFVF_POSITION_MASK
)
3896 WineD3DStrided
.u
.s
.position
.lpData
= D3DDrawPrimStrideData
->position
.lpvData
;
3897 WineD3DStrided
.u
.s
.position
.dwStride
= D3DDrawPrimStrideData
->position
.dwStride
;
3898 WineD3DStrided
.u
.s
.position
.dwType
= WINED3DDECLTYPE_FLOAT3
;
3899 if (VertexType
& D3DFVF_XYZRHW
)
3901 WineD3DStrided
.u
.s
.position
.dwType
= WINED3DDECLTYPE_FLOAT4
;
3902 WineD3DStrided
.position_transformed
= TRUE
;
3904 WineD3DStrided
.position_transformed
= FALSE
;
3907 if(VertexType
& D3DFVF_NORMAL
)
3909 WineD3DStrided
.u
.s
.normal
.lpData
= D3DDrawPrimStrideData
->normal
.lpvData
;
3910 WineD3DStrided
.u
.s
.normal
.dwStride
= D3DDrawPrimStrideData
->normal
.dwStride
;
3911 WineD3DStrided
.u
.s
.normal
.dwType
= WINED3DDECLTYPE_FLOAT3
;
3914 if(VertexType
& D3DFVF_DIFFUSE
)
3916 WineD3DStrided
.u
.s
.diffuse
.lpData
= D3DDrawPrimStrideData
->diffuse
.lpvData
;
3917 WineD3DStrided
.u
.s
.diffuse
.dwStride
= D3DDrawPrimStrideData
->diffuse
.dwStride
;
3918 WineD3DStrided
.u
.s
.diffuse
.dwType
= WINED3DDECLTYPE_D3DCOLOR
;
3921 if(VertexType
& D3DFVF_SPECULAR
)
3923 WineD3DStrided
.u
.s
.specular
.lpData
= D3DDrawPrimStrideData
->specular
.lpvData
;
3924 WineD3DStrided
.u
.s
.specular
.dwStride
= D3DDrawPrimStrideData
->specular
.dwStride
;
3925 WineD3DStrided
.u
.s
.specular
.dwType
= WINED3DDECLTYPE_D3DCOLOR
;
3928 for( i
= 0; i
< GET_TEXCOUNT_FROM_FVF(VertexType
); i
++)
3930 WineD3DStrided
.u
.s
.texCoords
[i
].lpData
= D3DDrawPrimStrideData
->textureCoords
[i
].lpvData
;
3931 WineD3DStrided
.u
.s
.texCoords
[i
].dwStride
= D3DDrawPrimStrideData
->textureCoords
[i
].dwStride
;
3932 switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType
, i
))
3934 case 1: WineD3DStrided
.u
.s
.texCoords
[i
].dwType
= WINED3DDECLTYPE_FLOAT1
; break;
3935 case 2: WineD3DStrided
.u
.s
.texCoords
[i
].dwType
= WINED3DDECLTYPE_FLOAT2
; break;
3936 case 3: WineD3DStrided
.u
.s
.texCoords
[i
].dwType
= WINED3DDECLTYPE_FLOAT3
; break;
3937 case 4: WineD3DStrided
.u
.s
.texCoords
[i
].dwType
= WINED3DDECLTYPE_FLOAT4
; break;
3938 default: ERR("Unexpected texture coordinate size %d\n",
3939 GET_TEXCOORD_SIZE_FROM_FVF(VertexType
, i
));
3943 /* Get the primitive count */
3944 switch(PrimitiveType
)
3946 case D3DPT_POINTLIST
:
3947 PrimitiveCount
= VertexCount
;
3950 case D3DPT_LINELIST
:
3951 PrimitiveCount
= VertexCount
/ 2;
3954 case D3DPT_LINESTRIP
:
3955 PrimitiveCount
= VertexCount
- 1;
3958 case D3DPT_TRIANGLELIST
:
3959 PrimitiveCount
= VertexCount
/ 3;
3962 case D3DPT_TRIANGLESTRIP
:
3963 PrimitiveCount
= VertexCount
- 2;
3966 case D3DPT_TRIANGLEFAN
:
3967 PrimitiveCount
= VertexCount
- 2;
3970 default: return DDERR_INVALIDPARAMS
;
3973 /* WineD3D doesn't need the FVF here */
3974 EnterCriticalSection(&ddraw_cs
);
3975 hr
= IWineD3DDevice_DrawPrimitiveStrided(This
->wineD3DDevice
,
3979 LeaveCriticalSection(&ddraw_cs
);
3983 static HRESULT WINAPI
3984 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUSetup(IDirect3DDevice7
*iface
,
3985 D3DPRIMITIVETYPE PrimitiveType
,
3987 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
3991 return IDirect3DDeviceImpl_7_DrawPrimitiveStrided(iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
3994 static HRESULT WINAPI
3995 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUPreserve(IDirect3DDevice7
*iface
,
3996 D3DPRIMITIVETYPE PrimitiveType
,
3998 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
4005 old_fpucw
= d3d_fpu_setup();
4006 hr
= IDirect3DDeviceImpl_7_DrawPrimitiveStrided(iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
4007 set_fpu_control_word(old_fpucw
);
4012 static HRESULT WINAPI
4013 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided(IDirect3DDevice3
*iface
,
4014 D3DPRIMITIVETYPE PrimitiveType
,
4016 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
4020 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
4021 TRACE_(ddraw_thunk
)("(%p)->(%08x,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
4022 return IDirect3DDevice7_DrawPrimitiveStrided((IDirect3DDevice7
*)This
,
4023 PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
4026 /*****************************************************************************
4027 * IDirect3DDevice7::DrawIndexedPrimitiveStrided
4029 * Draws primitives specified by strided data locations based on indices
4037 * D3D_OK, because it's a stub
4038 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
4039 * (DDERR_INVALIDPARAMS if Indices is NULL)
4040 * (For more details, see IWineD3DDevice::DrawIndexedPrimitiveStrided)
4042 *****************************************************************************/
4044 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(IDirect3DDevice7
*iface
,
4045 D3DPRIMITIVETYPE PrimitiveType
,
4047 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
4053 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
4054 WineDirect3DVertexStridedData WineD3DStrided
;
4056 UINT PrimitiveCount
;
4059 TRACE("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x)\n", This
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4061 memset(&WineD3DStrided
, 0, sizeof(WineD3DStrided
));
4062 /* Get the strided data right. the wined3d structure is a bit bigger
4063 * Watch out: The contents of the strided data are determined by the fvf,
4064 * not by the members set in D3DDrawPrimStrideData. So it's valid
4065 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
4066 * not set in the fvf.
4068 if(VertexType
& D3DFVF_POSITION_MASK
)
4070 WineD3DStrided
.u
.s
.position
.lpData
= D3DDrawPrimStrideData
->position
.lpvData
;
4071 WineD3DStrided
.u
.s
.position
.dwStride
= D3DDrawPrimStrideData
->position
.dwStride
;
4072 WineD3DStrided
.u
.s
.position
.dwType
= WINED3DDECLTYPE_FLOAT3
;
4073 if (VertexType
& D3DFVF_XYZRHW
)
4075 WineD3DStrided
.u
.s
.position
.dwType
= WINED3DDECLTYPE_FLOAT4
;
4076 WineD3DStrided
.position_transformed
= TRUE
;
4078 WineD3DStrided
.position_transformed
= FALSE
;
4081 if(VertexType
& D3DFVF_NORMAL
)
4083 WineD3DStrided
.u
.s
.normal
.lpData
= D3DDrawPrimStrideData
->normal
.lpvData
;
4084 WineD3DStrided
.u
.s
.normal
.dwStride
= D3DDrawPrimStrideData
->normal
.dwStride
;
4085 WineD3DStrided
.u
.s
.normal
.dwType
= WINED3DDECLTYPE_FLOAT3
;
4088 if(VertexType
& D3DFVF_DIFFUSE
)
4090 WineD3DStrided
.u
.s
.diffuse
.lpData
= D3DDrawPrimStrideData
->diffuse
.lpvData
;
4091 WineD3DStrided
.u
.s
.diffuse
.dwStride
= D3DDrawPrimStrideData
->diffuse
.dwStride
;
4092 WineD3DStrided
.u
.s
.diffuse
.dwType
= WINED3DDECLTYPE_D3DCOLOR
;
4095 if(VertexType
& D3DFVF_SPECULAR
)
4097 WineD3DStrided
.u
.s
.specular
.lpData
= D3DDrawPrimStrideData
->specular
.lpvData
;
4098 WineD3DStrided
.u
.s
.specular
.dwStride
= D3DDrawPrimStrideData
->specular
.dwStride
;
4099 WineD3DStrided
.u
.s
.specular
.dwType
= WINED3DDECLTYPE_D3DCOLOR
;
4102 for( i
= 0; i
< GET_TEXCOUNT_FROM_FVF(VertexType
); i
++)
4104 WineD3DStrided
.u
.s
.texCoords
[i
].lpData
= D3DDrawPrimStrideData
->textureCoords
[i
].lpvData
;
4105 WineD3DStrided
.u
.s
.texCoords
[i
].dwStride
= D3DDrawPrimStrideData
->textureCoords
[i
].dwStride
;
4106 switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType
, i
))
4108 case 1: WineD3DStrided
.u
.s
.texCoords
[i
].dwType
= WINED3DDECLTYPE_FLOAT1
; break;
4109 case 2: WineD3DStrided
.u
.s
.texCoords
[i
].dwType
= WINED3DDECLTYPE_FLOAT2
; break;
4110 case 3: WineD3DStrided
.u
.s
.texCoords
[i
].dwType
= WINED3DDECLTYPE_FLOAT3
; break;
4111 case 4: WineD3DStrided
.u
.s
.texCoords
[i
].dwType
= WINED3DDECLTYPE_FLOAT4
; break;
4112 default: ERR("Unexpected texture coordinate size %d\n",
4113 GET_TEXCOORD_SIZE_FROM_FVF(VertexType
, i
));
4117 /* Get the primitive count */
4118 switch(PrimitiveType
)
4120 case D3DPT_POINTLIST
:
4121 PrimitiveCount
= IndexCount
;
4124 case D3DPT_LINELIST
:
4125 PrimitiveCount
= IndexCount
/ 2;
4128 case D3DPT_LINESTRIP
:
4129 PrimitiveCount
= IndexCount
- 1;
4132 case D3DPT_TRIANGLELIST
:
4133 PrimitiveCount
= IndexCount
/ 3;
4136 case D3DPT_TRIANGLESTRIP
:
4137 PrimitiveCount
= IndexCount
- 2;
4140 case D3DPT_TRIANGLEFAN
:
4141 PrimitiveCount
= IndexCount
- 2;
4144 default: return DDERR_INVALIDPARAMS
;
4147 /* WineD3D doesn't need the FVF here */
4148 EnterCriticalSection(&ddraw_cs
);
4149 hr
= IWineD3DDevice_DrawIndexedPrimitiveStrided(This
->wineD3DDevice
, PrimitiveType
,
4150 PrimitiveCount
, &WineD3DStrided
, VertexCount
, Indices
, WINED3DFMT_R16_UINT
);
4151 LeaveCriticalSection(&ddraw_cs
);
4155 static HRESULT WINAPI
4156 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUSetup(IDirect3DDevice7
*iface
,
4157 D3DPRIMITIVETYPE PrimitiveType
,
4159 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
4165 return IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4168 static HRESULT WINAPI
4169 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUPreserve(IDirect3DDevice7
*iface
,
4170 D3DPRIMITIVETYPE PrimitiveType
,
4172 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
4181 old_fpucw
= d3d_fpu_setup();
4182 hr
= IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4183 set_fpu_control_word(old_fpucw
);
4188 static HRESULT WINAPI
4189 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided(IDirect3DDevice3
*iface
,
4190 D3DPRIMITIVETYPE PrimitiveType
,
4192 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
4198 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
4199 TRACE_(ddraw_thunk
)("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4200 return IDirect3DDevice7_DrawIndexedPrimitiveStrided((IDirect3DDevice7
*)This
, PrimitiveType
,
4201 VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4204 /*****************************************************************************
4205 * IDirect3DDevice7::DrawPrimitiveVB
4207 * Draws primitives from a vertex buffer to the screen.
4212 * PrimitiveType: Type of primitive to be rendered.
4213 * D3DVertexBuf: Source Vertex Buffer
4214 * StartVertex: Index of the first vertex from the buffer to be rendered
4215 * NumVertices: Number of vertices to be rendered
4216 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4220 * DDERR_INVALIDPARAMS if D3DVertexBuf is NULL
4222 *****************************************************************************/
4224 IDirect3DDeviceImpl_7_DrawPrimitiveVB(IDirect3DDevice7
*iface
,
4225 D3DPRIMITIVETYPE PrimitiveType
,
4226 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4231 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
4232 IDirect3DVertexBufferImpl
*vb
= (IDirect3DVertexBufferImpl
*)D3DVertexBuf
;
4233 UINT PrimitiveCount
;
4236 WINED3DVERTEXBUFFER_DESC Desc
;
4238 TRACE("(%p)->(%08x,%p,%08x,%08x,%08x)\n", This
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4243 ERR("(%p) No Vertex buffer specified\n", This
);
4244 return DDERR_INVALIDPARAMS
;
4247 /* Get the primitive count */
4248 switch(PrimitiveType
)
4250 case D3DPT_POINTLIST
:
4251 PrimitiveCount
= NumVertices
;
4254 case D3DPT_LINELIST
:
4255 PrimitiveCount
= NumVertices
/ 2;
4258 case D3DPT_LINESTRIP
:
4259 PrimitiveCount
= NumVertices
- 1;
4262 case D3DPT_TRIANGLELIST
:
4263 PrimitiveCount
= NumVertices
/ 3;
4266 case D3DPT_TRIANGLESTRIP
:
4267 PrimitiveCount
= NumVertices
- 2;
4270 case D3DPT_TRIANGLEFAN
:
4271 PrimitiveCount
= NumVertices
- 2;
4275 return DDERR_INVALIDPARAMS
;
4278 /* Get the FVF of the vertex buffer, and its stride */
4279 EnterCriticalSection(&ddraw_cs
);
4280 hr
= IWineD3DVertexBuffer_GetDesc(vb
->wineD3DVertexBuffer
,
4284 ERR("(%p) IWineD3DVertexBuffer::GetDesc failed with hr = %08x\n", This
, hr
);
4285 LeaveCriticalSection(&ddraw_cs
);
4288 stride
= get_flexible_vertex_size(Desc
.FVF
);
4290 hr
= IWineD3DDevice_SetVertexDeclaration(This
->wineD3DDevice
,
4291 vb
->wineD3DVertexDeclaration
);
4294 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This
, hr
);
4295 LeaveCriticalSection(&ddraw_cs
);
4299 /* Set the vertex stream source */
4300 hr
= IWineD3DDevice_SetStreamSource(This
->wineD3DDevice
,
4301 0 /* StreamNumber */,
4302 vb
->wineD3DVertexBuffer
,
4303 0 /* StartVertex - we pass this to DrawPrimitive */,
4307 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This
, hr
);
4308 LeaveCriticalSection(&ddraw_cs
);
4312 /* Now draw the primitives */
4313 hr
= IWineD3DDevice_DrawPrimitive(This
->wineD3DDevice
,
4317 LeaveCriticalSection(&ddraw_cs
);
4321 static HRESULT WINAPI
4322 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUSetup(IDirect3DDevice7
*iface
,
4323 D3DPRIMITIVETYPE PrimitiveType
,
4324 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4329 return IDirect3DDeviceImpl_7_DrawPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4332 static HRESULT WINAPI
4333 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUPreserve(IDirect3DDevice7
*iface
,
4334 D3DPRIMITIVETYPE PrimitiveType
,
4335 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4343 old_fpucw
= d3d_fpu_setup();
4344 hr
= IDirect3DDeviceImpl_7_DrawPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4345 set_fpu_control_word(old_fpucw
);
4350 static HRESULT WINAPI
4351 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB(IDirect3DDevice3
*iface
,
4352 D3DPRIMITIVETYPE PrimitiveType
,
4353 IDirect3DVertexBuffer
*D3DVertexBuf
,
4358 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
4359 IDirect3DVertexBufferImpl
*vb
= D3DVertexBuf
? vb_from_vb1(D3DVertexBuf
) : NULL
;
4360 TRACE_(ddraw_thunk
)("(%p)->(%08x,%p,%08x,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This
, PrimitiveType
, vb
, StartVertex
, NumVertices
, Flags
);
4361 return IDirect3DDevice7_DrawPrimitiveVB((IDirect3DDevice7
*)This
, PrimitiveType
,
4362 (IDirect3DVertexBuffer7
*)vb
, StartVertex
, NumVertices
, Flags
);
4366 /*****************************************************************************
4367 * IDirect3DDevice7::DrawIndexedPrimitiveVB
4369 * Draws primitives from a vertex buffer to the screen
4372 * PrimitiveType: Type of primitive to be rendered.
4373 * D3DVertexBuf: Source Vertex Buffer
4374 * StartVertex: Index of the first vertex from the buffer to be rendered
4375 * NumVertices: Number of vertices to be rendered
4376 * Indices: Array of DWORDs used to index into the Vertices
4377 * IndexCount: Number of indices in Indices
4378 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4382 *****************************************************************************/
4384 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(IDirect3DDevice7
*iface
,
4385 D3DPRIMITIVETYPE PrimitiveType
,
4386 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4393 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
4394 IDirect3DVertexBufferImpl
*vb
= (IDirect3DVertexBufferImpl
*)D3DVertexBuf
;
4396 UINT PrimitiveCount
;
4397 WORD
*LockedIndices
;
4399 WINED3DVERTEXBUFFER_DESC Desc
;
4401 TRACE("(%p)->(%08x,%p,%d,%d,%p,%d,%08x)\n", This
, PrimitiveType
, vb
, StartVertex
, NumVertices
, Indices
, IndexCount
, Flags
);
4404 * 1) Calculate some things: Vertex count -> Primitive count, stride, ...
4405 * 2) Upload the Indices to the index buffer
4406 * 3) Set the index source
4407 * 4) Set the Vertex Buffer as the Stream source
4408 * 5) Call IWineD3DDevice::DrawIndexedPrimitive
4411 /* Get the primitive count */
4412 switch(PrimitiveType
)
4414 case D3DPT_POINTLIST
:
4415 PrimitiveCount
= IndexCount
;
4418 case D3DPT_LINELIST
:
4419 PrimitiveCount
= IndexCount
/ 2;
4422 case D3DPT_LINESTRIP
:
4423 PrimitiveCount
= IndexCount
- 1;
4426 case D3DPT_TRIANGLELIST
:
4427 PrimitiveCount
= IndexCount
/ 3;
4430 case D3DPT_TRIANGLESTRIP
:
4431 PrimitiveCount
= IndexCount
- 2;
4434 case D3DPT_TRIANGLEFAN
:
4435 PrimitiveCount
= IndexCount
- 2;
4438 default: return DDERR_INVALIDPARAMS
;
4441 EnterCriticalSection(&ddraw_cs
);
4442 /* Get the FVF of the vertex buffer, and its stride */
4443 hr
= IWineD3DVertexBuffer_GetDesc(vb
->wineD3DVertexBuffer
,
4447 ERR("(%p) IWineD3DVertexBuffer::GetDesc failed with hr = %08x\n", This
, hr
);
4448 LeaveCriticalSection(&ddraw_cs
);
4451 stride
= get_flexible_vertex_size(Desc
.FVF
);
4452 TRACE("Vertex buffer FVF = %08x, stride=%d\n", Desc
.FVF
, stride
);
4454 hr
= IWineD3DDevice_SetVertexDeclaration(This
->wineD3DDevice
,
4455 vb
->wineD3DVertexDeclaration
);
4458 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This
, hr
);
4459 LeaveCriticalSection(&ddraw_cs
);
4463 /* copy the index stream into the index buffer.
4464 * A new IWineD3DDevice method could be created
4465 * which takes an user pointer containing the indices
4466 * or a SetData-Method for the index buffer, which
4467 * overrides the index buffer data with our pointer.
4469 hr
= IWineD3DIndexBuffer_Lock(This
->indexbuffer
,
4470 0 /* OffSetToLock */,
4471 IndexCount
* sizeof(WORD
),
4472 (BYTE
**) &LockedIndices
,
4474 assert(IndexCount
< 0x100000);
4477 ERR("(%p) IWineD3DIndexBuffer::Lock failed with hr = %08x\n", This
, hr
);
4478 LeaveCriticalSection(&ddraw_cs
);
4481 memcpy(LockedIndices
, Indices
, IndexCount
* sizeof(WORD
));
4482 hr
= IWineD3DIndexBuffer_Unlock(This
->indexbuffer
);
4485 ERR("(%p) IWineD3DIndexBuffer::Unlock failed with hr = %08x\n", This
, hr
);
4486 LeaveCriticalSection(&ddraw_cs
);
4490 /* Set the index stream */
4491 IWineD3DDevice_SetBaseVertexIndex(This
->wineD3DDevice
, StartVertex
);
4492 hr
= IWineD3DDevice_SetIndices(This
->wineD3DDevice
, This
->indexbuffer
);
4494 /* Set the vertex stream source */
4495 hr
= IWineD3DDevice_SetStreamSource(This
->wineD3DDevice
,
4496 0 /* StreamNumber */,
4497 vb
->wineD3DVertexBuffer
,
4498 0 /* offset, we pass this to DrawIndexedPrimitive */,
4502 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This
, hr
);
4503 LeaveCriticalSection(&ddraw_cs
);
4508 hr
= IWineD3DDevice_DrawIndexedPrimitive(This
->wineD3DDevice
,
4515 LeaveCriticalSection(&ddraw_cs
);
4519 static HRESULT WINAPI
4520 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUSetup(IDirect3DDevice7
*iface
,
4521 D3DPRIMITIVETYPE PrimitiveType
,
4522 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4529 return IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Indices
, IndexCount
, Flags
);
4532 static HRESULT WINAPI
4533 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUPreserve(IDirect3DDevice7
*iface
,
4534 D3DPRIMITIVETYPE PrimitiveType
,
4535 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4545 old_fpucw
= d3d_fpu_setup();
4546 hr
= IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Indices
, IndexCount
, Flags
);
4547 set_fpu_control_word(old_fpucw
);
4552 static HRESULT WINAPI
4553 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB(IDirect3DDevice3
*iface
,
4554 D3DPRIMITIVETYPE PrimitiveType
,
4555 IDirect3DVertexBuffer
*D3DVertexBuf
,
4560 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
4561 IDirect3DVertexBufferImpl
*VB
= vb_from_vb1(D3DVertexBuf
);
4562 TRACE_(ddraw_thunk
)("(%p)->(%08x,%p,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This
, PrimitiveType
, VB
, Indices
, IndexCount
, Flags
);
4564 return IDirect3DDevice7_DrawIndexedPrimitiveVB((IDirect3DDevice7
*)This
, PrimitiveType
,
4565 (IDirect3DVertexBuffer7
*)VB
, 0, IndexCount
, Indices
, IndexCount
, Flags
);
4568 /*****************************************************************************
4569 * IDirect3DDevice7::ComputeSphereVisibility
4571 * Calculates the visibility of spheres in the current viewport. The spheres
4572 * are passed in the Centers and Radii arrays, the results are passed back
4573 * in the ReturnValues array. Return values are either completely visible,
4574 * partially visible or completely invisible.
4575 * The return value consist of a combination of D3DCLIP_* flags, or it's
4576 * 0 if the sphere is completely visible(according to the SDK, not checked)
4578 * Sounds like an overdose of math ;)
4583 * Centers: Array containing the sphere centers
4584 * Radii: Array containing the sphere radii
4585 * NumSpheres: The number of centers and radii in the arrays
4587 * ReturnValues: Array to write the results to
4590 * D3D_OK because it's a stub
4591 * (DDERR_INVALIDPARAMS if Centers, Radii or ReturnValues are NULL)
4592 * (D3DERR_INVALIDMATRIX if the combined world, view and proj matrix
4595 *****************************************************************************/
4597 static DWORD
in_plane(UINT plane
, D3DVECTOR normal
, D3DVALUE origin_plane
, D3DVECTOR center
, D3DVALUE radius
)
4599 float distance
, norm
;
4601 norm
= sqrt( normal
.u1
.x
* normal
.u1
.x
+ normal
.u2
.y
* normal
.u2
.y
+ normal
.u3
.z
* normal
.u3
.z
);
4602 distance
= ( origin_plane
+ normal
.u1
.x
* center
.u1
.x
+ normal
.u2
.y
* center
.u2
.y
+ normal
.u3
.z
* center
.u3
.z
) / norm
;
4604 if ( fabs( distance
) < radius
) return D3DSTATUS_CLIPUNIONLEFT
<< plane
;
4605 if ( distance
< -radius
) return (D3DSTATUS_CLIPUNIONLEFT
| D3DSTATUS_CLIPINTERSECTIONLEFT
) << plane
;
4609 static HRESULT WINAPI
4610 IDirect3DDeviceImpl_7_ComputeSphereVisibility(IDirect3DDevice7
*iface
,
4615 DWORD
*ReturnValues
)
4618 D3DVALUE origin_plane
[6];
4623 TRACE("(%p)->(%p,%p,%08x,%08x,%p)\n", iface
, Centers
, Radii
, NumSpheres
, Flags
, ReturnValues
);
4625 hr
= IDirect3DDeviceImpl_7_GetTransform(iface
, D3DTRANSFORMSTATE_WORLD
, &m
);
4626 if ( hr
!= DD_OK
) return DDERR_INVALIDPARAMS
;
4627 hr
= IDirect3DDeviceImpl_7_GetTransform(iface
, D3DTRANSFORMSTATE_VIEW
, &temp
);
4628 if ( hr
!= DD_OK
) return DDERR_INVALIDPARAMS
;
4629 multiply_matrix_D3D_way(&m
, &m
, &temp
);
4631 hr
= IDirect3DDeviceImpl_7_GetTransform(iface
, D3DTRANSFORMSTATE_PROJECTION
, &temp
);
4632 if ( hr
!= DD_OK
) return DDERR_INVALIDPARAMS
;
4633 multiply_matrix_D3D_way(&m
, &m
, &temp
);
4636 vec
[0].u1
.x
= m
._14
+ m
._11
;
4637 vec
[0].u2
.y
= m
._24
+ m
._21
;
4638 vec
[0].u3
.z
= m
._34
+ m
._31
;
4639 origin_plane
[0] = m
._44
+ m
._41
;
4642 vec
[1].u1
.x
= m
._14
- m
._11
;
4643 vec
[1].u2
.y
= m
._24
- m
._21
;
4644 vec
[1].u3
.z
= m
._34
- m
._31
;
4645 origin_plane
[1] = m
._44
- m
._41
;
4648 vec
[2].u1
.x
= m
._14
- m
._12
;
4649 vec
[2].u2
.y
= m
._24
- m
._22
;
4650 vec
[2].u3
.z
= m
._34
- m
._32
;
4651 origin_plane
[2] = m
._44
- m
._42
;
4654 vec
[3].u1
.x
= m
._14
+ m
._12
;
4655 vec
[3].u2
.y
= m
._24
+ m
._22
;
4656 vec
[3].u3
.z
= m
._34
+ m
._32
;
4657 origin_plane
[3] = m
._44
+ m
._42
;
4660 vec
[4].u1
.x
= m
._13
;
4661 vec
[4].u2
.y
= m
._23
;
4662 vec
[4].u3
.z
= m
._33
;
4663 origin_plane
[4] = m
._43
;
4666 vec
[5].u1
.x
= m
._14
- m
._13
;
4667 vec
[5].u2
.y
= m
._24
- m
._23
;
4668 vec
[5].u3
.z
= m
._34
- m
._33
;
4669 origin_plane
[5] = m
._44
- m
._43
;
4671 for(i
=0; i
<NumSpheres
; i
++)
4673 ReturnValues
[i
] = 0;
4674 for(j
=0; j
<6; j
++) ReturnValues
[i
] |= in_plane(j
, vec
[j
], origin_plane
[j
], Centers
[i
], Radii
[i
]);
4680 static HRESULT WINAPI
4681 Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility(IDirect3DDevice3
*iface
,
4686 DWORD
*ReturnValues
)
4688 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
4689 TRACE_(ddraw_thunk
)("(%p)->(%p,%p,%08x,%08x,%p) thunking to IDirect3DDevice7 interface.\n", This
, Centers
, Radii
, NumSpheres
, Flags
, ReturnValues
);
4690 return IDirect3DDevice7_ComputeSphereVisibility((IDirect3DDevice7
*)This
,
4691 Centers
, Radii
, NumSpheres
, Flags
, ReturnValues
);
4694 /*****************************************************************************
4695 * IDirect3DDevice7::GetTexture
4697 * Returns the texture interface handle assigned to a texture stage.
4698 * The returned texture is AddRefed. This is taken from old ddraw,
4699 * not checked in Windows.
4704 * Stage: Texture stage to read the texture from
4705 * Texture: Address to store the interface pointer at
4709 * DDERR_INVALIDPARAMS if Texture is NULL
4710 * For details, see IWineD3DDevice::GetTexture
4712 *****************************************************************************/
4714 IDirect3DDeviceImpl_7_GetTexture(IDirect3DDevice7
*iface
,
4716 IDirectDrawSurface7
**Texture
)
4718 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
4719 IWineD3DBaseTexture
*Surf
;
4721 TRACE("(%p)->(%d,%p): Relay\n", This
, Stage
, Texture
);
4725 TRACE("Texture == NULL, failing with DDERR_INVALIDPARAMS\n");
4726 return DDERR_INVALIDPARAMS
;
4729 EnterCriticalSection(&ddraw_cs
);
4730 hr
= IWineD3DDevice_GetTexture(This
->wineD3DDevice
, Stage
, &Surf
);
4731 if( (hr
!= D3D_OK
) || (!Surf
) )
4734 LeaveCriticalSection(&ddraw_cs
);
4738 /* GetParent AddRef()s, which is perfectly OK.
4739 * We have passed the IDirectDrawSurface7 interface to WineD3D, so that's OK too.
4741 hr
= IWineD3DBaseTexture_GetParent(Surf
,
4742 (IUnknown
**) Texture
);
4743 LeaveCriticalSection(&ddraw_cs
);
4747 static HRESULT WINAPI
4748 IDirect3DDeviceImpl_7_GetTexture_FPUSetup(IDirect3DDevice7
*iface
,
4750 IDirectDrawSurface7
**Texture
)
4752 return IDirect3DDeviceImpl_7_GetTexture(iface
, Stage
, Texture
);
4755 static HRESULT WINAPI
4756 IDirect3DDeviceImpl_7_GetTexture_FPUPreserve(IDirect3DDevice7
*iface
,
4758 IDirectDrawSurface7
**Texture
)
4763 old_fpucw
= d3d_fpu_setup();
4764 hr
= IDirect3DDeviceImpl_7_GetTexture(iface
, Stage
, Texture
);
4765 set_fpu_control_word(old_fpucw
);
4770 static HRESULT WINAPI
4771 Thunk_IDirect3DDeviceImpl_3_GetTexture(IDirect3DDevice3
*iface
,
4773 IDirect3DTexture2
**Texture2
)
4775 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
4777 IDirectDrawSurface7
*ret_val
;
4779 TRACE_(ddraw_thunk
)("(%p)->(%d,%p) thunking to IDirect3DDevice7 interface.\n", This
, Stage
, Texture2
);
4780 ret
= IDirect3DDevice7_GetTexture((IDirect3DDevice7
*)This
, Stage
, &ret_val
);
4782 *Texture2
= ret_val
? (IDirect3DTexture2
*)&((IDirectDrawSurfaceImpl
*)ret_val
)->IDirect3DTexture2_vtbl
: NULL
;
4784 TRACE_(ddraw_thunk
)(" returning interface %p.\n", *Texture2
);
4789 /*****************************************************************************
4790 * IDirect3DDevice7::SetTexture
4792 * Assigns a texture to a texture stage. Is the texture AddRef-ed?
4797 * Stage: The stage to assign the texture to
4798 * Texture: Interface pointer to the texture surface
4802 * For details, see IWineD3DDevice::SetTexture
4804 *****************************************************************************/
4806 IDirect3DDeviceImpl_7_SetTexture(IDirect3DDevice7
*iface
,
4808 IDirectDrawSurface7
*Texture
)
4810 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
4811 IDirectDrawSurfaceImpl
*surf
= (IDirectDrawSurfaceImpl
*)Texture
;
4813 TRACE("(%p)->(%08x,%p): Relay!\n", This
, Stage
, surf
);
4815 /* Texture may be NULL here */
4816 EnterCriticalSection(&ddraw_cs
);
4817 hr
= IWineD3DDevice_SetTexture(This
->wineD3DDevice
,
4819 surf
? surf
->wineD3DTexture
: NULL
);
4820 LeaveCriticalSection(&ddraw_cs
);
4824 static HRESULT WINAPI
4825 IDirect3DDeviceImpl_7_SetTexture_FPUSetup(IDirect3DDevice7
*iface
,
4827 IDirectDrawSurface7
*Texture
)
4829 return IDirect3DDeviceImpl_7_SetTexture(iface
, Stage
, Texture
);
4832 static HRESULT WINAPI
4833 IDirect3DDeviceImpl_7_SetTexture_FPUPreserve(IDirect3DDevice7
*iface
,
4835 IDirectDrawSurface7
*Texture
)
4840 old_fpucw
= d3d_fpu_setup();
4841 hr
= IDirect3DDeviceImpl_7_SetTexture(iface
, Stage
, Texture
);
4842 set_fpu_control_word(old_fpucw
);
4847 static HRESULT WINAPI
4848 IDirect3DDeviceImpl_3_SetTexture(IDirect3DDevice3
*iface
,
4850 IDirect3DTexture2
*Texture2
)
4852 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
4853 IDirectDrawSurfaceImpl
*tex
= Texture2
? surface_from_texture2(Texture2
) : NULL
;
4856 TRACE("(%p)->(%d,%p)\n", This
, Stage
, tex
);
4858 EnterCriticalSection(&ddraw_cs
);
4860 if (This
->legacyTextureBlending
)
4861 IDirect3DDevice3_GetRenderState(iface
, D3DRENDERSTATE_TEXTUREMAPBLEND
, &texmapblend
);
4863 hr
= IDirect3DDevice7_SetTexture((IDirect3DDevice7
*)This
, Stage
, (IDirectDrawSurface7
*)tex
);
4865 if (This
->legacyTextureBlending
&& texmapblend
== D3DTBLEND_MODULATE
)
4867 /* This fixup is required by the way D3DTBLEND_MODULATE maps to texture stage states.
4868 See IDirect3DDeviceImpl_3_SetRenderState for details. */
4869 BOOL tex_alpha
= FALSE
;
4870 IWineD3DBaseTexture
*tex
= NULL
;
4871 WINED3DSURFACE_DESC desc
;
4873 DDPIXELFORMAT ddfmt
;
4876 result
= IWineD3DDevice_GetTexture(This
->wineD3DDevice
,
4880 if(result
== WINED3D_OK
&& tex
)
4882 memset(&desc
, 0, sizeof(desc
));
4884 result
= IWineD3DTexture_GetLevelDesc((IWineD3DTexture
*) tex
, 0, &desc
);
4885 if (SUCCEEDED(result
))
4887 ddfmt
.dwSize
= sizeof(ddfmt
);
4888 PixelFormat_WineD3DtoDD(&ddfmt
, fmt
);
4889 if (ddfmt
.u5
.dwRGBAlphaBitMask
) tex_alpha
= TRUE
;
4892 IWineD3DBaseTexture_Release(tex
);
4895 /* alphaop is WINED3DTOP_SELECTARG1 if it's D3DTBLEND_MODULATE, so only modify alphaarg1 */
4898 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG1
, WINED3DTA_TEXTURE
);
4902 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG1
, WINED3DTA_CURRENT
);
4906 LeaveCriticalSection(&ddraw_cs
);
4911 static const struct tss_lookup
4918 {FALSE
, WINED3DTSS_FORCE_DWORD
}, /* 0, unused */
4919 {FALSE
, WINED3DTSS_COLOROP
}, /* 1, D3DTSS_COLOROP */
4920 {FALSE
, WINED3DTSS_COLORARG1
}, /* 2, D3DTSS_COLORARG1 */
4921 {FALSE
, WINED3DTSS_COLORARG2
}, /* 3, D3DTSS_COLORARG2 */
4922 {FALSE
, WINED3DTSS_ALPHAOP
}, /* 4, D3DTSS_ALPHAOP */
4923 {FALSE
, WINED3DTSS_ALPHAARG1
}, /* 5, D3DTSS_ALPHAARG1 */
4924 {FALSE
, WINED3DTSS_ALPHAARG2
}, /* 6, D3DTSS_ALPHAARG2 */
4925 {FALSE
, WINED3DTSS_BUMPENVMAT00
}, /* 7, D3DTSS_BUMPENVMAT00 */
4926 {FALSE
, WINED3DTSS_BUMPENVMAT01
}, /* 8, D3DTSS_BUMPENVMAT01 */
4927 {FALSE
, WINED3DTSS_BUMPENVMAT10
}, /* 9, D3DTSS_BUMPENVMAT10 */
4928 {FALSE
, WINED3DTSS_BUMPENVMAT11
}, /* 10, D3DTSS_BUMPENVMAT11 */
4929 {FALSE
, WINED3DTSS_TEXCOORDINDEX
}, /* 11, D3DTSS_TEXCOORDINDEX */
4930 {TRUE
, WINED3DSAMP_ADDRESSU
}, /* 12, D3DTSS_ADDRESS */
4931 {TRUE
, WINED3DSAMP_ADDRESSU
}, /* 13, D3DTSS_ADDRESSU */
4932 {TRUE
, WINED3DSAMP_ADDRESSV
}, /* 14, D3DTSS_ADDRESSV */
4933 {TRUE
, WINED3DSAMP_BORDERCOLOR
}, /* 15, D3DTSS_BORDERCOLOR */
4934 {TRUE
, WINED3DSAMP_MAGFILTER
}, /* 16, D3DTSS_MAGFILTER */
4935 {TRUE
, WINED3DSAMP_MINFILTER
}, /* 17, D3DTSS_MINFILTER */
4936 {TRUE
, WINED3DSAMP_MIPFILTER
}, /* 18, D3DTSS_MIPFILTER */
4937 {TRUE
, WINED3DSAMP_MIPMAPLODBIAS
}, /* 19, D3DTSS_MIPMAPLODBIAS */
4938 {TRUE
, WINED3DSAMP_MAXMIPLEVEL
}, /* 20, D3DTSS_MAXMIPLEVEL */
4939 {TRUE
, WINED3DSAMP_MAXANISOTROPY
}, /* 21, D3DTSS_MAXANISOTROPY */
4940 {FALSE
, WINED3DTSS_BUMPENVLSCALE
}, /* 22, D3DTSS_BUMPENVLSCALE */
4941 {FALSE
, WINED3DTSS_BUMPENVLOFFSET
}, /* 23, D3DTSS_BUMPENVLOFFSET */
4942 {FALSE
, WINED3DTSS_TEXTURETRANSFORMFLAGS
}, /* 24, D3DTSS_TEXTURETRANSFORMFLAGS */
4945 /*****************************************************************************
4946 * IDirect3DDevice7::GetTextureStageState
4948 * Retrieves a state from a texture stage.
4953 * Stage: The stage to retrieve the state from
4954 * TexStageStateType: The state type to retrieve
4955 * State: Address to store the state's value at
4959 * DDERR_INVALIDPARAMS if State is NULL
4960 * For details, see IWineD3DDevice::GetTextureStageState
4962 *****************************************************************************/
4964 IDirect3DDeviceImpl_7_GetTextureStageState(IDirect3DDevice7
*iface
,
4966 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
4969 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
4971 const struct tss_lookup
*l
= &tss_lookup
[TexStageStateType
];
4972 TRACE("(%p)->(%08x,%08x,%p): Relay!\n", This
, Stage
, TexStageStateType
, State
);
4975 return DDERR_INVALIDPARAMS
;
4977 EnterCriticalSection(&ddraw_cs
);
4979 if (l
->sampler_state
)
4981 hr
= IWineD3DDevice_GetSamplerState(This
->wineD3DDevice
, Stage
, l
->state
, State
);
4983 switch(TexStageStateType
)
4985 /* Mipfilter is a sampler state with different values */
4986 case D3DTSS_MIPFILTER
:
4990 case WINED3DTEXF_NONE
: *State
= D3DTFP_NONE
; break;
4991 case WINED3DTEXF_POINT
: *State
= D3DTFP_POINT
; break;
4992 case WINED3DTEXF_LINEAR
: *State
= D3DTFP_LINEAR
; break;
4994 ERR("Unexpected mipfilter value %#x\n", *State
);
4995 *State
= D3DTFP_NONE
;
5001 /* Magfilter has slightly different values */
5002 case D3DTSS_MAGFILTER
:
5006 case WINED3DTEXF_POINT
: *State
= D3DTFG_POINT
; break;
5007 case WINED3DTEXF_LINEAR
: *State
= D3DTFG_LINEAR
; break;
5008 case WINED3DTEXF_ANISOTROPIC
: *State
= D3DTFG_ANISOTROPIC
; break;
5009 case WINED3DTEXF_FLATCUBIC
: *State
= D3DTFG_FLATCUBIC
; break;
5010 case WINED3DTEXF_GAUSSIANCUBIC
: *State
= D3DTFG_GAUSSIANCUBIC
; break;
5012 ERR("Unexpected wined3d mag filter value %#x\n", *State
);
5013 *State
= D3DTFG_POINT
;
5025 hr
= IWineD3DDevice_GetTextureStageState(This
->wineD3DDevice
, Stage
, l
->state
, State
);
5028 LeaveCriticalSection(&ddraw_cs
);
5032 static HRESULT WINAPI
5033 IDirect3DDeviceImpl_7_GetTextureStageState_FPUSetup(IDirect3DDevice7
*iface
,
5035 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
5038 return IDirect3DDeviceImpl_7_GetTextureStageState(iface
, Stage
, TexStageStateType
, State
);
5041 static HRESULT WINAPI
5042 IDirect3DDeviceImpl_7_GetTextureStageState_FPUPreserve(IDirect3DDevice7
*iface
,
5044 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
5050 old_fpucw
= d3d_fpu_setup();
5051 hr
= IDirect3DDeviceImpl_7_GetTextureStageState(iface
, Stage
, TexStageStateType
, State
);
5052 set_fpu_control_word(old_fpucw
);
5057 static HRESULT WINAPI
5058 Thunk_IDirect3DDeviceImpl_3_GetTextureStageState(IDirect3DDevice3
*iface
,
5060 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
5063 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
5064 TRACE_(ddraw_thunk
)("(%p)->(%08x,%08x,%p) thunking to IDirect3DDevice7 interface.\n", This
, Stage
, TexStageStateType
, State
);
5065 return IDirect3DDevice7_GetTextureStageState((IDirect3DDevice7
*)This
, Stage
, TexStageStateType
, State
);
5068 /*****************************************************************************
5069 * IDirect3DDevice7::SetTextureStageState
5071 * Sets a texture stage state. Some stage types need to be handled specially,
5072 * because they do not exist in WineD3D and were moved to another place
5077 * Stage: The stage to modify
5078 * TexStageStateType: The state to change
5079 * State: The new value for the state
5083 * For details, see IWineD3DDevice::SetTextureStageState
5085 *****************************************************************************/
5087 IDirect3DDeviceImpl_7_SetTextureStageState(IDirect3DDevice7
*iface
,
5089 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
5092 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5093 const struct tss_lookup
*l
= &tss_lookup
[TexStageStateType
];
5095 TRACE("(%p)->(%08x,%08x,%08x): Relay!\n", This
, Stage
, TexStageStateType
, State
);
5097 EnterCriticalSection(&ddraw_cs
);
5099 if (l
->sampler_state
)
5101 switch(TexStageStateType
)
5103 /* Mipfilter is a sampler state with different values */
5104 case D3DTSS_MIPFILTER
:
5108 case D3DTFP_NONE
: State
= WINED3DTEXF_NONE
; break;
5109 case D3DTFP_POINT
: State
= WINED3DTEXF_POINT
; break;
5110 case 0: /* Unchecked */
5111 case D3DTFP_LINEAR
: State
= WINED3DTEXF_LINEAR
; break;
5113 ERR("Unexpected mipfilter value %d\n", State
);
5114 State
= WINED3DTEXF_NONE
;
5120 /* Magfilter has slightly different values */
5121 case D3DTSS_MAGFILTER
:
5125 case D3DTFG_POINT
: State
= WINED3DTEXF_POINT
; break;
5126 case D3DTFG_LINEAR
: State
= WINED3DTEXF_LINEAR
; break;
5127 case D3DTFG_FLATCUBIC
: State
= WINED3DTEXF_FLATCUBIC
; break;
5128 case D3DTFG_GAUSSIANCUBIC
: State
= WINED3DTEXF_GAUSSIANCUBIC
; break;
5129 case D3DTFG_ANISOTROPIC
: State
= WINED3DTEXF_ANISOTROPIC
; break;
5131 ERR("Unexpected d3d7 mag filter type %d\n", State
);
5132 State
= WINED3DTEXF_POINT
;
5138 case D3DTSS_ADDRESS
:
5139 IWineD3DDevice_SetSamplerState(This
->wineD3DDevice
, Stage
, WINED3DSAMP_ADDRESSV
, State
);
5146 hr
= IWineD3DDevice_SetSamplerState(This
->wineD3DDevice
, Stage
, l
->state
, State
);
5150 hr
= IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, Stage
, l
->state
, State
);
5153 LeaveCriticalSection(&ddraw_cs
);
5157 static HRESULT WINAPI
5158 IDirect3DDeviceImpl_7_SetTextureStageState_FPUSetup(IDirect3DDevice7
*iface
,
5160 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
5163 return IDirect3DDeviceImpl_7_SetTextureStageState(iface
, Stage
, TexStageStateType
, State
);
5166 static HRESULT WINAPI
5167 IDirect3DDeviceImpl_7_SetTextureStageState_FPUPreserve(IDirect3DDevice7
*iface
,
5169 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
5175 old_fpucw
= d3d_fpu_setup();
5176 hr
= IDirect3DDeviceImpl_7_SetTextureStageState(iface
, Stage
, TexStageStateType
, State
);
5177 set_fpu_control_word(old_fpucw
);
5182 static HRESULT WINAPI
5183 Thunk_IDirect3DDeviceImpl_3_SetTextureStageState(IDirect3DDevice3
*iface
,
5185 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
5188 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
5189 TRACE_(ddraw_thunk
)("(%p)->(%08x,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This
, Stage
, TexStageStateType
, State
);
5190 return IDirect3DDevice7_SetTextureStageState((IDirect3DDevice7
*)This
, Stage
, TexStageStateType
, State
);
5193 /*****************************************************************************
5194 * IDirect3DDevice7::ValidateDevice
5196 * SDK: "Reports the device's ability to render the currently set
5197 * texture-blending operations in a single pass". Whatever that means
5203 * NumPasses: Address to write the number of necessary passes for the
5204 * desired effect to.
5208 * See IWineD3DDevice::ValidateDevice for more details
5210 *****************************************************************************/
5212 IDirect3DDeviceImpl_7_ValidateDevice(IDirect3DDevice7
*iface
,
5215 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5217 TRACE("(%p)->(%p): Relay\n", This
, NumPasses
);
5219 EnterCriticalSection(&ddraw_cs
);
5220 hr
= IWineD3DDevice_ValidateDevice(This
->wineD3DDevice
, NumPasses
);
5221 LeaveCriticalSection(&ddraw_cs
);
5225 static HRESULT WINAPI
5226 IDirect3DDeviceImpl_7_ValidateDevice_FPUSetup(IDirect3DDevice7
*iface
,
5229 return IDirect3DDeviceImpl_7_ValidateDevice(iface
, NumPasses
);
5232 static HRESULT WINAPI
5233 IDirect3DDeviceImpl_7_ValidateDevice_FPUPreserve(IDirect3DDevice7
*iface
,
5239 old_fpucw
= d3d_fpu_setup();
5240 hr
= IDirect3DDeviceImpl_7_ValidateDevice(iface
, NumPasses
);
5241 set_fpu_control_word(old_fpucw
);
5246 static HRESULT WINAPI
5247 Thunk_IDirect3DDeviceImpl_3_ValidateDevice(IDirect3DDevice3
*iface
,
5250 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
5251 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This
, Passes
);
5252 return IDirect3DDevice7_ValidateDevice((IDirect3DDevice7
*)This
, Passes
);
5255 /*****************************************************************************
5256 * IDirect3DDevice7::Clear
5258 * Fills the render target, the z buffer and the stencil buffer with a
5259 * clear color / value
5264 * Count: Number of rectangles in Rects must be 0 if Rects is NULL
5265 * Rects: Rectangles to clear. If NULL, the whole surface is cleared
5266 * Flags: Some flags, as usual
5267 * Color: Clear color for the render target
5268 * Z: Clear value for the Z buffer
5269 * Stencil: Clear value to store in each stencil buffer entry
5273 * For details, see IWineD3DDevice::Clear
5275 *****************************************************************************/
5277 IDirect3DDeviceImpl_7_Clear(IDirect3DDevice7
*iface
,
5285 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5287 TRACE("(%p)->(%08x,%p,%08x,%08x,%f,%08x): Relay\n", This
, Count
, Rects
, Flags
, Color
, Z
, Stencil
);
5289 /* Note; D3DRECT is compatible with WINED3DRECT */
5290 EnterCriticalSection(&ddraw_cs
);
5291 hr
= IWineD3DDevice_Clear(This
->wineD3DDevice
, Count
, (WINED3DRECT
*) Rects
, Flags
, Color
, Z
, Stencil
);
5292 LeaveCriticalSection(&ddraw_cs
);
5296 static HRESULT WINAPI
5297 IDirect3DDeviceImpl_7_Clear_FPUSetup(IDirect3DDevice7
*iface
,
5305 return IDirect3DDeviceImpl_7_Clear(iface
, Count
, Rects
, Flags
, Color
, Z
, Stencil
);
5308 static HRESULT WINAPI
5309 IDirect3DDeviceImpl_7_Clear_FPUPreserve(IDirect3DDevice7
*iface
,
5320 old_fpucw
= d3d_fpu_setup();
5321 hr
= IDirect3DDeviceImpl_7_Clear(iface
, Count
, Rects
, Flags
, Color
, Z
, Stencil
);
5322 set_fpu_control_word(old_fpucw
);
5327 /*****************************************************************************
5328 * IDirect3DDevice7::SetViewport
5330 * Sets the current viewport.
5332 * Version 7 only, but IDirect3DViewport uses this call for older
5336 * Data: The new viewport to set
5340 * DDERR_INVALIDPARAMS if Data is NULL
5341 * For more details, see IWineDDDevice::SetViewport
5343 *****************************************************************************/
5345 IDirect3DDeviceImpl_7_SetViewport(IDirect3DDevice7
*iface
,
5348 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5350 TRACE("(%p)->(%p) Relay!\n", This
, Data
);
5353 return DDERR_INVALIDPARAMS
;
5355 /* Note: D3DVIEWPORT7 is compatible with WINED3DVIEWPORT */
5356 EnterCriticalSection(&ddraw_cs
);
5357 hr
= IWineD3DDevice_SetViewport(This
->wineD3DDevice
,
5358 (WINED3DVIEWPORT
*) Data
);
5359 LeaveCriticalSection(&ddraw_cs
);
5363 static HRESULT WINAPI
5364 IDirect3DDeviceImpl_7_SetViewport_FPUSetup(IDirect3DDevice7
*iface
,
5367 return IDirect3DDeviceImpl_7_SetViewport(iface
, Data
);
5370 static HRESULT WINAPI
5371 IDirect3DDeviceImpl_7_SetViewport_FPUPreserve(IDirect3DDevice7
*iface
,
5377 old_fpucw
= d3d_fpu_setup();
5378 hr
= IDirect3DDeviceImpl_7_SetViewport(iface
, Data
);
5379 set_fpu_control_word(old_fpucw
);
5384 /*****************************************************************************
5385 * IDirect3DDevice::GetViewport
5387 * Returns the current viewport
5392 * Data: D3D7Viewport structure to write the viewport information to
5396 * DDERR_INVALIDPARAMS if Data is NULL
5397 * For more details, see IWineD3DDevice::GetViewport
5399 *****************************************************************************/
5401 IDirect3DDeviceImpl_7_GetViewport(IDirect3DDevice7
*iface
,
5404 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5406 TRACE("(%p)->(%p) Relay!\n", This
, Data
);
5409 return DDERR_INVALIDPARAMS
;
5411 /* Note: D3DVIEWPORT7 is compatible with WINED3DVIEWPORT */
5412 EnterCriticalSection(&ddraw_cs
);
5413 hr
= IWineD3DDevice_GetViewport(This
->wineD3DDevice
,
5414 (WINED3DVIEWPORT
*) Data
);
5416 LeaveCriticalSection(&ddraw_cs
);
5417 return hr_ddraw_from_wined3d(hr
);
5420 static HRESULT WINAPI
5421 IDirect3DDeviceImpl_7_GetViewport_FPUSetup(IDirect3DDevice7
*iface
,
5424 return IDirect3DDeviceImpl_7_GetViewport(iface
, Data
);
5427 static HRESULT WINAPI
5428 IDirect3DDeviceImpl_7_GetViewport_FPUPreserve(IDirect3DDevice7
*iface
,
5434 old_fpucw
= d3d_fpu_setup();
5435 hr
= IDirect3DDeviceImpl_7_GetViewport(iface
, Data
);
5436 set_fpu_control_word(old_fpucw
);
5441 /*****************************************************************************
5442 * IDirect3DDevice7::SetMaterial
5449 * Mat: The material to set
5453 * DDERR_INVALIDPARAMS if Mat is NULL.
5454 * For more details, see IWineD3DDevice::SetMaterial
5456 *****************************************************************************/
5458 IDirect3DDeviceImpl_7_SetMaterial(IDirect3DDevice7
*iface
,
5461 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5463 TRACE("(%p)->(%p): Relay!\n", This
, Mat
);
5465 if (!Mat
) return DDERR_INVALIDPARAMS
;
5466 /* Note: D3DMATERIAL7 is compatible with WINED3DMATERIAL */
5467 EnterCriticalSection(&ddraw_cs
);
5468 hr
= IWineD3DDevice_SetMaterial(This
->wineD3DDevice
,
5469 (WINED3DMATERIAL
*) Mat
);
5470 LeaveCriticalSection(&ddraw_cs
);
5471 return hr_ddraw_from_wined3d(hr
);
5474 static HRESULT WINAPI
5475 IDirect3DDeviceImpl_7_SetMaterial_FPUSetup(IDirect3DDevice7
*iface
,
5478 return IDirect3DDeviceImpl_7_SetMaterial(iface
, Mat
);
5481 static HRESULT WINAPI
5482 IDirect3DDeviceImpl_7_SetMaterial_FPUPreserve(IDirect3DDevice7
*iface
,
5488 old_fpucw
= d3d_fpu_setup();
5489 hr
= IDirect3DDeviceImpl_7_SetMaterial(iface
, Mat
);
5490 set_fpu_control_word(old_fpucw
);
5495 /*****************************************************************************
5496 * IDirect3DDevice7::GetMaterial
5498 * Returns the current material
5503 * Mat: D3DMATERIAL7 structure to write the material parameters to
5507 * DDERR_INVALIDPARAMS if Mat is NULL
5508 * For more details, see IWineD3DDevice::GetMaterial
5510 *****************************************************************************/
5512 IDirect3DDeviceImpl_7_GetMaterial(IDirect3DDevice7
*iface
,
5515 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5517 TRACE("(%p)->(%p): Relay!\n", This
, Mat
);
5519 EnterCriticalSection(&ddraw_cs
);
5520 /* Note: D3DMATERIAL7 is compatible with WINED3DMATERIAL */
5521 hr
= IWineD3DDevice_GetMaterial(This
->wineD3DDevice
,
5522 (WINED3DMATERIAL
*) Mat
);
5523 LeaveCriticalSection(&ddraw_cs
);
5524 return hr_ddraw_from_wined3d(hr
);
5527 static HRESULT WINAPI
5528 IDirect3DDeviceImpl_7_GetMaterial_FPUSetup(IDirect3DDevice7
*iface
,
5531 return IDirect3DDeviceImpl_7_GetMaterial(iface
, Mat
);
5534 static HRESULT WINAPI
5535 IDirect3DDeviceImpl_7_GetMaterial_FPUPreserve(IDirect3DDevice7
*iface
,
5541 old_fpucw
= d3d_fpu_setup();
5542 hr
= IDirect3DDeviceImpl_7_GetMaterial(iface
, Mat
);
5543 set_fpu_control_word(old_fpucw
);
5548 /*****************************************************************************
5549 * IDirect3DDevice7::SetLight
5551 * Assigns a light to a light index, but doesn't activate it yet.
5553 * Version 7, IDirect3DLight uses this method for older versions
5556 * LightIndex: The index of the new light
5557 * Light: A D3DLIGHT7 structure describing the light
5561 * For more details, see IWineD3DDevice::SetLight
5563 *****************************************************************************/
5565 IDirect3DDeviceImpl_7_SetLight(IDirect3DDevice7
*iface
,
5569 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5571 TRACE("(%p)->(%08x,%p): Relay!\n", This
, LightIndex
, Light
);
5573 EnterCriticalSection(&ddraw_cs
);
5574 /* Note: D3DLIGHT7 is compatible with WINED3DLIGHT */
5575 hr
= IWineD3DDevice_SetLight(This
->wineD3DDevice
,
5577 (WINED3DLIGHT
*) Light
);
5578 LeaveCriticalSection(&ddraw_cs
);
5579 return hr_ddraw_from_wined3d(hr
);
5582 static HRESULT WINAPI
5583 IDirect3DDeviceImpl_7_SetLight_FPUSetup(IDirect3DDevice7
*iface
,
5587 return IDirect3DDeviceImpl_7_SetLight(iface
, LightIndex
, Light
);
5590 static HRESULT WINAPI
5591 IDirect3DDeviceImpl_7_SetLight_FPUPreserve(IDirect3DDevice7
*iface
,
5598 old_fpucw
= d3d_fpu_setup();
5599 hr
= IDirect3DDeviceImpl_7_SetLight(iface
, LightIndex
, Light
);
5600 set_fpu_control_word(old_fpucw
);
5605 /*****************************************************************************
5606 * IDirect3DDevice7::GetLight
5608 * Returns the light assigned to a light index
5611 * Light: Structure to write the light information to
5615 * DDERR_INVALIDPARAMS if Light is NULL
5616 * For details, see IWineD3DDevice::GetLight
5618 *****************************************************************************/
5620 IDirect3DDeviceImpl_7_GetLight(IDirect3DDevice7
*iface
,
5624 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5626 TRACE("(%p)->(%08x,%p): Relay!\n", This
, LightIndex
, Light
);
5628 EnterCriticalSection(&ddraw_cs
);
5629 /* Note: D3DLIGHT7 is compatible with WINED3DLIGHT */
5630 rc
= IWineD3DDevice_GetLight(This
->wineD3DDevice
,
5632 (WINED3DLIGHT
*) Light
);
5634 /* Translate the result. WineD3D returns other values than D3D7 */
5635 LeaveCriticalSection(&ddraw_cs
);
5636 return hr_ddraw_from_wined3d(rc
);
5639 static HRESULT WINAPI
5640 IDirect3DDeviceImpl_7_GetLight_FPUSetup(IDirect3DDevice7
*iface
,
5644 return IDirect3DDeviceImpl_7_GetLight(iface
, LightIndex
, Light
);
5647 static HRESULT WINAPI
5648 IDirect3DDeviceImpl_7_GetLight_FPUPreserve(IDirect3DDevice7
*iface
,
5655 old_fpucw
= d3d_fpu_setup();
5656 hr
= IDirect3DDeviceImpl_7_GetLight(iface
, LightIndex
, Light
);
5657 set_fpu_control_word(old_fpucw
);
5662 /*****************************************************************************
5663 * IDirect3DDevice7::BeginStateBlock
5665 * Begins recording to a stateblock
5671 * For details see IWineD3DDevice::BeginStateBlock
5673 *****************************************************************************/
5675 IDirect3DDeviceImpl_7_BeginStateBlock(IDirect3DDevice7
*iface
)
5677 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5679 TRACE("(%p)->(): Relay!\n", This
);
5681 EnterCriticalSection(&ddraw_cs
);
5682 hr
= IWineD3DDevice_BeginStateBlock(This
->wineD3DDevice
);
5683 LeaveCriticalSection(&ddraw_cs
);
5684 return hr_ddraw_from_wined3d(hr
);
5687 static HRESULT WINAPI
5688 IDirect3DDeviceImpl_7_BeginStateBlock_FPUSetup(IDirect3DDevice7
*iface
)
5690 return IDirect3DDeviceImpl_7_BeginStateBlock(iface
);
5693 static HRESULT WINAPI
5694 IDirect3DDeviceImpl_7_BeginStateBlock_FPUPreserve(IDirect3DDevice7
*iface
)
5699 old_fpucw
= d3d_fpu_setup();
5700 hr
= IDirect3DDeviceImpl_7_BeginStateBlock(iface
);
5701 set_fpu_control_word(old_fpucw
);
5706 /*****************************************************************************
5707 * IDirect3DDevice7::EndStateBlock
5709 * Stops recording to a state block and returns the created stateblock
5715 * BlockHandle: Address to store the stateblock's handle to
5719 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5720 * See IWineD3DDevice::EndStateBlock for more details
5722 *****************************************************************************/
5724 IDirect3DDeviceImpl_7_EndStateBlock(IDirect3DDevice7
*iface
,
5727 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5729 TRACE("(%p)->(%p): Relay!\n", This
, BlockHandle
);
5733 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
5734 return DDERR_INVALIDPARAMS
;
5737 EnterCriticalSection(&ddraw_cs
);
5738 *BlockHandle
= IDirect3DDeviceImpl_CreateHandle(This
);
5741 ERR("Cannot get a handle number for the stateblock\n");
5742 LeaveCriticalSection(&ddraw_cs
);
5743 return DDERR_OUTOFMEMORY
;
5745 This
->Handles
[*BlockHandle
- 1].type
= DDrawHandle_StateBlock
;
5746 hr
= IWineD3DDevice_EndStateBlock(This
->wineD3DDevice
,
5747 (IWineD3DStateBlock
**) &This
->Handles
[*BlockHandle
- 1].ptr
);
5748 LeaveCriticalSection(&ddraw_cs
);
5749 return hr_ddraw_from_wined3d(hr
);
5752 static HRESULT WINAPI
5753 IDirect3DDeviceImpl_7_EndStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5756 return IDirect3DDeviceImpl_7_EndStateBlock(iface
, BlockHandle
);
5759 static HRESULT WINAPI
5760 IDirect3DDeviceImpl_7_EndStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5766 old_fpucw
= d3d_fpu_setup();
5767 hr
= IDirect3DDeviceImpl_7_EndStateBlock(iface
, BlockHandle
);
5768 set_fpu_control_word(old_fpucw
);
5773 /*****************************************************************************
5774 * IDirect3DDevice7::PreLoad
5776 * Allows the app to signal that a texture will be used soon, to allow
5777 * the Direct3DDevice to load it to the video card in the meantime.
5782 * Texture: The texture to preload
5786 * DDERR_INVALIDPARAMS if Texture is NULL
5787 * See IWineD3DSurface::PreLoad for details
5789 *****************************************************************************/
5791 IDirect3DDeviceImpl_7_PreLoad(IDirect3DDevice7
*iface
,
5792 IDirectDrawSurface7
*Texture
)
5794 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5795 IDirectDrawSurfaceImpl
*surf
= (IDirectDrawSurfaceImpl
*)Texture
;
5797 TRACE("(%p)->(%p): Relay!\n", This
, surf
);
5800 return DDERR_INVALIDPARAMS
;
5802 EnterCriticalSection(&ddraw_cs
);
5803 IWineD3DSurface_PreLoad(surf
->WineD3DSurface
);
5804 LeaveCriticalSection(&ddraw_cs
);
5808 static HRESULT WINAPI
5809 IDirect3DDeviceImpl_7_PreLoad_FPUSetup(IDirect3DDevice7
*iface
,
5810 IDirectDrawSurface7
*Texture
)
5812 return IDirect3DDeviceImpl_7_PreLoad(iface
, Texture
);
5815 static HRESULT WINAPI
5816 IDirect3DDeviceImpl_7_PreLoad_FPUPreserve(IDirect3DDevice7
*iface
,
5817 IDirectDrawSurface7
*Texture
)
5822 old_fpucw
= d3d_fpu_setup();
5823 hr
= IDirect3DDeviceImpl_7_PreLoad(iface
, Texture
);
5824 set_fpu_control_word(old_fpucw
);
5829 /*****************************************************************************
5830 * IDirect3DDevice7::ApplyStateBlock
5832 * Activates the state stored in a state block handle.
5835 * BlockHandle: The stateblock handle to activate
5839 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5841 *****************************************************************************/
5843 IDirect3DDeviceImpl_7_ApplyStateBlock(IDirect3DDevice7
*iface
,
5846 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5848 TRACE("(%p)->(%08x): Relay!\n", This
, BlockHandle
);
5850 EnterCriticalSection(&ddraw_cs
);
5851 if(!BlockHandle
|| BlockHandle
> This
->numHandles
)
5853 WARN("Out of range handle %d, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle
);
5854 LeaveCriticalSection(&ddraw_cs
);
5855 return D3DERR_INVALIDSTATEBLOCK
;
5857 if(This
->Handles
[BlockHandle
- 1].type
!= DDrawHandle_StateBlock
)
5859 WARN("Handle %d is not a stateblock, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle
);
5860 LeaveCriticalSection(&ddraw_cs
);
5861 return D3DERR_INVALIDSTATEBLOCK
;
5864 hr
= IWineD3DStateBlock_Apply((IWineD3DStateBlock
*) This
->Handles
[BlockHandle
- 1].ptr
);
5865 LeaveCriticalSection(&ddraw_cs
);
5866 return hr_ddraw_from_wined3d(hr
);
5869 static HRESULT WINAPI
5870 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5873 return IDirect3DDeviceImpl_7_ApplyStateBlock(iface
, BlockHandle
);
5876 static HRESULT WINAPI
5877 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5883 old_fpucw
= d3d_fpu_setup();
5884 hr
= IDirect3DDeviceImpl_7_ApplyStateBlock(iface
, BlockHandle
);
5885 set_fpu_control_word(old_fpucw
);
5890 /*****************************************************************************
5891 * IDirect3DDevice7::CaptureStateBlock
5893 * Updates a stateblock's values to the values currently set for the device
5898 * BlockHandle: Stateblock to update
5902 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5903 * See IWineD3DDevice::CaptureStateBlock for more details
5905 *****************************************************************************/
5907 IDirect3DDeviceImpl_7_CaptureStateBlock(IDirect3DDevice7
*iface
,
5910 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5912 TRACE("(%p)->(%08x): Relay!\n", This
, BlockHandle
);
5914 EnterCriticalSection(&ddraw_cs
);
5915 if(BlockHandle
== 0 || BlockHandle
> This
->numHandles
)
5917 WARN("Out of range handle %d, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle
);
5918 LeaveCriticalSection(&ddraw_cs
);
5919 return D3DERR_INVALIDSTATEBLOCK
;
5921 if(This
->Handles
[BlockHandle
- 1].type
!= DDrawHandle_StateBlock
)
5923 WARN("Handle %d is not a stateblock, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle
);
5924 LeaveCriticalSection(&ddraw_cs
);
5925 return D3DERR_INVALIDSTATEBLOCK
;
5928 hr
= IWineD3DStateBlock_Capture((IWineD3DStateBlock
*) This
->Handles
[BlockHandle
- 1].ptr
);
5929 LeaveCriticalSection(&ddraw_cs
);
5930 return hr_ddraw_from_wined3d(hr
);
5933 static HRESULT WINAPI
5934 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5937 return IDirect3DDeviceImpl_7_CaptureStateBlock(iface
, BlockHandle
);
5940 static HRESULT WINAPI
5941 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5947 old_fpucw
= d3d_fpu_setup();
5948 hr
= IDirect3DDeviceImpl_7_CaptureStateBlock(iface
, BlockHandle
);
5949 set_fpu_control_word(old_fpucw
);
5954 /*****************************************************************************
5955 * IDirect3DDevice7::DeleteStateBlock
5957 * Deletes a stateblock handle. This means releasing the WineD3DStateBlock
5962 * BlockHandle: Stateblock handle to delete
5966 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is 0
5968 *****************************************************************************/
5970 IDirect3DDeviceImpl_7_DeleteStateBlock(IDirect3DDevice7
*iface
,
5973 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5975 TRACE("(%p)->(%08x): Relay!\n", This
, BlockHandle
);
5977 EnterCriticalSection(&ddraw_cs
);
5978 if(BlockHandle
== 0 || BlockHandle
> This
->numHandles
)
5980 WARN("Out of range handle %d, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle
);
5981 LeaveCriticalSection(&ddraw_cs
);
5982 return D3DERR_INVALIDSTATEBLOCK
;
5984 if(This
->Handles
[BlockHandle
- 1].type
!= DDrawHandle_StateBlock
)
5986 WARN("Handle %d is not a stateblock, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle
);
5987 LeaveCriticalSection(&ddraw_cs
);
5988 return D3DERR_INVALIDSTATEBLOCK
;
5991 ref
= IWineD3DStateBlock_Release((IWineD3DStateBlock
*) This
->Handles
[BlockHandle
- 1].ptr
);
5994 ERR("Something is still holding the stateblock %p(Handle %d). Ref = %d\n", This
->Handles
[BlockHandle
- 1].ptr
, BlockHandle
, ref
);
5996 This
->Handles
[BlockHandle
- 1].ptr
= NULL
;
5997 This
->Handles
[BlockHandle
- 1].type
= DDrawHandle_Unknown
;
5999 LeaveCriticalSection(&ddraw_cs
);
6003 static HRESULT WINAPI
6004 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
6007 return IDirect3DDeviceImpl_7_DeleteStateBlock(iface
, BlockHandle
);
6010 static HRESULT WINAPI
6011 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
6017 old_fpucw
= d3d_fpu_setup();
6018 hr
= IDirect3DDeviceImpl_7_DeleteStateBlock(iface
, BlockHandle
);
6019 set_fpu_control_word(old_fpucw
);
6024 /*****************************************************************************
6025 * IDirect3DDevice7::CreateStateBlock
6027 * Creates a new state block handle.
6032 * Type: The state block type
6033 * BlockHandle: Address to write the created handle to
6037 * DDERR_INVALIDPARAMS if BlockHandle is NULL
6039 *****************************************************************************/
6041 IDirect3DDeviceImpl_7_CreateStateBlock(IDirect3DDevice7
*iface
,
6042 D3DSTATEBLOCKTYPE Type
,
6045 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
6047 TRACE("(%p)->(%08x,%p)!\n", This
, Type
, BlockHandle
);
6051 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
6052 return DDERR_INVALIDPARAMS
;
6054 if(Type
!= D3DSBT_ALL
&& Type
!= D3DSBT_PIXELSTATE
&&
6055 Type
!= D3DSBT_VERTEXSTATE
) {
6056 WARN("Unexpected stateblock type, returning DDERR_INVALIDPARAMS\n");
6057 return DDERR_INVALIDPARAMS
;
6060 EnterCriticalSection(&ddraw_cs
);
6061 *BlockHandle
= IDirect3DDeviceImpl_CreateHandle(This
);
6064 ERR("Cannot get a handle number for the stateblock\n");
6065 LeaveCriticalSection(&ddraw_cs
);
6066 return DDERR_OUTOFMEMORY
;
6068 This
->Handles
[*BlockHandle
- 1].type
= DDrawHandle_StateBlock
;
6070 /* The D3DSTATEBLOCKTYPE enum is fine here */
6071 hr
= IWineD3DDevice_CreateStateBlock(This
->wineD3DDevice
,
6073 (IWineD3DStateBlock
**) &This
->Handles
[*BlockHandle
- 1].ptr
,
6074 NULL
/* Parent, hope that works */);
6075 LeaveCriticalSection(&ddraw_cs
);
6076 return hr_ddraw_from_wined3d(hr
);
6079 static HRESULT WINAPI
6080 IDirect3DDeviceImpl_7_CreateStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
6081 D3DSTATEBLOCKTYPE Type
,
6084 return IDirect3DDeviceImpl_7_CreateStateBlock(iface
, Type
, BlockHandle
);
6087 static HRESULT WINAPI
6088 IDirect3DDeviceImpl_7_CreateStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
6089 D3DSTATEBLOCKTYPE Type
,
6095 old_fpucw
= d3d_fpu_setup();
6096 hr
=IDirect3DDeviceImpl_7_CreateStateBlock(iface
, Type
, BlockHandle
);
6097 set_fpu_control_word(old_fpucw
);
6102 /* Helper function for IDirect3DDeviceImpl_7_Load. */
6103 static BOOL
is_mip_level_subset(IDirectDrawSurfaceImpl
*dest
,
6104 IDirectDrawSurfaceImpl
*src
)
6106 IDirectDrawSurfaceImpl
*src_level
, *dest_level
;
6107 IDirectDrawSurface7
*temp
;
6108 DDSURFACEDESC2 ddsd
;
6109 BOOL levelFound
; /* at least one suitable sublevel in dest found */
6111 /* To satisfy "destination is mip level subset of source" criteria (regular texture counts as 1 level),
6112 * 1) there must be at least one mip level in destination that matched dimensions of some mip level in source and
6113 * 2) there must be no destination levels that don't match any levels in source. Otherwise it's INVALIDPARAMS.
6120 for (;src_level
&& dest_level
;)
6122 if (src_level
->surface_desc
.dwWidth
== dest_level
->surface_desc
.dwWidth
&&
6123 src_level
->surface_desc
.dwHeight
== dest_level
->surface_desc
.dwHeight
)
6127 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6128 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
6129 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7
*)dest_level
, &ddsd
.ddsCaps
, &temp
);
6131 if (dest_level
!= dest
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)dest_level
);
6133 dest_level
= (IDirectDrawSurfaceImpl
*)temp
;
6136 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6137 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
6138 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7
*)src_level
, &ddsd
.ddsCaps
, &temp
);
6140 if (src_level
!= src
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)src_level
);
6142 src_level
= (IDirectDrawSurfaceImpl
*)temp
;
6145 if (src_level
&& src_level
!= src
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)src_level
);
6146 if (dest_level
&& dest_level
!= dest
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)dest_level
);
6148 return !dest_level
&& levelFound
;
6151 /* Helper function for IDirect3DDeviceImpl_7_Load. */
6152 static void copy_mipmap_chain(IDirect3DDeviceImpl
*device
,
6153 IDirectDrawSurfaceImpl
*dest
,
6154 IDirectDrawSurfaceImpl
*src
,
6158 IDirectDrawSurfaceImpl
*src_level
, *dest_level
;
6159 IDirectDrawSurface7
*temp
;
6160 DDSURFACEDESC2 ddsd
;
6164 IDirectDrawPalette
*pal
= NULL
, *pal_src
= NULL
;
6167 BOOL palette_missing
= FALSE
;
6169 /* Copy palette, if possible. */
6170 IDirectDrawSurface7_GetPalette((IDirectDrawSurface7
*)src
, &pal_src
);
6171 IDirectDrawSurface7_GetPalette((IDirectDrawSurface7
*)dest
, &pal
);
6173 if (pal_src
!= NULL
&& pal
!= NULL
)
6175 PALETTEENTRY palent
[256];
6177 IDirectDrawPalette_GetEntries(pal_src
, 0, 0, 256, palent
);
6178 IDirectDrawPalette_SetEntries(pal
, 0, 0, 256, palent
);
6181 if (dest
->surface_desc
.u4
.ddpfPixelFormat
.dwFlags
& (DDPF_PALETTEINDEXED1
| DDPF_PALETTEINDEXED2
|
6182 DDPF_PALETTEINDEXED4
| DDPF_PALETTEINDEXED8
| DDPF_PALETTEINDEXEDTO8
) && !pal
)
6184 palette_missing
= TRUE
;
6187 if (pal
) IDirectDrawPalette_Release(pal
);
6188 if (pal_src
) IDirectDrawPalette_Release(pal_src
);
6190 /* Copy colorkeys, if present. */
6191 for (ckeyflag
= DDCKEY_DESTBLT
; ckeyflag
<= DDCKEY_SRCOVERLAY
; ckeyflag
<<= 1)
6193 hr
= IDirectDrawSurface7_GetColorKey((IDirectDrawSurface7
*)src
, ckeyflag
, &ddckey
);
6197 IDirectDrawSurface7_SetColorKey((IDirectDrawSurface7
*)dest
, ckeyflag
, &ddckey
);
6207 for (;src_level
&& dest_level
;)
6209 if (src_level
->surface_desc
.dwWidth
== dest_level
->surface_desc
.dwWidth
&&
6210 src_level
->surface_desc
.dwHeight
== dest_level
->surface_desc
.dwHeight
)
6212 /* Try UpdateSurface that may perform a more direct opengl loading. But skip this if destination is paletted texture and has no palette.
6213 * Some games like Sacrifice set palette after Load, and it is a waste of effort to try to load texture without palette and generates
6214 * warnings in wined3d. */
6215 if (!palette_missing
)
6216 hr
= IWineD3DDevice_UpdateSurface(device
->wineD3DDevice
, src_level
->WineD3DSurface
, &rect
, dest_level
->WineD3DSurface
,
6219 if (palette_missing
|| FAILED(hr
))
6221 /* UpdateSurface may fail e.g. if dest is in system memory. Fall back to BltFast that is less strict. */
6222 IWineD3DSurface_BltFast(dest_level
->WineD3DSurface
,
6224 src_level
->WineD3DSurface
, &rect
, 0);
6227 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6228 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
6229 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7
*)dest_level
, &ddsd
.ddsCaps
, &temp
);
6231 if (dest_level
!= dest
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)dest_level
);
6233 dest_level
= (IDirectDrawSurfaceImpl
*)temp
;
6236 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6237 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
6238 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7
*)src_level
, &ddsd
.ddsCaps
, &temp
);
6240 if (src_level
!= src
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)src_level
);
6242 src_level
= (IDirectDrawSurfaceImpl
*)temp
;
6249 rect
.right
= (rect
.right
+ 1) / 2;
6250 rect
.bottom
= (rect
.bottom
+ 1) / 2;
6253 if (src_level
&& src_level
!= src
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)src_level
);
6254 if (dest_level
&& dest_level
!= dest
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)dest_level
);
6257 /*****************************************************************************
6258 * IDirect3DDevice7::Load
6260 * Loads a rectangular area from the source into the destination texture.
6261 * It can also copy the source to the faces of a cubic environment map
6266 * DestTex: Destination texture
6267 * DestPoint: Point in the destination where the source image should be
6269 * SrcTex: Source texture
6270 * SrcRect: Source rectangle
6271 * Flags: Cubemap faces to load (DDSCAPS2_CUBEMAP_ALLFACES, DDSCAPS2_CUBEMAP_POSITIVEX,
6272 * DDSCAPS2_CUBEMAP_NEGATIVEX, DDSCAPS2_CUBEMAP_POSITIVEY, DDSCAPS2_CUBEMAP_NEGATIVEY,
6273 * DDSCAPS2_CUBEMAP_POSITIVEZ, DDSCAPS2_CUBEMAP_NEGATIVEZ)
6277 * DDERR_INVALIDPARAMS if DestTex or SrcTex are NULL, broken coordinates or anything unexpected.
6280 *****************************************************************************/
6283 IDirect3DDeviceImpl_7_Load(IDirect3DDevice7
*iface
,
6284 IDirectDrawSurface7
*DestTex
,
6286 IDirectDrawSurface7
*SrcTex
,
6290 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
6291 IDirectDrawSurfaceImpl
*dest
= (IDirectDrawSurfaceImpl
*)DestTex
;
6292 IDirectDrawSurfaceImpl
*src
= (IDirectDrawSurfaceImpl
*)SrcTex
;
6295 TRACE("(%p)->(%p,%p,%p,%p,%08x)\n", This
, dest
, DestPoint
, src
, SrcRect
, Flags
);
6297 if( (!src
) || (!dest
) )
6298 return DDERR_INVALIDPARAMS
;
6300 EnterCriticalSection(&ddraw_cs
);
6302 if (SrcRect
) srcrect
= *SrcRect
;
6305 srcrect
.left
= srcrect
.top
= 0;
6306 srcrect
.right
= src
->surface_desc
.dwWidth
;
6307 srcrect
.bottom
= src
->surface_desc
.dwHeight
;
6310 if (DestPoint
) destpoint
= *DestPoint
;
6313 destpoint
.x
= destpoint
.y
= 0;
6315 /* Check bad dimensions. DestPoint is validated against src, not dest, because
6316 * destination can be a subset of mip levels, in which case actual coordinates used
6317 * for it may be divided. If any dimension of dest is larger than source, it can't be
6318 * mip level subset, so an error can be returned early.
6320 if (srcrect
.left
>= srcrect
.right
|| srcrect
.top
>= srcrect
.bottom
||
6321 srcrect
.right
> src
->surface_desc
.dwWidth
||
6322 srcrect
.bottom
> src
->surface_desc
.dwHeight
||
6323 destpoint
.x
+ srcrect
.right
- srcrect
.left
> src
->surface_desc
.dwWidth
||
6324 destpoint
.y
+ srcrect
.bottom
- srcrect
.top
> src
->surface_desc
.dwHeight
||
6325 dest
->surface_desc
.dwWidth
> src
->surface_desc
.dwWidth
||
6326 dest
->surface_desc
.dwHeight
> src
->surface_desc
.dwHeight
)
6328 LeaveCriticalSection(&ddraw_cs
);
6329 return DDERR_INVALIDPARAMS
;
6332 /* Must be top level surfaces. */
6333 if (src
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_MIPMAPSUBLEVEL
||
6334 dest
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_MIPMAPSUBLEVEL
)
6336 LeaveCriticalSection(&ddraw_cs
);
6337 return DDERR_INVALIDPARAMS
;
6340 if (src
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
)
6342 DWORD src_face_flag
, dest_face_flag
;
6343 IDirectDrawSurfaceImpl
*src_face
, *dest_face
;
6344 IDirectDrawSurface7
*temp
;
6345 DDSURFACEDESC2 ddsd
;
6348 if (!(dest
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
))
6350 LeaveCriticalSection(&ddraw_cs
);
6351 return DDERR_INVALIDPARAMS
;
6354 /* Iterate through cube faces 2 times. First time is just to check INVALIDPARAMS conditions, second
6355 * time it's actual surface loading. */
6356 for (i
= 0; i
< 2; i
++)
6361 for (;dest_face
&& src_face
;)
6363 src_face_flag
= src_face
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP_ALLFACES
;
6364 dest_face_flag
= dest_face
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP_ALLFACES
;
6366 if (src_face_flag
== dest_face_flag
)
6370 /* Destination mip levels must be subset of source mip levels. */
6371 if (!is_mip_level_subset(dest_face
, src_face
))
6373 LeaveCriticalSection(&ddraw_cs
);
6374 return DDERR_INVALIDPARAMS
;
6377 else if (Flags
& dest_face_flag
)
6379 copy_mipmap_chain(This
, dest_face
, src_face
, &destpoint
, &srcrect
);
6382 if (src_face_flag
< DDSCAPS2_CUBEMAP_NEGATIVEZ
)
6384 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6385 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_CUBEMAP
| (src_face_flag
<< 1);
6386 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7
*)src
, &ddsd
.ddsCaps
, &temp
);
6388 if (src_face
!= src
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)src_face
);
6390 src_face
= (IDirectDrawSurfaceImpl
*)temp
;
6394 if (src_face
!= src
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)src_face
);
6400 if (dest_face_flag
< DDSCAPS2_CUBEMAP_NEGATIVEZ
)
6402 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6403 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_CUBEMAP
| (dest_face_flag
<< 1);
6404 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7
*)dest
, &ddsd
.ddsCaps
, &temp
);
6406 if (dest_face
!= dest
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)dest_face
);
6408 dest_face
= (IDirectDrawSurfaceImpl
*)temp
;
6412 if (dest_face
!= dest
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)dest_face
);
6420 /* Native returns error if src faces are not subset of dest faces. */
6423 LeaveCriticalSection(&ddraw_cs
);
6424 return DDERR_INVALIDPARAMS
;
6429 LeaveCriticalSection(&ddraw_cs
);
6432 else if (dest
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
)
6434 LeaveCriticalSection(&ddraw_cs
);
6435 return DDERR_INVALIDPARAMS
;
6438 /* Handle non cube map textures. */
6440 /* Destination mip levels must be subset of source mip levels. */
6441 if (!is_mip_level_subset(dest
, src
))
6443 LeaveCriticalSection(&ddraw_cs
);
6444 return DDERR_INVALIDPARAMS
;
6447 copy_mipmap_chain(This
, dest
, src
, &destpoint
, &srcrect
);
6449 LeaveCriticalSection(&ddraw_cs
);
6453 static HRESULT WINAPI
6454 IDirect3DDeviceImpl_7_Load_FPUSetup(IDirect3DDevice7
*iface
,
6455 IDirectDrawSurface7
*DestTex
,
6457 IDirectDrawSurface7
*SrcTex
,
6461 return IDirect3DDeviceImpl_7_Load(iface
, DestTex
, DestPoint
, SrcTex
, SrcRect
, Flags
);
6464 static HRESULT WINAPI
6465 IDirect3DDeviceImpl_7_Load_FPUPreserve(IDirect3DDevice7
*iface
,
6466 IDirectDrawSurface7
*DestTex
,
6468 IDirectDrawSurface7
*SrcTex
,
6475 old_fpucw
= d3d_fpu_setup();
6476 hr
= IDirect3DDeviceImpl_7_Load(iface
, DestTex
, DestPoint
, SrcTex
, SrcRect
, Flags
);
6477 set_fpu_control_word(old_fpucw
);
6482 /*****************************************************************************
6483 * IDirect3DDevice7::LightEnable
6485 * Enables or disables a light
6487 * Version 7, IDirect3DLight uses this method too.
6490 * LightIndex: The index of the light to enable / disable
6491 * Enable: Enable or disable the light
6495 * For more details, see IWineD3DDevice::SetLightEnable
6497 *****************************************************************************/
6499 IDirect3DDeviceImpl_7_LightEnable(IDirect3DDevice7
*iface
,
6503 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
6505 TRACE("(%p)->(%08x,%d): Relay!\n", This
, LightIndex
, Enable
);
6507 EnterCriticalSection(&ddraw_cs
);
6508 hr
= IWineD3DDevice_SetLightEnable(This
->wineD3DDevice
, LightIndex
, Enable
);
6509 LeaveCriticalSection(&ddraw_cs
);
6510 return hr_ddraw_from_wined3d(hr
);
6513 static HRESULT WINAPI
6514 IDirect3DDeviceImpl_7_LightEnable_FPUSetup(IDirect3DDevice7
*iface
,
6518 return IDirect3DDeviceImpl_7_LightEnable(iface
, LightIndex
, Enable
);
6521 static HRESULT WINAPI
6522 IDirect3DDeviceImpl_7_LightEnable_FPUPreserve(IDirect3DDevice7
*iface
,
6529 old_fpucw
= d3d_fpu_setup();
6530 hr
= IDirect3DDeviceImpl_7_LightEnable(iface
, LightIndex
, Enable
);
6531 set_fpu_control_word(old_fpucw
);
6536 /*****************************************************************************
6537 * IDirect3DDevice7::GetLightEnable
6539 * Retrieves if the light with the given index is enabled or not
6544 * LightIndex: Index of desired light
6545 * Enable: Pointer to a BOOL which contains the result
6549 * DDERR_INVALIDPARAMS if Enable is NULL
6550 * See IWineD3DDevice::GetLightEnable for more details
6552 *****************************************************************************/
6554 IDirect3DDeviceImpl_7_GetLightEnable(IDirect3DDevice7
*iface
,
6558 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
6560 TRACE("(%p)->(%08x,%p): Relay\n", This
, LightIndex
, Enable
);
6563 return DDERR_INVALIDPARAMS
;
6565 EnterCriticalSection(&ddraw_cs
);
6566 hr
= IWineD3DDevice_GetLightEnable(This
->wineD3DDevice
, LightIndex
, Enable
);
6567 LeaveCriticalSection(&ddraw_cs
);
6568 return hr_ddraw_from_wined3d(hr
);
6571 static HRESULT WINAPI
6572 IDirect3DDeviceImpl_7_GetLightEnable_FPUSetup(IDirect3DDevice7
*iface
,
6576 return IDirect3DDeviceImpl_7_GetLightEnable(iface
, LightIndex
, Enable
);
6579 static HRESULT WINAPI
6580 IDirect3DDeviceImpl_7_GetLightEnable_FPUPreserve(IDirect3DDevice7
*iface
,
6587 old_fpucw
= d3d_fpu_setup();
6588 hr
= IDirect3DDeviceImpl_7_GetLightEnable(iface
, LightIndex
, Enable
);
6589 set_fpu_control_word(old_fpucw
);
6594 /*****************************************************************************
6595 * IDirect3DDevice7::SetClipPlane
6597 * Sets custom clipping plane
6602 * Index: The index of the clipping plane
6603 * PlaneEquation: An equation defining the clipping plane
6607 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6608 * See IWineD3DDevice::SetClipPlane for more details
6610 *****************************************************************************/
6612 IDirect3DDeviceImpl_7_SetClipPlane(IDirect3DDevice7
*iface
,
6614 D3DVALUE
* PlaneEquation
)
6616 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
6618 TRACE("(%p)->(%08x,%p): Relay!\n", This
, Index
, PlaneEquation
);
6621 return DDERR_INVALIDPARAMS
;
6623 EnterCriticalSection(&ddraw_cs
);
6624 hr
= IWineD3DDevice_SetClipPlane(This
->wineD3DDevice
, Index
, PlaneEquation
);
6625 LeaveCriticalSection(&ddraw_cs
);
6629 static HRESULT WINAPI
6630 IDirect3DDeviceImpl_7_SetClipPlane_FPUSetup(IDirect3DDevice7
*iface
,
6632 D3DVALUE
* PlaneEquation
)
6634 return IDirect3DDeviceImpl_7_SetClipPlane(iface
, Index
, PlaneEquation
);
6637 static HRESULT WINAPI
6638 IDirect3DDeviceImpl_7_SetClipPlane_FPUPreserve(IDirect3DDevice7
*iface
,
6640 D3DVALUE
* PlaneEquation
)
6645 old_fpucw
= d3d_fpu_setup();
6646 hr
= IDirect3DDeviceImpl_7_SetClipPlane(iface
, Index
, PlaneEquation
);
6647 set_fpu_control_word(old_fpucw
);
6652 /*****************************************************************************
6653 * IDirect3DDevice7::GetClipPlane
6655 * Returns the clipping plane with a specific index
6658 * Index: The index of the desired plane
6659 * PlaneEquation: Address to store the plane equation to
6663 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6664 * See IWineD3DDevice::GetClipPlane for more details
6666 *****************************************************************************/
6668 IDirect3DDeviceImpl_7_GetClipPlane(IDirect3DDevice7
*iface
,
6670 D3DVALUE
* PlaneEquation
)
6672 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
6674 TRACE("(%p)->(%d,%p): Relay!\n", This
, Index
, PlaneEquation
);
6677 return DDERR_INVALIDPARAMS
;
6679 EnterCriticalSection(&ddraw_cs
);
6680 hr
= IWineD3DDevice_GetClipPlane(This
->wineD3DDevice
, Index
, PlaneEquation
);
6681 LeaveCriticalSection(&ddraw_cs
);
6685 static HRESULT WINAPI
6686 IDirect3DDeviceImpl_7_GetClipPlane_FPUSetup(IDirect3DDevice7
*iface
,
6688 D3DVALUE
* PlaneEquation
)
6690 return IDirect3DDeviceImpl_7_GetClipPlane(iface
, Index
, PlaneEquation
);
6693 static HRESULT WINAPI
6694 IDirect3DDeviceImpl_7_GetClipPlane_FPUPreserve(IDirect3DDevice7
*iface
,
6696 D3DVALUE
* PlaneEquation
)
6701 old_fpucw
= d3d_fpu_setup();
6702 hr
= IDirect3DDeviceImpl_7_GetClipPlane(iface
, Index
, PlaneEquation
);
6703 set_fpu_control_word(old_fpucw
);
6708 /*****************************************************************************
6709 * IDirect3DDevice7::GetInfo
6711 * Retrieves some information about the device. The DirectX sdk says that
6712 * this version returns S_FALSE for all retail builds of DirectX, that's what
6713 * this implementation does.
6716 * DevInfoID: Information type requested
6717 * DevInfoStruct: Pointer to a structure to store the info to
6718 * Size: Size of the structure
6721 * S_FALSE, because it's a non-debug driver
6723 *****************************************************************************/
6724 static HRESULT WINAPI
6725 IDirect3DDeviceImpl_7_GetInfo(IDirect3DDevice7
*iface
,
6727 void *DevInfoStruct
,
6730 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
6731 TRACE("(%p)->(%08x,%p,%08x)\n", This
, DevInfoID
, DevInfoStruct
, Size
);
6735 TRACE(" info requested : ");
6738 case D3DDEVINFOID_TEXTUREMANAGER
: TRACE("D3DDEVINFOID_TEXTUREMANAGER\n"); break;
6739 case D3DDEVINFOID_D3DTEXTUREMANAGER
: TRACE("D3DDEVINFOID_D3DTEXTUREMANAGER\n"); break;
6740 case D3DDEVINFOID_TEXTURING
: TRACE("D3DDEVINFOID_TEXTURING\n"); break;
6741 default: ERR(" invalid flag !!!\n"); return DDERR_INVALIDPARAMS
;
6745 return S_FALSE
; /* According to MSDN, this is valid for a non-debug driver */
6748 /* For performance optimization, devices created in FPUSETUP and FPUPRESERVE modes
6749 * have separate vtables. Simple functions where this doesn't matter like GetDirect3D
6750 * are not duplicated.
6752 * Device created with DDSCL_FPUSETUP (d3d7 default) - device methods assume that FPU
6753 * has already been setup for optimal d3d operation.
6755 * Device created with DDSCL_FPUPRESERVE - resets and restores FPU mode when necessary in
6756 * d3d calls (FPU may be in a mode non-suitable for d3d when the app calls d3d). Required
6757 * by Sacrifice (game). */
6758 const IDirect3DDevice7Vtbl IDirect3DDevice7_FPUSetup_Vtbl
=
6760 /*** IUnknown Methods ***/
6761 IDirect3DDeviceImpl_7_QueryInterface
,
6762 IDirect3DDeviceImpl_7_AddRef
,
6763 IDirect3DDeviceImpl_7_Release
,
6764 /*** IDirect3DDevice7 ***/
6765 IDirect3DDeviceImpl_7_GetCaps_FPUSetup
,
6766 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUSetup
,
6767 IDirect3DDeviceImpl_7_BeginScene_FPUSetup
,
6768 IDirect3DDeviceImpl_7_EndScene_FPUSetup
,
6769 IDirect3DDeviceImpl_7_GetDirect3D
,
6770 IDirect3DDeviceImpl_7_SetRenderTarget_FPUSetup
,
6771 IDirect3DDeviceImpl_7_GetRenderTarget
,
6772 IDirect3DDeviceImpl_7_Clear_FPUSetup
,
6773 IDirect3DDeviceImpl_7_SetTransform_FPUSetup
,
6774 IDirect3DDeviceImpl_7_GetTransform_FPUSetup
,
6775 IDirect3DDeviceImpl_7_SetViewport_FPUSetup
,
6776 IDirect3DDeviceImpl_7_MultiplyTransform_FPUSetup
,
6777 IDirect3DDeviceImpl_7_GetViewport_FPUSetup
,
6778 IDirect3DDeviceImpl_7_SetMaterial_FPUSetup
,
6779 IDirect3DDeviceImpl_7_GetMaterial_FPUSetup
,
6780 IDirect3DDeviceImpl_7_SetLight_FPUSetup
,
6781 IDirect3DDeviceImpl_7_GetLight_FPUSetup
,
6782 IDirect3DDeviceImpl_7_SetRenderState_FPUSetup
,
6783 IDirect3DDeviceImpl_7_GetRenderState_FPUSetup
,
6784 IDirect3DDeviceImpl_7_BeginStateBlock_FPUSetup
,
6785 IDirect3DDeviceImpl_7_EndStateBlock_FPUSetup
,
6786 IDirect3DDeviceImpl_7_PreLoad_FPUSetup
,
6787 IDirect3DDeviceImpl_7_DrawPrimitive_FPUSetup
,
6788 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUSetup
,
6789 IDirect3DDeviceImpl_7_SetClipStatus
,
6790 IDirect3DDeviceImpl_7_GetClipStatus
,
6791 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUSetup
,
6792 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUSetup
,
6793 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUSetup
,
6794 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUSetup
,
6795 IDirect3DDeviceImpl_7_ComputeSphereVisibility
,
6796 IDirect3DDeviceImpl_7_GetTexture_FPUSetup
,
6797 IDirect3DDeviceImpl_7_SetTexture_FPUSetup
,
6798 IDirect3DDeviceImpl_7_GetTextureStageState_FPUSetup
,
6799 IDirect3DDeviceImpl_7_SetTextureStageState_FPUSetup
,
6800 IDirect3DDeviceImpl_7_ValidateDevice_FPUSetup
,
6801 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUSetup
,
6802 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUSetup
,
6803 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUSetup
,
6804 IDirect3DDeviceImpl_7_CreateStateBlock_FPUSetup
,
6805 IDirect3DDeviceImpl_7_Load_FPUSetup
,
6806 IDirect3DDeviceImpl_7_LightEnable_FPUSetup
,
6807 IDirect3DDeviceImpl_7_GetLightEnable_FPUSetup
,
6808 IDirect3DDeviceImpl_7_SetClipPlane_FPUSetup
,
6809 IDirect3DDeviceImpl_7_GetClipPlane_FPUSetup
,
6810 IDirect3DDeviceImpl_7_GetInfo
6813 const IDirect3DDevice7Vtbl IDirect3DDevice7_FPUPreserve_Vtbl
=
6815 /*** IUnknown Methods ***/
6816 IDirect3DDeviceImpl_7_QueryInterface
,
6817 IDirect3DDeviceImpl_7_AddRef
,
6818 IDirect3DDeviceImpl_7_Release
,
6819 /*** IDirect3DDevice7 ***/
6820 IDirect3DDeviceImpl_7_GetCaps_FPUPreserve
,
6821 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUPreserve
,
6822 IDirect3DDeviceImpl_7_BeginScene_FPUPreserve
,
6823 IDirect3DDeviceImpl_7_EndScene_FPUPreserve
,
6824 IDirect3DDeviceImpl_7_GetDirect3D
,
6825 IDirect3DDeviceImpl_7_SetRenderTarget_FPUPreserve
,
6826 IDirect3DDeviceImpl_7_GetRenderTarget
,
6827 IDirect3DDeviceImpl_7_Clear_FPUPreserve
,
6828 IDirect3DDeviceImpl_7_SetTransform_FPUPreserve
,
6829 IDirect3DDeviceImpl_7_GetTransform_FPUPreserve
,
6830 IDirect3DDeviceImpl_7_SetViewport_FPUPreserve
,
6831 IDirect3DDeviceImpl_7_MultiplyTransform_FPUPreserve
,
6832 IDirect3DDeviceImpl_7_GetViewport_FPUPreserve
,
6833 IDirect3DDeviceImpl_7_SetMaterial_FPUPreserve
,
6834 IDirect3DDeviceImpl_7_GetMaterial_FPUPreserve
,
6835 IDirect3DDeviceImpl_7_SetLight_FPUPreserve
,
6836 IDirect3DDeviceImpl_7_GetLight_FPUPreserve
,
6837 IDirect3DDeviceImpl_7_SetRenderState_FPUPreserve
,
6838 IDirect3DDeviceImpl_7_GetRenderState_FPUPreserve
,
6839 IDirect3DDeviceImpl_7_BeginStateBlock_FPUPreserve
,
6840 IDirect3DDeviceImpl_7_EndStateBlock_FPUPreserve
,
6841 IDirect3DDeviceImpl_7_PreLoad_FPUPreserve
,
6842 IDirect3DDeviceImpl_7_DrawPrimitive_FPUPreserve
,
6843 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUPreserve
,
6844 IDirect3DDeviceImpl_7_SetClipStatus
,
6845 IDirect3DDeviceImpl_7_GetClipStatus
,
6846 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUPreserve
,
6847 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUPreserve
,
6848 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUPreserve
,
6849 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUPreserve
,
6850 IDirect3DDeviceImpl_7_ComputeSphereVisibility
,
6851 IDirect3DDeviceImpl_7_GetTexture_FPUPreserve
,
6852 IDirect3DDeviceImpl_7_SetTexture_FPUPreserve
,
6853 IDirect3DDeviceImpl_7_GetTextureStageState_FPUPreserve
,
6854 IDirect3DDeviceImpl_7_SetTextureStageState_FPUPreserve
,
6855 IDirect3DDeviceImpl_7_ValidateDevice_FPUPreserve
,
6856 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUPreserve
,
6857 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUPreserve
,
6858 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUPreserve
,
6859 IDirect3DDeviceImpl_7_CreateStateBlock_FPUPreserve
,
6860 IDirect3DDeviceImpl_7_Load_FPUPreserve
,
6861 IDirect3DDeviceImpl_7_LightEnable_FPUPreserve
,
6862 IDirect3DDeviceImpl_7_GetLightEnable_FPUPreserve
,
6863 IDirect3DDeviceImpl_7_SetClipPlane_FPUPreserve
,
6864 IDirect3DDeviceImpl_7_GetClipPlane_FPUPreserve
,
6865 IDirect3DDeviceImpl_7_GetInfo
6868 const IDirect3DDevice3Vtbl IDirect3DDevice3_Vtbl
=
6870 /*** IUnknown Methods ***/
6871 Thunk_IDirect3DDeviceImpl_3_QueryInterface
,
6872 Thunk_IDirect3DDeviceImpl_3_AddRef
,
6873 Thunk_IDirect3DDeviceImpl_3_Release
,
6874 /*** IDirect3DDevice3 ***/
6875 IDirect3DDeviceImpl_3_GetCaps
,
6876 IDirect3DDeviceImpl_3_GetStats
,
6877 IDirect3DDeviceImpl_3_AddViewport
,
6878 IDirect3DDeviceImpl_3_DeleteViewport
,
6879 IDirect3DDeviceImpl_3_NextViewport
,
6880 Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats
,
6881 Thunk_IDirect3DDeviceImpl_3_BeginScene
,
6882 Thunk_IDirect3DDeviceImpl_3_EndScene
,
6883 Thunk_IDirect3DDeviceImpl_3_GetDirect3D
,
6884 IDirect3DDeviceImpl_3_SetCurrentViewport
,
6885 IDirect3DDeviceImpl_3_GetCurrentViewport
,
6886 Thunk_IDirect3DDeviceImpl_3_SetRenderTarget
,
6887 Thunk_IDirect3DDeviceImpl_3_GetRenderTarget
,
6888 IDirect3DDeviceImpl_3_Begin
,
6889 IDirect3DDeviceImpl_3_BeginIndexed
,
6890 IDirect3DDeviceImpl_3_Vertex
,
6891 IDirect3DDeviceImpl_3_Index
,
6892 IDirect3DDeviceImpl_3_End
,
6893 IDirect3DDeviceImpl_3_GetRenderState
,
6894 IDirect3DDeviceImpl_3_SetRenderState
,
6895 IDirect3DDeviceImpl_3_GetLightState
,
6896 IDirect3DDeviceImpl_3_SetLightState
,
6897 Thunk_IDirect3DDeviceImpl_3_SetTransform
,
6898 Thunk_IDirect3DDeviceImpl_3_GetTransform
,
6899 Thunk_IDirect3DDeviceImpl_3_MultiplyTransform
,
6900 Thunk_IDirect3DDeviceImpl_3_DrawPrimitive
,
6901 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive
,
6902 Thunk_IDirect3DDeviceImpl_3_SetClipStatus
,
6903 Thunk_IDirect3DDeviceImpl_3_GetClipStatus
,
6904 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided
,
6905 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided
,
6906 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB
,
6907 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB
,
6908 Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility
,
6909 Thunk_IDirect3DDeviceImpl_3_GetTexture
,
6910 IDirect3DDeviceImpl_3_SetTexture
,
6911 Thunk_IDirect3DDeviceImpl_3_GetTextureStageState
,
6912 Thunk_IDirect3DDeviceImpl_3_SetTextureStageState
,
6913 Thunk_IDirect3DDeviceImpl_3_ValidateDevice
6916 const IDirect3DDevice2Vtbl IDirect3DDevice2_Vtbl
=
6918 /*** IUnknown Methods ***/
6919 Thunk_IDirect3DDeviceImpl_2_QueryInterface
,
6920 Thunk_IDirect3DDeviceImpl_2_AddRef
,
6921 Thunk_IDirect3DDeviceImpl_2_Release
,
6922 /*** IDirect3DDevice2 ***/
6923 Thunk_IDirect3DDeviceImpl_2_GetCaps
,
6924 IDirect3DDeviceImpl_2_SwapTextureHandles
,
6925 Thunk_IDirect3DDeviceImpl_2_GetStats
,
6926 Thunk_IDirect3DDeviceImpl_2_AddViewport
,
6927 Thunk_IDirect3DDeviceImpl_2_DeleteViewport
,
6928 Thunk_IDirect3DDeviceImpl_2_NextViewport
,
6929 IDirect3DDeviceImpl_2_EnumTextureFormats
,
6930 Thunk_IDirect3DDeviceImpl_2_BeginScene
,
6931 Thunk_IDirect3DDeviceImpl_2_EndScene
,
6932 Thunk_IDirect3DDeviceImpl_2_GetDirect3D
,
6933 Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport
,
6934 Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport
,
6935 Thunk_IDirect3DDeviceImpl_2_SetRenderTarget
,
6936 Thunk_IDirect3DDeviceImpl_2_GetRenderTarget
,
6937 Thunk_IDirect3DDeviceImpl_2_Begin
,
6938 Thunk_IDirect3DDeviceImpl_2_BeginIndexed
,
6939 Thunk_IDirect3DDeviceImpl_2_Vertex
,
6940 Thunk_IDirect3DDeviceImpl_2_Index
,
6941 Thunk_IDirect3DDeviceImpl_2_End
,
6942 Thunk_IDirect3DDeviceImpl_2_GetRenderState
,
6943 Thunk_IDirect3DDeviceImpl_2_SetRenderState
,
6944 Thunk_IDirect3DDeviceImpl_2_GetLightState
,
6945 Thunk_IDirect3DDeviceImpl_2_SetLightState
,
6946 Thunk_IDirect3DDeviceImpl_2_SetTransform
,
6947 Thunk_IDirect3DDeviceImpl_2_GetTransform
,
6948 Thunk_IDirect3DDeviceImpl_2_MultiplyTransform
,
6949 Thunk_IDirect3DDeviceImpl_2_DrawPrimitive
,
6950 Thunk_IDirect3DDeviceImpl_2_DrawIndexedPrimitive
,
6951 Thunk_IDirect3DDeviceImpl_2_SetClipStatus
,
6952 Thunk_IDirect3DDeviceImpl_2_GetClipStatus
6955 const IDirect3DDeviceVtbl IDirect3DDevice1_Vtbl
=
6957 /*** IUnknown Methods ***/
6958 Thunk_IDirect3DDeviceImpl_1_QueryInterface
,
6959 Thunk_IDirect3DDeviceImpl_1_AddRef
,
6960 Thunk_IDirect3DDeviceImpl_1_Release
,
6961 /*** IDirect3DDevice1 ***/
6962 IDirect3DDeviceImpl_1_Initialize
,
6963 Thunk_IDirect3DDeviceImpl_1_GetCaps
,
6964 Thunk_IDirect3DDeviceImpl_1_SwapTextureHandles
,
6965 IDirect3DDeviceImpl_1_CreateExecuteBuffer
,
6966 Thunk_IDirect3DDeviceImpl_1_GetStats
,
6967 IDirect3DDeviceImpl_1_Execute
,
6968 Thunk_IDirect3DDeviceImpl_1_AddViewport
,
6969 Thunk_IDirect3DDeviceImpl_1_DeleteViewport
,
6970 Thunk_IDirect3DDeviceImpl_1_NextViewport
,
6971 IDirect3DDeviceImpl_1_Pick
,
6972 IDirect3DDeviceImpl_1_GetPickRecords
,
6973 Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats
,
6974 IDirect3DDeviceImpl_1_CreateMatrix
,
6975 IDirect3DDeviceImpl_1_SetMatrix
,
6976 IDirect3DDeviceImpl_1_GetMatrix
,
6977 IDirect3DDeviceImpl_1_DeleteMatrix
,
6978 Thunk_IDirect3DDeviceImpl_1_BeginScene
,
6979 Thunk_IDirect3DDeviceImpl_1_EndScene
,
6980 Thunk_IDirect3DDeviceImpl_1_GetDirect3D
6983 /*****************************************************************************
6984 * IDirect3DDeviceImpl_CreateHandle
6986 * Not called from the VTable
6988 * Some older interface versions operate with handles, which are basically
6989 * DWORDs which identify an interface, for example
6990 * IDirect3DDevice::SetRenderState with DIRECT3DRENDERSTATE_TEXTUREHANDLE
6992 * Those handle could be just casts to the interface pointers or vice versa,
6993 * but that is not 64 bit safe and would mean blindly derefering a DWORD
6994 * passed by the app. Instead there is a dynamic array in the device which
6995 * keeps a DWORD to pointer information and a type for the handle.
6997 * Basically this array only grows, when a handle is freed its pointer is
6998 * just set to NULL. There will be much more reads from the array than
6999 * insertion operations, so a dynamic array is fine.
7002 * This: D3DDevice implementation for which this handle should be created
7005 * A free handle on success
7008 *****************************************************************************/
7010 IDirect3DDeviceImpl_CreateHandle(IDirect3DDeviceImpl
*This
)
7013 struct HandleEntry
*oldHandles
= This
->Handles
;
7015 TRACE("(%p)\n", This
);
7017 for(i
= 0; i
< This
->numHandles
; i
++)
7019 if(This
->Handles
[i
].ptr
== NULL
&&
7020 This
->Handles
[i
].type
== DDrawHandle_Unknown
)
7022 TRACE("Reusing freed handle %d\n", i
+ 1);
7027 TRACE("Growing the handle array\n");
7030 This
->Handles
= HeapAlloc(GetProcessHeap(), 0, sizeof(struct HandleEntry
) * This
->numHandles
);
7033 ERR("Out of memory\n");
7034 This
->Handles
= oldHandles
;
7040 memcpy(This
->Handles
, oldHandles
, (This
->numHandles
- 1) * sizeof(struct HandleEntry
));
7041 HeapFree(GetProcessHeap(), 0, oldHandles
);
7044 TRACE("Returning %d\n", This
->numHandles
);
7045 return This
->numHandles
;
7048 /*****************************************************************************
7049 * IDirect3DDeviceImpl_UpdateDepthStencil
7051 * Checks the current render target for attached depth stencils and sets the
7052 * WineD3D depth stencil accordingly.
7055 * The depth stencil state to set if creating the device
7057 *****************************************************************************/
7059 IDirect3DDeviceImpl_UpdateDepthStencil(IDirect3DDeviceImpl
*This
)
7061 IDirectDrawSurface7
*depthStencil
= NULL
;
7062 IDirectDrawSurfaceImpl
*dsi
;
7063 static DDSCAPS2 depthcaps
= { DDSCAPS_ZBUFFER
, 0, 0, 0 };
7065 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7
*)This
->target
, &depthcaps
, &depthStencil
);
7068 TRACE("Setting wined3d depth stencil to NULL\n");
7069 IWineD3DDevice_SetDepthStencilSurface(This
->wineD3DDevice
,
7071 return WINED3DZB_FALSE
;
7074 dsi
= (IDirectDrawSurfaceImpl
*)depthStencil
;
7075 TRACE("Setting wined3d depth stencil to %p (wined3d %p)\n", dsi
, dsi
->WineD3DSurface
);
7076 IWineD3DDevice_SetDepthStencilSurface(This
->wineD3DDevice
,
7077 dsi
->WineD3DSurface
);
7079 IDirectDrawSurface7_Release(depthStencil
);
7080 return WINED3DZB_TRUE
;