예제 #1
0
        public void Update(Container container)
        {
            Dictionary <string, int> fileLookup = new Dictionary <string, int>();

            for (int i = 0; i < m_Files.Count; i++)
            {
                fileLookup.Add(m_Files[i].Name, i);
            }

            container.PackfileBaseOffset = (uint)CalculateDataStartOffset();
            container.TotalCompressedPackfileReadSize = (int)FileData.CompressedDataSize;
            foreach (Primitive primitive in container.Primitives)
            {
                if (!fileLookup.ContainsKey(primitive.Name))
                {
                    continue;
                }

                IPackfileEntry iEntry = m_Files[fileLookup[primitive.Name]];
                PackfileEntry  entry  = (PackfileEntry)iEntry;
                primitive.Data.CPUSize = entry.Data.Size;

                string gpuFile      = "";
                string extension    = Path.GetExtension(primitive.Name);
                string gpuExtension = "";
                switch (extension)
                {
                default:
                {
                    if (extension.StartsWith(".c"))
                    {
                        gpuExtension = ".g" + extension.Remove(0, 2);
                    }
                    break;
                }
                }
                gpuFile = Path.ChangeExtension(primitive.Name, gpuExtension);

                if (fileLookup.ContainsKey(gpuFile))
                {
                    IPackfileEntry iGpuEntry = m_Files[fileLookup[gpuFile]];
                    PackfileEntry  gpuEntry  = (PackfileEntry)iGpuEntry;
                    primitive.Data.GPUSize = (uint)gpuEntry.Size;
                }
            }

            for (int i = 0; i < container.PrimitiveSizes.Count; i++)
            {
                var sizes         = container.PrimitiveSizes[i];
                var primitiveData = container.Primitives[i];
                sizes.CPUSize = primitiveData.Data.CPUSize;
                sizes.GPUSize = primitiveData.Data.GPUSize;
                container.PrimitiveSizes[i] = sizes;
            }
        }
예제 #2
0
        public void RemoveFile(string filename)
        {
            PackfileEntry entry = null;

            foreach (PackfileEntry e in Files)
            {
                if (e.Name == filename)
                {
                    entry = e;
                    break;
                }
            }

            if (entry == null)
            {
                return;
            }

            RemoveFile(entry);
        }
예제 #3
0
        public void Save(Stream stream)
        {
            long dataStart = CalculateDataStartOffset();

            stream.Seek(dataStart, SeekOrigin.Begin);

            long fileStart = 0;

            long compressedSize   = 0;
            long uncompressedSize = 0;

            // Output file data
            ZlibStream dataStream = null;

            if (IsCompressed && IsCondensed)
            {
                dataStream           = new ZlibStream(stream, CompressionMode.Compress, CompressionLevel.BestCompression, true);
                dataStream.FlushMode = FlushType.Sync;
            }

            long compressedStart = 0;

            for (int i = 0; i < Files.Count; i++)
            {
                IPackfileEntry entry = Files[i];
                Stream         fs    = m_Streams[entry.Name];

                bool isLast = (i == (Files.Count - 1));

                PackfileEntry pfE  = (PackfileEntry)entry;
                var           data = pfE.Data;
                data.Start     = (uint)fileStart;
                data.Size      = (uint)fs.Length;
                data.Alignment = (IsCondensed) ? (ushort)16 : (ushort)1;

                if (this.IsCompressed)
                {
                    data.Flags = PackfileEntryFlags.Compressed;
                }

                if (IsCompressed && IsCondensed)
                {
                    fs.CopyTo(dataStream);
                    dataStream.Flush();
                    long afterData = dataStream.TotalOut;
                    data.CompressedSize = (uint)(afterData - compressedStart);
                    compressedStart     = afterData;

                    if (IsStr2)
                    {
                        fileStart        += data.Size.Align(16);
                        uncompressedSize += data.Size.Align(16);
                        compressedSize   += data.CompressedSize;
                    }
                    else
                    {
                        fileStart += data.Size; //.Align(16);
                        if (!isLast)
                        {
                            uncompressedSize += data.Size; //.Align(16);
                            //uint toSkip = data.Size.Align(16) - data.Size;
//                            for (int j = 0; j < toSkip; j++)
                            //dataStream.WriteByte(0);
                        }
                        else
                        {
                            uncompressedSize += data.Size;
                        }
                        compressedSize += data.CompressedSize;
                    }
                }
                else if (IsCondensed)
                {
                    fs.CopyTo(stream);
                    data.CompressedSize = 0xFFFFFFFF;

                    fileStart += data.Size.Align(16);

                    if (isLast)
                    {
                        uncompressedSize += data.Size;
                    }
                    else
                    {
                        uint toSkip = data.Size.Align(16) - data.Size;
                        uncompressedSize += data.Size.Align(16);
                        stream.Seek(toSkip, SeekOrigin.Current);
                    }
                }
                else if (IsCompressed)
                {
                    long beforeData = stream.Position;
                    using (dataStream = new ZlibStream(stream, CompressionMode.Compress, CompressionLevel.BestCompression, true))
                    {
                        dataStream.FlushMode = FlushType.Sync;
                        fs.CopyTo(dataStream);
                        dataStream.Flush();
                    }
                    long afterData = stream.Position;
                    data.CompressedSize = (uint)(afterData - beforeData);
                    fileStart          += data.CompressedSize;
                    uncompressedSize   += data.Size;
                    compressedSize     += data.CompressedSize;
                }
                else
                {
                    fs.CopyTo(stream);
                    data.CompressedSize = 0xFFFFFFFF;
                    fileStart          += data.Size;
                    uncompressedSize   += data.Size;
                }

                fs.Close();

                pfE.Data = data;
            }

            if (IsCompressed && IsCondensed)
            {
                dataStream.Close();
            }

            // Output file names
            stream.Seek(CalculateEntryNamesOffset(), SeekOrigin.Begin);
            long startOffset = CalculateEntryNamesOffset();

            foreach (IPackfileEntry entry in Files)
            {
                PackfileEntry pfE = (PackfileEntry)entry;
                stream.Align(2);
                pfE.Data.FilenameOffset = (UInt32)(stream.Position - startOffset);
                stream.WriteAsciiNullTerminatedString(entry.Name);
                stream.Seek(1, SeekOrigin.Current);
                stream.Align(2);
            }
            long nameSize = stream.Position - CalculateEntryNamesOffset();

            // Output file info
            stream.Seek(GetEntryDataOffset(), SeekOrigin.Begin);
            foreach (IPackfileEntry entry in Files)
            {
                PackfileEntry pfE = (PackfileEntry)entry;
                stream.WriteStruct(pfE.Data);
            }
            long dirSize = stream.Position - GetEntryDataOffset();

            // Output header
            stream.Seek(0, SeekOrigin.Begin);
            FileData.Descriptor     = 0x51890ACE;
            FileData.Version        = 0x0A;
            FileData.HeaderChecksum = 0;
            FileData.FileSize       = (uint)stream.Length;
            FileData.NumFiles       = (uint)Files.Count;
            FileData.DirSize        = (uint)dirSize;
            FileData.FilenameSize   = (uint)nameSize;
            FileData.DataSize       = (uint)uncompressedSize;
            if (IsCompressed)
            {
                FileData.CompressedDataSize = (uint)compressedSize;
            }
            else
            {
                FileData.CompressedDataSize = 0xFFFFFFFF;
            }
            stream.WriteStruct(FileData);

            uint checksum = 0;

            byte[] checksumBuffer = new byte[0x1C];

            stream.Seek(0x0C, SeekOrigin.Begin);
            stream.Read(checksumBuffer, 0, checksumBuffer.Length);
            checksum = Hashes.CrcVolition(checksumBuffer);

            stream.Seek(0x08, SeekOrigin.Begin);
            stream.WriteUInt32(checksum);

            stream.Flush();
        }