From 499736490500d19670d1212b04ecbdbfc2b362d9 Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Fri, 9 Jun 2017 02:36:48 +0300 Subject: [PATCH] d3drm: Make it possible to create faces with CreateObject(). Signed-off-by: Nikolay Sivov Signed-off-by: Henri Verbeet Signed-off-by: Alexandre Julliard --- dlls/d3drm/d3drm.c | 40 ++++++++++++++++++++++++++++++--- dlls/d3drm/d3drm_private.h | 10 ++++++++- dlls/d3drm/face.c | 46 +++++++++++++++++++------------------- dlls/d3drm/meshbuilder.c | 20 +++++++++++++++-- dlls/d3drm/tests/d3drm.c | 18 +++++++++++++++ 5 files changed, 105 insertions(+), 29 deletions(-) diff --git a/dlls/d3drm/d3drm.c b/dlls/d3drm/d3drm.c index 31564364a53..f6c64a2483f 100644 --- a/dlls/d3drm/d3drm.c +++ b/dlls/d3drm/d3drm.c @@ -84,6 +84,19 @@ static HRESULT d3drm_create_viewport_object(void **object, IDirect3DRM *d3drm) return hr; } +static HRESULT d3drm_create_face_object(void **object, IDirect3DRM *d3drm) +{ + struct d3drm_face *face; + HRESULT hr; + + if (FAILED(hr = d3drm_face_create(&face))) + return hr; + + *object = &face->IDirect3DRMFace_iface; + + return hr; +} + struct d3drm { IDirect3DRM IDirect3DRM_iface; @@ -214,9 +227,17 @@ static HRESULT WINAPI d3drm1_CreateMeshBuilder(IDirect3DRM *iface, IDirect3DRMMe static HRESULT WINAPI d3drm1_CreateFace(IDirect3DRM *iface, IDirect3DRMFace **face) { + struct d3drm_face *object; + HRESULT hr; + TRACE("iface %p, face %p.\n", iface, face); - return Direct3DRMFace_create(&IID_IDirect3DRMFace, (IUnknown **)face); + if (FAILED(hr = d3drm_face_create(&object))) + return hr; + + *face = &object->IDirect3DRMFace_iface; + + return S_OK; } static HRESULT WINAPI d3drm1_CreateAnimation(IDirect3DRM *iface, IDirect3DRMAnimation **animation) @@ -734,9 +755,11 @@ static HRESULT WINAPI d3drm2_CreateMeshBuilder(IDirect3DRM2 *iface, IDirect3DRMM static HRESULT WINAPI d3drm2_CreateFace(IDirect3DRM2 *iface, IDirect3DRMFace **face) { + struct d3drm *d3drm = impl_from_IDirect3DRM2(iface); + TRACE("iface %p, face %p.\n", iface, face); - return Direct3DRMFace_create(&IID_IDirect3DRMFace, (IUnknown **)face); + return IDirect3DRM_CreateFace(&d3drm->IDirect3DRM_iface, face); } static HRESULT WINAPI d3drm2_CreateAnimation(IDirect3DRM2 *iface, IDirect3DRMAnimation **animation) @@ -1208,6 +1231,7 @@ static HRESULT WINAPI d3drm3_CreateObject(IDirect3DRM3 *iface, {&CLSID_CDirect3DRMTexture, d3drm_create_texture_object}, {&CLSID_CDirect3DRMDevice, d3drm_create_device_object}, {&CLSID_CDirect3DRMViewport, d3drm_create_viewport_object}, + {&CLSID_CDirect3DRMFace, d3drm_create_face_object}, }; TRACE("iface %p, clsid %s, outer %p, iid %s, out %p.\n", @@ -1288,9 +1312,19 @@ static HRESULT WINAPI d3drm3_CreateMeshBuilder(IDirect3DRM3 *iface, IDirect3DRMM static HRESULT WINAPI d3drm3_CreateFace(IDirect3DRM3 *iface, IDirect3DRMFace2 **face) { + struct d3drm *d3drm = impl_from_IDirect3DRM3(iface); + IDirect3DRMFace *face1; + HRESULT hr; + TRACE("iface %p, face %p.\n", iface, face); - return Direct3DRMFace_create(&IID_IDirect3DRMFace2, (IUnknown **)face); + if (FAILED(hr = IDirect3DRM_CreateFace(&d3drm->IDirect3DRM_iface, &face1))) + return hr; + + hr = IDirect3DRMFace_QueryInterface(face1, &IID_IDirect3DRMFace2, (void **)face); + IDirect3DRMFace_Release(face1); + + return hr; } static HRESULT WINAPI d3drm3_CreateAnimation(IDirect3DRM3 *iface, IDirect3DRMAnimation2 **animation) diff --git a/dlls/d3drm/d3drm_private.h b/dlls/d3drm/d3drm_private.h index 84cac686859..d53d4cde948 100644 --- a/dlls/d3drm/d3drm_private.h +++ b/dlls/d3drm/d3drm_private.h @@ -112,6 +112,14 @@ struct d3drm_device DWORD width; }; +struct d3drm_face +{ + struct d3drm_object obj; + IDirect3DRMFace IDirect3DRMFace_iface; + IDirect3DRMFace2 IDirect3DRMFace2_iface; + LONG ref; +}; + HRESULT d3drm_device_create(struct d3drm_device **device, IDirect3DRM *d3drm) DECLSPEC_HIDDEN; HRESULT d3drm_device_create_surfaces_from_clipper(struct d3drm_device *object, IDirectDraw *ddraw, IDirectDrawClipper *clipper, int width, int height, IDirectDrawSurface **surface) DECLSPEC_HIDDEN; @@ -130,8 +138,8 @@ struct d3drm_device *unsafe_impl_from_IDirect3DRMDevice3(IDirect3DRMDevice3 *ifa HRESULT d3drm_texture_create(struct d3drm_texture **texture, IDirect3DRM *d3drm) DECLSPEC_HIDDEN; HRESULT d3drm_frame_create(struct d3drm_frame **frame, IUnknown *parent_frame, IDirect3DRM *d3drm) DECLSPEC_HIDDEN; +HRESULT d3drm_face_create(struct d3drm_face **face) DECLSPEC_HIDDEN; HRESULT d3drm_viewport_create(struct d3drm_viewport **viewport, IDirect3DRM *d3drm) DECLSPEC_HIDDEN; -HRESULT Direct3DRMFace_create(REFIID riid, IUnknown** ret_iface) DECLSPEC_HIDDEN; HRESULT Direct3DRMLight_create(IUnknown** ppObj) DECLSPEC_HIDDEN; HRESULT Direct3DRMMesh_create(IDirect3DRMMesh** obj) DECLSPEC_HIDDEN; HRESULT Direct3DRMMeshBuilder_create(REFIID riid, IUnknown** ppObj) DECLSPEC_HIDDEN; diff --git a/dlls/d3drm/face.c b/dlls/d3drm/face.c index 65db1d06a9a..326314b8b07 100644 --- a/dlls/d3drm/face.c +++ b/dlls/d3drm/face.c @@ -25,14 +25,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3drm); -struct d3drm_face -{ - struct d3drm_object obj; - IDirect3DRMFace IDirect3DRMFace_iface; - IDirect3DRMFace2 IDirect3DRMFace2_iface; - LONG ref; -}; - static inline struct d3drm_face *impl_from_IDirect3DRMFace(IDirect3DRMFace *iface) { return CONTAINING_RECORD(iface, struct d3drm_face, IDirect3DRMFace_iface); @@ -49,8 +41,8 @@ static HRESULT WINAPI d3drm_face1_QueryInterface(IDirect3DRMFace *iface, REFIID TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out); - if (IsEqualGUID(riid, &IID_IDirect3DRMFace) + || IsEqualGUID(riid, &IID_IDirect3DRMObject) || IsEqualGUID(riid, &IID_IUnknown)) { *out = &face->IDirect3DRMFace_iface; @@ -88,7 +80,10 @@ static ULONG WINAPI d3drm_face1_Release(IDirect3DRMFace *iface) TRACE("%p decreasing refcount to %u.\n", iface, refcount); if (!refcount) + { + d3drm_object_cleanup((IDirect3DRMObject *)iface, &face->obj); HeapFree(GetProcessHeap(), 0, face); + } return refcount; } @@ -104,17 +99,21 @@ static HRESULT WINAPI d3drm_face1_Clone(IDirect3DRMFace *iface, static HRESULT WINAPI d3drm_face1_AddDestroyCallback(IDirect3DRMFace *iface, D3DRMOBJECTCALLBACK cb, void *ctx) { - FIXME("iface %p, cb %p, ctx %p stub!\n", iface, cb, ctx); + struct d3drm_face *face = impl_from_IDirect3DRMFace(iface); - return E_NOTIMPL; + TRACE("iface %p, cb %p, ctx %p.\n", iface, cb, ctx); + + return IDirect3DRMFace2_AddDestroyCallback(&face->IDirect3DRMFace2_iface, cb, ctx); } static HRESULT WINAPI d3drm_face1_DeleteDestroyCallback(IDirect3DRMFace *iface, D3DRMOBJECTCALLBACK cb, void *ctx) { - FIXME("iface %p, cb %p, ctx %p stub!\n", iface, cb, ctx); + struct d3drm_face *face = impl_from_IDirect3DRMFace(iface); - return E_NOTIMPL; + TRACE("iface %p, cb %p, ctx %p.\n", iface, cb, ctx); + + return IDirect3DRMFace2_DeleteDestroyCallback(&face->IDirect3DRMFace2_iface, cb, ctx); } static HRESULT WINAPI d3drm_face1_SetAppData(IDirect3DRMFace *iface, DWORD data) @@ -360,17 +359,21 @@ static HRESULT WINAPI d3drm_face2_Clone(IDirect3DRMFace2 *iface, static HRESULT WINAPI d3drm_face2_AddDestroyCallback(IDirect3DRMFace2 *iface, D3DRMOBJECTCALLBACK cb, void *ctx) { - FIXME("iface %p, cb %p, ctx %p stub!\n", iface, cb, ctx); + struct d3drm_face *face = impl_from_IDirect3DRMFace2(iface); - return E_NOTIMPL; + TRACE("iface %p, cb %p, ctx %p.\n", iface, cb, ctx); + + return d3drm_object_add_destroy_callback(&face->obj, cb, ctx); } static HRESULT WINAPI d3drm_face2_DeleteDestroyCallback(IDirect3DRMFace2 *iface, D3DRMOBJECTCALLBACK cb, void *ctx) { - FIXME("iface %p, cb %p, ctx %p stub!\n", iface, cb, ctx); + struct d3drm_face *face = impl_from_IDirect3DRMFace2(iface); - return E_NOTIMPL; + TRACE("iface %p, cb %p, ctx %p.\n", iface, cb, ctx); + + return d3drm_object_delete_destroy_callback(&face->obj, cb, ctx); } static HRESULT WINAPI d3drm_face2_SetAppData(IDirect3DRMFace2 *iface, DWORD data) @@ -583,12 +586,12 @@ static const struct IDirect3DRMFace2Vtbl d3drm_face2_vtbl = d3drm_face2_GetColor, }; -HRESULT Direct3DRMFace_create(REFIID riid, IUnknown **out) +HRESULT d3drm_face_create(struct d3drm_face **face) { static const char classname[] = "Face"; struct d3drm_face *object; - TRACE("riid %s, out %p.\n", debugstr_guid(riid), out); + TRACE("face %p.\n", face); if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) return E_OUTOFMEMORY; @@ -599,10 +602,7 @@ HRESULT Direct3DRMFace_create(REFIID riid, IUnknown **out) d3drm_object_init(&object->obj, classname); - if (IsEqualGUID(riid, &IID_IDirect3DRMFace2)) - *out = (IUnknown*)&object->IDirect3DRMFace2_iface; - else - *out = (IUnknown*)&object->IDirect3DRMFace_iface; + *face = object; return S_OK; } diff --git a/dlls/d3drm/meshbuilder.c b/dlls/d3drm/meshbuilder.c index 647520defb1..5be217c71d8 100644 --- a/dlls/d3drm/meshbuilder.c +++ b/dlls/d3drm/meshbuilder.c @@ -823,9 +823,17 @@ static int WINAPI d3drm_mesh_builder2_AddNormal(IDirect3DRMMeshBuilder2 *iface, static HRESULT WINAPI d3drm_mesh_builder2_CreateFace(IDirect3DRMMeshBuilder2 *iface, IDirect3DRMFace **face) { + struct d3drm_face *object; + HRESULT hr; + TRACE("iface %p, face %p.\n", iface, face); - return Direct3DRMFace_create(&IID_IDirect3DRMFace, (IUnknown **)face); + if (FAILED(hr = d3drm_face_create(&object))) + return hr; + + *face = &object->IDirect3DRMFace_iface; + + return S_OK; } static D3DRMRENDERQUALITY WINAPI d3drm_mesh_builder2_GetQuality(IDirect3DRMMeshBuilder2 *iface) @@ -1933,9 +1941,17 @@ static int WINAPI d3drm_mesh_builder3_AddNormal(IDirect3DRMMeshBuilder3 *iface, static HRESULT WINAPI d3drm_mesh_builder3_CreateFace(IDirect3DRMMeshBuilder3 *iface, IDirect3DRMFace2 **face) { + struct d3drm_face *object; + HRESULT hr; + TRACE("iface %p, face %p.\n", iface, face); - return Direct3DRMFace_create(&IID_IDirect3DRMFace2, (IUnknown **)face); + if (FAILED(hr = d3drm_face_create(&object))) + return hr; + + *face = &object->IDirect3DRMFace2_iface; + + return S_OK; } static D3DRMRENDERQUALITY WINAPI d3drm_mesh_builder3_GetQuality(IDirect3DRMMeshBuilder3 *iface) diff --git a/dlls/d3drm/tests/d3drm.c b/dlls/d3drm/tests/d3drm.c index da5656ee381..e244751612f 100644 --- a/dlls/d3drm/tests/d3drm.c +++ b/dlls/d3drm/tests/d3drm.c @@ -699,6 +699,7 @@ static void test_Face(void) IDirect3DRMMeshBuilder2 *MeshBuilder2; IDirect3DRMMeshBuilder3 *MeshBuilder3; IDirect3DRMFace *face1; + IDirect3DRMObject *obj; IDirect3DRMFace2 *face2; IDirect3DRMFaceArray *array1; D3DRMLOADMEMORY info; @@ -718,6 +719,11 @@ static void test_Face(void) return; } + hr = IDirect3DRMFace_QueryInterface(face1, &IID_IDirect3DRMObject, (void **)&obj); + ok(SUCCEEDED(hr), "Failed to get IDirect3DRMObject, %#x.\n", hr); + ok(obj == (IDirect3DRMObject *)face1, "Unexpected interface pointer.\n"); + IDirect3DRMObject_Release(obj); + test_class_name((IDirect3DRMObject *)face1, "Face"); icount = IDirect3DRMFace_GetVertexCount(face1); @@ -789,6 +795,16 @@ static void test_Face(void) hr = IDirect3DRMMeshBuilder3_CreateFace(MeshBuilder3, &face2); ok(hr == D3DRM_OK, "Cannot get IDirect3DRMFace2 interface (hr = %x)\n", hr); + hr = IDirect3DRMFace2_QueryInterface(face2, &IID_IDirect3DRMObject, (void **)&obj); + ok(SUCCEEDED(hr), "Failed to get IDirect3DRMObject, %#x.\n", hr); + + hr = IDirect3DRMFace2_QueryInterface(face2, &IID_IDirect3DRMFace, (void **)&face1); + ok(SUCCEEDED(hr), "Failed to get IDirect3DRMObject, %#x.\n", hr); + ok(obj == (IDirect3DRMObject *)face1, "Unexpected interface pointer.\n"); + + IDirect3DRMFace_Release(face1); + IDirect3DRMObject_Release(obj); + test_class_name((IDirect3DRMObject *)face2, "Face"); icount = IDirect3DRMMeshBuilder3_GetFaceCount(MeshBuilder3); @@ -1405,6 +1421,8 @@ static void test_object(void) { &CLSID_CDirect3DRMTexture, &IID_IDirect3DRMTexture3, FALSE }, { &CLSID_CDirect3DRMViewport, &IID_IDirect3DRMViewport, FALSE }, { &CLSID_CDirect3DRMViewport, &IID_IDirect3DRMViewport2, FALSE }, + { &CLSID_CDirect3DRMFace, &IID_IDirect3DRMFace }, + { &CLSID_CDirect3DRMFace, &IID_IDirect3DRMFace2 }, }; IDirect3DRM *d3drm1; IDirect3DRM2 *d3drm2;