using System.Collections.Generic; using System.Linq; using SabreTools.Core; using SabreTools.Core.Tools; using SabreTools.DatItems.Formats; namespace SabreTools.DatFiles { public partial class DatFile { #region To Metadata /// /// Convert metadata information /// public Models.Metadata.MetadataFile? ConvertMetadata(bool ignoreblanks = false) { // If we don't have items, we can't do anything if (this.Items == null || !this.Items.Any()) return null; // Create an object to hold the data var metadataFile = new Models.Metadata.MetadataFile(); // Convert and assign the header var header = ConvertHeader(); if (header != null) metadataFile[Models.Metadata.MetadataFile.HeaderKey] = header; // Convert and assign the machines var machines = ConvertMachines(ignoreblanks); if (machines != null) metadataFile[Models.Metadata.MetadataFile.MachineKey] = machines; return metadataFile; } /// /// Convert header information /// private Models.Metadata.Header? ConvertHeader() { // If the header is invalid, we can't do anything if (Header == null) return null; // Create an internal header var header = Header.GetInternalClone(); // Remove fields with default values if (header.Read(Models.Metadata.Header.ForceMergingKey) == Core.MergingFlag.None) header.Remove(Models.Metadata.Header.ForceMergingKey); if (header.Read(Models.Metadata.Header.ForceNodumpKey) == Core.NodumpFlag.None) header.Remove(Models.Metadata.Header.ForceNodumpKey); if (header.Read(Models.Metadata.Header.ForcePackingKey) == Core.PackingFlag.None) header.Remove(Models.Metadata.Header.ForcePackingKey); // Convert subheader values if (Header.CanOpenSpecified) header[Models.Metadata.Header.CanOpenKey] = new Models.OfflineList.CanOpen { Extension = Header.GetStringArrayFieldValue(Models.Metadata.Header.CanOpenKey) }; if (Header.ImagesSpecified) header[Models.Metadata.Header.ImagesKey] = Header.GetFieldValue(Models.Metadata.Header.ImagesKey); if (Header.InfosSpecified) { var infoItem = new Models.OfflineList.Infos(); var infos = Header.GetFieldValue(Models.Metadata.Header.InfosKey)!; foreach (var info in infos) { switch (info.Name) { case "title": infoItem.Title = new Models.OfflineList.Title { Visible = info.Visible.FromYesNo(), InNamingOption = info.InNamingOption.FromYesNo(), Default = info.Default.FromYesNo(), }; break; case "location": infoItem.Location = new Models.OfflineList.Location { Visible = info.Visible.FromYesNo(), InNamingOption = info.InNamingOption.FromYesNo(), Default = info.Default.FromYesNo(), }; break; case "publisher": infoItem.Publisher = new Models.OfflineList.Publisher { Visible = info.Visible.FromYesNo(), InNamingOption = info.InNamingOption.FromYesNo(), Default = info.Default.FromYesNo(), }; break; case "sourceRom": infoItem.SourceRom = new Models.OfflineList.SourceRom { Visible = info.Visible.FromYesNo(), InNamingOption = info.InNamingOption.FromYesNo(), Default = info.Default.FromYesNo(), }; break; case "saveType": infoItem.SaveType = new Models.OfflineList.SaveType { Visible = info.Visible.FromYesNo(), InNamingOption = info.InNamingOption.FromYesNo(), Default = info.Default.FromYesNo(), }; break; case "romSize": infoItem.RomSize = new Models.OfflineList.RomSize { Visible = info.Visible.FromYesNo(), InNamingOption = info.InNamingOption.FromYesNo(), Default = info.Default.FromYesNo(), }; break; case "releaseNumber": infoItem.ReleaseNumber = new Models.OfflineList.ReleaseNumber { Visible = info.Visible.FromYesNo(), InNamingOption = info.InNamingOption.FromYesNo(), Default = info.Default.FromYesNo(), }; break; case "languageNumber": infoItem.LanguageNumber = new Models.OfflineList.LanguageNumber { Visible = info.Visible.FromYesNo(), InNamingOption = info.InNamingOption.FromYesNo(), Default = info.Default.FromYesNo(), }; break; case "comment": infoItem.Comment = new Models.OfflineList.Comment { Visible = info.Visible.FromYesNo(), InNamingOption = info.InNamingOption.FromYesNo(), Default = info.Default.FromYesNo(), }; break; case "romCRC": infoItem.RomCRC = new Models.OfflineList.RomCRC { Visible = info.Visible.FromYesNo(), InNamingOption = info.InNamingOption.FromYesNo(), Default = info.Default.FromYesNo(), }; break; case "im1CRC": infoItem.Im1CRC = new Models.OfflineList.Im1CRC { Visible = info.Visible.FromYesNo(), InNamingOption = info.InNamingOption.FromYesNo(), Default = info.Default.FromYesNo(), }; break; case "im2CRC": infoItem.Im2CRC = new Models.OfflineList.Im2CRC { Visible = info.Visible.FromYesNo(), InNamingOption = info.InNamingOption.FromYesNo(), Default = info.Default.FromYesNo(), }; break; case "languages": infoItem.Languages = new Models.OfflineList.Languages { Visible = info.Visible.FromYesNo(), InNamingOption = info.InNamingOption.FromYesNo(), Default = info.Default.FromYesNo(), }; break; } } header[Models.Metadata.Header.InfosKey] = infoItem; } if (Header.NewDatSpecified) { var newDat = new Models.OfflineList.NewDat { DatVersionUrl = Header.GetStringFieldValue("DATVERSIONURL"), DatUrl = Header.GetFieldValue("DATURL"), ImUrl = Header.GetStringFieldValue("IMURL"), }; header[Models.Metadata.Header.NewDatKey] = newDat; } if (Header.SearchSpecified) header[Models.Metadata.Header.SearchKey] = Header.GetFieldValue(Models.Metadata.Header.SearchKey); return header; } /// /// Convert machines information /// private Models.Metadata.Machine[]? ConvertMachines(bool ignoreblanks = false) { // Create a machine list to hold all outputs var machines = new List(); // Loop through the sorted items and create games for them foreach (string key in Items.SortedKeys) { var items = Items.FilteredItems(key); if (items == null || !items.Any()) continue; // Create a machine to hold everything var machine = items[0].GetFieldValue(DatItems.DatItem.MachineKey)!.GetInternalClone(); // Handle Trurip object, if it exists if (machine.ContainsKey(Models.Metadata.Machine.TruripKey)) { var trurip = machine.Read(Models.Metadata.Machine.TruripKey); if (trurip != null) { var truripItem = trurip.ConvertToLogiqx(); truripItem.Publisher = machine.ReadString(Models.Metadata.Machine.PublisherKey); truripItem.Year = machine.ReadString(Models.Metadata.Machine.YearKey); truripItem.Players = machine.ReadString(Models.Metadata.Machine.PlayersKey); truripItem.Source = machine.ReadString(Models.Metadata.Machine.SourceFileKey); truripItem.CloneOf = machine.ReadString(Models.Metadata.Machine.CloneOfKey); machine[Models.Metadata.Machine.TruripKey] = truripItem; } } // Create mapping dictionaries for the Parts, DataAreas, and DiskAreas associated with this machine Dictionary partMappings = []; Dictionary<(Models.Metadata.Part, Models.Metadata.DataArea), Models.Metadata.Rom> dataAreaMapping = []; Dictionary<(Models.Metadata.Part, Models.Metadata.DiskArea), Models.Metadata.Disk> diskAreaMapping = []; // Loop through and convert the items to respective lists for (int index = 0; index < items.Count; index++) { // Get the item var item = items[index]; // Check for a "null" item item = ProcessNullifiedItem(item); // Skip if we're ignoring the item if (ShouldIgnore(item, ignoreblanks)) continue; switch (item) { case DatItems.Formats.Adjuster adjuster: var adjusterItem = ProcessItem(adjuster); EnsureMachineKey(machine, Models.Metadata.Machine.AdjusterKey); AppendToMachineKey(machine, Models.Metadata.Machine.AdjusterKey, adjusterItem); break; case DatItems.Formats.Archive archive: var archiveItem = archive.GetInternalClone(); EnsureMachineKey(machine, Models.Metadata.Machine.ArchiveKey); AppendToMachineKey(machine, Models.Metadata.Machine.ArchiveKey, archiveItem); break; case DatItems.Formats.BiosSet biosSet: var biosSetItem = biosSet.GetInternalClone(); EnsureMachineKey(machine, Models.Metadata.Machine.BiosSetKey); AppendToMachineKey(machine, Models.Metadata.Machine.BiosSetKey, biosSetItem); break; case DatItems.Formats.Chip chip: var chipItem = chip.GetInternalClone(); EnsureMachineKey(machine, Models.Metadata.Machine.ChipKey); AppendToMachineKey(machine, Models.Metadata.Machine.ChipKey, chipItem); break; case DatItems.Formats.Configuration configuration: var configurationItem = ProcessItem(configuration); EnsureMachineKey(machine, Models.Metadata.Machine.ConfigurationKey); AppendToMachineKey(machine, Models.Metadata.Machine.ConfigurationKey, configurationItem); break; case DatItems.Formats.Device device: var deviceItem = ProcessItem(device); EnsureMachineKey(machine, Models.Metadata.Machine.DeviceKey); AppendToMachineKey(machine, Models.Metadata.Machine.DeviceKey, deviceItem); break; case DatItems.Formats.DeviceRef deviceRef: var deviceRefItem = deviceRef.GetInternalClone(); EnsureMachineKey(machine, Models.Metadata.Machine.DeviceRefKey); AppendToMachineKey(machine, Models.Metadata.Machine.DeviceRefKey, deviceRefItem); break; case DatItems.Formats.DipSwitch dipSwitch: var dipSwitchItem = ProcessItem(dipSwitch); EnsureMachineKey(machine, Models.Metadata.Machine.DipSwitchKey); AppendToMachineKey(machine, Models.Metadata.Machine.DipSwitchKey, dipSwitchItem); // Add Part mapping bool dipSwitchContainsPart = dipSwitchItem.ContainsKey(DatItems.Formats.DipSwitch.PartKey); if (dipSwitchContainsPart) { var partItem = dipSwitchItem.Read(DatItems.Formats.DipSwitch.PartKey); if (partItem != null) partMappings[partItem.GetInternalClone()] = dipSwitchItem; } break; case DatItems.Formats.Disk disk: var diskItem = disk.GetInternalClone(); EnsureMachineKey(machine, Models.Metadata.Machine.DiskKey); AppendToMachineKey(machine, Models.Metadata.Machine.DiskKey, diskItem); // Add Part and DiskArea mappings bool diskContainsPart = diskItem.ContainsKey(DatItems.Formats.Disk.PartKey); bool diskContainsDiskArea = diskItem.ContainsKey(DatItems.Formats.Disk.DiskAreaKey); if (diskContainsPart && diskContainsDiskArea) { var partItem = diskItem.Read(DatItems.Formats.Disk.PartKey); if (partItem != null) partMappings[partItem.GetInternalClone()] = diskItem; var diskAreaItem = diskItem.Read(DatItems.Formats.Disk.DiskAreaKey); if (diskAreaItem != null) diskAreaMapping[(partItem!.GetInternalClone(), diskAreaItem.GetInternalClone())] = diskItem; } break; case DatItems.Formats.Display display: var displayItem = ProcessItem(display, machine); EnsureMachineKey(machine, Models.Metadata.Machine.DisplayKey); AppendToMachineKey(machine, Models.Metadata.Machine.DisplayKey, displayItem); break; case DatItems.Formats.Driver driver: var driverItem = driver.GetInternalClone(); EnsureMachineKey(machine, Models.Metadata.Machine.DriverKey); AppendToMachineKey(machine, Models.Metadata.Machine.DriverKey, driverItem); break; case DatItems.Formats.Feature feature: var featureItem = feature.GetInternalClone(); EnsureMachineKey(machine, Models.Metadata.Machine.FeatureKey); AppendToMachineKey(machine, Models.Metadata.Machine.FeatureKey, featureItem); break; case DatItems.Formats.Info info: var infoItem = info.GetInternalClone(); EnsureMachineKey(machine, Models.Metadata.Machine.InfoKey); AppendToMachineKey(machine, Models.Metadata.Machine.InfoKey, infoItem); break; case DatItems.Formats.Input input: var inputItem = ProcessItem(input); EnsureMachineKey(machine, Models.Metadata.Machine.InputKey); AppendToMachineKey(machine, Models.Metadata.Machine.InputKey, inputItem); break; case DatItems.Formats.Media media: var mediaItem = media.GetInternalClone(); EnsureMachineKey(machine, Models.Metadata.Machine.MediaKey); AppendToMachineKey(machine, Models.Metadata.Machine.MediaKey, mediaItem); break; case DatItems.Formats.PartFeature partFeature: var partFeatureItem = partFeature.GetInternalClone(); EnsureMachineKey(machine, Models.Metadata.Machine.FeatureKey); AppendToMachineKey(machine, Models.Metadata.Machine.FeatureKey, partFeatureItem); // Add Part mapping bool partFeatureContainsPart = partFeatureItem.ContainsKey(DatItems.Formats.PartFeature.PartKey); if (partFeatureContainsPart) { var partItem = partFeatureItem.Read(DatItems.Formats.PartFeature.PartKey); if (partItem != null) partMappings[partItem.GetInternalClone()] = partFeatureItem; } break; case DatItems.Formats.Port port: var portItem = ProcessItem(port); EnsureMachineKey(machine, Models.Metadata.Machine.PortKey); AppendToMachineKey(machine, Models.Metadata.Machine.PortKey, portItem); break; case DatItems.Formats.RamOption ramOption: var ramOptionItem = ramOption.GetInternalClone(); EnsureMachineKey(machine, Models.Metadata.Machine.RamOptionKey); AppendToMachineKey(machine, Models.Metadata.Machine.RamOptionKey, ramOptionItem); break; case DatItems.Formats.Release release: var releaseItem = release.GetInternalClone(); EnsureMachineKey(machine, Models.Metadata.Machine.ReleaseKey); AppendToMachineKey(machine, Models.Metadata.Machine.ReleaseKey, releaseItem); break; case DatItems.Formats.Rom rom: var romItem = ProcessItem(rom, machine); EnsureMachineKey(machine, Models.Metadata.Machine.RomKey); AppendToMachineKey(machine, Models.Metadata.Machine.RomKey, romItem); // Add Part and DataArea mappings bool romContainsPart = romItem.ContainsKey(DatItems.Formats.Rom.PartKey); bool romContainsDataArea = romItem.ContainsKey(DatItems.Formats.Rom.DataAreaKey); if (romContainsPart && romContainsDataArea) { var partItem = romItem.Read(DatItems.Formats.Rom.PartKey); if (partItem != null) partMappings[partItem.GetInternalClone()] = romItem; var dataAreaItem = romItem.Read(DatItems.Formats.Rom.DataAreaKey); if (dataAreaItem != null) dataAreaMapping[(partItem!.GetInternalClone(), dataAreaItem.GetInternalClone())] = romItem; } break; case DatItems.Formats.Sample sample: var sampleItem = sample.GetInternalClone(); EnsureMachineKey(machine, Models.Metadata.Machine.SampleKey); AppendToMachineKey(machine, Models.Metadata.Machine.SampleKey, sampleItem); break; case DatItems.Formats.SharedFeat sharedFeat: var sharedFeatItem = sharedFeat.GetInternalClone(); EnsureMachineKey(machine, Models.Metadata.Machine.SharedFeatKey); AppendToMachineKey(machine, Models.Metadata.Machine.SharedFeatKey, sharedFeatItem); break; case DatItems.Formats.Slot slot: var slotItem = ProcessItem(slot); EnsureMachineKey(machine, Models.Metadata.Machine.SlotKey); AppendToMachineKey(machine, Models.Metadata.Machine.SlotKey, slotItem); break; case DatItems.Formats.SoftwareList softwareList: var softwareListItem = softwareList.GetInternalClone(); EnsureMachineKey(machine, Models.Metadata.Machine.SoftwareListKey); AppendToMachineKey(machine, Models.Metadata.Machine.SoftwareListKey, softwareListItem); break; case DatItems.Formats.Sound sound: var soundItem = sound.GetInternalClone(); EnsureMachineKey(machine, Models.Metadata.Machine.SoundKey); AppendToMachineKey(machine, Models.Metadata.Machine.SoundKey, soundItem); break; } } // Handle Part, DiskItem, and DatItem mappings, if they exist if (partMappings.Any()) { // TODO: How do we aggregate the parts? // // One Part can contain multiple DataArea, DiskArea, DipSwitch, Feature (PartFeature) // One DataArea can contain multiple Rom // One DiskArea can contain multiple Disk // // If there is a DataArea mapping for the item, then we must have a Rom // If there is a DiskArea mapping for the item, then we must have a Disk // If neither exists, either it's either a DipSwitch or a Feature (PartFeature) // // If there's no DataArea mapping for a Rom, don't include it at all // If there's no DiskArea mapping for a Disk, don't include it at all // Create a collection to hold the inverted Parts Dictionary partItems = []; // Loop through the Part mappings foreach (var partMapping in partMappings) { // If the item has a DataArea mapping // If the item has a DiskArea mapping // Add the nested items to the Part // Aggregate in the part items dictionary based on Part name } // Assign the part array to the machine machine[Models.Metadata.Machine.PartKey] = partItems.Values.ToArray(); } // Add the machine to the list machines.Add(machine); } // Return the list of machines return [.. machines]; } /// /// Convert Adjuster information /// /// Item to convert private static Models.Metadata.Adjuster ProcessItem(DatItems.Formats.Adjuster item) { var adjusterItem = item.GetInternalClone(); var condition = item.GetFieldValue(Models.Metadata.Adjuster.ConditionKey); if (condition != null) adjusterItem[Models.Metadata.Adjuster.ConditionKey] = condition.GetInternalClone(); return adjusterItem; } /// /// Convert Configuration information /// /// Item to convert private static Models.Metadata.Configuration ProcessItem(DatItems.Formats.Configuration item) { var configurationItem = item.GetInternalClone(); var condition = item.GetFieldValue(Models.Metadata.Configuration.ConditionKey); if (condition != null) configurationItem[Models.Metadata.Configuration.ConditionKey] = condition.GetInternalClone(); var confLocations = item.GetFieldValue(Models.Metadata.Configuration.ConfLocationKey); if (confLocations != null) { var confLocationItems = new List(); foreach (var confLocation in confLocations) { var confLocationItem = confLocation.GetInternalClone(); confLocationItems.Add(confLocationItem); } configurationItem[Models.Metadata.Configuration.ConfLocationKey] = confLocationItems.ToArray(); } var confSettings = item.GetFieldValue(Models.Metadata.Configuration.ConfSettingKey); if (confSettings != null) { var confSettingItems = new List(); foreach (var confSetting in confSettings) { var confSettingItem = confSetting.GetInternalClone(); confSettingItems.Add(confSettingItem); } configurationItem[Models.Metadata.Configuration.ConfSettingKey] = confSettingItems.ToArray(); } return configurationItem; } /// /// Convert Device information /// /// Item to convert private static Models.Metadata.Device ProcessItem(DatItems.Formats.Device item) { var deviceItem = item.GetInternalClone(); var instance = item.GetFieldValue(Models.Metadata.Device.InstanceKey); if (instance != null) deviceItem[Models.Metadata.Device.InstanceKey] = instance.GetInternalClone(); var extensions = item.GetFieldValue(Models.Metadata.Device.ExtensionKey); if (extensions != null) { var extensionItems = new List(); foreach (var extension in extensions) { var extensionItem = extension.GetInternalClone(); extensionItems.Add(extensionItem); } deviceItem[Models.Metadata.Device.ExtensionKey] = extensionItems.ToArray(); } return deviceItem; } /// /// Convert DipSwitch information /// /// Item to convert /// Machine to use for Part private static Models.Metadata.DipSwitch ProcessItem(DatItems.Formats.DipSwitch item) { var dipSwitchItem = item.GetInternalClone(); var condition = item.GetFieldValue(Models.Metadata.DipSwitch.ConditionKey); if (condition != null) dipSwitchItem[Models.Metadata.DipSwitch.ConditionKey] = condition.GetInternalClone(); var dipLocations = item.GetFieldValue(Models.Metadata.DipSwitch.DipLocationKey); if (dipLocations != null) { var dipLocationItems = new List(); foreach (var dipLocation in dipLocations) { var extensionItem = dipLocation.GetInternalClone(); dipLocationItems.Add(extensionItem); } dipSwitchItem[Models.Metadata.DipSwitch.DipLocationKey] = dipLocationItems.ToArray(); } var dipValues = item.GetFieldValue(Models.Metadata.DipSwitch.DipValueKey); if (dipValues != null) { var dipValueItems = new List(); foreach (var dipValue in dipValues) { var extensionItem = dipValue.GetInternalClone(); dipValueItems.Add(extensionItem); } dipSwitchItem[Models.Metadata.DipSwitch.DipValueKey] = dipValueItems.ToArray(); } return dipSwitchItem; } /// /// Convert Display information /// /// Item to convert /// Machine to use for Video private static Models.Metadata.Display ProcessItem(DatItems.Formats.Display item, Models.Metadata.Machine machine) { var displayItem = item.GetInternalClone(); // Create a Video for any item that has specific fields if (displayItem.ContainsKey(Models.Metadata.Video.AspectXKey)) { var videoItem = new Models.Metadata.Video(); videoItem[Models.Metadata.Video.AspectXKey] = displayItem.ReadLong(Models.Metadata.Video.AspectXKey).ToString(); videoItem[Models.Metadata.Video.AspectYKey] = displayItem.ReadLong(Models.Metadata.Video.AspectYKey).ToString(); videoItem[Models.Metadata.Video.HeightKey] = displayItem.ReadLong(Models.Metadata.Display.HeightKey).ToString(); videoItem[Models.Metadata.Video.RefreshKey] = displayItem.ReadDouble(Models.Metadata.Display.RefreshKey).ToString(); videoItem[Models.Metadata.Video.ScreenKey] = displayItem.ReadString(Models.Metadata.Display.DisplayTypeKey).AsEnumValue().AsStringValue(); videoItem[Models.Metadata.Video.WidthKey] = displayItem.ReadLong(Models.Metadata.Display.WidthKey).ToString(); EnsureMachineKey(machine, Models.Metadata.Machine.VideoKey); AppendToMachineKey(machine, Models.Metadata.Machine.VideoKey, videoItem); } return displayItem; } /// /// Convert Input information /// /// Item to convert private static Models.Metadata.Input ProcessItem(DatItems.Formats.Input item) { var inputItem = item.GetInternalClone(); var controls = item.GetFieldValue(Models.Metadata.Input.ControlKey); if (controls != null) { var controlItems = new List(); foreach (var control in controls) { var controlItem = control.GetInternalClone(); controlItems.Add(controlItem); } inputItem[Models.Metadata.Input.ControlKey] = controlItems.ToArray(); } return inputItem; } /// /// Convert Port information /// /// Item to convert private static Models.Metadata.Port ProcessItem(DatItems.Formats.Port item) { var slotItem = item.GetInternalClone(); var analogs = item.GetFieldValue(Models.Metadata.Port.AnalogKey); if (analogs != null) { var analogItems = new List(); foreach (var analog in analogs) { var extensionItem = analog.GetInternalClone(); analogItems.Add(extensionItem); } slotItem[Models.Metadata.Port.AnalogKey] = analogItems.ToArray(); } return slotItem; } /// /// Convert Rom information /// /// Item to convert /// Machine to use for Part and DataArea private static Models.Metadata.Rom ProcessItem(DatItems.Formats.Rom item, Models.Metadata.Machine machine) { var romItem = item.GetInternalClone(); // Create a Dump for every Rom that has a subtype switch (romItem.ReadString(Models.Metadata.Rom.OpenMSXMediaType).AsEnumValue()) { case OpenMSXSubType.Rom: var dumpRom = new Models.Metadata.Dump(); var rom = new Models.Metadata.Rom(); rom[Models.Metadata.Rom.NameKey] = romItem.ReadString(Models.Metadata.Rom.NameKey); rom[Models.Metadata.Rom.OffsetKey] = romItem.ReadString(Models.Metadata.Rom.StartKey) ?? romItem.ReadString(Models.Metadata.Rom.OffsetKey); rom[Models.Metadata.Rom.OpenMSXType] = romItem.ReadString(Models.Metadata.Rom.OpenMSXType); rom[Models.Metadata.Rom.RemarkKey] = romItem.ReadString(Models.Metadata.Rom.RemarkKey); rom[Models.Metadata.Rom.SHA1Key] = romItem.ReadString(Models.Metadata.Rom.SHA1Key); rom[Models.Metadata.Rom.StartKey] = romItem.ReadString(Models.Metadata.Rom.StartKey) ?? romItem.ReadString(Models.Metadata.Rom.OffsetKey); dumpRom[Models.Metadata.Dump.RomKey] = rom; var romOriginal = romItem.Read("ORIGINAL"); if (romOriginal != null) { var newOriginal = new Models.Metadata.Original { [Models.Metadata.Original.ValueKey] = romOriginal.Value.FromYesNo(), [Models.Metadata.Original.ContentKey] = romOriginal.Content, }; dumpRom[Models.Metadata.Dump.OriginalKey] = newOriginal; } EnsureMachineKey(machine, Models.Metadata.Machine.DumpKey); AppendToMachineKey(machine, Models.Metadata.Machine.DumpKey, dumpRom); break; case OpenMSXSubType.MegaRom: var dumpMegaRom = new Models.Metadata.Dump(); var megaRom = new Models.Metadata.Rom(); megaRom[Models.Metadata.Rom.NameKey] = romItem.ReadString(Models.Metadata.Rom.NameKey); megaRom[Models.Metadata.Rom.OffsetKey] = romItem.ReadString(Models.Metadata.Rom.StartKey) ?? romItem.ReadString(Models.Metadata.Rom.OffsetKey); megaRom[Models.Metadata.Rom.OpenMSXType] = romItem.ReadString(Models.Metadata.Rom.OpenMSXType); megaRom[Models.Metadata.Rom.RemarkKey] = romItem.ReadString(Models.Metadata.Rom.RemarkKey); megaRom[Models.Metadata.Rom.SHA1Key] = romItem.ReadString(Models.Metadata.Rom.SHA1Key); megaRom[Models.Metadata.Rom.StartKey] = romItem.ReadString(Models.Metadata.Rom.StartKey) ?? romItem.ReadString(Models.Metadata.Rom.OffsetKey); dumpMegaRom[Models.Metadata.Dump.MegaRomKey] = megaRom; var megaRomOriginal = romItem.Read("ORIGINAL"); if (megaRomOriginal != null) { var newOriginal = new Models.Metadata.Original { [Models.Metadata.Original.ValueKey] = megaRomOriginal.Value.FromYesNo(), [Models.Metadata.Original.ContentKey] = megaRomOriginal.Content, }; dumpMegaRom[Models.Metadata.Dump.OriginalKey] = newOriginal; } EnsureMachineKey(machine, Models.Metadata.Machine.DumpKey); AppendToMachineKey(machine, Models.Metadata.Machine.DumpKey, dumpMegaRom); break; case OpenMSXSubType.SCCPlusCart: var dumpSccPlusCart = new Models.Metadata.Dump(); var sccPlusCart = new Models.Metadata.Rom(); sccPlusCart[Models.Metadata.Rom.NameKey] = romItem.ReadString(Models.Metadata.Rom.NameKey); sccPlusCart[Models.Metadata.Rom.OffsetKey] = romItem.ReadString(Models.Metadata.Rom.StartKey) ?? romItem.ReadString(Models.Metadata.Rom.OffsetKey); sccPlusCart[Models.Metadata.Rom.OpenMSXType] = romItem.ReadString(Models.Metadata.Rom.OpenMSXType); sccPlusCart[Models.Metadata.Rom.RemarkKey] = romItem.ReadString(Models.Metadata.Rom.RemarkKey); sccPlusCart[Models.Metadata.Rom.SHA1Key] = romItem.ReadString(Models.Metadata.Rom.SHA1Key); sccPlusCart[Models.Metadata.Rom.StartKey] = romItem.ReadString(Models.Metadata.Rom.StartKey) ?? romItem.ReadString(Models.Metadata.Rom.OffsetKey); dumpSccPlusCart[Models.Metadata.Dump.RomKey] = sccPlusCart; var sccPlusCartOriginal = romItem.Read("ORIGINAL"); if (sccPlusCartOriginal != null) { var newOriginal = new Models.Metadata.Original { [Models.Metadata.Original.ValueKey] = sccPlusCartOriginal.Value.FromYesNo(), [Models.Metadata.Original.ContentKey] = sccPlusCartOriginal.Content, }; dumpSccPlusCart[Models.Metadata.Dump.OriginalKey] = newOriginal; } EnsureMachineKey(machine, Models.Metadata.Machine.DumpKey); AppendToMachineKey(machine, Models.Metadata.Machine.DumpKey, dumpSccPlusCart); break; } return romItem; } /// /// Convert Slot information /// /// Item to convert private static Models.Metadata.Slot ProcessItem(DatItems.Formats.Slot item) { var slotItem = item.GetInternalClone(); var slotOptions = item.GetFieldValue(Models.Metadata.Slot.SlotOptionKey); if (slotOptions != null) { var slotOptionItems = new List(); foreach (var slotOption in slotOptions) { var extensionItem = slotOption.GetInternalClone(); slotOptionItems.Add(extensionItem); } slotItem[Models.Metadata.Slot.SlotOptionKey] = slotOptionItems.ToArray(); } return slotItem; } /// /// Ensure a key in a machine /// private static void EnsureMachineKey(Models.Metadata.Machine machine, string key) { if (machine.Read(key) == null) machine[key] = new T[0]; } /// /// Append to a machine key as if its an array /// private static void AppendToMachineKey(Models.Metadata.Machine machine, string key, T value) { var arr = machine.Read(key); if (arr == null) return; List list = [.. arr]; list.Add(value); machine[key] = list.ToArray(); } #endregion } }