Beispiel #1
0
        /// <summary>
        /// Write a DDS file from this header object and given pixel data.
        /// </summary>
        public byte[] Write(byte[] pixelData)
        {
            var bw = new BinaryWriterEx(false);

            bw.WriteASCII("DDS ");
            bw.WriteInt32(0x7C);
            bw.WriteUInt32((uint)dwFlags);
            bw.WriteInt32(dwHeight);
            bw.WriteInt32(dwWidth);
            bw.WriteInt32(dwPitchOrLinearSize);
            bw.WriteInt32(dwDepth);
            bw.WriteInt32(dwMipMapCount);
            bw.WriteInt32s(dwReserved1);
            ddspf.Write(bw);
            bw.WriteUInt32((uint)dwCaps);
            bw.WriteUInt32((uint)dwCaps2);
            bw.WriteInt32(dwCaps3);
            bw.WriteInt32(dwCaps4);
            bw.WriteInt32(dwReserved2);

            if (ddspf.dwFourCC == "DX10")
            {
                header10.Write(bw);
            }

            bw.WriteBytes(pixelData);
            return(bw.FinishBytes());
        }
Beispiel #2
0
        /// <summary>
        /// Compress a DCX file to an array of bytes using the specified DCX type.
        /// </summary>
        public static byte[] Compress(byte[] data, Type type)
        {
            BinaryWriterEx bw = new BinaryWriterEx(true);

            Compress(data, bw, type);
            return(bw.FinishBytes());
        }
Beispiel #3
0
        /// <summary>
        /// Writes the file to an array of bytes, compressing it as specified.
        /// </summary>
        public byte[] Write(DCX.Type compression)
        {
            BinaryWriterEx bw = new BinaryWriterEx(false);

            Write(bw, compression);
            return(bw.FinishBytes());
        }
Beispiel #4
0
        /// <summary>
        /// Writes the BHD and BDT as two arrays of bytes.
        /// </summary>
        public void Write(out byte[] bhdBytes, out byte[] bdtBytes)
        {
            BinaryWriterEx bhdWriter = new BinaryWriterEx(false);
            BinaryWriterEx bdtWriter = new BinaryWriterEx(false);

            Write(bhdWriter, bdtWriter);
            bhdBytes = bhdWriter.FinishBytes();
            bdtBytes = bdtWriter.FinishBytes();
        }
Beispiel #5
0
 /// <summary>
 /// Writes the BHD as a file and the BDT as an array of bytes.
 /// </summary>
 public void Write(string bhdPath, out byte[] bdtBytes)
 {
     using (FileStream bhdStream = System.IO.File.Create(bhdPath))
     {
         BinaryWriterEx bhdWriter = new BinaryWriterEx(false, bhdStream);
         BinaryWriterEx bdtWriter = new BinaryWriterEx(false);
         Write(bhdWriter, bdtWriter);
         bhdWriter.Finish();
         bdtBytes = bdtWriter.FinishBytes();
     }
 }
Beispiel #6
0
 /// <summary>
 /// Writes the BHD as an array of bytes and the BDT as a file.
 /// </summary>
 public void Write(out byte[] bhdBytes, string bdtPath)
 {
     using (FileStream bdtStream = System.IO.File.Create(bdtPath))
     {
         BinaryWriterEx bhdWriter = new BinaryWriterEx(false);
         BinaryWriterEx bdtWriter = new BinaryWriterEx(false, bdtStream);
         Write(bhdWriter, bdtWriter);
         bdtWriter.Finish();
         bhdBytes = bhdWriter.FinishBytes();
     }
 }
Beispiel #7
0
        /// <summary>
        /// Writes the file to an array of bytes, compressing it as specified.
        /// </summary>
        public byte[] Write(DCX.Type compression)
        {
            if (!Validate(out Exception ex))
            {
                throw ex;
            }

            BinaryWriterEx bw = new BinaryWriterEx(false);

            Write(bw, compression);
            return(bw.FinishBytes());
        }
Beispiel #8
0
            public static byte[] Write(List <Image> images)
            {
                var bw = new BinaryWriterEx(false);

                foreach (Image image in images)
                {
                    foreach (byte[] mip in image.MipLevels)
                    {
                        bw.WriteBytes(mip);
                    }
                }
                return(bw.FinishBytes());
            }
Beispiel #9
0
 /// <summary>
 /// Writes file data to a BinaryWriterEx, compressing it afterwards if specified.
 /// </summary>
 private void Write(BinaryWriterEx bw, DCX.Type compression)
 {
     if (compression == DCX.Type.None)
     {
         Write(bw);
     }
     else
     {
         BinaryWriterEx bwUncompressed = new BinaryWriterEx(false);
         Write(bwUncompressed);
         byte[] uncompressed = bwUncompressed.FinishBytes();
         DCX.Compress(uncompressed, bw, compression);
     }
 }
Beispiel #10
0
            /// <summary>
            /// Packs an enumeration of arg values into a byte array for use in an instruction.
            /// </summary>
            public void PackArgs(IEnumerable <object> args, bool bigEndian = false)
            {
                using (var ms = new MemoryStream())
                {
                    var bw = new BinaryWriterEx(bigEndian, ms);
                    foreach (object arg in args)
                    {
                        switch (arg)
                        {
                        case byte ub:
                            bw.WriteByte(ub); break;

                        case ushort us:
                            bw.Pad(2);
                            bw.WriteUInt16(us); break;

                        case uint ui:
                            bw.Pad(4);
                            bw.WriteUInt32(ui); break;

                        case sbyte sb:
                            bw.WriteSByte(sb); break;

                        case short ss:
                            bw.Pad(2);
                            bw.WriteInt16(ss); break;

                        case int si:
                            bw.Pad(4);
                            bw.WriteInt32(si); break;

                        case float f:
                            bw.Pad(4);
                            bw.WriteSingle(f); break;

                        case long sl:
                            bw.Pad(8);
                            bw.WriteInt64(sl); break;

                        default:
                            throw new NotSupportedException($"Unsupported argument type: {arg.GetType()}");
                        }
                    }
                    ArgData = bw.FinishBytes();
                }
            }
Beispiel #11
0
        internal override void Write(BinaryWriterEx bw)
        {
            BinaryWriterEx bwData = new BinaryWriterEx(false);

            bwData.WriteInt32(0);
            bwData.WriteInt32(Struct1s.Count);
            bwData.WriteInt32(Struct2s.Count);
            bwData.WriteInt32(0);

            foreach (Struct1 struct1 in Struct1s)
            {
                struct1.Write(bwData);
            }
            bwData.Pad(0x10);

            foreach (Struct2 struct2 in Struct2s)
            {
                struct2.Write(bwData);
            }
            bwData.Pad(0x10);

            bwData.WriteInt16(0);
            foreach (string str in Strings)
            {
                bwData.WriteUTF16(str, true);
            }
            bwData.Pad(0x10);

            byte[] data = bwData.FinishBytes();

            bw.WriteASCII("ENFL");
            bw.WriteInt32(0x10415);
            bw.ReserveInt32("CompressedSize");
            bw.WriteInt32(data.Length);
            int compressedSize = Util.WriteZlib(bw, 0xDA, data);

            bw.FillInt32("CompressedSize", compressedSize);
        }
Beispiel #12
0
        /// <summary>
        /// Write a DDS file from this header object and given pixel data.
        /// </summary>
        public byte[] Write(byte[] pixelData)
        {
            BinaryWriterEx bw = new BinaryWriterEx(false);

            bw.WriteASCII("DDS ");
            bw.WriteInt32(0x7C);

            bw.WriteUInt32((uint)dwFlags);
            bw.WriteInt32(dwHeight);
            bw.WriteInt32(dwWidth);
            bw.WriteInt32(dwPitchOrLinearSize);
            bw.WriteInt32(dwDepth);
            bw.WriteInt32(dwMipMapCount);

            for (int i = 0; i < 11; i++)
            {
                bw.WriteInt32(0);
            }

            ddspf.Write(bw);
            bw.WriteUInt32((uint)dwCaps);
            bw.WriteUInt32((uint)dwCaps2);

            for (int i = 0; i < 3; i++)
            {
                bw.WriteInt32(0);
            }

            if (ddspf.dwFourCC == PIXELFORMAT.FourCCDX10)
            {
                header10.Write(bw);
            }

            bw.WriteBytes(pixelData);
            return(bw.FinishBytes());
        }
Beispiel #13
0
            // <summary>
            // Convert the internal format to PC tpf format
            // </summary>
            public void ConsoleToPC(TPFPlatform source)
            {
                // Need to create a DDS Header
                BinaryWriterEx bw = new BinaryWriterEx(false);

                bw.WriteASCII("DDS ");
                bw.WriteInt32(124);
                bw.WriteUInt32(659463); // Flags
                bw.WriteUInt32((uint)Header.Height);
                bw.WriteUInt32((uint)Header.Width);
                bw.WriteUInt32(((uint)Header.Width * (uint)Header.Height) / 2); // Dummy pitch size
                bw.WriteUInt32(1);                                              // Depth
                if (source == TPFPlatform.PS3)
                {
                    // DeS sometimes has mipmap count set to 0 :trashcat:
                    if (Mipmaps == 0)
                    {
                        var dim = Math.Max(Header.Width, Header.Height);
                        while (dim >= 1)
                        {
                            Mipmaps++;
                            dim >>= 1;
                        }
                    }
                }
                bw.WriteUInt32(Mipmaps);
                for (int i = 0; i < 11; i++)
                {
                    bw.WriteInt32(0);
                }
                // Pixel format
                bw.WriteInt32(32);
                bw.WriteInt32(4); // Flags (compressed)
                bool writeExtendedHeader = false;

                if (Header.DXGIFormat == 71 || Header.DXGIFormat == 72 || (source == TPFPlatform.PS3 && (Format == 0 || Format == 1)))
                {
                    bw.WriteASCII("DXT1");
                }
                else if (Header.DXGIFormat == 73 || Header.DXGIFormat == 74 || Header.DXGIFormat == 75 || (source == TPFPlatform.PS3 && (Format == 2 || Format == 3)))
                {
                    bw.WriteASCII("DXT3");
                }
                else if (Header.DXGIFormat == 76 || Header.DXGIFormat == 77 || Header.DXGIFormat == 78 || (source == TPFPlatform.PS3 && (Format == 4 || Format == 5)))
                {
                    bw.WriteASCII("DXT5");
                }
                else if (Header.DXGIFormat == 79 || Header.DXGIFormat == 80 || Header.DXGIFormat == 81)
                {
                    bw.WriteASCII("ATI1");
                }
                else if (Header.DXGIFormat == 82 || Header.DXGIFormat == 83 || Header.DXGIFormat == 84)
                {
                    bw.WriteASCII("ATI2");
                }
                else if (source == TPFPlatform.PS3 && (Format == 9 || Format == 10))
                {
                    bw.WriteASCII("DXT1");
                    Console.WriteLine("ARGB");
                }
                else
                {
                    bw.WriteASCII("DX10");
                    writeExtendedHeader = true;
                }
                bw.WriteInt32(0);
                bw.WriteInt32(0);
                bw.WriteInt32(0);
                bw.WriteInt32(0);
                bw.WriteInt32(0);

                bw.WriteUInt32(0x401008); // Caps
                if (Cubemap)
                {
                    bw.WriteUInt32(0xFE00);
                }
                else
                {
                    bw.WriteUInt32(0);
                }
                bw.WriteUInt32(0);
                bw.WriteUInt32(0);
                bw.WriteUInt32(0);

                // DX10 extended header
                if (writeExtendedHeader)
                {
                    bw.WriteInt32(Header.DXGIFormat);
                    bw.WriteUInt32(3); // 2D texture
                    if (Cubemap)
                    {
                        bw.WriteUInt32(0x4);
                    }
                    else
                    {
                        bw.WriteUInt32(0);
                    }
                    bw.WriteUInt32(1); // Array Size
                    bw.WriteUInt32(0); // Misc
                }

                // Next attempt to unswizzle the texture
                byte[] unswizzled = new byte[Bytes.Length];
                for (int i = 0; i < unswizzled.Length; i++)
                {
                    unswizzled[i] = Bytes[i];
                }

                if (source == TPFPlatform.PS4)
                {
                    uint blockSize = 16;
                    if (Header.DXGIFormat == 71 || Header.DXGIFormat == 72 || Header.DXGIFormat == 79 || Header.DXGIFormat == 80 || Header.DXGIFormat == 81)
                    {
                        blockSize = 8;
                    }

                    int mipBase    = 0;
                    int mipBaseSrc = 0;
                    for (int miplevel = 0; miplevel < Mipmaps; miplevel++)
                    {
                        uint bytesPerLine = Math.Max((uint)Header.Width >> miplevel, 1) * blockSize / 4;
                        int  heightBlock  = Math.Max((Header.Height / 4) >> miplevel, 1);
                        int  widthBlock   = Math.Max((Header.Width / 4) >> miplevel, 1);
                        // Convert swizzled to linear strided

                        int index = 0;
                        for (int y = 0; y < heightBlock; y++)
                        {
                            for (int x = 0; x < widthBlock; x++)
                            {
                                int mx = x;
                                int my = y;
                                if (widthBlock > 1 && heightBlock > 1)
                                {
                                    MapBlockPosition(x, y, widthBlock, 2, out mx, out my);
                                }

                                if (widthBlock > 2 && heightBlock > 2)
                                {
                                    MapBlockPosition(mx, my, widthBlock, 4, out mx, out my);
                                }

                                if (widthBlock > 4 && heightBlock > 4)
                                {
                                    MapBlockPosition(mx, my, widthBlock, 8, out mx, out my);
                                }

                                int destinationIndex = (int)blockSize * (my * widthBlock + mx);
                                for (int i = 0; i < blockSize; i++)
                                {
                                    unswizzled[mipBase + destinationIndex + i] = Bytes[mipBaseSrc + index];
                                    index += 1;
                                }
                            }
                        }

                        mipBase += index;
                        if (index < 512)
                        {
                            mipBaseSrc += 512;
                        }
                        else
                        {
                            mipBaseSrc += index;
                        }
                    }
                }

                // Append the rest of the original texture and update
                bw.WriteBytes(unswizzled);
                Bytes = bw.FinishBytes();
            }