Beispiel #1
0
        private static void TpkTest()
        {
            //foreach (var f in Directory.GetFiles(@"C:\Games\Steam\steamapps\common\Dirt 2\frontend\ts", "*.tpk", SearchOption.TopDirectoryOnly))
            //foreach (var f in Directory.GetFiles(@"C:\Games\Steam\steamapps\common\DiRT 3 Complete Edition\frontend\ts", "*.tpk", SearchOption.TopDirectoryOnly))
            //foreach (var f in Directory.GetFiles(@"C:\Games\Steam\steamapps\common\F1 2012\frontend\ts", "*.tpk", SearchOption.TopDirectoryOnly))
            foreach (var f in Directory.GetFiles(@"C:\Games\Steam\steamapps\common\F1 2014\frontend\ts", "*.tpk", SearchOption.TopDirectoryOnly))
            {
                var fName = Path.GetFileName(f);
                using var fsi = File.Open(f, FileMode.Open, FileAccess.Read, FileShare.Read);
                var tpk = new TpkFile();
                tpk.Read(fsi);

                if (!Enum.IsDefined(tpk.Format))
                {
                    Console.WriteLine($"{fName}\t frmt {tpk.Format}");
                }

                if (tpk.Name != Path.GetFileNameWithoutExtension(f))
                {
                    Console.WriteLine($"{fName}\t name {tpk.Name}");
                }

                if (tpk.Unk11 != 0)
                {
                    Console.WriteLine($"{fName}\t u11 {tpk.Unk11}");
                }
                if (tpk.Unk12 != 1.0)
                {
                    Console.WriteLine($"{fName}\t u12 {tpk.Unk12}");
                }
            }
        }
 public static void FromDds(this TpkFile tpk, DdsFile dds)
 {
     tpk.Format      = GetTpkImageFormat(dds);
     tpk.Width       = dds.header.width;
     tpk.Height      = dds.header.height;
     tpk.MipMapCount = dds.header.mipMapCount;
     tpk.Data        = dds.bdata;
 }
    public static DdsFile ToDds(this TpkFile tpk)
    {
        var dds = new DdsFile();

        switch (tpk.Format)
        {
        case TpkImageFormat.Bgra:     // BGRA little-endian
            dds.header.flags            |= DdsHeader.Flags.DDSD_LINEARSIZE;
            dds.header.ddspf.flags      |= DdsPixelFormat.Flags.DDPF_ALPHAPIXELS | DdsPixelFormat.Flags.DDPF_RGB;
            dds.header.ddspf.fourCC      = 0;
            dds.header.ddspf.rGBBitCount = 32;
            dds.header.ddspf.bBitMask    = 0xFF;
            dds.header.ddspf.gBitMask    = 0xFF00;
            dds.header.ddspf.rBitMask    = 0xFF0000;
            dds.header.ddspf.aBitMask    = 0xFF000000;
            dds.header.pitchOrLinearSize = tpk.Width * tpk.Height * 4;
            break;

        case TpkImageFormat.Dxt1:
            dds.header.flags            |= DdsHeader.Flags.DDSD_LINEARSIZE;
            dds.header.ddspf.flags      |= DdsPixelFormat.Flags.DDPF_FOURCC;
            dds.header.ddspf.fourCC      = BitConverter.ToUInt32(Encoding.UTF8.GetBytes("DXT1"), 0);
            dds.header.pitchOrLinearSize = Math.Max(tpk.Width * tpk.Height / 2, MinBc1LinearSize);
            break;

        case TpkImageFormat.Dxt3:
            dds.header.flags            |= DdsHeader.Flags.DDSD_LINEARSIZE;
            dds.header.ddspf.flags      |= DdsPixelFormat.Flags.DDPF_FOURCC;
            dds.header.ddspf.fourCC      = BitConverter.ToUInt32(Encoding.UTF8.GetBytes("DXT3"), 0);
            dds.header.pitchOrLinearSize = Math.Max(tpk.Width * tpk.Height, MinBc2LinearSize);
            break;

        case TpkImageFormat.Dxt5:
            dds.header.flags            |= DdsHeader.Flags.DDSD_LINEARSIZE;
            dds.header.ddspf.flags      |= DdsPixelFormat.Flags.DDPF_FOURCC;
            dds.header.ddspf.fourCC      = BitConverter.ToUInt32(Encoding.UTF8.GetBytes("DXT5"), 0);
            dds.header.pitchOrLinearSize = Math.Max(tpk.Width * tpk.Height, MinBc3LinearSize);
            break;

        default:
            throw new NotSupportedException($"Tpk format {tpk.Format} not supported.");
        }

        dds.header.width  = tpk.Width;
        dds.header.height = tpk.Height;

        if (tpk.MipMapCount > 0)
        {
            dds.header.flags      |= DdsHeader.Flags.DDSD_MIPMAPCOUNT;
            dds.header.mipMapCount = tpk.MipMapCount;
            dds.header.caps       |= DdsHeader.Caps.DDSCAPS_MIPMAP | DdsHeader.Caps.DDSCAPS_COMPLEX;
        }

        dds.bdata = tpk.Data;
        return(dds);
    }
Beispiel #4
0
        static int Main(string[] args)
        {
            PrintBanner();

            if (args.Length < 1)
            {
                PrintUsage();
                return(1);
            }

            string     configFile = args[0];
            ConfigFile config     = new ConfigFile();

            config.LoadFile(configFile, new string[] { "texture" });

            FileInfo fileInfo = new FileInfo(configFile);

            Directory.SetCurrentDirectory(fileInfo.DirectoryName);

            string xName = config.GetValue("tpk", "xname");

            ArrayList textures     = new ArrayList();
            int       textureCount = config.GetCount("texture");
            uint      memoryOffset = 0;

            for (int i = 0; i < textureCount; i++)
            {
                DDS    dds     = new DDS();
                string ddsfile = config.GetValue("texture", i, "file");
                dds.Open(ddsfile);

                if ((dds.FormatFlags & DDS.DDSFormatFlags.DXT) == 0 ||
                    !(dds.FormatFourCC == DDS.DDSFormatFourCC.DXT1 ||
                      dds.FormatFourCC == DDS.DDSFormatFourCC.DXT3))
                {
                    throw new Exception("Currently only DXT1 and DXT3 textures are supported.");
                }

                bool hasAlpha = false;
                if (dds.FormatFourCC == DDS.DDSFormatFourCC.DXT3)
                {
                    hasAlpha = true;
                }

                TpkTextureInfo texInfo = new TpkTextureInfo();
                if (xName == null)
                {
                    texInfo.TextureName = config.GetValue("texture", i, "name");
                }
                else
                {
                    texInfo.TextureName = xName + "_" + config.GetValue("texture", i, "name");
                }
                texInfo.Hash = Hash(texInfo.TextureName);

                string usage = config.GetValue("texture", i, "usage");
                if (usage != null)
                {
                    usage = usage.ToLower();
                }
                if (usage == "type1")
                {
                    texInfo.Usage = 0x1B81E7B0;
                }
                else if (usage == "type2")
                {
                    texInfo.Usage = 0x1DA6C8A6;
                }
                else
                {
                    texInfo.Usage = 0x1A93CF;
                }

                bool flagA = config.GetValue("texture", i, "flaga") == "1";

                texInfo.MemoryOffset        = memoryOffset;
                texInfo.TextureLength       = (uint)dds.Pitch;
                texInfo.MemoryPaletteOffset = texInfo.MemoryOffset + texInfo.TextureLength;
                texInfo.PaletteLength       = 0;
                texInfo.PitchOrLinearSize   = dds.Pitch;
                texInfo.Width  = (ushort)dds.Width;
                texInfo.Height = (ushort)dds.Height;
                texInfo.D1     = 0x220000;
                texInfo.D1    += ((int)Math.Log((double)texInfo.Height, 2)) << 8;
                texInfo.D1    += ((int)Math.Log((double)texInfo.Width, 2));
                texInfo.D2     = 0x10000;
                texInfo.D3     = hasAlpha ? 0x500 : 0x0;
                texInfo.D4     = hasAlpha ? (0x10201 - (flagA ? 0x1 : 0x0)) :
                                 (0x1000000 + (flagA ? 0x2000000 : 0x0));
                texInfo.D5        = 0x100;
                texInfo.D6        = 0x0;
                texInfo.D7        = 0x1000000;
                texInfo.D8        = 0x100;
                texInfo.Alpha     = hasAlpha ? 0x1 : 0x0;
                texInfo.D9        = 5;
                texInfo.D10       = 6;
                texInfo.D3DFormat = (int)dds.FormatFourCC;

                MemoryStream msTex = new MemoryStream(dds.Pitch + 0x9c + 0x10);
                BinaryWriter bwTex = new BinaryWriter(msTex);
                bwTex.Write((int)0x57574152);
                bwTex.Write((int)0x1001);
                bwTex.Write((int)(dds.Pitch + 0x9c));
                bwTex.Write((int)(dds.Pitch + 0x9c + 0x10));
                bwTex.Write(dds.Texture[0]);
                texInfo.Write(bwTex);
                byte[] texData = msTex.GetBuffer();
                msTex.Close();

                TextureInfo textureInfo = new TextureInfo();
                textureInfo.Hash             = texInfo.Hash;
                textureInfo.Length           = (uint)texData.Length - 0x10;
                textureInfo.LengthCompressed = (uint)texData.Length;
                textureInfo.Data             = texData;
                textures.Add(textureInfo);

                memoryOffset += texInfo.TextureLength + texInfo.PaletteLength;
            }
            textures.Sort();

            int initialLen      = 0xDC + textures.Count * (0x8 + 0x18);
            int paddingToData   = 0x80 - ((initialLen + 8) % 0x80);
            int textureOffsBase = initialLen + 8 + paddingToData + 0x100;

            uint offs = (uint)textureOffsBase;

            foreach (TextureInfo ti in textures)
            {
                ti.Offset = offs;
                offs     += ti.LengthCompressed;
                if ((offs % 0x40) != 0)
                {
                    offs += 0x40 - (offs % 0x40);
                }
            }
            uint maxOffs = offs;

            TpkFile tpk = new TpkFile();

            tpk.AddBlock(new TpkNull(0x30));

            TpkBaseBlock head = new TpkBaseBlock(TpkChunk.TpkHead);

            TpkHeadFileInfo fi = new TpkHeadFileInfo();

            fi.GlobalPath = config.GetValue("tpk", "pipelinepath");
            if (fi.GlobalPath == null)
            {
                fi.GlobalPath = "";
            }
            fi.FileHash    = Hash(fi.GlobalPath);
            fi.TextureName = config.GetValue("tpk", "identifier");
            if (fi.TextureName == null)
            {
                fi.TextureName = "";
            }
            fi.Version = 5;
            head.AddBlock(fi);

            TpkHeadHash hashes = new TpkHeadHash();

            hashes.Count = textures.Count;
            for (int i = 0; i < textures.Count; i++)
            {
                hashes[i] = (textures[i] as TextureInfo).Hash;
            }
            head.AddBlock(hashes);

            TpkHeadDataOffset tpkdo = new TpkHeadDataOffset();

            for (int i = 0; i < textures.Count; i++)
            {
                TextureInfo ti = textures[i] as TextureInfo;
                TpkHeadDataOffset.DataOffsetStruct dos = new TpkHeadDataOffset.DataOffsetStruct();
                dos.Flags      = 0x100;
                dos.Hash       = ti.Hash;
                dos.Length     = ti.LengthCompressed;
                dos.RealLength = ti.Length;
                dos.Offset     = ti.Offset;
                tpkdo[ti.Hash] = dos;
            }
            head.AddBlock(tpkdo);

            tpk.AddBlock(head);

            tpk.AddBlock(new TpkNull(paddingToData));

            TpkBaseBlock data = new TpkBaseBlock(TpkChunk.TpkData);

            TpkDataHeadLink headlink = new TpkDataHeadLink();

            headlink.Unknown1 = 1;
            headlink.FileHash = fi.FileHash;
            data.AddBlock(headlink);

            data.AddBlock(new TpkNull(0x50));

            TpkDataRaw   raw  = new TpkDataRaw();
            MemoryStream ms   = new MemoryStream((int)maxOffs - textureOffsBase + 0x78);
            BinaryWriter msbw = new BinaryWriter(ms);

            for (int i = 0; i < textures.Count; i++)
            {
                TextureInfo ti = textures[i] as TextureInfo;
                msbw.Seek((int)ti.Offset - textureOffsBase + 0x78, SeekOrigin.Begin);
                msbw.Write(ti.Data);
            }

            /*
             * if (((ms.Position + 8) % 0x40) != 0)
             * {
             *      msbw.Seek((int)ms.Position + 0x40 - (((int)ms.Position + 8) % 0x40), SeekOrigin.Begin);
             *      msbw.Seek(-4, SeekOrigin.Current);
             *      msbw.Write((int)0xAAAAAA);
             * }
             */
            raw.SetDataRaw(ms.GetBuffer());
            ms.Close();
            data.AddBlock(raw);

            tpk.AddBlock(data);

            string save = config.GetValue("tpk", "output");

            if (save == null)
            {
                save = "TEXTURES.BIN";
            }
            tpk.Save(save);

            return(0);
        }
Beispiel #5
0
        private static void Convert(string f)
        {
            var    fileName = Path.GetFileName(f);
            var    ext      = Path.GetExtension(f);
            string magic;
            string xmlMagic;

            using (var fs = File.Open(f, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                PkgBinaryReader reader = new PkgBinaryReader(fs);
                magic = reader.ReadString(4);

                // Skip first byte since BXMLBig starts with \0 causing empty string
                reader.Seek(1, SeekOrigin.Begin);
                xmlMagic = reader.ReadString(3);
            }

            if (xmlMagic == "\"Rr" || xmlMagic == "BXM")
            {
                using var fsi = File.Open(f, FileMode.Open, FileAccess.Read, FileShare.Read);
                XmlFile file = new XmlFile(fsi);
                using var fso = File.Open(f + ".xml", FileMode.Create, FileAccess.Write, FileShare.Read);
                file.Write(fso, XMLType.Text);
                Console.WriteLine("Success! XML converted.");
            }
            else if (magic == "LNGT")
            {
                using var fsi = File.Open(f, FileMode.Open, FileAccess.Read, FileShare.Read);
                LngFile file = new LngFile(fsi);
                using var fso = File.Open(f + ".xml", FileMode.Create, FileAccess.Write, FileShare.Read);
                file.WriteXml(fso);
                Console.WriteLine("Success! Lng converted.");
            }
            else if (magic == "!pkg")
            {
                using var fsi = File.Open(f, FileMode.Open, FileAccess.Read, FileShare.Read);
                PkgFile file = PkgFile.ReadPkg(fsi);
                using var fso = File.Open(f + ".json", FileMode.Create, FileAccess.Write, FileShare.Read);
                file.WriteJson(fso);
                Console.WriteLine("Success! Pkg converted.");
            }
            else if (ext == ".tpk")
            {
                using var fsi = File.Open(f, FileMode.Open, FileAccess.Read, FileShare.Read);
                var tpk = new TpkFile();
                tpk.Read(fsi);
                Console.WriteLine($"Tpk name '{tpk.Name}', image format '{tpk.Format}'.");
                var dds = tpk.ToDds();
                using var fso = File.Open(f + ".dds", FileMode.Create, FileAccess.Write, FileShare.Read);
                dds.Write(fso, -1);
                Console.WriteLine("Success! Tpk converted.");
            }
            else if (fileName.EndsWith(".tpk.dds"))
            {
                using var fsi = File.Open(f, FileMode.Open, FileAccess.Read, FileShare.Read);
                var dds = new DdsFile(fsi);
                var tpk = new TpkFile()
                {
                    Name = fileName.Remove(fileName.IndexOf('.'))
                };
                tpk.FromDds(dds);
                using var fso = File.Open(f + ".tpk", FileMode.Create, FileAccess.Write, FileShare.Read);
                tpk.Write(fso);
                Console.WriteLine("Success! DDS converted.");
            }
            else
            {
                bool          isJSON = false;
                JsonException jsonEx = null;
                try
                {
                    using var fsi = File.Open(f, FileMode.Open, FileAccess.Read, FileShare.Read);
                    PkgFile pkgFile = PkgFile.ReadJson(fsi);
                    using var fso = File.Open(f + ".pkg", FileMode.Create, FileAccess.Write, FileShare.Read);
                    pkgFile.WritePkg(fso);
                    Console.WriteLine("Success! JSON converted.");
                    isJSON = true;
                }
                catch (JsonException e)
                {
                    jsonEx = e;
                }

                if (!isJSON)
                {
                    XmlDocument xmlDoc = new XmlDocument();
                    try
                    {
                        xmlDoc.Load(f);
                    }
                    catch (XmlException e)
                    {
                        throw new AggregateException("Could not determine the file type! Showing json, and xml errors: ", jsonEx, e);
                    }

                    if (xmlDoc.DocumentElement.Name == "language")
                    {
                        using var fsi = File.Open(f, FileMode.Open, FileAccess.Read, FileShare.Read);
                        DataSet dataSet = new DataSet("language");
                        dataSet.ReadXml(fsi, XmlReadMode.ReadSchema);
                        LngFile file = new LngFile(dataSet);
                        using var fso = File.Open(f + ".lng", FileMode.Create, FileAccess.Write, FileShare.Read);
                        file.Write(fso);
                        Console.WriteLine("Success! XML converted.");
                    }
                    else
                    {
                        using var fsi = File.Open(f, FileMode.Open, FileAccess.Read, FileShare.Read);
                        XmlFile file = new XmlFile(fsi);
                        using var fso = File.Open(f + ".xml", FileMode.Create, FileAccess.Write, FileShare.Read);
                        file.Write(fso);
                        Console.WriteLine("Success! XML converted.");
                    }
                }
            }
        }