/// <summary> /// Deserializes file data from a stream. /// </summary> protected override void Read(BinaryReaderEx br) { br.BigEndian = false; br.AssertASCII("BND\0"); Unk04 = br.AssertInt32(0xC8, 0xCA); int fileSize = br.ReadInt32(); int fileCount = br.ReadInt32(); Files = new List <File>(fileCount); for (int i = 0; i < fileCount; i++) { int nextOffset = fileSize; if (i < fileCount - 1) { nextOffset = br.GetInt32(br.Position + 0xC + 4); } Files.Add(new File(br, nextOffset)); } }
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.ReadFixStr(8); long fileHeaderSize = br.ReadInt64(); // Would be data start in BND4 br.AssertInt64(0); Unicode = br.ReadBoolean(); Format = br.ReadEnum8 <Binder.Format>(); Extended = br.AssertByte(0, 4); br.AssertByte(0); if (fileHeaderSize != Binder.FileHeaderSize(Format)) { throw new FormatException($"File header size 0x{fileHeaderSize} unexpected for format {Format}"); } 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)); } }
/// <summary> /// Reads BND0 data from a BinaryReaderEx. /// </summary> protected 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.VarintLong = false; br.AssertASCII("TAE "); bool isBigEndian = br.AssertByte(0, 1) == 1; br.BigEndian = isBigEndian; br.AssertByte(0); br.AssertByte(0); bool is64Bit = br.AssertByte(0, 0xFF) == 0xFF; br.VarintLong = is64Bit; // 0x1000B: DeS, DS1(R) // 0x1000C: DS2, DS2 SOTFS, BB, DS3 // 0x1000D: SDT int version = br.AssertInt32(0x1000B, 0x1000C, 0x1000D); if (version == 0x1000B && !is64Bit) { Format = TAEFormat.DS1; } else if (version == 0x1000C && !is64Bit) { throw new NotImplementedException("Dark Souls II 32-Bit original release not supported. Only Scholar of the First Sin."); } else if (version == 0x1000C && is64Bit) { Format = TAEFormat.DS3; } else if (version == 0x1000D) { Format = TAEFormat.SDT; } else { throw new System.IO.InvalidDataException("Invalid combination of TAE header values: " + $"IsBigEndian={isBigEndian}, Is64Bit={is64Bit}, Version={version}"); } br.ReadInt32(); // File size br.AssertVarint(0x40); br.AssertVarint(1); br.AssertVarint(0x50); if (is64Bit) { br.AssertVarint(0x80); } else { br.AssertVarint(0x70); } if (Format == TAEFormat.DS1) { br.AssertInt16(2); br.AssertInt16(1); } else { EventBank = br.ReadVarint(); } br.AssertVarint(0); if (Format == TAEFormat.DS1) { br.AssertInt64(0); br.AssertInt64(0); br.AssertInt64(0); } Flags = br.ReadBytes(8); var unkFlagA = br.ReadBoolean(); var unkFlagB = br.ReadBoolean(); if (!unkFlagA && unkFlagB) { Format = TAEFormat.SOTFS; } else if ((unkFlagA && unkFlagB) || (!unkFlagA && !unkFlagB)) { throw new System.IO.InvalidDataException("Invalid unknown flags at 0x48."); } for (int i = 0; i < 6; i++) { br.AssertByte(0); } ID = br.ReadInt32(); int animCount = br.ReadInt32(); long animsOffset = br.ReadVarint(); br.ReadVarint(); // Anim groups offset br.AssertVarint(Format == TAEFormat.DS1 ? 0x90 : 0xA0); br.AssertVarint(animCount); br.ReadVarint(); // First anim offset if (Format == TAEFormat.DS1) { br.AssertInt32(0); } br.AssertVarint(1); br.AssertVarint(Format == TAEFormat.DS1 ? 0x80 : 0x90); if (Format == TAEFormat.DS1) { br.AssertInt64(0); } br.AssertInt32(ID); br.AssertInt32(ID); br.AssertVarint(0x50); br.AssertInt64(0); br.AssertVarint(Format == TAEFormat.DS1 ? 0x98 : 0xB0); long skeletonNameOffset = br.ReadVarint(); long sibNameOffset = br.ReadVarint(); if (Format != TAEFormat.SOTFS) { br.AssertVarint(0); br.AssertVarint(0); } if (Format != TAEFormat.SOTFS) { SkeletonName = br.GetUTF16(skeletonNameOffset); SibName = br.GetUTF16(sibNameOffset); } br.StepIn(animsOffset); { Animations = new List <Animation>(animCount); bool previousAnimNeedsParamGen = false; long previousAnimParamStart = 0; for (int i = 0; i < animCount; i++) { Animations.Add(new Animation(br, Format, out bool lastEventNeedsParamGen, out long animFileOffset, out long lastEventParamOffset)); if (previousAnimNeedsParamGen) { br.StepIn(previousAnimParamStart); Animations[i - 1].Events[Animations[i - 1].Events.Count - 1].ReadParameters(br, (int)(animFileOffset - previousAnimParamStart)); br.StepOut(); } previousAnimNeedsParamGen = lastEventNeedsParamGen; previousAnimParamStart = lastEventParamOffset; } // Read from very last anim's very last event's parameters offset to end of file lul if (previousAnimNeedsParamGen) { br.StepIn(previousAnimParamStart); Animations[Animations.Count - 1].Events[Animations[Animations.Count - 1].Events.Count - 1].ReadParameters(br, (int)(br.Length - previousAnimParamStart)); br.StepOut(); } } br.StepOut(); // Don't bother reading anim groups. }
public void ReadWithContext(BinaryReaderEx br, EzSembleContext context) { LastSavedHash = br.GetMD5HashOfStream(); string magic = br.AssertASCII("fSSL", "fsSL", "FSSL", "FsSL"); FormatType = ESDFormatByMagic[magic]; br.BigEndian = (FormatType == ESDFormatType.BigEndian32Bit || FormatType == ESDFormatType.BigEndian64Bit); context.IsBigEndian = br.BigEndian; 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; Unk6C = br.AssertInt32(1, 0); 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(context, br, LongFormat, dataStart); } var conditions = new Dictionary <long, Condition>(conditionCount); for (int i = 0; i < conditionCount; i++) { conditions[br.Position - dataStart] = new Condition(context, 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."); } foreach (var s in conditions) { s.Value.MetaRefID = s.Key; s.Value.Name = $"Condition[{s.Key:X8}]"; } foreach (var g in StateGroups.Keys) { foreach (var s in StateGroups[g]) { s.Value.Name = $"State{g}-{s.Value.ID}"; } } StateGroupNames.Clear(); foreach (var g in StateGroups) { StateGroupNames.Add(g.Key, $"StateGroup{g.Key}"); } }
protected override void Read(BinaryReaderEx br) { br.BigEndian = false; br.ReadInt32(); // File size br.AssertASCII("MDL "); br.AssertInt16(1); br.AssertInt16(1); Unk0C = br.ReadInt32(); Unk10 = br.ReadInt32(); Unk14 = br.ReadInt32(); int meshCount = br.ReadInt32(); int indexCount = br.ReadInt32(); int vertexCountA = br.ReadInt32(); int vertexCountB = br.ReadInt32(); int vertexCountC = br.ReadInt32(); int vertexCountD = br.ReadInt32(); int count7 = br.ReadInt32(); int materialCount = br.ReadInt32(); int textureCount = br.ReadInt32(); int meshesOffset = br.ReadInt32(); int indicesOffset = br.ReadInt32(); int verticesOffsetA = br.ReadInt32(); int verticesOffsetB = br.ReadInt32(); int verticesOffsetC = br.ReadInt32(); int verticesOffsetD = br.ReadInt32(); int offset7 = br.ReadInt32(); int materialsOffset = br.ReadInt32(); int texturesOffset = br.ReadInt32(); br.Position = meshesOffset; Meshes = new List <Bone>(); for (int i = 0; i < meshCount; i++) { Meshes.Add(new Bone(br)); } Indices = br.GetUInt16s(indicesOffset, indexCount); br.Position = verticesOffsetA; VerticesA = new List <Vertex>(vertexCountA); for (int i = 0; i < vertexCountA; i++) { VerticesA.Add(new Vertex(br, VertexFormat.A)); } br.Position = verticesOffsetB; VerticesB = new List <Vertex>(vertexCountB); for (int i = 0; i < vertexCountB; i++) { VerticesB.Add(new Vertex(br, VertexFormat.B)); } br.Position = verticesOffsetC; VerticesC = new List <Vertex>(vertexCountC); for (int i = 0; i < vertexCountC; i++) { VerticesC.Add(new Vertex(br, VertexFormat.C)); } br.Position = verticesOffsetD; VerticesD = new List <VertexD>(vertexCountD); for (int i = 0; i < vertexCountD; i++) { VerticesD.Add(new VertexD(br)); } br.Position = offset7; Struct7s = new List <Struct7>(count7); for (int i = 0; i < count7; i++) { Struct7s.Add(new Struct7(br)); } br.Position = materialsOffset; Materials = new List <Material>(materialCount); for (int i = 0; i < materialCount; i++) { Materials.Add(new Material(br)); } br.Position = texturesOffset; Textures = new List <string>(textureCount); for (int i = 0; i < textureCount; i++) { Textures.Add(br.ReadShiftJIS()); } }