mountmgr: Store the contents of the device symlink in the drive object.
[wine/multimedia.git] / dlls / ddraw / device.c
blob7efc66f52616d60b5d7e79b08de6e94ee587939e
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 #endif
90 set_fpu_control_word(0x37f);
92 return oldcw;
95 /*****************************************************************************
96 * IUnknown Methods. Common for Version 1, 2, 3 and 7
97 *****************************************************************************/
99 /*****************************************************************************
100 * IDirect3DDevice7::QueryInterface
102 * Used to query other interfaces from a Direct3DDevice interface.
103 * It can return interface pointers to all Direct3DDevice versions as well
104 * as IDirectDraw and IDirect3D. For a link to QueryInterface
105 * rules see ddraw.c, IDirectDraw7::QueryInterface
107 * Exists in Version 1, 2, 3 and 7
109 * Params:
110 * refiid: Interface ID queried for
111 * obj: Used to return the interface pointer
113 * Returns:
114 * D3D_OK or E_NOINTERFACE
116 *****************************************************************************/
117 static HRESULT WINAPI
118 IDirect3DDeviceImpl_7_QueryInterface(IDirect3DDevice7 *iface,
119 REFIID refiid,
120 void **obj)
122 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
123 TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(refiid), obj);
125 /* According to COM docs, if the QueryInterface fails, obj should be set to NULL */
126 *obj = NULL;
128 if(!refiid)
129 return DDERR_INVALIDPARAMS;
131 if ( IsEqualGUID( &IID_IUnknown, refiid ) )
133 *obj = ICOM_INTERFACE(This, IDirect3DDevice7);
136 /* Check DirectDraw Interfac\x01s */
137 else if( IsEqualGUID( &IID_IDirectDraw7, refiid ) )
139 *obj = ICOM_INTERFACE(This->ddraw, IDirectDraw7);
140 TRACE("(%p) Returning IDirectDraw7 interface at %p\n", This, *obj);
142 else if ( IsEqualGUID( &IID_IDirectDraw4, refiid ) )
144 *obj = ICOM_INTERFACE(This->ddraw, IDirectDraw4);
145 TRACE("(%p) Returning IDirectDraw4 interface at %p\n", This, *obj);
147 else if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) )
149 *obj = ICOM_INTERFACE(This->ddraw, IDirectDraw2);
150 TRACE("(%p) Returning IDirectDraw2 interface at %p\n", This, *obj);
152 else if( IsEqualGUID( &IID_IDirectDraw, refiid ) )
154 *obj = ICOM_INTERFACE(This->ddraw, IDirectDraw);
155 TRACE("(%p) Returning IDirectDraw interface at %p\n", This, *obj);
158 /* Direct3D */
159 else if ( IsEqualGUID( &IID_IDirect3D , refiid ) )
161 *obj = ICOM_INTERFACE(This->ddraw, IDirect3D);
162 TRACE("(%p) Returning IDirect3D interface at %p\n", This, *obj);
164 else if ( IsEqualGUID( &IID_IDirect3D2 , refiid ) )
166 *obj = ICOM_INTERFACE(This->ddraw, IDirect3D2);
167 TRACE("(%p) Returning IDirect3D2 interface at %p\n", This, *obj);
169 else if ( IsEqualGUID( &IID_IDirect3D3 , refiid ) )
171 *obj = ICOM_INTERFACE(This->ddraw, IDirect3D3);
172 TRACE("(%p) Returning IDirect3D3 interface at %p\n", This, *obj);
174 else if ( IsEqualGUID( &IID_IDirect3D7 , refiid ) )
176 *obj = ICOM_INTERFACE(This->ddraw, IDirect3D7);
177 TRACE("(%p) Returning IDirect3D7 interface at %p\n", This, *obj);
180 /* Direct3DDevice */
181 else if ( IsEqualGUID( &IID_IDirect3DDevice , refiid ) )
183 *obj = ICOM_INTERFACE(This, IDirect3DDevice);
184 TRACE("(%p) Returning IDirect3DDevice interface at %p\n", This, *obj);
186 else if ( IsEqualGUID( &IID_IDirect3DDevice2 , refiid ) ) {
187 *obj = ICOM_INTERFACE(This, IDirect3DDevice2);
188 TRACE("(%p) Returning IDirect3DDevice2 interface at %p\n", This, *obj);
190 else if ( IsEqualGUID( &IID_IDirect3DDevice3 , refiid ) ) {
191 *obj = ICOM_INTERFACE(This, IDirect3DDevice3);
192 TRACE("(%p) Returning IDirect3DDevice3 interface at %p\n", This, *obj);
194 else if ( IsEqualGUID( &IID_IDirect3DDevice7 , refiid ) ) {
195 *obj = ICOM_INTERFACE(This, IDirect3DDevice7);
196 TRACE("(%p) Returning IDirect3DDevice7 interface at %p\n", This, *obj);
199 /* Unknown interface */
200 else
202 ERR("(%p)->(%s, %p): No interface found\n", This, debugstr_guid(refiid), obj);
203 return E_NOINTERFACE;
206 /* AddRef the returned interface */
207 IUnknown_AddRef( (IUnknown *) *obj);
208 return D3D_OK;
211 static HRESULT WINAPI
212 Thunk_IDirect3DDeviceImpl_3_QueryInterface(IDirect3DDevice3 *iface,
213 REFIID riid,
214 void **obj)
216 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
217 TRACE_(ddraw_thunk)("(%p)->(%s,%p) thunking to IDirect3DDevice7 interface.\n", This, debugstr_guid(riid), obj);
218 return IDirect3DDevice7_QueryInterface(ICOM_INTERFACE(This, IDirect3DDevice7),
219 riid,
220 obj);
223 static HRESULT WINAPI
224 Thunk_IDirect3DDeviceImpl_2_QueryInterface(IDirect3DDevice2 *iface,
225 REFIID riid,
226 void **obj)
228 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
229 TRACE_(ddraw_thunk)("(%p)->(%s,%p) thunking to IDirect3DDevice7 interface.\n", This, debugstr_guid(riid), obj);
230 return IDirect3DDevice7_QueryInterface(ICOM_INTERFACE(This, IDirect3DDevice7),
231 riid,
232 obj);
235 static HRESULT WINAPI
236 Thunk_IDirect3DDeviceImpl_1_QueryInterface(IDirect3DDevice *iface,
237 REFIID riid,
238 void **obp)
240 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
241 TRACE_(ddraw_thunk)("(%p)->(%s,%p) thunking to IDirect3DDevice7 interface.\n", This, debugstr_guid(riid), obp);
242 return IDirect3DDevice7_QueryInterface(ICOM_INTERFACE(This, IDirect3DDevice7),
243 riid,
244 obp);
247 /*****************************************************************************
248 * IDirect3DDevice7::AddRef
250 * Increases the refcount....
251 * The most exciting Method, definitely
253 * Exists in Version 1, 2, 3 and 7
255 * Returns:
256 * The new refcount
258 *****************************************************************************/
259 static ULONG WINAPI
260 IDirect3DDeviceImpl_7_AddRef(IDirect3DDevice7 *iface)
262 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
263 ULONG ref = InterlockedIncrement(&This->ref);
265 TRACE("(%p) : incrementing from %u.\n", This, ref -1);
267 return ref;
270 static ULONG WINAPI
271 Thunk_IDirect3DDeviceImpl_3_AddRef(IDirect3DDevice3 *iface)
273 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
274 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
275 return IDirect3DDevice7_AddRef(ICOM_INTERFACE(This, IDirect3DDevice7));
278 static ULONG WINAPI
279 Thunk_IDirect3DDeviceImpl_2_AddRef(IDirect3DDevice2 *iface)
281 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
282 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
283 return IDirect3DDevice7_AddRef(ICOM_INTERFACE(This, IDirect3DDevice7));
286 static ULONG WINAPI
287 Thunk_IDirect3DDeviceImpl_1_AddRef(IDirect3DDevice *iface)
289 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", iface);
290 return IDirect3DDevice7_AddRef(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice7, iface));
293 /*****************************************************************************
294 * IDirect3DDevice7::Release
296 * Decreases the refcount of the interface
297 * When the refcount is reduced to 0, the object is destroyed.
299 * Exists in Version 1, 2, 3 and 7
301 * Returns:d
302 * The new refcount
304 *****************************************************************************/
305 static ULONG WINAPI
306 IDirect3DDeviceImpl_7_Release(IDirect3DDevice7 *iface)
308 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
309 ULONG ref = InterlockedDecrement(&This->ref);
311 TRACE("(%p)->() decrementing from %u.\n", This, ref +1);
313 /* This method doesn't destroy the WineD3DDevice, because it's still in use for
314 * 2D rendering. IDirectDrawSurface7::Release will destroy the WineD3DDevice
315 * when the render target is released
317 if (ref == 0)
319 IParent *IndexBufferParent;
320 DWORD i;
322 EnterCriticalSection(&ddraw_cs);
323 /* Free the index buffer. */
324 IWineD3DDevice_SetIndices(This->wineD3DDevice, NULL);
325 IWineD3DIndexBuffer_GetParent(This->indexbuffer,
326 (IUnknown **) &IndexBufferParent);
327 IParent_Release(IndexBufferParent); /* Once for the getParent */
328 if( IParent_Release(IndexBufferParent) != 0) /* And now to destroy it */
330 ERR(" (%p) Something is still holding the index buffer parent %p\n", This, IndexBufferParent);
333 /* There is no need to unset the vertex buffer here, IWineD3DDevice_Uninit3D will do that when
334 * destroying the primary stateblock. If a vertex buffer is destroyed while it is bound
335 * IDirect3DVertexBuffer::Release will unset it.
338 /* Restore the render targets */
339 if(This->OffScreenTarget)
341 WINED3DVIEWPORT vp;
343 vp.X = 0;
344 vp.Y = 0;
345 vp.Width = This->ddraw->d3d_target->surface_desc.dwWidth;
346 vp.Height = This->ddraw->d3d_target->surface_desc.dwHeight;
347 vp.MinZ = 0.0;
348 vp.MaxZ = 1.0;
349 IWineD3DDevice_SetViewport(This->wineD3DDevice,
350 &vp);
352 /* Set the device up to render to the front buffer since the back buffer will
353 * vanish soon.
355 IWineD3DDevice_SetRenderTarget(This->wineD3DDevice, 0,
356 This->ddraw->d3d_target->WineD3DSurface);
357 /* This->target is the offscreen target.
358 * This->ddraw->d3d_target is the target used by DDraw
360 TRACE("(%p) Release: Using %p as front buffer, %p as back buffer\n", This, This->ddraw->d3d_target, NULL);
361 IWineD3DDevice_SetFrontBackBuffers(This->wineD3DDevice,
362 This->ddraw->d3d_target->WineD3DSurface,
363 NULL);
366 /* Release the WineD3DDevice. This won't destroy it */
367 if(IWineD3DDevice_Release(This->wineD3DDevice) <= 0)
369 ERR(" (%p) The wineD3D device %p was destroyed unexpectedly. Prepare for trouble\n", This, This->wineD3DDevice);
372 /* The texture handles should be unset by now, but there might be some bits
373 * missing in our reference counting(needs test). Do a sanity check
375 for(i = 0; i < This->numHandles; i++)
377 if(This->Handles[i].ptr)
379 switch(This->Handles[i].type)
381 case DDrawHandle_Texture:
383 IDirectDrawSurfaceImpl *surf = (IDirectDrawSurfaceImpl *) This->Handles[i].ptr;
384 FIXME("Texture Handle %d not unset properly\n", i + 1);
385 surf->Handle = 0;
387 break;
389 case DDrawHandle_Material:
391 IDirect3DMaterialImpl *mat = (IDirect3DMaterialImpl *) This->Handles[i].ptr;
392 FIXME("Material handle %d not unset properly\n", i + 1);
393 mat->Handle = 0;
395 break;
397 case DDrawHandle_Matrix:
399 /* No fixme here because this might happen because of sloppy apps */
400 WARN("Leftover matrix handle %d, deleting\n", i + 1);
401 IDirect3DDevice_DeleteMatrix(ICOM_INTERFACE(This, IDirect3DDevice),
402 i + 1);
404 break;
406 case DDrawHandle_StateBlock:
408 /* No fixme here because this might happen because of sloppy apps */
409 WARN("Leftover stateblock handle %d, deleting\n", i + 1);
410 IDirect3DDevice7_DeleteStateBlock(ICOM_INTERFACE(This, IDirect3DDevice7),
411 i + 1);
413 break;
415 default:
416 FIXME("Unknown handle %d not unset properly\n", i + 1);
421 HeapFree(GetProcessHeap(), 0, This->Handles);
423 TRACE("Releasing target %p %p\n", This->target, This->ddraw->d3d_target);
424 /* Release the render target and the WineD3D render target
425 * (See IDirect3D7::CreateDevice for more comments on this)
427 IDirectDrawSurface7_Release(ICOM_INTERFACE(This->target, IDirectDrawSurface7));
428 IDirectDrawSurface7_Release(ICOM_INTERFACE(This->ddraw->d3d_target,IDirectDrawSurface7));
429 TRACE("Target release done\n");
431 This->ddraw->d3ddevice = NULL;
433 /* Now free the structure */
434 HeapFree(GetProcessHeap(), 0, This);
435 LeaveCriticalSection(&ddraw_cs);
438 TRACE("Done\n");
439 return ref;
442 static ULONG WINAPI
443 Thunk_IDirect3DDeviceImpl_3_Release(IDirect3DDevice3 *iface)
445 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
446 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
447 return IDirect3DDevice7_Release(ICOM_INTERFACE(This, IDirect3DDevice7));
450 static ULONG WINAPI
451 Thunk_IDirect3DDeviceImpl_2_Release(IDirect3DDevice2 *iface)
453 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
454 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
455 return IDirect3DDevice7_Release(ICOM_INTERFACE(This, IDirect3DDevice7));
458 static ULONG WINAPI
459 Thunk_IDirect3DDeviceImpl_1_Release(IDirect3DDevice *iface)
461 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
462 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
463 return IDirect3DDevice7_Release(ICOM_INTERFACE(This, IDirect3DDevice7));
466 /*****************************************************************************
467 * IDirect3DDevice Methods
468 *****************************************************************************/
470 /*****************************************************************************
471 * IDirect3DDevice::Initialize
473 * Initializes a Direct3DDevice. This implementation is a no-op, as all
474 * initialization is done at create time.
476 * Exists in Version 1
478 * Parameters:
479 * No idea what they mean, as the MSDN page is gone
481 * Returns: DD_OK
483 *****************************************************************************/
484 static HRESULT WINAPI
485 IDirect3DDeviceImpl_1_Initialize(IDirect3DDevice *iface,
486 IDirect3D *Direct3D, GUID *guid,
487 D3DDEVICEDESC *Desc)
489 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
491 /* It shouldn't be crucial, but print a FIXME, I'm interested if
492 * any game calls it and when
494 FIXME("(%p)->(%p,%p,%p): No-op!\n", This, Direct3D, guid, Desc);
496 return D3D_OK;
499 /*****************************************************************************
500 * IDirect3DDevice7::GetCaps
502 * Retrieves the device's capabilities
504 * This implementation is used for Version 7 only, the older versions have
505 * their own implementation.
507 * Parameters:
508 * Desc: Pointer to a D3DDEVICEDESC7 structure to fill
510 * Returns:
511 * D3D_OK on success
512 * D3DERR_* if a problem occurs. See WineD3D
514 *****************************************************************************/
515 static HRESULT
516 IDirect3DDeviceImpl_7_GetCaps(IDirect3DDevice7 *iface,
517 D3DDEVICEDESC7 *Desc)
519 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
520 D3DDEVICEDESC OldDesc;
521 TRACE("(%p)->(%p)\n", This, Desc);
523 /* Call the same function used by IDirect3D, this saves code */
524 return IDirect3DImpl_GetCaps(This->ddraw->wineD3D, &OldDesc, Desc);
527 static HRESULT WINAPI
528 IDirect3DDeviceImpl_7_GetCaps_FPUSetup(IDirect3DDevice7 *iface,
529 D3DDEVICEDESC7 *Desc)
531 return IDirect3DDeviceImpl_7_GetCaps(iface, Desc);
534 static HRESULT WINAPI
535 IDirect3DDeviceImpl_7_GetCaps_FPUPreserve(IDirect3DDevice7 *iface,
536 D3DDEVICEDESC7 *Desc)
538 HRESULT hr;
539 WORD old_fpucw;
541 old_fpucw = d3d_fpu_setup();
542 hr = IDirect3DDeviceImpl_7_GetCaps(iface, Desc);
543 set_fpu_control_word(old_fpucw);
545 return hr;
547 /*****************************************************************************
548 * IDirect3DDevice3::GetCaps
550 * Retrieves the capabilities of the hardware device and the emulation
551 * device. For Wine, hardware and emulation are the same (it's all HW).
553 * This implementation is used for Version 1, 2, and 3. Version 7 has its own
555 * Parameters:
556 * HWDesc: Structure to fill with the HW caps
557 * HelDesc: Structure to fill with the hardware emulation caps
559 * Returns:
560 * D3D_OK on success
561 * D3DERR_* if a problem occurs. See WineD3D
563 *****************************************************************************/
564 static HRESULT WINAPI
565 IDirect3DDeviceImpl_3_GetCaps(IDirect3DDevice3 *iface,
566 D3DDEVICEDESC *HWDesc,
567 D3DDEVICEDESC *HelDesc)
569 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
570 D3DDEVICEDESC7 newDesc;
571 HRESULT hr;
572 TRACE("(%p)->(%p,%p)\n", iface, HWDesc, HelDesc);
574 hr = IDirect3DImpl_GetCaps(This->ddraw->wineD3D, HWDesc, &newDesc);
575 if(hr != D3D_OK) return hr;
577 *HelDesc = *HWDesc;
578 return D3D_OK;
581 static HRESULT WINAPI
582 Thunk_IDirect3DDeviceImpl_2_GetCaps(IDirect3DDevice2 *iface,
583 D3DDEVICEDESC *D3DHWDevDesc,
584 D3DDEVICEDESC *D3DHELDevDesc)
586 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
587 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice3 interface.\n", This, D3DHWDevDesc, D3DHELDevDesc);
588 return IDirect3DDevice3_GetCaps(ICOM_INTERFACE(This, IDirect3DDevice3),
589 D3DHWDevDesc,
590 D3DHELDevDesc);
593 static HRESULT WINAPI
594 Thunk_IDirect3DDeviceImpl_1_GetCaps(IDirect3DDevice *iface,
595 D3DDEVICEDESC *D3DHWDevDesc,
596 D3DDEVICEDESC *D3DHELDevDesc)
598 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
599 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice3 interface.\n", This, D3DHWDevDesc, D3DHELDevDesc);
600 return IDirect3DDevice3_GetCaps(ICOM_INTERFACE(This, IDirect3DDevice3),
601 D3DHWDevDesc,
602 D3DHELDevDesc);
605 /*****************************************************************************
606 * IDirect3DDevice2::SwapTextureHandles
608 * Swaps the texture handles of 2 Texture interfaces. Version 1 and 2
610 * Parameters:
611 * Tex1, Tex2: The 2 Textures to swap
613 * Returns:
614 * D3D_OK
616 *****************************************************************************/
617 static HRESULT WINAPI
618 IDirect3DDeviceImpl_2_SwapTextureHandles(IDirect3DDevice2 *iface,
619 IDirect3DTexture2 *Tex1,
620 IDirect3DTexture2 *Tex2)
622 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
623 DWORD swap;
624 IDirectDrawSurfaceImpl *surf1 = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture2, Tex1);
625 IDirectDrawSurfaceImpl *surf2 = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture2, Tex2);
626 TRACE("(%p)->(%p,%p)\n", This, surf1, surf2);
628 EnterCriticalSection(&ddraw_cs);
629 This->Handles[surf1->Handle - 1].ptr = surf2;
630 This->Handles[surf2->Handle - 1].ptr = surf1;
632 swap = surf2->Handle;
633 surf2->Handle = surf1->Handle;
634 surf1->Handle = swap;
635 LeaveCriticalSection(&ddraw_cs);
637 return D3D_OK;
640 static HRESULT WINAPI
641 Thunk_IDirect3DDeviceImpl_1_SwapTextureHandles(IDirect3DDevice *iface,
642 IDirect3DTexture *D3DTex1,
643 IDirect3DTexture *D3DTex2)
645 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
646 IDirectDrawSurfaceImpl *surf1 = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture, D3DTex1);
647 IDirectDrawSurfaceImpl *surf2 = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture, D3DTex2);
648 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice2 interface.\n", This, surf1, surf2);
649 return IDirect3DDevice2_SwapTextureHandles(ICOM_INTERFACE(This, IDirect3DDevice2),
650 ICOM_INTERFACE(surf1, IDirect3DTexture2),
651 ICOM_INTERFACE(surf2, IDirect3DTexture2));
654 /*****************************************************************************
655 * IDirect3DDevice3::GetStats
657 * This method seems to retrieve some stats from the device.
658 * The MSDN documentation doesn't exist any more, but the D3DSTATS
659 * structure suggests that the amount of drawn primitives and processed
660 * vertices is returned.
662 * Exists in Version 1, 2 and 3
664 * Parameters:
665 * Stats: Pointer to a D3DSTATS structure to be filled
667 * Returns:
668 * D3D_OK on success
669 * DDERR_INVALIDPARAMS if Stats == NULL
671 *****************************************************************************/
672 static HRESULT WINAPI
673 IDirect3DDeviceImpl_3_GetStats(IDirect3DDevice3 *iface,
674 D3DSTATS *Stats)
676 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
677 FIXME("(%p)->(%p): Stub!\n", This, Stats);
679 if(!Stats)
680 return DDERR_INVALIDPARAMS;
682 /* Fill the Stats with 0 */
683 Stats->dwTrianglesDrawn = 0;
684 Stats->dwLinesDrawn = 0;
685 Stats->dwPointsDrawn = 0;
686 Stats->dwSpansDrawn = 0;
687 Stats->dwVerticesProcessed = 0;
689 return D3D_OK;
692 static HRESULT WINAPI
693 Thunk_IDirect3DDeviceImpl_2_GetStats(IDirect3DDevice2 *iface,
694 D3DSTATS *Stats)
696 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
697 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, Stats);
698 return IDirect3DDevice3_GetStats(ICOM_INTERFACE(This, IDirect3DDevice3),
699 Stats);
702 static HRESULT WINAPI
703 Thunk_IDirect3DDeviceImpl_1_GetStats(IDirect3DDevice *iface,
704 D3DSTATS *Stats)
706 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
707 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, Stats);
708 return IDirect3DDevice3_GetStats(ICOM_INTERFACE(This, IDirect3DDevice3),
709 Stats);
712 /*****************************************************************************
713 * IDirect3DDevice::CreateExecuteBuffer
715 * Creates an IDirect3DExecuteBuffer, used for rendering with a
716 * Direct3DDevice.
718 * Version 1 only.
720 * Params:
721 * Desc: Buffer description
722 * ExecuteBuffer: Address to return the Interface pointer at
723 * UnkOuter: Must be NULL. Basically for aggregation, which ddraw doesn't
724 * support
726 * Returns:
727 * CLASS_E_NOAGGREGATION if UnkOuter != NULL
728 * DDERR_OUTOFMEMORY if we ran out of memory
729 * D3D_OK on success
731 *****************************************************************************/
732 static HRESULT WINAPI
733 IDirect3DDeviceImpl_1_CreateExecuteBuffer(IDirect3DDevice *iface,
734 D3DEXECUTEBUFFERDESC *Desc,
735 IDirect3DExecuteBuffer **ExecuteBuffer,
736 IUnknown *UnkOuter)
738 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
739 IDirect3DExecuteBufferImpl* object;
740 TRACE("(%p)->(%p,%p,%p)!\n", This, Desc, ExecuteBuffer, UnkOuter);
742 if(UnkOuter)
743 return CLASS_E_NOAGGREGATION;
745 /* Allocate the new Execute Buffer */
746 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DExecuteBufferImpl));
747 if(!object)
749 ERR("Out of memory when allocating a IDirect3DExecuteBufferImpl structure\n");
750 return DDERR_OUTOFMEMORY;
753 ICOM_INIT_INTERFACE(object, IDirect3DExecuteBuffer, IDirect3DExecuteBuffer_Vtbl);
755 object->ref = 1;
756 object->d3ddev = This;
758 /* Initializes memory */
759 memcpy(&object->desc, Desc, Desc->dwSize);
761 /* No buffer given */
762 if ((object->desc.dwFlags & D3DDEB_LPDATA) == 0)
763 object->desc.lpData = NULL;
765 /* No buffer size given */
766 if ((object->desc.dwFlags & D3DDEB_BUFSIZE) == 0)
767 object->desc.dwBufferSize = 0;
769 /* Create buffer if asked */
770 if ((object->desc.lpData == NULL) && (object->desc.dwBufferSize > 0))
772 object->need_free = TRUE;
773 object->desc.lpData = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,object->desc.dwBufferSize);
774 if(!object->desc.lpData)
776 ERR("Out of memory when allocating the execute buffer data\n");
777 HeapFree(GetProcessHeap(), 0, object);
778 return DDERR_OUTOFMEMORY;
781 else
783 object->need_free = FALSE;
786 /* No vertices for the moment */
787 object->vertex_data = NULL;
789 object->desc.dwFlags |= D3DDEB_LPDATA;
791 object->indices = NULL;
792 object->nb_indices = 0;
794 *ExecuteBuffer = ICOM_INTERFACE(object, IDirect3DExecuteBuffer);
796 TRACE(" Returning IDirect3DExecuteBuffer at %p, implementation is at %p\n", *ExecuteBuffer, object);
798 return D3D_OK;
801 /*****************************************************************************
802 * IDirect3DDevice::Execute
804 * Executes all the stuff in an execute buffer.
806 * Params:
807 * ExecuteBuffer: The buffer to execute
808 * Viewport: The viewport used for rendering
809 * Flags: Some flags
811 * Returns:
812 * DDERR_INVALIDPARAMS if ExecuteBuffer == NULL
813 * D3D_OK on success
815 *****************************************************************************/
816 static HRESULT WINAPI
817 IDirect3DDeviceImpl_1_Execute(IDirect3DDevice *iface,
818 IDirect3DExecuteBuffer *ExecuteBuffer,
819 IDirect3DViewport *Viewport,
820 DWORD Flags)
822 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
823 IDirect3DExecuteBufferImpl *Direct3DExecuteBufferImpl = ICOM_OBJECT(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, ExecuteBuffer);
824 IDirect3DViewportImpl *Direct3DViewportImpl = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport);
826 TRACE("(%p)->(%p,%p,%08x)\n", This, Direct3DExecuteBufferImpl, Direct3DViewportImpl, Flags);
828 if(!Direct3DExecuteBufferImpl)
829 return DDERR_INVALIDPARAMS;
831 /* Execute... */
832 EnterCriticalSection(&ddraw_cs);
833 IDirect3DExecuteBufferImpl_Execute(Direct3DExecuteBufferImpl, This, Direct3DViewportImpl);
834 LeaveCriticalSection(&ddraw_cs);
836 return D3D_OK;
839 /*****************************************************************************
840 * IDirect3DDevice3::AddViewport
842 * Add a Direct3DViewport to the device's viewport list. These viewports
843 * are wrapped to IDirect3DDevice7 viewports in viewport.c
845 * Exists in Version 1, 2 and 3. Note that IDirect3DViewport 1, 2 and 3
846 * are the same interfaces.
848 * Params:
849 * Viewport: The viewport to add
851 * Returns:
852 * DDERR_INVALIDPARAMS if Viewport == NULL
853 * D3D_OK on success
855 *****************************************************************************/
856 static HRESULT WINAPI
857 IDirect3DDeviceImpl_3_AddViewport(IDirect3DDevice3 *iface,
858 IDirect3DViewport3 *Viewport)
860 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
861 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport);
863 TRACE("(%p)->(%p)\n", This, vp);
865 /* Sanity check */
866 if(!vp)
867 return DDERR_INVALIDPARAMS;
869 EnterCriticalSection(&ddraw_cs);
870 vp->next = This->viewport_list;
871 This->viewport_list = vp;
872 vp->active_device = This; /* Viewport must be usable for Clear() after AddViewport,
873 so set active_device here. */
874 LeaveCriticalSection(&ddraw_cs);
876 return D3D_OK;
879 static HRESULT WINAPI
880 Thunk_IDirect3DDeviceImpl_2_AddViewport(IDirect3DDevice2 *iface,
881 IDirect3DViewport2 *Direct3DViewport2)
883 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
884 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport2);
885 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
886 return IDirect3DDevice3_AddViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
887 ICOM_INTERFACE(vp, IDirect3DViewport3));
890 static HRESULT WINAPI
891 Thunk_IDirect3DDeviceImpl_1_AddViewport(IDirect3DDevice *iface,
892 IDirect3DViewport *Direct3DViewport)
894 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
895 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport);
896 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
897 return IDirect3DDevice3_AddViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
898 ICOM_INTERFACE(vp, IDirect3DViewport3));
901 /*****************************************************************************
902 * IDirect3DDevice3::DeleteViewport
904 * Deletes a Direct3DViewport from the device's viewport list.
906 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
907 * are equal.
909 * Params:
910 * Viewport: The viewport to delete
912 * Returns:
913 * D3D_OK on success
914 * DDERR_INVALIDPARAMS if the viewport wasn't found in the list
916 *****************************************************************************/
917 static HRESULT WINAPI
918 IDirect3DDeviceImpl_3_DeleteViewport(IDirect3DDevice3 *iface,
919 IDirect3DViewport3 *Viewport)
921 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
922 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *) Viewport;
923 IDirect3DViewportImpl *cur_viewport, *prev_viewport = NULL;
925 TRACE("(%p)->(%p)\n", This, vp);
927 EnterCriticalSection(&ddraw_cs);
928 cur_viewport = This->viewport_list;
929 while (cur_viewport != NULL)
931 if (cur_viewport == vp)
933 if (prev_viewport == NULL) This->viewport_list = cur_viewport->next;
934 else prev_viewport->next = cur_viewport->next;
935 /* TODO : add desactivate of the viewport and all associated lights... */
936 LeaveCriticalSection(&ddraw_cs);
937 return D3D_OK;
939 prev_viewport = cur_viewport;
940 cur_viewport = cur_viewport->next;
943 LeaveCriticalSection(&ddraw_cs);
944 return DDERR_INVALIDPARAMS;
947 static HRESULT WINAPI
948 Thunk_IDirect3DDeviceImpl_2_DeleteViewport(IDirect3DDevice2 *iface,
949 IDirect3DViewport2 *Direct3DViewport2)
951 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
952 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport2);
953 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
954 return IDirect3DDevice3_DeleteViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
955 ICOM_INTERFACE(vp, IDirect3DViewport3));
958 static HRESULT WINAPI
959 Thunk_IDirect3DDeviceImpl_1_DeleteViewport(IDirect3DDevice *iface,
960 IDirect3DViewport *Direct3DViewport)
962 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
963 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport);
964 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
965 return IDirect3DDevice3_DeleteViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
966 ICOM_INTERFACE(vp, IDirect3DViewport3));
969 /*****************************************************************************
970 * IDirect3DDevice3::NextViewport
972 * Returns a viewport from the viewport list, depending on the
973 * passed viewport and the flags.
975 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
976 * are equal.
978 * Params:
979 * Viewport: Viewport to use for beginning the search
980 * Flags: D3DNEXT_NEXT, D3DNEXT_HEAD or D3DNEXT_TAIL
982 * Returns:
983 * D3D_OK on success
984 * DDERR_INVALIDPARAMS if the flags were wrong, or Viewport was NULL
986 *****************************************************************************/
987 static HRESULT WINAPI
988 IDirect3DDeviceImpl_3_NextViewport(IDirect3DDevice3 *iface,
989 IDirect3DViewport3 *Viewport3,
990 IDirect3DViewport3 **lplpDirect3DViewport3,
991 DWORD Flags)
993 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
994 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport3);
995 IDirect3DViewportImpl *res = NULL;
997 TRACE("(%p)->(%p,%p,%08x)\n", This, vp, lplpDirect3DViewport3, Flags);
999 if(!vp)
1001 *lplpDirect3DViewport3 = NULL;
1002 return DDERR_INVALIDPARAMS;
1006 EnterCriticalSection(&ddraw_cs);
1007 switch (Flags)
1009 case D3DNEXT_NEXT:
1011 res = vp->next;
1013 break;
1014 case D3DNEXT_HEAD:
1016 res = This->viewport_list;
1018 break;
1019 case D3DNEXT_TAIL:
1021 IDirect3DViewportImpl *cur_viewport = This->viewport_list;
1022 if (cur_viewport != NULL)
1024 while (cur_viewport->next != NULL) cur_viewport = cur_viewport->next;
1026 res = cur_viewport;
1028 break;
1029 default:
1030 *lplpDirect3DViewport3 = NULL;
1031 LeaveCriticalSection(&ddraw_cs);
1032 return DDERR_INVALIDPARAMS;
1035 *lplpDirect3DViewport3 = ICOM_INTERFACE(res, IDirect3DViewport3);
1036 LeaveCriticalSection(&ddraw_cs);
1037 return D3D_OK;
1040 static HRESULT WINAPI
1041 Thunk_IDirect3DDeviceImpl_2_NextViewport(IDirect3DDevice2 *iface,
1042 IDirect3DViewport2 *Viewport2,
1043 IDirect3DViewport2 **lplpDirect3DViewport2,
1044 DWORD Flags)
1046 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1047 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport2);
1048 IDirect3DViewport3 *res;
1049 HRESULT hr;
1050 TRACE_(ddraw_thunk)("(%p)->(%p,%p,%08x) thunking to IDirect3DDevice3 interface.\n", This, vp, lplpDirect3DViewport2, Flags);
1051 hr = IDirect3DDevice3_NextViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
1052 ICOM_INTERFACE(vp, IDirect3DViewport3),
1053 &res,
1054 Flags);
1055 *lplpDirect3DViewport2 = (IDirect3DViewport2 *) COM_INTERFACE_CAST(IDirect3DViewportImpl, IDirect3DViewport3, IDirect3DViewport3, res);
1056 return hr;
1059 static HRESULT WINAPI
1060 Thunk_IDirect3DDeviceImpl_1_NextViewport(IDirect3DDevice *iface,
1061 IDirect3DViewport *Viewport,
1062 IDirect3DViewport **lplpDirect3DViewport,
1063 DWORD Flags)
1065 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1066 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport);
1067 IDirect3DViewport3 *res;
1068 HRESULT hr;
1069 TRACE_(ddraw_thunk)("(%p)->(%p,%p,%08x) thunking to IDirect3DDevice3 interface.\n", This, vp, lplpDirect3DViewport, Flags);
1070 hr = IDirect3DDevice3_NextViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
1071 ICOM_INTERFACE(vp, IDirect3DViewport3),
1072 &res,
1073 Flags);
1074 *lplpDirect3DViewport = (IDirect3DViewport *) COM_INTERFACE_CAST(IDirect3DViewportImpl, IDirect3DViewport3, IDirect3DViewport3, res);
1075 return hr;
1078 /*****************************************************************************
1079 * IDirect3DDevice::Pick
1081 * Executes an execute buffer without performing rendering. Instead, a
1082 * list of primitives that intersect with (x1,y1) of the passed rectangle
1083 * is created. IDirect3DDevice::GetPickRecords can be used to retrieve
1084 * this list.
1086 * Version 1 only
1088 * Params:
1089 * ExecuteBuffer: Buffer to execute
1090 * Viewport: Viewport to use for execution
1091 * Flags: None are defined, according to the SDK
1092 * Rect: Specifies the coordinates to be picked. Only x1 and y2 are used,
1093 * x2 and y2 are ignored.
1095 * Returns:
1096 * D3D_OK because it's a stub
1098 *****************************************************************************/
1099 static HRESULT WINAPI
1100 IDirect3DDeviceImpl_1_Pick(IDirect3DDevice *iface,
1101 IDirect3DExecuteBuffer *ExecuteBuffer,
1102 IDirect3DViewport *Viewport,
1103 DWORD Flags,
1104 D3DRECT *Rect)
1106 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1107 IDirect3DExecuteBufferImpl *execbuf = ICOM_OBJECT(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, ExecuteBuffer);
1108 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport);
1109 FIXME("(%p)->(%p,%p,%08x,%p): stub!\n", This, execbuf, vp, Flags, Rect);
1111 return D3D_OK;
1114 /*****************************************************************************
1115 * IDirect3DDevice::GetPickRecords
1117 * Retrieves the pick records generated by IDirect3DDevice::GetPickRecords
1119 * Version 1 only
1121 * Params:
1122 * Count: Pointer to a DWORD containing the numbers of pick records to
1123 * retrieve
1124 * D3DPickRec: Address to store the resulting D3DPICKRECORD array.
1126 * Returns:
1127 * D3D_OK, because it's a stub
1129 *****************************************************************************/
1130 static HRESULT WINAPI
1131 IDirect3DDeviceImpl_1_GetPickRecords(IDirect3DDevice *iface,
1132 DWORD *Count,
1133 D3DPICKRECORD *D3DPickRec)
1135 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1136 FIXME("(%p)->(%p,%p): stub!\n", This, Count, D3DPickRec);
1138 return D3D_OK;
1141 /*****************************************************************************
1142 * IDirect3DDevice7::EnumTextureformats
1144 * Enumerates the supported texture formats. It has a list of all possible
1145 * formats and calls IWineD3D::CheckDeviceFormat for each format to see if
1146 * WineD3D supports it. If so, then it is passed to the app.
1148 * This is for Version 7 and 3, older versions have a different
1149 * callback function and their own implementation
1151 * Params:
1152 * Callback: Callback to call for each enumerated format
1153 * Arg: Argument to pass to the callback
1155 * Returns:
1156 * D3D_OK on success
1157 * DDERR_INVALIDPARAMS if Callback == NULL
1159 *****************************************************************************/
1160 static HRESULT
1161 IDirect3DDeviceImpl_7_EnumTextureFormats(IDirect3DDevice7 *iface,
1162 LPD3DENUMPIXELFORMATSCALLBACK Callback,
1163 void *Arg)
1165 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1166 HRESULT hr;
1167 WINED3DDISPLAYMODE mode;
1168 unsigned int i;
1170 WINED3DFORMAT FormatList[] = {
1171 /* 32 bit */
1172 WINED3DFMT_A8R8G8B8,
1173 WINED3DFMT_X8R8G8B8,
1174 /* 24 bit */
1175 WINED3DFMT_R8G8B8,
1176 /* 16 Bit */
1177 WINED3DFMT_A1R5G5B5,
1178 WINED3DFMT_A4R4G4B4,
1179 WINED3DFMT_R5G6B5,
1180 WINED3DFMT_X1R5G5B5,
1181 /* 8 Bit */
1182 WINED3DFMT_R3G3B2,
1183 WINED3DFMT_P8,
1184 /* FOURCC codes */
1185 WINED3DFMT_DXT1,
1186 WINED3DFMT_DXT3,
1187 WINED3DFMT_DXT5,
1190 WINED3DFORMAT BumpFormatList[] = {
1191 WINED3DFMT_V8U8,
1192 WINED3DFMT_L6V5U5,
1193 WINED3DFMT_X8L8V8U8,
1194 WINED3DFMT_Q8W8V8U8,
1195 WINED3DFMT_V16U16,
1196 WINED3DFMT_W11V11U10,
1197 WINED3DFMT_A2W10V10U10
1200 TRACE("(%p)->(%p,%p): Relay\n", This, Callback, Arg);
1202 if(!Callback)
1203 return DDERR_INVALIDPARAMS;
1205 EnterCriticalSection(&ddraw_cs);
1207 memset(&mode, 0, sizeof(mode));
1208 hr = IWineD3DDevice_GetDisplayMode(This->ddraw->wineD3DDevice,
1210 &mode);
1211 if(FAILED(hr)) {
1212 LeaveCriticalSection(&ddraw_cs);
1213 WARN("Cannot get the current adapter format\n");
1214 return hr;
1217 for(i = 0; i < sizeof(FormatList) / sizeof(WINED3DFORMAT); i++)
1219 hr = IWineD3D_CheckDeviceFormat(This->ddraw->wineD3D,
1220 WINED3DADAPTER_DEFAULT,
1221 WINED3DDEVTYPE_HAL,
1222 mode.Format,
1223 0 /* Usage */,
1224 WINED3DRTYPE_TEXTURE,
1225 FormatList[i],
1226 SURFACE_OPENGL);
1227 if(hr == D3D_OK)
1229 DDPIXELFORMAT pformat;
1231 memset(&pformat, 0, sizeof(pformat));
1232 pformat.dwSize = sizeof(pformat);
1233 PixelFormat_WineD3DtoDD(&pformat, FormatList[i]);
1235 TRACE("Enumerating WineD3DFormat %d\n", FormatList[i]);
1236 hr = Callback(&pformat, Arg);
1237 if(hr != DDENUMRET_OK)
1239 TRACE("Format enumeration cancelled by application\n");
1240 LeaveCriticalSection(&ddraw_cs);
1241 return D3D_OK;
1246 for(i = 0; i < sizeof(BumpFormatList) / sizeof(WINED3DFORMAT); i++)
1248 hr = IWineD3D_CheckDeviceFormat(This->ddraw->wineD3D,
1249 WINED3DADAPTER_DEFAULT,
1250 WINED3DDEVTYPE_HAL,
1251 mode.Format,
1252 WINED3DUSAGE_QUERY_LEGACYBUMPMAP,
1253 WINED3DRTYPE_TEXTURE,
1254 BumpFormatList[i],
1255 SURFACE_OPENGL);
1256 if(hr == D3D_OK)
1258 DDPIXELFORMAT pformat;
1260 memset(&pformat, 0, sizeof(pformat));
1261 pformat.dwSize = sizeof(pformat);
1262 PixelFormat_WineD3DtoDD(&pformat, BumpFormatList[i]);
1264 TRACE("Enumerating WineD3DFormat %d\n", BumpFormatList[i]);
1265 hr = Callback(&pformat, Arg);
1266 if(hr != DDENUMRET_OK)
1268 TRACE("Format enumeration cancelled by application\n");
1269 LeaveCriticalSection(&ddraw_cs);
1270 return D3D_OK;
1274 TRACE("End of enumeration\n");
1275 LeaveCriticalSection(&ddraw_cs);
1276 return D3D_OK;
1279 static HRESULT WINAPI
1280 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUSetup(IDirect3DDevice7 *iface,
1281 LPD3DENUMPIXELFORMATSCALLBACK Callback,
1282 void *Arg)
1284 return IDirect3DDeviceImpl_7_EnumTextureFormats(iface, Callback, Arg);
1287 static HRESULT WINAPI
1288 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUPreserve(IDirect3DDevice7 *iface,
1289 LPD3DENUMPIXELFORMATSCALLBACK Callback,
1290 void *Arg)
1292 HRESULT hr;
1293 WORD old_fpucw;
1295 old_fpucw = d3d_fpu_setup();
1296 hr = IDirect3DDeviceImpl_7_EnumTextureFormats(iface, Callback, Arg);
1297 set_fpu_control_word(old_fpucw);
1299 return hr;
1302 static HRESULT WINAPI
1303 Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats(IDirect3DDevice3 *iface,
1304 LPD3DENUMPIXELFORMATSCALLBACK Callback,
1305 void *Arg)
1307 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1308 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice7 interface.\n", This, Callback, Arg);
1309 return IDirect3DDevice7_EnumTextureFormats(ICOM_INTERFACE(This, IDirect3DDevice7),
1310 Callback,
1311 Arg);
1314 /*****************************************************************************
1315 * IDirect3DDevice2::EnumTextureformats
1317 * EnumTextureFormats for Version 1 and 2, see
1318 * IDirect3DDevice7::EnumTexureFormats for a more detailed description.
1320 * This version has a different callback and does not enumerate FourCC
1321 * formats
1323 *****************************************************************************/
1324 static HRESULT WINAPI
1325 IDirect3DDeviceImpl_2_EnumTextureFormats(IDirect3DDevice2 *iface,
1326 LPD3DENUMTEXTUREFORMATSCALLBACK Callback,
1327 void *Arg)
1329 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1330 HRESULT hr;
1331 unsigned int i;
1332 WINED3DDISPLAYMODE mode;
1334 WINED3DFORMAT FormatList[] = {
1335 /* 32 bit */
1336 WINED3DFMT_A8R8G8B8,
1337 WINED3DFMT_X8R8G8B8,
1338 /* 24 bit */
1339 WINED3DFMT_R8G8B8,
1340 /* 16 Bit */
1341 WINED3DFMT_A1R5G5B5,
1342 WINED3DFMT_A4R4G4B4,
1343 WINED3DFMT_R5G6B5,
1344 WINED3DFMT_X1R5G5B5,
1345 /* 8 Bit */
1346 WINED3DFMT_R3G3B2,
1347 WINED3DFMT_P8,
1348 /* FOURCC codes - Not in this version*/
1351 TRACE("(%p)->(%p,%p): Relay\n", This, Callback, Arg);
1353 if(!Callback)
1354 return DDERR_INVALIDPARAMS;
1356 EnterCriticalSection(&ddraw_cs);
1358 memset(&mode, 0, sizeof(mode));
1359 hr = IWineD3DDevice_GetDisplayMode(This->ddraw->wineD3DDevice,
1361 &mode);
1362 if(FAILED(hr)) {
1363 LeaveCriticalSection(&ddraw_cs);
1364 WARN("Cannot get the current adapter format\n");
1365 return hr;
1368 for(i = 0; i < sizeof(FormatList) / sizeof(WINED3DFORMAT); i++)
1370 hr = IWineD3D_CheckDeviceFormat(This->ddraw->wineD3D,
1371 0 /* Adapter */,
1372 WINED3DDEVTYPE_HAL,
1373 mode.Format,
1374 0 /* Usage */,
1375 WINED3DRTYPE_TEXTURE,
1376 FormatList[i],
1377 SURFACE_OPENGL);
1378 if(hr == D3D_OK)
1380 DDSURFACEDESC sdesc;
1382 memset(&sdesc, 0, sizeof(sdesc));
1383 sdesc.dwSize = sizeof(sdesc);
1384 sdesc.dwFlags = DDSD_PIXELFORMAT | DDSD_CAPS;
1385 sdesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1386 sdesc.ddpfPixelFormat.dwSize = sizeof(sdesc.ddpfPixelFormat);
1387 PixelFormat_WineD3DtoDD(&sdesc.ddpfPixelFormat, FormatList[i]);
1389 TRACE("Enumerating WineD3DFormat %d\n", FormatList[i]);
1390 hr = Callback(&sdesc, Arg);
1391 if(hr != DDENUMRET_OK)
1393 TRACE("Format enumeration cancelled by application\n");
1394 LeaveCriticalSection(&ddraw_cs);
1395 return D3D_OK;
1399 TRACE("End of enumeration\n");
1400 LeaveCriticalSection(&ddraw_cs);
1401 return D3D_OK;
1404 static HRESULT WINAPI
1405 Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats(IDirect3DDevice *iface,
1406 LPD3DENUMTEXTUREFORMATSCALLBACK Callback,
1407 void *Arg)
1409 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1410 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice2 interface.\n", This, Callback, Arg);
1411 return IDirect3DDevice2_EnumTextureFormats(ICOM_INTERFACE(This, IDirect3DDevice2),
1412 Callback,
1413 Arg);
1416 /*****************************************************************************
1417 * IDirect3DDevice::CreateMatrix
1419 * Creates a matrix handle. A handle is created and memory for a D3DMATRIX is
1420 * allocated for the handle.
1422 * Version 1 only
1424 * Params
1425 * D3DMatHandle: Address to return the handle at
1427 * Returns:
1428 * D3D_OK on success
1429 * DDERR_INVALIDPARAMS if D3DMatHandle = NULL
1431 *****************************************************************************/
1432 static HRESULT WINAPI
1433 IDirect3DDeviceImpl_1_CreateMatrix(IDirect3DDevice *iface, D3DMATRIXHANDLE *D3DMatHandle)
1435 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1436 D3DMATRIX *Matrix;
1437 TRACE("(%p)->(%p)\n", This, D3DMatHandle);
1439 if(!D3DMatHandle)
1440 return DDERR_INVALIDPARAMS;
1442 Matrix = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(D3DMATRIX));
1443 if(!Matrix)
1445 ERR("Out of memory when allocating a D3DMATRIX\n");
1446 return DDERR_OUTOFMEMORY;
1449 EnterCriticalSection(&ddraw_cs);
1450 *D3DMatHandle = IDirect3DDeviceImpl_CreateHandle(This);
1451 if(!(*D3DMatHandle))
1453 ERR("Failed to create a matrix handle\n");
1454 HeapFree(GetProcessHeap(), 0, Matrix);
1455 LeaveCriticalSection(&ddraw_cs);
1456 return DDERR_OUTOFMEMORY;
1458 This->Handles[*D3DMatHandle - 1].ptr = Matrix;
1459 This->Handles[*D3DMatHandle - 1].type = DDrawHandle_Matrix;
1460 TRACE(" returning matrix handle %d\n", *D3DMatHandle);
1462 LeaveCriticalSection(&ddraw_cs);
1463 return D3D_OK;
1466 /*****************************************************************************
1467 * IDirect3DDevice::SetMatrix
1469 * Sets a matrix for a matrix handle. The matrix is copied into the memory
1470 * allocated for the handle
1472 * Version 1 only
1474 * Params:
1475 * D3DMatHandle: Handle to set the matrix to
1476 * D3DMatrix: Matrix to set
1478 * Returns:
1479 * D3D_OK on success
1480 * DDERR_INVALIDPARAMS if the handle of the matrix is invalid or the matrix
1481 * to set is NULL
1483 *****************************************************************************/
1484 static HRESULT WINAPI
1485 IDirect3DDeviceImpl_1_SetMatrix(IDirect3DDevice *iface,
1486 D3DMATRIXHANDLE D3DMatHandle,
1487 D3DMATRIX *D3DMatrix)
1489 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1490 TRACE("(%p)->(%08x,%p)\n", This, D3DMatHandle, D3DMatrix);
1492 if( (!D3DMatHandle) || (!D3DMatrix) )
1493 return DDERR_INVALIDPARAMS;
1495 EnterCriticalSection(&ddraw_cs);
1496 if(D3DMatHandle > This->numHandles)
1498 ERR("Handle %d out of range\n", D3DMatHandle);
1499 LeaveCriticalSection(&ddraw_cs);
1500 return DDERR_INVALIDPARAMS;
1502 else if(This->Handles[D3DMatHandle - 1].type != DDrawHandle_Matrix)
1504 ERR("Handle %d is not a matrix handle\n", D3DMatHandle);
1505 LeaveCriticalSection(&ddraw_cs);
1506 return DDERR_INVALIDPARAMS;
1509 if (TRACE_ON(d3d7))
1510 dump_D3DMATRIX(D3DMatrix);
1512 *((D3DMATRIX *) This->Handles[D3DMatHandle - 1].ptr) = *D3DMatrix;
1514 if(This->world == D3DMatHandle)
1516 IWineD3DDevice_SetTransform(This->wineD3DDevice,
1517 WINED3DTS_WORLDMATRIX(0),
1518 (WINED3DMATRIX *) D3DMatrix);
1520 if(This->view == D3DMatHandle)
1522 IWineD3DDevice_SetTransform(This->wineD3DDevice,
1523 WINED3DTS_VIEW,
1524 (WINED3DMATRIX *) D3DMatrix);
1526 if(This->proj == D3DMatHandle)
1528 IWineD3DDevice_SetTransform(This->wineD3DDevice,
1529 WINED3DTS_PROJECTION,
1530 (WINED3DMATRIX *) D3DMatrix);
1533 LeaveCriticalSection(&ddraw_cs);
1534 return D3D_OK;
1537 /*****************************************************************************
1538 * IDirect3DDevice::SetMatrix
1540 * Returns the content of a D3DMATRIX handle
1542 * Version 1 only
1544 * Params:
1545 * D3DMatHandle: Matrix handle to read the content from
1546 * D3DMatrix: Address to store the content at
1548 * Returns:
1549 * D3D_OK on success
1550 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid or D3DMatrix is NULL
1552 *****************************************************************************/
1553 static HRESULT WINAPI
1554 IDirect3DDeviceImpl_1_GetMatrix(IDirect3DDevice *iface,
1555 D3DMATRIXHANDLE D3DMatHandle,
1556 D3DMATRIX *D3DMatrix)
1558 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1559 TRACE("(%p)->(%08x,%p)\n", This, D3DMatHandle, D3DMatrix);
1561 if(!D3DMatrix)
1562 return DDERR_INVALIDPARAMS;
1563 if(!D3DMatHandle)
1564 return DDERR_INVALIDPARAMS;
1566 EnterCriticalSection(&ddraw_cs);
1567 if(D3DMatHandle > This->numHandles)
1569 ERR("Handle %d out of range\n", D3DMatHandle);
1570 LeaveCriticalSection(&ddraw_cs);
1571 return DDERR_INVALIDPARAMS;
1573 else if(This->Handles[D3DMatHandle - 1].type != DDrawHandle_Matrix)
1575 ERR("Handle %d is not a matrix handle\n", D3DMatHandle);
1576 LeaveCriticalSection(&ddraw_cs);
1577 return DDERR_INVALIDPARAMS;
1580 /* The handle is simply a pointer to a D3DMATRIX structure */
1581 *D3DMatrix = *((D3DMATRIX *) This->Handles[D3DMatHandle - 1].ptr);
1583 LeaveCriticalSection(&ddraw_cs);
1584 return D3D_OK;
1587 /*****************************************************************************
1588 * IDirect3DDevice::DeleteMatrix
1590 * Destroys a Matrix handle. Frees the memory and unsets the handle data
1592 * Version 1 only
1594 * Params:
1595 * D3DMatHandle: Handle to destroy
1597 * Returns:
1598 * D3D_OK on success
1599 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid
1601 *****************************************************************************/
1602 static HRESULT WINAPI
1603 IDirect3DDeviceImpl_1_DeleteMatrix(IDirect3DDevice *iface,
1604 D3DMATRIXHANDLE D3DMatHandle)
1606 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1607 TRACE("(%p)->(%08x)\n", This, D3DMatHandle);
1609 if(!D3DMatHandle)
1610 return DDERR_INVALIDPARAMS;
1612 EnterCriticalSection(&ddraw_cs);
1613 if(D3DMatHandle > This->numHandles)
1615 ERR("Handle %d out of range\n", D3DMatHandle);
1616 LeaveCriticalSection(&ddraw_cs);
1617 return DDERR_INVALIDPARAMS;
1619 else if(This->Handles[D3DMatHandle - 1].type != DDrawHandle_Matrix)
1621 ERR("Handle %d is not a matrix handle\n", D3DMatHandle);
1622 LeaveCriticalSection(&ddraw_cs);
1623 return DDERR_INVALIDPARAMS;
1626 HeapFree(GetProcessHeap(), 0, This->Handles[D3DMatHandle - 1].ptr);
1627 This->Handles[D3DMatHandle - 1].ptr = NULL;
1628 This->Handles[D3DMatHandle - 1].type = DDrawHandle_Unknown;
1630 LeaveCriticalSection(&ddraw_cs);
1631 return D3D_OK;
1634 /*****************************************************************************
1635 * IDirect3DDevice7::BeginScene
1637 * This method must be called before any rendering is performed.
1638 * IDirect3DDevice::EndScene has to be called after the scene is complete
1640 * Version 1, 2, 3 and 7
1642 * Returns:
1643 * D3D_OK on success, for details see IWineD3DDevice::BeginScene
1644 * D3DERR_SCENE_IN_SCENE if WineD3D returns an error(Only in case of an already
1645 * started scene).
1647 *****************************************************************************/
1648 static HRESULT
1649 IDirect3DDeviceImpl_7_BeginScene(IDirect3DDevice7 *iface)
1651 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1652 HRESULT hr;
1653 TRACE("(%p): Relay\n", This);
1655 EnterCriticalSection(&ddraw_cs);
1656 hr = IWineD3DDevice_BeginScene(This->wineD3DDevice);
1657 LeaveCriticalSection(&ddraw_cs);
1658 if(hr == WINED3D_OK) return D3D_OK;
1659 else return D3DERR_SCENE_IN_SCENE; /* TODO: Other possible causes of failure */
1662 static HRESULT WINAPI
1663 IDirect3DDeviceImpl_7_BeginScene_FPUSetup(IDirect3DDevice7 *iface)
1665 return IDirect3DDeviceImpl_7_BeginScene(iface);
1668 static HRESULT WINAPI
1669 IDirect3DDeviceImpl_7_BeginScene_FPUPreserve(IDirect3DDevice7 *iface)
1671 HRESULT hr;
1672 WORD old_fpucw;
1674 old_fpucw = d3d_fpu_setup();
1675 hr = IDirect3DDeviceImpl_7_BeginScene(iface);
1676 set_fpu_control_word(old_fpucw);
1678 return hr;
1681 static HRESULT WINAPI
1682 Thunk_IDirect3DDeviceImpl_3_BeginScene(IDirect3DDevice3 *iface)
1684 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1685 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1686 return IDirect3DDevice7_BeginScene(ICOM_INTERFACE(This, IDirect3DDevice7));
1689 static HRESULT WINAPI
1690 Thunk_IDirect3DDeviceImpl_2_BeginScene(IDirect3DDevice2 *iface)
1692 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1693 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1694 return IDirect3DDevice7_BeginScene(ICOM_INTERFACE(This, IDirect3DDevice7));
1697 static HRESULT WINAPI
1698 Thunk_IDirect3DDeviceImpl_1_BeginScene(IDirect3DDevice *iface)
1700 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1701 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1702 return IDirect3DDevice7_BeginScene(ICOM_INTERFACE(This, IDirect3DDevice7));
1705 /*****************************************************************************
1706 * IDirect3DDevice7::EndScene
1708 * Ends a scene that has been begun with IDirect3DDevice7::BeginScene.
1709 * This method must be called after rendering is finished.
1711 * Version 1, 2, 3 and 7
1713 * Returns:
1714 * D3D_OK on success, for details see IWineD3DDevice::EndScene
1715 * D3DERR_SCENE_NOT_IN_SCENE is returned if WineD3D returns an error. It does
1716 * that only if the scene was already ended.
1718 *****************************************************************************/
1719 static HRESULT
1720 IDirect3DDeviceImpl_7_EndScene(IDirect3DDevice7 *iface)
1722 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1723 HRESULT hr;
1724 TRACE("(%p): Relay\n", This);
1726 EnterCriticalSection(&ddraw_cs);
1727 hr = IWineD3DDevice_EndScene(This->wineD3DDevice);
1728 LeaveCriticalSection(&ddraw_cs);
1729 if(hr == WINED3D_OK) return D3D_OK;
1730 else return D3DERR_SCENE_NOT_IN_SCENE;
1733 static HRESULT WINAPI
1734 IDirect3DDeviceImpl_7_EndScene_FPUSetup(IDirect3DDevice7 *iface)
1736 return IDirect3DDeviceImpl_7_EndScene(iface);
1739 static HRESULT WINAPI
1740 IDirect3DDeviceImpl_7_EndScene_FPUPreserve(IDirect3DDevice7 *iface)
1742 HRESULT hr;
1743 WORD old_fpucw;
1745 old_fpucw = d3d_fpu_setup();
1746 hr = IDirect3DDeviceImpl_7_EndScene(iface);
1747 set_fpu_control_word(old_fpucw);
1749 return hr;
1752 static HRESULT WINAPI
1753 Thunk_IDirect3DDeviceImpl_3_EndScene(IDirect3DDevice3 *iface)
1755 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1756 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1757 return IDirect3DDevice7_EndScene(ICOM_INTERFACE(This, IDirect3DDevice7));
1760 static HRESULT WINAPI
1761 Thunk_IDirect3DDeviceImpl_2_EndScene(IDirect3DDevice2 *iface)
1763 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1764 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1765 return IDirect3DDevice7_EndScene(ICOM_INTERFACE(This, IDirect3DDevice7));
1768 static HRESULT WINAPI
1769 Thunk_IDirect3DDeviceImpl_1_EndScene(IDirect3DDevice *iface)
1771 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1772 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1773 return IDirect3DDevice7_EndScene(ICOM_INTERFACE(This, IDirect3DDevice7));
1776 /*****************************************************************************
1777 * IDirect3DDevice7::GetDirect3D
1779 * Returns the IDirect3D(= interface to the DirectDraw object) used to create
1780 * this device.
1782 * Params:
1783 * Direct3D7: Address to store the interface pointer at
1785 * Returns:
1786 * D3D_OK on success
1787 * DDERR_INVALIDPARAMS if Direct3D7 == NULL
1789 *****************************************************************************/
1790 static HRESULT WINAPI
1791 IDirect3DDeviceImpl_7_GetDirect3D(IDirect3DDevice7 *iface,
1792 IDirect3D7 **Direct3D7)
1794 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1795 TRACE("(%p)->(%p)\n", This, Direct3D7);
1797 if(!Direct3D7)
1798 return DDERR_INVALIDPARAMS;
1800 *Direct3D7 = ICOM_INTERFACE(This->ddraw, IDirect3D7);
1801 IDirect3D7_AddRef(*Direct3D7);
1803 TRACE(" returning interface %p\n", *Direct3D7);
1804 return D3D_OK;
1807 static HRESULT WINAPI
1808 Thunk_IDirect3DDeviceImpl_3_GetDirect3D(IDirect3DDevice3 *iface,
1809 IDirect3D3 **Direct3D3)
1811 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1812 HRESULT ret;
1813 IDirect3D7 *ret_ptr;
1815 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Direct3D3);
1816 ret = IDirect3DDevice7_GetDirect3D(ICOM_INTERFACE(This, IDirect3DDevice7),
1817 &ret_ptr);
1818 if(ret != D3D_OK)
1819 return ret;
1820 *Direct3D3 = COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D7, IDirect3D3, ret_ptr);
1821 TRACE(" returning interface %p\n", *Direct3D3);
1822 return D3D_OK;
1825 static HRESULT WINAPI
1826 Thunk_IDirect3DDeviceImpl_2_GetDirect3D(IDirect3DDevice2 *iface,
1827 IDirect3D2 **Direct3D2)
1829 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1830 HRESULT ret;
1831 IDirect3D7 *ret_ptr;
1833 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Direct3D2);
1834 ret = IDirect3DDevice7_GetDirect3D(ICOM_INTERFACE(This, IDirect3DDevice7),
1835 &ret_ptr);
1836 if(ret != D3D_OK)
1837 return ret;
1838 *Direct3D2 = COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D7, IDirect3D2, ret_ptr);
1839 TRACE(" returning interface %p\n", *Direct3D2);
1840 return D3D_OK;
1843 static HRESULT WINAPI
1844 Thunk_IDirect3DDeviceImpl_1_GetDirect3D(IDirect3DDevice *iface,
1845 IDirect3D **Direct3D)
1847 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1848 HRESULT ret;
1849 IDirect3D7 *ret_ptr;
1851 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Direct3D);
1852 ret = IDirect3DDevice7_GetDirect3D(ICOM_INTERFACE(This, IDirect3DDevice7),
1853 &ret_ptr);
1854 if(ret != D3D_OK)
1855 return ret;
1856 *Direct3D = COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D7, IDirect3D, ret_ptr);
1857 TRACE(" returning interface %p\n", *Direct3D);
1858 return D3D_OK;
1861 /*****************************************************************************
1862 * IDirect3DDevice3::SetCurrentViewport
1864 * Sets a Direct3DViewport as the current viewport.
1865 * For the thunks note that all viewport interface versions are equal
1867 * Params:
1868 * Direct3DViewport3: The viewport to set
1870 * Version 2 and 3
1872 * Returns:
1873 * D3D_OK on success
1874 * (Is a NULL viewport valid?)
1876 *****************************************************************************/
1877 static HRESULT WINAPI
1878 IDirect3DDeviceImpl_3_SetCurrentViewport(IDirect3DDevice3 *iface,
1879 IDirect3DViewport3 *Direct3DViewport3)
1881 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1882 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport3);
1883 TRACE("(%p)->(%p)\n", This, Direct3DViewport3);
1885 EnterCriticalSection(&ddraw_cs);
1886 /* Do nothing if the specified viewport is the same as the current one */
1887 if (This->current_viewport == vp )
1889 LeaveCriticalSection(&ddraw_cs);
1890 return D3D_OK;
1893 /* Should check if the viewport was added or not */
1895 /* Release previous viewport and AddRef the new one */
1896 if (This->current_viewport)
1898 TRACE("ViewportImpl is at %p, interface is at %p\n", This->current_viewport, ICOM_INTERFACE(This->current_viewport, IDirect3DViewport3));
1899 IDirect3DViewport3_Release( ICOM_INTERFACE(This->current_viewport, IDirect3DViewport3) );
1901 IDirect3DViewport3_AddRef(Direct3DViewport3);
1903 /* Set this viewport as the current viewport */
1904 This->current_viewport = vp;
1906 /* Activate this viewport */
1907 This->current_viewport->active_device = This;
1908 This->current_viewport->activate(This->current_viewport, FALSE);
1910 LeaveCriticalSection(&ddraw_cs);
1911 return D3D_OK;
1914 static HRESULT WINAPI
1915 Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport(IDirect3DDevice2 *iface,
1916 IDirect3DViewport2 *Direct3DViewport2)
1918 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1919 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport2);
1920 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
1921 return IDirect3DDevice3_SetCurrentViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
1922 ICOM_INTERFACE(vp, IDirect3DViewport3));
1925 /*****************************************************************************
1926 * IDirect3DDevice3::GetCurrentViewport
1928 * Returns the currently active viewport.
1930 * Version 2 and 3
1932 * Params:
1933 * Direct3DViewport3: Address to return the interface pointer at
1935 * Returns:
1936 * D3D_OK on success
1937 * DDERR_INVALIDPARAMS if Direct3DViewport == NULL
1939 *****************************************************************************/
1940 static HRESULT WINAPI
1941 IDirect3DDeviceImpl_3_GetCurrentViewport(IDirect3DDevice3 *iface,
1942 IDirect3DViewport3 **Direct3DViewport3)
1944 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1945 TRACE("(%p)->(%p)\n", This, Direct3DViewport3);
1947 if(!Direct3DViewport3)
1948 return DDERR_INVALIDPARAMS;
1950 EnterCriticalSection(&ddraw_cs);
1951 *Direct3DViewport3 = ICOM_INTERFACE(This->current_viewport, IDirect3DViewport3);
1953 /* AddRef the returned viewport */
1954 if(*Direct3DViewport3) IDirect3DViewport3_AddRef(*Direct3DViewport3);
1956 TRACE(" returning interface %p\n", *Direct3DViewport3);
1958 LeaveCriticalSection(&ddraw_cs);
1959 return D3D_OK;
1962 static HRESULT WINAPI
1963 Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport(IDirect3DDevice2 *iface,
1964 IDirect3DViewport2 **Direct3DViewport2)
1966 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1967 HRESULT hr;
1968 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, Direct3DViewport2);
1969 hr = IDirect3DDevice3_GetCurrentViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
1970 (IDirect3DViewport3 **) Direct3DViewport2);
1971 if(hr != D3D_OK) return hr;
1972 *Direct3DViewport2 = (IDirect3DViewport2 *) COM_INTERFACE_CAST(IDirect3DViewportImpl, IDirect3DViewport3, IDirect3DViewport3, *Direct3DViewport2);
1973 return D3D_OK;
1976 /*****************************************************************************
1977 * IDirect3DDevice7::SetRenderTarget
1979 * Sets the render target for the Direct3DDevice.
1980 * For the thunks note that IDirectDrawSurface7 == IDirectDrawSurface4 and
1981 * IDirectDrawSurface3 == IDirectDrawSurface
1983 * Version 2, 3 and 7
1985 * Params:
1986 * NewTarget: Pointer to an IDirectDrawSurface7 interface to set as the new
1987 * render target
1988 * Flags: Some flags
1990 * Returns:
1991 * D3D_OK on success, for details see IWineD3DDevice::SetRenderTarget
1993 *****************************************************************************/
1994 static HRESULT
1995 IDirect3DDeviceImpl_7_SetRenderTarget(IDirect3DDevice7 *iface,
1996 IDirectDrawSurface7 *NewTarget,
1997 DWORD Flags)
1999 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
2000 IDirectDrawSurfaceImpl *Target = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, NewTarget);
2001 HRESULT hr;
2002 TRACE("(%p)->(%p,%08x): Relay\n", This, NewTarget, Flags);
2004 EnterCriticalSection(&ddraw_cs);
2005 /* Flags: Not used */
2007 if(This->target == Target)
2009 TRACE("No-op SetRenderTarget operation, not doing anything\n");
2010 LeaveCriticalSection(&ddraw_cs);
2011 return D3D_OK;
2014 hr = IWineD3DDevice_SetRenderTarget(This->wineD3DDevice,
2016 Target ? Target->WineD3DSurface : NULL);
2017 if(hr != D3D_OK)
2019 LeaveCriticalSection(&ddraw_cs);
2020 return hr;
2022 IDirectDrawSurface7_AddRef(NewTarget);
2023 IDirectDrawSurface7_Release(ICOM_INTERFACE(This->target, IDirectDrawSurface7));
2024 This->target = Target;
2025 IDirect3DDeviceImpl_UpdateDepthStencil(This);
2026 LeaveCriticalSection(&ddraw_cs);
2027 return D3D_OK;
2030 static HRESULT WINAPI
2031 IDirect3DDeviceImpl_7_SetRenderTarget_FPUSetup(IDirect3DDevice7 *iface,
2032 IDirectDrawSurface7 *NewTarget,
2033 DWORD Flags)
2035 return IDirect3DDeviceImpl_7_SetRenderTarget(iface, NewTarget, Flags);
2038 static HRESULT WINAPI
2039 IDirect3DDeviceImpl_7_SetRenderTarget_FPUPreserve(IDirect3DDevice7 *iface,
2040 IDirectDrawSurface7 *NewTarget,
2041 DWORD Flags)
2043 HRESULT hr;
2044 WORD old_fpucw;
2046 old_fpucw = d3d_fpu_setup();
2047 hr = IDirect3DDeviceImpl_7_SetRenderTarget(iface, NewTarget, Flags);
2048 set_fpu_control_word(old_fpucw);
2050 return hr;
2053 static HRESULT WINAPI
2054 Thunk_IDirect3DDeviceImpl_3_SetRenderTarget(IDirect3DDevice3 *iface,
2055 IDirectDrawSurface4 *NewRenderTarget,
2056 DWORD Flags)
2058 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2059 IDirectDrawSurfaceImpl *Target = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, NewRenderTarget);
2060 TRACE_(ddraw_thunk)("(%p)->(%p,%08x) thunking to IDirect3DDevice7 interface.\n", This, Target, Flags);
2061 return IDirect3DDevice7_SetRenderTarget(ICOM_INTERFACE(This, IDirect3DDevice7),
2062 ICOM_INTERFACE(Target, IDirectDrawSurface7),
2063 Flags);
2066 static HRESULT WINAPI
2067 Thunk_IDirect3DDeviceImpl_2_SetRenderTarget(IDirect3DDevice2 *iface,
2068 IDirectDrawSurface *NewRenderTarget,
2069 DWORD Flags)
2071 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2072 IDirectDrawSurfaceImpl *Target = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface3, NewRenderTarget);
2073 TRACE_(ddraw_thunk)("(%p)->(%p,%08x) thunking to IDirect3DDevice7 interface.\n", This, Target, Flags);
2074 return IDirect3DDevice7_SetRenderTarget(ICOM_INTERFACE(This, IDirect3DDevice7),
2075 ICOM_INTERFACE(Target, IDirectDrawSurface7),
2076 Flags);
2079 /*****************************************************************************
2080 * IDirect3DDevice7::GetRenderTarget
2082 * Returns the current render target.
2083 * This is handled locally, because the WineD3D render target's parent
2084 * is an IParent
2086 * Version 2, 3 and 7
2088 * Params:
2089 * RenderTarget: Address to store the surface interface pointer
2091 * Returns:
2092 * D3D_OK on success
2093 * DDERR_INVALIDPARAMS if RenderTarget == NULL
2095 *****************************************************************************/
2096 static HRESULT WINAPI
2097 IDirect3DDeviceImpl_7_GetRenderTarget(IDirect3DDevice7 *iface,
2098 IDirectDrawSurface7 **RenderTarget)
2100 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
2101 TRACE("(%p)->(%p): Relay\n", This, RenderTarget);
2103 if(!RenderTarget)
2104 return DDERR_INVALIDPARAMS;
2106 EnterCriticalSection(&ddraw_cs);
2107 *RenderTarget = ICOM_INTERFACE(This->target, IDirectDrawSurface7);
2108 IDirectDrawSurface7_AddRef(*RenderTarget);
2110 LeaveCriticalSection(&ddraw_cs);
2111 return D3D_OK;
2114 static HRESULT WINAPI
2115 Thunk_IDirect3DDeviceImpl_3_GetRenderTarget(IDirect3DDevice3 *iface,
2116 IDirectDrawSurface4 **RenderTarget)
2118 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2119 HRESULT hr;
2120 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, RenderTarget);
2121 hr = IDirect3DDevice7_GetRenderTarget(ICOM_INTERFACE(This, IDirect3DDevice7),
2122 (IDirectDrawSurface7 **) RenderTarget);
2123 if(hr != D3D_OK) return hr;
2124 *RenderTarget = (IDirectDrawSurface4 *) COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7, IDirectDrawSurface7, *RenderTarget);
2125 return D3D_OK;
2128 static HRESULT WINAPI
2129 Thunk_IDirect3DDeviceImpl_2_GetRenderTarget(IDirect3DDevice2 *iface,
2130 IDirectDrawSurface **RenderTarget)
2132 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2133 HRESULT hr;
2134 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, RenderTarget);
2135 hr = IDirect3DDevice7_GetRenderTarget(ICOM_INTERFACE(This, IDirect3DDevice7),
2136 (IDirectDrawSurface7 **) RenderTarget);
2137 if(hr != D3D_OK) return hr;
2138 *RenderTarget = (IDirectDrawSurface *) COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7, IDirectDrawSurface3, *RenderTarget);
2139 return D3D_OK;
2142 /*****************************************************************************
2143 * IDirect3DDevice3::Begin
2145 * Begins a description block of vertices. This is similar to glBegin()
2146 * and glEnd(). After a call to IDirect3DDevice3::End, the vertices
2147 * described with IDirect3DDevice::Vertex are drawn.
2149 * Version 2 and 3
2151 * Params:
2152 * PrimitiveType: The type of primitives to draw
2153 * VertexTypeDesc: A flexible vertex format description of the vertices
2154 * Flags: Some flags..
2156 * Returns:
2157 * D3D_OK on success
2159 *****************************************************************************/
2160 static HRESULT WINAPI
2161 IDirect3DDeviceImpl_3_Begin(IDirect3DDevice3 *iface,
2162 D3DPRIMITIVETYPE PrimitiveType,
2163 DWORD VertexTypeDesc,
2164 DWORD Flags)
2166 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2167 TRACE("(%p)->(%d,%d,%08x)\n", This, PrimitiveType, VertexTypeDesc, Flags);
2169 EnterCriticalSection(&ddraw_cs);
2170 This->primitive_type = PrimitiveType;
2171 This->vertex_type = VertexTypeDesc;
2172 This->render_flags = Flags;
2173 This->vertex_size = get_flexible_vertex_size(This->vertex_type);
2174 This->nb_vertices = 0;
2175 LeaveCriticalSection(&ddraw_cs);
2177 return D3D_OK;
2180 static HRESULT WINAPI
2181 Thunk_IDirect3DDeviceImpl_2_Begin(IDirect3DDevice2 *iface,
2182 D3DPRIMITIVETYPE d3dpt,
2183 D3DVERTEXTYPE dwVertexTypeDesc,
2184 DWORD dwFlags)
2186 DWORD FVF;
2187 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2188 TRACE_(ddraw_thunk)("(%p/%p)->(%08x,%08x,%08x): Thunking to IDirect3DDevice3\n", This, iface, d3dpt, dwVertexTypeDesc, dwFlags);
2190 switch(dwVertexTypeDesc)
2192 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
2193 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
2194 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
2195 default:
2196 ERR("Unexpected vertex type %d\n", dwVertexTypeDesc);
2197 return DDERR_INVALIDPARAMS; /* Should never happen */
2200 return IDirect3DDevice3_Begin(ICOM_INTERFACE(This, IDirect3DDevice3),
2201 d3dpt,
2202 FVF,
2203 dwFlags);
2206 /*****************************************************************************
2207 * IDirect3DDevice3::BeginIndexed
2209 * Draws primitives based on vertices in a vertex array which are specified
2210 * by indices.
2212 * Version 2 and 3
2214 * Params:
2215 * PrimitiveType: Primitive type to draw
2216 * VertexType: A FVF description of the vertex format
2217 * Vertices: pointer to an array containing the vertices
2218 * NumVertices: The number of vertices in the vertex array
2219 * Flags: Some flags ...
2221 * Returns:
2222 * D3D_OK, because it's a stub
2224 *****************************************************************************/
2225 static HRESULT WINAPI
2226 IDirect3DDeviceImpl_3_BeginIndexed(IDirect3DDevice3 *iface,
2227 D3DPRIMITIVETYPE PrimitiveType,
2228 DWORD VertexType,
2229 void *Vertices,
2230 DWORD NumVertices,
2231 DWORD Flags)
2233 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2234 FIXME("(%p)->(%08x,%08x,%p,%08x,%08x): stub!\n", This, PrimitiveType, VertexType, Vertices, NumVertices, Flags);
2235 return D3D_OK;
2239 static HRESULT WINAPI
2240 Thunk_IDirect3DDeviceImpl_2_BeginIndexed(IDirect3DDevice2 *iface,
2241 D3DPRIMITIVETYPE d3dptPrimitiveType,
2242 D3DVERTEXTYPE d3dvtVertexType,
2243 void *lpvVertices,
2244 DWORD dwNumVertices,
2245 DWORD dwFlags)
2247 DWORD FVF;
2248 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2249 TRACE_(ddraw_thunk)("(%p/%p)->(%08x,%08x,%p,%08x,%08x): Thunking to IDirect3DDevice3\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwNumVertices, dwFlags);
2251 switch(d3dvtVertexType)
2253 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
2254 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
2255 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
2256 default:
2257 ERR("Unexpected vertex type %d\n", d3dvtVertexType);
2258 return DDERR_INVALIDPARAMS; /* Should never happen */
2261 return IDirect3DDevice3_BeginIndexed(ICOM_INTERFACE(This,IDirect3DDevice3),
2262 d3dptPrimitiveType,
2263 FVF,
2264 lpvVertices,
2265 dwNumVertices,
2266 dwFlags);
2269 /*****************************************************************************
2270 * IDirect3DDevice3::Vertex
2272 * Draws a vertex as described by IDirect3DDevice3::Begin. It places all
2273 * drawn vertices in a vertex buffer. If the buffer is too small, its
2274 * size is increased.
2276 * Version 2 and 3
2278 * Params:
2279 * Vertex: Pointer to the vertex
2281 * Returns:
2282 * D3D_OK, on success
2283 * DDERR_INVALIDPARAMS if Vertex is NULL
2285 *****************************************************************************/
2286 static HRESULT WINAPI
2287 IDirect3DDeviceImpl_3_Vertex(IDirect3DDevice3 *iface,
2288 void *Vertex)
2290 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2291 TRACE("(%p)->(%p)\n", This, Vertex);
2293 if(!Vertex)
2294 return DDERR_INVALIDPARAMS;
2296 EnterCriticalSection(&ddraw_cs);
2297 if ((This->nb_vertices+1)*This->vertex_size > This->buffer_size)
2299 BYTE *old_buffer;
2300 This->buffer_size = This->buffer_size ? This->buffer_size * 2 : This->vertex_size * 3;
2301 old_buffer = This->vertex_buffer;
2302 This->vertex_buffer = HeapAlloc(GetProcessHeap(), 0, This->buffer_size);
2303 if (old_buffer)
2305 CopyMemory(This->vertex_buffer, old_buffer, This->nb_vertices * This->vertex_size);
2306 HeapFree(GetProcessHeap(), 0, old_buffer);
2310 CopyMemory(This->vertex_buffer + This->nb_vertices++ * This->vertex_size, Vertex, This->vertex_size);
2312 LeaveCriticalSection(&ddraw_cs);
2313 return D3D_OK;
2316 static HRESULT WINAPI
2317 Thunk_IDirect3DDeviceImpl_2_Vertex(IDirect3DDevice2 *iface,
2318 void *lpVertexType)
2320 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2321 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, lpVertexType);
2322 return IDirect3DDevice3_Vertex(ICOM_INTERFACE(This, IDirect3DDevice3),
2323 lpVertexType);
2326 /*****************************************************************************
2327 * IDirect3DDevice3::Index
2329 * Specifies an index to a vertex to be drawn. The vertex array has to
2330 * be specified with BeginIndexed first.
2332 * Parameters:
2333 * VertexIndex: The index of the vertex to draw
2335 * Returns:
2336 * D3D_OK because it's a stub
2338 *****************************************************************************/
2339 static HRESULT WINAPI
2340 IDirect3DDeviceImpl_3_Index(IDirect3DDevice3 *iface,
2341 WORD VertexIndex)
2343 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2344 FIXME("(%p)->(%04x): stub!\n", This, VertexIndex);
2345 return D3D_OK;
2348 static HRESULT WINAPI
2349 Thunk_IDirect3DDeviceImpl_2_Index(IDirect3DDevice2 *iface,
2350 WORD wVertexIndex)
2352 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2353 TRACE_(ddraw_thunk)("(%p)->(%04x) thunking to IDirect3DDevice3 interface.\n", This, wVertexIndex);
2354 return IDirect3DDevice3_Index(ICOM_INTERFACE(This, IDirect3DDevice3),
2355 wVertexIndex);
2358 /*****************************************************************************
2359 * IDirect3DDevice3::End
2361 * Ends a draw begun with IDirect3DDevice3::Begin or
2362 * IDirect3DDevice::BeginIndexed. The vertices specified with
2363 * IDirect3DDevice::Vertex or IDirect3DDevice::Index are drawn using
2364 * the IDirect3DDevice7::DrawPrimitive method. So far only
2365 * non-indexed mode is supported
2367 * Version 2 and 3
2369 * Params:
2370 * Flags: Some flags, as usual. Don't know which are defined
2372 * Returns:
2373 * The return value of IDirect3DDevice7::DrawPrimitive
2375 *****************************************************************************/
2376 static HRESULT WINAPI
2377 IDirect3DDeviceImpl_3_End(IDirect3DDevice3 *iface,
2378 DWORD Flags)
2380 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2381 TRACE("(%p)->(%08x)\n", This, Flags);
2383 return IDirect3DDevice7_DrawPrimitive(ICOM_INTERFACE(This, IDirect3DDevice7),
2384 This->primitive_type, This->vertex_type,
2385 This->vertex_buffer, This->nb_vertices,
2386 This->render_flags);
2389 static HRESULT WINAPI
2390 Thunk_IDirect3DDeviceImpl_2_End(IDirect3DDevice2 *iface,
2391 DWORD dwFlags)
2393 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2394 TRACE_(ddraw_thunk)("(%p)->(%08x) thunking to IDirect3DDevice3 interface.\n", This, dwFlags);
2395 return IDirect3DDevice3_End(ICOM_INTERFACE(This, IDirect3DDevice3),
2396 dwFlags);
2399 /*****************************************************************************
2400 * IDirect3DDevice7::GetRenderState
2402 * Returns the value of a render state. The possible render states are
2403 * defined in include/d3dtypes.h
2405 * Version 2, 3 and 7
2407 * Params:
2408 * RenderStateType: Render state to return the current setting of
2409 * Value: Address to store the value at
2411 * Returns:
2412 * D3D_OK on success, for details see IWineD3DDevice::GetRenderState
2413 * DDERR_INVALIDPARAMS if Value == NULL
2415 *****************************************************************************/
2416 static HRESULT
2417 IDirect3DDeviceImpl_7_GetRenderState(IDirect3DDevice7 *iface,
2418 D3DRENDERSTATETYPE RenderStateType,
2419 DWORD *Value)
2421 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
2422 HRESULT hr;
2423 TRACE("(%p)->(%08x,%p): Relay\n", This, RenderStateType, Value);
2425 if(!Value)
2426 return DDERR_INVALIDPARAMS;
2428 EnterCriticalSection(&ddraw_cs);
2429 switch(RenderStateType)
2431 case D3DRENDERSTATE_TEXTUREMAG:
2433 WINED3DTEXTUREFILTERTYPE tex_mag;
2435 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2436 0, WINED3DSAMP_MAGFILTER,
2437 &tex_mag);
2439 switch (tex_mag)
2441 case WINED3DTEXF_POINT:
2442 *Value = D3DFILTER_NEAREST;
2443 break;
2444 case WINED3DTEXF_LINEAR:
2445 *Value = D3DFILTER_LINEAR;
2446 break;
2447 default:
2448 ERR("Unhandled texture mag %d !\n",tex_mag);
2449 *Value = 0;
2451 break;
2454 case D3DRENDERSTATE_TEXTUREMIN:
2456 WINED3DTEXTUREFILTERTYPE tex_min;
2458 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2459 0, WINED3DSAMP_MINFILTER,
2460 &tex_min);
2462 switch (tex_min)
2464 case WINED3DTEXF_POINT:
2465 *Value = D3DFILTER_NEAREST;
2466 break;
2467 case WINED3DTEXF_LINEAR:
2468 *Value = D3DFILTER_LINEAR;
2469 break;
2470 default:
2471 ERR("Unhandled texture mag %d !\n",tex_min);
2472 *Value = 0;
2474 break;
2477 case D3DRENDERSTATE_TEXTUREADDRESS:
2478 case D3DRENDERSTATE_TEXTUREADDRESSU:
2479 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2480 0, WINED3DSAMP_ADDRESSU,
2481 Value);
2482 break;
2483 case D3DRENDERSTATE_TEXTUREADDRESSV:
2484 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2485 0, WINED3DSAMP_ADDRESSV,
2486 Value);
2487 break;
2489 default:
2490 /* FIXME: Unhandled: D3DRENDERSTATE_STIPPLEPATTERN00 - 31 */
2491 hr = IWineD3DDevice_GetRenderState(This->wineD3DDevice,
2492 RenderStateType,
2493 Value);
2495 LeaveCriticalSection(&ddraw_cs);
2496 return hr;
2499 static HRESULT WINAPI
2500 IDirect3DDeviceImpl_7_GetRenderState_FPUSetup(IDirect3DDevice7 *iface,
2501 D3DRENDERSTATETYPE RenderStateType,
2502 DWORD *Value)
2504 return IDirect3DDeviceImpl_7_GetRenderState(iface, RenderStateType, Value);
2507 static HRESULT WINAPI
2508 IDirect3DDeviceImpl_7_GetRenderState_FPUPreserve(IDirect3DDevice7 *iface,
2509 D3DRENDERSTATETYPE RenderStateType,
2510 DWORD *Value)
2512 HRESULT hr;
2513 WORD old_fpucw;
2515 old_fpucw = d3d_fpu_setup();
2516 hr = IDirect3DDeviceImpl_7_GetRenderState(iface, RenderStateType, Value);
2517 set_fpu_control_word(old_fpucw);
2519 return hr;
2522 static HRESULT WINAPI
2523 IDirect3DDeviceImpl_3_GetRenderState(IDirect3DDevice3 *iface,
2524 D3DRENDERSTATETYPE dwRenderStateType,
2525 DWORD *lpdwRenderState)
2527 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2528 HRESULT hr;
2529 TRACE("(%p)->(%08x,%p)\n", This, dwRenderStateType, lpdwRenderState);
2531 switch(dwRenderStateType)
2533 case D3DRENDERSTATE_TEXTUREHANDLE:
2535 /* This state is wrapped to SetTexture in SetRenderState, so
2536 * it has to be wrapped to GetTexture here
2538 IWineD3DBaseTexture *tex = NULL;
2539 *lpdwRenderState = 0;
2541 EnterCriticalSection(&ddraw_cs);
2543 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice,
2545 &tex);
2547 if(hr == WINED3D_OK && tex)
2549 IDirectDrawSurface7 *parent = NULL;
2550 hr = IWineD3DBaseTexture_GetParent(tex,
2551 (IUnknown **) &parent);
2552 if(parent)
2554 /* The parent of the texture is the IDirectDrawSurface7 interface
2555 * of the ddraw surface
2557 IDirectDrawSurfaceImpl *texImpl = ICOM_OBJECT(IDirectDrawSurfaceImpl,
2558 IDirectDrawSurface7,
2559 parent);
2560 *lpdwRenderState = texImpl->Handle;
2561 IDirectDrawSurface7_Release(parent);
2563 IWineD3DBaseTexture_Release(tex);
2566 LeaveCriticalSection(&ddraw_cs);
2568 return hr;
2571 case D3DRENDERSTATE_TEXTUREMAPBLEND:
2573 /* D3DRENDERSTATE_TEXTUREMAPBLEND is mapped to texture state stages in SetRenderState; reverse
2574 the mapping to get the value. */
2575 DWORD colorop, colorarg1, colorarg2;
2576 DWORD alphaop, alphaarg1, alphaarg2;
2578 EnterCriticalSection(&ddraw_cs);
2580 This->legacyTextureBlending = TRUE;
2582 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, &colorop);
2583 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, &colorarg1);
2584 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, &colorarg2);
2585 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, &alphaop);
2586 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, &alphaarg1);
2587 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, &alphaarg2);
2589 if (colorop == WINED3DTOP_SELECTARG1 && colorarg1 == WINED3DTA_TEXTURE &&
2590 alphaop == WINED3DTOP_SELECTARG1 && alphaarg1 == WINED3DTA_TEXTURE)
2592 *lpdwRenderState = D3DTBLEND_DECAL;
2594 else if (colorop == WINED3DTOP_SELECTARG1 && colorarg1 == WINED3DTA_TEXTURE &&
2595 alphaop == WINED3DTOP_MODULATE && alphaarg1 == WINED3DTA_TEXTURE && alphaarg2 == WINED3DTA_CURRENT)
2597 *lpdwRenderState = D3DTBLEND_DECALALPHA;
2599 else if (colorop == WINED3DTOP_MODULATE && colorarg1 == WINED3DTA_TEXTURE && colorarg2 == WINED3DTA_CURRENT &&
2600 alphaop == WINED3DTOP_MODULATE && alphaarg1 == WINED3DTA_TEXTURE && alphaarg2 == WINED3DTA_CURRENT)
2602 *lpdwRenderState = D3DTBLEND_MODULATEALPHA;
2604 else
2606 HRESULT hr;
2607 BOOL tex_alpha = FALSE;
2608 IWineD3DBaseTexture *tex = NULL;
2609 WINED3DSURFACE_DESC desc;
2610 WINED3DFORMAT fmt;
2611 DDPIXELFORMAT ddfmt;
2613 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice,
2615 &tex);
2617 if(hr == WINED3D_OK && tex)
2619 memset(&desc, 0, sizeof(desc));
2620 desc.Format = &fmt;
2621 hr = IWineD3DTexture_GetLevelDesc((IWineD3DTexture*) tex, 0, &desc);
2622 if (SUCCEEDED(hr))
2624 ddfmt.dwSize = sizeof(ddfmt);
2625 PixelFormat_WineD3DtoDD(&ddfmt, fmt);
2626 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
2629 IWineD3DBaseTexture_Release(tex);
2632 if (!(colorop == WINED3DTOP_MODULATE && colorarg1 == WINED3DTA_TEXTURE && colorarg2 == WINED3DTA_CURRENT &&
2633 alphaop == WINED3DTOP_SELECTARG1 && alphaarg1 == (tex_alpha ? WINED3DTA_TEXTURE : WINED3DTA_CURRENT)))
2635 ERR("Unexpected texture stage state setup, returning D3DTBLEND_MODULATE - likely erroneous\n");
2638 *lpdwRenderState = D3DTBLEND_MODULATE;
2641 LeaveCriticalSection(&ddraw_cs);
2643 return D3D_OK;
2646 default:
2647 return IDirect3DDevice7_GetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
2648 dwRenderStateType,
2649 lpdwRenderState);
2653 static HRESULT WINAPI
2654 Thunk_IDirect3DDeviceImpl_2_GetRenderState(IDirect3DDevice2 *iface,
2655 D3DRENDERSTATETYPE dwRenderStateType,
2656 DWORD *lpdwRenderState)
2658 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2659 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice3 interface.\n", This, dwRenderStateType, lpdwRenderState);
2660 return IDirect3DDevice3_GetRenderState(ICOM_INTERFACE(This, IDirect3DDevice3),
2661 dwRenderStateType,
2662 lpdwRenderState);
2665 /*****************************************************************************
2666 * IDirect3DDevice7::SetRenderState
2668 * Sets a render state. The possible render states are defined in
2669 * include/d3dtypes.h
2671 * Version 2, 3 and 7
2673 * Params:
2674 * RenderStateType: State to set
2675 * Value: Value to assign to that state
2677 * Returns:
2678 * D3D_OK on success,
2679 * for details see IWineD3DDevice::SetRenderState
2681 *****************************************************************************/
2682 static HRESULT
2683 IDirect3DDeviceImpl_7_SetRenderState(IDirect3DDevice7 *iface,
2684 D3DRENDERSTATETYPE RenderStateType,
2685 DWORD Value)
2687 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
2688 HRESULT hr;
2689 TRACE("(%p)->(%08x,%d): Relay\n", This, RenderStateType, Value);
2691 EnterCriticalSection(&ddraw_cs);
2692 /* Some render states need special care */
2693 switch(RenderStateType)
2695 case D3DRENDERSTATE_TEXTUREMAG:
2697 WINED3DTEXTUREFILTERTYPE tex_mag = WINED3DTEXF_NONE;
2699 switch ((D3DTEXTUREFILTER) Value)
2701 case D3DFILTER_NEAREST:
2702 case D3DFILTER_LINEARMIPNEAREST:
2703 tex_mag = WINED3DTEXF_POINT;
2704 break;
2705 case D3DFILTER_LINEAR:
2706 case D3DFILTER_LINEARMIPLINEAR:
2707 tex_mag = WINED3DTEXF_LINEAR;
2708 break;
2709 default:
2710 ERR("Unhandled texture mag %d !\n",Value);
2713 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2714 0, WINED3DSAMP_MAGFILTER,
2715 tex_mag);
2716 break;
2719 case D3DRENDERSTATE_TEXTUREMIN:
2721 WINED3DTEXTUREFILTERTYPE tex_min = WINED3DTEXF_NONE;
2722 WINED3DTEXTUREFILTERTYPE tex_mip = WINED3DTEXF_NONE;
2724 switch ((D3DTEXTUREFILTER) Value)
2726 case D3DFILTER_NEAREST:
2727 tex_min = WINED3DTEXF_POINT;
2728 break;
2729 case D3DFILTER_LINEAR:
2730 tex_min = WINED3DTEXF_LINEAR;
2731 break;
2732 case D3DFILTER_MIPNEAREST:
2733 tex_min = WINED3DTEXF_NONE;
2734 tex_mip = WINED3DTEXF_POINT;
2735 break;
2736 case D3DFILTER_MIPLINEAR:
2737 tex_min = WINED3DTEXF_NONE;
2738 tex_mip = WINED3DTEXF_LINEAR;
2739 break;
2740 case D3DFILTER_LINEARMIPNEAREST:
2741 tex_min = WINED3DTEXF_POINT;
2742 tex_mip = WINED3DTEXF_LINEAR;
2743 break;
2744 case D3DFILTER_LINEARMIPLINEAR:
2745 tex_min = WINED3DTEXF_LINEAR;
2746 tex_mip = WINED3DTEXF_LINEAR;
2747 break;
2749 default:
2750 ERR("Unhandled texture min %d !\n",Value);
2753 IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2754 0, WINED3DSAMP_MIPFILTER,
2755 tex_mip);
2756 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2757 0, WINED3DSAMP_MINFILTER,
2758 tex_min);
2759 break;
2762 case D3DRENDERSTATE_TEXTUREADDRESS:
2763 IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2764 0, WINED3DSAMP_ADDRESSV,
2765 Value);
2766 /* Drop through */
2767 case D3DRENDERSTATE_TEXTUREADDRESSU:
2768 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2769 0, WINED3DSAMP_ADDRESSU,
2770 Value);
2771 break;
2772 case D3DRENDERSTATE_TEXTUREADDRESSV:
2773 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2774 0, WINED3DSAMP_ADDRESSV,
2775 Value);
2776 break;
2778 default:
2780 /* FIXME: Unhandled: D3DRENDERSTATE_STIPPLEPATTERN00 - 31 */
2782 hr = IWineD3DDevice_SetRenderState(This->wineD3DDevice,
2783 RenderStateType,
2784 Value);
2785 break;
2787 LeaveCriticalSection(&ddraw_cs);
2788 return hr;
2791 static HRESULT WINAPI
2792 IDirect3DDeviceImpl_7_SetRenderState_FPUSetup(IDirect3DDevice7 *iface,
2793 D3DRENDERSTATETYPE RenderStateType,
2794 DWORD Value)
2796 return IDirect3DDeviceImpl_7_SetRenderState(iface, RenderStateType, Value);
2799 static HRESULT WINAPI
2800 IDirect3DDeviceImpl_7_SetRenderState_FPUPreserve(IDirect3DDevice7 *iface,
2801 D3DRENDERSTATETYPE RenderStateType,
2802 DWORD Value)
2804 HRESULT hr;
2805 WORD old_fpucw;
2807 old_fpucw = d3d_fpu_setup();
2808 hr = IDirect3DDeviceImpl_7_SetRenderState(iface, RenderStateType, Value);
2809 set_fpu_control_word(old_fpucw);
2811 return hr;
2814 static HRESULT WINAPI
2815 IDirect3DDeviceImpl_3_SetRenderState(IDirect3DDevice3 *iface,
2816 D3DRENDERSTATETYPE RenderStateType,
2817 DWORD Value)
2819 /* Note about D3DRENDERSTATE_TEXTUREMAPBLEND implementation: most of values
2820 for this state can be directly mapped to texture stage colorop and alphaop, but
2821 D3DTBLEND_MODULATE is tricky: it uses alpha from texture when available and alpha
2822 from diffuse otherwise. So changing the texture must be monitored in SetTexture to modify
2823 alphaarg when needed.
2825 Aliens vs Predator 1 depends on accurate D3DTBLEND_MODULATE emulation
2827 Legacy texture blending (TEXTUREMAPBLEND) and texture stage states: directx6 docs state that
2828 TEXTUREMAPBLEND is deprecated, yet can still be used. Games must not use both or results
2829 are undefined. D3DTBLEND_MODULATE mode in particular is dependent on texture pixel format and
2830 requires fixup of stage 0 texture states when texture changes, but this fixup can interfere
2831 with games not using this deprecated state. So a flag 'legacyTextureBlending' has to be kept
2832 in device - TRUE if the app is using TEXTUREMAPBLEND.
2834 Tests show that setting TEXTUREMAPBLEND on native doesn't seem to change values returned by
2835 GetTextureStageState and vice versa. Not so on Wine, but it is 'undefined' anyway so, probably, ok,
2836 unless some broken game will be found that cares. */
2838 HRESULT hr;
2839 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2840 TRACE("(%p)->(%08x,%d)\n", This, RenderStateType, Value);
2842 EnterCriticalSection(&ddraw_cs);
2844 switch(RenderStateType)
2846 case D3DRENDERSTATE_TEXTUREHANDLE:
2848 if(Value == 0)
2850 hr = IWineD3DDevice_SetTexture(This->wineD3DDevice,
2852 NULL);
2853 break;
2856 if(Value > This->numHandles)
2858 FIXME("Specified handle %d out of range\n", Value);
2859 hr = DDERR_INVALIDPARAMS;
2860 break;
2862 if(This->Handles[Value - 1].type != DDrawHandle_Texture)
2864 FIXME("Handle %d isn't a texture handle\n", Value);
2865 hr = DDERR_INVALIDPARAMS;
2866 break;
2868 else
2870 IDirectDrawSurfaceImpl *surf = (IDirectDrawSurfaceImpl *) This->Handles[Value - 1].ptr;
2871 hr = IDirect3DDevice3_SetTexture(iface, 0, ICOM_INTERFACE(surf, IDirect3DTexture2));
2872 break;
2876 case D3DRENDERSTATE_TEXTUREMAPBLEND:
2878 This->legacyTextureBlending = TRUE;
2880 switch ( (D3DTEXTUREBLEND) Value)
2882 case D3DTBLEND_MODULATE:
2884 BOOL tex_alpha = FALSE;
2885 IWineD3DBaseTexture *tex = NULL;
2886 WINED3DSURFACE_DESC desc;
2887 WINED3DFORMAT fmt;
2888 DDPIXELFORMAT ddfmt;
2890 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice,
2892 &tex);
2894 if(hr == WINED3D_OK && tex)
2896 memset(&desc, 0, sizeof(desc));
2897 desc.Format = &fmt;
2898 hr = IWineD3DTexture_GetLevelDesc((IWineD3DTexture*) tex, 0, &desc);
2899 if (SUCCEEDED(hr))
2901 ddfmt.dwSize = sizeof(ddfmt);
2902 PixelFormat_WineD3DtoDD(&ddfmt, fmt);
2903 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
2906 IWineD3DBaseTexture_Release(tex);
2909 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG1);
2910 if (tex_alpha)
2912 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2914 else
2916 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_CURRENT);
2919 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2920 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2921 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_MODULATE);
2923 break;
2926 case D3DTBLEND_ADD:
2927 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_ADD);
2928 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2929 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2930 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG2);
2931 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
2932 break;
2934 case D3DTBLEND_MODULATEALPHA:
2935 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2936 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2937 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2938 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
2939 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_MODULATE);
2940 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_MODULATE);
2941 break;
2943 case D3DTBLEND_COPY:
2944 case D3DTBLEND_DECAL:
2945 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2946 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2947 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_SELECTARG1);
2948 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG1);
2949 break;
2951 case D3DTBLEND_DECALALPHA:
2952 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_BLENDTEXTUREALPHA);
2953 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2954 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2955 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG2);
2956 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
2957 break;
2959 default:
2960 ERR("Unhandled texture environment %d !\n",Value);
2963 hr = D3D_OK;
2964 break;
2967 default:
2968 hr = IDirect3DDevice7_SetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
2969 RenderStateType,
2970 Value);
2971 break;
2974 LeaveCriticalSection(&ddraw_cs);
2976 return hr;
2979 static HRESULT WINAPI
2980 Thunk_IDirect3DDeviceImpl_2_SetRenderState(IDirect3DDevice2 *iface,
2981 D3DRENDERSTATETYPE RenderStateType,
2982 DWORD Value)
2984 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2985 TRACE_(ddraw_thunk)("(%p)->(%08x,%d) thunking to IDirect3DDevice3 interface.\n", This, RenderStateType, Value);
2986 return IDirect3DDevice3_SetRenderState(ICOM_INTERFACE(This, IDirect3DDevice3), RenderStateType, Value);
2989 /*****************************************************************************
2990 * Direct3DDevice3::SetLightState
2992 * Sets a light state for Direct3DDevice3 and Direct3DDevice2. The
2993 * light states are forwarded to Direct3DDevice7 render states
2995 * Version 2 and 3
2997 * Params:
2998 * LightStateType: The light state to change
2999 * Value: The value to assign to that light state
3001 * Returns:
3002 * D3D_OK on success
3003 * DDERR_INVALIDPARAMS if the parameters were incorrect
3004 * Also check IDirect3DDevice7::SetRenderState
3006 *****************************************************************************/
3007 static HRESULT WINAPI
3008 IDirect3DDeviceImpl_3_SetLightState(IDirect3DDevice3 *iface,
3009 D3DLIGHTSTATETYPE LightStateType,
3010 DWORD Value)
3012 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3013 HRESULT hr;
3015 TRACE("(%p)->(%08x,%08x)\n", This, LightStateType, Value);
3017 if (!LightStateType && (LightStateType > D3DLIGHTSTATE_COLORVERTEX))
3019 TRACE("Unexpected Light State Type\n");
3020 return DDERR_INVALIDPARAMS;
3023 EnterCriticalSection(&ddraw_cs);
3024 if (LightStateType == D3DLIGHTSTATE_MATERIAL /* 1 */)
3026 IDirect3DMaterialImpl *mat;
3028 if(Value == 0) mat = NULL;
3029 else if(Value > This->numHandles)
3031 ERR("Material handle out of range(%d)\n", Value);
3032 LeaveCriticalSection(&ddraw_cs);
3033 return DDERR_INVALIDPARAMS;
3035 else if(This->Handles[Value - 1].type != DDrawHandle_Material)
3037 ERR("Invalid handle %d\n", Value);
3038 LeaveCriticalSection(&ddraw_cs);
3039 return DDERR_INVALIDPARAMS;
3041 else
3043 mat = (IDirect3DMaterialImpl *) This->Handles[Value - 1].ptr;
3046 if (mat != NULL)
3048 TRACE(" activating material %p.\n", mat);
3049 mat->activate(mat);
3051 else
3053 FIXME(" D3DLIGHTSTATE_MATERIAL called with NULL material !!!\n");
3055 This->material = Value;
3057 else if (LightStateType == D3DLIGHTSTATE_COLORMODEL /* 3 */)
3059 switch (Value)
3061 case D3DCOLOR_MONO:
3062 ERR("DDCOLOR_MONO should not happen!\n");
3063 break;
3064 case D3DCOLOR_RGB:
3065 /* We are already in this mode */
3066 TRACE("Setting color model to RGB (no-op).\n");
3067 break;
3068 default:
3069 ERR("Unknown color model!\n");
3070 LeaveCriticalSection(&ddraw_cs);
3071 return DDERR_INVALIDPARAMS;
3074 else
3076 D3DRENDERSTATETYPE rs;
3077 switch (LightStateType)
3079 case D3DLIGHTSTATE_AMBIENT: /* 2 */
3080 rs = D3DRENDERSTATE_AMBIENT;
3081 break;
3082 case D3DLIGHTSTATE_FOGMODE: /* 4 */
3083 rs = D3DRENDERSTATE_FOGVERTEXMODE;
3084 break;
3085 case D3DLIGHTSTATE_FOGSTART: /* 5 */
3086 rs = D3DRENDERSTATE_FOGSTART;
3087 break;
3088 case D3DLIGHTSTATE_FOGEND: /* 6 */
3089 rs = D3DRENDERSTATE_FOGEND;
3090 break;
3091 case D3DLIGHTSTATE_FOGDENSITY: /* 7 */
3092 rs = D3DRENDERSTATE_FOGDENSITY;
3093 break;
3094 case D3DLIGHTSTATE_COLORVERTEX: /* 8 */
3095 rs = D3DRENDERSTATE_COLORVERTEX;
3096 break;
3097 default:
3098 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType);
3099 LeaveCriticalSection(&ddraw_cs);
3100 return DDERR_INVALIDPARAMS;
3103 hr = IDirect3DDevice7_SetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
3105 Value);
3106 LeaveCriticalSection(&ddraw_cs);
3107 return hr;
3110 LeaveCriticalSection(&ddraw_cs);
3111 return D3D_OK;
3114 static HRESULT WINAPI
3115 Thunk_IDirect3DDeviceImpl_2_SetLightState(IDirect3DDevice2 *iface,
3116 D3DLIGHTSTATETYPE LightStateType,
3117 DWORD Value)
3119 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3120 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x) thunking to IDirect3DDevice3 interface.\n", This, LightStateType, Value);
3121 return IDirect3DDevice3_SetLightState(ICOM_INTERFACE(This, IDirect3DDevice3),
3122 LightStateType,
3123 Value);
3126 /*****************************************************************************
3127 * IDirect3DDevice3::GetLightState
3129 * Returns the current setting of a light state. The state is read from
3130 * the Direct3DDevice7 render state.
3132 * Version 2 and 3
3134 * Params:
3135 * LightStateType: The light state to return
3136 * Value: The address to store the light state setting at
3138 * Returns:
3139 * D3D_OK on success
3140 * DDDERR_INVALIDPARAMS if the parameters were incorrect
3141 * Also see IDirect3DDevice7::GetRenderState
3143 *****************************************************************************/
3144 static HRESULT WINAPI
3145 IDirect3DDeviceImpl_3_GetLightState(IDirect3DDevice3 *iface,
3146 D3DLIGHTSTATETYPE LightStateType,
3147 DWORD *Value)
3149 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3150 HRESULT hr;
3152 TRACE("(%p)->(%08x,%p)\n", This, LightStateType, Value);
3154 if (!LightStateType && (LightStateType > D3DLIGHTSTATE_COLORVERTEX))
3156 TRACE("Unexpected Light State Type\n");
3157 return DDERR_INVALIDPARAMS;
3160 if(!Value)
3161 return DDERR_INVALIDPARAMS;
3163 EnterCriticalSection(&ddraw_cs);
3164 if (LightStateType == D3DLIGHTSTATE_MATERIAL /* 1 */)
3166 *Value = This->material;
3168 else if (LightStateType == D3DLIGHTSTATE_COLORMODEL /* 3 */)
3170 *Value = D3DCOLOR_RGB;
3172 else
3174 D3DRENDERSTATETYPE rs;
3175 switch (LightStateType)
3177 case D3DLIGHTSTATE_AMBIENT: /* 2 */
3178 rs = D3DRENDERSTATE_AMBIENT;
3179 break;
3180 case D3DLIGHTSTATE_FOGMODE: /* 4 */
3181 rs = D3DRENDERSTATE_FOGVERTEXMODE;
3182 break;
3183 case D3DLIGHTSTATE_FOGSTART: /* 5 */
3184 rs = D3DRENDERSTATE_FOGSTART;
3185 break;
3186 case D3DLIGHTSTATE_FOGEND: /* 6 */
3187 rs = D3DRENDERSTATE_FOGEND;
3188 break;
3189 case D3DLIGHTSTATE_FOGDENSITY: /* 7 */
3190 rs = D3DRENDERSTATE_FOGDENSITY;
3191 break;
3192 case D3DLIGHTSTATE_COLORVERTEX: /* 8 */
3193 rs = D3DRENDERSTATE_COLORVERTEX;
3194 break;
3195 default:
3196 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType);
3197 LeaveCriticalSection(&ddraw_cs);
3198 return DDERR_INVALIDPARAMS;
3201 hr = IDirect3DDevice7_GetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
3203 Value);
3204 LeaveCriticalSection(&ddraw_cs);
3205 return hr;
3208 LeaveCriticalSection(&ddraw_cs);
3209 return D3D_OK;
3212 static HRESULT WINAPI
3213 Thunk_IDirect3DDeviceImpl_2_GetLightState(IDirect3DDevice2 *iface,
3214 D3DLIGHTSTATETYPE LightStateType,
3215 DWORD *Value)
3217 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3218 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice3 interface.\n", This, LightStateType, Value);
3219 return IDirect3DDevice3_GetLightState(ICOM_INTERFACE(This, IDirect3DDevice3),
3220 LightStateType,
3221 Value);
3224 /*****************************************************************************
3225 * IDirect3DDevice7::SetTransform
3227 * Assigns a D3DMATRIX to a transform type. The transform types are defined
3228 * in include/d3dtypes.h.
3229 * The D3DTRANSFORMSTATE_WORLD (=1) is translated to D3DTS_WORLDMATRIX(0)
3230 * (=255) for wined3d, because the 1 transform state was removed in d3d8
3231 * and WineD3D already understands the replacement D3DTS_WORLDMATRIX(0)
3233 * Version 2, 3 and 7
3235 * Params:
3236 * TransformStateType: transform state to set
3237 * Matrix: Matrix to assign to the state
3239 * Returns:
3240 * D3D_OK on success
3241 * DDERR_INVALIDPARAMS if Matrix == NULL
3242 * For details see IWineD3DDevice::SetTransform
3244 *****************************************************************************/
3245 static HRESULT
3246 IDirect3DDeviceImpl_7_SetTransform(IDirect3DDevice7 *iface,
3247 D3DTRANSFORMSTATETYPE TransformStateType,
3248 D3DMATRIX *Matrix)
3250 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3251 D3DTRANSFORMSTATETYPE type;
3252 HRESULT hr;
3253 TRACE("(%p)->(%08x,%p): Relay\n", This, TransformStateType, Matrix);
3255 switch(TransformStateType)
3257 case D3DTRANSFORMSTATE_WORLD : type = WINED3DTS_WORLDMATRIX(0); break;
3258 case D3DTRANSFORMSTATE_WORLD1: type = WINED3DTS_WORLDMATRIX(1); break;
3259 case D3DTRANSFORMSTATE_WORLD2: type = WINED3DTS_WORLDMATRIX(2); break;
3260 case D3DTRANSFORMSTATE_WORLD3: type = WINED3DTS_WORLDMATRIX(3); break;
3261 default: type = TransformStateType;
3264 if(!Matrix)
3265 return DDERR_INVALIDPARAMS;
3267 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3268 EnterCriticalSection(&ddraw_cs);
3269 hr = IWineD3DDevice_SetTransform(This->wineD3DDevice,
3270 type,
3271 (WINED3DMATRIX*) Matrix);
3272 LeaveCriticalSection(&ddraw_cs);
3273 return hr;
3276 static HRESULT WINAPI
3277 IDirect3DDeviceImpl_7_SetTransform_FPUSetup(IDirect3DDevice7 *iface,
3278 D3DTRANSFORMSTATETYPE TransformStateType,
3279 D3DMATRIX *Matrix)
3281 return IDirect3DDeviceImpl_7_SetTransform(iface, TransformStateType, Matrix);
3284 static HRESULT WINAPI
3285 IDirect3DDeviceImpl_7_SetTransform_FPUPreserve(IDirect3DDevice7 *iface,
3286 D3DTRANSFORMSTATETYPE TransformStateType,
3287 D3DMATRIX *Matrix)
3289 HRESULT hr;
3290 WORD old_fpucw;
3292 old_fpucw = d3d_fpu_setup();
3293 hr = IDirect3DDeviceImpl_7_SetTransform(iface, TransformStateType, Matrix);
3294 set_fpu_control_word(old_fpucw);
3296 return hr;
3299 static HRESULT WINAPI
3300 Thunk_IDirect3DDeviceImpl_3_SetTransform(IDirect3DDevice3 *iface,
3301 D3DTRANSFORMSTATETYPE TransformStateType,
3302 D3DMATRIX *D3DMatrix)
3304 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3305 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3306 return IDirect3DDevice7_SetTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
3307 TransformStateType,
3308 D3DMatrix);
3311 static HRESULT WINAPI
3312 Thunk_IDirect3DDeviceImpl_2_SetTransform(IDirect3DDevice2 *iface,
3313 D3DTRANSFORMSTATETYPE TransformStateType,
3314 D3DMATRIX *D3DMatrix)
3316 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3317 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3318 return IDirect3DDevice7_SetTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
3319 TransformStateType,
3320 D3DMatrix);
3323 /*****************************************************************************
3324 * IDirect3DDevice7::GetTransform
3326 * Returns the matrix assigned to a transform state
3327 * D3DTRANSFORMSTATE_WORLD is translated to D3DTS_WORLDMATRIX(0), see
3328 * SetTransform
3330 * Params:
3331 * TransformStateType: State to read the matrix from
3332 * Matrix: Address to store the matrix at
3334 * Returns:
3335 * D3D_OK on success
3336 * DDERR_INVALIDPARAMS if Matrix == NULL
3337 * For details, see IWineD3DDevice::GetTransform
3339 *****************************************************************************/
3340 static HRESULT
3341 IDirect3DDeviceImpl_7_GetTransform(IDirect3DDevice7 *iface,
3342 D3DTRANSFORMSTATETYPE TransformStateType,
3343 D3DMATRIX *Matrix)
3345 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3346 D3DTRANSFORMSTATETYPE type;
3347 HRESULT hr;
3348 TRACE("(%p)->(%08x,%p): Relay\n", This, TransformStateType, Matrix);
3350 switch(TransformStateType)
3352 case D3DTRANSFORMSTATE_WORLD : type = WINED3DTS_WORLDMATRIX(0); break;
3353 case D3DTRANSFORMSTATE_WORLD1: type = WINED3DTS_WORLDMATRIX(1); break;
3354 case D3DTRANSFORMSTATE_WORLD2: type = WINED3DTS_WORLDMATRIX(2); break;
3355 case D3DTRANSFORMSTATE_WORLD3: type = WINED3DTS_WORLDMATRIX(3); break;
3356 default: type = TransformStateType;
3359 if(!Matrix)
3360 return DDERR_INVALIDPARAMS;
3362 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3363 EnterCriticalSection(&ddraw_cs);
3364 hr = IWineD3DDevice_GetTransform(This->wineD3DDevice, type, (WINED3DMATRIX*) Matrix);
3365 LeaveCriticalSection(&ddraw_cs);
3366 return hr;
3369 static HRESULT WINAPI
3370 IDirect3DDeviceImpl_7_GetTransform_FPUSetup(IDirect3DDevice7 *iface,
3371 D3DTRANSFORMSTATETYPE TransformStateType,
3372 D3DMATRIX *Matrix)
3374 return IDirect3DDeviceImpl_7_GetTransform(iface, TransformStateType, Matrix);
3377 static HRESULT WINAPI
3378 IDirect3DDeviceImpl_7_GetTransform_FPUPreserve(IDirect3DDevice7 *iface,
3379 D3DTRANSFORMSTATETYPE TransformStateType,
3380 D3DMATRIX *Matrix)
3382 HRESULT hr;
3383 WORD old_fpucw;
3385 old_fpucw = d3d_fpu_setup();
3386 hr = IDirect3DDeviceImpl_7_GetTransform(iface, TransformStateType, Matrix);
3387 set_fpu_control_word(old_fpucw);
3389 return hr;
3392 static HRESULT WINAPI
3393 Thunk_IDirect3DDeviceImpl_3_GetTransform(IDirect3DDevice3 *iface,
3394 D3DTRANSFORMSTATETYPE TransformStateType,
3395 D3DMATRIX *D3DMatrix)
3397 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3398 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3399 return IDirect3DDevice7_GetTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
3400 TransformStateType,
3401 D3DMatrix);
3404 static HRESULT WINAPI
3405 Thunk_IDirect3DDeviceImpl_2_GetTransform(IDirect3DDevice2 *iface,
3406 D3DTRANSFORMSTATETYPE TransformStateType,
3407 D3DMATRIX *D3DMatrix)
3409 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3410 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3411 return IDirect3DDevice7_GetTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
3412 TransformStateType,
3413 D3DMatrix);
3416 /*****************************************************************************
3417 * IDirect3DDevice7::MultiplyTransform
3419 * Multiplies the already-set transform matrix of a transform state
3420 * with another matrix. For the world matrix, see SetTransform
3422 * Version 2, 3 and 7
3424 * Params:
3425 * TransformStateType: Transform state to multiply
3426 * D3DMatrix Matrix to multiply with.
3428 * Returns
3429 * D3D_OK on success
3430 * DDERR_INVALIDPARAMS if D3DMatrix is NULL
3431 * For details, see IWineD3DDevice::MultiplyTransform
3433 *****************************************************************************/
3434 static HRESULT
3435 IDirect3DDeviceImpl_7_MultiplyTransform(IDirect3DDevice7 *iface,
3436 D3DTRANSFORMSTATETYPE TransformStateType,
3437 D3DMATRIX *D3DMatrix)
3439 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3440 HRESULT hr;
3441 D3DTRANSFORMSTATETYPE type;
3442 TRACE("(%p)->(%08x,%p): Relay\n", This, TransformStateType, D3DMatrix);
3444 switch(TransformStateType)
3446 case D3DTRANSFORMSTATE_WORLD : type = WINED3DTS_WORLDMATRIX(0); break;
3447 case D3DTRANSFORMSTATE_WORLD1: type = WINED3DTS_WORLDMATRIX(1); break;
3448 case D3DTRANSFORMSTATE_WORLD2: type = WINED3DTS_WORLDMATRIX(2); break;
3449 case D3DTRANSFORMSTATE_WORLD3: type = WINED3DTS_WORLDMATRIX(3); break;
3450 default: type = TransformStateType;
3453 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3454 EnterCriticalSection(&ddraw_cs);
3455 hr = IWineD3DDevice_MultiplyTransform(This->wineD3DDevice,
3456 type,
3457 (WINED3DMATRIX*) D3DMatrix);
3458 LeaveCriticalSection(&ddraw_cs);
3459 return hr;
3462 static HRESULT WINAPI
3463 IDirect3DDeviceImpl_7_MultiplyTransform_FPUSetup(IDirect3DDevice7 *iface,
3464 D3DTRANSFORMSTATETYPE TransformStateType,
3465 D3DMATRIX *D3DMatrix)
3467 return IDirect3DDeviceImpl_7_MultiplyTransform(iface, TransformStateType, D3DMatrix);
3470 static HRESULT WINAPI
3471 IDirect3DDeviceImpl_7_MultiplyTransform_FPUPreserve(IDirect3DDevice7 *iface,
3472 D3DTRANSFORMSTATETYPE TransformStateType,
3473 D3DMATRIX *D3DMatrix)
3475 HRESULT hr;
3476 WORD old_fpucw;
3478 old_fpucw = d3d_fpu_setup();
3479 hr = IDirect3DDeviceImpl_7_MultiplyTransform(iface, TransformStateType, D3DMatrix);
3480 set_fpu_control_word(old_fpucw);
3482 return hr;
3485 static HRESULT WINAPI
3486 Thunk_IDirect3DDeviceImpl_3_MultiplyTransform(IDirect3DDevice3 *iface,
3487 D3DTRANSFORMSTATETYPE TransformStateType,
3488 D3DMATRIX *D3DMatrix)
3490 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3491 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3492 return IDirect3DDevice7_MultiplyTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
3493 TransformStateType,
3494 D3DMatrix);
3497 static HRESULT WINAPI
3498 Thunk_IDirect3DDeviceImpl_2_MultiplyTransform(IDirect3DDevice2 *iface,
3499 D3DTRANSFORMSTATETYPE TransformStateType,
3500 D3DMATRIX *D3DMatrix)
3502 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3503 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3504 return IDirect3DDevice7_MultiplyTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
3505 TransformStateType,
3506 D3DMatrix);
3509 /*****************************************************************************
3510 * IDirect3DDevice7::DrawPrimitive
3512 * Draws primitives based on vertices in an application-provided pointer
3514 * Version 2, 3 and 7. The IDirect3DDevice2 thunk converts the fixed vertex type into
3515 * an FVF format for D3D7
3517 * Params:
3518 * PrimitiveType: The type of the primitives to draw
3519 * Vertex type: Flexible vertex format vertex description
3520 * Vertices: Pointer to the vertex array
3521 * VertexCount: The number of vertices to draw
3522 * Flags: As usual a few flags
3524 * Returns:
3525 * D3D_OK on success
3526 * DDERR_INVALIDPARAMS if Vertices is NULL
3527 * For details, see IWineD3DDevice::DrawPrimitiveUP
3529 *****************************************************************************/
3530 static HRESULT
3531 IDirect3DDeviceImpl_7_DrawPrimitive(IDirect3DDevice7 *iface,
3532 D3DPRIMITIVETYPE PrimitiveType,
3533 DWORD VertexType,
3534 void *Vertices,
3535 DWORD VertexCount,
3536 DWORD Flags)
3538 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3539 UINT PrimitiveCount, stride;
3540 HRESULT hr;
3541 TRACE("(%p)->(%08x,%08x,%p,%08x,%08x): Relay!\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3543 if(!Vertices)
3544 return DDERR_INVALIDPARAMS;
3546 /* Get the vertex count */
3547 switch(PrimitiveType)
3549 case D3DPT_POINTLIST:
3550 PrimitiveCount = VertexCount;
3551 break;
3553 case D3DPT_LINELIST:
3554 PrimitiveCount = VertexCount / 2;
3555 break;
3557 case D3DPT_LINESTRIP:
3558 PrimitiveCount = VertexCount - 1;
3559 break;
3561 case D3DPT_TRIANGLELIST:
3562 PrimitiveCount = VertexCount / 3;
3563 break;
3565 case D3DPT_TRIANGLESTRIP:
3566 PrimitiveCount = VertexCount - 2;
3567 break;
3569 case D3DPT_TRIANGLEFAN:
3570 PrimitiveCount = VertexCount - 2;
3571 break;
3573 default:
3574 return DDERR_INVALIDPARAMS;
3577 /* Get the stride */
3578 stride = get_flexible_vertex_size(VertexType);
3580 /* Set the FVF */
3581 EnterCriticalSection(&ddraw_cs);
3582 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
3583 IDirectDrawImpl_FindDecl(This->ddraw, VertexType));
3584 if(hr != D3D_OK)
3586 LeaveCriticalSection(&ddraw_cs);
3587 return hr;
3590 /* This method translates to the user pointer draw of WineD3D */
3591 hr = IWineD3DDevice_DrawPrimitiveUP(This->wineD3DDevice,
3592 PrimitiveType,
3593 PrimitiveCount,
3594 Vertices,
3595 stride);
3596 LeaveCriticalSection(&ddraw_cs);
3597 return hr;
3600 static HRESULT WINAPI
3601 IDirect3DDeviceImpl_7_DrawPrimitive_FPUSetup(IDirect3DDevice7 *iface,
3602 D3DPRIMITIVETYPE PrimitiveType,
3603 DWORD VertexType,
3604 void *Vertices,
3605 DWORD VertexCount,
3606 DWORD Flags)
3608 return IDirect3DDeviceImpl_7_DrawPrimitive(iface, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3611 static HRESULT WINAPI
3612 IDirect3DDeviceImpl_7_DrawPrimitive_FPUPreserve(IDirect3DDevice7 *iface,
3613 D3DPRIMITIVETYPE PrimitiveType,
3614 DWORD VertexType,
3615 void *Vertices,
3616 DWORD VertexCount,
3617 DWORD Flags)
3619 HRESULT hr;
3620 WORD old_fpucw;
3622 old_fpucw = d3d_fpu_setup();
3623 hr = IDirect3DDeviceImpl_7_DrawPrimitive(iface, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3624 set_fpu_control_word(old_fpucw);
3626 return hr;
3629 static HRESULT WINAPI
3630 Thunk_IDirect3DDeviceImpl_3_DrawPrimitive(IDirect3DDevice3 *iface,
3631 D3DPRIMITIVETYPE PrimitiveType,
3632 DWORD VertexType,
3633 void *Vertices,
3634 DWORD VertexCount,
3635 DWORD Flags)
3637 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3638 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3639 return IDirect3DDevice7_DrawPrimitive(ICOM_INTERFACE(This, IDirect3DDevice7),
3640 PrimitiveType,
3641 VertexType,
3642 Vertices,
3643 VertexCount,
3644 Flags);
3647 static HRESULT WINAPI
3648 Thunk_IDirect3DDeviceImpl_2_DrawPrimitive(IDirect3DDevice2 *iface,
3649 D3DPRIMITIVETYPE PrimitiveType,
3650 D3DVERTEXTYPE VertexType,
3651 void *Vertices,
3652 DWORD VertexCount,
3653 DWORD Flags)
3655 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3656 DWORD FVF;
3657 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3659 switch(VertexType)
3661 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
3662 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
3663 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
3664 default:
3665 ERR("Unexpected vertex type %d\n", VertexType);
3666 return DDERR_INVALIDPARAMS; /* Should never happen */
3669 return IDirect3DDevice7_DrawPrimitive(ICOM_INTERFACE(This, IDirect3DDevice7),
3670 PrimitiveType,
3671 FVF,
3672 Vertices,
3673 VertexCount,
3674 Flags);
3677 /*****************************************************************************
3678 * IDirect3DDevice7::DrawIndexedPrimitive
3680 * Draws vertices from an application-provided pointer, based on the index
3681 * numbers in a WORD array.
3683 * Version 2, 3 and 7. The version 7 thunk translates the vertex type into
3684 * an FVF format for D3D7
3686 * Params:
3687 * PrimitiveType: The primitive type to draw
3688 * VertexType: The FVF vertex description
3689 * Vertices: Pointer to the vertex array
3690 * VertexCount: ?
3691 * Indices: Pointer to the index array
3692 * IndexCount: Number of indices = Number of vertices to draw
3693 * Flags: As usual, some flags
3695 * Returns:
3696 * D3D_OK on success
3697 * DDERR_INVALIDPARAMS if Vertices or Indices is NULL
3698 * For details, see IWineD3DDevice::DrawIndexedPrimitiveUP
3700 *****************************************************************************/
3701 static HRESULT
3702 IDirect3DDeviceImpl_7_DrawIndexedPrimitive(IDirect3DDevice7 *iface,
3703 D3DPRIMITIVETYPE PrimitiveType,
3704 DWORD VertexType,
3705 void *Vertices,
3706 DWORD VertexCount,
3707 WORD *Indices,
3708 DWORD IndexCount,
3709 DWORD Flags)
3711 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3712 UINT PrimitiveCount = 0;
3713 HRESULT hr;
3714 TRACE("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x): Relay!\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3716 /* Get the primitive number */
3717 switch(PrimitiveType)
3719 case D3DPT_POINTLIST:
3720 PrimitiveCount = IndexCount;
3721 break;
3723 case D3DPT_LINELIST:
3724 PrimitiveCount = IndexCount / 2;
3725 break;
3727 case D3DPT_LINESTRIP:
3728 PrimitiveCount = IndexCount - 1;
3729 break;
3731 case D3DPT_TRIANGLELIST:
3732 PrimitiveCount = IndexCount / 3;
3733 break;
3735 case D3DPT_TRIANGLESTRIP:
3736 PrimitiveCount = IndexCount - 2;
3737 break;
3739 case D3DPT_TRIANGLEFAN:
3740 PrimitiveCount = IndexCount - 2;
3741 break;
3743 default:
3744 return DDERR_INVALIDPARAMS;
3747 /* Set the D3DDevice's FVF */
3748 EnterCriticalSection(&ddraw_cs);
3749 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
3750 IDirectDrawImpl_FindDecl(This->ddraw, VertexType));
3751 if(FAILED(hr))
3753 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr);
3754 LeaveCriticalSection(&ddraw_cs);
3755 return hr;
3758 hr = IWineD3DDevice_DrawIndexedPrimitiveUP(This->wineD3DDevice,
3759 PrimitiveType,
3760 0 /* MinVertexIndex */,
3761 VertexCount /* UINT NumVertexIndex */,
3762 PrimitiveCount,
3763 Indices,
3764 WINED3DFMT_INDEX16,
3765 Vertices,
3766 get_flexible_vertex_size(VertexType));
3767 LeaveCriticalSection(&ddraw_cs);
3768 return hr;
3771 static HRESULT WINAPI
3772 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUSetup(IDirect3DDevice7 *iface,
3773 D3DPRIMITIVETYPE PrimitiveType,
3774 DWORD VertexType,
3775 void *Vertices,
3776 DWORD VertexCount,
3777 WORD *Indices,
3778 DWORD IndexCount,
3779 DWORD Flags)
3781 return IDirect3DDeviceImpl_7_DrawIndexedPrimitive(iface, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3784 static HRESULT WINAPI
3785 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUPreserve(IDirect3DDevice7 *iface,
3786 D3DPRIMITIVETYPE PrimitiveType,
3787 DWORD VertexType,
3788 void *Vertices,
3789 DWORD VertexCount,
3790 WORD *Indices,
3791 DWORD IndexCount,
3792 DWORD Flags)
3794 HRESULT hr;
3795 WORD old_fpucw;
3797 old_fpucw = d3d_fpu_setup();
3798 hr = IDirect3DDeviceImpl_7_DrawIndexedPrimitive(iface, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3799 set_fpu_control_word(old_fpucw);
3801 return hr;
3804 static HRESULT WINAPI
3805 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive(IDirect3DDevice3 *iface,
3806 D3DPRIMITIVETYPE PrimitiveType,
3807 DWORD VertexType,
3808 void *Vertices,
3809 DWORD VertexCount,
3810 WORD *Indices,
3811 DWORD IndexCount,
3812 DWORD Flags)
3814 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3815 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3816 return IDirect3DDevice7_DrawIndexedPrimitive(ICOM_INTERFACE(This, IDirect3DDevice7),
3817 PrimitiveType,
3818 VertexType,
3819 Vertices,
3820 VertexCount,
3821 Indices,
3822 IndexCount,
3823 Flags);
3826 static HRESULT WINAPI
3827 Thunk_IDirect3DDeviceImpl_2_DrawIndexedPrimitive(IDirect3DDevice2 *iface,
3828 D3DPRIMITIVETYPE PrimitiveType,
3829 D3DVERTEXTYPE VertexType,
3830 void *Vertices,
3831 DWORD VertexCount,
3832 WORD *Indices,
3833 DWORD IndexCount,
3834 DWORD Flags)
3836 DWORD FVF;
3837 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3838 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3840 switch(VertexType)
3842 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
3843 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
3844 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
3845 default:
3846 ERR("Unexpected vertex type %d\n", VertexType);
3847 return DDERR_INVALIDPARAMS; /* Should never happen */
3850 return IDirect3DDevice7_DrawIndexedPrimitive(ICOM_INTERFACE(This, IDirect3DDevice7),
3851 PrimitiveType,
3852 FVF,
3853 Vertices,
3854 VertexCount,
3855 Indices,
3856 IndexCount,
3857 Flags);
3860 /*****************************************************************************
3861 * IDirect3DDevice7::SetClipStatus
3863 * Sets the clip status. This defines things as clipping conditions and
3864 * the extents of the clipping region.
3866 * Version 2, 3 and 7
3868 * Params:
3869 * ClipStatus:
3871 * Returns:
3872 * D3D_OK because it's a stub
3873 * (DDERR_INVALIDPARAMS if ClipStatus == NULL)
3875 *****************************************************************************/
3876 static HRESULT WINAPI
3877 IDirect3DDeviceImpl_7_SetClipStatus(IDirect3DDevice7 *iface,
3878 D3DCLIPSTATUS *ClipStatus)
3880 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3881 FIXME("(%p)->(%p): Stub!\n", This, ClipStatus);
3883 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them
3884 * Perhaps this needs a new data type and an additional IWineD3DDevice method
3886 /* return IWineD3DDevice_SetClipStatus(This->wineD3DDevice, ClipStatus);*/
3887 return D3D_OK;
3890 static HRESULT WINAPI
3891 Thunk_IDirect3DDeviceImpl_3_SetClipStatus(IDirect3DDevice3 *iface,
3892 D3DCLIPSTATUS *ClipStatus)
3894 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3895 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3896 return IDirect3DDevice7_SetClipStatus(ICOM_INTERFACE(This, IDirect3DDevice7),
3897 ClipStatus);
3900 static HRESULT WINAPI
3901 Thunk_IDirect3DDeviceImpl_2_SetClipStatus(IDirect3DDevice2 *iface,
3902 D3DCLIPSTATUS *ClipStatus)
3904 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3905 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3906 return IDirect3DDevice7_SetClipStatus(ICOM_INTERFACE(This, IDirect3DDevice7),
3907 ClipStatus);
3910 /*****************************************************************************
3911 * IDirect3DDevice7::GetClipStatus
3913 * Returns the clip status
3915 * Params:
3916 * ClipStatus: Address to write the clip status to
3918 * Returns:
3919 * D3D_OK because it's a stub
3921 *****************************************************************************/
3922 static HRESULT WINAPI
3923 IDirect3DDeviceImpl_7_GetClipStatus(IDirect3DDevice7 *iface,
3924 D3DCLIPSTATUS *ClipStatus)
3926 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3927 FIXME("(%p)->(%p): Stub!\n", This, ClipStatus);
3929 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them */
3930 /* return IWineD3DDevice_GetClipStatus(This->wineD3DDevice, ClipStatus);*/
3931 return D3D_OK;
3934 static HRESULT WINAPI
3935 Thunk_IDirect3DDeviceImpl_3_GetClipStatus(IDirect3DDevice3 *iface,
3936 D3DCLIPSTATUS *ClipStatus)
3938 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3939 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3940 return IDirect3DDevice7_GetClipStatus(ICOM_INTERFACE(This, IDirect3DDevice7),
3941 ClipStatus);
3944 static HRESULT WINAPI
3945 Thunk_IDirect3DDeviceImpl_2_GetClipStatus(IDirect3DDevice2 *iface,
3946 D3DCLIPSTATUS *ClipStatus)
3948 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3949 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3950 return IDirect3DDevice7_GetClipStatus(ICOM_INTERFACE(This, IDirect3DDevice7),
3951 ClipStatus);
3954 /*****************************************************************************
3955 * IDirect3DDevice::DrawPrimitiveStrided
3957 * Draws vertices described by a D3DDRAWPRIMITIVESTRIDEDDATA structure.
3959 * Version 3 and 7
3961 * Params:
3962 * PrimitiveType: The primitive type to draw
3963 * VertexType: The FVF description of the vertices to draw (for the stride??)
3964 * D3DDrawPrimStrideData: A D3DDRAWPRIMITIVESTRIDEDDATA structure describing
3965 * the vertex data locations
3966 * VertexCount: The number of vertices to draw
3967 * Flags: Some flags
3969 * Returns:
3970 * D3D_OK, because it's a stub
3971 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
3972 * (For details, see IWineD3DDevice::DrawPrimitiveStrided)
3974 *****************************************************************************/
3975 static HRESULT
3976 IDirect3DDeviceImpl_7_DrawPrimitiveStrided(IDirect3DDevice7 *iface,
3977 D3DPRIMITIVETYPE PrimitiveType,
3978 DWORD VertexType,
3979 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3980 DWORD VertexCount,
3981 DWORD Flags)
3983 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3984 WineDirect3DVertexStridedData WineD3DStrided;
3985 DWORD i;
3986 UINT PrimitiveCount;
3987 HRESULT hr;
3989 TRACE("(%p)->(%08x,%08x,%p,%08x,%08x): stub!\n", This, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
3991 memset(&WineD3DStrided, 0, sizeof(WineD3DStrided));
3992 /* Get the strided data right. the wined3d structure is a bit bigger
3993 * Watch out: The contents of the strided data are determined by the fvf,
3994 * not by the members set in D3DDrawPrimStrideData. So it's valid
3995 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
3996 * not set in the fvf.
3998 if(VertexType & D3DFVF_POSITION_MASK)
4000 WineD3DStrided.u.s.position.lpData = D3DDrawPrimStrideData->position.lpvData;
4001 WineD3DStrided.u.s.position.dwStride = D3DDrawPrimStrideData->position.dwStride;
4002 WineD3DStrided.u.s.position.dwType = WINED3DDECLTYPE_FLOAT3;
4003 if (VertexType & D3DFVF_XYZRHW)
4005 WineD3DStrided.u.s.position.dwType = WINED3DDECLTYPE_FLOAT4;
4006 WineD3DStrided.u.s.position_transformed = TRUE;
4007 } else
4008 WineD3DStrided.u.s.position_transformed = FALSE;
4011 if(VertexType & D3DFVF_NORMAL)
4013 WineD3DStrided.u.s.normal.lpData = D3DDrawPrimStrideData->normal.lpvData;
4014 WineD3DStrided.u.s.normal.dwStride = D3DDrawPrimStrideData->normal.dwStride;
4015 WineD3DStrided.u.s.normal.dwType = WINED3DDECLTYPE_FLOAT3;
4018 if(VertexType & D3DFVF_DIFFUSE)
4020 WineD3DStrided.u.s.diffuse.lpData = D3DDrawPrimStrideData->diffuse.lpvData;
4021 WineD3DStrided.u.s.diffuse.dwStride = D3DDrawPrimStrideData->diffuse.dwStride;
4022 WineD3DStrided.u.s.diffuse.dwType = WINED3DDECLTYPE_D3DCOLOR;
4025 if(VertexType & D3DFVF_SPECULAR)
4027 WineD3DStrided.u.s.specular.lpData = D3DDrawPrimStrideData->specular.lpvData;
4028 WineD3DStrided.u.s.specular.dwStride = D3DDrawPrimStrideData->specular.dwStride;
4029 WineD3DStrided.u.s.specular.dwType = WINED3DDECLTYPE_D3DCOLOR;
4032 for( i = 0; i < GET_TEXCOUNT_FROM_FVF(VertexType); i++)
4034 WineD3DStrided.u.s.texCoords[i].lpData = D3DDrawPrimStrideData->textureCoords[i].lpvData;
4035 WineD3DStrided.u.s.texCoords[i].dwStride = D3DDrawPrimStrideData->textureCoords[i].dwStride;
4036 switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i))
4038 case 1: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT1; break;
4039 case 2: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT2; break;
4040 case 3: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT3; break;
4041 case 4: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT4; break;
4042 default: ERR("Unexpected texture coordinate size %d\n",
4043 GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i));
4047 /* Get the primitive count */
4048 switch(PrimitiveType)
4050 case D3DPT_POINTLIST:
4051 PrimitiveCount = VertexCount;
4052 break;
4054 case D3DPT_LINELIST:
4055 PrimitiveCount = VertexCount / 2;
4056 break;
4058 case D3DPT_LINESTRIP:
4059 PrimitiveCount = VertexCount - 1;
4060 break;
4062 case D3DPT_TRIANGLELIST:
4063 PrimitiveCount = VertexCount / 3;
4064 break;
4066 case D3DPT_TRIANGLESTRIP:
4067 PrimitiveCount = VertexCount - 2;
4068 break;
4070 case D3DPT_TRIANGLEFAN:
4071 PrimitiveCount = VertexCount - 2;
4072 break;
4074 default: return DDERR_INVALIDPARAMS;
4077 /* WineD3D doesn't need the FVF here */
4078 EnterCriticalSection(&ddraw_cs);
4079 hr = IWineD3DDevice_DrawPrimitiveStrided(This->wineD3DDevice,
4080 PrimitiveType,
4081 PrimitiveCount,
4082 &WineD3DStrided);
4083 LeaveCriticalSection(&ddraw_cs);
4084 return hr;
4087 static HRESULT WINAPI
4088 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUSetup(IDirect3DDevice7 *iface,
4089 D3DPRIMITIVETYPE PrimitiveType,
4090 DWORD VertexType,
4091 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
4092 DWORD VertexCount,
4093 DWORD Flags)
4095 return IDirect3DDeviceImpl_7_DrawPrimitiveStrided(iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
4098 static HRESULT WINAPI
4099 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUPreserve(IDirect3DDevice7 *iface,
4100 D3DPRIMITIVETYPE PrimitiveType,
4101 DWORD VertexType,
4102 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
4103 DWORD VertexCount,
4104 DWORD Flags)
4106 HRESULT hr;
4107 WORD old_fpucw;
4109 old_fpucw = d3d_fpu_setup();
4110 hr = IDirect3DDeviceImpl_7_DrawPrimitiveStrided(iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
4111 set_fpu_control_word(old_fpucw);
4113 return hr;
4116 static HRESULT WINAPI
4117 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided(IDirect3DDevice3 *iface,
4118 D3DPRIMITIVETYPE PrimitiveType,
4119 DWORD VertexType,
4120 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
4121 DWORD VertexCount,
4122 DWORD Flags)
4124 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4125 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
4126 return IDirect3DDevice7_DrawPrimitiveStrided(ICOM_INTERFACE(This, IDirect3DDevice7),
4127 PrimitiveType,
4128 VertexType,
4129 D3DDrawPrimStrideData,
4130 VertexCount,
4131 Flags);
4134 /*****************************************************************************
4135 * IDirect3DDevice7::DrawIndexedPrimitiveStrided
4137 * Draws primitives specified by strided data locations based on indices
4139 * Version 3 and 7
4141 * Params:
4142 * PrimitiveType:
4144 * Returns:
4145 * D3D_OK, because it's a stub
4146 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
4147 * (DDERR_INVALIDPARAMS if Indices is NULL)
4148 * (For more details, see IWineD3DDevice::DrawIndexedPrimitiveStrided)
4150 *****************************************************************************/
4151 static HRESULT
4152 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(IDirect3DDevice7 *iface,
4153 D3DPRIMITIVETYPE PrimitiveType,
4154 DWORD VertexType,
4155 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
4156 DWORD VertexCount,
4157 WORD *Indices,
4158 DWORD IndexCount,
4159 DWORD Flags)
4161 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4162 WineDirect3DVertexStridedData WineD3DStrided;
4163 DWORD i;
4164 UINT PrimitiveCount;
4165 HRESULT hr;
4167 TRACE("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x)\n", This, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
4169 memset(&WineD3DStrided, 0, sizeof(WineD3DStrided));
4170 /* Get the strided data right. the wined3d structure is a bit bigger
4171 * Watch out: The contents of the strided data are determined by the fvf,
4172 * not by the members set in D3DDrawPrimStrideData. So it's valid
4173 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
4174 * not set in the fvf.
4176 if(VertexType & D3DFVF_POSITION_MASK)
4178 WineD3DStrided.u.s.position.lpData = D3DDrawPrimStrideData->position.lpvData;
4179 WineD3DStrided.u.s.position.dwStride = D3DDrawPrimStrideData->position.dwStride;
4180 WineD3DStrided.u.s.position.dwType = WINED3DDECLTYPE_FLOAT3;
4181 if (VertexType & D3DFVF_XYZRHW)
4183 WineD3DStrided.u.s.position.dwType = WINED3DDECLTYPE_FLOAT4;
4184 WineD3DStrided.u.s.position_transformed = TRUE;
4185 } else
4186 WineD3DStrided.u.s.position_transformed = FALSE;
4189 if(VertexType & D3DFVF_NORMAL)
4191 WineD3DStrided.u.s.normal.lpData = D3DDrawPrimStrideData->normal.lpvData;
4192 WineD3DStrided.u.s.normal.dwStride = D3DDrawPrimStrideData->normal.dwStride;
4193 WineD3DStrided.u.s.normal.dwType = WINED3DDECLTYPE_FLOAT3;
4196 if(VertexType & D3DFVF_DIFFUSE)
4198 WineD3DStrided.u.s.diffuse.lpData = D3DDrawPrimStrideData->diffuse.lpvData;
4199 WineD3DStrided.u.s.diffuse.dwStride = D3DDrawPrimStrideData->diffuse.dwStride;
4200 WineD3DStrided.u.s.diffuse.dwType = WINED3DDECLTYPE_D3DCOLOR;
4203 if(VertexType & D3DFVF_SPECULAR)
4205 WineD3DStrided.u.s.specular.lpData = D3DDrawPrimStrideData->specular.lpvData;
4206 WineD3DStrided.u.s.specular.dwStride = D3DDrawPrimStrideData->specular.dwStride;
4207 WineD3DStrided.u.s.specular.dwType = WINED3DDECLTYPE_D3DCOLOR;
4210 for( i = 0; i < GET_TEXCOUNT_FROM_FVF(VertexType); i++)
4212 WineD3DStrided.u.s.texCoords[i].lpData = D3DDrawPrimStrideData->textureCoords[i].lpvData;
4213 WineD3DStrided.u.s.texCoords[i].dwStride = D3DDrawPrimStrideData->textureCoords[i].dwStride;
4214 switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i))
4216 case 1: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT1; break;
4217 case 2: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT2; break;
4218 case 3: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT3; break;
4219 case 4: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT4; break;
4220 default: ERR("Unexpected texture coordinate size %d\n",
4221 GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i));
4225 /* Get the primitive count */
4226 switch(PrimitiveType)
4228 case D3DPT_POINTLIST:
4229 PrimitiveCount = IndexCount;
4230 break;
4232 case D3DPT_LINELIST:
4233 PrimitiveCount = IndexCount / 2;
4234 break;
4236 case D3DPT_LINESTRIP:
4237 PrimitiveCount = IndexCount - 1;
4238 break;
4240 case D3DPT_TRIANGLELIST:
4241 PrimitiveCount = IndexCount / 3;
4242 break;
4244 case D3DPT_TRIANGLESTRIP:
4245 PrimitiveCount = IndexCount - 2;
4246 break;
4248 case D3DPT_TRIANGLEFAN:
4249 PrimitiveCount = IndexCount - 2;
4250 break;
4252 default: return DDERR_INVALIDPARAMS;
4255 /* WineD3D doesn't need the FVF here */
4256 EnterCriticalSection(&ddraw_cs);
4257 hr = IWineD3DDevice_DrawIndexedPrimitiveStrided(This->wineD3DDevice,
4258 PrimitiveType,
4259 PrimitiveCount,
4260 &WineD3DStrided,
4261 VertexCount,
4262 Indices,
4263 WINED3DFMT_INDEX16);
4264 LeaveCriticalSection(&ddraw_cs);
4265 return hr;
4268 static HRESULT WINAPI
4269 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUSetup(IDirect3DDevice7 *iface,
4270 D3DPRIMITIVETYPE PrimitiveType,
4271 DWORD VertexType,
4272 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
4273 DWORD VertexCount,
4274 WORD *Indices,
4275 DWORD IndexCount,
4276 DWORD Flags)
4278 return IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
4281 static HRESULT WINAPI
4282 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUPreserve(IDirect3DDevice7 *iface,
4283 D3DPRIMITIVETYPE PrimitiveType,
4284 DWORD VertexType,
4285 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
4286 DWORD VertexCount,
4287 WORD *Indices,
4288 DWORD IndexCount,
4289 DWORD Flags)
4291 HRESULT hr;
4292 WORD old_fpucw;
4294 old_fpucw = d3d_fpu_setup();
4295 hr = IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
4296 set_fpu_control_word(old_fpucw);
4298 return hr;
4301 static HRESULT WINAPI
4302 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided(IDirect3DDevice3 *iface,
4303 D3DPRIMITIVETYPE PrimitiveType,
4304 DWORD VertexType,
4305 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
4306 DWORD VertexCount,
4307 WORD *Indices,
4308 DWORD IndexCount,
4309 DWORD Flags)
4311 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4312 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
4313 return IDirect3DDevice7_DrawIndexedPrimitiveStrided(ICOM_INTERFACE(This, IDirect3DDevice7),
4314 PrimitiveType,
4315 VertexType,
4316 D3DDrawPrimStrideData,
4317 VertexCount,
4318 Indices,
4319 IndexCount,
4320 Flags);
4323 /*****************************************************************************
4324 * IDirect3DDevice7::DrawPrimitiveVB
4326 * Draws primitives from a vertex buffer to the screen.
4328 * Version 3 and 7
4330 * Params:
4331 * PrimitiveType: Type of primitive to be rendered.
4332 * D3DVertexBuf: Source Vertex Buffer
4333 * StartVertex: Index of the first vertex from the buffer to be rendered
4334 * NumVertices: Number of vertices to be rendered
4335 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4337 * Return values
4338 * D3D_OK on success
4339 * DDERR_INVALIDPARAMS if D3DVertexBuf is NULL
4341 *****************************************************************************/
4342 static HRESULT
4343 IDirect3DDeviceImpl_7_DrawPrimitiveVB(IDirect3DDevice7 *iface,
4344 D3DPRIMITIVETYPE PrimitiveType,
4345 IDirect3DVertexBuffer7 *D3DVertexBuf,
4346 DWORD StartVertex,
4347 DWORD NumVertices,
4348 DWORD Flags)
4350 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4351 IDirect3DVertexBufferImpl *vb = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, D3DVertexBuf);
4352 UINT PrimitiveCount;
4353 HRESULT hr;
4354 DWORD stride;
4355 WINED3DVERTEXBUFFER_DESC Desc;
4357 TRACE("(%p)->(%08x,%p,%08x,%08x,%08x)\n", This, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags);
4359 /* Sanity checks */
4360 if(!vb)
4362 ERR("(%p) No Vertex buffer specified\n", This);
4363 return DDERR_INVALIDPARAMS;
4366 /* Get the primitive count */
4367 switch(PrimitiveType)
4369 case D3DPT_POINTLIST:
4370 PrimitiveCount = NumVertices;
4371 break;
4373 case D3DPT_LINELIST:
4374 PrimitiveCount = NumVertices / 2;
4375 break;
4377 case D3DPT_LINESTRIP:
4378 PrimitiveCount = NumVertices - 1;
4379 break;
4381 case D3DPT_TRIANGLELIST:
4382 PrimitiveCount = NumVertices / 3;
4383 break;
4385 case D3DPT_TRIANGLESTRIP:
4386 PrimitiveCount = NumVertices - 2;
4387 break;
4389 case D3DPT_TRIANGLEFAN:
4390 PrimitiveCount = NumVertices - 2;
4391 break;
4393 default:
4394 return DDERR_INVALIDPARAMS;
4397 /* Get the FVF of the vertex buffer, and its stride */
4398 EnterCriticalSection(&ddraw_cs);
4399 hr = IWineD3DVertexBuffer_GetDesc(vb->wineD3DVertexBuffer,
4400 &Desc);
4401 if(hr != D3D_OK)
4403 ERR("(%p) IWineD3DVertexBuffer::GetDesc failed with hr = %08x\n", This, hr);
4404 LeaveCriticalSection(&ddraw_cs);
4405 return hr;
4407 stride = get_flexible_vertex_size(Desc.FVF);
4409 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
4410 vb->wineD3DVertexDeclaration);
4411 if(FAILED(hr))
4413 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr);
4414 LeaveCriticalSection(&ddraw_cs);
4415 return hr;
4418 /* Set the vertex stream source */
4419 hr = IWineD3DDevice_SetStreamSource(This->wineD3DDevice,
4420 0 /* StreamNumber */,
4421 vb->wineD3DVertexBuffer,
4422 0 /* StartVertex - we pass this to DrawPrimitive */,
4423 stride);
4424 if(hr != D3D_OK)
4426 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This, hr);
4427 LeaveCriticalSection(&ddraw_cs);
4428 return hr;
4431 /* Now draw the primitives */
4432 hr = IWineD3DDevice_DrawPrimitive(This->wineD3DDevice,
4433 PrimitiveType,
4434 StartVertex,
4435 PrimitiveCount);
4436 LeaveCriticalSection(&ddraw_cs);
4437 return hr;
4440 static HRESULT WINAPI
4441 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUSetup(IDirect3DDevice7 *iface,
4442 D3DPRIMITIVETYPE PrimitiveType,
4443 IDirect3DVertexBuffer7 *D3DVertexBuf,
4444 DWORD StartVertex,
4445 DWORD NumVertices,
4446 DWORD Flags)
4448 return IDirect3DDeviceImpl_7_DrawPrimitiveVB(iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags);
4451 static HRESULT WINAPI
4452 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUPreserve(IDirect3DDevice7 *iface,
4453 D3DPRIMITIVETYPE PrimitiveType,
4454 IDirect3DVertexBuffer7 *D3DVertexBuf,
4455 DWORD StartVertex,
4456 DWORD NumVertices,
4457 DWORD Flags)
4459 HRESULT hr;
4460 WORD old_fpucw;
4462 old_fpucw = d3d_fpu_setup();
4463 hr = IDirect3DDeviceImpl_7_DrawPrimitiveVB(iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags);
4464 set_fpu_control_word(old_fpucw);
4466 return hr;
4469 static HRESULT WINAPI
4470 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB(IDirect3DDevice3 *iface,
4471 D3DPRIMITIVETYPE PrimitiveType,
4472 IDirect3DVertexBuffer *D3DVertexBuf,
4473 DWORD StartVertex,
4474 DWORD NumVertices,
4475 DWORD Flags)
4477 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4478 IDirect3DVertexBufferImpl *vb = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, D3DVertexBuf);
4479 TRACE_(ddraw_thunk)("(%p)->(%08x,%p,%08x,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, vb, StartVertex, NumVertices, Flags);
4480 return IDirect3DDevice7_DrawPrimitiveVB(ICOM_INTERFACE(This, IDirect3DDevice7),
4481 PrimitiveType,
4482 ICOM_INTERFACE(vb, IDirect3DVertexBuffer7),
4483 StartVertex,
4484 NumVertices,
4485 Flags);
4489 /*****************************************************************************
4490 * IDirect3DDevice7::DrawIndexedPrimitiveVB
4492 * Draws primitives from a vertex buffer to the screen
4494 * Params:
4495 * PrimitiveType: Type of primitive to be rendered.
4496 * D3DVertexBuf: Source Vertex Buffer
4497 * StartVertex: Index of the first vertex from the buffer to be rendered
4498 * NumVertices: Number of vertices to be rendered
4499 * Indices: Array of DWORDs used to index into the Vertices
4500 * IndexCount: Number of indices in Indices
4501 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4503 * Return values
4505 *****************************************************************************/
4506 static HRESULT
4507 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(IDirect3DDevice7 *iface,
4508 D3DPRIMITIVETYPE PrimitiveType,
4509 IDirect3DVertexBuffer7 *D3DVertexBuf,
4510 DWORD StartVertex,
4511 DWORD NumVertices,
4512 WORD *Indices,
4513 DWORD IndexCount,
4514 DWORD Flags)
4516 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4517 IDirect3DVertexBufferImpl *vb = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, D3DVertexBuf);
4518 DWORD stride;
4519 UINT PrimitiveCount;
4520 WORD *LockedIndices;
4521 HRESULT hr;
4522 WINED3DVERTEXBUFFER_DESC Desc;
4524 TRACE("(%p)->(%08x,%p,%d,%d,%p,%d,%08x)\n", This, PrimitiveType, vb, StartVertex, NumVertices, Indices, IndexCount, Flags);
4526 /* Steps:
4527 * 1) Calculate some things: Vertex count -> Primitive count, stride, ...
4528 * 2) Upload the Indices to the index buffer
4529 * 3) Set the index source
4530 * 4) Set the Vertex Buffer as the Stream source
4531 * 5) Call IWineD3DDevice::DrawIndexedPrimitive
4534 /* Get the primitive count */
4535 switch(PrimitiveType)
4537 case D3DPT_POINTLIST:
4538 PrimitiveCount = IndexCount;
4539 break;
4541 case D3DPT_LINELIST:
4542 PrimitiveCount = IndexCount / 2;
4543 break;
4545 case D3DPT_LINESTRIP:
4546 PrimitiveCount = IndexCount - 1;
4547 break;
4549 case D3DPT_TRIANGLELIST:
4550 PrimitiveCount = IndexCount / 3;
4551 break;
4553 case D3DPT_TRIANGLESTRIP:
4554 PrimitiveCount = IndexCount - 2;
4555 break;
4557 case D3DPT_TRIANGLEFAN:
4558 PrimitiveCount = IndexCount - 2;
4559 break;
4561 default: return DDERR_INVALIDPARAMS;
4564 EnterCriticalSection(&ddraw_cs);
4565 /* Get the FVF of the vertex buffer, and its stride */
4566 hr = IWineD3DVertexBuffer_GetDesc(vb->wineD3DVertexBuffer,
4567 &Desc);
4568 if(hr != D3D_OK)
4570 ERR("(%p) IWineD3DVertexBuffer::GetDesc failed with hr = %08x\n", This, hr);
4571 LeaveCriticalSection(&ddraw_cs);
4572 return hr;
4574 stride = get_flexible_vertex_size(Desc.FVF);
4575 TRACE("Vertex buffer FVF = %08x, stride=%d\n", Desc.FVF, stride);
4577 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
4578 vb->wineD3DVertexDeclaration);
4579 if(FAILED(hr))
4581 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr);
4582 LeaveCriticalSection(&ddraw_cs);
4583 return hr;
4586 /* copy the index stream into the index buffer.
4587 * A new IWineD3DDevice method could be created
4588 * which takes an user pointer containing the indices
4589 * or a SetData-Method for the index buffer, which
4590 * overrides the index buffer data with our pointer.
4592 hr = IWineD3DIndexBuffer_Lock(This->indexbuffer,
4593 0 /* OffSetToLock */,
4594 IndexCount * sizeof(WORD),
4595 (BYTE **) &LockedIndices,
4596 0 /* Flags */);
4597 assert(IndexCount < 0x100000);
4598 if(hr != D3D_OK)
4600 ERR("(%p) IWineD3DIndexBuffer::Lock failed with hr = %08x\n", This, hr);
4601 LeaveCriticalSection(&ddraw_cs);
4602 return hr;
4604 memcpy(LockedIndices, Indices, IndexCount * sizeof(WORD));
4605 hr = IWineD3DIndexBuffer_Unlock(This->indexbuffer);
4606 if(hr != D3D_OK)
4608 ERR("(%p) IWineD3DIndexBuffer::Unlock failed with hr = %08x\n", This, hr);
4609 LeaveCriticalSection(&ddraw_cs);
4610 return hr;
4613 /* Set the index stream */
4614 IWineD3DDevice_SetBaseVertexIndex(This->wineD3DDevice, StartVertex);
4615 hr = IWineD3DDevice_SetIndices(This->wineD3DDevice, This->indexbuffer);
4617 /* Set the vertex stream source */
4618 hr = IWineD3DDevice_SetStreamSource(This->wineD3DDevice,
4619 0 /* StreamNumber */,
4620 vb->wineD3DVertexBuffer,
4621 0 /* offset, we pass this to DrawIndexedPrimitive */,
4622 stride);
4623 if(hr != D3D_OK)
4625 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This, hr);
4626 LeaveCriticalSection(&ddraw_cs);
4627 return hr;
4631 hr = IWineD3DDevice_DrawIndexedPrimitive(This->wineD3DDevice,
4632 PrimitiveType,
4633 0 /* minIndex */,
4634 NumVertices,
4635 0 /* StartIndex */,
4636 PrimitiveCount);
4638 LeaveCriticalSection(&ddraw_cs);
4639 return hr;
4642 static HRESULT WINAPI
4643 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUSetup(IDirect3DDevice7 *iface,
4644 D3DPRIMITIVETYPE PrimitiveType,
4645 IDirect3DVertexBuffer7 *D3DVertexBuf,
4646 DWORD StartVertex,
4647 DWORD NumVertices,
4648 WORD *Indices,
4649 DWORD IndexCount,
4650 DWORD Flags)
4652 return IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Indices, IndexCount, Flags);
4655 static HRESULT WINAPI
4656 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUPreserve(IDirect3DDevice7 *iface,
4657 D3DPRIMITIVETYPE PrimitiveType,
4658 IDirect3DVertexBuffer7 *D3DVertexBuf,
4659 DWORD StartVertex,
4660 DWORD NumVertices,
4661 WORD *Indices,
4662 DWORD IndexCount,
4663 DWORD Flags)
4665 HRESULT hr;
4666 WORD old_fpucw;
4668 old_fpucw = d3d_fpu_setup();
4669 hr = IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Indices, IndexCount, Flags);
4670 set_fpu_control_word(old_fpucw);
4672 return hr;
4675 static HRESULT WINAPI
4676 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB(IDirect3DDevice3 *iface,
4677 D3DPRIMITIVETYPE PrimitiveType,
4678 IDirect3DVertexBuffer *D3DVertexBuf,
4679 WORD *Indices,
4680 DWORD IndexCount,
4681 DWORD Flags)
4683 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4684 IDirect3DVertexBufferImpl *VB = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, D3DVertexBuf);
4685 TRACE_(ddraw_thunk)("(%p)->(%08x,%p,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VB, Indices, IndexCount, Flags);
4687 return IDirect3DDevice7_DrawIndexedPrimitiveVB(ICOM_INTERFACE(This, IDirect3DDevice7),
4688 PrimitiveType,
4689 ICOM_INTERFACE(VB, IDirect3DVertexBuffer7),
4691 IndexCount,
4692 Indices,
4693 IndexCount,
4694 Flags);
4697 /*****************************************************************************
4698 * IDirect3DDevice7::ComputeSphereVisibility
4700 * Calculates the visibility of spheres in the current viewport. The spheres
4701 * are passed in the Centers and Radii arrays, the results are passed back
4702 * in the ReturnValues array. Return values are either completely visible,
4703 * partially visible or completely invisible.
4704 * The return value consist of a combination of D3DCLIP_* flags, or it's
4705 * 0 if the sphere is completely visible(according to the SDK, not checked)
4707 * Sounds like an overdose of math ;)
4709 * Version 3 and 7
4711 * Params:
4712 * Centers: Array containing the sphere centers
4713 * Radii: Array containing the sphere radii
4714 * NumSpheres: The number of centers and radii in the arrays
4715 * Flags: Some flags
4716 * ReturnValues: Array to write the results to
4718 * Returns:
4719 * D3D_OK because it's a stub
4720 * (DDERR_INVALIDPARAMS if Centers, Radii or ReturnValues are NULL)
4721 * (D3DERR_INVALIDMATRIX if the combined world, view and proj matrix
4722 * is singular)
4724 *****************************************************************************/
4725 static HRESULT WINAPI
4726 IDirect3DDeviceImpl_7_ComputeSphereVisibility(IDirect3DDevice7 *iface,
4727 D3DVECTOR *Centers,
4728 D3DVALUE *Radii,
4729 DWORD NumSpheres,
4730 DWORD Flags,
4731 DWORD *ReturnValues)
4733 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4734 FIXME("(%p)->(%p,%p,%08x,%08x,%p): stub!\n", This, Centers, Radii, NumSpheres, Flags, ReturnValues);
4736 /* the DirectX 7 sdk says that the visibility is computed by
4737 * back-transforming the viewing frustum to model space
4738 * using the inverse of the combined world, view and projection
4739 * matrix. If the matrix can't be reversed, D3DERR_INVALIDMATRIX
4740 * is returned.
4742 * Basic implementation idea:
4743 * 1) Check if the center is in the viewing frustum
4744 * 2) Cut the sphere with the planes of the viewing
4745 * frustum
4747 * ->Center inside the frustum, no intersections:
4748 * Fully visible
4749 * ->Center outside the frustum, no intersections:
4750 * Not visible
4751 * ->Some intersections: Partially visible
4753 * Implement this call in WineD3D. Either implement the
4754 * matrix and vector stuff in WineD3D, or use some external
4755 * math library.
4758 return D3D_OK;
4761 static HRESULT WINAPI
4762 Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility(IDirect3DDevice3 *iface,
4763 D3DVECTOR *Centers,
4764 D3DVALUE *Radii,
4765 DWORD NumSpheres,
4766 DWORD Flags,
4767 DWORD *ReturnValues)
4769 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4770 TRACE_(ddraw_thunk)("(%p)->(%p,%p,%08x,%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, Centers, Radii, NumSpheres, Flags, ReturnValues);
4771 return IDirect3DDevice7_ComputeSphereVisibility(ICOM_INTERFACE(This, IDirect3DDevice7),
4772 Centers,
4773 Radii,
4774 NumSpheres,
4775 Flags,
4776 ReturnValues);
4779 /*****************************************************************************
4780 * IDirect3DDevice7::GetTexture
4782 * Returns the texture interface handle assigned to a texture stage.
4783 * The returned texture is AddRefed. This is taken from old ddraw,
4784 * not checked in Windows.
4786 * Version 3 and 7
4788 * Params:
4789 * Stage: Texture stage to read the texture from
4790 * Texture: Address to store the interface pointer at
4792 * Returns:
4793 * D3D_OK on success
4794 * DDERR_INVALIDPARAMS if Texture is NULL
4795 * For details, see IWineD3DDevice::GetTexture
4797 *****************************************************************************/
4798 static HRESULT
4799 IDirect3DDeviceImpl_7_GetTexture(IDirect3DDevice7 *iface,
4800 DWORD Stage,
4801 IDirectDrawSurface7 **Texture)
4803 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4804 IWineD3DBaseTexture *Surf;
4805 HRESULT hr;
4806 TRACE("(%p)->(%d,%p): Relay\n", This, Stage, Texture);
4808 if(!Texture)
4810 TRACE("Texture == NULL, failing with DDERR_INVALIDPARAMS\n");
4811 return DDERR_INVALIDPARAMS;
4814 EnterCriticalSection(&ddraw_cs);
4815 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice, Stage, &Surf);
4816 if( (hr != D3D_OK) || (!Surf) )
4818 *Texture = NULL;
4819 LeaveCriticalSection(&ddraw_cs);
4820 return hr;
4823 /* GetParent AddRef()s, which is perfectly OK.
4824 * We have passed the IDirectDrawSurface7 interface to WineD3D, so that's OK too.
4826 hr = IWineD3DBaseTexture_GetParent(Surf,
4827 (IUnknown **) Texture);
4828 LeaveCriticalSection(&ddraw_cs);
4829 return hr;
4832 static HRESULT WINAPI
4833 IDirect3DDeviceImpl_7_GetTexture_FPUSetup(IDirect3DDevice7 *iface,
4834 DWORD Stage,
4835 IDirectDrawSurface7 **Texture)
4837 return IDirect3DDeviceImpl_7_GetTexture(iface, Stage, Texture);
4840 static HRESULT WINAPI
4841 IDirect3DDeviceImpl_7_GetTexture_FPUPreserve(IDirect3DDevice7 *iface,
4842 DWORD Stage,
4843 IDirectDrawSurface7 **Texture)
4845 HRESULT hr;
4846 WORD old_fpucw;
4848 old_fpucw = d3d_fpu_setup();
4849 hr = IDirect3DDeviceImpl_7_GetTexture(iface, Stage, Texture);
4850 set_fpu_control_word(old_fpucw);
4852 return hr;
4855 static HRESULT WINAPI
4856 Thunk_IDirect3DDeviceImpl_3_GetTexture(IDirect3DDevice3 *iface,
4857 DWORD Stage,
4858 IDirect3DTexture2 **Texture2)
4860 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4861 HRESULT ret;
4862 IDirectDrawSurface7 *ret_val;
4864 TRACE_(ddraw_thunk)("(%p)->(%d,%p) thunking to IDirect3DDevice7 interface.\n", This, Stage, Texture2);
4865 ret = IDirect3DDevice7_GetTexture(ICOM_INTERFACE(This, IDirect3DDevice7),
4866 Stage,
4867 &ret_val);
4869 *Texture2 = COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7, IDirect3DTexture2, ret_val);
4871 TRACE_(ddraw_thunk)(" returning interface %p.\n", *Texture2);
4873 return ret;
4876 /*****************************************************************************
4877 * IDirect3DDevice7::SetTexture
4879 * Assigns a texture to a texture stage. Is the texture AddRef-ed?
4881 * Version 3 and 7
4883 * Params:
4884 * Stage: The stage to assign the texture to
4885 * Texture: Interface pointer to the texture surface
4887 * Returns
4888 * D3D_OK on success
4889 * For details, see IWineD3DDevice::SetTexture
4891 *****************************************************************************/
4892 static HRESULT
4893 IDirect3DDeviceImpl_7_SetTexture(IDirect3DDevice7 *iface,
4894 DWORD Stage,
4895 IDirectDrawSurface7 *Texture)
4897 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4898 IDirectDrawSurfaceImpl *surf = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, Texture);
4899 HRESULT hr;
4900 TRACE("(%p)->(%08x,%p): Relay!\n", This, Stage, surf);
4902 /* Texture may be NULL here */
4903 EnterCriticalSection(&ddraw_cs);
4904 hr = IWineD3DDevice_SetTexture(This->wineD3DDevice,
4905 Stage,
4906 surf ? surf->wineD3DTexture : NULL);
4907 LeaveCriticalSection(&ddraw_cs);
4908 return hr;
4911 static HRESULT WINAPI
4912 IDirect3DDeviceImpl_7_SetTexture_FPUSetup(IDirect3DDevice7 *iface,
4913 DWORD Stage,
4914 IDirectDrawSurface7 *Texture)
4916 return IDirect3DDeviceImpl_7_SetTexture(iface, Stage, Texture);
4919 static HRESULT WINAPI
4920 IDirect3DDeviceImpl_7_SetTexture_FPUPreserve(IDirect3DDevice7 *iface,
4921 DWORD Stage,
4922 IDirectDrawSurface7 *Texture)
4924 HRESULT hr;
4925 WORD old_fpucw;
4927 old_fpucw = d3d_fpu_setup();
4928 hr = IDirect3DDeviceImpl_7_SetTexture(iface, Stage, Texture);
4929 set_fpu_control_word(old_fpucw);
4931 return hr;
4934 static HRESULT WINAPI
4935 IDirect3DDeviceImpl_3_SetTexture(IDirect3DDevice3 *iface,
4936 DWORD Stage,
4937 IDirect3DTexture2 *Texture2)
4939 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4940 IDirectDrawSurfaceImpl *tex = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture2, Texture2);
4941 DWORD texmapblend;
4942 HRESULT hr;
4943 TRACE("(%p)->(%d,%p)\n", This, Stage, tex);
4945 EnterCriticalSection(&ddraw_cs);
4947 if (This->legacyTextureBlending)
4948 IDirect3DDevice3_GetRenderState(iface, D3DRENDERSTATE_TEXTUREMAPBLEND, &texmapblend);
4950 hr = IDirect3DDevice7_SetTexture(ICOM_INTERFACE(This, IDirect3DDevice7),
4951 Stage,
4952 ICOM_INTERFACE(tex, IDirectDrawSurface7));
4954 if (This->legacyTextureBlending && texmapblend == D3DTBLEND_MODULATE)
4956 /* This fixup is required by the way D3DTBLEND_MODULATE maps to texture stage states.
4957 See IDirect3DDeviceImpl_3_SetRenderState for details. */
4958 BOOL tex_alpha = FALSE;
4959 IWineD3DBaseTexture *tex = NULL;
4960 WINED3DSURFACE_DESC desc;
4961 WINED3DFORMAT fmt;
4962 DDPIXELFORMAT ddfmt;
4963 HRESULT result;
4965 result = IWineD3DDevice_GetTexture(This->wineD3DDevice,
4967 &tex);
4969 if(result == WINED3D_OK && tex)
4971 memset(&desc, 0, sizeof(desc));
4972 desc.Format = &fmt;
4973 result = IWineD3DTexture_GetLevelDesc((IWineD3DTexture*) tex, 0, &desc);
4974 if (SUCCEEDED(result))
4976 ddfmt.dwSize = sizeof(ddfmt);
4977 PixelFormat_WineD3DtoDD(&ddfmt, fmt);
4978 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
4981 IWineD3DBaseTexture_Release(tex);
4984 /* alphaop is WINED3DTOP_SELECTARG1 if it's D3DTBLEND_MODULATE, so only modify alphaarg1 */
4985 if (tex_alpha)
4987 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
4989 else
4991 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_CURRENT);
4995 LeaveCriticalSection(&ddraw_cs);
4997 return hr;
5000 /*****************************************************************************
5001 * IDirect3DDevice7::GetTextureStageState
5003 * Retrieves a state from a texture stage.
5005 * Version 3 and 7
5007 * Params:
5008 * Stage: The stage to retrieve the state from
5009 * TexStageStateType: The state type to retrieve
5010 * State: Address to store the state's value at
5012 * Returns:
5013 * D3D_OK on success
5014 * DDERR_INVALIDPARAMS if State is NULL
5015 * For details, see IWineD3DDevice::GetTextureStageState
5017 *****************************************************************************/
5018 static HRESULT
5019 IDirect3DDeviceImpl_7_GetTextureStageState(IDirect3DDevice7 *iface,
5020 DWORD Stage,
5021 D3DTEXTURESTAGESTATETYPE TexStageStateType,
5022 DWORD *State)
5024 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5025 HRESULT hr;
5026 TRACE("(%p)->(%08x,%08x,%p): Relay!\n", This, Stage, TexStageStateType, State);
5028 if(!State)
5029 return DDERR_INVALIDPARAMS;
5031 EnterCriticalSection(&ddraw_cs);
5032 switch(TexStageStateType)
5034 /* Mipfilter is a sampler state with different values */
5035 case D3DTSS_MIPFILTER:
5037 WINED3DTEXTUREFILTERTYPE value;
5039 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
5040 Stage,
5041 WINED3DSAMP_MIPFILTER,
5042 &value);
5043 switch(value)
5045 case WINED3DTEXF_NONE: *State = D3DTFP_NONE; break;
5046 case WINED3DTEXF_POINT: *State = D3DTFP_POINT; break;
5047 case WINED3DTEXF_LINEAR: *State = D3DTFP_LINEAR; break;
5048 default:
5049 ERR("Unexpected mipfilter value %d\n", value);
5050 *State = D3DTFP_NONE;
5052 break;
5055 /* Minfilter is a sampler state too, equal values */
5056 case D3DTSS_MINFILTER:
5057 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
5058 Stage,
5059 WINED3DSAMP_MINFILTER,
5060 State);
5061 break;
5063 /* Magfilter has slightly different values */
5064 case D3DTSS_MAGFILTER:
5066 WINED3DTEXTUREFILTERTYPE wined3dfilter;
5067 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
5068 Stage,
5069 WINED3DSAMP_MAGFILTER,
5070 &wined3dfilter);
5071 switch(wined3dfilter)
5073 case WINED3DTEXF_POINT: *State = D3DTFG_POINT; break;
5074 case WINED3DTEXF_LINEAR: *State = D3DTFG_LINEAR; break;
5075 case WINED3DTEXF_ANISOTROPIC: *State = D3DTFG_ANISOTROPIC; break;
5076 case WINED3DTEXF_FLATCUBIC: *State = D3DTFG_FLATCUBIC; break;
5077 case WINED3DTEXF_GAUSSIANCUBIC: *State = D3DTFG_GAUSSIANCUBIC; break;
5078 default:
5079 ERR("Unexpected wined3d mag filter value %d\n", wined3dfilter);
5080 *State = D3DTFG_POINT;
5082 break;
5085 case D3DTSS_ADDRESS:
5086 case D3DTSS_ADDRESSU:
5087 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
5088 Stage,
5089 WINED3DSAMP_ADDRESSU,
5090 State);
5091 break;
5092 case D3DTSS_ADDRESSV:
5093 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
5094 Stage,
5095 WINED3DSAMP_ADDRESSV,
5096 State);
5097 break;
5098 default:
5099 hr = IWineD3DDevice_GetTextureStageState(This->wineD3DDevice,
5100 Stage,
5101 TexStageStateType,
5102 State);
5103 break;
5105 LeaveCriticalSection(&ddraw_cs);
5106 return hr;
5109 static HRESULT WINAPI
5110 IDirect3DDeviceImpl_7_GetTextureStageState_FPUSetup(IDirect3DDevice7 *iface,
5111 DWORD Stage,
5112 D3DTEXTURESTAGESTATETYPE TexStageStateType,
5113 DWORD *State)
5115 return IDirect3DDeviceImpl_7_GetTextureStageState(iface, Stage, TexStageStateType, State);
5118 static HRESULT WINAPI
5119 IDirect3DDeviceImpl_7_GetTextureStageState_FPUPreserve(IDirect3DDevice7 *iface,
5120 DWORD Stage,
5121 D3DTEXTURESTAGESTATETYPE TexStageStateType,
5122 DWORD *State)
5124 HRESULT hr;
5125 WORD old_fpucw;
5127 old_fpucw = d3d_fpu_setup();
5128 hr = IDirect3DDeviceImpl_7_GetTextureStageState(iface, Stage, TexStageStateType, State);
5129 set_fpu_control_word(old_fpucw);
5131 return hr;
5134 static HRESULT WINAPI
5135 Thunk_IDirect3DDeviceImpl_3_GetTextureStageState(IDirect3DDevice3 *iface,
5136 DWORD Stage,
5137 D3DTEXTURESTAGESTATETYPE TexStageStateType,
5138 DWORD *State)
5140 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
5141 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, Stage, TexStageStateType, State);
5142 return IDirect3DDevice7_GetTextureStageState(ICOM_INTERFACE(This, IDirect3DDevice7),
5143 Stage,
5144 TexStageStateType,
5145 State);
5148 /*****************************************************************************
5149 * IDirect3DDevice7::SetTextureStageState
5151 * Sets a texture stage state. Some stage types need to be handled specially,
5152 * because they do not exist in WineD3D and were moved to another place
5154 * Version 3 and 7
5156 * Params:
5157 * Stage: The stage to modify
5158 * TexStageStateType: The state to change
5159 * State: The new value for the state
5161 * Returns:
5162 * D3D_OK on success
5163 * For details, see IWineD3DDevice::SetTextureStageState
5165 *****************************************************************************/
5166 static HRESULT
5167 IDirect3DDeviceImpl_7_SetTextureStageState(IDirect3DDevice7 *iface,
5168 DWORD Stage,
5169 D3DTEXTURESTAGESTATETYPE TexStageStateType,
5170 DWORD State)
5172 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5173 HRESULT hr;
5174 TRACE("(%p)->(%08x,%08x,%08x): Relay!\n", This, Stage, TexStageStateType, State);
5176 EnterCriticalSection(&ddraw_cs);
5177 switch(TexStageStateType)
5179 /* Mipfilter is a sampler state with different values */
5180 case D3DTSS_MIPFILTER:
5182 WINED3DTEXTUREFILTERTYPE value;
5183 switch(State)
5185 case D3DTFP_NONE: value = WINED3DTEXF_NONE; break;
5186 case D3DTFP_POINT: value = WINED3DTEXF_POINT; break;
5187 case 0: /* Unchecked */
5188 case D3DTFP_LINEAR: value = WINED3DTEXF_LINEAR; break;
5189 default:
5190 ERR("Unexpected mipfilter value %d\n", State);
5191 value = WINED3DTEXF_NONE;
5193 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
5194 Stage,
5195 WINED3DSAMP_MIPFILTER,
5196 value);
5197 break;
5200 /* Minfilter is a sampler state too, equal values */
5201 case D3DTSS_MINFILTER:
5202 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
5203 Stage,
5204 WINED3DSAMP_MINFILTER,
5205 State);
5206 break;
5208 /* Magfilter has slightly different values */
5209 case D3DTSS_MAGFILTER:
5211 WINED3DTEXTUREFILTERTYPE wined3dfilter;
5212 switch((D3DTEXTUREMAGFILTER) State)
5214 case D3DTFG_POINT: wined3dfilter = WINED3DTEXF_POINT; break;
5215 case D3DTFG_LINEAR: wined3dfilter = WINED3DTEXF_LINEAR; break;
5216 case D3DTFG_FLATCUBIC: wined3dfilter = WINED3DTEXF_FLATCUBIC; break;
5217 case D3DTFG_GAUSSIANCUBIC: wined3dfilter = WINED3DTEXF_GAUSSIANCUBIC; break;
5218 case D3DTFG_ANISOTROPIC: wined3dfilter = WINED3DTEXF_ANISOTROPIC; break;
5219 default:
5220 ERR("Unexpected d3d7 mag filter type %d\n", State);
5221 wined3dfilter = WINED3DTEXF_POINT;
5223 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
5224 Stage,
5225 WINED3DSAMP_MAGFILTER,
5226 wined3dfilter);
5227 break;
5230 case D3DTSS_ADDRESS:
5231 IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
5232 Stage,
5233 WINED3DSAMP_ADDRESSV,
5234 State);
5235 /* Drop through */
5236 case D3DTSS_ADDRESSU:
5237 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
5238 Stage,
5239 WINED3DSAMP_ADDRESSU,
5240 State);
5241 break;
5243 case D3DTSS_ADDRESSV:
5244 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
5245 Stage,
5246 WINED3DSAMP_ADDRESSV,
5247 State);
5248 break;
5250 default:
5251 hr = IWineD3DDevice_SetTextureStageState(This->wineD3DDevice,
5252 Stage,
5253 TexStageStateType,
5254 State);
5255 break;
5257 LeaveCriticalSection(&ddraw_cs);
5258 return hr;
5261 static HRESULT WINAPI
5262 IDirect3DDeviceImpl_7_SetTextureStageState_FPUSetup(IDirect3DDevice7 *iface,
5263 DWORD Stage,
5264 D3DTEXTURESTAGESTATETYPE TexStageStateType,
5265 DWORD State)
5267 return IDirect3DDeviceImpl_7_SetTextureStageState(iface, Stage, TexStageStateType, State);
5270 static HRESULT WINAPI
5271 IDirect3DDeviceImpl_7_SetTextureStageState_FPUPreserve(IDirect3DDevice7 *iface,
5272 DWORD Stage,
5273 D3DTEXTURESTAGESTATETYPE TexStageStateType,
5274 DWORD State)
5276 HRESULT hr;
5277 WORD old_fpucw;
5279 old_fpucw = d3d_fpu_setup();
5280 hr = IDirect3DDeviceImpl_7_SetTextureStageState(iface, Stage, TexStageStateType, State);
5281 set_fpu_control_word(old_fpucw);
5283 return hr;
5286 static HRESULT WINAPI
5287 Thunk_IDirect3DDeviceImpl_3_SetTextureStageState(IDirect3DDevice3 *iface,
5288 DWORD Stage,
5289 D3DTEXTURESTAGESTATETYPE TexStageStateType,
5290 DWORD State)
5292 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
5293 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, Stage, TexStageStateType, State);
5294 return IDirect3DDevice7_SetTextureStageState(ICOM_INTERFACE(This, IDirect3DDevice7),
5295 Stage,
5296 TexStageStateType,
5297 State);
5300 /*****************************************************************************
5301 * IDirect3DDevice7::ValidateDevice
5303 * SDK: "Reports the device's ability to render the currently set
5304 * texture-blending operations in a single pass". Whatever that means
5305 * exactly...
5307 * Version 3 and 7
5309 * Params:
5310 * NumPasses: Address to write the number of necessary passes for the
5311 * desired effect to.
5313 * Returns:
5314 * D3D_OK on success
5315 * See IWineD3DDevice::ValidateDevice for more details
5317 *****************************************************************************/
5318 static HRESULT
5319 IDirect3DDeviceImpl_7_ValidateDevice(IDirect3DDevice7 *iface,
5320 DWORD *NumPasses)
5322 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5323 HRESULT hr;
5324 TRACE("(%p)->(%p): Relay\n", This, NumPasses);
5326 EnterCriticalSection(&ddraw_cs);
5327 hr = IWineD3DDevice_ValidateDevice(This->wineD3DDevice, NumPasses);
5328 LeaveCriticalSection(&ddraw_cs);
5329 return hr;
5332 static HRESULT WINAPI
5333 IDirect3DDeviceImpl_7_ValidateDevice_FPUSetup(IDirect3DDevice7 *iface,
5334 DWORD *NumPasses)
5336 return IDirect3DDeviceImpl_7_ValidateDevice(iface, NumPasses);
5339 static HRESULT WINAPI
5340 IDirect3DDeviceImpl_7_ValidateDevice_FPUPreserve(IDirect3DDevice7 *iface,
5341 DWORD *NumPasses)
5343 HRESULT hr;
5344 WORD old_fpucw;
5346 old_fpucw = d3d_fpu_setup();
5347 hr = IDirect3DDeviceImpl_7_ValidateDevice(iface, NumPasses);
5348 set_fpu_control_word(old_fpucw);
5350 return hr;
5353 static HRESULT WINAPI
5354 Thunk_IDirect3DDeviceImpl_3_ValidateDevice(IDirect3DDevice3 *iface,
5355 DWORD *Passes)
5357 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
5358 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Passes);
5359 return IDirect3DDevice7_ValidateDevice(ICOM_INTERFACE(This, IDirect3DDevice7),
5360 Passes);
5363 /*****************************************************************************
5364 * IDirect3DDevice7::Clear
5366 * Fills the render target, the z buffer and the stencil buffer with a
5367 * clear color / value
5369 * Version 7 only
5371 * Params:
5372 * Count: Number of rectangles in Rects must be 0 if Rects is NULL
5373 * Rects: Rectangles to clear. If NULL, the whole surface is cleared
5374 * Flags: Some flags, as usual
5375 * Color: Clear color for the render target
5376 * Z: Clear value for the Z buffer
5377 * Stencil: Clear value to store in each stencil buffer entry
5379 * Returns:
5380 * D3D_OK on success
5381 * For details, see IWineD3DDevice::Clear
5383 *****************************************************************************/
5384 static HRESULT
5385 IDirect3DDeviceImpl_7_Clear(IDirect3DDevice7 *iface,
5386 DWORD Count,
5387 D3DRECT *Rects,
5388 DWORD Flags,
5389 D3DCOLOR Color,
5390 D3DVALUE Z,
5391 DWORD Stencil)
5393 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5394 HRESULT hr;
5395 TRACE("(%p)->(%08x,%p,%08x,%08x,%f,%08x): Relay\n", This, Count, Rects, Flags, Color, Z, Stencil);
5397 /* Note; D3DRECT is compatible with WINED3DRECT */
5398 EnterCriticalSection(&ddraw_cs);
5399 hr = IWineD3DDevice_Clear(This->wineD3DDevice, Count, (WINED3DRECT*) Rects, Flags, Color, Z, Stencil);
5400 LeaveCriticalSection(&ddraw_cs);
5401 return hr;
5404 static HRESULT WINAPI
5405 IDirect3DDeviceImpl_7_Clear_FPUSetup(IDirect3DDevice7 *iface,
5406 DWORD Count,
5407 D3DRECT *Rects,
5408 DWORD Flags,
5409 D3DCOLOR Color,
5410 D3DVALUE Z,
5411 DWORD Stencil)
5413 return IDirect3DDeviceImpl_7_Clear(iface, Count, Rects, Flags, Color, Z, Stencil);
5416 static HRESULT WINAPI
5417 IDirect3DDeviceImpl_7_Clear_FPUPreserve(IDirect3DDevice7 *iface,
5418 DWORD Count,
5419 D3DRECT *Rects,
5420 DWORD Flags,
5421 D3DCOLOR Color,
5422 D3DVALUE Z,
5423 DWORD Stencil)
5425 HRESULT hr;
5426 WORD old_fpucw;
5428 old_fpucw = d3d_fpu_setup();
5429 hr = IDirect3DDeviceImpl_7_Clear(iface, Count, Rects, Flags, Color, Z, Stencil);
5430 set_fpu_control_word(old_fpucw);
5432 return hr;
5435 /*****************************************************************************
5436 * IDirect3DDevice7::SetViewport
5438 * Sets the current viewport.
5440 * Version 7 only, but IDirect3DViewport uses this call for older
5441 * versions
5443 * Params:
5444 * Data: The new viewport to set
5446 * Returns:
5447 * D3D_OK on success
5448 * DDERR_INVALIDPARAMS if Data is NULL
5449 * For more details, see IWineDDDevice::SetViewport
5451 *****************************************************************************/
5452 static HRESULT
5453 IDirect3DDeviceImpl_7_SetViewport(IDirect3DDevice7 *iface,
5454 D3DVIEWPORT7 *Data)
5456 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5457 HRESULT hr;
5458 TRACE("(%p)->(%p) Relay!\n", This, Data);
5460 if(!Data)
5461 return DDERR_INVALIDPARAMS;
5463 /* Note: D3DVIEWPORT7 is compatible with WINED3DVIEWPORT */
5464 EnterCriticalSection(&ddraw_cs);
5465 hr = IWineD3DDevice_SetViewport(This->wineD3DDevice,
5466 (WINED3DVIEWPORT*) Data);
5467 LeaveCriticalSection(&ddraw_cs);
5468 return hr;
5471 static HRESULT WINAPI
5472 IDirect3DDeviceImpl_7_SetViewport_FPUSetup(IDirect3DDevice7 *iface,
5473 D3DVIEWPORT7 *Data)
5475 return IDirect3DDeviceImpl_7_SetViewport(iface, Data);
5478 static HRESULT WINAPI
5479 IDirect3DDeviceImpl_7_SetViewport_FPUPreserve(IDirect3DDevice7 *iface,
5480 D3DVIEWPORT7 *Data)
5482 HRESULT hr;
5483 WORD old_fpucw;
5485 old_fpucw = d3d_fpu_setup();
5486 hr = IDirect3DDeviceImpl_7_SetViewport(iface, Data);
5487 set_fpu_control_word(old_fpucw);
5489 return hr;
5492 /*****************************************************************************
5493 * IDirect3DDevice::GetViewport
5495 * Returns the current viewport
5497 * Version 7
5499 * Params:
5500 * Data: D3D7Viewport structure to write the viewport information to
5502 * Returns:
5503 * D3D_OK on success
5504 * DDERR_INVALIDPARAMS if Data is NULL
5505 * For more details, see IWineD3DDevice::GetViewport
5507 *****************************************************************************/
5508 static HRESULT
5509 IDirect3DDeviceImpl_7_GetViewport(IDirect3DDevice7 *iface,
5510 D3DVIEWPORT7 *Data)
5512 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5513 HRESULT hr;
5514 TRACE("(%p)->(%p) Relay!\n", This, Data);
5516 if(!Data)
5517 return DDERR_INVALIDPARAMS;
5519 /* Note: D3DVIEWPORT7 is compatible with WINED3DVIEWPORT */
5520 EnterCriticalSection(&ddraw_cs);
5521 hr = IWineD3DDevice_GetViewport(This->wineD3DDevice,
5522 (WINED3DVIEWPORT*) Data);
5524 LeaveCriticalSection(&ddraw_cs);
5525 return hr_ddraw_from_wined3d(hr);
5528 static HRESULT WINAPI
5529 IDirect3DDeviceImpl_7_GetViewport_FPUSetup(IDirect3DDevice7 *iface,
5530 D3DVIEWPORT7 *Data)
5532 return IDirect3DDeviceImpl_7_GetViewport(iface, Data);
5535 static HRESULT WINAPI
5536 IDirect3DDeviceImpl_7_GetViewport_FPUPreserve(IDirect3DDevice7 *iface,
5537 D3DVIEWPORT7 *Data)
5539 HRESULT hr;
5540 WORD old_fpucw;
5542 old_fpucw = d3d_fpu_setup();
5543 hr = IDirect3DDeviceImpl_7_GetViewport(iface, Data);
5544 set_fpu_control_word(old_fpucw);
5546 return hr;
5549 /*****************************************************************************
5550 * IDirect3DDevice7::SetMaterial
5552 * Sets the Material
5554 * Version 7
5556 * Params:
5557 * Mat: The material to set
5559 * Returns:
5560 * D3D_OK on success
5561 * DDERR_INVALIDPARAMS if Mat is NULL.
5562 * For more details, see IWineD3DDevice::SetMaterial
5564 *****************************************************************************/
5565 static HRESULT
5566 IDirect3DDeviceImpl_7_SetMaterial(IDirect3DDevice7 *iface,
5567 D3DMATERIAL7 *Mat)
5569 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5570 HRESULT hr;
5571 TRACE("(%p)->(%p): Relay!\n", This, Mat);
5573 if (!Mat) return DDERR_INVALIDPARAMS;
5574 /* Note: D3DMATERIAL7 is compatible with WINED3DMATERIAL */
5575 EnterCriticalSection(&ddraw_cs);
5576 hr = IWineD3DDevice_SetMaterial(This->wineD3DDevice,
5577 (WINED3DMATERIAL*) Mat);
5578 LeaveCriticalSection(&ddraw_cs);
5579 return hr_ddraw_from_wined3d(hr);
5582 static HRESULT WINAPI
5583 IDirect3DDeviceImpl_7_SetMaterial_FPUSetup(IDirect3DDevice7 *iface,
5584 D3DMATERIAL7 *Mat)
5586 return IDirect3DDeviceImpl_7_SetMaterial(iface, Mat);
5589 static HRESULT WINAPI
5590 IDirect3DDeviceImpl_7_SetMaterial_FPUPreserve(IDirect3DDevice7 *iface,
5591 D3DMATERIAL7 *Mat)
5593 HRESULT hr;
5594 WORD old_fpucw;
5596 old_fpucw = d3d_fpu_setup();
5597 hr = IDirect3DDeviceImpl_7_SetMaterial(iface, Mat);
5598 set_fpu_control_word(old_fpucw);
5600 return hr;
5603 /*****************************************************************************
5604 * IDirect3DDevice7::GetMaterial
5606 * Returns the current material
5608 * Version 7
5610 * Params:
5611 * Mat: D3DMATERIAL7 structure to write the material parameters to
5613 * Returns:
5614 * D3D_OK on success
5615 * DDERR_INVALIDPARAMS if Mat is NULL
5616 * For more details, see IWineD3DDevice::GetMaterial
5618 *****************************************************************************/
5619 static HRESULT
5620 IDirect3DDeviceImpl_7_GetMaterial(IDirect3DDevice7 *iface,
5621 D3DMATERIAL7 *Mat)
5623 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5624 HRESULT hr;
5625 TRACE("(%p)->(%p): Relay!\n", This, Mat);
5627 EnterCriticalSection(&ddraw_cs);
5628 /* Note: D3DMATERIAL7 is compatible with WINED3DMATERIAL */
5629 hr = IWineD3DDevice_GetMaterial(This->wineD3DDevice,
5630 (WINED3DMATERIAL*) Mat);
5631 LeaveCriticalSection(&ddraw_cs);
5632 return hr_ddraw_from_wined3d(hr);
5635 static HRESULT WINAPI
5636 IDirect3DDeviceImpl_7_GetMaterial_FPUSetup(IDirect3DDevice7 *iface,
5637 D3DMATERIAL7 *Mat)
5639 return IDirect3DDeviceImpl_7_GetMaterial(iface, Mat);
5642 static HRESULT WINAPI
5643 IDirect3DDeviceImpl_7_GetMaterial_FPUPreserve(IDirect3DDevice7 *iface,
5644 D3DMATERIAL7 *Mat)
5646 HRESULT hr;
5647 WORD old_fpucw;
5649 old_fpucw = d3d_fpu_setup();
5650 hr = IDirect3DDeviceImpl_7_GetMaterial(iface, Mat);
5651 set_fpu_control_word(old_fpucw);
5653 return hr;
5656 /*****************************************************************************
5657 * IDirect3DDevice7::SetLight
5659 * Assigns a light to a light index, but doesn't activate it yet.
5661 * Version 7, IDirect3DLight uses this method for older versions
5663 * Params:
5664 * LightIndex: The index of the new light
5665 * Light: A D3DLIGHT7 structure describing the light
5667 * Returns:
5668 * D3D_OK on success
5669 * For more details, see IWineD3DDevice::SetLight
5671 *****************************************************************************/
5672 static HRESULT
5673 IDirect3DDeviceImpl_7_SetLight(IDirect3DDevice7 *iface,
5674 DWORD LightIndex,
5675 D3DLIGHT7 *Light)
5677 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5678 HRESULT hr;
5679 TRACE("(%p)->(%08x,%p): Relay!\n", This, LightIndex, Light);
5681 EnterCriticalSection(&ddraw_cs);
5682 /* Note: D3DLIGHT7 is compatible with WINED3DLIGHT */
5683 hr = IWineD3DDevice_SetLight(This->wineD3DDevice,
5684 LightIndex,
5685 (WINED3DLIGHT*) Light);
5686 LeaveCriticalSection(&ddraw_cs);
5687 return hr_ddraw_from_wined3d(hr);
5690 static HRESULT WINAPI
5691 IDirect3DDeviceImpl_7_SetLight_FPUSetup(IDirect3DDevice7 *iface,
5692 DWORD LightIndex,
5693 D3DLIGHT7 *Light)
5695 return IDirect3DDeviceImpl_7_SetLight(iface, LightIndex, Light);
5698 static HRESULT WINAPI
5699 IDirect3DDeviceImpl_7_SetLight_FPUPreserve(IDirect3DDevice7 *iface,
5700 DWORD LightIndex,
5701 D3DLIGHT7 *Light)
5703 HRESULT hr;
5704 WORD old_fpucw;
5706 old_fpucw = d3d_fpu_setup();
5707 hr = IDirect3DDeviceImpl_7_SetLight(iface, LightIndex, Light);
5708 set_fpu_control_word(old_fpucw);
5710 return hr;
5713 /*****************************************************************************
5714 * IDirect3DDevice7::GetLight
5716 * Returns the light assigned to a light index
5718 * Params:
5719 * Light: Structure to write the light information to
5721 * Returns:
5722 * D3D_OK on success
5723 * DDERR_INVALIDPARAMS if Light is NULL
5724 * For details, see IWineD3DDevice::GetLight
5726 *****************************************************************************/
5727 static HRESULT
5728 IDirect3DDeviceImpl_7_GetLight(IDirect3DDevice7 *iface,
5729 DWORD LightIndex,
5730 D3DLIGHT7 *Light)
5732 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5733 HRESULT rc;
5734 TRACE("(%p)->(%08x,%p): Relay!\n", This, LightIndex, Light);
5736 EnterCriticalSection(&ddraw_cs);
5737 /* Note: D3DLIGHT7 is compatible with WINED3DLIGHT */
5738 rc = IWineD3DDevice_GetLight(This->wineD3DDevice,
5739 LightIndex,
5740 (WINED3DLIGHT*) Light);
5742 /* Translate the result. WineD3D returns other values than D3D7 */
5743 LeaveCriticalSection(&ddraw_cs);
5744 return hr_ddraw_from_wined3d(rc);
5747 static HRESULT WINAPI
5748 IDirect3DDeviceImpl_7_GetLight_FPUSetup(IDirect3DDevice7 *iface,
5749 DWORD LightIndex,
5750 D3DLIGHT7 *Light)
5752 return IDirect3DDeviceImpl_7_GetLight(iface, LightIndex, Light);
5755 static HRESULT WINAPI
5756 IDirect3DDeviceImpl_7_GetLight_FPUPreserve(IDirect3DDevice7 *iface,
5757 DWORD LightIndex,
5758 D3DLIGHT7 *Light)
5760 HRESULT hr;
5761 WORD old_fpucw;
5763 old_fpucw = d3d_fpu_setup();
5764 hr = IDirect3DDeviceImpl_7_GetLight(iface, LightIndex, Light);
5765 set_fpu_control_word(old_fpucw);
5767 return hr;
5770 /*****************************************************************************
5771 * IDirect3DDevice7::BeginStateBlock
5773 * Begins recording to a stateblock
5775 * Version 7
5777 * Returns:
5778 * D3D_OK on success
5779 * For details see IWineD3DDevice::BeginStateBlock
5781 *****************************************************************************/
5782 static HRESULT
5783 IDirect3DDeviceImpl_7_BeginStateBlock(IDirect3DDevice7 *iface)
5785 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5786 HRESULT hr;
5787 TRACE("(%p)->(): Relay!\n", This);
5789 EnterCriticalSection(&ddraw_cs);
5790 hr = IWineD3DDevice_BeginStateBlock(This->wineD3DDevice);
5791 LeaveCriticalSection(&ddraw_cs);
5792 return hr_ddraw_from_wined3d(hr);
5795 static HRESULT WINAPI
5796 IDirect3DDeviceImpl_7_BeginStateBlock_FPUSetup(IDirect3DDevice7 *iface)
5798 return IDirect3DDeviceImpl_7_BeginStateBlock(iface);
5801 static HRESULT WINAPI
5802 IDirect3DDeviceImpl_7_BeginStateBlock_FPUPreserve(IDirect3DDevice7 *iface)
5804 HRESULT hr;
5805 WORD old_fpucw;
5807 old_fpucw = d3d_fpu_setup();
5808 hr = IDirect3DDeviceImpl_7_BeginStateBlock(iface);
5809 set_fpu_control_word(old_fpucw);
5811 return hr;
5814 /*****************************************************************************
5815 * IDirect3DDevice7::EndStateBlock
5817 * Stops recording to a state block and returns the created stateblock
5818 * handle.
5820 * Version 7
5822 * Params:
5823 * BlockHandle: Address to store the stateblock's handle to
5825 * Returns:
5826 * D3D_OK on success
5827 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5828 * See IWineD3DDevice::EndStateBlock for more details
5830 *****************************************************************************/
5831 static HRESULT
5832 IDirect3DDeviceImpl_7_EndStateBlock(IDirect3DDevice7 *iface,
5833 DWORD *BlockHandle)
5835 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5836 HRESULT hr;
5837 TRACE("(%p)->(%p): Relay!\n", This, BlockHandle);
5839 if(!BlockHandle)
5841 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
5842 return DDERR_INVALIDPARAMS;
5845 EnterCriticalSection(&ddraw_cs);
5846 *BlockHandle = IDirect3DDeviceImpl_CreateHandle(This);
5847 if(!*BlockHandle)
5849 ERR("Cannot get a handle number for the stateblock\n");
5850 LeaveCriticalSection(&ddraw_cs);
5851 return DDERR_OUTOFMEMORY;
5853 This->Handles[*BlockHandle - 1].type = DDrawHandle_StateBlock;
5854 hr = IWineD3DDevice_EndStateBlock(This->wineD3DDevice,
5855 (IWineD3DStateBlock **) &This->Handles[*BlockHandle - 1].ptr);
5856 LeaveCriticalSection(&ddraw_cs);
5857 return hr_ddraw_from_wined3d(hr);
5860 static HRESULT WINAPI
5861 IDirect3DDeviceImpl_7_EndStateBlock_FPUSetup(IDirect3DDevice7 *iface,
5862 DWORD *BlockHandle)
5864 return IDirect3DDeviceImpl_7_EndStateBlock(iface, BlockHandle);
5867 static HRESULT WINAPI
5868 IDirect3DDeviceImpl_7_EndStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
5869 DWORD *BlockHandle)
5871 HRESULT hr;
5872 WORD old_fpucw;
5874 old_fpucw = d3d_fpu_setup();
5875 hr = IDirect3DDeviceImpl_7_EndStateBlock(iface, BlockHandle);
5876 set_fpu_control_word(old_fpucw);
5878 return hr;
5881 /*****************************************************************************
5882 * IDirect3DDevice7::PreLoad
5884 * Allows the app to signal that a texture will be used soon, to allow
5885 * the Direct3DDevice to load it to the video card in the meantime.
5887 * Version 7
5889 * Params:
5890 * Texture: The texture to preload
5892 * Returns:
5893 * D3D_OK on success
5894 * DDERR_INVALIDPARAMS if Texture is NULL
5895 * See IWineD3DSurface::PreLoad for details
5897 *****************************************************************************/
5898 static HRESULT
5899 IDirect3DDeviceImpl_7_PreLoad(IDirect3DDevice7 *iface,
5900 IDirectDrawSurface7 *Texture)
5902 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5903 IDirectDrawSurfaceImpl *surf = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, Texture);
5905 TRACE("(%p)->(%p): Relay!\n", This, surf);
5907 if(!Texture)
5908 return DDERR_INVALIDPARAMS;
5910 EnterCriticalSection(&ddraw_cs);
5911 IWineD3DSurface_PreLoad(surf->WineD3DSurface);
5912 LeaveCriticalSection(&ddraw_cs);
5913 return D3D_OK;
5916 static HRESULT WINAPI
5917 IDirect3DDeviceImpl_7_PreLoad_FPUSetup(IDirect3DDevice7 *iface,
5918 IDirectDrawSurface7 *Texture)
5920 return IDirect3DDeviceImpl_7_PreLoad(iface, Texture);
5923 static HRESULT WINAPI
5924 IDirect3DDeviceImpl_7_PreLoad_FPUPreserve(IDirect3DDevice7 *iface,
5925 IDirectDrawSurface7 *Texture)
5927 HRESULT hr;
5928 WORD old_fpucw;
5930 old_fpucw = d3d_fpu_setup();
5931 hr = IDirect3DDeviceImpl_7_PreLoad(iface, Texture);
5932 set_fpu_control_word(old_fpucw);
5934 return hr;
5937 /*****************************************************************************
5938 * IDirect3DDevice7::ApplyStateBlock
5940 * Activates the state stored in a state block handle.
5942 * Params:
5943 * BlockHandle: The stateblock handle to activate
5945 * Returns:
5946 * D3D_OK on success
5947 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5949 *****************************************************************************/
5950 static HRESULT
5951 IDirect3DDeviceImpl_7_ApplyStateBlock(IDirect3DDevice7 *iface,
5952 DWORD BlockHandle)
5954 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5955 HRESULT hr;
5956 TRACE("(%p)->(%08x): Relay!\n", This, BlockHandle);
5958 EnterCriticalSection(&ddraw_cs);
5959 if(!BlockHandle || BlockHandle > This->numHandles)
5961 WARN("Out of range handle %d, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5962 LeaveCriticalSection(&ddraw_cs);
5963 return D3DERR_INVALIDSTATEBLOCK;
5965 if(This->Handles[BlockHandle - 1].type != DDrawHandle_StateBlock)
5967 WARN("Handle %d is not a stateblock, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5968 LeaveCriticalSection(&ddraw_cs);
5969 return D3DERR_INVALIDSTATEBLOCK;
5972 hr = IWineD3DStateBlock_Apply((IWineD3DStateBlock *) This->Handles[BlockHandle - 1].ptr);
5973 LeaveCriticalSection(&ddraw_cs);
5974 return hr_ddraw_from_wined3d(hr);
5977 static HRESULT WINAPI
5978 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUSetup(IDirect3DDevice7 *iface,
5979 DWORD BlockHandle)
5981 return IDirect3DDeviceImpl_7_ApplyStateBlock(iface, BlockHandle);
5984 static HRESULT WINAPI
5985 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
5986 DWORD BlockHandle)
5988 HRESULT hr;
5989 WORD old_fpucw;
5991 old_fpucw = d3d_fpu_setup();
5992 hr = IDirect3DDeviceImpl_7_ApplyStateBlock(iface, BlockHandle);
5993 set_fpu_control_word(old_fpucw);
5995 return hr;
5998 /*****************************************************************************
5999 * IDirect3DDevice7::CaptureStateBlock
6001 * Updates a stateblock's values to the values currently set for the device
6003 * Version 7
6005 * Params:
6006 * BlockHandle: Stateblock to update
6008 * Returns:
6009 * D3D_OK on success
6010 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
6011 * See IWineD3DDevice::CaptureStateBlock for more details
6013 *****************************************************************************/
6014 static HRESULT
6015 IDirect3DDeviceImpl_7_CaptureStateBlock(IDirect3DDevice7 *iface,
6016 DWORD BlockHandle)
6018 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
6019 HRESULT hr;
6020 TRACE("(%p)->(%08x): Relay!\n", This, BlockHandle);
6022 EnterCriticalSection(&ddraw_cs);
6023 if(BlockHandle == 0 || BlockHandle > This->numHandles)
6025 WARN("Out of range handle %d, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
6026 LeaveCriticalSection(&ddraw_cs);
6027 return D3DERR_INVALIDSTATEBLOCK;
6029 if(This->Handles[BlockHandle - 1].type != DDrawHandle_StateBlock)
6031 WARN("Handle %d is not a stateblock, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
6032 LeaveCriticalSection(&ddraw_cs);
6033 return D3DERR_INVALIDSTATEBLOCK;
6036 hr = IWineD3DStateBlock_Capture((IWineD3DStateBlock *) This->Handles[BlockHandle - 1].ptr);
6037 LeaveCriticalSection(&ddraw_cs);
6038 return hr_ddraw_from_wined3d(hr);
6041 static HRESULT WINAPI
6042 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUSetup(IDirect3DDevice7 *iface,
6043 DWORD BlockHandle)
6045 return IDirect3DDeviceImpl_7_CaptureStateBlock(iface, BlockHandle);
6048 static HRESULT WINAPI
6049 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
6050 DWORD BlockHandle)
6052 HRESULT hr;
6053 WORD old_fpucw;
6055 old_fpucw = d3d_fpu_setup();
6056 hr = IDirect3DDeviceImpl_7_CaptureStateBlock(iface, BlockHandle);
6057 set_fpu_control_word(old_fpucw);
6059 return hr;
6062 /*****************************************************************************
6063 * IDirect3DDevice7::DeleteStateBlock
6065 * Deletes a stateblock handle. This means releasing the WineD3DStateBlock
6067 * Version 7
6069 * Params:
6070 * BlockHandle: Stateblock handle to delete
6072 * Returns:
6073 * D3D_OK on success
6074 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is 0
6076 *****************************************************************************/
6077 static HRESULT
6078 IDirect3DDeviceImpl_7_DeleteStateBlock(IDirect3DDevice7 *iface,
6079 DWORD BlockHandle)
6081 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
6082 ULONG ref;
6083 TRACE("(%p)->(%08x): Relay!\n", This, BlockHandle);
6085 EnterCriticalSection(&ddraw_cs);
6086 if(BlockHandle == 0 || BlockHandle > This->numHandles)
6088 WARN("Out of range handle %d, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
6089 LeaveCriticalSection(&ddraw_cs);
6090 return D3DERR_INVALIDSTATEBLOCK;
6092 if(This->Handles[BlockHandle - 1].type != DDrawHandle_StateBlock)
6094 WARN("Handle %d is not a stateblock, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
6095 LeaveCriticalSection(&ddraw_cs);
6096 return D3DERR_INVALIDSTATEBLOCK;
6099 ref = IWineD3DStateBlock_Release((IWineD3DStateBlock *) This->Handles[BlockHandle - 1].ptr);
6100 if(ref)
6102 ERR("Something is still holding the stateblock %p(Handle %d). Ref = %d\n", This->Handles[BlockHandle - 1].ptr, BlockHandle, ref);
6104 This->Handles[BlockHandle - 1].ptr = NULL;
6105 This->Handles[BlockHandle - 1].type = DDrawHandle_Unknown;
6107 LeaveCriticalSection(&ddraw_cs);
6108 return D3D_OK;
6111 static HRESULT WINAPI
6112 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUSetup(IDirect3DDevice7 *iface,
6113 DWORD BlockHandle)
6115 return IDirect3DDeviceImpl_7_DeleteStateBlock(iface, BlockHandle);
6118 static HRESULT WINAPI
6119 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
6120 DWORD BlockHandle)
6122 HRESULT hr;
6123 WORD old_fpucw;
6125 old_fpucw = d3d_fpu_setup();
6126 hr = IDirect3DDeviceImpl_7_DeleteStateBlock(iface, BlockHandle);
6127 set_fpu_control_word(old_fpucw);
6129 return hr;
6132 /*****************************************************************************
6133 * IDirect3DDevice7::CreateStateBlock
6135 * Creates a new state block handle.
6137 * Version 7
6139 * Params:
6140 * Type: The state block type
6141 * BlockHandle: Address to write the created handle to
6143 * Returns:
6144 * D3D_OK on success
6145 * DDERR_INVALIDPARAMS if BlockHandle is NULL
6147 *****************************************************************************/
6148 static HRESULT
6149 IDirect3DDeviceImpl_7_CreateStateBlock(IDirect3DDevice7 *iface,
6150 D3DSTATEBLOCKTYPE Type,
6151 DWORD *BlockHandle)
6153 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
6154 HRESULT hr;
6155 TRACE("(%p)->(%08x,%p)!\n", This, Type, BlockHandle);
6157 if(!BlockHandle)
6159 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
6160 return DDERR_INVALIDPARAMS;
6162 if(Type != D3DSBT_ALL && Type != D3DSBT_PIXELSTATE &&
6163 Type != D3DSBT_VERTEXSTATE ) {
6164 WARN("Unexpected stateblock type, returning DDERR_INVALIDPARAMS\n");
6165 return DDERR_INVALIDPARAMS;
6168 EnterCriticalSection(&ddraw_cs);
6169 *BlockHandle = IDirect3DDeviceImpl_CreateHandle(This);
6170 if(!*BlockHandle)
6172 ERR("Cannot get a handle number for the stateblock\n");
6173 LeaveCriticalSection(&ddraw_cs);
6174 return DDERR_OUTOFMEMORY;
6176 This->Handles[*BlockHandle - 1].type = DDrawHandle_StateBlock;
6178 /* The D3DSTATEBLOCKTYPE enum is fine here */
6179 hr = IWineD3DDevice_CreateStateBlock(This->wineD3DDevice,
6180 Type,
6181 (IWineD3DStateBlock **) &This->Handles[*BlockHandle - 1].ptr,
6182 NULL /* Parent, hope that works */);
6183 LeaveCriticalSection(&ddraw_cs);
6184 return hr_ddraw_from_wined3d(hr);
6187 static HRESULT WINAPI
6188 IDirect3DDeviceImpl_7_CreateStateBlock_FPUSetup(IDirect3DDevice7 *iface,
6189 D3DSTATEBLOCKTYPE Type,
6190 DWORD *BlockHandle)
6192 return IDirect3DDeviceImpl_7_CreateStateBlock(iface, Type, BlockHandle);
6195 static HRESULT WINAPI
6196 IDirect3DDeviceImpl_7_CreateStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
6197 D3DSTATEBLOCKTYPE Type,
6198 DWORD *BlockHandle)
6200 HRESULT hr;
6201 WORD old_fpucw;
6203 old_fpucw = d3d_fpu_setup();
6204 hr =IDirect3DDeviceImpl_7_CreateStateBlock(iface, Type, BlockHandle);
6205 set_fpu_control_word(old_fpucw);
6207 return hr;
6210 /* Helper function for IDirect3DDeviceImpl_7_Load. */
6211 static BOOL is_mip_level_subset(IDirectDrawSurfaceImpl *dest,
6212 IDirectDrawSurfaceImpl *src)
6214 IDirectDrawSurfaceImpl *src_level, *dest_level;
6215 IDirectDrawSurface7 *temp;
6216 DDSURFACEDESC2 ddsd;
6217 BOOL levelFound; /* at least one suitable sublevel in dest found */
6219 /* To satisfy "destination is mip level subset of source" criteria (regular texture counts as 1 level),
6220 * 1) there must be at least one mip level in destination that matched dimensions of some mip level in source and
6221 * 2) there must be no destination levels that don't match any levels in source. Otherwise it's INVALIDPARAMS.
6223 levelFound = FALSE;
6225 src_level = src;
6226 dest_level = dest;
6228 for (;src_level && dest_level;)
6230 if (src_level->surface_desc.dwWidth == dest_level->surface_desc.dwWidth &&
6231 src_level->surface_desc.dwHeight == dest_level->surface_desc.dwHeight)
6233 levelFound = TRUE;
6235 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6236 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
6237 IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(dest_level, IDirectDrawSurface7), &ddsd.ddsCaps, &temp);
6239 if (dest_level != dest) IDirectDrawSurface7_Release(ICOM_INTERFACE(dest_level, IDirectDrawSurface7));
6241 dest_level = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, temp);
6244 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6245 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
6246 IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(src_level, IDirectDrawSurface7), &ddsd.ddsCaps, &temp);
6248 if (src_level != src) IDirectDrawSurface7_Release(ICOM_INTERFACE(src_level, IDirectDrawSurface7));
6250 src_level = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, temp);
6253 if (src_level && src_level != src) IDirectDrawSurface7_Release(ICOM_INTERFACE(src_level, IDirectDrawSurface7));
6254 if (dest_level && dest_level != dest) IDirectDrawSurface7_Release(ICOM_INTERFACE(dest_level, IDirectDrawSurface7));
6256 return !dest_level && levelFound;
6259 /* Helper function for IDirect3DDeviceImpl_7_Load. */
6260 static void copy_mipmap_chain(IDirect3DDeviceImpl *device,
6261 IDirectDrawSurfaceImpl *dest,
6262 IDirectDrawSurfaceImpl *src,
6263 POINT *DestPoint,
6264 RECT *SrcRect)
6266 IDirectDrawSurfaceImpl *src_level, *dest_level;
6267 IDirectDrawSurface7 *temp;
6268 DDSURFACEDESC2 ddsd;
6269 POINT point;
6270 RECT rect;
6271 HRESULT hr;
6272 IDirectDrawPalette *pal = NULL, *pal_src = NULL;
6273 DWORD ckeyflag;
6274 DDCOLORKEY ddckey;
6275 BOOL palette_missing = FALSE;
6277 /* Copy palette, if possible. */
6278 IDirectDrawSurface7_GetPalette(ICOM_INTERFACE(src, IDirectDrawSurface7), &pal_src);
6279 IDirectDrawSurface7_GetPalette(ICOM_INTERFACE(dest, IDirectDrawSurface7), &pal);
6281 if (pal_src != NULL && pal != NULL)
6283 PALETTEENTRY palent[256];
6285 IDirectDrawPalette_GetEntries(pal_src, 0, 0, 256, palent);
6286 IDirectDrawPalette_SetEntries(pal, 0, 0, 256, palent);
6289 if (dest->surface_desc.u4.ddpfPixelFormat.dwFlags & (DDPF_PALETTEINDEXED1 | DDPF_PALETTEINDEXED2 |
6290 DDPF_PALETTEINDEXED4 | DDPF_PALETTEINDEXED8 | DDPF_PALETTEINDEXEDTO8) && !pal)
6292 palette_missing = TRUE;
6295 if (pal) IDirectDrawPalette_Release(pal);
6296 if (pal_src) IDirectDrawPalette_Release(pal_src);
6298 /* Copy colorkeys, if present. */
6299 for (ckeyflag = DDCKEY_DESTBLT; ckeyflag <= DDCKEY_SRCOVERLAY; ckeyflag <<= 1)
6301 hr = IDirectDrawSurface7_GetColorKey(ICOM_INTERFACE(src, IDirectDrawSurface7), ckeyflag, &ddckey);
6303 if (SUCCEEDED(hr))
6305 IDirectDrawSurface7_SetColorKey(ICOM_INTERFACE(dest, IDirectDrawSurface7), ckeyflag, &ddckey);
6309 src_level = src;
6310 dest_level = dest;
6312 point = *DestPoint;
6313 rect = *SrcRect;
6315 for (;src_level && dest_level;)
6317 if (src_level->surface_desc.dwWidth == dest_level->surface_desc.dwWidth &&
6318 src_level->surface_desc.dwHeight == dest_level->surface_desc.dwHeight)
6320 /* Try UpdateSurface that may perform a more direct opengl loading. But skip this if destination is paletted texture and has no palette.
6321 * Some games like Sacrifice set palette after Load, and it is a waste of effort to try to load texture without palette and generates
6322 * warnings in wined3d. */
6323 if (!palette_missing)
6324 hr = IWineD3DDevice_UpdateSurface(device->wineD3DDevice, src_level->WineD3DSurface, &rect, dest_level->WineD3DSurface,
6325 &point);
6327 if (palette_missing || FAILED(hr))
6329 /* UpdateSurface may fail e.g. if dest is in system memory. Fall back to BltFast that is less strict. */
6330 IWineD3DSurface_BltFast(dest_level->WineD3DSurface,
6331 point.x, point.y,
6332 src_level->WineD3DSurface, &rect, 0);
6335 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6336 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
6337 IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(dest_level, IDirectDrawSurface7), &ddsd.ddsCaps, &temp);
6339 if (dest_level != dest) IDirectDrawSurface7_Release(ICOM_INTERFACE(dest_level, IDirectDrawSurface7));
6341 dest_level = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, temp);
6344 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6345 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
6346 IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(src_level, IDirectDrawSurface7), &ddsd.ddsCaps, &temp);
6348 if (src_level != src) IDirectDrawSurface7_Release(ICOM_INTERFACE(src_level, IDirectDrawSurface7));
6350 src_level = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, temp);
6352 point.x /= 2;
6353 point.y /= 2;
6355 rect.top /= 2;
6356 rect.left /= 2;
6357 rect.right = (rect.right + 1) / 2;
6358 rect.bottom = (rect.bottom + 1) / 2;
6361 if (src_level && src_level != src) IDirectDrawSurface7_Release(ICOM_INTERFACE(src_level, IDirectDrawSurface7));
6362 if (dest_level && dest_level != dest) IDirectDrawSurface7_Release(ICOM_INTERFACE(dest_level, IDirectDrawSurface7));
6365 /*****************************************************************************
6366 * IDirect3DDevice7::Load
6368 * Loads a rectangular area from the source into the destination texture.
6369 * It can also copy the source to the faces of a cubic environment map
6371 * Version 7
6373 * Params:
6374 * DestTex: Destination texture
6375 * DestPoint: Point in the destination where the source image should be
6376 * written to
6377 * SrcTex: Source texture
6378 * SrcRect: Source rectangle
6379 * Flags: Cubemap faces to load (DDSCAPS2_CUBEMAP_ALLFACES, DDSCAPS2_CUBEMAP_POSITIVEX,
6380 * DDSCAPS2_CUBEMAP_NEGATIVEX, DDSCAPS2_CUBEMAP_POSITIVEY, DDSCAPS2_CUBEMAP_NEGATIVEY,
6381 * DDSCAPS2_CUBEMAP_POSITIVEZ, DDSCAPS2_CUBEMAP_NEGATIVEZ)
6383 * Returns:
6384 * D3D_OK on success
6385 * DDERR_INVALIDPARAMS if DestTex or SrcTex are NULL, broken coordinates or anything unexpected.
6388 *****************************************************************************/
6390 static HRESULT
6391 IDirect3DDeviceImpl_7_Load(IDirect3DDevice7 *iface,
6392 IDirectDrawSurface7 *DestTex,
6393 POINT *DestPoint,
6394 IDirectDrawSurface7 *SrcTex,
6395 RECT *SrcRect,
6396 DWORD Flags)
6398 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
6399 IDirectDrawSurfaceImpl *dest = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, DestTex);
6400 IDirectDrawSurfaceImpl *src = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, SrcTex);
6401 POINT destpoint;
6402 RECT srcrect;
6403 TRACE("(%p)->(%p,%p,%p,%p,%08x)\n", This, dest, DestPoint, src, SrcRect, Flags);
6405 if( (!src) || (!dest) )
6406 return DDERR_INVALIDPARAMS;
6408 EnterCriticalSection(&ddraw_cs);
6410 if (SrcRect) srcrect = *SrcRect;
6411 else
6413 srcrect.left = srcrect.top = 0;
6414 srcrect.right = src->surface_desc.dwWidth;
6415 srcrect.bottom = src->surface_desc.dwHeight;
6418 if (DestPoint) destpoint = *DestPoint;
6419 else
6421 destpoint.x = destpoint.y = 0;
6423 /* Check bad dimensions. DestPoint is validated against src, not dest, because
6424 * destination can be a subset of mip levels, in which case actual coordinates used
6425 * for it may be divided. If any dimension of dest is larger than source, it can't be
6426 * mip level subset, so an error can be returned early.
6428 if (srcrect.left >= srcrect.right || srcrect.top >= srcrect.bottom ||
6429 srcrect.right > src->surface_desc.dwWidth ||
6430 srcrect.bottom > src->surface_desc.dwHeight ||
6431 destpoint.x + srcrect.right - srcrect.left > src->surface_desc.dwWidth ||
6432 destpoint.y + srcrect.bottom - srcrect.top > src->surface_desc.dwHeight ||
6433 dest->surface_desc.dwWidth > src->surface_desc.dwWidth ||
6434 dest->surface_desc.dwHeight > src->surface_desc.dwHeight)
6436 LeaveCriticalSection(&ddraw_cs);
6437 return DDERR_INVALIDPARAMS;
6440 /* Must be top level surfaces. */
6441 if (src->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_MIPMAPSUBLEVEL ||
6442 dest->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_MIPMAPSUBLEVEL)
6444 LeaveCriticalSection(&ddraw_cs);
6445 return DDERR_INVALIDPARAMS;
6448 if (src->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP)
6450 DWORD src_face_flag, dest_face_flag;
6451 IDirectDrawSurfaceImpl *src_face, *dest_face;
6452 IDirectDrawSurface7 *temp;
6453 DDSURFACEDESC2 ddsd;
6454 int i;
6456 if (!(dest->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP))
6458 LeaveCriticalSection(&ddraw_cs);
6459 return DDERR_INVALIDPARAMS;
6462 /* Iterate through cube faces 2 times. First time is just to check INVALIDPARAMS conditions, second
6463 * time it's actual surface loading. */
6464 for (i = 0; i < 2; i++)
6466 dest_face = dest;
6467 src_face = src;
6469 for (;dest_face && src_face;)
6471 src_face_flag = src_face->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP_ALLFACES;
6472 dest_face_flag = dest_face->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP_ALLFACES;
6474 if (src_face_flag == dest_face_flag)
6476 if (i == 0)
6478 /* Destination mip levels must be subset of source mip levels. */
6479 if (!is_mip_level_subset(dest_face, src_face))
6481 LeaveCriticalSection(&ddraw_cs);
6482 return DDERR_INVALIDPARAMS;
6485 else if (Flags & dest_face_flag)
6487 copy_mipmap_chain(This, dest_face, src_face, &destpoint, &srcrect);
6490 if (src_face_flag < DDSCAPS2_CUBEMAP_NEGATIVEZ)
6492 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6493 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | (src_face_flag << 1);
6494 IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(src, IDirectDrawSurface7), &ddsd.ddsCaps, &temp);
6496 if (src_face != src) IDirectDrawSurface7_Release(ICOM_INTERFACE(src_face, IDirectDrawSurface7));
6498 src_face = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, temp);
6500 else
6502 if (src_face != src) IDirectDrawSurface7_Release(ICOM_INTERFACE(src_face, IDirectDrawSurface7));
6504 src_face = NULL;
6508 if (dest_face_flag < DDSCAPS2_CUBEMAP_NEGATIVEZ)
6510 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6511 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | (dest_face_flag << 1);
6512 IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(dest, IDirectDrawSurface7), &ddsd.ddsCaps, &temp);
6514 if (dest_face != dest) IDirectDrawSurface7_Release(ICOM_INTERFACE(dest_face, IDirectDrawSurface7));
6516 dest_face = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, temp);
6518 else
6520 if (dest_face != dest) IDirectDrawSurface7_Release(ICOM_INTERFACE(dest_face, IDirectDrawSurface7));
6522 dest_face = NULL;
6526 if (i == 0)
6528 /* Native returns error if src faces are not subset of dest faces. */
6529 if (src_face)
6531 LeaveCriticalSection(&ddraw_cs);
6532 return DDERR_INVALIDPARAMS;
6537 LeaveCriticalSection(&ddraw_cs);
6538 return D3D_OK;
6540 else if (dest->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP)
6542 LeaveCriticalSection(&ddraw_cs);
6543 return DDERR_INVALIDPARAMS;
6546 /* Handle non cube map textures. */
6548 /* Destination mip levels must be subset of source mip levels. */
6549 if (!is_mip_level_subset(dest, src))
6551 LeaveCriticalSection(&ddraw_cs);
6552 return DDERR_INVALIDPARAMS;
6555 copy_mipmap_chain(This, dest, src, &destpoint, &srcrect);
6557 LeaveCriticalSection(&ddraw_cs);
6558 return D3D_OK;
6561 static HRESULT WINAPI
6562 IDirect3DDeviceImpl_7_Load_FPUSetup(IDirect3DDevice7 *iface,
6563 IDirectDrawSurface7 *DestTex,
6564 POINT *DestPoint,
6565 IDirectDrawSurface7 *SrcTex,
6566 RECT *SrcRect,
6567 DWORD Flags)
6569 return IDirect3DDeviceImpl_7_Load(iface, DestTex, DestPoint, SrcTex, SrcRect, Flags);
6572 static HRESULT WINAPI
6573 IDirect3DDeviceImpl_7_Load_FPUPreserve(IDirect3DDevice7 *iface,
6574 IDirectDrawSurface7 *DestTex,
6575 POINT *DestPoint,
6576 IDirectDrawSurface7 *SrcTex,
6577 RECT *SrcRect,
6578 DWORD Flags)
6580 HRESULT hr;
6581 WORD old_fpucw;
6583 old_fpucw = d3d_fpu_setup();
6584 hr = IDirect3DDeviceImpl_7_Load(iface, DestTex, DestPoint, SrcTex, SrcRect, Flags);
6585 set_fpu_control_word(old_fpucw);
6587 return hr;
6590 /*****************************************************************************
6591 * IDirect3DDevice7::LightEnable
6593 * Enables or disables a light
6595 * Version 7, IDirect3DLight uses this method too.
6597 * Params:
6598 * LightIndex: The index of the light to enable / disable
6599 * Enable: Enable or disable the light
6601 * Returns:
6602 * D3D_OK on success
6603 * For more details, see IWineD3DDevice::SetLightEnable
6605 *****************************************************************************/
6606 static HRESULT
6607 IDirect3DDeviceImpl_7_LightEnable(IDirect3DDevice7 *iface,
6608 DWORD LightIndex,
6609 BOOL Enable)
6611 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
6612 HRESULT hr;
6613 TRACE("(%p)->(%08x,%d): Relay!\n", This, LightIndex, Enable);
6615 EnterCriticalSection(&ddraw_cs);
6616 hr = IWineD3DDevice_SetLightEnable(This->wineD3DDevice, LightIndex, Enable);
6617 LeaveCriticalSection(&ddraw_cs);
6618 return hr_ddraw_from_wined3d(hr);
6621 static HRESULT WINAPI
6622 IDirect3DDeviceImpl_7_LightEnable_FPUSetup(IDirect3DDevice7 *iface,
6623 DWORD LightIndex,
6624 BOOL Enable)
6626 return IDirect3DDeviceImpl_7_LightEnable(iface, LightIndex, Enable);
6629 static HRESULT WINAPI
6630 IDirect3DDeviceImpl_7_LightEnable_FPUPreserve(IDirect3DDevice7 *iface,
6631 DWORD LightIndex,
6632 BOOL Enable)
6634 HRESULT hr;
6635 WORD old_fpucw;
6637 old_fpucw = d3d_fpu_setup();
6638 hr = IDirect3DDeviceImpl_7_LightEnable(iface, LightIndex, Enable);
6639 set_fpu_control_word(old_fpucw);
6641 return hr;
6644 /*****************************************************************************
6645 * IDirect3DDevice7::GetLightEnable
6647 * Retrieves if the light with the given index is enabled or not
6649 * Version 7
6651 * Params:
6652 * LightIndex: Index of desired light
6653 * Enable: Pointer to a BOOL which contains the result
6655 * Returns:
6656 * D3D_OK on success
6657 * DDERR_INVALIDPARAMS if Enable is NULL
6658 * See IWineD3DDevice::GetLightEnable for more details
6660 *****************************************************************************/
6661 static HRESULT
6662 IDirect3DDeviceImpl_7_GetLightEnable(IDirect3DDevice7 *iface,
6663 DWORD LightIndex,
6664 BOOL* Enable)
6666 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
6667 HRESULT hr;
6668 TRACE("(%p)->(%08x,%p): Relay\n", This, LightIndex, Enable);
6670 if(!Enable)
6671 return DDERR_INVALIDPARAMS;
6673 EnterCriticalSection(&ddraw_cs);
6674 hr = IWineD3DDevice_GetLightEnable(This->wineD3DDevice, LightIndex, Enable);
6675 LeaveCriticalSection(&ddraw_cs);
6676 return hr_ddraw_from_wined3d(hr);
6679 static HRESULT WINAPI
6680 IDirect3DDeviceImpl_7_GetLightEnable_FPUSetup(IDirect3DDevice7 *iface,
6681 DWORD LightIndex,
6682 BOOL* Enable)
6684 return IDirect3DDeviceImpl_7_GetLightEnable(iface, LightIndex, Enable);
6687 static HRESULT WINAPI
6688 IDirect3DDeviceImpl_7_GetLightEnable_FPUPreserve(IDirect3DDevice7 *iface,
6689 DWORD LightIndex,
6690 BOOL* Enable)
6692 HRESULT hr;
6693 WORD old_fpucw;
6695 old_fpucw = d3d_fpu_setup();
6696 hr = IDirect3DDeviceImpl_7_GetLightEnable(iface, LightIndex, Enable);
6697 set_fpu_control_word(old_fpucw);
6699 return hr;
6702 /*****************************************************************************
6703 * IDirect3DDevice7::SetClipPlane
6705 * Sets custom clipping plane
6707 * Version 7
6709 * Params:
6710 * Index: The index of the clipping plane
6711 * PlaneEquation: An equation defining the clipping plane
6713 * Returns:
6714 * D3D_OK on success
6715 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6716 * See IWineD3DDevice::SetClipPlane for more details
6718 *****************************************************************************/
6719 static HRESULT
6720 IDirect3DDeviceImpl_7_SetClipPlane(IDirect3DDevice7 *iface,
6721 DWORD Index,
6722 D3DVALUE* PlaneEquation)
6724 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
6725 HRESULT hr;
6726 TRACE("(%p)->(%08x,%p): Relay!\n", This, Index, PlaneEquation);
6728 if(!PlaneEquation)
6729 return DDERR_INVALIDPARAMS;
6731 EnterCriticalSection(&ddraw_cs);
6732 hr = IWineD3DDevice_SetClipPlane(This->wineD3DDevice, Index, PlaneEquation);
6733 LeaveCriticalSection(&ddraw_cs);
6734 return hr;
6737 static HRESULT WINAPI
6738 IDirect3DDeviceImpl_7_SetClipPlane_FPUSetup(IDirect3DDevice7 *iface,
6739 DWORD Index,
6740 D3DVALUE* PlaneEquation)
6742 return IDirect3DDeviceImpl_7_SetClipPlane(iface, Index, PlaneEquation);
6745 static HRESULT WINAPI
6746 IDirect3DDeviceImpl_7_SetClipPlane_FPUPreserve(IDirect3DDevice7 *iface,
6747 DWORD Index,
6748 D3DVALUE* PlaneEquation)
6750 HRESULT hr;
6751 WORD old_fpucw;
6753 old_fpucw = d3d_fpu_setup();
6754 hr = IDirect3DDeviceImpl_7_SetClipPlane(iface, Index, PlaneEquation);
6755 set_fpu_control_word(old_fpucw);
6757 return hr;
6760 /*****************************************************************************
6761 * IDirect3DDevice7::GetClipPlane
6763 * Returns the clipping plane with a specific index
6765 * Params:
6766 * Index: The index of the desired plane
6767 * PlaneEquation: Address to store the plane equation to
6769 * Returns:
6770 * D3D_OK on success
6771 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6772 * See IWineD3DDevice::GetClipPlane for more details
6774 *****************************************************************************/
6775 static HRESULT
6776 IDirect3DDeviceImpl_7_GetClipPlane(IDirect3DDevice7 *iface,
6777 DWORD Index,
6778 D3DVALUE* PlaneEquation)
6780 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
6781 HRESULT hr;
6782 TRACE("(%p)->(%d,%p): Relay!\n", This, Index, PlaneEquation);
6784 if(!PlaneEquation)
6785 return DDERR_INVALIDPARAMS;
6787 EnterCriticalSection(&ddraw_cs);
6788 hr = IWineD3DDevice_GetClipPlane(This->wineD3DDevice, Index, PlaneEquation);
6789 LeaveCriticalSection(&ddraw_cs);
6790 return hr;
6793 static HRESULT WINAPI
6794 IDirect3DDeviceImpl_7_GetClipPlane_FPUSetup(IDirect3DDevice7 *iface,
6795 DWORD Index,
6796 D3DVALUE* PlaneEquation)
6798 return IDirect3DDeviceImpl_7_GetClipPlane(iface, Index, PlaneEquation);
6801 static HRESULT WINAPI
6802 IDirect3DDeviceImpl_7_GetClipPlane_FPUPreserve(IDirect3DDevice7 *iface,
6803 DWORD Index,
6804 D3DVALUE* PlaneEquation)
6806 HRESULT hr;
6807 WORD old_fpucw;
6809 old_fpucw = d3d_fpu_setup();
6810 hr = IDirect3DDeviceImpl_7_GetClipPlane(iface, Index, PlaneEquation);
6811 set_fpu_control_word(old_fpucw);
6813 return hr;
6816 /*****************************************************************************
6817 * IDirect3DDevice7::GetInfo
6819 * Retrieves some information about the device. The DirectX sdk says that
6820 * this version returns S_FALSE for all retail builds of DirectX, that's what
6821 * this implementation does.
6823 * Params:
6824 * DevInfoID: Information type requested
6825 * DevInfoStruct: Pointer to a structure to store the info to
6826 * Size: Size of the structure
6828 * Returns:
6829 * S_FALSE, because it's a non-debug driver
6831 *****************************************************************************/
6832 static HRESULT WINAPI
6833 IDirect3DDeviceImpl_7_GetInfo(IDirect3DDevice7 *iface,
6834 DWORD DevInfoID,
6835 void *DevInfoStruct,
6836 DWORD Size)
6838 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
6839 TRACE("(%p)->(%08x,%p,%08x)\n", This, DevInfoID, DevInfoStruct, Size);
6841 if (TRACE_ON(d3d7))
6843 TRACE(" info requested : ");
6844 switch (DevInfoID)
6846 case D3DDEVINFOID_TEXTUREMANAGER: TRACE("D3DDEVINFOID_TEXTUREMANAGER\n"); break;
6847 case D3DDEVINFOID_D3DTEXTUREMANAGER: TRACE("D3DDEVINFOID_D3DTEXTUREMANAGER\n"); break;
6848 case D3DDEVINFOID_TEXTURING: TRACE("D3DDEVINFOID_TEXTURING\n"); break;
6849 default: ERR(" invalid flag !!!\n"); return DDERR_INVALIDPARAMS;
6853 return S_FALSE; /* According to MSDN, this is valid for a non-debug driver */
6856 /* For performance optimization, devices created in FPUSETUP and FPUPRESERVE modes
6857 * have separate vtables. Simple functions where this doesn't matter like GetDirect3D
6858 * are not duplicated.
6860 * Device created with DDSCL_FPUSETUP (d3d7 default) - device methods assume that FPU
6861 * has already been setup for optimal d3d operation.
6863 * Device created with DDSCL_FPUPRESERVE - resets and restores FPU mode when necessary in
6864 * d3d calls (FPU may be in a mode non-suitable for d3d when the app calls d3d). Required
6865 * by Sacrifice (game). */
6866 const IDirect3DDevice7Vtbl IDirect3DDevice7_FPUSetup_Vtbl =
6868 /*** IUnknown Methods ***/
6869 IDirect3DDeviceImpl_7_QueryInterface,
6870 IDirect3DDeviceImpl_7_AddRef,
6871 IDirect3DDeviceImpl_7_Release,
6872 /*** IDirect3DDevice7 ***/
6873 IDirect3DDeviceImpl_7_GetCaps_FPUSetup,
6874 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUSetup,
6875 IDirect3DDeviceImpl_7_BeginScene_FPUSetup,
6876 IDirect3DDeviceImpl_7_EndScene_FPUSetup,
6877 IDirect3DDeviceImpl_7_GetDirect3D,
6878 IDirect3DDeviceImpl_7_SetRenderTarget_FPUSetup,
6879 IDirect3DDeviceImpl_7_GetRenderTarget,
6880 IDirect3DDeviceImpl_7_Clear_FPUSetup,
6881 IDirect3DDeviceImpl_7_SetTransform_FPUSetup,
6882 IDirect3DDeviceImpl_7_GetTransform_FPUSetup,
6883 IDirect3DDeviceImpl_7_SetViewport_FPUSetup,
6884 IDirect3DDeviceImpl_7_MultiplyTransform_FPUSetup,
6885 IDirect3DDeviceImpl_7_GetViewport_FPUSetup,
6886 IDirect3DDeviceImpl_7_SetMaterial_FPUSetup,
6887 IDirect3DDeviceImpl_7_GetMaterial_FPUSetup,
6888 IDirect3DDeviceImpl_7_SetLight_FPUSetup,
6889 IDirect3DDeviceImpl_7_GetLight_FPUSetup,
6890 IDirect3DDeviceImpl_7_SetRenderState_FPUSetup,
6891 IDirect3DDeviceImpl_7_GetRenderState_FPUSetup,
6892 IDirect3DDeviceImpl_7_BeginStateBlock_FPUSetup,
6893 IDirect3DDeviceImpl_7_EndStateBlock_FPUSetup,
6894 IDirect3DDeviceImpl_7_PreLoad_FPUSetup,
6895 IDirect3DDeviceImpl_7_DrawPrimitive_FPUSetup,
6896 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUSetup,
6897 IDirect3DDeviceImpl_7_SetClipStatus,
6898 IDirect3DDeviceImpl_7_GetClipStatus,
6899 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUSetup,
6900 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUSetup,
6901 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUSetup,
6902 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUSetup,
6903 IDirect3DDeviceImpl_7_ComputeSphereVisibility,
6904 IDirect3DDeviceImpl_7_GetTexture_FPUSetup,
6905 IDirect3DDeviceImpl_7_SetTexture_FPUSetup,
6906 IDirect3DDeviceImpl_7_GetTextureStageState_FPUSetup,
6907 IDirect3DDeviceImpl_7_SetTextureStageState_FPUSetup,
6908 IDirect3DDeviceImpl_7_ValidateDevice_FPUSetup,
6909 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUSetup,
6910 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUSetup,
6911 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUSetup,
6912 IDirect3DDeviceImpl_7_CreateStateBlock_FPUSetup,
6913 IDirect3DDeviceImpl_7_Load_FPUSetup,
6914 IDirect3DDeviceImpl_7_LightEnable_FPUSetup,
6915 IDirect3DDeviceImpl_7_GetLightEnable_FPUSetup,
6916 IDirect3DDeviceImpl_7_SetClipPlane_FPUSetup,
6917 IDirect3DDeviceImpl_7_GetClipPlane_FPUSetup,
6918 IDirect3DDeviceImpl_7_GetInfo
6921 const IDirect3DDevice7Vtbl IDirect3DDevice7_FPUPreserve_Vtbl =
6923 /*** IUnknown Methods ***/
6924 IDirect3DDeviceImpl_7_QueryInterface,
6925 IDirect3DDeviceImpl_7_AddRef,
6926 IDirect3DDeviceImpl_7_Release,
6927 /*** IDirect3DDevice7 ***/
6928 IDirect3DDeviceImpl_7_GetCaps_FPUPreserve,
6929 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUPreserve,
6930 IDirect3DDeviceImpl_7_BeginScene_FPUPreserve,
6931 IDirect3DDeviceImpl_7_EndScene_FPUPreserve,
6932 IDirect3DDeviceImpl_7_GetDirect3D,
6933 IDirect3DDeviceImpl_7_SetRenderTarget_FPUPreserve,
6934 IDirect3DDeviceImpl_7_GetRenderTarget,
6935 IDirect3DDeviceImpl_7_Clear_FPUPreserve,
6936 IDirect3DDeviceImpl_7_SetTransform_FPUPreserve,
6937 IDirect3DDeviceImpl_7_GetTransform_FPUPreserve,
6938 IDirect3DDeviceImpl_7_SetViewport_FPUPreserve,
6939 IDirect3DDeviceImpl_7_MultiplyTransform_FPUPreserve,
6940 IDirect3DDeviceImpl_7_GetViewport_FPUPreserve,
6941 IDirect3DDeviceImpl_7_SetMaterial_FPUPreserve,
6942 IDirect3DDeviceImpl_7_GetMaterial_FPUPreserve,
6943 IDirect3DDeviceImpl_7_SetLight_FPUPreserve,
6944 IDirect3DDeviceImpl_7_GetLight_FPUPreserve,
6945 IDirect3DDeviceImpl_7_SetRenderState_FPUPreserve,
6946 IDirect3DDeviceImpl_7_GetRenderState_FPUPreserve,
6947 IDirect3DDeviceImpl_7_BeginStateBlock_FPUPreserve,
6948 IDirect3DDeviceImpl_7_EndStateBlock_FPUPreserve,
6949 IDirect3DDeviceImpl_7_PreLoad_FPUPreserve,
6950 IDirect3DDeviceImpl_7_DrawPrimitive_FPUPreserve,
6951 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUPreserve,
6952 IDirect3DDeviceImpl_7_SetClipStatus,
6953 IDirect3DDeviceImpl_7_GetClipStatus,
6954 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUPreserve,
6955 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUPreserve,
6956 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUPreserve,
6957 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUPreserve,
6958 IDirect3DDeviceImpl_7_ComputeSphereVisibility,
6959 IDirect3DDeviceImpl_7_GetTexture_FPUPreserve,
6960 IDirect3DDeviceImpl_7_SetTexture_FPUPreserve,
6961 IDirect3DDeviceImpl_7_GetTextureStageState_FPUPreserve,
6962 IDirect3DDeviceImpl_7_SetTextureStageState_FPUPreserve,
6963 IDirect3DDeviceImpl_7_ValidateDevice_FPUPreserve,
6964 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUPreserve,
6965 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUPreserve,
6966 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUPreserve,
6967 IDirect3DDeviceImpl_7_CreateStateBlock_FPUPreserve,
6968 IDirect3DDeviceImpl_7_Load_FPUPreserve,
6969 IDirect3DDeviceImpl_7_LightEnable_FPUPreserve,
6970 IDirect3DDeviceImpl_7_GetLightEnable_FPUPreserve,
6971 IDirect3DDeviceImpl_7_SetClipPlane_FPUPreserve,
6972 IDirect3DDeviceImpl_7_GetClipPlane_FPUPreserve,
6973 IDirect3DDeviceImpl_7_GetInfo
6976 const IDirect3DDevice3Vtbl IDirect3DDevice3_Vtbl =
6978 /*** IUnknown Methods ***/
6979 Thunk_IDirect3DDeviceImpl_3_QueryInterface,
6980 Thunk_IDirect3DDeviceImpl_3_AddRef,
6981 Thunk_IDirect3DDeviceImpl_3_Release,
6982 /*** IDirect3DDevice3 ***/
6983 IDirect3DDeviceImpl_3_GetCaps,
6984 IDirect3DDeviceImpl_3_GetStats,
6985 IDirect3DDeviceImpl_3_AddViewport,
6986 IDirect3DDeviceImpl_3_DeleteViewport,
6987 IDirect3DDeviceImpl_3_NextViewport,
6988 Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats,
6989 Thunk_IDirect3DDeviceImpl_3_BeginScene,
6990 Thunk_IDirect3DDeviceImpl_3_EndScene,
6991 Thunk_IDirect3DDeviceImpl_3_GetDirect3D,
6992 IDirect3DDeviceImpl_3_SetCurrentViewport,
6993 IDirect3DDeviceImpl_3_GetCurrentViewport,
6994 Thunk_IDirect3DDeviceImpl_3_SetRenderTarget,
6995 Thunk_IDirect3DDeviceImpl_3_GetRenderTarget,
6996 IDirect3DDeviceImpl_3_Begin,
6997 IDirect3DDeviceImpl_3_BeginIndexed,
6998 IDirect3DDeviceImpl_3_Vertex,
6999 IDirect3DDeviceImpl_3_Index,
7000 IDirect3DDeviceImpl_3_End,
7001 IDirect3DDeviceImpl_3_GetRenderState,
7002 IDirect3DDeviceImpl_3_SetRenderState,
7003 IDirect3DDeviceImpl_3_GetLightState,
7004 IDirect3DDeviceImpl_3_SetLightState,
7005 Thunk_IDirect3DDeviceImpl_3_SetTransform,
7006 Thunk_IDirect3DDeviceImpl_3_GetTransform,
7007 Thunk_IDirect3DDeviceImpl_3_MultiplyTransform,
7008 Thunk_IDirect3DDeviceImpl_3_DrawPrimitive,
7009 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive,
7010 Thunk_IDirect3DDeviceImpl_3_SetClipStatus,
7011 Thunk_IDirect3DDeviceImpl_3_GetClipStatus,
7012 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided,
7013 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided,
7014 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB,
7015 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB,
7016 Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility,
7017 Thunk_IDirect3DDeviceImpl_3_GetTexture,
7018 IDirect3DDeviceImpl_3_SetTexture,
7019 Thunk_IDirect3DDeviceImpl_3_GetTextureStageState,
7020 Thunk_IDirect3DDeviceImpl_3_SetTextureStageState,
7021 Thunk_IDirect3DDeviceImpl_3_ValidateDevice
7024 const IDirect3DDevice2Vtbl IDirect3DDevice2_Vtbl =
7026 /*** IUnknown Methods ***/
7027 Thunk_IDirect3DDeviceImpl_2_QueryInterface,
7028 Thunk_IDirect3DDeviceImpl_2_AddRef,
7029 Thunk_IDirect3DDeviceImpl_2_Release,
7030 /*** IDirect3DDevice2 ***/
7031 Thunk_IDirect3DDeviceImpl_2_GetCaps,
7032 IDirect3DDeviceImpl_2_SwapTextureHandles,
7033 Thunk_IDirect3DDeviceImpl_2_GetStats,
7034 Thunk_IDirect3DDeviceImpl_2_AddViewport,
7035 Thunk_IDirect3DDeviceImpl_2_DeleteViewport,
7036 Thunk_IDirect3DDeviceImpl_2_NextViewport,
7037 IDirect3DDeviceImpl_2_EnumTextureFormats,
7038 Thunk_IDirect3DDeviceImpl_2_BeginScene,
7039 Thunk_IDirect3DDeviceImpl_2_EndScene,
7040 Thunk_IDirect3DDeviceImpl_2_GetDirect3D,
7041 Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport,
7042 Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport,
7043 Thunk_IDirect3DDeviceImpl_2_SetRenderTarget,
7044 Thunk_IDirect3DDeviceImpl_2_GetRenderTarget,
7045 Thunk_IDirect3DDeviceImpl_2_Begin,
7046 Thunk_IDirect3DDeviceImpl_2_BeginIndexed,
7047 Thunk_IDirect3DDeviceImpl_2_Vertex,
7048 Thunk_IDirect3DDeviceImpl_2_Index,
7049 Thunk_IDirect3DDeviceImpl_2_End,
7050 Thunk_IDirect3DDeviceImpl_2_GetRenderState,
7051 Thunk_IDirect3DDeviceImpl_2_SetRenderState,
7052 Thunk_IDirect3DDeviceImpl_2_GetLightState,
7053 Thunk_IDirect3DDeviceImpl_2_SetLightState,
7054 Thunk_IDirect3DDeviceImpl_2_SetTransform,
7055 Thunk_IDirect3DDeviceImpl_2_GetTransform,
7056 Thunk_IDirect3DDeviceImpl_2_MultiplyTransform,
7057 Thunk_IDirect3DDeviceImpl_2_DrawPrimitive,
7058 Thunk_IDirect3DDeviceImpl_2_DrawIndexedPrimitive,
7059 Thunk_IDirect3DDeviceImpl_2_SetClipStatus,
7060 Thunk_IDirect3DDeviceImpl_2_GetClipStatus
7063 const IDirect3DDeviceVtbl IDirect3DDevice1_Vtbl =
7065 /*** IUnknown Methods ***/
7066 Thunk_IDirect3DDeviceImpl_1_QueryInterface,
7067 Thunk_IDirect3DDeviceImpl_1_AddRef,
7068 Thunk_IDirect3DDeviceImpl_1_Release,
7069 /*** IDirect3DDevice1 ***/
7070 IDirect3DDeviceImpl_1_Initialize,
7071 Thunk_IDirect3DDeviceImpl_1_GetCaps,
7072 Thunk_IDirect3DDeviceImpl_1_SwapTextureHandles,
7073 IDirect3DDeviceImpl_1_CreateExecuteBuffer,
7074 Thunk_IDirect3DDeviceImpl_1_GetStats,
7075 IDirect3DDeviceImpl_1_Execute,
7076 Thunk_IDirect3DDeviceImpl_1_AddViewport,
7077 Thunk_IDirect3DDeviceImpl_1_DeleteViewport,
7078 Thunk_IDirect3DDeviceImpl_1_NextViewport,
7079 IDirect3DDeviceImpl_1_Pick,
7080 IDirect3DDeviceImpl_1_GetPickRecords,
7081 Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats,
7082 IDirect3DDeviceImpl_1_CreateMatrix,
7083 IDirect3DDeviceImpl_1_SetMatrix,
7084 IDirect3DDeviceImpl_1_GetMatrix,
7085 IDirect3DDeviceImpl_1_DeleteMatrix,
7086 Thunk_IDirect3DDeviceImpl_1_BeginScene,
7087 Thunk_IDirect3DDeviceImpl_1_EndScene,
7088 Thunk_IDirect3DDeviceImpl_1_GetDirect3D
7091 /*****************************************************************************
7092 * IDirect3DDeviceImpl_CreateHandle
7094 * Not called from the VTable
7096 * Some older interface versions operate with handles, which are basically
7097 * DWORDs which identify an interface, for example
7098 * IDirect3DDevice::SetRenderState with DIRECT3DRENDERSTATE_TEXTUREHANDLE
7100 * Those handle could be just casts to the interface pointers or vice versa,
7101 * but that is not 64 bit safe and would mean blindly derefering a DWORD
7102 * passed by the app. Instead there is a dynamic array in the device which
7103 * keeps a DWORD to pointer information and a type for the handle.
7105 * Basically this array only grows, when a handle is freed its pointer is
7106 * just set to NULL. There will be much more reads from the array than
7107 * insertion operations, so a dynamic array is fine.
7109 * Params:
7110 * This: D3DDevice implementation for which this handle should be created
7112 * Returns:
7113 * A free handle on success
7114 * 0 on failure
7116 *****************************************************************************/
7117 DWORD
7118 IDirect3DDeviceImpl_CreateHandle(IDirect3DDeviceImpl *This)
7120 DWORD i;
7121 struct HandleEntry *oldHandles = This->Handles;
7123 TRACE("(%p)\n", This);
7125 for(i = 0; i < This->numHandles; i++)
7127 if(This->Handles[i].ptr == NULL &&
7128 This->Handles[i].type == DDrawHandle_Unknown)
7130 TRACE("Reusing freed handle %d\n", i + 1);
7131 return i + 1;
7135 TRACE("Growing the handle array\n");
7137 This->numHandles++;
7138 This->Handles = HeapAlloc(GetProcessHeap(), 0, sizeof(struct HandleEntry) * This->numHandles);
7139 if(!This->Handles)
7141 ERR("Out of memory\n");
7142 This->Handles = oldHandles;
7143 This->numHandles--;
7144 return 0;
7146 if(oldHandles)
7148 memcpy(This->Handles, oldHandles, (This->numHandles - 1) * sizeof(struct HandleEntry));
7149 HeapFree(GetProcessHeap(), 0, oldHandles);
7152 TRACE("Returning %d\n", This->numHandles);
7153 return This->numHandles;
7156 /*****************************************************************************
7157 * IDirect3DDeviceImpl_UpdateDepthStencil
7159 * Checks the current render target for attached depth stencils and sets the
7160 * WineD3D depth stencil accordingly.
7162 * Returns:
7163 * The depth stencil state to set if creating the device
7165 *****************************************************************************/
7166 WINED3DZBUFFERTYPE
7167 IDirect3DDeviceImpl_UpdateDepthStencil(IDirect3DDeviceImpl *This)
7169 IDirectDrawSurface7 *depthStencil = NULL;
7170 IDirectDrawSurfaceImpl *dsi;
7171 static DDSCAPS2 depthcaps = { DDSCAPS_ZBUFFER, 0, 0, 0 };
7173 IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(This->target, IDirectDrawSurface7),
7174 &depthcaps,
7175 &depthStencil);
7176 if(!depthStencil)
7178 TRACE("Setting wined3d depth stencil to NULL\n");
7179 IWineD3DDevice_SetDepthStencilSurface(This->wineD3DDevice,
7180 NULL);
7181 return WINED3DZB_FALSE;
7184 dsi = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, depthStencil);
7185 TRACE("Setting wined3d depth stencil to %p (wined3d %p)\n", dsi, dsi->WineD3DSurface);
7186 IWineD3DDevice_SetDepthStencilSurface(This->wineD3DDevice,
7187 dsi->WineD3DSurface);
7189 IDirectDrawSurface7_Release(depthStencil);
7190 return WINED3DZB_TRUE;