msvcrt/tests: Remove a space before a '\n'.
[wine/gsoc-2012-control.git] / dlls / ddraw / device.c
blobdb43b5579f3200919c63348ad95f8a1b7f03082d
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_SetIndices(This->wineD3DDevice, NULL);
320 IWineD3DIndexBuffer_GetParent(This->indexbuffer,
321 (IUnknown **) &IndexBufferParent);
322 IParent_Release(IndexBufferParent); /* Once for the getParent */
323 if( IParent_Release(IndexBufferParent) != 0) /* And now to destroy it */
325 ERR(" (%p) Something is still holding the index buffer parent %p\n", This, IndexBufferParent);
328 /* There is no need to unset the vertex buffer here, IWineD3DDevice_Uninit3D will do that when
329 * destroying the primary stateblock. If a vertex buffer is destroyed while it is bound
330 * IDirect3DVertexBuffer::Release will unset it.
333 /* Restore the render targets */
334 if(This->OffScreenTarget)
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_A8R8G8B8,
1151 WINED3DFMT_X8R8G8B8,
1152 /* 24 bit */
1153 WINED3DFMT_R8G8B8,
1154 /* 16 Bit */
1155 WINED3DFMT_A1R5G5B5,
1156 WINED3DFMT_A4R4G4B4,
1157 WINED3DFMT_R5G6B5,
1158 WINED3DFMT_X1R5G5B5,
1159 /* 8 Bit */
1160 WINED3DFMT_R3G3B2,
1161 WINED3DFMT_P8,
1162 /* FOURCC codes */
1163 WINED3DFMT_DXT1,
1164 WINED3DFMT_DXT3,
1165 WINED3DFMT_DXT5,
1168 WINED3DFORMAT BumpFormatList[] = {
1169 WINED3DFMT_V8U8,
1170 WINED3DFMT_L6V5U5,
1171 WINED3DFMT_X8L8V8U8,
1172 WINED3DFMT_Q8W8V8U8,
1173 WINED3DFMT_V16U16,
1174 WINED3DFMT_W11V11U10,
1175 WINED3DFMT_A2W10V10U10
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_A8R8G8B8,
1313 WINED3DFMT_X8R8G8B8,
1314 /* 24 bit */
1315 WINED3DFMT_R8G8B8,
1316 /* 16 Bit */
1317 WINED3DFMT_A1R5G5B5,
1318 WINED3DFMT_A4R4G4B4,
1319 WINED3DFMT_R5G6B5,
1320 WINED3DFMT_X1R5G5B5,
1321 /* 8 Bit */
1322 WINED3DFMT_R3G3B2,
1323 WINED3DFMT_P8,
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
1708 IDirect3DDeviceImpl_7_EndScene_FPUSetup(IDirect3DDevice7 *iface)
1710 return IDirect3DDeviceImpl_7_EndScene(iface);
1713 static HRESULT WINAPI
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
1727 Thunk_IDirect3DDeviceImpl_3_EndScene(IDirect3DDevice3 *iface)
1729 IDirect3DDeviceImpl *This = device_from_device3(iface);
1730 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1731 return IDirect3DDevice7_EndScene((IDirect3DDevice7 *)This);
1734 static HRESULT WINAPI
1735 Thunk_IDirect3DDeviceImpl_2_EndScene(IDirect3DDevice2 *iface)
1737 IDirect3DDeviceImpl *This = device_from_device2(iface);
1738 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1739 return IDirect3DDevice7_EndScene((IDirect3DDevice7 *)This);
1742 static HRESULT WINAPI
1743 Thunk_IDirect3DDeviceImpl_1_EndScene(IDirect3DDevice *iface)
1745 IDirect3DDeviceImpl *This = device_from_device1(iface);
1746 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1747 return IDirect3DDevice7_EndScene((IDirect3DDevice7 *)This);
1750 /*****************************************************************************
1751 * IDirect3DDevice7::GetDirect3D
1753 * Returns the IDirect3D(= interface to the DirectDraw object) used to create
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 *)&((IDirectDrawImpl *)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 *)&((IDirectDrawImpl *)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 *)&((IDirectDrawImpl *)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 WINED3DFORMAT fmt;
2562 DDPIXELFORMAT ddfmt;
2564 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice,
2566 &tex);
2568 if(hr == WINED3D_OK && tex)
2570 memset(&desc, 0, sizeof(desc));
2571 desc.Format = &fmt;
2572 hr = IWineD3DTexture_GetLevelDesc((IWineD3DTexture*) tex, 0, &desc);
2573 if (SUCCEEDED(hr))
2575 ddfmt.dwSize = sizeof(ddfmt);
2576 PixelFormat_WineD3DtoDD(&ddfmt, fmt);
2577 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
2580 IWineD3DBaseTexture_Release(tex);
2583 if (!(colorop == WINED3DTOP_MODULATE && colorarg1 == WINED3DTA_TEXTURE && colorarg2 == WINED3DTA_CURRENT &&
2584 alphaop == WINED3DTOP_SELECTARG1 && alphaarg1 == (tex_alpha ? WINED3DTA_TEXTURE : WINED3DTA_CURRENT)))
2586 ERR("Unexpected texture stage state setup, returning D3DTBLEND_MODULATE - likely erroneous\n");
2589 *lpdwRenderState = D3DTBLEND_MODULATE;
2592 LeaveCriticalSection(&ddraw_cs);
2594 return D3D_OK;
2597 default:
2598 return IDirect3DDevice7_GetRenderState((IDirect3DDevice7 *)This, dwRenderStateType, lpdwRenderState);
2602 static HRESULT WINAPI
2603 Thunk_IDirect3DDeviceImpl_2_GetRenderState(IDirect3DDevice2 *iface,
2604 D3DRENDERSTATETYPE dwRenderStateType,
2605 DWORD *lpdwRenderState)
2607 IDirect3DDeviceImpl *This = device_from_device2(iface);
2608 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice3 interface.\n", This, dwRenderStateType, lpdwRenderState);
2609 return IDirect3DDevice3_GetRenderState((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl,
2610 dwRenderStateType, lpdwRenderState);
2613 /*****************************************************************************
2614 * IDirect3DDevice7::SetRenderState
2616 * Sets a render state. The possible render states are defined in
2617 * include/d3dtypes.h
2619 * Version 2, 3 and 7
2621 * Params:
2622 * RenderStateType: State to set
2623 * Value: Value to assign to that state
2625 * Returns:
2626 * D3D_OK on success,
2627 * for details see IWineD3DDevice::SetRenderState
2629 *****************************************************************************/
2630 static HRESULT
2631 IDirect3DDeviceImpl_7_SetRenderState(IDirect3DDevice7 *iface,
2632 D3DRENDERSTATETYPE RenderStateType,
2633 DWORD Value)
2635 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
2636 HRESULT hr;
2637 TRACE("(%p)->(%08x,%d): Relay\n", This, RenderStateType, Value);
2639 EnterCriticalSection(&ddraw_cs);
2640 /* Some render states need special care */
2641 switch(RenderStateType)
2643 case D3DRENDERSTATE_TEXTUREMAG:
2645 WINED3DTEXTUREFILTERTYPE tex_mag = WINED3DTEXF_NONE;
2647 switch ((D3DTEXTUREFILTER) Value)
2649 case D3DFILTER_NEAREST:
2650 case D3DFILTER_LINEARMIPNEAREST:
2651 tex_mag = WINED3DTEXF_POINT;
2652 break;
2653 case D3DFILTER_LINEAR:
2654 case D3DFILTER_LINEARMIPLINEAR:
2655 tex_mag = WINED3DTEXF_LINEAR;
2656 break;
2657 default:
2658 ERR("Unhandled texture mag %d !\n",Value);
2661 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2662 0, WINED3DSAMP_MAGFILTER,
2663 tex_mag);
2664 break;
2667 case D3DRENDERSTATE_TEXTUREMIN:
2669 WINED3DTEXTUREFILTERTYPE tex_min = WINED3DTEXF_NONE;
2670 WINED3DTEXTUREFILTERTYPE tex_mip = WINED3DTEXF_NONE;
2672 switch ((D3DTEXTUREFILTER) Value)
2674 case D3DFILTER_NEAREST:
2675 tex_min = WINED3DTEXF_POINT;
2676 break;
2677 case D3DFILTER_LINEAR:
2678 tex_min = WINED3DTEXF_LINEAR;
2679 break;
2680 case D3DFILTER_MIPNEAREST:
2681 tex_min = WINED3DTEXF_NONE;
2682 tex_mip = WINED3DTEXF_POINT;
2683 break;
2684 case D3DFILTER_MIPLINEAR:
2685 tex_min = WINED3DTEXF_NONE;
2686 tex_mip = WINED3DTEXF_LINEAR;
2687 break;
2688 case D3DFILTER_LINEARMIPNEAREST:
2689 tex_min = WINED3DTEXF_POINT;
2690 tex_mip = WINED3DTEXF_LINEAR;
2691 break;
2692 case D3DFILTER_LINEARMIPLINEAR:
2693 tex_min = WINED3DTEXF_LINEAR;
2694 tex_mip = WINED3DTEXF_LINEAR;
2695 break;
2697 default:
2698 ERR("Unhandled texture min %d !\n",Value);
2701 IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2702 0, WINED3DSAMP_MIPFILTER,
2703 tex_mip);
2704 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2705 0, WINED3DSAMP_MINFILTER,
2706 tex_min);
2707 break;
2710 case D3DRENDERSTATE_TEXTUREADDRESS:
2711 IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2712 0, WINED3DSAMP_ADDRESSV,
2713 Value);
2714 /* Drop through */
2715 case D3DRENDERSTATE_TEXTUREADDRESSU:
2716 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2717 0, WINED3DSAMP_ADDRESSU,
2718 Value);
2719 break;
2720 case D3DRENDERSTATE_TEXTUREADDRESSV:
2721 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2722 0, WINED3DSAMP_ADDRESSV,
2723 Value);
2724 break;
2726 default:
2728 /* FIXME: Unhandled: D3DRENDERSTATE_STIPPLEPATTERN00 - 31 */
2730 hr = IWineD3DDevice_SetRenderState(This->wineD3DDevice,
2731 RenderStateType,
2732 Value);
2733 break;
2735 LeaveCriticalSection(&ddraw_cs);
2736 return hr;
2739 static HRESULT WINAPI
2740 IDirect3DDeviceImpl_7_SetRenderState_FPUSetup(IDirect3DDevice7 *iface,
2741 D3DRENDERSTATETYPE RenderStateType,
2742 DWORD Value)
2744 return IDirect3DDeviceImpl_7_SetRenderState(iface, RenderStateType, Value);
2747 static HRESULT WINAPI
2748 IDirect3DDeviceImpl_7_SetRenderState_FPUPreserve(IDirect3DDevice7 *iface,
2749 D3DRENDERSTATETYPE RenderStateType,
2750 DWORD Value)
2752 HRESULT hr;
2753 WORD old_fpucw;
2755 old_fpucw = d3d_fpu_setup();
2756 hr = IDirect3DDeviceImpl_7_SetRenderState(iface, RenderStateType, Value);
2757 set_fpu_control_word(old_fpucw);
2759 return hr;
2762 static HRESULT WINAPI
2763 IDirect3DDeviceImpl_3_SetRenderState(IDirect3DDevice3 *iface,
2764 D3DRENDERSTATETYPE RenderStateType,
2765 DWORD Value)
2767 /* Note about D3DRENDERSTATE_TEXTUREMAPBLEND implementation: most of values
2768 for this state can be directly mapped to texture stage colorop and alphaop, but
2769 D3DTBLEND_MODULATE is tricky: it uses alpha from texture when available and alpha
2770 from diffuse otherwise. So changing the texture must be monitored in SetTexture to modify
2771 alphaarg when needed.
2773 Aliens vs Predator 1 depends on accurate D3DTBLEND_MODULATE emulation
2775 Legacy texture blending (TEXTUREMAPBLEND) and texture stage states: directx6 docs state that
2776 TEXTUREMAPBLEND is deprecated, yet can still be used. Games must not use both or results
2777 are undefined. D3DTBLEND_MODULATE mode in particular is dependent on texture pixel format and
2778 requires fixup of stage 0 texture states when texture changes, but this fixup can interfere
2779 with games not using this deprecated state. So a flag 'legacyTextureBlending' has to be kept
2780 in device - TRUE if the app is using TEXTUREMAPBLEND.
2782 Tests show that setting TEXTUREMAPBLEND on native doesn't seem to change values returned by
2783 GetTextureStageState and vice versa. Not so on Wine, but it is 'undefined' anyway so, probably, ok,
2784 unless some broken game will be found that cares. */
2786 HRESULT hr;
2787 IDirect3DDeviceImpl *This = device_from_device3(iface);
2788 TRACE("(%p)->(%08x,%d)\n", This, RenderStateType, Value);
2790 EnterCriticalSection(&ddraw_cs);
2792 switch(RenderStateType)
2794 case D3DRENDERSTATE_TEXTUREHANDLE:
2796 if(Value == 0)
2798 hr = IWineD3DDevice_SetTexture(This->wineD3DDevice,
2800 NULL);
2801 break;
2804 if(Value > This->numHandles)
2806 FIXME("Specified handle %d out of range\n", Value);
2807 hr = DDERR_INVALIDPARAMS;
2808 break;
2810 if(This->Handles[Value - 1].type != DDrawHandle_Texture)
2812 FIXME("Handle %d isn't a texture handle\n", Value);
2813 hr = DDERR_INVALIDPARAMS;
2814 break;
2816 else
2818 IDirectDrawSurfaceImpl *surf = This->Handles[Value - 1].ptr;
2819 IDirect3DTexture2 *tex = surf ? (IDirect3DTexture2 *)&surf->IDirect3DTexture2_vtbl : NULL;
2820 hr = IDirect3DDevice3_SetTexture(iface, 0, tex);
2821 break;
2825 case D3DRENDERSTATE_TEXTUREMAPBLEND:
2827 This->legacyTextureBlending = TRUE;
2829 switch ( (D3DTEXTUREBLEND) Value)
2831 case D3DTBLEND_MODULATE:
2833 BOOL tex_alpha = FALSE;
2834 IWineD3DBaseTexture *tex = NULL;
2835 WINED3DSURFACE_DESC desc;
2836 WINED3DFORMAT fmt;
2837 DDPIXELFORMAT ddfmt;
2839 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice,
2841 &tex);
2843 if(hr == WINED3D_OK && tex)
2845 memset(&desc, 0, sizeof(desc));
2846 desc.Format = &fmt;
2847 hr = IWineD3DTexture_GetLevelDesc((IWineD3DTexture*) tex, 0, &desc);
2848 if (SUCCEEDED(hr))
2850 ddfmt.dwSize = sizeof(ddfmt);
2851 PixelFormat_WineD3DtoDD(&ddfmt, fmt);
2852 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
2855 IWineD3DBaseTexture_Release(tex);
2858 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG1);
2859 if (tex_alpha)
2861 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2863 else
2865 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_CURRENT);
2868 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2869 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2870 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_MODULATE);
2872 break;
2875 case D3DTBLEND_ADD:
2876 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_ADD);
2877 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2878 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2879 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG2);
2880 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
2881 break;
2883 case D3DTBLEND_MODULATEALPHA:
2884 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2885 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2886 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2887 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
2888 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_MODULATE);
2889 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_MODULATE);
2890 break;
2892 case D3DTBLEND_COPY:
2893 case D3DTBLEND_DECAL:
2894 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2895 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2896 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_SELECTARG1);
2897 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG1);
2898 break;
2900 case D3DTBLEND_DECALALPHA:
2901 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_BLENDTEXTUREALPHA);
2902 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2903 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2904 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG2);
2905 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
2906 break;
2908 default:
2909 ERR("Unhandled texture environment %d !\n",Value);
2912 hr = D3D_OK;
2913 break;
2916 default:
2917 hr = IDirect3DDevice7_SetRenderState((IDirect3DDevice7 *)This, RenderStateType, Value);
2918 break;
2921 LeaveCriticalSection(&ddraw_cs);
2923 return hr;
2926 static HRESULT WINAPI
2927 Thunk_IDirect3DDeviceImpl_2_SetRenderState(IDirect3DDevice2 *iface,
2928 D3DRENDERSTATETYPE RenderStateType,
2929 DWORD Value)
2931 IDirect3DDeviceImpl *This = device_from_device2(iface);
2932 TRACE_(ddraw_thunk)("(%p)->(%08x,%d) thunking to IDirect3DDevice3 interface.\n", This, RenderStateType, Value);
2933 return IDirect3DDevice3_SetRenderState((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, RenderStateType, Value);
2936 /*****************************************************************************
2937 * Direct3DDevice3::SetLightState
2939 * Sets a light state for Direct3DDevice3 and Direct3DDevice2. The
2940 * light states are forwarded to Direct3DDevice7 render states
2942 * Version 2 and 3
2944 * Params:
2945 * LightStateType: The light state to change
2946 * Value: The value to assign to that light state
2948 * Returns:
2949 * D3D_OK on success
2950 * DDERR_INVALIDPARAMS if the parameters were incorrect
2951 * Also check IDirect3DDevice7::SetRenderState
2953 *****************************************************************************/
2954 static HRESULT WINAPI
2955 IDirect3DDeviceImpl_3_SetLightState(IDirect3DDevice3 *iface,
2956 D3DLIGHTSTATETYPE LightStateType,
2957 DWORD Value)
2959 IDirect3DDeviceImpl *This = device_from_device3(iface);
2960 HRESULT hr;
2962 TRACE("(%p)->(%08x,%08x)\n", This, LightStateType, Value);
2964 if (!LightStateType && (LightStateType > D3DLIGHTSTATE_COLORVERTEX))
2966 TRACE("Unexpected Light State Type\n");
2967 return DDERR_INVALIDPARAMS;
2970 EnterCriticalSection(&ddraw_cs);
2971 if (LightStateType == D3DLIGHTSTATE_MATERIAL /* 1 */)
2973 IDirect3DMaterialImpl *mat;
2975 if(Value == 0) mat = NULL;
2976 else if(Value > This->numHandles)
2978 ERR("Material handle out of range(%d)\n", Value);
2979 LeaveCriticalSection(&ddraw_cs);
2980 return DDERR_INVALIDPARAMS;
2982 else if(This->Handles[Value - 1].type != DDrawHandle_Material)
2984 ERR("Invalid handle %d\n", Value);
2985 LeaveCriticalSection(&ddraw_cs);
2986 return DDERR_INVALIDPARAMS;
2988 else
2990 mat = This->Handles[Value - 1].ptr;
2993 if (mat != NULL)
2995 TRACE(" activating material %p.\n", mat);
2996 mat->activate(mat);
2998 else
3000 FIXME(" D3DLIGHTSTATE_MATERIAL called with NULL material !!!\n");
3002 This->material = Value;
3004 else if (LightStateType == D3DLIGHTSTATE_COLORMODEL /* 3 */)
3006 switch (Value)
3008 case D3DCOLOR_MONO:
3009 ERR("DDCOLOR_MONO should not happen!\n");
3010 break;
3011 case D3DCOLOR_RGB:
3012 /* We are already in this mode */
3013 TRACE("Setting color model to RGB (no-op).\n");
3014 break;
3015 default:
3016 ERR("Unknown color model!\n");
3017 LeaveCriticalSection(&ddraw_cs);
3018 return DDERR_INVALIDPARAMS;
3021 else
3023 D3DRENDERSTATETYPE rs;
3024 switch (LightStateType)
3026 case D3DLIGHTSTATE_AMBIENT: /* 2 */
3027 rs = D3DRENDERSTATE_AMBIENT;
3028 break;
3029 case D3DLIGHTSTATE_FOGMODE: /* 4 */
3030 rs = D3DRENDERSTATE_FOGVERTEXMODE;
3031 break;
3032 case D3DLIGHTSTATE_FOGSTART: /* 5 */
3033 rs = D3DRENDERSTATE_FOGSTART;
3034 break;
3035 case D3DLIGHTSTATE_FOGEND: /* 6 */
3036 rs = D3DRENDERSTATE_FOGEND;
3037 break;
3038 case D3DLIGHTSTATE_FOGDENSITY: /* 7 */
3039 rs = D3DRENDERSTATE_FOGDENSITY;
3040 break;
3041 case D3DLIGHTSTATE_COLORVERTEX: /* 8 */
3042 rs = D3DRENDERSTATE_COLORVERTEX;
3043 break;
3044 default:
3045 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType);
3046 LeaveCriticalSection(&ddraw_cs);
3047 return DDERR_INVALIDPARAMS;
3050 hr = IDirect3DDevice7_SetRenderState((IDirect3DDevice7 *)This, rs, Value);
3051 LeaveCriticalSection(&ddraw_cs);
3052 return hr;
3055 LeaveCriticalSection(&ddraw_cs);
3056 return D3D_OK;
3059 static HRESULT WINAPI
3060 Thunk_IDirect3DDeviceImpl_2_SetLightState(IDirect3DDevice2 *iface,
3061 D3DLIGHTSTATETYPE LightStateType,
3062 DWORD Value)
3064 IDirect3DDeviceImpl *This = device_from_device2(iface);
3065 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x) thunking to IDirect3DDevice3 interface.\n", This, LightStateType, Value);
3066 return IDirect3DDevice3_SetLightState((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, LightStateType, Value);
3069 /*****************************************************************************
3070 * IDirect3DDevice3::GetLightState
3072 * Returns the current setting of a light state. The state is read from
3073 * the Direct3DDevice7 render state.
3075 * Version 2 and 3
3077 * Params:
3078 * LightStateType: The light state to return
3079 * Value: The address to store the light state setting at
3081 * Returns:
3082 * D3D_OK on success
3083 * DDDERR_INVALIDPARAMS if the parameters were incorrect
3084 * Also see IDirect3DDevice7::GetRenderState
3086 *****************************************************************************/
3087 static HRESULT WINAPI
3088 IDirect3DDeviceImpl_3_GetLightState(IDirect3DDevice3 *iface,
3089 D3DLIGHTSTATETYPE LightStateType,
3090 DWORD *Value)
3092 IDirect3DDeviceImpl *This = device_from_device3(iface);
3093 HRESULT hr;
3095 TRACE("(%p)->(%08x,%p)\n", This, LightStateType, Value);
3097 if (!LightStateType && (LightStateType > D3DLIGHTSTATE_COLORVERTEX))
3099 TRACE("Unexpected Light State Type\n");
3100 return DDERR_INVALIDPARAMS;
3103 if(!Value)
3104 return DDERR_INVALIDPARAMS;
3106 EnterCriticalSection(&ddraw_cs);
3107 if (LightStateType == D3DLIGHTSTATE_MATERIAL /* 1 */)
3109 *Value = This->material;
3111 else if (LightStateType == D3DLIGHTSTATE_COLORMODEL /* 3 */)
3113 *Value = D3DCOLOR_RGB;
3115 else
3117 D3DRENDERSTATETYPE rs;
3118 switch (LightStateType)
3120 case D3DLIGHTSTATE_AMBIENT: /* 2 */
3121 rs = D3DRENDERSTATE_AMBIENT;
3122 break;
3123 case D3DLIGHTSTATE_FOGMODE: /* 4 */
3124 rs = D3DRENDERSTATE_FOGVERTEXMODE;
3125 break;
3126 case D3DLIGHTSTATE_FOGSTART: /* 5 */
3127 rs = D3DRENDERSTATE_FOGSTART;
3128 break;
3129 case D3DLIGHTSTATE_FOGEND: /* 6 */
3130 rs = D3DRENDERSTATE_FOGEND;
3131 break;
3132 case D3DLIGHTSTATE_FOGDENSITY: /* 7 */
3133 rs = D3DRENDERSTATE_FOGDENSITY;
3134 break;
3135 case D3DLIGHTSTATE_COLORVERTEX: /* 8 */
3136 rs = D3DRENDERSTATE_COLORVERTEX;
3137 break;
3138 default:
3139 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType);
3140 LeaveCriticalSection(&ddraw_cs);
3141 return DDERR_INVALIDPARAMS;
3144 hr = IDirect3DDevice7_GetRenderState((IDirect3DDevice7 *)This, rs, Value);
3145 LeaveCriticalSection(&ddraw_cs);
3146 return hr;
3149 LeaveCriticalSection(&ddraw_cs);
3150 return D3D_OK;
3153 static HRESULT WINAPI
3154 Thunk_IDirect3DDeviceImpl_2_GetLightState(IDirect3DDevice2 *iface,
3155 D3DLIGHTSTATETYPE LightStateType,
3156 DWORD *Value)
3158 IDirect3DDeviceImpl *This = device_from_device2(iface);
3159 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice3 interface.\n", This, LightStateType, Value);
3160 return IDirect3DDevice3_GetLightState((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, LightStateType, Value);
3163 /*****************************************************************************
3164 * IDirect3DDevice7::SetTransform
3166 * Assigns a D3DMATRIX to a transform type. The transform types are defined
3167 * in include/d3dtypes.h.
3168 * The D3DTRANSFORMSTATE_WORLD (=1) is translated to D3DTS_WORLDMATRIX(0)
3169 * (=255) for wined3d, because the 1 transform state was removed in d3d8
3170 * and WineD3D already understands the replacement D3DTS_WORLDMATRIX(0)
3172 * Version 2, 3 and 7
3174 * Params:
3175 * TransformStateType: transform state to set
3176 * Matrix: Matrix to assign to the state
3178 * Returns:
3179 * D3D_OK on success
3180 * DDERR_INVALIDPARAMS if Matrix == NULL
3181 * For details see IWineD3DDevice::SetTransform
3183 *****************************************************************************/
3184 static HRESULT
3185 IDirect3DDeviceImpl_7_SetTransform(IDirect3DDevice7 *iface,
3186 D3DTRANSFORMSTATETYPE TransformStateType,
3187 D3DMATRIX *Matrix)
3189 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3190 D3DTRANSFORMSTATETYPE type;
3191 HRESULT hr;
3192 TRACE("(%p)->(%08x,%p): Relay\n", This, TransformStateType, Matrix);
3194 switch(TransformStateType)
3196 case D3DTRANSFORMSTATE_WORLD : type = WINED3DTS_WORLDMATRIX(0); break;
3197 case D3DTRANSFORMSTATE_WORLD1: type = WINED3DTS_WORLDMATRIX(1); break;
3198 case D3DTRANSFORMSTATE_WORLD2: type = WINED3DTS_WORLDMATRIX(2); break;
3199 case D3DTRANSFORMSTATE_WORLD3: type = WINED3DTS_WORLDMATRIX(3); break;
3200 default: type = TransformStateType;
3203 if(!Matrix)
3204 return DDERR_INVALIDPARAMS;
3206 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3207 EnterCriticalSection(&ddraw_cs);
3208 hr = IWineD3DDevice_SetTransform(This->wineD3DDevice,
3209 type,
3210 (WINED3DMATRIX*) Matrix);
3211 LeaveCriticalSection(&ddraw_cs);
3212 return hr;
3215 static HRESULT WINAPI
3216 IDirect3DDeviceImpl_7_SetTransform_FPUSetup(IDirect3DDevice7 *iface,
3217 D3DTRANSFORMSTATETYPE TransformStateType,
3218 D3DMATRIX *Matrix)
3220 return IDirect3DDeviceImpl_7_SetTransform(iface, TransformStateType, Matrix);
3223 static HRESULT WINAPI
3224 IDirect3DDeviceImpl_7_SetTransform_FPUPreserve(IDirect3DDevice7 *iface,
3225 D3DTRANSFORMSTATETYPE TransformStateType,
3226 D3DMATRIX *Matrix)
3228 HRESULT hr;
3229 WORD old_fpucw;
3231 old_fpucw = d3d_fpu_setup();
3232 hr = IDirect3DDeviceImpl_7_SetTransform(iface, TransformStateType, Matrix);
3233 set_fpu_control_word(old_fpucw);
3235 return hr;
3238 static HRESULT WINAPI
3239 Thunk_IDirect3DDeviceImpl_3_SetTransform(IDirect3DDevice3 *iface,
3240 D3DTRANSFORMSTATETYPE TransformStateType,
3241 D3DMATRIX *D3DMatrix)
3243 IDirect3DDeviceImpl *This = device_from_device3(iface);
3244 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3245 return IDirect3DDevice7_SetTransform((IDirect3DDevice7 *)This, TransformStateType, D3DMatrix);
3248 static HRESULT WINAPI
3249 Thunk_IDirect3DDeviceImpl_2_SetTransform(IDirect3DDevice2 *iface,
3250 D3DTRANSFORMSTATETYPE TransformStateType,
3251 D3DMATRIX *D3DMatrix)
3253 IDirect3DDeviceImpl *This = device_from_device2(iface);
3254 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3255 return IDirect3DDevice7_SetTransform((IDirect3DDevice7 *)This, TransformStateType, D3DMatrix);
3258 /*****************************************************************************
3259 * IDirect3DDevice7::GetTransform
3261 * Returns the matrix assigned to a transform state
3262 * D3DTRANSFORMSTATE_WORLD is translated to D3DTS_WORLDMATRIX(0), see
3263 * SetTransform
3265 * Params:
3266 * TransformStateType: State to read the matrix from
3267 * Matrix: Address to store the matrix at
3269 * Returns:
3270 * D3D_OK on success
3271 * DDERR_INVALIDPARAMS if Matrix == NULL
3272 * For details, see IWineD3DDevice::GetTransform
3274 *****************************************************************************/
3275 static HRESULT
3276 IDirect3DDeviceImpl_7_GetTransform(IDirect3DDevice7 *iface,
3277 D3DTRANSFORMSTATETYPE TransformStateType,
3278 D3DMATRIX *Matrix)
3280 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3281 D3DTRANSFORMSTATETYPE type;
3282 HRESULT hr;
3283 TRACE("(%p)->(%08x,%p): Relay\n", This, TransformStateType, Matrix);
3285 switch(TransformStateType)
3287 case D3DTRANSFORMSTATE_WORLD : type = WINED3DTS_WORLDMATRIX(0); break;
3288 case D3DTRANSFORMSTATE_WORLD1: type = WINED3DTS_WORLDMATRIX(1); break;
3289 case D3DTRANSFORMSTATE_WORLD2: type = WINED3DTS_WORLDMATRIX(2); break;
3290 case D3DTRANSFORMSTATE_WORLD3: type = WINED3DTS_WORLDMATRIX(3); break;
3291 default: type = TransformStateType;
3294 if(!Matrix)
3295 return DDERR_INVALIDPARAMS;
3297 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3298 EnterCriticalSection(&ddraw_cs);
3299 hr = IWineD3DDevice_GetTransform(This->wineD3DDevice, type, (WINED3DMATRIX*) Matrix);
3300 LeaveCriticalSection(&ddraw_cs);
3301 return hr;
3304 static HRESULT WINAPI
3305 IDirect3DDeviceImpl_7_GetTransform_FPUSetup(IDirect3DDevice7 *iface,
3306 D3DTRANSFORMSTATETYPE TransformStateType,
3307 D3DMATRIX *Matrix)
3309 return IDirect3DDeviceImpl_7_GetTransform(iface, TransformStateType, Matrix);
3312 static HRESULT WINAPI
3313 IDirect3DDeviceImpl_7_GetTransform_FPUPreserve(IDirect3DDevice7 *iface,
3314 D3DTRANSFORMSTATETYPE TransformStateType,
3315 D3DMATRIX *Matrix)
3317 HRESULT hr;
3318 WORD old_fpucw;
3320 old_fpucw = d3d_fpu_setup();
3321 hr = IDirect3DDeviceImpl_7_GetTransform(iface, TransformStateType, Matrix);
3322 set_fpu_control_word(old_fpucw);
3324 return hr;
3327 static HRESULT WINAPI
3328 Thunk_IDirect3DDeviceImpl_3_GetTransform(IDirect3DDevice3 *iface,
3329 D3DTRANSFORMSTATETYPE TransformStateType,
3330 D3DMATRIX *D3DMatrix)
3332 IDirect3DDeviceImpl *This = device_from_device3(iface);
3333 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3334 return IDirect3DDevice7_GetTransform((IDirect3DDevice7 *)This, TransformStateType, D3DMatrix);
3337 static HRESULT WINAPI
3338 Thunk_IDirect3DDeviceImpl_2_GetTransform(IDirect3DDevice2 *iface,
3339 D3DTRANSFORMSTATETYPE TransformStateType,
3340 D3DMATRIX *D3DMatrix)
3342 IDirect3DDeviceImpl *This = device_from_device2(iface);
3343 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3344 return IDirect3DDevice7_GetTransform((IDirect3DDevice7 *)This, TransformStateType, D3DMatrix);
3347 /*****************************************************************************
3348 * IDirect3DDevice7::MultiplyTransform
3350 * Multiplies the already-set transform matrix of a transform state
3351 * with another matrix. For the world matrix, see SetTransform
3353 * Version 2, 3 and 7
3355 * Params:
3356 * TransformStateType: Transform state to multiply
3357 * D3DMatrix Matrix to multiply with.
3359 * Returns
3360 * D3D_OK on success
3361 * DDERR_INVALIDPARAMS if D3DMatrix is NULL
3362 * For details, see IWineD3DDevice::MultiplyTransform
3364 *****************************************************************************/
3365 static HRESULT
3366 IDirect3DDeviceImpl_7_MultiplyTransform(IDirect3DDevice7 *iface,
3367 D3DTRANSFORMSTATETYPE TransformStateType,
3368 D3DMATRIX *D3DMatrix)
3370 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3371 HRESULT hr;
3372 D3DTRANSFORMSTATETYPE type;
3373 TRACE("(%p)->(%08x,%p): Relay\n", This, TransformStateType, D3DMatrix);
3375 switch(TransformStateType)
3377 case D3DTRANSFORMSTATE_WORLD : type = WINED3DTS_WORLDMATRIX(0); break;
3378 case D3DTRANSFORMSTATE_WORLD1: type = WINED3DTS_WORLDMATRIX(1); break;
3379 case D3DTRANSFORMSTATE_WORLD2: type = WINED3DTS_WORLDMATRIX(2); break;
3380 case D3DTRANSFORMSTATE_WORLD3: type = WINED3DTS_WORLDMATRIX(3); break;
3381 default: type = TransformStateType;
3384 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3385 EnterCriticalSection(&ddraw_cs);
3386 hr = IWineD3DDevice_MultiplyTransform(This->wineD3DDevice,
3387 type,
3388 (WINED3DMATRIX*) D3DMatrix);
3389 LeaveCriticalSection(&ddraw_cs);
3390 return hr;
3393 static HRESULT WINAPI
3394 IDirect3DDeviceImpl_7_MultiplyTransform_FPUSetup(IDirect3DDevice7 *iface,
3395 D3DTRANSFORMSTATETYPE TransformStateType,
3396 D3DMATRIX *D3DMatrix)
3398 return IDirect3DDeviceImpl_7_MultiplyTransform(iface, TransformStateType, D3DMatrix);
3401 static HRESULT WINAPI
3402 IDirect3DDeviceImpl_7_MultiplyTransform_FPUPreserve(IDirect3DDevice7 *iface,
3403 D3DTRANSFORMSTATETYPE TransformStateType,
3404 D3DMATRIX *D3DMatrix)
3406 HRESULT hr;
3407 WORD old_fpucw;
3409 old_fpucw = d3d_fpu_setup();
3410 hr = IDirect3DDeviceImpl_7_MultiplyTransform(iface, TransformStateType, D3DMatrix);
3411 set_fpu_control_word(old_fpucw);
3413 return hr;
3416 static HRESULT WINAPI
3417 Thunk_IDirect3DDeviceImpl_3_MultiplyTransform(IDirect3DDevice3 *iface,
3418 D3DTRANSFORMSTATETYPE TransformStateType,
3419 D3DMATRIX *D3DMatrix)
3421 IDirect3DDeviceImpl *This = device_from_device3(iface);
3422 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3423 return IDirect3DDevice7_MultiplyTransform((IDirect3DDevice7 *)This, TransformStateType, D3DMatrix);
3426 static HRESULT WINAPI
3427 Thunk_IDirect3DDeviceImpl_2_MultiplyTransform(IDirect3DDevice2 *iface,
3428 D3DTRANSFORMSTATETYPE TransformStateType,
3429 D3DMATRIX *D3DMatrix)
3431 IDirect3DDeviceImpl *This = device_from_device2(iface);
3432 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3433 return IDirect3DDevice7_MultiplyTransform((IDirect3DDevice7 *)This, TransformStateType, D3DMatrix);
3436 /*****************************************************************************
3437 * IDirect3DDevice7::DrawPrimitive
3439 * Draws primitives based on vertices in an application-provided pointer
3441 * Version 2, 3 and 7. The IDirect3DDevice2 thunk converts the fixed vertex type into
3442 * an FVF format for D3D7
3444 * Params:
3445 * PrimitiveType: The type of the primitives to draw
3446 * Vertex type: Flexible vertex format vertex description
3447 * Vertices: Pointer to the vertex array
3448 * VertexCount: The number of vertices to draw
3449 * Flags: As usual a few flags
3451 * Returns:
3452 * D3D_OK on success
3453 * DDERR_INVALIDPARAMS if Vertices is NULL
3454 * For details, see IWineD3DDevice::DrawPrimitiveUP
3456 *****************************************************************************/
3457 static HRESULT
3458 IDirect3DDeviceImpl_7_DrawPrimitive(IDirect3DDevice7 *iface,
3459 D3DPRIMITIVETYPE PrimitiveType,
3460 DWORD VertexType,
3461 void *Vertices,
3462 DWORD VertexCount,
3463 DWORD Flags)
3465 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3466 UINT PrimitiveCount, stride;
3467 HRESULT hr;
3468 TRACE("(%p)->(%08x,%08x,%p,%08x,%08x): Relay!\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3470 if(!Vertices)
3471 return DDERR_INVALIDPARAMS;
3473 /* Get the vertex count */
3474 switch(PrimitiveType)
3476 case D3DPT_POINTLIST:
3477 PrimitiveCount = VertexCount;
3478 break;
3480 case D3DPT_LINELIST:
3481 PrimitiveCount = VertexCount / 2;
3482 break;
3484 case D3DPT_LINESTRIP:
3485 PrimitiveCount = VertexCount - 1;
3486 break;
3488 case D3DPT_TRIANGLELIST:
3489 PrimitiveCount = VertexCount / 3;
3490 break;
3492 case D3DPT_TRIANGLESTRIP:
3493 PrimitiveCount = VertexCount - 2;
3494 break;
3496 case D3DPT_TRIANGLEFAN:
3497 PrimitiveCount = VertexCount - 2;
3498 break;
3500 default:
3501 return DDERR_INVALIDPARAMS;
3504 /* Get the stride */
3505 stride = get_flexible_vertex_size(VertexType);
3507 /* Set the FVF */
3508 EnterCriticalSection(&ddraw_cs);
3509 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
3510 IDirectDrawImpl_FindDecl(This->ddraw, VertexType));
3511 if(hr != D3D_OK)
3513 LeaveCriticalSection(&ddraw_cs);
3514 return hr;
3517 /* This method translates to the user pointer draw of WineD3D */
3518 hr = IWineD3DDevice_DrawPrimitiveUP(This->wineD3DDevice,
3519 PrimitiveType,
3520 PrimitiveCount,
3521 Vertices,
3522 stride);
3523 LeaveCriticalSection(&ddraw_cs);
3524 return hr;
3527 static HRESULT WINAPI
3528 IDirect3DDeviceImpl_7_DrawPrimitive_FPUSetup(IDirect3DDevice7 *iface,
3529 D3DPRIMITIVETYPE PrimitiveType,
3530 DWORD VertexType,
3531 void *Vertices,
3532 DWORD VertexCount,
3533 DWORD Flags)
3535 return IDirect3DDeviceImpl_7_DrawPrimitive(iface, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3538 static HRESULT WINAPI
3539 IDirect3DDeviceImpl_7_DrawPrimitive_FPUPreserve(IDirect3DDevice7 *iface,
3540 D3DPRIMITIVETYPE PrimitiveType,
3541 DWORD VertexType,
3542 void *Vertices,
3543 DWORD VertexCount,
3544 DWORD Flags)
3546 HRESULT hr;
3547 WORD old_fpucw;
3549 old_fpucw = d3d_fpu_setup();
3550 hr = IDirect3DDeviceImpl_7_DrawPrimitive(iface, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3551 set_fpu_control_word(old_fpucw);
3553 return hr;
3556 static HRESULT WINAPI
3557 Thunk_IDirect3DDeviceImpl_3_DrawPrimitive(IDirect3DDevice3 *iface,
3558 D3DPRIMITIVETYPE PrimitiveType,
3559 DWORD VertexType,
3560 void *Vertices,
3561 DWORD VertexCount,
3562 DWORD Flags)
3564 IDirect3DDeviceImpl *This = device_from_device3(iface);
3565 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3566 return IDirect3DDevice7_DrawPrimitive((IDirect3DDevice7 *)This,
3567 PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3570 static HRESULT WINAPI
3571 Thunk_IDirect3DDeviceImpl_2_DrawPrimitive(IDirect3DDevice2 *iface,
3572 D3DPRIMITIVETYPE PrimitiveType,
3573 D3DVERTEXTYPE VertexType,
3574 void *Vertices,
3575 DWORD VertexCount,
3576 DWORD Flags)
3578 IDirect3DDeviceImpl *This = device_from_device2(iface);
3579 DWORD FVF;
3580 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3582 switch(VertexType)
3584 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
3585 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
3586 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
3587 default:
3588 ERR("Unexpected vertex type %d\n", VertexType);
3589 return DDERR_INVALIDPARAMS; /* Should never happen */
3592 return IDirect3DDevice7_DrawPrimitive((IDirect3DDevice7 *)This, PrimitiveType, FVF, Vertices, VertexCount, Flags);
3595 /*****************************************************************************
3596 * IDirect3DDevice7::DrawIndexedPrimitive
3598 * Draws vertices from an application-provided pointer, based on the index
3599 * numbers in a WORD array.
3601 * Version 2, 3 and 7. The version 7 thunk translates the vertex type into
3602 * an FVF format for D3D7
3604 * Params:
3605 * PrimitiveType: The primitive type to draw
3606 * VertexType: The FVF vertex description
3607 * Vertices: Pointer to the vertex array
3608 * VertexCount: ?
3609 * Indices: Pointer to the index array
3610 * IndexCount: Number of indices = Number of vertices to draw
3611 * Flags: As usual, some flags
3613 * Returns:
3614 * D3D_OK on success
3615 * DDERR_INVALIDPARAMS if Vertices or Indices is NULL
3616 * For details, see IWineD3DDevice::DrawIndexedPrimitiveUP
3618 *****************************************************************************/
3619 static HRESULT
3620 IDirect3DDeviceImpl_7_DrawIndexedPrimitive(IDirect3DDevice7 *iface,
3621 D3DPRIMITIVETYPE PrimitiveType,
3622 DWORD VertexType,
3623 void *Vertices,
3624 DWORD VertexCount,
3625 WORD *Indices,
3626 DWORD IndexCount,
3627 DWORD Flags)
3629 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3630 UINT PrimitiveCount = 0;
3631 HRESULT hr;
3632 TRACE("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x): Relay!\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3634 /* Get the primitive number */
3635 switch(PrimitiveType)
3637 case D3DPT_POINTLIST:
3638 PrimitiveCount = IndexCount;
3639 break;
3641 case D3DPT_LINELIST:
3642 PrimitiveCount = IndexCount / 2;
3643 break;
3645 case D3DPT_LINESTRIP:
3646 PrimitiveCount = IndexCount - 1;
3647 break;
3649 case D3DPT_TRIANGLELIST:
3650 PrimitiveCount = IndexCount / 3;
3651 break;
3653 case D3DPT_TRIANGLESTRIP:
3654 PrimitiveCount = IndexCount - 2;
3655 break;
3657 case D3DPT_TRIANGLEFAN:
3658 PrimitiveCount = IndexCount - 2;
3659 break;
3661 default:
3662 return DDERR_INVALIDPARAMS;
3665 /* Set the D3DDevice's FVF */
3666 EnterCriticalSection(&ddraw_cs);
3667 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
3668 IDirectDrawImpl_FindDecl(This->ddraw, VertexType));
3669 if(FAILED(hr))
3671 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr);
3672 LeaveCriticalSection(&ddraw_cs);
3673 return hr;
3676 hr = IWineD3DDevice_DrawIndexedPrimitiveUP(This->wineD3DDevice,
3677 PrimitiveType,
3678 0 /* MinVertexIndex */,
3679 VertexCount /* UINT NumVertexIndex */,
3680 PrimitiveCount,
3681 Indices,
3682 WINED3DFMT_INDEX16,
3683 Vertices,
3684 get_flexible_vertex_size(VertexType));
3685 LeaveCriticalSection(&ddraw_cs);
3686 return hr;
3689 static HRESULT WINAPI
3690 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUSetup(IDirect3DDevice7 *iface,
3691 D3DPRIMITIVETYPE PrimitiveType,
3692 DWORD VertexType,
3693 void *Vertices,
3694 DWORD VertexCount,
3695 WORD *Indices,
3696 DWORD IndexCount,
3697 DWORD Flags)
3699 return IDirect3DDeviceImpl_7_DrawIndexedPrimitive(iface, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3702 static HRESULT WINAPI
3703 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUPreserve(IDirect3DDevice7 *iface,
3704 D3DPRIMITIVETYPE PrimitiveType,
3705 DWORD VertexType,
3706 void *Vertices,
3707 DWORD VertexCount,
3708 WORD *Indices,
3709 DWORD IndexCount,
3710 DWORD Flags)
3712 HRESULT hr;
3713 WORD old_fpucw;
3715 old_fpucw = d3d_fpu_setup();
3716 hr = IDirect3DDeviceImpl_7_DrawIndexedPrimitive(iface, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3717 set_fpu_control_word(old_fpucw);
3719 return hr;
3722 static HRESULT WINAPI
3723 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive(IDirect3DDevice3 *iface,
3724 D3DPRIMITIVETYPE PrimitiveType,
3725 DWORD VertexType,
3726 void *Vertices,
3727 DWORD VertexCount,
3728 WORD *Indices,
3729 DWORD IndexCount,
3730 DWORD Flags)
3732 IDirect3DDeviceImpl *This = device_from_device3(iface);
3733 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3734 return IDirect3DDevice7_DrawIndexedPrimitive((IDirect3DDevice7 *)This,
3735 PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3738 static HRESULT WINAPI
3739 Thunk_IDirect3DDeviceImpl_2_DrawIndexedPrimitive(IDirect3DDevice2 *iface,
3740 D3DPRIMITIVETYPE PrimitiveType,
3741 D3DVERTEXTYPE VertexType,
3742 void *Vertices,
3743 DWORD VertexCount,
3744 WORD *Indices,
3745 DWORD IndexCount,
3746 DWORD Flags)
3748 DWORD FVF;
3749 IDirect3DDeviceImpl *This = device_from_device2(iface);
3750 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3752 switch(VertexType)
3754 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
3755 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
3756 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
3757 default:
3758 ERR("Unexpected vertex type %d\n", VertexType);
3759 return DDERR_INVALIDPARAMS; /* Should never happen */
3762 return IDirect3DDevice7_DrawIndexedPrimitive((IDirect3DDevice7 *)This,
3763 PrimitiveType, FVF, Vertices, VertexCount, Indices, IndexCount, Flags);
3766 /*****************************************************************************
3767 * IDirect3DDevice7::SetClipStatus
3769 * Sets the clip status. This defines things as clipping conditions and
3770 * the extents of the clipping region.
3772 * Version 2, 3 and 7
3774 * Params:
3775 * ClipStatus:
3777 * Returns:
3778 * D3D_OK because it's a stub
3779 * (DDERR_INVALIDPARAMS if ClipStatus == NULL)
3781 *****************************************************************************/
3782 static HRESULT WINAPI
3783 IDirect3DDeviceImpl_7_SetClipStatus(IDirect3DDevice7 *iface,
3784 D3DCLIPSTATUS *ClipStatus)
3786 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3787 FIXME("(%p)->(%p): Stub!\n", This, ClipStatus);
3789 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them
3790 * Perhaps this needs a new data type and an additional IWineD3DDevice method
3792 /* return IWineD3DDevice_SetClipStatus(This->wineD3DDevice, ClipStatus);*/
3793 return D3D_OK;
3796 static HRESULT WINAPI
3797 Thunk_IDirect3DDeviceImpl_3_SetClipStatus(IDirect3DDevice3 *iface,
3798 D3DCLIPSTATUS *ClipStatus)
3800 IDirect3DDeviceImpl *This = device_from_device3(iface);
3801 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3802 return IDirect3DDevice7_SetClipStatus((IDirect3DDevice7 *)This, ClipStatus);
3805 static HRESULT WINAPI
3806 Thunk_IDirect3DDeviceImpl_2_SetClipStatus(IDirect3DDevice2 *iface,
3807 D3DCLIPSTATUS *ClipStatus)
3809 IDirect3DDeviceImpl *This = device_from_device2(iface);
3810 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3811 return IDirect3DDevice7_SetClipStatus((IDirect3DDevice7 *)This, ClipStatus);
3814 /*****************************************************************************
3815 * IDirect3DDevice7::GetClipStatus
3817 * Returns the clip status
3819 * Params:
3820 * ClipStatus: Address to write the clip status to
3822 * Returns:
3823 * D3D_OK because it's a stub
3825 *****************************************************************************/
3826 static HRESULT WINAPI
3827 IDirect3DDeviceImpl_7_GetClipStatus(IDirect3DDevice7 *iface,
3828 D3DCLIPSTATUS *ClipStatus)
3830 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3831 FIXME("(%p)->(%p): Stub!\n", This, ClipStatus);
3833 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them */
3834 /* return IWineD3DDevice_GetClipStatus(This->wineD3DDevice, ClipStatus);*/
3835 return D3D_OK;
3838 static HRESULT WINAPI
3839 Thunk_IDirect3DDeviceImpl_3_GetClipStatus(IDirect3DDevice3 *iface,
3840 D3DCLIPSTATUS *ClipStatus)
3842 IDirect3DDeviceImpl *This = device_from_device3(iface);
3843 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3844 return IDirect3DDevice7_GetClipStatus((IDirect3DDevice7 *)This, ClipStatus);
3847 static HRESULT WINAPI
3848 Thunk_IDirect3DDeviceImpl_2_GetClipStatus(IDirect3DDevice2 *iface,
3849 D3DCLIPSTATUS *ClipStatus)
3851 IDirect3DDeviceImpl *This = device_from_device2(iface);
3852 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3853 return IDirect3DDevice7_GetClipStatus((IDirect3DDevice7 *)This, ClipStatus);
3856 /*****************************************************************************
3857 * IDirect3DDevice::DrawPrimitiveStrided
3859 * Draws vertices described by a D3DDRAWPRIMITIVESTRIDEDDATA structure.
3861 * Version 3 and 7
3863 * Params:
3864 * PrimitiveType: The primitive type to draw
3865 * VertexType: The FVF description of the vertices to draw (for the stride??)
3866 * D3DDrawPrimStrideData: A D3DDRAWPRIMITIVESTRIDEDDATA structure describing
3867 * the vertex data locations
3868 * VertexCount: The number of vertices to draw
3869 * Flags: Some flags
3871 * Returns:
3872 * D3D_OK, because it's a stub
3873 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
3874 * (For details, see IWineD3DDevice::DrawPrimitiveStrided)
3876 *****************************************************************************/
3877 static HRESULT
3878 IDirect3DDeviceImpl_7_DrawPrimitiveStrided(IDirect3DDevice7 *iface,
3879 D3DPRIMITIVETYPE PrimitiveType,
3880 DWORD VertexType,
3881 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3882 DWORD VertexCount,
3883 DWORD Flags)
3885 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3886 WineDirect3DVertexStridedData WineD3DStrided;
3887 DWORD i;
3888 UINT PrimitiveCount;
3889 HRESULT hr;
3891 TRACE("(%p)->(%08x,%08x,%p,%08x,%08x): stub!\n", This, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
3893 memset(&WineD3DStrided, 0, sizeof(WineD3DStrided));
3894 /* Get the strided data right. the wined3d structure is a bit bigger
3895 * Watch out: The contents of the strided data are determined by the fvf,
3896 * not by the members set in D3DDrawPrimStrideData. So it's valid
3897 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
3898 * not set in the fvf.
3900 if(VertexType & D3DFVF_POSITION_MASK)
3902 WineD3DStrided.u.s.position.lpData = D3DDrawPrimStrideData->position.lpvData;
3903 WineD3DStrided.u.s.position.dwStride = D3DDrawPrimStrideData->position.dwStride;
3904 WineD3DStrided.u.s.position.dwType = WINED3DDECLTYPE_FLOAT3;
3905 if (VertexType & D3DFVF_XYZRHW)
3907 WineD3DStrided.u.s.position.dwType = WINED3DDECLTYPE_FLOAT4;
3908 WineD3DStrided.position_transformed = TRUE;
3909 } else
3910 WineD3DStrided.position_transformed = FALSE;
3913 if(VertexType & D3DFVF_NORMAL)
3915 WineD3DStrided.u.s.normal.lpData = D3DDrawPrimStrideData->normal.lpvData;
3916 WineD3DStrided.u.s.normal.dwStride = D3DDrawPrimStrideData->normal.dwStride;
3917 WineD3DStrided.u.s.normal.dwType = WINED3DDECLTYPE_FLOAT3;
3920 if(VertexType & D3DFVF_DIFFUSE)
3922 WineD3DStrided.u.s.diffuse.lpData = D3DDrawPrimStrideData->diffuse.lpvData;
3923 WineD3DStrided.u.s.diffuse.dwStride = D3DDrawPrimStrideData->diffuse.dwStride;
3924 WineD3DStrided.u.s.diffuse.dwType = WINED3DDECLTYPE_D3DCOLOR;
3927 if(VertexType & D3DFVF_SPECULAR)
3929 WineD3DStrided.u.s.specular.lpData = D3DDrawPrimStrideData->specular.lpvData;
3930 WineD3DStrided.u.s.specular.dwStride = D3DDrawPrimStrideData->specular.dwStride;
3931 WineD3DStrided.u.s.specular.dwType = WINED3DDECLTYPE_D3DCOLOR;
3934 for( i = 0; i < GET_TEXCOUNT_FROM_FVF(VertexType); i++)
3936 WineD3DStrided.u.s.texCoords[i].lpData = D3DDrawPrimStrideData->textureCoords[i].lpvData;
3937 WineD3DStrided.u.s.texCoords[i].dwStride = D3DDrawPrimStrideData->textureCoords[i].dwStride;
3938 switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i))
3940 case 1: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT1; break;
3941 case 2: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT2; break;
3942 case 3: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT3; break;
3943 case 4: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT4; break;
3944 default: ERR("Unexpected texture coordinate size %d\n",
3945 GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i));
3949 /* Get the primitive count */
3950 switch(PrimitiveType)
3952 case D3DPT_POINTLIST:
3953 PrimitiveCount = VertexCount;
3954 break;
3956 case D3DPT_LINELIST:
3957 PrimitiveCount = VertexCount / 2;
3958 break;
3960 case D3DPT_LINESTRIP:
3961 PrimitiveCount = VertexCount - 1;
3962 break;
3964 case D3DPT_TRIANGLELIST:
3965 PrimitiveCount = VertexCount / 3;
3966 break;
3968 case D3DPT_TRIANGLESTRIP:
3969 PrimitiveCount = VertexCount - 2;
3970 break;
3972 case D3DPT_TRIANGLEFAN:
3973 PrimitiveCount = VertexCount - 2;
3974 break;
3976 default: return DDERR_INVALIDPARAMS;
3979 /* WineD3D doesn't need the FVF here */
3980 EnterCriticalSection(&ddraw_cs);
3981 hr = IWineD3DDevice_DrawPrimitiveStrided(This->wineD3DDevice,
3982 PrimitiveType,
3983 PrimitiveCount,
3984 &WineD3DStrided);
3985 LeaveCriticalSection(&ddraw_cs);
3986 return hr;
3989 static HRESULT WINAPI
3990 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUSetup(IDirect3DDevice7 *iface,
3991 D3DPRIMITIVETYPE PrimitiveType,
3992 DWORD VertexType,
3993 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3994 DWORD VertexCount,
3995 DWORD Flags)
3997 return IDirect3DDeviceImpl_7_DrawPrimitiveStrided(iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
4000 static HRESULT WINAPI
4001 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUPreserve(IDirect3DDevice7 *iface,
4002 D3DPRIMITIVETYPE PrimitiveType,
4003 DWORD VertexType,
4004 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
4005 DWORD VertexCount,
4006 DWORD Flags)
4008 HRESULT hr;
4009 WORD old_fpucw;
4011 old_fpucw = d3d_fpu_setup();
4012 hr = IDirect3DDeviceImpl_7_DrawPrimitiveStrided(iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
4013 set_fpu_control_word(old_fpucw);
4015 return hr;
4018 static HRESULT WINAPI
4019 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided(IDirect3DDevice3 *iface,
4020 D3DPRIMITIVETYPE PrimitiveType,
4021 DWORD VertexType,
4022 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
4023 DWORD VertexCount,
4024 DWORD Flags)
4026 IDirect3DDeviceImpl *This = device_from_device3(iface);
4027 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
4028 return IDirect3DDevice7_DrawPrimitiveStrided((IDirect3DDevice7 *)This,
4029 PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
4032 /*****************************************************************************
4033 * IDirect3DDevice7::DrawIndexedPrimitiveStrided
4035 * Draws primitives specified by strided data locations based on indices
4037 * Version 3 and 7
4039 * Params:
4040 * PrimitiveType:
4042 * Returns:
4043 * D3D_OK, because it's a stub
4044 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
4045 * (DDERR_INVALIDPARAMS if Indices is NULL)
4046 * (For more details, see IWineD3DDevice::DrawIndexedPrimitiveStrided)
4048 *****************************************************************************/
4049 static HRESULT
4050 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(IDirect3DDevice7 *iface,
4051 D3DPRIMITIVETYPE PrimitiveType,
4052 DWORD VertexType,
4053 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
4054 DWORD VertexCount,
4055 WORD *Indices,
4056 DWORD IndexCount,
4057 DWORD Flags)
4059 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
4060 WineDirect3DVertexStridedData WineD3DStrided;
4061 DWORD i;
4062 UINT PrimitiveCount;
4063 HRESULT hr;
4065 TRACE("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x)\n", This, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
4067 memset(&WineD3DStrided, 0, sizeof(WineD3DStrided));
4068 /* Get the strided data right. the wined3d structure is a bit bigger
4069 * Watch out: The contents of the strided data are determined by the fvf,
4070 * not by the members set in D3DDrawPrimStrideData. So it's valid
4071 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
4072 * not set in the fvf.
4074 if(VertexType & D3DFVF_POSITION_MASK)
4076 WineD3DStrided.u.s.position.lpData = D3DDrawPrimStrideData->position.lpvData;
4077 WineD3DStrided.u.s.position.dwStride = D3DDrawPrimStrideData->position.dwStride;
4078 WineD3DStrided.u.s.position.dwType = WINED3DDECLTYPE_FLOAT3;
4079 if (VertexType & D3DFVF_XYZRHW)
4081 WineD3DStrided.u.s.position.dwType = WINED3DDECLTYPE_FLOAT4;
4082 WineD3DStrided.position_transformed = TRUE;
4083 } else
4084 WineD3DStrided.position_transformed = FALSE;
4087 if(VertexType & D3DFVF_NORMAL)
4089 WineD3DStrided.u.s.normal.lpData = D3DDrawPrimStrideData->normal.lpvData;
4090 WineD3DStrided.u.s.normal.dwStride = D3DDrawPrimStrideData->normal.dwStride;
4091 WineD3DStrided.u.s.normal.dwType = WINED3DDECLTYPE_FLOAT3;
4094 if(VertexType & D3DFVF_DIFFUSE)
4096 WineD3DStrided.u.s.diffuse.lpData = D3DDrawPrimStrideData->diffuse.lpvData;
4097 WineD3DStrided.u.s.diffuse.dwStride = D3DDrawPrimStrideData->diffuse.dwStride;
4098 WineD3DStrided.u.s.diffuse.dwType = WINED3DDECLTYPE_D3DCOLOR;
4101 if(VertexType & D3DFVF_SPECULAR)
4103 WineD3DStrided.u.s.specular.lpData = D3DDrawPrimStrideData->specular.lpvData;
4104 WineD3DStrided.u.s.specular.dwStride = D3DDrawPrimStrideData->specular.dwStride;
4105 WineD3DStrided.u.s.specular.dwType = WINED3DDECLTYPE_D3DCOLOR;
4108 for( i = 0; i < GET_TEXCOUNT_FROM_FVF(VertexType); i++)
4110 WineD3DStrided.u.s.texCoords[i].lpData = D3DDrawPrimStrideData->textureCoords[i].lpvData;
4111 WineD3DStrided.u.s.texCoords[i].dwStride = D3DDrawPrimStrideData->textureCoords[i].dwStride;
4112 switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i))
4114 case 1: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT1; break;
4115 case 2: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT2; break;
4116 case 3: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT3; break;
4117 case 4: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT4; break;
4118 default: ERR("Unexpected texture coordinate size %d\n",
4119 GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i));
4123 /* Get the primitive count */
4124 switch(PrimitiveType)
4126 case D3DPT_POINTLIST:
4127 PrimitiveCount = IndexCount;
4128 break;
4130 case D3DPT_LINELIST:
4131 PrimitiveCount = IndexCount / 2;
4132 break;
4134 case D3DPT_LINESTRIP:
4135 PrimitiveCount = IndexCount - 1;
4136 break;
4138 case D3DPT_TRIANGLELIST:
4139 PrimitiveCount = IndexCount / 3;
4140 break;
4142 case D3DPT_TRIANGLESTRIP:
4143 PrimitiveCount = IndexCount - 2;
4144 break;
4146 case D3DPT_TRIANGLEFAN:
4147 PrimitiveCount = IndexCount - 2;
4148 break;
4150 default: return DDERR_INVALIDPARAMS;
4153 /* WineD3D doesn't need the FVF here */
4154 EnterCriticalSection(&ddraw_cs);
4155 hr = IWineD3DDevice_DrawIndexedPrimitiveStrided(This->wineD3DDevice,
4156 PrimitiveType,
4157 PrimitiveCount,
4158 &WineD3DStrided,
4159 VertexCount,
4160 Indices,
4161 WINED3DFMT_INDEX16);
4162 LeaveCriticalSection(&ddraw_cs);
4163 return hr;
4166 static HRESULT WINAPI
4167 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUSetup(IDirect3DDevice7 *iface,
4168 D3DPRIMITIVETYPE PrimitiveType,
4169 DWORD VertexType,
4170 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
4171 DWORD VertexCount,
4172 WORD *Indices,
4173 DWORD IndexCount,
4174 DWORD Flags)
4176 return IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
4179 static HRESULT WINAPI
4180 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUPreserve(IDirect3DDevice7 *iface,
4181 D3DPRIMITIVETYPE PrimitiveType,
4182 DWORD VertexType,
4183 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
4184 DWORD VertexCount,
4185 WORD *Indices,
4186 DWORD IndexCount,
4187 DWORD Flags)
4189 HRESULT hr;
4190 WORD old_fpucw;
4192 old_fpucw = d3d_fpu_setup();
4193 hr = IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
4194 set_fpu_control_word(old_fpucw);
4196 return hr;
4199 static HRESULT WINAPI
4200 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided(IDirect3DDevice3 *iface,
4201 D3DPRIMITIVETYPE PrimitiveType,
4202 DWORD VertexType,
4203 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
4204 DWORD VertexCount,
4205 WORD *Indices,
4206 DWORD IndexCount,
4207 DWORD Flags)
4209 IDirect3DDeviceImpl *This = device_from_device3(iface);
4210 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
4211 return IDirect3DDevice7_DrawIndexedPrimitiveStrided((IDirect3DDevice7 *)This, PrimitiveType,
4212 VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
4215 /*****************************************************************************
4216 * IDirect3DDevice7::DrawPrimitiveVB
4218 * Draws primitives from a vertex buffer to the screen.
4220 * Version 3 and 7
4222 * Params:
4223 * PrimitiveType: Type of primitive to be rendered.
4224 * D3DVertexBuf: Source Vertex Buffer
4225 * StartVertex: Index of the first vertex from the buffer to be rendered
4226 * NumVertices: Number of vertices to be rendered
4227 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4229 * Return values
4230 * D3D_OK on success
4231 * DDERR_INVALIDPARAMS if D3DVertexBuf is NULL
4233 *****************************************************************************/
4234 static HRESULT
4235 IDirect3DDeviceImpl_7_DrawPrimitiveVB(IDirect3DDevice7 *iface,
4236 D3DPRIMITIVETYPE PrimitiveType,
4237 IDirect3DVertexBuffer7 *D3DVertexBuf,
4238 DWORD StartVertex,
4239 DWORD NumVertices,
4240 DWORD Flags)
4242 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
4243 IDirect3DVertexBufferImpl *vb = (IDirect3DVertexBufferImpl *)D3DVertexBuf;
4244 UINT PrimitiveCount;
4245 HRESULT hr;
4246 DWORD stride;
4247 WINED3DVERTEXBUFFER_DESC Desc;
4249 TRACE("(%p)->(%08x,%p,%08x,%08x,%08x)\n", This, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags);
4251 /* Sanity checks */
4252 if(!vb)
4254 ERR("(%p) No Vertex buffer specified\n", This);
4255 return DDERR_INVALIDPARAMS;
4258 /* Get the primitive count */
4259 switch(PrimitiveType)
4261 case D3DPT_POINTLIST:
4262 PrimitiveCount = NumVertices;
4263 break;
4265 case D3DPT_LINELIST:
4266 PrimitiveCount = NumVertices / 2;
4267 break;
4269 case D3DPT_LINESTRIP:
4270 PrimitiveCount = NumVertices - 1;
4271 break;
4273 case D3DPT_TRIANGLELIST:
4274 PrimitiveCount = NumVertices / 3;
4275 break;
4277 case D3DPT_TRIANGLESTRIP:
4278 PrimitiveCount = NumVertices - 2;
4279 break;
4281 case D3DPT_TRIANGLEFAN:
4282 PrimitiveCount = NumVertices - 2;
4283 break;
4285 default:
4286 return DDERR_INVALIDPARAMS;
4289 /* Get the FVF of the vertex buffer, and its stride */
4290 EnterCriticalSection(&ddraw_cs);
4291 hr = IWineD3DVertexBuffer_GetDesc(vb->wineD3DVertexBuffer,
4292 &Desc);
4293 if(hr != D3D_OK)
4295 ERR("(%p) IWineD3DVertexBuffer::GetDesc failed with hr = %08x\n", This, hr);
4296 LeaveCriticalSection(&ddraw_cs);
4297 return hr;
4299 stride = get_flexible_vertex_size(Desc.FVF);
4301 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
4302 vb->wineD3DVertexDeclaration);
4303 if(FAILED(hr))
4305 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr);
4306 LeaveCriticalSection(&ddraw_cs);
4307 return hr;
4310 /* Set the vertex stream source */
4311 hr = IWineD3DDevice_SetStreamSource(This->wineD3DDevice,
4312 0 /* StreamNumber */,
4313 vb->wineD3DVertexBuffer,
4314 0 /* StartVertex - we pass this to DrawPrimitive */,
4315 stride);
4316 if(hr != D3D_OK)
4318 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This, hr);
4319 LeaveCriticalSection(&ddraw_cs);
4320 return hr;
4323 /* Now draw the primitives */
4324 hr = IWineD3DDevice_DrawPrimitive(This->wineD3DDevice,
4325 PrimitiveType,
4326 StartVertex,
4327 PrimitiveCount);
4328 LeaveCriticalSection(&ddraw_cs);
4329 return hr;
4332 static HRESULT WINAPI
4333 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUSetup(IDirect3DDevice7 *iface,
4334 D3DPRIMITIVETYPE PrimitiveType,
4335 IDirect3DVertexBuffer7 *D3DVertexBuf,
4336 DWORD StartVertex,
4337 DWORD NumVertices,
4338 DWORD Flags)
4340 return IDirect3DDeviceImpl_7_DrawPrimitiveVB(iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags);
4343 static HRESULT WINAPI
4344 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUPreserve(IDirect3DDevice7 *iface,
4345 D3DPRIMITIVETYPE PrimitiveType,
4346 IDirect3DVertexBuffer7 *D3DVertexBuf,
4347 DWORD StartVertex,
4348 DWORD NumVertices,
4349 DWORD Flags)
4351 HRESULT hr;
4352 WORD old_fpucw;
4354 old_fpucw = d3d_fpu_setup();
4355 hr = IDirect3DDeviceImpl_7_DrawPrimitiveVB(iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags);
4356 set_fpu_control_word(old_fpucw);
4358 return hr;
4361 static HRESULT WINAPI
4362 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB(IDirect3DDevice3 *iface,
4363 D3DPRIMITIVETYPE PrimitiveType,
4364 IDirect3DVertexBuffer *D3DVertexBuf,
4365 DWORD StartVertex,
4366 DWORD NumVertices,
4367 DWORD Flags)
4369 IDirect3DDeviceImpl *This = device_from_device3(iface);
4370 IDirect3DVertexBufferImpl *vb = D3DVertexBuf ? vb_from_vb1(D3DVertexBuf) : NULL;
4371 TRACE_(ddraw_thunk)("(%p)->(%08x,%p,%08x,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, vb, StartVertex, NumVertices, Flags);
4372 return IDirect3DDevice7_DrawPrimitiveVB((IDirect3DDevice7 *)This, PrimitiveType,
4373 (IDirect3DVertexBuffer7 *)vb, StartVertex, NumVertices, Flags);
4377 /*****************************************************************************
4378 * IDirect3DDevice7::DrawIndexedPrimitiveVB
4380 * Draws primitives from a vertex buffer to the screen
4382 * Params:
4383 * PrimitiveType: Type of primitive to be rendered.
4384 * D3DVertexBuf: Source Vertex Buffer
4385 * StartVertex: Index of the first vertex from the buffer to be rendered
4386 * NumVertices: Number of vertices to be rendered
4387 * Indices: Array of DWORDs used to index into the Vertices
4388 * IndexCount: Number of indices in Indices
4389 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4391 * Return values
4393 *****************************************************************************/
4394 static HRESULT
4395 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(IDirect3DDevice7 *iface,
4396 D3DPRIMITIVETYPE PrimitiveType,
4397 IDirect3DVertexBuffer7 *D3DVertexBuf,
4398 DWORD StartVertex,
4399 DWORD NumVertices,
4400 WORD *Indices,
4401 DWORD IndexCount,
4402 DWORD Flags)
4404 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
4405 IDirect3DVertexBufferImpl *vb = (IDirect3DVertexBufferImpl *)D3DVertexBuf;
4406 DWORD stride;
4407 UINT PrimitiveCount;
4408 WORD *LockedIndices;
4409 HRESULT hr;
4410 WINED3DVERTEXBUFFER_DESC Desc;
4412 TRACE("(%p)->(%08x,%p,%d,%d,%p,%d,%08x)\n", This, PrimitiveType, vb, StartVertex, NumVertices, Indices, IndexCount, Flags);
4414 /* Steps:
4415 * 1) Calculate some things: Vertex count -> Primitive count, stride, ...
4416 * 2) Upload the Indices to the index buffer
4417 * 3) Set the index source
4418 * 4) Set the Vertex Buffer as the Stream source
4419 * 5) Call IWineD3DDevice::DrawIndexedPrimitive
4422 /* Get the primitive count */
4423 switch(PrimitiveType)
4425 case D3DPT_POINTLIST:
4426 PrimitiveCount = IndexCount;
4427 break;
4429 case D3DPT_LINELIST:
4430 PrimitiveCount = IndexCount / 2;
4431 break;
4433 case D3DPT_LINESTRIP:
4434 PrimitiveCount = IndexCount - 1;
4435 break;
4437 case D3DPT_TRIANGLELIST:
4438 PrimitiveCount = IndexCount / 3;
4439 break;
4441 case D3DPT_TRIANGLESTRIP:
4442 PrimitiveCount = IndexCount - 2;
4443 break;
4445 case D3DPT_TRIANGLEFAN:
4446 PrimitiveCount = IndexCount - 2;
4447 break;
4449 default: return DDERR_INVALIDPARAMS;
4452 EnterCriticalSection(&ddraw_cs);
4453 /* Get the FVF of the vertex buffer, and its stride */
4454 hr = IWineD3DVertexBuffer_GetDesc(vb->wineD3DVertexBuffer,
4455 &Desc);
4456 if(hr != D3D_OK)
4458 ERR("(%p) IWineD3DVertexBuffer::GetDesc failed with hr = %08x\n", This, hr);
4459 LeaveCriticalSection(&ddraw_cs);
4460 return hr;
4462 stride = get_flexible_vertex_size(Desc.FVF);
4463 TRACE("Vertex buffer FVF = %08x, stride=%d\n", Desc.FVF, stride);
4465 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
4466 vb->wineD3DVertexDeclaration);
4467 if(FAILED(hr))
4469 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr);
4470 LeaveCriticalSection(&ddraw_cs);
4471 return hr;
4474 /* copy the index stream into the index buffer.
4475 * A new IWineD3DDevice method could be created
4476 * which takes an user pointer containing the indices
4477 * or a SetData-Method for the index buffer, which
4478 * overrides the index buffer data with our pointer.
4480 hr = IWineD3DIndexBuffer_Lock(This->indexbuffer,
4481 0 /* OffSetToLock */,
4482 IndexCount * sizeof(WORD),
4483 (BYTE **) &LockedIndices,
4484 0 /* Flags */);
4485 assert(IndexCount < 0x100000);
4486 if(hr != D3D_OK)
4488 ERR("(%p) IWineD3DIndexBuffer::Lock failed with hr = %08x\n", This, hr);
4489 LeaveCriticalSection(&ddraw_cs);
4490 return hr;
4492 memcpy(LockedIndices, Indices, IndexCount * sizeof(WORD));
4493 hr = IWineD3DIndexBuffer_Unlock(This->indexbuffer);
4494 if(hr != D3D_OK)
4496 ERR("(%p) IWineD3DIndexBuffer::Unlock failed with hr = %08x\n", This, hr);
4497 LeaveCriticalSection(&ddraw_cs);
4498 return hr;
4501 /* Set the index stream */
4502 IWineD3DDevice_SetBaseVertexIndex(This->wineD3DDevice, StartVertex);
4503 hr = IWineD3DDevice_SetIndices(This->wineD3DDevice, This->indexbuffer);
4505 /* Set the vertex stream source */
4506 hr = IWineD3DDevice_SetStreamSource(This->wineD3DDevice,
4507 0 /* StreamNumber */,
4508 vb->wineD3DVertexBuffer,
4509 0 /* offset, we pass this to DrawIndexedPrimitive */,
4510 stride);
4511 if(hr != D3D_OK)
4513 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This, hr);
4514 LeaveCriticalSection(&ddraw_cs);
4515 return hr;
4519 hr = IWineD3DDevice_DrawIndexedPrimitive(This->wineD3DDevice,
4520 PrimitiveType,
4521 0 /* minIndex */,
4522 NumVertices,
4523 0 /* StartIndex */,
4524 PrimitiveCount);
4526 LeaveCriticalSection(&ddraw_cs);
4527 return hr;
4530 static HRESULT WINAPI
4531 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUSetup(IDirect3DDevice7 *iface,
4532 D3DPRIMITIVETYPE PrimitiveType,
4533 IDirect3DVertexBuffer7 *D3DVertexBuf,
4534 DWORD StartVertex,
4535 DWORD NumVertices,
4536 WORD *Indices,
4537 DWORD IndexCount,
4538 DWORD Flags)
4540 return IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Indices, IndexCount, Flags);
4543 static HRESULT WINAPI
4544 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUPreserve(IDirect3DDevice7 *iface,
4545 D3DPRIMITIVETYPE PrimitiveType,
4546 IDirect3DVertexBuffer7 *D3DVertexBuf,
4547 DWORD StartVertex,
4548 DWORD NumVertices,
4549 WORD *Indices,
4550 DWORD IndexCount,
4551 DWORD Flags)
4553 HRESULT hr;
4554 WORD old_fpucw;
4556 old_fpucw = d3d_fpu_setup();
4557 hr = IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Indices, IndexCount, Flags);
4558 set_fpu_control_word(old_fpucw);
4560 return hr;
4563 static HRESULT WINAPI
4564 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB(IDirect3DDevice3 *iface,
4565 D3DPRIMITIVETYPE PrimitiveType,
4566 IDirect3DVertexBuffer *D3DVertexBuf,
4567 WORD *Indices,
4568 DWORD IndexCount,
4569 DWORD Flags)
4571 IDirect3DDeviceImpl *This = device_from_device3(iface);
4572 IDirect3DVertexBufferImpl *VB = vb_from_vb1(D3DVertexBuf);
4573 TRACE_(ddraw_thunk)("(%p)->(%08x,%p,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VB, Indices, IndexCount, Flags);
4575 return IDirect3DDevice7_DrawIndexedPrimitiveVB((IDirect3DDevice7 *)This, PrimitiveType,
4576 (IDirect3DVertexBuffer7 *)VB, 0, IndexCount, Indices, IndexCount, Flags);
4579 /*****************************************************************************
4580 * IDirect3DDevice7::ComputeSphereVisibility
4582 * Calculates the visibility of spheres in the current viewport. The spheres
4583 * are passed in the Centers and Radii arrays, the results are passed back
4584 * in the ReturnValues array. Return values are either completely visible,
4585 * partially visible or completely invisible.
4586 * The return value consist of a combination of D3DCLIP_* flags, or it's
4587 * 0 if the sphere is completely visible(according to the SDK, not checked)
4589 * Sounds like an overdose of math ;)
4591 * Version 3 and 7
4593 * Params:
4594 * Centers: Array containing the sphere centers
4595 * Radii: Array containing the sphere radii
4596 * NumSpheres: The number of centers and radii in the arrays
4597 * Flags: Some flags
4598 * ReturnValues: Array to write the results to
4600 * Returns:
4601 * D3D_OK because it's a stub
4602 * (DDERR_INVALIDPARAMS if Centers, Radii or ReturnValues are NULL)
4603 * (D3DERR_INVALIDMATRIX if the combined world, view and proj matrix
4604 * is singular)
4606 *****************************************************************************/
4607 static HRESULT WINAPI
4608 IDirect3DDeviceImpl_7_ComputeSphereVisibility(IDirect3DDevice7 *iface,
4609 D3DVECTOR *Centers,
4610 D3DVALUE *Radii,
4611 DWORD NumSpheres,
4612 DWORD Flags,
4613 DWORD *ReturnValues)
4615 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
4616 FIXME("(%p)->(%p,%p,%08x,%08x,%p): stub!\n", This, Centers, Radii, NumSpheres, Flags, ReturnValues);
4618 /* the DirectX 7 sdk says that the visibility is computed by
4619 * back-transforming the viewing frustum to model space
4620 * using the inverse of the combined world, view and projection
4621 * matrix. If the matrix can't be reversed, D3DERR_INVALIDMATRIX
4622 * is returned.
4624 * Basic implementation idea:
4625 * 1) Check if the center is in the viewing frustum
4626 * 2) Cut the sphere with the planes of the viewing
4627 * frustum
4629 * ->Center inside the frustum, no intersections:
4630 * Fully visible
4631 * ->Center outside the frustum, no intersections:
4632 * Not visible
4633 * ->Some intersections: Partially visible
4635 * Implement this call in WineD3D. Either implement the
4636 * matrix and vector stuff in WineD3D, or use some external
4637 * math library.
4640 return D3D_OK;
4643 static HRESULT WINAPI
4644 Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility(IDirect3DDevice3 *iface,
4645 D3DVECTOR *Centers,
4646 D3DVALUE *Radii,
4647 DWORD NumSpheres,
4648 DWORD Flags,
4649 DWORD *ReturnValues)
4651 IDirect3DDeviceImpl *This = device_from_device3(iface);
4652 TRACE_(ddraw_thunk)("(%p)->(%p,%p,%08x,%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, Centers, Radii, NumSpheres, Flags, ReturnValues);
4653 return IDirect3DDevice7_ComputeSphereVisibility((IDirect3DDevice7 *)This,
4654 Centers, Radii, NumSpheres, Flags, ReturnValues);
4657 /*****************************************************************************
4658 * IDirect3DDevice7::GetTexture
4660 * Returns the texture interface handle assigned to a texture stage.
4661 * The returned texture is AddRefed. This is taken from old ddraw,
4662 * not checked in Windows.
4664 * Version 3 and 7
4666 * Params:
4667 * Stage: Texture stage to read the texture from
4668 * Texture: Address to store the interface pointer at
4670 * Returns:
4671 * D3D_OK on success
4672 * DDERR_INVALIDPARAMS if Texture is NULL
4673 * For details, see IWineD3DDevice::GetTexture
4675 *****************************************************************************/
4676 static HRESULT
4677 IDirect3DDeviceImpl_7_GetTexture(IDirect3DDevice7 *iface,
4678 DWORD Stage,
4679 IDirectDrawSurface7 **Texture)
4681 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
4682 IWineD3DBaseTexture *Surf;
4683 HRESULT hr;
4684 TRACE("(%p)->(%d,%p): Relay\n", This, Stage, Texture);
4686 if(!Texture)
4688 TRACE("Texture == NULL, failing with DDERR_INVALIDPARAMS\n");
4689 return DDERR_INVALIDPARAMS;
4692 EnterCriticalSection(&ddraw_cs);
4693 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice, Stage, &Surf);
4694 if( (hr != D3D_OK) || (!Surf) )
4696 *Texture = NULL;
4697 LeaveCriticalSection(&ddraw_cs);
4698 return hr;
4701 /* GetParent AddRef()s, which is perfectly OK.
4702 * We have passed the IDirectDrawSurface7 interface to WineD3D, so that's OK too.
4704 hr = IWineD3DBaseTexture_GetParent(Surf,
4705 (IUnknown **) Texture);
4706 LeaveCriticalSection(&ddraw_cs);
4707 return hr;
4710 static HRESULT WINAPI
4711 IDirect3DDeviceImpl_7_GetTexture_FPUSetup(IDirect3DDevice7 *iface,
4712 DWORD Stage,
4713 IDirectDrawSurface7 **Texture)
4715 return IDirect3DDeviceImpl_7_GetTexture(iface, Stage, Texture);
4718 static HRESULT WINAPI
4719 IDirect3DDeviceImpl_7_GetTexture_FPUPreserve(IDirect3DDevice7 *iface,
4720 DWORD Stage,
4721 IDirectDrawSurface7 **Texture)
4723 HRESULT hr;
4724 WORD old_fpucw;
4726 old_fpucw = d3d_fpu_setup();
4727 hr = IDirect3DDeviceImpl_7_GetTexture(iface, Stage, Texture);
4728 set_fpu_control_word(old_fpucw);
4730 return hr;
4733 static HRESULT WINAPI
4734 Thunk_IDirect3DDeviceImpl_3_GetTexture(IDirect3DDevice3 *iface,
4735 DWORD Stage,
4736 IDirect3DTexture2 **Texture2)
4738 IDirect3DDeviceImpl *This = device_from_device3(iface);
4739 HRESULT ret;
4740 IDirectDrawSurface7 *ret_val;
4742 TRACE_(ddraw_thunk)("(%p)->(%d,%p) thunking to IDirect3DDevice7 interface.\n", This, Stage, Texture2);
4743 ret = IDirect3DDevice7_GetTexture((IDirect3DDevice7 *)This, Stage, &ret_val);
4745 *Texture2 = ret_val ? (IDirect3DTexture2 *)&((IDirectDrawSurfaceImpl *)ret_val)->IDirect3DTexture2_vtbl : NULL;
4747 TRACE_(ddraw_thunk)(" returning interface %p.\n", *Texture2);
4749 return ret;
4752 /*****************************************************************************
4753 * IDirect3DDevice7::SetTexture
4755 * Assigns a texture to a texture stage. Is the texture AddRef-ed?
4757 * Version 3 and 7
4759 * Params:
4760 * Stage: The stage to assign the texture to
4761 * Texture: Interface pointer to the texture surface
4763 * Returns
4764 * D3D_OK on success
4765 * For details, see IWineD3DDevice::SetTexture
4767 *****************************************************************************/
4768 static HRESULT
4769 IDirect3DDeviceImpl_7_SetTexture(IDirect3DDevice7 *iface,
4770 DWORD Stage,
4771 IDirectDrawSurface7 *Texture)
4773 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
4774 IDirectDrawSurfaceImpl *surf = (IDirectDrawSurfaceImpl *)Texture;
4775 HRESULT hr;
4776 TRACE("(%p)->(%08x,%p): Relay!\n", This, Stage, surf);
4778 /* Texture may be NULL here */
4779 EnterCriticalSection(&ddraw_cs);
4780 hr = IWineD3DDevice_SetTexture(This->wineD3DDevice,
4781 Stage,
4782 surf ? surf->wineD3DTexture : NULL);
4783 LeaveCriticalSection(&ddraw_cs);
4784 return hr;
4787 static HRESULT WINAPI
4788 IDirect3DDeviceImpl_7_SetTexture_FPUSetup(IDirect3DDevice7 *iface,
4789 DWORD Stage,
4790 IDirectDrawSurface7 *Texture)
4792 return IDirect3DDeviceImpl_7_SetTexture(iface, Stage, Texture);
4795 static HRESULT WINAPI
4796 IDirect3DDeviceImpl_7_SetTexture_FPUPreserve(IDirect3DDevice7 *iface,
4797 DWORD Stage,
4798 IDirectDrawSurface7 *Texture)
4800 HRESULT hr;
4801 WORD old_fpucw;
4803 old_fpucw = d3d_fpu_setup();
4804 hr = IDirect3DDeviceImpl_7_SetTexture(iface, Stage, Texture);
4805 set_fpu_control_word(old_fpucw);
4807 return hr;
4810 static HRESULT WINAPI
4811 IDirect3DDeviceImpl_3_SetTexture(IDirect3DDevice3 *iface,
4812 DWORD Stage,
4813 IDirect3DTexture2 *Texture2)
4815 IDirect3DDeviceImpl *This = device_from_device3(iface);
4816 IDirectDrawSurfaceImpl *tex = Texture2 ? surface_from_texture2(Texture2) : NULL;
4817 DWORD texmapblend;
4818 HRESULT hr;
4819 TRACE("(%p)->(%d,%p)\n", This, Stage, tex);
4821 EnterCriticalSection(&ddraw_cs);
4823 if (This->legacyTextureBlending)
4824 IDirect3DDevice3_GetRenderState(iface, D3DRENDERSTATE_TEXTUREMAPBLEND, &texmapblend);
4826 hr = IDirect3DDevice7_SetTexture((IDirect3DDevice7 *)This, Stage, (IDirectDrawSurface7 *)tex);
4828 if (This->legacyTextureBlending && texmapblend == D3DTBLEND_MODULATE)
4830 /* This fixup is required by the way D3DTBLEND_MODULATE maps to texture stage states.
4831 See IDirect3DDeviceImpl_3_SetRenderState for details. */
4832 BOOL tex_alpha = FALSE;
4833 IWineD3DBaseTexture *tex = NULL;
4834 WINED3DSURFACE_DESC desc;
4835 WINED3DFORMAT fmt;
4836 DDPIXELFORMAT ddfmt;
4837 HRESULT result;
4839 result = IWineD3DDevice_GetTexture(This->wineD3DDevice,
4841 &tex);
4843 if(result == WINED3D_OK && tex)
4845 memset(&desc, 0, sizeof(desc));
4846 desc.Format = &fmt;
4847 result = IWineD3DTexture_GetLevelDesc((IWineD3DTexture*) tex, 0, &desc);
4848 if (SUCCEEDED(result))
4850 ddfmt.dwSize = sizeof(ddfmt);
4851 PixelFormat_WineD3DtoDD(&ddfmt, fmt);
4852 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
4855 IWineD3DBaseTexture_Release(tex);
4858 /* alphaop is WINED3DTOP_SELECTARG1 if it's D3DTBLEND_MODULATE, so only modify alphaarg1 */
4859 if (tex_alpha)
4861 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
4863 else
4865 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_CURRENT);
4869 LeaveCriticalSection(&ddraw_cs);
4871 return hr;
4874 static const struct tss_lookup
4876 BOOL sampler_state;
4877 DWORD state;
4879 tss_lookup[] =
4881 {FALSE, WINED3DTSS_FORCE_DWORD}, /* 0, unused */
4882 {FALSE, WINED3DTSS_COLOROP}, /* 1, D3DTSS_COLOROP */
4883 {FALSE, WINED3DTSS_COLORARG1}, /* 2, D3DTSS_COLORARG1 */
4884 {FALSE, WINED3DTSS_COLORARG2}, /* 3, D3DTSS_COLORARG2 */
4885 {FALSE, WINED3DTSS_ALPHAOP}, /* 4, D3DTSS_ALPHAOP */
4886 {FALSE, WINED3DTSS_ALPHAARG1}, /* 5, D3DTSS_ALPHAARG1 */
4887 {FALSE, WINED3DTSS_ALPHAARG2}, /* 6, D3DTSS_ALPHAARG2 */
4888 {FALSE, WINED3DTSS_BUMPENVMAT00}, /* 7, D3DTSS_BUMPENVMAT00 */
4889 {FALSE, WINED3DTSS_BUMPENVMAT01}, /* 8, D3DTSS_BUMPENVMAT01 */
4890 {FALSE, WINED3DTSS_BUMPENVMAT10}, /* 9, D3DTSS_BUMPENVMAT10 */
4891 {FALSE, WINED3DTSS_BUMPENVMAT11}, /* 10, D3DTSS_BUMPENVMAT11 */
4892 {FALSE, WINED3DTSS_TEXCOORDINDEX}, /* 11, D3DTSS_TEXCOORDINDEX */
4893 {TRUE, WINED3DSAMP_ADDRESSU}, /* 12, D3DTSS_ADDRESS */
4894 {TRUE, WINED3DSAMP_ADDRESSU}, /* 13, D3DTSS_ADDRESSU */
4895 {TRUE, WINED3DSAMP_ADDRESSV}, /* 14, D3DTSS_ADDRESSV */
4896 {TRUE, WINED3DSAMP_BORDERCOLOR}, /* 15, D3DTSS_BORDERCOLOR */
4897 {TRUE, WINED3DSAMP_MAGFILTER}, /* 16, D3DTSS_MAGFILTER */
4898 {TRUE, WINED3DSAMP_MINFILTER}, /* 17, D3DTSS_MINFILTER */
4899 {TRUE, WINED3DSAMP_MIPFILTER}, /* 18, D3DTSS_MIPFILTER */
4900 {TRUE, WINED3DSAMP_MIPMAPLODBIAS}, /* 19, D3DTSS_MIPMAPLODBIAS */
4901 {TRUE, WINED3DSAMP_MAXMIPLEVEL}, /* 20, D3DTSS_MAXMIPLEVEL */
4902 {TRUE, WINED3DSAMP_MAXANISOTROPY}, /* 21, D3DTSS_MAXANISOTROPY */
4903 {FALSE, WINED3DTSS_BUMPENVLSCALE}, /* 22, D3DTSS_BUMPENVLSCALE */
4904 {FALSE, WINED3DTSS_BUMPENVLOFFSET}, /* 23, D3DTSS_BUMPENVLOFFSET */
4905 {FALSE, WINED3DTSS_TEXTURETRANSFORMFLAGS}, /* 24, D3DTSS_TEXTURETRANSFORMFLAGS */
4908 /*****************************************************************************
4909 * IDirect3DDevice7::GetTextureStageState
4911 * Retrieves a state from a texture stage.
4913 * Version 3 and 7
4915 * Params:
4916 * Stage: The stage to retrieve the state from
4917 * TexStageStateType: The state type to retrieve
4918 * State: Address to store the state's value at
4920 * Returns:
4921 * D3D_OK on success
4922 * DDERR_INVALIDPARAMS if State is NULL
4923 * For details, see IWineD3DDevice::GetTextureStageState
4925 *****************************************************************************/
4926 static HRESULT
4927 IDirect3DDeviceImpl_7_GetTextureStageState(IDirect3DDevice7 *iface,
4928 DWORD Stage,
4929 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4930 DWORD *State)
4932 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
4933 HRESULT hr;
4934 const struct tss_lookup *l = &tss_lookup[TexStageStateType];
4935 TRACE("(%p)->(%08x,%08x,%p): Relay!\n", This, Stage, TexStageStateType, State);
4937 if(!State)
4938 return DDERR_INVALIDPARAMS;
4940 EnterCriticalSection(&ddraw_cs);
4942 if (l->sampler_state)
4944 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice, Stage, l->state, State);
4946 switch(TexStageStateType)
4948 /* Mipfilter is a sampler state with different values */
4949 case D3DTSS_MIPFILTER:
4951 switch(*State)
4953 case WINED3DTEXF_NONE: *State = D3DTFP_NONE; break;
4954 case WINED3DTEXF_POINT: *State = D3DTFP_POINT; break;
4955 case WINED3DTEXF_LINEAR: *State = D3DTFP_LINEAR; break;
4956 default:
4957 ERR("Unexpected mipfilter value %#x\n", *State);
4958 *State = D3DTFP_NONE;
4959 break;
4961 break;
4964 /* Magfilter has slightly different values */
4965 case D3DTSS_MAGFILTER:
4967 switch(*State)
4969 case WINED3DTEXF_POINT: *State = D3DTFG_POINT; break;
4970 case WINED3DTEXF_LINEAR: *State = D3DTFG_LINEAR; break;
4971 case WINED3DTEXF_ANISOTROPIC: *State = D3DTFG_ANISOTROPIC; break;
4972 case WINED3DTEXF_FLATCUBIC: *State = D3DTFG_FLATCUBIC; break;
4973 case WINED3DTEXF_GAUSSIANCUBIC: *State = D3DTFG_GAUSSIANCUBIC; break;
4974 default:
4975 ERR("Unexpected wined3d mag filter value %#x\n", *State);
4976 *State = D3DTFG_POINT;
4977 break;
4979 break;
4982 default:
4983 break;
4986 else
4988 hr = IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, Stage, l->state, State);
4991 LeaveCriticalSection(&ddraw_cs);
4992 return hr;
4995 static HRESULT WINAPI
4996 IDirect3DDeviceImpl_7_GetTextureStageState_FPUSetup(IDirect3DDevice7 *iface,
4997 DWORD Stage,
4998 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4999 DWORD *State)
5001 return IDirect3DDeviceImpl_7_GetTextureStageState(iface, Stage, TexStageStateType, State);
5004 static HRESULT WINAPI
5005 IDirect3DDeviceImpl_7_GetTextureStageState_FPUPreserve(IDirect3DDevice7 *iface,
5006 DWORD Stage,
5007 D3DTEXTURESTAGESTATETYPE TexStageStateType,
5008 DWORD *State)
5010 HRESULT hr;
5011 WORD old_fpucw;
5013 old_fpucw = d3d_fpu_setup();
5014 hr = IDirect3DDeviceImpl_7_GetTextureStageState(iface, Stage, TexStageStateType, State);
5015 set_fpu_control_word(old_fpucw);
5017 return hr;
5020 static HRESULT WINAPI
5021 Thunk_IDirect3DDeviceImpl_3_GetTextureStageState(IDirect3DDevice3 *iface,
5022 DWORD Stage,
5023 D3DTEXTURESTAGESTATETYPE TexStageStateType,
5024 DWORD *State)
5026 IDirect3DDeviceImpl *This = device_from_device3(iface);
5027 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, Stage, TexStageStateType, State);
5028 return IDirect3DDevice7_GetTextureStageState((IDirect3DDevice7 *)This, Stage, TexStageStateType, State);
5031 /*****************************************************************************
5032 * IDirect3DDevice7::SetTextureStageState
5034 * Sets a texture stage state. Some stage types need to be handled specially,
5035 * because they do not exist in WineD3D and were moved to another place
5037 * Version 3 and 7
5039 * Params:
5040 * Stage: The stage to modify
5041 * TexStageStateType: The state to change
5042 * State: The new value for the state
5044 * Returns:
5045 * D3D_OK on success
5046 * For details, see IWineD3DDevice::SetTextureStageState
5048 *****************************************************************************/
5049 static HRESULT
5050 IDirect3DDeviceImpl_7_SetTextureStageState(IDirect3DDevice7 *iface,
5051 DWORD Stage,
5052 D3DTEXTURESTAGESTATETYPE TexStageStateType,
5053 DWORD State)
5055 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5056 const struct tss_lookup *l = &tss_lookup[TexStageStateType];
5057 HRESULT hr;
5058 TRACE("(%p)->(%08x,%08x,%08x): Relay!\n", This, Stage, TexStageStateType, State);
5060 EnterCriticalSection(&ddraw_cs);
5062 if (l->sampler_state)
5064 switch(TexStageStateType)
5066 /* Mipfilter is a sampler state with different values */
5067 case D3DTSS_MIPFILTER:
5069 switch(State)
5071 case D3DTFP_NONE: State = WINED3DTEXF_NONE; break;
5072 case D3DTFP_POINT: State = WINED3DTEXF_POINT; break;
5073 case 0: /* Unchecked */
5074 case D3DTFP_LINEAR: State = WINED3DTEXF_LINEAR; break;
5075 default:
5076 ERR("Unexpected mipfilter value %d\n", State);
5077 State = WINED3DTEXF_NONE;
5078 break;
5080 break;
5083 /* Magfilter has slightly different values */
5084 case D3DTSS_MAGFILTER:
5086 switch(State)
5088 case D3DTFG_POINT: State = WINED3DTEXF_POINT; break;
5089 case D3DTFG_LINEAR: State = WINED3DTEXF_LINEAR; break;
5090 case D3DTFG_FLATCUBIC: State = WINED3DTEXF_FLATCUBIC; break;
5091 case D3DTFG_GAUSSIANCUBIC: State = WINED3DTEXF_GAUSSIANCUBIC; break;
5092 case D3DTFG_ANISOTROPIC: State = WINED3DTEXF_ANISOTROPIC; break;
5093 default:
5094 ERR("Unexpected d3d7 mag filter type %d\n", State);
5095 State = WINED3DTEXF_POINT;
5096 break;
5098 break;
5101 case D3DTSS_ADDRESS:
5102 IWineD3DDevice_SetSamplerState(This->wineD3DDevice, Stage, WINED3DSAMP_ADDRESSV, State);
5103 break;
5105 default:
5106 break;
5109 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice, Stage, l->state, State);
5111 else
5113 hr = IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, Stage, l->state, State);
5116 LeaveCriticalSection(&ddraw_cs);
5117 return hr;
5120 static HRESULT WINAPI
5121 IDirect3DDeviceImpl_7_SetTextureStageState_FPUSetup(IDirect3DDevice7 *iface,
5122 DWORD Stage,
5123 D3DTEXTURESTAGESTATETYPE TexStageStateType,
5124 DWORD State)
5126 return IDirect3DDeviceImpl_7_SetTextureStageState(iface, Stage, TexStageStateType, State);
5129 static HRESULT WINAPI
5130 IDirect3DDeviceImpl_7_SetTextureStageState_FPUPreserve(IDirect3DDevice7 *iface,
5131 DWORD Stage,
5132 D3DTEXTURESTAGESTATETYPE TexStageStateType,
5133 DWORD State)
5135 HRESULT hr;
5136 WORD old_fpucw;
5138 old_fpucw = d3d_fpu_setup();
5139 hr = IDirect3DDeviceImpl_7_SetTextureStageState(iface, Stage, TexStageStateType, State);
5140 set_fpu_control_word(old_fpucw);
5142 return hr;
5145 static HRESULT WINAPI
5146 Thunk_IDirect3DDeviceImpl_3_SetTextureStageState(IDirect3DDevice3 *iface,
5147 DWORD Stage,
5148 D3DTEXTURESTAGESTATETYPE TexStageStateType,
5149 DWORD State)
5151 IDirect3DDeviceImpl *This = device_from_device3(iface);
5152 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, Stage, TexStageStateType, State);
5153 return IDirect3DDevice7_SetTextureStageState((IDirect3DDevice7 *)This, Stage, TexStageStateType, State);
5156 /*****************************************************************************
5157 * IDirect3DDevice7::ValidateDevice
5159 * SDK: "Reports the device's ability to render the currently set
5160 * texture-blending operations in a single pass". Whatever that means
5161 * exactly...
5163 * Version 3 and 7
5165 * Params:
5166 * NumPasses: Address to write the number of necessary passes for the
5167 * desired effect to.
5169 * Returns:
5170 * D3D_OK on success
5171 * See IWineD3DDevice::ValidateDevice for more details
5173 *****************************************************************************/
5174 static HRESULT
5175 IDirect3DDeviceImpl_7_ValidateDevice(IDirect3DDevice7 *iface,
5176 DWORD *NumPasses)
5178 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5179 HRESULT hr;
5180 TRACE("(%p)->(%p): Relay\n", This, NumPasses);
5182 EnterCriticalSection(&ddraw_cs);
5183 hr = IWineD3DDevice_ValidateDevice(This->wineD3DDevice, NumPasses);
5184 LeaveCriticalSection(&ddraw_cs);
5185 return hr;
5188 static HRESULT WINAPI
5189 IDirect3DDeviceImpl_7_ValidateDevice_FPUSetup(IDirect3DDevice7 *iface,
5190 DWORD *NumPasses)
5192 return IDirect3DDeviceImpl_7_ValidateDevice(iface, NumPasses);
5195 static HRESULT WINAPI
5196 IDirect3DDeviceImpl_7_ValidateDevice_FPUPreserve(IDirect3DDevice7 *iface,
5197 DWORD *NumPasses)
5199 HRESULT hr;
5200 WORD old_fpucw;
5202 old_fpucw = d3d_fpu_setup();
5203 hr = IDirect3DDeviceImpl_7_ValidateDevice(iface, NumPasses);
5204 set_fpu_control_word(old_fpucw);
5206 return hr;
5209 static HRESULT WINAPI
5210 Thunk_IDirect3DDeviceImpl_3_ValidateDevice(IDirect3DDevice3 *iface,
5211 DWORD *Passes)
5213 IDirect3DDeviceImpl *This = device_from_device3(iface);
5214 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Passes);
5215 return IDirect3DDevice7_ValidateDevice((IDirect3DDevice7 *)This, Passes);
5218 /*****************************************************************************
5219 * IDirect3DDevice7::Clear
5221 * Fills the render target, the z buffer and the stencil buffer with a
5222 * clear color / value
5224 * Version 7 only
5226 * Params:
5227 * Count: Number of rectangles in Rects must be 0 if Rects is NULL
5228 * Rects: Rectangles to clear. If NULL, the whole surface is cleared
5229 * Flags: Some flags, as usual
5230 * Color: Clear color for the render target
5231 * Z: Clear value for the Z buffer
5232 * Stencil: Clear value to store in each stencil buffer entry
5234 * Returns:
5235 * D3D_OK on success
5236 * For details, see IWineD3DDevice::Clear
5238 *****************************************************************************/
5239 static HRESULT
5240 IDirect3DDeviceImpl_7_Clear(IDirect3DDevice7 *iface,
5241 DWORD Count,
5242 D3DRECT *Rects,
5243 DWORD Flags,
5244 D3DCOLOR Color,
5245 D3DVALUE Z,
5246 DWORD Stencil)
5248 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5249 HRESULT hr;
5250 TRACE("(%p)->(%08x,%p,%08x,%08x,%f,%08x): Relay\n", This, Count, Rects, Flags, Color, Z, Stencil);
5252 /* Note; D3DRECT is compatible with WINED3DRECT */
5253 EnterCriticalSection(&ddraw_cs);
5254 hr = IWineD3DDevice_Clear(This->wineD3DDevice, Count, (WINED3DRECT*) Rects, Flags, Color, Z, Stencil);
5255 LeaveCriticalSection(&ddraw_cs);
5256 return hr;
5259 static HRESULT WINAPI
5260 IDirect3DDeviceImpl_7_Clear_FPUSetup(IDirect3DDevice7 *iface,
5261 DWORD Count,
5262 D3DRECT *Rects,
5263 DWORD Flags,
5264 D3DCOLOR Color,
5265 D3DVALUE Z,
5266 DWORD Stencil)
5268 return IDirect3DDeviceImpl_7_Clear(iface, Count, Rects, Flags, Color, Z, Stencil);
5271 static HRESULT WINAPI
5272 IDirect3DDeviceImpl_7_Clear_FPUPreserve(IDirect3DDevice7 *iface,
5273 DWORD Count,
5274 D3DRECT *Rects,
5275 DWORD Flags,
5276 D3DCOLOR Color,
5277 D3DVALUE Z,
5278 DWORD Stencil)
5280 HRESULT hr;
5281 WORD old_fpucw;
5283 old_fpucw = d3d_fpu_setup();
5284 hr = IDirect3DDeviceImpl_7_Clear(iface, Count, Rects, Flags, Color, Z, Stencil);
5285 set_fpu_control_word(old_fpucw);
5287 return hr;
5290 /*****************************************************************************
5291 * IDirect3DDevice7::SetViewport
5293 * Sets the current viewport.
5295 * Version 7 only, but IDirect3DViewport uses this call for older
5296 * versions
5298 * Params:
5299 * Data: The new viewport to set
5301 * Returns:
5302 * D3D_OK on success
5303 * DDERR_INVALIDPARAMS if Data is NULL
5304 * For more details, see IWineDDDevice::SetViewport
5306 *****************************************************************************/
5307 static HRESULT
5308 IDirect3DDeviceImpl_7_SetViewport(IDirect3DDevice7 *iface,
5309 D3DVIEWPORT7 *Data)
5311 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5312 HRESULT hr;
5313 TRACE("(%p)->(%p) Relay!\n", This, Data);
5315 if(!Data)
5316 return DDERR_INVALIDPARAMS;
5318 /* Note: D3DVIEWPORT7 is compatible with WINED3DVIEWPORT */
5319 EnterCriticalSection(&ddraw_cs);
5320 hr = IWineD3DDevice_SetViewport(This->wineD3DDevice,
5321 (WINED3DVIEWPORT*) Data);
5322 LeaveCriticalSection(&ddraw_cs);
5323 return hr;
5326 static HRESULT WINAPI
5327 IDirect3DDeviceImpl_7_SetViewport_FPUSetup(IDirect3DDevice7 *iface,
5328 D3DVIEWPORT7 *Data)
5330 return IDirect3DDeviceImpl_7_SetViewport(iface, Data);
5333 static HRESULT WINAPI
5334 IDirect3DDeviceImpl_7_SetViewport_FPUPreserve(IDirect3DDevice7 *iface,
5335 D3DVIEWPORT7 *Data)
5337 HRESULT hr;
5338 WORD old_fpucw;
5340 old_fpucw = d3d_fpu_setup();
5341 hr = IDirect3DDeviceImpl_7_SetViewport(iface, Data);
5342 set_fpu_control_word(old_fpucw);
5344 return hr;
5347 /*****************************************************************************
5348 * IDirect3DDevice::GetViewport
5350 * Returns the current viewport
5352 * Version 7
5354 * Params:
5355 * Data: D3D7Viewport structure to write the viewport information to
5357 * Returns:
5358 * D3D_OK on success
5359 * DDERR_INVALIDPARAMS if Data is NULL
5360 * For more details, see IWineD3DDevice::GetViewport
5362 *****************************************************************************/
5363 static HRESULT
5364 IDirect3DDeviceImpl_7_GetViewport(IDirect3DDevice7 *iface,
5365 D3DVIEWPORT7 *Data)
5367 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5368 HRESULT hr;
5369 TRACE("(%p)->(%p) Relay!\n", This, Data);
5371 if(!Data)
5372 return DDERR_INVALIDPARAMS;
5374 /* Note: D3DVIEWPORT7 is compatible with WINED3DVIEWPORT */
5375 EnterCriticalSection(&ddraw_cs);
5376 hr = IWineD3DDevice_GetViewport(This->wineD3DDevice,
5377 (WINED3DVIEWPORT*) Data);
5379 LeaveCriticalSection(&ddraw_cs);
5380 return hr_ddraw_from_wined3d(hr);
5383 static HRESULT WINAPI
5384 IDirect3DDeviceImpl_7_GetViewport_FPUSetup(IDirect3DDevice7 *iface,
5385 D3DVIEWPORT7 *Data)
5387 return IDirect3DDeviceImpl_7_GetViewport(iface, Data);
5390 static HRESULT WINAPI
5391 IDirect3DDeviceImpl_7_GetViewport_FPUPreserve(IDirect3DDevice7 *iface,
5392 D3DVIEWPORT7 *Data)
5394 HRESULT hr;
5395 WORD old_fpucw;
5397 old_fpucw = d3d_fpu_setup();
5398 hr = IDirect3DDeviceImpl_7_GetViewport(iface, Data);
5399 set_fpu_control_word(old_fpucw);
5401 return hr;
5404 /*****************************************************************************
5405 * IDirect3DDevice7::SetMaterial
5407 * Sets the Material
5409 * Version 7
5411 * Params:
5412 * Mat: The material to set
5414 * Returns:
5415 * D3D_OK on success
5416 * DDERR_INVALIDPARAMS if Mat is NULL.
5417 * For more details, see IWineD3DDevice::SetMaterial
5419 *****************************************************************************/
5420 static HRESULT
5421 IDirect3DDeviceImpl_7_SetMaterial(IDirect3DDevice7 *iface,
5422 D3DMATERIAL7 *Mat)
5424 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5425 HRESULT hr;
5426 TRACE("(%p)->(%p): Relay!\n", This, Mat);
5428 if (!Mat) return DDERR_INVALIDPARAMS;
5429 /* Note: D3DMATERIAL7 is compatible with WINED3DMATERIAL */
5430 EnterCriticalSection(&ddraw_cs);
5431 hr = IWineD3DDevice_SetMaterial(This->wineD3DDevice,
5432 (WINED3DMATERIAL*) Mat);
5433 LeaveCriticalSection(&ddraw_cs);
5434 return hr_ddraw_from_wined3d(hr);
5437 static HRESULT WINAPI
5438 IDirect3DDeviceImpl_7_SetMaterial_FPUSetup(IDirect3DDevice7 *iface,
5439 D3DMATERIAL7 *Mat)
5441 return IDirect3DDeviceImpl_7_SetMaterial(iface, Mat);
5444 static HRESULT WINAPI
5445 IDirect3DDeviceImpl_7_SetMaterial_FPUPreserve(IDirect3DDevice7 *iface,
5446 D3DMATERIAL7 *Mat)
5448 HRESULT hr;
5449 WORD old_fpucw;
5451 old_fpucw = d3d_fpu_setup();
5452 hr = IDirect3DDeviceImpl_7_SetMaterial(iface, Mat);
5453 set_fpu_control_word(old_fpucw);
5455 return hr;
5458 /*****************************************************************************
5459 * IDirect3DDevice7::GetMaterial
5461 * Returns the current material
5463 * Version 7
5465 * Params:
5466 * Mat: D3DMATERIAL7 structure to write the material parameters to
5468 * Returns:
5469 * D3D_OK on success
5470 * DDERR_INVALIDPARAMS if Mat is NULL
5471 * For more details, see IWineD3DDevice::GetMaterial
5473 *****************************************************************************/
5474 static HRESULT
5475 IDirect3DDeviceImpl_7_GetMaterial(IDirect3DDevice7 *iface,
5476 D3DMATERIAL7 *Mat)
5478 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5479 HRESULT hr;
5480 TRACE("(%p)->(%p): Relay!\n", This, Mat);
5482 EnterCriticalSection(&ddraw_cs);
5483 /* Note: D3DMATERIAL7 is compatible with WINED3DMATERIAL */
5484 hr = IWineD3DDevice_GetMaterial(This->wineD3DDevice,
5485 (WINED3DMATERIAL*) Mat);
5486 LeaveCriticalSection(&ddraw_cs);
5487 return hr_ddraw_from_wined3d(hr);
5490 static HRESULT WINAPI
5491 IDirect3DDeviceImpl_7_GetMaterial_FPUSetup(IDirect3DDevice7 *iface,
5492 D3DMATERIAL7 *Mat)
5494 return IDirect3DDeviceImpl_7_GetMaterial(iface, Mat);
5497 static HRESULT WINAPI
5498 IDirect3DDeviceImpl_7_GetMaterial_FPUPreserve(IDirect3DDevice7 *iface,
5499 D3DMATERIAL7 *Mat)
5501 HRESULT hr;
5502 WORD old_fpucw;
5504 old_fpucw = d3d_fpu_setup();
5505 hr = IDirect3DDeviceImpl_7_GetMaterial(iface, Mat);
5506 set_fpu_control_word(old_fpucw);
5508 return hr;
5511 /*****************************************************************************
5512 * IDirect3DDevice7::SetLight
5514 * Assigns a light to a light index, but doesn't activate it yet.
5516 * Version 7, IDirect3DLight uses this method for older versions
5518 * Params:
5519 * LightIndex: The index of the new light
5520 * Light: A D3DLIGHT7 structure describing the light
5522 * Returns:
5523 * D3D_OK on success
5524 * For more details, see IWineD3DDevice::SetLight
5526 *****************************************************************************/
5527 static HRESULT
5528 IDirect3DDeviceImpl_7_SetLight(IDirect3DDevice7 *iface,
5529 DWORD LightIndex,
5530 D3DLIGHT7 *Light)
5532 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5533 HRESULT hr;
5534 TRACE("(%p)->(%08x,%p): Relay!\n", This, LightIndex, Light);
5536 EnterCriticalSection(&ddraw_cs);
5537 /* Note: D3DLIGHT7 is compatible with WINED3DLIGHT */
5538 hr = IWineD3DDevice_SetLight(This->wineD3DDevice,
5539 LightIndex,
5540 (WINED3DLIGHT*) Light);
5541 LeaveCriticalSection(&ddraw_cs);
5542 return hr_ddraw_from_wined3d(hr);
5545 static HRESULT WINAPI
5546 IDirect3DDeviceImpl_7_SetLight_FPUSetup(IDirect3DDevice7 *iface,
5547 DWORD LightIndex,
5548 D3DLIGHT7 *Light)
5550 return IDirect3DDeviceImpl_7_SetLight(iface, LightIndex, Light);
5553 static HRESULT WINAPI
5554 IDirect3DDeviceImpl_7_SetLight_FPUPreserve(IDirect3DDevice7 *iface,
5555 DWORD LightIndex,
5556 D3DLIGHT7 *Light)
5558 HRESULT hr;
5559 WORD old_fpucw;
5561 old_fpucw = d3d_fpu_setup();
5562 hr = IDirect3DDeviceImpl_7_SetLight(iface, LightIndex, Light);
5563 set_fpu_control_word(old_fpucw);
5565 return hr;
5568 /*****************************************************************************
5569 * IDirect3DDevice7::GetLight
5571 * Returns the light assigned to a light index
5573 * Params:
5574 * Light: Structure to write the light information to
5576 * Returns:
5577 * D3D_OK on success
5578 * DDERR_INVALIDPARAMS if Light is NULL
5579 * For details, see IWineD3DDevice::GetLight
5581 *****************************************************************************/
5582 static HRESULT
5583 IDirect3DDeviceImpl_7_GetLight(IDirect3DDevice7 *iface,
5584 DWORD LightIndex,
5585 D3DLIGHT7 *Light)
5587 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5588 HRESULT rc;
5589 TRACE("(%p)->(%08x,%p): Relay!\n", This, LightIndex, Light);
5591 EnterCriticalSection(&ddraw_cs);
5592 /* Note: D3DLIGHT7 is compatible with WINED3DLIGHT */
5593 rc = IWineD3DDevice_GetLight(This->wineD3DDevice,
5594 LightIndex,
5595 (WINED3DLIGHT*) Light);
5597 /* Translate the result. WineD3D returns other values than D3D7 */
5598 LeaveCriticalSection(&ddraw_cs);
5599 return hr_ddraw_from_wined3d(rc);
5602 static HRESULT WINAPI
5603 IDirect3DDeviceImpl_7_GetLight_FPUSetup(IDirect3DDevice7 *iface,
5604 DWORD LightIndex,
5605 D3DLIGHT7 *Light)
5607 return IDirect3DDeviceImpl_7_GetLight(iface, LightIndex, Light);
5610 static HRESULT WINAPI
5611 IDirect3DDeviceImpl_7_GetLight_FPUPreserve(IDirect3DDevice7 *iface,
5612 DWORD LightIndex,
5613 D3DLIGHT7 *Light)
5615 HRESULT hr;
5616 WORD old_fpucw;
5618 old_fpucw = d3d_fpu_setup();
5619 hr = IDirect3DDeviceImpl_7_GetLight(iface, LightIndex, Light);
5620 set_fpu_control_word(old_fpucw);
5622 return hr;
5625 /*****************************************************************************
5626 * IDirect3DDevice7::BeginStateBlock
5628 * Begins recording to a stateblock
5630 * Version 7
5632 * Returns:
5633 * D3D_OK on success
5634 * For details see IWineD3DDevice::BeginStateBlock
5636 *****************************************************************************/
5637 static HRESULT
5638 IDirect3DDeviceImpl_7_BeginStateBlock(IDirect3DDevice7 *iface)
5640 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5641 HRESULT hr;
5642 TRACE("(%p)->(): Relay!\n", This);
5644 EnterCriticalSection(&ddraw_cs);
5645 hr = IWineD3DDevice_BeginStateBlock(This->wineD3DDevice);
5646 LeaveCriticalSection(&ddraw_cs);
5647 return hr_ddraw_from_wined3d(hr);
5650 static HRESULT WINAPI
5651 IDirect3DDeviceImpl_7_BeginStateBlock_FPUSetup(IDirect3DDevice7 *iface)
5653 return IDirect3DDeviceImpl_7_BeginStateBlock(iface);
5656 static HRESULT WINAPI
5657 IDirect3DDeviceImpl_7_BeginStateBlock_FPUPreserve(IDirect3DDevice7 *iface)
5659 HRESULT hr;
5660 WORD old_fpucw;
5662 old_fpucw = d3d_fpu_setup();
5663 hr = IDirect3DDeviceImpl_7_BeginStateBlock(iface);
5664 set_fpu_control_word(old_fpucw);
5666 return hr;
5669 /*****************************************************************************
5670 * IDirect3DDevice7::EndStateBlock
5672 * Stops recording to a state block and returns the created stateblock
5673 * handle.
5675 * Version 7
5677 * Params:
5678 * BlockHandle: Address to store the stateblock's handle to
5680 * Returns:
5681 * D3D_OK on success
5682 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5683 * See IWineD3DDevice::EndStateBlock for more details
5685 *****************************************************************************/
5686 static HRESULT
5687 IDirect3DDeviceImpl_7_EndStateBlock(IDirect3DDevice7 *iface,
5688 DWORD *BlockHandle)
5690 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5691 HRESULT hr;
5692 TRACE("(%p)->(%p): Relay!\n", This, BlockHandle);
5694 if(!BlockHandle)
5696 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
5697 return DDERR_INVALIDPARAMS;
5700 EnterCriticalSection(&ddraw_cs);
5701 *BlockHandle = IDirect3DDeviceImpl_CreateHandle(This);
5702 if(!*BlockHandle)
5704 ERR("Cannot get a handle number for the stateblock\n");
5705 LeaveCriticalSection(&ddraw_cs);
5706 return DDERR_OUTOFMEMORY;
5708 This->Handles[*BlockHandle - 1].type = DDrawHandle_StateBlock;
5709 hr = IWineD3DDevice_EndStateBlock(This->wineD3DDevice,
5710 (IWineD3DStateBlock **) &This->Handles[*BlockHandle - 1].ptr);
5711 LeaveCriticalSection(&ddraw_cs);
5712 return hr_ddraw_from_wined3d(hr);
5715 static HRESULT WINAPI
5716 IDirect3DDeviceImpl_7_EndStateBlock_FPUSetup(IDirect3DDevice7 *iface,
5717 DWORD *BlockHandle)
5719 return IDirect3DDeviceImpl_7_EndStateBlock(iface, BlockHandle);
5722 static HRESULT WINAPI
5723 IDirect3DDeviceImpl_7_EndStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
5724 DWORD *BlockHandle)
5726 HRESULT hr;
5727 WORD old_fpucw;
5729 old_fpucw = d3d_fpu_setup();
5730 hr = IDirect3DDeviceImpl_7_EndStateBlock(iface, BlockHandle);
5731 set_fpu_control_word(old_fpucw);
5733 return hr;
5736 /*****************************************************************************
5737 * IDirect3DDevice7::PreLoad
5739 * Allows the app to signal that a texture will be used soon, to allow
5740 * the Direct3DDevice to load it to the video card in the meantime.
5742 * Version 7
5744 * Params:
5745 * Texture: The texture to preload
5747 * Returns:
5748 * D3D_OK on success
5749 * DDERR_INVALIDPARAMS if Texture is NULL
5750 * See IWineD3DSurface::PreLoad for details
5752 *****************************************************************************/
5753 static HRESULT
5754 IDirect3DDeviceImpl_7_PreLoad(IDirect3DDevice7 *iface,
5755 IDirectDrawSurface7 *Texture)
5757 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5758 IDirectDrawSurfaceImpl *surf = (IDirectDrawSurfaceImpl *)Texture;
5760 TRACE("(%p)->(%p): Relay!\n", This, surf);
5762 if(!Texture)
5763 return DDERR_INVALIDPARAMS;
5765 EnterCriticalSection(&ddraw_cs);
5766 IWineD3DSurface_PreLoad(surf->WineD3DSurface);
5767 LeaveCriticalSection(&ddraw_cs);
5768 return D3D_OK;
5771 static HRESULT WINAPI
5772 IDirect3DDeviceImpl_7_PreLoad_FPUSetup(IDirect3DDevice7 *iface,
5773 IDirectDrawSurface7 *Texture)
5775 return IDirect3DDeviceImpl_7_PreLoad(iface, Texture);
5778 static HRESULT WINAPI
5779 IDirect3DDeviceImpl_7_PreLoad_FPUPreserve(IDirect3DDevice7 *iface,
5780 IDirectDrawSurface7 *Texture)
5782 HRESULT hr;
5783 WORD old_fpucw;
5785 old_fpucw = d3d_fpu_setup();
5786 hr = IDirect3DDeviceImpl_7_PreLoad(iface, Texture);
5787 set_fpu_control_word(old_fpucw);
5789 return hr;
5792 /*****************************************************************************
5793 * IDirect3DDevice7::ApplyStateBlock
5795 * Activates the state stored in a state block handle.
5797 * Params:
5798 * BlockHandle: The stateblock handle to activate
5800 * Returns:
5801 * D3D_OK on success
5802 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5804 *****************************************************************************/
5805 static HRESULT
5806 IDirect3DDeviceImpl_7_ApplyStateBlock(IDirect3DDevice7 *iface,
5807 DWORD BlockHandle)
5809 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5810 HRESULT hr;
5811 TRACE("(%p)->(%08x): Relay!\n", This, BlockHandle);
5813 EnterCriticalSection(&ddraw_cs);
5814 if(!BlockHandle || BlockHandle > This->numHandles)
5816 WARN("Out of range handle %d, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5817 LeaveCriticalSection(&ddraw_cs);
5818 return D3DERR_INVALIDSTATEBLOCK;
5820 if(This->Handles[BlockHandle - 1].type != DDrawHandle_StateBlock)
5822 WARN("Handle %d is not a stateblock, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5823 LeaveCriticalSection(&ddraw_cs);
5824 return D3DERR_INVALIDSTATEBLOCK;
5827 hr = IWineD3DStateBlock_Apply((IWineD3DStateBlock *) This->Handles[BlockHandle - 1].ptr);
5828 LeaveCriticalSection(&ddraw_cs);
5829 return hr_ddraw_from_wined3d(hr);
5832 static HRESULT WINAPI
5833 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUSetup(IDirect3DDevice7 *iface,
5834 DWORD BlockHandle)
5836 return IDirect3DDeviceImpl_7_ApplyStateBlock(iface, BlockHandle);
5839 static HRESULT WINAPI
5840 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
5841 DWORD BlockHandle)
5843 HRESULT hr;
5844 WORD old_fpucw;
5846 old_fpucw = d3d_fpu_setup();
5847 hr = IDirect3DDeviceImpl_7_ApplyStateBlock(iface, BlockHandle);
5848 set_fpu_control_word(old_fpucw);
5850 return hr;
5853 /*****************************************************************************
5854 * IDirect3DDevice7::CaptureStateBlock
5856 * Updates a stateblock's values to the values currently set for the device
5858 * Version 7
5860 * Params:
5861 * BlockHandle: Stateblock to update
5863 * Returns:
5864 * D3D_OK on success
5865 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5866 * See IWineD3DDevice::CaptureStateBlock for more details
5868 *****************************************************************************/
5869 static HRESULT
5870 IDirect3DDeviceImpl_7_CaptureStateBlock(IDirect3DDevice7 *iface,
5871 DWORD BlockHandle)
5873 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5874 HRESULT hr;
5875 TRACE("(%p)->(%08x): Relay!\n", This, BlockHandle);
5877 EnterCriticalSection(&ddraw_cs);
5878 if(BlockHandle == 0 || BlockHandle > This->numHandles)
5880 WARN("Out of range handle %d, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5881 LeaveCriticalSection(&ddraw_cs);
5882 return D3DERR_INVALIDSTATEBLOCK;
5884 if(This->Handles[BlockHandle - 1].type != DDrawHandle_StateBlock)
5886 WARN("Handle %d is not a stateblock, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5887 LeaveCriticalSection(&ddraw_cs);
5888 return D3DERR_INVALIDSTATEBLOCK;
5891 hr = IWineD3DStateBlock_Capture((IWineD3DStateBlock *) This->Handles[BlockHandle - 1].ptr);
5892 LeaveCriticalSection(&ddraw_cs);
5893 return hr_ddraw_from_wined3d(hr);
5896 static HRESULT WINAPI
5897 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUSetup(IDirect3DDevice7 *iface,
5898 DWORD BlockHandle)
5900 return IDirect3DDeviceImpl_7_CaptureStateBlock(iface, BlockHandle);
5903 static HRESULT WINAPI
5904 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
5905 DWORD BlockHandle)
5907 HRESULT hr;
5908 WORD old_fpucw;
5910 old_fpucw = d3d_fpu_setup();
5911 hr = IDirect3DDeviceImpl_7_CaptureStateBlock(iface, BlockHandle);
5912 set_fpu_control_word(old_fpucw);
5914 return hr;
5917 /*****************************************************************************
5918 * IDirect3DDevice7::DeleteStateBlock
5920 * Deletes a stateblock handle. This means releasing the WineD3DStateBlock
5922 * Version 7
5924 * Params:
5925 * BlockHandle: Stateblock handle to delete
5927 * Returns:
5928 * D3D_OK on success
5929 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is 0
5931 *****************************************************************************/
5932 static HRESULT
5933 IDirect3DDeviceImpl_7_DeleteStateBlock(IDirect3DDevice7 *iface,
5934 DWORD BlockHandle)
5936 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5937 ULONG ref;
5938 TRACE("(%p)->(%08x): Relay!\n", This, BlockHandle);
5940 EnterCriticalSection(&ddraw_cs);
5941 if(BlockHandle == 0 || BlockHandle > This->numHandles)
5943 WARN("Out of range handle %d, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5944 LeaveCriticalSection(&ddraw_cs);
5945 return D3DERR_INVALIDSTATEBLOCK;
5947 if(This->Handles[BlockHandle - 1].type != DDrawHandle_StateBlock)
5949 WARN("Handle %d is not a stateblock, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5950 LeaveCriticalSection(&ddraw_cs);
5951 return D3DERR_INVALIDSTATEBLOCK;
5954 ref = IWineD3DStateBlock_Release((IWineD3DStateBlock *) This->Handles[BlockHandle - 1].ptr);
5955 if(ref)
5957 ERR("Something is still holding the stateblock %p(Handle %d). Ref = %d\n", This->Handles[BlockHandle - 1].ptr, BlockHandle, ref);
5959 This->Handles[BlockHandle - 1].ptr = NULL;
5960 This->Handles[BlockHandle - 1].type = DDrawHandle_Unknown;
5962 LeaveCriticalSection(&ddraw_cs);
5963 return D3D_OK;
5966 static HRESULT WINAPI
5967 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUSetup(IDirect3DDevice7 *iface,
5968 DWORD BlockHandle)
5970 return IDirect3DDeviceImpl_7_DeleteStateBlock(iface, BlockHandle);
5973 static HRESULT WINAPI
5974 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
5975 DWORD BlockHandle)
5977 HRESULT hr;
5978 WORD old_fpucw;
5980 old_fpucw = d3d_fpu_setup();
5981 hr = IDirect3DDeviceImpl_7_DeleteStateBlock(iface, BlockHandle);
5982 set_fpu_control_word(old_fpucw);
5984 return hr;
5987 /*****************************************************************************
5988 * IDirect3DDevice7::CreateStateBlock
5990 * Creates a new state block handle.
5992 * Version 7
5994 * Params:
5995 * Type: The state block type
5996 * BlockHandle: Address to write the created handle to
5998 * Returns:
5999 * D3D_OK on success
6000 * DDERR_INVALIDPARAMS if BlockHandle is NULL
6002 *****************************************************************************/
6003 static HRESULT
6004 IDirect3DDeviceImpl_7_CreateStateBlock(IDirect3DDevice7 *iface,
6005 D3DSTATEBLOCKTYPE Type,
6006 DWORD *BlockHandle)
6008 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
6009 HRESULT hr;
6010 TRACE("(%p)->(%08x,%p)!\n", This, Type, BlockHandle);
6012 if(!BlockHandle)
6014 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
6015 return DDERR_INVALIDPARAMS;
6017 if(Type != D3DSBT_ALL && Type != D3DSBT_PIXELSTATE &&
6018 Type != D3DSBT_VERTEXSTATE ) {
6019 WARN("Unexpected stateblock type, returning DDERR_INVALIDPARAMS\n");
6020 return DDERR_INVALIDPARAMS;
6023 EnterCriticalSection(&ddraw_cs);
6024 *BlockHandle = IDirect3DDeviceImpl_CreateHandle(This);
6025 if(!*BlockHandle)
6027 ERR("Cannot get a handle number for the stateblock\n");
6028 LeaveCriticalSection(&ddraw_cs);
6029 return DDERR_OUTOFMEMORY;
6031 This->Handles[*BlockHandle - 1].type = DDrawHandle_StateBlock;
6033 /* The D3DSTATEBLOCKTYPE enum is fine here */
6034 hr = IWineD3DDevice_CreateStateBlock(This->wineD3DDevice,
6035 Type,
6036 (IWineD3DStateBlock **) &This->Handles[*BlockHandle - 1].ptr,
6037 NULL /* Parent, hope that works */);
6038 LeaveCriticalSection(&ddraw_cs);
6039 return hr_ddraw_from_wined3d(hr);
6042 static HRESULT WINAPI
6043 IDirect3DDeviceImpl_7_CreateStateBlock_FPUSetup(IDirect3DDevice7 *iface,
6044 D3DSTATEBLOCKTYPE Type,
6045 DWORD *BlockHandle)
6047 return IDirect3DDeviceImpl_7_CreateStateBlock(iface, Type, BlockHandle);
6050 static HRESULT WINAPI
6051 IDirect3DDeviceImpl_7_CreateStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
6052 D3DSTATEBLOCKTYPE Type,
6053 DWORD *BlockHandle)
6055 HRESULT hr;
6056 WORD old_fpucw;
6058 old_fpucw = d3d_fpu_setup();
6059 hr =IDirect3DDeviceImpl_7_CreateStateBlock(iface, Type, BlockHandle);
6060 set_fpu_control_word(old_fpucw);
6062 return hr;
6065 /* Helper function for IDirect3DDeviceImpl_7_Load. */
6066 static BOOL is_mip_level_subset(IDirectDrawSurfaceImpl *dest,
6067 IDirectDrawSurfaceImpl *src)
6069 IDirectDrawSurfaceImpl *src_level, *dest_level;
6070 IDirectDrawSurface7 *temp;
6071 DDSURFACEDESC2 ddsd;
6072 BOOL levelFound; /* at least one suitable sublevel in dest found */
6074 /* To satisfy "destination is mip level subset of source" criteria (regular texture counts as 1 level),
6075 * 1) there must be at least one mip level in destination that matched dimensions of some mip level in source and
6076 * 2) there must be no destination levels that don't match any levels in source. Otherwise it's INVALIDPARAMS.
6078 levelFound = FALSE;
6080 src_level = src;
6081 dest_level = dest;
6083 for (;src_level && dest_level;)
6085 if (src_level->surface_desc.dwWidth == dest_level->surface_desc.dwWidth &&
6086 src_level->surface_desc.dwHeight == dest_level->surface_desc.dwHeight)
6088 levelFound = TRUE;
6090 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6091 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
6092 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7 *)dest_level, &ddsd.ddsCaps, &temp);
6094 if (dest_level != dest) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)dest_level);
6096 dest_level = (IDirectDrawSurfaceImpl *)temp;
6099 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6100 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
6101 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7 *)src_level, &ddsd.ddsCaps, &temp);
6103 if (src_level != src) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)src_level);
6105 src_level = (IDirectDrawSurfaceImpl *)temp;
6108 if (src_level && src_level != src) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)src_level);
6109 if (dest_level && dest_level != dest) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)dest_level);
6111 return !dest_level && levelFound;
6114 /* Helper function for IDirect3DDeviceImpl_7_Load. */
6115 static void copy_mipmap_chain(IDirect3DDeviceImpl *device,
6116 IDirectDrawSurfaceImpl *dest,
6117 IDirectDrawSurfaceImpl *src,
6118 POINT *DestPoint,
6119 RECT *SrcRect)
6121 IDirectDrawSurfaceImpl *src_level, *dest_level;
6122 IDirectDrawSurface7 *temp;
6123 DDSURFACEDESC2 ddsd;
6124 POINT point;
6125 RECT rect;
6126 HRESULT hr;
6127 IDirectDrawPalette *pal = NULL, *pal_src = NULL;
6128 DWORD ckeyflag;
6129 DDCOLORKEY ddckey;
6130 BOOL palette_missing = FALSE;
6132 /* Copy palette, if possible. */
6133 IDirectDrawSurface7_GetPalette((IDirectDrawSurface7 *)src, &pal_src);
6134 IDirectDrawSurface7_GetPalette((IDirectDrawSurface7 *)dest, &pal);
6136 if (pal_src != NULL && pal != NULL)
6138 PALETTEENTRY palent[256];
6140 IDirectDrawPalette_GetEntries(pal_src, 0, 0, 256, palent);
6141 IDirectDrawPalette_SetEntries(pal, 0, 0, 256, palent);
6144 if (dest->surface_desc.u4.ddpfPixelFormat.dwFlags & (DDPF_PALETTEINDEXED1 | DDPF_PALETTEINDEXED2 |
6145 DDPF_PALETTEINDEXED4 | DDPF_PALETTEINDEXED8 | DDPF_PALETTEINDEXEDTO8) && !pal)
6147 palette_missing = TRUE;
6150 if (pal) IDirectDrawPalette_Release(pal);
6151 if (pal_src) IDirectDrawPalette_Release(pal_src);
6153 /* Copy colorkeys, if present. */
6154 for (ckeyflag = DDCKEY_DESTBLT; ckeyflag <= DDCKEY_SRCOVERLAY; ckeyflag <<= 1)
6156 hr = IDirectDrawSurface7_GetColorKey((IDirectDrawSurface7 *)src, ckeyflag, &ddckey);
6158 if (SUCCEEDED(hr))
6160 IDirectDrawSurface7_SetColorKey((IDirectDrawSurface7 *)dest, ckeyflag, &ddckey);
6164 src_level = src;
6165 dest_level = dest;
6167 point = *DestPoint;
6168 rect = *SrcRect;
6170 for (;src_level && dest_level;)
6172 if (src_level->surface_desc.dwWidth == dest_level->surface_desc.dwWidth &&
6173 src_level->surface_desc.dwHeight == dest_level->surface_desc.dwHeight)
6175 /* Try UpdateSurface that may perform a more direct opengl loading. But skip this if destination is paletted texture and has no palette.
6176 * Some games like Sacrifice set palette after Load, and it is a waste of effort to try to load texture without palette and generates
6177 * warnings in wined3d. */
6178 if (!palette_missing)
6179 hr = IWineD3DDevice_UpdateSurface(device->wineD3DDevice, src_level->WineD3DSurface, &rect, dest_level->WineD3DSurface,
6180 &point);
6182 if (palette_missing || FAILED(hr))
6184 /* UpdateSurface may fail e.g. if dest is in system memory. Fall back to BltFast that is less strict. */
6185 IWineD3DSurface_BltFast(dest_level->WineD3DSurface,
6186 point.x, point.y,
6187 src_level->WineD3DSurface, &rect, 0);
6190 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6191 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
6192 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7 *)dest_level, &ddsd.ddsCaps, &temp);
6194 if (dest_level != dest) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)dest_level);
6196 dest_level = (IDirectDrawSurfaceImpl *)temp;
6199 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6200 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
6201 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7 *)src_level, &ddsd.ddsCaps, &temp);
6203 if (src_level != src) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)src_level);
6205 src_level = (IDirectDrawSurfaceImpl *)temp;
6207 point.x /= 2;
6208 point.y /= 2;
6210 rect.top /= 2;
6211 rect.left /= 2;
6212 rect.right = (rect.right + 1) / 2;
6213 rect.bottom = (rect.bottom + 1) / 2;
6216 if (src_level && src_level != src) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)src_level);
6217 if (dest_level && dest_level != dest) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)dest_level);
6220 /*****************************************************************************
6221 * IDirect3DDevice7::Load
6223 * Loads a rectangular area from the source into the destination texture.
6224 * It can also copy the source to the faces of a cubic environment map
6226 * Version 7
6228 * Params:
6229 * DestTex: Destination texture
6230 * DestPoint: Point in the destination where the source image should be
6231 * written to
6232 * SrcTex: Source texture
6233 * SrcRect: Source rectangle
6234 * Flags: Cubemap faces to load (DDSCAPS2_CUBEMAP_ALLFACES, DDSCAPS2_CUBEMAP_POSITIVEX,
6235 * DDSCAPS2_CUBEMAP_NEGATIVEX, DDSCAPS2_CUBEMAP_POSITIVEY, DDSCAPS2_CUBEMAP_NEGATIVEY,
6236 * DDSCAPS2_CUBEMAP_POSITIVEZ, DDSCAPS2_CUBEMAP_NEGATIVEZ)
6238 * Returns:
6239 * D3D_OK on success
6240 * DDERR_INVALIDPARAMS if DestTex or SrcTex are NULL, broken coordinates or anything unexpected.
6243 *****************************************************************************/
6245 static HRESULT
6246 IDirect3DDeviceImpl_7_Load(IDirect3DDevice7 *iface,
6247 IDirectDrawSurface7 *DestTex,
6248 POINT *DestPoint,
6249 IDirectDrawSurface7 *SrcTex,
6250 RECT *SrcRect,
6251 DWORD Flags)
6253 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
6254 IDirectDrawSurfaceImpl *dest = (IDirectDrawSurfaceImpl *)DestTex;
6255 IDirectDrawSurfaceImpl *src = (IDirectDrawSurfaceImpl *)SrcTex;
6256 POINT destpoint;
6257 RECT srcrect;
6258 TRACE("(%p)->(%p,%p,%p,%p,%08x)\n", This, dest, DestPoint, src, SrcRect, Flags);
6260 if( (!src) || (!dest) )
6261 return DDERR_INVALIDPARAMS;
6263 EnterCriticalSection(&ddraw_cs);
6265 if (SrcRect) srcrect = *SrcRect;
6266 else
6268 srcrect.left = srcrect.top = 0;
6269 srcrect.right = src->surface_desc.dwWidth;
6270 srcrect.bottom = src->surface_desc.dwHeight;
6273 if (DestPoint) destpoint = *DestPoint;
6274 else
6276 destpoint.x = destpoint.y = 0;
6278 /* Check bad dimensions. DestPoint is validated against src, not dest, because
6279 * destination can be a subset of mip levels, in which case actual coordinates used
6280 * for it may be divided. If any dimension of dest is larger than source, it can't be
6281 * mip level subset, so an error can be returned early.
6283 if (srcrect.left >= srcrect.right || srcrect.top >= srcrect.bottom ||
6284 srcrect.right > src->surface_desc.dwWidth ||
6285 srcrect.bottom > src->surface_desc.dwHeight ||
6286 destpoint.x + srcrect.right - srcrect.left > src->surface_desc.dwWidth ||
6287 destpoint.y + srcrect.bottom - srcrect.top > src->surface_desc.dwHeight ||
6288 dest->surface_desc.dwWidth > src->surface_desc.dwWidth ||
6289 dest->surface_desc.dwHeight > src->surface_desc.dwHeight)
6291 LeaveCriticalSection(&ddraw_cs);
6292 return DDERR_INVALIDPARAMS;
6295 /* Must be top level surfaces. */
6296 if (src->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_MIPMAPSUBLEVEL ||
6297 dest->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_MIPMAPSUBLEVEL)
6299 LeaveCriticalSection(&ddraw_cs);
6300 return DDERR_INVALIDPARAMS;
6303 if (src->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP)
6305 DWORD src_face_flag, dest_face_flag;
6306 IDirectDrawSurfaceImpl *src_face, *dest_face;
6307 IDirectDrawSurface7 *temp;
6308 DDSURFACEDESC2 ddsd;
6309 int i;
6311 if (!(dest->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP))
6313 LeaveCriticalSection(&ddraw_cs);
6314 return DDERR_INVALIDPARAMS;
6317 /* Iterate through cube faces 2 times. First time is just to check INVALIDPARAMS conditions, second
6318 * time it's actual surface loading. */
6319 for (i = 0; i < 2; i++)
6321 dest_face = dest;
6322 src_face = src;
6324 for (;dest_face && src_face;)
6326 src_face_flag = src_face->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP_ALLFACES;
6327 dest_face_flag = dest_face->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP_ALLFACES;
6329 if (src_face_flag == dest_face_flag)
6331 if (i == 0)
6333 /* Destination mip levels must be subset of source mip levels. */
6334 if (!is_mip_level_subset(dest_face, src_face))
6336 LeaveCriticalSection(&ddraw_cs);
6337 return DDERR_INVALIDPARAMS;
6340 else if (Flags & dest_face_flag)
6342 copy_mipmap_chain(This, dest_face, src_face, &destpoint, &srcrect);
6345 if (src_face_flag < DDSCAPS2_CUBEMAP_NEGATIVEZ)
6347 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6348 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | (src_face_flag << 1);
6349 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7 *)src, &ddsd.ddsCaps, &temp);
6351 if (src_face != src) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)src_face);
6353 src_face = (IDirectDrawSurfaceImpl *)temp;
6355 else
6357 if (src_face != src) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)src_face);
6359 src_face = NULL;
6363 if (dest_face_flag < DDSCAPS2_CUBEMAP_NEGATIVEZ)
6365 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6366 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | (dest_face_flag << 1);
6367 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7 *)dest, &ddsd.ddsCaps, &temp);
6369 if (dest_face != dest) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)dest_face);
6371 dest_face = (IDirectDrawSurfaceImpl *)temp;
6373 else
6375 if (dest_face != dest) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)dest_face);
6377 dest_face = NULL;
6381 if (i == 0)
6383 /* Native returns error if src faces are not subset of dest faces. */
6384 if (src_face)
6386 LeaveCriticalSection(&ddraw_cs);
6387 return DDERR_INVALIDPARAMS;
6392 LeaveCriticalSection(&ddraw_cs);
6393 return D3D_OK;
6395 else if (dest->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP)
6397 LeaveCriticalSection(&ddraw_cs);
6398 return DDERR_INVALIDPARAMS;
6401 /* Handle non cube map textures. */
6403 /* Destination mip levels must be subset of source mip levels. */
6404 if (!is_mip_level_subset(dest, src))
6406 LeaveCriticalSection(&ddraw_cs);
6407 return DDERR_INVALIDPARAMS;
6410 copy_mipmap_chain(This, dest, src, &destpoint, &srcrect);
6412 LeaveCriticalSection(&ddraw_cs);
6413 return D3D_OK;
6416 static HRESULT WINAPI
6417 IDirect3DDeviceImpl_7_Load_FPUSetup(IDirect3DDevice7 *iface,
6418 IDirectDrawSurface7 *DestTex,
6419 POINT *DestPoint,
6420 IDirectDrawSurface7 *SrcTex,
6421 RECT *SrcRect,
6422 DWORD Flags)
6424 return IDirect3DDeviceImpl_7_Load(iface, DestTex, DestPoint, SrcTex, SrcRect, Flags);
6427 static HRESULT WINAPI
6428 IDirect3DDeviceImpl_7_Load_FPUPreserve(IDirect3DDevice7 *iface,
6429 IDirectDrawSurface7 *DestTex,
6430 POINT *DestPoint,
6431 IDirectDrawSurface7 *SrcTex,
6432 RECT *SrcRect,
6433 DWORD Flags)
6435 HRESULT hr;
6436 WORD old_fpucw;
6438 old_fpucw = d3d_fpu_setup();
6439 hr = IDirect3DDeviceImpl_7_Load(iface, DestTex, DestPoint, SrcTex, SrcRect, Flags);
6440 set_fpu_control_word(old_fpucw);
6442 return hr;
6445 /*****************************************************************************
6446 * IDirect3DDevice7::LightEnable
6448 * Enables or disables a light
6450 * Version 7, IDirect3DLight uses this method too.
6452 * Params:
6453 * LightIndex: The index of the light to enable / disable
6454 * Enable: Enable or disable the light
6456 * Returns:
6457 * D3D_OK on success
6458 * For more details, see IWineD3DDevice::SetLightEnable
6460 *****************************************************************************/
6461 static HRESULT
6462 IDirect3DDeviceImpl_7_LightEnable(IDirect3DDevice7 *iface,
6463 DWORD LightIndex,
6464 BOOL Enable)
6466 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
6467 HRESULT hr;
6468 TRACE("(%p)->(%08x,%d): Relay!\n", This, LightIndex, Enable);
6470 EnterCriticalSection(&ddraw_cs);
6471 hr = IWineD3DDevice_SetLightEnable(This->wineD3DDevice, LightIndex, Enable);
6472 LeaveCriticalSection(&ddraw_cs);
6473 return hr_ddraw_from_wined3d(hr);
6476 static HRESULT WINAPI
6477 IDirect3DDeviceImpl_7_LightEnable_FPUSetup(IDirect3DDevice7 *iface,
6478 DWORD LightIndex,
6479 BOOL Enable)
6481 return IDirect3DDeviceImpl_7_LightEnable(iface, LightIndex, Enable);
6484 static HRESULT WINAPI
6485 IDirect3DDeviceImpl_7_LightEnable_FPUPreserve(IDirect3DDevice7 *iface,
6486 DWORD LightIndex,
6487 BOOL Enable)
6489 HRESULT hr;
6490 WORD old_fpucw;
6492 old_fpucw = d3d_fpu_setup();
6493 hr = IDirect3DDeviceImpl_7_LightEnable(iface, LightIndex, Enable);
6494 set_fpu_control_word(old_fpucw);
6496 return hr;
6499 /*****************************************************************************
6500 * IDirect3DDevice7::GetLightEnable
6502 * Retrieves if the light with the given index is enabled or not
6504 * Version 7
6506 * Params:
6507 * LightIndex: Index of desired light
6508 * Enable: Pointer to a BOOL which contains the result
6510 * Returns:
6511 * D3D_OK on success
6512 * DDERR_INVALIDPARAMS if Enable is NULL
6513 * See IWineD3DDevice::GetLightEnable for more details
6515 *****************************************************************************/
6516 static HRESULT
6517 IDirect3DDeviceImpl_7_GetLightEnable(IDirect3DDevice7 *iface,
6518 DWORD LightIndex,
6519 BOOL* Enable)
6521 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
6522 HRESULT hr;
6523 TRACE("(%p)->(%08x,%p): Relay\n", This, LightIndex, Enable);
6525 if(!Enable)
6526 return DDERR_INVALIDPARAMS;
6528 EnterCriticalSection(&ddraw_cs);
6529 hr = IWineD3DDevice_GetLightEnable(This->wineD3DDevice, LightIndex, Enable);
6530 LeaveCriticalSection(&ddraw_cs);
6531 return hr_ddraw_from_wined3d(hr);
6534 static HRESULT WINAPI
6535 IDirect3DDeviceImpl_7_GetLightEnable_FPUSetup(IDirect3DDevice7 *iface,
6536 DWORD LightIndex,
6537 BOOL* Enable)
6539 return IDirect3DDeviceImpl_7_GetLightEnable(iface, LightIndex, Enable);
6542 static HRESULT WINAPI
6543 IDirect3DDeviceImpl_7_GetLightEnable_FPUPreserve(IDirect3DDevice7 *iface,
6544 DWORD LightIndex,
6545 BOOL* Enable)
6547 HRESULT hr;
6548 WORD old_fpucw;
6550 old_fpucw = d3d_fpu_setup();
6551 hr = IDirect3DDeviceImpl_7_GetLightEnable(iface, LightIndex, Enable);
6552 set_fpu_control_word(old_fpucw);
6554 return hr;
6557 /*****************************************************************************
6558 * IDirect3DDevice7::SetClipPlane
6560 * Sets custom clipping plane
6562 * Version 7
6564 * Params:
6565 * Index: The index of the clipping plane
6566 * PlaneEquation: An equation defining the clipping plane
6568 * Returns:
6569 * D3D_OK on success
6570 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6571 * See IWineD3DDevice::SetClipPlane for more details
6573 *****************************************************************************/
6574 static HRESULT
6575 IDirect3DDeviceImpl_7_SetClipPlane(IDirect3DDevice7 *iface,
6576 DWORD Index,
6577 D3DVALUE* PlaneEquation)
6579 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
6580 HRESULT hr;
6581 TRACE("(%p)->(%08x,%p): Relay!\n", This, Index, PlaneEquation);
6583 if(!PlaneEquation)
6584 return DDERR_INVALIDPARAMS;
6586 EnterCriticalSection(&ddraw_cs);
6587 hr = IWineD3DDevice_SetClipPlane(This->wineD3DDevice, Index, PlaneEquation);
6588 LeaveCriticalSection(&ddraw_cs);
6589 return hr;
6592 static HRESULT WINAPI
6593 IDirect3DDeviceImpl_7_SetClipPlane_FPUSetup(IDirect3DDevice7 *iface,
6594 DWORD Index,
6595 D3DVALUE* PlaneEquation)
6597 return IDirect3DDeviceImpl_7_SetClipPlane(iface, Index, PlaneEquation);
6600 static HRESULT WINAPI
6601 IDirect3DDeviceImpl_7_SetClipPlane_FPUPreserve(IDirect3DDevice7 *iface,
6602 DWORD Index,
6603 D3DVALUE* PlaneEquation)
6605 HRESULT hr;
6606 WORD old_fpucw;
6608 old_fpucw = d3d_fpu_setup();
6609 hr = IDirect3DDeviceImpl_7_SetClipPlane(iface, Index, PlaneEquation);
6610 set_fpu_control_word(old_fpucw);
6612 return hr;
6615 /*****************************************************************************
6616 * IDirect3DDevice7::GetClipPlane
6618 * Returns the clipping plane with a specific index
6620 * Params:
6621 * Index: The index of the desired plane
6622 * PlaneEquation: Address to store the plane equation to
6624 * Returns:
6625 * D3D_OK on success
6626 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6627 * See IWineD3DDevice::GetClipPlane for more details
6629 *****************************************************************************/
6630 static HRESULT
6631 IDirect3DDeviceImpl_7_GetClipPlane(IDirect3DDevice7 *iface,
6632 DWORD Index,
6633 D3DVALUE* PlaneEquation)
6635 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
6636 HRESULT hr;
6637 TRACE("(%p)->(%d,%p): Relay!\n", This, Index, PlaneEquation);
6639 if(!PlaneEquation)
6640 return DDERR_INVALIDPARAMS;
6642 EnterCriticalSection(&ddraw_cs);
6643 hr = IWineD3DDevice_GetClipPlane(This->wineD3DDevice, Index, PlaneEquation);
6644 LeaveCriticalSection(&ddraw_cs);
6645 return hr;
6648 static HRESULT WINAPI
6649 IDirect3DDeviceImpl_7_GetClipPlane_FPUSetup(IDirect3DDevice7 *iface,
6650 DWORD Index,
6651 D3DVALUE* PlaneEquation)
6653 return IDirect3DDeviceImpl_7_GetClipPlane(iface, Index, PlaneEquation);
6656 static HRESULT WINAPI
6657 IDirect3DDeviceImpl_7_GetClipPlane_FPUPreserve(IDirect3DDevice7 *iface,
6658 DWORD Index,
6659 D3DVALUE* PlaneEquation)
6661 HRESULT hr;
6662 WORD old_fpucw;
6664 old_fpucw = d3d_fpu_setup();
6665 hr = IDirect3DDeviceImpl_7_GetClipPlane(iface, Index, PlaneEquation);
6666 set_fpu_control_word(old_fpucw);
6668 return hr;
6671 /*****************************************************************************
6672 * IDirect3DDevice7::GetInfo
6674 * Retrieves some information about the device. The DirectX sdk says that
6675 * this version returns S_FALSE for all retail builds of DirectX, that's what
6676 * this implementation does.
6678 * Params:
6679 * DevInfoID: Information type requested
6680 * DevInfoStruct: Pointer to a structure to store the info to
6681 * Size: Size of the structure
6683 * Returns:
6684 * S_FALSE, because it's a non-debug driver
6686 *****************************************************************************/
6687 static HRESULT WINAPI
6688 IDirect3DDeviceImpl_7_GetInfo(IDirect3DDevice7 *iface,
6689 DWORD DevInfoID,
6690 void *DevInfoStruct,
6691 DWORD Size)
6693 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
6694 TRACE("(%p)->(%08x,%p,%08x)\n", This, DevInfoID, DevInfoStruct, Size);
6696 if (TRACE_ON(d3d7))
6698 TRACE(" info requested : ");
6699 switch (DevInfoID)
6701 case D3DDEVINFOID_TEXTUREMANAGER: TRACE("D3DDEVINFOID_TEXTUREMANAGER\n"); break;
6702 case D3DDEVINFOID_D3DTEXTUREMANAGER: TRACE("D3DDEVINFOID_D3DTEXTUREMANAGER\n"); break;
6703 case D3DDEVINFOID_TEXTURING: TRACE("D3DDEVINFOID_TEXTURING\n"); break;
6704 default: ERR(" invalid flag !!!\n"); return DDERR_INVALIDPARAMS;
6708 return S_FALSE; /* According to MSDN, this is valid for a non-debug driver */
6711 /* For performance optimization, devices created in FPUSETUP and FPUPRESERVE modes
6712 * have separate vtables. Simple functions where this doesn't matter like GetDirect3D
6713 * are not duplicated.
6715 * Device created with DDSCL_FPUSETUP (d3d7 default) - device methods assume that FPU
6716 * has already been setup for optimal d3d operation.
6718 * Device created with DDSCL_FPUPRESERVE - resets and restores FPU mode when necessary in
6719 * d3d calls (FPU may be in a mode non-suitable for d3d when the app calls d3d). Required
6720 * by Sacrifice (game). */
6721 const IDirect3DDevice7Vtbl IDirect3DDevice7_FPUSetup_Vtbl =
6723 /*** IUnknown Methods ***/
6724 IDirect3DDeviceImpl_7_QueryInterface,
6725 IDirect3DDeviceImpl_7_AddRef,
6726 IDirect3DDeviceImpl_7_Release,
6727 /*** IDirect3DDevice7 ***/
6728 IDirect3DDeviceImpl_7_GetCaps_FPUSetup,
6729 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUSetup,
6730 IDirect3DDeviceImpl_7_BeginScene_FPUSetup,
6731 IDirect3DDeviceImpl_7_EndScene_FPUSetup,
6732 IDirect3DDeviceImpl_7_GetDirect3D,
6733 IDirect3DDeviceImpl_7_SetRenderTarget_FPUSetup,
6734 IDirect3DDeviceImpl_7_GetRenderTarget,
6735 IDirect3DDeviceImpl_7_Clear_FPUSetup,
6736 IDirect3DDeviceImpl_7_SetTransform_FPUSetup,
6737 IDirect3DDeviceImpl_7_GetTransform_FPUSetup,
6738 IDirect3DDeviceImpl_7_SetViewport_FPUSetup,
6739 IDirect3DDeviceImpl_7_MultiplyTransform_FPUSetup,
6740 IDirect3DDeviceImpl_7_GetViewport_FPUSetup,
6741 IDirect3DDeviceImpl_7_SetMaterial_FPUSetup,
6742 IDirect3DDeviceImpl_7_GetMaterial_FPUSetup,
6743 IDirect3DDeviceImpl_7_SetLight_FPUSetup,
6744 IDirect3DDeviceImpl_7_GetLight_FPUSetup,
6745 IDirect3DDeviceImpl_7_SetRenderState_FPUSetup,
6746 IDirect3DDeviceImpl_7_GetRenderState_FPUSetup,
6747 IDirect3DDeviceImpl_7_BeginStateBlock_FPUSetup,
6748 IDirect3DDeviceImpl_7_EndStateBlock_FPUSetup,
6749 IDirect3DDeviceImpl_7_PreLoad_FPUSetup,
6750 IDirect3DDeviceImpl_7_DrawPrimitive_FPUSetup,
6751 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUSetup,
6752 IDirect3DDeviceImpl_7_SetClipStatus,
6753 IDirect3DDeviceImpl_7_GetClipStatus,
6754 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUSetup,
6755 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUSetup,
6756 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUSetup,
6757 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUSetup,
6758 IDirect3DDeviceImpl_7_ComputeSphereVisibility,
6759 IDirect3DDeviceImpl_7_GetTexture_FPUSetup,
6760 IDirect3DDeviceImpl_7_SetTexture_FPUSetup,
6761 IDirect3DDeviceImpl_7_GetTextureStageState_FPUSetup,
6762 IDirect3DDeviceImpl_7_SetTextureStageState_FPUSetup,
6763 IDirect3DDeviceImpl_7_ValidateDevice_FPUSetup,
6764 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUSetup,
6765 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUSetup,
6766 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUSetup,
6767 IDirect3DDeviceImpl_7_CreateStateBlock_FPUSetup,
6768 IDirect3DDeviceImpl_7_Load_FPUSetup,
6769 IDirect3DDeviceImpl_7_LightEnable_FPUSetup,
6770 IDirect3DDeviceImpl_7_GetLightEnable_FPUSetup,
6771 IDirect3DDeviceImpl_7_SetClipPlane_FPUSetup,
6772 IDirect3DDeviceImpl_7_GetClipPlane_FPUSetup,
6773 IDirect3DDeviceImpl_7_GetInfo
6776 const IDirect3DDevice7Vtbl IDirect3DDevice7_FPUPreserve_Vtbl =
6778 /*** IUnknown Methods ***/
6779 IDirect3DDeviceImpl_7_QueryInterface,
6780 IDirect3DDeviceImpl_7_AddRef,
6781 IDirect3DDeviceImpl_7_Release,
6782 /*** IDirect3DDevice7 ***/
6783 IDirect3DDeviceImpl_7_GetCaps_FPUPreserve,
6784 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUPreserve,
6785 IDirect3DDeviceImpl_7_BeginScene_FPUPreserve,
6786 IDirect3DDeviceImpl_7_EndScene_FPUPreserve,
6787 IDirect3DDeviceImpl_7_GetDirect3D,
6788 IDirect3DDeviceImpl_7_SetRenderTarget_FPUPreserve,
6789 IDirect3DDeviceImpl_7_GetRenderTarget,
6790 IDirect3DDeviceImpl_7_Clear_FPUPreserve,
6791 IDirect3DDeviceImpl_7_SetTransform_FPUPreserve,
6792 IDirect3DDeviceImpl_7_GetTransform_FPUPreserve,
6793 IDirect3DDeviceImpl_7_SetViewport_FPUPreserve,
6794 IDirect3DDeviceImpl_7_MultiplyTransform_FPUPreserve,
6795 IDirect3DDeviceImpl_7_GetViewport_FPUPreserve,
6796 IDirect3DDeviceImpl_7_SetMaterial_FPUPreserve,
6797 IDirect3DDeviceImpl_7_GetMaterial_FPUPreserve,
6798 IDirect3DDeviceImpl_7_SetLight_FPUPreserve,
6799 IDirect3DDeviceImpl_7_GetLight_FPUPreserve,
6800 IDirect3DDeviceImpl_7_SetRenderState_FPUPreserve,
6801 IDirect3DDeviceImpl_7_GetRenderState_FPUPreserve,
6802 IDirect3DDeviceImpl_7_BeginStateBlock_FPUPreserve,
6803 IDirect3DDeviceImpl_7_EndStateBlock_FPUPreserve,
6804 IDirect3DDeviceImpl_7_PreLoad_FPUPreserve,
6805 IDirect3DDeviceImpl_7_DrawPrimitive_FPUPreserve,
6806 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUPreserve,
6807 IDirect3DDeviceImpl_7_SetClipStatus,
6808 IDirect3DDeviceImpl_7_GetClipStatus,
6809 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUPreserve,
6810 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUPreserve,
6811 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUPreserve,
6812 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUPreserve,
6813 IDirect3DDeviceImpl_7_ComputeSphereVisibility,
6814 IDirect3DDeviceImpl_7_GetTexture_FPUPreserve,
6815 IDirect3DDeviceImpl_7_SetTexture_FPUPreserve,
6816 IDirect3DDeviceImpl_7_GetTextureStageState_FPUPreserve,
6817 IDirect3DDeviceImpl_7_SetTextureStageState_FPUPreserve,
6818 IDirect3DDeviceImpl_7_ValidateDevice_FPUPreserve,
6819 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUPreserve,
6820 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUPreserve,
6821 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUPreserve,
6822 IDirect3DDeviceImpl_7_CreateStateBlock_FPUPreserve,
6823 IDirect3DDeviceImpl_7_Load_FPUPreserve,
6824 IDirect3DDeviceImpl_7_LightEnable_FPUPreserve,
6825 IDirect3DDeviceImpl_7_GetLightEnable_FPUPreserve,
6826 IDirect3DDeviceImpl_7_SetClipPlane_FPUPreserve,
6827 IDirect3DDeviceImpl_7_GetClipPlane_FPUPreserve,
6828 IDirect3DDeviceImpl_7_GetInfo
6831 const IDirect3DDevice3Vtbl IDirect3DDevice3_Vtbl =
6833 /*** IUnknown Methods ***/
6834 Thunk_IDirect3DDeviceImpl_3_QueryInterface,
6835 Thunk_IDirect3DDeviceImpl_3_AddRef,
6836 Thunk_IDirect3DDeviceImpl_3_Release,
6837 /*** IDirect3DDevice3 ***/
6838 IDirect3DDeviceImpl_3_GetCaps,
6839 IDirect3DDeviceImpl_3_GetStats,
6840 IDirect3DDeviceImpl_3_AddViewport,
6841 IDirect3DDeviceImpl_3_DeleteViewport,
6842 IDirect3DDeviceImpl_3_NextViewport,
6843 Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats,
6844 Thunk_IDirect3DDeviceImpl_3_BeginScene,
6845 Thunk_IDirect3DDeviceImpl_3_EndScene,
6846 Thunk_IDirect3DDeviceImpl_3_GetDirect3D,
6847 IDirect3DDeviceImpl_3_SetCurrentViewport,
6848 IDirect3DDeviceImpl_3_GetCurrentViewport,
6849 Thunk_IDirect3DDeviceImpl_3_SetRenderTarget,
6850 Thunk_IDirect3DDeviceImpl_3_GetRenderTarget,
6851 IDirect3DDeviceImpl_3_Begin,
6852 IDirect3DDeviceImpl_3_BeginIndexed,
6853 IDirect3DDeviceImpl_3_Vertex,
6854 IDirect3DDeviceImpl_3_Index,
6855 IDirect3DDeviceImpl_3_End,
6856 IDirect3DDeviceImpl_3_GetRenderState,
6857 IDirect3DDeviceImpl_3_SetRenderState,
6858 IDirect3DDeviceImpl_3_GetLightState,
6859 IDirect3DDeviceImpl_3_SetLightState,
6860 Thunk_IDirect3DDeviceImpl_3_SetTransform,
6861 Thunk_IDirect3DDeviceImpl_3_GetTransform,
6862 Thunk_IDirect3DDeviceImpl_3_MultiplyTransform,
6863 Thunk_IDirect3DDeviceImpl_3_DrawPrimitive,
6864 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive,
6865 Thunk_IDirect3DDeviceImpl_3_SetClipStatus,
6866 Thunk_IDirect3DDeviceImpl_3_GetClipStatus,
6867 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided,
6868 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided,
6869 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB,
6870 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB,
6871 Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility,
6872 Thunk_IDirect3DDeviceImpl_3_GetTexture,
6873 IDirect3DDeviceImpl_3_SetTexture,
6874 Thunk_IDirect3DDeviceImpl_3_GetTextureStageState,
6875 Thunk_IDirect3DDeviceImpl_3_SetTextureStageState,
6876 Thunk_IDirect3DDeviceImpl_3_ValidateDevice
6879 const IDirect3DDevice2Vtbl IDirect3DDevice2_Vtbl =
6881 /*** IUnknown Methods ***/
6882 Thunk_IDirect3DDeviceImpl_2_QueryInterface,
6883 Thunk_IDirect3DDeviceImpl_2_AddRef,
6884 Thunk_IDirect3DDeviceImpl_2_Release,
6885 /*** IDirect3DDevice2 ***/
6886 Thunk_IDirect3DDeviceImpl_2_GetCaps,
6887 IDirect3DDeviceImpl_2_SwapTextureHandles,
6888 Thunk_IDirect3DDeviceImpl_2_GetStats,
6889 Thunk_IDirect3DDeviceImpl_2_AddViewport,
6890 Thunk_IDirect3DDeviceImpl_2_DeleteViewport,
6891 Thunk_IDirect3DDeviceImpl_2_NextViewport,
6892 IDirect3DDeviceImpl_2_EnumTextureFormats,
6893 Thunk_IDirect3DDeviceImpl_2_BeginScene,
6894 Thunk_IDirect3DDeviceImpl_2_EndScene,
6895 Thunk_IDirect3DDeviceImpl_2_GetDirect3D,
6896 Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport,
6897 Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport,
6898 Thunk_IDirect3DDeviceImpl_2_SetRenderTarget,
6899 Thunk_IDirect3DDeviceImpl_2_GetRenderTarget,
6900 Thunk_IDirect3DDeviceImpl_2_Begin,
6901 Thunk_IDirect3DDeviceImpl_2_BeginIndexed,
6902 Thunk_IDirect3DDeviceImpl_2_Vertex,
6903 Thunk_IDirect3DDeviceImpl_2_Index,
6904 Thunk_IDirect3DDeviceImpl_2_End,
6905 Thunk_IDirect3DDeviceImpl_2_GetRenderState,
6906 Thunk_IDirect3DDeviceImpl_2_SetRenderState,
6907 Thunk_IDirect3DDeviceImpl_2_GetLightState,
6908 Thunk_IDirect3DDeviceImpl_2_SetLightState,
6909 Thunk_IDirect3DDeviceImpl_2_SetTransform,
6910 Thunk_IDirect3DDeviceImpl_2_GetTransform,
6911 Thunk_IDirect3DDeviceImpl_2_MultiplyTransform,
6912 Thunk_IDirect3DDeviceImpl_2_DrawPrimitive,
6913 Thunk_IDirect3DDeviceImpl_2_DrawIndexedPrimitive,
6914 Thunk_IDirect3DDeviceImpl_2_SetClipStatus,
6915 Thunk_IDirect3DDeviceImpl_2_GetClipStatus
6918 const IDirect3DDeviceVtbl IDirect3DDevice1_Vtbl =
6920 /*** IUnknown Methods ***/
6921 Thunk_IDirect3DDeviceImpl_1_QueryInterface,
6922 Thunk_IDirect3DDeviceImpl_1_AddRef,
6923 Thunk_IDirect3DDeviceImpl_1_Release,
6924 /*** IDirect3DDevice1 ***/
6925 IDirect3DDeviceImpl_1_Initialize,
6926 Thunk_IDirect3DDeviceImpl_1_GetCaps,
6927 Thunk_IDirect3DDeviceImpl_1_SwapTextureHandles,
6928 IDirect3DDeviceImpl_1_CreateExecuteBuffer,
6929 Thunk_IDirect3DDeviceImpl_1_GetStats,
6930 IDirect3DDeviceImpl_1_Execute,
6931 Thunk_IDirect3DDeviceImpl_1_AddViewport,
6932 Thunk_IDirect3DDeviceImpl_1_DeleteViewport,
6933 Thunk_IDirect3DDeviceImpl_1_NextViewport,
6934 IDirect3DDeviceImpl_1_Pick,
6935 IDirect3DDeviceImpl_1_GetPickRecords,
6936 Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats,
6937 IDirect3DDeviceImpl_1_CreateMatrix,
6938 IDirect3DDeviceImpl_1_SetMatrix,
6939 IDirect3DDeviceImpl_1_GetMatrix,
6940 IDirect3DDeviceImpl_1_DeleteMatrix,
6941 Thunk_IDirect3DDeviceImpl_1_BeginScene,
6942 Thunk_IDirect3DDeviceImpl_1_EndScene,
6943 Thunk_IDirect3DDeviceImpl_1_GetDirect3D
6946 /*****************************************************************************
6947 * IDirect3DDeviceImpl_CreateHandle
6949 * Not called from the VTable
6951 * Some older interface versions operate with handles, which are basically
6952 * DWORDs which identify an interface, for example
6953 * IDirect3DDevice::SetRenderState with DIRECT3DRENDERSTATE_TEXTUREHANDLE
6955 * Those handle could be just casts to the interface pointers or vice versa,
6956 * but that is not 64 bit safe and would mean blindly derefering a DWORD
6957 * passed by the app. Instead there is a dynamic array in the device which
6958 * keeps a DWORD to pointer information and a type for the handle.
6960 * Basically this array only grows, when a handle is freed its pointer is
6961 * just set to NULL. There will be much more reads from the array than
6962 * insertion operations, so a dynamic array is fine.
6964 * Params:
6965 * This: D3DDevice implementation for which this handle should be created
6967 * Returns:
6968 * A free handle on success
6969 * 0 on failure
6971 *****************************************************************************/
6972 DWORD
6973 IDirect3DDeviceImpl_CreateHandle(IDirect3DDeviceImpl *This)
6975 DWORD i;
6976 struct HandleEntry *oldHandles = This->Handles;
6978 TRACE("(%p)\n", This);
6980 for(i = 0; i < This->numHandles; i++)
6982 if(This->Handles[i].ptr == NULL &&
6983 This->Handles[i].type == DDrawHandle_Unknown)
6985 TRACE("Reusing freed handle %d\n", i + 1);
6986 return i + 1;
6990 TRACE("Growing the handle array\n");
6992 This->numHandles++;
6993 This->Handles = HeapAlloc(GetProcessHeap(), 0, sizeof(struct HandleEntry) * This->numHandles);
6994 if(!This->Handles)
6996 ERR("Out of memory\n");
6997 This->Handles = oldHandles;
6998 This->numHandles--;
6999 return 0;
7001 if(oldHandles)
7003 memcpy(This->Handles, oldHandles, (This->numHandles - 1) * sizeof(struct HandleEntry));
7004 HeapFree(GetProcessHeap(), 0, oldHandles);
7007 TRACE("Returning %d\n", This->numHandles);
7008 return This->numHandles;
7011 /*****************************************************************************
7012 * IDirect3DDeviceImpl_UpdateDepthStencil
7014 * Checks the current render target for attached depth stencils and sets the
7015 * WineD3D depth stencil accordingly.
7017 * Returns:
7018 * The depth stencil state to set if creating the device
7020 *****************************************************************************/
7021 WINED3DZBUFFERTYPE
7022 IDirect3DDeviceImpl_UpdateDepthStencil(IDirect3DDeviceImpl *This)
7024 IDirectDrawSurface7 *depthStencil = NULL;
7025 IDirectDrawSurfaceImpl *dsi;
7026 static DDSCAPS2 depthcaps = { DDSCAPS_ZBUFFER, 0, 0, 0 };
7028 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7 *)This->target, &depthcaps, &depthStencil);
7029 if(!depthStencil)
7031 TRACE("Setting wined3d depth stencil to NULL\n");
7032 IWineD3DDevice_SetDepthStencilSurface(This->wineD3DDevice,
7033 NULL);
7034 return WINED3DZB_FALSE;
7037 dsi = (IDirectDrawSurfaceImpl *)depthStencil;
7038 TRACE("Setting wined3d depth stencil to %p (wined3d %p)\n", dsi, dsi->WineD3DSurface);
7039 IWineD3DDevice_SetDepthStencilSurface(This->wineD3DDevice,
7040 dsi->WineD3DSurface);
7042 IDirectDrawSurface7_Release(depthStencil);
7043 return WINED3DZB_TRUE;