msvcrt: Simplify fseek implementation.
[wine/multimedia.git] / dlls / d3dx9_36 / xfile.c
blob8fa20ff9bdd535d72ad5ede8c9a93bf2c7e8f3fc
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 IDirectXFileData *dxfile_data;
64 } ID3DXFileDataImpl;
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);
92 *ret_iface = iface;
93 return S_OK;
96 WARN("(%p)->(%s, %p), not found\n", iface, debugstr_guid(riid), ret_iface);
97 *ret_iface = NULL;
98 return E_NOINTERFACE;
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);
108 return 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);
118 if (!ref)
120 IDirectXFileData_Release(This->dxfile_data);
121 HeapFree(GetProcessHeap(), 0, This);
124 return ref;
128 /*** ID3DXFileData methods ***/
130 static HRESULT WINAPI ID3DXFileDataImpl_GetEnum(ID3DXFileData *iface, ID3DXFileEnumObject **enum_object)
132 FIXME("(%p)->(%p): stub\n", iface, enum_object);
134 return E_NOTIMPL;
138 static HRESULT WINAPI ID3DXFileDataImpl_GetName(ID3DXFileData *iface, char *name, SIZE_T *size)
140 FIXME("(%p)->(%p, %p): stub\n", iface, name, size);
142 return E_NOTIMPL;
146 static HRESULT WINAPI ID3DXFileDataImpl_GetId(ID3DXFileData *iface, GUID *guid)
148 FIXME("(%p)->(%p): stub\n", iface, guid);
150 return E_NOTIMPL;
154 static HRESULT WINAPI ID3DXFileDataImpl_Lock(ID3DXFileData *iface, SIZE_T *size, const void **data)
156 FIXME("(%p)->(%p, %p): stub\n", iface, size, data);
158 return E_NOTIMPL;
162 static HRESULT WINAPI ID3DXFileDataImpl_Unlock(ID3DXFileData *iface)
164 FIXME("(%p)->(): stub\n", iface);
166 return E_NOTIMPL;
170 static HRESULT WINAPI ID3DXFileDataImpl_GetType(ID3DXFileData *iface, GUID *guid)
172 ID3DXFileDataImpl *This = impl_from_ID3DXFileData(iface);
173 const GUID *dxfile_guid;
174 HRESULT ret;
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;
184 return S_OK;
188 static BOOL WINAPI ID3DXFileDataImpl_IsReference(ID3DXFileData *iface)
190 TRACE("(%p)->(): stub\n", iface);
192 return E_NOTIMPL;
196 static HRESULT WINAPI ID3DXFileDataImpl_GetChildren(ID3DXFileData *iface, SIZE_T *children)
198 TRACE("(%p)->(%p): stub\n", iface, children);
200 return E_NOTIMPL;
204 static HRESULT WINAPI ID3DXFileDataImpl_GetChild(ID3DXFileData *iface, SIZE_T id, ID3DXFileData **object)
206 TRACE("(%p)->(%lu, %p): stub\n", iface, id, object);
208 return E_NOTIMPL;
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);
235 *ret_iface = NULL;
237 object = HeapAlloc(GetProcessHeap(), 0, sizeof(*object));
238 if (!object)
239 return E_OUTOFMEMORY;
241 object->ID3DXFileData_iface.lpVtbl = &ID3DXFileData_Vtbl;
242 object->ref = 1;
243 object->dxfile_data = dxfile_data;
245 *ret_iface = &object->ID3DXFileData_iface;
247 return S_OK;
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);
261 *ret_iface = iface;
262 return S_OK;
265 WARN("(%p)->(%s, %p), not found\n", iface, debugstr_guid(riid), ret_iface);
266 *ret_iface = NULL;
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);
277 return 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);
287 if (!ref)
289 ULONG i;
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);
297 return ref;
301 /*** ID3DXFileEnumObject methods ***/
303 static HRESULT WINAPI ID3DXFileEnumObjectImpl_GetFile(ID3DXFileEnumObject *iface, ID3DXFile **file)
305 FIXME("(%p)->(%p): stub\n", iface, file);
307 return E_NOTIMPL;
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);
317 if (!children)
318 return E_POINTER;
320 *children = This->nb_children;
322 return S_OK;
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);
332 if (!object)
333 return E_POINTER;
335 *object = This->children[id];
336 (*object)->lpVtbl->AddRef(*object);
338 return S_OK;
342 static HRESULT WINAPI ID3DXFileEnumObjectImpl_GetDataObjectById(ID3DXFileEnumObject *iface, REFGUID guid, ID3DXFileData **object)
344 FIXME("(%p)->(%s, %p): stub\n", iface, debugstr_guid(guid), object);
346 return E_NOTIMPL;
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);
354 return E_NOTIMPL;
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);
381 *ret_iface = iface;
382 return S_OK;
385 WARN("(%p)->(%s, %p), not found\n", iface, debugstr_guid(riid), ret_iface);
386 *ret_iface = NULL;
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);
398 return 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);
409 if (!ref)
411 IDirectXFile_Release(This->dxfile);
412 HeapFree(GetProcessHeap(), 0, This);
415 return ref;
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;
426 void *dxfile_source;
427 DXFILELOADOPTIONS dxfile_options;
428 DXFILELOADRESOURCE dxfile_resource;
429 DXFILELOADMEMORY dxfile_memory;
430 IDirectXFileData *data_object;
431 HRESULT ret;
433 TRACE("(%p)->(%p, %x, %p)\n", iface, source, options, enum_object);
435 if (!enum_object)
436 return E_POINTER;
438 *enum_object = NULL;
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;
464 else
466 FIXME("Source type %u is not handled yet\n", options);
467 return E_NOTIMPL;
470 object = HeapAlloc(GetProcessHeap(), 0, sizeof(*object));
471 if (!object)
472 return E_OUTOFMEMORY;
474 object->ID3DXFileEnumObject_iface.lpVtbl = &ID3DXFileEnumObject_Vtbl;
475 object->ref = 1;
477 ret = IDirectXFile_CreateEnumObject(This->dxfile, dxfile_source, dxfile_options, &dxfile_enum_object);
479 if (ret != S_OK)
481 HeapFree(GetProcessHeap(), 0, object);
482 return ret;
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));
490 else
491 object->children = HeapAlloc(GetProcessHeap(), 0, sizeof(*object->children));
492 if (!object->children)
494 ret = E_OUTOFMEMORY;
495 break;
497 ret = ID3DXFileDataImpl_Create(data_object, &object->children[object->nb_children]);
498 if (ret != S_OK)
499 break;
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;
512 return S_OK;
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);
520 return E_NOTIMPL;
524 static HRESULT WINAPI ID3DXFileImpl_RegisterTemplates(ID3DXFile *iface, const void *data, SIZE_T size)
526 ID3DXFileImpl *This = impl_from_ID3DXFile(iface);
527 HRESULT ret;
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);
538 return S_OK;
542 static HRESULT WINAPI ID3DXFileImpl_RegisterEnumTemplates(ID3DXFile *iface, ID3DXFileEnumObject *enum_object)
544 FIXME("(%p)->(%p): stub\n", iface, enum_object);
546 return E_NOTIMPL;
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;
564 HRESULT ret;
566 TRACE("(%p)\n", d3dxfile);
568 if (!d3dxfile)
569 return E_POINTER;
571 *d3dxfile = NULL;
573 object = HeapAlloc(GetProcessHeap(), 0, sizeof(*object));
574 if (!object)
575 return E_OUTOFMEMORY;
577 ret = DirectXFileCreate(&object->dxfile);
578 if (ret != S_OK)
580 HeapFree(GetProcessHeap(), 0, object);
581 if (ret == E_OUTOFMEMORY)
582 return ret;
583 return E_FAIL;
586 object->ID3DXFile_iface.lpVtbl = &ID3DXFile_Vtbl;
587 object->ref = 1;
589 *d3dxfile = &object->ID3DXFile_iface;
591 return S_OK;