Skip to content

Commit

Permalink
try and keep the order of strings in .mdl the same
Browse files Browse the repository at this point in the history
  • Loading branch information
0ceal0t committed Oct 13, 2024
1 parent de6c63b commit 4aab046
Show file tree
Hide file tree
Showing 10 changed files with 65 additions and 40 deletions.
2 changes: 1 addition & 1 deletion VFXEditor/Formats/MdlFormat/Bone/MdlBoneTable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public virtual void Write( BinaryWriter writer, MdlWriteData data ) {
writer.Write( ( ushort )0 );
continue;
}
writer.Write( ( ushort )data.BoneStrings.IndexOf( Bones[i].Value ) );
writer.Write( ( ushort )data.StringTable.BoneStrings.IndexOf( Bones[i].Value ) );
}

writer.Write( ( byte )Bones.Count );
Expand Down
2 changes: 1 addition & 1 deletion VFXEditor/Formats/MdlFormat/Bone/MdlBoneTables.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public MdlBoneTables() {
}

public MdlBoneTables( BinaryReader reader, int count, MdlFileData data ) : this() {
for( var i = 0; i < count; i++ ) Tables.Add( new( reader, data.BoneStrings ) );
for( var i = 0; i < count; i++ ) Tables.Add( new( reader, data.StringTable.BoneStrings ) );
}

public virtual void Write( BinaryWriter writer, MdlWriteData data ) {
Expand Down
2 changes: 1 addition & 1 deletion VFXEditor/Formats/MdlFormat/Bone/V6/MdlBoneTableV6.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public MdlBoneTableV6( BinaryReader reader, List<string> boneStrings, int count
}

public override void Write( BinaryWriter writer, MdlWriteData data ) {
foreach( var item in Bones ) writer.Write( ( ushort )data.BoneStrings.IndexOf( item.Value ) );
foreach( var item in Bones ) writer.Write( ( ushort )data.StringTable.BoneStrings.IndexOf( item.Value ) );
}
}
}
2 changes: 1 addition & 1 deletion VFXEditor/Formats/MdlFormat/Bone/V6/MdlBoneTablesV6.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public MdlBoneTablesV6( BinaryReader reader, int count, MdlFileData data ) : bas

for( var i = 0; i < count; i++ ) {
var (_, tableCount) = header[i];
Tables.Add( new MdlBoneTableV6( reader, data.BoneStrings, tableCount ) );
Tables.Add( new MdlBoneTableV6( reader, data.StringTable.BoneStrings, tableCount ) );
FileUtils.PadTo( reader, 4 );
}
}
Expand Down
31 changes: 18 additions & 13 deletions VFXEditor/Formats/MdlFormat/MdlFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ public class MdlFile : FileManagerFile {

private readonly uint Version;

private readonly MdlStringTable OldStringTable = new();

private readonly ParsedByteBool IndexBufferStreaming = new( "Index Buffer Streaming" );
private readonly ParsedByteBool EdgeGeometry = new( "Edge Geometry" );
private readonly ParsedFloat Radius = new( "Radius" );
Expand Down Expand Up @@ -133,6 +135,7 @@ public MdlFile( BinaryReader reader, bool verify ) : base() {
var pos = reader.BaseStream.Position - stringStartPos;
var value = FileUtils.ReadString( reader );
data.OffsetToString[( uint )pos] = value;
Dalamud.Log( value );
}

StringTablePadding = ( uint )( stringEndPos - reader.BaseStream.Position );
Expand Down Expand Up @@ -192,12 +195,14 @@ public MdlFile( BinaryReader reader, bool verify ) : base() {
// ===== MESHES ========

for( var i = 0; i < meshCount; i++ ) data.Meshes.Add( new( this, vertexFormats[i], reader ) );
for( var i = 0; i < attributeCount; i++ ) data.AttributeStrings.Add( data.OffsetToString[reader.ReadUInt32()] );
for( var i = 0; i < attributeCount; i++ ) data.StringTable.AttributeStrings.Add( data.OffsetToString[reader.ReadUInt32()] );
for( var i = 0; i < terrainShadowMeshCount; i++ ) data.TerrainShadowMeshes.Add( new( this, reader ) );
for( var i = 0; i < submeshCount; i++ ) data.SubMeshes.Add( new( reader ) );
for( var i = 0; i < terrainShadowSubmeshCount; i++ ) data.TerrainShadowSubmeshes.Add( new( reader ) );
for( var i = 0; i < materialCount; i++ ) data.MaterialStrings.Add( data.OffsetToString[reader.ReadUInt32()] );
for( var i = 0; i < boneCount; i++ ) data.BoneStrings.Add( data.OffsetToString[reader.ReadUInt32()] );
for( var i = 0; i < materialCount; i++ ) data.StringTable.MaterialStrings.Add( data.OffsetToString[reader.ReadUInt32()] );
for( var i = 0; i < boneCount; i++ ) data.StringTable.BoneStrings.Add( data.OffsetToString[reader.ReadUInt32()] );

OldStringTable = data.StringTable;

BoneTables = Version == VERSION_6 ? new MdlBoneTablesV6( reader, boneTableCount, data ) : new MdlBoneTables( reader, boneTableCount, data );

Expand All @@ -219,7 +224,7 @@ public MdlFile( BinaryReader reader, bool verify ) : base() {
ModelBoundingBox = new( reader );
WaterBoundingBox = new( reader );
VerticalFogBoundingBox = new( reader );
for( var i = 0; i < data.BoneStrings.Count; i++ ) BoneBoundingBoxes.Add( new( data.BoneStrings[i], reader ) );
for( var i = 0; i < data.StringTable.BoneStrings.Count; i++ ) BoneBoundingBoxes.Add( new( data.StringTable.BoneStrings[i], reader ) );
for( var i = 0; i < unknownCount; i++ ) UnknownBoundingBoxes.Add( new( reader ) );

// ===== POPULATE =======
Expand Down Expand Up @@ -321,14 +326,14 @@ private void DrawBoxes() {
}

public override void Write( BinaryWriter writer ) {
var data = new MdlWriteData( this );
var data = new MdlWriteData( this, OldStringTable );

writer.Write( Version );
writer.Write( data.Meshes.Count * 136 ); // stack size
var runtimePlaceholder = writer.BaseStream.Position;
writer.Write( 0 ); // placeholder: runtime size
writer.Write( ( ushort )data.Meshes.Count ); // vertex declaration count
writer.Write( ( ushort )data.MaterialStrings.Count );
writer.Write( ( ushort )data.StringTable.MaterialStrings.Count );

var placeholders = writer.BaseStream.Position;
for( var i = 0; i < 12; i++ ) writer.Write( 0 ); // 3 x vertex offsets, 3 x index offsets, 3 x vertex size, 3 x index size
Expand All @@ -349,10 +354,10 @@ public override void Write( BinaryWriter writer ) {

Radius.Write( writer );
writer.Write( ( ushort )data.Meshes.Count );
writer.Write( ( ushort )data.AttributeStrings.Count );
writer.Write( ( ushort )data.StringTable.AttributeStrings.Count );
writer.Write( ( ushort )data.SubMeshes.Count );
writer.Write( ( ushort )data.MaterialStrings.Count );
writer.Write( ( ushort )data.BoneStrings.Count );
writer.Write( ( ushort )data.StringTable.MaterialStrings.Count );
writer.Write( ( ushort )data.StringTable.BoneStrings.Count );
writer.Write( ( ushort )BoneTables.Tables.Count );
writer.Write( ( ushort )data.Shapes.Count );
writer.Write( ( ushort )data.ShapesMeshes.Count );
Expand Down Expand Up @@ -380,12 +385,12 @@ public override void Write( BinaryWriter writer ) {
foreach( var item in ExtraLods ) item.Write( writer, data );

foreach( var item in data.Meshes ) item.Write( writer, data );
foreach( var item in data.AttributeStrings ) writer.Write( data.StringToOffset[item] );
foreach( var item in data.StringTable.AttributeStrings ) writer.Write( data.StringToOffset[item] );
foreach( var item in data.TerrainShadowMeshes ) item.Write( writer, data );
foreach( var item in data.SubMeshes ) item.Write( writer, data );
foreach( var item in data.TerrainShadowSubmeshes ) item.Write( writer );
foreach( var item in data.MaterialStrings ) writer.Write( data.StringToOffset[item] );
foreach( var item in data.BoneStrings ) writer.Write( data.StringToOffset[item] );
foreach( var item in data.StringTable.MaterialStrings ) writer.Write( data.StringToOffset[item] );
foreach( var item in data.StringTable.BoneStrings ) writer.Write( data.StringToOffset[item] );

BoneTables.Write( writer, data );

Expand All @@ -406,7 +411,7 @@ public override void Write( BinaryWriter writer ) {
WaterBoundingBox.Write( writer );
VerticalFogBoundingBox.Write( writer );

foreach( var bone in data.BoneStrings ) {
foreach( var bone in data.StringTable.BoneStrings ) {
if( BoneBoundingBoxes.FindFirst( x => x.Name.Value.Equals( bone ), out var box ) ) {
box.Write( writer );
continue;
Expand Down
4 changes: 2 additions & 2 deletions VFXEditor/Formats/MdlFormat/Mesh/MdlMesh.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ public void Populate( MdlFileData data, BinaryReader reader, int lod ) {
Submeshes.AddRange( data.SubMeshes.GetRange( _SubmeshIndex, _SubmeshCount ) );
foreach( var submesh in Submeshes ) submesh.Populate( this, data, reader, data.IndexBufferOffsets[lod] );

Material.Value = data.MaterialStrings[_MaterialStringIdx];
Material.Value = data.StringTable.MaterialStrings[_MaterialStringIdx];

foreach( var shape in data.Shapes ) Shapes.AddRange( shape.ShapeMeshes[lod].Where( x => x._MeshIndexOffset == _IndexOffset / 2 ) );
}
Expand All @@ -128,7 +128,7 @@ public void Write( BinaryWriter writer, MdlWriteData data ) {
writer.Write( VertexCount );
writer.Write( ( ushort )0 ); // padding
writer.Write( IndexCount );
writer.Write( ( ushort )data.MaterialStrings.IndexOf( Material.Value ) );
writer.Write( ( ushort )data.StringTable.MaterialStrings.IndexOf( Material.Value ) );
data.WriteIndexCount( writer, Submeshes, _SubmeshIndex );
writer.Write( ( ushort )( BoneTableIndex.Value == -1 ? 255 : BoneTableIndex.Value ) );

Expand Down
14 changes: 7 additions & 7 deletions VFXEditor/Formats/MdlFormat/Mesh/MdlSubMesh.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,16 @@ public void Populate( MdlMesh parent, MdlFileData data, BinaryReader reader, uin
for( var i = 0; i < _BoneCount; i++ ) {
var bone = new ParsedString( "##Bone" ) {
Value = ( ( _BoneStartIndex + i ) < data.SubmeshBoneMap.Count ) ?
( data.SubmeshBoneMap[_BoneStartIndex + i] < data.BoneStrings.Count ?
data.BoneStrings[data.SubmeshBoneMap[_BoneStartIndex + i]] : "[ERROR]" ) : "[ERROR]"
( data.SubmeshBoneMap[_BoneStartIndex + i] < data.StringTable.BoneStrings.Count ?
data.StringTable.BoneStrings[data.SubmeshBoneMap[_BoneStartIndex + i]] : "[ERROR]" ) : "[ERROR]"
};
Bones.Add( bone );
}

for( var i = 0; i < data.AttributeStrings.Count; i++ ) {
for( var i = 0; i < data.StringTable.AttributeStrings.Count; i++ ) {
if( ( _AttributeIndexMask & ( 1u << i ) ) != 0 ) {
var attr = new ParsedString( "##Atribute" ) {
Value = ( i < data.AttributeStrings.Count ) ? data.AttributeStrings[i] : "[ERROR]"
Value = ( i < data.StringTable.AttributeStrings.Count ) ? data.StringTable.AttributeStrings[i] : "[ERROR]"
};
Attributes.Add( attr );
}
Expand Down Expand Up @@ -82,9 +82,9 @@ public void Write( BinaryWriter writer, MdlWriteData data ) {

var attributeMask = _AttributeIndexMask;
var selected = Attributes.Select( x => x.Value ).ToList();
for( var i = 0; i < data.AttributeStrings.Count; i++ ) {
for( var i = 0; i < data.StringTable.AttributeStrings.Count; i++ ) {
var value = 1u << i;
if( selected.Contains( data.AttributeStrings[i] ) ) {
if( selected.Contains( data.StringTable.AttributeStrings[i] ) ) {
attributeMask |= value;
}
else {
Expand All @@ -97,7 +97,7 @@ public void Write( BinaryWriter writer, MdlWriteData data ) {
writer.Write( ( ushort )Bones.Count );

foreach( var bone in Bones ) {
data.SubmeshBoneMap.Add( ( ushort )data.BoneStrings.IndexOf( bone.Value ) );
data.SubmeshBoneMap.Add( ( ushort )data.StringTable.BoneStrings.IndexOf( bone.Value ) );
}
}
}
Expand Down
4 changes: 1 addition & 3 deletions VFXEditor/Formats/MdlFormat/Utils/MdlFileData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@ public class MdlFileData {
public readonly List<MdlTerrainShadowSubmesh> TerrainShadowSubmeshes = [];

public readonly Dictionary<uint, string> OffsetToString = [];
public readonly List<string> AttributeStrings = [];
public readonly List<string> MaterialStrings = [];
public readonly List<string> BoneStrings = [];
public MdlStringTable StringTable = new();

public readonly List<ushort> SubmeshBoneMap = [];

Expand Down
9 changes: 9 additions & 0 deletions VFXEditor/Formats/MdlFormat/Utils/MdlStringTable.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using System.Collections.Generic;

namespace VfxEditor.Formats.MdlFormat.Utils {
public class MdlStringTable {
public readonly List<string> AttributeStrings = [];
public readonly List<string> MaterialStrings = [];
public readonly List<string> BoneStrings = [];
}
}
35 changes: 24 additions & 11 deletions VFXEditor/Formats/MdlFormat/Utils/MdlWriteData.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using VfxEditor.Formats.MdlFormat.Lod;
using VfxEditor.Formats.MdlFormat.Mesh;
using VfxEditor.Formats.MdlFormat.Mesh.Shape;
Expand All @@ -8,9 +9,13 @@
namespace VfxEditor.Formats.MdlFormat.Utils {
public class MdlWriteData : MdlFileData {
public uint TotalStringLength { get; private set; } = 0;

public readonly MdlStringTable OldStringTable;

public readonly List<string> AllStrings = [];
public readonly Dictionary<string, uint> StringToOffset = [];
public readonly List<string> ShapeStrings = [];
public readonly List<string> BoneTableStrings = [];

public readonly Dictionary<MdlLod, long> LodPlaceholders = [];

Expand All @@ -25,9 +30,10 @@ public class MdlWriteData : MdlFileData {
public readonly List<List<MdlShapeMesh>> ShapeMeshesPerLod = [[], [], []];
public readonly List<List<MdlShapeValue>> ShapeValuesPerLod = [[], [], []];

public readonly List<string> BoneTableStrings = [];

public MdlWriteData( MdlFile file ) {
public MdlWriteData( MdlFile file, MdlStringTable oldStringTable ) {
OldStringTable = oldStringTable;

for( var j = 0; j < 3; j++ ) {
var vMs = new MemoryStream();
var vWriter = new BinaryWriter( vMs );
Expand All @@ -54,11 +60,11 @@ public MdlWriteData( MdlFile file ) {

// ======= GENERATE STRING OFFSETS ==========

AddStringOffsets( AttributeStrings );
AddStringOffsets( BoneStrings );
AddStringOffsets( MaterialStrings );
AddStringOffsets( BoneTableStrings );
AddStringOffsets( ShapeStrings );
AddStringOffsets( StringTable.AttributeStrings, OldStringTable.AttributeStrings );
AddStringOffsets( StringTable.BoneStrings, OldStringTable.BoneStrings );
AddStringOffsets( StringTable.MaterialStrings, OldStringTable.MaterialStrings );
AddStringOffsets( BoneTableStrings, null );
AddStringOffsets( ShapeStrings, null );
}

public void Dispose() {
Expand Down Expand Up @@ -117,17 +123,24 @@ private static void WriteIndexCount<T>( BinaryWriter writer, List<T> allItems, L

// ========= STRINGS =================

public void AddBone( string item ) => AddString( BoneStrings, item );
public void AddBone( string item ) => AddString( StringTable.BoneStrings, item );
public void AddBoneTable( string item ) => AddString( BoneTableStrings, item );
public void AddAttribute( string item ) => AddString( AttributeStrings, item );
public void AddMaterial( string item ) => AddString( MaterialStrings, item );
public void AddAttribute( string item ) => AddString( StringTable.AttributeStrings, item );
public void AddMaterial( string item ) => AddString( StringTable.MaterialStrings, item );
public void AddShape( string item ) => AddString( ShapeStrings, item );

private static void AddString( List<string> list, string item ) {
if( !list.Contains( item ) ) list.Add( item );
}

private void AddStringOffsets( List<string> list ) {
private void AddStringOffsets( List<string> list, List<string> oldList ) {
// Weird shit to try and keep the order of strings the same, since SE doesn't have a convention for it
if( oldList != null && oldList.Count > 0 ) {
var intersection = oldList.Where( list.Contains ).ToList();
list.RemoveAll( intersection.Contains );
list.InsertRange( 0, intersection );
}

foreach( var item in list ) {
if( AllStrings.Contains( item ) ) continue;
AllStrings.Add( item );
Expand Down

0 comments on commit 4aab046

Please sign in to comment.