MF_API void MFIntSound_CreateRuntimeData(MFIntSound *pSound, void **ppOutput, size_t *pSize, MFPlatform platform) { *ppOutput = NULL; MFAudioStream *pStream = (MFAudioStream*)pSound->pInternal; // decode audio into buffer size_t sampleSize = (pSound->soundTemplate.bitsPerSample * pSound->soundTemplate.numChannels) >> 3; size_t bytesAllocated = 44100 * sampleSize; size_t bytes = 0; char *pAudioData = (char*)MFHeap_Alloc(bytesAllocated); size_t read; do { // read samples from stream read = MFSound_ReadStreamSamples(pStream, pAudioData + bytes, bytesAllocated - bytes); bytes += read; // if we fill the buffer, increase it's size if(bytes == bytesAllocated) { bytesAllocated *= 4; pAudioData = (char*)MFHeap_Realloc(pAudioData, bytesAllocated); } } while(read); // calculate the number of samples from the bytes read int numSamples = (int)(bytes / sampleSize); // construct MFSoundTemplate size_t templateBytes = sizeof(MFSoundTemplate) + sizeof(char*)*pSound->soundTemplate.numStreams + sampleSize*numSamples; MFSoundTemplate *pTemplate = (MFSoundTemplate*)MFHeap_Alloc(templateBytes); MFCopyMemory(pTemplate, &pSound->soundTemplate, sizeof(MFSoundTemplate)); pTemplate->numSamples = numSamples; pTemplate->ppStreams = (char**)&pTemplate[1]; pTemplate->ppStreams[0] = (char*)&pTemplate->ppStreams[1]; // copy sample data MFCopyMemory(pTemplate->ppStreams[0], pAudioData, sampleSize * numSamples); // free decode buffer MFHeap_Free(pAudioData); // fix down pointers for(int a=0; a<pTemplate->numStreams; a++) MFFixUp(pTemplate->ppStreams[a], pTemplate, false); MFFixUp(pTemplate->ppStreams, pTemplate, false); // return template data *ppOutput = pTemplate; if(pSize) *pSize = templateBytes; }
void MFPoolHeapCollection::Init(int _numHeaps, const int *pNum, const size_t *pSizes, void *pMem, size_t memsize) { MFDebug_Assert(_numHeaps > 0 && pNum && pSizes, "Bad parameters"); numHeaps = _numHeaps; #if !defined(MF_RETAIL) overflows = 0; #endif if(pMem) { size_t size = (sizeof(MFPoolHeap*)+sizeof(MFPoolHeap))*numHeaps; for(int i=0; i<numHeaps; ++i) size += pNum[i]*pSizes[i]; MFDebug_Assert(memsize >= size, "Not enough memory"); pHeaps = (MFPoolHeap**)pMem; pMem = ((MFPoolHeap**)pMem) + numHeaps; } else { pHeaps = (MFPoolHeap**)MFHeap_Alloc(sizeof(MFPoolHeap*)*numHeaps); } size_t lastSize = 0; for(int i = 0; i < numHeaps; ++i) { const size_t size = pSizes[i]; const int num = pNum[i]; MFDebug_Assert(size > lastSize && num > 0, "Bad heap params"); lastSize = size; if(pMem) { pHeaps[i] = (MFPoolHeap*)pMem; pMem = ((MFPoolHeap*)pMem) + 1; const size_t memorySize = size*num; pHeaps[i]->Init(num, size, pMem, memorySize); pMem = ((char *)pMem) + memorySize; } else { pHeaps[i] = (MFPoolHeap*)MFHeap_Alloc(sizeof(MFPoolHeap)); pHeaps[i]->Init(num, size); } } }
void * MFPoolHeapExpanding::Alloc() { void *pMem = heap.Alloc(); if(pMem == NULL) { MFDebug_Assert(numberTilFull > 0, "The heap has grown larger than the maximum size requested"); MFPoolHeap *pHeap = (MFPoolHeap*)MFHeap_Alloc(sizeof(MFPoolHeap)); pHeap->Init(MFMin(numberTilFull, expandNum), heap.Size()); numberTilFull -= expandNum; // hook up the new heap to the chain pHeap->pNext = heap.pNext; heap.pNext = pHeap; // and hook up the free pointer heap.pFreeList = pHeap->pFreeList; heap.numItems += pHeap->numItems; pHeap->pFreeList = NULL; pHeap->numItems = 0; pMem = heap.Alloc(); } return pMem; }
void *MFObjectPoolGroup::Alloc(size_t bytes, size_t *pAllocated) { MFThread_LockMutex(mutex); void *pAlloc = NULL; for(int a=0; a<numPools; ++a) { if(bytes <= pConfig[a].objectSize) { if(pAllocated) *pAllocated = pConfig[a].objectSize; pAlloc = pPools[a].Alloc(); break; } } if(!pAlloc) { ++overflows; if(pAllocated) *pAllocated = bytes; MFHeap *pHeap = MFHeap_GetAllocHeap(pConfig); pAlloc = MFHeap_Alloc(bytes, pHeap); } MFThread_ReleaseMutex(mutex); return pAlloc; }
MF_API MFCollisionItem* MFCollision_CreateDynamicCollisionMesh(const char *pItemName, int numTris) { MFDebug_Assert(numTris > 0, "Cant create collision mesh with no triangles.."); MFCollisionItem *pItem; MFCollisionTemplate *pTemplate; MFCollisionMesh *pMesh; MFCollisionTriangle *pTris; pItem = MFCollision_CreateCollisionItem(); pTemplate = (MFCollisionTemplate*)MFHeap_Alloc(MFALIGN16(sizeof(MFCollisionTemplate)) + MFALIGN16(sizeof(MFCollisionMesh)) + sizeof(MFCollisionTriangle)*numTris + MFString_Length(pItemName) + 1); pMesh = (MFCollisionMesh*)MFALIGN16(&pTemplate[1]); pTris = (MFCollisionTriangle*)MFALIGN16(&pMesh[1]); pItem->pTemplate = pTemplate; pItem->flags = 0; pItem->refCount = 1; pItem->worldPos = MFMatrix::identity; pTemplate->pCollisionTemplateData = pMesh; pTemplate->type = MFCT_Mesh; pTemplate->pName = (char*)&pTris[numTris]; MFString_Copy((char*)pTemplate->pName, pItemName); pMesh->numTris = numTris; pMesh->pTriangles = pTris; return pItem; }
MF_API void MFVertex_LockVertexBuffer(MFVertexBuffer *pVertexBuffer, void **ppVertices) { MFDebug_Assert(pVertexBuffer, "Null vertex buffer"); MFDebug_Assert(!pVertexBuffer->bLocked, "Vertex buffer already locked!"); if(pVertexBuffer->bufferType == MFVBType_Dynamic) { ID3D11Buffer *pVB = (ID3D11Buffer*)pVertexBuffer->pPlatformData; D3D11_MAPPED_SUBRESOURCE subresource; D3D11_MAP map = (pVertexBuffer->bufferType == MFVBType_Dynamic) ? D3D11_MAP_WRITE_DISCARD : D3D11_MAP_WRITE; HRESULT hr = g_pImmediateContext->Map(pVB, 0, map, D3D11_MAP_FLAG_DO_NOT_WAIT, &subresource); if(hr == DXGI_ERROR_WAS_STILL_DRAWING) { MFDebug_Message("waiting on vertex buffer lock"); hr = g_pImmediateContext->Map(pVB, 0, map, 0, &subresource); } MFDebug_Assert(SUCCEEDED(hr), "Failed to map vertex buffer"); pVertexBuffer->pLocked = subresource.pData; } else { pVertexBuffer->pLocked = MFHeap_Alloc(pVertexBuffer->numVerts*pVertexBuffer->pVertexDeclatation->pElementData[0].stride, MFHeap_GetHeap(MFHT_ActiveTemporary)); } if(ppVertices) *ppVertices = pVertexBuffer->pLocked; pVertexBuffer->bLocked = true; }
MF_API void MFInput_EnableBufferedInput(bool bEnable, int frequency) { gInputFrequency = frequency; if(!gInputThread) { for(int i=0; i<MFInput_MaxInputID; ++i) { gInputEvents[IDD_Gamepad][i] = (MFInputEvent*)MFHeap_Alloc(sizeof(MFInputEvent)*MaxEvents); gNumEvents[IDD_Gamepad][i] = 0; } gInputMutex = MFThread_CreateMutex("MFInput Mutex"); gInputThread = MFThread_CreateThread("MFInput Thread", &MFInput_Thread, NULL); } else { bInputTerminate = true; MFThread_Join(gInputThread); gInputThread = NULL; MFThread_DestroyMutex(gInputMutex); for(int i=0; i<MFInput_MaxInputID; ++i) { MFHeap_Free(gInputEvents[IDD_Gamepad][i]); } } }
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; }
MF_API MFVertexBuffer *MFVertex_CreateVertexBuffer(const MFVertexDeclaration *pVertexFormat, int numVerts, MFVertexBufferType type, void *pVertexBufferMemory, const char *pName) { int nameLen = pName ? MFString_Length(pName) + 1 : 0; MFVertexBuffer *pVB; if(type == MFVBType_Scratch) pVB = (MFVertexBuffer*)MFRenderer_AllocateScratchMemory(sizeof(MFVertexBuffer) + nameLen); else pVB = (MFVertexBuffer*)MFHeap_Alloc(sizeof(MFVertexBuffer) + nameLen); MFZeroMemory(pVB, sizeof(MFVertexBuffer)); if(pName) pName = MFString_Copy((char*)&pVB[1], pName); pVB->pVertexDeclatation = pVertexFormat; pVB->bufferType = type; pVB->numVerts = numVerts; if(!MFVertex_CreateVertexBufferPlatformSpecific(pVB, pVertexBufferMemory)) { if(type != MFVBType_Scratch) MFHeap_Free(pVB); return NULL; } if(type == MFVBType_Scratch) { // add to a scratch list that will be cleaned up later... pVB->pNextScratchBuffer = gpScratchBufferList; gpScratchBufferList = pVB; } else MFResource_AddResource(pVB, MFRT_VertexBuffer, (uint32)(MFUtil_HashPointer(pVB) & 0xFFFFFFFF), pName); return pVB; }
MF_API wchar_t* MFWString_Dup(const wchar_t *pString) { size_t len = MFWString_Length(pString); wchar_t *pNew = (wchar_t*)MFHeap_Alloc((len + 1)*sizeof(wchar_t)); MFWString_Copy(pNew, pString); return pNew; }
MF_API char* MFString_Dup(const char *pString) { size_t len = MFString_Length(pString); char *pNew = (char*)MFHeap_Alloc(len + 1); MFString_Copy(pNew, pString); return pNew; }
void MFPoolHeap::Init(int num, size_t size, void *pMem, size_t memsize) { MFDebug_Assert(num > 0 && size >= 4 && (size & 3) == 0, "Bad args"); itemSize = size; numItems = num; pNext = NULL; #if !defined(MF_RETAIL) peakNumUsed = 0; #endif // Get the memory for the heap if(pMem) { MFDebug_Assert(memsize > num*size, "Not enought memory"); pStorage = pMem; bOwnStorage = false; } else { pStorage = MFHeap_Alloc(num*size); bOwnStorage = true; } DeleteAll(); }
MF_API int MFFileSystem_MountFujiPath(const char *pMountpoint, const char *pFujiPath, int priority, uint32 flags) { const char *pColon = MFString_Chr(pFujiPath, ':'); if(!pColon) return -1; // not a fuji path. needs a volume name! MFMount *pMount = MFFileSystem_FindVolume(MFStrN(pFujiPath, pColon-pFujiPath)); if(!pMount) return -2; // volume not mounted // get the path // ++pColon; // const char *pNewPath = MFStr("%s%s", pColon, MFString_EndsWith(pColon, "/") ? "" : "/"); MFMount *pNew = (MFMount*)MFHeap_Alloc(sizeof(MFMount) + MFString_Length(pMountpoint) + 1); MFCopyMemory(pNew, pMount, sizeof(MFMount)); pNew->volumeInfo.pVolumeName = (const char*)&pNew[1]; MFString_Copy((char*)pNew->volumeInfo.pVolumeName, pMountpoint); pNew->volumeInfo.priority = priority; pNew->volumeInfo.flags = (pNew->volumeInfo.flags & ~MFMF_DontCacheTOC) | flags; return MFFileSystem_AddVolume(pNew); }
void MFObjectPool::Init(size_t _objectSize, int numObjects, int growObjects, void *_pMemory, size_t _bytes) { objectSize = _objectSize; maxItems = numObjects; grow = growObjects; allocated = 0; bytes = _objectSize * numObjects; if(_pMemory) { MFDebug_Assert((uint32)bytes <= _bytes, "Supplied allocation is too small!"); pMemory = (char*)_pMemory; bOwnMemory = false; } else { pMemory = (char*)MFHeap_Alloc(bytes + sizeof(void**)*numObjects); bOwnMemory = true; } ppItems = (void**)(pMemory + bytes); for(int a=0; a<numObjects; ++a) ppItems[a] = pMemory + _objectSize*a; pNext = NULL; mutex = MFThread_CreateMutex("MFObjectPool alloc mutex"); }
MFInitStatus MFView_InitModule() { // allocate view stack gpViewStack = (MFView*)MFHeap_Alloc(sizeof(MFView) * gDefaults.view.maxViewsOnStack); // set default ortho rect MFView::defaultOrthoRect.x = gDefaults.view.orthoMinX; MFView::defaultOrthoRect.y = gDefaults.view.orthoMinY; MFView::defaultOrthoRect.width = gDefaults.view.orthoMaxX; MFView::defaultOrthoRect.height = gDefaults.view.orthoMaxY; // initialise default view MFZeroMemory(&MFView::defaultView, sizeof(MFView)); pCurrentView = &MFView::defaultView; pCurrentView->cameraMatrix = MFMatrix::identity; pCurrentView->view = MFMatrix::identity; pCurrentView->viewProj = MFMatrix::identity; MFView_SetOrtho(&MFView::defaultOrthoRect); MFView_ConfigureProjection(MFDEGREES(gDefaults.view.defaultFOV), gDefaults.view.defaultNearPlane, gDefaults.view.defaultFarPlane); MFView_SetAspectRatio(gDefaults.view.defaultAspect); MFView_SetProjection(); pCurrentView = gpViewStack; MFView_SetDefault(); return MFIS_Succeeded; }
MFInitStatus MFFileSystem_InitModule(int moduleId, bool bPerformInitialisation) { gModuleId = moduleId; if(!bPerformInitialisation) return MFIS_Succeeded; ALLOC_MODULE_DATA(MFFileSystemState); pModuleData->hNativeFileSystem = -1; pModuleData->hMemoryFileSystem = -1; pModuleData->hCachedFileSystem = -1; pModuleData->hZipFileSystem = -1; pModuleData->hHTTPFileSystem = -1; pModuleData->hFTPFileSystem = -1; pModuleData->gOpenFiles.Init(sizeof(MFFile), gDefaults.filesys.maxOpenFiles, gDefaults.filesys.maxOpenFiles); pModuleData->gFileSystems.Init("File Systems", gDefaults.filesys.maxFileSystems); pModuleData->ppFileSystemList = (MFFileSystem**)MFHeap_Alloc(sizeof(MFFileSystem*) * gDefaults.filesys.maxFileSystems); MFZeroMemory(pModuleData->ppFileSystemList, sizeof(MFFileSystem*) * gDefaults.filesys.maxFileSystems); pModuleData->gFinds.Init("File System Find Instances", gDefaults.filesys.maxFinds); return MFIS_Succeeded; }
// 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; }
void *MFObjectPool::Alloc() { MFThread_LockMutex(mutex); void *pAlloc = NULL; if(allocated < maxItems) { pAlloc = ppItems[allocated++]; } else { if(pNext) { pAlloc = pNext->Alloc(); } else if(grow) { MFHeap *pHeap = MFHeap_GetAllocHeap(pMemory); MFHeap *pOld = MFHeap_SetActiveHeap(pHeap); pNext = (MFObjectPool*)MFHeap_Alloc(sizeof(MFObjectPool)); pNext->Init(objectSize, grow, grow); MFHeap_SetActiveHeap(pOld); pAlloc = pNext->Alloc(); } } MFThread_ReleaseMutex(mutex); return pAlloc; }
MF_API MFCollisionItem* MFCollision_CreateField(const char *pFieldName, int maximumItemCount, const MFVector &cellSize) { MFCollisionItem *pItem; MFCollisionTemplate *pTemplate; MFCollisionField *pField; pItem = MFCollision_CreateCollisionItem(); pTemplate = (MFCollisionTemplate*)MFHeap_Alloc(sizeof(MFCollisionTemplate) + sizeof(MFCollisionField) + MFString_Length(pFieldName) + 1); pField = (MFCollisionField*)&pTemplate[1]; pItem->pTemplate = pTemplate; pItem->flags = 0; pItem->refCount = 1; pItem->worldPos = MFMatrix::identity; pTemplate->pCollisionTemplateData = pField; pTemplate->type = MFCT_Field; pTemplate->pName = (char*)&pField[1]; MFString_Copy((char*)pTemplate->pName, pFieldName); pField->itemList.Init("Collision Field Items", maximumItemCount); pField->pppItems = NULL; pField->cellSize = cellSize; return pItem; }
MF_API MFParticleEmitter* MFParticleSystem_CreateEmitter(MFParticleEmitterParameters *pEmitterParams) { MFParticleEmitter *pEmitter = (MFParticleEmitter*)MFHeap_Alloc(sizeof(MFParticleEmitter)); pEmitter->params = *pEmitterParams; pEmitter->emitPeriod = pEmitter->params.emitRate == 0.0f ? 0.0f : 1.0f / pEmitter->params.emitRate; pEmitter->emitTimeout = 0.0f; return pEmitter; }
MFInitStatus MFRenderer_InitModule(int moduleId, bool bPerformInitialisation) { gScratchMemorySize = gDefaults.render.renderHeapSize; int old = MFHeap_SetAllocAlignment(128); // 4k maybe? texture page? pScratchMemory = (char*)MFHeap_Alloc(gScratchMemorySize); MFHeap_SetAllocAlignment(old); MFRenderer_InitModulePlatformSpecific(); return MFIS_Succeeded; }
MF_API void MFVertex_LockIndexBuffer(MFIndexBuffer *pIndexBuffer, uint16 **ppIndices) { MFDebug_Assert(pIndexBuffer, "NULL index buffer"); MFDebug_Assert(!pIndexBuffer->bLocked, "Index buffer already locked!"); pIndexBuffer->pLocked = MFHeap_Alloc(sizeof(uint16)*pIndexBuffer->numIndices, MFHeap_GetHeap(MFHT_ActiveTemporary)); if(ppIndices) *ppIndices = (uint16*)pIndexBuffer->pLocked; pIndexBuffer->bLocked = true; }
static bool GetModes(Resolution **_modes, bool fullscreen) { MFCALLSTACK; int numModeLines; if(!fullscreen) { modes = defaultModes; for(uint32 i = 0; modes[i].width != 0; ++i) { ++numModes; } } else { int throwaway; if(!XF86VidModeQueryExtension(xdisplay, &throwaway, &throwaway)) { SetSingleMode(_modes); return true; } if((!XF86VidModeGetAllModeLines(xdisplay, screen, &numModeLines, &vidModes)) || numModeLines < 2) { SetSingleMode(_modes); return true; } originalVidMode = vidModes[0]; numModes = (uint32)numModeLines; modes = (Resolution *)MFHeap_Alloc(sizeof(Resolution) * (numModes + 1)); for(int32 i = 0; i < numModes; i++) { modes[i].width = vidModes[i]->hdisplay; modes[i].height = vidModes[i]->vdisplay; modes[i].refresh = ((float)vidModes[i]->dotclock / (float)vidModes[i]->htotal) / (float)vidModes[i]->htotal; } modes[numModes].width = 0; modes[numModes].height = 0; } if(_modes != NULL) *_modes = modes; return true; }
void MFObjectPoolGroup::Init(const MFObjectPoolGroupConfig *_pPools, int _numPools) { pConfig = (MFObjectPoolGroupConfig*)MFHeap_Alloc(sizeof(MFObjectPoolGroupConfig)*_numPools + sizeof(MFObjectPool)*_numPools); pPools = (MFObjectPool*)&pConfig[_numPools]; numPools = _numPools; MFCopyMemory(pConfig, _pPools, sizeof(MFObjectPoolGroupConfig)*_numPools); mutex = MFThread_CreateMutex("MFObjectPoolGroup alloc mutex"); for(int a=0; a<_numPools; ++a) { pPools[a].Init(pConfig[a].objectSize, pConfig[a].numObjects, pConfig[a].growObjects); } }
void MFSound_CreateInternal(MFSound *pSound) { MFSoundTemplate *pTemplate = pSound->pTemplate; MFSoundDataInternal *pInternal = pSound->pInternal; alGenBuffers(1, &pInternal->buffer); // if dynamic, allocate buffer if(pTemplate->flags & MFSF_Dynamic) { long bufferSize = ((pTemplate->numChannels * pTemplate->bitsPerSample) >> 3) * pTemplate->numSamples; if(gpCurrentContext->ext.static_buffer) { pTemplate->ppStreams = (char**)MFHeap_Alloc(sizeof(char*) + bufferSize); pTemplate->ppStreams[0] = (char*)&pTemplate->ppStreams[1]; alBufferDataStatic(pInternal->buffer, pInternal->format, pTemplate->ppStreams[0], bufferSize, pTemplate->sampleRate); } else if(gpCurrentContext->ext.buffer_sub_data) { switch((pTemplate->numChannels << 16) | pTemplate->bitsPerSample) { case 0x10000 | 8: pInternal->format = AL_FORMAT_MONO8; break; case 0x20000 | 8: pInternal->format = AL_FORMAT_STEREO8; break; case 0x10000 | 16: pInternal->format = AL_FORMAT_MONO16; break; case 0x20000 | 16: pInternal->format = AL_FORMAT_STEREO16; break; case 0x10000 | 32: if(gpCurrentContext->ext.float32) pInternal->format = AL_FORMAT_MONO_FLOAT32; else MFDebug_Assert(false, "Unsupported sample format!"); break; case 0x20000 | 32: if(gpCurrentContext->ext.float32) pInternal->format = AL_FORMAT_STEREO_FLOAT32; else MFDebug_Assert(false, "Unsupported sample format!"); break; default: MFDebug_Assert(false, "Unsupported sample format!"); break; } // set buffer data with null allocates a buffer filled with undefined junk alBufferData(pInternal->buffer, pInternal->format, NULL, bufferSize, pTemplate->sampleRate); } }
static void SetSingleMode(Resolution **modes) { *modes = (Resolution *)MFHeap_Alloc(sizeof(Resolution) * 2); (*modes)[0].width = DisplayWidth(xdisplay, screen); (*modes)[0].height = DisplayHeight(xdisplay, screen); (*modes)[0].refresh = 0; (*modes)[1].width = 0; (*modes)[1].height = 0; (*modes)[1].refresh = 0; originalVidMode = vidModes[0]; numModes = 1; }
MF_API void MFMaterial_RegisterMaterialType(const char *pName, const MFMaterialCallbacks *pCallbacks) { MFCALLSTACK; MFMaterialType *pMatType; pMatType = (MFMaterialType*)MFHeap_Alloc(sizeof(MFMaterialType) + MFString_Length(pName) + 1); pMatType->pTypeName = (char*)&pMatType[1]; MFString_Copy(pMatType->pTypeName, pName); MFDebug_Assert(pCallbacks->pBegin, "Material must supply Begin() callback."); MFCopyMemory(&pMatType->materialCallbacks, pCallbacks, sizeof(MFMaterialCallbacks)); gMaterialRegistry.Create(pMatType); pCallbacks->pRegisterMaterial(NULL); }
MF_API MFMaterial* MFMaterial_Create(const char *pName) { MFCALLSTACK; MFMaterial *pMat = MFMaterial_Find(pName); if(!pMat) { pMat = (MFMaterial*)MFHeap_Alloc(sizeof(MFMaterial) + MFString_Length(pName) + 1); MFZeroMemory(pMat, sizeof(MFMaterial)); pMat->pName = (char*)&pMat[1]; MFString_Copy(pMat->pName, pName); gMaterialList.Create(pMat); MaterialDefinition *pDef = pDefinitionRegistry; while(pDef) { MFIniLine *pLine = pDef->pIni->GetFirstLine()->FindEntry("section",pName); if (pLine) { MaterialInternal_InitialiseFromDefinition(pDef->pIni, pMat, pName); break; } pDef = pDef->pNextDefinition; } if(!pDef) { // assign material type pMat->pType = MaterialInternal_GetMaterialType("Standard"); pMat->pType->materialCallbacks.pCreateInstance(pMat); // set diffuse map parameter MFMaterial_SetParameterS(pMat, MFMatStandard_Texture, MFMatStandard_Tex_DifuseMap, pName); } } pMat->refCount++; return pMat; }
MFFileSystemHandle MFFileSystem_RegisterFileSystem(const char *pFilesystemName, MFFileSystemCallbacks *pCallbacks) { MFDebug_Log(5, MFStr("Call: MFFileSystem_RegisterFileSystem(\"%s\")", pFilesystemName)); GET_MODULE_DATA(MFFileSystemState); for(uint32 a=0; a<gDefaults.filesys.maxFileSystems; a++) { if(pModuleData->ppFileSystemList[a] == NULL) { MFDebug_Assert(pCallbacks->Open, "No Open function supplied."); MFDebug_Assert(pCallbacks->Close, "No Close function supplied."); MFDebug_Assert(pCallbacks->Read, "No Read function supplied."); MFDebug_Assert(pCallbacks->Write, "No Write function supplied."); MFDebug_Assert(pCallbacks->Seek, "No Seek function supplied."); MFFileSystem *pFS = pModuleData->gFileSystems.Create(); MFZeroMemory(pFS, sizeof(MFFileSystem)); MFString_Copy(pFS->name, pFilesystemName); MFCopyMemory(&pFS->callbacks, pCallbacks, sizeof(MFFileSystemCallbacks)); pModuleData->ppFileSystemList[a] = pFS; #if defined(USE_JOB_THREAD) pFS->ppJobQueue = (MFJob**)MFHeap_Alloc(sizeof(MFJob*)*MAX_JOBS); pFS->jobs.Init(MFStr("%s Job List", pFilesystemName), MAX_JOBS+2); pFS->readJob = 0; pFS->writeJob = 0; pFS->numJobs = MAX_JOBS; pFS->semaphore = MFThread_CreateSemaphore("Filesystem Semaphore", MAX_JOBS, 0); pFS->thread = MFThread_CreateThread(MFStr("%s Thread", pFilesystemName), MKFileJobThread, pFS, MFPriority_AboveNormal); #endif if(pFS->callbacks.RegisterFS) pFS->callbacks.RegisterFS(); return a; } } MFDebug_Assert(false, MFStr("Exceeded maximum of %d Filesystems. Modify 'gDefaults.filesys.maxFileSystems'.", gDefaults.filesys.maxFileSystems)); return -1; }
MF_API MFParticleSystem* MFParticleSystem_Create(MFParticleParameters *pParticleParams) { MFParticleSystem *pSystem = (MFParticleSystem*)MFHeap_Alloc(sizeof(MFParticleSystem)); pSystem->params = *pParticleParams; if(!pParticleParams->pMaterial) pSystem->pMaterial = MFMaterial_Create("_None"); else { pSystem->pMaterial = MFMaterial_Create(pParticleParams->pMaterial); // int additive = MFMaterial_GetParameterIndexFromName(pSystem->pMaterial, "additive"); MFMaterial_SetParameterI(pSystem->pMaterial, MFMatStandard_ZWrite, 0, 0); } pSystem->particles.Init("ParticleSystem", pSystem->params.maxActiveParticles); return pSystem; }