Beispiel #1
0
        protected virtual bool parentEntry(Entry e)
        {
            switch (e.Name.ToLowerInvariant())
            {
            case "nickname":
                //if (e.Count != 1) throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count);
                if (e.Count != 1)
                {
                    FLLog.Warning("Ini", "Object " + e[0].ToString() + " has multiple values in nickname section");
                }
                if (Nickname != null)
                {
                    throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name);
                }
                Nickname = e[0].ToString();
                break;

            case "pos":
                if (e.Count != 3)
                {
                    throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count);
                }
                if (Pos != null)
                {
                    throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name);
                }
                Pos = new Vector3(e[0].ToSingle(), e[1].ToSingle(), e[2].ToSingle());
                break;

            case "rotate":
                if (e.Count == 1)
                {
                    if (e [0].ToSingle() == 0)
                    {
                        Rotate = Vector3.Zero;
                    }
                    else
                    {
                        FLLog.Warning("INI", "Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count);
                    }
                }
                else
                {
                    if (e.Count != 3)
                    {
                        throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count);
                    }
                    if (Rotate != null)
                    {
                        throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name);
                    }
                    Rotate = new Vector3(e [0].ToSingle(), e [1].ToSingle(), e [2].ToSingle());
                }
                break;

            default: return(false);
            }

            return(true);
        }
        public void ParseAndFill(string filename)
        {
            var sections = GetContainerInfo(this.GetType());

            foreach (var section in ParseFile(filename))
            {
                var tgt = sections.FirstOrDefault((x) => x.Name.Equals(section.Name, StringComparison.InvariantCultureIgnoreCase));
                if (tgt == null)
                {
                    FLLog.Warning("Ini", "Unknown section " + section.Name + FormatLine(section.File, section.Line));
                    continue;
                }
                var parsed = GetFromSection(section, tgt.Type);
                if (parsed != null)
                {
                    if (tgt.Add != null)
                    {
                        var list = tgt.Field.GetValue(this);
                        tgt.Add.Invoke(list, new object[] { parsed });
                    }
                    else
                    {
                        tgt.Field.SetValue(this, parsed);
                    }
                }
            }
        }
Beispiel #3
0
        public static Texture FromStream(Stream stream)
        {
            var reader = new BinaryReader(stream);

            if (reader.ReadUInt32() != DDS_MAGIC)
            {
                throw new Exception("Not a DDS file");
            }
            var header = reader.ReadStruct <DDS_HEADER>();

            if (header.ddspf.dwFourCC == (FourCC)DX10)
            {
                throw new Exception("DX10+ DDS not supported");
            }
            if (header.dwSize != HEADER_SIZE ||
                header.ddspf.dwSize != PFORMAT_SIZE)
            {
                FLLog.Warning("DDS", "Bad DDS header, loading may fail.");
            }

            if (CheckFlag(header.dwFlags, DDSD_DEPTH) || CheckFlag(header.dwCaps2, DDSCAPS2_VOLUME))
            {
                throw new Exception("3D textures not supported");
            }

            if (CheckFlag(header.dwCaps2, DDSCAPS2_CUBEMAP))
            {
                return(GetTextureCube(ref header, reader));
            }

            return(GetTexture2D(ref header, reader));
        }
Beispiel #4
0
 public Script(IntermediateNode root, ConstructCollection constructs)
 {
     Name       = root.Name;
     ObjectMaps = new List <ObjectMap>();
     JointMaps  = new List <JointMap>();
     foreach (Node node in root)
     {
         if (node.Name.Equals("root height", StringComparison.OrdinalIgnoreCase))
         {
             HasRootHeight = true;
             RootHeight    = (node as LeafNode).SingleData.Value;
         }
         else if (node.Name.StartsWith("object map", StringComparison.OrdinalIgnoreCase))
         {
             ObjectMaps.Add(new ObjectMap(node as IntermediateNode));
         }
         else if (node.Name.StartsWith("joint map", StringComparison.OrdinalIgnoreCase))
         {
             JointMaps.Add(new JointMap(node as IntermediateNode));
         }
         else
         {
             FLLog.Warning("Anm", $"{root.Name}: invalid node {node.Name}, possible broken animation?");
         }
     }
 }
        int Read(byte[] buffer, Stream stream)
        {
            int read = stream.Read(buffer, 0, POOL_BUFFER_SIZE);

            if (read == POOL_BUFFER_SIZE || read == 0 || read % 4 == 0)
            {
                return(read);
            }
            int r2 = stream.Read(buffer, read, read % 4);

            if (r2 != 0)
            {
                read += r2;
            }
            if (read % 4 != 0)
            {
                FLLog.Warning("Audio", $"Source {info} has unaligned decoding");
                int remainder = read % 4;
                for (int i = 0; i < remainder; i++)
                {
                    buffer[read++] = 0;
                }
            }
            return(read);
        }
Beispiel #6
0
        static IEnumerable <Section> Chunk(string[] delimiters, Section parent)
        {
            Section currentSection = null;

            foreach (var e in parent)
            {
                if (HasIgnoreCase(delimiters, e.Name))
                {
                    if (currentSection != null)
                    {
                        yield return(currentSection);
                    }
                    currentSection = new Section(parent.Name)
                    {
                        File = parent.File,
                        Line = parent.Line
                    };
                }
                if (currentSection != null)
                {
                    currentSection.Add(e);
                }
                else
                {
                    FLLog.Warning("Ini", $"Entry without object '{e.Name}' {FormatLine(e.File, e.Line, parent.Name)}");
                }
            }
            if (currentSection != null)
            {
                yield return(currentSection);
            }
        }
Beispiel #7
0
 public string GetString(ushort resourceId)
 {
     try {
         return(Strings[(int)resourceId]);
     } catch (Exception) {
         FLLog.Warning("Infocards", "Not Found: " + resourceId);
         return("");
     }
 }
Beispiel #8
0
        public string GetNavbarIconPath(string icon)
        {
            string ic;

            if (!NavbarIcons.TryGetValue(icon, out ic))
            {
                FLLog.Warning("Interface", $"Could not find icon {icon}");
                ic = NavbarIcons.Values.First();
            }
            return(ic);
        }
Beispiel #9
0
 public string GetXmlResource(int id)
 {
     if (infocards.ContainsKey(id))
     {
         return(infocards [id]);
     }
     else
     {
         FLLog.Warning("Infocards", "Not Found: " + id);
         return(null);
     }
 }
Beispiel #10
0
 public string GetStringResource(int id)
 {
     if (strings.ContainsKey(id))
     {
         return(strings [id]);
     }
     else
     {
         FLLog.Warning("Infocards", "Not Found: " + id);
         return("");
     }
 }
Beispiel #11
0
        public NebulaLight(Section section)
        {
            if (section == null)
            {
                throw new ArgumentNullException("section");
            }

            foreach (Entry e in section)
            {
                switch (e.Name.ToLowerInvariant())
                {
                case "ambient":
                    if (e.Count != 3)
                    {
                        throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count);
                    }
                    if (Ambient != null)
                    {
                        throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name);
                    }
                    Ambient = new Color4(e[0].ToInt32() / 255f, e[1].ToInt32() / 255f, e[2].ToInt32() / 255f, 1f);
                    break;

                case "sun_burnthrough_intensity":
                    if (e.Count != 1)
                    {
                        FLLog.Warning("Ini", "Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count);
                    }
                    if (SunBurnthroughIntensity != null)
                    {
                        throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name);
                    }
                    SunBurnthroughIntensity = e[0].ToSingle();
                    break;

                case "sun_burnthrough_scaler":
                    if (e.Count != 1)
                    {
                        FLLog.Warning("Ini", "Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count);
                    }
                    if (SunBurnthroughScaler != null)
                    {
                        throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name);
                    }
                    SunBurnthroughScaler = e[0].ToSingle();
                    break;

                default:
                    FLLog.Warning("Ini", "Invalid Entry in " + section.Name + ": " + e.Name);
                    break;
                }
            }
        }
Beispiel #12
0
        public string GetNavbarIconPath(string icon)
        {
            var    p = DataPath.Replace('\\', Path.DirectorySeparatorChar);
            string ic;

            if (!NavbarIcons.TryGetValue(icon, out ic))
            {
                FLLog.Warning("Interface", $"Could not find icon {icon}");
                ic = NavbarIcons.Values.First();
            }

            return(Path.Combine(p, ic));
        }
Beispiel #13
0
        public void AddIni(string path, FreelancerIni ini)
        {
            foreach (Section s in ParseFile(path))
            {
                var au = new AudioEntry();
                if (s.Name.ToLowerInvariant() != "sound")
                {
                    throw new Exception("Invalid section " + s.Name + " in " + path);
                }
                foreach (Entry e in s)
                {
                    switch (e.Name.ToLowerInvariant())
                    {
                    case "nickname":
                        if (au.Nickname != null)
                        {
                            FLLog.Warning("Audio", "Invalid nickname entry in " + path + " (prev " + au.Nickname + ")");
                        }
                        else
                        {
                            au.Nickname = e[0].ToString();
                        }
                        break;

                    case "file":
                        if (au.File != null)
                        {
                            FLLog.Warning("Audio", "Invalid file entry in " + path + " (nick: " + (au.Nickname ?? "null") + ")");
                        }
                        else
                        {
                            au.File = e[0].ToString();
                        }
                        break;

                    case "crv_pitch":
                        au.CrvPitch = e[0].ToInt32();
                        break;

                    case "attenuation":
                        au.Attenuation = e[0].ToInt32();
                        break;

                    case "is_2d":
                        au.Is2d = e[0].ToBoolean();
                        break;
                    }
                }
                Entries.Add(au);
            }
        }
Beispiel #14
0
 static void SetDc(ColladaMaterial material, CL.common_color_or_texture_type obj)
 {
     if (obj == null)
     {
         return;
     }
     if (obj.Item is CL.common_color_or_texture_typeColor col)
     {
         TryParseColor(col.Text, out material.Dc);
     }
     if (obj.Item is CL.common_color_or_texture_typeTexture tex)
     {
         material.Dc = Color4.White;
         FLLog.Warning("Collada", "Not Implemented: Diffuse texture import");
     }
 }
Beispiel #15
0
 static bool ComponentCheck(int c, Section s, Entry e, int min = -1)
 {
     if (min == -1)
     {
         min = c;
     }
     if (e.Count > c)
     {
         FLLog.Warning("Ini", "Too many components for " + e.Name + FormatLine(e.File, e.Line, s.Name));
     }
     if (e.Count >= min)
     {
         return(true);
     }
     FLLog.Error("Ini", "Not enough components for " + e.Name + FormatLine(e.File, e.Line, s.Name));
     return(false);
 }
Beispiel #16
0
        static bool GdiOpenFace(string face, FontStyles style, out byte[] buffer)
        {
            int  weight    = GDI.FW_REGULAR;
            uint fdwItalic = 0;

            //Map style
            if ((style & FontStyles.Bold) == FontStyles.Bold)
            {
                weight = GDI.FW_BOLD;
            }
            if ((style & FontStyles.Italic) == FontStyles.Italic)
            {
                fdwItalic = 1;
            }
            //Get font data from GDI
            buffer = null;
            unsafe
            {
                var hfont = GDI.CreateFont(0, 0, 0, 0, weight,
                                           fdwItalic, 0, 0, GDI.DEFAULT_CHARSET, GDI.OUT_OUTLINE_PRECIS,
                                           GDI.CLIP_DEFAULT_PRECIS, GDI.DEFAULT_QUALITY,
                                           GDI.DEFAULT_PITCH, face);
                //get data
                var hdc = GDI.CreateCompatibleDC(IntPtr.Zero);
                GDI.SelectObject(hdc, hfont);
                var size = GDI.GetFontData(hdc, 0, 0, IntPtr.Zero, 0);
                if (size == GDI.GDI_ERROR)
                {
                    FLLog.Warning("GDI", "GetFontData for " + face + " failed");
                    GDI.DeleteDC(hdc);
                    GDI.DeleteObject(hfont);
                    return(false);
                }
                buffer = new byte[size];
                fixed(byte *ptr = buffer)
                {
                    GDI.GetFontData(hdc, 0, 0, (IntPtr)ptr, size);
                }

                GDI.DeleteDC(hdc);
                //delete font
                GDI.DeleteObject(hfont);
                return(true);
            }
        }
Beispiel #17
0
        void ProcessSection(Section section, ContainerClass sections, string datapath = null, FileSystem vfs = null)
        {
            var tgt = sections.GetSection(section.Name);

            if (tgt == null)
            {
                FLLog.Warning("Ini", "Unknown section " + section.Name + FormatLine(section.File, section.Line));
                return;
            }
            if (tgt.Field == null)
            {
                GetFromSection(section, tgt.Type, this);
            }
            else
            {
                if (tgt.Delimiters != null)
                {
                    foreach (var ch in Chunk(tgt.Delimiters, section))
                    {
                        var childObject = GetFromSection(ch, tgt.Type, null, datapath, vfs);
                        if (childObject != null)
                        {
                            var list = tgt.Field.GetValue(this);
                            tgt.Add.Invoke(list, new object[] { childObject });
                        }
                    }
                }
                else
                {
                    var parsed = GetFromSection(section, tgt.Type, null, datapath, vfs);
                    if (parsed != null)
                    {
                        if (tgt.Add != null)
                        {
                            var list = tgt.Field.GetValue(this);
                            tgt.Add.Invoke(list, new object[] { parsed });
                        }
                        else
                        {
                            tgt.Field.SetValue(this, parsed);
                        }
                    }
                }
            }
        }
        public StararchIni(string path, FileSystem vfs)
        {
            foreach (Section s in ParseFile(path, vfs))
            {
                switch (s.Name.ToLowerInvariant())
                {
                case "texture":
                    foreach (var e in s)
                    {
                        if (e.Name.ToLowerInvariant() == "file")
                        {
                            TextureFiles.Add(e[0].ToString());
                        }
                    }
                    break;

                case "star":
                    Stars.Add(FromSection <Star>(s));
                    break;

                case "star_glow":
                    StarGlows.Add(FromSection <StarGlow>(s));
                    break;

                case "lens_flare":
                    LensFlares.Add(FromSection <LensFlare>(s));
                    break;

                case "lens_glow":
                    LensGlows.Add(FromSection <LensGlow>(s));
                    break;

                case "spines":
                    Spines.Add(FromSection <Spines>(s));
                    break;

                default:
                    FLLog.Warning("Ini", "Invalid Section in " + path + ": " + s.Name + ", " + s.Line);
                    break;
                }
            }
        }
 public string GetXmlResource(int id)
 {
     if (id == 0)
     {
         return(null);
     }
     if (infocards.ContainsKey(id))
     {
         return(infocards [id]);
     }
     else
     {
         if (!missingXml.Contains(id))
         {
             FLLog.Warning("Infocards", "Not Found: " + id);
             missingXml.Add(id);
         }
         return(null);
     }
 }
 public string GetStringResource(int id)
 {
     if (id == 0)
     {
         return("");
     }
     if (strings.ContainsKey(id))
     {
         return(strings [id]);
     }
     else
     {
         if (!missingStrings.Contains(id))
         {
             FLLog.Warning("Strings", "Not Found: " + id);
             missingStrings.Add(id);
         }
         return("");
     }
 }
Beispiel #21
0
        public StarSystem(UniverseIni universe, Section section, FreelancerData data)
            : base(data)
        {
            if (universe == null)
            {
                throw new ArgumentNullException("universe");
            }
            if (section == null)
            {
                throw new ArgumentNullException("section");
            }
            SelfFromSection(section);

            if (systemFile == null)   //TODO: MultiUniverse
            {
                FLLog.Warning("Ini", "Unimplemented: Possible MultiUniverse system " + Nickname);
                MultiUniverse = true;
                return;
            }

            ParseAndFill(data.Freelancer.DataPath + "universe\\" + systemFile, data.Freelancer.DataPath, data.VFS);
        }
Beispiel #22
0
        public Band(StarSystem parent, Section section)
        {
            if (parent == null)
            {
                throw new ArgumentNullException("parent");
            }
            if (section == null)
            {
                throw new ArgumentNullException("section");
            }

            this.parent = parent;

            foreach (Entry e in section)
            {
                switch (e.Name.ToLowerInvariant())
                {
                case "zone":
                    if (e.Count != 1)
                    {
                        throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count);
                    }
                    if (zoneName != null)
                    {
                        throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name);
                    }
                    zoneName = e[0].ToString();
                    break;

                case "render_parts":
                    if (e.Count != 1)
                    {
                        throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count);
                    }
                    if (RenderParts != null)
                    {
                        throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name);
                    }
                    RenderParts = e[0].ToInt32();
                    break;

                case "shape":
                    if (e.Count != 1)
                    {
                        throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count);
                    }
                    if (Shape != null)
                    {
                        throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name);
                    }
                    Shape = e[0].ToString();
                    break;

                case "height":
                    if (e.Count != 1)
                    {
                        throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count);
                    }
                    if (Height != null)
                    {
                        throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name);
                    }
                    Height = e[0].ToInt32();
                    break;

                case "offset_dist":
                    if (e.Count != 1)
                    {
                        throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count);
                    }
                    if (OffsetDist != null)
                    {
                        throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name);
                    }
                    OffsetDist = e[0].ToInt32();
                    break;

                case "fade":
                    //if (e.Count != 4) throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count);
                    if (Fade != null)
                    {
                        throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name);
                    }
                    Fade = new List <float>();
                    foreach (IValue i in e)
                    {
                        Fade.Add(i.ToSingle());
                    }
                    break;

                case "texture_aspect":
                    if (e.Count != 1)
                    {
                        FLLog.Warning("Ini", "Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count);
                    }
                    if (TextureAspect != null)
                    {
                        throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name);
                    }
                    TextureAspect = e[0].ToSingle();
                    break;

                case "color_shift":
                    if (e.Count != 3)
                    {
                        throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count);
                    }
                    if (ColorShift != null)
                    {
                        throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name);
                    }
                    ColorShift = new Vector3(e[0].ToSingle(), e[1].ToSingle(), e[2].ToSingle());
                    break;

                case "ambient_intensity":
                    if (e.Count != 1)
                    {
                        throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count);
                    }
                    if (AmbientIntensity != null)
                    {
                        throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name);
                    }
                    AmbientIntensity = e[0].ToSingle();
                    break;

                case "cull_mode":
                    if (e.Count != 1)
                    {
                        throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count);
                    }
                    if (CullMode != null)
                    {
                        throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name);
                    }
                    CullMode = e[0].ToInt32();
                    break;

                case "vert_increase":
                    if (e.Count != 1)
                    {
                        throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count);
                    }
                    if (VertIncrease != null)
                    {
                        throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name);
                    }
                    VertIncrease = e[0].ToInt32();
                    break;

                default:
                    throw new Exception("Invalid Entry in " + section.Name + ": " + e.Name);
                }
            }
        }
        public FxBasicAppearance(AlchemyNode ale) : base(ale)
        {
            AleParameter temp;

            if (ale.TryGetParameter("BasicApp_QuadTexture", out temp))
            {
                QuadTexture = (bool)temp.Value;
            }
            if (ale.TryGetParameter("BasicApp_TriTexture", out temp))
            {
                if ((bool)temp.Value)
                {
                    FLLog.Warning("ALE", "BasicApp_TriTexture not implemented");
                }
            }
            if (ale.TryGetParameter("BasicApp_MotionBlur", out temp))
            {
                MotionBlur = (bool)temp.Value;
            }
            if (ale.TryGetParameter("BasicApp_Color", out temp))
            {
                Color = (AlchemyColorAnimation)temp.Value;
            }
            if (ale.TryGetParameter("BasicApp_Alpha", out temp))
            {
                Alpha = (AlchemyFloatAnimation)temp.Value;
            }
            if (ale.TryGetParameter("BasicApp_HtoVAspect", out temp))
            {
                HToVAspect = (AlchemyFloatAnimation)temp.Value;
            }
            if (ale.TryGetParameter("BasicApp_Rotate", out temp))
            {
                Rotate = (AlchemyFloatAnimation)temp.Value;
            }
            if (ale.TryGetParameter("BasicApp_TexName", out temp))
            {
                Texture = (string)temp.Value;
            }
            if (ale.TryGetParameter("BasicApp_UseCommonTexFrame", out temp))
            {
                UseCommonAnimation = (bool)temp.Value;
            }
            if (ale.TryGetParameter("BasicApp_TexFrame", out temp))
            {
                Animation = (AlchemyFloatAnimation)temp.Value;
            }
            if (ale.TryGetParameter("BasicApp_CommonTexFrame", out temp))
            {
                CommonAnimation = (AlchemyCurveAnimation)temp.Value;
            }
            if (ale.TryGetParameter("BasicApp_FlipTexU", out temp))
            {
                FlipHorizontal = (bool)temp.Value;
            }
            if (ale.TryGetParameter("BasicApp_FlipTexV", out temp))
            {
                FlipVertical = (bool)temp.Value;
            }
            if (ale.TryGetParameter("BasicApp_Size", out temp))
            {
                Size = (AlchemyFloatAnimation)temp.Value;
            }
            if (ale.TryGetParameter("BasicApp_BlendInfo", out temp))
            {
                BlendInfo = BlendMap.Map((Tuple <uint, uint>)temp.Value);
            }
        }
Beispiel #24
0
        protected List <Section> ParseFile(string path, bool allowmaps = false)
        {
            if (path == null)
            {
                throw new ArgumentNullException("path");
            }

            List <Section> sections = new List <Section>();

            if (!path.ToLowerInvariant().EndsWith(".ini"))
            {
                path = path + ".ini";
            }
            using (Stream stream = VFS.Open(path))
            {
                byte[] buffer = new byte[4];
                stream.Read(buffer, 0, 4);
                string fileType = Encoding.ASCII.GetString(buffer);

                if (fileType == FileType)                 // Binary Ini
                {
                    BinaryReader reader = new BinaryReader(stream);

                    int formatVersion = reader.ReadInt32();
                    if (formatVersion != FileVersion)
                    {
                        throw new FileVersionException(path, fileType, formatVersion, FileVersion);
                    }

                    int stringBlockOffset = reader.ReadInt32();
                    if (stringBlockOffset > reader.BaseStream.Length)
                    {
                        throw new FileContentException(path, fileType, "The string block offset was out of range: " + stringBlockOffset);
                    }

                    long sectionBlockOffset = reader.BaseStream.Position;

                    reader.BaseStream.Seek(stringBlockOffset, SeekOrigin.Begin);
                    Array.Resize <byte>(ref buffer, (int)(reader.BaseStream.Length - stringBlockOffset));
                    reader.Read(buffer, 0, buffer.Length);
                    string stringBlock = Encoding.ASCII.GetString(buffer);

                    reader.BaseStream.Seek(sectionBlockOffset, SeekOrigin.Begin);
                    while (reader.BaseStream.Position < stringBlockOffset)
                    {
                        sections.Add(new Section(reader, stringBlock));
                    }
                }
                else                 // Text Ini
                {
                    stream.Seek(0, SeekOrigin.Begin);
                    StreamReader reader = new StreamReader(stream);

                    int  currentSection = -2;
                    int  currentLine    = 0;
                    bool inSection      = false;
                    while (!reader.EndOfStream)
                    {
                        string line = reader.ReadLine().Trim();

                        if (string.IsNullOrWhiteSpace(line) ||
                            line.StartsWith(";", StringComparison.OrdinalIgnoreCase) ||
                            line.StartsWith("@", StringComparison.OrdinalIgnoreCase))
                        {
                            continue;
                        }

                        if (line.StartsWith("[", StringComparison.OrdinalIgnoreCase))
                        {
                            if (line.Substring(1).Trim()[0] == ';')
                            {
                                inSection      = false;
                                currentSection = -1;
                                continue;
                            }
                            if (!line.Contains("]"))
                            {
                                throw new FileContentException(path, IniFileType, "Invalid section header: " + line);
                            }
                            string name = line.Substring(1);
                            sections.Add(new Section(name.Remove(name.IndexOf(']')).Trim()));
                            currentSection = sections.Count - 1;
                            inSection      = true;
                            continue;
                        }
                        else
                        {
                            if (!inSection)
                            {
                                continue;
                            }
                            if (line.Contains(";"))
                            {
                                line = line.Remove(line.IndexOf(";", StringComparison.OrdinalIgnoreCase)).TrimEnd();
                            }
                            if (!char.IsLetterOrDigit(line [0]) && line [0] != '_')
                            {
                                FLLog.Warning("Ini", "Invalid line in file: " + path + " at line " + currentLine + '"' + line + '"');
                            }
                            else if (line.Contains("="))
                            {
                                string[] parts = line.Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries);
                                if (parts.Length == 2)
                                {
                                    string   val = parts [1].TrimStart();
                                    string[] valParts;
                                    if (val.Contains(","))
                                    {
                                        valParts = val.Split(new char[] { ',' });
                                    }
                                    else
                                    {
                                        valParts = new string[] { val }
                                    };

                                    List <IValue> values = new List <IValue> ();
                                    foreach (string part in valParts)
                                    {
                                        string s = part.Trim();
                                        bool   tempBool;
                                        int    tempInt;
                                        float  tempFloat;

                                        if (bool.TryParse(s, out tempBool))
                                        {
                                            values.Add(new BooleanValue(tempBool));
                                        }
                                        else if (int.TryParse(s, out tempInt))
                                        {
                                            values.Add(new Int32Value(tempInt));
                                        }
                                        else if (float.TryParse(s, out tempFloat))
                                        {
                                            long templong;
                                            bool a = long.TryParse(s, out templong);
                                            values.Add(new SingleValue(tempFloat, a ? (long?)templong : null));
                                        }
                                        else
                                        {
                                            values.Add(new StringValue(s));
                                        }
                                    }

                                    sections [currentSection].Add(new Entry(parts [0].TrimEnd(), values));
                                }
                                else if (parts.Length == 3 && allowmaps)
                                {
                                    string k = parts [1].Trim();
                                    string v = parts [2].Trim();
                                    sections[currentSection].Add(new Entry(parts[0].Trim(), new IValue[] { new StringKeyValue(k, v) }));
                                }
                                else if (parts.Length == 1)
                                {
                                    sections [currentSection].Add(new Entry(parts [0].Trim(), new List <IValue> ()));
                                }
                                else
                                {
                                    FLLog.Error("INI", "Invalid entry line: " + line + " in " + path);
                                }
                            }
                            else
                            {
                                sections[currentSection].Add(new Entry(line, new List <IValue>(0)));
                            }
                        }
                        currentLine++;
                    }
                }
            }
            return(sections);
        }
Beispiel #25
0
        static ColladaGeometry GetGeometry(CL.UpAxisType up, CL.geometry geo, CL.library_materials matlib, CL.library_effects fxlib)
        {
            var conv = new ColladaGeometry()
            {
                FVF = D3DFVF.XYZ
            };

            conv.Name = string.IsNullOrEmpty(geo.name) ? geo.id : geo.name;
            var msh = geo.Item as CL.mesh;

            if (msh == null)
            {
                return(null);
            }
            List <VertexPositionNormalDiffuseTextureTwo> vertices = new List <VertexPositionNormalDiffuseTextureTwo>();
            List <int>             hashes                    = new List <int>();
            List <ushort>          indices                   = new List <ushort>();
            List <ColladaDrawcall> drawcalls                 = new List <ColladaDrawcall>();
            Dictionary <string, GeometrySource> sources      = new Dictionary <string, GeometrySource>();
            Dictionary <string, float[]>        arrays       = new Dictionary <string, float[]>();
            Dictionary <string, GeometrySource> verticesRefs = new Dictionary <string, GeometrySource>();
            int placeHolderIdx = 0;

            //Get arrays
            foreach (var acc in msh.source)
            {
                var arr = acc.Item as CL.float_array;
                arrays.Add(arr.id, FloatArray(arr.Text));
            }
            //Accessors
            foreach (var acc in msh.source)
            {
                sources.Add(acc.id, new GeometrySource(acc, arrays));
            }
            //Process geometry
            foreach (var item in msh.Items)
            {
                if (!(item is CL.triangles || item is CL.polylist || item is CL.polygons))
                {
                    FLLog.Warning("Collada", "Ignoring " + item.GetType().Name + " element.");
                }
            }
            int totalTriangles = 0;

            foreach (var item in msh.Items.Where(x => x is CL.triangles || x is CL.polylist || x is CL.polygons))
            {
                if (item is CL.triangles)
                {
                    totalTriangles += (int)((CL.triangles)item).count;
                }
                else if (item is CL.polylist plist)
                {
                    totalTriangles += (int)plist.count;
                }
                else
                {
                    totalTriangles += (int)((CL.polygons)item).count;
                }
            }
            if (totalTriangles > 21845)
            {
                throw new Exception(string.Format(
                                        "Overflow!\nCollada geometry {0} has {1} triangles\nVMeshData has limit of 21845",
                                        string.IsNullOrEmpty(geo.name) ? geo.id : geo.name,
                                        totalTriangles));
            }
            foreach (var item in msh.Items.Where(x => x is CL.triangles || x is CL.polylist || x is CL.polygons))
            {
                CL.InputLocalOffset[] inputs;
                int[]           pRefs;
                int             indexCount;
                string          materialRef;
                ColladaMaterial material;
                if (item is CL.triangles)
                {
                    var triangles = (CL.triangles)item;
                    indexCount  = (int)(triangles.count * 3);
                    pRefs       = IntArray(triangles.p);
                    inputs      = triangles.input;
                    materialRef = triangles.material;
                }
                else if (item is CL.polygons polygons)
                {
                    indexCount = (int)(polygons.count * 3);
                    int j = 0;
                    pRefs = new int[indexCount];
                    foreach (var arr in polygons.Items)
                    {
                        if (!(arr is string))
                        {
                            throw new Exception("Polygons: ph element unsupported");
                        }
                        var ints = IntArray((string)arr);
                        if (ints.Length != 3)
                        {
                            throw new Exception("Polygons: non-triangle geometry not supported");
                        }
                        pRefs[j]     = ints[0];
                        pRefs[j + 1] = ints[1];
                        pRefs[j + 2] = ints[2];
                        j           += 3;
                    }
                    inputs      = polygons.input;
                    materialRef = polygons.material;
                }
                else
                {
                    var plist = (CL.polylist)item;
                    pRefs = IntArray(plist.p);
                    foreach (var c in IntArray(plist.vcount))
                    {
                        if (c != 3)
                        {
                            throw new Exception("Polylist: non-triangle geometry");
                        }
                    }
                    materialRef = plist.material;
                    inputs      = plist.input;
                    indexCount  = (int)(plist.count * 3);
                }
                if (indexCount == 0)
                {
                    continue;                  //Skip empty
                }
                material = ParseMaterial(materialRef, matlib, fxlib);
                int pStride = 0;
                foreach (var input in inputs)
                {
                    pStride = Math.Max((int)input.offset, pStride);
                }
                pStride++;
                GeometrySource sourceXYZ = null; int offXYZ = int.MinValue;
                GeometrySource sourceNORMAL = null; int offNORMAL = int.MinValue;
                GeometrySource sourceCOLOR = null; int offCOLOR = int.MinValue;
                GeometrySource sourceUV1 = null; int offUV1 = int.MinValue;
                GeometrySource sourceUV2 = null; int offUV2 = int.MinValue;
                int            texCount = 0;
                int            startIdx = indices.Count;
                foreach (var input in inputs)
                {
                    switch (input.semantic)
                    {
                    case SEM_VERTEX:
                        if (CheckURI(input.source) != msh.vertices.id)
                        {
                            throw new Exception("VERTEX doesn't match mesh vertices");
                        }
                        foreach (var ip2 in msh.vertices.input)
                        {
                            switch (ip2.semantic)
                            {
                            case SEM_POSITION:
                                offXYZ    = (int)input.offset;
                                sourceXYZ = sources[CheckURI(ip2.source)];
                                break;

                            case SEM_NORMAL:
                                offNORMAL    = (int)input.offset;
                                sourceNORMAL = sources[CheckURI(ip2.source)];
                                conv.FVF    |= D3DFVF.NORMAL;
                                break;

                            case SEM_COLOR:
                                offCOLOR    = (int)input.offset;
                                sourceCOLOR = sources[CheckURI(ip2.source)];
                                conv.FVF   |= D3DFVF.DIFFUSE;
                                break;

                            case SEM_TEXCOORD:
                                if (texCount == 2)
                                {
                                    throw new Exception("Too many texcoords!");
                                }
                                if (texCount == 1)
                                {
                                    offUV2    = (int)input.offset;
                                    sourceUV2 = sources[CheckURI(ip2.source)];
                                    conv.FVF &= ~D3DFVF.TEX1;
                                    conv.FVF |= D3DFVF.TEX2;
                                }
                                else
                                {
                                    offUV1    = (int)input.offset;
                                    sourceUV1 = sources[CheckURI(ip2.source)];
                                    if ((conv.FVF & D3DFVF.TEX2) != D3DFVF.TEX2)
                                    {
                                        conv.FVF |= D3DFVF.TEX1;
                                    }
                                }
                                texCount++;
                                break;
                            }
                        }
                        break;

                    case SEM_POSITION:
                        offXYZ    = (int)input.offset;
                        sourceXYZ = sources[CheckURI(input.source)];
                        break;

                    case SEM_NORMAL:
                        offNORMAL    = (int)input.offset;
                        sourceNORMAL = sources[CheckURI(input.source)];
                        conv.FVF    |= D3DFVF.NORMAL;
                        break;

                    case SEM_COLOR:
                        offCOLOR    = (int)input.offset;
                        sourceCOLOR = sources[CheckURI(input.source)];
                        conv.FVF   |= D3DFVF.DIFFUSE;
                        break;

                    case SEM_TEXCOORD:
                        if (texCount == 2)
                        {
                            throw new Exception("Too many texcoords!");
                        }
                        if (texCount == 1)
                        {
                            offUV2    = (int)input.offset;
                            sourceUV2 = sources[CheckURI(input.source)];
                            conv.FVF &= ~D3DFVF.TEX1;
                            conv.FVF |= D3DFVF.TEX2;
                        }
                        else
                        {
                            offUV1    = (int)input.offset;
                            sourceUV1 = sources[CheckURI(input.source)];
                            if ((conv.FVF & D3DFVF.TEX2) != D3DFVF.TEX2)
                            {
                                conv.FVF |= D3DFVF.TEX1;
                            }
                        }
                        texCount++;
                        break;
                    }
                }
                int vertexOffset = vertices.Count;
                for (int i = 0; i < indexCount; i++)
                {
                    int idx  = i * pStride;
                    var vert = new VertexPositionNormalDiffuseTextureTwo(
                        VecAxis(up, sourceXYZ.GetXYZ(pRefs[idx + offXYZ])),
                        offNORMAL == int.MinValue ? Vector3.Zero : VecAxis(up, sourceNORMAL.GetXYZ(pRefs[idx + offNORMAL])),
                        offCOLOR == int.MinValue ? (uint)Color4.White.ToRgba() : (uint)sourceCOLOR.GetColor(pRefs[idx + offCOLOR]).ToRgba(),
                        offUV1 == int.MinValue ? Vector2.Zero : sourceUV1.GetUV(pRefs[idx + offUV1]),
                        offUV2 == int.MinValue ? Vector2.Zero : sourceUV2.GetUV(pRefs[idx + offUV2])
                        );
                    var hash    = HashVert(ref vert);
                    var vertIdx = FindDuplicate(hashes, vertices, vertexOffset, ref vert, hash);
                    if (indices.Count >= ushort.MaxValue)
                    {
                        throw new Exception("Too many indices");
                    }
                    if (vertIdx == -1)
                    {
                        if (vertices.Count + 1 >= ushort.MaxValue)
                        {
                            throw new Exception("Too many vertices");
                        }
                        indices.Add((ushort)(vertices.Count - vertexOffset));
                        vertices.Add(vert);
                        hashes.Add(hash);
                    }
                    else
                    {
                        indices.Add((ushort)(vertIdx - vertexOffset));
                    }
                }
                drawcalls.Add(new ColladaDrawcall()
                {
                    StartIndex  = startIdx,
                    StartVertex = vertexOffset,
                    EndVertex   = vertices.Count - 1,
                    TriCount    = (indices.Count - startIdx) / 3,
                    Material    = material
                });
            }
            conv.Indices   = indices.ToArray();
            conv.Vertices  = vertices.ToArray();
            conv.Drawcalls = drawcalls.ToArray();
            conv.CalculateDimensions();
            return(conv);
        }
Beispiel #26
0
        public Light(Section section, FreelancerData gdata)
        {
            foreach (Entry e in section)
            {
                switch (e.Name.ToLowerInvariant())
                {
                case "nickname":
                    Nickname = e[0].ToString();
                    break;

                case "inherit":
                    if (e.Count != 1)
                    {
                        throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count);
                    }
                    if (Inherit != null)
                    {
                        throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name);
                    }
                    Inherit = gdata.Equipment.FindEquipment(e[0].ToString()) as Light;
                    break;

                case "always_on":
                    if (e.Count != 1)
                    {
                        throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count);
                    }
                    if (alwaysOn != null)
                    {
                        throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name);
                    }
                    alwaysOn = e[0].ToBoolean();
                    break;

                case "docking_light":
                    if (e.Count != 1)
                    {
                        throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count);
                    }
                    if (dockingLight != null)
                    {
                        throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name);
                    }
                    dockingLight = e[0].ToBoolean();
                    break;

                case "bulb_size":
                    if (e.Count != 1)
                    {
                        throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count);
                    }
                    if (bulbSize != null)
                    {
                        throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name);
                    }
                    bulbSize = e[0].ToSingle();
                    break;

                case "glow_size":
                    if (e.Count != 1)
                    {
                        throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count);
                    }
                    if (glowSize != null)
                    {
                        throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name);
                    }
                    glowSize = e[0].ToSingle();
                    break;

                case "glow_color":
                    if (e.Count != 3)
                    {
                        throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count);
                    }
                    if (glowColor != null)
                    {
                        throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name);
                    }
                    glowColor = new Color3f(e[0].ToInt32() / 255f, e[1].ToInt32() / 255f, e[2].ToInt32() / 255f);
                    break;

                case "color":
                    if (e.Count != 3)
                    {
                        throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count);
                    }
                    if (color != null)
                    {
                        throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name);
                    }
                    color = new Color3f(e[0].ToInt32() / 255f, e[1].ToInt32() / 255f, e[2].ToInt32() / 255f);
                    break;

                case "flare_cone":
                    if (e.Count != 2)
                    {
                        throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count);
                    }
                    if (flareCone != null)
                    {
                        throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name);
                    }
                    flareCone = new Vector2(e[0].ToInt32(), e[1].ToInt32());
                    break;

                case "intensity":
                    if (e.Count != 1)
                    {
                        throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count);
                    }
                    if (intensity != null)
                    {
                        throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name);
                    }
                    intensity = e[0].ToInt32();
                    break;

                case "lightsource_cone":
                    if (e.Count != 1)
                    {
                        throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count);
                    }
                    if (lightsourceCone != null)
                    {
                        throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name);
                    }
                    lightsourceCone = e[0].ToInt32();
                    break;

                case "min_color":
                    if (e.Count != 3)
                    {
                        throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count);
                    }
                    if (minColor != null)
                    {
                        FLLog.Warning("Light", "Duplicate " + e.Name + " Entry in " + section.Name);
                    }
                    minColor = new Color3f(e[0].ToInt32() / 255f, e[1].ToInt32() / 255f, e[2].ToInt32() / 255f);
                    break;

                case "avg_delay":
                    if (e.Count != 1)
                    {
                        throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count);
                    }
                    if (avgDelay != null)
                    {
                        throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name);
                    }
                    avgDelay = e[0].ToSingle();
                    break;

                case "blink_duration":
                    if (e.Count != 1)
                    {
                        throw new Exception("Invalid number of values in " + section.Name + " Entry " + e.Name + ": " + e.Count);
                    }
                    if (blinkDuration != null)
                    {
                        throw new Exception("Duplicate " + e.Name + " Entry in " + section.Name);
                    }
                    blinkDuration = e[0].ToSingle();
                    break;

                case "shape":
                    FLLog.Error("Light", "custom shape not implemented");
                    break;

                default: FLLog.Error("Equipment", "Invalid Entry in " + section.Name + ": " + e.Name); break;
                }
            }
        }
Beispiel #27
0
        protected virtual bool parentNode(LeafNode n)
        {
            switch (n.Name.ToLowerInvariant())
            {
            //standard flags (Dc*)
            case "dt_flags":
                DtFlags = n.Int32ArrayData [0];
                break;

            case "dt_name":
                DtName = n.StringData;
                break;

            case "dc":
                if (n.ColorData == null)
                {
                    Dc = new Color4(n.SingleArrayData [0], n.SingleArrayData [1], n.SingleArrayData [2], 1);
                }
                else
                {
                    Dc = n.ColorData.Value;
                }
                break;

            case "ec":
                if (n.ColorData == null)
                {
                    Ec = new Color4(n.SingleArrayData [0], n.SingleArrayData [1], n.SingleArrayData [2], 1);
                }
                else
                {
                    Ec = n.ColorData.Value;
                }
                break;

            case "bt_flags":
                BtFlags = n.Int32ArrayData[0];
                break;

            case "bt_name":
                btName = n.StringData;
                break;

            case "et_flags":
                EtFlags = n.Int32ArrayData [0];
                break;

            case "et_name":
                EtName = n.StringData;
                break;

            case "oc":
                Oc = n.SingleArrayData [0];
                break;

            case "type":
                break;

            //different material types
            case "ac":
                if (n.ColorData == null)
                {
                    Ac = new Color4(n.SingleArrayData [0], n.SingleArrayData [1], n.SingleArrayData [2], 1);
                }
                else
                {
                    Ac = n.ColorData.Value;
                }
                break;

            case "flip u":
                FlipU = n.Int32Data.Value;
                break;

            case "flip v":
                FlipV = n.Int32Data.Value;
                break;

            case "alpha":
                Alpha = n.SingleData.Value;
                break;

            case "fade":
                Fade = n.SingleData.Value;
                break;

            case "scale":
                Scale = n.SingleData.Value;
                break;

            case "dm0_flags":
                Dm0Flags = n.Int32Data.Value;
                break;

            case "dm0_name":
                Dm0Name = n.StringData;
                break;

            case "dm1_flags":
                Dm1Flags = n.Int32Data.Value;
                break;

            case "dm1_name":
                Dm1Name = n.StringData;
                break;

            case "tilerate0":
                TileRate0 = n.SingleData.Value;
                break;

            case "tilerate1":
                TileRate1 = n.SingleData.Value;
                break;

            case "tilerate":
                TileRate = n.SingleData.Value;
                break;

            case "dm_flags":
                DmFlags = n.Int32Data.Value;
                break;

            case "dm_name":
                DmName = n.StringData;
                break;

            case "nt_name":
                NtName = n.StringData;
                break;

            case "nt_flags":
                NtFlags = n.Int32Data.Value;
                break;

            default:
                FLLog.Warning("Material", Name + ": Unknown property " + n.Name.ToLowerInvariant());
                break;
            }

            return(true);
        }
Beispiel #28
0
        public SphFile(IntermediateNode root, ILibFile library, string path = "/")
        {
            if (root == null)
            {
                throw new ArgumentNullException("root");
            }
            if (library == null)
            {
                throw new ArgumentNullException("materialLibrary");
            }

            materialsAccessor = new SphMaterials(this);
            ready             = false;

            this.library      = library;
            sideMaterialNames = new List <string>();

            bool sphereSet = false;

            foreach (Node node in root)
            {
                switch (node.Name.ToLowerInvariant())
                {
                case "sphere":
                    if (sphereSet)
                    {
                        throw new Exception("Multiple sphere nodes");
                    }
                    sphereSet = true;
                    var sphereNode = (IntermediateNode)node;
                    foreach (LeafNode sphereSubNode in sphereNode)
                    {
                        string name = sphereSubNode.Name.ToLowerInvariant();

                        if (name.StartsWith("m", StringComparison.OrdinalIgnoreCase))
                        {
                            sideMaterialNames.Add(sphereSubNode.StringData);
                        }
                        else if (name == "radius")
                        {
                            Radius = sphereSubNode.SingleArrayData[0];
                        }
                        else if (name == "sides")
                        {
                            int count = sphereSubNode.Int32ArrayData[0];
                            if (count != sideMaterialNames.Count)
                            {
                                throw new Exception("Invalid number of sides in " + node.Name + ": " + count);
                            }
                        }
                        else
                        {
                            throw new Exception("Invalid node in " + node.Name + ": " + sphereSubNode.Name);
                        }
                    }
                    break;

                case "vmeshlibrary":
                    IntermediateNode vMeshLibraryNode = node as IntermediateNode;
                    if (VMeshLibrary == null)
                    {
                        VMeshLibrary = new VmsFile(vMeshLibraryNode, library);
                    }
                    else
                    {
                        throw new Exception("Multiple vmeshlibrary nodes in 3db root");
                    }
                    break;

                case "material library":
                    IntermediateNode materialLibraryNode = node as IntermediateNode;
                    if (MaterialLibrary == null)
                    {
                        MaterialLibrary = new MatFile(materialLibraryNode, library);
                    }
                    else
                    {
                        throw new Exception("Multiple material library nodes in 3db root");
                    }
                    break;

                case "texture library":
                    IntermediateNode textureLibraryNode = node as IntermediateNode;
                    if (TextureLibrary == null)
                    {
                        TextureLibrary = new TxmFile(textureLibraryNode);
                    }
                    else
                    {
                        throw new Exception("Multiple texture library nodes in 3db root");
                    }
                    break;
                }
            }

            if (sideMaterialNames.Count < 6)
            {
                FLLog.Warning("Sph", $"Sph {path} does not contain all 6 sides and will not render");
            }
        }
Beispiel #29
0
        void Optimize()
        {
            needsOptimize = false;
            List <int>             meshes      = new List <int>();
            bool                   didOptimise = false;
            List <MaterialIndices> mats        = new List <MaterialIndices>();

            for (int i = StartMesh; i < endMesh; i++)
            {
                var c = counts.Where((x) => x.Material == Mesh.Meshes[i].MaterialCrc).First();
                if (c.Count == 1 || Mesh.Meshes[i].Material == null || Mesh.Meshes[i].Material.Render.IsTransparent)
                {
                    meshes.Add(i);
                }
                else
                {
                    didOptimise = true;
                    var m = mats.Where((x) => x.Crc == Mesh.Meshes[i].MaterialCrc).FirstOrDefault();
                    if (m == null)
                    {
                        m = new MaterialIndices()
                        {
                            Crc = Mesh.Meshes[i].MaterialCrc
                        };
                        mats.Add(m);
                    }
                    for (int j = Mesh.Meshes[i].TriangleStart; j < (Mesh.Meshes[i].TriangleStart + Mesh.Meshes[i].NumRefVertices); j++)
                    {
                        m.Indices.Add(Mesh.Indices[j] + StartVertex + Mesh.Meshes[i].StartVertex);
                    }
                }
            }

            if (didOptimise)
            {
                List <OptimizedDrawcall> dcs     = new List <OptimizedDrawcall>();
                List <ushort>            indices = new List <ushort>();
                foreach (var m in mats)
                {
                    var dc = new OptimizedDrawcall();
                    dc.MaterialCrc    = m.Crc;
                    dc.PrimitiveCount = m.Indices.Count / 3;
                    dc.StartIndex     = indices.Count + Mesh.IndexHandle.CountIndex;
                    var min = m.Indices.Min();
                    for (int i = 0; i < m.Indices.Count; i++)
                    {
                        indices.Add((ushort)(m.Indices[i] - min));
                    }
                    dc.VertexOffset = min + Mesh.VertexOffset;
                    dc.vMeshLibrary = vMeshLibrary;
                    dcs.Add(dc);
                }
                if (Mesh.IndexHandle.CountIndex + indices.Count >= Mesh.IndexHandle.TotalIndex)
                {
                    FLLog.Warning("Vms", "Failed to optimise: Not enough space in element buffer");
                    return;
                }
                var arr = indices.ToArray();
                mesh.IndexHandle.Elements.SetData(arr, arr.Length, Mesh.IndexHandle.CountIndex);
                mesh.IndexHandle.CountIndex += arr.Length;
                FLLog.Debug("Optimiser", "Reduced from " + MeshCount + " drawcalls to " + (meshes.Count + dcs.Count));
                optimized            = new OptimizedDraw();
                optimized.NormalDraw = meshes.ToArray();
                optimized.Optimized  = dcs.ToArray();
            }
        }
Beispiel #30
0
        static object GetFromSection(Section s, ReflectionInfo type)
        {
            var   obj          = Activator.CreateInstance(type.Type);
            ulong bitmask      = 0;
            ulong requiredBits = type.RequiredFields;

            foreach (var e in s)
            {
                //Find entry
                int idx = -1;
                for (int i = 0; i < type.Fields.Count; i++)
                {
                    if (type.Fields[i].Attr.Name.Equals(e.Name, StringComparison.InvariantCultureIgnoreCase))
                    {
                        idx = i;
                        break;
                    }
                }
                //Special Handling
                if (idx == -1)
                {
                    bool handled = false;
                    if (type.HandleEntry != null)
                    {
                        handled = (bool)type.HandleEntry.Invoke(obj, new object[] { e });
                    }
                    if (!handled)
                    {
                        FLLog.Warning("Ini", "Unknown entry " + e.Name + FormatLine(e.File, e.Line, s.Name));
                    }
                    continue;
                }

                var field = type.Fields[idx];
                //Warning for duplicates
                if (!field.Attr.Multiline)
                {
                    if ((bitmask & (1ul << idx)) != 0)
                    {
                        FLLog.Warning("Ini", "Duplicate of " + field.Attr.Name + FormatLine(e.File, e.Line, s.Name));
                    }
                    bitmask |= 1ul << idx;
                }
                requiredBits &= ~(1ul << idx);
                var  ftype = field.Field.FieldType;
                Type nType;
                if ((nType = Nullable.GetUnderlyingType(ftype)) != null)
                {
                    ftype = nType;
                }
                //Fill
                if (ftype == typeof(string))
                {
                    if (ComponentCheck(1, s, e))
                    {
                        field.Field.SetValue(obj, e[0].ToString());
                    }
                }
                else if (ftype == typeof(float))
                {
                    if (ComponentCheck(1, s, e))
                    {
                        field.Field.SetValue(obj, e[0].ToSingle());
                    }
                }
                else if (ftype == typeof(int))
                {
                    if (ComponentCheck(1, s, e))
                    {
                        field.Field.SetValue(obj, e[0].ToInt32());
                    }
                }
                else if (ftype == typeof(long))
                {
                    if (ComponentCheck(1, s, e))
                    {
                        field.Field.SetValue(obj, e[0].ToInt64());
                    }
                }
                else if (ftype == typeof(bool))
                {
                    if (field.Attr.Presence)
                    {
                        field.Field.SetValue(obj, true);
                    }
                    else if (ComponentCheck(1, s, e))
                    {
                        field.Field.SetValue(obj, e[0].ToBoolean());
                    }
                }
                else if (ftype == typeof(Vector3))
                {
                    if (ComponentCheck(3, s, e))
                    {
                        field.Field.SetValue(obj, new Vector3(e[0].ToSingle(), e[1].ToSingle(), e[2].ToSingle()));
                    }
                }
                else if (ftype == typeof(Quaternion))
                {
                    if (ComponentCheck(4, s, e))
                    {
                        field.Field.SetValue(obj, new Quaternion(e[1].ToSingle(), e[2].ToSingle(), e[3].ToSingle(), e[0].ToSingle()));
                    }
                }
                else if (ftype == typeof(Vector2))
                {
                    if (e.Count == 1 && field.Attr.MinMax)
                    {
                        field.Field.SetValue(obj, new Vector2(-1, e[0].ToSingle()));
                    }
                    else if (ComponentCheck(2, s, e))
                    {
                        field.Field.SetValue(obj, new Vector2(e[0].ToSingle(), e[1].ToSingle()));
                    }
                }
                else if (ftype == typeof(Color4))
                {
                    if (ComponentCheck(4, s, e, 3))
                    {
                        Color4 col;
                        if (e.Count == 3)
                        {
                            col = new Color4(e[0].ToInt32() / 255f, e[1].ToInt32() / 255f, e[2].ToInt32() / 255f, 1f);
                        }
                        else
                        {
                            col = new Color4(e[0].ToInt32() / 255f, e[1].ToInt32() / 255f, e[2].ToInt32() / 255f, e[3].ToInt32() / 255f);
                        }
                        field.Field.SetValue(obj, col);
                    }
                }
                else if (ftype == typeof(Color3f))
                {
                    if (ComponentCheck(3, s, e))
                    {
                        field.Field.SetValue(obj, new Color3f(e[0].ToSingle(), e[1].ToSingle(), e[2].ToSingle()));
                    }
                }
                else if (ftype == typeof(List <string>))
                {
                    if (field.Attr.Multiline)
                    {
                        bitmask &= ~(1ul << idx); //Avoid duplicate warnings
                        if (ComponentCheck(1, s, e))
                        {
                            var v = (List <string>)field.Field.GetValue(obj);
                            v.Add(e[0].ToString());
                        }
                    }
                    else if (ComponentCheck(int.MaxValue, s, e, 1))
                    {
                        field.Field.SetValue(obj, e.Select((x) => x.ToString()).ToList());
                    }
                }
                else if (ftype == typeof(float[]))
                {
                    if (ComponentCheck(int.MaxValue, s, e, 1))
                    {
                        var floats = new float[e.Count];
                        for (int i = 0; i < e.Count; i++)
                        {
                            floats[i] = e[i].ToSingle();
                        }
                        field.Field.SetValue(obj, floats);
                    }
                }
                else if (ftype == typeof(string[]))
                {
                    if (ComponentCheck(int.MaxValue, s, e, 1))
                    {
                        var strings = new string[e.Count];
                        for (int i = 0; i < e.Count; i++)
                        {
                            strings[i] = e[i].ToString();
                        }
                        field.Field.SetValue(obj, strings);
                    }
                }
                else if (ftype.IsEnum)
                {
                    if (ComponentCheck(1, s, e))
                    {
                        //TryParse requires generics, wrap in exception handler
                        try
                        {
                            field.Field.SetValue(obj, Enum.Parse(field.Field.FieldType, e[0].ToString(), true));
                        }
                        catch (Exception)
                        {
                            FLLog.Error("Ini", "Invalid value for enum " + e[0].ToString() + FormatLine(e.File, e.Line, s.Name));
                        }
                    }
                }
            }
            if (requiredBits != 0)
            {
                //These sections crash the game if they don't have required fields
                //So don't let them be added to lists
                for (int i = 0; i < 64; i++)
                {
                    if ((requiredBits & (1ul << i)) != 0)
                    {
                        FLLog.Error("Ini", string.Format("Missing required field {0}{1}", type.Fields[i].Attr.Name, FormatLine(s.File, s.Line, s.Name)));
                    }
                }
                return(null);
            }
            else
            {
                return(obj);
            }
        }