Skip to content

Commit ab9e52b

Browse files
committed
Improve skeletons
* Animation skeleton is now changeable * Skeleton id in SKLB is now changeable * Parent/fallback skeletons can now be edited in SKLB
1 parent c1d61c1 commit ab9e52b

File tree

3 files changed

+124
-30
lines changed

3 files changed

+124
-30
lines changed

XAT/XAT/Game/Formats/Sklb/SklbFormat.cs

+91-30
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,37 @@ public class SklbFormat
1212
{
1313
private const string MAGIC = "blks";
1414

15-
public byte[] PreHavokData { get; set; }
15+
public short Header1 { get; set; }
16+
public short Header2 { get; set; }
17+
18+
[DependsOn(nameof(Header1), nameof(Header2))]
19+
public bool OldHeader
20+
{
21+
get
22+
{
23+
switch (Header2)
24+
{
25+
case 0x3132:
26+
return true;
27+
28+
case 0x3133:
29+
return false;
30+
31+
default:
32+
Log.Warning($"Unknown sklb headers: Part 1: 0x{Header1.ToString("X")}, Part 2: 0x{Header2.ToString("X")} - Assume it's new for now");
33+
return false;
34+
}
35+
}
36+
}
37+
38+
public int Unk1 { get; set; }
39+
40+
public int Skeleton { get; set; }
41+
public int[] ParentSkeletons { get; set; }
42+
43+
public byte[] Unk2 { get; set; }
44+
public byte[] Unk3 { get; set; }
45+
1646
public byte[] HavokData { get; set; }
1747

1848
public SklbFormat(BinaryReader reader)
@@ -23,51 +53,82 @@ public SklbFormat(BinaryReader reader)
2353
throw new Exception("Invalid sklb file - magic incorrect");
2454

2555
// Read header
26-
int header1 = reader.ReadInt16();
27-
int header2 = reader.ReadInt16();
28-
bool oldHeader;
56+
Header1 = reader.ReadInt16();
57+
Header2 = reader.ReadInt16();
58+
Log.Debug($"Sklb headers were: Part 1: 0x{Header1.ToString("X")}, Part 2: 0x{Header2.ToString("X")}");
2959

30-
Log.Debug($"Sklb headers were: Part 1: 0x{header1.ToString("X")}, Part 2: 0x{header2.ToString("X")}");
31-
32-
switch (header2)
33-
{
34-
case 0x3132:
35-
oldHeader = true;
36-
break;
37-
38-
case 0x3133:
39-
oldHeader = false;
40-
break;
41-
42-
default:
43-
Log.Warning($"Unknown sklb headers: Part 1: 0x{header1.ToString("X")}, Part 2: 0x{header2.ToString("X")} - Assume it's new for now");
44-
oldHeader = false;
45-
break;
46-
}
47-
48-
// Havok offset
60+
// Offsets
4961
int havokOffset;
50-
if (oldHeader)
62+
int unknownOffset;
63+
if (OldHeader)
5164
{
52-
reader.BaseStream.Seek(10, SeekOrigin.Begin);
65+
unknownOffset = reader.ReadInt16();
5366
havokOffset = reader.ReadInt16();
5467
}
5568
else
5669
{
57-
reader.BaseStream.Seek(12, SeekOrigin.Begin);
70+
unknownOffset = reader.ReadInt32();
5871
havokOffset = reader.ReadInt32();
72+
Unk1 = reader.ReadInt32();
5973
}
6074

61-
// Havok data
62-
reader.BaseStream.Seek(0, SeekOrigin.Begin);
63-
this.PreHavokData = reader.ReadBytes(havokOffset);
75+
Skeleton = reader.ReadInt32();
76+
77+
ParentSkeletons = new int[4];
78+
for (int i = 0; i < ParentSkeletons.Length; ++i)
79+
{
80+
ParentSkeletons[i] = reader.ReadInt32();
81+
}
82+
83+
this.Unk2 = reader.ReadBytes((int)(unknownOffset - reader.BaseStream.Position));
84+
85+
this.Unk3 = reader.ReadBytes((int)(havokOffset - reader.BaseStream.Position));
86+
6487
this.HavokData = reader.ReadBytes((int)reader.BaseStream.Length - havokOffset);
6588
}
6689

6790
public void Serialize(BinaryWriter writer)
6891
{
69-
writer.Write(this.PreHavokData);
92+
writer.WriteEncodedString(MAGIC);
93+
writer.Write(Header1);
94+
writer.Write(Header2);
95+
96+
if(OldHeader)
97+
{
98+
writer.Write((short)0);
99+
writer.Write((short)0);
100+
}
101+
else
102+
{
103+
writer.Write((int)0);
104+
writer.Write((int)0);
105+
writer.Write(Unk1);
106+
}
107+
108+
writer.Write(Skeleton);
109+
for (int i = 0; i < ParentSkeletons.Length; ++i)
110+
{
111+
writer.Write(ParentSkeletons[i]);
112+
}
113+
114+
writer.Write(Unk2);
115+
int firstOffset = (int) writer.BaseStream.Position;
116+
writer.Write(Unk3);
117+
118+
int havokOffset = (int)writer.BaseStream.Position;
70119
writer.Write(this.HavokData);
120+
121+
writer.BaseStream.Seek(8, SeekOrigin.Begin);
122+
if (OldHeader)
123+
{
124+
writer.Write((short)firstOffset);
125+
writer.Write((short)havokOffset);
126+
}
127+
else
128+
{
129+
writer.Write((int)firstOffset);
130+
writer.Write((int)havokOffset);
131+
}
71132
}
72133

73134
public byte[] ToBytes()

XAT/XAT/UI/Animation/AnimationEditor.xaml

+3
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@
4343

4444
<TabItem Header="Advanced">
4545
<StackPanel>
46+
<TextBox Text="{Binding Animation.Container.Skeleton}" materialDesign:HintAssist.Hint="Skeleton Id" materialDesign:HintAssist.HelperText="The skeleton this PAP is bound to." />
47+
48+
<Separator Opacity="0" Height="20"/>
4649
<TextBox Text="{Binding Animation.Data.Name}" materialDesign:HintAssist.Hint="Animation Name" materialDesign:HintAssist.HelperText="The name of this animation." />
4750

4851
<Separator Opacity="0" Height="20"/>

XAT/XAT/UI/Skeleton/SkeletonTab.xaml

+30
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,36 @@
3535
</GroupBox>
3636

3737
<StackPanel Grid.Column="2">
38+
<GroupBox Header="Properties">
39+
<StackPanel>
40+
<TextBox Text="{Binding Skeleton.Skeleton}" materialDesign:HintAssist.Hint="Skeleton Id" materialDesign:HintAssist.HelperText="The root skeleton." />
41+
42+
<Separator Opacity="0" Height="20"/>
43+
<Grid>
44+
<Grid.ColumnDefinitions>
45+
<ColumnDefinition />
46+
<ColumnDefinition Width="10" />
47+
<ColumnDefinition />
48+
<ColumnDefinition Width="10" />
49+
<ColumnDefinition />
50+
<ColumnDefinition Width="10" />
51+
<ColumnDefinition />
52+
</Grid.ColumnDefinitions>
53+
54+
<TextBox Grid.Column="0" Text="{Binding Skeleton.ParentSkeletons[0]}" materialDesign:HintAssist.Hint="Parent 1" materialDesign:HintAssist.HelperText="Parent skeleton 1." />
55+
56+
<TextBox Grid.Column="2" Text="{Binding Skeleton.ParentSkeletons[1]}" materialDesign:HintAssist.Hint="Parent 2" materialDesign:HintAssist.HelperText="Parent skeleton 2." />
57+
58+
<TextBox Grid.Column="4" Text="{Binding Skeleton.ParentSkeletons[2]}" materialDesign:HintAssist.Hint="Parent 3" materialDesign:HintAssist.HelperText="Parent skeleton 3." />
59+
60+
<TextBox Grid.Column="6" Text="{Binding Skeleton.ParentSkeletons[3]}" materialDesign:HintAssist.Hint="Parent 4" materialDesign:HintAssist.HelperText="Parent skeleton 4." />
61+
</Grid>
62+
<Separator Opacity="0" Height="20"/>
63+
</StackPanel>
64+
</GroupBox>
65+
66+
<Separator Opacity="0" Height="10" />
67+
3868
<GroupBox Header="Import">
3969
<local:SkeletonImportView Skeleton="{Binding Skeleton}" />
4070
</GroupBox>

0 commit comments

Comments
 (0)