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