[PATCH 2/2] d3drm: Partial implementation of IDirec3DRM:Load method + tests.

Christian Costa titan.costa at gmail.com
Mon Mar 26 15:07:40 CDT 2012


---
 dlls/d3drm/d3drm.c       |  233 +++++++++++++++++++++++++++++++++++++++++++++-
 dlls/d3drm/tests/d3drm.c |   56 +++++++++++
 2 files changed, 283 insertions(+), 6 deletions(-)

diff --git a/dlls/d3drm/d3drm.c b/dlls/d3drm/d3drm.c
index d140c08..8523b8c 100644
--- a/dlls/d3drm/d3drm.c
+++ b/dlls/d3drm/d3drm.c
@@ -25,11 +25,31 @@
 
 #include "winbase.h"
 #include "wingdi.h"
+#include "dxfile.h"
+#include "rmxfguid.h"
 
 #include "d3drm_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3drm);
 
+static const char* get_IID_string(const GUID* guid)
+{
+    if (IsEqualGUID(guid, &IID_IDirect3DRMFrame))
+        return "IID_IDirect3DRMFrame";
+    else if (IsEqualGUID(guid, &IID_IDirect3DRMFrame2))
+        return "IID_IDirect3DRMFrame2";
+    else if (IsEqualGUID(guid, &IID_IDirect3DRMFrame3))
+        return "IID_IDirect3DRMFrame3";
+    else if (IsEqualGUID(guid, &IID_IDirect3DRMMeshBuilder))
+        return "IID_IDirect3DRMMeshBuilder";
+    else if (IsEqualGUID(guid, &IID_IDirect3DRMMeshBuilder2))
+        return "IID_IDirect3DRMMeshBuilder2";
+    else if (IsEqualGUID(guid, &IID_IDirect3DRMMeshBuilder3))
+        return "IID_IDirect3DRMMeshBuilder3";
+
+    return "?";
+}
+
 typedef struct {
     IDirect3DRM IDirect3DRM_iface;
     IDirect3DRM2 IDirect3DRM2_iface;
@@ -387,10 +407,19 @@ static HRESULT WINAPI IDirect3DRMImpl_EnumerateObjects(IDirect3DRM* iface, D3DRM
 static HRESULT WINAPI IDirect3DRMImpl_Load(IDirect3DRM* iface, LPVOID pObjSource, LPVOID pObjID, LPIID * ppGUIDs, DWORD nb_GUIDs, D3DRMLOADOPTIONS LOFlags, D3DRMLOADCALLBACK LoadProc, LPVOID pArgLP, D3DRMLOADTEXTURECALLBACK LoadTextureProc, LPVOID pArgLTP, LPDIRECT3DRMFRAME pParentFrame)
 {
     IDirect3DRMImpl *This = impl_from_IDirect3DRM(iface);
+    LPDIRECT3DRMFRAME3 pParentFrame3 = NULL;
+    HRESULT hr = D3DRM_OK;
 
-    FIXME("(%p/%p)->(%p,%p,%p,%d,%d,%p,%p,%p,%p,%p): stub\n", iface, This, pObjSource, pObjID, ppGUIDs, nb_GUIDs, LOFlags, LoadProc, pArgLP, LoadTextureProc, pArgLTP, pParentFrame);
+    TRACE("(%p/%p)->(%p,%p,%p,%d,%d,%p,%p,%p,%p,%p): forwarding to IDirect3DRM3\n", iface, This, pObjSource, pObjID, ppGUIDs, nb_GUIDs, LOFlags, LoadProc, pArgLP, LoadTextureProc, pArgLTP, pParentFrame);
 
-    return E_NOTIMPL;
+    if (pParentFrame)
+        hr = IDirect3DRMFrame_QueryInterface(pParentFrame, &IID_IDirect3DRMFrame3, (void**)&pParentFrame3);
+    if (SUCCEEDED(hr))
+        hr = IDirect3DRM3_Load(&This->IDirect3DRM3_iface, pObjSource, pObjID, ppGUIDs, nb_GUIDs, LOFlags, LoadProc, pArgLP, LoadTextureProc, pArgLTP, pParentFrame3);
+    if (pParentFrame3)
+        IDirect3DRMFrame3_Release(pParentFrame3);
+
+    return hr;
 }
 
 static HRESULT WINAPI IDirect3DRMImpl_Tick(IDirect3DRM* iface, D3DVALUE tick)
@@ -796,11 +825,20 @@ static HRESULT WINAPI IDirect3DRM2Impl_Load(IDirect3DRM2* iface, LPVOID pObjSour
                                             LPVOID pArgLTP, LPDIRECT3DRMFRAME pParentFrame)
 {
     IDirect3DRMImpl *This = impl_from_IDirect3DRM2(iface);
+    LPDIRECT3DRMFRAME3 pParentFrame3 = NULL;
+    HRESULT hr = D3DRM_OK;
 
-    FIXME("(%p/%p)->(%p,%p,%p,%d,%d,%p,%p,%p,%p,%p): stub\n", iface, This, pObjSource, pObjID,
+    TRACE("(%p/%p)->(%p,%p,%p,%d,%d,%p,%p,%p,%p,%p): forwarding to IDirect3DRM3\n", iface, This, pObjSource, pObjID,
           ppGUIDs, nb_GUIDs, LOFlags, LoadProc, pArgLP, LoadTextureProc, pArgLTP, pParentFrame);
 
-    return E_NOTIMPL;
+    if (pParentFrame)
+        hr = IDirect3DRMFrame_QueryInterface(pParentFrame, &IID_IDirect3DRMFrame3, (void**)&pParentFrame3);
+    if (SUCCEEDED(hr))
+        hr = IDirect3DRM3_Load(&This->IDirect3DRM3_iface, pObjSource, pObjID, ppGUIDs, nb_GUIDs, LOFlags, LoadProc, pArgLP, LoadTextureProc, pArgLTP, pParentFrame3);
+    if (pParentFrame3)
+        IDirect3DRMFrame3_Release(pParentFrame3);
+
+    return hr;
 }
 
 static HRESULT WINAPI IDirect3DRM2Impl_Tick(IDirect3DRM2* iface, D3DVALUE tick)
@@ -1214,10 +1252,193 @@ static HRESULT WINAPI IDirect3DRM3Impl_Load(IDirect3DRM3* iface, LPVOID ObjSourc
                                             LPDIRECT3DRMFRAME3 ParentFrame)
 {
     IDirect3DRMImpl *This = impl_from_IDirect3DRM3(iface);
-
-    FIXME("(%p/%p)->(%p,%p,%p,%d,%d,%p,%p,%p,%p,%p): stub\n", iface, This, ObjSource, ObjID, GUIDs,
+    DXFILELOADOPTIONS load_options;
+    LPDIRECTXFILE pDXFile = NULL;
+    LPDIRECTXFILEENUMOBJECT pEnumObject = NULL;
+    LPDIRECTXFILEDATA pData = NULL;
+    HRESULT hr;
+    const GUID* pGuid;
+    DWORD size;
+    Header* pHeader;
+    HRESULT ret = D3DRMERR_BADOBJECT;
+    DWORD i;
+
+    FIXME("(%p/%p)->(%p,%p,%p,%d,%d,%p,%p,%p,%p,%p): partial stub\n", iface, This, ObjSource, ObjID, GUIDs,
           nb_GUIDs, LOFlags, LoadProc, ArgLP, LoadTextureProc, ArgLTP, ParentFrame);
 
+    TRACE("Looking for GUIDs:\n");
+    for (i = 0; i < nb_GUIDs; i++)
+        TRACE("- %s (%s)\n", debugstr_guid(GUIDs[i]), get_IID_string(GUIDs[i]));
+
+    if (LOFlags == D3DRMLOAD_FROMMEMORY)
+    {
+        load_options = DXFILELOAD_FROMMEMORY;
+    }
+    else if (LOFlags == D3DRMLOAD_FROMFILE)
+    {
+        load_options = DXFILELOAD_FROMFILE;
+    }
+    else
+    {
+        FIXME("Load options %d not supported yet\n", LOFlags);
+        return E_NOTIMPL;
+    }
+
+    hr = DirectXFileCreate(&pDXFile);
+    if (hr != DXFILE_OK)
+        goto end;
+
+    hr = IDirectXFile_RegisterTemplates(pDXFile, templates, strlen(templates));
+    if (hr != DXFILE_OK)
+        goto end;
+
+    hr = IDirectXFile_CreateEnumObject(pDXFile, ObjSource, load_options, &pEnumObject);
+    if (hr != DXFILE_OK)
+        goto end;
+
+    hr = IDirectXFileEnumObject_GetNextDataObject(pEnumObject, &pData);
+    if (hr != DXFILE_OK)
+        goto end;
+
+    hr = IDirectXFileData_GetType(pData, &pGuid);
+    if (hr != DXFILE_OK)
+        goto end;
+
+    TRACE("Found object type whose GUID = %s\n", debugstr_guid(pGuid));
+
+    if (!IsEqualGUID(pGuid, &TID_DXFILEHeader))
+    {
+        ret = D3DRMERR_BADFILE;
+        goto end;
+    }
+
+    hr = IDirectXFileData_GetData(pData, NULL, &size, (void**)&pHeader);
+    if ((hr != DXFILE_OK) || (size != sizeof(Header)))
+        goto end;
+
+    TRACE("Version is %d %d %d\n", pHeader->major, pHeader->minor, pHeader->flags);
+
+    /* Version must be 1.0.x */
+    if ((pHeader->major != 1) || (pHeader->minor != 0))
+    {
+        ret = D3DRMERR_BADFILE;
+        goto end;
+    }
+
+    IDirectXFileData_Release(pData);
+    pData = NULL;
+
+    while (1)
+    {
+        hr = IDirectXFileEnumObject_GetNextDataObject(pEnumObject, &pData);
+        if (hr == DXFILEERR_NOMOREOBJECTS)
+        {
+            TRACE("No more object\n");
+            break;
+        }
+        else if (hr != DXFILE_OK)
+        {
+            ret = D3DRMERR_NOTFOUND;
+            goto end;
+        }
+
+        hr = IDirectXFileData_GetType(pData, &pGuid);
+        if (hr != DXFILE_OK)
+            goto end;
+
+        TRACE("Found object type whose GUID = %s\n", debugstr_guid(pGuid));
+
+        if (IsEqualGUID(pGuid, &TID_D3DRMMesh))
+        {
+            BOOL requested = FALSE;
+            HRESULT hr;
+            LPDIRECT3DRMMESHBUILDER3 pMeshBuilder;
+
+            TRACE("Found TID_D3DRMMesh\n");
+
+            for (i = 0; i < nb_GUIDs; i++)
+                if (IsEqualGUID(GUIDs[i], &IID_IDirect3DRMMeshBuilder) ||
+                    IsEqualGUID(GUIDs[i], &IID_IDirect3DRMMeshBuilder2) ||
+                    IsEqualGUID(GUIDs[i], &IID_IDirect3DRMMeshBuilder3))
+                    requested = TRUE;
+
+            if (requested)
+            {
+                FIXME("Load mesh data and notify application\n");
+
+                hr = IDirect3DRM3_CreateMeshBuilder(iface, &pMeshBuilder);
+                if (SUCCEEDED(hr))
+                {
+                    LPDIRECT3DRMMESHBUILDER3 pMeshBuilder3;
+
+                    hr = IDirect3DRMMeshBuilder3_QueryInterface(pMeshBuilder, &IID_IDirect3DRMMeshBuilder3, (void**)&pMeshBuilder3);
+                    if (SUCCEEDED(hr))
+                    {
+                        hr = load_mesh_data(pMeshBuilder3, pData);
+                        IDirect3DRMMeshBuilder3_Release(pMeshBuilder3);
+                    }
+                    if (SUCCEEDED(hr))
+                        LoadProc((LPDIRECT3DRMOBJECT)pMeshBuilder3, &IID_IDirect3DRMMeshBuilder, ArgLP);
+                    IDirect3DRMMeshBuilder_Release(pMeshBuilder3);
+                }
+
+                if (FAILED(hr))
+                    ERR("Cannot process mesh\n");
+            }
+        }
+        else if (IsEqualGUID(pGuid, &TID_D3DRMFrame))
+        {
+            BOOL requested = FALSE;
+
+            TRACE("Found TID_D3DRMFrame\n");
+
+            for (i = 0; i < nb_GUIDs; i++)
+                if (IsEqualGUID(GUIDs[i], &IID_IDirect3DRMFrame) ||
+                    IsEqualGUID(GUIDs[i], &IID_IDirect3DRMFrame2) ||
+                    IsEqualGUID(GUIDs[i], &IID_IDirect3DRMFrame3))
+                    requested = TRUE;
+
+            if (requested)
+            {
+                FIXME("Processing frame not supported yet\n");
+            }
+        }
+        else if (IsEqualGUID(pGuid, &TID_D3DRMMaterial))
+        {
+            BOOL requested = FALSE;
+
+            TRACE("Found TID_D3DRMMaterial\n");
+
+            for (i = 0; i < nb_GUIDs; i++)
+                if (IsEqualGUID(GUIDs[i], &IID_IDirect3DRMMaterial) ||
+                    IsEqualGUID(GUIDs[i], &IID_IDirect3DRMMaterial2))
+                    requested = TRUE;
+
+            if (requested)
+            {
+                FIXME("Processing material not supported yet\n");
+            }
+        }
+        else
+        {
+            FIXME("Found unknown TID %s\n", debugstr_guid(pGuid));
+        }
+        IDirectXFileData_Release(pData);
+        pData = NULL;
+    }
+
+    ret = D3DRM_OK;
+
+end:
+    if (pData)
+        IDirectXFileData_Release(pData);
+    if (pEnumObject)
+        IDirectXFileEnumObject_Release(pEnumObject);
+    if (pDXFile)
+        IDirectXFile_Release(pDXFile);
+
+    return ret;
+
     return E_NOTIMPL;
 }
 
diff --git a/dlls/d3drm/tests/d3drm.c b/dlls/d3drm/tests/d3drm.c
index a1dee30..8d18d3b 100644
--- a/dlls/d3drm/tests/d3drm.c
+++ b/dlls/d3drm/tests/d3drm.c
@@ -134,6 +134,27 @@ static char data_full[] =
 " }\n"
 "}\n";
 
+static char data_d3drm_load[] =
+"xof 0302txt 0064\n"
+"Header Object\n"
+"{\n"
+"1; 0; 1;\n"
+"}\n"
+"Mesh Object1\n"
+"{\n"
+" 1;\n"
+" 0.1; 0.2; 0.3;,\n"
+" 1;\n"
+" 3; 0, 1, 2;;\n"
+"}\n"
+"Mesh Object2\n"
+"{\n"
+" 1;\n"
+" 0.1; 0.2; 0.3;,\n"
+" 1;\n"
+" 3; 0, 1, 2;;\n"
+"}\n";
+
 static void test_MeshBuilder(void)
 {
     HRESULT hr;
@@ -579,6 +600,40 @@ static void test_Frame(void)
     IDirect3DRM_Release(pD3DRM);
 }
 
+static int nb_objects = 0;
+static const GUID* refiids[] =
+{
+    &IID_IDirect3DRMMeshBuilder,
+    &IID_IDirect3DRMMeshBuilder
+};
+
+void __cdecl object_load_callback(LPDIRECT3DRMOBJECT object, REFIID objectguid, LPVOID arg)
+{
+    ok(object != NULL, "Arg 1 should not be null\n");
+    ok(IsEqualGUID(objectguid, refiids[nb_objects]), "Arg 2 should is incorrect\n");
+    ok(arg == (LPVOID)0xdeadbeef, "Arg 3 should be 0xdeadbeef (got %p)\n", arg);
+    nb_objects++;
+}
+
+static void test_d3drm_load(void)
+{
+    HRESULT hr;
+    LPDIRECT3DRM pD3DRM;
+    D3DRMLOADMEMORY info;
+    const GUID* req_refiids[] = { &IID_IDirect3DRMMeshBuilder };
+
+    hr = pDirect3DRMCreate(&pD3DRM);
+    ok(hr == D3DRM_OK, "Cannot get IDirect3DRM interface (hr = %x)\n", hr);
+
+    info.lpMemory = data_d3drm_load;
+    info.dSize = strlen(data_d3drm_load);
+    hr = IDirect3DRM_Load(pD3DRM, &info, NULL, (GUID**)req_refiids, 1, D3DRMLOAD_FROMMEMORY, object_load_callback, (LPVOID)0xdeadbeef, NULL, NULL, NULL);
+    ok(hr == D3DRM_OK, "Cannot load data (hr = %x)\n", hr);
+    ok(nb_objects == 2, "Should have loaded 2 objects (got %d)\n", nb_objects);
+
+    IDirect3DRM_Release(pD3DRM);
+}
+
 START_TEST(d3drm)
 {
     if (!InitFunctionPtrs())
@@ -587,6 +642,7 @@ START_TEST(d3drm)
     test_MeshBuilder();
     test_MeshBuilder3();
     test_Frame();
+    test_d3drm_load();
 
     FreeLibrary(d3drm_handle);
 }




More information about the wine-patches mailing list