d3drm: Avoid LPDIRECT3DRMVISUAL.
[wine] / dlls / d3drm / d3drm.c
1 /*
2  * Implementation of IDirect3DRM Interface
3  *
4  * Copyright 2010, 2012 Christian Costa
5  * Copyright 2011 AndrĂ© Hentschel
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21
22 #include "wine/debug.h"
23
24 #define COBJMACROS
25
26 #include "winbase.h"
27 #include "wingdi.h"
28 #include "dxfile.h"
29 #include "rmxfguid.h"
30
31 #include "d3drm_private.h"
32
33 WINE_DEFAULT_DEBUG_CHANNEL(d3drm);
34
35 static const char* get_IID_string(const GUID* guid)
36 {
37     if (IsEqualGUID(guid, &IID_IDirect3DRMFrame))
38         return "IID_IDirect3DRMFrame";
39     else if (IsEqualGUID(guid, &IID_IDirect3DRMFrame2))
40         return "IID_IDirect3DRMFrame2";
41     else if (IsEqualGUID(guid, &IID_IDirect3DRMFrame3))
42         return "IID_IDirect3DRMFrame3";
43     else if (IsEqualGUID(guid, &IID_IDirect3DRMMeshBuilder))
44         return "IID_IDirect3DRMMeshBuilder";
45     else if (IsEqualGUID(guid, &IID_IDirect3DRMMeshBuilder2))
46         return "IID_IDirect3DRMMeshBuilder2";
47     else if (IsEqualGUID(guid, &IID_IDirect3DRMMeshBuilder3))
48         return "IID_IDirect3DRMMeshBuilder3";
49
50     return "?";
51 }
52
53 typedef struct {
54     IDirect3DRM IDirect3DRM_iface;
55     IDirect3DRM2 IDirect3DRM2_iface;
56     IDirect3DRM3 IDirect3DRM3_iface;
57     LONG ref;
58 } IDirect3DRMImpl;
59
60 static inline IDirect3DRMImpl *impl_from_IDirect3DRM(IDirect3DRM *iface)
61 {
62     return CONTAINING_RECORD(iface, IDirect3DRMImpl, IDirect3DRM_iface);
63 }
64
65 static inline IDirect3DRMImpl *impl_from_IDirect3DRM2(IDirect3DRM2 *iface)
66 {
67     return CONTAINING_RECORD(iface, IDirect3DRMImpl, IDirect3DRM2_iface);
68 }
69
70 static inline IDirect3DRMImpl *impl_from_IDirect3DRM3(IDirect3DRM3 *iface)
71 {
72     return CONTAINING_RECORD(iface, IDirect3DRMImpl, IDirect3DRM3_iface);
73 }
74
75 /*** IUnknown methods ***/
76 static HRESULT WINAPI IDirect3DRMImpl_QueryInterface(IDirect3DRM* iface, REFIID riid, void** ppvObject)
77 {
78     IDirect3DRMImpl *This = impl_from_IDirect3DRM(iface);
79
80     TRACE("(%p/%p)->(%s,%p)\n", iface, This, debugstr_guid(riid), ppvObject);
81
82     *ppvObject = NULL;
83
84     if(IsEqualGUID(riid, &IID_IUnknown) ||
85        IsEqualGUID(riid, &IID_IDirect3DRM))
86     {
87         *ppvObject = &This->IDirect3DRM_iface;
88     }
89     else if(IsEqualGUID(riid, &IID_IDirect3DRM2))
90     {
91         *ppvObject = &This->IDirect3DRM2_iface;
92     }
93     else if(IsEqualGUID(riid, &IID_IDirect3DRM3))
94     {
95         *ppvObject = &This->IDirect3DRM3_iface;
96     }
97     else
98     {
99         FIXME("interface %s not implemented\n", debugstr_guid(riid));
100         return E_NOINTERFACE;
101     }
102
103     IDirect3DRM_AddRef(iface);
104     return S_OK;
105 }
106
107 static ULONG WINAPI IDirect3DRMImpl_AddRef(IDirect3DRM* iface)
108 {
109     IDirect3DRMImpl *This = impl_from_IDirect3DRM(iface);
110     ULONG ref = InterlockedIncrement(&This->ref);
111
112     TRACE("(%p/%p)->(): new ref = %d\n", iface, This, ref);
113
114     return ref;
115 }
116
117 static ULONG WINAPI IDirect3DRMImpl_Release(IDirect3DRM* iface)
118 {
119     IDirect3DRMImpl *This = impl_from_IDirect3DRM(iface);
120     ULONG ref = InterlockedDecrement(&This->ref);
121
122     TRACE("(%p/%p)->(): new ref = %d\n", iface, This, ref);
123
124     if (!ref)
125         HeapFree(GetProcessHeap(), 0, This);
126
127     return ref;
128 }
129
130 /*** IDirect3DRM methods ***/
131 static HRESULT WINAPI IDirect3DRMImpl_CreateObject(IDirect3DRM* iface, REFCLSID rclsid, LPUNKNOWN pUnkOuter, REFIID riid, LPVOID *ppvObj)
132 {
133     IDirect3DRMImpl *This = impl_from_IDirect3DRM(iface);
134
135     FIXME("(%p/%p)->(%s,%p,%s,%p): stub\n", iface, This, debugstr_guid(rclsid), pUnkOuter, debugstr_guid(riid), ppvObj);
136
137     return E_NOTIMPL;
138 }
139
140 static HRESULT WINAPI IDirect3DRMImpl_CreateFrame(IDirect3DRM *iface,
141         IDirect3DRMFrame *parent_frame, IDirect3DRMFrame **frame)
142 {
143     TRACE("iface %p, parent_frame %p, frame %p.\n", iface, parent_frame, frame);
144
145     return Direct3DRMFrame_create(&IID_IDirect3DRMFrame, (IUnknown *)parent_frame, (IUnknown **)frame);
146 }
147
148 static HRESULT WINAPI IDirect3DRMImpl_CreateMesh(IDirect3DRM* iface, LPDIRECT3DRMMESH * ppMesh)
149 {
150     IDirect3DRMImpl *This = impl_from_IDirect3DRM(iface);
151
152     TRACE("(%p/%p)->(%p)\n", iface, This, ppMesh);
153
154     return IDirect3DRM3_CreateMesh(&This->IDirect3DRM3_iface, ppMesh);
155 }
156
157 static HRESULT WINAPI IDirect3DRMImpl_CreateMeshBuilder(IDirect3DRM* iface, LPDIRECT3DRMMESHBUILDER * ppMeshBuilder)
158 {
159     IDirect3DRMImpl *This = impl_from_IDirect3DRM(iface);
160
161     TRACE("(%p/%p)->(%p)\n", iface, This, ppMeshBuilder);
162
163     return Direct3DRMMeshBuilder_create(&IID_IDirect3DRMMeshBuilder, (IUnknown**)ppMeshBuilder);
164 }
165
166 static HRESULT WINAPI IDirect3DRMImpl_CreateFace(IDirect3DRM* iface, LPDIRECT3DRMFACE * ppFace)
167 {
168     IDirect3DRMImpl *This = impl_from_IDirect3DRM(iface);
169
170     FIXME("(%p/%p)->(%p): stub\n", iface, This, ppFace);
171
172     return E_NOTIMPL;
173 }
174
175 static HRESULT WINAPI IDirect3DRMImpl_CreateAnimation(IDirect3DRM* iface, LPDIRECT3DRMANIMATION * ppAnimation)
176 {
177     IDirect3DRMImpl *This = impl_from_IDirect3DRM(iface);
178
179     FIXME("(%p/%p)->(%p): stub\n", iface, This, ppAnimation);
180
181     return E_NOTIMPL;
182 }
183
184 static HRESULT WINAPI IDirect3DRMImpl_CreateAnimationSet(IDirect3DRM* iface, LPDIRECT3DRMANIMATIONSET * ppAnimationSet)
185 {
186     IDirect3DRMImpl *This = impl_from_IDirect3DRM(iface);
187
188     FIXME("(%p/%p)->(%p): stub\n", iface, This, ppAnimationSet);
189
190     return E_NOTIMPL;
191 }
192
193 static HRESULT WINAPI IDirect3DRMImpl_CreateTexture(IDirect3DRM *iface,
194         D3DRMIMAGE *image, IDirect3DRMTexture **texture)
195 {
196     IDirect3DRMImpl *This = impl_from_IDirect3DRM(iface);
197
198     FIXME("(%p/%p)->(%p,%p): partial stub\n", iface, This, image, texture);
199
200     return Direct3DRMTexture_create(&IID_IDirect3DRMTexture, (IUnknown **)texture);
201 }
202
203 static HRESULT WINAPI IDirect3DRMImpl_CreateLight(IDirect3DRM* iface, D3DRMLIGHTTYPE type,
204                                                     D3DCOLOR color, LPDIRECT3DRMLIGHT* Light)
205 {
206     IDirect3DRMImpl *This = impl_from_IDirect3DRM(iface);
207
208     TRACE("(%p/%p)->(%d,%d,%p)\n", iface, This, type, color, Light);
209
210     return IDirect3DRM3_CreateLight(&This->IDirect3DRM3_iface, type, color, Light);
211 }
212
213 static HRESULT WINAPI IDirect3DRMImpl_CreateLightRGB(IDirect3DRM* iface, D3DRMLIGHTTYPE type,
214                                                        D3DVALUE red, D3DVALUE green, D3DVALUE blue,
215                                                        LPDIRECT3DRMLIGHT* Light)
216 {
217     IDirect3DRMImpl *This = impl_from_IDirect3DRM(iface);
218
219     TRACE("(%p/%p)->(%d,%f,%f,%f,%p)\n", iface, This, type, red, green, blue, Light);
220
221     return IDirect3DRM3_CreateLightRGB(&This->IDirect3DRM3_iface, type, red, green, blue, Light);
222 }
223
224 static HRESULT WINAPI IDirect3DRMImpl_CreateMaterial(IDirect3DRM* iface, D3DVALUE power, LPDIRECT3DRMMATERIAL * material)
225 {
226     IDirect3DRMImpl *This = impl_from_IDirect3DRM(iface);
227
228     TRACE("(%p/%p)->(%f,%p)\n", iface, This, power, material);
229
230     return IDirect3DRM3_CreateMaterial(&This->IDirect3DRM3_iface, power, (LPDIRECT3DRMMATERIAL2*)material);
231 }
232
233 static HRESULT WINAPI IDirect3DRMImpl_CreateDevice(IDirect3DRM *iface,
234         DWORD width, DWORD height, IDirect3DRMDevice **device)
235 {
236     FIXME("iface %p, width %u, height %u, device %p partial stub!\n", iface, width, height, device);
237
238     return Direct3DRMDevice_create(&IID_IDirect3DRMDevice, (IUnknown **)device);
239 }
240
241 static HRESULT WINAPI IDirect3DRMImpl_CreateDeviceFromSurface(IDirect3DRM *iface, GUID *pGUID,
242         IDirectDraw *pDD, IDirectDrawSurface *pDDSBack, IDirect3DRMDevice **ppDevice)
243 {
244     IDirect3DRMImpl *This = impl_from_IDirect3DRM(iface);
245
246     FIXME("(%p/%p)->(%s,%p,%p,%p): partial stub\n", iface, This, debugstr_guid(pGUID), pDD,
247           pDDSBack, ppDevice);
248
249     return Direct3DRMDevice_create(&IID_IDirect3DRMDevice, (IUnknown**)ppDevice);
250 }
251
252 static HRESULT WINAPI IDirect3DRMImpl_CreateDeviceFromD3D(IDirect3DRM *iface,
253         IDirect3D *pD3D, IDirect3DDevice *pD3DDev, IDirect3DRMDevice **ppDevice)
254 {
255     IDirect3DRMImpl *This = impl_from_IDirect3DRM(iface);
256
257     FIXME("(%p/%p)->(%p,%p,%p): partial stub\n", iface, This, pD3D, pD3DDev, ppDevice);
258
259     return Direct3DRMDevice_create(&IID_IDirect3DRMDevice, (IUnknown**)ppDevice);
260 }
261
262 static HRESULT WINAPI IDirect3DRMImpl_CreateDeviceFromClipper(IDirect3DRM *iface,
263         IDirectDrawClipper *pDDClipper, GUID *pGUID, int width, int height,
264         IDirect3DRMDevice **ppDevice)
265 {
266     IDirect3DRMImpl *This = impl_from_IDirect3DRM(iface);
267
268     FIXME("(%p/%p)->(%p,%s,%d,%d,%p): partial stub\n", iface, This, pDDClipper,
269           debugstr_guid(pGUID), width, height, ppDevice);
270
271     return Direct3DRMDevice_create(&IID_IDirect3DRMDevice, (IUnknown**)ppDevice);
272 }
273
274 static HRESULT WINAPI IDirect3DRMImpl_CreateTextureFromSurface(IDirect3DRM *iface,
275         IDirectDrawSurface *pDDS, IDirect3DRMTexture **ppTexture)
276 {
277     IDirect3DRMImpl *This = impl_from_IDirect3DRM(iface);
278
279     FIXME("(%p/%p)->(%p,%p): stub\n", iface, This, pDDS, ppTexture);
280
281     return E_NOTIMPL;
282 }
283
284 static HRESULT WINAPI IDirect3DRMImpl_CreateShadow(IDirect3DRM *iface, IDirect3DRMVisual *visual,
285         IDirect3DRMLight *light, D3DVALUE px, D3DVALUE py, D3DVALUE pz, D3DVALUE nx, D3DVALUE ny, D3DVALUE nz,
286         IDirect3DRMVisual **shadow)
287 {
288     FIXME("iface %p, visual %p, light %p, px %.8e, py %.8e, pz %.8e, nx %.8e, ny %.8e, nz %.8e, shadow %p stub!\n",
289             iface, visual, light, px, py, pz, nx, ny, nz, shadow);
290
291     return E_NOTIMPL;
292 }
293
294 static HRESULT WINAPI IDirect3DRMImpl_CreateViewport(IDirect3DRM *iface, IDirect3DRMDevice *device,
295         IDirect3DRMFrame *camera, DWORD x, DWORD y, DWORD width, DWORD height, IDirect3DRMViewport **viewport)
296 {
297     FIXME("iface %p, device %p, camera %p, x %u, y %u, width %u, height %u, viewport %p partial stub!\n",
298             iface, device, camera, x, y, width, height, viewport);
299
300     return Direct3DRMViewport_create(&IID_IDirect3DRMViewport, (IUnknown **)viewport);
301 }
302
303 static HRESULT WINAPI IDirect3DRMImpl_CreateWrap(IDirect3DRM *iface, D3DRMWRAPTYPE type, IDirect3DRMFrame *frame,
304         D3DVALUE ox, D3DVALUE oy, D3DVALUE oz, D3DVALUE dx, D3DVALUE dy, D3DVALUE dz,
305         D3DVALUE ux, D3DVALUE uy, D3DVALUE uz, D3DVALUE ou, D3DVALUE ov, D3DVALUE su, D3DVALUE sv,
306         IDirect3DRMWrap **wrap)
307 {
308     FIXME("iface %p, type %#x, frame %p, ox %.8e, oy %.8e, oz %.8e, dx %.8e, dy %.8e, dz %.8e, "
309             "ux %.8e, uy %.8e, uz %.8e, ou %.8e, ov %.8e, su %.8e, sv %.8e, wrap %p stub!\n",
310             iface, type, frame, ox, oy, oz, dx, dy, dz, ux, uy, uz, ou, ov, su, sv, wrap);
311
312     return E_NOTIMPL;
313 }
314
315 static HRESULT WINAPI IDirect3DRMImpl_CreateUserVisual(IDirect3DRM* iface, D3DRMUSERVISUALCALLBACK cb, LPVOID pArg, LPDIRECT3DRMUSERVISUAL * ppUserVisual)
316 {
317     IDirect3DRMImpl *This = impl_from_IDirect3DRM(iface);
318
319     FIXME("(%p/%p)->(%p,%p,%p): stub\n", iface, This, cb, pArg, ppUserVisual);
320
321     return E_NOTIMPL;
322 }
323
324 static HRESULT WINAPI IDirect3DRMImpl_LoadTexture(IDirect3DRM* iface, const char * filename, LPDIRECT3DRMTEXTURE * ppTexture)
325 {
326     IDirect3DRMImpl *This = impl_from_IDirect3DRM(iface);
327
328     FIXME("(%p/%p)->(%s,%p): stub\n", iface, This, filename, ppTexture);
329
330     return E_NOTIMPL;
331 }
332
333 static HRESULT WINAPI IDirect3DRMImpl_LoadTextureFromResource(IDirect3DRM* iface, HRSRC rs, LPDIRECT3DRMTEXTURE * ppTexture)
334 {
335     IDirect3DRMImpl *This = impl_from_IDirect3DRM(iface);
336
337     FIXME("(%p/%p)->(%p,%p): stub\n", iface, This, rs, ppTexture);
338
339     return E_NOTIMPL;
340 }
341
342 static HRESULT WINAPI IDirect3DRMImpl_SetSearchPath(IDirect3DRM* iface, LPCSTR path)
343 {
344     IDirect3DRMImpl *This = impl_from_IDirect3DRM(iface);
345
346     FIXME("(%p/%p)->(%s): stub\n", iface, This, path);
347
348     return E_NOTIMPL;
349 }
350
351 static HRESULT WINAPI IDirect3DRMImpl_AddSearchPath(IDirect3DRM* iface, LPCSTR path)
352 {
353     IDirect3DRMImpl *This = impl_from_IDirect3DRM(iface);
354
355     FIXME("(%p/%p)->(%s): stub\n", iface, This, path);
356
357     return E_NOTIMPL;
358 }
359
360 static HRESULT WINAPI IDirect3DRMImpl_GetSearchPath(IDirect3DRM* iface, DWORD *size_return, LPSTR path_return)
361 {
362     IDirect3DRMImpl *This = impl_from_IDirect3DRM(iface);
363
364     FIXME("(%p/%p)->(%p,%s): stub\n", iface, This, size_return, path_return);
365
366     return E_NOTIMPL;
367 }
368
369 static HRESULT WINAPI IDirect3DRMImpl_SetDefaultTextureColors(IDirect3DRM* iface, DWORD nb_colors)
370 {
371     IDirect3DRMImpl *This = impl_from_IDirect3DRM(iface);
372
373     FIXME("(%p/%p)->(%d): stub\n", iface, This, nb_colors);
374
375     return E_NOTIMPL;
376 }
377
378 static HRESULT WINAPI IDirect3DRMImpl_SetDefaultTextureShades(IDirect3DRM* iface, DWORD nb_shades)
379 {
380     IDirect3DRMImpl *This = impl_from_IDirect3DRM(iface);
381
382     FIXME("(%p/%p)->(%d): stub\n", iface, This, nb_shades);
383
384     return E_NOTIMPL;
385 }
386
387 static HRESULT WINAPI IDirect3DRMImpl_GetDevices(IDirect3DRM* iface, LPDIRECT3DRMDEVICEARRAY * ppDeviceArray)
388 {
389     IDirect3DRMImpl *This = impl_from_IDirect3DRM(iface);
390
391     FIXME("(%p/%p)->(%p): stub\n", iface, This, ppDeviceArray);
392
393     return E_NOTIMPL;
394 }
395
396 static HRESULT WINAPI IDirect3DRMImpl_GetNamedObject(IDirect3DRM *iface,
397         const char *name, IDirect3DRMObject **object)
398 {
399     FIXME("iface %p, name %s, object %p stub!\n", iface, debugstr_a(name), object);
400
401     return E_NOTIMPL;
402 }
403
404 static HRESULT WINAPI IDirect3DRMImpl_EnumerateObjects(IDirect3DRM* iface, D3DRMOBJECTCALLBACK cb, LPVOID pArg)
405 {
406     IDirect3DRMImpl *This = impl_from_IDirect3DRM(iface);
407
408     FIXME("(%p/%p)->(%p,%p): stub\n", iface, This, cb, pArg);
409
410     return E_NOTIMPL;
411 }
412
413 static HRESULT WINAPI IDirect3DRMImpl_Load(IDirect3DRM *iface, void *source, void *object_id, IID **iids,
414         DWORD iid_count, D3DRMLOADOPTIONS flags, D3DRMLOADCALLBACK load_cb, void *load_ctx,
415         D3DRMLOADTEXTURECALLBACK load_tex_cb, void *load_tex_ctx, IDirect3DRMFrame *parent_frame)
416 {
417     IDirect3DRMImpl *d3drm = impl_from_IDirect3DRM(iface);
418     IDirect3DRMFrame3 *parent_frame3 = NULL;
419     HRESULT hr = D3DRM_OK;
420
421     TRACE("iface %p, source %p, object_id %p, iids %p, iid_count %u, flags %#x, "
422             "load_cb %p, load_ctx %p, load_tex_cb %p, load_tex_ctx %p, parent_frame %p.\n",
423             iface, source, object_id, iids, iid_count, flags,
424             load_cb, load_ctx, load_tex_cb, load_tex_ctx, parent_frame);
425
426     if (parent_frame)
427         hr = IDirect3DRMFrame_QueryInterface(parent_frame, &IID_IDirect3DRMFrame3, (void **)&parent_frame3);
428     if (SUCCEEDED(hr))
429         hr = IDirect3DRM3_Load(&d3drm->IDirect3DRM3_iface, source, object_id, iids, iid_count,
430                 flags, load_cb, load_ctx, load_tex_cb, load_tex_ctx, parent_frame3);
431     if (parent_frame3)
432         IDirect3DRMFrame3_Release(parent_frame3);
433
434     return hr;
435 }
436
437 static HRESULT WINAPI IDirect3DRMImpl_Tick(IDirect3DRM* iface, D3DVALUE tick)
438 {
439     IDirect3DRMImpl *This = impl_from_IDirect3DRM(iface);
440
441     FIXME("(%p/%p)->(%f): stub\n", iface, This, tick);
442
443     return E_NOTIMPL;
444 }
445
446 static const struct IDirect3DRMVtbl Direct3DRM_Vtbl =
447 {
448     IDirect3DRMImpl_QueryInterface,
449     IDirect3DRMImpl_AddRef,
450     IDirect3DRMImpl_Release,
451     IDirect3DRMImpl_CreateObject,
452     IDirect3DRMImpl_CreateFrame,
453     IDirect3DRMImpl_CreateMesh,
454     IDirect3DRMImpl_CreateMeshBuilder,
455     IDirect3DRMImpl_CreateFace,
456     IDirect3DRMImpl_CreateAnimation,
457     IDirect3DRMImpl_CreateAnimationSet,
458     IDirect3DRMImpl_CreateTexture,
459     IDirect3DRMImpl_CreateLight,
460     IDirect3DRMImpl_CreateLightRGB,
461     IDirect3DRMImpl_CreateMaterial,
462     IDirect3DRMImpl_CreateDevice,
463     IDirect3DRMImpl_CreateDeviceFromSurface,
464     IDirect3DRMImpl_CreateDeviceFromD3D,
465     IDirect3DRMImpl_CreateDeviceFromClipper,
466     IDirect3DRMImpl_CreateTextureFromSurface,
467     IDirect3DRMImpl_CreateShadow,
468     IDirect3DRMImpl_CreateViewport,
469     IDirect3DRMImpl_CreateWrap,
470     IDirect3DRMImpl_CreateUserVisual,
471     IDirect3DRMImpl_LoadTexture,
472     IDirect3DRMImpl_LoadTextureFromResource,
473     IDirect3DRMImpl_SetSearchPath,
474     IDirect3DRMImpl_AddSearchPath,
475     IDirect3DRMImpl_GetSearchPath,
476     IDirect3DRMImpl_SetDefaultTextureColors,
477     IDirect3DRMImpl_SetDefaultTextureShades,
478     IDirect3DRMImpl_GetDevices,
479     IDirect3DRMImpl_GetNamedObject,
480     IDirect3DRMImpl_EnumerateObjects,
481     IDirect3DRMImpl_Load,
482     IDirect3DRMImpl_Tick
483 };
484
485
486 /*** IUnknown methods ***/
487 static HRESULT WINAPI IDirect3DRM2Impl_QueryInterface(IDirect3DRM2* iface, REFIID riid,
488                                                       void** ppvObject)
489 {
490     IDirect3DRMImpl *This = impl_from_IDirect3DRM2(iface);
491     return IDirect3DRM_QueryInterface(&This->IDirect3DRM_iface, riid, ppvObject);
492 }
493
494 static ULONG WINAPI IDirect3DRM2Impl_AddRef(IDirect3DRM2* iface)
495 {
496     IDirect3DRMImpl *This = impl_from_IDirect3DRM2(iface);
497     return IDirect3DRM_AddRef(&This->IDirect3DRM_iface);
498 }
499
500 static ULONG WINAPI IDirect3DRM2Impl_Release(IDirect3DRM2* iface)
501 {
502     IDirect3DRMImpl *This = impl_from_IDirect3DRM2(iface);
503     return IDirect3DRM_Release(&This->IDirect3DRM_iface);
504 }
505
506 /*** IDirect3DRM2 methods ***/
507 static HRESULT WINAPI IDirect3DRM2Impl_CreateObject(IDirect3DRM2* iface, REFCLSID rclsid,
508                                                     LPUNKNOWN pUnkOuter, REFIID riid,
509                                                     LPVOID *ppvObj)
510 {
511     IDirect3DRMImpl *This = impl_from_IDirect3DRM2(iface);
512
513     FIXME("(%p/%p)->(%s,%p,%s,%p): stub\n", iface, This, debugstr_guid(rclsid), pUnkOuter,
514                                             debugstr_guid(riid), ppvObj);
515
516     return E_NOTIMPL;
517 }
518
519 static HRESULT WINAPI IDirect3DRM2Impl_CreateFrame(IDirect3DRM2 *iface,
520         IDirect3DRMFrame *parent_frame, IDirect3DRMFrame2 **frame)
521 {
522     IDirect3DRMImpl *This = impl_from_IDirect3DRM2(iface);
523
524     TRACE("(%p/%p)->(%p,%p)\n", iface, This, parent_frame, frame);
525
526     return Direct3DRMFrame_create(&IID_IDirect3DRMFrame2, (IUnknown*)parent_frame, (IUnknown**)frame);
527 }
528
529 static HRESULT WINAPI IDirect3DRM2Impl_CreateMesh(IDirect3DRM2* iface, LPDIRECT3DRMMESH * ppMesh)
530 {
531     IDirect3DRMImpl *This = impl_from_IDirect3DRM2(iface);
532
533     TRACE("(%p/%p)->(%p)\n", iface, This, ppMesh);
534
535     return IDirect3DRM3_CreateMesh(&This->IDirect3DRM3_iface, ppMesh);
536 }
537
538 static HRESULT WINAPI IDirect3DRM2Impl_CreateMeshBuilder(IDirect3DRM2* iface,
539                                                          LPDIRECT3DRMMESHBUILDER2 * ppMeshBuilder)
540 {
541     IDirect3DRMImpl *This = impl_from_IDirect3DRM2(iface);
542
543     TRACE("(%p/%p)->(%p)\n", iface, This, ppMeshBuilder);
544
545     return Direct3DRMMeshBuilder_create(&IID_IDirect3DRMMeshBuilder2, (IUnknown**)ppMeshBuilder);
546 }
547
548 static HRESULT WINAPI IDirect3DRM2Impl_CreateFace(IDirect3DRM2* iface, LPDIRECT3DRMFACE * ppFace)
549 {
550     IDirect3DRMImpl *This = impl_from_IDirect3DRM2(iface);
551
552     FIXME("(%p/%p)->(%p): stub\n", iface, This, ppFace);
553
554     return E_NOTIMPL;
555 }
556
557 static HRESULT WINAPI IDirect3DRM2Impl_CreateAnimation(IDirect3DRM2* iface,
558                                                        LPDIRECT3DRMANIMATION * ppAnimation)
559 {
560     IDirect3DRMImpl *This = impl_from_IDirect3DRM2(iface);
561
562     FIXME("(%p/%p)->(%p): stub\n", iface, This, ppAnimation);
563
564     return E_NOTIMPL;
565 }
566
567 static HRESULT WINAPI IDirect3DRM2Impl_CreateAnimationSet(IDirect3DRM2* iface,
568                                                           LPDIRECT3DRMANIMATIONSET * ppAnimationSet)
569 {
570     IDirect3DRMImpl *This = impl_from_IDirect3DRM2(iface);
571
572     FIXME("(%p/%p)->(%p): stub\n", iface, This, ppAnimationSet);
573
574     return E_NOTIMPL;
575 }
576
577 static HRESULT WINAPI IDirect3DRM2Impl_CreateTexture(IDirect3DRM2 *iface,
578         D3DRMIMAGE *image, IDirect3DRMTexture2 **texture)
579 {
580     IDirect3DRMImpl *This = impl_from_IDirect3DRM2(iface);
581
582     FIXME("(%p/%p)->(%p,%p): partial stub\n", iface, This, image, texture);
583
584     return Direct3DRMTexture_create(&IID_IDirect3DRMTexture2, (IUnknown **)texture);
585 }
586
587 static HRESULT WINAPI IDirect3DRM2Impl_CreateLight(IDirect3DRM2* iface, D3DRMLIGHTTYPE type,
588                                                      D3DCOLOR color, LPDIRECT3DRMLIGHT* Light)
589 {
590     IDirect3DRMImpl *This = impl_from_IDirect3DRM2(iface);
591
592     TRACE("(%p/%p)->(%d,%d,%p)\n", iface, This, type, color, Light);
593
594     return IDirect3DRM3_CreateLight(&This->IDirect3DRM3_iface, type, color, Light);
595 }
596
597 static HRESULT WINAPI IDirect3DRM2Impl_CreateLightRGB(IDirect3DRM2* iface, D3DRMLIGHTTYPE type,
598                                                         D3DVALUE red, D3DVALUE green, D3DVALUE blue,
599                                                         LPDIRECT3DRMLIGHT* Light)
600 {
601     IDirect3DRMImpl *This = impl_from_IDirect3DRM2(iface);
602
603     TRACE("(%p/%p)->(%d,%f,%f,%f,%p)\n", iface, This, type, red, green, blue, Light);
604
605     return IDirect3DRM3_CreateLightRGB(&This->IDirect3DRM3_iface, type, red, green, blue, Light);
606 }
607
608 static HRESULT WINAPI IDirect3DRM2Impl_CreateMaterial(IDirect3DRM2* iface, D3DVALUE power,
609                                                       LPDIRECT3DRMMATERIAL * material)
610 {
611     IDirect3DRMImpl *This = impl_from_IDirect3DRM2(iface);
612
613     TRACE("(%p/%p)->(%f,%p)\n", iface, This, power, material);
614
615     return IDirect3DRM3_CreateMaterial(&This->IDirect3DRM3_iface, power, (LPDIRECT3DRMMATERIAL2*)material);
616 }
617
618 static HRESULT WINAPI IDirect3DRM2Impl_CreateDevice(IDirect3DRM2 *iface,
619         DWORD width, DWORD height, IDirect3DRMDevice2 **device)
620 {
621     FIXME("iface %p, width %u, height %u, device %p.\n", iface, width, height, device);
622
623     return Direct3DRMDevice_create(&IID_IDirect3DRMDevice2, (IUnknown **)device);
624 }
625
626 static HRESULT WINAPI IDirect3DRM2Impl_CreateDeviceFromSurface(IDirect3DRM2 *iface, GUID *pGUID,
627         IDirectDraw *pDD, IDirectDrawSurface *pDDSBack, IDirect3DRMDevice2 **ppDevice)
628 {
629     IDirect3DRMImpl *This = impl_from_IDirect3DRM2(iface);
630
631     FIXME("(%p/%p)->(%s,%p,%p,%p): partial stub\n", iface, This, debugstr_guid(pGUID),
632           pDD, pDDSBack, ppDevice);
633
634     return Direct3DRMDevice_create(&IID_IDirect3DRMDevice2, (IUnknown**)ppDevice);
635 }
636
637 static HRESULT WINAPI IDirect3DRM2Impl_CreateDeviceFromD3D(IDirect3DRM2 *iface,
638         IDirect3D2 *pD3D, IDirect3DDevice2 *pD3DDev, IDirect3DRMDevice2 **ppDevice)
639 {
640     IDirect3DRMImpl *This = impl_from_IDirect3DRM2(iface);
641
642     FIXME("(%p/%p)->(%p,%p,%p): partial stub\n", iface, This, pD3D, pD3DDev, ppDevice);
643
644     return Direct3DRMDevice_create(&IID_IDirect3DRMDevice2, (IUnknown**)ppDevice);
645 }
646
647 static HRESULT WINAPI IDirect3DRM2Impl_CreateDeviceFromClipper(IDirect3DRM2 *iface,
648         IDirectDrawClipper *pDDClipper, GUID *pGUID, int width, int height,
649         IDirect3DRMDevice2 **ppDevice)
650 {
651     IDirect3DRMImpl *This = impl_from_IDirect3DRM2(iface);
652
653     FIXME("(%p/%p)->(%p,%s,%d,%d,%p): partial stub\n", iface, This, pDDClipper,
654           debugstr_guid(pGUID), width, height, ppDevice);
655
656     return Direct3DRMDevice_create(&IID_IDirect3DRMDevice2, (IUnknown**)ppDevice);
657 }
658
659 static HRESULT WINAPI IDirect3DRM2Impl_CreateTextureFromSurface(IDirect3DRM2 *iface,
660         IDirectDrawSurface *pDDS, IDirect3DRMTexture2 **ppTexture)
661 {
662     IDirect3DRMImpl *This = impl_from_IDirect3DRM2(iface);
663
664     FIXME("(%p/%p)->(%p,%p): stub\n", iface, This, pDDS, ppTexture);
665
666     return E_NOTIMPL;
667 }
668
669 static HRESULT WINAPI IDirect3DRM2Impl_CreateShadow(IDirect3DRM2 *iface, IDirect3DRMVisual *visual,
670         IDirect3DRMLight *light, D3DVALUE px, D3DVALUE py, D3DVALUE pz, D3DVALUE nx, D3DVALUE ny, D3DVALUE nz,
671         IDirect3DRMVisual **shadow)
672 {
673     FIXME("iface %p, visual %p, light %p, px %.8e, py %.8e, pz %.8e, nx %.8e, ny %.8e, nz %.8e, shadow %p stub!\n",
674             iface, visual, light, px, py, pz, nx, ny, nz, shadow);
675
676     return E_NOTIMPL;
677 }
678
679 static HRESULT WINAPI IDirect3DRM2Impl_CreateViewport(IDirect3DRM2 *iface, IDirect3DRMDevice *device,
680         IDirect3DRMFrame *camera, DWORD x, DWORD y, DWORD width, DWORD height, IDirect3DRMViewport **viewport)
681 {
682     FIXME("iface %p, device %p, camera %p, x %u, y %u, width %u, height %u, viewport %p partial stub!\n",
683             iface, device, camera, x, y, width, height, viewport);
684
685     return Direct3DRMViewport_create(&IID_IDirect3DRMViewport, (IUnknown **)viewport);
686 }
687
688 static HRESULT WINAPI IDirect3DRM2Impl_CreateWrap(IDirect3DRM2 *iface, D3DRMWRAPTYPE type, IDirect3DRMFrame *frame,
689         D3DVALUE ox, D3DVALUE oy, D3DVALUE oz, D3DVALUE dx, D3DVALUE dy, D3DVALUE dz,
690         D3DVALUE ux, D3DVALUE uy, D3DVALUE uz, D3DVALUE ou, D3DVALUE ov, D3DVALUE su, D3DVALUE sv,
691         IDirect3DRMWrap **wrap)
692 {
693     FIXME("iface %p, type %#x, frame %p, ox %.8e, oy %.8e, oz %.8e, dx %.8e, dy %.8e, dz %.8e, "
694             "ux %.8e, uy %.8e, uz %.8e, ou %.8e, ov %.8e, su %.8e, sv %.8e, wrap %p stub!\n",
695             iface, type, frame, ox, oy, oz, dx, dy, dz, ux, uy, uz, ou, ov, su, sv, wrap);
696
697     return E_NOTIMPL;
698 }
699
700 static HRESULT WINAPI IDirect3DRM2Impl_CreateUserVisual(IDirect3DRM2* iface,
701                                                         D3DRMUSERVISUALCALLBACK cb, LPVOID pArg,
702                                                         LPDIRECT3DRMUSERVISUAL * ppUserVisual)
703 {
704     IDirect3DRMImpl *This = impl_from_IDirect3DRM2(iface);
705
706     FIXME("(%p/%p)->(%p,%p,%p): stub\n", iface, This, cb, pArg, ppUserVisual);
707
708     return E_NOTIMPL;
709 }
710
711 static HRESULT WINAPI IDirect3DRM2Impl_LoadTexture(IDirect3DRM2* iface, const char * filename,
712                                                    LPDIRECT3DRMTEXTURE2 * ppTexture)
713 {
714     IDirect3DRMImpl *This = impl_from_IDirect3DRM2(iface);
715
716     FIXME("(%p/%p)->(%s,%p): stub\n", iface, This, filename, ppTexture);
717
718     return E_NOTIMPL;
719 }
720
721 static HRESULT WINAPI IDirect3DRM2Impl_LoadTextureFromResource(IDirect3DRM2* iface, HMODULE hModule,
722                                                                LPCSTR strName, LPCSTR strType,
723                                                                LPDIRECT3DRMTEXTURE2 * ppTexture)
724 {
725     IDirect3DRMImpl *This = impl_from_IDirect3DRM2(iface);
726
727     FIXME("(%p/%p)->(%p,%p,%p,%p): stub\n", iface, This, hModule, strName, strType, ppTexture);
728
729     return E_NOTIMPL;
730 }
731
732 static HRESULT WINAPI IDirect3DRM2Impl_SetSearchPath(IDirect3DRM2* iface, LPCSTR path)
733 {
734     IDirect3DRMImpl *This = impl_from_IDirect3DRM2(iface);
735
736     FIXME("(%p/%p)->(%s): stub\n", iface, This, path);
737
738     return E_NOTIMPL;
739 }
740
741 static HRESULT WINAPI IDirect3DRM2Impl_AddSearchPath(IDirect3DRM2* iface, LPCSTR path)
742 {
743     IDirect3DRMImpl *This = impl_from_IDirect3DRM2(iface);
744
745     FIXME("(%p/%p)->(%s): stub\n", iface, This, path);
746
747     return E_NOTIMPL;
748 }
749
750 static HRESULT WINAPI IDirect3DRM2Impl_GetSearchPath(IDirect3DRM2* iface, DWORD *size_return,
751                                                      LPSTR path_return)
752 {
753     IDirect3DRMImpl *This = impl_from_IDirect3DRM2(iface);
754
755     FIXME("(%p/%p)->(%p,%s): stub\n", iface, This, size_return, path_return);
756
757     return E_NOTIMPL;
758 }
759
760 static HRESULT WINAPI IDirect3DRM2Impl_SetDefaultTextureColors(IDirect3DRM2* iface, DWORD nb_colors)
761 {
762     IDirect3DRMImpl *This = impl_from_IDirect3DRM2(iface);
763
764     FIXME("(%p/%p)->(%d): stub\n", iface, This, nb_colors);
765
766     return E_NOTIMPL;
767 }
768
769 static HRESULT WINAPI IDirect3DRM2Impl_SetDefaultTextureShades(IDirect3DRM2* iface, DWORD nb_shades)
770 {
771     IDirect3DRMImpl *This = impl_from_IDirect3DRM2(iface);
772
773     FIXME("(%p/%p)->(%d): stub\n", iface, This, nb_shades);
774
775     return E_NOTIMPL;
776 }
777
778 static HRESULT WINAPI IDirect3DRM2Impl_GetDevices(IDirect3DRM2* iface,
779                                                   LPDIRECT3DRMDEVICEARRAY * ppDeviceArray)
780 {
781     IDirect3DRMImpl *This = impl_from_IDirect3DRM2(iface);
782
783     FIXME("(%p/%p)->(%p): stub\n", iface, This, ppDeviceArray);
784
785     return E_NOTIMPL;
786 }
787
788 static HRESULT WINAPI IDirect3DRM2Impl_GetNamedObject(IDirect3DRM2 *iface,
789         const char *name, IDirect3DRMObject **object)
790 {
791     FIXME("iface %p, name %s, object %p stub!\n", iface, debugstr_a(name), object);
792
793     return E_NOTIMPL;
794 }
795
796 static HRESULT WINAPI IDirect3DRM2Impl_EnumerateObjects(IDirect3DRM2* iface, D3DRMOBJECTCALLBACK cb,
797                                                         LPVOID pArg)
798 {
799     IDirect3DRMImpl *This = impl_from_IDirect3DRM2(iface);
800
801     FIXME("(%p/%p)->(%p,%p): stub\n", iface, This, cb, pArg);
802
803     return E_NOTIMPL;
804 }
805
806 static HRESULT WINAPI IDirect3DRM2Impl_Load(IDirect3DRM2 *iface, void *source, void *object_id, IID **iids,
807         DWORD iid_count, D3DRMLOADOPTIONS flags, D3DRMLOADCALLBACK load_cb, void *load_ctx,
808         D3DRMLOADTEXTURECALLBACK load_tex_cb, void *load_tex_ctx, IDirect3DRMFrame *parent_frame)
809 {
810     IDirect3DRMImpl *d3drm = impl_from_IDirect3DRM2(iface);
811     IDirect3DRMFrame3 *parent_frame3 = NULL;
812     HRESULT hr = D3DRM_OK;
813
814     TRACE("iface %p, source %p, object_id %p, iids %p, iid_count %u, flags %#x, "
815             "load_cb %p, load_ctx %p, load_tex_cb %p, load_tex_ctx %p, parent_frame %p.\n",
816             iface, source, object_id, iids, iid_count, flags,
817             load_cb, load_ctx, load_tex_cb, load_tex_ctx, parent_frame);
818
819     if (parent_frame)
820         hr = IDirect3DRMFrame_QueryInterface(parent_frame, &IID_IDirect3DRMFrame3, (void **)&parent_frame3);
821     if (SUCCEEDED(hr))
822         hr = IDirect3DRM3_Load(&d3drm->IDirect3DRM3_iface, source, object_id, iids, iid_count,
823                 flags, load_cb, load_ctx, load_tex_cb, load_tex_ctx, parent_frame3);
824     if (parent_frame3)
825         IDirect3DRMFrame3_Release(parent_frame3);
826
827     return hr;
828 }
829
830 static HRESULT WINAPI IDirect3DRM2Impl_Tick(IDirect3DRM2* iface, D3DVALUE tick)
831 {
832     IDirect3DRMImpl *This = impl_from_IDirect3DRM2(iface);
833
834     FIXME("(%p/%p)->(%f): stub\n", iface, This, tick);
835
836     return E_NOTIMPL;
837 }
838
839 static HRESULT WINAPI IDirect3DRM2Impl_CreateProgressiveMesh(IDirect3DRM2* iface,
840                                                              LPDIRECT3DRMPROGRESSIVEMESH * ppMesh)
841 {
842     IDirect3DRMImpl *This = impl_from_IDirect3DRM2(iface);
843
844     FIXME("(%p/%p)->(%p): stub\n", iface, This, ppMesh);
845
846     return E_NOTIMPL;
847 }
848
849 static const struct IDirect3DRM2Vtbl Direct3DRM2_Vtbl =
850 {
851     IDirect3DRM2Impl_QueryInterface,
852     IDirect3DRM2Impl_AddRef,
853     IDirect3DRM2Impl_Release,
854     IDirect3DRM2Impl_CreateObject,
855     IDirect3DRM2Impl_CreateFrame,
856     IDirect3DRM2Impl_CreateMesh,
857     IDirect3DRM2Impl_CreateMeshBuilder,
858     IDirect3DRM2Impl_CreateFace,
859     IDirect3DRM2Impl_CreateAnimation,
860     IDirect3DRM2Impl_CreateAnimationSet,
861     IDirect3DRM2Impl_CreateTexture,
862     IDirect3DRM2Impl_CreateLight,
863     IDirect3DRM2Impl_CreateLightRGB,
864     IDirect3DRM2Impl_CreateMaterial,
865     IDirect3DRM2Impl_CreateDevice,
866     IDirect3DRM2Impl_CreateDeviceFromSurface,
867     IDirect3DRM2Impl_CreateDeviceFromD3D,
868     IDirect3DRM2Impl_CreateDeviceFromClipper,
869     IDirect3DRM2Impl_CreateTextureFromSurface,
870     IDirect3DRM2Impl_CreateShadow,
871     IDirect3DRM2Impl_CreateViewport,
872     IDirect3DRM2Impl_CreateWrap,
873     IDirect3DRM2Impl_CreateUserVisual,
874     IDirect3DRM2Impl_LoadTexture,
875     IDirect3DRM2Impl_LoadTextureFromResource,
876     IDirect3DRM2Impl_SetSearchPath,
877     IDirect3DRM2Impl_AddSearchPath,
878     IDirect3DRM2Impl_GetSearchPath,
879     IDirect3DRM2Impl_SetDefaultTextureColors,
880     IDirect3DRM2Impl_SetDefaultTextureShades,
881     IDirect3DRM2Impl_GetDevices,
882     IDirect3DRM2Impl_GetNamedObject,
883     IDirect3DRM2Impl_EnumerateObjects,
884     IDirect3DRM2Impl_Load,
885     IDirect3DRM2Impl_Tick,
886     IDirect3DRM2Impl_CreateProgressiveMesh
887 };
888
889
890 /*** IUnknown methods ***/
891 static HRESULT WINAPI IDirect3DRM3Impl_QueryInterface(IDirect3DRM3* iface, REFIID riid,
892                                                       void** ppvObject)
893 {
894     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
895     return IDirect3DRM_QueryInterface(&This->IDirect3DRM_iface, riid, ppvObject);
896 }
897
898 static ULONG WINAPI IDirect3DRM3Impl_AddRef(IDirect3DRM3* iface)
899 {
900     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
901     return IDirect3DRM_AddRef(&This->IDirect3DRM_iface);
902 }
903
904 static ULONG WINAPI IDirect3DRM3Impl_Release(IDirect3DRM3* iface)
905 {
906     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
907     return IDirect3DRM_Release(&This->IDirect3DRM_iface);
908 }
909
910 /*** IDirect3DRM3 methods ***/
911 static HRESULT WINAPI IDirect3DRM3Impl_CreateObject(IDirect3DRM3* iface, REFCLSID rclsid,
912                                                     LPUNKNOWN unkwn, REFIID riid, LPVOID* object)
913 {
914     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
915
916     FIXME("(%p/%p)->(%s,%p,%s,%p): stub\n", iface, This, debugstr_guid(rclsid), unkwn,
917           debugstr_guid(riid), object);
918
919     return E_NOTIMPL;
920 }
921
922 static HRESULT WINAPI IDirect3DRM3Impl_CreateFrame(IDirect3DRM3 *iface,
923         IDirect3DRMFrame3 *parent, IDirect3DRMFrame3 **frame)
924 {
925     TRACE("iface %p, parent %p, frame %p.\n", iface, parent, frame);
926
927     return Direct3DRMFrame_create(&IID_IDirect3DRMFrame3, (IUnknown *)parent, (IUnknown **)frame);
928 }
929
930 static HRESULT WINAPI IDirect3DRM3Impl_CreateMesh(IDirect3DRM3* iface, LPDIRECT3DRMMESH* Mesh)
931 {
932     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
933
934     TRACE("(%p/%p)->(%p)\n", iface, This, Mesh);
935
936     return Direct3DRMMesh_create(Mesh);
937 }
938
939 static HRESULT WINAPI IDirect3DRM3Impl_CreateMeshBuilder(IDirect3DRM3* iface,
940                                                          LPDIRECT3DRMMESHBUILDER3* ppMeshBuilder)
941 {
942     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
943
944     TRACE("(%p/%p)->(%p)\n", iface, This, ppMeshBuilder);
945
946     return Direct3DRMMeshBuilder_create(&IID_IDirect3DRMMeshBuilder3, (IUnknown**)ppMeshBuilder);
947 }
948
949 static HRESULT WINAPI IDirect3DRM3Impl_CreateFace(IDirect3DRM3* iface, LPDIRECT3DRMFACE2* Face)
950 {
951     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
952
953     FIXME("(%p/%p)->(%p): stub\n", iface, This, Face);
954
955     return E_NOTIMPL;
956 }
957
958 static HRESULT WINAPI IDirect3DRM3Impl_CreateAnimation(IDirect3DRM3* iface,
959                                                        LPDIRECT3DRMANIMATION2* Animation)
960 {
961     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
962
963     FIXME("(%p/%p)->(%p): stub\n", iface, This, Animation);
964
965     return E_NOTIMPL;
966 }
967
968 static HRESULT WINAPI IDirect3DRM3Impl_CreateAnimationSet(IDirect3DRM3* iface,
969                                                           LPDIRECT3DRMANIMATIONSET2* AnimationSet)
970 {
971     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
972
973     FIXME("(%p/%p)->(%p): stub\n", iface, This, AnimationSet);
974
975     return E_NOTIMPL;
976 }
977
978 static HRESULT WINAPI IDirect3DRM3Impl_CreateTexture(IDirect3DRM3 *iface,
979         D3DRMIMAGE *image, IDirect3DRMTexture3 **texture)
980 {
981     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
982
983     FIXME("(%p/%p)->(%p,%p): partial stub\n", iface, This, image, texture);
984
985     return Direct3DRMTexture_create(&IID_IDirect3DRMTexture3, (IUnknown **)texture);
986 }
987
988 static HRESULT WINAPI IDirect3DRM3Impl_CreateLight(IDirect3DRM3* iface, D3DRMLIGHTTYPE type,
989                                                      D3DCOLOR color, LPDIRECT3DRMLIGHT* Light)
990 {
991     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
992     HRESULT ret;
993
994     FIXME("(%p/%p)->(%d,%d,%p): partial stub\n", iface, This, type, color, Light);
995
996     ret = Direct3DRMLight_create((IUnknown**)Light);
997
998     if (SUCCEEDED(ret))
999     {
1000         IDirect3DRMLight_SetType(*Light, type);
1001         IDirect3DRMLight_SetColor(*Light, color);
1002     }
1003
1004     return ret;
1005 }
1006
1007 static HRESULT WINAPI IDirect3DRM3Impl_CreateLightRGB(IDirect3DRM3* iface, D3DRMLIGHTTYPE type,
1008                                                         D3DVALUE red, D3DVALUE green, D3DVALUE blue,
1009                                                         LPDIRECT3DRMLIGHT* Light)
1010 {
1011     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
1012     HRESULT ret;
1013
1014     FIXME("(%p/%p)->(%d,%f,%f,%f,%p): partial stub\n", iface, This, type, red, green, blue, Light);
1015
1016     ret = Direct3DRMLight_create((IUnknown**)Light);
1017
1018     if (SUCCEEDED(ret))
1019     {
1020         IDirect3DRMLight_SetType(*Light, type);
1021         IDirect3DRMLight_SetColorRGB(*Light, red, green, blue);
1022     }
1023
1024     return ret;
1025 }
1026
1027 static HRESULT WINAPI IDirect3DRM3Impl_CreateMaterial(IDirect3DRM3* iface, D3DVALUE power,
1028                                                       LPDIRECT3DRMMATERIAL2* material)
1029 {
1030     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
1031     HRESULT ret;
1032
1033     TRACE("(%p/%p)->(%f,%p)\n", iface, This, power, material);
1034
1035     ret = Direct3DRMMaterial_create(material);
1036
1037     if (SUCCEEDED(ret))
1038         IDirect3DRMMaterial2_SetPower(*material, power);
1039
1040     return ret;
1041 }
1042
1043 static HRESULT WINAPI IDirect3DRM3Impl_CreateDevice(IDirect3DRM3 *iface,
1044         DWORD width, DWORD height, IDirect3DRMDevice3 **device)
1045 {
1046     FIXME("iface %p, width %u, height %u, device %p partial stub!\n", iface, width, height, device);
1047
1048     return Direct3DRMDevice_create(&IID_IDirect3DRMDevice3, (IUnknown **)device);
1049 }
1050
1051 static HRESULT WINAPI IDirect3DRM3Impl_CreateDeviceFromSurface(IDirect3DRM3 *iface, GUID *pGUID,
1052         IDirectDraw *dd, IDirectDrawSurface *back, IDirect3DRMDevice3 **device)
1053 {
1054     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
1055
1056     FIXME("(%p/%p)->(%s,%p,%p,%p): partial stub\n", iface, This, debugstr_guid(pGUID), dd, back, device);
1057
1058     return Direct3DRMDevice_create(&IID_IDirect3DRMDevice3, (IUnknown**)device);
1059 }
1060
1061 static HRESULT WINAPI IDirect3DRM3Impl_CreateDeviceFromD3D(IDirect3DRM3 *iface,
1062         IDirect3D2 *d3d, IDirect3DDevice2 *d3ddev, IDirect3DRMDevice3 **device)
1063 {
1064     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
1065
1066     FIXME("(%p/%p)->(%p,%p,%p): partial stub\n", iface, This, d3d, d3ddev, device);
1067
1068     return Direct3DRMDevice_create(&IID_IDirect3DRMDevice3, (IUnknown**)device);
1069 }
1070
1071 static HRESULT WINAPI IDirect3DRM3Impl_CreateDeviceFromClipper(IDirect3DRM3 *iface,
1072         IDirectDrawClipper *clipper, GUID *guid, int width, int height,
1073         IDirect3DRMDevice3 **device)
1074 {
1075     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
1076
1077     FIXME("(%p/%p)->(%p,%s,%d,%d,%p): partial stub\n", iface, This, clipper, debugstr_guid(guid),
1078           width, height, device);
1079
1080     return Direct3DRMDevice_create(&IID_IDirect3DRMDevice3, (IUnknown**)device);
1081 }
1082
1083 static HRESULT WINAPI IDirect3DRM3Impl_CreateShadow(IDirect3DRM3* iface, LPUNKNOWN Visual1,
1084                                                     LPDIRECT3DRMLIGHT Light, D3DVALUE px,
1085                                                     D3DVALUE py, D3DVALUE pz, D3DVALUE nx,
1086                                                     D3DVALUE ny, D3DVALUE nz,
1087                                                     LPDIRECT3DRMSHADOW2* Visual2)
1088 {
1089     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
1090
1091     FIXME("(%p/%p)->(%p,%p,%f,%f,%f,%f,%f,%f,%p): stub\n", iface, This, Visual1, Light, px, py, pz,
1092           nx, ny, nz, Visual2);
1093
1094     return E_NOTIMPL;
1095 }
1096
1097 static HRESULT WINAPI IDirect3DRM3Impl_CreateTextureFromSurface(IDirect3DRM3 *iface,
1098         IDirectDrawSurface *surface, IDirect3DRMTexture3 **texture)
1099 {
1100     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
1101
1102     FIXME("(%p/%p)->(%p,%p): stub\n", iface, This, surface, texture);
1103
1104     return E_NOTIMPL;
1105 }
1106
1107 static HRESULT WINAPI IDirect3DRM3Impl_CreateViewport(IDirect3DRM3 *iface, IDirect3DRMDevice3 *device,
1108         IDirect3DRMFrame3 *camera, DWORD x, DWORD y, DWORD width, DWORD height, IDirect3DRMViewport2 **viewport)
1109 {
1110     FIXME("iface %p, device %p, camera %p, x %u, y %u, width %u, height %u, viewport %p partial stub!\n",
1111             iface, device, camera, x, y, width, height, viewport);
1112
1113     return Direct3DRMViewport_create(&IID_IDirect3DRMViewport2, (IUnknown **)viewport);
1114 }
1115
1116 static HRESULT WINAPI IDirect3DRM3Impl_CreateWrap(IDirect3DRM3 *iface, D3DRMWRAPTYPE type, IDirect3DRMFrame3 *frame,
1117         D3DVALUE ox, D3DVALUE oy, D3DVALUE oz, D3DVALUE dx, D3DVALUE dy, D3DVALUE dz,
1118         D3DVALUE ux, D3DVALUE uy, D3DVALUE uz, D3DVALUE ou, D3DVALUE ov, D3DVALUE su, D3DVALUE sv,
1119         IDirect3DRMWrap **wrap)
1120 {
1121     FIXME("iface %p, type %#x, frame %p, ox %.8e, oy %.8e, oz %.8e, dx %.8e, dy %.8e, dz %.8e, "
1122             "ux %.8e, uy %.8e, uz %.8e, ou %.8e, ov %.8e, su %.8e, sv %.8e, wrap %p stub!\n",
1123             iface, type, frame, ox, oy, oz, dx, dy, dz, ux, uy, uz, ou, ov, su, sv, wrap);
1124
1125     return E_NOTIMPL;
1126 }
1127
1128 static HRESULT WINAPI IDirect3DRM3Impl_CreateUserVisual(IDirect3DRM3* iface,
1129                                                         D3DRMUSERVISUALCALLBACK cb, LPVOID arg,
1130                                                         LPDIRECT3DRMUSERVISUAL* UserVisual)
1131 {
1132     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
1133
1134     FIXME("(%p/%p)->(%p,%p,%p): stub\n", iface, This, cb, arg, UserVisual);
1135
1136     return E_NOTIMPL;
1137 }
1138
1139 static HRESULT WINAPI IDirect3DRM3Impl_LoadTexture(IDirect3DRM3* iface, const char* filename,
1140                                                    LPDIRECT3DRMTEXTURE3* Texture)
1141 {
1142     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
1143
1144     FIXME("(%p/%p)->(%s,%p): stub\n", iface, This, filename, Texture);
1145
1146     return E_NOTIMPL;
1147 }
1148
1149 static HRESULT WINAPI IDirect3DRM3Impl_LoadTextureFromResource(IDirect3DRM3* iface, HMODULE mod,
1150                                                                LPCSTR strName, LPCSTR strType,
1151                                                                LPDIRECT3DRMTEXTURE3 * ppTexture)
1152 {
1153     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
1154
1155     FIXME("(%p/%p)->(%p,%p,%p,%p): stub\n", iface, This, mod, strName, strType, ppTexture);
1156
1157     return E_NOTIMPL;
1158 }
1159
1160 static HRESULT WINAPI IDirect3DRM3Impl_SetSearchPath(IDirect3DRM3* iface, LPCSTR path)
1161 {
1162     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
1163
1164     FIXME("(%p/%p)->(%s): stub\n", iface, This, path);
1165
1166     return E_NOTIMPL;
1167 }
1168
1169 static HRESULT WINAPI IDirect3DRM3Impl_AddSearchPath(IDirect3DRM3* iface, LPCSTR path)
1170 {
1171     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
1172
1173     FIXME("(%p/%p)->(%s): stub\n", iface, This, path);
1174
1175     return E_NOTIMPL;
1176 }
1177
1178 static HRESULT WINAPI IDirect3DRM3Impl_GetSearchPath(IDirect3DRM3* iface, DWORD* size_return,
1179                                                      LPSTR path_return)
1180 {
1181     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
1182
1183     FIXME("(%p/%p)->(%p,%s): stub\n", iface, This, size_return, path_return);
1184
1185     return E_NOTIMPL;
1186 }
1187
1188 static HRESULT WINAPI IDirect3DRM3Impl_SetDefaultTextureColors(IDirect3DRM3* iface, DWORD nb_colors)
1189 {
1190     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
1191
1192     FIXME("(%p/%p)->(%d): stub\n", iface, This, nb_colors);
1193
1194     return E_NOTIMPL;
1195 }
1196
1197 static HRESULT WINAPI IDirect3DRM3Impl_SetDefaultTextureShades(IDirect3DRM3* iface, DWORD nb_shades)
1198 {
1199     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
1200
1201     FIXME("(%p/%p)->(%d): stub\n", iface, This, nb_shades);
1202
1203     return E_NOTIMPL;
1204 }
1205
1206 static HRESULT WINAPI IDirect3DRM3Impl_GetDevices(IDirect3DRM3* iface,
1207                                                   LPDIRECT3DRMDEVICEARRAY* DeviceArray)
1208 {
1209     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
1210
1211     FIXME("(%p/%p)->(%p): stub\n", iface, This, DeviceArray);
1212
1213     return E_NOTIMPL;
1214 }
1215
1216 static HRESULT WINAPI IDirect3DRM3Impl_GetNamedObject(IDirect3DRM3 *iface,
1217         const char *name, IDirect3DRMObject **object)
1218 {
1219     FIXME("iface %p, name %s, object %p stub!\n", iface, debugstr_a(name), object);
1220
1221     return E_NOTIMPL;
1222 }
1223
1224 static HRESULT WINAPI IDirect3DRM3Impl_EnumerateObjects(IDirect3DRM3* iface, D3DRMOBJECTCALLBACK cb,
1225                                                         LPVOID arg)
1226 {
1227     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
1228
1229     FIXME("(%p/%p)->(%p,%p): stub\n", iface, This, cb, arg);
1230
1231     return E_NOTIMPL;
1232 }
1233
1234 static HRESULT load_data(IDirect3DRM3 *iface, IDirectXFileData *data_object, IID **GUIDs, DWORD nb_GUIDs, D3DRMLOADCALLBACK LoadProc,
1235                          void *ArgLP, D3DRMLOADTEXTURECALLBACK LoadTextureProc, void *ArgLTP, IDirect3DRMFrame3 *parent_frame)
1236 {
1237     HRESULT ret = D3DRMERR_BADOBJECT;
1238     HRESULT hr;
1239     const GUID* guid;
1240     DWORD i;
1241     BOOL requested = FALSE;
1242
1243     hr = IDirectXFileData_GetType(data_object, &guid);
1244     if (hr != DXFILE_OK)
1245         goto end;
1246
1247     TRACE("Found object type whose GUID = %s\n", debugstr_guid(guid));
1248
1249     /* Load object only if it is top level and requested or if it is part of another object */
1250
1251     if (IsEqualGUID(guid, &TID_D3DRMMesh))
1252     {
1253         TRACE("Found TID_D3DRMMesh\n");
1254
1255         for (i = 0; i < nb_GUIDs; i++)
1256             if (IsEqualGUID(GUIDs[i], &IID_IDirect3DRMMeshBuilder) ||
1257                 IsEqualGUID(GUIDs[i], &IID_IDirect3DRMMeshBuilder2) ||
1258                 IsEqualGUID(GUIDs[i], &IID_IDirect3DRMMeshBuilder3))
1259             {
1260                 requested = TRUE;
1261                 break;
1262             }
1263
1264         if (requested || parent_frame)
1265         {
1266             IDirect3DRMMeshBuilder3 *meshbuilder;
1267
1268             TRACE("Load mesh data\n");
1269
1270             hr = IDirect3DRM3_CreateMeshBuilder(iface, &meshbuilder);
1271             if (SUCCEEDED(hr))
1272             {
1273                 hr = load_mesh_data(meshbuilder, data_object, LoadTextureProc, ArgLTP);
1274                 if (SUCCEEDED(hr))
1275                 {
1276                     /* Only top level objects are notified */
1277                     if (!parent_frame)
1278                     {
1279                         IDirect3DRMObject *object;
1280
1281                         hr = IDirect3DRMMeshBuilder3_QueryInterface(meshbuilder, GUIDs[i], (void**)&object);
1282                         if (SUCCEEDED(hr))
1283                         {
1284                             LoadProc(object, GUIDs[i], ArgLP);
1285                             IDirect3DRMObject_Release(object);
1286                         }
1287                     }
1288                     else
1289                     {
1290                         IDirect3DRMFrame3_AddVisual(parent_frame, (IUnknown*)meshbuilder);
1291                     }
1292                 }
1293                 IDirect3DRMMeshBuilder3_Release(meshbuilder);
1294             }
1295
1296             if (FAILED(hr))
1297                 ERR("Cannot process mesh\n");
1298         }
1299     }
1300     else if (IsEqualGUID(guid, &TID_D3DRMFrame))
1301     {
1302         TRACE("Found TID_D3DRMFrame\n");
1303
1304         for (i = 0; i < nb_GUIDs; i++)
1305             if (IsEqualGUID(GUIDs[i], &IID_IDirect3DRMFrame) ||
1306                 IsEqualGUID(GUIDs[i], &IID_IDirect3DRMFrame2) ||
1307                 IsEqualGUID(GUIDs[i], &IID_IDirect3DRMFrame3))
1308             {
1309                 requested = TRUE;
1310                 break;
1311             }
1312
1313         if (requested || parent_frame)
1314         {
1315             IDirect3DRMFrame3 *frame;
1316
1317             TRACE("Load frame data\n");
1318
1319             hr = IDirect3DRM3_CreateFrame(iface, parent_frame, &frame);
1320             if (SUCCEEDED(hr))
1321             {
1322                 IDirectXFileObject *child;
1323
1324                 while (SUCCEEDED(hr = IDirectXFileData_GetNextObject(data_object, &child)))
1325                 {
1326                     IDirectXFileData *data;
1327                     IDirectXFileDataReference *reference;
1328                     IDirectXFileBinary *binary;
1329
1330                     hr = IDirectXFileObject_QueryInterface(child, &IID_IDirectXFileBinary, (void **)&binary);
1331                     if (SUCCEEDED(hr))
1332                     {
1333                         FIXME("Binary Object not supported yet\n");
1334                         IDirectXFileBinary_Release(binary);
1335                         continue;
1336                     }
1337
1338                     hr = IDirectXFileObject_QueryInterface(child, &IID_IDirectXFileData, (void **)&data);
1339                     if (SUCCEEDED(hr))
1340                     {
1341                         TRACE("Found Data Object\n");
1342                         hr = load_data(iface, data, GUIDs, nb_GUIDs, LoadProc, ArgLP, LoadTextureProc, ArgLTP, frame);
1343                         IDirectXFileData_Release(data);
1344                         continue;
1345                     }
1346                     hr = IDirectXFileObject_QueryInterface(child, &IID_IDirectXFileDataReference, (void **)&reference);
1347                     if (SUCCEEDED(hr))
1348                     {
1349                         TRACE("Found Data Object Reference\n");
1350                         IDirectXFileDataReference_Resolve(reference, &data);
1351                         hr = load_data(iface, data, GUIDs, nb_GUIDs, LoadProc, ArgLP, LoadTextureProc, ArgLTP, frame);
1352                         IDirectXFileData_Release(data);
1353                         IDirectXFileDataReference_Release(reference);
1354                         continue;
1355                     }
1356                 }
1357
1358                 if (hr != DXFILEERR_NOMOREOBJECTS)
1359                 {
1360                     IDirect3DRMFrame3_Release(frame);
1361                     goto end;
1362                 }
1363                 hr = S_OK;
1364
1365                 /* Only top level objects are notified */
1366                 if (!parent_frame)
1367                 {
1368                     IDirect3DRMObject *object;
1369
1370                     hr = IDirect3DRMFrame3_QueryInterface(frame, GUIDs[i], (void**)&object);
1371                     if (SUCCEEDED(hr))
1372                     {
1373                         LoadProc(object, GUIDs[i], ArgLP);
1374                         IDirect3DRMObject_Release(object);
1375                     }
1376                 }
1377                 IDirect3DRMFrame3_Release(frame);
1378             }
1379
1380             if (FAILED(hr))
1381                 ERR("Cannot process frame\n");
1382         }
1383     }
1384     else if (IsEqualGUID(guid, &TID_D3DRMMaterial))
1385     {
1386         TRACE("Found TID_D3DRMMaterial\n");
1387
1388         /* Cannot be requested so nothing to do */
1389     }
1390     else if (IsEqualGUID(guid, &TID_D3DRMFrameTransformMatrix))
1391     {
1392         TRACE("Found TID_D3DRMFrameTransformMatrix\n");
1393
1394         /* Cannot be requested */
1395         if (parent_frame)
1396         {
1397             D3DRMMATRIX4D matrix;
1398             DWORD size;
1399
1400             TRACE("Load Frame Transform Matrix data\n");
1401
1402             size = sizeof(matrix);
1403             hr = IDirectXFileData_GetData(data_object, NULL, &size, (void**)matrix);
1404             if ((hr != DXFILE_OK) || (size != sizeof(matrix)))
1405                 goto end;
1406
1407             hr = IDirect3DRMFrame3_AddTransform(parent_frame, D3DRMCOMBINE_REPLACE, matrix);
1408             if (FAILED(hr))
1409                 goto end;
1410         }
1411     }
1412     else
1413     {
1414         FIXME("Found unknown TID %s\n", debugstr_guid(guid));
1415     }
1416
1417     ret = D3DRM_OK;
1418
1419 end:
1420
1421     return ret;
1422 }
1423
1424 static HRESULT WINAPI IDirect3DRM3Impl_Load(IDirect3DRM3 *iface, void *source, void *object_id, IID **iids,
1425         DWORD iid_count, D3DRMLOADOPTIONS flags, D3DRMLOADCALLBACK load_cb, void *load_ctx,
1426         D3DRMLOADTEXTURECALLBACK load_tex_cb, void *load_tex_ctx, IDirect3DRMFrame3 *parent_frame)
1427 {
1428     DXFILELOADOPTIONS load_options;
1429     LPDIRECTXFILE pDXFile = NULL;
1430     LPDIRECTXFILEENUMOBJECT pEnumObject = NULL;
1431     LPDIRECTXFILEDATA pData = NULL;
1432     HRESULT hr;
1433     const GUID* pGuid;
1434     DWORD size;
1435     Header* pHeader;
1436     HRESULT ret = D3DRMERR_BADOBJECT;
1437     DWORD i;
1438
1439     TRACE("iface %p, source %p, object_id %p, iids %p, iid_count %u, flags %#x, "
1440             "load_cb %p, load_ctx %p, load_tex_cb %p, load_tex_ctx %p, parent_frame %p.\n",
1441             iface, source, object_id, iids, iid_count, flags,
1442             load_cb, load_ctx, load_tex_cb, load_tex_ctx, parent_frame);
1443
1444     TRACE("Looking for GUIDs:\n");
1445     for (i = 0; i < iid_count; ++i)
1446         TRACE("- %s (%s)\n", debugstr_guid(iids[i]), get_IID_string(iids[i]));
1447
1448     if (flags == D3DRMLOAD_FROMMEMORY)
1449     {
1450         load_options = DXFILELOAD_FROMMEMORY;
1451     }
1452     else if (flags == D3DRMLOAD_FROMFILE)
1453     {
1454         load_options = DXFILELOAD_FROMFILE;
1455         TRACE("Loading from file %s\n", debugstr_a(source));
1456     }
1457     else
1458     {
1459         FIXME("Load options %#x not supported yet.\n", flags);
1460         return E_NOTIMPL;
1461     }
1462
1463     hr = DirectXFileCreate(&pDXFile);
1464     if (hr != DXFILE_OK)
1465         goto end;
1466
1467     hr = IDirectXFile_RegisterTemplates(pDXFile, templates, strlen(templates));
1468     if (hr != DXFILE_OK)
1469         goto end;
1470
1471     hr = IDirectXFile_CreateEnumObject(pDXFile, source, load_options, &pEnumObject);
1472     if (hr != DXFILE_OK)
1473         goto end;
1474
1475     hr = IDirectXFileEnumObject_GetNextDataObject(pEnumObject, &pData);
1476     if (hr != DXFILE_OK)
1477         goto end;
1478
1479     hr = IDirectXFileData_GetType(pData, &pGuid);
1480     if (hr != DXFILE_OK)
1481         goto end;
1482
1483     TRACE("Found object type whose GUID = %s\n", debugstr_guid(pGuid));
1484
1485     if (!IsEqualGUID(pGuid, &TID_DXFILEHeader))
1486     {
1487         ret = D3DRMERR_BADFILE;
1488         goto end;
1489     }
1490
1491     hr = IDirectXFileData_GetData(pData, NULL, &size, (void**)&pHeader);
1492     if ((hr != DXFILE_OK) || (size != sizeof(Header)))
1493         goto end;
1494
1495     TRACE("Version is %d %d %d\n", pHeader->major, pHeader->minor, pHeader->flags);
1496
1497     /* Version must be 1.0.x */
1498     if ((pHeader->major != 1) || (pHeader->minor != 0))
1499     {
1500         ret = D3DRMERR_BADFILE;
1501         goto end;
1502     }
1503
1504     IDirectXFileData_Release(pData);
1505     pData = NULL;
1506
1507     while (1)
1508     {
1509         hr = IDirectXFileEnumObject_GetNextDataObject(pEnumObject, &pData);
1510         if (hr == DXFILEERR_NOMOREOBJECTS)
1511         {
1512             TRACE("No more object\n");
1513             break;
1514         }
1515         else if (hr != DXFILE_OK)
1516         {
1517             ret = D3DRMERR_BADFILE;
1518             goto end;
1519         }
1520
1521         ret = load_data(iface, pData, iids, iid_count, load_cb, load_ctx, load_tex_cb, load_tex_ctx, parent_frame);
1522         if (ret != D3DRM_OK)
1523             goto end;
1524
1525         IDirectXFileData_Release(pData);
1526         pData = NULL;
1527     }
1528
1529     ret = D3DRM_OK;
1530
1531 end:
1532     if (pData)
1533         IDirectXFileData_Release(pData);
1534     if (pEnumObject)
1535         IDirectXFileEnumObject_Release(pEnumObject);
1536     if (pDXFile)
1537         IDirectXFile_Release(pDXFile);
1538
1539     return ret;
1540 }
1541
1542 static HRESULT WINAPI IDirect3DRM3Impl_Tick(IDirect3DRM3* iface, D3DVALUE tick)
1543 {
1544     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
1545
1546     FIXME("(%p/%p)->(%f): stub\n", iface, This, tick);
1547
1548     return E_NOTIMPL;
1549 }
1550
1551 static HRESULT WINAPI IDirect3DRM3Impl_CreateProgressiveMesh(IDirect3DRM3* iface,
1552                                                              LPDIRECT3DRMPROGRESSIVEMESH Mesh)
1553 {
1554     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
1555
1556     FIXME("(%p/%p)->(%p): stub\n", iface, This, Mesh);
1557
1558     return E_NOTIMPL;
1559 }
1560
1561 static HRESULT WINAPI IDirect3DRM3Impl_RegisterClient(IDirect3DRM3* iface, REFGUID rguid,
1562                                                       LPDWORD id)
1563 {
1564     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
1565
1566     FIXME("(%p/%p)->(%s, %p): stub\n", iface, This, debugstr_guid(rguid), id);
1567
1568     return E_NOTIMPL;
1569 }
1570
1571 static HRESULT WINAPI IDirect3DRM3Impl_UnregisterClient(IDirect3DRM3* iface, REFGUID rguid)
1572 {
1573     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
1574
1575     FIXME("(%p/%p)->(%s): stub\n", iface, This, debugstr_guid(rguid));
1576
1577     return E_NOTIMPL;
1578 }
1579
1580 static HRESULT WINAPI IDirect3DRM3Impl_CreateClippedVisual(IDirect3DRM3 *iface,
1581         IDirect3DRMVisual *visual, IDirect3DRMClippedVisual **clipped_visual)
1582 {
1583     FIXME("iface %p, visual %p, clipped_visual %p stub!\n", iface, visual, clipped_visual);
1584
1585     return E_NOTIMPL;
1586 }
1587
1588 static HRESULT WINAPI IDirect3DRM3Impl_SetOptions(IDirect3DRM3* iface, DWORD opt)
1589 {
1590     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
1591
1592     FIXME("(%p/%p)->(%d): stub\n", iface, This, opt);
1593
1594     return E_NOTIMPL;
1595 }
1596
1597 static HRESULT WINAPI IDirect3DRM3Impl_GetOptions(IDirect3DRM3* iface, LPDWORD opt)
1598 {
1599     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
1600
1601     FIXME("(%p/%p)->(%p): stub\n", iface, This, opt);
1602
1603     return E_NOTIMPL;
1604 }
1605
1606 static const struct IDirect3DRM3Vtbl Direct3DRM3_Vtbl =
1607 {
1608     IDirect3DRM3Impl_QueryInterface,
1609     IDirect3DRM3Impl_AddRef,
1610     IDirect3DRM3Impl_Release,
1611     IDirect3DRM3Impl_CreateObject,
1612     IDirect3DRM3Impl_CreateFrame,
1613     IDirect3DRM3Impl_CreateMesh,
1614     IDirect3DRM3Impl_CreateMeshBuilder,
1615     IDirect3DRM3Impl_CreateFace,
1616     IDirect3DRM3Impl_CreateAnimation,
1617     IDirect3DRM3Impl_CreateAnimationSet,
1618     IDirect3DRM3Impl_CreateTexture,
1619     IDirect3DRM3Impl_CreateLight,
1620     IDirect3DRM3Impl_CreateLightRGB,
1621     IDirect3DRM3Impl_CreateMaterial,
1622     IDirect3DRM3Impl_CreateDevice,
1623     IDirect3DRM3Impl_CreateDeviceFromSurface,
1624     IDirect3DRM3Impl_CreateDeviceFromD3D,
1625     IDirect3DRM3Impl_CreateDeviceFromClipper,
1626     IDirect3DRM3Impl_CreateTextureFromSurface,
1627     IDirect3DRM3Impl_CreateShadow,
1628     IDirect3DRM3Impl_CreateViewport,
1629     IDirect3DRM3Impl_CreateWrap,
1630     IDirect3DRM3Impl_CreateUserVisual,
1631     IDirect3DRM3Impl_LoadTexture,
1632     IDirect3DRM3Impl_LoadTextureFromResource,
1633     IDirect3DRM3Impl_SetSearchPath,
1634     IDirect3DRM3Impl_AddSearchPath,
1635     IDirect3DRM3Impl_GetSearchPath,
1636     IDirect3DRM3Impl_SetDefaultTextureColors,
1637     IDirect3DRM3Impl_SetDefaultTextureShades,
1638     IDirect3DRM3Impl_GetDevices,
1639     IDirect3DRM3Impl_GetNamedObject,
1640     IDirect3DRM3Impl_EnumerateObjects,
1641     IDirect3DRM3Impl_Load,
1642     IDirect3DRM3Impl_Tick,
1643     IDirect3DRM3Impl_CreateProgressiveMesh,
1644     IDirect3DRM3Impl_RegisterClient,
1645     IDirect3DRM3Impl_UnregisterClient,
1646     IDirect3DRM3Impl_CreateClippedVisual,
1647     IDirect3DRM3Impl_SetOptions,
1648     IDirect3DRM3Impl_GetOptions
1649 };
1650
1651 HRESULT WINAPI Direct3DRMCreate(IDirect3DRM **d3drm)
1652 {
1653     IDirect3DRMImpl *object;
1654
1655     TRACE("d3drm %p.\n", d3drm);
1656
1657     if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
1658         return E_OUTOFMEMORY;
1659
1660     object->IDirect3DRM_iface.lpVtbl = &Direct3DRM_Vtbl;
1661     object->IDirect3DRM2_iface.lpVtbl = &Direct3DRM2_Vtbl;
1662     object->IDirect3DRM3_iface.lpVtbl = &Direct3DRM3_Vtbl;
1663     object->ref = 1;
1664
1665     *d3drm = &object->IDirect3DRM_iface;
1666
1667     return S_OK;
1668 }