void MFFileSystem_RegisterDefaultArchives(void *) { GET_MODULE_DATA(MFFileSystemState); MFFile *&hDataArchive = pModuleData->hDataArchive; MFFile *&hPatchArchive = pModuleData->hPatchArchive; // try and mount the 'standard' archives... // TODO: ponder removing this code and forcing the use of a filesystem init callback? :/ MFOpenDataNative dataArchive; dataArchive.cbSize = sizeof(MFOpenDataNative); dataArchive.openFlags = MFOF_Read|MFOF_Binary; hDataArchive = 0; const char **pArc = gArchiveNames; while(!hDataArchive && *pArc) { dataArchive.pFilename = MFFile_SystemPath(MFStr(*pArc, MFSystem_GetPlatformString(MFSystem_GetCurrentPlatform()))); hDataArchive = MFFile_Open(pModuleData->hNativeFileSystem, &dataArchive); ++pArc; } MFMountDataNative mountData; mountData.cbSize = sizeof(MFMountDataNative); mountData.priority = MFMP_Normal; if(hDataArchive) { // attempt to cache the zip archive MFOpenDataCachedFile cachedOpen; cachedOpen.cbSize = sizeof(MFOpenDataCachedFile); cachedOpen.openFlags = MFOF_Read | MFOF_Binary | MFOF_Cached_CleanupBaseFile; cachedOpen.maxCacheSize = 1*1024*1024; // 1mb cache for zip archives should be heaps!! cachedOpen.pBaseFile = hDataArchive; MFFile *pCachedFile = MFFile_Open(MFFileSystem_GetInternalFileSystemHandle(MFFSH_CachedFileSystem), &cachedOpen); if(pCachedFile) hDataArchive = pCachedFile; // mount the zip archive. MFMountDataZipFile zipMountData; zipMountData.cbSize = sizeof(MFMountDataZipFile); zipMountData.flags = MFMF_Recursive|MFMF_FlattenDirectoryStructure; zipMountData.priority = MFMP_Normal; zipMountData.pMountpoint = "data"; zipMountData.pZipArchive = hDataArchive; MFFileSystem_Mount(pModuleData->hZipFileSystem, &zipMountData); } mountData.flags = MFMF_DontCacheTOC; mountData.pMountpoint = "home"; mountData.pPath = MFFile_HomePath(); MFFileSystem_Mount(pModuleData->hNativeFileSystem, &mountData); // see if we can mount the patch archive.. hPatchArchive = 0; pArc = gPatchArchiveNames; while(!hPatchArchive && *pArc) { dataArchive.pFilename = MFFile_SystemPath(MFStr(*pArc, MFSystem_GetPlatformString(MFSystem_GetCurrentPlatform()))); hDataArchive = MFFile_Open(pModuleData->hNativeFileSystem, &dataArchive); ++pArc; } if(hPatchArchive) { // attempt to cache the zip archive MFOpenDataCachedFile cachedOpen; cachedOpen.cbSize = sizeof(MFOpenDataCachedFile); cachedOpen.openFlags = MFOF_Read | MFOF_Binary | MFOF_Cached_CleanupBaseFile; cachedOpen.maxCacheSize = 1*1024*1024; // 1mb cache for zip archives should be heaps!! cachedOpen.pBaseFile = hPatchArchive; MFFile *pCachedFile = MFFile_Open(MFFileSystem_GetInternalFileSystemHandle(MFFSH_CachedFileSystem), &cachedOpen); if(pCachedFile) hPatchArchive = pCachedFile; // mount the zip archive. MFMountDataZipFile zipMountData; zipMountData.cbSize = sizeof(MFMountDataZipFile); zipMountData.flags = MFMF_Recursive|MFMF_FlattenDirectoryStructure; zipMountData.priority = MFMP_VeryHigh; zipMountData.pMountpoint = "patch"; zipMountData.pZipArchive = hPatchArchive; MFFileSystem_Mount(pModuleData->hZipFileSystem, &zipMountData); } if(pModuleData->hHTTPFileSystem != -1) { // register the network filesystems MFMountDataHTTP mountDataHTTP; mountDataHTTP.cbSize = sizeof(MFMountDataHTTP); mountDataHTTP.pMountpoint = "http"; mountDataHTTP.priority = MFMP_Normal + 1; mountDataHTTP.flags = MFMF_OnlyAllowExclusiveAccess; MFFileSystem_Mount(pModuleData->hHTTPFileSystem, &mountDataHTTP); } }
MF_API MFModel* MFModel_Create(const char *pFilename) { const char* pOriginalFilename = pFilename; // see if it's already loaded MFModelPool::Iterator it = gModelBank.Get(pOriginalFilename); MFModelTemplate *pTemplate = it ? *it : NULL; if(!pTemplate) { char *pTemplateData = NULL; MFFile *hFile = MFFileSystem_Open(MFStr("%s.mdl", pFilename), MFOF_Read|MFOF_Binary); if(hFile) { int64 size = MFFile_GetSize(hFile); if(size > 0) { // allocate memory and load file pTemplateData = (char*)MFHeap_Alloc((size_t)size + MFString_Length(pFilename) + 1); MFFile_Read(hFile, pTemplateData, (size_t)size); MFFile_Close(hFile); MFString_Copy(&pTemplateData[size], pFilename); pFilename = &pTemplateData[size]; } } else { #if defined(ALLOW_LOAD_FROM_SOURCE_DATA) // try to load from source data const char * const pExt[] = { ".f3d", ".dae", ".x", ".ase", ".obj", ".md2", ".md3", ".me2", NULL }; const char * const *ppExt = pExt; MFIntModel *pIM = NULL; while(!pIM && *ppExt) { MFString tempFilename = MFString::Format("%s%s", pFilename, *ppExt); pIM = MFIntModel_CreateFromFile(tempFilename.CStr()); if(pIM) { pFilename = MFString_Copy((char*)MFHeap_Alloc(tempFilename.NumBytes()+1), tempFilename.CStr()); break; } ++ppExt; } if(pIM) { MFIntModel_Optimise(pIM); size_t size; MFIntModel_CreateRuntimeData(pIM, (void**)&pTemplateData, &size, MFSystem_GetCurrentPlatform()); MFFile *pFile = MFFileSystem_Open(MFStr("cache:%s.mdl", pOriginalFilename), MFOF_Write | MFOF_Binary); if(pFile) { MFFile_Write(pFile, pTemplateData, size, false); MFFile_Close(pFile); } MFIntModel_Destroy(pIM); } #endif } if(!pTemplateData) return NULL; // check ID string MFDebug_Assert(*(uint32*)pTemplateData == MFMAKEFOURCC('M', 'D', 'L', '2'), "Incorrect MFModel version."); // store filename for later reference pTemplate = (MFModelTemplate*)pTemplateData; pTemplate->pFilename = pFilename; gModelBank.Add(pOriginalFilename, pTemplate); MFModel_FixUp(pTemplate, true); MFModelDataChunk *pChunk = MFModel_GetDataChunk(pTemplate, MFChunkType_SubObjects); if(pChunk) { MFModelSubObject *pSubobjects = (MFModelSubObject*)pChunk->pData; for(int a=0; a<pChunk->count; a++) { // pSubobjects[a].pMaterial = MFMaterial_Create((char*)pSubobjects[a].pMaterial); for(int b=0; b<pSubobjects[a].numMeshChunks; b++) { MFModel_CreateMeshChunk(MFModel_GetMeshChunkInternal(pTemplate, a, b)); } } } } MFModel *pModel; pModel = (MFModel*)MFHeap_Alloc(sizeof(MFModel)); pModel->worldMatrix = MFMatrix::identity; pModel->modelColour = MFVector::one; pModel->pTemplate = pTemplate; pModel->pAnimation = NULL; ++pTemplate->refCount; return pModel; }