#undef interface before including alsa headers.
[wine] / dlls / ddraw / d3dviewport.c
1 /* Direct3D Viewport
2  * Copyright (c) 1998 Lionel ULMER
3  *
4  * This file contains the implementation of Direct3DViewport2.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include "config.h"
22
23 #include <stdarg.h>
24
25 #define NONAMELESSUNION
26 #define NONAMELESSSTRUCT
27
28 #define CONST_VTABLE
29
30 #include "windef.h"
31 #include "winbase.h"
32 #include "winerror.h"
33 #include "objbase.h"
34 #include "wingdi.h"
35 #include "ddraw.h"
36 #include "d3d.h"
37 #include "wine/debug.h"
38
39 #include "d3d_private.h"
40
41 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
42
43 static void activate(IDirect3DViewportImpl* This) {
44     IDirect3DLightImpl* light;
45     D3DVIEWPORT7 vp;
46     
47     /* Activate all the lights associated with this context */
48     light = This->lights;
49
50     while (light != NULL) {
51         light->activate(light);
52         light = light->next;
53     }
54
55     /* And copy the values in the structure used by the device */
56     if (This->use_vp2) {
57         vp.dwX = This->viewports.vp2.dwX;
58         vp.dwY = This->viewports.vp2.dwY;
59         vp.dwHeight = This->viewports.vp2.dwHeight;
60         vp.dwWidth = This->viewports.vp2.dwWidth;
61         vp.dvMinZ = This->viewports.vp2.dvMinZ;
62         vp.dvMaxZ = This->viewports.vp2.dvMaxZ;
63     } else {
64         vp.dwX = This->viewports.vp1.dwX;
65         vp.dwY = This->viewports.vp1.dwY;
66         vp.dwHeight = This->viewports.vp1.dwHeight;
67         vp.dwWidth = This->viewports.vp1.dwWidth;
68         vp.dvMinZ = This->viewports.vp1.dvMinZ;
69         vp.dvMaxZ = This->viewports.vp1.dvMaxZ;
70     }
71     
72     /* And also set the viewport */
73     IDirect3DDevice7_SetViewport(ICOM_INTERFACE(This->active_device, IDirect3DDevice7), &vp);
74 }
75
76
77 static void _dump_D3DVIEWPORT(D3DVIEWPORT *lpvp)
78 {
79     TRACE("    - dwSize = %ld   dwX = %ld   dwY = %ld\n",
80           lpvp->dwSize, lpvp->dwX, lpvp->dwY);
81     TRACE("    - dwWidth = %ld   dwHeight = %ld\n",
82           lpvp->dwWidth, lpvp->dwHeight);
83     TRACE("    - dvScaleX = %f   dvScaleY = %f\n",
84           lpvp->dvScaleX, lpvp->dvScaleY);
85     TRACE("    - dvMaxX = %f   dvMaxY = %f\n",
86           lpvp->dvMaxX, lpvp->dvMaxY);
87     TRACE("    - dvMinZ = %f   dvMaxZ = %f\n",
88           lpvp->dvMinZ, lpvp->dvMaxZ);
89 }
90
91 static void _dump_D3DVIEWPORT2(D3DVIEWPORT2 *lpvp)
92 {
93     TRACE("    - dwSize = %ld   dwX = %ld   dwY = %ld\n",
94           lpvp->dwSize, lpvp->dwX, lpvp->dwY);
95     TRACE("    - dwWidth = %ld   dwHeight = %ld\n",
96           lpvp->dwWidth, lpvp->dwHeight);
97     TRACE("    - dvClipX = %f   dvClipY = %f\n",
98           lpvp->dvClipX, lpvp->dvClipY);
99     TRACE("    - dvClipWidth = %f   dvClipHeight = %f\n",
100           lpvp->dvClipWidth, lpvp->dvClipHeight);
101     TRACE("    - dvMinZ = %f   dvMaxZ = %f\n",
102           lpvp->dvMinZ, lpvp->dvMaxZ);
103 }
104
105 HRESULT WINAPI
106 Main_IDirect3DViewportImpl_3_2_1_QueryInterface(LPDIRECT3DVIEWPORT3 iface,
107                                                 REFIID riid,
108                                                 LPVOID* obp)
109 {
110     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
111     TRACE("(%p/%p)->(%s,%p)\n", This, iface, debugstr_guid(riid), obp);
112
113     *obp = NULL;
114
115     if ( IsEqualGUID(&IID_IUnknown,  riid) ||
116          IsEqualGUID(&IID_IDirect3DViewport, riid) ||
117          IsEqualGUID(&IID_IDirect3DViewport2, riid) ||
118          IsEqualGUID(&IID_IDirect3DViewport3, riid) ) {
119         IDirect3DViewport3_AddRef(ICOM_INTERFACE(This, IDirect3DViewport3));
120         *obp = ICOM_INTERFACE(This, IDirect3DViewport3);
121         TRACE("  Creating IDirect3DViewport1/2/3 interface %p\n", *obp);
122         return S_OK;
123     }
124     FIXME("(%p): interface for IID %s NOT found!\n", This, debugstr_guid(riid));
125     return OLE_E_ENUM_NOMORE;
126 }
127
128 ULONG WINAPI
129 Main_IDirect3DViewportImpl_3_2_1_AddRef(LPDIRECT3DVIEWPORT3 iface)
130 {
131     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
132     ULONG ref = InterlockedIncrement(&This->ref);
133
134     TRACE("(%p/%p)->() incrementing from %lu.\n", This, iface, ref - 1);
135
136     return ref;
137 }
138
139 ULONG WINAPI
140 Main_IDirect3DViewportImpl_3_2_1_Release(LPDIRECT3DVIEWPORT3 iface)
141 {
142     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
143     ULONG ref = InterlockedDecrement(&This->ref);
144
145     TRACE("(%p/%p)->() decrementing from %lu.\n", This, iface, ref + 1);
146
147     if (!ref) {
148         HeapFree(GetProcessHeap(), 0, This);
149         return 0;
150     }
151     return ref;
152 }
153
154
155 HRESULT WINAPI
156 Main_IDirect3DViewportImpl_3_2_1_Initialize(LPDIRECT3DVIEWPORT3 iface,
157                                             LPDIRECT3D lpDirect3D)
158 {
159     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
160     TRACE("(%p/%p)->(%p) no-op...\n", This, iface, lpDirect3D);
161     return DD_OK;
162 }
163
164 HRESULT WINAPI
165 Main_IDirect3DViewportImpl_3_2_1_GetViewport(LPDIRECT3DVIEWPORT3 iface,
166                                              LPD3DVIEWPORT lpData)
167 {
168     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
169     DWORD dwSize;
170     TRACE("(%p/%p)->(%p)\n", This, iface, lpData);
171     if (This->use_vp2 != 0) {
172         ERR("  Requesting to get a D3DVIEWPORT struct where a D3DVIEWPORT2 was set !\n");
173         return DDERR_INVALIDPARAMS;
174     }
175     dwSize = lpData->dwSize;
176     memset(lpData, 0, dwSize);
177     memcpy(lpData, &(This->viewports.vp1), dwSize);
178
179     if (TRACE_ON(ddraw)) {
180         TRACE("  returning D3DVIEWPORT :\n");
181         _dump_D3DVIEWPORT(lpData);
182     }
183     
184     return DD_OK;
185 }
186
187 HRESULT WINAPI
188 Main_IDirect3DViewportImpl_3_2_1_SetViewport(LPDIRECT3DVIEWPORT3 iface,
189                                              LPD3DVIEWPORT lpData)
190 {
191     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
192     LPDIRECT3DVIEWPORT3 current_viewport;
193     TRACE("(%p/%p)->(%p)\n", This, iface, lpData);
194
195     if (TRACE_ON(ddraw)) {
196         TRACE("  getting D3DVIEWPORT :\n");
197         _dump_D3DVIEWPORT(lpData);
198     }
199
200     This->use_vp2 = 0;
201     memset(&(This->viewports.vp1), 0, sizeof(This->viewports.vp1));
202     memcpy(&(This->viewports.vp1), lpData, lpData->dwSize);
203
204     /* Tests on two games show that these values are never used properly so override
205        them with proper ones :-)
206     */
207     This->viewports.vp1.dvMinZ = 0.0;
208     This->viewports.vp1.dvMaxZ = 1.0;
209
210     if (This->active_device) {
211       IDirect3DDevice3_GetCurrentViewport(ICOM_INTERFACE(This->active_device, IDirect3DDevice3), &current_viewport);
212       if (ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, current_viewport) == This)
213           This->activate(This);
214       IDirect3DViewport3_Release(current_viewport);
215     }
216
217     return DD_OK;
218 }
219
220 HRESULT WINAPI
221 Main_IDirect3DViewportImpl_3_2_1_TransformVertices(LPDIRECT3DVIEWPORT3 iface,
222                                                    DWORD dwVertexCount,
223                                                    LPD3DTRANSFORMDATA lpData,
224                                                    DWORD dwFlags,
225                                                    LPDWORD lpOffScreen)
226 {
227     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
228     FIXME("(%p/%p)->(%08lx,%p,%08lx,%p): stub!\n", This, iface, dwVertexCount, lpData, dwFlags, lpOffScreen);
229     if (lpOffScreen)
230         *lpOffScreen = 0;
231     return DD_OK;
232 }
233
234 HRESULT WINAPI
235 Main_IDirect3DViewportImpl_3_2_1_LightElements(LPDIRECT3DVIEWPORT3 iface,
236                                                DWORD dwElementCount,
237                                                LPD3DLIGHTDATA lpData)
238 {
239     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
240     FIXME("(%p/%p)->(%08lx,%p): stub!\n", This, iface, dwElementCount, lpData);
241     return DD_OK;
242 }
243
244 HRESULT WINAPI
245 Main_IDirect3DViewportImpl_3_2_1_SetBackground(LPDIRECT3DVIEWPORT3 iface,
246                                                D3DMATERIALHANDLE hMat)
247 {
248     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
249     TRACE("(%p/%p)->(%08lx)\n", This, iface, (DWORD) hMat);
250     
251     This->background = (IDirect3DMaterialImpl *) hMat;
252     TRACE(" setting background color : %f %f %f %f\n",
253           This->background->mat.u.diffuse.u1.r,
254           This->background->mat.u.diffuse.u2.g,
255           This->background->mat.u.diffuse.u3.b,
256           This->background->mat.u.diffuse.u4.a);
257
258     return DD_OK;
259 }
260
261 HRESULT WINAPI
262 Main_IDirect3DViewportImpl_3_2_1_GetBackground(LPDIRECT3DVIEWPORT3 iface,
263                                                LPD3DMATERIALHANDLE lphMat,
264                                                LPBOOL lpValid)
265 {
266     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
267     FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lphMat, lpValid);
268     return DD_OK;
269 }
270
271 HRESULT WINAPI
272 Main_IDirect3DViewportImpl_3_2_1_SetBackgroundDepth(LPDIRECT3DVIEWPORT3 iface,
273                                                     LPDIRECTDRAWSURFACE lpDDSurface)
274 {
275     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
276     FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpDDSurface);
277     return DD_OK;
278 }
279
280 HRESULT WINAPI
281 Main_IDirect3DViewportImpl_3_2_1_GetBackgroundDepth(LPDIRECT3DVIEWPORT3 iface,
282                                                     LPDIRECTDRAWSURFACE* lplpDDSurface,
283                                                     LPBOOL lpValid)
284 {
285     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
286     FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lplpDDSurface, lpValid);
287     return DD_OK;
288 }
289
290 HRESULT WINAPI
291 Main_IDirect3DViewportImpl_3_2_1_Clear(LPDIRECT3DVIEWPORT3 iface,
292                                        DWORD dwCount,
293                                        LPD3DRECT lpRects,
294                                        DWORD dwFlags)
295 {
296     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
297     DWORD color = 0x00000000;
298     
299     TRACE("(%p/%p)->(%08lx,%p,%08lx)\n", This, iface, dwCount, lpRects, dwFlags);
300     if (This->active_device == NULL) {
301         ERR(" Trying to clear a viewport not attached to a device !\n");
302         return D3DERR_VIEWPORTHASNODEVICE;
303     }
304     if (dwFlags & D3DCLEAR_TARGET) {
305         if (This->background == NULL) {
306             ERR(" Trying to clear the color buffer without background material !\n");
307         } else {
308             color = 
309               ((int) ((This->background->mat.u.diffuse.u1.r) * 255) << 16) |
310               ((int) ((This->background->mat.u.diffuse.u2.g) * 255) <<  8) |
311               ((int) ((This->background->mat.u.diffuse.u3.b) * 255) <<  0) |
312               ((int) ((This->background->mat.u.diffuse.u4.a) * 255) << 24);
313         }
314     }
315     return This->active_device->clear(This->active_device, dwCount, lpRects, 
316                                       dwFlags & (D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET),
317                                       color, 1.0, 0x00000000);
318 }
319
320 HRESULT WINAPI
321 Main_IDirect3DViewportImpl_3_2_1_AddLight(LPDIRECT3DVIEWPORT3 iface,
322                                           LPDIRECT3DLIGHT lpDirect3DLight)
323 {
324     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
325     IDirect3DLightImpl *lpDirect3DLightImpl = ICOM_OBJECT(IDirect3DLightImpl, IDirect3DLight, lpDirect3DLight);
326     DWORD i = 0;
327     DWORD map = This->map_lights;
328     
329     TRACE("(%p/%p)->(%p)\n", This, iface, lpDirect3DLight);
330     
331     if (This->num_lights >= 8)
332         return DDERR_INVALIDPARAMS;
333
334     /* Find a light number and update both light and viewports objects accordingly */
335     while(map&1) {
336         map>>=1;
337         i++;
338     }
339     lpDirect3DLightImpl->dwLightIndex = i;
340     This->num_lights++;
341     This->map_lights |= 1<<i;
342
343     /* Add the light in the 'linked' chain */
344     lpDirect3DLightImpl->next = This->lights;
345     This->lights = lpDirect3DLightImpl;
346
347     /* Attach the light to the viewport */
348     lpDirect3DLightImpl->active_viewport = This;
349     
350     /* If active, activate the light */
351     if (This->active_device != NULL) {
352         lpDirect3DLightImpl->activate(lpDirect3DLightImpl);
353     }
354     
355     return DD_OK;
356 }
357
358 HRESULT WINAPI
359 Main_IDirect3DViewportImpl_3_2_1_DeleteLight(LPDIRECT3DVIEWPORT3 iface,
360                                              LPDIRECT3DLIGHT lpDirect3DLight)
361 {
362     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
363     IDirect3DLightImpl *lpDirect3DLightImpl = ICOM_OBJECT(IDirect3DLightImpl, IDirect3DLight, lpDirect3DLight);
364     IDirect3DLightImpl *cur_light, *prev_light = NULL;
365     
366     TRACE("(%p/%p)->(%p)\n", This, iface, lpDirect3DLight);
367     cur_light = This->lights;
368     while (cur_light != NULL) {
369         if (cur_light == lpDirect3DLightImpl) {
370             lpDirect3DLightImpl->desactivate(lpDirect3DLightImpl);
371             if (prev_light == NULL) This->lights = cur_light->next;
372             else prev_light->next = cur_light->next;
373             /* Detach the light to the viewport */
374             cur_light->active_viewport = NULL;
375             This->num_lights--;
376             This->map_lights &= ~(1<<lpDirect3DLightImpl->dwLightIndex);
377             return DD_OK;
378         }
379         prev_light = cur_light;
380         cur_light = cur_light->next;
381     }
382     return DDERR_INVALIDPARAMS;
383 }
384
385 HRESULT WINAPI
386 Main_IDirect3DViewportImpl_3_2_1_NextLight(LPDIRECT3DVIEWPORT3 iface,
387                                            LPDIRECT3DLIGHT lpDirect3DLight,
388                                            LPDIRECT3DLIGHT* lplpDirect3DLight,
389                                            DWORD dwFlags)
390 {
391     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
392     FIXME("(%p/%p)->(%p,%p,%08lx): stub!\n", This, iface, lpDirect3DLight, lplpDirect3DLight, dwFlags);
393     return DD_OK;
394 }
395
396 HRESULT WINAPI
397 Main_IDirect3DViewportImpl_3_2_GetViewport2(LPDIRECT3DVIEWPORT3 iface,
398                                             LPD3DVIEWPORT2 lpData)
399 {
400     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
401     DWORD dwSize;
402     TRACE("(%p/%p)->(%p)\n", This, iface, lpData);
403     if (This->use_vp2 != 1) {
404         ERR("  Requesting to get a D3DVIEWPORT2 struct where a D3DVIEWPORT was set !\n");
405         return DDERR_INVALIDPARAMS;
406     }
407     dwSize = lpData->dwSize;
408     memset(lpData, 0, dwSize);
409     memcpy(lpData, &(This->viewports.vp2), dwSize);
410
411     if (TRACE_ON(ddraw)) {
412         TRACE("  returning D3DVIEWPORT2 :\n");
413         _dump_D3DVIEWPORT2(lpData);
414     }
415     
416     return DD_OK;
417 }
418
419 HRESULT WINAPI
420 Main_IDirect3DViewportImpl_3_2_SetViewport2(LPDIRECT3DVIEWPORT3 iface,
421                                             LPD3DVIEWPORT2 lpData)
422 {
423     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
424     LPDIRECT3DVIEWPORT3 current_viewport;
425     TRACE("(%p/%p)->(%p)\n", This, iface, lpData);
426
427     if (TRACE_ON(ddraw)) {
428         TRACE("  getting D3DVIEWPORT2 :\n");
429         _dump_D3DVIEWPORT2(lpData);
430     }
431
432     This->use_vp2 = 1;
433     memset(&(This->viewports.vp2), 0, sizeof(This->viewports.vp2));
434     memcpy(&(This->viewports.vp2), lpData, lpData->dwSize);
435
436     if (This->active_device) {
437       IDirect3DDevice3_GetCurrentViewport(ICOM_INTERFACE(This->active_device, IDirect3DDevice3), &current_viewport);
438       if (ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, current_viewport) == This)
439         This->activate(This);
440       IDirect3DViewport3_Release(current_viewport);
441     }
442
443     return DD_OK;
444 }
445
446 HRESULT WINAPI
447 Main_IDirect3DViewportImpl_3_SetBackgroundDepth2(LPDIRECT3DVIEWPORT3 iface,
448                                                  LPDIRECTDRAWSURFACE4 lpDDS)
449 {
450     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
451     FIXME("(%p/%p)->(%p): stub!\n", This, iface, lpDDS);
452     return DD_OK;
453 }
454
455 HRESULT WINAPI
456 Main_IDirect3DViewportImpl_3_GetBackgroundDepth2(LPDIRECT3DVIEWPORT3 iface,
457                                                  LPDIRECTDRAWSURFACE4* lplpDDS,
458                                                  LPBOOL lpValid)
459 {
460     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
461     FIXME("(%p/%p)->(%p,%p): stub!\n", This, iface, lplpDDS, lpValid);
462     return DD_OK;
463 }
464
465 HRESULT WINAPI
466 Main_IDirect3DViewportImpl_3_Clear2(LPDIRECT3DVIEWPORT3 iface,
467                                     DWORD dwCount,
468                                     LPD3DRECT lpRects,
469                                     DWORD dwFlags,
470                                     DWORD dwColor,
471                                     D3DVALUE dvZ,
472                                     DWORD dwStencil)
473 {
474     ICOM_THIS_FROM(IDirect3DViewportImpl, IDirect3DViewport3, iface);
475     TRACE("(%p/%p)->(%08lx,%p,%08lx,%08lx,%f,%08lx)\n", This, iface, dwCount, lpRects, dwFlags, dwColor, dvZ, dwStencil);
476     if (This->active_device == NULL) {
477         ERR(" Trying to clear a viewport not attached to a device !\n");
478         return D3DERR_VIEWPORTHASNODEVICE;
479     }
480     return This->active_device->clear(This->active_device, dwCount, lpRects, dwFlags, dwColor, dvZ, dwStencil);
481 }
482
483 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
484 # define XCAST(fun)     (typeof(VTABLE_IDirect3DViewport3.fun))
485 #else
486 # define XCAST(fun)     (void*)
487 #endif
488
489 static const IDirect3DViewport3Vtbl VTABLE_IDirect3DViewport3 =
490 {
491     XCAST(QueryInterface) Main_IDirect3DViewportImpl_3_2_1_QueryInterface,
492     XCAST(AddRef) Main_IDirect3DViewportImpl_3_2_1_AddRef,
493     XCAST(Release) Main_IDirect3DViewportImpl_3_2_1_Release,
494     XCAST(Initialize) Main_IDirect3DViewportImpl_3_2_1_Initialize,
495     XCAST(GetViewport) Main_IDirect3DViewportImpl_3_2_1_GetViewport,
496     XCAST(SetViewport) Main_IDirect3DViewportImpl_3_2_1_SetViewport,
497     XCAST(TransformVertices) Main_IDirect3DViewportImpl_3_2_1_TransformVertices,
498     XCAST(LightElements) Main_IDirect3DViewportImpl_3_2_1_LightElements,
499     XCAST(SetBackground) Main_IDirect3DViewportImpl_3_2_1_SetBackground,
500     XCAST(GetBackground) Main_IDirect3DViewportImpl_3_2_1_GetBackground,
501     XCAST(SetBackgroundDepth) Main_IDirect3DViewportImpl_3_2_1_SetBackgroundDepth,
502     XCAST(GetBackgroundDepth) Main_IDirect3DViewportImpl_3_2_1_GetBackgroundDepth,
503     XCAST(Clear) Main_IDirect3DViewportImpl_3_2_1_Clear,
504     XCAST(AddLight) Main_IDirect3DViewportImpl_3_2_1_AddLight,
505     XCAST(DeleteLight) Main_IDirect3DViewportImpl_3_2_1_DeleteLight,
506     XCAST(NextLight) Main_IDirect3DViewportImpl_3_2_1_NextLight,
507     XCAST(GetViewport2) Main_IDirect3DViewportImpl_3_2_GetViewport2,
508     XCAST(SetViewport2) Main_IDirect3DViewportImpl_3_2_SetViewport2,
509     XCAST(SetBackgroundDepth2) Main_IDirect3DViewportImpl_3_SetBackgroundDepth2,
510     XCAST(GetBackgroundDepth2) Main_IDirect3DViewportImpl_3_GetBackgroundDepth2,
511     XCAST(Clear2) Main_IDirect3DViewportImpl_3_Clear2,
512 };
513
514 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
515 #undef XCAST
516 #endif
517
518
519
520
521 HRESULT d3dviewport_create(IDirect3DViewportImpl **obj, IDirectDrawImpl *d3d)
522 {
523     IDirect3DViewportImpl *object;
524
525     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DViewportImpl));
526     if (object == NULL) return DDERR_OUTOFMEMORY;
527
528     object->ref = 1;
529     object->d3d = d3d;
530     object->activate = activate;
531     object->use_vp2 = 0xFF;
532     object->next = NULL;
533     object->lights = NULL;
534     object->num_lights = 0;
535     object->map_lights = 0;
536     
537     ICOM_INIT_INTERFACE(object, IDirect3DViewport3, VTABLE_IDirect3DViewport3);
538
539     *obj = object;
540
541     TRACE(" creating implementation at %p.\n", *obj);
542     
543     return D3D_OK;
544 }