This section of the archives stores flipcode's complete Developer Toolbox collection, featuring a variety of mini-articles and source code contributions from our readers.

| Simple X File Wrapper For Loading Data Submitted by

This is my first post to COTD, in fact its my first post to Flipcode ever. Ok, I recently wrote a small proof of concept application and in doing so I needed to load models from Microsofts X flies. After working with the API directly for about a day I found it very redundant and not easy to manage so I went about creating a wrapper to make my life and everyone elses a bit easier. Im not going to explain how X Files are structured here, just briefly how to use my wrapper. This implementation only deals with loading data from a preexisting .x files and does not address saving data. The XFile object makes dealing with X files similar to using a stacks and lists. Data objects are pushed and popped and siblings of the current element are then iterated in order via next. X files do not allow reverse iteration so once a push, pop, or next action is executed there is no going back. Initially, the XFiles current data object is invalid (similar to an iterator pointing to end() ). To iterate through root frames use the NextRoot function, after the first call the XFile is set to the first root data object. The push operations leave the current data object invalid ( again similar to an iterator pointing to end() ). In order to access these child data objects the NextSibling function must be called, after a call to push, NextSibling moves to the first child data object. All other operations are performed on the current data object ( if valid ).
Below are some simple functions that iterate an X file using the XFile wrapper object.

    bool Loader::Init(void *pvSource)
    {
    XFile *pTemp = new XFile;
           pTemp-Create(pvSource,

    reinterpret_cast<const void*(g_pszPEXFileTemplates),
    strlen(g_pszPEXFileTemplates);
           m_pXFile = pTemp;
    }

    void Loader::LoadToWorld(WorldTree *pWorldTree, WorldFrame *pRootFrame)
    {
           m_pWorldTree = pWorldTree;

           if(NULL == pRootFrame)
                  pRootFrame = pWorldTree-RootFrame();

    //     Loop through all the root frames in the file
           while(m_pXFile-NextRoot())
           {
                  LoadFrame(pRootFrame);
           }
    }

    void Loader::LoadFrame(WorldFrame *pFrame)
    {
    //     Load the data
           WorldFrame *pCurrentFrame = LoadData(pFrame);

    //     Move to the frame data
           if(m_pXFile-Push())
           {
    //     iterate through the children

                  while(m_pXFile-NextSibling())
                  {
                         LoadFrame(pCurrentFrame);
                  }
                  m_pXFile-Pop();
           }
    }

    WorldFrame* Loader::LoadData(WorldFrame *pFrame)
    {
           if(m_pXFile-IsCurrent(TID_D3DRMHeader))
           {
           }
    else if(m_pXFile-IsCurrent(XFTID(Frame)))
    {
    //            return the new child frame

    }
    else if(m_pXFile-IsCurrent(TID_D3DRMFrameTransformMatrix))
           {
    //     load some data, in this case the frame transform matrix

                  D3DXMATRIX    *pMatrix;
    m_pXFile-GetFloatArray("frameMatrix", reinterpret_cast <float*&(pMatrix));
                  pFrame-SetTransform(*pMatrix);
           }
    //     else if
    }

In order to compile the XFile object you will need to replace the two macros D3DEX and PEASSERT as I dont provide the implementations. Also, the CD3DInterfacePtr will need to be replaced with some other auto COM pointer, the ATL COM pointer should work fine.

Currently browsing [XFile.zip] (4,226 bytes) - [XFile.h] - (4,078 bytes)

    // XFile.h: interface for the XFile class.
    //
    //////////////////////////////////////////////////////////////////////

    #if !defined(AFX_XFILE_H__BF50AAEB_41CA_4AE1_A190_CD5B82531E93__INCLUDED_)
    #define AFX_XFILE_H__BF50AAEB_41CA_4AE1_A190_CD5B82531E93__INCLUDED_

    #if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000

    #include <D3d8.h>
    #include <Dxfile.h>
    #include <list>

    //	GUIDs not defined by the DirectX RM headers

    // {3d82ab43-62da-11cf-ab39-0020af71e433}
    DEFINE_GUID(TID_D3DRMHeader,
    0x3d82ab43, 0x62da, 0x11cf, 0xab, 0x39, 0x00, 0x20, 0xaf, 0x71, 0xe4, 0x33);

    // {<10DD46A3-775B-11cf-8F52-0040333594A3>}
    DEFINE_GUID(TID_D3DRMQuaternion,
    0x10DD46A3, 0x775B, 0x11cf, 0x8F, 0x52, 0x00, 0x40, 0x33, 0x35, 0x94, 0xA3);

    // {<A3EB5D44-FC22-429D-9AFB-3221CB9719A6>}
    DEFINE_GUID(TID_D3DRMPatch,
    0xA3EB5D44, 0xFC22, 0x429D, 0x9A, 0xFB, 0x32, 0x21, 0xCB, 0x97, 0x19, 0xA6);

    // {<D02C95CC-EDBA-4305-9B5D-1820D7704BBF>}
    DEFINE_GUID(TID_D3DRMPatchMesh,
    0xD02C95CC, 0xEDBA, 0x4305, 0x9B, 0x5D, 0x18, 0x20, 0xD7, 0x70, 0x4B, 0xBF);

    // {<B8D65549-D7C9-4995-89CF-53A9A8B031E3>}
    DEFINE_GUID(TID_D3DRMVertexDuplicationIndices,
    0xB8D65549, 0xD7C9, 0x4995, 0x89, 0xCF, 0x53, 0xA9, 0xA8, 0xB0, 0x31, 0xE3);

    // {<3CF169CE-FF7C-44ab-93C0-F78F62D172E2>}
    DEFINE_GUID(TID_D3DRMXSkinMeshHeader,
    0x3CF169CE, 0xFF7C, 0x44ab, 0x93, 0xC0, 0xF7, 0x8F, 0x62, 0xD1, 0x72, 0xE2);

    // {<6F0D123B-BAD2-4167-A0D0-80224F25FABB>}
    DEFINE_GUID(TID_D3DRMSkinWeights,
    0x6F0D123B, 0xBAD2, 0x4167, 0xA0, 0xD0, 0x80, 0x22, 0x4F, 0x25, 0xFA, 0xBB);

    struct __declspec(uuid("3d82ab45-62da-11cf-ab39-0020af71e433")) IDirectXFileDataReference;
    struct __declspec(uuid("3d82ab44-62da-11cf-ab39-0020af71e433")) IDirectXFileData;

    //	You will need to replace these with some other auto COM ptr
    //	the ATL one sould work
    typedef CD3DInterfacePtr<IDirectXFile>				IDirectXFilePtr;
    typedef CD3DInterfacePtr<IDirectXFileEnumObject>	IDirectXFileEnumObjectPtr;
    typedef CD3DInterfacePtr<IDirectXFileData>			IDirectXFileDataPtr;
    typedef CD3DInterfacePtr<IDirectXFileObject>		IDirectXFileObjectPtr;
    typedef CD3DInterfacePtr<IDirectXFileDataReference>	IDirectXFileDataReferencePtr;
    typedef CD3DInterfacePtr<IDirectXFileBinary>		IDirectXFileBinaryPtr;

    class XFile
    {
    	typedef std::list<IDirectXFileDataPtr>	flie_data_stack;

    	IDirectXFilePtr				m_pXFile;
    	IDirectXFileEnumObjectPtr	m_pEnumObject;
    	IDirectXFileDataPtr			m_pCurrentObject;
    	flie_data_stack				m_stackFileData;
    	const GUID					*m_pCurrentType;

    public:
    	struct coords2d
    	{
    		float u;
    		float v;
    	};
    	struct meshface
    	{
    		DWORD	nFaceVertexIndices;
    		DWORD	pFaceVertexIndices[3];
    	};

    	XFile();
    	virtual ~XFile();
    	void Create(void *pvSource, const void *pvTemplate = NULL,
    			DWORD dwTemplateSize = 0, DWORD dwLoadFlags = DXFILELOAD_FROMFILE,
    			bool bLoadTemplatesFromFile = false,
    			bool bUseStandardTemplates = true);
    //	iteration
    	bool Push();
    	bool Pop();
    	bool NextSibling();
    	bool NextRoot();

    //	identification
    	bool IsCurrent(REFGUID refGuid);
    	bool CurrentType(GUID &refGuid);
    	bool CurrentID(GUID &refGuid);
    	bool CurrentName(std::string &strName);

    //	data retrieval
    	bool GetString(LPCSTR szName, char *&pszName);
    	bool GetStringArray(LPCSTR szName, char **&ppszName);
    	bool GetDword(LPCSTR szName, DWORD &dwData);
    	bool GetDwordArray(LPCSTR szName, DWORD *&pDWArray);
    	bool GetFloat(LPCSTR szName, float &fData);
    	bool GetFloatArray(LPCSTR szName, float *&pFArray);
    	bool GetVector3(LPCSTR szName, D3DVECTOR &vecVector3);
    	bool GetVector3Array(LPCSTR szName, D3DVECTOR *&pVectors);
    	bool GetColorRGBA(LPCSTR szName, D3DCOLORVALUE &rgbColorRGBA);
    	bool GetFaceArray(LPCSTR szName, meshface *&pFaces);
    	bool Get2DTextureCoordArray(LPCSTR szName, coords2d *&pCoords);

    //	utility
    	IDirectXFileDataPtr& CurrentDataObject(void);

    protected:
    	bool GetChildDataObject(IDirectXFileDataPtr &pDataObject,
    							const IDirectXFileDataPtr & pFileObject);

    };

    #endif //!defined(AFX_XFILE_H__BF50AAEB_41CA_4AE1_A190_CD5B82531E93__INCLUDED_)

Currently browsing [XFile.zip] (4,226 bytes) - [XFile.cpp] - (13,732 bytes)

    // XFile.cpp: implementation of the XFile class.
    //
    //////////////////////////////////////////////////////////////////////

    #include "stdafx.h"
    #include <rmxftmpl.h>
    #include <initguid.h>
    #include "..\INCLUDE\XFile.h"

    #ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endif

    //	error macros I use, sorry no sorce 8p
    //	replace with anything you like
    #define D3DEX(_h_result_)		_h_result_
    #define PEASSERT(_eval_)

    //////////////////////////////////////////////////////////////////////
    // Construction/Destruction
    //////////////////////////////////////////////////////////////////////

    XFile::XFile()
    : m_pCurrentType(NULL)
    {
    }

    XFile::~XFile()
    {
    }

    ///////////////////////////////////////////////////////////////////////////////
    // Function name	: XFile::Create
    // Description	    : Initializes the XFile object and sets up iteration
    // Return type		: void
    // Argument         : void *pvSource   :pointer to source file name or raw data
    // Argument         : void *pvTemplate :pointer to template file name or data
    // Argument         : DWORD dwTemplateSize :size of template data in bytes
    // Argument         : DWORD dwLoadFlags :pvSource data type flag
    // Argument         : bool bLoadTemplatesFromFile :pvTemplate data type flag
    //
    void XFile::Create(void *pvSource, const void *pvTemplate /*= NULL*/,
    				   DWORD dwTemplateSize /*= 0*/,
    				   DWORD dwLoadFlags /*= DXFILELOAD_FROMFILE*/,
    				   bool bLoadTemplatesFromFile /*= false*/,
    				   bool bUseStandardTemplates /*= true*/)
    {
    	IDirectXFilePtr				pXFile;
    	IDirectXFileEnumObjectPtr	pEnumObject;

    //	Create the XFile object interface
    	D3DEX(DirectXFileCreate(&pXFile.Interface()));

    //	Register the standard templates
    	if(bUseStandardTemplates)
    		D3DEX(pXFile->RegisterTemplates((VOID*)D3DRM_XTEMPLATES,
    										D3DRM_XTEMPLATE_BYTES));

    //	If there are custom templates try to load them
    	if(NULL != pvTemplate)
    	{
    		if(bLoadTemplatesFromFile)
    		{
    // Not supported yet, pvTemplate should be file name, path, stream or something
    			PEASSERT(bLoadTemplatesFromFile == true);
    		}
    		else
    		{
    			D3DEX(pXFile->RegisterTemplates(const_cast<void*>(pvTemplate),
    											dwTemplateSize));
    		}
    	}

    //	Now create the enum object
    	D3DEX(pXFile->CreateEnumObject(pvSource, dwLoadFlags,
    								   &pEnumObject.Interface()))
    	m_pXFile = pXFile;
    	m_pEnumObject = pEnumObject;
    }

    ///////////////////////////////////////////////////////////////////////////////
    // Function name	: XFile::Push
    // Description	    : Moves iteration to children of current opbjec
    // Return type		: bool
    //
    bool XFile::Push()
    {
    	bool bRet = false;

    	if(m_pCurrentObject)
    	{
    		m_stackFileData.push_back(m_pCurrentObject);
    		m_pCurrentType = NULL;
    		m_pCurrentObject = NULL;
    		bRet = true;
    	}

    	return bRet;
    }

    ///////////////////////////////////////////////////////////////////////////////
    // Function name	: XFile::Pop
    // Description	    : Moves iteration to parent of current object
    // Return type		: bool
    //
    bool XFile::Pop()
    {
    	bool bRet = false;

    	if(!m_stackFileData.empty())
    	{
    		m_pCurrentObject = m_stackFileData.back();
    		m_stackFileData.pop_back();
    		D3DEX(m_pCurrentObject->GetType(&m_pCurrentType));
    		bRet = true;
    	}

    	return bRet;
    }

    ///////////////////////////////////////////////////////////////////////////////
    // Function name	: XFile::NextSibling
    // Description	    : Moves iteration to next sibling object
    // Return type		: bool
    //
    bool XFile::NextSibling()
    {
    	bool bRet = false;

    	if(!m_stackFileData.empty())
    	{
    		IDirectXFileDataPtr pChild;

    		if(GetChildDataObject(pChild, m_stackFileData.back()))
    		{
    			m_pCurrentObject = pChild;
    			D3DEX(m_pCurrentObject->GetType(&m_pCurrentType));
    			bRet = true;
    		}
    	}
    	return bRet;
    }

    ///////////////////////////////////////////////////////////////////////////////
    // Function name	: XFile::NextRoot
    // Description	    : Moves iteration to next root object
    // Return type		: bool
    //
    bool XFile::NextRoot()
    {
    	IDirectXFileDataPtr pRoot;
    	HRESULT	hr;

    	m_stackFileData.clear();
    	m_pCurrentObject = NULL;
    	m_pCurrentType = NULL;

    	if(SUCCEEDED(hr = m_pEnumObject->GetNextDataObject(&pRoot.Interface())))
    	{
    		if(FAILED(hr = pRoot.QueryInterface(m_pCurrentObject)))
    		{
    			IDirectXFileDataReferencePtr	pReference;
    			if(SUCCEEDED(hr = pRoot.QueryInterface(pReference)))
    			{
    				D3DEX(pReference->Resolve(&m_pCurrentObject.Interface()));
    				pReference = NULL;
    			}
    		}

    	}

    	if(SUCCEEDED(hr))
    	{
    		m_pCurrentObject->GetType(&m_pCurrentType);
    	}
    	return SUCCEEDED(hr);
    }

    ///////////////////////////////////////////////////////////////////////////////
    // Function name	: XFile::IsCurrent
    // Description	    : Compares type of current object
    // Return type		: bool
    // Argument         : REFGUID rGuid
    //
    bool XFile::IsCurrent(REFGUID rGuid)
    {
    	PEASSERT(m_pCurrentType);
    	return NULL != m_pCurrentType && IsEqualGUID(rGuid, *m_pCurrentType);
    }

    ///////////////////////////////////////////////////////////////////////////////
    // Function name	: XFile::CurrentType
    // Description	    : Gets the current objects GUID
    // Return type		: bool
    // Argument         : GUID & refGuid
    //
    bool XFile::CurrentType(GUID & refGuid)
    {
    	if(m_pCurrentType)
    		refGuid = *m_pCurrentType;

    	return NULL != m_pCurrentType;
    }

    ///////////////////////////////////////////////////////////////////////////////
    // Function name	: XFile::CurrentID
    // Description	    : Gets the current objects ID
    // Return type		: bool
    // Argument         : GUID &refGuid
    //
    bool XFile::CurrentID(GUID &refGuid)
    {
    	if(!m_pCurrentObject)
    		D3DEX(m_pCurrentObject->GetId(&refGuid));

    	return !m_stackFileData.empty();
    }

    ///////////////////////////////////////////////////////////////////////////////
    // Function name	: XFile::CurrentName
    // Description	    : Gets the current objects name
    // Return type		: bool
    // Argument         : std::string &strName
    //
    bool XFile::CurrentName(std::string &strName)
    {
    	DWORD	dwLen;
    	if(m_pCurrentObject)
    	{
    		m_pCurrentObject->GetName(NULL, &dwLen);
    		strName.resize(dwLen);
    		D3DEX(m_pCurrentObject->GetName(&strName[0], &dwLen));
    	}
    	return 0 != strName.size();
    }

    IDirectXFileDataPtr& XFile::CurrentDataObject(void)
    {
    	return m_pCurrentObject;
    }

    ///////////////////////////////////////////////////////////////////////////////
    // Function name	: XFile::GetString
    // Description	    : Gets a string value
    // Return type		: bool
    // Argument         : LPCSTR szName
    // Argument         : char *&pszName
    //
    bool XFile::GetString(LPCSTR szName, char *&pszName)
    {
    	DWORD	dwSize = 0;
    	char	**ppString;
    	HRESULT	hr;

    	if(SUCCEEDED( hr = m_pCurrentObject->GetData(szName, &dwSize,
    									reinterpret_cast<void**>(&ppString))) )
    		pszName = *ppString;

    	PEASSERT(SUCCEEDED(hr));
    	return SUCCEEDED(hr);
    }

    ///////////////////////////////////////////////////////////////////////////////
    // Function name	: XFile::GetStringArray
    // Description	    : Gets an array of string values
    // Return type		: bool
    // Argument         : LPCSTR szName
    // Argument         : char **&ppszName
    //
    bool XFile::GetStringArray(LPCSTR szName, char **&ppszName)
    {
    	DWORD	dwSize = 0;
    	char	**ppString;
    	HRESULT	hr = m_pCurrentObject->GetData(szName, &dwSize,
    									reinterpret_cast<void**>(&ppString));
    	ppszName = ppString;
    	PEASSERT(SUCCEEDED(hr));
    	return SUCCEEDED(hr);
    }

    ///////////////////////////////////////////////////////////////////////////////
    // Function name	: XFile::GetDword
    // Description	    : Gets a DWORD value
    // Return type		: bool
    // Argument         : LPCSTR szName
    // Argument         : DWORD &dwData
    //
    bool XFile::GetDword(LPCSTR szName, DWORD &dwData)
    {
    	DWORD	*pDWORD;
    	DWORD	dwSize;
    	HRESULT	hr = m_pCurrentObject->GetData(szName, &dwSize,
    										reinterpret_cast<void**>(&pDWORD));
    	if(SUCCEEDED(hr) && sizeof(DWORD) == dwSize)
    		dwData = *pDWORD;
    	else
    		PEASSERT(SUCCEEDED(hr) && sizeof(DWORD) == dwSize);

    	return SUCCEEDED(hr);
    }

    ///////////////////////////////////////////////////////////////////////////////
    // Function name	: XFile::GetDwordArray
    // Description	    : Gets an array of DWORD values
    // Return type		: bool
    // Argument         : LPCSTR szName
    // Argument         : DWORD *&pDWArray
    //
    bool XFile::GetDwordArray(LPCSTR szName, DWORD *&pDWArray)
    {
    	DWORD	dwSize;
    	HRESULT	hr = m_pCurrentObject->GetData(szName, &dwSize,
    										reinterpret_cast<void**>(&pDWArray));
    	PEASSERT(SUCCEEDED(hr) && 0 == dwSize % sizeof(DWORD));
    	return SUCCEEDED(hr);
    }

    ///////////////////////////////////////////////////////////////////////////////
    // Function name	: XFile::GetFloat
    // Description	    : Gets a float value
    // Return type		: bool
    // Argument         : LPCSTR szName
    // Argument         : float &fData
    //
    bool XFile::GetFloat(LPCSTR szName, float &fData)
    {
    	float	*pFloat;
    	DWORD	dwSize;
    	HRESULT	hr = m_pCurrentObject->GetData(szName, &dwSize,
    										reinterpret_cast<void**>(&pFloat));
    	if(SUCCEEDED(hr) && sizeof(float) == dwSize)
    		fData = *pFloat;
    	else
    		PEASSERT(SUCCEEDED(hr) && sizeof(float) == dwSize);

    	return SUCCEEDED(hr);
    }

    ///////////////////////////////////////////////////////////////////////////////
    // Function name	: XFile::GetFloatArray
    // Description	    : Gets an array of float values
    // Return type		: bool
    // Argument         : LPCSTR szName
    // Argument         : float *&pFArray
    //
    bool XFile::GetFloatArray(LPCSTR szName, float *&pFArray)
    {
    	DWORD	dwSize;
    	HRESULT	hr = m_pCurrentObject->GetData(szName, &dwSize,
    										reinterpret_cast<void**>(&pFArray));
    	PEASSERT(SUCCEEDED(hr) && 0 == dwSize % sizeof(float));
    	return SUCCEEDED(hr);
    }

    ///////////////////////////////////////////////////////////////////////////////
    // Function name	: XFile::GetVector3
    // Description	    : Gets a 3 component vector
    // Return type		: bool
    // Argument         : LPCSTR szName
    // Argument         : D3DVECTOR &vecVector
    //
    bool XFile::GetVector3(LPCSTR szName, D3DVECTOR &vecVector)
    {
    	D3DVECTOR *pVec;
    	DWORD	dwSize;
    	HRESULT	hr = m_pCurrentObject->GetData(szName, &dwSize,
    											reinterpret_cast<void**>(&pVec));
    	PEASSERT(SUCCEEDED(hr) && dwSize ==  sizeof(D3DVECTOR));
    	vecVector = *pVec;
    	return SUCCEEDED(hr);
    }

    ///////////////////////////////////////////////////////////////////////////////
    // Function name	: XFile::GetVector3Array
    // Description	    : Gets an array of 3 component vectors
    // Return type		: bool
    // Argument         : LPCSTR szName
    // Argument         : D3DVECTOR *&pVectors
    //
    bool XFile::GetVector3Array(LPCSTR szName, D3DVECTOR *&pVectors)
    {
    	DWORD	dwSize;
    	HRESULT	hr = m_pCurrentObject->GetData(szName, &dwSize,
    										reinterpret_cast<void**>(&pVectors));
    	PEASSERT(SUCCEEDED(hr) && 0 == dwSize % sizeof(D3DVECTOR));
    	return SUCCEEDED(hr);
    }

    ///////////////////////////////////////////////////////////////////////////////
    // Function name	: XFile::GetColorRGBA
    // Description	    : Gets an RGBA color value
    // Return type		: bool
    // Argument         : LPCSTR szName
    // Argument         : D3DCOLORVALUE &rgbColorRGBA
    //
    bool XFile::GetColorRGBA(LPCSTR szName, D3DCOLORVALUE &rgbColorRGBA)
    {
    	D3DCOLORVALUE *pColor;
    	DWORD	dwSize;
    	HRESULT	hr = m_pCurrentObject->GetData(szName, &dwSize,
    										reinterpret_cast<void**>(&pColor));
    	PEASSERT(SUCCEEDED(hr) && dwSize == sizeof(D3DCOLORVALUE));
    	rgbColorRGBA = *pColor;
    	return SUCCEEDED(hr);
    }

    ///////////////////////////////////////////////////////////////////////////////
    // Function name	: XFile::GetFaceArray
    // Description	    : Gets an array of faces
    // Return type		: bool
    // Argument         : LPCSTR szName
    // Argument         : meshface *&pFaces
    //
    bool XFile::GetFaceArray(LPCSTR szName, meshface *&pFaces)
    {
    	DWORD	dwSize;
    	HRESULT	hr = m_pCurrentObject->GetData(szName, &dwSize,
    										reinterpret_cast<void**>(&pFaces));
    	PEASSERT(SUCCEEDED(hr) && 0 == dwSize % sizeof(meshface));
    	return SUCCEEDED(hr);
    }

    ///////////////////////////////////////////////////////////////////////////////
    // Function name	: XFile::Get2DTextureCoordArray
    // Description	    : Gets an array of 2D texture coords
    // Return type		: bool
    // Argument         : LPCSTR szName
    // Argument         : coords2d *&pCoords
    //
    bool XFile::Get2DTextureCoordArray(LPCSTR szName, coords2d *&pCoords)
    {
    	DWORD	dwSize;
    	HRESULT	hr = m_pCurrentObject->GetData(szName, &dwSize,
    										reinterpret_cast<void**>(&pCoords));
    	PEASSERT(SUCCEEDED(hr) && 0 == dwSize % sizeof(coords2d));
    	return SUCCEEDED(hr);
    }

    ///////////////////////////////////////////////////////////////////////////////
    // Function name	: XFile::GetChildDataObject
    // Description	    : Gets the next child data object
    // Return type		: bool
    // Argument         : IDirectXFileDataPtr &pDataObject
    // Argument         : const IDirectXFileDataPtr & pFileObject
    //
    bool XFile::GetChildDataObject(IDirectXFileDataPtr &pDataObject,
    							   const IDirectXFileDataPtr & pFileObject)
    {
    	HRESULT	hr;
    	IDirectXFileObjectPtr	pChildObject;

    	if(SUCCEEDED(hr = pFileObject->GetNextObject(&pChildObject.Interface())))
    	{
    		if(FAILED(hr = pChildObject.QueryInterface(pDataObject)))
    		{
    			IDirectXFileDataReferencePtr	pReference;
    			if(SUCCEEDED(hr = pChildObject.QueryInterface(pReference)))
    			{
    				D3DEX(pReference->Resolve(&pDataObject.Interface()));
    				pReference = NULL;
    			}
    			else
    				PEASSERT(false);
    		}
    	}
    	return SUCCEEDED(hr);
    }

The zip file viewer built into the Developer Toolbox made use of the zlib library, as well as the zlibdll source additions.

Copyright 1999-2008 (C) FLIPCODE.COM and/or the original content author(s). All rights reserved.
Please read our Terms, Conditions, and Privacy information.