// Methods public override void Read(ExtendedBinaryReader reader) { // PACx Header string sig = reader.ReadSignature(4); if (sig != PACxSignature) { throw new InvalidSignatureException(PACxSignature, sig); } // Version String string verString = reader.ReadSignature(3); if (!ushort.TryParse(verString, out Version)) { throw new InvalidSignatureException(PACxSignature + Version, sig + verString); } reader.IsBigEndian = IsBigEndian = (reader.ReadChar() == BigEndianFlag); ID = reader.ReadUInt32(); FileSize = reader.ReadUInt32(); RootOffset = reader.ReadUInt32(); RootCompressedLength = reader.ReadUInt32(); RootLength = reader.ReadUInt32(); var flags = reader.ReadInt16(); HasDependencies = (flags & 0x2) != 0; HasCompressedBlocks = (flags & 0x1) != 0; ushort uk1 = reader.ReadUInt16(); if (!HasCompressedBlocks && uk1 != UnknownConstant) { Console.WriteLine($"WARNING: Unknown1 != 0x108! ({uk1})"); } else if (HasCompressedBlocks && uk1 != UnknownConstant1) { Console.WriteLine($"WARNING: Unknown1 != 0x208! ({uk1})"); } if ((flags & 0x80) != 0) { DependencyEntriesLength = reader.ReadUInt32(); CompressedChunksLength = reader.ReadUInt32(); StringTableLength = reader.ReadUInt32(); FinalTableLength = reader.ReadUInt32(); Length = LengthWithFlags; } else { Length = LengthWithoutFlags; } reader.Offset = Length; }
public void Load(ExtendedBinaryReader reader) { TextureFullPath = reader.ReadSignature(0x200).Trim('\0'); TextureFileName = reader.ReadSignature(0x080).Trim('\0'); TextureWidth = reader.ReadInt32(); TextureHeight = reader.ReadInt32(); reader.JumpAhead(0x84); // Unknown }
// Methods public override void Read(ExtendedBinaryReader reader) { // BINA Header string sig = reader.ReadSignature(4); if (sig != Signature) { throw new InvalidSignatureException(Signature, sig); } // Version String string verString = reader.ReadSignature(3); if (!ushort.TryParse(verString, out Version)) { Console.WriteLine( "WARNING: BINA header version was invalid! ({0})", verString); } reader.IsBigEndian = IsBigEndian = (reader.ReadChar() == BigEndianFlag); FileSize = reader.ReadUInt32(); ushort nodeCount = reader.ReadUInt16(); ushort unknown1 = reader.ReadUInt16(); // Always 0? Padding?? // TODO: Read Nodes Properly if (nodeCount < 1) { return; } // DATA Header string dataSig = reader.ReadSignature(); if (dataSig != DataSignature) { throw new InvalidSignatureException(DataSignature, dataSig); } DataLength = reader.ReadUInt32(); StringTableOffset = reader.ReadUInt32(); StringTableLength = reader.ReadUInt32(); FinalTableLength = reader.ReadUInt32(); // Additional data ushort additionalDataLength = reader.ReadUInt16(); ushort unknown3 = reader.ReadUInt16(); // Padding? reader.JumpAhead(additionalDataLength); reader.Offset = (uint)reader.BaseStream.Position; }
public override void Load(ExtendedBinaryReader reader, bool keepOpen = false) { // Check if file has a signature string sig = reader.ReadSignature(); if (sig == "STSC") { // Newer script format uint headerSize = reader.ReadUInt32(); Version = reader.ReadUInt32(); switch (Version) { case 4: // Date A Live: Twin Edition Rio Reincarnation (PSV) ScriptID = reader.ReadUInt16(); break; case 7: // Date A Live: Rio Reincarnation (PC) ScriptName = reader.ReadNullTerminatedString(); reader.JumpAhead((uint)(0x20 - (ScriptName.Length + 1))); reader.JumpAhead(12); ScriptID = reader.ReadUInt32(); break; } } else { // Older script format // Jump back as older scripts have much smaller headers reader.JumpBehind(4); ScriptID = reader.ReadUInt16(); } // Stupid workaround to find the end of the code segment reader.Offset = (uint)reader.BaseStream.Length; while (true) { byte opcode = reader.ReadByte(); if (opcode >= 0x94) { throw new STSCDisassembleException(this, $"Got opcode 0x{opcode:X2} at 0x{reader.BaseStream.Position - 1:X8} in \"{ScriptName}\"" + " There is no opcodes larger than 0x93!"); } // Check if its a known instruction if (STSCInstructions.DALRRInstructions[opcode] == null) { throw new STSCDisassembleException(this, $"Got opcode 0x{opcode:X2} at 0x{reader.BaseStream.Position - 1:X8} in \"{ScriptName}\"" + " This opcode is unknown!"); } var instruction = STSCInstructions.DALRRInstructions[opcode].Read(reader); Instructions.Add(instruction); if (reader.BaseStream.Position >= reader.Offset) { break; } } }
// Methods public override void Load(Stream fileStream) { // Header var reader = new ExtendedBinaryReader(fileStream, Encoding.ASCII, false); string sig = reader.ReadSignature(); if (sig != Signature) { throw new InvalidSignatureException(Signature, sig); } // Textures uint totalFrameCount = reader.ReadUInt32(); byte textureCount = reader.ReadByte(); for (int i = 0; i < textureCount; ++i) { Textures.Add(new Texture() { FilePath = reader.ReadString(), Unknown1 = reader.ReadByte() }); } // Animations ushort animCount = reader.ReadUInt16(); for (int i2 = 0; i2 < animCount; ++i2) { var anim = new Animation() { Name = reader.ReadString() }; ushort frameCount = reader.ReadUInt16(); anim.Unknown1 = reader.ReadInt16(); anim.Unknown2 = reader.ReadInt16(); // Animation Frames for (int i3 = 0; i3 < frameCount; ++i3) { anim.Frames.Add(new Frame() { TextureIndex = reader.ReadByte(), Unknown1 = reader.ReadInt16(), Unknown2 = reader.ReadInt16(), X = reader.ReadUInt16(), Y = reader.ReadUInt16(), Width = reader.ReadUInt16(), Height = reader.ReadUInt16(), OriginX = reader.ReadInt16(), OriginY = reader.ReadInt16() }); } Animations.Add(anim); } }
// Methods public override void Read(ExtendedBinaryReader reader) { // PACx Header string sig = reader.ReadSignature(4); if (sig != PACxSignature) { throw new InvalidSignatureException(PACxSignature, sig); } // Version String string verString = reader.ReadSignature(3); if (!ushort.TryParse(verString, out Version)) { Console.WriteLine( "WARNING: PACx header version was invalid! ({0})", verString); } reader.IsBigEndian = IsBigEndian = (reader.ReadChar() == BigEndianFlag); ID = reader.ReadUInt32(); FileSize = reader.ReadUInt32(); NodeTreeLength = reader.ReadUInt32(); SplitListLength = reader.ReadUInt32(); FileEntriesLength = reader.ReadUInt32(); StringTableLength = reader.ReadUInt32(); DataLength = reader.ReadUInt32(); FinalTableLength = reader.ReadUInt32(); PacType = (PACTypes)reader.ReadUInt16(); ushort uk1 = reader.ReadUInt16(); if (uk1 != UnknownConstant) { Console.WriteLine($"WARNING: Unknown1 != 0x108! ({uk1})"); } SplitCount = reader.ReadUInt32(); reader.Offset = Length; }
// TODO protected void LoadShadowArchive(ExtendedBinaryReader reader) { reader.JumpAhead(0x4); // Unknown, Seems to always be 0 uint fileSize = reader.ReadUInt32(); // File Size - 0xC uint magic = reader.ReadUInt32(); // Magic string ONEVersion = reader.ReadNullTerminatedString(); // Gets the version String reader.FixPadding(); // Aligns the reader uint fileCount = reader.ReadUInt32(); // File Count reader.JumpAhead(0x38 * 2 + 0x20); // Jump to the third/first entry bool isVersion6 = ONEVersion == "ONE Ver 0.60"; // Checks if its version is 0.60 int fileNameLength = isVersion6 ? 0x2C : 0x20; // The max file name size // Read File List var files = new FileEntry[FileEntryCount]; for (int i = 0; i < fileCount; i++) { var entry = new FileEntry(); entry.FileName = reader.ReadSignature( fileNameLength).Replace("\0", string.Empty); entry.UncompressedSize = reader.ReadUInt32(); entry.DataOffset = reader.ReadUInt32(); reader.JumpAhead(4); // Unknown, Seems to always be 1 if (!isVersion6) { reader.JumpAhead(0xC); // Unknown, Seems to always be 0 } files[i] = entry; } // Read File Data if (files.Length > 0) { reader.JumpTo(files[0].DataOffset + 0xC); for (int i = 0; i < fileCount; ++i) { // Compute the file's data length files[i].DataLength = ((i == fileCount - 1) ? fileSize + 0xC : files[i + 1].DataOffset) - files[i].DataOffset; var file = new ArchiveFile() { Name = files[i].FileName, Data = reader.ReadBytes( (int)files[i].DataLength) // TODO: Decompress file }; Data.Add(file); } } }
public override void Load(Stream fileStream) { var reader = new ExtendedBinaryReader(fileStream, false); reader.JumpAhead(4); // CRC32? int fileCount = reader.ReadInt32(); var fileEntries = new List <FileEntry>(); for (int i = 0; i < fileCount; ++i) { var fileEntry = new FileEntry(); fileEntry.FileName = reader.ReadSignature(0x40).Replace("\0", ""); fileEntry.DataUncompressedSize = reader.ReadUInt32(); fileEntry.DataSize = reader.ReadUInt32(); fileEntry.DataOffset = reader.ReadUInt32(); fileEntry.Compressed = reader.ReadByte() == 1; reader.JumpAhead(3); // Other Attributes? fileEntries.Add(fileEntry); } foreach (var fileEntry in fileEntries) { reader.JumpTo(fileEntry.DataOffset); byte[] data = null; if (fileEntry.Compressed) { data = ReadAndDecompress(reader); } else { data = reader.ReadBytes((int)fileEntry.DataUncompressedSize); } // Adds the File Data.Add(new ArchiveFile() { Name = fileEntry.FileName, Data = data }); } }
public override void Load(Stream fileStream) { var reader = new ExtendedBinaryReader(fileStream, true); string sig = reader.ReadSignature(); if (sig != "SCSE") { throw new InvalidSignatureException("SCSE", sig); } int entryCount = reader.ReadInt32(); for (int i = 0; i < entryCount; ++i) { var entry = new Entry(); entry.OrcFileName = reader.ReadString(); entry.FriendlyName = reader.ReadString(); Entries.Add(entry); } }
public static void LoadConfig(Stream stream) { var reader = new ExtendedBinaryReader(stream, true); string sig = reader.ReadSignature(); if (sig != "SCSE") { throw new InvalidSignatureException("SCSE", sig); } if (reader.ReadUInt16() != ConfigVersion) { // Old Config stream.Close(); File.Delete(((FileStream)stream).Name); return; } DolphinExecutablePath = ReadEntry(reader); GameRootPath = ReadEntry(reader); }
public void Load(ExtendedBinaryReader reader) { LayerName = reader.ReadSignature(0x20); uint unknown20 = reader.ReadUInt32(); TextureID = reader.ReadInt32(); uint Offset = reader.ReadUInt32(); uint unknown2C = reader.ReadUInt32(); // uint oldpos = (uint)reader.GetPosition(); reader.JumpTo(Offset); reader.JumpAhead(0x164); LayerOffX = reader.ReadSingle(); LayerOffY = reader.ReadSingle(); reader.JumpAhead(4); LayerWidth = reader.ReadSingle(); LayerHeight = reader.ReadSingle(); reader.JumpAhead(0x88); // Unknown /* * Top Left * Top Right * Bottom Left * Bottom Right */ for (int i = 0; i < 4; ++i) { Verts.Add(new MAVert(reader)); } reader.JumpTo(oldpos); reader.JumpAhead(0x84); // Unknown }
// Methods public override void Read(ExtendedBinaryReader reader) { // We need to know whether the file is big or little endian first var pos = reader.BaseStream.Position; reader.BaseStream.Position += 0x14; reader.IsBigEndian = false; // Version String/Endian Flag uint binaFlags = reader.ReadUInt32(); string verString = "xyz"; // Just 3 chars that would fail ushort.TryParse unsafe { // Endian Flag reader.IsBigEndian = IsBigEndian = ((char)( (binaFlags & 0xFF000000) >> 24) == BigEndianFlag); // Quick way to grab the last 3 bytes from binaFlags (which // are chars) and stuff them into a string we can then // safely parse into a ushort via ushort.TryParse fixed(char *vp = verString) { *vp = (char)((binaFlags & 0xFF0000) >> 16); vp[1] = (char)((binaFlags & 0xFF00) >> 16); vp[2] = (char)(binaFlags & 0xFF); } } if (!ushort.TryParse(verString, out Version)) { Console.WriteLine( "WARNING: BINA header version was invalid! ({0})", verString); } // Alright, cool, *NOW* we can read the rest of the header reader.BaseStream.Position = pos; // Header FileSize = reader.ReadUInt32(); FinalTableOffset = reader.ReadUInt32(); FinalTableLength = reader.ReadUInt32(); uint unknown1 = reader.ReadUInt32(); if (unknown1 != 0) { Console.WriteLine($"WARNING: Unknown1 is not zero! ({unknown1})"); } ushort unknownFlag1 = reader.ReadUInt16(); if (unknownFlag1 != 0) { Console.WriteLine($"WARNING: UnknownFlag1 is not zero! ({unknownFlag1})"); } IsFooterMagicPresent = (reader.ReadUInt16() == 1); // FooterNodeCount? reader.JumpAhead(4); // BINA Signature string sig = reader.ReadSignature(4); if (sig != Signature) { throw new InvalidSignatureException(Signature, sig); } // TODO: Find out what this is. Maybe additional data length? uint unknown2 = reader.ReadUInt32(); if (unknown2 != 0) { Console.WriteLine($"WARNING: Unknown2 is not zero! ({unknown2})"); } reader.Offset = (uint)reader.BaseStream.Position; }
// Methods public override void Load(Stream fileStream) { // Signature var reader = new ExtendedBinaryReader( fileStream, Encoding.ASCII, false); string sig = reader.ReadSignature(4); if (sig != Signature) { throw new InvalidSignatureException(Signature, sig); } // Header Header = new DDSHeader() { Size = reader.ReadUInt32(), Flags = reader.ReadUInt32() }; if (!Header.HasFlag(DDSHeader.FLAGS.CAPS) || !Header.HasFlag(DDSHeader.FLAGS.WIDTH) || !Header.HasFlag(DDSHeader.FLAGS.HEIGHT) || !Header.HasFlag(DDSHeader.FLAGS.PIXEL_FORMAT)) { throw new Exception( "Could not load DDS file. Required header flags are missing!"); } Height = reader.ReadUInt32(); Width = reader.ReadUInt32(); Header.PitchOrLinearSize = reader.ReadUInt32(); Header.Depth = reader.ReadUInt32(); Header.MipmapCount = reader.ReadUInt32(); reader.JumpAhead(44); // Skip past padding Header.PixelFormat = new DDSPixelFormat(reader); Header.Caps = reader.ReadUInt32(); Header.Caps2 = reader.ReadUInt32(); Header.Caps3 = reader.ReadUInt32(); Header.Caps4 = reader.ReadUInt32(); reader.JumpTo(Header.Size + 4, true); // Depth uint depth = 1; if (Header.HasFlag(DDSHeader.FLAGS.DEPTH) && Header.HasFlag(DDSHeader.CAPS2.VOLUME)) { depth = Header.Depth; // TODO throw new NotImplementedException( "Reading 3D textures from DDS files is not yet supported."); } else if (Header.HasFlag(DDSHeader.CAPS2.CUBEMAP)) { depth = 6; // TODO throw new NotImplementedException( "Reading DDS cubemaps is not yet supported."); } // MipMaps uint mipmapCount = 1; if (Header.HasFlag(DDSHeader.FLAGS.MIPMAP_COUNT) && Header.HasFlag(DDSHeader.CAPS.MIPMAP)) { mipmapCount = Header.MipmapCount; } MipmapCount = mipmapCount; // Caps if (!Header.HasFlag(DDSHeader.CAPS.TEXTURE)) { throw new Exception( "Could not load DDS file. Required CAPS flag is missing!"); } // TODO // Caps2 // TODO // DX10 Header/Pixel Format uint pixelsPerBlock = 16; byte blockSize; if (Header.PixelFormat.HasFlag(DDSPixelFormat.FLAGS.FOURCC)) { switch ((DDSPixelFormat.FOURCCS)Header.PixelFormat.FourCC) { // DX10 Header case DDSPixelFormat.FOURCCS.DX10: { var dx10Header = new DX10Header(reader); depth = dx10Header.ArraySize; switch ((DX10Header.DXGI_FORMATS)dx10Header.DXGIFormat) { // BC1 case DX10Header.DXGI_FORMATS.BC1_TYPELESS: case DX10Header.DXGI_FORMATS.BC1_UNORM: CompressionFormat = CompressionFormats.RGB_S3TC_DXT1_EXT; blockSize = 8; break; // BC3 case DX10Header.DXGI_FORMATS.BC3_TYPELESS: case DX10Header.DXGI_FORMATS.BC3_UNORM: CompressionFormat = CompressionFormats.RGBA_S3TC_DXT3_EXT; blockSize = 16; break; // BC5 case DX10Header.DXGI_FORMATS.BC5_TYPELESS: case DX10Header.DXGI_FORMATS.BC5_SNORM: case DX10Header.DXGI_FORMATS.BC5_UNORM: CompressionFormat = CompressionFormats.RGBA_S3TC_DXT5_EXT; blockSize = 16; break; // BC7 case DX10Header.DXGI_FORMATS.BC7_TYPELESS: case DX10Header.DXGI_FORMATS.BC7_UNORM: CompressionFormat = CompressionFormats.RGBA_BPTC_UNORM_EXT; blockSize = 16; break; case DX10Header.DXGI_FORMATS.BC7_UNORM_SRGB: CompressionFormat = CompressionFormats.SRGB_ALPHA_BPTC_UNORM_EXT; blockSize = 16; break; // TODO: Add support for BC1 SRGB, BC2, BC3 SRGB, BC4, and BC6 default: throw new NotImplementedException(string.Format( "Reading DX10 DXGI type \"{0}\" is not yet supported.", dx10Header.DXGIFormat)); } break; } // DXT1 case DDSPixelFormat.FOURCCS.DXT1: CompressionFormat = CompressionFormats.RGB_S3TC_DXT1_EXT; blockSize = 8; break; // DXT3 case DDSPixelFormat.FOURCCS.DXT3: CompressionFormat = CompressionFormats.RGBA_S3TC_DXT3_EXT; blockSize = 16; break; // DXT5 case DDSPixelFormat.FOURCCS.DXT5: case DDSPixelFormat.FOURCCS.ATI2: case DDSPixelFormat.FOURCCS.BC5S: CompressionFormat = CompressionFormats.RGBA_S3TC_DXT5_EXT; blockSize = 16; break; // TODO: Add support for DXT2 and DXT4 default: throw new NotImplementedException(string.Format("{0} \"{1}\" {2}", "Reading DDS files with FOURCC", Header.PixelFormat.FourCC, "is not yet supported.")); } } else { if (!Header.PixelFormat.HasFlag(DDSPixelFormat.FLAGS.RGB)) { throw new NotImplementedException( "Reading DDS files without RGB data is not yet supported."); } if (Header.PixelFormat.RGBBitCount % 8 != 0) { throw new InvalidDataException( "RGBBitCount must be divisible by 8."); } if (Header.PixelFormat.RGBBitCount > 32) { throw new InvalidDataException( "RGBBitCount must be less than or equal to 32."); } if (Header.PixelFormat.RGBBitCount != 32) { throw new NotImplementedException( "Reading DDS files with non 32-bit data is not yet supported."); } pixelsPerBlock = 1; CompressionFormat = CompressionFormats.None; blockSize = (byte)(Header.PixelFormat.RGBBitCount / 8); PixelFormat = PixelFormats.RGBA; } // Whether or not uncompressed pixels need to be re-arranged to RGBA bool isARGB = (CompressionFormat == CompressionFormats.None && Header.PixelFormat.RGBBitCount == 32 && Header.PixelFormat.ABitMask == 0xFF000000 && Header.PixelFormat.RBitMask == 0xFF0000 && Header.PixelFormat.GBitMask == 0xFF00 && Header.PixelFormat.BBitMask == 0xFF); // Data uint width = Width, height = Height; ColorData = new byte[mipmapCount * depth][]; for (uint slice = 0; slice < depth; ++slice) { for (uint level = 0; level < mipmapCount; ++level) { // Pad out width/height to 4x4 blocks if (CompressionFormat != CompressionFormats.None) { if (width % 4 != 0) { width = ((width / 4) + 1) * 4; } if (height % 4 != 0) { height = ((height / 4) + 1) * 4; } } // Compute size of this block uint size = ((width * height) / pixelsPerBlock) * blockSize; // Re-arrange uncompressed pixels to RGBA8 format if necessary if (isARGB) { uint p; ColorData[level] = new byte[size]; for (uint i = 0; i < size; i += 4) { // Convert from ARGB8 to RGBA8 p = reader.ReadUInt32(); ColorData[level][i] = (byte)((p & Header.PixelFormat.RBitMask) >> 16); ColorData[level][i + 1] = (byte)((p & Header.PixelFormat.GBitMask) >> 8); ColorData[level][i + 2] = (byte)(p & Header.PixelFormat.BBitMask); ColorData[level][i + 3] = (byte)((p & Header.PixelFormat.ABitMask) >> 24); } } // Otherwise, simply read the block else { ColorData[level] = reader.ReadBytes((int)size); } // Divide width/height by 2 for the next mipmap width /= 2; height /= 2; } } }
public static byte[] DecompressLZ77(this byte[] compressed) { byte[] buffer = null; using (var reader = new ExtendedBinaryReader(new MemoryStream(compressed))) { int position = 0; long flagPosition = 0; if (reader.ReadSignature() == "LZ77") { int uncompressedSize = reader.ReadInt32(); int lz77Step = reader.ReadInt32(); int offset = reader.ReadInt32(); flagPosition = reader.GetPosition(); reader.JumpTo(offset); buffer = new byte[uncompressedSize]; } int flagCount = 0; int flag = 0; while (true) { if (flagCount == 0) { if (flagPosition >= compressed.Length) { break; } if (flagPosition == reader.GetPosition()) { reader.JumpAhead(1); } flag = compressed[flagPosition++]; flagCount = 8; } if ((flag & 0x80) != 0) { if (reader.GetPosition() + 2 > compressed.Length) { break; } int backStep = reader.ReadByte(); int amount = reader.ReadByte(); for (amount += 3; (amount--) != 0; position++) { if (position >= buffer.Length) { break; } buffer[position] = buffer[position - backStep]; } } else { if (position >= buffer.Length) { break; } buffer[position++] = reader.ReadByte(); } flag <<= 1; flagCount--; } } return(buffer); }