@@ -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