d3drm: Avoid LPDIRECT3DRMMESH.
[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, IDirect3DRMMesh **mesh)
149 {
150     IDirect3DRMImpl *d3drm = impl_from_IDirect3DRM(iface);
151
152     TRACE("iface %p, mesh %p.\n", iface, mesh);
153
154     return IDirect3DRM3_CreateMesh(&d3drm->IDirect3DRM3_iface, mesh);
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, IDirect3DRMMesh **mesh)
530 {
531     IDirect3DRMImpl *d3drm = impl_from_IDirect3DRM2(iface);
532
533     TRACE("iface %p, mesh %p.\n", iface, mesh);
534
535     return IDirect3DRM3_CreateMesh(&d3drm->IDirect3DRM3_iface, mesh);
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, IDirect3DRMMesh **mesh)
931 {
932     TRACE("iface %p, mesh %p.\n", iface, mesh);
933
934     return Direct3DRMMesh_create(mesh);
935 }
936
937 static HRESULT WINAPI IDirect3DRM3Impl_CreateMeshBuilder(IDirect3DRM3* iface,
938                                                          LPDIRECT3DRMMESHBUILDER3* ppMeshBuilder)
939 {
940     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
941
942     TRACE("(%p/%p)->(%p)\n", iface, This, ppMeshBuilder);
943
944     return Direct3DRMMeshBuilder_create(&IID_IDirect3DRMMeshBuilder3, (IUnknown**)ppMeshBuilder);
945 }
946
947 static HRESULT WINAPI IDirect3DRM3Impl_CreateFace(IDirect3DRM3* iface, LPDIRECT3DRMFACE2* Face)
948 {
949     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
950
951     FIXME("(%p/%p)->(%p): stub\n", iface, This, Face);
952
953     return E_NOTIMPL;
954 }
955
956 static HRESULT WINAPI IDirect3DRM3Impl_CreateAnimation(IDirect3DRM3* iface,
957                                                        LPDIRECT3DRMANIMATION2* Animation)
958 {
959     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
960
961     FIXME("(%p/%p)->(%p): stub\n", iface, This, Animation);
962
963     return E_NOTIMPL;
964 }
965
966 static HRESULT WINAPI IDirect3DRM3Impl_CreateAnimationSet(IDirect3DRM3* iface,
967                                                           LPDIRECT3DRMANIMATIONSET2* AnimationSet)
968 {
969     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
970
971     FIXME("(%p/%p)->(%p): stub\n", iface, This, AnimationSet);
972
973     return E_NOTIMPL;
974 }
975
976 static HRESULT WINAPI IDirect3DRM3Impl_CreateTexture(IDirect3DRM3 *iface,
977         D3DRMIMAGE *image, IDirect3DRMTexture3 **texture)
978 {
979     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
980
981     FIXME("(%p/%p)->(%p,%p): partial stub\n", iface, This, image, texture);
982
983     return Direct3DRMTexture_create(&IID_IDirect3DRMTexture3, (IUnknown **)texture);
984 }
985
986 static HRESULT WINAPI IDirect3DRM3Impl_CreateLight(IDirect3DRM3* iface, D3DRMLIGHTTYPE type,
987                                                      D3DCOLOR color, LPDIRECT3DRMLIGHT* Light)
988 {
989     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
990     HRESULT ret;
991
992     FIXME("(%p/%p)->(%d,%d,%p): partial stub\n", iface, This, type, color, Light);
993
994     ret = Direct3DRMLight_create((IUnknown**)Light);
995
996     if (SUCCEEDED(ret))
997     {
998         IDirect3DRMLight_SetType(*Light, type);
999         IDirect3DRMLight_SetColor(*Light, color);
1000     }
1001
1002     return ret;
1003 }
1004
1005 static HRESULT WINAPI IDirect3DRM3Impl_CreateLightRGB(IDirect3DRM3* iface, D3DRMLIGHTTYPE type,
1006                                                         D3DVALUE red, D3DVALUE green, D3DVALUE blue,
1007                                                         LPDIRECT3DRMLIGHT* Light)
1008 {
1009     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
1010     HRESULT ret;
1011
1012     FIXME("(%p/%p)->(%d,%f,%f,%f,%p): partial stub\n", iface, This, type, red, green, blue, Light);
1013
1014     ret = Direct3DRMLight_create((IUnknown**)Light);
1015
1016     if (SUCCEEDED(ret))
1017     {
1018         IDirect3DRMLight_SetType(*Light, type);
1019         IDirect3DRMLight_SetColorRGB(*Light, red, green, blue);
1020     }
1021
1022     return ret;
1023 }
1024
1025 static HRESULT WINAPI IDirect3DRM3Impl_CreateMaterial(IDirect3DRM3* iface, D3DVALUE power,
1026                                                       LPDIRECT3DRMMATERIAL2* material)
1027 {
1028     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
1029     HRESULT ret;
1030
1031     TRACE("(%p/%p)->(%f,%p)\n", iface, This, power, material);
1032
1033     ret = Direct3DRMMaterial_create(material);
1034
1035     if (SUCCEEDED(ret))
1036         IDirect3DRMMaterial2_SetPower(*material, power);
1037
1038     return ret;
1039 }
1040
1041 static HRESULT WINAPI IDirect3DRM3Impl_CreateDevice(IDirect3DRM3 *iface,
1042         DWORD width, DWORD height, IDirect3DRMDevice3 **device)
1043 {
1044     FIXME("iface %p, width %u, height %u, device %p partial stub!\n", iface, width, height, device);
1045
1046     return Direct3DRMDevice_create(&IID_IDirect3DRMDevice3, (IUnknown **)device);
1047 }
1048
1049 static HRESULT WINAPI IDirect3DRM3Impl_CreateDeviceFromSurface(IDirect3DRM3 *iface, GUID *pGUID,
1050         IDirectDraw *dd, IDirectDrawSurface *back, IDirect3DRMDevice3 **device)
1051 {
1052     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
1053
1054     FIXME("(%p/%p)->(%s,%p,%p,%p): partial stub\n", iface, This, debugstr_guid(pGUID), dd, back, device);
1055
1056     return Direct3DRMDevice_create(&IID_IDirect3DRMDevice3, (IUnknown**)device);
1057 }
1058
1059 static HRESULT WINAPI IDirect3DRM3Impl_CreateDeviceFromD3D(IDirect3DRM3 *iface,
1060         IDirect3D2 *d3d, IDirect3DDevice2 *d3ddev, IDirect3DRMDevice3 **device)
1061 {
1062     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
1063
1064     FIXME("(%p/%p)->(%p,%p,%p): partial stub\n", iface, This, d3d, d3ddev, device);
1065
1066     return Direct3DRMDevice_create(&IID_IDirect3DRMDevice3, (IUnknown**)device);
1067 }
1068
1069 static HRESULT WINAPI IDirect3DRM3Impl_CreateDeviceFromClipper(IDirect3DRM3 *iface,
1070         IDirectDrawClipper *clipper, GUID *guid, int width, int height,
1071         IDirect3DRMDevice3 **device)
1072 {
1073     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
1074
1075     FIXME("(%p/%p)->(%p,%s,%d,%d,%p): partial stub\n", iface, This, clipper, debugstr_guid(guid),
1076           width, height, device);
1077
1078     return Direct3DRMDevice_create(&IID_IDirect3DRMDevice3, (IUnknown**)device);
1079 }
1080
1081 static HRESULT WINAPI IDirect3DRM3Impl_CreateShadow(IDirect3DRM3* iface, LPUNKNOWN Visual1,
1082                                                     LPDIRECT3DRMLIGHT Light, D3DVALUE px,
1083                                                     D3DVALUE py, D3DVALUE pz, D3DVALUE nx,
1084                                                     D3DVALUE ny, D3DVALUE nz,
1085                                                     LPDIRECT3DRMSHADOW2* Visual2)
1086 {
1087     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
1088
1089     FIXME("(%p/%p)->(%p,%p,%f,%f,%f,%f,%f,%f,%p): stub\n", iface, This, Visual1, Light, px, py, pz,
1090           nx, ny, nz, Visual2);
1091
1092     return E_NOTIMPL;
1093 }
1094
1095 static HRESULT WINAPI IDirect3DRM3Impl_CreateTextureFromSurface(IDirect3DRM3 *iface,
1096         IDirectDrawSurface *surface, IDirect3DRMTexture3 **texture)
1097 {
1098     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
1099
1100     FIXME("(%p/%p)->(%p,%p): stub\n", iface, This, surface, texture);
1101
1102     return E_NOTIMPL;
1103 }
1104
1105 static HRESULT WINAPI IDirect3DRM3Impl_CreateViewport(IDirect3DRM3 *iface, IDirect3DRMDevice3 *device,
1106         IDirect3DRMFrame3 *camera, DWORD x, DWORD y, DWORD width, DWORD height, IDirect3DRMViewport2 **viewport)
1107 {
1108     FIXME("iface %p, device %p, camera %p, x %u, y %u, width %u, height %u, viewport %p partial stub!\n",
1109             iface, device, camera, x, y, width, height, viewport);
1110
1111     return Direct3DRMViewport_create(&IID_IDirect3DRMViewport2, (IUnknown **)viewport);
1112 }
1113
1114 static HRESULT WINAPI IDirect3DRM3Impl_CreateWrap(IDirect3DRM3 *iface, D3DRMWRAPTYPE type, IDirect3DRMFrame3 *frame,
1115         D3DVALUE ox, D3DVALUE oy, D3DVALUE oz, D3DVALUE dx, D3DVALUE dy, D3DVALUE dz,
1116         D3DVALUE ux, D3DVALUE uy, D3DVALUE uz, D3DVALUE ou, D3DVALUE ov, D3DVALUE su, D3DVALUE sv,
1117         IDirect3DRMWrap **wrap)
1118 {
1119     FIXME("iface %p, type %#x, frame %p, ox %.8e, oy %.8e, oz %.8e, dx %.8e, dy %.8e, dz %.8e, "
1120             "ux %.8e, uy %.8e, uz %.8e, ou %.8e, ov %.8e, su %.8e, sv %.8e, wrap %p stub!\n",
1121             iface, type, frame, ox, oy, oz, dx, dy, dz, ux, uy, uz, ou, ov, su, sv, wrap);
1122
1123     return E_NOTIMPL;
1124 }
1125
1126 static HRESULT WINAPI IDirect3DRM3Impl_CreateUserVisual(IDirect3DRM3* iface,
1127                                                         D3DRMUSERVISUALCALLBACK cb, LPVOID arg,
1128                                                         LPDIRECT3DRMUSERVISUAL* UserVisual)
1129 {
1130     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
1131
1132     FIXME("(%p/%p)->(%p,%p,%p): stub\n", iface, This, cb, arg, UserVisual);
1133
1134     return E_NOTIMPL;
1135 }
1136
1137 static HRESULT WINAPI IDirect3DRM3Impl_LoadTexture(IDirect3DRM3* iface, const char* filename,
1138                                                    LPDIRECT3DRMTEXTURE3* Texture)
1139 {
1140     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
1141
1142     FIXME("(%p/%p)->(%s,%p): stub\n", iface, This, filename, Texture);
1143
1144     return E_NOTIMPL;
1145 }
1146
1147 static HRESULT WINAPI IDirect3DRM3Impl_LoadTextureFromResource(IDirect3DRM3* iface, HMODULE mod,
1148                                                                LPCSTR strName, LPCSTR strType,
1149                                                                LPDIRECT3DRMTEXTURE3 * ppTexture)
1150 {
1151     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
1152
1153     FIXME("(%p/%p)->(%p,%p,%p,%p): stub\n", iface, This, mod, strName, strType, ppTexture);
1154
1155     return E_NOTIMPL;
1156 }
1157
1158 static HRESULT WINAPI IDirect3DRM3Impl_SetSearchPath(IDirect3DRM3* iface, LPCSTR path)
1159 {
1160     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
1161
1162     FIXME("(%p/%p)->(%s): stub\n", iface, This, path);
1163
1164     return E_NOTIMPL;
1165 }
1166
1167 static HRESULT WINAPI IDirect3DRM3Impl_AddSearchPath(IDirect3DRM3* iface, LPCSTR path)
1168 {
1169     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
1170
1171     FIXME("(%p/%p)->(%s): stub\n", iface, This, path);
1172
1173     return E_NOTIMPL;
1174 }
1175
1176 static HRESULT WINAPI IDirect3DRM3Impl_GetSearchPath(IDirect3DRM3* iface, DWORD* size_return,
1177                                                      LPSTR path_return)
1178 {
1179     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
1180
1181     FIXME("(%p/%p)->(%p,%s): stub\n", iface, This, size_return, path_return);
1182
1183     return E_NOTIMPL;
1184 }
1185
1186 static HRESULT WINAPI IDirect3DRM3Impl_SetDefaultTextureColors(IDirect3DRM3* iface, DWORD nb_colors)
1187 {
1188     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
1189
1190     FIXME("(%p/%p)->(%d): stub\n", iface, This, nb_colors);
1191
1192     return E_NOTIMPL;
1193 }
1194
1195 static HRESULT WINAPI IDirect3DRM3Impl_SetDefaultTextureShades(IDirect3DRM3* iface, DWORD nb_shades)
1196 {
1197     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
1198
1199     FIXME("(%p/%p)->(%d): stub\n", iface, This, nb_shades);
1200
1201     return E_NOTIMPL;
1202 }
1203
1204 static HRESULT WINAPI IDirect3DRM3Impl_GetDevices(IDirect3DRM3* iface,
1205                                                   LPDIRECT3DRMDEVICEARRAY* DeviceArray)
1206 {
1207     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
1208
1209     FIXME("(%p/%p)->(%p): stub\n", iface, This, DeviceArray);
1210
1211     return E_NOTIMPL;
1212 }
1213
1214 static HRESULT WINAPI IDirect3DRM3Impl_GetNamedObject(IDirect3DRM3 *iface,
1215         const char *name, IDirect3DRMObject **object)
1216 {
1217     FIXME("iface %p, name %s, object %p stub!\n", iface, debugstr_a(name), object);
1218
1219     return E_NOTIMPL;
1220 }
1221
1222 static HRESULT WINAPI IDirect3DRM3Impl_EnumerateObjects(IDirect3DRM3* iface, D3DRMOBJECTCALLBACK cb,
1223                                                         LPVOID arg)
1224 {
1225     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
1226
1227     FIXME("(%p/%p)->(%p,%p): stub\n", iface, This, cb, arg);
1228
1229     return E_NOTIMPL;
1230 }
1231
1232 static HRESULT load_data(IDirect3DRM3 *iface, IDirectXFileData *data_object, IID **GUIDs, DWORD nb_GUIDs, D3DRMLOADCALLBACK LoadProc,
1233                          void *ArgLP, D3DRMLOADTEXTURECALLBACK LoadTextureProc, void *ArgLTP, IDirect3DRMFrame3 *parent_frame)
1234 {
1235     HRESULT ret = D3DRMERR_BADOBJECT;
1236     HRESULT hr;
1237     const GUID* guid;
1238     DWORD i;
1239     BOOL requested = FALSE;
1240
1241     hr = IDirectXFileData_GetType(data_object, &guid);
1242     if (hr != DXFILE_OK)
1243         goto end;
1244
1245     TRACE("Found object type whose GUID = %s\n", debugstr_guid(guid));
1246
1247     /* Load object only if it is top level and requested or if it is part of another object */
1248
1249     if (IsEqualGUID(guid, &TID_D3DRMMesh))
1250     {
1251         TRACE("Found TID_D3DRMMesh\n");
1252
1253         for (i = 0; i < nb_GUIDs; i++)
1254             if (IsEqualGUID(GUIDs[i], &IID_IDirect3DRMMeshBuilder) ||
1255                 IsEqualGUID(GUIDs[i], &IID_IDirect3DRMMeshBuilder2) ||
1256                 IsEqualGUID(GUIDs[i], &IID_IDirect3DRMMeshBuilder3))
1257             {
1258                 requested = TRUE;
1259                 break;
1260             }
1261
1262         if (requested || parent_frame)
1263         {
1264             IDirect3DRMMeshBuilder3 *meshbuilder;
1265
1266             TRACE("Load mesh data\n");
1267
1268             hr = IDirect3DRM3_CreateMeshBuilder(iface, &meshbuilder);
1269             if (SUCCEEDED(hr))
1270             {
1271                 hr = load_mesh_data(meshbuilder, data_object, LoadTextureProc, ArgLTP);
1272                 if (SUCCEEDED(hr))
1273                 {
1274                     /* Only top level objects are notified */
1275                     if (!parent_frame)
1276                     {
1277                         IDirect3DRMObject *object;
1278
1279                         hr = IDirect3DRMMeshBuilder3_QueryInterface(meshbuilder, GUIDs[i], (void**)&object);
1280                         if (SUCCEEDED(hr))
1281                         {
1282                             LoadProc(object, GUIDs[i], ArgLP);
1283                             IDirect3DRMObject_Release(object);
1284                         }
1285                     }
1286                     else
1287                     {
1288                         IDirect3DRMFrame3_AddVisual(parent_frame, (IUnknown*)meshbuilder);
1289                     }
1290                 }
1291                 IDirect3DRMMeshBuilder3_Release(meshbuilder);
1292             }
1293
1294             if (FAILED(hr))
1295                 ERR("Cannot process mesh\n");
1296         }
1297     }
1298     else if (IsEqualGUID(guid, &TID_D3DRMFrame))
1299     {
1300         TRACE("Found TID_D3DRMFrame\n");
1301
1302         for (i = 0; i < nb_GUIDs; i++)
1303             if (IsEqualGUID(GUIDs[i], &IID_IDirect3DRMFrame) ||
1304                 IsEqualGUID(GUIDs[i], &IID_IDirect3DRMFrame2) ||
1305                 IsEqualGUID(GUIDs[i], &IID_IDirect3DRMFrame3))
1306             {
1307                 requested = TRUE;
1308                 break;
1309             }
1310
1311         if (requested || parent_frame)
1312         {
1313             IDirect3DRMFrame3 *frame;
1314
1315             TRACE("Load frame data\n");
1316
1317             hr = IDirect3DRM3_CreateFrame(iface, parent_frame, &frame);
1318             if (SUCCEEDED(hr))
1319             {
1320                 IDirectXFileObject *child;
1321
1322                 while (SUCCEEDED(hr = IDirectXFileData_GetNextObject(data_object, &child)))
1323                 {
1324                     IDirectXFileData *data;
1325                     IDirectXFileDataReference *reference;
1326                     IDirectXFileBinary *binary;
1327
1328                     hr = IDirectXFileObject_QueryInterface(child, &IID_IDirectXFileBinary, (void **)&binary);
1329                     if (SUCCEEDED(hr))
1330                     {
1331                         FIXME("Binary Object not supported yet\n");
1332                         IDirectXFileBinary_Release(binary);
1333                         continue;
1334                     }
1335
1336                     hr = IDirectXFileObject_QueryInterface(child, &IID_IDirectXFileData, (void **)&data);
1337                     if (SUCCEEDED(hr))
1338                     {
1339                         TRACE("Found Data Object\n");
1340                         hr = load_data(iface, data, GUIDs, nb_GUIDs, LoadProc, ArgLP, LoadTextureProc, ArgLTP, frame);
1341                         IDirectXFileData_Release(data);
1342                         continue;
1343                     }
1344                     hr = IDirectXFileObject_QueryInterface(child, &IID_IDirectXFileDataReference, (void **)&reference);
1345                     if (SUCCEEDED(hr))
1346                     {
1347                         TRACE("Found Data Object Reference\n");
1348                         IDirectXFileDataReference_Resolve(reference, &data);
1349                         hr = load_data(iface, data, GUIDs, nb_GUIDs, LoadProc, ArgLP, LoadTextureProc, ArgLTP, frame);
1350                         IDirectXFileData_Release(data);
1351                         IDirectXFileDataReference_Release(reference);
1352                         continue;
1353                     }
1354                 }
1355
1356                 if (hr != DXFILEERR_NOMOREOBJECTS)
1357                 {
1358                     IDirect3DRMFrame3_Release(frame);
1359                     goto end;
1360                 }
1361                 hr = S_OK;
1362
1363                 /* Only top level objects are notified */
1364                 if (!parent_frame)
1365                 {
1366                     IDirect3DRMObject *object;
1367
1368                     hr = IDirect3DRMFrame3_QueryInterface(frame, GUIDs[i], (void**)&object);
1369                     if (SUCCEEDED(hr))
1370                     {
1371                         LoadProc(object, GUIDs[i], ArgLP);
1372                         IDirect3DRMObject_Release(object);
1373                     }
1374                 }
1375                 IDirect3DRMFrame3_Release(frame);
1376             }
1377
1378             if (FAILED(hr))
1379                 ERR("Cannot process frame\n");
1380         }
1381     }
1382     else if (IsEqualGUID(guid, &TID_D3DRMMaterial))
1383     {
1384         TRACE("Found TID_D3DRMMaterial\n");
1385
1386         /* Cannot be requested so nothing to do */
1387     }
1388     else if (IsEqualGUID(guid, &TID_D3DRMFrameTransformMatrix))
1389     {
1390         TRACE("Found TID_D3DRMFrameTransformMatrix\n");
1391
1392         /* Cannot be requested */
1393         if (parent_frame)
1394         {
1395             D3DRMMATRIX4D matrix;
1396             DWORD size;
1397
1398             TRACE("Load Frame Transform Matrix data\n");
1399
1400             size = sizeof(matrix);
1401             hr = IDirectXFileData_GetData(data_object, NULL, &size, (void**)matrix);
1402             if ((hr != DXFILE_OK) || (size != sizeof(matrix)))
1403                 goto end;
1404
1405             hr = IDirect3DRMFrame3_AddTransform(parent_frame, D3DRMCOMBINE_REPLACE, matrix);
1406             if (FAILED(hr))
1407                 goto end;
1408         }
1409     }
1410     else
1411     {
1412         FIXME("Found unknown TID %s\n", debugstr_guid(guid));
1413     }
1414
1415     ret = D3DRM_OK;
1416
1417 end:
1418
1419     return ret;
1420 }
1421
1422 static HRESULT WINAPI IDirect3DRM3Impl_Load(IDirect3DRM3 *iface, void *source, void *object_id, IID **iids,
1423         DWORD iid_count, D3DRMLOADOPTIONS flags, D3DRMLOADCALLBACK load_cb, void *load_ctx,
1424         D3DRMLOADTEXTURECALLBACK load_tex_cb, void *load_tex_ctx, IDirect3DRMFrame3 *parent_frame)
1425 {
1426     DXFILELOADOPTIONS load_options;
1427     LPDIRECTXFILE pDXFile = NULL;
1428     LPDIRECTXFILEENUMOBJECT pEnumObject = NULL;
1429     LPDIRECTXFILEDATA pData = NULL;
1430     HRESULT hr;
1431     const GUID* pGuid;
1432     DWORD size;
1433     Header* pHeader;
1434     HRESULT ret = D3DRMERR_BADOBJECT;
1435     DWORD i;
1436
1437     TRACE("iface %p, source %p, object_id %p, iids %p, iid_count %u, flags %#x, "
1438             "load_cb %p, load_ctx %p, load_tex_cb %p, load_tex_ctx %p, parent_frame %p.\n",
1439             iface, source, object_id, iids, iid_count, flags,
1440             load_cb, load_ctx, load_tex_cb, load_tex_ctx, parent_frame);
1441
1442     TRACE("Looking for GUIDs:\n");
1443     for (i = 0; i < iid_count; ++i)
1444         TRACE("- %s (%s)\n", debugstr_guid(iids[i]), get_IID_string(iids[i]));
1445
1446     if (flags == D3DRMLOAD_FROMMEMORY)
1447     {
1448         load_options = DXFILELOAD_FROMMEMORY;
1449     }
1450     else if (flags == D3DRMLOAD_FROMFILE)
1451     {
1452         load_options = DXFILELOAD_FROMFILE;
1453         TRACE("Loading from file %s\n", debugstr_a(source));
1454     }
1455     else
1456     {
1457         FIXME("Load options %#x not supported yet.\n", flags);
1458         return E_NOTIMPL;
1459     }
1460
1461     hr = DirectXFileCreate(&pDXFile);
1462     if (hr != DXFILE_OK)
1463         goto end;
1464
1465     hr = IDirectXFile_RegisterTemplates(pDXFile, templates, strlen(templates));
1466     if (hr != DXFILE_OK)
1467         goto end;
1468
1469     hr = IDirectXFile_CreateEnumObject(pDXFile, source, load_options, &pEnumObject);
1470     if (hr != DXFILE_OK)
1471         goto end;
1472
1473     hr = IDirectXFileEnumObject_GetNextDataObject(pEnumObject, &pData);
1474     if (hr != DXFILE_OK)
1475         goto end;
1476
1477     hr = IDirectXFileData_GetType(pData, &pGuid);
1478     if (hr != DXFILE_OK)
1479         goto end;
1480
1481     TRACE("Found object type whose GUID = %s\n", debugstr_guid(pGuid));
1482
1483     if (!IsEqualGUID(pGuid, &TID_DXFILEHeader))
1484     {
1485         ret = D3DRMERR_BADFILE;
1486         goto end;
1487     }
1488
1489     hr = IDirectXFileData_GetData(pData, NULL, &size, (void**)&pHeader);
1490     if ((hr != DXFILE_OK) || (size != sizeof(Header)))
1491         goto end;
1492
1493     TRACE("Version is %d %d %d\n", pHeader->major, pHeader->minor, pHeader->flags);
1494
1495     /* Version must be 1.0.x */
1496     if ((pHeader->major != 1) || (pHeader->minor != 0))
1497     {
1498         ret = D3DRMERR_BADFILE;
1499         goto end;
1500     }
1501
1502     IDirectXFileData_Release(pData);
1503     pData = NULL;
1504
1505     while (1)
1506     {
1507         hr = IDirectXFileEnumObject_GetNextDataObject(pEnumObject, &pData);
1508         if (hr == DXFILEERR_NOMOREOBJECTS)
1509         {
1510             TRACE("No more object\n");
1511             break;
1512         }
1513         else if (hr != DXFILE_OK)
1514         {
1515             ret = D3DRMERR_BADFILE;
1516             goto end;
1517         }
1518
1519         ret = load_data(iface, pData, iids, iid_count, load_cb, load_ctx, load_tex_cb, load_tex_ctx, parent_frame);
1520         if (ret != D3DRM_OK)
1521             goto end;
1522
1523         IDirectXFileData_Release(pData);
1524         pData = NULL;
1525     }
1526
1527     ret = D3DRM_OK;
1528
1529 end:
1530     if (pData)
1531         IDirectXFileData_Release(pData);
1532     if (pEnumObject)
1533         IDirectXFileEnumObject_Release(pEnumObject);
1534     if (pDXFile)
1535         IDirectXFile_Release(pDXFile);
1536
1537     return ret;
1538 }
1539
1540 static HRESULT WINAPI IDirect3DRM3Impl_Tick(IDirect3DRM3* iface, D3DVALUE tick)
1541 {
1542     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
1543
1544     FIXME("(%p/%p)->(%f): stub\n", iface, This, tick);
1545
1546     return E_NOTIMPL;
1547 }
1548
1549 static HRESULT WINAPI IDirect3DRM3Impl_CreateProgressiveMesh(IDirect3DRM3* iface,
1550                                                              LPDIRECT3DRMPROGRESSIVEMESH Mesh)
1551 {
1552     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
1553
1554     FIXME("(%p/%p)->(%p): stub\n", iface, This, Mesh);
1555
1556     return E_NOTIMPL;
1557 }
1558
1559 static HRESULT WINAPI IDirect3DRM3Impl_RegisterClient(IDirect3DRM3* iface, REFGUID rguid,
1560                                                       LPDWORD id)
1561 {
1562     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
1563
1564     FIXME("(%p/%p)->(%s, %p): stub\n", iface, This, debugstr_guid(rguid), id);
1565
1566     return E_NOTIMPL;
1567 }
1568
1569 static HRESULT WINAPI IDirect3DRM3Impl_UnregisterClient(IDirect3DRM3* iface, REFGUID rguid)
1570 {
1571     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
1572
1573     FIXME("(%p/%p)->(%s): stub\n", iface, This, debugstr_guid(rguid));
1574
1575     return E_NOTIMPL;
1576 }
1577
1578 static HRESULT WINAPI IDirect3DRM3Impl_CreateClippedVisual(IDirect3DRM3 *iface,
1579         IDirect3DRMVisual *visual, IDirect3DRMClippedVisual **clipped_visual)
1580 {
1581     FIXME("iface %p, visual %p, clipped_visual %p stub!\n", iface, visual, clipped_visual);
1582
1583     return E_NOTIMPL;
1584 }
1585
1586 static HRESULT WINAPI IDirect3DRM3Impl_SetOptions(IDirect3DRM3* iface, DWORD opt)
1587 {
1588     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
1589
1590     FIXME("(%p/%p)->(%d): stub\n", iface, This, opt);
1591
1592     return E_NOTIMPL;
1593 }
1594
1595 static HRESULT WINAPI IDirect3DRM3Impl_GetOptions(IDirect3DRM3* iface, LPDWORD opt)
1596 {
1597     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
1598
1599     FIXME("(%p/%p)->(%p): stub\n", iface, This, opt);
1600
1601     return E_NOTIMPL;
1602 }
1603
1604 static const struct IDirect3DRM3Vtbl Direct3DRM3_Vtbl =
1605 {
1606     IDirect3DRM3Impl_QueryInterface,
1607     IDirect3DRM3Impl_AddRef,
1608     IDirect3DRM3Impl_Release,
1609     IDirect3DRM3Impl_CreateObject,
1610     IDirect3DRM3Impl_CreateFrame,
1611     IDirect3DRM3Impl_CreateMesh,
1612     IDirect3DRM3Impl_CreateMeshBuilder,
1613     IDirect3DRM3Impl_CreateFace,
1614     IDirect3DRM3Impl_CreateAnimation,
1615     IDirect3DRM3Impl_CreateAnimationSet,
1616     IDirect3DRM3Impl_CreateTexture,
1617     IDirect3DRM3Impl_CreateLight,
1618     IDirect3DRM3Impl_CreateLightRGB,
1619     IDirect3DRM3Impl_CreateMaterial,
1620     IDirect3DRM3Impl_CreateDevice,
1621     IDirect3DRM3Impl_CreateDeviceFromSurface,
1622     IDirect3DRM3Impl_CreateDeviceFromD3D,
1623     IDirect3DRM3Impl_CreateDeviceFromClipper,
1624     IDirect3DRM3Impl_CreateTextureFromSurface,
1625     IDirect3DRM3Impl_CreateShadow,
1626     IDirect3DRM3Impl_CreateViewport,
1627     IDirect3DRM3Impl_CreateWrap,
1628     IDirect3DRM3Impl_CreateUserVisual,
1629     IDirect3DRM3Impl_LoadTexture,
1630     IDirect3DRM3Impl_LoadTextureFromResource,
1631     IDirect3DRM3Impl_SetSearchPath,
1632     IDirect3DRM3Impl_AddSearchPath,
1633     IDirect3DRM3Impl_GetSearchPath,
1634     IDirect3DRM3Impl_SetDefaultTextureColors,
1635     IDirect3DRM3Impl_SetDefaultTextureShades,
1636     IDirect3DRM3Impl_GetDevices,
1637     IDirect3DRM3Impl_GetNamedObject,
1638     IDirect3DRM3Impl_EnumerateObjects,
1639     IDirect3DRM3Impl_Load,
1640     IDirect3DRM3Impl_Tick,
1641     IDirect3DRM3Impl_CreateProgressiveMesh,
1642     IDirect3DRM3Impl_RegisterClient,
1643     IDirect3DRM3Impl_UnregisterClient,
1644     IDirect3DRM3Impl_CreateClippedVisual,
1645     IDirect3DRM3Impl_SetOptions,
1646     IDirect3DRM3Impl_GetOptions
1647 };
1648
1649 HRESULT WINAPI Direct3DRMCreate(IDirect3DRM **d3drm)
1650 {
1651     IDirect3DRMImpl *object;
1652
1653     TRACE("d3drm %p.\n", d3drm);
1654
1655     if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
1656         return E_OUTOFMEMORY;
1657
1658     object->IDirect3DRM_iface.lpVtbl = &Direct3DRM_Vtbl;
1659     object->IDirect3DRM2_iface.lpVtbl = &Direct3DRM2_Vtbl;
1660     object->IDirect3DRM3_iface.lpVtbl = &Direct3DRM3_Vtbl;
1661     object->ref = 1;
1662
1663     *d3drm = &object->IDirect3DRM_iface;
1664
1665     return S_OK;
1666 }