[AMSTREAM] Sync with Wine Staging 3.9. CORE-14656
[reactos.git] / 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 * Copyright 2016 Aaryaman Vasishta
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 */
22
23 #include "config.h"
24 #include "wine/port.h"
25
26 #include "d3drm_private.h"
27
28 WINE_DEFAULT_DEBUG_CHANNEL(d3drm);
29
30 static const char* get_IID_string(const GUID* guid)
31 {
32 if (IsEqualGUID(guid, &IID_IDirect3DRMFrame))
33 return "IID_IDirect3DRMFrame";
34 else if (IsEqualGUID(guid, &IID_IDirect3DRMFrame2))
35 return "IID_IDirect3DRMFrame2";
36 else if (IsEqualGUID(guid, &IID_IDirect3DRMFrame3))
37 return "IID_IDirect3DRMFrame3";
38 else if (IsEqualGUID(guid, &IID_IDirect3DRMMeshBuilder))
39 return "IID_IDirect3DRMMeshBuilder";
40 else if (IsEqualGUID(guid, &IID_IDirect3DRMMeshBuilder2))
41 return "IID_IDirect3DRMMeshBuilder2";
42 else if (IsEqualGUID(guid, &IID_IDirect3DRMMeshBuilder3))
43 return "IID_IDirect3DRMMeshBuilder3";
44
45 return "?";
46 }
47
48 static HRESULT d3drm_create_texture_object(void **object, IDirect3DRM *d3drm)
49 {
50 struct d3drm_texture *texture;
51 HRESULT hr;
52
53 if (FAILED(hr = d3drm_texture_create(&texture, d3drm)))
54 return hr;
55
56 *object = &texture->IDirect3DRMTexture_iface;
57
58 return hr;
59 }
60
61 static HRESULT d3drm_create_device_object(void **object, IDirect3DRM *d3drm)
62 {
63 struct d3drm_device *device;
64 HRESULT hr;
65
66 if (FAILED(hr = d3drm_device_create(&device, d3drm)))
67 return hr;
68
69 *object = &device->IDirect3DRMDevice_iface;
70
71 return hr;
72 }
73
74 static HRESULT d3drm_create_viewport_object(void **object, IDirect3DRM *d3drm)
75 {
76 struct d3drm_viewport *viewport;
77 HRESULT hr;
78
79 if (FAILED(hr = d3drm_viewport_create(&viewport, d3drm)))
80 return hr;
81
82 *object = &viewport->IDirect3DRMViewport_iface;
83
84 return hr;
85 }
86
87 static HRESULT d3drm_create_face_object(void **object, IDirect3DRM *d3drm)
88 {
89 struct d3drm_face *face;
90 HRESULT hr;
91
92 if (FAILED(hr = d3drm_face_create(&face)))
93 return hr;
94
95 *object = &face->IDirect3DRMFace_iface;
96
97 return hr;
98 }
99
100 static HRESULT d3drm_create_mesh_builder_object(void **object, IDirect3DRM *d3drm)
101 {
102 struct d3drm_mesh_builder *mesh_builder;
103 HRESULT hr;
104
105 if (FAILED(hr = d3drm_mesh_builder_create(&mesh_builder, d3drm)))
106 return hr;
107
108 *object = &mesh_builder->IDirect3DRMMeshBuilder2_iface;
109
110 return hr;
111 }
112
113 static HRESULT d3drm_create_frame_object(void **object, IDirect3DRM *d3drm)
114 {
115 struct d3drm_frame *frame;
116 HRESULT hr;
117
118 if (FAILED(hr = d3drm_frame_create(&frame, NULL, d3drm)))
119 return hr;
120
121 *object = &frame->IDirect3DRMFrame_iface;
122
123 return hr;
124 }
125
126 static HRESULT d3drm_create_light_object(void **object, IDirect3DRM *d3drm)
127 {
128 struct d3drm_light *light;
129 HRESULT hr;
130
131 if (FAILED(hr = d3drm_light_create(&light, d3drm)))
132 return hr;
133
134 *object = &light->IDirect3DRMLight_iface;
135
136 return hr;
137 }
138
139 static HRESULT d3drm_create_material_object(void **object, IDirect3DRM *d3drm)
140 {
141 struct d3drm_material *material;
142 HRESULT hr;
143
144 if (FAILED(hr = d3drm_material_create(&material, d3drm)))
145 return hr;
146
147 *object = &material->IDirect3DRMMaterial2_iface;
148
149 return hr;
150 }
151
152 static HRESULT d3drm_create_mesh_object(void **object, IDirect3DRM *d3drm)
153 {
154 struct d3drm_mesh *mesh;
155 HRESULT hr;
156
157 if (FAILED(hr = d3drm_mesh_create(&mesh, d3drm)))
158 return hr;
159
160 *object = &mesh->IDirect3DRMMesh_iface;
161
162 return hr;
163 }
164
165 static HRESULT d3drm_create_animation_object(void **object, IDirect3DRM *d3drm)
166 {
167 struct d3drm_animation *animation;
168 HRESULT hr;
169
170 if (FAILED(hr = d3drm_animation_create(&animation, d3drm)))
171 return hr;
172
173 *object = &animation->IDirect3DRMAnimation_iface;
174
175 return hr;
176 }
177
178 static HRESULT d3drm_create_wrap_object(void **object, IDirect3DRM *d3drm)
179 {
180 struct d3drm_wrap *wrap;
181 HRESULT hr;
182
183 if (FAILED(hr = d3drm_wrap_create(&wrap, d3drm)))
184 return hr;
185
186 *object = &wrap->IDirect3DRMWrap_iface;
187
188 return hr;
189 }
190
191 struct d3drm
192 {
193 IDirect3DRM IDirect3DRM_iface;
194 IDirect3DRM2 IDirect3DRM2_iface;
195 IDirect3DRM3 IDirect3DRM3_iface;
196 LONG ref1, ref2, ref3, iface_count;
197 };
198
199 static inline struct d3drm *impl_from_IDirect3DRM(IDirect3DRM *iface)
200 {
201 return CONTAINING_RECORD(iface, struct d3drm, IDirect3DRM_iface);
202 }
203
204 static inline struct d3drm *impl_from_IDirect3DRM2(IDirect3DRM2 *iface)
205 {
206 return CONTAINING_RECORD(iface, struct d3drm, IDirect3DRM2_iface);
207 }
208
209 static inline struct d3drm *impl_from_IDirect3DRM3(IDirect3DRM3 *iface)
210 {
211 return CONTAINING_RECORD(iface, struct d3drm, IDirect3DRM3_iface);
212 }
213
214 static void d3drm_destroy(struct d3drm *d3drm)
215 {
216 heap_free(d3drm);
217 TRACE("d3drm object %p is being destroyed.\n", d3drm);
218 }
219
220 static HRESULT WINAPI d3drm1_QueryInterface(IDirect3DRM *iface, REFIID riid, void **out)
221 {
222 struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
223
224 TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
225
226 if (IsEqualGUID(riid, &IID_IDirect3DRM)
227 || IsEqualGUID(riid, &IID_IUnknown))
228 {
229 *out = &d3drm->IDirect3DRM_iface;
230 }
231 else if (IsEqualGUID(riid, &IID_IDirect3DRM2))
232 {
233 *out = &d3drm->IDirect3DRM2_iface;
234 }
235 else if (IsEqualGUID(riid, &IID_IDirect3DRM3))
236 {
237 *out = &d3drm->IDirect3DRM3_iface;
238 }
239 else
240 {
241 *out = NULL;
242 WARN("%s not implemented, returning CLASS_E_CLASSNOTAVAILABLE.\n", debugstr_guid(riid));
243 return CLASS_E_CLASSNOTAVAILABLE;
244 }
245
246 IUnknown_AddRef((IUnknown *)*out);
247 return S_OK;
248 }
249
250 static ULONG WINAPI d3drm1_AddRef(IDirect3DRM *iface)
251 {
252 struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
253 ULONG refcount = InterlockedIncrement(&d3drm->ref1);
254
255 TRACE("%p increasing refcount to %u.\n", iface, refcount);
256
257 if (refcount == 1)
258 InterlockedIncrement(&d3drm->iface_count);
259
260 return refcount;
261 }
262
263 static ULONG WINAPI d3drm1_Release(IDirect3DRM *iface)
264 {
265 struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
266 ULONG refcount = InterlockedDecrement(&d3drm->ref1);
267
268 TRACE("%p decreasing refcount to %u.\n", iface, refcount);
269
270 if (!refcount && !InterlockedDecrement(&d3drm->iface_count))
271 d3drm_destroy(d3drm);
272
273 return refcount;
274 }
275
276 static HRESULT WINAPI d3drm1_CreateObject(IDirect3DRM *iface,
277 REFCLSID clsid, IUnknown *outer, REFIID iid, void **out)
278 {
279 struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
280
281 TRACE("iface %p, clsid %s, outer %p, iid %s, out %p.\n",
282 iface, debugstr_guid(clsid), outer, debugstr_guid(iid), out);
283
284 return IDirect3DRM3_CreateObject(&d3drm->IDirect3DRM3_iface, clsid, outer, iid, out);
285 }
286
287 static HRESULT WINAPI d3drm1_CreateFrame(IDirect3DRM *iface,
288 IDirect3DRMFrame *parent_frame, IDirect3DRMFrame **frame)
289 {
290 struct d3drm_frame *object;
291 HRESULT hr;
292
293 TRACE("iface %p, parent_frame %p, frame %p.\n", iface, parent_frame, frame);
294
295 if (FAILED(hr = d3drm_frame_create(&object, (IUnknown *)parent_frame, iface)))
296 return hr;
297
298 *frame = &object->IDirect3DRMFrame_iface;
299
300 return D3DRM_OK;
301 }
302
303 static HRESULT WINAPI d3drm1_CreateMesh(IDirect3DRM *iface, IDirect3DRMMesh **mesh)
304 {
305 struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
306
307 TRACE("iface %p, mesh %p.\n", iface, mesh);
308
309 return IDirect3DRM3_CreateMesh(&d3drm->IDirect3DRM3_iface, mesh);
310 }
311
312 static HRESULT WINAPI d3drm1_CreateMeshBuilder(IDirect3DRM *iface, IDirect3DRMMeshBuilder **mesh_builder)
313 {
314 struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
315
316 TRACE("iface %p, mesh_builder %p.\n", iface, mesh_builder);
317
318 return IDirect3DRM2_CreateMeshBuilder(&d3drm->IDirect3DRM2_iface, (IDirect3DRMMeshBuilder2 **)mesh_builder);
319 }
320
321 static HRESULT WINAPI d3drm1_CreateFace(IDirect3DRM *iface, IDirect3DRMFace **face)
322 {
323 struct d3drm_face *object;
324 HRESULT hr;
325
326 TRACE("iface %p, face %p.\n", iface, face);
327
328 if (FAILED(hr = d3drm_face_create(&object)))
329 return hr;
330
331 *face = &object->IDirect3DRMFace_iface;
332
333 return S_OK;
334 }
335
336 static HRESULT WINAPI d3drm1_CreateAnimation(IDirect3DRM *iface, IDirect3DRMAnimation **animation)
337 {
338 struct d3drm_animation *object;
339 HRESULT hr;
340
341 TRACE("iface %p, animation %p.\n", iface, animation);
342
343 if (!animation)
344 return D3DRMERR_BADVALUE;
345
346 if (FAILED(hr = d3drm_animation_create(&object, iface)))
347 return hr;
348
349 *animation = &object->IDirect3DRMAnimation_iface;
350
351 return S_OK;
352 }
353
354 static HRESULT WINAPI d3drm1_CreateAnimationSet(IDirect3DRM *iface, IDirect3DRMAnimationSet **set)
355 {
356 FIXME("iface %p, set %p stub!\n", iface, set);
357
358 return E_NOTIMPL;
359 }
360
361 static HRESULT WINAPI d3drm1_CreateTexture(IDirect3DRM *iface,
362 D3DRMIMAGE *image, IDirect3DRMTexture **texture)
363 {
364 struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
365 IDirect3DRMTexture3 *texture3;
366 HRESULT hr;
367
368 TRACE("iface %p, image %p, texture %p.\n", iface, image, texture);
369
370 if (!texture)
371 return D3DRMERR_BADVALUE;
372
373 if (FAILED(hr = IDirect3DRM3_CreateTexture(&d3drm->IDirect3DRM3_iface, image, &texture3)))
374 {
375 *texture = NULL;
376 return hr;
377 }
378
379 hr = IDirect3DRMTexture3_QueryInterface(texture3, &IID_IDirect3DRMTexture, (void **)texture);
380 IDirect3DRMTexture3_Release(texture3);
381
382 return hr;
383 }
384
385 static HRESULT WINAPI d3drm1_CreateLight(IDirect3DRM *iface,
386 D3DRMLIGHTTYPE type, D3DCOLOR color, IDirect3DRMLight **light)
387 {
388 struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
389
390 TRACE("iface %p, type %#x, color 0x%08x, light %p.\n", iface, type, color, light);
391
392 return IDirect3DRM3_CreateLight(&d3drm->IDirect3DRM3_iface, type, color, light);
393 }
394
395 static HRESULT WINAPI d3drm1_CreateLightRGB(IDirect3DRM *iface, D3DRMLIGHTTYPE type,
396 D3DVALUE red, D3DVALUE green, D3DVALUE blue, IDirect3DRMLight **light)
397 {
398 struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
399
400 TRACE("iface %p, type %#x, red %.8e, green %.8e, blue %.8e, light %p.\n",
401 iface, type, red, green, blue, light);
402
403 return IDirect3DRM3_CreateLightRGB(&d3drm->IDirect3DRM3_iface, type, red, green, blue, light);
404 }
405
406 static HRESULT WINAPI d3drm1_CreateMaterial(IDirect3DRM *iface,
407 D3DVALUE power, IDirect3DRMMaterial **material)
408 {
409 struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
410
411 TRACE("iface %p, power %.8e, material %p.\n", iface, power, material);
412
413 return IDirect3DRM3_CreateMaterial(&d3drm->IDirect3DRM3_iface, power, (IDirect3DRMMaterial2 **)material);
414 }
415
416 static HRESULT WINAPI d3drm1_CreateDevice(IDirect3DRM *iface,
417 DWORD width, DWORD height, IDirect3DRMDevice **device)
418 {
419 struct d3drm_device *object;
420 HRESULT hr;
421
422 FIXME("iface %p, width %u, height %u, device %p partial stub!\n", iface, width, height, device);
423
424 if (FAILED(hr = d3drm_device_create(&object, iface)))
425 return hr;
426
427 *device = &object->IDirect3DRMDevice_iface;
428
429 return D3DRM_OK;
430 }
431
432 static HRESULT WINAPI d3drm1_CreateDeviceFromSurface(IDirect3DRM *iface, GUID *guid,
433 IDirectDraw *ddraw, IDirectDrawSurface *backbuffer, IDirect3DRMDevice **device)
434 {
435 struct d3drm_device *object;
436 HRESULT hr;
437
438 TRACE("iface %p, guid %s, ddraw %p, backbuffer %p, device %p.\n",
439 iface, debugstr_guid(guid), ddraw, backbuffer, device);
440
441 if (!device)
442 return D3DRMERR_BADVALUE;
443 *device = NULL;
444
445 if (!backbuffer || !ddraw)
446 return D3DRMERR_BADDEVICE;
447
448 if (FAILED(hr = d3drm_device_create(&object, iface)))
449 return hr;
450
451 if (SUCCEEDED(hr = d3drm_device_init(object, 1, ddraw, backbuffer, TRUE)))
452 *device = &object->IDirect3DRMDevice_iface;
453 else
454 d3drm_device_destroy(object);
455
456 return hr;
457 }
458
459 static HRESULT WINAPI d3drm1_CreateDeviceFromD3D(IDirect3DRM *iface,
460 IDirect3D *d3d, IDirect3DDevice *d3d_device, IDirect3DRMDevice **device)
461 {
462 struct d3drm_device *object;
463 HRESULT hr;
464 TRACE("iface %p, d3d %p, d3d_device %p, device %p.\n",
465 iface, d3d, d3d_device, device);
466
467 if (!device)
468 return D3DRMERR_BADVALUE;
469 *device = NULL;
470
471 if (FAILED(hr = d3drm_device_create(&object, iface)))
472 return hr;
473
474 if (FAILED(hr = IDirect3DRMDevice_InitFromD3D(&object->IDirect3DRMDevice_iface, d3d, d3d_device)))
475 {
476 d3drm_device_destroy(object);
477 return hr;
478 }
479 *device = &object->IDirect3DRMDevice_iface;
480
481 return D3DRM_OK;
482 }
483
484 static HRESULT WINAPI d3drm1_CreateDeviceFromClipper(IDirect3DRM *iface,
485 IDirectDrawClipper *clipper, GUID *guid, int width, int height,
486 IDirect3DRMDevice **device)
487 {
488 struct d3drm_device *object;
489 IDirectDraw *ddraw;
490 IDirectDrawSurface *render_target;
491 HRESULT hr;
492
493 TRACE("iface %p, clipper %p, guid %s, width %d, height %d, device %p.\n",
494 iface, clipper, debugstr_guid(guid), width, height, device);
495
496 if (!device)
497 return D3DRMERR_BADVALUE;
498 *device = NULL;
499
500 if (!clipper || !width || !height)
501 return D3DRMERR_BADVALUE;
502
503 hr = DirectDrawCreate(NULL, &ddraw, NULL);
504 if (FAILED(hr))
505 return hr;
506
507 if (FAILED(hr = d3drm_device_create(&object, iface)))
508 {
509 IDirectDraw_Release(ddraw);
510 return hr;
511 }
512
513 hr = d3drm_device_create_surfaces_from_clipper(object, ddraw, clipper, width, height, &render_target);
514 if (FAILED(hr))
515 {
516 IDirectDraw_Release(ddraw);
517 d3drm_device_destroy(object);
518 return hr;
519 }
520
521 hr = d3drm_device_init(object, 1, ddraw, render_target, TRUE);
522 IDirectDraw_Release(ddraw);
523 IDirectDrawSurface_Release(render_target);
524 if (FAILED(hr))
525 d3drm_device_destroy(object);
526 else
527 *device = &object->IDirect3DRMDevice_iface;
528
529 return hr;
530 }
531
532 static HRESULT WINAPI d3drm1_CreateTextureFromSurface(IDirect3DRM *iface,
533 IDirectDrawSurface *surface, IDirect3DRMTexture **texture)
534 {
535 struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
536 IDirect3DRMTexture3 *texture3;
537 HRESULT hr;
538
539 TRACE("iface %p, surface %p, texture %p.\n", iface, surface, texture);
540
541 if (!texture)
542 return D3DRMERR_BADVALUE;
543
544 if (FAILED(hr = IDirect3DRM3_CreateTextureFromSurface(&d3drm->IDirect3DRM3_iface, surface, &texture3)))
545 {
546 *texture = NULL;
547 return hr;
548 }
549
550 hr = IDirect3DRMTexture3_QueryInterface(texture3, &IID_IDirect3DRMTexture, (void **)texture);
551 IDirect3DRMTexture3_Release(texture3);
552
553 return hr;
554 }
555
556 static HRESULT WINAPI d3drm1_CreateShadow(IDirect3DRM *iface, IDirect3DRMVisual *visual,
557 IDirect3DRMLight *light, D3DVALUE px, D3DVALUE py, D3DVALUE pz, D3DVALUE nx, D3DVALUE ny, D3DVALUE nz,
558 IDirect3DRMVisual **shadow)
559 {
560 FIXME("iface %p, visual %p, light %p, px %.8e, py %.8e, pz %.8e, nx %.8e, ny %.8e, nz %.8e, shadow %p stub!\n",
561 iface, visual, light, px, py, pz, nx, ny, nz, shadow);
562
563 return E_NOTIMPL;
564 }
565
566 static HRESULT WINAPI d3drm1_CreateViewport(IDirect3DRM *iface, IDirect3DRMDevice *device,
567 IDirect3DRMFrame *camera, DWORD x, DWORD y, DWORD width, DWORD height, IDirect3DRMViewport **viewport)
568 {
569 struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
570 IDirect3DRMDevice3 *device3;
571 IDirect3DRMFrame3 *camera3;
572 IDirect3DRMViewport2 *viewport2;
573 HRESULT hr;
574
575 TRACE("iface %p, device %p, camera %p, x %u, y %u, width %u, height %u, viewport %p.\n",
576 iface, device, camera, x, y, width, height, viewport);
577
578 if (!device || !camera)
579 return D3DRMERR_BADOBJECT;
580 if (!viewport)
581 return D3DRMERR_BADVALUE;
582
583 if (FAILED(hr = IDirect3DRMDevice_QueryInterface(device, &IID_IDirect3DRMDevice3, (void **)&device3)))
584 return hr;
585
586 if (FAILED(hr = IDirect3DRMFrame_QueryInterface(camera, &IID_IDirect3DRMFrame3, (void **)&camera3)))
587 {
588 IDirect3DRMDevice3_Release(device3);
589 return hr;
590 }
591
592 hr = IDirect3DRM3_CreateViewport(&d3drm->IDirect3DRM3_iface, device3, camera3, x, y, width, height, &viewport2);
593 IDirect3DRMDevice3_Release(device3);
594 IDirect3DRMFrame3_Release(camera3);
595 if (FAILED(hr))
596 return hr;
597
598 hr = IDirect3DRMViewport2_QueryInterface(viewport2, &IID_IDirect3DRMViewport, (void **)viewport);
599 IDirect3DRMViewport2_Release(viewport2);
600
601 return hr;
602 }
603
604 static HRESULT WINAPI d3drm1_CreateWrap(IDirect3DRM *iface, D3DRMWRAPTYPE type, IDirect3DRMFrame *frame,
605 D3DVALUE ox, D3DVALUE oy, D3DVALUE oz, D3DVALUE dx, D3DVALUE dy, D3DVALUE dz,
606 D3DVALUE ux, D3DVALUE uy, D3DVALUE uz, D3DVALUE ou, D3DVALUE ov, D3DVALUE su, D3DVALUE sv,
607 IDirect3DRMWrap **wrap)
608 {
609 struct d3drm_wrap *object;
610 HRESULT hr;
611
612 FIXME("iface %p, type %#x, frame %p, ox %.8e, oy %.8e, oz %.8e, dx %.8e, dy %.8e, dz %.8e, "
613 "ux %.8e, uy %.8e, uz %.8e, ou %.8e, ov %.8e, su %.8e, sv %.8e, wrap %p, semi-stub.\n",
614 iface, type, frame, ox, oy, oz, dx, dy, dz, ux, uy, uz, ou, ov, su, sv, wrap);
615
616 if (!wrap)
617 return D3DRMERR_BADVALUE;
618
619 if (FAILED(hr = d3drm_wrap_create(&object, iface)))
620 return hr;
621
622 *wrap = &object->IDirect3DRMWrap_iface;
623
624 return S_OK;
625 }
626
627 static HRESULT WINAPI d3drm1_CreateUserVisual(IDirect3DRM *iface,
628 D3DRMUSERVISUALCALLBACK cb, void *ctx, IDirect3DRMUserVisual **visual)
629 {
630 FIXME("iface %p, cb %p, ctx %p visual %p stub!\n", iface, cb, ctx, visual);
631
632 return E_NOTIMPL;
633 }
634
635 static HRESULT WINAPI d3drm1_LoadTexture(IDirect3DRM *iface,
636 const char *filename, IDirect3DRMTexture **texture)
637 {
638 struct d3drm_texture *object;
639 HRESULT hr;
640
641 FIXME("iface %p, filename %s, texture %p stub!\n", iface, debugstr_a(filename), texture);
642
643 if (FAILED(hr = d3drm_texture_create(&object, iface)))
644 return hr;
645
646 *texture = &object->IDirect3DRMTexture_iface;
647
648 return D3DRM_OK;
649 }
650
651 static HRESULT WINAPI d3drm1_LoadTextureFromResource(IDirect3DRM *iface,
652 HRSRC resource, IDirect3DRMTexture **texture)
653 {
654 struct d3drm_texture *object;
655 HRESULT hr;
656
657 FIXME("iface %p, resource %p, texture %p stub!\n", iface, resource, texture);
658
659 if (FAILED(hr = d3drm_texture_create(&object, iface)))
660 return hr;
661
662 *texture = &object->IDirect3DRMTexture_iface;
663
664 return D3DRM_OK;
665 }
666
667 static HRESULT WINAPI d3drm1_SetSearchPath(IDirect3DRM *iface, const char *path)
668 {
669 FIXME("iface %p, path %s stub!\n", iface, debugstr_a(path));
670
671 return E_NOTIMPL;
672 }
673
674 static HRESULT WINAPI d3drm1_AddSearchPath(IDirect3DRM *iface, const char *path)
675 {
676 FIXME("iface %p, path %s stub!\n", iface, debugstr_a(path));
677
678 return E_NOTIMPL;
679 }
680
681 static HRESULT WINAPI d3drm1_GetSearchPath(IDirect3DRM *iface, DWORD *size, char *path)
682 {
683 FIXME("iface %p, size %p, path %p stub!\n", iface, size, path);
684
685 return E_NOTIMPL;
686 }
687
688 static HRESULT WINAPI d3drm1_SetDefaultTextureColors(IDirect3DRM *iface, DWORD color_count)
689 {
690 FIXME("iface %p, color_count %u stub!\n", iface, color_count);
691
692 return E_NOTIMPL;
693 }
694
695 static HRESULT WINAPI d3drm1_SetDefaultTextureShades(IDirect3DRM *iface, DWORD shade_count)
696 {
697 FIXME("iface %p, shade_count %u stub!\n", iface, shade_count);
698
699 return E_NOTIMPL;
700 }
701
702 static HRESULT WINAPI d3drm1_GetDevices(IDirect3DRM *iface, IDirect3DRMDeviceArray **array)
703 {
704 FIXME("iface %p, array %p stub!\n", iface, array);
705
706 return E_NOTIMPL;
707 }
708
709 static HRESULT WINAPI d3drm1_GetNamedObject(IDirect3DRM *iface,
710 const char *name, IDirect3DRMObject **object)
711 {
712 FIXME("iface %p, name %s, object %p stub!\n", iface, debugstr_a(name), object);
713
714 return E_NOTIMPL;
715 }
716
717 static HRESULT WINAPI d3drm1_EnumerateObjects(IDirect3DRM *iface, D3DRMOBJECTCALLBACK cb, void *ctx)
718 {
719 FIXME("iface %p, cb %p, ctx %p stub!\n", iface, cb, ctx);
720
721 return E_NOTIMPL;
722 }
723
724 static HRESULT WINAPI d3drm1_Load(IDirect3DRM *iface, void *source, void *object_id, IID **iids,
725 DWORD iid_count, D3DRMLOADOPTIONS flags, D3DRMLOADCALLBACK load_cb, void *load_ctx,
726 D3DRMLOADTEXTURECALLBACK load_tex_cb, void *load_tex_ctx, IDirect3DRMFrame *parent_frame)
727 {
728 struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
729 IDirect3DRMFrame3 *parent_frame3 = NULL;
730 HRESULT hr = D3DRM_OK;
731
732 TRACE("iface %p, source %p, object_id %p, iids %p, iid_count %u, flags %#x, "
733 "load_cb %p, load_ctx %p, load_tex_cb %p, load_tex_ctx %p, parent_frame %p.\n",
734 iface, source, object_id, iids, iid_count, flags,
735 load_cb, load_ctx, load_tex_cb, load_tex_ctx, parent_frame);
736
737 if (parent_frame)
738 hr = IDirect3DRMFrame_QueryInterface(parent_frame, &IID_IDirect3DRMFrame3, (void **)&parent_frame3);
739 if (SUCCEEDED(hr))
740 hr = IDirect3DRM3_Load(&d3drm->IDirect3DRM3_iface, source, object_id, iids, iid_count,
741 flags, load_cb, load_ctx, load_tex_cb, load_tex_ctx, parent_frame3);
742 if (parent_frame3)
743 IDirect3DRMFrame3_Release(parent_frame3);
744
745 return hr;
746 }
747
748 static HRESULT WINAPI d3drm1_Tick(IDirect3DRM *iface, D3DVALUE tick)
749 {
750 FIXME("iface %p, tick %.8e stub!\n", iface, tick);
751
752 return E_NOTIMPL;
753 }
754
755 static const struct IDirect3DRMVtbl d3drm1_vtbl =
756 {
757 d3drm1_QueryInterface,
758 d3drm1_AddRef,
759 d3drm1_Release,
760 d3drm1_CreateObject,
761 d3drm1_CreateFrame,
762 d3drm1_CreateMesh,
763 d3drm1_CreateMeshBuilder,
764 d3drm1_CreateFace,
765 d3drm1_CreateAnimation,
766 d3drm1_CreateAnimationSet,
767 d3drm1_CreateTexture,
768 d3drm1_CreateLight,
769 d3drm1_CreateLightRGB,
770 d3drm1_CreateMaterial,
771 d3drm1_CreateDevice,
772 d3drm1_CreateDeviceFromSurface,
773 d3drm1_CreateDeviceFromD3D,
774 d3drm1_CreateDeviceFromClipper,
775 d3drm1_CreateTextureFromSurface,
776 d3drm1_CreateShadow,
777 d3drm1_CreateViewport,
778 d3drm1_CreateWrap,
779 d3drm1_CreateUserVisual,
780 d3drm1_LoadTexture,
781 d3drm1_LoadTextureFromResource,
782 d3drm1_SetSearchPath,
783 d3drm1_AddSearchPath,
784 d3drm1_GetSearchPath,
785 d3drm1_SetDefaultTextureColors,
786 d3drm1_SetDefaultTextureShades,
787 d3drm1_GetDevices,
788 d3drm1_GetNamedObject,
789 d3drm1_EnumerateObjects,
790 d3drm1_Load,
791 d3drm1_Tick,
792 };
793
794 static HRESULT WINAPI d3drm2_QueryInterface(IDirect3DRM2 *iface, REFIID riid, void **out)
795 {
796 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
797
798 return d3drm1_QueryInterface(&d3drm->IDirect3DRM_iface, riid, out);
799 }
800
801 static ULONG WINAPI d3drm2_AddRef(IDirect3DRM2 *iface)
802 {
803 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
804 ULONG refcount = InterlockedIncrement(&d3drm->ref2);
805
806 TRACE("%p increasing refcount to %u.\n", iface, refcount);
807
808 if (refcount == 1)
809 InterlockedIncrement(&d3drm->iface_count);
810
811 return refcount;
812 }
813
814 static ULONG WINAPI d3drm2_Release(IDirect3DRM2 *iface)
815 {
816 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
817 ULONG refcount = InterlockedDecrement(&d3drm->ref2);
818
819 TRACE("%p decreasing refcount to %u.\n", iface, refcount);
820
821 if (!refcount && !InterlockedDecrement(&d3drm->iface_count))
822 d3drm_destroy(d3drm);
823
824 return refcount;
825 }
826
827 static HRESULT WINAPI d3drm2_CreateObject(IDirect3DRM2 *iface,
828 REFCLSID clsid, IUnknown *outer, REFIID iid, void **out)
829 {
830 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
831
832 TRACE("iface %p, clsid %s, outer %p, iid %s, out %p.\n",
833 iface, debugstr_guid(clsid), outer, debugstr_guid(iid), out);
834
835 return IDirect3DRM3_CreateObject(&d3drm->IDirect3DRM3_iface, clsid, outer, iid, out);
836 }
837
838 static HRESULT WINAPI d3drm2_CreateFrame(IDirect3DRM2 *iface,
839 IDirect3DRMFrame *parent_frame, IDirect3DRMFrame2 **frame)
840 {
841 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
842 struct d3drm_frame *object;
843 HRESULT hr;
844
845 TRACE("iface %p, parent_frame %p, frame %p.\n", iface, parent_frame, frame);
846
847 if (FAILED(hr = d3drm_frame_create(&object, (IUnknown *)parent_frame, &d3drm->IDirect3DRM_iface)))
848 return hr;
849
850 *frame = &object->IDirect3DRMFrame2_iface;
851
852 return D3DRM_OK;
853 }
854
855 static HRESULT WINAPI d3drm2_CreateMesh(IDirect3DRM2 *iface, IDirect3DRMMesh **mesh)
856 {
857 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
858
859 TRACE("iface %p, mesh %p.\n", iface, mesh);
860
861 return IDirect3DRM3_CreateMesh(&d3drm->IDirect3DRM3_iface, mesh);
862 }
863
864 static HRESULT WINAPI d3drm2_CreateMeshBuilder(IDirect3DRM2 *iface, IDirect3DRMMeshBuilder2 **mesh_builder)
865 {
866 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
867 struct d3drm_mesh_builder *object;
868 HRESULT hr;
869
870 TRACE("iface %p, mesh_builder %p.\n", iface, mesh_builder);
871
872 if (FAILED(hr = d3drm_mesh_builder_create(&object, &d3drm->IDirect3DRM_iface)))
873 return hr;
874
875 *mesh_builder = &object->IDirect3DRMMeshBuilder2_iface;
876
877 return S_OK;
878 }
879
880 static HRESULT WINAPI d3drm2_CreateFace(IDirect3DRM2 *iface, IDirect3DRMFace **face)
881 {
882 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
883
884 TRACE("iface %p, face %p.\n", iface, face);
885
886 return IDirect3DRM_CreateFace(&d3drm->IDirect3DRM_iface, face);
887 }
888
889 static HRESULT WINAPI d3drm2_CreateAnimation(IDirect3DRM2 *iface, IDirect3DRMAnimation **animation)
890 {
891 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
892
893 TRACE("iface %p, animation %p.\n", iface, animation);
894
895 return IDirect3DRM_CreateAnimation(&d3drm->IDirect3DRM_iface, animation);
896 }
897
898 static HRESULT WINAPI d3drm2_CreateAnimationSet(IDirect3DRM2 *iface, IDirect3DRMAnimationSet **set)
899 {
900 FIXME("iface %p, set %p stub!\n", iface, set);
901
902 return E_NOTIMPL;
903 }
904
905 static HRESULT WINAPI d3drm2_CreateTexture(IDirect3DRM2 *iface,
906 D3DRMIMAGE *image, IDirect3DRMTexture2 **texture)
907 {
908 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
909 IDirect3DRMTexture3 *texture3;
910 HRESULT hr;
911
912 TRACE("iface %p, image %p, texture %p.\n", iface, image, texture);
913
914 if (!texture)
915 return D3DRMERR_BADVALUE;
916
917 if (FAILED(hr = IDirect3DRM3_CreateTexture(&d3drm->IDirect3DRM3_iface, image, &texture3)))
918 {
919 *texture = NULL;
920 return hr;
921 }
922
923 hr = IDirect3DRMTexture3_QueryInterface(texture3, &IID_IDirect3DRMTexture2, (void **)texture);
924 IDirect3DRMTexture3_Release(texture3);
925
926 return hr;
927 }
928
929 static HRESULT WINAPI d3drm2_CreateLight(IDirect3DRM2 *iface,
930 D3DRMLIGHTTYPE type, D3DCOLOR color, IDirect3DRMLight **light)
931 {
932 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
933
934 TRACE("iface %p, type %#x, color 0x%08x, light %p.\n", iface, type, color, light);
935
936 return IDirect3DRM3_CreateLight(&d3drm->IDirect3DRM3_iface, type, color, light);
937 }
938
939 static HRESULT WINAPI d3drm2_CreateLightRGB(IDirect3DRM2 *iface, D3DRMLIGHTTYPE type,
940 D3DVALUE red, D3DVALUE green, D3DVALUE blue, IDirect3DRMLight **light)
941 {
942 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
943
944 TRACE("iface %p, type %#x, red %.8e, green %.8e, blue %.8e, light %p.\n",
945 iface, type, red, green, blue, light);
946
947 return IDirect3DRM3_CreateLightRGB(&d3drm->IDirect3DRM3_iface, type, red, green, blue, light);
948 }
949
950 static HRESULT WINAPI d3drm2_CreateMaterial(IDirect3DRM2 *iface,
951 D3DVALUE power, IDirect3DRMMaterial **material)
952 {
953 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
954
955 TRACE("iface %p, power %.8e, material %p.\n", iface, power, material);
956
957 return IDirect3DRM3_CreateMaterial(&d3drm->IDirect3DRM3_iface, power, (IDirect3DRMMaterial2 **)material);
958 }
959
960 static HRESULT WINAPI d3drm2_CreateDevice(IDirect3DRM2 *iface,
961 DWORD width, DWORD height, IDirect3DRMDevice2 **device)
962 {
963 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
964 struct d3drm_device *object;
965 HRESULT hr;
966
967 FIXME("iface %p, width %u, height %u, device %p partial stub!\n", iface, width, height, device);
968
969 if (FAILED(hr = d3drm_device_create(&object, &d3drm->IDirect3DRM_iface)))
970 return hr;
971
972 *device = &object->IDirect3DRMDevice2_iface;
973
974 return D3DRM_OK;
975 }
976
977 static HRESULT WINAPI d3drm2_CreateDeviceFromSurface(IDirect3DRM2 *iface, GUID *guid,
978 IDirectDraw *ddraw, IDirectDrawSurface *backbuffer, IDirect3DRMDevice2 **device)
979 {
980 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
981 IDirect3DRMDevice3 *device3;
982 HRESULT hr;
983 TRACE("iface %p, guid %s, ddraw %p, backbuffer %p, device %p.\n",
984 iface, debugstr_guid(guid), ddraw, backbuffer, device);
985
986 if (!device)
987 return D3DRMERR_BADVALUE;
988 *device = NULL;
989 hr = IDirect3DRM3_CreateDeviceFromSurface(&d3drm->IDirect3DRM3_iface, guid, ddraw, backbuffer, 0, &device3);
990 if (FAILED(hr))
991 return hr;
992
993 hr = IDirect3DRMDevice3_QueryInterface(device3, &IID_IDirect3DRMDevice2, (void**)device);
994 IDirect3DRMDevice3_Release(device3);
995
996 return hr;
997 }
998
999 static HRESULT WINAPI d3drm2_CreateDeviceFromD3D(IDirect3DRM2 *iface,
1000 IDirect3D2 *d3d, IDirect3DDevice2 *d3d_device, IDirect3DRMDevice2 **device)
1001 {
1002 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
1003 IDirect3DRMDevice3 *device3;
1004 HRESULT hr;
1005
1006 TRACE("iface %p, d3d %p, d3d_device %p, device %p.\n",
1007 iface, d3d, d3d_device, device);
1008
1009 if (!device)
1010 return D3DRMERR_BADVALUE;
1011 *device = NULL;
1012
1013 hr = IDirect3DRM3_CreateDeviceFromD3D(&d3drm->IDirect3DRM3_iface, d3d, d3d_device, &device3);
1014 if (FAILED(hr))
1015 return hr;
1016
1017 hr = IDirect3DRMDevice3_QueryInterface(device3, &IID_IDirect3DRMDevice2, (void **)device);
1018 IDirect3DRMDevice3_Release(device3);
1019
1020 return hr;
1021 }
1022
1023 static HRESULT WINAPI d3drm2_CreateDeviceFromClipper(IDirect3DRM2 *iface,
1024 IDirectDrawClipper *clipper, GUID *guid, int width, int height,
1025 IDirect3DRMDevice2 **device)
1026 {
1027 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
1028 IDirect3DRMDevice3 *device3;
1029 HRESULT hr;
1030
1031 TRACE("iface %p, clipper %p, guid %s, width %d, height %d, device %p.\n",
1032 iface, clipper, debugstr_guid(guid), width, height, device);
1033
1034 if (!device)
1035 return D3DRMERR_BADVALUE;
1036 *device = NULL;
1037 hr = IDirect3DRM3_CreateDeviceFromClipper(&d3drm->IDirect3DRM3_iface, clipper, guid, width, height, &device3);
1038 if (FAILED(hr))
1039 return hr;
1040
1041 hr = IDirect3DRMDevice3_QueryInterface(device3, &IID_IDirect3DRMDevice2, (void**)device);
1042 IDirect3DRMDevice3_Release(device3);
1043
1044 return hr;
1045 }
1046
1047 static HRESULT WINAPI d3drm2_CreateTextureFromSurface(IDirect3DRM2 *iface,
1048 IDirectDrawSurface *surface, IDirect3DRMTexture2 **texture)
1049 {
1050 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
1051 IDirect3DRMTexture3 *texture3;
1052 HRESULT hr;
1053
1054 TRACE("iface %p, surface %p, texture %p.\n", iface, surface, texture);
1055
1056 if (!texture)
1057 return D3DRMERR_BADVALUE;
1058
1059 if (FAILED(hr = IDirect3DRM3_CreateTextureFromSurface(&d3drm->IDirect3DRM3_iface, surface, &texture3)))
1060 {
1061 *texture = NULL;
1062 return hr;
1063 }
1064
1065 hr = IDirect3DRMTexture3_QueryInterface(texture3, &IID_IDirect3DRMTexture, (void **)texture);
1066 IDirect3DRMTexture3_Release(texture3);
1067
1068 return hr;
1069 }
1070
1071 static HRESULT WINAPI d3drm2_CreateShadow(IDirect3DRM2 *iface, IDirect3DRMVisual *visual,
1072 IDirect3DRMLight *light, D3DVALUE px, D3DVALUE py, D3DVALUE pz, D3DVALUE nx, D3DVALUE ny, D3DVALUE nz,
1073 IDirect3DRMVisual **shadow)
1074 {
1075 FIXME("iface %p, visual %p, light %p, px %.8e, py %.8e, pz %.8e, nx %.8e, ny %.8e, nz %.8e, shadow %p stub!\n",
1076 iface, visual, light, px, py, pz, nx, ny, nz, shadow);
1077
1078 return E_NOTIMPL;
1079 }
1080
1081 static HRESULT WINAPI d3drm2_CreateViewport(IDirect3DRM2 *iface, IDirect3DRMDevice *device,
1082 IDirect3DRMFrame *camera, DWORD x, DWORD y, DWORD width, DWORD height, IDirect3DRMViewport **viewport)
1083 {
1084 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
1085 IDirect3DRMDevice3 *device3;
1086 IDirect3DRMFrame3 *camera3;
1087 IDirect3DRMViewport2 *viewport2;
1088 HRESULT hr;
1089
1090 TRACE("iface %p, device %p, camera %p, x %u, y %u, width %u, height %u, viewport %p.\n",
1091 iface, device, camera, x, y, width, height, viewport);
1092
1093 if (!device || !camera)
1094 return D3DRMERR_BADOBJECT;
1095 if (!viewport)
1096 return D3DRMERR_BADVALUE;
1097
1098 if (FAILED(hr = IDirect3DRMDevice_QueryInterface(device, &IID_IDirect3DRMDevice3, (void **)&device3)))
1099 return hr;
1100
1101 if (FAILED(hr = IDirect3DRMFrame_QueryInterface(camera, &IID_IDirect3DRMFrame3, (void **)&camera3)))
1102 {
1103 IDirect3DRMDevice3_Release(device3);
1104 return hr;
1105 }
1106
1107 hr = IDirect3DRM3_CreateViewport(&d3drm->IDirect3DRM3_iface, device3, camera3, x, y, width, height, &viewport2);
1108 IDirect3DRMDevice3_Release(device3);
1109 IDirect3DRMFrame3_Release(camera3);
1110 if (FAILED(hr))
1111 return hr;
1112
1113 hr = IDirect3DRMViewport2_QueryInterface(viewport2, &IID_IDirect3DRMViewport, (void **)viewport);
1114 IDirect3DRMViewport2_Release(viewport2);
1115
1116 return hr;
1117 }
1118
1119 static HRESULT WINAPI d3drm2_CreateWrap(IDirect3DRM2 *iface, D3DRMWRAPTYPE type, IDirect3DRMFrame *frame,
1120 D3DVALUE ox, D3DVALUE oy, D3DVALUE oz, D3DVALUE dx, D3DVALUE dy, D3DVALUE dz,
1121 D3DVALUE ux, D3DVALUE uy, D3DVALUE uz, D3DVALUE ou, D3DVALUE ov, D3DVALUE su, D3DVALUE sv,
1122 IDirect3DRMWrap **wrap)
1123 {
1124 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
1125
1126 TRACE("iface %p, type %#x, frame %p, ox %.8e, oy %.8e, oz %.8e, dx %.8e, dy %.8e, dz %.8e, "
1127 "ux %.8e, uy %.8e, uz %.8e, ou %.8e, ov %.8e, su %.8e, sv %.8e, wrap %p.\n",
1128 iface, type, frame, ox, oy, oz, dx, dy, dz, ux, uy, uz, ou, ov, su, sv, wrap);
1129
1130 return IDirect3DRM_CreateWrap(&d3drm->IDirect3DRM_iface, type, frame, ox, oy, oz, dx, dy, dz, ux, uy, uz,
1131 ou, ov, su, sv, wrap);
1132 }
1133
1134 static HRESULT WINAPI d3drm2_CreateUserVisual(IDirect3DRM2 *iface,
1135 D3DRMUSERVISUALCALLBACK cb, void *ctx, IDirect3DRMUserVisual **visual)
1136 {
1137 FIXME("iface %p, cb %p, ctx %p, visual %p stub!\n", iface, cb, ctx, visual);
1138
1139 return E_NOTIMPL;
1140 }
1141
1142 static HRESULT WINAPI d3drm2_LoadTexture(IDirect3DRM2 *iface,
1143 const char *filename, IDirect3DRMTexture2 **texture)
1144 {
1145 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
1146 struct d3drm_texture *object;
1147 HRESULT hr;
1148
1149 FIXME("iface %p, filename %s, texture %p stub!\n", iface, debugstr_a(filename), texture);
1150
1151 if (FAILED(hr = d3drm_texture_create(&object, &d3drm->IDirect3DRM_iface)))
1152 return hr;
1153
1154 *texture = &object->IDirect3DRMTexture2_iface;
1155
1156 return hr;
1157 }
1158
1159 static HRESULT WINAPI d3drm2_LoadTextureFromResource(IDirect3DRM2 *iface, HMODULE module,
1160 const char *resource_name, const char *resource_type, IDirect3DRMTexture2 **texture)
1161 {
1162 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
1163 struct d3drm_texture *object;
1164 HRESULT hr;
1165
1166 FIXME("iface %p, resource_name %s, resource_type %s, texture %p stub!\n",
1167 iface, debugstr_a(resource_name), debugstr_a(resource_type), texture);
1168
1169 if (FAILED(hr = d3drm_texture_create(&object, &d3drm->IDirect3DRM_iface)))
1170 return hr;
1171
1172 *texture = &object->IDirect3DRMTexture2_iface;
1173
1174 return D3DRM_OK;
1175 }
1176
1177 static HRESULT WINAPI d3drm2_SetSearchPath(IDirect3DRM2 *iface, const char *path)
1178 {
1179 FIXME("iface %p, path %s stub!\n", iface, debugstr_a(path));
1180
1181 return E_NOTIMPL;
1182 }
1183
1184 static HRESULT WINAPI d3drm2_AddSearchPath(IDirect3DRM2 *iface, const char *path)
1185 {
1186 FIXME("iface %p, path %s stub!\n", iface, debugstr_a(path));
1187
1188 return E_NOTIMPL;
1189 }
1190
1191 static HRESULT WINAPI d3drm2_GetSearchPath(IDirect3DRM2 *iface, DWORD *size, char *path)
1192 {
1193 FIXME("iface %p, size %p, path %p stub!\n", iface, size, path);
1194
1195 return E_NOTIMPL;
1196 }
1197
1198 static HRESULT WINAPI d3drm2_SetDefaultTextureColors(IDirect3DRM2 *iface, DWORD color_count)
1199 {
1200 FIXME("iface %p, color_count %u stub!\n", iface, color_count);
1201
1202 return E_NOTIMPL;
1203 }
1204
1205 static HRESULT WINAPI d3drm2_SetDefaultTextureShades(IDirect3DRM2 *iface, DWORD shade_count)
1206 {
1207 FIXME("iface %p, shade_count %u stub!\n", iface, shade_count);
1208
1209 return E_NOTIMPL;
1210 }
1211
1212 static HRESULT WINAPI d3drm2_GetDevices(IDirect3DRM2 *iface, IDirect3DRMDeviceArray **array)
1213 {
1214 FIXME("iface %p, array %p stub!\n", iface, array);
1215
1216 return E_NOTIMPL;
1217 }
1218
1219 static HRESULT WINAPI d3drm2_GetNamedObject(IDirect3DRM2 *iface,
1220 const char *name, IDirect3DRMObject **object)
1221 {
1222 FIXME("iface %p, name %s, object %p stub!\n", iface, debugstr_a(name), object);
1223
1224 return E_NOTIMPL;
1225 }
1226
1227 static HRESULT WINAPI d3drm2_EnumerateObjects(IDirect3DRM2 *iface, D3DRMOBJECTCALLBACK cb, void *ctx)
1228 {
1229 FIXME("iface %p, cb %p, ctx %p stub!\n", iface, cb, ctx);
1230
1231 return E_NOTIMPL;
1232 }
1233
1234 static HRESULT WINAPI d3drm2_Load(IDirect3DRM2 *iface, void *source, void *object_id, IID **iids,
1235 DWORD iid_count, D3DRMLOADOPTIONS flags, D3DRMLOADCALLBACK load_cb, void *load_ctx,
1236 D3DRMLOADTEXTURECALLBACK load_tex_cb, void *load_tex_ctx, IDirect3DRMFrame *parent_frame)
1237 {
1238 struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
1239 IDirect3DRMFrame3 *parent_frame3 = NULL;
1240 HRESULT hr = D3DRM_OK;
1241
1242 TRACE("iface %p, source %p, object_id %p, iids %p, iid_count %u, flags %#x, "
1243 "load_cb %p, load_ctx %p, load_tex_cb %p, load_tex_ctx %p, parent_frame %p.\n",
1244 iface, source, object_id, iids, iid_count, flags,
1245 load_cb, load_ctx, load_tex_cb, load_tex_ctx, parent_frame);
1246
1247 if (parent_frame)
1248 hr = IDirect3DRMFrame_QueryInterface(parent_frame, &IID_IDirect3DRMFrame3, (void **)&parent_frame3);
1249 if (SUCCEEDED(hr))
1250 hr = IDirect3DRM3_Load(&d3drm->IDirect3DRM3_iface, source, object_id, iids, iid_count,
1251 flags, load_cb, load_ctx, load_tex_cb, load_tex_ctx, parent_frame3);
1252 if (parent_frame3)
1253 IDirect3DRMFrame3_Release(parent_frame3);
1254
1255 return hr;
1256 }
1257
1258 static HRESULT WINAPI d3drm2_Tick(IDirect3DRM2 *iface, D3DVALUE tick)
1259 {
1260 FIXME("iface %p, tick %.8e stub!\n", iface, tick);
1261
1262 return E_NOTIMPL;
1263 }
1264
1265 static HRESULT WINAPI d3drm2_CreateProgressiveMesh(IDirect3DRM2 *iface, IDirect3DRMProgressiveMesh **mesh)
1266 {
1267 FIXME("iface %p, mesh %p stub!\n", iface, mesh);
1268
1269 return E_NOTIMPL;
1270 }
1271
1272 static const struct IDirect3DRM2Vtbl d3drm2_vtbl =
1273 {
1274 d3drm2_QueryInterface,
1275 d3drm2_AddRef,
1276 d3drm2_Release,
1277 d3drm2_CreateObject,
1278 d3drm2_CreateFrame,
1279 d3drm2_CreateMesh,
1280 d3drm2_CreateMeshBuilder,
1281 d3drm2_CreateFace,
1282 d3drm2_CreateAnimation,
1283 d3drm2_CreateAnimationSet,
1284 d3drm2_CreateTexture,
1285 d3drm2_CreateLight,
1286 d3drm2_CreateLightRGB,
1287 d3drm2_CreateMaterial,
1288 d3drm2_CreateDevice,
1289 d3drm2_CreateDeviceFromSurface,
1290 d3drm2_CreateDeviceFromD3D,
1291 d3drm2_CreateDeviceFromClipper,
1292 d3drm2_CreateTextureFromSurface,
1293 d3drm2_CreateShadow,
1294 d3drm2_CreateViewport,
1295 d3drm2_CreateWrap,
1296 d3drm2_CreateUserVisual,
1297 d3drm2_LoadTexture,
1298 d3drm2_LoadTextureFromResource,
1299 d3drm2_SetSearchPath,
1300 d3drm2_AddSearchPath,
1301 d3drm2_GetSearchPath,
1302 d3drm2_SetDefaultTextureColors,
1303 d3drm2_SetDefaultTextureShades,
1304 d3drm2_GetDevices,
1305 d3drm2_GetNamedObject,
1306 d3drm2_EnumerateObjects,
1307 d3drm2_Load,
1308 d3drm2_Tick,
1309 d3drm2_CreateProgressiveMesh,
1310 };
1311
1312 static HRESULT WINAPI d3drm3_QueryInterface(IDirect3DRM3 *iface, REFIID riid, void **out)
1313 {
1314 struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1315
1316 return d3drm1_QueryInterface(&d3drm->IDirect3DRM_iface, riid, out);
1317 }
1318
1319 static ULONG WINAPI d3drm3_AddRef(IDirect3DRM3 *iface)
1320 {
1321 struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1322 ULONG refcount = InterlockedIncrement(&d3drm->ref3);
1323
1324 TRACE("%p increasing refcount to %u.\n", iface, refcount);
1325
1326 if (refcount == 1)
1327 InterlockedIncrement(&d3drm->iface_count);
1328
1329 return refcount;
1330 }
1331
1332 static ULONG WINAPI d3drm3_Release(IDirect3DRM3 *iface)
1333 {
1334 struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1335 ULONG refcount = InterlockedDecrement(&d3drm->ref3);
1336
1337 TRACE("%p decreasing refcount to %u.\n", iface, refcount);
1338
1339 if (!refcount && !InterlockedDecrement(&d3drm->iface_count))
1340 d3drm_destroy(d3drm);
1341
1342 return refcount;
1343 }
1344
1345 static HRESULT WINAPI d3drm3_CreateObject(IDirect3DRM3 *iface,
1346 REFCLSID clsid, IUnknown *outer, REFIID iid, void **out)
1347 {
1348 struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1349 IUnknown *object;
1350 unsigned int i;
1351 HRESULT hr;
1352
1353 static const struct
1354 {
1355 const CLSID *clsid;
1356 HRESULT (*create_object)(void **object, IDirect3DRM *d3drm);
1357 }
1358 object_table[] =
1359 {
1360 {&CLSID_CDirect3DRMTexture, d3drm_create_texture_object},
1361 {&CLSID_CDirect3DRMDevice, d3drm_create_device_object},
1362 {&CLSID_CDirect3DRMViewport, d3drm_create_viewport_object},
1363 {&CLSID_CDirect3DRMFace, d3drm_create_face_object},
1364 {&CLSID_CDirect3DRMMeshBuilder, d3drm_create_mesh_builder_object},
1365 {&CLSID_CDirect3DRMFrame, d3drm_create_frame_object},
1366 {&CLSID_CDirect3DRMLight, d3drm_create_light_object},
1367 {&CLSID_CDirect3DRMMaterial, d3drm_create_material_object},
1368 {&CLSID_CDirect3DRMMesh, d3drm_create_mesh_object},
1369 {&CLSID_CDirect3DRMAnimation, d3drm_create_animation_object},
1370 {&CLSID_CDirect3DRMWrap, d3drm_create_wrap_object},
1371 };
1372
1373 TRACE("iface %p, clsid %s, outer %p, iid %s, out %p.\n",
1374 iface, debugstr_guid(clsid), outer, debugstr_guid(iid), out);
1375
1376 if (!out)
1377 return D3DRMERR_BADVALUE;
1378
1379 if (!clsid || !iid)
1380 {
1381 *out = NULL;
1382 return D3DRMERR_BADVALUE;
1383 }
1384
1385 if (outer)
1386 {
1387 FIXME("COM aggregation for outer IUnknown (%p) not implemented. Returning E_NOTIMPL.\n", outer);
1388 *out = NULL;
1389 return E_NOTIMPL;
1390 }
1391
1392 for (i = 0; i < ARRAY_SIZE(object_table); ++i)
1393 {
1394 if (IsEqualGUID(clsid, object_table[i].clsid))
1395 {
1396 if (FAILED(hr = object_table[i].create_object((void **)&object, &d3drm->IDirect3DRM_iface)))
1397 {
1398 *out = NULL;
1399 return hr;
1400 }
1401 break;
1402 }
1403 }
1404 if (i == ARRAY_SIZE(object_table))
1405 {
1406 FIXME("%s not implemented. Returning CLASSFACTORY_E_FIRST.\n", debugstr_guid(clsid));
1407 *out = NULL;
1408 return CLASSFACTORY_E_FIRST;
1409 }
1410
1411 if (FAILED(hr = IUnknown_QueryInterface(object, iid, out)))
1412 *out = NULL;
1413 IUnknown_Release(object);
1414
1415 return hr;
1416 }
1417
1418 static HRESULT WINAPI d3drm3_CreateFrame(IDirect3DRM3 *iface,
1419 IDirect3DRMFrame3 *parent, IDirect3DRMFrame3 **frame)
1420 {
1421 struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1422 struct d3drm_frame *object;
1423 HRESULT hr;
1424
1425 TRACE("iface %p, parent %p, frame %p.\n", iface, parent, frame);
1426
1427 if (FAILED(hr = d3drm_frame_create(&object, (IUnknown *)parent, &d3drm->IDirect3DRM_iface)))
1428 return hr;
1429
1430 *frame = &object->IDirect3DRMFrame3_iface;
1431
1432 return D3DRM_OK;
1433 }
1434
1435 static HRESULT WINAPI d3drm3_CreateMesh(IDirect3DRM3 *iface, IDirect3DRMMesh **mesh)
1436 {
1437 struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1438 struct d3drm_mesh *object;
1439 HRESULT hr;
1440
1441 TRACE("iface %p, mesh %p.\n", iface, mesh);
1442
1443 if (FAILED(hr = d3drm_mesh_create(&object, &d3drm->IDirect3DRM_iface)))
1444 return hr;
1445
1446 *mesh = &object->IDirect3DRMMesh_iface;
1447
1448 return S_OK;
1449 }
1450
1451 static HRESULT WINAPI d3drm3_CreateMeshBuilder(IDirect3DRM3 *iface, IDirect3DRMMeshBuilder3 **mesh_builder)
1452 {
1453 struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1454 struct d3drm_mesh_builder *object;
1455 HRESULT hr;
1456
1457 TRACE("iface %p, mesh_builder %p.\n", iface, mesh_builder);
1458
1459 if (FAILED(hr = d3drm_mesh_builder_create(&object, &d3drm->IDirect3DRM_iface)))
1460 return hr;
1461
1462 *mesh_builder = &object->IDirect3DRMMeshBuilder3_iface;
1463
1464 return S_OK;
1465 }
1466
1467 static HRESULT WINAPI d3drm3_CreateFace(IDirect3DRM3 *iface, IDirect3DRMFace2 **face)
1468 {
1469 struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1470 IDirect3DRMFace *face1;
1471 HRESULT hr;
1472
1473 TRACE("iface %p, face %p.\n", iface, face);
1474
1475 if (FAILED(hr = IDirect3DRM_CreateFace(&d3drm->IDirect3DRM_iface, &face1)))
1476 return hr;
1477
1478 hr = IDirect3DRMFace_QueryInterface(face1, &IID_IDirect3DRMFace2, (void **)face);
1479 IDirect3DRMFace_Release(face1);
1480
1481 return hr;
1482 }
1483
1484 static HRESULT WINAPI d3drm3_CreateAnimation(IDirect3DRM3 *iface, IDirect3DRMAnimation2 **animation)
1485 {
1486 struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1487 struct d3drm_animation *object;
1488 HRESULT hr;
1489
1490 TRACE("iface %p, animation %p.\n", iface, animation);
1491
1492 if (FAILED(hr = d3drm_animation_create(&object, &d3drm->IDirect3DRM_iface)))
1493 return hr;
1494
1495 *animation = &object->IDirect3DRMAnimation2_iface;
1496
1497 return hr;
1498 }
1499
1500 static HRESULT WINAPI d3drm3_CreateAnimationSet(IDirect3DRM3 *iface, IDirect3DRMAnimationSet2 **set)
1501 {
1502 FIXME("iface %p, set %p stub!\n", iface, set);
1503
1504 return E_NOTIMPL;
1505 }
1506
1507 static HRESULT WINAPI d3drm3_CreateTexture(IDirect3DRM3 *iface,
1508 D3DRMIMAGE *image, IDirect3DRMTexture3 **texture)
1509 {
1510 struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1511 struct d3drm_texture *object;
1512 HRESULT hr;
1513
1514 TRACE("iface %p, image %p, texture %p.\n", iface, image, texture);
1515
1516 if (!texture)
1517 return D3DRMERR_BADVALUE;
1518
1519 if (FAILED(hr = d3drm_texture_create(&object, &d3drm->IDirect3DRM_iface)))
1520 return hr;
1521
1522 *texture = &object->IDirect3DRMTexture3_iface;
1523
1524 if (FAILED(IDirect3DRMTexture3_InitFromImage(*texture, image)))
1525 {
1526 IDirect3DRMTexture3_Release(*texture);
1527 *texture = NULL;
1528 return D3DRMERR_BADVALUE;
1529 }
1530
1531 return D3DRM_OK;
1532 }
1533
1534 static HRESULT WINAPI d3drm3_CreateLight(IDirect3DRM3 *iface,
1535 D3DRMLIGHTTYPE type, D3DCOLOR color, IDirect3DRMLight **light)
1536 {
1537 struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1538 struct d3drm_light *object;
1539 HRESULT hr;
1540
1541 FIXME("iface %p, type %#x, color 0x%08x, light %p partial stub!\n", iface, type, color, light);
1542
1543 if (SUCCEEDED(hr = d3drm_light_create(&object, &d3drm->IDirect3DRM_iface)))
1544 {
1545 IDirect3DRMLight_SetType(&object->IDirect3DRMLight_iface, type);
1546 IDirect3DRMLight_SetColor(&object->IDirect3DRMLight_iface, color);
1547 }
1548
1549 *light = &object->IDirect3DRMLight_iface;
1550
1551 return hr;
1552 }
1553
1554 static HRESULT WINAPI d3drm3_CreateLightRGB(IDirect3DRM3 *iface, D3DRMLIGHTTYPE type,
1555 D3DVALUE red, D3DVALUE green, D3DVALUE blue, IDirect3DRMLight **light)
1556 {
1557 struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1558 struct d3drm_light *object;
1559 HRESULT hr;
1560
1561 FIXME("iface %p, type %#x, red %.8e, green %.8e, blue %.8e, light %p partial stub!\n",
1562 iface, type, red, green, blue, light);
1563
1564 if (SUCCEEDED(hr = d3drm_light_create(&object, &d3drm->IDirect3DRM_iface)))
1565 {
1566 IDirect3DRMLight_SetType(&object->IDirect3DRMLight_iface, type);
1567 IDirect3DRMLight_SetColorRGB(&object->IDirect3DRMLight_iface, red, green, blue);
1568 }
1569
1570 *light = &object->IDirect3DRMLight_iface;
1571
1572 return hr;
1573 }
1574
1575 static HRESULT WINAPI d3drm3_CreateMaterial(IDirect3DRM3 *iface,
1576 D3DVALUE power, IDirect3DRMMaterial2 **material)
1577 {
1578 struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1579 struct d3drm_material *object;
1580 HRESULT hr;
1581
1582 TRACE("iface %p, power %.8e, material %p.\n", iface, power, material);
1583
1584 if (SUCCEEDED(hr = d3drm_material_create(&object, &d3drm->IDirect3DRM_iface)))
1585 IDirect3DRMMaterial2_SetPower(&object->IDirect3DRMMaterial2_iface, power);
1586
1587 *material = &object->IDirect3DRMMaterial2_iface;
1588
1589 return hr;
1590 }
1591
1592 static HRESULT WINAPI d3drm3_CreateDevice(IDirect3DRM3 *iface,
1593 DWORD width, DWORD height, IDirect3DRMDevice3 **device)
1594 {
1595 struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1596 struct d3drm_device *object;
1597 HRESULT hr;
1598
1599 FIXME("iface %p, width %u, height %u, device %p partial stub!\n", iface, width, height, device);
1600
1601 if (FAILED(hr = d3drm_device_create(&object, &d3drm->IDirect3DRM_iface)))
1602 return hr;
1603
1604 *device = &object->IDirect3DRMDevice3_iface;
1605
1606 return D3DRM_OK;
1607 }
1608
1609 static HRESULT WINAPI d3drm3_CreateDeviceFromSurface(IDirect3DRM3 *iface, GUID *guid,
1610 IDirectDraw *ddraw, IDirectDrawSurface *backbuffer, DWORD flags, IDirect3DRMDevice3 **device)
1611 {
1612 struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1613 struct d3drm_device *object;
1614 BOOL use_z_surface;
1615 HRESULT hr;
1616
1617 TRACE("iface %p, guid %s, ddraw %p, backbuffer %p, flags %#x, device %p.\n",
1618 iface, debugstr_guid(guid), ddraw, backbuffer, flags, device);
1619
1620 if (!device)
1621 return D3DRMERR_BADVALUE;
1622 *device = NULL;
1623
1624 if (!backbuffer || !ddraw)
1625 return D3DRMERR_BADDEVICE;
1626
1627 if (FAILED(hr = d3drm_device_create(&object, &d3drm->IDirect3DRM_iface)))
1628 return hr;
1629
1630 use_z_surface = !(flags & D3DRMDEVICE_NOZBUFFER);
1631
1632 if (SUCCEEDED(hr = d3drm_device_init(object, 3, ddraw, backbuffer, use_z_surface)))
1633 *device = &object->IDirect3DRMDevice3_iface;
1634 else
1635 d3drm_device_destroy(object);
1636
1637 return hr;
1638 }
1639
1640 static HRESULT WINAPI d3drm3_CreateDeviceFromD3D(IDirect3DRM3 *iface,
1641 IDirect3D2 *d3d, IDirect3DDevice2 *d3d_device, IDirect3DRMDevice3 **device)
1642 {
1643 struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1644 struct d3drm_device *object;
1645 HRESULT hr;
1646
1647 TRACE("iface %p, d3d %p, d3d_device %p, device %p.\n",
1648 iface, d3d, d3d_device, device);
1649
1650 if (!device)
1651 return D3DRMERR_BADVALUE;
1652 *device = NULL;
1653
1654 if (FAILED(hr = d3drm_device_create(&object, &d3drm->IDirect3DRM_iface)))
1655 return hr;
1656
1657 if (FAILED(hr = IDirect3DRMDevice3_InitFromD3D2(&object->IDirect3DRMDevice3_iface, d3d, d3d_device)))
1658 {
1659 d3drm_device_destroy(object);
1660 return hr;
1661 }
1662 *device = &object->IDirect3DRMDevice3_iface;
1663
1664 return D3DRM_OK;
1665 }
1666
1667 static HRESULT WINAPI d3drm3_CreateDeviceFromClipper(IDirect3DRM3 *iface,
1668 IDirectDrawClipper *clipper, GUID *guid, int width, int height,
1669 IDirect3DRMDevice3 **device)
1670 {
1671 struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1672 struct d3drm_device *object;
1673 IDirectDraw *ddraw;
1674 IDirectDrawSurface *render_target;
1675 HRESULT hr;
1676
1677 TRACE("iface %p, clipper %p, guid %s, width %d, height %d, device %p.\n",
1678 iface, clipper, debugstr_guid(guid), width, height, device);
1679
1680 if (!device)
1681 return D3DRMERR_BADVALUE;
1682 *device = NULL;
1683
1684 if (!clipper || !width || !height)
1685 return D3DRMERR_BADVALUE;
1686
1687 hr = DirectDrawCreate(NULL, &ddraw, NULL);
1688 if (FAILED(hr))
1689 return hr;
1690
1691 if (FAILED(hr = d3drm_device_create(&object, &d3drm->IDirect3DRM_iface)))
1692 {
1693 IDirectDraw_Release(ddraw);
1694 return hr;
1695 }
1696
1697 hr = d3drm_device_create_surfaces_from_clipper(object, ddraw, clipper, width, height, &render_target);
1698 if (FAILED(hr))
1699 {
1700 IDirectDraw_Release(ddraw);
1701 d3drm_device_destroy(object);
1702 return hr;
1703 }
1704
1705 hr = d3drm_device_init(object, 3, ddraw, render_target, TRUE);
1706 IDirectDraw_Release(ddraw);
1707 IDirectDrawSurface_Release(render_target);
1708 if (FAILED(hr))
1709 d3drm_device_destroy(object);
1710 else
1711 *device = &object->IDirect3DRMDevice3_iface;
1712
1713 return hr;
1714 }
1715
1716 static HRESULT WINAPI d3drm3_CreateShadow(IDirect3DRM3 *iface, IUnknown *object, IDirect3DRMLight *light,
1717 D3DVALUE px, D3DVALUE py, D3DVALUE pz, D3DVALUE nx, D3DVALUE ny, D3DVALUE nz, IDirect3DRMShadow2 **shadow)
1718 {
1719 FIXME("iface %p, object %p, light %p, px %.8e, py %.8e, pz %.8e, nx %.8e, ny %.8e, nz %.8e, shadow %p stub!\n",
1720 iface, object, light, px, py, pz, nx, ny, nz, shadow);
1721
1722 return E_NOTIMPL;
1723 }
1724
1725 static HRESULT WINAPI d3drm3_CreateTextureFromSurface(IDirect3DRM3 *iface,
1726 IDirectDrawSurface *surface, IDirect3DRMTexture3 **texture)
1727 {
1728 struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1729 struct d3drm_texture *object;
1730 HRESULT hr;
1731
1732 TRACE("iface %p, surface %p, texture %p.\n", iface, surface, texture);
1733
1734 if (!texture)
1735 return D3DRMERR_BADVALUE;
1736
1737 if (FAILED(hr = d3drm_texture_create(&object, &d3drm->IDirect3DRM_iface)))
1738 return hr;
1739
1740 *texture = &object->IDirect3DRMTexture3_iface;
1741
1742 if (FAILED(IDirect3DRMTexture3_InitFromSurface(*texture, surface)))
1743 {
1744 IDirect3DRMTexture3_Release(*texture);
1745 *texture = NULL;
1746 return D3DRMERR_BADVALUE;
1747 }
1748
1749 return D3DRM_OK;
1750 }
1751
1752 static HRESULT WINAPI d3drm3_CreateViewport(IDirect3DRM3 *iface, IDirect3DRMDevice3 *device,
1753 IDirect3DRMFrame3 *camera, DWORD x, DWORD y, DWORD width, DWORD height, IDirect3DRMViewport2 **viewport)
1754 {
1755 struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1756 struct d3drm_viewport *object;
1757 HRESULT hr;
1758
1759 TRACE("iface %p, device %p, camera %p, x %u, y %u, width %u, height %u, viewport %p.\n",
1760 iface, device, camera, x, y, width, height, viewport);
1761
1762 if (!device || !camera)
1763 return D3DRMERR_BADOBJECT;
1764 if (!viewport)
1765 return D3DRMERR_BADVALUE;
1766
1767 if (FAILED(hr = d3drm_viewport_create(&object, &d3drm->IDirect3DRM_iface)))
1768 return hr;
1769
1770 *viewport = &object->IDirect3DRMViewport2_iface;
1771
1772 if (FAILED(hr = IDirect3DRMViewport2_Init(*viewport, device, camera, x, y, width, height)))
1773 {
1774 IDirect3DRMViewport2_Release(*viewport);
1775 *viewport = NULL;
1776 return D3DRMERR_BADVALUE;
1777 }
1778
1779 return D3DRM_OK;
1780 }
1781
1782 static HRESULT WINAPI d3drm3_CreateWrap(IDirect3DRM3 *iface, D3DRMWRAPTYPE type, IDirect3DRMFrame3 *frame,
1783 D3DVALUE ox, D3DVALUE oy, D3DVALUE oz, D3DVALUE dx, D3DVALUE dy, D3DVALUE dz,
1784 D3DVALUE ux, D3DVALUE uy, D3DVALUE uz, D3DVALUE ou, D3DVALUE ov, D3DVALUE su, D3DVALUE sv,
1785 IDirect3DRMWrap **wrap)
1786 {
1787 struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1788 struct d3drm_wrap *object;
1789 HRESULT hr;
1790
1791 FIXME("iface %p, type %#x, frame %p, ox %.8e, oy %.8e, oz %.8e, dx %.8e, dy %.8e, dz %.8e, "
1792 "ux %.8e, uy %.8e, uz %.8e, ou %.8e, ov %.8e, su %.8e, sv %.8e, wrap %p, semi-stub.\n",
1793 iface, type, frame, ox, oy, oz, dx, dy, dz, ux, uy, uz, ou, ov, su, sv, wrap);
1794
1795 if (!wrap)
1796 return D3DRMERR_BADVALUE;
1797
1798 if (FAILED(hr = d3drm_wrap_create(&object, &d3drm->IDirect3DRM_iface)))
1799 return hr;
1800
1801 *wrap = &object->IDirect3DRMWrap_iface;
1802
1803 return S_OK;
1804 }
1805
1806 static HRESULT WINAPI d3drm3_CreateUserVisual(IDirect3DRM3 *iface,
1807 D3DRMUSERVISUALCALLBACK cb, void *ctx, IDirect3DRMUserVisual **visual)
1808 {
1809 FIXME("iface %p, cb %p, ctx %p, visual %p stub!\n", iface, cb, ctx, visual);
1810
1811 return E_NOTIMPL;
1812 }
1813
1814 static HRESULT WINAPI d3drm3_LoadTexture(IDirect3DRM3 *iface,
1815 const char *filename, IDirect3DRMTexture3 **texture)
1816 {
1817 struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1818 struct d3drm_texture *object;
1819 HRESULT hr;
1820
1821 FIXME("iface %p, filename %s, texture %p stub!\n", iface, debugstr_a(filename), texture);
1822
1823 if (FAILED(hr = d3drm_texture_create(&object, &d3drm->IDirect3DRM_iface)))
1824 return hr;
1825
1826 *texture = &object->IDirect3DRMTexture3_iface;
1827
1828 return D3DRM_OK;
1829 }
1830
1831 static HRESULT WINAPI d3drm3_LoadTextureFromResource(IDirect3DRM3 *iface, HMODULE module,
1832 const char *resource_name, const char *resource_type, IDirect3DRMTexture3 **texture)
1833 {
1834 struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
1835 struct d3drm_texture *object;
1836 HRESULT hr;
1837
1838 FIXME("iface %p, module %p, resource_name %s, resource_type %s, texture %p stub!\n",
1839 iface, module, debugstr_a(resource_name), debugstr_a(resource_type), texture);
1840
1841 if (FAILED(hr = d3drm_texture_create(&object, &d3drm->IDirect3DRM_iface)))
1842 return hr;
1843
1844 *texture = &object->IDirect3DRMTexture3_iface;
1845
1846 return D3DRM_OK;
1847 }
1848
1849 static HRESULT WINAPI d3drm3_SetSearchPath(IDirect3DRM3 *iface, const char *path)
1850 {
1851 FIXME("iface %p, path %s stub!\n", iface, debugstr_a(path));
1852
1853 return E_NOTIMPL;
1854 }
1855
1856 static HRESULT WINAPI d3drm3_AddSearchPath(IDirect3DRM3 *iface, const char *path)
1857 {
1858 FIXME("iface %p, path %s stub!\n", iface, debugstr_a(path));
1859
1860 return E_NOTIMPL;
1861 }
1862
1863 static HRESULT WINAPI d3drm3_GetSearchPath(IDirect3DRM3 *iface, DWORD *size, char *path)
1864 {
1865 FIXME("iface %p, size %p, path %p stub!\n", iface, size, path);
1866
1867 return E_NOTIMPL;
1868 }
1869
1870 static HRESULT WINAPI d3drm3_SetDefaultTextureColors(IDirect3DRM3 *iface, DWORD color_count)
1871 {
1872 FIXME("iface %p, color_count %u stub!\n", iface, color_count);
1873
1874 return E_NOTIMPL;
1875 }
1876
1877 static HRESULT WINAPI d3drm3_SetDefaultTextureShades(IDirect3DRM3 *iface, DWORD shade_count)
1878 {
1879 FIXME("iface %p, shade_count %u stub!\n", iface, shade_count);
1880
1881 return E_NOTIMPL;
1882 }
1883
1884 static HRESULT WINAPI d3drm3_GetDevices(IDirect3DRM3 *iface, IDirect3DRMDeviceArray **array)
1885 {
1886 FIXME("iface %p, array %p stub!\n", iface, array);
1887
1888 return E_NOTIMPL;
1889 }
1890
1891 static HRESULT WINAPI d3drm3_GetNamedObject(IDirect3DRM3 *iface,
1892 const char *name, IDirect3DRMObject **object)
1893 {
1894 FIXME("iface %p, name %s, object %p stub!\n", iface, debugstr_a(name), object);
1895
1896 return E_NOTIMPL;
1897 }
1898
1899 static HRESULT WINAPI d3drm3_EnumerateObjects(IDirect3DRM3 *iface, D3DRMOBJECTCALLBACK cb, void *ctx)
1900 {
1901 FIXME("iface %p, cb %p, ctx %p stub!\n", iface, cb, ctx);
1902
1903 return E_NOTIMPL;
1904 }
1905
1906 static HRESULT load_data(IDirect3DRM3 *iface, IDirectXFileData *data_object, IID **GUIDs, DWORD nb_GUIDs, D3DRMLOADCALLBACK LoadProc,
1907 void *ArgLP, D3DRMLOADTEXTURECALLBACK LoadTextureProc, void *ArgLTP, IDirect3DRMFrame3 *parent_frame)
1908 {
1909 HRESULT ret = D3DRMERR_BADOBJECT;
1910 HRESULT hr;
1911 const GUID* guid;
1912 DWORD i;
1913 BOOL requested = FALSE;
1914
1915 hr = IDirectXFileData_GetType(data_object, &guid);
1916 if (hr != DXFILE_OK)
1917 goto end;
1918
1919 TRACE("Found object type whose GUID = %s\n", debugstr_guid(guid));
1920
1921 /* Load object only if it is top level and requested or if it is part of another object */
1922
1923 if (IsEqualGUID(guid, &TID_D3DRMMesh))
1924 {
1925 TRACE("Found TID_D3DRMMesh\n");
1926
1927 for (i = 0; i < nb_GUIDs; i++)
1928 if (IsEqualGUID(GUIDs[i], &IID_IDirect3DRMMeshBuilder) ||
1929 IsEqualGUID(GUIDs[i], &IID_IDirect3DRMMeshBuilder2) ||
1930 IsEqualGUID(GUIDs[i], &IID_IDirect3DRMMeshBuilder3))
1931 {
1932 requested = TRUE;
1933 break;
1934 }
1935
1936 if (requested || parent_frame)
1937 {
1938 IDirect3DRMMeshBuilder3 *meshbuilder;
1939
1940 TRACE("Load mesh data\n");
1941
1942 hr = IDirect3DRM3_CreateMeshBuilder(iface, &meshbuilder);
1943 if (SUCCEEDED(hr))
1944 {
1945 hr = load_mesh_data(meshbuilder, data_object, LoadTextureProc, ArgLTP);
1946 if (SUCCEEDED(hr))
1947 {
1948 /* Only top level objects are notified */
1949 if (!parent_frame)
1950 {
1951 IDirect3DRMObject *object;
1952
1953 hr = IDirect3DRMMeshBuilder3_QueryInterface(meshbuilder, GUIDs[i], (void**)&object);
1954 if (SUCCEEDED(hr))
1955 {
1956 LoadProc(object, GUIDs[i], ArgLP);
1957 IDirect3DRMObject_Release(object);
1958 }
1959 }
1960 else
1961 {
1962 IDirect3DRMFrame3_AddVisual(parent_frame, (IUnknown*)meshbuilder);
1963 }
1964 }
1965 IDirect3DRMMeshBuilder3_Release(meshbuilder);
1966 }
1967
1968 if (FAILED(hr))
1969 ERR("Cannot process mesh\n");
1970 }
1971 }
1972 else if (IsEqualGUID(guid, &TID_D3DRMFrame))
1973 {
1974 TRACE("Found TID_D3DRMFrame\n");
1975
1976 for (i = 0; i < nb_GUIDs; i++)
1977 if (IsEqualGUID(GUIDs[i], &IID_IDirect3DRMFrame) ||
1978 IsEqualGUID(GUIDs[i], &IID_IDirect3DRMFrame2) ||
1979 IsEqualGUID(GUIDs[i], &IID_IDirect3DRMFrame3))
1980 {
1981 requested = TRUE;
1982 break;
1983 }
1984
1985 if (requested || parent_frame)
1986 {
1987 IDirect3DRMFrame3 *frame;
1988
1989 TRACE("Load frame data\n");
1990
1991 hr = IDirect3DRM3_CreateFrame(iface, parent_frame, &frame);
1992 if (SUCCEEDED(hr))
1993 {
1994 IDirectXFileObject *child;
1995
1996 while (SUCCEEDED(hr = IDirectXFileData_GetNextObject(data_object, &child)))
1997 {
1998 IDirectXFileData *data;
1999 IDirectXFileDataReference *reference;
2000 IDirectXFileBinary *binary;
2001
2002 if (SUCCEEDED(IDirectXFileObject_QueryInterface(child,
2003 &IID_IDirectXFileBinary, (void **)&binary)))
2004 {
2005 FIXME("Binary Object not supported yet\n");
2006 IDirectXFileBinary_Release(binary);
2007 }
2008 else if (SUCCEEDED(IDirectXFileObject_QueryInterface(child,
2009 &IID_IDirectXFileData, (void **)&data)))
2010 {
2011 TRACE("Found Data Object\n");
2012 hr = load_data(iface, data, GUIDs, nb_GUIDs, LoadProc, ArgLP, LoadTextureProc, ArgLTP, frame);
2013 IDirectXFileData_Release(data);
2014 }
2015 else if (SUCCEEDED(IDirectXFileObject_QueryInterface(child,
2016 &IID_IDirectXFileDataReference, (void **)&reference)))
2017 {
2018 TRACE("Found Data Object Reference\n");
2019 IDirectXFileDataReference_Resolve(reference, &data);
2020 hr = load_data(iface, data, GUIDs, nb_GUIDs, LoadProc, ArgLP, LoadTextureProc, ArgLTP, frame);
2021 IDirectXFileData_Release(data);
2022 IDirectXFileDataReference_Release(reference);
2023 }
2024 IDirectXFileObject_Release(child);
2025 }
2026
2027 if (hr != DXFILEERR_NOMOREOBJECTS)
2028 {
2029 IDirect3DRMFrame3_Release(frame);
2030 goto end;
2031 }
2032 hr = S_OK;
2033
2034 /* Only top level objects are notified */
2035 if (!parent_frame)
2036 {
2037 IDirect3DRMObject *object;
2038
2039 hr = IDirect3DRMFrame3_QueryInterface(frame, GUIDs[i], (void**)&object);
2040 if (SUCCEEDED(hr))
2041 {
2042 LoadProc(object, GUIDs[i], ArgLP);
2043 IDirect3DRMObject_Release(object);
2044 }
2045 }
2046 IDirect3DRMFrame3_Release(frame);
2047 }
2048
2049 if (FAILED(hr))
2050 ERR("Cannot process frame\n");
2051 }
2052 }
2053 else if (IsEqualGUID(guid, &TID_D3DRMMaterial))
2054 {
2055 TRACE("Found TID_D3DRMMaterial\n");
2056
2057 /* Cannot be requested so nothing to do */
2058 }
2059 else if (IsEqualGUID(guid, &TID_D3DRMFrameTransformMatrix))
2060 {
2061 TRACE("Found TID_D3DRMFrameTransformMatrix\n");
2062
2063 /* Cannot be requested */
2064 if (parent_frame)
2065 {
2066 D3DRMMATRIX4D *matrix;
2067 DWORD size;
2068
2069 TRACE("Load Frame Transform Matrix data\n");
2070
2071 hr = IDirectXFileData_GetData(data_object, NULL, &size, (void**)&matrix);
2072 if ((hr != DXFILE_OK) || (size != sizeof(matrix)))
2073 goto end;
2074
2075 hr = IDirect3DRMFrame3_AddTransform(parent_frame, D3DRMCOMBINE_REPLACE, *matrix);
2076 if (FAILED(hr))
2077 goto end;
2078 }
2079 }
2080 else
2081 {
2082 FIXME("Found unknown TID %s\n", debugstr_guid(guid));
2083 }
2084
2085 ret = D3DRM_OK;
2086
2087 end:
2088
2089 return ret;
2090 }
2091
2092 static HRESULT WINAPI d3drm3_Load(IDirect3DRM3 *iface, void *source, void *object_id, IID **iids,
2093 DWORD iid_count, D3DRMLOADOPTIONS flags, D3DRMLOADCALLBACK load_cb, void *load_ctx,
2094 D3DRMLOADTEXTURECALLBACK load_tex_cb, void *load_tex_ctx, IDirect3DRMFrame3 *parent_frame)
2095 {
2096 DXFILELOADOPTIONS load_options;
2097 IDirectXFile *file = NULL;
2098 IDirectXFileEnumObject *enum_object = NULL;
2099 IDirectXFileData *data = NULL;
2100 HRESULT hr;
2101 const GUID* pGuid;
2102 DWORD size;
2103 struct d3drm_file_header *header;
2104 HRESULT ret = D3DRMERR_BADOBJECT;
2105 DWORD i;
2106
2107 TRACE("iface %p, source %p, object_id %p, iids %p, iid_count %u, flags %#x, "
2108 "load_cb %p, load_ctx %p, load_tex_cb %p, load_tex_ctx %p, parent_frame %p.\n",
2109 iface, source, object_id, iids, iid_count, flags,
2110 load_cb, load_ctx, load_tex_cb, load_tex_ctx, parent_frame);
2111
2112 TRACE("Looking for GUIDs:\n");
2113 for (i = 0; i < iid_count; ++i)
2114 TRACE("- %s (%s)\n", debugstr_guid(iids[i]), get_IID_string(iids[i]));
2115
2116 if (flags == D3DRMLOAD_FROMMEMORY)
2117 {
2118 load_options = DXFILELOAD_FROMMEMORY;
2119 }
2120 else if (flags == D3DRMLOAD_FROMFILE)
2121 {
2122 load_options = DXFILELOAD_FROMFILE;
2123 TRACE("Loading from file %s\n", debugstr_a(source));
2124 }
2125 else
2126 {
2127 FIXME("Load options %#x not supported yet.\n", flags);
2128 return E_NOTIMPL;
2129 }
2130
2131 hr = DirectXFileCreate(&file);
2132 if (hr != DXFILE_OK)
2133 goto end;
2134
2135 hr = IDirectXFile_RegisterTemplates(file, templates, strlen(templates));
2136 if (hr != DXFILE_OK)
2137 goto end;
2138
2139 hr = IDirectXFile_CreateEnumObject(file, source, load_options, &enum_object);
2140 if (hr != DXFILE_OK)
2141 goto end;
2142
2143 hr = IDirectXFileEnumObject_GetNextDataObject(enum_object, &data);
2144 if (hr != DXFILE_OK)
2145 goto end;
2146
2147 hr = IDirectXFileData_GetType(data, &pGuid);
2148 if (hr != DXFILE_OK)
2149 goto end;
2150
2151 TRACE("Found object type whose GUID = %s\n", debugstr_guid(pGuid));
2152
2153 if (!IsEqualGUID(pGuid, &TID_DXFILEHeader))
2154 {
2155 ret = D3DRMERR_BADFILE;
2156 goto end;
2157 }
2158
2159 hr = IDirectXFileData_GetData(data, NULL, &size, (void **)&header);
2160 if ((hr != DXFILE_OK) || (size != sizeof(*header)))
2161 goto end;
2162
2163 TRACE("Version is %u.%u, flags %#x.\n", header->major, header->minor, header->flags);
2164
2165 /* Version must be 1.0.x */
2166 if ((header->major != 1) || (header->minor != 0))
2167 {
2168 ret = D3DRMERR_BADFILE;
2169 goto end;
2170 }
2171
2172 IDirectXFileData_Release(data);
2173 data = NULL;
2174
2175 while (1)
2176 {
2177 hr = IDirectXFileEnumObject_GetNextDataObject(enum_object, &data);
2178 if (hr == DXFILEERR_NOMOREOBJECTS)
2179 {
2180 TRACE("No more object\n");
2181 break;
2182 }
2183 else if (hr != DXFILE_OK)
2184 {
2185 ret = D3DRMERR_BADFILE;
2186 goto end;
2187 }
2188
2189 ret = load_data(iface, data, iids, iid_count, load_cb, load_ctx, load_tex_cb, load_tex_ctx, parent_frame);
2190 if (ret != D3DRM_OK)
2191 goto end;
2192
2193 IDirectXFileData_Release(data);
2194 data = NULL;
2195 }
2196
2197 ret = D3DRM_OK;
2198
2199 end:
2200 if (data)
2201 IDirectXFileData_Release(data);
2202 if (enum_object)
2203 IDirectXFileEnumObject_Release(enum_object);
2204 if (file)
2205 IDirectXFile_Release(file);
2206
2207 return ret;
2208 }
2209
2210 static HRESULT WINAPI d3drm3_Tick(IDirect3DRM3 *iface, D3DVALUE tick)
2211 {
2212 FIXME("iface %p, tick %.8e stub!\n", iface, tick);
2213
2214 return E_NOTIMPL;
2215 }
2216
2217 static HRESULT WINAPI d3drm3_CreateProgressiveMesh(IDirect3DRM3 *iface, IDirect3DRMProgressiveMesh **mesh)
2218 {
2219 FIXME("iface %p, mesh %p stub!\n", iface, mesh);
2220
2221 return E_NOTIMPL;
2222 }
2223
2224 static HRESULT WINAPI d3drm3_RegisterClient(IDirect3DRM3 *iface, REFGUID guid, DWORD *id)
2225 {
2226 FIXME("iface %p, guid %s, id %p stub!\n", iface, debugstr_guid(guid), id);
2227
2228 return E_NOTIMPL;
2229 }
2230
2231 static HRESULT WINAPI d3drm3_UnregisterClient(IDirect3DRM3 *iface, REFGUID guid)
2232 {
2233 FIXME("iface %p, guid %s stub!\n", iface, debugstr_guid(guid));
2234
2235 return E_NOTIMPL;
2236 }
2237
2238 static HRESULT WINAPI d3drm3_CreateClippedVisual(IDirect3DRM3 *iface,
2239 IDirect3DRMVisual *visual, IDirect3DRMClippedVisual **clipped_visual)
2240 {
2241 FIXME("iface %p, visual %p, clipped_visual %p stub!\n", iface, visual, clipped_visual);
2242
2243 return E_NOTIMPL;
2244 }
2245
2246 static HRESULT WINAPI d3drm3_SetOptions(IDirect3DRM3 *iface, DWORD flags)
2247 {
2248 FIXME("iface %p, flags %#x stub!\n", iface, flags);
2249
2250 return E_NOTIMPL;
2251 }
2252
2253 static HRESULT WINAPI d3drm3_GetOptions(IDirect3DRM3 *iface, DWORD *flags)
2254 {
2255 FIXME("iface %p, flags %p stub!\n", iface, flags);
2256
2257 return E_NOTIMPL;
2258 }
2259
2260 static const struct IDirect3DRM3Vtbl d3drm3_vtbl =
2261 {
2262 d3drm3_QueryInterface,
2263 d3drm3_AddRef,
2264 d3drm3_Release,
2265 d3drm3_CreateObject,
2266 d3drm3_CreateFrame,
2267 d3drm3_CreateMesh,
2268 d3drm3_CreateMeshBuilder,
2269 d3drm3_CreateFace,
2270 d3drm3_CreateAnimation,
2271 d3drm3_CreateAnimationSet,
2272 d3drm3_CreateTexture,
2273 d3drm3_CreateLight,
2274 d3drm3_CreateLightRGB,
2275 d3drm3_CreateMaterial,
2276 d3drm3_CreateDevice,
2277 d3drm3_CreateDeviceFromSurface,
2278 d3drm3_CreateDeviceFromD3D,
2279 d3drm3_CreateDeviceFromClipper,
2280 d3drm3_CreateTextureFromSurface,
2281 d3drm3_CreateShadow,
2282 d3drm3_CreateViewport,
2283 d3drm3_CreateWrap,
2284 d3drm3_CreateUserVisual,
2285 d3drm3_LoadTexture,
2286 d3drm3_LoadTextureFromResource,
2287 d3drm3_SetSearchPath,
2288 d3drm3_AddSearchPath,
2289 d3drm3_GetSearchPath,
2290 d3drm3_SetDefaultTextureColors,
2291 d3drm3_SetDefaultTextureShades,
2292 d3drm3_GetDevices,
2293 d3drm3_GetNamedObject,
2294 d3drm3_EnumerateObjects,
2295 d3drm3_Load,
2296 d3drm3_Tick,
2297 d3drm3_CreateProgressiveMesh,
2298 d3drm3_RegisterClient,
2299 d3drm3_UnregisterClient,
2300 d3drm3_CreateClippedVisual,
2301 d3drm3_SetOptions,
2302 d3drm3_GetOptions,
2303 };
2304
2305 HRESULT WINAPI Direct3DRMCreate(IDirect3DRM **d3drm)
2306 {
2307 struct d3drm *object;
2308
2309 TRACE("d3drm %p.\n", d3drm);
2310
2311 if (!(object = heap_alloc_zero(sizeof(*object))))
2312 return E_OUTOFMEMORY;
2313
2314 object->IDirect3DRM_iface.lpVtbl = &d3drm1_vtbl;
2315 object->IDirect3DRM2_iface.lpVtbl = &d3drm2_vtbl;
2316 object->IDirect3DRM3_iface.lpVtbl = &d3drm3_vtbl;
2317 object->ref1 = 1;
2318 object->iface_count = 1;
2319
2320 *d3drm = &object->IDirect3DRM_iface;
2321
2322 return S_OK;
2323 }
2324
2325 HRESULT WINAPI DllCanUnloadNow(void)
2326 {
2327 return S_FALSE;
2328 }
2329
2330 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv)
2331 {
2332 TRACE("(%s, %s, %p): stub\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
2333
2334 if(!ppv)
2335 return E_INVALIDARG;
2336
2337 return CLASS_E_CLASSNOTAVAILABLE;
2338 }