//Fully reads particle public static PCF ReadParticle(string filePath) { FileStream fs; try { fs = new FileStream(filePath, FileMode.Open); } catch (FileNotFoundException e) { CompilePalLogger.LogCompileError($"Could not find {filePath}\n", new Error($"Could not find {filePath}", ErrorSeverity.Error)); return(null); } PCF pcf = new PCF(); BinaryReader reader = new BinaryReader(fs); pcf.FilePath = filePath; //Get Magic String string magicString = ReadNullTerminatedString(fs, reader); //Throw away unneccesary info magicString = magicString.Replace("<!-- dmx encoding binary ", ""); magicString = magicString.Replace(" -->", ""); //Extract info from magic string string[] magicSplit = magicString.Split(' '); //Store binary and pcf versions Int32.TryParse(magicSplit[0], out pcf.BinaryVersion); Int32.TryParse(magicSplit[3], out pcf.PcfVersion); //Different versions have different stringDict sizes if (pcf.BinaryVersion != 4 && pcf.BinaryVersion != 5) { pcf.NumDictStrings = reader.ReadInt16(); //Read as short } else { pcf.NumDictStrings = reader.ReadInt32(); //Read as int } //Add strings to string dict for (int i = 0; i < pcf.NumDictStrings; i++) { pcf.StringDict.Add(ReadNullTerminatedString(fs, reader)); } //Read element dict for particle names int numElements = reader.ReadInt32(); for (int i = 0; i < numElements; i++) { int typeNameIndex = reader.ReadUInt16(); string typeName = pcf.StringDict[typeNameIndex]; string elementName = ""; if (pcf.BinaryVersion != 4 && pcf.BinaryVersion != 5) { elementName = ReadNullTerminatedString(fs, reader); //Skip data signature fs.Seek(16, SeekOrigin.Current); } else if (pcf.BinaryVersion == 4) { int elementNameIndex = reader.ReadUInt16(); elementName = pcf.StringDict[elementNameIndex]; fs.Seek(16, SeekOrigin.Current); } else if (pcf.BinaryVersion == 5) { int elementNameIndex = reader.ReadUInt16(); elementName = pcf.StringDict[elementNameIndex]; fs.Seek(20, SeekOrigin.Current); } //Get particle names if (typeName == "DmeParticleSystemDefinition") { pcf.ParticleNames.Add(elementName); } } if (pcf.BinaryVersion == 4 || pcf.BinaryVersion == 5) { //Can extract all neccesary data from string dict //Add materials and models to the master list List <string> materialNames = pcf.GetMaterialNamesV4(); if (materialNames != null && materialNames.Count != 0) { pcf.MaterialNames.AddRange(materialNames); } List <string> modelNames = pcf.GetModelNames(); if (modelNames != null && modelNames.Count != 0) { pcf.ModelNames.AddRange(modelNames); } reader.Close(); fs.Close(); return(pcf); } //Have to read element attributes to get materials for binary version under 4 //Read Element Attributes for (int a = 0; a < numElements; a++) { int numElementAttribs = reader.ReadInt32(); for (int n = 0; n < numElementAttribs; n++) { int typeID = reader.ReadUInt16(); int attributeType = reader.ReadByte(); string attributeTypeName = pcf.StringDict[typeID]; int count = (attributeType > 14) ? reader.ReadInt32() : 1; attributeType = (attributeType > 14) ? attributeType - 14 : attributeType; int[] typelength = { 0, 4, 4, 4, 1, 1, 4, 4, 4, 8, 12, 16, 12, 16, 64 }; switch (attributeType) { case 5: string material = ReadNullTerminatedString(fs, reader); if (attributeTypeName == "material") { pcf.MaterialNames.Add("materials/" + material); } break; case 6: for (int i = 0; i < count; i++) { uint len = reader.ReadUInt32(); fs.Seek(len, SeekOrigin.Current); } break; default: fs.Seek(typelength[attributeType] * count, SeekOrigin.Current); break; } } } reader.Close(); fs.Close(); return(pcf); }