[D3DRM] Sync with Wine Staging 1.7.55. CORE-10536
[reactos.git] / reactos / dll / directx / wine / 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 "d3drm_private.h"
23
24 static const char* get_IID_string(const GUID* guid)
25 {
26 if (IsEqualGUID(guid, &IID_IDirect3DRMFrame))
27 return "IID_IDirect3DRMFrame";
28 else if (IsEqualGUID(guid, &IID_IDirect3DRMFrame2))
29 return "IID_IDirect3DRMFrame2";
30 else if (IsEqualGUID(guid, &IID_IDirect3DRMFrame3))
31 return "IID_IDirect3DRMFrame3";
32 else if (IsEqualGUID(guid, &IID_IDirect3DRMMeshBuilder))
33 return "IID_IDirect3DRMMeshBuilder";
34 else if (IsEqualGUID(guid, &IID_IDirect3DRMMeshBuilder2))
35 return "IID_IDirect3DRMMeshBuilder2";
36 else if (IsEqualGUID(guid, &IID_IDirect3DRMMeshBuilder3))
37 return "IID_IDirect3DRMMeshBuilder3";
38
39 return "?";
40 }
41
42 struct d3drm
43 {
44 IDirect3DRM IDirect3DRM_iface;
45 IDirect3DRM2 IDirect3DRM2_iface;
46 IDirect3DRM3 IDirect3DRM3_iface;
47 LONG ref1, ref2, ref3, iface_count;
48 };
49
50 static inline struct d3drm *impl_from_IDirect3DRM(IDirect3DRM *iface)
51 {
52 return CONTAINING_RECORD(iface, struct d3drm, IDirect3DRM_iface);
53 }
54
55 static inline struct d3drm *impl_from_IDirect3DRM2(IDirect3DRM2 *iface)
56 {
57 return CONTAINING_RECORD(iface, struct d3drm, IDirect3DRM2_iface);
58 }
59
60 static inline struct d3drm *impl_from_IDirect3DRM3(IDirect3DRM3 *iface)
61 {
62 return CONTAINING_RECORD(iface, struct d3drm, IDirect3DRM3_iface);
63 }
64
65 static void d3drm_destroy(struct d3drm *d3drm)
66 {
67 HeapFree(GetProcessHeap(), 0, d3drm);
68 TRACE("d3drm object %p is being destroyed.\n", d3drm);
69 }
70
71 static HRESULT WINAPI d3drm1_QueryInterface(IDirect3DRM *iface, REFIID riid, void **out)
72 {
73 struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
74
75 TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
76
77 if (IsEqualGUID(riid, &IID_IDirect3DRM)
78 || IsEqualGUID(riid, &IID_IUnknown))
79 {
80 *out = &d3drm->IDirect3DRM_iface;
81 }
82 else if (IsEqualGUID(riid, &IID_IDirect3DRM2))
83 {
84 *out = &d3drm->IDirect3DRM2_iface;
85 }
86 else if (IsEqualGUID(riid, &IID_IDirect3DRM3))
87 {
88 *out = &d3drm->IDirect3DRM3_iface;
89 }
90 else
91 {
92 *out = NULL;
93 WARN("%s not implemented, returning CLASS_E_CLASSNOTAVAILABLE.\n", debugstr_guid(riid));
94 return CLASS_E_CLASSNOTAVAILABLE;
95 }
96
97 IUnknown_AddRef((IUnknown *)*out);
98 return S_OK;
99 }
100
101 static ULONG WINAPI d3drm1_AddRef(IDirect3DRM *iface)
102 {
103 struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
104 ULONG refcount = InterlockedIncrement(&d3drm->ref1);
105
106 TRACE("%p increasing refcount to %u.\n", iface, refcount);
107
108 if (refcount == 1)
109 InterlockedIncrement(&d3drm->iface_count);
110
111 return refcount;
112 }
113
114 static ULONG WINAPI d3drm1_Release(IDirect3DRM *iface)
115 {
116 struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
117 ULONG refcount = InterlockedDecrement(&d3drm->ref1);
118
119 TRACE("%p decreasing refcount to %u.\n", iface, refcount);
120
121 if (!refcount && !InterlockedDecrement(&d3drm->iface_count))
122 d3drm_destroy(d3drm);
123
124 return refcount;
125 }
126
127 static HRESULT WINAPI d3drm1_CreateObject(IDirect3DRM *iface,
128 REFCLSID clsid, IUnknown *outer, REFIID iid, void **out)
129 {
130 FIXME("iface %p, clsid %s, outer %p, iid %s, out %p stub!\n",
131 iface, debugstr_guid(clsid), outer, debugstr_guid(iid), out);
132
133 return E_NOTIMPL;
134 }
135
136 static HRESULT WINAPI d3drm1_CreateFrame(IDirect3DRM *iface,
137 IDirect3DRMFrame *parent_frame, IDirect3DRMFrame **frame)
138 {
139 TRACE("iface %p, parent_frame %p, frame %p.\n", iface, parent_frame, frame);
140
141 return Direct3DRMFrame_create(&IID_IDirect3DRMFrame, (IUnknown *)parent_frame, (IUnknown **)frame);
142 }
143
144 static HRESULT WINAPI d3drm1_CreateMesh(IDirect3DRM *iface, IDirect3DRMMesh **mesh)
145 {
146 struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
147
148 TRACE("iface %p, mesh %p.\n", iface, mesh);
149
150 return IDirect3DRM3_CreateMesh(&d3drm->IDirect3DRM3_iface, mesh);
151 }
152
153 static HRESULT WINAPI d3drm1_CreateMeshBuilder(IDirect3DRM *iface, IDirect3DRMMeshBuilder **mesh_builder)
154 {
155 TRACE("iface %p, mesh_builder %p.\n", iface, mesh_builder);
156
157 return Direct3DRMMeshBuilder_create(&IID_IDirect3DRMMeshBuilder, (IUnknown **)mesh_builder);
158 }
159
160 static HRESULT WINAPI d3drm1_CreateFace(IDirect3DRM *iface, IDirect3DRMFace **face)
161 {
162 TRACE("iface %p, face %p.\n", iface, face);
163
164 return Direct3DRMFace_create(&IID_IDirect3DRMFace, (IUnknown **)face);
165 }
166
167 static HRESULT WINAPI d3drm1_CreateAnimation(IDirect3DRM *iface, IDirect3DRMAnimation **animation)
168 {
169 FIXME("iface %p, animation %p stub!\n", iface, animation);
170
171 return E_NOTIMPL;
172 }
173
174 static HRESULT WINAPI d3drm1_CreateAnimationSet(IDirect3DRM *iface, IDirect3DRMAnimationSet **set)
175 {
176 FIXME("iface %p, set %p stub!\n", iface, set);
177
178 return E_NOTIMPL;
179 }
180
181 static HRESULT WINAPI d3drm1_CreateTexture(IDirect3DRM *iface,
182 D3DRMIMAGE *image, IDirect3DRMTexture **texture)
183 {
184 FIXME("iface %p, image %p, texture %p partial stub.\n", iface, image, texture);
185
186 return Direct3DRMTexture_create(&IID_IDirect3DRMTexture, (IUnknown **)texture);
187 }
188
189 static HRESULT WINAPI d3drm1_CreateLight(IDirect3DRM *iface,
190 D3DRMLIGHTTYPE type, D3DCOLOR color, IDirect3DRMLight **light)
191 {
192 struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
193
194 TRACE("iface %p, type %#x, color 0x%08x, light %p.\n", iface, type, color, light);
195
196 return IDirect3DRM3_CreateLight(&d3drm->IDirect3DRM3_iface, type, color, light);
197 }
198
199 static HRESULT WINAPI d3drm1_CreateLightRGB(IDirect3DRM *iface, D3DRMLIGHTTYPE type,
200 D3DVALUE red, D3DVALUE green, D3DVALUE blue, IDirect3DRMLight **light)
201 {
202 struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
203
204 TRACE("iface %p, type %#x, red %.8e, green %.8e, blue %.8e, light %p.\n",
205 iface, type, red, green, blue, light);
206
207 return IDirect3DRM3_CreateLightRGB(&d3drm->IDirect3DRM3_iface, type, red, green, blue, light);
208 }
209
210 static HRESULT WINAPI d3drm1_CreateMaterial(IDirect3DRM *iface,
211 D3DVALUE power, IDirect3DRMMaterial **material)
212 {
213 struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
214
215 TRACE("iface %p, power %.8e, material %p.\n", iface, power, material);
216
217 return IDirect3DRM3_CreateMaterial(&d3drm->IDirect3DRM3_iface, power, (IDirect3DRMMaterial2 **)material);
218 }
219
220 static HRESULT WINAPI d3drm1_CreateDevice(IDirect3DRM *iface,
221 DWORD width, DWORD height, IDirect3DRMDevice **device)
222 {
223 struct d3drm_device *object;
224 HRESULT hr;
225 FIXME("iface %p, width %u, height %u, device %p partial stub!\n", iface, width, height, device);
226
227 hr = d3drm_device_create(&object);
228 if (FAILED(hr))
229 return hr;
230
231 *device = IDirect3DRMDevice_from_impl(object);
232
233 return D3DRM_OK;
234 }
235
236 static HRESULT WINAPI d3drm1_CreateDeviceFromSurface(IDirect3DRM *iface, GUID *guid,
237 IDirectDraw *ddraw, IDirectDrawSurface *backbuffer, IDirect3DRMDevice **device)
238 {
239 struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
240 struct d3drm_device *object;
241 HRESULT hr;
242
243 TRACE("iface %p, guid %s, ddraw %p, backbuffer %p, device %p.\n",
244 iface, debugstr_guid(guid), ddraw, backbuffer, device);
245
246 if (!device)
247 return D3DRMERR_BADVALUE;
248 *device = NULL;
249
250 if (!backbuffer || !ddraw)
251 return D3DRMERR_BADDEVICE;
252
253 hr = d3drm_device_create(&object);
254 if (FAILED(hr))
255 return hr;
256
257 hr = d3drm_device_init(object, 1, &d3drm->IDirect3DRM_iface, ddraw, backbuffer, TRUE);
258 if (SUCCEEDED(hr))
259 *device = IDirect3DRMDevice_from_impl(object);
260 else
261 d3drm_device_destroy(object);
262
263 return hr;
264 }
265
266 static HRESULT WINAPI d3drm1_CreateDeviceFromD3D(IDirect3DRM *iface,
267 IDirect3D *d3d, IDirect3DDevice *d3d_device, IDirect3DRMDevice **device)
268 {
269 struct d3drm_device *object;
270 HRESULT hr;
271 TRACE("iface %p, d3d %p, d3d_device %p, device %p.\n",
272 iface, d3d, d3d_device, device);
273
274 if (!device)
275 return D3DRMERR_BADVALUE;
276 *device = NULL;
277 if (!d3d || !d3d_device)
278 return D3DRMERR_BADVALUE;
279
280 hr = d3drm_device_create(&object);
281 if (FAILED(hr))
282 return hr;
283
284 hr = d3drm_device_set_ddraw_device_d3d(object, iface, d3d, d3d_device);
285 if (FAILED(hr))
286 {
287 d3drm_device_destroy(object);
288 return hr;
289 }
290 *device = IDirect3DRMDevice_from_impl(object);
291
292 return D3DRM_OK;
293 }
294
295 static HRESULT WINAPI d3drm1_CreateDeviceFromClipper(IDirect3DRM *iface,
296 IDirectDrawClipper *clipper, GUID *guid, int width, int height,
297 IDirect3DRMDevice **device)
298 {
299 struct d3drm_device *object;
300 IDirectDraw *ddraw;
301 IDirectDrawSurface *render_target;
302 HRESULT hr;
303
304 TRACE("iface %p, clipper %p, guid %s, width %d, height %d, device %p.\n",
305 iface, clipper, debugstr_guid(guid), width, height, device);
306
307 if (!device)
308 return D3DRMERR_BADVALUE;
309 *device = NULL;
310
311 if (!clipper || !width || !height)
312 return D3DRMERR_BADVALUE;
313
314 hr = DirectDrawCreate(NULL, &ddraw, NULL);
315 if (FAILED(hr))
316 return hr;
317
318 hr = d3drm_device_create(&object);
319 if (FAILED(hr))
320 {
321 IDirectDraw_Release(ddraw);
322 return hr;
323 }
324
325 hr = d3drm_device_create_surfaces_from_clipper(object, ddraw, clipper, width, height, &render_target);
326 if (FAILED(hr))
327 {
328 IDirectDraw_Release(ddraw);
329 d3drm_device_destroy(object);
330 return hr;
331 }
332
333 hr = d3drm_device_init(object, 1, iface, ddraw, render_target, TRUE);
334 IDirectDraw_Release(ddraw);
335 IDirectDrawSurface_Release(render_target);
336 if (FAILED(hr))
337 d3drm_device_destroy(object);
338 else
339 *device = IDirect3DRMDevice_from_impl(object);
340
341 return hr;
342 }
343
344 static HRESULT WINAPI d3drm1_CreateTextureFromSurface(IDirect3DRM *iface,
345 IDirectDrawSurface *surface, IDirect3DRMTexture **texture)
346 {
347 FIXME("iface %p, surface %p, texture %p stub!\n", iface, surface, texture);
348
349 return E_NOTIMPL;
350 }
351
352 static HRESULT WINAPI d3drm1_CreateShadow(IDirect3DRM *iface, IDirect3DRMVisual *visual,
353 IDirect3DRMLight *light, D3DVALUE px, D3DVALUE py, D3DVALUE pz, D3DVALUE nx, D3DVALUE ny, D3DVALUE nz,
354 IDirect3DRMVisual **shadow)
355 {
356 FIXME("iface %p, visual %p, light %p, px %.8e, py %.8e, pz %.8e, nx %.8e, ny %.8e, nz %.8e, shadow %p stub!\n",
357 iface, visual, light, px, py, pz, nx, ny, nz, shadow);
358
359 return E_NOTIMPL;
360 }
361
362 static HRESULT WINAPI d3drm1_CreateViewport(IDirect3DRM *iface, IDirect3DRMDevice *device,
363 IDirect3DRMFrame *camera, DWORD x, DWORD y, DWORD width, DWORD height, IDirect3DRMViewport **viewport)
364 {
365 FIXME("iface %p, device %p, camera %p, x %u, y %u, width %u, height %u, viewport %p partial stub!\n",
366 iface, device, camera, x, y, width, height, viewport);
367
368 return Direct3DRMViewport_create(&IID_IDirect3DRMViewport, (IUnknown **)viewport);
369 }
370
371 static HRESULT WINAPI d3drm1_CreateWrap(IDirect3DRM *iface, D3DRMWRAPTYPE type, IDirect3DRMFrame *frame,
372 D3DVALUE ox, D3DVALUE oy, D3DVALUE oz, D3DVALUE dx, D3DVALUE dy, D3DVALUE dz,
373 D3DVALUE ux, D3DVALUE uy, D3DVALUE uz, D3DVALUE ou, D3DVALUE ov, D3DVALUE su, D3DVALUE sv,
374 IDirect3DRMWrap **wrap)
375 {
376 FIXME("iface %p, type %#x, frame %p, ox %.8e, oy %.8e, oz %.8e, dx %.8e, dy %.8e, dz %.8e, "
377 "ux %.8e, uy %.8e, uz %.8e, ou %.8e, ov %.8e, su %.8e, sv %.8e, wrap %p stub!\n",
378 iface, type, frame, ox, oy, oz, dx, dy, dz, ux, uy, uz, ou, ov, su, sv, wrap);
379
380 return E_NOTIMPL;
381 }
382
383 static HRESULT WINAPI d3drm1_CreateUserVisual(IDirect3DRM *iface,
384 D3DRMUSERVISUALCALLBACK cb, void *ctx, IDirect3DRMUserVisual **visual)
385 {
386 FIXME("iface %p, cb %p, ctx %p visual %p stub!\n", iface, cb, ctx, visual);
387
388 return E_NOTIMPL;
389 }
390
391 static HRESULT WINAPI d3drm1_LoadTexture(IDirect3DRM *iface,
392 const char *filename, IDirect3DRMTexture **texture)
393 {
394 FIXME("iface %p, filename %s, texture %p stub!\n", iface, debugstr_a(filename), texture);
395
396 return Direct3DRMTexture_create(&IID_IDirect3DRMTexture, (IUnknown **)texture);
397 }
398
399 static HRESULT WINAPI d3drm1_LoadTextureFromResource(IDirect3DRM *iface,
400 HRSRC resource, IDirect3DRMTexture **texture)
401 {
402 FIXME("iface %p, resource %p, texture %p stub!\n", iface, resource, texture);
403
404 return Direct3DRMTexture_create(&IID_IDirect3DRMTexture, (IUnknown **)texture);
405 }
406
407 static HRESULT WINAPI d3drm1_SetSearchPath(IDirect3DRM *iface, const char *path)
408 {
409 FIXME("iface %p, path %s stub!\n", iface, debugstr_a(path));
410
411 return E_NOTIMPL;
412 }
413
414 static HRESULT WINAPI d3drm1_AddSearchPath(IDirect3DRM *iface, const char *path)
415 {
416 FIXME("iface %p, path %s stub!\n", iface, debugstr_a(path));
417
418 return E_NOTIMPL;
419 }
420
421 static HRESULT WINAPI d3drm1_GetSearchPath(IDirect3DRM *iface, DWORD *size, char *path)
422 {
423 FIXME("iface %p, size %p, path %p stub!\n", iface, size, path);
424
425 return E_NOTIMPL;
426 }
427
428 static HRESULT WINAPI d3drm1_SetDefaultTextureColors(IDirect3DRM *iface, DWORD color_count)
429 {
430 FIXME("iface %p, color_count %u stub!\n", iface, color_count);
431
432 return E_NOTIMPL;
433 }
434
435 static HRESULT WINAPI d3drm1_SetDefaultTextureShades(IDirect3DRM *iface, DWORD shade_count)
436 {
437 FIXME("iface %p, shade_count %u stub!\n", iface, shade_count);
438
439 return E_NOTIMPL;
440 }
441
442 static HRESULT WINAPI d3drm1_GetDevices(IDirect3DRM *iface, IDirect3DRMDeviceArray **array)
443 {
444 FIXME("iface %p, array %p stub!\n", iface, array);
445
446 return E_NOTIMPL;
447 }
448
449 static HRESULT WINAPI d3drm1_GetNamedObject(IDirect3DRM *iface,
450 const char *name, IDirect3DRMObject **object)
451 {
452 FIXME("iface %p, name %s, object %p stub!\n", iface, debugstr_a(name), object);
453
454 return E_NOTIMPL;
455 }
456
457 static HRESULT WINAPI d3drm1_EnumerateObjects(IDirect3DRM *iface, D3DRMOBJECTCALLBACK cb, void *ctx)
458 {
459 FIXME("iface %p, cb %p, ctx %p stub!\n", iface, cb, ctx);
460
461 return E_NOTIMPL;
462 }
463
464 static HRESULT WINAPI d3drm1_Load(IDirect3DRM *iface, void *source, void *object_id, IID **iids,
465 DWORD iid_count, D3DRMLOADOPTIONS flags, D3DRMLOADCALLBACK load_cb, void *load_ctx,
466 D3DRMLOADTEXTURECALLBACK load_tex_cb, void *load_tex_ctx, IDirect3DRMFrame *parent_frame)
467 {
468 struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
469 IDirect3DRMFrame3 *parent_frame3 = NULL;
470 HRESULT hr = D3DRM_OK;
471
472 TRACE("iface %p, source %p, object_id %p, iids %p, iid_count %u, flags %#x, "
473 "load_cb %p, load_ctx %p, load_tex_cb %p, load_tex_ctx %p, parent_frame %p.\n",
474 iface, source, object_id, iids, iid_count, flags,
475 load_cb, load_ctx, load_tex_cb, load_tex_ctx, parent_frame);
476
477 if (parent_frame)
478 hr = IDirect3DRMFrame_QueryInterface(parent_frame, &IID_IDirect3DRMFrame3, (void **)&parent_frame3);
479 if (SUCCEEDED(hr))
480 hr = IDirect3DRM3_Load(&d3drm->IDirect3DRM3_iface, source, object_id, iids, iid_count,
481 flags, load_cb, load_ctx, load_tex_cb, load_tex_ctx, parent_frame3);
482 if (parent_frame3)
483 IDirect3DRMFrame3_Release(parent_frame3);
484
485 return hr;
486 }
487
488 static HRESULT WINAPI d3drm1_Tick(IDirect3DRM *iface, D3DVALUE tick)
489 {
490 FIXME("iface %p, tick %.8e stub!\n", iface, tick);
491
492 return E_NOTIMPL;
493 }
494
495 static const struct IDirect3DRMVtbl d3drm1_vtbl =
496 {
497 d3drm1_QueryInterface,
498 d3drm1_AddRef,
499 d3drm1_Release,
500 d3drm1_CreateObject,
501 d3drm1_CreateFrame,
502 d3drm1_CreateMesh,
503 d3drm1_CreateMeshBuilder,
504 d3drm1_CreateFace,
505 d3drm1_CreateAnimation,
506 d3drm1_CreateAnimationSet,
507 d3drm1_CreateTexture,
508 d3drm1_CreateLight,
509 d3drm1_CreateLightRGB,
510 d3drm1_CreateMaterial,
511 d3drm1_CreateDevice,
512 d3drm1_CreateDeviceFromSurface,
513 d3drm1_CreateDeviceFromD3D,
514 d3drm1_CreateDeviceFromClipper,
515 d3drm1_CreateTextureFromSurface,
516 d3drm1_CreateShadow,
517 d3drm1_CreateViewport,
518 d3drm1_CreateWrap,
519 d3drm1_CreateUserVisual,
520 d3drm1_LoadTexture,
521 d3drm1_LoadTextureFromResource,
522 d3drm1_SetSearchPath,
523 d3drm1_AddSearchPath,
524 d3drm1_GetSearchPath,
525 d3drm1_SetDefaultTextureColors,
526 d3drm1_SetDefaultTextureShades,
527 d3drm1_GetDevices,
528 d3drm1_GetNamedObject,
529 d3drm1_EnumerateObjects,
530 d3drm1_Load,
531 d3drm1_Tick,
532 };
533
534 static HRESULT WINAPI d3drm2_QueryInterface(IDirect3DRM2 *iface, REFIID riid, void **out)
535 {
536 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
537
538 return d3drm1_QueryInterface(&d3drm->IDirect3DRM_iface, riid, out);
539 }
540
541 static ULONG WINAPI d3drm2_AddRef(IDirect3DRM2 *iface)
542 {
543 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
544 ULONG refcount = InterlockedIncrement(&d3drm->ref2);
545
546 TRACE("%p increasing refcount to %u.\n", iface, refcount);
547
548 if (refcount == 1)
549 InterlockedIncrement(&d3drm->iface_count);
550
551 return refcount;
552 }
553
554 static ULONG WINAPI d3drm2_Release(IDirect3DRM2 *iface)
555 {
556 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
557 ULONG refcount = InterlockedDecrement(&d3drm->ref2);
558
559 TRACE("%p decreasing refcount to %u.\n", iface, refcount);
560
561 if (!refcount && !InterlockedDecrement(&d3drm->iface_count))
562 d3drm_destroy(d3drm);
563
564 return refcount;
565 }
566
567 static HRESULT WINAPI d3drm2_CreateObject(IDirect3DRM2 *iface,
568 REFCLSID clsid, IUnknown *outer, REFIID iid, void **out)
569 {
570 FIXME("iface %p, clsid %s, outer %p, iid %s, out %p stub!\n",
571 iface, debugstr_guid(clsid), outer, debugstr_guid(iid), out);
572
573 return E_NOTIMPL;
574 }
575
576 static HRESULT WINAPI d3drm2_CreateFrame(IDirect3DRM2 *iface,
577 IDirect3DRMFrame *parent_frame, IDirect3DRMFrame2 **frame)
578 {
579 TRACE("iface %p, parent_frame %p, frame %p.\n", iface, parent_frame, frame);
580
581 return Direct3DRMFrame_create(&IID_IDirect3DRMFrame2, (IUnknown*)parent_frame, (IUnknown**)frame);
582 }
583
584 static HRESULT WINAPI d3drm2_CreateMesh(IDirect3DRM2 *iface, IDirect3DRMMesh **mesh)
585 {
586 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
587
588 TRACE("iface %p, mesh %p.\n", iface, mesh);
589
590 return IDirect3DRM3_CreateMesh(&d3drm->IDirect3DRM3_iface, mesh);
591 }
592
593 static HRESULT WINAPI d3drm2_CreateMeshBuilder(IDirect3DRM2 *iface, IDirect3DRMMeshBuilder2 **mesh_builder)
594 {
595 TRACE("iface %p, mesh_builder %p.\n", iface, mesh_builder);
596
597 return Direct3DRMMeshBuilder_create(&IID_IDirect3DRMMeshBuilder2, (IUnknown **)mesh_builder);
598 }
599
600 static HRESULT WINAPI d3drm2_CreateFace(IDirect3DRM2 *iface, IDirect3DRMFace **face)
601 {
602 TRACE("iface %p, face %p.\n", iface, face);
603
604 return Direct3DRMFace_create(&IID_IDirect3DRMFace, (IUnknown **)face);
605 }
606
607 static HRESULT WINAPI d3drm2_CreateAnimation(IDirect3DRM2 *iface, IDirect3DRMAnimation **animation)
608 {
609 FIXME("iface %p, animation %p stub!\n", iface, animation);
610
611 return E_NOTIMPL;
612 }
613
614 static HRESULT WINAPI d3drm2_CreateAnimationSet(IDirect3DRM2 *iface, IDirect3DRMAnimationSet **set)
615 {
616 FIXME("iface %p, set %p stub!\n", iface, set);
617
618 return E_NOTIMPL;
619 }
620
621 static HRESULT WINAPI d3drm2_CreateTexture(IDirect3DRM2 *iface,
622 D3DRMIMAGE *image, IDirect3DRMTexture2 **texture)
623 {
624 FIXME("iface %p, image %p, texture %p partial stub.\n", iface, image, texture);
625
626 return Direct3DRMTexture_create(&IID_IDirect3DRMTexture2, (IUnknown **)texture);
627 }
628
629 static HRESULT WINAPI d3drm2_CreateLight(IDirect3DRM2 *iface,
630 D3DRMLIGHTTYPE type, D3DCOLOR color, IDirect3DRMLight **light)
631 {
632 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
633
634 TRACE("iface %p, type %#x, color 0x%08x, light %p.\n", iface, type, color, light);
635
636 return IDirect3DRM3_CreateLight(&d3drm->IDirect3DRM3_iface, type, color, light);
637 }
638
639 static HRESULT WINAPI d3drm2_CreateLightRGB(IDirect3DRM2 *iface, D3DRMLIGHTTYPE type,
640 D3DVALUE red, D3DVALUE green, D3DVALUE blue, IDirect3DRMLight **light)
641 {
642 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
643
644 TRACE("iface %p, type %#x, red %.8e, green %.8e, blue %.8e, light %p.\n",
645 iface, type, red, green, blue, light);
646
647 return IDirect3DRM3_CreateLightRGB(&d3drm->IDirect3DRM3_iface, type, red, green, blue, light);
648 }
649
650 static HRESULT WINAPI d3drm2_CreateMaterial(IDirect3DRM2 *iface,
651 D3DVALUE power, IDirect3DRMMaterial **material)
652 {
653 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
654
655 TRACE("iface %p, power %.8e, material %p.\n", iface, power, material);
656
657 return IDirect3DRM3_CreateMaterial(&d3drm->IDirect3DRM3_iface, power, (IDirect3DRMMaterial2 **)material);
658 }
659
660 static HRESULT WINAPI d3drm2_CreateDevice(IDirect3DRM2 *iface,
661 DWORD width, DWORD height, IDirect3DRMDevice2 **device)
662 {
663 struct d3drm_device *object;
664 HRESULT hr;
665 FIXME("iface %p, width %u, height %u, device %p partial stub!\n", iface, width, height, device);
666
667 hr = d3drm_device_create(&object);
668 if (FAILED(hr))
669 return hr;
670
671 *device = IDirect3DRMDevice2_from_impl(object);
672
673 return D3DRM_OK;
674 }
675
676 static HRESULT WINAPI d3drm2_CreateDeviceFromSurface(IDirect3DRM2 *iface, GUID *guid,
677 IDirectDraw *ddraw, IDirectDrawSurface *backbuffer, IDirect3DRMDevice2 **device)
678 {
679 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
680 IDirect3DRMDevice3 *device3;
681 HRESULT hr;
682 TRACE("iface %p, guid %s, ddraw %p, backbuffer %p, device %p.\n",
683 iface, debugstr_guid(guid), ddraw, backbuffer, device);
684
685 if (!device)
686 return D3DRMERR_BADVALUE;
687 *device = NULL;
688 hr = IDirect3DRM3_CreateDeviceFromSurface(&d3drm->IDirect3DRM3_iface, guid, ddraw, backbuffer, 0, &device3);
689 if (FAILED(hr))
690 return hr;
691
692 hr = IDirect3DRMDevice3_QueryInterface(device3, &IID_IDirect3DRMDevice2, (void**)device);
693 IDirect3DRMDevice3_Release(device3);
694
695 return hr;
696 }
697
698 static HRESULT WINAPI d3drm2_CreateDeviceFromD3D(IDirect3DRM2 *iface,
699 IDirect3D2 *d3d, IDirect3DDevice2 *d3d_device, IDirect3DRMDevice2 **device)
700 {
701 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
702 IDirect3D *d3d1;
703 IDirect3DDevice *d3d_device1;
704 IDirect3DRMDevice *device1;
705 HRESULT hr;
706 TRACE("iface %p, d3d %p, d3d_device %p, device %p.\n",
707 iface, d3d, d3d_device, device);
708
709 if (!device)
710 return D3DRMERR_BADVALUE;
711 *device = NULL;
712 if (!d3d || !d3d_device)
713 return D3DRMERR_BADVALUE;
714
715 hr = IDirect3D2_QueryInterface(d3d, &IID_IDirect3D, (void **)&d3d1);
716 if (FAILED(hr))
717 return hr;
718
719 hr = IDirect3DDevice2_QueryInterface(d3d_device, &IID_IDirect3DDevice, (void **)&d3d_device1);
720 if (FAILED(hr))
721 {
722 IDirect3D_Release(d3d1);
723 return hr;
724 }
725
726 hr = IDirect3DRM_CreateDeviceFromD3D(&d3drm->IDirect3DRM_iface, d3d1, d3d_device1, &device1);
727 IDirect3D_Release(d3d1);
728 IDirect3DDevice_Release(d3d_device1);
729 if (FAILED(hr))
730 return hr;
731
732 hr = IDirect3DRMDevice_QueryInterface(device1, &IID_IDirect3DRMDevice2, (void **)device);
733 IDirect3DRMDevice_Release(device1);
734
735 return hr;
736 }
737
738 static HRESULT WINAPI d3drm2_CreateDeviceFromClipper(IDirect3DRM2 *iface,
739 IDirectDrawClipper *clipper, GUID *guid, int width, int height,
740 IDirect3DRMDevice2 **device)
741 {
742 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
743 IDirect3DRMDevice3 *device3;
744 HRESULT hr;
745
746 TRACE("iface %p, clipper %p, guid %s, width %d, height %d, device %p.\n",
747 iface, clipper, debugstr_guid(guid), width, height, device);
748
749 if (!device)
750 return D3DRMERR_BADVALUE;
751 *device = NULL;
752 hr = IDirect3DRM3_CreateDeviceFromClipper(&d3drm->IDirect3DRM3_iface, clipper, guid, width, height, &device3);
753 if (FAILED(hr))
754 return hr;
755
756 hr = IDirect3DRMDevice3_QueryInterface(device3, &IID_IDirect3DRMDevice2, (void**)device);
757 IDirect3DRMDevice3_Release(device3);
758
759 return hr;
760 }
761
762 static HRESULT WINAPI d3drm2_CreateTextureFromSurface(IDirect3DRM2 *iface,
763 IDirectDrawSurface *surface, IDirect3DRMTexture2 **texture)
764 {
765 FIXME("iface %p, surface %p, texture %p stub!\n", iface, surface, texture);
766
767 return E_NOTIMPL;
768 }
769
770 static HRESULT WINAPI d3drm2_CreateShadow(IDirect3DRM2 *iface, IDirect3DRMVisual *visual,
771 IDirect3DRMLight *light, D3DVALUE px, D3DVALUE py, D3DVALUE pz, D3DVALUE nx, D3DVALUE ny, D3DVALUE nz,
772 IDirect3DRMVisual **shadow)
773 {
774 FIXME("iface %p, visual %p, light %p, px %.8e, py %.8e, pz %.8e, nx %.8e, ny %.8e, nz %.8e, shadow %p stub!\n",
775 iface, visual, light, px, py, pz, nx, ny, nz, shadow);
776
777 return E_NOTIMPL;
778 }
779
780 static HRESULT WINAPI d3drm2_CreateViewport(IDirect3DRM2 *iface, IDirect3DRMDevice *device,
781 IDirect3DRMFrame *camera, DWORD x, DWORD y, DWORD width, DWORD height, IDirect3DRMViewport **viewport)
782 {
783 FIXME("iface %p, device %p, camera %p, x %u, y %u, width %u, height %u, viewport %p partial stub!\n",
784 iface, device, camera, x, y, width, height, viewport);
785
786 return Direct3DRMViewport_create(&IID_IDirect3DRMViewport, (IUnknown **)viewport);
787 }
788
789 static HRESULT WINAPI d3drm2_CreateWrap(IDirect3DRM2 *iface, D3DRMWRAPTYPE type, IDirect3DRMFrame *frame,
790 D3DVALUE ox, D3DVALUE oy, D3DVALUE oz, D3DVALUE dx, D3DVALUE dy, D3DVALUE dz,
791 D3DVALUE ux, D3DVALUE uy, D3DVALUE uz, D3DVALUE ou, D3DVALUE ov, D3DVALUE su, D3DVALUE sv,
792 IDirect3DRMWrap **wrap)
793 {
794 FIXME("iface %p, type %#x, frame %p, ox %.8e, oy %.8e, oz %.8e, dx %.8e, dy %.8e, dz %.8e, "
795 "ux %.8e, uy %.8e, uz %.8e, ou %.8e, ov %.8e, su %.8e, sv %.8e, wrap %p stub!\n",
796 iface, type, frame, ox, oy, oz, dx, dy, dz, ux, uy, uz, ou, ov, su, sv, wrap);
797
798 return E_NOTIMPL;
799 }
800
801 static HRESULT WINAPI d3drm2_CreateUserVisual(IDirect3DRM2 *iface,
802 D3DRMUSERVISUALCALLBACK cb, void *ctx, IDirect3DRMUserVisual **visual)
803 {
804 FIXME("iface %p, cb %p, ctx %p, visual %p stub!\n", iface, cb, ctx, visual);
805
806 return E_NOTIMPL;
807 }
808
809 static HRESULT WINAPI d3drm2_LoadTexture(IDirect3DRM2 *iface,
810 const char *filename, IDirect3DRMTexture2 **texture)
811 {
812 FIXME("iface %p, filename %s, texture %p stub!\n", iface, debugstr_a(filename), texture);
813
814 return Direct3DRMTexture_create(&IID_IDirect3DRMTexture2, (IUnknown **)texture);
815 }
816
817 static HRESULT WINAPI d3drm2_LoadTextureFromResource(IDirect3DRM2 *iface, HMODULE module,
818 const char *resource_name, const char *resource_type, IDirect3DRMTexture2 **texture)
819 {
820 FIXME("iface %p, resource_name %s, resource_type %s, texture %p stub!\n",
821 iface, debugstr_a(resource_name), debugstr_a(resource_type), texture);
822
823 return Direct3DRMTexture_create(&IID_IDirect3DRMTexture2, (IUnknown **)texture);
824 }
825
826 static HRESULT WINAPI d3drm2_SetSearchPath(IDirect3DRM2 *iface, const char *path)
827 {
828 FIXME("iface %p, path %s stub!\n", iface, debugstr_a(path));
829
830 return E_NOTIMPL;
831 }
832
833 static HRESULT WINAPI d3drm2_AddSearchPath(IDirect3DRM2 *iface, const char *path)
834 {
835 FIXME("iface %p, path %s stub!\n", iface, debugstr_a(path));
836
837 return E_NOTIMPL;
838 }
839
840 static HRESULT WINAPI d3drm2_GetSearchPath(IDirect3DRM2 *iface, DWORD *size, char *path)
841 {
842 FIXME("iface %p, size %p, path %p stub!\n", iface, size, path);
843
844 return E_NOTIMPL;
845 }
846
847 static HRESULT WINAPI d3drm2_SetDefaultTextureColors(IDirect3DRM2 *iface, DWORD color_count)
848 {
849 FIXME("iface %p, color_count %u stub!\n", iface, color_count);
850
851 return E_NOTIMPL;
852 }
853
854 static HRESULT WINAPI d3drm2_SetDefaultTextureShades(IDirect3DRM2 *iface, DWORD shade_count)
855 {
856 FIXME("iface %p, shade_count %u stub!\n", iface, shade_count);
857
858 return E_NOTIMPL;
859 }
860
861 static HRESULT WINAPI d3drm2_GetDevices(IDirect3DRM2 *iface, IDirect3DRMDeviceArray **array)
862 {
863 FIXME("iface %p, array %p stub!\n", iface, array);
864
865 return E_NOTIMPL;
866 }
867
868 static HRESULT WINAPI d3drm2_GetNamedObject(IDirect3DRM2 *iface,
869 const char *name, IDirect3DRMObject **object)
870 {
871 FIXME("iface %p, name %s, object %p stub!\n", iface, debugstr_a(name), object);
872
873 return E_NOTIMPL;
874 }
875
876 static HRESULT WINAPI d3drm2_EnumerateObjects(IDirect3DRM2 *iface, D3DRMOBJECTCALLBACK cb, void *ctx)
877 {
878 FIXME("iface %p, cb %p, ctx %p stub!\n", iface, cb, ctx);
879
880 return E_NOTIMPL;
881 }
882
883 static HRESULT WINAPI d3drm2_Load(IDirect3DRM2 *iface, void *source, void *object_id, IID **iids,
884 DWORD iid_count, D3DRMLOADOPTIONS flags, D3DRMLOADCALLBACK load_cb, void *load_ctx,
885 D3DRMLOADTEXTURECALLBACK load_tex_cb, void *load_tex_ctx, IDirect3DRMFrame *parent_frame)
886 {
887 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
888 IDirect3DRMFrame3 *parent_frame3 = NULL;
889 HRESULT hr = D3DRM_OK;
890
891 TRACE("iface %p, source %p, object_id %p, iids %p, iid_count %u, flags %#x, "
892 "load_cb %p, load_ctx %p, load_tex_cb %p, load_tex_ctx %p, parent_frame %p.\n",
893 iface, source, object_id, iids, iid_count, flags,
894 load_cb, load_ctx, load_tex_cb, load_tex_ctx, parent_frame);
895
896 if (parent_frame)
897 hr = IDirect3DRMFrame_QueryInterface(parent_frame, &IID_IDirect3DRMFrame3, (void **)&parent_frame3);
898 if (SUCCEEDED(hr))
899 hr = IDirect3DRM3_Load(&d3drm->IDirect3DRM3_iface, source, object_id, iids, iid_count,
900 flags, load_cb, load_ctx, load_tex_cb, load_tex_ctx, parent_frame3);
901 if (parent_frame3)
902 IDirect3DRMFrame3_Release(parent_frame3);
903
904 return hr;
905 }
906
907 static HRESULT WINAPI d3drm2_Tick(IDirect3DRM2 *iface, D3DVALUE tick)
908 {
909 FIXME("iface %p, tick %.8e stub!\n", iface, tick);
910
911 return E_NOTIMPL;
912 }
913
914 static HRESULT WINAPI d3drm2_CreateProgressiveMesh(IDirect3DRM2 *iface, IDirect3DRMProgressiveMesh **mesh)
915 {
916 FIXME("iface %p, mesh %p stub!\n", iface, mesh);
917
918 return E_NOTIMPL;
919 }
920
921 static const struct IDirect3DRM2Vtbl d3drm2_vtbl =
922 {
923 d3drm2_QueryInterface,
924 d3drm2_AddRef,
925 d3drm2_Release,
926 d3drm2_CreateObject,
927 d3drm2_CreateFrame,
928 d3drm2_CreateMesh,
929 d3drm2_CreateMeshBuilder,
930 d3drm2_CreateFace,
931 d3drm2_CreateAnimation,
932 d3drm2_CreateAnimationSet,
933 d3drm2_CreateTexture,
934 d3drm2_CreateLight,
935 d3drm2_CreateLightRGB,
936 d3drm2_CreateMaterial,
937 d3drm2_CreateDevice,
938 d3drm2_CreateDeviceFromSurface,
939 d3drm2_CreateDeviceFromD3D,
940 d3drm2_CreateDeviceFromClipper,
941 d3drm2_CreateTextureFromSurface,
942 d3drm2_CreateShadow,
943 d3drm2_CreateViewport,
944 d3drm2_CreateWrap,
945 d3drm2_CreateUserVisual,
946 d3drm2_LoadTexture,
947 d3drm2_LoadTextureFromResource,
948 d3drm2_SetSearchPath,
949 d3drm2_AddSearchPath,
950 d3drm2_GetSearchPath,
951 d3drm2_SetDefaultTextureColors,
952 d3drm2_SetDefaultTextureShades,
953 d3drm2_GetDevices,
954 d3drm2_GetNamedObject,
955 d3drm2_EnumerateObjects,
956 d3drm2_Load,
957 d3drm2_Tick,
958 d3drm2_CreateProgressiveMesh,
959 };
960
961 static HRESULT WINAPI d3drm3_QueryInterface(IDirect3DRM3 *iface, REFIID riid, void **out)
962 {
963 struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
964
965 return d3drm1_QueryInterface(&d3drm->IDirect3DRM_iface, riid, out);
966 }
967
968 static ULONG WINAPI d3drm3_AddRef(IDirect3DRM3 *iface)
969 {
970 struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
971 ULONG refcount = InterlockedIncrement(&d3drm->ref3);
972
973 TRACE("%p increasing refcount to %u.\n", iface, refcount);
974
975 if (refcount == 1)
976 InterlockedIncrement(&d3drm->iface_count);
977
978 return refcount;
979 }
980
981 static ULONG WINAPI d3drm3_Release(IDirect3DRM3 *iface)
982 {
983 struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
984 ULONG refcount = InterlockedDecrement(&d3drm->ref3);
985
986 TRACE("%p decreasing refcount to %u.\n", iface, refcount);
987
988 if (!refcount && !InterlockedDecrement(&d3drm->iface_count))
989 d3drm_destroy(d3drm);
990
991 return refcount;
992 }
993
994 static HRESULT WINAPI d3drm3_CreateObject(IDirect3DRM3 *iface,
995 REFCLSID clsid, IUnknown *outer, REFIID iid, void **out)
996 {
997 FIXME("iface %p, clsid %s, outer %p, iid %s, out %p stub!\n",
998 iface, debugstr_guid(clsid), outer, debugstr_guid(iid), out);
999
1000 return E_NOTIMPL;
1001 }
1002
1003 static HRESULT WINAPI d3drm3_CreateFrame(IDirect3DRM3 *iface,
1004 IDirect3DRMFrame3 *parent, IDirect3DRMFrame3 **frame)
1005 {
1006 TRACE("iface %p, parent %p, frame %p.\n", iface, parent, frame);
1007
1008 return Direct3DRMFrame_create(&IID_IDirect3DRMFrame3, (IUnknown *)parent, (IUnknown **)frame);
1009 }
1010
1011 static HRESULT WINAPI d3drm3_CreateMesh(IDirect3DRM3 *iface, IDirect3DRMMesh **mesh)
1012 {
1013 TRACE("iface %p, mesh %p.\n", iface, mesh);
1014
1015 return Direct3DRMMesh_create(mesh);
1016 }
1017
1018 static HRESULT WINAPI d3drm3_CreateMeshBuilder(IDirect3DRM3 *iface, IDirect3DRMMeshBuilder3 **mesh_builder)
1019 {
1020 TRACE("iface %p, mesh_builder %p.\n", iface, mesh_builder);
1021
1022 return Direct3DRMMeshBuilder_create(&IID_IDirect3DRMMeshBuilder3, (IUnknown **)mesh_builder);
1023 }
1024
1025 static HRESULT WINAPI d3drm3_CreateFace(IDirect3DRM3 *iface, IDirect3DRMFace2 **face)
1026 {
1027 TRACE("iface %p, face %p.\n", iface, face);
1028
1029 return Direct3DRMFace_create(&IID_IDirect3DRMFace2, (IUnknown **)face);
1030 }
1031
1032 static HRESULT WINAPI d3drm3_CreateAnimation(IDirect3DRM3 *iface, IDirect3DRMAnimation2 **animation)
1033 {
1034 FIXME("iface %p, animation %p stub!\n", iface, animation);
1035
1036 return E_NOTIMPL;
1037 }
1038
1039 static HRESULT WINAPI d3drm3_CreateAnimationSet(IDirect3DRM3 *iface, IDirect3DRMAnimationSet2 **set)
1040 {
1041 FIXME("iface %p, set %p stub!\n", iface, set);
1042
1043 return E_NOTIMPL;
1044 }
1045
1046 static HRESULT WINAPI d3drm3_CreateTexture(IDirect3DRM3 *iface,
1047 D3DRMIMAGE *image, IDirect3DRMTexture3 **texture)
1048 {
1049 FIXME("iface %p, image %p, texture %p partial stub.\n", iface, image, texture);
1050
1051 return Direct3DRMTexture_create(&IID_IDirect3DRMTexture3, (IUnknown **)texture);
1052 }
1053
1054 static HRESULT WINAPI d3drm3_CreateLight(IDirect3DRM3 *iface,
1055 D3DRMLIGHTTYPE type, D3DCOLOR color, IDirect3DRMLight **light)
1056 {
1057 HRESULT hr;
1058
1059 FIXME("iface %p, type %#x, color 0x%08x, light %p partial stub!\n", iface, type, color, light);
1060
1061 if (SUCCEEDED(hr = Direct3DRMLight_create((IUnknown **)light)))
1062 {
1063 IDirect3DRMLight_SetType(*light, type);
1064 IDirect3DRMLight_SetColor(*light, color);
1065 }
1066
1067 return hr;
1068 }
1069
1070 static HRESULT WINAPI d3drm3_CreateLightRGB(IDirect3DRM3 *iface, D3DRMLIGHTTYPE type,
1071 D3DVALUE red, D3DVALUE green, D3DVALUE blue, IDirect3DRMLight **light)
1072 {
1073 HRESULT hr;
1074
1075 FIXME("iface %p, type %#x, red %.8e, green %.8e, blue %.8e, light %p partial stub!\n",
1076 iface, type, red, green, blue, light);
1077
1078 if (SUCCEEDED(hr = Direct3DRMLight_create((IUnknown **)light)))
1079 {
1080 IDirect3DRMLight_SetType(*light, type);
1081 IDirect3DRMLight_SetColorRGB(*light, red, green, blue);
1082 }
1083
1084 return hr;
1085 }
1086
1087 static HRESULT WINAPI d3drm3_CreateMaterial(IDirect3DRM3 *iface,
1088 D3DVALUE power, IDirect3DRMMaterial2 **material)
1089 {
1090 HRESULT hr;
1091
1092 TRACE("iface %p, power %.8e, material %p.\n", iface, power, material);
1093
1094 if (SUCCEEDED(hr = Direct3DRMMaterial_create(material)))
1095 IDirect3DRMMaterial2_SetPower(*material, power);
1096
1097 return hr;
1098 }
1099
1100 static HRESULT WINAPI d3drm3_CreateDevice(IDirect3DRM3 *iface,
1101 DWORD width, DWORD height, IDirect3DRMDevice3 **device)
1102 {
1103 struct d3drm_device *object;
1104 HRESULT hr;
1105 FIXME("iface %p, width %u, height %u, device %p partial stub!\n", iface, width, height, device);
1106
1107 hr = d3drm_device_create(&object);
1108 if (FAILED(hr))
1109 return hr;
1110
1111 *device = IDirect3DRMDevice3_from_impl(object);
1112
1113 return D3DRM_OK;
1114 }
1115
1116 static HRESULT WINAPI d3drm3_CreateDeviceFromSurface(IDirect3DRM3 *iface, GUID *guid,
1117 IDirectDraw *ddraw, IDirectDrawSurface *backbuffer, DWORD flags, IDirect3DRMDevice3 **device)
1118 {
1119 struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1120 struct d3drm_device *object;
1121 BOOL use_z_surface;
1122 HRESULT hr;
1123
1124 TRACE("iface %p, guid %s, ddraw %p, backbuffer %p, flags %#x, device %p.\n",
1125 iface, debugstr_guid(guid), ddraw, backbuffer, flags, device);
1126
1127 if (!device)
1128 return D3DRMERR_BADVALUE;
1129 *device = NULL;
1130
1131 if (!backbuffer || !ddraw)
1132 return D3DRMERR_BADDEVICE;
1133
1134 hr = d3drm_device_create(&object);
1135 if (FAILED(hr))
1136 return hr;
1137
1138 use_z_surface = !(flags & D3DRMDEVICE_NOZBUFFER);
1139
1140 hr = d3drm_device_init(object, 3, &d3drm->IDirect3DRM_iface, ddraw, backbuffer, use_z_surface);
1141 if (SUCCEEDED(hr))
1142 *device = IDirect3DRMDevice3_from_impl(object);
1143 else
1144 d3drm_device_destroy(object);
1145
1146 return hr;
1147 }
1148
1149 static HRESULT WINAPI d3drm3_CreateDeviceFromD3D(IDirect3DRM3 *iface,
1150 IDirect3D2 *d3d, IDirect3DDevice2 *d3d_device, IDirect3DRMDevice3 **device)
1151 {
1152 struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1153 IDirect3D *d3d1;
1154 IDirect3DDevice *d3d_device1;
1155 IDirect3DRMDevice *device1;
1156 HRESULT hr;
1157 TRACE("iface %p, d3d %p, d3d_device %p, device %p.\n",
1158 iface, d3d, d3d_device, device);
1159
1160 if (!device)
1161 return D3DRMERR_BADVALUE;
1162 *device = NULL;
1163 if (!d3d || !d3d_device)
1164 return D3DRMERR_BADVALUE;
1165
1166 hr = IDirect3D2_QueryInterface(d3d, &IID_IDirect3D, (void **)&d3d1);
1167 if (FAILED(hr))
1168 return hr;
1169 hr = IDirect3DDevice2_QueryInterface(d3d_device, &IID_IDirect3DDevice, (void **)&d3d_device1);
1170 if (FAILED(hr))
1171 {
1172 IDirect3D_Release(d3d1);
1173 return hr;
1174 }
1175
1176 hr = IDirect3DRM_CreateDeviceFromD3D(&d3drm->IDirect3DRM_iface, d3d1, d3d_device1, &device1);
1177 IDirect3D_Release(d3d1);
1178 IDirect3DDevice_Release(d3d_device1);
1179 if (FAILED(hr))
1180 return hr;
1181
1182 hr = IDirect3DRMDevice_QueryInterface(device1, &IID_IDirect3DRMDevice3, (void **)device);
1183 IDirect3DRMDevice_Release(device1);
1184
1185 return hr;
1186 }
1187
1188 static HRESULT WINAPI d3drm3_CreateDeviceFromClipper(IDirect3DRM3 *iface,
1189 IDirectDrawClipper *clipper, GUID *guid, int width, int height,
1190 IDirect3DRMDevice3 **device)
1191 {
1192 struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1193 struct d3drm_device *object;
1194 IDirectDraw *ddraw;
1195 IDirectDrawSurface *render_target;
1196 HRESULT hr;
1197
1198 TRACE("iface %p, clipper %p, guid %s, width %d, height %d, device %p.\n",
1199 iface, clipper, debugstr_guid(guid), width, height, device);
1200
1201 if (!device)
1202 return D3DRMERR_BADVALUE;
1203 *device = NULL;
1204
1205 if (!clipper || !width || !height)
1206 return D3DRMERR_BADVALUE;
1207
1208 hr = DirectDrawCreate(NULL, &ddraw, NULL);
1209 if (FAILED(hr))
1210 return hr;
1211
1212 hr = d3drm_device_create(&object);
1213 if (FAILED(hr))
1214 {
1215 IDirectDraw_Release(ddraw);
1216 return hr;
1217 }
1218
1219 hr = d3drm_device_create_surfaces_from_clipper(object, ddraw, clipper, width, height, &render_target);
1220 if (FAILED(hr))
1221 {
1222 IDirectDraw_Release(ddraw);
1223 d3drm_device_destroy(object);
1224 return hr;
1225 }
1226
1227 hr = d3drm_device_init(object, 3, &d3drm->IDirect3DRM_iface, ddraw, render_target, TRUE);
1228 IDirectDraw_Release(ddraw);
1229 IDirectDrawSurface_Release(render_target);
1230 if (FAILED(hr))
1231 d3drm_device_destroy(object);
1232 else
1233 *device = IDirect3DRMDevice3_from_impl(object);
1234
1235 return hr;
1236 }
1237
1238 static HRESULT WINAPI d3drm3_CreateShadow(IDirect3DRM3 *iface, IUnknown *object, IDirect3DRMLight *light,
1239 D3DVALUE px, D3DVALUE py, D3DVALUE pz, D3DVALUE nx, D3DVALUE ny, D3DVALUE nz, IDirect3DRMShadow2 **shadow)
1240 {
1241 FIXME("iface %p, object %p, light %p, px %.8e, py %.8e, pz %.8e, nx %.8e, ny %.8e, nz %.8e, shadow %p stub!\n",
1242 iface, object, light, px, py, pz, nx, ny, nz, shadow);
1243
1244 return E_NOTIMPL;
1245 }
1246
1247 static HRESULT WINAPI d3drm3_CreateTextureFromSurface(IDirect3DRM3 *iface,
1248 IDirectDrawSurface *surface, IDirect3DRMTexture3 **texture)
1249 {
1250 FIXME("iface %p, surface %p, texture %p stub!\n", iface, surface, texture);
1251
1252 return E_NOTIMPL;
1253 }
1254
1255 static HRESULT WINAPI d3drm3_CreateViewport(IDirect3DRM3 *iface, IDirect3DRMDevice3 *device,
1256 IDirect3DRMFrame3 *camera, DWORD x, DWORD y, DWORD width, DWORD height, IDirect3DRMViewport2 **viewport)
1257 {
1258 FIXME("iface %p, device %p, camera %p, x %u, y %u, width %u, height %u, viewport %p partial stub!\n",
1259 iface, device, camera, x, y, width, height, viewport);
1260
1261 return Direct3DRMViewport_create(&IID_IDirect3DRMViewport2, (IUnknown **)viewport);
1262 }
1263
1264 static HRESULT WINAPI d3drm3_CreateWrap(IDirect3DRM3 *iface, D3DRMWRAPTYPE type, IDirect3DRMFrame3 *frame,
1265 D3DVALUE ox, D3DVALUE oy, D3DVALUE oz, D3DVALUE dx, D3DVALUE dy, D3DVALUE dz,
1266 D3DVALUE ux, D3DVALUE uy, D3DVALUE uz, D3DVALUE ou, D3DVALUE ov, D3DVALUE su, D3DVALUE sv,
1267 IDirect3DRMWrap **wrap)
1268 {
1269 FIXME("iface %p, type %#x, frame %p, ox %.8e, oy %.8e, oz %.8e, dx %.8e, dy %.8e, dz %.8e, "
1270 "ux %.8e, uy %.8e, uz %.8e, ou %.8e, ov %.8e, su %.8e, sv %.8e, wrap %p stub!\n",
1271 iface, type, frame, ox, oy, oz, dx, dy, dz, ux, uy, uz, ou, ov, su, sv, wrap);
1272
1273 return E_NOTIMPL;
1274 }
1275
1276 static HRESULT WINAPI d3drm3_CreateUserVisual(IDirect3DRM3 *iface,
1277 D3DRMUSERVISUALCALLBACK cb, void *ctx, IDirect3DRMUserVisual **visual)
1278 {
1279 FIXME("iface %p, cb %p, ctx %p, visual %p stub!\n", iface, cb, ctx, visual);
1280
1281 return E_NOTIMPL;
1282 }
1283
1284 static HRESULT WINAPI d3drm3_LoadTexture(IDirect3DRM3 *iface,
1285 const char *filename, IDirect3DRMTexture3 **texture)
1286 {
1287 FIXME("iface %p, filename %s, texture %p stub!\n", iface, debugstr_a(filename), texture);
1288
1289 return Direct3DRMTexture_create(&IID_IDirect3DRMTexture3, (IUnknown **)texture);
1290 }
1291
1292 static HRESULT WINAPI d3drm3_LoadTextureFromResource(IDirect3DRM3 *iface, HMODULE module,
1293 const char *resource_name, const char *resource_type, IDirect3DRMTexture3 **texture)
1294 {
1295 FIXME("iface %p, module %p, resource_name %s, resource_type %s, texture %p stub!\n",
1296 iface, module, debugstr_a(resource_name), debugstr_a(resource_type), texture);
1297
1298 return Direct3DRMTexture_create(&IID_IDirect3DRMTexture3, (IUnknown **)texture);
1299 }
1300
1301 static HRESULT WINAPI d3drm3_SetSearchPath(IDirect3DRM3 *iface, const char *path)
1302 {
1303 FIXME("iface %p, path %s stub!\n", iface, debugstr_a(path));
1304
1305 return E_NOTIMPL;
1306 }
1307
1308 static HRESULT WINAPI d3drm3_AddSearchPath(IDirect3DRM3 *iface, const char *path)
1309 {
1310 FIXME("iface %p, path %s stub!\n", iface, debugstr_a(path));
1311
1312 return E_NOTIMPL;
1313 }
1314
1315 static HRESULT WINAPI d3drm3_GetSearchPath(IDirect3DRM3 *iface, DWORD *size, char *path)
1316 {
1317 FIXME("iface %p, size %p, path %p stub!\n", iface, size, path);
1318
1319 return E_NOTIMPL;
1320 }
1321
1322 static HRESULT WINAPI d3drm3_SetDefaultTextureColors(IDirect3DRM3 *iface, DWORD color_count)
1323 {
1324 FIXME("iface %p, color_count %u stub!\n", iface, color_count);
1325
1326 return E_NOTIMPL;
1327 }
1328
1329 static HRESULT WINAPI d3drm3_SetDefaultTextureShades(IDirect3DRM3 *iface, DWORD shade_count)
1330 {
1331 FIXME("iface %p, shade_count %u stub!\n", iface, shade_count);
1332
1333 return E_NOTIMPL;
1334 }
1335
1336 static HRESULT WINAPI d3drm3_GetDevices(IDirect3DRM3 *iface, IDirect3DRMDeviceArray **array)
1337 {
1338 FIXME("iface %p, array %p stub!\n", iface, array);
1339
1340 return E_NOTIMPL;
1341 }
1342
1343 static HRESULT WINAPI d3drm3_GetNamedObject(IDirect3DRM3 *iface,
1344 const char *name, IDirect3DRMObject **object)
1345 {
1346 FIXME("iface %p, name %s, object %p stub!\n", iface, debugstr_a(name), object);
1347
1348 return E_NOTIMPL;
1349 }
1350
1351 static HRESULT WINAPI d3drm3_EnumerateObjects(IDirect3DRM3 *iface, D3DRMOBJECTCALLBACK cb, void *ctx)
1352 {
1353 FIXME("iface %p, cb %p, ctx %p stub!\n", iface, cb, ctx);
1354
1355 return E_NOTIMPL;
1356 }
1357
1358 static HRESULT load_data(IDirect3DRM3 *iface, IDirectXFileData *data_object, IID **GUIDs, DWORD nb_GUIDs, D3DRMLOADCALLBACK LoadProc,
1359 void *ArgLP, D3DRMLOADTEXTURECALLBACK LoadTextureProc, void *ArgLTP, IDirect3DRMFrame3 *parent_frame)
1360 {
1361 HRESULT ret = D3DRMERR_BADOBJECT;
1362 HRESULT hr;
1363 const GUID* guid;
1364 DWORD i;
1365 BOOL requested = FALSE;
1366
1367 hr = IDirectXFileData_GetType(data_object, &guid);
1368 if (hr != DXFILE_OK)
1369 goto end;
1370
1371 TRACE("Found object type whose GUID = %s\n", debugstr_guid(guid));
1372
1373 /* Load object only if it is top level and requested or if it is part of another object */
1374
1375 if (IsEqualGUID(guid, &TID_D3DRMMesh))
1376 {
1377 TRACE("Found TID_D3DRMMesh\n");
1378
1379 for (i = 0; i < nb_GUIDs; i++)
1380 if (IsEqualGUID(GUIDs[i], &IID_IDirect3DRMMeshBuilder) ||
1381 IsEqualGUID(GUIDs[i], &IID_IDirect3DRMMeshBuilder2) ||
1382 IsEqualGUID(GUIDs[i], &IID_IDirect3DRMMeshBuilder3))
1383 {
1384 requested = TRUE;
1385 break;
1386 }
1387
1388 if (requested || parent_frame)
1389 {
1390 IDirect3DRMMeshBuilder3 *meshbuilder;
1391
1392 TRACE("Load mesh data\n");
1393
1394 hr = IDirect3DRM3_CreateMeshBuilder(iface, &meshbuilder);
1395 if (SUCCEEDED(hr))
1396 {
1397 hr = load_mesh_data(meshbuilder, data_object, LoadTextureProc, ArgLTP);
1398 if (SUCCEEDED(hr))
1399 {
1400 /* Only top level objects are notified */
1401 if (!parent_frame)
1402 {
1403 IDirect3DRMObject *object;
1404
1405 hr = IDirect3DRMMeshBuilder3_QueryInterface(meshbuilder, GUIDs[i], (void**)&object);
1406 if (SUCCEEDED(hr))
1407 {
1408 LoadProc(object, GUIDs[i], ArgLP);
1409 IDirect3DRMObject_Release(object);
1410 }
1411 }
1412 else
1413 {
1414 IDirect3DRMFrame3_AddVisual(parent_frame, (IUnknown*)meshbuilder);
1415 }
1416 }
1417 IDirect3DRMMeshBuilder3_Release(meshbuilder);
1418 }
1419
1420 if (FAILED(hr))
1421 ERR("Cannot process mesh\n");
1422 }
1423 }
1424 else if (IsEqualGUID(guid, &TID_D3DRMFrame))
1425 {
1426 TRACE("Found TID_D3DRMFrame\n");
1427
1428 for (i = 0; i < nb_GUIDs; i++)
1429 if (IsEqualGUID(GUIDs[i], &IID_IDirect3DRMFrame) ||
1430 IsEqualGUID(GUIDs[i], &IID_IDirect3DRMFrame2) ||
1431 IsEqualGUID(GUIDs[i], &IID_IDirect3DRMFrame3))
1432 {
1433 requested = TRUE;
1434 break;
1435 }
1436
1437 if (requested || parent_frame)
1438 {
1439 IDirect3DRMFrame3 *frame;
1440
1441 TRACE("Load frame data\n");
1442
1443 hr = IDirect3DRM3_CreateFrame(iface, parent_frame, &frame);
1444 if (SUCCEEDED(hr))
1445 {
1446 IDirectXFileObject *child;
1447
1448 while (SUCCEEDED(hr = IDirectXFileData_GetNextObject(data_object, &child)))
1449 {
1450 IDirectXFileData *data;
1451 IDirectXFileDataReference *reference;
1452 IDirectXFileBinary *binary;
1453
1454 if (SUCCEEDED(IDirectXFileObject_QueryInterface(child,
1455 &IID_IDirectXFileBinary, (void **)&binary)))
1456 {
1457 FIXME("Binary Object not supported yet\n");
1458 IDirectXFileBinary_Release(binary);
1459 }
1460 else if (SUCCEEDED(IDirectXFileObject_QueryInterface(child,
1461 &IID_IDirectXFileData, (void **)&data)))
1462 {
1463 TRACE("Found Data Object\n");
1464 hr = load_data(iface, data, GUIDs, nb_GUIDs, LoadProc, ArgLP, LoadTextureProc, ArgLTP, frame);
1465 IDirectXFileData_Release(data);
1466 }
1467 else if (SUCCEEDED(IDirectXFileObject_QueryInterface(child,
1468 &IID_IDirectXFileDataReference, (void **)&reference)))
1469 {
1470 TRACE("Found Data Object Reference\n");
1471 IDirectXFileDataReference_Resolve(reference, &data);
1472 hr = load_data(iface, data, GUIDs, nb_GUIDs, LoadProc, ArgLP, LoadTextureProc, ArgLTP, frame);
1473 IDirectXFileData_Release(data);
1474 IDirectXFileDataReference_Release(reference);
1475 }
1476 IDirectXFileObject_Release(child);
1477 }
1478
1479 if (hr != DXFILEERR_NOMOREOBJECTS)
1480 {
1481 IDirect3DRMFrame3_Release(frame);
1482 goto end;
1483 }
1484 hr = S_OK;
1485
1486 /* Only top level objects are notified */
1487 if (!parent_frame)
1488 {
1489 IDirect3DRMObject *object;
1490
1491 hr = IDirect3DRMFrame3_QueryInterface(frame, GUIDs[i], (void**)&object);
1492 if (SUCCEEDED(hr))
1493 {
1494 LoadProc(object, GUIDs[i], ArgLP);
1495 IDirect3DRMObject_Release(object);
1496 }
1497 }
1498 IDirect3DRMFrame3_Release(frame);
1499 }
1500
1501 if (FAILED(hr))
1502 ERR("Cannot process frame\n");
1503 }
1504 }
1505 else if (IsEqualGUID(guid, &TID_D3DRMMaterial))
1506 {
1507 TRACE("Found TID_D3DRMMaterial\n");
1508
1509 /* Cannot be requested so nothing to do */
1510 }
1511 else if (IsEqualGUID(guid, &TID_D3DRMFrameTransformMatrix))
1512 {
1513 TRACE("Found TID_D3DRMFrameTransformMatrix\n");
1514
1515 /* Cannot be requested */
1516 if (parent_frame)
1517 {
1518 D3DRMMATRIX4D *matrix;
1519 DWORD size;
1520
1521 TRACE("Load Frame Transform Matrix data\n");
1522
1523 hr = IDirectXFileData_GetData(data_object, NULL, &size, (void**)&matrix);
1524 if ((hr != DXFILE_OK) || (size != sizeof(matrix)))
1525 goto end;
1526
1527 hr = IDirect3DRMFrame3_AddTransform(parent_frame, D3DRMCOMBINE_REPLACE, *matrix);
1528 if (FAILED(hr))
1529 goto end;
1530 }
1531 }
1532 else
1533 {
1534 FIXME("Found unknown TID %s\n", debugstr_guid(guid));
1535 }
1536
1537 ret = D3DRM_OK;
1538
1539 end:
1540
1541 return ret;
1542 }
1543
1544 static HRESULT WINAPI d3drm3_Load(IDirect3DRM3 *iface, void *source, void *object_id, IID **iids,
1545 DWORD iid_count, D3DRMLOADOPTIONS flags, D3DRMLOADCALLBACK load_cb, void *load_ctx,
1546 D3DRMLOADTEXTURECALLBACK load_tex_cb, void *load_tex_ctx, IDirect3DRMFrame3 *parent_frame)
1547 {
1548 DXFILELOADOPTIONS load_options;
1549 IDirectXFile *file = NULL;
1550 IDirectXFileEnumObject *enum_object = NULL;
1551 IDirectXFileData *data = NULL;
1552 HRESULT hr;
1553 const GUID* pGuid;
1554 DWORD size;
1555 struct d3drm_file_header *header;
1556 HRESULT ret = D3DRMERR_BADOBJECT;
1557 DWORD i;
1558
1559 TRACE("iface %p, source %p, object_id %p, iids %p, iid_count %u, flags %#x, "
1560 "load_cb %p, load_ctx %p, load_tex_cb %p, load_tex_ctx %p, parent_frame %p.\n",
1561 iface, source, object_id, iids, iid_count, flags,
1562 load_cb, load_ctx, load_tex_cb, load_tex_ctx, parent_frame);
1563
1564 TRACE("Looking for GUIDs:\n");
1565 for (i = 0; i < iid_count; ++i)
1566 TRACE("- %s (%s)\n", debugstr_guid(iids[i]), get_IID_string(iids[i]));
1567
1568 if (flags == D3DRMLOAD_FROMMEMORY)
1569 {
1570 load_options = DXFILELOAD_FROMMEMORY;
1571 }
1572 else if (flags == D3DRMLOAD_FROMFILE)
1573 {
1574 load_options = DXFILELOAD_FROMFILE;
1575 TRACE("Loading from file %s\n", debugstr_a(source));
1576 }
1577 else
1578 {
1579 FIXME("Load options %#x not supported yet.\n", flags);
1580 return E_NOTIMPL;
1581 }
1582
1583 hr = DirectXFileCreate(&file);
1584 if (hr != DXFILE_OK)
1585 goto end;
1586
1587 hr = IDirectXFile_RegisterTemplates(file, templates, strlen(templates));
1588 if (hr != DXFILE_OK)
1589 goto end;
1590
1591 hr = IDirectXFile_CreateEnumObject(file, source, load_options, &enum_object);
1592 if (hr != DXFILE_OK)
1593 goto end;
1594
1595 hr = IDirectXFileEnumObject_GetNextDataObject(enum_object, &data);
1596 if (hr != DXFILE_OK)
1597 goto end;
1598
1599 hr = IDirectXFileData_GetType(data, &pGuid);
1600 if (hr != DXFILE_OK)
1601 goto end;
1602
1603 TRACE("Found object type whose GUID = %s\n", debugstr_guid(pGuid));
1604
1605 if (!IsEqualGUID(pGuid, &TID_DXFILEHeader))
1606 {
1607 ret = D3DRMERR_BADFILE;
1608 goto end;
1609 }
1610
1611 hr = IDirectXFileData_GetData(data, NULL, &size, (void **)&header);
1612 if ((hr != DXFILE_OK) || (size != sizeof(*header)))
1613 goto end;
1614
1615 TRACE("Version is %u.%u, flags %#x.\n", header->major, header->minor, header->flags);
1616
1617 /* Version must be 1.0.x */
1618 if ((header->major != 1) || (header->minor != 0))
1619 {
1620 ret = D3DRMERR_BADFILE;
1621 goto end;
1622 }
1623
1624 IDirectXFileData_Release(data);
1625 data = NULL;
1626
1627 while (1)
1628 {
1629 hr = IDirectXFileEnumObject_GetNextDataObject(enum_object, &data);
1630 if (hr == DXFILEERR_NOMOREOBJECTS)
1631 {
1632 TRACE("No more object\n");
1633 break;
1634 }
1635 else if (hr != DXFILE_OK)
1636 {
1637 ret = D3DRMERR_BADFILE;
1638 goto end;
1639 }
1640
1641 ret = load_data(iface, data, iids, iid_count, load_cb, load_ctx, load_tex_cb, load_tex_ctx, parent_frame);
1642 if (ret != D3DRM_OK)
1643 goto end;
1644
1645 IDirectXFileData_Release(data);
1646 data = NULL;
1647 }
1648
1649 ret = D3DRM_OK;
1650
1651 end:
1652 if (data)
1653 IDirectXFileData_Release(data);
1654 if (enum_object)
1655 IDirectXFileEnumObject_Release(enum_object);
1656 if (file)
1657 IDirectXFile_Release(file);
1658
1659 return ret;
1660 }
1661
1662 static HRESULT WINAPI d3drm3_Tick(IDirect3DRM3 *iface, D3DVALUE tick)
1663 {
1664 FIXME("iface %p, tick %.8e stub!\n", iface, tick);
1665
1666 return E_NOTIMPL;
1667 }
1668
1669 static HRESULT WINAPI d3drm3_CreateProgressiveMesh(IDirect3DRM3 *iface, IDirect3DRMProgressiveMesh **mesh)
1670 {
1671 FIXME("iface %p, mesh %p stub!\n", iface, mesh);
1672
1673 return E_NOTIMPL;
1674 }
1675
1676 static HRESULT WINAPI d3drm3_RegisterClient(IDirect3DRM3 *iface, REFGUID guid, DWORD *id)
1677 {
1678 FIXME("iface %p, guid %s, id %p stub!\n", iface, debugstr_guid(guid), id);
1679
1680 return E_NOTIMPL;
1681 }
1682
1683 static HRESULT WINAPI d3drm3_UnregisterClient(IDirect3DRM3 *iface, REFGUID guid)
1684 {
1685 FIXME("iface %p, guid %s stub!\n", iface, debugstr_guid(guid));
1686
1687 return E_NOTIMPL;
1688 }
1689
1690 static HRESULT WINAPI d3drm3_CreateClippedVisual(IDirect3DRM3 *iface,
1691 IDirect3DRMVisual *visual, IDirect3DRMClippedVisual **clipped_visual)
1692 {
1693 FIXME("iface %p, visual %p, clipped_visual %p stub!\n", iface, visual, clipped_visual);
1694
1695 return E_NOTIMPL;
1696 }
1697
1698 static HRESULT WINAPI d3drm3_SetOptions(IDirect3DRM3 *iface, DWORD flags)
1699 {
1700 FIXME("iface %p, flags %#x stub!\n", iface, flags);
1701
1702 return E_NOTIMPL;
1703 }
1704
1705 static HRESULT WINAPI d3drm3_GetOptions(IDirect3DRM3 *iface, DWORD *flags)
1706 {
1707 FIXME("iface %p, flags %p stub!\n", iface, flags);
1708
1709 return E_NOTIMPL;
1710 }
1711
1712 static const struct IDirect3DRM3Vtbl d3drm3_vtbl =
1713 {
1714 d3drm3_QueryInterface,
1715 d3drm3_AddRef,
1716 d3drm3_Release,
1717 d3drm3_CreateObject,
1718 d3drm3_CreateFrame,
1719 d3drm3_CreateMesh,
1720 d3drm3_CreateMeshBuilder,
1721 d3drm3_CreateFace,
1722 d3drm3_CreateAnimation,
1723 d3drm3_CreateAnimationSet,
1724 d3drm3_CreateTexture,
1725 d3drm3_CreateLight,
1726 d3drm3_CreateLightRGB,
1727 d3drm3_CreateMaterial,
1728 d3drm3_CreateDevice,
1729 d3drm3_CreateDeviceFromSurface,
1730 d3drm3_CreateDeviceFromD3D,
1731 d3drm3_CreateDeviceFromClipper,
1732 d3drm3_CreateTextureFromSurface,
1733 d3drm3_CreateShadow,
1734 d3drm3_CreateViewport,
1735 d3drm3_CreateWrap,
1736 d3drm3_CreateUserVisual,
1737 d3drm3_LoadTexture,
1738 d3drm3_LoadTextureFromResource,
1739 d3drm3_SetSearchPath,
1740 d3drm3_AddSearchPath,
1741 d3drm3_GetSearchPath,
1742 d3drm3_SetDefaultTextureColors,
1743 d3drm3_SetDefaultTextureShades,
1744 d3drm3_GetDevices,
1745 d3drm3_GetNamedObject,
1746 d3drm3_EnumerateObjects,
1747 d3drm3_Load,
1748 d3drm3_Tick,
1749 d3drm3_CreateProgressiveMesh,
1750 d3drm3_RegisterClient,
1751 d3drm3_UnregisterClient,
1752 d3drm3_CreateClippedVisual,
1753 d3drm3_SetOptions,
1754 d3drm3_GetOptions,
1755 };
1756
1757 HRESULT WINAPI Direct3DRMCreate(IDirect3DRM **d3drm)
1758 {
1759 struct d3drm *object;
1760
1761 TRACE("d3drm %p.\n", d3drm);
1762
1763 if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
1764 return E_OUTOFMEMORY;
1765
1766 object->IDirect3DRM_iface.lpVtbl = &d3drm1_vtbl;
1767 object->IDirect3DRM2_iface.lpVtbl = &d3drm2_vtbl;
1768 object->IDirect3DRM3_iface.lpVtbl = &d3drm3_vtbl;
1769 object->ref1 = 1;
1770 object->iface_count = 1;
1771
1772 *d3drm = &object->IDirect3DRM_iface;
1773
1774 return S_OK;
1775 }
1776
1777 HRESULT WINAPI DllCanUnloadNow(void)
1778 {
1779 return S_FALSE;
1780 }
1781
1782 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv)
1783 {
1784 TRACE("(%s, %s, %p): stub\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
1785
1786 if(!ppv)
1787 return E_INVALIDARG;
1788
1789 return CLASS_E_CLASSNOTAVAILABLE;
1790 }