Exemplo n.º 1
0
            public static TextureMapEntry ReadTextureMapEntry(MemoryStream texMap, MEGame game, List <string> packageNames)
            {
                TextureMapEntry tme = new TextureMapEntry();

                tme.Name        = texMap.ReadStringASCII(texMap.ReadByte());
                tme.CRC         = texMap.ReadUInt32();
                tme.Width       = texMap.ReadInt16();
                tme.Height      = texMap.ReadInt16();
                tme.PixelFormat = (PixelFormat)texMap.ReadByte();
                tme.Flags       = texMap.ReadByte();
                int countPackages = texMap.ReadInt16();

                for (int k = 0; k < countPackages; k++)
                {
                    TextureMapPackageEntry matched = new TextureMapPackageEntry();
                    matched.UIndex = texMap.ReadInt32();
                    if (game == ME3ExplorerCore.Packages.MEGame.ME1)
                    {
                        var isSlaveTexture = texMap.ReadInt16();
                        if (isSlaveTexture != -1)
                        {
                            matched.IsSlave           = true; //This file has external mips that point to a master package file
                            matched.MasterPackageName = texMap.ReadStringASCIINull();
                        }
                        matched.TextureOffset = texMap.ReadUInt32();
                    }
                    matched.NumEmptyMips = texMap.ReadByte();
                    matched.NumMips      = texMap.ReadByte();
                    //matched.IsMovieTexture = (texture.flags == TextureProperty::TextureTypes::Movie);
                    var packageIndex = texMap.ReadInt16();
                    matched.RelativePackagePath = packageNames[packageIndex].Replace("\\", "/"); // Not sure what pkgs is
                    matched.PackageName         = Path.GetFileName(matched.RelativePackagePath);
                    tme.ContainingPackages.Add(matched);
                }

                return(tme);
            }
Exemplo n.º 2
0
        void ReadMaterial()
        {
            if (clyt.Materials.Count > 0)
            {
                throw new FormatException("Expecting just one mat1 section");
            }

            long baseOffset   = reader.Stream.Position - 8;
            int  numMaterials = reader.ReadInt32();

            while (numMaterials > 0)
            {
                // Read from table and jump to material
                long offset = baseOffset + reader.ReadUInt32();
                reader.Stream.PushToPosition(offset);

                var material = new Material();
                material.Name = reader.ReadString(0x14).Replace("\0", string.Empty);

                for (int i = 0; i < material.TevConstantColors.Length; i++)
                {
                    // TODO: Convert to RGBA
                    material.TevConstantColors[i] = reader.ReadUInt32();
                }

                uint flags           = reader.ReadUInt32();
                uint numTexMap       = flags & 0x3;
                uint numTexMatrix    = (flags >> 2) & 0x3;
                uint numTexCoordGen  = (flags >> 4) & 0x3;
                uint numTevStage     = (flags >> 6) & 0x7;
                bool hasAlphaCompare = ((flags >> 9) & 0x01) == 1;
                bool hasBlendMode    = ((flags >> 10) & 0x01) == 1;
                material.UseTextureOnly = ((flags >> 11) & 0x01) == 1;
                bool separateBlendMode  = ((flags >> 12) & 0x01) == 1;
                bool hasIndirectParam   = ((flags >> 13) & 0x01) == 1;
                uint numProjTexGenParam = (flags >> 14) & 0x03;
                bool hasFontShadowParam = ((flags >> 16) & 0x01) == 1;

                for (int i = 0; i < numTexMap; i++)
                {
                    var entry = new TextureMapEntry();
                    entry.Index = reader.ReadUInt16();

                    byte flag1 = reader.ReadByte();
                    byte flag2 = reader.ReadByte();
                    entry.WrapS     = (WrapMode)(flag1 & 0x3);
                    entry.WrapT     = (WrapMode)(flag2 & 0x3);
                    entry.MinFilter = (TextureFilter)((flag1 >> 2) & 0x3);
                    entry.MagFilter = (TextureFilter)((flag2 >> 2) & 0x3);

                    material.TexMapEntries.Add(entry);
                }

                for (int i = 0; i < numTexMatrix; i++)
                {
                    var entry = new TextureMatrixEntry();
                    entry.Translation = new Vector2(reader.ReadSingle(), reader.ReadSingle());
                    entry.Rotation    = reader.ReadSingle();
                    entry.Scale       = new Vector2(reader.ReadSingle(), reader.ReadSingle());

                    material.TexMatrixEntries.Add(entry);
                }

                for (int i = 0; i < numTexCoordGen; i++)
                {
                    material.TextureCoordGen.Add(reader.ReadSingle());
                }

                for (int i = 0; i < numTevStage; i++)
                {
                    var stage = new TevStage();
                    stage.Param1 = reader.ReadUInt32();
                    stage.Param2 = reader.ReadUInt32();
                    stage.Param3 = reader.ReadUInt32();
                    material.TevStages.Add(stage);
                }

                if (hasAlphaCompare)
                {
                    material.AlphaCompare = new AlphaCompare {
                        Function  = reader.ReadUInt32(),
                        Reference = reader.ReadSingle(),
                    };
                }

                if (hasBlendMode)
                {
                    material.ColorBlendMode = new BlendMode {
                        BlendOperator     = reader.ReadByte(),
                        SourceFactor      = reader.ReadByte(),
                        DestinationFactor = reader.ReadByte(),
                        LogicOperator     = reader.ReadByte(),
                    };
                }

                if (separateBlendMode)
                {
                    material.AlphaBlendMode = new BlendMode {
                        BlendOperator     = reader.ReadByte(),
                        SourceFactor      = reader.ReadByte(),
                        DestinationFactor = reader.ReadByte(),
                        LogicOperator     = reader.ReadByte(),
                    };
                }

                if (hasIndirectParam || numProjTexGenParam > 0 || hasFontShadowParam)
                {
                    Console.WriteLine($"WARN: Material ({material.Name}) with unknown sections.");
                }

                clyt.Materials.Add(material);
                reader.Stream.PopPosition();
                numMaterials--;
            }
        }
Exemplo n.º 3
0
        public static Dictionary <uint, TextureMapEntry> LoadTextureMap(MEGame game)
        {
            // Read the vanilla file name table
            List <string> packageNames = null;
            {
                using var stream = File.OpenRead(Path.Combine(App.ExecFolder, @"TextureMap", $@"vanilla{game}.bin"));
                if (stream.ReadStringASCII(4) != @"MD5T")
                {
                    throw new Exception(@"Header of MD5 table doesn't match expected value!");
                }

                //Decompress
                var decompressedSize = stream.ReadInt32();
                //var compressedSize = stream.Length - stream.Position;

                var compressedBuffer   = stream.ReadToBuffer(stream.Length - stream.Position);
                var decompressedBuffer = LZMA.Decompress(compressedBuffer, (uint)decompressedSize);
                if (decompressedBuffer.Length != decompressedSize)
                {
                    throw new Exception(@"Vanilla database failed to decompress");
                }

                //Read
                MemoryStream table      = new MemoryStream(decompressedBuffer);
                int          numEntries = table.ReadInt32();
                packageNames = new List <string>(numEntries);
                //Package names
                for (int i = 0; i < numEntries; i++)
                {
                    //Read entry
                    packageNames.Add(table.ReadStringASCIINull().Replace('/', '\\').TrimStart('\\'));
                }
            }


            var tmf = Path.Combine(App.ExecFolder, @"TextureMap", $@"vanilla{game}Map.bin");

            using var fs = File.OpenRead(tmf);

            // read the precomputed vanilla texture map.
            // this map will help identify vanilla textures

            var magic = fs.ReadInt32();

            if (magic != 0x504D5443)
            {
                throw new Exception(@"Invalid precomputed texture map! Wrong magic");
            }
            var decompSize = fs.ReadUInt32();

            byte[] compresssed = fs.ReadToBuffer(fs.ReadInt32());

            var texMap = new MemoryStream(LZMA.Decompress(compresssed, decompSize));

            texMap.Seek(8, SeekOrigin.Begin); // skip magic, ???

            var textureCount = texMap.ReadInt32();
            Dictionary <uint, TextureMapEntry> map = new Dictionary <uint, TextureMapEntry>(textureCount);

            for (int i = 0; i < textureCount; i++)
            {
                var entry = TextureMapEntry.ReadTextureMapEntry(texMap, game, packageNames);
                map[entry.CRC] = entry;
            }

            return(map);
        }
Exemplo n.º 4
0
        void ReadMaterial()
        {
            if (clyt.Materials.Count > 0)
            {
                throw new FormatException("Expecting just one mat1 section");
            }

            long baseOffset   = reader.Stream.Position - 8;
            int  numMaterials = reader.ReadInt32();

            while (numMaterials > 0)
            {
                // Read from table and jump to material
                long offset = baseOffset + reader.ReadUInt32();
                reader.Stream.PushToPosition(offset);

                var material = new Material();
                material.Name = reader.ReadString(0x14).Replace("\0", string.Empty);

                for (int i = 0; i < material.TevConstantColors.Length; i++)
                {
                    // TODO: Convert to RGBA
                    material.TevConstantColors[i] = reader.ReadUInt32();
                }

                uint flags           = reader.ReadUInt32();
                uint numTexMap       = flags & 0x3;
                uint numTexMatrix    = (flags >> 2) & 0x3;
                uint numTexCoordGen  = (flags >> 4) & 0x3;
                uint numTevStage     = (flags >> 6) & 0x7;
                uint hasAlphaCompare = (flags >> 9) & 0x01;
                uint hasBlendMode    = (flags >> 10) & 0x01;
                material.UseTextureOnly = ((flags >> 11) & 0x01) == 1;
                uint separateBlendMode  = (flags >> 12) & 0x01;
                uint hasIndirectParam   = (flags >> 13) & 0x01;
                uint numProjTexGenParam = (flags >> 14) & 0x03;
                uint hasFontShadowParam = (flags >> 16) & 0x01;

                uint texMapOffset       = 0x34;
                uint texMatrixOffset    = texMapOffset + (numTexMap * 4);
                uint texCoordGenOffset  = texMatrixOffset + (numTexMatrix * 0x14);
                uint tevStageOffset     = texCoordGenOffset + (numTexCoordGen * 4);
                uint alphaCompareOffset = tevStageOffset + (numTevStage * 0xC);
                uint blendModeOffset    = alphaCompareOffset + 0x8;

                reader.Stream.Seek(offset + texMapOffset);
                for (int i = 0; i < numTexMap; i++)
                {
                    var entry = new TextureMapEntry();
                    entry.Index = reader.ReadUInt16();

                    byte flag1 = reader.ReadByte();
                    byte flag2 = reader.ReadByte();
                    entry.WrapS     = (WrapMode)(flag1 & 0x3);
                    entry.WrapT     = (WrapMode)(flag2 & 0x3);
                    entry.MinFilter = (TextureFilter)((flag1 >> 2) & 0x3);
                    entry.MagFilter = (TextureFilter)((flag2 >> 2) & 0x3);

                    material.TexMapEntries.Add(entry);
                }

                reader.Stream.Seek(offset + texMatrixOffset);
                for (int i = 0; i < numTexMatrix; i++)
                {
                    var entry = new TextureMatrixEntry();
                    entry.Translation = new Vector2(reader.ReadSingle(), reader.ReadSingle());
                    entry.Rotation    = reader.ReadSingle();
                    entry.Scale       = new Vector2(reader.ReadSingle(), reader.ReadSingle());

                    material.TexMatrixEntries.Add(entry);
                }

                reader.Stream.Seek(offset + texCoordGenOffset);
                for (int i = 0; i < numTexCoordGen; i++)
                {
                    material.TextureCoordGen.Add(reader.ReadSingle());
                }

                // TODO: Find a bclyt with the rest of sections

                clyt.Materials.Add(material);
                reader.Stream.PopPosition();
                numMaterials--;
            }
        }