gdiplus: Let GdipDrawArcI use float args version.
[wine.git] / dlls / ddraw / device.c
blob57bb83c283cb12b105334ea60ce296530e4a80cb
1 /*
2 * Copyright (c) 1998-2004 Lionel Ulmer
3 * Copyright (c) 2002-2005 Christian Costa
4 * Copyright (c) 2006 Stefan Dösinger
5 * Copyright (c) 2008 Alexander Dorofeyev
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 * IDirect3DDevice implementation, version 1, 2, 3 and 7. Rendering is relayed
22 * to WineD3D, some minimal DirectDraw specific management is handled here.
23 * The Direct3DDevice is NOT the parent of the WineD3DDevice, because d3d
24 * is initialized when DirectDraw creates the primary surface.
25 * Some type management is necessary, because some D3D types changed between
26 * D3D7 and D3D9.
30 #include "config.h"
31 #include "wine/port.h"
33 #include <assert.h>
34 #include <stdarg.h>
35 #include <string.h>
36 #include <stdlib.h>
38 #define COBJMACROS
39 #define NONAMELESSUNION
41 #include "windef.h"
42 #include "winbase.h"
43 #include "winerror.h"
44 #include "wingdi.h"
45 #include "wine/exception.h"
47 #include "ddraw.h"
48 #include "d3d.h"
50 #include "ddraw_private.h"
51 #include "wine/debug.h"
53 WINE_DEFAULT_DEBUG_CHANNEL(d3d7);
54 WINE_DECLARE_DEBUG_CHANNEL(ddraw_thunk);
56 /* The device ID */
57 const GUID IID_D3DDEVICE_WineD3D = {
58 0xaef72d43,
59 0xb09a,
60 0x4b7b,
61 { 0xb7,0x98,0xc6,0x8a,0x77,0x2d,0x72,0x2a }
64 /*****************************************************************************
65 * IUnknown Methods. Common for Version 1, 2, 3 and 7
66 *****************************************************************************/
68 /*****************************************************************************
69 * IDirect3DDevice7::QueryInterface
71 * Used to query other interfaces from a Direct3DDevice interface.
72 * It can return interface pointers to all Direct3DDevice versions as well
73 * as IDirectDraw and IDirect3D. For a link to QueryInterface
74 * rules see ddraw.c, IDirectDraw7::QueryInterface
76 * Exists in Version 1, 2, 3 and 7
78 * Params:
79 * refiid: Interface ID queried for
80 * obj: Used to return the interface pointer
82 * Returns:
83 * D3D_OK or E_NOINTERFACE
85 *****************************************************************************/
86 static HRESULT WINAPI
87 IDirect3DDeviceImpl_7_QueryInterface(IDirect3DDevice7 *iface,
88 REFIID refiid,
89 void **obj)
91 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
92 TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(refiid), obj);
94 /* According to COM docs, if the QueryInterface fails, obj should be set to NULL */
95 *obj = NULL;
97 if(!refiid)
98 return DDERR_INVALIDPARAMS;
100 if ( IsEqualGUID( &IID_IUnknown, refiid ) )
102 *obj = ICOM_INTERFACE(This, IDirect3DDevice7);
105 /* Check DirectDraw Interfac\x01s */
106 else if( IsEqualGUID( &IID_IDirectDraw7, refiid ) )
108 *obj = ICOM_INTERFACE(This->ddraw, IDirectDraw7);
109 TRACE("(%p) Returning IDirectDraw7 interface at %p\n", This, *obj);
111 else if ( IsEqualGUID( &IID_IDirectDraw4, refiid ) )
113 *obj = ICOM_INTERFACE(This->ddraw, IDirectDraw4);
114 TRACE("(%p) Returning IDirectDraw4 interface at %p\n", This, *obj);
116 else if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) )
118 *obj = ICOM_INTERFACE(This->ddraw, IDirectDraw2);
119 TRACE("(%p) Returning IDirectDraw2 interface at %p\n", This, *obj);
121 else if( IsEqualGUID( &IID_IDirectDraw, refiid ) )
123 *obj = ICOM_INTERFACE(This->ddraw, IDirectDraw);
124 TRACE("(%p) Returning IDirectDraw interface at %p\n", This, *obj);
127 /* Direct3D */
128 else if ( IsEqualGUID( &IID_IDirect3D , refiid ) )
130 *obj = ICOM_INTERFACE(This->ddraw, IDirect3D);
131 TRACE("(%p) Returning IDirect3D interface at %p\n", This, *obj);
133 else if ( IsEqualGUID( &IID_IDirect3D2 , refiid ) )
135 *obj = ICOM_INTERFACE(This->ddraw, IDirect3D2);
136 TRACE("(%p) Returning IDirect3D2 interface at %p\n", This, *obj);
138 else if ( IsEqualGUID( &IID_IDirect3D3 , refiid ) )
140 *obj = ICOM_INTERFACE(This->ddraw, IDirect3D3);
141 TRACE("(%p) Returning IDirect3D3 interface at %p\n", This, *obj);
143 else if ( IsEqualGUID( &IID_IDirect3D7 , refiid ) )
145 *obj = ICOM_INTERFACE(This->ddraw, IDirect3D7);
146 TRACE("(%p) Returning IDirect3D7 interface at %p\n", This, *obj);
149 /* Direct3DDevice */
150 else if ( IsEqualGUID( &IID_IDirect3DDevice , refiid ) )
152 *obj = ICOM_INTERFACE(This, IDirect3DDevice);
153 TRACE("(%p) Returning IDirect3DDevice interface at %p\n", This, *obj);
155 else if ( IsEqualGUID( &IID_IDirect3DDevice2 , refiid ) ) {
156 *obj = ICOM_INTERFACE(This, IDirect3DDevice2);
157 TRACE("(%p) Returning IDirect3DDevice2 interface at %p\n", This, *obj);
159 else if ( IsEqualGUID( &IID_IDirect3DDevice3 , refiid ) ) {
160 *obj = ICOM_INTERFACE(This, IDirect3DDevice3);
161 TRACE("(%p) Returning IDirect3DDevice3 interface at %p\n", This, *obj);
163 else if ( IsEqualGUID( &IID_IDirect3DDevice7 , refiid ) ) {
164 *obj = ICOM_INTERFACE(This, IDirect3DDevice7);
165 TRACE("(%p) Returning IDirect3DDevice7 interface at %p\n", This, *obj);
168 /* Unknown interface */
169 else
171 ERR("(%p)->(%s, %p): No interface found\n", This, debugstr_guid(refiid), obj);
172 return E_NOINTERFACE;
175 /* AddRef the returned interface */
176 IUnknown_AddRef( (IUnknown *) *obj);
177 return D3D_OK;
180 static HRESULT WINAPI
181 Thunk_IDirect3DDeviceImpl_3_QueryInterface(IDirect3DDevice3 *iface,
182 REFIID riid,
183 void **obj)
185 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
186 TRACE_(ddraw_thunk)("(%p)->(%s,%p) thunking to IDirect3DDevice7 interface.\n", This, debugstr_guid(riid), obj);
187 return IDirect3DDevice7_QueryInterface(ICOM_INTERFACE(This, IDirect3DDevice7),
188 riid,
189 obj);
192 static HRESULT WINAPI
193 Thunk_IDirect3DDeviceImpl_2_QueryInterface(IDirect3DDevice2 *iface,
194 REFIID riid,
195 void **obj)
197 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
198 TRACE_(ddraw_thunk)("(%p)->(%s,%p) thunking to IDirect3DDevice7 interface.\n", This, debugstr_guid(riid), obj);
199 return IDirect3DDevice7_QueryInterface(ICOM_INTERFACE(This, IDirect3DDevice7),
200 riid,
201 obj);
204 static HRESULT WINAPI
205 Thunk_IDirect3DDeviceImpl_1_QueryInterface(IDirect3DDevice *iface,
206 REFIID riid,
207 void **obp)
209 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
210 TRACE_(ddraw_thunk)("(%p)->(%s,%p) thunking to IDirect3DDevice7 interface.\n", This, debugstr_guid(riid), obp);
211 return IDirect3DDevice7_QueryInterface(ICOM_INTERFACE(This, IDirect3DDevice7),
212 riid,
213 obp);
216 /*****************************************************************************
217 * IDirect3DDevice7::AddRef
219 * Increases the refcount....
220 * The most exciting Method, definitely
222 * Exists in Version 1, 2, 3 and 7
224 * Returns:
225 * The new refcount
227 *****************************************************************************/
228 static ULONG WINAPI
229 IDirect3DDeviceImpl_7_AddRef(IDirect3DDevice7 *iface)
231 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
232 ULONG ref = InterlockedIncrement(&This->ref);
234 TRACE("(%p) : incrementing from %u.\n", This, ref -1);
236 return ref;
239 static ULONG WINAPI
240 Thunk_IDirect3DDeviceImpl_3_AddRef(IDirect3DDevice3 *iface)
242 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
243 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
244 return IDirect3DDevice7_AddRef(ICOM_INTERFACE(This, IDirect3DDevice7));
247 static ULONG WINAPI
248 Thunk_IDirect3DDeviceImpl_2_AddRef(IDirect3DDevice2 *iface)
250 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
251 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
252 return IDirect3DDevice7_AddRef(ICOM_INTERFACE(This, IDirect3DDevice7));
255 static ULONG WINAPI
256 Thunk_IDirect3DDeviceImpl_1_AddRef(IDirect3DDevice *iface)
258 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", iface);
259 return IDirect3DDevice7_AddRef(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice7, iface));
262 /*****************************************************************************
263 * IDirect3DDevice7::Release
265 * Decreases the refcount of the interface
266 * When the refcount is reduced to 0, the object is destroyed.
268 * Exists in Version 1, 2, 3 and 7
270 * Returns:d
271 * The new refcount
273 *****************************************************************************/
274 static ULONG WINAPI
275 IDirect3DDeviceImpl_7_Release(IDirect3DDevice7 *iface)
277 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
278 ULONG ref = InterlockedDecrement(&This->ref);
280 TRACE("(%p)->() decrementing from %u.\n", This, ref +1);
282 /* This method doesn't destroy the WineD3DDevice, because it's still in use for
283 * 2D rendering. IDirectDrawSurface7::Release will destroy the WineD3DDevice
284 * when the render target is released
286 if (ref == 0)
288 IParent *IndexBufferParent;
289 DWORD i;
291 EnterCriticalSection(&ddraw_cs);
292 /* Free the index buffer. */
293 IWineD3DDevice_SetIndices(This->wineD3DDevice, NULL);
294 IWineD3DIndexBuffer_GetParent(This->indexbuffer,
295 (IUnknown **) &IndexBufferParent);
296 IParent_Release(IndexBufferParent); /* Once for the getParent */
297 if( IParent_Release(IndexBufferParent) != 0) /* And now to destroy it */
299 ERR(" (%p) Something is still holding the index buffer parent %p\n", This, IndexBufferParent);
302 /* There is no need to unset the vertex buffer here, IWineD3DDevice_Uninit3D will do that when
303 * destroying the primary stateblock. If a vertex buffer is destroyed while it is bound
304 * IDirect3DVertexBuffer::Release will unset it.
307 /* Restore the render targets */
308 if(This->OffScreenTarget)
310 WINED3DVIEWPORT vp;
312 vp.X = 0;
313 vp.Y = 0;
314 vp.Width = This->ddraw->d3d_target->surface_desc.dwWidth;
315 vp.Height = This->ddraw->d3d_target->surface_desc.dwHeight;
316 vp.MinZ = 0.0;
317 vp.MaxZ = 1.0;
318 IWineD3DDevice_SetViewport(This->wineD3DDevice,
319 &vp);
321 /* Set the device up to render to the front buffer since the back buffer will
322 * vanish soon.
324 IWineD3DDevice_SetRenderTarget(This->wineD3DDevice, 0,
325 This->ddraw->d3d_target->WineD3DSurface);
326 /* This->target is the offscreen target.
327 * This->ddraw->d3d_target is the target used by DDraw
329 TRACE("(%p) Release: Using %p as front buffer, %p as back buffer\n", This, This->ddraw->d3d_target, NULL);
330 IWineD3DDevice_SetFrontBackBuffers(This->wineD3DDevice,
331 This->ddraw->d3d_target->WineD3DSurface,
332 NULL);
335 /* Release the WineD3DDevice. This won't destroy it */
336 if(IWineD3DDevice_Release(This->wineD3DDevice) <= 0)
338 ERR(" (%p) The wineD3D device %p was destroyed unexpectedly. Prepare for trouble\n", This, This->wineD3DDevice);
341 /* The texture handles should be unset by now, but there might be some bits
342 * missing in our reference counting(needs test). Do a sanity check
344 for(i = 0; i < This->numHandles; i++)
346 if(This->Handles[i].ptr)
348 switch(This->Handles[i].type)
350 case DDrawHandle_Texture:
352 IDirectDrawSurfaceImpl *surf = (IDirectDrawSurfaceImpl *) This->Handles[i].ptr;
353 FIXME("Texture Handle %d not unset properly\n", i + 1);
354 surf->Handle = 0;
356 break;
358 case DDrawHandle_Material:
360 IDirect3DMaterialImpl *mat = (IDirect3DMaterialImpl *) This->Handles[i].ptr;
361 FIXME("Material handle %d not unset properly\n", i + 1);
362 mat->Handle = 0;
364 break;
366 case DDrawHandle_Matrix:
368 /* No fixme here because this might happen because of sloppy apps */
369 WARN("Leftover matrix handle %d, deleting\n", i + 1);
370 IDirect3DDevice_DeleteMatrix(ICOM_INTERFACE(This, IDirect3DDevice),
371 i + 1);
373 break;
375 case DDrawHandle_StateBlock:
377 /* No fixme here because this might happen because of sloppy apps */
378 WARN("Leftover stateblock handle %d, deleting\n", i + 1);
379 IDirect3DDevice7_DeleteStateBlock(ICOM_INTERFACE(This, IDirect3DDevice7),
380 i + 1);
382 break;
384 default:
385 FIXME("Unknown handle %d not unset properly\n", i + 1);
390 HeapFree(GetProcessHeap(), 0, This->Handles);
392 TRACE("Releasing target %p %p\n", This->target, This->ddraw->d3d_target);
393 /* Release the render target and the WineD3D render target
394 * (See IDirect3D7::CreateDevice for more comments on this)
396 IDirectDrawSurface7_Release(ICOM_INTERFACE(This->target, IDirectDrawSurface7));
397 IDirectDrawSurface7_Release(ICOM_INTERFACE(This->ddraw->d3d_target,IDirectDrawSurface7));
398 TRACE("Target release done\n");
400 This->ddraw->d3ddevice = NULL;
402 /* Now free the structure */
403 HeapFree(GetProcessHeap(), 0, This);
404 LeaveCriticalSection(&ddraw_cs);
407 TRACE("Done\n");
408 return ref;
411 static ULONG WINAPI
412 Thunk_IDirect3DDeviceImpl_3_Release(IDirect3DDevice3 *iface)
414 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
415 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
416 return IDirect3DDevice7_Release(ICOM_INTERFACE(This, IDirect3DDevice7));
419 static ULONG WINAPI
420 Thunk_IDirect3DDeviceImpl_2_Release(IDirect3DDevice2 *iface)
422 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
423 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
424 return IDirect3DDevice7_Release(ICOM_INTERFACE(This, IDirect3DDevice7));
427 static ULONG WINAPI
428 Thunk_IDirect3DDeviceImpl_1_Release(IDirect3DDevice *iface)
430 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
431 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
432 return IDirect3DDevice7_Release(ICOM_INTERFACE(This, IDirect3DDevice7));
435 /*****************************************************************************
436 * IDirect3DDevice Methods
437 *****************************************************************************/
439 /*****************************************************************************
440 * IDirect3DDevice::Initialize
442 * Initializes a Direct3DDevice. This implementation is a no-op, as all
443 * initialization is done at create time.
445 * Exists in Version 1
447 * Parameters:
448 * No idea what they mean, as the MSDN page is gone
450 * Returns: DD_OK
452 *****************************************************************************/
453 static HRESULT WINAPI
454 IDirect3DDeviceImpl_1_Initialize(IDirect3DDevice *iface,
455 IDirect3D *Direct3D, GUID *guid,
456 D3DDEVICEDESC *Desc)
458 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
460 /* It shouldn't be crucial, but print a FIXME, I'm interested if
461 * any game calls it and when
463 FIXME("(%p)->(%p,%p,%p): No-op!\n", This, Direct3D, guid, Desc);
465 return D3D_OK;
468 /*****************************************************************************
469 * IDirect3DDevice7::GetCaps
471 * Retrieves the device's capabilities
473 * This implementation is used for Version 7 only, the older versions have
474 * their own implementation.
476 * Parameters:
477 * Desc: Pointer to a D3DDEVICEDESC7 structure to fill
479 * Returns:
480 * D3D_OK on success
481 * D3DERR_* if a problem occurs. See WineD3D
483 *****************************************************************************/
484 static HRESULT WINAPI
485 IDirect3DDeviceImpl_7_GetCaps(IDirect3DDevice7 *iface,
486 D3DDEVICEDESC7 *Desc)
488 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
489 D3DDEVICEDESC OldDesc;
490 TRACE("(%p)->(%p)\n", This, Desc);
492 /* Call the same function used by IDirect3D, this saves code */
493 return IDirect3DImpl_GetCaps(This->ddraw->wineD3D, &OldDesc, Desc);
496 /*****************************************************************************
497 * IDirect3DDevice3::GetCaps
499 * Retrieves the capabilities of the hardware device and the emulation
500 * device. For Wine, hardware and emulation are the same (it's all HW).
502 * This implementation is used for Version 1, 2, and 3. Version 7 has its own
504 * Parameters:
505 * HWDesc: Structure to fill with the HW caps
506 * HelDesc: Structure to fill with the hardware emulation caps
508 * Returns:
509 * D3D_OK on success
510 * D3DERR_* if a problem occurs. See WineD3D
512 *****************************************************************************/
513 static HRESULT WINAPI
514 IDirect3DDeviceImpl_3_GetCaps(IDirect3DDevice3 *iface,
515 D3DDEVICEDESC *HWDesc,
516 D3DDEVICEDESC *HelDesc)
518 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
519 D3DDEVICEDESC7 newDesc;
520 HRESULT hr;
521 TRACE("(%p)->(%p,%p)\n", iface, HWDesc, HelDesc);
523 hr = IDirect3DImpl_GetCaps(This->ddraw->wineD3D, HWDesc, &newDesc);
524 if(hr != D3D_OK) return hr;
526 *HelDesc = *HWDesc;
527 return D3D_OK;
530 static HRESULT WINAPI
531 Thunk_IDirect3DDeviceImpl_2_GetCaps(IDirect3DDevice2 *iface,
532 D3DDEVICEDESC *D3DHWDevDesc,
533 D3DDEVICEDESC *D3DHELDevDesc)
535 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
536 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice3 interface.\n", This, D3DHWDevDesc, D3DHELDevDesc);
537 return IDirect3DDevice3_GetCaps(ICOM_INTERFACE(This, IDirect3DDevice3),
538 D3DHWDevDesc,
539 D3DHELDevDesc);
542 static HRESULT WINAPI
543 Thunk_IDirect3DDeviceImpl_1_GetCaps(IDirect3DDevice *iface,
544 D3DDEVICEDESC *D3DHWDevDesc,
545 D3DDEVICEDESC *D3DHELDevDesc)
547 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
548 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice3 interface.\n", This, D3DHWDevDesc, D3DHELDevDesc);
549 return IDirect3DDevice3_GetCaps(ICOM_INTERFACE(This, IDirect3DDevice3),
550 D3DHWDevDesc,
551 D3DHELDevDesc);
554 /*****************************************************************************
555 * IDirect3DDevice2::SwapTextureHandles
557 * Swaps the texture handles of 2 Texture interfaces. Version 1 and 2
559 * Parameters:
560 * Tex1, Tex2: The 2 Textures to swap
562 * Returns:
563 * D3D_OK
565 *****************************************************************************/
566 static HRESULT WINAPI
567 IDirect3DDeviceImpl_2_SwapTextureHandles(IDirect3DDevice2 *iface,
568 IDirect3DTexture2 *Tex1,
569 IDirect3DTexture2 *Tex2)
571 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
572 DWORD swap;
573 IDirectDrawSurfaceImpl *surf1 = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture2, Tex1);
574 IDirectDrawSurfaceImpl *surf2 = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture2, Tex2);
575 TRACE("(%p)->(%p,%p)\n", This, surf1, surf2);
577 EnterCriticalSection(&ddraw_cs);
578 This->Handles[surf1->Handle - 1].ptr = surf2;
579 This->Handles[surf2->Handle - 1].ptr = surf1;
581 swap = surf2->Handle;
582 surf2->Handle = surf1->Handle;
583 surf1->Handle = swap;
584 LeaveCriticalSection(&ddraw_cs);
586 return D3D_OK;
589 static HRESULT WINAPI
590 Thunk_IDirect3DDeviceImpl_1_SwapTextureHandles(IDirect3DDevice *iface,
591 IDirect3DTexture *D3DTex1,
592 IDirect3DTexture *D3DTex2)
594 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
595 IDirectDrawSurfaceImpl *surf1 = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture, D3DTex1);
596 IDirectDrawSurfaceImpl *surf2 = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture, D3DTex2);
597 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice2 interface.\n", This, surf1, surf2);
598 return IDirect3DDevice2_SwapTextureHandles(ICOM_INTERFACE(This, IDirect3DDevice2),
599 ICOM_INTERFACE(surf1, IDirect3DTexture2),
600 ICOM_INTERFACE(surf2, IDirect3DTexture2));
603 /*****************************************************************************
604 * IDirect3DDevice3::GetStats
606 * This method seems to retrieve some stats from the device.
607 * The MSDN documentation doesn't exist any more, but the D3DSTATS
608 * structure suggests that the amount of drawn primitives and processed
609 * vertices is returned.
611 * Exists in Version 1, 2 and 3
613 * Parameters:
614 * Stats: Pointer to a D3DSTATS structure to be filled
616 * Returns:
617 * D3D_OK on success
618 * DDERR_INVALIDPARAMS if Stats == NULL
620 *****************************************************************************/
621 static HRESULT WINAPI
622 IDirect3DDeviceImpl_3_GetStats(IDirect3DDevice3 *iface,
623 D3DSTATS *Stats)
625 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
626 FIXME("(%p)->(%p): Stub!\n", This, Stats);
628 if(!Stats)
629 return DDERR_INVALIDPARAMS;
631 /* Fill the Stats with 0 */
632 Stats->dwTrianglesDrawn = 0;
633 Stats->dwLinesDrawn = 0;
634 Stats->dwPointsDrawn = 0;
635 Stats->dwSpansDrawn = 0;
636 Stats->dwVerticesProcessed = 0;
638 return D3D_OK;
641 static HRESULT WINAPI
642 Thunk_IDirect3DDeviceImpl_2_GetStats(IDirect3DDevice2 *iface,
643 D3DSTATS *Stats)
645 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
646 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, Stats);
647 return IDirect3DDevice3_GetStats(ICOM_INTERFACE(This, IDirect3DDevice3),
648 Stats);
651 static HRESULT WINAPI
652 Thunk_IDirect3DDeviceImpl_1_GetStats(IDirect3DDevice *iface,
653 D3DSTATS *Stats)
655 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
656 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, Stats);
657 return IDirect3DDevice3_GetStats(ICOM_INTERFACE(This, IDirect3DDevice3),
658 Stats);
661 /*****************************************************************************
662 * IDirect3DDevice::CreateExecuteBuffer
664 * Creates an IDirect3DExecuteBuffer, used for rendering with a
665 * Direct3DDevice.
667 * Version 1 only.
669 * Params:
670 * Desc: Buffer description
671 * ExecuteBuffer: Address to return the Interface pointer at
672 * UnkOuter: Must be NULL. Basically for aggregation, which ddraw doesn't
673 * support
675 * Returns:
676 * CLASS_E_NOAGGREGATION if UnkOuter != NULL
677 * DDERR_OUTOFMEMORY if we ran out of memory
678 * D3D_OK on success
680 *****************************************************************************/
681 static HRESULT WINAPI
682 IDirect3DDeviceImpl_1_CreateExecuteBuffer(IDirect3DDevice *iface,
683 D3DEXECUTEBUFFERDESC *Desc,
684 IDirect3DExecuteBuffer **ExecuteBuffer,
685 IUnknown *UnkOuter)
687 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
688 IDirect3DExecuteBufferImpl* object;
689 TRACE("(%p)->(%p,%p,%p)!\n", This, Desc, ExecuteBuffer, UnkOuter);
691 if(UnkOuter)
692 return CLASS_E_NOAGGREGATION;
694 /* Allocate the new Execute Buffer */
695 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DExecuteBufferImpl));
696 if(!object)
698 ERR("Out of memory when allocating a IDirect3DExecuteBufferImpl structure\n");
699 return DDERR_OUTOFMEMORY;
702 ICOM_INIT_INTERFACE(object, IDirect3DExecuteBuffer, IDirect3DExecuteBuffer_Vtbl);
704 object->ref = 1;
705 object->d3ddev = This;
707 /* Initializes memory */
708 memcpy(&object->desc, Desc, Desc->dwSize);
710 /* No buffer given */
711 if ((object->desc.dwFlags & D3DDEB_LPDATA) == 0)
712 object->desc.lpData = NULL;
714 /* No buffer size given */
715 if ((object->desc.dwFlags & D3DDEB_BUFSIZE) == 0)
716 object->desc.dwBufferSize = 0;
718 /* Create buffer if asked */
719 if ((object->desc.lpData == NULL) && (object->desc.dwBufferSize > 0))
721 object->need_free = TRUE;
722 object->desc.lpData = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,object->desc.dwBufferSize);
723 if(!object->desc.lpData)
725 ERR("Out of memory when allocating the execute buffer data\n");
726 HeapFree(GetProcessHeap(), 0, object);
727 return DDERR_OUTOFMEMORY;
730 else
732 object->need_free = FALSE;
735 /* No vertices for the moment */
736 object->vertex_data = NULL;
738 object->desc.dwFlags |= D3DDEB_LPDATA;
740 object->indices = NULL;
741 object->nb_indices = 0;
743 *ExecuteBuffer = ICOM_INTERFACE(object, IDirect3DExecuteBuffer);
745 TRACE(" Returning IDirect3DExecuteBuffer at %p, implementation is at %p\n", *ExecuteBuffer, object);
747 return D3D_OK;
750 /*****************************************************************************
751 * IDirect3DDevice::Execute
753 * Executes all the stuff in an execute buffer.
755 * Params:
756 * ExecuteBuffer: The buffer to execute
757 * Viewport: The viewport used for rendering
758 * Flags: Some flags
760 * Returns:
761 * DDERR_INVALIDPARAMS if ExecuteBuffer == NULL
762 * D3D_OK on success
764 *****************************************************************************/
765 static HRESULT WINAPI
766 IDirect3DDeviceImpl_1_Execute(IDirect3DDevice *iface,
767 IDirect3DExecuteBuffer *ExecuteBuffer,
768 IDirect3DViewport *Viewport,
769 DWORD Flags)
771 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
772 IDirect3DExecuteBufferImpl *Direct3DExecuteBufferImpl = ICOM_OBJECT(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, ExecuteBuffer);
773 IDirect3DViewportImpl *Direct3DViewportImpl = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport);
775 TRACE("(%p)->(%p,%p,%08x)\n", This, Direct3DExecuteBufferImpl, Direct3DViewportImpl, Flags);
777 if(!Direct3DExecuteBufferImpl)
778 return DDERR_INVALIDPARAMS;
780 /* Execute... */
781 EnterCriticalSection(&ddraw_cs);
782 IDirect3DExecuteBufferImpl_Execute(Direct3DExecuteBufferImpl, This, Direct3DViewportImpl);
783 LeaveCriticalSection(&ddraw_cs);
785 return D3D_OK;
788 /*****************************************************************************
789 * IDirect3DDevice3::AddViewport
791 * Add a Direct3DViewport to the device's viewport list. These viewports
792 * are wrapped to IDirect3DDevice7 viewports in viewport.c
794 * Exists in Version 1, 2 and 3. Note that IDirect3DViewport 1, 2 and 3
795 * are the same interfaces.
797 * Params:
798 * Viewport: The viewport to add
800 * Returns:
801 * DDERR_INVALIDPARAMS if Viewport == NULL
802 * D3D_OK on success
804 *****************************************************************************/
805 static HRESULT WINAPI
806 IDirect3DDeviceImpl_3_AddViewport(IDirect3DDevice3 *iface,
807 IDirect3DViewport3 *Viewport)
809 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
810 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport);
812 TRACE("(%p)->(%p)\n", This, vp);
814 /* Sanity check */
815 if(!vp)
816 return DDERR_INVALIDPARAMS;
818 EnterCriticalSection(&ddraw_cs);
819 vp->next = This->viewport_list;
820 This->viewport_list = vp;
821 vp->active_device = This; /* Viewport must be usable for Clear() after AddViewport,
822 so set active_device here. */
823 LeaveCriticalSection(&ddraw_cs);
825 return D3D_OK;
828 static HRESULT WINAPI
829 Thunk_IDirect3DDeviceImpl_2_AddViewport(IDirect3DDevice2 *iface,
830 IDirect3DViewport2 *Direct3DViewport2)
832 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
833 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport2);
834 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
835 return IDirect3DDevice3_AddViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
836 ICOM_INTERFACE(vp, IDirect3DViewport3));
839 static HRESULT WINAPI
840 Thunk_IDirect3DDeviceImpl_1_AddViewport(IDirect3DDevice *iface,
841 IDirect3DViewport *Direct3DViewport)
843 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
844 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport);
845 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
846 return IDirect3DDevice3_AddViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
847 ICOM_INTERFACE(vp, IDirect3DViewport3));
850 /*****************************************************************************
851 * IDirect3DDevice3::DeleteViewport
853 * Deletes a Direct3DViewport from the device's viewport list.
855 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
856 * are equal.
858 * Params:
859 * Viewport: The viewport to delete
861 * Returns:
862 * D3D_OK on success
863 * DDERR_INVALIDPARAMS if the viewport wasn't found in the list
865 *****************************************************************************/
866 static HRESULT WINAPI
867 IDirect3DDeviceImpl_3_DeleteViewport(IDirect3DDevice3 *iface,
868 IDirect3DViewport3 *Viewport)
870 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
871 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *) Viewport;
872 IDirect3DViewportImpl *cur_viewport, *prev_viewport = NULL;
874 TRACE("(%p)->(%p)\n", This, vp);
876 EnterCriticalSection(&ddraw_cs);
877 cur_viewport = This->viewport_list;
878 while (cur_viewport != NULL)
880 if (cur_viewport == vp)
882 if (prev_viewport == NULL) This->viewport_list = cur_viewport->next;
883 else prev_viewport->next = cur_viewport->next;
884 /* TODO : add desactivate of the viewport and all associated lights... */
885 LeaveCriticalSection(&ddraw_cs);
886 return D3D_OK;
888 prev_viewport = cur_viewport;
889 cur_viewport = cur_viewport->next;
892 LeaveCriticalSection(&ddraw_cs);
893 return DDERR_INVALIDPARAMS;
896 static HRESULT WINAPI
897 Thunk_IDirect3DDeviceImpl_2_DeleteViewport(IDirect3DDevice2 *iface,
898 IDirect3DViewport2 *Direct3DViewport2)
900 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
901 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport2);
902 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
903 return IDirect3DDevice3_DeleteViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
904 ICOM_INTERFACE(vp, IDirect3DViewport3));
907 static HRESULT WINAPI
908 Thunk_IDirect3DDeviceImpl_1_DeleteViewport(IDirect3DDevice *iface,
909 IDirect3DViewport *Direct3DViewport)
911 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
912 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport);
913 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
914 return IDirect3DDevice3_DeleteViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
915 ICOM_INTERFACE(vp, IDirect3DViewport3));
918 /*****************************************************************************
919 * IDirect3DDevice3::NextViewport
921 * Returns a viewport from the viewport list, depending on the
922 * passed viewport and the flags.
924 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
925 * are equal.
927 * Params:
928 * Viewport: Viewport to use for beginning the search
929 * Flags: D3DNEXT_NEXT, D3DNEXT_HEAD or D3DNEXT_TAIL
931 * Returns:
932 * D3D_OK on success
933 * DDERR_INVALIDPARAMS if the flags were wrong, or Viewport was NULL
935 *****************************************************************************/
936 static HRESULT WINAPI
937 IDirect3DDeviceImpl_3_NextViewport(IDirect3DDevice3 *iface,
938 IDirect3DViewport3 *Viewport3,
939 IDirect3DViewport3 **lplpDirect3DViewport3,
940 DWORD Flags)
942 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
943 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport3);
944 IDirect3DViewportImpl *res = NULL;
946 TRACE("(%p)->(%p,%p,%08x)\n", This, vp, lplpDirect3DViewport3, Flags);
948 if(!vp)
950 *lplpDirect3DViewport3 = NULL;
951 return DDERR_INVALIDPARAMS;
955 EnterCriticalSection(&ddraw_cs);
956 switch (Flags)
958 case D3DNEXT_NEXT:
960 res = vp->next;
962 break;
963 case D3DNEXT_HEAD:
965 res = This->viewport_list;
967 break;
968 case D3DNEXT_TAIL:
970 IDirect3DViewportImpl *cur_viewport = This->viewport_list;
971 if (cur_viewport != NULL)
973 while (cur_viewport->next != NULL) cur_viewport = cur_viewport->next;
975 res = cur_viewport;
977 break;
978 default:
979 *lplpDirect3DViewport3 = NULL;
980 LeaveCriticalSection(&ddraw_cs);
981 return DDERR_INVALIDPARAMS;
984 *lplpDirect3DViewport3 = ICOM_INTERFACE(res, IDirect3DViewport3);
985 LeaveCriticalSection(&ddraw_cs);
986 return D3D_OK;
989 static HRESULT WINAPI
990 Thunk_IDirect3DDeviceImpl_2_NextViewport(IDirect3DDevice2 *iface,
991 IDirect3DViewport2 *Viewport2,
992 IDirect3DViewport2 **lplpDirect3DViewport2,
993 DWORD Flags)
995 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
996 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport2);
997 IDirect3DViewport3 *res;
998 HRESULT hr;
999 TRACE_(ddraw_thunk)("(%p)->(%p,%p,%08x) thunking to IDirect3DDevice3 interface.\n", This, vp, lplpDirect3DViewport2, Flags);
1000 hr = IDirect3DDevice3_NextViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
1001 ICOM_INTERFACE(vp, IDirect3DViewport3),
1002 &res,
1003 Flags);
1004 *lplpDirect3DViewport2 = (IDirect3DViewport2 *) COM_INTERFACE_CAST(IDirect3DViewportImpl, IDirect3DViewport3, IDirect3DViewport3, res);
1005 return hr;
1008 static HRESULT WINAPI
1009 Thunk_IDirect3DDeviceImpl_1_NextViewport(IDirect3DDevice *iface,
1010 IDirect3DViewport *Viewport,
1011 IDirect3DViewport **lplpDirect3DViewport,
1012 DWORD Flags)
1014 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1015 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport);
1016 IDirect3DViewport3 *res;
1017 HRESULT hr;
1018 TRACE_(ddraw_thunk)("(%p)->(%p,%p,%08x) thunking to IDirect3DDevice3 interface.\n", This, vp, lplpDirect3DViewport, Flags);
1019 hr = IDirect3DDevice3_NextViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
1020 ICOM_INTERFACE(vp, IDirect3DViewport3),
1021 &res,
1022 Flags);
1023 *lplpDirect3DViewport = (IDirect3DViewport *) COM_INTERFACE_CAST(IDirect3DViewportImpl, IDirect3DViewport3, IDirect3DViewport3, res);
1024 return hr;
1027 /*****************************************************************************
1028 * IDirect3DDevice::Pick
1030 * Executes an execute buffer without performing rendering. Instead, a
1031 * list of primitives that intersect with (x1,y1) of the passed rectangle
1032 * is created. IDirect3DDevice::GetPickRecords can be used to retrieve
1033 * this list.
1035 * Version 1 only
1037 * Params:
1038 * ExecuteBuffer: Buffer to execute
1039 * Viewport: Viewport to use for execution
1040 * Flags: None are defined, according to the SDK
1041 * Rect: Specifies the coordinates to be picked. Only x1 and y2 are used,
1042 * x2 and y2 are ignored.
1044 * Returns:
1045 * D3D_OK because it's a stub
1047 *****************************************************************************/
1048 static HRESULT WINAPI
1049 IDirect3DDeviceImpl_1_Pick(IDirect3DDevice *iface,
1050 IDirect3DExecuteBuffer *ExecuteBuffer,
1051 IDirect3DViewport *Viewport,
1052 DWORD Flags,
1053 D3DRECT *Rect)
1055 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1056 IDirect3DExecuteBufferImpl *execbuf = ICOM_OBJECT(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, ExecuteBuffer);
1057 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport);
1058 FIXME("(%p)->(%p,%p,%08x,%p): stub!\n", This, execbuf, vp, Flags, Rect);
1060 return D3D_OK;
1063 /*****************************************************************************
1064 * IDirect3DDevice::GetPickRecords
1066 * Retrieves the pick records generated by IDirect3DDevice::GetPickRecords
1068 * Version 1 only
1070 * Params:
1071 * Count: Pointer to a DWORD containing the numbers of pick records to
1072 * retrieve
1073 * D3DPickRec: Address to store the resulting D3DPICKRECORD array.
1075 * Returns:
1076 * D3D_OK, because it's a stub
1078 *****************************************************************************/
1079 static HRESULT WINAPI
1080 IDirect3DDeviceImpl_1_GetPickRecords(IDirect3DDevice *iface,
1081 DWORD *Count,
1082 D3DPICKRECORD *D3DPickRec)
1084 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1085 FIXME("(%p)->(%p,%p): stub!\n", This, Count, D3DPickRec);
1087 return D3D_OK;
1090 /*****************************************************************************
1091 * IDirect3DDevice7::EnumTextureformats
1093 * Enumerates the supported texture formats. It has a list of all possible
1094 * formats and calls IWineD3D::CheckDeviceFormat for each format to see if
1095 * WineD3D supports it. If so, then it is passed to the app.
1097 * This is for Version 7 and 3, older versions have a different
1098 * callback function and their own implementation
1100 * Params:
1101 * Callback: Callback to call for each enumerated format
1102 * Arg: Argument to pass to the callback
1104 * Returns:
1105 * D3D_OK on success
1106 * DDERR_INVALIDPARAMS if Callback == NULL
1108 *****************************************************************************/
1109 static HRESULT WINAPI
1110 IDirect3DDeviceImpl_7_EnumTextureFormats(IDirect3DDevice7 *iface,
1111 LPD3DENUMPIXELFORMATSCALLBACK Callback,
1112 void *Arg)
1114 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1115 HRESULT hr;
1116 int i;
1118 WINED3DFORMAT FormatList[] = {
1119 /* 32 bit */
1120 WINED3DFMT_A8R8G8B8,
1121 WINED3DFMT_X8R8G8B8,
1122 /* 24 bit */
1123 WINED3DFMT_R8G8B8,
1124 /* 16 Bit */
1125 WINED3DFMT_A1R5G5B5,
1126 WINED3DFMT_A4R4G4B4,
1127 WINED3DFMT_R5G6B5,
1128 WINED3DFMT_X1R5G5B5,
1129 /* 8 Bit */
1130 WINED3DFMT_R3G3B2,
1131 WINED3DFMT_P8,
1132 /* FOURCC codes */
1133 WINED3DFMT_DXT1,
1134 WINED3DFMT_DXT3,
1135 WINED3DFMT_DXT5,
1138 WINED3DFORMAT BumpFormatList[] = {
1139 WINED3DFMT_V8U8,
1140 WINED3DFMT_L6V5U5,
1141 WINED3DFMT_X8L8V8U8,
1142 WINED3DFMT_Q8W8V8U8,
1143 WINED3DFMT_V16U16,
1144 WINED3DFMT_W11V11U10,
1145 WINED3DFMT_A2W10V10U10
1148 TRACE("(%p)->(%p,%p): Relay\n", This, Callback, Arg);
1150 if(!Callback)
1151 return DDERR_INVALIDPARAMS;
1153 EnterCriticalSection(&ddraw_cs);
1154 for(i = 0; i < sizeof(FormatList) / sizeof(WINED3DFORMAT); i++)
1156 hr = IWineD3D_CheckDeviceFormat(This->ddraw->wineD3D,
1157 0 /* Adapter */,
1158 0 /* DeviceType */,
1159 0 /* AdapterFormat */,
1160 0 /* Usage */,
1161 0 /* ResourceType */,
1162 FormatList[i]);
1163 if(hr == D3D_OK)
1165 DDPIXELFORMAT pformat;
1167 memset(&pformat, 0, sizeof(pformat));
1168 pformat.dwSize = sizeof(pformat);
1169 PixelFormat_WineD3DtoDD(&pformat, FormatList[i]);
1171 TRACE("Enumerating WineD3DFormat %d\n", FormatList[i]);
1172 hr = Callback(&pformat, Arg);
1173 if(hr != DDENUMRET_OK)
1175 TRACE("Format enumeration cancelled by application\n");
1176 LeaveCriticalSection(&ddraw_cs);
1177 return D3D_OK;
1182 for(i = 0; i < sizeof(BumpFormatList) / sizeof(WINED3DFORMAT); i++)
1184 hr = IWineD3D_CheckDeviceFormat(This->ddraw->wineD3D,
1185 0 /* Adapter */,
1186 0 /* DeviceType */,
1187 0 /* AdapterFormat */,
1188 WINED3DUSAGE_QUERY_LEGACYBUMPMAP,
1189 0 /* ResourceType */,
1190 BumpFormatList[i]);
1191 if(hr == D3D_OK)
1193 DDPIXELFORMAT pformat;
1195 memset(&pformat, 0, sizeof(pformat));
1196 pformat.dwSize = sizeof(pformat);
1197 PixelFormat_WineD3DtoDD(&pformat, BumpFormatList[i]);
1199 TRACE("Enumerating WineD3DFormat %d\n", BumpFormatList[i]);
1200 hr = Callback(&pformat, Arg);
1201 if(hr != DDENUMRET_OK)
1203 TRACE("Format enumeration cancelled by application\n");
1204 LeaveCriticalSection(&ddraw_cs);
1205 return D3D_OK;
1209 TRACE("End of enumeration\n");
1210 LeaveCriticalSection(&ddraw_cs);
1211 return D3D_OK;
1214 static HRESULT WINAPI
1215 Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats(IDirect3DDevice3 *iface,
1216 LPD3DENUMPIXELFORMATSCALLBACK Callback,
1217 void *Arg)
1219 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1220 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice7 interface.\n", This, Callback, Arg);
1221 return IDirect3DDevice7_EnumTextureFormats(ICOM_INTERFACE(This, IDirect3DDevice7),
1222 Callback,
1223 Arg);
1226 /*****************************************************************************
1227 * IDirect3DDevice2::EnumTextureformats
1229 * EnumTextureFormats for Version 1 and 2, see
1230 * IDirect3DDevice7::EnumTexureFormats for a more detailed description.
1232 * This version has a different callback and does not enumerate FourCC
1233 * formats
1235 *****************************************************************************/
1236 static HRESULT WINAPI
1237 IDirect3DDeviceImpl_2_EnumTextureFormats(IDirect3DDevice2 *iface,
1238 LPD3DENUMTEXTUREFORMATSCALLBACK Callback,
1239 void *Arg)
1241 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1242 HRESULT hr;
1243 int i;
1245 WINED3DFORMAT FormatList[] = {
1246 /* 32 bit */
1247 WINED3DFMT_A8R8G8B8,
1248 WINED3DFMT_X8R8G8B8,
1249 /* 24 bit */
1250 WINED3DFMT_R8G8B8,
1251 /* 16 Bit */
1252 WINED3DFMT_A1R5G5B5,
1253 WINED3DFMT_A4R4G4B4,
1254 WINED3DFMT_R5G6B5,
1255 WINED3DFMT_X1R5G5B5,
1256 /* 8 Bit */
1257 WINED3DFMT_R3G3B2,
1258 WINED3DFMT_P8,
1259 /* FOURCC codes - Not in this version*/
1262 TRACE("(%p)->(%p,%p): Relay\n", This, Callback, Arg);
1264 if(!Callback)
1265 return DDERR_INVALIDPARAMS;
1267 EnterCriticalSection(&ddraw_cs);
1268 for(i = 0; i < sizeof(FormatList) / sizeof(WINED3DFORMAT); i++)
1270 hr = IWineD3D_CheckDeviceFormat(This->ddraw->wineD3D,
1271 0 /* Adapter */,
1272 0 /* DeviceType */,
1273 0 /* AdapterFormat */,
1274 0 /* Usage */,
1275 0 /* ResourceType */,
1276 FormatList[i]);
1277 if(hr == D3D_OK)
1279 DDSURFACEDESC sdesc;
1281 memset(&sdesc, 0, sizeof(sdesc));
1282 sdesc.dwSize = sizeof(sdesc);
1283 sdesc.dwFlags = DDSD_PIXELFORMAT | DDSD_CAPS;
1284 sdesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1285 sdesc.ddpfPixelFormat.dwSize = sizeof(sdesc.ddpfPixelFormat);
1286 PixelFormat_WineD3DtoDD(&sdesc.ddpfPixelFormat, FormatList[i]);
1288 TRACE("Enumerating WineD3DFormat %d\n", FormatList[i]);
1289 hr = Callback(&sdesc, Arg);
1290 if(hr != DDENUMRET_OK)
1292 TRACE("Format enumeration cancelled by application\n");
1293 LeaveCriticalSection(&ddraw_cs);
1294 return D3D_OK;
1298 TRACE("End of enumeration\n");
1299 LeaveCriticalSection(&ddraw_cs);
1300 return D3D_OK;
1303 static HRESULT WINAPI
1304 Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats(IDirect3DDevice *iface,
1305 LPD3DENUMTEXTUREFORMATSCALLBACK Callback,
1306 void *Arg)
1308 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1309 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice2 interface.\n", This, Callback, Arg);
1310 return IDirect3DDevice2_EnumTextureFormats(ICOM_INTERFACE(This, IDirect3DDevice2),
1311 Callback,
1312 Arg);
1315 /*****************************************************************************
1316 * IDirect3DDevice::CreateMatrix
1318 * Creates a matrix handle. A handle is created and memory for a D3DMATRIX is
1319 * allocated for the handle.
1321 * Version 1 only
1323 * Params
1324 * D3DMatHandle: Address to return the handle at
1326 * Returns:
1327 * D3D_OK on success
1328 * DDERR_INVALIDPARAMS if D3DMatHandle = NULL
1330 *****************************************************************************/
1331 static HRESULT WINAPI
1332 IDirect3DDeviceImpl_1_CreateMatrix(IDirect3DDevice *iface, D3DMATRIXHANDLE *D3DMatHandle)
1334 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1335 D3DMATRIX *Matrix;
1336 TRACE("(%p)->(%p)\n", This, D3DMatHandle);
1338 if(!D3DMatHandle)
1339 return DDERR_INVALIDPARAMS;
1341 Matrix = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(D3DMATRIX));
1342 if(!Matrix)
1344 ERR("Out of memory when allocating a D3DMATRIX\n");
1345 return DDERR_OUTOFMEMORY;
1348 EnterCriticalSection(&ddraw_cs);
1349 *D3DMatHandle = IDirect3DDeviceImpl_CreateHandle(This);
1350 if(!(*D3DMatHandle))
1352 ERR("Failed to create a matrix handle\n");
1353 HeapFree(GetProcessHeap(), 0, Matrix);
1354 LeaveCriticalSection(&ddraw_cs);
1355 return DDERR_OUTOFMEMORY;
1357 This->Handles[*D3DMatHandle - 1].ptr = Matrix;
1358 This->Handles[*D3DMatHandle - 1].type = DDrawHandle_Matrix;
1359 TRACE(" returning matrix handle %d\n", *D3DMatHandle);
1361 LeaveCriticalSection(&ddraw_cs);
1362 return D3D_OK;
1365 /*****************************************************************************
1366 * IDirect3DDevice::SetMatrix
1368 * Sets a matrix for a matrix handle. The matrix is copied into the memory
1369 * allocated for the handle
1371 * Version 1 only
1373 * Params:
1374 * D3DMatHandle: Handle to set the matrix to
1375 * D3DMatrix: Matrix to set
1377 * Returns:
1378 * D3D_OK on success
1379 * DDERR_INVALIDPARAMS if the handle of the matrix is invalid or the matrix
1380 * to set is NULL
1382 *****************************************************************************/
1383 static HRESULT WINAPI
1384 IDirect3DDeviceImpl_1_SetMatrix(IDirect3DDevice *iface,
1385 D3DMATRIXHANDLE D3DMatHandle,
1386 D3DMATRIX *D3DMatrix)
1388 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1389 TRACE("(%p)->(%08x,%p)\n", This, D3DMatHandle, D3DMatrix);
1391 if( (!D3DMatHandle) || (!D3DMatrix) )
1392 return DDERR_INVALIDPARAMS;
1394 EnterCriticalSection(&ddraw_cs);
1395 if(D3DMatHandle > This->numHandles)
1397 ERR("Handle %d out of range\n", D3DMatHandle);
1398 LeaveCriticalSection(&ddraw_cs);
1399 return DDERR_INVALIDPARAMS;
1401 else if(This->Handles[D3DMatHandle - 1].type != DDrawHandle_Matrix)
1403 ERR("Handle %d is not a matrix handle\n", D3DMatHandle);
1404 LeaveCriticalSection(&ddraw_cs);
1405 return DDERR_INVALIDPARAMS;
1408 if (TRACE_ON(d3d7))
1409 dump_D3DMATRIX(D3DMatrix);
1411 *((D3DMATRIX *) This->Handles[D3DMatHandle - 1].ptr) = *D3DMatrix;
1413 if(This->world == D3DMatHandle)
1415 IWineD3DDevice_SetTransform(This->wineD3DDevice,
1416 WINED3DTS_WORLDMATRIX(0),
1417 (WINED3DMATRIX *) D3DMatrix);
1419 if(This->view == D3DMatHandle)
1421 IWineD3DDevice_SetTransform(This->wineD3DDevice,
1422 WINED3DTS_VIEW,
1423 (WINED3DMATRIX *) D3DMatrix);
1425 if(This->proj == D3DMatHandle)
1427 IWineD3DDevice_SetTransform(This->wineD3DDevice,
1428 WINED3DTS_PROJECTION,
1429 (WINED3DMATRIX *) D3DMatrix);
1432 LeaveCriticalSection(&ddraw_cs);
1433 return D3D_OK;
1436 /*****************************************************************************
1437 * IDirect3DDevice::SetMatrix
1439 * Returns the content of a D3DMATRIX handle
1441 * Version 1 only
1443 * Params:
1444 * D3DMatHandle: Matrix handle to read the content from
1445 * D3DMatrix: Address to store the content at
1447 * Returns:
1448 * D3D_OK on success
1449 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid or D3DMatrix is NULL
1451 *****************************************************************************/
1452 static HRESULT WINAPI
1453 IDirect3DDeviceImpl_1_GetMatrix(IDirect3DDevice *iface,
1454 D3DMATRIXHANDLE D3DMatHandle,
1455 D3DMATRIX *D3DMatrix)
1457 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1458 TRACE("(%p)->(%08x,%p)\n", This, D3DMatHandle, D3DMatrix);
1460 if(!D3DMatrix)
1461 return DDERR_INVALIDPARAMS;
1462 if(!D3DMatHandle)
1463 return DDERR_INVALIDPARAMS;
1465 EnterCriticalSection(&ddraw_cs);
1466 if(D3DMatHandle > This->numHandles)
1468 ERR("Handle %d out of range\n", D3DMatHandle);
1469 LeaveCriticalSection(&ddraw_cs);
1470 return DDERR_INVALIDPARAMS;
1472 else if(This->Handles[D3DMatHandle - 1].type != DDrawHandle_Matrix)
1474 ERR("Handle %d is not a matrix handle\n", D3DMatHandle);
1475 LeaveCriticalSection(&ddraw_cs);
1476 return DDERR_INVALIDPARAMS;
1479 /* The handle is simply a pointer to a D3DMATRIX structure */
1480 *D3DMatrix = *((D3DMATRIX *) This->Handles[D3DMatHandle - 1].ptr);
1482 LeaveCriticalSection(&ddraw_cs);
1483 return D3D_OK;
1486 /*****************************************************************************
1487 * IDirect3DDevice::DeleteMatrix
1489 * Destroys a Matrix handle. Frees the memory and unsets the handle data
1491 * Version 1 only
1493 * Params:
1494 * D3DMatHandle: Handle to destroy
1496 * Returns:
1497 * D3D_OK on success
1498 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid
1500 *****************************************************************************/
1501 static HRESULT WINAPI
1502 IDirect3DDeviceImpl_1_DeleteMatrix(IDirect3DDevice *iface,
1503 D3DMATRIXHANDLE D3DMatHandle)
1505 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1506 TRACE("(%p)->(%08x)\n", This, D3DMatHandle);
1508 if(!D3DMatHandle)
1509 return DDERR_INVALIDPARAMS;
1511 EnterCriticalSection(&ddraw_cs);
1512 if(D3DMatHandle > This->numHandles)
1514 ERR("Handle %d out of range\n", D3DMatHandle);
1515 LeaveCriticalSection(&ddraw_cs);
1516 return DDERR_INVALIDPARAMS;
1518 else if(This->Handles[D3DMatHandle - 1].type != DDrawHandle_Matrix)
1520 ERR("Handle %d is not a matrix handle\n", D3DMatHandle);
1521 LeaveCriticalSection(&ddraw_cs);
1522 return DDERR_INVALIDPARAMS;
1525 HeapFree(GetProcessHeap(), 0, This->Handles[D3DMatHandle - 1].ptr);
1526 This->Handles[D3DMatHandle - 1].ptr = NULL;
1527 This->Handles[D3DMatHandle - 1].type = DDrawHandle_Unknown;
1529 LeaveCriticalSection(&ddraw_cs);
1530 return D3D_OK;
1533 /*****************************************************************************
1534 * IDirect3DDevice7::BeginScene
1536 * This method must be called before any rendering is performed.
1537 * IDirect3DDevice::EndScene has to be called after the scene is complete
1539 * Version 1, 2, 3 and 7
1541 * Returns:
1542 * D3D_OK on success, for details see IWineD3DDevice::BeginScene
1543 * D3DERR_SCENE_IN_SCENE if WineD3D returns an error(Only in case of an already
1544 * started scene).
1546 *****************************************************************************/
1547 static HRESULT WINAPI
1548 IDirect3DDeviceImpl_7_BeginScene(IDirect3DDevice7 *iface)
1550 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1551 HRESULT hr;
1552 TRACE("(%p): Relay\n", This);
1554 EnterCriticalSection(&ddraw_cs);
1555 hr = IWineD3DDevice_BeginScene(This->wineD3DDevice);
1556 LeaveCriticalSection(&ddraw_cs);
1557 if(hr == WINED3D_OK) return D3D_OK;
1558 else return D3DERR_SCENE_IN_SCENE; /* TODO: Other possible causes of failure */
1561 static HRESULT WINAPI
1562 Thunk_IDirect3DDeviceImpl_3_BeginScene(IDirect3DDevice3 *iface)
1564 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1565 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1566 return IDirect3DDevice7_BeginScene(ICOM_INTERFACE(This, IDirect3DDevice7));
1569 static HRESULT WINAPI
1570 Thunk_IDirect3DDeviceImpl_2_BeginScene(IDirect3DDevice2 *iface)
1572 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1573 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1574 return IDirect3DDevice7_BeginScene(ICOM_INTERFACE(This, IDirect3DDevice7));
1577 static HRESULT WINAPI
1578 Thunk_IDirect3DDeviceImpl_1_BeginScene(IDirect3DDevice *iface)
1580 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1581 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1582 return IDirect3DDevice7_BeginScene(ICOM_INTERFACE(This, IDirect3DDevice7));
1585 /*****************************************************************************
1586 * IDirect3DDevice7::EndScene
1588 * Ends a scene that has been begun with IDirect3DDevice7::BeginScene.
1589 * This method must be called after rendering is finished.
1591 * Version 1, 2, 3 and 7
1593 * Returns:
1594 * D3D_OK on success, for details see IWineD3DDevice::EndScene
1595 * D3DERR_SCENE_NOT_IN_SCENE is returned if WineD3D returns an error. It does
1596 * that only if the scene was already ended.
1598 *****************************************************************************/
1599 static HRESULT WINAPI
1600 IDirect3DDeviceImpl_7_EndScene(IDirect3DDevice7 *iface)
1602 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1603 HRESULT hr;
1604 TRACE("(%p): Relay\n", This);
1606 EnterCriticalSection(&ddraw_cs);
1607 hr = IWineD3DDevice_EndScene(This->wineD3DDevice);
1608 LeaveCriticalSection(&ddraw_cs);
1609 if(hr == WINED3D_OK) return D3D_OK;
1610 else return D3DERR_SCENE_NOT_IN_SCENE;
1613 static HRESULT WINAPI
1614 Thunk_IDirect3DDeviceImpl_3_EndScene(IDirect3DDevice3 *iface)
1616 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1617 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1618 return IDirect3DDevice7_EndScene(ICOM_INTERFACE(This, IDirect3DDevice7));
1621 static HRESULT WINAPI
1622 Thunk_IDirect3DDeviceImpl_2_EndScene(IDirect3DDevice2 *iface)
1624 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1625 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1626 return IDirect3DDevice7_EndScene(ICOM_INTERFACE(This, IDirect3DDevice7));
1629 static HRESULT WINAPI
1630 Thunk_IDirect3DDeviceImpl_1_EndScene(IDirect3DDevice *iface)
1632 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1633 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1634 return IDirect3DDevice7_EndScene(ICOM_INTERFACE(This, IDirect3DDevice7));
1637 /*****************************************************************************
1638 * IDirect3DDevice7::GetDirect3D
1640 * Returns the IDirect3D(= interface to the DirectDraw object) used to create
1641 * this device.
1643 * Params:
1644 * Direct3D7: Address to store the interface pointer at
1646 * Returns:
1647 * D3D_OK on success
1648 * DDERR_INVALIDPARAMS if Direct3D7 == NULL
1650 *****************************************************************************/
1651 static HRESULT WINAPI
1652 IDirect3DDeviceImpl_7_GetDirect3D(IDirect3DDevice7 *iface,
1653 IDirect3D7 **Direct3D7)
1655 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1656 TRACE("(%p)->(%p)\n", This, Direct3D7);
1658 if(!Direct3D7)
1659 return DDERR_INVALIDPARAMS;
1661 *Direct3D7 = ICOM_INTERFACE(This->ddraw, IDirect3D7);
1662 IDirect3D7_AddRef(*Direct3D7);
1664 TRACE(" returning interface %p\n", *Direct3D7);
1665 return D3D_OK;
1668 static HRESULT WINAPI
1669 Thunk_IDirect3DDeviceImpl_3_GetDirect3D(IDirect3DDevice3 *iface,
1670 IDirect3D3 **Direct3D3)
1672 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1673 HRESULT ret;
1674 IDirect3D7 *ret_ptr;
1676 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Direct3D3);
1677 ret = IDirect3DDevice7_GetDirect3D(ICOM_INTERFACE(This, IDirect3DDevice7),
1678 &ret_ptr);
1679 if(ret != D3D_OK)
1680 return ret;
1681 *Direct3D3 = COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D7, IDirect3D3, ret_ptr);
1682 TRACE(" returning interface %p\n", *Direct3D3);
1683 return D3D_OK;
1686 static HRESULT WINAPI
1687 Thunk_IDirect3DDeviceImpl_2_GetDirect3D(IDirect3DDevice2 *iface,
1688 IDirect3D2 **Direct3D2)
1690 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1691 HRESULT ret;
1692 IDirect3D7 *ret_ptr;
1694 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Direct3D2);
1695 ret = IDirect3DDevice7_GetDirect3D(ICOM_INTERFACE(This, IDirect3DDevice7),
1696 &ret_ptr);
1697 if(ret != D3D_OK)
1698 return ret;
1699 *Direct3D2 = COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D7, IDirect3D2, ret_ptr);
1700 TRACE(" returning interface %p\n", *Direct3D2);
1701 return D3D_OK;
1704 static HRESULT WINAPI
1705 Thunk_IDirect3DDeviceImpl_1_GetDirect3D(IDirect3DDevice *iface,
1706 IDirect3D **Direct3D)
1708 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1709 HRESULT ret;
1710 IDirect3D7 *ret_ptr;
1712 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Direct3D);
1713 ret = IDirect3DDevice7_GetDirect3D(ICOM_INTERFACE(This, IDirect3DDevice7),
1714 &ret_ptr);
1715 if(ret != D3D_OK)
1716 return ret;
1717 *Direct3D = COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D7, IDirect3D, ret_ptr);
1718 TRACE(" returning interface %p\n", *Direct3D);
1719 return D3D_OK;
1722 /*****************************************************************************
1723 * IDirect3DDevice3::SetCurrentViewport
1725 * Sets a Direct3DViewport as the current viewport.
1726 * For the thunks note that all viewport interface versions are equal
1728 * Params:
1729 * Direct3DViewport3: The viewport to set
1731 * Version 2 and 3
1733 * Returns:
1734 * D3D_OK on success
1735 * (Is a NULL viewport valid?)
1737 *****************************************************************************/
1738 static HRESULT WINAPI
1739 IDirect3DDeviceImpl_3_SetCurrentViewport(IDirect3DDevice3 *iface,
1740 IDirect3DViewport3 *Direct3DViewport3)
1742 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1743 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport3);
1744 TRACE("(%p)->(%p)\n", This, Direct3DViewport3);
1746 EnterCriticalSection(&ddraw_cs);
1747 /* Do nothing if the specified viewport is the same as the current one */
1748 if (This->current_viewport == vp )
1750 LeaveCriticalSection(&ddraw_cs);
1751 return D3D_OK;
1754 /* Should check if the viewport was added or not */
1756 /* Release previous viewport and AddRef the new one */
1757 if (This->current_viewport)
1759 TRACE("ViewportImpl is at %p, interface is at %p\n", This->current_viewport, ICOM_INTERFACE(This->current_viewport, IDirect3DViewport3));
1760 IDirect3DViewport3_Release( ICOM_INTERFACE(This->current_viewport, IDirect3DViewport3) );
1762 IDirect3DViewport3_AddRef(Direct3DViewport3);
1764 /* Set this viewport as the current viewport */
1765 This->current_viewport = vp;
1767 /* Activate this viewport */
1768 This->current_viewport->active_device = This;
1769 This->current_viewport->activate(This->current_viewport, FALSE);
1771 LeaveCriticalSection(&ddraw_cs);
1772 return D3D_OK;
1775 static HRESULT WINAPI
1776 Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport(IDirect3DDevice2 *iface,
1777 IDirect3DViewport2 *Direct3DViewport2)
1779 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1780 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport2);
1781 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
1782 return IDirect3DDevice3_SetCurrentViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
1783 ICOM_INTERFACE(vp, IDirect3DViewport3));
1786 /*****************************************************************************
1787 * IDirect3DDevice3::GetCurrentViewport
1789 * Returns the currently active viewport.
1791 * Version 2 and 3
1793 * Params:
1794 * Direct3DViewport3: Address to return the interface pointer at
1796 * Returns:
1797 * D3D_OK on success
1798 * DDERR_INVALIDPARAMS if Direct3DViewport == NULL
1800 *****************************************************************************/
1801 static HRESULT WINAPI
1802 IDirect3DDeviceImpl_3_GetCurrentViewport(IDirect3DDevice3 *iface,
1803 IDirect3DViewport3 **Direct3DViewport3)
1805 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1806 TRACE("(%p)->(%p)\n", This, Direct3DViewport3);
1808 if(!Direct3DViewport3)
1809 return DDERR_INVALIDPARAMS;
1811 EnterCriticalSection(&ddraw_cs);
1812 *Direct3DViewport3 = ICOM_INTERFACE(This->current_viewport, IDirect3DViewport3);
1814 /* AddRef the returned viewport */
1815 if(*Direct3DViewport3) IDirect3DViewport3_AddRef(*Direct3DViewport3);
1817 TRACE(" returning interface %p\n", *Direct3DViewport3);
1819 LeaveCriticalSection(&ddraw_cs);
1820 return D3D_OK;
1823 static HRESULT WINAPI
1824 Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport(IDirect3DDevice2 *iface,
1825 IDirect3DViewport2 **Direct3DViewport2)
1827 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1828 HRESULT hr;
1829 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, Direct3DViewport2);
1830 hr = IDirect3DDevice3_GetCurrentViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
1831 (IDirect3DViewport3 **) Direct3DViewport2);
1832 if(hr != D3D_OK) return hr;
1833 *Direct3DViewport2 = (IDirect3DViewport2 *) COM_INTERFACE_CAST(IDirect3DViewportImpl, IDirect3DViewport3, IDirect3DViewport3, *Direct3DViewport2);
1834 return D3D_OK;
1837 /*****************************************************************************
1838 * IDirect3DDevice7::SetRenderTarget
1840 * Sets the render target for the Direct3DDevice.
1841 * For the thunks note that IDirectDrawSurface7 == IDirectDrawSurface4 and
1842 * IDirectDrawSurface3 == IDirectDrawSurface
1844 * Version 2, 3 and 7
1846 * Params:
1847 * NewTarget: Pointer to an IDirectDrawSurface7 interface to set as the new
1848 * render target
1849 * Flags: Some flags
1851 * Returns:
1852 * D3D_OK on success, for details see IWineD3DDevice::SetRenderTarget
1854 *****************************************************************************/
1855 static HRESULT WINAPI
1856 IDirect3DDeviceImpl_7_SetRenderTarget(IDirect3DDevice7 *iface,
1857 IDirectDrawSurface7 *NewTarget,
1858 DWORD Flags)
1860 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1861 IDirectDrawSurfaceImpl *Target = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, NewTarget);
1862 HRESULT hr;
1863 TRACE("(%p)->(%p,%08x): Relay\n", This, NewTarget, Flags);
1865 EnterCriticalSection(&ddraw_cs);
1866 /* Flags: Not used */
1868 if(This->target == Target)
1870 TRACE("No-op SetRenderTarget operation, not doing anything\n");
1871 LeaveCriticalSection(&ddraw_cs);
1872 return D3D_OK;
1875 hr = IWineD3DDevice_SetRenderTarget(This->wineD3DDevice,
1877 Target ? Target->WineD3DSurface : NULL);
1878 if(hr != D3D_OK)
1880 LeaveCriticalSection(&ddraw_cs);
1881 return hr;
1883 IDirectDrawSurface7_AddRef(NewTarget);
1884 IDirectDrawSurface7_Release(ICOM_INTERFACE(This->target, IDirectDrawSurface7));
1885 This->target = Target;
1886 IDirect3DDeviceImpl_UpdateDepthStencil(This);
1887 LeaveCriticalSection(&ddraw_cs);
1888 return D3D_OK;
1891 static HRESULT WINAPI
1892 Thunk_IDirect3DDeviceImpl_3_SetRenderTarget(IDirect3DDevice3 *iface,
1893 IDirectDrawSurface4 *NewRenderTarget,
1894 DWORD Flags)
1896 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1897 IDirectDrawSurfaceImpl *Target = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, NewRenderTarget);
1898 TRACE_(ddraw_thunk)("(%p)->(%p,%08x) thunking to IDirect3DDevice7 interface.\n", This, Target, Flags);
1899 return IDirect3DDevice7_SetRenderTarget(ICOM_INTERFACE(This, IDirect3DDevice7),
1900 ICOM_INTERFACE(Target, IDirectDrawSurface7),
1901 Flags);
1904 static HRESULT WINAPI
1905 Thunk_IDirect3DDeviceImpl_2_SetRenderTarget(IDirect3DDevice2 *iface,
1906 IDirectDrawSurface *NewRenderTarget,
1907 DWORD Flags)
1909 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1910 IDirectDrawSurfaceImpl *Target = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface3, NewRenderTarget);
1911 TRACE_(ddraw_thunk)("(%p)->(%p,%08x) thunking to IDirect3DDevice7 interface.\n", This, Target, Flags);
1912 return IDirect3DDevice7_SetRenderTarget(ICOM_INTERFACE(This, IDirect3DDevice7),
1913 ICOM_INTERFACE(Target, IDirectDrawSurface7),
1914 Flags);
1917 /*****************************************************************************
1918 * IDirect3DDevice7::GetRenderTarget
1920 * Returns the current render target.
1921 * This is handled locally, because the WineD3D render target's parent
1922 * is an IParent
1924 * Version 2, 3 and 7
1926 * Params:
1927 * RenderTarget: Address to store the surface interface pointer
1929 * Returns:
1930 * D3D_OK on success
1931 * DDERR_INVALIDPARAMS if RenderTarget == NULL
1933 *****************************************************************************/
1934 static HRESULT WINAPI
1935 IDirect3DDeviceImpl_7_GetRenderTarget(IDirect3DDevice7 *iface,
1936 IDirectDrawSurface7 **RenderTarget)
1938 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1939 TRACE("(%p)->(%p): Relay\n", This, RenderTarget);
1941 if(!RenderTarget)
1942 return DDERR_INVALIDPARAMS;
1944 EnterCriticalSection(&ddraw_cs);
1945 *RenderTarget = ICOM_INTERFACE(This->target, IDirectDrawSurface7);
1946 IDirectDrawSurface7_AddRef(*RenderTarget);
1948 LeaveCriticalSection(&ddraw_cs);
1949 return D3D_OK;
1952 static HRESULT WINAPI
1953 Thunk_IDirect3DDeviceImpl_3_GetRenderTarget(IDirect3DDevice3 *iface,
1954 IDirectDrawSurface4 **RenderTarget)
1956 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1957 HRESULT hr;
1958 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, RenderTarget);
1959 hr = IDirect3DDevice7_GetRenderTarget(ICOM_INTERFACE(This, IDirect3DDevice7),
1960 (IDirectDrawSurface7 **) RenderTarget);
1961 if(hr != D3D_OK) return hr;
1962 *RenderTarget = (IDirectDrawSurface4 *) COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7, IDirectDrawSurface7, *RenderTarget);
1963 return D3D_OK;
1966 static HRESULT WINAPI
1967 Thunk_IDirect3DDeviceImpl_2_GetRenderTarget(IDirect3DDevice2 *iface,
1968 IDirectDrawSurface **RenderTarget)
1970 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1971 HRESULT hr;
1972 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, RenderTarget);
1973 hr = IDirect3DDevice7_GetRenderTarget(ICOM_INTERFACE(This, IDirect3DDevice7),
1974 (IDirectDrawSurface7 **) RenderTarget);
1975 if(hr != D3D_OK) return hr;
1976 *RenderTarget = (IDirectDrawSurface *) COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7, IDirectDrawSurface3, *RenderTarget);
1977 return D3D_OK;
1980 /*****************************************************************************
1981 * IDirect3DDevice3::Begin
1983 * Begins a description block of vertices. This is similar to glBegin()
1984 * and glEnd(). After a call to IDirect3DDevice3::End, the vertices
1985 * described with IDirect3DDevice::Vertex are drawn.
1987 * Version 2 and 3
1989 * Params:
1990 * PrimitiveType: The type of primitives to draw
1991 * VertexTypeDesc: A flexible vertex format description of the vertices
1992 * Flags: Some flags..
1994 * Returns:
1995 * D3D_OK on success
1997 *****************************************************************************/
1998 static HRESULT WINAPI
1999 IDirect3DDeviceImpl_3_Begin(IDirect3DDevice3 *iface,
2000 D3DPRIMITIVETYPE PrimitiveType,
2001 DWORD VertexTypeDesc,
2002 DWORD Flags)
2004 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2005 TRACE("(%p)->(%d,%d,%08x)\n", This, PrimitiveType, VertexTypeDesc, Flags);
2007 EnterCriticalSection(&ddraw_cs);
2008 This->primitive_type = PrimitiveType;
2009 This->vertex_type = VertexTypeDesc;
2010 This->render_flags = Flags;
2011 This->vertex_size = get_flexible_vertex_size(This->vertex_type);
2012 This->nb_vertices = 0;
2013 LeaveCriticalSection(&ddraw_cs);
2015 return D3D_OK;
2018 static HRESULT WINAPI
2019 Thunk_IDirect3DDeviceImpl_2_Begin(IDirect3DDevice2 *iface,
2020 D3DPRIMITIVETYPE d3dpt,
2021 D3DVERTEXTYPE dwVertexTypeDesc,
2022 DWORD dwFlags)
2024 DWORD FVF;
2025 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2026 TRACE_(ddraw_thunk)("(%p/%p)->(%08x,%08x,%08x): Thunking to IDirect3DDevice3\n", This, iface, d3dpt, dwVertexTypeDesc, dwFlags);
2028 switch(dwVertexTypeDesc)
2030 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
2031 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
2032 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
2033 default:
2034 ERR("Unexpected vertex type %d\n", dwVertexTypeDesc);
2035 return DDERR_INVALIDPARAMS; /* Should never happen */
2038 return IDirect3DDevice3_Begin(ICOM_INTERFACE(This, IDirect3DDevice3),
2039 d3dpt,
2040 FVF,
2041 dwFlags);
2044 /*****************************************************************************
2045 * IDirect3DDevice3::BeginIndexed
2047 * Draws primitives based on vertices in a vertex array which are specified
2048 * by indices.
2050 * Version 2 and 3
2052 * Params:
2053 * PrimitiveType: Primitive type to draw
2054 * VertexType: A FVF description of the vertex format
2055 * Vertices: pointer to an array containing the vertices
2056 * NumVertices: The number of vertices in the vertex array
2057 * Flags: Some flags ...
2059 * Returns:
2060 * D3D_OK, because it's a stub
2062 *****************************************************************************/
2063 static HRESULT WINAPI
2064 IDirect3DDeviceImpl_3_BeginIndexed(IDirect3DDevice3 *iface,
2065 D3DPRIMITIVETYPE PrimitiveType,
2066 DWORD VertexType,
2067 void *Vertices,
2068 DWORD NumVertices,
2069 DWORD Flags)
2071 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2072 FIXME("(%p)->(%08x,%08x,%p,%08x,%08x): stub!\n", This, PrimitiveType, VertexType, Vertices, NumVertices, Flags);
2073 return D3D_OK;
2077 static HRESULT WINAPI
2078 Thunk_IDirect3DDeviceImpl_2_BeginIndexed(IDirect3DDevice2 *iface,
2079 D3DPRIMITIVETYPE d3dptPrimitiveType,
2080 D3DVERTEXTYPE d3dvtVertexType,
2081 void *lpvVertices,
2082 DWORD dwNumVertices,
2083 DWORD dwFlags)
2085 DWORD FVF;
2086 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2087 TRACE_(ddraw_thunk)("(%p/%p)->(%08x,%08x,%p,%08x,%08x): Thunking to IDirect3DDevice3\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwNumVertices, dwFlags);
2089 switch(d3dvtVertexType)
2091 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
2092 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
2093 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
2094 default:
2095 ERR("Unexpected vertex type %d\n", d3dvtVertexType);
2096 return DDERR_INVALIDPARAMS; /* Should never happen */
2099 return IDirect3DDevice3_BeginIndexed(ICOM_INTERFACE(This,IDirect3DDevice3),
2100 d3dptPrimitiveType,
2101 FVF,
2102 lpvVertices,
2103 dwNumVertices,
2104 dwFlags);
2107 /*****************************************************************************
2108 * IDirect3DDevice3::Vertex
2110 * Draws a vertex as described by IDirect3DDevice3::Begin. It places all
2111 * drawn vertices in a vertex buffer. If the buffer is too small, its
2112 * size is increased.
2114 * Version 2 and 3
2116 * Params:
2117 * Vertex: Pointer to the vertex
2119 * Returns:
2120 * D3D_OK, on success
2121 * DDERR_INVALIDPARAMS if Vertex is NULL
2123 *****************************************************************************/
2124 static HRESULT WINAPI
2125 IDirect3DDeviceImpl_3_Vertex(IDirect3DDevice3 *iface,
2126 void *Vertex)
2128 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2129 TRACE("(%p)->(%p)\n", This, Vertex);
2131 if(!Vertex)
2132 return DDERR_INVALIDPARAMS;
2134 EnterCriticalSection(&ddraw_cs);
2135 if ((This->nb_vertices+1)*This->vertex_size > This->buffer_size)
2137 BYTE *old_buffer;
2138 This->buffer_size = This->buffer_size ? This->buffer_size * 2 : This->vertex_size * 3;
2139 old_buffer = This->vertex_buffer;
2140 This->vertex_buffer = HeapAlloc(GetProcessHeap(), 0, This->buffer_size);
2141 if (old_buffer)
2143 CopyMemory(This->vertex_buffer, old_buffer, This->nb_vertices * This->vertex_size);
2144 HeapFree(GetProcessHeap(), 0, old_buffer);
2148 CopyMemory(This->vertex_buffer + This->nb_vertices++ * This->vertex_size, Vertex, This->vertex_size);
2150 LeaveCriticalSection(&ddraw_cs);
2151 return D3D_OK;
2154 static HRESULT WINAPI
2155 Thunk_IDirect3DDeviceImpl_2_Vertex(IDirect3DDevice2 *iface,
2156 void *lpVertexType)
2158 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2159 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, lpVertexType);
2160 return IDirect3DDevice3_Vertex(ICOM_INTERFACE(This, IDirect3DDevice3),
2161 lpVertexType);
2164 /*****************************************************************************
2165 * IDirect3DDevice3::Index
2167 * Specifies an index to a vertex to be drawn. The vertex array has to
2168 * be specified with BeginIndexed first.
2170 * Parameters:
2171 * VertexIndex: The index of the vertex to draw
2173 * Returns:
2174 * D3D_OK because it's a stub
2176 *****************************************************************************/
2177 static HRESULT WINAPI
2178 IDirect3DDeviceImpl_3_Index(IDirect3DDevice3 *iface,
2179 WORD VertexIndex)
2181 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2182 FIXME("(%p)->(%04x): stub!\n", This, VertexIndex);
2183 return D3D_OK;
2186 static HRESULT WINAPI
2187 Thunk_IDirect3DDeviceImpl_2_Index(IDirect3DDevice2 *iface,
2188 WORD wVertexIndex)
2190 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2191 TRACE_(ddraw_thunk)("(%p)->(%04x) thunking to IDirect3DDevice3 interface.\n", This, wVertexIndex);
2192 return IDirect3DDevice3_Index(ICOM_INTERFACE(This, IDirect3DDevice3),
2193 wVertexIndex);
2196 /*****************************************************************************
2197 * IDirect3DDevice3::End
2199 * Ends a draw begun with IDirect3DDevice3::Begin or
2200 * IDirect3DDevice::BeginIndexed. The vertices specified with
2201 * IDirect3DDevice::Vertex or IDirect3DDevice::Index are drawn using
2202 * the IDirect3DDevice7::DrawPrimitive method. So far only
2203 * non-indexed mode is supported
2205 * Version 2 and 3
2207 * Params:
2208 * Flags: Some flags, as usual. Don't know which are defined
2210 * Returns:
2211 * The return value of IDirect3DDevice7::DrawPrimitive
2213 *****************************************************************************/
2214 static HRESULT WINAPI
2215 IDirect3DDeviceImpl_3_End(IDirect3DDevice3 *iface,
2216 DWORD Flags)
2218 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2219 TRACE("(%p)->(%08x)\n", This, Flags);
2221 return IDirect3DDevice7_DrawPrimitive(ICOM_INTERFACE(This, IDirect3DDevice7),
2222 This->primitive_type, This->vertex_type,
2223 This->vertex_buffer, This->nb_vertices,
2224 This->render_flags);
2227 static HRESULT WINAPI
2228 Thunk_IDirect3DDeviceImpl_2_End(IDirect3DDevice2 *iface,
2229 DWORD dwFlags)
2231 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2232 TRACE_(ddraw_thunk)("(%p)->(%08x) thunking to IDirect3DDevice3 interface.\n", This, dwFlags);
2233 return IDirect3DDevice3_End(ICOM_INTERFACE(This, IDirect3DDevice3),
2234 dwFlags);
2237 /*****************************************************************************
2238 * IDirect3DDevice7::GetRenderState
2240 * Returns the value of a render state. The possible render states are
2241 * defined in include/d3dtypes.h
2243 * Version 2, 3 and 7
2245 * Params:
2246 * RenderStateType: Render state to return the current setting of
2247 * Value: Address to store the value at
2249 * Returns:
2250 * D3D_OK on success, for details see IWineD3DDevice::GetRenderState
2251 * DDERR_INVALIDPARAMS if Value == NULL
2253 *****************************************************************************/
2254 static HRESULT WINAPI
2255 IDirect3DDeviceImpl_7_GetRenderState(IDirect3DDevice7 *iface,
2256 D3DRENDERSTATETYPE RenderStateType,
2257 DWORD *Value)
2259 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
2260 HRESULT hr;
2261 TRACE("(%p)->(%08x,%p): Relay\n", This, RenderStateType, Value);
2263 if(!Value)
2264 return DDERR_INVALIDPARAMS;
2266 EnterCriticalSection(&ddraw_cs);
2267 switch(RenderStateType)
2269 case D3DRENDERSTATE_TEXTUREMAG:
2271 WINED3DTEXTUREFILTERTYPE tex_mag;
2273 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2274 0, WINED3DSAMP_MAGFILTER,
2275 &tex_mag);
2277 switch (tex_mag)
2279 case WINED3DTEXF_POINT:
2280 *Value = D3DFILTER_NEAREST;
2281 break;
2282 case WINED3DTEXF_LINEAR:
2283 *Value = D3DFILTER_LINEAR;
2284 break;
2285 default:
2286 ERR("Unhandled texture mag %d !\n",tex_mag);
2287 *Value = 0;
2289 break;
2292 case D3DRENDERSTATE_TEXTUREMIN:
2294 WINED3DTEXTUREFILTERTYPE tex_min;
2296 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2297 0, WINED3DSAMP_MINFILTER,
2298 &tex_min);
2300 switch (tex_min)
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_min);
2310 *Value = 0;
2312 break;
2315 case D3DRENDERSTATE_TEXTUREADDRESS:
2316 case D3DRENDERSTATE_TEXTUREADDRESSU:
2317 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2318 0, WINED3DSAMP_ADDRESSU,
2319 Value);
2320 break;
2321 case D3DRENDERSTATE_TEXTUREADDRESSV:
2322 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2323 0, WINED3DSAMP_ADDRESSV,
2324 Value);
2325 break;
2327 default:
2328 /* FIXME: Unhandled: D3DRENDERSTATE_STIPPLEPATTERN00 - 31 */
2329 hr = IWineD3DDevice_GetRenderState(This->wineD3DDevice,
2330 RenderStateType,
2331 Value);
2333 LeaveCriticalSection(&ddraw_cs);
2334 return hr;
2337 static HRESULT WINAPI
2338 IDirect3DDeviceImpl_3_GetRenderState(IDirect3DDevice3 *iface,
2339 D3DRENDERSTATETYPE dwRenderStateType,
2340 DWORD *lpdwRenderState)
2342 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2343 HRESULT hr;
2344 TRACE("(%p)->(%08x,%p)\n", This, dwRenderStateType, lpdwRenderState);
2346 /* D3DRENDERSTATE_TEXTUREMAPBLEND is mapped to texture state stages in SetRenderState; reverse
2347 the mapping to get the value. */
2348 switch(dwRenderStateType)
2350 case D3DRENDERSTATE_TEXTUREHANDLE:
2352 /* This state is wrapped to SetTexture in SetRenderState, so
2353 * it has to be wrapped to GetTexture here
2355 IWineD3DBaseTexture *tex = NULL;
2356 *lpdwRenderState = 0;
2358 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice,
2360 &tex);
2362 if(hr == WINED3D_OK && tex)
2364 IDirectDrawSurface7 *parent = NULL;
2365 hr = IWineD3DBaseTexture_GetParent(tex,
2366 (IUnknown **) &parent);
2367 if(parent)
2369 /* The parent of the texture is the IDirectDrawSurface7 interface
2370 * of the ddraw surface
2372 IDirectDrawSurfaceImpl *texImpl = ICOM_OBJECT(IDirectDrawSurfaceImpl,
2373 IDirectDrawSurface7,
2374 parent);
2375 *lpdwRenderState = texImpl->Handle;
2376 IDirectDrawSurface7_Release(parent);
2378 IWineD3DBaseTexture_Release(tex);
2381 return hr;
2384 case D3DRENDERSTATE_TEXTUREMAPBLEND:
2386 DWORD colorop, colorarg1, colorarg2;
2387 DWORD alphaop, alphaarg1, alphaarg2;
2389 EnterCriticalSection(&ddraw_cs);
2391 This->legacyTextureBlending = TRUE;
2393 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, &colorop);
2394 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, &colorarg1);
2395 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, &colorarg2);
2396 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, &alphaop);
2397 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, &alphaarg1);
2398 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, &alphaarg2);
2400 if (colorop == WINED3DTOP_SELECTARG1 && colorarg1 == WINED3DTA_TEXTURE &&
2401 alphaop == WINED3DTOP_SELECTARG1 && alphaarg1 == WINED3DTA_TEXTURE)
2403 *lpdwRenderState = D3DTBLEND_DECAL;
2405 else if (colorop == WINED3DTOP_SELECTARG1 && colorarg1 == WINED3DTA_TEXTURE &&
2406 alphaop == WINED3DTOP_MODULATE && alphaarg1 == WINED3DTA_TEXTURE && alphaarg2 == WINED3DTA_CURRENT)
2408 *lpdwRenderState = D3DTBLEND_DECALALPHA;
2410 else if (colorop == WINED3DTOP_MODULATE && colorarg1 == WINED3DTA_TEXTURE && colorarg2 == WINED3DTA_CURRENT &&
2411 alphaop == WINED3DTOP_MODULATE && alphaarg1 == WINED3DTA_TEXTURE && alphaarg2 == WINED3DTA_CURRENT)
2413 *lpdwRenderState = D3DTBLEND_MODULATEALPHA;
2415 else
2417 HRESULT hr;
2418 BOOL tex_alpha = FALSE;
2419 IWineD3DBaseTexture *tex = NULL;
2420 WINED3DSURFACE_DESC desc;
2421 WINED3DFORMAT fmt;
2422 DDPIXELFORMAT ddfmt;
2424 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice,
2426 &tex);
2428 if(hr == WINED3D_OK && tex)
2430 memset(&desc, 0, sizeof(desc));
2431 desc.Format = &fmt;
2432 hr = IWineD3DTexture_GetLevelDesc((IWineD3DTexture*) tex, 0, &desc);
2433 if (SUCCEEDED(hr))
2435 ddfmt.dwSize = sizeof(ddfmt);
2436 PixelFormat_WineD3DtoDD(&ddfmt, fmt);
2437 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
2440 IWineD3DBaseTexture_Release(tex);
2443 if (!(colorop == WINED3DTOP_MODULATE && colorarg1 == WINED3DTA_TEXTURE && colorarg2 == WINED3DTA_CURRENT &&
2444 alphaop == WINED3DTOP_SELECTARG1 && alphaarg1 == (tex_alpha ? WINED3DTA_TEXTURE : WINED3DTA_CURRENT)))
2446 ERR("Unexpected texture stage state setup, returning D3DTBLEND_MODULATE - likely erroneous\n");
2449 *lpdwRenderState = D3DTBLEND_MODULATE;
2452 LeaveCriticalSection(&ddraw_cs);
2454 return D3D_OK;
2457 default:
2458 return IDirect3DDevice7_GetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
2459 dwRenderStateType,
2460 lpdwRenderState);
2464 static HRESULT WINAPI
2465 Thunk_IDirect3DDeviceImpl_2_GetRenderState(IDirect3DDevice2 *iface,
2466 D3DRENDERSTATETYPE dwRenderStateType,
2467 DWORD *lpdwRenderState)
2469 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2470 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice3 interface.\n", This, dwRenderStateType, lpdwRenderState);
2471 return IDirect3DDevice3_GetRenderState(ICOM_INTERFACE(This, IDirect3DDevice3),
2472 dwRenderStateType,
2473 lpdwRenderState);
2476 /*****************************************************************************
2477 * IDirect3DDevice7::SetRenderState
2479 * Sets a render state. The possible render states are defined in
2480 * include/d3dtypes.h
2482 * Version 2, 3 and 7
2484 * Params:
2485 * RenderStateType: State to set
2486 * Value: Value to assign to that state
2488 * Returns:
2489 * D3D_OK on success,
2490 * for details see IWineD3DDevice::SetRenderState
2492 *****************************************************************************/
2493 static HRESULT WINAPI
2494 IDirect3DDeviceImpl_7_SetRenderState(IDirect3DDevice7 *iface,
2495 D3DRENDERSTATETYPE RenderStateType,
2496 DWORD Value)
2498 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
2499 HRESULT hr;
2500 TRACE("(%p)->(%08x,%d): Relay\n", This, RenderStateType, Value);
2502 EnterCriticalSection(&ddraw_cs);
2503 /* Some render states need special care */
2504 switch(RenderStateType)
2506 case D3DRENDERSTATE_TEXTUREMAG:
2508 WINED3DTEXTUREFILTERTYPE tex_mag = WINED3DTEXF_NONE;
2510 switch ((D3DTEXTUREFILTER) Value)
2512 case D3DFILTER_NEAREST:
2513 case D3DFILTER_LINEARMIPNEAREST:
2514 tex_mag = WINED3DTEXF_POINT;
2515 break;
2516 case D3DFILTER_LINEAR:
2517 case D3DFILTER_LINEARMIPLINEAR:
2518 tex_mag = WINED3DTEXF_LINEAR;
2519 break;
2520 default:
2521 ERR("Unhandled texture mag %d !\n",Value);
2524 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2525 0, WINED3DSAMP_MAGFILTER,
2526 tex_mag);
2527 break;
2530 case D3DRENDERSTATE_TEXTUREMIN:
2532 WINED3DTEXTUREFILTERTYPE tex_min = WINED3DTEXF_NONE;
2533 WINED3DTEXTUREFILTERTYPE tex_mip = WINED3DTEXF_NONE;
2535 switch ((D3DTEXTUREFILTER) Value)
2537 case D3DFILTER_NEAREST:
2538 tex_min = WINED3DTEXF_POINT;
2539 break;
2540 case D3DFILTER_LINEAR:
2541 tex_min = WINED3DTEXF_LINEAR;
2542 break;
2543 case D3DFILTER_MIPNEAREST:
2544 tex_min = WINED3DTEXF_NONE;
2545 tex_mip = WINED3DTEXF_POINT;
2546 break;
2547 case D3DFILTER_MIPLINEAR:
2548 tex_min = WINED3DTEXF_NONE;
2549 tex_mip = WINED3DTEXF_LINEAR;
2550 break;
2551 case D3DFILTER_LINEARMIPNEAREST:
2552 tex_min = WINED3DTEXF_POINT;
2553 tex_mip = WINED3DTEXF_LINEAR;
2554 break;
2555 case D3DFILTER_LINEARMIPLINEAR:
2556 tex_min = WINED3DTEXF_LINEAR;
2557 tex_mip = WINED3DTEXF_LINEAR;
2558 break;
2560 default:
2561 ERR("Unhandled texture min %d !\n",Value);
2564 IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2565 0, WINED3DSAMP_MIPFILTER,
2566 tex_mip);
2567 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2568 0, WINED3DSAMP_MINFILTER,
2569 tex_min);
2570 break;
2573 case D3DRENDERSTATE_TEXTUREADDRESS:
2574 IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2575 0, WINED3DSAMP_ADDRESSV,
2576 Value);
2577 /* Drop through */
2578 case D3DRENDERSTATE_TEXTUREADDRESSU:
2579 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2580 0, WINED3DSAMP_ADDRESSU,
2581 Value);
2582 break;
2583 case D3DRENDERSTATE_TEXTUREADDRESSV:
2584 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2585 0, WINED3DSAMP_ADDRESSV,
2586 Value);
2587 break;
2589 default:
2591 /* FIXME: Unhandled: D3DRENDERSTATE_STIPPLEPATTERN00 - 31 */
2593 hr = IWineD3DDevice_SetRenderState(This->wineD3DDevice,
2594 RenderStateType,
2595 Value);
2596 break;
2598 LeaveCriticalSection(&ddraw_cs);
2599 return hr;
2602 static HRESULT WINAPI
2603 IDirect3DDeviceImpl_3_SetRenderState(IDirect3DDevice3 *iface,
2604 D3DRENDERSTATETYPE RenderStateType,
2605 DWORD Value)
2607 /* Note about D3DRENDERSTATE_TEXTUREMAPBLEND implementation: most of values
2608 for this state can be directly mapped to texture stage colorop and alphaop, but
2609 D3DTBLEND_MODULATE is tricky: it uses alpha from texture when available and alpha
2610 from diffuse otherwise. So changing the texture must be monitored in SetTexture to modify
2611 alphaarg when needed.
2613 Aliens vs Predator 1 depends on accurate D3DTBLEND_MODULATE emulation
2615 Legacy texture blending (TEXTUREMAPBLEND) and texture stage states: directx6 docs state that
2616 TEXTUREMAPBLEND is deprecated, yet can still be used. Games must not use both or results
2617 are undefined. D3DTBLEND_MODULATE mode in particular is dependent on texture pixel format and
2618 requires fixup of stage 0 texture states when texture changes, but this fixup can interfere
2619 with games not using this deprecated state. So a flag 'legacyTextureBlending' has to be kept
2620 in device - TRUE if the app is using TEXTUREMAPBLEND.
2622 Tests show that setting TEXTUREMAPBLEND on native doesn't seem to change values returned by
2623 GetTextureStageState and vice versa. Not so on Wine, but it is 'undefined' anyway so, probably, ok,
2624 unless some broken game will be found that cares. */
2626 HRESULT hr;
2627 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2628 TRACE("(%p)->(%08x,%d)\n", This, RenderStateType, Value);
2630 switch(RenderStateType)
2632 case D3DRENDERSTATE_TEXTUREHANDLE:
2634 if(Value == 0)
2636 hr = IWineD3DDevice_SetTexture(This->wineD3DDevice,
2638 NULL);
2639 break;
2642 if(Value > This->numHandles)
2644 FIXME("Specified handle %d out of range\n", Value);
2645 hr = DDERR_INVALIDPARAMS;
2646 break;
2648 if(This->Handles[Value - 1].type != DDrawHandle_Texture)
2650 FIXME("Handle %d isn't a texture handle\n", Value);
2651 hr = DDERR_INVALIDPARAMS;
2652 break;
2654 else
2656 IDirectDrawSurfaceImpl *surf = (IDirectDrawSurfaceImpl *) This->Handles[Value - 1].ptr;
2657 hr = IDirect3DDevice3_SetTexture(iface, 0, ICOM_INTERFACE(surf, IDirect3DTexture2));
2658 break;
2662 case D3DRENDERSTATE_TEXTUREMAPBLEND:
2664 EnterCriticalSection(&ddraw_cs);
2666 This->legacyTextureBlending = TRUE;
2668 switch ( (D3DTEXTUREBLEND) Value)
2670 case D3DTBLEND_MODULATE:
2672 BOOL tex_alpha = FALSE;
2673 IWineD3DBaseTexture *tex = NULL;
2674 WINED3DSURFACE_DESC desc;
2675 WINED3DFORMAT fmt;
2676 DDPIXELFORMAT ddfmt;
2678 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice,
2680 &tex);
2682 if(hr == WINED3D_OK && tex)
2684 memset(&desc, 0, sizeof(desc));
2685 desc.Format = &fmt;
2686 hr = IWineD3DTexture_GetLevelDesc((IWineD3DTexture*) tex, 0, &desc);
2687 if (SUCCEEDED(hr))
2689 ddfmt.dwSize = sizeof(ddfmt);
2690 PixelFormat_WineD3DtoDD(&ddfmt, fmt);
2691 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
2694 IWineD3DBaseTexture_Release(tex);
2697 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG1);
2698 if (tex_alpha)
2700 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2702 else
2704 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_CURRENT);
2707 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2708 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2709 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_MODULATE);
2711 break;
2714 case D3DTBLEND_ADD:
2715 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_ADD);
2716 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2717 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2718 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG2);
2719 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
2720 break;
2722 case D3DTBLEND_MODULATEALPHA:
2723 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2724 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2725 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2726 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
2727 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_MODULATE);
2728 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_MODULATE);
2729 break;
2731 case D3DTBLEND_COPY:
2732 case D3DTBLEND_DECAL:
2733 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2734 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2735 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_SELECTARG1);
2736 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG1);
2737 break;
2739 case D3DTBLEND_DECALALPHA:
2740 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_BLENDTEXTUREALPHA);
2741 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2742 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2743 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG2);
2744 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
2745 break;
2747 default:
2748 ERR("Unhandled texture environment %d !\n",Value);
2751 LeaveCriticalSection(&ddraw_cs);
2753 hr = D3D_OK;
2754 break;
2757 default:
2758 hr = IDirect3DDevice7_SetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
2759 RenderStateType,
2760 Value);
2761 break;
2764 return hr;
2767 static HRESULT WINAPI
2768 Thunk_IDirect3DDeviceImpl_2_SetRenderState(IDirect3DDevice2 *iface,
2769 D3DRENDERSTATETYPE RenderStateType,
2770 DWORD Value)
2772 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2773 TRACE_(ddraw_thunk)("(%p)->(%08x,%d) thunking to IDirect3DDevice3 interface.\n", This, RenderStateType, Value);
2774 return IDirect3DDevice3_SetRenderState(ICOM_INTERFACE(This, IDirect3DDevice3), RenderStateType, Value);
2777 /*****************************************************************************
2778 * Direct3DDevice3::SetLightState
2780 * Sets a light state for Direct3DDevice3 and Direct3DDevice2. The
2781 * light states are forwarded to Direct3DDevice7 render states
2783 * Version 2 and 3
2785 * Params:
2786 * LightStateType: The light state to change
2787 * Value: The value to assign to that light state
2789 * Returns:
2790 * D3D_OK on success
2791 * DDERR_INVALIDPARAMS if the parameters were incorrect
2792 * Also check IDirect3DDevice7::SetRenderState
2794 *****************************************************************************/
2795 static HRESULT WINAPI
2796 IDirect3DDeviceImpl_3_SetLightState(IDirect3DDevice3 *iface,
2797 D3DLIGHTSTATETYPE LightStateType,
2798 DWORD Value)
2800 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2801 HRESULT hr;
2803 TRACE("(%p)->(%08x,%08x)\n", This, LightStateType, Value);
2805 if (!LightStateType && (LightStateType > D3DLIGHTSTATE_COLORVERTEX))
2807 TRACE("Unexpected Light State Type\n");
2808 return DDERR_INVALIDPARAMS;
2811 EnterCriticalSection(&ddraw_cs);
2812 if (LightStateType == D3DLIGHTSTATE_MATERIAL /* 1 */)
2814 IDirect3DMaterialImpl *mat;
2816 if(Value == 0) mat = NULL;
2817 else if(Value > This->numHandles)
2819 ERR("Material handle out of range(%d)\n", Value);
2820 LeaveCriticalSection(&ddraw_cs);
2821 return DDERR_INVALIDPARAMS;
2823 else if(This->Handles[Value - 1].type != DDrawHandle_Material)
2825 ERR("Invalid handle %d\n", Value);
2826 LeaveCriticalSection(&ddraw_cs);
2827 return DDERR_INVALIDPARAMS;
2829 else
2831 mat = (IDirect3DMaterialImpl *) This->Handles[Value - 1].ptr;
2834 if (mat != NULL)
2836 TRACE(" activating material %p.\n", mat);
2837 mat->activate(mat);
2839 else
2841 FIXME(" D3DLIGHTSTATE_MATERIAL called with NULL material !!!\n");
2843 This->material = Value;
2845 else if (LightStateType == D3DLIGHTSTATE_COLORMODEL /* 3 */)
2847 switch (Value)
2849 case D3DCOLOR_MONO:
2850 ERR("DDCOLOR_MONO should not happen!\n");
2851 break;
2852 case D3DCOLOR_RGB:
2853 /* We are already in this mode */
2854 TRACE("Setting color model to RGB (no-op).\n");
2855 break;
2856 default:
2857 ERR("Unknown color model!\n");
2858 LeaveCriticalSection(&ddraw_cs);
2859 return DDERR_INVALIDPARAMS;
2862 else
2864 D3DRENDERSTATETYPE rs;
2865 switch (LightStateType)
2867 case D3DLIGHTSTATE_AMBIENT: /* 2 */
2868 rs = D3DRENDERSTATE_AMBIENT;
2869 break;
2870 case D3DLIGHTSTATE_FOGMODE: /* 4 */
2871 rs = D3DRENDERSTATE_FOGVERTEXMODE;
2872 break;
2873 case D3DLIGHTSTATE_FOGSTART: /* 5 */
2874 rs = D3DRENDERSTATE_FOGSTART;
2875 break;
2876 case D3DLIGHTSTATE_FOGEND: /* 6 */
2877 rs = D3DRENDERSTATE_FOGEND;
2878 break;
2879 case D3DLIGHTSTATE_FOGDENSITY: /* 7 */
2880 rs = D3DRENDERSTATE_FOGDENSITY;
2881 break;
2882 case D3DLIGHTSTATE_COLORVERTEX: /* 8 */
2883 rs = D3DRENDERSTATE_COLORVERTEX;
2884 break;
2885 default:
2886 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType);
2887 LeaveCriticalSection(&ddraw_cs);
2888 return DDERR_INVALIDPARAMS;
2891 hr = IDirect3DDevice7_SetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
2893 Value);
2894 LeaveCriticalSection(&ddraw_cs);
2895 return hr;
2898 LeaveCriticalSection(&ddraw_cs);
2899 return D3D_OK;
2902 static HRESULT WINAPI
2903 Thunk_IDirect3DDeviceImpl_2_SetLightState(IDirect3DDevice2 *iface,
2904 D3DLIGHTSTATETYPE LightStateType,
2905 DWORD Value)
2907 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2908 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x) thunking to IDirect3DDevice3 interface.\n", This, LightStateType, Value);
2909 return IDirect3DDevice3_SetLightState(ICOM_INTERFACE(This, IDirect3DDevice3),
2910 LightStateType,
2911 Value);
2914 /*****************************************************************************
2915 * IDirect3DDevice3::GetLightState
2917 * Returns the current setting of a light state. The state is read from
2918 * the Direct3DDevice7 render state.
2920 * Version 2 and 3
2922 * Params:
2923 * LightStateType: The light state to return
2924 * Value: The address to store the light state setting at
2926 * Returns:
2927 * D3D_OK on success
2928 * DDDERR_INVALIDPARAMS if the parameters were incorrect
2929 * Also see IDirect3DDevice7::GetRenderState
2931 *****************************************************************************/
2932 static HRESULT WINAPI
2933 IDirect3DDeviceImpl_3_GetLightState(IDirect3DDevice3 *iface,
2934 D3DLIGHTSTATETYPE LightStateType,
2935 DWORD *Value)
2937 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2938 HRESULT hr;
2940 TRACE("(%p)->(%08x,%p)\n", This, LightStateType, Value);
2942 if (!LightStateType && (LightStateType > D3DLIGHTSTATE_COLORVERTEX))
2944 TRACE("Unexpected Light State Type\n");
2945 return DDERR_INVALIDPARAMS;
2948 if(!Value)
2949 return DDERR_INVALIDPARAMS;
2951 EnterCriticalSection(&ddraw_cs);
2952 if (LightStateType == D3DLIGHTSTATE_MATERIAL /* 1 */)
2954 *Value = This->material;
2956 else if (LightStateType == D3DLIGHTSTATE_COLORMODEL /* 3 */)
2958 *Value = D3DCOLOR_RGB;
2960 else
2962 D3DRENDERSTATETYPE rs;
2963 switch (LightStateType)
2965 case D3DLIGHTSTATE_AMBIENT: /* 2 */
2966 rs = D3DRENDERSTATE_AMBIENT;
2967 break;
2968 case D3DLIGHTSTATE_FOGMODE: /* 4 */
2969 rs = D3DRENDERSTATE_FOGVERTEXMODE;
2970 break;
2971 case D3DLIGHTSTATE_FOGSTART: /* 5 */
2972 rs = D3DRENDERSTATE_FOGSTART;
2973 break;
2974 case D3DLIGHTSTATE_FOGEND: /* 6 */
2975 rs = D3DRENDERSTATE_FOGEND;
2976 break;
2977 case D3DLIGHTSTATE_FOGDENSITY: /* 7 */
2978 rs = D3DRENDERSTATE_FOGDENSITY;
2979 break;
2980 case D3DLIGHTSTATE_COLORVERTEX: /* 8 */
2981 rs = D3DRENDERSTATE_COLORVERTEX;
2982 break;
2983 default:
2984 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType);
2985 LeaveCriticalSection(&ddraw_cs);
2986 return DDERR_INVALIDPARAMS;
2989 hr = IDirect3DDevice7_GetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
2991 Value);
2992 LeaveCriticalSection(&ddraw_cs);
2993 return hr;
2996 LeaveCriticalSection(&ddraw_cs);
2997 return D3D_OK;
3000 static HRESULT WINAPI
3001 Thunk_IDirect3DDeviceImpl_2_GetLightState(IDirect3DDevice2 *iface,
3002 D3DLIGHTSTATETYPE LightStateType,
3003 DWORD *Value)
3005 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3006 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice3 interface.\n", This, LightStateType, Value);
3007 return IDirect3DDevice3_GetLightState(ICOM_INTERFACE(This, IDirect3DDevice3),
3008 LightStateType,
3009 Value);
3012 /*****************************************************************************
3013 * IDirect3DDevice7::SetTransform
3015 * Assigns a D3DMATRIX to a transform type. The transform types are defined
3016 * in include/d3dtypes.h.
3017 * The D3DTRANSFORMSTATE_WORLD (=1) is translated to D3DTS_WORLDMATRIX(0)
3018 * (=255) for wined3d, because the 1 transform state was removed in d3d8
3019 * and WineD3D already understands the replacement D3DTS_WORLDMATRIX(0)
3021 * Version 2, 3 and 7
3023 * Params:
3024 * TransformStateType: transform state to set
3025 * Matrix: Matrix to assign to the state
3027 * Returns:
3028 * D3D_OK on success
3029 * DDERR_INVALIDPARAMS if Matrix == NULL
3030 * For details see IWineD3DDevice::SetTransform
3032 *****************************************************************************/
3033 static HRESULT WINAPI
3034 IDirect3DDeviceImpl_7_SetTransform(IDirect3DDevice7 *iface,
3035 D3DTRANSFORMSTATETYPE TransformStateType,
3036 D3DMATRIX *Matrix)
3038 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3039 D3DTRANSFORMSTATETYPE type = TransformStateType;
3040 HRESULT hr;
3041 TRACE("(%p)->(%08x,%p): Relay\n", This, TransformStateType, Matrix);
3043 switch(TransformStateType)
3045 case D3DTRANSFORMSTATE_WORLD : type = WINED3DTS_WORLDMATRIX(0); break;
3046 case D3DTRANSFORMSTATE_WORLD1: type = WINED3DTS_WORLDMATRIX(1); break;
3047 case D3DTRANSFORMSTATE_WORLD2: type = WINED3DTS_WORLDMATRIX(2); break;
3048 case D3DTRANSFORMSTATE_WORLD3: type = WINED3DTS_WORLDMATRIX(3); break;
3049 default: type = TransformStateType;
3052 if(!Matrix)
3053 return DDERR_INVALIDPARAMS;
3055 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3056 EnterCriticalSection(&ddraw_cs);
3057 hr = IWineD3DDevice_SetTransform(This->wineD3DDevice,
3058 type,
3059 (WINED3DMATRIX*) Matrix);
3060 LeaveCriticalSection(&ddraw_cs);
3061 return hr;
3064 static HRESULT WINAPI
3065 Thunk_IDirect3DDeviceImpl_3_SetTransform(IDirect3DDevice3 *iface,
3066 D3DTRANSFORMSTATETYPE TransformStateType,
3067 D3DMATRIX *D3DMatrix)
3069 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3070 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3071 return IDirect3DDevice7_SetTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
3072 TransformStateType,
3073 D3DMatrix);
3076 static HRESULT WINAPI
3077 Thunk_IDirect3DDeviceImpl_2_SetTransform(IDirect3DDevice2 *iface,
3078 D3DTRANSFORMSTATETYPE TransformStateType,
3079 D3DMATRIX *D3DMatrix)
3081 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3082 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3083 return IDirect3DDevice7_SetTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
3084 TransformStateType,
3085 D3DMatrix);
3088 /*****************************************************************************
3089 * IDirect3DDevice7::GetTransform
3091 * Returns the matrix assigned to a transform state
3092 * D3DTRANSFORMSTATE_WORLD is translated to D3DTS_WORLDMATRIX(0), see
3093 * SetTransform
3095 * Params:
3096 * TransformStateType: State to read the matrix from
3097 * Matrix: Address to store the matrix at
3099 * Returns:
3100 * D3D_OK on success
3101 * DDERR_INVALIDPARAMS if Matrix == NULL
3102 * For details, see IWineD3DDevice::GetTransform
3104 *****************************************************************************/
3105 static HRESULT WINAPI
3106 IDirect3DDeviceImpl_7_GetTransform(IDirect3DDevice7 *iface,
3107 D3DTRANSFORMSTATETYPE TransformStateType,
3108 D3DMATRIX *Matrix)
3110 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3111 D3DTRANSFORMSTATETYPE type = TransformStateType;
3112 HRESULT hr;
3113 TRACE("(%p)->(%08x,%p): Relay\n", This, TransformStateType, Matrix);
3115 switch(TransformStateType)
3117 case D3DTRANSFORMSTATE_WORLD : type = WINED3DTS_WORLDMATRIX(0); break;
3118 case D3DTRANSFORMSTATE_WORLD1: type = WINED3DTS_WORLDMATRIX(1); break;
3119 case D3DTRANSFORMSTATE_WORLD2: type = WINED3DTS_WORLDMATRIX(2); break;
3120 case D3DTRANSFORMSTATE_WORLD3: type = WINED3DTS_WORLDMATRIX(3); break;
3121 default: type = TransformStateType;
3124 if(!Matrix)
3125 return DDERR_INVALIDPARAMS;
3127 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3128 EnterCriticalSection(&ddraw_cs);
3129 hr = IWineD3DDevice_GetTransform(This->wineD3DDevice, type, (WINED3DMATRIX*) Matrix);
3130 LeaveCriticalSection(&ddraw_cs);
3131 return hr;
3134 static HRESULT WINAPI
3135 Thunk_IDirect3DDeviceImpl_3_GetTransform(IDirect3DDevice3 *iface,
3136 D3DTRANSFORMSTATETYPE TransformStateType,
3137 D3DMATRIX *D3DMatrix)
3139 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3140 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3141 return IDirect3DDevice7_GetTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
3142 TransformStateType,
3143 D3DMatrix);
3146 static HRESULT WINAPI
3147 Thunk_IDirect3DDeviceImpl_2_GetTransform(IDirect3DDevice2 *iface,
3148 D3DTRANSFORMSTATETYPE TransformStateType,
3149 D3DMATRIX *D3DMatrix)
3151 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3152 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3153 return IDirect3DDevice7_GetTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
3154 TransformStateType,
3155 D3DMatrix);
3158 /*****************************************************************************
3159 * IDirect3DDevice7::MultiplyTransform
3161 * Multiplies the already-set transform matrix of a transform state
3162 * with another matrix. For the world matrix, see SetTransform
3164 * Version 2, 3 and 7
3166 * Params:
3167 * TransformStateType: Transform state to multiply
3168 * D3DMatrix Matrix to multiply with.
3170 * Returns
3171 * D3D_OK on success
3172 * DDERR_INVALIDPARAMS if D3DMatrix is NULL
3173 * For details, see IWineD3DDevice::MultiplyTransform
3175 *****************************************************************************/
3176 static HRESULT WINAPI
3177 IDirect3DDeviceImpl_7_MultiplyTransform(IDirect3DDevice7 *iface,
3178 D3DTRANSFORMSTATETYPE TransformStateType,
3179 D3DMATRIX *D3DMatrix)
3181 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3182 HRESULT hr;
3183 D3DTRANSFORMSTATETYPE type;
3184 TRACE("(%p)->(%08x,%p): Relay\n", This, TransformStateType, D3DMatrix);
3186 switch(TransformStateType)
3188 case D3DTRANSFORMSTATE_WORLD : type = WINED3DTS_WORLDMATRIX(0); break;
3189 case D3DTRANSFORMSTATE_WORLD1: type = WINED3DTS_WORLDMATRIX(1); break;
3190 case D3DTRANSFORMSTATE_WORLD2: type = WINED3DTS_WORLDMATRIX(2); break;
3191 case D3DTRANSFORMSTATE_WORLD3: type = WINED3DTS_WORLDMATRIX(3); break;
3192 default: type = TransformStateType;
3195 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3196 EnterCriticalSection(&ddraw_cs);
3197 hr = IWineD3DDevice_MultiplyTransform(This->wineD3DDevice,
3198 type,
3199 (WINED3DMATRIX*) D3DMatrix);
3200 LeaveCriticalSection(&ddraw_cs);
3201 return hr;
3204 static HRESULT WINAPI
3205 Thunk_IDirect3DDeviceImpl_3_MultiplyTransform(IDirect3DDevice3 *iface,
3206 D3DTRANSFORMSTATETYPE TransformStateType,
3207 D3DMATRIX *D3DMatrix)
3209 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3210 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3211 return IDirect3DDevice7_MultiplyTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
3212 TransformStateType,
3213 D3DMatrix);
3216 static HRESULT WINAPI
3217 Thunk_IDirect3DDeviceImpl_2_MultiplyTransform(IDirect3DDevice2 *iface,
3218 D3DTRANSFORMSTATETYPE TransformStateType,
3219 D3DMATRIX *D3DMatrix)
3221 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3222 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3223 return IDirect3DDevice7_MultiplyTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
3224 TransformStateType,
3225 D3DMatrix);
3228 /*****************************************************************************
3229 * IDirect3DDevice7::DrawPrimitive
3231 * Draws primitives based on vertices in an application-provided pointer
3233 * Version 2, 3 and 7. The IDirect3DDevice2 thunk converts the fixed vertex type into
3234 * an FVF format for D3D7
3236 * Params:
3237 * PrimitiveType: The type of the primitives to draw
3238 * Vertex type: Flexible vertex format vertex description
3239 * Vertices: Pointer to the vertex array
3240 * VertexCount: The number of vertices to draw
3241 * Flags: As usual a few flags
3243 * Returns:
3244 * D3D_OK on success
3245 * DDERR_INVALIDPARAMS if Vertices is NULL
3246 * For details, see IWineD3DDevice::DrawPrimitiveUP
3248 *****************************************************************************/
3249 static HRESULT WINAPI
3250 IDirect3DDeviceImpl_7_DrawPrimitive(IDirect3DDevice7 *iface,
3251 D3DPRIMITIVETYPE PrimitiveType,
3252 DWORD VertexType,
3253 void *Vertices,
3254 DWORD VertexCount,
3255 DWORD Flags)
3257 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3258 UINT PrimitiveCount, stride;
3259 HRESULT hr;
3260 TRACE("(%p)->(%08x,%08x,%p,%08x,%08x): Relay!\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3262 if(!Vertices)
3263 return DDERR_INVALIDPARAMS;
3265 /* Get the vertex count */
3266 switch(PrimitiveType)
3268 case D3DPT_POINTLIST:
3269 PrimitiveCount = VertexCount;
3270 break;
3272 case D3DPT_LINELIST:
3273 PrimitiveCount = VertexCount / 2;
3274 break;
3276 case D3DPT_LINESTRIP:
3277 PrimitiveCount = VertexCount - 1;
3278 break;
3280 case D3DPT_TRIANGLELIST:
3281 PrimitiveCount = VertexCount / 3;
3282 break;
3284 case D3DPT_TRIANGLESTRIP:
3285 PrimitiveCount = VertexCount - 2;
3286 break;
3288 case D3DPT_TRIANGLEFAN:
3289 PrimitiveCount = VertexCount - 2;
3290 break;
3292 default:
3293 return DDERR_INVALIDPARAMS;
3296 /* Get the stride */
3297 stride = get_flexible_vertex_size(VertexType);
3299 /* Set the FVF */
3300 EnterCriticalSection(&ddraw_cs);
3301 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
3302 IDirectDrawImpl_FindDecl(This->ddraw, VertexType));
3303 if(hr != D3D_OK)
3305 LeaveCriticalSection(&ddraw_cs);
3306 return hr;
3309 /* This method translates to the user pointer draw of WineD3D */
3310 hr = IWineD3DDevice_DrawPrimitiveUP(This->wineD3DDevice,
3311 PrimitiveType,
3312 PrimitiveCount,
3313 Vertices,
3314 stride);
3315 LeaveCriticalSection(&ddraw_cs);
3316 return hr;
3319 static HRESULT WINAPI
3320 Thunk_IDirect3DDeviceImpl_3_DrawPrimitive(IDirect3DDevice3 *iface,
3321 D3DPRIMITIVETYPE PrimitiveType,
3322 DWORD VertexType,
3323 void *Vertices,
3324 DWORD VertexCount,
3325 DWORD Flags)
3327 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3328 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3329 return IDirect3DDevice7_DrawPrimitive(ICOM_INTERFACE(This, IDirect3DDevice7),
3330 PrimitiveType,
3331 VertexType,
3332 Vertices,
3333 VertexCount,
3334 Flags);
3337 static HRESULT WINAPI
3338 Thunk_IDirect3DDeviceImpl_2_DrawPrimitive(IDirect3DDevice2 *iface,
3339 D3DPRIMITIVETYPE PrimitiveType,
3340 D3DVERTEXTYPE VertexType,
3341 void *Vertices,
3342 DWORD VertexCount,
3343 DWORD Flags)
3345 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3346 DWORD FVF;
3347 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3349 switch(VertexType)
3351 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
3352 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
3353 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
3354 default:
3355 ERR("Unexpected vertex type %d\n", VertexType);
3356 return DDERR_INVALIDPARAMS; /* Should never happen */
3359 return IDirect3DDevice7_DrawPrimitive(ICOM_INTERFACE(This, IDirect3DDevice7),
3360 PrimitiveType,
3361 FVF,
3362 Vertices,
3363 VertexCount,
3364 Flags);
3367 /*****************************************************************************
3368 * IDirect3DDevice7::DrawIndexedPrimitive
3370 * Draws vertices from an application-provided pointer, based on the index
3371 * numbers in a WORD array.
3373 * Version 2, 3 and 7. The version 7 thunk translates the vertex type into
3374 * an FVF format for D3D7
3376 * Params:
3377 * PrimitiveType: The primitive type to draw
3378 * VertexType: The FVF vertex description
3379 * Vertices: Pointer to the vertex array
3380 * VertexCount: ?
3381 * Indices: Pointer to the index array
3382 * IndexCount: Number of indices = Number of vertices to draw
3383 * Flags: As usual, some flags
3385 * Returns:
3386 * D3D_OK on success
3387 * DDERR_INVALIDPARAMS if Vertices or Indices is NULL
3388 * For details, see IWineD3DDevice::DrawIndexedPrimitiveUP
3390 *****************************************************************************/
3391 static HRESULT WINAPI
3392 IDirect3DDeviceImpl_7_DrawIndexedPrimitive(IDirect3DDevice7 *iface,
3393 D3DPRIMITIVETYPE PrimitiveType,
3394 DWORD VertexType,
3395 void *Vertices,
3396 DWORD VertexCount,
3397 WORD *Indices,
3398 DWORD IndexCount,
3399 DWORD Flags)
3401 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3402 UINT PrimitiveCount = 0;
3403 HRESULT hr;
3404 TRACE("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x): Relay!\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3406 /* Get the primitive number */
3407 switch(PrimitiveType)
3409 case D3DPT_POINTLIST:
3410 PrimitiveCount = IndexCount;
3411 break;
3413 case D3DPT_LINELIST:
3414 PrimitiveCount = IndexCount / 2;
3415 break;
3417 case D3DPT_LINESTRIP:
3418 PrimitiveCount = IndexCount - 1;
3419 break;
3421 case D3DPT_TRIANGLELIST:
3422 PrimitiveCount = IndexCount / 3;
3423 break;
3425 case D3DPT_TRIANGLESTRIP:
3426 PrimitiveCount = IndexCount - 2;
3427 break;
3429 case D3DPT_TRIANGLEFAN:
3430 PrimitiveCount = IndexCount - 2;
3431 break;
3433 default:
3434 return DDERR_INVALIDPARAMS;
3437 /* Set the D3DDevice's FVF */
3438 EnterCriticalSection(&ddraw_cs);
3439 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
3440 IDirectDrawImpl_FindDecl(This->ddraw, VertexType));
3441 if(FAILED(hr))
3443 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr);
3444 LeaveCriticalSection(&ddraw_cs);
3445 return hr;
3448 hr = IWineD3DDevice_DrawIndexedPrimitiveUP(This->wineD3DDevice,
3449 PrimitiveType,
3450 0 /* MinVertexIndex */,
3451 VertexCount /* UINT NumVertexIndex */,
3452 PrimitiveCount,
3453 Indices,
3454 WINED3DFMT_INDEX16,
3455 Vertices,
3456 get_flexible_vertex_size(VertexType));
3457 LeaveCriticalSection(&ddraw_cs);
3458 return hr;
3461 static HRESULT WINAPI
3462 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive(IDirect3DDevice3 *iface,
3463 D3DPRIMITIVETYPE PrimitiveType,
3464 DWORD VertexType,
3465 void *Vertices,
3466 DWORD VertexCount,
3467 WORD *Indices,
3468 DWORD IndexCount,
3469 DWORD Flags)
3471 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3472 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3473 return IDirect3DDevice7_DrawIndexedPrimitive(ICOM_INTERFACE(This, IDirect3DDevice7),
3474 PrimitiveType,
3475 VertexType,
3476 Vertices,
3477 VertexCount,
3478 Indices,
3479 IndexCount,
3480 Flags);
3483 static HRESULT WINAPI
3484 Thunk_IDirect3DDeviceImpl_2_DrawIndexedPrimitive(IDirect3DDevice2 *iface,
3485 D3DPRIMITIVETYPE PrimitiveType,
3486 D3DVERTEXTYPE VertexType,
3487 void *Vertices,
3488 DWORD VertexCount,
3489 WORD *Indices,
3490 DWORD IndexCount,
3491 DWORD Flags)
3493 DWORD FVF;
3494 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3495 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3497 switch(VertexType)
3499 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
3500 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
3501 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
3502 default:
3503 ERR("Unexpected vertex type %d\n", VertexType);
3504 return DDERR_INVALIDPARAMS; /* Should never happen */
3507 return IDirect3DDevice7_DrawIndexedPrimitive(ICOM_INTERFACE(This, IDirect3DDevice7),
3508 PrimitiveType,
3509 FVF,
3510 Vertices,
3511 VertexCount,
3512 Indices,
3513 IndexCount,
3514 Flags);
3517 /*****************************************************************************
3518 * IDirect3DDevice7::SetClipStatus
3520 * Sets the clip status. This defines things as clipping conditions and
3521 * the extents of the clipping region.
3523 * Version 2, 3 and 7
3525 * Params:
3526 * ClipStatus:
3528 * Returns:
3529 * D3D_OK because it's a stub
3530 * (DDERR_INVALIDPARAMS if ClipStatus == NULL)
3532 *****************************************************************************/
3533 static HRESULT WINAPI
3534 IDirect3DDeviceImpl_7_SetClipStatus(IDirect3DDevice7 *iface,
3535 D3DCLIPSTATUS *ClipStatus)
3537 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3538 FIXME("(%p)->(%p): Stub!\n", This, ClipStatus);
3540 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them
3541 * Perhaps this needs a new data type and an additional IWineD3DDevice method
3543 /* return IWineD3DDevice_SetClipStatus(This->wineD3DDevice, ClipStatus);*/
3544 return D3D_OK;
3547 static HRESULT WINAPI
3548 Thunk_IDirect3DDeviceImpl_3_SetClipStatus(IDirect3DDevice3 *iface,
3549 D3DCLIPSTATUS *ClipStatus)
3551 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3552 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3553 return IDirect3DDevice7_SetClipStatus(ICOM_INTERFACE(This, IDirect3DDevice7),
3554 ClipStatus);
3557 static HRESULT WINAPI
3558 Thunk_IDirect3DDeviceImpl_2_SetClipStatus(IDirect3DDevice2 *iface,
3559 D3DCLIPSTATUS *ClipStatus)
3561 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3562 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3563 return IDirect3DDevice7_SetClipStatus(ICOM_INTERFACE(This, IDirect3DDevice7),
3564 ClipStatus);
3567 /*****************************************************************************
3568 * IDirect3DDevice7::GetClipStatus
3570 * Returns the clip status
3572 * Params:
3573 * ClipStatus: Address to write the clip status to
3575 * Returns:
3576 * D3D_OK because it's a stub
3578 *****************************************************************************/
3579 static HRESULT WINAPI
3580 IDirect3DDeviceImpl_7_GetClipStatus(IDirect3DDevice7 *iface,
3581 D3DCLIPSTATUS *ClipStatus)
3583 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3584 FIXME("(%p)->(%p): Stub!\n", This, ClipStatus);
3586 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them */
3587 /* return IWineD3DDevice_GetClipStatus(This->wineD3DDevice, ClipStatus);*/
3588 return D3D_OK;
3591 static HRESULT WINAPI
3592 Thunk_IDirect3DDeviceImpl_3_GetClipStatus(IDirect3DDevice3 *iface,
3593 D3DCLIPSTATUS *ClipStatus)
3595 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3596 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3597 return IDirect3DDevice7_GetClipStatus(ICOM_INTERFACE(This, IDirect3DDevice7),
3598 ClipStatus);
3601 static HRESULT WINAPI
3602 Thunk_IDirect3DDeviceImpl_2_GetClipStatus(IDirect3DDevice2 *iface,
3603 D3DCLIPSTATUS *ClipStatus)
3605 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3606 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3607 return IDirect3DDevice7_GetClipStatus(ICOM_INTERFACE(This, IDirect3DDevice7),
3608 ClipStatus);
3611 /*****************************************************************************
3612 * IDirect3DDevice::DrawPrimitiveStrided
3614 * Draws vertices described by a D3DDRAWPRIMITIVESTRIDEDDATA structure.
3616 * Version 3 and 7
3618 * Params:
3619 * PrimitiveType: The primitive type to draw
3620 * VertexType: The FVF description of the vertices to draw (for the stride??)
3621 * D3DDrawPrimStrideData: A D3DDRAWPRIMITIVESTRIDEDDATA structure describing
3622 * the vertex data locations
3623 * VertexCount: The number of vertices to draw
3624 * Flags: Some flags
3626 * Returns:
3627 * D3D_OK, because it's a stub
3628 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
3629 * (For details, see IWineD3DDevice::DrawPrimitiveStrided)
3631 *****************************************************************************/
3632 static HRESULT WINAPI
3633 IDirect3DDeviceImpl_7_DrawPrimitiveStrided(IDirect3DDevice7 *iface,
3634 D3DPRIMITIVETYPE PrimitiveType,
3635 DWORD VertexType,
3636 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3637 DWORD VertexCount,
3638 DWORD Flags)
3640 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3641 WineDirect3DVertexStridedData WineD3DStrided;
3642 int i;
3643 UINT PrimitiveCount;
3644 HRESULT hr;
3646 TRACE("(%p)->(%08x,%08x,%p,%08x,%08x): stub!\n", This, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
3648 memset(&WineD3DStrided, 0, sizeof(WineD3DStrided));
3649 /* Get the strided data right. the wined3d structure is a bit bigger
3650 * Watch out: The contents of the strided data are determined by the fvf,
3651 * not by the members set in D3DDrawPrimStrideData. So it's valid
3652 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
3653 * not set in the fvf.
3655 if(VertexType & D3DFVF_POSITION_MASK)
3657 WineD3DStrided.u.s.position.lpData = D3DDrawPrimStrideData->position.lpvData;
3658 WineD3DStrided.u.s.position.dwStride = D3DDrawPrimStrideData->position.dwStride;
3659 WineD3DStrided.u.s.position.dwType = WINED3DDECLTYPE_FLOAT3;
3660 if (VertexType & D3DFVF_XYZRHW)
3662 WineD3DStrided.u.s.position.dwType = WINED3DDECLTYPE_FLOAT4;
3663 WineD3DStrided.u.s.position_transformed = TRUE;
3664 } else
3665 WineD3DStrided.u.s.position_transformed = FALSE;
3668 if(VertexType & D3DFVF_NORMAL)
3670 WineD3DStrided.u.s.normal.lpData = D3DDrawPrimStrideData->normal.lpvData;
3671 WineD3DStrided.u.s.normal.dwStride = D3DDrawPrimStrideData->normal.dwStride;
3672 WineD3DStrided.u.s.normal.dwType = WINED3DDECLTYPE_FLOAT3;
3675 if(VertexType & D3DFVF_DIFFUSE)
3677 WineD3DStrided.u.s.diffuse.lpData = D3DDrawPrimStrideData->diffuse.lpvData;
3678 WineD3DStrided.u.s.diffuse.dwStride = D3DDrawPrimStrideData->diffuse.dwStride;
3679 WineD3DStrided.u.s.diffuse.dwType = WINED3DDECLTYPE_D3DCOLOR;
3682 if(VertexType & D3DFVF_SPECULAR)
3684 WineD3DStrided.u.s.specular.lpData = D3DDrawPrimStrideData->specular.lpvData;
3685 WineD3DStrided.u.s.specular.dwStride = D3DDrawPrimStrideData->specular.dwStride;
3686 WineD3DStrided.u.s.specular.dwType = WINED3DDECLTYPE_D3DCOLOR;
3689 for( i = 0; i < GET_TEXCOUNT_FROM_FVF(VertexType); i++)
3691 WineD3DStrided.u.s.texCoords[i].lpData = D3DDrawPrimStrideData->textureCoords[i].lpvData;
3692 WineD3DStrided.u.s.texCoords[i].dwStride = D3DDrawPrimStrideData->textureCoords[i].dwStride;
3693 switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i))
3695 case 1: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT1; break;
3696 case 2: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT2; break;
3697 case 3: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT3; break;
3698 case 4: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT4; break;
3699 default: ERR("Unexpected texture coordinate size %d\n",
3700 GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i));
3704 /* Get the primitive count */
3705 switch(PrimitiveType)
3707 case D3DPT_POINTLIST:
3708 PrimitiveCount = VertexCount;
3709 break;
3711 case D3DPT_LINELIST:
3712 PrimitiveCount = VertexCount / 2;
3713 break;
3715 case D3DPT_LINESTRIP:
3716 PrimitiveCount = VertexCount - 1;
3717 break;
3719 case D3DPT_TRIANGLELIST:
3720 PrimitiveCount = VertexCount / 3;
3721 break;
3723 case D3DPT_TRIANGLESTRIP:
3724 PrimitiveCount = VertexCount - 2;
3725 break;
3727 case D3DPT_TRIANGLEFAN:
3728 PrimitiveCount = VertexCount - 2;
3729 break;
3731 default: return DDERR_INVALIDPARAMS;
3734 /* WineD3D doesn't need the FVF here */
3735 EnterCriticalSection(&ddraw_cs);
3736 hr = IWineD3DDevice_DrawPrimitiveStrided(This->wineD3DDevice,
3737 PrimitiveType,
3738 PrimitiveCount,
3739 &WineD3DStrided);
3740 LeaveCriticalSection(&ddraw_cs);
3741 return hr;
3744 static HRESULT WINAPI
3745 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided(IDirect3DDevice3 *iface,
3746 D3DPRIMITIVETYPE PrimitiveType,
3747 DWORD VertexType,
3748 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3749 DWORD VertexCount,
3750 DWORD Flags)
3752 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3753 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
3754 return IDirect3DDevice7_DrawPrimitiveStrided(ICOM_INTERFACE(This, IDirect3DDevice7),
3755 PrimitiveType,
3756 VertexType,
3757 D3DDrawPrimStrideData,
3758 VertexCount,
3759 Flags);
3762 /*****************************************************************************
3763 * IDirect3DDevice7::DrawIndexedPrimitiveStrided
3765 * Draws primitives specified by strided data locations based on indices
3767 * Version 3 and 7
3769 * Params:
3770 * PrimitiveType:
3772 * Returns:
3773 * D3D_OK, because it's a stub
3774 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
3775 * (DDERR_INVALIDPARAMS if Indices is NULL)
3776 * (For more details, see IWineD3DDevice::DrawIndexedPrimitiveStrided)
3778 *****************************************************************************/
3779 static HRESULT WINAPI
3780 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(IDirect3DDevice7 *iface,
3781 D3DPRIMITIVETYPE PrimitiveType,
3782 DWORD VertexType,
3783 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3784 DWORD VertexCount,
3785 WORD *Indices,
3786 DWORD IndexCount,
3787 DWORD Flags)
3789 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3790 WineDirect3DVertexStridedData WineD3DStrided;
3791 int i;
3792 UINT PrimitiveCount;
3793 HRESULT hr;
3795 TRACE("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x)\n", This, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
3797 memset(&WineD3DStrided, 0, sizeof(WineD3DStrided));
3798 /* Get the strided data right. the wined3d structure is a bit bigger
3799 * Watch out: The contents of the strided data are determined by the fvf,
3800 * not by the members set in D3DDrawPrimStrideData. So it's valid
3801 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
3802 * not set in the fvf.
3804 if(VertexType & D3DFVF_POSITION_MASK)
3806 WineD3DStrided.u.s.position.lpData = D3DDrawPrimStrideData->position.lpvData;
3807 WineD3DStrided.u.s.position.dwStride = D3DDrawPrimStrideData->position.dwStride;
3808 WineD3DStrided.u.s.position.dwType = WINED3DDECLTYPE_FLOAT3;
3809 if (VertexType & D3DFVF_XYZRHW)
3811 WineD3DStrided.u.s.position.dwType = WINED3DDECLTYPE_FLOAT4;
3812 WineD3DStrided.u.s.position_transformed = TRUE;
3813 } else
3814 WineD3DStrided.u.s.position_transformed = FALSE;
3817 if(VertexType & D3DFVF_NORMAL)
3819 WineD3DStrided.u.s.normal.lpData = D3DDrawPrimStrideData->normal.lpvData;
3820 WineD3DStrided.u.s.normal.dwStride = D3DDrawPrimStrideData->normal.dwStride;
3821 WineD3DStrided.u.s.normal.dwType = WINED3DDECLTYPE_FLOAT3;
3824 if(VertexType & D3DFVF_DIFFUSE)
3826 WineD3DStrided.u.s.diffuse.lpData = D3DDrawPrimStrideData->diffuse.lpvData;
3827 WineD3DStrided.u.s.diffuse.dwStride = D3DDrawPrimStrideData->diffuse.dwStride;
3828 WineD3DStrided.u.s.diffuse.dwType = WINED3DDECLTYPE_D3DCOLOR;
3831 if(VertexType & D3DFVF_SPECULAR)
3833 WineD3DStrided.u.s.specular.lpData = D3DDrawPrimStrideData->specular.lpvData;
3834 WineD3DStrided.u.s.specular.dwStride = D3DDrawPrimStrideData->specular.dwStride;
3835 WineD3DStrided.u.s.specular.dwType = WINED3DDECLTYPE_D3DCOLOR;
3838 for( i = 0; i < GET_TEXCOUNT_FROM_FVF(VertexType); i++)
3840 WineD3DStrided.u.s.texCoords[i].lpData = D3DDrawPrimStrideData->textureCoords[i].lpvData;
3841 WineD3DStrided.u.s.texCoords[i].dwStride = D3DDrawPrimStrideData->textureCoords[i].dwStride;
3842 switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i))
3844 case 1: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT1; break;
3845 case 2: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT2; break;
3846 case 3: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT3; break;
3847 case 4: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT4; break;
3848 default: ERR("Unexpected texture coordinate size %d\n",
3849 GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i));
3853 /* Get the primitive count */
3854 switch(PrimitiveType)
3856 case D3DPT_POINTLIST:
3857 PrimitiveCount = IndexCount;
3858 break;
3860 case D3DPT_LINELIST:
3861 PrimitiveCount = IndexCount / 2;
3862 break;
3864 case D3DPT_LINESTRIP:
3865 PrimitiveCount = IndexCount - 1;
3866 break;
3868 case D3DPT_TRIANGLELIST:
3869 PrimitiveCount = IndexCount / 3;
3870 break;
3872 case D3DPT_TRIANGLESTRIP:
3873 PrimitiveCount = IndexCount - 2;
3874 break;
3876 case D3DPT_TRIANGLEFAN:
3877 PrimitiveCount = IndexCount - 2;
3878 break;
3880 default: return DDERR_INVALIDPARAMS;
3883 /* WineD3D doesn't need the FVF here */
3884 EnterCriticalSection(&ddraw_cs);
3885 hr = IWineD3DDevice_DrawIndexedPrimitiveStrided(This->wineD3DDevice,
3886 PrimitiveType,
3887 PrimitiveCount,
3888 &WineD3DStrided,
3889 VertexCount,
3890 Indices,
3891 WINED3DFMT_INDEX16);
3892 LeaveCriticalSection(&ddraw_cs);
3893 return hr;
3896 static HRESULT WINAPI
3897 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided(IDirect3DDevice3 *iface,
3898 D3DPRIMITIVETYPE PrimitiveType,
3899 DWORD VertexType,
3900 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3901 DWORD VertexCount,
3902 WORD *Indices,
3903 DWORD IndexCount,
3904 DWORD Flags)
3906 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3907 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
3908 return IDirect3DDevice7_DrawIndexedPrimitiveStrided(ICOM_INTERFACE(This, IDirect3DDevice7),
3909 PrimitiveType,
3910 VertexType,
3911 D3DDrawPrimStrideData,
3912 VertexCount,
3913 Indices,
3914 IndexCount,
3915 Flags);
3918 /*****************************************************************************
3919 * IDirect3DDevice7::DrawPrimitiveVB
3921 * Draws primitives from a vertex buffer to the screen.
3923 * Version 3 and 7
3925 * Params:
3926 * PrimitiveType: Type of primitive to be rendered.
3927 * D3DVertexBuf: Source Vertex Buffer
3928 * StartVertex: Index of the first vertex from the buffer to be rendered
3929 * NumVertices: Number of vertices to be rendered
3930 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
3932 * Return values
3933 * D3D_OK on success
3934 * DDERR_INVALIDPARAMS if D3DVertexBuf is NULL
3936 *****************************************************************************/
3937 static HRESULT WINAPI
3938 IDirect3DDeviceImpl_7_DrawPrimitiveVB(IDirect3DDevice7 *iface,
3939 D3DPRIMITIVETYPE PrimitiveType,
3940 IDirect3DVertexBuffer7 *D3DVertexBuf,
3941 DWORD StartVertex,
3942 DWORD NumVertices,
3943 DWORD Flags)
3945 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3946 IDirect3DVertexBufferImpl *vb = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, D3DVertexBuf);
3947 UINT PrimitiveCount;
3948 HRESULT hr;
3949 DWORD stride;
3950 WINED3DVERTEXBUFFER_DESC Desc;
3952 TRACE("(%p)->(%08x,%p,%08x,%08x,%08x)\n", This, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags);
3954 /* Sanity checks */
3955 if(!vb)
3957 ERR("(%p) No Vertex buffer specified\n", This);
3958 return DDERR_INVALIDPARAMS;
3961 /* Get the primitive count */
3962 switch(PrimitiveType)
3964 case D3DPT_POINTLIST:
3965 PrimitiveCount = NumVertices;
3966 break;
3968 case D3DPT_LINELIST:
3969 PrimitiveCount = NumVertices / 2;
3970 break;
3972 case D3DPT_LINESTRIP:
3973 PrimitiveCount = NumVertices - 1;
3974 break;
3976 case D3DPT_TRIANGLELIST:
3977 PrimitiveCount = NumVertices / 3;
3978 break;
3980 case D3DPT_TRIANGLESTRIP:
3981 PrimitiveCount = NumVertices - 2;
3982 break;
3984 case D3DPT_TRIANGLEFAN:
3985 PrimitiveCount = NumVertices - 2;
3986 break;
3988 default:
3989 return DDERR_INVALIDPARAMS;
3992 /* Get the FVF of the vertex buffer, and its stride */
3993 EnterCriticalSection(&ddraw_cs);
3994 hr = IWineD3DVertexBuffer_GetDesc(vb->wineD3DVertexBuffer,
3995 &Desc);
3996 if(hr != D3D_OK)
3998 ERR("(%p) IWineD3DVertexBuffer::GetDesc failed with hr = %08x\n", This, hr);
3999 LeaveCriticalSection(&ddraw_cs);
4000 return hr;
4002 stride = get_flexible_vertex_size(Desc.FVF);
4004 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
4005 vb->wineD3DVertexDeclaration);
4006 if(FAILED(hr))
4008 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr);
4009 LeaveCriticalSection(&ddraw_cs);
4010 return hr;
4013 /* Set the vertex stream source */
4014 hr = IWineD3DDevice_SetStreamSource(This->wineD3DDevice,
4015 0 /* StreamNumber */,
4016 vb->wineD3DVertexBuffer,
4017 0 /* StartVertex - we pass this to DrawPrimitive */,
4018 stride);
4019 if(hr != D3D_OK)
4021 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This, hr);
4022 LeaveCriticalSection(&ddraw_cs);
4023 return hr;
4026 /* Now draw the primitives */
4027 hr = IWineD3DDevice_DrawPrimitive(This->wineD3DDevice,
4028 PrimitiveType,
4029 StartVertex,
4030 PrimitiveCount);
4031 LeaveCriticalSection(&ddraw_cs);
4032 return hr;
4035 static HRESULT WINAPI
4036 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB(IDirect3DDevice3 *iface,
4037 D3DPRIMITIVETYPE PrimitiveType,
4038 IDirect3DVertexBuffer *D3DVertexBuf,
4039 DWORD StartVertex,
4040 DWORD NumVertices,
4041 DWORD Flags)
4043 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4044 IDirect3DVertexBufferImpl *vb = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, D3DVertexBuf);
4045 TRACE_(ddraw_thunk)("(%p)->(%08x,%p,%08x,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, vb, StartVertex, NumVertices, Flags);
4046 return IDirect3DDevice7_DrawPrimitiveVB(ICOM_INTERFACE(This, IDirect3DDevice7),
4047 PrimitiveType,
4048 ICOM_INTERFACE(vb, IDirect3DVertexBuffer7),
4049 StartVertex,
4050 NumVertices,
4051 Flags);
4055 /*****************************************************************************
4056 * IDirect3DDevice7::DrawIndexedPrimitiveVB
4058 * Draws primitives from a vertex buffer to the screen
4060 * Params:
4061 * PrimitiveType: Type of primitive to be rendered.
4062 * D3DVertexBuf: Source Vertex Buffer
4063 * StartVertex: Index of the first vertex from the buffer to be rendered
4064 * NumVertices: Number of vertices to be rendered
4065 * Indices: Array of DWORDs used to index into the Vertices
4066 * IndexCount: Number of indices in Indices
4067 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4069 * Return values
4071 *****************************************************************************/
4072 static HRESULT WINAPI
4073 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(IDirect3DDevice7 *iface,
4074 D3DPRIMITIVETYPE PrimitiveType,
4075 IDirect3DVertexBuffer7 *D3DVertexBuf,
4076 DWORD StartVertex,
4077 DWORD NumVertices,
4078 WORD *Indices,
4079 DWORD IndexCount,
4080 DWORD Flags)
4082 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4083 IDirect3DVertexBufferImpl *vb = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, D3DVertexBuf);
4084 DWORD stride;
4085 UINT PrimitiveCount;
4086 WORD *LockedIndices;
4087 HRESULT hr;
4088 WINED3DVERTEXBUFFER_DESC Desc;
4090 TRACE("(%p)->(%08x,%p,%d,%d,%p,%d,%08x)\n", This, PrimitiveType, vb, StartVertex, NumVertices, Indices, IndexCount, Flags);
4092 /* Steps:
4093 * 1) Calculate some things: Vertex count -> Primitive count, stride, ...
4094 * 2) Upload the Indices to the index buffer
4095 * 3) Set the index source
4096 * 4) Set the Vertex Buffer as the Stream source
4097 * 5) Call IWineD3DDevice::DrawIndexedPrimitive
4100 /* Get the primitive count */
4101 switch(PrimitiveType)
4103 case D3DPT_POINTLIST:
4104 PrimitiveCount = IndexCount;
4105 break;
4107 case D3DPT_LINELIST:
4108 PrimitiveCount = IndexCount / 2;
4109 break;
4111 case D3DPT_LINESTRIP:
4112 PrimitiveCount = IndexCount - 1;
4113 break;
4115 case D3DPT_TRIANGLELIST:
4116 PrimitiveCount = IndexCount / 3;
4117 break;
4119 case D3DPT_TRIANGLESTRIP:
4120 PrimitiveCount = IndexCount - 2;
4121 break;
4123 case D3DPT_TRIANGLEFAN:
4124 PrimitiveCount = IndexCount - 2;
4125 break;
4127 default: return DDERR_INVALIDPARAMS;
4130 EnterCriticalSection(&ddraw_cs);
4131 /* Get the FVF of the vertex buffer, and its stride */
4132 hr = IWineD3DVertexBuffer_GetDesc(vb->wineD3DVertexBuffer,
4133 &Desc);
4134 if(hr != D3D_OK)
4136 ERR("(%p) IWineD3DVertexBuffer::GetDesc failed with hr = %08x\n", This, hr);
4137 LeaveCriticalSection(&ddraw_cs);
4138 return hr;
4140 stride = get_flexible_vertex_size(Desc.FVF);
4141 TRACE("Vertex buffer FVF = %08x, stride=%d\n", Desc.FVF, stride);
4143 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
4144 vb->wineD3DVertexDeclaration);
4145 if(FAILED(hr))
4147 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr);
4148 LeaveCriticalSection(&ddraw_cs);
4149 return hr;
4152 /* copy the index stream into the index buffer.
4153 * A new IWineD3DDevice method could be created
4154 * which takes an user pointer containing the indices
4155 * or a SetData-Method for the index buffer, which
4156 * overrides the index buffer data with our pointer.
4158 hr = IWineD3DIndexBuffer_Lock(This->indexbuffer,
4159 0 /* OffSetToLock */,
4160 IndexCount * sizeof(WORD),
4161 (BYTE **) &LockedIndices,
4162 0 /* Flags */);
4163 assert(IndexCount < 0x100000);
4164 if(hr != D3D_OK)
4166 ERR("(%p) IWineD3DIndexBuffer::Lock failed with hr = %08x\n", This, hr);
4167 LeaveCriticalSection(&ddraw_cs);
4168 return hr;
4170 memcpy(LockedIndices, Indices, IndexCount * sizeof(WORD));
4171 hr = IWineD3DIndexBuffer_Unlock(This->indexbuffer);
4172 if(hr != D3D_OK)
4174 ERR("(%p) IWineD3DIndexBuffer::Unlock failed with hr = %08x\n", This, hr);
4175 LeaveCriticalSection(&ddraw_cs);
4176 return hr;
4179 /* Set the index stream */
4180 IWineD3DDevice_SetBaseVertexIndex(This->wineD3DDevice, StartVertex);
4181 hr = IWineD3DDevice_SetIndices(This->wineD3DDevice, This->indexbuffer);
4183 /* Set the vertex stream source */
4184 hr = IWineD3DDevice_SetStreamSource(This->wineD3DDevice,
4185 0 /* StreamNumber */,
4186 vb->wineD3DVertexBuffer,
4187 0 /* offset, we pass this to DrawIndexedPrimitive */,
4188 stride);
4189 if(hr != D3D_OK)
4191 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This, hr);
4192 LeaveCriticalSection(&ddraw_cs);
4193 return hr;
4197 hr = IWineD3DDevice_DrawIndexedPrimitive(This->wineD3DDevice,
4198 PrimitiveType,
4199 0 /* minIndex */,
4200 NumVertices,
4201 0 /* StartIndex */,
4202 PrimitiveCount);
4204 LeaveCriticalSection(&ddraw_cs);
4205 return hr;
4208 static HRESULT WINAPI
4209 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB(IDirect3DDevice3 *iface,
4210 D3DPRIMITIVETYPE PrimitiveType,
4211 IDirect3DVertexBuffer *D3DVertexBuf,
4212 WORD *Indices,
4213 DWORD IndexCount,
4214 DWORD Flags)
4216 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4217 IDirect3DVertexBufferImpl *VB = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, D3DVertexBuf);
4218 TRACE_(ddraw_thunk)("(%p)->(%08x,%p,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VB, Indices, IndexCount, Flags);
4220 return IDirect3DDevice7_DrawIndexedPrimitiveVB(ICOM_INTERFACE(This, IDirect3DDevice7),
4221 PrimitiveType,
4222 ICOM_INTERFACE(VB, IDirect3DVertexBuffer7),
4224 IndexCount,
4225 Indices,
4226 IndexCount,
4227 Flags);
4230 /*****************************************************************************
4231 * IDirect3DDevice7::ComputeSphereVisibility
4233 * Calculates the visibility of spheres in the current viewport. The spheres
4234 * are passed in the Centers and Radii arrays, the results are passed back
4235 * in the ReturnValues array. Return values are either completely visible,
4236 * partially visible or completely invisible.
4237 * The return value consist of a combination of D3DCLIP_* flags, or it's
4238 * 0 if the sphere is completely visible(according to the SDK, not checked)
4240 * Sounds like an overdose of math ;)
4242 * Version 3 and 7
4244 * Params:
4245 * Centers: Array containing the sphere centers
4246 * Radii: Array containing the sphere radii
4247 * NumSpheres: The number of centers and radii in the arrays
4248 * Flags: Some flags
4249 * ReturnValues: Array to write the results to
4251 * Returns:
4252 * D3D_OK because it's a stub
4253 * (DDERR_INVALIDPARAMS if Centers, Radii or ReturnValues are NULL)
4254 * (D3DERR_INVALIDMATRIX if the combined world, view and proj matrix
4255 * is singular)
4257 *****************************************************************************/
4258 static HRESULT WINAPI
4259 IDirect3DDeviceImpl_7_ComputeSphereVisibility(IDirect3DDevice7 *iface,
4260 D3DVECTOR *Centers,
4261 D3DVALUE *Radii,
4262 DWORD NumSpheres,
4263 DWORD Flags,
4264 DWORD *ReturnValues)
4266 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4267 FIXME("(%p)->(%p,%p,%08x,%08x,%p): stub!\n", This, Centers, Radii, NumSpheres, Flags, ReturnValues);
4269 /* the DirectX 7 sdk says that the visibility is computed by
4270 * back-transforming the viewing frustum to model space
4271 * using the inverse of the combined world, view and projection
4272 * matrix. If the matrix can't be reversed, D3DERR_INVALIDMATRIX
4273 * is returned.
4275 * Basic implementation idea:
4276 * 1) Check if the center is in the viewing frustum
4277 * 2) Cut the sphere with the planes of the viewing
4278 * frustum
4280 * ->Center inside the frustum, no intersections:
4281 * Fully visible
4282 * ->Center outside the frustum, no intersections:
4283 * Not visible
4284 * ->Some intersections: Partially visible
4286 * Implement this call in WineD3D. Either implement the
4287 * matrix and vector stuff in WineD3D, or use some external
4288 * math library.
4291 return D3D_OK;
4294 static HRESULT WINAPI
4295 Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility(IDirect3DDevice3 *iface,
4296 D3DVECTOR *Centers,
4297 D3DVALUE *Radii,
4298 DWORD NumSpheres,
4299 DWORD Flags,
4300 DWORD *ReturnValues)
4302 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4303 TRACE_(ddraw_thunk)("(%p)->(%p,%p,%08x,%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, Centers, Radii, NumSpheres, Flags, ReturnValues);
4304 return IDirect3DDevice7_ComputeSphereVisibility(ICOM_INTERFACE(This, IDirect3DDevice7),
4305 Centers,
4306 Radii,
4307 NumSpheres,
4308 Flags,
4309 ReturnValues);
4312 /*****************************************************************************
4313 * IDirect3DDevice7::GetTexture
4315 * Returns the texture interface handle assigned to a texture stage.
4316 * The returned texture is AddRefed. This is taken from old ddraw,
4317 * not checked in Windows.
4319 * Version 3 and 7
4321 * Params:
4322 * Stage: Texture stage to read the texture from
4323 * Texture: Address to store the interface pointer at
4325 * Returns:
4326 * D3D_OK on success
4327 * DDERR_INVALIDPARAMS if Texture is NULL
4328 * For details, see IWineD3DDevice::GetTexture
4330 *****************************************************************************/
4331 static HRESULT WINAPI
4332 IDirect3DDeviceImpl_7_GetTexture(IDirect3DDevice7 *iface,
4333 DWORD Stage,
4334 IDirectDrawSurface7 **Texture)
4336 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4337 IWineD3DBaseTexture *Surf;
4338 HRESULT hr;
4339 TRACE("(%p)->(%d,%p): Relay\n", This, Stage, Texture);
4341 if(!Texture)
4343 TRACE("Texture == NULL, failing with DDERR_INVALIDPARAMS\n");
4344 return DDERR_INVALIDPARAMS;
4347 EnterCriticalSection(&ddraw_cs);
4348 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice, Stage, &Surf);
4349 if( (hr != D3D_OK) || (!Surf) )
4351 *Texture = NULL;
4352 LeaveCriticalSection(&ddraw_cs);
4353 return hr;
4356 /* GetParent AddRef()s, which is perfectly OK.
4357 * We have passed the IDirectDrawSurface7 interface to WineD3D, so that's OK too.
4359 hr = IWineD3DBaseTexture_GetParent(Surf,
4360 (IUnknown **) Texture);
4361 LeaveCriticalSection(&ddraw_cs);
4362 return hr;
4365 static HRESULT WINAPI
4366 Thunk_IDirect3DDeviceImpl_3_GetTexture(IDirect3DDevice3 *iface,
4367 DWORD Stage,
4368 IDirect3DTexture2 **Texture2)
4370 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4371 HRESULT ret;
4372 IDirectDrawSurface7 *ret_val;
4374 TRACE_(ddraw_thunk)("(%p)->(%d,%p) thunking to IDirect3DDevice7 interface.\n", This, Stage, Texture2);
4375 ret = IDirect3DDevice7_GetTexture(ICOM_INTERFACE(This, IDirect3DDevice7),
4376 Stage,
4377 &ret_val);
4379 *Texture2 = COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7, IDirect3DTexture2, ret_val);
4381 TRACE_(ddraw_thunk)(" returning interface %p.\n", *Texture2);
4383 return ret;
4386 /*****************************************************************************
4387 * IDirect3DDevice7::SetTexture
4389 * Assigns a texture to a texture stage. Is the texture AddRef-ed?
4391 * Version 3 and 7
4393 * Params:
4394 * Stage: The stage to assign the texture to
4395 * Texture: Interface pointer to the texture surface
4397 * Returns
4398 * D3D_OK on success
4399 * For details, see IWineD3DDevice::SetTexture
4401 *****************************************************************************/
4402 static HRESULT WINAPI
4403 IDirect3DDeviceImpl_7_SetTexture(IDirect3DDevice7 *iface,
4404 DWORD Stage,
4405 IDirectDrawSurface7 *Texture)
4407 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4408 IDirectDrawSurfaceImpl *surf = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, Texture);
4409 HRESULT hr;
4410 TRACE("(%p)->(%08x,%p): Relay!\n", This, Stage, surf);
4412 /* Texture may be NULL here */
4413 EnterCriticalSection(&ddraw_cs);
4414 hr = IWineD3DDevice_SetTexture(This->wineD3DDevice,
4415 Stage,
4416 surf ? surf->wineD3DTexture : NULL);
4417 LeaveCriticalSection(&ddraw_cs);
4418 return hr;
4421 static HRESULT WINAPI
4422 IDirect3DDeviceImpl_3_SetTexture(IDirect3DDevice3 *iface,
4423 DWORD Stage,
4424 IDirect3DTexture2 *Texture2)
4426 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4427 IDirectDrawSurfaceImpl *tex = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture2, Texture2);
4428 DWORD texmapblend;
4429 HRESULT hr;
4430 TRACE("(%p)->(%d,%p)\n", This, Stage, tex);
4432 if (This->legacyTextureBlending)
4433 IDirect3DDevice3_GetRenderState(iface, D3DRENDERSTATE_TEXTUREMAPBLEND, &texmapblend);
4435 hr = IDirect3DDevice7_SetTexture(ICOM_INTERFACE(This, IDirect3DDevice7),
4436 Stage,
4437 ICOM_INTERFACE(tex, IDirectDrawSurface7));
4439 if (This->legacyTextureBlending && texmapblend == D3DTBLEND_MODULATE)
4441 /* This fixup is required by the way D3DTBLEND_MODULATE maps to texture stage states.
4442 See IDirect3DDeviceImpl_3_SetRenderState for details. */
4443 BOOL tex_alpha = FALSE;
4444 IWineD3DBaseTexture *tex = NULL;
4445 WINED3DSURFACE_DESC desc;
4446 WINED3DFORMAT fmt;
4447 DDPIXELFORMAT ddfmt;
4448 HRESULT result;
4450 EnterCriticalSection(&ddraw_cs);
4452 result = IWineD3DDevice_GetTexture(This->wineD3DDevice,
4454 &tex);
4456 if(result == WINED3D_OK && tex)
4458 memset(&desc, 0, sizeof(desc));
4459 desc.Format = &fmt;
4460 result = IWineD3DTexture_GetLevelDesc((IWineD3DTexture*) tex, 0, &desc);
4461 if (SUCCEEDED(result))
4463 ddfmt.dwSize = sizeof(ddfmt);
4464 PixelFormat_WineD3DtoDD(&ddfmt, fmt);
4465 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
4468 IWineD3DBaseTexture_Release(tex);
4471 /* alphaop is WINED3DTOP_SELECTARG1 if it's D3DTBLEND_MODULATE, so only modify alphaarg1 */
4472 if (tex_alpha)
4474 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
4476 else
4478 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_CURRENT);
4481 LeaveCriticalSection(&ddraw_cs);
4484 return hr;
4487 /*****************************************************************************
4488 * IDirect3DDevice7::GetTextureStageState
4490 * Retrieves a state from a texture stage.
4492 * Version 3 and 7
4494 * Params:
4495 * Stage: The stage to retrieve the state from
4496 * TexStageStateType: The state type to retrieve
4497 * State: Address to store the state's value at
4499 * Returns:
4500 * D3D_OK on success
4501 * DDERR_INVALIDPARAMS if State is NULL
4502 * For details, see IWineD3DDevice::GetTextureStageState
4504 *****************************************************************************/
4505 static HRESULT WINAPI
4506 IDirect3DDeviceImpl_7_GetTextureStageState(IDirect3DDevice7 *iface,
4507 DWORD Stage,
4508 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4509 DWORD *State)
4511 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4512 HRESULT hr;
4513 TRACE("(%p)->(%08x,%08x,%p): Relay!\n", This, Stage, TexStageStateType, State);
4515 if(!State)
4516 return DDERR_INVALIDPARAMS;
4518 EnterCriticalSection(&ddraw_cs);
4519 switch(TexStageStateType)
4521 /* Mipfilter is a sampler state with different values */
4522 case D3DTSS_MIPFILTER:
4524 WINED3DTEXTUREFILTERTYPE value;
4526 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
4527 Stage,
4528 WINED3DSAMP_MIPFILTER,
4529 &value);
4530 switch(value)
4532 case WINED3DTEXF_NONE: *State = D3DTFP_NONE; break;
4533 case WINED3DTEXF_POINT: *State = D3DTFP_POINT; break;
4534 case WINED3DTEXF_LINEAR: *State = D3DTFP_LINEAR; break;
4535 default:
4536 ERR("Unexpected mipfilter value %d\n", value);
4537 *State = D3DTFP_NONE;
4539 break;
4542 /* Minfilter is a sampler state too, equal values */
4543 case D3DTSS_MINFILTER:
4544 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
4545 Stage,
4546 WINED3DSAMP_MINFILTER,
4547 State);
4548 break;
4550 /* Magfilter has slightly different values */
4551 case D3DTSS_MAGFILTER:
4553 WINED3DTEXTUREFILTERTYPE wined3dfilter;
4554 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
4555 Stage,
4556 WINED3DSAMP_MAGFILTER,
4557 &wined3dfilter);
4558 switch(wined3dfilter)
4560 case WINED3DTEXF_POINT: *State = D3DTFG_POINT; break;
4561 case WINED3DTEXF_LINEAR: *State = D3DTFG_LINEAR; break;
4562 case WINED3DTEXF_ANISOTROPIC: *State = D3DTFG_ANISOTROPIC; break;
4563 case WINED3DTEXF_FLATCUBIC: *State = D3DTFG_FLATCUBIC; break;
4564 case WINED3DTEXF_GAUSSIANCUBIC: *State = D3DTFG_GAUSSIANCUBIC; break;
4565 default:
4566 ERR("Unexpected wined3d mag filter value %d\n", wined3dfilter);
4567 *State = D3DTFG_POINT;
4569 break;
4572 case D3DTSS_ADDRESS:
4573 case D3DTSS_ADDRESSU:
4574 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
4575 Stage,
4576 WINED3DSAMP_ADDRESSU,
4577 State);
4578 break;
4579 case D3DTSS_ADDRESSV:
4580 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
4581 Stage,
4582 WINED3DSAMP_ADDRESSV,
4583 State);
4584 break;
4585 default:
4586 hr = IWineD3DDevice_GetTextureStageState(This->wineD3DDevice,
4587 Stage,
4588 TexStageStateType,
4589 State);
4590 break;
4592 LeaveCriticalSection(&ddraw_cs);
4593 return hr;
4596 static HRESULT WINAPI
4597 Thunk_IDirect3DDeviceImpl_3_GetTextureStageState(IDirect3DDevice3 *iface,
4598 DWORD Stage,
4599 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4600 DWORD *State)
4602 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4603 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, Stage, TexStageStateType, State);
4604 return IDirect3DDevice7_GetTextureStageState(ICOM_INTERFACE(This, IDirect3DDevice7),
4605 Stage,
4606 TexStageStateType,
4607 State);
4610 /*****************************************************************************
4611 * IDirect3DDevice7::SetTextureStageState
4613 * Sets a texture stage state. Some stage types need to be handled specially,
4614 * because they do not exist in WineD3D and were moved to another place
4616 * Version 3 and 7
4618 * Params:
4619 * Stage: The stage to modify
4620 * TexStageStateType: The state to change
4621 * State: The new value for the state
4623 * Returns:
4624 * D3D_OK on success
4625 * For details, see IWineD3DDevice::SetTextureStageState
4627 *****************************************************************************/
4628 static HRESULT WINAPI
4629 IDirect3DDeviceImpl_7_SetTextureStageState(IDirect3DDevice7 *iface,
4630 DWORD Stage,
4631 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4632 DWORD State)
4634 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4635 HRESULT hr;
4636 TRACE("(%p)->(%08x,%08x,%08x): Relay!\n", This, Stage, TexStageStateType, State);
4638 EnterCriticalSection(&ddraw_cs);
4639 switch(TexStageStateType)
4641 /* Mipfilter is a sampler state with different values */
4642 case D3DTSS_MIPFILTER:
4644 WINED3DTEXTUREFILTERTYPE value;
4645 switch(State)
4647 case D3DTFP_NONE: value = WINED3DTEXF_NONE; break;
4648 case D3DTFP_POINT: value = WINED3DTEXF_POINT; break;
4649 case 0: /* Unchecked */
4650 case D3DTFP_LINEAR: value = WINED3DTEXF_LINEAR; break;
4651 default:
4652 ERR("Unexpected mipfilter value %d\n", State);
4653 value = WINED3DTEXF_NONE;
4655 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
4656 Stage,
4657 WINED3DSAMP_MIPFILTER,
4658 value);
4659 break;
4662 /* Minfilter is a sampler state too, equal values */
4663 case D3DTSS_MINFILTER:
4664 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
4665 Stage,
4666 WINED3DSAMP_MINFILTER,
4667 State);
4668 break;
4670 /* Magfilter has slightly different values */
4671 case D3DTSS_MAGFILTER:
4673 WINED3DTEXTUREFILTERTYPE wined3dfilter;
4674 switch((D3DTEXTUREMAGFILTER) State)
4676 case D3DTFG_POINT: wined3dfilter = WINED3DTEXF_POINT; break;
4677 case D3DTFG_LINEAR: wined3dfilter = WINED3DTEXF_LINEAR; break;
4678 case D3DTFG_FLATCUBIC: wined3dfilter = WINED3DTEXF_FLATCUBIC; break;
4679 case D3DTFG_GAUSSIANCUBIC: wined3dfilter = WINED3DTEXF_GAUSSIANCUBIC; break;
4680 case D3DTFG_ANISOTROPIC: wined3dfilter = WINED3DTEXF_ANISOTROPIC; break;
4681 default:
4682 ERR("Unexpected d3d7 mag filter type %d\n", State);
4683 wined3dfilter = WINED3DTEXF_POINT;
4685 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
4686 Stage,
4687 WINED3DSAMP_MAGFILTER,
4688 wined3dfilter);
4689 break;
4692 case D3DTSS_ADDRESS:
4693 IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
4694 Stage,
4695 WINED3DSAMP_ADDRESSV,
4696 State);
4697 /* Drop through */
4698 case D3DTSS_ADDRESSU:
4699 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
4700 Stage,
4701 WINED3DSAMP_ADDRESSU,
4702 State);
4703 break;
4705 case D3DTSS_ADDRESSV:
4706 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
4707 Stage,
4708 WINED3DSAMP_ADDRESSV,
4709 State);
4710 break;
4712 default:
4713 hr = IWineD3DDevice_SetTextureStageState(This->wineD3DDevice,
4714 Stage,
4715 TexStageStateType,
4716 State);
4717 break;
4719 LeaveCriticalSection(&ddraw_cs);
4720 return hr;
4723 static HRESULT WINAPI
4724 Thunk_IDirect3DDeviceImpl_3_SetTextureStageState(IDirect3DDevice3 *iface,
4725 DWORD Stage,
4726 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4727 DWORD State)
4729 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4730 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, Stage, TexStageStateType, State);
4731 return IDirect3DDevice7_SetTextureStageState(ICOM_INTERFACE(This, IDirect3DDevice7),
4732 Stage,
4733 TexStageStateType,
4734 State);
4737 /*****************************************************************************
4738 * IDirect3DDevice7::ValidateDevice
4740 * SDK: "Reports the device's ability to render the currently set
4741 * texture-blending operations in a single pass". Whatever that means
4742 * exactly...
4744 * Version 3 and 7
4746 * Params:
4747 * NumPasses: Address to write the number of necessary passes for the
4748 * desired effect to.
4750 * Returns:
4751 * D3D_OK on success
4752 * See IWineD3DDevice::ValidateDevice for more details
4754 *****************************************************************************/
4755 static HRESULT WINAPI
4756 IDirect3DDeviceImpl_7_ValidateDevice(IDirect3DDevice7 *iface,
4757 DWORD *NumPasses)
4759 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4760 HRESULT hr;
4761 TRACE("(%p)->(%p): Relay\n", This, NumPasses);
4763 EnterCriticalSection(&ddraw_cs);
4764 hr = IWineD3DDevice_ValidateDevice(This->wineD3DDevice, NumPasses);
4765 LeaveCriticalSection(&ddraw_cs);
4766 return hr;
4769 static HRESULT WINAPI
4770 Thunk_IDirect3DDeviceImpl_3_ValidateDevice(IDirect3DDevice3 *iface,
4771 DWORD *Passes)
4773 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4774 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Passes);
4775 return IDirect3DDevice7_ValidateDevice(ICOM_INTERFACE(This, IDirect3DDevice7),
4776 Passes);
4779 /*****************************************************************************
4780 * IDirect3DDevice7::Clear
4782 * Fills the render target, the z buffer and the stencil buffer with a
4783 * clear color / value
4785 * Version 7 only
4787 * Params:
4788 * Count: Number of rectangles in Rects must be 0 if Rects is NULL
4789 * Rects: Rectangles to clear. If NULL, the whole surface is cleared
4790 * Flags: Some flags, as usual
4791 * Color: Clear color for the render target
4792 * Z: Clear value for the Z buffer
4793 * Stencil: Clear value to store in each stencil buffer entry
4795 * Returns:
4796 * D3D_OK on success
4797 * For details, see IWineD3DDevice::Clear
4799 *****************************************************************************/
4800 static HRESULT WINAPI
4801 IDirect3DDeviceImpl_7_Clear(IDirect3DDevice7 *iface,
4802 DWORD Count,
4803 D3DRECT *Rects,
4804 DWORD Flags,
4805 D3DCOLOR Color,
4806 D3DVALUE Z,
4807 DWORD Stencil)
4809 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4810 HRESULT hr;
4811 TRACE("(%p)->(%08x,%p,%08x,%08x,%f,%08x): Relay\n", This, Count, Rects, Flags, Color, Z, Stencil);
4813 /* Note; D3DRECT is compatible with WINED3DRECT */
4814 EnterCriticalSection(&ddraw_cs);
4815 hr = IWineD3DDevice_Clear(This->wineD3DDevice, Count, (WINED3DRECT*) Rects, Flags, Color, Z, Stencil);
4816 LeaveCriticalSection(&ddraw_cs);
4817 return hr;
4820 /*****************************************************************************
4821 * IDirect3DDevice7::SetViewport
4823 * Sets the current viewport.
4825 * Version 7 only, but IDirect3DViewport uses this call for older
4826 * versions
4828 * Params:
4829 * Data: The new viewport to set
4831 * Returns:
4832 * D3D_OK on success
4833 * DDERR_INVALIDPARAMS if Data is NULL
4834 * For more details, see IWineDDDevice::SetViewport
4836 *****************************************************************************/
4837 static HRESULT WINAPI
4838 IDirect3DDeviceImpl_7_SetViewport(IDirect3DDevice7 *iface,
4839 D3DVIEWPORT7 *Data)
4841 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4842 HRESULT hr;
4843 TRACE("(%p)->(%p) Relay!\n", This, Data);
4845 if(!Data)
4846 return DDERR_INVALIDPARAMS;
4848 /* Note: D3DVIEWPORT7 is compatible with WINED3DVIEWPORT */
4849 EnterCriticalSection(&ddraw_cs);
4850 hr = IWineD3DDevice_SetViewport(This->wineD3DDevice,
4851 (WINED3DVIEWPORT*) Data);
4852 LeaveCriticalSection(&ddraw_cs);
4853 return hr;
4856 /*****************************************************************************
4857 * IDirect3DDevice::GetViewport
4859 * Returns the current viewport
4861 * Version 7
4863 * Params:
4864 * Data: D3D7Viewport structure to write the viewport information to
4866 * Returns:
4867 * D3D_OK on success
4868 * DDERR_INVALIDPARAMS if Data is NULL
4869 * For more details, see IWineD3DDevice::GetViewport
4871 *****************************************************************************/
4872 static HRESULT WINAPI
4873 IDirect3DDeviceImpl_7_GetViewport(IDirect3DDevice7 *iface,
4874 D3DVIEWPORT7 *Data)
4876 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4877 HRESULT hr;
4878 TRACE("(%p)->(%p) Relay!\n", This, Data);
4880 if(!Data)
4881 return DDERR_INVALIDPARAMS;
4883 /* Note: D3DVIEWPORT7 is compatible with WINED3DVIEWPORT */
4884 EnterCriticalSection(&ddraw_cs);
4885 hr = IWineD3DDevice_GetViewport(This->wineD3DDevice,
4886 (WINED3DVIEWPORT*) Data);
4888 LeaveCriticalSection(&ddraw_cs);
4889 return hr_ddraw_from_wined3d(hr);
4892 /*****************************************************************************
4893 * IDirect3DDevice7::SetMaterial
4895 * Sets the Material
4897 * Version 7
4899 * Params:
4900 * Mat: The material to set
4902 * Returns:
4903 * D3D_OK on success
4904 * DDERR_INVALIDPARAMS if Mat is NULL.
4905 * For more details, see IWineD3DDevice::SetMaterial
4907 *****************************************************************************/
4908 static HRESULT WINAPI
4909 IDirect3DDeviceImpl_7_SetMaterial(IDirect3DDevice7 *iface,
4910 D3DMATERIAL7 *Mat)
4912 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4913 HRESULT hr;
4914 TRACE("(%p)->(%p): Relay!\n", This, Mat);
4916 /* Note: D3DMATERIAL7 is compatible with WINED3DMATERIAL */
4917 EnterCriticalSection(&ddraw_cs);
4918 hr = IWineD3DDevice_SetMaterial(This->wineD3DDevice,
4919 (WINED3DMATERIAL*) Mat);
4920 LeaveCriticalSection(&ddraw_cs);
4921 return hr_ddraw_from_wined3d(hr);
4924 /*****************************************************************************
4925 * IDirect3DDevice7::GetMaterial
4927 * Returns the current material
4929 * Version 7
4931 * Params:
4932 * Mat: D3DMATERIAL7 structure to write the material parameters to
4934 * Returns:
4935 * D3D_OK on success
4936 * DDERR_INVALIDPARAMS if Mat is NULL
4937 * For more details, see IWineD3DDevice::GetMaterial
4939 *****************************************************************************/
4940 static HRESULT WINAPI
4941 IDirect3DDeviceImpl_7_GetMaterial(IDirect3DDevice7 *iface,
4942 D3DMATERIAL7 *Mat)
4944 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4945 HRESULT hr;
4946 TRACE("(%p)->(%p): Relay!\n", This, Mat);
4948 EnterCriticalSection(&ddraw_cs);
4949 /* Note: D3DMATERIAL7 is compatible with WINED3DMATERIAL */
4950 hr = IWineD3DDevice_GetMaterial(This->wineD3DDevice,
4951 (WINED3DMATERIAL*) Mat);
4952 LeaveCriticalSection(&ddraw_cs);
4953 return hr_ddraw_from_wined3d(hr);
4956 /*****************************************************************************
4957 * IDirect3DDevice7::SetLight
4959 * Assigns a light to a light index, but doesn't activate it yet.
4961 * Version 7, IDirect3DLight uses this method for older versions
4963 * Params:
4964 * LightIndex: The index of the new light
4965 * Light: A D3DLIGHT7 structure describing the light
4967 * Returns:
4968 * D3D_OK on success
4969 * For more details, see IWineD3DDevice::SetLight
4971 *****************************************************************************/
4972 static HRESULT WINAPI
4973 IDirect3DDeviceImpl_7_SetLight(IDirect3DDevice7 *iface,
4974 DWORD LightIndex,
4975 D3DLIGHT7 *Light)
4977 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4978 HRESULT hr;
4979 TRACE("(%p)->(%08x,%p): Relay!\n", This, LightIndex, Light);
4981 EnterCriticalSection(&ddraw_cs);
4982 /* Note: D3DLIGHT7 is compatible with WINED3DLIGHT */
4983 hr = IWineD3DDevice_SetLight(This->wineD3DDevice,
4984 LightIndex,
4985 (WINED3DLIGHT*) Light);
4986 LeaveCriticalSection(&ddraw_cs);
4987 return hr_ddraw_from_wined3d(hr);
4990 /*****************************************************************************
4991 * IDirect3DDevice7::GetLight
4993 * Returns the light assigned to a light index
4995 * Params:
4996 * Light: Structure to write the light information to
4998 * Returns:
4999 * D3D_OK on success
5000 * DDERR_INVALIDPARAMS if Light is NULL
5001 * For details, see IWineD3DDevice::GetLight
5003 *****************************************************************************/
5004 static HRESULT WINAPI
5005 IDirect3DDeviceImpl_7_GetLight(IDirect3DDevice7 *iface,
5006 DWORD LightIndex,
5007 D3DLIGHT7 *Light)
5009 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5010 HRESULT rc;
5011 TRACE("(%p)->(%08x,%p): Relay!\n", This, LightIndex, Light);
5013 EnterCriticalSection(&ddraw_cs);
5014 /* Note: D3DLIGHT7 is compatible with WINED3DLIGHT */
5015 rc = IWineD3DDevice_GetLight(This->wineD3DDevice,
5016 LightIndex,
5017 (WINED3DLIGHT*) Light);
5019 /* Translate the result. WineD3D returns other values than D3D7 */
5020 LeaveCriticalSection(&ddraw_cs);
5021 return hr_ddraw_from_wined3d(rc);
5024 /*****************************************************************************
5025 * IDirect3DDevice7::BeginStateBlock
5027 * Begins recording to a stateblock
5029 * Version 7
5031 * Returns:
5032 * D3D_OK on success
5033 * For details see IWineD3DDevice::BeginStateBlock
5035 *****************************************************************************/
5036 static HRESULT WINAPI
5037 IDirect3DDeviceImpl_7_BeginStateBlock(IDirect3DDevice7 *iface)
5039 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5040 HRESULT hr;
5041 TRACE("(%p)->(): Relay!\n", This);
5043 EnterCriticalSection(&ddraw_cs);
5044 hr = IWineD3DDevice_BeginStateBlock(This->wineD3DDevice);
5045 LeaveCriticalSection(&ddraw_cs);
5046 return hr_ddraw_from_wined3d(hr);
5049 /*****************************************************************************
5050 * IDirect3DDevice7::EndStateBlock
5052 * Stops recording to a state block and returns the created stateblock
5053 * handle.
5055 * Version 7
5057 * Params:
5058 * BlockHandle: Address to store the stateblock's handle to
5060 * Returns:
5061 * D3D_OK on success
5062 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5063 * See IWineD3DDevice::EndStateBlock for more details
5065 *****************************************************************************/
5066 static HRESULT WINAPI
5067 IDirect3DDeviceImpl_7_EndStateBlock(IDirect3DDevice7 *iface,
5068 DWORD *BlockHandle)
5070 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5071 HRESULT hr;
5072 TRACE("(%p)->(%p): Relay!\n", This, BlockHandle);
5074 if(!BlockHandle)
5076 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
5077 return DDERR_INVALIDPARAMS;
5080 EnterCriticalSection(&ddraw_cs);
5081 *BlockHandle = IDirect3DDeviceImpl_CreateHandle(This);
5082 if(!*BlockHandle)
5084 ERR("Cannot get a handle number for the stateblock\n");
5085 LeaveCriticalSection(&ddraw_cs);
5086 return DDERR_OUTOFMEMORY;
5088 This->Handles[*BlockHandle - 1].type = DDrawHandle_StateBlock;
5089 hr = IWineD3DDevice_EndStateBlock(This->wineD3DDevice,
5090 (IWineD3DStateBlock **) &This->Handles[*BlockHandle - 1].ptr);
5091 LeaveCriticalSection(&ddraw_cs);
5092 return hr_ddraw_from_wined3d(hr);
5095 /*****************************************************************************
5096 * IDirect3DDevice7::PreLoad
5098 * Allows the app to signal that a texture will be used soon, to allow
5099 * the Direct3DDevice to load it to the video card in the meantime.
5101 * Version 7
5103 * Params:
5104 * Texture: The texture to preload
5106 * Returns:
5107 * D3D_OK on success
5108 * DDERR_INVALIDPARAMS if Texture is NULL
5109 * See IWineD3DSurface::PreLoad for details
5111 *****************************************************************************/
5112 static HRESULT WINAPI
5113 IDirect3DDeviceImpl_7_PreLoad(IDirect3DDevice7 *iface,
5114 IDirectDrawSurface7 *Texture)
5116 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5117 IDirectDrawSurfaceImpl *surf = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, Texture);
5119 TRACE("(%p)->(%p): Relay!\n", This, surf);
5121 if(!Texture)
5122 return DDERR_INVALIDPARAMS;
5124 EnterCriticalSection(&ddraw_cs);
5125 IWineD3DSurface_PreLoad(surf->WineD3DSurface);
5126 LeaveCriticalSection(&ddraw_cs);
5127 return D3D_OK;
5130 /*****************************************************************************
5131 * IDirect3DDevice7::ApplyStateBlock
5133 * Activates the state stored in a state block handle.
5135 * Params:
5136 * BlockHandle: The stateblock handle to activate
5138 * Returns:
5139 * D3D_OK on success
5140 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5142 *****************************************************************************/
5143 static HRESULT WINAPI
5144 IDirect3DDeviceImpl_7_ApplyStateBlock(IDirect3DDevice7 *iface,
5145 DWORD BlockHandle)
5147 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5148 HRESULT hr;
5149 TRACE("(%p)->(%08x): Relay!\n", This, BlockHandle);
5151 EnterCriticalSection(&ddraw_cs);
5152 if(!BlockHandle || BlockHandle > This->numHandles)
5154 WARN("Out of range handle %d, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5155 LeaveCriticalSection(&ddraw_cs);
5156 return D3DERR_INVALIDSTATEBLOCK;
5158 if(This->Handles[BlockHandle - 1].type != DDrawHandle_StateBlock)
5160 WARN("Handle %d is not a stateblock, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5161 LeaveCriticalSection(&ddraw_cs);
5162 return D3DERR_INVALIDSTATEBLOCK;
5165 hr = IWineD3DStateBlock_Apply((IWineD3DStateBlock *) This->Handles[BlockHandle - 1].ptr);
5166 LeaveCriticalSection(&ddraw_cs);
5167 return hr_ddraw_from_wined3d(hr);
5170 /*****************************************************************************
5171 * IDirect3DDevice7::CaptureStateBlock
5173 * Updates a stateblock's values to the values currently set for the device
5175 * Version 7
5177 * Params:
5178 * BlockHandle: Stateblock to update
5180 * Returns:
5181 * D3D_OK on success
5182 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5183 * See IWineD3DDevice::CaptureStateBlock for more details
5185 *****************************************************************************/
5186 static HRESULT WINAPI
5187 IDirect3DDeviceImpl_7_CaptureStateBlock(IDirect3DDevice7 *iface,
5188 DWORD BlockHandle)
5190 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5191 HRESULT hr;
5192 TRACE("(%p)->(%08x): Relay!\n", This, BlockHandle);
5194 EnterCriticalSection(&ddraw_cs);
5195 if(BlockHandle == 0 || BlockHandle > This->numHandles)
5197 WARN("Out of range handle %d, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5198 LeaveCriticalSection(&ddraw_cs);
5199 return D3DERR_INVALIDSTATEBLOCK;
5201 if(This->Handles[BlockHandle - 1].type != DDrawHandle_StateBlock)
5203 WARN("Handle %d is not a stateblock, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5204 LeaveCriticalSection(&ddraw_cs);
5205 return D3DERR_INVALIDSTATEBLOCK;
5208 hr = IWineD3DStateBlock_Capture((IWineD3DStateBlock *) This->Handles[BlockHandle - 1].ptr);
5209 LeaveCriticalSection(&ddraw_cs);
5210 return hr_ddraw_from_wined3d(hr);
5213 /*****************************************************************************
5214 * IDirect3DDevice7::DeleteStateBlock
5216 * Deletes a stateblock handle. This means releasing the WineD3DStateBlock
5218 * Version 7
5220 * Params:
5221 * BlockHandle: Stateblock handle to delete
5223 * Returns:
5224 * D3D_OK on success
5225 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is 0
5227 *****************************************************************************/
5228 static HRESULT WINAPI
5229 IDirect3DDeviceImpl_7_DeleteStateBlock(IDirect3DDevice7 *iface,
5230 DWORD BlockHandle)
5232 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5233 ULONG ref;
5234 TRACE("(%p)->(%08x): Relay!\n", This, BlockHandle);
5236 EnterCriticalSection(&ddraw_cs);
5237 if(BlockHandle == 0 || BlockHandle > This->numHandles)
5239 WARN("Out of range handle %d, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5240 LeaveCriticalSection(&ddraw_cs);
5241 return D3DERR_INVALIDSTATEBLOCK;
5243 if(This->Handles[BlockHandle - 1].type != DDrawHandle_StateBlock)
5245 WARN("Handle %d is not a stateblock, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5246 LeaveCriticalSection(&ddraw_cs);
5247 return D3DERR_INVALIDSTATEBLOCK;
5250 ref = IWineD3DStateBlock_Release((IWineD3DStateBlock *) This->Handles[BlockHandle - 1].ptr);
5251 if(ref)
5253 ERR("Something is still holding the stateblock %p(Handle %d). Ref = %d\n", This->Handles[BlockHandle - 1].ptr, BlockHandle, ref);
5255 This->Handles[BlockHandle - 1].ptr = NULL;
5256 This->Handles[BlockHandle - 1].type = DDrawHandle_Unknown;
5258 LeaveCriticalSection(&ddraw_cs);
5259 return D3D_OK;
5262 /*****************************************************************************
5263 * IDirect3DDevice7::CreateStateBlock
5265 * Creates a new state block handle.
5267 * Version 7
5269 * Params:
5270 * Type: The state block type
5271 * BlockHandle: Address to write the created handle to
5273 * Returns:
5274 * D3D_OK on success
5275 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5277 *****************************************************************************/
5278 static HRESULT WINAPI
5279 IDirect3DDeviceImpl_7_CreateStateBlock(IDirect3DDevice7 *iface,
5280 D3DSTATEBLOCKTYPE Type,
5281 DWORD *BlockHandle)
5283 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5284 HRESULT hr;
5285 TRACE("(%p)->(%08x,%p)!\n", This, Type, BlockHandle);
5287 if(!BlockHandle)
5289 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
5290 return DDERR_INVALIDPARAMS;
5292 if(Type != D3DSBT_ALL && Type != D3DSBT_PIXELSTATE &&
5293 Type != D3DSBT_VERTEXSTATE ) {
5294 WARN("Unexpected stateblock type, returning DDERR_INVALIDPARAMS\n");
5295 return DDERR_INVALIDPARAMS;
5298 EnterCriticalSection(&ddraw_cs);
5299 *BlockHandle = IDirect3DDeviceImpl_CreateHandle(This);
5300 if(!*BlockHandle)
5302 ERR("Cannot get a handle number for the stateblock\n");
5303 LeaveCriticalSection(&ddraw_cs);
5304 return DDERR_OUTOFMEMORY;
5306 This->Handles[*BlockHandle - 1].type = DDrawHandle_StateBlock;
5308 /* The D3DSTATEBLOCKTYPE enum is fine here */
5309 hr = IWineD3DDevice_CreateStateBlock(This->wineD3DDevice,
5310 Type,
5311 (IWineD3DStateBlock **) &This->Handles[*BlockHandle - 1].ptr,
5312 NULL /* Parent, hope that works */);
5313 LeaveCriticalSection(&ddraw_cs);
5314 return hr_ddraw_from_wined3d(hr);
5317 /* Helper function for IDirect3DDeviceImpl_7_Load. */
5318 static BOOL is_mip_level_subset(IDirectDrawSurfaceImpl *dest,
5319 IDirectDrawSurfaceImpl *src)
5321 IDirectDrawSurfaceImpl *src_level, *dest_level;
5322 IDirectDrawSurface7 *temp;
5323 DDSURFACEDESC2 ddsd;
5324 BOOL levelFound; /* at least one suitable sublevel in dest found */
5326 /* To satisfy "destination is mip level subset of source" criteria (regular texture counts as 1 level),
5327 * 1) there must be at least one mip level in destination that matched dimensions of some mip level in source and
5328 * 2) there must be no destination levels that don't match any levels in source. Otherwise it's INVALIDPARAMS.
5330 levelFound = FALSE;
5332 src_level = src;
5333 dest_level = dest;
5335 for (;src_level && dest_level;)
5337 if (src_level->surface_desc.dwWidth == dest_level->surface_desc.dwWidth &&
5338 src_level->surface_desc.dwHeight == dest_level->surface_desc.dwHeight)
5340 levelFound = TRUE;
5342 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
5343 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
5344 IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(dest_level, IDirectDrawSurface7), &ddsd.ddsCaps, &temp);
5346 if (dest_level != dest) IDirectDrawSurface7_Release(ICOM_INTERFACE(dest_level, IDirectDrawSurface7));
5348 dest_level = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, temp);
5351 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
5352 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
5353 IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(src_level, IDirectDrawSurface7), &ddsd.ddsCaps, &temp);
5355 if (src_level != src) IDirectDrawSurface7_Release(ICOM_INTERFACE(src_level, IDirectDrawSurface7));
5357 src_level = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, temp);
5360 if (src_level && src_level != src) IDirectDrawSurface7_Release(ICOM_INTERFACE(src_level, IDirectDrawSurface7));
5361 if (dest_level && dest_level != dest) IDirectDrawSurface7_Release(ICOM_INTERFACE(dest_level, IDirectDrawSurface7));
5363 return !dest_level && levelFound;
5366 /* Helper function for IDirect3DDeviceImpl_7_Load. */
5367 static void copy_mipmap_chain(IDirect3DDeviceImpl *device,
5368 IDirectDrawSurfaceImpl *dest,
5369 IDirectDrawSurfaceImpl *src,
5370 POINT *DestPoint,
5371 RECT *SrcRect)
5373 IDirectDrawSurfaceImpl *src_level, *dest_level;
5374 IDirectDrawSurface7 *temp;
5375 DDSURFACEDESC2 ddsd;
5376 POINT point;
5377 RECT rect;
5378 HRESULT hr;
5379 IDirectDrawPalette *pal = NULL, *pal_src = NULL;
5380 DWORD ckeyflag;
5381 DDCOLORKEY ddckey;
5383 src_level = src;
5384 dest_level = dest;
5386 point = *DestPoint;
5387 rect = *SrcRect;
5389 for (;src_level && dest_level;)
5391 if (src_level->surface_desc.dwWidth == dest_level->surface_desc.dwWidth &&
5392 src_level->surface_desc.dwHeight == dest_level->surface_desc.dwHeight)
5394 /* Try UpdateSurface that may perform a more direct opengl loading. */
5395 hr = IWineD3DDevice_UpdateSurface(device->wineD3DDevice, src_level->WineD3DSurface, &rect, dest_level->WineD3DSurface,
5396 &point);
5397 if (FAILED(hr))
5399 /* UpdateSurface may fail e.g. if dest is in system memory. Fall back to BltFast that is less strict. */
5400 IWineD3DSurface_BltFast(dest_level->WineD3DSurface,
5401 point.x, point.y,
5402 src_level->WineD3DSurface, &rect, 0);
5405 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
5406 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
5407 IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(dest_level, IDirectDrawSurface7), &ddsd.ddsCaps, &temp);
5409 if (dest_level != dest) IDirectDrawSurface7_Release(ICOM_INTERFACE(dest_level, IDirectDrawSurface7));
5411 dest_level = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, temp);
5414 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
5415 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
5416 IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(src_level, IDirectDrawSurface7), &ddsd.ddsCaps, &temp);
5418 if (src_level != src) IDirectDrawSurface7_Release(ICOM_INTERFACE(src_level, IDirectDrawSurface7));
5420 src_level = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, temp);
5422 point.x /= 2;
5423 point.y /= 2;
5425 rect.top /= 2;
5426 rect.left /= 2;
5427 rect.right = (rect.right + 1) / 2;
5428 rect.bottom = (rect.bottom + 1) / 2;
5431 if (src_level && src_level != src) IDirectDrawSurface7_Release(ICOM_INTERFACE(src_level, IDirectDrawSurface7));
5432 if (dest_level && dest_level != dest) IDirectDrawSurface7_Release(ICOM_INTERFACE(dest_level, IDirectDrawSurface7));
5434 /* Copy palette, if possible. */
5435 IDirectDrawSurface7_GetPalette(ICOM_INTERFACE(src, IDirectDrawSurface7), &pal_src);
5436 IDirectDrawSurface7_GetPalette(ICOM_INTERFACE(dest, IDirectDrawSurface7), &pal);
5438 if (pal_src != NULL && pal != NULL)
5440 PALETTEENTRY palent[256];
5442 IDirectDrawPalette_GetEntries(pal_src, 0, 0, 256, palent);
5443 IDirectDrawPalette_SetEntries(pal, 0, 0, 256, palent);
5446 if (pal) IDirectDrawPalette_Release(pal);
5447 if (pal_src) IDirectDrawPalette_Release(pal_src);
5449 /* Copy colorkeys, if present. */
5450 for (ckeyflag = DDCKEY_DESTBLT; ckeyflag <= DDCKEY_SRCOVERLAY; ckeyflag <<= 1)
5452 hr = IDirectDrawSurface7_GetColorKey(ICOM_INTERFACE(src, IDirectDrawSurface7), ckeyflag, &ddckey);
5454 if (SUCCEEDED(hr))
5456 IDirectDrawSurface7_SetColorKey(ICOM_INTERFACE(dest, IDirectDrawSurface7), ckeyflag, &ddckey);
5461 /*****************************************************************************
5462 * IDirect3DDevice7::Load
5464 * Loads a rectangular area from the source into the destination texture.
5465 * It can also copy the source to the faces of a cubic environment map
5467 * Version 7
5469 * Params:
5470 * DestTex: Destination texture
5471 * DestPoint: Point in the destination where the source image should be
5472 * written to
5473 * SrcTex: Source texture
5474 * SrcRect: Source rectangle
5475 * Flags: Cubemap faces to load (DDSCAPS2_CUBEMAP_ALLFACES, DDSCAPS2_CUBEMAP_POSITIVEX,
5476 * DDSCAPS2_CUBEMAP_NEGATIVEX, DDSCAPS2_CUBEMAP_POSITIVEY, DDSCAPS2_CUBEMAP_NEGATIVEY,
5477 * DDSCAPS2_CUBEMAP_POSITIVEZ, DDSCAPS2_CUBEMAP_NEGATIVEZ)
5479 * Returns:
5480 * D3D_OK on success
5481 * DDERR_INVALIDPARAMS if DestTex or SrcTex are NULL, broken coordinates or anything unexpected.
5484 *****************************************************************************/
5486 static HRESULT WINAPI
5487 IDirect3DDeviceImpl_7_Load(IDirect3DDevice7 *iface,
5488 IDirectDrawSurface7 *DestTex,
5489 POINT *DestPoint,
5490 IDirectDrawSurface7 *SrcTex,
5491 RECT *SrcRect,
5492 DWORD Flags)
5494 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5495 IDirectDrawSurfaceImpl *dest = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, DestTex);
5496 IDirectDrawSurfaceImpl *src = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, SrcTex);
5497 POINT destpoint;
5498 RECT srcrect;
5499 TRACE("(%p)->(%p,%p,%p,%p,%08x)\n", This, dest, DestPoint, src, SrcRect, Flags);
5501 if( (!src) || (!dest) )
5502 return DDERR_INVALIDPARAMS;
5504 EnterCriticalSection(&ddraw_cs);
5506 if (SrcRect) srcrect = *SrcRect;
5507 else
5509 srcrect.left = srcrect.top = 0;
5510 srcrect.right = src->surface_desc.dwWidth;
5511 srcrect.bottom = src->surface_desc.dwHeight;
5514 if (DestPoint) destpoint = *DestPoint;
5515 else
5517 destpoint.x = destpoint.y = 0;
5519 /* Check bad dimensions. DestPoint is validated against src, not dest, because
5520 * destination can be a subset of mip levels, in which case actual coordinates used
5521 * for it may be divided. If any dimension of dest is larger than source, it can't be
5522 * mip level subset, so an error can be returned early.
5524 if (srcrect.left >= srcrect.right || srcrect.top >= srcrect.bottom ||
5525 srcrect.right > src->surface_desc.dwWidth ||
5526 srcrect.bottom > src->surface_desc.dwHeight ||
5527 destpoint.x + srcrect.right - srcrect.left > src->surface_desc.dwWidth ||
5528 destpoint.y + srcrect.bottom - srcrect.top > src->surface_desc.dwHeight ||
5529 dest->surface_desc.dwWidth > src->surface_desc.dwWidth ||
5530 dest->surface_desc.dwHeight > src->surface_desc.dwHeight)
5532 LeaveCriticalSection(&ddraw_cs);
5533 return DDERR_INVALIDPARAMS;
5536 /* Must be top level surfaces. */
5537 if (src->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_MIPMAPSUBLEVEL ||
5538 dest->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_MIPMAPSUBLEVEL)
5540 LeaveCriticalSection(&ddraw_cs);
5541 return DDERR_INVALIDPARAMS;
5544 if (src->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP)
5546 DWORD src_face_flag, dest_face_flag;
5547 IDirectDrawSurfaceImpl *src_face, *dest_face;
5548 IDirectDrawSurface7 *temp;
5549 DDSURFACEDESC2 ddsd;
5550 int i;
5552 if (!(dest->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP))
5554 LeaveCriticalSection(&ddraw_cs);
5555 return DDERR_INVALIDPARAMS;
5558 /* Iterate through cube faces 2 times. First time is just to check INVALIDPARAMS conditions, second
5559 * time it's actual surface loading. */
5560 for (i = 0; i < 2; i++)
5562 dest_face = dest;
5563 src_face = src;
5565 for (;dest_face && src_face;)
5567 src_face_flag = src_face->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP_ALLFACES;
5568 dest_face_flag = dest_face->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP_ALLFACES;
5570 if (src_face_flag == dest_face_flag)
5572 if (i == 0)
5574 /* Destination mip levels must be subset of source mip levels. */
5575 if (!is_mip_level_subset(dest_face, src_face))
5577 LeaveCriticalSection(&ddraw_cs);
5578 return DDERR_INVALIDPARAMS;
5581 else if (Flags & dest_face_flag)
5583 copy_mipmap_chain(This, dest_face, src_face, &destpoint, &srcrect);
5586 if (src_face_flag < DDSCAPS2_CUBEMAP_NEGATIVEZ)
5588 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
5589 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | (src_face_flag << 1);
5590 IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(src, IDirectDrawSurface7), &ddsd.ddsCaps, &temp);
5592 if (src_face != src) IDirectDrawSurface7_Release(ICOM_INTERFACE(src_face, IDirectDrawSurface7));
5594 src_face = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, temp);
5596 else
5598 if (src_face != src) IDirectDrawSurface7_Release(ICOM_INTERFACE(src_face, IDirectDrawSurface7));
5600 src_face = NULL;
5604 if (dest_face_flag < DDSCAPS2_CUBEMAP_NEGATIVEZ)
5606 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
5607 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | (dest_face_flag << 1);
5608 IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(dest, IDirectDrawSurface7), &ddsd.ddsCaps, &temp);
5610 if (dest_face != dest) IDirectDrawSurface7_Release(ICOM_INTERFACE(dest_face, IDirectDrawSurface7));
5612 dest_face = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, temp);
5614 else
5616 if (dest_face != dest) IDirectDrawSurface7_Release(ICOM_INTERFACE(dest_face, IDirectDrawSurface7));
5618 dest_face = NULL;
5622 if (i == 0)
5624 /* Native returns error if src faces are not subset of dest faces. */
5625 if (src_face)
5627 LeaveCriticalSection(&ddraw_cs);
5628 return DDERR_INVALIDPARAMS;
5633 LeaveCriticalSection(&ddraw_cs);
5634 return D3D_OK;
5636 else if (dest->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP)
5638 LeaveCriticalSection(&ddraw_cs);
5639 return DDERR_INVALIDPARAMS;
5642 /* Handle non cube map textures. */
5644 /* Destination mip levels must be subset of source mip levels. */
5645 if (!is_mip_level_subset(dest, src))
5647 LeaveCriticalSection(&ddraw_cs);
5648 return DDERR_INVALIDPARAMS;
5651 copy_mipmap_chain(This, dest, src, &destpoint, &srcrect);
5653 LeaveCriticalSection(&ddraw_cs);
5654 return D3D_OK;
5657 /*****************************************************************************
5658 * IDirect3DDevice7::LightEnable
5660 * Enables or disables a light
5662 * Version 7, IDirect3DLight uses this method too.
5664 * Params:
5665 * LightIndex: The index of the light to enable / disable
5666 * Enable: Enable or disable the light
5668 * Returns:
5669 * D3D_OK on success
5670 * For more details, see IWineD3DDevice::SetLightEnable
5672 *****************************************************************************/
5673 static HRESULT WINAPI
5674 IDirect3DDeviceImpl_7_LightEnable(IDirect3DDevice7 *iface,
5675 DWORD LightIndex,
5676 BOOL Enable)
5678 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5679 HRESULT hr;
5680 TRACE("(%p)->(%08x,%d): Relay!\n", This, LightIndex, Enable);
5682 EnterCriticalSection(&ddraw_cs);
5683 hr = IWineD3DDevice_SetLightEnable(This->wineD3DDevice, LightIndex, Enable);
5684 LeaveCriticalSection(&ddraw_cs);
5685 return hr_ddraw_from_wined3d(hr);
5688 /*****************************************************************************
5689 * IDirect3DDevice7::GetLightEnable
5691 * Retrieves if the light with the given index is enabled or not
5693 * Version 7
5695 * Params:
5696 * LightIndex: Index of desired light
5697 * Enable: Pointer to a BOOL which contains the result
5699 * Returns:
5700 * D3D_OK on success
5701 * DDERR_INVALIDPARAMS if Enable is NULL
5702 * See IWineD3DDevice::GetLightEnable for more details
5704 *****************************************************************************/
5705 static HRESULT WINAPI
5706 IDirect3DDeviceImpl_7_GetLightEnable(IDirect3DDevice7 *iface,
5707 DWORD LightIndex,
5708 BOOL* Enable)
5710 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5711 HRESULT hr;
5712 TRACE("(%p)->(%08x,%p): Relay\n", This, LightIndex, Enable);
5714 if(!Enable)
5715 return DDERR_INVALIDPARAMS;
5717 EnterCriticalSection(&ddraw_cs);
5718 hr = IWineD3DDevice_GetLightEnable(This->wineD3DDevice, LightIndex, Enable);
5719 LeaveCriticalSection(&ddraw_cs);
5720 return hr_ddraw_from_wined3d(hr);
5723 /*****************************************************************************
5724 * IDirect3DDevice7::SetClipPlane
5726 * Sets custom clipping plane
5728 * Version 7
5730 * Params:
5731 * Index: The index of the clipping plane
5732 * PlaneEquation: An equation defining the clipping plane
5734 * Returns:
5735 * D3D_OK on success
5736 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
5737 * See IWineD3DDevice::SetClipPlane for more details
5739 *****************************************************************************/
5740 static HRESULT WINAPI
5741 IDirect3DDeviceImpl_7_SetClipPlane(IDirect3DDevice7 *iface,
5742 DWORD Index,
5743 D3DVALUE* PlaneEquation)
5745 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5746 HRESULT hr;
5747 TRACE("(%p)->(%08x,%p): Relay!\n", This, Index, PlaneEquation);
5749 if(!PlaneEquation)
5750 return DDERR_INVALIDPARAMS;
5752 EnterCriticalSection(&ddraw_cs);
5753 hr = IWineD3DDevice_SetClipPlane(This->wineD3DDevice, Index, PlaneEquation);
5754 LeaveCriticalSection(&ddraw_cs);
5755 return hr;
5758 /*****************************************************************************
5759 * IDirect3DDevice7::GetClipPlane
5761 * Returns the clipping plane with a specific index
5763 * Params:
5764 * Index: The index of the desired plane
5765 * PlaneEquation: Address to store the plane equation to
5767 * Returns:
5768 * D3D_OK on success
5769 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
5770 * See IWineD3DDevice::GetClipPlane for more details
5772 *****************************************************************************/
5773 static HRESULT WINAPI
5774 IDirect3DDeviceImpl_7_GetClipPlane(IDirect3DDevice7 *iface,
5775 DWORD Index,
5776 D3DVALUE* PlaneEquation)
5778 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5779 HRESULT hr;
5780 TRACE("(%p)->(%d,%p): Relay!\n", This, Index, PlaneEquation);
5782 if(!PlaneEquation)
5783 return DDERR_INVALIDPARAMS;
5785 EnterCriticalSection(&ddraw_cs);
5786 hr = IWineD3DDevice_GetClipPlane(This->wineD3DDevice, Index, PlaneEquation);
5787 LeaveCriticalSection(&ddraw_cs);
5788 return hr;
5791 /*****************************************************************************
5792 * IDirect3DDevice7::GetInfo
5794 * Retrieves some information about the device. The DirectX sdk says that
5795 * this version returns S_FALSE for all retail builds of DirectX, that's what
5796 * this implementation does.
5798 * Params:
5799 * DevInfoID: Information type requested
5800 * DevInfoStruct: Pointer to a structure to store the info to
5801 * Size: Size of the structure
5803 * Returns:
5804 * S_FALSE, because it's a non-debug driver
5806 *****************************************************************************/
5807 static HRESULT WINAPI
5808 IDirect3DDeviceImpl_7_GetInfo(IDirect3DDevice7 *iface,
5809 DWORD DevInfoID,
5810 void *DevInfoStruct,
5811 DWORD Size)
5813 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5814 TRACE("(%p)->(%08x,%p,%08x)\n", This, DevInfoID, DevInfoStruct, Size);
5816 if (TRACE_ON(d3d7))
5818 TRACE(" info requested : ");
5819 switch (DevInfoID)
5821 case D3DDEVINFOID_TEXTUREMANAGER: TRACE("D3DDEVINFOID_TEXTUREMANAGER\n"); break;
5822 case D3DDEVINFOID_D3DTEXTUREMANAGER: TRACE("D3DDEVINFOID_D3DTEXTUREMANAGER\n"); break;
5823 case D3DDEVINFOID_TEXTURING: TRACE("D3DDEVINFOID_TEXTURING\n"); break;
5824 default: ERR(" invalid flag !!!\n"); return DDERR_INVALIDPARAMS;
5828 return S_FALSE; /* According to MSDN, this is valid for a non-debug driver */
5831 const IDirect3DDevice7Vtbl IDirect3DDevice7_Vtbl =
5833 /*** IUnknown Methods ***/
5834 IDirect3DDeviceImpl_7_QueryInterface,
5835 IDirect3DDeviceImpl_7_AddRef,
5836 IDirect3DDeviceImpl_7_Release,
5837 /*** IDirect3DDevice7 ***/
5838 IDirect3DDeviceImpl_7_GetCaps,
5839 IDirect3DDeviceImpl_7_EnumTextureFormats,
5840 IDirect3DDeviceImpl_7_BeginScene,
5841 IDirect3DDeviceImpl_7_EndScene,
5842 IDirect3DDeviceImpl_7_GetDirect3D,
5843 IDirect3DDeviceImpl_7_SetRenderTarget,
5844 IDirect3DDeviceImpl_7_GetRenderTarget,
5845 IDirect3DDeviceImpl_7_Clear,
5846 IDirect3DDeviceImpl_7_SetTransform,
5847 IDirect3DDeviceImpl_7_GetTransform,
5848 IDirect3DDeviceImpl_7_SetViewport,
5849 IDirect3DDeviceImpl_7_MultiplyTransform,
5850 IDirect3DDeviceImpl_7_GetViewport,
5851 IDirect3DDeviceImpl_7_SetMaterial,
5852 IDirect3DDeviceImpl_7_GetMaterial,
5853 IDirect3DDeviceImpl_7_SetLight,
5854 IDirect3DDeviceImpl_7_GetLight,
5855 IDirect3DDeviceImpl_7_SetRenderState,
5856 IDirect3DDeviceImpl_7_GetRenderState,
5857 IDirect3DDeviceImpl_7_BeginStateBlock,
5858 IDirect3DDeviceImpl_7_EndStateBlock,
5859 IDirect3DDeviceImpl_7_PreLoad,
5860 IDirect3DDeviceImpl_7_DrawPrimitive,
5861 IDirect3DDeviceImpl_7_DrawIndexedPrimitive,
5862 IDirect3DDeviceImpl_7_SetClipStatus,
5863 IDirect3DDeviceImpl_7_GetClipStatus,
5864 IDirect3DDeviceImpl_7_DrawPrimitiveStrided,
5865 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided,
5866 IDirect3DDeviceImpl_7_DrawPrimitiveVB,
5867 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB,
5868 IDirect3DDeviceImpl_7_ComputeSphereVisibility,
5869 IDirect3DDeviceImpl_7_GetTexture,
5870 IDirect3DDeviceImpl_7_SetTexture,
5871 IDirect3DDeviceImpl_7_GetTextureStageState,
5872 IDirect3DDeviceImpl_7_SetTextureStageState,
5873 IDirect3DDeviceImpl_7_ValidateDevice,
5874 IDirect3DDeviceImpl_7_ApplyStateBlock,
5875 IDirect3DDeviceImpl_7_CaptureStateBlock,
5876 IDirect3DDeviceImpl_7_DeleteStateBlock,
5877 IDirect3DDeviceImpl_7_CreateStateBlock,
5878 IDirect3DDeviceImpl_7_Load,
5879 IDirect3DDeviceImpl_7_LightEnable,
5880 IDirect3DDeviceImpl_7_GetLightEnable,
5881 IDirect3DDeviceImpl_7_SetClipPlane,
5882 IDirect3DDeviceImpl_7_GetClipPlane,
5883 IDirect3DDeviceImpl_7_GetInfo
5886 const IDirect3DDevice3Vtbl IDirect3DDevice3_Vtbl =
5888 /*** IUnknown Methods ***/
5889 Thunk_IDirect3DDeviceImpl_3_QueryInterface,
5890 Thunk_IDirect3DDeviceImpl_3_AddRef,
5891 Thunk_IDirect3DDeviceImpl_3_Release,
5892 /*** IDirect3DDevice3 ***/
5893 IDirect3DDeviceImpl_3_GetCaps,
5894 IDirect3DDeviceImpl_3_GetStats,
5895 IDirect3DDeviceImpl_3_AddViewport,
5896 IDirect3DDeviceImpl_3_DeleteViewport,
5897 IDirect3DDeviceImpl_3_NextViewport,
5898 Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats,
5899 Thunk_IDirect3DDeviceImpl_3_BeginScene,
5900 Thunk_IDirect3DDeviceImpl_3_EndScene,
5901 Thunk_IDirect3DDeviceImpl_3_GetDirect3D,
5902 IDirect3DDeviceImpl_3_SetCurrentViewport,
5903 IDirect3DDeviceImpl_3_GetCurrentViewport,
5904 Thunk_IDirect3DDeviceImpl_3_SetRenderTarget,
5905 Thunk_IDirect3DDeviceImpl_3_GetRenderTarget,
5906 IDirect3DDeviceImpl_3_Begin,
5907 IDirect3DDeviceImpl_3_BeginIndexed,
5908 IDirect3DDeviceImpl_3_Vertex,
5909 IDirect3DDeviceImpl_3_Index,
5910 IDirect3DDeviceImpl_3_End,
5911 IDirect3DDeviceImpl_3_GetRenderState,
5912 IDirect3DDeviceImpl_3_SetRenderState,
5913 IDirect3DDeviceImpl_3_GetLightState,
5914 IDirect3DDeviceImpl_3_SetLightState,
5915 Thunk_IDirect3DDeviceImpl_3_SetTransform,
5916 Thunk_IDirect3DDeviceImpl_3_GetTransform,
5917 Thunk_IDirect3DDeviceImpl_3_MultiplyTransform,
5918 Thunk_IDirect3DDeviceImpl_3_DrawPrimitive,
5919 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive,
5920 Thunk_IDirect3DDeviceImpl_3_SetClipStatus,
5921 Thunk_IDirect3DDeviceImpl_3_GetClipStatus,
5922 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided,
5923 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided,
5924 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB,
5925 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB,
5926 Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility,
5927 Thunk_IDirect3DDeviceImpl_3_GetTexture,
5928 IDirect3DDeviceImpl_3_SetTexture,
5929 Thunk_IDirect3DDeviceImpl_3_GetTextureStageState,
5930 Thunk_IDirect3DDeviceImpl_3_SetTextureStageState,
5931 Thunk_IDirect3DDeviceImpl_3_ValidateDevice
5934 const IDirect3DDevice2Vtbl IDirect3DDevice2_Vtbl =
5936 /*** IUnknown Methods ***/
5937 Thunk_IDirect3DDeviceImpl_2_QueryInterface,
5938 Thunk_IDirect3DDeviceImpl_2_AddRef,
5939 Thunk_IDirect3DDeviceImpl_2_Release,
5940 /*** IDirect3DDevice2 ***/
5941 Thunk_IDirect3DDeviceImpl_2_GetCaps,
5942 IDirect3DDeviceImpl_2_SwapTextureHandles,
5943 Thunk_IDirect3DDeviceImpl_2_GetStats,
5944 Thunk_IDirect3DDeviceImpl_2_AddViewport,
5945 Thunk_IDirect3DDeviceImpl_2_DeleteViewport,
5946 Thunk_IDirect3DDeviceImpl_2_NextViewport,
5947 IDirect3DDeviceImpl_2_EnumTextureFormats,
5948 Thunk_IDirect3DDeviceImpl_2_BeginScene,
5949 Thunk_IDirect3DDeviceImpl_2_EndScene,
5950 Thunk_IDirect3DDeviceImpl_2_GetDirect3D,
5951 Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport,
5952 Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport,
5953 Thunk_IDirect3DDeviceImpl_2_SetRenderTarget,
5954 Thunk_IDirect3DDeviceImpl_2_GetRenderTarget,
5955 Thunk_IDirect3DDeviceImpl_2_Begin,
5956 Thunk_IDirect3DDeviceImpl_2_BeginIndexed,
5957 Thunk_IDirect3DDeviceImpl_2_Vertex,
5958 Thunk_IDirect3DDeviceImpl_2_Index,
5959 Thunk_IDirect3DDeviceImpl_2_End,
5960 Thunk_IDirect3DDeviceImpl_2_GetRenderState,
5961 Thunk_IDirect3DDeviceImpl_2_SetRenderState,
5962 Thunk_IDirect3DDeviceImpl_2_GetLightState,
5963 Thunk_IDirect3DDeviceImpl_2_SetLightState,
5964 Thunk_IDirect3DDeviceImpl_2_SetTransform,
5965 Thunk_IDirect3DDeviceImpl_2_GetTransform,
5966 Thunk_IDirect3DDeviceImpl_2_MultiplyTransform,
5967 Thunk_IDirect3DDeviceImpl_2_DrawPrimitive,
5968 Thunk_IDirect3DDeviceImpl_2_DrawIndexedPrimitive,
5969 Thunk_IDirect3DDeviceImpl_2_SetClipStatus,
5970 Thunk_IDirect3DDeviceImpl_2_GetClipStatus
5973 const IDirect3DDeviceVtbl IDirect3DDevice1_Vtbl =
5975 /*** IUnknown Methods ***/
5976 Thunk_IDirect3DDeviceImpl_1_QueryInterface,
5977 Thunk_IDirect3DDeviceImpl_1_AddRef,
5978 Thunk_IDirect3DDeviceImpl_1_Release,
5979 /*** IDirect3DDevice1 ***/
5980 IDirect3DDeviceImpl_1_Initialize,
5981 Thunk_IDirect3DDeviceImpl_1_GetCaps,
5982 Thunk_IDirect3DDeviceImpl_1_SwapTextureHandles,
5983 IDirect3DDeviceImpl_1_CreateExecuteBuffer,
5984 Thunk_IDirect3DDeviceImpl_1_GetStats,
5985 IDirect3DDeviceImpl_1_Execute,
5986 Thunk_IDirect3DDeviceImpl_1_AddViewport,
5987 Thunk_IDirect3DDeviceImpl_1_DeleteViewport,
5988 Thunk_IDirect3DDeviceImpl_1_NextViewport,
5989 IDirect3DDeviceImpl_1_Pick,
5990 IDirect3DDeviceImpl_1_GetPickRecords,
5991 Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats,
5992 IDirect3DDeviceImpl_1_CreateMatrix,
5993 IDirect3DDeviceImpl_1_SetMatrix,
5994 IDirect3DDeviceImpl_1_GetMatrix,
5995 IDirect3DDeviceImpl_1_DeleteMatrix,
5996 Thunk_IDirect3DDeviceImpl_1_BeginScene,
5997 Thunk_IDirect3DDeviceImpl_1_EndScene,
5998 Thunk_IDirect3DDeviceImpl_1_GetDirect3D
6001 /*****************************************************************************
6002 * IDirect3DDeviceImpl_CreateHandle
6004 * Not called from the VTable
6006 * Some older interface versions operate with handles, which are basically
6007 * DWORDs which identify an interface, for example
6008 * IDirect3DDevice::SetRenderState with DIRECT3DRENDERSTATE_TEXTUREHANDLE
6010 * Those handle could be just casts to the interface pointers or vice versa,
6011 * but that is not 64 bit safe and would mean blindly derefering a DWORD
6012 * passed by the app. Instead there is a dynamic array in the device which
6013 * keeps a DWORD to pointer information and a type for the handle.
6015 * Basically this array only grows, when a handle is freed its pointer is
6016 * just set to NULL. There will be much more reads from the array than
6017 * insertion operations, so a dynamic array is fine.
6019 * Params:
6020 * This: D3DDevice implementation for which this handle should be created
6022 * Returns:
6023 * A free handle on success
6024 * 0 on failure
6026 *****************************************************************************/
6027 DWORD
6028 IDirect3DDeviceImpl_CreateHandle(IDirect3DDeviceImpl *This)
6030 DWORD i;
6031 struct HandleEntry *oldHandles = This->Handles;
6033 TRACE("(%p)\n", This);
6035 for(i = 0; i < This->numHandles; i++)
6037 if(This->Handles[i].ptr == NULL &&
6038 This->Handles[i].type == DDrawHandle_Unknown)
6040 TRACE("Reusing freed handle %d\n", i + 1);
6041 return i + 1;
6045 TRACE("Growing the handle array\n");
6047 This->numHandles++;
6048 This->Handles = HeapAlloc(GetProcessHeap(), 0, sizeof(struct HandleEntry) * This->numHandles);
6049 if(!This->Handles)
6051 ERR("Out of memory\n");
6052 This->Handles = oldHandles;
6053 This->numHandles--;
6054 return 0;
6056 if(oldHandles)
6058 memcpy(This->Handles, oldHandles, (This->numHandles - 1) * sizeof(struct HandleEntry));
6059 HeapFree(GetProcessHeap(), 0, oldHandles);
6062 TRACE("Returning %d\n", This->numHandles);
6063 return This->numHandles;
6066 /*****************************************************************************
6067 * IDirect3DDeviceImpl_UpdateDepthStencil
6069 * Checks the current render target for attached depth stencils and sets the
6070 * WineD3D depth stencil accordingly.
6072 * Returns:
6073 * The depth stencil state to set if creating the device
6075 *****************************************************************************/
6076 WINED3DZBUFFERTYPE
6077 IDirect3DDeviceImpl_UpdateDepthStencil(IDirect3DDeviceImpl *This)
6079 IDirectDrawSurface7 *depthStencil = NULL;
6080 IDirectDrawSurfaceImpl *dsi;
6081 static DDSCAPS2 depthcaps = { DDSCAPS_ZBUFFER, 0, 0, 0 };
6083 IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(This->target, IDirectDrawSurface7),
6084 &depthcaps,
6085 &depthStencil);
6086 if(!depthStencil)
6088 TRACE("Setting wined3d depth stencil to NULL\n");
6089 IWineD3DDevice_SetDepthStencilSurface(This->wineD3DDevice,
6090 NULL);
6091 return WINED3DZB_FALSE;
6094 dsi = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, depthStencil);
6095 TRACE("Setting wined3d depth stencil to %p (wined3d %p)\n", dsi, dsi->WineD3DSurface);
6096 IWineD3DDevice_SetDepthStencilSurface(This->wineD3DDevice,
6097 dsi->WineD3DSurface);
6099 IDirectDrawSurface7_Release(depthStencil);
6100 return WINED3DZB_TRUE;