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