push 5bc4839baba05cc4333240c25295b8dd6e351557
[wine/hacks.git] / dlls / ddraw / device.c
blob68b149e998cd43be017f26ef123f9e62d4ed278c
1 /*
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
26 * D3D7 and D3D9.
30 #include "config.h"
31 #include "wine/port.h"
33 #include <assert.h>
34 #include <stdarg.h>
35 #include <string.h>
36 #include <stdlib.h>
38 #define COBJMACROS
39 #define NONAMELESSUNION
41 #include "windef.h"
42 #include "winbase.h"
43 #include "winerror.h"
44 #include "wingdi.h"
45 #include "wine/exception.h"
47 #include "ddraw.h"
48 #include "d3d.h"
50 #include "ddraw_private.h"
51 #include "wine/debug.h"
53 WINE_DEFAULT_DEBUG_CHANNEL(d3d7);
54 WINE_DECLARE_DEBUG_CHANNEL(ddraw_thunk);
56 /* The device ID */
57 const GUID IID_D3DDEVICE_WineD3D = {
58 0xaef72d43,
59 0xb09a,
60 0x4b7b,
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)
69 __asm fldcw fpucw;
70 #endif
73 static inline WORD d3d_fpu_setup(void)
75 WORD oldcw;
77 #if defined(__i386__) && defined(__GNUC__)
78 __asm__ volatile ("fnstcw %0" : "=m" (oldcw));
79 #elif defined(__i386__) && defined(_MSC_VER)
80 __asm fnstcw oldcw;
81 #else
82 static BOOL warned = FALSE;
83 if(!warned)
85 FIXME("FPUPRESERVE not implemented for this platform / compiler\n");
86 warned = TRUE;
88 return 0;
89 #endif
91 set_fpu_control_word(0x37f);
93 return oldcw;
96 /*****************************************************************************
97 * IUnknown Methods. Common for Version 1, 2, 3 and 7
98 *****************************************************************************/
100 /*****************************************************************************
101 * IDirect3DDevice7::QueryInterface
103 * Used to query other interfaces from a Direct3DDevice interface.
104 * It can return interface pointers to all Direct3DDevice versions as well
105 * as IDirectDraw and IDirect3D. For a link to QueryInterface
106 * rules see ddraw.c, IDirectDraw7::QueryInterface
108 * Exists in Version 1, 2, 3 and 7
110 * Params:
111 * refiid: Interface ID queried for
112 * obj: Used to return the interface pointer
114 * Returns:
115 * D3D_OK or E_NOINTERFACE
117 *****************************************************************************/
118 static HRESULT WINAPI
119 IDirect3DDeviceImpl_7_QueryInterface(IDirect3DDevice7 *iface,
120 REFIID refiid,
121 void **obj)
123 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
124 TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(refiid), obj);
126 /* According to COM docs, if the QueryInterface fails, obj should be set to NULL */
127 *obj = NULL;
129 if(!refiid)
130 return DDERR_INVALIDPARAMS;
132 if ( IsEqualGUID( &IID_IUnknown, refiid ) )
134 *obj = iface;
137 /* Check DirectDraw Interfac\x01s */
138 else if( IsEqualGUID( &IID_IDirectDraw7, refiid ) )
140 *obj = This->ddraw;
141 TRACE("(%p) Returning IDirectDraw7 interface at %p\n", This, *obj);
143 else if ( IsEqualGUID( &IID_IDirectDraw4, refiid ) )
145 *obj = &This->ddraw->IDirectDraw4_vtbl;
146 TRACE("(%p) Returning IDirectDraw4 interface at %p\n", This, *obj);
148 else if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) )
150 *obj = &This->ddraw->IDirectDraw2_vtbl;
151 TRACE("(%p) Returning IDirectDraw2 interface at %p\n", This, *obj);
153 else if( IsEqualGUID( &IID_IDirectDraw, refiid ) )
155 *obj = &This->ddraw->IDirectDraw_vtbl;
156 TRACE("(%p) Returning IDirectDraw interface at %p\n", This, *obj);
159 /* Direct3D */
160 else if ( IsEqualGUID( &IID_IDirect3D , refiid ) )
162 *obj = &This->ddraw->IDirect3D_vtbl;
163 TRACE("(%p) Returning IDirect3D interface at %p\n", This, *obj);
165 else if ( IsEqualGUID( &IID_IDirect3D2 , refiid ) )
167 *obj = &This->ddraw->IDirect3D2_vtbl;
168 TRACE("(%p) Returning IDirect3D2 interface at %p\n", This, *obj);
170 else if ( IsEqualGUID( &IID_IDirect3D3 , refiid ) )
172 *obj = &This->ddraw->IDirect3D3_vtbl;
173 TRACE("(%p) Returning IDirect3D3 interface at %p\n", This, *obj);
175 else if ( IsEqualGUID( &IID_IDirect3D7 , refiid ) )
177 *obj = &This->ddraw->IDirect3D7_vtbl;
178 TRACE("(%p) Returning IDirect3D7 interface at %p\n", This, *obj);
181 /* Direct3DDevice */
182 else if ( IsEqualGUID( &IID_IDirect3DDevice , refiid ) )
184 *obj = &This->IDirect3DDevice_vtbl;
185 TRACE("(%p) Returning IDirect3DDevice interface at %p\n", This, *obj);
187 else if ( IsEqualGUID( &IID_IDirect3DDevice2 , refiid ) ) {
188 *obj = &This->IDirect3DDevice2_vtbl;
189 TRACE("(%p) Returning IDirect3DDevice2 interface at %p\n", This, *obj);
191 else if ( IsEqualGUID( &IID_IDirect3DDevice3 , refiid ) ) {
192 *obj = &This->IDirect3DDevice3_vtbl;
193 TRACE("(%p) Returning IDirect3DDevice3 interface at %p\n", This, *obj);
195 else if ( IsEqualGUID( &IID_IDirect3DDevice7 , refiid ) ) {
196 *obj = This;
197 TRACE("(%p) Returning IDirect3DDevice7 interface at %p\n", This, *obj);
200 /* Unknown interface */
201 else
203 ERR("(%p)->(%s, %p): No interface found\n", This, debugstr_guid(refiid), obj);
204 return E_NOINTERFACE;
207 /* AddRef the returned interface */
208 IUnknown_AddRef( (IUnknown *) *obj);
209 return D3D_OK;
212 static HRESULT WINAPI
213 Thunk_IDirect3DDeviceImpl_3_QueryInterface(IDirect3DDevice3 *iface,
214 REFIID riid,
215 void **obj)
217 IDirect3DDeviceImpl *This = device_from_device3(iface);
218 TRACE_(ddraw_thunk)("(%p)->(%s,%p) thunking to IDirect3DDevice7 interface.\n", This, debugstr_guid(riid), obj);
219 return IDirect3DDevice7_QueryInterface((IDirect3DDevice7 *)This, riid, obj);
222 static HRESULT WINAPI
223 Thunk_IDirect3DDeviceImpl_2_QueryInterface(IDirect3DDevice2 *iface,
224 REFIID riid,
225 void **obj)
227 IDirect3DDeviceImpl *This = device_from_device2(iface);
228 TRACE_(ddraw_thunk)("(%p)->(%s,%p) thunking to IDirect3DDevice7 interface.\n", This, debugstr_guid(riid), obj);
229 return IDirect3DDevice7_QueryInterface((IDirect3DDevice7 *)This, riid, obj);
232 static HRESULT WINAPI
233 Thunk_IDirect3DDeviceImpl_1_QueryInterface(IDirect3DDevice *iface,
234 REFIID riid,
235 void **obp)
237 IDirect3DDeviceImpl *This = device_from_device1(iface);
238 TRACE_(ddraw_thunk)("(%p)->(%s,%p) thunking to IDirect3DDevice7 interface.\n", This, debugstr_guid(riid), obp);
239 return IDirect3DDevice7_QueryInterface((IDirect3DDevice7 *)This, riid, obp);
242 /*****************************************************************************
243 * IDirect3DDevice7::AddRef
245 * Increases the refcount....
246 * The most exciting Method, definitely
248 * Exists in Version 1, 2, 3 and 7
250 * Returns:
251 * The new refcount
253 *****************************************************************************/
254 static ULONG WINAPI
255 IDirect3DDeviceImpl_7_AddRef(IDirect3DDevice7 *iface)
257 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
258 ULONG ref = InterlockedIncrement(&This->ref);
260 TRACE("(%p) : incrementing from %u.\n", This, ref -1);
262 return ref;
265 static ULONG WINAPI
266 Thunk_IDirect3DDeviceImpl_3_AddRef(IDirect3DDevice3 *iface)
268 IDirect3DDeviceImpl *This = device_from_device3(iface);
269 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
270 return IDirect3DDevice7_AddRef((IDirect3DDevice7 *)This);
273 static ULONG WINAPI
274 Thunk_IDirect3DDeviceImpl_2_AddRef(IDirect3DDevice2 *iface)
276 IDirect3DDeviceImpl *This = device_from_device2(iface);
277 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
278 return IDirect3DDevice7_AddRef((IDirect3DDevice7 *)This);
281 static ULONG WINAPI
282 Thunk_IDirect3DDeviceImpl_1_AddRef(IDirect3DDevice *iface)
284 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", iface);
285 return IDirect3DDevice7_AddRef((IDirect3DDevice7 *)device_from_device1(iface));
288 /*****************************************************************************
289 * IDirect3DDevice7::Release
291 * Decreases the refcount of the interface
292 * When the refcount is reduced to 0, the object is destroyed.
294 * Exists in Version 1, 2, 3 and 7
296 * Returns:d
297 * The new refcount
299 *****************************************************************************/
300 static ULONG WINAPI
301 IDirect3DDeviceImpl_7_Release(IDirect3DDevice7 *iface)
303 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
304 ULONG ref = InterlockedDecrement(&This->ref);
306 TRACE("(%p)->() decrementing from %u.\n", This, ref +1);
308 /* This method doesn't destroy the WineD3DDevice, because it's still in use for
309 * 2D rendering. IDirectDrawSurface7::Release will destroy the WineD3DDevice
310 * when the render target is released
312 if (ref == 0)
314 IParent *IndexBufferParent;
315 DWORD i;
317 EnterCriticalSection(&ddraw_cs);
318 /* Free the index buffer. */
319 IWineD3DDevice_SetIndexBuffer(This->wineD3DDevice, NULL, WINED3DFMT_UNKNOWN);
320 IWineD3DBuffer_GetParent(This->indexbuffer,
321 (IUnknown **) &IndexBufferParent);
322 IParent_Release(IndexBufferParent); /* Once for the getParent */
323 if( IParent_Release(IndexBufferParent) != 0) /* And now to destroy it */
325 ERR(" (%p) Something is still holding the index buffer parent %p\n", This, IndexBufferParent);
328 /* There is no need to unset the vertex buffer here, IWineD3DDevice_Uninit3D will do that when
329 * destroying the primary stateblock. If a vertex buffer is destroyed while it is bound
330 * IDirect3DVertexBuffer::Release will unset it.
333 /* Restore the render targets */
334 if(This->OffScreenTarget)
336 WINED3DVIEWPORT vp;
338 vp.X = 0;
339 vp.Y = 0;
340 vp.Width = This->ddraw->d3d_target->surface_desc.dwWidth;
341 vp.Height = This->ddraw->d3d_target->surface_desc.dwHeight;
342 vp.MinZ = 0.0;
343 vp.MaxZ = 1.0;
344 IWineD3DDevice_SetViewport(This->wineD3DDevice,
345 &vp);
347 /* Set the device up to render to the front buffer since the back buffer will
348 * vanish soon.
350 IWineD3DDevice_SetRenderTarget(This->wineD3DDevice, 0,
351 This->ddraw->d3d_target->WineD3DSurface,
352 FALSE);
353 /* This->target is the offscreen target.
354 * This->ddraw->d3d_target is the target used by DDraw
356 TRACE("(%p) Release: Using %p as front buffer, %p as back buffer\n", This, This->ddraw->d3d_target, NULL);
357 IWineD3DDevice_SetFrontBackBuffers(This->wineD3DDevice,
358 This->ddraw->d3d_target->WineD3DSurface,
359 NULL);
362 /* Release the WineD3DDevice. This won't destroy it */
363 if(IWineD3DDevice_Release(This->wineD3DDevice) <= 0)
365 ERR(" (%p) The wineD3D device %p was destroyed unexpectedly. Prepare for trouble\n", This, This->wineD3DDevice);
368 /* The texture handles should be unset by now, but there might be some bits
369 * missing in our reference counting(needs test). Do a sanity check
371 for(i = 0; i < This->numHandles; i++)
373 if(This->Handles[i].ptr)
375 switch(This->Handles[i].type)
377 case DDrawHandle_Texture:
379 IDirectDrawSurfaceImpl *surf = This->Handles[i].ptr;
380 FIXME("Texture Handle %d not unset properly\n", i + 1);
381 surf->Handle = 0;
383 break;
385 case DDrawHandle_Material:
387 IDirect3DMaterialImpl *mat = This->Handles[i].ptr;
388 FIXME("Material handle %d not unset properly\n", i + 1);
389 mat->Handle = 0;
391 break;
393 case DDrawHandle_Matrix:
395 /* No fixme here because this might happen because of sloppy apps */
396 WARN("Leftover matrix handle %d, deleting\n", i + 1);
397 IDirect3DDevice_DeleteMatrix((IDirect3DDevice *)&This->IDirect3DDevice_vtbl, i + 1);
399 break;
401 case DDrawHandle_StateBlock:
403 /* No fixme here because this might happen because of sloppy apps */
404 WARN("Leftover stateblock handle %d, deleting\n", i + 1);
405 IDirect3DDevice7_DeleteStateBlock((IDirect3DDevice7 *)This, i + 1);
407 break;
409 default:
410 FIXME("Unknown handle %d not unset properly\n", i + 1);
415 HeapFree(GetProcessHeap(), 0, This->Handles);
417 TRACE("Releasing target %p %p\n", This->target, This->ddraw->d3d_target);
418 /* Release the render target and the WineD3D render target
419 * (See IDirect3D7::CreateDevice for more comments on this)
421 IDirectDrawSurface7_Release((IDirectDrawSurface7 *)This->target);
422 IDirectDrawSurface7_Release((IDirectDrawSurface7 *)This->ddraw->d3d_target);
423 TRACE("Target release done\n");
425 This->ddraw->d3ddevice = NULL;
427 /* Now free the structure */
428 HeapFree(GetProcessHeap(), 0, This);
429 LeaveCriticalSection(&ddraw_cs);
432 TRACE("Done\n");
433 return ref;
436 static ULONG WINAPI
437 Thunk_IDirect3DDeviceImpl_3_Release(IDirect3DDevice3 *iface)
439 IDirect3DDeviceImpl *This = device_from_device3(iface);
440 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
441 return IDirect3DDevice7_Release((IDirect3DDevice7 *)This);
444 static ULONG WINAPI
445 Thunk_IDirect3DDeviceImpl_2_Release(IDirect3DDevice2 *iface)
447 IDirect3DDeviceImpl *This = device_from_device2(iface);
448 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
449 return IDirect3DDevice7_Release((IDirect3DDevice7 *)This);
452 static ULONG WINAPI
453 Thunk_IDirect3DDeviceImpl_1_Release(IDirect3DDevice *iface)
455 IDirect3DDeviceImpl *This = device_from_device1(iface);
456 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
457 return IDirect3DDevice7_Release((IDirect3DDevice7 *)This);
460 /*****************************************************************************
461 * IDirect3DDevice Methods
462 *****************************************************************************/
464 /*****************************************************************************
465 * IDirect3DDevice::Initialize
467 * Initializes a Direct3DDevice. This implementation is a no-op, as all
468 * initialization is done at create time.
470 * Exists in Version 1
472 * Parameters:
473 * No idea what they mean, as the MSDN page is gone
475 * Returns: DD_OK
477 *****************************************************************************/
478 static HRESULT WINAPI
479 IDirect3DDeviceImpl_1_Initialize(IDirect3DDevice *iface,
480 IDirect3D *Direct3D, GUID *guid,
481 D3DDEVICEDESC *Desc)
483 IDirect3DDeviceImpl *This = device_from_device1(iface);
485 /* It shouldn't be crucial, but print a FIXME, I'm interested if
486 * any game calls it and when
488 FIXME("(%p)->(%p,%p,%p): No-op!\n", This, Direct3D, guid, Desc);
490 return D3D_OK;
493 /*****************************************************************************
494 * IDirect3DDevice7::GetCaps
496 * Retrieves the device's capabilities
498 * This implementation is used for Version 7 only, the older versions have
499 * their own implementation.
501 * Parameters:
502 * Desc: Pointer to a D3DDEVICEDESC7 structure to fill
504 * Returns:
505 * D3D_OK on success
506 * D3DERR_* if a problem occurs. See WineD3D
508 *****************************************************************************/
509 static HRESULT
510 IDirect3DDeviceImpl_7_GetCaps(IDirect3DDevice7 *iface,
511 D3DDEVICEDESC7 *Desc)
513 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
514 D3DDEVICEDESC OldDesc;
515 TRACE("(%p)->(%p)\n", This, Desc);
517 /* Call the same function used by IDirect3D, this saves code */
518 return IDirect3DImpl_GetCaps(This->ddraw->wineD3D, &OldDesc, Desc);
521 static HRESULT WINAPI
522 IDirect3DDeviceImpl_7_GetCaps_FPUSetup(IDirect3DDevice7 *iface,
523 D3DDEVICEDESC7 *Desc)
525 return IDirect3DDeviceImpl_7_GetCaps(iface, Desc);
528 static HRESULT WINAPI
529 IDirect3DDeviceImpl_7_GetCaps_FPUPreserve(IDirect3DDevice7 *iface,
530 D3DDEVICEDESC7 *Desc)
532 HRESULT hr;
533 WORD old_fpucw;
535 old_fpucw = d3d_fpu_setup();
536 hr = IDirect3DDeviceImpl_7_GetCaps(iface, Desc);
537 set_fpu_control_word(old_fpucw);
539 return hr;
541 /*****************************************************************************
542 * IDirect3DDevice3::GetCaps
544 * Retrieves the capabilities of the hardware device and the emulation
545 * device. For Wine, hardware and emulation are the same (it's all HW).
547 * This implementation is used for Version 1, 2, and 3. Version 7 has its own
549 * Parameters:
550 * HWDesc: Structure to fill with the HW caps
551 * HelDesc: Structure to fill with the hardware emulation caps
553 * Returns:
554 * D3D_OK on success
555 * D3DERR_* if a problem occurs. See WineD3D
557 *****************************************************************************/
558 static HRESULT WINAPI
559 IDirect3DDeviceImpl_3_GetCaps(IDirect3DDevice3 *iface,
560 D3DDEVICEDESC *HWDesc,
561 D3DDEVICEDESC *HelDesc)
563 IDirect3DDeviceImpl *This = device_from_device3(iface);
564 D3DDEVICEDESC7 newDesc;
565 HRESULT hr;
566 TRACE("(%p)->(%p,%p)\n", iface, HWDesc, HelDesc);
568 hr = IDirect3DImpl_GetCaps(This->ddraw->wineD3D, HWDesc, &newDesc);
569 if(hr != D3D_OK) return hr;
571 *HelDesc = *HWDesc;
572 return D3D_OK;
575 static HRESULT WINAPI
576 Thunk_IDirect3DDeviceImpl_2_GetCaps(IDirect3DDevice2 *iface,
577 D3DDEVICEDESC *D3DHWDevDesc,
578 D3DDEVICEDESC *D3DHELDevDesc)
580 IDirect3DDeviceImpl *This = device_from_device2(iface);
581 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice3 interface.\n", This, D3DHWDevDesc, D3DHELDevDesc);
582 return IDirect3DDevice3_GetCaps((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, D3DHWDevDesc, D3DHELDevDesc);
585 static HRESULT WINAPI
586 Thunk_IDirect3DDeviceImpl_1_GetCaps(IDirect3DDevice *iface,
587 D3DDEVICEDESC *D3DHWDevDesc,
588 D3DDEVICEDESC *D3DHELDevDesc)
590 IDirect3DDeviceImpl *This = device_from_device1(iface);
591 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice3 interface.\n", This, D3DHWDevDesc, D3DHELDevDesc);
592 return IDirect3DDevice3_GetCaps((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, D3DHWDevDesc, D3DHELDevDesc);
595 /*****************************************************************************
596 * IDirect3DDevice2::SwapTextureHandles
598 * Swaps the texture handles of 2 Texture interfaces. Version 1 and 2
600 * Parameters:
601 * Tex1, Tex2: The 2 Textures to swap
603 * Returns:
604 * D3D_OK
606 *****************************************************************************/
607 static HRESULT WINAPI
608 IDirect3DDeviceImpl_2_SwapTextureHandles(IDirect3DDevice2 *iface,
609 IDirect3DTexture2 *Tex1,
610 IDirect3DTexture2 *Tex2)
612 IDirect3DDeviceImpl *This = device_from_device2(iface);
613 DWORD swap;
614 IDirectDrawSurfaceImpl *surf1 = surface_from_texture2(Tex1);
615 IDirectDrawSurfaceImpl *surf2 = surface_from_texture2(Tex2);
616 TRACE("(%p)->(%p,%p)\n", This, surf1, surf2);
618 EnterCriticalSection(&ddraw_cs);
619 This->Handles[surf1->Handle - 1].ptr = surf2;
620 This->Handles[surf2->Handle - 1].ptr = surf1;
622 swap = surf2->Handle;
623 surf2->Handle = surf1->Handle;
624 surf1->Handle = swap;
625 LeaveCriticalSection(&ddraw_cs);
627 return D3D_OK;
630 static HRESULT WINAPI
631 Thunk_IDirect3DDeviceImpl_1_SwapTextureHandles(IDirect3DDevice *iface,
632 IDirect3DTexture *D3DTex1,
633 IDirect3DTexture *D3DTex2)
635 IDirect3DDeviceImpl *This = device_from_device1(iface);
636 IDirectDrawSurfaceImpl *surf1 = surface_from_texture1(D3DTex1);
637 IDirectDrawSurfaceImpl *surf2 = surface_from_texture1(D3DTex2);
638 IDirect3DTexture2 *t1 = surf1 ? (IDirect3DTexture2 *)&surf1->IDirect3DTexture2_vtbl : NULL;
639 IDirect3DTexture2 *t2 = surf2 ? (IDirect3DTexture2 *)&surf2->IDirect3DTexture2_vtbl : NULL;
640 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice2 interface.\n", This, surf1, surf2);
641 return IDirect3DDevice2_SwapTextureHandles((IDirect3DDevice2 *)&This->IDirect3DDevice2_vtbl, t1, t2);
644 /*****************************************************************************
645 * IDirect3DDevice3::GetStats
647 * This method seems to retrieve some stats from the device.
648 * The MSDN documentation doesn't exist any more, but the D3DSTATS
649 * structure suggests that the amount of drawn primitives and processed
650 * vertices is returned.
652 * Exists in Version 1, 2 and 3
654 * Parameters:
655 * Stats: Pointer to a D3DSTATS structure to be filled
657 * Returns:
658 * D3D_OK on success
659 * DDERR_INVALIDPARAMS if Stats == NULL
661 *****************************************************************************/
662 static HRESULT WINAPI
663 IDirect3DDeviceImpl_3_GetStats(IDirect3DDevice3 *iface,
664 D3DSTATS *Stats)
666 IDirect3DDeviceImpl *This = device_from_device3(iface);
667 FIXME("(%p)->(%p): Stub!\n", This, Stats);
669 if(!Stats)
670 return DDERR_INVALIDPARAMS;
672 /* Fill the Stats with 0 */
673 Stats->dwTrianglesDrawn = 0;
674 Stats->dwLinesDrawn = 0;
675 Stats->dwPointsDrawn = 0;
676 Stats->dwSpansDrawn = 0;
677 Stats->dwVerticesProcessed = 0;
679 return D3D_OK;
682 static HRESULT WINAPI
683 Thunk_IDirect3DDeviceImpl_2_GetStats(IDirect3DDevice2 *iface,
684 D3DSTATS *Stats)
686 IDirect3DDeviceImpl *This = device_from_device2(iface);
687 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, Stats);
688 return IDirect3DDevice3_GetStats((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, Stats);
691 static HRESULT WINAPI
692 Thunk_IDirect3DDeviceImpl_1_GetStats(IDirect3DDevice *iface,
693 D3DSTATS *Stats)
695 IDirect3DDeviceImpl *This = device_from_device1(iface);
696 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, Stats);
697 return IDirect3DDevice3_GetStats((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, Stats);
700 /*****************************************************************************
701 * IDirect3DDevice::CreateExecuteBuffer
703 * Creates an IDirect3DExecuteBuffer, used for rendering with a
704 * Direct3DDevice.
706 * Version 1 only.
708 * Params:
709 * Desc: Buffer description
710 * ExecuteBuffer: Address to return the Interface pointer at
711 * UnkOuter: Must be NULL. Basically for aggregation, which ddraw doesn't
712 * support
714 * Returns:
715 * CLASS_E_NOAGGREGATION if UnkOuter != NULL
716 * DDERR_OUTOFMEMORY if we ran out of memory
717 * D3D_OK on success
719 *****************************************************************************/
720 static HRESULT WINAPI
721 IDirect3DDeviceImpl_1_CreateExecuteBuffer(IDirect3DDevice *iface,
722 D3DEXECUTEBUFFERDESC *Desc,
723 IDirect3DExecuteBuffer **ExecuteBuffer,
724 IUnknown *UnkOuter)
726 IDirect3DDeviceImpl *This = device_from_device1(iface);
727 IDirect3DExecuteBufferImpl* object;
728 TRACE("(%p)->(%p,%p,%p)!\n", This, Desc, ExecuteBuffer, UnkOuter);
730 if(UnkOuter)
731 return CLASS_E_NOAGGREGATION;
733 /* Allocate the new Execute Buffer */
734 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DExecuteBufferImpl));
735 if(!object)
737 ERR("Out of memory when allocating a IDirect3DExecuteBufferImpl structure\n");
738 return DDERR_OUTOFMEMORY;
741 object->lpVtbl = &IDirect3DExecuteBuffer_Vtbl;
742 object->ref = 1;
743 object->d3ddev = This;
745 /* Initializes memory */
746 memcpy(&object->desc, Desc, Desc->dwSize);
748 /* No buffer given */
749 if ((object->desc.dwFlags & D3DDEB_LPDATA) == 0)
750 object->desc.lpData = NULL;
752 /* No buffer size given */
753 if ((object->desc.dwFlags & D3DDEB_BUFSIZE) == 0)
754 object->desc.dwBufferSize = 0;
756 /* Create buffer if asked */
757 if ((object->desc.lpData == NULL) && (object->desc.dwBufferSize > 0))
759 object->need_free = TRUE;
760 object->desc.lpData = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,object->desc.dwBufferSize);
761 if(!object->desc.lpData)
763 ERR("Out of memory when allocating the execute buffer data\n");
764 HeapFree(GetProcessHeap(), 0, object);
765 return DDERR_OUTOFMEMORY;
768 else
770 object->need_free = FALSE;
773 /* No vertices for the moment */
774 object->vertex_data = NULL;
776 object->desc.dwFlags |= D3DDEB_LPDATA;
778 object->indices = NULL;
779 object->nb_indices = 0;
781 *ExecuteBuffer = (IDirect3DExecuteBuffer *)object;
783 TRACE(" Returning IDirect3DExecuteBuffer at %p, implementation is at %p\n", *ExecuteBuffer, object);
785 return D3D_OK;
788 /*****************************************************************************
789 * IDirect3DDevice::Execute
791 * Executes all the stuff in an execute buffer.
793 * Params:
794 * ExecuteBuffer: The buffer to execute
795 * Viewport: The viewport used for rendering
796 * Flags: Some flags
798 * Returns:
799 * DDERR_INVALIDPARAMS if ExecuteBuffer == NULL
800 * D3D_OK on success
802 *****************************************************************************/
803 static HRESULT WINAPI
804 IDirect3DDeviceImpl_1_Execute(IDirect3DDevice *iface,
805 IDirect3DExecuteBuffer *ExecuteBuffer,
806 IDirect3DViewport *Viewport,
807 DWORD Flags)
809 IDirect3DDeviceImpl *This = device_from_device1(iface);
810 IDirect3DExecuteBufferImpl *Direct3DExecuteBufferImpl = (IDirect3DExecuteBufferImpl *)ExecuteBuffer;
811 IDirect3DViewportImpl *Direct3DViewportImpl = (IDirect3DViewportImpl *)Viewport;
813 TRACE("(%p)->(%p,%p,%08x)\n", This, Direct3DExecuteBufferImpl, Direct3DViewportImpl, Flags);
815 if(!Direct3DExecuteBufferImpl)
816 return DDERR_INVALIDPARAMS;
818 /* Execute... */
819 EnterCriticalSection(&ddraw_cs);
820 IDirect3DExecuteBufferImpl_Execute(Direct3DExecuteBufferImpl, This, Direct3DViewportImpl);
821 LeaveCriticalSection(&ddraw_cs);
823 return D3D_OK;
826 /*****************************************************************************
827 * IDirect3DDevice3::AddViewport
829 * Add a Direct3DViewport to the device's viewport list. These viewports
830 * are wrapped to IDirect3DDevice7 viewports in viewport.c
832 * Exists in Version 1, 2 and 3. Note that IDirect3DViewport 1, 2 and 3
833 * are the same interfaces.
835 * Params:
836 * Viewport: The viewport to add
838 * Returns:
839 * DDERR_INVALIDPARAMS if Viewport == NULL
840 * D3D_OK on success
842 *****************************************************************************/
843 static HRESULT WINAPI
844 IDirect3DDeviceImpl_3_AddViewport(IDirect3DDevice3 *iface,
845 IDirect3DViewport3 *Viewport)
847 IDirect3DDeviceImpl *This = device_from_device3(iface);
848 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Viewport;
850 TRACE("(%p)->(%p)\n", This, vp);
852 /* Sanity check */
853 if(!vp)
854 return DDERR_INVALIDPARAMS;
856 EnterCriticalSection(&ddraw_cs);
857 vp->next = This->viewport_list;
858 This->viewport_list = vp;
859 vp->active_device = This; /* Viewport must be usable for Clear() after AddViewport,
860 so set active_device here. */
861 LeaveCriticalSection(&ddraw_cs);
863 return D3D_OK;
866 static HRESULT WINAPI
867 Thunk_IDirect3DDeviceImpl_2_AddViewport(IDirect3DDevice2 *iface,
868 IDirect3DViewport2 *Direct3DViewport2)
870 IDirect3DDeviceImpl *This = device_from_device2(iface);
871 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Direct3DViewport2;
872 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
873 return IDirect3DDevice3_AddViewport((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, (IDirect3DViewport3 *)vp);
876 static HRESULT WINAPI
877 Thunk_IDirect3DDeviceImpl_1_AddViewport(IDirect3DDevice *iface,
878 IDirect3DViewport *Direct3DViewport)
880 IDirect3DDeviceImpl *This = device_from_device1(iface);
881 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Direct3DViewport;
882 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
883 return IDirect3DDevice3_AddViewport((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, (IDirect3DViewport3 *)vp);
886 /*****************************************************************************
887 * IDirect3DDevice3::DeleteViewport
889 * Deletes a Direct3DViewport from the device's viewport list.
891 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
892 * are equal.
894 * Params:
895 * Viewport: The viewport to delete
897 * Returns:
898 * D3D_OK on success
899 * DDERR_INVALIDPARAMS if the viewport wasn't found in the list
901 *****************************************************************************/
902 static HRESULT WINAPI
903 IDirect3DDeviceImpl_3_DeleteViewport(IDirect3DDevice3 *iface,
904 IDirect3DViewport3 *Viewport)
906 IDirect3DDeviceImpl *This = device_from_device3(iface);
907 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *) Viewport;
908 IDirect3DViewportImpl *cur_viewport, *prev_viewport = NULL;
910 TRACE("(%p)->(%p)\n", This, vp);
912 EnterCriticalSection(&ddraw_cs);
913 cur_viewport = This->viewport_list;
914 while (cur_viewport != NULL)
916 if (cur_viewport == vp)
918 if (prev_viewport == NULL) This->viewport_list = cur_viewport->next;
919 else prev_viewport->next = cur_viewport->next;
920 /* TODO : add desactivate of the viewport and all associated lights... */
921 LeaveCriticalSection(&ddraw_cs);
922 return D3D_OK;
924 prev_viewport = cur_viewport;
925 cur_viewport = cur_viewport->next;
928 LeaveCriticalSection(&ddraw_cs);
929 return DDERR_INVALIDPARAMS;
932 static HRESULT WINAPI
933 Thunk_IDirect3DDeviceImpl_2_DeleteViewport(IDirect3DDevice2 *iface,
934 IDirect3DViewport2 *Direct3DViewport2)
936 IDirect3DDeviceImpl *This = device_from_device2(iface);
937 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Direct3DViewport2;
938 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
939 return IDirect3DDevice3_DeleteViewport((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, (IDirect3DViewport3 *)vp);
942 static HRESULT WINAPI
943 Thunk_IDirect3DDeviceImpl_1_DeleteViewport(IDirect3DDevice *iface,
944 IDirect3DViewport *Direct3DViewport)
946 IDirect3DDeviceImpl *This = device_from_device1(iface);
947 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Direct3DViewport;
948 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
949 return IDirect3DDevice3_DeleteViewport((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, (IDirect3DViewport3 *)vp);
952 /*****************************************************************************
953 * IDirect3DDevice3::NextViewport
955 * Returns a viewport from the viewport list, depending on the
956 * passed viewport and the flags.
958 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
959 * are equal.
961 * Params:
962 * Viewport: Viewport to use for beginning the search
963 * Flags: D3DNEXT_NEXT, D3DNEXT_HEAD or D3DNEXT_TAIL
965 * Returns:
966 * D3D_OK on success
967 * DDERR_INVALIDPARAMS if the flags were wrong, or Viewport was NULL
969 *****************************************************************************/
970 static HRESULT WINAPI
971 IDirect3DDeviceImpl_3_NextViewport(IDirect3DDevice3 *iface,
972 IDirect3DViewport3 *Viewport3,
973 IDirect3DViewport3 **lplpDirect3DViewport3,
974 DWORD Flags)
976 IDirect3DDeviceImpl *This = device_from_device3(iface);
977 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Viewport3;
978 IDirect3DViewportImpl *res = NULL;
980 TRACE("(%p)->(%p,%p,%08x)\n", This, vp, lplpDirect3DViewport3, Flags);
982 if(!vp)
984 *lplpDirect3DViewport3 = NULL;
985 return DDERR_INVALIDPARAMS;
989 EnterCriticalSection(&ddraw_cs);
990 switch (Flags)
992 case D3DNEXT_NEXT:
994 res = vp->next;
996 break;
997 case D3DNEXT_HEAD:
999 res = This->viewport_list;
1001 break;
1002 case D3DNEXT_TAIL:
1004 IDirect3DViewportImpl *cur_viewport = This->viewport_list;
1005 if (cur_viewport != NULL)
1007 while (cur_viewport->next != NULL) cur_viewport = cur_viewport->next;
1009 res = cur_viewport;
1011 break;
1012 default:
1013 *lplpDirect3DViewport3 = NULL;
1014 LeaveCriticalSection(&ddraw_cs);
1015 return DDERR_INVALIDPARAMS;
1018 *lplpDirect3DViewport3 = (IDirect3DViewport3 *)res;
1019 LeaveCriticalSection(&ddraw_cs);
1020 return D3D_OK;
1023 static HRESULT WINAPI
1024 Thunk_IDirect3DDeviceImpl_2_NextViewport(IDirect3DDevice2 *iface,
1025 IDirect3DViewport2 *Viewport2,
1026 IDirect3DViewport2 **lplpDirect3DViewport2,
1027 DWORD Flags)
1029 IDirect3DDeviceImpl *This = device_from_device2(iface);
1030 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Viewport2;
1031 IDirect3DViewport3 *res;
1032 HRESULT hr;
1033 TRACE_(ddraw_thunk)("(%p)->(%p,%p,%08x) thunking to IDirect3DDevice3 interface.\n", This, vp, lplpDirect3DViewport2, Flags);
1034 hr = IDirect3DDevice3_NextViewport((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl,
1035 (IDirect3DViewport3 *)vp, &res, Flags);
1036 *lplpDirect3DViewport2 = (IDirect3DViewport2 *)res;
1037 return hr;
1040 static HRESULT WINAPI
1041 Thunk_IDirect3DDeviceImpl_1_NextViewport(IDirect3DDevice *iface,
1042 IDirect3DViewport *Viewport,
1043 IDirect3DViewport **lplpDirect3DViewport,
1044 DWORD Flags)
1046 IDirect3DDeviceImpl *This = device_from_device1(iface);
1047 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Viewport;
1048 IDirect3DViewport3 *res;
1049 HRESULT hr;
1050 TRACE_(ddraw_thunk)("(%p)->(%p,%p,%08x) thunking to IDirect3DDevice3 interface.\n", This, vp, lplpDirect3DViewport, Flags);
1051 hr = IDirect3DDevice3_NextViewport((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl,
1052 (IDirect3DViewport3 *)vp, &res, Flags);
1053 *lplpDirect3DViewport = (IDirect3DViewport *)res;
1054 return hr;
1057 /*****************************************************************************
1058 * IDirect3DDevice::Pick
1060 * Executes an execute buffer without performing rendering. Instead, a
1061 * list of primitives that intersect with (x1,y1) of the passed rectangle
1062 * is created. IDirect3DDevice::GetPickRecords can be used to retrieve
1063 * this list.
1065 * Version 1 only
1067 * Params:
1068 * ExecuteBuffer: Buffer to execute
1069 * Viewport: Viewport to use for execution
1070 * Flags: None are defined, according to the SDK
1071 * Rect: Specifies the coordinates to be picked. Only x1 and y2 are used,
1072 * x2 and y2 are ignored.
1074 * Returns:
1075 * D3D_OK because it's a stub
1077 *****************************************************************************/
1078 static HRESULT WINAPI
1079 IDirect3DDeviceImpl_1_Pick(IDirect3DDevice *iface,
1080 IDirect3DExecuteBuffer *ExecuteBuffer,
1081 IDirect3DViewport *Viewport,
1082 DWORD Flags,
1083 D3DRECT *Rect)
1085 IDirect3DDeviceImpl *This = device_from_device1(iface);
1086 IDirect3DExecuteBufferImpl *execbuf = (IDirect3DExecuteBufferImpl *)ExecuteBuffer;
1087 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Viewport;
1088 FIXME("(%p)->(%p,%p,%08x,%p): stub!\n", This, execbuf, vp, Flags, Rect);
1090 return D3D_OK;
1093 /*****************************************************************************
1094 * IDirect3DDevice::GetPickRecords
1096 * Retrieves the pick records generated by IDirect3DDevice::GetPickRecords
1098 * Version 1 only
1100 * Params:
1101 * Count: Pointer to a DWORD containing the numbers of pick records to
1102 * retrieve
1103 * D3DPickRec: Address to store the resulting D3DPICKRECORD array.
1105 * Returns:
1106 * D3D_OK, because it's a stub
1108 *****************************************************************************/
1109 static HRESULT WINAPI
1110 IDirect3DDeviceImpl_1_GetPickRecords(IDirect3DDevice *iface,
1111 DWORD *Count,
1112 D3DPICKRECORD *D3DPickRec)
1114 IDirect3DDeviceImpl *This = device_from_device1(iface);
1115 FIXME("(%p)->(%p,%p): stub!\n", This, Count, D3DPickRec);
1117 return D3D_OK;
1120 /*****************************************************************************
1121 * IDirect3DDevice7::EnumTextureformats
1123 * Enumerates the supported texture formats. It has a list of all possible
1124 * formats and calls IWineD3D::CheckDeviceFormat for each format to see if
1125 * WineD3D supports it. If so, then it is passed to the app.
1127 * This is for Version 7 and 3, older versions have a different
1128 * callback function and their own implementation
1130 * Params:
1131 * Callback: Callback to call for each enumerated format
1132 * Arg: Argument to pass to the callback
1134 * Returns:
1135 * D3D_OK on success
1136 * DDERR_INVALIDPARAMS if Callback == NULL
1138 *****************************************************************************/
1139 static HRESULT
1140 IDirect3DDeviceImpl_7_EnumTextureFormats(IDirect3DDevice7 *iface,
1141 LPD3DENUMPIXELFORMATSCALLBACK Callback,
1142 void *Arg)
1144 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
1145 HRESULT hr;
1146 WINED3DDISPLAYMODE mode;
1147 unsigned int i;
1149 WINED3DFORMAT FormatList[] = {
1150 /* 32 bit */
1151 WINED3DFMT_B8G8R8A8_UNORM,
1152 WINED3DFMT_B8G8R8X8_UNORM,
1153 /* 24 bit */
1154 WINED3DFMT_B8G8R8_UNORM,
1155 /* 16 Bit */
1156 WINED3DFMT_B5G5R5A1_UNORM,
1157 WINED3DFMT_B4G4R4A4_UNORM,
1158 WINED3DFMT_B5G6R5_UNORM,
1159 WINED3DFMT_B5G5R5X1_UNORM,
1160 /* 8 Bit */
1161 WINED3DFMT_B2G3R3_UNORM,
1162 WINED3DFMT_P8_UINT,
1163 /* FOURCC codes */
1164 WINED3DFMT_DXT1,
1165 WINED3DFMT_DXT3,
1166 WINED3DFMT_DXT5,
1169 WINED3DFORMAT BumpFormatList[] = {
1170 WINED3DFMT_R8G8_SNORM,
1171 WINED3DFMT_R5G5_SNORM_L6_UNORM,
1172 WINED3DFMT_R8G8_SNORM_L8X8_UNORM,
1173 WINED3DFMT_R8G8B8A8_SNORM,
1174 WINED3DFMT_R16G16_SNORM,
1175 WINED3DFMT_R10G11B11_SNORM,
1176 WINED3DFMT_R10G10B10_SNORM_A2_UNORM
1179 TRACE("(%p)->(%p,%p): Relay\n", This, Callback, Arg);
1181 if(!Callback)
1182 return DDERR_INVALIDPARAMS;
1184 EnterCriticalSection(&ddraw_cs);
1186 memset(&mode, 0, sizeof(mode));
1187 hr = IWineD3DDevice_GetDisplayMode(This->ddraw->wineD3DDevice,
1189 &mode);
1190 if(FAILED(hr)) {
1191 LeaveCriticalSection(&ddraw_cs);
1192 WARN("Cannot get the current adapter format\n");
1193 return hr;
1196 for(i = 0; i < sizeof(FormatList) / sizeof(WINED3DFORMAT); i++)
1198 hr = IWineD3D_CheckDeviceFormat(This->ddraw->wineD3D,
1199 WINED3DADAPTER_DEFAULT,
1200 WINED3DDEVTYPE_HAL,
1201 mode.Format,
1202 0 /* Usage */,
1203 WINED3DRTYPE_TEXTURE,
1204 FormatList[i],
1205 SURFACE_OPENGL);
1206 if(hr == D3D_OK)
1208 DDPIXELFORMAT pformat;
1210 memset(&pformat, 0, sizeof(pformat));
1211 pformat.dwSize = sizeof(pformat);
1212 PixelFormat_WineD3DtoDD(&pformat, FormatList[i]);
1214 TRACE("Enumerating WineD3DFormat %d\n", FormatList[i]);
1215 hr = Callback(&pformat, Arg);
1216 if(hr != DDENUMRET_OK)
1218 TRACE("Format enumeration cancelled by application\n");
1219 LeaveCriticalSection(&ddraw_cs);
1220 return D3D_OK;
1225 for(i = 0; i < sizeof(BumpFormatList) / sizeof(WINED3DFORMAT); i++)
1227 hr = IWineD3D_CheckDeviceFormat(This->ddraw->wineD3D,
1228 WINED3DADAPTER_DEFAULT,
1229 WINED3DDEVTYPE_HAL,
1230 mode.Format,
1231 WINED3DUSAGE_QUERY_LEGACYBUMPMAP,
1232 WINED3DRTYPE_TEXTURE,
1233 BumpFormatList[i],
1234 SURFACE_OPENGL);
1235 if(hr == D3D_OK)
1237 DDPIXELFORMAT pformat;
1239 memset(&pformat, 0, sizeof(pformat));
1240 pformat.dwSize = sizeof(pformat);
1241 PixelFormat_WineD3DtoDD(&pformat, BumpFormatList[i]);
1243 TRACE("Enumerating WineD3DFormat %d\n", BumpFormatList[i]);
1244 hr = Callback(&pformat, Arg);
1245 if(hr != DDENUMRET_OK)
1247 TRACE("Format enumeration cancelled by application\n");
1248 LeaveCriticalSection(&ddraw_cs);
1249 return D3D_OK;
1253 TRACE("End of enumeration\n");
1254 LeaveCriticalSection(&ddraw_cs);
1255 return D3D_OK;
1258 static HRESULT WINAPI
1259 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUSetup(IDirect3DDevice7 *iface,
1260 LPD3DENUMPIXELFORMATSCALLBACK Callback,
1261 void *Arg)
1263 return IDirect3DDeviceImpl_7_EnumTextureFormats(iface, Callback, Arg);
1266 static HRESULT WINAPI
1267 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUPreserve(IDirect3DDevice7 *iface,
1268 LPD3DENUMPIXELFORMATSCALLBACK Callback,
1269 void *Arg)
1271 HRESULT hr;
1272 WORD old_fpucw;
1274 old_fpucw = d3d_fpu_setup();
1275 hr = IDirect3DDeviceImpl_7_EnumTextureFormats(iface, Callback, Arg);
1276 set_fpu_control_word(old_fpucw);
1278 return hr;
1281 static HRESULT WINAPI
1282 Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats(IDirect3DDevice3 *iface,
1283 LPD3DENUMPIXELFORMATSCALLBACK Callback,
1284 void *Arg)
1286 IDirect3DDeviceImpl *This = device_from_device3(iface);
1287 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice7 interface.\n", This, Callback, Arg);
1288 return IDirect3DDevice7_EnumTextureFormats((IDirect3DDevice7 *)This, Callback, Arg);
1291 /*****************************************************************************
1292 * IDirect3DDevice2::EnumTextureformats
1294 * EnumTextureFormats for Version 1 and 2, see
1295 * IDirect3DDevice7::EnumTexureFormats for a more detailed description.
1297 * This version has a different callback and does not enumerate FourCC
1298 * formats
1300 *****************************************************************************/
1301 static HRESULT WINAPI
1302 IDirect3DDeviceImpl_2_EnumTextureFormats(IDirect3DDevice2 *iface,
1303 LPD3DENUMTEXTUREFORMATSCALLBACK Callback,
1304 void *Arg)
1306 IDirect3DDeviceImpl *This = device_from_device2(iface);
1307 HRESULT hr;
1308 unsigned int i;
1309 WINED3DDISPLAYMODE mode;
1311 WINED3DFORMAT FormatList[] = {
1312 /* 32 bit */
1313 WINED3DFMT_B8G8R8A8_UNORM,
1314 WINED3DFMT_B8G8R8X8_UNORM,
1315 /* 24 bit */
1316 WINED3DFMT_B8G8R8_UNORM,
1317 /* 16 Bit */
1318 WINED3DFMT_B5G5R5A1_UNORM,
1319 WINED3DFMT_B4G4R4A4_UNORM,
1320 WINED3DFMT_B5G6R5_UNORM,
1321 WINED3DFMT_B5G5R5X1_UNORM,
1322 /* 8 Bit */
1323 WINED3DFMT_B2G3R3_UNORM,
1324 WINED3DFMT_P8_UINT,
1325 /* FOURCC codes - Not in this version*/
1328 TRACE("(%p)->(%p,%p): Relay\n", This, Callback, Arg);
1330 if(!Callback)
1331 return DDERR_INVALIDPARAMS;
1333 EnterCriticalSection(&ddraw_cs);
1335 memset(&mode, 0, sizeof(mode));
1336 hr = IWineD3DDevice_GetDisplayMode(This->ddraw->wineD3DDevice,
1338 &mode);
1339 if(FAILED(hr)) {
1340 LeaveCriticalSection(&ddraw_cs);
1341 WARN("Cannot get the current adapter format\n");
1342 return hr;
1345 for(i = 0; i < sizeof(FormatList) / sizeof(WINED3DFORMAT); i++)
1347 hr = IWineD3D_CheckDeviceFormat(This->ddraw->wineD3D,
1348 0 /* Adapter */,
1349 WINED3DDEVTYPE_HAL,
1350 mode.Format,
1351 0 /* Usage */,
1352 WINED3DRTYPE_TEXTURE,
1353 FormatList[i],
1354 SURFACE_OPENGL);
1355 if(hr == D3D_OK)
1357 DDSURFACEDESC sdesc;
1359 memset(&sdesc, 0, sizeof(sdesc));
1360 sdesc.dwSize = sizeof(sdesc);
1361 sdesc.dwFlags = DDSD_PIXELFORMAT | DDSD_CAPS;
1362 sdesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1363 sdesc.ddpfPixelFormat.dwSize = sizeof(sdesc.ddpfPixelFormat);
1364 PixelFormat_WineD3DtoDD(&sdesc.ddpfPixelFormat, FormatList[i]);
1366 TRACE("Enumerating WineD3DFormat %d\n", FormatList[i]);
1367 hr = Callback(&sdesc, Arg);
1368 if(hr != DDENUMRET_OK)
1370 TRACE("Format enumeration cancelled by application\n");
1371 LeaveCriticalSection(&ddraw_cs);
1372 return D3D_OK;
1376 TRACE("End of enumeration\n");
1377 LeaveCriticalSection(&ddraw_cs);
1378 return D3D_OK;
1381 static HRESULT WINAPI
1382 Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats(IDirect3DDevice *iface,
1383 LPD3DENUMTEXTUREFORMATSCALLBACK Callback,
1384 void *Arg)
1386 IDirect3DDeviceImpl *This = device_from_device1(iface);
1387 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice2 interface.\n", This, Callback, Arg);
1388 return IDirect3DDevice2_EnumTextureFormats((IDirect3DDevice2 *)&This->IDirect3DDevice2_vtbl, Callback, Arg);
1391 /*****************************************************************************
1392 * IDirect3DDevice::CreateMatrix
1394 * Creates a matrix handle. A handle is created and memory for a D3DMATRIX is
1395 * allocated for the handle.
1397 * Version 1 only
1399 * Params
1400 * D3DMatHandle: Address to return the handle at
1402 * Returns:
1403 * D3D_OK on success
1404 * DDERR_INVALIDPARAMS if D3DMatHandle = NULL
1406 *****************************************************************************/
1407 static HRESULT WINAPI
1408 IDirect3DDeviceImpl_1_CreateMatrix(IDirect3DDevice *iface, D3DMATRIXHANDLE *D3DMatHandle)
1410 IDirect3DDeviceImpl *This = device_from_device1(iface);
1411 D3DMATRIX *Matrix;
1412 TRACE("(%p)->(%p)\n", This, D3DMatHandle);
1414 if(!D3DMatHandle)
1415 return DDERR_INVALIDPARAMS;
1417 Matrix = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(D3DMATRIX));
1418 if(!Matrix)
1420 ERR("Out of memory when allocating a D3DMATRIX\n");
1421 return DDERR_OUTOFMEMORY;
1424 EnterCriticalSection(&ddraw_cs);
1425 *D3DMatHandle = IDirect3DDeviceImpl_CreateHandle(This);
1426 if(!(*D3DMatHandle))
1428 ERR("Failed to create a matrix handle\n");
1429 HeapFree(GetProcessHeap(), 0, Matrix);
1430 LeaveCriticalSection(&ddraw_cs);
1431 return DDERR_OUTOFMEMORY;
1433 This->Handles[*D3DMatHandle - 1].ptr = Matrix;
1434 This->Handles[*D3DMatHandle - 1].type = DDrawHandle_Matrix;
1435 TRACE(" returning matrix handle %d\n", *D3DMatHandle);
1437 LeaveCriticalSection(&ddraw_cs);
1438 return D3D_OK;
1441 /*****************************************************************************
1442 * IDirect3DDevice::SetMatrix
1444 * Sets a matrix for a matrix handle. The matrix is copied into the memory
1445 * allocated for the handle
1447 * Version 1 only
1449 * Params:
1450 * D3DMatHandle: Handle to set the matrix to
1451 * D3DMatrix: Matrix to set
1453 * Returns:
1454 * D3D_OK on success
1455 * DDERR_INVALIDPARAMS if the handle of the matrix is invalid or the matrix
1456 * to set is NULL
1458 *****************************************************************************/
1459 static HRESULT WINAPI
1460 IDirect3DDeviceImpl_1_SetMatrix(IDirect3DDevice *iface,
1461 D3DMATRIXHANDLE D3DMatHandle,
1462 D3DMATRIX *D3DMatrix)
1464 IDirect3DDeviceImpl *This = device_from_device1(iface);
1465 TRACE("(%p)->(%08x,%p)\n", This, D3DMatHandle, D3DMatrix);
1467 if( (!D3DMatHandle) || (!D3DMatrix) )
1468 return DDERR_INVALIDPARAMS;
1470 EnterCriticalSection(&ddraw_cs);
1471 if(D3DMatHandle > This->numHandles)
1473 ERR("Handle %d out of range\n", D3DMatHandle);
1474 LeaveCriticalSection(&ddraw_cs);
1475 return DDERR_INVALIDPARAMS;
1477 else if(This->Handles[D3DMatHandle - 1].type != DDrawHandle_Matrix)
1479 ERR("Handle %d is not a matrix handle\n", D3DMatHandle);
1480 LeaveCriticalSection(&ddraw_cs);
1481 return DDERR_INVALIDPARAMS;
1484 if (TRACE_ON(d3d7))
1485 dump_D3DMATRIX(D3DMatrix);
1487 *((D3DMATRIX *) This->Handles[D3DMatHandle - 1].ptr) = *D3DMatrix;
1489 if(This->world == D3DMatHandle)
1491 IWineD3DDevice_SetTransform(This->wineD3DDevice,
1492 WINED3DTS_WORLDMATRIX(0),
1493 (WINED3DMATRIX *) D3DMatrix);
1495 if(This->view == D3DMatHandle)
1497 IWineD3DDevice_SetTransform(This->wineD3DDevice,
1498 WINED3DTS_VIEW,
1499 (WINED3DMATRIX *) D3DMatrix);
1501 if(This->proj == D3DMatHandle)
1503 IWineD3DDevice_SetTransform(This->wineD3DDevice,
1504 WINED3DTS_PROJECTION,
1505 (WINED3DMATRIX *) D3DMatrix);
1508 LeaveCriticalSection(&ddraw_cs);
1509 return D3D_OK;
1512 /*****************************************************************************
1513 * IDirect3DDevice::SetMatrix
1515 * Returns the content of a D3DMATRIX handle
1517 * Version 1 only
1519 * Params:
1520 * D3DMatHandle: Matrix handle to read the content from
1521 * D3DMatrix: Address to store the content at
1523 * Returns:
1524 * D3D_OK on success
1525 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid or D3DMatrix is NULL
1527 *****************************************************************************/
1528 static HRESULT WINAPI
1529 IDirect3DDeviceImpl_1_GetMatrix(IDirect3DDevice *iface,
1530 D3DMATRIXHANDLE D3DMatHandle,
1531 D3DMATRIX *D3DMatrix)
1533 IDirect3DDeviceImpl *This = device_from_device1(iface);
1534 TRACE("(%p)->(%08x,%p)\n", This, D3DMatHandle, D3DMatrix);
1536 if(!D3DMatrix)
1537 return DDERR_INVALIDPARAMS;
1538 if(!D3DMatHandle)
1539 return DDERR_INVALIDPARAMS;
1541 EnterCriticalSection(&ddraw_cs);
1542 if(D3DMatHandle > This->numHandles)
1544 ERR("Handle %d out of range\n", D3DMatHandle);
1545 LeaveCriticalSection(&ddraw_cs);
1546 return DDERR_INVALIDPARAMS;
1548 else if(This->Handles[D3DMatHandle - 1].type != DDrawHandle_Matrix)
1550 ERR("Handle %d is not a matrix handle\n", D3DMatHandle);
1551 LeaveCriticalSection(&ddraw_cs);
1552 return DDERR_INVALIDPARAMS;
1555 /* The handle is simply a pointer to a D3DMATRIX structure */
1556 *D3DMatrix = *((D3DMATRIX *) This->Handles[D3DMatHandle - 1].ptr);
1558 LeaveCriticalSection(&ddraw_cs);
1559 return D3D_OK;
1562 /*****************************************************************************
1563 * IDirect3DDevice::DeleteMatrix
1565 * Destroys a Matrix handle. Frees the memory and unsets the handle data
1567 * Version 1 only
1569 * Params:
1570 * D3DMatHandle: Handle to destroy
1572 * Returns:
1573 * D3D_OK on success
1574 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid
1576 *****************************************************************************/
1577 static HRESULT WINAPI
1578 IDirect3DDeviceImpl_1_DeleteMatrix(IDirect3DDevice *iface,
1579 D3DMATRIXHANDLE D3DMatHandle)
1581 IDirect3DDeviceImpl *This = device_from_device1(iface);
1582 TRACE("(%p)->(%08x)\n", This, D3DMatHandle);
1584 if(!D3DMatHandle)
1585 return DDERR_INVALIDPARAMS;
1587 EnterCriticalSection(&ddraw_cs);
1588 if(D3DMatHandle > This->numHandles)
1590 ERR("Handle %d out of range\n", D3DMatHandle);
1591 LeaveCriticalSection(&ddraw_cs);
1592 return DDERR_INVALIDPARAMS;
1594 else if(This->Handles[D3DMatHandle - 1].type != DDrawHandle_Matrix)
1596 ERR("Handle %d is not a matrix handle\n", D3DMatHandle);
1597 LeaveCriticalSection(&ddraw_cs);
1598 return DDERR_INVALIDPARAMS;
1601 HeapFree(GetProcessHeap(), 0, This->Handles[D3DMatHandle - 1].ptr);
1602 This->Handles[D3DMatHandle - 1].ptr = NULL;
1603 This->Handles[D3DMatHandle - 1].type = DDrawHandle_Unknown;
1605 LeaveCriticalSection(&ddraw_cs);
1606 return D3D_OK;
1609 /*****************************************************************************
1610 * IDirect3DDevice7::BeginScene
1612 * This method must be called before any rendering is performed.
1613 * IDirect3DDevice::EndScene has to be called after the scene is complete
1615 * Version 1, 2, 3 and 7
1617 * Returns:
1618 * D3D_OK on success, for details see IWineD3DDevice::BeginScene
1619 * D3DERR_SCENE_IN_SCENE if WineD3D returns an error(Only in case of an already
1620 * started scene).
1622 *****************************************************************************/
1623 static HRESULT
1624 IDirect3DDeviceImpl_7_BeginScene(IDirect3DDevice7 *iface)
1626 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
1627 HRESULT hr;
1628 TRACE("(%p): Relay\n", This);
1630 EnterCriticalSection(&ddraw_cs);
1631 hr = IWineD3DDevice_BeginScene(This->wineD3DDevice);
1632 LeaveCriticalSection(&ddraw_cs);
1633 if(hr == WINED3D_OK) return D3D_OK;
1634 else return D3DERR_SCENE_IN_SCENE; /* TODO: Other possible causes of failure */
1637 static HRESULT WINAPI
1638 IDirect3DDeviceImpl_7_BeginScene_FPUSetup(IDirect3DDevice7 *iface)
1640 return IDirect3DDeviceImpl_7_BeginScene(iface);
1643 static HRESULT WINAPI
1644 IDirect3DDeviceImpl_7_BeginScene_FPUPreserve(IDirect3DDevice7 *iface)
1646 HRESULT hr;
1647 WORD old_fpucw;
1649 old_fpucw = d3d_fpu_setup();
1650 hr = IDirect3DDeviceImpl_7_BeginScene(iface);
1651 set_fpu_control_word(old_fpucw);
1653 return hr;
1656 static HRESULT WINAPI
1657 Thunk_IDirect3DDeviceImpl_3_BeginScene(IDirect3DDevice3 *iface)
1659 IDirect3DDeviceImpl *This = device_from_device3(iface);
1660 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1661 return IDirect3DDevice7_BeginScene((IDirect3DDevice7 *)This);
1664 static HRESULT WINAPI
1665 Thunk_IDirect3DDeviceImpl_2_BeginScene(IDirect3DDevice2 *iface)
1667 IDirect3DDeviceImpl *This = device_from_device2(iface);
1668 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1669 return IDirect3DDevice7_BeginScene((IDirect3DDevice7 *)This);
1672 static HRESULT WINAPI
1673 Thunk_IDirect3DDeviceImpl_1_BeginScene(IDirect3DDevice *iface)
1675 IDirect3DDeviceImpl *This = device_from_device1(iface);
1676 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1677 return IDirect3DDevice7_BeginScene((IDirect3DDevice7 *)This);
1680 /*****************************************************************************
1681 * IDirect3DDevice7::EndScene
1683 * Ends a scene that has been begun with IDirect3DDevice7::BeginScene.
1684 * This method must be called after rendering is finished.
1686 * Version 1, 2, 3 and 7
1688 * Returns:
1689 * D3D_OK on success, for details see IWineD3DDevice::EndScene
1690 * D3DERR_SCENE_NOT_IN_SCENE is returned if WineD3D returns an error. It does
1691 * that only if the scene was already ended.
1693 *****************************************************************************/
1694 static HRESULT
1695 IDirect3DDeviceImpl_7_EndScene(IDirect3DDevice7 *iface)
1697 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
1698 HRESULT hr;
1699 TRACE("(%p): Relay\n", This);
1701 EnterCriticalSection(&ddraw_cs);
1702 hr = IWineD3DDevice_EndScene(This->wineD3DDevice);
1703 LeaveCriticalSection(&ddraw_cs);
1704 if(hr == WINED3D_OK) return D3D_OK;
1705 else return D3DERR_SCENE_NOT_IN_SCENE;
1708 static HRESULT WINAPI DECLSPEC_HOTPATCH
1709 IDirect3DDeviceImpl_7_EndScene_FPUSetup(IDirect3DDevice7 *iface)
1711 return IDirect3DDeviceImpl_7_EndScene(iface);
1714 static HRESULT WINAPI DECLSPEC_HOTPATCH
1715 IDirect3DDeviceImpl_7_EndScene_FPUPreserve(IDirect3DDevice7 *iface)
1717 HRESULT hr;
1718 WORD old_fpucw;
1720 old_fpucw = d3d_fpu_setup();
1721 hr = IDirect3DDeviceImpl_7_EndScene(iface);
1722 set_fpu_control_word(old_fpucw);
1724 return hr;
1727 static HRESULT WINAPI DECLSPEC_HOTPATCH
1728 Thunk_IDirect3DDeviceImpl_3_EndScene(IDirect3DDevice3 *iface)
1730 IDirect3DDeviceImpl *This = device_from_device3(iface);
1731 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1732 return IDirect3DDevice7_EndScene((IDirect3DDevice7 *)This);
1735 static HRESULT WINAPI DECLSPEC_HOTPATCH
1736 Thunk_IDirect3DDeviceImpl_2_EndScene(IDirect3DDevice2 *iface)
1738 IDirect3DDeviceImpl *This = device_from_device2(iface);
1739 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1740 return IDirect3DDevice7_EndScene((IDirect3DDevice7 *)This);
1743 static HRESULT WINAPI DECLSPEC_HOTPATCH
1744 Thunk_IDirect3DDeviceImpl_1_EndScene(IDirect3DDevice *iface)
1746 IDirect3DDeviceImpl *This = device_from_device1(iface);
1747 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1748 return IDirect3DDevice7_EndScene((IDirect3DDevice7 *)This);
1751 /*****************************************************************************
1752 * IDirect3DDevice7::GetDirect3D
1754 * Returns the IDirect3D(= interface to the DirectDraw object) used to create
1755 * this device.
1757 * Params:
1758 * Direct3D7: Address to store the interface pointer at
1760 * Returns:
1761 * D3D_OK on success
1762 * DDERR_INVALIDPARAMS if Direct3D7 == NULL
1764 *****************************************************************************/
1765 static HRESULT WINAPI
1766 IDirect3DDeviceImpl_7_GetDirect3D(IDirect3DDevice7 *iface,
1767 IDirect3D7 **Direct3D7)
1769 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
1770 TRACE("(%p)->(%p)\n", This, Direct3D7);
1772 if(!Direct3D7)
1773 return DDERR_INVALIDPARAMS;
1775 *Direct3D7 = (IDirect3D7 *)&This->ddraw->IDirect3D7_vtbl;
1776 IDirect3D7_AddRef(*Direct3D7);
1778 TRACE(" returning interface %p\n", *Direct3D7);
1779 return D3D_OK;
1782 static HRESULT WINAPI
1783 Thunk_IDirect3DDeviceImpl_3_GetDirect3D(IDirect3DDevice3 *iface,
1784 IDirect3D3 **Direct3D3)
1786 IDirect3DDeviceImpl *This = device_from_device3(iface);
1787 HRESULT ret;
1788 IDirect3D7 *ret_ptr;
1790 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Direct3D3);
1791 ret = IDirect3DDevice7_GetDirect3D((IDirect3DDevice7 *)This, &ret_ptr);
1792 if(ret != D3D_OK)
1793 return ret;
1794 *Direct3D3 = ret_ptr ? (IDirect3D3 *)&ddraw_from_d3d7(ret_ptr)->IDirect3D3_vtbl : NULL;
1795 TRACE(" returning interface %p\n", *Direct3D3);
1796 return D3D_OK;
1799 static HRESULT WINAPI
1800 Thunk_IDirect3DDeviceImpl_2_GetDirect3D(IDirect3DDevice2 *iface,
1801 IDirect3D2 **Direct3D2)
1803 IDirect3DDeviceImpl *This = device_from_device2(iface);
1804 HRESULT ret;
1805 IDirect3D7 *ret_ptr;
1807 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Direct3D2);
1808 ret = IDirect3DDevice7_GetDirect3D((IDirect3DDevice7 *)This, &ret_ptr);
1809 if(ret != D3D_OK)
1810 return ret;
1811 *Direct3D2 = ret_ptr ? (IDirect3D2 *)&ddraw_from_d3d7(ret_ptr)->IDirect3D2_vtbl : NULL;
1812 TRACE(" returning interface %p\n", *Direct3D2);
1813 return D3D_OK;
1816 static HRESULT WINAPI
1817 Thunk_IDirect3DDeviceImpl_1_GetDirect3D(IDirect3DDevice *iface,
1818 IDirect3D **Direct3D)
1820 IDirect3DDeviceImpl *This = device_from_device1(iface);
1821 HRESULT ret;
1822 IDirect3D7 *ret_ptr;
1824 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Direct3D);
1825 ret = IDirect3DDevice7_GetDirect3D((IDirect3DDevice7 *)This, &ret_ptr);
1826 if(ret != D3D_OK)
1827 return ret;
1828 *Direct3D = ret_ptr ? (IDirect3D *)&ddraw_from_d3d7(ret_ptr)->IDirect3D_vtbl : NULL;
1829 TRACE(" returning interface %p\n", *Direct3D);
1830 return D3D_OK;
1833 /*****************************************************************************
1834 * IDirect3DDevice3::SetCurrentViewport
1836 * Sets a Direct3DViewport as the current viewport.
1837 * For the thunks note that all viewport interface versions are equal
1839 * Params:
1840 * Direct3DViewport3: The viewport to set
1842 * Version 2 and 3
1844 * Returns:
1845 * D3D_OK on success
1846 * (Is a NULL viewport valid?)
1848 *****************************************************************************/
1849 static HRESULT WINAPI
1850 IDirect3DDeviceImpl_3_SetCurrentViewport(IDirect3DDevice3 *iface,
1851 IDirect3DViewport3 *Direct3DViewport3)
1853 IDirect3DDeviceImpl *This = device_from_device3(iface);
1854 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Direct3DViewport3;
1855 TRACE("(%p)->(%p)\n", This, Direct3DViewport3);
1857 EnterCriticalSection(&ddraw_cs);
1858 /* Do nothing if the specified viewport is the same as the current one */
1859 if (This->current_viewport == vp )
1861 LeaveCriticalSection(&ddraw_cs);
1862 return D3D_OK;
1865 /* Should check if the viewport was added or not */
1867 /* Release previous viewport and AddRef the new one */
1868 if (This->current_viewport)
1870 TRACE("ViewportImpl is at %p, interface is at %p\n", This->current_viewport,
1871 (IDirect3DViewport3 *)This->current_viewport);
1872 IDirect3DViewport3_Release((IDirect3DViewport3 *)This->current_viewport);
1874 IDirect3DViewport3_AddRef(Direct3DViewport3);
1876 /* Set this viewport as the current viewport */
1877 This->current_viewport = vp;
1879 /* Activate this viewport */
1880 This->current_viewport->active_device = This;
1881 This->current_viewport->activate(This->current_viewport, FALSE);
1883 LeaveCriticalSection(&ddraw_cs);
1884 return D3D_OK;
1887 static HRESULT WINAPI
1888 Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport(IDirect3DDevice2 *iface,
1889 IDirect3DViewport2 *Direct3DViewport2)
1891 IDirect3DDeviceImpl *This = device_from_device2(iface);
1892 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Direct3DViewport2;
1893 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
1894 return IDirect3DDevice3_SetCurrentViewport((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl,
1895 (IDirect3DViewport3 *)vp);
1898 /*****************************************************************************
1899 * IDirect3DDevice3::GetCurrentViewport
1901 * Returns the currently active viewport.
1903 * Version 2 and 3
1905 * Params:
1906 * Direct3DViewport3: Address to return the interface pointer at
1908 * Returns:
1909 * D3D_OK on success
1910 * DDERR_INVALIDPARAMS if Direct3DViewport == NULL
1912 *****************************************************************************/
1913 static HRESULT WINAPI
1914 IDirect3DDeviceImpl_3_GetCurrentViewport(IDirect3DDevice3 *iface,
1915 IDirect3DViewport3 **Direct3DViewport3)
1917 IDirect3DDeviceImpl *This = device_from_device3(iface);
1918 TRACE("(%p)->(%p)\n", This, Direct3DViewport3);
1920 if(!Direct3DViewport3)
1921 return DDERR_INVALIDPARAMS;
1923 EnterCriticalSection(&ddraw_cs);
1924 *Direct3DViewport3 = (IDirect3DViewport3 *)This->current_viewport;
1926 /* AddRef the returned viewport */
1927 if(*Direct3DViewport3) IDirect3DViewport3_AddRef(*Direct3DViewport3);
1929 TRACE(" returning interface %p\n", *Direct3DViewport3);
1931 LeaveCriticalSection(&ddraw_cs);
1932 return D3D_OK;
1935 static HRESULT WINAPI
1936 Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport(IDirect3DDevice2 *iface,
1937 IDirect3DViewport2 **Direct3DViewport2)
1939 IDirect3DDeviceImpl *This = device_from_device2(iface);
1940 HRESULT hr;
1941 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, Direct3DViewport2);
1942 hr = IDirect3DDevice3_GetCurrentViewport((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl,
1943 (IDirect3DViewport3 **)Direct3DViewport2);
1944 if(hr != D3D_OK) return hr;
1945 return D3D_OK;
1948 /*****************************************************************************
1949 * IDirect3DDevice7::SetRenderTarget
1951 * Sets the render target for the Direct3DDevice.
1952 * For the thunks note that IDirectDrawSurface7 == IDirectDrawSurface4 and
1953 * IDirectDrawSurface3 == IDirectDrawSurface
1955 * Version 2, 3 and 7
1957 * Params:
1958 * NewTarget: Pointer to an IDirectDrawSurface7 interface to set as the new
1959 * render target
1960 * Flags: Some flags
1962 * Returns:
1963 * D3D_OK on success, for details see IWineD3DDevice::SetRenderTarget
1965 *****************************************************************************/
1966 static HRESULT
1967 IDirect3DDeviceImpl_7_SetRenderTarget(IDirect3DDevice7 *iface,
1968 IDirectDrawSurface7 *NewTarget,
1969 DWORD Flags)
1971 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
1972 IDirectDrawSurfaceImpl *Target = (IDirectDrawSurfaceImpl *)NewTarget;
1973 HRESULT hr;
1974 TRACE("(%p)->(%p,%08x): Relay\n", This, NewTarget, Flags);
1976 EnterCriticalSection(&ddraw_cs);
1977 /* Flags: Not used */
1979 if(This->target == Target)
1981 TRACE("No-op SetRenderTarget operation, not doing anything\n");
1982 LeaveCriticalSection(&ddraw_cs);
1983 return D3D_OK;
1986 hr = IWineD3DDevice_SetRenderTarget(This->wineD3DDevice,
1988 Target ? Target->WineD3DSurface : NULL,
1989 FALSE);
1990 if(hr != D3D_OK)
1992 LeaveCriticalSection(&ddraw_cs);
1993 return hr;
1995 IDirectDrawSurface7_AddRef(NewTarget);
1996 IDirectDrawSurface7_Release((IDirectDrawSurface7 *)This->target);
1997 This->target = Target;
1998 IDirect3DDeviceImpl_UpdateDepthStencil(This);
1999 LeaveCriticalSection(&ddraw_cs);
2000 return D3D_OK;
2003 static HRESULT WINAPI
2004 IDirect3DDeviceImpl_7_SetRenderTarget_FPUSetup(IDirect3DDevice7 *iface,
2005 IDirectDrawSurface7 *NewTarget,
2006 DWORD Flags)
2008 return IDirect3DDeviceImpl_7_SetRenderTarget(iface, NewTarget, Flags);
2011 static HRESULT WINAPI
2012 IDirect3DDeviceImpl_7_SetRenderTarget_FPUPreserve(IDirect3DDevice7 *iface,
2013 IDirectDrawSurface7 *NewTarget,
2014 DWORD Flags)
2016 HRESULT hr;
2017 WORD old_fpucw;
2019 old_fpucw = d3d_fpu_setup();
2020 hr = IDirect3DDeviceImpl_7_SetRenderTarget(iface, NewTarget, Flags);
2021 set_fpu_control_word(old_fpucw);
2023 return hr;
2026 static HRESULT WINAPI
2027 Thunk_IDirect3DDeviceImpl_3_SetRenderTarget(IDirect3DDevice3 *iface,
2028 IDirectDrawSurface4 *NewRenderTarget,
2029 DWORD Flags)
2031 IDirect3DDeviceImpl *This = device_from_device3(iface);
2032 IDirectDrawSurfaceImpl *Target = (IDirectDrawSurfaceImpl *)NewRenderTarget;
2033 TRACE_(ddraw_thunk)("(%p)->(%p,%08x) thunking to IDirect3DDevice7 interface.\n", This, Target, Flags);
2034 return IDirect3DDevice7_SetRenderTarget((IDirect3DDevice7 *)This, (IDirectDrawSurface7 *)Target, Flags);
2037 static HRESULT WINAPI
2038 Thunk_IDirect3DDeviceImpl_2_SetRenderTarget(IDirect3DDevice2 *iface,
2039 IDirectDrawSurface *NewRenderTarget,
2040 DWORD Flags)
2042 IDirect3DDeviceImpl *This = device_from_device2(iface);
2043 IDirectDrawSurfaceImpl *Target = (IDirectDrawSurfaceImpl *)NewRenderTarget;
2044 TRACE_(ddraw_thunk)("(%p)->(%p,%08x) thunking to IDirect3DDevice7 interface.\n", This, Target, Flags);
2045 return IDirect3DDevice7_SetRenderTarget((IDirect3DDevice7 *)This, (IDirectDrawSurface7 *)Target, Flags);
2048 /*****************************************************************************
2049 * IDirect3DDevice7::GetRenderTarget
2051 * Returns the current render target.
2052 * This is handled locally, because the WineD3D render target's parent
2053 * is an IParent
2055 * Version 2, 3 and 7
2057 * Params:
2058 * RenderTarget: Address to store the surface interface pointer
2060 * Returns:
2061 * D3D_OK on success
2062 * DDERR_INVALIDPARAMS if RenderTarget == NULL
2064 *****************************************************************************/
2065 static HRESULT WINAPI
2066 IDirect3DDeviceImpl_7_GetRenderTarget(IDirect3DDevice7 *iface,
2067 IDirectDrawSurface7 **RenderTarget)
2069 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
2070 TRACE("(%p)->(%p): Relay\n", This, RenderTarget);
2072 if(!RenderTarget)
2073 return DDERR_INVALIDPARAMS;
2075 EnterCriticalSection(&ddraw_cs);
2076 *RenderTarget = (IDirectDrawSurface7 *)This->target;
2077 IDirectDrawSurface7_AddRef(*RenderTarget);
2079 LeaveCriticalSection(&ddraw_cs);
2080 return D3D_OK;
2083 static HRESULT WINAPI
2084 Thunk_IDirect3DDeviceImpl_3_GetRenderTarget(IDirect3DDevice3 *iface,
2085 IDirectDrawSurface4 **RenderTarget)
2087 IDirect3DDeviceImpl *This = device_from_device3(iface);
2088 HRESULT hr;
2089 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, RenderTarget);
2090 hr = IDirect3DDevice7_GetRenderTarget((IDirect3DDevice7 *)This, (IDirectDrawSurface7 **)RenderTarget);
2091 if(hr != D3D_OK) return hr;
2092 return D3D_OK;
2095 static HRESULT WINAPI
2096 Thunk_IDirect3DDeviceImpl_2_GetRenderTarget(IDirect3DDevice2 *iface,
2097 IDirectDrawSurface **RenderTarget)
2099 IDirect3DDeviceImpl *This = device_from_device2(iface);
2100 HRESULT hr;
2101 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, RenderTarget);
2102 hr = IDirect3DDevice7_GetRenderTarget((IDirect3DDevice7 *)This, (IDirectDrawSurface7 **)RenderTarget);
2103 if(hr != D3D_OK) return hr;
2104 *RenderTarget = *RenderTarget ?
2105 (IDirectDrawSurface *)&((IDirectDrawSurfaceImpl *)*RenderTarget)->IDirectDrawSurface3_vtbl : NULL;
2106 return D3D_OK;
2109 /*****************************************************************************
2110 * IDirect3DDevice3::Begin
2112 * Begins a description block of vertices. This is similar to glBegin()
2113 * and glEnd(). After a call to IDirect3DDevice3::End, the vertices
2114 * described with IDirect3DDevice::Vertex are drawn.
2116 * Version 2 and 3
2118 * Params:
2119 * PrimitiveType: The type of primitives to draw
2120 * VertexTypeDesc: A flexible vertex format description of the vertices
2121 * Flags: Some flags..
2123 * Returns:
2124 * D3D_OK on success
2126 *****************************************************************************/
2127 static HRESULT WINAPI
2128 IDirect3DDeviceImpl_3_Begin(IDirect3DDevice3 *iface,
2129 D3DPRIMITIVETYPE PrimitiveType,
2130 DWORD VertexTypeDesc,
2131 DWORD Flags)
2133 IDirect3DDeviceImpl *This = device_from_device3(iface);
2134 TRACE("(%p)->(%d,%d,%08x)\n", This, PrimitiveType, VertexTypeDesc, Flags);
2136 EnterCriticalSection(&ddraw_cs);
2137 This->primitive_type = PrimitiveType;
2138 This->vertex_type = VertexTypeDesc;
2139 This->render_flags = Flags;
2140 This->vertex_size = get_flexible_vertex_size(This->vertex_type);
2141 This->nb_vertices = 0;
2142 LeaveCriticalSection(&ddraw_cs);
2144 return D3D_OK;
2147 static HRESULT WINAPI
2148 Thunk_IDirect3DDeviceImpl_2_Begin(IDirect3DDevice2 *iface,
2149 D3DPRIMITIVETYPE d3dpt,
2150 D3DVERTEXTYPE dwVertexTypeDesc,
2151 DWORD dwFlags)
2153 DWORD FVF;
2154 IDirect3DDeviceImpl *This = device_from_device2(iface);
2155 TRACE_(ddraw_thunk)("(%p/%p)->(%08x,%08x,%08x): Thunking to IDirect3DDevice3\n", This, iface, d3dpt, dwVertexTypeDesc, dwFlags);
2157 switch(dwVertexTypeDesc)
2159 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
2160 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
2161 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
2162 default:
2163 ERR("Unexpected vertex type %d\n", dwVertexTypeDesc);
2164 return DDERR_INVALIDPARAMS; /* Should never happen */
2167 return IDirect3DDevice3_Begin((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, d3dpt, FVF, dwFlags);
2170 /*****************************************************************************
2171 * IDirect3DDevice3::BeginIndexed
2173 * Draws primitives based on vertices in a vertex array which are specified
2174 * by indices.
2176 * Version 2 and 3
2178 * Params:
2179 * PrimitiveType: Primitive type to draw
2180 * VertexType: A FVF description of the vertex format
2181 * Vertices: pointer to an array containing the vertices
2182 * NumVertices: The number of vertices in the vertex array
2183 * Flags: Some flags ...
2185 * Returns:
2186 * D3D_OK, because it's a stub
2188 *****************************************************************************/
2189 static HRESULT WINAPI
2190 IDirect3DDeviceImpl_3_BeginIndexed(IDirect3DDevice3 *iface,
2191 D3DPRIMITIVETYPE PrimitiveType,
2192 DWORD VertexType,
2193 void *Vertices,
2194 DWORD NumVertices,
2195 DWORD Flags)
2197 IDirect3DDeviceImpl *This = device_from_device3(iface);
2198 FIXME("(%p)->(%08x,%08x,%p,%08x,%08x): stub!\n", This, PrimitiveType, VertexType, Vertices, NumVertices, Flags);
2199 return D3D_OK;
2203 static HRESULT WINAPI
2204 Thunk_IDirect3DDeviceImpl_2_BeginIndexed(IDirect3DDevice2 *iface,
2205 D3DPRIMITIVETYPE d3dptPrimitiveType,
2206 D3DVERTEXTYPE d3dvtVertexType,
2207 void *lpvVertices,
2208 DWORD dwNumVertices,
2209 DWORD dwFlags)
2211 DWORD FVF;
2212 IDirect3DDeviceImpl *This = device_from_device2(iface);
2213 TRACE_(ddraw_thunk)("(%p/%p)->(%08x,%08x,%p,%08x,%08x): Thunking to IDirect3DDevice3\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwNumVertices, dwFlags);
2215 switch(d3dvtVertexType)
2217 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
2218 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
2219 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
2220 default:
2221 ERR("Unexpected vertex type %d\n", d3dvtVertexType);
2222 return DDERR_INVALIDPARAMS; /* Should never happen */
2225 return IDirect3DDevice3_BeginIndexed((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl,
2226 d3dptPrimitiveType, FVF, lpvVertices, dwNumVertices, dwFlags);
2229 /*****************************************************************************
2230 * IDirect3DDevice3::Vertex
2232 * Draws a vertex as described by IDirect3DDevice3::Begin. It places all
2233 * drawn vertices in a vertex buffer. If the buffer is too small, its
2234 * size is increased.
2236 * Version 2 and 3
2238 * Params:
2239 * Vertex: Pointer to the vertex
2241 * Returns:
2242 * D3D_OK, on success
2243 * DDERR_INVALIDPARAMS if Vertex is NULL
2245 *****************************************************************************/
2246 static HRESULT WINAPI
2247 IDirect3DDeviceImpl_3_Vertex(IDirect3DDevice3 *iface,
2248 void *Vertex)
2250 IDirect3DDeviceImpl *This = device_from_device3(iface);
2251 TRACE("(%p)->(%p)\n", This, Vertex);
2253 if(!Vertex)
2254 return DDERR_INVALIDPARAMS;
2256 EnterCriticalSection(&ddraw_cs);
2257 if ((This->nb_vertices+1)*This->vertex_size > This->buffer_size)
2259 BYTE *old_buffer;
2260 This->buffer_size = This->buffer_size ? This->buffer_size * 2 : This->vertex_size * 3;
2261 old_buffer = This->vertex_buffer;
2262 This->vertex_buffer = HeapAlloc(GetProcessHeap(), 0, This->buffer_size);
2263 if (old_buffer)
2265 CopyMemory(This->vertex_buffer, old_buffer, This->nb_vertices * This->vertex_size);
2266 HeapFree(GetProcessHeap(), 0, old_buffer);
2270 CopyMemory(This->vertex_buffer + This->nb_vertices++ * This->vertex_size, Vertex, This->vertex_size);
2272 LeaveCriticalSection(&ddraw_cs);
2273 return D3D_OK;
2276 static HRESULT WINAPI
2277 Thunk_IDirect3DDeviceImpl_2_Vertex(IDirect3DDevice2 *iface,
2278 void *lpVertexType)
2280 IDirect3DDeviceImpl *This = device_from_device2(iface);
2281 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, lpVertexType);
2282 return IDirect3DDevice3_Vertex((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, lpVertexType);
2285 /*****************************************************************************
2286 * IDirect3DDevice3::Index
2288 * Specifies an index to a vertex to be drawn. The vertex array has to
2289 * be specified with BeginIndexed first.
2291 * Parameters:
2292 * VertexIndex: The index of the vertex to draw
2294 * Returns:
2295 * D3D_OK because it's a stub
2297 *****************************************************************************/
2298 static HRESULT WINAPI
2299 IDirect3DDeviceImpl_3_Index(IDirect3DDevice3 *iface,
2300 WORD VertexIndex)
2302 IDirect3DDeviceImpl *This = device_from_device3(iface);
2303 FIXME("(%p)->(%04x): stub!\n", This, VertexIndex);
2304 return D3D_OK;
2307 static HRESULT WINAPI
2308 Thunk_IDirect3DDeviceImpl_2_Index(IDirect3DDevice2 *iface,
2309 WORD wVertexIndex)
2311 IDirect3DDeviceImpl *This = device_from_device2(iface);
2312 TRACE_(ddraw_thunk)("(%p)->(%04x) thunking to IDirect3DDevice3 interface.\n", This, wVertexIndex);
2313 return IDirect3DDevice3_Index((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, wVertexIndex);
2316 /*****************************************************************************
2317 * IDirect3DDevice3::End
2319 * Ends a draw begun with IDirect3DDevice3::Begin or
2320 * IDirect3DDevice::BeginIndexed. The vertices specified with
2321 * IDirect3DDevice::Vertex or IDirect3DDevice::Index are drawn using
2322 * the IDirect3DDevice7::DrawPrimitive method. So far only
2323 * non-indexed mode is supported
2325 * Version 2 and 3
2327 * Params:
2328 * Flags: Some flags, as usual. Don't know which are defined
2330 * Returns:
2331 * The return value of IDirect3DDevice7::DrawPrimitive
2333 *****************************************************************************/
2334 static HRESULT WINAPI
2335 IDirect3DDeviceImpl_3_End(IDirect3DDevice3 *iface,
2336 DWORD Flags)
2338 IDirect3DDeviceImpl *This = device_from_device3(iface);
2339 TRACE("(%p)->(%08x)\n", This, Flags);
2341 return IDirect3DDevice7_DrawPrimitive((IDirect3DDevice7 *)This, This->primitive_type,
2342 This->vertex_type, This->vertex_buffer, This->nb_vertices, This->render_flags);
2345 static HRESULT WINAPI
2346 Thunk_IDirect3DDeviceImpl_2_End(IDirect3DDevice2 *iface,
2347 DWORD dwFlags)
2349 IDirect3DDeviceImpl *This = device_from_device2(iface);
2350 TRACE_(ddraw_thunk)("(%p)->(%08x) thunking to IDirect3DDevice3 interface.\n", This, dwFlags);
2351 return IDirect3DDevice3_End((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, dwFlags);
2354 /*****************************************************************************
2355 * IDirect3DDevice7::GetRenderState
2357 * Returns the value of a render state. The possible render states are
2358 * defined in include/d3dtypes.h
2360 * Version 2, 3 and 7
2362 * Params:
2363 * RenderStateType: Render state to return the current setting of
2364 * Value: Address to store the value at
2366 * Returns:
2367 * D3D_OK on success, for details see IWineD3DDevice::GetRenderState
2368 * DDERR_INVALIDPARAMS if Value == NULL
2370 *****************************************************************************/
2371 static HRESULT
2372 IDirect3DDeviceImpl_7_GetRenderState(IDirect3DDevice7 *iface,
2373 D3DRENDERSTATETYPE RenderStateType,
2374 DWORD *Value)
2376 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
2377 HRESULT hr;
2378 TRACE("(%p)->(%08x,%p): Relay\n", This, RenderStateType, Value);
2380 if(!Value)
2381 return DDERR_INVALIDPARAMS;
2383 EnterCriticalSection(&ddraw_cs);
2384 switch(RenderStateType)
2386 case D3DRENDERSTATE_TEXTUREMAG:
2388 WINED3DTEXTUREFILTERTYPE tex_mag;
2390 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2391 0, WINED3DSAMP_MAGFILTER,
2392 &tex_mag);
2394 switch (tex_mag)
2396 case WINED3DTEXF_POINT:
2397 *Value = D3DFILTER_NEAREST;
2398 break;
2399 case WINED3DTEXF_LINEAR:
2400 *Value = D3DFILTER_LINEAR;
2401 break;
2402 default:
2403 ERR("Unhandled texture mag %d !\n",tex_mag);
2404 *Value = 0;
2406 break;
2409 case D3DRENDERSTATE_TEXTUREMIN:
2411 WINED3DTEXTUREFILTERTYPE tex_min;
2413 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2414 0, WINED3DSAMP_MINFILTER,
2415 &tex_min);
2417 switch (tex_min)
2419 case WINED3DTEXF_POINT:
2420 *Value = D3DFILTER_NEAREST;
2421 break;
2422 case WINED3DTEXF_LINEAR:
2423 *Value = D3DFILTER_LINEAR;
2424 break;
2425 default:
2426 ERR("Unhandled texture mag %d !\n",tex_min);
2427 *Value = 0;
2429 break;
2432 case D3DRENDERSTATE_TEXTUREADDRESS:
2433 case D3DRENDERSTATE_TEXTUREADDRESSU:
2434 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2435 0, WINED3DSAMP_ADDRESSU,
2436 Value);
2437 break;
2438 case D3DRENDERSTATE_TEXTUREADDRESSV:
2439 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2440 0, WINED3DSAMP_ADDRESSV,
2441 Value);
2442 break;
2444 default:
2445 /* FIXME: Unhandled: D3DRENDERSTATE_STIPPLEPATTERN00 - 31 */
2446 hr = IWineD3DDevice_GetRenderState(This->wineD3DDevice,
2447 RenderStateType,
2448 Value);
2450 LeaveCriticalSection(&ddraw_cs);
2451 return hr;
2454 static HRESULT WINAPI
2455 IDirect3DDeviceImpl_7_GetRenderState_FPUSetup(IDirect3DDevice7 *iface,
2456 D3DRENDERSTATETYPE RenderStateType,
2457 DWORD *Value)
2459 return IDirect3DDeviceImpl_7_GetRenderState(iface, RenderStateType, Value);
2462 static HRESULT WINAPI
2463 IDirect3DDeviceImpl_7_GetRenderState_FPUPreserve(IDirect3DDevice7 *iface,
2464 D3DRENDERSTATETYPE RenderStateType,
2465 DWORD *Value)
2467 HRESULT hr;
2468 WORD old_fpucw;
2470 old_fpucw = d3d_fpu_setup();
2471 hr = IDirect3DDeviceImpl_7_GetRenderState(iface, RenderStateType, Value);
2472 set_fpu_control_word(old_fpucw);
2474 return hr;
2477 static HRESULT WINAPI
2478 IDirect3DDeviceImpl_3_GetRenderState(IDirect3DDevice3 *iface,
2479 D3DRENDERSTATETYPE dwRenderStateType,
2480 DWORD *lpdwRenderState)
2482 IDirect3DDeviceImpl *This = device_from_device3(iface);
2483 HRESULT hr;
2484 TRACE("(%p)->(%08x,%p)\n", This, dwRenderStateType, lpdwRenderState);
2486 switch(dwRenderStateType)
2488 case D3DRENDERSTATE_TEXTUREHANDLE:
2490 /* This state is wrapped to SetTexture in SetRenderState, so
2491 * it has to be wrapped to GetTexture here
2493 IWineD3DBaseTexture *tex = NULL;
2494 *lpdwRenderState = 0;
2496 EnterCriticalSection(&ddraw_cs);
2498 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice,
2500 &tex);
2502 if(hr == WINED3D_OK && tex)
2504 IDirectDrawSurface7 *parent = NULL;
2505 hr = IWineD3DBaseTexture_GetParent(tex,
2506 (IUnknown **) &parent);
2507 if(parent)
2509 /* The parent of the texture is the IDirectDrawSurface7 interface
2510 * of the ddraw surface
2512 IDirectDrawSurfaceImpl *texImpl = (IDirectDrawSurfaceImpl *)parent;
2513 *lpdwRenderState = texImpl->Handle;
2514 IDirectDrawSurface7_Release(parent);
2516 IWineD3DBaseTexture_Release(tex);
2519 LeaveCriticalSection(&ddraw_cs);
2521 return hr;
2524 case D3DRENDERSTATE_TEXTUREMAPBLEND:
2526 /* D3DRENDERSTATE_TEXTUREMAPBLEND is mapped to texture state stages in SetRenderState; reverse
2527 the mapping to get the value. */
2528 DWORD colorop, colorarg1, colorarg2;
2529 DWORD alphaop, alphaarg1, alphaarg2;
2531 EnterCriticalSection(&ddraw_cs);
2533 This->legacyTextureBlending = TRUE;
2535 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, &colorop);
2536 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, &colorarg1);
2537 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, &colorarg2);
2538 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, &alphaop);
2539 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, &alphaarg1);
2540 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, &alphaarg2);
2542 if (colorop == WINED3DTOP_SELECTARG1 && colorarg1 == WINED3DTA_TEXTURE &&
2543 alphaop == WINED3DTOP_SELECTARG1 && alphaarg1 == WINED3DTA_TEXTURE)
2545 *lpdwRenderState = D3DTBLEND_DECAL;
2547 else if (colorop == WINED3DTOP_SELECTARG1 && colorarg1 == WINED3DTA_TEXTURE &&
2548 alphaop == WINED3DTOP_MODULATE && alphaarg1 == WINED3DTA_TEXTURE && alphaarg2 == WINED3DTA_CURRENT)
2550 *lpdwRenderState = D3DTBLEND_DECALALPHA;
2552 else if (colorop == WINED3DTOP_MODULATE && colorarg1 == WINED3DTA_TEXTURE && colorarg2 == WINED3DTA_CURRENT &&
2553 alphaop == WINED3DTOP_MODULATE && alphaarg1 == WINED3DTA_TEXTURE && alphaarg2 == WINED3DTA_CURRENT)
2555 *lpdwRenderState = D3DTBLEND_MODULATEALPHA;
2557 else
2559 HRESULT hr;
2560 BOOL tex_alpha = FALSE;
2561 IWineD3DBaseTexture *tex = NULL;
2562 WINED3DSURFACE_DESC desc;
2563 DDPIXELFORMAT ddfmt;
2565 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice,
2567 &tex);
2569 if(hr == WINED3D_OK && tex)
2571 hr = IWineD3DTexture_GetLevelDesc((IWineD3DTexture*) tex, 0, &desc);
2572 if (SUCCEEDED(hr))
2574 ddfmt.dwSize = sizeof(ddfmt);
2575 PixelFormat_WineD3DtoDD(&ddfmt, desc.format);
2576 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
2579 IWineD3DBaseTexture_Release(tex);
2582 if (!(colorop == WINED3DTOP_MODULATE && colorarg1 == WINED3DTA_TEXTURE && colorarg2 == WINED3DTA_CURRENT &&
2583 alphaop == WINED3DTOP_SELECTARG1 && alphaarg1 == (tex_alpha ? WINED3DTA_TEXTURE : WINED3DTA_CURRENT)))
2585 ERR("Unexpected texture stage state setup, returning D3DTBLEND_MODULATE - likely erroneous\n");
2588 *lpdwRenderState = D3DTBLEND_MODULATE;
2591 LeaveCriticalSection(&ddraw_cs);
2593 return D3D_OK;
2596 default:
2597 return IDirect3DDevice7_GetRenderState((IDirect3DDevice7 *)This, dwRenderStateType, lpdwRenderState);
2601 static HRESULT WINAPI
2602 Thunk_IDirect3DDeviceImpl_2_GetRenderState(IDirect3DDevice2 *iface,
2603 D3DRENDERSTATETYPE dwRenderStateType,
2604 DWORD *lpdwRenderState)
2606 IDirect3DDeviceImpl *This = device_from_device2(iface);
2607 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice3 interface.\n", This, dwRenderStateType, lpdwRenderState);
2608 return IDirect3DDevice3_GetRenderState((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl,
2609 dwRenderStateType, lpdwRenderState);
2612 /*****************************************************************************
2613 * IDirect3DDevice7::SetRenderState
2615 * Sets a render state. The possible render states are defined in
2616 * include/d3dtypes.h
2618 * Version 2, 3 and 7
2620 * Params:
2621 * RenderStateType: State to set
2622 * Value: Value to assign to that state
2624 * Returns:
2625 * D3D_OK on success,
2626 * for details see IWineD3DDevice::SetRenderState
2628 *****************************************************************************/
2629 static HRESULT
2630 IDirect3DDeviceImpl_7_SetRenderState(IDirect3DDevice7 *iface,
2631 D3DRENDERSTATETYPE RenderStateType,
2632 DWORD Value)
2634 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
2635 HRESULT hr;
2636 TRACE("(%p)->(%08x,%d): Relay\n", This, RenderStateType, Value);
2638 EnterCriticalSection(&ddraw_cs);
2639 /* Some render states need special care */
2640 switch(RenderStateType)
2642 case D3DRENDERSTATE_TEXTUREMAG:
2644 WINED3DTEXTUREFILTERTYPE tex_mag = WINED3DTEXF_POINT;
2646 switch ((D3DTEXTUREFILTER) Value)
2648 case D3DFILTER_NEAREST:
2649 case D3DFILTER_LINEARMIPNEAREST:
2650 tex_mag = WINED3DTEXF_POINT;
2651 break;
2652 case D3DFILTER_LINEAR:
2653 case D3DFILTER_LINEARMIPLINEAR:
2654 tex_mag = WINED3DTEXF_LINEAR;
2655 break;
2656 default:
2657 ERR("Unhandled texture mag %d !\n",Value);
2660 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2661 0, WINED3DSAMP_MAGFILTER,
2662 tex_mag);
2663 break;
2666 case D3DRENDERSTATE_TEXTUREMIN:
2668 WINED3DTEXTUREFILTERTYPE tex_min = WINED3DTEXF_POINT;
2669 WINED3DTEXTUREFILTERTYPE tex_mip = WINED3DTEXF_NONE;
2671 switch ((D3DTEXTUREFILTER) Value)
2673 case D3DFILTER_NEAREST:
2674 tex_min = WINED3DTEXF_POINT;
2675 break;
2676 case D3DFILTER_LINEAR:
2677 tex_min = WINED3DTEXF_LINEAR;
2678 break;
2679 case D3DFILTER_MIPNEAREST:
2680 tex_min = WINED3DTEXF_POINT;
2681 tex_mip = WINED3DTEXF_POINT;
2682 break;
2683 case D3DFILTER_MIPLINEAR:
2684 tex_min = WINED3DTEXF_POINT;
2685 tex_mip = WINED3DTEXF_LINEAR;
2686 break;
2687 case D3DFILTER_LINEARMIPNEAREST:
2688 tex_min = WINED3DTEXF_POINT;
2689 tex_mip = WINED3DTEXF_LINEAR;
2690 break;
2691 case D3DFILTER_LINEARMIPLINEAR:
2692 tex_min = WINED3DTEXF_LINEAR;
2693 tex_mip = WINED3DTEXF_LINEAR;
2694 break;
2696 default:
2697 ERR("Unhandled texture min %d !\n",Value);
2700 IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2701 0, WINED3DSAMP_MIPFILTER,
2702 tex_mip);
2703 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2704 0, WINED3DSAMP_MINFILTER,
2705 tex_min);
2706 break;
2709 case D3DRENDERSTATE_TEXTUREADDRESS:
2710 IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2711 0, WINED3DSAMP_ADDRESSV,
2712 Value);
2713 /* Drop through */
2714 case D3DRENDERSTATE_TEXTUREADDRESSU:
2715 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2716 0, WINED3DSAMP_ADDRESSU,
2717 Value);
2718 break;
2719 case D3DRENDERSTATE_TEXTUREADDRESSV:
2720 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2721 0, WINED3DSAMP_ADDRESSV,
2722 Value);
2723 break;
2725 default:
2727 /* FIXME: Unhandled: D3DRENDERSTATE_STIPPLEPATTERN00 - 31 */
2729 hr = IWineD3DDevice_SetRenderState(This->wineD3DDevice,
2730 RenderStateType,
2731 Value);
2732 break;
2734 LeaveCriticalSection(&ddraw_cs);
2735 return hr;
2738 static HRESULT WINAPI
2739 IDirect3DDeviceImpl_7_SetRenderState_FPUSetup(IDirect3DDevice7 *iface,
2740 D3DRENDERSTATETYPE RenderStateType,
2741 DWORD Value)
2743 return IDirect3DDeviceImpl_7_SetRenderState(iface, RenderStateType, Value);
2746 static HRESULT WINAPI
2747 IDirect3DDeviceImpl_7_SetRenderState_FPUPreserve(IDirect3DDevice7 *iface,
2748 D3DRENDERSTATETYPE RenderStateType,
2749 DWORD Value)
2751 HRESULT hr;
2752 WORD old_fpucw;
2754 old_fpucw = d3d_fpu_setup();
2755 hr = IDirect3DDeviceImpl_7_SetRenderState(iface, RenderStateType, Value);
2756 set_fpu_control_word(old_fpucw);
2758 return hr;
2761 static HRESULT WINAPI
2762 IDirect3DDeviceImpl_3_SetRenderState(IDirect3DDevice3 *iface,
2763 D3DRENDERSTATETYPE RenderStateType,
2764 DWORD Value)
2766 /* Note about D3DRENDERSTATE_TEXTUREMAPBLEND implementation: most of values
2767 for this state can be directly mapped to texture stage colorop and alphaop, but
2768 D3DTBLEND_MODULATE is tricky: it uses alpha from texture when available and alpha
2769 from diffuse otherwise. So changing the texture must be monitored in SetTexture to modify
2770 alphaarg when needed.
2772 Aliens vs Predator 1 depends on accurate D3DTBLEND_MODULATE emulation
2774 Legacy texture blending (TEXTUREMAPBLEND) and texture stage states: directx6 docs state that
2775 TEXTUREMAPBLEND is deprecated, yet can still be used. Games must not use both or results
2776 are undefined. D3DTBLEND_MODULATE mode in particular is dependent on texture pixel format and
2777 requires fixup of stage 0 texture states when texture changes, but this fixup can interfere
2778 with games not using this deprecated state. So a flag 'legacyTextureBlending' has to be kept
2779 in device - TRUE if the app is using TEXTUREMAPBLEND.
2781 Tests show that setting TEXTUREMAPBLEND on native doesn't seem to change values returned by
2782 GetTextureStageState and vice versa. Not so on Wine, but it is 'undefined' anyway so, probably, ok,
2783 unless some broken game will be found that cares. */
2785 HRESULT hr;
2786 IDirect3DDeviceImpl *This = device_from_device3(iface);
2787 TRACE("(%p)->(%08x,%d)\n", This, RenderStateType, Value);
2789 EnterCriticalSection(&ddraw_cs);
2791 switch(RenderStateType)
2793 case D3DRENDERSTATE_TEXTUREHANDLE:
2795 if(Value == 0)
2797 hr = IWineD3DDevice_SetTexture(This->wineD3DDevice,
2799 NULL);
2800 break;
2803 if(Value > This->numHandles)
2805 FIXME("Specified handle %d out of range\n", Value);
2806 hr = DDERR_INVALIDPARAMS;
2807 break;
2809 if(This->Handles[Value - 1].type != DDrawHandle_Texture)
2811 FIXME("Handle %d isn't a texture handle\n", Value);
2812 hr = DDERR_INVALIDPARAMS;
2813 break;
2815 else
2817 IDirectDrawSurfaceImpl *surf = This->Handles[Value - 1].ptr;
2818 IDirect3DTexture2 *tex = surf ? (IDirect3DTexture2 *)&surf->IDirect3DTexture2_vtbl : NULL;
2819 hr = IDirect3DDevice3_SetTexture(iface, 0, tex);
2820 break;
2824 case D3DRENDERSTATE_TEXTUREMAPBLEND:
2826 This->legacyTextureBlending = TRUE;
2828 switch ( (D3DTEXTUREBLEND) Value)
2830 case D3DTBLEND_MODULATE:
2832 BOOL tex_alpha = FALSE;
2833 IWineD3DBaseTexture *tex = NULL;
2834 WINED3DSURFACE_DESC desc;
2835 DDPIXELFORMAT ddfmt;
2837 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice,
2839 &tex);
2841 if(hr == WINED3D_OK && tex)
2843 memset(&desc, 0, sizeof(desc));
2844 hr = IWineD3DTexture_GetLevelDesc((IWineD3DTexture*) tex, 0, &desc);
2845 if (SUCCEEDED(hr))
2847 ddfmt.dwSize = sizeof(ddfmt);
2848 PixelFormat_WineD3DtoDD(&ddfmt, desc.format);
2849 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
2852 IWineD3DBaseTexture_Release(tex);
2855 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG1);
2856 if (tex_alpha)
2858 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2860 else
2862 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_CURRENT);
2865 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2866 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2867 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_MODULATE);
2869 break;
2872 case D3DTBLEND_ADD:
2873 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_ADD);
2874 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2875 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2876 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG2);
2877 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
2878 break;
2880 case D3DTBLEND_MODULATEALPHA:
2881 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2882 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2883 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2884 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
2885 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_MODULATE);
2886 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_MODULATE);
2887 break;
2889 case D3DTBLEND_COPY:
2890 case D3DTBLEND_DECAL:
2891 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2892 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2893 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_SELECTARG1);
2894 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG1);
2895 break;
2897 case D3DTBLEND_DECALALPHA:
2898 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_BLENDTEXTUREALPHA);
2899 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2900 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2901 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG2);
2902 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
2903 break;
2905 default:
2906 ERR("Unhandled texture environment %d !\n",Value);
2909 hr = D3D_OK;
2910 break;
2913 default:
2914 hr = IDirect3DDevice7_SetRenderState((IDirect3DDevice7 *)This, RenderStateType, Value);
2915 break;
2918 LeaveCriticalSection(&ddraw_cs);
2920 return hr;
2923 static HRESULT WINAPI
2924 Thunk_IDirect3DDeviceImpl_2_SetRenderState(IDirect3DDevice2 *iface,
2925 D3DRENDERSTATETYPE RenderStateType,
2926 DWORD Value)
2928 IDirect3DDeviceImpl *This = device_from_device2(iface);
2929 TRACE_(ddraw_thunk)("(%p)->(%08x,%d) thunking to IDirect3DDevice3 interface.\n", This, RenderStateType, Value);
2930 return IDirect3DDevice3_SetRenderState((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, RenderStateType, Value);
2933 /*****************************************************************************
2934 * Direct3DDevice3::SetLightState
2936 * Sets a light state for Direct3DDevice3 and Direct3DDevice2. The
2937 * light states are forwarded to Direct3DDevice7 render states
2939 * Version 2 and 3
2941 * Params:
2942 * LightStateType: The light state to change
2943 * Value: The value to assign to that light state
2945 * Returns:
2946 * D3D_OK on success
2947 * DDERR_INVALIDPARAMS if the parameters were incorrect
2948 * Also check IDirect3DDevice7::SetRenderState
2950 *****************************************************************************/
2951 static HRESULT WINAPI
2952 IDirect3DDeviceImpl_3_SetLightState(IDirect3DDevice3 *iface,
2953 D3DLIGHTSTATETYPE LightStateType,
2954 DWORD Value)
2956 IDirect3DDeviceImpl *This = device_from_device3(iface);
2957 HRESULT hr;
2959 TRACE("(%p)->(%08x,%08x)\n", This, LightStateType, Value);
2961 if (!LightStateType || (LightStateType > D3DLIGHTSTATE_COLORVERTEX))
2963 TRACE("Unexpected Light State Type\n");
2964 return DDERR_INVALIDPARAMS;
2967 EnterCriticalSection(&ddraw_cs);
2968 if (LightStateType == D3DLIGHTSTATE_MATERIAL /* 1 */)
2970 IDirect3DMaterialImpl *mat;
2972 if(Value == 0) mat = NULL;
2973 else if(Value > This->numHandles)
2975 ERR("Material handle out of range(%d)\n", Value);
2976 LeaveCriticalSection(&ddraw_cs);
2977 return DDERR_INVALIDPARAMS;
2979 else if(This->Handles[Value - 1].type != DDrawHandle_Material)
2981 ERR("Invalid handle %d\n", Value);
2982 LeaveCriticalSection(&ddraw_cs);
2983 return DDERR_INVALIDPARAMS;
2985 else
2987 mat = This->Handles[Value - 1].ptr;
2990 if (mat != NULL)
2992 TRACE(" activating material %p.\n", mat);
2993 mat->activate(mat);
2995 else
2997 FIXME(" D3DLIGHTSTATE_MATERIAL called with NULL material !!!\n");
2999 This->material = Value;
3001 else if (LightStateType == D3DLIGHTSTATE_COLORMODEL /* 3 */)
3003 switch (Value)
3005 case D3DCOLOR_MONO:
3006 ERR("DDCOLOR_MONO should not happen!\n");
3007 break;
3008 case D3DCOLOR_RGB:
3009 /* We are already in this mode */
3010 TRACE("Setting color model to RGB (no-op).\n");
3011 break;
3012 default:
3013 ERR("Unknown color model!\n");
3014 LeaveCriticalSection(&ddraw_cs);
3015 return DDERR_INVALIDPARAMS;
3018 else
3020 D3DRENDERSTATETYPE rs;
3021 switch (LightStateType)
3023 case D3DLIGHTSTATE_AMBIENT: /* 2 */
3024 rs = D3DRENDERSTATE_AMBIENT;
3025 break;
3026 case D3DLIGHTSTATE_FOGMODE: /* 4 */
3027 rs = D3DRENDERSTATE_FOGVERTEXMODE;
3028 break;
3029 case D3DLIGHTSTATE_FOGSTART: /* 5 */
3030 rs = D3DRENDERSTATE_FOGSTART;
3031 break;
3032 case D3DLIGHTSTATE_FOGEND: /* 6 */
3033 rs = D3DRENDERSTATE_FOGEND;
3034 break;
3035 case D3DLIGHTSTATE_FOGDENSITY: /* 7 */
3036 rs = D3DRENDERSTATE_FOGDENSITY;
3037 break;
3038 case D3DLIGHTSTATE_COLORVERTEX: /* 8 */
3039 rs = D3DRENDERSTATE_COLORVERTEX;
3040 break;
3041 default:
3042 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType);
3043 LeaveCriticalSection(&ddraw_cs);
3044 return DDERR_INVALIDPARAMS;
3047 hr = IDirect3DDevice7_SetRenderState((IDirect3DDevice7 *)This, rs, Value);
3048 LeaveCriticalSection(&ddraw_cs);
3049 return hr;
3052 LeaveCriticalSection(&ddraw_cs);
3053 return D3D_OK;
3056 static HRESULT WINAPI
3057 Thunk_IDirect3DDeviceImpl_2_SetLightState(IDirect3DDevice2 *iface,
3058 D3DLIGHTSTATETYPE LightStateType,
3059 DWORD Value)
3061 IDirect3DDeviceImpl *This = device_from_device2(iface);
3062 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x) thunking to IDirect3DDevice3 interface.\n", This, LightStateType, Value);
3063 return IDirect3DDevice3_SetLightState((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, LightStateType, Value);
3066 /*****************************************************************************
3067 * IDirect3DDevice3::GetLightState
3069 * Returns the current setting of a light state. The state is read from
3070 * the Direct3DDevice7 render state.
3072 * Version 2 and 3
3074 * Params:
3075 * LightStateType: The light state to return
3076 * Value: The address to store the light state setting at
3078 * Returns:
3079 * D3D_OK on success
3080 * DDDERR_INVALIDPARAMS if the parameters were incorrect
3081 * Also see IDirect3DDevice7::GetRenderState
3083 *****************************************************************************/
3084 static HRESULT WINAPI
3085 IDirect3DDeviceImpl_3_GetLightState(IDirect3DDevice3 *iface,
3086 D3DLIGHTSTATETYPE LightStateType,
3087 DWORD *Value)
3089 IDirect3DDeviceImpl *This = device_from_device3(iface);
3090 HRESULT hr;
3092 TRACE("(%p)->(%08x,%p)\n", This, LightStateType, Value);
3094 if (!LightStateType || (LightStateType > D3DLIGHTSTATE_COLORVERTEX))
3096 TRACE("Unexpected Light State Type\n");
3097 return DDERR_INVALIDPARAMS;
3100 if(!Value)
3101 return DDERR_INVALIDPARAMS;
3103 EnterCriticalSection(&ddraw_cs);
3104 if (LightStateType == D3DLIGHTSTATE_MATERIAL /* 1 */)
3106 *Value = This->material;
3108 else if (LightStateType == D3DLIGHTSTATE_COLORMODEL /* 3 */)
3110 *Value = D3DCOLOR_RGB;
3112 else
3114 D3DRENDERSTATETYPE rs;
3115 switch (LightStateType)
3117 case D3DLIGHTSTATE_AMBIENT: /* 2 */
3118 rs = D3DRENDERSTATE_AMBIENT;
3119 break;
3120 case D3DLIGHTSTATE_FOGMODE: /* 4 */
3121 rs = D3DRENDERSTATE_FOGVERTEXMODE;
3122 break;
3123 case D3DLIGHTSTATE_FOGSTART: /* 5 */
3124 rs = D3DRENDERSTATE_FOGSTART;
3125 break;
3126 case D3DLIGHTSTATE_FOGEND: /* 6 */
3127 rs = D3DRENDERSTATE_FOGEND;
3128 break;
3129 case D3DLIGHTSTATE_FOGDENSITY: /* 7 */
3130 rs = D3DRENDERSTATE_FOGDENSITY;
3131 break;
3132 case D3DLIGHTSTATE_COLORVERTEX: /* 8 */
3133 rs = D3DRENDERSTATE_COLORVERTEX;
3134 break;
3135 default:
3136 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType);
3137 LeaveCriticalSection(&ddraw_cs);
3138 return DDERR_INVALIDPARAMS;
3141 hr = IDirect3DDevice7_GetRenderState((IDirect3DDevice7 *)This, rs, Value);
3142 LeaveCriticalSection(&ddraw_cs);
3143 return hr;
3146 LeaveCriticalSection(&ddraw_cs);
3147 return D3D_OK;
3150 static HRESULT WINAPI
3151 Thunk_IDirect3DDeviceImpl_2_GetLightState(IDirect3DDevice2 *iface,
3152 D3DLIGHTSTATETYPE LightStateType,
3153 DWORD *Value)
3155 IDirect3DDeviceImpl *This = device_from_device2(iface);
3156 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice3 interface.\n", This, LightStateType, Value);
3157 return IDirect3DDevice3_GetLightState((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, LightStateType, Value);
3160 /*****************************************************************************
3161 * IDirect3DDevice7::SetTransform
3163 * Assigns a D3DMATRIX to a transform type. The transform types are defined
3164 * in include/d3dtypes.h.
3165 * The D3DTRANSFORMSTATE_WORLD (=1) is translated to D3DTS_WORLDMATRIX(0)
3166 * (=255) for wined3d, because the 1 transform state was removed in d3d8
3167 * and WineD3D already understands the replacement D3DTS_WORLDMATRIX(0)
3169 * Version 2, 3 and 7
3171 * Params:
3172 * TransformStateType: transform state to set
3173 * Matrix: Matrix to assign to the state
3175 * Returns:
3176 * D3D_OK on success
3177 * DDERR_INVALIDPARAMS if Matrix == NULL
3178 * For details see IWineD3DDevice::SetTransform
3180 *****************************************************************************/
3181 static HRESULT
3182 IDirect3DDeviceImpl_7_SetTransform(IDirect3DDevice7 *iface,
3183 D3DTRANSFORMSTATETYPE TransformStateType,
3184 D3DMATRIX *Matrix)
3186 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3187 D3DTRANSFORMSTATETYPE type;
3188 HRESULT hr;
3189 TRACE("(%p)->(%08x,%p): Relay\n", This, TransformStateType, Matrix);
3191 switch(TransformStateType)
3193 case D3DTRANSFORMSTATE_WORLD : type = WINED3DTS_WORLDMATRIX(0); break;
3194 case D3DTRANSFORMSTATE_WORLD1: type = WINED3DTS_WORLDMATRIX(1); break;
3195 case D3DTRANSFORMSTATE_WORLD2: type = WINED3DTS_WORLDMATRIX(2); break;
3196 case D3DTRANSFORMSTATE_WORLD3: type = WINED3DTS_WORLDMATRIX(3); break;
3197 default: type = TransformStateType;
3200 if(!Matrix)
3201 return DDERR_INVALIDPARAMS;
3203 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3204 EnterCriticalSection(&ddraw_cs);
3205 hr = IWineD3DDevice_SetTransform(This->wineD3DDevice,
3206 type,
3207 (WINED3DMATRIX*) Matrix);
3208 LeaveCriticalSection(&ddraw_cs);
3209 return hr;
3212 static HRESULT WINAPI
3213 IDirect3DDeviceImpl_7_SetTransform_FPUSetup(IDirect3DDevice7 *iface,
3214 D3DTRANSFORMSTATETYPE TransformStateType,
3215 D3DMATRIX *Matrix)
3217 return IDirect3DDeviceImpl_7_SetTransform(iface, TransformStateType, Matrix);
3220 static HRESULT WINAPI
3221 IDirect3DDeviceImpl_7_SetTransform_FPUPreserve(IDirect3DDevice7 *iface,
3222 D3DTRANSFORMSTATETYPE TransformStateType,
3223 D3DMATRIX *Matrix)
3225 HRESULT hr;
3226 WORD old_fpucw;
3228 old_fpucw = d3d_fpu_setup();
3229 hr = IDirect3DDeviceImpl_7_SetTransform(iface, TransformStateType, Matrix);
3230 set_fpu_control_word(old_fpucw);
3232 return hr;
3235 static HRESULT WINAPI
3236 Thunk_IDirect3DDeviceImpl_3_SetTransform(IDirect3DDevice3 *iface,
3237 D3DTRANSFORMSTATETYPE TransformStateType,
3238 D3DMATRIX *D3DMatrix)
3240 IDirect3DDeviceImpl *This = device_from_device3(iface);
3241 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3242 return IDirect3DDevice7_SetTransform((IDirect3DDevice7 *)This, TransformStateType, D3DMatrix);
3245 static HRESULT WINAPI
3246 Thunk_IDirect3DDeviceImpl_2_SetTransform(IDirect3DDevice2 *iface,
3247 D3DTRANSFORMSTATETYPE TransformStateType,
3248 D3DMATRIX *D3DMatrix)
3250 IDirect3DDeviceImpl *This = device_from_device2(iface);
3251 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3252 return IDirect3DDevice7_SetTransform((IDirect3DDevice7 *)This, TransformStateType, D3DMatrix);
3255 /*****************************************************************************
3256 * IDirect3DDevice7::GetTransform
3258 * Returns the matrix assigned to a transform state
3259 * D3DTRANSFORMSTATE_WORLD is translated to D3DTS_WORLDMATRIX(0), see
3260 * SetTransform
3262 * Params:
3263 * TransformStateType: State to read the matrix from
3264 * Matrix: Address to store the matrix at
3266 * Returns:
3267 * D3D_OK on success
3268 * DDERR_INVALIDPARAMS if Matrix == NULL
3269 * For details, see IWineD3DDevice::GetTransform
3271 *****************************************************************************/
3272 static HRESULT
3273 IDirect3DDeviceImpl_7_GetTransform(IDirect3DDevice7 *iface,
3274 D3DTRANSFORMSTATETYPE TransformStateType,
3275 D3DMATRIX *Matrix)
3277 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3278 D3DTRANSFORMSTATETYPE type;
3279 HRESULT hr;
3280 TRACE("(%p)->(%08x,%p): Relay\n", This, TransformStateType, Matrix);
3282 switch(TransformStateType)
3284 case D3DTRANSFORMSTATE_WORLD : type = WINED3DTS_WORLDMATRIX(0); break;
3285 case D3DTRANSFORMSTATE_WORLD1: type = WINED3DTS_WORLDMATRIX(1); break;
3286 case D3DTRANSFORMSTATE_WORLD2: type = WINED3DTS_WORLDMATRIX(2); break;
3287 case D3DTRANSFORMSTATE_WORLD3: type = WINED3DTS_WORLDMATRIX(3); break;
3288 default: type = TransformStateType;
3291 if(!Matrix)
3292 return DDERR_INVALIDPARAMS;
3294 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3295 EnterCriticalSection(&ddraw_cs);
3296 hr = IWineD3DDevice_GetTransform(This->wineD3DDevice, type, (WINED3DMATRIX*) Matrix);
3297 LeaveCriticalSection(&ddraw_cs);
3298 return hr;
3301 static HRESULT WINAPI
3302 IDirect3DDeviceImpl_7_GetTransform_FPUSetup(IDirect3DDevice7 *iface,
3303 D3DTRANSFORMSTATETYPE TransformStateType,
3304 D3DMATRIX *Matrix)
3306 return IDirect3DDeviceImpl_7_GetTransform(iface, TransformStateType, Matrix);
3309 static HRESULT WINAPI
3310 IDirect3DDeviceImpl_7_GetTransform_FPUPreserve(IDirect3DDevice7 *iface,
3311 D3DTRANSFORMSTATETYPE TransformStateType,
3312 D3DMATRIX *Matrix)
3314 HRESULT hr;
3315 WORD old_fpucw;
3317 old_fpucw = d3d_fpu_setup();
3318 hr = IDirect3DDeviceImpl_7_GetTransform(iface, TransformStateType, Matrix);
3319 set_fpu_control_word(old_fpucw);
3321 return hr;
3324 static HRESULT WINAPI
3325 Thunk_IDirect3DDeviceImpl_3_GetTransform(IDirect3DDevice3 *iface,
3326 D3DTRANSFORMSTATETYPE TransformStateType,
3327 D3DMATRIX *D3DMatrix)
3329 IDirect3DDeviceImpl *This = device_from_device3(iface);
3330 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3331 return IDirect3DDevice7_GetTransform((IDirect3DDevice7 *)This, TransformStateType, D3DMatrix);
3334 static HRESULT WINAPI
3335 Thunk_IDirect3DDeviceImpl_2_GetTransform(IDirect3DDevice2 *iface,
3336 D3DTRANSFORMSTATETYPE TransformStateType,
3337 D3DMATRIX *D3DMatrix)
3339 IDirect3DDeviceImpl *This = device_from_device2(iface);
3340 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3341 return IDirect3DDevice7_GetTransform((IDirect3DDevice7 *)This, TransformStateType, D3DMatrix);
3344 /*****************************************************************************
3345 * IDirect3DDevice7::MultiplyTransform
3347 * Multiplies the already-set transform matrix of a transform state
3348 * with another matrix. For the world matrix, see SetTransform
3350 * Version 2, 3 and 7
3352 * Params:
3353 * TransformStateType: Transform state to multiply
3354 * D3DMatrix Matrix to multiply with.
3356 * Returns
3357 * D3D_OK on success
3358 * DDERR_INVALIDPARAMS if D3DMatrix is NULL
3359 * For details, see IWineD3DDevice::MultiplyTransform
3361 *****************************************************************************/
3362 static HRESULT
3363 IDirect3DDeviceImpl_7_MultiplyTransform(IDirect3DDevice7 *iface,
3364 D3DTRANSFORMSTATETYPE TransformStateType,
3365 D3DMATRIX *D3DMatrix)
3367 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3368 HRESULT hr;
3369 D3DTRANSFORMSTATETYPE type;
3370 TRACE("(%p)->(%08x,%p): Relay\n", This, TransformStateType, D3DMatrix);
3372 switch(TransformStateType)
3374 case D3DTRANSFORMSTATE_WORLD : type = WINED3DTS_WORLDMATRIX(0); break;
3375 case D3DTRANSFORMSTATE_WORLD1: type = WINED3DTS_WORLDMATRIX(1); break;
3376 case D3DTRANSFORMSTATE_WORLD2: type = WINED3DTS_WORLDMATRIX(2); break;
3377 case D3DTRANSFORMSTATE_WORLD3: type = WINED3DTS_WORLDMATRIX(3); break;
3378 default: type = TransformStateType;
3381 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3382 EnterCriticalSection(&ddraw_cs);
3383 hr = IWineD3DDevice_MultiplyTransform(This->wineD3DDevice,
3384 type,
3385 (WINED3DMATRIX*) D3DMatrix);
3386 LeaveCriticalSection(&ddraw_cs);
3387 return hr;
3390 static HRESULT WINAPI
3391 IDirect3DDeviceImpl_7_MultiplyTransform_FPUSetup(IDirect3DDevice7 *iface,
3392 D3DTRANSFORMSTATETYPE TransformStateType,
3393 D3DMATRIX *D3DMatrix)
3395 return IDirect3DDeviceImpl_7_MultiplyTransform(iface, TransformStateType, D3DMatrix);
3398 static HRESULT WINAPI
3399 IDirect3DDeviceImpl_7_MultiplyTransform_FPUPreserve(IDirect3DDevice7 *iface,
3400 D3DTRANSFORMSTATETYPE TransformStateType,
3401 D3DMATRIX *D3DMatrix)
3403 HRESULT hr;
3404 WORD old_fpucw;
3406 old_fpucw = d3d_fpu_setup();
3407 hr = IDirect3DDeviceImpl_7_MultiplyTransform(iface, TransformStateType, D3DMatrix);
3408 set_fpu_control_word(old_fpucw);
3410 return hr;
3413 static HRESULT WINAPI
3414 Thunk_IDirect3DDeviceImpl_3_MultiplyTransform(IDirect3DDevice3 *iface,
3415 D3DTRANSFORMSTATETYPE TransformStateType,
3416 D3DMATRIX *D3DMatrix)
3418 IDirect3DDeviceImpl *This = device_from_device3(iface);
3419 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3420 return IDirect3DDevice7_MultiplyTransform((IDirect3DDevice7 *)This, TransformStateType, D3DMatrix);
3423 static HRESULT WINAPI
3424 Thunk_IDirect3DDeviceImpl_2_MultiplyTransform(IDirect3DDevice2 *iface,
3425 D3DTRANSFORMSTATETYPE TransformStateType,
3426 D3DMATRIX *D3DMatrix)
3428 IDirect3DDeviceImpl *This = device_from_device2(iface);
3429 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3430 return IDirect3DDevice7_MultiplyTransform((IDirect3DDevice7 *)This, TransformStateType, D3DMatrix);
3433 /*****************************************************************************
3434 * IDirect3DDevice7::DrawPrimitive
3436 * Draws primitives based on vertices in an application-provided pointer
3438 * Version 2, 3 and 7. The IDirect3DDevice2 thunk converts the fixed vertex type into
3439 * an FVF format for D3D7
3441 * Params:
3442 * PrimitiveType: The type of the primitives to draw
3443 * Vertex type: Flexible vertex format vertex description
3444 * Vertices: Pointer to the vertex array
3445 * VertexCount: The number of vertices to draw
3446 * Flags: As usual a few flags
3448 * Returns:
3449 * D3D_OK on success
3450 * DDERR_INVALIDPARAMS if Vertices is NULL
3451 * For details, see IWineD3DDevice::DrawPrimitiveUP
3453 *****************************************************************************/
3454 static HRESULT
3455 IDirect3DDeviceImpl_7_DrawPrimitive(IDirect3DDevice7 *iface,
3456 D3DPRIMITIVETYPE PrimitiveType,
3457 DWORD VertexType,
3458 void *Vertices,
3459 DWORD VertexCount,
3460 DWORD Flags)
3462 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3463 UINT stride;
3464 HRESULT hr;
3465 TRACE("(%p)->(%08x,%08x,%p,%08x,%08x): Relay!\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3467 if(!Vertices)
3468 return DDERR_INVALIDPARAMS;
3470 /* Get the stride */
3471 stride = get_flexible_vertex_size(VertexType);
3473 /* Set the FVF */
3474 EnterCriticalSection(&ddraw_cs);
3475 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
3476 IDirectDrawImpl_FindDecl(This->ddraw, VertexType));
3477 if(hr != D3D_OK)
3479 LeaveCriticalSection(&ddraw_cs);
3480 return hr;
3483 /* This method translates to the user pointer draw of WineD3D */
3484 IWineD3DDevice_SetPrimitiveType(This->wineD3DDevice, PrimitiveType);
3485 hr = IWineD3DDevice_DrawPrimitiveUP(This->wineD3DDevice, VertexCount, Vertices, stride);
3486 LeaveCriticalSection(&ddraw_cs);
3487 return hr;
3490 static HRESULT WINAPI
3491 IDirect3DDeviceImpl_7_DrawPrimitive_FPUSetup(IDirect3DDevice7 *iface,
3492 D3DPRIMITIVETYPE PrimitiveType,
3493 DWORD VertexType,
3494 void *Vertices,
3495 DWORD VertexCount,
3496 DWORD Flags)
3498 return IDirect3DDeviceImpl_7_DrawPrimitive(iface, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3501 static HRESULT WINAPI
3502 IDirect3DDeviceImpl_7_DrawPrimitive_FPUPreserve(IDirect3DDevice7 *iface,
3503 D3DPRIMITIVETYPE PrimitiveType,
3504 DWORD VertexType,
3505 void *Vertices,
3506 DWORD VertexCount,
3507 DWORD Flags)
3509 HRESULT hr;
3510 WORD old_fpucw;
3512 old_fpucw = d3d_fpu_setup();
3513 hr = IDirect3DDeviceImpl_7_DrawPrimitive(iface, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3514 set_fpu_control_word(old_fpucw);
3516 return hr;
3519 static HRESULT WINAPI
3520 Thunk_IDirect3DDeviceImpl_3_DrawPrimitive(IDirect3DDevice3 *iface,
3521 D3DPRIMITIVETYPE PrimitiveType,
3522 DWORD VertexType,
3523 void *Vertices,
3524 DWORD VertexCount,
3525 DWORD Flags)
3527 IDirect3DDeviceImpl *This = device_from_device3(iface);
3528 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3529 return IDirect3DDevice7_DrawPrimitive((IDirect3DDevice7 *)This,
3530 PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3533 static HRESULT WINAPI
3534 Thunk_IDirect3DDeviceImpl_2_DrawPrimitive(IDirect3DDevice2 *iface,
3535 D3DPRIMITIVETYPE PrimitiveType,
3536 D3DVERTEXTYPE VertexType,
3537 void *Vertices,
3538 DWORD VertexCount,
3539 DWORD Flags)
3541 IDirect3DDeviceImpl *This = device_from_device2(iface);
3542 DWORD FVF;
3543 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3545 switch(VertexType)
3547 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
3548 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
3549 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
3550 default:
3551 ERR("Unexpected vertex type %d\n", VertexType);
3552 return DDERR_INVALIDPARAMS; /* Should never happen */
3555 return IDirect3DDevice7_DrawPrimitive((IDirect3DDevice7 *)This, PrimitiveType, FVF, Vertices, VertexCount, Flags);
3558 /*****************************************************************************
3559 * IDirect3DDevice7::DrawIndexedPrimitive
3561 * Draws vertices from an application-provided pointer, based on the index
3562 * numbers in a WORD array.
3564 * Version 2, 3 and 7. The version 7 thunk translates the vertex type into
3565 * an FVF format for D3D7
3567 * Params:
3568 * PrimitiveType: The primitive type to draw
3569 * VertexType: The FVF vertex description
3570 * Vertices: Pointer to the vertex array
3571 * VertexCount: ?
3572 * Indices: Pointer to the index array
3573 * IndexCount: Number of indices = Number of vertices to draw
3574 * Flags: As usual, some flags
3576 * Returns:
3577 * D3D_OK on success
3578 * DDERR_INVALIDPARAMS if Vertices or Indices is NULL
3579 * For details, see IWineD3DDevice::DrawIndexedPrimitiveUP
3581 *****************************************************************************/
3582 static HRESULT
3583 IDirect3DDeviceImpl_7_DrawIndexedPrimitive(IDirect3DDevice7 *iface,
3584 D3DPRIMITIVETYPE PrimitiveType,
3585 DWORD VertexType,
3586 void *Vertices,
3587 DWORD VertexCount,
3588 WORD *Indices,
3589 DWORD IndexCount,
3590 DWORD Flags)
3592 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3593 HRESULT hr;
3594 TRACE("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x): Relay!\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3596 /* Set the D3DDevice's FVF */
3597 EnterCriticalSection(&ddraw_cs);
3598 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
3599 IDirectDrawImpl_FindDecl(This->ddraw, VertexType));
3600 if(FAILED(hr))
3602 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr);
3603 LeaveCriticalSection(&ddraw_cs);
3604 return hr;
3607 IWineD3DDevice_SetPrimitiveType(This->wineD3DDevice, PrimitiveType);
3608 hr = IWineD3DDevice_DrawIndexedPrimitiveUP(This->wineD3DDevice, IndexCount, Indices,
3609 WINED3DFMT_R16_UINT, Vertices, get_flexible_vertex_size(VertexType));
3610 LeaveCriticalSection(&ddraw_cs);
3611 return hr;
3614 static HRESULT WINAPI
3615 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUSetup(IDirect3DDevice7 *iface,
3616 D3DPRIMITIVETYPE PrimitiveType,
3617 DWORD VertexType,
3618 void *Vertices,
3619 DWORD VertexCount,
3620 WORD *Indices,
3621 DWORD IndexCount,
3622 DWORD Flags)
3624 return IDirect3DDeviceImpl_7_DrawIndexedPrimitive(iface, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3627 static HRESULT WINAPI
3628 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUPreserve(IDirect3DDevice7 *iface,
3629 D3DPRIMITIVETYPE PrimitiveType,
3630 DWORD VertexType,
3631 void *Vertices,
3632 DWORD VertexCount,
3633 WORD *Indices,
3634 DWORD IndexCount,
3635 DWORD Flags)
3637 HRESULT hr;
3638 WORD old_fpucw;
3640 old_fpucw = d3d_fpu_setup();
3641 hr = IDirect3DDeviceImpl_7_DrawIndexedPrimitive(iface, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3642 set_fpu_control_word(old_fpucw);
3644 return hr;
3647 static HRESULT WINAPI
3648 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive(IDirect3DDevice3 *iface,
3649 D3DPRIMITIVETYPE PrimitiveType,
3650 DWORD VertexType,
3651 void *Vertices,
3652 DWORD VertexCount,
3653 WORD *Indices,
3654 DWORD IndexCount,
3655 DWORD Flags)
3657 IDirect3DDeviceImpl *This = device_from_device3(iface);
3658 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3659 return IDirect3DDevice7_DrawIndexedPrimitive((IDirect3DDevice7 *)This,
3660 PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3663 static HRESULT WINAPI
3664 Thunk_IDirect3DDeviceImpl_2_DrawIndexedPrimitive(IDirect3DDevice2 *iface,
3665 D3DPRIMITIVETYPE PrimitiveType,
3666 D3DVERTEXTYPE VertexType,
3667 void *Vertices,
3668 DWORD VertexCount,
3669 WORD *Indices,
3670 DWORD IndexCount,
3671 DWORD Flags)
3673 DWORD FVF;
3674 IDirect3DDeviceImpl *This = device_from_device2(iface);
3675 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3677 switch(VertexType)
3679 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
3680 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
3681 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
3682 default:
3683 ERR("Unexpected vertex type %d\n", VertexType);
3684 return DDERR_INVALIDPARAMS; /* Should never happen */
3687 return IDirect3DDevice7_DrawIndexedPrimitive((IDirect3DDevice7 *)This,
3688 PrimitiveType, FVF, Vertices, VertexCount, Indices, IndexCount, Flags);
3691 /*****************************************************************************
3692 * IDirect3DDevice7::SetClipStatus
3694 * Sets the clip status. This defines things as clipping conditions and
3695 * the extents of the clipping region.
3697 * Version 2, 3 and 7
3699 * Params:
3700 * ClipStatus:
3702 * Returns:
3703 * D3D_OK because it's a stub
3704 * (DDERR_INVALIDPARAMS if ClipStatus == NULL)
3706 *****************************************************************************/
3707 static HRESULT WINAPI
3708 IDirect3DDeviceImpl_7_SetClipStatus(IDirect3DDevice7 *iface,
3709 D3DCLIPSTATUS *ClipStatus)
3711 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3712 FIXME("(%p)->(%p): Stub!\n", This, ClipStatus);
3714 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them
3715 * Perhaps this needs a new data type and an additional IWineD3DDevice method
3717 /* return IWineD3DDevice_SetClipStatus(This->wineD3DDevice, ClipStatus);*/
3718 return D3D_OK;
3721 static HRESULT WINAPI
3722 Thunk_IDirect3DDeviceImpl_3_SetClipStatus(IDirect3DDevice3 *iface,
3723 D3DCLIPSTATUS *ClipStatus)
3725 IDirect3DDeviceImpl *This = device_from_device3(iface);
3726 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3727 return IDirect3DDevice7_SetClipStatus((IDirect3DDevice7 *)This, ClipStatus);
3730 static HRESULT WINAPI
3731 Thunk_IDirect3DDeviceImpl_2_SetClipStatus(IDirect3DDevice2 *iface,
3732 D3DCLIPSTATUS *ClipStatus)
3734 IDirect3DDeviceImpl *This = device_from_device2(iface);
3735 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3736 return IDirect3DDevice7_SetClipStatus((IDirect3DDevice7 *)This, ClipStatus);
3739 /*****************************************************************************
3740 * IDirect3DDevice7::GetClipStatus
3742 * Returns the clip status
3744 * Params:
3745 * ClipStatus: Address to write the clip status to
3747 * Returns:
3748 * D3D_OK because it's a stub
3750 *****************************************************************************/
3751 static HRESULT WINAPI
3752 IDirect3DDeviceImpl_7_GetClipStatus(IDirect3DDevice7 *iface,
3753 D3DCLIPSTATUS *ClipStatus)
3755 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3756 FIXME("(%p)->(%p): Stub!\n", This, ClipStatus);
3758 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them */
3759 /* return IWineD3DDevice_GetClipStatus(This->wineD3DDevice, ClipStatus);*/
3760 return D3D_OK;
3763 static HRESULT WINAPI
3764 Thunk_IDirect3DDeviceImpl_3_GetClipStatus(IDirect3DDevice3 *iface,
3765 D3DCLIPSTATUS *ClipStatus)
3767 IDirect3DDeviceImpl *This = device_from_device3(iface);
3768 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3769 return IDirect3DDevice7_GetClipStatus((IDirect3DDevice7 *)This, ClipStatus);
3772 static HRESULT WINAPI
3773 Thunk_IDirect3DDeviceImpl_2_GetClipStatus(IDirect3DDevice2 *iface,
3774 D3DCLIPSTATUS *ClipStatus)
3776 IDirect3DDeviceImpl *This = device_from_device2(iface);
3777 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3778 return IDirect3DDevice7_GetClipStatus((IDirect3DDevice7 *)This, ClipStatus);
3781 /*****************************************************************************
3782 * IDirect3DDevice::DrawPrimitiveStrided
3784 * Draws vertices described by a D3DDRAWPRIMITIVESTRIDEDDATA structure.
3786 * Version 3 and 7
3788 * Params:
3789 * PrimitiveType: The primitive type to draw
3790 * VertexType: The FVF description of the vertices to draw (for the stride??)
3791 * D3DDrawPrimStrideData: A D3DDRAWPRIMITIVESTRIDEDDATA structure describing
3792 * the vertex data locations
3793 * VertexCount: The number of vertices to draw
3794 * Flags: Some flags
3796 * Returns:
3797 * D3D_OK, because it's a stub
3798 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
3799 * (For details, see IWineD3DDevice::DrawPrimitiveStrided)
3801 *****************************************************************************/
3802 static HRESULT
3803 IDirect3DDeviceImpl_7_DrawPrimitiveStrided(IDirect3DDevice7 *iface,
3804 D3DPRIMITIVETYPE PrimitiveType,
3805 DWORD VertexType,
3806 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3807 DWORD VertexCount,
3808 DWORD Flags)
3810 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3811 WineDirect3DVertexStridedData WineD3DStrided;
3812 DWORD i;
3813 HRESULT hr;
3815 TRACE("(%p)->(%08x,%08x,%p,%08x,%08x): stub!\n", This, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
3817 memset(&WineD3DStrided, 0, sizeof(WineD3DStrided));
3818 /* Get the strided data right. the wined3d structure is a bit bigger
3819 * Watch out: The contents of the strided data are determined by the fvf,
3820 * not by the members set in D3DDrawPrimStrideData. So it's valid
3821 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
3822 * not set in the fvf.
3824 if(VertexType & D3DFVF_POSITION_MASK)
3826 WineD3DStrided.position.format = WINED3DFMT_R32G32B32_FLOAT;
3827 WineD3DStrided.position.lpData = D3DDrawPrimStrideData->position.lpvData;
3828 WineD3DStrided.position.dwStride = D3DDrawPrimStrideData->position.dwStride;
3829 if (VertexType & D3DFVF_XYZRHW)
3831 WineD3DStrided.position.format = WINED3DFMT_R32G32B32A32_FLOAT;
3832 WineD3DStrided.position_transformed = TRUE;
3833 } else
3834 WineD3DStrided.position_transformed = FALSE;
3837 if(VertexType & D3DFVF_NORMAL)
3839 WineD3DStrided.normal.format = WINED3DFMT_R32G32B32_FLOAT;
3840 WineD3DStrided.normal.lpData = D3DDrawPrimStrideData->normal.lpvData;
3841 WineD3DStrided.normal.dwStride = D3DDrawPrimStrideData->normal.dwStride;
3844 if(VertexType & D3DFVF_DIFFUSE)
3846 WineD3DStrided.diffuse.format = WINED3DFMT_B8G8R8A8_UNORM;
3847 WineD3DStrided.diffuse.lpData = D3DDrawPrimStrideData->diffuse.lpvData;
3848 WineD3DStrided.diffuse.dwStride = D3DDrawPrimStrideData->diffuse.dwStride;
3851 if(VertexType & D3DFVF_SPECULAR)
3853 WineD3DStrided.specular.format = WINED3DFMT_B8G8R8A8_UNORM;
3854 WineD3DStrided.specular.lpData = D3DDrawPrimStrideData->specular.lpvData;
3855 WineD3DStrided.specular.dwStride = D3DDrawPrimStrideData->specular.dwStride;
3858 for( i = 0; i < GET_TEXCOUNT_FROM_FVF(VertexType); i++)
3860 switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i))
3862 case 1: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32_FLOAT; break;
3863 case 2: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32G32_FLOAT; break;
3864 case 3: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32G32B32_FLOAT; break;
3865 case 4: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32G32B32A32_FLOAT; break;
3866 default: ERR("Unexpected texture coordinate size %d\n",
3867 GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i));
3869 WineD3DStrided.texCoords[i].lpData = D3DDrawPrimStrideData->textureCoords[i].lpvData;
3870 WineD3DStrided.texCoords[i].dwStride = D3DDrawPrimStrideData->textureCoords[i].dwStride;
3873 /* WineD3D doesn't need the FVF here */
3874 EnterCriticalSection(&ddraw_cs);
3875 IWineD3DDevice_SetPrimitiveType(This->wineD3DDevice, PrimitiveType);
3876 hr = IWineD3DDevice_DrawPrimitiveStrided(This->wineD3DDevice, VertexCount, &WineD3DStrided);
3877 LeaveCriticalSection(&ddraw_cs);
3878 return hr;
3881 static HRESULT WINAPI
3882 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUSetup(IDirect3DDevice7 *iface,
3883 D3DPRIMITIVETYPE PrimitiveType,
3884 DWORD VertexType,
3885 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3886 DWORD VertexCount,
3887 DWORD Flags)
3889 return IDirect3DDeviceImpl_7_DrawPrimitiveStrided(iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
3892 static HRESULT WINAPI
3893 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUPreserve(IDirect3DDevice7 *iface,
3894 D3DPRIMITIVETYPE PrimitiveType,
3895 DWORD VertexType,
3896 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3897 DWORD VertexCount,
3898 DWORD Flags)
3900 HRESULT hr;
3901 WORD old_fpucw;
3903 old_fpucw = d3d_fpu_setup();
3904 hr = IDirect3DDeviceImpl_7_DrawPrimitiveStrided(iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
3905 set_fpu_control_word(old_fpucw);
3907 return hr;
3910 static HRESULT WINAPI
3911 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided(IDirect3DDevice3 *iface,
3912 D3DPRIMITIVETYPE PrimitiveType,
3913 DWORD VertexType,
3914 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3915 DWORD VertexCount,
3916 DWORD Flags)
3918 IDirect3DDeviceImpl *This = device_from_device3(iface);
3919 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
3920 return IDirect3DDevice7_DrawPrimitiveStrided((IDirect3DDevice7 *)This,
3921 PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
3924 /*****************************************************************************
3925 * IDirect3DDevice7::DrawIndexedPrimitiveStrided
3927 * Draws primitives specified by strided data locations based on indices
3929 * Version 3 and 7
3931 * Params:
3932 * PrimitiveType:
3934 * Returns:
3935 * D3D_OK, because it's a stub
3936 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
3937 * (DDERR_INVALIDPARAMS if Indices is NULL)
3938 * (For more details, see IWineD3DDevice::DrawIndexedPrimitiveStrided)
3940 *****************************************************************************/
3941 static HRESULT
3942 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(IDirect3DDevice7 *iface,
3943 D3DPRIMITIVETYPE PrimitiveType,
3944 DWORD VertexType,
3945 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3946 DWORD VertexCount,
3947 WORD *Indices,
3948 DWORD IndexCount,
3949 DWORD Flags)
3951 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3952 WineDirect3DVertexStridedData WineD3DStrided;
3953 DWORD i;
3954 HRESULT hr;
3956 TRACE("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x)\n", This, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
3958 memset(&WineD3DStrided, 0, sizeof(WineD3DStrided));
3959 /* Get the strided data right. the wined3d structure is a bit bigger
3960 * Watch out: The contents of the strided data are determined by the fvf,
3961 * not by the members set in D3DDrawPrimStrideData. So it's valid
3962 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
3963 * not set in the fvf.
3965 if(VertexType & D3DFVF_POSITION_MASK)
3967 WineD3DStrided.position.format = WINED3DFMT_R32G32B32_FLOAT;
3968 WineD3DStrided.position.lpData = D3DDrawPrimStrideData->position.lpvData;
3969 WineD3DStrided.position.dwStride = D3DDrawPrimStrideData->position.dwStride;
3970 if (VertexType & D3DFVF_XYZRHW)
3972 WineD3DStrided.position.format = WINED3DFMT_R32G32B32A32_FLOAT;
3973 WineD3DStrided.position_transformed = TRUE;
3974 } else
3975 WineD3DStrided.position_transformed = FALSE;
3978 if(VertexType & D3DFVF_NORMAL)
3980 WineD3DStrided.normal.format = WINED3DFMT_R32G32B32_FLOAT;
3981 WineD3DStrided.normal.lpData = D3DDrawPrimStrideData->normal.lpvData;
3982 WineD3DStrided.normal.dwStride = D3DDrawPrimStrideData->normal.dwStride;
3985 if(VertexType & D3DFVF_DIFFUSE)
3987 WineD3DStrided.diffuse.format = WINED3DFMT_B8G8R8A8_UNORM;
3988 WineD3DStrided.diffuse.lpData = D3DDrawPrimStrideData->diffuse.lpvData;
3989 WineD3DStrided.diffuse.dwStride = D3DDrawPrimStrideData->diffuse.dwStride;
3992 if(VertexType & D3DFVF_SPECULAR)
3994 WineD3DStrided.specular.format = WINED3DFMT_B8G8R8A8_UNORM;
3995 WineD3DStrided.specular.lpData = D3DDrawPrimStrideData->specular.lpvData;
3996 WineD3DStrided.specular.dwStride = D3DDrawPrimStrideData->specular.dwStride;
3999 for( i = 0; i < GET_TEXCOUNT_FROM_FVF(VertexType); i++)
4001 switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i))
4003 case 1: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32_FLOAT; break;
4004 case 2: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32G32_FLOAT; break;
4005 case 3: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32G32B32_FLOAT; break;
4006 case 4: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32G32B32A32_FLOAT; break;
4007 default: ERR("Unexpected texture coordinate size %d\n",
4008 GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i));
4010 WineD3DStrided.texCoords[i].lpData = D3DDrawPrimStrideData->textureCoords[i].lpvData;
4011 WineD3DStrided.texCoords[i].dwStride = D3DDrawPrimStrideData->textureCoords[i].dwStride;
4014 /* WineD3D doesn't need the FVF here */
4015 EnterCriticalSection(&ddraw_cs);
4016 IWineD3DDevice_SetPrimitiveType(This->wineD3DDevice, PrimitiveType);
4017 hr = IWineD3DDevice_DrawIndexedPrimitiveStrided(This->wineD3DDevice,
4018 IndexCount, &WineD3DStrided, VertexCount, Indices, WINED3DFMT_R16_UINT);
4019 LeaveCriticalSection(&ddraw_cs);
4020 return hr;
4023 static HRESULT WINAPI
4024 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUSetup(IDirect3DDevice7 *iface,
4025 D3DPRIMITIVETYPE PrimitiveType,
4026 DWORD VertexType,
4027 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
4028 DWORD VertexCount,
4029 WORD *Indices,
4030 DWORD IndexCount,
4031 DWORD Flags)
4033 return IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
4036 static HRESULT WINAPI
4037 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUPreserve(IDirect3DDevice7 *iface,
4038 D3DPRIMITIVETYPE PrimitiveType,
4039 DWORD VertexType,
4040 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
4041 DWORD VertexCount,
4042 WORD *Indices,
4043 DWORD IndexCount,
4044 DWORD Flags)
4046 HRESULT hr;
4047 WORD old_fpucw;
4049 old_fpucw = d3d_fpu_setup();
4050 hr = IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
4051 set_fpu_control_word(old_fpucw);
4053 return hr;
4056 static HRESULT WINAPI
4057 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided(IDirect3DDevice3 *iface,
4058 D3DPRIMITIVETYPE PrimitiveType,
4059 DWORD VertexType,
4060 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
4061 DWORD VertexCount,
4062 WORD *Indices,
4063 DWORD IndexCount,
4064 DWORD Flags)
4066 IDirect3DDeviceImpl *This = device_from_device3(iface);
4067 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
4068 return IDirect3DDevice7_DrawIndexedPrimitiveStrided((IDirect3DDevice7 *)This, PrimitiveType,
4069 VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
4072 /*****************************************************************************
4073 * IDirect3DDevice7::DrawPrimitiveVB
4075 * Draws primitives from a vertex buffer to the screen.
4077 * Version 3 and 7
4079 * Params:
4080 * PrimitiveType: Type of primitive to be rendered.
4081 * D3DVertexBuf: Source Vertex Buffer
4082 * StartVertex: Index of the first vertex from the buffer to be rendered
4083 * NumVertices: Number of vertices to be rendered
4084 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4086 * Return values
4087 * D3D_OK on success
4088 * DDERR_INVALIDPARAMS if D3DVertexBuf is NULL
4090 *****************************************************************************/
4091 static HRESULT
4092 IDirect3DDeviceImpl_7_DrawPrimitiveVB(IDirect3DDevice7 *iface,
4093 D3DPRIMITIVETYPE PrimitiveType,
4094 IDirect3DVertexBuffer7 *D3DVertexBuf,
4095 DWORD StartVertex,
4096 DWORD NumVertices,
4097 DWORD Flags)
4099 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
4100 IDirect3DVertexBufferImpl *vb = (IDirect3DVertexBufferImpl *)D3DVertexBuf;
4101 HRESULT hr;
4102 DWORD stride;
4104 TRACE("(%p)->(%08x,%p,%08x,%08x,%08x)\n", This, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags);
4106 /* Sanity checks */
4107 if(!vb)
4109 ERR("(%p) No Vertex buffer specified\n", This);
4110 return DDERR_INVALIDPARAMS;
4112 stride = get_flexible_vertex_size(vb->fvf);
4114 EnterCriticalSection(&ddraw_cs);
4115 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
4116 vb->wineD3DVertexDeclaration);
4117 if(FAILED(hr))
4119 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr);
4120 LeaveCriticalSection(&ddraw_cs);
4121 return hr;
4124 /* Set the vertex stream source */
4125 hr = IWineD3DDevice_SetStreamSource(This->wineD3DDevice,
4126 0 /* StreamNumber */,
4127 vb->wineD3DVertexBuffer,
4128 0 /* StartVertex - we pass this to DrawPrimitive */,
4129 stride);
4130 if(hr != D3D_OK)
4132 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This, hr);
4133 LeaveCriticalSection(&ddraw_cs);
4134 return hr;
4137 /* Now draw the primitives */
4138 IWineD3DDevice_SetPrimitiveType(This->wineD3DDevice, PrimitiveType);
4139 hr = IWineD3DDevice_DrawPrimitive(This->wineD3DDevice, StartVertex, NumVertices);
4140 LeaveCriticalSection(&ddraw_cs);
4141 return hr;
4144 static HRESULT WINAPI
4145 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUSetup(IDirect3DDevice7 *iface,
4146 D3DPRIMITIVETYPE PrimitiveType,
4147 IDirect3DVertexBuffer7 *D3DVertexBuf,
4148 DWORD StartVertex,
4149 DWORD NumVertices,
4150 DWORD Flags)
4152 return IDirect3DDeviceImpl_7_DrawPrimitiveVB(iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags);
4155 static HRESULT WINAPI
4156 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUPreserve(IDirect3DDevice7 *iface,
4157 D3DPRIMITIVETYPE PrimitiveType,
4158 IDirect3DVertexBuffer7 *D3DVertexBuf,
4159 DWORD StartVertex,
4160 DWORD NumVertices,
4161 DWORD Flags)
4163 HRESULT hr;
4164 WORD old_fpucw;
4166 old_fpucw = d3d_fpu_setup();
4167 hr = IDirect3DDeviceImpl_7_DrawPrimitiveVB(iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags);
4168 set_fpu_control_word(old_fpucw);
4170 return hr;
4173 static HRESULT WINAPI
4174 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB(IDirect3DDevice3 *iface,
4175 D3DPRIMITIVETYPE PrimitiveType,
4176 IDirect3DVertexBuffer *D3DVertexBuf,
4177 DWORD StartVertex,
4178 DWORD NumVertices,
4179 DWORD Flags)
4181 IDirect3DDeviceImpl *This = device_from_device3(iface);
4182 IDirect3DVertexBufferImpl *vb = D3DVertexBuf ? vb_from_vb1(D3DVertexBuf) : NULL;
4183 TRACE_(ddraw_thunk)("(%p)->(%08x,%p,%08x,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, vb, StartVertex, NumVertices, Flags);
4184 return IDirect3DDevice7_DrawPrimitiveVB((IDirect3DDevice7 *)This, PrimitiveType,
4185 (IDirect3DVertexBuffer7 *)vb, StartVertex, NumVertices, Flags);
4189 /*****************************************************************************
4190 * IDirect3DDevice7::DrawIndexedPrimitiveVB
4192 * Draws primitives from a vertex buffer to the screen
4194 * Params:
4195 * PrimitiveType: Type of primitive to be rendered.
4196 * D3DVertexBuf: Source Vertex Buffer
4197 * StartVertex: Index of the first vertex from the buffer to be rendered
4198 * NumVertices: Number of vertices to be rendered
4199 * Indices: Array of DWORDs used to index into the Vertices
4200 * IndexCount: Number of indices in Indices
4201 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4203 * Return values
4205 *****************************************************************************/
4206 static HRESULT
4207 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(IDirect3DDevice7 *iface,
4208 D3DPRIMITIVETYPE PrimitiveType,
4209 IDirect3DVertexBuffer7 *D3DVertexBuf,
4210 DWORD StartVertex,
4211 DWORD NumVertices,
4212 WORD *Indices,
4213 DWORD IndexCount,
4214 DWORD Flags)
4216 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
4217 IDirect3DVertexBufferImpl *vb = (IDirect3DVertexBufferImpl *)D3DVertexBuf;
4218 DWORD stride = get_flexible_vertex_size(vb->fvf);
4219 WORD *LockedIndices;
4220 HRESULT hr;
4222 TRACE("(%p)->(%08x,%p,%d,%d,%p,%d,%08x)\n", This, PrimitiveType, vb, StartVertex, NumVertices, Indices, IndexCount, Flags);
4224 /* Steps:
4225 * 1) Upload the Indices to the index buffer
4226 * 2) Set the index source
4227 * 3) Set the Vertex Buffer as the Stream source
4228 * 4) Call IWineD3DDevice::DrawIndexedPrimitive
4231 EnterCriticalSection(&ddraw_cs);
4233 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
4234 vb->wineD3DVertexDeclaration);
4235 if(FAILED(hr))
4237 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr);
4238 LeaveCriticalSection(&ddraw_cs);
4239 return hr;
4242 /* copy the index stream into the index buffer.
4243 * A new IWineD3DDevice method could be created
4244 * which takes an user pointer containing the indices
4245 * or a SetData-Method for the index buffer, which
4246 * overrides the index buffer data with our pointer.
4248 hr = IWineD3DBuffer_Map(This->indexbuffer,
4249 0 /* OffSetToLock */,
4250 IndexCount * sizeof(WORD),
4251 (BYTE **) &LockedIndices,
4252 0 /* Flags */);
4253 assert(IndexCount < 0x100000);
4254 if(hr != D3D_OK)
4256 ERR("(%p) IWineD3DBuffer::Map failed with hr = %08x\n", This, hr);
4257 LeaveCriticalSection(&ddraw_cs);
4258 return hr;
4260 memcpy(LockedIndices, Indices, IndexCount * sizeof(WORD));
4261 hr = IWineD3DBuffer_Unmap(This->indexbuffer);
4262 if(hr != D3D_OK)
4264 ERR("(%p) IWineD3DBuffer::Unmap failed with hr = %08x\n", This, hr);
4265 LeaveCriticalSection(&ddraw_cs);
4266 return hr;
4269 /* Set the index stream */
4270 IWineD3DDevice_SetBaseVertexIndex(This->wineD3DDevice, StartVertex);
4271 hr = IWineD3DDevice_SetIndexBuffer(This->wineD3DDevice, This->indexbuffer,
4272 WINED3DFMT_R16_UINT);
4274 /* Set the vertex stream source */
4275 hr = IWineD3DDevice_SetStreamSource(This->wineD3DDevice,
4276 0 /* StreamNumber */,
4277 vb->wineD3DVertexBuffer,
4278 0 /* offset, we pass this to DrawIndexedPrimitive */,
4279 stride);
4280 if(hr != D3D_OK)
4282 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This, hr);
4283 LeaveCriticalSection(&ddraw_cs);
4284 return hr;
4288 IWineD3DDevice_SetPrimitiveType(This->wineD3DDevice, PrimitiveType);
4289 hr = IWineD3DDevice_DrawIndexedPrimitive(This->wineD3DDevice, 0 /* StartIndex */, IndexCount);
4291 LeaveCriticalSection(&ddraw_cs);
4292 return hr;
4295 static HRESULT WINAPI
4296 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUSetup(IDirect3DDevice7 *iface,
4297 D3DPRIMITIVETYPE PrimitiveType,
4298 IDirect3DVertexBuffer7 *D3DVertexBuf,
4299 DWORD StartVertex,
4300 DWORD NumVertices,
4301 WORD *Indices,
4302 DWORD IndexCount,
4303 DWORD Flags)
4305 return IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Indices, IndexCount, Flags);
4308 static HRESULT WINAPI
4309 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUPreserve(IDirect3DDevice7 *iface,
4310 D3DPRIMITIVETYPE PrimitiveType,
4311 IDirect3DVertexBuffer7 *D3DVertexBuf,
4312 DWORD StartVertex,
4313 DWORD NumVertices,
4314 WORD *Indices,
4315 DWORD IndexCount,
4316 DWORD Flags)
4318 HRESULT hr;
4319 WORD old_fpucw;
4321 old_fpucw = d3d_fpu_setup();
4322 hr = IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Indices, IndexCount, Flags);
4323 set_fpu_control_word(old_fpucw);
4325 return hr;
4328 static HRESULT WINAPI
4329 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB(IDirect3DDevice3 *iface,
4330 D3DPRIMITIVETYPE PrimitiveType,
4331 IDirect3DVertexBuffer *D3DVertexBuf,
4332 WORD *Indices,
4333 DWORD IndexCount,
4334 DWORD Flags)
4336 IDirect3DDeviceImpl *This = device_from_device3(iface);
4337 IDirect3DVertexBufferImpl *VB = vb_from_vb1(D3DVertexBuf);
4338 TRACE_(ddraw_thunk)("(%p)->(%08x,%p,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VB, Indices, IndexCount, Flags);
4340 return IDirect3DDevice7_DrawIndexedPrimitiveVB((IDirect3DDevice7 *)This, PrimitiveType,
4341 (IDirect3DVertexBuffer7 *)VB, 0, IndexCount, Indices, IndexCount, Flags);
4344 /*****************************************************************************
4345 * IDirect3DDevice7::ComputeSphereVisibility
4347 * Calculates the visibility of spheres in the current viewport. The spheres
4348 * are passed in the Centers and Radii arrays, the results are passed back
4349 * in the ReturnValues array. Return values are either completely visible,
4350 * partially visible or completely invisible.
4351 * The return value consist of a combination of D3DCLIP_* flags, or it's
4352 * 0 if the sphere is completely visible(according to the SDK, not checked)
4354 * Version 3 and 7
4356 * Params:
4357 * Centers: Array containing the sphere centers
4358 * Radii: Array containing the sphere radii
4359 * NumSpheres: The number of centers and radii in the arrays
4360 * Flags: Some flags
4361 * ReturnValues: Array to write the results to
4363 * Returns:
4364 * D3D_OK
4365 * (DDERR_INVALIDPARAMS if Centers, Radii or ReturnValues are NULL)
4366 * (D3DERR_INVALIDMATRIX if the combined world, view and proj matrix
4367 * is singular)
4369 *****************************************************************************/
4371 static DWORD in_plane(UINT plane, D3DVECTOR normal, D3DVALUE origin_plane, D3DVECTOR center, D3DVALUE radius)
4373 float distance, norm;
4375 norm = sqrt( normal.u1.x * normal.u1.x + normal.u2.y * normal.u2.y + normal.u3.z * normal.u3.z );
4376 distance = ( origin_plane + normal.u1.x * center.u1.x + normal.u2.y * center.u2.y + normal.u3.z * center.u3.z ) / norm;
4378 if ( fabs( distance ) < radius ) return D3DSTATUS_CLIPUNIONLEFT << plane;
4379 if ( distance < -radius ) return (D3DSTATUS_CLIPUNIONLEFT | D3DSTATUS_CLIPINTERSECTIONLEFT) << plane;
4380 return 0;
4383 static HRESULT WINAPI
4384 IDirect3DDeviceImpl_7_ComputeSphereVisibility(IDirect3DDevice7 *iface,
4385 D3DVECTOR *Centers,
4386 D3DVALUE *Radii,
4387 DWORD NumSpheres,
4388 DWORD Flags,
4389 DWORD *ReturnValues)
4391 D3DMATRIX m, temp;
4392 D3DVALUE origin_plane[6];
4393 D3DVECTOR vec[6];
4394 HRESULT hr;
4395 UINT i, j;
4397 TRACE("(%p)->(%p,%p,%08x,%08x,%p)\n", iface, Centers, Radii, NumSpheres, Flags, ReturnValues);
4399 hr = IDirect3DDeviceImpl_7_GetTransform(iface, D3DTRANSFORMSTATE_WORLD, &m);
4400 if ( hr != DD_OK ) return DDERR_INVALIDPARAMS;
4401 hr = IDirect3DDeviceImpl_7_GetTransform(iface, D3DTRANSFORMSTATE_VIEW, &temp);
4402 if ( hr != DD_OK ) return DDERR_INVALIDPARAMS;
4403 multiply_matrix_D3D_way(&m, &m, &temp);
4405 hr = IDirect3DDeviceImpl_7_GetTransform(iface, D3DTRANSFORMSTATE_PROJECTION, &temp);
4406 if ( hr != DD_OK ) return DDERR_INVALIDPARAMS;
4407 multiply_matrix_D3D_way(&m, &m, &temp);
4409 /* Left plane */
4410 vec[0].u1.x = m._14 + m._11;
4411 vec[0].u2.y = m._24 + m._21;
4412 vec[0].u3.z = m._34 + m._31;
4413 origin_plane[0] = m._44 + m._41;
4415 /* Right plane */
4416 vec[1].u1.x = m._14 - m._11;
4417 vec[1].u2.y = m._24 - m._21;
4418 vec[1].u3.z = m._34 - m._31;
4419 origin_plane[1] = m._44 - m._41;
4421 /* Top plane */
4422 vec[2].u1.x = m._14 - m._12;
4423 vec[2].u2.y = m._24 - m._22;
4424 vec[2].u3.z = m._34 - m._32;
4425 origin_plane[2] = m._44 - m._42;
4427 /* Bottom plane */
4428 vec[3].u1.x = m._14 + m._12;
4429 vec[3].u2.y = m._24 + m._22;
4430 vec[3].u3.z = m._34 + m._32;
4431 origin_plane[3] = m._44 + m._42;
4433 /* Front plane */
4434 vec[4].u1.x = m._13;
4435 vec[4].u2.y = m._23;
4436 vec[4].u3.z = m._33;
4437 origin_plane[4] = m._43;
4439 /* Back plane*/
4440 vec[5].u1.x = m._14 - m._13;
4441 vec[5].u2.y = m._24 - m._23;
4442 vec[5].u3.z = m._34 - m._33;
4443 origin_plane[5] = m._44 - m._43;
4445 for(i=0; i<NumSpheres; i++)
4447 ReturnValues[i] = 0;
4448 for(j=0; j<6; j++) ReturnValues[i] |= in_plane(j, vec[j], origin_plane[j], Centers[i], Radii[i]);
4451 return D3D_OK;
4454 static HRESULT WINAPI
4455 Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility(IDirect3DDevice3 *iface,
4456 D3DVECTOR *Centers,
4457 D3DVALUE *Radii,
4458 DWORD NumSpheres,
4459 DWORD Flags,
4460 DWORD *ReturnValues)
4462 IDirect3DDeviceImpl *This = device_from_device3(iface);
4463 TRACE_(ddraw_thunk)("(%p)->(%p,%p,%08x,%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, Centers, Radii, NumSpheres, Flags, ReturnValues);
4464 return IDirect3DDevice7_ComputeSphereVisibility((IDirect3DDevice7 *)This,
4465 Centers, Radii, NumSpheres, Flags, ReturnValues);
4468 /*****************************************************************************
4469 * IDirect3DDevice7::GetTexture
4471 * Returns the texture interface handle assigned to a texture stage.
4472 * The returned texture is AddRefed. This is taken from old ddraw,
4473 * not checked in Windows.
4475 * Version 3 and 7
4477 * Params:
4478 * Stage: Texture stage to read the texture from
4479 * Texture: Address to store the interface pointer at
4481 * Returns:
4482 * D3D_OK on success
4483 * DDERR_INVALIDPARAMS if Texture is NULL
4484 * For details, see IWineD3DDevice::GetTexture
4486 *****************************************************************************/
4487 static HRESULT
4488 IDirect3DDeviceImpl_7_GetTexture(IDirect3DDevice7 *iface,
4489 DWORD Stage,
4490 IDirectDrawSurface7 **Texture)
4492 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
4493 IWineD3DBaseTexture *Surf;
4494 HRESULT hr;
4495 TRACE("(%p)->(%d,%p): Relay\n", This, Stage, Texture);
4497 if(!Texture)
4499 TRACE("Texture == NULL, failing with DDERR_INVALIDPARAMS\n");
4500 return DDERR_INVALIDPARAMS;
4503 EnterCriticalSection(&ddraw_cs);
4504 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice, Stage, &Surf);
4505 if( (hr != D3D_OK) || (!Surf) )
4507 *Texture = NULL;
4508 LeaveCriticalSection(&ddraw_cs);
4509 return hr;
4512 /* GetParent AddRef()s, which is perfectly OK.
4513 * We have passed the IDirectDrawSurface7 interface to WineD3D, so that's OK too.
4515 hr = IWineD3DBaseTexture_GetParent(Surf,
4516 (IUnknown **) Texture);
4517 LeaveCriticalSection(&ddraw_cs);
4518 return hr;
4521 static HRESULT WINAPI
4522 IDirect3DDeviceImpl_7_GetTexture_FPUSetup(IDirect3DDevice7 *iface,
4523 DWORD Stage,
4524 IDirectDrawSurface7 **Texture)
4526 return IDirect3DDeviceImpl_7_GetTexture(iface, Stage, Texture);
4529 static HRESULT WINAPI
4530 IDirect3DDeviceImpl_7_GetTexture_FPUPreserve(IDirect3DDevice7 *iface,
4531 DWORD Stage,
4532 IDirectDrawSurface7 **Texture)
4534 HRESULT hr;
4535 WORD old_fpucw;
4537 old_fpucw = d3d_fpu_setup();
4538 hr = IDirect3DDeviceImpl_7_GetTexture(iface, Stage, Texture);
4539 set_fpu_control_word(old_fpucw);
4541 return hr;
4544 static HRESULT WINAPI
4545 Thunk_IDirect3DDeviceImpl_3_GetTexture(IDirect3DDevice3 *iface,
4546 DWORD Stage,
4547 IDirect3DTexture2 **Texture2)
4549 IDirect3DDeviceImpl *This = device_from_device3(iface);
4550 HRESULT ret;
4551 IDirectDrawSurface7 *ret_val;
4553 TRACE_(ddraw_thunk)("(%p)->(%d,%p) thunking to IDirect3DDevice7 interface.\n", This, Stage, Texture2);
4554 ret = IDirect3DDevice7_GetTexture((IDirect3DDevice7 *)This, Stage, &ret_val);
4556 *Texture2 = ret_val ? (IDirect3DTexture2 *)&((IDirectDrawSurfaceImpl *)ret_val)->IDirect3DTexture2_vtbl : NULL;
4558 TRACE_(ddraw_thunk)(" returning interface %p.\n", *Texture2);
4560 return ret;
4563 /*****************************************************************************
4564 * IDirect3DDevice7::SetTexture
4566 * Assigns a texture to a texture stage. Is the texture AddRef-ed?
4568 * Version 3 and 7
4570 * Params:
4571 * Stage: The stage to assign the texture to
4572 * Texture: Interface pointer to the texture surface
4574 * Returns
4575 * D3D_OK on success
4576 * For details, see IWineD3DDevice::SetTexture
4578 *****************************************************************************/
4579 static HRESULT
4580 IDirect3DDeviceImpl_7_SetTexture(IDirect3DDevice7 *iface,
4581 DWORD Stage,
4582 IDirectDrawSurface7 *Texture)
4584 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
4585 IDirectDrawSurfaceImpl *surf = (IDirectDrawSurfaceImpl *)Texture;
4586 HRESULT hr;
4587 TRACE("(%p)->(%08x,%p): Relay!\n", This, Stage, surf);
4589 /* Texture may be NULL here */
4590 EnterCriticalSection(&ddraw_cs);
4591 hr = IWineD3DDevice_SetTexture(This->wineD3DDevice,
4592 Stage,
4593 surf ? surf->wineD3DTexture : NULL);
4594 LeaveCriticalSection(&ddraw_cs);
4595 return hr;
4598 static HRESULT WINAPI
4599 IDirect3DDeviceImpl_7_SetTexture_FPUSetup(IDirect3DDevice7 *iface,
4600 DWORD Stage,
4601 IDirectDrawSurface7 *Texture)
4603 return IDirect3DDeviceImpl_7_SetTexture(iface, Stage, Texture);
4606 static HRESULT WINAPI
4607 IDirect3DDeviceImpl_7_SetTexture_FPUPreserve(IDirect3DDevice7 *iface,
4608 DWORD Stage,
4609 IDirectDrawSurface7 *Texture)
4611 HRESULT hr;
4612 WORD old_fpucw;
4614 old_fpucw = d3d_fpu_setup();
4615 hr = IDirect3DDeviceImpl_7_SetTexture(iface, Stage, Texture);
4616 set_fpu_control_word(old_fpucw);
4618 return hr;
4621 static HRESULT WINAPI
4622 IDirect3DDeviceImpl_3_SetTexture(IDirect3DDevice3 *iface,
4623 DWORD Stage,
4624 IDirect3DTexture2 *Texture2)
4626 IDirect3DDeviceImpl *This = device_from_device3(iface);
4627 IDirectDrawSurfaceImpl *tex = Texture2 ? surface_from_texture2(Texture2) : NULL;
4628 DWORD texmapblend;
4629 HRESULT hr;
4630 TRACE("(%p)->(%d,%p)\n", This, Stage, tex);
4632 EnterCriticalSection(&ddraw_cs);
4634 if (This->legacyTextureBlending)
4635 IDirect3DDevice3_GetRenderState(iface, D3DRENDERSTATE_TEXTUREMAPBLEND, &texmapblend);
4637 hr = IDirect3DDevice7_SetTexture((IDirect3DDevice7 *)This, Stage, (IDirectDrawSurface7 *)tex);
4639 if (This->legacyTextureBlending && texmapblend == D3DTBLEND_MODULATE)
4641 /* This fixup is required by the way D3DTBLEND_MODULATE maps to texture stage states.
4642 See IDirect3DDeviceImpl_3_SetRenderState for details. */
4643 BOOL tex_alpha = FALSE;
4644 IWineD3DBaseTexture *tex = NULL;
4645 WINED3DSURFACE_DESC desc;
4646 DDPIXELFORMAT ddfmt;
4647 HRESULT result;
4649 result = IWineD3DDevice_GetTexture(This->wineD3DDevice,
4651 &tex);
4653 if(result == WINED3D_OK && tex)
4655 memset(&desc, 0, sizeof(desc));
4656 result = IWineD3DTexture_GetLevelDesc((IWineD3DTexture*) tex, 0, &desc);
4657 if (SUCCEEDED(result))
4659 ddfmt.dwSize = sizeof(ddfmt);
4660 PixelFormat_WineD3DtoDD(&ddfmt, desc.format);
4661 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
4664 IWineD3DBaseTexture_Release(tex);
4667 /* alphaop is WINED3DTOP_SELECTARG1 if it's D3DTBLEND_MODULATE, so only modify alphaarg1 */
4668 if (tex_alpha)
4670 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
4672 else
4674 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_CURRENT);
4678 LeaveCriticalSection(&ddraw_cs);
4680 return hr;
4683 static const struct tss_lookup
4685 BOOL sampler_state;
4686 DWORD state;
4688 tss_lookup[] =
4690 {FALSE, WINED3DTSS_FORCE_DWORD}, /* 0, unused */
4691 {FALSE, WINED3DTSS_COLOROP}, /* 1, D3DTSS_COLOROP */
4692 {FALSE, WINED3DTSS_COLORARG1}, /* 2, D3DTSS_COLORARG1 */
4693 {FALSE, WINED3DTSS_COLORARG2}, /* 3, D3DTSS_COLORARG2 */
4694 {FALSE, WINED3DTSS_ALPHAOP}, /* 4, D3DTSS_ALPHAOP */
4695 {FALSE, WINED3DTSS_ALPHAARG1}, /* 5, D3DTSS_ALPHAARG1 */
4696 {FALSE, WINED3DTSS_ALPHAARG2}, /* 6, D3DTSS_ALPHAARG2 */
4697 {FALSE, WINED3DTSS_BUMPENVMAT00}, /* 7, D3DTSS_BUMPENVMAT00 */
4698 {FALSE, WINED3DTSS_BUMPENVMAT01}, /* 8, D3DTSS_BUMPENVMAT01 */
4699 {FALSE, WINED3DTSS_BUMPENVMAT10}, /* 9, D3DTSS_BUMPENVMAT10 */
4700 {FALSE, WINED3DTSS_BUMPENVMAT11}, /* 10, D3DTSS_BUMPENVMAT11 */
4701 {FALSE, WINED3DTSS_TEXCOORDINDEX}, /* 11, D3DTSS_TEXCOORDINDEX */
4702 {TRUE, WINED3DSAMP_ADDRESSU}, /* 12, D3DTSS_ADDRESS */
4703 {TRUE, WINED3DSAMP_ADDRESSU}, /* 13, D3DTSS_ADDRESSU */
4704 {TRUE, WINED3DSAMP_ADDRESSV}, /* 14, D3DTSS_ADDRESSV */
4705 {TRUE, WINED3DSAMP_BORDERCOLOR}, /* 15, D3DTSS_BORDERCOLOR */
4706 {TRUE, WINED3DSAMP_MAGFILTER}, /* 16, D3DTSS_MAGFILTER */
4707 {TRUE, WINED3DSAMP_MINFILTER}, /* 17, D3DTSS_MINFILTER */
4708 {TRUE, WINED3DSAMP_MIPFILTER}, /* 18, D3DTSS_MIPFILTER */
4709 {TRUE, WINED3DSAMP_MIPMAPLODBIAS}, /* 19, D3DTSS_MIPMAPLODBIAS */
4710 {TRUE, WINED3DSAMP_MAXMIPLEVEL}, /* 20, D3DTSS_MAXMIPLEVEL */
4711 {TRUE, WINED3DSAMP_MAXANISOTROPY}, /* 21, D3DTSS_MAXANISOTROPY */
4712 {FALSE, WINED3DTSS_BUMPENVLSCALE}, /* 22, D3DTSS_BUMPENVLSCALE */
4713 {FALSE, WINED3DTSS_BUMPENVLOFFSET}, /* 23, D3DTSS_BUMPENVLOFFSET */
4714 {FALSE, WINED3DTSS_TEXTURETRANSFORMFLAGS}, /* 24, D3DTSS_TEXTURETRANSFORMFLAGS */
4717 /*****************************************************************************
4718 * IDirect3DDevice7::GetTextureStageState
4720 * Retrieves a state from a texture stage.
4722 * Version 3 and 7
4724 * Params:
4725 * Stage: The stage to retrieve the state from
4726 * TexStageStateType: The state type to retrieve
4727 * State: Address to store the state's value at
4729 * Returns:
4730 * D3D_OK on success
4731 * DDERR_INVALIDPARAMS if State is NULL
4732 * For details, see IWineD3DDevice::GetTextureStageState
4734 *****************************************************************************/
4735 static HRESULT
4736 IDirect3DDeviceImpl_7_GetTextureStageState(IDirect3DDevice7 *iface,
4737 DWORD Stage,
4738 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4739 DWORD *State)
4741 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
4742 HRESULT hr;
4743 const struct tss_lookup *l = &tss_lookup[TexStageStateType];
4744 TRACE("(%p)->(%08x,%08x,%p): Relay!\n", This, Stage, TexStageStateType, State);
4746 if(!State)
4747 return DDERR_INVALIDPARAMS;
4749 if (TexStageStateType > D3DTSS_TEXTURETRANSFORMFLAGS)
4751 WARN("Invalid TexStageStateType %#x passed.\n", TexStageStateType);
4752 *State = 0;
4753 return DD_OK;
4756 EnterCriticalSection(&ddraw_cs);
4758 if (l->sampler_state)
4760 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice, Stage, l->state, State);
4762 switch(TexStageStateType)
4764 /* Mipfilter is a sampler state with different values */
4765 case D3DTSS_MIPFILTER:
4767 switch(*State)
4769 case WINED3DTEXF_NONE: *State = D3DTFP_NONE; break;
4770 case WINED3DTEXF_POINT: *State = D3DTFP_POINT; break;
4771 case WINED3DTEXF_LINEAR: *State = D3DTFP_LINEAR; break;
4772 default:
4773 ERR("Unexpected mipfilter value %#x\n", *State);
4774 *State = D3DTFP_NONE;
4775 break;
4777 break;
4780 /* Magfilter has slightly different values */
4781 case D3DTSS_MAGFILTER:
4783 switch(*State)
4785 case WINED3DTEXF_POINT: *State = D3DTFG_POINT; break;
4786 case WINED3DTEXF_LINEAR: *State = D3DTFG_LINEAR; break;
4787 case WINED3DTEXF_ANISOTROPIC: *State = D3DTFG_ANISOTROPIC; break;
4788 case WINED3DTEXF_FLATCUBIC: *State = D3DTFG_FLATCUBIC; break;
4789 case WINED3DTEXF_GAUSSIANCUBIC: *State = D3DTFG_GAUSSIANCUBIC; break;
4790 default:
4791 ERR("Unexpected wined3d mag filter value %#x\n", *State);
4792 *State = D3DTFG_POINT;
4793 break;
4795 break;
4798 default:
4799 break;
4802 else
4804 hr = IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, Stage, l->state, State);
4807 LeaveCriticalSection(&ddraw_cs);
4808 return hr;
4811 static HRESULT WINAPI
4812 IDirect3DDeviceImpl_7_GetTextureStageState_FPUSetup(IDirect3DDevice7 *iface,
4813 DWORD Stage,
4814 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4815 DWORD *State)
4817 return IDirect3DDeviceImpl_7_GetTextureStageState(iface, Stage, TexStageStateType, State);
4820 static HRESULT WINAPI
4821 IDirect3DDeviceImpl_7_GetTextureStageState_FPUPreserve(IDirect3DDevice7 *iface,
4822 DWORD Stage,
4823 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4824 DWORD *State)
4826 HRESULT hr;
4827 WORD old_fpucw;
4829 old_fpucw = d3d_fpu_setup();
4830 hr = IDirect3DDeviceImpl_7_GetTextureStageState(iface, Stage, TexStageStateType, State);
4831 set_fpu_control_word(old_fpucw);
4833 return hr;
4836 static HRESULT WINAPI
4837 Thunk_IDirect3DDeviceImpl_3_GetTextureStageState(IDirect3DDevice3 *iface,
4838 DWORD Stage,
4839 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4840 DWORD *State)
4842 IDirect3DDeviceImpl *This = device_from_device3(iface);
4843 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, Stage, TexStageStateType, State);
4844 return IDirect3DDevice7_GetTextureStageState((IDirect3DDevice7 *)This, Stage, TexStageStateType, State);
4847 /*****************************************************************************
4848 * IDirect3DDevice7::SetTextureStageState
4850 * Sets a texture stage state. Some stage types need to be handled specially,
4851 * because they do not exist in WineD3D and were moved to another place
4853 * Version 3 and 7
4855 * Params:
4856 * Stage: The stage to modify
4857 * TexStageStateType: The state to change
4858 * State: The new value for the state
4860 * Returns:
4861 * D3D_OK on success
4862 * For details, see IWineD3DDevice::SetTextureStageState
4864 *****************************************************************************/
4865 static HRESULT
4866 IDirect3DDeviceImpl_7_SetTextureStageState(IDirect3DDevice7 *iface,
4867 DWORD Stage,
4868 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4869 DWORD State)
4871 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
4872 const struct tss_lookup *l = &tss_lookup[TexStageStateType];
4873 HRESULT hr;
4874 TRACE("(%p)->(%08x,%08x,%08x): Relay!\n", This, Stage, TexStageStateType, State);
4876 if (TexStageStateType > D3DTSS_TEXTURETRANSFORMFLAGS)
4878 WARN("Invalid TexStageStateType %#x passed.\n", TexStageStateType);
4879 return DD_OK;
4882 EnterCriticalSection(&ddraw_cs);
4884 if (l->sampler_state)
4886 switch(TexStageStateType)
4888 /* Mipfilter is a sampler state with different values */
4889 case D3DTSS_MIPFILTER:
4891 switch(State)
4893 case D3DTFP_NONE: State = WINED3DTEXF_NONE; break;
4894 case D3DTFP_POINT: State = WINED3DTEXF_POINT; break;
4895 case 0: /* Unchecked */
4896 case D3DTFP_LINEAR: State = WINED3DTEXF_LINEAR; break;
4897 default:
4898 ERR("Unexpected mipfilter value %d\n", State);
4899 State = WINED3DTEXF_NONE;
4900 break;
4902 break;
4905 /* Magfilter has slightly different values */
4906 case D3DTSS_MAGFILTER:
4908 switch(State)
4910 case D3DTFG_POINT: State = WINED3DTEXF_POINT; break;
4911 case D3DTFG_LINEAR: State = WINED3DTEXF_LINEAR; break;
4912 case D3DTFG_FLATCUBIC: State = WINED3DTEXF_FLATCUBIC; break;
4913 case D3DTFG_GAUSSIANCUBIC: State = WINED3DTEXF_GAUSSIANCUBIC; break;
4914 case D3DTFG_ANISOTROPIC: State = WINED3DTEXF_ANISOTROPIC; break;
4915 default:
4916 ERR("Unexpected d3d7 mag filter type %d\n", State);
4917 State = WINED3DTEXF_POINT;
4918 break;
4920 break;
4923 case D3DTSS_ADDRESS:
4924 IWineD3DDevice_SetSamplerState(This->wineD3DDevice, Stage, WINED3DSAMP_ADDRESSV, State);
4925 break;
4927 default:
4928 break;
4931 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice, Stage, l->state, State);
4933 else
4935 hr = IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, Stage, l->state, State);
4938 LeaveCriticalSection(&ddraw_cs);
4939 return hr;
4942 static HRESULT WINAPI
4943 IDirect3DDeviceImpl_7_SetTextureStageState_FPUSetup(IDirect3DDevice7 *iface,
4944 DWORD Stage,
4945 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4946 DWORD State)
4948 return IDirect3DDeviceImpl_7_SetTextureStageState(iface, Stage, TexStageStateType, State);
4951 static HRESULT WINAPI
4952 IDirect3DDeviceImpl_7_SetTextureStageState_FPUPreserve(IDirect3DDevice7 *iface,
4953 DWORD Stage,
4954 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4955 DWORD State)
4957 HRESULT hr;
4958 WORD old_fpucw;
4960 old_fpucw = d3d_fpu_setup();
4961 hr = IDirect3DDeviceImpl_7_SetTextureStageState(iface, Stage, TexStageStateType, State);
4962 set_fpu_control_word(old_fpucw);
4964 return hr;
4967 static HRESULT WINAPI
4968 Thunk_IDirect3DDeviceImpl_3_SetTextureStageState(IDirect3DDevice3 *iface,
4969 DWORD Stage,
4970 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4971 DWORD State)
4973 IDirect3DDeviceImpl *This = device_from_device3(iface);
4974 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, Stage, TexStageStateType, State);
4975 return IDirect3DDevice7_SetTextureStageState((IDirect3DDevice7 *)This, Stage, TexStageStateType, State);
4978 /*****************************************************************************
4979 * IDirect3DDevice7::ValidateDevice
4981 * SDK: "Reports the device's ability to render the currently set
4982 * texture-blending operations in a single pass". Whatever that means
4983 * exactly...
4985 * Version 3 and 7
4987 * Params:
4988 * NumPasses: Address to write the number of necessary passes for the
4989 * desired effect to.
4991 * Returns:
4992 * D3D_OK on success
4993 * See IWineD3DDevice::ValidateDevice for more details
4995 *****************************************************************************/
4996 static HRESULT
4997 IDirect3DDeviceImpl_7_ValidateDevice(IDirect3DDevice7 *iface,
4998 DWORD *NumPasses)
5000 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5001 HRESULT hr;
5002 TRACE("(%p)->(%p): Relay\n", This, NumPasses);
5004 EnterCriticalSection(&ddraw_cs);
5005 hr = IWineD3DDevice_ValidateDevice(This->wineD3DDevice, NumPasses);
5006 LeaveCriticalSection(&ddraw_cs);
5007 return hr;
5010 static HRESULT WINAPI
5011 IDirect3DDeviceImpl_7_ValidateDevice_FPUSetup(IDirect3DDevice7 *iface,
5012 DWORD *NumPasses)
5014 return IDirect3DDeviceImpl_7_ValidateDevice(iface, NumPasses);
5017 static HRESULT WINAPI
5018 IDirect3DDeviceImpl_7_ValidateDevice_FPUPreserve(IDirect3DDevice7 *iface,
5019 DWORD *NumPasses)
5021 HRESULT hr;
5022 WORD old_fpucw;
5024 old_fpucw = d3d_fpu_setup();
5025 hr = IDirect3DDeviceImpl_7_ValidateDevice(iface, NumPasses);
5026 set_fpu_control_word(old_fpucw);
5028 return hr;
5031 static HRESULT WINAPI
5032 Thunk_IDirect3DDeviceImpl_3_ValidateDevice(IDirect3DDevice3 *iface,
5033 DWORD *Passes)
5035 IDirect3DDeviceImpl *This = device_from_device3(iface);
5036 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Passes);
5037 return IDirect3DDevice7_ValidateDevice((IDirect3DDevice7 *)This, Passes);
5040 /*****************************************************************************
5041 * IDirect3DDevice7::Clear
5043 * Fills the render target, the z buffer and the stencil buffer with a
5044 * clear color / value
5046 * Version 7 only
5048 * Params:
5049 * Count: Number of rectangles in Rects must be 0 if Rects is NULL
5050 * Rects: Rectangles to clear. If NULL, the whole surface is cleared
5051 * Flags: Some flags, as usual
5052 * Color: Clear color for the render target
5053 * Z: Clear value for the Z buffer
5054 * Stencil: Clear value to store in each stencil buffer entry
5056 * Returns:
5057 * D3D_OK on success
5058 * For details, see IWineD3DDevice::Clear
5060 *****************************************************************************/
5061 static HRESULT
5062 IDirect3DDeviceImpl_7_Clear(IDirect3DDevice7 *iface,
5063 DWORD Count,
5064 D3DRECT *Rects,
5065 DWORD Flags,
5066 D3DCOLOR Color,
5067 D3DVALUE Z,
5068 DWORD Stencil)
5070 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5071 HRESULT hr;
5072 TRACE("(%p)->(%08x,%p,%08x,%08x,%f,%08x): Relay\n", This, Count, Rects, Flags, Color, Z, Stencil);
5074 /* Note; D3DRECT is compatible with WINED3DRECT */
5075 EnterCriticalSection(&ddraw_cs);
5076 hr = IWineD3DDevice_Clear(This->wineD3DDevice, Count, (WINED3DRECT*) Rects, Flags, Color, Z, Stencil);
5077 LeaveCriticalSection(&ddraw_cs);
5078 return hr;
5081 static HRESULT WINAPI
5082 IDirect3DDeviceImpl_7_Clear_FPUSetup(IDirect3DDevice7 *iface,
5083 DWORD Count,
5084 D3DRECT *Rects,
5085 DWORD Flags,
5086 D3DCOLOR Color,
5087 D3DVALUE Z,
5088 DWORD Stencil)
5090 return IDirect3DDeviceImpl_7_Clear(iface, Count, Rects, Flags, Color, Z, Stencil);
5093 static HRESULT WINAPI
5094 IDirect3DDeviceImpl_7_Clear_FPUPreserve(IDirect3DDevice7 *iface,
5095 DWORD Count,
5096 D3DRECT *Rects,
5097 DWORD Flags,
5098 D3DCOLOR Color,
5099 D3DVALUE Z,
5100 DWORD Stencil)
5102 HRESULT hr;
5103 WORD old_fpucw;
5105 old_fpucw = d3d_fpu_setup();
5106 hr = IDirect3DDeviceImpl_7_Clear(iface, Count, Rects, Flags, Color, Z, Stencil);
5107 set_fpu_control_word(old_fpucw);
5109 return hr;
5112 /*****************************************************************************
5113 * IDirect3DDevice7::SetViewport
5115 * Sets the current viewport.
5117 * Version 7 only, but IDirect3DViewport uses this call for older
5118 * versions
5120 * Params:
5121 * Data: The new viewport to set
5123 * Returns:
5124 * D3D_OK on success
5125 * DDERR_INVALIDPARAMS if Data is NULL
5126 * For more details, see IWineDDDevice::SetViewport
5128 *****************************************************************************/
5129 static HRESULT
5130 IDirect3DDeviceImpl_7_SetViewport(IDirect3DDevice7 *iface,
5131 D3DVIEWPORT7 *Data)
5133 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5134 HRESULT hr;
5135 TRACE("(%p)->(%p) Relay!\n", This, Data);
5137 if(!Data)
5138 return DDERR_INVALIDPARAMS;
5140 /* Note: D3DVIEWPORT7 is compatible with WINED3DVIEWPORT */
5141 EnterCriticalSection(&ddraw_cs);
5142 hr = IWineD3DDevice_SetViewport(This->wineD3DDevice,
5143 (WINED3DVIEWPORT*) Data);
5144 LeaveCriticalSection(&ddraw_cs);
5145 return hr;
5148 static HRESULT WINAPI
5149 IDirect3DDeviceImpl_7_SetViewport_FPUSetup(IDirect3DDevice7 *iface,
5150 D3DVIEWPORT7 *Data)
5152 return IDirect3DDeviceImpl_7_SetViewport(iface, Data);
5155 static HRESULT WINAPI
5156 IDirect3DDeviceImpl_7_SetViewport_FPUPreserve(IDirect3DDevice7 *iface,
5157 D3DVIEWPORT7 *Data)
5159 HRESULT hr;
5160 WORD old_fpucw;
5162 old_fpucw = d3d_fpu_setup();
5163 hr = IDirect3DDeviceImpl_7_SetViewport(iface, Data);
5164 set_fpu_control_word(old_fpucw);
5166 return hr;
5169 /*****************************************************************************
5170 * IDirect3DDevice::GetViewport
5172 * Returns the current viewport
5174 * Version 7
5176 * Params:
5177 * Data: D3D7Viewport structure to write the viewport information to
5179 * Returns:
5180 * D3D_OK on success
5181 * DDERR_INVALIDPARAMS if Data is NULL
5182 * For more details, see IWineD3DDevice::GetViewport
5184 *****************************************************************************/
5185 static HRESULT
5186 IDirect3DDeviceImpl_7_GetViewport(IDirect3DDevice7 *iface,
5187 D3DVIEWPORT7 *Data)
5189 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5190 HRESULT hr;
5191 TRACE("(%p)->(%p) Relay!\n", This, Data);
5193 if(!Data)
5194 return DDERR_INVALIDPARAMS;
5196 /* Note: D3DVIEWPORT7 is compatible with WINED3DVIEWPORT */
5197 EnterCriticalSection(&ddraw_cs);
5198 hr = IWineD3DDevice_GetViewport(This->wineD3DDevice,
5199 (WINED3DVIEWPORT*) Data);
5201 LeaveCriticalSection(&ddraw_cs);
5202 return hr_ddraw_from_wined3d(hr);
5205 static HRESULT WINAPI
5206 IDirect3DDeviceImpl_7_GetViewport_FPUSetup(IDirect3DDevice7 *iface,
5207 D3DVIEWPORT7 *Data)
5209 return IDirect3DDeviceImpl_7_GetViewport(iface, Data);
5212 static HRESULT WINAPI
5213 IDirect3DDeviceImpl_7_GetViewport_FPUPreserve(IDirect3DDevice7 *iface,
5214 D3DVIEWPORT7 *Data)
5216 HRESULT hr;
5217 WORD old_fpucw;
5219 old_fpucw = d3d_fpu_setup();
5220 hr = IDirect3DDeviceImpl_7_GetViewport(iface, Data);
5221 set_fpu_control_word(old_fpucw);
5223 return hr;
5226 /*****************************************************************************
5227 * IDirect3DDevice7::SetMaterial
5229 * Sets the Material
5231 * Version 7
5233 * Params:
5234 * Mat: The material to set
5236 * Returns:
5237 * D3D_OK on success
5238 * DDERR_INVALIDPARAMS if Mat is NULL.
5239 * For more details, see IWineD3DDevice::SetMaterial
5241 *****************************************************************************/
5242 static HRESULT
5243 IDirect3DDeviceImpl_7_SetMaterial(IDirect3DDevice7 *iface,
5244 D3DMATERIAL7 *Mat)
5246 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5247 HRESULT hr;
5248 TRACE("(%p)->(%p): Relay!\n", This, Mat);
5250 if (!Mat) return DDERR_INVALIDPARAMS;
5251 /* Note: D3DMATERIAL7 is compatible with WINED3DMATERIAL */
5252 EnterCriticalSection(&ddraw_cs);
5253 hr = IWineD3DDevice_SetMaterial(This->wineD3DDevice,
5254 (WINED3DMATERIAL*) Mat);
5255 LeaveCriticalSection(&ddraw_cs);
5256 return hr_ddraw_from_wined3d(hr);
5259 static HRESULT WINAPI
5260 IDirect3DDeviceImpl_7_SetMaterial_FPUSetup(IDirect3DDevice7 *iface,
5261 D3DMATERIAL7 *Mat)
5263 return IDirect3DDeviceImpl_7_SetMaterial(iface, Mat);
5266 static HRESULT WINAPI
5267 IDirect3DDeviceImpl_7_SetMaterial_FPUPreserve(IDirect3DDevice7 *iface,
5268 D3DMATERIAL7 *Mat)
5270 HRESULT hr;
5271 WORD old_fpucw;
5273 old_fpucw = d3d_fpu_setup();
5274 hr = IDirect3DDeviceImpl_7_SetMaterial(iface, Mat);
5275 set_fpu_control_word(old_fpucw);
5277 return hr;
5280 /*****************************************************************************
5281 * IDirect3DDevice7::GetMaterial
5283 * Returns the current material
5285 * Version 7
5287 * Params:
5288 * Mat: D3DMATERIAL7 structure to write the material parameters to
5290 * Returns:
5291 * D3D_OK on success
5292 * DDERR_INVALIDPARAMS if Mat is NULL
5293 * For more details, see IWineD3DDevice::GetMaterial
5295 *****************************************************************************/
5296 static HRESULT
5297 IDirect3DDeviceImpl_7_GetMaterial(IDirect3DDevice7 *iface,
5298 D3DMATERIAL7 *Mat)
5300 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5301 HRESULT hr;
5302 TRACE("(%p)->(%p): Relay!\n", This, Mat);
5304 EnterCriticalSection(&ddraw_cs);
5305 /* Note: D3DMATERIAL7 is compatible with WINED3DMATERIAL */
5306 hr = IWineD3DDevice_GetMaterial(This->wineD3DDevice,
5307 (WINED3DMATERIAL*) Mat);
5308 LeaveCriticalSection(&ddraw_cs);
5309 return hr_ddraw_from_wined3d(hr);
5312 static HRESULT WINAPI
5313 IDirect3DDeviceImpl_7_GetMaterial_FPUSetup(IDirect3DDevice7 *iface,
5314 D3DMATERIAL7 *Mat)
5316 return IDirect3DDeviceImpl_7_GetMaterial(iface, Mat);
5319 static HRESULT WINAPI
5320 IDirect3DDeviceImpl_7_GetMaterial_FPUPreserve(IDirect3DDevice7 *iface,
5321 D3DMATERIAL7 *Mat)
5323 HRESULT hr;
5324 WORD old_fpucw;
5326 old_fpucw = d3d_fpu_setup();
5327 hr = IDirect3DDeviceImpl_7_GetMaterial(iface, Mat);
5328 set_fpu_control_word(old_fpucw);
5330 return hr;
5333 /*****************************************************************************
5334 * IDirect3DDevice7::SetLight
5336 * Assigns a light to a light index, but doesn't activate it yet.
5338 * Version 7, IDirect3DLight uses this method for older versions
5340 * Params:
5341 * LightIndex: The index of the new light
5342 * Light: A D3DLIGHT7 structure describing the light
5344 * Returns:
5345 * D3D_OK on success
5346 * For more details, see IWineD3DDevice::SetLight
5348 *****************************************************************************/
5349 static HRESULT
5350 IDirect3DDeviceImpl_7_SetLight(IDirect3DDevice7 *iface,
5351 DWORD LightIndex,
5352 D3DLIGHT7 *Light)
5354 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5355 HRESULT hr;
5356 TRACE("(%p)->(%08x,%p): Relay!\n", This, LightIndex, Light);
5358 EnterCriticalSection(&ddraw_cs);
5359 /* Note: D3DLIGHT7 is compatible with WINED3DLIGHT */
5360 hr = IWineD3DDevice_SetLight(This->wineD3DDevice,
5361 LightIndex,
5362 (WINED3DLIGHT*) Light);
5363 LeaveCriticalSection(&ddraw_cs);
5364 return hr_ddraw_from_wined3d(hr);
5367 static HRESULT WINAPI
5368 IDirect3DDeviceImpl_7_SetLight_FPUSetup(IDirect3DDevice7 *iface,
5369 DWORD LightIndex,
5370 D3DLIGHT7 *Light)
5372 return IDirect3DDeviceImpl_7_SetLight(iface, LightIndex, Light);
5375 static HRESULT WINAPI
5376 IDirect3DDeviceImpl_7_SetLight_FPUPreserve(IDirect3DDevice7 *iface,
5377 DWORD LightIndex,
5378 D3DLIGHT7 *Light)
5380 HRESULT hr;
5381 WORD old_fpucw;
5383 old_fpucw = d3d_fpu_setup();
5384 hr = IDirect3DDeviceImpl_7_SetLight(iface, LightIndex, Light);
5385 set_fpu_control_word(old_fpucw);
5387 return hr;
5390 /*****************************************************************************
5391 * IDirect3DDevice7::GetLight
5393 * Returns the light assigned to a light index
5395 * Params:
5396 * Light: Structure to write the light information to
5398 * Returns:
5399 * D3D_OK on success
5400 * DDERR_INVALIDPARAMS if Light is NULL
5401 * For details, see IWineD3DDevice::GetLight
5403 *****************************************************************************/
5404 static HRESULT
5405 IDirect3DDeviceImpl_7_GetLight(IDirect3DDevice7 *iface,
5406 DWORD LightIndex,
5407 D3DLIGHT7 *Light)
5409 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5410 HRESULT rc;
5411 TRACE("(%p)->(%08x,%p): Relay!\n", This, LightIndex, Light);
5413 EnterCriticalSection(&ddraw_cs);
5414 /* Note: D3DLIGHT7 is compatible with WINED3DLIGHT */
5415 rc = IWineD3DDevice_GetLight(This->wineD3DDevice,
5416 LightIndex,
5417 (WINED3DLIGHT*) Light);
5419 /* Translate the result. WineD3D returns other values than D3D7 */
5420 LeaveCriticalSection(&ddraw_cs);
5421 return hr_ddraw_from_wined3d(rc);
5424 static HRESULT WINAPI
5425 IDirect3DDeviceImpl_7_GetLight_FPUSetup(IDirect3DDevice7 *iface,
5426 DWORD LightIndex,
5427 D3DLIGHT7 *Light)
5429 return IDirect3DDeviceImpl_7_GetLight(iface, LightIndex, Light);
5432 static HRESULT WINAPI
5433 IDirect3DDeviceImpl_7_GetLight_FPUPreserve(IDirect3DDevice7 *iface,
5434 DWORD LightIndex,
5435 D3DLIGHT7 *Light)
5437 HRESULT hr;
5438 WORD old_fpucw;
5440 old_fpucw = d3d_fpu_setup();
5441 hr = IDirect3DDeviceImpl_7_GetLight(iface, LightIndex, Light);
5442 set_fpu_control_word(old_fpucw);
5444 return hr;
5447 /*****************************************************************************
5448 * IDirect3DDevice7::BeginStateBlock
5450 * Begins recording to a stateblock
5452 * Version 7
5454 * Returns:
5455 * D3D_OK on success
5456 * For details see IWineD3DDevice::BeginStateBlock
5458 *****************************************************************************/
5459 static HRESULT
5460 IDirect3DDeviceImpl_7_BeginStateBlock(IDirect3DDevice7 *iface)
5462 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5463 HRESULT hr;
5464 TRACE("(%p)->(): Relay!\n", This);
5466 EnterCriticalSection(&ddraw_cs);
5467 hr = IWineD3DDevice_BeginStateBlock(This->wineD3DDevice);
5468 LeaveCriticalSection(&ddraw_cs);
5469 return hr_ddraw_from_wined3d(hr);
5472 static HRESULT WINAPI
5473 IDirect3DDeviceImpl_7_BeginStateBlock_FPUSetup(IDirect3DDevice7 *iface)
5475 return IDirect3DDeviceImpl_7_BeginStateBlock(iface);
5478 static HRESULT WINAPI
5479 IDirect3DDeviceImpl_7_BeginStateBlock_FPUPreserve(IDirect3DDevice7 *iface)
5481 HRESULT hr;
5482 WORD old_fpucw;
5484 old_fpucw = d3d_fpu_setup();
5485 hr = IDirect3DDeviceImpl_7_BeginStateBlock(iface);
5486 set_fpu_control_word(old_fpucw);
5488 return hr;
5491 /*****************************************************************************
5492 * IDirect3DDevice7::EndStateBlock
5494 * Stops recording to a state block and returns the created stateblock
5495 * handle.
5497 * Version 7
5499 * Params:
5500 * BlockHandle: Address to store the stateblock's handle to
5502 * Returns:
5503 * D3D_OK on success
5504 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5505 * See IWineD3DDevice::EndStateBlock for more details
5507 *****************************************************************************/
5508 static HRESULT
5509 IDirect3DDeviceImpl_7_EndStateBlock(IDirect3DDevice7 *iface,
5510 DWORD *BlockHandle)
5512 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5513 HRESULT hr;
5514 TRACE("(%p)->(%p): Relay!\n", This, BlockHandle);
5516 if(!BlockHandle)
5518 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
5519 return DDERR_INVALIDPARAMS;
5522 EnterCriticalSection(&ddraw_cs);
5523 *BlockHandle = IDirect3DDeviceImpl_CreateHandle(This);
5524 if(!*BlockHandle)
5526 ERR("Cannot get a handle number for the stateblock\n");
5527 LeaveCriticalSection(&ddraw_cs);
5528 return DDERR_OUTOFMEMORY;
5530 This->Handles[*BlockHandle - 1].type = DDrawHandle_StateBlock;
5531 hr = IWineD3DDevice_EndStateBlock(This->wineD3DDevice,
5532 (IWineD3DStateBlock **) &This->Handles[*BlockHandle - 1].ptr);
5533 LeaveCriticalSection(&ddraw_cs);
5534 return hr_ddraw_from_wined3d(hr);
5537 static HRESULT WINAPI
5538 IDirect3DDeviceImpl_7_EndStateBlock_FPUSetup(IDirect3DDevice7 *iface,
5539 DWORD *BlockHandle)
5541 return IDirect3DDeviceImpl_7_EndStateBlock(iface, BlockHandle);
5544 static HRESULT WINAPI
5545 IDirect3DDeviceImpl_7_EndStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
5546 DWORD *BlockHandle)
5548 HRESULT hr;
5549 WORD old_fpucw;
5551 old_fpucw = d3d_fpu_setup();
5552 hr = IDirect3DDeviceImpl_7_EndStateBlock(iface, BlockHandle);
5553 set_fpu_control_word(old_fpucw);
5555 return hr;
5558 /*****************************************************************************
5559 * IDirect3DDevice7::PreLoad
5561 * Allows the app to signal that a texture will be used soon, to allow
5562 * the Direct3DDevice to load it to the video card in the meantime.
5564 * Version 7
5566 * Params:
5567 * Texture: The texture to preload
5569 * Returns:
5570 * D3D_OK on success
5571 * DDERR_INVALIDPARAMS if Texture is NULL
5572 * See IWineD3DSurface::PreLoad for details
5574 *****************************************************************************/
5575 static HRESULT
5576 IDirect3DDeviceImpl_7_PreLoad(IDirect3DDevice7 *iface,
5577 IDirectDrawSurface7 *Texture)
5579 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5580 IDirectDrawSurfaceImpl *surf = (IDirectDrawSurfaceImpl *)Texture;
5582 TRACE("(%p)->(%p): Relay!\n", This, surf);
5584 if(!Texture)
5585 return DDERR_INVALIDPARAMS;
5587 EnterCriticalSection(&ddraw_cs);
5588 IWineD3DSurface_PreLoad(surf->WineD3DSurface);
5589 LeaveCriticalSection(&ddraw_cs);
5590 return D3D_OK;
5593 static HRESULT WINAPI
5594 IDirect3DDeviceImpl_7_PreLoad_FPUSetup(IDirect3DDevice7 *iface,
5595 IDirectDrawSurface7 *Texture)
5597 return IDirect3DDeviceImpl_7_PreLoad(iface, Texture);
5600 static HRESULT WINAPI
5601 IDirect3DDeviceImpl_7_PreLoad_FPUPreserve(IDirect3DDevice7 *iface,
5602 IDirectDrawSurface7 *Texture)
5604 HRESULT hr;
5605 WORD old_fpucw;
5607 old_fpucw = d3d_fpu_setup();
5608 hr = IDirect3DDeviceImpl_7_PreLoad(iface, Texture);
5609 set_fpu_control_word(old_fpucw);
5611 return hr;
5614 /*****************************************************************************
5615 * IDirect3DDevice7::ApplyStateBlock
5617 * Activates the state stored in a state block handle.
5619 * Params:
5620 * BlockHandle: The stateblock handle to activate
5622 * Returns:
5623 * D3D_OK on success
5624 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5626 *****************************************************************************/
5627 static HRESULT
5628 IDirect3DDeviceImpl_7_ApplyStateBlock(IDirect3DDevice7 *iface,
5629 DWORD BlockHandle)
5631 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5632 HRESULT hr;
5633 TRACE("(%p)->(%08x): Relay!\n", This, BlockHandle);
5635 EnterCriticalSection(&ddraw_cs);
5636 if(!BlockHandle || BlockHandle > This->numHandles)
5638 WARN("Out of range handle %d, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5639 LeaveCriticalSection(&ddraw_cs);
5640 return D3DERR_INVALIDSTATEBLOCK;
5642 if(This->Handles[BlockHandle - 1].type != DDrawHandle_StateBlock)
5644 WARN("Handle %d is not a stateblock, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5645 LeaveCriticalSection(&ddraw_cs);
5646 return D3DERR_INVALIDSTATEBLOCK;
5649 hr = IWineD3DStateBlock_Apply((IWineD3DStateBlock *) This->Handles[BlockHandle - 1].ptr);
5650 LeaveCriticalSection(&ddraw_cs);
5651 return hr_ddraw_from_wined3d(hr);
5654 static HRESULT WINAPI
5655 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUSetup(IDirect3DDevice7 *iface,
5656 DWORD BlockHandle)
5658 return IDirect3DDeviceImpl_7_ApplyStateBlock(iface, BlockHandle);
5661 static HRESULT WINAPI
5662 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
5663 DWORD BlockHandle)
5665 HRESULT hr;
5666 WORD old_fpucw;
5668 old_fpucw = d3d_fpu_setup();
5669 hr = IDirect3DDeviceImpl_7_ApplyStateBlock(iface, BlockHandle);
5670 set_fpu_control_word(old_fpucw);
5672 return hr;
5675 /*****************************************************************************
5676 * IDirect3DDevice7::CaptureStateBlock
5678 * Updates a stateblock's values to the values currently set for the device
5680 * Version 7
5682 * Params:
5683 * BlockHandle: Stateblock to update
5685 * Returns:
5686 * D3D_OK on success
5687 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5688 * See IWineD3DDevice::CaptureStateBlock for more details
5690 *****************************************************************************/
5691 static HRESULT
5692 IDirect3DDeviceImpl_7_CaptureStateBlock(IDirect3DDevice7 *iface,
5693 DWORD BlockHandle)
5695 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5696 HRESULT hr;
5697 TRACE("(%p)->(%08x): Relay!\n", This, BlockHandle);
5699 EnterCriticalSection(&ddraw_cs);
5700 if(BlockHandle == 0 || BlockHandle > This->numHandles)
5702 WARN("Out of range handle %d, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5703 LeaveCriticalSection(&ddraw_cs);
5704 return D3DERR_INVALIDSTATEBLOCK;
5706 if(This->Handles[BlockHandle - 1].type != DDrawHandle_StateBlock)
5708 WARN("Handle %d is not a stateblock, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5709 LeaveCriticalSection(&ddraw_cs);
5710 return D3DERR_INVALIDSTATEBLOCK;
5713 hr = IWineD3DStateBlock_Capture((IWineD3DStateBlock *) This->Handles[BlockHandle - 1].ptr);
5714 LeaveCriticalSection(&ddraw_cs);
5715 return hr_ddraw_from_wined3d(hr);
5718 static HRESULT WINAPI
5719 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUSetup(IDirect3DDevice7 *iface,
5720 DWORD BlockHandle)
5722 return IDirect3DDeviceImpl_7_CaptureStateBlock(iface, BlockHandle);
5725 static HRESULT WINAPI
5726 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
5727 DWORD BlockHandle)
5729 HRESULT hr;
5730 WORD old_fpucw;
5732 old_fpucw = d3d_fpu_setup();
5733 hr = IDirect3DDeviceImpl_7_CaptureStateBlock(iface, BlockHandle);
5734 set_fpu_control_word(old_fpucw);
5736 return hr;
5739 /*****************************************************************************
5740 * IDirect3DDevice7::DeleteStateBlock
5742 * Deletes a stateblock handle. This means releasing the WineD3DStateBlock
5744 * Version 7
5746 * Params:
5747 * BlockHandle: Stateblock handle to delete
5749 * Returns:
5750 * D3D_OK on success
5751 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is 0
5753 *****************************************************************************/
5754 static HRESULT
5755 IDirect3DDeviceImpl_7_DeleteStateBlock(IDirect3DDevice7 *iface,
5756 DWORD BlockHandle)
5758 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5759 ULONG ref;
5760 TRACE("(%p)->(%08x): Relay!\n", This, BlockHandle);
5762 EnterCriticalSection(&ddraw_cs);
5763 if(BlockHandle == 0 || BlockHandle > This->numHandles)
5765 WARN("Out of range handle %d, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5766 LeaveCriticalSection(&ddraw_cs);
5767 return D3DERR_INVALIDSTATEBLOCK;
5769 if(This->Handles[BlockHandle - 1].type != DDrawHandle_StateBlock)
5771 WARN("Handle %d is not a stateblock, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5772 LeaveCriticalSection(&ddraw_cs);
5773 return D3DERR_INVALIDSTATEBLOCK;
5776 ref = IWineD3DStateBlock_Release((IWineD3DStateBlock *) This->Handles[BlockHandle - 1].ptr);
5777 if(ref)
5779 ERR("Something is still holding the stateblock %p(Handle %d). Ref = %d\n", This->Handles[BlockHandle - 1].ptr, BlockHandle, ref);
5781 This->Handles[BlockHandle - 1].ptr = NULL;
5782 This->Handles[BlockHandle - 1].type = DDrawHandle_Unknown;
5784 LeaveCriticalSection(&ddraw_cs);
5785 return D3D_OK;
5788 static HRESULT WINAPI
5789 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUSetup(IDirect3DDevice7 *iface,
5790 DWORD BlockHandle)
5792 return IDirect3DDeviceImpl_7_DeleteStateBlock(iface, BlockHandle);
5795 static HRESULT WINAPI
5796 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
5797 DWORD BlockHandle)
5799 HRESULT hr;
5800 WORD old_fpucw;
5802 old_fpucw = d3d_fpu_setup();
5803 hr = IDirect3DDeviceImpl_7_DeleteStateBlock(iface, BlockHandle);
5804 set_fpu_control_word(old_fpucw);
5806 return hr;
5809 /*****************************************************************************
5810 * IDirect3DDevice7::CreateStateBlock
5812 * Creates a new state block handle.
5814 * Version 7
5816 * Params:
5817 * Type: The state block type
5818 * BlockHandle: Address to write the created handle to
5820 * Returns:
5821 * D3D_OK on success
5822 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5824 *****************************************************************************/
5825 static HRESULT
5826 IDirect3DDeviceImpl_7_CreateStateBlock(IDirect3DDevice7 *iface,
5827 D3DSTATEBLOCKTYPE Type,
5828 DWORD *BlockHandle)
5830 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5831 HRESULT hr;
5832 TRACE("(%p)->(%08x,%p)!\n", This, Type, BlockHandle);
5834 if(!BlockHandle)
5836 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
5837 return DDERR_INVALIDPARAMS;
5839 if(Type != D3DSBT_ALL && Type != D3DSBT_PIXELSTATE &&
5840 Type != D3DSBT_VERTEXSTATE ) {
5841 WARN("Unexpected stateblock type, returning DDERR_INVALIDPARAMS\n");
5842 return DDERR_INVALIDPARAMS;
5845 EnterCriticalSection(&ddraw_cs);
5846 *BlockHandle = IDirect3DDeviceImpl_CreateHandle(This);
5847 if(!*BlockHandle)
5849 ERR("Cannot get a handle number for the stateblock\n");
5850 LeaveCriticalSection(&ddraw_cs);
5851 return DDERR_OUTOFMEMORY;
5853 This->Handles[*BlockHandle - 1].type = DDrawHandle_StateBlock;
5855 /* The D3DSTATEBLOCKTYPE enum is fine here */
5856 hr = IWineD3DDevice_CreateStateBlock(This->wineD3DDevice,
5857 Type,
5858 (IWineD3DStateBlock **) &This->Handles[*BlockHandle - 1].ptr,
5859 NULL /* Parent, hope that works */);
5860 LeaveCriticalSection(&ddraw_cs);
5861 return hr_ddraw_from_wined3d(hr);
5864 static HRESULT WINAPI
5865 IDirect3DDeviceImpl_7_CreateStateBlock_FPUSetup(IDirect3DDevice7 *iface,
5866 D3DSTATEBLOCKTYPE Type,
5867 DWORD *BlockHandle)
5869 return IDirect3DDeviceImpl_7_CreateStateBlock(iface, Type, BlockHandle);
5872 static HRESULT WINAPI
5873 IDirect3DDeviceImpl_7_CreateStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
5874 D3DSTATEBLOCKTYPE Type,
5875 DWORD *BlockHandle)
5877 HRESULT hr;
5878 WORD old_fpucw;
5880 old_fpucw = d3d_fpu_setup();
5881 hr =IDirect3DDeviceImpl_7_CreateStateBlock(iface, Type, BlockHandle);
5882 set_fpu_control_word(old_fpucw);
5884 return hr;
5887 /* Helper function for IDirect3DDeviceImpl_7_Load. */
5888 static BOOL is_mip_level_subset(IDirectDrawSurfaceImpl *dest,
5889 IDirectDrawSurfaceImpl *src)
5891 IDirectDrawSurfaceImpl *src_level, *dest_level;
5892 IDirectDrawSurface7 *temp;
5893 DDSURFACEDESC2 ddsd;
5894 BOOL levelFound; /* at least one suitable sublevel in dest found */
5896 /* To satisfy "destination is mip level subset of source" criteria (regular texture counts as 1 level),
5897 * 1) there must be at least one mip level in destination that matched dimensions of some mip level in source and
5898 * 2) there must be no destination levels that don't match any levels in source. Otherwise it's INVALIDPARAMS.
5900 levelFound = FALSE;
5902 src_level = src;
5903 dest_level = dest;
5905 for (;src_level && dest_level;)
5907 if (src_level->surface_desc.dwWidth == dest_level->surface_desc.dwWidth &&
5908 src_level->surface_desc.dwHeight == dest_level->surface_desc.dwHeight)
5910 levelFound = TRUE;
5912 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
5913 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
5914 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7 *)dest_level, &ddsd.ddsCaps, &temp);
5916 if (dest_level != dest) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)dest_level);
5918 dest_level = (IDirectDrawSurfaceImpl *)temp;
5921 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
5922 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
5923 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7 *)src_level, &ddsd.ddsCaps, &temp);
5925 if (src_level != src) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)src_level);
5927 src_level = (IDirectDrawSurfaceImpl *)temp;
5930 if (src_level && src_level != src) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)src_level);
5931 if (dest_level && dest_level != dest) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)dest_level);
5933 return !dest_level && levelFound;
5936 /* Helper function for IDirect3DDeviceImpl_7_Load. */
5937 static void copy_mipmap_chain(IDirect3DDeviceImpl *device,
5938 IDirectDrawSurfaceImpl *dest,
5939 IDirectDrawSurfaceImpl *src,
5940 const POINT *DestPoint,
5941 const RECT *SrcRect)
5943 IDirectDrawSurfaceImpl *src_level, *dest_level;
5944 IDirectDrawSurface7 *temp;
5945 DDSURFACEDESC2 ddsd;
5946 POINT point;
5947 RECT rect;
5948 HRESULT hr;
5949 IDirectDrawPalette *pal = NULL, *pal_src = NULL;
5950 DWORD ckeyflag;
5951 DDCOLORKEY ddckey;
5952 BOOL palette_missing = FALSE;
5954 /* Copy palette, if possible. */
5955 IDirectDrawSurface7_GetPalette((IDirectDrawSurface7 *)src, &pal_src);
5956 IDirectDrawSurface7_GetPalette((IDirectDrawSurface7 *)dest, &pal);
5958 if (pal_src != NULL && pal != NULL)
5960 PALETTEENTRY palent[256];
5962 IDirectDrawPalette_GetEntries(pal_src, 0, 0, 256, palent);
5963 IDirectDrawPalette_SetEntries(pal, 0, 0, 256, palent);
5966 if (dest->surface_desc.u4.ddpfPixelFormat.dwFlags & (DDPF_PALETTEINDEXED1 | DDPF_PALETTEINDEXED2 |
5967 DDPF_PALETTEINDEXED4 | DDPF_PALETTEINDEXED8 | DDPF_PALETTEINDEXEDTO8) && !pal)
5969 palette_missing = TRUE;
5972 if (pal) IDirectDrawPalette_Release(pal);
5973 if (pal_src) IDirectDrawPalette_Release(pal_src);
5975 /* Copy colorkeys, if present. */
5976 for (ckeyflag = DDCKEY_DESTBLT; ckeyflag <= DDCKEY_SRCOVERLAY; ckeyflag <<= 1)
5978 hr = IDirectDrawSurface7_GetColorKey((IDirectDrawSurface7 *)src, ckeyflag, &ddckey);
5980 if (SUCCEEDED(hr))
5982 IDirectDrawSurface7_SetColorKey((IDirectDrawSurface7 *)dest, ckeyflag, &ddckey);
5986 src_level = src;
5987 dest_level = dest;
5989 point = *DestPoint;
5990 rect = *SrcRect;
5992 for (;src_level && dest_level;)
5994 if (src_level->surface_desc.dwWidth == dest_level->surface_desc.dwWidth &&
5995 src_level->surface_desc.dwHeight == dest_level->surface_desc.dwHeight)
5997 /* Try UpdateSurface that may perform a more direct opengl loading. But skip this if destination is paletted texture and has no palette.
5998 * Some games like Sacrifice set palette after Load, and it is a waste of effort to try to load texture without palette and generates
5999 * warnings in wined3d. */
6000 if (!palette_missing)
6001 hr = IWineD3DDevice_UpdateSurface(device->wineD3DDevice, src_level->WineD3DSurface, &rect, dest_level->WineD3DSurface,
6002 &point);
6004 if (palette_missing || FAILED(hr))
6006 /* UpdateSurface may fail e.g. if dest is in system memory. Fall back to BltFast that is less strict. */
6007 IWineD3DSurface_BltFast(dest_level->WineD3DSurface,
6008 point.x, point.y,
6009 src_level->WineD3DSurface, &rect, 0);
6012 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6013 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
6014 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7 *)dest_level, &ddsd.ddsCaps, &temp);
6016 if (dest_level != dest) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)dest_level);
6018 dest_level = (IDirectDrawSurfaceImpl *)temp;
6021 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6022 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
6023 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7 *)src_level, &ddsd.ddsCaps, &temp);
6025 if (src_level != src) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)src_level);
6027 src_level = (IDirectDrawSurfaceImpl *)temp;
6029 point.x /= 2;
6030 point.y /= 2;
6032 rect.top /= 2;
6033 rect.left /= 2;
6034 rect.right = (rect.right + 1) / 2;
6035 rect.bottom = (rect.bottom + 1) / 2;
6038 if (src_level && src_level != src) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)src_level);
6039 if (dest_level && dest_level != dest) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)dest_level);
6042 /*****************************************************************************
6043 * IDirect3DDevice7::Load
6045 * Loads a rectangular area from the source into the destination texture.
6046 * It can also copy the source to the faces of a cubic environment map
6048 * Version 7
6050 * Params:
6051 * DestTex: Destination texture
6052 * DestPoint: Point in the destination where the source image should be
6053 * written to
6054 * SrcTex: Source texture
6055 * SrcRect: Source rectangle
6056 * Flags: Cubemap faces to load (DDSCAPS2_CUBEMAP_ALLFACES, DDSCAPS2_CUBEMAP_POSITIVEX,
6057 * DDSCAPS2_CUBEMAP_NEGATIVEX, DDSCAPS2_CUBEMAP_POSITIVEY, DDSCAPS2_CUBEMAP_NEGATIVEY,
6058 * DDSCAPS2_CUBEMAP_POSITIVEZ, DDSCAPS2_CUBEMAP_NEGATIVEZ)
6060 * Returns:
6061 * D3D_OK on success
6062 * DDERR_INVALIDPARAMS if DestTex or SrcTex are NULL, broken coordinates or anything unexpected.
6065 *****************************************************************************/
6067 static HRESULT
6068 IDirect3DDeviceImpl_7_Load(IDirect3DDevice7 *iface,
6069 IDirectDrawSurface7 *DestTex,
6070 POINT *DestPoint,
6071 IDirectDrawSurface7 *SrcTex,
6072 RECT *SrcRect,
6073 DWORD Flags)
6075 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
6076 IDirectDrawSurfaceImpl *dest = (IDirectDrawSurfaceImpl *)DestTex;
6077 IDirectDrawSurfaceImpl *src = (IDirectDrawSurfaceImpl *)SrcTex;
6078 POINT destpoint;
6079 RECT srcrect;
6080 TRACE("(%p)->(%p,%p,%p,%p,%08x)\n", This, dest, DestPoint, src, SrcRect, Flags);
6082 if( (!src) || (!dest) )
6083 return DDERR_INVALIDPARAMS;
6085 EnterCriticalSection(&ddraw_cs);
6087 if (SrcRect) srcrect = *SrcRect;
6088 else
6090 srcrect.left = srcrect.top = 0;
6091 srcrect.right = src->surface_desc.dwWidth;
6092 srcrect.bottom = src->surface_desc.dwHeight;
6095 if (DestPoint) destpoint = *DestPoint;
6096 else
6098 destpoint.x = destpoint.y = 0;
6100 /* Check bad dimensions. DestPoint is validated against src, not dest, because
6101 * destination can be a subset of mip levels, in which case actual coordinates used
6102 * for it may be divided. If any dimension of dest is larger than source, it can't be
6103 * mip level subset, so an error can be returned early.
6105 if (srcrect.left >= srcrect.right || srcrect.top >= srcrect.bottom ||
6106 srcrect.right > src->surface_desc.dwWidth ||
6107 srcrect.bottom > src->surface_desc.dwHeight ||
6108 destpoint.x + srcrect.right - srcrect.left > src->surface_desc.dwWidth ||
6109 destpoint.y + srcrect.bottom - srcrect.top > src->surface_desc.dwHeight ||
6110 dest->surface_desc.dwWidth > src->surface_desc.dwWidth ||
6111 dest->surface_desc.dwHeight > src->surface_desc.dwHeight)
6113 LeaveCriticalSection(&ddraw_cs);
6114 return DDERR_INVALIDPARAMS;
6117 /* Must be top level surfaces. */
6118 if (src->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_MIPMAPSUBLEVEL ||
6119 dest->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_MIPMAPSUBLEVEL)
6121 LeaveCriticalSection(&ddraw_cs);
6122 return DDERR_INVALIDPARAMS;
6125 if (src->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP)
6127 DWORD src_face_flag, dest_face_flag;
6128 IDirectDrawSurfaceImpl *src_face, *dest_face;
6129 IDirectDrawSurface7 *temp;
6130 DDSURFACEDESC2 ddsd;
6131 int i;
6133 if (!(dest->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP))
6135 LeaveCriticalSection(&ddraw_cs);
6136 return DDERR_INVALIDPARAMS;
6139 /* Iterate through cube faces 2 times. First time is just to check INVALIDPARAMS conditions, second
6140 * time it's actual surface loading. */
6141 for (i = 0; i < 2; i++)
6143 dest_face = dest;
6144 src_face = src;
6146 for (;dest_face && src_face;)
6148 src_face_flag = src_face->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP_ALLFACES;
6149 dest_face_flag = dest_face->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP_ALLFACES;
6151 if (src_face_flag == dest_face_flag)
6153 if (i == 0)
6155 /* Destination mip levels must be subset of source mip levels. */
6156 if (!is_mip_level_subset(dest_face, src_face))
6158 LeaveCriticalSection(&ddraw_cs);
6159 return DDERR_INVALIDPARAMS;
6162 else if (Flags & dest_face_flag)
6164 copy_mipmap_chain(This, dest_face, src_face, &destpoint, &srcrect);
6167 if (src_face_flag < DDSCAPS2_CUBEMAP_NEGATIVEZ)
6169 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6170 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | (src_face_flag << 1);
6171 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7 *)src, &ddsd.ddsCaps, &temp);
6173 if (src_face != src) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)src_face);
6175 src_face = (IDirectDrawSurfaceImpl *)temp;
6177 else
6179 if (src_face != src) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)src_face);
6181 src_face = NULL;
6185 if (dest_face_flag < DDSCAPS2_CUBEMAP_NEGATIVEZ)
6187 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6188 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | (dest_face_flag << 1);
6189 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7 *)dest, &ddsd.ddsCaps, &temp);
6191 if (dest_face != dest) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)dest_face);
6193 dest_face = (IDirectDrawSurfaceImpl *)temp;
6195 else
6197 if (dest_face != dest) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)dest_face);
6199 dest_face = NULL;
6203 if (i == 0)
6205 /* Native returns error if src faces are not subset of dest faces. */
6206 if (src_face)
6208 LeaveCriticalSection(&ddraw_cs);
6209 return DDERR_INVALIDPARAMS;
6214 LeaveCriticalSection(&ddraw_cs);
6215 return D3D_OK;
6217 else if (dest->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP)
6219 LeaveCriticalSection(&ddraw_cs);
6220 return DDERR_INVALIDPARAMS;
6223 /* Handle non cube map textures. */
6225 /* Destination mip levels must be subset of source mip levels. */
6226 if (!is_mip_level_subset(dest, src))
6228 LeaveCriticalSection(&ddraw_cs);
6229 return DDERR_INVALIDPARAMS;
6232 copy_mipmap_chain(This, dest, src, &destpoint, &srcrect);
6234 LeaveCriticalSection(&ddraw_cs);
6235 return D3D_OK;
6238 static HRESULT WINAPI
6239 IDirect3DDeviceImpl_7_Load_FPUSetup(IDirect3DDevice7 *iface,
6240 IDirectDrawSurface7 *DestTex,
6241 POINT *DestPoint,
6242 IDirectDrawSurface7 *SrcTex,
6243 RECT *SrcRect,
6244 DWORD Flags)
6246 return IDirect3DDeviceImpl_7_Load(iface, DestTex, DestPoint, SrcTex, SrcRect, Flags);
6249 static HRESULT WINAPI
6250 IDirect3DDeviceImpl_7_Load_FPUPreserve(IDirect3DDevice7 *iface,
6251 IDirectDrawSurface7 *DestTex,
6252 POINT *DestPoint,
6253 IDirectDrawSurface7 *SrcTex,
6254 RECT *SrcRect,
6255 DWORD Flags)
6257 HRESULT hr;
6258 WORD old_fpucw;
6260 old_fpucw = d3d_fpu_setup();
6261 hr = IDirect3DDeviceImpl_7_Load(iface, DestTex, DestPoint, SrcTex, SrcRect, Flags);
6262 set_fpu_control_word(old_fpucw);
6264 return hr;
6267 /*****************************************************************************
6268 * IDirect3DDevice7::LightEnable
6270 * Enables or disables a light
6272 * Version 7, IDirect3DLight uses this method too.
6274 * Params:
6275 * LightIndex: The index of the light to enable / disable
6276 * Enable: Enable or disable the light
6278 * Returns:
6279 * D3D_OK on success
6280 * For more details, see IWineD3DDevice::SetLightEnable
6282 *****************************************************************************/
6283 static HRESULT
6284 IDirect3DDeviceImpl_7_LightEnable(IDirect3DDevice7 *iface,
6285 DWORD LightIndex,
6286 BOOL Enable)
6288 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
6289 HRESULT hr;
6290 TRACE("(%p)->(%08x,%d): Relay!\n", This, LightIndex, Enable);
6292 EnterCriticalSection(&ddraw_cs);
6293 hr = IWineD3DDevice_SetLightEnable(This->wineD3DDevice, LightIndex, Enable);
6294 LeaveCriticalSection(&ddraw_cs);
6295 return hr_ddraw_from_wined3d(hr);
6298 static HRESULT WINAPI
6299 IDirect3DDeviceImpl_7_LightEnable_FPUSetup(IDirect3DDevice7 *iface,
6300 DWORD LightIndex,
6301 BOOL Enable)
6303 return IDirect3DDeviceImpl_7_LightEnable(iface, LightIndex, Enable);
6306 static HRESULT WINAPI
6307 IDirect3DDeviceImpl_7_LightEnable_FPUPreserve(IDirect3DDevice7 *iface,
6308 DWORD LightIndex,
6309 BOOL Enable)
6311 HRESULT hr;
6312 WORD old_fpucw;
6314 old_fpucw = d3d_fpu_setup();
6315 hr = IDirect3DDeviceImpl_7_LightEnable(iface, LightIndex, Enable);
6316 set_fpu_control_word(old_fpucw);
6318 return hr;
6321 /*****************************************************************************
6322 * IDirect3DDevice7::GetLightEnable
6324 * Retrieves if the light with the given index is enabled or not
6326 * Version 7
6328 * Params:
6329 * LightIndex: Index of desired light
6330 * Enable: Pointer to a BOOL which contains the result
6332 * Returns:
6333 * D3D_OK on success
6334 * DDERR_INVALIDPARAMS if Enable is NULL
6335 * See IWineD3DDevice::GetLightEnable for more details
6337 *****************************************************************************/
6338 static HRESULT
6339 IDirect3DDeviceImpl_7_GetLightEnable(IDirect3DDevice7 *iface,
6340 DWORD LightIndex,
6341 BOOL* Enable)
6343 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
6344 HRESULT hr;
6345 TRACE("(%p)->(%08x,%p): Relay\n", This, LightIndex, Enable);
6347 if(!Enable)
6348 return DDERR_INVALIDPARAMS;
6350 EnterCriticalSection(&ddraw_cs);
6351 hr = IWineD3DDevice_GetLightEnable(This->wineD3DDevice, LightIndex, Enable);
6352 LeaveCriticalSection(&ddraw_cs);
6353 return hr_ddraw_from_wined3d(hr);
6356 static HRESULT WINAPI
6357 IDirect3DDeviceImpl_7_GetLightEnable_FPUSetup(IDirect3DDevice7 *iface,
6358 DWORD LightIndex,
6359 BOOL* Enable)
6361 return IDirect3DDeviceImpl_7_GetLightEnable(iface, LightIndex, Enable);
6364 static HRESULT WINAPI
6365 IDirect3DDeviceImpl_7_GetLightEnable_FPUPreserve(IDirect3DDevice7 *iface,
6366 DWORD LightIndex,
6367 BOOL* Enable)
6369 HRESULT hr;
6370 WORD old_fpucw;
6372 old_fpucw = d3d_fpu_setup();
6373 hr = IDirect3DDeviceImpl_7_GetLightEnable(iface, LightIndex, Enable);
6374 set_fpu_control_word(old_fpucw);
6376 return hr;
6379 /*****************************************************************************
6380 * IDirect3DDevice7::SetClipPlane
6382 * Sets custom clipping plane
6384 * Version 7
6386 * Params:
6387 * Index: The index of the clipping plane
6388 * PlaneEquation: An equation defining the clipping plane
6390 * Returns:
6391 * D3D_OK on success
6392 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6393 * See IWineD3DDevice::SetClipPlane for more details
6395 *****************************************************************************/
6396 static HRESULT
6397 IDirect3DDeviceImpl_7_SetClipPlane(IDirect3DDevice7 *iface,
6398 DWORD Index,
6399 D3DVALUE* PlaneEquation)
6401 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
6402 HRESULT hr;
6403 TRACE("(%p)->(%08x,%p): Relay!\n", This, Index, PlaneEquation);
6405 if(!PlaneEquation)
6406 return DDERR_INVALIDPARAMS;
6408 EnterCriticalSection(&ddraw_cs);
6409 hr = IWineD3DDevice_SetClipPlane(This->wineD3DDevice, Index, PlaneEquation);
6410 LeaveCriticalSection(&ddraw_cs);
6411 return hr;
6414 static HRESULT WINAPI
6415 IDirect3DDeviceImpl_7_SetClipPlane_FPUSetup(IDirect3DDevice7 *iface,
6416 DWORD Index,
6417 D3DVALUE* PlaneEquation)
6419 return IDirect3DDeviceImpl_7_SetClipPlane(iface, Index, PlaneEquation);
6422 static HRESULT WINAPI
6423 IDirect3DDeviceImpl_7_SetClipPlane_FPUPreserve(IDirect3DDevice7 *iface,
6424 DWORD Index,
6425 D3DVALUE* PlaneEquation)
6427 HRESULT hr;
6428 WORD old_fpucw;
6430 old_fpucw = d3d_fpu_setup();
6431 hr = IDirect3DDeviceImpl_7_SetClipPlane(iface, Index, PlaneEquation);
6432 set_fpu_control_word(old_fpucw);
6434 return hr;
6437 /*****************************************************************************
6438 * IDirect3DDevice7::GetClipPlane
6440 * Returns the clipping plane with a specific index
6442 * Params:
6443 * Index: The index of the desired plane
6444 * PlaneEquation: Address to store the plane equation to
6446 * Returns:
6447 * D3D_OK on success
6448 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6449 * See IWineD3DDevice::GetClipPlane for more details
6451 *****************************************************************************/
6452 static HRESULT
6453 IDirect3DDeviceImpl_7_GetClipPlane(IDirect3DDevice7 *iface,
6454 DWORD Index,
6455 D3DVALUE* PlaneEquation)
6457 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
6458 HRESULT hr;
6459 TRACE("(%p)->(%d,%p): Relay!\n", This, Index, PlaneEquation);
6461 if(!PlaneEquation)
6462 return DDERR_INVALIDPARAMS;
6464 EnterCriticalSection(&ddraw_cs);
6465 hr = IWineD3DDevice_GetClipPlane(This->wineD3DDevice, Index, PlaneEquation);
6466 LeaveCriticalSection(&ddraw_cs);
6467 return hr;
6470 static HRESULT WINAPI
6471 IDirect3DDeviceImpl_7_GetClipPlane_FPUSetup(IDirect3DDevice7 *iface,
6472 DWORD Index,
6473 D3DVALUE* PlaneEquation)
6475 return IDirect3DDeviceImpl_7_GetClipPlane(iface, Index, PlaneEquation);
6478 static HRESULT WINAPI
6479 IDirect3DDeviceImpl_7_GetClipPlane_FPUPreserve(IDirect3DDevice7 *iface,
6480 DWORD Index,
6481 D3DVALUE* PlaneEquation)
6483 HRESULT hr;
6484 WORD old_fpucw;
6486 old_fpucw = d3d_fpu_setup();
6487 hr = IDirect3DDeviceImpl_7_GetClipPlane(iface, Index, PlaneEquation);
6488 set_fpu_control_word(old_fpucw);
6490 return hr;
6493 /*****************************************************************************
6494 * IDirect3DDevice7::GetInfo
6496 * Retrieves some information about the device. The DirectX sdk says that
6497 * this version returns S_FALSE for all retail builds of DirectX, that's what
6498 * this implementation does.
6500 * Params:
6501 * DevInfoID: Information type requested
6502 * DevInfoStruct: Pointer to a structure to store the info to
6503 * Size: Size of the structure
6505 * Returns:
6506 * S_FALSE, because it's a non-debug driver
6508 *****************************************************************************/
6509 static HRESULT WINAPI
6510 IDirect3DDeviceImpl_7_GetInfo(IDirect3DDevice7 *iface,
6511 DWORD DevInfoID,
6512 void *DevInfoStruct,
6513 DWORD Size)
6515 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
6516 TRACE("(%p)->(%08x,%p,%08x)\n", This, DevInfoID, DevInfoStruct, Size);
6518 if (TRACE_ON(d3d7))
6520 TRACE(" info requested : ");
6521 switch (DevInfoID)
6523 case D3DDEVINFOID_TEXTUREMANAGER: TRACE("D3DDEVINFOID_TEXTUREMANAGER\n"); break;
6524 case D3DDEVINFOID_D3DTEXTUREMANAGER: TRACE("D3DDEVINFOID_D3DTEXTUREMANAGER\n"); break;
6525 case D3DDEVINFOID_TEXTURING: TRACE("D3DDEVINFOID_TEXTURING\n"); break;
6526 default: ERR(" invalid flag !!!\n"); return DDERR_INVALIDPARAMS;
6530 return S_FALSE; /* According to MSDN, this is valid for a non-debug driver */
6533 /* For performance optimization, devices created in FPUSETUP and FPUPRESERVE modes
6534 * have separate vtables. Simple functions where this doesn't matter like GetDirect3D
6535 * are not duplicated.
6537 * Device created with DDSCL_FPUSETUP (d3d7 default) - device methods assume that FPU
6538 * has already been setup for optimal d3d operation.
6540 * Device created with DDSCL_FPUPRESERVE - resets and restores FPU mode when necessary in
6541 * d3d calls (FPU may be in a mode non-suitable for d3d when the app calls d3d). Required
6542 * by Sacrifice (game). */
6543 const IDirect3DDevice7Vtbl IDirect3DDevice7_FPUSetup_Vtbl =
6545 /*** IUnknown Methods ***/
6546 IDirect3DDeviceImpl_7_QueryInterface,
6547 IDirect3DDeviceImpl_7_AddRef,
6548 IDirect3DDeviceImpl_7_Release,
6549 /*** IDirect3DDevice7 ***/
6550 IDirect3DDeviceImpl_7_GetCaps_FPUSetup,
6551 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUSetup,
6552 IDirect3DDeviceImpl_7_BeginScene_FPUSetup,
6553 IDirect3DDeviceImpl_7_EndScene_FPUSetup,
6554 IDirect3DDeviceImpl_7_GetDirect3D,
6555 IDirect3DDeviceImpl_7_SetRenderTarget_FPUSetup,
6556 IDirect3DDeviceImpl_7_GetRenderTarget,
6557 IDirect3DDeviceImpl_7_Clear_FPUSetup,
6558 IDirect3DDeviceImpl_7_SetTransform_FPUSetup,
6559 IDirect3DDeviceImpl_7_GetTransform_FPUSetup,
6560 IDirect3DDeviceImpl_7_SetViewport_FPUSetup,
6561 IDirect3DDeviceImpl_7_MultiplyTransform_FPUSetup,
6562 IDirect3DDeviceImpl_7_GetViewport_FPUSetup,
6563 IDirect3DDeviceImpl_7_SetMaterial_FPUSetup,
6564 IDirect3DDeviceImpl_7_GetMaterial_FPUSetup,
6565 IDirect3DDeviceImpl_7_SetLight_FPUSetup,
6566 IDirect3DDeviceImpl_7_GetLight_FPUSetup,
6567 IDirect3DDeviceImpl_7_SetRenderState_FPUSetup,
6568 IDirect3DDeviceImpl_7_GetRenderState_FPUSetup,
6569 IDirect3DDeviceImpl_7_BeginStateBlock_FPUSetup,
6570 IDirect3DDeviceImpl_7_EndStateBlock_FPUSetup,
6571 IDirect3DDeviceImpl_7_PreLoad_FPUSetup,
6572 IDirect3DDeviceImpl_7_DrawPrimitive_FPUSetup,
6573 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUSetup,
6574 IDirect3DDeviceImpl_7_SetClipStatus,
6575 IDirect3DDeviceImpl_7_GetClipStatus,
6576 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUSetup,
6577 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUSetup,
6578 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUSetup,
6579 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUSetup,
6580 IDirect3DDeviceImpl_7_ComputeSphereVisibility,
6581 IDirect3DDeviceImpl_7_GetTexture_FPUSetup,
6582 IDirect3DDeviceImpl_7_SetTexture_FPUSetup,
6583 IDirect3DDeviceImpl_7_GetTextureStageState_FPUSetup,
6584 IDirect3DDeviceImpl_7_SetTextureStageState_FPUSetup,
6585 IDirect3DDeviceImpl_7_ValidateDevice_FPUSetup,
6586 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUSetup,
6587 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUSetup,
6588 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUSetup,
6589 IDirect3DDeviceImpl_7_CreateStateBlock_FPUSetup,
6590 IDirect3DDeviceImpl_7_Load_FPUSetup,
6591 IDirect3DDeviceImpl_7_LightEnable_FPUSetup,
6592 IDirect3DDeviceImpl_7_GetLightEnable_FPUSetup,
6593 IDirect3DDeviceImpl_7_SetClipPlane_FPUSetup,
6594 IDirect3DDeviceImpl_7_GetClipPlane_FPUSetup,
6595 IDirect3DDeviceImpl_7_GetInfo
6598 const IDirect3DDevice7Vtbl IDirect3DDevice7_FPUPreserve_Vtbl =
6600 /*** IUnknown Methods ***/
6601 IDirect3DDeviceImpl_7_QueryInterface,
6602 IDirect3DDeviceImpl_7_AddRef,
6603 IDirect3DDeviceImpl_7_Release,
6604 /*** IDirect3DDevice7 ***/
6605 IDirect3DDeviceImpl_7_GetCaps_FPUPreserve,
6606 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUPreserve,
6607 IDirect3DDeviceImpl_7_BeginScene_FPUPreserve,
6608 IDirect3DDeviceImpl_7_EndScene_FPUPreserve,
6609 IDirect3DDeviceImpl_7_GetDirect3D,
6610 IDirect3DDeviceImpl_7_SetRenderTarget_FPUPreserve,
6611 IDirect3DDeviceImpl_7_GetRenderTarget,
6612 IDirect3DDeviceImpl_7_Clear_FPUPreserve,
6613 IDirect3DDeviceImpl_7_SetTransform_FPUPreserve,
6614 IDirect3DDeviceImpl_7_GetTransform_FPUPreserve,
6615 IDirect3DDeviceImpl_7_SetViewport_FPUPreserve,
6616 IDirect3DDeviceImpl_7_MultiplyTransform_FPUPreserve,
6617 IDirect3DDeviceImpl_7_GetViewport_FPUPreserve,
6618 IDirect3DDeviceImpl_7_SetMaterial_FPUPreserve,
6619 IDirect3DDeviceImpl_7_GetMaterial_FPUPreserve,
6620 IDirect3DDeviceImpl_7_SetLight_FPUPreserve,
6621 IDirect3DDeviceImpl_7_GetLight_FPUPreserve,
6622 IDirect3DDeviceImpl_7_SetRenderState_FPUPreserve,
6623 IDirect3DDeviceImpl_7_GetRenderState_FPUPreserve,
6624 IDirect3DDeviceImpl_7_BeginStateBlock_FPUPreserve,
6625 IDirect3DDeviceImpl_7_EndStateBlock_FPUPreserve,
6626 IDirect3DDeviceImpl_7_PreLoad_FPUPreserve,
6627 IDirect3DDeviceImpl_7_DrawPrimitive_FPUPreserve,
6628 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUPreserve,
6629 IDirect3DDeviceImpl_7_SetClipStatus,
6630 IDirect3DDeviceImpl_7_GetClipStatus,
6631 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUPreserve,
6632 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUPreserve,
6633 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUPreserve,
6634 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUPreserve,
6635 IDirect3DDeviceImpl_7_ComputeSphereVisibility,
6636 IDirect3DDeviceImpl_7_GetTexture_FPUPreserve,
6637 IDirect3DDeviceImpl_7_SetTexture_FPUPreserve,
6638 IDirect3DDeviceImpl_7_GetTextureStageState_FPUPreserve,
6639 IDirect3DDeviceImpl_7_SetTextureStageState_FPUPreserve,
6640 IDirect3DDeviceImpl_7_ValidateDevice_FPUPreserve,
6641 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUPreserve,
6642 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUPreserve,
6643 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUPreserve,
6644 IDirect3DDeviceImpl_7_CreateStateBlock_FPUPreserve,
6645 IDirect3DDeviceImpl_7_Load_FPUPreserve,
6646 IDirect3DDeviceImpl_7_LightEnable_FPUPreserve,
6647 IDirect3DDeviceImpl_7_GetLightEnable_FPUPreserve,
6648 IDirect3DDeviceImpl_7_SetClipPlane_FPUPreserve,
6649 IDirect3DDeviceImpl_7_GetClipPlane_FPUPreserve,
6650 IDirect3DDeviceImpl_7_GetInfo
6653 const IDirect3DDevice3Vtbl IDirect3DDevice3_Vtbl =
6655 /*** IUnknown Methods ***/
6656 Thunk_IDirect3DDeviceImpl_3_QueryInterface,
6657 Thunk_IDirect3DDeviceImpl_3_AddRef,
6658 Thunk_IDirect3DDeviceImpl_3_Release,
6659 /*** IDirect3DDevice3 ***/
6660 IDirect3DDeviceImpl_3_GetCaps,
6661 IDirect3DDeviceImpl_3_GetStats,
6662 IDirect3DDeviceImpl_3_AddViewport,
6663 IDirect3DDeviceImpl_3_DeleteViewport,
6664 IDirect3DDeviceImpl_3_NextViewport,
6665 Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats,
6666 Thunk_IDirect3DDeviceImpl_3_BeginScene,
6667 Thunk_IDirect3DDeviceImpl_3_EndScene,
6668 Thunk_IDirect3DDeviceImpl_3_GetDirect3D,
6669 IDirect3DDeviceImpl_3_SetCurrentViewport,
6670 IDirect3DDeviceImpl_3_GetCurrentViewport,
6671 Thunk_IDirect3DDeviceImpl_3_SetRenderTarget,
6672 Thunk_IDirect3DDeviceImpl_3_GetRenderTarget,
6673 IDirect3DDeviceImpl_3_Begin,
6674 IDirect3DDeviceImpl_3_BeginIndexed,
6675 IDirect3DDeviceImpl_3_Vertex,
6676 IDirect3DDeviceImpl_3_Index,
6677 IDirect3DDeviceImpl_3_End,
6678 IDirect3DDeviceImpl_3_GetRenderState,
6679 IDirect3DDeviceImpl_3_SetRenderState,
6680 IDirect3DDeviceImpl_3_GetLightState,
6681 IDirect3DDeviceImpl_3_SetLightState,
6682 Thunk_IDirect3DDeviceImpl_3_SetTransform,
6683 Thunk_IDirect3DDeviceImpl_3_GetTransform,
6684 Thunk_IDirect3DDeviceImpl_3_MultiplyTransform,
6685 Thunk_IDirect3DDeviceImpl_3_DrawPrimitive,
6686 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive,
6687 Thunk_IDirect3DDeviceImpl_3_SetClipStatus,
6688 Thunk_IDirect3DDeviceImpl_3_GetClipStatus,
6689 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided,
6690 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided,
6691 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB,
6692 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB,
6693 Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility,
6694 Thunk_IDirect3DDeviceImpl_3_GetTexture,
6695 IDirect3DDeviceImpl_3_SetTexture,
6696 Thunk_IDirect3DDeviceImpl_3_GetTextureStageState,
6697 Thunk_IDirect3DDeviceImpl_3_SetTextureStageState,
6698 Thunk_IDirect3DDeviceImpl_3_ValidateDevice
6701 const IDirect3DDevice2Vtbl IDirect3DDevice2_Vtbl =
6703 /*** IUnknown Methods ***/
6704 Thunk_IDirect3DDeviceImpl_2_QueryInterface,
6705 Thunk_IDirect3DDeviceImpl_2_AddRef,
6706 Thunk_IDirect3DDeviceImpl_2_Release,
6707 /*** IDirect3DDevice2 ***/
6708 Thunk_IDirect3DDeviceImpl_2_GetCaps,
6709 IDirect3DDeviceImpl_2_SwapTextureHandles,
6710 Thunk_IDirect3DDeviceImpl_2_GetStats,
6711 Thunk_IDirect3DDeviceImpl_2_AddViewport,
6712 Thunk_IDirect3DDeviceImpl_2_DeleteViewport,
6713 Thunk_IDirect3DDeviceImpl_2_NextViewport,
6714 IDirect3DDeviceImpl_2_EnumTextureFormats,
6715 Thunk_IDirect3DDeviceImpl_2_BeginScene,
6716 Thunk_IDirect3DDeviceImpl_2_EndScene,
6717 Thunk_IDirect3DDeviceImpl_2_GetDirect3D,
6718 Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport,
6719 Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport,
6720 Thunk_IDirect3DDeviceImpl_2_SetRenderTarget,
6721 Thunk_IDirect3DDeviceImpl_2_GetRenderTarget,
6722 Thunk_IDirect3DDeviceImpl_2_Begin,
6723 Thunk_IDirect3DDeviceImpl_2_BeginIndexed,
6724 Thunk_IDirect3DDeviceImpl_2_Vertex,
6725 Thunk_IDirect3DDeviceImpl_2_Index,
6726 Thunk_IDirect3DDeviceImpl_2_End,
6727 Thunk_IDirect3DDeviceImpl_2_GetRenderState,
6728 Thunk_IDirect3DDeviceImpl_2_SetRenderState,
6729 Thunk_IDirect3DDeviceImpl_2_GetLightState,
6730 Thunk_IDirect3DDeviceImpl_2_SetLightState,
6731 Thunk_IDirect3DDeviceImpl_2_SetTransform,
6732 Thunk_IDirect3DDeviceImpl_2_GetTransform,
6733 Thunk_IDirect3DDeviceImpl_2_MultiplyTransform,
6734 Thunk_IDirect3DDeviceImpl_2_DrawPrimitive,
6735 Thunk_IDirect3DDeviceImpl_2_DrawIndexedPrimitive,
6736 Thunk_IDirect3DDeviceImpl_2_SetClipStatus,
6737 Thunk_IDirect3DDeviceImpl_2_GetClipStatus
6740 const IDirect3DDeviceVtbl IDirect3DDevice1_Vtbl =
6742 /*** IUnknown Methods ***/
6743 Thunk_IDirect3DDeviceImpl_1_QueryInterface,
6744 Thunk_IDirect3DDeviceImpl_1_AddRef,
6745 Thunk_IDirect3DDeviceImpl_1_Release,
6746 /*** IDirect3DDevice1 ***/
6747 IDirect3DDeviceImpl_1_Initialize,
6748 Thunk_IDirect3DDeviceImpl_1_GetCaps,
6749 Thunk_IDirect3DDeviceImpl_1_SwapTextureHandles,
6750 IDirect3DDeviceImpl_1_CreateExecuteBuffer,
6751 Thunk_IDirect3DDeviceImpl_1_GetStats,
6752 IDirect3DDeviceImpl_1_Execute,
6753 Thunk_IDirect3DDeviceImpl_1_AddViewport,
6754 Thunk_IDirect3DDeviceImpl_1_DeleteViewport,
6755 Thunk_IDirect3DDeviceImpl_1_NextViewport,
6756 IDirect3DDeviceImpl_1_Pick,
6757 IDirect3DDeviceImpl_1_GetPickRecords,
6758 Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats,
6759 IDirect3DDeviceImpl_1_CreateMatrix,
6760 IDirect3DDeviceImpl_1_SetMatrix,
6761 IDirect3DDeviceImpl_1_GetMatrix,
6762 IDirect3DDeviceImpl_1_DeleteMatrix,
6763 Thunk_IDirect3DDeviceImpl_1_BeginScene,
6764 Thunk_IDirect3DDeviceImpl_1_EndScene,
6765 Thunk_IDirect3DDeviceImpl_1_GetDirect3D
6768 /*****************************************************************************
6769 * IDirect3DDeviceImpl_CreateHandle
6771 * Not called from the VTable
6773 * Some older interface versions operate with handles, which are basically
6774 * DWORDs which identify an interface, for example
6775 * IDirect3DDevice::SetRenderState with DIRECT3DRENDERSTATE_TEXTUREHANDLE
6777 * Those handle could be just casts to the interface pointers or vice versa,
6778 * but that is not 64 bit safe and would mean blindly derefering a DWORD
6779 * passed by the app. Instead there is a dynamic array in the device which
6780 * keeps a DWORD to pointer information and a type for the handle.
6782 * Basically this array only grows, when a handle is freed its pointer is
6783 * just set to NULL. There will be much more reads from the array than
6784 * insertion operations, so a dynamic array is fine.
6786 * Params:
6787 * This: D3DDevice implementation for which this handle should be created
6789 * Returns:
6790 * A free handle on success
6791 * 0 on failure
6793 *****************************************************************************/
6794 DWORD
6795 IDirect3DDeviceImpl_CreateHandle(IDirect3DDeviceImpl *This)
6797 DWORD i;
6798 struct HandleEntry *oldHandles = This->Handles;
6800 TRACE("(%p)\n", This);
6802 for(i = 0; i < This->numHandles; i++)
6804 if(This->Handles[i].ptr == NULL &&
6805 This->Handles[i].type == DDrawHandle_Unknown)
6807 TRACE("Reusing freed handle %d\n", i + 1);
6808 return i + 1;
6812 TRACE("Growing the handle array\n");
6814 This->numHandles++;
6815 This->Handles = HeapAlloc(GetProcessHeap(), 0, sizeof(struct HandleEntry) * This->numHandles);
6816 if(!This->Handles)
6818 ERR("Out of memory\n");
6819 This->Handles = oldHandles;
6820 This->numHandles--;
6821 return 0;
6823 if(oldHandles)
6825 memcpy(This->Handles, oldHandles, (This->numHandles - 1) * sizeof(struct HandleEntry));
6826 HeapFree(GetProcessHeap(), 0, oldHandles);
6829 TRACE("Returning %d\n", This->numHandles);
6830 return This->numHandles;
6833 /*****************************************************************************
6834 * IDirect3DDeviceImpl_UpdateDepthStencil
6836 * Checks the current render target for attached depth stencils and sets the
6837 * WineD3D depth stencil accordingly.
6839 * Returns:
6840 * The depth stencil state to set if creating the device
6842 *****************************************************************************/
6843 WINED3DZBUFFERTYPE
6844 IDirect3DDeviceImpl_UpdateDepthStencil(IDirect3DDeviceImpl *This)
6846 IDirectDrawSurface7 *depthStencil = NULL;
6847 IDirectDrawSurfaceImpl *dsi;
6848 static DDSCAPS2 depthcaps = { DDSCAPS_ZBUFFER, 0, 0, 0 };
6850 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7 *)This->target, &depthcaps, &depthStencil);
6851 if(!depthStencil)
6853 TRACE("Setting wined3d depth stencil to NULL\n");
6854 IWineD3DDevice_SetDepthStencilSurface(This->wineD3DDevice,
6855 NULL);
6856 return WINED3DZB_FALSE;
6859 dsi = (IDirectDrawSurfaceImpl *)depthStencil;
6860 TRACE("Setting wined3d depth stencil to %p (wined3d %p)\n", dsi, dsi->WineD3DSurface);
6861 IWineD3DDevice_SetDepthStencilSurface(This->wineD3DDevice,
6862 dsi->WineD3DSurface);
6864 IDirectDrawSurface7_Release(depthStencil);
6865 return WINED3DZB_TRUE;