예제 #1
0
        public SPC(byte[] bytes, string spcName)
        {
            BinaryReader reader = new BinaryReader(new MemoryStream(bytes), Encoding.UTF8);

            string spcMagic = new string(reader.ReadChars(4));

            if (spcMagic == "$CMP")
            {
                throw new NotImplementedException("Error parsing SPC file: SRD-compressed SPC files are not yet supported.");
            }
            else if (spcMagic != "CPS.")
            {
                throw new InvalidDataException("Error parsing SPC file: Invalid magic number.");
            }

            Unk1 = reader.ReadBytes(0x24);
            uint fileCount = reader.ReadUInt32();

            Unk2 = reader.ReadUInt32();
            reader.BaseStream.Seek(0x10, SeekOrigin.Current);

            string tableMagic = new string(reader.ReadChars(4));

            if (tableMagic != "Root")
            {
                throw new InvalidDataException("Error parsing SPC file: Invalid file table identifier.");
            }
            reader.BaseStream.Seek(0x0C, SeekOrigin.Current);

            Entries = new Dictionary <string, SPCEntry>();
            for (int i = 0; i < fileCount; i++)
            {
                SPCEntry entry = new SPCEntry();

                entry.CmpFlag = reader.ReadUInt16();
                entry.UnkFlag = reader.ReadUInt16();
                int cmpSize = reader.ReadInt32();
                int decSize = reader.ReadInt32();
                int nameLen = reader.ReadInt32();
                reader.BaseStream.Seek(0x10, SeekOrigin.Current);

                int namePadding = (0x10 - (nameLen + 1) % 0x10) % 0x10;
                int dataPadding = (0x10 - cmpSize % 0x10) % 0x10;
                entry.Filename = new string(reader.ReadChars(nameLen));
                reader.BaseStream.Seek(namePadding + 1, SeekOrigin.Current);

                byte[] data = reader.ReadBytes(cmpSize);
                if (entry.CmpFlag == 2) // Decompress data if needed
                {
                    data = DecompressEntry(data);
                }
                entry.Contents = data;
                reader.BaseStream.Seek(dataPadding, SeekOrigin.Current);

                Entries[entry.Filename] = entry;
            }
        }
예제 #2
0
        public override byte[] ToBytesDefault()
        {
            List <byte> result = new List <byte>();

            result.AddRange(Encoding.UTF8.GetBytes("CPS."));
            result.AddRange(Unk1);
            result.AddRange(BitConverter.GetBytes(Entries.Count));
            result.AddRange(BitConverter.GetBytes(Unk2));
            for (int i = 0; i < 0x10; i++)
            {
                result.Add(0x00);
            }
            result.AddRange(Encoding.UTF8.GetBytes("Root"));
            for (int i = 0; i < 0x0C; i++)
            {
                result.Add(0x00);
            }

            foreach (KeyValuePair <string, SPCEntry> pair in Entries)
            {
                SPCEntry entry = pair.Value;

                result.AddRange(BitConverter.GetBytes(entry.CmpFlag));
                result.AddRange(BitConverter.GetBytes(entry.UnkFlag));
                result.AddRange(BitConverter.GetBytes(entry.CmpSize));
                result.AddRange(BitConverter.GetBytes(entry.DecSize));
                result.AddRange(BitConverter.GetBytes(entry.Filename.Length));
                for (int i = 0; i < 0x10; i++)
                {
                    result.Add(0x00);
                }

                uint namePadding = (uint)((0x10 - (entry.Filename.Length + 1) % 0x10) % 0x10);
                uint dataPadding = (uint)((0x10 - entry.CmpSize % 0x10) % 0x10);

                result.AddRange(Encoding.UTF8.GetBytes(entry.Filename));
                for (int i = 0; i < namePadding + 1; i++)
                {
                    result.Add(0x00);
                }

                result.AddRange(entry.Contents);
                for (int i = 0; i < dataPadding; i++)
                {
                    result.Add(0x00);
                }
            }

            return(result.ToArray());
        }
예제 #3
0
        protected V3Format(SPCEntry entry)
        {
            this.entry = entry;

            if (entry.CmpFlag == 0x02) // Decompress data if needed
            {
                byte[] result = SPC.DecompressEntry(entry.Contents);
                if (result.Length != entry.DecSize)
                {
                    throw new Exception($"Size mismatch: Size was {result.Length} but should be {entry.DecSize}");
                }
                entry.Contents = result;
                entry.CmpFlag  = 0x01;
                entry.CmpSize  = entry.Contents.Length;
            }
        }
예제 #4
0
 public WRD(SPCEntry entry, string spcName, string wrdName) : base(entry)
 {
     this.spcName = spcName;
     this.wrdName = wrdName;
 }
예제 #5
0
 public STX(SPCEntry entry) : base(entry)
 {
 }