diff --git a/OpenLocoTool/DatFileParsing/ByteReader.cs b/OpenLocoTool/DatFileParsing/ByteReader.cs index c3891340..be3d9f6f 100644 --- a/OpenLocoTool/DatFileParsing/ByteReader.cs +++ b/OpenLocoTool/DatFileParsing/ByteReader.cs @@ -1,6 +1,5 @@ namespace OpenLocoTool.DatFileParsing { - public static class ByteReader { public static object ReadT(ReadOnlySpan data, Type t, int offset, int arrLength = 0) @@ -120,7 +119,7 @@ public static ILocoStruct ReadLocoStruct(ReadOnlySpan data, Type t) var arrLength = 0; if (p.PropertyType.IsArray) { - var arrLengthAttr = AttributeHelper.Get(p) ?? throw new ArgumentOutOfRangeException(nameof(LocoArrayLengthAttribute), $"type {t} with property {p} didn't have LocoArrayLength attribute specified"); + var arrLengthAttr = AttributeHelper.Get(p) ?? throw new ArgumentOutOfRangeException(nameof(data), $"type {t} with property {p} didn't have LocoArrayLength attribute specified"); arrLength = arrLengthAttr.Length; } diff --git a/OpenLocoTool/DatFileParsing/ByteWriter.cs b/OpenLocoTool/DatFileParsing/ByteWriter.cs index 8afe1919..3af75a66 100644 --- a/OpenLocoTool/DatFileParsing/ByteWriter.cs +++ b/OpenLocoTool/DatFileParsing/ByteWriter.cs @@ -8,39 +8,32 @@ public static void WriteT(Span data, Type t, int offset, object val) { ByteWriterT.Write(data, offset, (uint8_t)(dynamic)val); } - else if (t == typeof(int8_t)) { ByteWriterT.Write(data, offset, (int8_t)(dynamic)val); } - else if (t == typeof(uint16_t)) { ByteWriterT.Write(data, offset, (uint16_t)(dynamic)val); } - else if (t == typeof(int16_t)) { ByteWriterT.Write(data, offset, (int16_t)(dynamic)val); } - else if (t == typeof(uint32_t)) { ByteWriterT.Write(data, offset, (uint32_t)(dynamic)val); } - else if (t == typeof(int32_t)) { ByteWriterT.Write(data, offset, (int32_t)(dynamic)val); } - else if (t == typeof(string_id)) { // string ids should always be 0 in the dat file - they're only set when loaded into memory and never saved val = 0; ByteWriterT.Write(data, offset, (string_id)(dynamic)val); } - else if (t.IsArray) { var elementType = t.GetElementType() ?? throw new NullReferenceException(); @@ -53,14 +46,12 @@ public static void WriteT(Span data, Type t, int offset, object val) WriteT(data, elementType, offset + (i * size), value); } } - else if (t.IsEnum) { var underlyingType = t.GetEnumUnderlyingType(); var underlyingValue = Convert.ChangeType(val, underlyingType); WriteT(data, underlyingType, offset, underlyingValue); } - else if (t.IsClass) { var objectSize = ByteHelpers.GetObjectSize(t); @@ -89,7 +80,6 @@ public static ReadOnlySpan WriteLocoStruct(ILocoStruct obj) var t = obj.GetType(); var objSize = ByteHelpers.GetObjectSize(t); var buf = new byte[objSize]; - var span = buf.AsSpan(); foreach (var p in t.GetProperties()) { @@ -112,7 +102,7 @@ public static ReadOnlySpan WriteLocoStruct(ILocoStruct obj) var arrLength = 0; if (p.PropertyType.IsArray) { - var arrLengthAttr = AttributeHelper.Get(p) ?? throw new ArgumentOutOfRangeException(nameof(LocoArrayLengthAttribute), $"type {t} with property {p} didn't have LocoArrayLength attribute specified"); + var arrLengthAttr = AttributeHelper.Get(p) ?? throw new ArgumentOutOfRangeException(nameof(obj), $"type {t} with property {p} didn't have LocoArrayLength attribute specified"); arrLength = arrLengthAttr.Length; } diff --git a/OpenLocoTool/DatFileParsing/ILocoObject.cs b/OpenLocoTool/DatFileParsing/ILocoObject.cs index e0b47280..d399c2f4 100644 --- a/OpenLocoTool/DatFileParsing/ILocoObject.cs +++ b/OpenLocoTool/DatFileParsing/ILocoObject.cs @@ -10,7 +10,7 @@ public interface ILocoObject ObjectHeader ObjectHeader { get; set; } ILocoStruct Object { get; set; } StringTable StringTable { get; set; } - G1Header G1Header { get; set; } - List G1Elements { get; set; } + G1Header? G1Header { get; set; } + List? G1Elements { get; set; } } } diff --git a/OpenLocoTool/DatFileParsing/SawyerStreamReader.cs b/OpenLocoTool/DatFileParsing/SawyerStreamReader.cs index b4e6a3f8..0be66308 100644 --- a/OpenLocoTool/DatFileParsing/SawyerStreamReader.cs +++ b/OpenLocoTool/DatFileParsing/SawyerStreamReader.cs @@ -7,7 +7,7 @@ namespace OpenLocoTool.DatFileParsing { - public class SawyerStreamReader(ILogger logger) + public static class SawyerStreamReader { static uint ComputeObjectChecksum(ReadOnlySpan flagByte, ReadOnlySpan name, ReadOnlySpan data) { @@ -107,7 +107,7 @@ public static ILocoObject LoadFull(string filename, ILogger? logger = null, bool remainingData = locoStructExtra.Load(remainingData); } - LocoObject newObj = null; + LocoObject? newObj; try { // some objects have graphics data diff --git a/OpenLocoTool/DatFileParsing/SawyerStreamWriter.cs b/OpenLocoTool/DatFileParsing/SawyerStreamWriter.cs index 5a8e9825..9828ef12 100644 --- a/OpenLocoTool/DatFileParsing/SawyerStreamWriter.cs +++ b/OpenLocoTool/DatFileParsing/SawyerStreamWriter.cs @@ -41,6 +41,7 @@ public static ReadOnlySpan WriteLocoObject(ILocoObject obj) ms.Write(strBytes, 0, strBytes.Length); ms.WriteByte((byte)'\0'); } + ms.WriteByte(0xff); } @@ -58,7 +59,7 @@ public static ReadOnlySpan WriteLocoObject(ILocoObject obj) ms.Write(BitConverter.GetBytes(obj.G1Header.NumEntries)); ms.Write(BitConverter.GetBytes(obj.G1Elements.Sum(x => G1Element32.StructLength + x.ImageData.Length))); - int idx = 0; + var idx = 0; // write G1Elements foreach (var g1Element in obj.G1Elements) { diff --git a/OpenLocoTool/DatFileParsing/Typedefs.cs b/OpenLocoTool/DatFileParsing/Typedefs.cs index 88d571bc..14d67fd6 100644 --- a/OpenLocoTool/DatFileParsing/Typedefs.cs +++ b/OpenLocoTool/DatFileParsing/Typedefs.cs @@ -25,7 +25,7 @@ public record Pos2( public class StringTable { - public Dictionary> table { get; set; } = new(); + public Dictionary> table { get; set; } = []; public void Add(string key, Dictionary value) => table.Add(key, value); diff --git a/OpenLocoTool/Headers/G1Header.cs b/OpenLocoTool/Headers/G1Header.cs index 2fee3265..48a1c8f1 100644 --- a/OpenLocoTool/Headers/G1Header.cs +++ b/OpenLocoTool/Headers/G1Header.cs @@ -30,7 +30,7 @@ public record G1Element32( ) : ILocoStruct { public static int StructLength => 0x10; - public byte[] ImageData; + public byte[] ImageData = []; public ReadOnlySpan Write() { @@ -67,6 +67,6 @@ public record G1Header( ) : ILocoStruct { public static int StructLength => 0x08; - public byte[] ImageData; + public byte[] ImageData = []; } } diff --git a/OpenLocoTool/Objects/BuildingObject.cs b/OpenLocoTool/Objects/BuildingObject.cs index fcdb7ff0..836ac2ad 100644 --- a/OpenLocoTool/Objects/BuildingObject.cs +++ b/OpenLocoTool/Objects/BuildingObject.cs @@ -77,7 +77,6 @@ public ReadOnlySpan Load(ReadOnlySpan remainingData) remainingData = remainingData[(S5Header.StructLength * var_A4.Length)..]; // load ?? - var ptr_AD = 0; for (var i = 0; i < var_AD; ++i) { var size = BitConverter.ToUInt16(remainingData[..2]); diff --git a/OpenLocoTool/Objects/SoundObject.cs b/OpenLocoTool/Objects/SoundObject.cs index 6a15a4e6..a349ac1d 100644 --- a/OpenLocoTool/Objects/SoundObject.cs +++ b/OpenLocoTool/Objects/SoundObject.cs @@ -55,7 +55,7 @@ public ReadOnlySpan Load(ReadOnlySpan remainingData) remainingData = remainingData[4..]; // pcm data length - var pcmDataLength = BitConverter.ToUInt32(remainingData[0..4]); + //var pcmDataLength = BitConverter.ToUInt32(remainingData[0..4]); // unused remainingData = remainingData[4..]; remainingData = remainingData[(int)(numUnkStructs * 16)..]; @@ -66,9 +66,7 @@ public ReadOnlySpan Load(ReadOnlySpan remainingData) RawPcmData = remainingData.ToArray(); - remainingData = remainingData[remainingData.Length..]; - - return remainingData; + return remainingData[remainingData.Length..]; } public ReadOnlySpan Save() => throw new NotImplementedException(); diff --git a/OpenLocoTool/Objects/TrainStationObject.cs b/OpenLocoTool/Objects/TrainStationObject.cs index 55788f1e..0856b606 100644 --- a/OpenLocoTool/Objects/TrainStationObject.cs +++ b/OpenLocoTool/Objects/TrainStationObject.cs @@ -42,7 +42,7 @@ public record TrainStationObject( public const int Var6ELength = 16; uint8_t[,] CargoOffsetBytes { get; set; } - uint8_t[] var_6E { get; set; } + uint8_t[] var_6E { get; set; } = []; public ReadOnlySpan Load(ReadOnlySpan remainingData) { diff --git a/OpenLocoToolGui/MainForm.cs b/OpenLocoToolGui/MainForm.cs index ed92d6b1..a0a0545a 100644 --- a/OpenLocoToolGui/MainForm.cs +++ b/OpenLocoToolGui/MainForm.cs @@ -9,13 +9,6 @@ namespace OpenLocoToolGui { - // how this program works - // - // 1. open UI, no loading - // 2. user selects a directory - // 3. if no open-loco-tool index file exists, open-loco-tool fully loads all dat files in directory, creates an index and writes it to `objectIndex.json` in that folder. this is SLOW (currently) - // 4. next time that directory is opened, the index is read instead of loading all files. this is FAST - public partial class MainForm : Form { readonly MainFormModel model; @@ -364,7 +357,7 @@ private void saveChangesToolStripMenuItem_Click(object sender, EventArgs e) try { var exists = File.Exists(filename); - model.SaveFile(filename, obj); + MainFormModel.SaveFile(filename, obj); if (!exists) { @@ -731,11 +724,11 @@ private void RefreshObjectUI() flpImageTable.ResumeLayout(true); - pgS5Header.SelectedObject = CurrentUIObject.S5Header; - pgObjHeader.SelectedObject = CurrentUIObject.ObjectHeader; - pgObject.SelectedObject = CurrentUIObject.Object; - ucStringTable.SetDataBinding(CurrentUIObject.StringTable); - //pgS5Header.SelectedObject = CurrentUIObject; // dont above with flpImageTable + pgS5Header.SelectedObject = CurrentUIObject?.S5Header; + pgObjHeader.SelectedObject = CurrentUIObject?.ObjectHeader; + pgObject.SelectedObject = CurrentUIObject?.Object; + ucStringTable.SetDataBinding(CurrentUIObject?.StringTable); + //pgS5Header.SelectedObject = CurrentUIObject; // done above with flpImageTable } private void imgContextMenuSave_Click(object sender, EventArgs e) diff --git a/OpenLocoToolGui/MainFormModel.cs b/OpenLocoToolGui/MainFormModel.cs index cf217c1b..626c275c 100644 --- a/OpenLocoToolGui/MainFormModel.cs +++ b/OpenLocoToolGui/MainFormModel.cs @@ -212,7 +212,7 @@ void CreateIndex(string[] allFiles, IProgress progress) logger.Info($"Finished creating index. Time={sw.Elapsed}"); } - public void SaveFile(string path, ILocoObject obj) + public static void SaveFile(string path, ILocoObject obj) => SawyerStreamWriter.Save(path, obj); public bool LoadDataDirectory(string directory) diff --git a/README.md b/README.md index a5006945..fcf3fdb6 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,13 @@ # OpenLocoTool A modern implementation of 'LocoTool' for dat file parsing +# GUI + +1. open UI, no loading +2. user selects a directory +3. if no open-loco-tool index file exists, open-loco-tool fully loads all dat files in directory, creates an index and writes it to `objectIndex.json` in that folder. this is SLOW (currently) +4. next time that directory is opened, the index is read instead of loading all files. this is FAST + # Dat Object Layout |-File-------------------------------|