From cdaf0885e00a0bcaf90fa70a3d40aa042de418d5 Mon Sep 17 00:00:00 2001 From: NextinMono <38560522+NextinMono@users.noreply.github.com> Date: Wed, 29 Oct 2025 14:02:43 +0100 Subject: [PATCH 1/2] x64 XNCP support --- Source/SharpNeedle/Framework/Ninja/Csd/Cast.cs | 10 +++++++++- .../Framework/Ninja/Csd/CastInfoTable.cs | 2 +- .../Framework/Ninja/Csd/CsdDictionary.cs | 8 ++++---- .../SharpNeedle/Framework/Ninja/Csd/CsdProject.cs | 1 + Source/SharpNeedle/Framework/Ninja/Csd/Family.cs | 5 +++-- .../Framework/Ninja/Csd/Motions/CastMotion.cs | 10 +++++++++- .../Framework/Ninja/Csd/Motions/KeyFrame.cs | 15 +++++++++++++-- Source/SharpNeedle/Framework/Ninja/Csd/Scene.cs | 10 ++++++++-- .../Framework/Ninja/Csd/TextureMirage.cs | 2 +- Source/SharpNeedle/Framework/Ninja/InfoChunk.cs | 5 +++-- 10 files changed, 52 insertions(+), 16 deletions(-) diff --git a/Source/SharpNeedle/Framework/Ninja/Csd/Cast.cs b/Source/SharpNeedle/Framework/Ninja/Csd/Cast.cs index 2426f2f..ebe01db 100644 --- a/Source/SharpNeedle/Framework/Ninja/Csd/Cast.cs +++ b/Source/SharpNeedle/Framework/Ninja/Csd/Cast.cs @@ -66,7 +66,15 @@ public void Read(BinaryObjectReader reader, Family family) Info = reader.ReadObjectOffset(); InheritanceFlags = reader.Read>(); MaterialFlags = reader.Read>(); - SpriteIndices = reader.ReadArrayOffset(reader.Read()); + + if (reader.OffsetBinaryFormat == OffsetBinaryFormat.U64) + { + SpriteIndices = reader.ReadArrayOffset((int)reader.Read()); + } + else + { + SpriteIndices = reader.ReadArrayOffset(reader.Read()); + } Text = reader.ReadStringOffset(); FontName = reader.ReadStringOffset(); diff --git a/Source/SharpNeedle/Framework/Ninja/Csd/CastInfoTable.cs b/Source/SharpNeedle/Framework/Ninja/Csd/CastInfoTable.cs index aac7cb9..38e8ae4 100644 --- a/Source/SharpNeedle/Framework/Ninja/Csd/CastInfoTable.cs +++ b/Source/SharpNeedle/Framework/Ninja/Csd/CastInfoTable.cs @@ -4,7 +4,7 @@ public class CastInfoTable : List<(string? Name, int FamilyIdx, int CastIdx)>, I { public void Read(BinaryObjectReader reader) { - int count = reader.Read(); + long count = reader.OffsetBinaryFormat == OffsetBinaryFormat.U64 ? reader.Read() : reader.Read(); if (count == 0) { reader.Skip(reader.GetOffsetSize()); diff --git a/Source/SharpNeedle/Framework/Ninja/Csd/CsdDictionary.cs b/Source/SharpNeedle/Framework/Ninja/Csd/CsdDictionary.cs index 75bbe5e..1b97fe3 100644 --- a/Source/SharpNeedle/Framework/Ninja/Csd/CsdDictionary.cs +++ b/Source/SharpNeedle/Framework/Ninja/Csd/CsdDictionary.cs @@ -72,15 +72,15 @@ public bool Remove(KeyValuePair item) public void Read(BinaryObjectReader reader) { - int count = reader.Read(); + long count = reader.OffsetBinaryFormat == OffsetBinaryFormat.U64 ? reader.Read() : reader.Read(); if (count == 0) { reader.Skip(reader.GetOffsetSize() * 2); return; } - Items.AddRange(reader.ReadObjectArrayOffset(count)); - NameTable.AddRange(reader.ReadObjectArrayOffset(count)); + Items.AddRange(reader.ReadObjectArrayOffset((int)count)); + NameTable.AddRange(reader.ReadObjectArrayOffset((int)count)); } public void Write(BinaryObjectWriter writer) @@ -232,7 +232,7 @@ public NameIndexPair(string? name, int idx) public void Read(BinaryObjectReader reader) { Name = reader.ReadStringOffset(); - Index = reader.Read(); + Index = (int)(reader.OffsetBinaryFormat == OffsetBinaryFormat.U64 ? reader.Read() : reader.Read()); } public void Write(BinaryObjectWriter writer) diff --git a/Source/SharpNeedle/Framework/Ninja/Csd/CsdProject.cs b/Source/SharpNeedle/Framework/Ninja/Csd/CsdProject.cs index 35a586f..dce252d 100644 --- a/Source/SharpNeedle/Framework/Ninja/Csd/CsdProject.cs +++ b/Source/SharpNeedle/Framework/Ninja/Csd/CsdProject.cs @@ -37,6 +37,7 @@ public void Read(BinaryObjectReader reader) continue; Stream stream = Package.GetStream(i); using BinaryObjectReader infoReader = new(stream, StreamOwnership.Transfer, Package.Endianness); + infoReader.OffsetBinaryFormat = reader.OffsetBinaryFormat; try { InfoChunk info = infoReader.ReadObject(options); diff --git a/Source/SharpNeedle/Framework/Ninja/Csd/Family.cs b/Source/SharpNeedle/Framework/Ninja/Csd/Family.cs index bdfa338..3c3b401 100644 --- a/Source/SharpNeedle/Framework/Ninja/Csd/Family.cs +++ b/Source/SharpNeedle/Framework/Ninja/Csd/Family.cs @@ -21,7 +21,8 @@ public void AttachMotion(FamilyMotion motion) public void Read(BinaryObjectReader reader, Scene context) { Scene = context; - int castCount = reader.Read(); + int castCount = (int)(reader.OffsetBinaryFormat == OffsetBinaryFormat.U64 ? reader.Read() : reader.Read()); + CastBuffer = new List(castCount); reader.ReadOffset(() => { @@ -31,7 +32,7 @@ public void Read(BinaryObjectReader reader, Scene context) } }); - int root = reader.Read(); + int root = (int)(reader.OffsetBinaryFormat == OffsetBinaryFormat.U64 ? reader.Read() : reader.Read()); TreeDescriptorNode[] tree = reader.ReadArrayOffset(CastBuffer.Count); if (CastBuffer.Count != 0) { diff --git a/Source/SharpNeedle/Framework/Ninja/Csd/Motions/CastMotion.cs b/Source/SharpNeedle/Framework/Ninja/Csd/Motions/CastMotion.cs index e2d36cd..0274b35 100644 --- a/Source/SharpNeedle/Framework/Ninja/Csd/Motions/CastMotion.cs +++ b/Source/SharpNeedle/Framework/Ninja/Csd/Motions/CastMotion.cs @@ -18,7 +18,15 @@ public CastMotion(Cast cast) public void Read(BinaryObjectReader reader) { Clear(); - Flags = reader.Read>(); + if (reader.OffsetBinaryFormat == OffsetBinaryFormat.U64) + { + Flags = (BitSet)reader.Read>().Value; + } + else + { + Flags = reader.Read>(); + } + int count = Flags.PopCount(); if (count == 0) diff --git a/Source/SharpNeedle/Framework/Ninja/Csd/Motions/KeyFrame.cs b/Source/SharpNeedle/Framework/Ninja/Csd/Motions/KeyFrame.cs index 9cb19a2..8d893ea 100644 --- a/Source/SharpNeedle/Framework/Ninja/Csd/Motions/KeyFrame.cs +++ b/Source/SharpNeedle/Framework/Ninja/Csd/Motions/KeyFrame.cs @@ -16,7 +16,15 @@ public void Read(BinaryObjectReader reader) { Frame = reader.Read(); Value = reader.Read(); - Interpolation = reader.Read(); + if (reader.OffsetBinaryFormat == OffsetBinaryFormat.U64) + { + Interpolation = (InterpolationType)reader.Read(); + } + else + { + Interpolation = reader.Read(); + } + InTangent = reader.Read(); OutTangent = reader.Read(); Field14 = reader.Read(); @@ -26,7 +34,10 @@ public void Write(BinaryObjectWriter writer) { writer.Write(Frame); writer.Write(Value.Uint); - writer.Write(Interpolation); + if(writer.OffsetBinaryFormat == OffsetBinaryFormat.U64) + writer.Write((uint)Interpolation); + else + writer.Write(Interpolation); writer.Write(InTangent); writer.Write(OutTangent); writer.Write(Field14); diff --git a/Source/SharpNeedle/Framework/Ninja/Csd/Scene.cs b/Source/SharpNeedle/Framework/Ninja/Csd/Scene.cs index ac9bd33..04faf7d 100644 --- a/Source/SharpNeedle/Framework/Ninja/Csd/Scene.cs +++ b/Source/SharpNeedle/Framework/Ninja/Csd/Scene.cs @@ -22,9 +22,9 @@ public void Read(BinaryObjectReader reader) float motionBegin = reader.Read(); float motionEnd = reader.Read(); Textures = new List(reader.ReadArrayOffset(reader.Read())); - Sprites = new List(reader.ReadArrayOffset(reader.Read())); + Sprites = new List(reader.ReadArrayOffset((int)(reader.OffsetBinaryFormat == OffsetBinaryFormat.U64 ? reader.Read() : reader.Read()))); - int familyCount = reader.Read(); + int familyCount = (int)(reader.OffsetBinaryFormat == OffsetBinaryFormat.U64 ? reader.Read() : reader.Read()); Families = new List(familyCount); reader.ReadOffset(() => { @@ -51,6 +51,12 @@ public void Read(BinaryObjectReader reader) if (Version >= 1) { AspectRatio = reader.Read(); + + //This is the only "new" field in x64 CSD files, is this alignment/padding, or is this a new field? + if (reader.OffsetBinaryFormat == OffsetBinaryFormat.U64) + { + reader.Read(); + } } if (Version >= 2) diff --git a/Source/SharpNeedle/Framework/Ninja/Csd/TextureMirage.cs b/Source/SharpNeedle/Framework/Ninja/Csd/TextureMirage.cs index bbb7a71..461f6a4 100644 --- a/Source/SharpNeedle/Framework/Ninja/Csd/TextureMirage.cs +++ b/Source/SharpNeedle/Framework/Ninja/Csd/TextureMirage.cs @@ -19,7 +19,7 @@ public TextureMirage(string name) public void Read(BinaryObjectReader reader) { Name = reader.ReadStringOffset(); - MemoryDataIndex = reader.Read(); + MemoryDataIndex = (int)(reader.OffsetBinaryFormat == OffsetBinaryFormat.U64 ? reader.Read() : reader.Read()); } public void Write(BinaryObjectWriter writer) diff --git a/Source/SharpNeedle/Framework/Ninja/InfoChunk.cs b/Source/SharpNeedle/Framework/Ninja/InfoChunk.cs index 4f640a9..1138a60 100644 --- a/Source/SharpNeedle/Framework/Ninja/InfoChunk.cs +++ b/Source/SharpNeedle/Framework/Ninja/InfoChunk.cs @@ -23,7 +23,8 @@ public void Read(BinaryObjectReader reader, ChunkBinaryOptions options) Chunks.Clear(); Chunks.Capacity = chunkCount; - reader.ReadOffset(() => + uint offset = reader.ReadUInt32(); + reader.ReadAtOffset(offset, () => { reader.PushOffsetOrigin(); for (int i = 0; i < chunkCount; i++) @@ -56,7 +57,7 @@ public void Read(BinaryObjectReader reader, ChunkBinaryOptions options) }); reader.Skip(4); // size of all chunks - Offsets = reader.ReadObjectOffset(); + Offsets = reader.ReadObjectAtOffset(reader.ReadUInt32()); reader.Skip(4); // Offsets.BinarySize Field1C = reader.Read(); From b2f7ed46660d1000596d9f0deaadea85aed2623e Mon Sep 17 00:00:00 2001 From: NextinMono <38560522+NextinMono@users.noreply.github.com> Date: Wed, 29 Oct 2025 14:15:20 +0100 Subject: [PATCH 2/2] Use ReadOffsetValue over ternary operator --- Source/SharpNeedle/Framework/Ninja/Csd/CastInfoTable.cs | 5 +++-- Source/SharpNeedle/Framework/Ninja/Csd/CsdDictionary.cs | 8 +++++--- Source/SharpNeedle/Framework/Ninja/Csd/Family.cs | 6 ++++-- Source/SharpNeedle/Framework/Ninja/Csd/Scene.cs | 6 ++++-- Source/SharpNeedle/Framework/Ninja/Csd/TextureMirage.cs | 3 ++- 5 files changed, 18 insertions(+), 10 deletions(-) diff --git a/Source/SharpNeedle/Framework/Ninja/Csd/CastInfoTable.cs b/Source/SharpNeedle/Framework/Ninja/Csd/CastInfoTable.cs index 38e8ae4..0b2393e 100644 --- a/Source/SharpNeedle/Framework/Ninja/Csd/CastInfoTable.cs +++ b/Source/SharpNeedle/Framework/Ninja/Csd/CastInfoTable.cs @@ -4,7 +4,8 @@ public class CastInfoTable : List<(string? Name, int FamilyIdx, int CastIdx)>, I { public void Read(BinaryObjectReader reader) { - long count = reader.OffsetBinaryFormat == OffsetBinaryFormat.U64 ? reader.Read() : reader.Read(); + // FYI: this is not an offset, this is just to read it as a long or int based on the format + long count = reader.ReadOffsetValue(); if (count == 0) { reader.Skip(reader.GetOffsetSize()); @@ -35,7 +36,7 @@ public void Write(BinaryObjectWriter writer) { foreach ((string? Name, int FamilyIdx, int CastIdx) in this) { - writer.WriteOffset(() => + writer.WriteOffset(() => { writer.WriteString(StringBinaryFormat.NullTerminated, Name); writer.Write(0); diff --git a/Source/SharpNeedle/Framework/Ninja/Csd/CsdDictionary.cs b/Source/SharpNeedle/Framework/Ninja/Csd/CsdDictionary.cs index 1b97fe3..3508ed0 100644 --- a/Source/SharpNeedle/Framework/Ninja/Csd/CsdDictionary.cs +++ b/Source/SharpNeedle/Framework/Ninja/Csd/CsdDictionary.cs @@ -72,7 +72,8 @@ public bool Remove(KeyValuePair item) public void Read(BinaryObjectReader reader) { - long count = reader.OffsetBinaryFormat == OffsetBinaryFormat.U64 ? reader.Read() : reader.Read(); + // FYI: this is not an offset, this is just to read it as a long or int based on the format + long count = reader.ReadOffsetValue(); if (count == 0) { reader.Skip(reader.GetOffsetSize() * 2); @@ -232,14 +233,15 @@ public NameIndexPair(string? name, int idx) public void Read(BinaryObjectReader reader) { Name = reader.ReadStringOffset(); - Index = (int)(reader.OffsetBinaryFormat == OffsetBinaryFormat.U64 ? reader.Read() : reader.Read()); + // FYI: this is not an offset, this is just to read it as a long or int based on the format + Index = (int)reader.ReadOffsetValue(); } public void Write(BinaryObjectWriter writer) { string? name = Name; - writer.WriteOffset(() => + writer.WriteOffset(() => { writer.WriteString(StringBinaryFormat.NullTerminated, name); writer.Write(0); diff --git a/Source/SharpNeedle/Framework/Ninja/Csd/Family.cs b/Source/SharpNeedle/Framework/Ninja/Csd/Family.cs index 3c3b401..2888a06 100644 --- a/Source/SharpNeedle/Framework/Ninja/Csd/Family.cs +++ b/Source/SharpNeedle/Framework/Ninja/Csd/Family.cs @@ -21,7 +21,8 @@ public void AttachMotion(FamilyMotion motion) public void Read(BinaryObjectReader reader, Scene context) { Scene = context; - int castCount = (int)(reader.OffsetBinaryFormat == OffsetBinaryFormat.U64 ? reader.Read() : reader.Read()); + // FYI: this is not an offset + int castCount = (int)reader.ReadOffsetValue(); CastBuffer = new List(castCount); reader.ReadOffset(() => @@ -32,7 +33,8 @@ public void Read(BinaryObjectReader reader, Scene context) } }); - int root = (int)(reader.OffsetBinaryFormat == OffsetBinaryFormat.U64 ? reader.Read() : reader.Read()); + // FYI: this is not an offset + int root = (int)reader.ReadOffsetValue(); TreeDescriptorNode[] tree = reader.ReadArrayOffset(CastBuffer.Count); if (CastBuffer.Count != 0) { diff --git a/Source/SharpNeedle/Framework/Ninja/Csd/Scene.cs b/Source/SharpNeedle/Framework/Ninja/Csd/Scene.cs index 04faf7d..ba1c407 100644 --- a/Source/SharpNeedle/Framework/Ninja/Csd/Scene.cs +++ b/Source/SharpNeedle/Framework/Ninja/Csd/Scene.cs @@ -22,9 +22,11 @@ public void Read(BinaryObjectReader reader) float motionBegin = reader.Read(); float motionEnd = reader.Read(); Textures = new List(reader.ReadArrayOffset(reader.Read())); - Sprites = new List(reader.ReadArrayOffset((int)(reader.OffsetBinaryFormat == OffsetBinaryFormat.U64 ? reader.Read() : reader.Read()))); + // The ReadOffsetValue call is not for an offset + Sprites = new List(reader.ReadArrayOffset((int)reader.ReadOffsetValue())); - int familyCount = (int)(reader.OffsetBinaryFormat == OffsetBinaryFormat.U64 ? reader.Read() : reader.Read()); + // FYI: this is not an offset + int familyCount = (int)reader.ReadOffsetValue(); Families = new List(familyCount); reader.ReadOffset(() => { diff --git a/Source/SharpNeedle/Framework/Ninja/Csd/TextureMirage.cs b/Source/SharpNeedle/Framework/Ninja/Csd/TextureMirage.cs index 461f6a4..2a479d0 100644 --- a/Source/SharpNeedle/Framework/Ninja/Csd/TextureMirage.cs +++ b/Source/SharpNeedle/Framework/Ninja/Csd/TextureMirage.cs @@ -19,7 +19,8 @@ public TextureMirage(string name) public void Read(BinaryObjectReader reader) { Name = reader.ReadStringOffset(); - MemoryDataIndex = (int)(reader.OffsetBinaryFormat == OffsetBinaryFormat.U64 ? reader.Read() : reader.Read()); + // FYI: this is not an offset + MemoryDataIndex = (int)reader.ReadOffsetValue(); } public void Write(BinaryObjectWriter writer)