xref: /reactos/dll/directx/wine/d3drm/viewport.c (revision c2c66aff)
1 /*
2  * Implementation of IDirect3DRMViewport Interface
3  *
4  * Copyright 2012 André Hentschel
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 
21 #include "d3drm_private.h"
22 
23 static inline struct d3drm_viewport *impl_from_IDirect3DRMViewport(IDirect3DRMViewport *iface)
24 {
25     return CONTAINING_RECORD(iface, struct d3drm_viewport, IDirect3DRMViewport_iface);
26 }
27 
28 static inline struct d3drm_viewport *impl_from_IDirect3DRMViewport2(IDirect3DRMViewport2 *iface)
29 {
30     return CONTAINING_RECORD(iface, struct d3drm_viewport, IDirect3DRMViewport2_iface);
31 }
32 
33 static inline void d3drm_normalize_d3d_color(D3DCOLORVALUE *color_value, D3DCOLOR color)
34 {
35     color_value->u1.r = RGBA_GETRED(color) / 255.0f;
36     color_value->u2.g = RGBA_GETGREEN(color) / 255.0f;
37     color_value->u3.b = RGBA_GETBLUE(color) / 255.0f;
38     color_value->u4.a = RGBA_GETALPHA(color) / 255.0f;
39 }
40 
41 static HRESULT d3drm_update_background_material(struct d3drm_viewport *viewport)
42 {
43     IDirect3DRMFrame *root_frame;
44     D3DCOLOR color;
45     D3DMATERIAL mat;
46     HRESULT hr;
47 
48     if (FAILED(hr = IDirect3DRMFrame_GetScene(viewport->camera, &root_frame)))
49         return hr;
50     color = IDirect3DRMFrame_GetSceneBackground(root_frame);
51 
52     memset(&mat, 0, sizeof(mat));
53     mat.dwSize = sizeof(mat);
54     d3drm_normalize_d3d_color(&mat.u.diffuse, color);
55 
56     return IDirect3DMaterial_SetMaterial(viewport->material, &mat);
57 }
58 
59 static void d3drm_viewport_destroy(struct d3drm_viewport *viewport)
60 {
61     TRACE("viewport %p releasing attached interfaces.\n", viewport);
62 
63     d3drm_object_cleanup((IDirect3DRMObject *)&viewport->IDirect3DRMViewport_iface, &viewport->obj);
64 
65     if (viewport->d3d_viewport)
66     {
67         IDirect3DViewport_Release(viewport->d3d_viewport);
68         IDirect3DMaterial_Release(viewport->material);
69         IDirect3DRMFrame_Release(viewport->camera);
70         IDirect3DRM_Release(viewport->d3drm);
71     }
72 
73     HeapFree(GetProcessHeap(), 0, viewport);
74 }
75 
76 static HRESULT WINAPI d3drm_viewport2_QueryInterface(IDirect3DRMViewport2 *iface, REFIID riid, void **out)
77 {
78     struct d3drm_viewport *viewport = impl_from_IDirect3DRMViewport2(iface);
79 
80     TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
81 
82     if (IsEqualGUID(riid, &IID_IDirect3DRMViewport)
83             || IsEqualGUID(riid, &IID_IDirect3DRMObject)
84             || IsEqualGUID(riid, &IID_IUnknown))
85     {
86         *out = &viewport->IDirect3DRMViewport_iface;
87     }
88     else if (IsEqualGUID(riid, &IID_IDirect3DRMViewport2))
89     {
90         *out = &viewport->IDirect3DRMViewport2_iface;
91     }
92     else
93     {
94         *out = NULL;
95         WARN("%s not implemented, returning CLASS_E_CLASSNOTAVAILABLE.\n", debugstr_guid(riid));
96         return CLASS_E_CLASSNOTAVAILABLE;
97     }
98 
99     IUnknown_AddRef((IUnknown *)*out);
100     return S_OK;
101 }
102 
103 static HRESULT WINAPI d3drm_viewport1_QueryInterface(IDirect3DRMViewport *iface, REFIID riid, void **out)
104 {
105     struct d3drm_viewport *viewport = impl_from_IDirect3DRMViewport(iface);
106 
107     TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
108 
109     return d3drm_viewport2_QueryInterface(&viewport->IDirect3DRMViewport2_iface, riid, out);
110 }
111 
112 static ULONG WINAPI d3drm_viewport2_AddRef(IDirect3DRMViewport2 *iface)
113 {
114     struct d3drm_viewport *viewport = impl_from_IDirect3DRMViewport2(iface);
115     ULONG refcount = InterlockedIncrement(&viewport->obj.ref);
116 
117     TRACE("%p increasing refcount to %u.\n", iface, refcount);
118 
119     return refcount;
120 }
121 
122 static ULONG WINAPI d3drm_viewport1_AddRef(IDirect3DRMViewport *iface)
123 {
124     struct d3drm_viewport *viewport = impl_from_IDirect3DRMViewport(iface);
125 
126     TRACE("iface %p.\n", iface);
127 
128     return d3drm_viewport2_AddRef(&viewport->IDirect3DRMViewport2_iface);
129 }
130 
131 static ULONG WINAPI d3drm_viewport2_Release(IDirect3DRMViewport2 *iface)
132 {
133     struct d3drm_viewport *viewport = impl_from_IDirect3DRMViewport2(iface);
134     ULONG refcount = InterlockedDecrement(&viewport->obj.ref);
135 
136     TRACE("%p decreasing refcount to %u.\n", iface, refcount);
137 
138     if (!refcount)
139         d3drm_viewport_destroy(viewport);
140 
141     return refcount;
142 }
143 
144 static ULONG WINAPI d3drm_viewport1_Release(IDirect3DRMViewport *iface)
145 {
146     struct d3drm_viewport *viewport = impl_from_IDirect3DRMViewport(iface);
147 
148     TRACE("iface %p.\n", iface);
149 
150     return d3drm_viewport2_Release(&viewport->IDirect3DRMViewport2_iface);
151 }
152 
153 static HRESULT WINAPI d3drm_viewport2_Clone(IDirect3DRMViewport2 *iface,
154         IUnknown *outer, REFIID iid, void **out)
155 {
156     FIXME("iface %p, outer %p, iid %s, out %p stub!\n", iface, outer, debugstr_guid(iid), out);
157 
158     return E_NOTIMPL;
159 }
160 
161 static HRESULT WINAPI d3drm_viewport1_Clone(IDirect3DRMViewport *iface,
162         IUnknown *outer, REFIID iid, void **out)
163 {
164     FIXME("iface %p, outer %p, iid %s, out %p stub!\n", iface, outer, debugstr_guid(iid), out);
165 
166     return E_NOTIMPL;
167 }
168 
169 static HRESULT WINAPI d3drm_viewport2_AddDestroyCallback(IDirect3DRMViewport2 *iface,
170         D3DRMOBJECTCALLBACK cb, void *ctx)
171 {
172     struct d3drm_viewport *viewport = impl_from_IDirect3DRMViewport2(iface);
173 
174     TRACE("iface %p, cb %p, ctx %p\n", iface, cb, ctx);
175 
176     return d3drm_object_add_destroy_callback(&viewport->obj, cb, ctx);
177 }
178 
179 static HRESULT WINAPI d3drm_viewport1_AddDestroyCallback(IDirect3DRMViewport *iface,
180         D3DRMOBJECTCALLBACK cb, void *ctx)
181 {
182     struct d3drm_viewport *viewport = impl_from_IDirect3DRMViewport(iface);
183 
184     TRACE("iface %p, cb %p, ctx %p\n", iface, cb, ctx);
185 
186     return d3drm_viewport2_AddDestroyCallback(&viewport->IDirect3DRMViewport2_iface, cb, ctx);
187 }
188 
189 static HRESULT WINAPI d3drm_viewport2_DeleteDestroyCallback(IDirect3DRMViewport2 *iface,
190         D3DRMOBJECTCALLBACK cb, void *ctx)
191 {
192     struct d3drm_viewport *viewport = impl_from_IDirect3DRMViewport2(iface);
193 
194     TRACE("iface %p, cb %p, ctx %p\n", iface, cb, ctx);
195 
196     return d3drm_object_delete_destroy_callback(&viewport->obj, cb, ctx);
197 }
198 
199 static HRESULT WINAPI d3drm_viewport1_DeleteDestroyCallback(IDirect3DRMViewport *iface,
200         D3DRMOBJECTCALLBACK cb, void *ctx)
201 {
202     struct d3drm_viewport *viewport = impl_from_IDirect3DRMViewport(iface);
203 
204     TRACE("iface %p, cb %p, ctx %p\n", iface, cb, ctx);
205 
206     return d3drm_viewport2_DeleteDestroyCallback(&viewport->IDirect3DRMViewport2_iface, cb, ctx);
207 }
208 
209 static HRESULT WINAPI d3drm_viewport2_SetAppData(IDirect3DRMViewport2 *iface, DWORD data)
210 {
211     struct d3drm_viewport *viewport = impl_from_IDirect3DRMViewport2(iface);
212 
213     TRACE("iface %p, data %#x\n", iface, data);
214 
215     viewport->obj.appdata = data;
216     return S_OK;
217 }
218 
219 static HRESULT WINAPI d3drm_viewport1_SetAppData(IDirect3DRMViewport *iface, DWORD data)
220 {
221     struct d3drm_viewport *viewport = impl_from_IDirect3DRMViewport(iface);
222 
223     TRACE("iface %p, data %#x\n", iface, data);
224 
225     return d3drm_viewport2_SetAppData(&viewport->IDirect3DRMViewport2_iface, data);
226 }
227 
228 static DWORD WINAPI d3drm_viewport2_GetAppData(IDirect3DRMViewport2 *iface)
229 {
230     struct d3drm_viewport *viewport = impl_from_IDirect3DRMViewport2(iface);
231 
232     TRACE("iface %p\n", iface);
233 
234     return viewport->obj.appdata;
235 }
236 
237 static DWORD WINAPI d3drm_viewport1_GetAppData(IDirect3DRMViewport *iface)
238 {
239     struct d3drm_viewport *viewport = impl_from_IDirect3DRMViewport(iface);
240 
241     TRACE("iface %p.\n", iface);
242 
243     return d3drm_viewport2_GetAppData(&viewport->IDirect3DRMViewport2_iface);
244 }
245 
246 static HRESULT WINAPI d3drm_viewport2_SetName(IDirect3DRMViewport2 *iface, const char *name)
247 {
248     struct d3drm_viewport *viewport = impl_from_IDirect3DRMViewport2(iface);
249 
250     TRACE("iface %p, name %s.\n", iface, debugstr_a(name));
251 
252     return d3drm_object_set_name(&viewport->obj, name);
253 }
254 
255 static HRESULT WINAPI d3drm_viewport1_SetName(IDirect3DRMViewport *iface, const char *name)
256 {
257     struct d3drm_viewport *viewport = impl_from_IDirect3DRMViewport(iface);
258 
259     TRACE("iface %p, name %s.\n", iface, debugstr_a(name));
260 
261     return d3drm_viewport2_SetName(&viewport->IDirect3DRMViewport2_iface, name);
262 }
263 
264 static HRESULT WINAPI d3drm_viewport2_GetName(IDirect3DRMViewport2 *iface, DWORD *size, char *name)
265 {
266     struct d3drm_viewport *viewport = impl_from_IDirect3DRMViewport2(iface);
267 
268     TRACE("iface %p, size %p, name %p.\n", iface, size, name);
269 
270     return d3drm_object_get_name(&viewport->obj, size, name);
271 }
272 
273 static HRESULT WINAPI d3drm_viewport1_GetName(IDirect3DRMViewport *iface, DWORD *size, char *name)
274 {
275     struct d3drm_viewport *viewport = impl_from_IDirect3DRMViewport(iface);
276 
277     TRACE("iface %p, size %p, name %p.\n", iface, size, name);
278 
279     return d3drm_viewport2_GetName(&viewport->IDirect3DRMViewport2_iface, size, name);
280 }
281 
282 static HRESULT WINAPI d3drm_viewport2_GetClassName(IDirect3DRMViewport2 *iface, DWORD *size, char *name)
283 {
284     struct d3drm_viewport *viewport = impl_from_IDirect3DRMViewport2(iface);
285 
286     TRACE("iface %p, size %p, name %p.\n", iface, size, name);
287 
288     return d3drm_object_get_class_name(&viewport->obj, size, name);
289 }
290 
291 static HRESULT WINAPI d3drm_viewport1_GetClassName(IDirect3DRMViewport *iface, DWORD *size, char *name)
292 {
293     struct d3drm_viewport *viewport = impl_from_IDirect3DRMViewport(iface);
294 
295     TRACE("iface %p, size %p, name %p.\n", iface, size, name);
296 
297     return d3drm_viewport2_GetClassName(&viewport->IDirect3DRMViewport2_iface, size, name);
298 }
299 
300 static HRESULT WINAPI d3drm_viewport2_Init(IDirect3DRMViewport2 *iface, IDirect3DRMDevice3 *device,
301         IDirect3DRMFrame3 *camera, DWORD x, DWORD y, DWORD width, DWORD height)
302 {
303     struct d3drm_viewport *viewport = impl_from_IDirect3DRMViewport2(iface);
304     struct d3drm_device *device_obj = unsafe_impl_from_IDirect3DRMDevice3(device);
305     D3DVIEWPORT vp;
306     D3DVALUE scale;
307     IDirect3D *d3d1 = NULL;
308     IDirect3DDevice *d3d_device = NULL;
309     IDirect3DMaterial *material = NULL;
310     D3DMATERIALHANDLE hmat;
311     HRESULT hr = D3DRM_OK;
312 
313     TRACE("iface %p, device %p, camera %p, x %u, y %u, width %u, height %u.\n",
314             iface, device, camera, x, y, width, height);
315 
316     if (!device_obj || !camera
317             || width > device_obj->width
318             || height > device_obj->height)
319     {
320         return D3DRMERR_BADOBJECT;
321     }
322 
323     if (viewport->d3d_viewport)
324         return D3DRMERR_BADOBJECT;
325 
326     IDirect3DRM_AddRef(viewport->d3drm);
327 
328     if (FAILED(hr = IDirect3DRMDevice3_GetDirect3DDevice(device, &d3d_device)))
329         goto cleanup;
330 
331     if (FAILED(hr = IDirect3DDevice_GetDirect3D(d3d_device, &d3d1)))
332         goto cleanup;
333 
334     if (FAILED(hr = IDirect3D_CreateViewport(d3d1, &viewport->d3d_viewport, NULL)))
335         goto cleanup;
336 
337     vp.dwSize = sizeof(vp);
338     vp.dwWidth = width;
339     vp.dwHeight = height;
340     vp.dwX = x;
341     vp.dwY = y;
342     scale = width > height ? (float)width / 2.0f : (float)height / 2.0f;
343     vp.dvScaleX = scale;
344     vp.dvScaleY = scale;
345     vp.dvMaxX = vp.dwWidth / (2.0f * vp.dvScaleX);
346     vp.dvMaxY = vp.dwHeight / (2.0f * vp.dvScaleY);
347     vp.dvMinZ = 0.0f;
348     vp.dvMaxZ = 1.0f;
349 
350     if (FAILED(hr = IDirect3DViewport_SetViewport(viewport->d3d_viewport, &vp)))
351         goto cleanup;
352 
353     if (FAILED(hr = IDirect3DDevice_AddViewport(d3d_device, viewport->d3d_viewport)))
354         goto cleanup;
355 
356     if (FAILED(hr = IDirect3DRMFrame3_QueryInterface(camera, &IID_IDirect3DRMFrame, (void **)&viewport->camera)))
357         goto cleanup;
358 
359     if (FAILED(hr = IDirect3D_CreateMaterial(d3d1, &material, NULL)))
360         goto cleanup;
361 
362     if (FAILED(hr = IDirect3DMaterial_GetHandle(material, d3d_device, &hmat)))
363         goto cleanup;
364 
365     hr = IDirect3DViewport_SetBackground(viewport->d3d_viewport, hmat);
366     viewport->material = material;
367     viewport->device = device_obj;
368 
369 cleanup:
370 
371     if (FAILED(hr))
372     {
373         if (viewport->d3d_viewport)
374         {
375             IDirect3DViewport_Release(viewport->d3d_viewport);
376             viewport->d3d_viewport = NULL;
377         }
378         if (viewport->camera)
379             IDirect3DRMFrame_Release(viewport->camera);
380         if (material)
381             IDirect3DMaterial_Release(material);
382         IDirect3DRM_Release(viewport->d3drm);
383     }
384     if (d3d_device)
385         IDirect3DDevice_Release(d3d_device);
386     if (d3d1)
387         IDirect3D_Release(d3d1);
388 
389     return hr;
390 }
391 
392 static HRESULT WINAPI d3drm_viewport1_Init(IDirect3DRMViewport *iface, IDirect3DRMDevice *device,
393         IDirect3DRMFrame *camera, DWORD x, DWORD y, DWORD width, DWORD height)
394 {
395     struct d3drm_viewport *viewport = impl_from_IDirect3DRMViewport(iface);
396     struct d3drm_frame *frame = unsafe_impl_from_IDirect3DRMFrame(camera);
397     IDirect3DRMDevice3 *device3;
398     HRESULT hr;
399 
400     TRACE("iface %p, device %p, camera %p, x %u, y %u, width %u, height %u.\n",
401           iface, device, camera, x, y, width, height);
402 
403     if (!device || !frame)
404         return D3DRMERR_BADOBJECT;
405 
406     if (FAILED(hr = IDirect3DRMDevice_QueryInterface(device, &IID_IDirect3DRMDevice3, (void **)&device3)))
407         return hr;
408 
409     hr = d3drm_viewport2_Init(&viewport->IDirect3DRMViewport2_iface, device3, &frame->IDirect3DRMFrame3_iface,
410             x, y, width, height);
411     IDirect3DRMDevice3_Release(device3);
412 
413     return hr;
414 }
415 
416 static HRESULT WINAPI d3drm_viewport2_Clear(IDirect3DRMViewport2 *iface, DWORD flags)
417 {
418     struct d3drm_viewport *viewport = impl_from_IDirect3DRMViewport2(iface);
419     DDSCAPS caps = { DDSCAPS_ZBUFFER };
420     HRESULT hr;
421     D3DRECT clear_rect;
422     IDirectDrawSurface *ds;
423     DWORD clear_flags = 0;
424 
425     TRACE("iface %p, flags %#x.\n", iface, flags);
426 
427     clear_rect.u1.x1 = clear_rect.u2.y1 = 0;
428     clear_rect.u3.x2 = viewport->device->width;
429     clear_rect.u4.y2 = viewport->device->height;
430 
431     if (flags & D3DRMCLEAR_TARGET)
432     {
433         clear_flags |= D3DCLEAR_TARGET;
434         d3drm_update_background_material(viewport);
435     }
436     if (flags & D3DRMCLEAR_ZBUFFER)
437     {
438         hr = IDirectDrawSurface_GetAttachedSurface(viewport->device->render_target, &caps, &ds);
439         if (SUCCEEDED(hr))
440         {
441             clear_flags |= D3DCLEAR_ZBUFFER;
442             IDirectDrawSurface_Release(ds);
443         }
444     }
445     if (flags & D3DRMCLEAR_DIRTYRECTS)
446         FIXME("Flag D3DRMCLEAR_DIRTYRECT not implemented yet.\n");
447 
448     if (FAILED(hr = IDirect3DViewport_Clear(viewport->d3d_viewport, 1, &clear_rect, clear_flags)))
449         return hr;
450 
451     return D3DRM_OK;
452 }
453 
454 static HRESULT WINAPI d3drm_viewport1_Clear(IDirect3DRMViewport *iface)
455 {
456     struct d3drm_viewport *viewport = impl_from_IDirect3DRMViewport(iface);
457 
458     TRACE("iface %p.\n", iface);
459 
460     return d3drm_viewport2_Clear(&viewport->IDirect3DRMViewport2_iface, D3DRMCLEAR_ALL);
461 }
462 
463 static HRESULT WINAPI d3drm_viewport2_Render(IDirect3DRMViewport2 *iface, IDirect3DRMFrame3 *frame)
464 {
465     FIXME("iface %p, frame %p stub!\n", iface, frame);
466 
467     return D3DRM_OK;
468 }
469 
470 static HRESULT WINAPI d3drm_viewport1_Render(IDirect3DRMViewport *iface, IDirect3DRMFrame *frame)
471 {
472     FIXME("iface %p, frame %p stub!\n", iface, frame);
473 
474     return D3DRM_OK;
475 }
476 
477 static HRESULT WINAPI d3drm_viewport2_SetFront(IDirect3DRMViewport2 *iface, D3DVALUE front)
478 {
479     struct d3drm_viewport *viewport = impl_from_IDirect3DRMViewport2(iface);
480 
481     TRACE("iface %p, front %.8e.\n", iface, front);
482 
483     viewport->front = front;
484 
485     return D3DRM_OK;
486 }
487 
488 static HRESULT WINAPI d3drm_viewport1_SetFront(IDirect3DRMViewport *iface, D3DVALUE front)
489 {
490     struct d3drm_viewport *viewport = impl_from_IDirect3DRMViewport(iface);
491 
492     TRACE("iface %p, front %.8e.\n", iface, front);
493 
494     return d3drm_viewport2_SetFront(&viewport->IDirect3DRMViewport2_iface, front);
495 }
496 
497 static HRESULT WINAPI d3drm_viewport2_SetBack(IDirect3DRMViewport2 *iface, D3DVALUE back)
498 {
499     struct d3drm_viewport *viewport = impl_from_IDirect3DRMViewport2(iface);
500 
501     TRACE("iface %p, back %.8e.\n", iface, back);
502 
503     viewport->back = back;
504 
505     return D3DRM_OK;
506 }
507 
508 static HRESULT WINAPI d3drm_viewport1_SetBack(IDirect3DRMViewport *iface, D3DVALUE back)
509 {
510     struct d3drm_viewport *viewport = impl_from_IDirect3DRMViewport(iface);
511 
512     TRACE("iface %p, back %.8e.\n", iface, back);
513 
514     return d3drm_viewport2_SetBack(&viewport->IDirect3DRMViewport2_iface, back);
515 }
516 
517 static HRESULT WINAPI d3drm_viewport2_SetField(IDirect3DRMViewport2 *iface, D3DVALUE field)
518 {
519     struct d3drm_viewport *viewport = impl_from_IDirect3DRMViewport2(iface);
520 
521     TRACE("iface %p, field %.8e.\n", iface, field);
522 
523     viewport->field = field;
524 
525     return D3DRM_OK;
526 }
527 
528 static HRESULT WINAPI d3drm_viewport1_SetField(IDirect3DRMViewport *iface, D3DVALUE field)
529 {
530     struct d3drm_viewport *viewport = impl_from_IDirect3DRMViewport(iface);
531 
532     TRACE("iface %p, field %.8e.\n", iface, field);
533 
534     return d3drm_viewport2_SetField(&viewport->IDirect3DRMViewport2_iface, field);
535 }
536 
537 static HRESULT WINAPI d3drm_viewport2_SetUniformScaling(IDirect3DRMViewport2 *iface, BOOL b)
538 {
539     FIXME("iface %p, b %#x stub!\n", iface, b);
540 
541     return E_NOTIMPL;
542 }
543 
544 static HRESULT WINAPI d3drm_viewport1_SetUniformScaling(IDirect3DRMViewport *iface, BOOL b)
545 {
546     FIXME("iface %p, b %#x stub!\n", iface, b);
547 
548     return E_NOTIMPL;
549 }
550 
551 static HRESULT WINAPI d3drm_viewport2_SetCamera(IDirect3DRMViewport2 *iface, IDirect3DRMFrame3 *camera)
552 {
553     FIXME("iface %p, camera %p stub!\n", iface, camera);
554 
555     return E_NOTIMPL;
556 }
557 
558 static HRESULT WINAPI d3drm_viewport1_SetCamera(IDirect3DRMViewport *iface, IDirect3DRMFrame *camera)
559 {
560     FIXME("iface %p, camera %p stub!\n", iface, camera);
561 
562     return E_NOTIMPL;
563 }
564 
565 static HRESULT WINAPI d3drm_viewport2_SetProjection(IDirect3DRMViewport2 *iface, D3DRMPROJECTIONTYPE type)
566 {
567     struct d3drm_viewport *viewport = impl_from_IDirect3DRMViewport2(iface);
568 
569     TRACE("iface %p, type %#x.\n", iface, type);
570 
571     viewport->projection = type;
572 
573     return D3DRM_OK;
574 }
575 
576 static HRESULT WINAPI d3drm_viewport1_SetProjection(IDirect3DRMViewport *iface, D3DRMPROJECTIONTYPE type)
577 {
578     struct d3drm_viewport *viewport = impl_from_IDirect3DRMViewport(iface);
579 
580     TRACE("iface %p, type %#x.\n", iface, type);
581 
582     return d3drm_viewport2_SetProjection(&viewport->IDirect3DRMViewport2_iface, type);
583 }
584 
585 static HRESULT WINAPI d3drm_viewport2_Transform(IDirect3DRMViewport2 *iface, D3DRMVECTOR4D *d, D3DVECTOR *s)
586 {
587     FIXME("iface %p, d %p, s %p stub!\n", iface, d, s);
588 
589     return E_NOTIMPL;
590 }
591 
592 static HRESULT WINAPI d3drm_viewport1_Transform(IDirect3DRMViewport *iface, D3DRMVECTOR4D *d, D3DVECTOR *s)
593 {
594     FIXME("iface %p, d %p, s %p stub!\n", iface, d, s);
595 
596     return E_NOTIMPL;
597 }
598 
599 static HRESULT WINAPI d3drm_viewport2_InverseTransform(IDirect3DRMViewport2 *iface, D3DVECTOR *d, D3DRMVECTOR4D *s)
600 {
601     FIXME("iface %p, d %p, s %p stub!\n", iface, d, s);
602 
603     return E_NOTIMPL;
604 }
605 
606 static HRESULT WINAPI d3drm_viewport1_InverseTransform(IDirect3DRMViewport *iface, D3DVECTOR *d, D3DRMVECTOR4D *s)
607 {
608     FIXME("iface %p, d %p, s %p stub!\n", iface, d, s);
609 
610     return E_NOTIMPL;
611 }
612 
613 static HRESULT WINAPI d3drm_viewport2_Configure(IDirect3DRMViewport2 *iface,
614         LONG x, LONG y, DWORD width, DWORD height)
615 {
616     FIXME("iface %p, x %d, y %d, width %u, height %u stub!\n", iface, x, y, width, height);
617 
618     return E_NOTIMPL;
619 }
620 
621 static HRESULT WINAPI d3drm_viewport1_Configure(IDirect3DRMViewport *iface,
622         LONG x, LONG y, DWORD width, DWORD height)
623 {
624     FIXME("iface %p, x %d, y %d, width %u, height %u stub!\n", iface, x, y, width, height);
625 
626     return E_NOTIMPL;
627 }
628 
629 static HRESULT WINAPI d3drm_viewport2_ForceUpdate(IDirect3DRMViewport2* iface,
630         DWORD x1, DWORD y1, DWORD x2, DWORD y2)
631 {
632     FIXME("iface %p, x1 %u, y1 %u, x2 %u, y2 %u stub!\n", iface, x1, y1, x2, y2);
633 
634     return E_NOTIMPL;
635 }
636 
637 static HRESULT WINAPI d3drm_viewport1_ForceUpdate(IDirect3DRMViewport *iface,
638         DWORD x1, DWORD y1, DWORD x2, DWORD y2)
639 {
640     FIXME("iface %p, x1 %u, y1 %u, x2 %u, y2 %u stub!\n", iface, x1, y1, x2, y2);
641 
642     return E_NOTIMPL;
643 }
644 
645 static HRESULT WINAPI d3drm_viewport2_SetPlane(IDirect3DRMViewport2 *iface,
646         D3DVALUE left, D3DVALUE right, D3DVALUE bottom, D3DVALUE top)
647 {
648     FIXME("iface %p, left %.8e, right %.8e, bottom %.8e, top %.8e stub!\n",
649             iface, left, right, bottom, top);
650 
651     return E_NOTIMPL;
652 }
653 
654 static HRESULT WINAPI d3drm_viewport1_SetPlane(IDirect3DRMViewport *iface,
655         D3DVALUE left, D3DVALUE right, D3DVALUE bottom, D3DVALUE top)
656 {
657     FIXME("iface %p, left %.8e, right %.8e, bottom %.8e, top %.8e stub!\n",
658             iface, left, right, bottom, top);
659 
660     return E_NOTIMPL;
661 }
662 
663 static HRESULT WINAPI d3drm_viewport2_GetCamera(IDirect3DRMViewport2 *iface, IDirect3DRMFrame3 **camera)
664 {
665     FIXME("iface %p, camera %p stub!\n", iface, camera);
666 
667     return E_NOTIMPL;
668 }
669 
670 static HRESULT WINAPI d3drm_viewport1_GetCamera(IDirect3DRMViewport *iface, IDirect3DRMFrame **camera)
671 {
672     FIXME("iface %p, camera %p stub!\n", iface, camera);
673 
674     return E_NOTIMPL;
675 }
676 
677 static HRESULT WINAPI d3drm_viewport2_GetDevice(IDirect3DRMViewport2 *iface, IDirect3DRMDevice3 **device)
678 {
679     struct d3drm_viewport *viewport = impl_from_IDirect3DRMViewport2(iface);
680 
681     TRACE("iface %p, device %p.\n", iface, device);
682 
683     if (!viewport->device)
684         return D3DRMERR_BADOBJECT;
685 
686     *device = &viewport->device->IDirect3DRMDevice3_iface;
687     IDirect3DRMDevice3_AddRef(*device);
688 
689     return D3DRM_OK;
690 }
691 
692 static HRESULT WINAPI d3drm_viewport1_GetDevice(IDirect3DRMViewport *iface, IDirect3DRMDevice **device)
693 {
694     struct d3drm_viewport *viewport = impl_from_IDirect3DRMViewport(iface);
695 
696     TRACE("iface %p, device %p.\n\n", iface, device);
697 
698     if (!viewport->device)
699         return D3DRMERR_BADOBJECT;
700 
701     *device = &viewport->device->IDirect3DRMDevice_iface;
702     IDirect3DRMDevice_AddRef(*device);
703 
704     return D3DRM_OK;
705 }
706 
707 static HRESULT WINAPI d3drm_viewport2_GetPlane(IDirect3DRMViewport2 *iface,
708         D3DVALUE *left, D3DVALUE *right, D3DVALUE *bottom, D3DVALUE *top)
709 {
710     FIXME("iface %p, left %p, right %p, bottom %p, top %p stub!\n",
711             iface, left, right, bottom, top);
712 
713     return E_NOTIMPL;
714 }
715 
716 static HRESULT WINAPI d3drm_viewport1_GetPlane(IDirect3DRMViewport *iface,
717         D3DVALUE *left, D3DVALUE *right, D3DVALUE *bottom, D3DVALUE *top)
718 {
719     FIXME("iface %p, left %p, right %p, bottom %p, top %p stub!\n",
720             iface, left, right, bottom, top);
721 
722     return E_NOTIMPL;
723 }
724 
725 static HRESULT WINAPI d3drm_viewport2_Pick(IDirect3DRMViewport2 *iface,
726         LONG x, LONG y, IDirect3DRMPickedArray **visuals)
727 {
728     FIXME("iface %p, x %d, y %d, visuals %p stub!\n", iface, x, y, visuals);
729 
730     return E_NOTIMPL;
731 }
732 
733 static HRESULT WINAPI d3drm_viewport1_Pick(IDirect3DRMViewport *iface,
734         LONG x, LONG y, IDirect3DRMPickedArray **visuals)
735 {
736     FIXME("iface %p, x %d, y %d, visuals %p stub!\n", iface, x, y, visuals);
737 
738     return E_NOTIMPL;
739 }
740 
741 static BOOL WINAPI d3drm_viewport2_GetUniformScaling(IDirect3DRMViewport2 *iface)
742 {
743     FIXME("iface %p stub!\n", iface);
744 
745     return FALSE;
746 }
747 
748 static BOOL WINAPI d3drm_viewport1_GetUniformScaling(IDirect3DRMViewport *iface)
749 {
750     FIXME("iface %p stub!\n", iface);
751 
752     return FALSE;
753 }
754 
755 static LONG WINAPI d3drm_viewport2_GetX(IDirect3DRMViewport2 *iface)
756 {
757     FIXME("iface %p stub!\n", iface);
758 
759     return E_NOTIMPL;
760 }
761 
762 static LONG WINAPI d3drm_viewport1_GetX(IDirect3DRMViewport *iface)
763 {
764     FIXME("iface %p stub!\n", iface);
765 
766     return E_NOTIMPL;
767 }
768 
769 static LONG WINAPI d3drm_viewport2_GetY(IDirect3DRMViewport2 *iface)
770 {
771     FIXME("iface %p stub!\n", iface);
772 
773     return E_NOTIMPL;
774 }
775 
776 static LONG WINAPI d3drm_viewport1_GetY(IDirect3DRMViewport *iface)
777 {
778     FIXME("iface %p stub!\n", iface);
779 
780     return E_NOTIMPL;
781 }
782 
783 static DWORD WINAPI d3drm_viewport2_GetWidth(IDirect3DRMViewport2 *iface)
784 {
785     FIXME("iface %p stub!\n", iface);
786 
787     return E_NOTIMPL;
788 }
789 
790 static DWORD WINAPI d3drm_viewport1_GetWidth(IDirect3DRMViewport *iface)
791 {
792     FIXME("iface %p stub!\n", iface);
793 
794     return E_NOTIMPL;
795 }
796 
797 static DWORD WINAPI d3drm_viewport2_GetHeight(IDirect3DRMViewport2 *iface)
798 {
799     FIXME("iface %p stub!\n", iface);
800 
801     return E_NOTIMPL;
802 }
803 
804 static DWORD WINAPI d3drm_viewport1_GetHeight(IDirect3DRMViewport *iface)
805 {
806     FIXME("iface %p stub!\n", iface);
807 
808     return E_NOTIMPL;
809 }
810 
811 static D3DVALUE WINAPI d3drm_viewport2_GetField(IDirect3DRMViewport2 *iface)
812 {
813     struct d3drm_viewport *viewport = impl_from_IDirect3DRMViewport2(iface);
814 
815     TRACE("iface %p.\n", iface);
816 
817     return viewport->field;
818 }
819 
820 static D3DVALUE WINAPI d3drm_viewport1_GetField(IDirect3DRMViewport *iface)
821 {
822     struct d3drm_viewport *viewport = impl_from_IDirect3DRMViewport(iface);
823 
824     TRACE("iface %p.\n", iface);
825 
826     return d3drm_viewport2_GetField(&viewport->IDirect3DRMViewport2_iface);
827 }
828 
829 static D3DVALUE WINAPI d3drm_viewport2_GetBack(IDirect3DRMViewport2 *iface)
830 {
831     struct d3drm_viewport *viewport = impl_from_IDirect3DRMViewport2(iface);
832 
833     TRACE("iface %p.\n", iface);
834 
835     return viewport->back;
836 }
837 
838 static D3DVALUE WINAPI d3drm_viewport1_GetBack(IDirect3DRMViewport *iface)
839 {
840     struct d3drm_viewport *viewport = impl_from_IDirect3DRMViewport(iface);
841 
842     TRACE("iface %p.\n", iface);
843 
844     return d3drm_viewport2_GetBack(&viewport->IDirect3DRMViewport2_iface);
845 }
846 
847 static D3DVALUE WINAPI d3drm_viewport2_GetFront(IDirect3DRMViewport2 *iface)
848 {
849     struct d3drm_viewport *viewport = impl_from_IDirect3DRMViewport2(iface);
850 
851     TRACE("iface %p.\n", iface);
852 
853     return viewport->front;
854 }
855 
856 static D3DVALUE WINAPI d3drm_viewport1_GetFront(IDirect3DRMViewport *iface)
857 {
858     struct d3drm_viewport *viewport = impl_from_IDirect3DRMViewport(iface);
859 
860     TRACE("iface %p.\n", iface);
861 
862     return d3drm_viewport2_GetFront(&viewport->IDirect3DRMViewport2_iface);
863 }
864 
865 static D3DRMPROJECTIONTYPE WINAPI d3drm_viewport2_GetProjection(IDirect3DRMViewport2 *iface)
866 {
867     struct d3drm_viewport *viewport = impl_from_IDirect3DRMViewport2(iface);
868 
869     TRACE("iface %p.\n", iface);
870 
871     return viewport->projection;
872 }
873 
874 static D3DRMPROJECTIONTYPE WINAPI d3drm_viewport1_GetProjection(IDirect3DRMViewport *iface)
875 {
876     struct d3drm_viewport *viewport = impl_from_IDirect3DRMViewport(iface);
877 
878     TRACE("iface %p.\n", iface);
879 
880     return d3drm_viewport2_GetProjection(&viewport->IDirect3DRMViewport2_iface);
881 }
882 
883 static HRESULT WINAPI d3drm_viewport2_GetDirect3DViewport(IDirect3DRMViewport2 *iface,
884         IDirect3DViewport **viewport)
885 {
886     struct d3drm_viewport *viewport_object = impl_from_IDirect3DRMViewport2(iface);
887 
888     TRACE("iface %p, viewport %p.\n", iface, viewport);
889 
890     if (!viewport_object->d3d_viewport)
891         return D3DRMERR_BADOBJECT;
892 
893     *viewport = viewport_object->d3d_viewport;
894     IDirect3DViewport_AddRef(*viewport);
895 
896     return D3DRM_OK;
897 }
898 
899 static HRESULT WINAPI d3drm_viewport1_GetDirect3DViewport(IDirect3DRMViewport *iface,
900         IDirect3DViewport **viewport)
901 {
902     struct d3drm_viewport *viewport_object = impl_from_IDirect3DRMViewport(iface);
903 
904     TRACE("iface %p, viewport %p.\n", iface, viewport);
905 
906     return d3drm_viewport2_GetDirect3DViewport(&viewport_object->IDirect3DRMViewport2_iface, viewport);
907 }
908 
909 static HRESULT WINAPI d3drm_viewport2_TransformVectors(IDirect3DRMViewport2 *iface,
910         DWORD vector_count, D3DRMVECTOR4D *dst, D3DVECTOR *src)
911 {
912     FIXME("iface %p, vector_count %u, dst %p, src %p stub!\n", iface, vector_count, dst, src);
913 
914     return E_NOTIMPL;
915 }
916 
917 static HRESULT WINAPI d3drm_viewport2_InverseTransformVectors(IDirect3DRMViewport2 *iface,
918         DWORD vector_count, D3DVECTOR *dst, D3DRMVECTOR4D *src)
919 {
920     FIXME("iface %p, vector_count %u, dst %p, src %p stub!\n", iface, vector_count, dst, src);
921 
922     return E_NOTIMPL;
923 }
924 
925 static const struct IDirect3DRMViewport2Vtbl d3drm_viewport2_vtbl =
926 {
927     d3drm_viewport2_QueryInterface,
928     d3drm_viewport2_AddRef,
929     d3drm_viewport2_Release,
930     d3drm_viewport2_Clone,
931     d3drm_viewport2_AddDestroyCallback,
932     d3drm_viewport2_DeleteDestroyCallback,
933     d3drm_viewport2_SetAppData,
934     d3drm_viewport2_GetAppData,
935     d3drm_viewport2_SetName,
936     d3drm_viewport2_GetName,
937     d3drm_viewport2_GetClassName,
938     d3drm_viewport2_Init,
939     d3drm_viewport2_Clear,
940     d3drm_viewport2_Render,
941     d3drm_viewport2_SetFront,
942     d3drm_viewport2_SetBack,
943     d3drm_viewport2_SetField,
944     d3drm_viewport2_SetUniformScaling,
945     d3drm_viewport2_SetCamera,
946     d3drm_viewport2_SetProjection,
947     d3drm_viewport2_Transform,
948     d3drm_viewport2_InverseTransform,
949     d3drm_viewport2_Configure,
950     d3drm_viewport2_ForceUpdate,
951     d3drm_viewport2_SetPlane,
952     d3drm_viewport2_GetCamera,
953     d3drm_viewport2_GetDevice,
954     d3drm_viewport2_GetPlane,
955     d3drm_viewport2_Pick,
956     d3drm_viewport2_GetUniformScaling,
957     d3drm_viewport2_GetX,
958     d3drm_viewport2_GetY,
959     d3drm_viewport2_GetWidth,
960     d3drm_viewport2_GetHeight,
961     d3drm_viewport2_GetField,
962     d3drm_viewport2_GetBack,
963     d3drm_viewport2_GetFront,
964     d3drm_viewport2_GetProjection,
965     d3drm_viewport2_GetDirect3DViewport,
966     d3drm_viewport2_TransformVectors,
967     d3drm_viewport2_InverseTransformVectors,
968 };
969 
970 static const struct IDirect3DRMViewportVtbl d3drm_viewport1_vtbl =
971 {
972     d3drm_viewport1_QueryInterface,
973     d3drm_viewport1_AddRef,
974     d3drm_viewport1_Release,
975     d3drm_viewport1_Clone,
976     d3drm_viewport1_AddDestroyCallback,
977     d3drm_viewport1_DeleteDestroyCallback,
978     d3drm_viewport1_SetAppData,
979     d3drm_viewport1_GetAppData,
980     d3drm_viewport1_SetName,
981     d3drm_viewport1_GetName,
982     d3drm_viewport1_GetClassName,
983     d3drm_viewport1_Init,
984     d3drm_viewport1_Clear,
985     d3drm_viewport1_Render,
986     d3drm_viewport1_SetFront,
987     d3drm_viewport1_SetBack,
988     d3drm_viewport1_SetField,
989     d3drm_viewport1_SetUniformScaling,
990     d3drm_viewport1_SetCamera,
991     d3drm_viewport1_SetProjection,
992     d3drm_viewport1_Transform,
993     d3drm_viewport1_InverseTransform,
994     d3drm_viewport1_Configure,
995     d3drm_viewport1_ForceUpdate,
996     d3drm_viewport1_SetPlane,
997     d3drm_viewport1_GetCamera,
998     d3drm_viewport1_GetDevice,
999     d3drm_viewport1_GetPlane,
1000     d3drm_viewport1_Pick,
1001     d3drm_viewport1_GetUniformScaling,
1002     d3drm_viewport1_GetX,
1003     d3drm_viewport1_GetY,
1004     d3drm_viewport1_GetWidth,
1005     d3drm_viewport1_GetHeight,
1006     d3drm_viewport1_GetField,
1007     d3drm_viewport1_GetBack,
1008     d3drm_viewport1_GetFront,
1009     d3drm_viewport1_GetProjection,
1010     d3drm_viewport1_GetDirect3DViewport,
1011 };
1012 
1013 HRESULT d3drm_viewport_create(struct d3drm_viewport **viewport, IDirect3DRM *d3drm)
1014 {
1015     static const char classname[] = "Viewport";
1016     struct d3drm_viewport *object;
1017 
1018     TRACE("viewport %p, d3drm %p.\n", viewport, d3drm);
1019 
1020     if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
1021         return E_OUTOFMEMORY;
1022 
1023     object->IDirect3DRMViewport_iface.lpVtbl = &d3drm_viewport1_vtbl;
1024     object->IDirect3DRMViewport2_iface.lpVtbl = &d3drm_viewport2_vtbl;
1025     object->d3drm = d3drm;
1026     d3drm_object_init(&object->obj, classname);
1027 
1028     *viewport = object;
1029 
1030     return S_OK;
1031 }
1032