Files
SabreTools/SabreTools.DatFiles/Formats/Listxml.Writer.cs

954 lines
43 KiB
C#
Raw Normal View History

2023-08-01 10:31:38 -04:00
using System;
using System.Collections.Generic;
2023-08-01 13:30:34 -04:00
using System.Linq;
2023-08-01 10:31:38 -04:00
using SabreTools.Core;
using SabreTools.Core.Tools;
using SabreTools.DatItems;
using SabreTools.DatItems.Formats;
namespace SabreTools.DatFiles.Formats
{
/// <summary>
/// Represents writing a MAME XML DAT
/// </summary>
internal partial class Listxml : DatFile
{
/// <inheritdoc/>
protected override ItemType[] GetSupportedTypes()
{
2024-02-28 19:19:50 -05:00
return
[
2023-08-01 10:31:38 -04:00
ItemType.Adjuster,
ItemType.BiosSet,
ItemType.Chip,
ItemType.Condition,
ItemType.Configuration,
ItemType.Device,
ItemType.DeviceReference,
ItemType.DipSwitch,
ItemType.Disk,
ItemType.Display,
ItemType.Driver,
ItemType.Feature,
ItemType.Input,
ItemType.Port,
ItemType.RamOption,
ItemType.Rom,
ItemType.Sample,
ItemType.Slot,
ItemType.SoftwareList,
ItemType.Sound,
2024-02-28 19:19:50 -05:00
];
2023-08-01 10:31:38 -04:00
}
/// <inheritdoc/>
2024-03-05 23:41:00 -05:00
protected override List<string>? GetMissingRequiredFields(DatItem datItem)
2023-08-01 10:31:38 -04:00
{
2024-03-05 23:41:00 -05:00
var missingFields = new List<string>();
2023-08-01 12:03:12 -04:00
switch (datItem)
{
case BiosSet biosset:
2024-03-08 20:42:24 -05:00
if (string.IsNullOrEmpty(biosset.GetName()))
2024-03-05 23:41:00 -05:00
missingFields.Add(Models.Metadata.BiosSet.NameKey);
2024-03-09 21:34:26 -05:00
if (string.IsNullOrEmpty(biosset.GetFieldValue<string?>(Models.Metadata.BiosSet.DescriptionKey)))
2024-03-05 23:41:00 -05:00
missingFields.Add(Models.Metadata.BiosSet.DescriptionKey);
2023-08-01 12:03:12 -04:00
break;
case Rom rom:
2024-03-08 20:42:24 -05:00
if (string.IsNullOrEmpty(rom.GetName()))
2024-03-05 23:41:00 -05:00
missingFields.Add(Models.Metadata.Rom.NameKey);
2024-03-09 21:34:26 -05:00
if (rom.GetFieldValue<long?>(Models.Metadata.Rom.SizeKey) == null || rom.GetFieldValue<long?>(Models.Metadata.Rom.SizeKey) < 0)
2024-03-05 23:41:00 -05:00
missingFields.Add(Models.Metadata.Rom.SizeKey);
2024-03-09 21:34:26 -05:00
if (string.IsNullOrEmpty(rom.GetFieldValue<string?>(Models.Metadata.Rom.CRCKey))
&& string.IsNullOrEmpty(rom.GetFieldValue<string?>(Models.Metadata.Rom.SHA1Key)))
2023-08-01 12:03:12 -04:00
{
2024-03-05 23:41:00 -05:00
missingFields.Add(Models.Metadata.Rom.SHA1Key);
2023-08-01 12:03:12 -04:00
}
break;
case Disk disk:
2024-03-08 20:42:24 -05:00
if (string.IsNullOrEmpty(disk.GetName()))
2024-03-05 23:41:00 -05:00
missingFields.Add(Models.Metadata.Disk.NameKey);
2024-03-09 21:34:26 -05:00
if (string.IsNullOrEmpty(disk.GetFieldValue<string?>(Models.Metadata.Disk.MD5Key))
&& string.IsNullOrEmpty(disk.GetFieldValue<string?>(Models.Metadata.Disk.SHA1Key)))
2023-08-01 12:03:12 -04:00
{
2024-03-05 23:41:00 -05:00
missingFields.Add(Models.Metadata.Disk.SHA1Key);
2023-08-01 12:03:12 -04:00
}
break;
case DeviceReference deviceref:
2024-03-08 20:42:24 -05:00
if (string.IsNullOrEmpty(deviceref.GetName()))
2024-03-05 23:41:00 -05:00
missingFields.Add(Models.Metadata.DeviceRef.NameKey);
2023-08-01 12:03:12 -04:00
break;
case Sample sample:
2024-03-08 20:42:24 -05:00
if (string.IsNullOrEmpty(sample.GetName()))
2024-03-05 23:41:00 -05:00
missingFields.Add(Models.Metadata.Sample.NameKey);
2023-08-01 12:03:12 -04:00
break;
case Chip chip:
2024-03-08 20:42:24 -05:00
if (string.IsNullOrEmpty(chip.GetName()))
2024-03-05 23:41:00 -05:00
missingFields.Add(Models.Metadata.Chip.NameKey);
2024-03-09 21:34:26 -05:00
if (chip.GetFieldValue<ChipType>(Models.Metadata.Chip.ChipTypeKey) == ChipType.NULL)
2024-03-05 23:41:00 -05:00
missingFields.Add(Models.Metadata.Chip.ChipTypeKey);
2023-08-01 12:03:12 -04:00
break;
case Display display:
2024-03-09 21:34:26 -05:00
if (display.GetFieldValue<DisplayType>(Models.Metadata.Display.DisplayTypeKey) == DisplayType.NULL)
2024-03-05 23:41:00 -05:00
missingFields.Add(Models.Metadata.Display.DisplayTypeKey);
2024-03-09 21:34:26 -05:00
if (display.GetFieldValue<double?>(Models.Metadata.Display.RefreshKey) == null)
2024-03-05 23:41:00 -05:00
missingFields.Add(Models.Metadata.Display.RefreshKey);
2023-08-01 12:03:12 -04:00
break;
case Sound sound:
2024-03-09 21:34:26 -05:00
if (sound.GetFieldValue<long?>(Models.Metadata.Sound.ChannelsKey) == null)
2024-03-05 23:41:00 -05:00
missingFields.Add(Models.Metadata.Sound.ChannelsKey);
2023-08-01 12:03:12 -04:00
break;
case Input input:
2024-03-09 21:34:26 -05:00
if (input.GetFieldValue<long?>(Models.Metadata.Input.PlayersKey) == null)
2024-03-05 23:41:00 -05:00
missingFields.Add(Models.Metadata.Input.PlayersKey);
2023-08-01 12:03:12 -04:00
break;
case DipSwitch dipswitch:
2024-03-08 20:42:24 -05:00
if (string.IsNullOrEmpty(dipswitch.GetName()))
2024-03-05 23:41:00 -05:00
missingFields.Add(Models.Metadata.DipSwitch.NameKey);
2024-03-09 21:34:26 -05:00
if (string.IsNullOrEmpty(dipswitch.GetFieldValue<string?>(Models.Metadata.DipSwitch.TagKey)))
2024-03-05 23:41:00 -05:00
missingFields.Add(Models.Metadata.DipSwitch.TagKey);
2023-08-01 12:03:12 -04:00
break;
case Configuration configuration:
2024-03-08 20:42:24 -05:00
if (string.IsNullOrEmpty(configuration.GetName()))
2024-03-05 23:41:00 -05:00
missingFields.Add(Models.Metadata.Configuration.NameKey);
2024-03-09 21:34:26 -05:00
if (string.IsNullOrEmpty(configuration.GetFieldValue<string>(Models.Metadata.Configuration.TagKey)))
2024-03-05 23:41:00 -05:00
missingFields.Add(Models.Metadata.Configuration.TagKey);
2023-08-01 12:03:12 -04:00
break;
case Port port:
2024-03-09 21:34:26 -05:00
if (string.IsNullOrEmpty(port.GetFieldValue<string>(Models.Metadata.Port.TagKey)))
2024-03-05 23:41:00 -05:00
missingFields.Add(Models.Metadata.Port.TagKey);
2023-08-01 12:03:12 -04:00
break;
case Adjuster adjuster:
2024-03-08 20:42:24 -05:00
if (string.IsNullOrEmpty(adjuster.GetName()))
2024-03-05 23:41:00 -05:00
missingFields.Add(Models.Metadata.Adjuster.NameKey);
2023-08-01 12:03:12 -04:00
break;
case Driver driver:
2024-03-09 21:34:26 -05:00
if (driver.GetFieldValue<SupportStatus>(Models.Metadata.Driver.StatusKey) == SupportStatus.NULL)
2024-03-05 23:41:00 -05:00
missingFields.Add(Models.Metadata.Driver.StatusKey);
2024-03-09 21:34:26 -05:00
if (driver.GetFieldValue<SupportStatus>(Models.Metadata.Driver.EmulationKey) == SupportStatus.NULL)
2024-03-05 23:41:00 -05:00
missingFields.Add(Models.Metadata.Driver.EmulationKey);
2024-03-09 21:34:26 -05:00
if (driver.GetFieldValue<SupportStatus>(Models.Metadata.Driver.CocktailKey) == SupportStatus.NULL)
2024-03-05 23:41:00 -05:00
missingFields.Add(Models.Metadata.Driver.CocktailKey);
2024-03-09 21:34:26 -05:00
if (driver.GetFieldValue<SupportStatus>(Models.Metadata.Driver.SaveStateKey) == SupportStatus.NULL)
2024-03-05 23:41:00 -05:00
missingFields.Add(Models.Metadata.Driver.SaveStateKey);
2023-08-01 12:03:12 -04:00
break;
case Feature feature:
2024-03-09 21:34:26 -05:00
if (feature.GetFieldValue<FeatureType>(Models.Metadata.Feature.FeatureTypeKey) == FeatureType.NULL)
2024-03-05 23:41:00 -05:00
missingFields.Add(Models.Metadata.Feature.FeatureTypeKey);
2023-08-01 12:03:12 -04:00
break;
case Device device:
2024-03-09 21:34:26 -05:00
if (device.GetFieldValue<DeviceType>(Models.Metadata.Device.DeviceTypeKey) != DeviceType.NULL)
2024-03-05 23:41:00 -05:00
missingFields.Add(Models.Metadata.Device.DeviceTypeKey);
2023-08-01 12:03:12 -04:00
break;
case Slot slot:
2024-03-08 20:42:24 -05:00
if (string.IsNullOrEmpty(slot.GetName()))
2024-03-05 23:41:00 -05:00
missingFields.Add(Models.Metadata.Slot.NameKey);
2023-08-01 12:03:12 -04:00
break;
case DatItems.Formats.SoftwareList softwarelist:
2024-03-09 21:34:26 -05:00
if (string.IsNullOrEmpty(softwarelist.GetFieldValue<string?>(Models.Metadata.SoftwareList.TagKey)))
2024-03-05 23:41:00 -05:00
missingFields.Add(Models.Metadata.SoftwareList.TagKey);
2024-03-08 20:42:24 -05:00
if (string.IsNullOrEmpty(softwarelist.GetName()))
2024-03-05 23:41:00 -05:00
missingFields.Add(Models.Metadata.SoftwareList.NameKey);
2024-03-09 21:34:26 -05:00
if (softwarelist.GetFieldValue<SoftwareListStatus?>(Models.Metadata.SoftwareList.StatusKey) == SoftwareListStatus.None)
2024-03-05 23:41:00 -05:00
missingFields.Add(Models.Metadata.SoftwareList.StatusKey);
2023-08-01 12:03:12 -04:00
break;
case RamOption ramoption:
2024-03-08 20:42:24 -05:00
if (string.IsNullOrEmpty(ramoption.GetName()))
2024-03-05 23:41:00 -05:00
missingFields.Add(Models.Metadata.RamOption.NameKey);
2023-08-01 12:03:12 -04:00
break;
}
return missingFields;
2023-08-01 10:31:38 -04:00
}
/// <inheritdoc/>
public override bool WriteToFile(string outfile, bool ignoreblanks = false, bool throwOnError = false)
{
try
{
logger.User($"Writing to '{outfile}'...");
2023-08-01 13:30:34 -04:00
var mame = CreateMame(ignoreblanks);
2023-09-11 01:20:21 -04:00
if (!(new Serialization.Files.Listxml().Serialize(mame, outfile)))
2023-08-01 10:31:38 -04:00
{
2023-08-01 13:30:34 -04:00
logger.Warning($"File '{outfile}' could not be written! See the log for more details.");
2023-08-01 10:31:38 -04:00
return false;
}
}
catch (Exception ex) when (!throwOnError)
{
logger.Error(ex);
return false;
}
2023-08-01 13:30:34 -04:00
logger.User($"'{outfile}' written!{Environment.NewLine}");
2023-08-01 10:31:38 -04:00
return true;
}
2023-08-01 13:30:34 -04:00
#region Converters
/// <summary>
/// Create a Mame from the current internal information
/// <summary>
/// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise</param>
private Models.Listxml.Mame CreateMame(bool ignoreblanks)
{
var datafile = new Models.Listxml.Mame
{
Build = Header.Name ?? Header.Description ?? Header.Build,
Debug = Header.Debug.FromYesNo(),
MameConfig = Header.MameConfig,
Game = CreateGames(ignoreblanks)
};
return datafile;
}
/// <summary>
/// Create an array of GameBase from the current internal information
/// <summary>
/// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise</param>
private Models.Listxml.GameBase[]? CreateGames(bool ignoreblanks)
{
// If we don't have items, we can't do anything
if (this.Items == null || !this.Items.Any())
return null;
// Create a list of hold the games
var games = new List<Models.Listxml.GameBase>();
// 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;
// Get the first item for game information
var machine = items[0].Machine;
2024-02-28 19:19:50 -05:00
var game = Listxml.CreateGame(machine!);
2023-08-01 13:30:34 -04:00
// Create holders for all item types
var biosSets = new List<Models.Listxml.BiosSet>();
var roms = new List<Models.Listxml.Rom>();
var disks = new List<Models.Listxml.Disk>();
var deviceRefs = new List<Models.Listxml.DeviceRef>();
var samples = new List<Models.Listxml.Sample>();
var chips = new List<Models.Listxml.Chip>();
var displays = new List<Models.Listxml.Display>();
var dipSwitches = new List<Models.Listxml.DipSwitch>();
var configurations = new List<Models.Listxml.Configuration>();
var ports = new List<Models.Listxml.Port>();
var adjusters = new List<Models.Listxml.Adjuster>();
var features = new List<Models.Listxml.Feature>();
var devices = new List<Models.Listxml.Device>();
var slots = new List<Models.Listxml.Slot>();
var softwareLists = new List<Models.Listxml.SoftwareList>();
var ramOptions = new List<Models.Listxml.RamOption>();
// 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 BiosSet biosset:
biosSets.Add(CreateBiosSet(biosset));
break;
case Rom rom:
roms.Add(CreateRom(rom));
break;
case Disk disk:
disks.Add(CreateDisk(disk));
break;
case DeviceReference deviceref:
deviceRefs.Add(CreateDeviceRef(deviceref));
break;
case Sample sample:
samples.Add(CreateSample(sample));
break;
case Chip chip:
chips.Add(CreateChip(chip));
break;
case Display display:
displays.Add(CreateDisplay(display));
break;
case Sound sound:
game.Sound = CreateSound(sound);
break;
case Input input:
game.Input = CreateInput(input);
break;
case DipSwitch dipswitch:
dipSwitches.Add(CreateDipSwitch(dipswitch));
break;
case Configuration configuration:
configurations.Add(CreateConfiguration(configuration));
break;
case Port port:
ports.Add(CreatePort(port));
break;
case Adjuster adjuster:
adjusters.Add(CreateAdjuster(adjuster));
break;
case Driver driver:
game.Driver = CreateDriver(driver);
break;
case Feature feature:
features.Add(CreateFeature(feature));
break;
case Device device:
devices.Add(CreateDevice(device));
break;
case Slot slot:
slots.Add(CreateSlot(slot));
break;
case DatItems.Formats.SoftwareList softwarelist:
softwareLists.Add(CreateSoftwareList(softwarelist));
break;
case RamOption ramoption:
ramOptions.Add(CreateRamOption(ramoption));
break;
}
}
// Assign the values to the game
2024-02-28 19:19:50 -05:00
game.BiosSet = [.. biosSets];
game.Rom = [.. roms];
game.Disk = [.. disks];
game.DeviceRef = [.. deviceRefs];
game.Sample = [.. samples];
game.Chip = [.. chips];
game.Display = [.. displays];
2023-08-01 13:30:34 -04:00
game.Video = null;
2024-02-28 19:19:50 -05:00
game.DipSwitch = [.. dipSwitches];
game.Configuration = [.. configurations];
game.Port = [.. ports];
game.Adjuster = [.. adjusters];
game.Feature = [.. features];
game.Device = [.. devices];
game.Slot = [.. slots];
game.SoftwareList = [.. softwareLists];
game.RamOption = [.. ramOptions];
2023-08-01 13:30:34 -04:00
// Add the game to the list
games.Add(game);
}
2024-02-28 19:19:50 -05:00
return [.. games];
2023-08-01 13:30:34 -04:00
}
/// <summary>
/// Create a GameBase from the current internal information
/// <summary>
2024-02-28 19:19:50 -05:00
private static Models.Listxml.GameBase CreateGame(Machine machine)
2023-08-01 13:30:34 -04:00
{
var game = new Models.Listxml.Machine
{
2024-03-09 23:43:43 -05:00
Name = machine.GetFieldValue<string?>(Models.Metadata.Machine.NameKey),
SourceFile = machine.GetFieldValue<string?>(Models.Metadata.Machine.SourceFileKey),
Runnable = machine.GetFieldValue<Runnable>(Models.Metadata.Machine.RunnableKey).AsStringValue<Runnable>(),
CloneOf = machine.GetFieldValue<string?>(Models.Metadata.Machine.CloneOfKey),
RomOf = machine.GetFieldValue<string?>(Models.Metadata.Machine.RomOfKey),
SampleOf = machine.GetFieldValue<string?>(Models.Metadata.Machine.SampleOfKey),
Description = machine.GetFieldValue<string?>(Models.Metadata.Machine.DescriptionKey),
Year = machine.GetFieldValue<string?>(Models.Metadata.Machine.YearKey),
Manufacturer = machine.GetFieldValue<string?>(Models.Metadata.Machine.ManufacturerKey),
History = machine.GetFieldValue<string?>(Models.Metadata.Machine.HistoryKey),
2023-08-01 13:30:34 -04:00
};
2024-03-09 23:43:43 -05:00
if (machine.GetFieldValue<bool?>(Models.Metadata.Machine.IsBiosKey) == true)
2024-02-28 22:54:56 -05:00
game.IsBios = "yes";
2024-03-09 23:43:43 -05:00
if (machine.GetFieldValue<bool?>(Models.Metadata.Machine.IsDeviceKey) == true)
2024-02-28 22:54:56 -05:00
game.IsDevice = "yes";
2024-03-09 23:43:43 -05:00
if (machine.GetFieldValue<bool?>(Models.Metadata.Machine.IsMechanicalKey) == true)
2024-02-28 22:54:56 -05:00
game.IsMechanical = "yes";
2023-08-01 13:30:34 -04:00
return game;
}
/// <summary>
/// Create a BiosSet from the current BiosSet DatItem
/// <summary>
private static Models.Listxml.BiosSet CreateBiosSet(BiosSet item)
{
var biosset = new Models.Listxml.BiosSet
{
2024-03-08 20:42:24 -05:00
Name = item.GetName(),
2024-03-09 21:34:26 -05:00
Default = item.GetFieldValue<bool?>(Models.Metadata.BiosSet.DefaultKey).FromYesNo(),
Description = item.GetFieldValue<string?>(Models.Metadata.BiosSet.DescriptionKey),
2023-08-01 13:30:34 -04:00
};
return biosset;
}
/// <summary>
/// Create a Rom from the current Rom DatItem
/// <summary>
private static Models.Listxml.Rom CreateRom(Rom item)
{
var rom = new Models.Listxml.Rom
{
2024-03-08 20:42:24 -05:00
Name = item.GetName(),
2024-03-09 21:34:26 -05:00
Bios = item.GetFieldValue<string?>(Models.Metadata.Rom.BiosKey),
Size = item.GetFieldValue<long?>(Models.Metadata.Rom.SizeKey)?.ToString(),
CRC = item.GetFieldValue<string?>(Models.Metadata.Rom.CRCKey),
SHA1 = item.GetFieldValue<string?>(Models.Metadata.Rom.SHA1Key),
Merge = item.GetFieldValue<string?>(Models.Metadata.Rom.MergeKey),
Region = item.GetFieldValue<string?>(Models.Metadata.Rom.RegionKey),
Offset = item.GetFieldValue<string?>(Models.Metadata.Rom.OffsetKey),
Status = item.GetFieldValue<ItemStatus>(Models.Metadata.Rom.StatusKey).AsStringValue<ItemStatus>(useSecond: false),
Optional = item.GetFieldValue<bool?>(Models.Metadata.Rom.OptionalKey).FromYesNo(),
Dispose = item.GetFieldValue<bool?>(Models.Metadata.Rom.DisposeKey).FromYesNo(),
SoundOnly = item.GetFieldValue<bool?>(Models.Metadata.Rom.SoundOnlyKey).FromYesNo(),
2023-08-01 13:30:34 -04:00
};
return rom;
}
/// <summary>
/// Create a Disk from the current Disk DatItem
/// <summary>
private static Models.Listxml.Disk CreateDisk(Disk item)
{
var disk = new Models.Listxml.Disk
{
2024-03-08 20:42:24 -05:00
Name = item.GetName(),
2024-03-09 21:34:26 -05:00
MD5 = item.GetFieldValue<string?>(Models.Metadata.Disk.MD5Key),
SHA1 = item.GetFieldValue<string?>(Models.Metadata.Disk.SHA1Key),
Merge = item.GetFieldValue<string?>(Models.Metadata.Disk.MergeKey),
Region = item.GetFieldValue<string?>(Models.Metadata.Disk.RegionKey),
Index = item.GetFieldValue<string?>(Models.Metadata.Disk.IndexKey),
Writable = item.GetFieldValue<bool?>(Models.Metadata.Disk.WritableKey).FromYesNo(),
Status = item.GetFieldValue<ItemStatus>(Models.Metadata.Disk.StatusKey).AsStringValue<ItemStatus>(useSecond: false),
Optional = item.GetFieldValue<bool?>(Models.Metadata.Disk.OptionalKey).FromYesNo(),
2023-08-01 13:30:34 -04:00
};
return disk;
}
/// <summary>
/// Create a DeviceRef from the current DeviceReference DatItem
/// <summary>
private static Models.Listxml.DeviceRef CreateDeviceRef(DeviceReference item)
{
var deviceref = new Models.Listxml.DeviceRef
{
2024-03-08 20:42:24 -05:00
Name = item.GetName(),
2023-08-01 13:30:34 -04:00
};
return deviceref;
}
/// <summary>
/// Create a Sample from the current Sample DatItem
/// <summary>
private static Models.Listxml.Sample CreateSample(Sample item)
{
var sample = new Models.Listxml.Sample
{
2024-03-08 20:42:24 -05:00
Name = item.GetName(),
2023-08-01 13:30:34 -04:00
};
return sample;
}
/// <summary>
/// Create a Chip from the current Chip DatItem
/// <summary>
private static Models.Listxml.Chip CreateChip(Chip item)
{
var chip = new Models.Listxml.Chip
{
2024-03-08 20:42:24 -05:00
Name = item.GetName(),
2024-03-09 21:34:26 -05:00
Tag = item.GetFieldValue<string?>(Models.Metadata.Chip.TagKey),
Type = item.GetFieldValue<ChipType>(Models.Metadata.Chip.ChipTypeKey).AsStringValue<ChipType>(),
SoundOnly = item.GetFieldValue<bool?>(Models.Metadata.Chip.SoundOnlyKey).FromYesNo(),
Clock = item.GetFieldValue<long?>(Models.Metadata.Chip.TagKey)?.ToString(),
2023-08-01 13:30:34 -04:00
};
return chip;
}
/// <summary>
/// Create a Display from the current Display DatItem
/// <summary>
private static Models.Listxml.Display CreateDisplay(Display item)
{
var display = new Models.Listxml.Display
{
2024-03-09 21:34:26 -05:00
Tag = item.GetFieldValue<string?>(Models.Metadata.Display.TagKey),
Type = item.GetFieldValue<DisplayType>(Models.Metadata.Display.DisplayTypeKey).AsStringValue<DisplayType>(),
Rotate = item.GetFieldValue<long?>(Models.Metadata.Display.RotateKey)?.ToString(),
FlipX = item.GetFieldValue<bool?>(Models.Metadata.Display.FlipXKey).FromYesNo(),
Width = item.GetFieldValue<string?>(Models.Metadata.Display.WidthKey)?.ToString(),
Height = item.GetFieldValue<string?>(Models.Metadata.Display.HeightKey)?.ToString(),
Refresh = item.GetFieldValue<double?>(Models.Metadata.Display.RefreshKey)?.ToString(),
PixClock = item.GetFieldValue<string?>(Models.Metadata.Display.PixClockKey)?.ToString(),
HTotal = item.GetFieldValue<string?>(Models.Metadata.Display.HTotalKey)?.ToString(),
HBEnd = item.GetFieldValue<string?>(Models.Metadata.Display.HBEndKey)?.ToString(),
HBStart = item.GetFieldValue<string?>(Models.Metadata.Display.HBStartKey)?.ToString(),
VTotal = item.GetFieldValue<string?>(Models.Metadata.Display.VTotalKey)?.ToString(),
VBEnd = item.GetFieldValue<string?>(Models.Metadata.Display.VBEndKey)?.ToString(),
VBStart = item.GetFieldValue<string?>(Models.Metadata.Display.VBStartKey)?.ToString(),
2023-08-01 13:30:34 -04:00
};
return display;
}
/// <summary>
/// Create a Sound from the current Sound DatItem
/// <summary>
private static Models.Listxml.Sound CreateSound(Sound item)
{
var sound = new Models.Listxml.Sound
{
2024-03-09 21:34:26 -05:00
Channels = item.GetFieldValue<long?>(Models.Metadata.Sound.ChannelsKey)?.ToString(),
2023-08-01 13:30:34 -04:00
};
return sound;
}
/// <summary>
/// Create an Input from the current Input DatItem
/// <summary>
private static Models.Listxml.Input CreateInput(Input item)
{
var input = new Models.Listxml.Input
{
2024-03-09 21:34:26 -05:00
Service = item.GetFieldValue<bool?>(Models.Metadata.Input.ServiceKey).FromYesNo(),
Tilt = item.GetFieldValue<bool?>(Models.Metadata.Input.TiltKey).FromYesNo(),
Players = item.GetFieldValue<long?>(Models.Metadata.Input.PlayersKey)?.ToString(),
//ControlAttr = item.GetFieldValue<string?>(Models.Metadata.Input.ControlKey),
Buttons = item.GetFieldValue<long?>(Models.Metadata.Input.ButtonsKey)?.ToString(),
Coins = item.GetFieldValue<long?>(Models.Metadata.Input.CoinsKey)?.ToString(),
2023-08-01 13:30:34 -04:00
};
var controls = new List<Models.Listxml.Control>();
2024-03-09 21:34:26 -05:00
foreach (var controlItem in item.GetFieldValue<Control[]?>(Models.Metadata.Input.ControlKey) ?? [])
2023-08-01 13:30:34 -04:00
{
var control = CreateControl(controlItem);
controls.Add(control);
}
if (controls.Any())
2024-02-28 19:19:50 -05:00
input.Control = [.. controls];
2023-08-01 13:30:34 -04:00
return input;
}
/// <summary>
/// Create an Control from the current Input DatItem
/// <summary>
private static Models.Listxml.Control CreateControl(Control item)
{
var control = new Models.Listxml.Control
{
2024-03-09 21:34:26 -05:00
Type = item.GetFieldValue<ControlType>(Models.Metadata.Control.ControlTypeKey).AsStringValue<ControlType>(),
Player = item.GetFieldValue<long?>(Models.Metadata.Control.PlayerKey)?.ToString(),
Buttons = item.GetFieldValue<long?>(Models.Metadata.Control.ButtonsKey)?.ToString(),
ReqButtons = item.GetFieldValue<long?>(Models.Metadata.Control.ReqButtonsKey)?.ToString(),
Minimum = item.GetFieldValue<long?>(Models.Metadata.Control.MinimumKey)?.ToString(),
Maximum = item.GetFieldValue<long?>(Models.Metadata.Control.MaximumKey)?.ToString(),
Sensitivity = item.GetFieldValue<long?>(Models.Metadata.Control.SensitivityKey)?.ToString(),
KeyDelta = item.GetFieldValue<long?>(Models.Metadata.Control.KeyDeltaKey)?.ToString(),
Reverse = item.GetFieldValue<bool?>(Models.Metadata.Control.ReverseKey).FromYesNo(),
Ways = item.GetFieldValue<string?>(Models.Metadata.Control.WaysKey),
Ways2 = item.GetFieldValue<string?>(Models.Metadata.Control.Ways2Key),
Ways3 = item.GetFieldValue<string?>(Models.Metadata.Control.Ways3Key),
2023-08-01 13:30:34 -04:00
};
return control;
}
/// <summary>
/// Create an DipSwitch from the current DipSwitch DatItem
/// <summary>
private static Models.Listxml.DipSwitch CreateDipSwitch(DipSwitch item)
{
var dipswitch = new Models.Listxml.DipSwitch
{
2024-03-08 20:42:24 -05:00
Name = item.GetName(),
2024-03-09 21:34:26 -05:00
Tag = item.GetFieldValue<string?>(Models.Metadata.DipSwitch.TagKey),
Mask = item.GetFieldValue<string?>(Models.Metadata.DipSwitch.MaskKey),
2023-08-01 13:30:34 -04:00
};
if (item.ConditionsSpecified)
{
2024-03-09 21:34:26 -05:00
var conditionItem = item.GetFieldValue<Condition[]?>(Models.Metadata.DipSwitch.ConditionKey)?.FirstOrDefault();
2023-08-01 13:30:34 -04:00
var condition = new Models.Listxml.Condition
{
2024-03-09 21:34:26 -05:00
Tag = conditionItem?.GetFieldValue<string?>(Models.Metadata.Condition.TagKey),
Mask = conditionItem?.GetFieldValue<string?>(Models.Metadata.Condition.MaskKey),
Relation = conditionItem?.GetFieldValue<Relation>(Models.Metadata.Condition.RelationKey).AsStringValue<Relation>(),
Value = conditionItem?.GetFieldValue<string?>(Models.Metadata.Condition.ValueKey),
2023-08-01 13:30:34 -04:00
};
dipswitch.Condition = condition;
}
var diplocations = new List<Models.Listxml.DipLocation>();
2024-03-09 21:34:26 -05:00
foreach (var locationItem in item.GetFieldValue<DipLocation[]?>(Models.Metadata.DipSwitch.DipLocationKey) ?? [])
2023-08-01 13:30:34 -04:00
{
var control = CreateDipLocation(locationItem);
diplocations.Add(control);
}
if (diplocations.Any())
2024-02-28 19:19:50 -05:00
dipswitch.DipLocation = [.. diplocations];
2023-08-01 13:30:34 -04:00
var dipvalues = new List<Models.Listxml.DipValue>();
2024-03-09 21:34:26 -05:00
foreach (var dipValueItem in item.GetFieldValue<DipValue[]?>(Models.Metadata.DipSwitch.DipValueKey) ?? [])
2023-08-01 13:30:34 -04:00
{
var dipvalue = CreateDipValue(dipValueItem);
2023-08-01 13:30:34 -04:00
dipvalues.Add(dipvalue);
}
if (dipvalues.Any())
2024-02-28 19:19:50 -05:00
dipswitch.DipValue = [.. dipvalues];
2023-08-01 13:30:34 -04:00
return dipswitch;
}
/// <summary>
/// Create a DipLocation from the current DipLocation DatItem
2023-08-01 13:30:34 -04:00
/// <summary>
private static Models.Listxml.DipLocation CreateDipLocation(DipLocation item)
2023-08-01 13:30:34 -04:00
{
var diplocation = new Models.Listxml.DipLocation
{
2024-03-08 20:42:24 -05:00
Name = item.GetName(),
2024-03-09 21:34:26 -05:00
Number = item.GetFieldValue<long?>(Models.Metadata.DipLocation.NumberKey)?.ToString(),
Inverted = item.GetFieldValue<bool?>(Models.Metadata.DipLocation.InvertedKey).FromYesNo(),
2023-08-01 13:30:34 -04:00
};
return diplocation;
}
/// <summary>
/// Create a DipValue from the current DipValue DatItem
2023-08-01 13:30:34 -04:00
/// <summary>
private static Models.Listxml.DipValue CreateDipValue(DipValue item)
2023-08-01 13:30:34 -04:00
{
var dipvalue = new Models.Listxml.DipValue
{
2024-03-08 20:42:24 -05:00
Name = item.GetName(),
2024-03-09 21:34:26 -05:00
Value = item.GetFieldValue<string?>(Models.Metadata.DipValue.ValueKey),
Default = item.GetFieldValue<bool?>(Models.Metadata.DipValue.DefaultKey).FromYesNo(),
2023-08-01 13:30:34 -04:00
};
if (item.ConditionsSpecified)
{
2024-03-09 21:34:26 -05:00
var conditionItem = item.GetFieldValue<Condition[]?>(Models.Metadata.DipValue.ConditionKey)?.FirstOrDefault();
2023-08-01 13:30:34 -04:00
var condition = new Models.Listxml.Condition
{
2024-03-09 21:34:26 -05:00
Tag = conditionItem?.GetFieldValue<string?>(Models.Metadata.Condition.TagKey),
Mask = conditionItem?.GetFieldValue<string?>(Models.Metadata.Condition.MaskKey),
Relation = conditionItem?.GetFieldValue<Relation>(Models.Metadata.Condition.RelationKey).AsStringValue<Relation>(),
Value = conditionItem?.GetFieldValue<string?>(Models.Metadata.Condition.ValueKey),
2023-08-01 13:30:34 -04:00
};
dipvalue.Condition = condition;
}
return dipvalue;
}
/// <summary>
/// Create an Configuration from the current Configuration DatItem
/// <summary>
private static Models.Listxml.Configuration CreateConfiguration(Configuration item)
{
var configuration = new Models.Listxml.Configuration
{
2024-03-08 20:42:24 -05:00
Name = item.GetName(),
2024-03-09 21:34:26 -05:00
Tag = item.GetFieldValue<string>(Models.Metadata.Configuration.TagKey),
Mask = item.GetFieldValue<string>(Models.Metadata.Configuration.MaskKey),
2023-08-01 13:30:34 -04:00
};
if (item.ConditionsSpecified)
{
2024-03-09 21:34:26 -05:00
var conditionItem = item.GetFieldValue<Condition[]?>(Models.Metadata.Configuration.ConditionKey)?.FirstOrDefault();
2023-08-01 13:30:34 -04:00
var condition = new Models.Listxml.Condition
{
2024-03-09 21:34:26 -05:00
Tag = conditionItem?.GetFieldValue<string?>(Models.Metadata.Condition.TagKey),
Mask = conditionItem?.GetFieldValue<string?>(Models.Metadata.Condition.MaskKey),
Relation = conditionItem?.GetFieldValue<Relation>(Models.Metadata.Condition.RelationKey).AsStringValue<Relation>(),
Value = conditionItem?.GetFieldValue<string?>(Models.Metadata.Condition.ValueKey),
2023-08-01 13:30:34 -04:00
};
configuration.Condition = condition;
}
var confLocations = new List<Models.Listxml.ConfLocation>();
2024-03-09 21:34:26 -05:00
foreach (var location in item.GetFieldValue<ConfLocation[]?>(Models.Metadata.Configuration.ConfLocationKey) ?? [])
2023-08-01 13:30:34 -04:00
{
var control = CreateConfLocation(location);
confLocations.Add(control);
}
if (confLocations.Any())
2024-02-28 19:19:50 -05:00
configuration.ConfLocation = [.. confLocations];
2023-08-01 13:30:34 -04:00
var confsettings = new List<Models.Listxml.ConfSetting>();
2024-03-09 21:34:26 -05:00
foreach (var confSettingItem in item.GetFieldValue<ConfSetting[]?>(Models.Metadata.Configuration.ConfSettingKey) ?? [])
2023-08-01 13:30:34 -04:00
{
var dipvalue = CreateConfSetting(confSettingItem);
2023-08-01 13:30:34 -04:00
confsettings.Add(dipvalue);
}
if (confsettings.Any())
2024-02-28 19:19:50 -05:00
configuration.ConfSetting = [.. confsettings];
2023-08-01 13:30:34 -04:00
return configuration;
}
/// <summary>
/// Create a ConfLocation from the current ConfLocation DatItem
2023-08-01 13:30:34 -04:00
/// <summary>
private static Models.Listxml.ConfLocation CreateConfLocation(ConfLocation item)
2023-08-01 13:30:34 -04:00
{
var conflocation = new Models.Listxml.ConfLocation
{
2024-03-08 20:42:24 -05:00
Name = item.GetName(),
2024-03-09 21:34:26 -05:00
Number = item.GetFieldValue<long?>(Models.Metadata.ConfLocation.NumberKey)?.ToString(),
Inverted = item.GetFieldValue<bool?>(Models.Metadata.ConfLocation.InvertedKey).FromYesNo(),
2023-08-01 13:30:34 -04:00
};
return conflocation;
}
/// <summary>
/// Create a ConfSetting from the current ConfSetting DatItem
2023-08-01 13:30:34 -04:00
/// <summary>
private static Models.Listxml.ConfSetting CreateConfSetting(ConfSetting item)
2023-08-01 13:30:34 -04:00
{
var confsetting = new Models.Listxml.ConfSetting
{
2024-03-08 20:42:24 -05:00
Name = item.GetName(),
2024-03-09 21:34:26 -05:00
Value = item.GetFieldValue<string?>(Models.Metadata.ConfSetting.ValueKey),
Default = item.GetFieldValue<bool?>(Models.Metadata.ConfSetting.DefaultKey).FromYesNo(),
2023-08-01 13:30:34 -04:00
};
if (item.ConditionsSpecified)
{
2024-03-09 21:34:26 -05:00
var conditionItem = item.GetFieldValue<Condition[]?>(Models.Metadata.ConfSetting.ConditionKey)?.FirstOrDefault();
2023-08-01 13:30:34 -04:00
var condition = new Models.Listxml.Condition
{
2024-03-09 21:34:26 -05:00
Tag = conditionItem?.GetFieldValue<string?>(Models.Metadata.Condition.TagKey),
Mask = conditionItem?.GetFieldValue<string?>(Models.Metadata.Condition.MaskKey),
Relation = conditionItem?.GetFieldValue<Relation>(Models.Metadata.Condition.RelationKey).AsStringValue<Relation>(),
Value = conditionItem?.GetFieldValue<string?>(Models.Metadata.Condition.ValueKey),
2023-08-01 13:30:34 -04:00
};
confsetting.Condition = condition;
}
return confsetting;
}
/// <summary>
/// Create a Port from the current Port DatItem
/// <summary>
private static Models.Listxml.Port CreatePort(Port item)
{
var port = new Models.Listxml.Port
{
2024-03-09 21:34:26 -05:00
Tag = item.GetFieldValue<string>(Models.Metadata.Port.TagKey),
2023-08-01 13:30:34 -04:00
};
return port;
}
/// <summary>
/// Create a Adjuster from the current Adjuster DatItem
/// <summary>
private static Models.Listxml.Adjuster CreateAdjuster(Adjuster item)
{
var adjuster = new Models.Listxml.Adjuster
{
2024-03-08 20:42:24 -05:00
Name = item.GetName(),
2024-03-08 21:12:13 -05:00
Default = item.GetFieldValue<bool?>(Models.Metadata.Adjuster.DefaultKey).FromYesNo(),
2023-08-01 13:30:34 -04:00
};
if (item.ConditionsSpecified)
{
2024-03-08 21:12:13 -05:00
var conditionItem = item.GetFieldValue<Condition[]?>(Models.Metadata.Adjuster.ConditionKey)?.FirstOrDefault();
2023-08-01 13:30:34 -04:00
var condition = new Models.Listxml.Condition
{
2024-03-09 21:34:26 -05:00
Tag = conditionItem?.GetFieldValue<string?>(Models.Metadata.Condition.TagKey),
Mask = conditionItem?.GetFieldValue<string?>(Models.Metadata.Condition.MaskKey),
Relation = conditionItem?.GetFieldValue<Relation>(Models.Metadata.Condition.RelationKey).AsStringValue<Relation>(),
Value = conditionItem?.GetFieldValue<string?>(Models.Metadata.Condition.ValueKey),
2023-08-01 13:30:34 -04:00
};
adjuster.Condition = condition;
}
return adjuster;
}
/// <summary>
/// Create a Driver from the current Driver DatItem
/// <summary>
private static Models.Listxml.Driver CreateDriver(Driver item)
{
var driver = new Models.Listxml.Driver
{
2024-03-09 21:34:26 -05:00
Status = item.GetFieldValue<SupportStatus>(Models.Metadata.Driver.StatusKey).AsStringValue<SupportStatus>(),
Color = item.GetFieldValue<SupportStatus>(Models.Metadata.Driver.ColorKey).AsStringValue<SupportStatus>(),
Sound = item.GetFieldValue<SupportStatus>(Models.Metadata.Driver.SoundKey).AsStringValue<SupportStatus>(),
PaletteSize = item.GetFieldValue<long?>(Models.Metadata.Driver.PaletteSizeKey)?.ToString(),
Emulation = item.GetFieldValue<SupportStatus>(Models.Metadata.Driver.EmulationKey).AsStringValue<SupportStatus>(),
Cocktail = item.GetFieldValue<SupportStatus>(Models.Metadata.Driver.CocktailKey).AsStringValue<SupportStatus>(),
SaveState = item.GetFieldValue<Supported>(Models.Metadata.Driver.SaveStateKey).AsStringValue<Supported>(useSecond: true),
RequiresArtwork = item.GetFieldValue<bool?>(Models.Metadata.Driver.RequiresArtworkKey).FromYesNo(),
Unofficial = item.GetFieldValue<bool?>(Models.Metadata.Driver.UnofficialKey).FromYesNo(),
NoSoundHardware = item.GetFieldValue<bool?>(Models.Metadata.Driver.NoSoundHardwareKey).FromYesNo(),
Incomplete = item.GetFieldValue<bool?>(Models.Metadata.Driver.IncompleteKey).FromYesNo(),
2023-08-01 13:30:34 -04:00
};
return driver;
}
/// <summary>
/// Create a Feature from the current Feature DatItem
/// <summary>
private static Models.Listxml.Feature CreateFeature(Feature item)
{
var feature = new Models.Listxml.Feature
{
2024-03-09 21:34:26 -05:00
Type = item.GetFieldValue<FeatureType>(Models.Metadata.Feature.FeatureTypeKey).AsStringValue<FeatureType>(),
Status = item.GetFieldValue<FeatureStatus>(Models.Metadata.Feature.StatusKey).AsStringValue<FeatureStatus>(),
Overall = item.GetFieldValue<FeatureStatus>(Models.Metadata.Feature.OverallKey).AsStringValue<FeatureStatus>(),
2023-08-01 13:30:34 -04:00
};
return feature;
}
/// <summary>
/// Create a Device from the current Device DatItem
/// <summary>
private static Models.Listxml.Device CreateDevice(Device item)
{
var device = new Models.Listxml.Device
{
2024-03-09 21:34:26 -05:00
Type = item.GetFieldValue<DeviceType>(Models.Metadata.Device.DeviceTypeKey).AsStringValue<DeviceType>(),
Tag = item.GetFieldValue<string?>(Models.Metadata.Device.TagKey),
FixedImage = item.GetFieldValue<string?>(Models.Metadata.Device.FixedImageKey),
Mandatory = item.GetFieldValue<long?>(Models.Metadata.Device.MandatoryKey)?.ToString(),
Interface = item.GetFieldValue<string?>(Models.Metadata.Device.InterfaceKey),
2023-08-01 13:30:34 -04:00
};
if (item.InstancesSpecified)
{
2024-03-09 21:34:26 -05:00
var instanceItem = item.GetFieldValue<Instance[]?>(Models.Metadata.Device.InstanceKey)?.FirstOrDefault();
2023-08-01 13:30:34 -04:00
var instance = new Models.Listxml.Instance
{
2024-03-08 20:42:24 -05:00
Name = instanceItem?.GetName(),
2024-03-09 21:34:26 -05:00
BriefName = instanceItem?.GetFieldValue<string?>(Models.Metadata.Instance.BriefNameKey),
2023-08-01 13:30:34 -04:00
};
device.Instance = instance;
}
var extensions = new List<Models.Listxml.Extension>();
2024-03-09 21:34:26 -05:00
foreach (var extensionItem in item.GetFieldValue<Extension[]?>(Models.Metadata.Device.ExtensionKey) ?? [])
2023-08-01 13:30:34 -04:00
{
var extension = new Models.Listxml.Extension
{
2024-03-08 20:42:24 -05:00
Name = extensionItem.GetName(),
2023-08-01 13:30:34 -04:00
};
extensions.Add(extension);
}
if (extensions.Any())
2024-02-28 19:19:50 -05:00
device.Extension = [.. extensions];
2023-08-01 13:30:34 -04:00
return device;
}
/// <summary>
/// Create a Slot from the current Slot DatItem
/// <summary>
private static Models.Listxml.Slot CreateSlot(Slot item)
{
var slot = new Models.Listxml.Slot
{
2024-03-08 20:42:24 -05:00
Name = item.GetName(),
2023-08-01 13:30:34 -04:00
};
var slotoptions = new List<Models.Listxml.SlotOption>();
2024-03-09 21:34:26 -05:00
foreach (var slotoptionItem in item.GetFieldValue<SlotOption[]?>(Models.Metadata.Slot.SlotOptionKey) ?? [])
2023-08-01 13:30:34 -04:00
{
var slotoption = new Models.Listxml.SlotOption
{
2024-03-08 20:42:24 -05:00
Name = slotoptionItem.GetName(),
2024-03-09 21:34:26 -05:00
DevName = slotoptionItem.GetFieldValue<string?>(Models.Metadata.SlotOption.DevNameKey),
Default = slotoptionItem.GetFieldValue<bool?>(Models.Metadata.SlotOption.DefaultKey).FromYesNo(),
2023-08-01 13:30:34 -04:00
};
slotoptions.Add(slotoption);
}
if (slotoptions.Any())
2024-02-28 19:19:50 -05:00
slot.SlotOption = [.. slotoptions];
2023-08-01 13:30:34 -04:00
return slot;
}
/// <summary>
/// Create a SoftwareList from the current SoftwareList DatItem
/// <summary>
private static Models.Listxml.SoftwareList CreateSoftwareList(DatItems.Formats.SoftwareList item)
{
var softwarelist = new Models.Listxml.SoftwareList
{
2024-03-09 21:34:26 -05:00
Tag = item.GetFieldValue<string?>(Models.Metadata.SoftwareList.TagKey),
2024-03-08 20:42:24 -05:00
Name = item.GetName(),
2024-03-09 21:34:26 -05:00
Status = item.GetFieldValue<SoftwareListStatus>(Models.Metadata.SoftwareList.StatusKey).AsStringValue<SoftwareListStatus>(),
Filter = item.GetFieldValue<string?>(Models.Metadata.SoftwareList.FilterKey),
2023-08-01 13:30:34 -04:00
};
return softwarelist;
}
/// <summary>
/// Create a RamOption from the current RamOption DatItem
/// <summary>
private static Models.Listxml.RamOption CreateRamOption(RamOption item)
{
var softwarelist = new Models.Listxml.RamOption
{
2024-03-08 20:42:24 -05:00
Name = item.GetName(),
2024-03-09 21:34:26 -05:00
Default = item.GetFieldValue<bool?>(Models.Metadata.RamOption.DefaultKey).FromYesNo(),
Content = item.GetFieldValue<string?>(Models.Metadata.RamOption.ContentKey),
2023-08-01 13:30:34 -04:00
};
return softwarelist;
}
#endregion
2023-08-01 10:31:38 -04:00
}
}