示例#1
0
        static void CreateTexbinFile(string pathname, bool generateRectSection = true, bool compressedData = true)
        {
            var filelist        = Directory.GetFiles(pathname).Where(x => !x.ToLower().EndsWith(".xml")).ToArray();
            var filelist_unique = filelist.Select(Path.GetFileNameWithoutExtension).Distinct().Where(x => !x.ToLower().EndsWith(".xml")).ToList();

            filelist_unique = filelist_unique.Select(x => x.ToUpper()).ToList();

            if (filelist_unique.Count != filelist.Length)
            {
                Console.WriteLine("Folder has more files than expected. Are there multiple files with the same name (not including extension)?");
                Environment.Exit(1);
            }

            var formatMetadata = new FormatMetadata();

            if (File.Exists(Path.Combine(pathname, "_metadata-format.xml")))
            {
                formatMetadata = DeserializeFormatMetadata(Path.Combine(pathname, "_metadata-format.xml"));
            }
            else
            {
                foreach (var filename in filelist_unique)
                {
                    var data = new FormatInfo
                    {
                        Filename   = filename,
                        FormatType = 0,
                    };
                    formatMetadata.FormatInfo.Add(data);
                }
            }

            var nameSection = CreateNameSection(filelist_unique);

            var dataSection     = new List <byte>();
            var fileinfoSection = new List <byte>();
            var imageRectInfo   = new Dictionary <string, Tuple <ushort, ushort> >();

            for (int i = 0; i < filelist_unique.Count; i++)
            {
                var data = File.ReadAllBytes(filelist[i]);

                Console.WriteLine("Adding {0}...", filelist[i]);

                if (!data.Take(4).SequenceEqual(new byte[] { 0x54, 0x58, 0x44, 0x54 }) &&
                    !data.Take(4).SequenceEqual(new byte[] { 0x54, 0x44, 0x58, 0x54 }))
                {
                    data = gitadora_textool.Program.CreateImageCore(data, true);
                }

                var formatTypeList = formatMetadata.FormatInfo.Where(x =>
                                                                     String.CompareOrdinal(Path.GetFileNameWithoutExtension(filelist_unique[i]),
                                                                                           x.Filename) == 0).ToList();

                data[0x2c] = formatTypeList.Count > 0 ? formatTypeList[0].FormatType : data[0x2c];

                fileinfoSection.AddRange(BitConverter.GetBytes(0));
                fileinfoSection.AddRange(BitConverter.GetBytes(data.Length + 0x08));
                fileinfoSection.AddRange(BitConverter.GetBytes(0x40 + nameSection.Count + (filelist_unique.Count * 0x0c) + dataSection.Count));

                if (compressedData)
                {
                    dataSection.AddRange(Compress(data));
                }
                else
                {
                    dataSection.AddRange(BitConverter.GetBytes(data.Length).Reverse());
                    dataSection.AddRange(BitConverter.GetBytes(0));
                    dataSection.AddRange(data);
                }

                imageRectInfo[filelist_unique[i]] = new Tuple <ushort, ushort>((ushort)((data[0x11] << 8) | data[0x10]), (ushort)((data[0x13] << 8) | data[0x12]));
            }

            if ((dataSection.Count % 4) != 0)
            {
                var padding = 4 - (dataSection.Count % 4);
                while (padding > 0)
                {
                    dataSection.Add(0);
                    padding--;
                }
            }

            var rectSection = new List <byte>();

            if (generateRectSection)
            {
                var rectInfo = new TexInfo();

                if (File.Exists(Path.Combine(pathname, "_metadata.xml")))
                {
                    rectInfo = Deserialize(Path.Combine(pathname, "_metadata.xml"));
                }
                else
                {
                    foreach (var filename in filelist_unique)
                    {
                        var data = new RectInfo
                        {
                            ExternalFilename = filename,
                            Filename         = filename,
                            X = 0,
                            Y = 0,
                            W = imageRectInfo[filename].Item1,
                            H = imageRectInfo[filename].Item2
                        };
                        rectInfo.RectInfo.Add(data);
                    }
                }

                var rectNameFilelist = rectInfo.RectInfo.Select(x => x.Filename)
                                       .Select(Path.GetFileNameWithoutExtension).Distinct()
                                       .Where(x => !x.ToLower().EndsWith(".xml")).ToList();

                var rectinfoSection = new List <byte>();
                var rectNameSection = CreateNameSection(rectNameFilelist);
                foreach (var data in rectInfo.RectInfo)
                {
                    rectinfoSection.AddRange(BitConverter.GetBytes(filelist_unique.IndexOf(Path.GetFileNameWithoutExtension(data.ExternalFilename))));
                    rectinfoSection.AddRange(BitConverter.GetBytes(data.X));
                    rectinfoSection.AddRange(BitConverter.GetBytes(data.W));
                    rectinfoSection.AddRange(BitConverter.GetBytes(data.Y));
                    rectinfoSection.AddRange(BitConverter.GetBytes(data.H));
                }

                rectSection.AddRange(
                    new byte[] { 0x54, 0x43, 0x45, 0x52, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00 });
                rectSection.AddRange(BitConverter.GetBytes(0x1c + rectNameSection.Count + rectinfoSection.Count));
                rectSection.AddRange(BitConverter.GetBytes(rectNameFilelist.Count));
                rectSection.AddRange(BitConverter.GetBytes(0x1c));
                rectSection.AddRange(BitConverter.GetBytes(0x1c + rectNameSection.Count));
                rectSection.AddRange(rectNameSection);
                rectSection.AddRange(rectinfoSection);
            }

            var outputData = new List <byte>();

            outputData.AddRange(new byte[] { 0x50, 0x58, 0x45, 0x54, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00 });
            outputData.AddRange(BitConverter.GetBytes(0x40 + nameSection.Count + fileinfoSection.Count + dataSection.Count + rectSection.Count)); // Archive size
            outputData.AddRange(BitConverter.GetBytes(1));
            outputData.AddRange(BitConverter.GetBytes(filelist_unique.Count));
            outputData.AddRange(BitConverter.GetBytes(0));
            outputData.AddRange(BitConverter.GetBytes(0x40 + nameSection.Count + fileinfoSection.Count));
            outputData.AddRange(BitConverter.GetBytes(rectSection.Count > 0 ? 0x40 + nameSection.Count + fileinfoSection.Count + dataSection.Count : 0));
            outputData.AddRange(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 });
            outputData.AddRange(BitConverter.GetBytes(0x40)); // PMAN section offset
            outputData.AddRange(BitConverter.GetBytes(0));
            outputData.AddRange(BitConverter.GetBytes(0x40 + nameSection.Count));
            outputData.AddRange(nameSection);
            outputData.AddRange(fileinfoSection);
            outputData.AddRange(dataSection);
            outputData.AddRange(rectSection);

            var basePath = Path.GetFileName(pathname);

            if (String.IsNullOrWhiteSpace(basePath))
            {
                basePath = pathname.Replace(".\\", "").Replace("\\", "");
            }

            var outputFilename = Path.Combine(Path.GetDirectoryName(pathname), String.Format("{0}.bin", basePath));

            File.WriteAllBytes(outputFilename, outputData.ToArray());
        }
示例#2
0
        static void ParseTexbinFile(string filename, bool splitImages = true)
        {
            var outputPath = Path.Combine(Path.GetDirectoryName(filename), Path.GetFileNameWithoutExtension(filename));

            Directory.CreateDirectory(outputPath);

            using (BinaryReader reader = new BinaryReader(File.Open(filename, FileMode.Open)))
            {
                var texpMagic = Encoding.ASCII.GetString(reader.ReadBytes(4));

                if (texpMagic != "PXET")
                {
                    Console.WriteLine("Not a valid texbin file");
                    Environment.Exit(1);
                }

                var unk1            = reader.ReadInt32();
                var unk2            = reader.ReadInt32();
                var archiveSize     = reader.ReadInt32();
                var unk3            = reader.ReadInt32();
                var fileCount       = reader.ReadInt64();
                var dataOffset      = reader.ReadInt32();
                var rectOffset      = reader.ReadInt32();
                var unk4            = reader.ReadBytes(0x10);
                var nameOffset      = reader.ReadInt32();
                var unk5            = reader.ReadInt32();
                var dataEntryOffset = reader.ReadInt32();

                if (fileCount == 0)
                {
                    Console.WriteLine("This file doesn't contain any image data.");
                    return;
                }

                var entries = ReadNameSection(reader, nameOffset);
                ReadDataEntrySection(reader, dataEntryOffset, fileCount, entries);

                var texInfo = new TexInfo();
                if (rectOffset != 0)
                {
                    var rectInfo = ReadRectEntrySection(reader, rectOffset);
                    foreach (var rect in rectInfo)
                    {
                        var e = new RectInfo
                        {
                            ExternalFilename = entries[rect.ImageId].Filename,
                            Filename         = rect.Entry.Filename,
                            X = rect.X,
                            Y = rect.Y,
                            W = rect.W,
                            H = rect.H
                        };
                        texInfo.RectInfo.Add(e);
                    }

                    // Add code to optionally not split texture files and save a metadata file instead
                    if (!splitImages)
                    {
                        Serialize <TexInfo>(texInfo, Path.Combine(outputPath, "_metadata.xml"));
                    }
                }

                var formatMetadata = new FormatMetadata();
                foreach (var entry in entries)
                {
                    reader.BaseStream.Seek(entry.DataOffset, SeekOrigin.Begin);

                    var data = Decompress(reader);

                    if (Encoding.ASCII.GetString(data, 0, 4) == "TXDT" ||
                        Encoding.ASCII.GetString(data, 0, 4) == "TDXT")
                    {
                        var rectInfoList = texInfo.RectInfo.Where(x =>
                                                                  String.CompareOrdinal(Path.GetFileNameWithoutExtension(entry.Filename),
                                                                                        x.ExternalFilename) == 0).ToList();

                        if (!splitImages)
                        {
                            rectInfoList.Clear();
                        }

                        if (rectInfoList.Count == 0)
                        {
                            var rectInfo = new RectInfo
                            {
                                ExternalFilename = entry.Filename,
                                Filename         = entry.Filename,
                                X = 0,
                                Y = 0,
                                W = 0,
                                H = 0
                            };
                            rectInfoList.Add(rectInfo);
                        }

                        if (!splitImages)
                        {
                            formatMetadata.FormatInfo.Add(new FormatInfo {
                                Filename   = entry.Filename,
                                FormatType = data[0x2c]
                            });
                        }

                        foreach (var rectInfo in rectInfoList)
                        {
                            try
                            {
                                using (var stream = new MemoryStream(data))
                                {
                                    using (var dataReader = new BinaryReader(stream))
                                    {
                                        byte[] extractedData;


                                        if (!splitImages || rectInfoList.Count == 0 || rectInfo.W == 0 || rectInfo.H == 0)
                                        {
                                            extractedData = gitadora_textool.Program.ExtractImageCore(dataReader, null);
                                        }
                                        else
                                        {
                                            extractedData = gitadora_textool.Program.ExtractImageCore(dataReader, rectInfo);
                                        }

                                        var ext = ".png";
                                        if (extractedData[0] == 'D' && extractedData[1] == 'D' && extractedData[2] == 'S' && extractedData[3] == ' ')
                                        {
                                            ext = ".dds";
                                        }

                                        var outputFilename = Path.Combine(outputPath, rectInfo.Filename);
                                        outputFilename += ext;

                                        Console.WriteLine("Saving {0}...", outputFilename);

                                        File.WriteAllBytes(outputFilename, extractedData);
                                        // File.WriteAllBytes(outputFilename.Replace(ext, ".bin"), data);

                                        if (splitImages)
                                        {
                                            formatMetadata.FormatInfo.Add(new FormatInfo {
                                                Filename   = rectInfo.Filename,
                                                FormatType = data[0x2c]
                                            });
                                        }
                                    }
                                }
                            }
                            catch (Exception e)
                            {
                                Console.WriteLine("Couldn't convert image: {0}", e.Message);
                                File.WriteAllBytes(Path.Combine(outputPath, entry.Filename), data);
                            }
                        }
                    }
                }

                Serialize <FormatMetadata>(formatMetadata, Path.Combine(outputPath, "_metadata-format.xml"));
            }
        }