Skip to content
This repository was archived by the owner on Feb 2, 2022. It is now read-only.

Commit a1faffd

Browse files
committed
[M2] Fix Dictionary Error.
1 parent fd7088b commit a1faffd

1 file changed

Lines changed: 54 additions & 45 deletions

File tree

MultiConverter.Lib/Converters/ModelConverter.cs

Lines changed: 54 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ public class M2Converter : WowFile
2323
private HashSet<uint> shiftedOfs = new HashSet<uint>();
2424
private Dictionary<int, byte[]> multitextInfo = new Dictionary<int, byte[]>();
2525
private List<SkinConverter> skins = new List<SkinConverter>();
26-
private Dictionary<string, int> Textures = new Dictionary<string, int>();
27-
private Dictionary<string, uint> Chunks = new Dictionary<string, uint>();
26+
27+
private Dictionary<Texture, int> Textures = new Dictionary<Texture, int>();
2828

2929
public M2Converter(string m2, bool fix_helm) : base(m2)
3030
{
@@ -44,9 +44,6 @@ public M2Converter(string m2, bool fix_helm) : base(m2)
4444
var chunk = new string(reader.ReadChars(4));
4545
var size = reader.ReadUInt32();
4646

47-
if (chunk != "MD21")
48-
Chunks.Add(chunk, size);
49-
5047
switch (chunk)
5148
{
5249
case "MD21":
@@ -64,8 +61,8 @@ public M2Converter(string m2, bool fix_helm) : base(m2)
6461

6562
// Skip to M2Array<Texture>.
6663
reader.ReadBytes(0x50);
67-
textureCount = reader.ReadInt32();
68-
textureOffset = reader.ReadInt32();
64+
textureCount = reader.ReadInt32();
65+
textureOffset = reader.ReadInt32();
6966

7067
reader.BaseStream.Position = offset + size;
7168
break;
@@ -79,8 +76,8 @@ public M2Converter(string m2, bool fix_helm) : base(m2)
7976
}
8077
}
8178

82-
dataSize = Data.Length - (int)CalculateChunksSize() - 8;
83-
texturesSize = CalculateTexturesSize();
79+
stream.Close();
80+
reader.Close();
8481
}
8582

8683
particleCount = ReadInt(0x128);
@@ -111,12 +108,21 @@ public void RemoveLegionChunks()
111108

112109
private void ReadTXID(BinaryReader reader, uint size)
113110
{
114-
for (int i = 0; i < size / 4; i++)
111+
for (var i = 0u; i < size / 4u; i++)
115112
{
116113
var textureId = reader.ReadUInt32();
117114

118-
var filename = Listfile.LookupFilename(textureId, ".m2", modelName).Replace('/', '\\');
119-
Textures.Add(filename + "\0\0", filename.Length);
115+
var filename = Listfile.LookupFilename(textureId, ".m2").Replace('/', '\\');
116+
var texture = new Texture
117+
{
118+
Filename = filename + "\0\0",
119+
FilenameLength = filename.Length
120+
};
121+
122+
if (Textures.ContainsKey(texture))
123+
Textures[texture]++;
124+
else
125+
Textures.Add(texture, 1);
120126
}
121127
}
122128

@@ -128,8 +134,8 @@ public bool Fix()
128134

129135
RemoveLegionChunks();
130136

131-
if (Textures.Count > 0)
132-
FixTXID();
137+
dataSize = Data.Length;
138+
texturesSize = CalculateTexturesSize();
133139

134140
FixCamera();
135141
FixAnimations();
@@ -213,37 +219,43 @@ public bool Fix()
213219
if (fixHelmOffset)
214220
FixHelmOffset();
215221

222+
if (Textures.Count >= 1)
223+
FixTXID();
224+
216225
return true;
217226
}
218227

219228
private void FixTXID()
220229
{
221-
int textureBlockSize = 16;
230+
var textureBlockSize = 4 * sizeof(uint);
231+
var textureKeys = Textures.Keys.ToList();
222232

223233
// Write `0` block at the end of the file.
224-
AddEmptyBytes(dataSize, (int)texturesSize + textureBlockSize);
234+
AddEmptyBytes(Data.Length, (int)texturesSize + textureBlockSize);
225235

226-
for (var i = 0; i < textureCount; ++i)
236+
for (var i = 0; i < Textures.Count; ++i)
227237
{
228-
// TEX_COMPONENT_HARDCODED
229-
var isHarcoded = ReadUInt(textureOffset) == 0;
230-
if (isHarcoded)
238+
var texture = textureKeys[i];
239+
240+
for (var j = 0; j < Textures[texture]; ++j)
231241
{
232-
var texture = Textures.First();
242+
// TEX_COMPONENT_HARDCODED
243+
var isHarcoded = ReadUInt(textureOffset) == 0;
244+
if (isHarcoded)
245+
{
246+
// Write Filename Length and Offset of Filename;
247+
WriteInt(textureOffset + 8, texture.FilenameLength);
248+
WriteInt(textureOffset + 12, dataSize);
233249

234-
// Write Filename Length and Offset of Filename;
235-
WriteUInt(textureOffset + 8, (uint)texture.Value);
236-
WriteUInt(textureOffset + 12, (uint)dataSize);
250+
for (var x = 0; x < texture.Filename.Length; ++x)
251+
WriteChar(dataSize + x, texture.Filename[x]);
237252

238-
for (var j = 0; j < texture.Value; ++j)
239-
WriteChar(dataSize + j, texture.Key[j]);
253+
dataSize += texture.Filename.Length;
254+
}
240255

241-
dataSize += texture.Value + 2;
242-
Textures.Remove(texture.Key);
256+
// Block reading finished, add 4 * sizeof(uint)
257+
textureOffset += textureBlockSize;
243258
}
244-
245-
// Block reading finished, add 16 (4 * sizeof(uint))
246-
textureOffset += textureBlockSize;
247259
}
248260
}
249261

@@ -534,7 +546,7 @@ private void FixSkins()
534546
if (!File.Exists(s))
535547
continue;
536548

537-
SkinConverter sf = new SkinConverter(s);
549+
var sf = new SkinConverter(s);
538550
sf.Fix(ref texture_unit_lookup, ref blend_override, n_transparency_lookup);
539551
skins.Add(sf);
540552
}
@@ -954,22 +966,13 @@ private void ShiftOfsForParticleStruct(uint ofs, uint pos, int shift)
954966
#endregion
955967

956968
#region Calculate Shit
957-
private uint CalculateChunksSize()
958-
{
959-
uint result = 0;
960-
961-
foreach (var chunk in Chunks)
962-
result += chunk.Value + 8; //< Calculate Chunk- and Size Identifiers
963-
964-
return result;
965-
}
966-
967969
private uint CalculateTexturesSize()
968970
{
969-
uint result = 0;
971+
var result = 0u;
970972

971-
foreach (var texture in Textures.Values)
972-
result += (uint)texture + 1;
973+
foreach (var texture in Textures)
974+
for (var i = 0; i < texture.Value; ++i)
975+
result += (uint)texture.Key.FilenameLength + 1;
973976

974977
return result;
975978
}
@@ -984,4 +987,10 @@ public override void Save()
984987
skin.Save();
985988
}
986989
}
990+
991+
public struct Texture
992+
{
993+
public string Filename;
994+
public int FilenameLength;
995+
}
987996
}

0 commit comments

Comments
 (0)