internal override void Read(BinaryReaderEx br) { br.BigEndian = false; br.AssertASCII("EVD\0"); br.AssertByte(0); br.AssertByte(0xFF); br.AssertByte(1); br.AssertByte(0xFF); br.AssertInt32(0xCD); br.ReadInt32(); // File size Offsets offsets; long eventCount = br.ReadInt64(); offsets.Events = br.ReadInt64(); br.ReadInt64(); // Command count offsets.Commands = br.ReadInt64(); br.AssertInt64(0); br.ReadInt64(); // Unused offset br.ReadInt64(); // Event layer count offsets.EventLayers = br.ReadInt64(); br.ReadInt64(); // Parameter count offsets.Parameters = br.ReadInt64(); long linkedFileCount = br.ReadInt64(); offsets.LinkedFiles = br.ReadInt64(); br.ReadInt64(); // Arguments length offsets.Arguments = br.ReadInt64(); long stringLength = br.ReadInt64(); offsets.Strings = br.ReadInt64(); br.Position = offsets.Events; Events = new List <Event>((int)eventCount); for (int i = 0; i < eventCount; i++) { Events.Add(new Event(br, offsets)); } LinkedFileOffsets = new List <long>(br.GetInt64s(offsets.LinkedFiles, (int)linkedFileCount)); Strings = br.GetBytes(offsets.Strings, (int)stringLength); }
public override void Read(HKX hkx, HKXSection section, BinaryReaderEx br, HKXVariation variation) { SectionOffset = (uint)br.Position; AssertPointer(hkx, br); if (variation == HKXVariation.HKXBloodBorne) { br.AssertInt32(0); } else { AssertPointer(hkx, br); } AnimationType = br.ReadEnum32 <AnimationType>(); Duration = br.ReadSingle(); TransformTrackCount = br.ReadInt32(); FloatTrackCount = br.ReadInt32(); if (variation == HKXVariation.HKXBloodBorne) { br.Pad(16); } if (variation == HKXVariation.HKXDS1) { br.ReadInt64s(2); // Annotations } else { // Literally guessing here br.ReadInt64s(3); // Annotations //br.ReadUInt32(); // padding? } Transforms = new HKArray <Transform>(hkx, section, this, br, variation); Floats = new HKArray <HKFloat>(hkx, section, this, br, variation); DataSize = (uint)br.Position - SectionOffset; ResolveDestinations(hkx, section); }
internal 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 void AssertValue(BinaryReaderEx br) { switch (Type) { case ParamType.aob: var assertAob = (byte[])ValueToAssert; for (int i = 0; i < AobLength; i++) { br.AssertByte(assertAob[i]); } break; case ParamType.b: br.AssertBoolean((bool)ValueToAssert); break; case ParamType.u8: case ParamType.x8: br.AssertByte((byte)ValueToAssert); break; case ParamType.s8: br.AssertSByte((sbyte)ValueToAssert); break; case ParamType.u16: case ParamType.x16: br.AssertUInt16((ushort)ValueToAssert); break; case ParamType.s16: br.AssertInt16((short)ValueToAssert); break; case ParamType.u32: case ParamType.x32: br.AssertUInt32((uint)ValueToAssert); break; case ParamType.s32: br.AssertInt32((int)ValueToAssert); break; case ParamType.u64: case ParamType.x64: br.AssertUInt64((ulong)ValueToAssert); break; case ParamType.s64: br.AssertInt64((long)ValueToAssert); break; case ParamType.f32: br.AssertSingle((float)ValueToAssert); break; case ParamType.f64: br.AssertDouble((double)ValueToAssert); break; default: throw new Exception($"Invalid ParamTemplate ParamType: {Type.ToString()}"); } }
protected override void Read(BinaryReaderEx br) { br.BigEndian = false; int fileSize = br.ReadInt32(); int offset1 = br.ReadInt32(); int offset2 = br.ReadInt32(); int offset3 = br.ReadInt32(); br.AssertInt32(0); int offset5 = br.ReadInt32(); int offset6 = br.ReadInt32(); Unk1C = br.ReadInt32(); var offsets = new List <int> { fileSize, offset1, offset2, offset3, offset5, offset6 }; offsets.Sort(); if (offset1 != 0) { Data1 = br.GetBytes(offset1, offsets[offsets.IndexOf(offset1) + 1] - offset1); } if (offset2 != 0) { Data2 = br.GetBytes(offset2, offsets[offsets.IndexOf(offset2) + 1] - offset2); } if (offset3 != 0) { Data3 = br.GetBytes(offset3, offsets[offsets.IndexOf(offset3) + 1] - offset3); } if (offset5 != 0) { Data5 = br.GetBytes(offset5, offsets[offsets.IndexOf(offset5) + 1] - offset5); } if (offset6 != 0) { Data6 = br.GetBytes(offset6, offsets[offsets.IndexOf(offset6) + 1] - offset6); } }
protected override void Read(BinaryReaderEx br) { br.ReadInt32(); // File size short struct2Count = br.ReadInt16(); br.ReadInt16(); // Mesh count br.ReadInt16(); // ? count br.ReadInt16(); // Vertex count br.AssertInt32(0); Struct1s = new Struct1[32]; for (int i = 0; i < 32; i++) { Struct1s[i] = new Struct1(br); } Struct2s = new List <Struct2>(struct2Count); for (int i = 0; i < struct2Count; i++) { Struct2s.Add(new Struct2(br)); } }
internal Command(BinaryReaderEx br, Offsets offsets) { CommandClass = br.ReadInt32(); CommandIndex = br.ReadInt32(); long argumentsLength = br.ReadInt64(); long argumentsOffset = br.ReadInt64(); long eventLayerOffset = br.ReadInt64(); Arguments = br.GetBytes(offsets.Arguments + argumentsOffset, (int)argumentsLength); if (eventLayerOffset != -1) { br.StepIn(offsets.EventLayers + eventLayerOffset); { br.AssertInt32(2); EventLayer = br.ReadInt32(); br.AssertInt64(0); br.AssertInt64(-1); br.AssertInt64(1); } br.StepOut(); } }
public override void Read(HKX hkx, HKXSection section, BinaryReaderEx br, HKXVariation variation) { SectionOffset = (uint)br.Position; AssertPointer(hkx, br); AssertPointer(hkx, br); if (variation != HKXVariation.HKXBloodBorne) { AssertPointer(hkx, br); AssertPointer(hkx, br); } Up.X = br.ReadSingle(); Up.Y = br.ReadSingle(); Up.Z = br.ReadSingle(); Up.W = br.ReadSingle(); Forward.X = br.ReadSingle(); Forward.Y = br.ReadSingle(); Forward.Z = br.ReadSingle(); Forward.W = br.ReadSingle(); Duration = br.ReadSingle(); if (variation != HKXVariation.HKXDS1) { br.AssertInt32(0); // probably padding } ReferenceFrameSamples = new HKArray <HKVector4>(hkx, section, this, br, variation); br.Pad(16); // probably DataSize = (uint)br.Position - SectionOffset; ResolveDestinations(hkx, section); }
/// <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)); } }
internal EventGroup(BinaryReaderEx br, List <long> eventHeaderOffsets, TAEFormat format) { long entryCount = br.ReadVarint(); long valuesOffset = br.ReadVarint(); long typeOffset = br.ReadVarint(); if (format != TAEFormat.DS1) { br.AssertVarint(0); } br.StepIn(typeOffset); { GroupType = br.ReadVarint(); if (format == TAEFormat.SOTFS) { br.AssertVarint(br.Position + (br.VarintLong ? 8 : 4)); br.AssertVarint(0); br.AssertVarint(0); } else if (format != TAEFormat.DS1) { br.AssertVarint(0); } else { GroupData.DataType = (EventGroupDataType)GroupType; long dataOffset = br.ReadVarint(); if (dataOffset != 0) { br.StepIn(dataOffset); { if (GroupData.DataType == EventGroupDataType.ApplyToSpecificCutsceneEntity) { GroupData.CutsceneEntityType = br.ReadEnum16 <EventGroupDataStruct.EntityTypes>(); GroupData.CutsceneEntityIDPart1 = br.ReadInt16(); GroupData.CutsceneEntityIDPart2 = br.ReadInt16(); GroupData.Block = br.ReadSByte(); GroupData.Area = br.ReadSByte(); br.AssertInt32(0); br.AssertInt32(0); } } br.StepOut(); } } } br.StepOut(); br.StepIn(valuesOffset); { if (format == TAEFormat.SOTFS) { indices = br.ReadVarints((int)entryCount).Select(offset => eventHeaderOffsets.FindIndex(headerOffset => headerOffset == offset)).ToList(); } else { indices = br.ReadInt32s((int)entryCount).Select(offset => eventHeaderOffsets.FindIndex(headerOffset => headerOffset == offset)).ToList(); } } br.StepOut(); }
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 override void Read(HKX hkx, HKXSection section, BinaryReaderEx br, HKXVariation variation) { SectionOffset = (uint)br.Position; AssertPointer(hkx, br); if (variation == HKXVariation.HKXBloodBorne) { br.AssertInt32(0); } else { AssertPointer(hkx, br); } AnimationType = br.ReadEnum32 <AnimationType>(); Duration = br.ReadSingle(); TransformTrackCount = br.ReadInt32(); FloatTrackCount = br.ReadInt32(); if (variation == HKXVariation.HKXBloodBorne) { br.Pad(16); } if (variation == HKXVariation.HKXDS1) { br.ReadInt64s(2); // Annotations FrameCount = br.ReadInt32(); BlockCount = br.ReadInt32(); FramesPerBlock = br.ReadInt32(); MaskAndQuantization = br.ReadUInt32(); BlockDuration = br.ReadSingle(); InverseBlockDuration = br.ReadSingle(); FrameDuration = br.ReadSingle(); } else { br.ReadInt64s(3); // Annotations FrameCount = br.ReadInt32(); BlockCount = br.ReadInt32(); FramesPerBlock = br.ReadInt32(); MaskAndQuantization = br.ReadUInt32(); BlockDuration = br.ReadSingle(); InverseBlockDuration = br.ReadSingle(); FrameDuration = br.ReadSingle(); br.ReadUInt32(); // padding? } BlockOffsets = new HKArray <HKUInt>(hkx, section, this, br, variation); FloatBlockOffsets = new HKArray <HKUInt>(hkx, section, this, br, variation); TransformBlockOffsets = new HKArray <HKUInt>(hkx, section, this, br, variation); FloatOffsets = new HKArray <HKUInt>(hkx, section, this, br, variation); Data = new HKArray <HKByte>(hkx, section, this, br, variation); Endian = br.ReadInt32(); DataSize = (uint)br.Position - SectionOffset; ResolveDestinations(hkx, section); }
public IHavokObject Deserialize(BinaryReaderEx br) { br.BigEndian = false; // Peek ahead and read the endian byte br.StepIn(0x11); br.BigEndian = (br.ReadByte() == 0x0) ? true : false; br.StepOut(); // Read header _header = new HKXHeader(); _header.Magic0 = br.AssertUInt32(0x57E0E057); _header.Magic1 = br.AssertUInt32(0x10C0C010); //Header.UserTag = br.AssertInt32(0); _header.UserTag = br.ReadInt32(); _header.Version = br.AssertInt32(0x05, 0x08, 0x0B); if (_header.Version == 0x05) { _variation = HKXVariation.HKXDeS; } else if (_header.Version == 0x08) { _variation = HKXVariation.HKXDS1; } else { _variation = HKXVariation.HKXDS3; } _header.PointerSize = br.AssertByte(4, 8); _header.Endian = br.AssertByte(0, 1); _header.PaddingOption = br.AssertByte(0, 1); _header.BaseClass = br.AssertByte(1); // ? _header.SectionCount = br.AssertInt32(3); // Always 3 sections pretty sure _header.ContentsSectionIndex = br.ReadInt32(); _header.ContentsSectionOffset = br.ReadInt32(); _header.ContentsClassNameSectionIndex = br.ReadInt32(); _header.ContentsClassNameSectionOffset = br.ReadInt32(); _header.ContentsVersionString = br.ReadFixStr(16); // Should be hk_2014.1.0-r1 _header.Flags = br.ReadInt32(); // Later versions of Havok have an extended header if (_header.Version >= 0x0B) { _header.Unk3C = br.ReadInt16(); _header.SectionOffset = br.ReadInt16(); if (_header.SectionOffset > 0) { _header.Unk40 = br.ReadUInt32(); _header.Unk44 = br.ReadUInt32(); _header.Unk48 = br.ReadUInt32(); _header.Unk4C = br.ReadUInt32(); } // Read the 3 sections in the file br.Position = _header.SectionOffset + 0x40; } else { // Just padding br.AssertUInt32(0xFFFFFFFF); } _classSection = new HKXSection(br, _variation); _classSection.SectionID = 0; _typeSection = new HKXSection(br, _variation); _typeSection.SectionID = 1; _dataSection = new HKXSection(br, _variation); _dataSection.SectionID = 2; // Process the class names _classnames = _classSection.ReadClassnames(this); // Deserialize the objects _deserializedObjects = new Dictionary <uint, IHavokObject>(); BinaryReaderEx br2 = new BinaryReaderEx((_header.Endian == 0) ? true : false, _dataSection.SectionData); var root = ConstructVirtualClass(br2, 0); return(root); }
internal Animation(BinaryReaderEx br, TAEFormat format, out bool lastEventNeedsParamGen, out long animFileOffset, out long lastEventParamOffset) { lastEventNeedsParamGen = false; lastEventParamOffset = 0; ID = br.ReadVarint(); long offset = br.ReadVarint(); br.StepIn(offset); { int eventCount; long eventHeadersOffset; int eventGroupCount; long eventGroupsOffset; long timesOffset; if (format == TAEFormat.DS1) { eventCount = br.ReadInt32(); eventHeadersOffset = br.ReadVarint(); eventGroupCount = br.ReadInt32(); eventGroupsOffset = br.ReadVarint(); br.ReadInt32(); // Times count timesOffset = br.ReadVarint(); // Times offset animFileOffset = br.ReadVarint(); //For DeS assert 5 int32 == 0 here } else { eventHeadersOffset = br.ReadVarint(); eventGroupsOffset = br.ReadVarint(); timesOffset = br.ReadVarint(); // Times offset animFileOffset = br.ReadVarint(); eventCount = br.ReadInt32(); eventGroupCount = br.ReadInt32(); br.ReadInt32(); // Times count br.AssertInt32(0); } var eventHeaderOffsets = new List <long>(eventCount); var eventParameterOffsets = new List <long>(eventCount); Events = new List <Event>(eventCount); br.StepIn(eventHeadersOffset); { for (int i = 0; i < eventCount; i++) { eventHeaderOffsets.Add(br.Position); Events.Add(Event.Read(br, out long pOffset, format)); eventParameterOffsets.Add(pOffset); if (i > 0) { // Go to previous event's parameters br.StepIn(eventParameterOffsets[i - 1]); { // Read the space between the previous event's parameter start and the start of this event data. long gapBetweenEventParamOffsets = eventParameterOffsets[i] - eventParameterOffsets[i - 1]; // Subtract to account for the current event's type and offset Events[i - 1].ReadParameters(br, (int)(gapBetweenEventParamOffsets - (br.VarintLong ? 16 : 8))); } br.StepOut(); } } } br.StepOut(); if (eventCount > 0) { if (eventGroupsOffset == 0) { lastEventNeedsParamGen = true; lastEventParamOffset = eventParameterOffsets[eventCount - 1]; } else { // Go to last event's parameters br.StepIn(eventParameterOffsets[eventCount - 1]); { // Read the space between the last event's parameter start and the start of the event groups. Events[eventCount - 1].ReadParameters(br, (int)(eventGroupsOffset - eventParameterOffsets[eventCount - 1])); } br.StepOut(); } } EventGroups = new List <EventGroup>(eventGroupCount); br.StepIn(eventGroupsOffset); { for (int i = 0; i < eventGroupCount; i++) { EventGroups.Add(new EventGroup(br, eventHeaderOffsets, format)); } } br.StepOut(); br.StepIn(animFileOffset); { var miniHeaderType = br.ReadEnum32 <MiniHeaderType>(); if (br.VarintLong) { br.AssertInt32(0); } br.AssertVarint(br.Position + (br.VarintLong ? 8 : 4)); long animFileNameOffset = br.ReadVarint(); //if (AnimFileReference) //{ // ReferenceID = br.ReadInt32(); // UnkReferenceFlag1 = br.ReadBoolean(); // ReferenceIsTAEOnly = br.ReadBoolean(); // ReferenceIsHKXOnly = br.ReadBoolean(); // LoopByDefault = br.ReadBoolean(); //} //else //{ // UnkReferenceFlag1 = br.ReadBoolean(); // ReferenceIsTAEOnly = br.ReadBoolean(); // ReferenceIsHKXOnly = br.ReadBoolean(); // LoopByDefault = br.ReadBoolean(); // ReferenceID = br.ReadInt32(); //} if (miniHeaderType == MiniHeaderType.Standard) { MiniHeader = new AnimMiniHeader.Standard(); } else if (miniHeaderType == MiniHeaderType.ImportOtherAnim) { MiniHeader = new AnimMiniHeader.ImportOtherAnim(); } else { throw new NotImplementedException($"{nameof(AnimMiniHeader)} type not implemented yet."); } MiniHeader.ReadInner(br); if (format != TAEFormat.DS1) { br.AssertVarint(0); br.AssertVarint(0); } else { br.AssertVarint(0); if (MiniHeader.Type == MiniHeaderType.ImportOtherAnim) { br.AssertVarint(0); } } if (animFileNameOffset < br.Length && animFileNameOffset != timesOffset) { if (br.GetInt64(animFileNameOffset) != 1) { var floatCheck = br.GetSingle(animFileNameOffset); if (!(floatCheck >= 0.016667f && floatCheck <= 100)) { AnimFileName = br.GetUTF16(animFileNameOffset); } } } AnimFileName = AnimFileName ?? ""; // When Reference is false, there's always a filename. // When true, there's usually not, but sometimes there is, and I cannot figure out why. // Thus, this stupid hack to achieve byte-perfection. //var animNameCheck = AnimFileName.ToLower(); //if (!(animNameCheck.EndsWith(".hkt") // || (format == TAEFormat.SDT && animNameCheck.EndsWith("hkt")) // || animNameCheck.EndsWith(".hkx") // || animNameCheck.EndsWith(".sib") // || animNameCheck.EndsWith(".hkxwin"))) // AnimFileName = ""; } br.StepOut(); } br.StepOut(); }
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.VarintLong = false; bool isBigEndian = br.AssertInt32(1, 0x1000000) != 1; br.BigEndian = isBigEndian; br.Skip(0x24); uint NumAnimValues = br.ReadUInt32(); Vector3[] AnimationData = new Vector3[NumAnimValues]; br.Skip(0x14C); CameraName = br.ReadASCII(); br.Pad(4); br.Skip(4); NumFrames = br.ReadUInt32(); FrameRef[] FrameRefs = new FrameRef[NumFrames]; CameraAnimation = new List <CameraFrame>((int)NumFrames); br.Skip(0x20); for (int i = 0; i < NumFrames; i++) { FrameRefs[i].Index = br.ReadUInt32(); FrameRefs[i].PositionIndex = br.ReadUInt32(); FrameRefs[i].PositionDiffPrevIndex1 = br.ReadUInt32(); FrameRefs[i].PositionDiffPrevIndex2 = br.ReadUInt32(); FrameRefs[i].RotationIndex = br.ReadUInt32(); FrameRefs[i].RotationDiffPrevIndex1 = br.ReadUInt32(); FrameRefs[i].RotationDiffPrevIndex2 = br.ReadUInt32(); FrameRefs[i].ScaleIndex = br.ReadUInt32(); } InitialFoV = br.ReadSingle(); br.ReadInt32(); NumFoVData = br.ReadUInt32(); br.ReadInt32(); FoVDataList = new List <FoVData>((int)NumFoVData); for (int i = 0; i < NumFoVData; i++) { FoVDataList.Add(new FoVData() { FrameIdx = br.ReadUInt32(), FoV = br.ReadSingle(), TanIn = br.ReadSingle(), TanOut = br.ReadSingle() }); } for (int i = 0; i < NumAnimValues; i++) { AnimationData[i].X = br.ReadSingle(); AnimationData[i].Y = br.ReadSingle(); AnimationData[i].Z = br.ReadSingle(); } //Done reading FrameRef currFrameRef; for (int i = 0; i < NumFrames; i++) { CameraFrame CamFrame = new CameraFrame(); currFrameRef = FrameRefs[i]; CamFrame.Index = currFrameRef.Index; CamFrame.Position = AnimationData[currFrameRef.PositionIndex]; CamFrame.PositionDiffPrev = AnimationData[currFrameRef.RotationDiffPrevIndex1]; CamFrame.Rotation = AnimationData[currFrameRef.RotationIndex]; CamFrame.RotationDiffPrev = AnimationData[currFrameRef.RotationDiffPrevIndex1]; CamFrame.Scale = AnimationData[currFrameRef.ScaleIndex]; CameraAnimation.Add(CamFrame); } }