using System.Collections.Generic; using System.Linq; using SabreTools.Core.Tools; using SabreTools.DatItems; namespace SabreTools.DatFiles { public partial class DatFile { #region From Metadata /// /// Convert metadata information /// /// Metadata file to convert /// Name of the file to be parsed /// Index ID for the DAT /// True if full pathnames are to be kept, false otherwise /// True to only add item statistics while parsing, false otherwise public void ConvertMetadata(Models.Metadata.MetadataFile? item, string filename, int indexId, bool keep, bool statsOnly) { // If the metadata file is invalid, we can't do anything if (item == null || !item.Any()) return; // Create an internal source and add to the dictionary var source = new DatItems.Source { Index = indexId, Name = filename }; long sourceIndex = ItemsDB.AddSource(source); // Get the header from the metadata var header = item.Read(Models.Metadata.MetadataFile.HeaderKey); if (header != null) ConvertHeader(header, keep); // Get the machines from the metadata var machines = ReadItemArray(item, Models.Metadata.MetadataFile.MachineKey); if (machines != null) ConvertMachines(machines, source, sourceIndex, statsOnly); } /// /// Convert header information /// /// Header to convert /// True if full pathnames are to be kept, false otherwise private void ConvertHeader(Models.Metadata.Header? item, bool keep) { // If the header is invalid, we can't do anything if (item == null || !item.Any()) return; // Create an internal header var header = new DatHeader(item); // Convert subheader values if (item.ContainsKey(Models.Metadata.Header.CanOpenKey)) { var canOpen = item.Read(Models.Metadata.Header.CanOpenKey); if (canOpen?.Extension != null) Header.SetFieldValue(Models.Metadata.Header.CanOpenKey, canOpen.Extension); } if (item.ContainsKey(Models.Metadata.Header.ImagesKey)) { var images = item.Read(Models.Metadata.Header.ImagesKey); if (images != null) Header.SetFieldValue(Models.Metadata.Header.ImagesKey, images); } if (item.ContainsKey(Models.Metadata.Header.InfosKey)) { var infos = item.Read(Models.Metadata.Header.InfosKey); if (infos != null) { var offlineListInfos = new List(); if (infos.Title != null) { offlineListInfos.Add(new Formats.OfflineListInfo { Name = "title", Visible = infos.Title.Visible.AsYesNo(), InNamingOption = infos.Title.InNamingOption.AsYesNo(), Default = infos.Title.Default.AsYesNo(), }); } if (infos.Location != null) { offlineListInfos.Add(new Formats.OfflineListInfo { Name = "location", Visible = infos.Location.Visible.AsYesNo(), InNamingOption = infos.Location.InNamingOption.AsYesNo(), Default = infos.Location.Default.AsYesNo(), }); } if (infos.Publisher != null) { offlineListInfos.Add(new Formats.OfflineListInfo { Name = "publisher", Visible = infos.Publisher.Visible.AsYesNo(), InNamingOption = infos.Publisher.InNamingOption.AsYesNo(), Default = infos.Publisher.Default.AsYesNo(), }); } if (infos.SourceRom != null) { offlineListInfos.Add(new Formats.OfflineListInfo { Name = "sourceRom", Visible = infos.SourceRom.Visible.AsYesNo(), InNamingOption = infos.SourceRom.InNamingOption.AsYesNo(), Default = infos.SourceRom.Default.AsYesNo(), }); } if (infos.SaveType != null) { offlineListInfos.Add(new Formats.OfflineListInfo { Name = "saveType", Visible = infos.SaveType.Visible.AsYesNo(), InNamingOption = infos.SaveType.InNamingOption.AsYesNo(), Default = infos.SaveType.Default.AsYesNo(), }); } if (infos.RomSize != null) { offlineListInfos.Add(new Formats.OfflineListInfo { Name = "romSize", Visible = infos.RomSize.Visible.AsYesNo(), InNamingOption = infos.RomSize.InNamingOption.AsYesNo(), Default = infos.RomSize.Default.AsYesNo(), }); } if (infos.ReleaseNumber != null) { offlineListInfos.Add(new Formats.OfflineListInfo { Name = "releaseNumber", Visible = infos.ReleaseNumber.Visible.AsYesNo(), InNamingOption = infos.ReleaseNumber.InNamingOption.AsYesNo(), Default = infos.ReleaseNumber.Default.AsYesNo(), }); } if (infos.ImageNumber != null) { offlineListInfos.Add(new Formats.OfflineListInfo { Name = "imageNumber", Visible = infos.ImageNumber.Visible.AsYesNo(), InNamingOption = infos.ImageNumber.InNamingOption.AsYesNo(), Default = infos.ImageNumber.Default.AsYesNo(), }); } if (infos.LanguageNumber != null) { offlineListInfos.Add(new Formats.OfflineListInfo { Name = "languageNumber", Visible = infos.LanguageNumber.Visible.AsYesNo(), InNamingOption = infos.LanguageNumber.InNamingOption.AsYesNo(), Default = infos.LanguageNumber.Default.AsYesNo(), }); } if (infos.Comment != null) { offlineListInfos.Add(new Formats.OfflineListInfo { Name = "comment", Visible = infos.Comment.Visible.AsYesNo(), InNamingOption = infos.Comment.InNamingOption.AsYesNo(), Default = infos.Comment.Default.AsYesNo(), }); } if (infos.RomCRC != null) { offlineListInfos.Add(new Formats.OfflineListInfo { Name = "romCRC", Visible = infos.RomCRC.Visible.AsYesNo(), InNamingOption = infos.RomCRC.InNamingOption.AsYesNo(), Default = infos.RomCRC.Default.AsYesNo(), }); } if (infos.Im1CRC != null) { offlineListInfos.Add(new Formats.OfflineListInfo { Name = "im1CRC", Visible = infos.Im1CRC.Visible.AsYesNo(), InNamingOption = infos.Im1CRC.InNamingOption.AsYesNo(), Default = infos.Im1CRC.Default.AsYesNo(), }); } if (infos.Im2CRC != null) { offlineListInfos.Add(new Formats.OfflineListInfo { Name = "im2CRC", Visible = infos.Im2CRC.Visible.AsYesNo(), InNamingOption = infos.Im2CRC.InNamingOption.AsYesNo(), Default = infos.Im2CRC.Default.AsYesNo(), }); } if (infos.Languages != null) { offlineListInfos.Add(new Formats.OfflineListInfo { Name = "languages", Visible = infos.Languages.Visible.AsYesNo(), InNamingOption = infos.Languages.InNamingOption.AsYesNo(), Default = infos.Languages.Default.AsYesNo(), }); } Header.SetFieldValue(Models.Metadata.Header.InfosKey, [.. offlineListInfos]); } } if (item.ContainsKey(Models.Metadata.Header.NewDatKey)) { var newDat = item.Read(Models.Metadata.Header.NewDatKey); if (newDat != null) { Header.SetFieldValue("DATVERSIONURL", newDat.DatVersionUrl); Header.SetFieldValue("DATURL", newDat.DatUrl); Header.SetFieldValue("IMURL", newDat.ImUrl); } } if (item.ContainsKey(Models.Metadata.Header.SearchKey)) { var search = item.Read(Models.Metadata.Header.SearchKey); if (search != null) Header.SetFieldValue(Models.Metadata.Header.SearchKey, search); } // Selectively set all possible fields -- TODO: Figure out how to make this less manual if (Header.GetStringFieldValue(Models.Metadata.Header.AuthorKey) == null) Header.SetFieldValue(Models.Metadata.Header.AuthorKey, header.GetStringFieldValue(Models.Metadata.Header.AuthorKey)); if (Header.GetStringFieldValue(Models.Metadata.Header.BiosModeKey).AsEnumValue() == MergingFlag.None) Header.SetFieldValue(Models.Metadata.Header.BiosModeKey, header.GetStringFieldValue(Models.Metadata.Header.BiosModeKey).AsEnumValue().AsStringValue()); if (Header.GetStringFieldValue(Models.Metadata.Header.BuildKey) == null) Header.SetFieldValue(Models.Metadata.Header.BuildKey, header.GetStringFieldValue(Models.Metadata.Header.BuildKey)); if (Header.GetStringFieldValue(Models.Metadata.Header.CategoryKey) == null) Header.SetFieldValue(Models.Metadata.Header.CategoryKey, header.GetStringFieldValue(Models.Metadata.Header.CategoryKey)); if (Header.GetStringFieldValue(Models.Metadata.Header.CommentKey) == null) Header.SetFieldValue(Models.Metadata.Header.CommentKey, header.GetStringFieldValue(Models.Metadata.Header.CommentKey)); if (Header.GetStringFieldValue(Models.Metadata.Header.DateKey) == null) Header.SetFieldValue(Models.Metadata.Header.DateKey, header.GetStringFieldValue(Models.Metadata.Header.DateKey)); if (Header.GetStringFieldValue(Models.Metadata.Header.DatVersionKey) == null) Header.SetFieldValue(Models.Metadata.Header.DatVersionKey, header.GetStringFieldValue(Models.Metadata.Header.DatVersionKey)); if (Header.GetBoolFieldValue(Models.Metadata.Header.DebugKey) == null) Header.SetFieldValue(Models.Metadata.Header.DebugKey, header.GetBoolFieldValue(Models.Metadata.Header.DebugKey)); if (Header.GetStringFieldValue(Models.Metadata.Header.DescriptionKey) == null) Header.SetFieldValue(Models.Metadata.Header.DescriptionKey, header.GetStringFieldValue(Models.Metadata.Header.DescriptionKey)); if (Header.GetStringFieldValue(Models.Metadata.Header.EmailKey) == null) Header.SetFieldValue(Models.Metadata.Header.EmailKey, header.GetStringFieldValue(Models.Metadata.Header.EmailKey)); if (Header.GetStringFieldValue(Models.Metadata.Header.EmulatorVersionKey) == null) Header.SetFieldValue(Models.Metadata.Header.EmulatorVersionKey, header.GetStringFieldValue(Models.Metadata.Header.EmulatorVersionKey)); if (Header.GetStringFieldValue(Models.Metadata.Header.ForceMergingKey).AsEnumValue() == MergingFlag.None) Header.SetFieldValue(Models.Metadata.Header.ForceMergingKey, header.GetStringFieldValue(Models.Metadata.Header.ForceMergingKey).AsEnumValue().AsStringValue()); if (Header.GetStringFieldValue(Models.Metadata.Header.ForceNodumpKey).AsEnumValue() == NodumpFlag.None) Header.SetFieldValue(Models.Metadata.Header.ForceNodumpKey, header.GetStringFieldValue(Models.Metadata.Header.ForceNodumpKey).AsEnumValue().AsStringValue()); if (Header.GetStringFieldValue(Models.Metadata.Header.ForcePackingKey).AsEnumValue() == PackingFlag.None) Header.SetFieldValue(Models.Metadata.Header.ForcePackingKey, header.GetStringFieldValue(Models.Metadata.Header.ForcePackingKey).AsEnumValue().AsStringValue()); if (Header.GetStringFieldValue(Models.Metadata.Header.HeaderKey) == null) Header.SetFieldValue(Models.Metadata.Header.HeaderKey, header.GetStringFieldValue(Models.Metadata.Header.HeaderKey)); if (Header.GetStringFieldValue(Models.Metadata.Header.HomepageKey) == null) Header.SetFieldValue(Models.Metadata.Header.HomepageKey, header.GetStringFieldValue(Models.Metadata.Header.HomepageKey)); if (Header.GetStringFieldValue(Models.Metadata.Header.IdKey) == null) Header.SetFieldValue(Models.Metadata.Header.IdKey, header.GetStringFieldValue(Models.Metadata.Header.IdKey)); if (Header.GetStringFieldValue(Models.Metadata.Header.ImFolderKey) == null) Header.SetFieldValue(Models.Metadata.Header.ImFolderKey, header.GetStringFieldValue(Models.Metadata.Header.ImFolderKey)); if (Header.GetBoolFieldValue(Models.Metadata.Header.LockBiosModeKey) == null) Header.SetFieldValue(Models.Metadata.Header.LockBiosModeKey, header.GetBoolFieldValue(Models.Metadata.Header.LockBiosModeKey)); if (Header.GetBoolFieldValue(Models.Metadata.Header.LockRomModeKey) == null) Header.SetFieldValue(Models.Metadata.Header.LockRomModeKey, header.GetBoolFieldValue(Models.Metadata.Header.LockRomModeKey)); if (Header.GetBoolFieldValue(Models.Metadata.Header.LockSampleModeKey) == null) Header.SetFieldValue(Models.Metadata.Header.LockSampleModeKey, header.GetBoolFieldValue(Models.Metadata.Header.LockSampleModeKey)); if (Header.GetStringFieldValue(Models.Metadata.Header.MameConfigKey) == null) Header.SetFieldValue(Models.Metadata.Header.MameConfigKey, header.GetStringFieldValue(Models.Metadata.Header.MameConfigKey)); if (Header.GetStringFieldValue(Models.Metadata.Header.NameKey) == null) Header.SetFieldValue(Models.Metadata.Header.NameKey, header.GetStringFieldValue(Models.Metadata.Header.NameKey)); if (Header.GetStringFieldValue(Models.Metadata.Header.PluginKey) == null) Header.SetFieldValue(Models.Metadata.Header.PluginKey, header.GetStringFieldValue(Models.Metadata.Header.PluginKey)); if (Header.GetStringFieldValue(Models.Metadata.Header.RefNameKey) == null) Header.SetFieldValue(Models.Metadata.Header.RefNameKey, header.GetStringFieldValue(Models.Metadata.Header.RefNameKey)); if (Header.GetStringFieldValue(Models.Metadata.Header.RomModeKey).AsEnumValue() == MergingFlag.None) Header.SetFieldValue(Models.Metadata.Header.RomModeKey, header.GetStringFieldValue(Models.Metadata.Header.RomModeKey).AsEnumValue().AsStringValue()); if (Header.GetStringFieldValue(Models.Metadata.Header.RomTitleKey) == null) Header.SetFieldValue(Models.Metadata.Header.RomTitleKey, header.GetStringFieldValue(Models.Metadata.Header.RomTitleKey)); if (Header.GetStringFieldValue(Models.Metadata.Header.RootDirKey) == null) Header.SetFieldValue(Models.Metadata.Header.RootDirKey, header.GetStringFieldValue(Models.Metadata.Header.RootDirKey)); if (Header.GetStringFieldValue(Models.Metadata.Header.SampleModeKey).AsEnumValue() == MergingFlag.None) Header.SetFieldValue(Models.Metadata.Header.SampleModeKey, header.GetStringFieldValue(Models.Metadata.Header.SampleModeKey).AsEnumValue().AsStringValue()); if (Header.GetStringFieldValue(Models.Metadata.Header.ScreenshotsHeightKey) == null) Header.SetFieldValue(Models.Metadata.Header.ScreenshotsHeightKey, header.GetStringFieldValue(Models.Metadata.Header.ScreenshotsHeightKey)); if (Header.GetStringFieldValue(Models.Metadata.Header.ScreenshotsWidthKey) == null) Header.SetFieldValue(Models.Metadata.Header.ScreenshotsWidthKey, header.GetStringFieldValue(Models.Metadata.Header.ScreenshotsWidthKey)); if (Header.GetStringFieldValue(Models.Metadata.Header.SystemKey) == null) Header.SetFieldValue(Models.Metadata.Header.SystemKey, header.GetStringFieldValue(Models.Metadata.Header.SystemKey)); if (Header.GetStringFieldValue(Models.Metadata.Header.TypeKey) == null) Header.SetFieldValue(Models.Metadata.Header.TypeKey, header.GetStringFieldValue(Models.Metadata.Header.TypeKey)); if (Header.GetStringFieldValue(Models.Metadata.Header.UrlKey) == null) Header.SetFieldValue(Models.Metadata.Header.UrlKey, header.GetStringFieldValue(Models.Metadata.Header.UrlKey)); if (Header.GetStringFieldValue(Models.Metadata.Header.VersionKey) == null) Header.SetFieldValue(Models.Metadata.Header.VersionKey, header.GetStringFieldValue(Models.Metadata.Header.VersionKey)); // Handle implied SuperDAT if (Header.GetStringFieldValue(Models.Metadata.Header.NameKey)?.Contains(" - SuperDAT") == true && keep) { if (Header.GetStringFieldValue(Models.Metadata.Header.TypeKey) == null) Header.SetFieldValue(Models.Metadata.Header.TypeKey, "SuperDAT"); } } /// /// Convert machines information /// /// Machine array to convert /// Source to use with the converted items /// Index of the Source to use with the converted items /// True to only add item statistics while parsing, false otherwise private void ConvertMachines(Models.Metadata.Machine[]? items, Source source, long sourceIndex, bool statsOnly) { // If the array is invalid, we can't do anything if (items == null || items.Length == 0) return; // Loop through the machines and add foreach (var machine in items) { ConvertMachine(machine, source, sourceIndex, statsOnly); } } /// /// Convert machine information /// /// Machine to convert /// Source to use with the converted items /// Index of the Source to use with the converted items /// True to only add item statistics while parsing, false otherwise private void ConvertMachine(Models.Metadata.Machine? item, Source source, long sourceIndex, bool statsOnly) { // If the machine is invalid, we can't do anything if (item == null || !item.Any()) return; // Create an internal machine var machine = new DatItems.Machine(item); // Process flag values if (machine.GetStringFieldValue(Models.Metadata.Machine.Im1CRCKey) != null) machine.SetFieldValue(Models.Metadata.Machine.Im1CRCKey, TextHelper.NormalizeCRC32(machine.GetStringFieldValue(Models.Metadata.Machine.Im1CRCKey))); if (machine.GetStringFieldValue(Models.Metadata.Machine.Im2CRCKey) != null) machine.SetFieldValue(Models.Metadata.Machine.Im2CRCKey, TextHelper.NormalizeCRC32(machine.GetStringFieldValue(Models.Metadata.Machine.Im2CRCKey))); if (machine.GetBoolFieldValue(Models.Metadata.Machine.IsBiosKey) != null) machine.SetFieldValue(Models.Metadata.Machine.IsBiosKey, machine.GetBoolFieldValue(Models.Metadata.Machine.IsBiosKey).FromYesNo()); if (machine.GetBoolFieldValue(Models.Metadata.Machine.IsDeviceKey) != null) machine.SetFieldValue(Models.Metadata.Machine.IsDeviceKey, machine.GetBoolFieldValue(Models.Metadata.Machine.IsDeviceKey).FromYesNo()); if (machine.GetBoolFieldValue(Models.Metadata.Machine.IsMechanicalKey) != null) machine.SetFieldValue(Models.Metadata.Machine.IsMechanicalKey, machine.GetBoolFieldValue(Models.Metadata.Machine.IsMechanicalKey).FromYesNo()); if (machine.GetStringFieldValue(Models.Metadata.Machine.SupportedKey) != null) machine.SetFieldValue(Models.Metadata.Machine.SupportedKey, machine.GetStringFieldValue(Models.Metadata.Machine.SupportedKey).AsEnumValue().AsStringValue()); // Handle Trurip object, if it exists if (item.ContainsKey(Models.Metadata.Machine.TruripKey)) { var truripItem = item.Read(Models.Metadata.Machine.TruripKey); if (truripItem != null) { var trurip = new DatItems.Trurip(truripItem); machine.SetFieldValue(Models.Metadata.Machine.TruripKey, trurip); } } // Add the machine to the dictionary long machineIndex = ItemsDB.AddMachine(machine); // Convert items in the machine if (item.ContainsKey(Models.Metadata.Machine.AdjusterKey)) { var items = ReadItemArray(item, Models.Metadata.Machine.AdjusterKey); ProcessItems(items, machine, machineIndex, source, sourceIndex, statsOnly); } if (item.ContainsKey(Models.Metadata.Machine.ArchiveKey)) { var items = ReadItemArray(item, Models.Metadata.Machine.ArchiveKey); ProcessItems(items, machine, machineIndex, source, sourceIndex, statsOnly); } if (item.ContainsKey(Models.Metadata.Machine.BiosSetKey)) { var items = ReadItemArray(item, Models.Metadata.Machine.BiosSetKey); ProcessItems(items, machine, machineIndex, source, sourceIndex, statsOnly); } if (item.ContainsKey(Models.Metadata.Machine.ChipKey)) { var items = ReadItemArray(item, Models.Metadata.Machine.ChipKey); ProcessItems(items, machine, machineIndex, source, sourceIndex, statsOnly); } if (item.ContainsKey(Models.Metadata.Machine.ConfigurationKey)) { var items = ReadItemArray(item, Models.Metadata.Machine.ConfigurationKey); ProcessItems(items, machine, machineIndex, source, sourceIndex, statsOnly); } if (item.ContainsKey(Models.Metadata.Machine.DeviceKey)) { var items = ReadItemArray(item, Models.Metadata.Machine.DeviceKey); ProcessItems(items, machine, machineIndex, source, sourceIndex, statsOnly); } if (item.ContainsKey(Models.Metadata.Machine.DeviceRefKey)) { var items = ReadItemArray(item, Models.Metadata.Machine.DeviceRefKey); ProcessItems(items, machine, machineIndex, source, sourceIndex, statsOnly); } if (item.ContainsKey(Models.Metadata.Machine.DipSwitchKey)) { var items = ReadItemArray(item, Models.Metadata.Machine.DipSwitchKey); ProcessItems(items, machine, machineIndex, source, sourceIndex, statsOnly); } if (item.ContainsKey(Models.Metadata.Machine.DiskKey)) { var items = ReadItemArray(item, Models.Metadata.Machine.DiskKey) ?? ReadItemArray(item, Models.Metadata.Machine.DiskKey)?.Select(d => (d as Models.Metadata.Disk)!)?.ToArray(); // TODO: Remove case when Serialization fixed ProcessItems(items, machine, machineIndex, source, sourceIndex, statsOnly); } if (item.ContainsKey(Models.Metadata.Machine.DisplayKey)) { var items = ReadItemArray(item, Models.Metadata.Machine.DisplayKey); ProcessItems(items, machine, machineIndex, source, sourceIndex, statsOnly); } if (item.ContainsKey(Models.Metadata.Machine.DriverKey)) { var items = ReadItemArray(item, Models.Metadata.Machine.DriverKey); ProcessItems(items, machine, machineIndex, source, sourceIndex, statsOnly); } if (item.ContainsKey(Models.Metadata.Machine.DumpKey)) { var items = ReadItemArray(item, Models.Metadata.Machine.DumpKey); string? machineName = machine.GetStringFieldValue(Models.Metadata.Machine.NameKey); ProcessItems(items, machine, machineIndex, source, sourceIndex, statsOnly, machineName); } if (item.ContainsKey(Models.Metadata.Machine.FeatureKey)) { var items = ReadItemArray(item, Models.Metadata.Machine.FeatureKey); ProcessItems(items, machine, machineIndex, source, sourceIndex, statsOnly); } if (item.ContainsKey(Models.Metadata.Machine.InfoKey)) { var items = ReadItemArray(item, Models.Metadata.Machine.InfoKey); ProcessItems(items, machine, machineIndex, source, sourceIndex, statsOnly); } if (item.ContainsKey(Models.Metadata.Machine.InputKey)) { var items = ReadItemArray(item, Models.Metadata.Machine.InputKey); ProcessItems(items, machine, machineIndex, source, sourceIndex, statsOnly); } if (item.ContainsKey(Models.Metadata.Machine.MediaKey)) { var items = ReadItemArray(item, Models.Metadata.Machine.MediaKey); ProcessItems(items, machine, machineIndex, source, sourceIndex, statsOnly); } if (item.ContainsKey(Models.Metadata.Machine.PartKey)) { var items = ReadItemArray(item, Models.Metadata.Machine.PartKey); ProcessItems(items, machine, machineIndex, source, sourceIndex, statsOnly); } if (item.ContainsKey(Models.Metadata.Machine.PortKey)) { var items = ReadItemArray(item, Models.Metadata.Machine.PortKey); ProcessItems(items, machine, machineIndex, source, sourceIndex, statsOnly); } if (item.ContainsKey(Models.Metadata.Machine.RamOptionKey)) { var items = ReadItemArray(item, Models.Metadata.Machine.RamOptionKey); ProcessItems(items, machine, machineIndex, source, sourceIndex, statsOnly); } if (item.ContainsKey(Models.Metadata.Machine.ReleaseKey)) { var items = ReadItemArray(item, Models.Metadata.Machine.ReleaseKey); ProcessItems(items, machine, machineIndex, source, sourceIndex, statsOnly); } if (item.ContainsKey(Models.Metadata.Machine.RomKey)) { var items = ReadItemArray(item, Models.Metadata.Machine.RomKey) ?? ReadItemArray(item, Models.Metadata.Machine.RomKey)?.Select(d => (d as Models.Metadata.Rom)!)?.ToArray(); // TODO: Remove case when Serialization fixed ProcessItems(items, machine, machineIndex, source, sourceIndex, statsOnly); } if (item.ContainsKey(Models.Metadata.Machine.SampleKey)) { var items = ReadItemArray(item, Models.Metadata.Machine.SampleKey); ProcessItems(items, machine, machineIndex, source, sourceIndex, statsOnly); } if (item.ContainsKey(Models.Metadata.Machine.SharedFeatKey)) { var items = ReadItemArray(item, Models.Metadata.Machine.SharedFeatKey); ProcessItems(items, machine, machineIndex, source, sourceIndex, statsOnly); } if (item.ContainsKey(Models.Metadata.Machine.SlotKey)) { var items = ReadItemArray(item, Models.Metadata.Machine.SlotKey); ProcessItems(items, machine, machineIndex, source, sourceIndex, statsOnly); } if (item.ContainsKey(Models.Metadata.Machine.SoftwareListKey)) { var items = ReadItemArray(item, Models.Metadata.Machine.SoftwareListKey); ProcessItems(items, machine, machineIndex, source, sourceIndex, statsOnly); } if (item.ContainsKey(Models.Metadata.Machine.SoundKey)) { var items = ReadItemArray(item, Models.Metadata.Machine.SoundKey); ProcessItems(items, machine, machineIndex, source, sourceIndex, statsOnly); } if (item.ContainsKey(Models.Metadata.Machine.VideoKey)) { var items = ReadItemArray(item, Models.Metadata.Machine.VideoKey); ProcessItems(items, machine, machineIndex, source, sourceIndex, statsOnly); } } /// /// Convert Adjuster information /// /// Array of internal items to convert /// Machine to use with the converted items /// Index of the Machine to use with the converted items /// Source to use with the converted items /// Index of the Source to use with the converted items /// True to only add item statistics while parsing, false otherwise private void ProcessItems(Models.Metadata.Adjuster[]? items, Machine machine, long machineIndex, Source source, long sourceIndex, bool statsOnly) { // If the array is null or empty, return without processing if (items == null || items.Length == 0) return; // Loop through the items and add foreach (var item in items) { var datItem = new DatItems.Formats.Adjuster(item); datItem.SetFieldValue(DatItems.DatItem.SourceKey, source); datItem.CopyMachineInformation(machine); // Process flag values if (datItem.GetBoolFieldValue(Models.Metadata.Adjuster.DefaultKey) != null) datItem.SetFieldValue(Models.Metadata.Adjuster.DefaultKey, datItem.GetBoolFieldValue(Models.Metadata.Adjuster.DefaultKey).FromYesNo()); // Handle subitems var condition = item.Read(Models.Metadata.Adjuster.ConditionKey); if (condition != null) { var subItem = new DatItems.Formats.Condition(condition); // Process flag values if (subItem.GetStringFieldValue(Models.Metadata.Condition.RelationKey) != null) subItem.SetFieldValue(Models.Metadata.Condition.RelationKey, subItem.GetStringFieldValue(Models.Metadata.Condition.RelationKey).AsEnumValue().AsStringValue()); datItem.SetFieldValue(Models.Metadata.Adjuster.ConditionKey, subItem); } ParseAddHelper(datItem, statsOnly); ParseAddHelper(datItem, machineIndex, sourceIndex, statsOnly); } } /// /// Convert Archive information /// /// Array of internal items to convert /// Machine to use with the converted items /// Index of the Machine to use with the converted items /// Source to use with the converted items /// Index of the Source to use with the converted items /// True to only add item statistics while parsing, false otherwise private void ProcessItems(Models.Metadata.Archive[]? items, Machine machine, long machineIndex, Source source, long sourceIndex, bool statsOnly) { // If the array is null or empty, return without processing if (items == null || items.Length == 0) return; // Loop through the items and add foreach (var item in items) { var datItem = new DatItems.Formats.Archive(item); datItem.SetFieldValue(DatItems.DatItem.SourceKey, source); datItem.CopyMachineInformation(machine); ParseAddHelper(datItem, statsOnly); ParseAddHelper(datItem, machineIndex, sourceIndex, statsOnly); } } /// /// Convert BiosSet information /// /// Array of internal items to convert /// Machine to use with the converted items /// Index of the Machine to use with the converted items /// Source to use with the converted items /// Index of the Source to use with the converted items /// True to only add item statistics while parsing, false otherwise private void ProcessItems(Models.Metadata.BiosSet[]? items, Machine machine, long machineIndex, Source source, long sourceIndex, bool statsOnly) { // If the array is null or empty, return without processing if (items == null || items.Length == 0) return; // Loop through the items and add foreach (var item in items) { var datItem = new DatItems.Formats.BiosSet(item); datItem.SetFieldValue(DatItems.DatItem.SourceKey, source); datItem.CopyMachineInformation(machine); // Process flag values if (datItem.GetBoolFieldValue(Models.Metadata.BiosSet.DefaultKey) != null) datItem.SetFieldValue(Models.Metadata.BiosSet.DefaultKey, datItem.GetBoolFieldValue(Models.Metadata.BiosSet.DefaultKey).FromYesNo()); ParseAddHelper(datItem, statsOnly); ParseAddHelper(datItem, machineIndex, sourceIndex, statsOnly); } } /// /// Convert Chip information /// /// Array of internal items to convert /// Machine to use with the converted items /// Index of the Machine to use with the converted items /// Source to use with the converted items /// Index of the Source to use with the converted items /// True to only add item statistics while parsing, false otherwise private void ProcessItems(Models.Metadata.Chip[]? items, Machine machine, long machineIndex, Source source, long sourceIndex, bool statsOnly) { // If the array is null or empty, return without processing if (items == null || items.Length == 0) return; // Loop through the items and add foreach (var item in items) { var datItem = new DatItems.Formats.Chip(item); datItem.SetFieldValue(DatItems.DatItem.SourceKey, source); datItem.CopyMachineInformation(machine); // Process flag values if (datItem.GetBoolFieldValue(Models.Metadata.Chip.SoundOnlyKey) != null) datItem.SetFieldValue(Models.Metadata.Chip.SoundOnlyKey, datItem.GetBoolFieldValue(Models.Metadata.Chip.SoundOnlyKey).FromYesNo()); if (datItem.GetStringFieldValue(Models.Metadata.Chip.ChipTypeKey) != null) datItem.SetFieldValue(Models.Metadata.Chip.ChipTypeKey, datItem.GetStringFieldValue(Models.Metadata.Chip.ChipTypeKey).AsEnumValue().AsStringValue()); ParseAddHelper(datItem, statsOnly); ParseAddHelper(datItem, machineIndex, sourceIndex, statsOnly); } } /// /// Convert Configuration information /// /// Array of internal items to convert /// Machine to use with the converted items /// Index of the Machine to use with the converted items /// Source to use with the converted items /// Index of the Source to use with the converted items /// True to only add item statistics while parsing, false otherwise private void ProcessItems(Models.Metadata.Configuration[]? items, Machine machine, long machineIndex, Source source, long sourceIndex, bool statsOnly) { // If the array is null or empty, return without processing if (items == null || items.Length == 0) return; // Loop through the items and add foreach (var item in items) { var datItem = new DatItems.Formats.Configuration(item); datItem.SetFieldValue(DatItems.DatItem.SourceKey, source); datItem.CopyMachineInformation(machine); // Handle subitems var condition = item.Read(Models.Metadata.Configuration.ConditionKey); if (condition != null) { var subItem = new DatItems.Formats.Condition(condition); // Process flag values if (subItem.GetStringFieldValue(Models.Metadata.Condition.RelationKey) != null) subItem.SetFieldValue(Models.Metadata.Condition.RelationKey, subItem.GetStringFieldValue(Models.Metadata.Condition.RelationKey).AsEnumValue().AsStringValue()); datItem.SetFieldValue(Models.Metadata.Configuration.ConditionKey, subItem); } var confLocations = ReadItemArray(item, Models.Metadata.Configuration.ConfLocationKey); if (confLocations != null) { var subLocations = new List(); foreach (var location in confLocations) { var subItem = new DatItems.Formats.ConfLocation(location); // Process flag values if (subItem.GetBoolFieldValue(Models.Metadata.ConfLocation.InvertedKey) != null) subItem.SetFieldValue(Models.Metadata.ConfLocation.InvertedKey, subItem.GetBoolFieldValue(Models.Metadata.ConfLocation.InvertedKey).FromYesNo()); subLocations.Add(subItem); } datItem.SetFieldValue(Models.Metadata.Configuration.ConfLocationKey, [.. subLocations]); } var confSettings = ReadItemArray(item, Models.Metadata.Configuration.ConfSettingKey); if (confSettings != null) { var subValues = new List(); foreach (var setting in confSettings) { var subItem = new DatItems.Formats.ConfSetting(setting); // Process flag values if (subItem.GetBoolFieldValue(Models.Metadata.ConfSetting.DefaultKey) != null) subItem.SetFieldValue(Models.Metadata.ConfSetting.DefaultKey, subItem.GetBoolFieldValue(Models.Metadata.ConfSetting.DefaultKey).FromYesNo()); var subCondition = item.Read(Models.Metadata.ConfSetting.ConditionKey); if (subCondition != null) { var subSubItem = new DatItems.Formats.Condition(subCondition); // Process flag values if (subSubItem.GetStringFieldValue(Models.Metadata.Condition.RelationKey) != null) subSubItem.SetFieldValue(Models.Metadata.Condition.RelationKey, subSubItem.GetStringFieldValue(Models.Metadata.Condition.RelationKey).AsEnumValue().AsStringValue()); subItem.SetFieldValue(Models.Metadata.ConfSetting.ConditionKey, subSubItem); } subValues.Add(subItem); } datItem.SetFieldValue(Models.Metadata.Configuration.ConfSettingKey, [.. subValues]); } ParseAddHelper(datItem, statsOnly); ParseAddHelper(datItem, machineIndex, sourceIndex, statsOnly); } } /// /// Convert Device information /// /// Array of internal items to convert /// Machine to use with the converted items /// Index of the Machine to use with the converted items /// Source to use with the converted items /// Index of the Source to use with the converted items /// True to only add item statistics while parsing, false otherwise private void ProcessItems(Models.Metadata.Device[]? items, Machine machine, long machineIndex, Source source, long sourceIndex, bool statsOnly) { // If the array is null or empty, return without processing if (items == null || items.Length == 0) return; // Loop through the items and add foreach (var item in items) { var datItem = new DatItems.Formats.Device(item); datItem.SetFieldValue(DatItems.DatItem.SourceKey, source); datItem.CopyMachineInformation(machine); // Process flag values if (datItem.GetBoolFieldValue(Models.Metadata.Device.MandatoryKey) != null) datItem.SetFieldValue(Models.Metadata.Device.MandatoryKey, datItem.GetBoolFieldValue(Models.Metadata.Device.MandatoryKey).FromYesNo()); if (datItem.GetStringFieldValue(Models.Metadata.Device.DeviceTypeKey) != null) datItem.SetFieldValue(Models.Metadata.Device.DeviceTypeKey, datItem.GetStringFieldValue(Models.Metadata.Device.DeviceTypeKey).AsEnumValue().AsStringValue()); // Handle subitems var instance = item.Read(Models.Metadata.Device.InstanceKey); if (instance != null) { var subItem = new DatItems.Formats.Instance(instance); datItem.SetFieldValue(Models.Metadata.Device.InstanceKey, subItem); } var extensions = ReadItemArray(item, Models.Metadata.Device.ExtensionKey); if (extensions != null) { var subExtensions = new List(); foreach (var extension in extensions) { var subItem = new DatItems.Formats.Extension(extension); subExtensions.Add(subItem); } datItem.SetFieldValue(Models.Metadata.Device.ExtensionKey, [.. subExtensions]); } ParseAddHelper(datItem, statsOnly); ParseAddHelper(datItem, machineIndex, sourceIndex, statsOnly); } } /// /// Convert DeviceRef information /// /// Array of internal items to convert /// Machine to use with the converted items /// Index of the Machine to use with the converted items /// Source to use with the converted items /// Index of the Source to use with the converted items /// True to only add item statistics while parsing, false otherwise private void ProcessItems(Models.Metadata.DeviceRef[]? items, Machine machine, long machineIndex, Source source, long sourceIndex, bool statsOnly) { // If the array is null or empty, return without processing if (items == null || items.Length == 0) return; // Loop through the items and add foreach (var item in items) { var datItem = new DatItems.Formats.DeviceRef(item); datItem.SetFieldValue(DatItems.DatItem.SourceKey, source); datItem.CopyMachineInformation(machine); ParseAddHelper(datItem, statsOnly); ParseAddHelper(datItem, machineIndex, sourceIndex, statsOnly); } } /// /// Convert DipSwitch information /// /// Array of internal items to convert /// Machine to use with the converted items /// Index of the Machine to use with the converted items /// Source to use with the converted items /// Index of the Source to use with the converted items /// True to only add item statistics while parsing, false otherwise private void ProcessItems(Models.Metadata.DipSwitch[]? items, Machine machine, long machineIndex, Source source, long sourceIndex, bool statsOnly) { // If the array is null or empty, return without processing if (items == null || items.Length == 0) return; // Loop through the items and add foreach (var item in items) { var datItem = new DatItems.Formats.DipSwitch(item); datItem.SetFieldValue(DatItems.DatItem.SourceKey, source); datItem.CopyMachineInformation(machine); // Process flag values if (datItem.GetBoolFieldValue(Models.Metadata.DipSwitch.DefaultKey) != null) datItem.SetFieldValue(Models.Metadata.DipSwitch.DefaultKey, datItem.GetBoolFieldValue(Models.Metadata.DipSwitch.DefaultKey).FromYesNo()); // Handle subitems var condition = item.Read(Models.Metadata.DipSwitch.ConditionKey); if (condition != null) { var subItem = new DatItems.Formats.Condition(condition); // Process flag values if (subItem.GetStringFieldValue(Models.Metadata.Condition.RelationKey) != null) subItem.SetFieldValue(Models.Metadata.Condition.RelationKey, subItem.GetStringFieldValue(Models.Metadata.Condition.RelationKey).AsEnumValue().AsStringValue()); datItem.SetFieldValue(Models.Metadata.DipSwitch.ConditionKey, subItem); } var dipLocations = ReadItemArray(item, Models.Metadata.DipSwitch.DipLocationKey); if (dipLocations != null) { var subLocations = new List(); foreach (var location in dipLocations) { var subItem = new DatItems.Formats.DipLocation(location); // Process flag values if (subItem.GetBoolFieldValue(Models.Metadata.DipLocation.InvertedKey) != null) subItem.SetFieldValue(Models.Metadata.DipLocation.InvertedKey, subItem.GetBoolFieldValue(Models.Metadata.DipLocation.InvertedKey).FromYesNo()); subLocations.Add(subItem); } datItem.SetFieldValue(Models.Metadata.DipSwitch.DipLocationKey, [.. subLocations]); } var dipValues = ReadItemArray(item, Models.Metadata.DipSwitch.DipValueKey); if (dipValues != null) { var subValues = new List(); foreach (var value in dipValues) { var subItem = new DatItems.Formats.DipValue(value); // Process flag values if (subItem.GetBoolFieldValue(Models.Metadata.DipValue.DefaultKey) != null) subItem.SetFieldValue(Models.Metadata.DipValue.DefaultKey, subItem.GetBoolFieldValue(Models.Metadata.DipValue.DefaultKey).FromYesNo()); var subCondition = item.Read(Models.Metadata.DipValue.ConditionKey); if (subCondition != null) { var subSubItem = new DatItems.Formats.Condition(subCondition); // Process flag values if (subSubItem.GetStringFieldValue(Models.Metadata.Condition.RelationKey) != null) subSubItem.SetFieldValue(Models.Metadata.Condition.RelationKey, subSubItem.GetStringFieldValue(Models.Metadata.Condition.RelationKey).AsEnumValue().AsStringValue()); subItem.SetFieldValue(Models.Metadata.DipValue.ConditionKey, subSubItem); } subValues.Add(subItem); } datItem.SetFieldValue(Models.Metadata.DipSwitch.DipValueKey, [.. subValues]); } ParseAddHelper(datItem, statsOnly); ParseAddHelper(datItem, machineIndex, sourceIndex, statsOnly); } } /// /// Convert Disk information /// /// Array of internal items to convert /// Machine to use with the converted items /// Index of the Machine to use with the converted items /// Source to use with the converted items /// Index of the Source to use with the converted items /// True to only add item statistics while parsing, false otherwise private void ProcessItems(Models.Metadata.Disk[]? items, Machine machine, long machineIndex, Source source, long sourceIndex, bool statsOnly) { // If the array is null or empty, return without processing if (items == null || items.Length == 0) return; // Loop through the items and add foreach (var item in items) { var datItem = new DatItems.Formats.Disk(item); datItem.SetFieldValue(DatItems.DatItem.SourceKey, source); datItem.CopyMachineInformation(machine); // Process flag values if (datItem.GetBoolFieldValue(Models.Metadata.Disk.OptionalKey) != null) datItem.SetFieldValue(Models.Metadata.Disk.OptionalKey, datItem.GetBoolFieldValue(Models.Metadata.Disk.OptionalKey).FromYesNo()); if (datItem.GetStringFieldValue(Models.Metadata.Disk.StatusKey) != null) datItem.SetFieldValue(Models.Metadata.Disk.StatusKey, datItem.GetStringFieldValue(Models.Metadata.Disk.StatusKey).AsEnumValue().AsStringValue()); if (datItem.GetBoolFieldValue(Models.Metadata.Disk.WritableKey) != null) datItem.SetFieldValue(Models.Metadata.Disk.WritableKey, datItem.GetBoolFieldValue(Models.Metadata.Disk.WritableKey).FromYesNo()); // Process hash values if (datItem.GetStringFieldValue(Models.Metadata.Disk.MD5Key) != null) datItem.SetFieldValue(Models.Metadata.Disk.MD5Key, TextHelper.NormalizeMD5(datItem.GetStringFieldValue(Models.Metadata.Disk.MD5Key))); if (datItem.GetStringFieldValue(Models.Metadata.Disk.SHA1Key) != null) datItem.SetFieldValue(Models.Metadata.Disk.SHA1Key, TextHelper.NormalizeSHA1(datItem.GetStringFieldValue(Models.Metadata.Disk.SHA1Key))); ParseAddHelper(datItem, statsOnly); ParseAddHelper(datItem, machineIndex, sourceIndex, statsOnly); } } /// /// Convert Display information /// /// Array of internal items to convert /// Machine to use with the converted items /// Index of the Machine to use with the converted items /// Source to use with the converted items /// Index of the Source to use with the converted items /// True to only add item statistics while parsing, false otherwise private void ProcessItems(Models.Metadata.Display[]? items, Machine machine, long machineIndex, Source source, long sourceIndex, bool statsOnly) { // If the array is null or empty, return without processing if (items == null || items.Length == 0) return; // Loop through the items and add foreach (var item in items) { var datItem = new DatItems.Formats.Display(item); datItem.SetFieldValue(DatItems.DatItem.SourceKey, source); datItem.CopyMachineInformation(machine); // Process flag values if (datItem.GetBoolFieldValue(Models.Metadata.Display.FlipXKey) != null) datItem.SetFieldValue(Models.Metadata.Display.FlipXKey, datItem.GetBoolFieldValue(Models.Metadata.Display.FlipXKey).FromYesNo()); if (datItem.GetInt64FieldValue(Models.Metadata.Display.HBEndKey) != null) datItem.SetFieldValue(Models.Metadata.Display.HBEndKey, datItem.GetInt64FieldValue(Models.Metadata.Display.HBEndKey).ToString()); if (datItem.GetInt64FieldValue(Models.Metadata.Display.HBStartKey) != null) datItem.SetFieldValue(Models.Metadata.Display.HBStartKey, datItem.GetInt64FieldValue(Models.Metadata.Display.HBStartKey).ToString()); if (datItem.GetInt64FieldValue(Models.Metadata.Display.HeightKey) != null) datItem.SetFieldValue(Models.Metadata.Display.HeightKey, datItem.GetInt64FieldValue(Models.Metadata.Display.HeightKey).ToString()); if (datItem.GetInt64FieldValue(Models.Metadata.Display.HTotalKey) != null) datItem.SetFieldValue(Models.Metadata.Display.HTotalKey, datItem.GetInt64FieldValue(Models.Metadata.Display.HTotalKey).ToString()); if (datItem.GetInt64FieldValue(Models.Metadata.Display.PixClockKey) != null) datItem.SetFieldValue(Models.Metadata.Display.PixClockKey, datItem.GetInt64FieldValue(Models.Metadata.Display.PixClockKey).ToString()); if (datItem.GetDoubleFieldValue(Models.Metadata.Display.RefreshKey) != null) datItem.SetFieldValue(Models.Metadata.Display.RefreshKey, datItem.GetDoubleFieldValue(Models.Metadata.Display.RefreshKey).ToString()); if (datItem.GetInt64FieldValue(Models.Metadata.Display.RotateKey) != null) datItem.SetFieldValue(Models.Metadata.Display.RotateKey, datItem.GetInt64FieldValue(Models.Metadata.Display.RotateKey).ToString()); if (datItem.GetStringFieldValue(Models.Metadata.Display.DisplayTypeKey) != null) datItem.SetFieldValue(Models.Metadata.Display.DisplayTypeKey, datItem.GetStringFieldValue(Models.Metadata.Display.DisplayTypeKey).AsEnumValue().AsStringValue()); if (datItem.GetInt64FieldValue(Models.Metadata.Display.VBEndKey) != null) datItem.SetFieldValue(Models.Metadata.Display.VBEndKey, datItem.GetInt64FieldValue(Models.Metadata.Display.VBEndKey).ToString()); if (datItem.GetInt64FieldValue(Models.Metadata.Display.VBStartKey) != null) datItem.SetFieldValue(Models.Metadata.Display.VBStartKey, datItem.GetInt64FieldValue(Models.Metadata.Display.VBStartKey).ToString()); if (datItem.GetInt64FieldValue(Models.Metadata.Display.VTotalKey) != null) datItem.SetFieldValue(Models.Metadata.Display.VTotalKey, datItem.GetInt64FieldValue(Models.Metadata.Display.VTotalKey).ToString()); if (datItem.GetInt64FieldValue(Models.Metadata.Display.WidthKey) != null) datItem.SetFieldValue(Models.Metadata.Display.WidthKey, datItem.GetInt64FieldValue(Models.Metadata.Display.WidthKey).ToString()); ParseAddHelper(datItem, statsOnly); ParseAddHelper(datItem, machineIndex, sourceIndex, statsOnly); } } /// /// Convert Driver information /// /// Array of internal items to convert /// Machine to use with the converted items /// Index of the Machine to use with the converted items /// Source to use with the converted items /// Index of the Source to use with the converted items /// True to only add item statistics while parsing, false otherwise private void ProcessItems(Models.Metadata.Driver[]? items, Machine machine, long machineIndex, Source source, long sourceIndex, bool statsOnly) { // If the array is null or empty, return without processing if (items == null || items.Length == 0) return; // Loop through the items and add foreach (var item in items) { var datItem = new DatItems.Formats.Driver(item); datItem.SetFieldValue(DatItems.DatItem.SourceKey, source); datItem.CopyMachineInformation(machine); // Process flag values if (datItem.GetStringFieldValue(Models.Metadata.Driver.CocktailKey) != null) datItem.SetFieldValue(Models.Metadata.Driver.CocktailKey, datItem.GetStringFieldValue(Models.Metadata.Driver.CocktailKey).AsEnumValue().AsStringValue()); if (datItem.GetStringFieldValue(Models.Metadata.Driver.ColorKey) != null) datItem.SetFieldValue(Models.Metadata.Driver.ColorKey, datItem.GetStringFieldValue(Models.Metadata.Driver.ColorKey).AsEnumValue().AsStringValue()); if (datItem.GetStringFieldValue(Models.Metadata.Driver.EmulationKey) != null) datItem.SetFieldValue(Models.Metadata.Driver.EmulationKey, datItem.GetStringFieldValue(Models.Metadata.Driver.EmulationKey).AsEnumValue().AsStringValue()); if (datItem.GetBoolFieldValue(Models.Metadata.Driver.IncompleteKey) != null) datItem.SetFieldValue(Models.Metadata.Driver.IncompleteKey, datItem.GetBoolFieldValue(Models.Metadata.Driver.EmulationKey).FromYesNo()); if (datItem.GetBoolFieldValue(Models.Metadata.Driver.NoSoundHardwareKey) != null) datItem.SetFieldValue(Models.Metadata.Driver.NoSoundHardwareKey, datItem.GetBoolFieldValue(Models.Metadata.Driver.NoSoundHardwareKey).FromYesNo()); if (datItem.GetInt64FieldValue(Models.Metadata.Driver.PaletteSizeKey) != null) datItem.SetFieldValue(Models.Metadata.Driver.PaletteSizeKey, datItem.GetInt64FieldValue(Models.Metadata.Driver.PaletteSizeKey).ToString()); if (datItem.GetBoolFieldValue(Models.Metadata.Driver.RequiresArtworkKey) != null) datItem.SetFieldValue(Models.Metadata.Driver.RequiresArtworkKey, datItem.GetBoolFieldValue(Models.Metadata.Driver.RequiresArtworkKey).FromYesNo()); if (datItem.GetStringFieldValue(Models.Metadata.Driver.SaveStateKey) != null) datItem.SetFieldValue(Models.Metadata.Driver.SaveStateKey, datItem.GetStringFieldValue(Models.Metadata.Driver.SaveStateKey).AsEnumValue().AsStringValue()); if (datItem.GetStringFieldValue(Models.Metadata.Driver.SoundKey) != null) datItem.SetFieldValue(Models.Metadata.Driver.SoundKey, datItem.GetStringFieldValue(Models.Metadata.Driver.SoundKey).AsEnumValue().AsStringValue()); if (datItem.GetStringFieldValue(Models.Metadata.Driver.StatusKey) != null) datItem.SetFieldValue(Models.Metadata.Driver.StatusKey, datItem.GetStringFieldValue(Models.Metadata.Driver.StatusKey).AsEnumValue().AsStringValue()); if (datItem.GetBoolFieldValue(Models.Metadata.Driver.UnofficialKey) != null) datItem.SetFieldValue(Models.Metadata.Driver.UnofficialKey, datItem.GetBoolFieldValue(Models.Metadata.Driver.UnofficialKey).FromYesNo()); ParseAddHelper(datItem, statsOnly); ParseAddHelper(datItem, machineIndex, sourceIndex, statsOnly); } } /// /// Convert Dump information /// /// Array of internal items to convert /// Machine to use with the converted items /// Index of the Machine to use with the converted items /// Source to use with the converted items /// Index of the Source to use with the converted items /// True to only add item statistics while parsing, false otherwise /// Machine name to use when constructing item names private void ProcessItems(Models.Metadata.Dump[]? items, Machine machine, long machineIndex, Source source, long sourceIndex, bool statsOnly, string? machineName) { // If the array is null or empty, return without processing if (items == null || items.Length == 0) return; // Loop through the items and add int index = 0; foreach (var dump in items) { // If we don't have rom data, we can't do anything Models.Metadata.Rom? rom = null; OpenMSXSubType subType = OpenMSXSubType.NULL; if (dump?.Read(Models.Metadata.Dump.RomKey) != null) { rom = dump.Read(Models.Metadata.Dump.RomKey); subType = OpenMSXSubType.Rom; } else if (dump?.Read(Models.Metadata.Dump.MegaRomKey) != null) { rom = dump.Read(Models.Metadata.Dump.MegaRomKey); subType = OpenMSXSubType.MegaRom; } else if (dump?.Read(Models.Metadata.Dump.SCCPlusCartKey) != null) { rom = dump.Read(Models.Metadata.Dump.SCCPlusCartKey); subType = OpenMSXSubType.SCCPlusCart; } else { continue; } string name = $"{machineName}_{index++}{(!string.IsNullOrEmpty(rom!.ReadString(Models.Metadata.Rom.RemarkKey)) ? $" {rom.ReadString(Models.Metadata.Rom.RemarkKey)}" : string.Empty)}"; var datItem = new DatItems.Formats.Rom(); datItem.SetName(name); datItem.SetFieldValue(Models.Metadata.Rom.OffsetKey, rom.ReadString(Models.Metadata.Rom.StartKey)); datItem.SetFieldValue(Models.Metadata.Rom.OpenMSXMediaType, subType.AsStringValue()); datItem.SetFieldValue(Models.Metadata.Rom.OpenMSXType, rom.ReadString(Models.Metadata.Rom.OpenMSXType) ?? rom.ReadString(Models.Metadata.Rom.TypeKey)); datItem.SetFieldValue(Models.Metadata.Rom.RemarkKey, rom.ReadString(Models.Metadata.Rom.RemarkKey)); datItem.SetFieldValue(Models.Metadata.Rom.SHA1Key, rom.ReadString(Models.Metadata.Rom.SHA1Key)); datItem.SetFieldValue(Models.Metadata.Rom.StartKey, rom.ReadString(Models.Metadata.Rom.StartKey)); datItem.SetFieldValue(DatItems.DatItem.SourceKey, source); if (dump.Read(Models.Metadata.Dump.OriginalKey) != null) { var original = dump.Read(Models.Metadata.Dump.OriginalKey)!; datItem.SetFieldValue("ORIGINAL", new DatItems.Formats.Original { Value = original.ReadBool(Models.Metadata.Original.ValueKey), Content = original.ReadString(Models.Metadata.Original.ContentKey), }); } datItem.CopyMachineInformation(machine); // Process hash values if (datItem.GetInt64FieldValue(Models.Metadata.Rom.SizeKey) != null) datItem.SetFieldValue(Models.Metadata.Rom.SizeKey, datItem.GetInt64FieldValue(Models.Metadata.Rom.SizeKey).ToString()); if (datItem.GetStringFieldValue(Models.Metadata.Rom.CRCKey) != null) datItem.SetFieldValue(Models.Metadata.Rom.CRCKey, TextHelper.NormalizeCRC32(datItem.GetStringFieldValue(Models.Metadata.Rom.CRCKey))); if (datItem.GetStringFieldValue(Models.Metadata.Rom.MD5Key) != null) datItem.SetFieldValue(Models.Metadata.Rom.MD5Key, TextHelper.NormalizeMD5(datItem.GetStringFieldValue(Models.Metadata.Rom.MD5Key))); if (datItem.GetStringFieldValue(Models.Metadata.Rom.SHA1Key) != null) datItem.SetFieldValue(Models.Metadata.Rom.SHA1Key, TextHelper.NormalizeSHA1(datItem.GetStringFieldValue(Models.Metadata.Rom.SHA1Key))); if (datItem.GetStringFieldValue(Models.Metadata.Rom.SHA256Key) != null) datItem.SetFieldValue(Models.Metadata.Rom.SHA256Key, TextHelper.NormalizeSHA256(datItem.GetStringFieldValue(Models.Metadata.Rom.SHA256Key))); if (datItem.GetStringFieldValue(Models.Metadata.Rom.SHA384Key) != null) datItem.SetFieldValue(Models.Metadata.Rom.SHA384Key, TextHelper.NormalizeSHA384(datItem.GetStringFieldValue(Models.Metadata.Rom.SHA384Key))); if (datItem.GetStringFieldValue(Models.Metadata.Rom.SHA512Key) != null) datItem.SetFieldValue(Models.Metadata.Rom.SHA512Key, TextHelper.NormalizeSHA512(datItem.GetStringFieldValue(Models.Metadata.Rom.SHA512Key))); ParseAddHelper(datItem, statsOnly); ParseAddHelper(datItem, machineIndex, sourceIndex, statsOnly); } } /// /// Convert Feature information /// /// Array of internal items to convert /// Machine to use with the converted items /// Index of the Machine to use with the converted items /// Source to use with the converted items /// Index of the Source to use with the converted items /// True to only add item statistics while parsing, false otherwise private void ProcessItems(Models.Metadata.Feature[]? items, Machine machine, long machineIndex, Source source, long sourceIndex, bool statsOnly) { // If the array is null or empty, return without processing if (items == null || items.Length == 0) return; // Loop through the items and add foreach (var item in items) { var datItem = new DatItems.Formats.Feature(item); datItem.SetFieldValue(DatItems.DatItem.SourceKey, source); datItem.CopyMachineInformation(machine); // Process flag values if (datItem.GetStringFieldValue(Models.Metadata.Feature.OverallKey) != null) datItem.SetFieldValue(Models.Metadata.Feature.OverallKey, datItem.GetStringFieldValue(Models.Metadata.Feature.OverallKey).AsEnumValue().AsStringValue()); if (datItem.GetStringFieldValue(Models.Metadata.Feature.StatusKey) != null) datItem.SetFieldValue(Models.Metadata.Feature.StatusKey, datItem.GetStringFieldValue(Models.Metadata.Feature.StatusKey).AsEnumValue().AsStringValue()); if (datItem.GetStringFieldValue(Models.Metadata.Feature.FeatureTypeKey) != null) datItem.SetFieldValue(Models.Metadata.Feature.FeatureTypeKey, datItem.GetStringFieldValue(Models.Metadata.Feature.FeatureTypeKey).AsEnumValue().AsStringValue()); ParseAddHelper(datItem, statsOnly); ParseAddHelper(datItem, machineIndex, sourceIndex, statsOnly); } } /// /// Convert Info information /// /// Array of internal items to convert /// Machine to use with the converted items /// Index of the Machine to use with the converted items /// Source to use with the converted items /// Index of the Source to use with the converted items /// True to only add item statistics while parsing, false otherwise private void ProcessItems(Models.Metadata.Info[]? items, Machine machine, long machineIndex, Source source, long sourceIndex, bool statsOnly) { // If the array is null or empty, return without processing if (items == null || items.Length == 0) return; // Loop through the items and add foreach (var item in items) { var datItem = new DatItems.Formats.Info(item); datItem.SetFieldValue(DatItems.DatItem.SourceKey, source); datItem.CopyMachineInformation(machine); ParseAddHelper(datItem, statsOnly); ParseAddHelper(datItem, machineIndex, sourceIndex, statsOnly); } } /// /// Convert Input information /// /// Array of internal items to convert /// Machine to use with the converted items /// Index of the Machine to use with the converted items /// Source to use with the converted items /// Index of the Source to use with the converted items /// True to only add item statistics while parsing, false otherwise private void ProcessItems(Models.Metadata.Input[]? items, Machine machine, long machineIndex, Source source, long sourceIndex, bool statsOnly) { // If the array is null or empty, return without processing if (items == null || items.Length == 0) return; // Loop through the items and add foreach (var item in items) { var datItem = new DatItems.Formats.Input(item); datItem.SetFieldValue(DatItems.DatItem.SourceKey, source); datItem.CopyMachineInformation(machine); // Process flag values if (datItem.GetInt64FieldValue(Models.Metadata.Input.ButtonsKey) != null) datItem.SetFieldValue(Models.Metadata.Input.ButtonsKey, datItem.GetInt64FieldValue(Models.Metadata.Input.ButtonsKey).ToString()); if (datItem.GetInt64FieldValue(Models.Metadata.Input.CoinsKey) != null) datItem.SetFieldValue(Models.Metadata.Input.CoinsKey, datItem.GetInt64FieldValue(Models.Metadata.Input.CoinsKey).ToString()); if (datItem.GetInt64FieldValue(Models.Metadata.Input.PlayersKey) != null) datItem.SetFieldValue(Models.Metadata.Input.PlayersKey, datItem.GetInt64FieldValue(Models.Metadata.Input.PlayersKey).ToString()); if (datItem.GetBoolFieldValue(Models.Metadata.Input.ServiceKey) != null) datItem.SetFieldValue(Models.Metadata.Input.ServiceKey, datItem.GetBoolFieldValue(Models.Metadata.Input.ServiceKey).FromYesNo()); if (datItem.GetBoolFieldValue(Models.Metadata.Input.TiltKey) != null) datItem.SetFieldValue(Models.Metadata.Input.TiltKey, datItem.GetBoolFieldValue(Models.Metadata.Input.TiltKey).FromYesNo()); // Handle subitems var controls = ReadItemArray(item, Models.Metadata.Input.ControlKey); if (controls != null) { var subControls = new List(); foreach (var control in controls) { var subItem = new DatItems.Formats.Control(control); // Process flag values if (subItem.GetInt64FieldValue(Models.Metadata.Control.ButtonsKey) != null) subItem.SetFieldValue(Models.Metadata.Control.ButtonsKey, subItem.GetInt64FieldValue(Models.Metadata.Control.ButtonsKey).ToString()); if (subItem.GetInt64FieldValue(Models.Metadata.Control.KeyDeltaKey) != null) subItem.SetFieldValue(Models.Metadata.Control.KeyDeltaKey, subItem.GetInt64FieldValue(Models.Metadata.Control.KeyDeltaKey).ToString()); if (subItem.GetInt64FieldValue(Models.Metadata.Control.MaximumKey) != null) subItem.SetFieldValue(Models.Metadata.Control.MaximumKey, subItem.GetInt64FieldValue(Models.Metadata.Control.MaximumKey).ToString()); if (subItem.GetInt64FieldValue(Models.Metadata.Control.MinimumKey) != null) subItem.SetFieldValue(Models.Metadata.Control.MinimumKey, subItem.GetInt64FieldValue(Models.Metadata.Control.MinimumKey).ToString()); if (subItem.GetInt64FieldValue(Models.Metadata.Control.PlayerKey) != null) subItem.SetFieldValue(Models.Metadata.Control.PlayerKey, subItem.GetInt64FieldValue(Models.Metadata.Control.PlayerKey).ToString()); if (subItem.GetInt64FieldValue(Models.Metadata.Control.ReqButtonsKey) != null) subItem.SetFieldValue(Models.Metadata.Control.ReqButtonsKey, subItem.GetInt64FieldValue(Models.Metadata.Control.ReqButtonsKey).ToString()); if (subItem.GetBoolFieldValue(Models.Metadata.Control.ReverseKey) != null) subItem.SetFieldValue(Models.Metadata.Control.ReverseKey, subItem.GetBoolFieldValue(Models.Metadata.Control.ReverseKey).FromYesNo()); if (subItem.GetInt64FieldValue(Models.Metadata.Control.SensitivityKey) != null) subItem.SetFieldValue(Models.Metadata.Control.SensitivityKey, subItem.GetInt64FieldValue(Models.Metadata.Control.SensitivityKey).ToString()); if (subItem.GetStringFieldValue(Models.Metadata.Control.ControlTypeKey) != null) subItem.SetFieldValue(Models.Metadata.Control.ControlTypeKey, subItem.GetStringFieldValue(Models.Metadata.Control.ControlTypeKey).AsEnumValue().AsStringValue()); subControls.Add(subItem); } datItem.SetFieldValue(Models.Metadata.Input.ControlKey, [.. subControls]); } ParseAddHelper(datItem, statsOnly); ParseAddHelper(datItem, machineIndex, sourceIndex, statsOnly); } } /// /// Convert Media information /// /// Array of internal items to convert /// Machine to use with the converted items /// Index of the Machine to use with the converted items /// Source to use with the converted items /// Index of the Source to use with the converted items /// True to only add item statistics while parsing, false otherwise private void ProcessItems(Models.Metadata.Media[]? items, Machine machine, long machineIndex, Source source, long sourceIndex, bool statsOnly) { // If the array is null or empty, return without processing if (items == null || items.Length == 0) return; // Loop through the items and add foreach (var item in items) { var datItem = new DatItems.Formats.Media(item); datItem.SetFieldValue(DatItems.DatItem.SourceKey, source); datItem.CopyMachineInformation(machine); // Process hash values if (datItem.GetStringFieldValue(Models.Metadata.Media.MD5Key) != null) datItem.SetFieldValue(Models.Metadata.Media.MD5Key, TextHelper.NormalizeMD5(datItem.GetStringFieldValue(Models.Metadata.Media.MD5Key))); if (datItem.GetStringFieldValue(Models.Metadata.Media.SHA1Key) != null) datItem.SetFieldValue(Models.Metadata.Media.SHA1Key, TextHelper.NormalizeSHA1(datItem.GetStringFieldValue(Models.Metadata.Media.SHA1Key))); if (datItem.GetStringFieldValue(Models.Metadata.Media.SHA256Key) != null) datItem.SetFieldValue(Models.Metadata.Media.SHA256Key, TextHelper.NormalizeSHA256(datItem.GetStringFieldValue(Models.Metadata.Media.SHA256Key))); ParseAddHelper(datItem, statsOnly); ParseAddHelper(datItem, machineIndex, sourceIndex, statsOnly); } } /// /// Convert Part information /// /// Array of internal items to convert /// Machine to use with the converted items /// Index of the Machine to use with the converted items /// Source to use with the converted items /// Index of the Source to use with the converted items /// True to only add item statistics while parsing, false otherwise private void ProcessItems(Models.Metadata.Part[]? items, Machine machine, long machineIndex, Source source, long sourceIndex, bool statsOnly) { // If the array is null or empty, return without processing if (items == null || items.Length == 0) return; // Loop through the items and add foreach (var item in items) { var partItem = new DatItems.Formats.Part(item); // Handle subitems var dataAreas = ReadItemArray(item, Models.Metadata.Part.DataAreaKey); if (dataAreas != null) { foreach (var dataArea in dataAreas) { var dataAreaItem = new DatItems.Formats.DataArea(dataArea); var roms = ReadItemArray(dataArea, Models.Metadata.DataArea.RomKey); if (roms == null) continue; // Process flag values if (dataAreaItem.GetStringFieldValue(Models.Metadata.DataArea.EndiannessKey) != null) dataAreaItem.SetFieldValue(Models.Metadata.DataArea.EndiannessKey, dataAreaItem.GetStringFieldValue(Models.Metadata.DataArea.EndiannessKey).AsEnumValue().AsStringValue()); if (dataAreaItem.GetInt64FieldValue(Models.Metadata.DataArea.SizeKey) != null) dataAreaItem.SetFieldValue(Models.Metadata.DataArea.SizeKey, dataAreaItem.GetInt64FieldValue(Models.Metadata.DataArea.SizeKey).ToString()); if (dataAreaItem.GetInt64FieldValue(Models.Metadata.DataArea.WidthKey) != null) dataAreaItem.SetFieldValue(Models.Metadata.DataArea.WidthKey, dataAreaItem.GetInt64FieldValue(Models.Metadata.DataArea.WidthKey).ToString()); foreach (var rom in roms) { var romItem = new DatItems.Formats.Rom(rom); romItem.SetFieldValue(DatItems.Formats.Rom.DataAreaKey, dataAreaItem); romItem.SetFieldValue(DatItems.Formats.Rom.PartKey, partItem); romItem.SetFieldValue(DatItems.DatItem.SourceKey, source); romItem.CopyMachineInformation(machine); // Process flag values if (romItem.GetBoolFieldValue(Models.Metadata.Rom.DisposeKey) != null) romItem.SetFieldValue(Models.Metadata.Rom.DisposeKey, romItem.GetBoolFieldValue(Models.Metadata.Rom.DisposeKey).FromYesNo()); if (romItem.GetBoolFieldValue(Models.Metadata.Rom.InvertedKey) != null) romItem.SetFieldValue(Models.Metadata.Rom.InvertedKey, romItem.GetBoolFieldValue(Models.Metadata.Rom.InvertedKey).FromYesNo()); if (romItem.GetStringFieldValue(Models.Metadata.Rom.LoadFlagKey) != null) romItem.SetFieldValue(Models.Metadata.Rom.LoadFlagKey, romItem.GetStringFieldValue(Models.Metadata.Rom.LoadFlagKey).AsEnumValue().AsStringValue()); if (romItem.GetStringFieldValue(Models.Metadata.Rom.OpenMSXMediaType) != null) romItem.SetFieldValue(Models.Metadata.Rom.OpenMSXMediaType, romItem.GetStringFieldValue(Models.Metadata.Rom.OpenMSXMediaType).AsEnumValue().AsStringValue()); if (romItem.GetBoolFieldValue(Models.Metadata.Rom.MIAKey) != null) romItem.SetFieldValue(Models.Metadata.Rom.MIAKey, romItem.GetBoolFieldValue(Models.Metadata.Rom.MIAKey).FromYesNo()); if (romItem.GetBoolFieldValue(Models.Metadata.Rom.OptionalKey) != null) romItem.SetFieldValue(Models.Metadata.Rom.OptionalKey, romItem.GetBoolFieldValue(Models.Metadata.Rom.OptionalKey).FromYesNo()); if (romItem.GetBoolFieldValue(Models.Metadata.Rom.SoundOnlyKey) != null) romItem.SetFieldValue(Models.Metadata.Rom.SoundOnlyKey, romItem.GetBoolFieldValue(Models.Metadata.Rom.SoundOnlyKey).FromYesNo()); if (romItem.GetStringFieldValue(Models.Metadata.Rom.StatusKey) != null) romItem.SetFieldValue(Models.Metadata.Rom.StatusKey, romItem.GetStringFieldValue(Models.Metadata.Rom.StatusKey).AsEnumValue().AsStringValue()); // Process hash values if (romItem.GetInt64FieldValue(Models.Metadata.Rom.SizeKey) != null) romItem.SetFieldValue(Models.Metadata.Rom.SizeKey, romItem.GetInt64FieldValue(Models.Metadata.Rom.SizeKey).ToString()); if (romItem.GetStringFieldValue(Models.Metadata.Rom.CRCKey) != null) romItem.SetFieldValue(Models.Metadata.Rom.CRCKey, TextHelper.NormalizeCRC32(romItem.GetStringFieldValue(Models.Metadata.Rom.CRCKey))); if (romItem.GetStringFieldValue(Models.Metadata.Rom.MD5Key) != null) romItem.SetFieldValue(Models.Metadata.Rom.MD5Key, TextHelper.NormalizeMD5(romItem.GetStringFieldValue(Models.Metadata.Rom.MD5Key))); if (romItem.GetStringFieldValue(Models.Metadata.Rom.SHA1Key) != null) romItem.SetFieldValue(Models.Metadata.Rom.SHA1Key, TextHelper.NormalizeSHA1(romItem.GetStringFieldValue(Models.Metadata.Rom.SHA1Key))); if (romItem.GetStringFieldValue(Models.Metadata.Rom.SHA256Key) != null) romItem.SetFieldValue(Models.Metadata.Rom.SHA256Key, TextHelper.NormalizeSHA256(romItem.GetStringFieldValue(Models.Metadata.Rom.SHA256Key))); if (romItem.GetStringFieldValue(Models.Metadata.Rom.SHA384Key) != null) romItem.SetFieldValue(Models.Metadata.Rom.SHA384Key, TextHelper.NormalizeSHA384(romItem.GetStringFieldValue(Models.Metadata.Rom.SHA384Key))); if (romItem.GetStringFieldValue(Models.Metadata.Rom.SHA512Key) != null) romItem.SetFieldValue(Models.Metadata.Rom.SHA512Key, TextHelper.NormalizeSHA512(romItem.GetStringFieldValue(Models.Metadata.Rom.SHA512Key))); ParseAddHelper(romItem, statsOnly); ParseAddHelper(romItem, machineIndex, sourceIndex, statsOnly); } } } var diskAreas = ReadItemArray(item, Models.Metadata.Part.DiskAreaKey); if (diskAreas != null) { foreach (var diskArea in diskAreas) { var diskAreaitem = new DatItems.Formats.DiskArea(diskArea); var disks = ReadItemArray(diskArea, Models.Metadata.DiskArea.DiskKey); if (disks == null) continue; foreach (var disk in disks) { var diskItem = new DatItems.Formats.Disk(disk); diskItem.SetFieldValue(DatItems.Formats.Disk.DiskAreaKey, diskAreaitem); diskItem.SetFieldValue(DatItems.Formats.Disk.PartKey, partItem); diskItem.SetFieldValue(DatItems.DatItem.SourceKey, source); diskItem.CopyMachineInformation(machine); // Process flag values if (diskItem.GetBoolFieldValue(Models.Metadata.Disk.OptionalKey) != null) diskItem.SetFieldValue(Models.Metadata.Disk.OptionalKey, diskItem.GetBoolFieldValue(Models.Metadata.Disk.OptionalKey).FromYesNo()); if (diskItem.GetStringFieldValue(Models.Metadata.Disk.StatusKey) != null) diskItem.SetFieldValue(Models.Metadata.Disk.StatusKey, diskItem.GetStringFieldValue(Models.Metadata.Disk.StatusKey).AsEnumValue().AsStringValue()); if (diskItem.GetBoolFieldValue(Models.Metadata.Disk.WritableKey) != null) diskItem.SetFieldValue(Models.Metadata.Disk.WritableKey, diskItem.GetBoolFieldValue(Models.Metadata.Disk.WritableKey).FromYesNo()); // Process hash values if (diskItem.GetStringFieldValue(Models.Metadata.Disk.MD5Key) != null) diskItem.SetFieldValue(Models.Metadata.Disk.MD5Key, TextHelper.NormalizeMD5(diskItem.GetStringFieldValue(Models.Metadata.Disk.MD5Key))); if (diskItem.GetStringFieldValue(Models.Metadata.Disk.SHA1Key) != null) diskItem.SetFieldValue(Models.Metadata.Disk.SHA1Key, TextHelper.NormalizeSHA1(diskItem.GetStringFieldValue(Models.Metadata.Disk.SHA1Key))); ParseAddHelper(diskItem, statsOnly); ParseAddHelper(diskItem, machineIndex, sourceIndex, statsOnly); } } } var dipSwitches = ReadItemArray(item, Models.Metadata.Part.DipSwitchKey); if (dipSwitches != null) { foreach (var dipSwitch in dipSwitches) { var dipSwitchItem = new DatItems.Formats.DipSwitch(dipSwitch); dipSwitchItem.SetFieldValue(DatItems.Formats.DipSwitch.PartKey, partItem); dipSwitchItem.SetFieldValue(DatItems.DatItem.SourceKey, source); dipSwitchItem.CopyMachineInformation(machine); // Process flag values if (dipSwitchItem.GetBoolFieldValue(Models.Metadata.DipSwitch.DefaultKey) != null) dipSwitchItem.SetFieldValue(Models.Metadata.DipSwitch.DefaultKey, dipSwitchItem.GetBoolFieldValue(Models.Metadata.DipSwitch.DefaultKey).FromYesNo()); // Handle subitems var condition = dipSwitch.Read(Models.Metadata.DipSwitch.ConditionKey); if (condition != null) { var subItem = new DatItems.Formats.Condition(condition); // Process flag values if (subItem.GetStringFieldValue(Models.Metadata.Condition.RelationKey) != null) subItem.SetFieldValue(Models.Metadata.Condition.RelationKey, subItem.GetStringFieldValue(Models.Metadata.Condition.RelationKey).AsEnumValue().AsStringValue()); dipSwitchItem.SetFieldValue(Models.Metadata.DipSwitch.ConditionKey, subItem); } var dipLocations = ReadItemArray(dipSwitch, Models.Metadata.DipSwitch.DipLocationKey); if (dipLocations != null) { var subLocations = new List(); foreach (var location in dipLocations) { var subItem = new DatItems.Formats.DipLocation(location); // Process flag values if (subItem.GetBoolFieldValue(Models.Metadata.DipLocation.InvertedKey) != null) subItem.SetFieldValue(Models.Metadata.DipLocation.InvertedKey, subItem.GetBoolFieldValue(Models.Metadata.DipLocation.InvertedKey).FromYesNo()); subLocations.Add(subItem); } dipSwitchItem.SetFieldValue(Models.Metadata.DipSwitch.DipLocationKey, [.. subLocations]); } var dipValues = ReadItemArray(dipSwitch, Models.Metadata.DipSwitch.DipValueKey); if (dipValues != null) { var subValues = new List(); foreach (var value in dipValues) { var subItem = new DatItems.Formats.DipValue(value); // Process flag values if (subItem.GetBoolFieldValue(Models.Metadata.DipValue.DefaultKey) != null) subItem.SetFieldValue(Models.Metadata.DipValue.DefaultKey, subItem.GetBoolFieldValue(Models.Metadata.DipValue.DefaultKey).FromYesNo()); var subCondition = dipSwitch.Read(Models.Metadata.DipValue.ConditionKey); if (subCondition != null) { var subSubItem = new DatItems.Formats.Condition(subCondition); // Process flag values if (subSubItem.GetStringFieldValue(Models.Metadata.Condition.RelationKey) != null) subSubItem.SetFieldValue(Models.Metadata.Condition.RelationKey, subSubItem.GetStringFieldValue(Models.Metadata.Condition.RelationKey).AsEnumValue().AsStringValue()); subItem.SetFieldValue(Models.Metadata.DipValue.ConditionKey, subSubItem); } subValues.Add(subItem); } dipSwitchItem.SetFieldValue(Models.Metadata.DipSwitch.DipValueKey, [.. subValues]); } ParseAddHelper(dipSwitchItem, statsOnly); ParseAddHelper(dipSwitchItem, machineIndex, sourceIndex, statsOnly); } } var partFeatures = ReadItemArray(item, Models.Metadata.Part.FeatureKey); if (partFeatures != null) { foreach (var partFeature in partFeatures) { var partFeatureItem = new DatItems.Formats.PartFeature(partFeature); partFeatureItem.SetFieldValue(DatItems.Formats.DipSwitch.PartKey, partItem); partFeatureItem.SetFieldValue(DatItems.DatItem.SourceKey, source); partFeatureItem.CopyMachineInformation(machine); // Process flag values if (partFeatureItem.GetStringFieldValue(Models.Metadata.Feature.OverallKey) != null) partFeatureItem.SetFieldValue(Models.Metadata.Feature.OverallKey, partFeatureItem.GetStringFieldValue(Models.Metadata.Feature.OverallKey).AsEnumValue().AsStringValue()); if (partFeatureItem.GetStringFieldValue(Models.Metadata.Feature.StatusKey) != null) partFeatureItem.SetFieldValue(Models.Metadata.Feature.StatusKey, partFeatureItem.GetStringFieldValue(Models.Metadata.Feature.StatusKey).AsEnumValue().AsStringValue()); if (partFeatureItem.GetStringFieldValue(Models.Metadata.Feature.FeatureTypeKey) != null) partFeatureItem.SetFieldValue(Models.Metadata.Feature.FeatureTypeKey, partFeatureItem.GetStringFieldValue(Models.Metadata.Feature.FeatureTypeKey).AsEnumValue().AsStringValue()); ParseAddHelper(partFeatureItem, statsOnly); ParseAddHelper(partFeatureItem, machineIndex, sourceIndex, statsOnly); } } } } /// /// Convert Port information /// /// Array of internal items to convert /// Machine to use with the converted items /// Index of the Machine to use with the converted items /// Source to use with the converted items /// Index of the Source to use with the converted items /// True to only add item statistics while parsing, false otherwise private void ProcessItems(Models.Metadata.Port[]? items, Machine machine, long machineIndex, Source source, long sourceIndex, bool statsOnly) { // If the array is null or empty, return without processing if (items == null || items.Length == 0) return; // Loop through the items and add foreach (var item in items) { var datItem = new DatItems.Formats.Port(item); datItem.SetFieldValue(DatItems.DatItem.SourceKey, source); datItem.CopyMachineInformation(machine); // Handle subitems var analogs = ReadItemArray(item, Models.Metadata.Port.AnalogKey); if (analogs != null) { var subAnalogs = new List(); foreach (var analog in analogs) { var subItem = new DatItems.Formats.Analog(analog); subAnalogs.Add(subItem); } datItem.SetFieldValue(Models.Metadata.Port.AnalogKey, [.. subAnalogs]); } ParseAddHelper(datItem, statsOnly); ParseAddHelper(datItem, machineIndex, sourceIndex, statsOnly); } } /// /// Convert RamOption information /// /// Array of internal items to convert /// Machine to use with the converted items /// Index of the Machine to use with the converted items /// Source to use with the converted items /// Index of the Source to use with the converted items /// True to only add item statistics while parsing, false otherwise private void ProcessItems(Models.Metadata.RamOption[]? items, Machine machine, long machineIndex, Source source, long sourceIndex, bool statsOnly) { // If the array is null or empty, return without processing if (items == null || items.Length == 0) return; // Loop through the items and add foreach (var item in items) { var datItem = new DatItems.Formats.RamOption(item); datItem.SetFieldValue(DatItems.DatItem.SourceKey, source); datItem.CopyMachineInformation(machine); // Process flag values if (datItem.GetBoolFieldValue(Models.Metadata.RamOption.DefaultKey) != null) datItem.SetFieldValue(Models.Metadata.RamOption.DefaultKey, datItem.GetBoolFieldValue(Models.Metadata.RamOption.DefaultKey).FromYesNo()); ParseAddHelper(datItem, statsOnly); ParseAddHelper(datItem, machineIndex, sourceIndex, statsOnly); } } /// /// Convert Release information /// /// Array of internal items to convert /// Machine to use with the converted items /// Index of the Machine to use with the converted items /// Source to use with the converted items /// Index of the Source to use with the converted items /// True to only add item statistics while parsing, false otherwise private void ProcessItems(Models.Metadata.Release[]? items, Machine machine, long machineIndex, Source source, long sourceIndex, bool statsOnly) { // If the array is null or empty, return without processing if (items == null || items.Length == 0) return; // Loop through the items and add foreach (var item in items) { var datItem = new DatItems.Formats.Release(item); datItem.SetFieldValue(DatItems.DatItem.SourceKey, source); datItem.CopyMachineInformation(machine); // Process flag values if (datItem.GetBoolFieldValue(Models.Metadata.Release.DefaultKey) != null) datItem.SetFieldValue(Models.Metadata.Release.DefaultKey, datItem.GetBoolFieldValue(Models.Metadata.Release.DefaultKey).FromYesNo()); ParseAddHelper(datItem, statsOnly); ParseAddHelper(datItem, machineIndex, sourceIndex, statsOnly); } } /// /// Convert Rom information /// /// Array of internal items to convert /// Machine to use with the converted items /// Index of the Machine to use with the converted items /// Source to use with the converted items /// Index of the Source to use with the converted items /// True to only add item statistics while parsing, false otherwise private void ProcessItems(Models.Metadata.Rom[]? items, Machine machine, long machineIndex, Source source, long sourceIndex, bool statsOnly) { // If the array is null or empty, return without processing if (items == null || items.Length == 0) return; // Loop through the items and add foreach (var item in items) { var datItem = new DatItems.Formats.Rom(item); datItem.SetFieldValue(DatItems.DatItem.SourceKey, source); datItem.CopyMachineInformation(machine); // Process flag values if (datItem.GetBoolFieldValue(Models.Metadata.Rom.DisposeKey) != null) datItem.SetFieldValue(Models.Metadata.Rom.DisposeKey, datItem.GetBoolFieldValue(Models.Metadata.Rom.DisposeKey).FromYesNo()); if (datItem.GetBoolFieldValue(Models.Metadata.Rom.InvertedKey) != null) datItem.SetFieldValue(Models.Metadata.Rom.InvertedKey, datItem.GetBoolFieldValue(Models.Metadata.Rom.InvertedKey).FromYesNo()); if (datItem.GetStringFieldValue(Models.Metadata.Rom.LoadFlagKey) != null) datItem.SetFieldValue(Models.Metadata.Rom.LoadFlagKey, datItem.GetStringFieldValue(Models.Metadata.Rom.LoadFlagKey).AsEnumValue().AsStringValue()); if (datItem.GetStringFieldValue(Models.Metadata.Rom.OpenMSXMediaType) != null) datItem.SetFieldValue(Models.Metadata.Rom.OpenMSXMediaType, datItem.GetStringFieldValue(Models.Metadata.Rom.OpenMSXMediaType).AsEnumValue().AsStringValue()); if (datItem.GetBoolFieldValue(Models.Metadata.Rom.MIAKey) != null) datItem.SetFieldValue(Models.Metadata.Rom.MIAKey, datItem.GetBoolFieldValue(Models.Metadata.Rom.MIAKey).FromYesNo()); if (datItem.GetBoolFieldValue(Models.Metadata.Rom.OptionalKey) != null) datItem.SetFieldValue(Models.Metadata.Rom.OptionalKey, datItem.GetBoolFieldValue(Models.Metadata.Rom.OptionalKey).FromYesNo()); if (datItem.GetBoolFieldValue(Models.Metadata.Rom.SoundOnlyKey) != null) datItem.SetFieldValue(Models.Metadata.Rom.SoundOnlyKey, datItem.GetBoolFieldValue(Models.Metadata.Rom.SoundOnlyKey).FromYesNo()); if (datItem.GetStringFieldValue(Models.Metadata.Rom.StatusKey) != null) datItem.SetFieldValue(Models.Metadata.Rom.StatusKey, datItem.GetStringFieldValue(Models.Metadata.Rom.StatusKey).AsEnumValue().AsStringValue()); // Process hash values if (datItem.GetInt64FieldValue(Models.Metadata.Rom.SizeKey) != null) datItem.SetFieldValue(Models.Metadata.Rom.SizeKey, datItem.GetInt64FieldValue(Models.Metadata.Rom.SizeKey).ToString()); if (datItem.GetStringFieldValue(Models.Metadata.Rom.CRCKey) != null) datItem.SetFieldValue(Models.Metadata.Rom.CRCKey, TextHelper.NormalizeCRC32(datItem.GetStringFieldValue(Models.Metadata.Rom.CRCKey))); if (datItem.GetStringFieldValue(Models.Metadata.Rom.MD5Key) != null) datItem.SetFieldValue(Models.Metadata.Rom.MD5Key, TextHelper.NormalizeMD5(datItem.GetStringFieldValue(Models.Metadata.Rom.MD5Key))); if (datItem.GetStringFieldValue(Models.Metadata.Rom.SHA1Key) != null) datItem.SetFieldValue(Models.Metadata.Rom.SHA1Key, TextHelper.NormalizeSHA1(datItem.GetStringFieldValue(Models.Metadata.Rom.SHA1Key))); if (datItem.GetStringFieldValue(Models.Metadata.Rom.SHA256Key) != null) datItem.SetFieldValue(Models.Metadata.Rom.SHA256Key, TextHelper.NormalizeSHA256(datItem.GetStringFieldValue(Models.Metadata.Rom.SHA256Key))); if (datItem.GetStringFieldValue(Models.Metadata.Rom.SHA384Key) != null) datItem.SetFieldValue(Models.Metadata.Rom.SHA384Key, TextHelper.NormalizeSHA384(datItem.GetStringFieldValue(Models.Metadata.Rom.SHA384Key))); if (datItem.GetStringFieldValue(Models.Metadata.Rom.SHA512Key) != null) datItem.SetFieldValue(Models.Metadata.Rom.SHA512Key, TextHelper.NormalizeSHA512(datItem.GetStringFieldValue(Models.Metadata.Rom.SHA512Key))); ParseAddHelper(datItem, statsOnly); ParseAddHelper(datItem, machineIndex, sourceIndex, statsOnly); } } /// /// Convert Sample information /// /// Array of internal items to convert /// Machine to use with the converted items /// Index of the Machine to use with the converted items /// Source to use with the converted items /// Index of the Source to use with the converted items /// True to only add item statistics while parsing, false otherwise private void ProcessItems(Models.Metadata.Sample[]? items, Machine machine, long machineIndex, Source source, long sourceIndex, bool statsOnly) { // If the array is null or empty, return without processing if (items == null || items.Length == 0) return; // Loop through the items and add foreach (var item in items) { var datItem = new DatItems.Formats.Sample(item); datItem.SetFieldValue(DatItems.DatItem.SourceKey, source); datItem.CopyMachineInformation(machine); ParseAddHelper(datItem, statsOnly); ParseAddHelper(datItem, machineIndex, sourceIndex, statsOnly); } } /// /// Convert SharedFeat information /// /// Array of internal items to convert /// Machine to use with the converted items /// Index of the Machine to use with the converted items /// Source to use with the converted items /// Index of the Source to use with the converted items /// True to only add item statistics while parsing, false otherwise private void ProcessItems(Models.Metadata.SharedFeat[]? items, Machine machine, long machineIndex, Source source, long sourceIndex, bool statsOnly) { // If the array is null or empty, return without processing if (items == null || items.Length == 0) return; // Loop through the items and add foreach (var item in items) { var datItem = new DatItems.Formats.SharedFeat(item); datItem.SetFieldValue(DatItems.DatItem.SourceKey, source); datItem.CopyMachineInformation(machine); ParseAddHelper(datItem, statsOnly); ParseAddHelper(datItem, machineIndex, sourceIndex, statsOnly); } } /// /// Convert Slot information /// /// Array of internal items to convert /// Machine to use with the converted items /// Index of the Machine to use with the converted items /// Source to use with the converted items /// Index of the Source to use with the converted items /// True to only add item statistics while parsing, false otherwise private void ProcessItems(Models.Metadata.Slot[]? items, Machine machine, long machineIndex, Source source, long sourceIndex, bool statsOnly) { // If the array is null or empty, return without processing if (items == null || items.Length == 0) return; // Loop through the items and add foreach (var item in items) { var datItem = new DatItems.Formats.Slot(item); datItem.SetFieldValue(DatItems.DatItem.SourceKey, source); datItem.CopyMachineInformation(machine); // Handle subitems var slotOptions = ReadItemArray(item, Models.Metadata.Slot.SlotOptionKey); if (slotOptions != null) { var subOptions = new List(); foreach (var slotOption in slotOptions) { var subItem = new DatItems.Formats.SlotOption(slotOption); // Process flag values if (subItem.GetBoolFieldValue(Models.Metadata.SlotOption.DefaultKey) != null) subItem.SetFieldValue(Models.Metadata.SlotOption.DefaultKey, subItem.GetBoolFieldValue(Models.Metadata.SlotOption.DefaultKey).FromYesNo()); subOptions.Add(subItem); } datItem.SetFieldValue(Models.Metadata.Slot.SlotOptionKey, [.. subOptions]); } ParseAddHelper(datItem, statsOnly); ParseAddHelper(datItem, machineIndex, sourceIndex, statsOnly); } } /// /// Convert SoftwareList information /// /// Array of internal items to convert /// Machine to use with the converted items /// Index of the Machine to use with the converted items /// Source to use with the converted items /// Index of the Source to use with the converted items /// True to only add item statistics while parsing, false otherwise private void ProcessItems(Models.Metadata.SoftwareList[]? items, Machine machine, long machineIndex, Source source, long sourceIndex, bool statsOnly) { // If the array is null or empty, return without processing if (items == null || items.Length == 0) return; // Loop through the items and add foreach (var item in items) { var datItem = new DatItems.Formats.SoftwareList(item); datItem.SetFieldValue(DatItems.DatItem.SourceKey, source); datItem.CopyMachineInformation(machine); // Process flag values if (datItem.GetStringFieldValue(Models.Metadata.SoftwareList.StatusKey) != null) datItem.SetFieldValue(Models.Metadata.SoftwareList.StatusKey, datItem.GetStringFieldValue(Models.Metadata.SoftwareList.StatusKey).AsEnumValue().AsStringValue()); ParseAddHelper(datItem, statsOnly); ParseAddHelper(datItem, machineIndex, sourceIndex, statsOnly); } } /// /// Convert Sound information /// /// Array of internal items to convert /// Machine to use with the converted items /// Index of the Machine to use with the converted items /// Source to use with the converted items /// Index of the Source to use with the converted items /// True to only add item statistics while parsing, false otherwise private void ProcessItems(Models.Metadata.Sound[]? items, Machine machine, long machineIndex, Source source, long sourceIndex, bool statsOnly) { // If the array is null or empty, return without processing if (items == null || items.Length == 0) return; // Loop through the items and add foreach (var item in items) { var datItem = new DatItems.Formats.Sound(item); datItem.SetFieldValue(DatItems.DatItem.SourceKey, source); datItem.CopyMachineInformation(machine); // Process flag values if (datItem.GetInt64FieldValue(Models.Metadata.Sound.ChannelsKey) != null) datItem.SetFieldValue(Models.Metadata.Sound.ChannelsKey, datItem.GetInt64FieldValue(Models.Metadata.Sound.ChannelsKey).ToString()); ParseAddHelper(datItem, statsOnly); ParseAddHelper(datItem, machineIndex, sourceIndex, statsOnly); } } /// /// Convert Video information /// /// Array of internal items to convert /// Machine to use with the converted items /// Index of the Machine to use with the converted items /// Source to use with the converted items /// Index of the Source to use with the converted items /// True to only add item statistics while parsing, false otherwise private void ProcessItems(Models.Metadata.Video[]? items, Machine machine, long machineIndex, Source source, long sourceIndex, bool statsOnly) { // If the array is null or empty, return without processing if (items == null || items.Length == 0) return; // Loop through the items and add foreach (var item in items) { var datItem = new DatItems.Formats.Display(item); datItem.SetFieldValue(DatItems.DatItem.SourceKey, source); datItem.CopyMachineInformation(machine); // Process flag values if (datItem.GetInt64FieldValue(Models.Metadata.Video.AspectXKey) != null) datItem.SetFieldValue(Models.Metadata.Video.AspectXKey, datItem.GetInt64FieldValue(Models.Metadata.Video.AspectXKey).ToString()); if (datItem.GetInt64FieldValue(Models.Metadata.Video.AspectYKey) != null) datItem.SetFieldValue(Models.Metadata.Video.AspectYKey, datItem.GetInt64FieldValue(Models.Metadata.Video.AspectYKey).ToString()); if (datItem.GetInt64FieldValue(Models.Metadata.Video.HeightKey) != null) datItem.SetFieldValue(Models.Metadata.Display.HeightKey, datItem.GetInt64FieldValue(Models.Metadata.Video.HeightKey).ToString()); if (datItem.GetDoubleFieldValue(Models.Metadata.Video.RefreshKey) != null) datItem.SetFieldValue(Models.Metadata.Display.RefreshKey, datItem.GetDoubleFieldValue(Models.Metadata.Video.RefreshKey).ToString()); if (datItem.GetStringFieldValue(Models.Metadata.Video.ScreenKey) != null) datItem.SetFieldValue(Models.Metadata.Display.DisplayTypeKey, datItem.GetStringFieldValue(Models.Metadata.Video.ScreenKey).AsEnumValue().AsStringValue()); if (datItem.GetInt64FieldValue(Models.Metadata.Video.WidthKey) != null) datItem.SetFieldValue(Models.Metadata.Display.WidthKey, datItem.GetInt64FieldValue(Models.Metadata.Video.WidthKey).ToString()); ParseAddHelper(datItem, statsOnly); ParseAddHelper(datItem, machineIndex, sourceIndex, statsOnly); } } /// /// Read an item array from a given key, if possible /// private static T[]? ReadItemArray(Models.Metadata.DictionaryBase item, string key) where T : Models.Metadata.DictionaryBase { var items = item.Read(key); if (items == default) { var single = item.Read(key); if (single != default) items = [single]; } return items; } #endregion } }