ddraw: Exclude unused headers.
[wine] / dlls / ddraw / light.c
1 /* Direct3D Light
2  * Copyright (c) 1998 / 2002 Lionel ULMER
3  * Copyright (c) 2006        Stefan DÖSINGER
4  *
5  * This file contains the implementation of Direct3DLight.
6  *
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.
11  *
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.
16  *
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
20  */
21
22 #include "config.h"
23 #include "wine/port.h"
24 #include "wine/debug.h"
25
26 #include <assert.h>
27 #include <stdarg.h>
28 #include <string.h>
29 #include <stdlib.h>
30
31 #define COBJMACROS
32
33 #include "windef.h"
34 #include "winbase.h"
35 #include "winerror.h"
36 #include "wingdi.h"
37 #include "wine/exception.h"
38
39 #include "ddraw.h"
40 #include "d3d.h"
41
42 #include "ddraw_private.h"
43
44 WINE_DEFAULT_DEBUG_CHANNEL(d3d7);
45
46 /*****************************************************************************
47  * IUnknown Methods.
48  *****************************************************************************/
49
50 /*****************************************************************************
51  * IDirect3DLight::QueryInterface
52  *
53  * Queries the object for different interfaces. Unimplemented for this
54  * object at the moment
55  *
56  * Params:
57  *  riid: Interface id asked for
58  *  obj: Address to return the resulting pointer at.
59  *
60  * Returns:
61  *  E_NOINTERFACE, because it's a stub
62  *****************************************************************************/
63 static HRESULT WINAPI
64 IDirect3DLightImpl_QueryInterface(IDirect3DLight *iface,
65                                   REFIID riid,
66                                   void **obp)
67 {
68     ICOM_THIS_FROM(IDirect3DLightImpl, IDirect3DLight, iface);
69     FIXME("(%p)->(%s,%p): stub!\n", This, debugstr_guid(riid), obp);
70     *obp = NULL;
71     return E_NOINTERFACE;
72 }
73
74 /*****************************************************************************
75  * IDirect3DLight::AddRef
76  *
77  * Increases the refcount by 1
78  *
79  * Returns:
80  *  The new refcount
81  *
82  *****************************************************************************/
83 static ULONG WINAPI
84 IDirect3DLightImpl_AddRef(IDirect3DLight *iface)
85 {
86     ICOM_THIS_FROM(IDirect3DLightImpl, IDirect3DLight, iface);
87     ULONG ref = InterlockedIncrement(&This->ref);
88
89     TRACE("(%p)->() incrementing from %u.\n", This, ref - 1);
90
91     return ref;
92 }
93
94 /*****************************************************************************
95  * IDirect3DLight::Release
96  *
97  * Reduces the refcount by one. If the refcount falls to 0, the object
98  * is destroyed
99  *
100  * Returns:
101  *  The new refcount
102  *
103  *****************************************************************************/
104 static ULONG WINAPI
105 IDirect3DLightImpl_Release(IDirect3DLight *iface)
106 {
107     ICOM_THIS_FROM(IDirect3DLightImpl, IDirect3DLight, iface);
108     ULONG ref = InterlockedDecrement(&This->ref);
109
110     TRACE("(%p)->() decrementing from %u.\n", This, ref + 1);
111
112     if (!ref) {
113         HeapFree(GetProcessHeap(), 0, This);
114         return 0;
115     }
116     return ref;
117 }
118
119 /*****************************************************************************
120  * IDirect3DLight Methods.
121  *****************************************************************************/
122
123 /*****************************************************************************
124  * IDirect3DLight::Initialize
125  *
126  * Initializes the interface. This implementation is a no-op, because
127  * initialization takes place at creation time
128  *
129  * Params:
130  *  Direct3D: Pointer to an IDirect3D interface.
131  *
132  * Returns:
133  *  D3D_OK
134  *
135  *****************************************************************************/
136 static HRESULT WINAPI
137 IDirect3DLightImpl_Initialize(IDirect3DLight *iface,
138                               IDirect3D *lpDirect3D)
139 {
140     ICOM_THIS_FROM(IDirect3DLightImpl, IDirect3DLight, iface);
141     IDirectDrawImpl *d3d = ICOM_OBJECT(IDirectDrawImpl, IDirect3D, lpDirect3D);
142     TRACE("(%p)->(%p) no-op...\n", This, d3d);
143     return D3D_OK;
144 }
145
146 /*****************************************************************************
147  * IDirect3DLight::SetLight
148  *
149  * Assigns a lighting value to this object
150  *
151  * Params:
152  *  Light: Lighting parametes to set
153  *
154  * Returns:
155  *  D3D_OK on success
156  *  DDERR_INVALIDPARAMS if Light is NULL
157  *
158  *****************************************************************************/
159 static void dump_light(const D3DLIGHT2 *light)
160 {
161     DPRINTF("    - dwSize : %d\n", light->dwSize);
162 }
163
164 static const float zero_value[] = {
165     0.0, 0.0, 0.0, 0.0
166 };
167
168 static HRESULT WINAPI
169 IDirect3DLightImpl_SetLight(IDirect3DLight *iface,
170                             D3DLIGHT *lpLight)
171 {
172     ICOM_THIS_FROM(IDirect3DLightImpl, IDirect3DLight, iface);
173     LPD3DLIGHT7 light7 = &(This->light7);
174     TRACE("(%p)->(%p)\n", This, lpLight);
175     if (TRACE_ON(d3d7)) {
176         TRACE("  Light definition :\n");
177         dump_light((LPD3DLIGHT2) lpLight);
178     }
179
180     if ( (lpLight->dltType == 0) || (lpLight->dltType > D3DLIGHT_PARALLELPOINT) )
181          return DDERR_INVALIDPARAMS;
182     
183     if ( lpLight->dltType == D3DLIGHT_PARALLELPOINT )
184          FIXME("D3DLIGHT_PARALLELPOINT no supported\n");
185     
186     /* Translate D3DLIGH2 structure to D3DLIGHT7 */
187     light7->dltType        = lpLight->dltType;
188     light7->dcvDiffuse     = lpLight->dcvColor;
189     if ((((LPD3DLIGHT2)lpLight)->dwFlags & D3DLIGHT_NO_SPECULAR) != 0)      
190       light7->dcvSpecular    = lpLight->dcvColor;
191     else
192       light7->dcvSpecular    = *(const D3DCOLORVALUE*)zero_value;           
193     light7->dcvAmbient     = lpLight->dcvColor;
194     light7->dvPosition     = lpLight->dvPosition;
195     light7->dvDirection    = lpLight->dvDirection;
196     light7->dvRange        = lpLight->dvRange;
197     light7->dvFalloff      = lpLight->dvFalloff;
198     light7->dvAttenuation0 = lpLight->dvAttenuation0;
199     light7->dvAttenuation1 = lpLight->dvAttenuation1;
200     light7->dvAttenuation2 = lpLight->dvAttenuation2;
201     light7->dvTheta        = lpLight->dvTheta;
202     light7->dvPhi          = lpLight->dvPhi;
203
204     memcpy(&This->light, lpLight, lpLight->dwSize);
205     if ((This->light.dwFlags & D3DLIGHT_ACTIVE) != 0) {
206         This->update(This);        
207     }
208     return D3D_OK;
209 }
210
211 /*****************************************************************************
212  * IDirect3DLight::GetLight
213  *
214  * Returns the parameters currently assigned to the IDirect3DLight object
215  *
216  * Params:
217  *  Light: Pointer to an D3DLIGHT structure to store the parameters
218  *
219  * Returns:
220  *  D3D_OK on success
221  *  DDERR_INVALIDPARAMS if Light is NULL
222  *****************************************************************************/
223 static HRESULT WINAPI
224 IDirect3DLightImpl_GetLight(IDirect3DLight *iface,
225                             D3DLIGHT *lpLight)
226 {
227     ICOM_THIS_FROM(IDirect3DLightImpl, IDirect3DLight, iface);
228     TRACE("(%p/%p)->(%p)\n", This, iface, lpLight);
229     if (TRACE_ON(d3d7)) {
230         TRACE("  Returning light definition :\n");
231         dump_light(&This->light);
232     }
233     memcpy(lpLight, &This->light, lpLight->dwSize);
234     return DD_OK;
235 }
236
237 /*****************************************************************************
238  * light_update
239  *
240  * Updates the Direct3DDevice7 lighting parameters
241  *
242  *****************************************************************************/
243 void light_update(IDirect3DLightImpl* This)
244 {
245     IDirect3DDeviceImpl* device;
246
247     TRACE("(%p)\n", This);
248
249     if (!This->active_viewport || !This->active_viewport->active_device)
250         return;
251     device =  This->active_viewport->active_device;
252
253     IDirect3DDevice7_SetLight(ICOM_INTERFACE(device,IDirect3DDevice7), This->dwLightIndex, &(This->light7));
254 }
255
256 /*****************************************************************************
257  * light_activate
258  *
259  * Uses the Direct3DDevice7::LightEnable method to active the light
260  *
261  *****************************************************************************/
262 void light_activate(IDirect3DLightImpl* This)
263 {
264     IDirect3DDeviceImpl* device;
265
266     TRACE("(%p)\n", This);
267
268     if (!This->active_viewport || !This->active_viewport->active_device)
269         return;
270     device =  This->active_viewport->active_device;
271     
272     light_update(This);
273     /* If was not active, activate it */
274     if ((This->light.dwFlags & D3DLIGHT_ACTIVE) == 0) {
275         IDirect3DDevice7_LightEnable(ICOM_INTERFACE(device,IDirect3DDevice7), This->dwLightIndex, TRUE);
276         This->light.dwFlags |= D3DLIGHT_ACTIVE;
277     }
278 }
279
280 /*****************************************************************************
281  *
282  * light_desactivate
283  *
284  * Uses the Direct3DDevice7::LightEnable method to deactivate the light
285  *
286  *****************************************************************************/
287 void light_desactivate(IDirect3DLightImpl* This)
288 {
289     IDirect3DDeviceImpl* device;
290
291     TRACE("(%p)\n", This);
292
293     if (!This->active_viewport || !This->active_viewport->active_device)
294         return;
295     device =  This->active_viewport->active_device;
296     
297     /* If was not active, activate it */
298     if ((This->light.dwFlags & D3DLIGHT_ACTIVE) != 0) {
299         IDirect3DDevice7_LightEnable(ICOM_INTERFACE(device,IDirect3DDevice7), This->dwLightIndex, FALSE);
300         This->light.dwFlags &= ~D3DLIGHT_ACTIVE;
301     }
302 }
303
304 const IDirect3DLightVtbl IDirect3DLight_Vtbl =
305 {
306     /*** IUnknown Methods ***/
307     IDirect3DLightImpl_QueryInterface,
308     IDirect3DLightImpl_AddRef,
309     IDirect3DLightImpl_Release,
310     /*** IDirect3DLight Methods ***/
311     IDirect3DLightImpl_Initialize,
312     IDirect3DLightImpl_SetLight,
313     IDirect3DLightImpl_GetLight
314 };