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");
90 set_fpu_control_word(0x37f);
95 /*****************************************************************************
96 * IUnknown Methods. Common for Version 1, 2, 3 and 7
97 *****************************************************************************/
99 /*****************************************************************************
100 * IDirect3DDevice7::QueryInterface
102 * Used to query other interfaces from a Direct3DDevice interface.
103 * It can return interface pointers to all Direct3DDevice versions as well
104 * as IDirectDraw and IDirect3D. For a link to QueryInterface
105 * rules see ddraw.c, IDirectDraw7::QueryInterface
107 * Exists in Version 1, 2, 3 and 7
110 * refiid: Interface ID queried for
111 * obj: Used to return the interface pointer
114 * D3D_OK or E_NOINTERFACE
116 *****************************************************************************/
117 static HRESULT WINAPI
118 IDirect3DDeviceImpl_7_QueryInterface(IDirect3DDevice7
*iface
,
122 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
123 TRACE("(%p)->(%s,%p)\n", This
, debugstr_guid(refiid
), obj
);
125 /* According to COM docs, if the QueryInterface fails, obj should be set to NULL */
129 return DDERR_INVALIDPARAMS
;
131 if ( IsEqualGUID( &IID_IUnknown
, refiid
) )
133 *obj
= ICOM_INTERFACE(This
, IDirect3DDevice7
);
136 /* Check DirectDraw Interfac\x01s */
137 else if( IsEqualGUID( &IID_IDirectDraw7
, refiid
) )
139 *obj
= ICOM_INTERFACE(This
->ddraw
, IDirectDraw7
);
140 TRACE("(%p) Returning IDirectDraw7 interface at %p\n", This
, *obj
);
142 else if ( IsEqualGUID( &IID_IDirectDraw4
, refiid
) )
144 *obj
= ICOM_INTERFACE(This
->ddraw
, IDirectDraw4
);
145 TRACE("(%p) Returning IDirectDraw4 interface at %p\n", This
, *obj
);
147 else if ( IsEqualGUID( &IID_IDirectDraw2
, refiid
) )
149 *obj
= ICOM_INTERFACE(This
->ddraw
, IDirectDraw2
);
150 TRACE("(%p) Returning IDirectDraw2 interface at %p\n", This
, *obj
);
152 else if( IsEqualGUID( &IID_IDirectDraw
, refiid
) )
154 *obj
= ICOM_INTERFACE(This
->ddraw
, IDirectDraw
);
155 TRACE("(%p) Returning IDirectDraw interface at %p\n", This
, *obj
);
159 else if ( IsEqualGUID( &IID_IDirect3D
, refiid
) )
161 *obj
= ICOM_INTERFACE(This
->ddraw
, IDirect3D
);
162 TRACE("(%p) Returning IDirect3D interface at %p\n", This
, *obj
);
164 else if ( IsEqualGUID( &IID_IDirect3D2
, refiid
) )
166 *obj
= ICOM_INTERFACE(This
->ddraw
, IDirect3D2
);
167 TRACE("(%p) Returning IDirect3D2 interface at %p\n", This
, *obj
);
169 else if ( IsEqualGUID( &IID_IDirect3D3
, refiid
) )
171 *obj
= ICOM_INTERFACE(This
->ddraw
, IDirect3D3
);
172 TRACE("(%p) Returning IDirect3D3 interface at %p\n", This
, *obj
);
174 else if ( IsEqualGUID( &IID_IDirect3D7
, refiid
) )
176 *obj
= ICOM_INTERFACE(This
->ddraw
, IDirect3D7
);
177 TRACE("(%p) Returning IDirect3D7 interface at %p\n", This
, *obj
);
181 else if ( IsEqualGUID( &IID_IDirect3DDevice
, refiid
) )
183 *obj
= ICOM_INTERFACE(This
, IDirect3DDevice
);
184 TRACE("(%p) Returning IDirect3DDevice interface at %p\n", This
, *obj
);
186 else if ( IsEqualGUID( &IID_IDirect3DDevice2
, refiid
) ) {
187 *obj
= ICOM_INTERFACE(This
, IDirect3DDevice2
);
188 TRACE("(%p) Returning IDirect3DDevice2 interface at %p\n", This
, *obj
);
190 else if ( IsEqualGUID( &IID_IDirect3DDevice3
, refiid
) ) {
191 *obj
= ICOM_INTERFACE(This
, IDirect3DDevice3
);
192 TRACE("(%p) Returning IDirect3DDevice3 interface at %p\n", This
, *obj
);
194 else if ( IsEqualGUID( &IID_IDirect3DDevice7
, refiid
) ) {
195 *obj
= ICOM_INTERFACE(This
, IDirect3DDevice7
);
196 TRACE("(%p) Returning IDirect3DDevice7 interface at %p\n", This
, *obj
);
199 /* Unknown interface */
202 ERR("(%p)->(%s, %p): No interface found\n", This
, debugstr_guid(refiid
), obj
);
203 return E_NOINTERFACE
;
206 /* AddRef the returned interface */
207 IUnknown_AddRef( (IUnknown
*) *obj
);
211 static HRESULT WINAPI
212 Thunk_IDirect3DDeviceImpl_3_QueryInterface(IDirect3DDevice3
*iface
,
216 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice3
, iface
);
217 TRACE_(ddraw_thunk
)("(%p)->(%s,%p) thunking to IDirect3DDevice7 interface.\n", This
, debugstr_guid(riid
), obj
);
218 return IDirect3DDevice7_QueryInterface(ICOM_INTERFACE(This
, IDirect3DDevice7
),
223 static HRESULT WINAPI
224 Thunk_IDirect3DDeviceImpl_2_QueryInterface(IDirect3DDevice2
*iface
,
228 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice2
, iface
);
229 TRACE_(ddraw_thunk
)("(%p)->(%s,%p) thunking to IDirect3DDevice7 interface.\n", This
, debugstr_guid(riid
), obj
);
230 return IDirect3DDevice7_QueryInterface(ICOM_INTERFACE(This
, IDirect3DDevice7
),
235 static HRESULT WINAPI
236 Thunk_IDirect3DDeviceImpl_1_QueryInterface(IDirect3DDevice
*iface
,
240 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice
, iface
);
241 TRACE_(ddraw_thunk
)("(%p)->(%s,%p) thunking to IDirect3DDevice7 interface.\n", This
, debugstr_guid(riid
), obp
);
242 return IDirect3DDevice7_QueryInterface(ICOM_INTERFACE(This
, IDirect3DDevice7
),
247 /*****************************************************************************
248 * IDirect3DDevice7::AddRef
250 * Increases the refcount....
251 * The most exciting Method, definitely
253 * Exists in Version 1, 2, 3 and 7
258 *****************************************************************************/
260 IDirect3DDeviceImpl_7_AddRef(IDirect3DDevice7
*iface
)
262 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
263 ULONG ref
= InterlockedIncrement(&This
->ref
);
265 TRACE("(%p) : incrementing from %u.\n", This
, ref
-1);
271 Thunk_IDirect3DDeviceImpl_3_AddRef(IDirect3DDevice3
*iface
)
273 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice3
, iface
);
274 TRACE_(ddraw_thunk
)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This
);
275 return IDirect3DDevice7_AddRef(ICOM_INTERFACE(This
, IDirect3DDevice7
));
279 Thunk_IDirect3DDeviceImpl_2_AddRef(IDirect3DDevice2
*iface
)
281 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice2
, iface
);
282 TRACE_(ddraw_thunk
)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This
);
283 return IDirect3DDevice7_AddRef(ICOM_INTERFACE(This
, IDirect3DDevice7
));
287 Thunk_IDirect3DDeviceImpl_1_AddRef(IDirect3DDevice
*iface
)
289 TRACE_(ddraw_thunk
)("(%p)->() thunking to IDirect3DDevice7 interface.\n", iface
);
290 return IDirect3DDevice7_AddRef(COM_INTERFACE_CAST(IDirect3DDeviceImpl
, IDirect3DDevice
, IDirect3DDevice7
, iface
));
293 /*****************************************************************************
294 * IDirect3DDevice7::Release
296 * Decreases the refcount of the interface
297 * When the refcount is reduced to 0, the object is destroyed.
299 * Exists in Version 1, 2, 3 and 7
304 *****************************************************************************/
306 IDirect3DDeviceImpl_7_Release(IDirect3DDevice7
*iface
)
308 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
309 ULONG ref
= InterlockedDecrement(&This
->ref
);
311 TRACE("(%p)->() decrementing from %u.\n", This
, ref
+1);
313 /* This method doesn't destroy the WineD3DDevice, because it's still in use for
314 * 2D rendering. IDirectDrawSurface7::Release will destroy the WineD3DDevice
315 * when the render target is released
319 IParent
*IndexBufferParent
;
322 EnterCriticalSection(&ddraw_cs
);
323 /* Free the index buffer. */
324 IWineD3DDevice_SetIndices(This
->wineD3DDevice
, NULL
);
325 IWineD3DIndexBuffer_GetParent(This
->indexbuffer
,
326 (IUnknown
**) &IndexBufferParent
);
327 IParent_Release(IndexBufferParent
); /* Once for the getParent */
328 if( IParent_Release(IndexBufferParent
) != 0) /* And now to destroy it */
330 ERR(" (%p) Something is still holding the index buffer parent %p\n", This
, IndexBufferParent
);
333 /* There is no need to unset the vertex buffer here, IWineD3DDevice_Uninit3D will do that when
334 * destroying the primary stateblock. If a vertex buffer is destroyed while it is bound
335 * IDirect3DVertexBuffer::Release will unset it.
338 /* Restore the render targets */
339 if(This
->OffScreenTarget
)
345 vp
.Width
= This
->ddraw
->d3d_target
->surface_desc
.dwWidth
;
346 vp
.Height
= This
->ddraw
->d3d_target
->surface_desc
.dwHeight
;
349 IWineD3DDevice_SetViewport(This
->wineD3DDevice
,
352 /* Set the device up to render to the front buffer since the back buffer will
355 IWineD3DDevice_SetRenderTarget(This
->wineD3DDevice
, 0,
356 This
->ddraw
->d3d_target
->WineD3DSurface
);
357 /* This->target is the offscreen target.
358 * This->ddraw->d3d_target is the target used by DDraw
360 TRACE("(%p) Release: Using %p as front buffer, %p as back buffer\n", This
, This
->ddraw
->d3d_target
, NULL
);
361 IWineD3DDevice_SetFrontBackBuffers(This
->wineD3DDevice
,
362 This
->ddraw
->d3d_target
->WineD3DSurface
,
366 /* Release the WineD3DDevice. This won't destroy it */
367 if(IWineD3DDevice_Release(This
->wineD3DDevice
) <= 0)
369 ERR(" (%p) The wineD3D device %p was destroyed unexpectedly. Prepare for trouble\n", This
, This
->wineD3DDevice
);
372 /* The texture handles should be unset by now, but there might be some bits
373 * missing in our reference counting(needs test). Do a sanity check
375 for(i
= 0; i
< This
->numHandles
; i
++)
377 if(This
->Handles
[i
].ptr
)
379 switch(This
->Handles
[i
].type
)
381 case DDrawHandle_Texture
:
383 IDirectDrawSurfaceImpl
*surf
= (IDirectDrawSurfaceImpl
*) This
->Handles
[i
].ptr
;
384 FIXME("Texture Handle %d not unset properly\n", i
+ 1);
389 case DDrawHandle_Material
:
391 IDirect3DMaterialImpl
*mat
= (IDirect3DMaterialImpl
*) This
->Handles
[i
].ptr
;
392 FIXME("Material handle %d not unset properly\n", i
+ 1);
397 case DDrawHandle_Matrix
:
399 /* No fixme here because this might happen because of sloppy apps */
400 WARN("Leftover matrix handle %d, deleting\n", i
+ 1);
401 IDirect3DDevice_DeleteMatrix(ICOM_INTERFACE(This
, IDirect3DDevice
),
406 case DDrawHandle_StateBlock
:
408 /* No fixme here because this might happen because of sloppy apps */
409 WARN("Leftover stateblock handle %d, deleting\n", i
+ 1);
410 IDirect3DDevice7_DeleteStateBlock(ICOM_INTERFACE(This
, IDirect3DDevice7
),
416 FIXME("Unknown handle %d not unset properly\n", i
+ 1);
421 HeapFree(GetProcessHeap(), 0, This
->Handles
);
423 TRACE("Releasing target %p %p\n", This
->target
, This
->ddraw
->d3d_target
);
424 /* Release the render target and the WineD3D render target
425 * (See IDirect3D7::CreateDevice for more comments on this)
427 IDirectDrawSurface7_Release(ICOM_INTERFACE(This
->target
, IDirectDrawSurface7
));
428 IDirectDrawSurface7_Release(ICOM_INTERFACE(This
->ddraw
->d3d_target
,IDirectDrawSurface7
));
429 TRACE("Target release done\n");
431 This
->ddraw
->d3ddevice
= NULL
;
433 /* Now free the structure */
434 HeapFree(GetProcessHeap(), 0, This
);
435 LeaveCriticalSection(&ddraw_cs
);
443 Thunk_IDirect3DDeviceImpl_3_Release(IDirect3DDevice3
*iface
)
445 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice3
, iface
);
446 TRACE_(ddraw_thunk
)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This
);
447 return IDirect3DDevice7_Release(ICOM_INTERFACE(This
, IDirect3DDevice7
));
451 Thunk_IDirect3DDeviceImpl_2_Release(IDirect3DDevice2
*iface
)
453 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice2
, iface
);
454 TRACE_(ddraw_thunk
)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This
);
455 return IDirect3DDevice7_Release(ICOM_INTERFACE(This
, IDirect3DDevice7
));
459 Thunk_IDirect3DDeviceImpl_1_Release(IDirect3DDevice
*iface
)
461 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice
, iface
);
462 TRACE_(ddraw_thunk
)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This
);
463 return IDirect3DDevice7_Release(ICOM_INTERFACE(This
, IDirect3DDevice7
));
466 /*****************************************************************************
467 * IDirect3DDevice Methods
468 *****************************************************************************/
470 /*****************************************************************************
471 * IDirect3DDevice::Initialize
473 * Initializes a Direct3DDevice. This implementation is a no-op, as all
474 * initialization is done at create time.
476 * Exists in Version 1
479 * No idea what they mean, as the MSDN page is gone
483 *****************************************************************************/
484 static HRESULT WINAPI
485 IDirect3DDeviceImpl_1_Initialize(IDirect3DDevice
*iface
,
486 IDirect3D
*Direct3D
, GUID
*guid
,
489 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice
, iface
);
491 /* It shouldn't be crucial, but print a FIXME, I'm interested if
492 * any game calls it and when
494 FIXME("(%p)->(%p,%p,%p): No-op!\n", This
, Direct3D
, guid
, Desc
);
499 /*****************************************************************************
500 * IDirect3DDevice7::GetCaps
502 * Retrieves the device's capabilities
504 * This implementation is used for Version 7 only, the older versions have
505 * their own implementation.
508 * Desc: Pointer to a D3DDEVICEDESC7 structure to fill
512 * D3DERR_* if a problem occurs. See WineD3D
514 *****************************************************************************/
516 IDirect3DDeviceImpl_7_GetCaps(IDirect3DDevice7
*iface
,
517 D3DDEVICEDESC7
*Desc
)
519 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
520 D3DDEVICEDESC OldDesc
;
521 TRACE("(%p)->(%p)\n", This
, Desc
);
523 /* Call the same function used by IDirect3D, this saves code */
524 return IDirect3DImpl_GetCaps(This
->ddraw
->wineD3D
, &OldDesc
, Desc
);
527 static HRESULT WINAPI
528 IDirect3DDeviceImpl_7_GetCaps_FPUSetup(IDirect3DDevice7
*iface
,
529 D3DDEVICEDESC7
*Desc
)
531 return IDirect3DDeviceImpl_7_GetCaps(iface
, Desc
);
534 static HRESULT WINAPI
535 IDirect3DDeviceImpl_7_GetCaps_FPUPreserve(IDirect3DDevice7
*iface
,
536 D3DDEVICEDESC7
*Desc
)
541 old_fpucw
= d3d_fpu_setup();
542 hr
= IDirect3DDeviceImpl_7_GetCaps(iface
, Desc
);
543 set_fpu_control_word(old_fpucw
);
547 /*****************************************************************************
548 * IDirect3DDevice3::GetCaps
550 * Retrieves the capabilities of the hardware device and the emulation
551 * device. For Wine, hardware and emulation are the same (it's all HW).
553 * This implementation is used for Version 1, 2, and 3. Version 7 has its own
556 * HWDesc: Structure to fill with the HW caps
557 * HelDesc: Structure to fill with the hardware emulation caps
561 * D3DERR_* if a problem occurs. See WineD3D
563 *****************************************************************************/
564 static HRESULT WINAPI
565 IDirect3DDeviceImpl_3_GetCaps(IDirect3DDevice3
*iface
,
566 D3DDEVICEDESC
*HWDesc
,
567 D3DDEVICEDESC
*HelDesc
)
569 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice3
, iface
);
570 D3DDEVICEDESC7 newDesc
;
572 TRACE("(%p)->(%p,%p)\n", iface
, HWDesc
, HelDesc
);
574 hr
= IDirect3DImpl_GetCaps(This
->ddraw
->wineD3D
, HWDesc
, &newDesc
);
575 if(hr
!= D3D_OK
) return hr
;
581 static HRESULT WINAPI
582 Thunk_IDirect3DDeviceImpl_2_GetCaps(IDirect3DDevice2
*iface
,
583 D3DDEVICEDESC
*D3DHWDevDesc
,
584 D3DDEVICEDESC
*D3DHELDevDesc
)
586 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice2
, iface
);
587 TRACE_(ddraw_thunk
)("(%p)->(%p,%p) thunking to IDirect3DDevice3 interface.\n", This
, D3DHWDevDesc
, D3DHELDevDesc
);
588 return IDirect3DDevice3_GetCaps(ICOM_INTERFACE(This
, IDirect3DDevice3
),
593 static HRESULT WINAPI
594 Thunk_IDirect3DDeviceImpl_1_GetCaps(IDirect3DDevice
*iface
,
595 D3DDEVICEDESC
*D3DHWDevDesc
,
596 D3DDEVICEDESC
*D3DHELDevDesc
)
598 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice
, iface
);
599 TRACE_(ddraw_thunk
)("(%p)->(%p,%p) thunking to IDirect3DDevice3 interface.\n", This
, D3DHWDevDesc
, D3DHELDevDesc
);
600 return IDirect3DDevice3_GetCaps(ICOM_INTERFACE(This
, IDirect3DDevice3
),
605 /*****************************************************************************
606 * IDirect3DDevice2::SwapTextureHandles
608 * Swaps the texture handles of 2 Texture interfaces. Version 1 and 2
611 * Tex1, Tex2: The 2 Textures to swap
616 *****************************************************************************/
617 static HRESULT WINAPI
618 IDirect3DDeviceImpl_2_SwapTextureHandles(IDirect3DDevice2
*iface
,
619 IDirect3DTexture2
*Tex1
,
620 IDirect3DTexture2
*Tex2
)
622 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice2
, iface
);
624 IDirectDrawSurfaceImpl
*surf1
= ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirect3DTexture2
, Tex1
);
625 IDirectDrawSurfaceImpl
*surf2
= ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirect3DTexture2
, Tex2
);
626 TRACE("(%p)->(%p,%p)\n", This
, surf1
, surf2
);
628 EnterCriticalSection(&ddraw_cs
);
629 This
->Handles
[surf1
->Handle
- 1].ptr
= surf2
;
630 This
->Handles
[surf2
->Handle
- 1].ptr
= surf1
;
632 swap
= surf2
->Handle
;
633 surf2
->Handle
= surf1
->Handle
;
634 surf1
->Handle
= swap
;
635 LeaveCriticalSection(&ddraw_cs
);
640 static HRESULT WINAPI
641 Thunk_IDirect3DDeviceImpl_1_SwapTextureHandles(IDirect3DDevice
*iface
,
642 IDirect3DTexture
*D3DTex1
,
643 IDirect3DTexture
*D3DTex2
)
645 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice
, iface
);
646 IDirectDrawSurfaceImpl
*surf1
= ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirect3DTexture
, D3DTex1
);
647 IDirectDrawSurfaceImpl
*surf2
= ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirect3DTexture
, D3DTex2
);
648 TRACE_(ddraw_thunk
)("(%p)->(%p,%p) thunking to IDirect3DDevice2 interface.\n", This
, surf1
, surf2
);
649 return IDirect3DDevice2_SwapTextureHandles(ICOM_INTERFACE(This
, IDirect3DDevice2
),
650 ICOM_INTERFACE(surf1
, IDirect3DTexture2
),
651 ICOM_INTERFACE(surf2
, IDirect3DTexture2
));
654 /*****************************************************************************
655 * IDirect3DDevice3::GetStats
657 * This method seems to retrieve some stats from the device.
658 * The MSDN documentation doesn't exist any more, but the D3DSTATS
659 * structure suggests that the amount of drawn primitives and processed
660 * vertices is returned.
662 * Exists in Version 1, 2 and 3
665 * Stats: Pointer to a D3DSTATS structure to be filled
669 * DDERR_INVALIDPARAMS if Stats == NULL
671 *****************************************************************************/
672 static HRESULT WINAPI
673 IDirect3DDeviceImpl_3_GetStats(IDirect3DDevice3
*iface
,
676 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice3
, iface
);
677 FIXME("(%p)->(%p): Stub!\n", This
, Stats
);
680 return DDERR_INVALIDPARAMS
;
682 /* Fill the Stats with 0 */
683 Stats
->dwTrianglesDrawn
= 0;
684 Stats
->dwLinesDrawn
= 0;
685 Stats
->dwPointsDrawn
= 0;
686 Stats
->dwSpansDrawn
= 0;
687 Stats
->dwVerticesProcessed
= 0;
692 static HRESULT WINAPI
693 Thunk_IDirect3DDeviceImpl_2_GetStats(IDirect3DDevice2
*iface
,
696 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice2
, iface
);
697 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This
, Stats
);
698 return IDirect3DDevice3_GetStats(ICOM_INTERFACE(This
, IDirect3DDevice3
),
702 static HRESULT WINAPI
703 Thunk_IDirect3DDeviceImpl_1_GetStats(IDirect3DDevice
*iface
,
706 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice
, iface
);
707 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This
, Stats
);
708 return IDirect3DDevice3_GetStats(ICOM_INTERFACE(This
, IDirect3DDevice3
),
712 /*****************************************************************************
713 * IDirect3DDevice::CreateExecuteBuffer
715 * Creates an IDirect3DExecuteBuffer, used for rendering with a
721 * Desc: Buffer description
722 * ExecuteBuffer: Address to return the Interface pointer at
723 * UnkOuter: Must be NULL. Basically for aggregation, which ddraw doesn't
727 * CLASS_E_NOAGGREGATION if UnkOuter != NULL
728 * DDERR_OUTOFMEMORY if we ran out of memory
731 *****************************************************************************/
732 static HRESULT WINAPI
733 IDirect3DDeviceImpl_1_CreateExecuteBuffer(IDirect3DDevice
*iface
,
734 D3DEXECUTEBUFFERDESC
*Desc
,
735 IDirect3DExecuteBuffer
**ExecuteBuffer
,
738 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice
, iface
);
739 IDirect3DExecuteBufferImpl
* object
;
740 TRACE("(%p)->(%p,%p,%p)!\n", This
, Desc
, ExecuteBuffer
, UnkOuter
);
743 return CLASS_E_NOAGGREGATION
;
745 /* Allocate the new Execute Buffer */
746 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirect3DExecuteBufferImpl
));
749 ERR("Out of memory when allocating a IDirect3DExecuteBufferImpl structure\n");
750 return DDERR_OUTOFMEMORY
;
753 ICOM_INIT_INTERFACE(object
, IDirect3DExecuteBuffer
, IDirect3DExecuteBuffer_Vtbl
);
756 object
->d3ddev
= This
;
758 /* Initializes memory */
759 memcpy(&object
->desc
, Desc
, Desc
->dwSize
);
761 /* No buffer given */
762 if ((object
->desc
.dwFlags
& D3DDEB_LPDATA
) == 0)
763 object
->desc
.lpData
= NULL
;
765 /* No buffer size given */
766 if ((object
->desc
.dwFlags
& D3DDEB_BUFSIZE
) == 0)
767 object
->desc
.dwBufferSize
= 0;
769 /* Create buffer if asked */
770 if ((object
->desc
.lpData
== NULL
) && (object
->desc
.dwBufferSize
> 0))
772 object
->need_free
= TRUE
;
773 object
->desc
.lpData
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,object
->desc
.dwBufferSize
);
774 if(!object
->desc
.lpData
)
776 ERR("Out of memory when allocating the execute buffer data\n");
777 HeapFree(GetProcessHeap(), 0, object
);
778 return DDERR_OUTOFMEMORY
;
783 object
->need_free
= FALSE
;
786 /* No vertices for the moment */
787 object
->vertex_data
= NULL
;
789 object
->desc
.dwFlags
|= D3DDEB_LPDATA
;
791 object
->indices
= NULL
;
792 object
->nb_indices
= 0;
794 *ExecuteBuffer
= ICOM_INTERFACE(object
, IDirect3DExecuteBuffer
);
796 TRACE(" Returning IDirect3DExecuteBuffer at %p, implementation is at %p\n", *ExecuteBuffer
, object
);
801 /*****************************************************************************
802 * IDirect3DDevice::Execute
804 * Executes all the stuff in an execute buffer.
807 * ExecuteBuffer: The buffer to execute
808 * Viewport: The viewport used for rendering
812 * DDERR_INVALIDPARAMS if ExecuteBuffer == NULL
815 *****************************************************************************/
816 static HRESULT WINAPI
817 IDirect3DDeviceImpl_1_Execute(IDirect3DDevice
*iface
,
818 IDirect3DExecuteBuffer
*ExecuteBuffer
,
819 IDirect3DViewport
*Viewport
,
822 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice
, iface
);
823 IDirect3DExecuteBufferImpl
*Direct3DExecuteBufferImpl
= ICOM_OBJECT(IDirect3DExecuteBufferImpl
, IDirect3DExecuteBuffer
, ExecuteBuffer
);
824 IDirect3DViewportImpl
*Direct3DViewportImpl
= ICOM_OBJECT(IDirect3DViewportImpl
, IDirect3DViewport3
, Viewport
);
826 TRACE("(%p)->(%p,%p,%08x)\n", This
, Direct3DExecuteBufferImpl
, Direct3DViewportImpl
, Flags
);
828 if(!Direct3DExecuteBufferImpl
)
829 return DDERR_INVALIDPARAMS
;
832 EnterCriticalSection(&ddraw_cs
);
833 IDirect3DExecuteBufferImpl_Execute(Direct3DExecuteBufferImpl
, This
, Direct3DViewportImpl
);
834 LeaveCriticalSection(&ddraw_cs
);
839 /*****************************************************************************
840 * IDirect3DDevice3::AddViewport
842 * Add a Direct3DViewport to the device's viewport list. These viewports
843 * are wrapped to IDirect3DDevice7 viewports in viewport.c
845 * Exists in Version 1, 2 and 3. Note that IDirect3DViewport 1, 2 and 3
846 * are the same interfaces.
849 * Viewport: The viewport to add
852 * DDERR_INVALIDPARAMS if Viewport == NULL
855 *****************************************************************************/
856 static HRESULT WINAPI
857 IDirect3DDeviceImpl_3_AddViewport(IDirect3DDevice3
*iface
,
858 IDirect3DViewport3
*Viewport
)
860 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice3
, iface
);
861 IDirect3DViewportImpl
*vp
= ICOM_OBJECT(IDirect3DViewportImpl
, IDirect3DViewport3
, Viewport
);
863 TRACE("(%p)->(%p)\n", This
, vp
);
867 return DDERR_INVALIDPARAMS
;
869 EnterCriticalSection(&ddraw_cs
);
870 vp
->next
= This
->viewport_list
;
871 This
->viewport_list
= vp
;
872 vp
->active_device
= This
; /* Viewport must be usable for Clear() after AddViewport,
873 so set active_device here. */
874 LeaveCriticalSection(&ddraw_cs
);
879 static HRESULT WINAPI
880 Thunk_IDirect3DDeviceImpl_2_AddViewport(IDirect3DDevice2
*iface
,
881 IDirect3DViewport2
*Direct3DViewport2
)
883 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice2
, iface
);
884 IDirect3DViewportImpl
*vp
= ICOM_OBJECT(IDirect3DViewportImpl
, IDirect3DViewport3
, Direct3DViewport2
);
885 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This
, vp
);
886 return IDirect3DDevice3_AddViewport(ICOM_INTERFACE(This
, IDirect3DDevice3
),
887 ICOM_INTERFACE(vp
, IDirect3DViewport3
));
890 static HRESULT WINAPI
891 Thunk_IDirect3DDeviceImpl_1_AddViewport(IDirect3DDevice
*iface
,
892 IDirect3DViewport
*Direct3DViewport
)
894 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice
, iface
);
895 IDirect3DViewportImpl
*vp
= ICOM_OBJECT(IDirect3DViewportImpl
, IDirect3DViewport3
, Direct3DViewport
);
896 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This
, vp
);
897 return IDirect3DDevice3_AddViewport(ICOM_INTERFACE(This
, IDirect3DDevice3
),
898 ICOM_INTERFACE(vp
, IDirect3DViewport3
));
901 /*****************************************************************************
902 * IDirect3DDevice3::DeleteViewport
904 * Deletes a Direct3DViewport from the device's viewport list.
906 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
910 * Viewport: The viewport to delete
914 * DDERR_INVALIDPARAMS if the viewport wasn't found in the list
916 *****************************************************************************/
917 static HRESULT WINAPI
918 IDirect3DDeviceImpl_3_DeleteViewport(IDirect3DDevice3
*iface
,
919 IDirect3DViewport3
*Viewport
)
921 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice3
, iface
);
922 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*) Viewport
;
923 IDirect3DViewportImpl
*cur_viewport
, *prev_viewport
= NULL
;
925 TRACE("(%p)->(%p)\n", This
, vp
);
927 EnterCriticalSection(&ddraw_cs
);
928 cur_viewport
= This
->viewport_list
;
929 while (cur_viewport
!= NULL
)
931 if (cur_viewport
== vp
)
933 if (prev_viewport
== NULL
) This
->viewport_list
= cur_viewport
->next
;
934 else prev_viewport
->next
= cur_viewport
->next
;
935 /* TODO : add desactivate of the viewport and all associated lights... */
936 LeaveCriticalSection(&ddraw_cs
);
939 prev_viewport
= cur_viewport
;
940 cur_viewport
= cur_viewport
->next
;
943 LeaveCriticalSection(&ddraw_cs
);
944 return DDERR_INVALIDPARAMS
;
947 static HRESULT WINAPI
948 Thunk_IDirect3DDeviceImpl_2_DeleteViewport(IDirect3DDevice2
*iface
,
949 IDirect3DViewport2
*Direct3DViewport2
)
951 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice2
, iface
);
952 IDirect3DViewportImpl
*vp
= ICOM_OBJECT(IDirect3DViewportImpl
, IDirect3DViewport3
, Direct3DViewport2
);
953 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This
, vp
);
954 return IDirect3DDevice3_DeleteViewport(ICOM_INTERFACE(This
, IDirect3DDevice3
),
955 ICOM_INTERFACE(vp
, IDirect3DViewport3
));
958 static HRESULT WINAPI
959 Thunk_IDirect3DDeviceImpl_1_DeleteViewport(IDirect3DDevice
*iface
,
960 IDirect3DViewport
*Direct3DViewport
)
962 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice
, iface
);
963 IDirect3DViewportImpl
*vp
= ICOM_OBJECT(IDirect3DViewportImpl
, IDirect3DViewport3
, Direct3DViewport
);
964 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This
, vp
);
965 return IDirect3DDevice3_DeleteViewport(ICOM_INTERFACE(This
, IDirect3DDevice3
),
966 ICOM_INTERFACE(vp
, IDirect3DViewport3
));
969 /*****************************************************************************
970 * IDirect3DDevice3::NextViewport
972 * Returns a viewport from the viewport list, depending on the
973 * passed viewport and the flags.
975 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
979 * Viewport: Viewport to use for beginning the search
980 * Flags: D3DNEXT_NEXT, D3DNEXT_HEAD or D3DNEXT_TAIL
984 * DDERR_INVALIDPARAMS if the flags were wrong, or Viewport was NULL
986 *****************************************************************************/
987 static HRESULT WINAPI
988 IDirect3DDeviceImpl_3_NextViewport(IDirect3DDevice3
*iface
,
989 IDirect3DViewport3
*Viewport3
,
990 IDirect3DViewport3
**lplpDirect3DViewport3
,
993 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice3
, iface
);
994 IDirect3DViewportImpl
*vp
= ICOM_OBJECT(IDirect3DViewportImpl
, IDirect3DViewport3
, Viewport3
);
995 IDirect3DViewportImpl
*res
= NULL
;
997 TRACE("(%p)->(%p,%p,%08x)\n", This
, vp
, lplpDirect3DViewport3
, Flags
);
1001 *lplpDirect3DViewport3
= NULL
;
1002 return DDERR_INVALIDPARAMS
;
1006 EnterCriticalSection(&ddraw_cs
);
1016 res
= This
->viewport_list
;
1021 IDirect3DViewportImpl
*cur_viewport
= This
->viewport_list
;
1022 if (cur_viewport
!= NULL
)
1024 while (cur_viewport
->next
!= NULL
) cur_viewport
= cur_viewport
->next
;
1030 *lplpDirect3DViewport3
= NULL
;
1031 LeaveCriticalSection(&ddraw_cs
);
1032 return DDERR_INVALIDPARAMS
;
1035 *lplpDirect3DViewport3
= ICOM_INTERFACE(res
, IDirect3DViewport3
);
1036 LeaveCriticalSection(&ddraw_cs
);
1040 static HRESULT WINAPI
1041 Thunk_IDirect3DDeviceImpl_2_NextViewport(IDirect3DDevice2
*iface
,
1042 IDirect3DViewport2
*Viewport2
,
1043 IDirect3DViewport2
**lplpDirect3DViewport2
,
1046 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice2
, iface
);
1047 IDirect3DViewportImpl
*vp
= ICOM_OBJECT(IDirect3DViewportImpl
, IDirect3DViewport3
, Viewport2
);
1048 IDirect3DViewport3
*res
;
1050 TRACE_(ddraw_thunk
)("(%p)->(%p,%p,%08x) thunking to IDirect3DDevice3 interface.\n", This
, vp
, lplpDirect3DViewport2
, Flags
);
1051 hr
= IDirect3DDevice3_NextViewport(ICOM_INTERFACE(This
, IDirect3DDevice3
),
1052 ICOM_INTERFACE(vp
, IDirect3DViewport3
),
1055 *lplpDirect3DViewport2
= (IDirect3DViewport2
*) COM_INTERFACE_CAST(IDirect3DViewportImpl
, IDirect3DViewport3
, IDirect3DViewport3
, res
);
1059 static HRESULT WINAPI
1060 Thunk_IDirect3DDeviceImpl_1_NextViewport(IDirect3DDevice
*iface
,
1061 IDirect3DViewport
*Viewport
,
1062 IDirect3DViewport
**lplpDirect3DViewport
,
1065 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice
, iface
);
1066 IDirect3DViewportImpl
*vp
= ICOM_OBJECT(IDirect3DViewportImpl
, IDirect3DViewport3
, Viewport
);
1067 IDirect3DViewport3
*res
;
1069 TRACE_(ddraw_thunk
)("(%p)->(%p,%p,%08x) thunking to IDirect3DDevice3 interface.\n", This
, vp
, lplpDirect3DViewport
, Flags
);
1070 hr
= IDirect3DDevice3_NextViewport(ICOM_INTERFACE(This
, IDirect3DDevice3
),
1071 ICOM_INTERFACE(vp
, IDirect3DViewport3
),
1074 *lplpDirect3DViewport
= (IDirect3DViewport
*) COM_INTERFACE_CAST(IDirect3DViewportImpl
, IDirect3DViewport3
, IDirect3DViewport3
, res
);
1078 /*****************************************************************************
1079 * IDirect3DDevice::Pick
1081 * Executes an execute buffer without performing rendering. Instead, a
1082 * list of primitives that intersect with (x1,y1) of the passed rectangle
1083 * is created. IDirect3DDevice::GetPickRecords can be used to retrieve
1089 * ExecuteBuffer: Buffer to execute
1090 * Viewport: Viewport to use for execution
1091 * Flags: None are defined, according to the SDK
1092 * Rect: Specifies the coordinates to be picked. Only x1 and y2 are used,
1093 * x2 and y2 are ignored.
1096 * D3D_OK because it's a stub
1098 *****************************************************************************/
1099 static HRESULT WINAPI
1100 IDirect3DDeviceImpl_1_Pick(IDirect3DDevice
*iface
,
1101 IDirect3DExecuteBuffer
*ExecuteBuffer
,
1102 IDirect3DViewport
*Viewport
,
1106 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice
, iface
);
1107 IDirect3DExecuteBufferImpl
*execbuf
= ICOM_OBJECT(IDirect3DExecuteBufferImpl
, IDirect3DExecuteBuffer
, ExecuteBuffer
);
1108 IDirect3DViewportImpl
*vp
= ICOM_OBJECT(IDirect3DViewportImpl
, IDirect3DViewport3
, Viewport
);
1109 FIXME("(%p)->(%p,%p,%08x,%p): stub!\n", This
, execbuf
, vp
, Flags
, Rect
);
1114 /*****************************************************************************
1115 * IDirect3DDevice::GetPickRecords
1117 * Retrieves the pick records generated by IDirect3DDevice::GetPickRecords
1122 * Count: Pointer to a DWORD containing the numbers of pick records to
1124 * D3DPickRec: Address to store the resulting D3DPICKRECORD array.
1127 * D3D_OK, because it's a stub
1129 *****************************************************************************/
1130 static HRESULT WINAPI
1131 IDirect3DDeviceImpl_1_GetPickRecords(IDirect3DDevice
*iface
,
1133 D3DPICKRECORD
*D3DPickRec
)
1135 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice
, iface
);
1136 FIXME("(%p)->(%p,%p): stub!\n", This
, Count
, D3DPickRec
);
1141 /*****************************************************************************
1142 * IDirect3DDevice7::EnumTextureformats
1144 * Enumerates the supported texture formats. It has a list of all possible
1145 * formats and calls IWineD3D::CheckDeviceFormat for each format to see if
1146 * WineD3D supports it. If so, then it is passed to the app.
1148 * This is for Version 7 and 3, older versions have a different
1149 * callback function and their own implementation
1152 * Callback: Callback to call for each enumerated format
1153 * Arg: Argument to pass to the callback
1157 * DDERR_INVALIDPARAMS if Callback == NULL
1159 *****************************************************************************/
1161 IDirect3DDeviceImpl_7_EnumTextureFormats(IDirect3DDevice7
*iface
,
1162 LPD3DENUMPIXELFORMATSCALLBACK Callback
,
1165 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
1169 WINED3DFORMAT FormatList
[] = {
1171 WINED3DFMT_A8R8G8B8
,
1172 WINED3DFMT_X8R8G8B8
,
1176 WINED3DFMT_A1R5G5B5
,
1177 WINED3DFMT_A4R4G4B4
,
1179 WINED3DFMT_X1R5G5B5
,
1189 WINED3DFORMAT BumpFormatList
[] = {
1192 WINED3DFMT_X8L8V8U8
,
1193 WINED3DFMT_Q8W8V8U8
,
1195 WINED3DFMT_W11V11U10
,
1196 WINED3DFMT_A2W10V10U10
1199 TRACE("(%p)->(%p,%p): Relay\n", This
, Callback
, Arg
);
1202 return DDERR_INVALIDPARAMS
;
1204 EnterCriticalSection(&ddraw_cs
);
1205 for(i
= 0; i
< sizeof(FormatList
) / sizeof(WINED3DFORMAT
); i
++)
1207 hr
= IWineD3D_CheckDeviceFormat(This
->ddraw
->wineD3D
,
1210 0 /* AdapterFormat */,
1212 0 /* ResourceType */,
1217 DDPIXELFORMAT pformat
;
1219 memset(&pformat
, 0, sizeof(pformat
));
1220 pformat
.dwSize
= sizeof(pformat
);
1221 PixelFormat_WineD3DtoDD(&pformat
, FormatList
[i
]);
1223 TRACE("Enumerating WineD3DFormat %d\n", FormatList
[i
]);
1224 hr
= Callback(&pformat
, Arg
);
1225 if(hr
!= DDENUMRET_OK
)
1227 TRACE("Format enumeration cancelled by application\n");
1228 LeaveCriticalSection(&ddraw_cs
);
1234 for(i
= 0; i
< sizeof(BumpFormatList
) / sizeof(WINED3DFORMAT
); i
++)
1236 hr
= IWineD3D_CheckDeviceFormat(This
->ddraw
->wineD3D
,
1239 0 /* AdapterFormat */,
1240 WINED3DUSAGE_QUERY_LEGACYBUMPMAP
,
1241 0 /* ResourceType */,
1246 DDPIXELFORMAT pformat
;
1248 memset(&pformat
, 0, sizeof(pformat
));
1249 pformat
.dwSize
= sizeof(pformat
);
1250 PixelFormat_WineD3DtoDD(&pformat
, BumpFormatList
[i
]);
1252 TRACE("Enumerating WineD3DFormat %d\n", BumpFormatList
[i
]);
1253 hr
= Callback(&pformat
, Arg
);
1254 if(hr
!= DDENUMRET_OK
)
1256 TRACE("Format enumeration cancelled by application\n");
1257 LeaveCriticalSection(&ddraw_cs
);
1262 TRACE("End of enumeration\n");
1263 LeaveCriticalSection(&ddraw_cs
);
1267 static HRESULT WINAPI
1268 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUSetup(IDirect3DDevice7
*iface
,
1269 LPD3DENUMPIXELFORMATSCALLBACK Callback
,
1272 return IDirect3DDeviceImpl_7_EnumTextureFormats(iface
, Callback
, Arg
);
1275 static HRESULT WINAPI
1276 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUPreserve(IDirect3DDevice7
*iface
,
1277 LPD3DENUMPIXELFORMATSCALLBACK Callback
,
1283 old_fpucw
= d3d_fpu_setup();
1284 hr
= IDirect3DDeviceImpl_7_EnumTextureFormats(iface
, Callback
, Arg
);
1285 set_fpu_control_word(old_fpucw
);
1290 static HRESULT WINAPI
1291 Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats(IDirect3DDevice3
*iface
,
1292 LPD3DENUMPIXELFORMATSCALLBACK Callback
,
1295 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice3
, iface
);
1296 TRACE_(ddraw_thunk
)("(%p)->(%p,%p) thunking to IDirect3DDevice7 interface.\n", This
, Callback
, Arg
);
1297 return IDirect3DDevice7_EnumTextureFormats(ICOM_INTERFACE(This
, IDirect3DDevice7
),
1302 /*****************************************************************************
1303 * IDirect3DDevice2::EnumTextureformats
1305 * EnumTextureFormats for Version 1 and 2, see
1306 * IDirect3DDevice7::EnumTexureFormats for a more detailed description.
1308 * This version has a different callback and does not enumerate FourCC
1311 *****************************************************************************/
1312 static HRESULT WINAPI
1313 IDirect3DDeviceImpl_2_EnumTextureFormats(IDirect3DDevice2
*iface
,
1314 LPD3DENUMTEXTUREFORMATSCALLBACK Callback
,
1317 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice2
, iface
);
1321 WINED3DFORMAT FormatList
[] = {
1323 WINED3DFMT_A8R8G8B8
,
1324 WINED3DFMT_X8R8G8B8
,
1328 WINED3DFMT_A1R5G5B5
,
1329 WINED3DFMT_A4R4G4B4
,
1331 WINED3DFMT_X1R5G5B5
,
1335 /* FOURCC codes - Not in this version*/
1338 TRACE("(%p)->(%p,%p): Relay\n", This
, Callback
, Arg
);
1341 return DDERR_INVALIDPARAMS
;
1343 EnterCriticalSection(&ddraw_cs
);
1344 for(i
= 0; i
< sizeof(FormatList
) / sizeof(WINED3DFORMAT
); i
++)
1346 hr
= IWineD3D_CheckDeviceFormat(This
->ddraw
->wineD3D
,
1349 0 /* AdapterFormat */,
1351 0 /* ResourceType */,
1356 DDSURFACEDESC sdesc
;
1358 memset(&sdesc
, 0, sizeof(sdesc
));
1359 sdesc
.dwSize
= sizeof(sdesc
);
1360 sdesc
.dwFlags
= DDSD_PIXELFORMAT
| DDSD_CAPS
;
1361 sdesc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1362 sdesc
.ddpfPixelFormat
.dwSize
= sizeof(sdesc
.ddpfPixelFormat
);
1363 PixelFormat_WineD3DtoDD(&sdesc
.ddpfPixelFormat
, FormatList
[i
]);
1365 TRACE("Enumerating WineD3DFormat %d\n", FormatList
[i
]);
1366 hr
= Callback(&sdesc
, Arg
);
1367 if(hr
!= DDENUMRET_OK
)
1369 TRACE("Format enumeration cancelled by application\n");
1370 LeaveCriticalSection(&ddraw_cs
);
1375 TRACE("End of enumeration\n");
1376 LeaveCriticalSection(&ddraw_cs
);
1380 static HRESULT WINAPI
1381 Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats(IDirect3DDevice
*iface
,
1382 LPD3DENUMTEXTUREFORMATSCALLBACK Callback
,
1385 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice
, iface
);
1386 TRACE_(ddraw_thunk
)("(%p)->(%p,%p) thunking to IDirect3DDevice2 interface.\n", This
, Callback
, Arg
);
1387 return IDirect3DDevice2_EnumTextureFormats(ICOM_INTERFACE(This
, IDirect3DDevice2
),
1392 /*****************************************************************************
1393 * IDirect3DDevice::CreateMatrix
1395 * Creates a matrix handle. A handle is created and memory for a D3DMATRIX is
1396 * allocated for the handle.
1401 * D3DMatHandle: Address to return the handle at
1405 * DDERR_INVALIDPARAMS if D3DMatHandle = NULL
1407 *****************************************************************************/
1408 static HRESULT WINAPI
1409 IDirect3DDeviceImpl_1_CreateMatrix(IDirect3DDevice
*iface
, D3DMATRIXHANDLE
*D3DMatHandle
)
1411 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice
, iface
);
1413 TRACE("(%p)->(%p)\n", This
, D3DMatHandle
);
1416 return DDERR_INVALIDPARAMS
;
1418 Matrix
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(D3DMATRIX
));
1421 ERR("Out of memory when allocating a D3DMATRIX\n");
1422 return DDERR_OUTOFMEMORY
;
1425 EnterCriticalSection(&ddraw_cs
);
1426 *D3DMatHandle
= IDirect3DDeviceImpl_CreateHandle(This
);
1427 if(!(*D3DMatHandle
))
1429 ERR("Failed to create a matrix handle\n");
1430 HeapFree(GetProcessHeap(), 0, Matrix
);
1431 LeaveCriticalSection(&ddraw_cs
);
1432 return DDERR_OUTOFMEMORY
;
1434 This
->Handles
[*D3DMatHandle
- 1].ptr
= Matrix
;
1435 This
->Handles
[*D3DMatHandle
- 1].type
= DDrawHandle_Matrix
;
1436 TRACE(" returning matrix handle %d\n", *D3DMatHandle
);
1438 LeaveCriticalSection(&ddraw_cs
);
1442 /*****************************************************************************
1443 * IDirect3DDevice::SetMatrix
1445 * Sets a matrix for a matrix handle. The matrix is copied into the memory
1446 * allocated for the handle
1451 * D3DMatHandle: Handle to set the matrix to
1452 * D3DMatrix: Matrix to set
1456 * DDERR_INVALIDPARAMS if the handle of the matrix is invalid or the matrix
1459 *****************************************************************************/
1460 static HRESULT WINAPI
1461 IDirect3DDeviceImpl_1_SetMatrix(IDirect3DDevice
*iface
,
1462 D3DMATRIXHANDLE D3DMatHandle
,
1463 D3DMATRIX
*D3DMatrix
)
1465 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice
, iface
);
1466 TRACE("(%p)->(%08x,%p)\n", This
, D3DMatHandle
, D3DMatrix
);
1468 if( (!D3DMatHandle
) || (!D3DMatrix
) )
1469 return DDERR_INVALIDPARAMS
;
1471 EnterCriticalSection(&ddraw_cs
);
1472 if(D3DMatHandle
> This
->numHandles
)
1474 ERR("Handle %d out of range\n", D3DMatHandle
);
1475 LeaveCriticalSection(&ddraw_cs
);
1476 return DDERR_INVALIDPARAMS
;
1478 else if(This
->Handles
[D3DMatHandle
- 1].type
!= DDrawHandle_Matrix
)
1480 ERR("Handle %d is not a matrix handle\n", D3DMatHandle
);
1481 LeaveCriticalSection(&ddraw_cs
);
1482 return DDERR_INVALIDPARAMS
;
1486 dump_D3DMATRIX(D3DMatrix
);
1488 *((D3DMATRIX
*) This
->Handles
[D3DMatHandle
- 1].ptr
) = *D3DMatrix
;
1490 if(This
->world
== D3DMatHandle
)
1492 IWineD3DDevice_SetTransform(This
->wineD3DDevice
,
1493 WINED3DTS_WORLDMATRIX(0),
1494 (WINED3DMATRIX
*) D3DMatrix
);
1496 if(This
->view
== D3DMatHandle
)
1498 IWineD3DDevice_SetTransform(This
->wineD3DDevice
,
1500 (WINED3DMATRIX
*) D3DMatrix
);
1502 if(This
->proj
== D3DMatHandle
)
1504 IWineD3DDevice_SetTransform(This
->wineD3DDevice
,
1505 WINED3DTS_PROJECTION
,
1506 (WINED3DMATRIX
*) D3DMatrix
);
1509 LeaveCriticalSection(&ddraw_cs
);
1513 /*****************************************************************************
1514 * IDirect3DDevice::SetMatrix
1516 * Returns the content of a D3DMATRIX handle
1521 * D3DMatHandle: Matrix handle to read the content from
1522 * D3DMatrix: Address to store the content at
1526 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid or D3DMatrix is NULL
1528 *****************************************************************************/
1529 static HRESULT WINAPI
1530 IDirect3DDeviceImpl_1_GetMatrix(IDirect3DDevice
*iface
,
1531 D3DMATRIXHANDLE D3DMatHandle
,
1532 D3DMATRIX
*D3DMatrix
)
1534 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice
, iface
);
1535 TRACE("(%p)->(%08x,%p)\n", This
, D3DMatHandle
, D3DMatrix
);
1538 return DDERR_INVALIDPARAMS
;
1540 return DDERR_INVALIDPARAMS
;
1542 EnterCriticalSection(&ddraw_cs
);
1543 if(D3DMatHandle
> This
->numHandles
)
1545 ERR("Handle %d out of range\n", D3DMatHandle
);
1546 LeaveCriticalSection(&ddraw_cs
);
1547 return DDERR_INVALIDPARAMS
;
1549 else if(This
->Handles
[D3DMatHandle
- 1].type
!= DDrawHandle_Matrix
)
1551 ERR("Handle %d is not a matrix handle\n", D3DMatHandle
);
1552 LeaveCriticalSection(&ddraw_cs
);
1553 return DDERR_INVALIDPARAMS
;
1556 /* The handle is simply a pointer to a D3DMATRIX structure */
1557 *D3DMatrix
= *((D3DMATRIX
*) This
->Handles
[D3DMatHandle
- 1].ptr
);
1559 LeaveCriticalSection(&ddraw_cs
);
1563 /*****************************************************************************
1564 * IDirect3DDevice::DeleteMatrix
1566 * Destroys a Matrix handle. Frees the memory and unsets the handle data
1571 * D3DMatHandle: Handle to destroy
1575 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid
1577 *****************************************************************************/
1578 static HRESULT WINAPI
1579 IDirect3DDeviceImpl_1_DeleteMatrix(IDirect3DDevice
*iface
,
1580 D3DMATRIXHANDLE D3DMatHandle
)
1582 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice
, iface
);
1583 TRACE("(%p)->(%08x)\n", This
, D3DMatHandle
);
1586 return DDERR_INVALIDPARAMS
;
1588 EnterCriticalSection(&ddraw_cs
);
1589 if(D3DMatHandle
> This
->numHandles
)
1591 ERR("Handle %d out of range\n", D3DMatHandle
);
1592 LeaveCriticalSection(&ddraw_cs
);
1593 return DDERR_INVALIDPARAMS
;
1595 else if(This
->Handles
[D3DMatHandle
- 1].type
!= DDrawHandle_Matrix
)
1597 ERR("Handle %d is not a matrix handle\n", D3DMatHandle
);
1598 LeaveCriticalSection(&ddraw_cs
);
1599 return DDERR_INVALIDPARAMS
;
1602 HeapFree(GetProcessHeap(), 0, This
->Handles
[D3DMatHandle
- 1].ptr
);
1603 This
->Handles
[D3DMatHandle
- 1].ptr
= NULL
;
1604 This
->Handles
[D3DMatHandle
- 1].type
= DDrawHandle_Unknown
;
1606 LeaveCriticalSection(&ddraw_cs
);
1610 /*****************************************************************************
1611 * IDirect3DDevice7::BeginScene
1613 * This method must be called before any rendering is performed.
1614 * IDirect3DDevice::EndScene has to be called after the scene is complete
1616 * Version 1, 2, 3 and 7
1619 * D3D_OK on success, for details see IWineD3DDevice::BeginScene
1620 * D3DERR_SCENE_IN_SCENE if WineD3D returns an error(Only in case of an already
1623 *****************************************************************************/
1625 IDirect3DDeviceImpl_7_BeginScene(IDirect3DDevice7
*iface
)
1627 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
1629 TRACE("(%p): Relay\n", This
);
1631 EnterCriticalSection(&ddraw_cs
);
1632 hr
= IWineD3DDevice_BeginScene(This
->wineD3DDevice
);
1633 LeaveCriticalSection(&ddraw_cs
);
1634 if(hr
== WINED3D_OK
) return D3D_OK
;
1635 else return D3DERR_SCENE_IN_SCENE
; /* TODO: Other possible causes of failure */
1638 static HRESULT WINAPI
1639 IDirect3DDeviceImpl_7_BeginScene_FPUSetup(IDirect3DDevice7
*iface
)
1641 return IDirect3DDeviceImpl_7_BeginScene(iface
);
1644 static HRESULT WINAPI
1645 IDirect3DDeviceImpl_7_BeginScene_FPUPreserve(IDirect3DDevice7
*iface
)
1650 old_fpucw
= d3d_fpu_setup();
1651 hr
= IDirect3DDeviceImpl_7_BeginScene(iface
);
1652 set_fpu_control_word(old_fpucw
);
1657 static HRESULT WINAPI
1658 Thunk_IDirect3DDeviceImpl_3_BeginScene(IDirect3DDevice3
*iface
)
1660 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice3
, iface
);
1661 TRACE_(ddraw_thunk
)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This
);
1662 return IDirect3DDevice7_BeginScene(ICOM_INTERFACE(This
, IDirect3DDevice7
));
1665 static HRESULT WINAPI
1666 Thunk_IDirect3DDeviceImpl_2_BeginScene(IDirect3DDevice2
*iface
)
1668 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice2
, iface
);
1669 TRACE_(ddraw_thunk
)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This
);
1670 return IDirect3DDevice7_BeginScene(ICOM_INTERFACE(This
, IDirect3DDevice7
));
1673 static HRESULT WINAPI
1674 Thunk_IDirect3DDeviceImpl_1_BeginScene(IDirect3DDevice
*iface
)
1676 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice
, iface
);
1677 TRACE_(ddraw_thunk
)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This
);
1678 return IDirect3DDevice7_BeginScene(ICOM_INTERFACE(This
, IDirect3DDevice7
));
1681 /*****************************************************************************
1682 * IDirect3DDevice7::EndScene
1684 * Ends a scene that has been begun with IDirect3DDevice7::BeginScene.
1685 * This method must be called after rendering is finished.
1687 * Version 1, 2, 3 and 7
1690 * D3D_OK on success, for details see IWineD3DDevice::EndScene
1691 * D3DERR_SCENE_NOT_IN_SCENE is returned if WineD3D returns an error. It does
1692 * that only if the scene was already ended.
1694 *****************************************************************************/
1696 IDirect3DDeviceImpl_7_EndScene(IDirect3DDevice7
*iface
)
1698 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
1700 TRACE("(%p): Relay\n", This
);
1702 EnterCriticalSection(&ddraw_cs
);
1703 hr
= IWineD3DDevice_EndScene(This
->wineD3DDevice
);
1704 LeaveCriticalSection(&ddraw_cs
);
1705 if(hr
== WINED3D_OK
) return D3D_OK
;
1706 else return D3DERR_SCENE_NOT_IN_SCENE
;
1709 static HRESULT WINAPI
1710 IDirect3DDeviceImpl_7_EndScene_FPUSetup(IDirect3DDevice7
*iface
)
1712 return IDirect3DDeviceImpl_7_EndScene(iface
);
1715 static HRESULT WINAPI
1716 IDirect3DDeviceImpl_7_EndScene_FPUPreserve(IDirect3DDevice7
*iface
)
1721 old_fpucw
= d3d_fpu_setup();
1722 hr
= IDirect3DDeviceImpl_7_EndScene(iface
);
1723 set_fpu_control_word(old_fpucw
);
1728 static HRESULT WINAPI
1729 Thunk_IDirect3DDeviceImpl_3_EndScene(IDirect3DDevice3
*iface
)
1731 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice3
, iface
);
1732 TRACE_(ddraw_thunk
)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This
);
1733 return IDirect3DDevice7_EndScene(ICOM_INTERFACE(This
, IDirect3DDevice7
));
1736 static HRESULT WINAPI
1737 Thunk_IDirect3DDeviceImpl_2_EndScene(IDirect3DDevice2
*iface
)
1739 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice2
, iface
);
1740 TRACE_(ddraw_thunk
)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This
);
1741 return IDirect3DDevice7_EndScene(ICOM_INTERFACE(This
, IDirect3DDevice7
));
1744 static HRESULT WINAPI
1745 Thunk_IDirect3DDeviceImpl_1_EndScene(IDirect3DDevice
*iface
)
1747 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice
, iface
);
1748 TRACE_(ddraw_thunk
)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This
);
1749 return IDirect3DDevice7_EndScene(ICOM_INTERFACE(This
, IDirect3DDevice7
));
1752 /*****************************************************************************
1753 * IDirect3DDevice7::GetDirect3D
1755 * Returns the IDirect3D(= interface to the DirectDraw object) used to create
1759 * Direct3D7: Address to store the interface pointer at
1763 * DDERR_INVALIDPARAMS if Direct3D7 == NULL
1765 *****************************************************************************/
1766 static HRESULT WINAPI
1767 IDirect3DDeviceImpl_7_GetDirect3D(IDirect3DDevice7
*iface
,
1768 IDirect3D7
**Direct3D7
)
1770 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
1771 TRACE("(%p)->(%p)\n", This
, Direct3D7
);
1774 return DDERR_INVALIDPARAMS
;
1776 *Direct3D7
= ICOM_INTERFACE(This
->ddraw
, IDirect3D7
);
1777 IDirect3D7_AddRef(*Direct3D7
);
1779 TRACE(" returning interface %p\n", *Direct3D7
);
1783 static HRESULT WINAPI
1784 Thunk_IDirect3DDeviceImpl_3_GetDirect3D(IDirect3DDevice3
*iface
,
1785 IDirect3D3
**Direct3D3
)
1787 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice3
, iface
);
1789 IDirect3D7
*ret_ptr
;
1791 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This
, Direct3D3
);
1792 ret
= IDirect3DDevice7_GetDirect3D(ICOM_INTERFACE(This
, IDirect3DDevice7
),
1796 *Direct3D3
= COM_INTERFACE_CAST(IDirectDrawImpl
, IDirect3D7
, IDirect3D3
, ret_ptr
);
1797 TRACE(" returning interface %p\n", *Direct3D3
);
1801 static HRESULT WINAPI
1802 Thunk_IDirect3DDeviceImpl_2_GetDirect3D(IDirect3DDevice2
*iface
,
1803 IDirect3D2
**Direct3D2
)
1805 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice2
, iface
);
1807 IDirect3D7
*ret_ptr
;
1809 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This
, Direct3D2
);
1810 ret
= IDirect3DDevice7_GetDirect3D(ICOM_INTERFACE(This
, IDirect3DDevice7
),
1814 *Direct3D2
= COM_INTERFACE_CAST(IDirectDrawImpl
, IDirect3D7
, IDirect3D2
, ret_ptr
);
1815 TRACE(" returning interface %p\n", *Direct3D2
);
1819 static HRESULT WINAPI
1820 Thunk_IDirect3DDeviceImpl_1_GetDirect3D(IDirect3DDevice
*iface
,
1821 IDirect3D
**Direct3D
)
1823 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice
, iface
);
1825 IDirect3D7
*ret_ptr
;
1827 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This
, Direct3D
);
1828 ret
= IDirect3DDevice7_GetDirect3D(ICOM_INTERFACE(This
, IDirect3DDevice7
),
1832 *Direct3D
= COM_INTERFACE_CAST(IDirectDrawImpl
, IDirect3D7
, IDirect3D
, ret_ptr
);
1833 TRACE(" returning interface %p\n", *Direct3D
);
1837 /*****************************************************************************
1838 * IDirect3DDevice3::SetCurrentViewport
1840 * Sets a Direct3DViewport as the current viewport.
1841 * For the thunks note that all viewport interface versions are equal
1844 * Direct3DViewport3: The viewport to set
1850 * (Is a NULL viewport valid?)
1852 *****************************************************************************/
1853 static HRESULT WINAPI
1854 IDirect3DDeviceImpl_3_SetCurrentViewport(IDirect3DDevice3
*iface
,
1855 IDirect3DViewport3
*Direct3DViewport3
)
1857 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice3
, iface
);
1858 IDirect3DViewportImpl
*vp
= ICOM_OBJECT(IDirect3DViewportImpl
, IDirect3DViewport3
, Direct3DViewport3
);
1859 TRACE("(%p)->(%p)\n", This
, Direct3DViewport3
);
1861 EnterCriticalSection(&ddraw_cs
);
1862 /* Do nothing if the specified viewport is the same as the current one */
1863 if (This
->current_viewport
== vp
)
1865 LeaveCriticalSection(&ddraw_cs
);
1869 /* Should check if the viewport was added or not */
1871 /* Release previous viewport and AddRef the new one */
1872 if (This
->current_viewport
)
1874 TRACE("ViewportImpl is at %p, interface is at %p\n", This
->current_viewport
, ICOM_INTERFACE(This
->current_viewport
, IDirect3DViewport3
));
1875 IDirect3DViewport3_Release( ICOM_INTERFACE(This
->current_viewport
, IDirect3DViewport3
) );
1877 IDirect3DViewport3_AddRef(Direct3DViewport3
);
1879 /* Set this viewport as the current viewport */
1880 This
->current_viewport
= vp
;
1882 /* Activate this viewport */
1883 This
->current_viewport
->active_device
= This
;
1884 This
->current_viewport
->activate(This
->current_viewport
, FALSE
);
1886 LeaveCriticalSection(&ddraw_cs
);
1890 static HRESULT WINAPI
1891 Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport(IDirect3DDevice2
*iface
,
1892 IDirect3DViewport2
*Direct3DViewport2
)
1894 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice2
, iface
);
1895 IDirect3DViewportImpl
*vp
= ICOM_OBJECT(IDirect3DViewportImpl
, IDirect3DViewport3
, Direct3DViewport2
);
1896 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This
, vp
);
1897 return IDirect3DDevice3_SetCurrentViewport(ICOM_INTERFACE(This
, IDirect3DDevice3
),
1898 ICOM_INTERFACE(vp
, IDirect3DViewport3
));
1901 /*****************************************************************************
1902 * IDirect3DDevice3::GetCurrentViewport
1904 * Returns the currently active viewport.
1909 * Direct3DViewport3: Address to return the interface pointer at
1913 * DDERR_INVALIDPARAMS if Direct3DViewport == NULL
1915 *****************************************************************************/
1916 static HRESULT WINAPI
1917 IDirect3DDeviceImpl_3_GetCurrentViewport(IDirect3DDevice3
*iface
,
1918 IDirect3DViewport3
**Direct3DViewport3
)
1920 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice3
, iface
);
1921 TRACE("(%p)->(%p)\n", This
, Direct3DViewport3
);
1923 if(!Direct3DViewport3
)
1924 return DDERR_INVALIDPARAMS
;
1926 EnterCriticalSection(&ddraw_cs
);
1927 *Direct3DViewport3
= ICOM_INTERFACE(This
->current_viewport
, IDirect3DViewport3
);
1929 /* AddRef the returned viewport */
1930 if(*Direct3DViewport3
) IDirect3DViewport3_AddRef(*Direct3DViewport3
);
1932 TRACE(" returning interface %p\n", *Direct3DViewport3
);
1934 LeaveCriticalSection(&ddraw_cs
);
1938 static HRESULT WINAPI
1939 Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport(IDirect3DDevice2
*iface
,
1940 IDirect3DViewport2
**Direct3DViewport2
)
1942 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice3
, iface
);
1944 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This
, Direct3DViewport2
);
1945 hr
= IDirect3DDevice3_GetCurrentViewport(ICOM_INTERFACE(This
, IDirect3DDevice3
),
1946 (IDirect3DViewport3
**) Direct3DViewport2
);
1947 if(hr
!= D3D_OK
) return hr
;
1948 *Direct3DViewport2
= (IDirect3DViewport2
*) COM_INTERFACE_CAST(IDirect3DViewportImpl
, IDirect3DViewport3
, IDirect3DViewport3
, *Direct3DViewport2
);
1952 /*****************************************************************************
1953 * IDirect3DDevice7::SetRenderTarget
1955 * Sets the render target for the Direct3DDevice.
1956 * For the thunks note that IDirectDrawSurface7 == IDirectDrawSurface4 and
1957 * IDirectDrawSurface3 == IDirectDrawSurface
1959 * Version 2, 3 and 7
1962 * NewTarget: Pointer to an IDirectDrawSurface7 interface to set as the new
1967 * D3D_OK on success, for details see IWineD3DDevice::SetRenderTarget
1969 *****************************************************************************/
1971 IDirect3DDeviceImpl_7_SetRenderTarget(IDirect3DDevice7
*iface
,
1972 IDirectDrawSurface7
*NewTarget
,
1975 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
1976 IDirectDrawSurfaceImpl
*Target
= ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, NewTarget
);
1978 TRACE("(%p)->(%p,%08x): Relay\n", This
, NewTarget
, Flags
);
1980 EnterCriticalSection(&ddraw_cs
);
1981 /* Flags: Not used */
1983 if(This
->target
== Target
)
1985 TRACE("No-op SetRenderTarget operation, not doing anything\n");
1986 LeaveCriticalSection(&ddraw_cs
);
1990 hr
= IWineD3DDevice_SetRenderTarget(This
->wineD3DDevice
,
1992 Target
? Target
->WineD3DSurface
: NULL
);
1995 LeaveCriticalSection(&ddraw_cs
);
1998 IDirectDrawSurface7_AddRef(NewTarget
);
1999 IDirectDrawSurface7_Release(ICOM_INTERFACE(This
->target
, IDirectDrawSurface7
));
2000 This
->target
= Target
;
2001 IDirect3DDeviceImpl_UpdateDepthStencil(This
);
2002 LeaveCriticalSection(&ddraw_cs
);
2006 static HRESULT WINAPI
2007 IDirect3DDeviceImpl_7_SetRenderTarget_FPUSetup(IDirect3DDevice7
*iface
,
2008 IDirectDrawSurface7
*NewTarget
,
2011 return IDirect3DDeviceImpl_7_SetRenderTarget(iface
, NewTarget
, Flags
);
2014 static HRESULT WINAPI
2015 IDirect3DDeviceImpl_7_SetRenderTarget_FPUPreserve(IDirect3DDevice7
*iface
,
2016 IDirectDrawSurface7
*NewTarget
,
2022 old_fpucw
= d3d_fpu_setup();
2023 hr
= IDirect3DDeviceImpl_7_SetRenderTarget(iface
, NewTarget
, Flags
);
2024 set_fpu_control_word(old_fpucw
);
2029 static HRESULT WINAPI
2030 Thunk_IDirect3DDeviceImpl_3_SetRenderTarget(IDirect3DDevice3
*iface
,
2031 IDirectDrawSurface4
*NewRenderTarget
,
2034 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice3
, iface
);
2035 IDirectDrawSurfaceImpl
*Target
= ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, NewRenderTarget
);
2036 TRACE_(ddraw_thunk
)("(%p)->(%p,%08x) thunking to IDirect3DDevice7 interface.\n", This
, Target
, Flags
);
2037 return IDirect3DDevice7_SetRenderTarget(ICOM_INTERFACE(This
, IDirect3DDevice7
),
2038 ICOM_INTERFACE(Target
, IDirectDrawSurface7
),
2042 static HRESULT WINAPI
2043 Thunk_IDirect3DDeviceImpl_2_SetRenderTarget(IDirect3DDevice2
*iface
,
2044 IDirectDrawSurface
*NewRenderTarget
,
2047 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice2
, iface
);
2048 IDirectDrawSurfaceImpl
*Target
= ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirectDrawSurface3
, NewRenderTarget
);
2049 TRACE_(ddraw_thunk
)("(%p)->(%p,%08x) thunking to IDirect3DDevice7 interface.\n", This
, Target
, Flags
);
2050 return IDirect3DDevice7_SetRenderTarget(ICOM_INTERFACE(This
, IDirect3DDevice7
),
2051 ICOM_INTERFACE(Target
, IDirectDrawSurface7
),
2055 /*****************************************************************************
2056 * IDirect3DDevice7::GetRenderTarget
2058 * Returns the current render target.
2059 * This is handled locally, because the WineD3D render target's parent
2062 * Version 2, 3 and 7
2065 * RenderTarget: Address to store the surface interface pointer
2069 * DDERR_INVALIDPARAMS if RenderTarget == NULL
2071 *****************************************************************************/
2072 static HRESULT WINAPI
2073 IDirect3DDeviceImpl_7_GetRenderTarget(IDirect3DDevice7
*iface
,
2074 IDirectDrawSurface7
**RenderTarget
)
2076 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
2077 TRACE("(%p)->(%p): Relay\n", This
, RenderTarget
);
2080 return DDERR_INVALIDPARAMS
;
2082 EnterCriticalSection(&ddraw_cs
);
2083 *RenderTarget
= ICOM_INTERFACE(This
->target
, IDirectDrawSurface7
);
2084 IDirectDrawSurface7_AddRef(*RenderTarget
);
2086 LeaveCriticalSection(&ddraw_cs
);
2090 static HRESULT WINAPI
2091 Thunk_IDirect3DDeviceImpl_3_GetRenderTarget(IDirect3DDevice3
*iface
,
2092 IDirectDrawSurface4
**RenderTarget
)
2094 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice3
, iface
);
2096 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This
, RenderTarget
);
2097 hr
= IDirect3DDevice7_GetRenderTarget(ICOM_INTERFACE(This
, IDirect3DDevice7
),
2098 (IDirectDrawSurface7
**) RenderTarget
);
2099 if(hr
!= D3D_OK
) return hr
;
2100 *RenderTarget
= (IDirectDrawSurface4
*) COM_INTERFACE_CAST(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, IDirectDrawSurface7
, *RenderTarget
);
2104 static HRESULT WINAPI
2105 Thunk_IDirect3DDeviceImpl_2_GetRenderTarget(IDirect3DDevice2
*iface
,
2106 IDirectDrawSurface
**RenderTarget
)
2108 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice2
, iface
);
2110 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This
, RenderTarget
);
2111 hr
= IDirect3DDevice7_GetRenderTarget(ICOM_INTERFACE(This
, IDirect3DDevice7
),
2112 (IDirectDrawSurface7
**) RenderTarget
);
2113 if(hr
!= D3D_OK
) return hr
;
2114 *RenderTarget
= (IDirectDrawSurface
*) COM_INTERFACE_CAST(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, IDirectDrawSurface3
, *RenderTarget
);
2118 /*****************************************************************************
2119 * IDirect3DDevice3::Begin
2121 * Begins a description block of vertices. This is similar to glBegin()
2122 * and glEnd(). After a call to IDirect3DDevice3::End, the vertices
2123 * described with IDirect3DDevice::Vertex are drawn.
2128 * PrimitiveType: The type of primitives to draw
2129 * VertexTypeDesc: A flexible vertex format description of the vertices
2130 * Flags: Some flags..
2135 *****************************************************************************/
2136 static HRESULT WINAPI
2137 IDirect3DDeviceImpl_3_Begin(IDirect3DDevice3
*iface
,
2138 D3DPRIMITIVETYPE PrimitiveType
,
2139 DWORD VertexTypeDesc
,
2142 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice3
, iface
);
2143 TRACE("(%p)->(%d,%d,%08x)\n", This
, PrimitiveType
, VertexTypeDesc
, Flags
);
2145 EnterCriticalSection(&ddraw_cs
);
2146 This
->primitive_type
= PrimitiveType
;
2147 This
->vertex_type
= VertexTypeDesc
;
2148 This
->render_flags
= Flags
;
2149 This
->vertex_size
= get_flexible_vertex_size(This
->vertex_type
);
2150 This
->nb_vertices
= 0;
2151 LeaveCriticalSection(&ddraw_cs
);
2156 static HRESULT WINAPI
2157 Thunk_IDirect3DDeviceImpl_2_Begin(IDirect3DDevice2
*iface
,
2158 D3DPRIMITIVETYPE d3dpt
,
2159 D3DVERTEXTYPE dwVertexTypeDesc
,
2163 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice2
, iface
);
2164 TRACE_(ddraw_thunk
)("(%p/%p)->(%08x,%08x,%08x): Thunking to IDirect3DDevice3\n", This
, iface
, d3dpt
, dwVertexTypeDesc
, dwFlags
);
2166 switch(dwVertexTypeDesc
)
2168 case D3DVT_VERTEX
: FVF
= D3DFVF_VERTEX
; break;
2169 case D3DVT_LVERTEX
: FVF
= D3DFVF_LVERTEX
; break;
2170 case D3DVT_TLVERTEX
: FVF
= D3DFVF_TLVERTEX
; break;
2172 ERR("Unexpected vertex type %d\n", dwVertexTypeDesc
);
2173 return DDERR_INVALIDPARAMS
; /* Should never happen */
2176 return IDirect3DDevice3_Begin(ICOM_INTERFACE(This
, IDirect3DDevice3
),
2182 /*****************************************************************************
2183 * IDirect3DDevice3::BeginIndexed
2185 * Draws primitives based on vertices in a vertex array which are specified
2191 * PrimitiveType: Primitive type to draw
2192 * VertexType: A FVF description of the vertex format
2193 * Vertices: pointer to an array containing the vertices
2194 * NumVertices: The number of vertices in the vertex array
2195 * Flags: Some flags ...
2198 * D3D_OK, because it's a stub
2200 *****************************************************************************/
2201 static HRESULT WINAPI
2202 IDirect3DDeviceImpl_3_BeginIndexed(IDirect3DDevice3
*iface
,
2203 D3DPRIMITIVETYPE PrimitiveType
,
2209 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice3
, iface
);
2210 FIXME("(%p)->(%08x,%08x,%p,%08x,%08x): stub!\n", This
, PrimitiveType
, VertexType
, Vertices
, NumVertices
, Flags
);
2215 static HRESULT WINAPI
2216 Thunk_IDirect3DDeviceImpl_2_BeginIndexed(IDirect3DDevice2
*iface
,
2217 D3DPRIMITIVETYPE d3dptPrimitiveType
,
2218 D3DVERTEXTYPE d3dvtVertexType
,
2220 DWORD dwNumVertices
,
2224 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice2
, iface
);
2225 TRACE_(ddraw_thunk
)("(%p/%p)->(%08x,%08x,%p,%08x,%08x): Thunking to IDirect3DDevice3\n", This
, iface
, d3dptPrimitiveType
, d3dvtVertexType
, lpvVertices
, dwNumVertices
, dwFlags
);
2227 switch(d3dvtVertexType
)
2229 case D3DVT_VERTEX
: FVF
= D3DFVF_VERTEX
; break;
2230 case D3DVT_LVERTEX
: FVF
= D3DFVF_LVERTEX
; break;
2231 case D3DVT_TLVERTEX
: FVF
= D3DFVF_TLVERTEX
; break;
2233 ERR("Unexpected vertex type %d\n", d3dvtVertexType
);
2234 return DDERR_INVALIDPARAMS
; /* Should never happen */
2237 return IDirect3DDevice3_BeginIndexed(ICOM_INTERFACE(This
,IDirect3DDevice3
),
2245 /*****************************************************************************
2246 * IDirect3DDevice3::Vertex
2248 * Draws a vertex as described by IDirect3DDevice3::Begin. It places all
2249 * drawn vertices in a vertex buffer. If the buffer is too small, its
2250 * size is increased.
2255 * Vertex: Pointer to the vertex
2258 * D3D_OK, on success
2259 * DDERR_INVALIDPARAMS if Vertex is NULL
2261 *****************************************************************************/
2262 static HRESULT WINAPI
2263 IDirect3DDeviceImpl_3_Vertex(IDirect3DDevice3
*iface
,
2266 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice3
, iface
);
2267 TRACE("(%p)->(%p)\n", This
, Vertex
);
2270 return DDERR_INVALIDPARAMS
;
2272 EnterCriticalSection(&ddraw_cs
);
2273 if ((This
->nb_vertices
+1)*This
->vertex_size
> This
->buffer_size
)
2276 This
->buffer_size
= This
->buffer_size
? This
->buffer_size
* 2 : This
->vertex_size
* 3;
2277 old_buffer
= This
->vertex_buffer
;
2278 This
->vertex_buffer
= HeapAlloc(GetProcessHeap(), 0, This
->buffer_size
);
2281 CopyMemory(This
->vertex_buffer
, old_buffer
, This
->nb_vertices
* This
->vertex_size
);
2282 HeapFree(GetProcessHeap(), 0, old_buffer
);
2286 CopyMemory(This
->vertex_buffer
+ This
->nb_vertices
++ * This
->vertex_size
, Vertex
, This
->vertex_size
);
2288 LeaveCriticalSection(&ddraw_cs
);
2292 static HRESULT WINAPI
2293 Thunk_IDirect3DDeviceImpl_2_Vertex(IDirect3DDevice2
*iface
,
2296 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice2
, iface
);
2297 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This
, lpVertexType
);
2298 return IDirect3DDevice3_Vertex(ICOM_INTERFACE(This
, IDirect3DDevice3
),
2302 /*****************************************************************************
2303 * IDirect3DDevice3::Index
2305 * Specifies an index to a vertex to be drawn. The vertex array has to
2306 * be specified with BeginIndexed first.
2309 * VertexIndex: The index of the vertex to draw
2312 * D3D_OK because it's a stub
2314 *****************************************************************************/
2315 static HRESULT WINAPI
2316 IDirect3DDeviceImpl_3_Index(IDirect3DDevice3
*iface
,
2319 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice3
, iface
);
2320 FIXME("(%p)->(%04x): stub!\n", This
, VertexIndex
);
2324 static HRESULT WINAPI
2325 Thunk_IDirect3DDeviceImpl_2_Index(IDirect3DDevice2
*iface
,
2328 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice2
, iface
);
2329 TRACE_(ddraw_thunk
)("(%p)->(%04x) thunking to IDirect3DDevice3 interface.\n", This
, wVertexIndex
);
2330 return IDirect3DDevice3_Index(ICOM_INTERFACE(This
, IDirect3DDevice3
),
2334 /*****************************************************************************
2335 * IDirect3DDevice3::End
2337 * Ends a draw begun with IDirect3DDevice3::Begin or
2338 * IDirect3DDevice::BeginIndexed. The vertices specified with
2339 * IDirect3DDevice::Vertex or IDirect3DDevice::Index are drawn using
2340 * the IDirect3DDevice7::DrawPrimitive method. So far only
2341 * non-indexed mode is supported
2346 * Flags: Some flags, as usual. Don't know which are defined
2349 * The return value of IDirect3DDevice7::DrawPrimitive
2351 *****************************************************************************/
2352 static HRESULT WINAPI
2353 IDirect3DDeviceImpl_3_End(IDirect3DDevice3
*iface
,
2356 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice3
, iface
);
2357 TRACE("(%p)->(%08x)\n", This
, Flags
);
2359 return IDirect3DDevice7_DrawPrimitive(ICOM_INTERFACE(This
, IDirect3DDevice7
),
2360 This
->primitive_type
, This
->vertex_type
,
2361 This
->vertex_buffer
, This
->nb_vertices
,
2362 This
->render_flags
);
2365 static HRESULT WINAPI
2366 Thunk_IDirect3DDeviceImpl_2_End(IDirect3DDevice2
*iface
,
2369 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice2
, iface
);
2370 TRACE_(ddraw_thunk
)("(%p)->(%08x) thunking to IDirect3DDevice3 interface.\n", This
, dwFlags
);
2371 return IDirect3DDevice3_End(ICOM_INTERFACE(This
, IDirect3DDevice3
),
2375 /*****************************************************************************
2376 * IDirect3DDevice7::GetRenderState
2378 * Returns the value of a render state. The possible render states are
2379 * defined in include/d3dtypes.h
2381 * Version 2, 3 and 7
2384 * RenderStateType: Render state to return the current setting of
2385 * Value: Address to store the value at
2388 * D3D_OK on success, for details see IWineD3DDevice::GetRenderState
2389 * DDERR_INVALIDPARAMS if Value == NULL
2391 *****************************************************************************/
2393 IDirect3DDeviceImpl_7_GetRenderState(IDirect3DDevice7
*iface
,
2394 D3DRENDERSTATETYPE RenderStateType
,
2397 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
2399 TRACE("(%p)->(%08x,%p): Relay\n", This
, RenderStateType
, Value
);
2402 return DDERR_INVALIDPARAMS
;
2404 EnterCriticalSection(&ddraw_cs
);
2405 switch(RenderStateType
)
2407 case D3DRENDERSTATE_TEXTUREMAG
:
2409 WINED3DTEXTUREFILTERTYPE tex_mag
;
2411 hr
= IWineD3DDevice_GetSamplerState(This
->wineD3DDevice
,
2412 0, WINED3DSAMP_MAGFILTER
,
2417 case WINED3DTEXF_POINT
:
2418 *Value
= D3DFILTER_NEAREST
;
2420 case WINED3DTEXF_LINEAR
:
2421 *Value
= D3DFILTER_LINEAR
;
2424 ERR("Unhandled texture mag %d !\n",tex_mag
);
2430 case D3DRENDERSTATE_TEXTUREMIN
:
2432 WINED3DTEXTUREFILTERTYPE tex_min
;
2434 hr
= IWineD3DDevice_GetSamplerState(This
->wineD3DDevice
,
2435 0, WINED3DSAMP_MINFILTER
,
2440 case WINED3DTEXF_POINT
:
2441 *Value
= D3DFILTER_NEAREST
;
2443 case WINED3DTEXF_LINEAR
:
2444 *Value
= D3DFILTER_LINEAR
;
2447 ERR("Unhandled texture mag %d !\n",tex_min
);
2453 case D3DRENDERSTATE_TEXTUREADDRESS
:
2454 case D3DRENDERSTATE_TEXTUREADDRESSU
:
2455 hr
= IWineD3DDevice_GetSamplerState(This
->wineD3DDevice
,
2456 0, WINED3DSAMP_ADDRESSU
,
2459 case D3DRENDERSTATE_TEXTUREADDRESSV
:
2460 hr
= IWineD3DDevice_GetSamplerState(This
->wineD3DDevice
,
2461 0, WINED3DSAMP_ADDRESSV
,
2466 /* FIXME: Unhandled: D3DRENDERSTATE_STIPPLEPATTERN00 - 31 */
2467 hr
= IWineD3DDevice_GetRenderState(This
->wineD3DDevice
,
2471 LeaveCriticalSection(&ddraw_cs
);
2475 static HRESULT WINAPI
2476 IDirect3DDeviceImpl_7_GetRenderState_FPUSetup(IDirect3DDevice7
*iface
,
2477 D3DRENDERSTATETYPE RenderStateType
,
2480 return IDirect3DDeviceImpl_7_GetRenderState(iface
, RenderStateType
, Value
);
2483 static HRESULT WINAPI
2484 IDirect3DDeviceImpl_7_GetRenderState_FPUPreserve(IDirect3DDevice7
*iface
,
2485 D3DRENDERSTATETYPE RenderStateType
,
2491 old_fpucw
= d3d_fpu_setup();
2492 hr
= IDirect3DDeviceImpl_7_GetRenderState(iface
, RenderStateType
, Value
);
2493 set_fpu_control_word(old_fpucw
);
2498 static HRESULT WINAPI
2499 IDirect3DDeviceImpl_3_GetRenderState(IDirect3DDevice3
*iface
,
2500 D3DRENDERSTATETYPE dwRenderStateType
,
2501 DWORD
*lpdwRenderState
)
2503 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice3
, iface
);
2505 TRACE("(%p)->(%08x,%p)\n", This
, dwRenderStateType
, lpdwRenderState
);
2507 switch(dwRenderStateType
)
2509 case D3DRENDERSTATE_TEXTUREHANDLE
:
2511 /* This state is wrapped to SetTexture in SetRenderState, so
2512 * it has to be wrapped to GetTexture here
2514 IWineD3DBaseTexture
*tex
= NULL
;
2515 *lpdwRenderState
= 0;
2517 EnterCriticalSection(&ddraw_cs
);
2519 hr
= IWineD3DDevice_GetTexture(This
->wineD3DDevice
,
2523 if(hr
== WINED3D_OK
&& tex
)
2525 IDirectDrawSurface7
*parent
= NULL
;
2526 hr
= IWineD3DBaseTexture_GetParent(tex
,
2527 (IUnknown
**) &parent
);
2530 /* The parent of the texture is the IDirectDrawSurface7 interface
2531 * of the ddraw surface
2533 IDirectDrawSurfaceImpl
*texImpl
= ICOM_OBJECT(IDirectDrawSurfaceImpl
,
2534 IDirectDrawSurface7
,
2536 *lpdwRenderState
= texImpl
->Handle
;
2537 IDirectDrawSurface7_Release(parent
);
2539 IWineD3DBaseTexture_Release(tex
);
2542 LeaveCriticalSection(&ddraw_cs
);
2547 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2549 /* D3DRENDERSTATE_TEXTUREMAPBLEND is mapped to texture state stages in SetRenderState; reverse
2550 the mapping to get the value. */
2551 DWORD colorop
, colorarg1
, colorarg2
;
2552 DWORD alphaop
, alphaarg1
, alphaarg2
;
2554 EnterCriticalSection(&ddraw_cs
);
2556 This
->legacyTextureBlending
= TRUE
;
2558 IWineD3DDevice_GetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLOROP
, &colorop
);
2559 IWineD3DDevice_GetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG1
, &colorarg1
);
2560 IWineD3DDevice_GetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG2
, &colorarg2
);
2561 IWineD3DDevice_GetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAOP
, &alphaop
);
2562 IWineD3DDevice_GetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG1
, &alphaarg1
);
2563 IWineD3DDevice_GetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG2
, &alphaarg2
);
2565 if (colorop
== WINED3DTOP_SELECTARG1
&& colorarg1
== WINED3DTA_TEXTURE
&&
2566 alphaop
== WINED3DTOP_SELECTARG1
&& alphaarg1
== WINED3DTA_TEXTURE
)
2568 *lpdwRenderState
= D3DTBLEND_DECAL
;
2570 else if (colorop
== WINED3DTOP_SELECTARG1
&& colorarg1
== WINED3DTA_TEXTURE
&&
2571 alphaop
== WINED3DTOP_MODULATE
&& alphaarg1
== WINED3DTA_TEXTURE
&& alphaarg2
== WINED3DTA_CURRENT
)
2573 *lpdwRenderState
= D3DTBLEND_DECALALPHA
;
2575 else if (colorop
== WINED3DTOP_MODULATE
&& colorarg1
== WINED3DTA_TEXTURE
&& colorarg2
== WINED3DTA_CURRENT
&&
2576 alphaop
== WINED3DTOP_MODULATE
&& alphaarg1
== WINED3DTA_TEXTURE
&& alphaarg2
== WINED3DTA_CURRENT
)
2578 *lpdwRenderState
= D3DTBLEND_MODULATEALPHA
;
2583 BOOL tex_alpha
= FALSE
;
2584 IWineD3DBaseTexture
*tex
= NULL
;
2585 WINED3DSURFACE_DESC desc
;
2587 DDPIXELFORMAT ddfmt
;
2589 hr
= IWineD3DDevice_GetTexture(This
->wineD3DDevice
,
2593 if(hr
== WINED3D_OK
&& tex
)
2595 memset(&desc
, 0, sizeof(desc
));
2597 hr
= IWineD3DTexture_GetLevelDesc((IWineD3DTexture
*) tex
, 0, &desc
);
2600 ddfmt
.dwSize
= sizeof(ddfmt
);
2601 PixelFormat_WineD3DtoDD(&ddfmt
, fmt
);
2602 if (ddfmt
.u5
.dwRGBAlphaBitMask
) tex_alpha
= TRUE
;
2605 IWineD3DBaseTexture_Release(tex
);
2608 if (!(colorop
== WINED3DTOP_MODULATE
&& colorarg1
== WINED3DTA_TEXTURE
&& colorarg2
== WINED3DTA_CURRENT
&&
2609 alphaop
== WINED3DTOP_SELECTARG1
&& alphaarg1
== (tex_alpha
? WINED3DTA_TEXTURE
: WINED3DTA_CURRENT
)))
2611 ERR("Unexpected texture stage state setup, returning D3DTBLEND_MODULATE - likely erroneous\n");
2614 *lpdwRenderState
= D3DTBLEND_MODULATE
;
2617 LeaveCriticalSection(&ddraw_cs
);
2623 return IDirect3DDevice7_GetRenderState(ICOM_INTERFACE(This
, IDirect3DDevice7
),
2629 static HRESULT WINAPI
2630 Thunk_IDirect3DDeviceImpl_2_GetRenderState(IDirect3DDevice2
*iface
,
2631 D3DRENDERSTATETYPE dwRenderStateType
,
2632 DWORD
*lpdwRenderState
)
2634 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice2
, iface
);
2635 TRACE_(ddraw_thunk
)("(%p)->(%08x,%p) thunking to IDirect3DDevice3 interface.\n", This
, dwRenderStateType
, lpdwRenderState
);
2636 return IDirect3DDevice3_GetRenderState(ICOM_INTERFACE(This
, IDirect3DDevice3
),
2641 /*****************************************************************************
2642 * IDirect3DDevice7::SetRenderState
2644 * Sets a render state. The possible render states are defined in
2645 * include/d3dtypes.h
2647 * Version 2, 3 and 7
2650 * RenderStateType: State to set
2651 * Value: Value to assign to that state
2654 * D3D_OK on success,
2655 * for details see IWineD3DDevice::SetRenderState
2657 *****************************************************************************/
2659 IDirect3DDeviceImpl_7_SetRenderState(IDirect3DDevice7
*iface
,
2660 D3DRENDERSTATETYPE RenderStateType
,
2663 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
2665 TRACE("(%p)->(%08x,%d): Relay\n", This
, RenderStateType
, Value
);
2667 EnterCriticalSection(&ddraw_cs
);
2668 /* Some render states need special care */
2669 switch(RenderStateType
)
2671 case D3DRENDERSTATE_TEXTUREMAG
:
2673 WINED3DTEXTUREFILTERTYPE tex_mag
= WINED3DTEXF_NONE
;
2675 switch ((D3DTEXTUREFILTER
) Value
)
2677 case D3DFILTER_NEAREST
:
2678 case D3DFILTER_LINEARMIPNEAREST
:
2679 tex_mag
= WINED3DTEXF_POINT
;
2681 case D3DFILTER_LINEAR
:
2682 case D3DFILTER_LINEARMIPLINEAR
:
2683 tex_mag
= WINED3DTEXF_LINEAR
;
2686 ERR("Unhandled texture mag %d !\n",Value
);
2689 hr
= IWineD3DDevice_SetSamplerState(This
->wineD3DDevice
,
2690 0, WINED3DSAMP_MAGFILTER
,
2695 case D3DRENDERSTATE_TEXTUREMIN
:
2697 WINED3DTEXTUREFILTERTYPE tex_min
= WINED3DTEXF_NONE
;
2698 WINED3DTEXTUREFILTERTYPE tex_mip
= WINED3DTEXF_NONE
;
2700 switch ((D3DTEXTUREFILTER
) Value
)
2702 case D3DFILTER_NEAREST
:
2703 tex_min
= WINED3DTEXF_POINT
;
2705 case D3DFILTER_LINEAR
:
2706 tex_min
= WINED3DTEXF_LINEAR
;
2708 case D3DFILTER_MIPNEAREST
:
2709 tex_min
= WINED3DTEXF_NONE
;
2710 tex_mip
= WINED3DTEXF_POINT
;
2712 case D3DFILTER_MIPLINEAR
:
2713 tex_min
= WINED3DTEXF_NONE
;
2714 tex_mip
= WINED3DTEXF_LINEAR
;
2716 case D3DFILTER_LINEARMIPNEAREST
:
2717 tex_min
= WINED3DTEXF_POINT
;
2718 tex_mip
= WINED3DTEXF_LINEAR
;
2720 case D3DFILTER_LINEARMIPLINEAR
:
2721 tex_min
= WINED3DTEXF_LINEAR
;
2722 tex_mip
= WINED3DTEXF_LINEAR
;
2726 ERR("Unhandled texture min %d !\n",Value
);
2729 IWineD3DDevice_SetSamplerState(This
->wineD3DDevice
,
2730 0, WINED3DSAMP_MIPFILTER
,
2732 hr
= IWineD3DDevice_SetSamplerState(This
->wineD3DDevice
,
2733 0, WINED3DSAMP_MINFILTER
,
2738 case D3DRENDERSTATE_TEXTUREADDRESS
:
2739 IWineD3DDevice_SetSamplerState(This
->wineD3DDevice
,
2740 0, WINED3DSAMP_ADDRESSV
,
2743 case D3DRENDERSTATE_TEXTUREADDRESSU
:
2744 hr
= IWineD3DDevice_SetSamplerState(This
->wineD3DDevice
,
2745 0, WINED3DSAMP_ADDRESSU
,
2748 case D3DRENDERSTATE_TEXTUREADDRESSV
:
2749 hr
= IWineD3DDevice_SetSamplerState(This
->wineD3DDevice
,
2750 0, WINED3DSAMP_ADDRESSV
,
2756 /* FIXME: Unhandled: D3DRENDERSTATE_STIPPLEPATTERN00 - 31 */
2758 hr
= IWineD3DDevice_SetRenderState(This
->wineD3DDevice
,
2763 LeaveCriticalSection(&ddraw_cs
);
2767 static HRESULT WINAPI
2768 IDirect3DDeviceImpl_7_SetRenderState_FPUSetup(IDirect3DDevice7
*iface
,
2769 D3DRENDERSTATETYPE RenderStateType
,
2772 return IDirect3DDeviceImpl_7_SetRenderState(iface
, RenderStateType
, Value
);
2775 static HRESULT WINAPI
2776 IDirect3DDeviceImpl_7_SetRenderState_FPUPreserve(IDirect3DDevice7
*iface
,
2777 D3DRENDERSTATETYPE RenderStateType
,
2783 old_fpucw
= d3d_fpu_setup();
2784 hr
= IDirect3DDeviceImpl_7_SetRenderState(iface
, RenderStateType
, Value
);
2785 set_fpu_control_word(old_fpucw
);
2790 static HRESULT WINAPI
2791 IDirect3DDeviceImpl_3_SetRenderState(IDirect3DDevice3
*iface
,
2792 D3DRENDERSTATETYPE RenderStateType
,
2795 /* Note about D3DRENDERSTATE_TEXTUREMAPBLEND implementation: most of values
2796 for this state can be directly mapped to texture stage colorop and alphaop, but
2797 D3DTBLEND_MODULATE is tricky: it uses alpha from texture when available and alpha
2798 from diffuse otherwise. So changing the texture must be monitored in SetTexture to modify
2799 alphaarg when needed.
2801 Aliens vs Predator 1 depends on accurate D3DTBLEND_MODULATE emulation
2803 Legacy texture blending (TEXTUREMAPBLEND) and texture stage states: directx6 docs state that
2804 TEXTUREMAPBLEND is deprecated, yet can still be used. Games must not use both or results
2805 are undefined. D3DTBLEND_MODULATE mode in particular is dependent on texture pixel format and
2806 requires fixup of stage 0 texture states when texture changes, but this fixup can interfere
2807 with games not using this deprecated state. So a flag 'legacyTextureBlending' has to be kept
2808 in device - TRUE if the app is using TEXTUREMAPBLEND.
2810 Tests show that setting TEXTUREMAPBLEND on native doesn't seem to change values returned by
2811 GetTextureStageState and vice versa. Not so on Wine, but it is 'undefined' anyway so, probably, ok,
2812 unless some broken game will be found that cares. */
2815 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice3
, iface
);
2816 TRACE("(%p)->(%08x,%d)\n", This
, RenderStateType
, Value
);
2818 EnterCriticalSection(&ddraw_cs
);
2820 switch(RenderStateType
)
2822 case D3DRENDERSTATE_TEXTUREHANDLE
:
2826 hr
= IWineD3DDevice_SetTexture(This
->wineD3DDevice
,
2832 if(Value
> This
->numHandles
)
2834 FIXME("Specified handle %d out of range\n", Value
);
2835 hr
= DDERR_INVALIDPARAMS
;
2838 if(This
->Handles
[Value
- 1].type
!= DDrawHandle_Texture
)
2840 FIXME("Handle %d isn't a texture handle\n", Value
);
2841 hr
= DDERR_INVALIDPARAMS
;
2846 IDirectDrawSurfaceImpl
*surf
= (IDirectDrawSurfaceImpl
*) This
->Handles
[Value
- 1].ptr
;
2847 hr
= IDirect3DDevice3_SetTexture(iface
, 0, ICOM_INTERFACE(surf
, IDirect3DTexture2
));
2852 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2854 This
->legacyTextureBlending
= TRUE
;
2856 switch ( (D3DTEXTUREBLEND
) Value
)
2858 case D3DTBLEND_MODULATE
:
2860 BOOL tex_alpha
= FALSE
;
2861 IWineD3DBaseTexture
*tex
= NULL
;
2862 WINED3DSURFACE_DESC desc
;
2864 DDPIXELFORMAT ddfmt
;
2866 hr
= IWineD3DDevice_GetTexture(This
->wineD3DDevice
,
2870 if(hr
== WINED3D_OK
&& tex
)
2872 memset(&desc
, 0, sizeof(desc
));
2874 hr
= IWineD3DTexture_GetLevelDesc((IWineD3DTexture
*) tex
, 0, &desc
);
2877 ddfmt
.dwSize
= sizeof(ddfmt
);
2878 PixelFormat_WineD3DtoDD(&ddfmt
, fmt
);
2879 if (ddfmt
.u5
.dwRGBAlphaBitMask
) tex_alpha
= TRUE
;
2882 IWineD3DBaseTexture_Release(tex
);
2885 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG1
);
2888 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG1
, WINED3DTA_TEXTURE
);
2892 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG1
, WINED3DTA_CURRENT
);
2895 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG1
, WINED3DTA_TEXTURE
);
2896 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG2
, WINED3DTA_CURRENT
);
2897 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLOROP
, WINED3DTOP_MODULATE
);
2903 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLOROP
, WINED3DTOP_ADD
);
2904 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG1
, WINED3DTA_TEXTURE
);
2905 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG2
, WINED3DTA_CURRENT
);
2906 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG2
);
2907 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG2
, WINED3DTA_CURRENT
);
2910 case D3DTBLEND_MODULATEALPHA
:
2911 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG1
, WINED3DTA_TEXTURE
);
2912 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG1
, WINED3DTA_TEXTURE
);
2913 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG2
, WINED3DTA_CURRENT
);
2914 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG2
, WINED3DTA_CURRENT
);
2915 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLOROP
, WINED3DTOP_MODULATE
);
2916 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_MODULATE
);
2919 case D3DTBLEND_COPY
:
2920 case D3DTBLEND_DECAL
:
2921 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG1
, WINED3DTA_TEXTURE
);
2922 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG1
, WINED3DTA_TEXTURE
);
2923 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLOROP
, WINED3DTOP_SELECTARG1
);
2924 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG1
);
2927 case D3DTBLEND_DECALALPHA
:
2928 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLOROP
, WINED3DTOP_BLENDTEXTUREALPHA
);
2929 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG1
, WINED3DTA_TEXTURE
);
2930 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG2
, WINED3DTA_CURRENT
);
2931 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG2
);
2932 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG2
, WINED3DTA_CURRENT
);
2936 ERR("Unhandled texture environment %d !\n",Value
);
2944 hr
= IDirect3DDevice7_SetRenderState(ICOM_INTERFACE(This
, IDirect3DDevice7
),
2950 LeaveCriticalSection(&ddraw_cs
);
2955 static HRESULT WINAPI
2956 Thunk_IDirect3DDeviceImpl_2_SetRenderState(IDirect3DDevice2
*iface
,
2957 D3DRENDERSTATETYPE RenderStateType
,
2960 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice2
, iface
);
2961 TRACE_(ddraw_thunk
)("(%p)->(%08x,%d) thunking to IDirect3DDevice3 interface.\n", This
, RenderStateType
, Value
);
2962 return IDirect3DDevice3_SetRenderState(ICOM_INTERFACE(This
, IDirect3DDevice3
), RenderStateType
, Value
);
2965 /*****************************************************************************
2966 * Direct3DDevice3::SetLightState
2968 * Sets a light state for Direct3DDevice3 and Direct3DDevice2. The
2969 * light states are forwarded to Direct3DDevice7 render states
2974 * LightStateType: The light state to change
2975 * Value: The value to assign to that light state
2979 * DDERR_INVALIDPARAMS if the parameters were incorrect
2980 * Also check IDirect3DDevice7::SetRenderState
2982 *****************************************************************************/
2983 static HRESULT WINAPI
2984 IDirect3DDeviceImpl_3_SetLightState(IDirect3DDevice3
*iface
,
2985 D3DLIGHTSTATETYPE LightStateType
,
2988 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice3
, iface
);
2991 TRACE("(%p)->(%08x,%08x)\n", This
, LightStateType
, Value
);
2993 if (!LightStateType
&& (LightStateType
> D3DLIGHTSTATE_COLORVERTEX
))
2995 TRACE("Unexpected Light State Type\n");
2996 return DDERR_INVALIDPARAMS
;
2999 EnterCriticalSection(&ddraw_cs
);
3000 if (LightStateType
== D3DLIGHTSTATE_MATERIAL
/* 1 */)
3002 IDirect3DMaterialImpl
*mat
;
3004 if(Value
== 0) mat
= NULL
;
3005 else if(Value
> This
->numHandles
)
3007 ERR("Material handle out of range(%d)\n", Value
);
3008 LeaveCriticalSection(&ddraw_cs
);
3009 return DDERR_INVALIDPARAMS
;
3011 else if(This
->Handles
[Value
- 1].type
!= DDrawHandle_Material
)
3013 ERR("Invalid handle %d\n", Value
);
3014 LeaveCriticalSection(&ddraw_cs
);
3015 return DDERR_INVALIDPARAMS
;
3019 mat
= (IDirect3DMaterialImpl
*) This
->Handles
[Value
- 1].ptr
;
3024 TRACE(" activating material %p.\n", mat
);
3029 FIXME(" D3DLIGHTSTATE_MATERIAL called with NULL material !!!\n");
3031 This
->material
= Value
;
3033 else if (LightStateType
== D3DLIGHTSTATE_COLORMODEL
/* 3 */)
3038 ERR("DDCOLOR_MONO should not happen!\n");
3041 /* We are already in this mode */
3042 TRACE("Setting color model to RGB (no-op).\n");
3045 ERR("Unknown color model!\n");
3046 LeaveCriticalSection(&ddraw_cs
);
3047 return DDERR_INVALIDPARAMS
;
3052 D3DRENDERSTATETYPE rs
;
3053 switch (LightStateType
)
3055 case D3DLIGHTSTATE_AMBIENT
: /* 2 */
3056 rs
= D3DRENDERSTATE_AMBIENT
;
3058 case D3DLIGHTSTATE_FOGMODE
: /* 4 */
3059 rs
= D3DRENDERSTATE_FOGVERTEXMODE
;
3061 case D3DLIGHTSTATE_FOGSTART
: /* 5 */
3062 rs
= D3DRENDERSTATE_FOGSTART
;
3064 case D3DLIGHTSTATE_FOGEND
: /* 6 */
3065 rs
= D3DRENDERSTATE_FOGEND
;
3067 case D3DLIGHTSTATE_FOGDENSITY
: /* 7 */
3068 rs
= D3DRENDERSTATE_FOGDENSITY
;
3070 case D3DLIGHTSTATE_COLORVERTEX
: /* 8 */
3071 rs
= D3DRENDERSTATE_COLORVERTEX
;
3074 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType
);
3075 LeaveCriticalSection(&ddraw_cs
);
3076 return DDERR_INVALIDPARAMS
;
3079 hr
= IDirect3DDevice7_SetRenderState(ICOM_INTERFACE(This
, IDirect3DDevice7
),
3082 LeaveCriticalSection(&ddraw_cs
);
3086 LeaveCriticalSection(&ddraw_cs
);
3090 static HRESULT WINAPI
3091 Thunk_IDirect3DDeviceImpl_2_SetLightState(IDirect3DDevice2
*iface
,
3092 D3DLIGHTSTATETYPE LightStateType
,
3095 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice2
, iface
);
3096 TRACE_(ddraw_thunk
)("(%p)->(%08x,%08x) thunking to IDirect3DDevice3 interface.\n", This
, LightStateType
, Value
);
3097 return IDirect3DDevice3_SetLightState(ICOM_INTERFACE(This
, IDirect3DDevice3
),
3102 /*****************************************************************************
3103 * IDirect3DDevice3::GetLightState
3105 * Returns the current setting of a light state. The state is read from
3106 * the Direct3DDevice7 render state.
3111 * LightStateType: The light state to return
3112 * Value: The address to store the light state setting at
3116 * DDDERR_INVALIDPARAMS if the parameters were incorrect
3117 * Also see IDirect3DDevice7::GetRenderState
3119 *****************************************************************************/
3120 static HRESULT WINAPI
3121 IDirect3DDeviceImpl_3_GetLightState(IDirect3DDevice3
*iface
,
3122 D3DLIGHTSTATETYPE LightStateType
,
3125 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice3
, iface
);
3128 TRACE("(%p)->(%08x,%p)\n", This
, LightStateType
, Value
);
3130 if (!LightStateType
&& (LightStateType
> D3DLIGHTSTATE_COLORVERTEX
))
3132 TRACE("Unexpected Light State Type\n");
3133 return DDERR_INVALIDPARAMS
;
3137 return DDERR_INVALIDPARAMS
;
3139 EnterCriticalSection(&ddraw_cs
);
3140 if (LightStateType
== D3DLIGHTSTATE_MATERIAL
/* 1 */)
3142 *Value
= This
->material
;
3144 else if (LightStateType
== D3DLIGHTSTATE_COLORMODEL
/* 3 */)
3146 *Value
= D3DCOLOR_RGB
;
3150 D3DRENDERSTATETYPE rs
;
3151 switch (LightStateType
)
3153 case D3DLIGHTSTATE_AMBIENT
: /* 2 */
3154 rs
= D3DRENDERSTATE_AMBIENT
;
3156 case D3DLIGHTSTATE_FOGMODE
: /* 4 */
3157 rs
= D3DRENDERSTATE_FOGVERTEXMODE
;
3159 case D3DLIGHTSTATE_FOGSTART
: /* 5 */
3160 rs
= D3DRENDERSTATE_FOGSTART
;
3162 case D3DLIGHTSTATE_FOGEND
: /* 6 */
3163 rs
= D3DRENDERSTATE_FOGEND
;
3165 case D3DLIGHTSTATE_FOGDENSITY
: /* 7 */
3166 rs
= D3DRENDERSTATE_FOGDENSITY
;
3168 case D3DLIGHTSTATE_COLORVERTEX
: /* 8 */
3169 rs
= D3DRENDERSTATE_COLORVERTEX
;
3172 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType
);
3173 LeaveCriticalSection(&ddraw_cs
);
3174 return DDERR_INVALIDPARAMS
;
3177 hr
= IDirect3DDevice7_GetRenderState(ICOM_INTERFACE(This
, IDirect3DDevice7
),
3180 LeaveCriticalSection(&ddraw_cs
);
3184 LeaveCriticalSection(&ddraw_cs
);
3188 static HRESULT WINAPI
3189 Thunk_IDirect3DDeviceImpl_2_GetLightState(IDirect3DDevice2
*iface
,
3190 D3DLIGHTSTATETYPE LightStateType
,
3193 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice2
, iface
);
3194 TRACE_(ddraw_thunk
)("(%p)->(%08x,%p) thunking to IDirect3DDevice3 interface.\n", This
, LightStateType
, Value
);
3195 return IDirect3DDevice3_GetLightState(ICOM_INTERFACE(This
, IDirect3DDevice3
),
3200 /*****************************************************************************
3201 * IDirect3DDevice7::SetTransform
3203 * Assigns a D3DMATRIX to a transform type. The transform types are defined
3204 * in include/d3dtypes.h.
3205 * The D3DTRANSFORMSTATE_WORLD (=1) is translated to D3DTS_WORLDMATRIX(0)
3206 * (=255) for wined3d, because the 1 transform state was removed in d3d8
3207 * and WineD3D already understands the replacement D3DTS_WORLDMATRIX(0)
3209 * Version 2, 3 and 7
3212 * TransformStateType: transform state to set
3213 * Matrix: Matrix to assign to the state
3217 * DDERR_INVALIDPARAMS if Matrix == NULL
3218 * For details see IWineD3DDevice::SetTransform
3220 *****************************************************************************/
3222 IDirect3DDeviceImpl_7_SetTransform(IDirect3DDevice7
*iface
,
3223 D3DTRANSFORMSTATETYPE TransformStateType
,
3226 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
3227 D3DTRANSFORMSTATETYPE type
= TransformStateType
;
3229 TRACE("(%p)->(%08x,%p): Relay\n", This
, TransformStateType
, Matrix
);
3231 switch(TransformStateType
)
3233 case D3DTRANSFORMSTATE_WORLD
: type
= WINED3DTS_WORLDMATRIX(0); break;
3234 case D3DTRANSFORMSTATE_WORLD1
: type
= WINED3DTS_WORLDMATRIX(1); break;
3235 case D3DTRANSFORMSTATE_WORLD2
: type
= WINED3DTS_WORLDMATRIX(2); break;
3236 case D3DTRANSFORMSTATE_WORLD3
: type
= WINED3DTS_WORLDMATRIX(3); break;
3237 default: type
= TransformStateType
;
3241 return DDERR_INVALIDPARAMS
;
3243 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3244 EnterCriticalSection(&ddraw_cs
);
3245 hr
= IWineD3DDevice_SetTransform(This
->wineD3DDevice
,
3247 (WINED3DMATRIX
*) Matrix
);
3248 LeaveCriticalSection(&ddraw_cs
);
3252 static HRESULT WINAPI
3253 IDirect3DDeviceImpl_7_SetTransform_FPUSetup(IDirect3DDevice7
*iface
,
3254 D3DTRANSFORMSTATETYPE TransformStateType
,
3257 return IDirect3DDeviceImpl_7_SetTransform(iface
, TransformStateType
, Matrix
);
3260 static HRESULT WINAPI
3261 IDirect3DDeviceImpl_7_SetTransform_FPUPreserve(IDirect3DDevice7
*iface
,
3262 D3DTRANSFORMSTATETYPE TransformStateType
,
3268 old_fpucw
= d3d_fpu_setup();
3269 hr
= IDirect3DDeviceImpl_7_SetTransform(iface
, TransformStateType
, Matrix
);
3270 set_fpu_control_word(old_fpucw
);
3275 static HRESULT WINAPI
3276 Thunk_IDirect3DDeviceImpl_3_SetTransform(IDirect3DDevice3
*iface
,
3277 D3DTRANSFORMSTATETYPE TransformStateType
,
3278 D3DMATRIX
*D3DMatrix
)
3280 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice3
, iface
);
3281 TRACE_(ddraw_thunk
)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This
, TransformStateType
, D3DMatrix
);
3282 return IDirect3DDevice7_SetTransform(ICOM_INTERFACE(This
, IDirect3DDevice7
),
3287 static HRESULT WINAPI
3288 Thunk_IDirect3DDeviceImpl_2_SetTransform(IDirect3DDevice2
*iface
,
3289 D3DTRANSFORMSTATETYPE TransformStateType
,
3290 D3DMATRIX
*D3DMatrix
)
3292 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice2
, iface
);
3293 TRACE_(ddraw_thunk
)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This
, TransformStateType
, D3DMatrix
);
3294 return IDirect3DDevice7_SetTransform(ICOM_INTERFACE(This
, IDirect3DDevice7
),
3299 /*****************************************************************************
3300 * IDirect3DDevice7::GetTransform
3302 * Returns the matrix assigned to a transform state
3303 * D3DTRANSFORMSTATE_WORLD is translated to D3DTS_WORLDMATRIX(0), see
3307 * TransformStateType: State to read the matrix from
3308 * Matrix: Address to store the matrix at
3312 * DDERR_INVALIDPARAMS if Matrix == NULL
3313 * For details, see IWineD3DDevice::GetTransform
3315 *****************************************************************************/
3317 IDirect3DDeviceImpl_7_GetTransform(IDirect3DDevice7
*iface
,
3318 D3DTRANSFORMSTATETYPE TransformStateType
,
3321 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
3322 D3DTRANSFORMSTATETYPE type
= TransformStateType
;
3324 TRACE("(%p)->(%08x,%p): Relay\n", This
, TransformStateType
, Matrix
);
3326 switch(TransformStateType
)
3328 case D3DTRANSFORMSTATE_WORLD
: type
= WINED3DTS_WORLDMATRIX(0); break;
3329 case D3DTRANSFORMSTATE_WORLD1
: type
= WINED3DTS_WORLDMATRIX(1); break;
3330 case D3DTRANSFORMSTATE_WORLD2
: type
= WINED3DTS_WORLDMATRIX(2); break;
3331 case D3DTRANSFORMSTATE_WORLD3
: type
= WINED3DTS_WORLDMATRIX(3); break;
3332 default: type
= TransformStateType
;
3336 return DDERR_INVALIDPARAMS
;
3338 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3339 EnterCriticalSection(&ddraw_cs
);
3340 hr
= IWineD3DDevice_GetTransform(This
->wineD3DDevice
, type
, (WINED3DMATRIX
*) Matrix
);
3341 LeaveCriticalSection(&ddraw_cs
);
3345 static HRESULT WINAPI
3346 IDirect3DDeviceImpl_7_GetTransform_FPUSetup(IDirect3DDevice7
*iface
,
3347 D3DTRANSFORMSTATETYPE TransformStateType
,
3350 return IDirect3DDeviceImpl_7_GetTransform(iface
, TransformStateType
, Matrix
);
3353 static HRESULT WINAPI
3354 IDirect3DDeviceImpl_7_GetTransform_FPUPreserve(IDirect3DDevice7
*iface
,
3355 D3DTRANSFORMSTATETYPE TransformStateType
,
3361 old_fpucw
= d3d_fpu_setup();
3362 hr
= IDirect3DDeviceImpl_7_GetTransform(iface
, TransformStateType
, Matrix
);
3363 set_fpu_control_word(old_fpucw
);
3368 static HRESULT WINAPI
3369 Thunk_IDirect3DDeviceImpl_3_GetTransform(IDirect3DDevice3
*iface
,
3370 D3DTRANSFORMSTATETYPE TransformStateType
,
3371 D3DMATRIX
*D3DMatrix
)
3373 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice3
, iface
);
3374 TRACE_(ddraw_thunk
)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This
, TransformStateType
, D3DMatrix
);
3375 return IDirect3DDevice7_GetTransform(ICOM_INTERFACE(This
, IDirect3DDevice7
),
3380 static HRESULT WINAPI
3381 Thunk_IDirect3DDeviceImpl_2_GetTransform(IDirect3DDevice2
*iface
,
3382 D3DTRANSFORMSTATETYPE TransformStateType
,
3383 D3DMATRIX
*D3DMatrix
)
3385 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice2
, iface
);
3386 TRACE_(ddraw_thunk
)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This
, TransformStateType
, D3DMatrix
);
3387 return IDirect3DDevice7_GetTransform(ICOM_INTERFACE(This
, IDirect3DDevice7
),
3392 /*****************************************************************************
3393 * IDirect3DDevice7::MultiplyTransform
3395 * Multiplies the already-set transform matrix of a transform state
3396 * with another matrix. For the world matrix, see SetTransform
3398 * Version 2, 3 and 7
3401 * TransformStateType: Transform state to multiply
3402 * D3DMatrix Matrix to multiply with.
3406 * DDERR_INVALIDPARAMS if D3DMatrix is NULL
3407 * For details, see IWineD3DDevice::MultiplyTransform
3409 *****************************************************************************/
3411 IDirect3DDeviceImpl_7_MultiplyTransform(IDirect3DDevice7
*iface
,
3412 D3DTRANSFORMSTATETYPE TransformStateType
,
3413 D3DMATRIX
*D3DMatrix
)
3415 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
3417 D3DTRANSFORMSTATETYPE type
;
3418 TRACE("(%p)->(%08x,%p): Relay\n", This
, TransformStateType
, D3DMatrix
);
3420 switch(TransformStateType
)
3422 case D3DTRANSFORMSTATE_WORLD
: type
= WINED3DTS_WORLDMATRIX(0); break;
3423 case D3DTRANSFORMSTATE_WORLD1
: type
= WINED3DTS_WORLDMATRIX(1); break;
3424 case D3DTRANSFORMSTATE_WORLD2
: type
= WINED3DTS_WORLDMATRIX(2); break;
3425 case D3DTRANSFORMSTATE_WORLD3
: type
= WINED3DTS_WORLDMATRIX(3); break;
3426 default: type
= TransformStateType
;
3429 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3430 EnterCriticalSection(&ddraw_cs
);
3431 hr
= IWineD3DDevice_MultiplyTransform(This
->wineD3DDevice
,
3433 (WINED3DMATRIX
*) D3DMatrix
);
3434 LeaveCriticalSection(&ddraw_cs
);
3438 static HRESULT WINAPI
3439 IDirect3DDeviceImpl_7_MultiplyTransform_FPUSetup(IDirect3DDevice7
*iface
,
3440 D3DTRANSFORMSTATETYPE TransformStateType
,
3441 D3DMATRIX
*D3DMatrix
)
3443 return IDirect3DDeviceImpl_7_MultiplyTransform(iface
, TransformStateType
, D3DMatrix
);
3446 static HRESULT WINAPI
3447 IDirect3DDeviceImpl_7_MultiplyTransform_FPUPreserve(IDirect3DDevice7
*iface
,
3448 D3DTRANSFORMSTATETYPE TransformStateType
,
3449 D3DMATRIX
*D3DMatrix
)
3454 old_fpucw
= d3d_fpu_setup();
3455 hr
= IDirect3DDeviceImpl_7_MultiplyTransform(iface
, TransformStateType
, D3DMatrix
);
3456 set_fpu_control_word(old_fpucw
);
3461 static HRESULT WINAPI
3462 Thunk_IDirect3DDeviceImpl_3_MultiplyTransform(IDirect3DDevice3
*iface
,
3463 D3DTRANSFORMSTATETYPE TransformStateType
,
3464 D3DMATRIX
*D3DMatrix
)
3466 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice3
, iface
);
3467 TRACE_(ddraw_thunk
)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This
, TransformStateType
, D3DMatrix
);
3468 return IDirect3DDevice7_MultiplyTransform(ICOM_INTERFACE(This
, IDirect3DDevice7
),
3473 static HRESULT WINAPI
3474 Thunk_IDirect3DDeviceImpl_2_MultiplyTransform(IDirect3DDevice2
*iface
,
3475 D3DTRANSFORMSTATETYPE TransformStateType
,
3476 D3DMATRIX
*D3DMatrix
)
3478 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice2
, iface
);
3479 TRACE_(ddraw_thunk
)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This
, TransformStateType
, D3DMatrix
);
3480 return IDirect3DDevice7_MultiplyTransform(ICOM_INTERFACE(This
, IDirect3DDevice7
),
3485 /*****************************************************************************
3486 * IDirect3DDevice7::DrawPrimitive
3488 * Draws primitives based on vertices in an application-provided pointer
3490 * Version 2, 3 and 7. The IDirect3DDevice2 thunk converts the fixed vertex type into
3491 * an FVF format for D3D7
3494 * PrimitiveType: The type of the primitives to draw
3495 * Vertex type: Flexible vertex format vertex description
3496 * Vertices: Pointer to the vertex array
3497 * VertexCount: The number of vertices to draw
3498 * Flags: As usual a few flags
3502 * DDERR_INVALIDPARAMS if Vertices is NULL
3503 * For details, see IWineD3DDevice::DrawPrimitiveUP
3505 *****************************************************************************/
3507 IDirect3DDeviceImpl_7_DrawPrimitive(IDirect3DDevice7
*iface
,
3508 D3DPRIMITIVETYPE PrimitiveType
,
3514 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
3515 UINT PrimitiveCount
, stride
;
3517 TRACE("(%p)->(%08x,%08x,%p,%08x,%08x): Relay!\n", This
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3520 return DDERR_INVALIDPARAMS
;
3522 /* Get the vertex count */
3523 switch(PrimitiveType
)
3525 case D3DPT_POINTLIST
:
3526 PrimitiveCount
= VertexCount
;
3529 case D3DPT_LINELIST
:
3530 PrimitiveCount
= VertexCount
/ 2;
3533 case D3DPT_LINESTRIP
:
3534 PrimitiveCount
= VertexCount
- 1;
3537 case D3DPT_TRIANGLELIST
:
3538 PrimitiveCount
= VertexCount
/ 3;
3541 case D3DPT_TRIANGLESTRIP
:
3542 PrimitiveCount
= VertexCount
- 2;
3545 case D3DPT_TRIANGLEFAN
:
3546 PrimitiveCount
= VertexCount
- 2;
3550 return DDERR_INVALIDPARAMS
;
3553 /* Get the stride */
3554 stride
= get_flexible_vertex_size(VertexType
);
3557 EnterCriticalSection(&ddraw_cs
);
3558 hr
= IWineD3DDevice_SetVertexDeclaration(This
->wineD3DDevice
,
3559 IDirectDrawImpl_FindDecl(This
->ddraw
, VertexType
));
3562 LeaveCriticalSection(&ddraw_cs
);
3566 /* This method translates to the user pointer draw of WineD3D */
3567 hr
= IWineD3DDevice_DrawPrimitiveUP(This
->wineD3DDevice
,
3572 LeaveCriticalSection(&ddraw_cs
);
3576 static HRESULT WINAPI
3577 IDirect3DDeviceImpl_7_DrawPrimitive_FPUSetup(IDirect3DDevice7
*iface
,
3578 D3DPRIMITIVETYPE PrimitiveType
,
3584 return IDirect3DDeviceImpl_7_DrawPrimitive(iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3587 static HRESULT WINAPI
3588 IDirect3DDeviceImpl_7_DrawPrimitive_FPUPreserve(IDirect3DDevice7
*iface
,
3589 D3DPRIMITIVETYPE PrimitiveType
,
3598 old_fpucw
= d3d_fpu_setup();
3599 hr
= IDirect3DDeviceImpl_7_DrawPrimitive(iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3600 set_fpu_control_word(old_fpucw
);
3605 static HRESULT WINAPI
3606 Thunk_IDirect3DDeviceImpl_3_DrawPrimitive(IDirect3DDevice3
*iface
,
3607 D3DPRIMITIVETYPE PrimitiveType
,
3613 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice3
, iface
);
3614 TRACE_(ddraw_thunk
)("(%p)->(%08x,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3615 return IDirect3DDevice7_DrawPrimitive(ICOM_INTERFACE(This
, IDirect3DDevice7
),
3623 static HRESULT WINAPI
3624 Thunk_IDirect3DDeviceImpl_2_DrawPrimitive(IDirect3DDevice2
*iface
,
3625 D3DPRIMITIVETYPE PrimitiveType
,
3626 D3DVERTEXTYPE VertexType
,
3631 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice2
, iface
);
3633 TRACE_(ddraw_thunk
)("(%p)->(%08x,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3637 case D3DVT_VERTEX
: FVF
= D3DFVF_VERTEX
; break;
3638 case D3DVT_LVERTEX
: FVF
= D3DFVF_LVERTEX
; break;
3639 case D3DVT_TLVERTEX
: FVF
= D3DFVF_TLVERTEX
; break;
3641 ERR("Unexpected vertex type %d\n", VertexType
);
3642 return DDERR_INVALIDPARAMS
; /* Should never happen */
3645 return IDirect3DDevice7_DrawPrimitive(ICOM_INTERFACE(This
, IDirect3DDevice7
),
3653 /*****************************************************************************
3654 * IDirect3DDevice7::DrawIndexedPrimitive
3656 * Draws vertices from an application-provided pointer, based on the index
3657 * numbers in a WORD array.
3659 * Version 2, 3 and 7. The version 7 thunk translates the vertex type into
3660 * an FVF format for D3D7
3663 * PrimitiveType: The primitive type to draw
3664 * VertexType: The FVF vertex description
3665 * Vertices: Pointer to the vertex array
3667 * Indices: Pointer to the index array
3668 * IndexCount: Number of indices = Number of vertices to draw
3669 * Flags: As usual, some flags
3673 * DDERR_INVALIDPARAMS if Vertices or Indices is NULL
3674 * For details, see IWineD3DDevice::DrawIndexedPrimitiveUP
3676 *****************************************************************************/
3678 IDirect3DDeviceImpl_7_DrawIndexedPrimitive(IDirect3DDevice7
*iface
,
3679 D3DPRIMITIVETYPE PrimitiveType
,
3687 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
3688 UINT PrimitiveCount
= 0;
3690 TRACE("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x): Relay!\n", This
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3692 /* Get the primitive number */
3693 switch(PrimitiveType
)
3695 case D3DPT_POINTLIST
:
3696 PrimitiveCount
= IndexCount
;
3699 case D3DPT_LINELIST
:
3700 PrimitiveCount
= IndexCount
/ 2;
3703 case D3DPT_LINESTRIP
:
3704 PrimitiveCount
= IndexCount
- 1;
3707 case D3DPT_TRIANGLELIST
:
3708 PrimitiveCount
= IndexCount
/ 3;
3711 case D3DPT_TRIANGLESTRIP
:
3712 PrimitiveCount
= IndexCount
- 2;
3715 case D3DPT_TRIANGLEFAN
:
3716 PrimitiveCount
= IndexCount
- 2;
3720 return DDERR_INVALIDPARAMS
;
3723 /* Set the D3DDevice's FVF */
3724 EnterCriticalSection(&ddraw_cs
);
3725 hr
= IWineD3DDevice_SetVertexDeclaration(This
->wineD3DDevice
,
3726 IDirectDrawImpl_FindDecl(This
->ddraw
, VertexType
));
3729 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This
, hr
);
3730 LeaveCriticalSection(&ddraw_cs
);
3734 hr
= IWineD3DDevice_DrawIndexedPrimitiveUP(This
->wineD3DDevice
,
3736 0 /* MinVertexIndex */,
3737 VertexCount
/* UINT NumVertexIndex */,
3742 get_flexible_vertex_size(VertexType
));
3743 LeaveCriticalSection(&ddraw_cs
);
3747 static HRESULT WINAPI
3748 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUSetup(IDirect3DDevice7
*iface
,
3749 D3DPRIMITIVETYPE PrimitiveType
,
3757 return IDirect3DDeviceImpl_7_DrawIndexedPrimitive(iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3760 static HRESULT WINAPI
3761 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUPreserve(IDirect3DDevice7
*iface
,
3762 D3DPRIMITIVETYPE PrimitiveType
,
3773 old_fpucw
= d3d_fpu_setup();
3774 hr
= IDirect3DDeviceImpl_7_DrawIndexedPrimitive(iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3775 set_fpu_control_word(old_fpucw
);
3780 static HRESULT WINAPI
3781 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive(IDirect3DDevice3
*iface
,
3782 D3DPRIMITIVETYPE PrimitiveType
,
3790 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice3
, iface
);
3791 TRACE_(ddraw_thunk
)("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3792 return IDirect3DDevice7_DrawIndexedPrimitive(ICOM_INTERFACE(This
, IDirect3DDevice7
),
3802 static HRESULT WINAPI
3803 Thunk_IDirect3DDeviceImpl_2_DrawIndexedPrimitive(IDirect3DDevice2
*iface
,
3804 D3DPRIMITIVETYPE PrimitiveType
,
3805 D3DVERTEXTYPE VertexType
,
3813 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice2
, iface
);
3814 TRACE_(ddraw_thunk
)("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3818 case D3DVT_VERTEX
: FVF
= D3DFVF_VERTEX
; break;
3819 case D3DVT_LVERTEX
: FVF
= D3DFVF_LVERTEX
; break;
3820 case D3DVT_TLVERTEX
: FVF
= D3DFVF_TLVERTEX
; break;
3822 ERR("Unexpected vertex type %d\n", VertexType
);
3823 return DDERR_INVALIDPARAMS
; /* Should never happen */
3826 return IDirect3DDevice7_DrawIndexedPrimitive(ICOM_INTERFACE(This
, IDirect3DDevice7
),
3836 /*****************************************************************************
3837 * IDirect3DDevice7::SetClipStatus
3839 * Sets the clip status. This defines things as clipping conditions and
3840 * the extents of the clipping region.
3842 * Version 2, 3 and 7
3848 * D3D_OK because it's a stub
3849 * (DDERR_INVALIDPARAMS if ClipStatus == NULL)
3851 *****************************************************************************/
3852 static HRESULT WINAPI
3853 IDirect3DDeviceImpl_7_SetClipStatus(IDirect3DDevice7
*iface
,
3854 D3DCLIPSTATUS
*ClipStatus
)
3856 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
3857 FIXME("(%p)->(%p): Stub!\n", This
, ClipStatus
);
3859 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them
3860 * Perhaps this needs a new data type and an additional IWineD3DDevice method
3862 /* return IWineD3DDevice_SetClipStatus(This->wineD3DDevice, ClipStatus);*/
3866 static HRESULT WINAPI
3867 Thunk_IDirect3DDeviceImpl_3_SetClipStatus(IDirect3DDevice3
*iface
,
3868 D3DCLIPSTATUS
*ClipStatus
)
3870 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice3
, iface
);
3871 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This
, ClipStatus
);
3872 return IDirect3DDevice7_SetClipStatus(ICOM_INTERFACE(This
, IDirect3DDevice7
),
3876 static HRESULT WINAPI
3877 Thunk_IDirect3DDeviceImpl_2_SetClipStatus(IDirect3DDevice2
*iface
,
3878 D3DCLIPSTATUS
*ClipStatus
)
3880 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice2
, iface
);
3881 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This
, ClipStatus
);
3882 return IDirect3DDevice7_SetClipStatus(ICOM_INTERFACE(This
, IDirect3DDevice7
),
3886 /*****************************************************************************
3887 * IDirect3DDevice7::GetClipStatus
3889 * Returns the clip status
3892 * ClipStatus: Address to write the clip status to
3895 * D3D_OK because it's a stub
3897 *****************************************************************************/
3898 static HRESULT WINAPI
3899 IDirect3DDeviceImpl_7_GetClipStatus(IDirect3DDevice7
*iface
,
3900 D3DCLIPSTATUS
*ClipStatus
)
3902 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
3903 FIXME("(%p)->(%p): Stub!\n", This
, ClipStatus
);
3905 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them */
3906 /* return IWineD3DDevice_GetClipStatus(This->wineD3DDevice, ClipStatus);*/
3910 static HRESULT WINAPI
3911 Thunk_IDirect3DDeviceImpl_3_GetClipStatus(IDirect3DDevice3
*iface
,
3912 D3DCLIPSTATUS
*ClipStatus
)
3914 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice3
, iface
);
3915 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This
, ClipStatus
);
3916 return IDirect3DDevice7_GetClipStatus(ICOM_INTERFACE(This
, IDirect3DDevice7
),
3920 static HRESULT WINAPI
3921 Thunk_IDirect3DDeviceImpl_2_GetClipStatus(IDirect3DDevice2
*iface
,
3922 D3DCLIPSTATUS
*ClipStatus
)
3924 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice2
, iface
);
3925 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This
, ClipStatus
);
3926 return IDirect3DDevice7_GetClipStatus(ICOM_INTERFACE(This
, IDirect3DDevice7
),
3930 /*****************************************************************************
3931 * IDirect3DDevice::DrawPrimitiveStrided
3933 * Draws vertices described by a D3DDRAWPRIMITIVESTRIDEDDATA structure.
3938 * PrimitiveType: The primitive type to draw
3939 * VertexType: The FVF description of the vertices to draw (for the stride??)
3940 * D3DDrawPrimStrideData: A D3DDRAWPRIMITIVESTRIDEDDATA structure describing
3941 * the vertex data locations
3942 * VertexCount: The number of vertices to draw
3946 * D3D_OK, because it's a stub
3947 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
3948 * (For details, see IWineD3DDevice::DrawPrimitiveStrided)
3950 *****************************************************************************/
3952 IDirect3DDeviceImpl_7_DrawPrimitiveStrided(IDirect3DDevice7
*iface
,
3953 D3DPRIMITIVETYPE PrimitiveType
,
3955 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
3959 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
3960 WineDirect3DVertexStridedData WineD3DStrided
;
3962 UINT PrimitiveCount
;
3965 TRACE("(%p)->(%08x,%08x,%p,%08x,%08x): stub!\n", This
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
3967 memset(&WineD3DStrided
, 0, sizeof(WineD3DStrided
));
3968 /* Get the strided data right. the wined3d structure is a bit bigger
3969 * Watch out: The contents of the strided data are determined by the fvf,
3970 * not by the members set in D3DDrawPrimStrideData. So it's valid
3971 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
3972 * not set in the fvf.
3974 if(VertexType
& D3DFVF_POSITION_MASK
)
3976 WineD3DStrided
.u
.s
.position
.lpData
= D3DDrawPrimStrideData
->position
.lpvData
;
3977 WineD3DStrided
.u
.s
.position
.dwStride
= D3DDrawPrimStrideData
->position
.dwStride
;
3978 WineD3DStrided
.u
.s
.position
.dwType
= WINED3DDECLTYPE_FLOAT3
;
3979 if (VertexType
& D3DFVF_XYZRHW
)
3981 WineD3DStrided
.u
.s
.position
.dwType
= WINED3DDECLTYPE_FLOAT4
;
3982 WineD3DStrided
.u
.s
.position_transformed
= TRUE
;
3984 WineD3DStrided
.u
.s
.position_transformed
= FALSE
;
3987 if(VertexType
& D3DFVF_NORMAL
)
3989 WineD3DStrided
.u
.s
.normal
.lpData
= D3DDrawPrimStrideData
->normal
.lpvData
;
3990 WineD3DStrided
.u
.s
.normal
.dwStride
= D3DDrawPrimStrideData
->normal
.dwStride
;
3991 WineD3DStrided
.u
.s
.normal
.dwType
= WINED3DDECLTYPE_FLOAT3
;
3994 if(VertexType
& D3DFVF_DIFFUSE
)
3996 WineD3DStrided
.u
.s
.diffuse
.lpData
= D3DDrawPrimStrideData
->diffuse
.lpvData
;
3997 WineD3DStrided
.u
.s
.diffuse
.dwStride
= D3DDrawPrimStrideData
->diffuse
.dwStride
;
3998 WineD3DStrided
.u
.s
.diffuse
.dwType
= WINED3DDECLTYPE_D3DCOLOR
;
4001 if(VertexType
& D3DFVF_SPECULAR
)
4003 WineD3DStrided
.u
.s
.specular
.lpData
= D3DDrawPrimStrideData
->specular
.lpvData
;
4004 WineD3DStrided
.u
.s
.specular
.dwStride
= D3DDrawPrimStrideData
->specular
.dwStride
;
4005 WineD3DStrided
.u
.s
.specular
.dwType
= WINED3DDECLTYPE_D3DCOLOR
;
4008 for( i
= 0; i
< GET_TEXCOUNT_FROM_FVF(VertexType
); i
++)
4010 WineD3DStrided
.u
.s
.texCoords
[i
].lpData
= D3DDrawPrimStrideData
->textureCoords
[i
].lpvData
;
4011 WineD3DStrided
.u
.s
.texCoords
[i
].dwStride
= D3DDrawPrimStrideData
->textureCoords
[i
].dwStride
;
4012 switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType
, i
))
4014 case 1: WineD3DStrided
.u
.s
.texCoords
[i
].dwType
= WINED3DDECLTYPE_FLOAT1
; break;
4015 case 2: WineD3DStrided
.u
.s
.texCoords
[i
].dwType
= WINED3DDECLTYPE_FLOAT2
; break;
4016 case 3: WineD3DStrided
.u
.s
.texCoords
[i
].dwType
= WINED3DDECLTYPE_FLOAT3
; break;
4017 case 4: WineD3DStrided
.u
.s
.texCoords
[i
].dwType
= WINED3DDECLTYPE_FLOAT4
; break;
4018 default: ERR("Unexpected texture coordinate size %d\n",
4019 GET_TEXCOORD_SIZE_FROM_FVF(VertexType
, i
));
4023 /* Get the primitive count */
4024 switch(PrimitiveType
)
4026 case D3DPT_POINTLIST
:
4027 PrimitiveCount
= VertexCount
;
4030 case D3DPT_LINELIST
:
4031 PrimitiveCount
= VertexCount
/ 2;
4034 case D3DPT_LINESTRIP
:
4035 PrimitiveCount
= VertexCount
- 1;
4038 case D3DPT_TRIANGLELIST
:
4039 PrimitiveCount
= VertexCount
/ 3;
4042 case D3DPT_TRIANGLESTRIP
:
4043 PrimitiveCount
= VertexCount
- 2;
4046 case D3DPT_TRIANGLEFAN
:
4047 PrimitiveCount
= VertexCount
- 2;
4050 default: return DDERR_INVALIDPARAMS
;
4053 /* WineD3D doesn't need the FVF here */
4054 EnterCriticalSection(&ddraw_cs
);
4055 hr
= IWineD3DDevice_DrawPrimitiveStrided(This
->wineD3DDevice
,
4059 LeaveCriticalSection(&ddraw_cs
);
4063 static HRESULT WINAPI
4064 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUSetup(IDirect3DDevice7
*iface
,
4065 D3DPRIMITIVETYPE PrimitiveType
,
4067 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
4071 return IDirect3DDeviceImpl_7_DrawPrimitiveStrided(iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
4074 static HRESULT WINAPI
4075 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUPreserve(IDirect3DDevice7
*iface
,
4076 D3DPRIMITIVETYPE PrimitiveType
,
4078 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
4085 old_fpucw
= d3d_fpu_setup();
4086 hr
= IDirect3DDeviceImpl_7_DrawPrimitiveStrided(iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
4087 set_fpu_control_word(old_fpucw
);
4092 static HRESULT WINAPI
4093 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided(IDirect3DDevice3
*iface
,
4094 D3DPRIMITIVETYPE PrimitiveType
,
4096 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
4100 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice3
, iface
);
4101 TRACE_(ddraw_thunk
)("(%p)->(%08x,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
4102 return IDirect3DDevice7_DrawPrimitiveStrided(ICOM_INTERFACE(This
, IDirect3DDevice7
),
4105 D3DDrawPrimStrideData
,
4110 /*****************************************************************************
4111 * IDirect3DDevice7::DrawIndexedPrimitiveStrided
4113 * Draws primitives specified by strided data locations based on indices
4121 * D3D_OK, because it's a stub
4122 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
4123 * (DDERR_INVALIDPARAMS if Indices is NULL)
4124 * (For more details, see IWineD3DDevice::DrawIndexedPrimitiveStrided)
4126 *****************************************************************************/
4128 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(IDirect3DDevice7
*iface
,
4129 D3DPRIMITIVETYPE PrimitiveType
,
4131 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
4137 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
4138 WineDirect3DVertexStridedData WineD3DStrided
;
4140 UINT PrimitiveCount
;
4143 TRACE("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x)\n", This
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4145 memset(&WineD3DStrided
, 0, sizeof(WineD3DStrided
));
4146 /* Get the strided data right. the wined3d structure is a bit bigger
4147 * Watch out: The contents of the strided data are determined by the fvf,
4148 * not by the members set in D3DDrawPrimStrideData. So it's valid
4149 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
4150 * not set in the fvf.
4152 if(VertexType
& D3DFVF_POSITION_MASK
)
4154 WineD3DStrided
.u
.s
.position
.lpData
= D3DDrawPrimStrideData
->position
.lpvData
;
4155 WineD3DStrided
.u
.s
.position
.dwStride
= D3DDrawPrimStrideData
->position
.dwStride
;
4156 WineD3DStrided
.u
.s
.position
.dwType
= WINED3DDECLTYPE_FLOAT3
;
4157 if (VertexType
& D3DFVF_XYZRHW
)
4159 WineD3DStrided
.u
.s
.position
.dwType
= WINED3DDECLTYPE_FLOAT4
;
4160 WineD3DStrided
.u
.s
.position_transformed
= TRUE
;
4162 WineD3DStrided
.u
.s
.position_transformed
= FALSE
;
4165 if(VertexType
& D3DFVF_NORMAL
)
4167 WineD3DStrided
.u
.s
.normal
.lpData
= D3DDrawPrimStrideData
->normal
.lpvData
;
4168 WineD3DStrided
.u
.s
.normal
.dwStride
= D3DDrawPrimStrideData
->normal
.dwStride
;
4169 WineD3DStrided
.u
.s
.normal
.dwType
= WINED3DDECLTYPE_FLOAT3
;
4172 if(VertexType
& D3DFVF_DIFFUSE
)
4174 WineD3DStrided
.u
.s
.diffuse
.lpData
= D3DDrawPrimStrideData
->diffuse
.lpvData
;
4175 WineD3DStrided
.u
.s
.diffuse
.dwStride
= D3DDrawPrimStrideData
->diffuse
.dwStride
;
4176 WineD3DStrided
.u
.s
.diffuse
.dwType
= WINED3DDECLTYPE_D3DCOLOR
;
4179 if(VertexType
& D3DFVF_SPECULAR
)
4181 WineD3DStrided
.u
.s
.specular
.lpData
= D3DDrawPrimStrideData
->specular
.lpvData
;
4182 WineD3DStrided
.u
.s
.specular
.dwStride
= D3DDrawPrimStrideData
->specular
.dwStride
;
4183 WineD3DStrided
.u
.s
.specular
.dwType
= WINED3DDECLTYPE_D3DCOLOR
;
4186 for( i
= 0; i
< GET_TEXCOUNT_FROM_FVF(VertexType
); i
++)
4188 WineD3DStrided
.u
.s
.texCoords
[i
].lpData
= D3DDrawPrimStrideData
->textureCoords
[i
].lpvData
;
4189 WineD3DStrided
.u
.s
.texCoords
[i
].dwStride
= D3DDrawPrimStrideData
->textureCoords
[i
].dwStride
;
4190 switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType
, i
))
4192 case 1: WineD3DStrided
.u
.s
.texCoords
[i
].dwType
= WINED3DDECLTYPE_FLOAT1
; break;
4193 case 2: WineD3DStrided
.u
.s
.texCoords
[i
].dwType
= WINED3DDECLTYPE_FLOAT2
; break;
4194 case 3: WineD3DStrided
.u
.s
.texCoords
[i
].dwType
= WINED3DDECLTYPE_FLOAT3
; break;
4195 case 4: WineD3DStrided
.u
.s
.texCoords
[i
].dwType
= WINED3DDECLTYPE_FLOAT4
; break;
4196 default: ERR("Unexpected texture coordinate size %d\n",
4197 GET_TEXCOORD_SIZE_FROM_FVF(VertexType
, i
));
4201 /* Get the primitive count */
4202 switch(PrimitiveType
)
4204 case D3DPT_POINTLIST
:
4205 PrimitiveCount
= IndexCount
;
4208 case D3DPT_LINELIST
:
4209 PrimitiveCount
= IndexCount
/ 2;
4212 case D3DPT_LINESTRIP
:
4213 PrimitiveCount
= IndexCount
- 1;
4216 case D3DPT_TRIANGLELIST
:
4217 PrimitiveCount
= IndexCount
/ 3;
4220 case D3DPT_TRIANGLESTRIP
:
4221 PrimitiveCount
= IndexCount
- 2;
4224 case D3DPT_TRIANGLEFAN
:
4225 PrimitiveCount
= IndexCount
- 2;
4228 default: return DDERR_INVALIDPARAMS
;
4231 /* WineD3D doesn't need the FVF here */
4232 EnterCriticalSection(&ddraw_cs
);
4233 hr
= IWineD3DDevice_DrawIndexedPrimitiveStrided(This
->wineD3DDevice
,
4239 WINED3DFMT_INDEX16
);
4240 LeaveCriticalSection(&ddraw_cs
);
4244 static HRESULT WINAPI
4245 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUSetup(IDirect3DDevice7
*iface
,
4246 D3DPRIMITIVETYPE PrimitiveType
,
4248 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
4254 return IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4257 static HRESULT WINAPI
4258 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUPreserve(IDirect3DDevice7
*iface
,
4259 D3DPRIMITIVETYPE PrimitiveType
,
4261 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
4270 old_fpucw
= d3d_fpu_setup();
4271 hr
= IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4272 set_fpu_control_word(old_fpucw
);
4277 static HRESULT WINAPI
4278 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided(IDirect3DDevice3
*iface
,
4279 D3DPRIMITIVETYPE PrimitiveType
,
4281 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
4287 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice3
, iface
);
4288 TRACE_(ddraw_thunk
)("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4289 return IDirect3DDevice7_DrawIndexedPrimitiveStrided(ICOM_INTERFACE(This
, IDirect3DDevice7
),
4292 D3DDrawPrimStrideData
,
4299 /*****************************************************************************
4300 * IDirect3DDevice7::DrawPrimitiveVB
4302 * Draws primitives from a vertex buffer to the screen.
4307 * PrimitiveType: Type of primitive to be rendered.
4308 * D3DVertexBuf: Source Vertex Buffer
4309 * StartVertex: Index of the first vertex from the buffer to be rendered
4310 * NumVertices: Number of vertices to be rendered
4311 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4315 * DDERR_INVALIDPARAMS if D3DVertexBuf is NULL
4317 *****************************************************************************/
4319 IDirect3DDeviceImpl_7_DrawPrimitiveVB(IDirect3DDevice7
*iface
,
4320 D3DPRIMITIVETYPE PrimitiveType
,
4321 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4326 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
4327 IDirect3DVertexBufferImpl
*vb
= ICOM_OBJECT(IDirect3DVertexBufferImpl
, IDirect3DVertexBuffer7
, D3DVertexBuf
);
4328 UINT PrimitiveCount
;
4331 WINED3DVERTEXBUFFER_DESC Desc
;
4333 TRACE("(%p)->(%08x,%p,%08x,%08x,%08x)\n", This
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4338 ERR("(%p) No Vertex buffer specified\n", This
);
4339 return DDERR_INVALIDPARAMS
;
4342 /* Get the primitive count */
4343 switch(PrimitiveType
)
4345 case D3DPT_POINTLIST
:
4346 PrimitiveCount
= NumVertices
;
4349 case D3DPT_LINELIST
:
4350 PrimitiveCount
= NumVertices
/ 2;
4353 case D3DPT_LINESTRIP
:
4354 PrimitiveCount
= NumVertices
- 1;
4357 case D3DPT_TRIANGLELIST
:
4358 PrimitiveCount
= NumVertices
/ 3;
4361 case D3DPT_TRIANGLESTRIP
:
4362 PrimitiveCount
= NumVertices
- 2;
4365 case D3DPT_TRIANGLEFAN
:
4366 PrimitiveCount
= NumVertices
- 2;
4370 return DDERR_INVALIDPARAMS
;
4373 /* Get the FVF of the vertex buffer, and its stride */
4374 EnterCriticalSection(&ddraw_cs
);
4375 hr
= IWineD3DVertexBuffer_GetDesc(vb
->wineD3DVertexBuffer
,
4379 ERR("(%p) IWineD3DVertexBuffer::GetDesc failed with hr = %08x\n", This
, hr
);
4380 LeaveCriticalSection(&ddraw_cs
);
4383 stride
= get_flexible_vertex_size(Desc
.FVF
);
4385 hr
= IWineD3DDevice_SetVertexDeclaration(This
->wineD3DDevice
,
4386 vb
->wineD3DVertexDeclaration
);
4389 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This
, hr
);
4390 LeaveCriticalSection(&ddraw_cs
);
4394 /* Set the vertex stream source */
4395 hr
= IWineD3DDevice_SetStreamSource(This
->wineD3DDevice
,
4396 0 /* StreamNumber */,
4397 vb
->wineD3DVertexBuffer
,
4398 0 /* StartVertex - we pass this to DrawPrimitive */,
4402 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This
, hr
);
4403 LeaveCriticalSection(&ddraw_cs
);
4407 /* Now draw the primitives */
4408 hr
= IWineD3DDevice_DrawPrimitive(This
->wineD3DDevice
,
4412 LeaveCriticalSection(&ddraw_cs
);
4416 static HRESULT WINAPI
4417 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUSetup(IDirect3DDevice7
*iface
,
4418 D3DPRIMITIVETYPE PrimitiveType
,
4419 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4424 return IDirect3DDeviceImpl_7_DrawPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4427 static HRESULT WINAPI
4428 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUPreserve(IDirect3DDevice7
*iface
,
4429 D3DPRIMITIVETYPE PrimitiveType
,
4430 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4438 old_fpucw
= d3d_fpu_setup();
4439 hr
= IDirect3DDeviceImpl_7_DrawPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4440 set_fpu_control_word(old_fpucw
);
4445 static HRESULT WINAPI
4446 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB(IDirect3DDevice3
*iface
,
4447 D3DPRIMITIVETYPE PrimitiveType
,
4448 IDirect3DVertexBuffer
*D3DVertexBuf
,
4453 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice3
, iface
);
4454 IDirect3DVertexBufferImpl
*vb
= ICOM_OBJECT(IDirect3DVertexBufferImpl
, IDirect3DVertexBuffer
, D3DVertexBuf
);
4455 TRACE_(ddraw_thunk
)("(%p)->(%08x,%p,%08x,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This
, PrimitiveType
, vb
, StartVertex
, NumVertices
, Flags
);
4456 return IDirect3DDevice7_DrawPrimitiveVB(ICOM_INTERFACE(This
, IDirect3DDevice7
),
4458 ICOM_INTERFACE(vb
, IDirect3DVertexBuffer7
),
4465 /*****************************************************************************
4466 * IDirect3DDevice7::DrawIndexedPrimitiveVB
4468 * Draws primitives from a vertex buffer to the screen
4471 * PrimitiveType: Type of primitive to be rendered.
4472 * D3DVertexBuf: Source Vertex Buffer
4473 * StartVertex: Index of the first vertex from the buffer to be rendered
4474 * NumVertices: Number of vertices to be rendered
4475 * Indices: Array of DWORDs used to index into the Vertices
4476 * IndexCount: Number of indices in Indices
4477 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4481 *****************************************************************************/
4483 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(IDirect3DDevice7
*iface
,
4484 D3DPRIMITIVETYPE PrimitiveType
,
4485 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4492 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
4493 IDirect3DVertexBufferImpl
*vb
= ICOM_OBJECT(IDirect3DVertexBufferImpl
, IDirect3DVertexBuffer7
, D3DVertexBuf
);
4495 UINT PrimitiveCount
;
4496 WORD
*LockedIndices
;
4498 WINED3DVERTEXBUFFER_DESC Desc
;
4500 TRACE("(%p)->(%08x,%p,%d,%d,%p,%d,%08x)\n", This
, PrimitiveType
, vb
, StartVertex
, NumVertices
, Indices
, IndexCount
, Flags
);
4503 * 1) Calculate some things: Vertex count -> Primitive count, stride, ...
4504 * 2) Upload the Indices to the index buffer
4505 * 3) Set the index source
4506 * 4) Set the Vertex Buffer as the Stream source
4507 * 5) Call IWineD3DDevice::DrawIndexedPrimitive
4510 /* Get the primitive count */
4511 switch(PrimitiveType
)
4513 case D3DPT_POINTLIST
:
4514 PrimitiveCount
= IndexCount
;
4517 case D3DPT_LINELIST
:
4518 PrimitiveCount
= IndexCount
/ 2;
4521 case D3DPT_LINESTRIP
:
4522 PrimitiveCount
= IndexCount
- 1;
4525 case D3DPT_TRIANGLELIST
:
4526 PrimitiveCount
= IndexCount
/ 3;
4529 case D3DPT_TRIANGLESTRIP
:
4530 PrimitiveCount
= IndexCount
- 2;
4533 case D3DPT_TRIANGLEFAN
:
4534 PrimitiveCount
= IndexCount
- 2;
4537 default: return DDERR_INVALIDPARAMS
;
4540 EnterCriticalSection(&ddraw_cs
);
4541 /* Get the FVF of the vertex buffer, and its stride */
4542 hr
= IWineD3DVertexBuffer_GetDesc(vb
->wineD3DVertexBuffer
,
4546 ERR("(%p) IWineD3DVertexBuffer::GetDesc failed with hr = %08x\n", This
, hr
);
4547 LeaveCriticalSection(&ddraw_cs
);
4550 stride
= get_flexible_vertex_size(Desc
.FVF
);
4551 TRACE("Vertex buffer FVF = %08x, stride=%d\n", Desc
.FVF
, stride
);
4553 hr
= IWineD3DDevice_SetVertexDeclaration(This
->wineD3DDevice
,
4554 vb
->wineD3DVertexDeclaration
);
4557 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This
, hr
);
4558 LeaveCriticalSection(&ddraw_cs
);
4562 /* copy the index stream into the index buffer.
4563 * A new IWineD3DDevice method could be created
4564 * which takes an user pointer containing the indices
4565 * or a SetData-Method for the index buffer, which
4566 * overrides the index buffer data with our pointer.
4568 hr
= IWineD3DIndexBuffer_Lock(This
->indexbuffer
,
4569 0 /* OffSetToLock */,
4570 IndexCount
* sizeof(WORD
),
4571 (BYTE
**) &LockedIndices
,
4573 assert(IndexCount
< 0x100000);
4576 ERR("(%p) IWineD3DIndexBuffer::Lock failed with hr = %08x\n", This
, hr
);
4577 LeaveCriticalSection(&ddraw_cs
);
4580 memcpy(LockedIndices
, Indices
, IndexCount
* sizeof(WORD
));
4581 hr
= IWineD3DIndexBuffer_Unlock(This
->indexbuffer
);
4584 ERR("(%p) IWineD3DIndexBuffer::Unlock failed with hr = %08x\n", This
, hr
);
4585 LeaveCriticalSection(&ddraw_cs
);
4589 /* Set the index stream */
4590 IWineD3DDevice_SetBaseVertexIndex(This
->wineD3DDevice
, StartVertex
);
4591 hr
= IWineD3DDevice_SetIndices(This
->wineD3DDevice
, This
->indexbuffer
);
4593 /* Set the vertex stream source */
4594 hr
= IWineD3DDevice_SetStreamSource(This
->wineD3DDevice
,
4595 0 /* StreamNumber */,
4596 vb
->wineD3DVertexBuffer
,
4597 0 /* offset, we pass this to DrawIndexedPrimitive */,
4601 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This
, hr
);
4602 LeaveCriticalSection(&ddraw_cs
);
4607 hr
= IWineD3DDevice_DrawIndexedPrimitive(This
->wineD3DDevice
,
4614 LeaveCriticalSection(&ddraw_cs
);
4618 static HRESULT WINAPI
4619 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUSetup(IDirect3DDevice7
*iface
,
4620 D3DPRIMITIVETYPE PrimitiveType
,
4621 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4628 return IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Indices
, IndexCount
, Flags
);
4631 static HRESULT WINAPI
4632 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUPreserve(IDirect3DDevice7
*iface
,
4633 D3DPRIMITIVETYPE PrimitiveType
,
4634 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4644 old_fpucw
= d3d_fpu_setup();
4645 hr
= IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Indices
, IndexCount
, Flags
);
4646 set_fpu_control_word(old_fpucw
);
4651 static HRESULT WINAPI
4652 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB(IDirect3DDevice3
*iface
,
4653 D3DPRIMITIVETYPE PrimitiveType
,
4654 IDirect3DVertexBuffer
*D3DVertexBuf
,
4659 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice3
, iface
);
4660 IDirect3DVertexBufferImpl
*VB
= ICOM_OBJECT(IDirect3DVertexBufferImpl
, IDirect3DVertexBuffer
, D3DVertexBuf
);
4661 TRACE_(ddraw_thunk
)("(%p)->(%08x,%p,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This
, PrimitiveType
, VB
, Indices
, IndexCount
, Flags
);
4663 return IDirect3DDevice7_DrawIndexedPrimitiveVB(ICOM_INTERFACE(This
, IDirect3DDevice7
),
4665 ICOM_INTERFACE(VB
, IDirect3DVertexBuffer7
),
4673 /*****************************************************************************
4674 * IDirect3DDevice7::ComputeSphereVisibility
4676 * Calculates the visibility of spheres in the current viewport. The spheres
4677 * are passed in the Centers and Radii arrays, the results are passed back
4678 * in the ReturnValues array. Return values are either completely visible,
4679 * partially visible or completely invisible.
4680 * The return value consist of a combination of D3DCLIP_* flags, or it's
4681 * 0 if the sphere is completely visible(according to the SDK, not checked)
4683 * Sounds like an overdose of math ;)
4688 * Centers: Array containing the sphere centers
4689 * Radii: Array containing the sphere radii
4690 * NumSpheres: The number of centers and radii in the arrays
4692 * ReturnValues: Array to write the results to
4695 * D3D_OK because it's a stub
4696 * (DDERR_INVALIDPARAMS if Centers, Radii or ReturnValues are NULL)
4697 * (D3DERR_INVALIDMATRIX if the combined world, view and proj matrix
4700 *****************************************************************************/
4701 static HRESULT WINAPI
4702 IDirect3DDeviceImpl_7_ComputeSphereVisibility(IDirect3DDevice7
*iface
,
4707 DWORD
*ReturnValues
)
4709 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
4710 FIXME("(%p)->(%p,%p,%08x,%08x,%p): stub!\n", This
, Centers
, Radii
, NumSpheres
, Flags
, ReturnValues
);
4712 /* the DirectX 7 sdk says that the visibility is computed by
4713 * back-transforming the viewing frustum to model space
4714 * using the inverse of the combined world, view and projection
4715 * matrix. If the matrix can't be reversed, D3DERR_INVALIDMATRIX
4718 * Basic implementation idea:
4719 * 1) Check if the center is in the viewing frustum
4720 * 2) Cut the sphere with the planes of the viewing
4723 * ->Center inside the frustum, no intersections:
4725 * ->Center outside the frustum, no intersections:
4727 * ->Some intersections: Partially visible
4729 * Implement this call in WineD3D. Either implement the
4730 * matrix and vector stuff in WineD3D, or use some external
4737 static HRESULT WINAPI
4738 Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility(IDirect3DDevice3
*iface
,
4743 DWORD
*ReturnValues
)
4745 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice3
, iface
);
4746 TRACE_(ddraw_thunk
)("(%p)->(%p,%p,%08x,%08x,%p) thunking to IDirect3DDevice7 interface.\n", This
, Centers
, Radii
, NumSpheres
, Flags
, ReturnValues
);
4747 return IDirect3DDevice7_ComputeSphereVisibility(ICOM_INTERFACE(This
, IDirect3DDevice7
),
4755 /*****************************************************************************
4756 * IDirect3DDevice7::GetTexture
4758 * Returns the texture interface handle assigned to a texture stage.
4759 * The returned texture is AddRefed. This is taken from old ddraw,
4760 * not checked in Windows.
4765 * Stage: Texture stage to read the texture from
4766 * Texture: Address to store the interface pointer at
4770 * DDERR_INVALIDPARAMS if Texture is NULL
4771 * For details, see IWineD3DDevice::GetTexture
4773 *****************************************************************************/
4775 IDirect3DDeviceImpl_7_GetTexture(IDirect3DDevice7
*iface
,
4777 IDirectDrawSurface7
**Texture
)
4779 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
4780 IWineD3DBaseTexture
*Surf
;
4782 TRACE("(%p)->(%d,%p): Relay\n", This
, Stage
, Texture
);
4786 TRACE("Texture == NULL, failing with DDERR_INVALIDPARAMS\n");
4787 return DDERR_INVALIDPARAMS
;
4790 EnterCriticalSection(&ddraw_cs
);
4791 hr
= IWineD3DDevice_GetTexture(This
->wineD3DDevice
, Stage
, &Surf
);
4792 if( (hr
!= D3D_OK
) || (!Surf
) )
4795 LeaveCriticalSection(&ddraw_cs
);
4799 /* GetParent AddRef()s, which is perfectly OK.
4800 * We have passed the IDirectDrawSurface7 interface to WineD3D, so that's OK too.
4802 hr
= IWineD3DBaseTexture_GetParent(Surf
,
4803 (IUnknown
**) Texture
);
4804 LeaveCriticalSection(&ddraw_cs
);
4808 static HRESULT WINAPI
4809 IDirect3DDeviceImpl_7_GetTexture_FPUSetup(IDirect3DDevice7
*iface
,
4811 IDirectDrawSurface7
**Texture
)
4813 return IDirect3DDeviceImpl_7_GetTexture(iface
, Stage
, Texture
);
4816 static HRESULT WINAPI
4817 IDirect3DDeviceImpl_7_GetTexture_FPUPreserve(IDirect3DDevice7
*iface
,
4819 IDirectDrawSurface7
**Texture
)
4824 old_fpucw
= d3d_fpu_setup();
4825 hr
= IDirect3DDeviceImpl_7_GetTexture(iface
, Stage
, Texture
);
4826 set_fpu_control_word(old_fpucw
);
4831 static HRESULT WINAPI
4832 Thunk_IDirect3DDeviceImpl_3_GetTexture(IDirect3DDevice3
*iface
,
4834 IDirect3DTexture2
**Texture2
)
4836 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice3
, iface
);
4838 IDirectDrawSurface7
*ret_val
;
4840 TRACE_(ddraw_thunk
)("(%p)->(%d,%p) thunking to IDirect3DDevice7 interface.\n", This
, Stage
, Texture2
);
4841 ret
= IDirect3DDevice7_GetTexture(ICOM_INTERFACE(This
, IDirect3DDevice7
),
4845 *Texture2
= COM_INTERFACE_CAST(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, IDirect3DTexture2
, ret_val
);
4847 TRACE_(ddraw_thunk
)(" returning interface %p.\n", *Texture2
);
4852 /*****************************************************************************
4853 * IDirect3DDevice7::SetTexture
4855 * Assigns a texture to a texture stage. Is the texture AddRef-ed?
4860 * Stage: The stage to assign the texture to
4861 * Texture: Interface pointer to the texture surface
4865 * For details, see IWineD3DDevice::SetTexture
4867 *****************************************************************************/
4869 IDirect3DDeviceImpl_7_SetTexture(IDirect3DDevice7
*iface
,
4871 IDirectDrawSurface7
*Texture
)
4873 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
4874 IDirectDrawSurfaceImpl
*surf
= ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, Texture
);
4876 TRACE("(%p)->(%08x,%p): Relay!\n", This
, Stage
, surf
);
4878 /* Texture may be NULL here */
4879 EnterCriticalSection(&ddraw_cs
);
4880 hr
= IWineD3DDevice_SetTexture(This
->wineD3DDevice
,
4882 surf
? surf
->wineD3DTexture
: NULL
);
4883 LeaveCriticalSection(&ddraw_cs
);
4887 static HRESULT WINAPI
4888 IDirect3DDeviceImpl_7_SetTexture_FPUSetup(IDirect3DDevice7
*iface
,
4890 IDirectDrawSurface7
*Texture
)
4892 return IDirect3DDeviceImpl_7_SetTexture(iface
, Stage
, Texture
);
4895 static HRESULT WINAPI
4896 IDirect3DDeviceImpl_7_SetTexture_FPUPreserve(IDirect3DDevice7
*iface
,
4898 IDirectDrawSurface7
*Texture
)
4903 old_fpucw
= d3d_fpu_setup();
4904 hr
= IDirect3DDeviceImpl_7_SetTexture(iface
, Stage
, Texture
);
4905 set_fpu_control_word(old_fpucw
);
4910 static HRESULT WINAPI
4911 IDirect3DDeviceImpl_3_SetTexture(IDirect3DDevice3
*iface
,
4913 IDirect3DTexture2
*Texture2
)
4915 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice3
, iface
);
4916 IDirectDrawSurfaceImpl
*tex
= ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirect3DTexture2
, Texture2
);
4919 TRACE("(%p)->(%d,%p)\n", This
, Stage
, tex
);
4921 EnterCriticalSection(&ddraw_cs
);
4923 if (This
->legacyTextureBlending
)
4924 IDirect3DDevice3_GetRenderState(iface
, D3DRENDERSTATE_TEXTUREMAPBLEND
, &texmapblend
);
4926 hr
= IDirect3DDevice7_SetTexture(ICOM_INTERFACE(This
, IDirect3DDevice7
),
4928 ICOM_INTERFACE(tex
, IDirectDrawSurface7
));
4930 if (This
->legacyTextureBlending
&& texmapblend
== D3DTBLEND_MODULATE
)
4932 /* This fixup is required by the way D3DTBLEND_MODULATE maps to texture stage states.
4933 See IDirect3DDeviceImpl_3_SetRenderState for details. */
4934 BOOL tex_alpha
= FALSE
;
4935 IWineD3DBaseTexture
*tex
= NULL
;
4936 WINED3DSURFACE_DESC desc
;
4938 DDPIXELFORMAT ddfmt
;
4941 result
= IWineD3DDevice_GetTexture(This
->wineD3DDevice
,
4945 if(result
== WINED3D_OK
&& tex
)
4947 memset(&desc
, 0, sizeof(desc
));
4949 result
= IWineD3DTexture_GetLevelDesc((IWineD3DTexture
*) tex
, 0, &desc
);
4950 if (SUCCEEDED(result
))
4952 ddfmt
.dwSize
= sizeof(ddfmt
);
4953 PixelFormat_WineD3DtoDD(&ddfmt
, fmt
);
4954 if (ddfmt
.u5
.dwRGBAlphaBitMask
) tex_alpha
= TRUE
;
4957 IWineD3DBaseTexture_Release(tex
);
4960 /* alphaop is WINED3DTOP_SELECTARG1 if it's D3DTBLEND_MODULATE, so only modify alphaarg1 */
4963 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG1
, WINED3DTA_TEXTURE
);
4967 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG1
, WINED3DTA_CURRENT
);
4971 LeaveCriticalSection(&ddraw_cs
);
4976 /*****************************************************************************
4977 * IDirect3DDevice7::GetTextureStageState
4979 * Retrieves a state from a texture stage.
4984 * Stage: The stage to retrieve the state from
4985 * TexStageStateType: The state type to retrieve
4986 * State: Address to store the state's value at
4990 * DDERR_INVALIDPARAMS if State is NULL
4991 * For details, see IWineD3DDevice::GetTextureStageState
4993 *****************************************************************************/
4995 IDirect3DDeviceImpl_7_GetTextureStageState(IDirect3DDevice7
*iface
,
4997 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
5000 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
5002 TRACE("(%p)->(%08x,%08x,%p): Relay!\n", This
, Stage
, TexStageStateType
, State
);
5005 return DDERR_INVALIDPARAMS
;
5007 EnterCriticalSection(&ddraw_cs
);
5008 switch(TexStageStateType
)
5010 /* Mipfilter is a sampler state with different values */
5011 case D3DTSS_MIPFILTER
:
5013 WINED3DTEXTUREFILTERTYPE value
;
5015 hr
= IWineD3DDevice_GetSamplerState(This
->wineD3DDevice
,
5017 WINED3DSAMP_MIPFILTER
,
5021 case WINED3DTEXF_NONE
: *State
= D3DTFP_NONE
; break;
5022 case WINED3DTEXF_POINT
: *State
= D3DTFP_POINT
; break;
5023 case WINED3DTEXF_LINEAR
: *State
= D3DTFP_LINEAR
; break;
5025 ERR("Unexpected mipfilter value %d\n", value
);
5026 *State
= D3DTFP_NONE
;
5031 /* Minfilter is a sampler state too, equal values */
5032 case D3DTSS_MINFILTER
:
5033 hr
= IWineD3DDevice_GetSamplerState(This
->wineD3DDevice
,
5035 WINED3DSAMP_MINFILTER
,
5039 /* Magfilter has slightly different values */
5040 case D3DTSS_MAGFILTER
:
5042 WINED3DTEXTUREFILTERTYPE wined3dfilter
;
5043 hr
= IWineD3DDevice_GetSamplerState(This
->wineD3DDevice
,
5045 WINED3DSAMP_MAGFILTER
,
5047 switch(wined3dfilter
)
5049 case WINED3DTEXF_POINT
: *State
= D3DTFG_POINT
; break;
5050 case WINED3DTEXF_LINEAR
: *State
= D3DTFG_LINEAR
; break;
5051 case WINED3DTEXF_ANISOTROPIC
: *State
= D3DTFG_ANISOTROPIC
; break;
5052 case WINED3DTEXF_FLATCUBIC
: *State
= D3DTFG_FLATCUBIC
; break;
5053 case WINED3DTEXF_GAUSSIANCUBIC
: *State
= D3DTFG_GAUSSIANCUBIC
; break;
5055 ERR("Unexpected wined3d mag filter value %d\n", wined3dfilter
);
5056 *State
= D3DTFG_POINT
;
5061 case D3DTSS_ADDRESS
:
5062 case D3DTSS_ADDRESSU
:
5063 hr
= IWineD3DDevice_GetSamplerState(This
->wineD3DDevice
,
5065 WINED3DSAMP_ADDRESSU
,
5068 case D3DTSS_ADDRESSV
:
5069 hr
= IWineD3DDevice_GetSamplerState(This
->wineD3DDevice
,
5071 WINED3DSAMP_ADDRESSV
,
5075 hr
= IWineD3DDevice_GetTextureStageState(This
->wineD3DDevice
,
5081 LeaveCriticalSection(&ddraw_cs
);
5085 static HRESULT WINAPI
5086 IDirect3DDeviceImpl_7_GetTextureStageState_FPUSetup(IDirect3DDevice7
*iface
,
5088 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
5091 return IDirect3DDeviceImpl_7_GetTextureStageState(iface
, Stage
, TexStageStateType
, State
);
5094 static HRESULT WINAPI
5095 IDirect3DDeviceImpl_7_GetTextureStageState_FPUPreserve(IDirect3DDevice7
*iface
,
5097 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
5103 old_fpucw
= d3d_fpu_setup();
5104 hr
= IDirect3DDeviceImpl_7_GetTextureStageState(iface
, Stage
, TexStageStateType
, State
);
5105 set_fpu_control_word(old_fpucw
);
5110 static HRESULT WINAPI
5111 Thunk_IDirect3DDeviceImpl_3_GetTextureStageState(IDirect3DDevice3
*iface
,
5113 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
5116 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice3
, iface
);
5117 TRACE_(ddraw_thunk
)("(%p)->(%08x,%08x,%p) thunking to IDirect3DDevice7 interface.\n", This
, Stage
, TexStageStateType
, State
);
5118 return IDirect3DDevice7_GetTextureStageState(ICOM_INTERFACE(This
, IDirect3DDevice7
),
5124 /*****************************************************************************
5125 * IDirect3DDevice7::SetTextureStageState
5127 * Sets a texture stage state. Some stage types need to be handled specially,
5128 * because they do not exist in WineD3D and were moved to another place
5133 * Stage: The stage to modify
5134 * TexStageStateType: The state to change
5135 * State: The new value for the state
5139 * For details, see IWineD3DDevice::SetTextureStageState
5141 *****************************************************************************/
5143 IDirect3DDeviceImpl_7_SetTextureStageState(IDirect3DDevice7
*iface
,
5145 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
5148 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
5150 TRACE("(%p)->(%08x,%08x,%08x): Relay!\n", This
, Stage
, TexStageStateType
, State
);
5152 EnterCriticalSection(&ddraw_cs
);
5153 switch(TexStageStateType
)
5155 /* Mipfilter is a sampler state with different values */
5156 case D3DTSS_MIPFILTER
:
5158 WINED3DTEXTUREFILTERTYPE value
;
5161 case D3DTFP_NONE
: value
= WINED3DTEXF_NONE
; break;
5162 case D3DTFP_POINT
: value
= WINED3DTEXF_POINT
; break;
5163 case 0: /* Unchecked */
5164 case D3DTFP_LINEAR
: value
= WINED3DTEXF_LINEAR
; break;
5166 ERR("Unexpected mipfilter value %d\n", State
);
5167 value
= WINED3DTEXF_NONE
;
5169 hr
= IWineD3DDevice_SetSamplerState(This
->wineD3DDevice
,
5171 WINED3DSAMP_MIPFILTER
,
5176 /* Minfilter is a sampler state too, equal values */
5177 case D3DTSS_MINFILTER
:
5178 hr
= IWineD3DDevice_SetSamplerState(This
->wineD3DDevice
,
5180 WINED3DSAMP_MINFILTER
,
5184 /* Magfilter has slightly different values */
5185 case D3DTSS_MAGFILTER
:
5187 WINED3DTEXTUREFILTERTYPE wined3dfilter
;
5188 switch((D3DTEXTUREMAGFILTER
) State
)
5190 case D3DTFG_POINT
: wined3dfilter
= WINED3DTEXF_POINT
; break;
5191 case D3DTFG_LINEAR
: wined3dfilter
= WINED3DTEXF_LINEAR
; break;
5192 case D3DTFG_FLATCUBIC
: wined3dfilter
= WINED3DTEXF_FLATCUBIC
; break;
5193 case D3DTFG_GAUSSIANCUBIC
: wined3dfilter
= WINED3DTEXF_GAUSSIANCUBIC
; break;
5194 case D3DTFG_ANISOTROPIC
: wined3dfilter
= WINED3DTEXF_ANISOTROPIC
; break;
5196 ERR("Unexpected d3d7 mag filter type %d\n", State
);
5197 wined3dfilter
= WINED3DTEXF_POINT
;
5199 hr
= IWineD3DDevice_SetSamplerState(This
->wineD3DDevice
,
5201 WINED3DSAMP_MAGFILTER
,
5206 case D3DTSS_ADDRESS
:
5207 IWineD3DDevice_SetSamplerState(This
->wineD3DDevice
,
5209 WINED3DSAMP_ADDRESSV
,
5212 case D3DTSS_ADDRESSU
:
5213 hr
= IWineD3DDevice_SetSamplerState(This
->wineD3DDevice
,
5215 WINED3DSAMP_ADDRESSU
,
5219 case D3DTSS_ADDRESSV
:
5220 hr
= IWineD3DDevice_SetSamplerState(This
->wineD3DDevice
,
5222 WINED3DSAMP_ADDRESSV
,
5227 hr
= IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
,
5233 LeaveCriticalSection(&ddraw_cs
);
5237 static HRESULT WINAPI
5238 IDirect3DDeviceImpl_7_SetTextureStageState_FPUSetup(IDirect3DDevice7
*iface
,
5240 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
5243 return IDirect3DDeviceImpl_7_SetTextureStageState(iface
, Stage
, TexStageStateType
, State
);
5246 static HRESULT WINAPI
5247 IDirect3DDeviceImpl_7_SetTextureStageState_FPUPreserve(IDirect3DDevice7
*iface
,
5249 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
5255 old_fpucw
= d3d_fpu_setup();
5256 hr
= IDirect3DDeviceImpl_7_SetTextureStageState(iface
, Stage
, TexStageStateType
, State
);
5257 set_fpu_control_word(old_fpucw
);
5262 static HRESULT WINAPI
5263 Thunk_IDirect3DDeviceImpl_3_SetTextureStageState(IDirect3DDevice3
*iface
,
5265 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
5268 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice3
, iface
);
5269 TRACE_(ddraw_thunk
)("(%p)->(%08x,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This
, Stage
, TexStageStateType
, State
);
5270 return IDirect3DDevice7_SetTextureStageState(ICOM_INTERFACE(This
, IDirect3DDevice7
),
5276 /*****************************************************************************
5277 * IDirect3DDevice7::ValidateDevice
5279 * SDK: "Reports the device's ability to render the currently set
5280 * texture-blending operations in a single pass". Whatever that means
5286 * NumPasses: Address to write the number of necessary passes for the
5287 * desired effect to.
5291 * See IWineD3DDevice::ValidateDevice for more details
5293 *****************************************************************************/
5295 IDirect3DDeviceImpl_7_ValidateDevice(IDirect3DDevice7
*iface
,
5298 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
5300 TRACE("(%p)->(%p): Relay\n", This
, NumPasses
);
5302 EnterCriticalSection(&ddraw_cs
);
5303 hr
= IWineD3DDevice_ValidateDevice(This
->wineD3DDevice
, NumPasses
);
5304 LeaveCriticalSection(&ddraw_cs
);
5308 static HRESULT WINAPI
5309 IDirect3DDeviceImpl_7_ValidateDevice_FPUSetup(IDirect3DDevice7
*iface
,
5312 return IDirect3DDeviceImpl_7_ValidateDevice(iface
, NumPasses
);
5315 static HRESULT WINAPI
5316 IDirect3DDeviceImpl_7_ValidateDevice_FPUPreserve(IDirect3DDevice7
*iface
,
5322 old_fpucw
= d3d_fpu_setup();
5323 hr
= IDirect3DDeviceImpl_7_ValidateDevice(iface
, NumPasses
);
5324 set_fpu_control_word(old_fpucw
);
5329 static HRESULT WINAPI
5330 Thunk_IDirect3DDeviceImpl_3_ValidateDevice(IDirect3DDevice3
*iface
,
5333 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice3
, iface
);
5334 TRACE_(ddraw_thunk
)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This
, Passes
);
5335 return IDirect3DDevice7_ValidateDevice(ICOM_INTERFACE(This
, IDirect3DDevice7
),
5339 /*****************************************************************************
5340 * IDirect3DDevice7::Clear
5342 * Fills the render target, the z buffer and the stencil buffer with a
5343 * clear color / value
5348 * Count: Number of rectangles in Rects must be 0 if Rects is NULL
5349 * Rects: Rectangles to clear. If NULL, the whole surface is cleared
5350 * Flags: Some flags, as usual
5351 * Color: Clear color for the render target
5352 * Z: Clear value for the Z buffer
5353 * Stencil: Clear value to store in each stencil buffer entry
5357 * For details, see IWineD3DDevice::Clear
5359 *****************************************************************************/
5361 IDirect3DDeviceImpl_7_Clear(IDirect3DDevice7
*iface
,
5369 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
5371 TRACE("(%p)->(%08x,%p,%08x,%08x,%f,%08x): Relay\n", This
, Count
, Rects
, Flags
, Color
, Z
, Stencil
);
5373 /* Note; D3DRECT is compatible with WINED3DRECT */
5374 EnterCriticalSection(&ddraw_cs
);
5375 hr
= IWineD3DDevice_Clear(This
->wineD3DDevice
, Count
, (WINED3DRECT
*) Rects
, Flags
, Color
, Z
, Stencil
);
5376 LeaveCriticalSection(&ddraw_cs
);
5380 static HRESULT WINAPI
5381 IDirect3DDeviceImpl_7_Clear_FPUSetup(IDirect3DDevice7
*iface
,
5389 return IDirect3DDeviceImpl_7_Clear(iface
, Count
, Rects
, Flags
, Color
, Z
, Stencil
);
5392 static HRESULT WINAPI
5393 IDirect3DDeviceImpl_7_Clear_FPUPreserve(IDirect3DDevice7
*iface
,
5404 old_fpucw
= d3d_fpu_setup();
5405 hr
= IDirect3DDeviceImpl_7_Clear(iface
, Count
, Rects
, Flags
, Color
, Z
, Stencil
);
5406 set_fpu_control_word(old_fpucw
);
5411 /*****************************************************************************
5412 * IDirect3DDevice7::SetViewport
5414 * Sets the current viewport.
5416 * Version 7 only, but IDirect3DViewport uses this call for older
5420 * Data: The new viewport to set
5424 * DDERR_INVALIDPARAMS if Data is NULL
5425 * For more details, see IWineDDDevice::SetViewport
5427 *****************************************************************************/
5429 IDirect3DDeviceImpl_7_SetViewport(IDirect3DDevice7
*iface
,
5432 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
5434 TRACE("(%p)->(%p) Relay!\n", This
, Data
);
5437 return DDERR_INVALIDPARAMS
;
5439 /* Note: D3DVIEWPORT7 is compatible with WINED3DVIEWPORT */
5440 EnterCriticalSection(&ddraw_cs
);
5441 hr
= IWineD3DDevice_SetViewport(This
->wineD3DDevice
,
5442 (WINED3DVIEWPORT
*) Data
);
5443 LeaveCriticalSection(&ddraw_cs
);
5447 static HRESULT WINAPI
5448 IDirect3DDeviceImpl_7_SetViewport_FPUSetup(IDirect3DDevice7
*iface
,
5451 return IDirect3DDeviceImpl_7_SetViewport(iface
, Data
);
5454 static HRESULT WINAPI
5455 IDirect3DDeviceImpl_7_SetViewport_FPUPreserve(IDirect3DDevice7
*iface
,
5461 old_fpucw
= d3d_fpu_setup();
5462 hr
= IDirect3DDeviceImpl_7_SetViewport(iface
, Data
);
5463 set_fpu_control_word(old_fpucw
);
5468 /*****************************************************************************
5469 * IDirect3DDevice::GetViewport
5471 * Returns the current viewport
5476 * Data: D3D7Viewport structure to write the viewport information to
5480 * DDERR_INVALIDPARAMS if Data is NULL
5481 * For more details, see IWineD3DDevice::GetViewport
5483 *****************************************************************************/
5485 IDirect3DDeviceImpl_7_GetViewport(IDirect3DDevice7
*iface
,
5488 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
5490 TRACE("(%p)->(%p) Relay!\n", This
, Data
);
5493 return DDERR_INVALIDPARAMS
;
5495 /* Note: D3DVIEWPORT7 is compatible with WINED3DVIEWPORT */
5496 EnterCriticalSection(&ddraw_cs
);
5497 hr
= IWineD3DDevice_GetViewport(This
->wineD3DDevice
,
5498 (WINED3DVIEWPORT
*) Data
);
5500 LeaveCriticalSection(&ddraw_cs
);
5501 return hr_ddraw_from_wined3d(hr
);
5504 static HRESULT WINAPI
5505 IDirect3DDeviceImpl_7_GetViewport_FPUSetup(IDirect3DDevice7
*iface
,
5508 return IDirect3DDeviceImpl_7_GetViewport(iface
, Data
);
5511 static HRESULT WINAPI
5512 IDirect3DDeviceImpl_7_GetViewport_FPUPreserve(IDirect3DDevice7
*iface
,
5518 old_fpucw
= d3d_fpu_setup();
5519 hr
= IDirect3DDeviceImpl_7_GetViewport(iface
, Data
);
5520 set_fpu_control_word(old_fpucw
);
5525 /*****************************************************************************
5526 * IDirect3DDevice7::SetMaterial
5533 * Mat: The material to set
5537 * DDERR_INVALIDPARAMS if Mat is NULL.
5538 * For more details, see IWineD3DDevice::SetMaterial
5540 *****************************************************************************/
5542 IDirect3DDeviceImpl_7_SetMaterial(IDirect3DDevice7
*iface
,
5545 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
5547 TRACE("(%p)->(%p): Relay!\n", This
, Mat
);
5549 if (!Mat
) return DDERR_INVALIDPARAMS
;
5550 /* Note: D3DMATERIAL7 is compatible with WINED3DMATERIAL */
5551 EnterCriticalSection(&ddraw_cs
);
5552 hr
= IWineD3DDevice_SetMaterial(This
->wineD3DDevice
,
5553 (WINED3DMATERIAL
*) Mat
);
5554 LeaveCriticalSection(&ddraw_cs
);
5555 return hr_ddraw_from_wined3d(hr
);
5558 static HRESULT WINAPI
5559 IDirect3DDeviceImpl_7_SetMaterial_FPUSetup(IDirect3DDevice7
*iface
,
5562 return IDirect3DDeviceImpl_7_SetMaterial(iface
, Mat
);
5565 static HRESULT WINAPI
5566 IDirect3DDeviceImpl_7_SetMaterial_FPUPreserve(IDirect3DDevice7
*iface
,
5572 old_fpucw
= d3d_fpu_setup();
5573 hr
= IDirect3DDeviceImpl_7_SetMaterial(iface
, Mat
);
5574 set_fpu_control_word(old_fpucw
);
5579 /*****************************************************************************
5580 * IDirect3DDevice7::GetMaterial
5582 * Returns the current material
5587 * Mat: D3DMATERIAL7 structure to write the material parameters to
5591 * DDERR_INVALIDPARAMS if Mat is NULL
5592 * For more details, see IWineD3DDevice::GetMaterial
5594 *****************************************************************************/
5596 IDirect3DDeviceImpl_7_GetMaterial(IDirect3DDevice7
*iface
,
5599 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
5601 TRACE("(%p)->(%p): Relay!\n", This
, Mat
);
5603 EnterCriticalSection(&ddraw_cs
);
5604 /* Note: D3DMATERIAL7 is compatible with WINED3DMATERIAL */
5605 hr
= IWineD3DDevice_GetMaterial(This
->wineD3DDevice
,
5606 (WINED3DMATERIAL
*) Mat
);
5607 LeaveCriticalSection(&ddraw_cs
);
5608 return hr_ddraw_from_wined3d(hr
);
5611 static HRESULT WINAPI
5612 IDirect3DDeviceImpl_7_GetMaterial_FPUSetup(IDirect3DDevice7
*iface
,
5615 return IDirect3DDeviceImpl_7_GetMaterial(iface
, Mat
);
5618 static HRESULT WINAPI
5619 IDirect3DDeviceImpl_7_GetMaterial_FPUPreserve(IDirect3DDevice7
*iface
,
5625 old_fpucw
= d3d_fpu_setup();
5626 hr
= IDirect3DDeviceImpl_7_GetMaterial(iface
, Mat
);
5627 set_fpu_control_word(old_fpucw
);
5632 /*****************************************************************************
5633 * IDirect3DDevice7::SetLight
5635 * Assigns a light to a light index, but doesn't activate it yet.
5637 * Version 7, IDirect3DLight uses this method for older versions
5640 * LightIndex: The index of the new light
5641 * Light: A D3DLIGHT7 structure describing the light
5645 * For more details, see IWineD3DDevice::SetLight
5647 *****************************************************************************/
5649 IDirect3DDeviceImpl_7_SetLight(IDirect3DDevice7
*iface
,
5653 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
5655 TRACE("(%p)->(%08x,%p): Relay!\n", This
, LightIndex
, Light
);
5657 EnterCriticalSection(&ddraw_cs
);
5658 /* Note: D3DLIGHT7 is compatible with WINED3DLIGHT */
5659 hr
= IWineD3DDevice_SetLight(This
->wineD3DDevice
,
5661 (WINED3DLIGHT
*) Light
);
5662 LeaveCriticalSection(&ddraw_cs
);
5663 return hr_ddraw_from_wined3d(hr
);
5666 static HRESULT WINAPI
5667 IDirect3DDeviceImpl_7_SetLight_FPUSetup(IDirect3DDevice7
*iface
,
5671 return IDirect3DDeviceImpl_7_SetLight(iface
, LightIndex
, Light
);
5674 static HRESULT WINAPI
5675 IDirect3DDeviceImpl_7_SetLight_FPUPreserve(IDirect3DDevice7
*iface
,
5682 old_fpucw
= d3d_fpu_setup();
5683 hr
= IDirect3DDeviceImpl_7_SetLight(iface
, LightIndex
, Light
);
5684 set_fpu_control_word(old_fpucw
);
5689 /*****************************************************************************
5690 * IDirect3DDevice7::GetLight
5692 * Returns the light assigned to a light index
5695 * Light: Structure to write the light information to
5699 * DDERR_INVALIDPARAMS if Light is NULL
5700 * For details, see IWineD3DDevice::GetLight
5702 *****************************************************************************/
5704 IDirect3DDeviceImpl_7_GetLight(IDirect3DDevice7
*iface
,
5708 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
5710 TRACE("(%p)->(%08x,%p): Relay!\n", This
, LightIndex
, Light
);
5712 EnterCriticalSection(&ddraw_cs
);
5713 /* Note: D3DLIGHT7 is compatible with WINED3DLIGHT */
5714 rc
= IWineD3DDevice_GetLight(This
->wineD3DDevice
,
5716 (WINED3DLIGHT
*) Light
);
5718 /* Translate the result. WineD3D returns other values than D3D7 */
5719 LeaveCriticalSection(&ddraw_cs
);
5720 return hr_ddraw_from_wined3d(rc
);
5723 static HRESULT WINAPI
5724 IDirect3DDeviceImpl_7_GetLight_FPUSetup(IDirect3DDevice7
*iface
,
5728 return IDirect3DDeviceImpl_7_GetLight(iface
, LightIndex
, Light
);
5731 static HRESULT WINAPI
5732 IDirect3DDeviceImpl_7_GetLight_FPUPreserve(IDirect3DDevice7
*iface
,
5739 old_fpucw
= d3d_fpu_setup();
5740 hr
= IDirect3DDeviceImpl_7_GetLight(iface
, LightIndex
, Light
);
5741 set_fpu_control_word(old_fpucw
);
5746 /*****************************************************************************
5747 * IDirect3DDevice7::BeginStateBlock
5749 * Begins recording to a stateblock
5755 * For details see IWineD3DDevice::BeginStateBlock
5757 *****************************************************************************/
5759 IDirect3DDeviceImpl_7_BeginStateBlock(IDirect3DDevice7
*iface
)
5761 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
5763 TRACE("(%p)->(): Relay!\n", This
);
5765 EnterCriticalSection(&ddraw_cs
);
5766 hr
= IWineD3DDevice_BeginStateBlock(This
->wineD3DDevice
);
5767 LeaveCriticalSection(&ddraw_cs
);
5768 return hr_ddraw_from_wined3d(hr
);
5771 static HRESULT WINAPI
5772 IDirect3DDeviceImpl_7_BeginStateBlock_FPUSetup(IDirect3DDevice7
*iface
)
5774 return IDirect3DDeviceImpl_7_BeginStateBlock(iface
);
5777 static HRESULT WINAPI
5778 IDirect3DDeviceImpl_7_BeginStateBlock_FPUPreserve(IDirect3DDevice7
*iface
)
5783 old_fpucw
= d3d_fpu_setup();
5784 hr
= IDirect3DDeviceImpl_7_BeginStateBlock(iface
);
5785 set_fpu_control_word(old_fpucw
);
5790 /*****************************************************************************
5791 * IDirect3DDevice7::EndStateBlock
5793 * Stops recording to a state block and returns the created stateblock
5799 * BlockHandle: Address to store the stateblock's handle to
5803 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5804 * See IWineD3DDevice::EndStateBlock for more details
5806 *****************************************************************************/
5808 IDirect3DDeviceImpl_7_EndStateBlock(IDirect3DDevice7
*iface
,
5811 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
5813 TRACE("(%p)->(%p): Relay!\n", This
, BlockHandle
);
5817 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
5818 return DDERR_INVALIDPARAMS
;
5821 EnterCriticalSection(&ddraw_cs
);
5822 *BlockHandle
= IDirect3DDeviceImpl_CreateHandle(This
);
5825 ERR("Cannot get a handle number for the stateblock\n");
5826 LeaveCriticalSection(&ddraw_cs
);
5827 return DDERR_OUTOFMEMORY
;
5829 This
->Handles
[*BlockHandle
- 1].type
= DDrawHandle_StateBlock
;
5830 hr
= IWineD3DDevice_EndStateBlock(This
->wineD3DDevice
,
5831 (IWineD3DStateBlock
**) &This
->Handles
[*BlockHandle
- 1].ptr
);
5832 LeaveCriticalSection(&ddraw_cs
);
5833 return hr_ddraw_from_wined3d(hr
);
5836 static HRESULT WINAPI
5837 IDirect3DDeviceImpl_7_EndStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5840 return IDirect3DDeviceImpl_7_EndStateBlock(iface
, BlockHandle
);
5843 static HRESULT WINAPI
5844 IDirect3DDeviceImpl_7_EndStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5850 old_fpucw
= d3d_fpu_setup();
5851 hr
= IDirect3DDeviceImpl_7_EndStateBlock(iface
, BlockHandle
);
5852 set_fpu_control_word(old_fpucw
);
5857 /*****************************************************************************
5858 * IDirect3DDevice7::PreLoad
5860 * Allows the app to signal that a texture will be used soon, to allow
5861 * the Direct3DDevice to load it to the video card in the meantime.
5866 * Texture: The texture to preload
5870 * DDERR_INVALIDPARAMS if Texture is NULL
5871 * See IWineD3DSurface::PreLoad for details
5873 *****************************************************************************/
5875 IDirect3DDeviceImpl_7_PreLoad(IDirect3DDevice7
*iface
,
5876 IDirectDrawSurface7
*Texture
)
5878 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
5879 IDirectDrawSurfaceImpl
*surf
= ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, Texture
);
5881 TRACE("(%p)->(%p): Relay!\n", This
, surf
);
5884 return DDERR_INVALIDPARAMS
;
5886 EnterCriticalSection(&ddraw_cs
);
5887 IWineD3DSurface_PreLoad(surf
->WineD3DSurface
);
5888 LeaveCriticalSection(&ddraw_cs
);
5892 static HRESULT WINAPI
5893 IDirect3DDeviceImpl_7_PreLoad_FPUSetup(IDirect3DDevice7
*iface
,
5894 IDirectDrawSurface7
*Texture
)
5896 return IDirect3DDeviceImpl_7_PreLoad(iface
, Texture
);
5899 static HRESULT WINAPI
5900 IDirect3DDeviceImpl_7_PreLoad_FPUPreserve(IDirect3DDevice7
*iface
,
5901 IDirectDrawSurface7
*Texture
)
5906 old_fpucw
= d3d_fpu_setup();
5907 hr
= IDirect3DDeviceImpl_7_PreLoad(iface
, Texture
);
5908 set_fpu_control_word(old_fpucw
);
5913 /*****************************************************************************
5914 * IDirect3DDevice7::ApplyStateBlock
5916 * Activates the state stored in a state block handle.
5919 * BlockHandle: The stateblock handle to activate
5923 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5925 *****************************************************************************/
5927 IDirect3DDeviceImpl_7_ApplyStateBlock(IDirect3DDevice7
*iface
,
5930 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
5932 TRACE("(%p)->(%08x): Relay!\n", This
, BlockHandle
);
5934 EnterCriticalSection(&ddraw_cs
);
5935 if(!BlockHandle
|| BlockHandle
> This
->numHandles
)
5937 WARN("Out of range handle %d, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle
);
5938 LeaveCriticalSection(&ddraw_cs
);
5939 return D3DERR_INVALIDSTATEBLOCK
;
5941 if(This
->Handles
[BlockHandle
- 1].type
!= DDrawHandle_StateBlock
)
5943 WARN("Handle %d is not a stateblock, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle
);
5944 LeaveCriticalSection(&ddraw_cs
);
5945 return D3DERR_INVALIDSTATEBLOCK
;
5948 hr
= IWineD3DStateBlock_Apply((IWineD3DStateBlock
*) This
->Handles
[BlockHandle
- 1].ptr
);
5949 LeaveCriticalSection(&ddraw_cs
);
5950 return hr_ddraw_from_wined3d(hr
);
5953 static HRESULT WINAPI
5954 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5957 return IDirect3DDeviceImpl_7_ApplyStateBlock(iface
, BlockHandle
);
5960 static HRESULT WINAPI
5961 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5967 old_fpucw
= d3d_fpu_setup();
5968 hr
= IDirect3DDeviceImpl_7_ApplyStateBlock(iface
, BlockHandle
);
5969 set_fpu_control_word(old_fpucw
);
5974 /*****************************************************************************
5975 * IDirect3DDevice7::CaptureStateBlock
5977 * Updates a stateblock's values to the values currently set for the device
5982 * BlockHandle: Stateblock to update
5986 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5987 * See IWineD3DDevice::CaptureStateBlock for more details
5989 *****************************************************************************/
5991 IDirect3DDeviceImpl_7_CaptureStateBlock(IDirect3DDevice7
*iface
,
5994 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
5996 TRACE("(%p)->(%08x): Relay!\n", This
, BlockHandle
);
5998 EnterCriticalSection(&ddraw_cs
);
5999 if(BlockHandle
== 0 || BlockHandle
> This
->numHandles
)
6001 WARN("Out of range handle %d, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle
);
6002 LeaveCriticalSection(&ddraw_cs
);
6003 return D3DERR_INVALIDSTATEBLOCK
;
6005 if(This
->Handles
[BlockHandle
- 1].type
!= DDrawHandle_StateBlock
)
6007 WARN("Handle %d is not a stateblock, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle
);
6008 LeaveCriticalSection(&ddraw_cs
);
6009 return D3DERR_INVALIDSTATEBLOCK
;
6012 hr
= IWineD3DStateBlock_Capture((IWineD3DStateBlock
*) This
->Handles
[BlockHandle
- 1].ptr
);
6013 LeaveCriticalSection(&ddraw_cs
);
6014 return hr_ddraw_from_wined3d(hr
);
6017 static HRESULT WINAPI
6018 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
6021 return IDirect3DDeviceImpl_7_CaptureStateBlock(iface
, BlockHandle
);
6024 static HRESULT WINAPI
6025 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
6031 old_fpucw
= d3d_fpu_setup();
6032 hr
= IDirect3DDeviceImpl_7_CaptureStateBlock(iface
, BlockHandle
);
6033 set_fpu_control_word(old_fpucw
);
6038 /*****************************************************************************
6039 * IDirect3DDevice7::DeleteStateBlock
6041 * Deletes a stateblock handle. This means releasing the WineD3DStateBlock
6046 * BlockHandle: Stateblock handle to delete
6050 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is 0
6052 *****************************************************************************/
6054 IDirect3DDeviceImpl_7_DeleteStateBlock(IDirect3DDevice7
*iface
,
6057 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
6059 TRACE("(%p)->(%08x): Relay!\n", This
, BlockHandle
);
6061 EnterCriticalSection(&ddraw_cs
);
6062 if(BlockHandle
== 0 || BlockHandle
> This
->numHandles
)
6064 WARN("Out of range handle %d, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle
);
6065 LeaveCriticalSection(&ddraw_cs
);
6066 return D3DERR_INVALIDSTATEBLOCK
;
6068 if(This
->Handles
[BlockHandle
- 1].type
!= DDrawHandle_StateBlock
)
6070 WARN("Handle %d is not a stateblock, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle
);
6071 LeaveCriticalSection(&ddraw_cs
);
6072 return D3DERR_INVALIDSTATEBLOCK
;
6075 ref
= IWineD3DStateBlock_Release((IWineD3DStateBlock
*) This
->Handles
[BlockHandle
- 1].ptr
);
6078 ERR("Something is still holding the stateblock %p(Handle %d). Ref = %d\n", This
->Handles
[BlockHandle
- 1].ptr
, BlockHandle
, ref
);
6080 This
->Handles
[BlockHandle
- 1].ptr
= NULL
;
6081 This
->Handles
[BlockHandle
- 1].type
= DDrawHandle_Unknown
;
6083 LeaveCriticalSection(&ddraw_cs
);
6087 static HRESULT WINAPI
6088 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
6091 return IDirect3DDeviceImpl_7_DeleteStateBlock(iface
, BlockHandle
);
6094 static HRESULT WINAPI
6095 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
6101 old_fpucw
= d3d_fpu_setup();
6102 hr
= IDirect3DDeviceImpl_7_DeleteStateBlock(iface
, BlockHandle
);
6103 set_fpu_control_word(old_fpucw
);
6108 /*****************************************************************************
6109 * IDirect3DDevice7::CreateStateBlock
6111 * Creates a new state block handle.
6116 * Type: The state block type
6117 * BlockHandle: Address to write the created handle to
6121 * DDERR_INVALIDPARAMS if BlockHandle is NULL
6123 *****************************************************************************/
6125 IDirect3DDeviceImpl_7_CreateStateBlock(IDirect3DDevice7
*iface
,
6126 D3DSTATEBLOCKTYPE Type
,
6129 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
6131 TRACE("(%p)->(%08x,%p)!\n", This
, Type
, BlockHandle
);
6135 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
6136 return DDERR_INVALIDPARAMS
;
6138 if(Type
!= D3DSBT_ALL
&& Type
!= D3DSBT_PIXELSTATE
&&
6139 Type
!= D3DSBT_VERTEXSTATE
) {
6140 WARN("Unexpected stateblock type, returning DDERR_INVALIDPARAMS\n");
6141 return DDERR_INVALIDPARAMS
;
6144 EnterCriticalSection(&ddraw_cs
);
6145 *BlockHandle
= IDirect3DDeviceImpl_CreateHandle(This
);
6148 ERR("Cannot get a handle number for the stateblock\n");
6149 LeaveCriticalSection(&ddraw_cs
);
6150 return DDERR_OUTOFMEMORY
;
6152 This
->Handles
[*BlockHandle
- 1].type
= DDrawHandle_StateBlock
;
6154 /* The D3DSTATEBLOCKTYPE enum is fine here */
6155 hr
= IWineD3DDevice_CreateStateBlock(This
->wineD3DDevice
,
6157 (IWineD3DStateBlock
**) &This
->Handles
[*BlockHandle
- 1].ptr
,
6158 NULL
/* Parent, hope that works */);
6159 LeaveCriticalSection(&ddraw_cs
);
6160 return hr_ddraw_from_wined3d(hr
);
6163 static HRESULT WINAPI
6164 IDirect3DDeviceImpl_7_CreateStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
6165 D3DSTATEBLOCKTYPE Type
,
6168 return IDirect3DDeviceImpl_7_CreateStateBlock(iface
, Type
, BlockHandle
);
6171 static HRESULT WINAPI
6172 IDirect3DDeviceImpl_7_CreateStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
6173 D3DSTATEBLOCKTYPE Type
,
6179 old_fpucw
= d3d_fpu_setup();
6180 hr
=IDirect3DDeviceImpl_7_CreateStateBlock(iface
, Type
, BlockHandle
);
6181 set_fpu_control_word(old_fpucw
);
6186 /* Helper function for IDirect3DDeviceImpl_7_Load. */
6187 static BOOL
is_mip_level_subset(IDirectDrawSurfaceImpl
*dest
,
6188 IDirectDrawSurfaceImpl
*src
)
6190 IDirectDrawSurfaceImpl
*src_level
, *dest_level
;
6191 IDirectDrawSurface7
*temp
;
6192 DDSURFACEDESC2 ddsd
;
6193 BOOL levelFound
; /* at least one suitable sublevel in dest found */
6195 /* To satisfy "destination is mip level subset of source" criteria (regular texture counts as 1 level),
6196 * 1) there must be at least one mip level in destination that matched dimensions of some mip level in source and
6197 * 2) there must be no destination levels that don't match any levels in source. Otherwise it's INVALIDPARAMS.
6204 for (;src_level
&& dest_level
;)
6206 if (src_level
->surface_desc
.dwWidth
== dest_level
->surface_desc
.dwWidth
&&
6207 src_level
->surface_desc
.dwHeight
== dest_level
->surface_desc
.dwHeight
)
6211 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6212 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
6213 IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(dest_level
, IDirectDrawSurface7
), &ddsd
.ddsCaps
, &temp
);
6215 if (dest_level
!= dest
) IDirectDrawSurface7_Release(ICOM_INTERFACE(dest_level
, IDirectDrawSurface7
));
6217 dest_level
= ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, temp
);
6220 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6221 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
6222 IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(src_level
, IDirectDrawSurface7
), &ddsd
.ddsCaps
, &temp
);
6224 if (src_level
!= src
) IDirectDrawSurface7_Release(ICOM_INTERFACE(src_level
, IDirectDrawSurface7
));
6226 src_level
= ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, temp
);
6229 if (src_level
&& src_level
!= src
) IDirectDrawSurface7_Release(ICOM_INTERFACE(src_level
, IDirectDrawSurface7
));
6230 if (dest_level
&& dest_level
!= dest
) IDirectDrawSurface7_Release(ICOM_INTERFACE(dest_level
, IDirectDrawSurface7
));
6232 return !dest_level
&& levelFound
;
6235 /* Helper function for IDirect3DDeviceImpl_7_Load. */
6236 static void copy_mipmap_chain(IDirect3DDeviceImpl
*device
,
6237 IDirectDrawSurfaceImpl
*dest
,
6238 IDirectDrawSurfaceImpl
*src
,
6242 IDirectDrawSurfaceImpl
*src_level
, *dest_level
;
6243 IDirectDrawSurface7
*temp
;
6244 DDSURFACEDESC2 ddsd
;
6248 IDirectDrawPalette
*pal
= NULL
, *pal_src
= NULL
;
6251 BOOL palette_missing
= FALSE
;
6253 /* Copy palette, if possible. */
6254 IDirectDrawSurface7_GetPalette(ICOM_INTERFACE(src
, IDirectDrawSurface7
), &pal_src
);
6255 IDirectDrawSurface7_GetPalette(ICOM_INTERFACE(dest
, IDirectDrawSurface7
), &pal
);
6257 if (pal_src
!= NULL
&& pal
!= NULL
)
6259 PALETTEENTRY palent
[256];
6261 IDirectDrawPalette_GetEntries(pal_src
, 0, 0, 256, palent
);
6262 IDirectDrawPalette_SetEntries(pal
, 0, 0, 256, palent
);
6265 if (dest
->surface_desc
.u4
.ddpfPixelFormat
.dwFlags
& (DDPF_PALETTEINDEXED1
| DDPF_PALETTEINDEXED2
|
6266 DDPF_PALETTEINDEXED4
| DDPF_PALETTEINDEXED8
| DDPF_PALETTEINDEXEDTO8
) && !pal
)
6268 palette_missing
= TRUE
;
6271 if (pal
) IDirectDrawPalette_Release(pal
);
6272 if (pal_src
) IDirectDrawPalette_Release(pal_src
);
6274 /* Copy colorkeys, if present. */
6275 for (ckeyflag
= DDCKEY_DESTBLT
; ckeyflag
<= DDCKEY_SRCOVERLAY
; ckeyflag
<<= 1)
6277 hr
= IDirectDrawSurface7_GetColorKey(ICOM_INTERFACE(src
, IDirectDrawSurface7
), ckeyflag
, &ddckey
);
6281 IDirectDrawSurface7_SetColorKey(ICOM_INTERFACE(dest
, IDirectDrawSurface7
), ckeyflag
, &ddckey
);
6291 for (;src_level
&& dest_level
;)
6293 if (src_level
->surface_desc
.dwWidth
== dest_level
->surface_desc
.dwWidth
&&
6294 src_level
->surface_desc
.dwHeight
== dest_level
->surface_desc
.dwHeight
)
6296 /* Try UpdateSurface that may perform a more direct opengl loading. But skip this if destination is paletted texture and has no palette.
6297 * Some games like Sacrifice set palette after Load, and it is a waste of effort to try to load texture without palette and generates
6298 * warnings in wined3d. */
6299 if (!palette_missing
)
6300 hr
= IWineD3DDevice_UpdateSurface(device
->wineD3DDevice
, src_level
->WineD3DSurface
, &rect
, dest_level
->WineD3DSurface
,
6303 if (palette_missing
|| FAILED(hr
))
6305 /* UpdateSurface may fail e.g. if dest is in system memory. Fall back to BltFast that is less strict. */
6306 IWineD3DSurface_BltFast(dest_level
->WineD3DSurface
,
6308 src_level
->WineD3DSurface
, &rect
, 0);
6311 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6312 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
6313 IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(dest_level
, IDirectDrawSurface7
), &ddsd
.ddsCaps
, &temp
);
6315 if (dest_level
!= dest
) IDirectDrawSurface7_Release(ICOM_INTERFACE(dest_level
, IDirectDrawSurface7
));
6317 dest_level
= ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, temp
);
6320 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6321 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
6322 IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(src_level
, IDirectDrawSurface7
), &ddsd
.ddsCaps
, &temp
);
6324 if (src_level
!= src
) IDirectDrawSurface7_Release(ICOM_INTERFACE(src_level
, IDirectDrawSurface7
));
6326 src_level
= ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, temp
);
6333 rect
.right
= (rect
.right
+ 1) / 2;
6334 rect
.bottom
= (rect
.bottom
+ 1) / 2;
6337 if (src_level
&& src_level
!= src
) IDirectDrawSurface7_Release(ICOM_INTERFACE(src_level
, IDirectDrawSurface7
));
6338 if (dest_level
&& dest_level
!= dest
) IDirectDrawSurface7_Release(ICOM_INTERFACE(dest_level
, IDirectDrawSurface7
));
6341 /*****************************************************************************
6342 * IDirect3DDevice7::Load
6344 * Loads a rectangular area from the source into the destination texture.
6345 * It can also copy the source to the faces of a cubic environment map
6350 * DestTex: Destination texture
6351 * DestPoint: Point in the destination where the source image should be
6353 * SrcTex: Source texture
6354 * SrcRect: Source rectangle
6355 * Flags: Cubemap faces to load (DDSCAPS2_CUBEMAP_ALLFACES, DDSCAPS2_CUBEMAP_POSITIVEX,
6356 * DDSCAPS2_CUBEMAP_NEGATIVEX, DDSCAPS2_CUBEMAP_POSITIVEY, DDSCAPS2_CUBEMAP_NEGATIVEY,
6357 * DDSCAPS2_CUBEMAP_POSITIVEZ, DDSCAPS2_CUBEMAP_NEGATIVEZ)
6361 * DDERR_INVALIDPARAMS if DestTex or SrcTex are NULL, broken coordinates or anything unexpected.
6364 *****************************************************************************/
6367 IDirect3DDeviceImpl_7_Load(IDirect3DDevice7
*iface
,
6368 IDirectDrawSurface7
*DestTex
,
6370 IDirectDrawSurface7
*SrcTex
,
6374 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
6375 IDirectDrawSurfaceImpl
*dest
= ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, DestTex
);
6376 IDirectDrawSurfaceImpl
*src
= ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, SrcTex
);
6379 TRACE("(%p)->(%p,%p,%p,%p,%08x)\n", This
, dest
, DestPoint
, src
, SrcRect
, Flags
);
6381 if( (!src
) || (!dest
) )
6382 return DDERR_INVALIDPARAMS
;
6384 EnterCriticalSection(&ddraw_cs
);
6386 if (SrcRect
) srcrect
= *SrcRect
;
6389 srcrect
.left
= srcrect
.top
= 0;
6390 srcrect
.right
= src
->surface_desc
.dwWidth
;
6391 srcrect
.bottom
= src
->surface_desc
.dwHeight
;
6394 if (DestPoint
) destpoint
= *DestPoint
;
6397 destpoint
.x
= destpoint
.y
= 0;
6399 /* Check bad dimensions. DestPoint is validated against src, not dest, because
6400 * destination can be a subset of mip levels, in which case actual coordinates used
6401 * for it may be divided. If any dimension of dest is larger than source, it can't be
6402 * mip level subset, so an error can be returned early.
6404 if (srcrect
.left
>= srcrect
.right
|| srcrect
.top
>= srcrect
.bottom
||
6405 srcrect
.right
> src
->surface_desc
.dwWidth
||
6406 srcrect
.bottom
> src
->surface_desc
.dwHeight
||
6407 destpoint
.x
+ srcrect
.right
- srcrect
.left
> src
->surface_desc
.dwWidth
||
6408 destpoint
.y
+ srcrect
.bottom
- srcrect
.top
> src
->surface_desc
.dwHeight
||
6409 dest
->surface_desc
.dwWidth
> src
->surface_desc
.dwWidth
||
6410 dest
->surface_desc
.dwHeight
> src
->surface_desc
.dwHeight
)
6412 LeaveCriticalSection(&ddraw_cs
);
6413 return DDERR_INVALIDPARAMS
;
6416 /* Must be top level surfaces. */
6417 if (src
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_MIPMAPSUBLEVEL
||
6418 dest
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_MIPMAPSUBLEVEL
)
6420 LeaveCriticalSection(&ddraw_cs
);
6421 return DDERR_INVALIDPARAMS
;
6424 if (src
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
)
6426 DWORD src_face_flag
, dest_face_flag
;
6427 IDirectDrawSurfaceImpl
*src_face
, *dest_face
;
6428 IDirectDrawSurface7
*temp
;
6429 DDSURFACEDESC2 ddsd
;
6432 if (!(dest
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
))
6434 LeaveCriticalSection(&ddraw_cs
);
6435 return DDERR_INVALIDPARAMS
;
6438 /* Iterate through cube faces 2 times. First time is just to check INVALIDPARAMS conditions, second
6439 * time it's actual surface loading. */
6440 for (i
= 0; i
< 2; i
++)
6445 for (;dest_face
&& src_face
;)
6447 src_face_flag
= src_face
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP_ALLFACES
;
6448 dest_face_flag
= dest_face
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP_ALLFACES
;
6450 if (src_face_flag
== dest_face_flag
)
6454 /* Destination mip levels must be subset of source mip levels. */
6455 if (!is_mip_level_subset(dest_face
, src_face
))
6457 LeaveCriticalSection(&ddraw_cs
);
6458 return DDERR_INVALIDPARAMS
;
6461 else if (Flags
& dest_face_flag
)
6463 copy_mipmap_chain(This
, dest_face
, src_face
, &destpoint
, &srcrect
);
6466 if (src_face_flag
< DDSCAPS2_CUBEMAP_NEGATIVEZ
)
6468 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6469 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_CUBEMAP
| (src_face_flag
<< 1);
6470 IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(src
, IDirectDrawSurface7
), &ddsd
.ddsCaps
, &temp
);
6472 if (src_face
!= src
) IDirectDrawSurface7_Release(ICOM_INTERFACE(src_face
, IDirectDrawSurface7
));
6474 src_face
= ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, temp
);
6478 if (src_face
!= src
) IDirectDrawSurface7_Release(ICOM_INTERFACE(src_face
, IDirectDrawSurface7
));
6484 if (dest_face_flag
< DDSCAPS2_CUBEMAP_NEGATIVEZ
)
6486 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6487 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_CUBEMAP
| (dest_face_flag
<< 1);
6488 IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(dest
, IDirectDrawSurface7
), &ddsd
.ddsCaps
, &temp
);
6490 if (dest_face
!= dest
) IDirectDrawSurface7_Release(ICOM_INTERFACE(dest_face
, IDirectDrawSurface7
));
6492 dest_face
= ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, temp
);
6496 if (dest_face
!= dest
) IDirectDrawSurface7_Release(ICOM_INTERFACE(dest_face
, IDirectDrawSurface7
));
6504 /* Native returns error if src faces are not subset of dest faces. */
6507 LeaveCriticalSection(&ddraw_cs
);
6508 return DDERR_INVALIDPARAMS
;
6513 LeaveCriticalSection(&ddraw_cs
);
6516 else if (dest
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
)
6518 LeaveCriticalSection(&ddraw_cs
);
6519 return DDERR_INVALIDPARAMS
;
6522 /* Handle non cube map textures. */
6524 /* Destination mip levels must be subset of source mip levels. */
6525 if (!is_mip_level_subset(dest
, src
))
6527 LeaveCriticalSection(&ddraw_cs
);
6528 return DDERR_INVALIDPARAMS
;
6531 copy_mipmap_chain(This
, dest
, src
, &destpoint
, &srcrect
);
6533 LeaveCriticalSection(&ddraw_cs
);
6537 static HRESULT WINAPI
6538 IDirect3DDeviceImpl_7_Load_FPUSetup(IDirect3DDevice7
*iface
,
6539 IDirectDrawSurface7
*DestTex
,
6541 IDirectDrawSurface7
*SrcTex
,
6545 return IDirect3DDeviceImpl_7_Load(iface
, DestTex
, DestPoint
, SrcTex
, SrcRect
, Flags
);
6548 static HRESULT WINAPI
6549 IDirect3DDeviceImpl_7_Load_FPUPreserve(IDirect3DDevice7
*iface
,
6550 IDirectDrawSurface7
*DestTex
,
6552 IDirectDrawSurface7
*SrcTex
,
6559 old_fpucw
= d3d_fpu_setup();
6560 hr
= IDirect3DDeviceImpl_7_Load(iface
, DestTex
, DestPoint
, SrcTex
, SrcRect
, Flags
);
6561 set_fpu_control_word(old_fpucw
);
6566 /*****************************************************************************
6567 * IDirect3DDevice7::LightEnable
6569 * Enables or disables a light
6571 * Version 7, IDirect3DLight uses this method too.
6574 * LightIndex: The index of the light to enable / disable
6575 * Enable: Enable or disable the light
6579 * For more details, see IWineD3DDevice::SetLightEnable
6581 *****************************************************************************/
6583 IDirect3DDeviceImpl_7_LightEnable(IDirect3DDevice7
*iface
,
6587 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
6589 TRACE("(%p)->(%08x,%d): Relay!\n", This
, LightIndex
, Enable
);
6591 EnterCriticalSection(&ddraw_cs
);
6592 hr
= IWineD3DDevice_SetLightEnable(This
->wineD3DDevice
, LightIndex
, Enable
);
6593 LeaveCriticalSection(&ddraw_cs
);
6594 return hr_ddraw_from_wined3d(hr
);
6597 static HRESULT WINAPI
6598 IDirect3DDeviceImpl_7_LightEnable_FPUSetup(IDirect3DDevice7
*iface
,
6602 return IDirect3DDeviceImpl_7_LightEnable(iface
, LightIndex
, Enable
);
6605 static HRESULT WINAPI
6606 IDirect3DDeviceImpl_7_LightEnable_FPUPreserve(IDirect3DDevice7
*iface
,
6613 old_fpucw
= d3d_fpu_setup();
6614 hr
= IDirect3DDeviceImpl_7_LightEnable(iface
, LightIndex
, Enable
);
6615 set_fpu_control_word(old_fpucw
);
6620 /*****************************************************************************
6621 * IDirect3DDevice7::GetLightEnable
6623 * Retrieves if the light with the given index is enabled or not
6628 * LightIndex: Index of desired light
6629 * Enable: Pointer to a BOOL which contains the result
6633 * DDERR_INVALIDPARAMS if Enable is NULL
6634 * See IWineD3DDevice::GetLightEnable for more details
6636 *****************************************************************************/
6638 IDirect3DDeviceImpl_7_GetLightEnable(IDirect3DDevice7
*iface
,
6642 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
6644 TRACE("(%p)->(%08x,%p): Relay\n", This
, LightIndex
, Enable
);
6647 return DDERR_INVALIDPARAMS
;
6649 EnterCriticalSection(&ddraw_cs
);
6650 hr
= IWineD3DDevice_GetLightEnable(This
->wineD3DDevice
, LightIndex
, Enable
);
6651 LeaveCriticalSection(&ddraw_cs
);
6652 return hr_ddraw_from_wined3d(hr
);
6655 static HRESULT WINAPI
6656 IDirect3DDeviceImpl_7_GetLightEnable_FPUSetup(IDirect3DDevice7
*iface
,
6660 return IDirect3DDeviceImpl_7_GetLightEnable(iface
, LightIndex
, Enable
);
6663 static HRESULT WINAPI
6664 IDirect3DDeviceImpl_7_GetLightEnable_FPUPreserve(IDirect3DDevice7
*iface
,
6671 old_fpucw
= d3d_fpu_setup();
6672 hr
= IDirect3DDeviceImpl_7_GetLightEnable(iface
, LightIndex
, Enable
);
6673 set_fpu_control_word(old_fpucw
);
6678 /*****************************************************************************
6679 * IDirect3DDevice7::SetClipPlane
6681 * Sets custom clipping plane
6686 * Index: The index of the clipping plane
6687 * PlaneEquation: An equation defining the clipping plane
6691 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6692 * See IWineD3DDevice::SetClipPlane for more details
6694 *****************************************************************************/
6696 IDirect3DDeviceImpl_7_SetClipPlane(IDirect3DDevice7
*iface
,
6698 D3DVALUE
* PlaneEquation
)
6700 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
6702 TRACE("(%p)->(%08x,%p): Relay!\n", This
, Index
, PlaneEquation
);
6705 return DDERR_INVALIDPARAMS
;
6707 EnterCriticalSection(&ddraw_cs
);
6708 hr
= IWineD3DDevice_SetClipPlane(This
->wineD3DDevice
, Index
, PlaneEquation
);
6709 LeaveCriticalSection(&ddraw_cs
);
6713 static HRESULT WINAPI
6714 IDirect3DDeviceImpl_7_SetClipPlane_FPUSetup(IDirect3DDevice7
*iface
,
6716 D3DVALUE
* PlaneEquation
)
6718 return IDirect3DDeviceImpl_7_SetClipPlane(iface
, Index
, PlaneEquation
);
6721 static HRESULT WINAPI
6722 IDirect3DDeviceImpl_7_SetClipPlane_FPUPreserve(IDirect3DDevice7
*iface
,
6724 D3DVALUE
* PlaneEquation
)
6729 old_fpucw
= d3d_fpu_setup();
6730 hr
= IDirect3DDeviceImpl_7_SetClipPlane(iface
, Index
, PlaneEquation
);
6731 set_fpu_control_word(old_fpucw
);
6736 /*****************************************************************************
6737 * IDirect3DDevice7::GetClipPlane
6739 * Returns the clipping plane with a specific index
6742 * Index: The index of the desired plane
6743 * PlaneEquation: Address to store the plane equation to
6747 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6748 * See IWineD3DDevice::GetClipPlane for more details
6750 *****************************************************************************/
6752 IDirect3DDeviceImpl_7_GetClipPlane(IDirect3DDevice7
*iface
,
6754 D3DVALUE
* PlaneEquation
)
6756 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
6758 TRACE("(%p)->(%d,%p): Relay!\n", This
, Index
, PlaneEquation
);
6761 return DDERR_INVALIDPARAMS
;
6763 EnterCriticalSection(&ddraw_cs
);
6764 hr
= IWineD3DDevice_GetClipPlane(This
->wineD3DDevice
, Index
, PlaneEquation
);
6765 LeaveCriticalSection(&ddraw_cs
);
6769 static HRESULT WINAPI
6770 IDirect3DDeviceImpl_7_GetClipPlane_FPUSetup(IDirect3DDevice7
*iface
,
6772 D3DVALUE
* PlaneEquation
)
6774 return IDirect3DDeviceImpl_7_GetClipPlane(iface
, Index
, PlaneEquation
);
6777 static HRESULT WINAPI
6778 IDirect3DDeviceImpl_7_GetClipPlane_FPUPreserve(IDirect3DDevice7
*iface
,
6780 D3DVALUE
* PlaneEquation
)
6785 old_fpucw
= d3d_fpu_setup();
6786 hr
= IDirect3DDeviceImpl_7_GetClipPlane(iface
, Index
, PlaneEquation
);
6787 set_fpu_control_word(old_fpucw
);
6792 /*****************************************************************************
6793 * IDirect3DDevice7::GetInfo
6795 * Retrieves some information about the device. The DirectX sdk says that
6796 * this version returns S_FALSE for all retail builds of DirectX, that's what
6797 * this implementation does.
6800 * DevInfoID: Information type requested
6801 * DevInfoStruct: Pointer to a structure to store the info to
6802 * Size: Size of the structure
6805 * S_FALSE, because it's a non-debug driver
6807 *****************************************************************************/
6808 static HRESULT WINAPI
6809 IDirect3DDeviceImpl_7_GetInfo(IDirect3DDevice7
*iface
,
6811 void *DevInfoStruct
,
6814 ICOM_THIS_FROM(IDirect3DDeviceImpl
, IDirect3DDevice7
, iface
);
6815 TRACE("(%p)->(%08x,%p,%08x)\n", This
, DevInfoID
, DevInfoStruct
, Size
);
6819 TRACE(" info requested : ");
6822 case D3DDEVINFOID_TEXTUREMANAGER
: TRACE("D3DDEVINFOID_TEXTUREMANAGER\n"); break;
6823 case D3DDEVINFOID_D3DTEXTUREMANAGER
: TRACE("D3DDEVINFOID_D3DTEXTUREMANAGER\n"); break;
6824 case D3DDEVINFOID_TEXTURING
: TRACE("D3DDEVINFOID_TEXTURING\n"); break;
6825 default: ERR(" invalid flag !!!\n"); return DDERR_INVALIDPARAMS
;
6829 return S_FALSE
; /* According to MSDN, this is valid for a non-debug driver */
6832 /* For performance optimization, devices created in FPUSETUP and FPUPRESERVE modes
6833 * have separate vtables. Simple functions where this doesn't matter like GetDirect3D
6834 * are not duplicated.
6836 * Device created with DDSCL_FPUSETUP (d3d7 default) - device methods assume that FPU
6837 * has already been setup for optimal d3d operation.
6839 * Device created with DDSCL_FPUPRESERVE - resets and restores FPU mode when necessary in
6840 * d3d calls (FPU may be in a mode non-suitable for d3d when the app calls d3d). Required
6841 * by Sacrifice (game). */
6842 const IDirect3DDevice7Vtbl IDirect3DDevice7_FPUSetup_Vtbl
=
6844 /*** IUnknown Methods ***/
6845 IDirect3DDeviceImpl_7_QueryInterface
,
6846 IDirect3DDeviceImpl_7_AddRef
,
6847 IDirect3DDeviceImpl_7_Release
,
6848 /*** IDirect3DDevice7 ***/
6849 IDirect3DDeviceImpl_7_GetCaps_FPUSetup
,
6850 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUSetup
,
6851 IDirect3DDeviceImpl_7_BeginScene_FPUSetup
,
6852 IDirect3DDeviceImpl_7_EndScene_FPUSetup
,
6853 IDirect3DDeviceImpl_7_GetDirect3D
,
6854 IDirect3DDeviceImpl_7_SetRenderTarget_FPUSetup
,
6855 IDirect3DDeviceImpl_7_GetRenderTarget
,
6856 IDirect3DDeviceImpl_7_Clear_FPUSetup
,
6857 IDirect3DDeviceImpl_7_SetTransform_FPUSetup
,
6858 IDirect3DDeviceImpl_7_GetTransform_FPUSetup
,
6859 IDirect3DDeviceImpl_7_SetViewport_FPUSetup
,
6860 IDirect3DDeviceImpl_7_MultiplyTransform_FPUSetup
,
6861 IDirect3DDeviceImpl_7_GetViewport_FPUSetup
,
6862 IDirect3DDeviceImpl_7_SetMaterial_FPUSetup
,
6863 IDirect3DDeviceImpl_7_GetMaterial_FPUSetup
,
6864 IDirect3DDeviceImpl_7_SetLight_FPUSetup
,
6865 IDirect3DDeviceImpl_7_GetLight_FPUSetup
,
6866 IDirect3DDeviceImpl_7_SetRenderState_FPUSetup
,
6867 IDirect3DDeviceImpl_7_GetRenderState_FPUSetup
,
6868 IDirect3DDeviceImpl_7_BeginStateBlock_FPUSetup
,
6869 IDirect3DDeviceImpl_7_EndStateBlock_FPUSetup
,
6870 IDirect3DDeviceImpl_7_PreLoad_FPUSetup
,
6871 IDirect3DDeviceImpl_7_DrawPrimitive_FPUSetup
,
6872 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUSetup
,
6873 IDirect3DDeviceImpl_7_SetClipStatus
,
6874 IDirect3DDeviceImpl_7_GetClipStatus
,
6875 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUSetup
,
6876 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUSetup
,
6877 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUSetup
,
6878 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUSetup
,
6879 IDirect3DDeviceImpl_7_ComputeSphereVisibility
,
6880 IDirect3DDeviceImpl_7_GetTexture_FPUSetup
,
6881 IDirect3DDeviceImpl_7_SetTexture_FPUSetup
,
6882 IDirect3DDeviceImpl_7_GetTextureStageState_FPUSetup
,
6883 IDirect3DDeviceImpl_7_SetTextureStageState_FPUSetup
,
6884 IDirect3DDeviceImpl_7_ValidateDevice_FPUSetup
,
6885 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUSetup
,
6886 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUSetup
,
6887 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUSetup
,
6888 IDirect3DDeviceImpl_7_CreateStateBlock_FPUSetup
,
6889 IDirect3DDeviceImpl_7_Load_FPUSetup
,
6890 IDirect3DDeviceImpl_7_LightEnable_FPUSetup
,
6891 IDirect3DDeviceImpl_7_GetLightEnable_FPUSetup
,
6892 IDirect3DDeviceImpl_7_SetClipPlane_FPUSetup
,
6893 IDirect3DDeviceImpl_7_GetClipPlane_FPUSetup
,
6894 IDirect3DDeviceImpl_7_GetInfo
6897 const IDirect3DDevice7Vtbl IDirect3DDevice7_FPUPreserve_Vtbl
=
6899 /*** IUnknown Methods ***/
6900 IDirect3DDeviceImpl_7_QueryInterface
,
6901 IDirect3DDeviceImpl_7_AddRef
,
6902 IDirect3DDeviceImpl_7_Release
,
6903 /*** IDirect3DDevice7 ***/
6904 IDirect3DDeviceImpl_7_GetCaps_FPUPreserve
,
6905 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUPreserve
,
6906 IDirect3DDeviceImpl_7_BeginScene_FPUPreserve
,
6907 IDirect3DDeviceImpl_7_EndScene_FPUPreserve
,
6908 IDirect3DDeviceImpl_7_GetDirect3D
,
6909 IDirect3DDeviceImpl_7_SetRenderTarget_FPUPreserve
,
6910 IDirect3DDeviceImpl_7_GetRenderTarget
,
6911 IDirect3DDeviceImpl_7_Clear_FPUPreserve
,
6912 IDirect3DDeviceImpl_7_SetTransform_FPUPreserve
,
6913 IDirect3DDeviceImpl_7_GetTransform_FPUPreserve
,
6914 IDirect3DDeviceImpl_7_SetViewport_FPUPreserve
,
6915 IDirect3DDeviceImpl_7_MultiplyTransform_FPUPreserve
,
6916 IDirect3DDeviceImpl_7_GetViewport_FPUPreserve
,
6917 IDirect3DDeviceImpl_7_SetMaterial_FPUPreserve
,
6918 IDirect3DDeviceImpl_7_GetMaterial_FPUPreserve
,
6919 IDirect3DDeviceImpl_7_SetLight_FPUPreserve
,
6920 IDirect3DDeviceImpl_7_GetLight_FPUPreserve
,
6921 IDirect3DDeviceImpl_7_SetRenderState_FPUPreserve
,
6922 IDirect3DDeviceImpl_7_GetRenderState_FPUPreserve
,
6923 IDirect3DDeviceImpl_7_BeginStateBlock_FPUPreserve
,
6924 IDirect3DDeviceImpl_7_EndStateBlock_FPUPreserve
,
6925 IDirect3DDeviceImpl_7_PreLoad_FPUPreserve
,
6926 IDirect3DDeviceImpl_7_DrawPrimitive_FPUPreserve
,
6927 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUPreserve
,
6928 IDirect3DDeviceImpl_7_SetClipStatus
,
6929 IDirect3DDeviceImpl_7_GetClipStatus
,
6930 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUPreserve
,
6931 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUPreserve
,
6932 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUPreserve
,
6933 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUPreserve
,
6934 IDirect3DDeviceImpl_7_ComputeSphereVisibility
,
6935 IDirect3DDeviceImpl_7_GetTexture_FPUPreserve
,
6936 IDirect3DDeviceImpl_7_SetTexture_FPUPreserve
,
6937 IDirect3DDeviceImpl_7_GetTextureStageState_FPUPreserve
,
6938 IDirect3DDeviceImpl_7_SetTextureStageState_FPUPreserve
,
6939 IDirect3DDeviceImpl_7_ValidateDevice_FPUPreserve
,
6940 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUPreserve
,
6941 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUPreserve
,
6942 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUPreserve
,
6943 IDirect3DDeviceImpl_7_CreateStateBlock_FPUPreserve
,
6944 IDirect3DDeviceImpl_7_Load_FPUPreserve
,
6945 IDirect3DDeviceImpl_7_LightEnable_FPUPreserve
,
6946 IDirect3DDeviceImpl_7_GetLightEnable_FPUPreserve
,
6947 IDirect3DDeviceImpl_7_SetClipPlane_FPUPreserve
,
6948 IDirect3DDeviceImpl_7_GetClipPlane_FPUPreserve
,
6949 IDirect3DDeviceImpl_7_GetInfo
6952 const IDirect3DDevice3Vtbl IDirect3DDevice3_Vtbl
=
6954 /*** IUnknown Methods ***/
6955 Thunk_IDirect3DDeviceImpl_3_QueryInterface
,
6956 Thunk_IDirect3DDeviceImpl_3_AddRef
,
6957 Thunk_IDirect3DDeviceImpl_3_Release
,
6958 /*** IDirect3DDevice3 ***/
6959 IDirect3DDeviceImpl_3_GetCaps
,
6960 IDirect3DDeviceImpl_3_GetStats
,
6961 IDirect3DDeviceImpl_3_AddViewport
,
6962 IDirect3DDeviceImpl_3_DeleteViewport
,
6963 IDirect3DDeviceImpl_3_NextViewport
,
6964 Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats
,
6965 Thunk_IDirect3DDeviceImpl_3_BeginScene
,
6966 Thunk_IDirect3DDeviceImpl_3_EndScene
,
6967 Thunk_IDirect3DDeviceImpl_3_GetDirect3D
,
6968 IDirect3DDeviceImpl_3_SetCurrentViewport
,
6969 IDirect3DDeviceImpl_3_GetCurrentViewport
,
6970 Thunk_IDirect3DDeviceImpl_3_SetRenderTarget
,
6971 Thunk_IDirect3DDeviceImpl_3_GetRenderTarget
,
6972 IDirect3DDeviceImpl_3_Begin
,
6973 IDirect3DDeviceImpl_3_BeginIndexed
,
6974 IDirect3DDeviceImpl_3_Vertex
,
6975 IDirect3DDeviceImpl_3_Index
,
6976 IDirect3DDeviceImpl_3_End
,
6977 IDirect3DDeviceImpl_3_GetRenderState
,
6978 IDirect3DDeviceImpl_3_SetRenderState
,
6979 IDirect3DDeviceImpl_3_GetLightState
,
6980 IDirect3DDeviceImpl_3_SetLightState
,
6981 Thunk_IDirect3DDeviceImpl_3_SetTransform
,
6982 Thunk_IDirect3DDeviceImpl_3_GetTransform
,
6983 Thunk_IDirect3DDeviceImpl_3_MultiplyTransform
,
6984 Thunk_IDirect3DDeviceImpl_3_DrawPrimitive
,
6985 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive
,
6986 Thunk_IDirect3DDeviceImpl_3_SetClipStatus
,
6987 Thunk_IDirect3DDeviceImpl_3_GetClipStatus
,
6988 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided
,
6989 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided
,
6990 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB
,
6991 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB
,
6992 Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility
,
6993 Thunk_IDirect3DDeviceImpl_3_GetTexture
,
6994 IDirect3DDeviceImpl_3_SetTexture
,
6995 Thunk_IDirect3DDeviceImpl_3_GetTextureStageState
,
6996 Thunk_IDirect3DDeviceImpl_3_SetTextureStageState
,
6997 Thunk_IDirect3DDeviceImpl_3_ValidateDevice
7000 const IDirect3DDevice2Vtbl IDirect3DDevice2_Vtbl
=
7002 /*** IUnknown Methods ***/
7003 Thunk_IDirect3DDeviceImpl_2_QueryInterface
,
7004 Thunk_IDirect3DDeviceImpl_2_AddRef
,
7005 Thunk_IDirect3DDeviceImpl_2_Release
,
7006 /*** IDirect3DDevice2 ***/
7007 Thunk_IDirect3DDeviceImpl_2_GetCaps
,
7008 IDirect3DDeviceImpl_2_SwapTextureHandles
,
7009 Thunk_IDirect3DDeviceImpl_2_GetStats
,
7010 Thunk_IDirect3DDeviceImpl_2_AddViewport
,
7011 Thunk_IDirect3DDeviceImpl_2_DeleteViewport
,
7012 Thunk_IDirect3DDeviceImpl_2_NextViewport
,
7013 IDirect3DDeviceImpl_2_EnumTextureFormats
,
7014 Thunk_IDirect3DDeviceImpl_2_BeginScene
,
7015 Thunk_IDirect3DDeviceImpl_2_EndScene
,
7016 Thunk_IDirect3DDeviceImpl_2_GetDirect3D
,
7017 Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport
,
7018 Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport
,
7019 Thunk_IDirect3DDeviceImpl_2_SetRenderTarget
,
7020 Thunk_IDirect3DDeviceImpl_2_GetRenderTarget
,
7021 Thunk_IDirect3DDeviceImpl_2_Begin
,
7022 Thunk_IDirect3DDeviceImpl_2_BeginIndexed
,
7023 Thunk_IDirect3DDeviceImpl_2_Vertex
,
7024 Thunk_IDirect3DDeviceImpl_2_Index
,
7025 Thunk_IDirect3DDeviceImpl_2_End
,
7026 Thunk_IDirect3DDeviceImpl_2_GetRenderState
,
7027 Thunk_IDirect3DDeviceImpl_2_SetRenderState
,
7028 Thunk_IDirect3DDeviceImpl_2_GetLightState
,
7029 Thunk_IDirect3DDeviceImpl_2_SetLightState
,
7030 Thunk_IDirect3DDeviceImpl_2_SetTransform
,
7031 Thunk_IDirect3DDeviceImpl_2_GetTransform
,
7032 Thunk_IDirect3DDeviceImpl_2_MultiplyTransform
,
7033 Thunk_IDirect3DDeviceImpl_2_DrawPrimitive
,
7034 Thunk_IDirect3DDeviceImpl_2_DrawIndexedPrimitive
,
7035 Thunk_IDirect3DDeviceImpl_2_SetClipStatus
,
7036 Thunk_IDirect3DDeviceImpl_2_GetClipStatus
7039 const IDirect3DDeviceVtbl IDirect3DDevice1_Vtbl
=
7041 /*** IUnknown Methods ***/
7042 Thunk_IDirect3DDeviceImpl_1_QueryInterface
,
7043 Thunk_IDirect3DDeviceImpl_1_AddRef
,
7044 Thunk_IDirect3DDeviceImpl_1_Release
,
7045 /*** IDirect3DDevice1 ***/
7046 IDirect3DDeviceImpl_1_Initialize
,
7047 Thunk_IDirect3DDeviceImpl_1_GetCaps
,
7048 Thunk_IDirect3DDeviceImpl_1_SwapTextureHandles
,
7049 IDirect3DDeviceImpl_1_CreateExecuteBuffer
,
7050 Thunk_IDirect3DDeviceImpl_1_GetStats
,
7051 IDirect3DDeviceImpl_1_Execute
,
7052 Thunk_IDirect3DDeviceImpl_1_AddViewport
,
7053 Thunk_IDirect3DDeviceImpl_1_DeleteViewport
,
7054 Thunk_IDirect3DDeviceImpl_1_NextViewport
,
7055 IDirect3DDeviceImpl_1_Pick
,
7056 IDirect3DDeviceImpl_1_GetPickRecords
,
7057 Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats
,
7058 IDirect3DDeviceImpl_1_CreateMatrix
,
7059 IDirect3DDeviceImpl_1_SetMatrix
,
7060 IDirect3DDeviceImpl_1_GetMatrix
,
7061 IDirect3DDeviceImpl_1_DeleteMatrix
,
7062 Thunk_IDirect3DDeviceImpl_1_BeginScene
,
7063 Thunk_IDirect3DDeviceImpl_1_EndScene
,
7064 Thunk_IDirect3DDeviceImpl_1_GetDirect3D
7067 /*****************************************************************************
7068 * IDirect3DDeviceImpl_CreateHandle
7070 * Not called from the VTable
7072 * Some older interface versions operate with handles, which are basically
7073 * DWORDs which identify an interface, for example
7074 * IDirect3DDevice::SetRenderState with DIRECT3DRENDERSTATE_TEXTUREHANDLE
7076 * Those handle could be just casts to the interface pointers or vice versa,
7077 * but that is not 64 bit safe and would mean blindly derefering a DWORD
7078 * passed by the app. Instead there is a dynamic array in the device which
7079 * keeps a DWORD to pointer information and a type for the handle.
7081 * Basically this array only grows, when a handle is freed its pointer is
7082 * just set to NULL. There will be much more reads from the array than
7083 * insertion operations, so a dynamic array is fine.
7086 * This: D3DDevice implementation for which this handle should be created
7089 * A free handle on success
7092 *****************************************************************************/
7094 IDirect3DDeviceImpl_CreateHandle(IDirect3DDeviceImpl
*This
)
7097 struct HandleEntry
*oldHandles
= This
->Handles
;
7099 TRACE("(%p)\n", This
);
7101 for(i
= 0; i
< This
->numHandles
; i
++)
7103 if(This
->Handles
[i
].ptr
== NULL
&&
7104 This
->Handles
[i
].type
== DDrawHandle_Unknown
)
7106 TRACE("Reusing freed handle %d\n", i
+ 1);
7111 TRACE("Growing the handle array\n");
7114 This
->Handles
= HeapAlloc(GetProcessHeap(), 0, sizeof(struct HandleEntry
) * This
->numHandles
);
7117 ERR("Out of memory\n");
7118 This
->Handles
= oldHandles
;
7124 memcpy(This
->Handles
, oldHandles
, (This
->numHandles
- 1) * sizeof(struct HandleEntry
));
7125 HeapFree(GetProcessHeap(), 0, oldHandles
);
7128 TRACE("Returning %d\n", This
->numHandles
);
7129 return This
->numHandles
;
7132 /*****************************************************************************
7133 * IDirect3DDeviceImpl_UpdateDepthStencil
7135 * Checks the current render target for attached depth stencils and sets the
7136 * WineD3D depth stencil accordingly.
7139 * The depth stencil state to set if creating the device
7141 *****************************************************************************/
7143 IDirect3DDeviceImpl_UpdateDepthStencil(IDirect3DDeviceImpl
*This
)
7145 IDirectDrawSurface7
*depthStencil
= NULL
;
7146 IDirectDrawSurfaceImpl
*dsi
;
7147 static DDSCAPS2 depthcaps
= { DDSCAPS_ZBUFFER
, 0, 0, 0 };
7149 IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(This
->target
, IDirectDrawSurface7
),
7154 TRACE("Setting wined3d depth stencil to NULL\n");
7155 IWineD3DDevice_SetDepthStencilSurface(This
->wineD3DDevice
,
7157 return WINED3DZB_FALSE
;
7160 dsi
= ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, depthStencil
);
7161 TRACE("Setting wined3d depth stencil to %p (wined3d %p)\n", dsi
, dsi
->WineD3DSurface
);
7162 IWineD3DDevice_SetDepthStencilSurface(This
->wineD3DDevice
,
7163 dsi
->WineD3DSurface
);
7165 IDirectDrawSurface7_Release(depthStencil
);
7166 return WINED3DZB_TRUE
;