Exemplo n.º 1
0
        private bool repackFile(TPF.Texture tpfEntry, string name, string baseDir, string subDir)
        {
            string inputPath = baseDir + "\\" + subDir + "\\" + name + ".dds";

            //DBGTEX_DETAIL crashes this, what in the heck
            if (inputPath != null && File.Exists(inputPath) && name != "DBGTEX_DETAIL")
            {
                byte[] inputBytes = File.ReadAllBytes(inputPath);

                DXGIFormat originalFormat = DDSFile.Read(new MemoryStream(tpfEntry.Bytes)).Format;

                DXGIFormat newFormat = DDSFile.Read(new MemoryStream(inputBytes)).Format;

                if (originalFormat != DXGIFormat.Unknown && newFormat != DXGIFormat.Unknown && originalFormat != newFormat)
                {
                    byte[] newBytes = convertFile(inputPath, originalFormat);
                    if (newBytes != null)
                    {
                        inputBytes = newBytes;
                    }
                }

                tpfEntry.Bytes = inputBytes;

                return(true);
            }
            else
            {
                return(false);
            }
        }
Exemplo n.º 2
0
        private void repackTPF(TPF tpf, string baseDir, string subDir)
        {
            // parts\HR_F_0010 and parts\HR_F_0010_M have duplicate filenames in the same tpf
            // thx QLOC
            List <string> names = new List <string>();
            List <string> dupes = new List <string>();

            foreach (TPF.Texture tpfEntry in tpf.Textures)
            {
                if (names.Contains(tpfEntry.Name))
                {
                    dupes.Add(tpfEntry.Name);
                }
                else
                {
                    names.Add(tpfEntry.Name);
                }
            }

            for (int i = 0; i < tpf.Textures.Count; i++)
            {
                TPF.Texture tpfEntry = tpf.Textures[i];
                string      name     = tpfEntry.Name;
                if (dupes.Contains(name))
                {
                    name += "_" + i;
                }

                repackFile(tpfEntry, name, baseDir, subDir);
            }
        }
Exemplo n.º 3
0
 public static bool IsTPFCube(TPF.Texture tex, TPF.TPFPlatform platform)
 {
     if (platform == TPF.TPFPlatform.PC)
     {
         DDS dds = new DDS(tex.Bytes);
         return((dds.dwCaps2 & DDS.DDSCAPS2.CUBEMAP) > 0);
     }
     return(tex.Type == TPF.TexType.Cubemap);
 }
Exemplo n.º 4
0
 public UnpackReportFile(TPF.Texture tex)
 {
     using (var ms = new MemoryStream(tex.Bytes))
         using (var dds = DDSFile.Read(ms))
         {
             Name   = tex.Name;
             Format = dds?.Format ?? DXGIFormat.Unknown;
             Width  = dds?.MipChains[0][0].Width ?? -1;
             Height = dds?.MipChains[0][0].Height ?? -1;
         }
 }
Exemplo n.º 5
0
        private void UnpackFile(TPF.Texture tpfEntry, string name, string baseDir, string subDir)
        {
            string subPath = subDir + "\\" + name + ".dds";
            string ddsPath = baseDir + "\\" + subPath;

            if (!File.Exists(ddsPath))
            {
                Directory.CreateDirectory(Path.GetDirectoryName(ddsPath));
                File.WriteAllBytes(ddsPath, tpfEntry.Bytes);
            }
        }
Exemplo n.º 6
0
        private bool repackFile(TPF.Texture tpfEntry, string name, string baseDir, string subDir)
        {
            string inputPath = getSwappedPath(name, subDir, out bool dds);

            if (inputPath != null && File.Exists(inputPath))
            {
                byte[] inputBytes = File.ReadAllBytes(inputPath);

                DXGIFormat originalFormat = DDSFile.Read(new MemoryStream(tpfEntry.Bytes)).Format;
                if (originalFormat == DXGIFormat.Unknown)
                {
                    appendError("Error: {0}\r\n\u2514\u2500 Could not determine format of game file.", subDir + "\\" + name + ".dds");
                }

                bool convert = !dds;
                if (dds)
                {
                    DXGIFormat newFormat = DDSFile.Read(new MemoryStream(inputBytes)).Format;

                    if (newFormat == DXGIFormat.Unknown)
                    {
                        appendError("Error: {0}\r\n\u2514\u2500 Could not determine format of override file.", inputPath);
                    }

                    if (originalFormat != DXGIFormat.Unknown && newFormat != DXGIFormat.Unknown && originalFormat != newFormat)
                    {
                        convert = true;
                    }
                }

                if (convert)
                {
                    byte[] newBytes = convertFile(inputPath, originalFormat);
                    if (newBytes != null)
                    {
                        inputBytes = newBytes;
                    }
                }

                tpfEntry.Bytes = inputBytes;
                lock (countLock)
                    textureCount++;

                return(true);
            }
            else
            {
                return(false);
            }
        }
Exemplo n.º 7
0
        public static void Unpack(this TPF tpf, string sourceName, string targetDir, IProgress <float> progress)
        {
#if !DEBUG
            if (tpf.Platform != TPF.TPFPlatform.PC)
            {
                throw new NotSupportedException("Yabber does not support console TPFs at the moment.");
            }
#endif

            Directory.CreateDirectory(targetDir);
            var xws = new XmlWriterSettings();
            xws.Indent = true;
            var xw = XmlWriter.Create($"{targetDir}\\_yabber-tpf.xml", xws);
            xw.WriteStartElement("tpf");

            xw.WriteElementString("filename", sourceName);
            xw.WriteElementString("compression", tpf.Compression.ToString());
            xw.WriteElementString("encoding", $"0x{tpf.Encoding:X2}");
            xw.WriteElementString("flag2", $"0x{tpf.Flag2:X2}");

            xw.WriteStartElement("textures");
            for (int i = 0; i < tpf.Textures.Count; i++)
            {
                TPF.Texture texture = tpf.Textures[i];
                xw.WriteStartElement("texture");
                xw.WriteElementString("name", texture.Name + ".dds");
                xw.WriteElementString("format", texture.Format.ToString());
                xw.WriteElementString("flags1", $"0x{texture.Flags1:X2}");

                if (texture.FloatStruct != null)
                {
                    xw.WriteStartElement("FloatStruct");
                    xw.WriteAttributeString("Unk00", texture.FloatStruct.Unk00.ToString());
                    foreach (float value in texture.FloatStruct.Values)
                    {
                        xw.WriteElementString("Value", value.ToString());
                    }
                    xw.WriteEndElement();
                }
                xw.WriteEndElement();

                File.WriteAllBytes($"{targetDir}\\{texture.Name}.dds", texture.Headerize());
                progress.Report((float)i / tpf.Textures.Count);
            }
            xw.WriteEndElement();

            xw.WriteEndElement();
            xw.Close();
        }
Exemplo n.º 8
0
        private bool processTPF(TPF tpf, string baseDir, string subDir)
        {
            // parts\HR_F_0010 and parts\HR_F_0010_M have duplicate filenames in the same tpf
            // thx QLOC
            List <string> names = new List <string>();
            List <string> dupes = new List <string>();

            foreach (TPF.Texture tpfEntry in tpf.Textures)
            {
                if (names.Contains(tpfEntry.Name))
                {
                    dupes.Add(tpfEntry.Name);
                }
                else
                {
                    names.Add(tpfEntry.Name);
                }
            }

            bool edited = false;

            for (int i = 0; i < tpf.Textures.Count; i++)
            {
                if (stop)
                {
                    return(false);
                }

                TPF.Texture tpfEntry = tpf.Textures[i];
                string      name     = tpfEntry.Name;
                if (dupes.Contains(name))
                {
                    name += "_" + i;
                }

                if (repack)
                {
                    edited |= repackFile(tpfEntry, name, baseDir, subDir);
                }
                else
                {
                    unpackFile(tpfEntry, name, baseDir, subDir);
                }
            }
            return(edited);
        }
Exemplo n.º 9
0
        public static void Repack(string sourceDir, string targetDir)
        {
            TPF         tpf = new TPF();
            XmlDocument xml = new XmlDocument();

            xml.Load($"{sourceDir}\\_yabber-tpf.xml");

            string filename = xml.SelectSingleNode("tpf/filename").InnerText;

            Enum.TryParse(xml.SelectSingleNode("tpf/compression")?.InnerText ?? "None", out tpf.Compression);
            tpf.Encoding = Convert.ToByte(xml.SelectSingleNode("tpf/encoding").InnerText, 16);
            tpf.Flag2    = Convert.ToByte(xml.SelectSingleNode("tpf/flag2").InnerText, 16);

            foreach (XmlNode texNode in xml.SelectNodes("tpf/textures/texture"))
            {
                string name   = Path.GetFileNameWithoutExtension(texNode.SelectSingleNode("name").InnerText);
                byte   format = Convert.ToByte(texNode.SelectSingleNode("format").InnerText);
                byte   flags1 = Convert.ToByte(texNode.SelectSingleNode("flags1").InnerText, 16);

                TPF.FloatStruct floatStruct = null;
                XmlNode         floatsNode  = texNode.SelectSingleNode("FloatStruct");
                if (floatsNode != null)
                {
                    floatStruct       = new TPF.FloatStruct();
                    floatStruct.Unk00 = int.Parse(floatsNode.Attributes["Unk00"].InnerText);
                    foreach (XmlNode valueNode in floatsNode.SelectNodes("Value"))
                    {
                        floatStruct.Values.Add(float.Parse(valueNode.InnerText));
                    }
                }

                byte[] bytes   = File.ReadAllBytes($"{sourceDir}\\{name}.dds");
                var    texture = new TPF.Texture(name, format, flags1, bytes);
                texture.FloatStruct = floatStruct;
                tpf.Textures.Add(texture);
            }

            string outPath = $"{targetDir}\\{filename}";

            YBUtil.Backup(outPath);
            tpf.Write(outPath);
        }
Exemplo n.º 10
0
        private void unpackFile(TPF.Texture tpfEntry, string name, string baseDir, string subDir)
        {
            string subPath = subDir + "\\" + name + ".dds";
            string ddsPath = baseDir + "\\" + subPath;

            lock (writeLock)
            {
                if (!File.Exists(ddsPath))
                {
                    Directory.CreateDirectory(Path.GetDirectoryName(ddsPath));
                    File.WriteAllBytes(ddsPath, tpfEntry.Bytes);
                    lock (countLock)
                        textureCount++;
                }
                else
                {
                    appendError("Error: {0}\r\n\u2514\u2500 Duplicate file found.", subPath);
                }
            }
        }
Exemplo n.º 11
0
            public unsafe void FillWithPS4TPF(GraphicsDevice d, CommandList cl, TPF.TPFPlatform platform, TPF.Texture tex, string name)
            {
                if (platform != TPF.TPFPlatform.PS4)
                {
                    return;
                }
                uint        width    = (uint)tex.Header.Width;
                uint        height   = (uint)tex.Header.Height;
                uint        mipCount = (uint)tex.Mipmaps;
                PixelFormat format;

                format = GetPixelFormatFromDXGI((DDS.DXGI_FORMAT)tex.Header.DXGIFormat);

                width  = (uint)(Math.Ceiling(width / 4f) * 4f);
                height = (uint)(Math.Ceiling(height / 4f) * 4f);
                if (mipCount == 0)
                {
                    mipCount = (uint)(1 + Math.Floor(Math.Log(Math.Max(width, height), 2)));
                }

                bool isCubemap = (tex.Type == TPF.TexType.Cubemap);

                var usage = (isCubemap) ? TextureUsage.Cubemap : 0;

                uint arrayCount = isCubemap ? 6u : 1;

                TextureDescription desc = new TextureDescription();

                desc.Width       = width;
                desc.Height      = height;
                desc.MipLevels   = mipCount;
                desc.SampleCount = TextureSampleCount.Count1;
                desc.ArrayLayers = arrayCount;
                desc.Depth       = 1;
                desc.Type        = TextureType.Texture2D;
                desc.Usage       = TextureUsage.Staging;
                desc.Format      = format;

                _staging = d.ResourceFactory.CreateTexture(desc);

                uint blockSize    = (uint)GetBlockSize(tex.Format);
                uint paddedWidth  = 0;
                uint paddedHeight = 0;
                uint paddedSize   = 0;
                uint copyOffset   = 0;

                for (int slice = 0; slice < arrayCount; slice++)
                {
                    uint currentWidth  = width;
                    uint currentHeight = height;
                    for (uint level = 0; level < mipCount; level++)
                    {
                        if (tex.Format == 105)
                        {
                            paddedWidth  = currentWidth;
                            paddedHeight = currentHeight;
                            paddedSize   = paddedWidth * paddedHeight * blockSize;
                        }
                        else
                        {
                            paddedWidth  = (uint)(Math.Ceiling(currentWidth / 32f) * 32f);
                            paddedHeight = (uint)(Math.Ceiling(currentHeight / 32f) * 32f);
                            paddedSize   = (uint)(Math.Ceiling(paddedWidth / 4f) * Math.Ceiling(paddedHeight / 4f) * blockSize);
                        }

                        var mipInfo = GetMipInfo(format, tex.Header.Width, tex.Header.Height, (int)level, false);

                        MappedResource map = d.Map(_staging, MapMode.Write, (uint)slice * (uint)mipCount + level);
                        //fixed (void* data = &tex.Bytes[copyOffset])
                        //{
                        //Unsafe.CopyBlock(map.Data.ToPointer(), data, (uint)paddedSize);
                        DeswizzleDDSBytesPS4((int)currentWidth, (int)currentHeight, tex.Format, (int)blockSize,
                                             (int)paddedWidth, new Span <byte>(tex.Bytes, (int)copyOffset, (int)paddedSize),
                                             new Span <byte>(map.Data.ToPointer(), (int)mipInfo));
                        //}
                        copyOffset += paddedSize;

                        if (currentWidth > 1)
                        {
                            currentWidth /= 2;
                        }
                        if (currentHeight > 1)
                        {
                            currentHeight /= 2;
                        }
                    }
                }

                desc.Usage       = TextureUsage.Sampled | usage;
                desc.ArrayLayers = 1;
                _texture         = d.ResourceFactory.CreateTexture(desc);
                _texture.Name    = name;
                cl.CopyTexture(_staging, _texture);
                Resident = true;
                _pool.DescriptorTableDirty = true;
            }
Exemplo n.º 12
0
            public unsafe void FillWithTPF(GraphicsDevice d, CommandList cl, TPF.TPFPlatform platform, TPF.Texture tex, string name)
            {
                DDS dds;
                var bytes = tex.Bytes;

                if (platform != TPF.TPFPlatform.PC)
                {
                    bytes = tex.Headerize();
                    dds   = new DDS(bytes);
                }
                else
                {
                    dds = new DDS(tex.Bytes);
                }

                uint        width  = (uint)dds.dwWidth;
                uint        height = (uint)dds.dwHeight;
                PixelFormat format;

                if (dds.header10 != null)
                {
                    format = GetPixelFormatFromDXGI(dds.header10.dxgiFormat);
                }
                else
                {
                    if (dds.ddspf.dwFlags == (DDS.DDPF.RGB | DDS.DDPF.ALPHAPIXELS) &&
                        dds.ddspf.dwRGBBitCount == 32)
                    {
                        format = PixelFormat.R8_G8_B8_A8_UNorm_SRgb;
                    }
                    else if (dds.ddspf.dwFlags == (DDS.DDPF.RGB) && dds.ddspf.dwRGBBitCount == 24)
                    {
                        format = PixelFormat.R8_G8_B8_A8_UNorm_SRgb;
                        // 24-bit formats are annoying for now
                        return;
                    }
                    else
                    {
                        format = GetPixelFormatFromFourCC(dds.ddspf.dwFourCC);
                    }
                }

                if (!Utils.IsPowerTwo(width) || !Utils.IsPowerTwo(height))
                {
                    return;
                }
                width  = IsCompressedFormat(format) ? (uint)((width + 3) & ~0x3) : width;
                height = IsCompressedFormat(format) ? (uint)((height + 3) & ~0x3) : height;

                bool isCubemap = false;

                if ((dds.dwCaps2 & DDS.DDSCAPS2.CUBEMAP) > 0)
                {
                    isCubemap = true;
                }

                var usage = (isCubemap) ? TextureUsage.Cubemap : 0;

                uint arrayCount = isCubemap ? 6u : 1;

                TextureDescription desc = new TextureDescription();

                desc.Width       = width;
                desc.Height      = height;
                desc.MipLevels   = (uint)dds.dwMipMapCount;
                desc.SampleCount = TextureSampleCount.Count1;
                desc.ArrayLayers = arrayCount;
                desc.Depth       = 1;
                desc.Type        = TextureType.Texture2D;
                desc.Usage       = TextureUsage.Staging;
                desc.Format      = format;

                _staging = d.ResourceFactory.CreateTexture(desc);

                int paddedWidth  = 0;
                int paddedHeight = 0;
                int paddedSize   = 0;
                int copyOffset   = dds.DataOffset;

                for (int slice = 0; slice < arrayCount; slice++)
                {
                    for (uint level = 0; level < dds.dwMipMapCount; level++)
                    {
                        MappedResource map     = d.Map(_staging, MapMode.Write, (uint)slice * (uint)dds.dwMipMapCount + level);
                        var            mipInfo = GetMipInfo(format, (int)dds.dwWidth, (int)dds.dwHeight, (int)level, false);
                        //paddedSize = mipInfo.ByteCount;
                        paddedSize = mipInfo;
                        fixed(void *data = &bytes[copyOffset])
                        {
                            Unsafe.CopyBlock(map.Data.ToPointer(), data, (uint)paddedSize);
                        }

                        copyOffset += paddedSize;
                    }
                }

                desc.Usage       = TextureUsage.Sampled | usage;
                desc.ArrayLayers = 1;
                _texture         = d.ResourceFactory.CreateTexture(desc);
                _texture.Name    = name;
                cl.CopyTexture(_staging, _texture);
                Resident = true;
                _pool.DescriptorTableDirty = true;
            }