Example #1
0
        //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);
        }