Esempio n. 1
0
        public static bool SplitPkf(Byte[] File, string Directory)
        {
            try {
                System.IO.Directory.CreateDirectory(Directory);
                uint location = 0;
                while (true)
                {
                    byte Ident            = File[location];
                    uint CompressedSize   = BitConverter.ToUInt32(File, (int)location + 1);
                    uint DecompressedSize = BitConverter.ToUInt32(File, (int)location + 5);

                    byte[] SplitFile = new byte[CompressedSize + 9];
                    ArrayUtils.CopyByteArrayPart(File, (int)location, SplitFile, 0, (int)CompressedSize + 9);

                    System.IO.File.WriteAllBytes(Directory + "/" + location.ToString("X8") + ".c", SplitFile);

                    location = NumberUtils.Align(location + CompressedSize + 9, 0x800u);
                    if (location >= File.Length)
                    {
                        break;
                    }
                }
            } catch (Exception) {
                return(false);
            }
            return(true);
        }
Esempio n. 2
0
        public override Stream GetSinglePlane(Stream inputStream, uint depthlevel)
        {
            if (Mipmaps > 1)
            {
                throw new Exception("Don't know how to deal with volume textures with mipmaps.");
            }
            if (!(Format == TextureFormat.DXT1a || Format == TextureFormat.DXT1b || Format == TextureFormat.DXT5a || Format == TextureFormat.DXT5b))
            {
                throw new Exception("Volume textures only implemented for DXT formats.");
            }

            // Format reference: https://www.khronos.org/registry/OpenGL/extensions/NV/NV_texture_compression_vtc.txt
            uint bytecount        = GetByteCountSingleDepthPlane(0);
            uint group            = depthlevel / 4u;
            uint texInGroupBefore = depthlevel % 4u;
            uint texInGroupAfter  = 3u - texInGroupBefore;

            // special handling for last group if depth not divisible by 4
            uint nonDivisiblePlanesAtEnd = Depth % 4;
            uint groupCount = NumberUtils.Align(Depth, 4u) / 4;

            if (nonDivisiblePlanesAtEnd != 0 && group == (groupCount - 1u))
            {
                texInGroupAfter = (nonDivisiblePlanesAtEnd - texInGroupBefore) - 1u;
            }

            uint bytesPerTexLine;

            switch (Format)
            {
            case TextureFormat.DXT1a:
            case TextureFormat.DXT1b:
                bytesPerTexLine = 8;
                break;

            case TextureFormat.DXT5a:
            case TextureFormat.DXT5b:
                bytesPerTexLine = 16;
                break;

            default:
                throw new Exception("Unexpected format during volume texture plane fetching: " + Format + ".");
            }

            // skip to correct group
            inputStream.DiscardBytes(group * bytecount * 4u);

            // copy texture
            MemoryStream s = new MemoryStream((int)bytecount);

            for (uint i = 0; i < bytecount; i += bytesPerTexLine)
            {
                inputStream.DiscardBytes(texInGroupBefore * bytesPerTexLine);
                StreamUtils.CopyStream(inputStream, s, bytesPerTexLine);
                inputStream.DiscardBytes(texInGroupAfter * bytesPerTexLine);
            }
            return(s);
        }
Esempio n. 3
0
        private bool LoadFile(byte[] File)
        {
            this.File    = File;
            FilePointers = new List <uint>();

            int FileCount = BitConverter.ToUInt16(File, 0);

            for (int i = 0; i < FileCount + 1; ++i)
            {
                uint ptr = NumberUtils.ToUInt24(File, i * 3 + 2);
                FilePointers.Add(ptr);
            }

            return(true);
        }
Esempio n. 4
0
        public Stream GetSinglePlane_MipBeforeDepth(Stream inputStream, uint depthlevel)
        {
            Stream s = new MemoryStream();
            uint   planesBeforeCurrent = depthlevel;
            uint   planesAfterCurrent  = Depth - depthlevel - 1;
            uint   sum = 0u;

            for (int i = 0; i < Mipmaps; ++i)
            {
                uint bytecount = GetByteCountSingleDepthPlane(i);
                sum += bytecount;
            }
            if (Format == TextureFormat.DXT1a || Format == TextureFormat.DXT1b || Format == TextureFormat.DXT5a || Format == TextureFormat.DXT5b)
            {
                // this feels stupid??
                sum = NumberUtils.Align(sum, 0x80u);
            }
            inputStream.DiscardBytes(planesBeforeCurrent * sum);
            StreamUtils.CopyStream(inputStream, s, sum);
            inputStream.DiscardBytes(planesAfterCurrent * sum);
            return(s);
        }
Esempio n. 5
0
        public void CreateFromDirectory(string Dir, string Outfile)
        {
            string[] Filepaths = System.IO.Directory.GetFiles(Dir);

            ushort Filecount = (ushort)Filepaths.Length;
            uint   RequiredBytesForHeader = NumberUtils.Align(Filecount * 4u + 4u, 0x50u);             // pretty sure this is not right but should work
            var    Filestream             = new System.IO.FileStream(Outfile, System.IO.FileMode.Create);

            // header
            Filestream.WriteByte((byte)'S'); Filestream.WriteByte((byte)'C');
            Filestream.WriteByte((byte)'M'); Filestream.WriteByte((byte)'P');
            uint TotalFilesize = RequiredBytesForHeader;

            foreach (string Path in Filepaths)
            {
                Filestream.Write(BitConverter.GetBytes(TotalFilesize), 0, 4);
                TotalFilesize += (uint)(new System.IO.FileInfo(Path).Length);
                TotalFilesize  = TotalFilesize.Align(0x10u);
            }
            while (Filestream.Length < RequiredBytesForHeader)
            {
                Filestream.WriteByte(0x00);
            }

            // files
            foreach (string Path in Filepaths)
            {
                var File = new System.IO.FileStream(Path, System.IO.FileMode.Open);
                StreamUtils.CopyStream(File, Filestream, (int)File.Length);
                File.Close();
                while (Filestream.Length % 0x10 != 0)
                {
                    Filestream.WriteByte(0x00);
                }
            }

            Filestream.Close();
        }
Esempio n. 6
0
        public void CreateFromDirectory(string Dir, string Outfile)
        {
            string[] Filepaths = System.IO.Directory.GetFiles(Dir);

            ushort Filecount = (ushort)Filepaths.Length;
            uint   RequiredBytesForHeader = NumberUtils.Align(Filecount * 3u + 5u, 0x10u);             // 3 bytes per filesize + 3 bytes for an extra pointer to first file + 2 bytes for filecount
            var    Filestream             = new System.IO.FileStream(Outfile, System.IO.FileMode.Create);

            // header
            Filestream.Write(BitConverter.GetBytes(Filecount), 0, 2);
            Filestream.Write(NumberUtils.GetBytesForUInt24(RequiredBytesForHeader), 0, 3);
            uint TotalFilesize = RequiredBytesForHeader;

            foreach (string Path in Filepaths)
            {
                TotalFilesize += (uint)(new System.IO.FileInfo(Path).Length);
                Filestream.Write(NumberUtils.GetBytesForUInt24(TotalFilesize), 0, 3);
                TotalFilesize = TotalFilesize.Align(0x10u);
            }
            while (Filestream.Length < RequiredBytesForHeader)
            {
                Filestream.WriteByte(0x00);
            }

            // files
            foreach (string Path in Filepaths)
            {
                var File = new System.IO.FileStream(Path, System.IO.FileMode.Open);
                StreamUtils.CopyStream(File, Filestream, (int)File.Length);
                File.Close();
                while (Filestream.Length % 0x10 != 0)
                {
                    Filestream.WriteByte(0x00);
                }
            }

            Filestream.Close();
        }
Esempio n. 7
0
        public void CreateFromDirectory(string Dir, string Outfile, string[] FileOrder)
        {
            List <string> Filepaths = new List <string>();

            foreach (string f in FileOrder)
            {
                Filepaths.Add(System.IO.Path.Combine(Dir, f));
            }
            var Filestream = new System.IO.FileStream(Outfile, System.IO.FileMode.Create);


            uint RequiredBytesForHeader;
            uint Filecount = (uint)Filepaths.Count;
            uint TotalFilesize;

            Xorbyte = 0x55;
            //Xorbyte = 0x00;

            // 0x20 Header + 0x28 per file
            RequiredBytesForHeader = NumberUtils.Align(Filecount * 0x28u + 0x20u, 0x20u);

            TotalFilesize = RequiredBytesForHeader;
            foreach (string Path in Filepaths)
            {
                TotalFilesize += (uint)(new System.IO.FileInfo(Path).Length);
                TotalFilesize  = TotalFilesize.Align(0x20u);
            }

            // header
            Filestream.WriteByte((byte)'R'); Filestream.WriteByte((byte)'T');
            Filestream.WriteByte((byte)'D'); Filestream.WriteByte((byte)'P');
            Filestream.Write(BitConverter.GetBytes(RequiredBytesForHeader), 0, 4);
            Filestream.Write(BitConverter.GetBytes(Filecount), 0, 4);
            Filestream.Write(BitConverter.GetBytes(TotalFilesize), 0, 4);
            Filestream.WriteByte(Xorbyte);
            Filestream.WriteByte(0x28); Filestream.WriteByte(0x25);
            while (Filestream.Length < 0x20)
            {
                Filestream.WriteByte(0x00);
            }

            // header file info
            uint ptr = 0;

            foreach (string Path in Filepaths)
            {
                var  fi   = new System.IO.FileInfo(Path);
                uint size = (uint)(fi.Length);

                byte[] name = Encoding.ASCII.GetBytes(fi.Name);
                Filestream.Write(name, 0, Math.Min(0x20, name.Length));
                for (int i = name.Length; i < 0x20; ++i)
                {
                    Filestream.WriteByte(0x00);
                }

                Filestream.Write(BitConverter.GetBytes(size), 0, 4);
                Filestream.Write(BitConverter.GetBytes(ptr), 0, 4);

                ptr = NumberUtils.Align(ptr + size, 0x20u);
            }
            while (Filestream.Length < RequiredBytesForHeader)
            {
                Filestream.WriteByte(0x00);
            }

            // files
            foreach (string Path in Filepaths)
            {
                var File = new System.IO.FileStream(Path, System.IO.FileMode.Open);

                while (true)
                {
                    int b = File.ReadByte();
                    if (b == -1)
                    {
                        break;
                    }
                    Filestream.WriteByte((byte)(b ^ Xorbyte));
                }

                File.Close();
                while (Filestream.Length % 0x20 != 0)
                {
                    Filestream.WriteByte(0x00);
                }
            }

            Filestream.Close();
        }