Avoid structures or arrays of size 0.
[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 #include "windef.h"
23 #include "winerror.h"
24 #include "wine/obj_base.h"
25 #include "ddraw.h"
26 #include "d3d.h"
27 #include "wine/debug.h"
28
29 #include "d3d_private.h"
30 #include "mesa_private.h"
31
32 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
33
34 #ifdef HAVE_OPENGL
35
36 #define D3DVPRIVATE(x) mesa_d3dv_private*dvpriv=((mesa_d3dv_private*)x->private)
37 #define D3DLPRIVATE(x) mesa_d3dl_private*dlpriv=((mesa_d3dl_private*)x->private)
38
39 static ICOM_VTABLE(IDirect3DViewport2) viewport2_vtable;
40
41 /*******************************************************************************
42  *                              Viewport1/2 static functions
43  */
44 static void activate(IDirect3DViewport2Impl* This) {
45   IDirect3DLightImpl* l;
46
47   /* Activate all the lights associated with this context */
48   l = This->lights;
49
50   while (l != NULL) {
51     l->activate(l);
52     l = l->next;
53   }
54 }
55
56 /*******************************************************************************
57  *                              Viewport1/2 Creation functions
58  */
59 LPDIRECT3DVIEWPORT2 d3dviewport2_create(IDirect3D2Impl* d3d2)
60 {
61   IDirect3DViewport2Impl* vp;
62
63   vp = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DViewport2Impl));
64   vp->private = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(mesa_d3dv_private));
65   vp->ref = 1;
66   ICOM_VTBL(vp) = &viewport2_vtable;
67   vp->d3d.d3d2 = d3d2;
68   vp->use_d3d2 = 1;
69
70   vp->device.active_device2 = NULL;
71   vp->activate = activate;
72
73   vp->lights = NULL;
74
75   ((mesa_d3dv_private *) vp->private)->nextlight = GL_LIGHT0;
76
77   return (LPDIRECT3DVIEWPORT2)vp;
78 }
79
80 LPDIRECT3DVIEWPORT d3dviewport_create(IDirect3DImpl* d3d1)
81 {
82   IDirect3DViewport2Impl* vp;
83
84   vp = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DViewport2Impl));
85   vp->private = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(mesa_d3dv_private));
86   vp->ref = 1;
87   ICOM_VTBL(vp) = &viewport2_vtable;
88   vp->d3d.d3d1 = d3d1;
89   vp->use_d3d2 = 0;
90
91   vp->device.active_device1 = NULL;
92   vp->activate = activate;
93
94   vp->lights = NULL;
95
96   ((mesa_d3dv_private *) vp->private)->nextlight = GL_LIGHT0;
97
98   return (LPDIRECT3DVIEWPORT) vp;
99 }
100
101 /*******************************************************************************
102  *                              IDirect3DViewport2 methods
103  */
104
105 HRESULT WINAPI IDirect3DViewport2Impl_QueryInterface(LPDIRECT3DVIEWPORT2 iface,
106                                                         REFIID riid,
107                                                         LPVOID* ppvObj)
108 {
109   ICOM_THIS(IDirect3DViewport2Impl,iface);
110
111   FIXME("(%p)->(%s,%p): stub\n", This, debugstr_guid(riid),ppvObj);
112
113   return S_OK;
114 }
115
116
117
118 ULONG WINAPI IDirect3DViewport2Impl_AddRef(LPDIRECT3DVIEWPORT2 iface)
119 {
120   ICOM_THIS(IDirect3DViewport2Impl,iface);
121   TRACE("(%p)->()incrementing from %lu.\n", This, This->ref );
122
123   return ++(This->ref);
124 }
125
126
127
128 ULONG WINAPI IDirect3DViewport2Impl_Release(LPDIRECT3DVIEWPORT2 iface)
129 {
130   ICOM_THIS(IDirect3DViewport2Impl,iface);
131   FIXME("(%p)->() decrementing from %lu.\n", This, This->ref );
132
133   if (!--(This->ref)) {
134     HeapFree(GetProcessHeap(),0,This);
135     return 0;
136   }
137
138   return This->ref;
139 }
140
141 /*** IDirect3DViewport methods ***/
142 HRESULT WINAPI IDirect3DViewport2Impl_Initialize(LPDIRECT3DVIEWPORT2 iface,
143                                                     LPDIRECT3D d3d)
144 {
145   ICOM_THIS(IDirect3DViewport2Impl,iface);
146   FIXME("(%p)->(%p): stub\n", This, d3d);
147
148   return DD_OK;
149 }
150
151 HRESULT WINAPI IDirect3DViewport2Impl_GetViewport(LPDIRECT3DVIEWPORT2 iface,
152                                                      LPD3DVIEWPORT lpvp)
153 {
154   ICOM_THIS(IDirect3DViewport2Impl,iface);
155   FIXME("(%p)->(%p): stub\n", This, lpvp);
156
157   if (This->use_vp2 != 0)
158     return DDERR_INVALIDPARAMS;
159
160   *lpvp = This->viewport.vp1;
161
162   return DD_OK;
163 }
164
165 HRESULT WINAPI IDirect3DViewport2Impl_SetViewport(LPDIRECT3DVIEWPORT2 iface,
166                                                      LPD3DVIEWPORT lpvp)
167 {
168   ICOM_THIS(IDirect3DViewport2Impl,iface);
169   FIXME("(%p)->(%p): stub\n", This, lpvp);
170
171   This->use_vp2 = 0;
172   This->viewport.vp1 = *lpvp;
173
174   TRACE("dwSize = %ld   dwX = %ld   dwY = %ld\n",
175         lpvp->dwSize, lpvp->dwX, lpvp->dwY);
176   TRACE("dwWidth = %ld   dwHeight = %ld\n",
177         lpvp->dwWidth, lpvp->dwHeight);
178   TRACE("dvScaleX = %f   dvScaleY = %f\n",
179         lpvp->dvScaleX, lpvp->dvScaleY);
180   TRACE("dvMaxX = %f   dvMaxY = %f\n",
181         lpvp->dvMaxX, lpvp->dvMaxY);
182   TRACE("dvMinZ = %f   dvMaxZ = %f\n",
183         lpvp->dvMinZ, lpvp->dvMaxZ);
184
185
186   return DD_OK;
187 }
188
189 HRESULT WINAPI IDirect3DViewport2Impl_TransformVertices(LPDIRECT3DVIEWPORT2 iface,
190                                                            DWORD dwVertexCount,
191                                                            LPD3DTRANSFORMDATA lpData,
192                                                            DWORD dwFlags,
193                                                            LPDWORD lpOffScreen)
194 {
195   ICOM_THIS(IDirect3DViewport2Impl,iface);
196   FIXME("(%p)->(%8ld,%p,%08lx,%p): stub\n",
197         This, dwVertexCount, lpData, dwFlags, lpOffScreen);
198
199   return DD_OK;
200 }
201
202 HRESULT WINAPI IDirect3DViewport2Impl_LightElements(LPDIRECT3DVIEWPORT2 iface,
203                                                        DWORD dwElementCount,
204                                                        LPD3DLIGHTDATA lpData)
205 {
206   ICOM_THIS(IDirect3DViewport2Impl,iface);
207   FIXME("(%p)->(%8ld,%p): stub\n", This, dwElementCount, lpData);
208
209   return DD_OK;
210 }
211
212 HRESULT WINAPI IDirect3DViewport2Impl_SetBackground(LPDIRECT3DVIEWPORT2 iface,
213                                                        D3DMATERIALHANDLE hMat)
214 {
215   ICOM_THIS(IDirect3DViewport2Impl,iface);
216   FIXME("(%p)->(%08lx): stub\n", This, (DWORD) hMat);
217
218   return DD_OK;
219 }
220
221 HRESULT WINAPI IDirect3DViewport2Impl_GetBackground(LPDIRECT3DVIEWPORT2 iface,
222                                                        LPD3DMATERIALHANDLE lphMat,
223                                                        LPBOOL lpValid)
224 {
225   ICOM_THIS(IDirect3DViewport2Impl,iface);
226   FIXME("(%p)->(%p,%p): stub\n", This, lphMat, lpValid);
227
228   return DD_OK;
229 }
230
231 HRESULT WINAPI IDirect3DViewport2Impl_SetBackgroundDepth(LPDIRECT3DVIEWPORT2 iface,
232                                                             LPDIRECTDRAWSURFACE lpDDSurface)
233 {
234   ICOM_THIS(IDirect3DViewport2Impl,iface);
235   FIXME("(%p)->(%p): stub\n", This, lpDDSurface);
236
237   return DD_OK;
238 }
239
240 HRESULT WINAPI IDirect3DViewport2Impl_GetBackgroundDepth(LPDIRECT3DVIEWPORT2 iface,
241                                                             LPDIRECTDRAWSURFACE* lplpDDSurface,
242                                                             LPBOOL lpValid)
243 {
244   ICOM_THIS(IDirect3DViewport2Impl,iface);
245   FIXME("(%p)->(%p,%p): stub\n", This, lplpDDSurface, lpValid);
246
247   return DD_OK;
248 }
249
250 HRESULT WINAPI IDirect3DViewport2Impl_Clear(LPDIRECT3DVIEWPORT2 iface,
251                                                DWORD dwCount,
252                                                LPD3DRECT lpRects,
253                                                DWORD dwFlags)
254 {
255   ICOM_THIS(IDirect3DViewport2Impl,iface);
256   GLboolean ztest;
257   FIXME("(%p)->(%8ld,%p,%08lx): stub\n", This, dwCount, lpRects, dwFlags);
258
259   /* For the moment, ignore the rectangles */
260   if (This->device.active_device1 != NULL) {
261     /* Get the rendering context */
262     if (This->use_d3d2)
263       This->device.active_device2->set_context(This->device.active_device2);
264     else
265       This->device.active_device1->set_context(This->device.active_device1);
266   }
267
268     /* Clears the screen */
269     ENTER_GL();
270     glGetBooleanv(GL_DEPTH_TEST, &ztest);
271     glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */
272     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
273     glDepthMask(ztest);
274     LEAVE_GL();
275
276   return DD_OK;
277 }
278
279 HRESULT WINAPI IDirect3DViewport2Impl_AddLight(LPDIRECT3DVIEWPORT2 iface,
280                                                   LPDIRECT3DLIGHT lpLight)
281 {
282   ICOM_THIS(IDirect3DViewport2Impl,iface);
283   IDirect3DLightImpl* ilpLight=(IDirect3DLightImpl*)lpLight;
284   FIXME("(%p)->(%p): stub\n", This, ilpLight);
285
286   /* Add the light in the 'linked' chain */
287   ilpLight->next = This->lights;
288   This->lights = ilpLight;
289
290   /* If active, activate the light */
291   if (This->device.active_device1 != NULL) {
292     D3DVPRIVATE(This);
293     D3DLPRIVATE(ilpLight);
294
295     /* Get the rendering context */
296     if (This->use_d3d2)
297       This->device.active_device2->set_context(This->device.active_device2);
298     else
299       This->device.active_device1->set_context(This->device.active_device1);
300
301     /* Activate the light */
302     dlpriv->light_num = dvpriv->nextlight++;
303     ilpLight->activate(ilpLight);
304   }
305
306   return DD_OK;
307 }
308
309 HRESULT WINAPI IDirect3DViewport2Impl_DeleteLight(LPDIRECT3DVIEWPORT2 iface,
310                                                      LPDIRECT3DLIGHT lpLight)
311 {
312   ICOM_THIS(IDirect3DViewport2Impl,iface);
313   FIXME("(%p)->(%p): stub\n", This, lpLight);
314
315   return DD_OK;
316 }
317
318 HRESULT WINAPI IDirect3DViewport2Impl_NextLight(LPDIRECT3DVIEWPORT2 iface,
319                                                    LPDIRECT3DLIGHT lpLight,
320                                                    LPDIRECT3DLIGHT* lplpLight,
321                                                    DWORD dwFlags)
322 {
323   ICOM_THIS(IDirect3DViewport2Impl,iface);
324   FIXME("(%p)->(%p,%p,%08lx): stub\n", This, lpLight, lplpLight, dwFlags);
325
326   return DD_OK;
327 }
328
329 /*** IDirect3DViewport2 methods ***/
330 HRESULT WINAPI IDirect3DViewport2Impl_GetViewport2(LPDIRECT3DVIEWPORT2 iface,
331                                                       LPD3DVIEWPORT2 lpViewport2)
332 {
333   ICOM_THIS(IDirect3DViewport2Impl,iface);
334   TRACE("(%p)->(%p)\n", This, lpViewport2);
335
336   if (This->use_vp2 != 1)
337     return DDERR_INVALIDPARAMS;
338
339   *lpViewport2 = This->viewport.vp2;
340
341   return DD_OK;
342 }
343
344 HRESULT WINAPI IDirect3DViewport2Impl_SetViewport2(LPDIRECT3DVIEWPORT2 iface,
345                                                       LPD3DVIEWPORT2 lpViewport2)
346 {
347   ICOM_THIS(IDirect3DViewport2Impl,iface);
348   TRACE("(%p)->(%p)\n", This, lpViewport2);
349
350   TRACE("dwSize = %ld   dwX = %ld   dwY = %ld\n",
351         lpViewport2->dwSize, lpViewport2->dwX, lpViewport2->dwY);
352   TRACE("dwWidth = %ld   dwHeight = %ld\n",
353         lpViewport2->dwWidth, lpViewport2->dwHeight);
354   TRACE("dvClipX = %f   dvClipY = %f\n",
355         lpViewport2->dvClipX, lpViewport2->dvClipY);
356   TRACE("dvClipWidth = %f   dvClipHeight = %f\n",
357         lpViewport2->dvClipWidth, lpViewport2->dvClipHeight);
358   TRACE("dvMinZ = %f   dvMaxZ = %f\n",
359         lpViewport2->dvMinZ, lpViewport2->dvMaxZ);
360
361   This->viewport.vp2 = *lpViewport2;
362   This->use_vp2 = 1;
363
364   return DD_OK;
365 }
366
367
368 /*******************************************************************************
369  *                              IDirect3DViewport1/2 VTable
370  */
371 static ICOM_VTABLE(IDirect3DViewport2) viewport2_vtable =
372 {
373   ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
374   /*** IUnknown methods ***/
375   IDirect3DViewport2Impl_QueryInterface,
376   IDirect3DViewport2Impl_AddRef,
377   IDirect3DViewport2Impl_Release,
378   /*** IDirect3DViewport methods ***/
379   IDirect3DViewport2Impl_Initialize,
380   IDirect3DViewport2Impl_GetViewport,
381   IDirect3DViewport2Impl_SetViewport,
382   IDirect3DViewport2Impl_TransformVertices,
383   IDirect3DViewport2Impl_LightElements,
384   IDirect3DViewport2Impl_SetBackground,
385   IDirect3DViewport2Impl_GetBackground,
386   IDirect3DViewport2Impl_SetBackgroundDepth,
387   IDirect3DViewport2Impl_GetBackgroundDepth,
388   IDirect3DViewport2Impl_Clear,
389   IDirect3DViewport2Impl_AddLight,
390   IDirect3DViewport2Impl_DeleteLight,
391   IDirect3DViewport2Impl_NextLight,
392   /*** IDirect3DViewport2 methods ***/
393   IDirect3DViewport2Impl_GetViewport2,
394   IDirect3DViewport2Impl_SetViewport2
395 };
396
397 #else /* HAVE_OPENGL */
398
399 LPDIRECT3DVIEWPORT d3dviewport_create(IDirect3DImpl* d3d1) {
400   ERR("Should not be called...\n");
401   return NULL;
402 }
403
404 LPDIRECT3DVIEWPORT2 d3dviewport2_create(IDirect3D2Impl* d3d2) {
405   ERR("Should not be called...\n");
406   return NULL;
407 }
408
409 #endif /* HAVE_OPENGL */