[PATCH 2/3] d3drm: Make it possible to create mesh builder with CreateObject()

Nikolay Sivov nsivov at codeweavers.com
Thu Jun 8 18:36:49 CDT 2017


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/d3drm/d3drm.c         | 40 ++++++++++++++++++++++++++---
 dlls/d3drm/d3drm_private.h | 29 ++++++++++++++++++++-
 dlls/d3drm/meshbuilder.c   | 63 +++++++++++++++++-----------------------------
 dlls/d3drm/tests/d3drm.c   | 21 +++++++++++++---
 4 files changed, 106 insertions(+), 47 deletions(-)

diff --git a/dlls/d3drm/d3drm.c b/dlls/d3drm/d3drm.c
index f6c64a2483..2b4e87c1ec 100644
--- a/dlls/d3drm/d3drm.c
+++ b/dlls/d3drm/d3drm.c
@@ -97,6 +97,19 @@ static HRESULT d3drm_create_face_object(void **object, IDirect3DRM *d3drm)
     return hr;
 }
 
+static HRESULT d3drm_create_mesh_builder_object(void **object, IDirect3DRM *d3drm)
+{
+    struct d3drm_mesh_builder *mesh_builder;
+    HRESULT hr;
+
+    if (FAILED(hr = d3drm_mesh_builder_create(&mesh_builder, d3drm)))
+        return hr;
+
+    *object = &mesh_builder->IDirect3DRMMeshBuilder2_iface;
+
+    return hr;
+}
+
 struct d3drm
 {
     IDirect3DRM IDirect3DRM_iface;
@@ -220,9 +233,11 @@ static HRESULT WINAPI d3drm1_CreateMesh(IDirect3DRM *iface, IDirect3DRMMesh **me
 
 static HRESULT WINAPI d3drm1_CreateMeshBuilder(IDirect3DRM *iface, IDirect3DRMMeshBuilder **mesh_builder)
 {
+    struct d3drm *d3drm = impl_from_IDirect3DRM(iface);
+
     TRACE("iface %p, mesh_builder %p.\n", iface, mesh_builder);
 
-    return Direct3DRMMeshBuilder_create(&IID_IDirect3DRMMeshBuilder, (IUnknown **)mesh_builder);
+    return IDirect3DRM2_CreateMeshBuilder(&d3drm->IDirect3DRM2_iface, (IDirect3DRMMeshBuilder2 **)mesh_builder);
 }
 
 static HRESULT WINAPI d3drm1_CreateFace(IDirect3DRM *iface, IDirect3DRMFace **face)
@@ -748,9 +763,18 @@ static HRESULT WINAPI d3drm2_CreateMesh(IDirect3DRM2 *iface, IDirect3DRMMesh **m
 
 static HRESULT WINAPI d3drm2_CreateMeshBuilder(IDirect3DRM2 *iface, IDirect3DRMMeshBuilder2 **mesh_builder)
 {
+    struct d3drm *d3drm = impl_from_IDirect3DRM2(iface);
+    struct d3drm_mesh_builder *object;
+    HRESULT hr;
+
     TRACE("iface %p, mesh_builder %p.\n", iface, mesh_builder);
 
-    return Direct3DRMMeshBuilder_create(&IID_IDirect3DRMMeshBuilder2, (IUnknown **)mesh_builder);
+    if (FAILED(hr = d3drm_mesh_builder_create(&object, &d3drm->IDirect3DRM_iface)))
+        return hr;
+
+    *mesh_builder = &object->IDirect3DRMMeshBuilder2_iface;
+
+    return S_OK;
 }
 
 static HRESULT WINAPI d3drm2_CreateFace(IDirect3DRM2 *iface, IDirect3DRMFace **face)
@@ -1232,6 +1256,7 @@ static HRESULT WINAPI d3drm3_CreateObject(IDirect3DRM3 *iface,
         {&CLSID_CDirect3DRMDevice, d3drm_create_device_object},
         {&CLSID_CDirect3DRMViewport, d3drm_create_viewport_object},
         {&CLSID_CDirect3DRMFace, d3drm_create_face_object},
+        {&CLSID_CDirect3DRMMeshBuilder, d3drm_create_mesh_builder_object},
     };
 
     TRACE("iface %p, clsid %s, outer %p, iid %s, out %p.\n",
@@ -1305,9 +1330,18 @@ static HRESULT WINAPI d3drm3_CreateMesh(IDirect3DRM3 *iface, IDirect3DRMMesh **m
 
 static HRESULT WINAPI d3drm3_CreateMeshBuilder(IDirect3DRM3 *iface, IDirect3DRMMeshBuilder3 **mesh_builder)
 {
+    struct d3drm *d3drm = impl_from_IDirect3DRM3(iface);
+    struct d3drm_mesh_builder *object;
+    HRESULT hr;
+
     TRACE("iface %p, mesh_builder %p.\n", iface, mesh_builder);
 
-    return Direct3DRMMeshBuilder_create(&IID_IDirect3DRMMeshBuilder3, (IUnknown **)mesh_builder);
+    if (FAILED(hr = d3drm_mesh_builder_create(&object, &d3drm->IDirect3DRM_iface)))
+        return hr;
+
+    *mesh_builder = &object->IDirect3DRMMeshBuilder3_iface;
+
+    return S_OK;
 }
 
 static HRESULT WINAPI d3drm3_CreateFace(IDirect3DRM3 *iface, IDirect3DRMFace2 **face)
diff --git a/dlls/d3drm/d3drm_private.h b/dlls/d3drm/d3drm_private.h
index d53d4cde94..f78200d5f0 100644
--- a/dlls/d3drm/d3drm_private.h
+++ b/dlls/d3drm/d3drm_private.h
@@ -120,6 +120,33 @@ struct d3drm_face
     LONG ref;
 };
 
+struct d3drm_mesh_builder
+{
+    struct d3drm_object obj;
+    IDirect3DRMMeshBuilder2 IDirect3DRMMeshBuilder2_iface;
+    IDirect3DRMMeshBuilder3 IDirect3DRMMeshBuilder3_iface;
+    LONG ref;
+    IDirect3DRM *d3drm;
+    char* name;
+    SIZE_T nb_vertices;
+    SIZE_T vertices_size;
+    D3DVECTOR *vertices;
+    SIZE_T nb_normals;
+    SIZE_T normals_size;
+    D3DVECTOR *normals;
+    DWORD nb_faces;
+    DWORD face_data_size;
+    void *pFaceData;
+    DWORD nb_coords2d;
+    struct coords_2d *pCoords2d;
+    D3DCOLOR color;
+    IDirect3DRMMaterial2 *material;
+    IDirect3DRMTexture3 *texture;
+    DWORD nb_materials;
+    struct mesh_material *materials;
+    DWORD *material_indices;
+};
+
 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;
@@ -140,9 +167,9 @@ HRESULT d3drm_texture_create(struct d3drm_texture **texture, IDirect3DRM *d3drm)
 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 d3drm_mesh_builder_create(struct d3drm_mesh_builder **mesh_builder, IDirect3DRM *d3drm) 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;
 HRESULT Direct3DRMMaterial_create(IDirect3DRMMaterial2** ret_iface) DECLSPEC_HIDDEN;
 
 HRESULT load_mesh_data(IDirect3DRMMeshBuilder3 *iface, IDirectXFileData *data,
diff --git a/dlls/d3drm/meshbuilder.c b/dlls/d3drm/meshbuilder.c
index 5be217c71d..eda068ce08 100644
--- a/dlls/d3drm/meshbuilder.c
+++ b/dlls/d3drm/meshbuilder.c
@@ -62,32 +62,6 @@ struct mesh_material
     IDirect3DRMTexture3 *texture;
 };
 
-struct d3drm_mesh_builder
-{
-    struct d3drm_object obj;
-    IDirect3DRMMeshBuilder2 IDirect3DRMMeshBuilder2_iface;
-    IDirect3DRMMeshBuilder3 IDirect3DRMMeshBuilder3_iface;
-    LONG ref;
-    char* name;
-    SIZE_T nb_vertices;
-    SIZE_T vertices_size;
-    D3DVECTOR *vertices;
-    SIZE_T nb_normals;
-    SIZE_T normals_size;
-    D3DVECTOR *normals;
-    DWORD nb_faces;
-    DWORD face_data_size;
-    void *pFaceData;
-    DWORD nb_coords2d;
-    struct coords_2d *pCoords2d;
-    D3DCOLOR color;
-    IDirect3DRMMaterial2 *material;
-    IDirect3DRMTexture3 *texture;
-    DWORD nb_materials;
-    struct mesh_material *materials;
-    DWORD *material_indices;
-};
-
 char templates[] = {
 "xof 0302txt 0064"
 "template Header"
@@ -439,11 +413,13 @@ static ULONG WINAPI d3drm_mesh_builder2_Release(IDirect3DRMMeshBuilder2 *iface)
 
     if (!refcount)
     {
+        d3drm_object_cleanup((IDirect3DRMObject *)iface, &mesh_builder->obj);
         clean_mesh_builder_data(mesh_builder);
         if (mesh_builder->material)
             IDirect3DRMMaterial2_Release(mesh_builder->material);
         if (mesh_builder->texture)
             IDirect3DRMTexture3_Release(mesh_builder->texture);
+        IDirect3DRM_Release(mesh_builder->d3drm);
         HeapFree(GetProcessHeap(), 0, mesh_builder);
     }
 
@@ -461,17 +437,21 @@ static HRESULT WINAPI d3drm_mesh_builder2_Clone(IDirect3DRMMeshBuilder2 *iface,
 static HRESULT WINAPI d3drm_mesh_builder2_AddDestroyCallback(IDirect3DRMMeshBuilder2 *iface,
         D3DRMOBJECTCALLBACK cb, void *ctx)
 {
-    FIXME("iface %p, cb %p, ctx %p stub!\n", iface, cb, ctx);
+    struct d3drm_mesh_builder *mesh_builder = impl_from_IDirect3DRMMeshBuilder2(iface);
 
-    return E_NOTIMPL;
+    TRACE("iface %p, cb %p, ctx %p.\n", iface, cb, ctx);
+
+    return IDirect3DRMMeshBuilder3_AddDestroyCallback(&mesh_builder->IDirect3DRMMeshBuilder3_iface, cb, ctx);
 }
 
 static HRESULT WINAPI d3drm_mesh_builder2_DeleteDestroyCallback(IDirect3DRMMeshBuilder2 *iface,
         D3DRMOBJECTCALLBACK cb, void *ctx)
 {
-    FIXME("iface %p, cb %p, ctx %p stub!\n", iface, cb, ctx);
+    struct d3drm_mesh_builder *mesh_builder = impl_from_IDirect3DRMMeshBuilder2(iface);
 
-    return E_NOTIMPL;
+    TRACE("iface %p, cb %p, ctx %p.\n", iface, cb, ctx);
+
+    return IDirect3DRMMeshBuilder3_DeleteDestroyCallback(&mesh_builder->IDirect3DRMMeshBuilder3_iface, cb, ctx);
 }
 
 static HRESULT WINAPI d3drm_mesh_builder2_SetAppData(IDirect3DRMMeshBuilder2 *iface, DWORD data)
@@ -993,17 +973,21 @@ static HRESULT WINAPI d3drm_mesh_builder3_Clone(IDirect3DRMMeshBuilder3 *iface,
 static HRESULT WINAPI d3drm_mesh_builder3_AddDestroyCallback(IDirect3DRMMeshBuilder3 *iface,
         D3DRMOBJECTCALLBACK cb, void *ctx)
 {
-    FIXME("iface %p, cb %p, ctx %p stub!\n", iface, cb, ctx);
+    struct d3drm_mesh_builder *mesh_builder = impl_from_IDirect3DRMMeshBuilder3(iface);
 
-    return E_NOTIMPL;
+    TRACE("iface %p, cb %p, ctx %p.\n", iface, cb, ctx);
+
+    return d3drm_object_add_destroy_callback(&mesh_builder->obj, cb, ctx);
 }
 
 static HRESULT WINAPI d3drm_mesh_builder3_DeleteDestroyCallback(IDirect3DRMMeshBuilder3 *iface,
         D3DRMOBJECTCALLBACK cb, void *ctx)
 {
-    FIXME("iface %p, cb %p, ctx %p stub!\n", iface, cb, ctx);
+    struct d3drm_mesh_builder *mesh_builder = impl_from_IDirect3DRMMeshBuilder3(iface);
 
-    return E_NOTIMPL;
+    TRACE("iface %p, cb %p, ctx %p.\n", iface, cb, ctx);
+
+    return d3drm_object_delete_destroy_callback(&mesh_builder->obj, cb, ctx);
 }
 
 static HRESULT WINAPI d3drm_mesh_builder3_SetAppData(IDirect3DRMMeshBuilder3 *iface, DWORD data)
@@ -2386,12 +2370,12 @@ static const struct IDirect3DRMMeshBuilder3Vtbl d3drm_mesh_builder3_vtbl =
     d3drm_mesh_builder3_GetNormalCount,
 };
 
-HRESULT Direct3DRMMeshBuilder_create(REFIID riid, IUnknown **out)
+HRESULT d3drm_mesh_builder_create(struct d3drm_mesh_builder **mesh_builder, IDirect3DRM *d3drm)
 {
     static const char classname[] = "Builder";
     struct d3drm_mesh_builder *object;
 
-    TRACE("riid %s, out %p.\n", debugstr_guid(riid), out);
+    TRACE("mesh_builder %p.\n", mesh_builder);
 
     if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
         return E_OUTOFMEMORY;
@@ -2399,13 +2383,12 @@ HRESULT Direct3DRMMeshBuilder_create(REFIID riid, IUnknown **out)
     object->IDirect3DRMMeshBuilder2_iface.lpVtbl = &d3drm_mesh_builder2_vtbl;
     object->IDirect3DRMMeshBuilder3_iface.lpVtbl = &d3drm_mesh_builder3_vtbl;
     object->ref = 1;
+    object->d3drm = d3drm;
+    IDirect3DRM_AddRef(object->d3drm);
 
     d3drm_object_init(&object->obj, classname);
 
-    if (IsEqualGUID(riid, &IID_IDirect3DRMMeshBuilder3))
-        *out = (IUnknown *)&object->IDirect3DRMMeshBuilder3_iface;
-    else
-        *out = (IUnknown *)&object->IDirect3DRMMeshBuilder2_iface;
+    *mesh_builder = object;
 
     return S_OK;
 }
diff --git a/dlls/d3drm/tests/d3drm.c b/dlls/d3drm/tests/d3drm.c
index e244751612..ccbc9a62d7 100644
--- a/dlls/d3drm/tests/d3drm.c
+++ b/dlls/d3drm/tests/d3drm.c
@@ -1423,6 +1423,9 @@ static void test_object(void)
         { &CLSID_CDirect3DRMViewport,      &IID_IDirect3DRMViewport2,    FALSE },
         { &CLSID_CDirect3DRMFace,          &IID_IDirect3DRMFace },
         { &CLSID_CDirect3DRMFace,          &IID_IDirect3DRMFace2 },
+        { &CLSID_CDirect3DRMMeshBuilder,   &IID_IDirect3DRMMeshBuilder },
+        { &CLSID_CDirect3DRMMeshBuilder,   &IID_IDirect3DRMMeshBuilder2 },
+        { &CLSID_CDirect3DRMMeshBuilder,   &IID_IDirect3DRMMeshBuilder3 },
     };
     IDirect3DRM *d3drm1;
     IDirect3DRM2 *d3drm2;
@@ -1446,6 +1449,8 @@ static void test_object(void)
 
     for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
     {
+        BOOL takes_ref = IsEqualGUID(tests[i].clsid, &CLSID_CDirect3DRMMeshBuilder);
+
         unknown = (IUnknown *)0xdeadbeef;
         hr = IDirect3DRM_CreateObject(d3drm1, NULL, NULL, tests[i].iid, (void **)&unknown);
         ok(hr == D3DRMERR_BADVALUE, "Test %u: expected hr == D3DRMERR_BADVALUE, got %#x.\n", i, hr);
@@ -1463,7 +1468,11 @@ static void test_object(void)
         if (SUCCEEDED(hr))
         {
             ref2 = get_refcount((IUnknown *)d3drm1);
-            ok(ref2 == ref1, "Test %u: expected ref2 == ref1, got ref1 = %u, ref2 = %u.\n", i, ref1, ref2);
+            if (takes_ref)
+                ok(ref2 == ref1 + 1, "Test %u: expected ref2 == ref1 + 1, got ref1 = %u, ref2 = %u.\n", i, ref1, ref2);
+            else
+                ok(ref2 == ref1, "Test %u: expected ref2 == ref1, got ref1 = %u, ref2 = %u.\n", i, ref1, ref2);
+
             ref3 = get_refcount((IUnknown *)d3drm2);
             ok(ref3 == ref1, "Test %u: expected ref3 == ref1, got ref1 = %u, ref3 = %u.\n", i, ref1, ref3);
             ref4 = get_refcount((IUnknown *)d3drm3);
@@ -1482,7 +1491,10 @@ static void test_object(void)
             hr = IDirect3DRM2_CreateObject(d3drm2, tests[i].clsid, NULL, tests[i].iid, (void **)&unknown);
             ok(SUCCEEDED(hr), "Test %u: expected hr == D3DRM_OK, got %#x.\n", i, hr);
             ref2 = get_refcount((IUnknown *)d3drm1);
-            ok(ref2 == ref1, "Test %u: expected ref2 == ref1, got ref1 = %u, ref2 = %u.\n", i, ref1, ref2);
+            if (takes_ref)
+                ok(ref2 == ref1 + 1, "Test %u: expected ref2 == ref1 + 1, got ref1 = %u, ref2 = %u.\n", i, ref1, ref2);
+            else
+                ok(ref2 == ref1, "Test %u: expected ref2 == ref1, got ref1 = %u, ref2 = %u.\n", i, ref1, ref2);
             ref3 = get_refcount((IUnknown *)d3drm2);
             ok(ref3 == ref1, "Test %u: expected ref3 == ref1, got ref1 = %u, ref3 = %u.\n", i, ref1, ref3);
             ref4 = get_refcount((IUnknown *)d3drm3);
@@ -1498,7 +1510,10 @@ static void test_object(void)
             hr = IDirect3DRM3_CreateObject(d3drm3, tests[i].clsid, NULL, tests[i].iid, (void **)&unknown);
             ok(SUCCEEDED(hr), "Test %u: expected hr == D3DRM_OK, got %#x.\n", i, hr);
             ref2 = get_refcount((IUnknown *)d3drm1);
-            ok(ref2 == ref1, "Test %u: expected ref2 == ref1, got ref1 = %u, ref2 = %u.\n", i, ref1, ref2);
+            if (takes_ref)
+                ok(ref2 == ref1 + 1, "Test %u: expected ref2 == ref1 + 1, got ref1 = %u, ref2 = %u.\n", i, ref1, ref2);
+            else
+                ok(ref2 == ref1, "Test %u: expected ref2 == ref1, got ref1 = %u, ref2 = %u.\n", i, ref1, ref2);
             ref3 = get_refcount((IUnknown *)d3drm2);
             ok(ref3 == ref1, "Test %u: expected ref3 == ref1, got ref1 = %u, ref3 = %u.\n", i, ref1, ref3);
             ref4 = get_refcount((IUnknown *)d3drm3);
-- 
2.11.0




More information about the wine-patches mailing list