Skip to content

Commit

Permalink
Lots of random dirs, fix saving uncompressed scenes
Browse files Browse the repository at this point in the history
  • Loading branch information
ihatecompvir committed Jan 1, 2025
1 parent 51682f4 commit f150e0e
Show file tree
Hide file tree
Showing 52 changed files with 1,208 additions and 342 deletions.
110 changes: 50 additions & 60 deletions MiloEditor/MainForm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,85 +104,75 @@ private void PopulateListWithEntries()
miloSceneItemsTree.ImageList = imageList;

// add a root node for the Milo scene and its dir
if (currentMiloScene.dirMeta.directory == null)
string rootName = currentMiloScene.dirMeta?.name ?? "Scene Has No Root Directory";
if (string.IsNullOrEmpty(rootName))
{
currentMiloScene.dirMeta.name = "Scene Has No Root Directory";
rootName = "<empty name>";
}
else if (currentMiloScene.dirMeta.name == "")
{
currentMiloScene.dirMeta.name = "<empty name>";
}
TreeNode rootNode = new TreeNode(currentMiloScene.dirMeta.name, GetImageIndex(imageList, currentMiloScene.dirMeta.type), GetImageIndex(imageList, currentMiloScene.dirMeta.type))

TreeNode rootNode = new TreeNode(rootName, GetImageIndex(imageList, currentMiloScene.dirMeta?.type), GetImageIndex(imageList, currentMiloScene.dirMeta?.type))
{
Tag = currentMiloScene.dirMeta
};

miloSceneItemsTree.Nodes.Add(rootNode);


if (currentMiloScene.dirMeta.type != "")
// Handle inline subdirectories
if (currentMiloScene.dirMeta != null && currentMiloScene.dirMeta.directory is ObjectDir objDir && objDir.inlineSubDirs.Count > 0)
{
// Check if there are any inline subdirectories
var inlineSubDirs = ((ObjectDir)currentMiloScene.dirMeta.directory).inlineSubDirs;
if (inlineSubDirs.Count > 0)
TreeNode inlineSubdirsNode = new TreeNode("Inline Subdirectories", -1, -1);
foreach (var subDir in objDir.inlineSubDirs)
{
// Add a parent node for inline subdirectories
TreeNode inlineSubdirsNode = new TreeNode("Inline Subdirectories", -1, -1);
AddDirectoryNode(subDir, inlineSubdirsNode);
}
rootNode.Nodes.Add(inlineSubdirsNode);
}

foreach (DirectoryMeta subDir in inlineSubDirs)
{
// Create a node for the subdirectory
TreeNode subDirNode = new TreeNode(subDir.name.value, GetImageIndex(imageList, subDir.type), GetImageIndex(imageList, subDir.type))
{
Tag = subDir
};

foreach (DirectoryMeta.Entry entry in subDir.entries)
{
TreeNode node = new TreeNode(entry.name.value, GetImageIndex(imageList, entry.type), GetImageIndex(imageList, entry.type))
{
Tag = entry
};
subDirNode.Nodes.Add(node);
}
// Add root entries
if (currentMiloScene.dirMeta != null)
AddChildNodes(currentMiloScene.dirMeta, rootNode);

// Add the subdirectory node to the Inline Subdirectories node
inlineSubdirsNode.Nodes.Add(subDirNode);
}
// onclick handlers so the tree view actually functions
// first we remove any existing handlers then add some to prevent any weird dupe issues
miloSceneItemsTree.NodeMouseClick -= MiloSceneItemsTree_NodeMouseClick;
miloSceneItemsTree.NodeMouseClick += MiloSceneItemsTree_NodeMouseClick;
}

// Add the Inline Subdirectories node to the root
rootNode.Nodes.Add(inlineSubdirsNode);
}
}
private void AddChildNodes(DirectoryMeta parentDirMeta, TreeNode parentNode)
{
if (parentDirMeta == null || parentDirMeta.entries == null) return; //Added null check.

// add all the nodes for the children of the root dir
foreach (DirectoryMeta.Entry entry in currentMiloScene.dirMeta.entries)
foreach (DirectoryMeta.Entry entry in parentDirMeta.entries)
{
TreeNode node = new TreeNode(entry.name.value, GetImageIndex(imageList, entry.type), GetImageIndex(imageList, entry.type))
{
Tag = entry
};

// detect if it is a directory
if (entry.dir != null)
{

foreach (DirectoryMeta.Entry dirEntry in entry.dir.entries)
{
TreeNode dirNode = new TreeNode(dirEntry.name.value, GetImageIndex(imageList, dirEntry.type), GetImageIndex(imageList, dirEntry.type))
{
Tag = dirEntry
};
node.Nodes.Add(dirNode);
}
AddChildNodes(entry.dir, node);
}
rootNode.Nodes.Add(node);

parentNode.Nodes.Add(node);
}
}

// onclick handlers so the tree view actually functions
// first we remove any existing handlers then add some to prevent any weird dupe issues
miloSceneItemsTree.NodeMouseClick -= MiloSceneItemsTree_NodeMouseClick;
miloSceneItemsTree.NodeMouseClick += MiloSceneItemsTree_NodeMouseClick;
private void AddDirectoryNode(DirectoryMeta dirMeta, TreeNode parentNode)
{
TreeNode subDirNode = new TreeNode(dirMeta.name.value, GetImageIndex(imageList, dirMeta.type), GetImageIndex(imageList, dirMeta.type))
{
Tag = dirMeta
};

//Recursively add entries
if (dirMeta != null)
{
AddChildNodes(dirMeta, subDirNode);
}

parentNode.Nodes.Add(subDirNode);
}

private void MiloSceneItemsTree_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
Expand Down Expand Up @@ -489,26 +479,26 @@ private void ImportAsset(TreeNode node)
switch (entry.type.value)
{
case "Tex":
entry.obj = new RndTex().Read(reader, false, directoryEntry);
entry.obj = new RndTex().Read(reader, false, directoryEntry, entry);
break;
case "Group":
entry.obj = new RndGroup().Read(reader, false, directoryEntry);
entry.obj = new RndGroup().Read(reader, false, directoryEntry, entry);
break;
case "Trans":
entry.obj = new RndTrans().Read(reader, false, directoryEntry);
entry.obj = new RndTrans().Read(reader, false, directoryEntry, entry);
break;
case "BandSongPref":
entry.obj = new BandSongPref().Read(reader, false, directoryEntry);
entry.obj = new BandSongPref().Read(reader, false, directoryEntry, entry);
break;
case "Sfx":
entry.obj = new Sfx().Read(reader, false, directoryEntry);
entry.obj = new Sfx().Read(reader, false, directoryEntry, entry);
break;
case "BandCharDesc":
entry.obj = new BandCharDesc().Read(reader, false, directoryEntry);
entry.obj = new BandCharDesc().Read(reader, false, directoryEntry, entry);
break;
default:
Debug.WriteLine("Unknown asset type: " + entry.type.value);
entry.obj = new Object().Read(reader, false, directoryEntry);
entry.obj = new Object().Read(reader, false, directoryEntry, entry);
break;
}
}
Expand Down
4 changes: 2 additions & 2 deletions MiloLib/Assets/Band/BandCharDesc.cs
Original file line number Diff line number Diff line change
Expand Up @@ -305,12 +305,12 @@ public class BandCharDesc : Object
public uint head2;


public BandCharDesc Read(EndianReader reader, bool standalone, DirectoryMeta parent)
public BandCharDesc Read(EndianReader reader, bool standalone, DirectoryMeta parent, DirectoryMeta.Entry entry)

Check warning on line 308 in MiloLib/Assets/Band/BandCharDesc.cs

View workflow job for this annotation

GitHub Actions / build

'BandCharDesc.Read(EndianReader, bool, DirectoryMeta, DirectoryMeta.Entry)' hides inherited member 'Object.Read(EndianReader, bool, DirectoryMeta, DirectoryMeta.Entry)'. Use the new keyword if hiding was intended.
{
uint combinedRevision = reader.ReadUInt32();
if (BitConverter.IsLittleEndian) (revision, altRevision) = ((ushort)(combinedRevision & 0xFFFF), (ushort)((combinedRevision >> 16) & 0xFFFF));
else (altRevision, revision) = ((ushort)(combinedRevision & 0xFFFF), (ushort)((combinedRevision >> 16) & 0xFFFF));
base.Read(reader, false, parent);
base.Read(reader, false, parent, entry);

if (revision > 0x10)
prefab = Symbol.Read(reader);
Expand Down
6 changes: 3 additions & 3 deletions MiloLib/Assets/Band/BandCharacter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,13 @@ public BandCharacter(ushort revision, ushort altRevision = 0) : base(revision, a
return;
}

public BandCharacter Read(EndianReader reader, bool standalone, DirectoryMeta parent)
public BandCharacter Read(EndianReader reader, bool standalone, DirectoryMeta parent, DirectoryMeta.Entry entry)

Check warning on line 37 in MiloLib/Assets/Band/BandCharacter.cs

View workflow job for this annotation

GitHub Actions / build

'BandCharacter.Read(EndianReader, bool, DirectoryMeta, DirectoryMeta.Entry)' hides inherited member 'Character.Read(EndianReader, bool, DirectoryMeta, DirectoryMeta.Entry)'. Use the new keyword if hiding was intended.
{
uint combinedRevision = reader.ReadUInt32();
if (BitConverter.IsLittleEndian) (revision, altRevision) = ((ushort)(combinedRevision & 0xFFFF), (ushort)((combinedRevision >> 16) & 0xFFFF));
else (altRevision, revision) = ((ushort)(combinedRevision & 0xFFFF), (ushort)((combinedRevision >> 16) & 0xFFFF));

base.Read(reader, false, parent);
base.Read(reader, false, parent, entry);

playFlags = reader.ReadInt32();
tempo = Symbol.Read(reader);
Expand All @@ -65,7 +65,7 @@ public BandCharacter Read(EndianReader reader, bool standalone, DirectoryMeta pa

if (revision != 0)
{
testPrefab = testPrefab.Read(reader, false, parent);
testPrefab = testPrefab.Read(reader, false, parent, entry);
}

if (revision == 2 || revision == 3 || revision == 4)
Expand Down
72 changes: 50 additions & 22 deletions MiloLib/Assets/Band/BandCrowdMeterDir.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,57 +17,85 @@ public class BandCrowdMeterDir : RndDir

private uint colorCount;

[MinVersion(2)]
[Name("Colors"), Description("The colors that will be shown as the meter decreases."), MinVersion(2)]
public List<HmxColor4> colors = new();

[MinVersion(1)]
[Name("Peak Value"), Description("Peak state value"), MinVersion(1)]
public float peakValue;

private float groupCount;

[MaxVersion(2)]
private List<Symbol> groups = new();

public uint unkInt;

[Name("Needle Anim"), Description("anim to drive the needle")]
public Symbol needleAnim = new(0, "");
[Name("Warning Anim"), Description("animation that is played when below the warning level")]
public Symbol warningAnim = new(0, "");
[Name("Red Anim"), Description("animation that is played when in the red state")]
public Symbol redAnim = new(0, "");
[Name("Yellow Anim"), Description("animation that is played when in the yellow state")]
public Symbol yellowAnim = new(0, "");
[Name("Green Anim"), Description("animation that is played when in the green state")]
public Symbol greenAnim = new(0, "");


public BandCrowdMeterDir(ushort revision, ushort altRevision = 0) : base(revision, altRevision)
{
revision = revision;
altRevision = altRevision;
return;
}

public BandCrowdMeterDir Read(EndianReader reader, bool standalone, DirectoryMeta parent)
public BandCrowdMeterDir Read(EndianReader reader, bool standalone, DirectoryMeta parent, DirectoryMeta.Entry entry)
{
uint combinedRevision = reader.ReadUInt32();
if (BitConverter.IsLittleEndian) (revision, altRevision) = ((ushort)(combinedRevision & 0xFFFF), (ushort)((combinedRevision >> 16) & 0xFFFF));
else (altRevision, revision) = ((ushort)(combinedRevision & 0xFFFF), (ushort)((combinedRevision >> 16) & 0xFFFF));

if (revision > 3)
// despite being the same revision this is a way different asset in GH2, so try to detect if its being loaded out of a GH2-versioned scene, so check if the version is 25 or earlier
if (parent.revision <= 25)
{
throw new UnsupportedAssetRevisionException("BandCrowdMeterDir", revision);
}
unkInt = reader.ReadUInt32();

if (revision < 3)
{
groupCount = reader.ReadUInt32();
for (int i = 0; i < groupCount; i++)
{
groups.Add(Symbol.Read(reader));
}
}
warningAnim = Symbol.Read(reader);
redAnim = Symbol.Read(reader);
yellowAnim = Symbol.Read(reader);
greenAnim = Symbol.Read(reader);
needleAnim = Symbol.Read(reader);

if (revision >= 2)
}
else
{
colorCount = reader.ReadUInt32();
for (int i = 0; i < colorCount; i++)
// fields only read when dir is not proxied
if (!entry.isDir)
{
colors.Add(new HmxColor4().Read(reader));
if (revision < 3)
{
groupCount = reader.ReadUInt32();
for (int i = 0; i < groupCount; i++)
{
groups.Add(Symbol.Read(reader));
}
}

if (revision >= 2)
{
colorCount = reader.ReadUInt32();
for (int i = 0; i < colorCount; i++)
{
colors.Add(new HmxColor4().Read(reader));
}
}
}
}

if (revision >= 1)
peakValue = reader.ReadFloat();
if (revision >= 1)
peakValue = reader.ReadFloat();
}

base.Read(reader, false, parent);
base.Read(reader, false, parent, entry);

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");
Expand Down
8 changes: 4 additions & 4 deletions MiloLib/Assets/Band/BandPlacer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,16 @@ public class BandPlacer : Object

public Symbol center = new(0, "");

public BandPlacer Read(EndianReader reader, bool standalone, DirectoryMeta parent)
public BandPlacer Read(EndianReader reader, bool standalone, DirectoryMeta parent, DirectoryMeta.Entry entry)
{
uint combinedRevision = reader.ReadUInt32();
if (BitConverter.IsLittleEndian) (revision, altRevision) = ((ushort)(combinedRevision & 0xFFFF), (ushort)((combinedRevision >> 16) & 0xFFFF));
else (altRevision, revision) = ((ushort)(combinedRevision & 0xFFFF), (ushort)((combinedRevision >> 16) & 0xFFFF));

base.objFields = base.objFields.Read(reader, parent);
base.objFields = base.objFields.Read(reader, parent, entry);

draw = draw.Read(reader, false, parent);
trans = trans.Read(reader, false, parent);
draw = draw.Read(reader, false, parent, entry);
trans = trans.Read(reader, false, parent, entry);

center = Symbol.Read(reader);

Expand Down
57 changes: 57 additions & 0 deletions MiloLib/Assets/Band/BandScoreboard.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
using MiloLib.Assets.Rnd;
using MiloLib.Classes;
using MiloLib.Utils;

namespace MiloLib.Assets.Band
{
[Name("BandScoreboard"), Description("Scoreboard HUD element including stars")]
public class BandScoreboard : RndDir
{
public ushort altRevision;
public ushort revision;

public Symbol sym = new(0, "");

public BandScoreboard(ushort revision, ushort altRevision = 0) : base(revision, altRevision)
{
revision = revision;
altRevision = altRevision;
return;
}

public BandScoreboard Read(EndianReader reader, bool standalone, DirectoryMeta parent, DirectoryMeta.Entry entry)
{
uint combinedRevision = reader.ReadUInt32();
if (BitConverter.IsLittleEndian) (revision, altRevision) = ((ushort)(combinedRevision & 0xFFFF), (ushort)(combinedRevision >> 16 & 0xFFFF));
else (altRevision, revision) = ((ushort)(combinedRevision & 0xFFFF), (ushort)(combinedRevision >> 16 & 0xFFFF));

if (!entry.isDir)
{
sym = Symbol.Read(reader);
}

base.Read(reader, false, parent, entry);

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");

return this;
}

public override void Write(EndianWriter writer, bool standalone)
{
writer.WriteUInt32(BitConverter.IsLittleEndian ? (uint)(altRevision << 16 | revision) : (uint)(revision << 16 | altRevision));

base.Write(writer, false);

if (standalone)
writer.WriteBlock(new byte[4] { 0xAD, 0xDE, 0xAD, 0xDE });
}

public override bool IsDirectory()
{
return true;
}

}
}
Loading

0 comments on commit f150e0e

Please sign in to comment.