dmusic: Assign to structs instead of using memcpy.
[wine.git] / dlls / ddraw / device.c
blobb60b6f3cc51d4af9a8b85b2351ecb4150e276376
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 hardare 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 LeaveCriticalSection(&ddraw_cs);
822 return D3D_OK;
825 static HRESULT WINAPI
826 Thunk_IDirect3DDeviceImpl_2_AddViewport(IDirect3DDevice2 *iface,
827 IDirect3DViewport2 *Direct3DViewport2)
829 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
830 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport2);
831 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
832 return IDirect3DDevice3_AddViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
833 ICOM_INTERFACE(vp, IDirect3DViewport3));
836 static HRESULT WINAPI
837 Thunk_IDirect3DDeviceImpl_1_AddViewport(IDirect3DDevice *iface,
838 IDirect3DViewport *Direct3DViewport)
840 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
841 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport);
842 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
843 return IDirect3DDevice3_AddViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
844 ICOM_INTERFACE(vp, IDirect3DViewport3));
847 /*****************************************************************************
848 * IDirect3DDevice3::DeleteViewport
850 * Deletes a Direct3DViewport from the device's viewport list.
852 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
853 * are equal.
855 * Params:
856 * Viewport: The viewport to delete
858 * Returns:
859 * D3D_OK on success
860 * DDERR_INVALIDPARAMS if the viewport wasn't found in the list
862 *****************************************************************************/
863 static HRESULT WINAPI
864 IDirect3DDeviceImpl_3_DeleteViewport(IDirect3DDevice3 *iface,
865 IDirect3DViewport3 *Viewport)
867 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
868 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *) Viewport;
869 IDirect3DViewportImpl *cur_viewport, *prev_viewport = NULL;
871 TRACE("(%p)->(%p)\n", This, vp);
873 EnterCriticalSection(&ddraw_cs);
874 cur_viewport = This->viewport_list;
875 while (cur_viewport != NULL)
877 if (cur_viewport == vp)
879 if (prev_viewport == NULL) This->viewport_list = cur_viewport->next;
880 else prev_viewport->next = cur_viewport->next;
881 /* TODO : add desactivate of the viewport and all associated lights... */
882 LeaveCriticalSection(&ddraw_cs);
883 return D3D_OK;
885 prev_viewport = cur_viewport;
886 cur_viewport = cur_viewport->next;
889 LeaveCriticalSection(&ddraw_cs);
890 return DDERR_INVALIDPARAMS;
893 static HRESULT WINAPI
894 Thunk_IDirect3DDeviceImpl_2_DeleteViewport(IDirect3DDevice2 *iface,
895 IDirect3DViewport2 *Direct3DViewport2)
897 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
898 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport2);
899 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
900 return IDirect3DDevice3_DeleteViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
901 ICOM_INTERFACE(vp, IDirect3DViewport3));
904 static HRESULT WINAPI
905 Thunk_IDirect3DDeviceImpl_1_DeleteViewport(IDirect3DDevice *iface,
906 IDirect3DViewport *Direct3DViewport)
908 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
909 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport);
910 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
911 return IDirect3DDevice3_DeleteViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
912 ICOM_INTERFACE(vp, IDirect3DViewport3));
915 /*****************************************************************************
916 * IDirect3DDevice3::NextViewport
918 * Returns a viewport from the viewport list, depending on the
919 * passed viewport and the flags.
921 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
922 * are equal.
924 * Params:
925 * Viewport: Viewport to use for beginning the search
926 * Flags: D3DNEXT_NEXT, D3DNEXT_HEAD or D3DNEXT_TAIL
928 * Returns:
929 * D3D_OK on success
930 * DDERR_INVALIDPARAMS if the flags were wrong, or Viewport was NULL
932 *****************************************************************************/
933 static HRESULT WINAPI
934 IDirect3DDeviceImpl_3_NextViewport(IDirect3DDevice3 *iface,
935 IDirect3DViewport3 *Viewport3,
936 IDirect3DViewport3 **lplpDirect3DViewport3,
937 DWORD Flags)
939 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
940 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport3);
941 IDirect3DViewportImpl *res = NULL;
943 TRACE("(%p)->(%p,%p,%08x)\n", This, vp, lplpDirect3DViewport3, Flags);
945 if(!vp)
947 *lplpDirect3DViewport3 = NULL;
948 return DDERR_INVALIDPARAMS;
952 EnterCriticalSection(&ddraw_cs);
953 switch (Flags)
955 case D3DNEXT_NEXT:
957 res = vp->next;
959 break;
960 case D3DNEXT_HEAD:
962 res = This->viewport_list;
964 break;
965 case D3DNEXT_TAIL:
967 IDirect3DViewportImpl *cur_viewport = This->viewport_list;
968 if (cur_viewport != NULL)
970 while (cur_viewport->next != NULL) cur_viewport = cur_viewport->next;
972 res = cur_viewport;
974 break;
975 default:
976 *lplpDirect3DViewport3 = NULL;
977 LeaveCriticalSection(&ddraw_cs);
978 return DDERR_INVALIDPARAMS;
981 *lplpDirect3DViewport3 = ICOM_INTERFACE(res, IDirect3DViewport3);
982 LeaveCriticalSection(&ddraw_cs);
983 return D3D_OK;
986 static HRESULT WINAPI
987 Thunk_IDirect3DDeviceImpl_2_NextViewport(IDirect3DDevice2 *iface,
988 IDirect3DViewport2 *Viewport2,
989 IDirect3DViewport2 **lplpDirect3DViewport2,
990 DWORD Flags)
992 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
993 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport2);
994 IDirect3DViewport3 *res;
995 HRESULT hr;
996 TRACE_(ddraw_thunk)("(%p)->(%p,%p,%08x) thunking to IDirect3DDevice3 interface.\n", This, vp, lplpDirect3DViewport2, Flags);
997 hr = IDirect3DDevice3_NextViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
998 ICOM_INTERFACE(vp, IDirect3DViewport3),
999 &res,
1000 Flags);
1001 *lplpDirect3DViewport2 = (IDirect3DViewport2 *) COM_INTERFACE_CAST(IDirect3DViewportImpl, IDirect3DViewport3, IDirect3DViewport3, res);
1002 return hr;
1005 static HRESULT WINAPI
1006 Thunk_IDirect3DDeviceImpl_1_NextViewport(IDirect3DDevice *iface,
1007 IDirect3DViewport *Viewport,
1008 IDirect3DViewport **lplpDirect3DViewport,
1009 DWORD Flags)
1011 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1012 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport);
1013 IDirect3DViewport3 *res;
1014 HRESULT hr;
1015 TRACE_(ddraw_thunk)("(%p)->(%p,%p,%08x) thunking to IDirect3DDevice3 interface.\n", This, vp, lplpDirect3DViewport, Flags);
1016 hr = IDirect3DDevice3_NextViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
1017 ICOM_INTERFACE(vp, IDirect3DViewport3),
1018 &res,
1019 Flags);
1020 *lplpDirect3DViewport = (IDirect3DViewport *) COM_INTERFACE_CAST(IDirect3DViewportImpl, IDirect3DViewport3, IDirect3DViewport3, res);
1021 return hr;
1024 /*****************************************************************************
1025 * IDirect3DDevice::Pick
1027 * Executes an execute buffer without performing rendering. Instead, a
1028 * list of primitives that intersect with (x1,y1) of the passed rectangle
1029 * is created. IDirect3DDevice::GetPickRecords can be used to retrieve
1030 * this list.
1032 * Version 1 only
1034 * Params:
1035 * ExecuteBuffer: Buffer to execute
1036 * Viewport: Viewport to use for execution
1037 * Flags: None are defined, according to the SDK
1038 * Rect: Specifies the coordinates to be picked. Only x1 and y2 are used,
1039 * x2 and y2 are ignored.
1041 * Returns:
1042 * D3D_OK because it's a stub
1044 *****************************************************************************/
1045 static HRESULT WINAPI
1046 IDirect3DDeviceImpl_1_Pick(IDirect3DDevice *iface,
1047 IDirect3DExecuteBuffer *ExecuteBuffer,
1048 IDirect3DViewport *Viewport,
1049 DWORD Flags,
1050 D3DRECT *Rect)
1052 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1053 IDirect3DExecuteBufferImpl *execbuf = ICOM_OBJECT(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, ExecuteBuffer);
1054 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport);
1055 FIXME("(%p)->(%p,%p,%08x,%p): stub!\n", This, execbuf, vp, Flags, Rect);
1057 return D3D_OK;
1060 /*****************************************************************************
1061 * IDirect3DDevice::GetPickRecords
1063 * Retrieves the pick records generated by IDirect3DDevice::GetPickRecords
1065 * Version 1 only
1067 * Params:
1068 * Count: Pointer to a DWORD containing the numbers of pick records to
1069 * retrieve
1070 * D3DPickRec: Address to store the resulting D3DPICKRECORD arry.
1072 * Returns:
1073 * D3D_OK, because it's a stub
1075 *****************************************************************************/
1076 static HRESULT WINAPI
1077 IDirect3DDeviceImpl_1_GetPickRecords(IDirect3DDevice *iface,
1078 DWORD *Count,
1079 D3DPICKRECORD *D3DPickRec)
1081 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1082 FIXME("(%p)->(%p,%p): stub!\n", This, Count, D3DPickRec);
1084 return D3D_OK;
1087 /*****************************************************************************
1088 * IDirect3DDevice7::EnumTextureformats
1090 * Enumerates the supported texture formats. It has a list of all possible
1091 * formats and calls IWineD3D::CheckDeviceFormat for each format to see if
1092 * WineD3D supports it. If so, then it is passed to the app.
1094 * This is for Version 7 and 3, older versions have a different
1095 * callback function and their own implementation
1097 * Params:
1098 * Callback: Callback to call for each enumerated format
1099 * Arg: Argument to pass to the callback
1101 * Returns:
1102 * D3D_OK on success
1103 * DDERR_INVALIDPARAMS if Callback == NULL
1105 *****************************************************************************/
1106 static HRESULT WINAPI
1107 IDirect3DDeviceImpl_7_EnumTextureFormats(IDirect3DDevice7 *iface,
1108 LPD3DENUMPIXELFORMATSCALLBACK Callback,
1109 void *Arg)
1111 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1112 HRESULT hr;
1113 int i;
1115 WINED3DFORMAT FormatList[] = {
1116 /* 32 bit */
1117 WINED3DFMT_A8R8G8B8,
1118 WINED3DFMT_X8R8G8B8,
1119 /* 24 bit */
1120 WINED3DFMT_R8G8B8,
1121 /* 16 Bit */
1122 WINED3DFMT_A1R5G5B5,
1123 WINED3DFMT_A4R4G4B4,
1124 WINED3DFMT_R5G6B5,
1125 WINED3DFMT_X1R5G5B5,
1126 /* 8 Bit */
1127 WINED3DFMT_R3G3B2,
1128 WINED3DFMT_P8,
1129 /* FOURCC codes */
1130 WINED3DFMT_DXT1,
1131 WINED3DFMT_DXT3,
1132 WINED3DFMT_DXT5,
1135 WINED3DFORMAT BumpFormatList[] = {
1136 WINED3DFMT_V8U8,
1137 WINED3DFMT_L6V5U5,
1138 WINED3DFMT_X8L8V8U8,
1139 WINED3DFMT_Q8W8V8U8,
1140 WINED3DFMT_V16U16,
1141 WINED3DFMT_W11V11U10,
1142 WINED3DFMT_A2W10V10U10
1145 TRACE("(%p)->(%p,%p): Relay\n", This, Callback, Arg);
1147 if(!Callback)
1148 return DDERR_INVALIDPARAMS;
1150 EnterCriticalSection(&ddraw_cs);
1151 for(i = 0; i < sizeof(FormatList) / sizeof(WINED3DFORMAT); i++)
1153 hr = IWineD3D_CheckDeviceFormat(This->ddraw->wineD3D,
1154 0 /* Adapter */,
1155 0 /* DeviceType */,
1156 0 /* AdapterFormat */,
1157 0 /* Usage */,
1158 0 /* ResourceType */,
1159 FormatList[i]);
1160 if(hr == D3D_OK)
1162 DDPIXELFORMAT pformat;
1164 memset(&pformat, 0, sizeof(pformat));
1165 pformat.dwSize = sizeof(pformat);
1166 PixelFormat_WineD3DtoDD(&pformat, FormatList[i]);
1168 TRACE("Enumerating WineD3DFormat %d\n", FormatList[i]);
1169 hr = Callback(&pformat, Arg);
1170 if(hr != DDENUMRET_OK)
1172 TRACE("Format enumeration cancelled by application\n");
1173 LeaveCriticalSection(&ddraw_cs);
1174 return D3D_OK;
1179 for(i = 0; i < sizeof(BumpFormatList) / sizeof(WINED3DFORMAT); i++)
1181 hr = IWineD3D_CheckDeviceFormat(This->ddraw->wineD3D,
1182 0 /* Adapter */,
1183 0 /* DeviceType */,
1184 0 /* AdapterFormat */,
1185 WINED3DUSAGE_QUERY_LEGACYBUMPMAP,
1186 0 /* ResourceType */,
1187 BumpFormatList[i]);
1188 if(hr == D3D_OK)
1190 DDPIXELFORMAT pformat;
1192 memset(&pformat, 0, sizeof(pformat));
1193 pformat.dwSize = sizeof(pformat);
1194 PixelFormat_WineD3DtoDD(&pformat, BumpFormatList[i]);
1196 TRACE("Enumerating WineD3DFormat %d\n", BumpFormatList[i]);
1197 hr = Callback(&pformat, Arg);
1198 if(hr != DDENUMRET_OK)
1200 TRACE("Format enumeration cancelled by application\n");
1201 LeaveCriticalSection(&ddraw_cs);
1202 return D3D_OK;
1206 TRACE("End of enumeration\n");
1207 LeaveCriticalSection(&ddraw_cs);
1208 return D3D_OK;
1211 static HRESULT WINAPI
1212 Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats(IDirect3DDevice3 *iface,
1213 LPD3DENUMPIXELFORMATSCALLBACK Callback,
1214 void *Arg)
1216 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1217 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice7 interface.\n", This, Callback, Arg);
1218 return IDirect3DDevice7_EnumTextureFormats(ICOM_INTERFACE(This, IDirect3DDevice7),
1219 Callback,
1220 Arg);
1223 /*****************************************************************************
1224 * IDirect3DDevice2::EnumTextureformats
1226 * EnumTextureFormats for Version 1 and 2, see
1227 * IDirect3DDevice7::EnumTexureFormats for a more detailed description.
1229 * This version has a different callback and does not enumerate FourCC
1230 * formats
1232 *****************************************************************************/
1233 static HRESULT WINAPI
1234 IDirect3DDeviceImpl_2_EnumTextureFormats(IDirect3DDevice2 *iface,
1235 LPD3DENUMTEXTUREFORMATSCALLBACK Callback,
1236 void *Arg)
1238 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1239 HRESULT hr;
1240 int i;
1242 WINED3DFORMAT FormatList[] = {
1243 /* 32 bit */
1244 WINED3DFMT_A8R8G8B8,
1245 WINED3DFMT_X8R8G8B8,
1246 /* 24 bit */
1247 WINED3DFMT_R8G8B8,
1248 /* 16 Bit */
1249 WINED3DFMT_A1R5G5B5,
1250 WINED3DFMT_A4R4G4B4,
1251 WINED3DFMT_R5G6B5,
1252 WINED3DFMT_X1R5G5B5,
1253 /* 8 Bit */
1254 WINED3DFMT_R3G3B2,
1255 WINED3DFMT_P8,
1256 /* FOURCC codes - Not in this version*/
1259 TRACE("(%p)->(%p,%p): Relay\n", This, Callback, Arg);
1261 if(!Callback)
1262 return DDERR_INVALIDPARAMS;
1264 EnterCriticalSection(&ddraw_cs);
1265 for(i = 0; i < sizeof(FormatList) / sizeof(WINED3DFORMAT); i++)
1267 hr = IWineD3D_CheckDeviceFormat(This->ddraw->wineD3D,
1268 0 /* Adapter */,
1269 0 /* DeviceType */,
1270 0 /* AdapterFormat */,
1271 0 /* Usage */,
1272 0 /* ResourceType */,
1273 FormatList[i]);
1274 if(hr == D3D_OK)
1276 DDSURFACEDESC sdesc;
1278 memset(&sdesc, 0, sizeof(sdesc));
1279 sdesc.dwSize = sizeof(sdesc);
1280 sdesc.dwFlags = DDSD_PIXELFORMAT | DDSD_CAPS;
1281 sdesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1282 sdesc.ddpfPixelFormat.dwSize = sizeof(sdesc.ddpfPixelFormat);
1283 PixelFormat_WineD3DtoDD(&sdesc.ddpfPixelFormat, FormatList[i]);
1285 TRACE("Enumerating WineD3DFormat %d\n", FormatList[i]);
1286 hr = Callback(&sdesc, Arg);
1287 if(hr != DDENUMRET_OK)
1289 TRACE("Format enumeration cancelled by application\n");
1290 LeaveCriticalSection(&ddraw_cs);
1291 return D3D_OK;
1295 TRACE("End of enumeration\n");
1296 LeaveCriticalSection(&ddraw_cs);
1297 return D3D_OK;
1300 static HRESULT WINAPI
1301 Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats(IDirect3DDevice *iface,
1302 LPD3DENUMTEXTUREFORMATSCALLBACK Callback,
1303 void *Arg)
1305 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1306 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice2 interface.\n", This, Callback, Arg);
1307 return IDirect3DDevice2_EnumTextureFormats(ICOM_INTERFACE(This, IDirect3DDevice2),
1308 Callback,
1309 Arg);
1312 /*****************************************************************************
1313 * IDirect3DDevice::CreateMatrix
1315 * Creates a matrix handle. A handle is created and memory for a D3DMATRIX is
1316 * allocated for the handle.
1318 * Version 1 only
1320 * Params
1321 * D3DMatHandle: Address to return the handle at
1323 * Returns:
1324 * D3D_OK on success
1325 * DDERR_INVALIDPARAMS if D3DMatHandle = NULL
1327 *****************************************************************************/
1328 static HRESULT WINAPI
1329 IDirect3DDeviceImpl_1_CreateMatrix(IDirect3DDevice *iface, D3DMATRIXHANDLE *D3DMatHandle)
1331 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1332 D3DMATRIX *Matrix;
1333 TRACE("(%p)->(%p)\n", This, D3DMatHandle);
1335 if(!D3DMatHandle)
1336 return DDERR_INVALIDPARAMS;
1338 Matrix = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(D3DMATRIX));
1339 if(!Matrix)
1341 ERR("Out of memory when allocating a D3DMATRIX\n");
1342 return DDERR_OUTOFMEMORY;
1345 EnterCriticalSection(&ddraw_cs);
1346 *D3DMatHandle = IDirect3DDeviceImpl_CreateHandle(This);
1347 if(!(*D3DMatHandle))
1349 ERR("Failed to create a matrix handle\n");
1350 HeapFree(GetProcessHeap(), 0, Matrix);
1351 LeaveCriticalSection(&ddraw_cs);
1352 return DDERR_OUTOFMEMORY;
1354 This->Handles[*D3DMatHandle - 1].ptr = Matrix;
1355 This->Handles[*D3DMatHandle - 1].type = DDrawHandle_Matrix;
1356 TRACE(" returning matrix handle %d\n", *D3DMatHandle);
1358 LeaveCriticalSection(&ddraw_cs);
1359 return D3D_OK;
1362 /*****************************************************************************
1363 * IDirect3DDevice::SetMatrix
1365 * Sets a matrix for a matrix handle. The matrix is copied into the memory
1366 * allocated for the handle
1368 * Version 1 only
1370 * Params:
1371 * D3DMatHandle: Handle to set the matrix to
1372 * D3DMatrix: Matrix to set
1374 * Returns:
1375 * D3D_OK on success
1376 * DDERR_INVALIDPARAMS if the handle of the matrix is invalid or the matrix
1377 * to set is NULL
1379 *****************************************************************************/
1380 static HRESULT WINAPI
1381 IDirect3DDeviceImpl_1_SetMatrix(IDirect3DDevice *iface,
1382 D3DMATRIXHANDLE D3DMatHandle,
1383 D3DMATRIX *D3DMatrix)
1385 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1386 TRACE("(%p)->(%08x,%p)\n", This, D3DMatHandle, D3DMatrix);
1388 if( (!D3DMatHandle) || (!D3DMatrix) )
1389 return DDERR_INVALIDPARAMS;
1391 EnterCriticalSection(&ddraw_cs);
1392 if(D3DMatHandle > This->numHandles)
1394 ERR("Handle %d out of range\n", D3DMatHandle);
1395 LeaveCriticalSection(&ddraw_cs);
1396 return DDERR_INVALIDPARAMS;
1398 else if(This->Handles[D3DMatHandle - 1].type != DDrawHandle_Matrix)
1400 ERR("Handle %d is not a matrix handle\n", D3DMatHandle);
1401 LeaveCriticalSection(&ddraw_cs);
1402 return DDERR_INVALIDPARAMS;
1405 if (TRACE_ON(d3d7))
1406 dump_D3DMATRIX(D3DMatrix);
1408 *((D3DMATRIX *) This->Handles[D3DMatHandle - 1].ptr) = *D3DMatrix;
1410 if(This->world == D3DMatHandle)
1412 IWineD3DDevice_SetTransform(This->wineD3DDevice,
1413 WINED3DTS_WORLDMATRIX(0),
1414 (WINED3DMATRIX *) D3DMatrix);
1416 if(This->view == D3DMatHandle)
1418 IWineD3DDevice_SetTransform(This->wineD3DDevice,
1419 WINED3DTS_VIEW,
1420 (WINED3DMATRIX *) D3DMatrix);
1422 if(This->proj == D3DMatHandle)
1424 IWineD3DDevice_SetTransform(This->wineD3DDevice,
1425 WINED3DTS_PROJECTION,
1426 (WINED3DMATRIX *) D3DMatrix);
1429 LeaveCriticalSection(&ddraw_cs);
1430 return D3D_OK;
1433 /*****************************************************************************
1434 * IDirect3DDevice::SetMatrix
1436 * Returns the content of a D3DMATRIX handle
1438 * Version 1 only
1440 * Params:
1441 * D3DMatHandle: Matrix handle to read the content from
1442 * D3DMatrix: Address to store the content at
1444 * Returns:
1445 * D3D_OK on success
1446 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid or D3DMatrix is NULL
1448 *****************************************************************************/
1449 static HRESULT WINAPI
1450 IDirect3DDeviceImpl_1_GetMatrix(IDirect3DDevice *iface,
1451 D3DMATRIXHANDLE D3DMatHandle,
1452 D3DMATRIX *D3DMatrix)
1454 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1455 TRACE("(%p)->(%08x,%p)\n", This, D3DMatHandle, D3DMatrix);
1457 if(!D3DMatrix)
1458 return DDERR_INVALIDPARAMS;
1459 if(!D3DMatHandle)
1460 return DDERR_INVALIDPARAMS;
1462 EnterCriticalSection(&ddraw_cs);
1463 if(D3DMatHandle > This->numHandles)
1465 ERR("Handle %d out of range\n", D3DMatHandle);
1466 LeaveCriticalSection(&ddraw_cs);
1467 return DDERR_INVALIDPARAMS;
1469 else if(This->Handles[D3DMatHandle - 1].type != DDrawHandle_Matrix)
1471 ERR("Handle %d is not a matrix handle\n", D3DMatHandle);
1472 LeaveCriticalSection(&ddraw_cs);
1473 return DDERR_INVALIDPARAMS;
1476 /* The handle is simply a pointer to a D3DMATRIX structure */
1477 *D3DMatrix = *((D3DMATRIX *) This->Handles[D3DMatHandle - 1].ptr);
1479 LeaveCriticalSection(&ddraw_cs);
1480 return D3D_OK;
1483 /*****************************************************************************
1484 * IDirect3DDevice::DeleteMatrix
1486 * Destroys a Matrix handle. Frees the memory and unsets the handle data
1488 * Version 1 only
1490 * Params:
1491 * D3DMatHandle: Handle to destroy
1493 * Returns:
1494 * D3D_OK on success
1495 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid
1497 *****************************************************************************/
1498 static HRESULT WINAPI
1499 IDirect3DDeviceImpl_1_DeleteMatrix(IDirect3DDevice *iface,
1500 D3DMATRIXHANDLE D3DMatHandle)
1502 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1503 TRACE("(%p)->(%08x)\n", This, D3DMatHandle);
1505 if(!D3DMatHandle)
1506 return DDERR_INVALIDPARAMS;
1508 EnterCriticalSection(&ddraw_cs);
1509 if(D3DMatHandle > This->numHandles)
1511 ERR("Handle %d out of range\n", D3DMatHandle);
1512 LeaveCriticalSection(&ddraw_cs);
1513 return DDERR_INVALIDPARAMS;
1515 else if(This->Handles[D3DMatHandle - 1].type != DDrawHandle_Matrix)
1517 ERR("Handle %d is not a matrix handle\n", D3DMatHandle);
1518 LeaveCriticalSection(&ddraw_cs);
1519 return DDERR_INVALIDPARAMS;
1522 HeapFree(GetProcessHeap(), 0, This->Handles[D3DMatHandle - 1].ptr);
1523 This->Handles[D3DMatHandle - 1].ptr = NULL;
1524 This->Handles[D3DMatHandle - 1].type = DDrawHandle_Unknown;
1526 LeaveCriticalSection(&ddraw_cs);
1527 return D3D_OK;
1530 /*****************************************************************************
1531 * IDirect3DDevice7::BeginScene
1533 * This method must be called before any rendering is performed.
1534 * IDirect3DDevice::EndScene has to be called after the scene is complete
1536 * Version 1, 2, 3 and 7
1538 * Returns:
1539 * D3D_OK on success, for details see IWineD3DDevice::BeginScene
1540 * D3DERR_SCENE_IN_SCENE if WineD3D returns an error(Only in case of an already
1541 * started scene).
1543 *****************************************************************************/
1544 static HRESULT WINAPI
1545 IDirect3DDeviceImpl_7_BeginScene(IDirect3DDevice7 *iface)
1547 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1548 HRESULT hr;
1549 TRACE("(%p): Relay\n", This);
1551 EnterCriticalSection(&ddraw_cs);
1552 hr = IWineD3DDevice_BeginScene(This->wineD3DDevice);
1553 LeaveCriticalSection(&ddraw_cs);
1554 if(hr == WINED3D_OK) return D3D_OK;
1555 else return D3DERR_SCENE_IN_SCENE; /* TODO: Other possible causes of failure */
1558 static HRESULT WINAPI
1559 Thunk_IDirect3DDeviceImpl_3_BeginScene(IDirect3DDevice3 *iface)
1561 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1562 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1563 return IDirect3DDevice7_BeginScene(ICOM_INTERFACE(This, IDirect3DDevice7));
1566 static HRESULT WINAPI
1567 Thunk_IDirect3DDeviceImpl_2_BeginScene(IDirect3DDevice2 *iface)
1569 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1570 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1571 return IDirect3DDevice7_BeginScene(ICOM_INTERFACE(This, IDirect3DDevice7));
1574 static HRESULT WINAPI
1575 Thunk_IDirect3DDeviceImpl_1_BeginScene(IDirect3DDevice *iface)
1577 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1578 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1579 return IDirect3DDevice7_BeginScene(ICOM_INTERFACE(This, IDirect3DDevice7));
1582 /*****************************************************************************
1583 * IDirect3DDevice7::EndScene
1585 * Ends a scene that has been begun with IDirect3DDevice7::BeginScene.
1586 * This method must be called after rendering is finished.
1588 * Version 1, 2, 3 and 7
1590 * Returns:
1591 * D3D_OK on success, for details see IWineD3DDevice::EndScene
1592 * D3DERR_SCENE_NOT_IN_SCENE is returned if WineD3D returns an error. It does
1593 * that only if the scene was already ended.
1595 *****************************************************************************/
1596 static HRESULT WINAPI
1597 IDirect3DDeviceImpl_7_EndScene(IDirect3DDevice7 *iface)
1599 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1600 HRESULT hr;
1601 TRACE("(%p): Relay\n", This);
1603 EnterCriticalSection(&ddraw_cs);
1604 hr = IWineD3DDevice_EndScene(This->wineD3DDevice);
1605 LeaveCriticalSection(&ddraw_cs);
1606 if(hr == WINED3D_OK) return D3D_OK;
1607 else return D3DERR_SCENE_NOT_IN_SCENE;
1610 static HRESULT WINAPI
1611 Thunk_IDirect3DDeviceImpl_3_EndScene(IDirect3DDevice3 *iface)
1613 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1614 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1615 return IDirect3DDevice7_EndScene(ICOM_INTERFACE(This, IDirect3DDevice7));
1618 static HRESULT WINAPI
1619 Thunk_IDirect3DDeviceImpl_2_EndScene(IDirect3DDevice2 *iface)
1621 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1622 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1623 return IDirect3DDevice7_EndScene(ICOM_INTERFACE(This, IDirect3DDevice7));
1626 static HRESULT WINAPI
1627 Thunk_IDirect3DDeviceImpl_1_EndScene(IDirect3DDevice *iface)
1629 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1630 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1631 return IDirect3DDevice7_EndScene(ICOM_INTERFACE(This, IDirect3DDevice7));
1634 /*****************************************************************************
1635 * IDirect3DDevice7::GetDirect3D
1637 * Returns the IDirect3D(= interface to the DirectDraw object) used to create
1638 * this device.
1640 * Params:
1641 * Direct3D7: Address to store the interface pointer at
1643 * Returns:
1644 * D3D_OK on success
1645 * DDERR_INVALIDPARAMS if Direct3D7 == NULL
1647 *****************************************************************************/
1648 static HRESULT WINAPI
1649 IDirect3DDeviceImpl_7_GetDirect3D(IDirect3DDevice7 *iface,
1650 IDirect3D7 **Direct3D7)
1652 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1653 TRACE("(%p)->(%p)\n", This, Direct3D7);
1655 if(!Direct3D7)
1656 return DDERR_INVALIDPARAMS;
1658 *Direct3D7 = ICOM_INTERFACE(This->ddraw, IDirect3D7);
1659 IDirect3D7_AddRef(*Direct3D7);
1661 TRACE(" returning interface %p\n", *Direct3D7);
1662 return D3D_OK;
1665 static HRESULT WINAPI
1666 Thunk_IDirect3DDeviceImpl_3_GetDirect3D(IDirect3DDevice3 *iface,
1667 IDirect3D3 **Direct3D3)
1669 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1670 HRESULT ret;
1671 IDirect3D7 *ret_ptr;
1673 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Direct3D3);
1674 ret = IDirect3DDevice7_GetDirect3D(ICOM_INTERFACE(This, IDirect3DDevice7),
1675 &ret_ptr);
1676 if(ret != D3D_OK)
1677 return ret;
1678 *Direct3D3 = COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D7, IDirect3D3, ret_ptr);
1679 TRACE(" returning interface %p\n", *Direct3D3);
1680 return D3D_OK;
1683 static HRESULT WINAPI
1684 Thunk_IDirect3DDeviceImpl_2_GetDirect3D(IDirect3DDevice2 *iface,
1685 IDirect3D2 **Direct3D2)
1687 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1688 HRESULT ret;
1689 IDirect3D7 *ret_ptr;
1691 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Direct3D2);
1692 ret = IDirect3DDevice7_GetDirect3D(ICOM_INTERFACE(This, IDirect3DDevice7),
1693 &ret_ptr);
1694 if(ret != D3D_OK)
1695 return ret;
1696 *Direct3D2 = COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D7, IDirect3D2, ret_ptr);
1697 TRACE(" returning interface %p\n", *Direct3D2);
1698 return D3D_OK;
1701 static HRESULT WINAPI
1702 Thunk_IDirect3DDeviceImpl_1_GetDirect3D(IDirect3DDevice *iface,
1703 IDirect3D **Direct3D)
1705 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1706 HRESULT ret;
1707 IDirect3D7 *ret_ptr;
1709 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Direct3D);
1710 ret = IDirect3DDevice7_GetDirect3D(ICOM_INTERFACE(This, IDirect3DDevice7),
1711 &ret_ptr);
1712 if(ret != D3D_OK)
1713 return ret;
1714 *Direct3D = COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D7, IDirect3D, ret_ptr);
1715 TRACE(" returning interface %p\n", *Direct3D);
1716 return D3D_OK;
1719 /*****************************************************************************
1720 * IDirect3DDevice3::SetCurrentViewport
1722 * Sets a Direct3DViewport as the current viewport.
1723 * For the thunks note that all viewport interface versions are equal
1725 * Params:
1726 * Direct3DViewport3: The viewport to set
1728 * Version 2 and 3
1730 * Returns:
1731 * D3D_OK on success
1732 * (Is a NULL viewport valid?)
1734 *****************************************************************************/
1735 static HRESULT WINAPI
1736 IDirect3DDeviceImpl_3_SetCurrentViewport(IDirect3DDevice3 *iface,
1737 IDirect3DViewport3 *Direct3DViewport3)
1739 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1740 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport3);
1741 TRACE("(%p)->(%p)\n", This, Direct3DViewport3);
1743 EnterCriticalSection(&ddraw_cs);
1744 /* Do nothing if the specified viewport is the same as the current one */
1745 if (This->current_viewport == vp )
1747 LeaveCriticalSection(&ddraw_cs);
1748 return D3D_OK;
1751 /* Should check if the viewport was added or not */
1753 /* Release previous viewport and AddRef the new one */
1754 if (This->current_viewport)
1756 TRACE("ViewportImpl is at %p, interface is at %p\n", This->current_viewport, ICOM_INTERFACE(This->current_viewport, IDirect3DViewport3));
1757 IDirect3DViewport3_Release( ICOM_INTERFACE(This->current_viewport, IDirect3DViewport3) );
1759 IDirect3DViewport3_AddRef(Direct3DViewport3);
1761 /* Set this viewport as the current viewport */
1762 This->current_viewport = vp;
1764 /* Activate this viewport */
1765 This->current_viewport->active_device = This;
1766 This->current_viewport->activate(This->current_viewport);
1768 LeaveCriticalSection(&ddraw_cs);
1769 return D3D_OK;
1772 static HRESULT WINAPI
1773 Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport(IDirect3DDevice2 *iface,
1774 IDirect3DViewport2 *Direct3DViewport2)
1776 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1777 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport2);
1778 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
1779 return IDirect3DDevice3_SetCurrentViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
1780 ICOM_INTERFACE(vp, IDirect3DViewport3));
1783 /*****************************************************************************
1784 * IDirect3DDevice3::GetCurrentViewport
1786 * Returns the currently active viewport.
1788 * Version 2 and 3
1790 * Params:
1791 * Direct3DViewport3: Address to return the interface pointer at
1793 * Returns:
1794 * D3D_OK on success
1795 * DDERR_INVALIDPARAMS if Direct3DViewport == NULL
1797 *****************************************************************************/
1798 static HRESULT WINAPI
1799 IDirect3DDeviceImpl_3_GetCurrentViewport(IDirect3DDevice3 *iface,
1800 IDirect3DViewport3 **Direct3DViewport3)
1802 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1803 TRACE("(%p)->(%p)\n", This, Direct3DViewport3);
1805 if(!Direct3DViewport3)
1806 return DDERR_INVALIDPARAMS;
1808 EnterCriticalSection(&ddraw_cs);
1809 *Direct3DViewport3 = ICOM_INTERFACE(This->current_viewport, IDirect3DViewport3);
1811 /* AddRef the returned viewport */
1812 if(*Direct3DViewport3) IDirect3DViewport3_AddRef(*Direct3DViewport3);
1814 TRACE(" returning interface %p\n", *Direct3DViewport3);
1816 LeaveCriticalSection(&ddraw_cs);
1817 return D3D_OK;
1820 static HRESULT WINAPI
1821 Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport(IDirect3DDevice2 *iface,
1822 IDirect3DViewport2 **Direct3DViewport2)
1824 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1825 HRESULT hr;
1826 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, Direct3DViewport2);
1827 hr = IDirect3DDevice3_GetCurrentViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
1828 (IDirect3DViewport3 **) Direct3DViewport2);
1829 if(hr != D3D_OK) return hr;
1830 *Direct3DViewport2 = (IDirect3DViewport2 *) COM_INTERFACE_CAST(IDirect3DViewportImpl, IDirect3DViewport3, IDirect3DViewport3, *Direct3DViewport2);
1831 return D3D_OK;
1834 /*****************************************************************************
1835 * IDirect3DDevice7::SetRenderTarget
1837 * Sets the render target for the Direct3DDevice.
1838 * For the thunks note that IDirectDrawSurface7 == IDirectDrawSurface4 and
1839 * IDirectDrawSurface3 == IDirectDrawSurface
1841 * Version 2, 3 and 7
1843 * Params:
1844 * NewTarget: Pointer to an IDirectDrawSurface7 interface to set as the new
1845 * render target
1846 * Flags: Some flags
1848 * Returns:
1849 * D3D_OK on success, for details see IWineD3DDevice::SetRenderTarget
1851 *****************************************************************************/
1852 static HRESULT WINAPI
1853 IDirect3DDeviceImpl_7_SetRenderTarget(IDirect3DDevice7 *iface,
1854 IDirectDrawSurface7 *NewTarget,
1855 DWORD Flags)
1857 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1858 IDirectDrawSurfaceImpl *Target = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, NewTarget);
1859 HRESULT hr;
1860 TRACE("(%p)->(%p,%08x): Relay\n", This, NewTarget, Flags);
1862 EnterCriticalSection(&ddraw_cs);
1863 /* Flags: Not used */
1865 hr = IWineD3DDevice_SetRenderTarget(This->wineD3DDevice,
1867 Target ? Target->WineD3DSurface : NULL);
1868 if(hr != D3D_OK)
1870 LeaveCriticalSection(&ddraw_cs);
1871 return hr;
1873 IDirectDrawSurface7_AddRef(NewTarget);
1874 IDirectDrawSurface7_Release(ICOM_INTERFACE(This->target, IDirectDrawSurface7));
1875 This->target = Target;
1876 IDirect3DDeviceImpl_UpdateDepthStencil(This);
1877 LeaveCriticalSection(&ddraw_cs);
1878 return D3D_OK;
1881 static HRESULT WINAPI
1882 Thunk_IDirect3DDeviceImpl_3_SetRenderTarget(IDirect3DDevice3 *iface,
1883 IDirectDrawSurface4 *NewRenderTarget,
1884 DWORD Flags)
1886 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1887 IDirectDrawSurfaceImpl *Target = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, NewRenderTarget);
1888 TRACE_(ddraw_thunk)("(%p)->(%p,%08x) thunking to IDirect3DDevice7 interface.\n", This, Target, Flags);
1889 return IDirect3DDevice7_SetRenderTarget(ICOM_INTERFACE(This, IDirect3DDevice7),
1890 ICOM_INTERFACE(Target, IDirectDrawSurface7),
1891 Flags);
1894 static HRESULT WINAPI
1895 Thunk_IDirect3DDeviceImpl_2_SetRenderTarget(IDirect3DDevice2 *iface,
1896 IDirectDrawSurface *NewRenderTarget,
1897 DWORD Flags)
1899 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1900 IDirectDrawSurfaceImpl *Target = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface3, NewRenderTarget);
1901 TRACE_(ddraw_thunk)("(%p)->(%p,%08x) thunking to IDirect3DDevice7 interface.\n", This, Target, Flags);
1902 return IDirect3DDevice7_SetRenderTarget(ICOM_INTERFACE(This, IDirect3DDevice7),
1903 ICOM_INTERFACE(Target, IDirectDrawSurface7),
1904 Flags);
1907 /*****************************************************************************
1908 * IDirect3DDevice7::GetRenderTarget
1910 * Returns the current render target.
1911 * This is handled locally, because the WineD3D render target's parent
1912 * is an IParent
1914 * Version 2, 3 and 7
1916 * Params:
1917 * RenderTarget: Address to store the surface interface pointer
1919 * Returns:
1920 * D3D_OK on success
1921 * DDERR_INVALIDPARAMS if RenderTarget == NULL
1923 *****************************************************************************/
1924 static HRESULT WINAPI
1925 IDirect3DDeviceImpl_7_GetRenderTarget(IDirect3DDevice7 *iface,
1926 IDirectDrawSurface7 **RenderTarget)
1928 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1929 TRACE("(%p)->(%p): Relay\n", This, RenderTarget);
1931 if(!RenderTarget)
1932 return DDERR_INVALIDPARAMS;
1934 EnterCriticalSection(&ddraw_cs);
1935 *RenderTarget = ICOM_INTERFACE(This->target, IDirectDrawSurface7);
1936 IDirectDrawSurface7_AddRef(*RenderTarget);
1938 LeaveCriticalSection(&ddraw_cs);
1939 return D3D_OK;
1942 static HRESULT WINAPI
1943 Thunk_IDirect3DDeviceImpl_3_GetRenderTarget(IDirect3DDevice3 *iface,
1944 IDirectDrawSurface4 **RenderTarget)
1946 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1947 HRESULT hr;
1948 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, RenderTarget);
1949 hr = IDirect3DDevice7_GetRenderTarget(ICOM_INTERFACE(This, IDirect3DDevice7),
1950 (IDirectDrawSurface7 **) RenderTarget);
1951 if(hr != D3D_OK) return hr;
1952 *RenderTarget = (IDirectDrawSurface4 *) COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7, IDirectDrawSurface7, *RenderTarget);
1953 return D3D_OK;
1956 static HRESULT WINAPI
1957 Thunk_IDirect3DDeviceImpl_2_GetRenderTarget(IDirect3DDevice2 *iface,
1958 IDirectDrawSurface **RenderTarget)
1960 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1961 HRESULT hr;
1962 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, RenderTarget);
1963 hr = IDirect3DDevice7_GetRenderTarget(ICOM_INTERFACE(This, IDirect3DDevice7),
1964 (IDirectDrawSurface7 **) RenderTarget);
1965 if(hr != D3D_OK) return hr;
1966 *RenderTarget = (IDirectDrawSurface *) COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7, IDirectDrawSurface3, *RenderTarget);
1967 return D3D_OK;
1970 /*****************************************************************************
1971 * IDirect3DDevice3::Begin
1973 * Begins a description block of vertices. This is similar to glBegin()
1974 * and glEnd(). After a call to IDirect3DDevice3::End, the vertices
1975 * described with IDirect3DDevice::Vertex are drawn.
1977 * Version 2 and 3
1979 * Params:
1980 * PrimitiveType: The type of primitives to draw
1981 * VertexTypeDesc: A flexible vertex format description of the vertices
1982 * Flags: Some flags..
1984 * Returns:
1985 * D3D_OK on success
1987 *****************************************************************************/
1988 static HRESULT WINAPI
1989 IDirect3DDeviceImpl_3_Begin(IDirect3DDevice3 *iface,
1990 D3DPRIMITIVETYPE PrimitiveType,
1991 DWORD VertexTypeDesc,
1992 DWORD Flags)
1994 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1995 TRACE("(%p)->(%d,%d,%08x)\n", This, PrimitiveType, VertexTypeDesc, Flags);
1997 EnterCriticalSection(&ddraw_cs);
1998 This->primitive_type = PrimitiveType;
1999 This->vertex_type = VertexTypeDesc;
2000 This->render_flags = Flags;
2001 This->vertex_size = get_flexible_vertex_size(This->vertex_type);
2002 This->nb_vertices = 0;
2003 LeaveCriticalSection(&ddraw_cs);
2005 return D3D_OK;
2008 static HRESULT WINAPI
2009 Thunk_IDirect3DDeviceImpl_2_Begin(IDirect3DDevice2 *iface,
2010 D3DPRIMITIVETYPE d3dpt,
2011 D3DVERTEXTYPE dwVertexTypeDesc,
2012 DWORD dwFlags)
2014 DWORD FVF;
2015 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2016 TRACE_(ddraw_thunk)("(%p/%p)->(%08x,%08x,%08x): Thunking to IDirect3DDevice3\n", This, iface, d3dpt, dwVertexTypeDesc, dwFlags);
2018 switch(dwVertexTypeDesc)
2020 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
2021 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
2022 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
2023 default:
2024 ERR("Unexpected vertex type %d\n", dwVertexTypeDesc);
2025 return DDERR_INVALIDPARAMS; /* Should never happen */
2028 return IDirect3DDevice3_Begin(ICOM_INTERFACE(This, IDirect3DDevice3),
2029 d3dpt,
2030 FVF,
2031 dwFlags);
2034 /*****************************************************************************
2035 * IDirect3DDevice3::BeginIndexed
2037 * Draws primitives based on vertices in a vertex array which are specified
2038 * by indices.
2040 * Version 2 and 3
2042 * Params:
2043 * PrimitiveType: Primitive type to draw
2044 * VertexType: A FVF description of the vertex format
2045 * Vertices: pointer to an array containing the vertices
2046 * NumVertices: The number of vertices in the vertex array
2047 * Flags: Some flags ...
2049 * Returns:
2050 * D3D_OK, because it's a stub
2052 *****************************************************************************/
2053 static HRESULT WINAPI
2054 IDirect3DDeviceImpl_3_BeginIndexed(IDirect3DDevice3 *iface,
2055 D3DPRIMITIVETYPE PrimitiveType,
2056 DWORD VertexType,
2057 void *Vertices,
2058 DWORD NumVertices,
2059 DWORD Flags)
2061 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2062 FIXME("(%p)->(%08x,%08x,%p,%08x,%08x): stub!\n", This, PrimitiveType, VertexType, Vertices, NumVertices, Flags);
2063 return D3D_OK;
2067 static HRESULT WINAPI
2068 Thunk_IDirect3DDeviceImpl_2_BeginIndexed(IDirect3DDevice2 *iface,
2069 D3DPRIMITIVETYPE d3dptPrimitiveType,
2070 D3DVERTEXTYPE d3dvtVertexType,
2071 void *lpvVertices,
2072 DWORD dwNumVertices,
2073 DWORD dwFlags)
2075 DWORD FVF;
2076 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2077 TRACE_(ddraw_thunk)("(%p/%p)->(%08x,%08x,%p,%08x,%08x): Thunking to IDirect3DDevice3\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwNumVertices, dwFlags);
2079 switch(d3dvtVertexType)
2081 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
2082 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
2083 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
2084 default:
2085 ERR("Unexpected vertex type %d\n", d3dvtVertexType);
2086 return DDERR_INVALIDPARAMS; /* Should never happen */
2089 return IDirect3DDevice3_BeginIndexed(ICOM_INTERFACE(This,IDirect3DDevice3),
2090 d3dptPrimitiveType,
2091 FVF,
2092 lpvVertices,
2093 dwNumVertices,
2094 dwFlags);
2097 /*****************************************************************************
2098 * IDirect3DDevice3::Vertex
2100 * Draws a vertex as described by IDirect3DDevice3::Begin. It places all
2101 * drawn vertices in a vertex buffer. If the buffer is too small, its
2102 * size is increased.
2104 * Version 2 and 3
2106 * Params:
2107 * Vertex: Pointer to the vertex
2109 * Returns:
2110 * D3D_OK, on success
2111 * DDERR_INVALIDPARAMS if Vertex is NULL
2113 *****************************************************************************/
2114 static HRESULT WINAPI
2115 IDirect3DDeviceImpl_3_Vertex(IDirect3DDevice3 *iface,
2116 void *Vertex)
2118 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2119 TRACE("(%p)->(%p)\n", This, Vertex);
2121 if(!Vertex)
2122 return DDERR_INVALIDPARAMS;
2124 EnterCriticalSection(&ddraw_cs);
2125 if ((This->nb_vertices+1)*This->vertex_size > This->buffer_size)
2127 BYTE *old_buffer;
2128 This->buffer_size = This->buffer_size ? This->buffer_size * 2 : This->vertex_size * 3;
2129 old_buffer = This->vertex_buffer;
2130 This->vertex_buffer = HeapAlloc(GetProcessHeap(), 0, This->buffer_size);
2131 if (old_buffer)
2133 CopyMemory(This->vertex_buffer, old_buffer, This->nb_vertices * This->vertex_size);
2134 HeapFree(GetProcessHeap(), 0, old_buffer);
2138 CopyMemory(This->vertex_buffer + This->nb_vertices++ * This->vertex_size, Vertex, This->vertex_size);
2140 LeaveCriticalSection(&ddraw_cs);
2141 return D3D_OK;
2144 static HRESULT WINAPI
2145 Thunk_IDirect3DDeviceImpl_2_Vertex(IDirect3DDevice2 *iface,
2146 void *lpVertexType)
2148 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2149 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, lpVertexType);
2150 return IDirect3DDevice3_Vertex(ICOM_INTERFACE(This, IDirect3DDevice3),
2151 lpVertexType);
2154 /*****************************************************************************
2155 * IDirect3DDevice3::Index
2157 * Specifies an index to a vertex to be drawn. The vertex array has to
2158 * be specified with BeginIndexed first.
2160 * Parameters:
2161 * VertexIndex: The index of the vertex to draw
2163 * Returns:
2164 * D3D_OK because it's a stub
2166 *****************************************************************************/
2167 static HRESULT WINAPI
2168 IDirect3DDeviceImpl_3_Index(IDirect3DDevice3 *iface,
2169 WORD VertexIndex)
2171 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2172 FIXME("(%p)->(%04x): stub!\n", This, VertexIndex);
2173 return D3D_OK;
2176 static HRESULT WINAPI
2177 Thunk_IDirect3DDeviceImpl_2_Index(IDirect3DDevice2 *iface,
2178 WORD wVertexIndex)
2180 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2181 TRACE_(ddraw_thunk)("(%p)->(%04x) thunking to IDirect3DDevice3 interface.\n", This, wVertexIndex);
2182 return IDirect3DDevice3_Index(ICOM_INTERFACE(This, IDirect3DDevice3),
2183 wVertexIndex);
2186 /*****************************************************************************
2187 * IDirect3DDevice3::End
2189 * Ends a draw begun with IDirect3DDevice3::Begin or
2190 * IDirect3DDevice::BeginIndexed. The vertices specified with
2191 * IDirect3DDevice::Vertex or IDirect3DDevice::Index are drawn using
2192 * the IDirect3DDevice7::DrawPrimitive method. So far only
2193 * non-indexed mode is supported
2195 * Version 2 and 3
2197 * Params:
2198 * Flags: Some flags, as usual. Don't know which are defined
2200 * Returns:
2201 * The return value of IDirect3DDevice7::DrawPrimitive
2203 *****************************************************************************/
2204 static HRESULT WINAPI
2205 IDirect3DDeviceImpl_3_End(IDirect3DDevice3 *iface,
2206 DWORD Flags)
2208 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2209 TRACE("(%p)->(%08x)\n", This, Flags);
2211 return IDirect3DDevice7_DrawPrimitive(ICOM_INTERFACE(This, IDirect3DDevice7),
2212 This->primitive_type, This->vertex_type,
2213 This->vertex_buffer, This->nb_vertices,
2214 This->render_flags);
2217 static HRESULT WINAPI
2218 Thunk_IDirect3DDeviceImpl_2_End(IDirect3DDevice2 *iface,
2219 DWORD dwFlags)
2221 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2222 TRACE_(ddraw_thunk)("(%p)->(%08x) thunking to IDirect3DDevice3 interface.\n", This, dwFlags);
2223 return IDirect3DDevice3_End(ICOM_INTERFACE(This, IDirect3DDevice3),
2224 dwFlags);
2227 /*****************************************************************************
2228 * IDirect3DDevice7::GetRenderState
2230 * Returns the value of a render state. The possible render states are
2231 * defined in include/d3dtypes.h
2233 * Version 2, 3 and 7
2235 * Params:
2236 * RenderStateType: Render state to return the current setting of
2237 * Value: Address to store the value at
2239 * Returns:
2240 * D3D_OK on success, for details see IWineD3DDevice::GetRenderState
2241 * DDERR_INVALIDPARAMS if Value == NULL
2243 *****************************************************************************/
2244 static HRESULT WINAPI
2245 IDirect3DDeviceImpl_7_GetRenderState(IDirect3DDevice7 *iface,
2246 D3DRENDERSTATETYPE RenderStateType,
2247 DWORD *Value)
2249 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
2250 HRESULT hr;
2251 TRACE("(%p)->(%08x,%p): Relay\n", This, RenderStateType, Value);
2253 if(!Value)
2254 return DDERR_INVALIDPARAMS;
2256 EnterCriticalSection(&ddraw_cs);
2257 switch(RenderStateType)
2259 case D3DRENDERSTATE_TEXTUREHANDLE:
2261 /* This state is wrapped to SetTexture in SetRenderState, so
2262 * it has to be wrapped to GetTexture here
2264 IWineD3DBaseTexture *tex = NULL;
2265 *Value = 0;
2267 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice,
2269 &tex);
2271 if(hr == WINED3D_OK && tex)
2273 IDirectDrawSurface7 *parent = NULL;
2274 hr = IWineD3DBaseTexture_GetParent(tex,
2275 (IUnknown **) &parent);
2276 if(parent)
2278 /* The parent of the texture is the IDirectDrawSurface7 interface
2279 * of the ddraw surface
2281 IDirectDrawSurfaceImpl *texImpl = ICOM_OBJECT(IDirectDrawSurfaceImpl,
2282 IDirectDrawSurface7,
2283 parent);
2284 *Value = texImpl->Handle;
2285 IDirectDrawSurface7_Release(parent);
2287 IWineD3DBaseTexture_Release(tex);
2289 break;
2292 case D3DRENDERSTATE_TEXTUREMAG:
2294 WINED3DTEXTUREFILTERTYPE tex_mag;
2296 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2297 0, WINED3DSAMP_MAGFILTER,
2298 &tex_mag);
2300 switch (tex_mag)
2302 case WINED3DTEXF_POINT:
2303 *Value = D3DFILTER_NEAREST;
2304 break;
2305 case WINED3DTEXF_LINEAR:
2306 *Value = D3DFILTER_LINEAR;
2307 break;
2308 default:
2309 ERR("Unhandled texture mag %d !\n",tex_mag);
2310 *Value = 0;
2312 break;
2315 case D3DRENDERSTATE_TEXTUREMIN:
2317 WINED3DTEXTUREFILTERTYPE tex_min;
2319 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2320 0, WINED3DSAMP_MINFILTER,
2321 &tex_min);
2323 switch (tex_min)
2325 case WINED3DTEXF_POINT:
2326 *Value = D3DFILTER_NEAREST;
2327 break;
2328 case WINED3DTEXF_LINEAR:
2329 *Value = D3DFILTER_LINEAR;
2330 break;
2331 default:
2332 ERR("Unhandled texture mag %d !\n",tex_min);
2333 *Value = 0;
2335 break;
2338 case D3DRENDERSTATE_TEXTUREADDRESS:
2339 case D3DRENDERSTATE_TEXTUREADDRESSU:
2340 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2341 0, WINED3DSAMP_ADDRESSU,
2342 Value);
2343 break;
2344 case D3DRENDERSTATE_TEXTUREADDRESSV:
2345 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2346 0, WINED3DSAMP_ADDRESSV,
2347 Value);
2348 break;
2350 default:
2351 /* FIXME: Unhandled: D3DRENDERSTATE_STIPPLEPATTERN00 - 31 */
2352 hr = IWineD3DDevice_GetRenderState(This->wineD3DDevice,
2353 RenderStateType,
2354 Value);
2356 LeaveCriticalSection(&ddraw_cs);
2357 return hr;
2360 static HRESULT WINAPI
2361 Thunk_IDirect3DDeviceImpl_3_GetRenderState(IDirect3DDevice3 *iface,
2362 D3DRENDERSTATETYPE dwRenderStateType,
2363 DWORD *lpdwRenderState)
2365 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2366 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, dwRenderStateType, lpdwRenderState);
2367 return IDirect3DDevice7_GetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
2368 dwRenderStateType,
2369 lpdwRenderState);
2372 static HRESULT WINAPI
2373 IDirect3DDeviceImpl_2_GetRenderState(IDirect3DDevice2 *iface,
2374 D3DRENDERSTATETYPE dwRenderStateType,
2375 DWORD *lpdwRenderState)
2377 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2378 TRACE("(%p)->(%08x,%p): Relay\n", This, dwRenderStateType, lpdwRenderState);
2380 /* D3DRENDERSTATE_TEXTUREMAPBLEND is mapped to texture state stages in SetRenderState; reverse
2381 the mapping to get the value; other states relayed to IDirect3DDevice7::GetRenderState */
2382 switch(dwRenderStateType)
2384 case D3DRENDERSTATE_TEXTUREMAPBLEND:
2386 DWORD colorop, colorarg1, colorarg2;
2387 DWORD alphaop, alphaarg1, alphaarg2;
2389 EnterCriticalSection(&ddraw_cs);
2391 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, &colorop);
2392 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, &colorarg1);
2393 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, &colorarg2);
2394 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, &alphaop);
2395 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, &alphaarg1);
2396 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, &alphaarg2);
2398 if (colorop == WINED3DTOP_SELECTARG1 && colorarg1 == WINED3DTA_TEXTURE &&
2399 alphaop == WINED3DTOP_SELECTARG1 && alphaarg1 == WINED3DTA_TEXTURE)
2401 *lpdwRenderState = D3DTBLEND_DECAL;
2403 else if (colorop == WINED3DTOP_SELECTARG1 && colorarg1 == WINED3DTA_TEXTURE &&
2404 alphaop == WINED3DTOP_MODULATE && alphaarg1 == WINED3DTA_TEXTURE && alphaarg2 == WINED3DTA_CURRENT)
2406 *lpdwRenderState = D3DTBLEND_DECALALPHA;
2408 else if (colorop == WINED3DTOP_MODULATE && colorarg1 == WINED3DTA_TEXTURE && colorarg2 == WINED3DTA_CURRENT &&
2409 alphaop == WINED3DTOP_MODULATE && alphaarg1 == WINED3DTA_TEXTURE && alphaarg2 == WINED3DTA_CURRENT)
2411 *lpdwRenderState = D3DTBLEND_MODULATEALPHA;
2413 else
2415 HRESULT hr;
2416 BOOL tex_alpha = FALSE;
2417 IWineD3DBaseTexture *tex = NULL;
2418 WINED3DSURFACE_DESC desc;
2419 WINED3DFORMAT fmt;
2420 DDPIXELFORMAT ddfmt;
2422 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice,
2424 &tex);
2426 if(hr == WINED3D_OK && tex)
2428 memset(&desc, 0, sizeof(desc));
2429 desc.Format = &fmt;
2430 hr = IWineD3DTexture_GetLevelDesc((IWineD3DTexture*) tex, 0, &desc);
2431 if (SUCCEEDED(hr))
2433 ddfmt.dwSize = sizeof(ddfmt);
2434 PixelFormat_WineD3DtoDD(&ddfmt, fmt);
2435 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
2438 IWineD3DBaseTexture_Release(tex);
2441 if (!(colorop == WINED3DTOP_MODULATE && colorarg1 == WINED3DTA_TEXTURE && colorarg2 == WINED3DTA_CURRENT &&
2442 alphaop == WINED3DTOP_SELECTARG1 && alphaarg1 == (tex_alpha ? WINED3DTA_TEXTURE : WINED3DTA_CURRENT)))
2444 ERR("Unexpected texture stage state setup, returning D3DTBLEND_MODULATE - likely erroneous\n");
2447 *lpdwRenderState = D3DTBLEND_MODULATE;
2450 LeaveCriticalSection(&ddraw_cs);
2452 return D3D_OK;
2455 default:
2456 return IDirect3DDevice7_GetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
2457 dwRenderStateType,
2458 lpdwRenderState);
2462 /*****************************************************************************
2463 * IDirect3DDevice7::SetRenderState
2465 * Sets a render state. The possible render states are defined in
2466 * include/d3dtypes.h
2468 * Version 2, 3 and 7
2470 * Params:
2471 * RenderStateType: State to set
2472 * Value: Value to assign to that state
2474 * Returns:
2475 * D3D_OK on success,
2476 * for details see IWineD3DDevice::SetRenderState
2478 *****************************************************************************/
2479 static HRESULT WINAPI
2480 IDirect3DDeviceImpl_7_SetRenderState(IDirect3DDevice7 *iface,
2481 D3DRENDERSTATETYPE RenderStateType,
2482 DWORD Value)
2484 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
2485 HRESULT hr;
2486 TRACE("(%p)->(%08x,%d): Relay\n", This, RenderStateType, Value);
2488 EnterCriticalSection(&ddraw_cs);
2489 /* Some render states need special care */
2490 switch(RenderStateType)
2492 case D3DRENDERSTATE_TEXTUREHANDLE:
2494 if(Value == 0)
2496 hr = IWineD3DDevice_SetTexture(This->wineD3DDevice,
2498 NULL);
2499 break;
2502 if(Value > This->numHandles)
2504 FIXME("Specified handle %d out of range\n", Value);
2505 hr = DDERR_INVALIDPARAMS;
2506 break;
2508 if(This->Handles[Value - 1].type != DDrawHandle_Texture)
2510 FIXME("Handle %d isn't a texture handle\n", Value);
2511 hr = DDERR_INVALIDPARAMS;
2512 break;
2514 else
2516 IDirectDrawSurfaceImpl *surf = (IDirectDrawSurfaceImpl *) This->Handles[Value - 1].ptr;
2517 hr = IWineD3DDevice_SetTexture(This->wineD3DDevice,
2519 surf->wineD3DTexture);
2520 break;
2524 case D3DRENDERSTATE_TEXTUREMAG:
2526 WINED3DTEXTUREFILTERTYPE tex_mag = WINED3DTEXF_NONE;
2528 switch ((D3DTEXTUREFILTER) Value)
2530 case D3DFILTER_NEAREST:
2531 case D3DFILTER_LINEARMIPNEAREST:
2532 tex_mag = WINED3DTEXF_POINT;
2533 break;
2534 case D3DFILTER_LINEAR:
2535 case D3DFILTER_LINEARMIPLINEAR:
2536 tex_mag = WINED3DTEXF_LINEAR;
2537 break;
2538 default:
2539 ERR("Unhandled texture mag %d !\n",Value);
2542 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2543 0, WINED3DSAMP_MAGFILTER,
2544 tex_mag);
2545 break;
2548 case D3DRENDERSTATE_TEXTUREMIN:
2550 WINED3DTEXTUREFILTERTYPE tex_min = WINED3DTEXF_NONE;
2551 WINED3DTEXTUREFILTERTYPE tex_mip = WINED3DTEXF_NONE;
2553 switch ((D3DTEXTUREFILTER) Value)
2555 case D3DFILTER_NEAREST:
2556 tex_min = WINED3DTEXF_POINT;
2557 break;
2558 case D3DFILTER_LINEAR:
2559 tex_min = WINED3DTEXF_LINEAR;
2560 break;
2561 case D3DFILTER_MIPNEAREST:
2562 tex_min = WINED3DTEXF_NONE;
2563 tex_mip = WINED3DTEXF_POINT;
2564 break;
2565 case D3DFILTER_MIPLINEAR:
2566 tex_min = WINED3DTEXF_NONE;
2567 tex_mip = WINED3DTEXF_LINEAR;
2568 break;
2569 case D3DFILTER_LINEARMIPNEAREST:
2570 tex_min = WINED3DTEXF_POINT;
2571 tex_mip = WINED3DTEXF_LINEAR;
2572 break;
2573 case D3DFILTER_LINEARMIPLINEAR:
2574 tex_min = WINED3DTEXF_LINEAR;
2575 tex_mip = WINED3DTEXF_LINEAR;
2576 break;
2578 default:
2579 ERR("Unhandled texture min %d !\n",Value);
2582 IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2583 0, WINED3DSAMP_MIPFILTER,
2584 tex_mip);
2585 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2586 0, WINED3DSAMP_MINFILTER,
2587 tex_min);
2588 break;
2591 case D3DRENDERSTATE_TEXTUREADDRESS:
2592 IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2593 0, WINED3DSAMP_ADDRESSV,
2594 Value);
2595 /* Drop through */
2596 case D3DRENDERSTATE_TEXTUREADDRESSU:
2597 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2598 0, WINED3DSAMP_ADDRESSU,
2599 Value);
2600 break;
2601 case D3DRENDERSTATE_TEXTUREADDRESSV:
2602 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2603 0, WINED3DSAMP_ADDRESSV,
2604 Value);
2605 break;
2607 default:
2609 /* FIXME: Unhandled: D3DRENDERSTATE_STIPPLEPATTERN00 - 31 */
2611 hr = IWineD3DDevice_SetRenderState(This->wineD3DDevice,
2612 RenderStateType,
2613 Value);
2614 break;
2616 LeaveCriticalSection(&ddraw_cs);
2617 return hr;
2620 static HRESULT WINAPI
2621 Thunk_IDirect3DDeviceImpl_3_SetRenderState(IDirect3DDevice3 *iface,
2622 D3DRENDERSTATETYPE RenderStateType,
2623 DWORD Value)
2625 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2626 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, RenderStateType, Value);
2627 return IDirect3DDevice7_SetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
2628 RenderStateType,
2629 Value);
2632 static HRESULT WINAPI
2633 IDirect3DDeviceImpl_2_SetRenderState(IDirect3DDevice2 *iface,
2634 D3DRENDERSTATETYPE RenderStateType,
2635 DWORD Value)
2637 /* Note about D3DRENDERSTATE_TEXTUREMAPBLEND implementation: most of values
2638 for this state can be directly mapped to texture stage colorop and alphaop, but
2639 D3DTBLEND_MODULATE is tricky: it uses alpha from texture when available and alpha
2640 from diffuse otherwise. So changing the texture is monitored here to modify
2641 alphaarg when needed.
2643 Other states are relayed to IDirect3DDevice7
2645 Aliens vs Predator 1 depends on accurate D3DTBLEND_MODULATE emulation */
2647 HRESULT hr;
2648 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2649 TRACE("(%p)->(%08x,%d): Relay\n", This, RenderStateType, Value);
2651 switch(RenderStateType)
2653 case D3DRENDERSTATE_TEXTUREMAPBLEND:
2655 EnterCriticalSection(&ddraw_cs);
2657 switch ( (D3DTEXTUREBLEND) Value)
2659 case D3DTBLEND_MODULATE:
2661 BOOL tex_alpha = FALSE;
2662 IWineD3DBaseTexture *tex = NULL;
2663 WINED3DSURFACE_DESC desc;
2664 WINED3DFORMAT fmt;
2665 DDPIXELFORMAT ddfmt;
2667 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice,
2669 &tex);
2671 if(hr == WINED3D_OK && tex)
2673 memset(&desc, 0, sizeof(desc));
2674 desc.Format = &fmt;
2675 hr = IWineD3DTexture_GetLevelDesc((IWineD3DTexture*) tex, 0, &desc);
2676 if (SUCCEEDED(hr))
2678 ddfmt.dwSize = sizeof(ddfmt);
2679 PixelFormat_WineD3DtoDD(&ddfmt, fmt);
2680 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
2683 IWineD3DBaseTexture_Release(tex);
2686 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG1);
2687 if (tex_alpha)
2689 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2691 else
2693 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_CURRENT);
2696 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2697 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2698 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_MODULATE);
2700 break;
2703 case D3DTBLEND_MODULATEALPHA:
2704 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2705 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2706 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2707 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
2708 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_MODULATE);
2709 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_MODULATE);
2710 break;
2712 case D3DTBLEND_DECAL:
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_COLOROP, WINED3DTOP_SELECTARG1);
2716 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG1);
2717 break;
2719 case D3DTBLEND_DECALALPHA:
2720 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2721 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2722 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
2723 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_SELECTARG1);
2724 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_MODULATE);
2725 break;
2727 default:
2728 ERR("Unhandled texture environment %d !\n",Value);
2731 LeaveCriticalSection(&ddraw_cs);
2733 hr = D3D_OK;
2734 break;
2737 case D3DRENDERSTATE_TEXTUREHANDLE:
2739 DWORD texmapblend;
2741 IDirect3DDevice2_GetRenderState(iface, D3DRENDERSTATE_TEXTUREMAPBLEND, &texmapblend);
2743 hr = IDirect3DDevice7_SetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
2744 D3DRENDERSTATE_TEXTUREHANDLE,
2745 Value);
2747 if (texmapblend == D3DTBLEND_MODULATE)
2749 BOOL tex_alpha = FALSE;
2750 IWineD3DBaseTexture *tex = NULL;
2751 WINED3DSURFACE_DESC desc;
2752 WINED3DFORMAT fmt;
2753 DDPIXELFORMAT ddfmt;
2755 EnterCriticalSection(&ddraw_cs);
2757 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice,
2759 &tex);
2761 if(hr == WINED3D_OK && tex)
2763 memset(&desc, 0, sizeof(desc));
2764 desc.Format = &fmt;
2765 hr = IWineD3DTexture_GetLevelDesc((IWineD3DTexture*) tex, 0, &desc);
2766 if (SUCCEEDED(hr))
2768 ddfmt.dwSize = sizeof(ddfmt);
2769 PixelFormat_WineD3DtoDD(&ddfmt, fmt);
2770 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
2773 IWineD3DBaseTexture_Release(tex);
2776 /* alphaop is WINED3DTOP_SELECTARG1 if it's D3DTBLEND_MODULATE, so only modify alphaarg1 */
2777 if (tex_alpha)
2779 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2781 else
2783 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_CURRENT);
2786 LeaveCriticalSection(&ddraw_cs);
2789 break;
2792 default:
2793 hr = IDirect3DDevice7_SetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
2794 RenderStateType,
2795 Value);
2796 break;
2799 return hr;
2802 /*****************************************************************************
2803 * Direct3DDevice3::SetLightState
2805 * Sets a light state for Direct3DDevice3 and Direct3DDevice2. The
2806 * light states are forwarded to Direct3DDevice7 render states
2808 * Version 2 and 3
2810 * Params:
2811 * LightStateType: The light state to change
2812 * Value: The value to assign to that light state
2814 * Returns:
2815 * D3D_OK on success
2816 * DDERR_INVALIDPARAMS if the parameters were incorrect
2817 * Also check IDirect3DDevice7::SetRenderState
2819 *****************************************************************************/
2820 static HRESULT WINAPI
2821 IDirect3DDeviceImpl_3_SetLightState(IDirect3DDevice3 *iface,
2822 D3DLIGHTSTATETYPE LightStateType,
2823 DWORD Value)
2825 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2826 HRESULT hr;
2828 TRACE("(%p)->(%08x,%08x)\n", This, LightStateType, Value);
2830 if (!LightStateType && (LightStateType > D3DLIGHTSTATE_COLORVERTEX))
2832 TRACE("Unexpected Light State Type\n");
2833 return DDERR_INVALIDPARAMS;
2836 EnterCriticalSection(&ddraw_cs);
2837 if (LightStateType == D3DLIGHTSTATE_MATERIAL /* 1 */)
2839 IDirect3DMaterialImpl *mat;
2841 if(Value == 0) mat = NULL;
2842 else if(Value > This->numHandles)
2844 ERR("Material handle out of range(%d)\n", Value);
2845 LeaveCriticalSection(&ddraw_cs);
2846 return DDERR_INVALIDPARAMS;
2848 else if(This->Handles[Value - 1].type != DDrawHandle_Material)
2850 ERR("Invalid handle %d\n", Value);
2851 LeaveCriticalSection(&ddraw_cs);
2852 return DDERR_INVALIDPARAMS;
2854 else
2856 mat = (IDirect3DMaterialImpl *) This->Handles[Value - 1].ptr;
2859 if (mat != NULL)
2861 TRACE(" activating material %p.\n", mat);
2862 mat->activate(mat);
2864 else
2866 FIXME(" D3DLIGHTSTATE_MATERIAL called with NULL material !!!\n");
2868 This->material = Value;
2870 else if (LightStateType == D3DLIGHTSTATE_COLORMODEL /* 3 */)
2872 switch (Value)
2874 case D3DCOLOR_MONO:
2875 ERR("DDCOLOR_MONO should not happen!\n");
2876 break;
2877 case D3DCOLOR_RGB:
2878 /* We are already in this mode */
2879 TRACE("Setting color model to RGB (no-op).\n");
2880 break;
2881 default:
2882 ERR("Unknown color model!\n");
2883 LeaveCriticalSection(&ddraw_cs);
2884 return DDERR_INVALIDPARAMS;
2887 else
2889 D3DRENDERSTATETYPE rs;
2890 switch (LightStateType)
2892 case D3DLIGHTSTATE_AMBIENT: /* 2 */
2893 rs = D3DRENDERSTATE_AMBIENT;
2894 break;
2895 case D3DLIGHTSTATE_FOGMODE: /* 4 */
2896 rs = D3DRENDERSTATE_FOGVERTEXMODE;
2897 break;
2898 case D3DLIGHTSTATE_FOGSTART: /* 5 */
2899 rs = D3DRENDERSTATE_FOGSTART;
2900 break;
2901 case D3DLIGHTSTATE_FOGEND: /* 6 */
2902 rs = D3DRENDERSTATE_FOGEND;
2903 break;
2904 case D3DLIGHTSTATE_FOGDENSITY: /* 7 */
2905 rs = D3DRENDERSTATE_FOGDENSITY;
2906 break;
2907 case D3DLIGHTSTATE_COLORVERTEX: /* 8 */
2908 rs = D3DRENDERSTATE_COLORVERTEX;
2909 break;
2910 default:
2911 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType);
2912 LeaveCriticalSection(&ddraw_cs);
2913 return DDERR_INVALIDPARAMS;
2916 hr = IDirect3DDevice7_SetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
2918 Value);
2919 LeaveCriticalSection(&ddraw_cs);
2920 return hr;
2923 LeaveCriticalSection(&ddraw_cs);
2924 return D3D_OK;
2927 static HRESULT WINAPI
2928 Thunk_IDirect3DDeviceImpl_2_SetLightState(IDirect3DDevice2 *iface,
2929 D3DLIGHTSTATETYPE LightStateType,
2930 DWORD Value)
2932 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2933 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x) thunking to IDirect3DDevice3 interface.\n", This, LightStateType, Value);
2934 return IDirect3DDevice3_SetLightState(ICOM_INTERFACE(This, IDirect3DDevice3),
2935 LightStateType,
2936 Value);
2939 /*****************************************************************************
2940 * IDirect3DDevice3::GetLightState
2942 * Returns the current setting of a light state. The state is read from
2943 * the Direct3DDevice7 render state.
2945 * Version 2 and 3
2947 * Params:
2948 * LightStateType: The light state to return
2949 * Value: The address to store the light state setting at
2951 * Returns:
2952 * D3D_OK on success
2953 * DDDERR_INVALIDPARAMS if the parameters were incorrect
2954 * Also see IDirect3DDevice7::GetRenderState
2956 *****************************************************************************/
2957 static HRESULT WINAPI
2958 IDirect3DDeviceImpl_3_GetLightState(IDirect3DDevice3 *iface,
2959 D3DLIGHTSTATETYPE LightStateType,
2960 DWORD *Value)
2962 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2963 HRESULT hr;
2965 TRACE("(%p)->(%08x,%p)\n", This, LightStateType, Value);
2967 if (!LightStateType && (LightStateType > D3DLIGHTSTATE_COLORVERTEX))
2969 TRACE("Unexpected Light State Type\n");
2970 return DDERR_INVALIDPARAMS;
2973 if(!Value)
2974 return DDERR_INVALIDPARAMS;
2976 EnterCriticalSection(&ddraw_cs);
2977 if (LightStateType == D3DLIGHTSTATE_MATERIAL /* 1 */)
2979 *Value = This->material;
2981 else if (LightStateType == D3DLIGHTSTATE_COLORMODEL /* 3 */)
2983 *Value = D3DCOLOR_RGB;
2985 else
2987 D3DRENDERSTATETYPE rs;
2988 switch (LightStateType)
2990 case D3DLIGHTSTATE_AMBIENT: /* 2 */
2991 rs = D3DRENDERSTATE_AMBIENT;
2992 break;
2993 case D3DLIGHTSTATE_FOGMODE: /* 4 */
2994 rs = D3DRENDERSTATE_FOGVERTEXMODE;
2995 break;
2996 case D3DLIGHTSTATE_FOGSTART: /* 5 */
2997 rs = D3DRENDERSTATE_FOGSTART;
2998 break;
2999 case D3DLIGHTSTATE_FOGEND: /* 6 */
3000 rs = D3DRENDERSTATE_FOGEND;
3001 break;
3002 case D3DLIGHTSTATE_FOGDENSITY: /* 7 */
3003 rs = D3DRENDERSTATE_FOGDENSITY;
3004 break;
3005 case D3DLIGHTSTATE_COLORVERTEX: /* 8 */
3006 rs = D3DRENDERSTATE_COLORVERTEX;
3007 break;
3008 default:
3009 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType);
3010 LeaveCriticalSection(&ddraw_cs);
3011 return DDERR_INVALIDPARAMS;
3014 hr = IDirect3DDevice7_GetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
3016 Value);
3017 LeaveCriticalSection(&ddraw_cs);
3018 return hr;
3021 LeaveCriticalSection(&ddraw_cs);
3022 return D3D_OK;
3025 static HRESULT WINAPI
3026 Thunk_IDirect3DDeviceImpl_2_GetLightState(IDirect3DDevice2 *iface,
3027 D3DLIGHTSTATETYPE LightStateType,
3028 DWORD *Value)
3030 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3031 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice3 interface.\n", This, LightStateType, Value);
3032 return IDirect3DDevice3_GetLightState(ICOM_INTERFACE(This, IDirect3DDevice3),
3033 LightStateType,
3034 Value);
3037 /*****************************************************************************
3038 * IDirect3DDevice7::SetTransform
3040 * Assigns a D3DMATRIX to a transform type. The transform types are defined
3041 * in include/d3dtypes.h.
3042 * The D3DTRANSFORMSTATE_WORLD (=1) is translated to D3DTS_WORLDMATRIX(0)
3043 * (=255) for wined3d, because the 1 transform state was removed in d3d8
3044 * and WineD3D already understands the replacement D3DTS_WORLDMATRIX(0)
3046 * Version 2, 3 and 7
3048 * Params:
3049 * TransformStateType: transform state to set
3050 * Matrix: Matrix to assign to the state
3052 * Returns:
3053 * D3D_OK on success
3054 * DDERR_INVALIDPARAMS if Matrix == NULL
3055 * For details see IWineD3DDevice::SetTransform
3057 *****************************************************************************/
3058 static HRESULT WINAPI
3059 IDirect3DDeviceImpl_7_SetTransform(IDirect3DDevice7 *iface,
3060 D3DTRANSFORMSTATETYPE TransformStateType,
3061 D3DMATRIX *Matrix)
3063 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3064 D3DTRANSFORMSTATETYPE type = TransformStateType;
3065 HRESULT hr;
3066 TRACE("(%p)->(%08x,%p): Relay\n", This, TransformStateType, Matrix);
3068 switch(TransformStateType)
3070 case D3DTRANSFORMSTATE_WORLD : type = WINED3DTS_WORLDMATRIX(0); break;
3071 case D3DTRANSFORMSTATE_WORLD1: type = WINED3DTS_WORLDMATRIX(1); break;
3072 case D3DTRANSFORMSTATE_WORLD2: type = WINED3DTS_WORLDMATRIX(2); break;
3073 case D3DTRANSFORMSTATE_WORLD3: type = WINED3DTS_WORLDMATRIX(3); break;
3074 default: type = TransformStateType;
3077 if(!Matrix)
3078 return DDERR_INVALIDPARAMS;
3080 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3081 EnterCriticalSection(&ddraw_cs);
3082 hr = IWineD3DDevice_SetTransform(This->wineD3DDevice,
3083 type,
3084 (WINED3DMATRIX*) Matrix);
3085 LeaveCriticalSection(&ddraw_cs);
3086 return hr;
3089 static HRESULT WINAPI
3090 Thunk_IDirect3DDeviceImpl_3_SetTransform(IDirect3DDevice3 *iface,
3091 D3DTRANSFORMSTATETYPE TransformStateType,
3092 D3DMATRIX *D3DMatrix)
3094 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3095 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3096 return IDirect3DDevice7_SetTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
3097 TransformStateType,
3098 D3DMatrix);
3101 static HRESULT WINAPI
3102 Thunk_IDirect3DDeviceImpl_2_SetTransform(IDirect3DDevice2 *iface,
3103 D3DTRANSFORMSTATETYPE TransformStateType,
3104 D3DMATRIX *D3DMatrix)
3106 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3107 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3108 return IDirect3DDevice7_SetTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
3109 TransformStateType,
3110 D3DMatrix);
3113 /*****************************************************************************
3114 * IDirect3DDevice7::GetTransform
3116 * Returns the matrix assigned to a transform state
3117 * D3DTRANSFORMSTATE_WORLD is translated to D3DTS_WORLDMATRIX(0), see
3118 * SetTransform
3120 * Params:
3121 * TransformStateType: State to read the matrix from
3122 * Matrix: Address to store the matrix at
3124 * Returns:
3125 * D3D_OK on success
3126 * DDERR_INVALIDPARAMS if Matrix == NULL
3127 * For details, see IWineD3DDevice::GetTransform
3129 *****************************************************************************/
3130 static HRESULT WINAPI
3131 IDirect3DDeviceImpl_7_GetTransform(IDirect3DDevice7 *iface,
3132 D3DTRANSFORMSTATETYPE TransformStateType,
3133 D3DMATRIX *Matrix)
3135 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3136 D3DTRANSFORMSTATETYPE type = TransformStateType;
3137 HRESULT hr;
3138 TRACE("(%p)->(%08x,%p): Relay\n", This, TransformStateType, Matrix);
3140 switch(TransformStateType)
3142 case D3DTRANSFORMSTATE_WORLD : type = WINED3DTS_WORLDMATRIX(0); break;
3143 case D3DTRANSFORMSTATE_WORLD1: type = WINED3DTS_WORLDMATRIX(1); break;
3144 case D3DTRANSFORMSTATE_WORLD2: type = WINED3DTS_WORLDMATRIX(2); break;
3145 case D3DTRANSFORMSTATE_WORLD3: type = WINED3DTS_WORLDMATRIX(3); break;
3146 default: type = TransformStateType;
3149 if(!Matrix)
3150 return DDERR_INVALIDPARAMS;
3152 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3153 EnterCriticalSection(&ddraw_cs);
3154 hr = IWineD3DDevice_GetTransform(This->wineD3DDevice, type, (WINED3DMATRIX*) Matrix);
3155 LeaveCriticalSection(&ddraw_cs);
3156 return hr;
3159 static HRESULT WINAPI
3160 Thunk_IDirect3DDeviceImpl_3_GetTransform(IDirect3DDevice3 *iface,
3161 D3DTRANSFORMSTATETYPE TransformStateType,
3162 D3DMATRIX *D3DMatrix)
3164 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3165 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3166 return IDirect3DDevice7_GetTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
3167 TransformStateType,
3168 D3DMatrix);
3171 static HRESULT WINAPI
3172 Thunk_IDirect3DDeviceImpl_2_GetTransform(IDirect3DDevice2 *iface,
3173 D3DTRANSFORMSTATETYPE TransformStateType,
3174 D3DMATRIX *D3DMatrix)
3176 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3177 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3178 return IDirect3DDevice7_GetTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
3179 TransformStateType,
3180 D3DMatrix);
3183 /*****************************************************************************
3184 * IDirect3DDevice7::MultiplyTransform
3186 * Multiplies the already-set transform matrix of a transform state
3187 * with another matrix. For the world matrix, see SetTransform
3189 * Version 2, 3 and 7
3191 * Params:
3192 * TransformStateType: Transform state to multiply
3193 * D3DMatrix Matrix to multiply with.
3195 * Returns
3196 * D3D_OK on success
3197 * DDERR_INVALIDPARAMS if D3DMatrix is NULL
3198 * For details, see IWineD3DDevice::MultiplyTransform
3200 *****************************************************************************/
3201 static HRESULT WINAPI
3202 IDirect3DDeviceImpl_7_MultiplyTransform(IDirect3DDevice7 *iface,
3203 D3DTRANSFORMSTATETYPE TransformStateType,
3204 D3DMATRIX *D3DMatrix)
3206 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3207 HRESULT hr;
3208 D3DTRANSFORMSTATETYPE type;
3209 TRACE("(%p)->(%08x,%p): Relay\n", This, TransformStateType, D3DMatrix);
3211 switch(TransformStateType)
3213 case D3DTRANSFORMSTATE_WORLD : type = WINED3DTS_WORLDMATRIX(0); break;
3214 case D3DTRANSFORMSTATE_WORLD1: type = WINED3DTS_WORLDMATRIX(1); break;
3215 case D3DTRANSFORMSTATE_WORLD2: type = WINED3DTS_WORLDMATRIX(2); break;
3216 case D3DTRANSFORMSTATE_WORLD3: type = WINED3DTS_WORLDMATRIX(3); break;
3217 default: type = TransformStateType;
3220 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3221 EnterCriticalSection(&ddraw_cs);
3222 hr = IWineD3DDevice_MultiplyTransform(This->wineD3DDevice,
3223 type,
3224 (WINED3DMATRIX*) D3DMatrix);
3225 LeaveCriticalSection(&ddraw_cs);
3226 return hr;
3229 static HRESULT WINAPI
3230 Thunk_IDirect3DDeviceImpl_3_MultiplyTransform(IDirect3DDevice3 *iface,
3231 D3DTRANSFORMSTATETYPE TransformStateType,
3232 D3DMATRIX *D3DMatrix)
3234 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3235 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3236 return IDirect3DDevice7_MultiplyTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
3237 TransformStateType,
3238 D3DMatrix);
3241 static HRESULT WINAPI
3242 Thunk_IDirect3DDeviceImpl_2_MultiplyTransform(IDirect3DDevice2 *iface,
3243 D3DTRANSFORMSTATETYPE TransformStateType,
3244 D3DMATRIX *D3DMatrix)
3246 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3247 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3248 return IDirect3DDevice7_MultiplyTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
3249 TransformStateType,
3250 D3DMatrix);
3253 /*****************************************************************************
3254 * IDirect3DDevice7::DrawPrimitive
3256 * Draws primitives based on vertices in an application-provided pointer
3258 * Version 2, 3 and 7. The IDirect3DDevice2 thunk converts the fixed vertex type into
3259 * an FVF format for D3D7
3261 * Params:
3262 * PrimitiveType: The type of the primitives to draw
3263 * Vertex type: Flexible vertex format vertex description
3264 * Vertices: Pointer to the vertex array
3265 * VertexCount: The number of vertices to draw
3266 * Flags: As usual a few flags
3268 * Returns:
3269 * D3D_OK on success
3270 * DDERR_INVALIDPARAMS if Vertices is NULL
3271 * For details, see IWineD3DDevice::DrawPrimitiveUP
3273 *****************************************************************************/
3274 static HRESULT WINAPI
3275 IDirect3DDeviceImpl_7_DrawPrimitive(IDirect3DDevice7 *iface,
3276 D3DPRIMITIVETYPE PrimitiveType,
3277 DWORD VertexType,
3278 void *Vertices,
3279 DWORD VertexCount,
3280 DWORD Flags)
3282 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3283 UINT PrimitiveCount, stride;
3284 HRESULT hr;
3285 TRACE("(%p)->(%08x,%08x,%p,%08x,%08x): Relay!\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3287 if(!Vertices)
3288 return DDERR_INVALIDPARAMS;
3290 /* Get the vertex count */
3291 switch(PrimitiveType)
3293 case D3DPT_POINTLIST:
3294 PrimitiveCount = VertexCount;
3295 break;
3297 case D3DPT_LINELIST:
3298 PrimitiveCount = VertexCount / 2;
3299 break;
3301 case D3DPT_LINESTRIP:
3302 PrimitiveCount = VertexCount - 1;
3303 break;
3305 case D3DPT_TRIANGLELIST:
3306 PrimitiveCount = VertexCount / 3;
3307 break;
3309 case D3DPT_TRIANGLESTRIP:
3310 PrimitiveCount = VertexCount - 2;
3311 break;
3313 case D3DPT_TRIANGLEFAN:
3314 PrimitiveCount = VertexCount - 2;
3315 break;
3317 default:
3318 return DDERR_INVALIDPARAMS;
3321 /* Get the stride */
3322 stride = get_flexible_vertex_size(VertexType);
3324 /* Set the FVF */
3325 EnterCriticalSection(&ddraw_cs);
3326 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
3327 IDirectDrawImpl_FindDecl(This->ddraw, VertexType));
3328 if(hr != D3D_OK)
3330 LeaveCriticalSection(&ddraw_cs);
3331 return hr;
3334 /* This method translates to the user pointer draw of WineD3D */
3335 hr = IWineD3DDevice_DrawPrimitiveUP(This->wineD3DDevice,
3336 PrimitiveType,
3337 PrimitiveCount,
3338 Vertices,
3339 stride);
3340 LeaveCriticalSection(&ddraw_cs);
3341 return hr;
3344 static HRESULT WINAPI
3345 Thunk_IDirect3DDeviceImpl_3_DrawPrimitive(IDirect3DDevice3 *iface,
3346 D3DPRIMITIVETYPE PrimitiveType,
3347 DWORD VertexType,
3348 void *Vertices,
3349 DWORD VertexCount,
3350 DWORD Flags)
3352 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3353 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3354 return IDirect3DDevice7_DrawPrimitive(ICOM_INTERFACE(This, IDirect3DDevice7),
3355 PrimitiveType,
3356 VertexType,
3357 Vertices,
3358 VertexCount,
3359 Flags);
3362 static HRESULT WINAPI
3363 Thunk_IDirect3DDeviceImpl_2_DrawPrimitive(IDirect3DDevice2 *iface,
3364 D3DPRIMITIVETYPE PrimitiveType,
3365 D3DVERTEXTYPE VertexType,
3366 void *Vertices,
3367 DWORD VertexCount,
3368 DWORD Flags)
3370 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3371 DWORD FVF;
3372 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3374 switch(VertexType)
3376 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
3377 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
3378 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
3379 default:
3380 ERR("Unexpected vertex type %d\n", VertexType);
3381 return DDERR_INVALIDPARAMS; /* Should never happen */
3384 return IDirect3DDevice7_DrawPrimitive(ICOM_INTERFACE(This, IDirect3DDevice7),
3385 PrimitiveType,
3386 FVF,
3387 Vertices,
3388 VertexCount,
3389 Flags);
3392 /*****************************************************************************
3393 * IDirect3DDevice7::DrawIndexedPrimitive
3395 * Draws vertices from an application-provided pointer, based on the index
3396 * numbers in a WORD array.
3398 * Version 2, 3 and 7. The version 7 thunk translates the vertex type into
3399 * an FVF format for D3D7
3401 * Params:
3402 * PrimitiveType: The primitive type to draw
3403 * VertexType: The FVF vertex description
3404 * Vertices: Pointer to the vertex array
3405 * VertexCount: ?
3406 * Indices: Pointer to the index array
3407 * IndexCount: Number of indices = Number of vertices to draw
3408 * Flags: As usual, some flags
3410 * Returns:
3411 * D3D_OK on success
3412 * DDERR_INVALIDPARAMS if Vertices or Indices is NULL
3413 * For details, see IWineD3DDevice::DrawIndexedPrimitiveUP
3415 *****************************************************************************/
3416 static HRESULT WINAPI
3417 IDirect3DDeviceImpl_7_DrawIndexedPrimitive(IDirect3DDevice7 *iface,
3418 D3DPRIMITIVETYPE PrimitiveType,
3419 DWORD VertexType,
3420 void *Vertices,
3421 DWORD VertexCount,
3422 WORD *Indices,
3423 DWORD IndexCount,
3424 DWORD Flags)
3426 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3427 UINT PrimitiveCount = 0;
3428 HRESULT hr;
3429 TRACE("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x): Relay!\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3431 /* Get the primitive number */
3432 switch(PrimitiveType)
3434 case D3DPT_POINTLIST:
3435 PrimitiveCount = IndexCount;
3436 break;
3438 case D3DPT_LINELIST:
3439 PrimitiveCount = IndexCount / 2;
3440 break;
3442 case D3DPT_LINESTRIP:
3443 PrimitiveCount = IndexCount - 1;
3444 break;
3446 case D3DPT_TRIANGLELIST:
3447 PrimitiveCount = IndexCount / 3;
3448 break;
3450 case D3DPT_TRIANGLESTRIP:
3451 PrimitiveCount = IndexCount - 2;
3452 break;
3454 case D3DPT_TRIANGLEFAN:
3455 PrimitiveCount = IndexCount - 2;
3456 break;
3458 default:
3459 return DDERR_INVALIDPARAMS;
3462 /* Set the D3DDevice's FVF */
3463 EnterCriticalSection(&ddraw_cs);
3464 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
3465 IDirectDrawImpl_FindDecl(This->ddraw, VertexType));
3466 if(FAILED(hr))
3468 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr);
3469 LeaveCriticalSection(&ddraw_cs);
3470 return hr;
3473 hr = IWineD3DDevice_DrawIndexedPrimitiveUP(This->wineD3DDevice,
3474 PrimitiveType,
3475 0 /* MinVertexIndex */,
3476 VertexCount /* UINT NumVertexIndex */,
3477 PrimitiveCount,
3478 Indices,
3479 WINED3DFMT_INDEX16,
3480 Vertices,
3481 get_flexible_vertex_size(VertexType));
3482 LeaveCriticalSection(&ddraw_cs);
3483 return hr;
3486 static HRESULT WINAPI
3487 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive(IDirect3DDevice3 *iface,
3488 D3DPRIMITIVETYPE PrimitiveType,
3489 DWORD VertexType,
3490 void *Vertices,
3491 DWORD VertexCount,
3492 WORD *Indices,
3493 DWORD IndexCount,
3494 DWORD Flags)
3496 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3497 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3498 return IDirect3DDevice7_DrawIndexedPrimitive(ICOM_INTERFACE(This, IDirect3DDevice7),
3499 PrimitiveType,
3500 VertexType,
3501 Vertices,
3502 VertexCount,
3503 Indices,
3504 IndexCount,
3505 Flags);
3508 static HRESULT WINAPI
3509 Thunk_IDirect3DDeviceImpl_2_DrawIndexedPrimitive(IDirect3DDevice2 *iface,
3510 D3DPRIMITIVETYPE PrimitiveType,
3511 D3DVERTEXTYPE VertexType,
3512 void *Vertices,
3513 DWORD VertexCount,
3514 WORD *Indices,
3515 DWORD IndexCount,
3516 DWORD Flags)
3518 DWORD FVF;
3519 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3520 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3522 switch(VertexType)
3524 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
3525 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
3526 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
3527 default:
3528 ERR("Unexpected vertex type %d\n", VertexType);
3529 return DDERR_INVALIDPARAMS; /* Should never happen */
3532 return IDirect3DDevice7_DrawIndexedPrimitive(ICOM_INTERFACE(This, IDirect3DDevice7),
3533 PrimitiveType,
3534 FVF,
3535 Vertices,
3536 VertexCount,
3537 Indices,
3538 IndexCount,
3539 Flags);
3542 /*****************************************************************************
3543 * IDirect3DDevice7::SetClipStatus
3545 * Sets the clip status. This defines things as clipping conditions and
3546 * the extents of the clipping region.
3548 * Version 2, 3 and 7
3550 * Params:
3551 * ClipStatus:
3553 * Returns:
3554 * D3D_OK because it's a stub
3555 * (DDERR_INVALIDPARAMS if ClipStatus == NULL)
3557 *****************************************************************************/
3558 static HRESULT WINAPI
3559 IDirect3DDeviceImpl_7_SetClipStatus(IDirect3DDevice7 *iface,
3560 D3DCLIPSTATUS *ClipStatus)
3562 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3563 FIXME("(%p)->(%p): Stub!\n", This, ClipStatus);
3565 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them
3566 * Perhaps this needs a new data type and an additional IWineD3DDevice method
3568 /* return IWineD3DDevice_SetClipStatus(This->wineD3DDevice, ClipStatus);*/
3569 return D3D_OK;
3572 static HRESULT WINAPI
3573 Thunk_IDirect3DDeviceImpl_3_SetClipStatus(IDirect3DDevice3 *iface,
3574 D3DCLIPSTATUS *ClipStatus)
3576 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3577 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3578 return IDirect3DDevice7_SetClipStatus(ICOM_INTERFACE(This, IDirect3DDevice7),
3579 ClipStatus);
3582 static HRESULT WINAPI
3583 Thunk_IDirect3DDeviceImpl_2_SetClipStatus(IDirect3DDevice2 *iface,
3584 D3DCLIPSTATUS *ClipStatus)
3586 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3587 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3588 return IDirect3DDevice7_SetClipStatus(ICOM_INTERFACE(This, IDirect3DDevice7),
3589 ClipStatus);
3592 /*****************************************************************************
3593 * IDirect3DDevice7::GetClipStatus
3595 * Returns the clip status
3597 * Params:
3598 * ClipStatus: Address to write the clip status to
3600 * Returns:
3601 * D3D_OK because it's a stub
3603 *****************************************************************************/
3604 static HRESULT WINAPI
3605 IDirect3DDeviceImpl_7_GetClipStatus(IDirect3DDevice7 *iface,
3606 D3DCLIPSTATUS *ClipStatus)
3608 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3609 FIXME("(%p)->(%p): Stub!\n", This, ClipStatus);
3611 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them */
3612 /* return IWineD3DDevice_GetClipStatus(This->wineD3DDevice, ClipStatus);*/
3613 return D3D_OK;
3616 static HRESULT WINAPI
3617 Thunk_IDirect3DDeviceImpl_3_GetClipStatus(IDirect3DDevice3 *iface,
3618 D3DCLIPSTATUS *ClipStatus)
3620 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3621 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3622 return IDirect3DDevice7_GetClipStatus(ICOM_INTERFACE(This, IDirect3DDevice7),
3623 ClipStatus);
3626 static HRESULT WINAPI
3627 Thunk_IDirect3DDeviceImpl_2_GetClipStatus(IDirect3DDevice2 *iface,
3628 D3DCLIPSTATUS *ClipStatus)
3630 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3631 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3632 return IDirect3DDevice7_GetClipStatus(ICOM_INTERFACE(This, IDirect3DDevice7),
3633 ClipStatus);
3636 /*****************************************************************************
3637 * IDirect3DDevice::DrawPrimitiveStrided
3639 * Draws vertices described by a D3DDRAWPRIMITIVESTRIDEDDATA structure.
3641 * Version 3 and 7
3643 * Params:
3644 * PrimitiveType: The primitive type to draw
3645 * VertexType: The FVF description of the vertices to draw (for the stride??)
3646 * D3DDrawPrimStrideData: A D3DDRAWPRIMITIVESTRIDEDDATA structure describing
3647 * the vertex data locations
3648 * VertexCount: The number of vertices to draw
3649 * Flags: Some flags
3651 * Returns:
3652 * D3D_OK, because it's a stub
3653 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
3654 * (For details, see IWineD3DDevice::DrawPrimitiveStrided)
3656 *****************************************************************************/
3657 static HRESULT WINAPI
3658 IDirect3DDeviceImpl_7_DrawPrimitiveStrided(IDirect3DDevice7 *iface,
3659 D3DPRIMITIVETYPE PrimitiveType,
3660 DWORD VertexType,
3661 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3662 DWORD VertexCount,
3663 DWORD Flags)
3665 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3666 WineDirect3DVertexStridedData WineD3DStrided;
3667 int i;
3668 UINT PrimitiveCount;
3669 HRESULT hr;
3671 TRACE("(%p)->(%08x,%08x,%p,%08x,%08x): stub!\n", This, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
3673 memset(&WineD3DStrided, 0, sizeof(WineD3DStrided));
3674 /* Get the strided data right. the wined3d structure is a bit bigger
3675 * Watch out: The contents of the strided data are determined by the fvf,
3676 * not by the members set in D3DDrawPrimStrideData. So it's valid
3677 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
3678 * not set in the fvf.
3680 if(VertexType & D3DFVF_POSITION_MASK)
3682 WineD3DStrided.u.s.position.lpData = D3DDrawPrimStrideData->position.lpvData;
3683 WineD3DStrided.u.s.position.dwStride = D3DDrawPrimStrideData->position.dwStride;
3684 WineD3DStrided.u.s.position.dwType = WINED3DDECLTYPE_FLOAT3;
3685 if (VertexType & D3DFVF_XYZRHW)
3687 WineD3DStrided.u.s.position.dwType = WINED3DDECLTYPE_FLOAT4;
3688 WineD3DStrided.u.s.position_transformed = TRUE;
3689 } else
3690 WineD3DStrided.u.s.position_transformed = FALSE;
3693 if(VertexType & D3DFVF_NORMAL)
3695 WineD3DStrided.u.s.normal.lpData = D3DDrawPrimStrideData->normal.lpvData;
3696 WineD3DStrided.u.s.normal.dwStride = D3DDrawPrimStrideData->normal.dwStride;
3697 WineD3DStrided.u.s.normal.dwType = WINED3DDECLTYPE_FLOAT3;
3700 if(VertexType & D3DFVF_DIFFUSE)
3702 WineD3DStrided.u.s.diffuse.lpData = D3DDrawPrimStrideData->diffuse.lpvData;
3703 WineD3DStrided.u.s.diffuse.dwStride = D3DDrawPrimStrideData->diffuse.dwStride;
3704 WineD3DStrided.u.s.diffuse.dwType = WINED3DDECLTYPE_SHORT4;
3707 if(VertexType & D3DFVF_SPECULAR)
3709 WineD3DStrided.u.s.specular.lpData = D3DDrawPrimStrideData->specular.lpvData;
3710 WineD3DStrided.u.s.specular.dwStride = D3DDrawPrimStrideData->specular.dwStride;
3711 WineD3DStrided.u.s.specular.dwType = WINED3DDECLTYPE_SHORT4;
3714 for( i = 0; i < GET_TEXCOUNT_FROM_FVF(VertexType); i++)
3716 WineD3DStrided.u.s.texCoords[i].lpData = D3DDrawPrimStrideData->textureCoords[i].lpvData;
3717 WineD3DStrided.u.s.texCoords[i].dwStride = D3DDrawPrimStrideData->textureCoords[i].dwStride;
3718 switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i))
3720 case 1: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT1; break;
3721 case 2: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT2; break;
3722 case 3: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT3; break;
3723 case 4: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT4; break;
3724 default: ERR("Unexpected texture coordinate size %d\n",
3725 GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i));
3729 /* Get the primitive count */
3730 switch(PrimitiveType)
3732 case D3DPT_POINTLIST:
3733 PrimitiveCount = VertexCount;
3734 break;
3736 case D3DPT_LINELIST:
3737 PrimitiveCount = VertexCount / 2;
3738 break;
3740 case D3DPT_LINESTRIP:
3741 PrimitiveCount = VertexCount - 1;
3742 break;
3744 case D3DPT_TRIANGLELIST:
3745 PrimitiveCount = VertexCount / 3;
3746 break;
3748 case D3DPT_TRIANGLESTRIP:
3749 PrimitiveCount = VertexCount - 2;
3750 break;
3752 case D3DPT_TRIANGLEFAN:
3753 PrimitiveCount = VertexCount - 2;
3754 break;
3756 default: return DDERR_INVALIDPARAMS;
3759 /* WineD3D doesn't need the FVF here */
3760 EnterCriticalSection(&ddraw_cs);
3761 hr = IWineD3DDevice_DrawPrimitiveStrided(This->wineD3DDevice,
3762 PrimitiveType,
3763 PrimitiveCount,
3764 &WineD3DStrided);
3765 LeaveCriticalSection(&ddraw_cs);
3766 return hr;
3769 static HRESULT WINAPI
3770 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided(IDirect3DDevice3 *iface,
3771 D3DPRIMITIVETYPE PrimitiveType,
3772 DWORD VertexType,
3773 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3774 DWORD VertexCount,
3775 DWORD Flags)
3777 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3778 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
3779 return IDirect3DDevice7_DrawPrimitiveStrided(ICOM_INTERFACE(This, IDirect3DDevice7),
3780 PrimitiveType,
3781 VertexType,
3782 D3DDrawPrimStrideData,
3783 VertexCount,
3784 Flags);
3787 /*****************************************************************************
3788 * IDirect3DDevice7::DrawIndexedPrimitiveStrided
3790 * Draws primitives specified by strided data locations based on indices
3792 * Version 3 and 7
3794 * Params:
3795 * PrimitiveType:
3797 * Returns:
3798 * D3D_OK, because it's a stub
3799 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
3800 * (DDERR_INVALIDPARAMS if Indices is NULL)
3801 * (For more details, see IWineD3DDevice::DrawIndexedPrimitiveStrided)
3803 *****************************************************************************/
3804 static HRESULT WINAPI
3805 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(IDirect3DDevice7 *iface,
3806 D3DPRIMITIVETYPE PrimitiveType,
3807 DWORD VertexType,
3808 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3809 DWORD VertexCount,
3810 WORD *Indices,
3811 DWORD IndexCount,
3812 DWORD Flags)
3814 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3815 WineDirect3DVertexStridedData WineD3DStrided;
3816 int i;
3817 UINT PrimitiveCount;
3818 HRESULT hr;
3820 TRACE("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x)\n", This, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
3822 memset(&WineD3DStrided, 0, sizeof(WineD3DStrided));
3823 /* Get the strided data right. the wined3d structure is a bit bigger
3824 * Watch out: The contents of the strided data are determined by the fvf,
3825 * not by the members set in D3DDrawPrimStrideData. So it's valid
3826 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
3827 * not set in the fvf.
3829 if(VertexType & D3DFVF_POSITION_MASK)
3831 WineD3DStrided.u.s.position.lpData = D3DDrawPrimStrideData->position.lpvData;
3832 WineD3DStrided.u.s.position.dwStride = D3DDrawPrimStrideData->position.dwStride;
3833 WineD3DStrided.u.s.position.dwType = WINED3DDECLTYPE_FLOAT3;
3834 if (VertexType & D3DFVF_XYZRHW)
3836 WineD3DStrided.u.s.position.dwType = WINED3DDECLTYPE_FLOAT4;
3837 WineD3DStrided.u.s.position_transformed = TRUE;
3838 } else
3839 WineD3DStrided.u.s.position_transformed = FALSE;
3842 if(VertexType & D3DFVF_NORMAL)
3844 WineD3DStrided.u.s.normal.lpData = D3DDrawPrimStrideData->normal.lpvData;
3845 WineD3DStrided.u.s.normal.dwStride = D3DDrawPrimStrideData->normal.dwStride;
3846 WineD3DStrided.u.s.normal.dwType = WINED3DDECLTYPE_FLOAT3;
3849 if(VertexType & D3DFVF_DIFFUSE)
3851 WineD3DStrided.u.s.diffuse.lpData = D3DDrawPrimStrideData->diffuse.lpvData;
3852 WineD3DStrided.u.s.diffuse.dwStride = D3DDrawPrimStrideData->diffuse.dwStride;
3853 WineD3DStrided.u.s.diffuse.dwType = WINED3DDECLTYPE_SHORT4;
3856 if(VertexType & D3DFVF_SPECULAR)
3858 WineD3DStrided.u.s.specular.lpData = D3DDrawPrimStrideData->specular.lpvData;
3859 WineD3DStrided.u.s.specular.dwStride = D3DDrawPrimStrideData->specular.dwStride;
3860 WineD3DStrided.u.s.specular.dwType = WINED3DDECLTYPE_SHORT4;
3863 for( i = 0; i < GET_TEXCOUNT_FROM_FVF(VertexType); i++)
3865 WineD3DStrided.u.s.texCoords[i].lpData = D3DDrawPrimStrideData->textureCoords[i].lpvData;
3866 WineD3DStrided.u.s.texCoords[i].dwStride = D3DDrawPrimStrideData->textureCoords[i].dwStride;
3867 switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i))
3869 case 1: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT1; break;
3870 case 2: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT2; break;
3871 case 3: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT3; break;
3872 case 4: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT4; break;
3873 default: ERR("Unexpected texture coordinate size %d\n",
3874 GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i));
3878 /* Get the primitive count */
3879 switch(PrimitiveType)
3881 case D3DPT_POINTLIST:
3882 PrimitiveCount = IndexCount;
3883 break;
3885 case D3DPT_LINELIST:
3886 PrimitiveCount = IndexCount / 2;
3887 break;
3889 case D3DPT_LINESTRIP:
3890 PrimitiveCount = IndexCount - 1;
3891 break;
3893 case D3DPT_TRIANGLELIST:
3894 PrimitiveCount = IndexCount / 3;
3895 break;
3897 case D3DPT_TRIANGLESTRIP:
3898 PrimitiveCount = IndexCount - 2;
3899 break;
3901 case D3DPT_TRIANGLEFAN:
3902 PrimitiveCount = IndexCount - 2;
3903 break;
3905 default: return DDERR_INVALIDPARAMS;
3908 /* WineD3D doesn't need the FVF here */
3909 EnterCriticalSection(&ddraw_cs);
3910 hr = IWineD3DDevice_DrawIndexedPrimitiveStrided(This->wineD3DDevice,
3911 PrimitiveType,
3912 PrimitiveCount,
3913 &WineD3DStrided,
3914 VertexCount,
3915 Indices,
3916 WINED3DFMT_INDEX16);
3917 LeaveCriticalSection(&ddraw_cs);
3918 return hr;
3921 static HRESULT WINAPI
3922 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided(IDirect3DDevice3 *iface,
3923 D3DPRIMITIVETYPE PrimitiveType,
3924 DWORD VertexType,
3925 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3926 DWORD VertexCount,
3927 WORD *Indices,
3928 DWORD IndexCount,
3929 DWORD Flags)
3931 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3932 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
3933 return IDirect3DDevice7_DrawIndexedPrimitiveStrided(ICOM_INTERFACE(This, IDirect3DDevice7),
3934 PrimitiveType,
3935 VertexType,
3936 D3DDrawPrimStrideData,
3937 VertexCount,
3938 Indices,
3939 IndexCount,
3940 Flags);
3943 /*****************************************************************************
3944 * IDirect3DDevice7::DrawPrimitiveVB
3946 * Draws primitives from a vertex buffer to the screen.
3948 * Version 3 and 7
3950 * Params:
3951 * PrimitiveType: Type of primitive to be rendered.
3952 * D3DVertexBuf: Source Vertex Buffer
3953 * StartVertex: Index of the first vertex from the buffer to be rendered
3954 * NumVertices: Number of vertices to be rendered
3955 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
3957 * Return values
3958 * D3D_OK on success
3959 * DDERR_INVALIDPARAMS if D3DVertexBuf is NULL
3961 *****************************************************************************/
3962 static HRESULT WINAPI
3963 IDirect3DDeviceImpl_7_DrawPrimitiveVB(IDirect3DDevice7 *iface,
3964 D3DPRIMITIVETYPE PrimitiveType,
3965 IDirect3DVertexBuffer7 *D3DVertexBuf,
3966 DWORD StartVertex,
3967 DWORD NumVertices,
3968 DWORD Flags)
3970 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3971 IDirect3DVertexBufferImpl *vb = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, D3DVertexBuf);
3972 UINT PrimitiveCount;
3973 HRESULT hr;
3974 DWORD stride;
3975 WINED3DVERTEXBUFFER_DESC Desc;
3977 TRACE("(%p)->(%08x,%p,%08x,%08x,%08x)\n", This, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags);
3979 /* Sanity checks */
3980 if(!vb)
3982 ERR("(%p) No Vertex buffer specified\n", This);
3983 return DDERR_INVALIDPARAMS;
3986 /* Get the primitive count */
3987 switch(PrimitiveType)
3989 case D3DPT_POINTLIST:
3990 PrimitiveCount = NumVertices;
3991 break;
3993 case D3DPT_LINELIST:
3994 PrimitiveCount = NumVertices / 2;
3995 break;
3997 case D3DPT_LINESTRIP:
3998 PrimitiveCount = NumVertices - 1;
3999 break;
4001 case D3DPT_TRIANGLELIST:
4002 PrimitiveCount = NumVertices / 3;
4003 break;
4005 case D3DPT_TRIANGLESTRIP:
4006 PrimitiveCount = NumVertices - 2;
4007 break;
4009 case D3DPT_TRIANGLEFAN:
4010 PrimitiveCount = NumVertices - 2;
4011 break;
4013 default:
4014 return DDERR_INVALIDPARAMS;
4017 /* Get the FVF of the vertex buffer, and its stride */
4018 EnterCriticalSection(&ddraw_cs);
4019 hr = IWineD3DVertexBuffer_GetDesc(vb->wineD3DVertexBuffer,
4020 &Desc);
4021 if(hr != D3D_OK)
4023 ERR("(%p) IWineD3DVertexBuffer::GetDesc failed with hr = %08x\n", This, hr);
4024 LeaveCriticalSection(&ddraw_cs);
4025 return hr;
4027 stride = get_flexible_vertex_size(Desc.FVF);
4029 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
4030 vb->wineD3DVertexDeclaration);
4031 if(FAILED(hr))
4033 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr);
4034 LeaveCriticalSection(&ddraw_cs);
4035 return hr;
4038 /* Set the vertex stream source */
4039 hr = IWineD3DDevice_SetStreamSource(This->wineD3DDevice,
4040 0 /* StreamNumber */,
4041 vb->wineD3DVertexBuffer,
4042 0 /* StartVertex - we pass this to DrawPrimitive */,
4043 stride);
4044 if(hr != D3D_OK)
4046 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This, hr);
4047 LeaveCriticalSection(&ddraw_cs);
4048 return hr;
4051 /* Now draw the primitives */
4052 hr = IWineD3DDevice_DrawPrimitive(This->wineD3DDevice,
4053 PrimitiveType,
4054 StartVertex,
4055 PrimitiveCount);
4056 LeaveCriticalSection(&ddraw_cs);
4057 return hr;
4060 static HRESULT WINAPI
4061 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB(IDirect3DDevice3 *iface,
4062 D3DPRIMITIVETYPE PrimitiveType,
4063 IDirect3DVertexBuffer *D3DVertexBuf,
4064 DWORD StartVertex,
4065 DWORD NumVertices,
4066 DWORD Flags)
4068 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4069 IDirect3DVertexBufferImpl *vb = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, D3DVertexBuf);
4070 TRACE_(ddraw_thunk)("(%p)->(%08x,%p,%08x,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, vb, StartVertex, NumVertices, Flags);
4071 return IDirect3DDevice7_DrawPrimitiveVB(ICOM_INTERFACE(This, IDirect3DDevice7),
4072 PrimitiveType,
4073 ICOM_INTERFACE(vb, IDirect3DVertexBuffer7),
4074 StartVertex,
4075 NumVertices,
4076 Flags);
4080 /*****************************************************************************
4081 * IDirect3DDevice7::DrawIndexedPrimitiveVB
4083 * Draws primitives from a vertex buffer to the screen
4085 * Params:
4086 * PrimitiveType: Type of primitive to be rendered.
4087 * D3DVertexBuf: Source Vertex Buffer
4088 * StartVertex: Index of the first vertex from the buffer to be rendered
4089 * NumVertices: Number of vertices to be rendered
4090 * Indices: Array of DWORDs used to index into the Vertices
4091 * IndexCount: Number of indices in Indices
4092 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4094 * Return values
4096 *****************************************************************************/
4097 static HRESULT WINAPI
4098 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(IDirect3DDevice7 *iface,
4099 D3DPRIMITIVETYPE PrimitiveType,
4100 IDirect3DVertexBuffer7 *D3DVertexBuf,
4101 DWORD StartVertex,
4102 DWORD NumVertices,
4103 WORD *Indices,
4104 DWORD IndexCount,
4105 DWORD Flags)
4107 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4108 IDirect3DVertexBufferImpl *vb = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, D3DVertexBuf);
4109 DWORD stride;
4110 UINT PrimitiveCount;
4111 WORD *LockedIndices;
4112 HRESULT hr;
4113 WINED3DVERTEXBUFFER_DESC Desc;
4115 TRACE("(%p)->(%08x,%p,%d,%d,%p,%d,%08x)\n", This, PrimitiveType, vb, StartVertex, NumVertices, Indices, IndexCount, Flags);
4117 /* Steps:
4118 * 1) Calculate some things: Vertex count -> Primitive count, stride, ...
4119 * 2) Upload the Indices to the index buffer
4120 * 3) Set the index source
4121 * 4) Set the Vertex Buffer as the Stream source
4122 * 5) Call IWineD3DDevice::DrawIndexedPrimitive
4125 /* Get the primitive count */
4126 switch(PrimitiveType)
4128 case D3DPT_POINTLIST:
4129 PrimitiveCount = IndexCount;
4130 break;
4132 case D3DPT_LINELIST:
4133 PrimitiveCount = IndexCount / 2;
4134 break;
4136 case D3DPT_LINESTRIP:
4137 PrimitiveCount = IndexCount - 1;
4138 break;
4140 case D3DPT_TRIANGLELIST:
4141 PrimitiveCount = IndexCount / 3;
4142 break;
4144 case D3DPT_TRIANGLESTRIP:
4145 PrimitiveCount = IndexCount - 2;
4146 break;
4148 case D3DPT_TRIANGLEFAN:
4149 PrimitiveCount = IndexCount - 2;
4150 break;
4152 default: return DDERR_INVALIDPARAMS;
4155 EnterCriticalSection(&ddraw_cs);
4156 /* Get the FVF of the vertex buffer, and its stride */
4157 hr = IWineD3DVertexBuffer_GetDesc(vb->wineD3DVertexBuffer,
4158 &Desc);
4159 if(hr != D3D_OK)
4161 ERR("(%p) IWineD3DVertexBuffer::GetDesc failed with hr = %08x\n", This, hr);
4162 LeaveCriticalSection(&ddraw_cs);
4163 return hr;
4165 stride = get_flexible_vertex_size(Desc.FVF);
4166 TRACE("Vertex buffer FVF = %08x, stride=%d\n", Desc.FVF, stride);
4168 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
4169 vb->wineD3DVertexDeclaration);
4170 if(FAILED(hr))
4172 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr);
4173 LeaveCriticalSection(&ddraw_cs);
4174 return hr;
4177 /* copy the index stream into the index buffer.
4178 * A new IWineD3DDevice method could be created
4179 * which takes an user pointer containing the indices
4180 * or a SetData-Method for the index buffer, which
4181 * overrides the index buffer data with our pointer.
4183 hr = IWineD3DIndexBuffer_Lock(This->indexbuffer,
4184 0 /* OffSetToLock */,
4185 IndexCount * sizeof(WORD),
4186 (BYTE **) &LockedIndices,
4187 0 /* Flags */);
4188 assert(IndexCount < 0x100000);
4189 if(hr != D3D_OK)
4191 ERR("(%p) IWineD3DIndexBuffer::Lock failed with hr = %08x\n", This, hr);
4192 LeaveCriticalSection(&ddraw_cs);
4193 return hr;
4195 memcpy(LockedIndices, Indices, IndexCount * sizeof(WORD));
4196 hr = IWineD3DIndexBuffer_Unlock(This->indexbuffer);
4197 if(hr != D3D_OK)
4199 ERR("(%p) IWineD3DIndexBuffer::Unlock failed with hr = %08x\n", This, hr);
4200 LeaveCriticalSection(&ddraw_cs);
4201 return hr;
4204 /* Set the index stream */
4205 IWineD3DDevice_SetBaseVertexIndex(This->wineD3DDevice, StartVertex);
4206 hr = IWineD3DDevice_SetIndices(This->wineD3DDevice, This->indexbuffer);
4208 /* Set the vertex stream source */
4209 hr = IWineD3DDevice_SetStreamSource(This->wineD3DDevice,
4210 0 /* StreamNumber */,
4211 vb->wineD3DVertexBuffer,
4212 0 /* offset, we pass this to DrawIndexedPrimitive */,
4213 stride);
4214 if(hr != D3D_OK)
4216 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This, hr);
4217 LeaveCriticalSection(&ddraw_cs);
4218 return hr;
4222 hr = IWineD3DDevice_DrawIndexedPrimitive(This->wineD3DDevice,
4223 PrimitiveType,
4224 0 /* minIndex */,
4225 NumVertices,
4226 0 /* StartIndex */,
4227 PrimitiveCount);
4229 LeaveCriticalSection(&ddraw_cs);
4230 return hr;
4233 static HRESULT WINAPI
4234 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB(IDirect3DDevice3 *iface,
4235 D3DPRIMITIVETYPE PrimitiveType,
4236 IDirect3DVertexBuffer *D3DVertexBuf,
4237 WORD *Indices,
4238 DWORD IndexCount,
4239 DWORD Flags)
4241 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4242 IDirect3DVertexBufferImpl *VB = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, D3DVertexBuf);
4243 TRACE_(ddraw_thunk)("(%p)->(%08x,%p,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VB, Indices, IndexCount, Flags);
4245 return IDirect3DDevice7_DrawIndexedPrimitiveVB(ICOM_INTERFACE(This, IDirect3DDevice7),
4246 PrimitiveType,
4247 ICOM_INTERFACE(VB, IDirect3DVertexBuffer7),
4249 IndexCount,
4250 Indices,
4251 IndexCount,
4252 Flags);
4255 /*****************************************************************************
4256 * IDirect3DDevice7::ComputeSphereVisibility
4258 * Calculates the visibility of spheres in the current viewport. The spheres
4259 * are passed in the Centers and Radii arrays, the results are passed back
4260 * in the ReturnValues array. Return values are either completely visible,
4261 * partially visible or completely invisible.
4262 * The return value consist of a combination of D3DCLIP_* flags, or it's
4263 * 0 if the sphere is completely visible(according to the SDK, not checked)
4265 * Sounds like an overdose of math ;)
4267 * Version 3 and 7
4269 * Params:
4270 * Centers: Array containing the sphere centers
4271 * Radii: Array containing the sphere radii
4272 * NumSpheres: The number of centers and radii in the arrays
4273 * Flags: Some flags
4274 * ReturnValues: Array to write the results to
4276 * Returns:
4277 * D3D_OK because it's a stub
4278 * (DDERR_INVALIDPARAMS if Centers, Radii or ReturnValues are NULL)
4279 * (D3DERR_INVALIDMATRIX if the combined world, view and proj matrix
4280 * is singular)
4282 *****************************************************************************/
4283 static HRESULT WINAPI
4284 IDirect3DDeviceImpl_7_ComputeSphereVisibility(IDirect3DDevice7 *iface,
4285 D3DVECTOR *Centers,
4286 D3DVALUE *Radii,
4287 DWORD NumSpheres,
4288 DWORD Flags,
4289 DWORD *ReturnValues)
4291 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4292 FIXME("(%p)->(%p,%p,%08x,%08x,%p): stub!\n", This, Centers, Radii, NumSpheres, Flags, ReturnValues);
4294 /* the DirectX 7 sdk says that the visibility is computed by
4295 * back-transforming the viewing frustum to model space
4296 * using the inverse of the combined world, view and projection
4297 * matrix. If the matrix can't be reversed, D3DERR_INVALIDMATRIX
4298 * is returned.
4300 * Basic implementation idea:
4301 * 1) Check if the center is in the viewing frustum
4302 * 2) Cut the sphere with the planes of the viewing
4303 * frustum
4305 * ->Center inside the frustum, no intersections:
4306 * Fully visible
4307 * ->Center outside the frustum, no intersections:
4308 * Not visible
4309 * ->Some intersections: Partially visible
4311 * Implement this call in WineD3D. Either implement the
4312 * matrix and vector stuff in WineD3D, or use some external
4313 * math library.
4316 return D3D_OK;
4319 static HRESULT WINAPI
4320 Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility(IDirect3DDevice3 *iface,
4321 D3DVECTOR *Centers,
4322 D3DVALUE *Radii,
4323 DWORD NumSpheres,
4324 DWORD Flags,
4325 DWORD *ReturnValues)
4327 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4328 TRACE_(ddraw_thunk)("(%p)->(%p,%p,%08x,%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, Centers, Radii, NumSpheres, Flags, ReturnValues);
4329 return IDirect3DDevice7_ComputeSphereVisibility(ICOM_INTERFACE(This, IDirect3DDevice7),
4330 Centers,
4331 Radii,
4332 NumSpheres,
4333 Flags,
4334 ReturnValues);
4337 /*****************************************************************************
4338 * IDirect3DDevice7::GetTexture
4340 * Returns the texture interface handle assigned to a texture stage.
4341 * The returned texture is AddRefed. This is taken from old ddraw,
4342 * not checked in Windows.
4344 * Version 3 and 7
4346 * Params:
4347 * Stage: Texture stage to read the texture from
4348 * Texture: Address to store the interface pointer at
4350 * Returns:
4351 * D3D_OK on success
4352 * DDERR_INVALIDPARAMS if Texture is NULL
4353 * For details, see IWineD3DDevice::GetTexture
4355 *****************************************************************************/
4356 static HRESULT WINAPI
4357 IDirect3DDeviceImpl_7_GetTexture(IDirect3DDevice7 *iface,
4358 DWORD Stage,
4359 IDirectDrawSurface7 **Texture)
4361 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4362 IWineD3DBaseTexture *Surf;
4363 HRESULT hr;
4364 TRACE("(%p)->(%d,%p): Relay\n", This, Stage, Texture);
4366 if(!Texture)
4368 TRACE("Texture == NULL, failing with DDERR_INVALIDPARAMS\n");
4369 return DDERR_INVALIDPARAMS;
4372 EnterCriticalSection(&ddraw_cs);
4373 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice, Stage, &Surf);
4374 if( (hr != D3D_OK) || (!Surf) )
4376 *Texture = NULL;
4377 LeaveCriticalSection(&ddraw_cs);
4378 return hr;
4381 /* GetParent AddRef()s, which is perfectly OK.
4382 * We have passed the IDirectDrawSurface7 interface to WineD3D, so that's OK too.
4384 hr = IWineD3DBaseTexture_GetParent(Surf,
4385 (IUnknown **) Texture);
4386 LeaveCriticalSection(&ddraw_cs);
4387 return hr;
4390 static HRESULT WINAPI
4391 Thunk_IDirect3DDeviceImpl_3_GetTexture(IDirect3DDevice3 *iface,
4392 DWORD Stage,
4393 IDirect3DTexture2 **Texture2)
4395 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4396 HRESULT ret;
4397 IDirectDrawSurface7 *ret_val;
4399 TRACE_(ddraw_thunk)("(%p)->(%d,%p) thunking to IDirect3DDevice7 interface.\n", This, Stage, Texture2);
4400 ret = IDirect3DDevice7_GetTexture(ICOM_INTERFACE(This, IDirect3DDevice7),
4401 Stage,
4402 &ret_val);
4404 *Texture2 = COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7, IDirect3DTexture2, ret_val);
4406 TRACE_(ddraw_thunk)(" returning interface %p.\n", *Texture2);
4408 return ret;
4411 /*****************************************************************************
4412 * IDirect3DDevice7::SetTexture
4414 * Assigns a texture to a texture stage. Is the texture AddRef-ed?
4416 * Version 3 and 7
4418 * Params:
4419 * Stage: The stage to assign the texture to
4420 * Texture: Interface pointer to the texture surface
4422 * Returns
4423 * D3D_OK on success
4424 * For details, see IWineD3DDevice::SetTexture
4426 *****************************************************************************/
4427 static HRESULT WINAPI
4428 IDirect3DDeviceImpl_7_SetTexture(IDirect3DDevice7 *iface,
4429 DWORD Stage,
4430 IDirectDrawSurface7 *Texture)
4432 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4433 IDirectDrawSurfaceImpl *surf = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, Texture);
4434 HRESULT hr;
4435 TRACE("(%p)->(%08x,%p): Relay!\n", This, Stage, surf);
4437 /* Texture may be NULL here */
4438 EnterCriticalSection(&ddraw_cs);
4439 hr = IWineD3DDevice_SetTexture(This->wineD3DDevice,
4440 Stage,
4441 surf ? surf->wineD3DTexture : NULL);
4442 LeaveCriticalSection(&ddraw_cs);
4443 return hr;
4446 static HRESULT WINAPI
4447 Thunk_IDirect3DDeviceImpl_3_SetTexture(IDirect3DDevice3 *iface,
4448 DWORD Stage,
4449 IDirect3DTexture2 *Texture2)
4451 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4452 IDirectDrawSurfaceImpl *tex = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture2, Texture2);
4453 TRACE_(ddraw_thunk)("(%p)->(%d,%p) thunking to IDirect3DDevice7 interface.\n", This, Stage, tex);
4454 return IDirect3DDevice7_SetTexture(ICOM_INTERFACE(This, IDirect3DDevice7),
4455 Stage,
4456 ICOM_INTERFACE(tex, IDirectDrawSurface7));
4459 /*****************************************************************************
4460 * IDirect3DDevice7::GetTextureStageState
4462 * Retrieves a state from a texture stage.
4464 * Version 3 and 7
4466 * Params:
4467 * Stage: The stage to retrieve the state from
4468 * TexStageStateType: The state type to retrieve
4469 * State: Address to store the state's value at
4471 * Returns:
4472 * D3D_OK on success
4473 * DDERR_INVALIDPARAMS if State is NULL
4474 * For details, see IWineD3DDevice::GetTextureStageState
4476 *****************************************************************************/
4477 static HRESULT WINAPI
4478 IDirect3DDeviceImpl_7_GetTextureStageState(IDirect3DDevice7 *iface,
4479 DWORD Stage,
4480 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4481 DWORD *State)
4483 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4484 HRESULT hr;
4485 TRACE("(%p)->(%08x,%08x,%p): Relay!\n", This, Stage, TexStageStateType, State);
4487 if(!State)
4488 return DDERR_INVALIDPARAMS;
4490 EnterCriticalSection(&ddraw_cs);
4491 switch(TexStageStateType)
4493 /* Mipfilter is a sampler state with different values */
4494 case D3DTSS_MIPFILTER:
4496 WINED3DTEXTUREFILTERTYPE value;
4498 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
4499 Stage,
4500 WINED3DSAMP_MIPFILTER,
4501 &value);
4502 switch(value)
4504 case WINED3DTEXF_NONE: *State = D3DTFP_NONE; break;
4505 case WINED3DTEXF_POINT: *State = D3DTFP_POINT; break;
4506 case WINED3DTEXF_LINEAR: *State = D3DTFP_LINEAR; break;
4507 default:
4508 ERR("Unexpected mipfilter value %d\n", value);
4509 *State = D3DTFP_NONE;
4511 break;
4514 /* Minfilter is a sampler state too, equal values */
4515 case D3DTSS_MINFILTER:
4516 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
4517 Stage,
4518 WINED3DSAMP_MINFILTER,
4519 State);
4520 break;
4522 /* Magfilter has slightly different values */
4523 case D3DTSS_MAGFILTER:
4525 WINED3DTEXTUREFILTERTYPE wined3dfilter;
4526 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
4527 Stage,
4528 WINED3DSAMP_MAGFILTER,
4529 &wined3dfilter);
4530 switch(wined3dfilter)
4532 case WINED3DTEXF_POINT: *State = D3DTFG_POINT; break;
4533 case WINED3DTEXF_LINEAR: *State = D3DTFG_LINEAR; break;
4534 case WINED3DTEXF_ANISOTROPIC: *State = D3DTFG_ANISOTROPIC; break;
4535 case WINED3DTEXF_FLATCUBIC: *State = D3DTFG_FLATCUBIC; break;
4536 case WINED3DTEXF_GAUSSIANCUBIC: *State = D3DTFG_GAUSSIANCUBIC; break;
4537 default:
4538 ERR("Unexpected wined3d mag filter value %d\n", wined3dfilter);
4539 *State = D3DTFG_POINT;
4541 break;
4544 case D3DTSS_ADDRESS:
4545 case D3DTSS_ADDRESSU:
4546 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
4547 Stage,
4548 WINED3DSAMP_ADDRESSU,
4549 State);
4550 break;
4551 case D3DTSS_ADDRESSV:
4552 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
4553 Stage,
4554 WINED3DSAMP_ADDRESSV,
4555 State);
4556 break;
4557 default:
4558 hr = IWineD3DDevice_GetTextureStageState(This->wineD3DDevice,
4559 Stage,
4560 TexStageStateType,
4561 State);
4562 break;
4564 LeaveCriticalSection(&ddraw_cs);
4565 return hr;
4568 static HRESULT WINAPI
4569 Thunk_IDirect3DDeviceImpl_3_GetTextureStageState(IDirect3DDevice3 *iface,
4570 DWORD Stage,
4571 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4572 DWORD *State)
4574 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4575 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, Stage, TexStageStateType, State);
4576 return IDirect3DDevice7_GetTextureStageState(ICOM_INTERFACE(This, IDirect3DDevice7),
4577 Stage,
4578 TexStageStateType,
4579 State);
4582 /*****************************************************************************
4583 * IDirect3DDevice7::SetTextureStageState
4585 * Sets a texture stage state. Some stage types need to be handled specially,
4586 * because they do not exist in WineD3D and were moved to another place
4588 * Version 3 and 7
4590 * Params:
4591 * Stage: The stage to modify
4592 * TexStageStateType: The state to change
4593 * State: The new value for the state
4595 * Returns:
4596 * D3D_OK on success
4597 * For details, see IWineD3DDevice::SetTextureStageState
4599 *****************************************************************************/
4600 static HRESULT WINAPI
4601 IDirect3DDeviceImpl_7_SetTextureStageState(IDirect3DDevice7 *iface,
4602 DWORD Stage,
4603 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4604 DWORD State)
4606 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4607 HRESULT hr;
4608 TRACE("(%p)->(%08x,%08x,%08x): Relay!\n", This, Stage, TexStageStateType, State);
4610 EnterCriticalSection(&ddraw_cs);
4611 switch(TexStageStateType)
4613 /* Mipfilter is a sampler state with different values */
4614 case D3DTSS_MIPFILTER:
4616 WINED3DTEXTUREFILTERTYPE value;
4617 switch(State)
4619 case D3DTFP_NONE: value = WINED3DTEXF_NONE; break;
4620 case D3DTFP_POINT: value = WINED3DTEXF_POINT; break;
4621 case 0: /* Unchecked */
4622 case D3DTFP_LINEAR: value = WINED3DTEXF_LINEAR; break;
4623 default:
4624 ERR("Unexpected mipfilter value %d\n", State);
4625 value = WINED3DTEXF_NONE;
4627 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
4628 Stage,
4629 WINED3DSAMP_MIPFILTER,
4630 value);
4631 break;
4634 /* Minfilter is a sampler state too, equal values */
4635 case D3DTSS_MINFILTER:
4636 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
4637 Stage,
4638 WINED3DSAMP_MINFILTER,
4639 State);
4640 break;
4642 /* Magfilter has slightly different values */
4643 case D3DTSS_MAGFILTER:
4645 WINED3DTEXTUREFILTERTYPE wined3dfilter;
4646 switch((D3DTEXTUREMAGFILTER) State)
4648 case D3DTFG_POINT: wined3dfilter = WINED3DTEXF_POINT; break;
4649 case D3DTFG_LINEAR: wined3dfilter = WINED3DTEXF_LINEAR; break;
4650 case D3DTFG_FLATCUBIC: wined3dfilter = WINED3DTEXF_FLATCUBIC; break;
4651 case D3DTFG_GAUSSIANCUBIC: wined3dfilter = WINED3DTEXF_GAUSSIANCUBIC; break;
4652 case D3DTFG_ANISOTROPIC: wined3dfilter = WINED3DTEXF_ANISOTROPIC; break;
4653 default:
4654 ERR("Unexpected d3d7 mag filter type %d\n", State);
4655 wined3dfilter = WINED3DTEXF_POINT;
4657 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
4658 Stage,
4659 WINED3DSAMP_MAGFILTER,
4660 wined3dfilter);
4661 break;
4664 case D3DTSS_ADDRESS:
4665 IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
4666 Stage,
4667 WINED3DSAMP_ADDRESSV,
4668 State);
4669 /* Drop through */
4670 case D3DTSS_ADDRESSU:
4671 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
4672 Stage,
4673 WINED3DSAMP_ADDRESSU,
4674 State);
4675 break;
4677 case D3DTSS_ADDRESSV:
4678 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
4679 Stage,
4680 WINED3DSAMP_ADDRESSV,
4681 State);
4682 break;
4684 default:
4685 hr = IWineD3DDevice_SetTextureStageState(This->wineD3DDevice,
4686 Stage,
4687 TexStageStateType,
4688 State);
4689 break;
4691 LeaveCriticalSection(&ddraw_cs);
4692 return hr;
4695 static HRESULT WINAPI
4696 Thunk_IDirect3DDeviceImpl_3_SetTextureStageState(IDirect3DDevice3 *iface,
4697 DWORD Stage,
4698 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4699 DWORD State)
4701 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4702 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, Stage, TexStageStateType, State);
4703 return IDirect3DDevice7_SetTextureStageState(ICOM_INTERFACE(This, IDirect3DDevice7),
4704 Stage,
4705 TexStageStateType,
4706 State);
4709 /*****************************************************************************
4710 * IDirect3DDevice7::ValidateDevice
4712 * SDK: "Reports the device's ability to render the currently set
4713 * texture-blending operations in a single pass". Whatever that means
4714 * exactly...
4716 * Version 3 and 7
4718 * Params:
4719 * NumPasses: Address to write the number of necessary passes for the
4720 * desired effect to.
4722 * Returns:
4723 * D3D_OK on success
4724 * See IWineD3DDevice::ValidateDevice for more details
4726 *****************************************************************************/
4727 static HRESULT WINAPI
4728 IDirect3DDeviceImpl_7_ValidateDevice(IDirect3DDevice7 *iface,
4729 DWORD *NumPasses)
4731 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4732 HRESULT hr;
4733 TRACE("(%p)->(%p): Relay\n", This, NumPasses);
4735 EnterCriticalSection(&ddraw_cs);
4736 hr = IWineD3DDevice_ValidateDevice(This->wineD3DDevice, NumPasses);
4737 LeaveCriticalSection(&ddraw_cs);
4738 return hr;
4741 static HRESULT WINAPI
4742 Thunk_IDirect3DDeviceImpl_3_ValidateDevice(IDirect3DDevice3 *iface,
4743 DWORD *Passes)
4745 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4746 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Passes);
4747 return IDirect3DDevice7_ValidateDevice(ICOM_INTERFACE(This, IDirect3DDevice7),
4748 Passes);
4751 /*****************************************************************************
4752 * IDirect3DDevice7::Clear
4754 * Fills the render target, the z buffer and the stencil buffer with a
4755 * clear color / value
4757 * Version 7 only
4759 * Params:
4760 * Count: Number of rectangles in Rects must be 0 if Rects is NULL
4761 * Rects: Rectangles to clear. If NULL, the whole surface is cleared
4762 * Flags: Some flags, as usual
4763 * Color: Clear color for the render target
4764 * Z: Clear value for the Z buffer
4765 * Stencil: Clear value to store in each stencil buffer entry
4767 * Returns:
4768 * D3D_OK on success
4769 * For details, see IWineD3DDevice::Clear
4771 *****************************************************************************/
4772 static HRESULT WINAPI
4773 IDirect3DDeviceImpl_7_Clear(IDirect3DDevice7 *iface,
4774 DWORD Count,
4775 D3DRECT *Rects,
4776 DWORD Flags,
4777 D3DCOLOR Color,
4778 D3DVALUE Z,
4779 DWORD Stencil)
4781 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4782 HRESULT hr;
4783 TRACE("(%p)->(%08x,%p,%08x,%08x,%f,%08x): Relay\n", This, Count, Rects, Flags, Color, Z, Stencil);
4785 /* Note; D3DRECT is compatible with WINED3DRECT */
4786 EnterCriticalSection(&ddraw_cs);
4787 hr = IWineD3DDevice_Clear(This->wineD3DDevice, Count, (WINED3DRECT*) Rects, Flags, Color, Z, Stencil);
4788 LeaveCriticalSection(&ddraw_cs);
4789 return hr;
4792 /*****************************************************************************
4793 * IDirect3DDevice7::SetViewport
4795 * Sets the current viewport.
4797 * Version 7 only, but IDirect3DViewport uses this call for older
4798 * versions
4800 * Params:
4801 * Data: The new viewport to set
4803 * Returns:
4804 * D3D_OK on success
4805 * DDERR_INVALIDPARAMS if Data is NULL
4806 * For more details, see IWineDDDevice::SetViewport
4808 *****************************************************************************/
4809 static HRESULT WINAPI
4810 IDirect3DDeviceImpl_7_SetViewport(IDirect3DDevice7 *iface,
4811 D3DVIEWPORT7 *Data)
4813 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4814 HRESULT hr;
4815 TRACE("(%p)->(%p) Relay!\n", This, Data);
4817 if(!Data)
4818 return DDERR_INVALIDPARAMS;
4820 /* Note: D3DVIEWPORT7 is compatible with WINED3DVIEWPORT */
4821 EnterCriticalSection(&ddraw_cs);
4822 hr = IWineD3DDevice_SetViewport(This->wineD3DDevice,
4823 (WINED3DVIEWPORT*) Data);
4824 LeaveCriticalSection(&ddraw_cs);
4825 return hr;
4828 /*****************************************************************************
4829 * IDirect3DDevice::GetViewport
4831 * Returns the current viewport
4833 * Version 7
4835 * Params:
4836 * Data: D3D7Viewport structure to write the viewport information to
4838 * Returns:
4839 * D3D_OK on success
4840 * DDERR_INVALIDPARAMS if Data is NULL
4841 * For more details, see IWineD3DDevice::GetViewport
4843 *****************************************************************************/
4844 static HRESULT WINAPI
4845 IDirect3DDeviceImpl_7_GetViewport(IDirect3DDevice7 *iface,
4846 D3DVIEWPORT7 *Data)
4848 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4849 HRESULT hr;
4850 TRACE("(%p)->(%p) Relay!\n", This, Data);
4852 if(!Data)
4853 return DDERR_INVALIDPARAMS;
4855 /* Note: D3DVIEWPORT7 is compatible with WINED3DVIEWPORT */
4856 EnterCriticalSection(&ddraw_cs);
4857 hr = IWineD3DDevice_GetViewport(This->wineD3DDevice,
4858 (WINED3DVIEWPORT*) Data);
4860 LeaveCriticalSection(&ddraw_cs);
4861 return hr_ddraw_from_wined3d(hr);
4864 /*****************************************************************************
4865 * IDirect3DDevice7::SetMaterial
4867 * Sets the Material
4869 * Version 7
4871 * Params:
4872 * Mat: The material to set
4874 * Returns:
4875 * D3D_OK on success
4876 * DDERR_INVALIDPARAMS if Mat is NULL.
4877 * For more details, see IWineD3DDevice::SetMaterial
4879 *****************************************************************************/
4880 static HRESULT WINAPI
4881 IDirect3DDeviceImpl_7_SetMaterial(IDirect3DDevice7 *iface,
4882 D3DMATERIAL7 *Mat)
4884 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4885 HRESULT hr;
4886 TRACE("(%p)->(%p): Relay!\n", This, Mat);
4888 /* Note: D3DMATERIAL7 is compatible with WINED3DMATERIAL */
4889 EnterCriticalSection(&ddraw_cs);
4890 hr = IWineD3DDevice_SetMaterial(This->wineD3DDevice,
4891 (WINED3DMATERIAL*) Mat);
4892 LeaveCriticalSection(&ddraw_cs);
4893 return hr_ddraw_from_wined3d(hr);
4896 /*****************************************************************************
4897 * IDirect3DDevice7::GetMaterial
4899 * Returns the current material
4901 * Version 7
4903 * Params:
4904 * Mat: D3DMATERIAL7 structure to write the material parameters to
4906 * Returns:
4907 * D3D_OK on success
4908 * DDERR_INVALIDPARAMS if Mat is NULL
4909 * For more details, see IWineD3DDevice::GetMaterial
4911 *****************************************************************************/
4912 static HRESULT WINAPI
4913 IDirect3DDeviceImpl_7_GetMaterial(IDirect3DDevice7 *iface,
4914 D3DMATERIAL7 *Mat)
4916 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4917 HRESULT hr;
4918 TRACE("(%p)->(%p): Relay!\n", This, Mat);
4920 EnterCriticalSection(&ddraw_cs);
4921 /* Note: D3DMATERIAL7 is compatible with WINED3DMATERIAL */
4922 hr = IWineD3DDevice_GetMaterial(This->wineD3DDevice,
4923 (WINED3DMATERIAL*) Mat);
4924 LeaveCriticalSection(&ddraw_cs);
4925 return hr_ddraw_from_wined3d(hr);
4928 /*****************************************************************************
4929 * IDirect3DDevice7::SetLight
4931 * Assigns a light to a light index, but doesn't activate it yet.
4933 * Version 7, IDirect3DLight uses this method for older versions
4935 * Params:
4936 * LightIndex: The index of the new light
4937 * Light: A D3DLIGHT7 structure describing the light
4939 * Returns:
4940 * D3D_OK on success
4941 * For more details, see IWineD3DDevice::SetLight
4943 *****************************************************************************/
4944 static HRESULT WINAPI
4945 IDirect3DDeviceImpl_7_SetLight(IDirect3DDevice7 *iface,
4946 DWORD LightIndex,
4947 D3DLIGHT7 *Light)
4949 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4950 HRESULT hr;
4951 TRACE("(%p)->(%08x,%p): Relay!\n", This, LightIndex, Light);
4953 EnterCriticalSection(&ddraw_cs);
4954 /* Note: D3DLIGHT7 is compatible with WINED3DLIGHT */
4955 hr = IWineD3DDevice_SetLight(This->wineD3DDevice,
4956 LightIndex,
4957 (WINED3DLIGHT*) Light);
4958 LeaveCriticalSection(&ddraw_cs);
4959 return hr_ddraw_from_wined3d(hr);
4962 /*****************************************************************************
4963 * IDirect3DDevice7::GetLight
4965 * Returns the light assigned to a light index
4967 * Params:
4968 * Light: Structure to write the light information to
4970 * Returns:
4971 * D3D_OK on success
4972 * DDERR_INVALIDPARAMS if Light is NULL
4973 * For details, see IWineD3DDevice::GetLight
4975 *****************************************************************************/
4976 static HRESULT WINAPI
4977 IDirect3DDeviceImpl_7_GetLight(IDirect3DDevice7 *iface,
4978 DWORD LightIndex,
4979 D3DLIGHT7 *Light)
4981 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4982 HRESULT rc;
4983 TRACE("(%p)->(%08x,%p): Relay!\n", This, LightIndex, Light);
4985 EnterCriticalSection(&ddraw_cs);
4986 /* Note: D3DLIGHT7 is compatible with WINED3DLIGHT */
4987 rc = IWineD3DDevice_GetLight(This->wineD3DDevice,
4988 LightIndex,
4989 (WINED3DLIGHT*) Light);
4991 /* Translate the result. WineD3D returns other values than D3D7 */
4992 LeaveCriticalSection(&ddraw_cs);
4993 return hr_ddraw_from_wined3d(rc);
4996 /*****************************************************************************
4997 * IDirect3DDevice7::BeginStateBlock
4999 * Begins recording to a stateblock
5001 * Version 7
5003 * Returns:
5004 * D3D_OK on success
5005 * For details see IWineD3DDevice::BeginStateBlock
5007 *****************************************************************************/
5008 static HRESULT WINAPI
5009 IDirect3DDeviceImpl_7_BeginStateBlock(IDirect3DDevice7 *iface)
5011 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5012 HRESULT hr;
5013 TRACE("(%p)->(): Relay!\n", This);
5015 EnterCriticalSection(&ddraw_cs);
5016 hr = IWineD3DDevice_BeginStateBlock(This->wineD3DDevice);
5017 LeaveCriticalSection(&ddraw_cs);
5018 return hr_ddraw_from_wined3d(hr);
5021 /*****************************************************************************
5022 * IDirect3DDevice7::EndStateBlock
5024 * Stops recording to a state block and returns the created stateblock
5025 * handle.
5027 * Version 7
5029 * Params:
5030 * BlockHandle: Address to store the stateblock's handle to
5032 * Returns:
5033 * D3D_OK on success
5034 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5035 * See IWineD3DDevice::EndStateBlock for more details
5037 *****************************************************************************/
5038 static HRESULT WINAPI
5039 IDirect3DDeviceImpl_7_EndStateBlock(IDirect3DDevice7 *iface,
5040 DWORD *BlockHandle)
5042 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5043 HRESULT hr;
5044 TRACE("(%p)->(%p): Relay!\n", This, BlockHandle);
5046 if(!BlockHandle)
5048 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
5049 return DDERR_INVALIDPARAMS;
5052 EnterCriticalSection(&ddraw_cs);
5053 *BlockHandle = IDirect3DDeviceImpl_CreateHandle(This);
5054 if(!*BlockHandle)
5056 ERR("Cannot get a handle number for the stateblock\n");
5057 LeaveCriticalSection(&ddraw_cs);
5058 return DDERR_OUTOFMEMORY;
5060 This->Handles[*BlockHandle - 1].type = DDrawHandle_StateBlock;
5061 hr = IWineD3DDevice_EndStateBlock(This->wineD3DDevice,
5062 (IWineD3DStateBlock **) &This->Handles[*BlockHandle - 1].ptr);
5063 LeaveCriticalSection(&ddraw_cs);
5064 return hr_ddraw_from_wined3d(hr);
5067 /*****************************************************************************
5068 * IDirect3DDevice7::PreLoad
5070 * Allows the app to signal that a texture will be used soon, to allow
5071 * the Direct3DDevice to load it to the video card in the meantime.
5073 * Version 7
5075 * Params:
5076 * Texture: The texture to preload
5078 * Returns:
5079 * D3D_OK on success
5080 * DDERR_INVALIDPARAMS if Texture is NULL
5081 * See IWineD3DSurface::PreLoad for details
5083 *****************************************************************************/
5084 static HRESULT WINAPI
5085 IDirect3DDeviceImpl_7_PreLoad(IDirect3DDevice7 *iface,
5086 IDirectDrawSurface7 *Texture)
5088 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5089 IDirectDrawSurfaceImpl *surf = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, Texture);
5091 TRACE("(%p)->(%p): Relay!\n", This, surf);
5093 if(!Texture)
5094 return DDERR_INVALIDPARAMS;
5096 EnterCriticalSection(&ddraw_cs);
5097 IWineD3DSurface_PreLoad(surf->WineD3DSurface);
5098 LeaveCriticalSection(&ddraw_cs);
5099 return D3D_OK;
5102 /*****************************************************************************
5103 * IDirect3DDevice7::ApplyStateBlock
5105 * Activates the state stored in a state block handle.
5107 * Params:
5108 * BlockHandle: The stateblock handle to activate
5110 * Returns:
5111 * D3D_OK on success
5112 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5114 *****************************************************************************/
5115 static HRESULT WINAPI
5116 IDirect3DDeviceImpl_7_ApplyStateBlock(IDirect3DDevice7 *iface,
5117 DWORD BlockHandle)
5119 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5120 HRESULT hr;
5121 TRACE("(%p)->(%08x): Relay!\n", This, BlockHandle);
5123 EnterCriticalSection(&ddraw_cs);
5124 if(!BlockHandle || BlockHandle > This->numHandles)
5126 WARN("Out of range handle %d, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5127 LeaveCriticalSection(&ddraw_cs);
5128 return D3DERR_INVALIDSTATEBLOCK;
5130 if(This->Handles[BlockHandle - 1].type != DDrawHandle_StateBlock)
5132 WARN("Handle %d is not a stateblock, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5133 LeaveCriticalSection(&ddraw_cs);
5134 return D3DERR_INVALIDSTATEBLOCK;
5137 hr = IWineD3DStateBlock_Apply((IWineD3DStateBlock *) This->Handles[BlockHandle - 1].ptr);
5138 LeaveCriticalSection(&ddraw_cs);
5139 return hr_ddraw_from_wined3d(hr);
5142 /*****************************************************************************
5143 * IDirect3DDevice7::CaptureStateBlock
5145 * Updates a stateblock's values to the values currently set for the device
5147 * Version 7
5149 * Params:
5150 * BlockHandle: Stateblock to update
5152 * Returns:
5153 * D3D_OK on success
5154 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5155 * See IWineD3DDevice::CaptureStateBlock for more details
5157 *****************************************************************************/
5158 static HRESULT WINAPI
5159 IDirect3DDeviceImpl_7_CaptureStateBlock(IDirect3DDevice7 *iface,
5160 DWORD BlockHandle)
5162 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5163 HRESULT hr;
5164 TRACE("(%p)->(%08x): Relay!\n", This, BlockHandle);
5166 EnterCriticalSection(&ddraw_cs);
5167 if(BlockHandle == 0 || BlockHandle > This->numHandles)
5169 WARN("Out of range handle %d, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5170 LeaveCriticalSection(&ddraw_cs);
5171 return D3DERR_INVALIDSTATEBLOCK;
5173 if(This->Handles[BlockHandle - 1].type != DDrawHandle_StateBlock)
5175 WARN("Handle %d is not a stateblock, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5176 LeaveCriticalSection(&ddraw_cs);
5177 return D3DERR_INVALIDSTATEBLOCK;
5180 hr = IWineD3DStateBlock_Capture((IWineD3DStateBlock *) This->Handles[BlockHandle - 1].ptr);
5181 LeaveCriticalSection(&ddraw_cs);
5182 return hr_ddraw_from_wined3d(hr);
5185 /*****************************************************************************
5186 * IDirect3DDevice7::DeleteStateBlock
5188 * Deletes a stateblock handle. This means releasing the WineD3DStateBlock
5190 * Version 7
5192 * Params:
5193 * BlockHandle: Stateblock handle to delete
5195 * Returns:
5196 * D3D_OK on success
5197 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is 0
5199 *****************************************************************************/
5200 static HRESULT WINAPI
5201 IDirect3DDeviceImpl_7_DeleteStateBlock(IDirect3DDevice7 *iface,
5202 DWORD BlockHandle)
5204 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5205 ULONG ref;
5206 TRACE("(%p)->(%08x): Relay!\n", This, BlockHandle);
5208 EnterCriticalSection(&ddraw_cs);
5209 if(BlockHandle == 0 || BlockHandle > This->numHandles)
5211 WARN("Out of range handle %d, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5212 LeaveCriticalSection(&ddraw_cs);
5213 return D3DERR_INVALIDSTATEBLOCK;
5215 if(This->Handles[BlockHandle - 1].type != DDrawHandle_StateBlock)
5217 WARN("Handle %d is not a stateblock, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5218 LeaveCriticalSection(&ddraw_cs);
5219 return D3DERR_INVALIDSTATEBLOCK;
5222 ref = IWineD3DStateBlock_Release((IWineD3DStateBlock *) This->Handles[BlockHandle - 1].ptr);
5223 if(ref)
5225 ERR("Something is still holding the stateblock %p(Handle %d). Ref = %d\n", This->Handles[BlockHandle - 1].ptr, BlockHandle, ref);
5227 This->Handles[BlockHandle - 1].ptr = NULL;
5228 This->Handles[BlockHandle - 1].type = DDrawHandle_Unknown;
5230 LeaveCriticalSection(&ddraw_cs);
5231 return D3D_OK;
5234 /*****************************************************************************
5235 * IDirect3DDevice7::CreateStateBlock
5237 * Creates a new state block handle.
5239 * Version 7
5241 * Params:
5242 * Type: The state block type
5243 * BlockHandle: Address to write the created handle to
5245 * Returns:
5246 * D3D_OK on success
5247 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5249 *****************************************************************************/
5250 static HRESULT WINAPI
5251 IDirect3DDeviceImpl_7_CreateStateBlock(IDirect3DDevice7 *iface,
5252 D3DSTATEBLOCKTYPE Type,
5253 DWORD *BlockHandle)
5255 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5256 HRESULT hr;
5257 TRACE("(%p)->(%08x,%p)!\n", This, Type, BlockHandle);
5259 if(!BlockHandle)
5261 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
5262 return DDERR_INVALIDPARAMS;
5264 if(Type != D3DSBT_ALL && Type != D3DSBT_PIXELSTATE &&
5265 Type != D3DSBT_VERTEXSTATE ) {
5266 WARN("Unexpected stateblock type, returning DDERR_INVALIDPARAMS\n");
5267 return DDERR_INVALIDPARAMS;
5270 EnterCriticalSection(&ddraw_cs);
5271 *BlockHandle = IDirect3DDeviceImpl_CreateHandle(This);
5272 if(!*BlockHandle)
5274 ERR("Cannot get a handle number for the stateblock\n");
5275 LeaveCriticalSection(&ddraw_cs);
5276 return DDERR_OUTOFMEMORY;
5278 This->Handles[*BlockHandle - 1].type = DDrawHandle_StateBlock;
5280 /* The D3DSTATEBLOCKTYPE enum is fine here */
5281 hr = IWineD3DDevice_CreateStateBlock(This->wineD3DDevice,
5282 Type,
5283 (IWineD3DStateBlock **) &This->Handles[*BlockHandle - 1].ptr,
5284 NULL /* Parent, hope that works */);
5285 LeaveCriticalSection(&ddraw_cs);
5286 return hr_ddraw_from_wined3d(hr);
5289 /*****************************************************************************
5290 * IDirect3DDevice7::Load
5292 * Loads a rectangular area from the source into the destination texture.
5293 * It can also copy the source to the faces of a cubic environment map
5295 * Version 7
5297 * Params:
5298 * DestTex: Destination texture
5299 * DestPoint: Point in the destination where the source image should be
5300 * written to
5301 * SrcTex: Source texture
5302 * SrcRect: Source rectangle
5303 * Flags: Some flags
5305 * Returns:
5306 * D3D_OK on success
5307 * DDERR_INVALIDPARAMS if DestTex or SrcTex are NULL
5308 * See IDirect3DTexture2::Load for details
5310 *****************************************************************************/
5311 static HRESULT WINAPI
5312 IDirect3DDeviceImpl_7_Load(IDirect3DDevice7 *iface,
5313 IDirectDrawSurface7 *DestTex,
5314 POINT *DestPoint,
5315 IDirectDrawSurface7 *SrcTex,
5316 RECT *SrcRect,
5317 DWORD Flags)
5319 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5320 IDirectDrawSurfaceImpl *dest = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, DestTex);
5321 IDirectDrawSurfaceImpl *src = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, SrcTex);
5322 FIXME("(%p)->(%p,%p,%p,%p,%08x): Partially Implemented!\n", This, dest, DestPoint, src, SrcRect, Flags);
5324 if( (!src) || (!dest) )
5325 return DDERR_INVALIDPARAMS;
5327 IDirect3DTexture2_Load(ICOM_INTERFACE(dest, IDirect3DTexture2),
5328 ICOM_INTERFACE(src, IDirect3DTexture2));
5329 return D3D_OK;
5332 /*****************************************************************************
5333 * IDirect3DDevice7::LightEnable
5335 * Enables or disables a light
5337 * Version 7, IDirect3DLight uses this method too.
5339 * Params:
5340 * LightIndex: The index of the light to enable / disable
5341 * Enable: Enable or disable the light
5343 * Returns:
5344 * D3D_OK on success
5345 * For more details, see IWineD3DDevice::SetLightEnable
5347 *****************************************************************************/
5348 static HRESULT WINAPI
5349 IDirect3DDeviceImpl_7_LightEnable(IDirect3DDevice7 *iface,
5350 DWORD LightIndex,
5351 BOOL Enable)
5353 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5354 HRESULT hr;
5355 TRACE("(%p)->(%08x,%d): Relay!\n", This, LightIndex, Enable);
5357 EnterCriticalSection(&ddraw_cs);
5358 hr = IWineD3DDevice_SetLightEnable(This->wineD3DDevice, LightIndex, Enable);
5359 LeaveCriticalSection(&ddraw_cs);
5360 return hr_ddraw_from_wined3d(hr);
5363 /*****************************************************************************
5364 * IDirect3DDevice7::GetLightEnable
5366 * Retrieves if the light with the given index is enabled or not
5368 * Version 7
5370 * Params:
5371 * LightIndex: Index of desired light
5372 * Enable: Pointer to a BOOL which contains the result
5374 * Returns:
5375 * D3D_OK on success
5376 * DDERR_INVALIDPARAMS if Enable is NULL
5377 * See IWineD3DDevice::GetLightEnable for more details
5379 *****************************************************************************/
5380 static HRESULT WINAPI
5381 IDirect3DDeviceImpl_7_GetLightEnable(IDirect3DDevice7 *iface,
5382 DWORD LightIndex,
5383 BOOL* Enable)
5385 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5386 HRESULT hr;
5387 TRACE("(%p)->(%08x,%p): Relay\n", This, LightIndex, Enable);
5389 if(!Enable)
5390 return DDERR_INVALIDPARAMS;
5392 EnterCriticalSection(&ddraw_cs);
5393 hr = IWineD3DDevice_GetLightEnable(This->wineD3DDevice, LightIndex, Enable);
5394 LeaveCriticalSection(&ddraw_cs);
5395 return hr_ddraw_from_wined3d(hr);
5398 /*****************************************************************************
5399 * IDirect3DDevice7::SetClipPlane
5401 * Sets custom clipping plane
5403 * Version 7
5405 * Params:
5406 * Index: The index of the clipping plane
5407 * PlaneEquation: An equation defining the clipping plane
5409 * Returns:
5410 * D3D_OK on success
5411 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
5412 * See IWineD3DDevice::SetClipPlane for more details
5414 *****************************************************************************/
5415 static HRESULT WINAPI
5416 IDirect3DDeviceImpl_7_SetClipPlane(IDirect3DDevice7 *iface,
5417 DWORD Index,
5418 D3DVALUE* PlaneEquation)
5420 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5421 HRESULT hr;
5422 TRACE("(%p)->(%08x,%p): Relay!\n", This, Index, PlaneEquation);
5424 if(!PlaneEquation)
5425 return DDERR_INVALIDPARAMS;
5427 EnterCriticalSection(&ddraw_cs);
5428 hr = IWineD3DDevice_SetClipPlane(This->wineD3DDevice, Index, PlaneEquation);
5429 LeaveCriticalSection(&ddraw_cs);
5430 return hr;
5433 /*****************************************************************************
5434 * IDirect3DDevice7::GetClipPlane
5436 * Returns the clipping plane with a specific index
5438 * Params:
5439 * Index: The index of the desired plane
5440 * PlaneEquation: Address to store the plane equation to
5442 * Returns:
5443 * D3D_OK on success
5444 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
5445 * See IWineD3DDevice::GetClipPlane for more details
5447 *****************************************************************************/
5448 static HRESULT WINAPI
5449 IDirect3DDeviceImpl_7_GetClipPlane(IDirect3DDevice7 *iface,
5450 DWORD Index,
5451 D3DVALUE* PlaneEquation)
5453 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5454 HRESULT hr;
5455 TRACE("(%p)->(%d,%p): Relay!\n", This, Index, PlaneEquation);
5457 if(!PlaneEquation)
5458 return DDERR_INVALIDPARAMS;
5460 EnterCriticalSection(&ddraw_cs);
5461 hr = IWineD3DDevice_GetClipPlane(This->wineD3DDevice, Index, PlaneEquation);
5462 LeaveCriticalSection(&ddraw_cs);
5463 return hr;
5466 /*****************************************************************************
5467 * IDirect3DDevice7::GetInfo
5469 * Retrieves some information about the device. The DirectX sdk says that
5470 * this version returns S_FALSE for all retail builds of DirectX, that's what
5471 * this implementation does.
5473 * Params:
5474 * DevInfoID: Information type requested
5475 * DevInfoStruct: Pointer to a structure to store the info to
5476 * Size: Size of the structure
5478 * Returns:
5479 * S_FALSE, because it's a non-debug driver
5481 *****************************************************************************/
5482 static HRESULT WINAPI
5483 IDirect3DDeviceImpl_7_GetInfo(IDirect3DDevice7 *iface,
5484 DWORD DevInfoID,
5485 void *DevInfoStruct,
5486 DWORD Size)
5488 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5489 TRACE("(%p)->(%08x,%p,%08x)\n", This, DevInfoID, DevInfoStruct, Size);
5491 if (TRACE_ON(d3d7))
5493 TRACE(" info requested : ");
5494 switch (DevInfoID)
5496 case D3DDEVINFOID_TEXTUREMANAGER: TRACE("D3DDEVINFOID_TEXTUREMANAGER\n"); break;
5497 case D3DDEVINFOID_D3DTEXTUREMANAGER: TRACE("D3DDEVINFOID_D3DTEXTUREMANAGER\n"); break;
5498 case D3DDEVINFOID_TEXTURING: TRACE("D3DDEVINFOID_TEXTURING\n"); break;
5499 default: ERR(" invalid flag !!!\n"); return DDERR_INVALIDPARAMS;
5503 return S_FALSE; /* According to MSDN, this is valid for a non-debug driver */
5506 const IDirect3DDevice7Vtbl IDirect3DDevice7_Vtbl =
5508 /*** IUnknown Methods ***/
5509 IDirect3DDeviceImpl_7_QueryInterface,
5510 IDirect3DDeviceImpl_7_AddRef,
5511 IDirect3DDeviceImpl_7_Release,
5512 /*** IDirect3DDevice7 ***/
5513 IDirect3DDeviceImpl_7_GetCaps,
5514 IDirect3DDeviceImpl_7_EnumTextureFormats,
5515 IDirect3DDeviceImpl_7_BeginScene,
5516 IDirect3DDeviceImpl_7_EndScene,
5517 IDirect3DDeviceImpl_7_GetDirect3D,
5518 IDirect3DDeviceImpl_7_SetRenderTarget,
5519 IDirect3DDeviceImpl_7_GetRenderTarget,
5520 IDirect3DDeviceImpl_7_Clear,
5521 IDirect3DDeviceImpl_7_SetTransform,
5522 IDirect3DDeviceImpl_7_GetTransform,
5523 IDirect3DDeviceImpl_7_SetViewport,
5524 IDirect3DDeviceImpl_7_MultiplyTransform,
5525 IDirect3DDeviceImpl_7_GetViewport,
5526 IDirect3DDeviceImpl_7_SetMaterial,
5527 IDirect3DDeviceImpl_7_GetMaterial,
5528 IDirect3DDeviceImpl_7_SetLight,
5529 IDirect3DDeviceImpl_7_GetLight,
5530 IDirect3DDeviceImpl_7_SetRenderState,
5531 IDirect3DDeviceImpl_7_GetRenderState,
5532 IDirect3DDeviceImpl_7_BeginStateBlock,
5533 IDirect3DDeviceImpl_7_EndStateBlock,
5534 IDirect3DDeviceImpl_7_PreLoad,
5535 IDirect3DDeviceImpl_7_DrawPrimitive,
5536 IDirect3DDeviceImpl_7_DrawIndexedPrimitive,
5537 IDirect3DDeviceImpl_7_SetClipStatus,
5538 IDirect3DDeviceImpl_7_GetClipStatus,
5539 IDirect3DDeviceImpl_7_DrawPrimitiveStrided,
5540 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided,
5541 IDirect3DDeviceImpl_7_DrawPrimitiveVB,
5542 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB,
5543 IDirect3DDeviceImpl_7_ComputeSphereVisibility,
5544 IDirect3DDeviceImpl_7_GetTexture,
5545 IDirect3DDeviceImpl_7_SetTexture,
5546 IDirect3DDeviceImpl_7_GetTextureStageState,
5547 IDirect3DDeviceImpl_7_SetTextureStageState,
5548 IDirect3DDeviceImpl_7_ValidateDevice,
5549 IDirect3DDeviceImpl_7_ApplyStateBlock,
5550 IDirect3DDeviceImpl_7_CaptureStateBlock,
5551 IDirect3DDeviceImpl_7_DeleteStateBlock,
5552 IDirect3DDeviceImpl_7_CreateStateBlock,
5553 IDirect3DDeviceImpl_7_Load,
5554 IDirect3DDeviceImpl_7_LightEnable,
5555 IDirect3DDeviceImpl_7_GetLightEnable,
5556 IDirect3DDeviceImpl_7_SetClipPlane,
5557 IDirect3DDeviceImpl_7_GetClipPlane,
5558 IDirect3DDeviceImpl_7_GetInfo
5561 const IDirect3DDevice3Vtbl IDirect3DDevice3_Vtbl =
5563 /*** IUnknown Methods ***/
5564 Thunk_IDirect3DDeviceImpl_3_QueryInterface,
5565 Thunk_IDirect3DDeviceImpl_3_AddRef,
5566 Thunk_IDirect3DDeviceImpl_3_Release,
5567 /*** IDirect3DDevice3 ***/
5568 IDirect3DDeviceImpl_3_GetCaps,
5569 IDirect3DDeviceImpl_3_GetStats,
5570 IDirect3DDeviceImpl_3_AddViewport,
5571 IDirect3DDeviceImpl_3_DeleteViewport,
5572 IDirect3DDeviceImpl_3_NextViewport,
5573 Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats,
5574 Thunk_IDirect3DDeviceImpl_3_BeginScene,
5575 Thunk_IDirect3DDeviceImpl_3_EndScene,
5576 Thunk_IDirect3DDeviceImpl_3_GetDirect3D,
5577 IDirect3DDeviceImpl_3_SetCurrentViewport,
5578 IDirect3DDeviceImpl_3_GetCurrentViewport,
5579 Thunk_IDirect3DDeviceImpl_3_SetRenderTarget,
5580 Thunk_IDirect3DDeviceImpl_3_GetRenderTarget,
5581 IDirect3DDeviceImpl_3_Begin,
5582 IDirect3DDeviceImpl_3_BeginIndexed,
5583 IDirect3DDeviceImpl_3_Vertex,
5584 IDirect3DDeviceImpl_3_Index,
5585 IDirect3DDeviceImpl_3_End,
5586 Thunk_IDirect3DDeviceImpl_3_GetRenderState,
5587 Thunk_IDirect3DDeviceImpl_3_SetRenderState,
5588 IDirect3DDeviceImpl_3_GetLightState,
5589 IDirect3DDeviceImpl_3_SetLightState,
5590 Thunk_IDirect3DDeviceImpl_3_SetTransform,
5591 Thunk_IDirect3DDeviceImpl_3_GetTransform,
5592 Thunk_IDirect3DDeviceImpl_3_MultiplyTransform,
5593 Thunk_IDirect3DDeviceImpl_3_DrawPrimitive,
5594 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive,
5595 Thunk_IDirect3DDeviceImpl_3_SetClipStatus,
5596 Thunk_IDirect3DDeviceImpl_3_GetClipStatus,
5597 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided,
5598 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided,
5599 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB,
5600 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB,
5601 Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility,
5602 Thunk_IDirect3DDeviceImpl_3_GetTexture,
5603 Thunk_IDirect3DDeviceImpl_3_SetTexture,
5604 Thunk_IDirect3DDeviceImpl_3_GetTextureStageState,
5605 Thunk_IDirect3DDeviceImpl_3_SetTextureStageState,
5606 Thunk_IDirect3DDeviceImpl_3_ValidateDevice
5609 const IDirect3DDevice2Vtbl IDirect3DDevice2_Vtbl =
5611 /*** IUnknown Methods ***/
5612 Thunk_IDirect3DDeviceImpl_2_QueryInterface,
5613 Thunk_IDirect3DDeviceImpl_2_AddRef,
5614 Thunk_IDirect3DDeviceImpl_2_Release,
5615 /*** IDirect3DDevice2 ***/
5616 Thunk_IDirect3DDeviceImpl_2_GetCaps,
5617 IDirect3DDeviceImpl_2_SwapTextureHandles,
5618 Thunk_IDirect3DDeviceImpl_2_GetStats,
5619 Thunk_IDirect3DDeviceImpl_2_AddViewport,
5620 Thunk_IDirect3DDeviceImpl_2_DeleteViewport,
5621 Thunk_IDirect3DDeviceImpl_2_NextViewport,
5622 IDirect3DDeviceImpl_2_EnumTextureFormats,
5623 Thunk_IDirect3DDeviceImpl_2_BeginScene,
5624 Thunk_IDirect3DDeviceImpl_2_EndScene,
5625 Thunk_IDirect3DDeviceImpl_2_GetDirect3D,
5626 Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport,
5627 Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport,
5628 Thunk_IDirect3DDeviceImpl_2_SetRenderTarget,
5629 Thunk_IDirect3DDeviceImpl_2_GetRenderTarget,
5630 Thunk_IDirect3DDeviceImpl_2_Begin,
5631 Thunk_IDirect3DDeviceImpl_2_BeginIndexed,
5632 Thunk_IDirect3DDeviceImpl_2_Vertex,
5633 Thunk_IDirect3DDeviceImpl_2_Index,
5634 Thunk_IDirect3DDeviceImpl_2_End,
5635 IDirect3DDeviceImpl_2_GetRenderState,
5636 IDirect3DDeviceImpl_2_SetRenderState,
5637 Thunk_IDirect3DDeviceImpl_2_GetLightState,
5638 Thunk_IDirect3DDeviceImpl_2_SetLightState,
5639 Thunk_IDirect3DDeviceImpl_2_SetTransform,
5640 Thunk_IDirect3DDeviceImpl_2_GetTransform,
5641 Thunk_IDirect3DDeviceImpl_2_MultiplyTransform,
5642 Thunk_IDirect3DDeviceImpl_2_DrawPrimitive,
5643 Thunk_IDirect3DDeviceImpl_2_DrawIndexedPrimitive,
5644 Thunk_IDirect3DDeviceImpl_2_SetClipStatus,
5645 Thunk_IDirect3DDeviceImpl_2_GetClipStatus
5648 const IDirect3DDeviceVtbl IDirect3DDevice1_Vtbl =
5650 /*** IUnknown Methods ***/
5651 Thunk_IDirect3DDeviceImpl_1_QueryInterface,
5652 Thunk_IDirect3DDeviceImpl_1_AddRef,
5653 Thunk_IDirect3DDeviceImpl_1_Release,
5654 /*** IDirect3DDevice1 ***/
5655 IDirect3DDeviceImpl_1_Initialize,
5656 Thunk_IDirect3DDeviceImpl_1_GetCaps,
5657 Thunk_IDirect3DDeviceImpl_1_SwapTextureHandles,
5658 IDirect3DDeviceImpl_1_CreateExecuteBuffer,
5659 Thunk_IDirect3DDeviceImpl_1_GetStats,
5660 IDirect3DDeviceImpl_1_Execute,
5661 Thunk_IDirect3DDeviceImpl_1_AddViewport,
5662 Thunk_IDirect3DDeviceImpl_1_DeleteViewport,
5663 Thunk_IDirect3DDeviceImpl_1_NextViewport,
5664 IDirect3DDeviceImpl_1_Pick,
5665 IDirect3DDeviceImpl_1_GetPickRecords,
5666 Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats,
5667 IDirect3DDeviceImpl_1_CreateMatrix,
5668 IDirect3DDeviceImpl_1_SetMatrix,
5669 IDirect3DDeviceImpl_1_GetMatrix,
5670 IDirect3DDeviceImpl_1_DeleteMatrix,
5671 Thunk_IDirect3DDeviceImpl_1_BeginScene,
5672 Thunk_IDirect3DDeviceImpl_1_EndScene,
5673 Thunk_IDirect3DDeviceImpl_1_GetDirect3D
5676 /*****************************************************************************
5677 * IDirect3DDeviceImpl_CreateHandle
5679 * Not called from the VTable
5681 * Some older interface versions operate with handles, which are basically
5682 * DWORDs which identify an interface, for example
5683 * IDirect3DDevice::SetRenderState with DIRECT3DRENDERSTATE_TEXTUREHANDLE
5685 * Those handle could be just casts to the interface pointers or vice versa,
5686 * but that is not 64 bit safe and would mean blindly derefering a DWORD
5687 * passed by the app. Instead there is a dynamic array in the device which
5688 * keeps a DWORD to pointer information and a type for the handle.
5690 * Basically this array only grows, when a handle is freed its pointer is
5691 * just set to NULL. There will be much more reads from the array than
5692 * insertion operations, so a dynamic array is fine.
5694 * Params:
5695 * This: D3DDevice implementation for which this handle should be created
5697 * Returns:
5698 * A free handle on success
5699 * 0 on failure
5701 *****************************************************************************/
5702 DWORD
5703 IDirect3DDeviceImpl_CreateHandle(IDirect3DDeviceImpl *This)
5705 DWORD i;
5706 struct HandleEntry *oldHandles = This->Handles;
5708 TRACE("(%p)\n", This);
5710 for(i = 0; i < This->numHandles; i++)
5712 if(This->Handles[i].ptr == NULL &&
5713 This->Handles[i].type == DDrawHandle_Unknown)
5715 TRACE("Reusing freed handle %d\n", i + 1);
5716 return i + 1;
5720 TRACE("Growing the handle array\n");
5722 This->numHandles++;
5723 This->Handles = HeapAlloc(GetProcessHeap(), 0, sizeof(struct HandleEntry) * This->numHandles);
5724 if(!This->Handles)
5726 ERR("Out of memory\n");
5727 This->Handles = oldHandles;
5728 This->numHandles--;
5729 return 0;
5731 if(oldHandles)
5733 memcpy(This->Handles, oldHandles, (This->numHandles - 1) * sizeof(struct HandleEntry));
5734 HeapFree(GetProcessHeap(), 0, oldHandles);
5737 TRACE("Returning %d\n", This->numHandles);
5738 return This->numHandles;
5741 /*****************************************************************************
5742 * IDirect3DDeviceImpl_UpdateDepthStencil
5744 * Checks the current render target for attached depth stencils and sets the
5745 * WineD3D depth stencil accordingly.
5747 * Returns:
5748 * The depth stencil state to set if creating the device
5750 *****************************************************************************/
5751 WINED3DZBUFFERTYPE
5752 IDirect3DDeviceImpl_UpdateDepthStencil(IDirect3DDeviceImpl *This)
5754 IDirectDrawSurface7 *depthStencil = NULL;
5755 IDirectDrawSurfaceImpl *dsi;
5756 static DDSCAPS2 depthcaps = { DDSCAPS_ZBUFFER, 0, 0, 0 };
5758 IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(This->target, IDirectDrawSurface7),
5759 &depthcaps,
5760 &depthStencil);
5761 if(!depthStencil)
5763 TRACE("Setting wined3d depth stencil to NULL\n");
5764 IWineD3DDevice_SetDepthStencilSurface(This->wineD3DDevice,
5765 NULL);
5766 return WINED3DZB_FALSE;
5769 dsi = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, depthStencil);
5770 TRACE("Setting wined3d depth stencil to %p (wined3d %p)\n", dsi, dsi->WineD3DSurface);
5771 IWineD3DDevice_SetDepthStencilSurface(This->wineD3DDevice,
5772 dsi->WineD3DSurface);
5774 IDirectDrawSurface7_Release(depthStencil);
5775 return WINED3DZB_TRUE;