push 52d6b63ba2f2d4f9b02b6b922d27bff05a60596f
[wine/hacks.git] / dlls / ddraw / device.c
blob1883a5daf276f8df1be36bf08c69fcca78ffc97a
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 /* This->target is the offscreen target.
353 * This->ddraw->d3d_target is the target used by DDraw
355 TRACE("(%p) Release: Using %p as front buffer, %p as back buffer\n", This, This->ddraw->d3d_target, NULL);
356 IWineD3DDevice_SetFrontBackBuffers(This->wineD3DDevice,
357 This->ddraw->d3d_target->WineD3DSurface,
358 NULL);
361 /* Release the WineD3DDevice. This won't destroy it */
362 if(IWineD3DDevice_Release(This->wineD3DDevice) <= 0)
364 ERR(" (%p) The wineD3D device %p was destroyed unexpectedly. Prepare for trouble\n", This, This->wineD3DDevice);
367 /* The texture handles should be unset by now, but there might be some bits
368 * missing in our reference counting(needs test). Do a sanity check
370 for(i = 0; i < This->numHandles; i++)
372 if(This->Handles[i].ptr)
374 switch(This->Handles[i].type)
376 case DDrawHandle_Texture:
378 IDirectDrawSurfaceImpl *surf = This->Handles[i].ptr;
379 FIXME("Texture Handle %d not unset properly\n", i + 1);
380 surf->Handle = 0;
382 break;
384 case DDrawHandle_Material:
386 IDirect3DMaterialImpl *mat = This->Handles[i].ptr;
387 FIXME("Material handle %d not unset properly\n", i + 1);
388 mat->Handle = 0;
390 break;
392 case DDrawHandle_Matrix:
394 /* No fixme here because this might happen because of sloppy apps */
395 WARN("Leftover matrix handle %d, deleting\n", i + 1);
396 IDirect3DDevice_DeleteMatrix((IDirect3DDevice *)&This->IDirect3DDevice_vtbl, i + 1);
398 break;
400 case DDrawHandle_StateBlock:
402 /* No fixme here because this might happen because of sloppy apps */
403 WARN("Leftover stateblock handle %d, deleting\n", i + 1);
404 IDirect3DDevice7_DeleteStateBlock((IDirect3DDevice7 *)This, i + 1);
406 break;
408 default:
409 FIXME("Unknown handle %d not unset properly\n", i + 1);
414 HeapFree(GetProcessHeap(), 0, This->Handles);
416 TRACE("Releasing target %p %p\n", This->target, This->ddraw->d3d_target);
417 /* Release the render target and the WineD3D render target
418 * (See IDirect3D7::CreateDevice for more comments on this)
420 IDirectDrawSurface7_Release((IDirectDrawSurface7 *)This->target);
421 IDirectDrawSurface7_Release((IDirectDrawSurface7 *)This->ddraw->d3d_target);
422 TRACE("Target release done\n");
424 This->ddraw->d3ddevice = NULL;
426 /* Now free the structure */
427 HeapFree(GetProcessHeap(), 0, This);
428 LeaveCriticalSection(&ddraw_cs);
431 TRACE("Done\n");
432 return ref;
435 static ULONG WINAPI
436 Thunk_IDirect3DDeviceImpl_3_Release(IDirect3DDevice3 *iface)
438 IDirect3DDeviceImpl *This = device_from_device3(iface);
439 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
440 return IDirect3DDevice7_Release((IDirect3DDevice7 *)This);
443 static ULONG WINAPI
444 Thunk_IDirect3DDeviceImpl_2_Release(IDirect3DDevice2 *iface)
446 IDirect3DDeviceImpl *This = device_from_device2(iface);
447 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
448 return IDirect3DDevice7_Release((IDirect3DDevice7 *)This);
451 static ULONG WINAPI
452 Thunk_IDirect3DDeviceImpl_1_Release(IDirect3DDevice *iface)
454 IDirect3DDeviceImpl *This = device_from_device1(iface);
455 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
456 return IDirect3DDevice7_Release((IDirect3DDevice7 *)This);
459 /*****************************************************************************
460 * IDirect3DDevice Methods
461 *****************************************************************************/
463 /*****************************************************************************
464 * IDirect3DDevice::Initialize
466 * Initializes a Direct3DDevice. This implementation is a no-op, as all
467 * initialization is done at create time.
469 * Exists in Version 1
471 * Parameters:
472 * No idea what they mean, as the MSDN page is gone
474 * Returns: DD_OK
476 *****************************************************************************/
477 static HRESULT WINAPI
478 IDirect3DDeviceImpl_1_Initialize(IDirect3DDevice *iface,
479 IDirect3D *Direct3D, GUID *guid,
480 D3DDEVICEDESC *Desc)
482 IDirect3DDeviceImpl *This = device_from_device1(iface);
484 /* It shouldn't be crucial, but print a FIXME, I'm interested if
485 * any game calls it and when
487 FIXME("(%p)->(%p,%p,%p): No-op!\n", This, Direct3D, guid, Desc);
489 return D3D_OK;
492 /*****************************************************************************
493 * IDirect3DDevice7::GetCaps
495 * Retrieves the device's capabilities
497 * This implementation is used for Version 7 only, the older versions have
498 * their own implementation.
500 * Parameters:
501 * Desc: Pointer to a D3DDEVICEDESC7 structure to fill
503 * Returns:
504 * D3D_OK on success
505 * D3DERR_* if a problem occurs. See WineD3D
507 *****************************************************************************/
508 static HRESULT
509 IDirect3DDeviceImpl_7_GetCaps(IDirect3DDevice7 *iface,
510 D3DDEVICEDESC7 *Desc)
512 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
513 D3DDEVICEDESC OldDesc;
514 TRACE("(%p)->(%p)\n", This, Desc);
516 /* Call the same function used by IDirect3D, this saves code */
517 return IDirect3DImpl_GetCaps(This->ddraw->wineD3D, &OldDesc, Desc);
520 static HRESULT WINAPI
521 IDirect3DDeviceImpl_7_GetCaps_FPUSetup(IDirect3DDevice7 *iface,
522 D3DDEVICEDESC7 *Desc)
524 return IDirect3DDeviceImpl_7_GetCaps(iface, Desc);
527 static HRESULT WINAPI
528 IDirect3DDeviceImpl_7_GetCaps_FPUPreserve(IDirect3DDevice7 *iface,
529 D3DDEVICEDESC7 *Desc)
531 HRESULT hr;
532 WORD old_fpucw;
534 old_fpucw = d3d_fpu_setup();
535 hr = IDirect3DDeviceImpl_7_GetCaps(iface, Desc);
536 set_fpu_control_word(old_fpucw);
538 return hr;
540 /*****************************************************************************
541 * IDirect3DDevice3::GetCaps
543 * Retrieves the capabilities of the hardware device and the emulation
544 * device. For Wine, hardware and emulation are the same (it's all HW).
546 * This implementation is used for Version 1, 2, and 3. Version 7 has its own
548 * Parameters:
549 * HWDesc: Structure to fill with the HW caps
550 * HelDesc: Structure to fill with the hardware emulation caps
552 * Returns:
553 * D3D_OK on success
554 * D3DERR_* if a problem occurs. See WineD3D
556 *****************************************************************************/
557 static HRESULT WINAPI
558 IDirect3DDeviceImpl_3_GetCaps(IDirect3DDevice3 *iface,
559 D3DDEVICEDESC *HWDesc,
560 D3DDEVICEDESC *HelDesc)
562 IDirect3DDeviceImpl *This = device_from_device3(iface);
563 D3DDEVICEDESC7 newDesc;
564 HRESULT hr;
565 TRACE("(%p)->(%p,%p)\n", iface, HWDesc, HelDesc);
567 hr = IDirect3DImpl_GetCaps(This->ddraw->wineD3D, HWDesc, &newDesc);
568 if(hr != D3D_OK) return hr;
570 *HelDesc = *HWDesc;
571 return D3D_OK;
574 static HRESULT WINAPI
575 Thunk_IDirect3DDeviceImpl_2_GetCaps(IDirect3DDevice2 *iface,
576 D3DDEVICEDESC *D3DHWDevDesc,
577 D3DDEVICEDESC *D3DHELDevDesc)
579 IDirect3DDeviceImpl *This = device_from_device2(iface);
580 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice3 interface.\n", This, D3DHWDevDesc, D3DHELDevDesc);
581 return IDirect3DDevice3_GetCaps((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, D3DHWDevDesc, D3DHELDevDesc);
584 static HRESULT WINAPI
585 Thunk_IDirect3DDeviceImpl_1_GetCaps(IDirect3DDevice *iface,
586 D3DDEVICEDESC *D3DHWDevDesc,
587 D3DDEVICEDESC *D3DHELDevDesc)
589 IDirect3DDeviceImpl *This = device_from_device1(iface);
590 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice3 interface.\n", This, D3DHWDevDesc, D3DHELDevDesc);
591 return IDirect3DDevice3_GetCaps((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, D3DHWDevDesc, D3DHELDevDesc);
594 /*****************************************************************************
595 * IDirect3DDevice2::SwapTextureHandles
597 * Swaps the texture handles of 2 Texture interfaces. Version 1 and 2
599 * Parameters:
600 * Tex1, Tex2: The 2 Textures to swap
602 * Returns:
603 * D3D_OK
605 *****************************************************************************/
606 static HRESULT WINAPI
607 IDirect3DDeviceImpl_2_SwapTextureHandles(IDirect3DDevice2 *iface,
608 IDirect3DTexture2 *Tex1,
609 IDirect3DTexture2 *Tex2)
611 IDirect3DDeviceImpl *This = device_from_device2(iface);
612 DWORD swap;
613 IDirectDrawSurfaceImpl *surf1 = surface_from_texture2(Tex1);
614 IDirectDrawSurfaceImpl *surf2 = surface_from_texture2(Tex2);
615 TRACE("(%p)->(%p,%p)\n", This, surf1, surf2);
617 EnterCriticalSection(&ddraw_cs);
618 This->Handles[surf1->Handle - 1].ptr = surf2;
619 This->Handles[surf2->Handle - 1].ptr = surf1;
621 swap = surf2->Handle;
622 surf2->Handle = surf1->Handle;
623 surf1->Handle = swap;
624 LeaveCriticalSection(&ddraw_cs);
626 return D3D_OK;
629 static HRESULT WINAPI
630 Thunk_IDirect3DDeviceImpl_1_SwapTextureHandles(IDirect3DDevice *iface,
631 IDirect3DTexture *D3DTex1,
632 IDirect3DTexture *D3DTex2)
634 IDirect3DDeviceImpl *This = device_from_device1(iface);
635 IDirectDrawSurfaceImpl *surf1 = surface_from_texture1(D3DTex1);
636 IDirectDrawSurfaceImpl *surf2 = surface_from_texture1(D3DTex2);
637 IDirect3DTexture2 *t1 = surf1 ? (IDirect3DTexture2 *)&surf1->IDirect3DTexture2_vtbl : NULL;
638 IDirect3DTexture2 *t2 = surf2 ? (IDirect3DTexture2 *)&surf2->IDirect3DTexture2_vtbl : NULL;
639 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice2 interface.\n", This, surf1, surf2);
640 return IDirect3DDevice2_SwapTextureHandles((IDirect3DDevice2 *)&This->IDirect3DDevice2_vtbl, t1, t2);
643 /*****************************************************************************
644 * IDirect3DDevice3::GetStats
646 * This method seems to retrieve some stats from the device.
647 * The MSDN documentation doesn't exist any more, but the D3DSTATS
648 * structure suggests that the amount of drawn primitives and processed
649 * vertices is returned.
651 * Exists in Version 1, 2 and 3
653 * Parameters:
654 * Stats: Pointer to a D3DSTATS structure to be filled
656 * Returns:
657 * D3D_OK on success
658 * DDERR_INVALIDPARAMS if Stats == NULL
660 *****************************************************************************/
661 static HRESULT WINAPI
662 IDirect3DDeviceImpl_3_GetStats(IDirect3DDevice3 *iface,
663 D3DSTATS *Stats)
665 IDirect3DDeviceImpl *This = device_from_device3(iface);
666 FIXME("(%p)->(%p): Stub!\n", This, Stats);
668 if(!Stats)
669 return DDERR_INVALIDPARAMS;
671 /* Fill the Stats with 0 */
672 Stats->dwTrianglesDrawn = 0;
673 Stats->dwLinesDrawn = 0;
674 Stats->dwPointsDrawn = 0;
675 Stats->dwSpansDrawn = 0;
676 Stats->dwVerticesProcessed = 0;
678 return D3D_OK;
681 static HRESULT WINAPI
682 Thunk_IDirect3DDeviceImpl_2_GetStats(IDirect3DDevice2 *iface,
683 D3DSTATS *Stats)
685 IDirect3DDeviceImpl *This = device_from_device2(iface);
686 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, Stats);
687 return IDirect3DDevice3_GetStats((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, Stats);
690 static HRESULT WINAPI
691 Thunk_IDirect3DDeviceImpl_1_GetStats(IDirect3DDevice *iface,
692 D3DSTATS *Stats)
694 IDirect3DDeviceImpl *This = device_from_device1(iface);
695 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, Stats);
696 return IDirect3DDevice3_GetStats((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, Stats);
699 /*****************************************************************************
700 * IDirect3DDevice::CreateExecuteBuffer
702 * Creates an IDirect3DExecuteBuffer, used for rendering with a
703 * Direct3DDevice.
705 * Version 1 only.
707 * Params:
708 * Desc: Buffer description
709 * ExecuteBuffer: Address to return the Interface pointer at
710 * UnkOuter: Must be NULL. Basically for aggregation, which ddraw doesn't
711 * support
713 * Returns:
714 * CLASS_E_NOAGGREGATION if UnkOuter != NULL
715 * DDERR_OUTOFMEMORY if we ran out of memory
716 * D3D_OK on success
718 *****************************************************************************/
719 static HRESULT WINAPI
720 IDirect3DDeviceImpl_1_CreateExecuteBuffer(IDirect3DDevice *iface,
721 D3DEXECUTEBUFFERDESC *Desc,
722 IDirect3DExecuteBuffer **ExecuteBuffer,
723 IUnknown *UnkOuter)
725 IDirect3DDeviceImpl *This = device_from_device1(iface);
726 IDirect3DExecuteBufferImpl* object;
727 TRACE("(%p)->(%p,%p,%p)!\n", This, Desc, ExecuteBuffer, UnkOuter);
729 if(UnkOuter)
730 return CLASS_E_NOAGGREGATION;
732 /* Allocate the new Execute Buffer */
733 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DExecuteBufferImpl));
734 if(!object)
736 ERR("Out of memory when allocating a IDirect3DExecuteBufferImpl structure\n");
737 return DDERR_OUTOFMEMORY;
740 object->lpVtbl = &IDirect3DExecuteBuffer_Vtbl;
741 object->ref = 1;
742 object->d3ddev = This;
744 /* Initializes memory */
745 memcpy(&object->desc, Desc, Desc->dwSize);
747 /* No buffer given */
748 if ((object->desc.dwFlags & D3DDEB_LPDATA) == 0)
749 object->desc.lpData = NULL;
751 /* No buffer size given */
752 if ((object->desc.dwFlags & D3DDEB_BUFSIZE) == 0)
753 object->desc.dwBufferSize = 0;
755 /* Create buffer if asked */
756 if ((object->desc.lpData == NULL) && (object->desc.dwBufferSize > 0))
758 object->need_free = TRUE;
759 object->desc.lpData = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,object->desc.dwBufferSize);
760 if(!object->desc.lpData)
762 ERR("Out of memory when allocating the execute buffer data\n");
763 HeapFree(GetProcessHeap(), 0, object);
764 return DDERR_OUTOFMEMORY;
767 else
769 object->need_free = FALSE;
772 /* No vertices for the moment */
773 object->vertex_data = NULL;
775 object->desc.dwFlags |= D3DDEB_LPDATA;
777 object->indices = NULL;
778 object->nb_indices = 0;
780 *ExecuteBuffer = (IDirect3DExecuteBuffer *)object;
782 TRACE(" Returning IDirect3DExecuteBuffer at %p, implementation is at %p\n", *ExecuteBuffer, object);
784 return D3D_OK;
787 /*****************************************************************************
788 * IDirect3DDevice::Execute
790 * Executes all the stuff in an execute buffer.
792 * Params:
793 * ExecuteBuffer: The buffer to execute
794 * Viewport: The viewport used for rendering
795 * Flags: Some flags
797 * Returns:
798 * DDERR_INVALIDPARAMS if ExecuteBuffer == NULL
799 * D3D_OK on success
801 *****************************************************************************/
802 static HRESULT WINAPI
803 IDirect3DDeviceImpl_1_Execute(IDirect3DDevice *iface,
804 IDirect3DExecuteBuffer *ExecuteBuffer,
805 IDirect3DViewport *Viewport,
806 DWORD Flags)
808 IDirect3DDeviceImpl *This = device_from_device1(iface);
809 IDirect3DExecuteBufferImpl *Direct3DExecuteBufferImpl = (IDirect3DExecuteBufferImpl *)ExecuteBuffer;
810 IDirect3DViewportImpl *Direct3DViewportImpl = (IDirect3DViewportImpl *)Viewport;
812 TRACE("(%p)->(%p,%p,%08x)\n", This, Direct3DExecuteBufferImpl, Direct3DViewportImpl, Flags);
814 if(!Direct3DExecuteBufferImpl)
815 return DDERR_INVALIDPARAMS;
817 /* Execute... */
818 EnterCriticalSection(&ddraw_cs);
819 IDirect3DExecuteBufferImpl_Execute(Direct3DExecuteBufferImpl, This, Direct3DViewportImpl);
820 LeaveCriticalSection(&ddraw_cs);
822 return D3D_OK;
825 /*****************************************************************************
826 * IDirect3DDevice3::AddViewport
828 * Add a Direct3DViewport to the device's viewport list. These viewports
829 * are wrapped to IDirect3DDevice7 viewports in viewport.c
831 * Exists in Version 1, 2 and 3. Note that IDirect3DViewport 1, 2 and 3
832 * are the same interfaces.
834 * Params:
835 * Viewport: The viewport to add
837 * Returns:
838 * DDERR_INVALIDPARAMS if Viewport == NULL
839 * D3D_OK on success
841 *****************************************************************************/
842 static HRESULT WINAPI
843 IDirect3DDeviceImpl_3_AddViewport(IDirect3DDevice3 *iface,
844 IDirect3DViewport3 *Viewport)
846 IDirect3DDeviceImpl *This = device_from_device3(iface);
847 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Viewport;
849 TRACE("(%p)->(%p)\n", This, vp);
851 /* Sanity check */
852 if(!vp)
853 return DDERR_INVALIDPARAMS;
855 EnterCriticalSection(&ddraw_cs);
856 vp->next = This->viewport_list;
857 This->viewport_list = vp;
858 vp->active_device = This; /* Viewport must be usable for Clear() after AddViewport,
859 so set active_device here. */
860 LeaveCriticalSection(&ddraw_cs);
862 return D3D_OK;
865 static HRESULT WINAPI
866 Thunk_IDirect3DDeviceImpl_2_AddViewport(IDirect3DDevice2 *iface,
867 IDirect3DViewport2 *Direct3DViewport2)
869 IDirect3DDeviceImpl *This = device_from_device2(iface);
870 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Direct3DViewport2;
871 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
872 return IDirect3DDevice3_AddViewport((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, (IDirect3DViewport3 *)vp);
875 static HRESULT WINAPI
876 Thunk_IDirect3DDeviceImpl_1_AddViewport(IDirect3DDevice *iface,
877 IDirect3DViewport *Direct3DViewport)
879 IDirect3DDeviceImpl *This = device_from_device1(iface);
880 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Direct3DViewport;
881 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
882 return IDirect3DDevice3_AddViewport((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, (IDirect3DViewport3 *)vp);
885 /*****************************************************************************
886 * IDirect3DDevice3::DeleteViewport
888 * Deletes a Direct3DViewport from the device's viewport list.
890 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
891 * are equal.
893 * Params:
894 * Viewport: The viewport to delete
896 * Returns:
897 * D3D_OK on success
898 * DDERR_INVALIDPARAMS if the viewport wasn't found in the list
900 *****************************************************************************/
901 static HRESULT WINAPI
902 IDirect3DDeviceImpl_3_DeleteViewport(IDirect3DDevice3 *iface,
903 IDirect3DViewport3 *Viewport)
905 IDirect3DDeviceImpl *This = device_from_device3(iface);
906 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *) Viewport;
907 IDirect3DViewportImpl *cur_viewport, *prev_viewport = NULL;
909 TRACE("(%p)->(%p)\n", This, vp);
911 EnterCriticalSection(&ddraw_cs);
912 cur_viewport = This->viewport_list;
913 while (cur_viewport != NULL)
915 if (cur_viewport == vp)
917 if (prev_viewport == NULL) This->viewport_list = cur_viewport->next;
918 else prev_viewport->next = cur_viewport->next;
919 /* TODO : add desactivate of the viewport and all associated lights... */
920 LeaveCriticalSection(&ddraw_cs);
921 return D3D_OK;
923 prev_viewport = cur_viewport;
924 cur_viewport = cur_viewport->next;
927 LeaveCriticalSection(&ddraw_cs);
928 return DDERR_INVALIDPARAMS;
931 static HRESULT WINAPI
932 Thunk_IDirect3DDeviceImpl_2_DeleteViewport(IDirect3DDevice2 *iface,
933 IDirect3DViewport2 *Direct3DViewport2)
935 IDirect3DDeviceImpl *This = device_from_device2(iface);
936 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Direct3DViewport2;
937 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
938 return IDirect3DDevice3_DeleteViewport((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, (IDirect3DViewport3 *)vp);
941 static HRESULT WINAPI
942 Thunk_IDirect3DDeviceImpl_1_DeleteViewport(IDirect3DDevice *iface,
943 IDirect3DViewport *Direct3DViewport)
945 IDirect3DDeviceImpl *This = device_from_device1(iface);
946 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Direct3DViewport;
947 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
948 return IDirect3DDevice3_DeleteViewport((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, (IDirect3DViewport3 *)vp);
951 /*****************************************************************************
952 * IDirect3DDevice3::NextViewport
954 * Returns a viewport from the viewport list, depending on the
955 * passed viewport and the flags.
957 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
958 * are equal.
960 * Params:
961 * Viewport: Viewport to use for beginning the search
962 * Flags: D3DNEXT_NEXT, D3DNEXT_HEAD or D3DNEXT_TAIL
964 * Returns:
965 * D3D_OK on success
966 * DDERR_INVALIDPARAMS if the flags were wrong, or Viewport was NULL
968 *****************************************************************************/
969 static HRESULT WINAPI
970 IDirect3DDeviceImpl_3_NextViewport(IDirect3DDevice3 *iface,
971 IDirect3DViewport3 *Viewport3,
972 IDirect3DViewport3 **lplpDirect3DViewport3,
973 DWORD Flags)
975 IDirect3DDeviceImpl *This = device_from_device3(iface);
976 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Viewport3;
977 IDirect3DViewportImpl *res = NULL;
979 TRACE("(%p)->(%p,%p,%08x)\n", This, vp, lplpDirect3DViewport3, Flags);
981 if(!vp)
983 *lplpDirect3DViewport3 = NULL;
984 return DDERR_INVALIDPARAMS;
988 EnterCriticalSection(&ddraw_cs);
989 switch (Flags)
991 case D3DNEXT_NEXT:
993 res = vp->next;
995 break;
996 case D3DNEXT_HEAD:
998 res = This->viewport_list;
1000 break;
1001 case D3DNEXT_TAIL:
1003 IDirect3DViewportImpl *cur_viewport = This->viewport_list;
1004 if (cur_viewport != NULL)
1006 while (cur_viewport->next != NULL) cur_viewport = cur_viewport->next;
1008 res = cur_viewport;
1010 break;
1011 default:
1012 *lplpDirect3DViewport3 = NULL;
1013 LeaveCriticalSection(&ddraw_cs);
1014 return DDERR_INVALIDPARAMS;
1017 *lplpDirect3DViewport3 = (IDirect3DViewport3 *)res;
1018 LeaveCriticalSection(&ddraw_cs);
1019 return D3D_OK;
1022 static HRESULT WINAPI
1023 Thunk_IDirect3DDeviceImpl_2_NextViewport(IDirect3DDevice2 *iface,
1024 IDirect3DViewport2 *Viewport2,
1025 IDirect3DViewport2 **lplpDirect3DViewport2,
1026 DWORD Flags)
1028 IDirect3DDeviceImpl *This = device_from_device2(iface);
1029 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Viewport2;
1030 IDirect3DViewport3 *res;
1031 HRESULT hr;
1032 TRACE_(ddraw_thunk)("(%p)->(%p,%p,%08x) thunking to IDirect3DDevice3 interface.\n", This, vp, lplpDirect3DViewport2, Flags);
1033 hr = IDirect3DDevice3_NextViewport((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl,
1034 (IDirect3DViewport3 *)vp, &res, Flags);
1035 *lplpDirect3DViewport2 = (IDirect3DViewport2 *)res;
1036 return hr;
1039 static HRESULT WINAPI
1040 Thunk_IDirect3DDeviceImpl_1_NextViewport(IDirect3DDevice *iface,
1041 IDirect3DViewport *Viewport,
1042 IDirect3DViewport **lplpDirect3DViewport,
1043 DWORD Flags)
1045 IDirect3DDeviceImpl *This = device_from_device1(iface);
1046 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Viewport;
1047 IDirect3DViewport3 *res;
1048 HRESULT hr;
1049 TRACE_(ddraw_thunk)("(%p)->(%p,%p,%08x) thunking to IDirect3DDevice3 interface.\n", This, vp, lplpDirect3DViewport, Flags);
1050 hr = IDirect3DDevice3_NextViewport((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl,
1051 (IDirect3DViewport3 *)vp, &res, Flags);
1052 *lplpDirect3DViewport = (IDirect3DViewport *)res;
1053 return hr;
1056 /*****************************************************************************
1057 * IDirect3DDevice::Pick
1059 * Executes an execute buffer without performing rendering. Instead, a
1060 * list of primitives that intersect with (x1,y1) of the passed rectangle
1061 * is created. IDirect3DDevice::GetPickRecords can be used to retrieve
1062 * this list.
1064 * Version 1 only
1066 * Params:
1067 * ExecuteBuffer: Buffer to execute
1068 * Viewport: Viewport to use for execution
1069 * Flags: None are defined, according to the SDK
1070 * Rect: Specifies the coordinates to be picked. Only x1 and y2 are used,
1071 * x2 and y2 are ignored.
1073 * Returns:
1074 * D3D_OK because it's a stub
1076 *****************************************************************************/
1077 static HRESULT WINAPI
1078 IDirect3DDeviceImpl_1_Pick(IDirect3DDevice *iface,
1079 IDirect3DExecuteBuffer *ExecuteBuffer,
1080 IDirect3DViewport *Viewport,
1081 DWORD Flags,
1082 D3DRECT *Rect)
1084 IDirect3DDeviceImpl *This = device_from_device1(iface);
1085 IDirect3DExecuteBufferImpl *execbuf = (IDirect3DExecuteBufferImpl *)ExecuteBuffer;
1086 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Viewport;
1087 FIXME("(%p)->(%p,%p,%08x,%p): stub!\n", This, execbuf, vp, Flags, Rect);
1089 return D3D_OK;
1092 /*****************************************************************************
1093 * IDirect3DDevice::GetPickRecords
1095 * Retrieves the pick records generated by IDirect3DDevice::GetPickRecords
1097 * Version 1 only
1099 * Params:
1100 * Count: Pointer to a DWORD containing the numbers of pick records to
1101 * retrieve
1102 * D3DPickRec: Address to store the resulting D3DPICKRECORD array.
1104 * Returns:
1105 * D3D_OK, because it's a stub
1107 *****************************************************************************/
1108 static HRESULT WINAPI
1109 IDirect3DDeviceImpl_1_GetPickRecords(IDirect3DDevice *iface,
1110 DWORD *Count,
1111 D3DPICKRECORD *D3DPickRec)
1113 IDirect3DDeviceImpl *This = device_from_device1(iface);
1114 FIXME("(%p)->(%p,%p): stub!\n", This, Count, D3DPickRec);
1116 return D3D_OK;
1119 /*****************************************************************************
1120 * IDirect3DDevice7::EnumTextureformats
1122 * Enumerates the supported texture formats. It has a list of all possible
1123 * formats and calls IWineD3D::CheckDeviceFormat for each format to see if
1124 * WineD3D supports it. If so, then it is passed to the app.
1126 * This is for Version 7 and 3, older versions have a different
1127 * callback function and their own implementation
1129 * Params:
1130 * Callback: Callback to call for each enumerated format
1131 * Arg: Argument to pass to the callback
1133 * Returns:
1134 * D3D_OK on success
1135 * DDERR_INVALIDPARAMS if Callback == NULL
1137 *****************************************************************************/
1138 static HRESULT
1139 IDirect3DDeviceImpl_7_EnumTextureFormats(IDirect3DDevice7 *iface,
1140 LPD3DENUMPIXELFORMATSCALLBACK Callback,
1141 void *Arg)
1143 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
1144 HRESULT hr;
1145 WINED3DDISPLAYMODE mode;
1146 unsigned int i;
1148 WINED3DFORMAT FormatList[] = {
1149 /* 32 bit */
1150 WINED3DFMT_B8G8R8A8_UNORM,
1151 WINED3DFMT_B8G8R8X8_UNORM,
1152 /* 24 bit */
1153 WINED3DFMT_B8G8R8_UNORM,
1154 /* 16 Bit */
1155 WINED3DFMT_B5G5R5A1_UNORM,
1156 WINED3DFMT_B4G4R4A4_UNORM,
1157 WINED3DFMT_B5G6R5_UNORM,
1158 WINED3DFMT_B5G5R5X1_UNORM,
1159 /* 8 Bit */
1160 WINED3DFMT_B2G3R3_UNORM,
1161 WINED3DFMT_P8_UINT,
1162 /* FOURCC codes */
1163 WINED3DFMT_DXT1,
1164 WINED3DFMT_DXT3,
1165 WINED3DFMT_DXT5,
1168 WINED3DFORMAT BumpFormatList[] = {
1169 WINED3DFMT_R8G8_SNORM,
1170 WINED3DFMT_R5G5_SNORM_L6_UNORM,
1171 WINED3DFMT_R8G8_SNORM_L8X8_UNORM,
1172 WINED3DFMT_R8G8B8A8_SNORM,
1173 WINED3DFMT_R16G16_SNORM,
1174 WINED3DFMT_R10G11B11_SNORM,
1175 WINED3DFMT_R10G10B10_SNORM_A2_UNORM
1178 TRACE("(%p)->(%p,%p): Relay\n", This, Callback, Arg);
1180 if(!Callback)
1181 return DDERR_INVALIDPARAMS;
1183 EnterCriticalSection(&ddraw_cs);
1185 memset(&mode, 0, sizeof(mode));
1186 hr = IWineD3DDevice_GetDisplayMode(This->ddraw->wineD3DDevice,
1188 &mode);
1189 if(FAILED(hr)) {
1190 LeaveCriticalSection(&ddraw_cs);
1191 WARN("Cannot get the current adapter format\n");
1192 return hr;
1195 for(i = 0; i < sizeof(FormatList) / sizeof(WINED3DFORMAT); i++)
1197 hr = IWineD3D_CheckDeviceFormat(This->ddraw->wineD3D,
1198 WINED3DADAPTER_DEFAULT,
1199 WINED3DDEVTYPE_HAL,
1200 mode.Format,
1201 0 /* Usage */,
1202 WINED3DRTYPE_TEXTURE,
1203 FormatList[i],
1204 SURFACE_OPENGL);
1205 if(hr == D3D_OK)
1207 DDPIXELFORMAT pformat;
1209 memset(&pformat, 0, sizeof(pformat));
1210 pformat.dwSize = sizeof(pformat);
1211 PixelFormat_WineD3DtoDD(&pformat, FormatList[i]);
1213 TRACE("Enumerating WineD3DFormat %d\n", FormatList[i]);
1214 hr = Callback(&pformat, Arg);
1215 if(hr != DDENUMRET_OK)
1217 TRACE("Format enumeration cancelled by application\n");
1218 LeaveCriticalSection(&ddraw_cs);
1219 return D3D_OK;
1224 for(i = 0; i < sizeof(BumpFormatList) / sizeof(WINED3DFORMAT); i++)
1226 hr = IWineD3D_CheckDeviceFormat(This->ddraw->wineD3D,
1227 WINED3DADAPTER_DEFAULT,
1228 WINED3DDEVTYPE_HAL,
1229 mode.Format,
1230 WINED3DUSAGE_QUERY_LEGACYBUMPMAP,
1231 WINED3DRTYPE_TEXTURE,
1232 BumpFormatList[i],
1233 SURFACE_OPENGL);
1234 if(hr == D3D_OK)
1236 DDPIXELFORMAT pformat;
1238 memset(&pformat, 0, sizeof(pformat));
1239 pformat.dwSize = sizeof(pformat);
1240 PixelFormat_WineD3DtoDD(&pformat, BumpFormatList[i]);
1242 TRACE("Enumerating WineD3DFormat %d\n", BumpFormatList[i]);
1243 hr = Callback(&pformat, Arg);
1244 if(hr != DDENUMRET_OK)
1246 TRACE("Format enumeration cancelled by application\n");
1247 LeaveCriticalSection(&ddraw_cs);
1248 return D3D_OK;
1252 TRACE("End of enumeration\n");
1253 LeaveCriticalSection(&ddraw_cs);
1254 return D3D_OK;
1257 static HRESULT WINAPI
1258 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUSetup(IDirect3DDevice7 *iface,
1259 LPD3DENUMPIXELFORMATSCALLBACK Callback,
1260 void *Arg)
1262 return IDirect3DDeviceImpl_7_EnumTextureFormats(iface, Callback, Arg);
1265 static HRESULT WINAPI
1266 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUPreserve(IDirect3DDevice7 *iface,
1267 LPD3DENUMPIXELFORMATSCALLBACK Callback,
1268 void *Arg)
1270 HRESULT hr;
1271 WORD old_fpucw;
1273 old_fpucw = d3d_fpu_setup();
1274 hr = IDirect3DDeviceImpl_7_EnumTextureFormats(iface, Callback, Arg);
1275 set_fpu_control_word(old_fpucw);
1277 return hr;
1280 static HRESULT WINAPI
1281 Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats(IDirect3DDevice3 *iface,
1282 LPD3DENUMPIXELFORMATSCALLBACK Callback,
1283 void *Arg)
1285 IDirect3DDeviceImpl *This = device_from_device3(iface);
1286 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice7 interface.\n", This, Callback, Arg);
1287 return IDirect3DDevice7_EnumTextureFormats((IDirect3DDevice7 *)This, Callback, Arg);
1290 /*****************************************************************************
1291 * IDirect3DDevice2::EnumTextureformats
1293 * EnumTextureFormats for Version 1 and 2, see
1294 * IDirect3DDevice7::EnumTexureFormats for a more detailed description.
1296 * This version has a different callback and does not enumerate FourCC
1297 * formats
1299 *****************************************************************************/
1300 static HRESULT WINAPI
1301 IDirect3DDeviceImpl_2_EnumTextureFormats(IDirect3DDevice2 *iface,
1302 LPD3DENUMTEXTUREFORMATSCALLBACK Callback,
1303 void *Arg)
1305 IDirect3DDeviceImpl *This = device_from_device2(iface);
1306 HRESULT hr;
1307 unsigned int i;
1308 WINED3DDISPLAYMODE mode;
1310 WINED3DFORMAT FormatList[] = {
1311 /* 32 bit */
1312 WINED3DFMT_B8G8R8A8_UNORM,
1313 WINED3DFMT_B8G8R8X8_UNORM,
1314 /* 24 bit */
1315 WINED3DFMT_B8G8R8_UNORM,
1316 /* 16 Bit */
1317 WINED3DFMT_B5G5R5A1_UNORM,
1318 WINED3DFMT_B4G4R4A4_UNORM,
1319 WINED3DFMT_B5G6R5_UNORM,
1320 WINED3DFMT_B5G5R5X1_UNORM,
1321 /* 8 Bit */
1322 WINED3DFMT_B2G3R3_UNORM,
1323 WINED3DFMT_P8_UINT,
1324 /* FOURCC codes - Not in this version*/
1327 TRACE("(%p)->(%p,%p): Relay\n", This, Callback, Arg);
1329 if(!Callback)
1330 return DDERR_INVALIDPARAMS;
1332 EnterCriticalSection(&ddraw_cs);
1334 memset(&mode, 0, sizeof(mode));
1335 hr = IWineD3DDevice_GetDisplayMode(This->ddraw->wineD3DDevice,
1337 &mode);
1338 if(FAILED(hr)) {
1339 LeaveCriticalSection(&ddraw_cs);
1340 WARN("Cannot get the current adapter format\n");
1341 return hr;
1344 for(i = 0; i < sizeof(FormatList) / sizeof(WINED3DFORMAT); i++)
1346 hr = IWineD3D_CheckDeviceFormat(This->ddraw->wineD3D,
1347 0 /* Adapter */,
1348 WINED3DDEVTYPE_HAL,
1349 mode.Format,
1350 0 /* Usage */,
1351 WINED3DRTYPE_TEXTURE,
1352 FormatList[i],
1353 SURFACE_OPENGL);
1354 if(hr == D3D_OK)
1356 DDSURFACEDESC sdesc;
1358 memset(&sdesc, 0, sizeof(sdesc));
1359 sdesc.dwSize = sizeof(sdesc);
1360 sdesc.dwFlags = DDSD_PIXELFORMAT | DDSD_CAPS;
1361 sdesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1362 sdesc.ddpfPixelFormat.dwSize = sizeof(sdesc.ddpfPixelFormat);
1363 PixelFormat_WineD3DtoDD(&sdesc.ddpfPixelFormat, FormatList[i]);
1365 TRACE("Enumerating WineD3DFormat %d\n", FormatList[i]);
1366 hr = Callback(&sdesc, Arg);
1367 if(hr != DDENUMRET_OK)
1369 TRACE("Format enumeration cancelled by application\n");
1370 LeaveCriticalSection(&ddraw_cs);
1371 return D3D_OK;
1375 TRACE("End of enumeration\n");
1376 LeaveCriticalSection(&ddraw_cs);
1377 return D3D_OK;
1380 static HRESULT WINAPI
1381 Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats(IDirect3DDevice *iface,
1382 LPD3DENUMTEXTUREFORMATSCALLBACK Callback,
1383 void *Arg)
1385 IDirect3DDeviceImpl *This = device_from_device1(iface);
1386 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice2 interface.\n", This, Callback, Arg);
1387 return IDirect3DDevice2_EnumTextureFormats((IDirect3DDevice2 *)&This->IDirect3DDevice2_vtbl, Callback, Arg);
1390 /*****************************************************************************
1391 * IDirect3DDevice::CreateMatrix
1393 * Creates a matrix handle. A handle is created and memory for a D3DMATRIX is
1394 * allocated for the handle.
1396 * Version 1 only
1398 * Params
1399 * D3DMatHandle: Address to return the handle at
1401 * Returns:
1402 * D3D_OK on success
1403 * DDERR_INVALIDPARAMS if D3DMatHandle = NULL
1405 *****************************************************************************/
1406 static HRESULT WINAPI
1407 IDirect3DDeviceImpl_1_CreateMatrix(IDirect3DDevice *iface, D3DMATRIXHANDLE *D3DMatHandle)
1409 IDirect3DDeviceImpl *This = device_from_device1(iface);
1410 D3DMATRIX *Matrix;
1411 TRACE("(%p)->(%p)\n", This, D3DMatHandle);
1413 if(!D3DMatHandle)
1414 return DDERR_INVALIDPARAMS;
1416 Matrix = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(D3DMATRIX));
1417 if(!Matrix)
1419 ERR("Out of memory when allocating a D3DMATRIX\n");
1420 return DDERR_OUTOFMEMORY;
1423 EnterCriticalSection(&ddraw_cs);
1424 *D3DMatHandle = IDirect3DDeviceImpl_CreateHandle(This);
1425 if(!(*D3DMatHandle))
1427 ERR("Failed to create a matrix handle\n");
1428 HeapFree(GetProcessHeap(), 0, Matrix);
1429 LeaveCriticalSection(&ddraw_cs);
1430 return DDERR_OUTOFMEMORY;
1432 This->Handles[*D3DMatHandle - 1].ptr = Matrix;
1433 This->Handles[*D3DMatHandle - 1].type = DDrawHandle_Matrix;
1434 TRACE(" returning matrix handle %d\n", *D3DMatHandle);
1436 LeaveCriticalSection(&ddraw_cs);
1437 return D3D_OK;
1440 /*****************************************************************************
1441 * IDirect3DDevice::SetMatrix
1443 * Sets a matrix for a matrix handle. The matrix is copied into the memory
1444 * allocated for the handle
1446 * Version 1 only
1448 * Params:
1449 * D3DMatHandle: Handle to set the matrix to
1450 * D3DMatrix: Matrix to set
1452 * Returns:
1453 * D3D_OK on success
1454 * DDERR_INVALIDPARAMS if the handle of the matrix is invalid or the matrix
1455 * to set is NULL
1457 *****************************************************************************/
1458 static HRESULT WINAPI
1459 IDirect3DDeviceImpl_1_SetMatrix(IDirect3DDevice *iface,
1460 D3DMATRIXHANDLE D3DMatHandle,
1461 D3DMATRIX *D3DMatrix)
1463 IDirect3DDeviceImpl *This = device_from_device1(iface);
1464 TRACE("(%p)->(%08x,%p)\n", This, D3DMatHandle, D3DMatrix);
1466 if( (!D3DMatHandle) || (!D3DMatrix) )
1467 return DDERR_INVALIDPARAMS;
1469 EnterCriticalSection(&ddraw_cs);
1470 if(D3DMatHandle > This->numHandles)
1472 ERR("Handle %d out of range\n", D3DMatHandle);
1473 LeaveCriticalSection(&ddraw_cs);
1474 return DDERR_INVALIDPARAMS;
1476 else if(This->Handles[D3DMatHandle - 1].type != DDrawHandle_Matrix)
1478 ERR("Handle %d is not a matrix handle\n", D3DMatHandle);
1479 LeaveCriticalSection(&ddraw_cs);
1480 return DDERR_INVALIDPARAMS;
1483 if (TRACE_ON(d3d7))
1484 dump_D3DMATRIX(D3DMatrix);
1486 *((D3DMATRIX *) This->Handles[D3DMatHandle - 1].ptr) = *D3DMatrix;
1488 if(This->world == D3DMatHandle)
1490 IWineD3DDevice_SetTransform(This->wineD3DDevice,
1491 WINED3DTS_WORLDMATRIX(0),
1492 (WINED3DMATRIX *) D3DMatrix);
1494 if(This->view == D3DMatHandle)
1496 IWineD3DDevice_SetTransform(This->wineD3DDevice,
1497 WINED3DTS_VIEW,
1498 (WINED3DMATRIX *) D3DMatrix);
1500 if(This->proj == D3DMatHandle)
1502 IWineD3DDevice_SetTransform(This->wineD3DDevice,
1503 WINED3DTS_PROJECTION,
1504 (WINED3DMATRIX *) D3DMatrix);
1507 LeaveCriticalSection(&ddraw_cs);
1508 return D3D_OK;
1511 /*****************************************************************************
1512 * IDirect3DDevice::SetMatrix
1514 * Returns the content of a D3DMATRIX handle
1516 * Version 1 only
1518 * Params:
1519 * D3DMatHandle: Matrix handle to read the content from
1520 * D3DMatrix: Address to store the content at
1522 * Returns:
1523 * D3D_OK on success
1524 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid or D3DMatrix is NULL
1526 *****************************************************************************/
1527 static HRESULT WINAPI
1528 IDirect3DDeviceImpl_1_GetMatrix(IDirect3DDevice *iface,
1529 D3DMATRIXHANDLE D3DMatHandle,
1530 D3DMATRIX *D3DMatrix)
1532 IDirect3DDeviceImpl *This = device_from_device1(iface);
1533 TRACE("(%p)->(%08x,%p)\n", This, D3DMatHandle, D3DMatrix);
1535 if(!D3DMatrix)
1536 return DDERR_INVALIDPARAMS;
1537 if(!D3DMatHandle)
1538 return DDERR_INVALIDPARAMS;
1540 EnterCriticalSection(&ddraw_cs);
1541 if(D3DMatHandle > This->numHandles)
1543 ERR("Handle %d out of range\n", D3DMatHandle);
1544 LeaveCriticalSection(&ddraw_cs);
1545 return DDERR_INVALIDPARAMS;
1547 else if(This->Handles[D3DMatHandle - 1].type != DDrawHandle_Matrix)
1549 ERR("Handle %d is not a matrix handle\n", D3DMatHandle);
1550 LeaveCriticalSection(&ddraw_cs);
1551 return DDERR_INVALIDPARAMS;
1554 /* The handle is simply a pointer to a D3DMATRIX structure */
1555 *D3DMatrix = *((D3DMATRIX *) This->Handles[D3DMatHandle - 1].ptr);
1557 LeaveCriticalSection(&ddraw_cs);
1558 return D3D_OK;
1561 /*****************************************************************************
1562 * IDirect3DDevice::DeleteMatrix
1564 * Destroys a Matrix handle. Frees the memory and unsets the handle data
1566 * Version 1 only
1568 * Params:
1569 * D3DMatHandle: Handle to destroy
1571 * Returns:
1572 * D3D_OK on success
1573 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid
1575 *****************************************************************************/
1576 static HRESULT WINAPI
1577 IDirect3DDeviceImpl_1_DeleteMatrix(IDirect3DDevice *iface,
1578 D3DMATRIXHANDLE D3DMatHandle)
1580 IDirect3DDeviceImpl *This = device_from_device1(iface);
1581 TRACE("(%p)->(%08x)\n", This, D3DMatHandle);
1583 if(!D3DMatHandle)
1584 return DDERR_INVALIDPARAMS;
1586 EnterCriticalSection(&ddraw_cs);
1587 if(D3DMatHandle > This->numHandles)
1589 ERR("Handle %d out of range\n", D3DMatHandle);
1590 LeaveCriticalSection(&ddraw_cs);
1591 return DDERR_INVALIDPARAMS;
1593 else if(This->Handles[D3DMatHandle - 1].type != DDrawHandle_Matrix)
1595 ERR("Handle %d is not a matrix handle\n", D3DMatHandle);
1596 LeaveCriticalSection(&ddraw_cs);
1597 return DDERR_INVALIDPARAMS;
1600 HeapFree(GetProcessHeap(), 0, This->Handles[D3DMatHandle - 1].ptr);
1601 This->Handles[D3DMatHandle - 1].ptr = NULL;
1602 This->Handles[D3DMatHandle - 1].type = DDrawHandle_Unknown;
1604 LeaveCriticalSection(&ddraw_cs);
1605 return D3D_OK;
1608 /*****************************************************************************
1609 * IDirect3DDevice7::BeginScene
1611 * This method must be called before any rendering is performed.
1612 * IDirect3DDevice::EndScene has to be called after the scene is complete
1614 * Version 1, 2, 3 and 7
1616 * Returns:
1617 * D3D_OK on success, for details see IWineD3DDevice::BeginScene
1618 * D3DERR_SCENE_IN_SCENE if WineD3D returns an error(Only in case of an already
1619 * started scene).
1621 *****************************************************************************/
1622 static HRESULT
1623 IDirect3DDeviceImpl_7_BeginScene(IDirect3DDevice7 *iface)
1625 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
1626 HRESULT hr;
1627 TRACE("(%p): Relay\n", This);
1629 EnterCriticalSection(&ddraw_cs);
1630 hr = IWineD3DDevice_BeginScene(This->wineD3DDevice);
1631 LeaveCriticalSection(&ddraw_cs);
1632 if(hr == WINED3D_OK) return D3D_OK;
1633 else return D3DERR_SCENE_IN_SCENE; /* TODO: Other possible causes of failure */
1636 static HRESULT WINAPI
1637 IDirect3DDeviceImpl_7_BeginScene_FPUSetup(IDirect3DDevice7 *iface)
1639 return IDirect3DDeviceImpl_7_BeginScene(iface);
1642 static HRESULT WINAPI
1643 IDirect3DDeviceImpl_7_BeginScene_FPUPreserve(IDirect3DDevice7 *iface)
1645 HRESULT hr;
1646 WORD old_fpucw;
1648 old_fpucw = d3d_fpu_setup();
1649 hr = IDirect3DDeviceImpl_7_BeginScene(iface);
1650 set_fpu_control_word(old_fpucw);
1652 return hr;
1655 static HRESULT WINAPI
1656 Thunk_IDirect3DDeviceImpl_3_BeginScene(IDirect3DDevice3 *iface)
1658 IDirect3DDeviceImpl *This = device_from_device3(iface);
1659 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1660 return IDirect3DDevice7_BeginScene((IDirect3DDevice7 *)This);
1663 static HRESULT WINAPI
1664 Thunk_IDirect3DDeviceImpl_2_BeginScene(IDirect3DDevice2 *iface)
1666 IDirect3DDeviceImpl *This = device_from_device2(iface);
1667 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1668 return IDirect3DDevice7_BeginScene((IDirect3DDevice7 *)This);
1671 static HRESULT WINAPI
1672 Thunk_IDirect3DDeviceImpl_1_BeginScene(IDirect3DDevice *iface)
1674 IDirect3DDeviceImpl *This = device_from_device1(iface);
1675 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1676 return IDirect3DDevice7_BeginScene((IDirect3DDevice7 *)This);
1679 /*****************************************************************************
1680 * IDirect3DDevice7::EndScene
1682 * Ends a scene that has been begun with IDirect3DDevice7::BeginScene.
1683 * This method must be called after rendering is finished.
1685 * Version 1, 2, 3 and 7
1687 * Returns:
1688 * D3D_OK on success, for details see IWineD3DDevice::EndScene
1689 * D3DERR_SCENE_NOT_IN_SCENE is returned if WineD3D returns an error. It does
1690 * that only if the scene was already ended.
1692 *****************************************************************************/
1693 static HRESULT
1694 IDirect3DDeviceImpl_7_EndScene(IDirect3DDevice7 *iface)
1696 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
1697 HRESULT hr;
1698 TRACE("(%p): Relay\n", This);
1700 EnterCriticalSection(&ddraw_cs);
1701 hr = IWineD3DDevice_EndScene(This->wineD3DDevice);
1702 LeaveCriticalSection(&ddraw_cs);
1703 if(hr == WINED3D_OK) return D3D_OK;
1704 else return D3DERR_SCENE_NOT_IN_SCENE;
1707 static HRESULT WINAPI DECLSPEC_HOTPATCH
1708 IDirect3DDeviceImpl_7_EndScene_FPUSetup(IDirect3DDevice7 *iface)
1710 return IDirect3DDeviceImpl_7_EndScene(iface);
1713 static HRESULT WINAPI DECLSPEC_HOTPATCH
1714 IDirect3DDeviceImpl_7_EndScene_FPUPreserve(IDirect3DDevice7 *iface)
1716 HRESULT hr;
1717 WORD old_fpucw;
1719 old_fpucw = d3d_fpu_setup();
1720 hr = IDirect3DDeviceImpl_7_EndScene(iface);
1721 set_fpu_control_word(old_fpucw);
1723 return hr;
1726 static HRESULT WINAPI DECLSPEC_HOTPATCH
1727 Thunk_IDirect3DDeviceImpl_3_EndScene(IDirect3DDevice3 *iface)
1729 IDirect3DDeviceImpl *This = device_from_device3(iface);
1730 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1731 return IDirect3DDevice7_EndScene((IDirect3DDevice7 *)This);
1734 static HRESULT WINAPI DECLSPEC_HOTPATCH
1735 Thunk_IDirect3DDeviceImpl_2_EndScene(IDirect3DDevice2 *iface)
1737 IDirect3DDeviceImpl *This = device_from_device2(iface);
1738 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1739 return IDirect3DDevice7_EndScene((IDirect3DDevice7 *)This);
1742 static HRESULT WINAPI DECLSPEC_HOTPATCH
1743 Thunk_IDirect3DDeviceImpl_1_EndScene(IDirect3DDevice *iface)
1745 IDirect3DDeviceImpl *This = device_from_device1(iface);
1746 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1747 return IDirect3DDevice7_EndScene((IDirect3DDevice7 *)This);
1750 /*****************************************************************************
1751 * IDirect3DDevice7::GetDirect3D
1753 * Returns the IDirect3D(= interface to the DirectDraw object) used to create
1754 * this device.
1756 * Params:
1757 * Direct3D7: Address to store the interface pointer at
1759 * Returns:
1760 * D3D_OK on success
1761 * DDERR_INVALIDPARAMS if Direct3D7 == NULL
1763 *****************************************************************************/
1764 static HRESULT WINAPI
1765 IDirect3DDeviceImpl_7_GetDirect3D(IDirect3DDevice7 *iface,
1766 IDirect3D7 **Direct3D7)
1768 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
1769 TRACE("(%p)->(%p)\n", This, Direct3D7);
1771 if(!Direct3D7)
1772 return DDERR_INVALIDPARAMS;
1774 *Direct3D7 = (IDirect3D7 *)&This->ddraw->IDirect3D7_vtbl;
1775 IDirect3D7_AddRef(*Direct3D7);
1777 TRACE(" returning interface %p\n", *Direct3D7);
1778 return D3D_OK;
1781 static HRESULT WINAPI
1782 Thunk_IDirect3DDeviceImpl_3_GetDirect3D(IDirect3DDevice3 *iface,
1783 IDirect3D3 **Direct3D3)
1785 IDirect3DDeviceImpl *This = device_from_device3(iface);
1786 HRESULT ret;
1787 IDirect3D7 *ret_ptr;
1789 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Direct3D3);
1790 ret = IDirect3DDevice7_GetDirect3D((IDirect3DDevice7 *)This, &ret_ptr);
1791 if(ret != D3D_OK)
1792 return ret;
1793 *Direct3D3 = ret_ptr ? (IDirect3D3 *)&ddraw_from_d3d7(ret_ptr)->IDirect3D3_vtbl : NULL;
1794 TRACE(" returning interface %p\n", *Direct3D3);
1795 return D3D_OK;
1798 static HRESULT WINAPI
1799 Thunk_IDirect3DDeviceImpl_2_GetDirect3D(IDirect3DDevice2 *iface,
1800 IDirect3D2 **Direct3D2)
1802 IDirect3DDeviceImpl *This = device_from_device2(iface);
1803 HRESULT ret;
1804 IDirect3D7 *ret_ptr;
1806 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Direct3D2);
1807 ret = IDirect3DDevice7_GetDirect3D((IDirect3DDevice7 *)This, &ret_ptr);
1808 if(ret != D3D_OK)
1809 return ret;
1810 *Direct3D2 = ret_ptr ? (IDirect3D2 *)&ddraw_from_d3d7(ret_ptr)->IDirect3D2_vtbl : NULL;
1811 TRACE(" returning interface %p\n", *Direct3D2);
1812 return D3D_OK;
1815 static HRESULT WINAPI
1816 Thunk_IDirect3DDeviceImpl_1_GetDirect3D(IDirect3DDevice *iface,
1817 IDirect3D **Direct3D)
1819 IDirect3DDeviceImpl *This = device_from_device1(iface);
1820 HRESULT ret;
1821 IDirect3D7 *ret_ptr;
1823 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Direct3D);
1824 ret = IDirect3DDevice7_GetDirect3D((IDirect3DDevice7 *)This, &ret_ptr);
1825 if(ret != D3D_OK)
1826 return ret;
1827 *Direct3D = ret_ptr ? (IDirect3D *)&ddraw_from_d3d7(ret_ptr)->IDirect3D_vtbl : NULL;
1828 TRACE(" returning interface %p\n", *Direct3D);
1829 return D3D_OK;
1832 /*****************************************************************************
1833 * IDirect3DDevice3::SetCurrentViewport
1835 * Sets a Direct3DViewport as the current viewport.
1836 * For the thunks note that all viewport interface versions are equal
1838 * Params:
1839 * Direct3DViewport3: The viewport to set
1841 * Version 2 and 3
1843 * Returns:
1844 * D3D_OK on success
1845 * (Is a NULL viewport valid?)
1847 *****************************************************************************/
1848 static HRESULT WINAPI
1849 IDirect3DDeviceImpl_3_SetCurrentViewport(IDirect3DDevice3 *iface,
1850 IDirect3DViewport3 *Direct3DViewport3)
1852 IDirect3DDeviceImpl *This = device_from_device3(iface);
1853 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Direct3DViewport3;
1854 TRACE("(%p)->(%p)\n", This, Direct3DViewport3);
1856 EnterCriticalSection(&ddraw_cs);
1857 /* Do nothing if the specified viewport is the same as the current one */
1858 if (This->current_viewport == vp )
1860 LeaveCriticalSection(&ddraw_cs);
1861 return D3D_OK;
1864 /* Should check if the viewport was added or not */
1866 /* Release previous viewport and AddRef the new one */
1867 if (This->current_viewport)
1869 TRACE("ViewportImpl is at %p, interface is at %p\n", This->current_viewport,
1870 (IDirect3DViewport3 *)This->current_viewport);
1871 IDirect3DViewport3_Release((IDirect3DViewport3 *)This->current_viewport);
1873 IDirect3DViewport3_AddRef(Direct3DViewport3);
1875 /* Set this viewport as the current viewport */
1876 This->current_viewport = vp;
1878 /* Activate this viewport */
1879 This->current_viewport->active_device = This;
1880 This->current_viewport->activate(This->current_viewport, FALSE);
1882 LeaveCriticalSection(&ddraw_cs);
1883 return D3D_OK;
1886 static HRESULT WINAPI
1887 Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport(IDirect3DDevice2 *iface,
1888 IDirect3DViewport2 *Direct3DViewport2)
1890 IDirect3DDeviceImpl *This = device_from_device2(iface);
1891 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Direct3DViewport2;
1892 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
1893 return IDirect3DDevice3_SetCurrentViewport((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl,
1894 (IDirect3DViewport3 *)vp);
1897 /*****************************************************************************
1898 * IDirect3DDevice3::GetCurrentViewport
1900 * Returns the currently active viewport.
1902 * Version 2 and 3
1904 * Params:
1905 * Direct3DViewport3: Address to return the interface pointer at
1907 * Returns:
1908 * D3D_OK on success
1909 * DDERR_INVALIDPARAMS if Direct3DViewport == NULL
1911 *****************************************************************************/
1912 static HRESULT WINAPI
1913 IDirect3DDeviceImpl_3_GetCurrentViewport(IDirect3DDevice3 *iface,
1914 IDirect3DViewport3 **Direct3DViewport3)
1916 IDirect3DDeviceImpl *This = device_from_device3(iface);
1917 TRACE("(%p)->(%p)\n", This, Direct3DViewport3);
1919 if(!Direct3DViewport3)
1920 return DDERR_INVALIDPARAMS;
1922 EnterCriticalSection(&ddraw_cs);
1923 *Direct3DViewport3 = (IDirect3DViewport3 *)This->current_viewport;
1925 /* AddRef the returned viewport */
1926 if(*Direct3DViewport3) IDirect3DViewport3_AddRef(*Direct3DViewport3);
1928 TRACE(" returning interface %p\n", *Direct3DViewport3);
1930 LeaveCriticalSection(&ddraw_cs);
1931 return D3D_OK;
1934 static HRESULT WINAPI
1935 Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport(IDirect3DDevice2 *iface,
1936 IDirect3DViewport2 **Direct3DViewport2)
1938 IDirect3DDeviceImpl *This = device_from_device2(iface);
1939 HRESULT hr;
1940 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, Direct3DViewport2);
1941 hr = IDirect3DDevice3_GetCurrentViewport((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl,
1942 (IDirect3DViewport3 **)Direct3DViewport2);
1943 if(hr != D3D_OK) return hr;
1944 return D3D_OK;
1947 /*****************************************************************************
1948 * IDirect3DDevice7::SetRenderTarget
1950 * Sets the render target for the Direct3DDevice.
1951 * For the thunks note that IDirectDrawSurface7 == IDirectDrawSurface4 and
1952 * IDirectDrawSurface3 == IDirectDrawSurface
1954 * Version 2, 3 and 7
1956 * Params:
1957 * NewTarget: Pointer to an IDirectDrawSurface7 interface to set as the new
1958 * render target
1959 * Flags: Some flags
1961 * Returns:
1962 * D3D_OK on success, for details see IWineD3DDevice::SetRenderTarget
1964 *****************************************************************************/
1965 static HRESULT
1966 IDirect3DDeviceImpl_7_SetRenderTarget(IDirect3DDevice7 *iface,
1967 IDirectDrawSurface7 *NewTarget,
1968 DWORD Flags)
1970 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
1971 IDirectDrawSurfaceImpl *Target = (IDirectDrawSurfaceImpl *)NewTarget;
1972 HRESULT hr;
1973 TRACE("(%p)->(%p,%08x): Relay\n", This, NewTarget, Flags);
1975 EnterCriticalSection(&ddraw_cs);
1976 /* Flags: Not used */
1978 if(This->target == Target)
1980 TRACE("No-op SetRenderTarget operation, not doing anything\n");
1981 LeaveCriticalSection(&ddraw_cs);
1982 return D3D_OK;
1985 hr = IWineD3DDevice_SetRenderTarget(This->wineD3DDevice,
1987 Target ? Target->WineD3DSurface : NULL);
1988 if(hr != D3D_OK)
1990 LeaveCriticalSection(&ddraw_cs);
1991 return hr;
1993 IDirectDrawSurface7_AddRef(NewTarget);
1994 IDirectDrawSurface7_Release((IDirectDrawSurface7 *)This->target);
1995 This->target = Target;
1996 IDirect3DDeviceImpl_UpdateDepthStencil(This);
1997 LeaveCriticalSection(&ddraw_cs);
1998 return D3D_OK;
2001 static HRESULT WINAPI
2002 IDirect3DDeviceImpl_7_SetRenderTarget_FPUSetup(IDirect3DDevice7 *iface,
2003 IDirectDrawSurface7 *NewTarget,
2004 DWORD Flags)
2006 return IDirect3DDeviceImpl_7_SetRenderTarget(iface, NewTarget, Flags);
2009 static HRESULT WINAPI
2010 IDirect3DDeviceImpl_7_SetRenderTarget_FPUPreserve(IDirect3DDevice7 *iface,
2011 IDirectDrawSurface7 *NewTarget,
2012 DWORD Flags)
2014 HRESULT hr;
2015 WORD old_fpucw;
2017 old_fpucw = d3d_fpu_setup();
2018 hr = IDirect3DDeviceImpl_7_SetRenderTarget(iface, NewTarget, Flags);
2019 set_fpu_control_word(old_fpucw);
2021 return hr;
2024 static HRESULT WINAPI
2025 Thunk_IDirect3DDeviceImpl_3_SetRenderTarget(IDirect3DDevice3 *iface,
2026 IDirectDrawSurface4 *NewRenderTarget,
2027 DWORD Flags)
2029 IDirect3DDeviceImpl *This = device_from_device3(iface);
2030 IDirectDrawSurfaceImpl *Target = (IDirectDrawSurfaceImpl *)NewRenderTarget;
2031 TRACE_(ddraw_thunk)("(%p)->(%p,%08x) thunking to IDirect3DDevice7 interface.\n", This, Target, Flags);
2032 return IDirect3DDevice7_SetRenderTarget((IDirect3DDevice7 *)This, (IDirectDrawSurface7 *)Target, Flags);
2035 static HRESULT WINAPI
2036 Thunk_IDirect3DDeviceImpl_2_SetRenderTarget(IDirect3DDevice2 *iface,
2037 IDirectDrawSurface *NewRenderTarget,
2038 DWORD Flags)
2040 IDirect3DDeviceImpl *This = device_from_device2(iface);
2041 IDirectDrawSurfaceImpl *Target = (IDirectDrawSurfaceImpl *)NewRenderTarget;
2042 TRACE_(ddraw_thunk)("(%p)->(%p,%08x) thunking to IDirect3DDevice7 interface.\n", This, Target, Flags);
2043 return IDirect3DDevice7_SetRenderTarget((IDirect3DDevice7 *)This, (IDirectDrawSurface7 *)Target, Flags);
2046 /*****************************************************************************
2047 * IDirect3DDevice7::GetRenderTarget
2049 * Returns the current render target.
2050 * This is handled locally, because the WineD3D render target's parent
2051 * is an IParent
2053 * Version 2, 3 and 7
2055 * Params:
2056 * RenderTarget: Address to store the surface interface pointer
2058 * Returns:
2059 * D3D_OK on success
2060 * DDERR_INVALIDPARAMS if RenderTarget == NULL
2062 *****************************************************************************/
2063 static HRESULT WINAPI
2064 IDirect3DDeviceImpl_7_GetRenderTarget(IDirect3DDevice7 *iface,
2065 IDirectDrawSurface7 **RenderTarget)
2067 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
2068 TRACE("(%p)->(%p): Relay\n", This, RenderTarget);
2070 if(!RenderTarget)
2071 return DDERR_INVALIDPARAMS;
2073 EnterCriticalSection(&ddraw_cs);
2074 *RenderTarget = (IDirectDrawSurface7 *)This->target;
2075 IDirectDrawSurface7_AddRef(*RenderTarget);
2077 LeaveCriticalSection(&ddraw_cs);
2078 return D3D_OK;
2081 static HRESULT WINAPI
2082 Thunk_IDirect3DDeviceImpl_3_GetRenderTarget(IDirect3DDevice3 *iface,
2083 IDirectDrawSurface4 **RenderTarget)
2085 IDirect3DDeviceImpl *This = device_from_device3(iface);
2086 HRESULT hr;
2087 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, RenderTarget);
2088 hr = IDirect3DDevice7_GetRenderTarget((IDirect3DDevice7 *)This, (IDirectDrawSurface7 **)RenderTarget);
2089 if(hr != D3D_OK) return hr;
2090 return D3D_OK;
2093 static HRESULT WINAPI
2094 Thunk_IDirect3DDeviceImpl_2_GetRenderTarget(IDirect3DDevice2 *iface,
2095 IDirectDrawSurface **RenderTarget)
2097 IDirect3DDeviceImpl *This = device_from_device2(iface);
2098 HRESULT hr;
2099 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, RenderTarget);
2100 hr = IDirect3DDevice7_GetRenderTarget((IDirect3DDevice7 *)This, (IDirectDrawSurface7 **)RenderTarget);
2101 if(hr != D3D_OK) return hr;
2102 *RenderTarget = *RenderTarget ?
2103 (IDirectDrawSurface *)&((IDirectDrawSurfaceImpl *)*RenderTarget)->IDirectDrawSurface3_vtbl : NULL;
2104 return D3D_OK;
2107 /*****************************************************************************
2108 * IDirect3DDevice3::Begin
2110 * Begins a description block of vertices. This is similar to glBegin()
2111 * and glEnd(). After a call to IDirect3DDevice3::End, the vertices
2112 * described with IDirect3DDevice::Vertex are drawn.
2114 * Version 2 and 3
2116 * Params:
2117 * PrimitiveType: The type of primitives to draw
2118 * VertexTypeDesc: A flexible vertex format description of the vertices
2119 * Flags: Some flags..
2121 * Returns:
2122 * D3D_OK on success
2124 *****************************************************************************/
2125 static HRESULT WINAPI
2126 IDirect3DDeviceImpl_3_Begin(IDirect3DDevice3 *iface,
2127 D3DPRIMITIVETYPE PrimitiveType,
2128 DWORD VertexTypeDesc,
2129 DWORD Flags)
2131 IDirect3DDeviceImpl *This = device_from_device3(iface);
2132 TRACE("(%p)->(%d,%d,%08x)\n", This, PrimitiveType, VertexTypeDesc, Flags);
2134 EnterCriticalSection(&ddraw_cs);
2135 This->primitive_type = PrimitiveType;
2136 This->vertex_type = VertexTypeDesc;
2137 This->render_flags = Flags;
2138 This->vertex_size = get_flexible_vertex_size(This->vertex_type);
2139 This->nb_vertices = 0;
2140 LeaveCriticalSection(&ddraw_cs);
2142 return D3D_OK;
2145 static HRESULT WINAPI
2146 Thunk_IDirect3DDeviceImpl_2_Begin(IDirect3DDevice2 *iface,
2147 D3DPRIMITIVETYPE d3dpt,
2148 D3DVERTEXTYPE dwVertexTypeDesc,
2149 DWORD dwFlags)
2151 DWORD FVF;
2152 IDirect3DDeviceImpl *This = device_from_device2(iface);
2153 TRACE_(ddraw_thunk)("(%p/%p)->(%08x,%08x,%08x): Thunking to IDirect3DDevice3\n", This, iface, d3dpt, dwVertexTypeDesc, dwFlags);
2155 switch(dwVertexTypeDesc)
2157 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
2158 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
2159 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
2160 default:
2161 ERR("Unexpected vertex type %d\n", dwVertexTypeDesc);
2162 return DDERR_INVALIDPARAMS; /* Should never happen */
2165 return IDirect3DDevice3_Begin((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, d3dpt, FVF, dwFlags);
2168 /*****************************************************************************
2169 * IDirect3DDevice3::BeginIndexed
2171 * Draws primitives based on vertices in a vertex array which are specified
2172 * by indices.
2174 * Version 2 and 3
2176 * Params:
2177 * PrimitiveType: Primitive type to draw
2178 * VertexType: A FVF description of the vertex format
2179 * Vertices: pointer to an array containing the vertices
2180 * NumVertices: The number of vertices in the vertex array
2181 * Flags: Some flags ...
2183 * Returns:
2184 * D3D_OK, because it's a stub
2186 *****************************************************************************/
2187 static HRESULT WINAPI
2188 IDirect3DDeviceImpl_3_BeginIndexed(IDirect3DDevice3 *iface,
2189 D3DPRIMITIVETYPE PrimitiveType,
2190 DWORD VertexType,
2191 void *Vertices,
2192 DWORD NumVertices,
2193 DWORD Flags)
2195 IDirect3DDeviceImpl *This = device_from_device3(iface);
2196 FIXME("(%p)->(%08x,%08x,%p,%08x,%08x): stub!\n", This, PrimitiveType, VertexType, Vertices, NumVertices, Flags);
2197 return D3D_OK;
2201 static HRESULT WINAPI
2202 Thunk_IDirect3DDeviceImpl_2_BeginIndexed(IDirect3DDevice2 *iface,
2203 D3DPRIMITIVETYPE d3dptPrimitiveType,
2204 D3DVERTEXTYPE d3dvtVertexType,
2205 void *lpvVertices,
2206 DWORD dwNumVertices,
2207 DWORD dwFlags)
2209 DWORD FVF;
2210 IDirect3DDeviceImpl *This = device_from_device2(iface);
2211 TRACE_(ddraw_thunk)("(%p/%p)->(%08x,%08x,%p,%08x,%08x): Thunking to IDirect3DDevice3\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwNumVertices, dwFlags);
2213 switch(d3dvtVertexType)
2215 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
2216 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
2217 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
2218 default:
2219 ERR("Unexpected vertex type %d\n", d3dvtVertexType);
2220 return DDERR_INVALIDPARAMS; /* Should never happen */
2223 return IDirect3DDevice3_BeginIndexed((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl,
2224 d3dptPrimitiveType, FVF, lpvVertices, dwNumVertices, dwFlags);
2227 /*****************************************************************************
2228 * IDirect3DDevice3::Vertex
2230 * Draws a vertex as described by IDirect3DDevice3::Begin. It places all
2231 * drawn vertices in a vertex buffer. If the buffer is too small, its
2232 * size is increased.
2234 * Version 2 and 3
2236 * Params:
2237 * Vertex: Pointer to the vertex
2239 * Returns:
2240 * D3D_OK, on success
2241 * DDERR_INVALIDPARAMS if Vertex is NULL
2243 *****************************************************************************/
2244 static HRESULT WINAPI
2245 IDirect3DDeviceImpl_3_Vertex(IDirect3DDevice3 *iface,
2246 void *Vertex)
2248 IDirect3DDeviceImpl *This = device_from_device3(iface);
2249 TRACE("(%p)->(%p)\n", This, Vertex);
2251 if(!Vertex)
2252 return DDERR_INVALIDPARAMS;
2254 EnterCriticalSection(&ddraw_cs);
2255 if ((This->nb_vertices+1)*This->vertex_size > This->buffer_size)
2257 BYTE *old_buffer;
2258 This->buffer_size = This->buffer_size ? This->buffer_size * 2 : This->vertex_size * 3;
2259 old_buffer = This->vertex_buffer;
2260 This->vertex_buffer = HeapAlloc(GetProcessHeap(), 0, This->buffer_size);
2261 if (old_buffer)
2263 CopyMemory(This->vertex_buffer, old_buffer, This->nb_vertices * This->vertex_size);
2264 HeapFree(GetProcessHeap(), 0, old_buffer);
2268 CopyMemory(This->vertex_buffer + This->nb_vertices++ * This->vertex_size, Vertex, This->vertex_size);
2270 LeaveCriticalSection(&ddraw_cs);
2271 return D3D_OK;
2274 static HRESULT WINAPI
2275 Thunk_IDirect3DDeviceImpl_2_Vertex(IDirect3DDevice2 *iface,
2276 void *lpVertexType)
2278 IDirect3DDeviceImpl *This = device_from_device2(iface);
2279 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, lpVertexType);
2280 return IDirect3DDevice3_Vertex((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, lpVertexType);
2283 /*****************************************************************************
2284 * IDirect3DDevice3::Index
2286 * Specifies an index to a vertex to be drawn. The vertex array has to
2287 * be specified with BeginIndexed first.
2289 * Parameters:
2290 * VertexIndex: The index of the vertex to draw
2292 * Returns:
2293 * D3D_OK because it's a stub
2295 *****************************************************************************/
2296 static HRESULT WINAPI
2297 IDirect3DDeviceImpl_3_Index(IDirect3DDevice3 *iface,
2298 WORD VertexIndex)
2300 IDirect3DDeviceImpl *This = device_from_device3(iface);
2301 FIXME("(%p)->(%04x): stub!\n", This, VertexIndex);
2302 return D3D_OK;
2305 static HRESULT WINAPI
2306 Thunk_IDirect3DDeviceImpl_2_Index(IDirect3DDevice2 *iface,
2307 WORD wVertexIndex)
2309 IDirect3DDeviceImpl *This = device_from_device2(iface);
2310 TRACE_(ddraw_thunk)("(%p)->(%04x) thunking to IDirect3DDevice3 interface.\n", This, wVertexIndex);
2311 return IDirect3DDevice3_Index((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, wVertexIndex);
2314 /*****************************************************************************
2315 * IDirect3DDevice3::End
2317 * Ends a draw begun with IDirect3DDevice3::Begin or
2318 * IDirect3DDevice::BeginIndexed. The vertices specified with
2319 * IDirect3DDevice::Vertex or IDirect3DDevice::Index are drawn using
2320 * the IDirect3DDevice7::DrawPrimitive method. So far only
2321 * non-indexed mode is supported
2323 * Version 2 and 3
2325 * Params:
2326 * Flags: Some flags, as usual. Don't know which are defined
2328 * Returns:
2329 * The return value of IDirect3DDevice7::DrawPrimitive
2331 *****************************************************************************/
2332 static HRESULT WINAPI
2333 IDirect3DDeviceImpl_3_End(IDirect3DDevice3 *iface,
2334 DWORD Flags)
2336 IDirect3DDeviceImpl *This = device_from_device3(iface);
2337 TRACE("(%p)->(%08x)\n", This, Flags);
2339 return IDirect3DDevice7_DrawPrimitive((IDirect3DDevice7 *)This, This->primitive_type,
2340 This->vertex_type, This->vertex_buffer, This->nb_vertices, This->render_flags);
2343 static HRESULT WINAPI
2344 Thunk_IDirect3DDeviceImpl_2_End(IDirect3DDevice2 *iface,
2345 DWORD dwFlags)
2347 IDirect3DDeviceImpl *This = device_from_device2(iface);
2348 TRACE_(ddraw_thunk)("(%p)->(%08x) thunking to IDirect3DDevice3 interface.\n", This, dwFlags);
2349 return IDirect3DDevice3_End((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, dwFlags);
2352 /*****************************************************************************
2353 * IDirect3DDevice7::GetRenderState
2355 * Returns the value of a render state. The possible render states are
2356 * defined in include/d3dtypes.h
2358 * Version 2, 3 and 7
2360 * Params:
2361 * RenderStateType: Render state to return the current setting of
2362 * Value: Address to store the value at
2364 * Returns:
2365 * D3D_OK on success, for details see IWineD3DDevice::GetRenderState
2366 * DDERR_INVALIDPARAMS if Value == NULL
2368 *****************************************************************************/
2369 static HRESULT
2370 IDirect3DDeviceImpl_7_GetRenderState(IDirect3DDevice7 *iface,
2371 D3DRENDERSTATETYPE RenderStateType,
2372 DWORD *Value)
2374 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
2375 HRESULT hr;
2376 TRACE("(%p)->(%08x,%p): Relay\n", This, RenderStateType, Value);
2378 if(!Value)
2379 return DDERR_INVALIDPARAMS;
2381 EnterCriticalSection(&ddraw_cs);
2382 switch(RenderStateType)
2384 case D3DRENDERSTATE_TEXTUREMAG:
2386 WINED3DTEXTUREFILTERTYPE tex_mag;
2388 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2389 0, WINED3DSAMP_MAGFILTER,
2390 &tex_mag);
2392 switch (tex_mag)
2394 case WINED3DTEXF_POINT:
2395 *Value = D3DFILTER_NEAREST;
2396 break;
2397 case WINED3DTEXF_LINEAR:
2398 *Value = D3DFILTER_LINEAR;
2399 break;
2400 default:
2401 ERR("Unhandled texture mag %d !\n",tex_mag);
2402 *Value = 0;
2404 break;
2407 case D3DRENDERSTATE_TEXTUREMIN:
2409 WINED3DTEXTUREFILTERTYPE tex_min;
2411 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2412 0, WINED3DSAMP_MINFILTER,
2413 &tex_min);
2415 switch (tex_min)
2417 case WINED3DTEXF_POINT:
2418 *Value = D3DFILTER_NEAREST;
2419 break;
2420 case WINED3DTEXF_LINEAR:
2421 *Value = D3DFILTER_LINEAR;
2422 break;
2423 default:
2424 ERR("Unhandled texture mag %d !\n",tex_min);
2425 *Value = 0;
2427 break;
2430 case D3DRENDERSTATE_TEXTUREADDRESS:
2431 case D3DRENDERSTATE_TEXTUREADDRESSU:
2432 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2433 0, WINED3DSAMP_ADDRESSU,
2434 Value);
2435 break;
2436 case D3DRENDERSTATE_TEXTUREADDRESSV:
2437 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2438 0, WINED3DSAMP_ADDRESSV,
2439 Value);
2440 break;
2442 default:
2443 /* FIXME: Unhandled: D3DRENDERSTATE_STIPPLEPATTERN00 - 31 */
2444 hr = IWineD3DDevice_GetRenderState(This->wineD3DDevice,
2445 RenderStateType,
2446 Value);
2448 LeaveCriticalSection(&ddraw_cs);
2449 return hr;
2452 static HRESULT WINAPI
2453 IDirect3DDeviceImpl_7_GetRenderState_FPUSetup(IDirect3DDevice7 *iface,
2454 D3DRENDERSTATETYPE RenderStateType,
2455 DWORD *Value)
2457 return IDirect3DDeviceImpl_7_GetRenderState(iface, RenderStateType, Value);
2460 static HRESULT WINAPI
2461 IDirect3DDeviceImpl_7_GetRenderState_FPUPreserve(IDirect3DDevice7 *iface,
2462 D3DRENDERSTATETYPE RenderStateType,
2463 DWORD *Value)
2465 HRESULT hr;
2466 WORD old_fpucw;
2468 old_fpucw = d3d_fpu_setup();
2469 hr = IDirect3DDeviceImpl_7_GetRenderState(iface, RenderStateType, Value);
2470 set_fpu_control_word(old_fpucw);
2472 return hr;
2475 static HRESULT WINAPI
2476 IDirect3DDeviceImpl_3_GetRenderState(IDirect3DDevice3 *iface,
2477 D3DRENDERSTATETYPE dwRenderStateType,
2478 DWORD *lpdwRenderState)
2480 IDirect3DDeviceImpl *This = device_from_device3(iface);
2481 HRESULT hr;
2482 TRACE("(%p)->(%08x,%p)\n", This, dwRenderStateType, lpdwRenderState);
2484 switch(dwRenderStateType)
2486 case D3DRENDERSTATE_TEXTUREHANDLE:
2488 /* This state is wrapped to SetTexture in SetRenderState, so
2489 * it has to be wrapped to GetTexture here
2491 IWineD3DBaseTexture *tex = NULL;
2492 *lpdwRenderState = 0;
2494 EnterCriticalSection(&ddraw_cs);
2496 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice,
2498 &tex);
2500 if(hr == WINED3D_OK && tex)
2502 IDirectDrawSurface7 *parent = NULL;
2503 hr = IWineD3DBaseTexture_GetParent(tex,
2504 (IUnknown **) &parent);
2505 if(parent)
2507 /* The parent of the texture is the IDirectDrawSurface7 interface
2508 * of the ddraw surface
2510 IDirectDrawSurfaceImpl *texImpl = (IDirectDrawSurfaceImpl *)parent;
2511 *lpdwRenderState = texImpl->Handle;
2512 IDirectDrawSurface7_Release(parent);
2514 IWineD3DBaseTexture_Release(tex);
2517 LeaveCriticalSection(&ddraw_cs);
2519 return hr;
2522 case D3DRENDERSTATE_TEXTUREMAPBLEND:
2524 /* D3DRENDERSTATE_TEXTUREMAPBLEND is mapped to texture state stages in SetRenderState; reverse
2525 the mapping to get the value. */
2526 DWORD colorop, colorarg1, colorarg2;
2527 DWORD alphaop, alphaarg1, alphaarg2;
2529 EnterCriticalSection(&ddraw_cs);
2531 This->legacyTextureBlending = TRUE;
2533 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, &colorop);
2534 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, &colorarg1);
2535 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, &colorarg2);
2536 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, &alphaop);
2537 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, &alphaarg1);
2538 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, &alphaarg2);
2540 if (colorop == WINED3DTOP_SELECTARG1 && colorarg1 == WINED3DTA_TEXTURE &&
2541 alphaop == WINED3DTOP_SELECTARG1 && alphaarg1 == WINED3DTA_TEXTURE)
2543 *lpdwRenderState = D3DTBLEND_DECAL;
2545 else if (colorop == WINED3DTOP_SELECTARG1 && colorarg1 == WINED3DTA_TEXTURE &&
2546 alphaop == WINED3DTOP_MODULATE && alphaarg1 == WINED3DTA_TEXTURE && alphaarg2 == WINED3DTA_CURRENT)
2548 *lpdwRenderState = D3DTBLEND_DECALALPHA;
2550 else if (colorop == WINED3DTOP_MODULATE && colorarg1 == WINED3DTA_TEXTURE && colorarg2 == WINED3DTA_CURRENT &&
2551 alphaop == WINED3DTOP_MODULATE && alphaarg1 == WINED3DTA_TEXTURE && alphaarg2 == WINED3DTA_CURRENT)
2553 *lpdwRenderState = D3DTBLEND_MODULATEALPHA;
2555 else
2557 HRESULT hr;
2558 BOOL tex_alpha = FALSE;
2559 IWineD3DBaseTexture *tex = NULL;
2560 WINED3DSURFACE_DESC desc;
2561 DDPIXELFORMAT ddfmt;
2563 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice,
2565 &tex);
2567 if(hr == WINED3D_OK && tex)
2569 hr = IWineD3DTexture_GetLevelDesc((IWineD3DTexture*) tex, 0, &desc);
2570 if (SUCCEEDED(hr))
2572 ddfmt.dwSize = sizeof(ddfmt);
2573 PixelFormat_WineD3DtoDD(&ddfmt, desc.format);
2574 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
2577 IWineD3DBaseTexture_Release(tex);
2580 if (!(colorop == WINED3DTOP_MODULATE && colorarg1 == WINED3DTA_TEXTURE && colorarg2 == WINED3DTA_CURRENT &&
2581 alphaop == WINED3DTOP_SELECTARG1 && alphaarg1 == (tex_alpha ? WINED3DTA_TEXTURE : WINED3DTA_CURRENT)))
2583 ERR("Unexpected texture stage state setup, returning D3DTBLEND_MODULATE - likely erroneous\n");
2586 *lpdwRenderState = D3DTBLEND_MODULATE;
2589 LeaveCriticalSection(&ddraw_cs);
2591 return D3D_OK;
2594 default:
2595 return IDirect3DDevice7_GetRenderState((IDirect3DDevice7 *)This, dwRenderStateType, lpdwRenderState);
2599 static HRESULT WINAPI
2600 Thunk_IDirect3DDeviceImpl_2_GetRenderState(IDirect3DDevice2 *iface,
2601 D3DRENDERSTATETYPE dwRenderStateType,
2602 DWORD *lpdwRenderState)
2604 IDirect3DDeviceImpl *This = device_from_device2(iface);
2605 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice3 interface.\n", This, dwRenderStateType, lpdwRenderState);
2606 return IDirect3DDevice3_GetRenderState((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl,
2607 dwRenderStateType, lpdwRenderState);
2610 /*****************************************************************************
2611 * IDirect3DDevice7::SetRenderState
2613 * Sets a render state. The possible render states are defined in
2614 * include/d3dtypes.h
2616 * Version 2, 3 and 7
2618 * Params:
2619 * RenderStateType: State to set
2620 * Value: Value to assign to that state
2622 * Returns:
2623 * D3D_OK on success,
2624 * for details see IWineD3DDevice::SetRenderState
2626 *****************************************************************************/
2627 static HRESULT
2628 IDirect3DDeviceImpl_7_SetRenderState(IDirect3DDevice7 *iface,
2629 D3DRENDERSTATETYPE RenderStateType,
2630 DWORD Value)
2632 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
2633 HRESULT hr;
2634 TRACE("(%p)->(%08x,%d): Relay\n", This, RenderStateType, Value);
2636 EnterCriticalSection(&ddraw_cs);
2637 /* Some render states need special care */
2638 switch(RenderStateType)
2640 case D3DRENDERSTATE_TEXTUREMAG:
2642 WINED3DTEXTUREFILTERTYPE tex_mag = WINED3DTEXF_POINT;
2644 switch ((D3DTEXTUREFILTER) Value)
2646 case D3DFILTER_NEAREST:
2647 case D3DFILTER_LINEARMIPNEAREST:
2648 tex_mag = WINED3DTEXF_POINT;
2649 break;
2650 case D3DFILTER_LINEAR:
2651 case D3DFILTER_LINEARMIPLINEAR:
2652 tex_mag = WINED3DTEXF_LINEAR;
2653 break;
2654 default:
2655 ERR("Unhandled texture mag %d !\n",Value);
2658 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2659 0, WINED3DSAMP_MAGFILTER,
2660 tex_mag);
2661 break;
2664 case D3DRENDERSTATE_TEXTUREMIN:
2666 WINED3DTEXTUREFILTERTYPE tex_min = WINED3DTEXF_POINT;
2667 WINED3DTEXTUREFILTERTYPE tex_mip = WINED3DTEXF_NONE;
2669 switch ((D3DTEXTUREFILTER) Value)
2671 case D3DFILTER_NEAREST:
2672 tex_min = WINED3DTEXF_POINT;
2673 break;
2674 case D3DFILTER_LINEAR:
2675 tex_min = WINED3DTEXF_LINEAR;
2676 break;
2677 case D3DFILTER_MIPNEAREST:
2678 tex_min = WINED3DTEXF_POINT;
2679 tex_mip = WINED3DTEXF_POINT;
2680 break;
2681 case D3DFILTER_MIPLINEAR:
2682 tex_min = WINED3DTEXF_POINT;
2683 tex_mip = WINED3DTEXF_LINEAR;
2684 break;
2685 case D3DFILTER_LINEARMIPNEAREST:
2686 tex_min = WINED3DTEXF_POINT;
2687 tex_mip = WINED3DTEXF_LINEAR;
2688 break;
2689 case D3DFILTER_LINEARMIPLINEAR:
2690 tex_min = WINED3DTEXF_LINEAR;
2691 tex_mip = WINED3DTEXF_LINEAR;
2692 break;
2694 default:
2695 ERR("Unhandled texture min %d !\n",Value);
2698 IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2699 0, WINED3DSAMP_MIPFILTER,
2700 tex_mip);
2701 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2702 0, WINED3DSAMP_MINFILTER,
2703 tex_min);
2704 break;
2707 case D3DRENDERSTATE_TEXTUREADDRESS:
2708 IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2709 0, WINED3DSAMP_ADDRESSV,
2710 Value);
2711 /* Drop through */
2712 case D3DRENDERSTATE_TEXTUREADDRESSU:
2713 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2714 0, WINED3DSAMP_ADDRESSU,
2715 Value);
2716 break;
2717 case D3DRENDERSTATE_TEXTUREADDRESSV:
2718 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2719 0, WINED3DSAMP_ADDRESSV,
2720 Value);
2721 break;
2723 default:
2725 /* FIXME: Unhandled: D3DRENDERSTATE_STIPPLEPATTERN00 - 31 */
2727 hr = IWineD3DDevice_SetRenderState(This->wineD3DDevice,
2728 RenderStateType,
2729 Value);
2730 break;
2732 LeaveCriticalSection(&ddraw_cs);
2733 return hr;
2736 static HRESULT WINAPI
2737 IDirect3DDeviceImpl_7_SetRenderState_FPUSetup(IDirect3DDevice7 *iface,
2738 D3DRENDERSTATETYPE RenderStateType,
2739 DWORD Value)
2741 return IDirect3DDeviceImpl_7_SetRenderState(iface, RenderStateType, Value);
2744 static HRESULT WINAPI
2745 IDirect3DDeviceImpl_7_SetRenderState_FPUPreserve(IDirect3DDevice7 *iface,
2746 D3DRENDERSTATETYPE RenderStateType,
2747 DWORD Value)
2749 HRESULT hr;
2750 WORD old_fpucw;
2752 old_fpucw = d3d_fpu_setup();
2753 hr = IDirect3DDeviceImpl_7_SetRenderState(iface, RenderStateType, Value);
2754 set_fpu_control_word(old_fpucw);
2756 return hr;
2759 static HRESULT WINAPI
2760 IDirect3DDeviceImpl_3_SetRenderState(IDirect3DDevice3 *iface,
2761 D3DRENDERSTATETYPE RenderStateType,
2762 DWORD Value)
2764 /* Note about D3DRENDERSTATE_TEXTUREMAPBLEND implementation: most of values
2765 for this state can be directly mapped to texture stage colorop and alphaop, but
2766 D3DTBLEND_MODULATE is tricky: it uses alpha from texture when available and alpha
2767 from diffuse otherwise. So changing the texture must be monitored in SetTexture to modify
2768 alphaarg when needed.
2770 Aliens vs Predator 1 depends on accurate D3DTBLEND_MODULATE emulation
2772 Legacy texture blending (TEXTUREMAPBLEND) and texture stage states: directx6 docs state that
2773 TEXTUREMAPBLEND is deprecated, yet can still be used. Games must not use both or results
2774 are undefined. D3DTBLEND_MODULATE mode in particular is dependent on texture pixel format and
2775 requires fixup of stage 0 texture states when texture changes, but this fixup can interfere
2776 with games not using this deprecated state. So a flag 'legacyTextureBlending' has to be kept
2777 in device - TRUE if the app is using TEXTUREMAPBLEND.
2779 Tests show that setting TEXTUREMAPBLEND on native doesn't seem to change values returned by
2780 GetTextureStageState and vice versa. Not so on Wine, but it is 'undefined' anyway so, probably, ok,
2781 unless some broken game will be found that cares. */
2783 HRESULT hr;
2784 IDirect3DDeviceImpl *This = device_from_device3(iface);
2785 TRACE("(%p)->(%08x,%d)\n", This, RenderStateType, Value);
2787 EnterCriticalSection(&ddraw_cs);
2789 switch(RenderStateType)
2791 case D3DRENDERSTATE_TEXTUREHANDLE:
2793 if(Value == 0)
2795 hr = IWineD3DDevice_SetTexture(This->wineD3DDevice,
2797 NULL);
2798 break;
2801 if(Value > This->numHandles)
2803 FIXME("Specified handle %d out of range\n", Value);
2804 hr = DDERR_INVALIDPARAMS;
2805 break;
2807 if(This->Handles[Value - 1].type != DDrawHandle_Texture)
2809 FIXME("Handle %d isn't a texture handle\n", Value);
2810 hr = DDERR_INVALIDPARAMS;
2811 break;
2813 else
2815 IDirectDrawSurfaceImpl *surf = This->Handles[Value - 1].ptr;
2816 IDirect3DTexture2 *tex = surf ? (IDirect3DTexture2 *)&surf->IDirect3DTexture2_vtbl : NULL;
2817 hr = IDirect3DDevice3_SetTexture(iface, 0, tex);
2818 break;
2822 case D3DRENDERSTATE_TEXTUREMAPBLEND:
2824 This->legacyTextureBlending = TRUE;
2826 switch ( (D3DTEXTUREBLEND) Value)
2828 case D3DTBLEND_MODULATE:
2830 BOOL tex_alpha = FALSE;
2831 IWineD3DBaseTexture *tex = NULL;
2832 WINED3DSURFACE_DESC desc;
2833 DDPIXELFORMAT ddfmt;
2835 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice,
2837 &tex);
2839 if(hr == WINED3D_OK && tex)
2841 memset(&desc, 0, sizeof(desc));
2842 hr = IWineD3DTexture_GetLevelDesc((IWineD3DTexture*) tex, 0, &desc);
2843 if (SUCCEEDED(hr))
2845 ddfmt.dwSize = sizeof(ddfmt);
2846 PixelFormat_WineD3DtoDD(&ddfmt, desc.format);
2847 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
2850 IWineD3DBaseTexture_Release(tex);
2853 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG1);
2854 if (tex_alpha)
2856 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2858 else
2860 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_CURRENT);
2863 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2864 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2865 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_MODULATE);
2867 break;
2870 case D3DTBLEND_ADD:
2871 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_ADD);
2872 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2873 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2874 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG2);
2875 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
2876 break;
2878 case D3DTBLEND_MODULATEALPHA:
2879 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2880 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2881 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2882 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
2883 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_MODULATE);
2884 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_MODULATE);
2885 break;
2887 case D3DTBLEND_COPY:
2888 case D3DTBLEND_DECAL:
2889 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2890 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2891 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_SELECTARG1);
2892 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG1);
2893 break;
2895 case D3DTBLEND_DECALALPHA:
2896 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_BLENDTEXTUREALPHA);
2897 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2898 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2899 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG2);
2900 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
2901 break;
2903 default:
2904 ERR("Unhandled texture environment %d !\n",Value);
2907 hr = D3D_OK;
2908 break;
2911 default:
2912 hr = IDirect3DDevice7_SetRenderState((IDirect3DDevice7 *)This, RenderStateType, Value);
2913 break;
2916 LeaveCriticalSection(&ddraw_cs);
2918 return hr;
2921 static HRESULT WINAPI
2922 Thunk_IDirect3DDeviceImpl_2_SetRenderState(IDirect3DDevice2 *iface,
2923 D3DRENDERSTATETYPE RenderStateType,
2924 DWORD Value)
2926 IDirect3DDeviceImpl *This = device_from_device2(iface);
2927 TRACE_(ddraw_thunk)("(%p)->(%08x,%d) thunking to IDirect3DDevice3 interface.\n", This, RenderStateType, Value);
2928 return IDirect3DDevice3_SetRenderState((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, RenderStateType, Value);
2931 /*****************************************************************************
2932 * Direct3DDevice3::SetLightState
2934 * Sets a light state for Direct3DDevice3 and Direct3DDevice2. The
2935 * light states are forwarded to Direct3DDevice7 render states
2937 * Version 2 and 3
2939 * Params:
2940 * LightStateType: The light state to change
2941 * Value: The value to assign to that light state
2943 * Returns:
2944 * D3D_OK on success
2945 * DDERR_INVALIDPARAMS if the parameters were incorrect
2946 * Also check IDirect3DDevice7::SetRenderState
2948 *****************************************************************************/
2949 static HRESULT WINAPI
2950 IDirect3DDeviceImpl_3_SetLightState(IDirect3DDevice3 *iface,
2951 D3DLIGHTSTATETYPE LightStateType,
2952 DWORD Value)
2954 IDirect3DDeviceImpl *This = device_from_device3(iface);
2955 HRESULT hr;
2957 TRACE("(%p)->(%08x,%08x)\n", This, LightStateType, Value);
2959 if (!LightStateType || (LightStateType > D3DLIGHTSTATE_COLORVERTEX))
2961 TRACE("Unexpected Light State Type\n");
2962 return DDERR_INVALIDPARAMS;
2965 EnterCriticalSection(&ddraw_cs);
2966 if (LightStateType == D3DLIGHTSTATE_MATERIAL /* 1 */)
2968 IDirect3DMaterialImpl *mat;
2970 if(Value == 0) mat = NULL;
2971 else if(Value > This->numHandles)
2973 ERR("Material handle out of range(%d)\n", Value);
2974 LeaveCriticalSection(&ddraw_cs);
2975 return DDERR_INVALIDPARAMS;
2977 else if(This->Handles[Value - 1].type != DDrawHandle_Material)
2979 ERR("Invalid handle %d\n", Value);
2980 LeaveCriticalSection(&ddraw_cs);
2981 return DDERR_INVALIDPARAMS;
2983 else
2985 mat = This->Handles[Value - 1].ptr;
2988 if (mat != NULL)
2990 TRACE(" activating material %p.\n", mat);
2991 mat->activate(mat);
2993 else
2995 FIXME(" D3DLIGHTSTATE_MATERIAL called with NULL material !!!\n");
2997 This->material = Value;
2999 else if (LightStateType == D3DLIGHTSTATE_COLORMODEL /* 3 */)
3001 switch (Value)
3003 case D3DCOLOR_MONO:
3004 ERR("DDCOLOR_MONO should not happen!\n");
3005 break;
3006 case D3DCOLOR_RGB:
3007 /* We are already in this mode */
3008 TRACE("Setting color model to RGB (no-op).\n");
3009 break;
3010 default:
3011 ERR("Unknown color model!\n");
3012 LeaveCriticalSection(&ddraw_cs);
3013 return DDERR_INVALIDPARAMS;
3016 else
3018 D3DRENDERSTATETYPE rs;
3019 switch (LightStateType)
3021 case D3DLIGHTSTATE_AMBIENT: /* 2 */
3022 rs = D3DRENDERSTATE_AMBIENT;
3023 break;
3024 case D3DLIGHTSTATE_FOGMODE: /* 4 */
3025 rs = D3DRENDERSTATE_FOGVERTEXMODE;
3026 break;
3027 case D3DLIGHTSTATE_FOGSTART: /* 5 */
3028 rs = D3DRENDERSTATE_FOGSTART;
3029 break;
3030 case D3DLIGHTSTATE_FOGEND: /* 6 */
3031 rs = D3DRENDERSTATE_FOGEND;
3032 break;
3033 case D3DLIGHTSTATE_FOGDENSITY: /* 7 */
3034 rs = D3DRENDERSTATE_FOGDENSITY;
3035 break;
3036 case D3DLIGHTSTATE_COLORVERTEX: /* 8 */
3037 rs = D3DRENDERSTATE_COLORVERTEX;
3038 break;
3039 default:
3040 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType);
3041 LeaveCriticalSection(&ddraw_cs);
3042 return DDERR_INVALIDPARAMS;
3045 hr = IDirect3DDevice7_SetRenderState((IDirect3DDevice7 *)This, rs, Value);
3046 LeaveCriticalSection(&ddraw_cs);
3047 return hr;
3050 LeaveCriticalSection(&ddraw_cs);
3051 return D3D_OK;
3054 static HRESULT WINAPI
3055 Thunk_IDirect3DDeviceImpl_2_SetLightState(IDirect3DDevice2 *iface,
3056 D3DLIGHTSTATETYPE LightStateType,
3057 DWORD Value)
3059 IDirect3DDeviceImpl *This = device_from_device2(iface);
3060 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x) thunking to IDirect3DDevice3 interface.\n", This, LightStateType, Value);
3061 return IDirect3DDevice3_SetLightState((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, LightStateType, Value);
3064 /*****************************************************************************
3065 * IDirect3DDevice3::GetLightState
3067 * Returns the current setting of a light state. The state is read from
3068 * the Direct3DDevice7 render state.
3070 * Version 2 and 3
3072 * Params:
3073 * LightStateType: The light state to return
3074 * Value: The address to store the light state setting at
3076 * Returns:
3077 * D3D_OK on success
3078 * DDDERR_INVALIDPARAMS if the parameters were incorrect
3079 * Also see IDirect3DDevice7::GetRenderState
3081 *****************************************************************************/
3082 static HRESULT WINAPI
3083 IDirect3DDeviceImpl_3_GetLightState(IDirect3DDevice3 *iface,
3084 D3DLIGHTSTATETYPE LightStateType,
3085 DWORD *Value)
3087 IDirect3DDeviceImpl *This = device_from_device3(iface);
3088 HRESULT hr;
3090 TRACE("(%p)->(%08x,%p)\n", This, LightStateType, Value);
3092 if (!LightStateType || (LightStateType > D3DLIGHTSTATE_COLORVERTEX))
3094 TRACE("Unexpected Light State Type\n");
3095 return DDERR_INVALIDPARAMS;
3098 if(!Value)
3099 return DDERR_INVALIDPARAMS;
3101 EnterCriticalSection(&ddraw_cs);
3102 if (LightStateType == D3DLIGHTSTATE_MATERIAL /* 1 */)
3104 *Value = This->material;
3106 else if (LightStateType == D3DLIGHTSTATE_COLORMODEL /* 3 */)
3108 *Value = D3DCOLOR_RGB;
3110 else
3112 D3DRENDERSTATETYPE rs;
3113 switch (LightStateType)
3115 case D3DLIGHTSTATE_AMBIENT: /* 2 */
3116 rs = D3DRENDERSTATE_AMBIENT;
3117 break;
3118 case D3DLIGHTSTATE_FOGMODE: /* 4 */
3119 rs = D3DRENDERSTATE_FOGVERTEXMODE;
3120 break;
3121 case D3DLIGHTSTATE_FOGSTART: /* 5 */
3122 rs = D3DRENDERSTATE_FOGSTART;
3123 break;
3124 case D3DLIGHTSTATE_FOGEND: /* 6 */
3125 rs = D3DRENDERSTATE_FOGEND;
3126 break;
3127 case D3DLIGHTSTATE_FOGDENSITY: /* 7 */
3128 rs = D3DRENDERSTATE_FOGDENSITY;
3129 break;
3130 case D3DLIGHTSTATE_COLORVERTEX: /* 8 */
3131 rs = D3DRENDERSTATE_COLORVERTEX;
3132 break;
3133 default:
3134 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType);
3135 LeaveCriticalSection(&ddraw_cs);
3136 return DDERR_INVALIDPARAMS;
3139 hr = IDirect3DDevice7_GetRenderState((IDirect3DDevice7 *)This, rs, Value);
3140 LeaveCriticalSection(&ddraw_cs);
3141 return hr;
3144 LeaveCriticalSection(&ddraw_cs);
3145 return D3D_OK;
3148 static HRESULT WINAPI
3149 Thunk_IDirect3DDeviceImpl_2_GetLightState(IDirect3DDevice2 *iface,
3150 D3DLIGHTSTATETYPE LightStateType,
3151 DWORD *Value)
3153 IDirect3DDeviceImpl *This = device_from_device2(iface);
3154 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice3 interface.\n", This, LightStateType, Value);
3155 return IDirect3DDevice3_GetLightState((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, LightStateType, Value);
3158 /*****************************************************************************
3159 * IDirect3DDevice7::SetTransform
3161 * Assigns a D3DMATRIX to a transform type. The transform types are defined
3162 * in include/d3dtypes.h.
3163 * The D3DTRANSFORMSTATE_WORLD (=1) is translated to D3DTS_WORLDMATRIX(0)
3164 * (=255) for wined3d, because the 1 transform state was removed in d3d8
3165 * and WineD3D already understands the replacement D3DTS_WORLDMATRIX(0)
3167 * Version 2, 3 and 7
3169 * Params:
3170 * TransformStateType: transform state to set
3171 * Matrix: Matrix to assign to the state
3173 * Returns:
3174 * D3D_OK on success
3175 * DDERR_INVALIDPARAMS if Matrix == NULL
3176 * For details see IWineD3DDevice::SetTransform
3178 *****************************************************************************/
3179 static HRESULT
3180 IDirect3DDeviceImpl_7_SetTransform(IDirect3DDevice7 *iface,
3181 D3DTRANSFORMSTATETYPE TransformStateType,
3182 D3DMATRIX *Matrix)
3184 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3185 D3DTRANSFORMSTATETYPE type;
3186 HRESULT hr;
3187 TRACE("(%p)->(%08x,%p): Relay\n", This, TransformStateType, Matrix);
3189 switch(TransformStateType)
3191 case D3DTRANSFORMSTATE_WORLD : type = WINED3DTS_WORLDMATRIX(0); break;
3192 case D3DTRANSFORMSTATE_WORLD1: type = WINED3DTS_WORLDMATRIX(1); break;
3193 case D3DTRANSFORMSTATE_WORLD2: type = WINED3DTS_WORLDMATRIX(2); break;
3194 case D3DTRANSFORMSTATE_WORLD3: type = WINED3DTS_WORLDMATRIX(3); break;
3195 default: type = TransformStateType;
3198 if(!Matrix)
3199 return DDERR_INVALIDPARAMS;
3201 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3202 EnterCriticalSection(&ddraw_cs);
3203 hr = IWineD3DDevice_SetTransform(This->wineD3DDevice,
3204 type,
3205 (WINED3DMATRIX*) Matrix);
3206 LeaveCriticalSection(&ddraw_cs);
3207 return hr;
3210 static HRESULT WINAPI
3211 IDirect3DDeviceImpl_7_SetTransform_FPUSetup(IDirect3DDevice7 *iface,
3212 D3DTRANSFORMSTATETYPE TransformStateType,
3213 D3DMATRIX *Matrix)
3215 return IDirect3DDeviceImpl_7_SetTransform(iface, TransformStateType, Matrix);
3218 static HRESULT WINAPI
3219 IDirect3DDeviceImpl_7_SetTransform_FPUPreserve(IDirect3DDevice7 *iface,
3220 D3DTRANSFORMSTATETYPE TransformStateType,
3221 D3DMATRIX *Matrix)
3223 HRESULT hr;
3224 WORD old_fpucw;
3226 old_fpucw = d3d_fpu_setup();
3227 hr = IDirect3DDeviceImpl_7_SetTransform(iface, TransformStateType, Matrix);
3228 set_fpu_control_word(old_fpucw);
3230 return hr;
3233 static HRESULT WINAPI
3234 Thunk_IDirect3DDeviceImpl_3_SetTransform(IDirect3DDevice3 *iface,
3235 D3DTRANSFORMSTATETYPE TransformStateType,
3236 D3DMATRIX *D3DMatrix)
3238 IDirect3DDeviceImpl *This = device_from_device3(iface);
3239 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3240 return IDirect3DDevice7_SetTransform((IDirect3DDevice7 *)This, TransformStateType, D3DMatrix);
3243 static HRESULT WINAPI
3244 Thunk_IDirect3DDeviceImpl_2_SetTransform(IDirect3DDevice2 *iface,
3245 D3DTRANSFORMSTATETYPE TransformStateType,
3246 D3DMATRIX *D3DMatrix)
3248 IDirect3DDeviceImpl *This = device_from_device2(iface);
3249 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3250 return IDirect3DDevice7_SetTransform((IDirect3DDevice7 *)This, TransformStateType, D3DMatrix);
3253 /*****************************************************************************
3254 * IDirect3DDevice7::GetTransform
3256 * Returns the matrix assigned to a transform state
3257 * D3DTRANSFORMSTATE_WORLD is translated to D3DTS_WORLDMATRIX(0), see
3258 * SetTransform
3260 * Params:
3261 * TransformStateType: State to read the matrix from
3262 * Matrix: Address to store the matrix at
3264 * Returns:
3265 * D3D_OK on success
3266 * DDERR_INVALIDPARAMS if Matrix == NULL
3267 * For details, see IWineD3DDevice::GetTransform
3269 *****************************************************************************/
3270 static HRESULT
3271 IDirect3DDeviceImpl_7_GetTransform(IDirect3DDevice7 *iface,
3272 D3DTRANSFORMSTATETYPE TransformStateType,
3273 D3DMATRIX *Matrix)
3275 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3276 D3DTRANSFORMSTATETYPE type;
3277 HRESULT hr;
3278 TRACE("(%p)->(%08x,%p): Relay\n", This, TransformStateType, Matrix);
3280 switch(TransformStateType)
3282 case D3DTRANSFORMSTATE_WORLD : type = WINED3DTS_WORLDMATRIX(0); break;
3283 case D3DTRANSFORMSTATE_WORLD1: type = WINED3DTS_WORLDMATRIX(1); break;
3284 case D3DTRANSFORMSTATE_WORLD2: type = WINED3DTS_WORLDMATRIX(2); break;
3285 case D3DTRANSFORMSTATE_WORLD3: type = WINED3DTS_WORLDMATRIX(3); break;
3286 default: type = TransformStateType;
3289 if(!Matrix)
3290 return DDERR_INVALIDPARAMS;
3292 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3293 EnterCriticalSection(&ddraw_cs);
3294 hr = IWineD3DDevice_GetTransform(This->wineD3DDevice, type, (WINED3DMATRIX*) Matrix);
3295 LeaveCriticalSection(&ddraw_cs);
3296 return hr;
3299 static HRESULT WINAPI
3300 IDirect3DDeviceImpl_7_GetTransform_FPUSetup(IDirect3DDevice7 *iface,
3301 D3DTRANSFORMSTATETYPE TransformStateType,
3302 D3DMATRIX *Matrix)
3304 return IDirect3DDeviceImpl_7_GetTransform(iface, TransformStateType, Matrix);
3307 static HRESULT WINAPI
3308 IDirect3DDeviceImpl_7_GetTransform_FPUPreserve(IDirect3DDevice7 *iface,
3309 D3DTRANSFORMSTATETYPE TransformStateType,
3310 D3DMATRIX *Matrix)
3312 HRESULT hr;
3313 WORD old_fpucw;
3315 old_fpucw = d3d_fpu_setup();
3316 hr = IDirect3DDeviceImpl_7_GetTransform(iface, TransformStateType, Matrix);
3317 set_fpu_control_word(old_fpucw);
3319 return hr;
3322 static HRESULT WINAPI
3323 Thunk_IDirect3DDeviceImpl_3_GetTransform(IDirect3DDevice3 *iface,
3324 D3DTRANSFORMSTATETYPE TransformStateType,
3325 D3DMATRIX *D3DMatrix)
3327 IDirect3DDeviceImpl *This = device_from_device3(iface);
3328 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3329 return IDirect3DDevice7_GetTransform((IDirect3DDevice7 *)This, TransformStateType, D3DMatrix);
3332 static HRESULT WINAPI
3333 Thunk_IDirect3DDeviceImpl_2_GetTransform(IDirect3DDevice2 *iface,
3334 D3DTRANSFORMSTATETYPE TransformStateType,
3335 D3DMATRIX *D3DMatrix)
3337 IDirect3DDeviceImpl *This = device_from_device2(iface);
3338 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3339 return IDirect3DDevice7_GetTransform((IDirect3DDevice7 *)This, TransformStateType, D3DMatrix);
3342 /*****************************************************************************
3343 * IDirect3DDevice7::MultiplyTransform
3345 * Multiplies the already-set transform matrix of a transform state
3346 * with another matrix. For the world matrix, see SetTransform
3348 * Version 2, 3 and 7
3350 * Params:
3351 * TransformStateType: Transform state to multiply
3352 * D3DMatrix Matrix to multiply with.
3354 * Returns
3355 * D3D_OK on success
3356 * DDERR_INVALIDPARAMS if D3DMatrix is NULL
3357 * For details, see IWineD3DDevice::MultiplyTransform
3359 *****************************************************************************/
3360 static HRESULT
3361 IDirect3DDeviceImpl_7_MultiplyTransform(IDirect3DDevice7 *iface,
3362 D3DTRANSFORMSTATETYPE TransformStateType,
3363 D3DMATRIX *D3DMatrix)
3365 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3366 HRESULT hr;
3367 D3DTRANSFORMSTATETYPE type;
3368 TRACE("(%p)->(%08x,%p): Relay\n", This, TransformStateType, D3DMatrix);
3370 switch(TransformStateType)
3372 case D3DTRANSFORMSTATE_WORLD : type = WINED3DTS_WORLDMATRIX(0); break;
3373 case D3DTRANSFORMSTATE_WORLD1: type = WINED3DTS_WORLDMATRIX(1); break;
3374 case D3DTRANSFORMSTATE_WORLD2: type = WINED3DTS_WORLDMATRIX(2); break;
3375 case D3DTRANSFORMSTATE_WORLD3: type = WINED3DTS_WORLDMATRIX(3); break;
3376 default: type = TransformStateType;
3379 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3380 EnterCriticalSection(&ddraw_cs);
3381 hr = IWineD3DDevice_MultiplyTransform(This->wineD3DDevice,
3382 type,
3383 (WINED3DMATRIX*) D3DMatrix);
3384 LeaveCriticalSection(&ddraw_cs);
3385 return hr;
3388 static HRESULT WINAPI
3389 IDirect3DDeviceImpl_7_MultiplyTransform_FPUSetup(IDirect3DDevice7 *iface,
3390 D3DTRANSFORMSTATETYPE TransformStateType,
3391 D3DMATRIX *D3DMatrix)
3393 return IDirect3DDeviceImpl_7_MultiplyTransform(iface, TransformStateType, D3DMatrix);
3396 static HRESULT WINAPI
3397 IDirect3DDeviceImpl_7_MultiplyTransform_FPUPreserve(IDirect3DDevice7 *iface,
3398 D3DTRANSFORMSTATETYPE TransformStateType,
3399 D3DMATRIX *D3DMatrix)
3401 HRESULT hr;
3402 WORD old_fpucw;
3404 old_fpucw = d3d_fpu_setup();
3405 hr = IDirect3DDeviceImpl_7_MultiplyTransform(iface, TransformStateType, D3DMatrix);
3406 set_fpu_control_word(old_fpucw);
3408 return hr;
3411 static HRESULT WINAPI
3412 Thunk_IDirect3DDeviceImpl_3_MultiplyTransform(IDirect3DDevice3 *iface,
3413 D3DTRANSFORMSTATETYPE TransformStateType,
3414 D3DMATRIX *D3DMatrix)
3416 IDirect3DDeviceImpl *This = device_from_device3(iface);
3417 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3418 return IDirect3DDevice7_MultiplyTransform((IDirect3DDevice7 *)This, TransformStateType, D3DMatrix);
3421 static HRESULT WINAPI
3422 Thunk_IDirect3DDeviceImpl_2_MultiplyTransform(IDirect3DDevice2 *iface,
3423 D3DTRANSFORMSTATETYPE TransformStateType,
3424 D3DMATRIX *D3DMatrix)
3426 IDirect3DDeviceImpl *This = device_from_device2(iface);
3427 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3428 return IDirect3DDevice7_MultiplyTransform((IDirect3DDevice7 *)This, TransformStateType, D3DMatrix);
3431 /*****************************************************************************
3432 * IDirect3DDevice7::DrawPrimitive
3434 * Draws primitives based on vertices in an application-provided pointer
3436 * Version 2, 3 and 7. The IDirect3DDevice2 thunk converts the fixed vertex type into
3437 * an FVF format for D3D7
3439 * Params:
3440 * PrimitiveType: The type of the primitives to draw
3441 * Vertex type: Flexible vertex format vertex description
3442 * Vertices: Pointer to the vertex array
3443 * VertexCount: The number of vertices to draw
3444 * Flags: As usual a few flags
3446 * Returns:
3447 * D3D_OK on success
3448 * DDERR_INVALIDPARAMS if Vertices is NULL
3449 * For details, see IWineD3DDevice::DrawPrimitiveUP
3451 *****************************************************************************/
3452 static HRESULT
3453 IDirect3DDeviceImpl_7_DrawPrimitive(IDirect3DDevice7 *iface,
3454 D3DPRIMITIVETYPE PrimitiveType,
3455 DWORD VertexType,
3456 void *Vertices,
3457 DWORD VertexCount,
3458 DWORD Flags)
3460 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3461 UINT stride;
3462 HRESULT hr;
3463 TRACE("(%p)->(%08x,%08x,%p,%08x,%08x): Relay!\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3465 if(!Vertices)
3466 return DDERR_INVALIDPARAMS;
3468 /* Get the stride */
3469 stride = get_flexible_vertex_size(VertexType);
3471 /* Set the FVF */
3472 EnterCriticalSection(&ddraw_cs);
3473 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
3474 IDirectDrawImpl_FindDecl(This->ddraw, VertexType));
3475 if(hr != D3D_OK)
3477 LeaveCriticalSection(&ddraw_cs);
3478 return hr;
3481 /* This method translates to the user pointer draw of WineD3D */
3482 IWineD3DDevice_SetPrimitiveType(This->wineD3DDevice, PrimitiveType);
3483 hr = IWineD3DDevice_DrawPrimitiveUP(This->wineD3DDevice, VertexCount, Vertices, stride);
3484 LeaveCriticalSection(&ddraw_cs);
3485 return hr;
3488 static HRESULT WINAPI
3489 IDirect3DDeviceImpl_7_DrawPrimitive_FPUSetup(IDirect3DDevice7 *iface,
3490 D3DPRIMITIVETYPE PrimitiveType,
3491 DWORD VertexType,
3492 void *Vertices,
3493 DWORD VertexCount,
3494 DWORD Flags)
3496 return IDirect3DDeviceImpl_7_DrawPrimitive(iface, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3499 static HRESULT WINAPI
3500 IDirect3DDeviceImpl_7_DrawPrimitive_FPUPreserve(IDirect3DDevice7 *iface,
3501 D3DPRIMITIVETYPE PrimitiveType,
3502 DWORD VertexType,
3503 void *Vertices,
3504 DWORD VertexCount,
3505 DWORD Flags)
3507 HRESULT hr;
3508 WORD old_fpucw;
3510 old_fpucw = d3d_fpu_setup();
3511 hr = IDirect3DDeviceImpl_7_DrawPrimitive(iface, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3512 set_fpu_control_word(old_fpucw);
3514 return hr;
3517 static HRESULT WINAPI
3518 Thunk_IDirect3DDeviceImpl_3_DrawPrimitive(IDirect3DDevice3 *iface,
3519 D3DPRIMITIVETYPE PrimitiveType,
3520 DWORD VertexType,
3521 void *Vertices,
3522 DWORD VertexCount,
3523 DWORD Flags)
3525 IDirect3DDeviceImpl *This = device_from_device3(iface);
3526 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3527 return IDirect3DDevice7_DrawPrimitive((IDirect3DDevice7 *)This,
3528 PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3531 static HRESULT WINAPI
3532 Thunk_IDirect3DDeviceImpl_2_DrawPrimitive(IDirect3DDevice2 *iface,
3533 D3DPRIMITIVETYPE PrimitiveType,
3534 D3DVERTEXTYPE VertexType,
3535 void *Vertices,
3536 DWORD VertexCount,
3537 DWORD Flags)
3539 IDirect3DDeviceImpl *This = device_from_device2(iface);
3540 DWORD FVF;
3541 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3543 switch(VertexType)
3545 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
3546 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
3547 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
3548 default:
3549 ERR("Unexpected vertex type %d\n", VertexType);
3550 return DDERR_INVALIDPARAMS; /* Should never happen */
3553 return IDirect3DDevice7_DrawPrimitive((IDirect3DDevice7 *)This, PrimitiveType, FVF, Vertices, VertexCount, Flags);
3556 /*****************************************************************************
3557 * IDirect3DDevice7::DrawIndexedPrimitive
3559 * Draws vertices from an application-provided pointer, based on the index
3560 * numbers in a WORD array.
3562 * Version 2, 3 and 7. The version 7 thunk translates the vertex type into
3563 * an FVF format for D3D7
3565 * Params:
3566 * PrimitiveType: The primitive type to draw
3567 * VertexType: The FVF vertex description
3568 * Vertices: Pointer to the vertex array
3569 * VertexCount: ?
3570 * Indices: Pointer to the index array
3571 * IndexCount: Number of indices = Number of vertices to draw
3572 * Flags: As usual, some flags
3574 * Returns:
3575 * D3D_OK on success
3576 * DDERR_INVALIDPARAMS if Vertices or Indices is NULL
3577 * For details, see IWineD3DDevice::DrawIndexedPrimitiveUP
3579 *****************************************************************************/
3580 static HRESULT
3581 IDirect3DDeviceImpl_7_DrawIndexedPrimitive(IDirect3DDevice7 *iface,
3582 D3DPRIMITIVETYPE PrimitiveType,
3583 DWORD VertexType,
3584 void *Vertices,
3585 DWORD VertexCount,
3586 WORD *Indices,
3587 DWORD IndexCount,
3588 DWORD Flags)
3590 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3591 HRESULT hr;
3592 TRACE("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x): Relay!\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3594 /* Set the D3DDevice's FVF */
3595 EnterCriticalSection(&ddraw_cs);
3596 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
3597 IDirectDrawImpl_FindDecl(This->ddraw, VertexType));
3598 if(FAILED(hr))
3600 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr);
3601 LeaveCriticalSection(&ddraw_cs);
3602 return hr;
3605 IWineD3DDevice_SetPrimitiveType(This->wineD3DDevice, PrimitiveType);
3606 hr = IWineD3DDevice_DrawIndexedPrimitiveUP(This->wineD3DDevice, IndexCount, Indices,
3607 WINED3DFMT_R16_UINT, Vertices, get_flexible_vertex_size(VertexType));
3608 LeaveCriticalSection(&ddraw_cs);
3609 return hr;
3612 static HRESULT WINAPI
3613 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUSetup(IDirect3DDevice7 *iface,
3614 D3DPRIMITIVETYPE PrimitiveType,
3615 DWORD VertexType,
3616 void *Vertices,
3617 DWORD VertexCount,
3618 WORD *Indices,
3619 DWORD IndexCount,
3620 DWORD Flags)
3622 return IDirect3DDeviceImpl_7_DrawIndexedPrimitive(iface, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3625 static HRESULT WINAPI
3626 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUPreserve(IDirect3DDevice7 *iface,
3627 D3DPRIMITIVETYPE PrimitiveType,
3628 DWORD VertexType,
3629 void *Vertices,
3630 DWORD VertexCount,
3631 WORD *Indices,
3632 DWORD IndexCount,
3633 DWORD Flags)
3635 HRESULT hr;
3636 WORD old_fpucw;
3638 old_fpucw = d3d_fpu_setup();
3639 hr = IDirect3DDeviceImpl_7_DrawIndexedPrimitive(iface, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3640 set_fpu_control_word(old_fpucw);
3642 return hr;
3645 static HRESULT WINAPI
3646 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive(IDirect3DDevice3 *iface,
3647 D3DPRIMITIVETYPE PrimitiveType,
3648 DWORD VertexType,
3649 void *Vertices,
3650 DWORD VertexCount,
3651 WORD *Indices,
3652 DWORD IndexCount,
3653 DWORD Flags)
3655 IDirect3DDeviceImpl *This = device_from_device3(iface);
3656 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3657 return IDirect3DDevice7_DrawIndexedPrimitive((IDirect3DDevice7 *)This,
3658 PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3661 static HRESULT WINAPI
3662 Thunk_IDirect3DDeviceImpl_2_DrawIndexedPrimitive(IDirect3DDevice2 *iface,
3663 D3DPRIMITIVETYPE PrimitiveType,
3664 D3DVERTEXTYPE VertexType,
3665 void *Vertices,
3666 DWORD VertexCount,
3667 WORD *Indices,
3668 DWORD IndexCount,
3669 DWORD Flags)
3671 DWORD FVF;
3672 IDirect3DDeviceImpl *This = device_from_device2(iface);
3673 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3675 switch(VertexType)
3677 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
3678 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
3679 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
3680 default:
3681 ERR("Unexpected vertex type %d\n", VertexType);
3682 return DDERR_INVALIDPARAMS; /* Should never happen */
3685 return IDirect3DDevice7_DrawIndexedPrimitive((IDirect3DDevice7 *)This,
3686 PrimitiveType, FVF, Vertices, VertexCount, Indices, IndexCount, Flags);
3689 /*****************************************************************************
3690 * IDirect3DDevice7::SetClipStatus
3692 * Sets the clip status. This defines things as clipping conditions and
3693 * the extents of the clipping region.
3695 * Version 2, 3 and 7
3697 * Params:
3698 * ClipStatus:
3700 * Returns:
3701 * D3D_OK because it's a stub
3702 * (DDERR_INVALIDPARAMS if ClipStatus == NULL)
3704 *****************************************************************************/
3705 static HRESULT WINAPI
3706 IDirect3DDeviceImpl_7_SetClipStatus(IDirect3DDevice7 *iface,
3707 D3DCLIPSTATUS *ClipStatus)
3709 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3710 FIXME("(%p)->(%p): Stub!\n", This, ClipStatus);
3712 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them
3713 * Perhaps this needs a new data type and an additional IWineD3DDevice method
3715 /* return IWineD3DDevice_SetClipStatus(This->wineD3DDevice, ClipStatus);*/
3716 return D3D_OK;
3719 static HRESULT WINAPI
3720 Thunk_IDirect3DDeviceImpl_3_SetClipStatus(IDirect3DDevice3 *iface,
3721 D3DCLIPSTATUS *ClipStatus)
3723 IDirect3DDeviceImpl *This = device_from_device3(iface);
3724 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3725 return IDirect3DDevice7_SetClipStatus((IDirect3DDevice7 *)This, ClipStatus);
3728 static HRESULT WINAPI
3729 Thunk_IDirect3DDeviceImpl_2_SetClipStatus(IDirect3DDevice2 *iface,
3730 D3DCLIPSTATUS *ClipStatus)
3732 IDirect3DDeviceImpl *This = device_from_device2(iface);
3733 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3734 return IDirect3DDevice7_SetClipStatus((IDirect3DDevice7 *)This, ClipStatus);
3737 /*****************************************************************************
3738 * IDirect3DDevice7::GetClipStatus
3740 * Returns the clip status
3742 * Params:
3743 * ClipStatus: Address to write the clip status to
3745 * Returns:
3746 * D3D_OK because it's a stub
3748 *****************************************************************************/
3749 static HRESULT WINAPI
3750 IDirect3DDeviceImpl_7_GetClipStatus(IDirect3DDevice7 *iface,
3751 D3DCLIPSTATUS *ClipStatus)
3753 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3754 FIXME("(%p)->(%p): Stub!\n", This, ClipStatus);
3756 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them */
3757 /* return IWineD3DDevice_GetClipStatus(This->wineD3DDevice, ClipStatus);*/
3758 return D3D_OK;
3761 static HRESULT WINAPI
3762 Thunk_IDirect3DDeviceImpl_3_GetClipStatus(IDirect3DDevice3 *iface,
3763 D3DCLIPSTATUS *ClipStatus)
3765 IDirect3DDeviceImpl *This = device_from_device3(iface);
3766 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3767 return IDirect3DDevice7_GetClipStatus((IDirect3DDevice7 *)This, ClipStatus);
3770 static HRESULT WINAPI
3771 Thunk_IDirect3DDeviceImpl_2_GetClipStatus(IDirect3DDevice2 *iface,
3772 D3DCLIPSTATUS *ClipStatus)
3774 IDirect3DDeviceImpl *This = device_from_device2(iface);
3775 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3776 return IDirect3DDevice7_GetClipStatus((IDirect3DDevice7 *)This, ClipStatus);
3779 /*****************************************************************************
3780 * IDirect3DDevice::DrawPrimitiveStrided
3782 * Draws vertices described by a D3DDRAWPRIMITIVESTRIDEDDATA structure.
3784 * Version 3 and 7
3786 * Params:
3787 * PrimitiveType: The primitive type to draw
3788 * VertexType: The FVF description of the vertices to draw (for the stride??)
3789 * D3DDrawPrimStrideData: A D3DDRAWPRIMITIVESTRIDEDDATA structure describing
3790 * the vertex data locations
3791 * VertexCount: The number of vertices to draw
3792 * Flags: Some flags
3794 * Returns:
3795 * D3D_OK, because it's a stub
3796 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
3797 * (For details, see IWineD3DDevice::DrawPrimitiveStrided)
3799 *****************************************************************************/
3800 static HRESULT
3801 IDirect3DDeviceImpl_7_DrawPrimitiveStrided(IDirect3DDevice7 *iface,
3802 D3DPRIMITIVETYPE PrimitiveType,
3803 DWORD VertexType,
3804 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3805 DWORD VertexCount,
3806 DWORD Flags)
3808 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3809 WineDirect3DVertexStridedData WineD3DStrided;
3810 DWORD i;
3811 HRESULT hr;
3813 TRACE("(%p)->(%08x,%08x,%p,%08x,%08x): stub!\n", This, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
3815 memset(&WineD3DStrided, 0, sizeof(WineD3DStrided));
3816 /* Get the strided data right. the wined3d structure is a bit bigger
3817 * Watch out: The contents of the strided data are determined by the fvf,
3818 * not by the members set in D3DDrawPrimStrideData. So it's valid
3819 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
3820 * not set in the fvf.
3822 if(VertexType & D3DFVF_POSITION_MASK)
3824 WineD3DStrided.position.format = WINED3DFMT_R32G32B32_FLOAT;
3825 WineD3DStrided.position.lpData = D3DDrawPrimStrideData->position.lpvData;
3826 WineD3DStrided.position.dwStride = D3DDrawPrimStrideData->position.dwStride;
3827 if (VertexType & D3DFVF_XYZRHW)
3829 WineD3DStrided.position.format = WINED3DFMT_R32G32B32A32_FLOAT;
3830 WineD3DStrided.position_transformed = TRUE;
3831 } else
3832 WineD3DStrided.position_transformed = FALSE;
3835 if(VertexType & D3DFVF_NORMAL)
3837 WineD3DStrided.normal.format = WINED3DFMT_R32G32B32_FLOAT;
3838 WineD3DStrided.normal.lpData = D3DDrawPrimStrideData->normal.lpvData;
3839 WineD3DStrided.normal.dwStride = D3DDrawPrimStrideData->normal.dwStride;
3842 if(VertexType & D3DFVF_DIFFUSE)
3844 WineD3DStrided.diffuse.format = WINED3DFMT_B8G8R8A8_UNORM;
3845 WineD3DStrided.diffuse.lpData = D3DDrawPrimStrideData->diffuse.lpvData;
3846 WineD3DStrided.diffuse.dwStride = D3DDrawPrimStrideData->diffuse.dwStride;
3849 if(VertexType & D3DFVF_SPECULAR)
3851 WineD3DStrided.specular.format = WINED3DFMT_B8G8R8A8_UNORM;
3852 WineD3DStrided.specular.lpData = D3DDrawPrimStrideData->specular.lpvData;
3853 WineD3DStrided.specular.dwStride = D3DDrawPrimStrideData->specular.dwStride;
3856 for( i = 0; i < GET_TEXCOUNT_FROM_FVF(VertexType); i++)
3858 switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i))
3860 case 1: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32_FLOAT; break;
3861 case 2: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32G32_FLOAT; break;
3862 case 3: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32G32B32_FLOAT; break;
3863 case 4: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32G32B32A32_FLOAT; break;
3864 default: ERR("Unexpected texture coordinate size %d\n",
3865 GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i));
3867 WineD3DStrided.texCoords[i].lpData = D3DDrawPrimStrideData->textureCoords[i].lpvData;
3868 WineD3DStrided.texCoords[i].dwStride = D3DDrawPrimStrideData->textureCoords[i].dwStride;
3871 /* WineD3D doesn't need the FVF here */
3872 EnterCriticalSection(&ddraw_cs);
3873 IWineD3DDevice_SetPrimitiveType(This->wineD3DDevice, PrimitiveType);
3874 hr = IWineD3DDevice_DrawPrimitiveStrided(This->wineD3DDevice, VertexCount, &WineD3DStrided);
3875 LeaveCriticalSection(&ddraw_cs);
3876 return hr;
3879 static HRESULT WINAPI
3880 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUSetup(IDirect3DDevice7 *iface,
3881 D3DPRIMITIVETYPE PrimitiveType,
3882 DWORD VertexType,
3883 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3884 DWORD VertexCount,
3885 DWORD Flags)
3887 return IDirect3DDeviceImpl_7_DrawPrimitiveStrided(iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
3890 static HRESULT WINAPI
3891 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUPreserve(IDirect3DDevice7 *iface,
3892 D3DPRIMITIVETYPE PrimitiveType,
3893 DWORD VertexType,
3894 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3895 DWORD VertexCount,
3896 DWORD Flags)
3898 HRESULT hr;
3899 WORD old_fpucw;
3901 old_fpucw = d3d_fpu_setup();
3902 hr = IDirect3DDeviceImpl_7_DrawPrimitiveStrided(iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
3903 set_fpu_control_word(old_fpucw);
3905 return hr;
3908 static HRESULT WINAPI
3909 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided(IDirect3DDevice3 *iface,
3910 D3DPRIMITIVETYPE PrimitiveType,
3911 DWORD VertexType,
3912 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3913 DWORD VertexCount,
3914 DWORD Flags)
3916 IDirect3DDeviceImpl *This = device_from_device3(iface);
3917 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
3918 return IDirect3DDevice7_DrawPrimitiveStrided((IDirect3DDevice7 *)This,
3919 PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
3922 /*****************************************************************************
3923 * IDirect3DDevice7::DrawIndexedPrimitiveStrided
3925 * Draws primitives specified by strided data locations based on indices
3927 * Version 3 and 7
3929 * Params:
3930 * PrimitiveType:
3932 * Returns:
3933 * D3D_OK, because it's a stub
3934 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
3935 * (DDERR_INVALIDPARAMS if Indices is NULL)
3936 * (For more details, see IWineD3DDevice::DrawIndexedPrimitiveStrided)
3938 *****************************************************************************/
3939 static HRESULT
3940 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(IDirect3DDevice7 *iface,
3941 D3DPRIMITIVETYPE PrimitiveType,
3942 DWORD VertexType,
3943 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3944 DWORD VertexCount,
3945 WORD *Indices,
3946 DWORD IndexCount,
3947 DWORD Flags)
3949 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3950 WineDirect3DVertexStridedData WineD3DStrided;
3951 DWORD i;
3952 HRESULT hr;
3954 TRACE("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x)\n", This, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
3956 memset(&WineD3DStrided, 0, sizeof(WineD3DStrided));
3957 /* Get the strided data right. the wined3d structure is a bit bigger
3958 * Watch out: The contents of the strided data are determined by the fvf,
3959 * not by the members set in D3DDrawPrimStrideData. So it's valid
3960 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
3961 * not set in the fvf.
3963 if(VertexType & D3DFVF_POSITION_MASK)
3965 WineD3DStrided.position.format = WINED3DFMT_R32G32B32_FLOAT;
3966 WineD3DStrided.position.lpData = D3DDrawPrimStrideData->position.lpvData;
3967 WineD3DStrided.position.dwStride = D3DDrawPrimStrideData->position.dwStride;
3968 if (VertexType & D3DFVF_XYZRHW)
3970 WineD3DStrided.position.format = WINED3DFMT_R32G32B32A32_FLOAT;
3971 WineD3DStrided.position_transformed = TRUE;
3972 } else
3973 WineD3DStrided.position_transformed = FALSE;
3976 if(VertexType & D3DFVF_NORMAL)
3978 WineD3DStrided.normal.format = WINED3DFMT_R32G32B32_FLOAT;
3979 WineD3DStrided.normal.lpData = D3DDrawPrimStrideData->normal.lpvData;
3980 WineD3DStrided.normal.dwStride = D3DDrawPrimStrideData->normal.dwStride;
3983 if(VertexType & D3DFVF_DIFFUSE)
3985 WineD3DStrided.diffuse.format = WINED3DFMT_B8G8R8A8_UNORM;
3986 WineD3DStrided.diffuse.lpData = D3DDrawPrimStrideData->diffuse.lpvData;
3987 WineD3DStrided.diffuse.dwStride = D3DDrawPrimStrideData->diffuse.dwStride;
3990 if(VertexType & D3DFVF_SPECULAR)
3992 WineD3DStrided.specular.format = WINED3DFMT_B8G8R8A8_UNORM;
3993 WineD3DStrided.specular.lpData = D3DDrawPrimStrideData->specular.lpvData;
3994 WineD3DStrided.specular.dwStride = D3DDrawPrimStrideData->specular.dwStride;
3997 for( i = 0; i < GET_TEXCOUNT_FROM_FVF(VertexType); i++)
3999 switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i))
4001 case 1: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32_FLOAT; break;
4002 case 2: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32G32_FLOAT; break;
4003 case 3: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32G32B32_FLOAT; break;
4004 case 4: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32G32B32A32_FLOAT; break;
4005 default: ERR("Unexpected texture coordinate size %d\n",
4006 GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i));
4008 WineD3DStrided.texCoords[i].lpData = D3DDrawPrimStrideData->textureCoords[i].lpvData;
4009 WineD3DStrided.texCoords[i].dwStride = D3DDrawPrimStrideData->textureCoords[i].dwStride;
4012 /* WineD3D doesn't need the FVF here */
4013 EnterCriticalSection(&ddraw_cs);
4014 IWineD3DDevice_SetPrimitiveType(This->wineD3DDevice, PrimitiveType);
4015 hr = IWineD3DDevice_DrawIndexedPrimitiveStrided(This->wineD3DDevice,
4016 IndexCount, &WineD3DStrided, VertexCount, Indices, WINED3DFMT_R16_UINT);
4017 LeaveCriticalSection(&ddraw_cs);
4018 return hr;
4021 static HRESULT WINAPI
4022 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUSetup(IDirect3DDevice7 *iface,
4023 D3DPRIMITIVETYPE PrimitiveType,
4024 DWORD VertexType,
4025 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
4026 DWORD VertexCount,
4027 WORD *Indices,
4028 DWORD IndexCount,
4029 DWORD Flags)
4031 return IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
4034 static HRESULT WINAPI
4035 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUPreserve(IDirect3DDevice7 *iface,
4036 D3DPRIMITIVETYPE PrimitiveType,
4037 DWORD VertexType,
4038 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
4039 DWORD VertexCount,
4040 WORD *Indices,
4041 DWORD IndexCount,
4042 DWORD Flags)
4044 HRESULT hr;
4045 WORD old_fpucw;
4047 old_fpucw = d3d_fpu_setup();
4048 hr = IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
4049 set_fpu_control_word(old_fpucw);
4051 return hr;
4054 static HRESULT WINAPI
4055 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided(IDirect3DDevice3 *iface,
4056 D3DPRIMITIVETYPE PrimitiveType,
4057 DWORD VertexType,
4058 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
4059 DWORD VertexCount,
4060 WORD *Indices,
4061 DWORD IndexCount,
4062 DWORD Flags)
4064 IDirect3DDeviceImpl *This = device_from_device3(iface);
4065 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
4066 return IDirect3DDevice7_DrawIndexedPrimitiveStrided((IDirect3DDevice7 *)This, PrimitiveType,
4067 VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
4070 /*****************************************************************************
4071 * IDirect3DDevice7::DrawPrimitiveVB
4073 * Draws primitives from a vertex buffer to the screen.
4075 * Version 3 and 7
4077 * Params:
4078 * PrimitiveType: Type of primitive to be rendered.
4079 * D3DVertexBuf: Source Vertex Buffer
4080 * StartVertex: Index of the first vertex from the buffer to be rendered
4081 * NumVertices: Number of vertices to be rendered
4082 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4084 * Return values
4085 * D3D_OK on success
4086 * DDERR_INVALIDPARAMS if D3DVertexBuf is NULL
4088 *****************************************************************************/
4089 static HRESULT
4090 IDirect3DDeviceImpl_7_DrawPrimitiveVB(IDirect3DDevice7 *iface,
4091 D3DPRIMITIVETYPE PrimitiveType,
4092 IDirect3DVertexBuffer7 *D3DVertexBuf,
4093 DWORD StartVertex,
4094 DWORD NumVertices,
4095 DWORD Flags)
4097 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
4098 IDirect3DVertexBufferImpl *vb = (IDirect3DVertexBufferImpl *)D3DVertexBuf;
4099 HRESULT hr;
4100 DWORD stride;
4102 TRACE("(%p)->(%08x,%p,%08x,%08x,%08x)\n", This, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags);
4104 /* Sanity checks */
4105 if(!vb)
4107 ERR("(%p) No Vertex buffer specified\n", This);
4108 return DDERR_INVALIDPARAMS;
4110 stride = get_flexible_vertex_size(vb->fvf);
4112 EnterCriticalSection(&ddraw_cs);
4113 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
4114 vb->wineD3DVertexDeclaration);
4115 if(FAILED(hr))
4117 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr);
4118 LeaveCriticalSection(&ddraw_cs);
4119 return hr;
4122 /* Set the vertex stream source */
4123 hr = IWineD3DDevice_SetStreamSource(This->wineD3DDevice,
4124 0 /* StreamNumber */,
4125 vb->wineD3DVertexBuffer,
4126 0 /* StartVertex - we pass this to DrawPrimitive */,
4127 stride);
4128 if(hr != D3D_OK)
4130 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This, hr);
4131 LeaveCriticalSection(&ddraw_cs);
4132 return hr;
4135 /* Now draw the primitives */
4136 IWineD3DDevice_SetPrimitiveType(This->wineD3DDevice, PrimitiveType);
4137 hr = IWineD3DDevice_DrawPrimitive(This->wineD3DDevice, StartVertex, NumVertices);
4138 LeaveCriticalSection(&ddraw_cs);
4139 return hr;
4142 static HRESULT WINAPI
4143 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUSetup(IDirect3DDevice7 *iface,
4144 D3DPRIMITIVETYPE PrimitiveType,
4145 IDirect3DVertexBuffer7 *D3DVertexBuf,
4146 DWORD StartVertex,
4147 DWORD NumVertices,
4148 DWORD Flags)
4150 return IDirect3DDeviceImpl_7_DrawPrimitiveVB(iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags);
4153 static HRESULT WINAPI
4154 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUPreserve(IDirect3DDevice7 *iface,
4155 D3DPRIMITIVETYPE PrimitiveType,
4156 IDirect3DVertexBuffer7 *D3DVertexBuf,
4157 DWORD StartVertex,
4158 DWORD NumVertices,
4159 DWORD Flags)
4161 HRESULT hr;
4162 WORD old_fpucw;
4164 old_fpucw = d3d_fpu_setup();
4165 hr = IDirect3DDeviceImpl_7_DrawPrimitiveVB(iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags);
4166 set_fpu_control_word(old_fpucw);
4168 return hr;
4171 static HRESULT WINAPI
4172 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB(IDirect3DDevice3 *iface,
4173 D3DPRIMITIVETYPE PrimitiveType,
4174 IDirect3DVertexBuffer *D3DVertexBuf,
4175 DWORD StartVertex,
4176 DWORD NumVertices,
4177 DWORD Flags)
4179 IDirect3DDeviceImpl *This = device_from_device3(iface);
4180 IDirect3DVertexBufferImpl *vb = D3DVertexBuf ? vb_from_vb1(D3DVertexBuf) : NULL;
4181 TRACE_(ddraw_thunk)("(%p)->(%08x,%p,%08x,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, vb, StartVertex, NumVertices, Flags);
4182 return IDirect3DDevice7_DrawPrimitiveVB((IDirect3DDevice7 *)This, PrimitiveType,
4183 (IDirect3DVertexBuffer7 *)vb, StartVertex, NumVertices, Flags);
4187 /*****************************************************************************
4188 * IDirect3DDevice7::DrawIndexedPrimitiveVB
4190 * Draws primitives from a vertex buffer to the screen
4192 * Params:
4193 * PrimitiveType: Type of primitive to be rendered.
4194 * D3DVertexBuf: Source Vertex Buffer
4195 * StartVertex: Index of the first vertex from the buffer to be rendered
4196 * NumVertices: Number of vertices to be rendered
4197 * Indices: Array of DWORDs used to index into the Vertices
4198 * IndexCount: Number of indices in Indices
4199 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4201 * Return values
4203 *****************************************************************************/
4204 static HRESULT
4205 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(IDirect3DDevice7 *iface,
4206 D3DPRIMITIVETYPE PrimitiveType,
4207 IDirect3DVertexBuffer7 *D3DVertexBuf,
4208 DWORD StartVertex,
4209 DWORD NumVertices,
4210 WORD *Indices,
4211 DWORD IndexCount,
4212 DWORD Flags)
4214 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
4215 IDirect3DVertexBufferImpl *vb = (IDirect3DVertexBufferImpl *)D3DVertexBuf;
4216 DWORD stride = get_flexible_vertex_size(vb->fvf);
4217 WORD *LockedIndices;
4218 HRESULT hr;
4220 TRACE("(%p)->(%08x,%p,%d,%d,%p,%d,%08x)\n", This, PrimitiveType, vb, StartVertex, NumVertices, Indices, IndexCount, Flags);
4222 /* Steps:
4223 * 1) Upload the Indices to the index buffer
4224 * 2) Set the index source
4225 * 3) Set the Vertex Buffer as the Stream source
4226 * 4) Call IWineD3DDevice::DrawIndexedPrimitive
4229 EnterCriticalSection(&ddraw_cs);
4231 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
4232 vb->wineD3DVertexDeclaration);
4233 if(FAILED(hr))
4235 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr);
4236 LeaveCriticalSection(&ddraw_cs);
4237 return hr;
4240 /* copy the index stream into the index buffer.
4241 * A new IWineD3DDevice method could be created
4242 * which takes an user pointer containing the indices
4243 * or a SetData-Method for the index buffer, which
4244 * overrides the index buffer data with our pointer.
4246 hr = IWineD3DBuffer_Map(This->indexbuffer,
4247 0 /* OffSetToLock */,
4248 IndexCount * sizeof(WORD),
4249 (BYTE **) &LockedIndices,
4250 0 /* Flags */);
4251 assert(IndexCount < 0x100000);
4252 if(hr != D3D_OK)
4254 ERR("(%p) IWineD3DBuffer::Map failed with hr = %08x\n", This, hr);
4255 LeaveCriticalSection(&ddraw_cs);
4256 return hr;
4258 memcpy(LockedIndices, Indices, IndexCount * sizeof(WORD));
4259 hr = IWineD3DBuffer_Unmap(This->indexbuffer);
4260 if(hr != D3D_OK)
4262 ERR("(%p) IWineD3DBuffer::Unmap failed with hr = %08x\n", This, hr);
4263 LeaveCriticalSection(&ddraw_cs);
4264 return hr;
4267 /* Set the index stream */
4268 IWineD3DDevice_SetBaseVertexIndex(This->wineD3DDevice, StartVertex);
4269 hr = IWineD3DDevice_SetIndexBuffer(This->wineD3DDevice, This->indexbuffer,
4270 WINED3DFMT_R16_UINT);
4272 /* Set the vertex stream source */
4273 hr = IWineD3DDevice_SetStreamSource(This->wineD3DDevice,
4274 0 /* StreamNumber */,
4275 vb->wineD3DVertexBuffer,
4276 0 /* offset, we pass this to DrawIndexedPrimitive */,
4277 stride);
4278 if(hr != D3D_OK)
4280 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This, hr);
4281 LeaveCriticalSection(&ddraw_cs);
4282 return hr;
4286 IWineD3DDevice_SetPrimitiveType(This->wineD3DDevice, PrimitiveType);
4287 hr = IWineD3DDevice_DrawIndexedPrimitive(This->wineD3DDevice, 0 /* StartIndex */, IndexCount);
4289 LeaveCriticalSection(&ddraw_cs);
4290 return hr;
4293 static HRESULT WINAPI
4294 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUSetup(IDirect3DDevice7 *iface,
4295 D3DPRIMITIVETYPE PrimitiveType,
4296 IDirect3DVertexBuffer7 *D3DVertexBuf,
4297 DWORD StartVertex,
4298 DWORD NumVertices,
4299 WORD *Indices,
4300 DWORD IndexCount,
4301 DWORD Flags)
4303 return IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Indices, IndexCount, Flags);
4306 static HRESULT WINAPI
4307 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUPreserve(IDirect3DDevice7 *iface,
4308 D3DPRIMITIVETYPE PrimitiveType,
4309 IDirect3DVertexBuffer7 *D3DVertexBuf,
4310 DWORD StartVertex,
4311 DWORD NumVertices,
4312 WORD *Indices,
4313 DWORD IndexCount,
4314 DWORD Flags)
4316 HRESULT hr;
4317 WORD old_fpucw;
4319 old_fpucw = d3d_fpu_setup();
4320 hr = IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Indices, IndexCount, Flags);
4321 set_fpu_control_word(old_fpucw);
4323 return hr;
4326 static HRESULT WINAPI
4327 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB(IDirect3DDevice3 *iface,
4328 D3DPRIMITIVETYPE PrimitiveType,
4329 IDirect3DVertexBuffer *D3DVertexBuf,
4330 WORD *Indices,
4331 DWORD IndexCount,
4332 DWORD Flags)
4334 IDirect3DDeviceImpl *This = device_from_device3(iface);
4335 IDirect3DVertexBufferImpl *VB = vb_from_vb1(D3DVertexBuf);
4336 TRACE_(ddraw_thunk)("(%p)->(%08x,%p,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VB, Indices, IndexCount, Flags);
4338 return IDirect3DDevice7_DrawIndexedPrimitiveVB((IDirect3DDevice7 *)This, PrimitiveType,
4339 (IDirect3DVertexBuffer7 *)VB, 0, IndexCount, Indices, IndexCount, Flags);
4342 /*****************************************************************************
4343 * IDirect3DDevice7::ComputeSphereVisibility
4345 * Calculates the visibility of spheres in the current viewport. The spheres
4346 * are passed in the Centers and Radii arrays, the results are passed back
4347 * in the ReturnValues array. Return values are either completely visible,
4348 * partially visible or completely invisible.
4349 * The return value consist of a combination of D3DCLIP_* flags, or it's
4350 * 0 if the sphere is completely visible(according to the SDK, not checked)
4352 * Version 3 and 7
4354 * Params:
4355 * Centers: Array containing the sphere centers
4356 * Radii: Array containing the sphere radii
4357 * NumSpheres: The number of centers and radii in the arrays
4358 * Flags: Some flags
4359 * ReturnValues: Array to write the results to
4361 * Returns:
4362 * D3D_OK
4363 * (DDERR_INVALIDPARAMS if Centers, Radii or ReturnValues are NULL)
4364 * (D3DERR_INVALIDMATRIX if the combined world, view and proj matrix
4365 * is singular)
4367 *****************************************************************************/
4369 static DWORD in_plane(UINT plane, D3DVECTOR normal, D3DVALUE origin_plane, D3DVECTOR center, D3DVALUE radius)
4371 float distance, norm;
4373 norm = sqrt( normal.u1.x * normal.u1.x + normal.u2.y * normal.u2.y + normal.u3.z * normal.u3.z );
4374 distance = ( origin_plane + normal.u1.x * center.u1.x + normal.u2.y * center.u2.y + normal.u3.z * center.u3.z ) / norm;
4376 if ( fabs( distance ) < radius ) return D3DSTATUS_CLIPUNIONLEFT << plane;
4377 if ( distance < -radius ) return (D3DSTATUS_CLIPUNIONLEFT | D3DSTATUS_CLIPINTERSECTIONLEFT) << plane;
4378 return 0;
4381 static HRESULT WINAPI
4382 IDirect3DDeviceImpl_7_ComputeSphereVisibility(IDirect3DDevice7 *iface,
4383 D3DVECTOR *Centers,
4384 D3DVALUE *Radii,
4385 DWORD NumSpheres,
4386 DWORD Flags,
4387 DWORD *ReturnValues)
4389 D3DMATRIX m, temp;
4390 D3DVALUE origin_plane[6];
4391 D3DVECTOR vec[6];
4392 HRESULT hr;
4393 UINT i, j;
4395 TRACE("(%p)->(%p,%p,%08x,%08x,%p)\n", iface, Centers, Radii, NumSpheres, Flags, ReturnValues);
4397 hr = IDirect3DDeviceImpl_7_GetTransform(iface, D3DTRANSFORMSTATE_WORLD, &m);
4398 if ( hr != DD_OK ) return DDERR_INVALIDPARAMS;
4399 hr = IDirect3DDeviceImpl_7_GetTransform(iface, D3DTRANSFORMSTATE_VIEW, &temp);
4400 if ( hr != DD_OK ) return DDERR_INVALIDPARAMS;
4401 multiply_matrix_D3D_way(&m, &m, &temp);
4403 hr = IDirect3DDeviceImpl_7_GetTransform(iface, D3DTRANSFORMSTATE_PROJECTION, &temp);
4404 if ( hr != DD_OK ) return DDERR_INVALIDPARAMS;
4405 multiply_matrix_D3D_way(&m, &m, &temp);
4407 /* Left plane */
4408 vec[0].u1.x = m._14 + m._11;
4409 vec[0].u2.y = m._24 + m._21;
4410 vec[0].u3.z = m._34 + m._31;
4411 origin_plane[0] = m._44 + m._41;
4413 /* Right plane */
4414 vec[1].u1.x = m._14 - m._11;
4415 vec[1].u2.y = m._24 - m._21;
4416 vec[1].u3.z = m._34 - m._31;
4417 origin_plane[1] = m._44 - m._41;
4419 /* Top plane */
4420 vec[2].u1.x = m._14 - m._12;
4421 vec[2].u2.y = m._24 - m._22;
4422 vec[2].u3.z = m._34 - m._32;
4423 origin_plane[2] = m._44 - m._42;
4425 /* Bottom plane */
4426 vec[3].u1.x = m._14 + m._12;
4427 vec[3].u2.y = m._24 + m._22;
4428 vec[3].u3.z = m._34 + m._32;
4429 origin_plane[3] = m._44 + m._42;
4431 /* Front plane */
4432 vec[4].u1.x = m._13;
4433 vec[4].u2.y = m._23;
4434 vec[4].u3.z = m._33;
4435 origin_plane[4] = m._43;
4437 /* Back plane*/
4438 vec[5].u1.x = m._14 - m._13;
4439 vec[5].u2.y = m._24 - m._23;
4440 vec[5].u3.z = m._34 - m._33;
4441 origin_plane[5] = m._44 - m._43;
4443 for(i=0; i<NumSpheres; i++)
4445 ReturnValues[i] = 0;
4446 for(j=0; j<6; j++) ReturnValues[i] |= in_plane(j, vec[j], origin_plane[j], Centers[i], Radii[i]);
4449 return D3D_OK;
4452 static HRESULT WINAPI
4453 Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility(IDirect3DDevice3 *iface,
4454 D3DVECTOR *Centers,
4455 D3DVALUE *Radii,
4456 DWORD NumSpheres,
4457 DWORD Flags,
4458 DWORD *ReturnValues)
4460 IDirect3DDeviceImpl *This = device_from_device3(iface);
4461 TRACE_(ddraw_thunk)("(%p)->(%p,%p,%08x,%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, Centers, Radii, NumSpheres, Flags, ReturnValues);
4462 return IDirect3DDevice7_ComputeSphereVisibility((IDirect3DDevice7 *)This,
4463 Centers, Radii, NumSpheres, Flags, ReturnValues);
4466 /*****************************************************************************
4467 * IDirect3DDevice7::GetTexture
4469 * Returns the texture interface handle assigned to a texture stage.
4470 * The returned texture is AddRefed. This is taken from old ddraw,
4471 * not checked in Windows.
4473 * Version 3 and 7
4475 * Params:
4476 * Stage: Texture stage to read the texture from
4477 * Texture: Address to store the interface pointer at
4479 * Returns:
4480 * D3D_OK on success
4481 * DDERR_INVALIDPARAMS if Texture is NULL
4482 * For details, see IWineD3DDevice::GetTexture
4484 *****************************************************************************/
4485 static HRESULT
4486 IDirect3DDeviceImpl_7_GetTexture(IDirect3DDevice7 *iface,
4487 DWORD Stage,
4488 IDirectDrawSurface7 **Texture)
4490 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
4491 IWineD3DBaseTexture *Surf;
4492 HRESULT hr;
4493 TRACE("(%p)->(%d,%p): Relay\n", This, Stage, Texture);
4495 if(!Texture)
4497 TRACE("Texture == NULL, failing with DDERR_INVALIDPARAMS\n");
4498 return DDERR_INVALIDPARAMS;
4501 EnterCriticalSection(&ddraw_cs);
4502 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice, Stage, &Surf);
4503 if( (hr != D3D_OK) || (!Surf) )
4505 *Texture = NULL;
4506 LeaveCriticalSection(&ddraw_cs);
4507 return hr;
4510 /* GetParent AddRef()s, which is perfectly OK.
4511 * We have passed the IDirectDrawSurface7 interface to WineD3D, so that's OK too.
4513 hr = IWineD3DBaseTexture_GetParent(Surf,
4514 (IUnknown **) Texture);
4515 LeaveCriticalSection(&ddraw_cs);
4516 return hr;
4519 static HRESULT WINAPI
4520 IDirect3DDeviceImpl_7_GetTexture_FPUSetup(IDirect3DDevice7 *iface,
4521 DWORD Stage,
4522 IDirectDrawSurface7 **Texture)
4524 return IDirect3DDeviceImpl_7_GetTexture(iface, Stage, Texture);
4527 static HRESULT WINAPI
4528 IDirect3DDeviceImpl_7_GetTexture_FPUPreserve(IDirect3DDevice7 *iface,
4529 DWORD Stage,
4530 IDirectDrawSurface7 **Texture)
4532 HRESULT hr;
4533 WORD old_fpucw;
4535 old_fpucw = d3d_fpu_setup();
4536 hr = IDirect3DDeviceImpl_7_GetTexture(iface, Stage, Texture);
4537 set_fpu_control_word(old_fpucw);
4539 return hr;
4542 static HRESULT WINAPI
4543 Thunk_IDirect3DDeviceImpl_3_GetTexture(IDirect3DDevice3 *iface,
4544 DWORD Stage,
4545 IDirect3DTexture2 **Texture2)
4547 IDirect3DDeviceImpl *This = device_from_device3(iface);
4548 HRESULT ret;
4549 IDirectDrawSurface7 *ret_val;
4551 TRACE_(ddraw_thunk)("(%p)->(%d,%p) thunking to IDirect3DDevice7 interface.\n", This, Stage, Texture2);
4552 ret = IDirect3DDevice7_GetTexture((IDirect3DDevice7 *)This, Stage, &ret_val);
4554 *Texture2 = ret_val ? (IDirect3DTexture2 *)&((IDirectDrawSurfaceImpl *)ret_val)->IDirect3DTexture2_vtbl : NULL;
4556 TRACE_(ddraw_thunk)(" returning interface %p.\n", *Texture2);
4558 return ret;
4561 /*****************************************************************************
4562 * IDirect3DDevice7::SetTexture
4564 * Assigns a texture to a texture stage. Is the texture AddRef-ed?
4566 * Version 3 and 7
4568 * Params:
4569 * Stage: The stage to assign the texture to
4570 * Texture: Interface pointer to the texture surface
4572 * Returns
4573 * D3D_OK on success
4574 * For details, see IWineD3DDevice::SetTexture
4576 *****************************************************************************/
4577 static HRESULT
4578 IDirect3DDeviceImpl_7_SetTexture(IDirect3DDevice7 *iface,
4579 DWORD Stage,
4580 IDirectDrawSurface7 *Texture)
4582 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
4583 IDirectDrawSurfaceImpl *surf = (IDirectDrawSurfaceImpl *)Texture;
4584 HRESULT hr;
4585 TRACE("(%p)->(%08x,%p): Relay!\n", This, Stage, surf);
4587 /* Texture may be NULL here */
4588 EnterCriticalSection(&ddraw_cs);
4589 hr = IWineD3DDevice_SetTexture(This->wineD3DDevice,
4590 Stage,
4591 surf ? surf->wineD3DTexture : NULL);
4592 LeaveCriticalSection(&ddraw_cs);
4593 return hr;
4596 static HRESULT WINAPI
4597 IDirect3DDeviceImpl_7_SetTexture_FPUSetup(IDirect3DDevice7 *iface,
4598 DWORD Stage,
4599 IDirectDrawSurface7 *Texture)
4601 return IDirect3DDeviceImpl_7_SetTexture(iface, Stage, Texture);
4604 static HRESULT WINAPI
4605 IDirect3DDeviceImpl_7_SetTexture_FPUPreserve(IDirect3DDevice7 *iface,
4606 DWORD Stage,
4607 IDirectDrawSurface7 *Texture)
4609 HRESULT hr;
4610 WORD old_fpucw;
4612 old_fpucw = d3d_fpu_setup();
4613 hr = IDirect3DDeviceImpl_7_SetTexture(iface, Stage, Texture);
4614 set_fpu_control_word(old_fpucw);
4616 return hr;
4619 static HRESULT WINAPI
4620 IDirect3DDeviceImpl_3_SetTexture(IDirect3DDevice3 *iface,
4621 DWORD Stage,
4622 IDirect3DTexture2 *Texture2)
4624 IDirect3DDeviceImpl *This = device_from_device3(iface);
4625 IDirectDrawSurfaceImpl *tex = Texture2 ? surface_from_texture2(Texture2) : NULL;
4626 DWORD texmapblend;
4627 HRESULT hr;
4628 TRACE("(%p)->(%d,%p)\n", This, Stage, tex);
4630 EnterCriticalSection(&ddraw_cs);
4632 if (This->legacyTextureBlending)
4633 IDirect3DDevice3_GetRenderState(iface, D3DRENDERSTATE_TEXTUREMAPBLEND, &texmapblend);
4635 hr = IDirect3DDevice7_SetTexture((IDirect3DDevice7 *)This, Stage, (IDirectDrawSurface7 *)tex);
4637 if (This->legacyTextureBlending && texmapblend == D3DTBLEND_MODULATE)
4639 /* This fixup is required by the way D3DTBLEND_MODULATE maps to texture stage states.
4640 See IDirect3DDeviceImpl_3_SetRenderState for details. */
4641 BOOL tex_alpha = FALSE;
4642 IWineD3DBaseTexture *tex = NULL;
4643 WINED3DSURFACE_DESC desc;
4644 DDPIXELFORMAT ddfmt;
4645 HRESULT result;
4647 result = IWineD3DDevice_GetTexture(This->wineD3DDevice,
4649 &tex);
4651 if(result == WINED3D_OK && tex)
4653 memset(&desc, 0, sizeof(desc));
4654 result = IWineD3DTexture_GetLevelDesc((IWineD3DTexture*) tex, 0, &desc);
4655 if (SUCCEEDED(result))
4657 ddfmt.dwSize = sizeof(ddfmt);
4658 PixelFormat_WineD3DtoDD(&ddfmt, desc.format);
4659 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
4662 IWineD3DBaseTexture_Release(tex);
4665 /* alphaop is WINED3DTOP_SELECTARG1 if it's D3DTBLEND_MODULATE, so only modify alphaarg1 */
4666 if (tex_alpha)
4668 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
4670 else
4672 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_CURRENT);
4676 LeaveCriticalSection(&ddraw_cs);
4678 return hr;
4681 static const struct tss_lookup
4683 BOOL sampler_state;
4684 DWORD state;
4686 tss_lookup[] =
4688 {FALSE, WINED3DTSS_FORCE_DWORD}, /* 0, unused */
4689 {FALSE, WINED3DTSS_COLOROP}, /* 1, D3DTSS_COLOROP */
4690 {FALSE, WINED3DTSS_COLORARG1}, /* 2, D3DTSS_COLORARG1 */
4691 {FALSE, WINED3DTSS_COLORARG2}, /* 3, D3DTSS_COLORARG2 */
4692 {FALSE, WINED3DTSS_ALPHAOP}, /* 4, D3DTSS_ALPHAOP */
4693 {FALSE, WINED3DTSS_ALPHAARG1}, /* 5, D3DTSS_ALPHAARG1 */
4694 {FALSE, WINED3DTSS_ALPHAARG2}, /* 6, D3DTSS_ALPHAARG2 */
4695 {FALSE, WINED3DTSS_BUMPENVMAT00}, /* 7, D3DTSS_BUMPENVMAT00 */
4696 {FALSE, WINED3DTSS_BUMPENVMAT01}, /* 8, D3DTSS_BUMPENVMAT01 */
4697 {FALSE, WINED3DTSS_BUMPENVMAT10}, /* 9, D3DTSS_BUMPENVMAT10 */
4698 {FALSE, WINED3DTSS_BUMPENVMAT11}, /* 10, D3DTSS_BUMPENVMAT11 */
4699 {FALSE, WINED3DTSS_TEXCOORDINDEX}, /* 11, D3DTSS_TEXCOORDINDEX */
4700 {TRUE, WINED3DSAMP_ADDRESSU}, /* 12, D3DTSS_ADDRESS */
4701 {TRUE, WINED3DSAMP_ADDRESSU}, /* 13, D3DTSS_ADDRESSU */
4702 {TRUE, WINED3DSAMP_ADDRESSV}, /* 14, D3DTSS_ADDRESSV */
4703 {TRUE, WINED3DSAMP_BORDERCOLOR}, /* 15, D3DTSS_BORDERCOLOR */
4704 {TRUE, WINED3DSAMP_MAGFILTER}, /* 16, D3DTSS_MAGFILTER */
4705 {TRUE, WINED3DSAMP_MINFILTER}, /* 17, D3DTSS_MINFILTER */
4706 {TRUE, WINED3DSAMP_MIPFILTER}, /* 18, D3DTSS_MIPFILTER */
4707 {TRUE, WINED3DSAMP_MIPMAPLODBIAS}, /* 19, D3DTSS_MIPMAPLODBIAS */
4708 {TRUE, WINED3DSAMP_MAXMIPLEVEL}, /* 20, D3DTSS_MAXMIPLEVEL */
4709 {TRUE, WINED3DSAMP_MAXANISOTROPY}, /* 21, D3DTSS_MAXANISOTROPY */
4710 {FALSE, WINED3DTSS_BUMPENVLSCALE}, /* 22, D3DTSS_BUMPENVLSCALE */
4711 {FALSE, WINED3DTSS_BUMPENVLOFFSET}, /* 23, D3DTSS_BUMPENVLOFFSET */
4712 {FALSE, WINED3DTSS_TEXTURETRANSFORMFLAGS}, /* 24, D3DTSS_TEXTURETRANSFORMFLAGS */
4715 /*****************************************************************************
4716 * IDirect3DDevice7::GetTextureStageState
4718 * Retrieves a state from a texture stage.
4720 * Version 3 and 7
4722 * Params:
4723 * Stage: The stage to retrieve the state from
4724 * TexStageStateType: The state type to retrieve
4725 * State: Address to store the state's value at
4727 * Returns:
4728 * D3D_OK on success
4729 * DDERR_INVALIDPARAMS if State is NULL
4730 * For details, see IWineD3DDevice::GetTextureStageState
4732 *****************************************************************************/
4733 static HRESULT
4734 IDirect3DDeviceImpl_7_GetTextureStageState(IDirect3DDevice7 *iface,
4735 DWORD Stage,
4736 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4737 DWORD *State)
4739 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
4740 HRESULT hr;
4741 const struct tss_lookup *l = &tss_lookup[TexStageStateType];
4742 TRACE("(%p)->(%08x,%08x,%p): Relay!\n", This, Stage, TexStageStateType, State);
4744 if(!State)
4745 return DDERR_INVALIDPARAMS;
4747 if (TexStageStateType > D3DTSS_TEXTURETRANSFORMFLAGS)
4749 WARN("Invalid TexStageStateType %#x passed.\n", TexStageStateType);
4750 *State = 0;
4751 return DD_OK;
4754 EnterCriticalSection(&ddraw_cs);
4756 if (l->sampler_state)
4758 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice, Stage, l->state, State);
4760 switch(TexStageStateType)
4762 /* Mipfilter is a sampler state with different values */
4763 case D3DTSS_MIPFILTER:
4765 switch(*State)
4767 case WINED3DTEXF_NONE: *State = D3DTFP_NONE; break;
4768 case WINED3DTEXF_POINT: *State = D3DTFP_POINT; break;
4769 case WINED3DTEXF_LINEAR: *State = D3DTFP_LINEAR; break;
4770 default:
4771 ERR("Unexpected mipfilter value %#x\n", *State);
4772 *State = D3DTFP_NONE;
4773 break;
4775 break;
4778 /* Magfilter has slightly different values */
4779 case D3DTSS_MAGFILTER:
4781 switch(*State)
4783 case WINED3DTEXF_POINT: *State = D3DTFG_POINT; break;
4784 case WINED3DTEXF_LINEAR: *State = D3DTFG_LINEAR; break;
4785 case WINED3DTEXF_ANISOTROPIC: *State = D3DTFG_ANISOTROPIC; break;
4786 case WINED3DTEXF_FLATCUBIC: *State = D3DTFG_FLATCUBIC; break;
4787 case WINED3DTEXF_GAUSSIANCUBIC: *State = D3DTFG_GAUSSIANCUBIC; break;
4788 default:
4789 ERR("Unexpected wined3d mag filter value %#x\n", *State);
4790 *State = D3DTFG_POINT;
4791 break;
4793 break;
4796 default:
4797 break;
4800 else
4802 hr = IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, Stage, l->state, State);
4805 LeaveCriticalSection(&ddraw_cs);
4806 return hr;
4809 static HRESULT WINAPI
4810 IDirect3DDeviceImpl_7_GetTextureStageState_FPUSetup(IDirect3DDevice7 *iface,
4811 DWORD Stage,
4812 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4813 DWORD *State)
4815 return IDirect3DDeviceImpl_7_GetTextureStageState(iface, Stage, TexStageStateType, State);
4818 static HRESULT WINAPI
4819 IDirect3DDeviceImpl_7_GetTextureStageState_FPUPreserve(IDirect3DDevice7 *iface,
4820 DWORD Stage,
4821 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4822 DWORD *State)
4824 HRESULT hr;
4825 WORD old_fpucw;
4827 old_fpucw = d3d_fpu_setup();
4828 hr = IDirect3DDeviceImpl_7_GetTextureStageState(iface, Stage, TexStageStateType, State);
4829 set_fpu_control_word(old_fpucw);
4831 return hr;
4834 static HRESULT WINAPI
4835 Thunk_IDirect3DDeviceImpl_3_GetTextureStageState(IDirect3DDevice3 *iface,
4836 DWORD Stage,
4837 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4838 DWORD *State)
4840 IDirect3DDeviceImpl *This = device_from_device3(iface);
4841 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, Stage, TexStageStateType, State);
4842 return IDirect3DDevice7_GetTextureStageState((IDirect3DDevice7 *)This, Stage, TexStageStateType, State);
4845 /*****************************************************************************
4846 * IDirect3DDevice7::SetTextureStageState
4848 * Sets a texture stage state. Some stage types need to be handled specially,
4849 * because they do not exist in WineD3D and were moved to another place
4851 * Version 3 and 7
4853 * Params:
4854 * Stage: The stage to modify
4855 * TexStageStateType: The state to change
4856 * State: The new value for the state
4858 * Returns:
4859 * D3D_OK on success
4860 * For details, see IWineD3DDevice::SetTextureStageState
4862 *****************************************************************************/
4863 static HRESULT
4864 IDirect3DDeviceImpl_7_SetTextureStageState(IDirect3DDevice7 *iface,
4865 DWORD Stage,
4866 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4867 DWORD State)
4869 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
4870 const struct tss_lookup *l = &tss_lookup[TexStageStateType];
4871 HRESULT hr;
4872 TRACE("(%p)->(%08x,%08x,%08x): Relay!\n", This, Stage, TexStageStateType, State);
4874 if (TexStageStateType > D3DTSS_TEXTURETRANSFORMFLAGS)
4876 WARN("Invalid TexStageStateType %#x passed.\n", TexStageStateType);
4877 return DD_OK;
4880 EnterCriticalSection(&ddraw_cs);
4882 if (l->sampler_state)
4884 switch(TexStageStateType)
4886 /* Mipfilter is a sampler state with different values */
4887 case D3DTSS_MIPFILTER:
4889 switch(State)
4891 case D3DTFP_NONE: State = WINED3DTEXF_NONE; break;
4892 case D3DTFP_POINT: State = WINED3DTEXF_POINT; break;
4893 case 0: /* Unchecked */
4894 case D3DTFP_LINEAR: State = WINED3DTEXF_LINEAR; break;
4895 default:
4896 ERR("Unexpected mipfilter value %d\n", State);
4897 State = WINED3DTEXF_NONE;
4898 break;
4900 break;
4903 /* Magfilter has slightly different values */
4904 case D3DTSS_MAGFILTER:
4906 switch(State)
4908 case D3DTFG_POINT: State = WINED3DTEXF_POINT; break;
4909 case D3DTFG_LINEAR: State = WINED3DTEXF_LINEAR; break;
4910 case D3DTFG_FLATCUBIC: State = WINED3DTEXF_FLATCUBIC; break;
4911 case D3DTFG_GAUSSIANCUBIC: State = WINED3DTEXF_GAUSSIANCUBIC; break;
4912 case D3DTFG_ANISOTROPIC: State = WINED3DTEXF_ANISOTROPIC; break;
4913 default:
4914 ERR("Unexpected d3d7 mag filter type %d\n", State);
4915 State = WINED3DTEXF_POINT;
4916 break;
4918 break;
4921 case D3DTSS_ADDRESS:
4922 IWineD3DDevice_SetSamplerState(This->wineD3DDevice, Stage, WINED3DSAMP_ADDRESSV, State);
4923 break;
4925 default:
4926 break;
4929 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice, Stage, l->state, State);
4931 else
4933 hr = IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, Stage, l->state, State);
4936 LeaveCriticalSection(&ddraw_cs);
4937 return hr;
4940 static HRESULT WINAPI
4941 IDirect3DDeviceImpl_7_SetTextureStageState_FPUSetup(IDirect3DDevice7 *iface,
4942 DWORD Stage,
4943 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4944 DWORD State)
4946 return IDirect3DDeviceImpl_7_SetTextureStageState(iface, Stage, TexStageStateType, State);
4949 static HRESULT WINAPI
4950 IDirect3DDeviceImpl_7_SetTextureStageState_FPUPreserve(IDirect3DDevice7 *iface,
4951 DWORD Stage,
4952 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4953 DWORD State)
4955 HRESULT hr;
4956 WORD old_fpucw;
4958 old_fpucw = d3d_fpu_setup();
4959 hr = IDirect3DDeviceImpl_7_SetTextureStageState(iface, Stage, TexStageStateType, State);
4960 set_fpu_control_word(old_fpucw);
4962 return hr;
4965 static HRESULT WINAPI
4966 Thunk_IDirect3DDeviceImpl_3_SetTextureStageState(IDirect3DDevice3 *iface,
4967 DWORD Stage,
4968 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4969 DWORD State)
4971 IDirect3DDeviceImpl *This = device_from_device3(iface);
4972 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, Stage, TexStageStateType, State);
4973 return IDirect3DDevice7_SetTextureStageState((IDirect3DDevice7 *)This, Stage, TexStageStateType, State);
4976 /*****************************************************************************
4977 * IDirect3DDevice7::ValidateDevice
4979 * SDK: "Reports the device's ability to render the currently set
4980 * texture-blending operations in a single pass". Whatever that means
4981 * exactly...
4983 * Version 3 and 7
4985 * Params:
4986 * NumPasses: Address to write the number of necessary passes for the
4987 * desired effect to.
4989 * Returns:
4990 * D3D_OK on success
4991 * See IWineD3DDevice::ValidateDevice for more details
4993 *****************************************************************************/
4994 static HRESULT
4995 IDirect3DDeviceImpl_7_ValidateDevice(IDirect3DDevice7 *iface,
4996 DWORD *NumPasses)
4998 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
4999 HRESULT hr;
5000 TRACE("(%p)->(%p): Relay\n", This, NumPasses);
5002 EnterCriticalSection(&ddraw_cs);
5003 hr = IWineD3DDevice_ValidateDevice(This->wineD3DDevice, NumPasses);
5004 LeaveCriticalSection(&ddraw_cs);
5005 return hr;
5008 static HRESULT WINAPI
5009 IDirect3DDeviceImpl_7_ValidateDevice_FPUSetup(IDirect3DDevice7 *iface,
5010 DWORD *NumPasses)
5012 return IDirect3DDeviceImpl_7_ValidateDevice(iface, NumPasses);
5015 static HRESULT WINAPI
5016 IDirect3DDeviceImpl_7_ValidateDevice_FPUPreserve(IDirect3DDevice7 *iface,
5017 DWORD *NumPasses)
5019 HRESULT hr;
5020 WORD old_fpucw;
5022 old_fpucw = d3d_fpu_setup();
5023 hr = IDirect3DDeviceImpl_7_ValidateDevice(iface, NumPasses);
5024 set_fpu_control_word(old_fpucw);
5026 return hr;
5029 static HRESULT WINAPI
5030 Thunk_IDirect3DDeviceImpl_3_ValidateDevice(IDirect3DDevice3 *iface,
5031 DWORD *Passes)
5033 IDirect3DDeviceImpl *This = device_from_device3(iface);
5034 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Passes);
5035 return IDirect3DDevice7_ValidateDevice((IDirect3DDevice7 *)This, Passes);
5038 /*****************************************************************************
5039 * IDirect3DDevice7::Clear
5041 * Fills the render target, the z buffer and the stencil buffer with a
5042 * clear color / value
5044 * Version 7 only
5046 * Params:
5047 * Count: Number of rectangles in Rects must be 0 if Rects is NULL
5048 * Rects: Rectangles to clear. If NULL, the whole surface is cleared
5049 * Flags: Some flags, as usual
5050 * Color: Clear color for the render target
5051 * Z: Clear value for the Z buffer
5052 * Stencil: Clear value to store in each stencil buffer entry
5054 * Returns:
5055 * D3D_OK on success
5056 * For details, see IWineD3DDevice::Clear
5058 *****************************************************************************/
5059 static HRESULT
5060 IDirect3DDeviceImpl_7_Clear(IDirect3DDevice7 *iface,
5061 DWORD Count,
5062 D3DRECT *Rects,
5063 DWORD Flags,
5064 D3DCOLOR Color,
5065 D3DVALUE Z,
5066 DWORD Stencil)
5068 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5069 HRESULT hr;
5070 TRACE("(%p)->(%08x,%p,%08x,%08x,%f,%08x): Relay\n", This, Count, Rects, Flags, Color, Z, Stencil);
5072 /* Note; D3DRECT is compatible with WINED3DRECT */
5073 EnterCriticalSection(&ddraw_cs);
5074 hr = IWineD3DDevice_Clear(This->wineD3DDevice, Count, (WINED3DRECT*) Rects, Flags, Color, Z, Stencil);
5075 LeaveCriticalSection(&ddraw_cs);
5076 return hr;
5079 static HRESULT WINAPI
5080 IDirect3DDeviceImpl_7_Clear_FPUSetup(IDirect3DDevice7 *iface,
5081 DWORD Count,
5082 D3DRECT *Rects,
5083 DWORD Flags,
5084 D3DCOLOR Color,
5085 D3DVALUE Z,
5086 DWORD Stencil)
5088 return IDirect3DDeviceImpl_7_Clear(iface, Count, Rects, Flags, Color, Z, Stencil);
5091 static HRESULT WINAPI
5092 IDirect3DDeviceImpl_7_Clear_FPUPreserve(IDirect3DDevice7 *iface,
5093 DWORD Count,
5094 D3DRECT *Rects,
5095 DWORD Flags,
5096 D3DCOLOR Color,
5097 D3DVALUE Z,
5098 DWORD Stencil)
5100 HRESULT hr;
5101 WORD old_fpucw;
5103 old_fpucw = d3d_fpu_setup();
5104 hr = IDirect3DDeviceImpl_7_Clear(iface, Count, Rects, Flags, Color, Z, Stencil);
5105 set_fpu_control_word(old_fpucw);
5107 return hr;
5110 /*****************************************************************************
5111 * IDirect3DDevice7::SetViewport
5113 * Sets the current viewport.
5115 * Version 7 only, but IDirect3DViewport uses this call for older
5116 * versions
5118 * Params:
5119 * Data: The new viewport to set
5121 * Returns:
5122 * D3D_OK on success
5123 * DDERR_INVALIDPARAMS if Data is NULL
5124 * For more details, see IWineDDDevice::SetViewport
5126 *****************************************************************************/
5127 static HRESULT
5128 IDirect3DDeviceImpl_7_SetViewport(IDirect3DDevice7 *iface,
5129 D3DVIEWPORT7 *Data)
5131 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5132 HRESULT hr;
5133 TRACE("(%p)->(%p) Relay!\n", This, Data);
5135 if(!Data)
5136 return DDERR_INVALIDPARAMS;
5138 /* Note: D3DVIEWPORT7 is compatible with WINED3DVIEWPORT */
5139 EnterCriticalSection(&ddraw_cs);
5140 hr = IWineD3DDevice_SetViewport(This->wineD3DDevice,
5141 (WINED3DVIEWPORT*) Data);
5142 LeaveCriticalSection(&ddraw_cs);
5143 return hr;
5146 static HRESULT WINAPI
5147 IDirect3DDeviceImpl_7_SetViewport_FPUSetup(IDirect3DDevice7 *iface,
5148 D3DVIEWPORT7 *Data)
5150 return IDirect3DDeviceImpl_7_SetViewport(iface, Data);
5153 static HRESULT WINAPI
5154 IDirect3DDeviceImpl_7_SetViewport_FPUPreserve(IDirect3DDevice7 *iface,
5155 D3DVIEWPORT7 *Data)
5157 HRESULT hr;
5158 WORD old_fpucw;
5160 old_fpucw = d3d_fpu_setup();
5161 hr = IDirect3DDeviceImpl_7_SetViewport(iface, Data);
5162 set_fpu_control_word(old_fpucw);
5164 return hr;
5167 /*****************************************************************************
5168 * IDirect3DDevice::GetViewport
5170 * Returns the current viewport
5172 * Version 7
5174 * Params:
5175 * Data: D3D7Viewport structure to write the viewport information to
5177 * Returns:
5178 * D3D_OK on success
5179 * DDERR_INVALIDPARAMS if Data is NULL
5180 * For more details, see IWineD3DDevice::GetViewport
5182 *****************************************************************************/
5183 static HRESULT
5184 IDirect3DDeviceImpl_7_GetViewport(IDirect3DDevice7 *iface,
5185 D3DVIEWPORT7 *Data)
5187 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5188 HRESULT hr;
5189 TRACE("(%p)->(%p) Relay!\n", This, Data);
5191 if(!Data)
5192 return DDERR_INVALIDPARAMS;
5194 /* Note: D3DVIEWPORT7 is compatible with WINED3DVIEWPORT */
5195 EnterCriticalSection(&ddraw_cs);
5196 hr = IWineD3DDevice_GetViewport(This->wineD3DDevice,
5197 (WINED3DVIEWPORT*) Data);
5199 LeaveCriticalSection(&ddraw_cs);
5200 return hr_ddraw_from_wined3d(hr);
5203 static HRESULT WINAPI
5204 IDirect3DDeviceImpl_7_GetViewport_FPUSetup(IDirect3DDevice7 *iface,
5205 D3DVIEWPORT7 *Data)
5207 return IDirect3DDeviceImpl_7_GetViewport(iface, Data);
5210 static HRESULT WINAPI
5211 IDirect3DDeviceImpl_7_GetViewport_FPUPreserve(IDirect3DDevice7 *iface,
5212 D3DVIEWPORT7 *Data)
5214 HRESULT hr;
5215 WORD old_fpucw;
5217 old_fpucw = d3d_fpu_setup();
5218 hr = IDirect3DDeviceImpl_7_GetViewport(iface, Data);
5219 set_fpu_control_word(old_fpucw);
5221 return hr;
5224 /*****************************************************************************
5225 * IDirect3DDevice7::SetMaterial
5227 * Sets the Material
5229 * Version 7
5231 * Params:
5232 * Mat: The material to set
5234 * Returns:
5235 * D3D_OK on success
5236 * DDERR_INVALIDPARAMS if Mat is NULL.
5237 * For more details, see IWineD3DDevice::SetMaterial
5239 *****************************************************************************/
5240 static HRESULT
5241 IDirect3DDeviceImpl_7_SetMaterial(IDirect3DDevice7 *iface,
5242 D3DMATERIAL7 *Mat)
5244 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5245 HRESULT hr;
5246 TRACE("(%p)->(%p): Relay!\n", This, Mat);
5248 if (!Mat) return DDERR_INVALIDPARAMS;
5249 /* Note: D3DMATERIAL7 is compatible with WINED3DMATERIAL */
5250 EnterCriticalSection(&ddraw_cs);
5251 hr = IWineD3DDevice_SetMaterial(This->wineD3DDevice,
5252 (WINED3DMATERIAL*) Mat);
5253 LeaveCriticalSection(&ddraw_cs);
5254 return hr_ddraw_from_wined3d(hr);
5257 static HRESULT WINAPI
5258 IDirect3DDeviceImpl_7_SetMaterial_FPUSetup(IDirect3DDevice7 *iface,
5259 D3DMATERIAL7 *Mat)
5261 return IDirect3DDeviceImpl_7_SetMaterial(iface, Mat);
5264 static HRESULT WINAPI
5265 IDirect3DDeviceImpl_7_SetMaterial_FPUPreserve(IDirect3DDevice7 *iface,
5266 D3DMATERIAL7 *Mat)
5268 HRESULT hr;
5269 WORD old_fpucw;
5271 old_fpucw = d3d_fpu_setup();
5272 hr = IDirect3DDeviceImpl_7_SetMaterial(iface, Mat);
5273 set_fpu_control_word(old_fpucw);
5275 return hr;
5278 /*****************************************************************************
5279 * IDirect3DDevice7::GetMaterial
5281 * Returns the current material
5283 * Version 7
5285 * Params:
5286 * Mat: D3DMATERIAL7 structure to write the material parameters to
5288 * Returns:
5289 * D3D_OK on success
5290 * DDERR_INVALIDPARAMS if Mat is NULL
5291 * For more details, see IWineD3DDevice::GetMaterial
5293 *****************************************************************************/
5294 static HRESULT
5295 IDirect3DDeviceImpl_7_GetMaterial(IDirect3DDevice7 *iface,
5296 D3DMATERIAL7 *Mat)
5298 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5299 HRESULT hr;
5300 TRACE("(%p)->(%p): Relay!\n", This, Mat);
5302 EnterCriticalSection(&ddraw_cs);
5303 /* Note: D3DMATERIAL7 is compatible with WINED3DMATERIAL */
5304 hr = IWineD3DDevice_GetMaterial(This->wineD3DDevice,
5305 (WINED3DMATERIAL*) Mat);
5306 LeaveCriticalSection(&ddraw_cs);
5307 return hr_ddraw_from_wined3d(hr);
5310 static HRESULT WINAPI
5311 IDirect3DDeviceImpl_7_GetMaterial_FPUSetup(IDirect3DDevice7 *iface,
5312 D3DMATERIAL7 *Mat)
5314 return IDirect3DDeviceImpl_7_GetMaterial(iface, Mat);
5317 static HRESULT WINAPI
5318 IDirect3DDeviceImpl_7_GetMaterial_FPUPreserve(IDirect3DDevice7 *iface,
5319 D3DMATERIAL7 *Mat)
5321 HRESULT hr;
5322 WORD old_fpucw;
5324 old_fpucw = d3d_fpu_setup();
5325 hr = IDirect3DDeviceImpl_7_GetMaterial(iface, Mat);
5326 set_fpu_control_word(old_fpucw);
5328 return hr;
5331 /*****************************************************************************
5332 * IDirect3DDevice7::SetLight
5334 * Assigns a light to a light index, but doesn't activate it yet.
5336 * Version 7, IDirect3DLight uses this method for older versions
5338 * Params:
5339 * LightIndex: The index of the new light
5340 * Light: A D3DLIGHT7 structure describing the light
5342 * Returns:
5343 * D3D_OK on success
5344 * For more details, see IWineD3DDevice::SetLight
5346 *****************************************************************************/
5347 static HRESULT
5348 IDirect3DDeviceImpl_7_SetLight(IDirect3DDevice7 *iface,
5349 DWORD LightIndex,
5350 D3DLIGHT7 *Light)
5352 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5353 HRESULT hr;
5354 TRACE("(%p)->(%08x,%p): Relay!\n", This, LightIndex, Light);
5356 EnterCriticalSection(&ddraw_cs);
5357 /* Note: D3DLIGHT7 is compatible with WINED3DLIGHT */
5358 hr = IWineD3DDevice_SetLight(This->wineD3DDevice,
5359 LightIndex,
5360 (WINED3DLIGHT*) Light);
5361 LeaveCriticalSection(&ddraw_cs);
5362 return hr_ddraw_from_wined3d(hr);
5365 static HRESULT WINAPI
5366 IDirect3DDeviceImpl_7_SetLight_FPUSetup(IDirect3DDevice7 *iface,
5367 DWORD LightIndex,
5368 D3DLIGHT7 *Light)
5370 return IDirect3DDeviceImpl_7_SetLight(iface, LightIndex, Light);
5373 static HRESULT WINAPI
5374 IDirect3DDeviceImpl_7_SetLight_FPUPreserve(IDirect3DDevice7 *iface,
5375 DWORD LightIndex,
5376 D3DLIGHT7 *Light)
5378 HRESULT hr;
5379 WORD old_fpucw;
5381 old_fpucw = d3d_fpu_setup();
5382 hr = IDirect3DDeviceImpl_7_SetLight(iface, LightIndex, Light);
5383 set_fpu_control_word(old_fpucw);
5385 return hr;
5388 /*****************************************************************************
5389 * IDirect3DDevice7::GetLight
5391 * Returns the light assigned to a light index
5393 * Params:
5394 * Light: Structure to write the light information to
5396 * Returns:
5397 * D3D_OK on success
5398 * DDERR_INVALIDPARAMS if Light is NULL
5399 * For details, see IWineD3DDevice::GetLight
5401 *****************************************************************************/
5402 static HRESULT
5403 IDirect3DDeviceImpl_7_GetLight(IDirect3DDevice7 *iface,
5404 DWORD LightIndex,
5405 D3DLIGHT7 *Light)
5407 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5408 HRESULT rc;
5409 TRACE("(%p)->(%08x,%p): Relay!\n", This, LightIndex, Light);
5411 EnterCriticalSection(&ddraw_cs);
5412 /* Note: D3DLIGHT7 is compatible with WINED3DLIGHT */
5413 rc = IWineD3DDevice_GetLight(This->wineD3DDevice,
5414 LightIndex,
5415 (WINED3DLIGHT*) Light);
5417 /* Translate the result. WineD3D returns other values than D3D7 */
5418 LeaveCriticalSection(&ddraw_cs);
5419 return hr_ddraw_from_wined3d(rc);
5422 static HRESULT WINAPI
5423 IDirect3DDeviceImpl_7_GetLight_FPUSetup(IDirect3DDevice7 *iface,
5424 DWORD LightIndex,
5425 D3DLIGHT7 *Light)
5427 return IDirect3DDeviceImpl_7_GetLight(iface, LightIndex, Light);
5430 static HRESULT WINAPI
5431 IDirect3DDeviceImpl_7_GetLight_FPUPreserve(IDirect3DDevice7 *iface,
5432 DWORD LightIndex,
5433 D3DLIGHT7 *Light)
5435 HRESULT hr;
5436 WORD old_fpucw;
5438 old_fpucw = d3d_fpu_setup();
5439 hr = IDirect3DDeviceImpl_7_GetLight(iface, LightIndex, Light);
5440 set_fpu_control_word(old_fpucw);
5442 return hr;
5445 /*****************************************************************************
5446 * IDirect3DDevice7::BeginStateBlock
5448 * Begins recording to a stateblock
5450 * Version 7
5452 * Returns:
5453 * D3D_OK on success
5454 * For details see IWineD3DDevice::BeginStateBlock
5456 *****************************************************************************/
5457 static HRESULT
5458 IDirect3DDeviceImpl_7_BeginStateBlock(IDirect3DDevice7 *iface)
5460 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5461 HRESULT hr;
5462 TRACE("(%p)->(): Relay!\n", This);
5464 EnterCriticalSection(&ddraw_cs);
5465 hr = IWineD3DDevice_BeginStateBlock(This->wineD3DDevice);
5466 LeaveCriticalSection(&ddraw_cs);
5467 return hr_ddraw_from_wined3d(hr);
5470 static HRESULT WINAPI
5471 IDirect3DDeviceImpl_7_BeginStateBlock_FPUSetup(IDirect3DDevice7 *iface)
5473 return IDirect3DDeviceImpl_7_BeginStateBlock(iface);
5476 static HRESULT WINAPI
5477 IDirect3DDeviceImpl_7_BeginStateBlock_FPUPreserve(IDirect3DDevice7 *iface)
5479 HRESULT hr;
5480 WORD old_fpucw;
5482 old_fpucw = d3d_fpu_setup();
5483 hr = IDirect3DDeviceImpl_7_BeginStateBlock(iface);
5484 set_fpu_control_word(old_fpucw);
5486 return hr;
5489 /*****************************************************************************
5490 * IDirect3DDevice7::EndStateBlock
5492 * Stops recording to a state block and returns the created stateblock
5493 * handle.
5495 * Version 7
5497 * Params:
5498 * BlockHandle: Address to store the stateblock's handle to
5500 * Returns:
5501 * D3D_OK on success
5502 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5503 * See IWineD3DDevice::EndStateBlock for more details
5505 *****************************************************************************/
5506 static HRESULT
5507 IDirect3DDeviceImpl_7_EndStateBlock(IDirect3DDevice7 *iface,
5508 DWORD *BlockHandle)
5510 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5511 HRESULT hr;
5512 TRACE("(%p)->(%p): Relay!\n", This, BlockHandle);
5514 if(!BlockHandle)
5516 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
5517 return DDERR_INVALIDPARAMS;
5520 EnterCriticalSection(&ddraw_cs);
5521 *BlockHandle = IDirect3DDeviceImpl_CreateHandle(This);
5522 if(!*BlockHandle)
5524 ERR("Cannot get a handle number for the stateblock\n");
5525 LeaveCriticalSection(&ddraw_cs);
5526 return DDERR_OUTOFMEMORY;
5528 This->Handles[*BlockHandle - 1].type = DDrawHandle_StateBlock;
5529 hr = IWineD3DDevice_EndStateBlock(This->wineD3DDevice,
5530 (IWineD3DStateBlock **) &This->Handles[*BlockHandle - 1].ptr);
5531 LeaveCriticalSection(&ddraw_cs);
5532 return hr_ddraw_from_wined3d(hr);
5535 static HRESULT WINAPI
5536 IDirect3DDeviceImpl_7_EndStateBlock_FPUSetup(IDirect3DDevice7 *iface,
5537 DWORD *BlockHandle)
5539 return IDirect3DDeviceImpl_7_EndStateBlock(iface, BlockHandle);
5542 static HRESULT WINAPI
5543 IDirect3DDeviceImpl_7_EndStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
5544 DWORD *BlockHandle)
5546 HRESULT hr;
5547 WORD old_fpucw;
5549 old_fpucw = d3d_fpu_setup();
5550 hr = IDirect3DDeviceImpl_7_EndStateBlock(iface, BlockHandle);
5551 set_fpu_control_word(old_fpucw);
5553 return hr;
5556 /*****************************************************************************
5557 * IDirect3DDevice7::PreLoad
5559 * Allows the app to signal that a texture will be used soon, to allow
5560 * the Direct3DDevice to load it to the video card in the meantime.
5562 * Version 7
5564 * Params:
5565 * Texture: The texture to preload
5567 * Returns:
5568 * D3D_OK on success
5569 * DDERR_INVALIDPARAMS if Texture is NULL
5570 * See IWineD3DSurface::PreLoad for details
5572 *****************************************************************************/
5573 static HRESULT
5574 IDirect3DDeviceImpl_7_PreLoad(IDirect3DDevice7 *iface,
5575 IDirectDrawSurface7 *Texture)
5577 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5578 IDirectDrawSurfaceImpl *surf = (IDirectDrawSurfaceImpl *)Texture;
5580 TRACE("(%p)->(%p): Relay!\n", This, surf);
5582 if(!Texture)
5583 return DDERR_INVALIDPARAMS;
5585 EnterCriticalSection(&ddraw_cs);
5586 IWineD3DSurface_PreLoad(surf->WineD3DSurface);
5587 LeaveCriticalSection(&ddraw_cs);
5588 return D3D_OK;
5591 static HRESULT WINAPI
5592 IDirect3DDeviceImpl_7_PreLoad_FPUSetup(IDirect3DDevice7 *iface,
5593 IDirectDrawSurface7 *Texture)
5595 return IDirect3DDeviceImpl_7_PreLoad(iface, Texture);
5598 static HRESULT WINAPI
5599 IDirect3DDeviceImpl_7_PreLoad_FPUPreserve(IDirect3DDevice7 *iface,
5600 IDirectDrawSurface7 *Texture)
5602 HRESULT hr;
5603 WORD old_fpucw;
5605 old_fpucw = d3d_fpu_setup();
5606 hr = IDirect3DDeviceImpl_7_PreLoad(iface, Texture);
5607 set_fpu_control_word(old_fpucw);
5609 return hr;
5612 /*****************************************************************************
5613 * IDirect3DDevice7::ApplyStateBlock
5615 * Activates the state stored in a state block handle.
5617 * Params:
5618 * BlockHandle: The stateblock handle to activate
5620 * Returns:
5621 * D3D_OK on success
5622 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5624 *****************************************************************************/
5625 static HRESULT
5626 IDirect3DDeviceImpl_7_ApplyStateBlock(IDirect3DDevice7 *iface,
5627 DWORD BlockHandle)
5629 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5630 HRESULT hr;
5631 TRACE("(%p)->(%08x): Relay!\n", This, BlockHandle);
5633 EnterCriticalSection(&ddraw_cs);
5634 if(!BlockHandle || BlockHandle > This->numHandles)
5636 WARN("Out of range handle %d, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5637 LeaveCriticalSection(&ddraw_cs);
5638 return D3DERR_INVALIDSTATEBLOCK;
5640 if(This->Handles[BlockHandle - 1].type != DDrawHandle_StateBlock)
5642 WARN("Handle %d is not a stateblock, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5643 LeaveCriticalSection(&ddraw_cs);
5644 return D3DERR_INVALIDSTATEBLOCK;
5647 hr = IWineD3DStateBlock_Apply((IWineD3DStateBlock *) This->Handles[BlockHandle - 1].ptr);
5648 LeaveCriticalSection(&ddraw_cs);
5649 return hr_ddraw_from_wined3d(hr);
5652 static HRESULT WINAPI
5653 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUSetup(IDirect3DDevice7 *iface,
5654 DWORD BlockHandle)
5656 return IDirect3DDeviceImpl_7_ApplyStateBlock(iface, BlockHandle);
5659 static HRESULT WINAPI
5660 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
5661 DWORD BlockHandle)
5663 HRESULT hr;
5664 WORD old_fpucw;
5666 old_fpucw = d3d_fpu_setup();
5667 hr = IDirect3DDeviceImpl_7_ApplyStateBlock(iface, BlockHandle);
5668 set_fpu_control_word(old_fpucw);
5670 return hr;
5673 /*****************************************************************************
5674 * IDirect3DDevice7::CaptureStateBlock
5676 * Updates a stateblock's values to the values currently set for the device
5678 * Version 7
5680 * Params:
5681 * BlockHandle: Stateblock to update
5683 * Returns:
5684 * D3D_OK on success
5685 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5686 * See IWineD3DDevice::CaptureStateBlock for more details
5688 *****************************************************************************/
5689 static HRESULT
5690 IDirect3DDeviceImpl_7_CaptureStateBlock(IDirect3DDevice7 *iface,
5691 DWORD BlockHandle)
5693 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5694 HRESULT hr;
5695 TRACE("(%p)->(%08x): Relay!\n", This, BlockHandle);
5697 EnterCriticalSection(&ddraw_cs);
5698 if(BlockHandle == 0 || BlockHandle > This->numHandles)
5700 WARN("Out of range handle %d, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5701 LeaveCriticalSection(&ddraw_cs);
5702 return D3DERR_INVALIDSTATEBLOCK;
5704 if(This->Handles[BlockHandle - 1].type != DDrawHandle_StateBlock)
5706 WARN("Handle %d is not a stateblock, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5707 LeaveCriticalSection(&ddraw_cs);
5708 return D3DERR_INVALIDSTATEBLOCK;
5711 hr = IWineD3DStateBlock_Capture((IWineD3DStateBlock *) This->Handles[BlockHandle - 1].ptr);
5712 LeaveCriticalSection(&ddraw_cs);
5713 return hr_ddraw_from_wined3d(hr);
5716 static HRESULT WINAPI
5717 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUSetup(IDirect3DDevice7 *iface,
5718 DWORD BlockHandle)
5720 return IDirect3DDeviceImpl_7_CaptureStateBlock(iface, BlockHandle);
5723 static HRESULT WINAPI
5724 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
5725 DWORD BlockHandle)
5727 HRESULT hr;
5728 WORD old_fpucw;
5730 old_fpucw = d3d_fpu_setup();
5731 hr = IDirect3DDeviceImpl_7_CaptureStateBlock(iface, BlockHandle);
5732 set_fpu_control_word(old_fpucw);
5734 return hr;
5737 /*****************************************************************************
5738 * IDirect3DDevice7::DeleteStateBlock
5740 * Deletes a stateblock handle. This means releasing the WineD3DStateBlock
5742 * Version 7
5744 * Params:
5745 * BlockHandle: Stateblock handle to delete
5747 * Returns:
5748 * D3D_OK on success
5749 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is 0
5751 *****************************************************************************/
5752 static HRESULT
5753 IDirect3DDeviceImpl_7_DeleteStateBlock(IDirect3DDevice7 *iface,
5754 DWORD BlockHandle)
5756 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5757 ULONG ref;
5758 TRACE("(%p)->(%08x): Relay!\n", This, BlockHandle);
5760 EnterCriticalSection(&ddraw_cs);
5761 if(BlockHandle == 0 || BlockHandle > This->numHandles)
5763 WARN("Out of range handle %d, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5764 LeaveCriticalSection(&ddraw_cs);
5765 return D3DERR_INVALIDSTATEBLOCK;
5767 if(This->Handles[BlockHandle - 1].type != DDrawHandle_StateBlock)
5769 WARN("Handle %d is not a stateblock, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5770 LeaveCriticalSection(&ddraw_cs);
5771 return D3DERR_INVALIDSTATEBLOCK;
5774 ref = IWineD3DStateBlock_Release((IWineD3DStateBlock *) This->Handles[BlockHandle - 1].ptr);
5775 if(ref)
5777 ERR("Something is still holding the stateblock %p(Handle %d). Ref = %d\n", This->Handles[BlockHandle - 1].ptr, BlockHandle, ref);
5779 This->Handles[BlockHandle - 1].ptr = NULL;
5780 This->Handles[BlockHandle - 1].type = DDrawHandle_Unknown;
5782 LeaveCriticalSection(&ddraw_cs);
5783 return D3D_OK;
5786 static HRESULT WINAPI
5787 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUSetup(IDirect3DDevice7 *iface,
5788 DWORD BlockHandle)
5790 return IDirect3DDeviceImpl_7_DeleteStateBlock(iface, BlockHandle);
5793 static HRESULT WINAPI
5794 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
5795 DWORD BlockHandle)
5797 HRESULT hr;
5798 WORD old_fpucw;
5800 old_fpucw = d3d_fpu_setup();
5801 hr = IDirect3DDeviceImpl_7_DeleteStateBlock(iface, BlockHandle);
5802 set_fpu_control_word(old_fpucw);
5804 return hr;
5807 /*****************************************************************************
5808 * IDirect3DDevice7::CreateStateBlock
5810 * Creates a new state block handle.
5812 * Version 7
5814 * Params:
5815 * Type: The state block type
5816 * BlockHandle: Address to write the created handle to
5818 * Returns:
5819 * D3D_OK on success
5820 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5822 *****************************************************************************/
5823 static HRESULT
5824 IDirect3DDeviceImpl_7_CreateStateBlock(IDirect3DDevice7 *iface,
5825 D3DSTATEBLOCKTYPE Type,
5826 DWORD *BlockHandle)
5828 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5829 HRESULT hr;
5830 TRACE("(%p)->(%08x,%p)!\n", This, Type, BlockHandle);
5832 if(!BlockHandle)
5834 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
5835 return DDERR_INVALIDPARAMS;
5837 if(Type != D3DSBT_ALL && Type != D3DSBT_PIXELSTATE &&
5838 Type != D3DSBT_VERTEXSTATE ) {
5839 WARN("Unexpected stateblock type, returning DDERR_INVALIDPARAMS\n");
5840 return DDERR_INVALIDPARAMS;
5843 EnterCriticalSection(&ddraw_cs);
5844 *BlockHandle = IDirect3DDeviceImpl_CreateHandle(This);
5845 if(!*BlockHandle)
5847 ERR("Cannot get a handle number for the stateblock\n");
5848 LeaveCriticalSection(&ddraw_cs);
5849 return DDERR_OUTOFMEMORY;
5851 This->Handles[*BlockHandle - 1].type = DDrawHandle_StateBlock;
5853 /* The D3DSTATEBLOCKTYPE enum is fine here */
5854 hr = IWineD3DDevice_CreateStateBlock(This->wineD3DDevice,
5855 Type,
5856 (IWineD3DStateBlock **) &This->Handles[*BlockHandle - 1].ptr,
5857 NULL /* Parent, hope that works */);
5858 LeaveCriticalSection(&ddraw_cs);
5859 return hr_ddraw_from_wined3d(hr);
5862 static HRESULT WINAPI
5863 IDirect3DDeviceImpl_7_CreateStateBlock_FPUSetup(IDirect3DDevice7 *iface,
5864 D3DSTATEBLOCKTYPE Type,
5865 DWORD *BlockHandle)
5867 return IDirect3DDeviceImpl_7_CreateStateBlock(iface, Type, BlockHandle);
5870 static HRESULT WINAPI
5871 IDirect3DDeviceImpl_7_CreateStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
5872 D3DSTATEBLOCKTYPE Type,
5873 DWORD *BlockHandle)
5875 HRESULT hr;
5876 WORD old_fpucw;
5878 old_fpucw = d3d_fpu_setup();
5879 hr =IDirect3DDeviceImpl_7_CreateStateBlock(iface, Type, BlockHandle);
5880 set_fpu_control_word(old_fpucw);
5882 return hr;
5885 /* Helper function for IDirect3DDeviceImpl_7_Load. */
5886 static BOOL is_mip_level_subset(IDirectDrawSurfaceImpl *dest,
5887 IDirectDrawSurfaceImpl *src)
5889 IDirectDrawSurfaceImpl *src_level, *dest_level;
5890 IDirectDrawSurface7 *temp;
5891 DDSURFACEDESC2 ddsd;
5892 BOOL levelFound; /* at least one suitable sublevel in dest found */
5894 /* To satisfy "destination is mip level subset of source" criteria (regular texture counts as 1 level),
5895 * 1) there must be at least one mip level in destination that matched dimensions of some mip level in source and
5896 * 2) there must be no destination levels that don't match any levels in source. Otherwise it's INVALIDPARAMS.
5898 levelFound = FALSE;
5900 src_level = src;
5901 dest_level = dest;
5903 for (;src_level && dest_level;)
5905 if (src_level->surface_desc.dwWidth == dest_level->surface_desc.dwWidth &&
5906 src_level->surface_desc.dwHeight == dest_level->surface_desc.dwHeight)
5908 levelFound = TRUE;
5910 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
5911 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
5912 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7 *)dest_level, &ddsd.ddsCaps, &temp);
5914 if (dest_level != dest) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)dest_level);
5916 dest_level = (IDirectDrawSurfaceImpl *)temp;
5919 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
5920 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
5921 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7 *)src_level, &ddsd.ddsCaps, &temp);
5923 if (src_level != src) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)src_level);
5925 src_level = (IDirectDrawSurfaceImpl *)temp;
5928 if (src_level && src_level != src) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)src_level);
5929 if (dest_level && dest_level != dest) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)dest_level);
5931 return !dest_level && levelFound;
5934 /* Helper function for IDirect3DDeviceImpl_7_Load. */
5935 static void copy_mipmap_chain(IDirect3DDeviceImpl *device,
5936 IDirectDrawSurfaceImpl *dest,
5937 IDirectDrawSurfaceImpl *src,
5938 const POINT *DestPoint,
5939 const RECT *SrcRect)
5941 IDirectDrawSurfaceImpl *src_level, *dest_level;
5942 IDirectDrawSurface7 *temp;
5943 DDSURFACEDESC2 ddsd;
5944 POINT point;
5945 RECT rect;
5946 HRESULT hr;
5947 IDirectDrawPalette *pal = NULL, *pal_src = NULL;
5948 DWORD ckeyflag;
5949 DDCOLORKEY ddckey;
5950 BOOL palette_missing = FALSE;
5952 /* Copy palette, if possible. */
5953 IDirectDrawSurface7_GetPalette((IDirectDrawSurface7 *)src, &pal_src);
5954 IDirectDrawSurface7_GetPalette((IDirectDrawSurface7 *)dest, &pal);
5956 if (pal_src != NULL && pal != NULL)
5958 PALETTEENTRY palent[256];
5960 IDirectDrawPalette_GetEntries(pal_src, 0, 0, 256, palent);
5961 IDirectDrawPalette_SetEntries(pal, 0, 0, 256, palent);
5964 if (dest->surface_desc.u4.ddpfPixelFormat.dwFlags & (DDPF_PALETTEINDEXED1 | DDPF_PALETTEINDEXED2 |
5965 DDPF_PALETTEINDEXED4 | DDPF_PALETTEINDEXED8 | DDPF_PALETTEINDEXEDTO8) && !pal)
5967 palette_missing = TRUE;
5970 if (pal) IDirectDrawPalette_Release(pal);
5971 if (pal_src) IDirectDrawPalette_Release(pal_src);
5973 /* Copy colorkeys, if present. */
5974 for (ckeyflag = DDCKEY_DESTBLT; ckeyflag <= DDCKEY_SRCOVERLAY; ckeyflag <<= 1)
5976 hr = IDirectDrawSurface7_GetColorKey((IDirectDrawSurface7 *)src, ckeyflag, &ddckey);
5978 if (SUCCEEDED(hr))
5980 IDirectDrawSurface7_SetColorKey((IDirectDrawSurface7 *)dest, ckeyflag, &ddckey);
5984 src_level = src;
5985 dest_level = dest;
5987 point = *DestPoint;
5988 rect = *SrcRect;
5990 for (;src_level && dest_level;)
5992 if (src_level->surface_desc.dwWidth == dest_level->surface_desc.dwWidth &&
5993 src_level->surface_desc.dwHeight == dest_level->surface_desc.dwHeight)
5995 /* Try UpdateSurface that may perform a more direct opengl loading. But skip this if destination is paletted texture and has no palette.
5996 * Some games like Sacrifice set palette after Load, and it is a waste of effort to try to load texture without palette and generates
5997 * warnings in wined3d. */
5998 if (!palette_missing)
5999 hr = IWineD3DDevice_UpdateSurface(device->wineD3DDevice, src_level->WineD3DSurface, &rect, dest_level->WineD3DSurface,
6000 &point);
6002 if (palette_missing || FAILED(hr))
6004 /* UpdateSurface may fail e.g. if dest is in system memory. Fall back to BltFast that is less strict. */
6005 IWineD3DSurface_BltFast(dest_level->WineD3DSurface,
6006 point.x, point.y,
6007 src_level->WineD3DSurface, &rect, 0);
6010 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6011 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
6012 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7 *)dest_level, &ddsd.ddsCaps, &temp);
6014 if (dest_level != dest) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)dest_level);
6016 dest_level = (IDirectDrawSurfaceImpl *)temp;
6019 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6020 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
6021 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7 *)src_level, &ddsd.ddsCaps, &temp);
6023 if (src_level != src) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)src_level);
6025 src_level = (IDirectDrawSurfaceImpl *)temp;
6027 point.x /= 2;
6028 point.y /= 2;
6030 rect.top /= 2;
6031 rect.left /= 2;
6032 rect.right = (rect.right + 1) / 2;
6033 rect.bottom = (rect.bottom + 1) / 2;
6036 if (src_level && src_level != src) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)src_level);
6037 if (dest_level && dest_level != dest) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)dest_level);
6040 /*****************************************************************************
6041 * IDirect3DDevice7::Load
6043 * Loads a rectangular area from the source into the destination texture.
6044 * It can also copy the source to the faces of a cubic environment map
6046 * Version 7
6048 * Params:
6049 * DestTex: Destination texture
6050 * DestPoint: Point in the destination where the source image should be
6051 * written to
6052 * SrcTex: Source texture
6053 * SrcRect: Source rectangle
6054 * Flags: Cubemap faces to load (DDSCAPS2_CUBEMAP_ALLFACES, DDSCAPS2_CUBEMAP_POSITIVEX,
6055 * DDSCAPS2_CUBEMAP_NEGATIVEX, DDSCAPS2_CUBEMAP_POSITIVEY, DDSCAPS2_CUBEMAP_NEGATIVEY,
6056 * DDSCAPS2_CUBEMAP_POSITIVEZ, DDSCAPS2_CUBEMAP_NEGATIVEZ)
6058 * Returns:
6059 * D3D_OK on success
6060 * DDERR_INVALIDPARAMS if DestTex or SrcTex are NULL, broken coordinates or anything unexpected.
6063 *****************************************************************************/
6065 static HRESULT
6066 IDirect3DDeviceImpl_7_Load(IDirect3DDevice7 *iface,
6067 IDirectDrawSurface7 *DestTex,
6068 POINT *DestPoint,
6069 IDirectDrawSurface7 *SrcTex,
6070 RECT *SrcRect,
6071 DWORD Flags)
6073 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
6074 IDirectDrawSurfaceImpl *dest = (IDirectDrawSurfaceImpl *)DestTex;
6075 IDirectDrawSurfaceImpl *src = (IDirectDrawSurfaceImpl *)SrcTex;
6076 POINT destpoint;
6077 RECT srcrect;
6078 TRACE("(%p)->(%p,%p,%p,%p,%08x)\n", This, dest, DestPoint, src, SrcRect, Flags);
6080 if( (!src) || (!dest) )
6081 return DDERR_INVALIDPARAMS;
6083 EnterCriticalSection(&ddraw_cs);
6085 if (SrcRect) srcrect = *SrcRect;
6086 else
6088 srcrect.left = srcrect.top = 0;
6089 srcrect.right = src->surface_desc.dwWidth;
6090 srcrect.bottom = src->surface_desc.dwHeight;
6093 if (DestPoint) destpoint = *DestPoint;
6094 else
6096 destpoint.x = destpoint.y = 0;
6098 /* Check bad dimensions. DestPoint is validated against src, not dest, because
6099 * destination can be a subset of mip levels, in which case actual coordinates used
6100 * for it may be divided. If any dimension of dest is larger than source, it can't be
6101 * mip level subset, so an error can be returned early.
6103 if (srcrect.left >= srcrect.right || srcrect.top >= srcrect.bottom ||
6104 srcrect.right > src->surface_desc.dwWidth ||
6105 srcrect.bottom > src->surface_desc.dwHeight ||
6106 destpoint.x + srcrect.right - srcrect.left > src->surface_desc.dwWidth ||
6107 destpoint.y + srcrect.bottom - srcrect.top > src->surface_desc.dwHeight ||
6108 dest->surface_desc.dwWidth > src->surface_desc.dwWidth ||
6109 dest->surface_desc.dwHeight > src->surface_desc.dwHeight)
6111 LeaveCriticalSection(&ddraw_cs);
6112 return DDERR_INVALIDPARAMS;
6115 /* Must be top level surfaces. */
6116 if (src->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_MIPMAPSUBLEVEL ||
6117 dest->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_MIPMAPSUBLEVEL)
6119 LeaveCriticalSection(&ddraw_cs);
6120 return DDERR_INVALIDPARAMS;
6123 if (src->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP)
6125 DWORD src_face_flag, dest_face_flag;
6126 IDirectDrawSurfaceImpl *src_face, *dest_face;
6127 IDirectDrawSurface7 *temp;
6128 DDSURFACEDESC2 ddsd;
6129 int i;
6131 if (!(dest->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP))
6133 LeaveCriticalSection(&ddraw_cs);
6134 return DDERR_INVALIDPARAMS;
6137 /* Iterate through cube faces 2 times. First time is just to check INVALIDPARAMS conditions, second
6138 * time it's actual surface loading. */
6139 for (i = 0; i < 2; i++)
6141 dest_face = dest;
6142 src_face = src;
6144 for (;dest_face && src_face;)
6146 src_face_flag = src_face->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP_ALLFACES;
6147 dest_face_flag = dest_face->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP_ALLFACES;
6149 if (src_face_flag == dest_face_flag)
6151 if (i == 0)
6153 /* Destination mip levels must be subset of source mip levels. */
6154 if (!is_mip_level_subset(dest_face, src_face))
6156 LeaveCriticalSection(&ddraw_cs);
6157 return DDERR_INVALIDPARAMS;
6160 else if (Flags & dest_face_flag)
6162 copy_mipmap_chain(This, dest_face, src_face, &destpoint, &srcrect);
6165 if (src_face_flag < DDSCAPS2_CUBEMAP_NEGATIVEZ)
6167 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6168 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | (src_face_flag << 1);
6169 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7 *)src, &ddsd.ddsCaps, &temp);
6171 if (src_face != src) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)src_face);
6173 src_face = (IDirectDrawSurfaceImpl *)temp;
6175 else
6177 if (src_face != src) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)src_face);
6179 src_face = NULL;
6183 if (dest_face_flag < DDSCAPS2_CUBEMAP_NEGATIVEZ)
6185 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6186 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | (dest_face_flag << 1);
6187 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7 *)dest, &ddsd.ddsCaps, &temp);
6189 if (dest_face != dest) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)dest_face);
6191 dest_face = (IDirectDrawSurfaceImpl *)temp;
6193 else
6195 if (dest_face != dest) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)dest_face);
6197 dest_face = NULL;
6201 if (i == 0)
6203 /* Native returns error if src faces are not subset of dest faces. */
6204 if (src_face)
6206 LeaveCriticalSection(&ddraw_cs);
6207 return DDERR_INVALIDPARAMS;
6212 LeaveCriticalSection(&ddraw_cs);
6213 return D3D_OK;
6215 else if (dest->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP)
6217 LeaveCriticalSection(&ddraw_cs);
6218 return DDERR_INVALIDPARAMS;
6221 /* Handle non cube map textures. */
6223 /* Destination mip levels must be subset of source mip levels. */
6224 if (!is_mip_level_subset(dest, src))
6226 LeaveCriticalSection(&ddraw_cs);
6227 return DDERR_INVALIDPARAMS;
6230 copy_mipmap_chain(This, dest, src, &destpoint, &srcrect);
6232 LeaveCriticalSection(&ddraw_cs);
6233 return D3D_OK;
6236 static HRESULT WINAPI
6237 IDirect3DDeviceImpl_7_Load_FPUSetup(IDirect3DDevice7 *iface,
6238 IDirectDrawSurface7 *DestTex,
6239 POINT *DestPoint,
6240 IDirectDrawSurface7 *SrcTex,
6241 RECT *SrcRect,
6242 DWORD Flags)
6244 return IDirect3DDeviceImpl_7_Load(iface, DestTex, DestPoint, SrcTex, SrcRect, Flags);
6247 static HRESULT WINAPI
6248 IDirect3DDeviceImpl_7_Load_FPUPreserve(IDirect3DDevice7 *iface,
6249 IDirectDrawSurface7 *DestTex,
6250 POINT *DestPoint,
6251 IDirectDrawSurface7 *SrcTex,
6252 RECT *SrcRect,
6253 DWORD Flags)
6255 HRESULT hr;
6256 WORD old_fpucw;
6258 old_fpucw = d3d_fpu_setup();
6259 hr = IDirect3DDeviceImpl_7_Load(iface, DestTex, DestPoint, SrcTex, SrcRect, Flags);
6260 set_fpu_control_word(old_fpucw);
6262 return hr;
6265 /*****************************************************************************
6266 * IDirect3DDevice7::LightEnable
6268 * Enables or disables a light
6270 * Version 7, IDirect3DLight uses this method too.
6272 * Params:
6273 * LightIndex: The index of the light to enable / disable
6274 * Enable: Enable or disable the light
6276 * Returns:
6277 * D3D_OK on success
6278 * For more details, see IWineD3DDevice::SetLightEnable
6280 *****************************************************************************/
6281 static HRESULT
6282 IDirect3DDeviceImpl_7_LightEnable(IDirect3DDevice7 *iface,
6283 DWORD LightIndex,
6284 BOOL Enable)
6286 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
6287 HRESULT hr;
6288 TRACE("(%p)->(%08x,%d): Relay!\n", This, LightIndex, Enable);
6290 EnterCriticalSection(&ddraw_cs);
6291 hr = IWineD3DDevice_SetLightEnable(This->wineD3DDevice, LightIndex, Enable);
6292 LeaveCriticalSection(&ddraw_cs);
6293 return hr_ddraw_from_wined3d(hr);
6296 static HRESULT WINAPI
6297 IDirect3DDeviceImpl_7_LightEnable_FPUSetup(IDirect3DDevice7 *iface,
6298 DWORD LightIndex,
6299 BOOL Enable)
6301 return IDirect3DDeviceImpl_7_LightEnable(iface, LightIndex, Enable);
6304 static HRESULT WINAPI
6305 IDirect3DDeviceImpl_7_LightEnable_FPUPreserve(IDirect3DDevice7 *iface,
6306 DWORD LightIndex,
6307 BOOL Enable)
6309 HRESULT hr;
6310 WORD old_fpucw;
6312 old_fpucw = d3d_fpu_setup();
6313 hr = IDirect3DDeviceImpl_7_LightEnable(iface, LightIndex, Enable);
6314 set_fpu_control_word(old_fpucw);
6316 return hr;
6319 /*****************************************************************************
6320 * IDirect3DDevice7::GetLightEnable
6322 * Retrieves if the light with the given index is enabled or not
6324 * Version 7
6326 * Params:
6327 * LightIndex: Index of desired light
6328 * Enable: Pointer to a BOOL which contains the result
6330 * Returns:
6331 * D3D_OK on success
6332 * DDERR_INVALIDPARAMS if Enable is NULL
6333 * See IWineD3DDevice::GetLightEnable for more details
6335 *****************************************************************************/
6336 static HRESULT
6337 IDirect3DDeviceImpl_7_GetLightEnable(IDirect3DDevice7 *iface,
6338 DWORD LightIndex,
6339 BOOL* Enable)
6341 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
6342 HRESULT hr;
6343 TRACE("(%p)->(%08x,%p): Relay\n", This, LightIndex, Enable);
6345 if(!Enable)
6346 return DDERR_INVALIDPARAMS;
6348 EnterCriticalSection(&ddraw_cs);
6349 hr = IWineD3DDevice_GetLightEnable(This->wineD3DDevice, LightIndex, Enable);
6350 LeaveCriticalSection(&ddraw_cs);
6351 return hr_ddraw_from_wined3d(hr);
6354 static HRESULT WINAPI
6355 IDirect3DDeviceImpl_7_GetLightEnable_FPUSetup(IDirect3DDevice7 *iface,
6356 DWORD LightIndex,
6357 BOOL* Enable)
6359 return IDirect3DDeviceImpl_7_GetLightEnable(iface, LightIndex, Enable);
6362 static HRESULT WINAPI
6363 IDirect3DDeviceImpl_7_GetLightEnable_FPUPreserve(IDirect3DDevice7 *iface,
6364 DWORD LightIndex,
6365 BOOL* Enable)
6367 HRESULT hr;
6368 WORD old_fpucw;
6370 old_fpucw = d3d_fpu_setup();
6371 hr = IDirect3DDeviceImpl_7_GetLightEnable(iface, LightIndex, Enable);
6372 set_fpu_control_word(old_fpucw);
6374 return hr;
6377 /*****************************************************************************
6378 * IDirect3DDevice7::SetClipPlane
6380 * Sets custom clipping plane
6382 * Version 7
6384 * Params:
6385 * Index: The index of the clipping plane
6386 * PlaneEquation: An equation defining the clipping plane
6388 * Returns:
6389 * D3D_OK on success
6390 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6391 * See IWineD3DDevice::SetClipPlane for more details
6393 *****************************************************************************/
6394 static HRESULT
6395 IDirect3DDeviceImpl_7_SetClipPlane(IDirect3DDevice7 *iface,
6396 DWORD Index,
6397 D3DVALUE* PlaneEquation)
6399 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
6400 HRESULT hr;
6401 TRACE("(%p)->(%08x,%p): Relay!\n", This, Index, PlaneEquation);
6403 if(!PlaneEquation)
6404 return DDERR_INVALIDPARAMS;
6406 EnterCriticalSection(&ddraw_cs);
6407 hr = IWineD3DDevice_SetClipPlane(This->wineD3DDevice, Index, PlaneEquation);
6408 LeaveCriticalSection(&ddraw_cs);
6409 return hr;
6412 static HRESULT WINAPI
6413 IDirect3DDeviceImpl_7_SetClipPlane_FPUSetup(IDirect3DDevice7 *iface,
6414 DWORD Index,
6415 D3DVALUE* PlaneEquation)
6417 return IDirect3DDeviceImpl_7_SetClipPlane(iface, Index, PlaneEquation);
6420 static HRESULT WINAPI
6421 IDirect3DDeviceImpl_7_SetClipPlane_FPUPreserve(IDirect3DDevice7 *iface,
6422 DWORD Index,
6423 D3DVALUE* PlaneEquation)
6425 HRESULT hr;
6426 WORD old_fpucw;
6428 old_fpucw = d3d_fpu_setup();
6429 hr = IDirect3DDeviceImpl_7_SetClipPlane(iface, Index, PlaneEquation);
6430 set_fpu_control_word(old_fpucw);
6432 return hr;
6435 /*****************************************************************************
6436 * IDirect3DDevice7::GetClipPlane
6438 * Returns the clipping plane with a specific index
6440 * Params:
6441 * Index: The index of the desired plane
6442 * PlaneEquation: Address to store the plane equation to
6444 * Returns:
6445 * D3D_OK on success
6446 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6447 * See IWineD3DDevice::GetClipPlane for more details
6449 *****************************************************************************/
6450 static HRESULT
6451 IDirect3DDeviceImpl_7_GetClipPlane(IDirect3DDevice7 *iface,
6452 DWORD Index,
6453 D3DVALUE* PlaneEquation)
6455 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
6456 HRESULT hr;
6457 TRACE("(%p)->(%d,%p): Relay!\n", This, Index, PlaneEquation);
6459 if(!PlaneEquation)
6460 return DDERR_INVALIDPARAMS;
6462 EnterCriticalSection(&ddraw_cs);
6463 hr = IWineD3DDevice_GetClipPlane(This->wineD3DDevice, Index, PlaneEquation);
6464 LeaveCriticalSection(&ddraw_cs);
6465 return hr;
6468 static HRESULT WINAPI
6469 IDirect3DDeviceImpl_7_GetClipPlane_FPUSetup(IDirect3DDevice7 *iface,
6470 DWORD Index,
6471 D3DVALUE* PlaneEquation)
6473 return IDirect3DDeviceImpl_7_GetClipPlane(iface, Index, PlaneEquation);
6476 static HRESULT WINAPI
6477 IDirect3DDeviceImpl_7_GetClipPlane_FPUPreserve(IDirect3DDevice7 *iface,
6478 DWORD Index,
6479 D3DVALUE* PlaneEquation)
6481 HRESULT hr;
6482 WORD old_fpucw;
6484 old_fpucw = d3d_fpu_setup();
6485 hr = IDirect3DDeviceImpl_7_GetClipPlane(iface, Index, PlaneEquation);
6486 set_fpu_control_word(old_fpucw);
6488 return hr;
6491 /*****************************************************************************
6492 * IDirect3DDevice7::GetInfo
6494 * Retrieves some information about the device. The DirectX sdk says that
6495 * this version returns S_FALSE for all retail builds of DirectX, that's what
6496 * this implementation does.
6498 * Params:
6499 * DevInfoID: Information type requested
6500 * DevInfoStruct: Pointer to a structure to store the info to
6501 * Size: Size of the structure
6503 * Returns:
6504 * S_FALSE, because it's a non-debug driver
6506 *****************************************************************************/
6507 static HRESULT WINAPI
6508 IDirect3DDeviceImpl_7_GetInfo(IDirect3DDevice7 *iface,
6509 DWORD DevInfoID,
6510 void *DevInfoStruct,
6511 DWORD Size)
6513 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
6514 TRACE("(%p)->(%08x,%p,%08x)\n", This, DevInfoID, DevInfoStruct, Size);
6516 if (TRACE_ON(d3d7))
6518 TRACE(" info requested : ");
6519 switch (DevInfoID)
6521 case D3DDEVINFOID_TEXTUREMANAGER: TRACE("D3DDEVINFOID_TEXTUREMANAGER\n"); break;
6522 case D3DDEVINFOID_D3DTEXTUREMANAGER: TRACE("D3DDEVINFOID_D3DTEXTUREMANAGER\n"); break;
6523 case D3DDEVINFOID_TEXTURING: TRACE("D3DDEVINFOID_TEXTURING\n"); break;
6524 default: ERR(" invalid flag !!!\n"); return DDERR_INVALIDPARAMS;
6528 return S_FALSE; /* According to MSDN, this is valid for a non-debug driver */
6531 /* For performance optimization, devices created in FPUSETUP and FPUPRESERVE modes
6532 * have separate vtables. Simple functions where this doesn't matter like GetDirect3D
6533 * are not duplicated.
6535 * Device created with DDSCL_FPUSETUP (d3d7 default) - device methods assume that FPU
6536 * has already been setup for optimal d3d operation.
6538 * Device created with DDSCL_FPUPRESERVE - resets and restores FPU mode when necessary in
6539 * d3d calls (FPU may be in a mode non-suitable for d3d when the app calls d3d). Required
6540 * by Sacrifice (game). */
6541 const IDirect3DDevice7Vtbl IDirect3DDevice7_FPUSetup_Vtbl =
6543 /*** IUnknown Methods ***/
6544 IDirect3DDeviceImpl_7_QueryInterface,
6545 IDirect3DDeviceImpl_7_AddRef,
6546 IDirect3DDeviceImpl_7_Release,
6547 /*** IDirect3DDevice7 ***/
6548 IDirect3DDeviceImpl_7_GetCaps_FPUSetup,
6549 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUSetup,
6550 IDirect3DDeviceImpl_7_BeginScene_FPUSetup,
6551 IDirect3DDeviceImpl_7_EndScene_FPUSetup,
6552 IDirect3DDeviceImpl_7_GetDirect3D,
6553 IDirect3DDeviceImpl_7_SetRenderTarget_FPUSetup,
6554 IDirect3DDeviceImpl_7_GetRenderTarget,
6555 IDirect3DDeviceImpl_7_Clear_FPUSetup,
6556 IDirect3DDeviceImpl_7_SetTransform_FPUSetup,
6557 IDirect3DDeviceImpl_7_GetTransform_FPUSetup,
6558 IDirect3DDeviceImpl_7_SetViewport_FPUSetup,
6559 IDirect3DDeviceImpl_7_MultiplyTransform_FPUSetup,
6560 IDirect3DDeviceImpl_7_GetViewport_FPUSetup,
6561 IDirect3DDeviceImpl_7_SetMaterial_FPUSetup,
6562 IDirect3DDeviceImpl_7_GetMaterial_FPUSetup,
6563 IDirect3DDeviceImpl_7_SetLight_FPUSetup,
6564 IDirect3DDeviceImpl_7_GetLight_FPUSetup,
6565 IDirect3DDeviceImpl_7_SetRenderState_FPUSetup,
6566 IDirect3DDeviceImpl_7_GetRenderState_FPUSetup,
6567 IDirect3DDeviceImpl_7_BeginStateBlock_FPUSetup,
6568 IDirect3DDeviceImpl_7_EndStateBlock_FPUSetup,
6569 IDirect3DDeviceImpl_7_PreLoad_FPUSetup,
6570 IDirect3DDeviceImpl_7_DrawPrimitive_FPUSetup,
6571 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUSetup,
6572 IDirect3DDeviceImpl_7_SetClipStatus,
6573 IDirect3DDeviceImpl_7_GetClipStatus,
6574 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUSetup,
6575 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUSetup,
6576 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUSetup,
6577 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUSetup,
6578 IDirect3DDeviceImpl_7_ComputeSphereVisibility,
6579 IDirect3DDeviceImpl_7_GetTexture_FPUSetup,
6580 IDirect3DDeviceImpl_7_SetTexture_FPUSetup,
6581 IDirect3DDeviceImpl_7_GetTextureStageState_FPUSetup,
6582 IDirect3DDeviceImpl_7_SetTextureStageState_FPUSetup,
6583 IDirect3DDeviceImpl_7_ValidateDevice_FPUSetup,
6584 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUSetup,
6585 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUSetup,
6586 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUSetup,
6587 IDirect3DDeviceImpl_7_CreateStateBlock_FPUSetup,
6588 IDirect3DDeviceImpl_7_Load_FPUSetup,
6589 IDirect3DDeviceImpl_7_LightEnable_FPUSetup,
6590 IDirect3DDeviceImpl_7_GetLightEnable_FPUSetup,
6591 IDirect3DDeviceImpl_7_SetClipPlane_FPUSetup,
6592 IDirect3DDeviceImpl_7_GetClipPlane_FPUSetup,
6593 IDirect3DDeviceImpl_7_GetInfo
6596 const IDirect3DDevice7Vtbl IDirect3DDevice7_FPUPreserve_Vtbl =
6598 /*** IUnknown Methods ***/
6599 IDirect3DDeviceImpl_7_QueryInterface,
6600 IDirect3DDeviceImpl_7_AddRef,
6601 IDirect3DDeviceImpl_7_Release,
6602 /*** IDirect3DDevice7 ***/
6603 IDirect3DDeviceImpl_7_GetCaps_FPUPreserve,
6604 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUPreserve,
6605 IDirect3DDeviceImpl_7_BeginScene_FPUPreserve,
6606 IDirect3DDeviceImpl_7_EndScene_FPUPreserve,
6607 IDirect3DDeviceImpl_7_GetDirect3D,
6608 IDirect3DDeviceImpl_7_SetRenderTarget_FPUPreserve,
6609 IDirect3DDeviceImpl_7_GetRenderTarget,
6610 IDirect3DDeviceImpl_7_Clear_FPUPreserve,
6611 IDirect3DDeviceImpl_7_SetTransform_FPUPreserve,
6612 IDirect3DDeviceImpl_7_GetTransform_FPUPreserve,
6613 IDirect3DDeviceImpl_7_SetViewport_FPUPreserve,
6614 IDirect3DDeviceImpl_7_MultiplyTransform_FPUPreserve,
6615 IDirect3DDeviceImpl_7_GetViewport_FPUPreserve,
6616 IDirect3DDeviceImpl_7_SetMaterial_FPUPreserve,
6617 IDirect3DDeviceImpl_7_GetMaterial_FPUPreserve,
6618 IDirect3DDeviceImpl_7_SetLight_FPUPreserve,
6619 IDirect3DDeviceImpl_7_GetLight_FPUPreserve,
6620 IDirect3DDeviceImpl_7_SetRenderState_FPUPreserve,
6621 IDirect3DDeviceImpl_7_GetRenderState_FPUPreserve,
6622 IDirect3DDeviceImpl_7_BeginStateBlock_FPUPreserve,
6623 IDirect3DDeviceImpl_7_EndStateBlock_FPUPreserve,
6624 IDirect3DDeviceImpl_7_PreLoad_FPUPreserve,
6625 IDirect3DDeviceImpl_7_DrawPrimitive_FPUPreserve,
6626 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUPreserve,
6627 IDirect3DDeviceImpl_7_SetClipStatus,
6628 IDirect3DDeviceImpl_7_GetClipStatus,
6629 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUPreserve,
6630 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUPreserve,
6631 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUPreserve,
6632 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUPreserve,
6633 IDirect3DDeviceImpl_7_ComputeSphereVisibility,
6634 IDirect3DDeviceImpl_7_GetTexture_FPUPreserve,
6635 IDirect3DDeviceImpl_7_SetTexture_FPUPreserve,
6636 IDirect3DDeviceImpl_7_GetTextureStageState_FPUPreserve,
6637 IDirect3DDeviceImpl_7_SetTextureStageState_FPUPreserve,
6638 IDirect3DDeviceImpl_7_ValidateDevice_FPUPreserve,
6639 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUPreserve,
6640 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUPreserve,
6641 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUPreserve,
6642 IDirect3DDeviceImpl_7_CreateStateBlock_FPUPreserve,
6643 IDirect3DDeviceImpl_7_Load_FPUPreserve,
6644 IDirect3DDeviceImpl_7_LightEnable_FPUPreserve,
6645 IDirect3DDeviceImpl_7_GetLightEnable_FPUPreserve,
6646 IDirect3DDeviceImpl_7_SetClipPlane_FPUPreserve,
6647 IDirect3DDeviceImpl_7_GetClipPlane_FPUPreserve,
6648 IDirect3DDeviceImpl_7_GetInfo
6651 const IDirect3DDevice3Vtbl IDirect3DDevice3_Vtbl =
6653 /*** IUnknown Methods ***/
6654 Thunk_IDirect3DDeviceImpl_3_QueryInterface,
6655 Thunk_IDirect3DDeviceImpl_3_AddRef,
6656 Thunk_IDirect3DDeviceImpl_3_Release,
6657 /*** IDirect3DDevice3 ***/
6658 IDirect3DDeviceImpl_3_GetCaps,
6659 IDirect3DDeviceImpl_3_GetStats,
6660 IDirect3DDeviceImpl_3_AddViewport,
6661 IDirect3DDeviceImpl_3_DeleteViewport,
6662 IDirect3DDeviceImpl_3_NextViewport,
6663 Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats,
6664 Thunk_IDirect3DDeviceImpl_3_BeginScene,
6665 Thunk_IDirect3DDeviceImpl_3_EndScene,
6666 Thunk_IDirect3DDeviceImpl_3_GetDirect3D,
6667 IDirect3DDeviceImpl_3_SetCurrentViewport,
6668 IDirect3DDeviceImpl_3_GetCurrentViewport,
6669 Thunk_IDirect3DDeviceImpl_3_SetRenderTarget,
6670 Thunk_IDirect3DDeviceImpl_3_GetRenderTarget,
6671 IDirect3DDeviceImpl_3_Begin,
6672 IDirect3DDeviceImpl_3_BeginIndexed,
6673 IDirect3DDeviceImpl_3_Vertex,
6674 IDirect3DDeviceImpl_3_Index,
6675 IDirect3DDeviceImpl_3_End,
6676 IDirect3DDeviceImpl_3_GetRenderState,
6677 IDirect3DDeviceImpl_3_SetRenderState,
6678 IDirect3DDeviceImpl_3_GetLightState,
6679 IDirect3DDeviceImpl_3_SetLightState,
6680 Thunk_IDirect3DDeviceImpl_3_SetTransform,
6681 Thunk_IDirect3DDeviceImpl_3_GetTransform,
6682 Thunk_IDirect3DDeviceImpl_3_MultiplyTransform,
6683 Thunk_IDirect3DDeviceImpl_3_DrawPrimitive,
6684 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive,
6685 Thunk_IDirect3DDeviceImpl_3_SetClipStatus,
6686 Thunk_IDirect3DDeviceImpl_3_GetClipStatus,
6687 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided,
6688 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided,
6689 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB,
6690 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB,
6691 Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility,
6692 Thunk_IDirect3DDeviceImpl_3_GetTexture,
6693 IDirect3DDeviceImpl_3_SetTexture,
6694 Thunk_IDirect3DDeviceImpl_3_GetTextureStageState,
6695 Thunk_IDirect3DDeviceImpl_3_SetTextureStageState,
6696 Thunk_IDirect3DDeviceImpl_3_ValidateDevice
6699 const IDirect3DDevice2Vtbl IDirect3DDevice2_Vtbl =
6701 /*** IUnknown Methods ***/
6702 Thunk_IDirect3DDeviceImpl_2_QueryInterface,
6703 Thunk_IDirect3DDeviceImpl_2_AddRef,
6704 Thunk_IDirect3DDeviceImpl_2_Release,
6705 /*** IDirect3DDevice2 ***/
6706 Thunk_IDirect3DDeviceImpl_2_GetCaps,
6707 IDirect3DDeviceImpl_2_SwapTextureHandles,
6708 Thunk_IDirect3DDeviceImpl_2_GetStats,
6709 Thunk_IDirect3DDeviceImpl_2_AddViewport,
6710 Thunk_IDirect3DDeviceImpl_2_DeleteViewport,
6711 Thunk_IDirect3DDeviceImpl_2_NextViewport,
6712 IDirect3DDeviceImpl_2_EnumTextureFormats,
6713 Thunk_IDirect3DDeviceImpl_2_BeginScene,
6714 Thunk_IDirect3DDeviceImpl_2_EndScene,
6715 Thunk_IDirect3DDeviceImpl_2_GetDirect3D,
6716 Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport,
6717 Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport,
6718 Thunk_IDirect3DDeviceImpl_2_SetRenderTarget,
6719 Thunk_IDirect3DDeviceImpl_2_GetRenderTarget,
6720 Thunk_IDirect3DDeviceImpl_2_Begin,
6721 Thunk_IDirect3DDeviceImpl_2_BeginIndexed,
6722 Thunk_IDirect3DDeviceImpl_2_Vertex,
6723 Thunk_IDirect3DDeviceImpl_2_Index,
6724 Thunk_IDirect3DDeviceImpl_2_End,
6725 Thunk_IDirect3DDeviceImpl_2_GetRenderState,
6726 Thunk_IDirect3DDeviceImpl_2_SetRenderState,
6727 Thunk_IDirect3DDeviceImpl_2_GetLightState,
6728 Thunk_IDirect3DDeviceImpl_2_SetLightState,
6729 Thunk_IDirect3DDeviceImpl_2_SetTransform,
6730 Thunk_IDirect3DDeviceImpl_2_GetTransform,
6731 Thunk_IDirect3DDeviceImpl_2_MultiplyTransform,
6732 Thunk_IDirect3DDeviceImpl_2_DrawPrimitive,
6733 Thunk_IDirect3DDeviceImpl_2_DrawIndexedPrimitive,
6734 Thunk_IDirect3DDeviceImpl_2_SetClipStatus,
6735 Thunk_IDirect3DDeviceImpl_2_GetClipStatus
6738 const IDirect3DDeviceVtbl IDirect3DDevice1_Vtbl =
6740 /*** IUnknown Methods ***/
6741 Thunk_IDirect3DDeviceImpl_1_QueryInterface,
6742 Thunk_IDirect3DDeviceImpl_1_AddRef,
6743 Thunk_IDirect3DDeviceImpl_1_Release,
6744 /*** IDirect3DDevice1 ***/
6745 IDirect3DDeviceImpl_1_Initialize,
6746 Thunk_IDirect3DDeviceImpl_1_GetCaps,
6747 Thunk_IDirect3DDeviceImpl_1_SwapTextureHandles,
6748 IDirect3DDeviceImpl_1_CreateExecuteBuffer,
6749 Thunk_IDirect3DDeviceImpl_1_GetStats,
6750 IDirect3DDeviceImpl_1_Execute,
6751 Thunk_IDirect3DDeviceImpl_1_AddViewport,
6752 Thunk_IDirect3DDeviceImpl_1_DeleteViewport,
6753 Thunk_IDirect3DDeviceImpl_1_NextViewport,
6754 IDirect3DDeviceImpl_1_Pick,
6755 IDirect3DDeviceImpl_1_GetPickRecords,
6756 Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats,
6757 IDirect3DDeviceImpl_1_CreateMatrix,
6758 IDirect3DDeviceImpl_1_SetMatrix,
6759 IDirect3DDeviceImpl_1_GetMatrix,
6760 IDirect3DDeviceImpl_1_DeleteMatrix,
6761 Thunk_IDirect3DDeviceImpl_1_BeginScene,
6762 Thunk_IDirect3DDeviceImpl_1_EndScene,
6763 Thunk_IDirect3DDeviceImpl_1_GetDirect3D
6766 /*****************************************************************************
6767 * IDirect3DDeviceImpl_CreateHandle
6769 * Not called from the VTable
6771 * Some older interface versions operate with handles, which are basically
6772 * DWORDs which identify an interface, for example
6773 * IDirect3DDevice::SetRenderState with DIRECT3DRENDERSTATE_TEXTUREHANDLE
6775 * Those handle could be just casts to the interface pointers or vice versa,
6776 * but that is not 64 bit safe and would mean blindly derefering a DWORD
6777 * passed by the app. Instead there is a dynamic array in the device which
6778 * keeps a DWORD to pointer information and a type for the handle.
6780 * Basically this array only grows, when a handle is freed its pointer is
6781 * just set to NULL. There will be much more reads from the array than
6782 * insertion operations, so a dynamic array is fine.
6784 * Params:
6785 * This: D3DDevice implementation for which this handle should be created
6787 * Returns:
6788 * A free handle on success
6789 * 0 on failure
6791 *****************************************************************************/
6792 DWORD
6793 IDirect3DDeviceImpl_CreateHandle(IDirect3DDeviceImpl *This)
6795 DWORD i;
6796 struct HandleEntry *oldHandles = This->Handles;
6798 TRACE("(%p)\n", This);
6800 for(i = 0; i < This->numHandles; i++)
6802 if(This->Handles[i].ptr == NULL &&
6803 This->Handles[i].type == DDrawHandle_Unknown)
6805 TRACE("Reusing freed handle %d\n", i + 1);
6806 return i + 1;
6810 TRACE("Growing the handle array\n");
6812 This->numHandles++;
6813 This->Handles = HeapAlloc(GetProcessHeap(), 0, sizeof(struct HandleEntry) * This->numHandles);
6814 if(!This->Handles)
6816 ERR("Out of memory\n");
6817 This->Handles = oldHandles;
6818 This->numHandles--;
6819 return 0;
6821 if(oldHandles)
6823 memcpy(This->Handles, oldHandles, (This->numHandles - 1) * sizeof(struct HandleEntry));
6824 HeapFree(GetProcessHeap(), 0, oldHandles);
6827 TRACE("Returning %d\n", This->numHandles);
6828 return This->numHandles;
6831 /*****************************************************************************
6832 * IDirect3DDeviceImpl_UpdateDepthStencil
6834 * Checks the current render target for attached depth stencils and sets the
6835 * WineD3D depth stencil accordingly.
6837 * Returns:
6838 * The depth stencil state to set if creating the device
6840 *****************************************************************************/
6841 WINED3DZBUFFERTYPE
6842 IDirect3DDeviceImpl_UpdateDepthStencil(IDirect3DDeviceImpl *This)
6844 IDirectDrawSurface7 *depthStencil = NULL;
6845 IDirectDrawSurfaceImpl *dsi;
6846 static DDSCAPS2 depthcaps = { DDSCAPS_ZBUFFER, 0, 0, 0 };
6848 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7 *)This->target, &depthcaps, &depthStencil);
6849 if(!depthStencil)
6851 TRACE("Setting wined3d depth stencil to NULL\n");
6852 IWineD3DDevice_SetDepthStencilSurface(This->wineD3DDevice,
6853 NULL);
6854 return WINED3DZB_FALSE;
6857 dsi = (IDirectDrawSurfaceImpl *)depthStencil;
6858 TRACE("Setting wined3d depth stencil to %p (wined3d %p)\n", dsi, dsi->WineD3DSurface);
6859 IWineD3DDevice_SetDepthStencilSurface(This->wineD3DDevice,
6860 dsi->WineD3DSurface);
6862 IDirectDrawSurface7_Release(depthStencil);
6863 return WINED3DZB_TRUE;