internal void WriteFaceIndices(BinaryWriterEx bw, ref short index, ref int faceIndexIndex) { short thisIndex = index; if (FaceIndices == null) { bw.FillInt16($"FaceIndexCount{thisIndex}", 0); bw.FillInt16($"FaceIndexIndex{thisIndex}", 0); } else { bw.FillInt16($"FaceIndexCount{thisIndex}", (short)FaceIndices.Count); bw.FillInt16($"FaceIndexIndex{thisIndex}", (short)faceIndexIndex); bw.WriteInt16s(FaceIndices); faceIndexIndex += FaceIndices.Count; } if (Left != null) { index++; Left.WriteFaceIndices(bw, ref index, ref faceIndexIndex); } if (Right != null) { index++; Right.WriteFaceIndices(bw, ref index, ref faceIndexIndex); } }
internal void Write(BinaryWriterEx bw, ref short index) { short thisIndex = index; bw.WriteSingle(Unk00); bw.ReserveInt16($"LeftIndex{thisIndex}"); bw.ReserveInt16($"RightIndex{thisIndex}"); bw.ReserveInt16($"FaceIndexCount{thisIndex}"); bw.ReserveInt16($"FaceIndexIndex{thisIndex}"); if (Left == null) { bw.FillInt16($"LeftIndex{thisIndex}", -1); } else { index++; bw.FillInt16($"LeftIndex{thisIndex}", index); Left.Write(bw, ref index); } if (Right == null) { bw.FillInt16($"RightIndex{thisIndex}", -1); } else { index++; bw.FillInt16($"RightIndex{thisIndex}", index); Right.Write(bw, ref index); } }
/// <summary> /// Serializes file data to a stream. /// </summary> protected override void Write(BinaryWriterEx bw) { bw.BigEndian = false; bw.WriteUInt32((uint)Version); bw.BigEndian = Version == CCMVer.DemonsSouls; bw.ReserveInt32("FileSize"); bw.WriteInt16(FullWidth); bw.WriteInt16(TexWidth); bw.WriteInt16(TexHeight); if (Version == CCMVer.DemonsSouls || Version == CCMVer.DarkSouls1) { bw.WriteInt16(Unk0E); bw.ReserveInt16("CodeGroupCount"); bw.WriteInt16((short)Glyphs.Count); } else if (Version == CCMVer.DarkSouls2) { bw.ReserveInt16("TexRegionCount"); bw.WriteInt16((short)Glyphs.Count); bw.WriteInt16(0); } bw.WriteInt32(0x20); bw.ReserveInt32("GlyphOffset"); bw.WriteByte(Unk1C); bw.WriteByte(Unk1D); bw.WriteByte(TexCount); bw.WriteByte(0); var codes = new List <int>(Glyphs.Keys); codes.Sort(); if (Version == CCMVer.DemonsSouls || Version == CCMVer.DarkSouls1) { var codeGroups = new List <CodeGroup>(); for (int i = 0; i < Glyphs.Count;) { int startCode = codes[i]; int glyphIndex = i; for (i++; i < Glyphs.Count && codes[i] == codes[i - 1] + 1; i++) { ; } int endCode = codes[i - 1]; codeGroups.Add(new CodeGroup(startCode, endCode, glyphIndex)); } bw.FillInt16("CodeGroupCount", (short)codeGroups.Count); foreach (CodeGroup group in codeGroups) { group.Write(bw); } bw.FillInt32("GlyphOffset", (int)bw.Position); foreach (int code in codes) { Glyph glyph = Glyphs[code]; bw.WriteVector2(glyph.UV1); bw.WriteVector2(glyph.UV2); bw.WriteInt16(glyph.PreSpace); bw.WriteInt16(glyph.Width); bw.WriteInt16(glyph.Advance); bw.WriteInt16(glyph.TexIndex); } } else if (Version == CCMVer.DarkSouls2) { var texRegionsByCode = new Dictionary <int, TexRegion>(Glyphs.Count); var texRegions = new HashSet <TexRegion>(); foreach (int code in codes) { Glyph glyph = Glyphs[code]; short x1 = (short)Math.Round(glyph.UV1.X * TexWidth); short y1 = (short)Math.Round(glyph.UV1.Y * TexHeight); short x2 = (short)Math.Round(glyph.UV2.X * TexWidth); short y2 = (short)Math.Round(glyph.UV2.Y * TexHeight); var region = new TexRegion(x1, y1, x2, y2); texRegionsByCode[code] = region; texRegions.Add(region); } bw.FillInt16("TexRegionCount", (short)texRegions.Count); var texRegionOffsets = new Dictionary <TexRegion, int>(texRegions.Count); foreach (TexRegion region in texRegions) { texRegionOffsets[region] = (int)bw.Position; region.Write(bw); } bw.FillInt32("GlyphOffset", (int)bw.Position); foreach (int code in codes) { Glyph glyph = Glyphs[code]; bw.WriteInt32(code); bw.WriteInt32(texRegionOffsets[texRegionsByCode[code]]); bw.WriteInt16(glyph.TexIndex); bw.WriteInt16(glyph.PreSpace); bw.WriteInt16(glyph.Width); bw.WriteInt16(glyph.Advance); bw.WriteInt32(0); bw.WriteInt32(0); } } bw.FillInt32("FileSize", (int)bw.Position); }