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