From: Aaryaman Vasishta Subject: [PATCH 6/7] d3drm: Implement IDirect3DRMViewport*::Init. Message-Id: <1466804973-82867-6-git-send-email-jem456.vasishta@gmail.com> Date: Sat, 25 Jun 2016 03:19:32 +0530 In-Reply-To: <1466804973-82867-1-git-send-email-jem456.vasishta@gmail.com> References: <1466804973-82867-1-git-send-email-jem456.vasishta@gmail.com> Signed-off-by: Aaryaman Vasishta --- dlls/d3drm/d3drm.c | 16 +++- dlls/d3drm/d3drm_private.h | 2 + dlls/d3drm/tests/d3drm.c | 179 +++++++++++++++++++++++++++++++++++++++++---- dlls/d3drm/viewport.c | 128 ++++++++++++++++++++++++++++++-- 4 files changed, 303 insertions(+), 22 deletions(-) diff --git a/dlls/d3drm/d3drm.c b/dlls/d3drm/d3drm.c index 7833d81..001ace4 100644 --- a/dlls/d3drm/d3drm.c +++ b/dlls/d3drm/d3drm.c @@ -64,6 +64,19 @@ static HRESULT d3drm_create_texture_object(void **object, IDirect3DRM *d3drm) return hr; } +static HRESULT d3drm_create_viewport_object(void **object, IDirect3DRM *d3drm) +{ + struct d3drm_viewport *viewport; + HRESULT hr; + + if (FAILED(hr = d3drm_viewport_create(&viewport, d3drm))) + return hr; + + *object = &viewport->IDirect3DRMViewport_iface; + + return hr; +} + struct d3drm { IDirect3DRM IDirect3DRM_iface; @@ -1128,7 +1141,8 @@ static HRESULT WINAPI d3drm3_CreateObject(IDirect3DRM3 *iface, } object_table[] = { - { &CLSID_CDirect3DRMTexture, d3drm_create_texture_object }, + { &CLSID_CDirect3DRMTexture, d3drm_create_texture_object }, + { &CLSID_CDirect3DRMViewport, d3drm_create_viewport_object }, }; int num_entries = sizeof(object_table) / sizeof(*object_table); diff --git a/dlls/d3drm/d3drm_private.h b/dlls/d3drm/d3drm_private.h index 06cbdc1..8f15706 100644 --- a/dlls/d3drm/d3drm_private.h +++ b/dlls/d3drm/d3drm_private.h @@ -68,8 +68,10 @@ struct d3drm_frame struct d3drm_viewport { struct d3drm_object obj; + IDirect3DRMFrame *camera; IDirect3DRMViewport IDirect3DRMViewport_iface; IDirect3DRMViewport2 IDirect3DRMViewport2_iface; + IDirect3DViewport *d3d_viewport; IDirect3DRM *d3drm; D3DVALUE back; D3DVALUE front; diff --git a/dlls/d3drm/tests/d3drm.c b/dlls/d3drm/tests/d3drm.c index 4321bc9..3d7b389 100644 --- a/dlls/d3drm/tests/d3drm.c +++ b/dlls/d3drm/tests/d3drm.c @@ -1364,8 +1364,8 @@ static void test_object(void) { &CLSID_CDirect3DRMTexture, &IID_IDirect3DRMTexture, FALSE }, { &CLSID_CDirect3DRMTexture, &IID_IDirect3DRMTexture2, FALSE }, { &CLSID_CDirect3DRMTexture, &IID_IDirect3DRMTexture3, FALSE }, - { &CLSID_CDirect3DRMViewport, &IID_IDirect3DRMViewport, TRUE }, - { &CLSID_CDirect3DRMViewport, &IID_IDirect3DRMViewport2, TRUE }, + { &CLSID_CDirect3DRMViewport, &IID_IDirect3DRMViewport, FALSE }, + { &CLSID_CDirect3DRMViewport, &IID_IDirect3DRMViewport2, FALSE }, }; IDirect3DRM *d3drm1; IDirect3DRM2 *d3drm2; @@ -1463,40 +1463,56 @@ static void test_object(void) static void test_Viewport(void) { - IDirectDrawClipper *pClipper; + IDirectDrawClipper *clipper; HRESULT hr; - IDirect3DRM *d3drm; - IDirect3DRMDevice *device; + IDirect3DRM *d3drm1; + IDirect3DRM2 *d3drm2; + IDirect3DRM3 *d3drm3; + IDirect3DRMDevice *device1; + IDirect3DRMDevice3 *device3; IDirect3DRMFrame *frame; + IDirect3DRMFrame3 *frame3; IDirect3DRMViewport *viewport; IDirect3DRMViewport2 *viewport2; IDirect3DRMObject *obj, *obj2; GUID driver; HWND window; RECT rc; - DWORD size, data; + DWORD size, data, ref1, ref2, ref3, ref4; + DWORD initial_ref1, initial_ref2, initial_ref3, device_ref, frame_ref, frame_ref2; CHAR cname[64] = {0}; window = CreateWindowA("static", "d3drm_test", WS_OVERLAPPEDWINDOW, 0, 0, 300, 200, 0, 0, 0, 0); GetClientRect(window, &rc); - hr = Direct3DRMCreate(&d3drm); + hr = Direct3DRMCreate(&d3drm1); ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x)\n", hr); + hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM2, (void **)&d3drm2); + ok(SUCCEEDED(hr), "Cannot get IDirect3DRM2 interface (hr = %#x).\n", hr); + hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM3, (void **)&d3drm3); + ok(SUCCEEDED(hr), "Cannot get IDirect3DRM3 interface (hr = %#x).\n", hr); + initial_ref1 = get_refcount((IUnknown *)d3drm1); + initial_ref2 = get_refcount((IUnknown *)d3drm2); + initial_ref3 = get_refcount((IUnknown *)d3drm3); - hr = DirectDrawCreateClipper(0, &pClipper, NULL); + hr = DirectDrawCreateClipper(0, &clipper, NULL); ok(hr == DD_OK, "Cannot get IDirectDrawClipper interface (hr = %x)\n", hr); - hr = IDirectDrawClipper_SetHWnd(pClipper, 0, window); + hr = IDirectDrawClipper_SetHWnd(clipper, 0, window); ok(hr == DD_OK, "Cannot set HWnd to Clipper (hr = %x)\n", hr); memcpy(&driver, &IID_IDirect3DRGBDevice, sizeof(GUID)); - hr = IDirect3DRM3_CreateDeviceFromClipper(d3drm, pClipper, &driver, rc.right, rc.bottom, &device); + hr = IDirect3DRM3_CreateDeviceFromClipper(d3drm3, clipper, &driver, rc.right, rc.bottom, &device3); ok(hr == D3DRM_OK, "Cannot get IDirect3DRMDevice interface (hr = %x)\n", hr); + hr = IDirect3DRMDevice3_QueryInterface(device3, &IID_IDirect3DRMDevice, (void **)&device1); + ok(SUCCEEDED(hr), "Cannot get IDirect3DRMDevice interface (hr = %#x).\n", hr); - hr = IDirect3DRM_CreateFrame(d3drm, NULL, &frame); + hr = IDirect3DRM_CreateFrame(d3drm1, NULL, &frame); ok(hr == D3DRM_OK, "Cannot get IDirect3DRMFrame interface (hr = %x)\n", hr); + hr = IDirect3DRM3_CreateFrame(d3drm3, NULL, &frame3); + ok(SUCCEEDED(hr), "Cannot get IDirect3DRMFrame3 interface (hr = %x).\n", hr); - hr = IDirect3DRM_CreateViewport(d3drm, device, frame, rc.left, rc.top, rc.right, rc.bottom, &viewport); + hr = IDirect3DRM_CreateViewport(d3drm1, device1, frame, rc.left, rc.top, rc.right, rc.bottom, &viewport); ok(hr == D3DRM_OK, "Cannot get IDirect3DRMViewport interface (hr = %x)\n", hr); hr = IDirect3DRMViewport_QueryInterface(viewport, &IID_IDirect3DRMObject, (void**)&obj); @@ -1547,12 +1563,145 @@ static void test_Viewport(void) data = IDirect3DRMViewport2_GetAppData(viewport2); ok(data == 1, "got %x\n", data); IDirect3DRMViewport2_Release(viewport2); + IDirect3DRMViewport_Release(viewport); + + /* IDirect3DRMViewport*::Init tests */ + ref1 = get_refcount((IUnknown *)d3drm1); + ref2 = get_refcount((IUnknown *)d3drm2); + ref3 = get_refcount((IUnknown *)d3drm3); + hr = IDirect3DRM_CreateObject(d3drm1, &CLSID_CDirect3DRMViewport, NULL, &IID_IDirect3DRMViewport, + (void **)&viewport); + ok(SUCCEEDED(hr), "Cannot get IDirect3DRMViewport interface (hr = %#x).\n", hr); + ref4 = get_refcount((IUnknown *)d3drm1); + ok(ref4 == ref1, "Expected ref4 == ref1, got ref1 = %u, ref4 = %u.\n", ref1, ref4); + ref4 = get_refcount((IUnknown *)d3drm2); + ok(ref4 == ref2, "Expected ref4 == ref2, got ref2 = %u, ref4 = %u.\n", ref2, ref4); + ref4 = get_refcount((IUnknown *)d3drm3); + ok(ref4 == ref3, "Expected ref4 == ref3, got ref3 = %u, ref4 = %u.\n", ref3, ref4); + + /* Test all failures together */ + hr = IDirect3DRMViewport_Init(viewport, NULL, frame, rc.left, rc.top, rc.right, rc.bottom); + ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr); + hr = IDirect3DRMViewport_Init(viewport, device1, NULL, rc.left, rc.top, rc.right, rc.bottom); + ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr); + hr = IDirect3DRMViewport_Init(viewport, device1, frame, rc.left, rc.top, rc.right + 1, rc.bottom + 1); + ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr); + hr = IDirect3DRMViewport_Init(viewport, device1, frame, rc.left, rc.top, rc.right + 1, rc.bottom); + ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr); + hr = IDirect3DRMViewport_Init(viewport, device1, frame, rc.left, rc.top, rc.right + 1, rc.bottom + 1); + ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr); + + device_ref = get_refcount((IUnknown *)device1); + frame_ref = get_refcount((IUnknown *)frame); + hr = IDirect3DRMViewport_Init(viewport, device1, frame, rc.left, rc.top, rc.right, rc.bottom); + ok(SUCCEEDED(hr), "Cannot initialize IDirect3DRMViewport interface (hr = %#x).\n", hr); + ref4 = get_refcount((IUnknown *)d3drm1); + ok(ref4 > ref1, "Expected ref4 > ref1, got ref1 = %u, ref4 = %u.\n", ref1, ref4); + ref4 = get_refcount((IUnknown *)d3drm2); + ok(ref4 == ref2, "Expected ref4 == ref2, got ref2 = %u, ref4 = %u.\n", ref2, ref4); + ref4 = get_refcount((IUnknown *)d3drm3); + ok(ref4 == ref3, "Expected ref4 == ref3, got ref3 = %u, ref4 = %u.\n", ref3, ref4); + ref4 = get_refcount((IUnknown *)device1); + ok(ref4 == device_ref, "Expected ref4 == device_ref, got device_ref = %u, ref4 = %u.\n", device_ref, ref4); + ref4 = get_refcount((IUnknown *)frame); + ok(ref4 > frame_ref, "Expected ref4 > frame_ref, got frame_ref = %u, ref4 = %u.\n", frame_ref, ref4); + + hr = IDirect3DRMViewport_Init(viewport, device1, frame, rc.left, rc.top, rc.right, rc.bottom); + ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr); + + IDirect3DRMViewport_Release(viewport); + ref4 = get_refcount((IUnknown *)d3drm1); + todo_wine ok(ref4 > ref1, "Expected ref4 > ref1, got ref1 = %u, ref4 = %u.\n", ref1, ref4); + ref4 = get_refcount((IUnknown *)d3drm2); + ok(ref4 == ref2, "Expected ref4 == ref2, got ref2 = %u, ref4 = %u.\n", ref2, ref4); + ref4 = get_refcount((IUnknown *)d3drm3); + ok(ref4 == ref3, "Expected ref4 == ref3, got ref3 = %u, ref4 = %u.\n", ref3, ref4); + ref4 = get_refcount((IUnknown *)device1); + ok(ref4 == device_ref, "Expected ref4 == device_ref, got device_ref = %u, ref4 = %u.\n", device_ref, ref4); + ref4 = get_refcount((IUnknown *)frame); + todo_wine ok(ref4 > frame_ref, "Expected ref4 > frame_ref, got frame_ref = %u, ref4 = %u.\n", frame_ref, ref4); + + ref1 = get_refcount((IUnknown *)d3drm1); + ref2 = get_refcount((IUnknown *)d3drm2); + ref3 = get_refcount((IUnknown *)d3drm3); + hr = IDirect3DRM3_CreateObject(d3drm2, &CLSID_CDirect3DRMViewport, NULL, &IID_IDirect3DRMViewport2, + (void **)&viewport2); + ok(SUCCEEDED(hr), "Cannot get IDirect3DRMViewport2 interface (hr = %#x).\n", hr); + ref4 = get_refcount((IUnknown *)d3drm1); + ok(ref4 == ref1, "Expected ref4 == ref1, got ref1 = %u, ref4 = %u.\n", ref1, ref4); + ref4 = get_refcount((IUnknown *)d3drm2); + ok(ref4 == ref2, "Expected ref4 == ref2, got ref2 = %u, ref4 = %u.\n", ref2, ref4); + ref4 = get_refcount((IUnknown *)d3drm3); + ok(ref4 == ref3, "Expected ref4 == ref3, got ref3 = %u, ref4 = %u.\n", ref3, ref4); + + hr = IDirect3DRMViewport2_Init(viewport2, NULL, frame3, rc.left, rc.top, rc.right, rc.bottom); + ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr); + hr = IDirect3DRMViewport2_Init(viewport2, device3, NULL, rc.left, rc.top, rc.right, rc.bottom); + ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr); + hr = IDirect3DRMViewport2_Init(viewport2, device3, frame3, rc.left, rc.top, rc.right + 1, rc.bottom + 1); + ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr); + hr = IDirect3DRMViewport2_Init(viewport2, device3, frame3, rc.left, rc.top, rc.right + 1, rc.bottom); + ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr); + hr = IDirect3DRMViewport2_Init(viewport2, device3, frame3, rc.left, rc.top, rc.right, rc.bottom + 1); + ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr); + + device_ref = get_refcount((IUnknown *)device3); + frame_ref2 = get_refcount((IUnknown *)frame3); + hr = IDirect3DRMViewport2_Init(viewport2, device3, frame3, rc.left, rc.top, rc.right, rc.bottom); + ok(SUCCEEDED(hr), "Cannot initialize IDirect3DRMViewport2 interface (hr = %#x).\n", hr); + ref4 = get_refcount((IUnknown *)device3); + ok(ref4 == device_ref, "Expected ref4 == device_ref, got device_ref = %u, ref4 = %u.\n", device_ref, ref4); + ref4 = get_refcount((IUnknown *)frame3); + ok(ref4 > frame_ref2, "Expected ref4 > frame_ref2, got frame_ref2 = %u, ref4 = %u.\n", frame_ref2, ref4); + + hr = IDirect3DRMViewport2_Init(viewport2, device3, frame3, rc.left, rc.top, rc.right, rc.bottom); + ok(hr == D3DRMERR_BADOBJECT, "Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", hr); + + IDirect3DRMViewport2_Release(viewport2); + ref4 = get_refcount((IUnknown *)d3drm1); + todo_wine ok(ref4 > ref1, "Expected ref4 > ref1, got ref1 = %u, ref4 = %u.\n", ref1, ref4); + ref4 = get_refcount((IUnknown *)d3drm2); + ok(ref4 == ref2, "Expected ref4 == ref2, got ref2 = %u, ref4 = %u.\n", ref2, ref4); + ref4 = get_refcount((IUnknown *)d3drm3); + ok(ref4 == ref3, "Expected ref4 == ref3, got ref3 = %u, ref4 = %u.\n", ref3, ref4); + ref4 = get_refcount((IUnknown *)device3); + ok(ref4 == device_ref, "Expected ref4 == device_ref, got device_ref = %u, ref4 = %u.\n", device_ref, ref4); + ref4 = get_refcount((IUnknown *)frame3); + todo_wine ok(ref4 > frame_ref2, "Expected ref4 > frame_ref2, got frame_ref2 = %u, ref4 = %u.\n", frame_ref2, ref4); + + IDirect3DRMDevice3_Release(device3); + IDirect3DRMDevice_Release(device1); + ref4 = get_refcount((IUnknown *)d3drm1); + todo_wine ok(ref4 > initial_ref1, "Expected ref4 > initial_ref1, got initial_ref1 = %u, ref4 = %u.\n", initial_ref1, ref4); + ref4 = get_refcount((IUnknown *)d3drm2); + ok(ref4 == initial_ref2, "Expected ref4 == initial_ref2, got initial_ref2 = %u, ref4 = %u.\n", initial_ref2, ref4); + ref4 = get_refcount((IUnknown *)d3drm3); + ok(ref4 == initial_ref3, "Expected ref4 == initial_ref3, got initial_ref3 = %u, ref4 = %u.\n", initial_ref3, ref4); + ref4 = get_refcount((IUnknown *)frame); + ok(ref4 == frame_ref, "Expected ref4 == frame_ref, got frame_ref = %u, ref4 = %u.\n", frame_ref, ref4); + ref4 = get_refcount((IUnknown *)frame3); + ok(ref4 == frame_ref2, "Expected ref4 == frame_ref2, got frame_ref2 = %u, ref4 = %u.\n", frame_ref2, ref4); + + IDirect3DRMFrame3_Release(frame3); + ref4 = get_refcount((IUnknown *)d3drm1); + todo_wine ok(ref4 > initial_ref1, "Expected ref4 > initial_ref1, got initial_ref1 = %u, ref4 = %u.\n", initial_ref1, ref4); + ref4 = get_refcount((IUnknown *)d3drm2); + ok(ref4 == initial_ref2, "Expected ref4 == initial_ref2, got initial_ref2 = %u, ref4 = %u.\n", initial_ref2, ref4); + ref4 = get_refcount((IUnknown *)d3drm3); + ok(ref4 == initial_ref3, "Expected ref4 == initial_ref3, got initial_ref3 = %u, ref4 = %u.\n", initial_ref3, ref4); IDirect3DRMFrame_Release(frame); - IDirect3DRMDevice_Release(device); - IDirectDrawClipper_Release(pClipper); + ref4 = get_refcount((IUnknown *)d3drm1); + ok(ref4 == initial_ref1, "Expected ref4 == initial_ref1, got initial_ref1 = %u, ref4 = %u.\n", initial_ref1, ref4); + ref4 = get_refcount((IUnknown *)d3drm2); + ok(ref4 == initial_ref2, "Expected ref4 == initial_ref2, got initial_ref2 = %u, ref4 = %u.\n", initial_ref2, ref4); + ref4 = get_refcount((IUnknown *)d3drm3); + ok(ref4 == initial_ref3, "Expected ref4 == initial_ref3, got initial_ref3 = %u, ref4 = %u.\n", initial_ref3, ref4); + IDirectDrawClipper_Release(clipper); - IDirect3DRM_Release(d3drm); + IDirect3DRM3_Release(d3drm3); + IDirect3DRM2_Release(d3drm2); + IDirect3DRM_Release(d3drm1); DestroyWindow(window); } diff --git a/dlls/d3drm/viewport.c b/dlls/d3drm/viewport.c index cb5f9b5..8b0c772 100644 --- a/dlls/d3drm/viewport.c +++ b/dlls/d3drm/viewport.c @@ -42,6 +42,13 @@ static inline struct d3drm_viewport *impl_from_IDirect3DRMViewport2(IDirect3DRMV static void d3drm_viewport_destroy(struct d3drm_viewport *viewport) { d3drm_object_cleanup((IDirect3DRMObject*)&viewport->IDirect3DRMViewport_iface, &viewport->obj); + TRACE("viewport %p releasing attached interfaces.\n", viewport); + if (viewport->d3d_viewport) + { + IDirect3DViewport_Release(viewport->d3d_viewport); + IDirect3DRMFrame_Release(viewport->camera); + IDirect3DRM_Release(viewport->d3drm); + } HeapFree(GetProcessHeap(), 0, viewport); } @@ -270,19 +277,128 @@ static HRESULT WINAPI d3drm_viewport1_GetClassName(IDirect3DRMViewport *iface, D static HRESULT WINAPI d3drm_viewport2_Init(IDirect3DRMViewport2 *iface, IDirect3DRMDevice3 *device, IDirect3DRMFrame3 *camera, DWORD x, DWORD y, DWORD width, DWORD height) { - FIXME("iface %p, device %p, camera %p, x %u, y %u, width %u, height %u stub!\n", + struct d3drm_viewport *viewport = impl_from_IDirect3DRMViewport2(iface); + D3DVIEWPORT vp; + D3DVALUE scale; + IDirect3D *d3d1 = NULL; + D3DCOLOR color; + IDirect3DDevice *d3d_device = NULL; + IDirect3DMaterial *material = NULL; + D3DMATERIAL mat; + D3DMATERIALHANDLE hmat; + HRESULT hr = D3DRM_OK; + + TRACE("iface %p, device %p, camera %p, x %u, y %u, width %u, height %u.\n", iface, device, camera, x, y, width, height); - return E_NOTIMPL; + if (!device || !camera + || width > IDirect3DRMDevice3_GetWidth(device) + || height > IDirect3DRMDevice3_GetHeight(device)) + { + return D3DRMERR_BADOBJECT; + } + + if (viewport->d3d_viewport) + return D3DRMERR_BADOBJECT; + + IDirect3DRM_AddRef(viewport->d3drm); + + if (FAILED(hr = IDirect3DRMDevice3_GetDirect3DDevice(device, &d3d_device))) + goto cleanup; + + if (FAILED(hr = IDirect3DDevice_GetDirect3D(d3d_device, &d3d1))) + goto cleanup; + + if (FAILED(hr = IDirect3D_CreateViewport(d3d1, &viewport->d3d_viewport, NULL))) + goto cleanup; + + vp.dwSize = sizeof(vp); + vp.dwWidth = width; + vp.dwHeight = height; + vp.dwX = x; + vp.dwY = y; + scale = width > height ? (float)width / 2.0f : (float)height / 2.0f; + vp.dvScaleX = scale; + vp.dvScaleY = scale; + vp.dvMaxX = vp.dwWidth / (2.0f * vp.dvScaleX); + vp.dvMaxY = vp.dwHeight / (2.0f * vp.dvScaleY); + vp.dvMinZ = 0.0f; + vp.dvMaxZ = 1.0f; + + if (FAILED(hr = IDirect3DViewport_SetViewport(viewport->d3d_viewport, &vp))) + goto cleanup; + + if (FAILED(hr = IDirect3DDevice_AddViewport(d3d_device, viewport->d3d_viewport))) + goto cleanup; + + if (FAILED(hr = IDirect3DRMFrame3_QueryInterface(camera, &IID_IDirect3DRMFrame, (void **)&viewport->camera))) + goto cleanup; + + color = IDirect3DRMFrame3_GetSceneBackground(camera); + /* Create material (ambient/diffuse/emissive?), set material */ + if (FAILED(hr = IDirect3D_CreateMaterial(d3d1, &material, NULL))) + goto cleanup; + + memset(&mat, 0, sizeof(mat)); + memcpy(&mat.diffuse, &color, sizeof(color)); + + if (FAILED(hr = IDirect3DMaterial_SetMaterial(material, &mat))) + goto cleanup; + + if (FAILED(hr = IDirect3DMaterial_GetHandle(material, d3d_device, &hmat))) + goto cleanup; + + hr = IDirect3DViewport_SetBackground(viewport->d3d_viewport, hmat); + +cleanup: + + if (material) + IDirect3DMaterial_Release(material); + if (FAILED(hr)) + { + if (viewport->d3d_viewport) + { + IDirect3DViewport_Release(viewport->d3d_viewport); + viewport->d3d_viewport = NULL; + } + if (viewport->camera) + IDirect3DRMFrame_Release(viewport->camera); + IDirect3DRM_Release(viewport->d3drm); + } + if (d3d_device) + IDirect3DDevice_Release(d3d_device); + if (d3d1) + IDirect3D_Release(d3d1); + + return hr; } static HRESULT WINAPI d3drm_viewport1_Init(IDirect3DRMViewport *iface, IDirect3DRMDevice *device, IDirect3DRMFrame *camera, DWORD x, DWORD y, DWORD width, DWORD height) { - FIXME("iface %p, device %p, camera %p, x %u, y %u, width %u, height %u stub!\n", - iface, device, camera, x, y, width, height); + struct d3drm_viewport *viewport = impl_from_IDirect3DRMViewport(iface); + IDirect3DRMDevice3 *device3; + IDirect3DRMFrame3 *camera3; + HRESULT hr; - return E_NOTIMPL; + TRACE("iface %p, device %p, camera %p, x %u, y %u, width %u, height %u.\n", + iface, device, camera, x, y, width, height); + + if (!device || !camera) + return D3DRMERR_BADOBJECT; + + if (FAILED(hr = IDirect3DRMDevice_QueryInterface(device, &IID_IDirect3DRMDevice3, (void **)&device3))) + return hr; + + if (FAILED(hr = IDirect3DRMFrame_QueryInterface(camera, &IID_IDirect3DRMFrame3, (void **)&camera3))) + { + IDirect3DRMDevice3_Release(device3); + return hr; + } + IDirect3DRMDevice_Release(device); + IDirect3DRMFrame_Release(camera); + + return d3drm_viewport2_Init(&viewport->IDirect3DRMViewport2_iface, device3, camera3, x, y, width, height); } static HRESULT WINAPI d3drm_viewport2_Clear(IDirect3DRMViewport2 *iface, DWORD flags) @@ -827,7 +943,7 @@ HRESULT d3drm_viewport_create(struct d3drm_viewport **viewport, IDirect3DRM *d3d { struct d3drm_viewport *object; - TRACE("viewport %p, d3drm %p.\n", viewport, d3drm); + TRACE("out %p, d3drm %p.\n", viewport, d3drm); if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) return E_OUTOFMEMORY; -- 2.3.2 (Apple Git-55)