diff --git a/dlls/d3drm/d3drm.c b/dlls/d3drm/d3drm.c index e4cc4fad93a..61d0a25c7c9 100644 --- a/dlls/d3drm/d3drm.c +++ b/dlls/d3drm/d3drm.c @@ -697,18 +697,24 @@ static HRESULT WINAPI d3drm2_CreateDeviceFromClipper(IDirect3DRM2 *iface, IDirectDrawClipper *clipper, GUID *guid, int width, int height, IDirect3DRMDevice2 **device) { - struct d3drm_device *object; + struct d3drm *d3drm = impl_from_IDirect3DRM2(iface); + IDirect3DRMDevice3 *device3; HRESULT hr; - FIXME("iface %p, clipper %p, guid %s, width %d, height %d, device %p.\n", + + TRACE("iface %p, clipper %p, guid %s, width %d, height %d, device %p.\n", iface, clipper, debugstr_guid(guid), width, height, device); - hr = d3drm_device_create(&object); + if (!device) + return D3DRMERR_BADVALUE; + *device = NULL; + hr = IDirect3DRM3_CreateDeviceFromClipper(&d3drm->IDirect3DRM3_iface, clipper, guid, width, height, &device3); if (FAILED(hr)) return hr; - *device = IDirect3DRMDevice2_from_impl(object); + hr = IDirect3DRMDevice3_QueryInterface(device3, &IID_IDirect3DRMDevice2, (void**)device); + IDirect3DRMDevice3_Release(device3); - return D3DRM_OK; + return hr; } static HRESULT WINAPI d3drm2_CreateTextureFromSurface(IDirect3DRM2 *iface, @@ -1103,18 +1109,50 @@ static HRESULT WINAPI d3drm3_CreateDeviceFromClipper(IDirect3DRM3 *iface, IDirectDrawClipper *clipper, GUID *guid, int width, int height, IDirect3DRMDevice3 **device) { + struct d3drm *d3drm = impl_from_IDirect3DRM3(iface); struct d3drm_device *object; + IDirectDraw *ddraw; + IDirectDrawSurface *render_target; HRESULT hr; - FIXME("iface %p, clipper %p, guid %s, width %d, height %d, device %p.\n", + + TRACE("iface %p, clipper %p, guid %s, width %d, height %d, device %p.\n", iface, clipper, debugstr_guid(guid), width, height, device); - hr = d3drm_device_create(&object); + if (!device) + return D3DRMERR_BADVALUE; + *device = NULL; + + if (!clipper || !width || !height) + return D3DRMERR_BADVALUE; + + hr = DirectDrawCreate(NULL, &ddraw, NULL); if (FAILED(hr)) return hr; - *device = IDirect3DRMDevice3_from_impl(object); + hr = d3drm_device_create(&object); + if (FAILED(hr)) + { + IDirectDraw_Release(ddraw); + return hr; + } - return D3DRM_OK; + hr = d3drm_device_create_surfaces_from_clipper(object, ddraw, clipper, width, height, &render_target); + if (FAILED(hr)) + { + IDirectDraw_Release(ddraw); + d3drm_device_destroy(object); + return hr; + } + + hr = d3drm_device_init(object, 3, &d3drm->IDirect3DRM_iface, ddraw, render_target); + IDirectDraw_Release(ddraw); + IDirectDrawSurface_Release(render_target); + if (FAILED(hr)) + d3drm_device_destroy(object); + else + *device = IDirect3DRMDevice3_from_impl(object); + + return hr; } static HRESULT WINAPI d3drm3_CreateShadow(IDirect3DRM3 *iface, IUnknown *object, IDirect3DRMLight *light, diff --git a/dlls/d3drm/tests/d3drm.c b/dlls/d3drm/tests/d3drm.c index 93a8b736173..7790f02a586 100644 --- a/dlls/d3drm/tests/d3drm.c +++ b/dlls/d3drm/tests/d3drm.c @@ -2134,7 +2134,7 @@ static void test_create_device_from_clipper2(void) IDirect3DRM2 *d3drm2 = NULL; IDirectDraw *ddraw = NULL; IUnknown *unknown = NULL; - IDirect3DRMDevice2 *device2 = NULL; + IDirect3DRMDevice2 *device2 = (IDirect3DRMDevice2 *)0xdeadbeef; IDirect3DDevice2 *d3ddevice2 = NULL; IDirectDrawClipper *clipper = NULL, *d3drm_clipper = NULL; IDirectDrawSurface *surface = NULL, *ds = NULL, *d3drm_primary = NULL; @@ -2164,24 +2164,24 @@ static void test_create_device_from_clipper2(void) ref2 = get_refcount((IUnknown *)d3drm2); hr = IDirect3DRM2_CreateDeviceFromClipper(d3drm2, clipper, &driver, 0, 0, &device2); - todo_wine ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %x.\n", hr); - if (SUCCEEDED(hr)) - IDirect3DRMDevice2_Release(device2); + ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %x.\n", hr); + ok(device2 == NULL, "Expected device returned == NULL, got %p.\n", device2); /* If NULL is passed for clipper, CreateDeviceFromClipper returns D3DRMERR_BADVALUE */ hr = IDirect3DRM2_CreateDeviceFromClipper(d3drm2, NULL, &driver, 300, 200, &device2); - todo_wine ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %x.\n", hr); - if (SUCCEEDED(hr)) - IDirect3DRMDevice2_Release(device2); + ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %x.\n", hr); + + hr = IDirect3DRM2_CreateDeviceFromClipper(d3drm2, clipper, &driver, 300, 200, NULL); + ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %x.\n", hr); hr = IDirect3DRM2_CreateDeviceFromClipper(d3drm2, clipper, &driver, 300, 200, &device2); ok(hr == D3DRM_OK, "Cannot create IDirect3DRMDevice2 interface (hr = %x).\n", hr); ref3 = get_refcount((IUnknown *)d3drm1); - todo_wine ok(ref3 > ref1, "expected ref3 > ref1, got ref1 = %u , ref3 = %u.\n", ref1, ref3); + ok(ref3 > ref1, "expected ref3 > ref1, got ref1 = %u , ref3 = %u.\n", ref1, ref3); ref3 = get_refcount((IUnknown *)d3drm2); ok(ref3 == ref2, "expected ref3 == ref2, got ref2 = %u , ref3 = %u.\n", ref2, ref3); cref2 = get_refcount((IUnknown *)clipper); - todo_wine ok(cref2 > cref1, "expected cref2 > cref1, got cref1 = %u , cref2 = %u.\n", cref1, cref2); + ok(cref2 > cref1, "expected cref2 > cref1, got cref1 = %u , cref2 = %u.\n", cref1, cref2); /* Fetch immediate mode device in order to access render target */ hr = IDirect3DRMDevice2_GetDirect3DDevice2(device2, &d3ddevice2); @@ -2322,7 +2322,7 @@ static void test_create_device_from_clipper3(void) IDirect3DRM3 *d3drm3 = NULL; IDirectDraw *ddraw = NULL; IUnknown *unknown = NULL; - IDirect3DRMDevice3 *device3 = NULL; + IDirect3DRMDevice3 *device3 = (IDirect3DRMDevice3 *)0xdeadbeef; IDirect3DDevice2 *d3ddevice2 = NULL; IDirectDrawClipper *clipper = NULL, *d3drm_clipper = NULL; IDirectDrawSurface *surface = NULL, *ds = NULL, *d3drm_primary = NULL; @@ -2352,24 +2352,24 @@ static void test_create_device_from_clipper3(void) ref2 = get_refcount((IUnknown *)d3drm3); hr = IDirect3DRM3_CreateDeviceFromClipper(d3drm3, clipper, &driver, 0, 0, &device3); - todo_wine ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %x.\n", hr); - if (SUCCEEDED(hr)) - IDirect3DRMDevice3_Release(device3); + ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %x.\n", hr); + ok(device3 == NULL, "Expected device returned == NULL, got %p.\n", device3); /* If NULL is passed for clipper, CreateDeviceFromClipper returns D3DRMERR_BADVALUE */ hr = IDirect3DRM3_CreateDeviceFromClipper(d3drm3, NULL, &driver, 300, 200, &device3); - todo_wine ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %x.\n", hr); - if (SUCCEEDED(hr)) - IDirect3DRMDevice3_Release(device3); + ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %x.\n", hr); + + hr = IDirect3DRM3_CreateDeviceFromClipper(d3drm3, clipper, &driver, 300, 200, NULL); + ok(hr == D3DRMERR_BADVALUE, "Expected hr == D3DRMERR_BADVALUE, got %x.\n", hr); hr = IDirect3DRM3_CreateDeviceFromClipper(d3drm3, clipper, &driver, 300, 200, &device3); ok(hr == D3DRM_OK, "Cannot create IDirect3DRMDevice3 interface (hr = %x).\n", hr); ref3 = get_refcount((IUnknown *)d3drm1); - todo_wine ok(ref3 > ref1, "expected ref3 > ref1, got ref1 = %u , ref3 = %u.\n", ref1, ref3); + ok(ref3 > ref1, "expected ref3 > ref1, got ref1 = %u , ref3 = %u.\n", ref1, ref3); ref3 = get_refcount((IUnknown *)d3drm3); ok(ref3 == ref2, "expected ref3 == ref2, got ref2 = %u , ref3 = %u.\n", ref2, ref3); cref2 = get_refcount((IUnknown *)clipper); - todo_wine ok(cref2 > cref1, "expected cref2 > cref1, got cref1 = %u , cref2 = %u.\n", cref1, cref2); + ok(cref2 > cref1, "expected cref2 > cref1, got cref1 = %u , cref2 = %u.\n", cref1, cref2); /* Fetch immediate mode device in order to access render target */ hr = IDirect3DRMDevice3_GetDirect3DDevice2(device3, &d3ddevice2);