d3dx9_36: Implement ID3DXFileDataImpl_IsReference.
[wine/multimedia.git] / dlls / d3dx9_36 / xfile.c
blob81f9da35ddabeb5ac573f230510228e13cc62233
1 /*
2 * Copyright (C) 2012 Christian Costa
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.
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.
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
20 #include "wine/debug.h"
22 #include "d3dx9.h"
23 #include "d3dx9xof.h"
24 #undef MAKE_DDHRESULT
25 #include "dxfile.h"
27 WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
29 static HRESULT error_dxfile_to_d3dxfile(HRESULT error)
31 switch (error)
33 case DXFILEERR_BADFILETYPE:
34 return D3DXFERR_BADFILETYPE;
35 case DXFILEERR_BADFILEVERSION:
36 return D3DXFERR_BADFILEVERSION;
37 case DXFILEERR_BADFILEFLOATSIZE:
38 return D3DXFERR_BADFILEFLOATSIZE;
39 case DXFILEERR_PARSEERROR:
40 return D3DXFERR_PARSEERROR;
41 default:
42 FIXME("Cannot map error %#x\n", error);
43 return E_FAIL;
47 typedef struct {
48 ID3DXFile ID3DXFile_iface;
49 LONG ref;
50 IDirectXFile *dxfile;
51 } ID3DXFileImpl;
53 typedef struct {
54 ID3DXFileEnumObject ID3DXFileEnumObject_iface;
55 LONG ref;
56 ULONG nb_children;
57 ID3DXFileData **children;
58 } ID3DXFileEnumObjectImpl;
60 typedef struct {
61 ID3DXFileData ID3DXFileData_iface;
62 LONG ref;
63 BOOL reference;
64 IDirectXFileData *dxfile_data;
65 ULONG nb_children;
66 ID3DXFileData **children;
67 } ID3DXFileDataImpl;
70 static inline ID3DXFileImpl* impl_from_ID3DXFile(ID3DXFile *iface)
72 return CONTAINING_RECORD(iface, ID3DXFileImpl, ID3DXFile_iface);
75 static inline ID3DXFileEnumObjectImpl* impl_from_ID3DXFileEnumObject(ID3DXFileEnumObject *iface)
77 return CONTAINING_RECORD(iface, ID3DXFileEnumObjectImpl, ID3DXFileEnumObject_iface);
80 static inline ID3DXFileDataImpl* impl_from_ID3DXFileData(ID3DXFileData *iface)
82 return CONTAINING_RECORD(iface, ID3DXFileDataImpl, ID3DXFileData_iface);
85 /*** IUnknown methods ***/
87 static HRESULT WINAPI ID3DXFileDataImpl_QueryInterface(ID3DXFileData *iface, REFIID riid, void **ret_iface)
89 TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ret_iface);
91 if (IsEqualGUID(riid, &IID_IUnknown) ||
92 IsEqualGUID(riid, &IID_ID3DXFileData))
94 iface->lpVtbl->AddRef(iface);
95 *ret_iface = iface;
96 return S_OK;
99 WARN("(%p)->(%s, %p), not found\n", iface, debugstr_guid(riid), ret_iface);
100 *ret_iface = NULL;
101 return E_NOINTERFACE;
104 static ULONG WINAPI ID3DXFileDataImpl_AddRef(ID3DXFileData *iface)
106 ID3DXFileDataImpl *This = impl_from_ID3DXFileData(iface);
107 ULONG ref = InterlockedIncrement(&This->ref);
109 TRACE("(%p)->(): new ref = %u\n", iface, ref);
111 return ref;
114 static ULONG WINAPI ID3DXFileDataImpl_Release(ID3DXFileData *iface)
116 ID3DXFileDataImpl *This = impl_from_ID3DXFileData(iface);
117 ULONG ref = InterlockedDecrement(&This->ref);
119 TRACE("(%p)->(): new ref = %u\n", iface, ref);
121 if (!ref)
123 ULONG i;
125 for (i = 0; i < This->nb_children; i++)
126 (This->children[i])->lpVtbl->Release(This->children[i]);
127 HeapFree(GetProcessHeap(), 0, This->children);
128 IDirectXFileData_Release(This->dxfile_data);
129 HeapFree(GetProcessHeap(), 0, This);
132 return ref;
136 /*** ID3DXFileData methods ***/
138 static HRESULT WINAPI ID3DXFileDataImpl_GetEnum(ID3DXFileData *iface, ID3DXFileEnumObject **enum_object)
140 FIXME("(%p)->(%p): stub\n", iface, enum_object);
142 return E_NOTIMPL;
146 static HRESULT WINAPI ID3DXFileDataImpl_GetName(ID3DXFileData *iface, char *name, SIZE_T *size)
148 ID3DXFileDataImpl *This = impl_from_ID3DXFileData(iface);
149 DWORD dxfile_size;
150 HRESULT ret;
152 TRACE("(%p)->(%p, %p)\n", iface, name, size);
154 if (!name || !size)
155 return E_POINTER;
157 dxfile_size = *size;
159 ret = IDirectXFileData_GetName(This->dxfile_data, name, &dxfile_size);
160 if (ret != DXFILE_OK)
161 return error_dxfile_to_d3dxfile(ret);
163 *size = dxfile_size;
165 return S_OK;
169 static HRESULT WINAPI ID3DXFileDataImpl_GetId(ID3DXFileData *iface, GUID *guid)
171 ID3DXFileDataImpl *This = impl_from_ID3DXFileData(iface);
172 HRESULT ret;
174 TRACE("(%p)->(%p)\n", iface, guid);
176 if (!guid)
177 return E_POINTER;
179 ret = IDirectXFileData_GetId(This->dxfile_data, guid);
180 if (ret != DXFILE_OK)
181 return error_dxfile_to_d3dxfile(ret);
183 return S_OK;
187 static HRESULT WINAPI ID3DXFileDataImpl_Lock(ID3DXFileData *iface, SIZE_T *size, const void **data)
189 ID3DXFileDataImpl *This = impl_from_ID3DXFileData(iface);
190 DWORD dxfile_size;
191 HRESULT ret;
193 TRACE("(%p)->(%p, %p)\n", iface, size, data);
195 if (!size || !data)
196 return E_POINTER;
198 ret = IDirectXFileData_GetData(This->dxfile_data, NULL, &dxfile_size, (void**)data);
199 if (ret != DXFILE_OK)
200 return error_dxfile_to_d3dxfile(ret);
202 *size = dxfile_size;
204 return S_OK;
208 static HRESULT WINAPI ID3DXFileDataImpl_Unlock(ID3DXFileData *iface)
210 TRACE("(%p)->()\n", iface);
212 /* Nothing to do */
214 return S_OK;
218 static HRESULT WINAPI ID3DXFileDataImpl_GetType(ID3DXFileData *iface, GUID *guid)
220 ID3DXFileDataImpl *This = impl_from_ID3DXFileData(iface);
221 const GUID *dxfile_guid;
222 HRESULT ret;
224 TRACE("(%p)->(%p)\n", iface, guid);
226 ret = IDirectXFileData_GetType(This->dxfile_data, &dxfile_guid);
227 if (ret != DXFILE_OK)
228 return error_dxfile_to_d3dxfile(ret);
230 *guid = *dxfile_guid;
232 return S_OK;
236 static BOOL WINAPI ID3DXFileDataImpl_IsReference(ID3DXFileData *iface)
238 ID3DXFileDataImpl *This = impl_from_ID3DXFileData(iface);
240 TRACE("(%p)->()\n", iface);
242 return This->reference;
246 static HRESULT WINAPI ID3DXFileDataImpl_GetChildren(ID3DXFileData *iface, SIZE_T *children)
248 ID3DXFileDataImpl *This = impl_from_ID3DXFileData(iface);
250 TRACE("(%p)->(%p)\n", iface, children);
252 if (!children)
253 return E_POINTER;
255 *children = This->nb_children;
257 return S_OK;
261 static HRESULT WINAPI ID3DXFileDataImpl_GetChild(ID3DXFileData *iface, SIZE_T id, ID3DXFileData **object)
263 ID3DXFileDataImpl *This = impl_from_ID3DXFileData(iface);
265 TRACE("(%p)->(%lu, %p)\n", iface, id, object);
267 if (!object)
268 return E_POINTER;
270 *object = This->children[id];
271 (*object)->lpVtbl->AddRef(*object);
273 return S_OK;
277 static const ID3DXFileDataVtbl ID3DXFileData_Vtbl =
279 ID3DXFileDataImpl_QueryInterface,
280 ID3DXFileDataImpl_AddRef,
281 ID3DXFileDataImpl_Release,
282 ID3DXFileDataImpl_GetEnum,
283 ID3DXFileDataImpl_GetName,
284 ID3DXFileDataImpl_GetId,
285 ID3DXFileDataImpl_Lock,
286 ID3DXFileDataImpl_Unlock,
287 ID3DXFileDataImpl_GetType,
288 ID3DXFileDataImpl_IsReference,
289 ID3DXFileDataImpl_GetChildren,
290 ID3DXFileDataImpl_GetChild
294 static HRESULT ID3DXFileDataImpl_Create(IDirectXFileObject *dxfile_object, ID3DXFileData **ret_iface)
296 ID3DXFileDataImpl *object;
297 IDirectXFileObject *data_object;
298 HRESULT ret;
300 TRACE("(%p, %p)\n", dxfile_object, ret_iface);
302 *ret_iface = NULL;
304 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
305 if (!object)
306 return E_OUTOFMEMORY;
308 object->ID3DXFileData_iface.lpVtbl = &ID3DXFileData_Vtbl;
309 object->ref = 1;
311 ret = IDirectXFileObject_QueryInterface(dxfile_object, &IID_IDirectXFileData, (void **)&object->dxfile_data);
312 if (FAILED(ret))
314 IDirectXFileDataReference *reference;
316 ret = IDirectXFileObject_QueryInterface(dxfile_object, &IID_IDirectXFileDataReference, (void **)&reference);
317 if (SUCCEEDED(ret))
319 ret = IDirectXFileDataReference_Resolve(reference, &object->dxfile_data);
320 if (FAILED(ret))
322 HeapFree(GetProcessHeap(), 0, object);
323 return E_FAIL;
325 object->reference = TRUE;
327 else
329 FIXME("Don't known what to do with binary object\n");
330 HeapFree(GetProcessHeap(), 0, object);
331 return E_FAIL;
335 while (SUCCEEDED(ret = IDirectXFileData_GetNextObject(object->dxfile_data, &data_object)))
337 if (object->children)
338 object->children = HeapReAlloc(GetProcessHeap(), 0, object->children, sizeof(ID3DXFileData*) * (object->nb_children + 1));
339 else
340 object->children = HeapAlloc(GetProcessHeap(), 0, sizeof(ID3DXFileData*));
341 if (!object->children)
343 ret = E_OUTOFMEMORY;
344 break;
346 ret = ID3DXFileDataImpl_Create(data_object, &object->children[object->nb_children]);
347 if (ret != S_OK)
348 break;
349 object->nb_children++;
352 if (ret != DXFILEERR_NOMOREOBJECTS)
354 (&object->ID3DXFileData_iface)->lpVtbl->Release(&object->ID3DXFileData_iface);
355 return ret;
358 TRACE("Found %u children\n", object->nb_children);
360 *ret_iface = &object->ID3DXFileData_iface;
362 return S_OK;
366 /*** IUnknown methods ***/
368 static HRESULT WINAPI ID3DXFileEnumObjectImpl_QueryInterface(ID3DXFileEnumObject *iface, REFIID riid, void **ret_iface)
370 TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ret_iface);
372 if (IsEqualGUID(riid, &IID_IUnknown) ||
373 IsEqualGUID(riid, &IID_ID3DXFileEnumObject))
375 iface->lpVtbl->AddRef(iface);
376 *ret_iface = iface;
377 return S_OK;
380 WARN("(%p)->(%s, %p), not found\n", iface, debugstr_guid(riid), ret_iface);
381 *ret_iface = NULL;
382 return E_NOINTERFACE;
385 static ULONG WINAPI ID3DXFileEnumObjectImpl_AddRef(ID3DXFileEnumObject *iface)
387 ID3DXFileEnumObjectImpl *This = impl_from_ID3DXFileEnumObject(iface);
388 ULONG ref = InterlockedIncrement(&This->ref);
390 TRACE("(%p)->(): new ref = %u\n", iface, ref);
392 return ref;
395 static ULONG WINAPI ID3DXFileEnumObjectImpl_Release(ID3DXFileEnumObject *iface)
397 ID3DXFileEnumObjectImpl *This = impl_from_ID3DXFileEnumObject(iface);
398 ULONG ref = InterlockedDecrement(&This->ref);
400 TRACE("(%p)->(): new ref = %u\n", iface, ref);
402 if (!ref)
404 ULONG i;
406 for (i = 0; i < This->nb_children; i++)
407 (This->children[i])->lpVtbl->Release(This->children[i]);
408 HeapFree(GetProcessHeap(), 0, This->children);
409 HeapFree(GetProcessHeap(), 0, This);
412 return ref;
416 /*** ID3DXFileEnumObject methods ***/
418 static HRESULT WINAPI ID3DXFileEnumObjectImpl_GetFile(ID3DXFileEnumObject *iface, ID3DXFile **file)
420 FIXME("(%p)->(%p): stub\n", iface, file);
422 return E_NOTIMPL;
426 static HRESULT WINAPI ID3DXFileEnumObjectImpl_GetChildren(ID3DXFileEnumObject *iface, SIZE_T *children)
428 ID3DXFileEnumObjectImpl *This = impl_from_ID3DXFileEnumObject(iface);
430 TRACE("(%p)->(%p)\n", iface, children);
432 if (!children)
433 return E_POINTER;
435 *children = This->nb_children;
437 return S_OK;
441 static HRESULT WINAPI ID3DXFileEnumObjectImpl_GetChild(ID3DXFileEnumObject *iface, SIZE_T id, ID3DXFileData **object)
443 ID3DXFileEnumObjectImpl *This = impl_from_ID3DXFileEnumObject(iface);
445 TRACE("(%p)->(%lu, %p)\n", iface, id, object);
447 if (!object)
448 return E_POINTER;
450 *object = This->children[id];
451 (*object)->lpVtbl->AddRef(*object);
453 return S_OK;
457 static HRESULT WINAPI ID3DXFileEnumObjectImpl_GetDataObjectById(ID3DXFileEnumObject *iface, REFGUID guid, ID3DXFileData **object)
459 FIXME("(%p)->(%s, %p): stub\n", iface, debugstr_guid(guid), object);
461 return E_NOTIMPL;
465 static HRESULT WINAPI ID3DXFileEnumObjectImpl_GetDataObjectByName(ID3DXFileEnumObject *iface, const char *name, ID3DXFileData **object)
467 FIXME("(%p)->(%s, %p): stub\n", iface, debugstr_a(name), object);
469 return E_NOTIMPL;
473 static const ID3DXFileEnumObjectVtbl ID3DXFileEnumObject_Vtbl =
475 ID3DXFileEnumObjectImpl_QueryInterface,
476 ID3DXFileEnumObjectImpl_AddRef,
477 ID3DXFileEnumObjectImpl_Release,
478 ID3DXFileEnumObjectImpl_GetFile,
479 ID3DXFileEnumObjectImpl_GetChildren,
480 ID3DXFileEnumObjectImpl_GetChild,
481 ID3DXFileEnumObjectImpl_GetDataObjectById,
482 ID3DXFileEnumObjectImpl_GetDataObjectByName
486 /*** IUnknown methods ***/
488 static HRESULT WINAPI ID3DXFileImpl_QueryInterface(ID3DXFile *iface, REFIID riid, void **ret_iface)
490 TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ret_iface);
492 if (IsEqualGUID(riid, &IID_IUnknown) ||
493 IsEqualGUID(riid, &IID_ID3DXFile))
495 iface->lpVtbl->AddRef(iface);
496 *ret_iface = iface;
497 return S_OK;
500 WARN("(%p)->(%s, %p), not found\n", iface, debugstr_guid(riid), ret_iface);
501 *ret_iface = NULL;
502 return E_NOINTERFACE;
506 static ULONG WINAPI ID3DXFileImpl_AddRef(ID3DXFile *iface)
508 ID3DXFileImpl *This = impl_from_ID3DXFile(iface);
509 ULONG ref = InterlockedIncrement(&This->ref);
511 TRACE("(%p)->(): new ref = %u\n", iface, ref);
513 return ref;
517 static ULONG WINAPI ID3DXFileImpl_Release(ID3DXFile *iface)
519 ID3DXFileImpl *This = impl_from_ID3DXFile(iface);
520 ULONG ref = InterlockedDecrement(&This->ref);
522 TRACE("(%p)->(): new ref = %u\n", iface, ref);
524 if (!ref)
526 IDirectXFile_Release(This->dxfile);
527 HeapFree(GetProcessHeap(), 0, This);
530 return ref;
534 /*** ID3DXFile methods ***/
536 static HRESULT WINAPI ID3DXFileImpl_CreateEnumObject(ID3DXFile *iface, const void *source, D3DXF_FILELOADOPTIONS options, ID3DXFileEnumObject **enum_object)
538 ID3DXFileImpl *This = impl_from_ID3DXFile(iface);
539 ID3DXFileEnumObjectImpl *object;
540 IDirectXFileEnumObject *dxfile_enum_object;
541 void *dxfile_source;
542 DXFILELOADOPTIONS dxfile_options;
543 DXFILELOADRESOURCE dxfile_resource;
544 DXFILELOADMEMORY dxfile_memory;
545 IDirectXFileData *data_object;
546 HRESULT ret;
548 TRACE("(%p)->(%p, %x, %p)\n", iface, source, options, enum_object);
550 if (!enum_object)
551 return E_POINTER;
553 *enum_object = NULL;
555 if (options == D3DXF_FILELOAD_FROMFILE)
557 dxfile_source = (void*)source;
558 dxfile_options = DXFILELOAD_FROMFILE;
560 else if (options == D3DXF_FILELOAD_FROMRESOURCE)
562 D3DXF_FILELOADRESOURCE *resource = (D3DXF_FILELOADRESOURCE*)source;
564 dxfile_resource.hModule = resource->hModule;
565 dxfile_resource.lpName = resource->lpName;
566 dxfile_resource.lpType = resource->lpType;
567 dxfile_source = &dxfile_resource;
568 dxfile_options = DXFILELOAD_FROMRESOURCE;
570 else if (options == D3DXF_FILELOAD_FROMMEMORY)
572 D3DXF_FILELOADMEMORY *memory = (D3DXF_FILELOADMEMORY*)source;
574 dxfile_memory.lpMemory = memory->lpMemory;
575 dxfile_memory.dSize = memory->dSize;
576 dxfile_source = &dxfile_memory;
577 dxfile_options = DXFILELOAD_FROMMEMORY;
579 else
581 FIXME("Source type %u is not handled yet\n", options);
582 return E_NOTIMPL;
585 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
586 if (!object)
587 return E_OUTOFMEMORY;
589 object->ID3DXFileEnumObject_iface.lpVtbl = &ID3DXFileEnumObject_Vtbl;
590 object->ref = 1;
592 ret = IDirectXFile_CreateEnumObject(This->dxfile, dxfile_source, dxfile_options, &dxfile_enum_object);
594 if (ret != S_OK)
596 HeapFree(GetProcessHeap(), 0, object);
597 return ret;
600 /* Fill enum object with top level data objects */
601 while (SUCCEEDED(ret = IDirectXFileEnumObject_GetNextDataObject(dxfile_enum_object, &data_object)))
603 if (object->children)
604 object->children = HeapReAlloc(GetProcessHeap(), 0, object->children, sizeof(*object->children) * (object->nb_children + 1));
605 else
606 object->children = HeapAlloc(GetProcessHeap(), 0, sizeof(*object->children));
607 if (!object->children)
609 ret = E_OUTOFMEMORY;
610 break;
612 ret = ID3DXFileDataImpl_Create((IDirectXFileObject*)data_object, &object->children[object->nb_children]);
613 if (ret != S_OK)
614 break;
615 object->nb_children++;
618 IDirectXFileEnumObject_Release(dxfile_enum_object);
620 if (ret != DXFILEERR_NOMOREOBJECTS)
621 WARN("Cannot get all top level data objects\n");
623 TRACE("Found %u children\n", object->nb_children);
625 *enum_object = &object->ID3DXFileEnumObject_iface;
627 return S_OK;
631 static HRESULT WINAPI ID3DXFileImpl_CreateSaveObject(ID3DXFile *iface, const void *data, D3DXF_FILESAVEOPTIONS options, D3DXF_FILEFORMAT format, ID3DXFileSaveObject **save_object)
633 FIXME("(%p)->(%p, %x, %u, %p): stub\n", iface, data, options, format, save_object);
635 return E_NOTIMPL;
639 static HRESULT WINAPI ID3DXFileImpl_RegisterTemplates(ID3DXFile *iface, const void *data, SIZE_T size)
641 ID3DXFileImpl *This = impl_from_ID3DXFile(iface);
642 HRESULT ret;
644 TRACE("(%p)->(%p, %lu)\n", iface, data, size);
646 ret = IDirectXFile_RegisterTemplates(This->dxfile, (void*)data, size);
647 if (ret != DXFILE_OK)
649 WARN("Error %#x\n", ret);
650 return error_dxfile_to_d3dxfile(ret);
653 return S_OK;
657 static HRESULT WINAPI ID3DXFileImpl_RegisterEnumTemplates(ID3DXFile *iface, ID3DXFileEnumObject *enum_object)
659 FIXME("(%p)->(%p): stub\n", iface, enum_object);
661 return E_NOTIMPL;
665 static const ID3DXFileVtbl ID3DXFile_Vtbl =
667 ID3DXFileImpl_QueryInterface,
668 ID3DXFileImpl_AddRef,
669 ID3DXFileImpl_Release,
670 ID3DXFileImpl_CreateEnumObject,
671 ID3DXFileImpl_CreateSaveObject,
672 ID3DXFileImpl_RegisterTemplates,
673 ID3DXFileImpl_RegisterEnumTemplates
676 HRESULT WINAPI D3DXFileCreate(ID3DXFile **d3dxfile)
678 ID3DXFileImpl *object;
679 HRESULT ret;
681 TRACE("(%p)\n", d3dxfile);
683 if (!d3dxfile)
684 return E_POINTER;
686 *d3dxfile = NULL;
688 object = HeapAlloc(GetProcessHeap(), 0, sizeof(*object));
689 if (!object)
690 return E_OUTOFMEMORY;
692 ret = DirectXFileCreate(&object->dxfile);
693 if (ret != S_OK)
695 HeapFree(GetProcessHeap(), 0, object);
696 if (ret == E_OUTOFMEMORY)
697 return ret;
698 return E_FAIL;
701 object->ID3DXFile_iface.lpVtbl = &ID3DXFile_Vtbl;
702 object->ref = 1;
704 *d3dxfile = &object->ID3DXFile_iface;
706 return S_OK;