diff --git a/MiloEditor/Images/AnimFilter.png b/MiloEditor/Images/AnimFilter.png new file mode 100644 index 0000000..8a0d9c3 Binary files /dev/null and b/MiloEditor/Images/AnimFilter.png differ diff --git a/MiloEditor/Images/BandStarDisplay.png b/MiloEditor/Images/BandStarDisplay.png new file mode 100644 index 0000000..97e0445 Binary files /dev/null and b/MiloEditor/Images/BandStarDisplay.png differ diff --git a/MiloEditor/Images/Button.png b/MiloEditor/Images/Button.png new file mode 100644 index 0000000..38c84c6 Binary files /dev/null and b/MiloEditor/Images/Button.png differ diff --git a/MiloEditor/Images/CharClip.png b/MiloEditor/Images/CharClip.png new file mode 100644 index 0000000..33de402 Binary files /dev/null and b/MiloEditor/Images/CharClip.png differ diff --git a/MiloEditor/Images/Environ.png b/MiloEditor/Images/Environ.png new file mode 100644 index 0000000..b8305d2 Binary files /dev/null and b/MiloEditor/Images/Environ.png differ diff --git a/MiloEditor/Images/FileMerger.png b/MiloEditor/Images/FileMerger.png new file mode 100644 index 0000000..9de92d3 Binary files /dev/null and b/MiloEditor/Images/FileMerger.png differ diff --git a/MiloEditor/Images/Group.png b/MiloEditor/Images/Group.png new file mode 100644 index 0000000..81a6b6b Binary files /dev/null and b/MiloEditor/Images/Group.png differ diff --git a/MiloEditor/Images/Line.png b/MiloEditor/Images/Line.png new file mode 100644 index 0000000..3564c57 Binary files /dev/null and b/MiloEditor/Images/Line.png differ diff --git a/MiloEditor/Images/Lipsync.png b/MiloEditor/Images/Lipsync.png new file mode 100644 index 0000000..7149333 Binary files /dev/null and b/MiloEditor/Images/Lipsync.png differ diff --git a/MiloEditor/Images/MatAnim.png b/MiloEditor/Images/MatAnim.png new file mode 100644 index 0000000..b26efa6 Binary files /dev/null and b/MiloEditor/Images/MatAnim.png differ diff --git a/MiloEditor/Images/MeshAnim.png b/MiloEditor/Images/MeshAnim.png new file mode 100644 index 0000000..7569b6a Binary files /dev/null and b/MiloEditor/Images/MeshAnim.png differ diff --git a/MiloEditor/Images/MidiInstrument.png b/MiloEditor/Images/MidiInstrument.png new file mode 100644 index 0000000..a055444 Binary files /dev/null and b/MiloEditor/Images/MidiInstrument.png differ diff --git a/MiloEditor/Images/ParticleSys.png b/MiloEditor/Images/ParticleSys.png new file mode 100644 index 0000000..c4b29ea Binary files /dev/null and b/MiloEditor/Images/ParticleSys.png differ diff --git a/MiloEditor/Images/PropAnim.png b/MiloEditor/Images/PropAnim.png new file mode 100644 index 0000000..f721706 Binary files /dev/null and b/MiloEditor/Images/PropAnim.png differ diff --git a/MiloEditor/Images/Sfx.png b/MiloEditor/Images/Sfx.png index 447d6ee..09b74eb 100644 Binary files a/MiloEditor/Images/Sfx.png and b/MiloEditor/Images/Sfx.png differ diff --git a/MiloEditor/Images/TransAnim.png b/MiloEditor/Images/TransAnim.png index 1fde854..26b578a 100644 Binary files a/MiloEditor/Images/TransAnim.png and b/MiloEditor/Images/TransAnim.png differ diff --git a/MiloEditor/Images/TransProxy.png b/MiloEditor/Images/TransProxy.png new file mode 100644 index 0000000..3ff67d7 Binary files /dev/null and b/MiloEditor/Images/TransProxy.png differ diff --git a/MiloEditor/Images/Trigger.png b/MiloEditor/Images/Trigger.png new file mode 100644 index 0000000..a429618 Binary files /dev/null and b/MiloEditor/Images/Trigger.png differ diff --git a/MiloEditor/Images/UILabel.png b/MiloEditor/Images/UILabel.png new file mode 100644 index 0000000..62a849f Binary files /dev/null and b/MiloEditor/Images/UILabel.png differ diff --git a/MiloEditor/MainForm.cs b/MiloEditor/MainForm.cs index c3908cb..e695495 100644 --- a/MiloEditor/MainForm.cs +++ b/MiloEditor/MainForm.cs @@ -45,7 +45,6 @@ private int GetImageIndex(ImageList imageList, string key) private void Form1_Load(object sender, EventArgs e) { - // change title of window to "Milo Editor (version)" this.Text = "Milo Editor (" + Application.ProductVersion + ")"; } @@ -57,6 +56,7 @@ private void quitToolStripMenuItem_Click(object sender, EventArgs e) private void LoadAssetClassImages() { + imageList.ImageSize = new Size(24, 24); imageList.Images.Add("default", Image.FromFile("Images/default.png")); imageList.Images.Add("ObjectDir", Image.FromFile("Images/ObjectDir.png")); imageList.Images.Add("RndDir", Image.FromFile("Images/RndDir.png")); @@ -64,6 +64,7 @@ private void LoadAssetClassImages() imageList.Images.Add("BandSongPref", Image.FromFile("Images/BandSongPref.png")); imageList.Images.Add("Tex", Image.FromFile("Images/RndTex.png")); imageList.Images.Add("TexRenderer", Image.FromFile("Images/RndTex.png")); + imageList.Images.Add("Group", Image.FromFile("Images/Group.png")); imageList.Images.Add("Mat", Image.FromFile("Images/RndMat.png")); imageList.Images.Add("Mesh", Image.FromFile("Images/RndMesh.png")); imageList.Images.Add("MultiMesh", Image.FromFile("Images/RndMultiMesh.png")); @@ -83,7 +84,31 @@ private void LoadAssetClassImages() imageList.Images.Add("BandCrowdMeterDir", Image.FromFile("Images/BandCrowdMeterDir.png")); imageList.Images.Add("Font", Image.FromFile("Images/Font.png")); imageList.Images.Add("Text", Image.FromFile("Images/Text.png")); + imageList.Images.Add("BandList", Image.FromFile("Images/Text.png")); imageList.Images.Add("BandCamShot", Image.FromFile("Images/Camera.png")); + imageList.Images.Add("UIColor", Image.FromFile("Images/UIColor.png")); + imageList.Images.Add("UILabel", Image.FromFile("Images/UILabel.png")); + imageList.Images.Add("BandLabel", Image.FromFile("Images/UILabel.png")); + imageList.Images.Add("CharLipSync", Image.FromFile("Images/Lipsync.png")); + imageList.Images.Add("UIButton", Image.FromFile("Images/Button.png")); + imageList.Images.Add("BandButton", Image.FromFile("Images/Button.png")); + imageList.Images.Add("BandStarDisplay", Image.FromFile("Images/BandStarDisplay.png")); + imageList.Images.Add("Environ", Image.FromFile("Images/Environ.png")); + imageList.Images.Add("PropAnim", Image.FromFile("Images/PropAnim.png")); + imageList.Images.Add("MeshAnim", Image.FromFile("Images/PropAnim.png")); + imageList.Images.Add("Line", Image.FromFile("Images/Line.png")); + imageList.Images.Add("AnimFilter", Image.FromFile("Images/AnimFilter.png")); + imageList.Images.Add("UITrigger", Image.FromFile("Images/Trigger.png")); + imageList.Images.Add("EventTrigger", Image.FromFile("Images/Trigger.png")); + imageList.Images.Add("Cam", Image.FromFile("Images/Camera.png")); + imageList.Images.Add("MeshAnim", Image.FromFile("Images/MeshAnim.png")); + imageList.Images.Add("ParticleSys", Image.FromFile("Images/ParticleSys.png")); + imageList.Images.Add("MatAnim", Image.FromFile("Images/MatAnim.png")); + imageList.Images.Add("CharClip", Image.FromFile("Images/CharClip.png")); + imageList.Images.Add("CharClipSet", Image.FromFile("Images/CharClip.png")); + imageList.Images.Add("MidiInstrument", Image.FromFile("Images/MidiInstrument.png")); + imageList.Images.Add("FileMerger", Image.FromFile("Images/FileMerger.png")); + imageList.Images.Add("TransProxy", Image.FromFile("Images/TransProxy.png")); imageList.Images.Add("", Image.FromFile("Images/NoDir.png")); imageList.ColorDepth = ColorDepth.Depth32Bit; @@ -96,10 +121,10 @@ private void PopulateListWithEntries() throw new Exception("Tried to populate list with milo scene entries when no Milo scene was loaded!"); } - // clear the TreeView of all existing nodes miloSceneItemsTree.Nodes.Clear(); - // clear the editor panel + miloSceneItemsTree.ShowNodeToolTips = true; + splitContainer1.Panel2.Controls.Clear(); miloSceneItemsTree.ImageList = imageList; @@ -113,7 +138,8 @@ private void PopulateListWithEntries() TreeNode rootNode = new TreeNode(rootName, GetImageIndex(imageList, currentMiloScene.dirMeta?.type), GetImageIndex(imageList, currentMiloScene.dirMeta?.type)) { - Tag = currentMiloScene.dirMeta + Tag = currentMiloScene.dirMeta, + ToolTipText = $"{currentMiloScene.dirMeta?.name ?? ""} ({currentMiloScene.dirMeta?.type ?? "Unknown"})" }; miloSceneItemsTree.Nodes.Add(rootNode); @@ -121,7 +147,7 @@ private void PopulateListWithEntries() // Handle inline subdirectories if (currentMiloScene.dirMeta != null && currentMiloScene.dirMeta.directory is ObjectDir objDir && objDir.inlineSubDirs.Count > 0) { - TreeNode inlineSubdirsNode = new TreeNode("Inline Subdirectories", -1, -1); + TreeNode inlineSubdirsNode = new TreeNode("Inline Subdirectories", GetImageIndex(imageList, "ObjectDir"), GetImageIndex(imageList, "ObjectDir")); foreach (var subDir in objDir.inlineSubDirs) { AddDirectoryNode(subDir, inlineSubdirsNode); @@ -148,7 +174,8 @@ private void AddChildNodes(DirectoryMeta parentDirMeta, TreeNode parentNode) { TreeNode node = new TreeNode(entry.name.value, GetImageIndex(imageList, entry.type), GetImageIndex(imageList, entry.type)) { - Tag = entry + Tag = entry, + ToolTipText = $"{entry.name ?? ""} ({entry.type ?? "Unknown"})" }; if (entry.dir != null) @@ -164,7 +191,8 @@ private void AddDirectoryNode(DirectoryMeta dirMeta, TreeNode parentNode) { TreeNode subDirNode = new TreeNode(dirMeta.name.value, GetImageIndex(imageList, dirMeta.type), GetImageIndex(imageList, dirMeta.type)) { - Tag = dirMeta + Tag = dirMeta, + ToolTipText = $"{dirMeta.name ?? ""} ({dirMeta.type ?? "Unknown"})" }; //Recursively add entries diff --git a/MiloEditor/MiloEditor.csproj b/MiloEditor/MiloEditor.csproj index 15fed6f..00ef96d 100644 --- a/MiloEditor/MiloEditor.csproj +++ b/MiloEditor/MiloEditor.csproj @@ -16,15 +16,29 @@ + + + + + + + + + + + + + + @@ -38,35 +52,77 @@ + + + + + Always + Always Always + + Always + + + Always + Always Always + + Always + Always Always + + Always + Always + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + Always + + Always + + + Always + Always @@ -109,9 +165,18 @@ Always + + Always + + + Always + Always + + Always + Always @@ -128,6 +193,12 @@ + + + Always + + + diff --git a/MiloEditor/Panels/BitmapEditor.cs b/MiloEditor/Panels/BitmapEditor.cs index 6a9d459..1bfd02c 100644 --- a/MiloEditor/Panels/BitmapEditor.cs +++ b/MiloEditor/Panels/BitmapEditor.cs @@ -55,11 +55,13 @@ private void RndTexEditor_Load(object sender, EventArgs e) string encodingName = encodingTypeNames.Find(x => x.Item2 == (int)tex.bitmap.encoding).Item1; dataGridView1.Rows.Add("Texture Encoding", encodingName); + dataGridView1.Rows.Add("Number of Mip Maps", tex.bitmap.mipMaps); bitmapBox.SizeMode = PictureBoxSizeMode.Zoom; // convert the tex into a DDS and load it into the picturebox - LoadDdsIntoPictureBox(tex.bitmap.ConvertToImage(), bitmapBox); + if (tex.bitmap.encoding == TextureEncoding.DXT1_BC1 || tex.bitmap.encoding == TextureEncoding.DXT5_BC3 || tex.bitmap.encoding == TextureEncoding.ATI2_BC5) + LoadDdsIntoPictureBox(tex.bitmap.ConvertToImage(), bitmapBox); } private void exportButton_Click(object sender, EventArgs e) diff --git a/MiloLib/Assets/ObjectDir.cs b/MiloLib/Assets/ObjectDir.cs index 339081f..96dbd22 100644 --- a/MiloLib/Assets/ObjectDir.cs +++ b/MiloLib/Assets/ObjectDir.cs @@ -228,6 +228,7 @@ public ObjectDir Read(EndianReader reader, bool standalone, DirectoryMeta parent for (int i = 0; i < inlineSubDirCount; i++) { DirectoryMeta inlineSubDir = new DirectoryMeta(); + inlineSubDir.platform = parent.platform; inlineSubDir.Read(reader); inlineSubDirs.Add(inlineSubDir); } diff --git a/MiloLib/Assets/Rnd/RndGroup.cs b/MiloLib/Assets/Rnd/RndGroup.cs index 7cbe116..47b06ce 100644 --- a/MiloLib/Assets/Rnd/RndGroup.cs +++ b/MiloLib/Assets/Rnd/RndGroup.cs @@ -23,7 +23,7 @@ public class RndGroup : Object [Name("Environ"), MinVersion(16)] public Symbol environ = new(0, ""); - [Name("Draw Only"), Description("If set, only draws this member of the group"), MinVersion(14)] + [Name("Draw Only"), Description("If set, only draws this member of the group"), MinVersion(13)] public Symbol drawOnly = new(0, ""); [Name("LOD"), Description("Object to draw instead below lod_screen_size"), MinVersion(12), MaxVersion(15)] @@ -66,7 +66,7 @@ public RndGroup Read(EndianReader reader, bool standalone, DirectoryMeta parent, if (revision < 16) environ = Symbol.Read(reader); - if (revision > 13) + if (revision > 12) drawOnly = Symbol.Read(reader); } diff --git a/MiloLib/Assets/Rnd/RndTex.cs b/MiloLib/Assets/Rnd/RndTex.cs index 0715342..f3d122f 100644 --- a/MiloLib/Assets/Rnd/RndTex.cs +++ b/MiloLib/Assets/Rnd/RndTex.cs @@ -27,7 +27,7 @@ public class RndTex : Object public uint index2; [MinVersion(11)] - public bool unk; + public bool optimizeForPS3; [Name("Use External Path"), Description("Whether or not to use the external path.")] public bool useExternalPath; @@ -35,6 +35,12 @@ public class RndTex : Object [Name("Bitmap"), Description("The bitmap data.")] public RndBitmap bitmap = new(); + public ushort unkShort; + + public uint unkInt; + public uint unkInt2; + public ushort unkShort2; + public RndTex Read(EndianReader reader, bool standalone, DirectoryMeta parent, DirectoryMeta.Entry entry) { uint combinedRevision = reader.ReadUInt32(); @@ -56,15 +62,32 @@ public RndTex Read(EndianReader reader, bool standalone, DirectoryMeta parent, D index2 = reader.ReadUInt32(); if (revision >= 11) - unk = reader.ReadBoolean(); + optimizeForPS3 = reader.ReadBoolean(); if (revision != 7) useExternalPath = reader.ReadBoolean(); else useExternalPath = reader.ReadUInt32() == 1; + if (parent.platform == DirectoryMeta.Platform.Wii && revision > 10) + unkShort = reader.ReadUInt16(); + + Endian origEndian = reader.Endianness; + + if (parent.platform == DirectoryMeta.Platform.Wii && revision > 10) + reader.Endianness = Endian.LittleEndian; + bitmap = new RndBitmap().Read(reader, false, parent, entry); + reader.Endianness = origEndian; + + if (parent.platform == DirectoryMeta.Platform.Wii && revision > 10) + { + unkInt = reader.ReadUInt32(); + unkInt2 = reader.ReadUInt32(); + unkShort2 = reader.ReadUInt16(); + } + if (standalone) { if ((reader.Endianness == Endian.BigEndian ? 0xADDEADDE : 0xDEADDEAD) != reader.ReadUInt32()) throw new Exception("Got to end of standalone asset but didn't find the expected end bytes, read likely did not succeed"); @@ -92,13 +115,16 @@ public override void Write(EndianWriter writer, bool standalone, DirectoryMeta p writer.WriteUInt32(index2); if (revision >= 11) - writer.WriteBoolean(unk); + writer.WriteBoolean(optimizeForPS3); if (revision != 7) writer.WriteBoolean(useExternalPath); else writer.WriteUInt32(useExternalPath ? 1u : 0u); + if (altRevision == 1) + writer.WriteUInt16(unkShort); + bitmap.Write(writer, false, parent, entry); if (standalone) diff --git a/MiloLib/Assets/UI/UIColor.cs b/MiloLib/Assets/UI/UIColor.cs index 97de5d2..abbd5e8 100644 --- a/MiloLib/Assets/UI/UIColor.cs +++ b/MiloLib/Assets/UI/UIColor.cs @@ -9,10 +9,8 @@ public class UIColor : Object public ushort altRevision; public ushort revision; - public float r; - public float g; - public float b; - public float a; + [Name("Color")] + public HmxColor4 color = new(); public UIColor Read(EndianReader reader, bool standalone, DirectoryMeta parent, DirectoryMeta.Entry entry) { @@ -27,10 +25,7 @@ public UIColor Read(EndianReader reader, bool standalone, DirectoryMeta parent, base.objFields.Read(reader, parent, entry); - r = reader.ReadFloat(); - g = reader.ReadFloat(); - b = reader.ReadFloat(); - a = reader.ReadFloat(); + color.Read(reader); if (standalone) { @@ -46,10 +41,7 @@ public override void Write(EndianWriter writer, bool standalone, DirectoryMeta p base.objFields.Write(writer); - writer.WriteFloat(r); - writer.WriteFloat(g); - writer.WriteFloat(b); - writer.WriteFloat(a); + color.Write(writer); if (standalone) { diff --git a/MiloLib/Assets/WorldDir.cs b/MiloLib/Assets/WorldDir.cs index 2f69c8c..38c1a70 100644 --- a/MiloLib/Assets/WorldDir.cs +++ b/MiloLib/Assets/WorldDir.cs @@ -1,6 +1,7 @@ using MiloLib.Utils; using MiloLib.Classes; using MiloLib.Assets.UI; +using MiloLib.Assets.Rnd; namespace MiloLib.Assets { @@ -57,6 +58,13 @@ public class PresetOverride public Symbol hud = new(0, ""); public Symbol cam = new(0, ""); + public Matrix xfm = new(); + + public uint unkInt1; + public uint unkInt2; + + public Symbol unkSym = new(0, ""); + public WorldDir(ushort revision, ushort altRevision = 0) : base(revision, altRevision) { revision = revision; @@ -76,6 +84,12 @@ public WorldDir Read(EndianReader reader, bool standalone, DirectoryMeta parent, cam = Symbol.Read(reader); } + if (revision >= 2 && revision <= 20) + { + unkInt1 = reader.ReadUInt32(); + unkInt2 = reader.ReadUInt32(); + } + if (revision > 9) { fakeHUDFilename = Symbol.Read(reader); @@ -83,6 +97,13 @@ public WorldDir Read(EndianReader reader, bool standalone, DirectoryMeta parent, base.Read(reader, false, parent, entry); + if (revision < 0x19) + { + if (revision > 0xA) + { + xfm = xfm.Read(reader); + } + } if (revision > 0xB) { @@ -154,6 +175,11 @@ public WorldDir Read(EndianReader reader, bool standalone, DirectoryMeta parent, } } + if (revision == 0x12 || revision == 0x13 || revision == 0x14 || revision == 0x15) + { + unkSym = Symbol.Read(reader); + } + if (revision > 0x12) { mTestPreset1 = Symbol.Read(reader); @@ -184,6 +210,12 @@ public override void Write(EndianWriter writer, bool standalone, DirectoryMeta p Symbol.Write(writer, cam); } + if (revision >= 2 && revision <= 20) + { + writer.WriteUInt32(unkInt1); + writer.WriteUInt32(unkInt2); + } + if (revision > 9) { Symbol.Write(writer, fakeHUDFilename); @@ -191,6 +223,14 @@ public override void Write(EndianWriter writer, bool standalone, DirectoryMeta p base.Write(writer, false, parent, entry); + if (revision < 0x19) + { + if (revision > 0xA) + { + xfm.Write(writer); + } + } + if (revision > 0xB) { writer.WriteUInt32((uint)hideOverrides.Count); @@ -251,6 +291,11 @@ public override void Write(EndianWriter writer, bool standalone, DirectoryMeta p } } + if (revision == 0x12 || revision == 0x13 || revision == 0x14 || revision == 0x15) + { + Symbol.Write(writer, unkSym); + } + if (revision > 0x12) { Symbol.Write(writer, mTestPreset1);