d3dx9_36/tests: Use assignment instead of memcpy to copy a struct.
[wine] / dlls / d3dx9_36 / line.c
1 /*
2  * Copyright 2010 Christian Costa
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  *
18  */
19
20 #include "wine/debug.h"
21 #include "d3dx9_36_private.h"
22
23 WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
24
25 static const struct ID3DXLineVtbl ID3DXLine_Vtbl;
26
27 typedef struct ID3DXLineImpl {
28     ID3DXLine ID3DXLine_iface;
29     LONG ref;
30
31     IDirect3DDevice9 *device;
32     IDirect3DStateBlock9 *state;
33 } ID3DXLineImpl;
34
35 static inline ID3DXLineImpl *impl_from_ID3DXLine(ID3DXLine *iface)
36 {
37     return CONTAINING_RECORD(iface, ID3DXLineImpl, ID3DXLine_iface);
38 }
39
40 /*** IUnknown methods ***/
41 static HRESULT WINAPI ID3DXLineImpl_QueryInterface(ID3DXLine* iface, REFIID riid, LPVOID* object)
42 {
43     TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), object);
44
45     if (IsEqualGUID(riid, &IID_IUnknown) ||
46         IsEqualGUID(riid, &IID_ID3DXLine))
47     {
48         ID3DXLine_AddRef(iface);
49         *object = iface;
50         return S_OK;
51     }
52
53     ERR("Interface %s not found\n", debugstr_guid(riid));
54
55     return E_NOINTERFACE;
56 }
57
58 static ULONG WINAPI ID3DXLineImpl_AddRef(ID3DXLine* iface)
59 {
60     ID3DXLineImpl *This = impl_from_ID3DXLine(iface);
61
62     TRACE("(%p)->(): AddRef from %u\n", This, This->ref);
63
64     return InterlockedIncrement(&This->ref);
65 }
66
67 static ULONG WINAPI ID3DXLineImpl_Release(ID3DXLine* iface)
68 {
69     ID3DXLineImpl *This = impl_from_ID3DXLine(iface);
70     ULONG ref = InterlockedDecrement(&This->ref);
71
72     TRACE("(%p)->(): Release from %u\n", This, ref + 1);
73
74     if (!ref)
75     {
76         IDirect3DDevice9_Release(This->device);
77         HeapFree(GetProcessHeap(), 0, This);
78     }
79
80     return ref;
81 }
82
83 /*** ID3DXLine methods ***/
84 static HRESULT WINAPI ID3DXLineImpl_GetDevice(struct ID3DXLine *iface, struct IDirect3DDevice9 **device)
85 {
86     ID3DXLineImpl *This = impl_from_ID3DXLine(iface);
87
88     TRACE ("(%p)->(%p): relay\n", This, device);
89
90     if (device == NULL) return D3DERR_INVALIDCALL;
91
92     *device = This->device;
93     IDirect3DDevice9_AddRef(This->device);
94
95     return D3D_OK;
96 }
97
98 static HRESULT WINAPI ID3DXLineImpl_Begin(ID3DXLine* iface)
99 {
100     ID3DXLineImpl *This = impl_from_ID3DXLine(iface);
101
102     HRESULT hr;
103     D3DXMATRIX identity, projection;
104     D3DVIEWPORT9 vp;
105
106     TRACE ("(%p)->()\n", This);
107
108     if (This->state != NULL) /* We already began. Return error. */
109         return D3DERR_INVALIDCALL;
110
111     hr = IDirect3DDevice9_CreateStateBlock(This->device, D3DSBT_ALL, &This->state);
112     if (FAILED(hr)) return D3DXERR_INVALIDDATA;
113
114     hr = IDirect3DDevice9_GetViewport(This->device, &vp);
115     if (FAILED(hr)) goto failed;
116
117     D3DXMatrixIdentity(&identity);
118     D3DXMatrixOrthoOffCenterLH(&projection,
119                                0.0, vp.Width, /* Min and max x */
120                                vp.Height, 0.0, /* Min and max y. Screen y is on top so this is inverted */
121                                0.0, 1.0); /* Min and max z */
122
123     hr = IDirect3DDevice9_SetTransform(This->device, D3DTS_WORLD, &identity);
124     if (FAILED(hr)) goto failed;
125
126     hr = IDirect3DDevice9_SetTransform(This->device, D3DTS_VIEW, &identity);
127     if (FAILED(hr)) goto failed;
128
129     hr = IDirect3DDevice9_SetTransform(This->device, D3DTS_PROJECTION, &projection);
130     if (FAILED(hr)) goto failed;
131
132     /* Windows sets similar states so we do the same */
133
134     hr = IDirect3DDevice9_SetRenderState(This->device, D3DRS_LIGHTING, FALSE);
135     if (FAILED(hr)) goto failed;
136
137     hr = IDirect3DDevice9_SetRenderState(This->device, D3DRS_FOGENABLE, FALSE);
138     if (FAILED(hr)) goto failed;
139
140     hr = IDirect3DDevice9_SetRenderState(This->device, D3DRS_SHADEMODE, D3DSHADE_FLAT);
141     if (FAILED(hr)) goto failed;
142
143     hr = IDirect3DDevice9_SetRenderState(This->device, D3DRS_ALPHABLENDENABLE, TRUE);
144     if (FAILED(hr)) goto failed;
145
146     hr = IDirect3DDevice9_SetRenderState(This->device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
147     if (FAILED(hr)) goto failed;
148
149     hr = IDirect3DDevice9_SetRenderState(This->device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
150     if (FAILED(hr)) goto failed;
151
152     return D3D_OK;
153 failed:
154     IDirect3DStateBlock9_Apply(This->state);
155     IDirect3DStateBlock9_Release(This->state);
156     This->state = NULL;
157     return D3DXERR_INVALIDDATA;
158 }
159
160 static HRESULT WINAPI ID3DXLineImpl_Draw(ID3DXLine* iface, CONST D3DXVECTOR2* vertexlist, DWORD vertexlistcount, D3DCOLOR color)
161 {
162     ID3DXLineImpl *This = impl_from_ID3DXLine(iface);
163
164     FIXME("(%p)->(%p, %u, %#x): stub\n", This, vertexlist, vertexlistcount, color);
165
166     return E_NOTIMPL;
167 }
168
169 static HRESULT WINAPI ID3DXLineImpl_DrawTransform(ID3DXLine* iface, CONST D3DXVECTOR3* vertexlist, DWORD vertexlistcount,
170                                                   CONST D3DXMATRIX* transform, D3DCOLOR color)
171 {
172     ID3DXLineImpl *This = impl_from_ID3DXLine(iface);
173
174     FIXME("(%p)->(%p, %u, %p, %#x): stub\n", This, vertexlist, vertexlistcount, transform, color);
175
176     return E_NOTIMPL;
177 }
178
179 static HRESULT WINAPI ID3DXLineImpl_SetPattern(ID3DXLine* iface, DWORD pattern)
180 {
181     ID3DXLineImpl *This = impl_from_ID3DXLine(iface);
182
183     FIXME("(%p)->(%#x): stub\n", This, pattern);
184
185     return E_NOTIMPL;
186 }
187
188 static DWORD WINAPI ID3DXLineImpl_GetPattern(ID3DXLine* iface)
189 {
190     ID3DXLineImpl *This = impl_from_ID3DXLine(iface);
191
192     FIXME("(%p)->(): stub\n", This);
193
194     return 0xFFFFFFFF;
195 }
196
197 static HRESULT WINAPI ID3DXLineImpl_SetPatternScale(ID3DXLine* iface, FLOAT scale)
198 {
199     ID3DXLineImpl *This = impl_from_ID3DXLine(iface);
200
201     FIXME("(%p)->(%f): stub\n", This, scale);
202
203     return E_NOTIMPL;
204 }
205
206 static FLOAT WINAPI ID3DXLineImpl_GetPatternScale(ID3DXLine* iface)
207 {
208     ID3DXLineImpl *This = impl_from_ID3DXLine(iface);
209
210     FIXME("(%p)->(): stub\n", This);
211
212     return 1.0f;
213 }
214
215 static HRESULT WINAPI ID3DXLineImpl_SetWidth(ID3DXLine* iface, FLOAT width)
216 {
217     ID3DXLineImpl *This = impl_from_ID3DXLine(iface);
218
219     FIXME("(%p)->(%f): stub\n", This, width);
220
221     return E_NOTIMPL;
222 }
223
224 static FLOAT WINAPI ID3DXLineImpl_GetWidth(ID3DXLine* iface)
225 {
226     ID3DXLineImpl *This = impl_from_ID3DXLine(iface);
227
228     FIXME("(%p)->(): stub\n", This);
229
230     return 1.0f;
231 }
232
233 static HRESULT WINAPI ID3DXLineImpl_SetAntialias(ID3DXLine* iface, BOOL antialias)
234 {
235     ID3DXLineImpl *This = impl_from_ID3DXLine(iface);
236
237     FIXME("(%p)->(%u): stub\n", This, antialias);
238
239     return E_NOTIMPL;
240 }
241
242 static BOOL WINAPI ID3DXLineImpl_GetAntialias(ID3DXLine* iface)
243 {
244     ID3DXLineImpl *This = impl_from_ID3DXLine(iface);
245
246     FIXME("(%p)->(): stub\n", This);
247
248     return FALSE;
249 }
250
251 static HRESULT WINAPI ID3DXLineImpl_SetGLLines(ID3DXLine* iface, BOOL gl_lines)
252 {
253     ID3DXLineImpl *This = impl_from_ID3DXLine(iface);
254
255     FIXME("(%p)->(%u): stub\n", This, gl_lines);
256
257     return E_NOTIMPL;
258 }
259
260 static BOOL WINAPI ID3DXLineImpl_GetGLLines(ID3DXLine* iface)
261 {
262     ID3DXLineImpl *This = impl_from_ID3DXLine(iface);
263
264     FIXME("(%p)->(): stub\n", This);
265
266     return FALSE;
267 }
268
269 static HRESULT WINAPI ID3DXLineImpl_End(ID3DXLine* iface)
270 {
271     ID3DXLineImpl *This = impl_from_ID3DXLine(iface);
272
273     HRESULT hr;
274
275     TRACE ("(%p)->()\n", This);
276
277     if (This->state == NULL) /* We haven't begun yet. */
278         return D3DERR_INVALIDCALL;
279
280     hr = IDirect3DStateBlock9_Apply(This->state);
281     IDirect3DStateBlock9_Release(This->state);
282     This->state = NULL;
283
284     if (FAILED(hr)) return D3DXERR_INVALIDDATA;
285     else return D3D_OK;
286 }
287
288 static HRESULT WINAPI ID3DXLineImpl_OnLostDevice(ID3DXLine* iface)
289 {
290     ID3DXLineImpl *This = impl_from_ID3DXLine(iface);
291
292     FIXME("(%p)->(): stub\n", This);
293
294     return E_NOTIMPL;
295 }
296 static HRESULT WINAPI ID3DXLineImpl_OnResetDevice(ID3DXLine* iface)
297 {
298     ID3DXLineImpl *This = impl_from_ID3DXLine(iface);
299
300     FIXME("(%p)->(): stub\n", This);
301
302     return E_NOTIMPL;
303 }
304
305 static const struct ID3DXLineVtbl ID3DXLine_Vtbl =
306 {
307     /*** IUnknown methods ***/
308     ID3DXLineImpl_QueryInterface,
309     ID3DXLineImpl_AddRef,
310     ID3DXLineImpl_Release,
311     /*** ID3DXLine methods ***/
312     ID3DXLineImpl_GetDevice,
313     ID3DXLineImpl_Begin,
314     ID3DXLineImpl_Draw,
315     ID3DXLineImpl_DrawTransform,
316     ID3DXLineImpl_SetPattern,
317     ID3DXLineImpl_GetPattern,
318     ID3DXLineImpl_SetPatternScale,
319     ID3DXLineImpl_GetPatternScale,
320     ID3DXLineImpl_SetWidth,
321     ID3DXLineImpl_GetWidth,
322     ID3DXLineImpl_SetAntialias,
323     ID3DXLineImpl_GetAntialias,
324     ID3DXLineImpl_SetGLLines,
325     ID3DXLineImpl_GetGLLines,
326     ID3DXLineImpl_End,
327     ID3DXLineImpl_OnLostDevice,
328     ID3DXLineImpl_OnResetDevice
329 };
330
331 HRESULT WINAPI D3DXCreateLine(struct IDirect3DDevice9 *device, struct ID3DXLine **line)
332 {
333     ID3DXLineImpl* object;
334
335     TRACE("(%p, %p)\n", device, line);
336
337     if (!device || !line)
338         return D3DERR_INVALIDCALL;
339
340     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ID3DXLineImpl));
341     if (!object)
342     {
343         ERR("Out of memory\n");
344         return E_OUTOFMEMORY;
345     }
346
347     object->ID3DXLine_iface.lpVtbl = &ID3DXLine_Vtbl;
348     object->ref = 1;
349     object->device = device;
350     object->state = NULL; /* We only initialize it on Begin */
351     IDirect3DDevice9_AddRef(device);
352
353     *line = &object->ID3DXLine_iface;
354
355     return D3D_OK;
356 }