public Farc(byte[] data) { using var binaryFile = new BinaryFile(data); IReadOnlyBinaryDataAccessor accessor = binaryFile; Magic = accessor.ReadInt32(0); UnknownHeaderData = accessor.ReadArray(4, 0x1C); FarcVersion = accessor.ReadInt32(0x20); if (FarcVersion != 5) { throw new NotSupportedException("Only FARC version 5 is supported"); } var fatOffset = accessor.ReadInt32(0x24); var fatLength = accessor.ReadInt32(0x28); var dataOffset = accessor.ReadInt32(0x2C); var dataLength = accessor.ReadInt32(0x30); var fat = new FarcFat(data, fatOffset, fatLength); var files = new Dictionary <uint, byte[]>(); foreach (var file in fat.Entries) { files.Add(file.Hash, accessor.ReadArray(dataOffset + file.DataOffset, file.DataLength)); } Files = files; }
public override (int, int)? Read(IReadOnlyBinaryDataAccessor data, long position, byte[] dest, int offset, int count) { if (byteCount <= 0) { return(null); } var toWrite = Math.Min(count, byteCount); var toRead = Math.Max(toWrite / 2, byteCount % 2); var bytes = data.ReadArray(position, toRead); for (int i = 0; i < toWrite; i++) { if ((byteCount + i) % 2 == 0) { dest[offset + i] = separator; } else { dest[offset + i] = bytes[i / 2]; } } byteCount -= toWrite; return(toRead, toWrite); }
private void OpenInternalNormal(IReadOnlyBinaryDataAccessor f) { BgrsName = f.ReadNullTerminatedString(0x58, Encoding.ASCII); // Max length: &H40 BgrsDevName = f.ReadNullTerminatedString(0x58 + 0x40, Encoding.ASCII); // Max length: &H80 // Yes, the counts of these two sections are in a different order than the sections themselves var animationCount = f.ReadInt32(0x118); var partCount = f.ReadInt32(0x11C); for (var partIndex = 0x140; partIndex <= 0x140 + (0x80 * partCount) - 1; partIndex += 0x80) { var partName = f.ReadNullTerminatedString(partIndex + 0x18, System.Text.Encoding.ASCII); Parts.Add(new ModelPart(f.ReadArray(partIndex, 0x80), partName)); } UnknownModelPartsFooter = f.ReadArray(0x140 + (0x80 * partCount), 0x18); OpenInternalAnimations(f, 0x140 + (0x80 * partCount) + 0x18, animationCount); }
public PokemonGraphicsDatabaseEntry(IReadOnlyBinaryDataAccessor entryAccessor, IReadOnlyBinaryDataAccessor rawDataAccessor) { BgrsFilenamePointer = entryAccessor.ReadInt32(0); SecondaryBgrsFilenamePointer = entryAccessor.ReadInt32(4); PortraitNamePointer = entryAccessor.ReadInt32(8); BgrsFilename = rawDataAccessor.ReadNullTerminatedUnicodeString(BgrsFilenamePointer); SecondaryBgrsFilename = rawDataAccessor.ReadNullTerminatedUnicodeString(SecondaryBgrsFilenamePointer); PortraitName = rawDataAccessor.ReadNullTerminatedUnicodeString(PortraitNamePointer); UnknownData = entryAccessor.ReadArray(0xC, entrySize - 0xC); }
public static IBinaryDataAccessor Compress(IReadOnlyBinaryDataAccessor input) { var output = new MemoryStream((int)input.Length / 2); var inputData = input.ReadArray(); void writeArray(byte[] array) { output.Write(array, 0, array.Length); }; writeArray(Encoding.ASCII.GetBytes("GYU0")); writeArray(BitConverter.GetBytes(inputData.Length)); long dataOffset = 0; var compressionResult = new CompressionResult(); while (dataOffset < inputData.LongLength) { // Try each of the compression algorithms without copying data first. // If we get a result, write that to the output right away. // Otherwise, try copying the least amount of data followed by one of the algorithms. TryCompress(inputData, dataOffset, output, ref compressionResult); if (!compressionResult.Valid) { var copyOffset = dataOffset; var copyCommandOffset = output.Position; output.Position++; while (!compressionResult.Valid && copyOffset - dataOffset < 31 && copyOffset < inputData.LongLength) { output.WriteByte(inputData[copyOffset]); copyOffset++; TryCompress(inputData, copyOffset, output, ref compressionResult); } var currPos = output.Position; output.Position = copyCommandOffset; output.WriteByte((byte)(0x80 + copyOffset - dataOffset - 1)); output.Position = currPos; dataOffset = copyOffset; } if (compressionResult.Valid) { dataOffset += compressionResult.InputByteCount; } } // Write EOF marker output.WriteByte(0x7F); output.WriteByte(0xFF); // Trim any excess bytes that may have been written by the TryCompress* methods output.SetLength(output.Position); return(new BinaryFile(output.ToArray())); }
public FloorInfoEntry(IReadOnlyBinaryDataAccessor data) { Index = data.ReadInt16(0x00); Short02 = data.ReadInt16(0x02); Event = data.ReadString(0x04, 32, Encoding.ASCII).Trim('\0'); Short24 = data.ReadInt16(0x24); Short26 = data.ReadInt16(0x26); Short28 = data.ReadInt16(0x28); Short2A = data.ReadInt16(0x2A); Byte2C = data.ReadByte(0x2C); Byte2D = data.ReadByte(0x2D); Byte2E = data.ReadByte(0x2E); Byte2F = data.ReadByte(0x2F); Short30 = data.ReadInt16(0x30); Short32 = data.ReadInt16(0x32); Byte34 = data.ReadByte(0x34); Byte35 = data.ReadByte(0x35); Byte36 = data.ReadByte(0x36); InvitationIndex = data.ReadByte(0x54); Bytes37to53 = data.ReadArray(0x37, 0x53 - 0x37 + 1); Bytes55to61 = data.ReadArray(0x55, 0x61 - 0x55 + 1); }
public override (int, int)? Read(IReadOnlyBinaryDataAccessor data, long position, byte[] dest, int offset, int count) { if (byteCount <= 0) { return(null); } var bytes = data.ReadArray(position, Math.Min(count, byteCount)); bytes.CopyTo(dest, offset); byteCount -= bytes.Length; return(bytes.Length, bytes.Length); }