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; } }
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()); }
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; } }
public WRD(SPCEntry entry, string spcName, string wrdName) : base(entry) { this.spcName = spcName; this.wrdName = wrdName; }
public STX(SPCEntry entry) : base(entry) { }