diff --git a/dlls/d3drm/frame.c b/dlls/d3drm/frame.c index 2ff0241d76f..d79a8e3ed6d 100644 --- a/dlls/d3drm/frame.c +++ b/dlls/d3drm/frame.c @@ -1339,23 +1339,53 @@ static HRESULT WINAPI d3drm_frame1_GetRotation(IDirect3DRMFrame *iface, static HRESULT WINAPI d3drm_frame3_GetScene(IDirect3DRMFrame3 *iface, IDirect3DRMFrame3 **scene) { - FIXME("iface %p, scene %p stub!\n", iface, scene); + struct d3drm_frame *frame = impl_from_IDirect3DRMFrame3(iface); - return E_NOTIMPL; + TRACE("iface %p, scene %p.\n", iface, scene); + + if (!scene) + return D3DRMERR_BADVALUE; + + while (frame->parent) + frame = frame->parent; + + *scene = &frame->IDirect3DRMFrame3_iface; + IDirect3DRMFrame3_AddRef(*scene); + + return D3DRM_OK; } static HRESULT WINAPI d3drm_frame2_GetScene(IDirect3DRMFrame2 *iface, IDirect3DRMFrame **scene) { - FIXME("iface %p, scene %p stub!\n", iface, scene); + struct d3drm_frame *frame = impl_from_IDirect3DRMFrame2(iface); + IDirect3DRMFrame3 *frame3; + HRESULT hr; - return E_NOTIMPL; + TRACE("iface %p, scene %p.\n", iface, scene); + + if (!scene) + return D3DRMERR_BADVALUE; + + hr = IDirect3DRMFrame3_GetScene(&frame->IDirect3DRMFrame3_iface, &frame3); + if (FAILED(hr) || !frame3) + { + *scene = NULL; + return hr; + } + + hr = IDirect3DRMFrame3_QueryInterface(frame3, &IID_IDirect3DRMFrame, (void **)scene); + IDirect3DRMFrame3_Release(frame3); + + return hr; } static HRESULT WINAPI d3drm_frame1_GetScene(IDirect3DRMFrame *iface, IDirect3DRMFrame **scene) { - FIXME("iface %p, scene %p stub!\n", iface, scene); + struct d3drm_frame *frame = impl_from_IDirect3DRMFrame(iface); - return E_NOTIMPL; + TRACE("iface %p, scene %p.\n", iface, scene); + + return d3drm_frame2_GetScene(&frame->IDirect3DRMFrame2_iface, scene); } static D3DRMSORTMODE WINAPI d3drm_frame3_GetSortMode(IDirect3DRMFrame3 *iface) diff --git a/dlls/d3drm/tests/d3drm.c b/dlls/d3drm/tests/d3drm.c index 1abaed58ee7..d86477d49c8 100644 --- a/dlls/d3drm/tests/d3drm.c +++ b/dlls/d3drm/tests/d3drm.c @@ -885,6 +885,7 @@ static void test_Frame(void) IDirect3DRMFrame *pFrameP1; IDirect3DRMFrame *pFrameP2; IDirect3DRMFrame *pFrameTmp; + IDirect3DRMFrame *scene_frame; IDirect3DRMFrameArray *frame_array; IDirect3DRMMeshBuilder *mesh_builder; IDirect3DRMVisual *visual1; @@ -967,6 +968,19 @@ static void test_Frame(void) CHECK_REFCOUNT(pFrameP1, 1); CHECK_REFCOUNT(pFrameC, 2); + hr = IDirect3DRMFrame_GetScene(pFrameC, NULL); + ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %#x.\n", hr); + hr = IDirect3DRMFrame_GetScene(pFrameC, &scene_frame); + ok(SUCCEEDED(hr), "Cannot get scene (hr == %#x).\n", hr); + ok(scene_frame == pFrameP1, "Expected scene frame == %p, got %p.\n", pFrameP1, scene_frame); + CHECK_REFCOUNT(pFrameP1, 2); + IDirect3DRMFrame_Release(scene_frame); + hr = IDirect3DRMFrame_GetScene(pFrameP1, &scene_frame); + ok(SUCCEEDED(hr), "Cannot get scene (hr == %#x).\n", hr); + ok(scene_frame == pFrameP1, "Expected scene frame == %p, got %p.\n", pFrameP1, scene_frame); + CHECK_REFCOUNT(pFrameP1, 2); + IDirect3DRMFrame_Release(scene_frame); + frame_array = NULL; hr = IDirect3DRMFrame_GetChildren(pFrameP1, &frame_array); ok(hr == D3DRM_OK, "Cannot get children (hr = %x)\n", hr); @@ -1032,6 +1046,16 @@ static void test_Frame(void) ok(pFrameTmp == NULL, "pFrameTmp = %p\n", pFrameTmp); IDirect3DRMFrameArray_Release(frame_array); } + hr = IDirect3DRMFrame_GetScene(pFrameC, &scene_frame); + ok(SUCCEEDED(hr), "Cannot get scene (hr == %#x).\n", hr); + ok(scene_frame == pFrameP2, "Expected scene frame == %p, got %p.\n", pFrameP2, scene_frame); + CHECK_REFCOUNT(pFrameP2, 2); + IDirect3DRMFrame_Release(scene_frame); + hr = IDirect3DRMFrame_GetScene(pFrameP2, &scene_frame); + ok(SUCCEEDED(hr), "Cannot get scene (hr == %#x).\n", hr); + ok(scene_frame == pFrameP2, "Expected scene frame == %p, got %p.\n", pFrameP2, scene_frame); + CHECK_REFCOUNT(pFrameP2, 2); + IDirect3DRMFrame_Release(scene_frame); pFrameTmp = (void*)0xdeadbeef; hr = IDirect3DRMFrame_GetParent(pFrameC, &pFrameTmp);