예제 #1
0
파일: YTPF.cs 프로젝트: micvb123/Yabber
        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();
        }
예제 #2
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;
            }