Files
SabreTools/SabreTools.DatFiles/Formats/OpenMSX.Reader.cs

178 lines
7.4 KiB
C#
Raw Normal View History

2023-07-31 13:14:42 -04:00
using System;
using System.Linq;
2023-07-31 13:14:42 -04:00
using SabreTools.Core;
using SabreTools.Core.Tools;
2023-07-31 13:14:42 -04:00
using SabreTools.DatItems;
using SabreTools.DatItems.Formats;
namespace SabreTools.DatFiles.Formats
{
/// <summary>
/// Represents parsing an openMSX softawre list XML DAT
/// </summary>
internal partial class OpenMSX : DatFile
{
/// <inheritdoc/>
public override void ParseFile(string filename, int indexId, bool keep, bool statsOnly = false, bool throwOnError = false)
{
try
{
// Deserialize the input file
2023-09-11 01:20:21 -04:00
var softwareDb = new Serialization.Files.OpenMSX().Deserialize(filename);
2023-07-31 13:14:42 -04:00
// Convert the header to the internal format
ConvertHeader(softwareDb);
2023-07-31 13:14:42 -04:00
// Convert the software data to the internal format
ConvertSoftwares(softwareDb?.Software, filename, indexId, statsOnly);
2023-07-31 13:14:42 -04:00
}
catch (Exception ex) when (!throwOnError)
{
string message = $"'{filename}' - An error occurred during parsing";
logger.Error(ex, message);
2023-07-31 13:14:42 -04:00
}
}
#region Converters
2023-07-31 13:14:42 -04:00
/// <summary>
/// Convert header information
2023-07-31 13:14:42 -04:00
/// </summary>
/// <param name="softwaredb">Deserialized model to convert</param>
private void ConvertHeader(Models.OpenMSX.SoftwareDb? softwaredb)
2023-07-31 13:14:42 -04:00
{
// If the datafile is missing, we can't do anything
if (softwaredb == null)
2023-07-31 13:14:42 -04:00
return;
Header.Name ??= "openMSX Software List";
Header.Description ??= Header.Name;
Header.Date ??= softwaredb.Timestamp;
2023-07-31 13:14:42 -04:00
}
/// <summary>
/// Convert softwares information
2023-07-31 13:14:42 -04:00
/// </summary>
/// <param name="softwares">Array of deserialized models to convert</param>
2023-07-31 13:14:42 -04:00
/// <param name="filename">Name of the file to be parsed</param>
/// <param name="indexId">Index ID for the DAT</param>
/// <param name="statsOnly">True to only add item statistics while parsing, false otherwise</param>
private void ConvertSoftwares(Models.OpenMSX.Software[]? softwares, string filename, int indexId, bool statsOnly)
2023-07-31 13:14:42 -04:00
{
// If the software array is missing, we can't do anything
if (softwares == null || !softwares.Any())
return;
2023-07-31 13:14:42 -04:00
// Loop through the software and add
foreach (var software in softwares)
2023-07-31 13:14:42 -04:00
{
ConvertSoftware(software, filename, indexId, statsOnly);
2023-07-31 13:14:42 -04:00
}
}
/// <summary>
/// Convert software information
2023-07-31 13:14:42 -04:00
/// </summary>
/// <param name="software">Deserialized model to convert</param>
2023-07-31 13:14:42 -04:00
/// <param name="filename">Name of the file to be parsed</param>
/// <param name="indexId">Index ID for the DAT</param>
/// <param name="statsOnly">True to only add item statistics while parsing, false otherwise</param>
private void ConvertSoftware(Models.OpenMSX.Software software, string filename, int indexId, bool statsOnly)
2023-07-31 13:14:42 -04:00
{
// If the software is missing, we can't do anything
if (software == null)
return;
2023-07-31 13:14:42 -04:00
// Create the machine for copying information
2024-03-09 23:43:43 -05:00
var machine = new Machine();
machine.SetFieldValue<string?>(Models.Metadata.Machine.CountryKey, software.Country);
machine.SetFieldValue<string?>(Models.Metadata.Machine.GenMSXIDKey, software.GenMSXID);
machine.SetFieldValue<string?>(Models.Metadata.Machine.ManufacturerKey, software.Company);
machine.SetFieldValue<string?>(Models.Metadata.Machine.SystemKey, software.System);
machine.SetFieldValue<string?>(Models.Metadata.Machine.NameKey, software.Title);
machine.SetFieldValue<string?>(Models.Metadata.Machine.YearKey, software.Year);
// Check if there are any items
bool containsItems = false;
ConvertDumps(software.Dump, machine, filename, indexId, statsOnly, ref containsItems);
2023-07-31 13:14:42 -04:00
// If we had no items, create a Blank placeholder
if (!containsItems)
2023-07-31 13:14:42 -04:00
{
var blank = new Blank
2023-07-31 13:14:42 -04:00
{
2024-03-08 21:12:13 -05:00
Source = new Source { Index = indexId, Name = filename },
2023-07-31 13:14:42 -04:00
};
blank.CopyMachineInformation(machine);
ParseAddHelper(blank, statsOnly);
}
2023-07-31 13:14:42 -04:00
}
/// <summary>
/// Convert Dump information
2023-07-31 13:14:42 -04:00
/// </summary>
/// <param name="dumps">Array of deserialized models to convert</param>
/// <param name="machine">Prefilled machine to use</param>
2023-07-31 13:14:42 -04:00
/// <param name="filename">Name of the file to be parsed</param>
/// <param name="indexId">Index ID for the DAT</param>
/// <param name="statsOnly">True to only add item statistics while parsing, false otherwise</param>
/// <param name="containsItems">True if there were any items in the array, false otherwise</param>
private void ConvertDumps(Models.OpenMSX.Dump[]? dumps, Machine machine, string filename, int indexId, bool statsOnly, ref bool containsItems)
2023-07-31 13:14:42 -04:00
{
// If the dumps array is missing, we can't do anything
if (dumps == null || !dumps.Any())
return;
2023-07-31 13:14:42 -04:00
containsItems = true;
int index = 0;
foreach (var dump in dumps)
2023-07-31 13:14:42 -04:00
{
// If we don't have rom data, we can't do anything
if (dump?.Rom == null)
2023-07-31 13:14:42 -04:00
continue;
var rom = dump.Rom;
2023-07-31 13:14:42 -04:00
2024-03-09 23:43:43 -05:00
string name = $"{machine.GetFieldValue<string?>(Models.Metadata.Machine.NameKey)}_{index++}{(!string.IsNullOrEmpty(rom.Remark) ? $" {rom.Remark}" : string.Empty)}";
var item = new Rom
2023-07-31 13:14:42 -04:00
{
2024-03-08 21:12:13 -05:00
Source = new Source { Index = indexId, Name = filename },
2023-07-31 13:14:42 -04:00
};
2024-03-08 20:42:24 -05:00
item.SetName(name);
2024-03-09 21:34:26 -05:00
item.SetFieldValue<string?>(Models.Metadata.Rom.OffsetKey, dump.Rom?.Start);
item.SetFieldValue<string?>(Models.Metadata.Rom.OpenMSXType, rom.Type);
item.SetFieldValue<string?>(Models.Metadata.Rom.RemarkKey, rom.Remark);
item.SetFieldValue<string?>(Models.Metadata.Rom.SHA1Key, rom.Hash);
2023-07-31 13:14:42 -04:00
if (dump.Original != null)
2023-07-31 13:14:42 -04:00
{
2024-03-09 21:34:26 -05:00
item.SetFieldValue<Original?>("ORIGINAL", new Original
{
Value = dump.Original.Value.AsYesNo(),
Content = dump.Original.Content,
2024-03-09 21:34:26 -05:00
});
2023-07-31 13:14:42 -04:00
}
switch (dump.Rom)
2023-07-31 13:14:42 -04:00
{
case Models.OpenMSX.Rom:
2024-03-09 21:34:26 -05:00
item.SetFieldValue<OpenMSXSubType>(Models.Metadata.Rom.OpenMSXMediaType, OpenMSXSubType.Rom);
2023-07-31 13:14:42 -04:00
break;
case Models.OpenMSX.MegaRom:
2024-03-09 21:34:26 -05:00
item.SetFieldValue<OpenMSXSubType>(Models.Metadata.Rom.OpenMSXMediaType, OpenMSXSubType.MegaRom);
2023-07-31 13:14:42 -04:00
break;
case Models.OpenMSX.SCCPlusCart:
2024-03-09 21:34:26 -05:00
item.SetFieldValue<OpenMSXSubType>(Models.Metadata.Rom.OpenMSXMediaType, OpenMSXSubType.SCCPlusCart);
2023-07-31 13:14:42 -04:00
break;
}
item.CopyMachineInformation(machine);
ParseAddHelper(item, statsOnly);
2023-07-31 13:14:42 -04:00
}
}
#endregion
2023-07-31 13:14:42 -04:00
}
}