Esempio n. 1
0
char* GetString(char *pFilePtr, char **ppString)
{
	char *pEnd;

	pFilePtr = MFSkipWhite(pFilePtr);

	if(*pFilePtr != '\"')
	{
		MFDebug_Warn(3, "Error: GetString() expected a string.");
		*ppString = (char*)"";
		return pFilePtr;
	}

	pFilePtr++;

	pEnd = pFilePtr;
	while(*pEnd != '\"' && *pEnd != 0 && !MFIsNewline(*pEnd)) pEnd++;

	if(*pEnd != '\"')
	{
		MFDebug_Warn(3, "Error: GetString() encountered an unterminated String.");
		*ppString = (char*)"";
		return pFilePtr;
	}

	*ppString = (char*)MFStrN(pFilePtr, (int)(pEnd - pFilePtr));
	pFilePtr = pEnd + 1;

	return pFilePtr;
}
Esempio n. 2
0
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);
}
Esempio n. 3
0
char* GetFloat(char *pFilePtr, float *pFloat)
{
	char *pEnd, *pToken;
	bool negative = false;
	int dotFound = 1;

	pFilePtr = MFSkipWhite(pFilePtr);

	if(*pFilePtr == '-')
	{
		negative = true;
		pFilePtr++;
	}

	pEnd = pFilePtr;
	while(MFIsNumeric(*pEnd) || (*pEnd == '.' && dotFound--)) pEnd++;

	pToken = (char*)MFStrN(pFilePtr, (int)(pEnd-pFilePtr));
	if(*pEnd == 'f') pEnd++;

	if(!MFIsWhite(*pEnd) && !MFIsNewline(*pEnd) && *pEnd != 0)
	{
		MFDebug_Warn(3, "Error: GetFloat() found non numeric character.");
		*pFloat = 0.0f;
		return pFilePtr;
	}

	pFilePtr = pEnd;

	*pFloat = (float)atof(pToken);
	if(negative) *pFloat = -*pFloat;

	return pFilePtr;
}
Esempio n. 4
0
char* GetInt(char *pFilePtr, int *pInt)
{
	char *pEnd, *pToken;
	bool negative = false;

	pFilePtr = MFSkipWhite(pFilePtr);

	if(*pFilePtr == '-')
	{
		negative = true;
		pFilePtr++;
	}

	pEnd = pFilePtr;
	while(MFIsNumeric(*pEnd)) pEnd++;

	if(!MFIsWhite(*pEnd) && !MFIsNewline(*pEnd) && *pEnd != 0)
	{
		MFDebug_Warn(3, "Error: GetInt() found non numeric character.");
		*pInt = 0;
		return pFilePtr;
	}

	pToken = (char*)MFStrN(pFilePtr, (int)(pEnd - pFilePtr));
	pFilePtr = pEnd;

	*pInt = atoi(pToken);
	if(negative) *pInt = -*pInt;

	return pFilePtr;
}
Esempio n. 5
0
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;
}
Esempio n. 6
0
// 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;
}
Esempio n. 7
0
const char *GetRestOfLine(const char *&pString)
{
	while(MFIsWhite(*pString))
		++pString;

	const char *pEnd = pString;
	while(*pEnd && !MFIsNewline(*pEnd))
		++pEnd;

	const char *pRestOfLine = MFStrN(pString, (int)((uintp)pEnd - (uintp)pString));
	pString = pEnd;

	return pRestOfLine;
}
Esempio n. 8
0
const char *GetNextIndex(const char *&pString)
{
	if(*pString == '/')
		++pString;

	const char *pEnd = pString;

	while(*pEnd && *pEnd != '/')
		++pEnd;

	const char *pToken = MFStrN(pString, (int)((uintp)pEnd-(uintp)pString));
	pString = pEnd;

	return pToken;
}
Esempio n. 9
0
const char *GetNextToken(const char *&pString)
{
	while(MFIsWhite(*pString) || MFIsNewline(*pString))
		++pString;

	const char *pEnd = pString;

	while(*pEnd && !MFIsWhite(*pEnd) && !MFIsNewline(*pEnd))
		++pEnd;

	const char *pToken = MFStrN(pString, (int)((uintp)pEnd-(uintp)pString));
	pString = pEnd;

	return pToken;
}
Esempio n. 10
0
char *ProcessBlock(char *pFilePtr, const char *pBlockName, char* (*BlockFunc)(char*, char*))
{
	char *pEnd;
	char *pToken;

	int braceCount = 0;
	bool inQuote = false;

	pFilePtr = MFSkipWhite(pFilePtr);

	if(*pFilePtr != '{')
	{
		MFDebug_Warn(3, MFStr("Error: Expected %s Block.", pBlockName));
		return pFilePtr;
	}

	pFilePtr++;

	while(*pFilePtr != 0)
	{
		while(!(*pFilePtr == '*' && !braceCount && !inQuote) && *pFilePtr != 0)
		{
			if(*pFilePtr == '\"') inQuote = !inQuote;
			if(!inQuote)
			{
				if(*pFilePtr == '{') braceCount++;
				if(*pFilePtr == '}') braceCount--;
			}
			pFilePtr++;

			if(braceCount < 0) return pFilePtr;
		}

		pEnd = pFilePtr;

		while(!MFIsWhite(*pEnd) && *pEnd != 0) pEnd++;

		pToken = (char*)MFStrN(pFilePtr, (int)(pEnd - pFilePtr));
		pFilePtr = pEnd;

		pFilePtr = BlockFunc(pFilePtr, pToken);
	}

	return pFilePtr;
}
Esempio n. 11
0
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;
}
Esempio n. 12
0
void ParseMD3File(char *pBuffer, uint32 bufferSize, const char *pFilename, const char *pSkin)
{
	int a,b;

	F3DMeshChunk *pMC = pModel->GetMeshChunk();
	F3DSkeletonChunk *pSC = pModel->GetSkeletonChunk();

	MD3Header *pHeader = (MD3Header*)pBuffer;

//	DBGASSERT(pHeader->ident == (('3'<<24) | ('P'<<16) | ('D'<<8) | 'I'), "Invalid MD3 header.");
//	DBGASSERT(pHeader->version == 15, "Invalid MD3 version.");
//	DBGASSERT(pHeader->offsetEnd == bufferSize, "Incorrect MD3 Size.");

	(char*&)pHeader->pTags += (uintp)pBuffer;
	(char*&)pHeader->pSurfaces += (uintp)pBuffer;

	// read materials
	if(pSkin)
	{
		char *pT, *pTok = MFString_Chr(pSkin, ',');

		while(pTok)
		{
			++pTok;
			for(pT = pTok; *pT != 0 && *pT != '\r' && *pT != '\n'; ++pT) { }

			// get texture name
			char *pTT = pT - (uintp)pTok;
			char *pMaterialName = (char*)MFStrN(pTok, (int&)pTT);

			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;

			if(*pT && pModel->GetMaterialChunk()->GetMaterialIndexByName(pT) == -1)
			{
				F3DMaterial &mat = pModel->GetMaterialChunk()->materials.push();

				mat.name = pT;
				mat.maps[0] = pT;
			}

			pTok = MFString_Chr(pTok, ',');
		}
	}

	// process bones
	for(a=0; a<pHeader->numTags; a++)
	{
		F3DBone &bone = pSC->bones.push();

		bone.name = pHeader->pTags[a].tagName;

		bone.worldMatrix.SetXAxis3(MakeVector(pHeader->pTags[a].rotationMatrix[0][0], pHeader->pTags[a].rotationMatrix[0][1], pHeader->pTags[a].rotationMatrix[0][2]));
		bone.worldMatrix.SetYAxis3(MakeVector(pHeader->pTags[a].rotationMatrix[1][0], pHeader->pTags[a].rotationMatrix[1][1], pHeader->pTags[a].rotationMatrix[1][2]));
		bone.worldMatrix.SetZAxis3(MakeVector(pHeader->pTags[a].rotationMatrix[2][0], pHeader->pTags[a].rotationMatrix[2][1], pHeader->pTags[a].rotationMatrix[2][2]));
		bone.worldMatrix.SetTrans3(MakeVector(pHeader->pTags[a].origin[0], pHeader->pTags[a].origin[1], pHeader->pTags[a].origin[2]));
	}

	// process mesh
	for(a=0; a<pHeader->numSurfaces; a++)
	{
//		DBGASSERT(pHeader->pSurfaces->identity == (('3'<<24) | ('P'<<16) | ('D'<<8) | 'I'), "Invalid MD3 surface header.");

		(char*&)pHeader->pSurfaces->pTextureCoords += (uintp)pHeader->pSurfaces;
		(char*&)pHeader->pSurfaces->pTriangles += (uintp)pHeader->pSurfaces;
		(char*&)pHeader->pSurfaces->pVertices += (uintp)pHeader->pSurfaces;

		F3DSubObject &sub = pMC->subObjects.push();
		F3DMaterialSubobject &matSub = sub.matSubobjects[0];

		// read subobject name
		sub.name = pHeader->pSurfaces->surfaceName;

		// find material info
		matSub.materialIndex = pModel->GetMaterialChunk()->GetMaterialIndexByName(GetMaterialName(pSkin, sub.name.CStr()));

		// create one colour (white)
		sub.colours.resize(1);
		sub.colours[0] = MFVector::one;

		// read vertex data
		sub.uvs.resize(pHeader->pSurfaces->numVertices);
		sub.positions.resize(pHeader->pSurfaces->numVertices);
		sub.normals.resize(pHeader->pSurfaces->numVertices);

		for(b=0; b<pHeader->pSurfaces->numVertices; b++)
		{
			sub.uvs[b] = MakeVector(pHeader->pSurfaces->pTextureCoords[b].u, pHeader->pSurfaces->pTextureCoords[b].v);
			sub.normals[b] = MD3DecodeNormal(pHeader->pSurfaces->pVertices[b].encodedNormal);
			sub.positions[b] = MakeVector(pHeader->pSurfaces->pVertices[b].x, pHeader->pSurfaces->pVertices[b].y, pHeader->pSurfaces->pVertices[b].z);

			// scale vertex appropriately..
//			sub.positions[b].Mul3(sub.positions[b], 1.0f/6400.0f);
			sub.positions[b].Mul3(sub.positions[b], 1.0f/64.0f);

			matSub.vertices[b].colour = 0;
			matSub.vertices[b].normal = b;
			matSub.vertices[b].uv[0] = b;
			matSub.vertices[b].position = b;
		}

		// read triangles
		matSub.triangles.resize(pHeader->pSurfaces->numTriangles);

		for(b=0; b<pHeader->pSurfaces->numTriangles; b++)
		{
			matSub.triangles[b].v[0] = pHeader->pSurfaces->pTriangles[b].indices[0];
			matSub.triangles[b].v[1] = pHeader->pSurfaces->pTriangles[b].indices[2];
			matSub.triangles[b].v[2] = pHeader->pSurfaces->pTriangles[b].indices[1];
		}

		// skip to next surface
		(char*&)pHeader->pSurfaces += pHeader->pSurfaces->surfaceSize;
	}
}
Esempio n. 13
0
MF_API MFFind* MFFileSystem_FindFirst(const char *pSearchPattern, MFFindData *pFindData)
{
	GET_MODULE_DATA(MFFileSystemState);

	const char *pMountpoint = NULL;
	MFFind *pFind = NULL;

	// search for a mountpoint
	const char *pColon = MFString_Chr(pSearchPattern, ':');
	if(pColon)
	{
		pMountpoint = MFStrN(pSearchPattern, pColon - pSearchPattern);
		pSearchPattern = pColon + 1;
	}

	MFDebug_Assert(pMountpoint, "A volume name must be specified in the search pattern.");

	// find the volume
	MFMount *pMount = MFFileSystem_FindVolume(pMountpoint);
	if(!pMount)
	{
		MFDebug_Warn(2, MFStr("MFFileSystem_FindFirst: Volume '%s' in not mounted.", pMountpoint));
		return NULL;
	}

	// search for file through the mount list...
	if(!(pMount->volumeInfo.flags & MFMF_DontCacheTOC))
	{
		if(pMount->numFiles)
		{
			pFind = pModuleData->gFinds.Create();

			pFind->pMount = pMount;
			MFString_Copy(pFind->searchPattern, pSearchPattern);

			size_t file = 0;
			for(; file < pFind->pMount->numFiles; ++file)
			{
				if(MFString_PatternMatch(pSearchPattern, pMount->pEntries[file].pName))
					break;
			}

			if(file == pFind->pMount->numFiles)
			{
				pModuleData->gFinds.Destroy(pFind);
				pFind = NULL;
			}
			else
			{
				pFind->pFilesystemData = (void*)file;

				MFString_Copy(pFindData->pFilename, pMount->pEntries[file].pName);
				MFString_Copy(pFindData->pSystemPath, (char*)pMount->pEntries[file].pFilesysData);

				pFindData->info = pMount->pEntries[file].info;
			}
		}
	}
	else
	{
		pFind = pModuleData->gFinds.Create();

		pFind->pMount = pMount;
		pFind->pFilesystemData = NULL;
		MFString_Copy(pFind->searchPattern, pSearchPattern);

		if(!pModuleData->ppFileSystemList[pMount->volumeInfo.fileSystem]->callbacks.FindFirst(pFind, pSearchPattern, pFindData))
		{
			pModuleData->gFinds.Destroy(pFind);
			pFind = NULL;
		}
	}

	return pFind;
}
Esempio n. 14
0
void MFInputLinux_InitGamepad(int fd, LinuxGamepad *pGamepad)
{
#if !defined(__CYGWIN__)
	MFCALLSTACK;

	pGamepad->joyFD = fd;

	// get the pad details
	ioctl(fd, JSIOCGNAME(80), pGamepad->identifier);
	ioctl(fd, JSIOCGAXES, &pGamepad->numAxiis);
	ioctl(fd, JSIOCGBUTTONS, &pGamepad->numButtons);

	MFGamepadInfo *pGI = pGamepadMappingRegistry;

	// we need to find a better way to get the VID/PID from the gamepad...
	if(!MFString_CompareN(pGamepad->identifier, "HID", 3))
	{
		// the device was unnamed, but it is a HID device, so we'll try and match the VID/PID
		char *pBase = pGamepad->identifier + 3, *pEnd;

		// get the VID string
		while(*pBase && !MFIsHex(*pBase))
			++pBase;

		pEnd = pBase + 1;
		while(MFIsHex(*pEnd))
			++pEnd;

		uint32 vid = MFHexToInt(MFStrN(pBase, pEnd - pBase));

		// get the PID string
		pBase = pEnd;
		while(*pBase && !MFIsHex(*pBase))
			++pBase;

		pEnd = pBase + 1;
		while(MFIsHex(*pEnd))
			++pEnd;

		uint32 pid = MFHexToInt(MFStrN(pBase, pEnd - pBase));

		// find a matching descriptor
		for(; pGI; pGI = pGI->pNext)
		{
			if(pGI->vendorID == vid && pGI->productID == pid)
				break;
		}
	}
	else
	{
		// the device is named, so we'll compare the name against our list and hope its the same as windows..
		// since we dont have the VID/PID though, we cant verify its not a device with an aliased name.
		pGI = pGI->pNext; // skip the first one
		for(; pGI; pGI = pGI->pNext)
		{
			// since linux appends the manufacturer name, we'll just check for a match on the end of the string
			int len1 = MFString_Length(pGamepad->identifier);
			int len2 = MFString_Length(pGI->pIdentifier);
			if(!MFString_Compare(pGamepad->identifier + (len1 - len2), pGI->pIdentifier))
				break;
		}
	}

	if(!pGI)
	{
		// use default descriptor
		pGamepad->pGamepadInfo = pGamepadMappingRegistry;
		MFDebug_Warn(1, MFStr("Found an unknown gamepad '%s', using default mappings.", pGamepad->identifier));

		// offer to send email detailing controller info..
//		MessageBox(NULL, "An unknown gamepad has been detected.\r\nWe strive to support every gamepad natively, please report your gamepad to Manu at [email protected].\r\nI will contact you and request a few details about the gamepad so it can be added to the registry for the next release.", "Unknown gamepad detected...", MB_OK);
	}
	else
	{
		// use applicable descriptor
		pGamepad->pGamepadInfo = pGI;
		MFDebug_Log(2, MFStr("Found gamepad: %s '%s'.", pGI->pName, pGI->pIdentifier));
	}
/*
	// fix up the linux mapping table
	const int *pButtonMap = pGamepad->pGamepadInfo->pButtonMap;
	int numAxiis = 0;

	for(int a=0; a<60; a++)
	{
		for(int b=0; b<GamepadType_Max; ++b)
		{
			if((pButtonMap[b] & AID_Analog) && MFGETAXIS(pButtonMap[b]) == a)
			{
				pGamepad->axisMap[a] = numAxiis;
				printf("%d = %d\n", a, numAxiis);
				++numAxiis;
			}
		}
	}
*/
#endif
}
Esempio n. 15
0
void ParseASEFile(char *pFilePtr, F3DFile *_pModel)
{
	pModel = _pModel;

	char *pEnd;
	char *pToken;

	int braceCount = 0;
	bool inQuote = false;

	while(*pFilePtr != 0)
	{
		while(!(*pFilePtr == '*' && !braceCount && !inQuote) && *pFilePtr != 0)
		{
			if(*pFilePtr == '\"') inQuote = !inQuote;
			if(!inQuote)
			{
				if(*pFilePtr == '{') braceCount++;
				if(*pFilePtr == '}') braceCount--;
			}
			pFilePtr++;
		}

		pEnd = pFilePtr;

		while(!MFIsWhite(*pEnd) && *pEnd != 0) pEnd++;

		pToken = (char*)MFStrN(pFilePtr, (int)(pEnd - pFilePtr));
		pFilePtr = pEnd;

		if(!MFString_CaseCmp(pToken, "*3DSMAX_ASCIIEXPORT"))
		{
			int version = 0;

			pFilePtr = GetInt(pFilePtr, &version);

			MFDebug_Log(4, MFStr("Recognised .ASE file version: %d\n", version));
		}
		else if(!MFString_CaseCmp(pToken, "*COMMENT"))
		{
			char *pComment;

			pFilePtr = GetString(pFilePtr, &pComment);

			MFDebug_Log(4, MFStr("Comment: %s", pComment));
		}
		else if(!MFString_CaseCmp(pToken, "*SCENE"))
		{
			pFilePtr = ProcessBlock(pFilePtr, "*SCENE", ReadSceneChunk);
		}
		else if(!MFString_CaseCmp(pToken, "*MATERIAL_LIST"))
		{
			pFilePtr = ProcessBlock(pFilePtr, "*MATERIAL_LIST", ReadMaterialChunk);
		}
		else if(!MFString_CaseCmp(pToken, "*GEOMOBJECT"))
		{
			pFilePtr = ProcessBlock(pFilePtr, "*GEOMOBJECT", ReadGeomChunk);
		}
		else
		{
			MFDebug_Warn(3, MFStr("Unknown token: %s", pToken));
		}
	}
}