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