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"
27 WINE_DEFAULT_DEBUG_CHANNEL(d3dx
);
29 static HRESULT
error_dxfile_to_d3dxfile(HRESULT 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
;
42 FIXME("Cannot map error %#x\n", error
);
48 ID3DXFile ID3DXFile_iface
;
54 ID3DXFileEnumObject ID3DXFileEnumObject_iface
;
57 ID3DXFileData
**children
;
58 } ID3DXFileEnumObjectImpl
;
61 ID3DXFileData ID3DXFileData_iface
;
63 IDirectXFileData
*dxfile_data
;
67 static inline ID3DXFileImpl
* impl_from_ID3DXFile(ID3DXFile
*iface
)
69 return CONTAINING_RECORD(iface
, ID3DXFileImpl
, ID3DXFile_iface
);
72 static inline ID3DXFileEnumObjectImpl
* impl_from_ID3DXFileEnumObject(ID3DXFileEnumObject
*iface
)
74 return CONTAINING_RECORD(iface
, ID3DXFileEnumObjectImpl
, ID3DXFileEnumObject_iface
);
77 static inline ID3DXFileDataImpl
* impl_from_ID3DXFileData(ID3DXFileData
*iface
)
79 return CONTAINING_RECORD(iface
, ID3DXFileDataImpl
, ID3DXFileData_iface
);
82 /*** IUnknown methods ***/
84 static HRESULT WINAPI
ID3DXFileDataImpl_QueryInterface(ID3DXFileData
*iface
, REFIID riid
, void **ret_iface
)
86 TRACE("(%p)->(%s, %p)\n", iface
, debugstr_guid(riid
), ret_iface
);
88 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
89 IsEqualGUID(riid
, &IID_ID3DXFileData
))
91 iface
->lpVtbl
->AddRef(iface
);
96 WARN("(%p)->(%s, %p), not found\n", iface
, debugstr_guid(riid
), ret_iface
);
101 static ULONG WINAPI
ID3DXFileDataImpl_AddRef(ID3DXFileData
*iface
)
103 ID3DXFileDataImpl
*This
= impl_from_ID3DXFileData(iface
);
104 ULONG ref
= InterlockedIncrement(&This
->ref
);
106 TRACE("(%p)->(): new ref = %u\n", iface
, ref
);
111 static ULONG WINAPI
ID3DXFileDataImpl_Release(ID3DXFileData
*iface
)
113 ID3DXFileDataImpl
*This
= impl_from_ID3DXFileData(iface
);
114 ULONG ref
= InterlockedDecrement(&This
->ref
);
116 TRACE("(%p)->(): new ref = %u\n", iface
, ref
);
120 IDirectXFileData_Release(This
->dxfile_data
);
121 HeapFree(GetProcessHeap(), 0, This
);
128 /*** ID3DXFileData methods ***/
130 static HRESULT WINAPI
ID3DXFileDataImpl_GetEnum(ID3DXFileData
*iface
, ID3DXFileEnumObject
**enum_object
)
132 FIXME("(%p)->(%p): stub\n", iface
, enum_object
);
138 static HRESULT WINAPI
ID3DXFileDataImpl_GetName(ID3DXFileData
*iface
, char *name
, SIZE_T
*size
)
140 FIXME("(%p)->(%p, %p): stub\n", iface
, name
, size
);
146 static HRESULT WINAPI
ID3DXFileDataImpl_GetId(ID3DXFileData
*iface
, GUID
*guid
)
148 FIXME("(%p)->(%p): stub\n", iface
, guid
);
154 static HRESULT WINAPI
ID3DXFileDataImpl_Lock(ID3DXFileData
*iface
, SIZE_T
*size
, const void **data
)
156 FIXME("(%p)->(%p, %p): stub\n", iface
, size
, data
);
162 static HRESULT WINAPI
ID3DXFileDataImpl_Unlock(ID3DXFileData
*iface
)
164 FIXME("(%p)->(): stub\n", iface
);
170 static HRESULT WINAPI
ID3DXFileDataImpl_GetType(ID3DXFileData
*iface
, GUID
*guid
)
172 ID3DXFileDataImpl
*This
= impl_from_ID3DXFileData(iface
);
173 const GUID
*dxfile_guid
;
176 TRACE("(%p)->(%p)\n", iface
, guid
);
178 ret
= IDirectXFileData_GetType(This
->dxfile_data
, &dxfile_guid
);
179 if (ret
!= DXFILE_OK
)
180 return error_dxfile_to_d3dxfile(ret
);
182 *guid
= *dxfile_guid
;
188 static BOOL WINAPI
ID3DXFileDataImpl_IsReference(ID3DXFileData
*iface
)
190 TRACE("(%p)->(): stub\n", iface
);
196 static HRESULT WINAPI
ID3DXFileDataImpl_GetChildren(ID3DXFileData
*iface
, SIZE_T
*children
)
198 TRACE("(%p)->(%p): stub\n", iface
, children
);
204 static HRESULT WINAPI
ID3DXFileDataImpl_GetChild(ID3DXFileData
*iface
, SIZE_T id
, ID3DXFileData
**object
)
206 TRACE("(%p)->(%lu, %p): stub\n", iface
, id
, object
);
212 static const ID3DXFileDataVtbl ID3DXFileData_Vtbl
=
214 ID3DXFileDataImpl_QueryInterface
,
215 ID3DXFileDataImpl_AddRef
,
216 ID3DXFileDataImpl_Release
,
217 ID3DXFileDataImpl_GetEnum
,
218 ID3DXFileDataImpl_GetName
,
219 ID3DXFileDataImpl_GetId
,
220 ID3DXFileDataImpl_Lock
,
221 ID3DXFileDataImpl_Unlock
,
222 ID3DXFileDataImpl_GetType
,
223 ID3DXFileDataImpl_IsReference
,
224 ID3DXFileDataImpl_GetChildren
,
225 ID3DXFileDataImpl_GetChild
229 static HRESULT
ID3DXFileDataImpl_Create(IDirectXFileData
*dxfile_data
, ID3DXFileData
**ret_iface
)
231 ID3DXFileDataImpl
*object
;
233 TRACE("(%p, %p)\n", dxfile_data
, ret_iface
);
237 object
= HeapAlloc(GetProcessHeap(), 0, sizeof(*object
));
239 return E_OUTOFMEMORY
;
241 object
->ID3DXFileData_iface
.lpVtbl
= &ID3DXFileData_Vtbl
;
243 object
->dxfile_data
= dxfile_data
;
245 *ret_iface
= &object
->ID3DXFileData_iface
;
251 /*** IUnknown methods ***/
253 static HRESULT WINAPI
ID3DXFileEnumObjectImpl_QueryInterface(ID3DXFileEnumObject
*iface
, REFIID riid
, void **ret_iface
)
255 TRACE("(%p)->(%s, %p)\n", iface
, debugstr_guid(riid
), ret_iface
);
257 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
258 IsEqualGUID(riid
, &IID_ID3DXFileEnumObject
))
260 iface
->lpVtbl
->AddRef(iface
);
265 WARN("(%p)->(%s, %p), not found\n", iface
, debugstr_guid(riid
), ret_iface
);
267 return E_NOINTERFACE
;
270 static ULONG WINAPI
ID3DXFileEnumObjectImpl_AddRef(ID3DXFileEnumObject
*iface
)
272 ID3DXFileEnumObjectImpl
*This
= impl_from_ID3DXFileEnumObject(iface
);
273 ULONG ref
= InterlockedIncrement(&This
->ref
);
275 TRACE("(%p)->(): new ref = %u\n", iface
, ref
);
280 static ULONG WINAPI
ID3DXFileEnumObjectImpl_Release(ID3DXFileEnumObject
*iface
)
282 ID3DXFileEnumObjectImpl
*This
= impl_from_ID3DXFileEnumObject(iface
);
283 ULONG ref
= InterlockedDecrement(&This
->ref
);
285 TRACE("(%p)->(): new ref = %u\n", iface
, ref
);
291 for (i
= 0; i
< This
->nb_children
; i
++)
292 (This
->children
[i
])->lpVtbl
->Release(This
->children
[i
]);
293 HeapFree(GetProcessHeap(), 0, This
->children
);
294 HeapFree(GetProcessHeap(), 0, This
);
301 /*** ID3DXFileEnumObject methods ***/
303 static HRESULT WINAPI
ID3DXFileEnumObjectImpl_GetFile(ID3DXFileEnumObject
*iface
, ID3DXFile
**file
)
305 FIXME("(%p)->(%p): stub\n", iface
, file
);
311 static HRESULT WINAPI
ID3DXFileEnumObjectImpl_GetChildren(ID3DXFileEnumObject
*iface
, SIZE_T
*children
)
313 ID3DXFileEnumObjectImpl
*This
= impl_from_ID3DXFileEnumObject(iface
);
315 TRACE("(%p)->(%p)\n", iface
, children
);
320 *children
= This
->nb_children
;
326 static HRESULT WINAPI
ID3DXFileEnumObjectImpl_GetChild(ID3DXFileEnumObject
*iface
, SIZE_T id
, ID3DXFileData
**object
)
328 ID3DXFileEnumObjectImpl
*This
= impl_from_ID3DXFileEnumObject(iface
);
330 TRACE("(%p)->(%lu, %p)\n", iface
, id
, object
);
335 *object
= This
->children
[id
];
336 (*object
)->lpVtbl
->AddRef(*object
);
342 static HRESULT WINAPI
ID3DXFileEnumObjectImpl_GetDataObjectById(ID3DXFileEnumObject
*iface
, REFGUID guid
, ID3DXFileData
**object
)
344 FIXME("(%p)->(%s, %p): stub\n", iface
, debugstr_guid(guid
), object
);
350 static HRESULT WINAPI
ID3DXFileEnumObjectImpl_GetDataObjectByName(ID3DXFileEnumObject
*iface
, const char *name
, ID3DXFileData
**object
)
352 FIXME("(%p)->(%s, %p): stub\n", iface
, debugstr_a(name
), object
);
358 static const ID3DXFileEnumObjectVtbl ID3DXFileEnumObject_Vtbl
=
360 ID3DXFileEnumObjectImpl_QueryInterface
,
361 ID3DXFileEnumObjectImpl_AddRef
,
362 ID3DXFileEnumObjectImpl_Release
,
363 ID3DXFileEnumObjectImpl_GetFile
,
364 ID3DXFileEnumObjectImpl_GetChildren
,
365 ID3DXFileEnumObjectImpl_GetChild
,
366 ID3DXFileEnumObjectImpl_GetDataObjectById
,
367 ID3DXFileEnumObjectImpl_GetDataObjectByName
371 /*** IUnknown methods ***/
373 static HRESULT WINAPI
ID3DXFileImpl_QueryInterface(ID3DXFile
*iface
, REFIID riid
, void **ret_iface
)
375 TRACE("(%p)->(%s, %p)\n", iface
, debugstr_guid(riid
), ret_iface
);
377 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
378 IsEqualGUID(riid
, &IID_ID3DXFile
))
380 iface
->lpVtbl
->AddRef(iface
);
385 WARN("(%p)->(%s, %p), not found\n", iface
, debugstr_guid(riid
), ret_iface
);
387 return E_NOINTERFACE
;
391 static ULONG WINAPI
ID3DXFileImpl_AddRef(ID3DXFile
*iface
)
393 ID3DXFileImpl
*This
= impl_from_ID3DXFile(iface
);
394 ULONG ref
= InterlockedIncrement(&This
->ref
);
396 TRACE("(%p)->(): new ref = %u\n", iface
, ref
);
402 static ULONG WINAPI
ID3DXFileImpl_Release(ID3DXFile
*iface
)
404 ID3DXFileImpl
*This
= impl_from_ID3DXFile(iface
);
405 ULONG ref
= InterlockedDecrement(&This
->ref
);
407 TRACE("(%p)->(): new ref = %u\n", iface
, ref
);
411 IDirectXFile_Release(This
->dxfile
);
412 HeapFree(GetProcessHeap(), 0, This
);
419 /*** ID3DXFile methods ***/
421 static HRESULT WINAPI
ID3DXFileImpl_CreateEnumObject(ID3DXFile
*iface
, const void *source
, D3DXF_FILELOADOPTIONS options
, ID3DXFileEnumObject
**enum_object
)
423 ID3DXFileImpl
*This
= impl_from_ID3DXFile(iface
);
424 ID3DXFileEnumObjectImpl
*object
;
425 IDirectXFileEnumObject
*dxfile_enum_object
;
427 DXFILELOADOPTIONS dxfile_options
;
428 DXFILELOADRESOURCE dxfile_resource
;
429 DXFILELOADMEMORY dxfile_memory
;
430 IDirectXFileData
*data_object
;
433 TRACE("(%p)->(%p, %x, %p)\n", iface
, source
, options
, enum_object
);
440 if (options
== D3DXF_FILELOAD_FROMFILE
)
442 dxfile_source
= (void*)source
;
443 dxfile_options
= DXFILELOAD_FROMFILE
;
445 else if (options
== D3DXF_FILELOAD_FROMRESOURCE
)
447 D3DXF_FILELOADRESOURCE
*resource
= (D3DXF_FILELOADRESOURCE
*)source
;
449 dxfile_resource
.hModule
= resource
->hModule
;
450 dxfile_resource
.lpName
= resource
->lpName
;
451 dxfile_resource
.lpType
= resource
->lpType
;
452 dxfile_source
= &dxfile_resource
;
453 dxfile_options
= DXFILELOAD_FROMRESOURCE
;
455 else if (options
== D3DXF_FILELOAD_FROMMEMORY
)
457 D3DXF_FILELOADMEMORY
*memory
= (D3DXF_FILELOADMEMORY
*)source
;
459 dxfile_memory
.lpMemory
= memory
->lpMemory
;
460 dxfile_memory
.dSize
= memory
->dSize
;
461 dxfile_source
= &dxfile_memory
;
462 dxfile_options
= DXFILELOAD_FROMMEMORY
;
466 FIXME("Source type %u is not handled yet\n", options
);
470 object
= HeapAlloc(GetProcessHeap(), 0, sizeof(*object
));
472 return E_OUTOFMEMORY
;
474 object
->ID3DXFileEnumObject_iface
.lpVtbl
= &ID3DXFileEnumObject_Vtbl
;
477 ret
= IDirectXFile_CreateEnumObject(This
->dxfile
, dxfile_source
, dxfile_options
, &dxfile_enum_object
);
481 HeapFree(GetProcessHeap(), 0, object
);
485 /* Fill enum object with top level data objects */
486 while (SUCCEEDED(ret
= IDirectXFileEnumObject_GetNextDataObject(dxfile_enum_object
, &data_object
)))
488 if (object
->children
)
489 object
->children
= HeapReAlloc(GetProcessHeap(), 0, object
->children
, sizeof(*object
->children
) * (object
->nb_children
+ 1));
491 object
->children
= HeapAlloc(GetProcessHeap(), 0, sizeof(*object
->children
));
492 if (!object
->children
)
497 ret
= ID3DXFileDataImpl_Create(data_object
, &object
->children
[object
->nb_children
]);
500 object
->nb_children
++;
503 IDirectXFileEnumObject_Release(dxfile_enum_object
);
505 if (ret
!= DXFILEERR_NOMOREOBJECTS
)
506 WARN("Cannot get all top level data objects\n");
508 TRACE("Found %u children\n", object
->nb_children
);
510 *enum_object
= &object
->ID3DXFileEnumObject_iface
;
516 static HRESULT WINAPI
ID3DXFileImpl_CreateSaveObject(ID3DXFile
*iface
, const void *data
, D3DXF_FILESAVEOPTIONS options
, D3DXF_FILEFORMAT format
, ID3DXFileSaveObject
**save_object
)
518 FIXME("(%p)->(%p, %x, %u, %p): stub\n", iface
, data
, options
, format
, save_object
);
524 static HRESULT WINAPI
ID3DXFileImpl_RegisterTemplates(ID3DXFile
*iface
, const void *data
, SIZE_T size
)
526 ID3DXFileImpl
*This
= impl_from_ID3DXFile(iface
);
529 TRACE("(%p)->(%p, %lu)\n", iface
, data
, size
);
531 ret
= IDirectXFile_RegisterTemplates(This
->dxfile
, (void*)data
, size
);
532 if (ret
!= DXFILE_OK
)
534 WARN("Error %#x\n", ret
);
535 return error_dxfile_to_d3dxfile(ret
);
542 static HRESULT WINAPI
ID3DXFileImpl_RegisterEnumTemplates(ID3DXFile
*iface
, ID3DXFileEnumObject
*enum_object
)
544 FIXME("(%p)->(%p): stub\n", iface
, enum_object
);
550 static const ID3DXFileVtbl ID3DXFile_Vtbl
=
552 ID3DXFileImpl_QueryInterface
,
553 ID3DXFileImpl_AddRef
,
554 ID3DXFileImpl_Release
,
555 ID3DXFileImpl_CreateEnumObject
,
556 ID3DXFileImpl_CreateSaveObject
,
557 ID3DXFileImpl_RegisterTemplates
,
558 ID3DXFileImpl_RegisterEnumTemplates
561 HRESULT WINAPI
D3DXFileCreate(ID3DXFile
**d3dxfile
)
563 ID3DXFileImpl
*object
;
566 TRACE("(%p)\n", d3dxfile
);
573 object
= HeapAlloc(GetProcessHeap(), 0, sizeof(*object
));
575 return E_OUTOFMEMORY
;
577 ret
= DirectXFileCreate(&object
->dxfile
);
580 HeapFree(GetProcessHeap(), 0, object
);
581 if (ret
== E_OUTOFMEMORY
)
586 object
->ID3DXFile_iface
.lpVtbl
= &ID3DXFile_Vtbl
;
589 *d3dxfile
= &object
->ID3DXFile_iface
;