push 83071add6f9f2e5b8e6b93c0b0e6ee71c20d2ad7
[wine/hacks.git] / dlls / ddraw / viewport.c
blob1b7e21e9a31410453da7cd599b9662a021353e98
1 /* Direct3D Viewport
2 * Copyright (c) 1998 Lionel ULMER
3 * Copyright (c) 2006 Stefan DÖSINGER
5 * This file contains the implementation of Direct3DViewport2.
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
22 #include "config.h"
23 #include "wine/port.h"
25 #include <assert.h>
26 #include <stdarg.h>
27 #include <string.h>
28 #include <stdlib.h>
30 #define COBJMACROS
31 #define NONAMELESSUNION
33 #include "windef.h"
34 #include "winbase.h"
35 #include "winerror.h"
36 #include "wingdi.h"
37 #include "wine/exception.h"
39 #include "ddraw.h"
40 #include "d3d.h"
42 #include "ddraw_private.h"
43 #include "wine/debug.h"
45 WINE_DEFAULT_DEBUG_CHANNEL(d3d7);
47 /*****************************************************************************
48 * Helper functions
49 *****************************************************************************/
51 /*****************************************************************************
52 * viewport_activate
54 * activates the viewport using IDirect3DDevice7::SetViewport
56 *****************************************************************************/
57 void viewport_activate(IDirect3DViewportImpl* This) {
58 IDirect3DLightImpl* light;
59 D3DVIEWPORT7 vp;
61 /* Activate all the lights associated with this context */
62 light = This->lights;
64 while (light != NULL) {
65 light->activate(light);
66 light = light->next;
69 /* And copy the values in the structure used by the device */
70 if (This->use_vp2) {
71 vp.dwX = This->viewports.vp2.dwX;
72 vp.dwY = This->viewports.vp2.dwY;
73 vp.dwHeight = This->viewports.vp2.dwHeight;
74 vp.dwWidth = This->viewports.vp2.dwWidth;
75 vp.dvMinZ = This->viewports.vp2.dvMinZ;
76 vp.dvMaxZ = This->viewports.vp2.dvMaxZ;
77 } else {
78 vp.dwX = This->viewports.vp1.dwX;
79 vp.dwY = This->viewports.vp1.dwY;
80 vp.dwHeight = This->viewports.vp1.dwHeight;
81 vp.dwWidth = This->viewports.vp1.dwWidth;
82 vp.dvMinZ = This->viewports.vp1.dvMinZ;
83 vp.dvMaxZ = This->viewports.vp1.dvMaxZ;
86 /* And also set the viewport */
87 IDirect3DDevice7_SetViewport(ICOM_INTERFACE(This->active_device, IDirect3DDevice7), &vp);
90 /*****************************************************************************
91 * _dump_D3DVIEWPORT, _dump_D3DVIEWPORT2
93 * Writes viewport information to TRACE
95 *****************************************************************************/
96 static void _dump_D3DVIEWPORT(const D3DVIEWPORT *lpvp)
98 TRACE(" - dwSize = %d dwX = %d dwY = %d\n",
99 lpvp->dwSize, lpvp->dwX, lpvp->dwY);
100 TRACE(" - dwWidth = %d dwHeight = %d\n",
101 lpvp->dwWidth, lpvp->dwHeight);
102 TRACE(" - dvScaleX = %f dvScaleY = %f\n",
103 lpvp->dvScaleX, lpvp->dvScaleY);
104 TRACE(" - dvMaxX = %f dvMaxY = %f\n",
105 lpvp->dvMaxX, lpvp->dvMaxY);
106 TRACE(" - dvMinZ = %f dvMaxZ = %f\n",
107 lpvp->dvMinZ, lpvp->dvMaxZ);
110 static void _dump_D3DVIEWPORT2(const D3DVIEWPORT2 *lpvp)
112 TRACE(" - dwSize = %d dwX = %d dwY = %d\n",
113 lpvp->dwSize, lpvp->dwX, lpvp->dwY);
114 TRACE(" - dwWidth = %d dwHeight = %d\n",
115 lpvp->dwWidth, lpvp->dwHeight);
116 TRACE(" - dvClipX = %f dvClipY = %f\n",
117 lpvp->dvClipX, lpvp->dvClipY);
118 TRACE(" - dvClipWidth = %f dvClipHeight = %f\n",
119 lpvp->dvClipWidth, lpvp->dvClipHeight);
120 TRACE(" - dvMinZ = %f dvMaxZ = %f\n",
121 lpvp->dvMinZ, lpvp->dvMaxZ);
124 /*****************************************************************************
125 * IUnknown Methods.
126 *****************************************************************************/
128 /*****************************************************************************
129 * IDirect3DViewport3::QueryInterface
131 * A normal QueryInterface. Can query all interface versions and the
132 * IUnknown interface. The VTables of the different versions
133 * are equal
135 * Params:
136 * refiid: Interface id queried for
137 * obj: Address to write the interface pointer to
139 * Returns:
140 * S_OK on success.
141 * E_NOINTERFACE if the requested interface wasn't found
143 *****************************************************************************/
144 static HRESULT WINAPI
145 IDirect3DViewportImpl_QueryInterface(IDirect3DViewport3 *iface,
146 REFIID riid,
147 void **obp)
149 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
150 TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(riid), obp);
152 *obp = NULL;
154 if ( IsEqualGUID(&IID_IUnknown, riid) ||
155 IsEqualGUID(&IID_IDirect3DViewport, riid) ||
156 IsEqualGUID(&IID_IDirect3DViewport2, riid) ||
157 IsEqualGUID(&IID_IDirect3DViewport3, riid) ) {
158 IDirect3DViewport3_AddRef(ICOM_INTERFACE(This, IDirect3DViewport3));
159 *obp = ICOM_INTERFACE(This, IDirect3DViewport3);
160 TRACE(" Creating IDirect3DViewport1/2/3 interface %p\n", *obp);
161 return S_OK;
163 FIXME("(%p): interface for IID %s NOT found!\n", This, debugstr_guid(riid));
164 return E_NOINTERFACE;
167 /*****************************************************************************
168 * IDirect3DViewport3::AddRef
170 * Increases the refcount.
172 * Returns:
173 * The new refcount
175 *****************************************************************************/
176 static ULONG WINAPI
177 IDirect3DViewportImpl_AddRef(IDirect3DViewport3 *iface)
179 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
180 ULONG ref = InterlockedIncrement(&This->ref);
182 TRACE("(%p)->() incrementing from %u.\n", This, ref - 1);
184 return ref;
187 /*****************************************************************************
188 * IDirect3DViewport3::Release
190 * Reduces the refcount. If it falls to 0, the interface is released
192 * Returns:
193 * The new refcount
195 *****************************************************************************/
196 static ULONG WINAPI
197 IDirect3DViewportImpl_Release(IDirect3DViewport3 *iface)
199 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
200 ULONG ref = InterlockedDecrement(&This->ref);
202 TRACE("(%p)->() decrementing from %u.\n", This, ref + 1);
204 if (!ref) {
205 HeapFree(GetProcessHeap(), 0, This);
206 return 0;
208 return ref;
211 /*****************************************************************************
212 * IDirect3DViewport Methods.
213 *****************************************************************************/
215 /*****************************************************************************
216 * IDirect3DViewport3::Initialize
218 * No-op initialization.
220 * Params:
221 * Direct3D: The direct3D device this viewport is assigned to
223 * Returns:
224 * DDERR_ALREADYINITIALIZED
226 *****************************************************************************/
227 static HRESULT WINAPI
228 IDirect3DViewportImpl_Initialize(IDirect3DViewport3 *iface,
229 IDirect3D *Direct3D)
231 TRACE("(%p)->(%p) no-op...\n", iface, Direct3D);
232 return DDERR_ALREADYINITIALIZED;
235 /*****************************************************************************
236 * IDirect3DViewport3::GetViewport
238 * Returns the viewport data assigned to this viewport interface
240 * Params:
241 * Data: Address to store the data
243 * Returns:
244 * D3D_OK on success
245 * DDERR_INVALIDPARAMS if Data is NULL
247 *****************************************************************************/
248 static HRESULT WINAPI
249 IDirect3DViewportImpl_GetViewport(IDirect3DViewport3 *iface,
250 D3DVIEWPORT *lpData)
252 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
253 DWORD dwSize;
254 TRACE("(%p/%p)->(%p)\n", This, iface, lpData);
256 EnterCriticalSection(&ddraw_cs);
257 if (This->use_vp2 != 0) {
258 ERR(" Requesting to get a D3DVIEWPORT struct where a D3DVIEWPORT2 was set !\n");
259 LeaveCriticalSection(&ddraw_cs);
260 return DDERR_INVALIDPARAMS;
262 dwSize = lpData->dwSize;
263 memset(lpData, 0, dwSize);
264 memcpy(lpData, &(This->viewports.vp1), dwSize);
266 if (TRACE_ON(d3d7)) {
267 TRACE(" returning D3DVIEWPORT :\n");
268 _dump_D3DVIEWPORT(lpData);
270 LeaveCriticalSection(&ddraw_cs);
272 return DD_OK;
275 /*****************************************************************************
276 * IDirect3DViewport3::SetViewport
278 * Sets the viewport information for this interface
280 * Params:
281 * lpData: Viewport to set
283 * Returns:
284 * D3D_OK on success
285 * DDERR_INVALIDPARAMS if Data is NULL
287 *****************************************************************************/
288 static HRESULT WINAPI
289 IDirect3DViewportImpl_SetViewport(IDirect3DViewport3 *iface,
290 D3DVIEWPORT *lpData)
292 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
293 LPDIRECT3DVIEWPORT3 current_viewport;
294 TRACE("(%p/%p)->(%p)\n", This, iface, lpData);
296 if (TRACE_ON(d3d7)) {
297 TRACE(" getting D3DVIEWPORT :\n");
298 _dump_D3DVIEWPORT(lpData);
301 EnterCriticalSection(&ddraw_cs);
302 This->use_vp2 = 0;
303 memset(&(This->viewports.vp1), 0, sizeof(This->viewports.vp1));
304 memcpy(&(This->viewports.vp1), lpData, lpData->dwSize);
306 /* Tests on two games show that these values are never used properly so override
307 them with proper ones :-)
309 This->viewports.vp1.dvMinZ = 0.0;
310 This->viewports.vp1.dvMaxZ = 1.0;
312 if (This->active_device) {
313 IDirect3DDevice3_GetCurrentViewport(ICOM_INTERFACE(This->active_device, IDirect3DDevice3), &current_viewport);
314 if (ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, current_viewport) == This)
315 This->activate(This);
316 if(current_viewport) IDirect3DViewport3_Release(current_viewport);
318 LeaveCriticalSection(&ddraw_cs);
320 return DD_OK;
323 /*****************************************************************************
324 * IDirect3DViewport3::TransformVertices
326 * Transforms vertices by the transformation matrix.
328 * Params:
329 * dwVertexCount: The number of vertices to be transformed
330 * lpData: Pointer to the vertex data
331 * dwFlags: D3DTRANSFORM_CLIPPED or D3DTRANSFORM_UNCLIPPED
332 * lpOffScreen: Is set to nonzero if all vertices are off-screen
334 * Returns:
335 * D3D_OK because it's a stub
337 *****************************************************************************/
338 static HRESULT WINAPI
339 IDirect3DViewportImpl_TransformVertices(IDirect3DViewport3 *iface,
340 DWORD dwVertexCount,
341 D3DTRANSFORMDATA *lpData,
342 DWORD dwFlags,
343 DWORD *lpOffScreen)
345 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
346 FIXME("(%p)->(%08x,%p,%08x,%p): stub!\n", This, dwVertexCount, lpData, dwFlags, lpOffScreen);
347 if (lpOffScreen)
348 *lpOffScreen = 0;
349 return DD_OK;
352 /*****************************************************************************
353 * IDirect3DViewport3::LightElements
355 * The DirectX 5.0 sdk says that it's not implemented
357 * Params:
360 * Returns:
361 * DDERR_UNSUPPORTED
363 *****************************************************************************/
364 static HRESULT WINAPI
365 IDirect3DViewportImpl_LightElements(IDirect3DViewport3 *iface,
366 DWORD dwElementCount,
367 LPD3DLIGHTDATA lpData)
369 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
370 TRACE("(%p)->(%08x,%p): Unimplemented!\n", This, dwElementCount, lpData);
371 return DDERR_UNSUPPORTED;
374 /*****************************************************************************
375 * IDirect3DViewport3::SetBackground
377 * Sets tje background material
379 * Params:
380 * hMat: Handle from a IDirect3DMaterial interface
382 * Returns:
383 * D3D_OK on success
385 *****************************************************************************/
386 static HRESULT WINAPI
387 IDirect3DViewportImpl_SetBackground(IDirect3DViewport3 *iface,
388 D3DMATERIALHANDLE hMat)
390 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
391 TRACE("(%p)->(%d)\n", This, (DWORD) hMat);
393 EnterCriticalSection(&ddraw_cs);
394 if(hMat && hMat > This->ddraw->d3ddevice->numHandles)
396 WARN("Specified Handle %d out of range\n", hMat);
397 LeaveCriticalSection(&ddraw_cs);
398 return DDERR_INVALIDPARAMS;
400 else if(hMat && This->ddraw->d3ddevice->Handles[hMat - 1].type != DDrawHandle_Material)
402 WARN("Handle %d is not a material handle\n", hMat);
403 LeaveCriticalSection(&ddraw_cs);
404 return DDERR_INVALIDPARAMS;
407 if(hMat)
409 This->background = (IDirect3DMaterialImpl *) This->ddraw->d3ddevice->Handles[hMat - 1].ptr;
410 TRACE(" setting background color : %f %f %f %f\n",
411 This->background->mat.u.diffuse.u1.r,
412 This->background->mat.u.diffuse.u2.g,
413 This->background->mat.u.diffuse.u3.b,
414 This->background->mat.u.diffuse.u4.a);
416 else
418 This->background = NULL;
419 TRACE("Setting background to NULL\n");
422 LeaveCriticalSection(&ddraw_cs);
423 return D3D_OK;
426 /*****************************************************************************
427 * IDirect3DViewport3::GetBackground
429 * Returns the material handle assigned to the background of the viewport
431 * Params:
432 * lphMat: Address to store the handle
433 * lpValid: is set to FALSE if no background is set, TRUE if one is set
435 * Returns:
436 * D3D_OK
438 *****************************************************************************/
439 static HRESULT WINAPI
440 IDirect3DViewportImpl_GetBackground(IDirect3DViewport3 *iface,
441 D3DMATERIALHANDLE *lphMat,
442 BOOL *lpValid)
444 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
445 TRACE("(%p)->(%p,%p)\n", This, lphMat, lpValid);
447 EnterCriticalSection(&ddraw_cs);
448 if(lpValid)
450 *lpValid = This->background != NULL;
452 if(lphMat)
454 if(This->background)
456 *lphMat = This->background->Handle;
458 else
460 *lphMat = 0;
463 LeaveCriticalSection(&ddraw_cs);
465 return D3D_OK;
468 /*****************************************************************************
469 * IDirect3DViewport3::SetBackgroundDepth
471 * Sets a surface that represents the background depth. It's contents are
472 * used to set the depth buffer in IDirect3DViewport3::Clear
474 * Params:
475 * lpDDSurface: Surface to set
477 * Returns: D3D_OK, because it's a stub
479 *****************************************************************************/
480 static HRESULT WINAPI
481 IDirect3DViewportImpl_SetBackgroundDepth(IDirect3DViewport3 *iface,
482 IDirectDrawSurface *lpDDSurface)
484 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
485 FIXME("(%p)->(%p): stub!\n", This, lpDDSurface);
486 return D3D_OK;
489 /*****************************************************************************
490 * IDirect3DViewport3::GetBackgroundDepth
492 * Returns the surface that represents the depth field
494 * Params:
495 * lplpDDSurface: Address to store the interface pointer
496 * lpValid: Set to TRUE if a depth is asigned, FALSE otherwise
498 * Returns:
499 * D3D_OK, because it's a stub
500 * (DDERR_INVALIDPARAMS if DDSurface of Valid is NULL)
502 *****************************************************************************/
503 static HRESULT WINAPI
504 IDirect3DViewportImpl_GetBackgroundDepth(IDirect3DViewport3 *iface,
505 IDirectDrawSurface **lplpDDSurface,
506 LPBOOL lpValid)
508 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
509 FIXME("(%p)->(%p,%p): stub!\n", This, lplpDDSurface, lpValid);
510 return DD_OK;
513 /*****************************************************************************
514 * IDirect3DViewport3::Clear
516 * Clears the render target and / or the z buffer
518 * Params:
519 * dwCount: The amount of rectangles to clear. If 0, the whole buffer is
520 * cleared
521 * lpRects: Pointer to the array of rectangles. If NULL, Count must be 0
522 * dwFlags: D3DCLEAR_ZBUFFER and / or D3DCLEAR_TARGET
524 * Returns:
525 * D3D_OK on success
526 * D3DERR_VIEWPORTHASNODEVICE if there's no active device
527 * The return value of IDirect3DDevice7::Clear
529 *****************************************************************************/
530 static HRESULT WINAPI
531 IDirect3DViewportImpl_Clear(IDirect3DViewport3 *iface,
532 DWORD dwCount,
533 D3DRECT *lpRects,
534 DWORD dwFlags)
536 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
537 DWORD color = 0x00000000;
538 HRESULT hr;
540 TRACE("(%p/%p)->(%08x,%p,%08x)\n", This, iface, dwCount, lpRects, dwFlags);
541 if (This->active_device == NULL) {
542 ERR(" Trying to clear a viewport not attached to a device !\n");
543 return D3DERR_VIEWPORTHASNODEVICE;
546 EnterCriticalSection(&ddraw_cs);
547 if (dwFlags & D3DCLEAR_TARGET) {
548 if (This->background == NULL) {
549 ERR(" Trying to clear the color buffer without background material !\n");
550 } else {
551 color =
552 ((int) ((This->background->mat.u.diffuse.u1.r) * 255) << 16) |
553 ((int) ((This->background->mat.u.diffuse.u2.g) * 255) << 8) |
554 ((int) ((This->background->mat.u.diffuse.u3.b) * 255) << 0) |
555 ((int) ((This->background->mat.u.diffuse.u4.a) * 255) << 24);
559 hr = IDirect3DDevice7_Clear(ICOM_INTERFACE(This->active_device, IDirect3DDevice7),
560 dwCount,
561 lpRects,
562 dwFlags & (D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET),
563 color,
564 1.0,
565 0x00000000);
566 LeaveCriticalSection(&ddraw_cs);
567 return hr;
570 /*****************************************************************************
571 * IDirect3DViewport3::AddLight
573 * Adds an light to the viewport
575 * Params:
576 * lpDirect3DLight: Interface of the light to add
578 * Returns:
579 * D3D_OK on success
580 * DDERR_INVALIDPARAMS if Direct3DLight is NULL
581 * DDERR_INVALIDPARAMS if there are 8 lights or more
583 *****************************************************************************/
584 static HRESULT WINAPI
585 IDirect3DViewportImpl_AddLight(IDirect3DViewport3 *iface,
586 IDirect3DLight *lpDirect3DLight)
588 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
589 IDirect3DLightImpl *lpDirect3DLightImpl = ICOM_OBJECT(IDirect3DLightImpl, IDirect3DLight, lpDirect3DLight);
590 DWORD i = 0;
591 DWORD map = This->map_lights;
593 TRACE("(%p)->(%p)\n", This, lpDirect3DLight);
595 EnterCriticalSection(&ddraw_cs);
596 if (This->num_lights >= 8)
598 LeaveCriticalSection(&ddraw_cs);
599 return DDERR_INVALIDPARAMS;
602 /* Find a light number and update both light and viewports objects accordingly */
603 while(map&1) {
604 map>>=1;
605 i++;
607 lpDirect3DLightImpl->dwLightIndex = i;
608 This->num_lights++;
609 This->map_lights |= 1<<i;
611 /* Add the light in the 'linked' chain */
612 lpDirect3DLightImpl->next = This->lights;
613 This->lights = lpDirect3DLightImpl;
615 /* Attach the light to the viewport */
616 lpDirect3DLightImpl->active_viewport = This;
618 /* If active, activate the light */
619 if (This->active_device != NULL) {
620 lpDirect3DLightImpl->activate(lpDirect3DLightImpl);
623 LeaveCriticalSection(&ddraw_cs);
624 return D3D_OK;
627 /*****************************************************************************
628 * IDirect3DViewport3::DeleteLight
630 * Deletes a light from the viewports' light list
632 * Params:
633 * lpDirect3DLight: Light to delete
635 * Returns:
636 * D3D_OK on success
637 * DDERR_INVALIDPARAMS if the light wasn't found
639 *****************************************************************************/
640 static HRESULT WINAPI
641 IDirect3DViewportImpl_DeleteLight(IDirect3DViewport3 *iface,
642 IDirect3DLight *lpDirect3DLight)
644 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
645 IDirect3DLightImpl *lpDirect3DLightImpl = ICOM_OBJECT(IDirect3DLightImpl, IDirect3DLight, lpDirect3DLight);
646 IDirect3DLightImpl *cur_light, *prev_light = NULL;
648 TRACE("(%p)->(%p)\n", This, lpDirect3DLight);
650 EnterCriticalSection(&ddraw_cs);
651 cur_light = This->lights;
652 while (cur_light != NULL) {
653 if (cur_light == lpDirect3DLightImpl) {
654 lpDirect3DLightImpl->desactivate(lpDirect3DLightImpl);
655 if (prev_light == NULL) This->lights = cur_light->next;
656 else prev_light->next = cur_light->next;
657 /* Detach the light to the viewport */
658 cur_light->active_viewport = NULL;
659 This->num_lights--;
660 This->map_lights &= ~(1<<lpDirect3DLightImpl->dwLightIndex);
661 LeaveCriticalSection(&ddraw_cs);
662 return D3D_OK;
664 prev_light = cur_light;
665 cur_light = cur_light->next;
667 LeaveCriticalSection(&ddraw_cs);
669 return DDERR_INVALIDPARAMS;
672 /*****************************************************************************
673 * IDirect3DViewport::NextLight
675 * Enumerates the lights associated with the viewport
677 * Params:
678 * lpDirect3DLight: Light to start with
679 * lplpDirect3DLight: Address to store the successor to
681 * Returns:
682 * D3D_OK, because it's a stub
684 *****************************************************************************/
685 static HRESULT WINAPI
686 IDirect3DViewportImpl_NextLight(IDirect3DViewport3 *iface,
687 IDirect3DLight *lpDirect3DLight,
688 IDirect3DLight **lplpDirect3DLight,
689 DWORD dwFlags)
691 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
692 FIXME("(%p)->(%p,%p,%08x): stub!\n", This, lpDirect3DLight, lplpDirect3DLight, dwFlags);
693 return D3D_OK;
696 /*****************************************************************************
697 * IDirect3DViewport2 Methods.
698 *****************************************************************************/
700 /*****************************************************************************
701 * IDirect3DViewport3::GetViewport2
703 * Returns the currently set viewport in a D3DVIEWPORT2 structure.
704 * Similar to IDirect3DViewport3::GetViewport
706 * Params:
707 * lpData: Pointer to the structure to fill
709 * Returns:
710 * D3D_OK on success
711 * DDERR_INVALIDPARAMS if the viewport was set with
712 * IDirect3DViewport3::SetViewport
713 * DDERR_INVALIDPARAMS if Data is NULL
715 *****************************************************************************/
716 static HRESULT WINAPI
717 IDirect3DViewportImpl_GetViewport2(IDirect3DViewport3 *iface,
718 D3DVIEWPORT2 *lpData)
720 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
721 DWORD dwSize;
722 TRACE("(%p)->(%p)\n", This, lpData);
724 EnterCriticalSection(&ddraw_cs);
725 if (This->use_vp2 != 1) {
726 ERR(" Requesting to get a D3DVIEWPORT2 struct where a D3DVIEWPORT was set !\n");
727 LeaveCriticalSection(&ddraw_cs);
728 return DDERR_INVALIDPARAMS;
730 dwSize = lpData->dwSize;
731 memset(lpData, 0, dwSize);
732 memcpy(lpData, &(This->viewports.vp2), dwSize);
734 if (TRACE_ON(d3d7)) {
735 TRACE(" returning D3DVIEWPORT2 :\n");
736 _dump_D3DVIEWPORT2(lpData);
739 LeaveCriticalSection(&ddraw_cs);
740 return D3D_OK;
743 /*****************************************************************************
744 * IDirect3DViewport3::SetViewport2
746 * Sets the viewport from a D3DVIEWPORT2 structure
748 * Params:
749 * lpData: Viewport to set
751 * Returns:
752 * D3D_OK on success
754 *****************************************************************************/
755 static HRESULT WINAPI
756 IDirect3DViewportImpl_SetViewport2(IDirect3DViewport3 *iface,
757 D3DVIEWPORT2 *lpData)
759 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
760 LPDIRECT3DVIEWPORT3 current_viewport;
761 TRACE("(%p/%p)->(%p)\n", This, iface, lpData);
763 if (TRACE_ON(d3d7)) {
764 TRACE(" getting D3DVIEWPORT2 :\n");
765 _dump_D3DVIEWPORT2(lpData);
768 EnterCriticalSection(&ddraw_cs);
769 This->use_vp2 = 1;
770 memset(&(This->viewports.vp2), 0, sizeof(This->viewports.vp2));
771 memcpy(&(This->viewports.vp2), lpData, lpData->dwSize);
773 if (This->active_device) {
774 IDirect3DDevice3_GetCurrentViewport(ICOM_INTERFACE(This->active_device, IDirect3DDevice3), &current_viewport);
775 if (ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, current_viewport) == This)
776 This->activate(This);
777 IDirect3DViewport3_Release(current_viewport);
779 LeaveCriticalSection(&ddraw_cs);
781 return D3D_OK;
784 /*****************************************************************************
785 * IDirect3DViewport3 Methods.
786 *****************************************************************************/
788 /*****************************************************************************
789 * IDirect3DViewport3::SetBackgroundDepth2
791 * Sets a IDirectDrawSurface4 surface as the background depth surface
793 * Params:
794 * lpDDS: Surface to set
796 * Returns:
797 * D3D_OK, because it's stub
799 *****************************************************************************/
800 static HRESULT WINAPI
801 IDirect3DViewportImpl_SetBackgroundDepth2(IDirect3DViewport3 *iface,
802 IDirectDrawSurface4 *lpDDS)
804 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
805 FIXME("(%p)->(%p): stub!\n", This, lpDDS);
806 return D3D_OK;
809 /*****************************************************************************
810 * IDirect3DViewport3::GetBackgroundDepth2
812 * Returns the IDirect3DSurface4 interface to the background depth surface
814 * Params:
815 * lplpDDS: Address to store the interface pointer at
816 * lpValid: Set to true if a surface is assigned
818 * Returns:
819 * D3D_OK because it's a stub
821 *****************************************************************************/
822 static HRESULT WINAPI
823 IDirect3DViewportImpl_GetBackgroundDepth2(IDirect3DViewport3 *iface,
824 IDirectDrawSurface4 **lplpDDS,
825 BOOL *lpValid)
827 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
828 FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lplpDDS, lpValid);
829 return D3D_OK;
832 /*****************************************************************************
833 * IDirect3DViewport3::Clear2
835 * Another clearing method
837 * Params:
838 * Count: Number of rectangles to clear
839 * Rects: Rectangle array to clear
840 * Flags: Some flags :)
841 * Color: Color to fill the render target with
842 * Z: Value to fill the depth buffer with
843 * Stencil: Value to fill the stencil bits with
845 * Returns:
847 *****************************************************************************/
848 static HRESULT WINAPI
849 IDirect3DViewportImpl_Clear2(IDirect3DViewport3 *iface,
850 DWORD dwCount,
851 LPD3DRECT lpRects,
852 DWORD dwFlags,
853 DWORD dwColor,
854 D3DVALUE dvZ,
855 DWORD dwStencil)
857 ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
858 HRESULT hr;
859 TRACE("(%p)->(%08x,%p,%08x,%08x,%f,%08x)\n", This, dwCount, lpRects, dwFlags, dwColor, dvZ, dwStencil);
861 EnterCriticalSection(&ddraw_cs);
862 if (This->active_device == NULL) {
863 ERR(" Trying to clear a viewport not attached to a device !\n");
864 LeaveCriticalSection(&ddraw_cs);
865 return D3DERR_VIEWPORTHASNODEVICE;
867 hr = IDirect3DDevice7_Clear(ICOM_INTERFACE(This->active_device, IDirect3DDevice7),
868 dwCount,
869 lpRects,
870 dwFlags,
871 dwColor,
872 dvZ,
873 dwStencil);
874 LeaveCriticalSection(&ddraw_cs);
875 return hr;
878 /*****************************************************************************
879 * The VTable
880 *****************************************************************************/
882 const IDirect3DViewport3Vtbl IDirect3DViewport3_Vtbl =
884 /*** IUnknown Methods ***/
885 IDirect3DViewportImpl_QueryInterface,
886 IDirect3DViewportImpl_AddRef,
887 IDirect3DViewportImpl_Release,
888 /*** IDirect3DViewport Methods */
889 IDirect3DViewportImpl_Initialize,
890 IDirect3DViewportImpl_GetViewport,
891 IDirect3DViewportImpl_SetViewport,
892 IDirect3DViewportImpl_TransformVertices,
893 IDirect3DViewportImpl_LightElements,
894 IDirect3DViewportImpl_SetBackground,
895 IDirect3DViewportImpl_GetBackground,
896 IDirect3DViewportImpl_SetBackgroundDepth,
897 IDirect3DViewportImpl_GetBackgroundDepth,
898 IDirect3DViewportImpl_Clear,
899 IDirect3DViewportImpl_AddLight,
900 IDirect3DViewportImpl_DeleteLight,
901 IDirect3DViewportImpl_NextLight,
902 /*** IDirect3DViewport2 Methods ***/
903 IDirect3DViewportImpl_GetViewport2,
904 IDirect3DViewportImpl_SetViewport2,
905 /*** IDirect3DViewport3 Methods ***/
906 IDirect3DViewportImpl_SetBackgroundDepth2,
907 IDirect3DViewportImpl_GetBackgroundDepth2,
908 IDirect3DViewportImpl_Clear2,