Exemple #1
0
MF_API bool MFAsset_ConvertModelAndAnimationFromFile(const char *pFilename, void **ppMesh, size_t *pMeshSize, void **ppAnimation, size_t *pAnimationSize, MFPlatform platform, size_t extraBytes)
{
	// should this request be forewarded to the file server, or should we do it locally?
	//... todo

	if(!MFIntAsset_ConvertModelAndAnimationFromFile(pFilename, ppMesh, pMeshSize, ppAnimation, pAnimationSize, platform, extraBytes))
		return false;

	if(ppMesh && *ppMesh)
	{
		MFFile *pFile = MFFileSystem_Open(MFStr("cache:%s.mdl", pFilename), MFOF_Write | MFOF_Binary);
		if(pFile)
		{
			MFFile_Write(pFile, *ppMesh, *pMeshSize, false);
			MFFile_Close(pFile);
		}
	}
	if(ppAnimation && *ppAnimation)
	{
		MFFile *pFile = MFFileSystem_Open(MFStr("cache:%s.anm", pFilename), MFOF_Write | MFOF_Binary);
		if(pFile)
		{
			MFFile_Write(pFile, *ppAnimation, *pAnimationSize, false);
			MFFile_Close(pFile);
		}
	}
	return true;
}
Exemple #2
0
// read/write a file to a filesystem
MF_API char* MFFileSystem_Load(const char *pFilename, size_t *pBytesRead, size_t extraBytes)
{
	char *pBuffer = NULL;

	MFFile *hFile = MFFileSystem_Open(pFilename, MFOF_Read|MFOF_Binary);
	if(hFile)
	{
		uint64 size = MFFile_GetSize(hFile);

		if(size > 0)
		{
#if defined(MF_32BIT)
			if(size >= 1LL << 32)
			{
				MFDebug_Warn(1, MFStr("File is larger than the available address space!", pFilename));
				return NULL;
			}
#endif

			pBuffer = (char*)MFHeap_Alloc((size_t)size + extraBytes);

			size_t bytesRead = MFFile_Read(hFile, pBuffer, (size_t)size);

			if(extraBytes > 0)
				pBuffer[size] = 0;

			if(pBytesRead)
				*pBytesRead = bytesRead;
		}

		MFFile_Close(hFile);
	}

	return pBuffer;
}
Exemple #3
0
MF_API bool MFAsset_ConvertAssetFromFile(const char *pFilename, void **ppOutput, size_t *pSize, MFPlatform platform, size_t extraBytes)
{
	// should this request be forewarded to the file server, or should we do it locally?
	//... todo

	size_t size;
	if(!MFIntAsset_ConvertAssetFromFile(pFilename, ppOutput, &size, platform, extraBytes) || !*ppOutput)
		return false;

	if(pSize)
		*pSize = size;

	const char *pExt = MFString_GetFileExtension(pFilename);
	const char *pCacheExt = NULL;
	if(!MFString_CaseCmp(pExt, ".mfx"))
		pCacheExt = ".bfx";
	else if(!MFString_CaseCmp(pExt, ".fnt"))
		pCacheExt = ".fft";
	else if(!MFAsset_IsSoundFile(pExt))
		pCacheExt = ".snd";
	else if(!MFAsset_IsImageFile(pExt))
		pCacheExt = ".tex";
	else if(!MFAsset_IsGeometryFile(pExt))
		pCacheExt = ".mdl";
	else if(!MFAsset_IsShaderFile(pExt))
		pCacheExt = ".fsh";

	MFFile *pFile = MFFileSystem_Open(MFStr("cache:%s%s", pFilename, pCacheExt), MFOF_Write | MFOF_Binary);
	if(pFile)
	{
		MFFile_Write(pFile, *ppOutput, size, false);
		MFFile_Close(pFile);
	}
	return true;
}
Exemple #4
0
int F3DFile::ReadOBJ(const char *pFilename)
{
	pModel = this;

	MFFile *pFile = MFFileSystem_Open(pFilename, MFOF_Read);
	if(!pFile)
	{
		MFDebug_Warn(2, MFStr("Failed to open OBJ file %s", pFilename));
		return 1;
	}

	uint64 size = MFFile_Seek(pFile, 0, MFSeek_End);
	MFFile_Seek(pFile, 0, MFSeek_Begin);

	char *pMem = (char*)MFHeap_Alloc((size_t)size+1);
	MFFile_Read(pFile, pMem, size);
	pMem[size] = 0;

	MFFile_Close(pFile);

	ParseOBJFile(pMem);
	MFHeap_Free(pMem);

	return 0;
}
Exemple #5
0
// returns true if the file can be found within the mounted filesystem stack
MF_API bool MFFileSystem_Exists(const char *pFilename)
{
	MFCALLSTACK;

	bool exists = false;

	MFFile *hFile = MFFileSystem_Open(pFilename, MFOF_Read|MFOF_Binary|MFOF_TryOpen);
	if(hFile)
	{
		exists = true;
		MFFile_Close(hFile);
	}

	return exists;
}
Exemple #6
0
// if file does not exist, GetSize returns 0, however, a zero length file can also return 0 use 'Exists' to confirm
MF_API uint64 MFFileSystem_GetSize(const char *pFilename)
{
	MFCALLSTACK;

	uint64 size = 0;

	MFFile *hFile = MFFileSystem_Open(pFilename, MFOF_Read|MFOF_Binary);
	if(hFile)
	{
		size = MFFile_GetSize(hFile);
		MFFile_Close(hFile);
	}

	return size;
}
Exemple #7
0
MF_API size_t MFFileSystem_Save(const char *pFilename, const char *pBuffer, size_t size)
{
	MFDebug_Log(5, MFStr("Call: MFFileSystem_Save(\"%s\")", pFilename));

	size_t bytesWritten = 0;

	MFFile *hFile = MFFileSystem_Open(pFilename, MFOF_Write|MFOF_Truncate|MFOF_Binary|MFOF_CreateDirectory);
	if(hFile)
	{
		bytesWritten = MFFile_Write(hFile, pBuffer, size, false);

		MFFile_Close(hFile);
	}

	return bytesWritten;
}
Exemple #8
0
MF_API bool MFAsset_ConvertShaderFromFile(const char *pFilename, void **ppOutput, size_t *pSize, MFPlatform platform, MFShaderType shaderType, MFShaderMacro *pMacros, MFRendererDrivers renderDriver, MFShaderLanguage language)
{
	// should this request be forewarded to the file server, or should we do it locally?
	//... todo

	if(!MFIntAsset_ConvertShaderFromFile(pFilename, ppOutput, pSize, platform, shaderType, pMacros, renderDriver, language))
		return false;

	MFFile *pFile = MFFileSystem_Open(MFStr("cache:%s.fsh", pFilename), MFOF_Write | MFOF_Binary);
	if(pFile)
	{
		MFFile_Write(pFile, *ppOutput, *pSize, false);
		MFFile_Close(pFile);
	}
	return true;
}
Exemple #9
0
MF_API bool MFAsset_ConvertTextureFromFile(const char *pFilename, void **ppOutput, size_t *pSize, MFPlatform platform, uint32 flags, MFImageFormat targetFormat, size_t extraBytes)
{
	// should this request be forewarded to the file server, or should we do it locally?
	//... todo

	if(!MFIntAsset_ConvertTextureFromFile(pFilename, ppOutput, pSize, platform, flags, targetFormat, extraBytes))
		return false;

	MFFile *pFile = MFFileSystem_Open(MFStr("cache:%s.tex", pFilename), MFOF_Write | MFOF_Binary);
	if(pFile)
	{
		MFFile_Write(pFile, *ppOutput, *pSize, false);
		MFFile_Close(pFile);
	}
	return true;
}
Exemple #10
0
void MFFileSystem_DeinitModule()
{
	GET_MODULE_DATA(MFFileSystemState);

	if(pModuleData->hDataArchive)
	{
		MFFile_Close(pModuleData->hDataArchive);
	}

	MFFileSystemHTTP_DeinitModule();
	MFFileSystemZipFile_DeinitModule();
	MFFileSystemCachedFile_DeinitModule();
	MFFileSystemMemory_DeinitModule();
	MFFileSystemNative_DeinitModule();

	MFHeap_Free(pModuleData->ppFileSystemList);

	pModuleData->gFileSystems.Deinit();
	pModuleData->gOpenFiles.Deinit();
	pModuleData->gFinds.Deinit();
}
Exemple #11
0
MF_API const char *MFFileSystem_ResolveSystemPath(const char *pFilename, bool bAbsolute)
{
	MFFile *pFile = MFFileSystem_Open(pFilename, MFOF_Read|MFOF_Binary);

	const char *pPath = NULL;
	if(pFile)
	{
		GET_MODULE_DATA(MFFileSystemState);

		// TODO: support other filesystems that forward to the native filesystem (like cache filesystem?)
		if(pFile->filesystem == pModuleData->hNativeFileSystem)
			pPath = MFStr(pFile->fileIdentifier);
		MFFile_Close(pFile);
	}

	// convert to absolute...
	if(bAbsolute)
		pPath = MFFileNative_MakeAbsolute(pPath);

	return pPath;
}
MF_API MFAnimation* MFAnimation_Create(const char *pFilename, MFModel *pModel)
{
	MFAnimationTemplate *pTemplate = MFAnimation_FindTemplate(pFilename);

	if(!pTemplate)
	{
		size_t size = 0;
		pTemplate = (MFAnimationTemplate*)MFModelInternal_PendingAnimationTemplate(&size);

		if(!pTemplate)
		{
			MFFile *hFile = MFFileSystem_Open(MFStr("%s.anm", pFilename), MFOF_Read|MFOF_Binary);

			if(hFile)
			{
				size = (size_t)MFFile_GetSize(hFile);

				if(size > 0)
				{
					char *pTemplateData;

					// allocate memory and load file
					pTemplateData = (char*)MFHeap_Alloc(size + MFString_Length(pFilename) + 1);
					MFFile_Read(hFile, pTemplateData, size);

					pTemplate = (MFAnimationTemplate*)pTemplateData;

					// check ID string
					MFDebug_Assert(pTemplate->hash == MFMAKEFOURCC('A', 'N', 'M', '2'), "Incorrect MFAnimation version.");
				}

				MFFile_Close(hFile);
			}
		}

		if(!pTemplate)
			return NULL;

		pFilename = MFString_Copy((char*)pTemplate + size, pFilename);

		MFAnimation_FixUp(pTemplate, true);
		MFResource_AddResource(pTemplate, MFRT_AnimationTemplate, MFUtil_HashString(pFilename) ^ 0xA010A010, pFilename);
	}

	// get the model bone chunk
	MFModelDataChunk *pBoneChunk = MFModel_GetDataChunk(pModel->pTemplate, MFChunkType_Bones);
	MFDebug_Assert(pBoneChunk, "Cant apply animation to a model with no skeleton!");

	// create and init instance
	MFAnimation *pAnimation;
	size_t bytes = MFALIGN16(sizeof(MFAnimation)) + sizeof(MFMatrix)*pBoneChunk->count + sizeof(int)*pBoneChunk->count + sizeof(MFAnimationCurrentFrame)*pBoneChunk->count;
	pAnimation = (MFAnimation*)MFHeap_Alloc(bytes);
	pAnimation->pModel = pModel;
	pAnimation->pTemplate = pTemplate;

	// add animation to model animation list
	pModel->pAnimation = pAnimation;

	// get bones pointer from model (for convenience)
	pAnimation->pBones = (MFModelBone*)pBoneChunk->pData;
	pAnimation->numBones = pBoneChunk->count;

	// set matrices to identity
	pAnimation->pMatrices = (MFMatrix*)MFALIGN16(&pAnimation[1]);
	for(int a=0; a<pBoneChunk->count; a++)
	{
		pAnimation->pMatrices[a] = MFMatrix::identity;
	}

	MFStateConstant_AnimationMatrices animMats;
	animMats.pMatrices = pAnimation->pMatrices;
	animMats.numMatrices = pAnimation->numBones;
	MFStateBlock_SetAnimMatrices(pModel->pEntityState, animMats);

	// build bone to animation stream mapping
	pAnimation->pBoneMap = (int*)MFALIGN16(&pAnimation->pMatrices[pBoneChunk->count]);
	for(int a=0; a<pBoneChunk->count; a++)
	{
		const char *pBoneName = MFModel_GetBoneName(pModel, a);

		// find bone in animation
		pAnimation->pBoneMap[a] = -1;
		for(uint32 b=0; b<pTemplate->numBones; b++)
		{
			if(!MFString_CaseCmp(pBoneName, pTemplate->pBones[b].pBoneName))
			{
				pAnimation->pBoneMap[a] = b;
				break;
			}
		}
	}

	pAnimation->pCustomMatrices = NULL;
	pAnimation->blendLayer.frameTime = pAnimation->pTemplate->startTime;

	pAnimation->blendLayer.pCurFrames = (MFAnimationCurrentFrame*)&pAnimation->pBoneMap[pBoneChunk->count];
	MFZeroMemory(pAnimation->blendLayer.pCurFrames, sizeof(MFAnimationCurrentFrame)*pBoneChunk->count);

	return pAnimation;
}
Exemple #13
0
MF_API int MFFile_StdClose(void* fileHandle)
{
	return MFFile_Close((MFFile*)fileHandle);
}
Exemple #14
0
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;
}
Exemple #15
0
void DestroyWAVStream(MFAudioStream *pStream)
{
	MFWAVStream *pWS = (MFWAVStream*)pStream->pStreamData;
	MFFile_Close(pWS->pStream);
	MFHeap_Free(pWS);
}