protected override void SaveInternal(SaveContext saveContext) { // A little maintenance... if we have any models with bones, let's // make sure their indexes are correct... var models = (ChunkDICTModel)Entries[(int)EntryType.Model]; foreach (var modelEntry in models.Entries) { var model = (DICTObjModel)modelEntry.EntryObject; if (model.HasSkeleton) { var bones = model.Skeleton.Bones; for (var i = 0; i < bones.Entries.Count; i++) { (bones.Entries[i].EntryObject as DICTObjBone).Index = i; } // TODO -- fix all SubMeshes with BoneIndices here now! } } var utility = saveContext.Utility; // Write out zeroes to accomodate all entries, reserving the space var dictLUTStartPos = utility.GetWritePosition(); for (var entry = EntryType.Model; entry < EntryType.TotalEntries; entry++) { var numEntries = Entries[(int)entry]?.NumEntries ?? 0U; utility.Write(numEntries); // We can write number of entries NOW... utility.Write(0U); // ... but we can't know the offset yet! } // First the dictionary headers are written out for (var entry = EntryType.Model; entry < EntryType.TotalEntries; entry++) { var dict = Entries[(int)entry]; if (dict != null && dict.NumEntries > 0) { // From start of LUT to 4 + entry * 8 bytes inward... var dictLUTTarget = (uint)(dictLUTStartPos + 4 + ((int)entry * 8)); utility.WriteOffset(dictLUTTarget); // Save DICT chunk dict.Save(saveContext); } } // Now we need to explicitly write out the dictionary contents for (var entry = EntryType.Model; entry < EntryType.TotalEntries; entry++) { var dict = Entries[(int)entry]; dict?.SaveEntries(saveContext); } // Resolve all references saveContext.ResolvePointerReferences(); // Finally, write out the string table saveContext.DumpStringTable(); // The IMAG chunk seems to have its data (passed the 8 byte header) aligned to nearest // 128 byte boundary. So we need to make sure we're aligned there before writing it. // We need to do this here (unfortunately kinda) because it needs to be included in // the recorded size of the DATA chunk. utility.AlignWrite(128, 8); }