int F3DFile::ReadMD2(const char *pFilename) { pModel = this; size_t size; char *pFile = MFFileSystem_Load(pFilename, &size); if(!pFile) { MFDebug_Warn(2, MFStr("Failed to open MD2 file %s", pFilename)); return 1; } int a; for(a=MFString_Length(pFilename)-1; a>=0; --a) { if(pFilename[a] == '/' || pFilename[a] == '\\') { break; } } MFString_Copy(pModel->name, &pFilename[a+1]); pModel->name[MFString_Length(pModel->name) - 4] = 0; ParseMD2File(pFile, size); MFHeap_Free(pFile); return 0; }
static int MFFileSystem_GetNumEntries(const char *pFindPattern, bool recursive, bool flatten, size_t *pStringLengths) { MFFindData findData; MFFind *hFind; int numFiles = 0; hFind = MFFileSystem_FindFirst(MFString::Format("%s*", pFindPattern).CStr(), &findData); if(hFind) { *pStringLengths += MFString_Length(findData.pSystemPath) + 1; } while(hFind) { if(MFString_Compare(findData.pFilename, ".") && MFString_Compare(findData.pFilename, "..") && MFString_Compare(findData.pFilename, ".svn")) { if(findData.info.attributes & MFFA_Directory) { if(recursive) { if(flatten) { MFString newPath = MFString::Format("%s%s/", pFindPattern, findData.pFilename); numFiles += MFFileSystem_GetNumEntries(newPath.CStr(), recursive, flatten, pStringLengths); } else { *pStringLengths += MFString_Length(findData.pFilename) + 1; ++numFiles; } } } else { *pStringLengths += MFString_Length(findData.pFilename) + 1; ++numFiles; } } if(!MFFileSystem_FindNext(hFind, &findData)) { MFFileSystem_FindClose(hFind); hFind = NULL; } } return numFiles; }
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 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); }
MF_API void DebugMenu_AddMenuTo(const char *name, Menu *pParent, DebugCallback callback, void *userData) { MFDebug_Assert(pParent, "Invalid parent menu."); MFDebug_Assert(pParent->type == MenuType_Menu, MFStr("Cant add menu '%s', Parent is not of Menu type.", name)); MFDebug_Assert(MFString_Length(name) < 64, "Max of 64 characters in Menu Name."); MFDebug_Assert(pParent->numChildren < MENU_MAX_CHILDREN, MFStr("Maximum number of items in menu: '%s'", pParent->name)); // Menu *pMenu = Heap_New(Menu); Menu *pMenu = new Menu; MFString_Copy(pMenu->name, name); pMenu->type = MenuType_Menu; pMenu->pParent = pParent; pMenu->menuDepth = pParent->menuDepth+1; pMenu->numChildren = 0; pMenu->selection = 0; pMenu->pCallback = callback; pMenu->pUserData = userData; pParent->pChildren[pParent->numChildren] = pMenu; ++pParent->numChildren; }
MF_API size_t MFString_URLEncode(char *pDest, const char *pString, const char *pExcludeChars) { size_t sourceLen = MFString_Length(pString); size_t destLen = 0; for(size_t a=0; a<sourceLen; ++a) { int c = (uint8)pString[a]; if(MFIsAlphaNumeric(c) || MFString_Chr("-_.!~*'()", c) || (pExcludeChars && MFString_Chr(pExcludeChars, c))) { if(pDest) pDest[destLen] = (char)c; destLen++; } else if(c == ' ') { if(pDest) pDest[destLen] = '+'; destLen++; } else { if(pDest) destLen += sprintf(pDest + destLen, "%%%02X", c); else destLen += 3; // *** surely this can't write more than 3 chars? '%xx' } } if(pDest) pDest[destLen] = 0; return destLen; }
MF_API const char* MFStr_URLEncodeString(const char *pString, const char *pExcludeChars) { char *pBuffer = &gStringBuffer[gStringOffset]; size_t sourceLen = MFString_Length(pString); size_t destLen = 0; for(size_t a=0; a<sourceLen; ++a) { int c = (uint8)pString[a]; if(MFIsAlphaNumeric(c) || MFString_Chr("-_.!~*'()", c) || (pExcludeChars && MFString_Chr(pExcludeChars, c))) pBuffer[destLen++] = (char)c; else if(c == ' ') pBuffer[destLen++] = '+'; else destLen += sprintf(pBuffer + destLen, "%%%02X", c); } pBuffer[destLen] = 0; gStringOffset += destLen+1; if(gStringOffset >= sizeof(gStringBuffer) - 1024) gStringOffset = 0; return pBuffer; }
int F3DFile::ReadMD2(const char *pFilename) { pModel = this; size_t size; char *pFile = MFFileSystem_Load(pFilename, &size); if(!pFile) { MFDebug_Warn(2, MFStr("Failed to open MD2 file %s", pFilename)); return 1; } int a; for(a=(int)MFString_Length(pFilename)-1; a>=0; --a) { if(pFilename[a] == '/' || pFilename[a] == '\\') { break; } } pModel->name = pFilename + a+1; pModel->name.TruncateExtension(); ParseMD2File(pFile, size); MFHeap_Free(pFile); return 0; }
MFString& MFString::PadRight(int minLength, const char *pPadding, bool bAlignPadding) { // check if the string is already long enough int len = NumBytes(); if(len >= minLength) return *this; // reserve enough memory Reserve(minLength + 1); pData->bytes = minLength; pData->pMemory[minLength] = 0; // pad the string size_t padLen = MFString_Length(pPadding); size_t b = bAlignPadding ? len%padLen : 0; for(int a=len; a<minLength; ++a, ++b) { if(b >= padLen) b = 0; pData->pMemory[a] = pPadding[b]; } return *this; }
MFString& MFString::PadLeft(int minLength, const char *pPadding) { // check if the string is already long enough int len = NumBytes(); if(len >= minLength) return *this; // reserve enough memory Reserve(minLength + 1); pData->bytes = minLength; // move string size_t preBytes = minLength - len; for(int a=len; a>=0; --a) pData->pMemory[a + preBytes] = pData->pMemory[a]; // pre-pad the string size_t padLen = MFString_Length(pPadding); for(size_t a=0, b=0; a<preBytes; ++a, ++b) { if(b >= padLen) b = 0; pData->pMemory[a] = pPadding[b]; } return *this; }
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 MFRenderer_D3D11_SetDebugName(ID3D11DeviceChild* pResource, const char* pName) { #if !defined(MF_RETAIL) if (pResource) pResource->SetPrivateData(WKPDID_D3DDebugObjectName, (UINT)MFString_Length(pName), pName); #endif }
const char* GetMaterialName(const char *pSkin, const char *pSubobjectName) { if(pSkin) { char *pTok = MFString_Chr(pSkin, ','); while(pTok) { char *pT = pTok-1; for(; pT > pSkin && pT[-1] != '\n'; --pT) { } // get subobject name char *pTokTemp = pTok - (uintp)pT; const char *pSubName = MFStrN(pT, (int&)pTokTemp); ++pTok; if(!MFString_CaseCmp(pSubName, pSubobjectName)) { for(pT = pTok; *pT != 0 && *pT != '\r' && *pT != '\n'; ++pT) { } // get texture name pTokTemp = pT - (uintp)pTok; char *pMaterialName = (char*)MFStrN(pTok, (int&)pTokTemp); for(pT = pMaterialName+MFString_Length(pMaterialName); pT > pMaterialName && pT[-1] != '/' && pT[-1] != '\\' && pT[-1] != '\n' && pT[-1] != '\r'; --pT) { } pT[MFString_Length(pT) - 4] = 0; return pT; } pTok = MFString_Chr(pTok, ','); } } return NULL; }
// open a file from the mounted filesystem stack MF_API MFFile* MFFileSystem_Open(const char *pFilename, uint32 openFlags) { MFDebug_Log(5, MFStr("Call: MFFileSystem_Open(\"%s\", 0x%x)", pFilename, openFlags)); GET_MODULE_DATA(MFFileSystemState); MFMount *pMount = pModuleData->pMountList; const char *pMountpoint = NULL; // search for a mountpoint size_t len = MFString_Length(pFilename); for(size_t a=0; a<len; a++) { if(pFilename[a] == ':') { pMountpoint = MFStrN(pFilename, a); pFilename += a+1; break; } if(pFilename[a] == '.') { // if we have found a dot, this cant be a mountpoint // (mountpoints may only be alphanumeric) break; } } // search for file through the mount list... while(pMount) { int onlyexclusive = pMount->volumeInfo.flags & MFMF_OnlyAllowExclusiveAccess; if((!pMountpoint && !onlyexclusive) || (pMountpoint && !MFString_CaseCmp(pMountpoint, pMount->volumeInfo.pVolumeName))) { // open the file from a mount MFFile *hFile = pModuleData->ppFileSystemList[pMount->volumeInfo.fileSystem]->callbacks.FSOpen(pMount, pFilename, openFlags); if(hFile) return hFile; } pMount = pMount->pNext; } if(!(openFlags & MFOF_TryOpen)) MFDebug_Warn(4, MFStr("MFFile_Open(\"%s\", 0x%x) - Failed to open file", pFilename, openFlags)); return NULL; }
char* ReadSceneChunk(char *pFilePtr, char *pToken) { if(!MFString_CaseCmp(pToken, "*SCENE_FILENAME")) { char *pName; pFilePtr = GetString(pFilePtr, &pName); if(MFString_Length(pName) > 255) { MFDebug_Warn(3, MFStr("Error: More than 256 characters in nodel name, \"%s\"", pName)); return pFilePtr; } pModel->name = pName; MFDebug_Log(4, MFStr("Model: %s", pName)); } else if(!MFString_CaseCmp(pToken, "*SCENE_FIRSTFRAME")) { } else if(!MFString_CaseCmp(pToken, "*SCENE_LASTFRAME")) { } else if(!MFString_CaseCmp(pToken, "*SCENE_FRAMESPEED")) { } else if(!MFString_CaseCmp(pToken, "*SCENE_TICKSPERFRAME")) { } else if(!MFString_CaseCmp(pToken, "*SCENE_BACKGROUND_STATIC")) { } else if(!MFString_CaseCmp(pToken, "*SCENE_AMBIENT_STATIC")) { } else { MFDebug_Warn(3, MFStr("Unknown token: %s", pToken)); } return pFilePtr; }
static void CreateDir(const char *pPath) { if(!pPath || *pPath == 0) return; // strip trailing '/' ((char*)pPath)[MFString_Length(pPath)-1] = 0; // the path is empty if(*pPath == 0) return; CreateDir(MFStr_GetFilePath(pPath)); CreateDirectory(pPath, NULL); }
bool MFFileNative_CreateDirectory(const char *pPath) { if(!pPath || *pPath == 0) return false; // strip trailing '/' ((char*)pPath)[MFString_Length(pPath)-1] = 0; // the path is empty if(*pPath == 0) return false; MFFileNative_CreateDirectory(MFStr_GetFilePath(pPath)); return CreateDirectory(MFString_UFT8AsWChar(pPath), NULL) != 0; }
void GotoSection(int cancel, const char *pString) { if(cancel || !*pString) return; const char *pTest = pString; while(*pTest && (MFIsNumeric(*pTest) || *pTest == '.')) ++pTest; int res = gEditor.pSong->GetRes(); if(pTest > pString) { if(!*pTest) { OffsetToMeasureAndBeat((int)((float)atof(pString) * res), &gEditor.measure, &gEditor.beat); return; } if(!MFString_CaseCmp(pTest, "s")) { float time = (float)atof(pString); OffsetToMeasureAndBeat(gEditor.pSong->CalculateTickAtTime((int64)(time*1000000.0f)), &gEditor.measure, &gEditor.beat); return; } else if(!MFString_CaseCmp(pTest, "ms")) { float time = (float)atof(pString); OffsetToMeasureAndBeat(gEditor.pSong->CalculateTickAtTime((int64)(time*1000.0f)), &gEditor.measure, &gEditor.beat); return; } } // find section by name size_t len = MFString_Length(pString); GHEvent *pSE = gEditor.pSong->events.First(); while(pSE) { if(!MFString_CaseCmpN(pSE->GetString(), "section ", 8) && !MFString_CaseCmpN(&pSE->GetString()[8], pString, len)) { OffsetToMeasureAndBeat(pSE->tick, &gEditor.measure, &gEditor.beat); return; } pSE = pSE->Next(); } }
MF_API MFMaterial* MFMaterial_Create(const char *pName) { MFCALLSTACK; MFMaterial *pMat = MFMaterial_Find(pName); if(!pMat) { pMat = (MFMaterial*)MFHeap_AllocAndZero(sizeof(MFMaterial) + MFString_Length(pName) + 1); pName = MFString_Copy((char*)&pMat[1], pName); MFResource_AddResource(pMat, MFRT_Material, MFUtil_HashString(pName) ^ 0x0a7e01a1, pName); // TODO: how to determine size? pMat->pMaterialState = MFStateBlock_Create(256); pMat->bStateDirty = true; 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->pInstanceData = MFHeap_AllocAndZero(pMat->pType->instanceDataSize); pMat->pType->materialCallbacks.pCreateInstance(pMat); // set diffuse map parameter MFMaterial_SetParameterS(pMat, MFMatStandard_Texture, MFMatStandard_Tex_DifuseMap, pName); } } return pMat; }
MFString& MFString::SetStaticString(const char *pStaticString) { if(pData) { MFStringData_Release(pData); pData = NULL; } if(pStaticString) { pData = MFStringData_Alloc(); pData->bytes = MFString_Length(pStaticString); pData->pMemory = (char*)pStaticString; } return *this; }
MFString MFString::operator+(const char *pString) const { if(!pString || *pString == 0) return *this; if(IsEmpty()) return MFString(pString); size_t bytes = pData->bytes + MFString_Length(pString); MFString t; t.Reserve(bytes + 1); MFString_CopyCat(t.pData->pMemory, pData->pMemory, pString); t.pData->bytes = bytes; return t; }
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; }
MF_API const char * MFString_ToUpper(const char *pString) { char *pBuffer = &gStringBuffer[gStringOffset]; size_t len = MFString_Length(pString); gStringOffset += len+1; char *pT = pBuffer; while(*pString) { *pT = (char)MFToUpper(*pString); ++pT; ++pString; } if(gStringOffset >= sizeof(gStringBuffer) - 1024) gStringOffset = 0; return pBuffer; }
MFString& MFString::operator=(const char *pString) { if(pString) { size_t bytes = MFString_Length(pString); Reserve(bytes + 1, true); MFString_Copy(pData->pMemory, pString); pData->bytes = bytes; } else if(pData) { MFStringData_Release(pData); pData = NULL; } return *this; }
MFString& MFString::operator+=(const char *pString) { if(!pString || *pString == 0) return *this; if(IsEmpty()) { *this = pString; } else { size_t sumBytes = pData->bytes + MFString_Length(pString); Reserve(sumBytes + 1); MFString_Copy(pData->pMemory + pData->bytes, pString); pData->bytes = sumBytes; } return *this; }
void HKStringEntryLogic::StringCopyOverlap(char *pDest, const char *pSrc) { if(pDest < pSrc) { while(*pSrc) *pDest++ = *pSrc++; *pDest = 0; } else { int len = MFString_Length(pSrc); while(len >= 0) { pDest[len] = pSrc[len]; --len; } } }
MFTOCEntry *MFFileSystem_GetTocEntry(const char *pFilename, MFTOCEntry *pEntry, int numEntries) { MFCALLSTACK; const char *pSearchString = pFilename; size_t nameLen = MFString_Length(pFilename); bool isDirectory = false; for(size_t a=0; a<nameLen; a++) { if(pFilename[a] == '/') { isDirectory = true; pSearchString = MFStrN(pFilename, a); pFilename += a+1; break; } } for(int a=0; a<numEntries; a++) { if(!MFString_CaseCmp(pSearchString, pEntry[a].pName)) { if(isDirectory) { if(pEntry[a].info.attributes & MFFA_Directory) { return MFFileSystem_GetTocEntry(pFilename, pEntry[a].pChildren, pEntry[a].numChildren); } } else { if(!(pEntry[a].info.attributes & MFFA_Directory)) { return &pEntry[a]; } } } } return NULL; }
MF_API MFIndexBuffer *MFVertex_CreateIndexBuffer(int numIndices, uint16 *pIndexBufferMemory, const char *pName) { int nameLen = pName ? MFString_Length(pName) + 1 : 0; MFIndexBuffer *pIB = (MFIndexBuffer*)MFHeap_AllocAndZero(sizeof(MFIndexBuffer) + nameLen); if(pName) pName = MFString_Copy((char*)&pIB[1], pName); pIB->numIndices = numIndices; if(!MFVertex_CreateIndexBufferPlatformSpecific(pIB, pIndexBufferMemory)) { MFHeap_Free(pIB); return NULL; } MFResource_AddResource(pIB, MFRT_IndexBuffer, (uint32)(MFUtil_HashPointer(pIB) & 0xFFFFFFFF), pName); return pIB; }
MFString::MFString(const char *pString, bool bHoldStaticPointer) { if(!pString) { pData = NULL; } else { pData = MFStringData_Alloc(); pData->bytes = MFString_Length(pString); if(bHoldStaticPointer) { pData->pMemory = (char*)pString; } else { pData->pMemory = (char*)stringHeap.Alloc(pData->bytes + 1, &pData->allocated); MFString_Copy(pData->pMemory, pString); } } }