[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