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_SetIndexBuffer(This
->wineD3DDevice
, NULL
, WINED3DFMT_UNKNOWN
);
320 IWineD3DBuffer_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
,
353 /* This->target is the offscreen target.
354 * This->ddraw->d3d_target is the target used by DDraw
356 TRACE("(%p) Release: Using %p as front buffer, %p as back buffer\n", This
, This
->ddraw
->d3d_target
, NULL
);
357 IWineD3DDevice_SetFrontBackBuffers(This
->wineD3DDevice
,
358 This
->ddraw
->d3d_target
->WineD3DSurface
,
362 /* Release the WineD3DDevice. This won't destroy it */
363 if(IWineD3DDevice_Release(This
->wineD3DDevice
) <= 0)
365 ERR(" (%p) The wineD3D device %p was destroyed unexpectedly. Prepare for trouble\n", This
, This
->wineD3DDevice
);
368 /* The texture handles should be unset by now, but there might be some bits
369 * missing in our reference counting(needs test). Do a sanity check
371 for(i
= 0; i
< This
->numHandles
; i
++)
373 if(This
->Handles
[i
].ptr
)
375 switch(This
->Handles
[i
].type
)
377 case DDrawHandle_Texture
:
379 IDirectDrawSurfaceImpl
*surf
= This
->Handles
[i
].ptr
;
380 FIXME("Texture Handle %d not unset properly\n", i
+ 1);
385 case DDrawHandle_Material
:
387 IDirect3DMaterialImpl
*mat
= This
->Handles
[i
].ptr
;
388 FIXME("Material handle %d not unset properly\n", i
+ 1);
393 case DDrawHandle_Matrix
:
395 /* No fixme here because this might happen because of sloppy apps */
396 WARN("Leftover matrix handle %d, deleting\n", i
+ 1);
397 IDirect3DDevice_DeleteMatrix((IDirect3DDevice
*)&This
->IDirect3DDevice_vtbl
, i
+ 1);
401 case DDrawHandle_StateBlock
:
403 /* No fixme here because this might happen because of sloppy apps */
404 WARN("Leftover stateblock handle %d, deleting\n", i
+ 1);
405 IDirect3DDevice7_DeleteStateBlock((IDirect3DDevice7
*)This
, i
+ 1);
410 FIXME("Unknown handle %d not unset properly\n", i
+ 1);
415 HeapFree(GetProcessHeap(), 0, This
->Handles
);
417 TRACE("Releasing target %p %p\n", This
->target
, This
->ddraw
->d3d_target
);
418 /* Release the render target and the WineD3D render target
419 * (See IDirect3D7::CreateDevice for more comments on this)
421 IDirectDrawSurface7_Release((IDirectDrawSurface7
*)This
->target
);
422 IDirectDrawSurface7_Release((IDirectDrawSurface7
*)This
->ddraw
->d3d_target
);
423 TRACE("Target release done\n");
425 This
->ddraw
->d3ddevice
= NULL
;
427 /* Now free the structure */
428 HeapFree(GetProcessHeap(), 0, This
);
429 LeaveCriticalSection(&ddraw_cs
);
437 Thunk_IDirect3DDeviceImpl_3_Release(IDirect3DDevice3
*iface
)
439 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
440 TRACE_(ddraw_thunk
)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This
);
441 return IDirect3DDevice7_Release((IDirect3DDevice7
*)This
);
445 Thunk_IDirect3DDeviceImpl_2_Release(IDirect3DDevice2
*iface
)
447 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
448 TRACE_(ddraw_thunk
)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This
);
449 return IDirect3DDevice7_Release((IDirect3DDevice7
*)This
);
453 Thunk_IDirect3DDeviceImpl_1_Release(IDirect3DDevice
*iface
)
455 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
456 TRACE_(ddraw_thunk
)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This
);
457 return IDirect3DDevice7_Release((IDirect3DDevice7
*)This
);
460 /*****************************************************************************
461 * IDirect3DDevice Methods
462 *****************************************************************************/
464 /*****************************************************************************
465 * IDirect3DDevice::Initialize
467 * Initializes a Direct3DDevice. This implementation is a no-op, as all
468 * initialization is done at create time.
470 * Exists in Version 1
473 * No idea what they mean, as the MSDN page is gone
477 *****************************************************************************/
478 static HRESULT WINAPI
479 IDirect3DDeviceImpl_1_Initialize(IDirect3DDevice
*iface
,
480 IDirect3D
*Direct3D
, GUID
*guid
,
483 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
485 /* It shouldn't be crucial, but print a FIXME, I'm interested if
486 * any game calls it and when
488 FIXME("(%p)->(%p,%p,%p): No-op!\n", This
, Direct3D
, guid
, Desc
);
493 /*****************************************************************************
494 * IDirect3DDevice7::GetCaps
496 * Retrieves the device's capabilities
498 * This implementation is used for Version 7 only, the older versions have
499 * their own implementation.
502 * Desc: Pointer to a D3DDEVICEDESC7 structure to fill
506 * D3DERR_* if a problem occurs. See WineD3D
508 *****************************************************************************/
510 IDirect3DDeviceImpl_7_GetCaps(IDirect3DDevice7
*iface
,
511 D3DDEVICEDESC7
*Desc
)
513 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
514 D3DDEVICEDESC OldDesc
;
515 TRACE("(%p)->(%p)\n", This
, Desc
);
517 /* Call the same function used by IDirect3D, this saves code */
518 return IDirect3DImpl_GetCaps(This
->ddraw
->wineD3D
, &OldDesc
, Desc
);
521 static HRESULT WINAPI
522 IDirect3DDeviceImpl_7_GetCaps_FPUSetup(IDirect3DDevice7
*iface
,
523 D3DDEVICEDESC7
*Desc
)
525 return IDirect3DDeviceImpl_7_GetCaps(iface
, Desc
);
528 static HRESULT WINAPI
529 IDirect3DDeviceImpl_7_GetCaps_FPUPreserve(IDirect3DDevice7
*iface
,
530 D3DDEVICEDESC7
*Desc
)
535 old_fpucw
= d3d_fpu_setup();
536 hr
= IDirect3DDeviceImpl_7_GetCaps(iface
, Desc
);
537 set_fpu_control_word(old_fpucw
);
541 /*****************************************************************************
542 * IDirect3DDevice3::GetCaps
544 * Retrieves the capabilities of the hardware device and the emulation
545 * device. For Wine, hardware and emulation are the same (it's all HW).
547 * This implementation is used for Version 1, 2, and 3. Version 7 has its own
550 * HWDesc: Structure to fill with the HW caps
551 * HelDesc: Structure to fill with the hardware emulation caps
555 * D3DERR_* if a problem occurs. See WineD3D
557 *****************************************************************************/
558 static HRESULT WINAPI
559 IDirect3DDeviceImpl_3_GetCaps(IDirect3DDevice3
*iface
,
560 D3DDEVICEDESC
*HWDesc
,
561 D3DDEVICEDESC
*HelDesc
)
563 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
564 D3DDEVICEDESC7 newDesc
;
566 TRACE("(%p)->(%p,%p)\n", iface
, HWDesc
, HelDesc
);
568 hr
= IDirect3DImpl_GetCaps(This
->ddraw
->wineD3D
, HWDesc
, &newDesc
);
569 if(hr
!= D3D_OK
) return hr
;
575 static HRESULT WINAPI
576 Thunk_IDirect3DDeviceImpl_2_GetCaps(IDirect3DDevice2
*iface
,
577 D3DDEVICEDESC
*D3DHWDevDesc
,
578 D3DDEVICEDESC
*D3DHELDevDesc
)
580 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
581 TRACE_(ddraw_thunk
)("(%p)->(%p,%p) thunking to IDirect3DDevice3 interface.\n", This
, D3DHWDevDesc
, D3DHELDevDesc
);
582 return IDirect3DDevice3_GetCaps((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, D3DHWDevDesc
, D3DHELDevDesc
);
585 static HRESULT WINAPI
586 Thunk_IDirect3DDeviceImpl_1_GetCaps(IDirect3DDevice
*iface
,
587 D3DDEVICEDESC
*D3DHWDevDesc
,
588 D3DDEVICEDESC
*D3DHELDevDesc
)
590 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
591 TRACE_(ddraw_thunk
)("(%p)->(%p,%p) thunking to IDirect3DDevice3 interface.\n", This
, D3DHWDevDesc
, D3DHELDevDesc
);
592 return IDirect3DDevice3_GetCaps((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, D3DHWDevDesc
, D3DHELDevDesc
);
595 /*****************************************************************************
596 * IDirect3DDevice2::SwapTextureHandles
598 * Swaps the texture handles of 2 Texture interfaces. Version 1 and 2
601 * Tex1, Tex2: The 2 Textures to swap
606 *****************************************************************************/
607 static HRESULT WINAPI
608 IDirect3DDeviceImpl_2_SwapTextureHandles(IDirect3DDevice2
*iface
,
609 IDirect3DTexture2
*Tex1
,
610 IDirect3DTexture2
*Tex2
)
612 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
614 IDirectDrawSurfaceImpl
*surf1
= surface_from_texture2(Tex1
);
615 IDirectDrawSurfaceImpl
*surf2
= surface_from_texture2(Tex2
);
616 TRACE("(%p)->(%p,%p)\n", This
, surf1
, surf2
);
618 EnterCriticalSection(&ddraw_cs
);
619 This
->Handles
[surf1
->Handle
- 1].ptr
= surf2
;
620 This
->Handles
[surf2
->Handle
- 1].ptr
= surf1
;
622 swap
= surf2
->Handle
;
623 surf2
->Handle
= surf1
->Handle
;
624 surf1
->Handle
= swap
;
625 LeaveCriticalSection(&ddraw_cs
);
630 static HRESULT WINAPI
631 Thunk_IDirect3DDeviceImpl_1_SwapTextureHandles(IDirect3DDevice
*iface
,
632 IDirect3DTexture
*D3DTex1
,
633 IDirect3DTexture
*D3DTex2
)
635 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
636 IDirectDrawSurfaceImpl
*surf1
= surface_from_texture1(D3DTex1
);
637 IDirectDrawSurfaceImpl
*surf2
= surface_from_texture1(D3DTex2
);
638 IDirect3DTexture2
*t1
= surf1
? (IDirect3DTexture2
*)&surf1
->IDirect3DTexture2_vtbl
: NULL
;
639 IDirect3DTexture2
*t2
= surf2
? (IDirect3DTexture2
*)&surf2
->IDirect3DTexture2_vtbl
: NULL
;
640 TRACE_(ddraw_thunk
)("(%p)->(%p,%p) thunking to IDirect3DDevice2 interface.\n", This
, surf1
, surf2
);
641 return IDirect3DDevice2_SwapTextureHandles((IDirect3DDevice2
*)&This
->IDirect3DDevice2_vtbl
, t1
, t2
);
644 /*****************************************************************************
645 * IDirect3DDevice3::GetStats
647 * This method seems to retrieve some stats from the device.
648 * The MSDN documentation doesn't exist any more, but the D3DSTATS
649 * structure suggests that the amount of drawn primitives and processed
650 * vertices is returned.
652 * Exists in Version 1, 2 and 3
655 * Stats: Pointer to a D3DSTATS structure to be filled
659 * DDERR_INVALIDPARAMS if Stats == NULL
661 *****************************************************************************/
662 static HRESULT WINAPI
663 IDirect3DDeviceImpl_3_GetStats(IDirect3DDevice3
*iface
,
666 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
667 FIXME("(%p)->(%p): Stub!\n", This
, Stats
);
670 return DDERR_INVALIDPARAMS
;
672 /* Fill the Stats with 0 */
673 Stats
->dwTrianglesDrawn
= 0;
674 Stats
->dwLinesDrawn
= 0;
675 Stats
->dwPointsDrawn
= 0;
676 Stats
->dwSpansDrawn
= 0;
677 Stats
->dwVerticesProcessed
= 0;
682 static HRESULT WINAPI
683 Thunk_IDirect3DDeviceImpl_2_GetStats(IDirect3DDevice2
*iface
,
686 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
687 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This
, Stats
);
688 return IDirect3DDevice3_GetStats((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, Stats
);
691 static HRESULT WINAPI
692 Thunk_IDirect3DDeviceImpl_1_GetStats(IDirect3DDevice
*iface
,
695 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
696 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This
, Stats
);
697 return IDirect3DDevice3_GetStats((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, Stats
);
700 /*****************************************************************************
701 * IDirect3DDevice::CreateExecuteBuffer
703 * Creates an IDirect3DExecuteBuffer, used for rendering with a
709 * Desc: Buffer description
710 * ExecuteBuffer: Address to return the Interface pointer at
711 * UnkOuter: Must be NULL. Basically for aggregation, which ddraw doesn't
715 * CLASS_E_NOAGGREGATION if UnkOuter != NULL
716 * DDERR_OUTOFMEMORY if we ran out of memory
719 *****************************************************************************/
720 static HRESULT WINAPI
721 IDirect3DDeviceImpl_1_CreateExecuteBuffer(IDirect3DDevice
*iface
,
722 D3DEXECUTEBUFFERDESC
*Desc
,
723 IDirect3DExecuteBuffer
**ExecuteBuffer
,
726 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
727 IDirect3DExecuteBufferImpl
* object
;
728 TRACE("(%p)->(%p,%p,%p)!\n", This
, Desc
, ExecuteBuffer
, UnkOuter
);
731 return CLASS_E_NOAGGREGATION
;
733 /* Allocate the new Execute Buffer */
734 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirect3DExecuteBufferImpl
));
737 ERR("Out of memory when allocating a IDirect3DExecuteBufferImpl structure\n");
738 return DDERR_OUTOFMEMORY
;
741 object
->lpVtbl
= &IDirect3DExecuteBuffer_Vtbl
;
743 object
->d3ddev
= This
;
745 /* Initializes memory */
746 memcpy(&object
->desc
, Desc
, Desc
->dwSize
);
748 /* No buffer given */
749 if ((object
->desc
.dwFlags
& D3DDEB_LPDATA
) == 0)
750 object
->desc
.lpData
= NULL
;
752 /* No buffer size given */
753 if ((object
->desc
.dwFlags
& D3DDEB_BUFSIZE
) == 0)
754 object
->desc
.dwBufferSize
= 0;
756 /* Create buffer if asked */
757 if ((object
->desc
.lpData
== NULL
) && (object
->desc
.dwBufferSize
> 0))
759 object
->need_free
= TRUE
;
760 object
->desc
.lpData
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,object
->desc
.dwBufferSize
);
761 if(!object
->desc
.lpData
)
763 ERR("Out of memory when allocating the execute buffer data\n");
764 HeapFree(GetProcessHeap(), 0, object
);
765 return DDERR_OUTOFMEMORY
;
770 object
->need_free
= FALSE
;
773 /* No vertices for the moment */
774 object
->vertex_data
= NULL
;
776 object
->desc
.dwFlags
|= D3DDEB_LPDATA
;
778 object
->indices
= NULL
;
779 object
->nb_indices
= 0;
781 *ExecuteBuffer
= (IDirect3DExecuteBuffer
*)object
;
783 TRACE(" Returning IDirect3DExecuteBuffer at %p, implementation is at %p\n", *ExecuteBuffer
, object
);
788 /*****************************************************************************
789 * IDirect3DDevice::Execute
791 * Executes all the stuff in an execute buffer.
794 * ExecuteBuffer: The buffer to execute
795 * Viewport: The viewport used for rendering
799 * DDERR_INVALIDPARAMS if ExecuteBuffer == NULL
802 *****************************************************************************/
803 static HRESULT WINAPI
804 IDirect3DDeviceImpl_1_Execute(IDirect3DDevice
*iface
,
805 IDirect3DExecuteBuffer
*ExecuteBuffer
,
806 IDirect3DViewport
*Viewport
,
809 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
810 IDirect3DExecuteBufferImpl
*Direct3DExecuteBufferImpl
= (IDirect3DExecuteBufferImpl
*)ExecuteBuffer
;
811 IDirect3DViewportImpl
*Direct3DViewportImpl
= (IDirect3DViewportImpl
*)Viewport
;
813 TRACE("(%p)->(%p,%p,%08x)\n", This
, Direct3DExecuteBufferImpl
, Direct3DViewportImpl
, Flags
);
815 if(!Direct3DExecuteBufferImpl
)
816 return DDERR_INVALIDPARAMS
;
819 EnterCriticalSection(&ddraw_cs
);
820 IDirect3DExecuteBufferImpl_Execute(Direct3DExecuteBufferImpl
, This
, Direct3DViewportImpl
);
821 LeaveCriticalSection(&ddraw_cs
);
826 /*****************************************************************************
827 * IDirect3DDevice3::AddViewport
829 * Add a Direct3DViewport to the device's viewport list. These viewports
830 * are wrapped to IDirect3DDevice7 viewports in viewport.c
832 * Exists in Version 1, 2 and 3. Note that IDirect3DViewport 1, 2 and 3
833 * are the same interfaces.
836 * Viewport: The viewport to add
839 * DDERR_INVALIDPARAMS if Viewport == NULL
842 *****************************************************************************/
843 static HRESULT WINAPI
844 IDirect3DDeviceImpl_3_AddViewport(IDirect3DDevice3
*iface
,
845 IDirect3DViewport3
*Viewport
)
847 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
848 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*)Viewport
;
850 TRACE("(%p)->(%p)\n", This
, vp
);
854 return DDERR_INVALIDPARAMS
;
856 EnterCriticalSection(&ddraw_cs
);
857 vp
->next
= This
->viewport_list
;
858 This
->viewport_list
= vp
;
859 vp
->active_device
= This
; /* Viewport must be usable for Clear() after AddViewport,
860 so set active_device here. */
861 LeaveCriticalSection(&ddraw_cs
);
866 static HRESULT WINAPI
867 Thunk_IDirect3DDeviceImpl_2_AddViewport(IDirect3DDevice2
*iface
,
868 IDirect3DViewport2
*Direct3DViewport2
)
870 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
871 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*)Direct3DViewport2
;
872 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This
, vp
);
873 return IDirect3DDevice3_AddViewport((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, (IDirect3DViewport3
*)vp
);
876 static HRESULT WINAPI
877 Thunk_IDirect3DDeviceImpl_1_AddViewport(IDirect3DDevice
*iface
,
878 IDirect3DViewport
*Direct3DViewport
)
880 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
881 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*)Direct3DViewport
;
882 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This
, vp
);
883 return IDirect3DDevice3_AddViewport((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, (IDirect3DViewport3
*)vp
);
886 /*****************************************************************************
887 * IDirect3DDevice3::DeleteViewport
889 * Deletes a Direct3DViewport from the device's viewport list.
891 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
895 * Viewport: The viewport to delete
899 * DDERR_INVALIDPARAMS if the viewport wasn't found in the list
901 *****************************************************************************/
902 static HRESULT WINAPI
903 IDirect3DDeviceImpl_3_DeleteViewport(IDirect3DDevice3
*iface
,
904 IDirect3DViewport3
*Viewport
)
906 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
907 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*) Viewport
;
908 IDirect3DViewportImpl
*cur_viewport
, *prev_viewport
= NULL
;
910 TRACE("(%p)->(%p)\n", This
, vp
);
912 EnterCriticalSection(&ddraw_cs
);
913 cur_viewport
= This
->viewport_list
;
914 while (cur_viewport
!= NULL
)
916 if (cur_viewport
== vp
)
918 if (prev_viewport
== NULL
) This
->viewport_list
= cur_viewport
->next
;
919 else prev_viewport
->next
= cur_viewport
->next
;
920 /* TODO : add desactivate of the viewport and all associated lights... */
921 LeaveCriticalSection(&ddraw_cs
);
924 prev_viewport
= cur_viewport
;
925 cur_viewport
= cur_viewport
->next
;
928 LeaveCriticalSection(&ddraw_cs
);
929 return DDERR_INVALIDPARAMS
;
932 static HRESULT WINAPI
933 Thunk_IDirect3DDeviceImpl_2_DeleteViewport(IDirect3DDevice2
*iface
,
934 IDirect3DViewport2
*Direct3DViewport2
)
936 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
937 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*)Direct3DViewport2
;
938 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This
, vp
);
939 return IDirect3DDevice3_DeleteViewport((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, (IDirect3DViewport3
*)vp
);
942 static HRESULT WINAPI
943 Thunk_IDirect3DDeviceImpl_1_DeleteViewport(IDirect3DDevice
*iface
,
944 IDirect3DViewport
*Direct3DViewport
)
946 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
947 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*)Direct3DViewport
;
948 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This
, vp
);
949 return IDirect3DDevice3_DeleteViewport((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, (IDirect3DViewport3
*)vp
);
952 /*****************************************************************************
953 * IDirect3DDevice3::NextViewport
955 * Returns a viewport from the viewport list, depending on the
956 * passed viewport and the flags.
958 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
962 * Viewport: Viewport to use for beginning the search
963 * Flags: D3DNEXT_NEXT, D3DNEXT_HEAD or D3DNEXT_TAIL
967 * DDERR_INVALIDPARAMS if the flags were wrong, or Viewport was NULL
969 *****************************************************************************/
970 static HRESULT WINAPI
971 IDirect3DDeviceImpl_3_NextViewport(IDirect3DDevice3
*iface
,
972 IDirect3DViewport3
*Viewport3
,
973 IDirect3DViewport3
**lplpDirect3DViewport3
,
976 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
977 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*)Viewport3
;
978 IDirect3DViewportImpl
*res
= NULL
;
980 TRACE("(%p)->(%p,%p,%08x)\n", This
, vp
, lplpDirect3DViewport3
, Flags
);
984 *lplpDirect3DViewport3
= NULL
;
985 return DDERR_INVALIDPARAMS
;
989 EnterCriticalSection(&ddraw_cs
);
999 res
= This
->viewport_list
;
1004 IDirect3DViewportImpl
*cur_viewport
= This
->viewport_list
;
1005 if (cur_viewport
!= NULL
)
1007 while (cur_viewport
->next
!= NULL
) cur_viewport
= cur_viewport
->next
;
1013 *lplpDirect3DViewport3
= NULL
;
1014 LeaveCriticalSection(&ddraw_cs
);
1015 return DDERR_INVALIDPARAMS
;
1018 *lplpDirect3DViewport3
= (IDirect3DViewport3
*)res
;
1019 LeaveCriticalSection(&ddraw_cs
);
1023 static HRESULT WINAPI
1024 Thunk_IDirect3DDeviceImpl_2_NextViewport(IDirect3DDevice2
*iface
,
1025 IDirect3DViewport2
*Viewport2
,
1026 IDirect3DViewport2
**lplpDirect3DViewport2
,
1029 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
1030 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*)Viewport2
;
1031 IDirect3DViewport3
*res
;
1033 TRACE_(ddraw_thunk
)("(%p)->(%p,%p,%08x) thunking to IDirect3DDevice3 interface.\n", This
, vp
, lplpDirect3DViewport2
, Flags
);
1034 hr
= IDirect3DDevice3_NextViewport((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
,
1035 (IDirect3DViewport3
*)vp
, &res
, Flags
);
1036 *lplpDirect3DViewport2
= (IDirect3DViewport2
*)res
;
1040 static HRESULT WINAPI
1041 Thunk_IDirect3DDeviceImpl_1_NextViewport(IDirect3DDevice
*iface
,
1042 IDirect3DViewport
*Viewport
,
1043 IDirect3DViewport
**lplpDirect3DViewport
,
1046 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
1047 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*)Viewport
;
1048 IDirect3DViewport3
*res
;
1050 TRACE_(ddraw_thunk
)("(%p)->(%p,%p,%08x) thunking to IDirect3DDevice3 interface.\n", This
, vp
, lplpDirect3DViewport
, Flags
);
1051 hr
= IDirect3DDevice3_NextViewport((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
,
1052 (IDirect3DViewport3
*)vp
, &res
, Flags
);
1053 *lplpDirect3DViewport
= (IDirect3DViewport
*)res
;
1057 /*****************************************************************************
1058 * IDirect3DDevice::Pick
1060 * Executes an execute buffer without performing rendering. Instead, a
1061 * list of primitives that intersect with (x1,y1) of the passed rectangle
1062 * is created. IDirect3DDevice::GetPickRecords can be used to retrieve
1068 * ExecuteBuffer: Buffer to execute
1069 * Viewport: Viewport to use for execution
1070 * Flags: None are defined, according to the SDK
1071 * Rect: Specifies the coordinates to be picked. Only x1 and y2 are used,
1072 * x2 and y2 are ignored.
1075 * D3D_OK because it's a stub
1077 *****************************************************************************/
1078 static HRESULT WINAPI
1079 IDirect3DDeviceImpl_1_Pick(IDirect3DDevice
*iface
,
1080 IDirect3DExecuteBuffer
*ExecuteBuffer
,
1081 IDirect3DViewport
*Viewport
,
1085 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
1086 IDirect3DExecuteBufferImpl
*execbuf
= (IDirect3DExecuteBufferImpl
*)ExecuteBuffer
;
1087 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*)Viewport
;
1088 FIXME("(%p)->(%p,%p,%08x,%p): stub!\n", This
, execbuf
, vp
, Flags
, Rect
);
1093 /*****************************************************************************
1094 * IDirect3DDevice::GetPickRecords
1096 * Retrieves the pick records generated by IDirect3DDevice::GetPickRecords
1101 * Count: Pointer to a DWORD containing the numbers of pick records to
1103 * D3DPickRec: Address to store the resulting D3DPICKRECORD array.
1106 * D3D_OK, because it's a stub
1108 *****************************************************************************/
1109 static HRESULT WINAPI
1110 IDirect3DDeviceImpl_1_GetPickRecords(IDirect3DDevice
*iface
,
1112 D3DPICKRECORD
*D3DPickRec
)
1114 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
1115 FIXME("(%p)->(%p,%p): stub!\n", This
, Count
, D3DPickRec
);
1120 /*****************************************************************************
1121 * IDirect3DDevice7::EnumTextureformats
1123 * Enumerates the supported texture formats. It has a list of all possible
1124 * formats and calls IWineD3D::CheckDeviceFormat for each format to see if
1125 * WineD3D supports it. If so, then it is passed to the app.
1127 * This is for Version 7 and 3, older versions have a different
1128 * callback function and their own implementation
1131 * Callback: Callback to call for each enumerated format
1132 * Arg: Argument to pass to the callback
1136 * DDERR_INVALIDPARAMS if Callback == NULL
1138 *****************************************************************************/
1140 IDirect3DDeviceImpl_7_EnumTextureFormats(IDirect3DDevice7
*iface
,
1141 LPD3DENUMPIXELFORMATSCALLBACK Callback
,
1144 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
1146 WINED3DDISPLAYMODE mode
;
1149 WINED3DFORMAT FormatList
[] = {
1151 WINED3DFMT_B8G8R8A8_UNORM
,
1152 WINED3DFMT_B8G8R8X8_UNORM
,
1154 WINED3DFMT_B8G8R8_UNORM
,
1156 WINED3DFMT_B5G5R5A1_UNORM
,
1157 WINED3DFMT_B4G4R4A4_UNORM
,
1158 WINED3DFMT_B5G6R5_UNORM
,
1159 WINED3DFMT_B5G5R5X1_UNORM
,
1161 WINED3DFMT_B2G3R3_UNORM
,
1169 WINED3DFORMAT BumpFormatList
[] = {
1170 WINED3DFMT_R8G8_SNORM
,
1171 WINED3DFMT_R5G5_SNORM_L6_UNORM
,
1172 WINED3DFMT_R8G8_SNORM_L8X8_UNORM
,
1173 WINED3DFMT_R8G8B8A8_SNORM
,
1174 WINED3DFMT_R16G16_SNORM
,
1175 WINED3DFMT_R10G11B11_SNORM
,
1176 WINED3DFMT_R10G10B10_SNORM_A2_UNORM
1179 TRACE("(%p)->(%p,%p): Relay\n", This
, Callback
, Arg
);
1182 return DDERR_INVALIDPARAMS
;
1184 EnterCriticalSection(&ddraw_cs
);
1186 memset(&mode
, 0, sizeof(mode
));
1187 hr
= IWineD3DDevice_GetDisplayMode(This
->ddraw
->wineD3DDevice
,
1191 LeaveCriticalSection(&ddraw_cs
);
1192 WARN("Cannot get the current adapter format\n");
1196 for(i
= 0; i
< sizeof(FormatList
) / sizeof(WINED3DFORMAT
); i
++)
1198 hr
= IWineD3D_CheckDeviceFormat(This
->ddraw
->wineD3D
,
1199 WINED3DADAPTER_DEFAULT
,
1203 WINED3DRTYPE_TEXTURE
,
1208 DDPIXELFORMAT pformat
;
1210 memset(&pformat
, 0, sizeof(pformat
));
1211 pformat
.dwSize
= sizeof(pformat
);
1212 PixelFormat_WineD3DtoDD(&pformat
, FormatList
[i
]);
1214 TRACE("Enumerating WineD3DFormat %d\n", FormatList
[i
]);
1215 hr
= Callback(&pformat
, Arg
);
1216 if(hr
!= DDENUMRET_OK
)
1218 TRACE("Format enumeration cancelled by application\n");
1219 LeaveCriticalSection(&ddraw_cs
);
1225 for(i
= 0; i
< sizeof(BumpFormatList
) / sizeof(WINED3DFORMAT
); i
++)
1227 hr
= IWineD3D_CheckDeviceFormat(This
->ddraw
->wineD3D
,
1228 WINED3DADAPTER_DEFAULT
,
1231 WINED3DUSAGE_QUERY_LEGACYBUMPMAP
,
1232 WINED3DRTYPE_TEXTURE
,
1237 DDPIXELFORMAT pformat
;
1239 memset(&pformat
, 0, sizeof(pformat
));
1240 pformat
.dwSize
= sizeof(pformat
);
1241 PixelFormat_WineD3DtoDD(&pformat
, BumpFormatList
[i
]);
1243 TRACE("Enumerating WineD3DFormat %d\n", BumpFormatList
[i
]);
1244 hr
= Callback(&pformat
, Arg
);
1245 if(hr
!= DDENUMRET_OK
)
1247 TRACE("Format enumeration cancelled by application\n");
1248 LeaveCriticalSection(&ddraw_cs
);
1253 TRACE("End of enumeration\n");
1254 LeaveCriticalSection(&ddraw_cs
);
1258 static HRESULT WINAPI
1259 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUSetup(IDirect3DDevice7
*iface
,
1260 LPD3DENUMPIXELFORMATSCALLBACK Callback
,
1263 return IDirect3DDeviceImpl_7_EnumTextureFormats(iface
, Callback
, Arg
);
1266 static HRESULT WINAPI
1267 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUPreserve(IDirect3DDevice7
*iface
,
1268 LPD3DENUMPIXELFORMATSCALLBACK Callback
,
1274 old_fpucw
= d3d_fpu_setup();
1275 hr
= IDirect3DDeviceImpl_7_EnumTextureFormats(iface
, Callback
, Arg
);
1276 set_fpu_control_word(old_fpucw
);
1281 static HRESULT WINAPI
1282 Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats(IDirect3DDevice3
*iface
,
1283 LPD3DENUMPIXELFORMATSCALLBACK Callback
,
1286 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
1287 TRACE_(ddraw_thunk
)("(%p)->(%p,%p) thunking to IDirect3DDevice7 interface.\n", This
, Callback
, Arg
);
1288 return IDirect3DDevice7_EnumTextureFormats((IDirect3DDevice7
*)This
, Callback
, Arg
);
1291 /*****************************************************************************
1292 * IDirect3DDevice2::EnumTextureformats
1294 * EnumTextureFormats for Version 1 and 2, see
1295 * IDirect3DDevice7::EnumTexureFormats for a more detailed description.
1297 * This version has a different callback and does not enumerate FourCC
1300 *****************************************************************************/
1301 static HRESULT WINAPI
1302 IDirect3DDeviceImpl_2_EnumTextureFormats(IDirect3DDevice2
*iface
,
1303 LPD3DENUMTEXTUREFORMATSCALLBACK Callback
,
1306 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
1309 WINED3DDISPLAYMODE mode
;
1311 WINED3DFORMAT FormatList
[] = {
1313 WINED3DFMT_B8G8R8A8_UNORM
,
1314 WINED3DFMT_B8G8R8X8_UNORM
,
1316 WINED3DFMT_B8G8R8_UNORM
,
1318 WINED3DFMT_B5G5R5A1_UNORM
,
1319 WINED3DFMT_B4G4R4A4_UNORM
,
1320 WINED3DFMT_B5G6R5_UNORM
,
1321 WINED3DFMT_B5G5R5X1_UNORM
,
1323 WINED3DFMT_B2G3R3_UNORM
,
1325 /* FOURCC codes - Not in this version*/
1328 TRACE("(%p)->(%p,%p): Relay\n", This
, Callback
, Arg
);
1331 return DDERR_INVALIDPARAMS
;
1333 EnterCriticalSection(&ddraw_cs
);
1335 memset(&mode
, 0, sizeof(mode
));
1336 hr
= IWineD3DDevice_GetDisplayMode(This
->ddraw
->wineD3DDevice
,
1340 LeaveCriticalSection(&ddraw_cs
);
1341 WARN("Cannot get the current adapter format\n");
1345 for(i
= 0; i
< sizeof(FormatList
) / sizeof(WINED3DFORMAT
); i
++)
1347 hr
= IWineD3D_CheckDeviceFormat(This
->ddraw
->wineD3D
,
1352 WINED3DRTYPE_TEXTURE
,
1357 DDSURFACEDESC sdesc
;
1359 memset(&sdesc
, 0, sizeof(sdesc
));
1360 sdesc
.dwSize
= sizeof(sdesc
);
1361 sdesc
.dwFlags
= DDSD_PIXELFORMAT
| DDSD_CAPS
;
1362 sdesc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1363 sdesc
.ddpfPixelFormat
.dwSize
= sizeof(sdesc
.ddpfPixelFormat
);
1364 PixelFormat_WineD3DtoDD(&sdesc
.ddpfPixelFormat
, FormatList
[i
]);
1366 TRACE("Enumerating WineD3DFormat %d\n", FormatList
[i
]);
1367 hr
= Callback(&sdesc
, Arg
);
1368 if(hr
!= DDENUMRET_OK
)
1370 TRACE("Format enumeration cancelled by application\n");
1371 LeaveCriticalSection(&ddraw_cs
);
1376 TRACE("End of enumeration\n");
1377 LeaveCriticalSection(&ddraw_cs
);
1381 static HRESULT WINAPI
1382 Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats(IDirect3DDevice
*iface
,
1383 LPD3DENUMTEXTUREFORMATSCALLBACK Callback
,
1386 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
1387 TRACE_(ddraw_thunk
)("(%p)->(%p,%p) thunking to IDirect3DDevice2 interface.\n", This
, Callback
, Arg
);
1388 return IDirect3DDevice2_EnumTextureFormats((IDirect3DDevice2
*)&This
->IDirect3DDevice2_vtbl
, Callback
, Arg
);
1391 /*****************************************************************************
1392 * IDirect3DDevice::CreateMatrix
1394 * Creates a matrix handle. A handle is created and memory for a D3DMATRIX is
1395 * allocated for the handle.
1400 * D3DMatHandle: Address to return the handle at
1404 * DDERR_INVALIDPARAMS if D3DMatHandle = NULL
1406 *****************************************************************************/
1407 static HRESULT WINAPI
1408 IDirect3DDeviceImpl_1_CreateMatrix(IDirect3DDevice
*iface
, D3DMATRIXHANDLE
*D3DMatHandle
)
1410 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
1412 TRACE("(%p)->(%p)\n", This
, D3DMatHandle
);
1415 return DDERR_INVALIDPARAMS
;
1417 Matrix
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(D3DMATRIX
));
1420 ERR("Out of memory when allocating a D3DMATRIX\n");
1421 return DDERR_OUTOFMEMORY
;
1424 EnterCriticalSection(&ddraw_cs
);
1425 *D3DMatHandle
= IDirect3DDeviceImpl_CreateHandle(This
);
1426 if(!(*D3DMatHandle
))
1428 ERR("Failed to create a matrix handle\n");
1429 HeapFree(GetProcessHeap(), 0, Matrix
);
1430 LeaveCriticalSection(&ddraw_cs
);
1431 return DDERR_OUTOFMEMORY
;
1433 This
->Handles
[*D3DMatHandle
- 1].ptr
= Matrix
;
1434 This
->Handles
[*D3DMatHandle
- 1].type
= DDrawHandle_Matrix
;
1435 TRACE(" returning matrix handle %d\n", *D3DMatHandle
);
1437 LeaveCriticalSection(&ddraw_cs
);
1441 /*****************************************************************************
1442 * IDirect3DDevice::SetMatrix
1444 * Sets a matrix for a matrix handle. The matrix is copied into the memory
1445 * allocated for the handle
1450 * D3DMatHandle: Handle to set the matrix to
1451 * D3DMatrix: Matrix to set
1455 * DDERR_INVALIDPARAMS if the handle of the matrix is invalid or the matrix
1458 *****************************************************************************/
1459 static HRESULT WINAPI
1460 IDirect3DDeviceImpl_1_SetMatrix(IDirect3DDevice
*iface
,
1461 D3DMATRIXHANDLE D3DMatHandle
,
1462 D3DMATRIX
*D3DMatrix
)
1464 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
1465 TRACE("(%p)->(%08x,%p)\n", This
, D3DMatHandle
, D3DMatrix
);
1467 if( (!D3DMatHandle
) || (!D3DMatrix
) )
1468 return DDERR_INVALIDPARAMS
;
1470 EnterCriticalSection(&ddraw_cs
);
1471 if(D3DMatHandle
> This
->numHandles
)
1473 ERR("Handle %d out of range\n", D3DMatHandle
);
1474 LeaveCriticalSection(&ddraw_cs
);
1475 return DDERR_INVALIDPARAMS
;
1477 else if(This
->Handles
[D3DMatHandle
- 1].type
!= DDrawHandle_Matrix
)
1479 ERR("Handle %d is not a matrix handle\n", D3DMatHandle
);
1480 LeaveCriticalSection(&ddraw_cs
);
1481 return DDERR_INVALIDPARAMS
;
1485 dump_D3DMATRIX(D3DMatrix
);
1487 *((D3DMATRIX
*) This
->Handles
[D3DMatHandle
- 1].ptr
) = *D3DMatrix
;
1489 if(This
->world
== D3DMatHandle
)
1491 IWineD3DDevice_SetTransform(This
->wineD3DDevice
,
1492 WINED3DTS_WORLDMATRIX(0),
1493 (WINED3DMATRIX
*) D3DMatrix
);
1495 if(This
->view
== D3DMatHandle
)
1497 IWineD3DDevice_SetTransform(This
->wineD3DDevice
,
1499 (WINED3DMATRIX
*) D3DMatrix
);
1501 if(This
->proj
== D3DMatHandle
)
1503 IWineD3DDevice_SetTransform(This
->wineD3DDevice
,
1504 WINED3DTS_PROJECTION
,
1505 (WINED3DMATRIX
*) D3DMatrix
);
1508 LeaveCriticalSection(&ddraw_cs
);
1512 /*****************************************************************************
1513 * IDirect3DDevice::SetMatrix
1515 * Returns the content of a D3DMATRIX handle
1520 * D3DMatHandle: Matrix handle to read the content from
1521 * D3DMatrix: Address to store the content at
1525 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid or D3DMatrix is NULL
1527 *****************************************************************************/
1528 static HRESULT WINAPI
1529 IDirect3DDeviceImpl_1_GetMatrix(IDirect3DDevice
*iface
,
1530 D3DMATRIXHANDLE D3DMatHandle
,
1531 D3DMATRIX
*D3DMatrix
)
1533 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
1534 TRACE("(%p)->(%08x,%p)\n", This
, D3DMatHandle
, D3DMatrix
);
1537 return DDERR_INVALIDPARAMS
;
1539 return DDERR_INVALIDPARAMS
;
1541 EnterCriticalSection(&ddraw_cs
);
1542 if(D3DMatHandle
> This
->numHandles
)
1544 ERR("Handle %d out of range\n", D3DMatHandle
);
1545 LeaveCriticalSection(&ddraw_cs
);
1546 return DDERR_INVALIDPARAMS
;
1548 else if(This
->Handles
[D3DMatHandle
- 1].type
!= DDrawHandle_Matrix
)
1550 ERR("Handle %d is not a matrix handle\n", D3DMatHandle
);
1551 LeaveCriticalSection(&ddraw_cs
);
1552 return DDERR_INVALIDPARAMS
;
1555 /* The handle is simply a pointer to a D3DMATRIX structure */
1556 *D3DMatrix
= *((D3DMATRIX
*) This
->Handles
[D3DMatHandle
- 1].ptr
);
1558 LeaveCriticalSection(&ddraw_cs
);
1562 /*****************************************************************************
1563 * IDirect3DDevice::DeleteMatrix
1565 * Destroys a Matrix handle. Frees the memory and unsets the handle data
1570 * D3DMatHandle: Handle to destroy
1574 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid
1576 *****************************************************************************/
1577 static HRESULT WINAPI
1578 IDirect3DDeviceImpl_1_DeleteMatrix(IDirect3DDevice
*iface
,
1579 D3DMATRIXHANDLE D3DMatHandle
)
1581 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
1582 TRACE("(%p)->(%08x)\n", This
, D3DMatHandle
);
1585 return DDERR_INVALIDPARAMS
;
1587 EnterCriticalSection(&ddraw_cs
);
1588 if(D3DMatHandle
> This
->numHandles
)
1590 ERR("Handle %d out of range\n", D3DMatHandle
);
1591 LeaveCriticalSection(&ddraw_cs
);
1592 return DDERR_INVALIDPARAMS
;
1594 else if(This
->Handles
[D3DMatHandle
- 1].type
!= DDrawHandle_Matrix
)
1596 ERR("Handle %d is not a matrix handle\n", D3DMatHandle
);
1597 LeaveCriticalSection(&ddraw_cs
);
1598 return DDERR_INVALIDPARAMS
;
1601 HeapFree(GetProcessHeap(), 0, This
->Handles
[D3DMatHandle
- 1].ptr
);
1602 This
->Handles
[D3DMatHandle
- 1].ptr
= NULL
;
1603 This
->Handles
[D3DMatHandle
- 1].type
= DDrawHandle_Unknown
;
1605 LeaveCriticalSection(&ddraw_cs
);
1609 /*****************************************************************************
1610 * IDirect3DDevice7::BeginScene
1612 * This method must be called before any rendering is performed.
1613 * IDirect3DDevice::EndScene has to be called after the scene is complete
1615 * Version 1, 2, 3 and 7
1618 * D3D_OK on success, for details see IWineD3DDevice::BeginScene
1619 * D3DERR_SCENE_IN_SCENE if WineD3D returns an error(Only in case of an already
1622 *****************************************************************************/
1624 IDirect3DDeviceImpl_7_BeginScene(IDirect3DDevice7
*iface
)
1626 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
1628 TRACE("(%p): Relay\n", This
);
1630 EnterCriticalSection(&ddraw_cs
);
1631 hr
= IWineD3DDevice_BeginScene(This
->wineD3DDevice
);
1632 LeaveCriticalSection(&ddraw_cs
);
1633 if(hr
== WINED3D_OK
) return D3D_OK
;
1634 else return D3DERR_SCENE_IN_SCENE
; /* TODO: Other possible causes of failure */
1637 static HRESULT WINAPI
1638 IDirect3DDeviceImpl_7_BeginScene_FPUSetup(IDirect3DDevice7
*iface
)
1640 return IDirect3DDeviceImpl_7_BeginScene(iface
);
1643 static HRESULT WINAPI
1644 IDirect3DDeviceImpl_7_BeginScene_FPUPreserve(IDirect3DDevice7
*iface
)
1649 old_fpucw
= d3d_fpu_setup();
1650 hr
= IDirect3DDeviceImpl_7_BeginScene(iface
);
1651 set_fpu_control_word(old_fpucw
);
1656 static HRESULT WINAPI
1657 Thunk_IDirect3DDeviceImpl_3_BeginScene(IDirect3DDevice3
*iface
)
1659 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
1660 TRACE_(ddraw_thunk
)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This
);
1661 return IDirect3DDevice7_BeginScene((IDirect3DDevice7
*)This
);
1664 static HRESULT WINAPI
1665 Thunk_IDirect3DDeviceImpl_2_BeginScene(IDirect3DDevice2
*iface
)
1667 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
1668 TRACE_(ddraw_thunk
)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This
);
1669 return IDirect3DDevice7_BeginScene((IDirect3DDevice7
*)This
);
1672 static HRESULT WINAPI
1673 Thunk_IDirect3DDeviceImpl_1_BeginScene(IDirect3DDevice
*iface
)
1675 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
1676 TRACE_(ddraw_thunk
)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This
);
1677 return IDirect3DDevice7_BeginScene((IDirect3DDevice7
*)This
);
1680 /*****************************************************************************
1681 * IDirect3DDevice7::EndScene
1683 * Ends a scene that has been begun with IDirect3DDevice7::BeginScene.
1684 * This method must be called after rendering is finished.
1686 * Version 1, 2, 3 and 7
1689 * D3D_OK on success, for details see IWineD3DDevice::EndScene
1690 * D3DERR_SCENE_NOT_IN_SCENE is returned if WineD3D returns an error. It does
1691 * that only if the scene was already ended.
1693 *****************************************************************************/
1695 IDirect3DDeviceImpl_7_EndScene(IDirect3DDevice7
*iface
)
1697 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
1699 TRACE("(%p): Relay\n", This
);
1701 EnterCriticalSection(&ddraw_cs
);
1702 hr
= IWineD3DDevice_EndScene(This
->wineD3DDevice
);
1703 LeaveCriticalSection(&ddraw_cs
);
1704 if(hr
== WINED3D_OK
) return D3D_OK
;
1705 else return D3DERR_SCENE_NOT_IN_SCENE
;
1708 static HRESULT WINAPI DECLSPEC_HOTPATCH
1709 IDirect3DDeviceImpl_7_EndScene_FPUSetup(IDirect3DDevice7
*iface
)
1711 return IDirect3DDeviceImpl_7_EndScene(iface
);
1714 static HRESULT WINAPI DECLSPEC_HOTPATCH
1715 IDirect3DDeviceImpl_7_EndScene_FPUPreserve(IDirect3DDevice7
*iface
)
1720 old_fpucw
= d3d_fpu_setup();
1721 hr
= IDirect3DDeviceImpl_7_EndScene(iface
);
1722 set_fpu_control_word(old_fpucw
);
1727 static HRESULT WINAPI DECLSPEC_HOTPATCH
1728 Thunk_IDirect3DDeviceImpl_3_EndScene(IDirect3DDevice3
*iface
)
1730 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
1731 TRACE_(ddraw_thunk
)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This
);
1732 return IDirect3DDevice7_EndScene((IDirect3DDevice7
*)This
);
1735 static HRESULT WINAPI DECLSPEC_HOTPATCH
1736 Thunk_IDirect3DDeviceImpl_2_EndScene(IDirect3DDevice2
*iface
)
1738 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
1739 TRACE_(ddraw_thunk
)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This
);
1740 return IDirect3DDevice7_EndScene((IDirect3DDevice7
*)This
);
1743 static HRESULT WINAPI DECLSPEC_HOTPATCH
1744 Thunk_IDirect3DDeviceImpl_1_EndScene(IDirect3DDevice
*iface
)
1746 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
1747 TRACE_(ddraw_thunk
)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This
);
1748 return IDirect3DDevice7_EndScene((IDirect3DDevice7
*)This
);
1751 /*****************************************************************************
1752 * IDirect3DDevice7::GetDirect3D
1754 * Returns the IDirect3D(= interface to the DirectDraw object) used to create
1758 * Direct3D7: Address to store the interface pointer at
1762 * DDERR_INVALIDPARAMS if Direct3D7 == NULL
1764 *****************************************************************************/
1765 static HRESULT WINAPI
1766 IDirect3DDeviceImpl_7_GetDirect3D(IDirect3DDevice7
*iface
,
1767 IDirect3D7
**Direct3D7
)
1769 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
1770 TRACE("(%p)->(%p)\n", This
, Direct3D7
);
1773 return DDERR_INVALIDPARAMS
;
1775 *Direct3D7
= (IDirect3D7
*)&This
->ddraw
->IDirect3D7_vtbl
;
1776 IDirect3D7_AddRef(*Direct3D7
);
1778 TRACE(" returning interface %p\n", *Direct3D7
);
1782 static HRESULT WINAPI
1783 Thunk_IDirect3DDeviceImpl_3_GetDirect3D(IDirect3DDevice3
*iface
,
1784 IDirect3D3
**Direct3D3
)
1786 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
1788 IDirect3D7
*ret_ptr
;
1790 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This
, Direct3D3
);
1791 ret
= IDirect3DDevice7_GetDirect3D((IDirect3DDevice7
*)This
, &ret_ptr
);
1794 *Direct3D3
= ret_ptr
? (IDirect3D3
*)&ddraw_from_d3d7(ret_ptr
)->IDirect3D3_vtbl
: NULL
;
1795 TRACE(" returning interface %p\n", *Direct3D3
);
1799 static HRESULT WINAPI
1800 Thunk_IDirect3DDeviceImpl_2_GetDirect3D(IDirect3DDevice2
*iface
,
1801 IDirect3D2
**Direct3D2
)
1803 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
1805 IDirect3D7
*ret_ptr
;
1807 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This
, Direct3D2
);
1808 ret
= IDirect3DDevice7_GetDirect3D((IDirect3DDevice7
*)This
, &ret_ptr
);
1811 *Direct3D2
= ret_ptr
? (IDirect3D2
*)&ddraw_from_d3d7(ret_ptr
)->IDirect3D2_vtbl
: NULL
;
1812 TRACE(" returning interface %p\n", *Direct3D2
);
1816 static HRESULT WINAPI
1817 Thunk_IDirect3DDeviceImpl_1_GetDirect3D(IDirect3DDevice
*iface
,
1818 IDirect3D
**Direct3D
)
1820 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
1822 IDirect3D7
*ret_ptr
;
1824 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This
, Direct3D
);
1825 ret
= IDirect3DDevice7_GetDirect3D((IDirect3DDevice7
*)This
, &ret_ptr
);
1828 *Direct3D
= ret_ptr
? (IDirect3D
*)&ddraw_from_d3d7(ret_ptr
)->IDirect3D_vtbl
: NULL
;
1829 TRACE(" returning interface %p\n", *Direct3D
);
1833 /*****************************************************************************
1834 * IDirect3DDevice3::SetCurrentViewport
1836 * Sets a Direct3DViewport as the current viewport.
1837 * For the thunks note that all viewport interface versions are equal
1840 * Direct3DViewport3: The viewport to set
1846 * (Is a NULL viewport valid?)
1848 *****************************************************************************/
1849 static HRESULT WINAPI
1850 IDirect3DDeviceImpl_3_SetCurrentViewport(IDirect3DDevice3
*iface
,
1851 IDirect3DViewport3
*Direct3DViewport3
)
1853 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
1854 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*)Direct3DViewport3
;
1855 TRACE("(%p)->(%p)\n", This
, Direct3DViewport3
);
1857 EnterCriticalSection(&ddraw_cs
);
1858 /* Do nothing if the specified viewport is the same as the current one */
1859 if (This
->current_viewport
== vp
)
1861 LeaveCriticalSection(&ddraw_cs
);
1865 /* Should check if the viewport was added or not */
1867 /* Release previous viewport and AddRef the new one */
1868 if (This
->current_viewport
)
1870 TRACE("ViewportImpl is at %p, interface is at %p\n", This
->current_viewport
,
1871 (IDirect3DViewport3
*)This
->current_viewport
);
1872 IDirect3DViewport3_Release((IDirect3DViewport3
*)This
->current_viewport
);
1874 IDirect3DViewport3_AddRef(Direct3DViewport3
);
1876 /* Set this viewport as the current viewport */
1877 This
->current_viewport
= vp
;
1879 /* Activate this viewport */
1880 This
->current_viewport
->active_device
= This
;
1881 This
->current_viewport
->activate(This
->current_viewport
, FALSE
);
1883 LeaveCriticalSection(&ddraw_cs
);
1887 static HRESULT WINAPI
1888 Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport(IDirect3DDevice2
*iface
,
1889 IDirect3DViewport2
*Direct3DViewport2
)
1891 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
1892 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*)Direct3DViewport2
;
1893 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This
, vp
);
1894 return IDirect3DDevice3_SetCurrentViewport((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
,
1895 (IDirect3DViewport3
*)vp
);
1898 /*****************************************************************************
1899 * IDirect3DDevice3::GetCurrentViewport
1901 * Returns the currently active viewport.
1906 * Direct3DViewport3: Address to return the interface pointer at
1910 * DDERR_INVALIDPARAMS if Direct3DViewport == NULL
1912 *****************************************************************************/
1913 static HRESULT WINAPI
1914 IDirect3DDeviceImpl_3_GetCurrentViewport(IDirect3DDevice3
*iface
,
1915 IDirect3DViewport3
**Direct3DViewport3
)
1917 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
1918 TRACE("(%p)->(%p)\n", This
, Direct3DViewport3
);
1920 if(!Direct3DViewport3
)
1921 return DDERR_INVALIDPARAMS
;
1923 EnterCriticalSection(&ddraw_cs
);
1924 *Direct3DViewport3
= (IDirect3DViewport3
*)This
->current_viewport
;
1926 /* AddRef the returned viewport */
1927 if(*Direct3DViewport3
) IDirect3DViewport3_AddRef(*Direct3DViewport3
);
1929 TRACE(" returning interface %p\n", *Direct3DViewport3
);
1931 LeaveCriticalSection(&ddraw_cs
);
1935 static HRESULT WINAPI
1936 Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport(IDirect3DDevice2
*iface
,
1937 IDirect3DViewport2
**Direct3DViewport2
)
1939 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
1941 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This
, Direct3DViewport2
);
1942 hr
= IDirect3DDevice3_GetCurrentViewport((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
,
1943 (IDirect3DViewport3
**)Direct3DViewport2
);
1944 if(hr
!= D3D_OK
) return hr
;
1948 /*****************************************************************************
1949 * IDirect3DDevice7::SetRenderTarget
1951 * Sets the render target for the Direct3DDevice.
1952 * For the thunks note that IDirectDrawSurface7 == IDirectDrawSurface4 and
1953 * IDirectDrawSurface3 == IDirectDrawSurface
1955 * Version 2, 3 and 7
1958 * NewTarget: Pointer to an IDirectDrawSurface7 interface to set as the new
1963 * D3D_OK on success, for details see IWineD3DDevice::SetRenderTarget
1965 *****************************************************************************/
1967 IDirect3DDeviceImpl_7_SetRenderTarget(IDirect3DDevice7
*iface
,
1968 IDirectDrawSurface7
*NewTarget
,
1971 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
1972 IDirectDrawSurfaceImpl
*Target
= (IDirectDrawSurfaceImpl
*)NewTarget
;
1974 TRACE("(%p)->(%p,%08x): Relay\n", This
, NewTarget
, Flags
);
1976 EnterCriticalSection(&ddraw_cs
);
1977 /* Flags: Not used */
1979 if(This
->target
== Target
)
1981 TRACE("No-op SetRenderTarget operation, not doing anything\n");
1982 LeaveCriticalSection(&ddraw_cs
);
1986 hr
= IWineD3DDevice_SetRenderTarget(This
->wineD3DDevice
,
1988 Target
? Target
->WineD3DSurface
: NULL
,
1992 LeaveCriticalSection(&ddraw_cs
);
1995 IDirectDrawSurface7_AddRef(NewTarget
);
1996 IDirectDrawSurface7_Release((IDirectDrawSurface7
*)This
->target
);
1997 This
->target
= Target
;
1998 IDirect3DDeviceImpl_UpdateDepthStencil(This
);
1999 LeaveCriticalSection(&ddraw_cs
);
2003 static HRESULT WINAPI
2004 IDirect3DDeviceImpl_7_SetRenderTarget_FPUSetup(IDirect3DDevice7
*iface
,
2005 IDirectDrawSurface7
*NewTarget
,
2008 return IDirect3DDeviceImpl_7_SetRenderTarget(iface
, NewTarget
, Flags
);
2011 static HRESULT WINAPI
2012 IDirect3DDeviceImpl_7_SetRenderTarget_FPUPreserve(IDirect3DDevice7
*iface
,
2013 IDirectDrawSurface7
*NewTarget
,
2019 old_fpucw
= d3d_fpu_setup();
2020 hr
= IDirect3DDeviceImpl_7_SetRenderTarget(iface
, NewTarget
, Flags
);
2021 set_fpu_control_word(old_fpucw
);
2026 static HRESULT WINAPI
2027 Thunk_IDirect3DDeviceImpl_3_SetRenderTarget(IDirect3DDevice3
*iface
,
2028 IDirectDrawSurface4
*NewRenderTarget
,
2031 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
2032 IDirectDrawSurfaceImpl
*Target
= (IDirectDrawSurfaceImpl
*)NewRenderTarget
;
2033 TRACE_(ddraw_thunk
)("(%p)->(%p,%08x) thunking to IDirect3DDevice7 interface.\n", This
, Target
, Flags
);
2034 return IDirect3DDevice7_SetRenderTarget((IDirect3DDevice7
*)This
, (IDirectDrawSurface7
*)Target
, Flags
);
2037 static HRESULT WINAPI
2038 Thunk_IDirect3DDeviceImpl_2_SetRenderTarget(IDirect3DDevice2
*iface
,
2039 IDirectDrawSurface
*NewRenderTarget
,
2042 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
2043 IDirectDrawSurfaceImpl
*Target
= (IDirectDrawSurfaceImpl
*)NewRenderTarget
;
2044 TRACE_(ddraw_thunk
)("(%p)->(%p,%08x) thunking to IDirect3DDevice7 interface.\n", This
, Target
, Flags
);
2045 return IDirect3DDevice7_SetRenderTarget((IDirect3DDevice7
*)This
, (IDirectDrawSurface7
*)Target
, Flags
);
2048 /*****************************************************************************
2049 * IDirect3DDevice7::GetRenderTarget
2051 * Returns the current render target.
2052 * This is handled locally, because the WineD3D render target's parent
2055 * Version 2, 3 and 7
2058 * RenderTarget: Address to store the surface interface pointer
2062 * DDERR_INVALIDPARAMS if RenderTarget == NULL
2064 *****************************************************************************/
2065 static HRESULT WINAPI
2066 IDirect3DDeviceImpl_7_GetRenderTarget(IDirect3DDevice7
*iface
,
2067 IDirectDrawSurface7
**RenderTarget
)
2069 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
2070 TRACE("(%p)->(%p): Relay\n", This
, RenderTarget
);
2073 return DDERR_INVALIDPARAMS
;
2075 EnterCriticalSection(&ddraw_cs
);
2076 *RenderTarget
= (IDirectDrawSurface7
*)This
->target
;
2077 IDirectDrawSurface7_AddRef(*RenderTarget
);
2079 LeaveCriticalSection(&ddraw_cs
);
2083 static HRESULT WINAPI
2084 Thunk_IDirect3DDeviceImpl_3_GetRenderTarget(IDirect3DDevice3
*iface
,
2085 IDirectDrawSurface4
**RenderTarget
)
2087 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
2089 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This
, RenderTarget
);
2090 hr
= IDirect3DDevice7_GetRenderTarget((IDirect3DDevice7
*)This
, (IDirectDrawSurface7
**)RenderTarget
);
2091 if(hr
!= D3D_OK
) return hr
;
2095 static HRESULT WINAPI
2096 Thunk_IDirect3DDeviceImpl_2_GetRenderTarget(IDirect3DDevice2
*iface
,
2097 IDirectDrawSurface
**RenderTarget
)
2099 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
2101 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This
, RenderTarget
);
2102 hr
= IDirect3DDevice7_GetRenderTarget((IDirect3DDevice7
*)This
, (IDirectDrawSurface7
**)RenderTarget
);
2103 if(hr
!= D3D_OK
) return hr
;
2104 *RenderTarget
= *RenderTarget
?
2105 (IDirectDrawSurface
*)&((IDirectDrawSurfaceImpl
*)*RenderTarget
)->IDirectDrawSurface3_vtbl
: NULL
;
2109 /*****************************************************************************
2110 * IDirect3DDevice3::Begin
2112 * Begins a description block of vertices. This is similar to glBegin()
2113 * and glEnd(). After a call to IDirect3DDevice3::End, the vertices
2114 * described with IDirect3DDevice::Vertex are drawn.
2119 * PrimitiveType: The type of primitives to draw
2120 * VertexTypeDesc: A flexible vertex format description of the vertices
2121 * Flags: Some flags..
2126 *****************************************************************************/
2127 static HRESULT WINAPI
2128 IDirect3DDeviceImpl_3_Begin(IDirect3DDevice3
*iface
,
2129 D3DPRIMITIVETYPE PrimitiveType
,
2130 DWORD VertexTypeDesc
,
2133 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
2134 TRACE("(%p)->(%d,%d,%08x)\n", This
, PrimitiveType
, VertexTypeDesc
, Flags
);
2136 EnterCriticalSection(&ddraw_cs
);
2137 This
->primitive_type
= PrimitiveType
;
2138 This
->vertex_type
= VertexTypeDesc
;
2139 This
->render_flags
= Flags
;
2140 This
->vertex_size
= get_flexible_vertex_size(This
->vertex_type
);
2141 This
->nb_vertices
= 0;
2142 LeaveCriticalSection(&ddraw_cs
);
2147 static HRESULT WINAPI
2148 Thunk_IDirect3DDeviceImpl_2_Begin(IDirect3DDevice2
*iface
,
2149 D3DPRIMITIVETYPE d3dpt
,
2150 D3DVERTEXTYPE dwVertexTypeDesc
,
2154 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
2155 TRACE_(ddraw_thunk
)("(%p/%p)->(%08x,%08x,%08x): Thunking to IDirect3DDevice3\n", This
, iface
, d3dpt
, dwVertexTypeDesc
, dwFlags
);
2157 switch(dwVertexTypeDesc
)
2159 case D3DVT_VERTEX
: FVF
= D3DFVF_VERTEX
; break;
2160 case D3DVT_LVERTEX
: FVF
= D3DFVF_LVERTEX
; break;
2161 case D3DVT_TLVERTEX
: FVF
= D3DFVF_TLVERTEX
; break;
2163 ERR("Unexpected vertex type %d\n", dwVertexTypeDesc
);
2164 return DDERR_INVALIDPARAMS
; /* Should never happen */
2167 return IDirect3DDevice3_Begin((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, d3dpt
, FVF
, dwFlags
);
2170 /*****************************************************************************
2171 * IDirect3DDevice3::BeginIndexed
2173 * Draws primitives based on vertices in a vertex array which are specified
2179 * PrimitiveType: Primitive type to draw
2180 * VertexType: A FVF description of the vertex format
2181 * Vertices: pointer to an array containing the vertices
2182 * NumVertices: The number of vertices in the vertex array
2183 * Flags: Some flags ...
2186 * D3D_OK, because it's a stub
2188 *****************************************************************************/
2189 static HRESULT WINAPI
2190 IDirect3DDeviceImpl_3_BeginIndexed(IDirect3DDevice3
*iface
,
2191 D3DPRIMITIVETYPE PrimitiveType
,
2197 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
2198 FIXME("(%p)->(%08x,%08x,%p,%08x,%08x): stub!\n", This
, PrimitiveType
, VertexType
, Vertices
, NumVertices
, Flags
);
2203 static HRESULT WINAPI
2204 Thunk_IDirect3DDeviceImpl_2_BeginIndexed(IDirect3DDevice2
*iface
,
2205 D3DPRIMITIVETYPE d3dptPrimitiveType
,
2206 D3DVERTEXTYPE d3dvtVertexType
,
2208 DWORD dwNumVertices
,
2212 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
2213 TRACE_(ddraw_thunk
)("(%p/%p)->(%08x,%08x,%p,%08x,%08x): Thunking to IDirect3DDevice3\n", This
, iface
, d3dptPrimitiveType
, d3dvtVertexType
, lpvVertices
, dwNumVertices
, dwFlags
);
2215 switch(d3dvtVertexType
)
2217 case D3DVT_VERTEX
: FVF
= D3DFVF_VERTEX
; break;
2218 case D3DVT_LVERTEX
: FVF
= D3DFVF_LVERTEX
; break;
2219 case D3DVT_TLVERTEX
: FVF
= D3DFVF_TLVERTEX
; break;
2221 ERR("Unexpected vertex type %d\n", d3dvtVertexType
);
2222 return DDERR_INVALIDPARAMS
; /* Should never happen */
2225 return IDirect3DDevice3_BeginIndexed((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
,
2226 d3dptPrimitiveType
, FVF
, lpvVertices
, dwNumVertices
, dwFlags
);
2229 /*****************************************************************************
2230 * IDirect3DDevice3::Vertex
2232 * Draws a vertex as described by IDirect3DDevice3::Begin. It places all
2233 * drawn vertices in a vertex buffer. If the buffer is too small, its
2234 * size is increased.
2239 * Vertex: Pointer to the vertex
2242 * D3D_OK, on success
2243 * DDERR_INVALIDPARAMS if Vertex is NULL
2245 *****************************************************************************/
2246 static HRESULT WINAPI
2247 IDirect3DDeviceImpl_3_Vertex(IDirect3DDevice3
*iface
,
2250 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
2251 TRACE("(%p)->(%p)\n", This
, Vertex
);
2254 return DDERR_INVALIDPARAMS
;
2256 EnterCriticalSection(&ddraw_cs
);
2257 if ((This
->nb_vertices
+1)*This
->vertex_size
> This
->buffer_size
)
2260 This
->buffer_size
= This
->buffer_size
? This
->buffer_size
* 2 : This
->vertex_size
* 3;
2261 old_buffer
= This
->vertex_buffer
;
2262 This
->vertex_buffer
= HeapAlloc(GetProcessHeap(), 0, This
->buffer_size
);
2265 CopyMemory(This
->vertex_buffer
, old_buffer
, This
->nb_vertices
* This
->vertex_size
);
2266 HeapFree(GetProcessHeap(), 0, old_buffer
);
2270 CopyMemory(This
->vertex_buffer
+ This
->nb_vertices
++ * This
->vertex_size
, Vertex
, This
->vertex_size
);
2272 LeaveCriticalSection(&ddraw_cs
);
2276 static HRESULT WINAPI
2277 Thunk_IDirect3DDeviceImpl_2_Vertex(IDirect3DDevice2
*iface
,
2280 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
2281 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This
, lpVertexType
);
2282 return IDirect3DDevice3_Vertex((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, lpVertexType
);
2285 /*****************************************************************************
2286 * IDirect3DDevice3::Index
2288 * Specifies an index to a vertex to be drawn. The vertex array has to
2289 * be specified with BeginIndexed first.
2292 * VertexIndex: The index of the vertex to draw
2295 * D3D_OK because it's a stub
2297 *****************************************************************************/
2298 static HRESULT WINAPI
2299 IDirect3DDeviceImpl_3_Index(IDirect3DDevice3
*iface
,
2302 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
2303 FIXME("(%p)->(%04x): stub!\n", This
, VertexIndex
);
2307 static HRESULT WINAPI
2308 Thunk_IDirect3DDeviceImpl_2_Index(IDirect3DDevice2
*iface
,
2311 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
2312 TRACE_(ddraw_thunk
)("(%p)->(%04x) thunking to IDirect3DDevice3 interface.\n", This
, wVertexIndex
);
2313 return IDirect3DDevice3_Index((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, wVertexIndex
);
2316 /*****************************************************************************
2317 * IDirect3DDevice3::End
2319 * Ends a draw begun with IDirect3DDevice3::Begin or
2320 * IDirect3DDevice::BeginIndexed. The vertices specified with
2321 * IDirect3DDevice::Vertex or IDirect3DDevice::Index are drawn using
2322 * the IDirect3DDevice7::DrawPrimitive method. So far only
2323 * non-indexed mode is supported
2328 * Flags: Some flags, as usual. Don't know which are defined
2331 * The return value of IDirect3DDevice7::DrawPrimitive
2333 *****************************************************************************/
2334 static HRESULT WINAPI
2335 IDirect3DDeviceImpl_3_End(IDirect3DDevice3
*iface
,
2338 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
2339 TRACE("(%p)->(%08x)\n", This
, Flags
);
2341 return IDirect3DDevice7_DrawPrimitive((IDirect3DDevice7
*)This
, This
->primitive_type
,
2342 This
->vertex_type
, This
->vertex_buffer
, This
->nb_vertices
, This
->render_flags
);
2345 static HRESULT WINAPI
2346 Thunk_IDirect3DDeviceImpl_2_End(IDirect3DDevice2
*iface
,
2349 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
2350 TRACE_(ddraw_thunk
)("(%p)->(%08x) thunking to IDirect3DDevice3 interface.\n", This
, dwFlags
);
2351 return IDirect3DDevice3_End((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, dwFlags
);
2354 /*****************************************************************************
2355 * IDirect3DDevice7::GetRenderState
2357 * Returns the value of a render state. The possible render states are
2358 * defined in include/d3dtypes.h
2360 * Version 2, 3 and 7
2363 * RenderStateType: Render state to return the current setting of
2364 * Value: Address to store the value at
2367 * D3D_OK on success, for details see IWineD3DDevice::GetRenderState
2368 * DDERR_INVALIDPARAMS if Value == NULL
2370 *****************************************************************************/
2372 IDirect3DDeviceImpl_7_GetRenderState(IDirect3DDevice7
*iface
,
2373 D3DRENDERSTATETYPE RenderStateType
,
2376 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
2378 TRACE("(%p)->(%08x,%p): Relay\n", This
, RenderStateType
, Value
);
2381 return DDERR_INVALIDPARAMS
;
2383 EnterCriticalSection(&ddraw_cs
);
2384 switch(RenderStateType
)
2386 case D3DRENDERSTATE_TEXTUREMAG
:
2388 WINED3DTEXTUREFILTERTYPE tex_mag
;
2390 hr
= IWineD3DDevice_GetSamplerState(This
->wineD3DDevice
,
2391 0, WINED3DSAMP_MAGFILTER
,
2396 case WINED3DTEXF_POINT
:
2397 *Value
= D3DFILTER_NEAREST
;
2399 case WINED3DTEXF_LINEAR
:
2400 *Value
= D3DFILTER_LINEAR
;
2403 ERR("Unhandled texture mag %d !\n",tex_mag
);
2409 case D3DRENDERSTATE_TEXTUREMIN
:
2411 WINED3DTEXTUREFILTERTYPE tex_min
;
2412 WINED3DTEXTUREFILTERTYPE tex_mip
;
2414 hr
= IWineD3DDevice_GetSamplerState(This
->wineD3DDevice
,
2415 0, WINED3DSAMP_MINFILTER
, &tex_min
);
2418 LeaveCriticalSection(&ddraw_cs
);
2421 hr
= IWineD3DDevice_GetSamplerState(This
->wineD3DDevice
,
2422 0, WINED3DSAMP_MIPFILTER
, &tex_mip
);
2426 case WINED3DTEXF_POINT
:
2429 case WINED3DTEXF_NONE
:
2430 *Value
= D3DFILTER_NEAREST
;
2432 case WINED3DTEXF_POINT
:
2433 *Value
= D3DFILTER_MIPNEAREST
;
2435 case WINED3DTEXF_LINEAR
:
2436 *Value
= D3DFILTER_LINEARMIPNEAREST
;
2439 ERR("Unhandled mip filter %#x.\n", tex_mip
);
2440 *Value
= D3DFILTER_NEAREST
;
2444 case WINED3DTEXF_LINEAR
:
2447 case WINED3DTEXF_NONE
:
2448 *Value
= D3DFILTER_LINEAR
;
2450 case WINED3DTEXF_POINT
:
2451 *Value
= D3DFILTER_MIPLINEAR
;
2453 case WINED3DTEXF_LINEAR
:
2454 *Value
= D3DFILTER_LINEARMIPLINEAR
;
2457 ERR("Unhandled mip filter %#x.\n", tex_mip
);
2458 *Value
= D3DFILTER_LINEAR
;
2463 ERR("Unhandled texture min filter %#x.\n",tex_min
);
2464 *Value
= D3DFILTER_NEAREST
;
2470 case D3DRENDERSTATE_TEXTUREADDRESS
:
2471 case D3DRENDERSTATE_TEXTUREADDRESSU
:
2472 hr
= IWineD3DDevice_GetSamplerState(This
->wineD3DDevice
,
2473 0, WINED3DSAMP_ADDRESSU
,
2476 case D3DRENDERSTATE_TEXTUREADDRESSV
:
2477 hr
= IWineD3DDevice_GetSamplerState(This
->wineD3DDevice
,
2478 0, WINED3DSAMP_ADDRESSV
,
2482 case D3DRENDERSTATE_BORDERCOLOR
:
2483 FIXME("Unhandled render state D3DRENDERSTATE_BORDERCOLOR.\n");
2488 if (RenderStateType
>= D3DRENDERSTATE_STIPPLEPATTERN00
2489 && RenderStateType
<= D3DRENDERSTATE_STIPPLEPATTERN31
)
2491 FIXME("Unhandled stipple pattern render state (%#x).\n",
2496 hr
= IWineD3DDevice_GetRenderState(This
->wineD3DDevice
,
2500 LeaveCriticalSection(&ddraw_cs
);
2504 static HRESULT WINAPI
2505 IDirect3DDeviceImpl_7_GetRenderState_FPUSetup(IDirect3DDevice7
*iface
,
2506 D3DRENDERSTATETYPE RenderStateType
,
2509 return IDirect3DDeviceImpl_7_GetRenderState(iface
, RenderStateType
, Value
);
2512 static HRESULT WINAPI
2513 IDirect3DDeviceImpl_7_GetRenderState_FPUPreserve(IDirect3DDevice7
*iface
,
2514 D3DRENDERSTATETYPE RenderStateType
,
2520 old_fpucw
= d3d_fpu_setup();
2521 hr
= IDirect3DDeviceImpl_7_GetRenderState(iface
, RenderStateType
, Value
);
2522 set_fpu_control_word(old_fpucw
);
2527 static HRESULT WINAPI
2528 IDirect3DDeviceImpl_3_GetRenderState(IDirect3DDevice3
*iface
,
2529 D3DRENDERSTATETYPE dwRenderStateType
,
2530 DWORD
*lpdwRenderState
)
2532 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
2534 TRACE("(%p)->(%08x,%p)\n", This
, dwRenderStateType
, lpdwRenderState
);
2536 switch(dwRenderStateType
)
2538 case D3DRENDERSTATE_TEXTUREHANDLE
:
2540 /* This state is wrapped to SetTexture in SetRenderState, so
2541 * it has to be wrapped to GetTexture here
2543 IWineD3DBaseTexture
*tex
= NULL
;
2544 *lpdwRenderState
= 0;
2546 EnterCriticalSection(&ddraw_cs
);
2548 hr
= IWineD3DDevice_GetTexture(This
->wineD3DDevice
,
2552 if(hr
== WINED3D_OK
&& tex
)
2554 IDirectDrawSurface7
*parent
= NULL
;
2555 hr
= IWineD3DBaseTexture_GetParent(tex
,
2556 (IUnknown
**) &parent
);
2559 /* The parent of the texture is the IDirectDrawSurface7 interface
2560 * of the ddraw surface
2562 IDirectDrawSurfaceImpl
*texImpl
= (IDirectDrawSurfaceImpl
*)parent
;
2563 *lpdwRenderState
= texImpl
->Handle
;
2564 IDirectDrawSurface7_Release(parent
);
2566 IWineD3DBaseTexture_Release(tex
);
2569 LeaveCriticalSection(&ddraw_cs
);
2574 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2576 /* D3DRENDERSTATE_TEXTUREMAPBLEND is mapped to texture state stages in SetRenderState; reverse
2577 the mapping to get the value. */
2578 DWORD colorop
, colorarg1
, colorarg2
;
2579 DWORD alphaop
, alphaarg1
, alphaarg2
;
2581 EnterCriticalSection(&ddraw_cs
);
2583 This
->legacyTextureBlending
= TRUE
;
2585 IWineD3DDevice_GetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLOROP
, &colorop
);
2586 IWineD3DDevice_GetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG1
, &colorarg1
);
2587 IWineD3DDevice_GetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG2
, &colorarg2
);
2588 IWineD3DDevice_GetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAOP
, &alphaop
);
2589 IWineD3DDevice_GetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG1
, &alphaarg1
);
2590 IWineD3DDevice_GetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG2
, &alphaarg2
);
2592 if (colorop
== WINED3DTOP_SELECTARG1
&& colorarg1
== WINED3DTA_TEXTURE
&&
2593 alphaop
== WINED3DTOP_SELECTARG1
&& alphaarg1
== WINED3DTA_TEXTURE
)
2595 *lpdwRenderState
= D3DTBLEND_DECAL
;
2597 else if (colorop
== WINED3DTOP_SELECTARG1
&& colorarg1
== WINED3DTA_TEXTURE
&&
2598 alphaop
== WINED3DTOP_MODULATE
&& alphaarg1
== WINED3DTA_TEXTURE
&& alphaarg2
== WINED3DTA_CURRENT
)
2600 *lpdwRenderState
= D3DTBLEND_DECALALPHA
;
2602 else if (colorop
== WINED3DTOP_MODULATE
&& colorarg1
== WINED3DTA_TEXTURE
&& colorarg2
== WINED3DTA_CURRENT
&&
2603 alphaop
== WINED3DTOP_MODULATE
&& alphaarg1
== WINED3DTA_TEXTURE
&& alphaarg2
== WINED3DTA_CURRENT
)
2605 *lpdwRenderState
= D3DTBLEND_MODULATEALPHA
;
2610 BOOL tex_alpha
= FALSE
;
2611 IWineD3DBaseTexture
*tex
= NULL
;
2612 WINED3DSURFACE_DESC desc
;
2613 DDPIXELFORMAT ddfmt
;
2615 hr
= IWineD3DDevice_GetTexture(This
->wineD3DDevice
,
2619 if(hr
== WINED3D_OK
&& tex
)
2621 hr
= IWineD3DTexture_GetLevelDesc((IWineD3DTexture
*) tex
, 0, &desc
);
2624 ddfmt
.dwSize
= sizeof(ddfmt
);
2625 PixelFormat_WineD3DtoDD(&ddfmt
, desc
.format
);
2626 if (ddfmt
.u5
.dwRGBAlphaBitMask
) tex_alpha
= TRUE
;
2629 IWineD3DBaseTexture_Release(tex
);
2632 if (!(colorop
== WINED3DTOP_MODULATE
&& colorarg1
== WINED3DTA_TEXTURE
&& colorarg2
== WINED3DTA_CURRENT
&&
2633 alphaop
== (tex_alpha
? WINED3DTOP_SELECTARG1
: WINED3DTOP_SELECTARG2
) &&
2634 alphaarg1
== WINED3DTA_TEXTURE
&& alphaarg2
== WINED3DTA_CURRENT
))
2636 ERR("Unexpected texture stage state setup, returning D3DTBLEND_MODULATE - likely erroneous\n");
2639 *lpdwRenderState
= D3DTBLEND_MODULATE
;
2642 LeaveCriticalSection(&ddraw_cs
);
2648 return IDirect3DDevice7_GetRenderState((IDirect3DDevice7
*)This
, dwRenderStateType
, lpdwRenderState
);
2652 static HRESULT WINAPI
2653 Thunk_IDirect3DDeviceImpl_2_GetRenderState(IDirect3DDevice2
*iface
,
2654 D3DRENDERSTATETYPE dwRenderStateType
,
2655 DWORD
*lpdwRenderState
)
2657 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
2658 TRACE_(ddraw_thunk
)("(%p)->(%08x,%p) thunking to IDirect3DDevice3 interface.\n", This
, dwRenderStateType
, lpdwRenderState
);
2659 return IDirect3DDevice3_GetRenderState((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
,
2660 dwRenderStateType
, lpdwRenderState
);
2663 /*****************************************************************************
2664 * IDirect3DDevice7::SetRenderState
2666 * Sets a render state. The possible render states are defined in
2667 * include/d3dtypes.h
2669 * Version 2, 3 and 7
2672 * RenderStateType: State to set
2673 * Value: Value to assign to that state
2676 * D3D_OK on success,
2677 * for details see IWineD3DDevice::SetRenderState
2679 *****************************************************************************/
2681 IDirect3DDeviceImpl_7_SetRenderState(IDirect3DDevice7
*iface
,
2682 D3DRENDERSTATETYPE RenderStateType
,
2685 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
2687 TRACE("(%p)->(%08x,%d): Relay\n", This
, RenderStateType
, Value
);
2689 EnterCriticalSection(&ddraw_cs
);
2690 /* Some render states need special care */
2691 switch(RenderStateType
)
2694 * The ddraw texture filter mapping works like this:
2695 * D3DFILTER_NEAREST Point min/mag, no mip
2696 * D3DFILTER_MIPNEAREST Point min/mag, point mip
2697 * D3DFILTER_LINEARMIPNEAREST: Point min/mag, linear mip
2699 * D3DFILTER_LINEAR Linear min/mag, no mip
2700 * D3DFILTER_MIPLINEAR Linear min/mag, point mip
2701 * D3DFILTER_LINEARMIPLINEAR Linear min/mag, linear mip
2703 * This is the opposite of the GL naming convention,
2704 * D3DFILTER_LINEARMIPNEAREST corresponds to GL_NEAREST_MIPMAP_LINEAR.
2706 case D3DRENDERSTATE_TEXTUREMAG
:
2708 WINED3DTEXTUREFILTERTYPE tex_mag
;
2712 case D3DFILTER_NEAREST
:
2713 case D3DFILTER_MIPNEAREST
:
2714 case D3DFILTER_LINEARMIPNEAREST
:
2715 tex_mag
= WINED3DTEXF_POINT
;
2717 case D3DFILTER_LINEAR
:
2718 case D3DFILTER_MIPLINEAR
:
2719 case D3DFILTER_LINEARMIPLINEAR
:
2720 tex_mag
= WINED3DTEXF_LINEAR
;
2723 tex_mag
= WINED3DTEXF_POINT
;
2724 ERR("Unhandled texture mag %d !\n",Value
);
2728 hr
= IWineD3DDevice_SetSamplerState(This
->wineD3DDevice
,
2729 0, WINED3DSAMP_MAGFILTER
,
2734 case D3DRENDERSTATE_TEXTUREMIN
:
2736 WINED3DTEXTUREFILTERTYPE tex_min
;
2737 WINED3DTEXTUREFILTERTYPE tex_mip
;
2739 switch ((D3DTEXTUREFILTER
) Value
)
2741 case D3DFILTER_NEAREST
:
2742 tex_min
= WINED3DTEXF_POINT
;
2743 tex_mip
= WINED3DTEXF_NONE
;
2745 case D3DFILTER_LINEAR
:
2746 tex_min
= WINED3DTEXF_LINEAR
;
2747 tex_mip
= WINED3DTEXF_NONE
;
2749 case D3DFILTER_MIPNEAREST
:
2750 tex_min
= WINED3DTEXF_POINT
;
2751 tex_mip
= WINED3DTEXF_POINT
;
2753 case D3DFILTER_MIPLINEAR
:
2754 tex_min
= WINED3DTEXF_LINEAR
;
2755 tex_mip
= WINED3DTEXF_POINT
;
2757 case D3DFILTER_LINEARMIPNEAREST
:
2758 tex_min
= WINED3DTEXF_POINT
;
2759 tex_mip
= WINED3DTEXF_LINEAR
;
2761 case D3DFILTER_LINEARMIPLINEAR
:
2762 tex_min
= WINED3DTEXF_LINEAR
;
2763 tex_mip
= WINED3DTEXF_LINEAR
;
2767 ERR("Unhandled texture min %d !\n",Value
);
2768 tex_min
= WINED3DTEXF_POINT
;
2769 tex_mip
= WINED3DTEXF_NONE
;
2773 IWineD3DDevice_SetSamplerState(This
->wineD3DDevice
,
2774 0, WINED3DSAMP_MIPFILTER
, tex_mip
);
2775 hr
= IWineD3DDevice_SetSamplerState(This
->wineD3DDevice
,
2776 0, WINED3DSAMP_MINFILTER
,
2781 case D3DRENDERSTATE_TEXTUREADDRESS
:
2782 IWineD3DDevice_SetSamplerState(This
->wineD3DDevice
,
2783 0, WINED3DSAMP_ADDRESSV
,
2786 case D3DRENDERSTATE_TEXTUREADDRESSU
:
2787 hr
= IWineD3DDevice_SetSamplerState(This
->wineD3DDevice
,
2788 0, WINED3DSAMP_ADDRESSU
,
2791 case D3DRENDERSTATE_TEXTUREADDRESSV
:
2792 hr
= IWineD3DDevice_SetSamplerState(This
->wineD3DDevice
,
2793 0, WINED3DSAMP_ADDRESSV
,
2797 case D3DRENDERSTATE_BORDERCOLOR
:
2798 /* This should probably just forward to the corresponding sampler
2799 * state. Needs tests. */
2800 FIXME("Unhandled render state D3DRENDERSTATE_BORDERCOLOR.\n");
2805 if (RenderStateType
>= D3DRENDERSTATE_STIPPLEPATTERN00
2806 && RenderStateType
<= D3DRENDERSTATE_STIPPLEPATTERN31
)
2808 FIXME("Unhandled stipple pattern render state (%#x).\n",
2814 hr
= IWineD3DDevice_SetRenderState(This
->wineD3DDevice
,
2819 LeaveCriticalSection(&ddraw_cs
);
2823 static HRESULT WINAPI
2824 IDirect3DDeviceImpl_7_SetRenderState_FPUSetup(IDirect3DDevice7
*iface
,
2825 D3DRENDERSTATETYPE RenderStateType
,
2828 return IDirect3DDeviceImpl_7_SetRenderState(iface
, RenderStateType
, Value
);
2831 static HRESULT WINAPI
2832 IDirect3DDeviceImpl_7_SetRenderState_FPUPreserve(IDirect3DDevice7
*iface
,
2833 D3DRENDERSTATETYPE RenderStateType
,
2839 old_fpucw
= d3d_fpu_setup();
2840 hr
= IDirect3DDeviceImpl_7_SetRenderState(iface
, RenderStateType
, Value
);
2841 set_fpu_control_word(old_fpucw
);
2846 static HRESULT WINAPI
2847 IDirect3DDeviceImpl_3_SetRenderState(IDirect3DDevice3
*iface
,
2848 D3DRENDERSTATETYPE RenderStateType
,
2851 /* Note about D3DRENDERSTATE_TEXTUREMAPBLEND implementation: most of values
2852 for this state can be directly mapped to texture stage colorop and alphaop, but
2853 D3DTBLEND_MODULATE is tricky: it uses alpha from texture when available and alpha
2854 from diffuse otherwise. So changing the texture must be monitored in SetTexture to modify
2855 alphaarg when needed.
2857 Aliens vs Predator 1 depends on accurate D3DTBLEND_MODULATE emulation
2859 Legacy texture blending (TEXTUREMAPBLEND) and texture stage states: directx6 docs state that
2860 TEXTUREMAPBLEND is deprecated, yet can still be used. Games must not use both or results
2861 are undefined. D3DTBLEND_MODULATE mode in particular is dependent on texture pixel format and
2862 requires fixup of stage 0 texture states when texture changes, but this fixup can interfere
2863 with games not using this deprecated state. So a flag 'legacyTextureBlending' has to be kept
2864 in device - TRUE if the app is using TEXTUREMAPBLEND.
2866 Tests show that setting TEXTUREMAPBLEND on native doesn't seem to change values returned by
2867 GetTextureStageState and vice versa. Not so on Wine, but it is 'undefined' anyway so, probably, ok,
2868 unless some broken game will be found that cares. */
2871 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
2872 TRACE("(%p)->(%08x,%d)\n", This
, RenderStateType
, Value
);
2874 EnterCriticalSection(&ddraw_cs
);
2876 switch(RenderStateType
)
2878 case D3DRENDERSTATE_TEXTUREHANDLE
:
2882 hr
= IWineD3DDevice_SetTexture(This
->wineD3DDevice
,
2888 if(Value
> This
->numHandles
)
2890 FIXME("Specified handle %d out of range\n", Value
);
2891 hr
= DDERR_INVALIDPARAMS
;
2894 if(This
->Handles
[Value
- 1].type
!= DDrawHandle_Texture
)
2896 FIXME("Handle %d isn't a texture handle\n", Value
);
2897 hr
= DDERR_INVALIDPARAMS
;
2902 IDirectDrawSurfaceImpl
*surf
= This
->Handles
[Value
- 1].ptr
;
2903 IDirect3DTexture2
*tex
= surf
? (IDirect3DTexture2
*)&surf
->IDirect3DTexture2_vtbl
: NULL
;
2904 hr
= IDirect3DDevice3_SetTexture(iface
, 0, tex
);
2909 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2911 This
->legacyTextureBlending
= TRUE
;
2913 switch ( (D3DTEXTUREBLEND
) Value
)
2915 case D3DTBLEND_MODULATE
:
2917 BOOL tex_alpha
= FALSE
;
2918 IWineD3DBaseTexture
*tex
= NULL
;
2919 WINED3DSURFACE_DESC desc
;
2920 DDPIXELFORMAT ddfmt
;
2922 hr
= IWineD3DDevice_GetTexture(This
->wineD3DDevice
,
2926 if(hr
== WINED3D_OK
&& tex
)
2928 memset(&desc
, 0, sizeof(desc
));
2929 hr
= IWineD3DTexture_GetLevelDesc((IWineD3DTexture
*) tex
, 0, &desc
);
2932 ddfmt
.dwSize
= sizeof(ddfmt
);
2933 PixelFormat_WineD3DtoDD(&ddfmt
, desc
.format
);
2934 if (ddfmt
.u5
.dwRGBAlphaBitMask
) tex_alpha
= TRUE
;
2937 IWineD3DBaseTexture_Release(tex
);
2941 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG1
);
2943 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG2
);
2944 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG1
, WINED3DTA_TEXTURE
);
2945 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG2
, WINED3DTA_CURRENT
);
2946 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG1
, WINED3DTA_TEXTURE
);
2947 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG2
, WINED3DTA_CURRENT
);
2948 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLOROP
, WINED3DTOP_MODULATE
);
2954 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLOROP
, WINED3DTOP_ADD
);
2955 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG1
, WINED3DTA_TEXTURE
);
2956 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG2
, WINED3DTA_CURRENT
);
2957 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG2
);
2958 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG2
, WINED3DTA_CURRENT
);
2961 case D3DTBLEND_MODULATEALPHA
:
2962 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG1
, WINED3DTA_TEXTURE
);
2963 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG1
, WINED3DTA_TEXTURE
);
2964 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG2
, WINED3DTA_CURRENT
);
2965 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG2
, WINED3DTA_CURRENT
);
2966 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLOROP
, WINED3DTOP_MODULATE
);
2967 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_MODULATE
);
2970 case D3DTBLEND_COPY
:
2971 case D3DTBLEND_DECAL
:
2972 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG1
, WINED3DTA_TEXTURE
);
2973 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG1
, WINED3DTA_TEXTURE
);
2974 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLOROP
, WINED3DTOP_SELECTARG1
);
2975 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG1
);
2978 case D3DTBLEND_DECALALPHA
:
2979 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLOROP
, WINED3DTOP_BLENDTEXTUREALPHA
);
2980 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG1
, WINED3DTA_TEXTURE
);
2981 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG2
, WINED3DTA_CURRENT
);
2982 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG2
);
2983 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG2
, WINED3DTA_CURRENT
);
2987 ERR("Unhandled texture environment %d !\n",Value
);
2995 hr
= IDirect3DDevice7_SetRenderState((IDirect3DDevice7
*)This
, RenderStateType
, Value
);
2999 LeaveCriticalSection(&ddraw_cs
);
3004 static HRESULT WINAPI
3005 Thunk_IDirect3DDeviceImpl_2_SetRenderState(IDirect3DDevice2
*iface
,
3006 D3DRENDERSTATETYPE RenderStateType
,
3009 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
3010 TRACE_(ddraw_thunk
)("(%p)->(%08x,%d) thunking to IDirect3DDevice3 interface.\n", This
, RenderStateType
, Value
);
3011 return IDirect3DDevice3_SetRenderState((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, RenderStateType
, Value
);
3014 /*****************************************************************************
3015 * Direct3DDevice3::SetLightState
3017 * Sets a light state for Direct3DDevice3 and Direct3DDevice2. The
3018 * light states are forwarded to Direct3DDevice7 render states
3023 * LightStateType: The light state to change
3024 * Value: The value to assign to that light state
3028 * DDERR_INVALIDPARAMS if the parameters were incorrect
3029 * Also check IDirect3DDevice7::SetRenderState
3031 *****************************************************************************/
3032 static HRESULT WINAPI
3033 IDirect3DDeviceImpl_3_SetLightState(IDirect3DDevice3
*iface
,
3034 D3DLIGHTSTATETYPE LightStateType
,
3037 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
3040 TRACE("(%p)->(%08x,%08x)\n", This
, LightStateType
, Value
);
3042 if (!LightStateType
|| (LightStateType
> D3DLIGHTSTATE_COLORVERTEX
))
3044 TRACE("Unexpected Light State Type\n");
3045 return DDERR_INVALIDPARAMS
;
3048 EnterCriticalSection(&ddraw_cs
);
3049 if (LightStateType
== D3DLIGHTSTATE_MATERIAL
/* 1 */)
3051 IDirect3DMaterialImpl
*mat
;
3053 if(Value
== 0) mat
= NULL
;
3054 else if(Value
> This
->numHandles
)
3056 ERR("Material handle out of range(%d)\n", Value
);
3057 LeaveCriticalSection(&ddraw_cs
);
3058 return DDERR_INVALIDPARAMS
;
3060 else if(This
->Handles
[Value
- 1].type
!= DDrawHandle_Material
)
3062 ERR("Invalid handle %d\n", Value
);
3063 LeaveCriticalSection(&ddraw_cs
);
3064 return DDERR_INVALIDPARAMS
;
3068 mat
= This
->Handles
[Value
- 1].ptr
;
3073 TRACE(" activating material %p.\n", mat
);
3078 FIXME(" D3DLIGHTSTATE_MATERIAL called with NULL material !!!\n");
3080 This
->material
= Value
;
3082 else if (LightStateType
== D3DLIGHTSTATE_COLORMODEL
/* 3 */)
3087 ERR("DDCOLOR_MONO should not happen!\n");
3090 /* We are already in this mode */
3091 TRACE("Setting color model to RGB (no-op).\n");
3094 ERR("Unknown color model!\n");
3095 LeaveCriticalSection(&ddraw_cs
);
3096 return DDERR_INVALIDPARAMS
;
3101 D3DRENDERSTATETYPE rs
;
3102 switch (LightStateType
)
3104 case D3DLIGHTSTATE_AMBIENT
: /* 2 */
3105 rs
= D3DRENDERSTATE_AMBIENT
;
3107 case D3DLIGHTSTATE_FOGMODE
: /* 4 */
3108 rs
= D3DRENDERSTATE_FOGVERTEXMODE
;
3110 case D3DLIGHTSTATE_FOGSTART
: /* 5 */
3111 rs
= D3DRENDERSTATE_FOGSTART
;
3113 case D3DLIGHTSTATE_FOGEND
: /* 6 */
3114 rs
= D3DRENDERSTATE_FOGEND
;
3116 case D3DLIGHTSTATE_FOGDENSITY
: /* 7 */
3117 rs
= D3DRENDERSTATE_FOGDENSITY
;
3119 case D3DLIGHTSTATE_COLORVERTEX
: /* 8 */
3120 rs
= D3DRENDERSTATE_COLORVERTEX
;
3123 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType
);
3124 LeaveCriticalSection(&ddraw_cs
);
3125 return DDERR_INVALIDPARAMS
;
3128 hr
= IDirect3DDevice7_SetRenderState((IDirect3DDevice7
*)This
, rs
, Value
);
3129 LeaveCriticalSection(&ddraw_cs
);
3133 LeaveCriticalSection(&ddraw_cs
);
3137 static HRESULT WINAPI
3138 Thunk_IDirect3DDeviceImpl_2_SetLightState(IDirect3DDevice2
*iface
,
3139 D3DLIGHTSTATETYPE LightStateType
,
3142 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
3143 TRACE_(ddraw_thunk
)("(%p)->(%08x,%08x) thunking to IDirect3DDevice3 interface.\n", This
, LightStateType
, Value
);
3144 return IDirect3DDevice3_SetLightState((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, LightStateType
, Value
);
3147 /*****************************************************************************
3148 * IDirect3DDevice3::GetLightState
3150 * Returns the current setting of a light state. The state is read from
3151 * the Direct3DDevice7 render state.
3156 * LightStateType: The light state to return
3157 * Value: The address to store the light state setting at
3161 * DDDERR_INVALIDPARAMS if the parameters were incorrect
3162 * Also see IDirect3DDevice7::GetRenderState
3164 *****************************************************************************/
3165 static HRESULT WINAPI
3166 IDirect3DDeviceImpl_3_GetLightState(IDirect3DDevice3
*iface
,
3167 D3DLIGHTSTATETYPE LightStateType
,
3170 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
3173 TRACE("(%p)->(%08x,%p)\n", This
, LightStateType
, Value
);
3175 if (!LightStateType
|| (LightStateType
> D3DLIGHTSTATE_COLORVERTEX
))
3177 TRACE("Unexpected Light State Type\n");
3178 return DDERR_INVALIDPARAMS
;
3182 return DDERR_INVALIDPARAMS
;
3184 EnterCriticalSection(&ddraw_cs
);
3185 if (LightStateType
== D3DLIGHTSTATE_MATERIAL
/* 1 */)
3187 *Value
= This
->material
;
3189 else if (LightStateType
== D3DLIGHTSTATE_COLORMODEL
/* 3 */)
3191 *Value
= D3DCOLOR_RGB
;
3195 D3DRENDERSTATETYPE rs
;
3196 switch (LightStateType
)
3198 case D3DLIGHTSTATE_AMBIENT
: /* 2 */
3199 rs
= D3DRENDERSTATE_AMBIENT
;
3201 case D3DLIGHTSTATE_FOGMODE
: /* 4 */
3202 rs
= D3DRENDERSTATE_FOGVERTEXMODE
;
3204 case D3DLIGHTSTATE_FOGSTART
: /* 5 */
3205 rs
= D3DRENDERSTATE_FOGSTART
;
3207 case D3DLIGHTSTATE_FOGEND
: /* 6 */
3208 rs
= D3DRENDERSTATE_FOGEND
;
3210 case D3DLIGHTSTATE_FOGDENSITY
: /* 7 */
3211 rs
= D3DRENDERSTATE_FOGDENSITY
;
3213 case D3DLIGHTSTATE_COLORVERTEX
: /* 8 */
3214 rs
= D3DRENDERSTATE_COLORVERTEX
;
3217 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType
);
3218 LeaveCriticalSection(&ddraw_cs
);
3219 return DDERR_INVALIDPARAMS
;
3222 hr
= IDirect3DDevice7_GetRenderState((IDirect3DDevice7
*)This
, rs
, Value
);
3223 LeaveCriticalSection(&ddraw_cs
);
3227 LeaveCriticalSection(&ddraw_cs
);
3231 static HRESULT WINAPI
3232 Thunk_IDirect3DDeviceImpl_2_GetLightState(IDirect3DDevice2
*iface
,
3233 D3DLIGHTSTATETYPE LightStateType
,
3236 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
3237 TRACE_(ddraw_thunk
)("(%p)->(%08x,%p) thunking to IDirect3DDevice3 interface.\n", This
, LightStateType
, Value
);
3238 return IDirect3DDevice3_GetLightState((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, LightStateType
, Value
);
3241 /*****************************************************************************
3242 * IDirect3DDevice7::SetTransform
3244 * Assigns a D3DMATRIX to a transform type. The transform types are defined
3245 * in include/d3dtypes.h.
3246 * The D3DTRANSFORMSTATE_WORLD (=1) is translated to D3DTS_WORLDMATRIX(0)
3247 * (=255) for wined3d, because the 1 transform state was removed in d3d8
3248 * and WineD3D already understands the replacement D3DTS_WORLDMATRIX(0)
3250 * Version 2, 3 and 7
3253 * TransformStateType: transform state to set
3254 * Matrix: Matrix to assign to the state
3258 * DDERR_INVALIDPARAMS if Matrix == NULL
3259 * For details see IWineD3DDevice::SetTransform
3261 *****************************************************************************/
3263 IDirect3DDeviceImpl_7_SetTransform(IDirect3DDevice7
*iface
,
3264 D3DTRANSFORMSTATETYPE TransformStateType
,
3267 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
3268 D3DTRANSFORMSTATETYPE type
;
3270 TRACE("(%p)->(%08x,%p): Relay\n", This
, TransformStateType
, Matrix
);
3272 switch(TransformStateType
)
3274 case D3DTRANSFORMSTATE_WORLD
: type
= WINED3DTS_WORLDMATRIX(0); break;
3275 case D3DTRANSFORMSTATE_WORLD1
: type
= WINED3DTS_WORLDMATRIX(1); break;
3276 case D3DTRANSFORMSTATE_WORLD2
: type
= WINED3DTS_WORLDMATRIX(2); break;
3277 case D3DTRANSFORMSTATE_WORLD3
: type
= WINED3DTS_WORLDMATRIX(3); break;
3278 default: type
= TransformStateType
;
3282 return DDERR_INVALIDPARAMS
;
3284 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3285 EnterCriticalSection(&ddraw_cs
);
3286 hr
= IWineD3DDevice_SetTransform(This
->wineD3DDevice
,
3288 (WINED3DMATRIX
*) Matrix
);
3289 LeaveCriticalSection(&ddraw_cs
);
3293 static HRESULT WINAPI
3294 IDirect3DDeviceImpl_7_SetTransform_FPUSetup(IDirect3DDevice7
*iface
,
3295 D3DTRANSFORMSTATETYPE TransformStateType
,
3298 return IDirect3DDeviceImpl_7_SetTransform(iface
, TransformStateType
, Matrix
);
3301 static HRESULT WINAPI
3302 IDirect3DDeviceImpl_7_SetTransform_FPUPreserve(IDirect3DDevice7
*iface
,
3303 D3DTRANSFORMSTATETYPE TransformStateType
,
3309 old_fpucw
= d3d_fpu_setup();
3310 hr
= IDirect3DDeviceImpl_7_SetTransform(iface
, TransformStateType
, Matrix
);
3311 set_fpu_control_word(old_fpucw
);
3316 static HRESULT WINAPI
3317 Thunk_IDirect3DDeviceImpl_3_SetTransform(IDirect3DDevice3
*iface
,
3318 D3DTRANSFORMSTATETYPE TransformStateType
,
3319 D3DMATRIX
*D3DMatrix
)
3321 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
3322 TRACE_(ddraw_thunk
)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This
, TransformStateType
, D3DMatrix
);
3323 return IDirect3DDevice7_SetTransform((IDirect3DDevice7
*)This
, TransformStateType
, D3DMatrix
);
3326 static HRESULT WINAPI
3327 Thunk_IDirect3DDeviceImpl_2_SetTransform(IDirect3DDevice2
*iface
,
3328 D3DTRANSFORMSTATETYPE TransformStateType
,
3329 D3DMATRIX
*D3DMatrix
)
3331 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
3332 TRACE_(ddraw_thunk
)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This
, TransformStateType
, D3DMatrix
);
3333 return IDirect3DDevice7_SetTransform((IDirect3DDevice7
*)This
, TransformStateType
, D3DMatrix
);
3336 /*****************************************************************************
3337 * IDirect3DDevice7::GetTransform
3339 * Returns the matrix assigned to a transform state
3340 * D3DTRANSFORMSTATE_WORLD is translated to D3DTS_WORLDMATRIX(0), see
3344 * TransformStateType: State to read the matrix from
3345 * Matrix: Address to store the matrix at
3349 * DDERR_INVALIDPARAMS if Matrix == NULL
3350 * For details, see IWineD3DDevice::GetTransform
3352 *****************************************************************************/
3354 IDirect3DDeviceImpl_7_GetTransform(IDirect3DDevice7
*iface
,
3355 D3DTRANSFORMSTATETYPE TransformStateType
,
3358 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
3359 D3DTRANSFORMSTATETYPE type
;
3361 TRACE("(%p)->(%08x,%p): Relay\n", This
, TransformStateType
, Matrix
);
3363 switch(TransformStateType
)
3365 case D3DTRANSFORMSTATE_WORLD
: type
= WINED3DTS_WORLDMATRIX(0); break;
3366 case D3DTRANSFORMSTATE_WORLD1
: type
= WINED3DTS_WORLDMATRIX(1); break;
3367 case D3DTRANSFORMSTATE_WORLD2
: type
= WINED3DTS_WORLDMATRIX(2); break;
3368 case D3DTRANSFORMSTATE_WORLD3
: type
= WINED3DTS_WORLDMATRIX(3); break;
3369 default: type
= TransformStateType
;
3373 return DDERR_INVALIDPARAMS
;
3375 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3376 EnterCriticalSection(&ddraw_cs
);
3377 hr
= IWineD3DDevice_GetTransform(This
->wineD3DDevice
, type
, (WINED3DMATRIX
*) Matrix
);
3378 LeaveCriticalSection(&ddraw_cs
);
3382 static HRESULT WINAPI
3383 IDirect3DDeviceImpl_7_GetTransform_FPUSetup(IDirect3DDevice7
*iface
,
3384 D3DTRANSFORMSTATETYPE TransformStateType
,
3387 return IDirect3DDeviceImpl_7_GetTransform(iface
, TransformStateType
, Matrix
);
3390 static HRESULT WINAPI
3391 IDirect3DDeviceImpl_7_GetTransform_FPUPreserve(IDirect3DDevice7
*iface
,
3392 D3DTRANSFORMSTATETYPE TransformStateType
,
3398 old_fpucw
= d3d_fpu_setup();
3399 hr
= IDirect3DDeviceImpl_7_GetTransform(iface
, TransformStateType
, Matrix
);
3400 set_fpu_control_word(old_fpucw
);
3405 static HRESULT WINAPI
3406 Thunk_IDirect3DDeviceImpl_3_GetTransform(IDirect3DDevice3
*iface
,
3407 D3DTRANSFORMSTATETYPE TransformStateType
,
3408 D3DMATRIX
*D3DMatrix
)
3410 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
3411 TRACE_(ddraw_thunk
)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This
, TransformStateType
, D3DMatrix
);
3412 return IDirect3DDevice7_GetTransform((IDirect3DDevice7
*)This
, TransformStateType
, D3DMatrix
);
3415 static HRESULT WINAPI
3416 Thunk_IDirect3DDeviceImpl_2_GetTransform(IDirect3DDevice2
*iface
,
3417 D3DTRANSFORMSTATETYPE TransformStateType
,
3418 D3DMATRIX
*D3DMatrix
)
3420 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
3421 TRACE_(ddraw_thunk
)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This
, TransformStateType
, D3DMatrix
);
3422 return IDirect3DDevice7_GetTransform((IDirect3DDevice7
*)This
, TransformStateType
, D3DMatrix
);
3425 /*****************************************************************************
3426 * IDirect3DDevice7::MultiplyTransform
3428 * Multiplies the already-set transform matrix of a transform state
3429 * with another matrix. For the world matrix, see SetTransform
3431 * Version 2, 3 and 7
3434 * TransformStateType: Transform state to multiply
3435 * D3DMatrix Matrix to multiply with.
3439 * DDERR_INVALIDPARAMS if D3DMatrix is NULL
3440 * For details, see IWineD3DDevice::MultiplyTransform
3442 *****************************************************************************/
3444 IDirect3DDeviceImpl_7_MultiplyTransform(IDirect3DDevice7
*iface
,
3445 D3DTRANSFORMSTATETYPE TransformStateType
,
3446 D3DMATRIX
*D3DMatrix
)
3448 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
3450 D3DTRANSFORMSTATETYPE type
;
3451 TRACE("(%p)->(%08x,%p): Relay\n", This
, TransformStateType
, D3DMatrix
);
3453 switch(TransformStateType
)
3455 case D3DTRANSFORMSTATE_WORLD
: type
= WINED3DTS_WORLDMATRIX(0); break;
3456 case D3DTRANSFORMSTATE_WORLD1
: type
= WINED3DTS_WORLDMATRIX(1); break;
3457 case D3DTRANSFORMSTATE_WORLD2
: type
= WINED3DTS_WORLDMATRIX(2); break;
3458 case D3DTRANSFORMSTATE_WORLD3
: type
= WINED3DTS_WORLDMATRIX(3); break;
3459 default: type
= TransformStateType
;
3462 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3463 EnterCriticalSection(&ddraw_cs
);
3464 hr
= IWineD3DDevice_MultiplyTransform(This
->wineD3DDevice
,
3466 (WINED3DMATRIX
*) D3DMatrix
);
3467 LeaveCriticalSection(&ddraw_cs
);
3471 static HRESULT WINAPI
3472 IDirect3DDeviceImpl_7_MultiplyTransform_FPUSetup(IDirect3DDevice7
*iface
,
3473 D3DTRANSFORMSTATETYPE TransformStateType
,
3474 D3DMATRIX
*D3DMatrix
)
3476 return IDirect3DDeviceImpl_7_MultiplyTransform(iface
, TransformStateType
, D3DMatrix
);
3479 static HRESULT WINAPI
3480 IDirect3DDeviceImpl_7_MultiplyTransform_FPUPreserve(IDirect3DDevice7
*iface
,
3481 D3DTRANSFORMSTATETYPE TransformStateType
,
3482 D3DMATRIX
*D3DMatrix
)
3487 old_fpucw
= d3d_fpu_setup();
3488 hr
= IDirect3DDeviceImpl_7_MultiplyTransform(iface
, TransformStateType
, D3DMatrix
);
3489 set_fpu_control_word(old_fpucw
);
3494 static HRESULT WINAPI
3495 Thunk_IDirect3DDeviceImpl_3_MultiplyTransform(IDirect3DDevice3
*iface
,
3496 D3DTRANSFORMSTATETYPE TransformStateType
,
3497 D3DMATRIX
*D3DMatrix
)
3499 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
3500 TRACE_(ddraw_thunk
)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This
, TransformStateType
, D3DMatrix
);
3501 return IDirect3DDevice7_MultiplyTransform((IDirect3DDevice7
*)This
, TransformStateType
, D3DMatrix
);
3504 static HRESULT WINAPI
3505 Thunk_IDirect3DDeviceImpl_2_MultiplyTransform(IDirect3DDevice2
*iface
,
3506 D3DTRANSFORMSTATETYPE TransformStateType
,
3507 D3DMATRIX
*D3DMatrix
)
3509 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
3510 TRACE_(ddraw_thunk
)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This
, TransformStateType
, D3DMatrix
);
3511 return IDirect3DDevice7_MultiplyTransform((IDirect3DDevice7
*)This
, TransformStateType
, D3DMatrix
);
3514 /*****************************************************************************
3515 * IDirect3DDevice7::DrawPrimitive
3517 * Draws primitives based on vertices in an application-provided pointer
3519 * Version 2, 3 and 7. The IDirect3DDevice2 thunk converts the fixed vertex type into
3520 * an FVF format for D3D7
3523 * PrimitiveType: The type of the primitives to draw
3524 * Vertex type: Flexible vertex format vertex description
3525 * Vertices: Pointer to the vertex array
3526 * VertexCount: The number of vertices to draw
3527 * Flags: As usual a few flags
3531 * DDERR_INVALIDPARAMS if Vertices is NULL
3532 * For details, see IWineD3DDevice::DrawPrimitiveUP
3534 *****************************************************************************/
3536 IDirect3DDeviceImpl_7_DrawPrimitive(IDirect3DDevice7
*iface
,
3537 D3DPRIMITIVETYPE PrimitiveType
,
3543 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
3546 TRACE("(%p)->(%08x,%08x,%p,%08x,%08x): Relay!\n", This
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3549 return DDERR_INVALIDPARAMS
;
3551 /* Get the stride */
3552 stride
= get_flexible_vertex_size(VertexType
);
3555 EnterCriticalSection(&ddraw_cs
);
3556 hr
= IWineD3DDevice_SetVertexDeclaration(This
->wineD3DDevice
,
3557 IDirectDrawImpl_FindDecl(This
->ddraw
, VertexType
));
3560 LeaveCriticalSection(&ddraw_cs
);
3564 /* This method translates to the user pointer draw of WineD3D */
3565 IWineD3DDevice_SetPrimitiveType(This
->wineD3DDevice
, PrimitiveType
);
3566 hr
= IWineD3DDevice_DrawPrimitiveUP(This
->wineD3DDevice
, VertexCount
, Vertices
, stride
);
3567 LeaveCriticalSection(&ddraw_cs
);
3571 static HRESULT WINAPI
3572 IDirect3DDeviceImpl_7_DrawPrimitive_FPUSetup(IDirect3DDevice7
*iface
,
3573 D3DPRIMITIVETYPE PrimitiveType
,
3579 return IDirect3DDeviceImpl_7_DrawPrimitive(iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3582 static HRESULT WINAPI
3583 IDirect3DDeviceImpl_7_DrawPrimitive_FPUPreserve(IDirect3DDevice7
*iface
,
3584 D3DPRIMITIVETYPE PrimitiveType
,
3593 old_fpucw
= d3d_fpu_setup();
3594 hr
= IDirect3DDeviceImpl_7_DrawPrimitive(iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3595 set_fpu_control_word(old_fpucw
);
3600 static HRESULT WINAPI
3601 Thunk_IDirect3DDeviceImpl_3_DrawPrimitive(IDirect3DDevice3
*iface
,
3602 D3DPRIMITIVETYPE PrimitiveType
,
3608 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
3609 TRACE_(ddraw_thunk
)("(%p)->(%08x,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3610 return IDirect3DDevice7_DrawPrimitive((IDirect3DDevice7
*)This
,
3611 PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3614 static HRESULT WINAPI
3615 Thunk_IDirect3DDeviceImpl_2_DrawPrimitive(IDirect3DDevice2
*iface
,
3616 D3DPRIMITIVETYPE PrimitiveType
,
3617 D3DVERTEXTYPE VertexType
,
3622 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
3624 TRACE_(ddraw_thunk
)("(%p)->(%08x,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3628 case D3DVT_VERTEX
: FVF
= D3DFVF_VERTEX
; break;
3629 case D3DVT_LVERTEX
: FVF
= D3DFVF_LVERTEX
; break;
3630 case D3DVT_TLVERTEX
: FVF
= D3DFVF_TLVERTEX
; break;
3632 ERR("Unexpected vertex type %d\n", VertexType
);
3633 return DDERR_INVALIDPARAMS
; /* Should never happen */
3636 return IDirect3DDevice7_DrawPrimitive((IDirect3DDevice7
*)This
, PrimitiveType
, FVF
, Vertices
, VertexCount
, Flags
);
3639 /*****************************************************************************
3640 * IDirect3DDevice7::DrawIndexedPrimitive
3642 * Draws vertices from an application-provided pointer, based on the index
3643 * numbers in a WORD array.
3645 * Version 2, 3 and 7. The version 7 thunk translates the vertex type into
3646 * an FVF format for D3D7
3649 * PrimitiveType: The primitive type to draw
3650 * VertexType: The FVF vertex description
3651 * Vertices: Pointer to the vertex array
3653 * Indices: Pointer to the index array
3654 * IndexCount: Number of indices = Number of vertices to draw
3655 * Flags: As usual, some flags
3659 * DDERR_INVALIDPARAMS if Vertices or Indices is NULL
3660 * For details, see IWineD3DDevice::DrawIndexedPrimitiveUP
3662 *****************************************************************************/
3664 IDirect3DDeviceImpl_7_DrawIndexedPrimitive(IDirect3DDevice7
*iface
,
3665 D3DPRIMITIVETYPE PrimitiveType
,
3673 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
3675 TRACE("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x): Relay!\n", This
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3677 /* Set the D3DDevice's FVF */
3678 EnterCriticalSection(&ddraw_cs
);
3679 hr
= IWineD3DDevice_SetVertexDeclaration(This
->wineD3DDevice
,
3680 IDirectDrawImpl_FindDecl(This
->ddraw
, VertexType
));
3683 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This
, hr
);
3684 LeaveCriticalSection(&ddraw_cs
);
3688 IWineD3DDevice_SetPrimitiveType(This
->wineD3DDevice
, PrimitiveType
);
3689 hr
= IWineD3DDevice_DrawIndexedPrimitiveUP(This
->wineD3DDevice
, IndexCount
, Indices
,
3690 WINED3DFMT_R16_UINT
, Vertices
, get_flexible_vertex_size(VertexType
));
3691 LeaveCriticalSection(&ddraw_cs
);
3695 static HRESULT WINAPI
3696 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUSetup(IDirect3DDevice7
*iface
,
3697 D3DPRIMITIVETYPE PrimitiveType
,
3705 return IDirect3DDeviceImpl_7_DrawIndexedPrimitive(iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3708 static HRESULT WINAPI
3709 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUPreserve(IDirect3DDevice7
*iface
,
3710 D3DPRIMITIVETYPE PrimitiveType
,
3721 old_fpucw
= d3d_fpu_setup();
3722 hr
= IDirect3DDeviceImpl_7_DrawIndexedPrimitive(iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3723 set_fpu_control_word(old_fpucw
);
3728 static HRESULT WINAPI
3729 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive(IDirect3DDevice3
*iface
,
3730 D3DPRIMITIVETYPE PrimitiveType
,
3738 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
3739 TRACE_(ddraw_thunk
)("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3740 return IDirect3DDevice7_DrawIndexedPrimitive((IDirect3DDevice7
*)This
,
3741 PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3744 static HRESULT WINAPI
3745 Thunk_IDirect3DDeviceImpl_2_DrawIndexedPrimitive(IDirect3DDevice2
*iface
,
3746 D3DPRIMITIVETYPE PrimitiveType
,
3747 D3DVERTEXTYPE VertexType
,
3755 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
3756 TRACE_(ddraw_thunk
)("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3760 case D3DVT_VERTEX
: FVF
= D3DFVF_VERTEX
; break;
3761 case D3DVT_LVERTEX
: FVF
= D3DFVF_LVERTEX
; break;
3762 case D3DVT_TLVERTEX
: FVF
= D3DFVF_TLVERTEX
; break;
3764 ERR("Unexpected vertex type %d\n", VertexType
);
3765 return DDERR_INVALIDPARAMS
; /* Should never happen */
3768 return IDirect3DDevice7_DrawIndexedPrimitive((IDirect3DDevice7
*)This
,
3769 PrimitiveType
, FVF
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3772 /*****************************************************************************
3773 * IDirect3DDevice7::SetClipStatus
3775 * Sets the clip status. This defines things as clipping conditions and
3776 * the extents of the clipping region.
3778 * Version 2, 3 and 7
3784 * D3D_OK because it's a stub
3785 * (DDERR_INVALIDPARAMS if ClipStatus == NULL)
3787 *****************************************************************************/
3788 static HRESULT WINAPI
3789 IDirect3DDeviceImpl_7_SetClipStatus(IDirect3DDevice7
*iface
,
3790 D3DCLIPSTATUS
*ClipStatus
)
3792 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
3793 FIXME("(%p)->(%p): Stub!\n", This
, ClipStatus
);
3795 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them
3796 * Perhaps this needs a new data type and an additional IWineD3DDevice method
3798 /* return IWineD3DDevice_SetClipStatus(This->wineD3DDevice, ClipStatus);*/
3802 static HRESULT WINAPI
3803 Thunk_IDirect3DDeviceImpl_3_SetClipStatus(IDirect3DDevice3
*iface
,
3804 D3DCLIPSTATUS
*ClipStatus
)
3806 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
3807 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This
, ClipStatus
);
3808 return IDirect3DDevice7_SetClipStatus((IDirect3DDevice7
*)This
, ClipStatus
);
3811 static HRESULT WINAPI
3812 Thunk_IDirect3DDeviceImpl_2_SetClipStatus(IDirect3DDevice2
*iface
,
3813 D3DCLIPSTATUS
*ClipStatus
)
3815 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
3816 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This
, ClipStatus
);
3817 return IDirect3DDevice7_SetClipStatus((IDirect3DDevice7
*)This
, ClipStatus
);
3820 /*****************************************************************************
3821 * IDirect3DDevice7::GetClipStatus
3823 * Returns the clip status
3826 * ClipStatus: Address to write the clip status to
3829 * D3D_OK because it's a stub
3831 *****************************************************************************/
3832 static HRESULT WINAPI
3833 IDirect3DDeviceImpl_7_GetClipStatus(IDirect3DDevice7
*iface
,
3834 D3DCLIPSTATUS
*ClipStatus
)
3836 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
3837 FIXME("(%p)->(%p): Stub!\n", This
, ClipStatus
);
3839 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them */
3840 /* return IWineD3DDevice_GetClipStatus(This->wineD3DDevice, ClipStatus);*/
3844 static HRESULT WINAPI
3845 Thunk_IDirect3DDeviceImpl_3_GetClipStatus(IDirect3DDevice3
*iface
,
3846 D3DCLIPSTATUS
*ClipStatus
)
3848 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
3849 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This
, ClipStatus
);
3850 return IDirect3DDevice7_GetClipStatus((IDirect3DDevice7
*)This
, ClipStatus
);
3853 static HRESULT WINAPI
3854 Thunk_IDirect3DDeviceImpl_2_GetClipStatus(IDirect3DDevice2
*iface
,
3855 D3DCLIPSTATUS
*ClipStatus
)
3857 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
3858 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This
, ClipStatus
);
3859 return IDirect3DDevice7_GetClipStatus((IDirect3DDevice7
*)This
, ClipStatus
);
3862 /*****************************************************************************
3863 * IDirect3DDevice::DrawPrimitiveStrided
3865 * Draws vertices described by a D3DDRAWPRIMITIVESTRIDEDDATA structure.
3870 * PrimitiveType: The primitive type to draw
3871 * VertexType: The FVF description of the vertices to draw (for the stride??)
3872 * D3DDrawPrimStrideData: A D3DDRAWPRIMITIVESTRIDEDDATA structure describing
3873 * the vertex data locations
3874 * VertexCount: The number of vertices to draw
3878 * D3D_OK, because it's a stub
3879 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
3880 * (For details, see IWineD3DDevice::DrawPrimitiveStrided)
3882 *****************************************************************************/
3884 IDirect3DDeviceImpl_7_DrawPrimitiveStrided(IDirect3DDevice7
*iface
,
3885 D3DPRIMITIVETYPE PrimitiveType
,
3887 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
3891 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
3892 WineDirect3DVertexStridedData WineD3DStrided
;
3896 TRACE("(%p)->(%08x,%08x,%p,%08x,%08x): stub!\n", This
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
3898 memset(&WineD3DStrided
, 0, sizeof(WineD3DStrided
));
3899 /* Get the strided data right. the wined3d structure is a bit bigger
3900 * Watch out: The contents of the strided data are determined by the fvf,
3901 * not by the members set in D3DDrawPrimStrideData. So it's valid
3902 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
3903 * not set in the fvf.
3905 if(VertexType
& D3DFVF_POSITION_MASK
)
3907 WineD3DStrided
.position
.format
= WINED3DFMT_R32G32B32_FLOAT
;
3908 WineD3DStrided
.position
.lpData
= D3DDrawPrimStrideData
->position
.lpvData
;
3909 WineD3DStrided
.position
.dwStride
= D3DDrawPrimStrideData
->position
.dwStride
;
3910 if (VertexType
& D3DFVF_XYZRHW
)
3912 WineD3DStrided
.position
.format
= WINED3DFMT_R32G32B32A32_FLOAT
;
3913 WineD3DStrided
.position_transformed
= TRUE
;
3915 WineD3DStrided
.position_transformed
= FALSE
;
3918 if(VertexType
& D3DFVF_NORMAL
)
3920 WineD3DStrided
.normal
.format
= WINED3DFMT_R32G32B32_FLOAT
;
3921 WineD3DStrided
.normal
.lpData
= D3DDrawPrimStrideData
->normal
.lpvData
;
3922 WineD3DStrided
.normal
.dwStride
= D3DDrawPrimStrideData
->normal
.dwStride
;
3925 if(VertexType
& D3DFVF_DIFFUSE
)
3927 WineD3DStrided
.diffuse
.format
= WINED3DFMT_B8G8R8A8_UNORM
;
3928 WineD3DStrided
.diffuse
.lpData
= D3DDrawPrimStrideData
->diffuse
.lpvData
;
3929 WineD3DStrided
.diffuse
.dwStride
= D3DDrawPrimStrideData
->diffuse
.dwStride
;
3932 if(VertexType
& D3DFVF_SPECULAR
)
3934 WineD3DStrided
.specular
.format
= WINED3DFMT_B8G8R8A8_UNORM
;
3935 WineD3DStrided
.specular
.lpData
= D3DDrawPrimStrideData
->specular
.lpvData
;
3936 WineD3DStrided
.specular
.dwStride
= D3DDrawPrimStrideData
->specular
.dwStride
;
3939 for( i
= 0; i
< GET_TEXCOUNT_FROM_FVF(VertexType
); i
++)
3941 switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType
, i
))
3943 case 1: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32_FLOAT
; break;
3944 case 2: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32G32_FLOAT
; break;
3945 case 3: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32G32B32_FLOAT
; break;
3946 case 4: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32G32B32A32_FLOAT
; break;
3947 default: ERR("Unexpected texture coordinate size %d\n",
3948 GET_TEXCOORD_SIZE_FROM_FVF(VertexType
, i
));
3950 WineD3DStrided
.texCoords
[i
].lpData
= D3DDrawPrimStrideData
->textureCoords
[i
].lpvData
;
3951 WineD3DStrided
.texCoords
[i
].dwStride
= D3DDrawPrimStrideData
->textureCoords
[i
].dwStride
;
3954 /* WineD3D doesn't need the FVF here */
3955 EnterCriticalSection(&ddraw_cs
);
3956 IWineD3DDevice_SetPrimitiveType(This
->wineD3DDevice
, PrimitiveType
);
3957 hr
= IWineD3DDevice_DrawPrimitiveStrided(This
->wineD3DDevice
, VertexCount
, &WineD3DStrided
);
3958 LeaveCriticalSection(&ddraw_cs
);
3962 static HRESULT WINAPI
3963 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUSetup(IDirect3DDevice7
*iface
,
3964 D3DPRIMITIVETYPE PrimitiveType
,
3966 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
3970 return IDirect3DDeviceImpl_7_DrawPrimitiveStrided(iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
3973 static HRESULT WINAPI
3974 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUPreserve(IDirect3DDevice7
*iface
,
3975 D3DPRIMITIVETYPE PrimitiveType
,
3977 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
3984 old_fpucw
= d3d_fpu_setup();
3985 hr
= IDirect3DDeviceImpl_7_DrawPrimitiveStrided(iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
3986 set_fpu_control_word(old_fpucw
);
3991 static HRESULT WINAPI
3992 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided(IDirect3DDevice3
*iface
,
3993 D3DPRIMITIVETYPE PrimitiveType
,
3995 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
3999 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
4000 TRACE_(ddraw_thunk
)("(%p)->(%08x,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
4001 return IDirect3DDevice7_DrawPrimitiveStrided((IDirect3DDevice7
*)This
,
4002 PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
4005 /*****************************************************************************
4006 * IDirect3DDevice7::DrawIndexedPrimitiveStrided
4008 * Draws primitives specified by strided data locations based on indices
4016 * D3D_OK, because it's a stub
4017 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
4018 * (DDERR_INVALIDPARAMS if Indices is NULL)
4019 * (For more details, see IWineD3DDevice::DrawIndexedPrimitiveStrided)
4021 *****************************************************************************/
4023 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(IDirect3DDevice7
*iface
,
4024 D3DPRIMITIVETYPE PrimitiveType
,
4026 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
4032 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
4033 WineDirect3DVertexStridedData WineD3DStrided
;
4037 TRACE("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x)\n", This
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4039 memset(&WineD3DStrided
, 0, sizeof(WineD3DStrided
));
4040 /* Get the strided data right. the wined3d structure is a bit bigger
4041 * Watch out: The contents of the strided data are determined by the fvf,
4042 * not by the members set in D3DDrawPrimStrideData. So it's valid
4043 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
4044 * not set in the fvf.
4046 if(VertexType
& D3DFVF_POSITION_MASK
)
4048 WineD3DStrided
.position
.format
= WINED3DFMT_R32G32B32_FLOAT
;
4049 WineD3DStrided
.position
.lpData
= D3DDrawPrimStrideData
->position
.lpvData
;
4050 WineD3DStrided
.position
.dwStride
= D3DDrawPrimStrideData
->position
.dwStride
;
4051 if (VertexType
& D3DFVF_XYZRHW
)
4053 WineD3DStrided
.position
.format
= WINED3DFMT_R32G32B32A32_FLOAT
;
4054 WineD3DStrided
.position_transformed
= TRUE
;
4056 WineD3DStrided
.position_transformed
= FALSE
;
4059 if(VertexType
& D3DFVF_NORMAL
)
4061 WineD3DStrided
.normal
.format
= WINED3DFMT_R32G32B32_FLOAT
;
4062 WineD3DStrided
.normal
.lpData
= D3DDrawPrimStrideData
->normal
.lpvData
;
4063 WineD3DStrided
.normal
.dwStride
= D3DDrawPrimStrideData
->normal
.dwStride
;
4066 if(VertexType
& D3DFVF_DIFFUSE
)
4068 WineD3DStrided
.diffuse
.format
= WINED3DFMT_B8G8R8A8_UNORM
;
4069 WineD3DStrided
.diffuse
.lpData
= D3DDrawPrimStrideData
->diffuse
.lpvData
;
4070 WineD3DStrided
.diffuse
.dwStride
= D3DDrawPrimStrideData
->diffuse
.dwStride
;
4073 if(VertexType
& D3DFVF_SPECULAR
)
4075 WineD3DStrided
.specular
.format
= WINED3DFMT_B8G8R8A8_UNORM
;
4076 WineD3DStrided
.specular
.lpData
= D3DDrawPrimStrideData
->specular
.lpvData
;
4077 WineD3DStrided
.specular
.dwStride
= D3DDrawPrimStrideData
->specular
.dwStride
;
4080 for( i
= 0; i
< GET_TEXCOUNT_FROM_FVF(VertexType
); i
++)
4082 switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType
, i
))
4084 case 1: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32_FLOAT
; break;
4085 case 2: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32G32_FLOAT
; break;
4086 case 3: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32G32B32_FLOAT
; break;
4087 case 4: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32G32B32A32_FLOAT
; break;
4088 default: ERR("Unexpected texture coordinate size %d\n",
4089 GET_TEXCOORD_SIZE_FROM_FVF(VertexType
, i
));
4091 WineD3DStrided
.texCoords
[i
].lpData
= D3DDrawPrimStrideData
->textureCoords
[i
].lpvData
;
4092 WineD3DStrided
.texCoords
[i
].dwStride
= D3DDrawPrimStrideData
->textureCoords
[i
].dwStride
;
4095 /* WineD3D doesn't need the FVF here */
4096 EnterCriticalSection(&ddraw_cs
);
4097 IWineD3DDevice_SetPrimitiveType(This
->wineD3DDevice
, PrimitiveType
);
4098 hr
= IWineD3DDevice_DrawIndexedPrimitiveStrided(This
->wineD3DDevice
,
4099 IndexCount
, &WineD3DStrided
, VertexCount
, Indices
, WINED3DFMT_R16_UINT
);
4100 LeaveCriticalSection(&ddraw_cs
);
4104 static HRESULT WINAPI
4105 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUSetup(IDirect3DDevice7
*iface
,
4106 D3DPRIMITIVETYPE PrimitiveType
,
4108 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
4114 return IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4117 static HRESULT WINAPI
4118 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUPreserve(IDirect3DDevice7
*iface
,
4119 D3DPRIMITIVETYPE PrimitiveType
,
4121 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
4130 old_fpucw
= d3d_fpu_setup();
4131 hr
= IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4132 set_fpu_control_word(old_fpucw
);
4137 static HRESULT WINAPI
4138 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided(IDirect3DDevice3
*iface
,
4139 D3DPRIMITIVETYPE PrimitiveType
,
4141 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
4147 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
4148 TRACE_(ddraw_thunk
)("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4149 return IDirect3DDevice7_DrawIndexedPrimitiveStrided((IDirect3DDevice7
*)This
, PrimitiveType
,
4150 VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4153 /*****************************************************************************
4154 * IDirect3DDevice7::DrawPrimitiveVB
4156 * Draws primitives from a vertex buffer to the screen.
4161 * PrimitiveType: Type of primitive to be rendered.
4162 * D3DVertexBuf: Source Vertex Buffer
4163 * StartVertex: Index of the first vertex from the buffer to be rendered
4164 * NumVertices: Number of vertices to be rendered
4165 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4169 * DDERR_INVALIDPARAMS if D3DVertexBuf is NULL
4171 *****************************************************************************/
4173 IDirect3DDeviceImpl_7_DrawPrimitiveVB(IDirect3DDevice7
*iface
,
4174 D3DPRIMITIVETYPE PrimitiveType
,
4175 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4180 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
4181 IDirect3DVertexBufferImpl
*vb
= (IDirect3DVertexBufferImpl
*)D3DVertexBuf
;
4185 TRACE("(%p)->(%08x,%p,%08x,%08x,%08x)\n", This
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4190 ERR("(%p) No Vertex buffer specified\n", This
);
4191 return DDERR_INVALIDPARAMS
;
4193 stride
= get_flexible_vertex_size(vb
->fvf
);
4195 EnterCriticalSection(&ddraw_cs
);
4196 hr
= IWineD3DDevice_SetVertexDeclaration(This
->wineD3DDevice
,
4197 vb
->wineD3DVertexDeclaration
);
4200 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This
, hr
);
4201 LeaveCriticalSection(&ddraw_cs
);
4205 /* Set the vertex stream source */
4206 hr
= IWineD3DDevice_SetStreamSource(This
->wineD3DDevice
,
4207 0 /* StreamNumber */,
4208 vb
->wineD3DVertexBuffer
,
4209 0 /* StartVertex - we pass this to DrawPrimitive */,
4213 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This
, hr
);
4214 LeaveCriticalSection(&ddraw_cs
);
4218 /* Now draw the primitives */
4219 IWineD3DDevice_SetPrimitiveType(This
->wineD3DDevice
, PrimitiveType
);
4220 hr
= IWineD3DDevice_DrawPrimitive(This
->wineD3DDevice
, StartVertex
, NumVertices
);
4221 LeaveCriticalSection(&ddraw_cs
);
4225 static HRESULT WINAPI
4226 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUSetup(IDirect3DDevice7
*iface
,
4227 D3DPRIMITIVETYPE PrimitiveType
,
4228 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4233 return IDirect3DDeviceImpl_7_DrawPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4236 static HRESULT WINAPI
4237 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUPreserve(IDirect3DDevice7
*iface
,
4238 D3DPRIMITIVETYPE PrimitiveType
,
4239 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4247 old_fpucw
= d3d_fpu_setup();
4248 hr
= IDirect3DDeviceImpl_7_DrawPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4249 set_fpu_control_word(old_fpucw
);
4254 static HRESULT WINAPI
4255 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB(IDirect3DDevice3
*iface
,
4256 D3DPRIMITIVETYPE PrimitiveType
,
4257 IDirect3DVertexBuffer
*D3DVertexBuf
,
4262 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
4263 IDirect3DVertexBufferImpl
*vb
= D3DVertexBuf
? vb_from_vb1(D3DVertexBuf
) : NULL
;
4264 TRACE_(ddraw_thunk
)("(%p)->(%08x,%p,%08x,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This
, PrimitiveType
, vb
, StartVertex
, NumVertices
, Flags
);
4265 return IDirect3DDevice7_DrawPrimitiveVB((IDirect3DDevice7
*)This
, PrimitiveType
,
4266 (IDirect3DVertexBuffer7
*)vb
, StartVertex
, NumVertices
, Flags
);
4270 /*****************************************************************************
4271 * IDirect3DDevice7::DrawIndexedPrimitiveVB
4273 * Draws primitives from a vertex buffer to the screen
4276 * PrimitiveType: Type of primitive to be rendered.
4277 * D3DVertexBuf: Source Vertex Buffer
4278 * StartVertex: Index of the first vertex from the buffer to be rendered
4279 * NumVertices: Number of vertices to be rendered
4280 * Indices: Array of DWORDs used to index into the Vertices
4281 * IndexCount: Number of indices in Indices
4282 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4286 *****************************************************************************/
4288 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(IDirect3DDevice7
*iface
,
4289 D3DPRIMITIVETYPE PrimitiveType
,
4290 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4297 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
4298 IDirect3DVertexBufferImpl
*vb
= (IDirect3DVertexBufferImpl
*)D3DVertexBuf
;
4299 DWORD stride
= get_flexible_vertex_size(vb
->fvf
);
4300 WORD
*LockedIndices
;
4302 WINED3DBUFFER_DESC desc
;
4304 TRACE("(%p)->(%08x,%p,%d,%d,%p,%d,%08x)\n", This
, PrimitiveType
, vb
, StartVertex
, NumVertices
, Indices
, IndexCount
, Flags
);
4307 * 1) Upload the Indices to the index buffer
4308 * 2) Set the index source
4309 * 3) Set the Vertex Buffer as the Stream source
4310 * 4) Call IWineD3DDevice::DrawIndexedPrimitive
4313 EnterCriticalSection(&ddraw_cs
);
4315 hr
= IWineD3DDevice_SetVertexDeclaration(This
->wineD3DDevice
,
4316 vb
->wineD3DVertexDeclaration
);
4319 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This
, hr
);
4320 LeaveCriticalSection(&ddraw_cs
);
4324 /* check that the buffer is large enough to hold the indices,
4325 * reallocate if necessary.
4327 hr
= IWineD3DBuffer_GetDesc(This
->indexbuffer
, &desc
);
4328 if(desc
.Size
< IndexCount
* sizeof(WORD
))
4330 UINT size
= max(desc
.Size
* 2, IndexCount
* sizeof(WORD
));
4331 IWineD3DBuffer
*buffer
;
4334 TRACE("Growing index buffer to %u bytes\n", size
);
4336 IWineD3DBuffer_GetParent(This
->indexbuffer
, &parent
);
4337 hr
= IWineD3DDevice_CreateIndexBuffer(This
->wineD3DDevice
, size
,
4338 WINED3DUSAGE_DYNAMIC
/* Usage */, WINED3DPOOL_DEFAULT
, &buffer
, parent
,
4339 &ddraw_null_wined3d_parent_ops
);
4342 ERR("(%p) IWineD3DDevice::CreateIndexBuffer failed with hr = %08x\n", This
, hr
);
4343 IParent_Release(parent
);
4344 LeaveCriticalSection(&ddraw_cs
);
4348 IWineD3DBuffer_Release(This
->indexbuffer
);
4349 This
->indexbuffer
= buffer
;
4351 ((IParentImpl
*)parent
)->child
= (IUnknown
*)buffer
;
4352 IParent_Release(parent
);
4355 /* copy the index stream into the index buffer.
4356 * A new IWineD3DDevice method could be created
4357 * which takes an user pointer containing the indices
4358 * or a SetData-Method for the index buffer, which
4359 * overrides the index buffer data with our pointer.
4361 hr
= IWineD3DBuffer_Map(This
->indexbuffer
,
4362 0 /* OffSetToLock */,
4363 IndexCount
* sizeof(WORD
),
4364 (BYTE
**) &LockedIndices
,
4368 ERR("(%p) IWineD3DBuffer::Map failed with hr = %08x\n", This
, hr
);
4369 LeaveCriticalSection(&ddraw_cs
);
4372 memcpy(LockedIndices
, Indices
, IndexCount
* sizeof(WORD
));
4373 hr
= IWineD3DBuffer_Unmap(This
->indexbuffer
);
4376 ERR("(%p) IWineD3DBuffer::Unmap failed with hr = %08x\n", This
, hr
);
4377 LeaveCriticalSection(&ddraw_cs
);
4381 /* Set the index stream */
4382 IWineD3DDevice_SetBaseVertexIndex(This
->wineD3DDevice
, StartVertex
);
4383 hr
= IWineD3DDevice_SetIndexBuffer(This
->wineD3DDevice
, This
->indexbuffer
,
4384 WINED3DFMT_R16_UINT
);
4386 /* Set the vertex stream source */
4387 hr
= IWineD3DDevice_SetStreamSource(This
->wineD3DDevice
,
4388 0 /* StreamNumber */,
4389 vb
->wineD3DVertexBuffer
,
4390 0 /* offset, we pass this to DrawIndexedPrimitive */,
4394 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This
, hr
);
4395 LeaveCriticalSection(&ddraw_cs
);
4400 IWineD3DDevice_SetPrimitiveType(This
->wineD3DDevice
, PrimitiveType
);
4401 hr
= IWineD3DDevice_DrawIndexedPrimitive(This
->wineD3DDevice
, 0 /* StartIndex */, IndexCount
);
4403 LeaveCriticalSection(&ddraw_cs
);
4407 static HRESULT WINAPI
4408 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUSetup(IDirect3DDevice7
*iface
,
4409 D3DPRIMITIVETYPE PrimitiveType
,
4410 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4417 return IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Indices
, IndexCount
, Flags
);
4420 static HRESULT WINAPI
4421 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUPreserve(IDirect3DDevice7
*iface
,
4422 D3DPRIMITIVETYPE PrimitiveType
,
4423 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4433 old_fpucw
= d3d_fpu_setup();
4434 hr
= IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Indices
, IndexCount
, Flags
);
4435 set_fpu_control_word(old_fpucw
);
4440 static HRESULT WINAPI
4441 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB(IDirect3DDevice3
*iface
,
4442 D3DPRIMITIVETYPE PrimitiveType
,
4443 IDirect3DVertexBuffer
*D3DVertexBuf
,
4448 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
4449 IDirect3DVertexBufferImpl
*VB
= vb_from_vb1(D3DVertexBuf
);
4450 TRACE_(ddraw_thunk
)("(%p)->(%08x,%p,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This
, PrimitiveType
, VB
, Indices
, IndexCount
, Flags
);
4452 return IDirect3DDevice7_DrawIndexedPrimitiveVB((IDirect3DDevice7
*)This
, PrimitiveType
,
4453 (IDirect3DVertexBuffer7
*)VB
, 0, IndexCount
, Indices
, IndexCount
, Flags
);
4456 /*****************************************************************************
4457 * IDirect3DDevice7::ComputeSphereVisibility
4459 * Calculates the visibility of spheres in the current viewport. The spheres
4460 * are passed in the Centers and Radii arrays, the results are passed back
4461 * in the ReturnValues array. Return values are either completely visible,
4462 * partially visible or completely invisible.
4463 * The return value consist of a combination of D3DCLIP_* flags, or it's
4464 * 0 if the sphere is completely visible(according to the SDK, not checked)
4469 * Centers: Array containing the sphere centers
4470 * Radii: Array containing the sphere radii
4471 * NumSpheres: The number of centers and radii in the arrays
4473 * ReturnValues: Array to write the results to
4477 * (DDERR_INVALIDPARAMS if Centers, Radii or ReturnValues are NULL)
4478 * (D3DERR_INVALIDMATRIX if the combined world, view and proj matrix
4481 *****************************************************************************/
4483 static DWORD
in_plane(UINT plane
, D3DVECTOR normal
, D3DVALUE origin_plane
, D3DVECTOR center
, D3DVALUE radius
)
4485 float distance
, norm
;
4487 norm
= sqrt( normal
.u1
.x
* normal
.u1
.x
+ normal
.u2
.y
* normal
.u2
.y
+ normal
.u3
.z
* normal
.u3
.z
);
4488 distance
= ( origin_plane
+ normal
.u1
.x
* center
.u1
.x
+ normal
.u2
.y
* center
.u2
.y
+ normal
.u3
.z
* center
.u3
.z
) / norm
;
4490 if ( fabs( distance
) < radius
) return D3DSTATUS_CLIPUNIONLEFT
<< plane
;
4491 if ( distance
< -radius
) return (D3DSTATUS_CLIPUNIONLEFT
| D3DSTATUS_CLIPINTERSECTIONLEFT
) << plane
;
4495 static HRESULT WINAPI
4496 IDirect3DDeviceImpl_7_ComputeSphereVisibility(IDirect3DDevice7
*iface
,
4501 DWORD
*ReturnValues
)
4504 D3DVALUE origin_plane
[6];
4509 TRACE("(%p)->(%p,%p,%08x,%08x,%p)\n", iface
, Centers
, Radii
, NumSpheres
, Flags
, ReturnValues
);
4511 hr
= IDirect3DDeviceImpl_7_GetTransform(iface
, D3DTRANSFORMSTATE_WORLD
, &m
);
4512 if ( hr
!= DD_OK
) return DDERR_INVALIDPARAMS
;
4513 hr
= IDirect3DDeviceImpl_7_GetTransform(iface
, D3DTRANSFORMSTATE_VIEW
, &temp
);
4514 if ( hr
!= DD_OK
) return DDERR_INVALIDPARAMS
;
4515 multiply_matrix_D3D_way(&m
, &m
, &temp
);
4517 hr
= IDirect3DDeviceImpl_7_GetTransform(iface
, D3DTRANSFORMSTATE_PROJECTION
, &temp
);
4518 if ( hr
!= DD_OK
) return DDERR_INVALIDPARAMS
;
4519 multiply_matrix_D3D_way(&m
, &m
, &temp
);
4522 vec
[0].u1
.x
= m
._14
+ m
._11
;
4523 vec
[0].u2
.y
= m
._24
+ m
._21
;
4524 vec
[0].u3
.z
= m
._34
+ m
._31
;
4525 origin_plane
[0] = m
._44
+ m
._41
;
4528 vec
[1].u1
.x
= m
._14
- m
._11
;
4529 vec
[1].u2
.y
= m
._24
- m
._21
;
4530 vec
[1].u3
.z
= m
._34
- m
._31
;
4531 origin_plane
[1] = m
._44
- m
._41
;
4534 vec
[2].u1
.x
= m
._14
- m
._12
;
4535 vec
[2].u2
.y
= m
._24
- m
._22
;
4536 vec
[2].u3
.z
= m
._34
- m
._32
;
4537 origin_plane
[2] = m
._44
- m
._42
;
4540 vec
[3].u1
.x
= m
._14
+ m
._12
;
4541 vec
[3].u2
.y
= m
._24
+ m
._22
;
4542 vec
[3].u3
.z
= m
._34
+ m
._32
;
4543 origin_plane
[3] = m
._44
+ m
._42
;
4546 vec
[4].u1
.x
= m
._13
;
4547 vec
[4].u2
.y
= m
._23
;
4548 vec
[4].u3
.z
= m
._33
;
4549 origin_plane
[4] = m
._43
;
4552 vec
[5].u1
.x
= m
._14
- m
._13
;
4553 vec
[5].u2
.y
= m
._24
- m
._23
;
4554 vec
[5].u3
.z
= m
._34
- m
._33
;
4555 origin_plane
[5] = m
._44
- m
._43
;
4557 for(i
=0; i
<NumSpheres
; i
++)
4559 ReturnValues
[i
] = 0;
4560 for(j
=0; j
<6; j
++) ReturnValues
[i
] |= in_plane(j
, vec
[j
], origin_plane
[j
], Centers
[i
], Radii
[i
]);
4566 static HRESULT WINAPI
4567 Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility(IDirect3DDevice3
*iface
,
4572 DWORD
*ReturnValues
)
4574 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
4575 TRACE_(ddraw_thunk
)("(%p)->(%p,%p,%08x,%08x,%p) thunking to IDirect3DDevice7 interface.\n", This
, Centers
, Radii
, NumSpheres
, Flags
, ReturnValues
);
4576 return IDirect3DDevice7_ComputeSphereVisibility((IDirect3DDevice7
*)This
,
4577 Centers
, Radii
, NumSpheres
, Flags
, ReturnValues
);
4580 /*****************************************************************************
4581 * IDirect3DDevice7::GetTexture
4583 * Returns the texture interface handle assigned to a texture stage.
4584 * The returned texture is AddRefed. This is taken from old ddraw,
4585 * not checked in Windows.
4590 * Stage: Texture stage to read the texture from
4591 * Texture: Address to store the interface pointer at
4595 * DDERR_INVALIDPARAMS if Texture is NULL
4596 * For details, see IWineD3DDevice::GetTexture
4598 *****************************************************************************/
4600 IDirect3DDeviceImpl_7_GetTexture(IDirect3DDevice7
*iface
,
4602 IDirectDrawSurface7
**Texture
)
4604 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
4605 IWineD3DBaseTexture
*Surf
;
4607 TRACE("(%p)->(%d,%p): Relay\n", This
, Stage
, Texture
);
4611 TRACE("Texture == NULL, failing with DDERR_INVALIDPARAMS\n");
4612 return DDERR_INVALIDPARAMS
;
4615 EnterCriticalSection(&ddraw_cs
);
4616 hr
= IWineD3DDevice_GetTexture(This
->wineD3DDevice
, Stage
, &Surf
);
4617 if( (hr
!= D3D_OK
) || (!Surf
) )
4620 LeaveCriticalSection(&ddraw_cs
);
4624 /* GetParent AddRef()s, which is perfectly OK.
4625 * We have passed the IDirectDrawSurface7 interface to WineD3D, so that's OK too.
4627 hr
= IWineD3DBaseTexture_GetParent(Surf
,
4628 (IUnknown
**) Texture
);
4629 LeaveCriticalSection(&ddraw_cs
);
4633 static HRESULT WINAPI
4634 IDirect3DDeviceImpl_7_GetTexture_FPUSetup(IDirect3DDevice7
*iface
,
4636 IDirectDrawSurface7
**Texture
)
4638 return IDirect3DDeviceImpl_7_GetTexture(iface
, Stage
, Texture
);
4641 static HRESULT WINAPI
4642 IDirect3DDeviceImpl_7_GetTexture_FPUPreserve(IDirect3DDevice7
*iface
,
4644 IDirectDrawSurface7
**Texture
)
4649 old_fpucw
= d3d_fpu_setup();
4650 hr
= IDirect3DDeviceImpl_7_GetTexture(iface
, Stage
, Texture
);
4651 set_fpu_control_word(old_fpucw
);
4656 static HRESULT WINAPI
4657 Thunk_IDirect3DDeviceImpl_3_GetTexture(IDirect3DDevice3
*iface
,
4659 IDirect3DTexture2
**Texture2
)
4661 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
4663 IDirectDrawSurface7
*ret_val
;
4665 TRACE_(ddraw_thunk
)("(%p)->(%d,%p) thunking to IDirect3DDevice7 interface.\n", This
, Stage
, Texture2
);
4666 ret
= IDirect3DDevice7_GetTexture((IDirect3DDevice7
*)This
, Stage
, &ret_val
);
4668 *Texture2
= ret_val
? (IDirect3DTexture2
*)&((IDirectDrawSurfaceImpl
*)ret_val
)->IDirect3DTexture2_vtbl
: NULL
;
4670 TRACE_(ddraw_thunk
)(" returning interface %p.\n", *Texture2
);
4675 /*****************************************************************************
4676 * IDirect3DDevice7::SetTexture
4678 * Assigns a texture to a texture stage. Is the texture AddRef-ed?
4683 * Stage: The stage to assign the texture to
4684 * Texture: Interface pointer to the texture surface
4688 * For details, see IWineD3DDevice::SetTexture
4690 *****************************************************************************/
4692 IDirect3DDeviceImpl_7_SetTexture(IDirect3DDevice7
*iface
,
4694 IDirectDrawSurface7
*Texture
)
4696 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
4697 IDirectDrawSurfaceImpl
*surf
= (IDirectDrawSurfaceImpl
*)Texture
;
4699 TRACE("(%p)->(%08x,%p): Relay!\n", This
, Stage
, surf
);
4701 /* Texture may be NULL here */
4702 EnterCriticalSection(&ddraw_cs
);
4703 hr
= IWineD3DDevice_SetTexture(This
->wineD3DDevice
,
4705 surf
? surf
->wineD3DTexture
: NULL
);
4706 LeaveCriticalSection(&ddraw_cs
);
4710 static HRESULT WINAPI
4711 IDirect3DDeviceImpl_7_SetTexture_FPUSetup(IDirect3DDevice7
*iface
,
4713 IDirectDrawSurface7
*Texture
)
4715 return IDirect3DDeviceImpl_7_SetTexture(iface
, Stage
, Texture
);
4718 static HRESULT WINAPI
4719 IDirect3DDeviceImpl_7_SetTexture_FPUPreserve(IDirect3DDevice7
*iface
,
4721 IDirectDrawSurface7
*Texture
)
4726 old_fpucw
= d3d_fpu_setup();
4727 hr
= IDirect3DDeviceImpl_7_SetTexture(iface
, Stage
, Texture
);
4728 set_fpu_control_word(old_fpucw
);
4733 static HRESULT WINAPI
4734 IDirect3DDeviceImpl_3_SetTexture(IDirect3DDevice3
*iface
,
4736 IDirect3DTexture2
*Texture2
)
4738 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
4739 IDirectDrawSurfaceImpl
*tex
= Texture2
? surface_from_texture2(Texture2
) : NULL
;
4742 TRACE("(%p)->(%d,%p)\n", This
, Stage
, tex
);
4744 EnterCriticalSection(&ddraw_cs
);
4746 if (This
->legacyTextureBlending
)
4747 IDirect3DDevice3_GetRenderState(iface
, D3DRENDERSTATE_TEXTUREMAPBLEND
, &texmapblend
);
4749 hr
= IDirect3DDevice7_SetTexture((IDirect3DDevice7
*)This
, Stage
, (IDirectDrawSurface7
*)tex
);
4751 if (This
->legacyTextureBlending
&& texmapblend
== D3DTBLEND_MODULATE
)
4753 /* This fixup is required by the way D3DTBLEND_MODULATE maps to texture stage states.
4754 See IDirect3DDeviceImpl_3_SetRenderState for details. */
4755 BOOL tex_alpha
= FALSE
;
4756 IWineD3DBaseTexture
*tex
= NULL
;
4757 WINED3DSURFACE_DESC desc
;
4758 DDPIXELFORMAT ddfmt
;
4761 result
= IWineD3DDevice_GetTexture(This
->wineD3DDevice
,
4765 if(result
== WINED3D_OK
&& tex
)
4767 memset(&desc
, 0, sizeof(desc
));
4768 result
= IWineD3DTexture_GetLevelDesc((IWineD3DTexture
*) tex
, 0, &desc
);
4769 if (SUCCEEDED(result
))
4771 ddfmt
.dwSize
= sizeof(ddfmt
);
4772 PixelFormat_WineD3DtoDD(&ddfmt
, desc
.format
);
4773 if (ddfmt
.u5
.dwRGBAlphaBitMask
) tex_alpha
= TRUE
;
4776 IWineD3DBaseTexture_Release(tex
);
4779 /* Arg 1/2 are already set to WINED3DTA_TEXTURE/WINED3DTA_CURRENT in case of D3DTBLEND_MODULATE */
4781 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG1
);
4783 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG2
);
4786 LeaveCriticalSection(&ddraw_cs
);
4791 static const struct tss_lookup
4798 {FALSE
, WINED3DTSS_FORCE_DWORD
}, /* 0, unused */
4799 {FALSE
, WINED3DTSS_COLOROP
}, /* 1, D3DTSS_COLOROP */
4800 {FALSE
, WINED3DTSS_COLORARG1
}, /* 2, D3DTSS_COLORARG1 */
4801 {FALSE
, WINED3DTSS_COLORARG2
}, /* 3, D3DTSS_COLORARG2 */
4802 {FALSE
, WINED3DTSS_ALPHAOP
}, /* 4, D3DTSS_ALPHAOP */
4803 {FALSE
, WINED3DTSS_ALPHAARG1
}, /* 5, D3DTSS_ALPHAARG1 */
4804 {FALSE
, WINED3DTSS_ALPHAARG2
}, /* 6, D3DTSS_ALPHAARG2 */
4805 {FALSE
, WINED3DTSS_BUMPENVMAT00
}, /* 7, D3DTSS_BUMPENVMAT00 */
4806 {FALSE
, WINED3DTSS_BUMPENVMAT01
}, /* 8, D3DTSS_BUMPENVMAT01 */
4807 {FALSE
, WINED3DTSS_BUMPENVMAT10
}, /* 9, D3DTSS_BUMPENVMAT10 */
4808 {FALSE
, WINED3DTSS_BUMPENVMAT11
}, /* 10, D3DTSS_BUMPENVMAT11 */
4809 {FALSE
, WINED3DTSS_TEXCOORDINDEX
}, /* 11, D3DTSS_TEXCOORDINDEX */
4810 {TRUE
, WINED3DSAMP_ADDRESSU
}, /* 12, D3DTSS_ADDRESS */
4811 {TRUE
, WINED3DSAMP_ADDRESSU
}, /* 13, D3DTSS_ADDRESSU */
4812 {TRUE
, WINED3DSAMP_ADDRESSV
}, /* 14, D3DTSS_ADDRESSV */
4813 {TRUE
, WINED3DSAMP_BORDERCOLOR
}, /* 15, D3DTSS_BORDERCOLOR */
4814 {TRUE
, WINED3DSAMP_MAGFILTER
}, /* 16, D3DTSS_MAGFILTER */
4815 {TRUE
, WINED3DSAMP_MINFILTER
}, /* 17, D3DTSS_MINFILTER */
4816 {TRUE
, WINED3DSAMP_MIPFILTER
}, /* 18, D3DTSS_MIPFILTER */
4817 {TRUE
, WINED3DSAMP_MIPMAPLODBIAS
}, /* 19, D3DTSS_MIPMAPLODBIAS */
4818 {TRUE
, WINED3DSAMP_MAXMIPLEVEL
}, /* 20, D3DTSS_MAXMIPLEVEL */
4819 {TRUE
, WINED3DSAMP_MAXANISOTROPY
}, /* 21, D3DTSS_MAXANISOTROPY */
4820 {FALSE
, WINED3DTSS_BUMPENVLSCALE
}, /* 22, D3DTSS_BUMPENVLSCALE */
4821 {FALSE
, WINED3DTSS_BUMPENVLOFFSET
}, /* 23, D3DTSS_BUMPENVLOFFSET */
4822 {FALSE
, WINED3DTSS_TEXTURETRANSFORMFLAGS
}, /* 24, D3DTSS_TEXTURETRANSFORMFLAGS */
4825 /*****************************************************************************
4826 * IDirect3DDevice7::GetTextureStageState
4828 * Retrieves a state from a texture stage.
4833 * Stage: The stage to retrieve the state from
4834 * TexStageStateType: The state type to retrieve
4835 * State: Address to store the state's value at
4839 * DDERR_INVALIDPARAMS if State is NULL
4840 * For details, see IWineD3DDevice::GetTextureStageState
4842 *****************************************************************************/
4844 IDirect3DDeviceImpl_7_GetTextureStageState(IDirect3DDevice7
*iface
,
4846 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
4849 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
4851 const struct tss_lookup
*l
= &tss_lookup
[TexStageStateType
];
4852 TRACE("(%p)->(%08x,%08x,%p): Relay!\n", This
, Stage
, TexStageStateType
, State
);
4855 return DDERR_INVALIDPARAMS
;
4857 if (TexStageStateType
> D3DTSS_TEXTURETRANSFORMFLAGS
)
4859 WARN("Invalid TexStageStateType %#x passed.\n", TexStageStateType
);
4864 EnterCriticalSection(&ddraw_cs
);
4866 if (l
->sampler_state
)
4868 hr
= IWineD3DDevice_GetSamplerState(This
->wineD3DDevice
, Stage
, l
->state
, State
);
4870 switch(TexStageStateType
)
4872 /* Mipfilter is a sampler state with different values */
4873 case D3DTSS_MIPFILTER
:
4877 case WINED3DTEXF_NONE
: *State
= D3DTFP_NONE
; break;
4878 case WINED3DTEXF_POINT
: *State
= D3DTFP_POINT
; break;
4879 case WINED3DTEXF_LINEAR
: *State
= D3DTFP_LINEAR
; break;
4881 ERR("Unexpected mipfilter value %#x\n", *State
);
4882 *State
= D3DTFP_NONE
;
4888 /* Magfilter has slightly different values */
4889 case D3DTSS_MAGFILTER
:
4893 case WINED3DTEXF_POINT
: *State
= D3DTFG_POINT
; break;
4894 case WINED3DTEXF_LINEAR
: *State
= D3DTFG_LINEAR
; break;
4895 case WINED3DTEXF_ANISOTROPIC
: *State
= D3DTFG_ANISOTROPIC
; break;
4896 case WINED3DTEXF_FLATCUBIC
: *State
= D3DTFG_FLATCUBIC
; break;
4897 case WINED3DTEXF_GAUSSIANCUBIC
: *State
= D3DTFG_GAUSSIANCUBIC
; break;
4899 ERR("Unexpected wined3d mag filter value %#x\n", *State
);
4900 *State
= D3DTFG_POINT
;
4912 hr
= IWineD3DDevice_GetTextureStageState(This
->wineD3DDevice
, Stage
, l
->state
, State
);
4915 LeaveCriticalSection(&ddraw_cs
);
4919 static HRESULT WINAPI
4920 IDirect3DDeviceImpl_7_GetTextureStageState_FPUSetup(IDirect3DDevice7
*iface
,
4922 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
4925 return IDirect3DDeviceImpl_7_GetTextureStageState(iface
, Stage
, TexStageStateType
, State
);
4928 static HRESULT WINAPI
4929 IDirect3DDeviceImpl_7_GetTextureStageState_FPUPreserve(IDirect3DDevice7
*iface
,
4931 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
4937 old_fpucw
= d3d_fpu_setup();
4938 hr
= IDirect3DDeviceImpl_7_GetTextureStageState(iface
, Stage
, TexStageStateType
, State
);
4939 set_fpu_control_word(old_fpucw
);
4944 static HRESULT WINAPI
4945 Thunk_IDirect3DDeviceImpl_3_GetTextureStageState(IDirect3DDevice3
*iface
,
4947 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
4950 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
4951 TRACE_(ddraw_thunk
)("(%p)->(%08x,%08x,%p) thunking to IDirect3DDevice7 interface.\n", This
, Stage
, TexStageStateType
, State
);
4952 return IDirect3DDevice7_GetTextureStageState((IDirect3DDevice7
*)This
, Stage
, TexStageStateType
, State
);
4955 /*****************************************************************************
4956 * IDirect3DDevice7::SetTextureStageState
4958 * Sets a texture stage state. Some stage types need to be handled specially,
4959 * because they do not exist in WineD3D and were moved to another place
4964 * Stage: The stage to modify
4965 * TexStageStateType: The state to change
4966 * State: The new value for the state
4970 * For details, see IWineD3DDevice::SetTextureStageState
4972 *****************************************************************************/
4974 IDirect3DDeviceImpl_7_SetTextureStageState(IDirect3DDevice7
*iface
,
4976 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
4979 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
4980 const struct tss_lookup
*l
= &tss_lookup
[TexStageStateType
];
4982 TRACE("(%p)->(%08x,%08x,%08x): Relay!\n", This
, Stage
, TexStageStateType
, State
);
4984 if (TexStageStateType
> D3DTSS_TEXTURETRANSFORMFLAGS
)
4986 WARN("Invalid TexStageStateType %#x passed.\n", TexStageStateType
);
4990 EnterCriticalSection(&ddraw_cs
);
4992 if (l
->sampler_state
)
4994 switch(TexStageStateType
)
4996 /* Mipfilter is a sampler state with different values */
4997 case D3DTSS_MIPFILTER
:
5001 case D3DTFP_NONE
: State
= WINED3DTEXF_NONE
; break;
5002 case D3DTFP_POINT
: State
= WINED3DTEXF_POINT
; break;
5003 case 0: /* Unchecked */
5004 case D3DTFP_LINEAR
: State
= WINED3DTEXF_LINEAR
; break;
5006 ERR("Unexpected mipfilter value %d\n", State
);
5007 State
= WINED3DTEXF_NONE
;
5013 /* Magfilter has slightly different values */
5014 case D3DTSS_MAGFILTER
:
5018 case D3DTFG_POINT
: State
= WINED3DTEXF_POINT
; break;
5019 case D3DTFG_LINEAR
: State
= WINED3DTEXF_LINEAR
; break;
5020 case D3DTFG_FLATCUBIC
: State
= WINED3DTEXF_FLATCUBIC
; break;
5021 case D3DTFG_GAUSSIANCUBIC
: State
= WINED3DTEXF_GAUSSIANCUBIC
; break;
5022 case D3DTFG_ANISOTROPIC
: State
= WINED3DTEXF_ANISOTROPIC
; break;
5024 ERR("Unexpected d3d7 mag filter type %d\n", State
);
5025 State
= WINED3DTEXF_POINT
;
5031 case D3DTSS_ADDRESS
:
5032 IWineD3DDevice_SetSamplerState(This
->wineD3DDevice
, Stage
, WINED3DSAMP_ADDRESSV
, State
);
5039 hr
= IWineD3DDevice_SetSamplerState(This
->wineD3DDevice
, Stage
, l
->state
, State
);
5043 hr
= IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, Stage
, l
->state
, State
);
5046 LeaveCriticalSection(&ddraw_cs
);
5050 static HRESULT WINAPI
5051 IDirect3DDeviceImpl_7_SetTextureStageState_FPUSetup(IDirect3DDevice7
*iface
,
5053 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
5056 return IDirect3DDeviceImpl_7_SetTextureStageState(iface
, Stage
, TexStageStateType
, State
);
5059 static HRESULT WINAPI
5060 IDirect3DDeviceImpl_7_SetTextureStageState_FPUPreserve(IDirect3DDevice7
*iface
,
5062 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
5068 old_fpucw
= d3d_fpu_setup();
5069 hr
= IDirect3DDeviceImpl_7_SetTextureStageState(iface
, Stage
, TexStageStateType
, State
);
5070 set_fpu_control_word(old_fpucw
);
5075 static HRESULT WINAPI
5076 Thunk_IDirect3DDeviceImpl_3_SetTextureStageState(IDirect3DDevice3
*iface
,
5078 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
5081 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
5082 TRACE_(ddraw_thunk
)("(%p)->(%08x,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This
, Stage
, TexStageStateType
, State
);
5083 return IDirect3DDevice7_SetTextureStageState((IDirect3DDevice7
*)This
, Stage
, TexStageStateType
, State
);
5086 /*****************************************************************************
5087 * IDirect3DDevice7::ValidateDevice
5089 * SDK: "Reports the device's ability to render the currently set
5090 * texture-blending operations in a single pass". Whatever that means
5096 * NumPasses: Address to write the number of necessary passes for the
5097 * desired effect to.
5101 * See IWineD3DDevice::ValidateDevice for more details
5103 *****************************************************************************/
5105 IDirect3DDeviceImpl_7_ValidateDevice(IDirect3DDevice7
*iface
,
5108 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5110 TRACE("(%p)->(%p): Relay\n", This
, NumPasses
);
5112 EnterCriticalSection(&ddraw_cs
);
5113 hr
= IWineD3DDevice_ValidateDevice(This
->wineD3DDevice
, NumPasses
);
5114 LeaveCriticalSection(&ddraw_cs
);
5118 static HRESULT WINAPI
5119 IDirect3DDeviceImpl_7_ValidateDevice_FPUSetup(IDirect3DDevice7
*iface
,
5122 return IDirect3DDeviceImpl_7_ValidateDevice(iface
, NumPasses
);
5125 static HRESULT WINAPI
5126 IDirect3DDeviceImpl_7_ValidateDevice_FPUPreserve(IDirect3DDevice7
*iface
,
5132 old_fpucw
= d3d_fpu_setup();
5133 hr
= IDirect3DDeviceImpl_7_ValidateDevice(iface
, NumPasses
);
5134 set_fpu_control_word(old_fpucw
);
5139 static HRESULT WINAPI
5140 Thunk_IDirect3DDeviceImpl_3_ValidateDevice(IDirect3DDevice3
*iface
,
5143 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
5144 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This
, Passes
);
5145 return IDirect3DDevice7_ValidateDevice((IDirect3DDevice7
*)This
, Passes
);
5148 /*****************************************************************************
5149 * IDirect3DDevice7::Clear
5151 * Fills the render target, the z buffer and the stencil buffer with a
5152 * clear color / value
5157 * Count: Number of rectangles in Rects must be 0 if Rects is NULL
5158 * Rects: Rectangles to clear. If NULL, the whole surface is cleared
5159 * Flags: Some flags, as usual
5160 * Color: Clear color for the render target
5161 * Z: Clear value for the Z buffer
5162 * Stencil: Clear value to store in each stencil buffer entry
5166 * For details, see IWineD3DDevice::Clear
5168 *****************************************************************************/
5170 IDirect3DDeviceImpl_7_Clear(IDirect3DDevice7
*iface
,
5178 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5180 TRACE("(%p)->(%08x,%p,%08x,%08x,%f,%08x): Relay\n", This
, Count
, Rects
, Flags
, Color
, Z
, Stencil
);
5182 /* Note; D3DRECT is compatible with WINED3DRECT */
5183 EnterCriticalSection(&ddraw_cs
);
5184 hr
= IWineD3DDevice_Clear(This
->wineD3DDevice
, Count
, (WINED3DRECT
*) Rects
, Flags
, Color
, Z
, Stencil
);
5185 LeaveCriticalSection(&ddraw_cs
);
5189 static HRESULT WINAPI
5190 IDirect3DDeviceImpl_7_Clear_FPUSetup(IDirect3DDevice7
*iface
,
5198 return IDirect3DDeviceImpl_7_Clear(iface
, Count
, Rects
, Flags
, Color
, Z
, Stencil
);
5201 static HRESULT WINAPI
5202 IDirect3DDeviceImpl_7_Clear_FPUPreserve(IDirect3DDevice7
*iface
,
5213 old_fpucw
= d3d_fpu_setup();
5214 hr
= IDirect3DDeviceImpl_7_Clear(iface
, Count
, Rects
, Flags
, Color
, Z
, Stencil
);
5215 set_fpu_control_word(old_fpucw
);
5220 /*****************************************************************************
5221 * IDirect3DDevice7::SetViewport
5223 * Sets the current viewport.
5225 * Version 7 only, but IDirect3DViewport uses this call for older
5229 * Data: The new viewport to set
5233 * DDERR_INVALIDPARAMS if Data is NULL
5234 * For more details, see IWineDDDevice::SetViewport
5236 *****************************************************************************/
5238 IDirect3DDeviceImpl_7_SetViewport(IDirect3DDevice7
*iface
,
5241 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5243 TRACE("(%p)->(%p) Relay!\n", This
, Data
);
5246 return DDERR_INVALIDPARAMS
;
5248 /* Note: D3DVIEWPORT7 is compatible with WINED3DVIEWPORT */
5249 EnterCriticalSection(&ddraw_cs
);
5250 hr
= IWineD3DDevice_SetViewport(This
->wineD3DDevice
,
5251 (WINED3DVIEWPORT
*) Data
);
5252 LeaveCriticalSection(&ddraw_cs
);
5256 static HRESULT WINAPI
5257 IDirect3DDeviceImpl_7_SetViewport_FPUSetup(IDirect3DDevice7
*iface
,
5260 return IDirect3DDeviceImpl_7_SetViewport(iface
, Data
);
5263 static HRESULT WINAPI
5264 IDirect3DDeviceImpl_7_SetViewport_FPUPreserve(IDirect3DDevice7
*iface
,
5270 old_fpucw
= d3d_fpu_setup();
5271 hr
= IDirect3DDeviceImpl_7_SetViewport(iface
, Data
);
5272 set_fpu_control_word(old_fpucw
);
5277 /*****************************************************************************
5278 * IDirect3DDevice::GetViewport
5280 * Returns the current viewport
5285 * Data: D3D7Viewport structure to write the viewport information to
5289 * DDERR_INVALIDPARAMS if Data is NULL
5290 * For more details, see IWineD3DDevice::GetViewport
5292 *****************************************************************************/
5294 IDirect3DDeviceImpl_7_GetViewport(IDirect3DDevice7
*iface
,
5297 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5299 TRACE("(%p)->(%p) Relay!\n", This
, Data
);
5302 return DDERR_INVALIDPARAMS
;
5304 /* Note: D3DVIEWPORT7 is compatible with WINED3DVIEWPORT */
5305 EnterCriticalSection(&ddraw_cs
);
5306 hr
= IWineD3DDevice_GetViewport(This
->wineD3DDevice
,
5307 (WINED3DVIEWPORT
*) Data
);
5309 LeaveCriticalSection(&ddraw_cs
);
5310 return hr_ddraw_from_wined3d(hr
);
5313 static HRESULT WINAPI
5314 IDirect3DDeviceImpl_7_GetViewport_FPUSetup(IDirect3DDevice7
*iface
,
5317 return IDirect3DDeviceImpl_7_GetViewport(iface
, Data
);
5320 static HRESULT WINAPI
5321 IDirect3DDeviceImpl_7_GetViewport_FPUPreserve(IDirect3DDevice7
*iface
,
5327 old_fpucw
= d3d_fpu_setup();
5328 hr
= IDirect3DDeviceImpl_7_GetViewport(iface
, Data
);
5329 set_fpu_control_word(old_fpucw
);
5334 /*****************************************************************************
5335 * IDirect3DDevice7::SetMaterial
5342 * Mat: The material to set
5346 * DDERR_INVALIDPARAMS if Mat is NULL.
5347 * For more details, see IWineD3DDevice::SetMaterial
5349 *****************************************************************************/
5351 IDirect3DDeviceImpl_7_SetMaterial(IDirect3DDevice7
*iface
,
5354 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5356 TRACE("(%p)->(%p): Relay!\n", This
, Mat
);
5358 if (!Mat
) return DDERR_INVALIDPARAMS
;
5359 /* Note: D3DMATERIAL7 is compatible with WINED3DMATERIAL */
5360 EnterCriticalSection(&ddraw_cs
);
5361 hr
= IWineD3DDevice_SetMaterial(This
->wineD3DDevice
,
5362 (WINED3DMATERIAL
*) Mat
);
5363 LeaveCriticalSection(&ddraw_cs
);
5364 return hr_ddraw_from_wined3d(hr
);
5367 static HRESULT WINAPI
5368 IDirect3DDeviceImpl_7_SetMaterial_FPUSetup(IDirect3DDevice7
*iface
,
5371 return IDirect3DDeviceImpl_7_SetMaterial(iface
, Mat
);
5374 static HRESULT WINAPI
5375 IDirect3DDeviceImpl_7_SetMaterial_FPUPreserve(IDirect3DDevice7
*iface
,
5381 old_fpucw
= d3d_fpu_setup();
5382 hr
= IDirect3DDeviceImpl_7_SetMaterial(iface
, Mat
);
5383 set_fpu_control_word(old_fpucw
);
5388 /*****************************************************************************
5389 * IDirect3DDevice7::GetMaterial
5391 * Returns the current material
5396 * Mat: D3DMATERIAL7 structure to write the material parameters to
5400 * DDERR_INVALIDPARAMS if Mat is NULL
5401 * For more details, see IWineD3DDevice::GetMaterial
5403 *****************************************************************************/
5405 IDirect3DDeviceImpl_7_GetMaterial(IDirect3DDevice7
*iface
,
5408 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5410 TRACE("(%p)->(%p): Relay!\n", This
, Mat
);
5412 EnterCriticalSection(&ddraw_cs
);
5413 /* Note: D3DMATERIAL7 is compatible with WINED3DMATERIAL */
5414 hr
= IWineD3DDevice_GetMaterial(This
->wineD3DDevice
,
5415 (WINED3DMATERIAL
*) Mat
);
5416 LeaveCriticalSection(&ddraw_cs
);
5417 return hr_ddraw_from_wined3d(hr
);
5420 static HRESULT WINAPI
5421 IDirect3DDeviceImpl_7_GetMaterial_FPUSetup(IDirect3DDevice7
*iface
,
5424 return IDirect3DDeviceImpl_7_GetMaterial(iface
, Mat
);
5427 static HRESULT WINAPI
5428 IDirect3DDeviceImpl_7_GetMaterial_FPUPreserve(IDirect3DDevice7
*iface
,
5434 old_fpucw
= d3d_fpu_setup();
5435 hr
= IDirect3DDeviceImpl_7_GetMaterial(iface
, Mat
);
5436 set_fpu_control_word(old_fpucw
);
5441 /*****************************************************************************
5442 * IDirect3DDevice7::SetLight
5444 * Assigns a light to a light index, but doesn't activate it yet.
5446 * Version 7, IDirect3DLight uses this method for older versions
5449 * LightIndex: The index of the new light
5450 * Light: A D3DLIGHT7 structure describing the light
5454 * For more details, see IWineD3DDevice::SetLight
5456 *****************************************************************************/
5458 IDirect3DDeviceImpl_7_SetLight(IDirect3DDevice7
*iface
,
5462 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5464 TRACE("(%p)->(%08x,%p): Relay!\n", This
, LightIndex
, Light
);
5466 EnterCriticalSection(&ddraw_cs
);
5467 /* Note: D3DLIGHT7 is compatible with WINED3DLIGHT */
5468 hr
= IWineD3DDevice_SetLight(This
->wineD3DDevice
,
5470 (WINED3DLIGHT
*) Light
);
5471 LeaveCriticalSection(&ddraw_cs
);
5472 return hr_ddraw_from_wined3d(hr
);
5475 static HRESULT WINAPI
5476 IDirect3DDeviceImpl_7_SetLight_FPUSetup(IDirect3DDevice7
*iface
,
5480 return IDirect3DDeviceImpl_7_SetLight(iface
, LightIndex
, Light
);
5483 static HRESULT WINAPI
5484 IDirect3DDeviceImpl_7_SetLight_FPUPreserve(IDirect3DDevice7
*iface
,
5491 old_fpucw
= d3d_fpu_setup();
5492 hr
= IDirect3DDeviceImpl_7_SetLight(iface
, LightIndex
, Light
);
5493 set_fpu_control_word(old_fpucw
);
5498 /*****************************************************************************
5499 * IDirect3DDevice7::GetLight
5501 * Returns the light assigned to a light index
5504 * Light: Structure to write the light information to
5508 * DDERR_INVALIDPARAMS if Light is NULL
5509 * For details, see IWineD3DDevice::GetLight
5511 *****************************************************************************/
5513 IDirect3DDeviceImpl_7_GetLight(IDirect3DDevice7
*iface
,
5517 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5519 TRACE("(%p)->(%08x,%p): Relay!\n", This
, LightIndex
, Light
);
5521 EnterCriticalSection(&ddraw_cs
);
5522 /* Note: D3DLIGHT7 is compatible with WINED3DLIGHT */
5523 rc
= IWineD3DDevice_GetLight(This
->wineD3DDevice
,
5525 (WINED3DLIGHT
*) Light
);
5527 /* Translate the result. WineD3D returns other values than D3D7 */
5528 LeaveCriticalSection(&ddraw_cs
);
5529 return hr_ddraw_from_wined3d(rc
);
5532 static HRESULT WINAPI
5533 IDirect3DDeviceImpl_7_GetLight_FPUSetup(IDirect3DDevice7
*iface
,
5537 return IDirect3DDeviceImpl_7_GetLight(iface
, LightIndex
, Light
);
5540 static HRESULT WINAPI
5541 IDirect3DDeviceImpl_7_GetLight_FPUPreserve(IDirect3DDevice7
*iface
,
5548 old_fpucw
= d3d_fpu_setup();
5549 hr
= IDirect3DDeviceImpl_7_GetLight(iface
, LightIndex
, Light
);
5550 set_fpu_control_word(old_fpucw
);
5555 /*****************************************************************************
5556 * IDirect3DDevice7::BeginStateBlock
5558 * Begins recording to a stateblock
5564 * For details see IWineD3DDevice::BeginStateBlock
5566 *****************************************************************************/
5568 IDirect3DDeviceImpl_7_BeginStateBlock(IDirect3DDevice7
*iface
)
5570 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5572 TRACE("(%p)->(): Relay!\n", This
);
5574 EnterCriticalSection(&ddraw_cs
);
5575 hr
= IWineD3DDevice_BeginStateBlock(This
->wineD3DDevice
);
5576 LeaveCriticalSection(&ddraw_cs
);
5577 return hr_ddraw_from_wined3d(hr
);
5580 static HRESULT WINAPI
5581 IDirect3DDeviceImpl_7_BeginStateBlock_FPUSetup(IDirect3DDevice7
*iface
)
5583 return IDirect3DDeviceImpl_7_BeginStateBlock(iface
);
5586 static HRESULT WINAPI
5587 IDirect3DDeviceImpl_7_BeginStateBlock_FPUPreserve(IDirect3DDevice7
*iface
)
5592 old_fpucw
= d3d_fpu_setup();
5593 hr
= IDirect3DDeviceImpl_7_BeginStateBlock(iface
);
5594 set_fpu_control_word(old_fpucw
);
5599 /*****************************************************************************
5600 * IDirect3DDevice7::EndStateBlock
5602 * Stops recording to a state block and returns the created stateblock
5608 * BlockHandle: Address to store the stateblock's handle to
5612 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5613 * See IWineD3DDevice::EndStateBlock for more details
5615 *****************************************************************************/
5617 IDirect3DDeviceImpl_7_EndStateBlock(IDirect3DDevice7
*iface
,
5620 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5622 TRACE("(%p)->(%p): Relay!\n", This
, BlockHandle
);
5626 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
5627 return DDERR_INVALIDPARAMS
;
5630 EnterCriticalSection(&ddraw_cs
);
5631 *BlockHandle
= IDirect3DDeviceImpl_CreateHandle(This
);
5634 ERR("Cannot get a handle number for the stateblock\n");
5635 LeaveCriticalSection(&ddraw_cs
);
5636 return DDERR_OUTOFMEMORY
;
5638 This
->Handles
[*BlockHandle
- 1].type
= DDrawHandle_StateBlock
;
5639 hr
= IWineD3DDevice_EndStateBlock(This
->wineD3DDevice
,
5640 (IWineD3DStateBlock
**) &This
->Handles
[*BlockHandle
- 1].ptr
);
5641 LeaveCriticalSection(&ddraw_cs
);
5642 return hr_ddraw_from_wined3d(hr
);
5645 static HRESULT WINAPI
5646 IDirect3DDeviceImpl_7_EndStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5649 return IDirect3DDeviceImpl_7_EndStateBlock(iface
, BlockHandle
);
5652 static HRESULT WINAPI
5653 IDirect3DDeviceImpl_7_EndStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5659 old_fpucw
= d3d_fpu_setup();
5660 hr
= IDirect3DDeviceImpl_7_EndStateBlock(iface
, BlockHandle
);
5661 set_fpu_control_word(old_fpucw
);
5666 /*****************************************************************************
5667 * IDirect3DDevice7::PreLoad
5669 * Allows the app to signal that a texture will be used soon, to allow
5670 * the Direct3DDevice to load it to the video card in the meantime.
5675 * Texture: The texture to preload
5679 * DDERR_INVALIDPARAMS if Texture is NULL
5680 * See IWineD3DSurface::PreLoad for details
5682 *****************************************************************************/
5684 IDirect3DDeviceImpl_7_PreLoad(IDirect3DDevice7
*iface
,
5685 IDirectDrawSurface7
*Texture
)
5687 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5688 IDirectDrawSurfaceImpl
*surf
= (IDirectDrawSurfaceImpl
*)Texture
;
5690 TRACE("(%p)->(%p): Relay!\n", This
, surf
);
5693 return DDERR_INVALIDPARAMS
;
5695 EnterCriticalSection(&ddraw_cs
);
5696 IWineD3DSurface_PreLoad(surf
->WineD3DSurface
);
5697 LeaveCriticalSection(&ddraw_cs
);
5701 static HRESULT WINAPI
5702 IDirect3DDeviceImpl_7_PreLoad_FPUSetup(IDirect3DDevice7
*iface
,
5703 IDirectDrawSurface7
*Texture
)
5705 return IDirect3DDeviceImpl_7_PreLoad(iface
, Texture
);
5708 static HRESULT WINAPI
5709 IDirect3DDeviceImpl_7_PreLoad_FPUPreserve(IDirect3DDevice7
*iface
,
5710 IDirectDrawSurface7
*Texture
)
5715 old_fpucw
= d3d_fpu_setup();
5716 hr
= IDirect3DDeviceImpl_7_PreLoad(iface
, Texture
);
5717 set_fpu_control_word(old_fpucw
);
5722 /*****************************************************************************
5723 * IDirect3DDevice7::ApplyStateBlock
5725 * Activates the state stored in a state block handle.
5728 * BlockHandle: The stateblock handle to activate
5732 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5734 *****************************************************************************/
5736 IDirect3DDeviceImpl_7_ApplyStateBlock(IDirect3DDevice7
*iface
,
5739 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5741 TRACE("(%p)->(%08x): Relay!\n", This
, BlockHandle
);
5743 EnterCriticalSection(&ddraw_cs
);
5744 if(!BlockHandle
|| BlockHandle
> This
->numHandles
)
5746 WARN("Out of range handle %d, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle
);
5747 LeaveCriticalSection(&ddraw_cs
);
5748 return D3DERR_INVALIDSTATEBLOCK
;
5750 if(This
->Handles
[BlockHandle
- 1].type
!= DDrawHandle_StateBlock
)
5752 WARN("Handle %d is not a stateblock, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle
);
5753 LeaveCriticalSection(&ddraw_cs
);
5754 return D3DERR_INVALIDSTATEBLOCK
;
5757 hr
= IWineD3DStateBlock_Apply((IWineD3DStateBlock
*) This
->Handles
[BlockHandle
- 1].ptr
);
5758 LeaveCriticalSection(&ddraw_cs
);
5759 return hr_ddraw_from_wined3d(hr
);
5762 static HRESULT WINAPI
5763 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5766 return IDirect3DDeviceImpl_7_ApplyStateBlock(iface
, BlockHandle
);
5769 static HRESULT WINAPI
5770 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5776 old_fpucw
= d3d_fpu_setup();
5777 hr
= IDirect3DDeviceImpl_7_ApplyStateBlock(iface
, BlockHandle
);
5778 set_fpu_control_word(old_fpucw
);
5783 /*****************************************************************************
5784 * IDirect3DDevice7::CaptureStateBlock
5786 * Updates a stateblock's values to the values currently set for the device
5791 * BlockHandle: Stateblock to update
5795 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5796 * See IWineD3DDevice::CaptureStateBlock for more details
5798 *****************************************************************************/
5800 IDirect3DDeviceImpl_7_CaptureStateBlock(IDirect3DDevice7
*iface
,
5803 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5805 TRACE("(%p)->(%08x): Relay!\n", This
, BlockHandle
);
5807 EnterCriticalSection(&ddraw_cs
);
5808 if(BlockHandle
== 0 || BlockHandle
> This
->numHandles
)
5810 WARN("Out of range handle %d, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle
);
5811 LeaveCriticalSection(&ddraw_cs
);
5812 return D3DERR_INVALIDSTATEBLOCK
;
5814 if(This
->Handles
[BlockHandle
- 1].type
!= DDrawHandle_StateBlock
)
5816 WARN("Handle %d is not a stateblock, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle
);
5817 LeaveCriticalSection(&ddraw_cs
);
5818 return D3DERR_INVALIDSTATEBLOCK
;
5821 hr
= IWineD3DStateBlock_Capture((IWineD3DStateBlock
*) This
->Handles
[BlockHandle
- 1].ptr
);
5822 LeaveCriticalSection(&ddraw_cs
);
5823 return hr_ddraw_from_wined3d(hr
);
5826 static HRESULT WINAPI
5827 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5830 return IDirect3DDeviceImpl_7_CaptureStateBlock(iface
, BlockHandle
);
5833 static HRESULT WINAPI
5834 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5840 old_fpucw
= d3d_fpu_setup();
5841 hr
= IDirect3DDeviceImpl_7_CaptureStateBlock(iface
, BlockHandle
);
5842 set_fpu_control_word(old_fpucw
);
5847 /*****************************************************************************
5848 * IDirect3DDevice7::DeleteStateBlock
5850 * Deletes a stateblock handle. This means releasing the WineD3DStateBlock
5855 * BlockHandle: Stateblock handle to delete
5859 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is 0
5861 *****************************************************************************/
5863 IDirect3DDeviceImpl_7_DeleteStateBlock(IDirect3DDevice7
*iface
,
5866 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5868 TRACE("(%p)->(%08x): Relay!\n", This
, BlockHandle
);
5870 EnterCriticalSection(&ddraw_cs
);
5871 if(BlockHandle
== 0 || BlockHandle
> This
->numHandles
)
5873 WARN("Out of range handle %d, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle
);
5874 LeaveCriticalSection(&ddraw_cs
);
5875 return D3DERR_INVALIDSTATEBLOCK
;
5877 if(This
->Handles
[BlockHandle
- 1].type
!= DDrawHandle_StateBlock
)
5879 WARN("Handle %d is not a stateblock, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle
);
5880 LeaveCriticalSection(&ddraw_cs
);
5881 return D3DERR_INVALIDSTATEBLOCK
;
5884 ref
= IWineD3DStateBlock_Release((IWineD3DStateBlock
*) This
->Handles
[BlockHandle
- 1].ptr
);
5887 ERR("Something is still holding the stateblock %p(Handle %d). Ref = %d\n", This
->Handles
[BlockHandle
- 1].ptr
, BlockHandle
, ref
);
5889 This
->Handles
[BlockHandle
- 1].ptr
= NULL
;
5890 This
->Handles
[BlockHandle
- 1].type
= DDrawHandle_Unknown
;
5892 LeaveCriticalSection(&ddraw_cs
);
5896 static HRESULT WINAPI
5897 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5900 return IDirect3DDeviceImpl_7_DeleteStateBlock(iface
, BlockHandle
);
5903 static HRESULT WINAPI
5904 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5910 old_fpucw
= d3d_fpu_setup();
5911 hr
= IDirect3DDeviceImpl_7_DeleteStateBlock(iface
, BlockHandle
);
5912 set_fpu_control_word(old_fpucw
);
5917 /*****************************************************************************
5918 * IDirect3DDevice7::CreateStateBlock
5920 * Creates a new state block handle.
5925 * Type: The state block type
5926 * BlockHandle: Address to write the created handle to
5930 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5932 *****************************************************************************/
5934 IDirect3DDeviceImpl_7_CreateStateBlock(IDirect3DDevice7
*iface
,
5935 D3DSTATEBLOCKTYPE Type
,
5938 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5940 TRACE("(%p)->(%08x,%p)!\n", This
, Type
, BlockHandle
);
5944 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
5945 return DDERR_INVALIDPARAMS
;
5947 if(Type
!= D3DSBT_ALL
&& Type
!= D3DSBT_PIXELSTATE
&&
5948 Type
!= D3DSBT_VERTEXSTATE
) {
5949 WARN("Unexpected stateblock type, returning DDERR_INVALIDPARAMS\n");
5950 return DDERR_INVALIDPARAMS
;
5953 EnterCriticalSection(&ddraw_cs
);
5954 *BlockHandle
= IDirect3DDeviceImpl_CreateHandle(This
);
5957 ERR("Cannot get a handle number for the stateblock\n");
5958 LeaveCriticalSection(&ddraw_cs
);
5959 return DDERR_OUTOFMEMORY
;
5961 This
->Handles
[*BlockHandle
- 1].type
= DDrawHandle_StateBlock
;
5963 /* The D3DSTATEBLOCKTYPE enum is fine here */
5964 hr
= IWineD3DDevice_CreateStateBlock(This
->wineD3DDevice
,
5966 (IWineD3DStateBlock
**) &This
->Handles
[*BlockHandle
- 1].ptr
,
5967 NULL
/* Parent, hope that works */);
5968 LeaveCriticalSection(&ddraw_cs
);
5969 return hr_ddraw_from_wined3d(hr
);
5972 static HRESULT WINAPI
5973 IDirect3DDeviceImpl_7_CreateStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5974 D3DSTATEBLOCKTYPE Type
,
5977 return IDirect3DDeviceImpl_7_CreateStateBlock(iface
, Type
, BlockHandle
);
5980 static HRESULT WINAPI
5981 IDirect3DDeviceImpl_7_CreateStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5982 D3DSTATEBLOCKTYPE Type
,
5988 old_fpucw
= d3d_fpu_setup();
5989 hr
=IDirect3DDeviceImpl_7_CreateStateBlock(iface
, Type
, BlockHandle
);
5990 set_fpu_control_word(old_fpucw
);
5995 /* Helper function for IDirect3DDeviceImpl_7_Load. */
5996 static BOOL
is_mip_level_subset(IDirectDrawSurfaceImpl
*dest
,
5997 IDirectDrawSurfaceImpl
*src
)
5999 IDirectDrawSurfaceImpl
*src_level
, *dest_level
;
6000 IDirectDrawSurface7
*temp
;
6001 DDSURFACEDESC2 ddsd
;
6002 BOOL levelFound
; /* at least one suitable sublevel in dest found */
6004 /* To satisfy "destination is mip level subset of source" criteria (regular texture counts as 1 level),
6005 * 1) there must be at least one mip level in destination that matched dimensions of some mip level in source and
6006 * 2) there must be no destination levels that don't match any levels in source. Otherwise it's INVALIDPARAMS.
6013 for (;src_level
&& dest_level
;)
6015 if (src_level
->surface_desc
.dwWidth
== dest_level
->surface_desc
.dwWidth
&&
6016 src_level
->surface_desc
.dwHeight
== dest_level
->surface_desc
.dwHeight
)
6020 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6021 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
6022 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7
*)dest_level
, &ddsd
.ddsCaps
, &temp
);
6024 if (dest_level
!= dest
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)dest_level
);
6026 dest_level
= (IDirectDrawSurfaceImpl
*)temp
;
6029 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6030 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
6031 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7
*)src_level
, &ddsd
.ddsCaps
, &temp
);
6033 if (src_level
!= src
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)src_level
);
6035 src_level
= (IDirectDrawSurfaceImpl
*)temp
;
6038 if (src_level
&& src_level
!= src
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)src_level
);
6039 if (dest_level
&& dest_level
!= dest
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)dest_level
);
6041 return !dest_level
&& levelFound
;
6044 /* Helper function for IDirect3DDeviceImpl_7_Load. */
6045 static void copy_mipmap_chain(IDirect3DDeviceImpl
*device
,
6046 IDirectDrawSurfaceImpl
*dest
,
6047 IDirectDrawSurfaceImpl
*src
,
6048 const POINT
*DestPoint
,
6049 const RECT
*SrcRect
)
6051 IDirectDrawSurfaceImpl
*src_level
, *dest_level
;
6052 IDirectDrawSurface7
*temp
;
6053 DDSURFACEDESC2 ddsd
;
6057 IDirectDrawPalette
*pal
= NULL
, *pal_src
= NULL
;
6060 BOOL palette_missing
= FALSE
;
6062 /* Copy palette, if possible. */
6063 IDirectDrawSurface7_GetPalette((IDirectDrawSurface7
*)src
, &pal_src
);
6064 IDirectDrawSurface7_GetPalette((IDirectDrawSurface7
*)dest
, &pal
);
6066 if (pal_src
!= NULL
&& pal
!= NULL
)
6068 PALETTEENTRY palent
[256];
6070 IDirectDrawPalette_GetEntries(pal_src
, 0, 0, 256, palent
);
6071 IDirectDrawPalette_SetEntries(pal
, 0, 0, 256, palent
);
6074 if (dest
->surface_desc
.u4
.ddpfPixelFormat
.dwFlags
& (DDPF_PALETTEINDEXED1
| DDPF_PALETTEINDEXED2
|
6075 DDPF_PALETTEINDEXED4
| DDPF_PALETTEINDEXED8
| DDPF_PALETTEINDEXEDTO8
) && !pal
)
6077 palette_missing
= TRUE
;
6080 if (pal
) IDirectDrawPalette_Release(pal
);
6081 if (pal_src
) IDirectDrawPalette_Release(pal_src
);
6083 /* Copy colorkeys, if present. */
6084 for (ckeyflag
= DDCKEY_DESTBLT
; ckeyflag
<= DDCKEY_SRCOVERLAY
; ckeyflag
<<= 1)
6086 hr
= IDirectDrawSurface7_GetColorKey((IDirectDrawSurface7
*)src
, ckeyflag
, &ddckey
);
6090 IDirectDrawSurface7_SetColorKey((IDirectDrawSurface7
*)dest
, ckeyflag
, &ddckey
);
6100 for (;src_level
&& dest_level
;)
6102 if (src_level
->surface_desc
.dwWidth
== dest_level
->surface_desc
.dwWidth
&&
6103 src_level
->surface_desc
.dwHeight
== dest_level
->surface_desc
.dwHeight
)
6105 /* Try UpdateSurface that may perform a more direct opengl loading. But skip this if destination is paletted texture and has no palette.
6106 * Some games like Sacrifice set palette after Load, and it is a waste of effort to try to load texture without palette and generates
6107 * warnings in wined3d. */
6108 if (!palette_missing
)
6109 hr
= IWineD3DDevice_UpdateSurface(device
->wineD3DDevice
, src_level
->WineD3DSurface
, &rect
, dest_level
->WineD3DSurface
,
6112 if (palette_missing
|| FAILED(hr
))
6114 /* UpdateSurface may fail e.g. if dest is in system memory. Fall back to BltFast that is less strict. */
6115 IWineD3DSurface_BltFast(dest_level
->WineD3DSurface
,
6117 src_level
->WineD3DSurface
, &rect
, 0);
6120 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6121 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
6122 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7
*)dest_level
, &ddsd
.ddsCaps
, &temp
);
6124 if (dest_level
!= dest
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)dest_level
);
6126 dest_level
= (IDirectDrawSurfaceImpl
*)temp
;
6129 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6130 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
6131 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7
*)src_level
, &ddsd
.ddsCaps
, &temp
);
6133 if (src_level
!= src
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)src_level
);
6135 src_level
= (IDirectDrawSurfaceImpl
*)temp
;
6142 rect
.right
= (rect
.right
+ 1) / 2;
6143 rect
.bottom
= (rect
.bottom
+ 1) / 2;
6146 if (src_level
&& src_level
!= src
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)src_level
);
6147 if (dest_level
&& dest_level
!= dest
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)dest_level
);
6150 /*****************************************************************************
6151 * IDirect3DDevice7::Load
6153 * Loads a rectangular area from the source into the destination texture.
6154 * It can also copy the source to the faces of a cubic environment map
6159 * DestTex: Destination texture
6160 * DestPoint: Point in the destination where the source image should be
6162 * SrcTex: Source texture
6163 * SrcRect: Source rectangle
6164 * Flags: Cubemap faces to load (DDSCAPS2_CUBEMAP_ALLFACES, DDSCAPS2_CUBEMAP_POSITIVEX,
6165 * DDSCAPS2_CUBEMAP_NEGATIVEX, DDSCAPS2_CUBEMAP_POSITIVEY, DDSCAPS2_CUBEMAP_NEGATIVEY,
6166 * DDSCAPS2_CUBEMAP_POSITIVEZ, DDSCAPS2_CUBEMAP_NEGATIVEZ)
6170 * DDERR_INVALIDPARAMS if DestTex or SrcTex are NULL, broken coordinates or anything unexpected.
6173 *****************************************************************************/
6176 IDirect3DDeviceImpl_7_Load(IDirect3DDevice7
*iface
,
6177 IDirectDrawSurface7
*DestTex
,
6179 IDirectDrawSurface7
*SrcTex
,
6183 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
6184 IDirectDrawSurfaceImpl
*dest
= (IDirectDrawSurfaceImpl
*)DestTex
;
6185 IDirectDrawSurfaceImpl
*src
= (IDirectDrawSurfaceImpl
*)SrcTex
;
6188 TRACE("(%p)->(%p,%p,%p,%p,%08x)\n", This
, dest
, DestPoint
, src
, SrcRect
, Flags
);
6190 if( (!src
) || (!dest
) )
6191 return DDERR_INVALIDPARAMS
;
6193 EnterCriticalSection(&ddraw_cs
);
6195 if (SrcRect
) srcrect
= *SrcRect
;
6198 srcrect
.left
= srcrect
.top
= 0;
6199 srcrect
.right
= src
->surface_desc
.dwWidth
;
6200 srcrect
.bottom
= src
->surface_desc
.dwHeight
;
6203 if (DestPoint
) destpoint
= *DestPoint
;
6206 destpoint
.x
= destpoint
.y
= 0;
6208 /* Check bad dimensions. DestPoint is validated against src, not dest, because
6209 * destination can be a subset of mip levels, in which case actual coordinates used
6210 * for it may be divided. If any dimension of dest is larger than source, it can't be
6211 * mip level subset, so an error can be returned early.
6213 if (srcrect
.left
>= srcrect
.right
|| srcrect
.top
>= srcrect
.bottom
||
6214 srcrect
.right
> src
->surface_desc
.dwWidth
||
6215 srcrect
.bottom
> src
->surface_desc
.dwHeight
||
6216 destpoint
.x
+ srcrect
.right
- srcrect
.left
> src
->surface_desc
.dwWidth
||
6217 destpoint
.y
+ srcrect
.bottom
- srcrect
.top
> src
->surface_desc
.dwHeight
||
6218 dest
->surface_desc
.dwWidth
> src
->surface_desc
.dwWidth
||
6219 dest
->surface_desc
.dwHeight
> src
->surface_desc
.dwHeight
)
6221 LeaveCriticalSection(&ddraw_cs
);
6222 return DDERR_INVALIDPARAMS
;
6225 /* Must be top level surfaces. */
6226 if (src
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_MIPMAPSUBLEVEL
||
6227 dest
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_MIPMAPSUBLEVEL
)
6229 LeaveCriticalSection(&ddraw_cs
);
6230 return DDERR_INVALIDPARAMS
;
6233 if (src
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
)
6235 DWORD src_face_flag
, dest_face_flag
;
6236 IDirectDrawSurfaceImpl
*src_face
, *dest_face
;
6237 IDirectDrawSurface7
*temp
;
6238 DDSURFACEDESC2 ddsd
;
6241 if (!(dest
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
))
6243 LeaveCriticalSection(&ddraw_cs
);
6244 return DDERR_INVALIDPARAMS
;
6247 /* Iterate through cube faces 2 times. First time is just to check INVALIDPARAMS conditions, second
6248 * time it's actual surface loading. */
6249 for (i
= 0; i
< 2; i
++)
6254 for (;dest_face
&& src_face
;)
6256 src_face_flag
= src_face
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP_ALLFACES
;
6257 dest_face_flag
= dest_face
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP_ALLFACES
;
6259 if (src_face_flag
== dest_face_flag
)
6263 /* Destination mip levels must be subset of source mip levels. */
6264 if (!is_mip_level_subset(dest_face
, src_face
))
6266 LeaveCriticalSection(&ddraw_cs
);
6267 return DDERR_INVALIDPARAMS
;
6270 else if (Flags
& dest_face_flag
)
6272 copy_mipmap_chain(This
, dest_face
, src_face
, &destpoint
, &srcrect
);
6275 if (src_face_flag
< DDSCAPS2_CUBEMAP_NEGATIVEZ
)
6277 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6278 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_CUBEMAP
| (src_face_flag
<< 1);
6279 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7
*)src
, &ddsd
.ddsCaps
, &temp
);
6281 if (src_face
!= src
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)src_face
);
6283 src_face
= (IDirectDrawSurfaceImpl
*)temp
;
6287 if (src_face
!= src
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)src_face
);
6293 if (dest_face_flag
< DDSCAPS2_CUBEMAP_NEGATIVEZ
)
6295 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6296 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_CUBEMAP
| (dest_face_flag
<< 1);
6297 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7
*)dest
, &ddsd
.ddsCaps
, &temp
);
6299 if (dest_face
!= dest
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)dest_face
);
6301 dest_face
= (IDirectDrawSurfaceImpl
*)temp
;
6305 if (dest_face
!= dest
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)dest_face
);
6313 /* Native returns error if src faces are not subset of dest faces. */
6316 LeaveCriticalSection(&ddraw_cs
);
6317 return DDERR_INVALIDPARAMS
;
6322 LeaveCriticalSection(&ddraw_cs
);
6325 else if (dest
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
)
6327 LeaveCriticalSection(&ddraw_cs
);
6328 return DDERR_INVALIDPARAMS
;
6331 /* Handle non cube map textures. */
6333 /* Destination mip levels must be subset of source mip levels. */
6334 if (!is_mip_level_subset(dest
, src
))
6336 LeaveCriticalSection(&ddraw_cs
);
6337 return DDERR_INVALIDPARAMS
;
6340 copy_mipmap_chain(This
, dest
, src
, &destpoint
, &srcrect
);
6342 LeaveCriticalSection(&ddraw_cs
);
6346 static HRESULT WINAPI
6347 IDirect3DDeviceImpl_7_Load_FPUSetup(IDirect3DDevice7
*iface
,
6348 IDirectDrawSurface7
*DestTex
,
6350 IDirectDrawSurface7
*SrcTex
,
6354 return IDirect3DDeviceImpl_7_Load(iface
, DestTex
, DestPoint
, SrcTex
, SrcRect
, Flags
);
6357 static HRESULT WINAPI
6358 IDirect3DDeviceImpl_7_Load_FPUPreserve(IDirect3DDevice7
*iface
,
6359 IDirectDrawSurface7
*DestTex
,
6361 IDirectDrawSurface7
*SrcTex
,
6368 old_fpucw
= d3d_fpu_setup();
6369 hr
= IDirect3DDeviceImpl_7_Load(iface
, DestTex
, DestPoint
, SrcTex
, SrcRect
, Flags
);
6370 set_fpu_control_word(old_fpucw
);
6375 /*****************************************************************************
6376 * IDirect3DDevice7::LightEnable
6378 * Enables or disables a light
6380 * Version 7, IDirect3DLight uses this method too.
6383 * LightIndex: The index of the light to enable / disable
6384 * Enable: Enable or disable the light
6388 * For more details, see IWineD3DDevice::SetLightEnable
6390 *****************************************************************************/
6392 IDirect3DDeviceImpl_7_LightEnable(IDirect3DDevice7
*iface
,
6396 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
6398 TRACE("(%p)->(%08x,%d): Relay!\n", This
, LightIndex
, Enable
);
6400 EnterCriticalSection(&ddraw_cs
);
6401 hr
= IWineD3DDevice_SetLightEnable(This
->wineD3DDevice
, LightIndex
, Enable
);
6402 LeaveCriticalSection(&ddraw_cs
);
6403 return hr_ddraw_from_wined3d(hr
);
6406 static HRESULT WINAPI
6407 IDirect3DDeviceImpl_7_LightEnable_FPUSetup(IDirect3DDevice7
*iface
,
6411 return IDirect3DDeviceImpl_7_LightEnable(iface
, LightIndex
, Enable
);
6414 static HRESULT WINAPI
6415 IDirect3DDeviceImpl_7_LightEnable_FPUPreserve(IDirect3DDevice7
*iface
,
6422 old_fpucw
= d3d_fpu_setup();
6423 hr
= IDirect3DDeviceImpl_7_LightEnable(iface
, LightIndex
, Enable
);
6424 set_fpu_control_word(old_fpucw
);
6429 /*****************************************************************************
6430 * IDirect3DDevice7::GetLightEnable
6432 * Retrieves if the light with the given index is enabled or not
6437 * LightIndex: Index of desired light
6438 * Enable: Pointer to a BOOL which contains the result
6442 * DDERR_INVALIDPARAMS if Enable is NULL
6443 * See IWineD3DDevice::GetLightEnable for more details
6445 *****************************************************************************/
6447 IDirect3DDeviceImpl_7_GetLightEnable(IDirect3DDevice7
*iface
,
6451 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
6453 TRACE("(%p)->(%08x,%p): Relay\n", This
, LightIndex
, Enable
);
6456 return DDERR_INVALIDPARAMS
;
6458 EnterCriticalSection(&ddraw_cs
);
6459 hr
= IWineD3DDevice_GetLightEnable(This
->wineD3DDevice
, LightIndex
, Enable
);
6460 LeaveCriticalSection(&ddraw_cs
);
6461 return hr_ddraw_from_wined3d(hr
);
6464 static HRESULT WINAPI
6465 IDirect3DDeviceImpl_7_GetLightEnable_FPUSetup(IDirect3DDevice7
*iface
,
6469 return IDirect3DDeviceImpl_7_GetLightEnable(iface
, LightIndex
, Enable
);
6472 static HRESULT WINAPI
6473 IDirect3DDeviceImpl_7_GetLightEnable_FPUPreserve(IDirect3DDevice7
*iface
,
6480 old_fpucw
= d3d_fpu_setup();
6481 hr
= IDirect3DDeviceImpl_7_GetLightEnable(iface
, LightIndex
, Enable
);
6482 set_fpu_control_word(old_fpucw
);
6487 /*****************************************************************************
6488 * IDirect3DDevice7::SetClipPlane
6490 * Sets custom clipping plane
6495 * Index: The index of the clipping plane
6496 * PlaneEquation: An equation defining the clipping plane
6500 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6501 * See IWineD3DDevice::SetClipPlane for more details
6503 *****************************************************************************/
6505 IDirect3DDeviceImpl_7_SetClipPlane(IDirect3DDevice7
*iface
,
6507 D3DVALUE
* PlaneEquation
)
6509 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
6511 TRACE("(%p)->(%08x,%p): Relay!\n", This
, Index
, PlaneEquation
);
6514 return DDERR_INVALIDPARAMS
;
6516 EnterCriticalSection(&ddraw_cs
);
6517 hr
= IWineD3DDevice_SetClipPlane(This
->wineD3DDevice
, Index
, PlaneEquation
);
6518 LeaveCriticalSection(&ddraw_cs
);
6522 static HRESULT WINAPI
6523 IDirect3DDeviceImpl_7_SetClipPlane_FPUSetup(IDirect3DDevice7
*iface
,
6525 D3DVALUE
* PlaneEquation
)
6527 return IDirect3DDeviceImpl_7_SetClipPlane(iface
, Index
, PlaneEquation
);
6530 static HRESULT WINAPI
6531 IDirect3DDeviceImpl_7_SetClipPlane_FPUPreserve(IDirect3DDevice7
*iface
,
6533 D3DVALUE
* PlaneEquation
)
6538 old_fpucw
= d3d_fpu_setup();
6539 hr
= IDirect3DDeviceImpl_7_SetClipPlane(iface
, Index
, PlaneEquation
);
6540 set_fpu_control_word(old_fpucw
);
6545 /*****************************************************************************
6546 * IDirect3DDevice7::GetClipPlane
6548 * Returns the clipping plane with a specific index
6551 * Index: The index of the desired plane
6552 * PlaneEquation: Address to store the plane equation to
6556 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6557 * See IWineD3DDevice::GetClipPlane for more details
6559 *****************************************************************************/
6561 IDirect3DDeviceImpl_7_GetClipPlane(IDirect3DDevice7
*iface
,
6563 D3DVALUE
* PlaneEquation
)
6565 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
6567 TRACE("(%p)->(%d,%p): Relay!\n", This
, Index
, PlaneEquation
);
6570 return DDERR_INVALIDPARAMS
;
6572 EnterCriticalSection(&ddraw_cs
);
6573 hr
= IWineD3DDevice_GetClipPlane(This
->wineD3DDevice
, Index
, PlaneEquation
);
6574 LeaveCriticalSection(&ddraw_cs
);
6578 static HRESULT WINAPI
6579 IDirect3DDeviceImpl_7_GetClipPlane_FPUSetup(IDirect3DDevice7
*iface
,
6581 D3DVALUE
* PlaneEquation
)
6583 return IDirect3DDeviceImpl_7_GetClipPlane(iface
, Index
, PlaneEquation
);
6586 static HRESULT WINAPI
6587 IDirect3DDeviceImpl_7_GetClipPlane_FPUPreserve(IDirect3DDevice7
*iface
,
6589 D3DVALUE
* PlaneEquation
)
6594 old_fpucw
= d3d_fpu_setup();
6595 hr
= IDirect3DDeviceImpl_7_GetClipPlane(iface
, Index
, PlaneEquation
);
6596 set_fpu_control_word(old_fpucw
);
6601 /*****************************************************************************
6602 * IDirect3DDevice7::GetInfo
6604 * Retrieves some information about the device. The DirectX sdk says that
6605 * this version returns S_FALSE for all retail builds of DirectX, that's what
6606 * this implementation does.
6609 * DevInfoID: Information type requested
6610 * DevInfoStruct: Pointer to a structure to store the info to
6611 * Size: Size of the structure
6614 * S_FALSE, because it's a non-debug driver
6616 *****************************************************************************/
6617 static HRESULT WINAPI
6618 IDirect3DDeviceImpl_7_GetInfo(IDirect3DDevice7
*iface
,
6620 void *DevInfoStruct
,
6623 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
6624 TRACE("(%p)->(%08x,%p,%08x)\n", This
, DevInfoID
, DevInfoStruct
, Size
);
6628 TRACE(" info requested : ");
6631 case D3DDEVINFOID_TEXTUREMANAGER
: TRACE("D3DDEVINFOID_TEXTUREMANAGER\n"); break;
6632 case D3DDEVINFOID_D3DTEXTUREMANAGER
: TRACE("D3DDEVINFOID_D3DTEXTUREMANAGER\n"); break;
6633 case D3DDEVINFOID_TEXTURING
: TRACE("D3DDEVINFOID_TEXTURING\n"); break;
6634 default: ERR(" invalid flag !!!\n"); return DDERR_INVALIDPARAMS
;
6638 return S_FALSE
; /* According to MSDN, this is valid for a non-debug driver */
6641 /* For performance optimization, devices created in FPUSETUP and FPUPRESERVE modes
6642 * have separate vtables. Simple functions where this doesn't matter like GetDirect3D
6643 * are not duplicated.
6645 * Device created with DDSCL_FPUSETUP (d3d7 default) - device methods assume that FPU
6646 * has already been setup for optimal d3d operation.
6648 * Device created with DDSCL_FPUPRESERVE - resets and restores FPU mode when necessary in
6649 * d3d calls (FPU may be in a mode non-suitable for d3d when the app calls d3d). Required
6650 * by Sacrifice (game). */
6651 const IDirect3DDevice7Vtbl IDirect3DDevice7_FPUSetup_Vtbl
=
6653 /*** IUnknown Methods ***/
6654 IDirect3DDeviceImpl_7_QueryInterface
,
6655 IDirect3DDeviceImpl_7_AddRef
,
6656 IDirect3DDeviceImpl_7_Release
,
6657 /*** IDirect3DDevice7 ***/
6658 IDirect3DDeviceImpl_7_GetCaps_FPUSetup
,
6659 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUSetup
,
6660 IDirect3DDeviceImpl_7_BeginScene_FPUSetup
,
6661 IDirect3DDeviceImpl_7_EndScene_FPUSetup
,
6662 IDirect3DDeviceImpl_7_GetDirect3D
,
6663 IDirect3DDeviceImpl_7_SetRenderTarget_FPUSetup
,
6664 IDirect3DDeviceImpl_7_GetRenderTarget
,
6665 IDirect3DDeviceImpl_7_Clear_FPUSetup
,
6666 IDirect3DDeviceImpl_7_SetTransform_FPUSetup
,
6667 IDirect3DDeviceImpl_7_GetTransform_FPUSetup
,
6668 IDirect3DDeviceImpl_7_SetViewport_FPUSetup
,
6669 IDirect3DDeviceImpl_7_MultiplyTransform_FPUSetup
,
6670 IDirect3DDeviceImpl_7_GetViewport_FPUSetup
,
6671 IDirect3DDeviceImpl_7_SetMaterial_FPUSetup
,
6672 IDirect3DDeviceImpl_7_GetMaterial_FPUSetup
,
6673 IDirect3DDeviceImpl_7_SetLight_FPUSetup
,
6674 IDirect3DDeviceImpl_7_GetLight_FPUSetup
,
6675 IDirect3DDeviceImpl_7_SetRenderState_FPUSetup
,
6676 IDirect3DDeviceImpl_7_GetRenderState_FPUSetup
,
6677 IDirect3DDeviceImpl_7_BeginStateBlock_FPUSetup
,
6678 IDirect3DDeviceImpl_7_EndStateBlock_FPUSetup
,
6679 IDirect3DDeviceImpl_7_PreLoad_FPUSetup
,
6680 IDirect3DDeviceImpl_7_DrawPrimitive_FPUSetup
,
6681 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUSetup
,
6682 IDirect3DDeviceImpl_7_SetClipStatus
,
6683 IDirect3DDeviceImpl_7_GetClipStatus
,
6684 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUSetup
,
6685 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUSetup
,
6686 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUSetup
,
6687 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUSetup
,
6688 IDirect3DDeviceImpl_7_ComputeSphereVisibility
,
6689 IDirect3DDeviceImpl_7_GetTexture_FPUSetup
,
6690 IDirect3DDeviceImpl_7_SetTexture_FPUSetup
,
6691 IDirect3DDeviceImpl_7_GetTextureStageState_FPUSetup
,
6692 IDirect3DDeviceImpl_7_SetTextureStageState_FPUSetup
,
6693 IDirect3DDeviceImpl_7_ValidateDevice_FPUSetup
,
6694 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUSetup
,
6695 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUSetup
,
6696 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUSetup
,
6697 IDirect3DDeviceImpl_7_CreateStateBlock_FPUSetup
,
6698 IDirect3DDeviceImpl_7_Load_FPUSetup
,
6699 IDirect3DDeviceImpl_7_LightEnable_FPUSetup
,
6700 IDirect3DDeviceImpl_7_GetLightEnable_FPUSetup
,
6701 IDirect3DDeviceImpl_7_SetClipPlane_FPUSetup
,
6702 IDirect3DDeviceImpl_7_GetClipPlane_FPUSetup
,
6703 IDirect3DDeviceImpl_7_GetInfo
6706 const IDirect3DDevice7Vtbl IDirect3DDevice7_FPUPreserve_Vtbl
=
6708 /*** IUnknown Methods ***/
6709 IDirect3DDeviceImpl_7_QueryInterface
,
6710 IDirect3DDeviceImpl_7_AddRef
,
6711 IDirect3DDeviceImpl_7_Release
,
6712 /*** IDirect3DDevice7 ***/
6713 IDirect3DDeviceImpl_7_GetCaps_FPUPreserve
,
6714 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUPreserve
,
6715 IDirect3DDeviceImpl_7_BeginScene_FPUPreserve
,
6716 IDirect3DDeviceImpl_7_EndScene_FPUPreserve
,
6717 IDirect3DDeviceImpl_7_GetDirect3D
,
6718 IDirect3DDeviceImpl_7_SetRenderTarget_FPUPreserve
,
6719 IDirect3DDeviceImpl_7_GetRenderTarget
,
6720 IDirect3DDeviceImpl_7_Clear_FPUPreserve
,
6721 IDirect3DDeviceImpl_7_SetTransform_FPUPreserve
,
6722 IDirect3DDeviceImpl_7_GetTransform_FPUPreserve
,
6723 IDirect3DDeviceImpl_7_SetViewport_FPUPreserve
,
6724 IDirect3DDeviceImpl_7_MultiplyTransform_FPUPreserve
,
6725 IDirect3DDeviceImpl_7_GetViewport_FPUPreserve
,
6726 IDirect3DDeviceImpl_7_SetMaterial_FPUPreserve
,
6727 IDirect3DDeviceImpl_7_GetMaterial_FPUPreserve
,
6728 IDirect3DDeviceImpl_7_SetLight_FPUPreserve
,
6729 IDirect3DDeviceImpl_7_GetLight_FPUPreserve
,
6730 IDirect3DDeviceImpl_7_SetRenderState_FPUPreserve
,
6731 IDirect3DDeviceImpl_7_GetRenderState_FPUPreserve
,
6732 IDirect3DDeviceImpl_7_BeginStateBlock_FPUPreserve
,
6733 IDirect3DDeviceImpl_7_EndStateBlock_FPUPreserve
,
6734 IDirect3DDeviceImpl_7_PreLoad_FPUPreserve
,
6735 IDirect3DDeviceImpl_7_DrawPrimitive_FPUPreserve
,
6736 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUPreserve
,
6737 IDirect3DDeviceImpl_7_SetClipStatus
,
6738 IDirect3DDeviceImpl_7_GetClipStatus
,
6739 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUPreserve
,
6740 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUPreserve
,
6741 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUPreserve
,
6742 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUPreserve
,
6743 IDirect3DDeviceImpl_7_ComputeSphereVisibility
,
6744 IDirect3DDeviceImpl_7_GetTexture_FPUPreserve
,
6745 IDirect3DDeviceImpl_7_SetTexture_FPUPreserve
,
6746 IDirect3DDeviceImpl_7_GetTextureStageState_FPUPreserve
,
6747 IDirect3DDeviceImpl_7_SetTextureStageState_FPUPreserve
,
6748 IDirect3DDeviceImpl_7_ValidateDevice_FPUPreserve
,
6749 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUPreserve
,
6750 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUPreserve
,
6751 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUPreserve
,
6752 IDirect3DDeviceImpl_7_CreateStateBlock_FPUPreserve
,
6753 IDirect3DDeviceImpl_7_Load_FPUPreserve
,
6754 IDirect3DDeviceImpl_7_LightEnable_FPUPreserve
,
6755 IDirect3DDeviceImpl_7_GetLightEnable_FPUPreserve
,
6756 IDirect3DDeviceImpl_7_SetClipPlane_FPUPreserve
,
6757 IDirect3DDeviceImpl_7_GetClipPlane_FPUPreserve
,
6758 IDirect3DDeviceImpl_7_GetInfo
6761 const IDirect3DDevice3Vtbl IDirect3DDevice3_Vtbl
=
6763 /*** IUnknown Methods ***/
6764 Thunk_IDirect3DDeviceImpl_3_QueryInterface
,
6765 Thunk_IDirect3DDeviceImpl_3_AddRef
,
6766 Thunk_IDirect3DDeviceImpl_3_Release
,
6767 /*** IDirect3DDevice3 ***/
6768 IDirect3DDeviceImpl_3_GetCaps
,
6769 IDirect3DDeviceImpl_3_GetStats
,
6770 IDirect3DDeviceImpl_3_AddViewport
,
6771 IDirect3DDeviceImpl_3_DeleteViewport
,
6772 IDirect3DDeviceImpl_3_NextViewport
,
6773 Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats
,
6774 Thunk_IDirect3DDeviceImpl_3_BeginScene
,
6775 Thunk_IDirect3DDeviceImpl_3_EndScene
,
6776 Thunk_IDirect3DDeviceImpl_3_GetDirect3D
,
6777 IDirect3DDeviceImpl_3_SetCurrentViewport
,
6778 IDirect3DDeviceImpl_3_GetCurrentViewport
,
6779 Thunk_IDirect3DDeviceImpl_3_SetRenderTarget
,
6780 Thunk_IDirect3DDeviceImpl_3_GetRenderTarget
,
6781 IDirect3DDeviceImpl_3_Begin
,
6782 IDirect3DDeviceImpl_3_BeginIndexed
,
6783 IDirect3DDeviceImpl_3_Vertex
,
6784 IDirect3DDeviceImpl_3_Index
,
6785 IDirect3DDeviceImpl_3_End
,
6786 IDirect3DDeviceImpl_3_GetRenderState
,
6787 IDirect3DDeviceImpl_3_SetRenderState
,
6788 IDirect3DDeviceImpl_3_GetLightState
,
6789 IDirect3DDeviceImpl_3_SetLightState
,
6790 Thunk_IDirect3DDeviceImpl_3_SetTransform
,
6791 Thunk_IDirect3DDeviceImpl_3_GetTransform
,
6792 Thunk_IDirect3DDeviceImpl_3_MultiplyTransform
,
6793 Thunk_IDirect3DDeviceImpl_3_DrawPrimitive
,
6794 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive
,
6795 Thunk_IDirect3DDeviceImpl_3_SetClipStatus
,
6796 Thunk_IDirect3DDeviceImpl_3_GetClipStatus
,
6797 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided
,
6798 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided
,
6799 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB
,
6800 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB
,
6801 Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility
,
6802 Thunk_IDirect3DDeviceImpl_3_GetTexture
,
6803 IDirect3DDeviceImpl_3_SetTexture
,
6804 Thunk_IDirect3DDeviceImpl_3_GetTextureStageState
,
6805 Thunk_IDirect3DDeviceImpl_3_SetTextureStageState
,
6806 Thunk_IDirect3DDeviceImpl_3_ValidateDevice
6809 const IDirect3DDevice2Vtbl IDirect3DDevice2_Vtbl
=
6811 /*** IUnknown Methods ***/
6812 Thunk_IDirect3DDeviceImpl_2_QueryInterface
,
6813 Thunk_IDirect3DDeviceImpl_2_AddRef
,
6814 Thunk_IDirect3DDeviceImpl_2_Release
,
6815 /*** IDirect3DDevice2 ***/
6816 Thunk_IDirect3DDeviceImpl_2_GetCaps
,
6817 IDirect3DDeviceImpl_2_SwapTextureHandles
,
6818 Thunk_IDirect3DDeviceImpl_2_GetStats
,
6819 Thunk_IDirect3DDeviceImpl_2_AddViewport
,
6820 Thunk_IDirect3DDeviceImpl_2_DeleteViewport
,
6821 Thunk_IDirect3DDeviceImpl_2_NextViewport
,
6822 IDirect3DDeviceImpl_2_EnumTextureFormats
,
6823 Thunk_IDirect3DDeviceImpl_2_BeginScene
,
6824 Thunk_IDirect3DDeviceImpl_2_EndScene
,
6825 Thunk_IDirect3DDeviceImpl_2_GetDirect3D
,
6826 Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport
,
6827 Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport
,
6828 Thunk_IDirect3DDeviceImpl_2_SetRenderTarget
,
6829 Thunk_IDirect3DDeviceImpl_2_GetRenderTarget
,
6830 Thunk_IDirect3DDeviceImpl_2_Begin
,
6831 Thunk_IDirect3DDeviceImpl_2_BeginIndexed
,
6832 Thunk_IDirect3DDeviceImpl_2_Vertex
,
6833 Thunk_IDirect3DDeviceImpl_2_Index
,
6834 Thunk_IDirect3DDeviceImpl_2_End
,
6835 Thunk_IDirect3DDeviceImpl_2_GetRenderState
,
6836 Thunk_IDirect3DDeviceImpl_2_SetRenderState
,
6837 Thunk_IDirect3DDeviceImpl_2_GetLightState
,
6838 Thunk_IDirect3DDeviceImpl_2_SetLightState
,
6839 Thunk_IDirect3DDeviceImpl_2_SetTransform
,
6840 Thunk_IDirect3DDeviceImpl_2_GetTransform
,
6841 Thunk_IDirect3DDeviceImpl_2_MultiplyTransform
,
6842 Thunk_IDirect3DDeviceImpl_2_DrawPrimitive
,
6843 Thunk_IDirect3DDeviceImpl_2_DrawIndexedPrimitive
,
6844 Thunk_IDirect3DDeviceImpl_2_SetClipStatus
,
6845 Thunk_IDirect3DDeviceImpl_2_GetClipStatus
6848 const IDirect3DDeviceVtbl IDirect3DDevice1_Vtbl
=
6850 /*** IUnknown Methods ***/
6851 Thunk_IDirect3DDeviceImpl_1_QueryInterface
,
6852 Thunk_IDirect3DDeviceImpl_1_AddRef
,
6853 Thunk_IDirect3DDeviceImpl_1_Release
,
6854 /*** IDirect3DDevice1 ***/
6855 IDirect3DDeviceImpl_1_Initialize
,
6856 Thunk_IDirect3DDeviceImpl_1_GetCaps
,
6857 Thunk_IDirect3DDeviceImpl_1_SwapTextureHandles
,
6858 IDirect3DDeviceImpl_1_CreateExecuteBuffer
,
6859 Thunk_IDirect3DDeviceImpl_1_GetStats
,
6860 IDirect3DDeviceImpl_1_Execute
,
6861 Thunk_IDirect3DDeviceImpl_1_AddViewport
,
6862 Thunk_IDirect3DDeviceImpl_1_DeleteViewport
,
6863 Thunk_IDirect3DDeviceImpl_1_NextViewport
,
6864 IDirect3DDeviceImpl_1_Pick
,
6865 IDirect3DDeviceImpl_1_GetPickRecords
,
6866 Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats
,
6867 IDirect3DDeviceImpl_1_CreateMatrix
,
6868 IDirect3DDeviceImpl_1_SetMatrix
,
6869 IDirect3DDeviceImpl_1_GetMatrix
,
6870 IDirect3DDeviceImpl_1_DeleteMatrix
,
6871 Thunk_IDirect3DDeviceImpl_1_BeginScene
,
6872 Thunk_IDirect3DDeviceImpl_1_EndScene
,
6873 Thunk_IDirect3DDeviceImpl_1_GetDirect3D
6876 /*****************************************************************************
6877 * IDirect3DDeviceImpl_CreateHandle
6879 * Not called from the VTable
6881 * Some older interface versions operate with handles, which are basically
6882 * DWORDs which identify an interface, for example
6883 * IDirect3DDevice::SetRenderState with DIRECT3DRENDERSTATE_TEXTUREHANDLE
6885 * Those handle could be just casts to the interface pointers or vice versa,
6886 * but that is not 64 bit safe and would mean blindly derefering a DWORD
6887 * passed by the app. Instead there is a dynamic array in the device which
6888 * keeps a DWORD to pointer information and a type for the handle.
6890 * Basically this array only grows, when a handle is freed its pointer is
6891 * just set to NULL. There will be much more reads from the array than
6892 * insertion operations, so a dynamic array is fine.
6895 * This: D3DDevice implementation for which this handle should be created
6898 * A free handle on success
6901 *****************************************************************************/
6903 IDirect3DDeviceImpl_CreateHandle(IDirect3DDeviceImpl
*This
)
6906 struct HandleEntry
*oldHandles
= This
->Handles
;
6908 TRACE("(%p)\n", This
);
6910 for(i
= 0; i
< This
->numHandles
; i
++)
6912 if(This
->Handles
[i
].ptr
== NULL
&&
6913 This
->Handles
[i
].type
== DDrawHandle_Unknown
)
6915 TRACE("Reusing freed handle %d\n", i
+ 1);
6920 TRACE("Growing the handle array\n");
6923 This
->Handles
= HeapAlloc(GetProcessHeap(), 0, sizeof(struct HandleEntry
) * This
->numHandles
);
6926 ERR("Out of memory\n");
6927 This
->Handles
= oldHandles
;
6933 memcpy(This
->Handles
, oldHandles
, (This
->numHandles
- 1) * sizeof(struct HandleEntry
));
6934 HeapFree(GetProcessHeap(), 0, oldHandles
);
6937 TRACE("Returning %d\n", This
->numHandles
);
6938 return This
->numHandles
;
6941 /*****************************************************************************
6942 * IDirect3DDeviceImpl_UpdateDepthStencil
6944 * Checks the current render target for attached depth stencils and sets the
6945 * WineD3D depth stencil accordingly.
6948 * The depth stencil state to set if creating the device
6950 *****************************************************************************/
6952 IDirect3DDeviceImpl_UpdateDepthStencil(IDirect3DDeviceImpl
*This
)
6954 IDirectDrawSurface7
*depthStencil
= NULL
;
6955 IDirectDrawSurfaceImpl
*dsi
;
6956 static DDSCAPS2 depthcaps
= { DDSCAPS_ZBUFFER
, 0, 0, 0 };
6958 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7
*)This
->target
, &depthcaps
, &depthStencil
);
6961 TRACE("Setting wined3d depth stencil to NULL\n");
6962 IWineD3DDevice_SetDepthStencilSurface(This
->wineD3DDevice
,
6964 return WINED3DZB_FALSE
;
6967 dsi
= (IDirectDrawSurfaceImpl
*)depthStencil
;
6968 TRACE("Setting wined3d depth stencil to %p (wined3d %p)\n", dsi
, dsi
->WineD3DSurface
);
6969 IWineD3DDevice_SetDepthStencilSurface(This
->wineD3DDevice
,
6970 dsi
->WineD3DSurface
);
6972 IDirectDrawSurface7_Release(depthStencil
);
6973 return WINED3DZB_TRUE
;