dinput: Explicitly define ASCII and Unicode methods in DirectInputDevice base class...
[wine] / dlls / d3d8 / buffer.c
1 /*
2  * Copyright 2005 Oliver Stieber
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 #include "config.h"
20 #include "d3d8_private.h"
21
22 WINE_DEFAULT_DEBUG_CHANNEL(d3d8);
23
24 static HRESULT WINAPI d3d8_vertexbuffer_QueryInterface(IDirect3DVertexBuffer8 *iface, REFIID riid, void **object)
25 {
26     TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
27
28     if (IsEqualGUID(riid, &IID_IDirect3DVertexBuffer8)
29             || IsEqualGUID(riid, &IID_IDirect3DResource8)
30             || IsEqualGUID(riid, &IID_IUnknown))
31     {
32         IUnknown_AddRef(iface);
33         *object = iface;
34         return S_OK;
35     }
36
37     WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
38
39     *object = NULL;
40     return E_NOINTERFACE;
41 }
42
43 static ULONG WINAPI d3d8_vertexbuffer_AddRef(IDirect3DVertexBuffer8 *iface)
44 {
45     IDirect3DVertexBuffer8Impl *buffer = (IDirect3DVertexBuffer8Impl *)iface;
46     ULONG refcount = InterlockedIncrement(&buffer->ref);
47
48     TRACE("%p increasing refcount to %u.\n", iface, refcount);
49
50     if (refcount == 1)
51     {
52         IDirect3DDevice8_AddRef(buffer->parentDevice);
53         wined3d_mutex_lock();
54         IWineD3DBuffer_AddRef(buffer->wineD3DVertexBuffer);
55         wined3d_mutex_unlock();
56     }
57
58     return refcount;
59 }
60
61 static ULONG WINAPI d3d8_vertexbuffer_Release(IDirect3DVertexBuffer8 *iface)
62 {
63     IDirect3DVertexBuffer8Impl *buffer = (IDirect3DVertexBuffer8Impl *)iface;
64     ULONG refcount = InterlockedDecrement(&buffer->ref);
65
66     TRACE("%p decreasing refcount to %u.\n", iface, refcount);
67
68     if (!refcount)
69     {
70         IDirect3DDevice8 *device = buffer->parentDevice;
71
72         wined3d_mutex_lock();
73         IWineD3DBuffer_Release(buffer->wineD3DVertexBuffer);
74         wined3d_mutex_unlock();
75
76         /* Release the device last, as it may cause the device to be destroyed. */
77         IDirect3DDevice8_Release(device);
78     }
79
80     return refcount;
81 }
82
83 static HRESULT WINAPI d3d8_vertexbuffer_GetDevice(IDirect3DVertexBuffer8 *iface, IDirect3DDevice8 **device)
84 {
85     TRACE("iface %p, device %p.\n", iface, device);
86
87     *device = (IDirect3DDevice8 *)((IDirect3DVertexBuffer8Impl *)iface)->parentDevice;
88     IDirect3DDevice8_AddRef(*device);
89
90     TRACE("Returning device %p.\n", *device);
91
92     return D3D_OK;
93 }
94
95 static HRESULT WINAPI d3d8_vertexbuffer_SetPrivateData(IDirect3DVertexBuffer8 *iface,
96         REFGUID guid, const void *data, DWORD data_size, DWORD flags)
97 {
98     HRESULT hr;
99
100     TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
101             iface, debugstr_guid(guid), data, data_size, flags);
102
103     wined3d_mutex_lock();
104     hr = IWineD3DBuffer_SetPrivateData(((IDirect3DVertexBuffer8Impl *)iface)->wineD3DVertexBuffer,
105             guid, data, data_size, flags);
106     wined3d_mutex_unlock();
107
108     return hr;
109 }
110
111 static HRESULT WINAPI d3d8_vertexbuffer_GetPrivateData(IDirect3DVertexBuffer8 *iface,
112         REFGUID guid, void *data, DWORD *data_size)
113 {
114     HRESULT hr;
115
116     TRACE("iface %p, guid %s, data %p, data_size %p.\n",
117             iface, debugstr_guid(guid), data, data_size);
118
119     wined3d_mutex_lock();
120     hr = IWineD3DBuffer_GetPrivateData(((IDirect3DVertexBuffer8Impl *)iface)->wineD3DVertexBuffer,
121             guid, data, data_size);
122     wined3d_mutex_unlock();
123
124     return hr;
125 }
126
127 static HRESULT WINAPI d3d8_vertexbuffer_FreePrivateData(IDirect3DVertexBuffer8 *iface, REFGUID guid)
128 {
129     HRESULT hr;
130
131     TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
132
133     wined3d_mutex_lock();
134     hr = IWineD3DBuffer_FreePrivateData(((IDirect3DVertexBuffer8Impl *)iface)->wineD3DVertexBuffer, guid);
135     wined3d_mutex_unlock();
136
137     return hr;
138 }
139
140 static DWORD WINAPI d3d8_vertexbuffer_SetPriority(IDirect3DVertexBuffer8 *iface, DWORD priority)
141 {
142     DWORD previous;
143
144     TRACE("iface %p, priority %u.\n", iface, priority);
145
146     wined3d_mutex_lock();
147     previous = IWineD3DBuffer_SetPriority(((IDirect3DVertexBuffer8Impl *)iface)->wineD3DVertexBuffer, priority);
148     wined3d_mutex_unlock();
149
150     return previous;
151 }
152
153 static DWORD WINAPI d3d8_vertexbuffer_GetPriority(IDirect3DVertexBuffer8 *iface)
154 {
155     DWORD priority;
156
157     TRACE("iface %p.\n", iface);
158
159     wined3d_mutex_lock();
160     priority = IWineD3DBuffer_GetPriority(((IDirect3DVertexBuffer8Impl *)iface)->wineD3DVertexBuffer);
161     wined3d_mutex_unlock();
162
163     return priority;
164 }
165
166 static void WINAPI d3d8_vertexbuffer_PreLoad(IDirect3DVertexBuffer8 *iface)
167 {
168     TRACE("iface %p.\n", iface);
169
170     wined3d_mutex_lock();
171     IWineD3DBuffer_PreLoad(((IDirect3DVertexBuffer8Impl *)iface)->wineD3DVertexBuffer);
172     wined3d_mutex_unlock();
173 }
174
175 static D3DRESOURCETYPE WINAPI d3d8_vertexbuffer_GetType(IDirect3DVertexBuffer8 *iface)
176 {
177     TRACE("iface %p.\n", iface);
178
179     return D3DRTYPE_VERTEXBUFFER;
180 }
181
182 static HRESULT WINAPI d3d8_vertexbuffer_Lock(IDirect3DVertexBuffer8 *iface,
183         UINT offset, UINT size, BYTE **data, DWORD flags)
184 {
185     HRESULT hr;
186
187     TRACE("iface %p, offset %u, size %u, data %p, flags %#x.\n",
188             iface, offset, size, data, flags);
189
190     wined3d_mutex_lock();
191     hr = IWineD3DBuffer_Map(((IDirect3DVertexBuffer8Impl *)iface)->wineD3DVertexBuffer,
192             offset, size, data, flags);
193     wined3d_mutex_unlock();
194
195     return hr;
196 }
197
198 static HRESULT WINAPI d3d8_vertexbuffer_Unlock(IDirect3DVertexBuffer8 *iface)
199 {
200     TRACE("iface %p.\n", iface);
201
202     wined3d_mutex_lock();
203     IWineD3DBuffer_Unmap(((IDirect3DVertexBuffer8Impl *)iface)->wineD3DVertexBuffer);
204     wined3d_mutex_unlock();
205
206     return D3D_OK;
207 }
208
209 static HRESULT WINAPI d3d8_vertexbuffer_GetDesc(IDirect3DVertexBuffer8 *iface, D3DVERTEXBUFFER_DESC *desc)
210 {
211     IDirect3DVertexBuffer8Impl *buffer = (IDirect3DVertexBuffer8Impl *)iface;
212     WINED3DBUFFER_DESC wined3d_desc;
213
214     TRACE("iface %p, desc %p.\n", iface, desc);
215
216     wined3d_mutex_lock();
217     IWineD3DBuffer_GetDesc(buffer->wineD3DVertexBuffer, &wined3d_desc);
218     wined3d_mutex_unlock();
219
220     desc->Type = D3DRTYPE_VERTEXBUFFER;
221     desc->Usage = wined3d_desc.Usage;
222     desc->Pool = wined3d_desc.Pool;
223     desc->Size = wined3d_desc.Size;
224     desc->FVF = buffer->fvf;
225     desc->Format = D3DFMT_VERTEXDATA;
226
227     return D3D_OK;
228 }
229
230 static const IDirect3DVertexBuffer8Vtbl Direct3DVertexBuffer8_Vtbl =
231 {
232     /* IUnknown */
233     d3d8_vertexbuffer_QueryInterface,
234     d3d8_vertexbuffer_AddRef,
235     d3d8_vertexbuffer_Release,
236     /* IDirect3DResource8 */
237     d3d8_vertexbuffer_GetDevice,
238     d3d8_vertexbuffer_SetPrivateData,
239     d3d8_vertexbuffer_GetPrivateData,
240     d3d8_vertexbuffer_FreePrivateData,
241     d3d8_vertexbuffer_SetPriority,
242     d3d8_vertexbuffer_GetPriority,
243     d3d8_vertexbuffer_PreLoad,
244     d3d8_vertexbuffer_GetType,
245     /* IDirect3DVertexBuffer8 */
246     d3d8_vertexbuffer_Lock,
247     d3d8_vertexbuffer_Unlock,
248     d3d8_vertexbuffer_GetDesc,
249 };
250
251 static void STDMETHODCALLTYPE d3d8_vertexbuffer_wined3d_object_destroyed(void *parent)
252 {
253     HeapFree(GetProcessHeap(), 0, parent);
254 }
255
256 static const struct wined3d_parent_ops d3d8_vertexbuffer_wined3d_parent_ops =
257 {
258     d3d8_vertexbuffer_wined3d_object_destroyed,
259 };
260
261 HRESULT vertexbuffer_init(IDirect3DVertexBuffer8Impl *buffer, IDirect3DDevice8Impl *device,
262         UINT size, DWORD usage, DWORD fvf, D3DPOOL pool)
263 {
264     HRESULT hr;
265
266     buffer->lpVtbl = &Direct3DVertexBuffer8_Vtbl;
267     buffer->ref = 1;
268     buffer->fvf = fvf;
269
270     wined3d_mutex_lock();
271     hr = IWineD3DDevice_CreateVertexBuffer(device->WineD3DDevice, size, usage & WINED3DUSAGE_MASK,
272             (WINED3DPOOL)pool, buffer, &d3d8_vertexbuffer_wined3d_parent_ops, &buffer->wineD3DVertexBuffer);
273     wined3d_mutex_unlock();
274     if (FAILED(hr))
275     {
276         WARN("Failed to create wined3d buffer, hr %#x.\n", hr);
277         return hr;
278     }
279
280     buffer->parentDevice = (IDirect3DDevice8 *)device;
281     IUnknown_AddRef(buffer->parentDevice);
282
283     return D3D_OK;
284 }
285
286 static HRESULT WINAPI d3d8_indexbuffer_QueryInterface(IDirect3DIndexBuffer8 *iface, REFIID riid, void **object)
287 {
288     TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
289
290     if (IsEqualGUID(riid, &IID_IDirect3DIndexBuffer8)
291             || IsEqualGUID(riid, &IID_IDirect3DResource8)
292             || IsEqualGUID(riid, &IID_IUnknown))
293     {
294         IUnknown_AddRef(iface);
295         *object = iface;
296         return S_OK;
297     }
298
299     WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
300
301     *object = NULL;
302     return E_NOINTERFACE;
303 }
304
305 static ULONG WINAPI d3d8_indexbuffer_AddRef(IDirect3DIndexBuffer8 *iface)
306 {
307     IDirect3DIndexBuffer8Impl *buffer = (IDirect3DIndexBuffer8Impl *)iface;
308     ULONG refcount = InterlockedIncrement(&buffer->ref);
309
310     TRACE("%p increasing refcount to %u.\n", iface, refcount);
311
312     if (refcount == 1)
313     {
314         IDirect3DDevice8_AddRef(buffer->parentDevice);
315         wined3d_mutex_lock();
316         IWineD3DBuffer_AddRef(buffer->wineD3DIndexBuffer);
317         wined3d_mutex_unlock();
318     }
319
320     return refcount;
321 }
322
323 static ULONG WINAPI d3d8_indexbuffer_Release(IDirect3DIndexBuffer8 *iface)
324 {
325     IDirect3DIndexBuffer8Impl *buffer = (IDirect3DIndexBuffer8Impl *)iface;
326     ULONG refcount = InterlockedDecrement(&buffer->ref);
327
328     TRACE("%p decreasing refcount to %u.\n", iface, refcount);
329
330     if (!refcount)
331     {
332         IDirect3DDevice8 *device = buffer->parentDevice;
333
334         wined3d_mutex_lock();
335         IWineD3DBuffer_Release(buffer->wineD3DIndexBuffer);
336         wined3d_mutex_unlock();
337
338         /* Release the device last, as it may cause the device to be destroyed. */
339         IDirect3DDevice8_Release(device);
340     }
341
342     return refcount;
343 }
344
345 static HRESULT WINAPI d3d8_indexbuffer_GetDevice(IDirect3DIndexBuffer8 *iface, IDirect3DDevice8 **device)
346 {
347     TRACE("iface %p, device %p.\n", iface, device);
348
349     *device = (IDirect3DDevice8 *)((IDirect3DIndexBuffer8Impl *)iface)->parentDevice;
350     IDirect3DDevice8_AddRef(*device);
351
352     TRACE("Returning device %p.\n", *device);
353
354     return D3D_OK;
355 }
356
357 static HRESULT WINAPI d3d8_indexbuffer_SetPrivateData(IDirect3DIndexBuffer8 *iface,
358         REFGUID guid, const void *data, DWORD data_size, DWORD flags)
359 {
360     HRESULT hr;
361
362     TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
363             iface, debugstr_guid(guid), data, data_size, flags);
364
365     wined3d_mutex_lock();
366     hr = IWineD3DBuffer_SetPrivateData(((IDirect3DIndexBuffer8Impl *)iface)->wineD3DIndexBuffer,
367             guid, data, data_size, flags);
368     wined3d_mutex_unlock();
369
370     return hr;
371 }
372
373 static HRESULT WINAPI d3d8_indexbuffer_GetPrivateData(IDirect3DIndexBuffer8 *iface,
374         REFGUID guid, void *data, DWORD *data_size)
375 {
376     HRESULT hr;
377
378     TRACE("iface %p, guid %s, data %p, data_size %p.\n",
379             iface, debugstr_guid(guid), data, data_size);
380
381     wined3d_mutex_lock();
382     hr = IWineD3DBuffer_GetPrivateData(((IDirect3DIndexBuffer8Impl *)iface)->wineD3DIndexBuffer,
383             guid, data, data_size);
384     wined3d_mutex_unlock();
385
386     return hr;
387 }
388
389 static HRESULT WINAPI d3d8_indexbuffer_FreePrivateData(IDirect3DIndexBuffer8 *iface, REFGUID guid)
390 {
391     HRESULT hr;
392
393     TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
394
395     wined3d_mutex_lock();
396     hr = IWineD3DBuffer_FreePrivateData(((IDirect3DIndexBuffer8Impl *)iface)->wineD3DIndexBuffer, guid);
397     wined3d_mutex_unlock();
398
399     return hr;
400 }
401
402 static DWORD WINAPI d3d8_indexbuffer_SetPriority(IDirect3DIndexBuffer8 *iface, DWORD priority)
403 {
404     DWORD previous;
405
406     TRACE("iface %p, priority %u.\n", iface, priority);
407
408     wined3d_mutex_lock();
409     previous = IWineD3DBuffer_SetPriority(((IDirect3DIndexBuffer8Impl *)iface)->wineD3DIndexBuffer, priority);
410     wined3d_mutex_unlock();
411
412     return previous;
413 }
414
415 static DWORD WINAPI d3d8_indexbuffer_GetPriority(IDirect3DIndexBuffer8 *iface)
416 {
417     DWORD priority;
418
419     TRACE("iface %p.\n", iface);
420
421     wined3d_mutex_lock();
422     priority = IWineD3DBuffer_GetPriority(((IDirect3DIndexBuffer8Impl *)iface)->wineD3DIndexBuffer);
423     wined3d_mutex_unlock();
424
425     return priority;
426 }
427
428 static void WINAPI d3d8_indexbuffer_PreLoad(IDirect3DIndexBuffer8 *iface)
429 {
430     TRACE("iface %p.\n", iface);
431
432     wined3d_mutex_lock();
433     IWineD3DBuffer_PreLoad(((IDirect3DIndexBuffer8Impl *)iface)->wineD3DIndexBuffer);
434     wined3d_mutex_unlock();
435 }
436
437 static D3DRESOURCETYPE WINAPI d3d8_indexbuffer_GetType(IDirect3DIndexBuffer8 *iface)
438 {
439     TRACE("iface %p.\n", iface);
440
441     return D3DRTYPE_INDEXBUFFER;
442 }
443
444 static HRESULT WINAPI d3d8_indexbuffer_Lock(IDirect3DIndexBuffer8 *iface,
445         UINT offset, UINT size, BYTE **data, DWORD flags)
446 {
447     HRESULT hr;
448
449     TRACE("iface %p, offset %u, size %u, data %p, flags %#x.\n",
450             iface, offset, size, data, flags);
451
452     wined3d_mutex_lock();
453     hr = IWineD3DBuffer_Map(((IDirect3DIndexBuffer8Impl *)iface)->wineD3DIndexBuffer,
454             offset, size, data, flags);
455     wined3d_mutex_unlock();
456
457     return hr;
458 }
459
460 static HRESULT WINAPI d3d8_indexbuffer_Unlock(IDirect3DIndexBuffer8 *iface)
461 {
462     TRACE("iface %p.\n", iface);
463
464     wined3d_mutex_lock();
465     IWineD3DBuffer_Unmap(((IDirect3DIndexBuffer8Impl *)iface)->wineD3DIndexBuffer);
466     wined3d_mutex_unlock();
467
468     return D3D_OK;
469 }
470
471 static HRESULT WINAPI d3d8_indexbuffer_GetDesc(IDirect3DIndexBuffer8 *iface, D3DINDEXBUFFER_DESC *desc)
472 {
473     IDirect3DIndexBuffer8Impl *buffer = (IDirect3DIndexBuffer8Impl *)iface;
474     WINED3DBUFFER_DESC wined3d_desc;
475
476     TRACE("iface %p, desc %p.\n", iface, desc);
477
478     wined3d_mutex_lock();
479     IWineD3DBuffer_GetDesc(buffer->wineD3DIndexBuffer, &wined3d_desc);
480     wined3d_mutex_unlock();
481
482     desc->Format = d3dformat_from_wined3dformat(buffer->format);
483     desc->Type = D3DRTYPE_INDEXBUFFER;
484     desc->Usage = wined3d_desc.Usage;
485     desc->Pool = wined3d_desc.Pool;
486     desc->Size = wined3d_desc.Size;
487
488     return D3D_OK;
489 }
490
491 static const IDirect3DIndexBuffer8Vtbl d3d8_indexbuffer_vtbl =
492 {
493     /* IUnknown */
494     d3d8_indexbuffer_QueryInterface,
495     d3d8_indexbuffer_AddRef,
496     d3d8_indexbuffer_Release,
497     /* IDirect3DResource8 */
498     d3d8_indexbuffer_GetDevice,
499     d3d8_indexbuffer_SetPrivateData,
500     d3d8_indexbuffer_GetPrivateData,
501     d3d8_indexbuffer_FreePrivateData,
502     d3d8_indexbuffer_SetPriority,
503     d3d8_indexbuffer_GetPriority,
504     d3d8_indexbuffer_PreLoad,
505     d3d8_indexbuffer_GetType,
506     /* IDirect3DIndexBuffer8 */
507     d3d8_indexbuffer_Lock,
508     d3d8_indexbuffer_Unlock,
509     d3d8_indexbuffer_GetDesc,
510 };
511
512 static void STDMETHODCALLTYPE d3d8_indexbuffer_wined3d_object_destroyed(void *parent)
513 {
514     HeapFree(GetProcessHeap(), 0, parent);
515 }
516
517 static const struct wined3d_parent_ops d3d8_indexbuffer_wined3d_parent_ops =
518 {
519     d3d8_indexbuffer_wined3d_object_destroyed,
520 };
521
522 HRESULT indexbuffer_init(IDirect3DIndexBuffer8Impl *buffer, IDirect3DDevice8Impl *device,
523         UINT size, DWORD usage, D3DFORMAT format, D3DPOOL pool)
524 {
525     HRESULT hr;
526
527     buffer->lpVtbl = &d3d8_indexbuffer_vtbl;
528     buffer->ref = 1;
529     buffer->format = wined3dformat_from_d3dformat(format);
530
531     wined3d_mutex_lock();
532     hr = IWineD3DDevice_CreateIndexBuffer(device->WineD3DDevice, size, usage & WINED3DUSAGE_MASK,
533             (WINED3DPOOL)pool, buffer, &d3d8_indexbuffer_wined3d_parent_ops, &buffer->wineD3DIndexBuffer);
534     wined3d_mutex_unlock();
535     if (FAILED(hr))
536     {
537         WARN("Failed to create wined3d buffer, hr %#x.\n", hr);
538         return hr;
539     }
540
541     buffer->parentDevice = (IDirect3DDevice8 *)device;
542     IUnknown_AddRef(buffer->parentDevice);
543
544     return D3D_OK;
545 }