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