-
Notifications
You must be signed in to change notification settings - Fork 6
/
ParticleTextureBank.cs
126 lines (99 loc) · 3.82 KB
/
ParticleTextureBank.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
namespace Marathon.Formats.Particle
{
/// <summary>
/// File base for the *.ptb format.
/// <para>Used in SONIC THE HEDGEHOG for defining textures for particle effects.</para>
/// </summary>
public class ParticleTextureBank : FileBase
{
public ParticleTextureBank() { }
public ParticleTextureBank(string file, bool serialise = false)
{
switch (Path.GetExtension(file))
{
case ".json":
{
Data = JsonDeserialise<FormatData>(file);
// Save extension-less JSON (exploiting .NET weirdness, because it doesn't omit all extensions).
if (serialise)
Save(Path.GetFileNameWithoutExtension(file));
break;
}
default:
{
Load(file);
if (serialise)
JsonSerialise(Data);
break;
}
}
}
public override string Signature { get; } = "BTEP";
public override string Extension { get; } = ".ptb";
public class FormatData
{
public string Name { get; set; }
public List<ParticleTexture> ParticleTextures { get; set; } = new();
public override string ToString() => Name;
}
public FormatData Data { get; set; } = new();
public override void Load(Stream stream)
{
BINAReader reader = new(stream);
reader.ReadSignature(4, Signature);
reader.JumpAhead(0x8); // Always Null.
uint EntryCount = reader.ReadUInt32();
Data.Name = reader.ReadNullPaddedString(0x20);
uint OffsetTable = reader.ReadUInt32();
reader.JumpTo(OffsetTable, true); // Should already be here but just to be safe.
// Particle Texture Entries.
for (int i = 0; i < EntryCount; i++)
{
ParticleTexture particle = new()
{
Name = reader.ReadNullPaddedString(0x20),
FilePath = reader.ReadNullPaddedString(0x80),
Width = reader.ReadUInt32(),
Height = reader.ReadUInt32()
};
// Save particle texture entry into the ParticleTextures list.
Data.ParticleTextures.Add(particle);
}
}
public override void Save(Stream stream)
{
BINAWriter writer = new(stream);
// Header
writer.WriteSignature(Signature);
writer.WriteNulls(0x8);
writer.Write(Data.ParticleTextures.Count);
writer.WriteNullPaddedString(Data.Name, 0x20);
writer.AddOffset("OffsetTable");
writer.FillOffset("OffsetTable", true);
// Particle Texture Entries
for (int i = 0; i < Data.ParticleTextures.Count; i++)
{
writer.WriteNullPaddedString(Data.ParticleTextures[i].Name, 0x20);
writer.WriteNullPaddedString(Data.ParticleTextures[i].FilePath, 0x80);
writer.Write(Data.ParticleTextures[i].Width);
writer.Write(Data.ParticleTextures[i].Height);
}
// Write the footer.
writer.FinishWrite();
}
}
public class ParticleTexture
{
/// <summary>
/// Name of this particle texture.
/// </summary>
public string Name { get; set; }
/// <summary>
/// Filepath to the texture used by this particle.
/// </summary>
public string FilePath { get; set; }
public uint Width { get; set; }
public uint Height { get; set; }
public override string ToString() => Name;
}
}