Example #1
0
void ParseID3(MFAudioStream *pStream, MFID3 *pID3, int dataSize)
{
	unsigned char *pData = pID3->pID3Data;

	while(pData - pID3->pID3Data <= dataSize)
	{
		if(pID3->major == 2)
		{
			// for the moment, to be safe...
//			MFDebug_Assert(false, "Make this work!!");
			return;

			//int size = (int)pData[5] | ((int)pData[4] << 7) | ((int)pData[3] << 14);
			//pData += 6 + size;
		}
		if(pID3->major > 2)
		{
			ID3Chunk *pChunkHeader = (ID3Chunk*)pData;
			int size = GetSynchSafeInt(pData + 4);

			if(*pData == 'T')
			{
				//uint8 encoding = pData[10];
				const char *pString = (const char*)pData + 11;

				switch(pChunkHeader->id)
				{
					case MFMAKEFOURCC('T', 'I', 'T', '2'):
						MFString_CopyN(pStream->streamInfo.songName, pString, MFMin(size-1, (int)sizeof(pStream->streamInfo.songName)-1));
						break;
					case MFMAKEFOURCC('T', 'A', 'L', 'B'):
						MFString_CopyN(pStream->streamInfo.albumName, pString, MFMin(size-1, (int)sizeof(pStream->streamInfo.albumName)-1));
						break;
					case MFMAKEFOURCC('T', 'P', 'E', '1'):
					case MFMAKEFOURCC('T', 'P', 'E', '2'):
						MFString_CopyN(pStream->streamInfo.artistName, pString, MFMin(size-1, (int)sizeof(pStream->streamInfo.artistName)-1));
						break;
					case MFMAKEFOURCC('T', 'C', 'O', 'N'):
						MFString_CopyN(pStream->streamInfo.genre, pString, MFMin(size-1, (int)sizeof(pStream->streamInfo.genre)-1));
						break;
				}
			}

			pData += 10 + size;
		}
	}
}
Example #2
0
MF_API MFTexture* MFTexture_CreateRenderTarget(const char *pName, int width, int height, MFTextureFormat targetFormat)
{
	MFTexture *pTexture = MFTexture_FindTexture(pName);

	if(!pTexture)
	{
		pTexture = &gTextureBank.Create(pName);

		if(targetFormat & TexFmt_SelectNicest)
		{
			targetFormat = TexFmt_A8R8G8B8;
		}

		pTexture->pTemplateData = (MFTextureTemplateData*)MFHeap_AllocAndZero(sizeof(MFTextureTemplateData) + sizeof(MFTextureSurfaceLevel));
		pTexture->pTemplateData->pSurfaces = (MFTextureSurfaceLevel*)&pTexture->pTemplateData[1];
		pTexture->pTemplateData->magicNumber = MFMAKEFOURCC('F','T','E','X');
		pTexture->pTemplateData->imageFormat = targetFormat;
		pTexture->pTemplateData->mipLevels = 1;
		pTexture->pTemplateData->flags = TEX_RenderTarget;

		pTexture->pTemplateData->pSurfaces->width = width;
		pTexture->pTemplateData->pSurfaces->height = height;
		pTexture->pTemplateData->pSurfaces->bitsPerPixel = MFTexture_GetBitsPerPixel(pTexture->pTemplateData->imageFormat);
		pTexture->pTemplateData->pSurfaces->xBlocks = width;
		pTexture->pTemplateData->pSurfaces->yBlocks = height;
		pTexture->pTemplateData->pSurfaces->bitsPerBlock = pTexture->pTemplateData->pSurfaces->bitsPerPixel;
		pTexture->pTemplateData->pSurfaces->pImageData = NULL;
		pTexture->pTemplateData->pSurfaces->bufferLength = 0;
		pTexture->pTemplateData->pSurfaces->pPaletteEntries = NULL;
		pTexture->pTemplateData->pSurfaces->paletteBufferLength = 0;

		pTexture->refCount = 1;
		MFString_CopyN(pTexture->name, pName, sizeof(pTexture->name) - 1);
		pTexture->name[sizeof(pTexture->name) - 1] = 0;

		D3DFORMAT platformFormat = (D3DFORMAT)MFTexture_GetPlatformFormatID(targetFormat, MFDD_D3D9);
		HRESULT hr = pd3dDevice->CreateTexture(width, height, 1, D3DUSAGE_RENDERTARGET, platformFormat, D3DPOOL_DEFAULT, (IDirect3DTexture9**)&pTexture->pInternalData, NULL);

		if(hr != D3D_OK)
		{
			MFHeap_Free(pTexture->pTemplateData);
			gTextureBank.DestroyItem(*pTexture);
			pTexture = NULL;
		}
	}
	else
	{
		pTexture->refCount++;
	}

	return pTexture;
}
Example #3
0
MF_API MFIntSound *MFIntSound_CreateFromFile(const char *pFilename)
{
	MFAudioStream *pStream = MFSound_CreateStream(pFilename, MFASF_DecodeOnly | MFASF_QueryLength);
	if(!pStream)
		return NULL;

	MFIntSound *pSound = (MFIntSound*)MFHeap_Alloc(sizeof(MFIntSound));

	pSound->pInternal = pStream;

	pSound->soundTemplate.magic = MFMAKEFOURCC('S', 'N', 'D', '1');
	pSound->soundTemplate.format = pStream->streamInfo.bitsPerSample == 8 ? MFWaveFmt_PCM_u8 : (pStream->streamInfo.bitsPerSample == 24 ? MFWaveFmt_PCM_s24 : MFWaveFmt_PCM_s16);
	pSound->soundTemplate.flags = 0;
	pSound->soundTemplate.sampleRate = pStream->streamInfo.sampleRate;
	pSound->soundTemplate.numSamples = 0;
	pSound->soundTemplate.bitsPerSample = pStream->streamInfo.bitsPerSample;
	pSound->soundTemplate.numChannels = (uint16)pStream->streamInfo.channels;
	pSound->soundTemplate.numStreams = 1;

	return pSound;
}
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;
}
Example #5
0
int main(int argc, char *argv[])
{
    MFPlatform platform = FP_Unknown;
    MFWaveFormat targetFormat = MFWF_PCM_s16;

    char fileName[256] = "";
    char outFile[256] = "";

    int a;

    // process command line
    for(a=1; a<argc; a++)
    {
        if(argv[a][0] == '-' || argv[a][0] == '/')
        {
            for(int b=0; b<FP_Max; b++)
            {
                if(!MFString_CaseCmp(&argv[a][1], MFSystem_GetPlatformString(b)))
                {
                    platform = (MFPlatform)b;
                    break;
                }
            }

            if(!MFString_CaseCmp(&argv[a][1], "v") || !MFString_CaseCmp(&argv[a][1], "version"))
            {
                // print version
                return 0;
            }
        }
        else
        {
            if(!fileName[0])
                MFString_Copy(fileName, argv[a]);
            else if(!outFile[0])
                MFString_Copy(outFile, argv[a]);
        }
    }

    if(platform == FP_Unknown)
    {
        LOGERROR("No platform specified...\n");
        return 1;
    }

    if(!fileName[0])
    {
        LOGERROR("No file specified...\n");
        return 1;
    }

    if(!outFile[0])
    {
        // generate output filename
        MFString_Copy(outFile, fileName);
        for(int i=MFString_Length(outFile); --i; )
        {
            if(outFile[i] == '.')
            {
                outFile[i] = 0;
                break;
            }
        }

        MFString_Cat(outFile, ".snd");
    }

    // load image
    char *pBuffer;

    FILE *pFile = fopen(fileName, "rb");
    if(!pFile)
    {
        LOGERROR("Couldnt open source file '%s' for reading.", fileName);
        return 1;
    }

    fseek(pFile, 0, SEEK_END);
    int bytes = ftell(pFile) + 1;
    fseek(pFile, 0, SEEK_SET);

    pBuffer = (char*)malloc(bytes);
    fread(pBuffer, bytes, 1, pFile);
    fclose(pFile);

    FILE *pOutFile = fopen(outFile, "wb");

    if(!pOutFile)
    {
        LOGERROR("Couldnt open output file '%s' for writing.", outFile);
        return 2;
    }

    // parse the sound file...
    WAVHeader *pHeader = (WAVHeader*)pBuffer;

    if(pHeader->RIFF != MFMAKEFOURCC('R', 'I', 'F', 'F') || pHeader->WAVE != MFMAKEFOURCC('W', 'A', 'V', 'E'))
    {
        LOGERROR("Source file '%s' is not a wave file.", fileName);
        return 1;
    }

    WAVChunk *pChunk = (WAVChunk*)&pHeader[1];

    WAVFormatChunk *pFormat = NULL;
    WAVDataChunk *pData = NULL;

    while((char*)pChunk - pBuffer < bytes && bytes - ((char*)pChunk - pBuffer) >= sizeof(WAVChunk))
    {
        if(pChunk->id == MFMAKEFOURCC('f', 'm', 't', ' '))
        {
            pFormat = (WAVFormatChunk*)pChunk;
        }
        else if(pChunk->id == MFMAKEFOURCC('d', 'a', 't', 'a'))
        {
            pData = (WAVDataChunk*)pChunk;
        }

        pChunk = (WAVChunk*)((char*)pChunk + sizeof(WAVChunk) + ((pChunk->size+1) & ~1));
    }

    if(!pFormat || !pData)
    {
        LOGERROR("WAVE file '%s' has no format or data chunks.", fileName);
        return 2;
    }

    // we only output 1 stream for now..
    int numStreams = 1;
    int numSamples = ((pData->size*8) / ((pFormat->wBitsPerSample + 7) & ~7)) / pFormat->nChannels;

    int fileSize = sizeof(MFSoundTemplate) + sizeof(char*)*numStreams + bytesPerSample[targetFormat]*pFormat->nChannels*numSamples*numStreams;
    char *pSndFile = (char*)MFHeap_Alloc(fileSize);

    MFSoundTemplate *pTemplate = (MFSoundTemplate*)pSndFile;
    pTemplate->ppStreams = (char **)&pTemplate[1];
    char *pWaveData = (char*)&pTemplate->ppStreams[numStreams];
    for(int a=0; a<numStreams; a++)
    {
        pTemplate->ppStreams[a] = pWaveData;
        pWaveData += bytesPerSample[targetFormat]*pFormat->nChannels*numSamples;
    }

    pTemplate->magic = MFMAKEFOURCC('S', 'N', 'D', '1');
    pTemplate->flags = 0;
    pTemplate->format = targetFormat;
    pTemplate->numSamples = numSamples;
    pTemplate->numStreams = numStreams;
    pTemplate->numChannels = pFormat->nChannels;
    pTemplate->bitsPerSample = bytesPerSample[targetFormat]*8;
    pTemplate->sampleRate = pFormat->nSamplesPerSec;

    // write wave data into file
    if(pTemplate->bitsPerSample == pFormat->wBitsPerSample)
    {
        for(int a=0; a<pTemplate->numStreams; a++)
            MFCopyMemory(pTemplate->ppStreams[a], pData->data, bytesPerSample[targetFormat]*pTemplate->numChannels*pTemplate->numSamples);
    }
    else
    {
        // do a format conversion
        LOGERROR("Format conversion not written.");
        return 3;
    }

    // fix up template
    for(int a=0; a<numStreams; a++)
        MFFixUp(pTemplate->ppStreams[a], pTemplate, false);
    MFFixUp(pTemplate->ppStreams, pTemplate, false);

    // write to disk
    fwrite(pSndFile, fileSize, 1, pOutFile);
    fclose(pOutFile);

    printf("> %s\n", outFile);

    return 0;
}
Example #6
0
		25,	// D3DFMT_A1R5G5B5		// TexFmt_A1R5G5B5
		0,	//						// TexFmt_R5G5B5A1
		0,	//						// TexFmt_A1B5G5R5

		26,	// D3DFMT_A4R4G4B4		// TexFmt_A4R4G4B4
		0,	//						// TexFmt_A4B4G4R4
		0,	//						// TexFmt_R4G4B4A4

		113,// D3DFMT_A16B16G16R16F	// TexFmt_ABGR_F16
		116,// D3DFMT_A32B32G32R32F	// TexFmt_ABGR_F32

		41,	// D3DFMT_P8			// TexFmt_I8
		0,	//						// TexFmt_I4

		MFMAKEFOURCC('D', 'X', 'T', '1'),	// D3DFMT_DXT1	// TexFmt_DXT1
		MFMAKEFOURCC('D', 'X', 'T', '2'),	// D3DFMT_DXT2	// TexFmt_DXT2
		MFMAKEFOURCC('D', 'X', 'T', '3'),	// D3DFMT_DXT3	// TexFmt_DXT3
		MFMAKEFOURCC('D', 'X', 'T', '4'),	// D3DFMT_DXT4	// TexFmt_DXT4
		MFMAKEFOURCC('D', 'X', 'T', '5'),	// D3DFMT_DXT5	// TexFmt_DXT5

		0,	// TexFmt_PSP_DXT1
		0,	// TexFmt_PSP_DXT3
		0,	// TexFmt_PSP_DXT5

		0,	// TexFmt_XB_A8R8G8B8
		0,	// TexFmt_XB_A8B8G8R8
		0,	// TexFmt_XB_B8G8R8A8
		0,	// TexFmt_XB_R8G8B8A8

		0,	// TexFmt_XB_R5G6B5
Example #7
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;
}
Example #8
0
void CreateWAVStream(MFAudioStream *pStream, const char *pFilename)
{
	MFCALLSTACK;

	// open wav file
	MFFile* hFile = MFFileSystem_Open(pFilename);
	if(!hFile)
		return;

	// attempt to cache the vorbis stream
	MFOpenDataCachedFile cachedOpen;
	cachedOpen.cbSize = sizeof(MFOpenDataCachedFile);
	cachedOpen.openFlags = MFOF_Read | MFOF_Binary | MFOF_Cached_CleanupBaseFile;
	cachedOpen.maxCacheSize = 256*1024; // 256k cache for wav stream should be heaps!!
	cachedOpen.pBaseFile = hFile;

	MFFile *pCachedFile = MFFile_Open(MFFileSystem_GetInternalFileSystemHandle(MFFSH_CachedFileSystem), &cachedOpen);
	if(pCachedFile)
		hFile = pCachedFile;

	RIFFHeader header;
	MFFile_Read(hFile, &header, sizeof(header));

	if(header.RIFF != MFMAKEFOURCC('R', 'I', 'F', 'F') || header.WAVE != MFMAKEFOURCC('W', 'A', 'V', 'E'))
		return;	// not a .wav file...

	// if everything's good, and it appears to be a valid wav file
	MFWAVStream *pWS = (MFWAVStream*)MFHeap_AllocAndZero(sizeof(MFWAVStream));
	pStream->pStreamData = pWS;
	pWS->pStream = hFile;

	size_t read;
	size_t fptr = sizeof(header);
	do
	{
		MFFile_Seek(hFile, fptr, MFSeek_Begin);

		WAVChunk dataChunk;
		MFZeroMemory(&dataChunk, sizeof(dataChunk));
		read = MFFile_Read(hFile, &dataChunk, sizeof(dataChunk));
		fptr += sizeof(dataChunk) + dataChunk.size;

		if(dataChunk.id == MFMAKEFOURCC('f', 'm', 't', ' '))
		{
			read = MFFile_Read(hFile, &pWS->format, dataChunk.size);
			if(pWS->format.cbSize)
				read = (size_t)MFFile_Seek(hFile, pWS->format.cbSize, MFSeek_Current);
		}
		else if(dataChunk.id == MFMAKEFOURCC('d', 'a', 't', 'a'))
		{
			pWS->dataOffset = (size_t)MFFile_Tell(hFile);
			pWS->dataSize = dataChunk.size;
		}
	}
	while(read);

	// return to the start of the audio data
	MFFile_Seek(pWS->pStream, (int)pWS->dataOffset, MFSeek_Begin);

	// calculate the track length
	pWS->sampleSize = (pWS->format.nChannels * pWS->format.wBitsPerSample) >> 3;
	pStream->trackLength = (float)(pWS->dataSize / pWS->sampleSize) / (float)pWS->format.nSamplesPerSec;

	// fill out the stream info
	pStream->streamInfo.sampleRate = pWS->format.nSamplesPerSec;
	pStream->streamInfo.channels = pWS->format.nChannels;
	pStream->streamInfo.bitsPerSample = pWS->format.wBitsPerSample;
	pStream->streamInfo.bufferLength = pWS->format.nSamplesPerSec;
}