Skip to content

Commit

Permalink
(Rockman X7) Experimental SLDSpline Support
Browse files Browse the repository at this point in the history
Is kinda borked but some info can be gleamed from it.
  • Loading branch information
Knuxfan24 committed Dec 7, 2023
1 parent 5e798a1 commit bc4fdbd
Show file tree
Hide file tree
Showing 4 changed files with 162 additions and 1 deletion.
2 changes: 2 additions & 0 deletions Experimental_Formats.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ The following formats are only partially supported, either due to missing functi

- [Stage Entity Table (.328f438b/.osd)](KnuxLib/Engines/RockmanX7/StageEntityTable.cs). Entirely functional besides basically every value being an unknown.

- [SLD Spline (.6ae91701/.sld)](KnuxLib/Engines/RockmanX7/SLDSpline.cs). Has very basic reading, but half of the file is an unknown placeholder that clearly interacts with the spline points in some ways. Can also export to a basic OBJ.

## Rockman X8 Engine

- [Stage Entity Table (.31bf570e/.set)](KnuxLib/Engines/RockmanX8/StageEntityTable.cs). Entirely functional besides basically every value being an unknown.
Expand Down
149 changes: 149 additions & 0 deletions KnuxLib/Engines/RockmanX7/SLDSpline.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
namespace KnuxLib.Engines.RockmanX7
{
// TODO: Saving.
// TODO: Figure out the unknown data and how it interacts with the points.
// ST08_03 (The inside part of Wind Crowrang's stage) has a branch with an obvious mistake that these numbers might be a part of?
// TODO: What does SLD mean? Scripted Line Definition?
public class SLDSpline : FileBase
{
// Generic VS stuff to allow creating an object that instantly loads a file.
public SLDSpline() { }
public SLDSpline(string filepath, bool export = false)
{
Load(filepath);

if (export)
ExportOBJ($@"{Path.GetDirectoryName(filepath)}\{Path.GetFileNameWithoutExtension(filepath)}.obj");
}

// Classes for this format.
public class FormatData
{
/// <summary>
/// The coordinates for the various vertices that make up this spline.
/// </summary>
public List<Vector3> Vertices { get; set; } = new();

/// <summary>
/// An unknown chunk of data for each vertex.
/// TODO: What is all of this and are the numbers within them actually half floating points?
/// </summary>
public List<UnknownData_1> UnknownData_1 { get; set; } = new();
}

public class UnknownData_1
{
/// <summary>
/// The index of this data. Not actually a thing, just used for reference.
/// </summary>
public int Index { get; set; }

/// <summary>
/// An unknown two byte floating point value (converted to a standard float for ease of reading in JSON).
/// TODO: What is this?
/// </summary>
public float UnknownHalf_1 { get; set; }

/// <summary>
/// An unknown two byte floating point value (converted to a standard float for ease of reading in JSON).
/// TODO: What is this?
/// </summary>
public float UnknownHalf_2 { get; set; }

/// <summary>
/// An unknown two byte floating point value (converted to a standard float for ease of reading in JSON).
/// TODO: What is this?
/// </summary>
public float UnknownHalf_3 { get; set; }

/// <summary>
/// An unknown two byte floating point value (converted to a standard float for ease of reading in JSON).
/// TODO: What is this?
/// </summary>
public float UnknownHalf_4 { get; set; }

/// <summary>
/// An unknown two byte floating point value (converted to a standard float for ease of reading in JSON).
/// TODO: What is this?
/// </summary>
public float UnknownHalf_5 { get; set; }

/// <summary>
/// An unknown two byte floating point value (converted to a standard float for ease of reading in JSON).
/// TODO: What is this?
/// </summary>
public float UnknownHalf_6 { get; set; }

/// <summary>
/// An unknown two byte floating point value (converted to a standard float for ease of reading in JSON).
/// TODO: What is this?
/// </summary>
public float UnknownHalf_7 { get; set; }
}

// Actual data presented to the end user.
public FormatData Data = new();

/// <summary>
/// Loads and parses this format's file.
/// </summary>
/// <param name="filepath">The path to the file to load and parse.</param>
public override void Load(string filepath)
{
// Set up Marathon's BinaryReader.
BinaryReaderEx reader = new(File.OpenRead(filepath));

// Read this file's point count.
ushort pointCount = reader.ReadUInt16();

// Loop through and read this spline's vertices.
for (int pointIndex = 0; pointIndex < pointCount; pointIndex++)
Data.Vertices.Add(reader.ReadVector3());

// Loop through and read this spline's unknown data.
for (int pointIndex = 0; pointIndex < pointCount; pointIndex++)
{
Data.UnknownData_1.Add(new()
{
Index = pointIndex,
UnknownHalf_1 = (float)reader.ReadHalf(),
UnknownHalf_2 = (float)reader.ReadHalf(),
UnknownHalf_3 = (float)reader.ReadHalf(),
UnknownHalf_4 = (float)reader.ReadHalf(),
UnknownHalf_5 = (float)reader.ReadHalf(),
UnknownHalf_6 = (float)reader.ReadHalf(),
UnknownHalf_7 = (float)reader.ReadHalf()
});
}

// Close Marathon's BinaryReader.
reader.Close();
}

/// <summary>
/// Exports the position values from this spline to an OBJ.
/// </summary>
/// <param name="filepath">The filepath to export to.</param>
public void ExportOBJ(string filepath)
{
// Set up the StreamWriter.
StreamWriter obj = new(filepath);

// Write each vertex's positions.
for (int vertexIndex = 0; vertexIndex < Data.Vertices.Count; vertexIndex++)
obj.WriteLine($"v {Data.Vertices[vertexIndex].X} {Data.Vertices[vertexIndex].Y} {Data.Vertices[vertexIndex].Z}");

// Write this path's object name.
obj.WriteLine($"o {Path.GetFileNameWithoutExtension(filepath)}");
obj.WriteLine($"g {Path.GetFileNameWithoutExtension(filepath)}");

// Write this path's object.
obj.Write("l ");
for (int vertexIndex = 0; vertexIndex < Data.Vertices.Count; vertexIndex++)
obj.Write($"{vertexIndex + 1} ");

// Close this StreamWriter.
obj.Close();
}
}
}
3 changes: 3 additions & 0 deletions KnuxLib/Engines/Storybook/PlayerMotionTable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,9 @@ public override void Load(string filepath)
// Save this motion entry.
Data.Add(motion);
}

// Close Marathon's BinaryReader.
reader.Close();
}

/// <summary>
Expand Down
9 changes: 8 additions & 1 deletion KnuxTools/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,8 @@ static void Main(string[] args)
Console.WriteLine("Rockman X7 Engine:");
ColourConsole("Stage Entity Table (.328f438b/.osd)");
ColourConsole(" Extension Flag (Original) - OSD", true, ConsoleColor.Yellow);
ColourConsole(" Extension Flag (Legacy Collection 2) - 328F438B\n", true, ConsoleColor.Yellow);
ColourConsole(" Extension Flag (Legacy Collection 2) - 328F438B", true, ConsoleColor.Yellow);
ColourConsole("SLD Spline (.6ae91701/.sld)\n");

Console.WriteLine("Rockman X8 Engine:");
ColourConsole("Stage Entity Table (.31bf570e/.set)");
Expand Down Expand Up @@ -1229,6 +1230,12 @@ private static void HandleFile(string arg, string? extension, string? version)
using (KnuxLib.Engines.RockmanX7.StageEntityTable stageEntityTable = new(arg, true))
break;

case ".6ae91701":
case ".sld":
Console.WriteLine("Converting Rockman X7 Engine SLD Spline to OBJ.");
using (KnuxLib.Engines.RockmanX7.SLDSpline sldSpline = new(arg, true))
break;

case ".rockmanx7.stageentitytable.json":
// If an extension isn't specified, then ask the user which stage entity table extension to save with.
if (string.IsNullOrEmpty(extension))
Expand Down

0 comments on commit bc4fdbd

Please sign in to comment.