Fixes for Sparc build.
[wine] / dlls / ddraw / d3dlight.c
1 /* Direct3D Light
2  * Copyright (c) 1998 Lionel ULMER
3  *
4  * This file contains the implementation of Direct3DLight.
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 "mesa_private.h"
30
31 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
32
33 #define D3DLPRIVATE(x) mesa_d3dl_private*dlpriv=((mesa_d3dl_private*)x->private)
34
35 static ICOM_VTABLE(IDirect3DLight) light_vtable;
36
37 enum {
38   D3D_1,
39   D3D_2
40 };
41
42 /*******************************************************************************
43  *                              Light static functions
44  */
45 static const float zero_value[] = {
46   0.0, 0.0, 0.0, 0.0
47 };
48
49 static void update(IDirect3DLightImpl* This) {
50   D3DLPRIVATE(This);
51   switch (This->light.dltType) {
52   case D3DLIGHT_POINT:         /* 1 */
53     TRACE("Activating POINT\n");
54     break;
55
56   case D3DLIGHT_SPOT:          /* 2 */
57     TRACE("Activating SPOT\n");
58     break;
59
60   case D3DLIGHT_DIRECTIONAL: {  /* 3 */
61     float direction[4];
62
63     TRACE("Activating DIRECTIONAL\n");
64     TRACE("  direction : %f %f %f\n",
65           This->light.dvDirection.u1.x,
66           This->light.dvDirection.u2.y,
67           This->light.dvDirection.u3.z);
68     _dump_colorvalue(" color    ", This->light.dcvColor);
69
70     glLightfv(dlpriv->light_num, GL_AMBIENT, (float *) zero_value);
71     glLightfv(dlpriv->light_num, GL_DIFFUSE, (float *) &(This->light.dcvColor));
72
73     direction[0] = -This->light.dvDirection.u1.x;
74     direction[1] = -This->light.dvDirection.u2.y;
75     direction[2] = -This->light.dvDirection.u3.z;
76     direction[3] = 0.0; /* This is a directional light */
77
78     glLightfv(dlpriv->light_num, GL_POSITION, (float *) direction);
79   } break;
80
81   case D3DLIGHT_PARALLELPOINT:  /* 4 */
82     TRACE("Activating PARRALLEL-POINT\n");
83     break;
84
85   default:
86     TRACE("Not a known Light Type: %d\n",This->light.dltType);
87     break;
88   }
89 }
90
91 static void activate(IDirect3DLightImpl* This) {
92   D3DLPRIVATE(This);
93
94   ENTER_GL();
95   update(This);
96   /* If was not active, activate it */
97   if (This->is_active == 0) {
98     glEnable(dlpriv->light_num);
99     This->is_active = 1;
100   }
101   LEAVE_GL();
102
103   return ;
104 }
105
106 /*******************************************************************************
107  *                              Light Creation functions
108  */
109 LPDIRECT3DLIGHT d3dlight_create(IDirect3D2Impl* d3d2)
110 {
111   IDirect3DLightImpl* light;
112
113   light = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DLightImpl));
114   light->ref = 1;
115   ICOM_VTBL(light) = &light_vtable;
116   light->d3d.d3d2 = d3d2;
117   light->type = D3D_2;
118
119   light->next = NULL;
120   light->prev = NULL;
121   light->activate = activate;
122   light->is_active = 0;
123
124   return (LPDIRECT3DLIGHT)light;
125 }
126
127 LPDIRECT3DLIGHT d3dlight_create_dx3(IDirect3DImpl* d3d1)
128 {
129   IDirect3DLightImpl* light;
130
131   light = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirect3DLightImpl));
132   light->ref = 1;
133   ICOM_VTBL(light) = &light_vtable;
134
135   light->d3d.d3d1 = d3d1;
136   light->type = D3D_1;
137
138   light->next = NULL;
139   light->prev = NULL;
140   light->activate = activate;
141   light->is_active = 0;
142
143   return (LPDIRECT3DLIGHT)light;
144 }
145
146 /*******************************************************************************
147  *                              IDirect3DLight methods
148  */
149
150 static HRESULT WINAPI IDirect3DLightImpl_QueryInterface(LPDIRECT3DLIGHT iface,
151                                                     REFIID riid,
152                                                     LPVOID* ppvObj)
153 {
154   ICOM_THIS(IDirect3DLightImpl,iface);
155
156   FIXME("(%p)->(%s,%p): stub\n", This, debugstr_guid(riid),ppvObj);
157
158   return S_OK;
159 }
160
161
162
163 static ULONG WINAPI IDirect3DLightImpl_AddRef(LPDIRECT3DLIGHT iface)
164 {
165   ICOM_THIS(IDirect3DLightImpl,iface);
166   TRACE("(%p)->()incrementing from %lu.\n", This, This->ref );
167
168   return ++(This->ref);
169 }
170
171
172
173 static ULONG WINAPI IDirect3DLightImpl_Release(LPDIRECT3DLIGHT iface)
174 {
175   ICOM_THIS(IDirect3DLightImpl,iface);
176   FIXME("(%p)->() decrementing from %lu.\n", This, This->ref );
177
178   if (!--(This->ref)) {
179     HeapFree(GetProcessHeap(),0,This);
180     return 0;
181   }
182
183   return This->ref;
184 }
185
186 /*** IDirect3DLight methods ***/
187 static void dump_light(LPD3DLIGHT light)
188 {
189   DPRINTF("  dwSize : %ld\n", light->dwSize);
190 }
191
192 static HRESULT WINAPI IDirect3DLightImpl_GetLight(LPDIRECT3DLIGHT iface,
193                                               LPD3DLIGHT lpLight)
194 {
195   ICOM_THIS(IDirect3DLightImpl,iface);
196   TRACE("(%p)->(%p)\n", This, lpLight);
197   if (TRACE_ON(ddraw))
198     dump_light(lpLight);
199
200   /* Copies the light structure */
201   switch (This->type) {
202   case D3D_1:
203     *((LPD3DLIGHT)lpLight) = *((LPD3DLIGHT) &(This->light));
204     break;
205   case D3D_2:
206     *((LPD3DLIGHT2)lpLight) = *((LPD3DLIGHT2) &(This->light));
207     break;
208   }
209
210   return DD_OK;
211 }
212
213 static HRESULT WINAPI IDirect3DLightImpl_SetLight(LPDIRECT3DLIGHT iface,
214                                               LPD3DLIGHT lpLight)
215 {
216   ICOM_THIS(IDirect3DLightImpl,iface);
217   TRACE("(%p)->(%p)\n", This, lpLight);
218   if (TRACE_ON(ddraw))
219     dump_light(lpLight);
220
221   /* Stores the light */
222   switch (This->type) {
223   case D3D_1:
224     *((LPD3DLIGHT) &(This->light)) = *((LPD3DLIGHT)lpLight);
225     break;
226   case D3D_2:
227     *((LPD3DLIGHT2) &(This->light)) = *((LPD3DLIGHT2)lpLight);
228     break;
229   }
230
231   ENTER_GL();
232   if (This->is_active)
233     update(This);
234   LEAVE_GL();
235
236   return DD_OK;
237 }
238
239 static HRESULT WINAPI IDirect3DLightImpl_Initialize(LPDIRECT3DLIGHT iface,
240                                                 LPDIRECT3D lpDirect3D)
241
242 {
243   ICOM_THIS(IDirect3DLightImpl,iface);
244   TRACE("(%p)->(%p)\n", This, lpDirect3D);
245
246   return DDERR_ALREADYINITIALIZED;
247 }
248
249
250 /*******************************************************************************
251  *                              IDirect3DLight VTable
252  */
253 static ICOM_VTABLE(IDirect3DLight) light_vtable =
254 {
255   ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
256   /*** IUnknown methods ***/
257   IDirect3DLightImpl_QueryInterface,
258   IDirect3DLightImpl_AddRef,
259   IDirect3DLightImpl_Release,
260   /*** IDirect3DLight methods ***/
261   IDirect3DLightImpl_Initialize,
262   IDirect3DLightImpl_SetLight,
263   IDirect3DLightImpl_GetLight
264 };