public void Save(string file) { Console.WriteLine(file); using (var bw = new BinaryWriter(File.Create(file))) { // skip header until later ------------------------------------------------------------------------------------ bw.Pad(Header.HeaderLength); if (EventGroupsA.Count != EventGroupsB.Count) { throw new Exception($"Event groups A and B count don't match ({EventGroupsA.Count}, {EventGroupsB.Count})"); } int numGroups = EventGroupsA.Count; // write the list containing the number of items in each subgroup ---------------------------------------------- for (int i = 0; i < numGroups; i++) { var groupA = EventGroupsA[i]; var groupB = EventGroupsB[i]; if (groupA.Count != groupB.Count) { throw new Exception($"Event group {i} does not contain the same number of events in A and B"); } bw.Write(groupA.Count); } // skip offset table until later ------------------------------------------------------------------------------ int numOffsets = EventGroupsA.Sum(i => i.Count); // the +1 is because there's an 'end' one too // *4 for each byte in an offset entry // *2 for the two tables A and B int dataStart = OffsetTableStart + (numOffsets + 1) * 4 * 2; bw.BaseStream.Seek(dataStart, SeekOrigin.Begin); // write data, keep track of offsets ---------------------------------------------------------------------------- List <List <int> > offsetsA = new List <List <int> >(); long startOffsetA = bw.BaseStream.Position; foreach (var group in EventGroupsA) { List <int> subgroupOffsets = new List <int>(); offsetsA.Add(subgroupOffsets); foreach (var(b, e) in group) { subgroupOffsets.Add((int)(bw.BaseStream.Position - startOffsetA)); bw.Write(b); e.WriteTo(bw); } } List <List <int> > offsetsB = new List <List <int> >(); long startOffsetB = bw.BaseStream.Position; int tableBDataOffset = (int)(startOffsetB - startOffsetA); foreach (var group in EventGroupsB) { List <int> subgroupOffsets = new List <int>(); offsetsB.Add(subgroupOffsets); foreach (var e in group) { subgroupOffsets.Add((int)(bw.BaseStream.Position - startOffsetB)); e.WriteTo(bw); } } int dataEndB = (int)(bw.BaseStream.Position - startOffsetB); // pad the file to be divisible by 0x10 while (bw.BaseStream.Length % 8 != 0) { bw.Pad(1); } // write offsets ---------------------------------------------------------------------------------------------- bw.BaseStream.Position = OffsetTableStart; foreach (var offsets in offsetsA) { foreach (var o in offsets) { bw.Write(o); } } bw.Write(tableBDataOffset); foreach (var offsets in offsetsB) { foreach (var o in offsets) { bw.Write(o); } } bw.Write(dataEndB); // write the header ---------------------------------------------------------------------------------------------- var header = new Header() { FortyEight = 0x48, FileId = FileId, Unknown = HeaderUnknown, NumGroups = numGroups, TableBDataOffset = tableBDataOffset, FileLength = (int)bw.BaseStream.Length, NumOffsets = numOffsets }; bw.BaseStream.Position = 0; header.WriteTo(bw); } }