Release 0.9.61.
[wine/gsoc-2012-control.git] / dlls / ddraw / device.c
blob9ff24f3ec6ec8a0efed0053c9d532e62f0158543
1 /*
2 * Copyright (c) 1998-2004 Lionel Ulmer
3 * Copyright (c) 2002-2005 Christian Costa
4 * Copyright (c) 2006 Stefan Dösinger
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 * IDirect3DDevice implementation, version 1, 2, 3 and 7. Rendering is relayed
21 * to WineD3D, some minimal DirectDraw specific management is handled here.
22 * The Direct3DDevice is NOT the parent of the WineD3DDevice, because d3d
23 * is initialized when DirectDraw creates the primary surface.
24 * Some type management is necessary, because some D3D types changed between
25 * D3D7 and D3D9.
29 #include "config.h"
30 #include "wine/port.h"
32 #include <assert.h>
33 #include <stdarg.h>
34 #include <string.h>
35 #include <stdlib.h>
37 #define COBJMACROS
38 #define NONAMELESSUNION
40 #include "windef.h"
41 #include "winbase.h"
42 #include "winerror.h"
43 #include "wingdi.h"
44 #include "wine/exception.h"
46 #include "ddraw.h"
47 #include "d3d.h"
49 #include "ddraw_private.h"
50 #include "wine/debug.h"
52 WINE_DEFAULT_DEBUG_CHANNEL(d3d7);
53 WINE_DECLARE_DEBUG_CHANNEL(ddraw_thunk);
55 /* The device ID */
56 const GUID IID_D3DDEVICE_WineD3D = {
57 0xaef72d43,
58 0xb09a,
59 0x4b7b,
60 { 0xb7,0x98,0xc6,0x8a,0x77,0x2d,0x72,0x2a }
63 /*****************************************************************************
64 * IUnknown Methods. Common for Version 1, 2, 3 and 7
65 *****************************************************************************/
67 /*****************************************************************************
68 * IDirect3DDevice7::QueryInterface
70 * Used to query other interfaces from a Direct3DDevice interface.
71 * It can return interface pointers to all Direct3DDevice versions as well
72 * as IDirectDraw and IDirect3D. For a link to QueryInterface
73 * rules see ddraw.c, IDirectDraw7::QueryInterface
75 * Exists in Version 1, 2, 3 and 7
77 * Params:
78 * refiid: Interface ID queried for
79 * obj: Used to return the interface pointer
81 * Returns:
82 * D3D_OK or E_NOINTERFACE
84 *****************************************************************************/
85 static HRESULT WINAPI
86 IDirect3DDeviceImpl_7_QueryInterface(IDirect3DDevice7 *iface,
87 REFIID refiid,
88 void **obj)
90 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
91 TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(refiid), obj);
93 /* According to COM docs, if the QueryInterface fails, obj should be set to NULL */
94 *obj = NULL;
96 if(!refiid)
97 return DDERR_INVALIDPARAMS;
99 if ( IsEqualGUID( &IID_IUnknown, refiid ) )
101 *obj = ICOM_INTERFACE(This, IDirect3DDevice7);
104 /* Check DirectDraw Interfac\x01s */
105 else if( IsEqualGUID( &IID_IDirectDraw7, refiid ) )
107 *obj = ICOM_INTERFACE(This->ddraw, IDirectDraw7);
108 TRACE("(%p) Returning IDirectDraw7 interface at %p\n", This, *obj);
110 else if ( IsEqualGUID( &IID_IDirectDraw4, refiid ) )
112 *obj = ICOM_INTERFACE(This->ddraw, IDirectDraw4);
113 TRACE("(%p) Returning IDirectDraw4 interface at %p\n", This, *obj);
115 else if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) )
117 *obj = ICOM_INTERFACE(This->ddraw, IDirectDraw2);
118 TRACE("(%p) Returning IDirectDraw2 interface at %p\n", This, *obj);
120 else if( IsEqualGUID( &IID_IDirectDraw, refiid ) )
122 *obj = ICOM_INTERFACE(This->ddraw, IDirectDraw);
123 TRACE("(%p) Returning IDirectDraw interface at %p\n", This, *obj);
126 /* Direct3D */
127 else if ( IsEqualGUID( &IID_IDirect3D , refiid ) )
129 *obj = ICOM_INTERFACE(This->ddraw, IDirect3D);
130 TRACE("(%p) Returning IDirect3D interface at %p\n", This, *obj);
132 else if ( IsEqualGUID( &IID_IDirect3D2 , refiid ) )
134 *obj = ICOM_INTERFACE(This->ddraw, IDirect3D2);
135 TRACE("(%p) Returning IDirect3D2 interface at %p\n", This, *obj);
137 else if ( IsEqualGUID( &IID_IDirect3D3 , refiid ) )
139 *obj = ICOM_INTERFACE(This->ddraw, IDirect3D3);
140 TRACE("(%p) Returning IDirect3D3 interface at %p\n", This, *obj);
142 else if ( IsEqualGUID( &IID_IDirect3D7 , refiid ) )
144 *obj = ICOM_INTERFACE(This->ddraw, IDirect3D7);
145 TRACE("(%p) Returning IDirect3D7 interface at %p\n", This, *obj);
148 /* Direct3DDevice */
149 else if ( IsEqualGUID( &IID_IDirect3DDevice , refiid ) )
151 *obj = ICOM_INTERFACE(This, IDirect3DDevice);
152 TRACE("(%p) Returning IDirect3DDevice interface at %p\n", This, *obj);
154 else if ( IsEqualGUID( &IID_IDirect3DDevice2 , refiid ) ) {
155 *obj = ICOM_INTERFACE(This, IDirect3DDevice2);
156 TRACE("(%p) Returning IDirect3DDevice2 interface at %p\n", This, *obj);
158 else if ( IsEqualGUID( &IID_IDirect3DDevice3 , refiid ) ) {
159 *obj = ICOM_INTERFACE(This, IDirect3DDevice3);
160 TRACE("(%p) Returning IDirect3DDevice3 interface at %p\n", This, *obj);
162 else if ( IsEqualGUID( &IID_IDirect3DDevice7 , refiid ) ) {
163 *obj = ICOM_INTERFACE(This, IDirect3DDevice7);
164 TRACE("(%p) Returning IDirect3DDevice7 interface at %p\n", This, *obj);
167 /* Unknown interface */
168 else
170 ERR("(%p)->(%s, %p): No interface found\n", This, debugstr_guid(refiid), obj);
171 return E_NOINTERFACE;
174 /* AddRef the returned interface */
175 IUnknown_AddRef( (IUnknown *) *obj);
176 return D3D_OK;
179 static HRESULT WINAPI
180 Thunk_IDirect3DDeviceImpl_3_QueryInterface(IDirect3DDevice3 *iface,
181 REFIID riid,
182 void **obj)
184 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
185 TRACE_(ddraw_thunk)("(%p)->(%s,%p) thunking to IDirect3DDevice7 interface.\n", This, debugstr_guid(riid), obj);
186 return IDirect3DDevice7_QueryInterface(ICOM_INTERFACE(This, IDirect3DDevice7),
187 riid,
188 obj);
191 static HRESULT WINAPI
192 Thunk_IDirect3DDeviceImpl_2_QueryInterface(IDirect3DDevice2 *iface,
193 REFIID riid,
194 void **obj)
196 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
197 TRACE_(ddraw_thunk)("(%p)->(%s,%p) thunking to IDirect3DDevice7 interface.\n", This, debugstr_guid(riid), obj);
198 return IDirect3DDevice7_QueryInterface(ICOM_INTERFACE(This, IDirect3DDevice7),
199 riid,
200 obj);
203 static HRESULT WINAPI
204 Thunk_IDirect3DDeviceImpl_1_QueryInterface(IDirect3DDevice *iface,
205 REFIID riid,
206 void **obp)
208 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
209 TRACE_(ddraw_thunk)("(%p)->(%s,%p) thunking to IDirect3DDevice7 interface.\n", This, debugstr_guid(riid), obp);
210 return IDirect3DDevice7_QueryInterface(ICOM_INTERFACE(This, IDirect3DDevice7),
211 riid,
212 obp);
215 /*****************************************************************************
216 * IDirect3DDevice7::AddRef
218 * Increases the refcount....
219 * The most exciting Method, definitely
221 * Exists in Version 1, 2, 3 and 7
223 * Returns:
224 * The new refcount
226 *****************************************************************************/
227 static ULONG WINAPI
228 IDirect3DDeviceImpl_7_AddRef(IDirect3DDevice7 *iface)
230 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
231 ULONG ref = InterlockedIncrement(&This->ref);
233 TRACE("(%p) : incrementing from %u.\n", This, ref -1);
235 return ref;
238 static ULONG WINAPI
239 Thunk_IDirect3DDeviceImpl_3_AddRef(IDirect3DDevice3 *iface)
241 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
242 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
243 return IDirect3DDevice7_AddRef(ICOM_INTERFACE(This, IDirect3DDevice7));
246 static ULONG WINAPI
247 Thunk_IDirect3DDeviceImpl_2_AddRef(IDirect3DDevice2 *iface)
249 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
250 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
251 return IDirect3DDevice7_AddRef(ICOM_INTERFACE(This, IDirect3DDevice7));
254 static ULONG WINAPI
255 Thunk_IDirect3DDeviceImpl_1_AddRef(IDirect3DDevice *iface)
257 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", iface);
258 return IDirect3DDevice7_AddRef(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice7, iface));
261 /*****************************************************************************
262 * IDirect3DDevice7::Release
264 * Decreases the refcount of the interface
265 * When the refcount is reduced to 0, the object is destroyed.
267 * Exists in Version 1, 2, 3 and 7
269 * Returns:d
270 * The new refcount
272 *****************************************************************************/
273 static ULONG WINAPI
274 IDirect3DDeviceImpl_7_Release(IDirect3DDevice7 *iface)
276 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
277 ULONG ref = InterlockedDecrement(&This->ref);
279 TRACE("(%p)->() decrementing from %u.\n", This, ref +1);
281 /* This method doesn't destroy the WineD3DDevice, because it's still in use for
282 * 2D rendering. IDirectDrawSurface7::Release will destroy the WineD3DDevice
283 * when the render target is released
285 if (ref == 0)
287 IParent *IndexBufferParent;
288 DWORD i;
290 EnterCriticalSection(&ddraw_cs);
291 /* Free the index buffer. */
292 IWineD3DDevice_SetIndices(This->wineD3DDevice, NULL);
293 IWineD3DIndexBuffer_GetParent(This->indexbuffer,
294 (IUnknown **) &IndexBufferParent);
295 IParent_Release(IndexBufferParent); /* Once for the getParent */
296 if( IParent_Release(IndexBufferParent) != 0) /* And now to destroy it */
298 ERR(" (%p) Something is still holding the index buffer parent %p\n", This, IndexBufferParent);
301 /* There is no need to unset the vertex buffer here, IWineD3DDevice_Uninit3D will do that when
302 * destroying the primary stateblock. If a vertex buffer is destroyed while it is bound
303 * IDirect3DVertexBuffer::Release will unset it.
306 /* Restore the render targets */
307 if(This->OffScreenTarget)
309 WINED3DVIEWPORT vp;
311 vp.X = 0;
312 vp.Y = 0;
313 vp.Width = This->ddraw->d3d_target->surface_desc.dwWidth;
314 vp.Height = This->ddraw->d3d_target->surface_desc.dwHeight;
315 vp.MinZ = 0.0;
316 vp.MaxZ = 1.0;
317 IWineD3DDevice_SetViewport(This->wineD3DDevice,
318 &vp);
320 /* Set the device up to render to the front buffer since the back buffer will
321 * vanish soon.
323 IWineD3DDevice_SetRenderTarget(This->wineD3DDevice, 0,
324 This->ddraw->d3d_target->WineD3DSurface);
325 /* This->target is the offscreen target.
326 * This->ddraw->d3d_target is the target used by DDraw
328 TRACE("(%p) Release: Using %p as front buffer, %p as back buffer\n", This, This->ddraw->d3d_target, NULL);
329 IWineD3DDevice_SetFrontBackBuffers(This->wineD3DDevice,
330 This->ddraw->d3d_target->WineD3DSurface,
331 NULL);
334 /* Release the WineD3DDevice. This won't destroy it */
335 if(IWineD3DDevice_Release(This->wineD3DDevice) <= 0)
337 ERR(" (%p) The wineD3D device %p was destroyed unexpectadely. Prepare for trouble\n", This, This->wineD3DDevice);
340 /* The texture handles should be unset by now, but there might be some bits
341 * missing in our reference counting(needs test). Do a sanity check
343 for(i = 0; i < This->numHandles; i++)
345 if(This->Handles[i].ptr)
347 switch(This->Handles[i].type)
349 case DDrawHandle_Texture:
351 IDirectDrawSurfaceImpl *surf = (IDirectDrawSurfaceImpl *) This->Handles[i].ptr;
352 FIXME("Texture Handle %d not unset properly\n", i + 1);
353 surf->Handle = 0;
355 break;
357 case DDrawHandle_Material:
359 IDirect3DMaterialImpl *mat = (IDirect3DMaterialImpl *) This->Handles[i].ptr;
360 FIXME("Material handle %d not unset properly\n", i + 1);
361 mat->Handle = 0;
363 break;
365 case DDrawHandle_Matrix:
367 /* No fixme here because this might happen because of sloppy apps */
368 WARN("Leftover matrix handle %d, deleting\n", i + 1);
369 IDirect3DDevice_DeleteMatrix(ICOM_INTERFACE(This, IDirect3DDevice),
370 i + 1);
372 break;
374 case DDrawHandle_StateBlock:
376 /* No fixme here because this might happen because of sloppy apps */
377 WARN("Leftover stateblock handle %d, deleting\n", i + 1);
378 IDirect3DDevice7_DeleteStateBlock(ICOM_INTERFACE(This, IDirect3DDevice7),
379 i + 1);
381 break;
383 default:
384 FIXME("Unknown handle %d not unset properly\n", i + 1);
389 HeapFree(GetProcessHeap(), 0, This->Handles);
391 TRACE("Releasing target %p %p\n", This->target, This->ddraw->d3d_target);
392 /* Release the render target and the WineD3D render target
393 * (See IDirect3D7::CreateDevice for more comments on this)
395 IDirectDrawSurface7_Release(ICOM_INTERFACE(This->target, IDirectDrawSurface7));
396 IDirectDrawSurface7_Release(ICOM_INTERFACE(This->ddraw->d3d_target,IDirectDrawSurface7));
397 TRACE("Target release done\n");
399 This->ddraw->d3ddevice = NULL;
401 /* Now free the structure */
402 HeapFree(GetProcessHeap(), 0, This);
403 LeaveCriticalSection(&ddraw_cs);
406 TRACE("Done\n");
407 return ref;
410 static ULONG WINAPI
411 Thunk_IDirect3DDeviceImpl_3_Release(IDirect3DDevice3 *iface)
413 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
414 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
415 return IDirect3DDevice7_Release(ICOM_INTERFACE(This, IDirect3DDevice7));
418 static ULONG WINAPI
419 Thunk_IDirect3DDeviceImpl_2_Release(IDirect3DDevice2 *iface)
421 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
422 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
423 return IDirect3DDevice7_Release(ICOM_INTERFACE(This, IDirect3DDevice7));
426 static ULONG WINAPI
427 Thunk_IDirect3DDeviceImpl_1_Release(IDirect3DDevice *iface)
429 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
430 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
431 return IDirect3DDevice7_Release(ICOM_INTERFACE(This, IDirect3DDevice7));
434 /*****************************************************************************
435 * IDirect3DDevice Methods
436 *****************************************************************************/
438 /*****************************************************************************
439 * IDirect3DDevice::Initialize
441 * Initializes a Direct3DDevice. This implementation is a no-op, as all
442 * initialization is done at create time.
444 * Exists in Version 1
446 * Parameters:
447 * No idea what they mean, as the MSDN page is gone
449 * Returns: DD_OK
451 *****************************************************************************/
452 static HRESULT WINAPI
453 IDirect3DDeviceImpl_1_Initialize(IDirect3DDevice *iface,
454 IDirect3D *Direct3D, GUID *guid,
455 D3DDEVICEDESC *Desc)
457 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
459 /* It shouldn't be crucial, but print a FIXME, I'm interested if
460 * any game calls it and when
462 FIXME("(%p)->(%p,%p,%p): No-op!\n", This, Direct3D, guid, Desc);
464 return D3D_OK;
467 /*****************************************************************************
468 * IDirect3DDevice7::GetCaps
470 * Retrieves the device's capabilities
472 * This implementation is used for Version 7 only, the older versions have
473 * their own implementation.
475 * Parameters:
476 * Desc: Pointer to a D3DDEVICEDESC7 structure to fill
478 * Returns:
479 * D3D_OK on success
480 * D3DERR_* if a problem occurs. See WineD3D
482 *****************************************************************************/
483 static HRESULT WINAPI
484 IDirect3DDeviceImpl_7_GetCaps(IDirect3DDevice7 *iface,
485 D3DDEVICEDESC7 *Desc)
487 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
488 D3DDEVICEDESC OldDesc;
489 TRACE("(%p)->(%p)\n", This, Desc);
491 /* Call the same function used by IDirect3D, this saves code */
492 return IDirect3DImpl_GetCaps(This->ddraw->wineD3D, &OldDesc, Desc);
495 /*****************************************************************************
496 * IDirect3DDevice3::GetCaps
498 * Retrieves the capabilities of the hardware device and the emulation
499 * device. For Wine, hardware and emulation are the same (it's all HW).
501 * This implementation is used for Version 1, 2, and 3. Version 7 has its own
503 * Parameters:
504 * HWDesc: Structure to fill with the HW caps
505 * HelDesc: Structure to fill with the hardware emulation caps
507 * Returns:
508 * D3D_OK on success
509 * D3DERR_* if a problem occurs. See WineD3D
511 *****************************************************************************/
512 static HRESULT WINAPI
513 IDirect3DDeviceImpl_3_GetCaps(IDirect3DDevice3 *iface,
514 D3DDEVICEDESC *HWDesc,
515 D3DDEVICEDESC *HelDesc)
517 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
518 D3DDEVICEDESC7 newDesc;
519 HRESULT hr;
520 TRACE("(%p)->(%p,%p)\n", iface, HWDesc, HelDesc);
522 hr = IDirect3DImpl_GetCaps(This->ddraw->wineD3D, HWDesc, &newDesc);
523 if(hr != D3D_OK) return hr;
525 *HelDesc = *HWDesc;
526 return D3D_OK;
529 static HRESULT WINAPI
530 Thunk_IDirect3DDeviceImpl_2_GetCaps(IDirect3DDevice2 *iface,
531 D3DDEVICEDESC *D3DHWDevDesc,
532 D3DDEVICEDESC *D3DHELDevDesc)
534 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
535 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice3 interface.\n", This, D3DHWDevDesc, D3DHELDevDesc);
536 return IDirect3DDevice3_GetCaps(ICOM_INTERFACE(This, IDirect3DDevice3),
537 D3DHWDevDesc,
538 D3DHELDevDesc);
541 static HRESULT WINAPI
542 Thunk_IDirect3DDeviceImpl_1_GetCaps(IDirect3DDevice *iface,
543 D3DDEVICEDESC *D3DHWDevDesc,
544 D3DDEVICEDESC *D3DHELDevDesc)
546 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
547 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice3 interface.\n", This, D3DHWDevDesc, D3DHELDevDesc);
548 return IDirect3DDevice3_GetCaps(ICOM_INTERFACE(This, IDirect3DDevice3),
549 D3DHWDevDesc,
550 D3DHELDevDesc);
553 /*****************************************************************************
554 * IDirect3DDevice2::SwapTextureHandles
556 * Swaps the texture handles of 2 Texture interfaces. Version 1 and 2
558 * Parameters:
559 * Tex1, Tex2: The 2 Textures to swap
561 * Returns:
562 * D3D_OK
564 *****************************************************************************/
565 static HRESULT WINAPI
566 IDirect3DDeviceImpl_2_SwapTextureHandles(IDirect3DDevice2 *iface,
567 IDirect3DTexture2 *Tex1,
568 IDirect3DTexture2 *Tex2)
570 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
571 DWORD swap;
572 IDirectDrawSurfaceImpl *surf1 = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture2, Tex1);
573 IDirectDrawSurfaceImpl *surf2 = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture2, Tex2);
574 TRACE("(%p)->(%p,%p)\n", This, surf1, surf2);
576 EnterCriticalSection(&ddraw_cs);
577 This->Handles[surf1->Handle - 1].ptr = surf2;
578 This->Handles[surf2->Handle - 1].ptr = surf1;
580 swap = surf2->Handle;
581 surf2->Handle = surf1->Handle;
582 surf1->Handle = swap;
583 LeaveCriticalSection(&ddraw_cs);
585 return D3D_OK;
588 static HRESULT WINAPI
589 Thunk_IDirect3DDeviceImpl_1_SwapTextureHandles(IDirect3DDevice *iface,
590 IDirect3DTexture *D3DTex1,
591 IDirect3DTexture *D3DTex2)
593 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
594 IDirectDrawSurfaceImpl *surf1 = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture, D3DTex1);
595 IDirectDrawSurfaceImpl *surf2 = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture, D3DTex2);
596 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice2 interface.\n", This, surf1, surf2);
597 return IDirect3DDevice2_SwapTextureHandles(ICOM_INTERFACE(This, IDirect3DDevice2),
598 ICOM_INTERFACE(surf1, IDirect3DTexture2),
599 ICOM_INTERFACE(surf2, IDirect3DTexture2));
602 /*****************************************************************************
603 * IDirect3DDevice3::GetStats
605 * This method seems to retrieve some stats from the device.
606 * The MSDN documentation doesn't exist any more, but the D3DSTATS
607 * structure suggests that the amount of drawn primitives and processed
608 * vertices is returned.
610 * Exists in Version 1, 2 and 3
612 * Parameters:
613 * Stats: Pointer to a D3DSTATS structure to be filled
615 * Returns:
616 * D3D_OK on success
617 * DDERR_INVALIDPARAMS if Stats == NULL
619 *****************************************************************************/
620 static HRESULT WINAPI
621 IDirect3DDeviceImpl_3_GetStats(IDirect3DDevice3 *iface,
622 D3DSTATS *Stats)
624 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
625 FIXME("(%p)->(%p): Stub!\n", This, Stats);
627 if(!Stats)
628 return DDERR_INVALIDPARAMS;
630 /* Fill the Stats with 0 */
631 Stats->dwTrianglesDrawn = 0;
632 Stats->dwLinesDrawn = 0;
633 Stats->dwPointsDrawn = 0;
634 Stats->dwSpansDrawn = 0;
635 Stats->dwVerticesProcessed = 0;
637 return D3D_OK;
640 static HRESULT WINAPI
641 Thunk_IDirect3DDeviceImpl_2_GetStats(IDirect3DDevice2 *iface,
642 D3DSTATS *Stats)
644 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
645 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, Stats);
646 return IDirect3DDevice3_GetStats(ICOM_INTERFACE(This, IDirect3DDevice3),
647 Stats);
650 static HRESULT WINAPI
651 Thunk_IDirect3DDeviceImpl_1_GetStats(IDirect3DDevice *iface,
652 D3DSTATS *Stats)
654 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
655 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, Stats);
656 return IDirect3DDevice3_GetStats(ICOM_INTERFACE(This, IDirect3DDevice3),
657 Stats);
660 /*****************************************************************************
661 * IDirect3DDevice::CreateExecuteBuffer
663 * Creates an IDirect3DExecuteBuffer, used for rendering with a
664 * Direct3DDevice.
666 * Version 1 only.
668 * Params:
669 * Desc: Buffer description
670 * ExecuteBuffer: Address to return the Interface pointer at
671 * UnkOuter: Must be NULL. Basically for aggregation, which ddraw doesn't
672 * support
674 * Returns:
675 * CLASS_E_NOAGGREGATION if UnkOuter != NULL
676 * DDERR_OUTOFMEMORY if we ran out of memory
677 * D3D_OK on success
679 *****************************************************************************/
680 static HRESULT WINAPI
681 IDirect3DDeviceImpl_1_CreateExecuteBuffer(IDirect3DDevice *iface,
682 D3DEXECUTEBUFFERDESC *Desc,
683 IDirect3DExecuteBuffer **ExecuteBuffer,
684 IUnknown *UnkOuter)
686 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
687 IDirect3DExecuteBufferImpl* object;
688 TRACE("(%p)->(%p,%p,%p)!\n", This, Desc, ExecuteBuffer, UnkOuter);
690 if(UnkOuter)
691 return CLASS_E_NOAGGREGATION;
693 /* Allocate the new Execute Buffer */
694 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DExecuteBufferImpl));
695 if(!object)
697 ERR("Out of memory when allocating a IDirect3DExecuteBufferImpl structure\n");
698 return DDERR_OUTOFMEMORY;
701 ICOM_INIT_INTERFACE(object, IDirect3DExecuteBuffer, IDirect3DExecuteBuffer_Vtbl);
703 object->ref = 1;
704 object->d3ddev = This;
706 /* Initializes memory */
707 memcpy(&object->desc, Desc, Desc->dwSize);
709 /* No buffer given */
710 if ((object->desc.dwFlags & D3DDEB_LPDATA) == 0)
711 object->desc.lpData = NULL;
713 /* No buffer size given */
714 if ((object->desc.dwFlags & D3DDEB_BUFSIZE) == 0)
715 object->desc.dwBufferSize = 0;
717 /* Create buffer if asked */
718 if ((object->desc.lpData == NULL) && (object->desc.dwBufferSize > 0))
720 object->need_free = TRUE;
721 object->desc.lpData = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,object->desc.dwBufferSize);
722 if(!object->desc.lpData)
724 ERR("Out of memory when allocating the execute buffer data\n");
725 HeapFree(GetProcessHeap(), 0, object);
726 return DDERR_OUTOFMEMORY;
729 else
731 object->need_free = FALSE;
734 /* No vertices for the moment */
735 object->vertex_data = NULL;
737 object->desc.dwFlags |= D3DDEB_LPDATA;
739 object->indices = NULL;
740 object->nb_indices = 0;
742 *ExecuteBuffer = ICOM_INTERFACE(object, IDirect3DExecuteBuffer);
744 TRACE(" Returning IDirect3DExecuteBuffer at %p, implementation is at %p\n", *ExecuteBuffer, object);
746 return D3D_OK;
749 /*****************************************************************************
750 * IDirect3DDevice::Execute
752 * Executes all the stuff in an execute buffer.
754 * Params:
755 * ExecuteBuffer: The buffer to execute
756 * Viewport: The viewport used for rendering
757 * Flags: Some flags
759 * Returns:
760 * DDERR_INVALIDPARAMS if ExecuteBuffer == NULL
761 * D3D_OK on success
763 *****************************************************************************/
764 static HRESULT WINAPI
765 IDirect3DDeviceImpl_1_Execute(IDirect3DDevice *iface,
766 IDirect3DExecuteBuffer *ExecuteBuffer,
767 IDirect3DViewport *Viewport,
768 DWORD Flags)
770 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
771 IDirect3DExecuteBufferImpl *Direct3DExecuteBufferImpl = ICOM_OBJECT(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, ExecuteBuffer);
772 IDirect3DViewportImpl *Direct3DViewportImpl = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport);
774 TRACE("(%p)->(%p,%p,%08x)\n", This, Direct3DExecuteBufferImpl, Direct3DViewportImpl, Flags);
776 if(!Direct3DExecuteBufferImpl)
777 return DDERR_INVALIDPARAMS;
779 /* Execute... */
780 EnterCriticalSection(&ddraw_cs);
781 IDirect3DExecuteBufferImpl_Execute(Direct3DExecuteBufferImpl, This, Direct3DViewportImpl);
782 LeaveCriticalSection(&ddraw_cs);
784 return D3D_OK;
787 /*****************************************************************************
788 * IDirect3DDevice3::AddViewport
790 * Add a Direct3DViewport to the device's viewport list. These viewports
791 * are wrapped to IDirect3DDevice7 viewports in viewport.c
793 * Exists in Version 1, 2 and 3. Note that IDirect3DViewport 1, 2 and 3
794 * are the same interfaces.
796 * Params:
797 * Viewport: The viewport to add
799 * Returns:
800 * DDERR_INVALIDPARAMS if Viewport == NULL
801 * D3D_OK on success
803 *****************************************************************************/
804 static HRESULT WINAPI
805 IDirect3DDeviceImpl_3_AddViewport(IDirect3DDevice3 *iface,
806 IDirect3DViewport3 *Viewport)
808 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
809 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport);
811 TRACE("(%p)->(%p)\n", This, vp);
813 /* Sanity check */
814 if(!vp)
815 return DDERR_INVALIDPARAMS;
817 EnterCriticalSection(&ddraw_cs);
818 vp->next = This->viewport_list;
819 This->viewport_list = vp;
820 vp->active_device = This; /* Viewport must be usable for Clear() after AddViewport,
821 so set active_device here. */
822 LeaveCriticalSection(&ddraw_cs);
824 return D3D_OK;
827 static HRESULT WINAPI
828 Thunk_IDirect3DDeviceImpl_2_AddViewport(IDirect3DDevice2 *iface,
829 IDirect3DViewport2 *Direct3DViewport2)
831 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
832 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport2);
833 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
834 return IDirect3DDevice3_AddViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
835 ICOM_INTERFACE(vp, IDirect3DViewport3));
838 static HRESULT WINAPI
839 Thunk_IDirect3DDeviceImpl_1_AddViewport(IDirect3DDevice *iface,
840 IDirect3DViewport *Direct3DViewport)
842 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
843 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport);
844 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
845 return IDirect3DDevice3_AddViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
846 ICOM_INTERFACE(vp, IDirect3DViewport3));
849 /*****************************************************************************
850 * IDirect3DDevice3::DeleteViewport
852 * Deletes a Direct3DViewport from the device's viewport list.
854 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
855 * are equal.
857 * Params:
858 * Viewport: The viewport to delete
860 * Returns:
861 * D3D_OK on success
862 * DDERR_INVALIDPARAMS if the viewport wasn't found in the list
864 *****************************************************************************/
865 static HRESULT WINAPI
866 IDirect3DDeviceImpl_3_DeleteViewport(IDirect3DDevice3 *iface,
867 IDirect3DViewport3 *Viewport)
869 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
870 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *) Viewport;
871 IDirect3DViewportImpl *cur_viewport, *prev_viewport = NULL;
873 TRACE("(%p)->(%p)\n", This, vp);
875 EnterCriticalSection(&ddraw_cs);
876 cur_viewport = This->viewport_list;
877 while (cur_viewport != NULL)
879 if (cur_viewport == vp)
881 if (prev_viewport == NULL) This->viewport_list = cur_viewport->next;
882 else prev_viewport->next = cur_viewport->next;
883 /* TODO : add desactivate of the viewport and all associated lights... */
884 LeaveCriticalSection(&ddraw_cs);
885 return D3D_OK;
887 prev_viewport = cur_viewport;
888 cur_viewport = cur_viewport->next;
891 LeaveCriticalSection(&ddraw_cs);
892 return DDERR_INVALIDPARAMS;
895 static HRESULT WINAPI
896 Thunk_IDirect3DDeviceImpl_2_DeleteViewport(IDirect3DDevice2 *iface,
897 IDirect3DViewport2 *Direct3DViewport2)
899 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
900 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport2);
901 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
902 return IDirect3DDevice3_DeleteViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
903 ICOM_INTERFACE(vp, IDirect3DViewport3));
906 static HRESULT WINAPI
907 Thunk_IDirect3DDeviceImpl_1_DeleteViewport(IDirect3DDevice *iface,
908 IDirect3DViewport *Direct3DViewport)
910 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
911 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport);
912 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
913 return IDirect3DDevice3_DeleteViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
914 ICOM_INTERFACE(vp, IDirect3DViewport3));
917 /*****************************************************************************
918 * IDirect3DDevice3::NextViewport
920 * Returns a viewport from the viewport list, depending on the
921 * passed viewport and the flags.
923 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
924 * are equal.
926 * Params:
927 * Viewport: Viewport to use for beginning the search
928 * Flags: D3DNEXT_NEXT, D3DNEXT_HEAD or D3DNEXT_TAIL
930 * Returns:
931 * D3D_OK on success
932 * DDERR_INVALIDPARAMS if the flags were wrong, or Viewport was NULL
934 *****************************************************************************/
935 static HRESULT WINAPI
936 IDirect3DDeviceImpl_3_NextViewport(IDirect3DDevice3 *iface,
937 IDirect3DViewport3 *Viewport3,
938 IDirect3DViewport3 **lplpDirect3DViewport3,
939 DWORD Flags)
941 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
942 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport3);
943 IDirect3DViewportImpl *res = NULL;
945 TRACE("(%p)->(%p,%p,%08x)\n", This, vp, lplpDirect3DViewport3, Flags);
947 if(!vp)
949 *lplpDirect3DViewport3 = NULL;
950 return DDERR_INVALIDPARAMS;
954 EnterCriticalSection(&ddraw_cs);
955 switch (Flags)
957 case D3DNEXT_NEXT:
959 res = vp->next;
961 break;
962 case D3DNEXT_HEAD:
964 res = This->viewport_list;
966 break;
967 case D3DNEXT_TAIL:
969 IDirect3DViewportImpl *cur_viewport = This->viewport_list;
970 if (cur_viewport != NULL)
972 while (cur_viewport->next != NULL) cur_viewport = cur_viewport->next;
974 res = cur_viewport;
976 break;
977 default:
978 *lplpDirect3DViewport3 = NULL;
979 LeaveCriticalSection(&ddraw_cs);
980 return DDERR_INVALIDPARAMS;
983 *lplpDirect3DViewport3 = ICOM_INTERFACE(res, IDirect3DViewport3);
984 LeaveCriticalSection(&ddraw_cs);
985 return D3D_OK;
988 static HRESULT WINAPI
989 Thunk_IDirect3DDeviceImpl_2_NextViewport(IDirect3DDevice2 *iface,
990 IDirect3DViewport2 *Viewport2,
991 IDirect3DViewport2 **lplpDirect3DViewport2,
992 DWORD Flags)
994 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
995 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport2);
996 IDirect3DViewport3 *res;
997 HRESULT hr;
998 TRACE_(ddraw_thunk)("(%p)->(%p,%p,%08x) thunking to IDirect3DDevice3 interface.\n", This, vp, lplpDirect3DViewport2, Flags);
999 hr = IDirect3DDevice3_NextViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
1000 ICOM_INTERFACE(vp, IDirect3DViewport3),
1001 &res,
1002 Flags);
1003 *lplpDirect3DViewport2 = (IDirect3DViewport2 *) COM_INTERFACE_CAST(IDirect3DViewportImpl, IDirect3DViewport3, IDirect3DViewport3, res);
1004 return hr;
1007 static HRESULT WINAPI
1008 Thunk_IDirect3DDeviceImpl_1_NextViewport(IDirect3DDevice *iface,
1009 IDirect3DViewport *Viewport,
1010 IDirect3DViewport **lplpDirect3DViewport,
1011 DWORD Flags)
1013 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1014 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport);
1015 IDirect3DViewport3 *res;
1016 HRESULT hr;
1017 TRACE_(ddraw_thunk)("(%p)->(%p,%p,%08x) thunking to IDirect3DDevice3 interface.\n", This, vp, lplpDirect3DViewport, Flags);
1018 hr = IDirect3DDevice3_NextViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
1019 ICOM_INTERFACE(vp, IDirect3DViewport3),
1020 &res,
1021 Flags);
1022 *lplpDirect3DViewport = (IDirect3DViewport *) COM_INTERFACE_CAST(IDirect3DViewportImpl, IDirect3DViewport3, IDirect3DViewport3, res);
1023 return hr;
1026 /*****************************************************************************
1027 * IDirect3DDevice::Pick
1029 * Executes an execute buffer without performing rendering. Instead, a
1030 * list of primitives that intersect with (x1,y1) of the passed rectangle
1031 * is created. IDirect3DDevice::GetPickRecords can be used to retrieve
1032 * this list.
1034 * Version 1 only
1036 * Params:
1037 * ExecuteBuffer: Buffer to execute
1038 * Viewport: Viewport to use for execution
1039 * Flags: None are defined, according to the SDK
1040 * Rect: Specifies the coordinates to be picked. Only x1 and y2 are used,
1041 * x2 and y2 are ignored.
1043 * Returns:
1044 * D3D_OK because it's a stub
1046 *****************************************************************************/
1047 static HRESULT WINAPI
1048 IDirect3DDeviceImpl_1_Pick(IDirect3DDevice *iface,
1049 IDirect3DExecuteBuffer *ExecuteBuffer,
1050 IDirect3DViewport *Viewport,
1051 DWORD Flags,
1052 D3DRECT *Rect)
1054 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1055 IDirect3DExecuteBufferImpl *execbuf = ICOM_OBJECT(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, ExecuteBuffer);
1056 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport);
1057 FIXME("(%p)->(%p,%p,%08x,%p): stub!\n", This, execbuf, vp, Flags, Rect);
1059 return D3D_OK;
1062 /*****************************************************************************
1063 * IDirect3DDevice::GetPickRecords
1065 * Retrieves the pick records generated by IDirect3DDevice::GetPickRecords
1067 * Version 1 only
1069 * Params:
1070 * Count: Pointer to a DWORD containing the numbers of pick records to
1071 * retrieve
1072 * D3DPickRec: Address to store the resulting D3DPICKRECORD array.
1074 * Returns:
1075 * D3D_OK, because it's a stub
1077 *****************************************************************************/
1078 static HRESULT WINAPI
1079 IDirect3DDeviceImpl_1_GetPickRecords(IDirect3DDevice *iface,
1080 DWORD *Count,
1081 D3DPICKRECORD *D3DPickRec)
1083 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1084 FIXME("(%p)->(%p,%p): stub!\n", This, Count, D3DPickRec);
1086 return D3D_OK;
1089 /*****************************************************************************
1090 * IDirect3DDevice7::EnumTextureformats
1092 * Enumerates the supported texture formats. It has a list of all possible
1093 * formats and calls IWineD3D::CheckDeviceFormat for each format to see if
1094 * WineD3D supports it. If so, then it is passed to the app.
1096 * This is for Version 7 and 3, older versions have a different
1097 * callback function and their own implementation
1099 * Params:
1100 * Callback: Callback to call for each enumerated format
1101 * Arg: Argument to pass to the callback
1103 * Returns:
1104 * D3D_OK on success
1105 * DDERR_INVALIDPARAMS if Callback == NULL
1107 *****************************************************************************/
1108 static HRESULT WINAPI
1109 IDirect3DDeviceImpl_7_EnumTextureFormats(IDirect3DDevice7 *iface,
1110 LPD3DENUMPIXELFORMATSCALLBACK Callback,
1111 void *Arg)
1113 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1114 HRESULT hr;
1115 int i;
1117 WINED3DFORMAT FormatList[] = {
1118 /* 32 bit */
1119 WINED3DFMT_A8R8G8B8,
1120 WINED3DFMT_X8R8G8B8,
1121 /* 24 bit */
1122 WINED3DFMT_R8G8B8,
1123 /* 16 Bit */
1124 WINED3DFMT_A1R5G5B5,
1125 WINED3DFMT_A4R4G4B4,
1126 WINED3DFMT_R5G6B5,
1127 WINED3DFMT_X1R5G5B5,
1128 /* 8 Bit */
1129 WINED3DFMT_R3G3B2,
1130 WINED3DFMT_P8,
1131 /* FOURCC codes */
1132 WINED3DFMT_DXT1,
1133 WINED3DFMT_DXT3,
1134 WINED3DFMT_DXT5,
1137 WINED3DFORMAT BumpFormatList[] = {
1138 WINED3DFMT_V8U8,
1139 WINED3DFMT_L6V5U5,
1140 WINED3DFMT_X8L8V8U8,
1141 WINED3DFMT_Q8W8V8U8,
1142 WINED3DFMT_V16U16,
1143 WINED3DFMT_W11V11U10,
1144 WINED3DFMT_A2W10V10U10
1147 TRACE("(%p)->(%p,%p): Relay\n", This, Callback, Arg);
1149 if(!Callback)
1150 return DDERR_INVALIDPARAMS;
1152 EnterCriticalSection(&ddraw_cs);
1153 for(i = 0; i < sizeof(FormatList) / sizeof(WINED3DFORMAT); i++)
1155 hr = IWineD3D_CheckDeviceFormat(This->ddraw->wineD3D,
1156 0 /* Adapter */,
1157 0 /* DeviceType */,
1158 0 /* AdapterFormat */,
1159 0 /* Usage */,
1160 0 /* ResourceType */,
1161 FormatList[i]);
1162 if(hr == D3D_OK)
1164 DDPIXELFORMAT pformat;
1166 memset(&pformat, 0, sizeof(pformat));
1167 pformat.dwSize = sizeof(pformat);
1168 PixelFormat_WineD3DtoDD(&pformat, FormatList[i]);
1170 TRACE("Enumerating WineD3DFormat %d\n", FormatList[i]);
1171 hr = Callback(&pformat, Arg);
1172 if(hr != DDENUMRET_OK)
1174 TRACE("Format enumeration cancelled by application\n");
1175 LeaveCriticalSection(&ddraw_cs);
1176 return D3D_OK;
1181 for(i = 0; i < sizeof(BumpFormatList) / sizeof(WINED3DFORMAT); i++)
1183 hr = IWineD3D_CheckDeviceFormat(This->ddraw->wineD3D,
1184 0 /* Adapter */,
1185 0 /* DeviceType */,
1186 0 /* AdapterFormat */,
1187 WINED3DUSAGE_QUERY_LEGACYBUMPMAP,
1188 0 /* ResourceType */,
1189 BumpFormatList[i]);
1190 if(hr == D3D_OK)
1192 DDPIXELFORMAT pformat;
1194 memset(&pformat, 0, sizeof(pformat));
1195 pformat.dwSize = sizeof(pformat);
1196 PixelFormat_WineD3DtoDD(&pformat, BumpFormatList[i]);
1198 TRACE("Enumerating WineD3DFormat %d\n", BumpFormatList[i]);
1199 hr = Callback(&pformat, Arg);
1200 if(hr != DDENUMRET_OK)
1202 TRACE("Format enumeration cancelled by application\n");
1203 LeaveCriticalSection(&ddraw_cs);
1204 return D3D_OK;
1208 TRACE("End of enumeration\n");
1209 LeaveCriticalSection(&ddraw_cs);
1210 return D3D_OK;
1213 static HRESULT WINAPI
1214 Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats(IDirect3DDevice3 *iface,
1215 LPD3DENUMPIXELFORMATSCALLBACK Callback,
1216 void *Arg)
1218 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1219 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice7 interface.\n", This, Callback, Arg);
1220 return IDirect3DDevice7_EnumTextureFormats(ICOM_INTERFACE(This, IDirect3DDevice7),
1221 Callback,
1222 Arg);
1225 /*****************************************************************************
1226 * IDirect3DDevice2::EnumTextureformats
1228 * EnumTextureFormats for Version 1 and 2, see
1229 * IDirect3DDevice7::EnumTexureFormats for a more detailed description.
1231 * This version has a different callback and does not enumerate FourCC
1232 * formats
1234 *****************************************************************************/
1235 static HRESULT WINAPI
1236 IDirect3DDeviceImpl_2_EnumTextureFormats(IDirect3DDevice2 *iface,
1237 LPD3DENUMTEXTUREFORMATSCALLBACK Callback,
1238 void *Arg)
1240 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1241 HRESULT hr;
1242 int i;
1244 WINED3DFORMAT FormatList[] = {
1245 /* 32 bit */
1246 WINED3DFMT_A8R8G8B8,
1247 WINED3DFMT_X8R8G8B8,
1248 /* 24 bit */
1249 WINED3DFMT_R8G8B8,
1250 /* 16 Bit */
1251 WINED3DFMT_A1R5G5B5,
1252 WINED3DFMT_A4R4G4B4,
1253 WINED3DFMT_R5G6B5,
1254 WINED3DFMT_X1R5G5B5,
1255 /* 8 Bit */
1256 WINED3DFMT_R3G3B2,
1257 WINED3DFMT_P8,
1258 /* FOURCC codes - Not in this version*/
1261 TRACE("(%p)->(%p,%p): Relay\n", This, Callback, Arg);
1263 if(!Callback)
1264 return DDERR_INVALIDPARAMS;
1266 EnterCriticalSection(&ddraw_cs);
1267 for(i = 0; i < sizeof(FormatList) / sizeof(WINED3DFORMAT); i++)
1269 hr = IWineD3D_CheckDeviceFormat(This->ddraw->wineD3D,
1270 0 /* Adapter */,
1271 0 /* DeviceType */,
1272 0 /* AdapterFormat */,
1273 0 /* Usage */,
1274 0 /* ResourceType */,
1275 FormatList[i]);
1276 if(hr == D3D_OK)
1278 DDSURFACEDESC sdesc;
1280 memset(&sdesc, 0, sizeof(sdesc));
1281 sdesc.dwSize = sizeof(sdesc);
1282 sdesc.dwFlags = DDSD_PIXELFORMAT | DDSD_CAPS;
1283 sdesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1284 sdesc.ddpfPixelFormat.dwSize = sizeof(sdesc.ddpfPixelFormat);
1285 PixelFormat_WineD3DtoDD(&sdesc.ddpfPixelFormat, FormatList[i]);
1287 TRACE("Enumerating WineD3DFormat %d\n", FormatList[i]);
1288 hr = Callback(&sdesc, Arg);
1289 if(hr != DDENUMRET_OK)
1291 TRACE("Format enumeration cancelled by application\n");
1292 LeaveCriticalSection(&ddraw_cs);
1293 return D3D_OK;
1297 TRACE("End of enumeration\n");
1298 LeaveCriticalSection(&ddraw_cs);
1299 return D3D_OK;
1302 static HRESULT WINAPI
1303 Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats(IDirect3DDevice *iface,
1304 LPD3DENUMTEXTUREFORMATSCALLBACK Callback,
1305 void *Arg)
1307 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1308 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice2 interface.\n", This, Callback, Arg);
1309 return IDirect3DDevice2_EnumTextureFormats(ICOM_INTERFACE(This, IDirect3DDevice2),
1310 Callback,
1311 Arg);
1314 /*****************************************************************************
1315 * IDirect3DDevice::CreateMatrix
1317 * Creates a matrix handle. A handle is created and memory for a D3DMATRIX is
1318 * allocated for the handle.
1320 * Version 1 only
1322 * Params
1323 * D3DMatHandle: Address to return the handle at
1325 * Returns:
1326 * D3D_OK on success
1327 * DDERR_INVALIDPARAMS if D3DMatHandle = NULL
1329 *****************************************************************************/
1330 static HRESULT WINAPI
1331 IDirect3DDeviceImpl_1_CreateMatrix(IDirect3DDevice *iface, D3DMATRIXHANDLE *D3DMatHandle)
1333 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1334 D3DMATRIX *Matrix;
1335 TRACE("(%p)->(%p)\n", This, D3DMatHandle);
1337 if(!D3DMatHandle)
1338 return DDERR_INVALIDPARAMS;
1340 Matrix = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(D3DMATRIX));
1341 if(!Matrix)
1343 ERR("Out of memory when allocating a D3DMATRIX\n");
1344 return DDERR_OUTOFMEMORY;
1347 EnterCriticalSection(&ddraw_cs);
1348 *D3DMatHandle = IDirect3DDeviceImpl_CreateHandle(This);
1349 if(!(*D3DMatHandle))
1351 ERR("Failed to create a matrix handle\n");
1352 HeapFree(GetProcessHeap(), 0, Matrix);
1353 LeaveCriticalSection(&ddraw_cs);
1354 return DDERR_OUTOFMEMORY;
1356 This->Handles[*D3DMatHandle - 1].ptr = Matrix;
1357 This->Handles[*D3DMatHandle - 1].type = DDrawHandle_Matrix;
1358 TRACE(" returning matrix handle %d\n", *D3DMatHandle);
1360 LeaveCriticalSection(&ddraw_cs);
1361 return D3D_OK;
1364 /*****************************************************************************
1365 * IDirect3DDevice::SetMatrix
1367 * Sets a matrix for a matrix handle. The matrix is copied into the memory
1368 * allocated for the handle
1370 * Version 1 only
1372 * Params:
1373 * D3DMatHandle: Handle to set the matrix to
1374 * D3DMatrix: Matrix to set
1376 * Returns:
1377 * D3D_OK on success
1378 * DDERR_INVALIDPARAMS if the handle of the matrix is invalid or the matrix
1379 * to set is NULL
1381 *****************************************************************************/
1382 static HRESULT WINAPI
1383 IDirect3DDeviceImpl_1_SetMatrix(IDirect3DDevice *iface,
1384 D3DMATRIXHANDLE D3DMatHandle,
1385 D3DMATRIX *D3DMatrix)
1387 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1388 TRACE("(%p)->(%08x,%p)\n", This, D3DMatHandle, D3DMatrix);
1390 if( (!D3DMatHandle) || (!D3DMatrix) )
1391 return DDERR_INVALIDPARAMS;
1393 EnterCriticalSection(&ddraw_cs);
1394 if(D3DMatHandle > This->numHandles)
1396 ERR("Handle %d out of range\n", D3DMatHandle);
1397 LeaveCriticalSection(&ddraw_cs);
1398 return DDERR_INVALIDPARAMS;
1400 else if(This->Handles[D3DMatHandle - 1].type != DDrawHandle_Matrix)
1402 ERR("Handle %d is not a matrix handle\n", D3DMatHandle);
1403 LeaveCriticalSection(&ddraw_cs);
1404 return DDERR_INVALIDPARAMS;
1407 if (TRACE_ON(d3d7))
1408 dump_D3DMATRIX(D3DMatrix);
1410 *((D3DMATRIX *) This->Handles[D3DMatHandle - 1].ptr) = *D3DMatrix;
1412 if(This->world == D3DMatHandle)
1414 IWineD3DDevice_SetTransform(This->wineD3DDevice,
1415 WINED3DTS_WORLDMATRIX(0),
1416 (WINED3DMATRIX *) D3DMatrix);
1418 if(This->view == D3DMatHandle)
1420 IWineD3DDevice_SetTransform(This->wineD3DDevice,
1421 WINED3DTS_VIEW,
1422 (WINED3DMATRIX *) D3DMatrix);
1424 if(This->proj == D3DMatHandle)
1426 IWineD3DDevice_SetTransform(This->wineD3DDevice,
1427 WINED3DTS_PROJECTION,
1428 (WINED3DMATRIX *) D3DMatrix);
1431 LeaveCriticalSection(&ddraw_cs);
1432 return D3D_OK;
1435 /*****************************************************************************
1436 * IDirect3DDevice::SetMatrix
1438 * Returns the content of a D3DMATRIX handle
1440 * Version 1 only
1442 * Params:
1443 * D3DMatHandle: Matrix handle to read the content from
1444 * D3DMatrix: Address to store the content at
1446 * Returns:
1447 * D3D_OK on success
1448 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid or D3DMatrix is NULL
1450 *****************************************************************************/
1451 static HRESULT WINAPI
1452 IDirect3DDeviceImpl_1_GetMatrix(IDirect3DDevice *iface,
1453 D3DMATRIXHANDLE D3DMatHandle,
1454 D3DMATRIX *D3DMatrix)
1456 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1457 TRACE("(%p)->(%08x,%p)\n", This, D3DMatHandle, D3DMatrix);
1459 if(!D3DMatrix)
1460 return DDERR_INVALIDPARAMS;
1461 if(!D3DMatHandle)
1462 return DDERR_INVALIDPARAMS;
1464 EnterCriticalSection(&ddraw_cs);
1465 if(D3DMatHandle > This->numHandles)
1467 ERR("Handle %d out of range\n", D3DMatHandle);
1468 LeaveCriticalSection(&ddraw_cs);
1469 return DDERR_INVALIDPARAMS;
1471 else if(This->Handles[D3DMatHandle - 1].type != DDrawHandle_Matrix)
1473 ERR("Handle %d is not a matrix handle\n", D3DMatHandle);
1474 LeaveCriticalSection(&ddraw_cs);
1475 return DDERR_INVALIDPARAMS;
1478 /* The handle is simply a pointer to a D3DMATRIX structure */
1479 *D3DMatrix = *((D3DMATRIX *) This->Handles[D3DMatHandle - 1].ptr);
1481 LeaveCriticalSection(&ddraw_cs);
1482 return D3D_OK;
1485 /*****************************************************************************
1486 * IDirect3DDevice::DeleteMatrix
1488 * Destroys a Matrix handle. Frees the memory and unsets the handle data
1490 * Version 1 only
1492 * Params:
1493 * D3DMatHandle: Handle to destroy
1495 * Returns:
1496 * D3D_OK on success
1497 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid
1499 *****************************************************************************/
1500 static HRESULT WINAPI
1501 IDirect3DDeviceImpl_1_DeleteMatrix(IDirect3DDevice *iface,
1502 D3DMATRIXHANDLE D3DMatHandle)
1504 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1505 TRACE("(%p)->(%08x)\n", This, D3DMatHandle);
1507 if(!D3DMatHandle)
1508 return DDERR_INVALIDPARAMS;
1510 EnterCriticalSection(&ddraw_cs);
1511 if(D3DMatHandle > This->numHandles)
1513 ERR("Handle %d out of range\n", D3DMatHandle);
1514 LeaveCriticalSection(&ddraw_cs);
1515 return DDERR_INVALIDPARAMS;
1517 else if(This->Handles[D3DMatHandle - 1].type != DDrawHandle_Matrix)
1519 ERR("Handle %d is not a matrix handle\n", D3DMatHandle);
1520 LeaveCriticalSection(&ddraw_cs);
1521 return DDERR_INVALIDPARAMS;
1524 HeapFree(GetProcessHeap(), 0, This->Handles[D3DMatHandle - 1].ptr);
1525 This->Handles[D3DMatHandle - 1].ptr = NULL;
1526 This->Handles[D3DMatHandle - 1].type = DDrawHandle_Unknown;
1528 LeaveCriticalSection(&ddraw_cs);
1529 return D3D_OK;
1532 /*****************************************************************************
1533 * IDirect3DDevice7::BeginScene
1535 * This method must be called before any rendering is performed.
1536 * IDirect3DDevice::EndScene has to be called after the scene is complete
1538 * Version 1, 2, 3 and 7
1540 * Returns:
1541 * D3D_OK on success, for details see IWineD3DDevice::BeginScene
1542 * D3DERR_SCENE_IN_SCENE if WineD3D returns an error(Only in case of an already
1543 * started scene).
1545 *****************************************************************************/
1546 static HRESULT WINAPI
1547 IDirect3DDeviceImpl_7_BeginScene(IDirect3DDevice7 *iface)
1549 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1550 HRESULT hr;
1551 TRACE("(%p): Relay\n", This);
1553 EnterCriticalSection(&ddraw_cs);
1554 hr = IWineD3DDevice_BeginScene(This->wineD3DDevice);
1555 LeaveCriticalSection(&ddraw_cs);
1556 if(hr == WINED3D_OK) return D3D_OK;
1557 else return D3DERR_SCENE_IN_SCENE; /* TODO: Other possible causes of failure */
1560 static HRESULT WINAPI
1561 Thunk_IDirect3DDeviceImpl_3_BeginScene(IDirect3DDevice3 *iface)
1563 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1564 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1565 return IDirect3DDevice7_BeginScene(ICOM_INTERFACE(This, IDirect3DDevice7));
1568 static HRESULT WINAPI
1569 Thunk_IDirect3DDeviceImpl_2_BeginScene(IDirect3DDevice2 *iface)
1571 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1572 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1573 return IDirect3DDevice7_BeginScene(ICOM_INTERFACE(This, IDirect3DDevice7));
1576 static HRESULT WINAPI
1577 Thunk_IDirect3DDeviceImpl_1_BeginScene(IDirect3DDevice *iface)
1579 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1580 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1581 return IDirect3DDevice7_BeginScene(ICOM_INTERFACE(This, IDirect3DDevice7));
1584 /*****************************************************************************
1585 * IDirect3DDevice7::EndScene
1587 * Ends a scene that has been begun with IDirect3DDevice7::BeginScene.
1588 * This method must be called after rendering is finished.
1590 * Version 1, 2, 3 and 7
1592 * Returns:
1593 * D3D_OK on success, for details see IWineD3DDevice::EndScene
1594 * D3DERR_SCENE_NOT_IN_SCENE is returned if WineD3D returns an error. It does
1595 * that only if the scene was already ended.
1597 *****************************************************************************/
1598 static HRESULT WINAPI
1599 IDirect3DDeviceImpl_7_EndScene(IDirect3DDevice7 *iface)
1601 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1602 HRESULT hr;
1603 TRACE("(%p): Relay\n", This);
1605 EnterCriticalSection(&ddraw_cs);
1606 hr = IWineD3DDevice_EndScene(This->wineD3DDevice);
1607 LeaveCriticalSection(&ddraw_cs);
1608 if(hr == WINED3D_OK) return D3D_OK;
1609 else return D3DERR_SCENE_NOT_IN_SCENE;
1612 static HRESULT WINAPI
1613 Thunk_IDirect3DDeviceImpl_3_EndScene(IDirect3DDevice3 *iface)
1615 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1616 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1617 return IDirect3DDevice7_EndScene(ICOM_INTERFACE(This, IDirect3DDevice7));
1620 static HRESULT WINAPI
1621 Thunk_IDirect3DDeviceImpl_2_EndScene(IDirect3DDevice2 *iface)
1623 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1624 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1625 return IDirect3DDevice7_EndScene(ICOM_INTERFACE(This, IDirect3DDevice7));
1628 static HRESULT WINAPI
1629 Thunk_IDirect3DDeviceImpl_1_EndScene(IDirect3DDevice *iface)
1631 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1632 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1633 return IDirect3DDevice7_EndScene(ICOM_INTERFACE(This, IDirect3DDevice7));
1636 /*****************************************************************************
1637 * IDirect3DDevice7::GetDirect3D
1639 * Returns the IDirect3D(= interface to the DirectDraw object) used to create
1640 * this device.
1642 * Params:
1643 * Direct3D7: Address to store the interface pointer at
1645 * Returns:
1646 * D3D_OK on success
1647 * DDERR_INVALIDPARAMS if Direct3D7 == NULL
1649 *****************************************************************************/
1650 static HRESULT WINAPI
1651 IDirect3DDeviceImpl_7_GetDirect3D(IDirect3DDevice7 *iface,
1652 IDirect3D7 **Direct3D7)
1654 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1655 TRACE("(%p)->(%p)\n", This, Direct3D7);
1657 if(!Direct3D7)
1658 return DDERR_INVALIDPARAMS;
1660 *Direct3D7 = ICOM_INTERFACE(This->ddraw, IDirect3D7);
1661 IDirect3D7_AddRef(*Direct3D7);
1663 TRACE(" returning interface %p\n", *Direct3D7);
1664 return D3D_OK;
1667 static HRESULT WINAPI
1668 Thunk_IDirect3DDeviceImpl_3_GetDirect3D(IDirect3DDevice3 *iface,
1669 IDirect3D3 **Direct3D3)
1671 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1672 HRESULT ret;
1673 IDirect3D7 *ret_ptr;
1675 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Direct3D3);
1676 ret = IDirect3DDevice7_GetDirect3D(ICOM_INTERFACE(This, IDirect3DDevice7),
1677 &ret_ptr);
1678 if(ret != D3D_OK)
1679 return ret;
1680 *Direct3D3 = COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D7, IDirect3D3, ret_ptr);
1681 TRACE(" returning interface %p\n", *Direct3D3);
1682 return D3D_OK;
1685 static HRESULT WINAPI
1686 Thunk_IDirect3DDeviceImpl_2_GetDirect3D(IDirect3DDevice2 *iface,
1687 IDirect3D2 **Direct3D2)
1689 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1690 HRESULT ret;
1691 IDirect3D7 *ret_ptr;
1693 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Direct3D2);
1694 ret = IDirect3DDevice7_GetDirect3D(ICOM_INTERFACE(This, IDirect3DDevice7),
1695 &ret_ptr);
1696 if(ret != D3D_OK)
1697 return ret;
1698 *Direct3D2 = COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D7, IDirect3D2, ret_ptr);
1699 TRACE(" returning interface %p\n", *Direct3D2);
1700 return D3D_OK;
1703 static HRESULT WINAPI
1704 Thunk_IDirect3DDeviceImpl_1_GetDirect3D(IDirect3DDevice *iface,
1705 IDirect3D **Direct3D)
1707 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1708 HRESULT ret;
1709 IDirect3D7 *ret_ptr;
1711 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Direct3D);
1712 ret = IDirect3DDevice7_GetDirect3D(ICOM_INTERFACE(This, IDirect3DDevice7),
1713 &ret_ptr);
1714 if(ret != D3D_OK)
1715 return ret;
1716 *Direct3D = COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D7, IDirect3D, ret_ptr);
1717 TRACE(" returning interface %p\n", *Direct3D);
1718 return D3D_OK;
1721 /*****************************************************************************
1722 * IDirect3DDevice3::SetCurrentViewport
1724 * Sets a Direct3DViewport as the current viewport.
1725 * For the thunks note that all viewport interface versions are equal
1727 * Params:
1728 * Direct3DViewport3: The viewport to set
1730 * Version 2 and 3
1732 * Returns:
1733 * D3D_OK on success
1734 * (Is a NULL viewport valid?)
1736 *****************************************************************************/
1737 static HRESULT WINAPI
1738 IDirect3DDeviceImpl_3_SetCurrentViewport(IDirect3DDevice3 *iface,
1739 IDirect3DViewport3 *Direct3DViewport3)
1741 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1742 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport3);
1743 TRACE("(%p)->(%p)\n", This, Direct3DViewport3);
1745 EnterCriticalSection(&ddraw_cs);
1746 /* Do nothing if the specified viewport is the same as the current one */
1747 if (This->current_viewport == vp )
1749 LeaveCriticalSection(&ddraw_cs);
1750 return D3D_OK;
1753 /* Should check if the viewport was added or not */
1755 /* Release previous viewport and AddRef the new one */
1756 if (This->current_viewport)
1758 TRACE("ViewportImpl is at %p, interface is at %p\n", This->current_viewport, ICOM_INTERFACE(This->current_viewport, IDirect3DViewport3));
1759 IDirect3DViewport3_Release( ICOM_INTERFACE(This->current_viewport, IDirect3DViewport3) );
1761 IDirect3DViewport3_AddRef(Direct3DViewport3);
1763 /* Set this viewport as the current viewport */
1764 This->current_viewport = vp;
1766 /* Activate this viewport */
1767 This->current_viewport->active_device = This;
1768 This->current_viewport->activate(This->current_viewport, FALSE);
1770 LeaveCriticalSection(&ddraw_cs);
1771 return D3D_OK;
1774 static HRESULT WINAPI
1775 Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport(IDirect3DDevice2 *iface,
1776 IDirect3DViewport2 *Direct3DViewport2)
1778 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1779 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport2);
1780 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
1781 return IDirect3DDevice3_SetCurrentViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
1782 ICOM_INTERFACE(vp, IDirect3DViewport3));
1785 /*****************************************************************************
1786 * IDirect3DDevice3::GetCurrentViewport
1788 * Returns the currently active viewport.
1790 * Version 2 and 3
1792 * Params:
1793 * Direct3DViewport3: Address to return the interface pointer at
1795 * Returns:
1796 * D3D_OK on success
1797 * DDERR_INVALIDPARAMS if Direct3DViewport == NULL
1799 *****************************************************************************/
1800 static HRESULT WINAPI
1801 IDirect3DDeviceImpl_3_GetCurrentViewport(IDirect3DDevice3 *iface,
1802 IDirect3DViewport3 **Direct3DViewport3)
1804 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1805 TRACE("(%p)->(%p)\n", This, Direct3DViewport3);
1807 if(!Direct3DViewport3)
1808 return DDERR_INVALIDPARAMS;
1810 EnterCriticalSection(&ddraw_cs);
1811 *Direct3DViewport3 = ICOM_INTERFACE(This->current_viewport, IDirect3DViewport3);
1813 /* AddRef the returned viewport */
1814 if(*Direct3DViewport3) IDirect3DViewport3_AddRef(*Direct3DViewport3);
1816 TRACE(" returning interface %p\n", *Direct3DViewport3);
1818 LeaveCriticalSection(&ddraw_cs);
1819 return D3D_OK;
1822 static HRESULT WINAPI
1823 Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport(IDirect3DDevice2 *iface,
1824 IDirect3DViewport2 **Direct3DViewport2)
1826 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1827 HRESULT hr;
1828 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, Direct3DViewport2);
1829 hr = IDirect3DDevice3_GetCurrentViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
1830 (IDirect3DViewport3 **) Direct3DViewport2);
1831 if(hr != D3D_OK) return hr;
1832 *Direct3DViewport2 = (IDirect3DViewport2 *) COM_INTERFACE_CAST(IDirect3DViewportImpl, IDirect3DViewport3, IDirect3DViewport3, *Direct3DViewport2);
1833 return D3D_OK;
1836 /*****************************************************************************
1837 * IDirect3DDevice7::SetRenderTarget
1839 * Sets the render target for the Direct3DDevice.
1840 * For the thunks note that IDirectDrawSurface7 == IDirectDrawSurface4 and
1841 * IDirectDrawSurface3 == IDirectDrawSurface
1843 * Version 2, 3 and 7
1845 * Params:
1846 * NewTarget: Pointer to an IDirectDrawSurface7 interface to set as the new
1847 * render target
1848 * Flags: Some flags
1850 * Returns:
1851 * D3D_OK on success, for details see IWineD3DDevice::SetRenderTarget
1853 *****************************************************************************/
1854 static HRESULT WINAPI
1855 IDirect3DDeviceImpl_7_SetRenderTarget(IDirect3DDevice7 *iface,
1856 IDirectDrawSurface7 *NewTarget,
1857 DWORD Flags)
1859 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1860 IDirectDrawSurfaceImpl *Target = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, NewTarget);
1861 HRESULT hr;
1862 TRACE("(%p)->(%p,%08x): Relay\n", This, NewTarget, Flags);
1864 EnterCriticalSection(&ddraw_cs);
1865 /* Flags: Not used */
1867 if(This->target == Target)
1869 TRACE("No-op SetRenderTarget operation, not doing anything\n");
1870 LeaveCriticalSection(&ddraw_cs);
1871 return D3D_OK;
1874 hr = IWineD3DDevice_SetRenderTarget(This->wineD3DDevice,
1876 Target ? Target->WineD3DSurface : NULL);
1877 if(hr != D3D_OK)
1879 LeaveCriticalSection(&ddraw_cs);
1880 return hr;
1882 IDirectDrawSurface7_AddRef(NewTarget);
1883 IDirectDrawSurface7_Release(ICOM_INTERFACE(This->target, IDirectDrawSurface7));
1884 This->target = Target;
1885 IDirect3DDeviceImpl_UpdateDepthStencil(This);
1886 LeaveCriticalSection(&ddraw_cs);
1887 return D3D_OK;
1890 static HRESULT WINAPI
1891 Thunk_IDirect3DDeviceImpl_3_SetRenderTarget(IDirect3DDevice3 *iface,
1892 IDirectDrawSurface4 *NewRenderTarget,
1893 DWORD Flags)
1895 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1896 IDirectDrawSurfaceImpl *Target = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, NewRenderTarget);
1897 TRACE_(ddraw_thunk)("(%p)->(%p,%08x) thunking to IDirect3DDevice7 interface.\n", This, Target, Flags);
1898 return IDirect3DDevice7_SetRenderTarget(ICOM_INTERFACE(This, IDirect3DDevice7),
1899 ICOM_INTERFACE(Target, IDirectDrawSurface7),
1900 Flags);
1903 static HRESULT WINAPI
1904 Thunk_IDirect3DDeviceImpl_2_SetRenderTarget(IDirect3DDevice2 *iface,
1905 IDirectDrawSurface *NewRenderTarget,
1906 DWORD Flags)
1908 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1909 IDirectDrawSurfaceImpl *Target = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface3, NewRenderTarget);
1910 TRACE_(ddraw_thunk)("(%p)->(%p,%08x) thunking to IDirect3DDevice7 interface.\n", This, Target, Flags);
1911 return IDirect3DDevice7_SetRenderTarget(ICOM_INTERFACE(This, IDirect3DDevice7),
1912 ICOM_INTERFACE(Target, IDirectDrawSurface7),
1913 Flags);
1916 /*****************************************************************************
1917 * IDirect3DDevice7::GetRenderTarget
1919 * Returns the current render target.
1920 * This is handled locally, because the WineD3D render target's parent
1921 * is an IParent
1923 * Version 2, 3 and 7
1925 * Params:
1926 * RenderTarget: Address to store the surface interface pointer
1928 * Returns:
1929 * D3D_OK on success
1930 * DDERR_INVALIDPARAMS if RenderTarget == NULL
1932 *****************************************************************************/
1933 static HRESULT WINAPI
1934 IDirect3DDeviceImpl_7_GetRenderTarget(IDirect3DDevice7 *iface,
1935 IDirectDrawSurface7 **RenderTarget)
1937 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1938 TRACE("(%p)->(%p): Relay\n", This, RenderTarget);
1940 if(!RenderTarget)
1941 return DDERR_INVALIDPARAMS;
1943 EnterCriticalSection(&ddraw_cs);
1944 *RenderTarget = ICOM_INTERFACE(This->target, IDirectDrawSurface7);
1945 IDirectDrawSurface7_AddRef(*RenderTarget);
1947 LeaveCriticalSection(&ddraw_cs);
1948 return D3D_OK;
1951 static HRESULT WINAPI
1952 Thunk_IDirect3DDeviceImpl_3_GetRenderTarget(IDirect3DDevice3 *iface,
1953 IDirectDrawSurface4 **RenderTarget)
1955 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1956 HRESULT hr;
1957 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, RenderTarget);
1958 hr = IDirect3DDevice7_GetRenderTarget(ICOM_INTERFACE(This, IDirect3DDevice7),
1959 (IDirectDrawSurface7 **) RenderTarget);
1960 if(hr != D3D_OK) return hr;
1961 *RenderTarget = (IDirectDrawSurface4 *) COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7, IDirectDrawSurface7, *RenderTarget);
1962 return D3D_OK;
1965 static HRESULT WINAPI
1966 Thunk_IDirect3DDeviceImpl_2_GetRenderTarget(IDirect3DDevice2 *iface,
1967 IDirectDrawSurface **RenderTarget)
1969 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1970 HRESULT hr;
1971 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, RenderTarget);
1972 hr = IDirect3DDevice7_GetRenderTarget(ICOM_INTERFACE(This, IDirect3DDevice7),
1973 (IDirectDrawSurface7 **) RenderTarget);
1974 if(hr != D3D_OK) return hr;
1975 *RenderTarget = (IDirectDrawSurface *) COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7, IDirectDrawSurface3, *RenderTarget);
1976 return D3D_OK;
1979 /*****************************************************************************
1980 * IDirect3DDevice3::Begin
1982 * Begins a description block of vertices. This is similar to glBegin()
1983 * and glEnd(). After a call to IDirect3DDevice3::End, the vertices
1984 * described with IDirect3DDevice::Vertex are drawn.
1986 * Version 2 and 3
1988 * Params:
1989 * PrimitiveType: The type of primitives to draw
1990 * VertexTypeDesc: A flexible vertex format description of the vertices
1991 * Flags: Some flags..
1993 * Returns:
1994 * D3D_OK on success
1996 *****************************************************************************/
1997 static HRESULT WINAPI
1998 IDirect3DDeviceImpl_3_Begin(IDirect3DDevice3 *iface,
1999 D3DPRIMITIVETYPE PrimitiveType,
2000 DWORD VertexTypeDesc,
2001 DWORD Flags)
2003 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2004 TRACE("(%p)->(%d,%d,%08x)\n", This, PrimitiveType, VertexTypeDesc, Flags);
2006 EnterCriticalSection(&ddraw_cs);
2007 This->primitive_type = PrimitiveType;
2008 This->vertex_type = VertexTypeDesc;
2009 This->render_flags = Flags;
2010 This->vertex_size = get_flexible_vertex_size(This->vertex_type);
2011 This->nb_vertices = 0;
2012 LeaveCriticalSection(&ddraw_cs);
2014 return D3D_OK;
2017 static HRESULT WINAPI
2018 Thunk_IDirect3DDeviceImpl_2_Begin(IDirect3DDevice2 *iface,
2019 D3DPRIMITIVETYPE d3dpt,
2020 D3DVERTEXTYPE dwVertexTypeDesc,
2021 DWORD dwFlags)
2023 DWORD FVF;
2024 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2025 TRACE_(ddraw_thunk)("(%p/%p)->(%08x,%08x,%08x): Thunking to IDirect3DDevice3\n", This, iface, d3dpt, dwVertexTypeDesc, dwFlags);
2027 switch(dwVertexTypeDesc)
2029 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
2030 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
2031 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
2032 default:
2033 ERR("Unexpected vertex type %d\n", dwVertexTypeDesc);
2034 return DDERR_INVALIDPARAMS; /* Should never happen */
2037 return IDirect3DDevice3_Begin(ICOM_INTERFACE(This, IDirect3DDevice3),
2038 d3dpt,
2039 FVF,
2040 dwFlags);
2043 /*****************************************************************************
2044 * IDirect3DDevice3::BeginIndexed
2046 * Draws primitives based on vertices in a vertex array which are specified
2047 * by indices.
2049 * Version 2 and 3
2051 * Params:
2052 * PrimitiveType: Primitive type to draw
2053 * VertexType: A FVF description of the vertex format
2054 * Vertices: pointer to an array containing the vertices
2055 * NumVertices: The number of vertices in the vertex array
2056 * Flags: Some flags ...
2058 * Returns:
2059 * D3D_OK, because it's a stub
2061 *****************************************************************************/
2062 static HRESULT WINAPI
2063 IDirect3DDeviceImpl_3_BeginIndexed(IDirect3DDevice3 *iface,
2064 D3DPRIMITIVETYPE PrimitiveType,
2065 DWORD VertexType,
2066 void *Vertices,
2067 DWORD NumVertices,
2068 DWORD Flags)
2070 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2071 FIXME("(%p)->(%08x,%08x,%p,%08x,%08x): stub!\n", This, PrimitiveType, VertexType, Vertices, NumVertices, Flags);
2072 return D3D_OK;
2076 static HRESULT WINAPI
2077 Thunk_IDirect3DDeviceImpl_2_BeginIndexed(IDirect3DDevice2 *iface,
2078 D3DPRIMITIVETYPE d3dptPrimitiveType,
2079 D3DVERTEXTYPE d3dvtVertexType,
2080 void *lpvVertices,
2081 DWORD dwNumVertices,
2082 DWORD dwFlags)
2084 DWORD FVF;
2085 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2086 TRACE_(ddraw_thunk)("(%p/%p)->(%08x,%08x,%p,%08x,%08x): Thunking to IDirect3DDevice3\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwNumVertices, dwFlags);
2088 switch(d3dvtVertexType)
2090 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
2091 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
2092 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
2093 default:
2094 ERR("Unexpected vertex type %d\n", d3dvtVertexType);
2095 return DDERR_INVALIDPARAMS; /* Should never happen */
2098 return IDirect3DDevice3_BeginIndexed(ICOM_INTERFACE(This,IDirect3DDevice3),
2099 d3dptPrimitiveType,
2100 FVF,
2101 lpvVertices,
2102 dwNumVertices,
2103 dwFlags);
2106 /*****************************************************************************
2107 * IDirect3DDevice3::Vertex
2109 * Draws a vertex as described by IDirect3DDevice3::Begin. It places all
2110 * drawn vertices in a vertex buffer. If the buffer is too small, its
2111 * size is increased.
2113 * Version 2 and 3
2115 * Params:
2116 * Vertex: Pointer to the vertex
2118 * Returns:
2119 * D3D_OK, on success
2120 * DDERR_INVALIDPARAMS if Vertex is NULL
2122 *****************************************************************************/
2123 static HRESULT WINAPI
2124 IDirect3DDeviceImpl_3_Vertex(IDirect3DDevice3 *iface,
2125 void *Vertex)
2127 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2128 TRACE("(%p)->(%p)\n", This, Vertex);
2130 if(!Vertex)
2131 return DDERR_INVALIDPARAMS;
2133 EnterCriticalSection(&ddraw_cs);
2134 if ((This->nb_vertices+1)*This->vertex_size > This->buffer_size)
2136 BYTE *old_buffer;
2137 This->buffer_size = This->buffer_size ? This->buffer_size * 2 : This->vertex_size * 3;
2138 old_buffer = This->vertex_buffer;
2139 This->vertex_buffer = HeapAlloc(GetProcessHeap(), 0, This->buffer_size);
2140 if (old_buffer)
2142 CopyMemory(This->vertex_buffer, old_buffer, This->nb_vertices * This->vertex_size);
2143 HeapFree(GetProcessHeap(), 0, old_buffer);
2147 CopyMemory(This->vertex_buffer + This->nb_vertices++ * This->vertex_size, Vertex, This->vertex_size);
2149 LeaveCriticalSection(&ddraw_cs);
2150 return D3D_OK;
2153 static HRESULT WINAPI
2154 Thunk_IDirect3DDeviceImpl_2_Vertex(IDirect3DDevice2 *iface,
2155 void *lpVertexType)
2157 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2158 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, lpVertexType);
2159 return IDirect3DDevice3_Vertex(ICOM_INTERFACE(This, IDirect3DDevice3),
2160 lpVertexType);
2163 /*****************************************************************************
2164 * IDirect3DDevice3::Index
2166 * Specifies an index to a vertex to be drawn. The vertex array has to
2167 * be specified with BeginIndexed first.
2169 * Parameters:
2170 * VertexIndex: The index of the vertex to draw
2172 * Returns:
2173 * D3D_OK because it's a stub
2175 *****************************************************************************/
2176 static HRESULT WINAPI
2177 IDirect3DDeviceImpl_3_Index(IDirect3DDevice3 *iface,
2178 WORD VertexIndex)
2180 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2181 FIXME("(%p)->(%04x): stub!\n", This, VertexIndex);
2182 return D3D_OK;
2185 static HRESULT WINAPI
2186 Thunk_IDirect3DDeviceImpl_2_Index(IDirect3DDevice2 *iface,
2187 WORD wVertexIndex)
2189 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2190 TRACE_(ddraw_thunk)("(%p)->(%04x) thunking to IDirect3DDevice3 interface.\n", This, wVertexIndex);
2191 return IDirect3DDevice3_Index(ICOM_INTERFACE(This, IDirect3DDevice3),
2192 wVertexIndex);
2195 /*****************************************************************************
2196 * IDirect3DDevice3::End
2198 * Ends a draw begun with IDirect3DDevice3::Begin or
2199 * IDirect3DDevice::BeginIndexed. The vertices specified with
2200 * IDirect3DDevice::Vertex or IDirect3DDevice::Index are drawn using
2201 * the IDirect3DDevice7::DrawPrimitive method. So far only
2202 * non-indexed mode is supported
2204 * Version 2 and 3
2206 * Params:
2207 * Flags: Some flags, as usual. Don't know which are defined
2209 * Returns:
2210 * The return value of IDirect3DDevice7::DrawPrimitive
2212 *****************************************************************************/
2213 static HRESULT WINAPI
2214 IDirect3DDeviceImpl_3_End(IDirect3DDevice3 *iface,
2215 DWORD Flags)
2217 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2218 TRACE("(%p)->(%08x)\n", This, Flags);
2220 return IDirect3DDevice7_DrawPrimitive(ICOM_INTERFACE(This, IDirect3DDevice7),
2221 This->primitive_type, This->vertex_type,
2222 This->vertex_buffer, This->nb_vertices,
2223 This->render_flags);
2226 static HRESULT WINAPI
2227 Thunk_IDirect3DDeviceImpl_2_End(IDirect3DDevice2 *iface,
2228 DWORD dwFlags)
2230 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2231 TRACE_(ddraw_thunk)("(%p)->(%08x) thunking to IDirect3DDevice3 interface.\n", This, dwFlags);
2232 return IDirect3DDevice3_End(ICOM_INTERFACE(This, IDirect3DDevice3),
2233 dwFlags);
2236 /*****************************************************************************
2237 * IDirect3DDevice7::GetRenderState
2239 * Returns the value of a render state. The possible render states are
2240 * defined in include/d3dtypes.h
2242 * Version 2, 3 and 7
2244 * Params:
2245 * RenderStateType: Render state to return the current setting of
2246 * Value: Address to store the value at
2248 * Returns:
2249 * D3D_OK on success, for details see IWineD3DDevice::GetRenderState
2250 * DDERR_INVALIDPARAMS if Value == NULL
2252 *****************************************************************************/
2253 static HRESULT WINAPI
2254 IDirect3DDeviceImpl_7_GetRenderState(IDirect3DDevice7 *iface,
2255 D3DRENDERSTATETYPE RenderStateType,
2256 DWORD *Value)
2258 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
2259 HRESULT hr;
2260 TRACE("(%p)->(%08x,%p): Relay\n", This, RenderStateType, Value);
2262 if(!Value)
2263 return DDERR_INVALIDPARAMS;
2265 EnterCriticalSection(&ddraw_cs);
2266 switch(RenderStateType)
2268 case D3DRENDERSTATE_TEXTUREHANDLE:
2270 /* This state is wrapped to SetTexture in SetRenderState, so
2271 * it has to be wrapped to GetTexture here
2273 IWineD3DBaseTexture *tex = NULL;
2274 *Value = 0;
2276 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice,
2278 &tex);
2280 if(hr == WINED3D_OK && tex)
2282 IDirectDrawSurface7 *parent = NULL;
2283 hr = IWineD3DBaseTexture_GetParent(tex,
2284 (IUnknown **) &parent);
2285 if(parent)
2287 /* The parent of the texture is the IDirectDrawSurface7 interface
2288 * of the ddraw surface
2290 IDirectDrawSurfaceImpl *texImpl = ICOM_OBJECT(IDirectDrawSurfaceImpl,
2291 IDirectDrawSurface7,
2292 parent);
2293 *Value = texImpl->Handle;
2294 IDirectDrawSurface7_Release(parent);
2296 IWineD3DBaseTexture_Release(tex);
2298 break;
2301 case D3DRENDERSTATE_TEXTUREMAG:
2303 WINED3DTEXTUREFILTERTYPE tex_mag;
2305 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2306 0, WINED3DSAMP_MAGFILTER,
2307 &tex_mag);
2309 switch (tex_mag)
2311 case WINED3DTEXF_POINT:
2312 *Value = D3DFILTER_NEAREST;
2313 break;
2314 case WINED3DTEXF_LINEAR:
2315 *Value = D3DFILTER_LINEAR;
2316 break;
2317 default:
2318 ERR("Unhandled texture mag %d !\n",tex_mag);
2319 *Value = 0;
2321 break;
2324 case D3DRENDERSTATE_TEXTUREMIN:
2326 WINED3DTEXTUREFILTERTYPE tex_min;
2328 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2329 0, WINED3DSAMP_MINFILTER,
2330 &tex_min);
2332 switch (tex_min)
2334 case WINED3DTEXF_POINT:
2335 *Value = D3DFILTER_NEAREST;
2336 break;
2337 case WINED3DTEXF_LINEAR:
2338 *Value = D3DFILTER_LINEAR;
2339 break;
2340 default:
2341 ERR("Unhandled texture mag %d !\n",tex_min);
2342 *Value = 0;
2344 break;
2347 case D3DRENDERSTATE_TEXTUREADDRESS:
2348 case D3DRENDERSTATE_TEXTUREADDRESSU:
2349 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2350 0, WINED3DSAMP_ADDRESSU,
2351 Value);
2352 break;
2353 case D3DRENDERSTATE_TEXTUREADDRESSV:
2354 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2355 0, WINED3DSAMP_ADDRESSV,
2356 Value);
2357 break;
2359 default:
2360 /* FIXME: Unhandled: D3DRENDERSTATE_STIPPLEPATTERN00 - 31 */
2361 hr = IWineD3DDevice_GetRenderState(This->wineD3DDevice,
2362 RenderStateType,
2363 Value);
2365 LeaveCriticalSection(&ddraw_cs);
2366 return hr;
2369 static HRESULT WINAPI
2370 Thunk_IDirect3DDeviceImpl_3_GetRenderState(IDirect3DDevice3 *iface,
2371 D3DRENDERSTATETYPE dwRenderStateType,
2372 DWORD *lpdwRenderState)
2374 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2375 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, dwRenderStateType, lpdwRenderState);
2376 return IDirect3DDevice7_GetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
2377 dwRenderStateType,
2378 lpdwRenderState);
2381 static HRESULT WINAPI
2382 IDirect3DDeviceImpl_2_GetRenderState(IDirect3DDevice2 *iface,
2383 D3DRENDERSTATETYPE dwRenderStateType,
2384 DWORD *lpdwRenderState)
2386 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2387 TRACE("(%p)->(%08x,%p): Relay\n", This, dwRenderStateType, lpdwRenderState);
2389 /* D3DRENDERSTATE_TEXTUREMAPBLEND is mapped to texture state stages in SetRenderState; reverse
2390 the mapping to get the value; other states relayed to IDirect3DDevice7::GetRenderState */
2391 switch(dwRenderStateType)
2393 case D3DRENDERSTATE_TEXTUREMAPBLEND:
2395 DWORD colorop, colorarg1, colorarg2;
2396 DWORD alphaop, alphaarg1, alphaarg2;
2398 EnterCriticalSection(&ddraw_cs);
2400 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, &colorop);
2401 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, &colorarg1);
2402 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, &colorarg2);
2403 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, &alphaop);
2404 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, &alphaarg1);
2405 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, &alphaarg2);
2407 if (colorop == WINED3DTOP_SELECTARG1 && colorarg1 == WINED3DTA_TEXTURE &&
2408 alphaop == WINED3DTOP_SELECTARG1 && alphaarg1 == WINED3DTA_TEXTURE)
2410 *lpdwRenderState = D3DTBLEND_DECAL;
2412 else if (colorop == WINED3DTOP_SELECTARG1 && colorarg1 == WINED3DTA_TEXTURE &&
2413 alphaop == WINED3DTOP_MODULATE && alphaarg1 == WINED3DTA_TEXTURE && alphaarg2 == WINED3DTA_CURRENT)
2415 *lpdwRenderState = D3DTBLEND_DECALALPHA;
2417 else if (colorop == WINED3DTOP_MODULATE && colorarg1 == WINED3DTA_TEXTURE && colorarg2 == WINED3DTA_CURRENT &&
2418 alphaop == WINED3DTOP_MODULATE && alphaarg1 == WINED3DTA_TEXTURE && alphaarg2 == WINED3DTA_CURRENT)
2420 *lpdwRenderState = D3DTBLEND_MODULATEALPHA;
2422 else
2424 HRESULT hr;
2425 BOOL tex_alpha = FALSE;
2426 IWineD3DBaseTexture *tex = NULL;
2427 WINED3DSURFACE_DESC desc;
2428 WINED3DFORMAT fmt;
2429 DDPIXELFORMAT ddfmt;
2431 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice,
2433 &tex);
2435 if(hr == WINED3D_OK && tex)
2437 memset(&desc, 0, sizeof(desc));
2438 desc.Format = &fmt;
2439 hr = IWineD3DTexture_GetLevelDesc((IWineD3DTexture*) tex, 0, &desc);
2440 if (SUCCEEDED(hr))
2442 ddfmt.dwSize = sizeof(ddfmt);
2443 PixelFormat_WineD3DtoDD(&ddfmt, fmt);
2444 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
2447 IWineD3DBaseTexture_Release(tex);
2450 if (!(colorop == WINED3DTOP_MODULATE && colorarg1 == WINED3DTA_TEXTURE && colorarg2 == WINED3DTA_CURRENT &&
2451 alphaop == WINED3DTOP_SELECTARG1 && alphaarg1 == (tex_alpha ? WINED3DTA_TEXTURE : WINED3DTA_CURRENT)))
2453 ERR("Unexpected texture stage state setup, returning D3DTBLEND_MODULATE - likely erroneous\n");
2456 *lpdwRenderState = D3DTBLEND_MODULATE;
2459 LeaveCriticalSection(&ddraw_cs);
2461 return D3D_OK;
2464 default:
2465 return IDirect3DDevice7_GetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
2466 dwRenderStateType,
2467 lpdwRenderState);
2471 /*****************************************************************************
2472 * IDirect3DDevice7::SetRenderState
2474 * Sets a render state. The possible render states are defined in
2475 * include/d3dtypes.h
2477 * Version 2, 3 and 7
2479 * Params:
2480 * RenderStateType: State to set
2481 * Value: Value to assign to that state
2483 * Returns:
2484 * D3D_OK on success,
2485 * for details see IWineD3DDevice::SetRenderState
2487 *****************************************************************************/
2488 static HRESULT WINAPI
2489 IDirect3DDeviceImpl_7_SetRenderState(IDirect3DDevice7 *iface,
2490 D3DRENDERSTATETYPE RenderStateType,
2491 DWORD Value)
2493 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
2494 HRESULT hr;
2495 TRACE("(%p)->(%08x,%d): Relay\n", This, RenderStateType, Value);
2497 EnterCriticalSection(&ddraw_cs);
2498 /* Some render states need special care */
2499 switch(RenderStateType)
2501 case D3DRENDERSTATE_TEXTUREHANDLE:
2503 if(Value == 0)
2505 hr = IWineD3DDevice_SetTexture(This->wineD3DDevice,
2507 NULL);
2508 break;
2511 if(Value > This->numHandles)
2513 FIXME("Specified handle %d out of range\n", Value);
2514 hr = DDERR_INVALIDPARAMS;
2515 break;
2517 if(This->Handles[Value - 1].type != DDrawHandle_Texture)
2519 FIXME("Handle %d isn't a texture handle\n", Value);
2520 hr = DDERR_INVALIDPARAMS;
2521 break;
2523 else
2525 IDirectDrawSurfaceImpl *surf = (IDirectDrawSurfaceImpl *) This->Handles[Value - 1].ptr;
2526 hr = IWineD3DDevice_SetTexture(This->wineD3DDevice,
2528 surf->wineD3DTexture);
2529 break;
2533 case D3DRENDERSTATE_TEXTUREMAG:
2535 WINED3DTEXTUREFILTERTYPE tex_mag = WINED3DTEXF_NONE;
2537 switch ((D3DTEXTUREFILTER) Value)
2539 case D3DFILTER_NEAREST:
2540 case D3DFILTER_LINEARMIPNEAREST:
2541 tex_mag = WINED3DTEXF_POINT;
2542 break;
2543 case D3DFILTER_LINEAR:
2544 case D3DFILTER_LINEARMIPLINEAR:
2545 tex_mag = WINED3DTEXF_LINEAR;
2546 break;
2547 default:
2548 ERR("Unhandled texture mag %d !\n",Value);
2551 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2552 0, WINED3DSAMP_MAGFILTER,
2553 tex_mag);
2554 break;
2557 case D3DRENDERSTATE_TEXTUREMIN:
2559 WINED3DTEXTUREFILTERTYPE tex_min = WINED3DTEXF_NONE;
2560 WINED3DTEXTUREFILTERTYPE tex_mip = WINED3DTEXF_NONE;
2562 switch ((D3DTEXTUREFILTER) Value)
2564 case D3DFILTER_NEAREST:
2565 tex_min = WINED3DTEXF_POINT;
2566 break;
2567 case D3DFILTER_LINEAR:
2568 tex_min = WINED3DTEXF_LINEAR;
2569 break;
2570 case D3DFILTER_MIPNEAREST:
2571 tex_min = WINED3DTEXF_NONE;
2572 tex_mip = WINED3DTEXF_POINT;
2573 break;
2574 case D3DFILTER_MIPLINEAR:
2575 tex_min = WINED3DTEXF_NONE;
2576 tex_mip = WINED3DTEXF_LINEAR;
2577 break;
2578 case D3DFILTER_LINEARMIPNEAREST:
2579 tex_min = WINED3DTEXF_POINT;
2580 tex_mip = WINED3DTEXF_LINEAR;
2581 break;
2582 case D3DFILTER_LINEARMIPLINEAR:
2583 tex_min = WINED3DTEXF_LINEAR;
2584 tex_mip = WINED3DTEXF_LINEAR;
2585 break;
2587 default:
2588 ERR("Unhandled texture min %d !\n",Value);
2591 IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2592 0, WINED3DSAMP_MIPFILTER,
2593 tex_mip);
2594 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2595 0, WINED3DSAMP_MINFILTER,
2596 tex_min);
2597 break;
2600 case D3DRENDERSTATE_TEXTUREADDRESS:
2601 IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2602 0, WINED3DSAMP_ADDRESSV,
2603 Value);
2604 /* Drop through */
2605 case D3DRENDERSTATE_TEXTUREADDRESSU:
2606 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2607 0, WINED3DSAMP_ADDRESSU,
2608 Value);
2609 break;
2610 case D3DRENDERSTATE_TEXTUREADDRESSV:
2611 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2612 0, WINED3DSAMP_ADDRESSV,
2613 Value);
2614 break;
2616 default:
2618 /* FIXME: Unhandled: D3DRENDERSTATE_STIPPLEPATTERN00 - 31 */
2620 hr = IWineD3DDevice_SetRenderState(This->wineD3DDevice,
2621 RenderStateType,
2622 Value);
2623 break;
2625 LeaveCriticalSection(&ddraw_cs);
2626 return hr;
2629 static HRESULT WINAPI
2630 Thunk_IDirect3DDeviceImpl_3_SetRenderState(IDirect3DDevice3 *iface,
2631 D3DRENDERSTATETYPE RenderStateType,
2632 DWORD Value)
2634 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2635 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, RenderStateType, Value);
2636 return IDirect3DDevice7_SetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
2637 RenderStateType,
2638 Value);
2641 static HRESULT WINAPI
2642 IDirect3DDeviceImpl_2_SetRenderState(IDirect3DDevice2 *iface,
2643 D3DRENDERSTATETYPE RenderStateType,
2644 DWORD Value)
2646 /* Note about D3DRENDERSTATE_TEXTUREMAPBLEND implementation: most of values
2647 for this state can be directly mapped to texture stage colorop and alphaop, but
2648 D3DTBLEND_MODULATE is tricky: it uses alpha from texture when available and alpha
2649 from diffuse otherwise. So changing the texture is monitored here to modify
2650 alphaarg when needed.
2652 Other states are relayed to IDirect3DDevice7
2654 Aliens vs Predator 1 depends on accurate D3DTBLEND_MODULATE emulation */
2656 HRESULT hr;
2657 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2658 TRACE("(%p)->(%08x,%d): Relay\n", This, RenderStateType, Value);
2660 switch(RenderStateType)
2662 case D3DRENDERSTATE_TEXTUREMAPBLEND:
2664 EnterCriticalSection(&ddraw_cs);
2666 switch ( (D3DTEXTUREBLEND) Value)
2668 case D3DTBLEND_MODULATE:
2670 BOOL tex_alpha = FALSE;
2671 IWineD3DBaseTexture *tex = NULL;
2672 WINED3DSURFACE_DESC desc;
2673 WINED3DFORMAT fmt;
2674 DDPIXELFORMAT ddfmt;
2676 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice,
2678 &tex);
2680 if(hr == WINED3D_OK && tex)
2682 memset(&desc, 0, sizeof(desc));
2683 desc.Format = &fmt;
2684 hr = IWineD3DTexture_GetLevelDesc((IWineD3DTexture*) tex, 0, &desc);
2685 if (SUCCEEDED(hr))
2687 ddfmt.dwSize = sizeof(ddfmt);
2688 PixelFormat_WineD3DtoDD(&ddfmt, fmt);
2689 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
2692 IWineD3DBaseTexture_Release(tex);
2695 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG1);
2696 if (tex_alpha)
2698 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2700 else
2702 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_CURRENT);
2705 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2706 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2707 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_MODULATE);
2709 break;
2712 case D3DTBLEND_MODULATEALPHA:
2713 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2714 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2715 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2716 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
2717 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_MODULATE);
2718 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_MODULATE);
2719 break;
2721 case D3DTBLEND_DECAL:
2722 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2723 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2724 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_SELECTARG1);
2725 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG1);
2726 break;
2728 case D3DTBLEND_DECALALPHA:
2729 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2730 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2731 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
2732 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_SELECTARG1);
2733 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_MODULATE);
2734 break;
2736 default:
2737 ERR("Unhandled texture environment %d !\n",Value);
2740 LeaveCriticalSection(&ddraw_cs);
2742 hr = D3D_OK;
2743 break;
2746 case D3DRENDERSTATE_TEXTUREHANDLE:
2748 DWORD texmapblend;
2750 IDirect3DDevice2_GetRenderState(iface, D3DRENDERSTATE_TEXTUREMAPBLEND, &texmapblend);
2752 hr = IDirect3DDevice7_SetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
2753 D3DRENDERSTATE_TEXTUREHANDLE,
2754 Value);
2756 if (texmapblend == D3DTBLEND_MODULATE)
2758 BOOL tex_alpha = FALSE;
2759 IWineD3DBaseTexture *tex = NULL;
2760 WINED3DSURFACE_DESC desc;
2761 WINED3DFORMAT fmt;
2762 DDPIXELFORMAT ddfmt;
2764 EnterCriticalSection(&ddraw_cs);
2766 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice,
2768 &tex);
2770 if(hr == WINED3D_OK && tex)
2772 memset(&desc, 0, sizeof(desc));
2773 desc.Format = &fmt;
2774 hr = IWineD3DTexture_GetLevelDesc((IWineD3DTexture*) tex, 0, &desc);
2775 if (SUCCEEDED(hr))
2777 ddfmt.dwSize = sizeof(ddfmt);
2778 PixelFormat_WineD3DtoDD(&ddfmt, fmt);
2779 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
2782 IWineD3DBaseTexture_Release(tex);
2785 /* alphaop is WINED3DTOP_SELECTARG1 if it's D3DTBLEND_MODULATE, so only modify alphaarg1 */
2786 if (tex_alpha)
2788 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2790 else
2792 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_CURRENT);
2795 LeaveCriticalSection(&ddraw_cs);
2798 break;
2801 default:
2802 hr = IDirect3DDevice7_SetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
2803 RenderStateType,
2804 Value);
2805 break;
2808 return hr;
2811 /*****************************************************************************
2812 * Direct3DDevice3::SetLightState
2814 * Sets a light state for Direct3DDevice3 and Direct3DDevice2. The
2815 * light states are forwarded to Direct3DDevice7 render states
2817 * Version 2 and 3
2819 * Params:
2820 * LightStateType: The light state to change
2821 * Value: The value to assign to that light state
2823 * Returns:
2824 * D3D_OK on success
2825 * DDERR_INVALIDPARAMS if the parameters were incorrect
2826 * Also check IDirect3DDevice7::SetRenderState
2828 *****************************************************************************/
2829 static HRESULT WINAPI
2830 IDirect3DDeviceImpl_3_SetLightState(IDirect3DDevice3 *iface,
2831 D3DLIGHTSTATETYPE LightStateType,
2832 DWORD Value)
2834 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2835 HRESULT hr;
2837 TRACE("(%p)->(%08x,%08x)\n", This, LightStateType, Value);
2839 if (!LightStateType && (LightStateType > D3DLIGHTSTATE_COLORVERTEX))
2841 TRACE("Unexpected Light State Type\n");
2842 return DDERR_INVALIDPARAMS;
2845 EnterCriticalSection(&ddraw_cs);
2846 if (LightStateType == D3DLIGHTSTATE_MATERIAL /* 1 */)
2848 IDirect3DMaterialImpl *mat;
2850 if(Value == 0) mat = NULL;
2851 else if(Value > This->numHandles)
2853 ERR("Material handle out of range(%d)\n", Value);
2854 LeaveCriticalSection(&ddraw_cs);
2855 return DDERR_INVALIDPARAMS;
2857 else if(This->Handles[Value - 1].type != DDrawHandle_Material)
2859 ERR("Invalid handle %d\n", Value);
2860 LeaveCriticalSection(&ddraw_cs);
2861 return DDERR_INVALIDPARAMS;
2863 else
2865 mat = (IDirect3DMaterialImpl *) This->Handles[Value - 1].ptr;
2868 if (mat != NULL)
2870 TRACE(" activating material %p.\n", mat);
2871 mat->activate(mat);
2873 else
2875 FIXME(" D3DLIGHTSTATE_MATERIAL called with NULL material !!!\n");
2877 This->material = Value;
2879 else if (LightStateType == D3DLIGHTSTATE_COLORMODEL /* 3 */)
2881 switch (Value)
2883 case D3DCOLOR_MONO:
2884 ERR("DDCOLOR_MONO should not happen!\n");
2885 break;
2886 case D3DCOLOR_RGB:
2887 /* We are already in this mode */
2888 TRACE("Setting color model to RGB (no-op).\n");
2889 break;
2890 default:
2891 ERR("Unknown color model!\n");
2892 LeaveCriticalSection(&ddraw_cs);
2893 return DDERR_INVALIDPARAMS;
2896 else
2898 D3DRENDERSTATETYPE rs;
2899 switch (LightStateType)
2901 case D3DLIGHTSTATE_AMBIENT: /* 2 */
2902 rs = D3DRENDERSTATE_AMBIENT;
2903 break;
2904 case D3DLIGHTSTATE_FOGMODE: /* 4 */
2905 rs = D3DRENDERSTATE_FOGVERTEXMODE;
2906 break;
2907 case D3DLIGHTSTATE_FOGSTART: /* 5 */
2908 rs = D3DRENDERSTATE_FOGSTART;
2909 break;
2910 case D3DLIGHTSTATE_FOGEND: /* 6 */
2911 rs = D3DRENDERSTATE_FOGEND;
2912 break;
2913 case D3DLIGHTSTATE_FOGDENSITY: /* 7 */
2914 rs = D3DRENDERSTATE_FOGDENSITY;
2915 break;
2916 case D3DLIGHTSTATE_COLORVERTEX: /* 8 */
2917 rs = D3DRENDERSTATE_COLORVERTEX;
2918 break;
2919 default:
2920 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType);
2921 LeaveCriticalSection(&ddraw_cs);
2922 return DDERR_INVALIDPARAMS;
2925 hr = IDirect3DDevice7_SetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
2927 Value);
2928 LeaveCriticalSection(&ddraw_cs);
2929 return hr;
2932 LeaveCriticalSection(&ddraw_cs);
2933 return D3D_OK;
2936 static HRESULT WINAPI
2937 Thunk_IDirect3DDeviceImpl_2_SetLightState(IDirect3DDevice2 *iface,
2938 D3DLIGHTSTATETYPE LightStateType,
2939 DWORD Value)
2941 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2942 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x) thunking to IDirect3DDevice3 interface.\n", This, LightStateType, Value);
2943 return IDirect3DDevice3_SetLightState(ICOM_INTERFACE(This, IDirect3DDevice3),
2944 LightStateType,
2945 Value);
2948 /*****************************************************************************
2949 * IDirect3DDevice3::GetLightState
2951 * Returns the current setting of a light state. The state is read from
2952 * the Direct3DDevice7 render state.
2954 * Version 2 and 3
2956 * Params:
2957 * LightStateType: The light state to return
2958 * Value: The address to store the light state setting at
2960 * Returns:
2961 * D3D_OK on success
2962 * DDDERR_INVALIDPARAMS if the parameters were incorrect
2963 * Also see IDirect3DDevice7::GetRenderState
2965 *****************************************************************************/
2966 static HRESULT WINAPI
2967 IDirect3DDeviceImpl_3_GetLightState(IDirect3DDevice3 *iface,
2968 D3DLIGHTSTATETYPE LightStateType,
2969 DWORD *Value)
2971 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2972 HRESULT hr;
2974 TRACE("(%p)->(%08x,%p)\n", This, LightStateType, Value);
2976 if (!LightStateType && (LightStateType > D3DLIGHTSTATE_COLORVERTEX))
2978 TRACE("Unexpected Light State Type\n");
2979 return DDERR_INVALIDPARAMS;
2982 if(!Value)
2983 return DDERR_INVALIDPARAMS;
2985 EnterCriticalSection(&ddraw_cs);
2986 if (LightStateType == D3DLIGHTSTATE_MATERIAL /* 1 */)
2988 *Value = This->material;
2990 else if (LightStateType == D3DLIGHTSTATE_COLORMODEL /* 3 */)
2992 *Value = D3DCOLOR_RGB;
2994 else
2996 D3DRENDERSTATETYPE rs;
2997 switch (LightStateType)
2999 case D3DLIGHTSTATE_AMBIENT: /* 2 */
3000 rs = D3DRENDERSTATE_AMBIENT;
3001 break;
3002 case D3DLIGHTSTATE_FOGMODE: /* 4 */
3003 rs = D3DRENDERSTATE_FOGVERTEXMODE;
3004 break;
3005 case D3DLIGHTSTATE_FOGSTART: /* 5 */
3006 rs = D3DRENDERSTATE_FOGSTART;
3007 break;
3008 case D3DLIGHTSTATE_FOGEND: /* 6 */
3009 rs = D3DRENDERSTATE_FOGEND;
3010 break;
3011 case D3DLIGHTSTATE_FOGDENSITY: /* 7 */
3012 rs = D3DRENDERSTATE_FOGDENSITY;
3013 break;
3014 case D3DLIGHTSTATE_COLORVERTEX: /* 8 */
3015 rs = D3DRENDERSTATE_COLORVERTEX;
3016 break;
3017 default:
3018 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType);
3019 LeaveCriticalSection(&ddraw_cs);
3020 return DDERR_INVALIDPARAMS;
3023 hr = IDirect3DDevice7_GetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
3025 Value);
3026 LeaveCriticalSection(&ddraw_cs);
3027 return hr;
3030 LeaveCriticalSection(&ddraw_cs);
3031 return D3D_OK;
3034 static HRESULT WINAPI
3035 Thunk_IDirect3DDeviceImpl_2_GetLightState(IDirect3DDevice2 *iface,
3036 D3DLIGHTSTATETYPE LightStateType,
3037 DWORD *Value)
3039 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3040 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice3 interface.\n", This, LightStateType, Value);
3041 return IDirect3DDevice3_GetLightState(ICOM_INTERFACE(This, IDirect3DDevice3),
3042 LightStateType,
3043 Value);
3046 /*****************************************************************************
3047 * IDirect3DDevice7::SetTransform
3049 * Assigns a D3DMATRIX to a transform type. The transform types are defined
3050 * in include/d3dtypes.h.
3051 * The D3DTRANSFORMSTATE_WORLD (=1) is translated to D3DTS_WORLDMATRIX(0)
3052 * (=255) for wined3d, because the 1 transform state was removed in d3d8
3053 * and WineD3D already understands the replacement D3DTS_WORLDMATRIX(0)
3055 * Version 2, 3 and 7
3057 * Params:
3058 * TransformStateType: transform state to set
3059 * Matrix: Matrix to assign to the state
3061 * Returns:
3062 * D3D_OK on success
3063 * DDERR_INVALIDPARAMS if Matrix == NULL
3064 * For details see IWineD3DDevice::SetTransform
3066 *****************************************************************************/
3067 static HRESULT WINAPI
3068 IDirect3DDeviceImpl_7_SetTransform(IDirect3DDevice7 *iface,
3069 D3DTRANSFORMSTATETYPE TransformStateType,
3070 D3DMATRIX *Matrix)
3072 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3073 D3DTRANSFORMSTATETYPE type = TransformStateType;
3074 HRESULT hr;
3075 TRACE("(%p)->(%08x,%p): Relay\n", This, TransformStateType, Matrix);
3077 switch(TransformStateType)
3079 case D3DTRANSFORMSTATE_WORLD : type = WINED3DTS_WORLDMATRIX(0); break;
3080 case D3DTRANSFORMSTATE_WORLD1: type = WINED3DTS_WORLDMATRIX(1); break;
3081 case D3DTRANSFORMSTATE_WORLD2: type = WINED3DTS_WORLDMATRIX(2); break;
3082 case D3DTRANSFORMSTATE_WORLD3: type = WINED3DTS_WORLDMATRIX(3); break;
3083 default: type = TransformStateType;
3086 if(!Matrix)
3087 return DDERR_INVALIDPARAMS;
3089 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3090 EnterCriticalSection(&ddraw_cs);
3091 hr = IWineD3DDevice_SetTransform(This->wineD3DDevice,
3092 type,
3093 (WINED3DMATRIX*) Matrix);
3094 LeaveCriticalSection(&ddraw_cs);
3095 return hr;
3098 static HRESULT WINAPI
3099 Thunk_IDirect3DDeviceImpl_3_SetTransform(IDirect3DDevice3 *iface,
3100 D3DTRANSFORMSTATETYPE TransformStateType,
3101 D3DMATRIX *D3DMatrix)
3103 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3104 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3105 return IDirect3DDevice7_SetTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
3106 TransformStateType,
3107 D3DMatrix);
3110 static HRESULT WINAPI
3111 Thunk_IDirect3DDeviceImpl_2_SetTransform(IDirect3DDevice2 *iface,
3112 D3DTRANSFORMSTATETYPE TransformStateType,
3113 D3DMATRIX *D3DMatrix)
3115 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3116 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3117 return IDirect3DDevice7_SetTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
3118 TransformStateType,
3119 D3DMatrix);
3122 /*****************************************************************************
3123 * IDirect3DDevice7::GetTransform
3125 * Returns the matrix assigned to a transform state
3126 * D3DTRANSFORMSTATE_WORLD is translated to D3DTS_WORLDMATRIX(0), see
3127 * SetTransform
3129 * Params:
3130 * TransformStateType: State to read the matrix from
3131 * Matrix: Address to store the matrix at
3133 * Returns:
3134 * D3D_OK on success
3135 * DDERR_INVALIDPARAMS if Matrix == NULL
3136 * For details, see IWineD3DDevice::GetTransform
3138 *****************************************************************************/
3139 static HRESULT WINAPI
3140 IDirect3DDeviceImpl_7_GetTransform(IDirect3DDevice7 *iface,
3141 D3DTRANSFORMSTATETYPE TransformStateType,
3142 D3DMATRIX *Matrix)
3144 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3145 D3DTRANSFORMSTATETYPE type = TransformStateType;
3146 HRESULT hr;
3147 TRACE("(%p)->(%08x,%p): Relay\n", This, TransformStateType, Matrix);
3149 switch(TransformStateType)
3151 case D3DTRANSFORMSTATE_WORLD : type = WINED3DTS_WORLDMATRIX(0); break;
3152 case D3DTRANSFORMSTATE_WORLD1: type = WINED3DTS_WORLDMATRIX(1); break;
3153 case D3DTRANSFORMSTATE_WORLD2: type = WINED3DTS_WORLDMATRIX(2); break;
3154 case D3DTRANSFORMSTATE_WORLD3: type = WINED3DTS_WORLDMATRIX(3); break;
3155 default: type = TransformStateType;
3158 if(!Matrix)
3159 return DDERR_INVALIDPARAMS;
3161 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3162 EnterCriticalSection(&ddraw_cs);
3163 hr = IWineD3DDevice_GetTransform(This->wineD3DDevice, type, (WINED3DMATRIX*) Matrix);
3164 LeaveCriticalSection(&ddraw_cs);
3165 return hr;
3168 static HRESULT WINAPI
3169 Thunk_IDirect3DDeviceImpl_3_GetTransform(IDirect3DDevice3 *iface,
3170 D3DTRANSFORMSTATETYPE TransformStateType,
3171 D3DMATRIX *D3DMatrix)
3173 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3174 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3175 return IDirect3DDevice7_GetTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
3176 TransformStateType,
3177 D3DMatrix);
3180 static HRESULT WINAPI
3181 Thunk_IDirect3DDeviceImpl_2_GetTransform(IDirect3DDevice2 *iface,
3182 D3DTRANSFORMSTATETYPE TransformStateType,
3183 D3DMATRIX *D3DMatrix)
3185 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3186 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3187 return IDirect3DDevice7_GetTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
3188 TransformStateType,
3189 D3DMatrix);
3192 /*****************************************************************************
3193 * IDirect3DDevice7::MultiplyTransform
3195 * Multiplies the already-set transform matrix of a transform state
3196 * with another matrix. For the world matrix, see SetTransform
3198 * Version 2, 3 and 7
3200 * Params:
3201 * TransformStateType: Transform state to multiply
3202 * D3DMatrix Matrix to multiply with.
3204 * Returns
3205 * D3D_OK on success
3206 * DDERR_INVALIDPARAMS if D3DMatrix is NULL
3207 * For details, see IWineD3DDevice::MultiplyTransform
3209 *****************************************************************************/
3210 static HRESULT WINAPI
3211 IDirect3DDeviceImpl_7_MultiplyTransform(IDirect3DDevice7 *iface,
3212 D3DTRANSFORMSTATETYPE TransformStateType,
3213 D3DMATRIX *D3DMatrix)
3215 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3216 HRESULT hr;
3217 D3DTRANSFORMSTATETYPE type;
3218 TRACE("(%p)->(%08x,%p): Relay\n", This, TransformStateType, D3DMatrix);
3220 switch(TransformStateType)
3222 case D3DTRANSFORMSTATE_WORLD : type = WINED3DTS_WORLDMATRIX(0); break;
3223 case D3DTRANSFORMSTATE_WORLD1: type = WINED3DTS_WORLDMATRIX(1); break;
3224 case D3DTRANSFORMSTATE_WORLD2: type = WINED3DTS_WORLDMATRIX(2); break;
3225 case D3DTRANSFORMSTATE_WORLD3: type = WINED3DTS_WORLDMATRIX(3); break;
3226 default: type = TransformStateType;
3229 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3230 EnterCriticalSection(&ddraw_cs);
3231 hr = IWineD3DDevice_MultiplyTransform(This->wineD3DDevice,
3232 type,
3233 (WINED3DMATRIX*) D3DMatrix);
3234 LeaveCriticalSection(&ddraw_cs);
3235 return hr;
3238 static HRESULT WINAPI
3239 Thunk_IDirect3DDeviceImpl_3_MultiplyTransform(IDirect3DDevice3 *iface,
3240 D3DTRANSFORMSTATETYPE TransformStateType,
3241 D3DMATRIX *D3DMatrix)
3243 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3244 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3245 return IDirect3DDevice7_MultiplyTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
3246 TransformStateType,
3247 D3DMatrix);
3250 static HRESULT WINAPI
3251 Thunk_IDirect3DDeviceImpl_2_MultiplyTransform(IDirect3DDevice2 *iface,
3252 D3DTRANSFORMSTATETYPE TransformStateType,
3253 D3DMATRIX *D3DMatrix)
3255 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3256 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3257 return IDirect3DDevice7_MultiplyTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
3258 TransformStateType,
3259 D3DMatrix);
3262 /*****************************************************************************
3263 * IDirect3DDevice7::DrawPrimitive
3265 * Draws primitives based on vertices in an application-provided pointer
3267 * Version 2, 3 and 7. The IDirect3DDevice2 thunk converts the fixed vertex type into
3268 * an FVF format for D3D7
3270 * Params:
3271 * PrimitiveType: The type of the primitives to draw
3272 * Vertex type: Flexible vertex format vertex description
3273 * Vertices: Pointer to the vertex array
3274 * VertexCount: The number of vertices to draw
3275 * Flags: As usual a few flags
3277 * Returns:
3278 * D3D_OK on success
3279 * DDERR_INVALIDPARAMS if Vertices is NULL
3280 * For details, see IWineD3DDevice::DrawPrimitiveUP
3282 *****************************************************************************/
3283 static HRESULT WINAPI
3284 IDirect3DDeviceImpl_7_DrawPrimitive(IDirect3DDevice7 *iface,
3285 D3DPRIMITIVETYPE PrimitiveType,
3286 DWORD VertexType,
3287 void *Vertices,
3288 DWORD VertexCount,
3289 DWORD Flags)
3291 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3292 UINT PrimitiveCount, stride;
3293 HRESULT hr;
3294 TRACE("(%p)->(%08x,%08x,%p,%08x,%08x): Relay!\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3296 if(!Vertices)
3297 return DDERR_INVALIDPARAMS;
3299 /* Get the vertex count */
3300 switch(PrimitiveType)
3302 case D3DPT_POINTLIST:
3303 PrimitiveCount = VertexCount;
3304 break;
3306 case D3DPT_LINELIST:
3307 PrimitiveCount = VertexCount / 2;
3308 break;
3310 case D3DPT_LINESTRIP:
3311 PrimitiveCount = VertexCount - 1;
3312 break;
3314 case D3DPT_TRIANGLELIST:
3315 PrimitiveCount = VertexCount / 3;
3316 break;
3318 case D3DPT_TRIANGLESTRIP:
3319 PrimitiveCount = VertexCount - 2;
3320 break;
3322 case D3DPT_TRIANGLEFAN:
3323 PrimitiveCount = VertexCount - 2;
3324 break;
3326 default:
3327 return DDERR_INVALIDPARAMS;
3330 /* Get the stride */
3331 stride = get_flexible_vertex_size(VertexType);
3333 /* Set the FVF */
3334 EnterCriticalSection(&ddraw_cs);
3335 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
3336 IDirectDrawImpl_FindDecl(This->ddraw, VertexType));
3337 if(hr != D3D_OK)
3339 LeaveCriticalSection(&ddraw_cs);
3340 return hr;
3343 /* This method translates to the user pointer draw of WineD3D */
3344 hr = IWineD3DDevice_DrawPrimitiveUP(This->wineD3DDevice,
3345 PrimitiveType,
3346 PrimitiveCount,
3347 Vertices,
3348 stride);
3349 LeaveCriticalSection(&ddraw_cs);
3350 return hr;
3353 static HRESULT WINAPI
3354 Thunk_IDirect3DDeviceImpl_3_DrawPrimitive(IDirect3DDevice3 *iface,
3355 D3DPRIMITIVETYPE PrimitiveType,
3356 DWORD VertexType,
3357 void *Vertices,
3358 DWORD VertexCount,
3359 DWORD Flags)
3361 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3362 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3363 return IDirect3DDevice7_DrawPrimitive(ICOM_INTERFACE(This, IDirect3DDevice7),
3364 PrimitiveType,
3365 VertexType,
3366 Vertices,
3367 VertexCount,
3368 Flags);
3371 static HRESULT WINAPI
3372 Thunk_IDirect3DDeviceImpl_2_DrawPrimitive(IDirect3DDevice2 *iface,
3373 D3DPRIMITIVETYPE PrimitiveType,
3374 D3DVERTEXTYPE VertexType,
3375 void *Vertices,
3376 DWORD VertexCount,
3377 DWORD Flags)
3379 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3380 DWORD FVF;
3381 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3383 switch(VertexType)
3385 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
3386 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
3387 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
3388 default:
3389 ERR("Unexpected vertex type %d\n", VertexType);
3390 return DDERR_INVALIDPARAMS; /* Should never happen */
3393 return IDirect3DDevice7_DrawPrimitive(ICOM_INTERFACE(This, IDirect3DDevice7),
3394 PrimitiveType,
3395 FVF,
3396 Vertices,
3397 VertexCount,
3398 Flags);
3401 /*****************************************************************************
3402 * IDirect3DDevice7::DrawIndexedPrimitive
3404 * Draws vertices from an application-provided pointer, based on the index
3405 * numbers in a WORD array.
3407 * Version 2, 3 and 7. The version 7 thunk translates the vertex type into
3408 * an FVF format for D3D7
3410 * Params:
3411 * PrimitiveType: The primitive type to draw
3412 * VertexType: The FVF vertex description
3413 * Vertices: Pointer to the vertex array
3414 * VertexCount: ?
3415 * Indices: Pointer to the index array
3416 * IndexCount: Number of indices = Number of vertices to draw
3417 * Flags: As usual, some flags
3419 * Returns:
3420 * D3D_OK on success
3421 * DDERR_INVALIDPARAMS if Vertices or Indices is NULL
3422 * For details, see IWineD3DDevice::DrawIndexedPrimitiveUP
3424 *****************************************************************************/
3425 static HRESULT WINAPI
3426 IDirect3DDeviceImpl_7_DrawIndexedPrimitive(IDirect3DDevice7 *iface,
3427 D3DPRIMITIVETYPE PrimitiveType,
3428 DWORD VertexType,
3429 void *Vertices,
3430 DWORD VertexCount,
3431 WORD *Indices,
3432 DWORD IndexCount,
3433 DWORD Flags)
3435 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3436 UINT PrimitiveCount = 0;
3437 HRESULT hr;
3438 TRACE("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x): Relay!\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3440 /* Get the primitive number */
3441 switch(PrimitiveType)
3443 case D3DPT_POINTLIST:
3444 PrimitiveCount = IndexCount;
3445 break;
3447 case D3DPT_LINELIST:
3448 PrimitiveCount = IndexCount / 2;
3449 break;
3451 case D3DPT_LINESTRIP:
3452 PrimitiveCount = IndexCount - 1;
3453 break;
3455 case D3DPT_TRIANGLELIST:
3456 PrimitiveCount = IndexCount / 3;
3457 break;
3459 case D3DPT_TRIANGLESTRIP:
3460 PrimitiveCount = IndexCount - 2;
3461 break;
3463 case D3DPT_TRIANGLEFAN:
3464 PrimitiveCount = IndexCount - 2;
3465 break;
3467 default:
3468 return DDERR_INVALIDPARAMS;
3471 /* Set the D3DDevice's FVF */
3472 EnterCriticalSection(&ddraw_cs);
3473 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
3474 IDirectDrawImpl_FindDecl(This->ddraw, VertexType));
3475 if(FAILED(hr))
3477 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr);
3478 LeaveCriticalSection(&ddraw_cs);
3479 return hr;
3482 hr = IWineD3DDevice_DrawIndexedPrimitiveUP(This->wineD3DDevice,
3483 PrimitiveType,
3484 0 /* MinVertexIndex */,
3485 VertexCount /* UINT NumVertexIndex */,
3486 PrimitiveCount,
3487 Indices,
3488 WINED3DFMT_INDEX16,
3489 Vertices,
3490 get_flexible_vertex_size(VertexType));
3491 LeaveCriticalSection(&ddraw_cs);
3492 return hr;
3495 static HRESULT WINAPI
3496 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive(IDirect3DDevice3 *iface,
3497 D3DPRIMITIVETYPE PrimitiveType,
3498 DWORD VertexType,
3499 void *Vertices,
3500 DWORD VertexCount,
3501 WORD *Indices,
3502 DWORD IndexCount,
3503 DWORD Flags)
3505 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3506 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3507 return IDirect3DDevice7_DrawIndexedPrimitive(ICOM_INTERFACE(This, IDirect3DDevice7),
3508 PrimitiveType,
3509 VertexType,
3510 Vertices,
3511 VertexCount,
3512 Indices,
3513 IndexCount,
3514 Flags);
3517 static HRESULT WINAPI
3518 Thunk_IDirect3DDeviceImpl_2_DrawIndexedPrimitive(IDirect3DDevice2 *iface,
3519 D3DPRIMITIVETYPE PrimitiveType,
3520 D3DVERTEXTYPE VertexType,
3521 void *Vertices,
3522 DWORD VertexCount,
3523 WORD *Indices,
3524 DWORD IndexCount,
3525 DWORD Flags)
3527 DWORD FVF;
3528 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3529 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3531 switch(VertexType)
3533 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
3534 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
3535 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
3536 default:
3537 ERR("Unexpected vertex type %d\n", VertexType);
3538 return DDERR_INVALIDPARAMS; /* Should never happen */
3541 return IDirect3DDevice7_DrawIndexedPrimitive(ICOM_INTERFACE(This, IDirect3DDevice7),
3542 PrimitiveType,
3543 FVF,
3544 Vertices,
3545 VertexCount,
3546 Indices,
3547 IndexCount,
3548 Flags);
3551 /*****************************************************************************
3552 * IDirect3DDevice7::SetClipStatus
3554 * Sets the clip status. This defines things as clipping conditions and
3555 * the extents of the clipping region.
3557 * Version 2, 3 and 7
3559 * Params:
3560 * ClipStatus:
3562 * Returns:
3563 * D3D_OK because it's a stub
3564 * (DDERR_INVALIDPARAMS if ClipStatus == NULL)
3566 *****************************************************************************/
3567 static HRESULT WINAPI
3568 IDirect3DDeviceImpl_7_SetClipStatus(IDirect3DDevice7 *iface,
3569 D3DCLIPSTATUS *ClipStatus)
3571 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3572 FIXME("(%p)->(%p): Stub!\n", This, ClipStatus);
3574 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them
3575 * Perhaps this needs a new data type and an additional IWineD3DDevice method
3577 /* return IWineD3DDevice_SetClipStatus(This->wineD3DDevice, ClipStatus);*/
3578 return D3D_OK;
3581 static HRESULT WINAPI
3582 Thunk_IDirect3DDeviceImpl_3_SetClipStatus(IDirect3DDevice3 *iface,
3583 D3DCLIPSTATUS *ClipStatus)
3585 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3586 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3587 return IDirect3DDevice7_SetClipStatus(ICOM_INTERFACE(This, IDirect3DDevice7),
3588 ClipStatus);
3591 static HRESULT WINAPI
3592 Thunk_IDirect3DDeviceImpl_2_SetClipStatus(IDirect3DDevice2 *iface,
3593 D3DCLIPSTATUS *ClipStatus)
3595 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3596 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3597 return IDirect3DDevice7_SetClipStatus(ICOM_INTERFACE(This, IDirect3DDevice7),
3598 ClipStatus);
3601 /*****************************************************************************
3602 * IDirect3DDevice7::GetClipStatus
3604 * Returns the clip status
3606 * Params:
3607 * ClipStatus: Address to write the clip status to
3609 * Returns:
3610 * D3D_OK because it's a stub
3612 *****************************************************************************/
3613 static HRESULT WINAPI
3614 IDirect3DDeviceImpl_7_GetClipStatus(IDirect3DDevice7 *iface,
3615 D3DCLIPSTATUS *ClipStatus)
3617 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3618 FIXME("(%p)->(%p): Stub!\n", This, ClipStatus);
3620 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them */
3621 /* return IWineD3DDevice_GetClipStatus(This->wineD3DDevice, ClipStatus);*/
3622 return D3D_OK;
3625 static HRESULT WINAPI
3626 Thunk_IDirect3DDeviceImpl_3_GetClipStatus(IDirect3DDevice3 *iface,
3627 D3DCLIPSTATUS *ClipStatus)
3629 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3630 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3631 return IDirect3DDevice7_GetClipStatus(ICOM_INTERFACE(This, IDirect3DDevice7),
3632 ClipStatus);
3635 static HRESULT WINAPI
3636 Thunk_IDirect3DDeviceImpl_2_GetClipStatus(IDirect3DDevice2 *iface,
3637 D3DCLIPSTATUS *ClipStatus)
3639 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3640 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3641 return IDirect3DDevice7_GetClipStatus(ICOM_INTERFACE(This, IDirect3DDevice7),
3642 ClipStatus);
3645 /*****************************************************************************
3646 * IDirect3DDevice::DrawPrimitiveStrided
3648 * Draws vertices described by a D3DDRAWPRIMITIVESTRIDEDDATA structure.
3650 * Version 3 and 7
3652 * Params:
3653 * PrimitiveType: The primitive type to draw
3654 * VertexType: The FVF description of the vertices to draw (for the stride??)
3655 * D3DDrawPrimStrideData: A D3DDRAWPRIMITIVESTRIDEDDATA structure describing
3656 * the vertex data locations
3657 * VertexCount: The number of vertices to draw
3658 * Flags: Some flags
3660 * Returns:
3661 * D3D_OK, because it's a stub
3662 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
3663 * (For details, see IWineD3DDevice::DrawPrimitiveStrided)
3665 *****************************************************************************/
3666 static HRESULT WINAPI
3667 IDirect3DDeviceImpl_7_DrawPrimitiveStrided(IDirect3DDevice7 *iface,
3668 D3DPRIMITIVETYPE PrimitiveType,
3669 DWORD VertexType,
3670 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3671 DWORD VertexCount,
3672 DWORD Flags)
3674 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3675 WineDirect3DVertexStridedData WineD3DStrided;
3676 int i;
3677 UINT PrimitiveCount;
3678 HRESULT hr;
3680 TRACE("(%p)->(%08x,%08x,%p,%08x,%08x): stub!\n", This, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
3682 memset(&WineD3DStrided, 0, sizeof(WineD3DStrided));
3683 /* Get the strided data right. the wined3d structure is a bit bigger
3684 * Watch out: The contents of the strided data are determined by the fvf,
3685 * not by the members set in D3DDrawPrimStrideData. So it's valid
3686 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
3687 * not set in the fvf.
3689 if(VertexType & D3DFVF_POSITION_MASK)
3691 WineD3DStrided.u.s.position.lpData = D3DDrawPrimStrideData->position.lpvData;
3692 WineD3DStrided.u.s.position.dwStride = D3DDrawPrimStrideData->position.dwStride;
3693 WineD3DStrided.u.s.position.dwType = WINED3DDECLTYPE_FLOAT3;
3694 if (VertexType & D3DFVF_XYZRHW)
3696 WineD3DStrided.u.s.position.dwType = WINED3DDECLTYPE_FLOAT4;
3697 WineD3DStrided.u.s.position_transformed = TRUE;
3698 } else
3699 WineD3DStrided.u.s.position_transformed = FALSE;
3702 if(VertexType & D3DFVF_NORMAL)
3704 WineD3DStrided.u.s.normal.lpData = D3DDrawPrimStrideData->normal.lpvData;
3705 WineD3DStrided.u.s.normal.dwStride = D3DDrawPrimStrideData->normal.dwStride;
3706 WineD3DStrided.u.s.normal.dwType = WINED3DDECLTYPE_FLOAT3;
3709 if(VertexType & D3DFVF_DIFFUSE)
3711 WineD3DStrided.u.s.diffuse.lpData = D3DDrawPrimStrideData->diffuse.lpvData;
3712 WineD3DStrided.u.s.diffuse.dwStride = D3DDrawPrimStrideData->diffuse.dwStride;
3713 WineD3DStrided.u.s.diffuse.dwType = WINED3DDECLTYPE_D3DCOLOR;
3716 if(VertexType & D3DFVF_SPECULAR)
3718 WineD3DStrided.u.s.specular.lpData = D3DDrawPrimStrideData->specular.lpvData;
3719 WineD3DStrided.u.s.specular.dwStride = D3DDrawPrimStrideData->specular.dwStride;
3720 WineD3DStrided.u.s.specular.dwType = WINED3DDECLTYPE_D3DCOLOR;
3723 for( i = 0; i < GET_TEXCOUNT_FROM_FVF(VertexType); i++)
3725 WineD3DStrided.u.s.texCoords[i].lpData = D3DDrawPrimStrideData->textureCoords[i].lpvData;
3726 WineD3DStrided.u.s.texCoords[i].dwStride = D3DDrawPrimStrideData->textureCoords[i].dwStride;
3727 switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i))
3729 case 1: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT1; break;
3730 case 2: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT2; break;
3731 case 3: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT3; break;
3732 case 4: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT4; break;
3733 default: ERR("Unexpected texture coordinate size %d\n",
3734 GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i));
3738 /* Get the primitive count */
3739 switch(PrimitiveType)
3741 case D3DPT_POINTLIST:
3742 PrimitiveCount = VertexCount;
3743 break;
3745 case D3DPT_LINELIST:
3746 PrimitiveCount = VertexCount / 2;
3747 break;
3749 case D3DPT_LINESTRIP:
3750 PrimitiveCount = VertexCount - 1;
3751 break;
3753 case D3DPT_TRIANGLELIST:
3754 PrimitiveCount = VertexCount / 3;
3755 break;
3757 case D3DPT_TRIANGLESTRIP:
3758 PrimitiveCount = VertexCount - 2;
3759 break;
3761 case D3DPT_TRIANGLEFAN:
3762 PrimitiveCount = VertexCount - 2;
3763 break;
3765 default: return DDERR_INVALIDPARAMS;
3768 /* WineD3D doesn't need the FVF here */
3769 EnterCriticalSection(&ddraw_cs);
3770 hr = IWineD3DDevice_DrawPrimitiveStrided(This->wineD3DDevice,
3771 PrimitiveType,
3772 PrimitiveCount,
3773 &WineD3DStrided);
3774 LeaveCriticalSection(&ddraw_cs);
3775 return hr;
3778 static HRESULT WINAPI
3779 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided(IDirect3DDevice3 *iface,
3780 D3DPRIMITIVETYPE PrimitiveType,
3781 DWORD VertexType,
3782 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3783 DWORD VertexCount,
3784 DWORD Flags)
3786 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3787 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
3788 return IDirect3DDevice7_DrawPrimitiveStrided(ICOM_INTERFACE(This, IDirect3DDevice7),
3789 PrimitiveType,
3790 VertexType,
3791 D3DDrawPrimStrideData,
3792 VertexCount,
3793 Flags);
3796 /*****************************************************************************
3797 * IDirect3DDevice7::DrawIndexedPrimitiveStrided
3799 * Draws primitives specified by strided data locations based on indices
3801 * Version 3 and 7
3803 * Params:
3804 * PrimitiveType:
3806 * Returns:
3807 * D3D_OK, because it's a stub
3808 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
3809 * (DDERR_INVALIDPARAMS if Indices is NULL)
3810 * (For more details, see IWineD3DDevice::DrawIndexedPrimitiveStrided)
3812 *****************************************************************************/
3813 static HRESULT WINAPI
3814 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(IDirect3DDevice7 *iface,
3815 D3DPRIMITIVETYPE PrimitiveType,
3816 DWORD VertexType,
3817 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3818 DWORD VertexCount,
3819 WORD *Indices,
3820 DWORD IndexCount,
3821 DWORD Flags)
3823 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3824 WineDirect3DVertexStridedData WineD3DStrided;
3825 int i;
3826 UINT PrimitiveCount;
3827 HRESULT hr;
3829 TRACE("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x)\n", This, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
3831 memset(&WineD3DStrided, 0, sizeof(WineD3DStrided));
3832 /* Get the strided data right. the wined3d structure is a bit bigger
3833 * Watch out: The contents of the strided data are determined by the fvf,
3834 * not by the members set in D3DDrawPrimStrideData. So it's valid
3835 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
3836 * not set in the fvf.
3838 if(VertexType & D3DFVF_POSITION_MASK)
3840 WineD3DStrided.u.s.position.lpData = D3DDrawPrimStrideData->position.lpvData;
3841 WineD3DStrided.u.s.position.dwStride = D3DDrawPrimStrideData->position.dwStride;
3842 WineD3DStrided.u.s.position.dwType = WINED3DDECLTYPE_FLOAT3;
3843 if (VertexType & D3DFVF_XYZRHW)
3845 WineD3DStrided.u.s.position.dwType = WINED3DDECLTYPE_FLOAT4;
3846 WineD3DStrided.u.s.position_transformed = TRUE;
3847 } else
3848 WineD3DStrided.u.s.position_transformed = FALSE;
3851 if(VertexType & D3DFVF_NORMAL)
3853 WineD3DStrided.u.s.normal.lpData = D3DDrawPrimStrideData->normal.lpvData;
3854 WineD3DStrided.u.s.normal.dwStride = D3DDrawPrimStrideData->normal.dwStride;
3855 WineD3DStrided.u.s.normal.dwType = WINED3DDECLTYPE_FLOAT3;
3858 if(VertexType & D3DFVF_DIFFUSE)
3860 WineD3DStrided.u.s.diffuse.lpData = D3DDrawPrimStrideData->diffuse.lpvData;
3861 WineD3DStrided.u.s.diffuse.dwStride = D3DDrawPrimStrideData->diffuse.dwStride;
3862 WineD3DStrided.u.s.diffuse.dwType = WINED3DDECLTYPE_D3DCOLOR;
3865 if(VertexType & D3DFVF_SPECULAR)
3867 WineD3DStrided.u.s.specular.lpData = D3DDrawPrimStrideData->specular.lpvData;
3868 WineD3DStrided.u.s.specular.dwStride = D3DDrawPrimStrideData->specular.dwStride;
3869 WineD3DStrided.u.s.specular.dwType = WINED3DDECLTYPE_D3DCOLOR;
3872 for( i = 0; i < GET_TEXCOUNT_FROM_FVF(VertexType); i++)
3874 WineD3DStrided.u.s.texCoords[i].lpData = D3DDrawPrimStrideData->textureCoords[i].lpvData;
3875 WineD3DStrided.u.s.texCoords[i].dwStride = D3DDrawPrimStrideData->textureCoords[i].dwStride;
3876 switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i))
3878 case 1: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT1; break;
3879 case 2: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT2; break;
3880 case 3: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT3; break;
3881 case 4: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT4; break;
3882 default: ERR("Unexpected texture coordinate size %d\n",
3883 GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i));
3887 /* Get the primitive count */
3888 switch(PrimitiveType)
3890 case D3DPT_POINTLIST:
3891 PrimitiveCount = IndexCount;
3892 break;
3894 case D3DPT_LINELIST:
3895 PrimitiveCount = IndexCount / 2;
3896 break;
3898 case D3DPT_LINESTRIP:
3899 PrimitiveCount = IndexCount - 1;
3900 break;
3902 case D3DPT_TRIANGLELIST:
3903 PrimitiveCount = IndexCount / 3;
3904 break;
3906 case D3DPT_TRIANGLESTRIP:
3907 PrimitiveCount = IndexCount - 2;
3908 break;
3910 case D3DPT_TRIANGLEFAN:
3911 PrimitiveCount = IndexCount - 2;
3912 break;
3914 default: return DDERR_INVALIDPARAMS;
3917 /* WineD3D doesn't need the FVF here */
3918 EnterCriticalSection(&ddraw_cs);
3919 hr = IWineD3DDevice_DrawIndexedPrimitiveStrided(This->wineD3DDevice,
3920 PrimitiveType,
3921 PrimitiveCount,
3922 &WineD3DStrided,
3923 VertexCount,
3924 Indices,
3925 WINED3DFMT_INDEX16);
3926 LeaveCriticalSection(&ddraw_cs);
3927 return hr;
3930 static HRESULT WINAPI
3931 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided(IDirect3DDevice3 *iface,
3932 D3DPRIMITIVETYPE PrimitiveType,
3933 DWORD VertexType,
3934 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3935 DWORD VertexCount,
3936 WORD *Indices,
3937 DWORD IndexCount,
3938 DWORD Flags)
3940 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3941 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
3942 return IDirect3DDevice7_DrawIndexedPrimitiveStrided(ICOM_INTERFACE(This, IDirect3DDevice7),
3943 PrimitiveType,
3944 VertexType,
3945 D3DDrawPrimStrideData,
3946 VertexCount,
3947 Indices,
3948 IndexCount,
3949 Flags);
3952 /*****************************************************************************
3953 * IDirect3DDevice7::DrawPrimitiveVB
3955 * Draws primitives from a vertex buffer to the screen.
3957 * Version 3 and 7
3959 * Params:
3960 * PrimitiveType: Type of primitive to be rendered.
3961 * D3DVertexBuf: Source Vertex Buffer
3962 * StartVertex: Index of the first vertex from the buffer to be rendered
3963 * NumVertices: Number of vertices to be rendered
3964 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
3966 * Return values
3967 * D3D_OK on success
3968 * DDERR_INVALIDPARAMS if D3DVertexBuf is NULL
3970 *****************************************************************************/
3971 static HRESULT WINAPI
3972 IDirect3DDeviceImpl_7_DrawPrimitiveVB(IDirect3DDevice7 *iface,
3973 D3DPRIMITIVETYPE PrimitiveType,
3974 IDirect3DVertexBuffer7 *D3DVertexBuf,
3975 DWORD StartVertex,
3976 DWORD NumVertices,
3977 DWORD Flags)
3979 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3980 IDirect3DVertexBufferImpl *vb = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, D3DVertexBuf);
3981 UINT PrimitiveCount;
3982 HRESULT hr;
3983 DWORD stride;
3984 WINED3DVERTEXBUFFER_DESC Desc;
3986 TRACE("(%p)->(%08x,%p,%08x,%08x,%08x)\n", This, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags);
3988 /* Sanity checks */
3989 if(!vb)
3991 ERR("(%p) No Vertex buffer specified\n", This);
3992 return DDERR_INVALIDPARAMS;
3995 /* Get the primitive count */
3996 switch(PrimitiveType)
3998 case D3DPT_POINTLIST:
3999 PrimitiveCount = NumVertices;
4000 break;
4002 case D3DPT_LINELIST:
4003 PrimitiveCount = NumVertices / 2;
4004 break;
4006 case D3DPT_LINESTRIP:
4007 PrimitiveCount = NumVertices - 1;
4008 break;
4010 case D3DPT_TRIANGLELIST:
4011 PrimitiveCount = NumVertices / 3;
4012 break;
4014 case D3DPT_TRIANGLESTRIP:
4015 PrimitiveCount = NumVertices - 2;
4016 break;
4018 case D3DPT_TRIANGLEFAN:
4019 PrimitiveCount = NumVertices - 2;
4020 break;
4022 default:
4023 return DDERR_INVALIDPARAMS;
4026 /* Get the FVF of the vertex buffer, and its stride */
4027 EnterCriticalSection(&ddraw_cs);
4028 hr = IWineD3DVertexBuffer_GetDesc(vb->wineD3DVertexBuffer,
4029 &Desc);
4030 if(hr != D3D_OK)
4032 ERR("(%p) IWineD3DVertexBuffer::GetDesc failed with hr = %08x\n", This, hr);
4033 LeaveCriticalSection(&ddraw_cs);
4034 return hr;
4036 stride = get_flexible_vertex_size(Desc.FVF);
4038 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
4039 vb->wineD3DVertexDeclaration);
4040 if(FAILED(hr))
4042 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr);
4043 LeaveCriticalSection(&ddraw_cs);
4044 return hr;
4047 /* Set the vertex stream source */
4048 hr = IWineD3DDevice_SetStreamSource(This->wineD3DDevice,
4049 0 /* StreamNumber */,
4050 vb->wineD3DVertexBuffer,
4051 0 /* StartVertex - we pass this to DrawPrimitive */,
4052 stride);
4053 if(hr != D3D_OK)
4055 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This, hr);
4056 LeaveCriticalSection(&ddraw_cs);
4057 return hr;
4060 /* Now draw the primitives */
4061 hr = IWineD3DDevice_DrawPrimitive(This->wineD3DDevice,
4062 PrimitiveType,
4063 StartVertex,
4064 PrimitiveCount);
4065 LeaveCriticalSection(&ddraw_cs);
4066 return hr;
4069 static HRESULT WINAPI
4070 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB(IDirect3DDevice3 *iface,
4071 D3DPRIMITIVETYPE PrimitiveType,
4072 IDirect3DVertexBuffer *D3DVertexBuf,
4073 DWORD StartVertex,
4074 DWORD NumVertices,
4075 DWORD Flags)
4077 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4078 IDirect3DVertexBufferImpl *vb = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, D3DVertexBuf);
4079 TRACE_(ddraw_thunk)("(%p)->(%08x,%p,%08x,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, vb, StartVertex, NumVertices, Flags);
4080 return IDirect3DDevice7_DrawPrimitiveVB(ICOM_INTERFACE(This, IDirect3DDevice7),
4081 PrimitiveType,
4082 ICOM_INTERFACE(vb, IDirect3DVertexBuffer7),
4083 StartVertex,
4084 NumVertices,
4085 Flags);
4089 /*****************************************************************************
4090 * IDirect3DDevice7::DrawIndexedPrimitiveVB
4092 * Draws primitives from a vertex buffer to the screen
4094 * Params:
4095 * PrimitiveType: Type of primitive to be rendered.
4096 * D3DVertexBuf: Source Vertex Buffer
4097 * StartVertex: Index of the first vertex from the buffer to be rendered
4098 * NumVertices: Number of vertices to be rendered
4099 * Indices: Array of DWORDs used to index into the Vertices
4100 * IndexCount: Number of indices in Indices
4101 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4103 * Return values
4105 *****************************************************************************/
4106 static HRESULT WINAPI
4107 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(IDirect3DDevice7 *iface,
4108 D3DPRIMITIVETYPE PrimitiveType,
4109 IDirect3DVertexBuffer7 *D3DVertexBuf,
4110 DWORD StartVertex,
4111 DWORD NumVertices,
4112 WORD *Indices,
4113 DWORD IndexCount,
4114 DWORD Flags)
4116 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4117 IDirect3DVertexBufferImpl *vb = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, D3DVertexBuf);
4118 DWORD stride;
4119 UINT PrimitiveCount;
4120 WORD *LockedIndices;
4121 HRESULT hr;
4122 WINED3DVERTEXBUFFER_DESC Desc;
4124 TRACE("(%p)->(%08x,%p,%d,%d,%p,%d,%08x)\n", This, PrimitiveType, vb, StartVertex, NumVertices, Indices, IndexCount, Flags);
4126 /* Steps:
4127 * 1) Calculate some things: Vertex count -> Primitive count, stride, ...
4128 * 2) Upload the Indices to the index buffer
4129 * 3) Set the index source
4130 * 4) Set the Vertex Buffer as the Stream source
4131 * 5) Call IWineD3DDevice::DrawIndexedPrimitive
4134 /* Get the primitive count */
4135 switch(PrimitiveType)
4137 case D3DPT_POINTLIST:
4138 PrimitiveCount = IndexCount;
4139 break;
4141 case D3DPT_LINELIST:
4142 PrimitiveCount = IndexCount / 2;
4143 break;
4145 case D3DPT_LINESTRIP:
4146 PrimitiveCount = IndexCount - 1;
4147 break;
4149 case D3DPT_TRIANGLELIST:
4150 PrimitiveCount = IndexCount / 3;
4151 break;
4153 case D3DPT_TRIANGLESTRIP:
4154 PrimitiveCount = IndexCount - 2;
4155 break;
4157 case D3DPT_TRIANGLEFAN:
4158 PrimitiveCount = IndexCount - 2;
4159 break;
4161 default: return DDERR_INVALIDPARAMS;
4164 EnterCriticalSection(&ddraw_cs);
4165 /* Get the FVF of the vertex buffer, and its stride */
4166 hr = IWineD3DVertexBuffer_GetDesc(vb->wineD3DVertexBuffer,
4167 &Desc);
4168 if(hr != D3D_OK)
4170 ERR("(%p) IWineD3DVertexBuffer::GetDesc failed with hr = %08x\n", This, hr);
4171 LeaveCriticalSection(&ddraw_cs);
4172 return hr;
4174 stride = get_flexible_vertex_size(Desc.FVF);
4175 TRACE("Vertex buffer FVF = %08x, stride=%d\n", Desc.FVF, stride);
4177 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
4178 vb->wineD3DVertexDeclaration);
4179 if(FAILED(hr))
4181 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr);
4182 LeaveCriticalSection(&ddraw_cs);
4183 return hr;
4186 /* copy the index stream into the index buffer.
4187 * A new IWineD3DDevice method could be created
4188 * which takes an user pointer containing the indices
4189 * or a SetData-Method for the index buffer, which
4190 * overrides the index buffer data with our pointer.
4192 hr = IWineD3DIndexBuffer_Lock(This->indexbuffer,
4193 0 /* OffSetToLock */,
4194 IndexCount * sizeof(WORD),
4195 (BYTE **) &LockedIndices,
4196 0 /* Flags */);
4197 assert(IndexCount < 0x100000);
4198 if(hr != D3D_OK)
4200 ERR("(%p) IWineD3DIndexBuffer::Lock failed with hr = %08x\n", This, hr);
4201 LeaveCriticalSection(&ddraw_cs);
4202 return hr;
4204 memcpy(LockedIndices, Indices, IndexCount * sizeof(WORD));
4205 hr = IWineD3DIndexBuffer_Unlock(This->indexbuffer);
4206 if(hr != D3D_OK)
4208 ERR("(%p) IWineD3DIndexBuffer::Unlock failed with hr = %08x\n", This, hr);
4209 LeaveCriticalSection(&ddraw_cs);
4210 return hr;
4213 /* Set the index stream */
4214 IWineD3DDevice_SetBaseVertexIndex(This->wineD3DDevice, StartVertex);
4215 hr = IWineD3DDevice_SetIndices(This->wineD3DDevice, This->indexbuffer);
4217 /* Set the vertex stream source */
4218 hr = IWineD3DDevice_SetStreamSource(This->wineD3DDevice,
4219 0 /* StreamNumber */,
4220 vb->wineD3DVertexBuffer,
4221 0 /* offset, we pass this to DrawIndexedPrimitive */,
4222 stride);
4223 if(hr != D3D_OK)
4225 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This, hr);
4226 LeaveCriticalSection(&ddraw_cs);
4227 return hr;
4231 hr = IWineD3DDevice_DrawIndexedPrimitive(This->wineD3DDevice,
4232 PrimitiveType,
4233 0 /* minIndex */,
4234 NumVertices,
4235 0 /* StartIndex */,
4236 PrimitiveCount);
4238 LeaveCriticalSection(&ddraw_cs);
4239 return hr;
4242 static HRESULT WINAPI
4243 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB(IDirect3DDevice3 *iface,
4244 D3DPRIMITIVETYPE PrimitiveType,
4245 IDirect3DVertexBuffer *D3DVertexBuf,
4246 WORD *Indices,
4247 DWORD IndexCount,
4248 DWORD Flags)
4250 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4251 IDirect3DVertexBufferImpl *VB = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, D3DVertexBuf);
4252 TRACE_(ddraw_thunk)("(%p)->(%08x,%p,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VB, Indices, IndexCount, Flags);
4254 return IDirect3DDevice7_DrawIndexedPrimitiveVB(ICOM_INTERFACE(This, IDirect3DDevice7),
4255 PrimitiveType,
4256 ICOM_INTERFACE(VB, IDirect3DVertexBuffer7),
4258 IndexCount,
4259 Indices,
4260 IndexCount,
4261 Flags);
4264 /*****************************************************************************
4265 * IDirect3DDevice7::ComputeSphereVisibility
4267 * Calculates the visibility of spheres in the current viewport. The spheres
4268 * are passed in the Centers and Radii arrays, the results are passed back
4269 * in the ReturnValues array. Return values are either completely visible,
4270 * partially visible or completely invisible.
4271 * The return value consist of a combination of D3DCLIP_* flags, or it's
4272 * 0 if the sphere is completely visible(according to the SDK, not checked)
4274 * Sounds like an overdose of math ;)
4276 * Version 3 and 7
4278 * Params:
4279 * Centers: Array containing the sphere centers
4280 * Radii: Array containing the sphere radii
4281 * NumSpheres: The number of centers and radii in the arrays
4282 * Flags: Some flags
4283 * ReturnValues: Array to write the results to
4285 * Returns:
4286 * D3D_OK because it's a stub
4287 * (DDERR_INVALIDPARAMS if Centers, Radii or ReturnValues are NULL)
4288 * (D3DERR_INVALIDMATRIX if the combined world, view and proj matrix
4289 * is singular)
4291 *****************************************************************************/
4292 static HRESULT WINAPI
4293 IDirect3DDeviceImpl_7_ComputeSphereVisibility(IDirect3DDevice7 *iface,
4294 D3DVECTOR *Centers,
4295 D3DVALUE *Radii,
4296 DWORD NumSpheres,
4297 DWORD Flags,
4298 DWORD *ReturnValues)
4300 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4301 FIXME("(%p)->(%p,%p,%08x,%08x,%p): stub!\n", This, Centers, Radii, NumSpheres, Flags, ReturnValues);
4303 /* the DirectX 7 sdk says that the visibility is computed by
4304 * back-transforming the viewing frustum to model space
4305 * using the inverse of the combined world, view and projection
4306 * matrix. If the matrix can't be reversed, D3DERR_INVALIDMATRIX
4307 * is returned.
4309 * Basic implementation idea:
4310 * 1) Check if the center is in the viewing frustum
4311 * 2) Cut the sphere with the planes of the viewing
4312 * frustum
4314 * ->Center inside the frustum, no intersections:
4315 * Fully visible
4316 * ->Center outside the frustum, no intersections:
4317 * Not visible
4318 * ->Some intersections: Partially visible
4320 * Implement this call in WineD3D. Either implement the
4321 * matrix and vector stuff in WineD3D, or use some external
4322 * math library.
4325 return D3D_OK;
4328 static HRESULT WINAPI
4329 Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility(IDirect3DDevice3 *iface,
4330 D3DVECTOR *Centers,
4331 D3DVALUE *Radii,
4332 DWORD NumSpheres,
4333 DWORD Flags,
4334 DWORD *ReturnValues)
4336 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4337 TRACE_(ddraw_thunk)("(%p)->(%p,%p,%08x,%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, Centers, Radii, NumSpheres, Flags, ReturnValues);
4338 return IDirect3DDevice7_ComputeSphereVisibility(ICOM_INTERFACE(This, IDirect3DDevice7),
4339 Centers,
4340 Radii,
4341 NumSpheres,
4342 Flags,
4343 ReturnValues);
4346 /*****************************************************************************
4347 * IDirect3DDevice7::GetTexture
4349 * Returns the texture interface handle assigned to a texture stage.
4350 * The returned texture is AddRefed. This is taken from old ddraw,
4351 * not checked in Windows.
4353 * Version 3 and 7
4355 * Params:
4356 * Stage: Texture stage to read the texture from
4357 * Texture: Address to store the interface pointer at
4359 * Returns:
4360 * D3D_OK on success
4361 * DDERR_INVALIDPARAMS if Texture is NULL
4362 * For details, see IWineD3DDevice::GetTexture
4364 *****************************************************************************/
4365 static HRESULT WINAPI
4366 IDirect3DDeviceImpl_7_GetTexture(IDirect3DDevice7 *iface,
4367 DWORD Stage,
4368 IDirectDrawSurface7 **Texture)
4370 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4371 IWineD3DBaseTexture *Surf;
4372 HRESULT hr;
4373 TRACE("(%p)->(%d,%p): Relay\n", This, Stage, Texture);
4375 if(!Texture)
4377 TRACE("Texture == NULL, failing with DDERR_INVALIDPARAMS\n");
4378 return DDERR_INVALIDPARAMS;
4381 EnterCriticalSection(&ddraw_cs);
4382 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice, Stage, &Surf);
4383 if( (hr != D3D_OK) || (!Surf) )
4385 *Texture = NULL;
4386 LeaveCriticalSection(&ddraw_cs);
4387 return hr;
4390 /* GetParent AddRef()s, which is perfectly OK.
4391 * We have passed the IDirectDrawSurface7 interface to WineD3D, so that's OK too.
4393 hr = IWineD3DBaseTexture_GetParent(Surf,
4394 (IUnknown **) Texture);
4395 LeaveCriticalSection(&ddraw_cs);
4396 return hr;
4399 static HRESULT WINAPI
4400 Thunk_IDirect3DDeviceImpl_3_GetTexture(IDirect3DDevice3 *iface,
4401 DWORD Stage,
4402 IDirect3DTexture2 **Texture2)
4404 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4405 HRESULT ret;
4406 IDirectDrawSurface7 *ret_val;
4408 TRACE_(ddraw_thunk)("(%p)->(%d,%p) thunking to IDirect3DDevice7 interface.\n", This, Stage, Texture2);
4409 ret = IDirect3DDevice7_GetTexture(ICOM_INTERFACE(This, IDirect3DDevice7),
4410 Stage,
4411 &ret_val);
4413 *Texture2 = COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7, IDirect3DTexture2, ret_val);
4415 TRACE_(ddraw_thunk)(" returning interface %p.\n", *Texture2);
4417 return ret;
4420 /*****************************************************************************
4421 * IDirect3DDevice7::SetTexture
4423 * Assigns a texture to a texture stage. Is the texture AddRef-ed?
4425 * Version 3 and 7
4427 * Params:
4428 * Stage: The stage to assign the texture to
4429 * Texture: Interface pointer to the texture surface
4431 * Returns
4432 * D3D_OK on success
4433 * For details, see IWineD3DDevice::SetTexture
4435 *****************************************************************************/
4436 static HRESULT WINAPI
4437 IDirect3DDeviceImpl_7_SetTexture(IDirect3DDevice7 *iface,
4438 DWORD Stage,
4439 IDirectDrawSurface7 *Texture)
4441 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4442 IDirectDrawSurfaceImpl *surf = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, Texture);
4443 HRESULT hr;
4444 TRACE("(%p)->(%08x,%p): Relay!\n", This, Stage, surf);
4446 /* Texture may be NULL here */
4447 EnterCriticalSection(&ddraw_cs);
4448 hr = IWineD3DDevice_SetTexture(This->wineD3DDevice,
4449 Stage,
4450 surf ? surf->wineD3DTexture : NULL);
4451 LeaveCriticalSection(&ddraw_cs);
4452 return hr;
4455 static HRESULT WINAPI
4456 Thunk_IDirect3DDeviceImpl_3_SetTexture(IDirect3DDevice3 *iface,
4457 DWORD Stage,
4458 IDirect3DTexture2 *Texture2)
4460 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4461 IDirectDrawSurfaceImpl *tex = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture2, Texture2);
4462 TRACE_(ddraw_thunk)("(%p)->(%d,%p) thunking to IDirect3DDevice7 interface.\n", This, Stage, tex);
4463 return IDirect3DDevice7_SetTexture(ICOM_INTERFACE(This, IDirect3DDevice7),
4464 Stage,
4465 ICOM_INTERFACE(tex, IDirectDrawSurface7));
4468 /*****************************************************************************
4469 * IDirect3DDevice7::GetTextureStageState
4471 * Retrieves a state from a texture stage.
4473 * Version 3 and 7
4475 * Params:
4476 * Stage: The stage to retrieve the state from
4477 * TexStageStateType: The state type to retrieve
4478 * State: Address to store the state's value at
4480 * Returns:
4481 * D3D_OK on success
4482 * DDERR_INVALIDPARAMS if State is NULL
4483 * For details, see IWineD3DDevice::GetTextureStageState
4485 *****************************************************************************/
4486 static HRESULT WINAPI
4487 IDirect3DDeviceImpl_7_GetTextureStageState(IDirect3DDevice7 *iface,
4488 DWORD Stage,
4489 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4490 DWORD *State)
4492 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4493 HRESULT hr;
4494 TRACE("(%p)->(%08x,%08x,%p): Relay!\n", This, Stage, TexStageStateType, State);
4496 if(!State)
4497 return DDERR_INVALIDPARAMS;
4499 EnterCriticalSection(&ddraw_cs);
4500 switch(TexStageStateType)
4502 /* Mipfilter is a sampler state with different values */
4503 case D3DTSS_MIPFILTER:
4505 WINED3DTEXTUREFILTERTYPE value;
4507 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
4508 Stage,
4509 WINED3DSAMP_MIPFILTER,
4510 &value);
4511 switch(value)
4513 case WINED3DTEXF_NONE: *State = D3DTFP_NONE; break;
4514 case WINED3DTEXF_POINT: *State = D3DTFP_POINT; break;
4515 case WINED3DTEXF_LINEAR: *State = D3DTFP_LINEAR; break;
4516 default:
4517 ERR("Unexpected mipfilter value %d\n", value);
4518 *State = D3DTFP_NONE;
4520 break;
4523 /* Minfilter is a sampler state too, equal values */
4524 case D3DTSS_MINFILTER:
4525 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
4526 Stage,
4527 WINED3DSAMP_MINFILTER,
4528 State);
4529 break;
4531 /* Magfilter has slightly different values */
4532 case D3DTSS_MAGFILTER:
4534 WINED3DTEXTUREFILTERTYPE wined3dfilter;
4535 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
4536 Stage,
4537 WINED3DSAMP_MAGFILTER,
4538 &wined3dfilter);
4539 switch(wined3dfilter)
4541 case WINED3DTEXF_POINT: *State = D3DTFG_POINT; break;
4542 case WINED3DTEXF_LINEAR: *State = D3DTFG_LINEAR; break;
4543 case WINED3DTEXF_ANISOTROPIC: *State = D3DTFG_ANISOTROPIC; break;
4544 case WINED3DTEXF_FLATCUBIC: *State = D3DTFG_FLATCUBIC; break;
4545 case WINED3DTEXF_GAUSSIANCUBIC: *State = D3DTFG_GAUSSIANCUBIC; break;
4546 default:
4547 ERR("Unexpected wined3d mag filter value %d\n", wined3dfilter);
4548 *State = D3DTFG_POINT;
4550 break;
4553 case D3DTSS_ADDRESS:
4554 case D3DTSS_ADDRESSU:
4555 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
4556 Stage,
4557 WINED3DSAMP_ADDRESSU,
4558 State);
4559 break;
4560 case D3DTSS_ADDRESSV:
4561 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
4562 Stage,
4563 WINED3DSAMP_ADDRESSV,
4564 State);
4565 break;
4566 default:
4567 hr = IWineD3DDevice_GetTextureStageState(This->wineD3DDevice,
4568 Stage,
4569 TexStageStateType,
4570 State);
4571 break;
4573 LeaveCriticalSection(&ddraw_cs);
4574 return hr;
4577 static HRESULT WINAPI
4578 Thunk_IDirect3DDeviceImpl_3_GetTextureStageState(IDirect3DDevice3 *iface,
4579 DWORD Stage,
4580 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4581 DWORD *State)
4583 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4584 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, Stage, TexStageStateType, State);
4585 return IDirect3DDevice7_GetTextureStageState(ICOM_INTERFACE(This, IDirect3DDevice7),
4586 Stage,
4587 TexStageStateType,
4588 State);
4591 /*****************************************************************************
4592 * IDirect3DDevice7::SetTextureStageState
4594 * Sets a texture stage state. Some stage types need to be handled specially,
4595 * because they do not exist in WineD3D and were moved to another place
4597 * Version 3 and 7
4599 * Params:
4600 * Stage: The stage to modify
4601 * TexStageStateType: The state to change
4602 * State: The new value for the state
4604 * Returns:
4605 * D3D_OK on success
4606 * For details, see IWineD3DDevice::SetTextureStageState
4608 *****************************************************************************/
4609 static HRESULT WINAPI
4610 IDirect3DDeviceImpl_7_SetTextureStageState(IDirect3DDevice7 *iface,
4611 DWORD Stage,
4612 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4613 DWORD State)
4615 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4616 HRESULT hr;
4617 TRACE("(%p)->(%08x,%08x,%08x): Relay!\n", This, Stage, TexStageStateType, State);
4619 EnterCriticalSection(&ddraw_cs);
4620 switch(TexStageStateType)
4622 /* Mipfilter is a sampler state with different values */
4623 case D3DTSS_MIPFILTER:
4625 WINED3DTEXTUREFILTERTYPE value;
4626 switch(State)
4628 case D3DTFP_NONE: value = WINED3DTEXF_NONE; break;
4629 case D3DTFP_POINT: value = WINED3DTEXF_POINT; break;
4630 case 0: /* Unchecked */
4631 case D3DTFP_LINEAR: value = WINED3DTEXF_LINEAR; break;
4632 default:
4633 ERR("Unexpected mipfilter value %d\n", State);
4634 value = WINED3DTEXF_NONE;
4636 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
4637 Stage,
4638 WINED3DSAMP_MIPFILTER,
4639 value);
4640 break;
4643 /* Minfilter is a sampler state too, equal values */
4644 case D3DTSS_MINFILTER:
4645 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
4646 Stage,
4647 WINED3DSAMP_MINFILTER,
4648 State);
4649 break;
4651 /* Magfilter has slightly different values */
4652 case D3DTSS_MAGFILTER:
4654 WINED3DTEXTUREFILTERTYPE wined3dfilter;
4655 switch((D3DTEXTUREMAGFILTER) State)
4657 case D3DTFG_POINT: wined3dfilter = WINED3DTEXF_POINT; break;
4658 case D3DTFG_LINEAR: wined3dfilter = WINED3DTEXF_LINEAR; break;
4659 case D3DTFG_FLATCUBIC: wined3dfilter = WINED3DTEXF_FLATCUBIC; break;
4660 case D3DTFG_GAUSSIANCUBIC: wined3dfilter = WINED3DTEXF_GAUSSIANCUBIC; break;
4661 case D3DTFG_ANISOTROPIC: wined3dfilter = WINED3DTEXF_ANISOTROPIC; break;
4662 default:
4663 ERR("Unexpected d3d7 mag filter type %d\n", State);
4664 wined3dfilter = WINED3DTEXF_POINT;
4666 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
4667 Stage,
4668 WINED3DSAMP_MAGFILTER,
4669 wined3dfilter);
4670 break;
4673 case D3DTSS_ADDRESS:
4674 IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
4675 Stage,
4676 WINED3DSAMP_ADDRESSV,
4677 State);
4678 /* Drop through */
4679 case D3DTSS_ADDRESSU:
4680 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
4681 Stage,
4682 WINED3DSAMP_ADDRESSU,
4683 State);
4684 break;
4686 case D3DTSS_ADDRESSV:
4687 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
4688 Stage,
4689 WINED3DSAMP_ADDRESSV,
4690 State);
4691 break;
4693 default:
4694 hr = IWineD3DDevice_SetTextureStageState(This->wineD3DDevice,
4695 Stage,
4696 TexStageStateType,
4697 State);
4698 break;
4700 LeaveCriticalSection(&ddraw_cs);
4701 return hr;
4704 static HRESULT WINAPI
4705 Thunk_IDirect3DDeviceImpl_3_SetTextureStageState(IDirect3DDevice3 *iface,
4706 DWORD Stage,
4707 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4708 DWORD State)
4710 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4711 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, Stage, TexStageStateType, State);
4712 return IDirect3DDevice7_SetTextureStageState(ICOM_INTERFACE(This, IDirect3DDevice7),
4713 Stage,
4714 TexStageStateType,
4715 State);
4718 /*****************************************************************************
4719 * IDirect3DDevice7::ValidateDevice
4721 * SDK: "Reports the device's ability to render the currently set
4722 * texture-blending operations in a single pass". Whatever that means
4723 * exactly...
4725 * Version 3 and 7
4727 * Params:
4728 * NumPasses: Address to write the number of necessary passes for the
4729 * desired effect to.
4731 * Returns:
4732 * D3D_OK on success
4733 * See IWineD3DDevice::ValidateDevice for more details
4735 *****************************************************************************/
4736 static HRESULT WINAPI
4737 IDirect3DDeviceImpl_7_ValidateDevice(IDirect3DDevice7 *iface,
4738 DWORD *NumPasses)
4740 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4741 HRESULT hr;
4742 TRACE("(%p)->(%p): Relay\n", This, NumPasses);
4744 EnterCriticalSection(&ddraw_cs);
4745 hr = IWineD3DDevice_ValidateDevice(This->wineD3DDevice, NumPasses);
4746 LeaveCriticalSection(&ddraw_cs);
4747 return hr;
4750 static HRESULT WINAPI
4751 Thunk_IDirect3DDeviceImpl_3_ValidateDevice(IDirect3DDevice3 *iface,
4752 DWORD *Passes)
4754 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4755 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Passes);
4756 return IDirect3DDevice7_ValidateDevice(ICOM_INTERFACE(This, IDirect3DDevice7),
4757 Passes);
4760 /*****************************************************************************
4761 * IDirect3DDevice7::Clear
4763 * Fills the render target, the z buffer and the stencil buffer with a
4764 * clear color / value
4766 * Version 7 only
4768 * Params:
4769 * Count: Number of rectangles in Rects must be 0 if Rects is NULL
4770 * Rects: Rectangles to clear. If NULL, the whole surface is cleared
4771 * Flags: Some flags, as usual
4772 * Color: Clear color for the render target
4773 * Z: Clear value for the Z buffer
4774 * Stencil: Clear value to store in each stencil buffer entry
4776 * Returns:
4777 * D3D_OK on success
4778 * For details, see IWineD3DDevice::Clear
4780 *****************************************************************************/
4781 static HRESULT WINAPI
4782 IDirect3DDeviceImpl_7_Clear(IDirect3DDevice7 *iface,
4783 DWORD Count,
4784 D3DRECT *Rects,
4785 DWORD Flags,
4786 D3DCOLOR Color,
4787 D3DVALUE Z,
4788 DWORD Stencil)
4790 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4791 HRESULT hr;
4792 TRACE("(%p)->(%08x,%p,%08x,%08x,%f,%08x): Relay\n", This, Count, Rects, Flags, Color, Z, Stencil);
4794 /* Note; D3DRECT is compatible with WINED3DRECT */
4795 EnterCriticalSection(&ddraw_cs);
4796 hr = IWineD3DDevice_Clear(This->wineD3DDevice, Count, (WINED3DRECT*) Rects, Flags, Color, Z, Stencil);
4797 LeaveCriticalSection(&ddraw_cs);
4798 return hr;
4801 /*****************************************************************************
4802 * IDirect3DDevice7::SetViewport
4804 * Sets the current viewport.
4806 * Version 7 only, but IDirect3DViewport uses this call for older
4807 * versions
4809 * Params:
4810 * Data: The new viewport to set
4812 * Returns:
4813 * D3D_OK on success
4814 * DDERR_INVALIDPARAMS if Data is NULL
4815 * For more details, see IWineDDDevice::SetViewport
4817 *****************************************************************************/
4818 static HRESULT WINAPI
4819 IDirect3DDeviceImpl_7_SetViewport(IDirect3DDevice7 *iface,
4820 D3DVIEWPORT7 *Data)
4822 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4823 HRESULT hr;
4824 TRACE("(%p)->(%p) Relay!\n", This, Data);
4826 if(!Data)
4827 return DDERR_INVALIDPARAMS;
4829 /* Note: D3DVIEWPORT7 is compatible with WINED3DVIEWPORT */
4830 EnterCriticalSection(&ddraw_cs);
4831 hr = IWineD3DDevice_SetViewport(This->wineD3DDevice,
4832 (WINED3DVIEWPORT*) Data);
4833 LeaveCriticalSection(&ddraw_cs);
4834 return hr;
4837 /*****************************************************************************
4838 * IDirect3DDevice::GetViewport
4840 * Returns the current viewport
4842 * Version 7
4844 * Params:
4845 * Data: D3D7Viewport structure to write the viewport information to
4847 * Returns:
4848 * D3D_OK on success
4849 * DDERR_INVALIDPARAMS if Data is NULL
4850 * For more details, see IWineD3DDevice::GetViewport
4852 *****************************************************************************/
4853 static HRESULT WINAPI
4854 IDirect3DDeviceImpl_7_GetViewport(IDirect3DDevice7 *iface,
4855 D3DVIEWPORT7 *Data)
4857 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4858 HRESULT hr;
4859 TRACE("(%p)->(%p) Relay!\n", This, Data);
4861 if(!Data)
4862 return DDERR_INVALIDPARAMS;
4864 /* Note: D3DVIEWPORT7 is compatible with WINED3DVIEWPORT */
4865 EnterCriticalSection(&ddraw_cs);
4866 hr = IWineD3DDevice_GetViewport(This->wineD3DDevice,
4867 (WINED3DVIEWPORT*) Data);
4869 LeaveCriticalSection(&ddraw_cs);
4870 return hr_ddraw_from_wined3d(hr);
4873 /*****************************************************************************
4874 * IDirect3DDevice7::SetMaterial
4876 * Sets the Material
4878 * Version 7
4880 * Params:
4881 * Mat: The material to set
4883 * Returns:
4884 * D3D_OK on success
4885 * DDERR_INVALIDPARAMS if Mat is NULL.
4886 * For more details, see IWineD3DDevice::SetMaterial
4888 *****************************************************************************/
4889 static HRESULT WINAPI
4890 IDirect3DDeviceImpl_7_SetMaterial(IDirect3DDevice7 *iface,
4891 D3DMATERIAL7 *Mat)
4893 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4894 HRESULT hr;
4895 TRACE("(%p)->(%p): Relay!\n", This, Mat);
4897 /* Note: D3DMATERIAL7 is compatible with WINED3DMATERIAL */
4898 EnterCriticalSection(&ddraw_cs);
4899 hr = IWineD3DDevice_SetMaterial(This->wineD3DDevice,
4900 (WINED3DMATERIAL*) Mat);
4901 LeaveCriticalSection(&ddraw_cs);
4902 return hr_ddraw_from_wined3d(hr);
4905 /*****************************************************************************
4906 * IDirect3DDevice7::GetMaterial
4908 * Returns the current material
4910 * Version 7
4912 * Params:
4913 * Mat: D3DMATERIAL7 structure to write the material parameters to
4915 * Returns:
4916 * D3D_OK on success
4917 * DDERR_INVALIDPARAMS if Mat is NULL
4918 * For more details, see IWineD3DDevice::GetMaterial
4920 *****************************************************************************/
4921 static HRESULT WINAPI
4922 IDirect3DDeviceImpl_7_GetMaterial(IDirect3DDevice7 *iface,
4923 D3DMATERIAL7 *Mat)
4925 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4926 HRESULT hr;
4927 TRACE("(%p)->(%p): Relay!\n", This, Mat);
4929 EnterCriticalSection(&ddraw_cs);
4930 /* Note: D3DMATERIAL7 is compatible with WINED3DMATERIAL */
4931 hr = IWineD3DDevice_GetMaterial(This->wineD3DDevice,
4932 (WINED3DMATERIAL*) Mat);
4933 LeaveCriticalSection(&ddraw_cs);
4934 return hr_ddraw_from_wined3d(hr);
4937 /*****************************************************************************
4938 * IDirect3DDevice7::SetLight
4940 * Assigns a light to a light index, but doesn't activate it yet.
4942 * Version 7, IDirect3DLight uses this method for older versions
4944 * Params:
4945 * LightIndex: The index of the new light
4946 * Light: A D3DLIGHT7 structure describing the light
4948 * Returns:
4949 * D3D_OK on success
4950 * For more details, see IWineD3DDevice::SetLight
4952 *****************************************************************************/
4953 static HRESULT WINAPI
4954 IDirect3DDeviceImpl_7_SetLight(IDirect3DDevice7 *iface,
4955 DWORD LightIndex,
4956 D3DLIGHT7 *Light)
4958 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4959 HRESULT hr;
4960 TRACE("(%p)->(%08x,%p): Relay!\n", This, LightIndex, Light);
4962 EnterCriticalSection(&ddraw_cs);
4963 /* Note: D3DLIGHT7 is compatible with WINED3DLIGHT */
4964 hr = IWineD3DDevice_SetLight(This->wineD3DDevice,
4965 LightIndex,
4966 (WINED3DLIGHT*) Light);
4967 LeaveCriticalSection(&ddraw_cs);
4968 return hr_ddraw_from_wined3d(hr);
4971 /*****************************************************************************
4972 * IDirect3DDevice7::GetLight
4974 * Returns the light assigned to a light index
4976 * Params:
4977 * Light: Structure to write the light information to
4979 * Returns:
4980 * D3D_OK on success
4981 * DDERR_INVALIDPARAMS if Light is NULL
4982 * For details, see IWineD3DDevice::GetLight
4984 *****************************************************************************/
4985 static HRESULT WINAPI
4986 IDirect3DDeviceImpl_7_GetLight(IDirect3DDevice7 *iface,
4987 DWORD LightIndex,
4988 D3DLIGHT7 *Light)
4990 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4991 HRESULT rc;
4992 TRACE("(%p)->(%08x,%p): Relay!\n", This, LightIndex, Light);
4994 EnterCriticalSection(&ddraw_cs);
4995 /* Note: D3DLIGHT7 is compatible with WINED3DLIGHT */
4996 rc = IWineD3DDevice_GetLight(This->wineD3DDevice,
4997 LightIndex,
4998 (WINED3DLIGHT*) Light);
5000 /* Translate the result. WineD3D returns other values than D3D7 */
5001 LeaveCriticalSection(&ddraw_cs);
5002 return hr_ddraw_from_wined3d(rc);
5005 /*****************************************************************************
5006 * IDirect3DDevice7::BeginStateBlock
5008 * Begins recording to a stateblock
5010 * Version 7
5012 * Returns:
5013 * D3D_OK on success
5014 * For details see IWineD3DDevice::BeginStateBlock
5016 *****************************************************************************/
5017 static HRESULT WINAPI
5018 IDirect3DDeviceImpl_7_BeginStateBlock(IDirect3DDevice7 *iface)
5020 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5021 HRESULT hr;
5022 TRACE("(%p)->(): Relay!\n", This);
5024 EnterCriticalSection(&ddraw_cs);
5025 hr = IWineD3DDevice_BeginStateBlock(This->wineD3DDevice);
5026 LeaveCriticalSection(&ddraw_cs);
5027 return hr_ddraw_from_wined3d(hr);
5030 /*****************************************************************************
5031 * IDirect3DDevice7::EndStateBlock
5033 * Stops recording to a state block and returns the created stateblock
5034 * handle.
5036 * Version 7
5038 * Params:
5039 * BlockHandle: Address to store the stateblock's handle to
5041 * Returns:
5042 * D3D_OK on success
5043 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5044 * See IWineD3DDevice::EndStateBlock for more details
5046 *****************************************************************************/
5047 static HRESULT WINAPI
5048 IDirect3DDeviceImpl_7_EndStateBlock(IDirect3DDevice7 *iface,
5049 DWORD *BlockHandle)
5051 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5052 HRESULT hr;
5053 TRACE("(%p)->(%p): Relay!\n", This, BlockHandle);
5055 if(!BlockHandle)
5057 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
5058 return DDERR_INVALIDPARAMS;
5061 EnterCriticalSection(&ddraw_cs);
5062 *BlockHandle = IDirect3DDeviceImpl_CreateHandle(This);
5063 if(!*BlockHandle)
5065 ERR("Cannot get a handle number for the stateblock\n");
5066 LeaveCriticalSection(&ddraw_cs);
5067 return DDERR_OUTOFMEMORY;
5069 This->Handles[*BlockHandle - 1].type = DDrawHandle_StateBlock;
5070 hr = IWineD3DDevice_EndStateBlock(This->wineD3DDevice,
5071 (IWineD3DStateBlock **) &This->Handles[*BlockHandle - 1].ptr);
5072 LeaveCriticalSection(&ddraw_cs);
5073 return hr_ddraw_from_wined3d(hr);
5076 /*****************************************************************************
5077 * IDirect3DDevice7::PreLoad
5079 * Allows the app to signal that a texture will be used soon, to allow
5080 * the Direct3DDevice to load it to the video card in the meantime.
5082 * Version 7
5084 * Params:
5085 * Texture: The texture to preload
5087 * Returns:
5088 * D3D_OK on success
5089 * DDERR_INVALIDPARAMS if Texture is NULL
5090 * See IWineD3DSurface::PreLoad for details
5092 *****************************************************************************/
5093 static HRESULT WINAPI
5094 IDirect3DDeviceImpl_7_PreLoad(IDirect3DDevice7 *iface,
5095 IDirectDrawSurface7 *Texture)
5097 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5098 IDirectDrawSurfaceImpl *surf = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, Texture);
5100 TRACE("(%p)->(%p): Relay!\n", This, surf);
5102 if(!Texture)
5103 return DDERR_INVALIDPARAMS;
5105 EnterCriticalSection(&ddraw_cs);
5106 IWineD3DSurface_PreLoad(surf->WineD3DSurface);
5107 LeaveCriticalSection(&ddraw_cs);
5108 return D3D_OK;
5111 /*****************************************************************************
5112 * IDirect3DDevice7::ApplyStateBlock
5114 * Activates the state stored in a state block handle.
5116 * Params:
5117 * BlockHandle: The stateblock handle to activate
5119 * Returns:
5120 * D3D_OK on success
5121 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5123 *****************************************************************************/
5124 static HRESULT WINAPI
5125 IDirect3DDeviceImpl_7_ApplyStateBlock(IDirect3DDevice7 *iface,
5126 DWORD BlockHandle)
5128 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5129 HRESULT hr;
5130 TRACE("(%p)->(%08x): Relay!\n", This, BlockHandle);
5132 EnterCriticalSection(&ddraw_cs);
5133 if(!BlockHandle || BlockHandle > This->numHandles)
5135 WARN("Out of range handle %d, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5136 LeaveCriticalSection(&ddraw_cs);
5137 return D3DERR_INVALIDSTATEBLOCK;
5139 if(This->Handles[BlockHandle - 1].type != DDrawHandle_StateBlock)
5141 WARN("Handle %d is not a stateblock, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5142 LeaveCriticalSection(&ddraw_cs);
5143 return D3DERR_INVALIDSTATEBLOCK;
5146 hr = IWineD3DStateBlock_Apply((IWineD3DStateBlock *) This->Handles[BlockHandle - 1].ptr);
5147 LeaveCriticalSection(&ddraw_cs);
5148 return hr_ddraw_from_wined3d(hr);
5151 /*****************************************************************************
5152 * IDirect3DDevice7::CaptureStateBlock
5154 * Updates a stateblock's values to the values currently set for the device
5156 * Version 7
5158 * Params:
5159 * BlockHandle: Stateblock to update
5161 * Returns:
5162 * D3D_OK on success
5163 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5164 * See IWineD3DDevice::CaptureStateBlock for more details
5166 *****************************************************************************/
5167 static HRESULT WINAPI
5168 IDirect3DDeviceImpl_7_CaptureStateBlock(IDirect3DDevice7 *iface,
5169 DWORD BlockHandle)
5171 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5172 HRESULT hr;
5173 TRACE("(%p)->(%08x): Relay!\n", This, BlockHandle);
5175 EnterCriticalSection(&ddraw_cs);
5176 if(BlockHandle == 0 || BlockHandle > This->numHandles)
5178 WARN("Out of range handle %d, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5179 LeaveCriticalSection(&ddraw_cs);
5180 return D3DERR_INVALIDSTATEBLOCK;
5182 if(This->Handles[BlockHandle - 1].type != DDrawHandle_StateBlock)
5184 WARN("Handle %d is not a stateblock, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5185 LeaveCriticalSection(&ddraw_cs);
5186 return D3DERR_INVALIDSTATEBLOCK;
5189 hr = IWineD3DStateBlock_Capture((IWineD3DStateBlock *) This->Handles[BlockHandle - 1].ptr);
5190 LeaveCriticalSection(&ddraw_cs);
5191 return hr_ddraw_from_wined3d(hr);
5194 /*****************************************************************************
5195 * IDirect3DDevice7::DeleteStateBlock
5197 * Deletes a stateblock handle. This means releasing the WineD3DStateBlock
5199 * Version 7
5201 * Params:
5202 * BlockHandle: Stateblock handle to delete
5204 * Returns:
5205 * D3D_OK on success
5206 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is 0
5208 *****************************************************************************/
5209 static HRESULT WINAPI
5210 IDirect3DDeviceImpl_7_DeleteStateBlock(IDirect3DDevice7 *iface,
5211 DWORD BlockHandle)
5213 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5214 ULONG ref;
5215 TRACE("(%p)->(%08x): Relay!\n", This, BlockHandle);
5217 EnterCriticalSection(&ddraw_cs);
5218 if(BlockHandle == 0 || BlockHandle > This->numHandles)
5220 WARN("Out of range handle %d, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5221 LeaveCriticalSection(&ddraw_cs);
5222 return D3DERR_INVALIDSTATEBLOCK;
5224 if(This->Handles[BlockHandle - 1].type != DDrawHandle_StateBlock)
5226 WARN("Handle %d is not a stateblock, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5227 LeaveCriticalSection(&ddraw_cs);
5228 return D3DERR_INVALIDSTATEBLOCK;
5231 ref = IWineD3DStateBlock_Release((IWineD3DStateBlock *) This->Handles[BlockHandle - 1].ptr);
5232 if(ref)
5234 ERR("Something is still holding the stateblock %p(Handle %d). Ref = %d\n", This->Handles[BlockHandle - 1].ptr, BlockHandle, ref);
5236 This->Handles[BlockHandle - 1].ptr = NULL;
5237 This->Handles[BlockHandle - 1].type = DDrawHandle_Unknown;
5239 LeaveCriticalSection(&ddraw_cs);
5240 return D3D_OK;
5243 /*****************************************************************************
5244 * IDirect3DDevice7::CreateStateBlock
5246 * Creates a new state block handle.
5248 * Version 7
5250 * Params:
5251 * Type: The state block type
5252 * BlockHandle: Address to write the created handle to
5254 * Returns:
5255 * D3D_OK on success
5256 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5258 *****************************************************************************/
5259 static HRESULT WINAPI
5260 IDirect3DDeviceImpl_7_CreateStateBlock(IDirect3DDevice7 *iface,
5261 D3DSTATEBLOCKTYPE Type,
5262 DWORD *BlockHandle)
5264 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5265 HRESULT hr;
5266 TRACE("(%p)->(%08x,%p)!\n", This, Type, BlockHandle);
5268 if(!BlockHandle)
5270 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
5271 return DDERR_INVALIDPARAMS;
5273 if(Type != D3DSBT_ALL && Type != D3DSBT_PIXELSTATE &&
5274 Type != D3DSBT_VERTEXSTATE ) {
5275 WARN("Unexpected stateblock type, returning DDERR_INVALIDPARAMS\n");
5276 return DDERR_INVALIDPARAMS;
5279 EnterCriticalSection(&ddraw_cs);
5280 *BlockHandle = IDirect3DDeviceImpl_CreateHandle(This);
5281 if(!*BlockHandle)
5283 ERR("Cannot get a handle number for the stateblock\n");
5284 LeaveCriticalSection(&ddraw_cs);
5285 return DDERR_OUTOFMEMORY;
5287 This->Handles[*BlockHandle - 1].type = DDrawHandle_StateBlock;
5289 /* The D3DSTATEBLOCKTYPE enum is fine here */
5290 hr = IWineD3DDevice_CreateStateBlock(This->wineD3DDevice,
5291 Type,
5292 (IWineD3DStateBlock **) &This->Handles[*BlockHandle - 1].ptr,
5293 NULL /* Parent, hope that works */);
5294 LeaveCriticalSection(&ddraw_cs);
5295 return hr_ddraw_from_wined3d(hr);
5298 /*****************************************************************************
5299 * IDirect3DDevice7::Load
5301 * Loads a rectangular area from the source into the destination texture.
5302 * It can also copy the source to the faces of a cubic environment map
5304 * Version 7
5306 * Params:
5307 * DestTex: Destination texture
5308 * DestPoint: Point in the destination where the source image should be
5309 * written to
5310 * SrcTex: Source texture
5311 * SrcRect: Source rectangle
5312 * Flags: Some flags
5314 * Returns:
5315 * D3D_OK on success
5316 * DDERR_INVALIDPARAMS if DestTex or SrcTex are NULL
5317 * See IDirect3DTexture2::Load for details
5319 *****************************************************************************/
5320 static HRESULT WINAPI
5321 IDirect3DDeviceImpl_7_Load(IDirect3DDevice7 *iface,
5322 IDirectDrawSurface7 *DestTex,
5323 POINT *DestPoint,
5324 IDirectDrawSurface7 *SrcTex,
5325 RECT *SrcRect,
5326 DWORD Flags)
5328 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5329 IDirectDrawSurfaceImpl *dest = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, DestTex);
5330 IDirectDrawSurfaceImpl *src = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, SrcTex);
5331 FIXME("(%p)->(%p,%p,%p,%p,%08x): Partially Implemented!\n", This, dest, DestPoint, src, SrcRect, Flags);
5333 if( (!src) || (!dest) )
5334 return DDERR_INVALIDPARAMS;
5336 IDirect3DTexture2_Load(ICOM_INTERFACE(dest, IDirect3DTexture2),
5337 ICOM_INTERFACE(src, IDirect3DTexture2));
5338 return D3D_OK;
5341 /*****************************************************************************
5342 * IDirect3DDevice7::LightEnable
5344 * Enables or disables a light
5346 * Version 7, IDirect3DLight uses this method too.
5348 * Params:
5349 * LightIndex: The index of the light to enable / disable
5350 * Enable: Enable or disable the light
5352 * Returns:
5353 * D3D_OK on success
5354 * For more details, see IWineD3DDevice::SetLightEnable
5356 *****************************************************************************/
5357 static HRESULT WINAPI
5358 IDirect3DDeviceImpl_7_LightEnable(IDirect3DDevice7 *iface,
5359 DWORD LightIndex,
5360 BOOL Enable)
5362 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5363 HRESULT hr;
5364 TRACE("(%p)->(%08x,%d): Relay!\n", This, LightIndex, Enable);
5366 EnterCriticalSection(&ddraw_cs);
5367 hr = IWineD3DDevice_SetLightEnable(This->wineD3DDevice, LightIndex, Enable);
5368 LeaveCriticalSection(&ddraw_cs);
5369 return hr_ddraw_from_wined3d(hr);
5372 /*****************************************************************************
5373 * IDirect3DDevice7::GetLightEnable
5375 * Retrieves if the light with the given index is enabled or not
5377 * Version 7
5379 * Params:
5380 * LightIndex: Index of desired light
5381 * Enable: Pointer to a BOOL which contains the result
5383 * Returns:
5384 * D3D_OK on success
5385 * DDERR_INVALIDPARAMS if Enable is NULL
5386 * See IWineD3DDevice::GetLightEnable for more details
5388 *****************************************************************************/
5389 static HRESULT WINAPI
5390 IDirect3DDeviceImpl_7_GetLightEnable(IDirect3DDevice7 *iface,
5391 DWORD LightIndex,
5392 BOOL* Enable)
5394 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5395 HRESULT hr;
5396 TRACE("(%p)->(%08x,%p): Relay\n", This, LightIndex, Enable);
5398 if(!Enable)
5399 return DDERR_INVALIDPARAMS;
5401 EnterCriticalSection(&ddraw_cs);
5402 hr = IWineD3DDevice_GetLightEnable(This->wineD3DDevice, LightIndex, Enable);
5403 LeaveCriticalSection(&ddraw_cs);
5404 return hr_ddraw_from_wined3d(hr);
5407 /*****************************************************************************
5408 * IDirect3DDevice7::SetClipPlane
5410 * Sets custom clipping plane
5412 * Version 7
5414 * Params:
5415 * Index: The index of the clipping plane
5416 * PlaneEquation: An equation defining the clipping plane
5418 * Returns:
5419 * D3D_OK on success
5420 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
5421 * See IWineD3DDevice::SetClipPlane for more details
5423 *****************************************************************************/
5424 static HRESULT WINAPI
5425 IDirect3DDeviceImpl_7_SetClipPlane(IDirect3DDevice7 *iface,
5426 DWORD Index,
5427 D3DVALUE* PlaneEquation)
5429 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5430 HRESULT hr;
5431 TRACE("(%p)->(%08x,%p): Relay!\n", This, Index, PlaneEquation);
5433 if(!PlaneEquation)
5434 return DDERR_INVALIDPARAMS;
5436 EnterCriticalSection(&ddraw_cs);
5437 hr = IWineD3DDevice_SetClipPlane(This->wineD3DDevice, Index, PlaneEquation);
5438 LeaveCriticalSection(&ddraw_cs);
5439 return hr;
5442 /*****************************************************************************
5443 * IDirect3DDevice7::GetClipPlane
5445 * Returns the clipping plane with a specific index
5447 * Params:
5448 * Index: The index of the desired plane
5449 * PlaneEquation: Address to store the plane equation to
5451 * Returns:
5452 * D3D_OK on success
5453 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
5454 * See IWineD3DDevice::GetClipPlane for more details
5456 *****************************************************************************/
5457 static HRESULT WINAPI
5458 IDirect3DDeviceImpl_7_GetClipPlane(IDirect3DDevice7 *iface,
5459 DWORD Index,
5460 D3DVALUE* PlaneEquation)
5462 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5463 HRESULT hr;
5464 TRACE("(%p)->(%d,%p): Relay!\n", This, Index, PlaneEquation);
5466 if(!PlaneEquation)
5467 return DDERR_INVALIDPARAMS;
5469 EnterCriticalSection(&ddraw_cs);
5470 hr = IWineD3DDevice_GetClipPlane(This->wineD3DDevice, Index, PlaneEquation);
5471 LeaveCriticalSection(&ddraw_cs);
5472 return hr;
5475 /*****************************************************************************
5476 * IDirect3DDevice7::GetInfo
5478 * Retrieves some information about the device. The DirectX sdk says that
5479 * this version returns S_FALSE for all retail builds of DirectX, that's what
5480 * this implementation does.
5482 * Params:
5483 * DevInfoID: Information type requested
5484 * DevInfoStruct: Pointer to a structure to store the info to
5485 * Size: Size of the structure
5487 * Returns:
5488 * S_FALSE, because it's a non-debug driver
5490 *****************************************************************************/
5491 static HRESULT WINAPI
5492 IDirect3DDeviceImpl_7_GetInfo(IDirect3DDevice7 *iface,
5493 DWORD DevInfoID,
5494 void *DevInfoStruct,
5495 DWORD Size)
5497 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5498 TRACE("(%p)->(%08x,%p,%08x)\n", This, DevInfoID, DevInfoStruct, Size);
5500 if (TRACE_ON(d3d7))
5502 TRACE(" info requested : ");
5503 switch (DevInfoID)
5505 case D3DDEVINFOID_TEXTUREMANAGER: TRACE("D3DDEVINFOID_TEXTUREMANAGER\n"); break;
5506 case D3DDEVINFOID_D3DTEXTUREMANAGER: TRACE("D3DDEVINFOID_D3DTEXTUREMANAGER\n"); break;
5507 case D3DDEVINFOID_TEXTURING: TRACE("D3DDEVINFOID_TEXTURING\n"); break;
5508 default: ERR(" invalid flag !!!\n"); return DDERR_INVALIDPARAMS;
5512 return S_FALSE; /* According to MSDN, this is valid for a non-debug driver */
5515 const IDirect3DDevice7Vtbl IDirect3DDevice7_Vtbl =
5517 /*** IUnknown Methods ***/
5518 IDirect3DDeviceImpl_7_QueryInterface,
5519 IDirect3DDeviceImpl_7_AddRef,
5520 IDirect3DDeviceImpl_7_Release,
5521 /*** IDirect3DDevice7 ***/
5522 IDirect3DDeviceImpl_7_GetCaps,
5523 IDirect3DDeviceImpl_7_EnumTextureFormats,
5524 IDirect3DDeviceImpl_7_BeginScene,
5525 IDirect3DDeviceImpl_7_EndScene,
5526 IDirect3DDeviceImpl_7_GetDirect3D,
5527 IDirect3DDeviceImpl_7_SetRenderTarget,
5528 IDirect3DDeviceImpl_7_GetRenderTarget,
5529 IDirect3DDeviceImpl_7_Clear,
5530 IDirect3DDeviceImpl_7_SetTransform,
5531 IDirect3DDeviceImpl_7_GetTransform,
5532 IDirect3DDeviceImpl_7_SetViewport,
5533 IDirect3DDeviceImpl_7_MultiplyTransform,
5534 IDirect3DDeviceImpl_7_GetViewport,
5535 IDirect3DDeviceImpl_7_SetMaterial,
5536 IDirect3DDeviceImpl_7_GetMaterial,
5537 IDirect3DDeviceImpl_7_SetLight,
5538 IDirect3DDeviceImpl_7_GetLight,
5539 IDirect3DDeviceImpl_7_SetRenderState,
5540 IDirect3DDeviceImpl_7_GetRenderState,
5541 IDirect3DDeviceImpl_7_BeginStateBlock,
5542 IDirect3DDeviceImpl_7_EndStateBlock,
5543 IDirect3DDeviceImpl_7_PreLoad,
5544 IDirect3DDeviceImpl_7_DrawPrimitive,
5545 IDirect3DDeviceImpl_7_DrawIndexedPrimitive,
5546 IDirect3DDeviceImpl_7_SetClipStatus,
5547 IDirect3DDeviceImpl_7_GetClipStatus,
5548 IDirect3DDeviceImpl_7_DrawPrimitiveStrided,
5549 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided,
5550 IDirect3DDeviceImpl_7_DrawPrimitiveVB,
5551 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB,
5552 IDirect3DDeviceImpl_7_ComputeSphereVisibility,
5553 IDirect3DDeviceImpl_7_GetTexture,
5554 IDirect3DDeviceImpl_7_SetTexture,
5555 IDirect3DDeviceImpl_7_GetTextureStageState,
5556 IDirect3DDeviceImpl_7_SetTextureStageState,
5557 IDirect3DDeviceImpl_7_ValidateDevice,
5558 IDirect3DDeviceImpl_7_ApplyStateBlock,
5559 IDirect3DDeviceImpl_7_CaptureStateBlock,
5560 IDirect3DDeviceImpl_7_DeleteStateBlock,
5561 IDirect3DDeviceImpl_7_CreateStateBlock,
5562 IDirect3DDeviceImpl_7_Load,
5563 IDirect3DDeviceImpl_7_LightEnable,
5564 IDirect3DDeviceImpl_7_GetLightEnable,
5565 IDirect3DDeviceImpl_7_SetClipPlane,
5566 IDirect3DDeviceImpl_7_GetClipPlane,
5567 IDirect3DDeviceImpl_7_GetInfo
5570 const IDirect3DDevice3Vtbl IDirect3DDevice3_Vtbl =
5572 /*** IUnknown Methods ***/
5573 Thunk_IDirect3DDeviceImpl_3_QueryInterface,
5574 Thunk_IDirect3DDeviceImpl_3_AddRef,
5575 Thunk_IDirect3DDeviceImpl_3_Release,
5576 /*** IDirect3DDevice3 ***/
5577 IDirect3DDeviceImpl_3_GetCaps,
5578 IDirect3DDeviceImpl_3_GetStats,
5579 IDirect3DDeviceImpl_3_AddViewport,
5580 IDirect3DDeviceImpl_3_DeleteViewport,
5581 IDirect3DDeviceImpl_3_NextViewport,
5582 Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats,
5583 Thunk_IDirect3DDeviceImpl_3_BeginScene,
5584 Thunk_IDirect3DDeviceImpl_3_EndScene,
5585 Thunk_IDirect3DDeviceImpl_3_GetDirect3D,
5586 IDirect3DDeviceImpl_3_SetCurrentViewport,
5587 IDirect3DDeviceImpl_3_GetCurrentViewport,
5588 Thunk_IDirect3DDeviceImpl_3_SetRenderTarget,
5589 Thunk_IDirect3DDeviceImpl_3_GetRenderTarget,
5590 IDirect3DDeviceImpl_3_Begin,
5591 IDirect3DDeviceImpl_3_BeginIndexed,
5592 IDirect3DDeviceImpl_3_Vertex,
5593 IDirect3DDeviceImpl_3_Index,
5594 IDirect3DDeviceImpl_3_End,
5595 Thunk_IDirect3DDeviceImpl_3_GetRenderState,
5596 Thunk_IDirect3DDeviceImpl_3_SetRenderState,
5597 IDirect3DDeviceImpl_3_GetLightState,
5598 IDirect3DDeviceImpl_3_SetLightState,
5599 Thunk_IDirect3DDeviceImpl_3_SetTransform,
5600 Thunk_IDirect3DDeviceImpl_3_GetTransform,
5601 Thunk_IDirect3DDeviceImpl_3_MultiplyTransform,
5602 Thunk_IDirect3DDeviceImpl_3_DrawPrimitive,
5603 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive,
5604 Thunk_IDirect3DDeviceImpl_3_SetClipStatus,
5605 Thunk_IDirect3DDeviceImpl_3_GetClipStatus,
5606 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided,
5607 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided,
5608 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB,
5609 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB,
5610 Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility,
5611 Thunk_IDirect3DDeviceImpl_3_GetTexture,
5612 Thunk_IDirect3DDeviceImpl_3_SetTexture,
5613 Thunk_IDirect3DDeviceImpl_3_GetTextureStageState,
5614 Thunk_IDirect3DDeviceImpl_3_SetTextureStageState,
5615 Thunk_IDirect3DDeviceImpl_3_ValidateDevice
5618 const IDirect3DDevice2Vtbl IDirect3DDevice2_Vtbl =
5620 /*** IUnknown Methods ***/
5621 Thunk_IDirect3DDeviceImpl_2_QueryInterface,
5622 Thunk_IDirect3DDeviceImpl_2_AddRef,
5623 Thunk_IDirect3DDeviceImpl_2_Release,
5624 /*** IDirect3DDevice2 ***/
5625 Thunk_IDirect3DDeviceImpl_2_GetCaps,
5626 IDirect3DDeviceImpl_2_SwapTextureHandles,
5627 Thunk_IDirect3DDeviceImpl_2_GetStats,
5628 Thunk_IDirect3DDeviceImpl_2_AddViewport,
5629 Thunk_IDirect3DDeviceImpl_2_DeleteViewport,
5630 Thunk_IDirect3DDeviceImpl_2_NextViewport,
5631 IDirect3DDeviceImpl_2_EnumTextureFormats,
5632 Thunk_IDirect3DDeviceImpl_2_BeginScene,
5633 Thunk_IDirect3DDeviceImpl_2_EndScene,
5634 Thunk_IDirect3DDeviceImpl_2_GetDirect3D,
5635 Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport,
5636 Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport,
5637 Thunk_IDirect3DDeviceImpl_2_SetRenderTarget,
5638 Thunk_IDirect3DDeviceImpl_2_GetRenderTarget,
5639 Thunk_IDirect3DDeviceImpl_2_Begin,
5640 Thunk_IDirect3DDeviceImpl_2_BeginIndexed,
5641 Thunk_IDirect3DDeviceImpl_2_Vertex,
5642 Thunk_IDirect3DDeviceImpl_2_Index,
5643 Thunk_IDirect3DDeviceImpl_2_End,
5644 IDirect3DDeviceImpl_2_GetRenderState,
5645 IDirect3DDeviceImpl_2_SetRenderState,
5646 Thunk_IDirect3DDeviceImpl_2_GetLightState,
5647 Thunk_IDirect3DDeviceImpl_2_SetLightState,
5648 Thunk_IDirect3DDeviceImpl_2_SetTransform,
5649 Thunk_IDirect3DDeviceImpl_2_GetTransform,
5650 Thunk_IDirect3DDeviceImpl_2_MultiplyTransform,
5651 Thunk_IDirect3DDeviceImpl_2_DrawPrimitive,
5652 Thunk_IDirect3DDeviceImpl_2_DrawIndexedPrimitive,
5653 Thunk_IDirect3DDeviceImpl_2_SetClipStatus,
5654 Thunk_IDirect3DDeviceImpl_2_GetClipStatus
5657 const IDirect3DDeviceVtbl IDirect3DDevice1_Vtbl =
5659 /*** IUnknown Methods ***/
5660 Thunk_IDirect3DDeviceImpl_1_QueryInterface,
5661 Thunk_IDirect3DDeviceImpl_1_AddRef,
5662 Thunk_IDirect3DDeviceImpl_1_Release,
5663 /*** IDirect3DDevice1 ***/
5664 IDirect3DDeviceImpl_1_Initialize,
5665 Thunk_IDirect3DDeviceImpl_1_GetCaps,
5666 Thunk_IDirect3DDeviceImpl_1_SwapTextureHandles,
5667 IDirect3DDeviceImpl_1_CreateExecuteBuffer,
5668 Thunk_IDirect3DDeviceImpl_1_GetStats,
5669 IDirect3DDeviceImpl_1_Execute,
5670 Thunk_IDirect3DDeviceImpl_1_AddViewport,
5671 Thunk_IDirect3DDeviceImpl_1_DeleteViewport,
5672 Thunk_IDirect3DDeviceImpl_1_NextViewport,
5673 IDirect3DDeviceImpl_1_Pick,
5674 IDirect3DDeviceImpl_1_GetPickRecords,
5675 Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats,
5676 IDirect3DDeviceImpl_1_CreateMatrix,
5677 IDirect3DDeviceImpl_1_SetMatrix,
5678 IDirect3DDeviceImpl_1_GetMatrix,
5679 IDirect3DDeviceImpl_1_DeleteMatrix,
5680 Thunk_IDirect3DDeviceImpl_1_BeginScene,
5681 Thunk_IDirect3DDeviceImpl_1_EndScene,
5682 Thunk_IDirect3DDeviceImpl_1_GetDirect3D
5685 /*****************************************************************************
5686 * IDirect3DDeviceImpl_CreateHandle
5688 * Not called from the VTable
5690 * Some older interface versions operate with handles, which are basically
5691 * DWORDs which identify an interface, for example
5692 * IDirect3DDevice::SetRenderState with DIRECT3DRENDERSTATE_TEXTUREHANDLE
5694 * Those handle could be just casts to the interface pointers or vice versa,
5695 * but that is not 64 bit safe and would mean blindly derefering a DWORD
5696 * passed by the app. Instead there is a dynamic array in the device which
5697 * keeps a DWORD to pointer information and a type for the handle.
5699 * Basically this array only grows, when a handle is freed its pointer is
5700 * just set to NULL. There will be much more reads from the array than
5701 * insertion operations, so a dynamic array is fine.
5703 * Params:
5704 * This: D3DDevice implementation for which this handle should be created
5706 * Returns:
5707 * A free handle on success
5708 * 0 on failure
5710 *****************************************************************************/
5711 DWORD
5712 IDirect3DDeviceImpl_CreateHandle(IDirect3DDeviceImpl *This)
5714 DWORD i;
5715 struct HandleEntry *oldHandles = This->Handles;
5717 TRACE("(%p)\n", This);
5719 for(i = 0; i < This->numHandles; i++)
5721 if(This->Handles[i].ptr == NULL &&
5722 This->Handles[i].type == DDrawHandle_Unknown)
5724 TRACE("Reusing freed handle %d\n", i + 1);
5725 return i + 1;
5729 TRACE("Growing the handle array\n");
5731 This->numHandles++;
5732 This->Handles = HeapAlloc(GetProcessHeap(), 0, sizeof(struct HandleEntry) * This->numHandles);
5733 if(!This->Handles)
5735 ERR("Out of memory\n");
5736 This->Handles = oldHandles;
5737 This->numHandles--;
5738 return 0;
5740 if(oldHandles)
5742 memcpy(This->Handles, oldHandles, (This->numHandles - 1) * sizeof(struct HandleEntry));
5743 HeapFree(GetProcessHeap(), 0, oldHandles);
5746 TRACE("Returning %d\n", This->numHandles);
5747 return This->numHandles;
5750 /*****************************************************************************
5751 * IDirect3DDeviceImpl_UpdateDepthStencil
5753 * Checks the current render target for attached depth stencils and sets the
5754 * WineD3D depth stencil accordingly.
5756 * Returns:
5757 * The depth stencil state to set if creating the device
5759 *****************************************************************************/
5760 WINED3DZBUFFERTYPE
5761 IDirect3DDeviceImpl_UpdateDepthStencil(IDirect3DDeviceImpl *This)
5763 IDirectDrawSurface7 *depthStencil = NULL;
5764 IDirectDrawSurfaceImpl *dsi;
5765 static DDSCAPS2 depthcaps = { DDSCAPS_ZBUFFER, 0, 0, 0 };
5767 IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(This->target, IDirectDrawSurface7),
5768 &depthcaps,
5769 &depthStencil);
5770 if(!depthStencil)
5772 TRACE("Setting wined3d depth stencil to NULL\n");
5773 IWineD3DDevice_SetDepthStencilSurface(This->wineD3DDevice,
5774 NULL);
5775 return WINED3DZB_FALSE;
5778 dsi = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, depthStencil);
5779 TRACE("Setting wined3d depth stencil to %p (wined3d %p)\n", dsi, dsi->WineD3DSurface);
5780 IWineD3DDevice_SetDepthStencilSurface(This->wineD3DDevice,
5781 dsi->WineD3DSurface);
5783 IDirectDrawSurface7_Release(depthStencil);
5784 return WINED3DZB_TRUE;