/// <summary> /// Reads TPF data from a BinaryReaderEx. /// </summary> internal override void Read(BinaryReaderEx br) { br.BigEndian = false; br.AssertASCII("TPF\0"); br.BigEndian = br.GetByte(0xC) == 2; int totalFileSize = br.ReadInt32(); int fileCount = br.ReadInt32(); Platform = br.ReadEnum8 <TPFPlatform>(); Flag2 = br.AssertByte(1, 2, 3); Encoding = br.AssertByte(0, 1, 2); br.AssertByte(0); Textures = new List <Texture>(); for (int i = 0; i < fileCount; i++) { Textures.Add(new Texture(br, Platform, Encoding)); } }
private BXF3(BinaryReaderEx bhdReader, BinaryReaderEx bdtReader) { BHD3 bhd = new BHD3(bhdReader); BHDTimestamp = bhd.Timestamp; Format = bhd.Format; bdtReader.AssertASCII("BDF3"); BDTTimestamp = bdtReader.ReadASCII(8).TrimEnd('\0'); bdtReader.AssertInt32(0); Files = new List <File>(); for (int i = 0; i < bhd.FileHeaders.Count; i++) { BHD3.FileHeader fileHeader = bhd.FileHeaders[i]; byte[] data = bdtReader.GetBytes(fileHeader.Offset, fileHeader.Size); Files.Add(new File(fileHeader.ID, fileHeader.Name, data)); } }
/// <summary> /// Reads TPF data from a BinaryReaderEx. /// </summary> protected override void Read(BinaryReaderEx br) { br.BigEndian = false; br.AssertASCII("TPF\0"); Platform = br.GetEnum8 <TPFPlatform>(0xC); br.BigEndian = Platform == TPFPlatform.Xbox360 || Platform == TPFPlatform.PS3; br.ReadInt32(); // Data length int fileCount = br.ReadInt32(); br.Skip(1); // Platform Flag2 = br.AssertByte(0, 1, 2, 3); Encoding = br.AssertByte(0, 1, 2); br.AssertByte(0); Textures = new List <Texture>(fileCount); for (int i = 0; i < fileCount; i++) { Textures.Add(new Texture(br, Platform, Flag2, Encoding)); } }
/// <summary> /// Deserializes file data from a stream. /// </summary> protected override void Read(BinaryReaderEx br) { br.AssertASCII("CLM2"); br.AssertInt32(0); br.AssertInt16(1); br.AssertInt16(1); br.AssertInt32(0); br.AssertInt32(0); int meshCount = br.ReadInt32(); br.AssertInt32(0x28); br.AssertInt32(0); br.AssertInt32(0); br.AssertInt32(0x28); Meshes = new List <Mesh>(meshCount); for (int i = 0; i < meshCount; i++) { Meshes.Add(new Mesh(br)); } }
internal override void Read(BinaryReaderEx br) { br.BigEndian = false; br.AssertASCII("ENFL"); // Probably 4 bytes br.AssertInt32(0x10415); int compressedSize = br.ReadInt32(); int uncompressedSize = br.ReadInt32(); byte[] data = Util.ReadZlib(br, compressedSize); br = new BinaryReaderEx(false, data); br.AssertInt32(0); int unkCount1 = br.ReadInt32(); int unkCount2 = br.ReadInt32(); br.AssertInt32(0); Struct1s = new List <Struct1>(); for (int i = 0; i < unkCount1; i++) { Struct1s.Add(new Struct1(br)); } br.Pad(0x10); Struct2s = new List <Struct2>(); for (int i = 0; i < unkCount2; i++) { Struct2s.Add(new Struct2(br)); } br.Pad(0x10); br.AssertInt16(0); Strings = new List <string>(); for (int i = 0; i < unkCount2; i++) { Strings.Add(br.ReadUTF16()); } }
internal override void Read(BinaryReaderEx br) { br.BigEndian = false; br.AssertASCII("ACB\0"); br.AssertInt32(0x00000102); int assetCount = br.ReadInt32(); br.ReadInt32(); // Offset index offset Assets = new List <Asset>(assetCount); foreach (int assetOffset in br.ReadInt32s(assetCount)) { br.Position = assetOffset; AssetType type = br.GetEnum16 <AssetType>(br.Position + 8); if (type == AssetType.General) { Assets.Add(new Asset.General(br)); } else if (type == AssetType.Model) { Assets.Add(new Asset.Model(br)); } else if (type == AssetType.Texture) { Assets.Add(new Asset.Texture(br)); } else if (type == AssetType.GITexture) { Assets.Add(new Asset.GITexture(br)); } else if (type == AssetType.Motion) { Assets.Add(new Asset.Motion(br)); } else { throw new NotImplementedException($"Unsupported asset type: {type}"); } } }
public BHD3(BinaryReaderEx br) { br.AssertASCII("BHF3"); Timestamp = br.ReadASCII(8).TrimEnd('\0'); Format = br.AssertByte(0x54, 0x74, 0xE0); br.AssertByte(0); br.AssertByte(0); br.AssertByte(0); br.BigEndian = Format == 0xE0; int fileCount = br.ReadInt32(); br.AssertInt32(0); br.AssertInt32(0); br.AssertInt32(0); FileHeaders = new List <FileHeader>(fileCount); for (int i = 0; i < fileCount; i++) { FileHeaders.Add(new FileHeader(br, Format)); } }
public BHD3(BinaryReaderEx br) { br.AssertASCII("BHF3"); Timestamp = br.ReadFixStr(8); Format = br.ReadEnum8 <Binder.Format>(); br.AssertByte(0); br.AssertByte(0); br.AssertByte(0); br.BigEndian = Binder.ForceBigEndian(Format); int fileCount = br.ReadInt32(); br.AssertInt32(0); br.AssertInt32(0); br.AssertInt32(0); FileHeaders = new List <FileHeader>(fileCount); for (int i = 0; i < fileCount; i++) { FileHeaders.Add(new FileHeader(br, Format)); } }
internal override void Read(BinaryReaderEx br) { br.BigEndian = false; br.AssertASCII("filt"); br.AssertInt32(2); br.AssertInt32(0); int groupCount = br.ReadInt32(); Unk1 = br.ReadInt32(); // Header size br.AssertInt32(0x40); Offsets offsets; offsets.GroupHeaders = br.ReadInt32(); offsets.ParamHeaderOffsets = br.ReadInt32(); offsets.ParamHeaders = br.ReadInt32(); offsets.Values = br.ReadInt32(); offsets.Unk1 = br.ReadInt32(); offsets.Unk2 = br.ReadInt32(); Unk2 = br.ReadInt32(); offsets.Unk3 = br.ReadInt32(); offsets.Unk4 = br.ReadInt32(); br.AssertInt32(0); Groups = new List <Group>(groupCount); for (int i = 0; i < groupCount; i++) { Groups.Add(new Group(br, offsets)); } UnkBlock1 = br.GetBytes(offsets.Unk1, offsets.Unk2 - offsets.Unk1); UnkBlock2 = br.GetBytes(offsets.Unk2, offsets.Unk3 - offsets.Unk2); UnkBlock3 = br.GetBytes(offsets.Unk3, offsets.Unk4 - offsets.Unk3); UnkBlock4 = br.GetBytes(offsets.Unk4, (int)br.Stream.Length - offsets.Unk4); }
/// <summary> /// Deserializes file data from a stream. /// </summary> protected override void Read(BinaryReaderEx br) { br.BigEndian = false; br.AssertASCII("NVMA"); Version = br.ReadEnum32 <NVAVersion>(); br.ReadUInt32(); // File size br.AssertInt32(Version == NVAVersion.OldBloodborne ? 8 : 9); // Section count Navmeshes = new NavmeshSection(br); Entries1 = new Section1(br); Entries2 = new Section2(br); new Section3(br); Connectors = new ConnectorSection(br); var connectorPoints = new ConnectorPointSection(br); var connectorConditions = new ConnectorConditionSection(br); Entries7 = new Section7(br); MapNodeSection mapNodes; if (Version == NVAVersion.OldBloodborne) { mapNodes = new MapNodeSection(1); } else { mapNodes = new MapNodeSection(br); } foreach (Navmesh navmesh in Navmeshes) { navmesh.TakeMapNodes(mapNodes); } foreach (Connector connector in Connectors) { connector.TakePointsAndConds(connectorPoints, connectorConditions); } }
/// <summary> /// Deserializes file data from a stream. /// </summary> protected override void Read(BinaryReaderEx br) { br.BigEndian = false; br.AssertASCII("LUAI"); BigEndian = br.AssertInt32(1, 0x1000000) == 0x1000000; br.BigEndian = BigEndian; int goalCount = br.ReadInt32(); br.AssertInt32(0); if (goalCount == 0) { throw new NotSupportedException("LUAINFO format cannot be detected on files with 0 goals."); } else if (goalCount >= 2) { LongFormat = br.GetInt32(0x24) == 0; } else if (br.GetInt32(0x18) == 0x10 + 0x18 * goalCount) { LongFormat = true; } else if (br.GetInt32(0x14) == 0x10 + 0x10 * goalCount) { LongFormat = false; } else { throw new NotSupportedException("Could not detect LUAINFO format."); } Goals = new List <Goal>(goalCount); for (int i = 0; i < goalCount; i++) { Goals.Add(new Goal(br, LongFormat)); } }
/// <summary> /// Reads BND0 data from a BinaryReaderEx. /// </summary> internal override void Read(BinaryReaderEx br) { br.BigEndian = false; br.AssertASCII("BND\0"); // File size in non-lite format Lite = br.GetInt32(0xC) == 0; int fileSize, fileCount; if (Lite) { fileSize = br.ReadInt32(); fileCount = br.ReadInt32(); br.AssertInt32(0); } else { br.AssertInt32(0xF7FF); br.AssertInt32(0xD3); fileSize = br.ReadInt32(); fileCount = br.ReadInt32(); br.AssertInt32(0); Flag1 = br.AssertByte(0, 0x20); Flag2 = br.AssertByte(0, 0x08); br.AssertByte(3); br.AssertByte(0); br.AssertInt32(0); br.AssertInt32(0); } Files = new List <File>(fileCount); for (int i = 0; i < fileCount; i++) { Files.Add(new File(br, Lite)); } }
protected override void Read(BinaryReaderEx br) { br.BigEndian = false; br.AssertASCII("DLsE"); br.AssertByte(1); br.AssertByte(3); br.AssertByte(0); br.AssertByte(0); br.AssertInt32(0); br.AssertInt32(0); br.AssertByte(0); br.AssertInt32(1); short classNameCount = br.ReadInt16(); var classNames = new List <string>(classNameCount); for (int i = 0; i < classNameCount; i++) { int length = br.ReadInt32(); classNames.Add(br.ReadASCII(length)); } Effect = new FXEffect(br, classNames); }
/// <summary> /// Reads BND3 data from a BinaryReaderEx. /// </summary> internal override void Read(BinaryReaderEx br) { br.BigEndian = false; br.AssertASCII("BND3"); Timestamp = br.ReadFixStr(8); Format = br.ReadEnum8 <Binder.Format>(); BigEndian = br.ReadBoolean(); Unk1 = br.ReadBoolean(); br.AssertByte(0); br.BigEndian = BigEndian || Binder.ForceBigEndian(Format); int fileCount = br.ReadInt32(); int fileHeadersEnd = br.ReadInt32(); Unk2 = br.ReadInt32(); br.AssertInt32(0); Files = new List <BinderFile>(fileCount); for (int i = 0; i < fileCount; i++) { Files.Add(ReadFile(br, Format)); } }
internal override void Read(BinaryReaderEx br) { br.BigEndian = false; br.AssertASCII("FXR\0"); br.AssertInt32(0x40000); br.AssertInt32(1); ID = br.ReadInt32(); int section1Offset = br.ReadInt32(); int section1Count = br.AssertInt32(1); int section2Offset = br.ReadInt32(); int section2Count = br.ReadInt32(); int section3Offset = br.ReadInt32(); int section3Count = br.ReadInt32(); int section4Offset = br.ReadInt32(); int section4Count = br.ReadInt32(); int section5Offset = br.ReadInt32(); int section5Count = br.ReadInt32(); int section6Offset = br.ReadInt32(); int section6Count = br.ReadInt32(); int section7Offset = br.ReadInt32(); int section7Count = br.ReadInt32(); int section8Offset = br.ReadInt32(); int section8Count = br.ReadInt32(); int section9Offset = br.ReadInt32(); int section9Count = br.ReadInt32(); int section10Offset = br.ReadInt32(); int section10Count = br.ReadInt32(); int section11Offset = br.ReadInt32(); int section11Count = br.ReadInt32(); br.AssertInt32(1); br.AssertInt32(0); br.Position = section1Offset; Section1Tree = new Section1(br); br.Position = section2Offset; var section2s = new Dictionary <int, Section2>(section2Count); for (int i = 0; i < section2Count; i++) { section2s[(int)br.Position] = new Section2(br); } br.Position = section3Offset; var section3s = new Dictionary <int, Section3>(section3Count); for (int i = 0; i < section3Count; i++) { section3s[(int)br.Position] = new Section3(br); } br.Position = section4Offset; var section4s = new Dictionary <int, Section4>(section4Count); for (int i = 0; i < section4Count; i++) { section4s[(int)br.Position] = new Section4(br); } br.Position = section5Offset; var section5s = new Dictionary <int, Section5>(section5Count); for (int i = 0; i < section5Count; i++) { section5s[(int)br.Position] = new Section5(br); } br.Position = section6Offset; var section6s = new Dictionary <int, Section6>(section6Count); for (int i = 0; i < section6Count; i++) { section6s[(int)br.Position] = new Section6(br); } br.Position = section7Offset; var section7s = new Dictionary <int, Section7>(section7Count); for (int i = 0; i < section7Count; i++) { section7s[(int)br.Position] = new Section7(br); } br.Position = section8Offset; var section8s = new Dictionary <int, Section8>(section8Count); for (int i = 0; i < section8Count; i++) { section8s[(int)br.Position] = new Section8(br); } br.Position = section9Offset; var section9s = new Dictionary <int, Section9>(section9Count); for (int i = 0; i < section9Count; i++) { section9s[(int)br.Position] = new Section9(br); } br.Position = section10Offset; var section10s = new Dictionary <int, Section10>(section10Count); for (int i = 0; i < section10Count; i++) { section10s[(int)br.Position] = new Section10(br); } br.Position = section11Offset; var section11s = new Dictionary <int, int>(section11Count); for (int i = 0; i < section11Count; i++) { section11s[(int)br.Position] = br.ReadInt32(); } var section2List = new List <Section2>(section2s.Values); var section3List = new List <Section3>(section3s.Values); var section4List = new List <Section4>(section4s.Values); var section5List = new List <Section5>(section5s.Values); var section6List = new List <Section6>(section6s.Values); var section7List = new List <Section7>(section7s.Values); var section8List = new List <Section8>(section8s.Values); var section9List = new List <Section9>(section9s.Values); var section10List = new List <Section10>(section10s.Values); Section1Tree.Take(section2s); foreach (Section2 section2 in section2List) { section2.Take(section3s); } foreach (Section3 section3 in section3List) { section3.Take(section11s); } foreach (Section4 section4 in section4List) { section4.Take(section4s, section5s, section6s); } foreach (Section5 section5 in section5List) { section5.Take(section6s); } foreach (Section6 section6 in section6List) { section6.Take(section7s, section10s, section11s); } foreach (Section7 section7 in section7List) { section7.Take(section8s, section11s); } foreach (Section8 section8 in section8List) { section8.Take(section9s, section11s); } foreach (Section9 section9 in section9List) { section9.Take(section11s); } foreach (Section10 section10 in section10List) { section10.Take(section11s); } if (section2s.Count != 0) { throw null; } if (section3s.Count != 0) { throw null; } if (section4s.Count != 1) { throw null; } if (section5s.Count != 0) { throw null; } if (section6s.Count != 0) { throw null; } if (section7s.Count != 0) { throw null; } if (section8s.Count != 0) { throw null; } if (section9s.Count != 0) { throw null; } if (section10s.Count != 0) { throw null; } if (section11s.Count != 0) { throw null; } Section4Tree = section4s.Values.First(); }
protected override void Read(BinaryReaderEx br) { br.AssertASCII("MQB "); br.BigEndian = BigEndian = br.AssertSByte(0, -1) == -1; br.AssertByte(0); sbyte longFormat = br.AssertSByte(0, -1); br.AssertByte(0); Version = br.ReadEnum32 <MQBVersion>(); int headerSize = br.ReadInt32(); if (Version != MQBVersion.DarkSouls2Scholar && longFormat == -1 || Version == MQBVersion.DarkSouls2Scholar && longFormat == 0) { throw new FormatException($"Unexpected long format {longFormat} for version {Version}."); } if (Version == MQBVersion.DarkSouls2 && headerSize != 0x14 || Version == MQBVersion.DarkSouls2Scholar && headerSize != 0x28 || Version == MQBVersion.Bloodborne && headerSize != 0x20 || Version == MQBVersion.DarkSouls3 && headerSize != 0x24) { throw new FormatException($"Unexpected header size {headerSize} for version {Version}."); } br.VarintLong = Version == MQBVersion.DarkSouls2Scholar; long resourcePathsOffset = br.ReadVarint(); if (Version == MQBVersion.DarkSouls2Scholar) { br.AssertInt32(0); br.AssertInt32(0); br.AssertInt32(0); br.AssertInt32(0); } else if (Version >= MQBVersion.Bloodborne) { br.AssertInt32(1); br.AssertInt32(0); br.AssertInt32(0); if (Version >= MQBVersion.DarkSouls3) { br.AssertInt32(0); } } Name = br.ReadFixStrW(0x40); Framerate = br.ReadSingle(); int resourceCount = br.ReadInt32(); int cutCount = br.ReadInt32(); br.AssertInt32(0); br.AssertInt32(0); br.AssertInt32(0); br.AssertInt32(0); br.AssertInt32(0); Resources = new List <Resource>(resourceCount); for (int i = 0; i < resourceCount; i++) { Resources.Add(new Resource(br, i)); } Cuts = new List <Cut>(cutCount); for (int i = 0; i < cutCount; i++) { Cuts.Add(new Cut(br, Version)); } br.Position = resourcePathsOffset; long[] resourcePathOffsets = br.ReadVarints(resourceCount); ResourceDirectory = br.ReadUTF16(); for (int i = 0; i < resourceCount; i++) { long offset = resourcePathOffsets[i]; if (offset != 0) { Resources[i].Path = br.GetUTF16(offset); } } }
internal override void Read(BinaryReaderEx br) { br.BigEndian = false; // Don't @ me. br.AssertASCII("f\0i\0l\0t\0"); br.AssertInt32(3); br.AssertInt32(0); int groupCount = br.ReadInt32(); Unk1 = br.ReadInt32(); // Header size br.AssertInt32(0x50); Offsets offsets; offsets.GroupHeaders = br.ReadInt32(); offsets.ParamHeaderOffsets = br.ReadInt32(); offsets.ParamHeaders = br.ReadInt32(); offsets.Values = br.ReadInt32(); offsets.Unk1 = br.ReadInt32(); offsets.Unk2 = br.ReadInt32(); Unk2 = br.ReadInt32(); offsets.Unk3 = br.ReadInt32(); offsets.Unk4 = br.ReadInt32(); br.AssertInt32(0); offsets.Unk5 = br.ReadInt32(); offsets.CommentOffsets = br.ReadInt32(); offsets.Comments = br.ReadInt32(); Groups = new List <Group>(); for (int i = 0; i < groupCount; i++) { Groups.Add(new Group(br, offsets)); } UnkBlock1 = br.GetBytes(offsets.Unk1, offsets.Unk2 - offsets.Unk1); UnkBlock2 = br.GetBytes(offsets.Unk2, offsets.Unk3 - offsets.Unk2); UnkBlock3 = br.GetBytes(offsets.Unk3, offsets.Unk4 - offsets.Unk3); UnkBlock4 = br.GetBytes(offsets.Unk4, offsets.Unk5 - offsets.Unk4); UnkBlock5 = br.GetBytes(offsets.Unk5, offsets.CommentOffsets - offsets.Unk5); CommentOffsetsBlock = br.GetBytes(offsets.CommentOffsets, offsets.Comments - offsets.CommentOffsets); CommentBlock = br.GetBytes(offsets.Comments, (int)br.Stream.Length - offsets.Comments); br.Position = offsets.Unk5; Comments = new List <string>(); if (offsets.CommentOffsets < br.Stream.Length) { while (br.Position < offsets.Comments) { int commentOffset = br.ReadInt32(); if (offsets.Comments + commentOffset < br.Stream.Length) { string comment = br.GetUTF16(offsets.Comments + commentOffset); if (comment != "") { Comments.Add(comment); } } } } }
internal override void Read(BinaryReaderEx br) { br.BigEndian = false; br.AssertInt32(0); int fileSize = br.ReadInt32(); br.AssertInt32(0); br.AssertInt32(3); AssertMarker(br, 0x01); br.AssertInt32(0); br.AssertInt32(0x1C); br.AssertInt32(1); br.AssertInt32(2); AssertMarker(br, 0xB0); br.AssertInt32(4); br.AssertASCII("MTD "); AssertMarker(br, 0x34); br.AssertInt32(0x3E8); AssertMarker(br, 0x01); br.AssertInt32(0); int dataSize = br.ReadInt32(); br.AssertInt32(2); br.AssertInt32(4); AssertMarker(br, 0xA3); ShaderPath = br.ReadShiftJISLengthPrefixed(0xA3); Description = br.ReadShiftJISLengthPrefixed(0x03); br.AssertInt32(1); br.AssertInt32(0); int paramSize = br.ReadInt32(); br.AssertInt32(3); br.AssertInt32(4); AssertMarker(br, 0xA3); br.AssertInt32(0); AssertMarker(br, 0x03); int paramCount = br.ReadInt32(); Params = new List <Param>(paramCount); for (int i = 0; i < paramCount; i++) { Params.Add(new Param(br)); } AssertMarker(br, 0x03); int textureCount = br.ReadInt32(); Textures = new List <Texture>(textureCount); for (int i = 0; i < textureCount; i++) { Textures.Add(new Texture(br)); } AssertMarker(br, 0x04); br.AssertInt32(0); AssertMarker(br, 0x04); br.AssertInt32(0); AssertMarker(br, 0x04); br.AssertInt32(0); }
internal override void Read(BinaryReaderEx br) { br.BigEndian = false; br.AssertASCII("MSB "); br.AssertInt32(1); // Header size/data start br.AssertInt32(0x10); // Probably bytes, just guessing br.AssertByte(0); br.AssertByte(0); br.AssertByte(1); br.AssertByte(0xFF); Entries entries = default; long nextSectionOffset = br.Position; while (nextSectionOffset != 0) { br.Position = nextSectionOffset; int unk1 = br.ReadInt32(); int offsets = br.ReadInt32() - 1; long typeOffset = br.ReadInt64(); string type = br.GetUTF16(typeOffset); switch (type) { case "MODEL_PARAM_ST": Models = new ModelSection(br, unk1); entries.Models = Models.Read(br, offsets); break; case "EVENT_PARAM_ST": Events = new EventSection(br, unk1); entries.Events = Events.Read(br, offsets); break; case "POINT_PARAM_ST": Regions = new PointSection(br, unk1); entries.Regions = Regions.Read(br, offsets); break; case "ROUTE_PARAM_ST": Routes = new RouteSection(br, unk1); entries.Routes = Routes.Read(br, offsets); break; case "LAYER_PARAM_ST": Layers = new LayerSection(br, unk1); entries.Layers = Layers.Read(br, offsets); break; case "PARTS_PARAM_ST": Parts = new PartsSection(br, unk1); entries.Parts = Parts.Read(br, offsets); break; case "MAPSTUDIO_PARTS_POSE_ST": PartsPoses = new PartsPoseSection(br, unk1, offsets); break; case "MAPSTUDIO_BONE_NAME_STRING": BoneNames = new BoneNameSection(br, unk1); entries.BoneNames = BoneNames.Read(br, offsets); break; default: throw new NotImplementedException($"Unimplemented section: {type}"); } nextSectionOffset = br.ReadInt64(); } DisambiguateNames(entries.Events); DisambiguateNames(entries.Models); DisambiguateNames(entries.Parts); DisambiguateNames(entries.Regions); Events.GetNames(this, entries); Parts.GetNames(this, entries); Regions.GetNames(this, entries); }
internal override void Read(BinaryReaderEx br) { br.AssertASCII("EVD\0"); uint versionA = br.AssertUInt32(0, 0xFF00, 0x1FF00); uint versionB = br.AssertUInt32(0xCC, 0xCD); if (versionA == 0 && versionB == 0xCC) { Game = GameType.DS1; } else if (versionA == 0xFF00 && versionB == 0xCC) { Game = GameType.BB; } else if (versionA == 0x1FF00 && versionB == 0xCD) { Game = GameType.DS3; } else { throw new InvalidDataException($"Invalid pair of version values in EMEVD header: 0x{versionA:X8}, 0x{versionB:X8}."); } if (Game == GameType.BB) { br.AssertInt64(br.Length); } else { br.AssertInt32((int)br.Length); } OffsetsContainer offsets; long eventsCount = ReadIntW(br, Game != GameType.DS1); offsets.EventsOffset = ReadIntW(br, Game != GameType.DS1); ReadIntW(br, Game != GameType.DS1); // Instruction count offsets.InstructionsOffset = ReadIntW(br, Game != GameType.DS1); AssertIntW(br, Game != GameType.DS1, 0); // Unknown count ReadIntW(br, Game != GameType.DS1); // Unknown offset ReadIntW(br, Game != GameType.DS1); // Event layer count offsets.EventLayersOffset = ReadIntW(br, Game != GameType.DS1); ReadIntW(br, Game != GameType.DS1); // Parameter count offsets.ParametersOffset = ReadIntW(br, Game != GameType.DS1); long linkedFilesCount = ReadIntW(br, Game != GameType.DS1); offsets.LinkedFilesOffset = ReadIntW(br, Game != GameType.DS1); ReadIntW(br, Game != GameType.DS1); // Args length offsets.ArgsBlockOffset = ReadIntW(br, Game != GameType.DS1); long stringsBlockSize = ReadIntW(br, Game != GameType.DS1); offsets.StringsBlockOffset = ReadIntW(br, Game != GameType.DS1); if (Game == GameType.DS1) { br.AssertInt32(0); } br.Position = offsets.EventsOffset; Events = new List <Event>((int)eventsCount); for (int i = 0; i < eventsCount; i++) { Events.Add(new Event(br, Game, offsets)); } br.Position = offsets.StringsBlockOffset; var stringOffsets = new List <long>(); while (br.Position < offsets.StringsBlockOffset + stringsBlockSize) { long strOffset = br.Position - offsets.StringsBlockOffset; stringOffsets.Add(strOffset); var str = br.ReadUTF16(); StringTable.Add(str); } br.Position = offsets.LinkedFilesOffset; for (int i = 0; i < linkedFilesCount; i++) { long strOffset = (Game != GameType.DS1) ? br.ReadInt64() : br.ReadInt32(); LinkedFileStringIndices.Add(stringOffsets.IndexOf(strOffset)); } }
internal override void Read(BinaryReaderEx br) { br.BigEndian = false; string magic = br.AssertASCII("fSSL", "fsSL"); LongFormat = magic == "fsSL"; br.VarintLong = LongFormat; br.AssertInt32(1); br.AssertInt32(1); br.AssertInt32(1); br.AssertInt32(0x7C); int dataSize = br.ReadInt32(); br.AssertInt32(11); br.AssertInt32(LongFormat ? 0x58 : 0x34); br.AssertInt32(1); br.AssertInt32(LongFormat ? 0x10 : 8); int stringCount = br.ReadInt32(); br.AssertInt32(4); br.AssertInt32(0); br.AssertInt32(8); int functionSpecCount = br.ReadInt32(); int conditionSize = br.AssertInt32(LongFormat ? 0x10 : 8); int conditionCount = br.ReadInt32(); br.AssertInt32(LongFormat ? 0x10 : 8); br.AssertInt32(0); br.AssertInt32(LongFormat ? 0x18 : 0x10); int commandSpecCount = br.ReadInt32(); int commandSize = br.AssertInt32(4); int commandCount = br.ReadInt32(); int passCommandSize = br.AssertInt32(LongFormat ? 0x10 : 8); int passCommandCount = br.ReadInt32(); int stateSize = br.AssertInt32(LongFormat ? 0x78 : 0x3C); int stateCount = br.ReadInt32(); br.AssertInt32(LongFormat ? 0x48 : 0x30); int machineCount = br.ReadInt32(); int stringsOffset = br.ReadInt32(); br.AssertInt32(0); br.AssertInt32(stringsOffset); Unk80 = br.ReadInt32(); br.AssertInt32(dataSize); br.AssertInt32(0); br.AssertInt32(dataSize); br.AssertInt32(0); long dataStart = br.Position; br.AssertVarint(0); long commandSpecOffset = br.ReadVarint(); br.AssertVarint(commandSpecCount); long functionSpecOffset = br.ReadVarint(); br.AssertVarint(functionSpecCount); long machineOffset = br.ReadVarint(); br.AssertInt32(machineCount); UnkB0 = br.ReadInt32s(4); if (LongFormat) { br.AssertInt32(0); } br.AssertVarint(LongFormat ? 0x58 : 0x34); br.AssertVarint(stringCount); List <string> strings = new List <string>(); for (int i = 0; i < stringCount; i++) { long stringOffset = br.ReadVarint(); // Char count not needed as all strings are null-terminated br.ReadVarint(); br.StepIn(dataStart + stringOffset); string str = br.ReadUTF16(); br.StepOut(); strings.Add(str); } FunctionSpecs = new List <FunctionSpec>(); for (int i = 0; i < functionSpecCount; i++) { FunctionSpecs.Add(new FunctionSpec(br, strings)); } Dictionary <long, ConditionDesc> conditions = new Dictionary <long, ConditionDesc>(); for (int i = 0; i < conditionCount; i++) { long offset = br.Position - dataStart; conditions[offset] = new ConditionDesc(br); } CommandSpecs = new List <CommandSpec>(); for (int i = 0; i < commandSpecCount; i++) { CommandSpecs.Add(new CommandSpec(br, strings)); } Dictionary <long, CommandDesc> commands = new Dictionary <long, CommandDesc>(); for (int i = 0; i < commandCount; i++) { long offset = br.Position - dataStart; commands[offset] = new CommandDesc(br, strings); } if (LongFormat) { // Data-start-aligned padding. long offset = br.Position - dataStart; if (offset % 8 > 0) { br.Skip(8 - (int)(offset % 8)); } } Dictionary <long, PassCommandDesc> passCommands = new Dictionary <long, PassCommandDesc>(); for (int i = 0; i < passCommandCount; i++) { long offset = br.Position - dataStart; passCommands[offset] = new PassCommandDesc(br, commands, commandSize); } Dictionary <long, StateDesc> states = new Dictionary <long, StateDesc>(); for (int i = 0; i < stateCount; i++) { long offset = br.Position - dataStart; states[offset] = new StateDesc(br, strings, dataStart, conditions, conditionSize, commands, commandSize, passCommands, passCommandSize); } Machines = new List <MachineDesc>(); for (int i = 0; i < machineCount; i++) { Machines.Add(new MachineDesc(br, strings, states, stateSize)); } if (conditions.Count > 0 || commands.Count > 0 || passCommands.Count > 0 || states.Count > 0) { throw new FormatException("Orphaned ESD descriptions found"); } }
protected override void Read(BinaryReaderEx br) { br.AssertASCII("EVD\0"); bool bigEndian = br.ReadBoolean(); bool is64Bit = br.AssertSByte(0, -1) == -1; bool unk06 = br.ReadBoolean(); bool unk07 = br.AssertSByte(0, -1) == -1; br.BigEndian = bigEndian; br.VarintLong = is64Bit; int version = br.AssertInt32(0xCC, 0xCD); br.ReadInt32(); // File size if (!bigEndian && !is64Bit && !unk06 && !unk07 && version == 0xCC) { Format = Game.DarkSouls1; } else if (bigEndian && !is64Bit && !unk06 && !unk07 && version == 0xCC) { Format = Game.DarkSouls1BE; } else if (!bigEndian && is64Bit && !unk06 && !unk07 && version == 0xCC) { Format = Game.Bloodborne; } else if (!bigEndian && is64Bit && unk06 && !unk07 && version == 0xCD) { Format = Game.DarkSouls3; } else if (!bigEndian && is64Bit && unk06 && unk07 && version == 0xCD) { Format = Game.Sekiro; } else { throw new NotSupportedException($"Unknown EMEVD format: BigEndian={bigEndian} Is64Bit={is64Bit} Unicode={unk06} Unk07={unk07} Version=0x{version:X}"); } Offsets offsets; long eventCount = br.ReadVarint(); offsets.Events = br.ReadVarint(); br.ReadVarint(); // Instruction count offsets.Instructions = br.ReadVarint(); br.AssertVarint(0); // Unknown struct count br.ReadVarint(); // Unknown struct offset br.ReadVarint(); // Layer count offsets.Layers = br.ReadVarint(); br.ReadVarint(); // Parameter count offsets.Parameters = br.ReadVarint(); long linkedFileCount = br.ReadVarint(); offsets.LinkedFiles = br.ReadVarint(); br.ReadVarint(); // Argument data length offsets.Arguments = br.ReadVarint(); long stringsLength = br.ReadVarint(); offsets.Strings = br.ReadVarint(); if (!is64Bit) { br.AssertInt32(0); } br.Position = offsets.Events; Events = new List <Event>((int)eventCount); for (int i = 0; i < eventCount; i++) { Events.Add(new Event(br, Format, offsets)); } br.Position = offsets.LinkedFiles; LinkedFileOffsets = new List <long>(br.ReadVarints((int)linkedFileCount)); br.Position = offsets.Strings; StringData = br.ReadBytes((int)stringsLength); }
/// <summary> /// Deserializes file data from a stream. /// </summary> protected override void Read(BinaryReaderEx br) { br.BigEndian = false; string magic = br.AssertASCII("fSSL", "fsSL"); LongFormat = magic == "fsSL"; br.AssertInt32(1); DarkSoulsCount = br.AssertInt32(1, 2, 3); br.AssertInt32(DarkSoulsCount); br.AssertInt32(0x54); int dataSize = br.ReadInt32(); br.AssertInt32(6); br.AssertInt32(LongFormat ? 0x48 : 0x2C); br.AssertInt32(1); int stateGroupSize = br.AssertInt32(LongFormat ? 0x20 : 0x10); int stateGroupCount = br.ReadInt32(); int stateSize = br.AssertInt32(LongFormat ? 0x48 : 0x24); int stateCount = br.ReadInt32(); br.AssertInt32(LongFormat ? 0x38 : 0x1C); int conditionCount = br.ReadInt32(); br.AssertInt32(LongFormat ? 0x18 : 0x10); int commandCallCount = br.ReadInt32(); br.AssertInt32(LongFormat ? 0x10 : 0x8); int commandArgCount = br.ReadInt32(); int conditionOffsetsOffset = br.ReadInt32(); int conditionOffsetsCount = br.ReadInt32(); int nameBlockOffset = br.ReadInt32(); int nameLength = br.ReadInt32(); int unkOffset1 = br.ReadInt32(); br.AssertInt32(0); int unkOffset2 = br.ReadInt32(); br.AssertInt32(0); long dataStart = br.Position; br.AssertInt32(1); Unk70 = br.ReadInt32(); Unk74 = br.ReadInt32(); Unk78 = br.ReadInt32(); Unk7C = br.ReadInt32(); if (LongFormat) { br.AssertInt32(0); } long stateGroupsOffset = ReadVarint(br, LongFormat); AssertVarint(br, LongFormat, stateGroupCount); long nameOffset = ReadVarint(br, LongFormat); AssertVarint(br, LongFormat, nameLength); long unkNull = DarkSoulsCount == 1 ? 0 : -1; AssertVarint(br, LongFormat, unkNull); AssertVarint(br, LongFormat, unkNull); if (nameLength > 0) { Name = br.GetUTF16(dataStart + nameOffset); } else { Name = null; } var stateGroupOffsets = new Dictionary <long, long[]>(stateGroupCount); for (int i = 0; i < stateGroupCount; i++) { long id = ReadVarint(br, LongFormat); long[] stateOffsets = ReadStateGroup(br, LongFormat, dataStart, stateSize); if (stateGroupOffsets.ContainsKey(id)) { throw new FormatException("Duplicate state group ID."); } stateGroupOffsets[id] = stateOffsets; } var states = new Dictionary <long, State>(stateCount); for (int i = 0; i < stateCount; i++) { states[br.Position - dataStart] = new State(br, LongFormat, dataStart); } var conditions = new Dictionary <long, Condition>(conditionCount); for (int i = 0; i < conditionCount; i++) { conditions[br.Position - dataStart] = new Condition(br, LongFormat, dataStart); } foreach (State state in states.Values) { state.GetConditions(conditions); } StateGroups = new Dictionary <long, Dictionary <long, State> >(stateGroupCount); var groupedStateOffsets = new Dictionary <long, Dictionary <long, long> >(); foreach (long stateGroupID in stateGroupOffsets.Keys) { long[] stateOffsets = stateGroupOffsets[stateGroupID]; Dictionary <long, State> stateGroup = TakeStates(stateSize, stateOffsets, states, out Dictionary <long, long> stateIDs); StateGroups[stateGroupID] = stateGroup; groupedStateOffsets[stateGroupID] = stateIDs; foreach (State state in stateGroup.Values) { foreach (Condition condition in state.Conditions) { condition.GetStateAndConditions(stateIDs, conditions); } } } if (states.Count > 0) { throw new FormatException("Orphaned states found."); } }
/// <summary> /// Reads FLVER data from a BinaryReaderEx. /// </summary> protected override void Read(BinaryReaderEx br) { if (Cache == null) { Cache = new FlverCache(); } br.BigEndian = false; Header = new FLVERHeader(); br.AssertASCII("FLVER\0"); Header.BigEndian = br.AssertASCII("L\0", "B\0") == "B\0"; br.BigEndian = Header.BigEndian; // Gundam Unicorn: 0x20005, 0x2000E // DS1: 2000C, 2000D // DS2 NT: 2000F, 20010 // DS2: 20010, 20009 (armor 9320) // SFS: 20010 // BB: 20013, 20014 // DS3: 20013, 20014 // SDT: 2001A, 20016 (test chr) Header.Version = br.AssertInt32(0x20005, 0x20009, 0x2000C, 0x2000D, 0x2000E, 0x2000F, 0x20010, 0x20013, 0x20014, 0x20016, 0x2001A); int dataOffset = br.ReadInt32(); br.ReadInt32(); // Data length int dummyCount = br.ReadInt32(); int materialCount = br.ReadInt32(); int boneCount = br.ReadInt32(); int meshCount = br.ReadInt32(); int vertexBufferCount = br.ReadInt32(); Header.BoundingBoxMin = br.ReadVector3(); Header.BoundingBoxMax = br.ReadVector3(); br.ReadInt32(); // Face count not including motion blur meshes or degenerate faces br.ReadInt32(); // Total face count int vertexIndicesSize = br.AssertByte(0, 16, 32); Header.Unicode = br.ReadBoolean(); Header.Unk4A = br.ReadBoolean(); br.AssertByte(0); Header.Unk4C = br.ReadInt32(); int faceSetCount = br.ReadInt32(); int bufferLayoutCount = br.ReadInt32(); int textureCount = br.ReadInt32(); Header.Unk5C = br.ReadByte(); Header.Unk5D = br.ReadByte(); br.AssertByte(0); br.AssertByte(0); br.AssertInt32(0); br.AssertInt32(0); Header.Unk68 = br.AssertInt32(0, 1, 2, 3, 4); br.AssertInt32(0); br.AssertInt32(0); br.AssertInt32(0); br.AssertInt32(0); br.AssertInt32(0); Dummies = new List <FLVER.Dummy>(dummyCount); for (int i = 0; i < dummyCount; i++) { Dummies.Add(new FLVER.Dummy(br, Header.Version)); } Materials = new List <Material>(materialCount); var gxListIndices = new Dictionary <int, int>(); GXLists = new List <GXList>(); for (int i = 0; i < materialCount; i++) { Materials.Add(new Material(br, Header, GXLists, gxListIndices)); } Bones = new List <FLVER.Bone>(boneCount); for (int i = 0; i < boneCount; i++) { Bones.Add(new FLVER.Bone(br, Header.Unicode)); } Meshes = new List <Mesh>(meshCount); for (int i = 0; i < meshCount; i++) { Meshes.Add(new Mesh(br, Header)); } var faceSets = new List <FaceSet>(faceSetCount); for (int i = 0; i < faceSetCount; i++) { faceSets.Add(new FaceSet(br, Header, Cache, vertexIndicesSize, dataOffset)); } var vertexBuffers = new List <VertexBuffer>(vertexBufferCount); for (int i = 0; i < vertexBufferCount; i++) { vertexBuffers.Add(new VertexBuffer(br)); } BufferLayouts = new List <BufferLayout>(bufferLayoutCount); for (int i = 0; i < bufferLayoutCount; i++) { BufferLayouts.Add(new BufferLayout(br)); } var textures = new List <Texture>(textureCount); for (int i = 0; i < textureCount; i++) { textures.Add(new Texture(br, Header)); } if (Header.Version >= 0x2001A) { SekiroUnk = new SekiroUnkStruct(br); } Dictionary <int, Texture> textureDict = SFUtil.Dictionize(textures); foreach (Material material in Materials) { material.TakeTextures(textureDict); } if (textureDict.Count != 0) { throw new NotSupportedException("Orphaned textures found."); } Dictionary <int, FaceSet> faceSetDict = SFUtil.Dictionize(faceSets); Dictionary <int, VertexBuffer> vertexBufferDict = SFUtil.Dictionize(vertexBuffers); foreach (Mesh mesh in Meshes) { mesh.TakeFaceSets(faceSetDict); mesh.TakeVertexBuffers(vertexBufferDict, BufferLayouts); mesh.ReadVertices(br, dataOffset, BufferLayouts, Header, Cache); } if (faceSetDict.Count != 0) { throw new NotSupportedException("Orphaned face sets found."); } if (vertexBufferDict.Count != 0) { throw new NotSupportedException("Orphaned vertex buffers found."); } }
/// <summary> /// Reads BND4 data from a BinaryReaderEx. /// </summary> internal override void Read(BinaryReaderEx br) { br.BigEndian = false; br.AssertASCII("BND4"); Flag1 = br.ReadBoolean(); Flag2 = br.ReadBoolean(); br.AssertByte(0); br.AssertByte(0); BigEndian = br.AssertInt32(0x00010000, 0x00000100) == 0x00000100; br.BigEndian = BigEndian; int fileCount = br.ReadInt32(); // Header size br.AssertInt64(0x40); Timestamp = br.ReadFixStr(8); // File header size long fileHeaderSize = br.AssertInt64(0x18, 0x1C, 0x24); long dataStart = br.ReadInt64(); Unicode = br.ReadBoolean(); if (fileHeaderSize == 0x18) { Format = br.AssertByte(0x0C); } else if (fileHeaderSize == 0x1C) { Format = br.AssertByte(0x70); } else if (fileHeaderSize == 0x24) { Format = br.AssertByte(0x26, 0x2A, 0x2E, 0x54, 0x74); } Extended = br.AssertByte(0, 1, 4, 0x80); br.AssertByte(0); br.AssertInt32(0); long hashGroupsOffset = 0; if (Extended == 4) { hashGroupsOffset = br.ReadInt64(); } else { br.AssertInt64(0); } Files = new List <File>(fileCount); for (int i = 0; i < fileCount; i++) { Files.Add(new File(br, Unicode, Format)); } if (Extended == 4) { br.Position = hashGroupsOffset; long pathHashesOffset = br.ReadInt64(); int hashGroupsCount = br.ReadInt32(); // Probably 4 bytes br.AssertInt32(0x00080810); var hashGroups = new List <HashGroup>(hashGroupsCount); for (int i = 0; i < hashGroupsCount; i++) { hashGroups.Add(new HashGroup(br)); } br.Position = pathHashesOffset; var pathHashes = new List <PathHash>(fileCount); for (int i = 0; i < fileCount; i++) { pathHashes.Add(new PathHash(br)); } } }
protected override void Read(BinaryReaderEx br) { br.BigEndian = false; br.AssertASCII("FXR\0"); br.AssertInt16(0); Version = br.ReadEnum16 <FXRVersion>(); br.AssertInt32(1); ID = br.ReadInt32(); int section1Offset = br.ReadInt32(); br.AssertInt32(1); // Section 1 count br.ReadInt32(); // Section 2 offset br.ReadInt32(); // Section 2 count br.ReadInt32(); // Section 3 offset br.ReadInt32(); // Section 3 count int section4Offset = br.ReadInt32(); br.ReadInt32(); // Section 4 count br.ReadInt32(); // Section 5 offset br.ReadInt32(); // Section 5 count br.ReadInt32(); // Section 6 offset br.ReadInt32(); // Section 6 count br.ReadInt32(); // Section 7 offset br.ReadInt32(); // Section 7 count br.ReadInt32(); // Section 8 offset br.ReadInt32(); // Section 8 count br.ReadInt32(); // Section 9 offset br.ReadInt32(); // Section 9 count br.ReadInt32(); // Section 10 offset br.ReadInt32(); // Section 10 count br.ReadInt32(); // Section 11 offset br.ReadInt32(); // Section 11 count br.AssertInt32(1); br.AssertInt32(0); if (Version == FXRVersion.Sekiro) { int section12Offset = br.ReadInt32(); int section12Count = br.ReadInt32(); int section13Offset = br.ReadInt32(); int section13Count = br.ReadInt32(); br.ReadInt32(); // Section 14 offset br.AssertInt32(0); // Section 14 count br.AssertInt32(0); br.AssertInt32(0); Section12s = new List <int>(br.GetInt32s(section12Offset, section12Count)); Section13s = new List <int>(br.GetInt32s(section13Offset, section13Count)); } else { Section12s = new List <int>(); Section13s = new List <int>(); } br.Position = section1Offset; Section1Tree = new Section1(br); br.Position = section4Offset; Section4Tree = new Section4(br); }
internal BHF4(BinaryReaderEx br) { br.AssertASCII("BHF4"); Flag1 = br.ReadBoolean(); Flag2 = br.ReadBoolean(); br.AssertByte(0); br.AssertByte(0); BigEndian = br.AssertInt32(0x00010000, 0x00000100) == 0x00000100; br.BigEndian = BigEndian; int fileCount = br.ReadInt32(); // File headers start br.AssertInt64(0x40); Timestamp = br.ReadASCII(8).TrimEnd('\0'); // File header size long fileHeaderSize = br.AssertInt64(0x18, 0x24, 0x28); // Would be data start in BND4 br.AssertInt64(0); Unicode = br.ReadBoolean(); if (fileHeaderSize == 0x18) { Format = br.AssertByte(0x0C, 0x30); } else if (fileHeaderSize == 0x24) { Format = br.AssertByte(0x2E, 0x74); } else if (fileHeaderSize == 0x28) { Format = br.AssertByte(0x3E); } Extended = br.AssertByte(0, 4); br.AssertByte(0); br.AssertInt32(0); long hashGroupsOffset = br.ReadInt64(); FileHeaders = new List <FileHeader>(fileCount); for (int i = 0; i < fileCount; i++) { FileHeaders.Add(new FileHeader(br, Unicode, Format)); } if (Extended == 4) { br.Position = hashGroupsOffset; long pathHashesOffset = br.ReadInt64(); int hashGroupsCount = br.ReadInt32(); // Probably 4 bytes br.AssertInt32(0x00080810); var hashGroups = new List <HashGroup>(hashGroupsCount); for (int i = 0; i < hashGroupsCount; i++) { hashGroups.Add(new HashGroup(br)); } br.Position = pathHashesOffset; var pathHashes = new List <PathHash>(fileCount); for (int i = 0; i < fileCount; i++) { pathHashes.Add(new PathHash(br)); } } }
internal override void Read(BinaryReaderEx br) { br.AssertASCII("FLVER\0"); string endian = br.ReadASCII(2); if (endian == "L\0") { BigEndian = false; } else if (endian == "B\0") { BigEndian = true; } else { throw new FormatException("FLVER endian character must be either L or B."); } br.BigEndian = BigEndian; int version = br.AssertInt32(0x0E, 0x0F, 0x10, 0x12, 0x13, 0x14, 0x15); int dataOffset = br.ReadInt32(); int dataSize = br.ReadInt32(); int dummyCount = br.ReadInt32(); int materialCount = br.ReadInt32(); int boneCount = br.ReadInt32(); int meshCount = br.ReadInt32(); br.AssertInt32(meshCount); BoundingBoxMin = br.ReadVector3(); BoundingBoxMax = br.ReadVector3(); Unk40 = br.ReadInt32(); int totalFaceCount = br.ReadInt32(); Unk48 = br.ReadInt32(); Unk4C = br.ReadInt32(); for (int i = 0; i < 12; i++) { br.AssertInt32(0); } Dummies = new List <Dummy>(dummyCount); for (int i = 0; i < dummyCount; i++) { Dummies.Add(new Dummy(br)); } Materials = new List <Material>(materialCount); for (int i = 0; i < materialCount; i++) { Materials.Add(new Material(br)); } Bones = new List <Bone>(boneCount); for (int i = 0; i < boneCount; i++) { Bones.Add(new Bone(br)); } Meshes = new List <Mesh>(meshCount); for (int i = 0; i < meshCount; i++) { Meshes.Add(new Mesh(br, Materials, dataOffset)); } }
private static byte[] DecompressDCXEDGE(BinaryReaderEx br) { br.AssertASCII("DCX\0"); br.AssertInt32(0x10000); br.AssertInt32(0x18); br.AssertInt32(0x24); br.AssertInt32(0x24); int unk1 = br.ReadInt32(); br.AssertASCII("DCS\0"); int uncompressedSize = br.ReadInt32(); int compressedSize = br.ReadInt32(); br.AssertASCII("DCP\0"); br.AssertASCII("EDGE"); br.AssertInt32(0x20); br.AssertInt32(0x9000000); br.AssertInt32(0x10000); br.AssertInt32(0x0); br.AssertInt32(0x0); br.AssertInt32(0x00100100); long dcaStart = br.Position; br.AssertASCII("DCA\0"); int dcaSize = br.ReadInt32(); // ??? br.AssertASCII("EgdT"); br.AssertInt32(0x00010100); br.AssertInt32(0x24); br.AssertInt32(0x10); br.AssertInt32(0x10000); // Uncompressed size of last block int trailingUncompressedSize = br.AssertInt32(uncompressedSize % 0x10000, 0x10000); int egdtSize = br.ReadInt32(); int chunkCount = br.ReadInt32(); br.AssertInt32(0x100000); if (unk1 != 0x50 + chunkCount * 0x10) { throw new InvalidDataException("Unexpected unk1 value in EDGE DCX."); } if (egdtSize != 0x24 + chunkCount * 0x10) { throw new InvalidDataException("Unexpected EgdT size in EDGE DCX."); } byte[] decompressed = new byte[uncompressedSize]; using (MemoryStream dcmpStream = new MemoryStream(decompressed)) { for (int i = 0; i < chunkCount; i++) { br.AssertInt32(0); int offset = br.ReadInt32(); int size = br.ReadInt32(); bool compressed = br.AssertInt32(0, 1) == 1; byte[] chunk = br.GetBytes(dcaStart + dcaSize + offset, size); if (compressed) { using (MemoryStream cmpStream = new MemoryStream(chunk)) using (DeflateStream dfltStream = new DeflateStream(cmpStream, CompressionMode.Decompress)) dfltStream.CopyTo(dcmpStream); } else { dcmpStream.Write(chunk, 0, chunk.Length); } } } return(decompressed); }
internal override void Read(BinaryReaderEx br) { br.BigEndian = false; // Don't @ me. if (br.AssertASCII("filt", "f\0i\0") == "f\0i\0") { br.AssertASCII("l\0t\0"); } Game = br.ReadEnum32 <GPGame>(); br.AssertByte(0); Unk0D = br.ReadBoolean(); br.AssertInt16(0); int groupCount = br.ReadInt32(); Unk14 = br.ReadInt32(); // Header size or group header headers offset, you decide br.AssertInt32(0x40, 0x50, 0x54); Offsets offsets = default; offsets.GroupHeaders = br.ReadInt32(); offsets.ParamHeaderOffsets = br.ReadInt32(); offsets.ParamHeaders = br.ReadInt32(); offsets.Values = br.ReadInt32(); offsets.ValueIDs = br.ReadInt32(); offsets.Unk2 = br.ReadInt32(); int unk3Count = br.ReadInt32(); offsets.Unk3 = br.ReadInt32(); offsets.Unk3ValueIDs = br.ReadInt32(); br.AssertInt32(0); if (Game == GPGame.DarkSouls3 || Game == GPGame.Sekiro) { offsets.CommentOffsetsOffsets = br.ReadInt32(); offsets.CommentOffsets = br.ReadInt32(); offsets.Comments = br.ReadInt32(); } if (Game == GPGame.Sekiro) { Unk50 = br.ReadSingle(); } Groups = new List <Group>(groupCount); for (int i = 0; i < groupCount; i++) { Groups.Add(new Group(br, Game, i, offsets)); } UnkBlock2 = br.GetBytes(offsets.Unk2, offsets.Unk3 - offsets.Unk2); br.Position = offsets.Unk3; Unk3s = new List <Unk3>(unk3Count); for (int i = 0; i < unk3Count; i++) { Unk3s.Add(new Unk3(br, Game, offsets)); } if (Game == GPGame.DarkSouls3 || Game == GPGame.Sekiro) { int[] commentOffsetsOffsets = br.GetInt32s(offsets.CommentOffsetsOffsets, groupCount); int commentOffsetsLength = offsets.Comments - offsets.CommentOffsets; for (int i = 0; i < groupCount; i++) { int commentCount; if (i == groupCount - 1) { commentCount = (commentOffsetsLength - commentOffsetsOffsets[i]) / 4; } else { commentCount = (commentOffsetsOffsets[i + 1] - commentOffsetsOffsets[i]) / 4; } br.Position = offsets.CommentOffsets + commentOffsetsOffsets[i]; for (int j = 0; j < commentCount; j++) { int commentOffset = br.ReadInt32(); string comment = br.GetUTF16(offsets.Comments + commentOffset); Groups[i].Comments.Add(comment); } } } }