/*=========================================================================== * * File: Dfarchdt.CPP * Author: Dave Humphrey (uesp@m0use.net) * Created On: Friday, June 29, 2001 * * Contains the primary CDFArch3D object and routines used to load 3D * objects from that file. * *=========================================================================*/ /* Include Files */ #include "dfarchdt.h" #include "uesp/dagger/bsa/dfarch3d.h" /*=========================================================================== * * Begin Local Variable Definitions * *=========================================================================*/ DEFINE_FILE(); /* Main Arch3D file object */ CDFArch3dFile l_DFArch3DFile; /* Cache of 3D objects */ CDF3dObject** l_ppDF3dObjectCache = NULL; int l_NumDF3dObjectsCache = 0; /*=========================================================================== * End of Local Variable Definitions *=========================================================================*/ /*=========================================================================== * * Function - void AddDF3dObjectCache (pObject, Index); * * Attempts to add the given object to the 3D cache of objects. If the * given index is occupied, the current cache object is destroyed. * *=========================================================================*/ void AddDF3dObjectCache (CDF3dObject* pObject, const int Index) { DEFINE_FUNCTION("AddDF3dObjectCache()"); /* Ensure valid input */ ASSERT(pObject != NULL && Index >= 0 && Index < DFARCH3D_DATA_CACHESIZE); ASSERT(l_ppDF3dObjectCache != NULL); /* Delete current cache object, if any */ DestroyPointer(l_ppDF3dObjectCache[Index]); /* Set the cache object */ l_ppDF3dObjectCache[Index] = pObject; } /*=========================================================================== * End of Function AddDF3dObjectCache() *=========================================================================*/ /*=========================================================================== * * Function - void CreateDF3dObjectCache (void); * * Allocates the global Arch3D object cache. * *=========================================================================*/ void CreateDF3dObjectCache (void) { DEFINE_FUNCTION("CreateDF3dObjectCache()"); static boolean RegisterAtExit = FALSE; /* Ensure valid application state */ if (l_ppDF3dObjectCache != NULL) return; /* Create the array of pointers and initialize */ CreateArrayPointer(l_ppDF3dObjectCache, CDF3dObject*, DFARCH3D_DATA_CACHESIZE); memset(l_ppDF3dObjectCache, 0, sizeof(CDF3dObject*)*DFARCH3D_DATA_CACHESIZE); l_NumDF3dObjectsCache = 0; /* Register the at exit function to destroy array */ atexit(DestroyDF3dObjectCache); RegisterAtExit = TRUE; } /*=========================================================================== * End of Function CreateDF3dObjectCache() *=========================================================================*/ /*=========================================================================== * * Function - void ClearDF3dObjectCache (void); * * Removes any allocated 3D objects from the cache. * *=========================================================================*/ void ClearDF3dObjectCache (void) { DEFINE_FUNCTION("ClearDF3dObjectCache()"); int Index; /* Ignore if no cache to destroy */ if (l_ppDF3dObjectCache == NULL) return; /* Delete any allocated 3D objects */ for (Index = 0; Index < DFARCH3D_DATA_CACHESIZE; Index++) { DestroyPointer(l_ppDF3dObjectCache[Index]); } l_NumDF3dObjectsCache = 0; } /*=========================================================================== * End of Function ClearDF3dObjectCache() *=========================================================================*/ /*=========================================================================== * * Function - void DestroyDF3dObjectCache (void); * * Delete any cached 3D Objects loaded from the Arch3D file. * *=========================================================================*/ void DestroyDF3dObjectCache (void) { /* Ignore if no cache to destroy */ if (l_ppDF3dObjectCache == NULL) return; /* Clear and destroy the array */ ClearDF3dObjectCache(); DestroyArrayPointer(l_ppDF3dObjectCache); } /*=========================================================================== * End of Function DestroyDF3dObjectCache() *=========================================================================*/ /*=========================================================================== * * Function - void DestroyDFArch3d (void); * * Delete the Arch3D file information. * *=========================================================================*/ void DestroyDFArch3d (void) { DestroyDF3dObjectCache(); l_DFArch3DFile.Destroy(); } /*=========================================================================== * End of Function DestroyDFArch3dCache() *=========================================================================*/ /*=========================================================================== * * Function - boolean GetDF3dObject (ppObject, ObjectValue); * * Attempt to retrieve the 3D object with the given object value from the * Arch3D.BSA file. Returns the cached object if it exists, otherwise the * object is loaded. * *=========================================================================*/ boolean GetDF3dObject (CDF3dObject** ppObject, const long ObjectValue) { DEFINE_FUNCTION("GetDF3dObject()"); boolean Result; int Index; /* Ensure the file has been opened */ ASSERT(l_DFArch3DFile.IsOpen() && l_ppDF3dObjectCache != NULL); /* Attempt to find BSA record index from object value */ Index = l_DFArch3DFile.FindRecord(ObjectValue); if (Index < 0) return (FALSE); /* Does the cached object exist? */ if (l_ppDF3dObjectCache[Index] != NULL) { *ppObject = l_ppDF3dObjectCache[Index]; return (TRUE); } /* Attempt to load object by its index */ Result = l_DFArch3DFile.LoadObject(ppObject, Index); if (!Result) return (Result); /* Add loaded object to the cache */ AddDF3dObjectCache(*ppObject, Index); return (TRUE); } /*=========================================================================== * End of Function GetDF3dObject() *=========================================================================*/ /*=========================================================================== * * Function - boolean InitDFArch3d (pFilename); * * Attempt to open the Daggerfall Arch3D.BSA file with the given filename * and read in the BSA directory contents. The file is kept open. Returns * FALSE on any error. Initializes the 3D object cache. * *=========================================================================*/ boolean InitDFArch3d (const char* pFilename) { DEFINE_FUNCTION("InitDFArch3d()"); boolean Result; /* Initialize the 3D object cache */ CreateDF3dObjectCache(); /* Open file and load the BSA directory */ Result = l_DFArch3DFile.Open(pFilename, "rb"); return (Result); } /*=========================================================================== * End of Function InitDFArch3d() *=========================================================================*/