diff --git a/SabreTools.Library/DatFiles/DatFile.cs b/SabreTools.Library/DatFiles/DatFile.cs index 361c68ec..700e6bb4 100644 --- a/SabreTools.Library/DatFiles/DatFile.cs +++ b/SabreTools.Library/DatFiles/DatFile.cs @@ -1383,87 +1383,112 @@ namespace SabreTools.Library.DatFiles if (Items[game] == null || Items[game].Count == 0) continue; - // If the game (is/is not) a bios, we want to continue + // If the game (is/is not) a device, we want to continue if (dev ^ (Items[game][0].Machine.MachineType.HasFlag(MachineType.Device))) continue; - // If the game has no devices, we continue + // If the game has no devices, mark it + bool devices = true; if (Items[game][0].Machine.DeviceReferences == null - || Items[game][0].Machine.DeviceReferences.Count == 0 - || (slotoptions && Items[game][0].Machine.Slots == null) - || (slotoptions && Items[game][0].Machine.Slots.Count == 0)) + || Items[game][0].Machine.DeviceReferences.Count == 0) { - continue; + devices = false; } - // Determine if the game has any devices or not - List deviceReferences = Items[game][0].Machine.DeviceReferences; - List newdevs = new List(); - foreach (ListXmlDeviceReference deviceReference in deviceReferences) + // If we're checking devices + if (devices) { - // If the device doesn't exist then we continue - if (Items[deviceReference.Name].Count == 0) - continue; - - // Otherwise, copy the items from the device to the current game - DatItem copyFrom = Items[game][0]; - List devItems = Items[deviceReference.Name]; - foreach (DatItem item in devItems) + // Determine if the game has any devices or not + List deviceReferences = Items[game][0].Machine.DeviceReferences.Select(d => d.Name).ToList(); + List newdevs = new List(); + foreach (string deviceReference in deviceReferences) { - DatItem datItem = (DatItem)item.Clone(); - newdevs.AddRange(datItem.Machine.DeviceReferences ?? new List()); - datItem.CopyMachineInformation(copyFrom); - if (Items[game].Where(i => i.Name.ToLowerInvariant() == datItem.Name.ToLowerInvariant()).Count() == 0) + // If the device doesn't exist then we continue + if (Items[deviceReference] == null || Items[deviceReference].Count == 0) + continue; + + // Otherwise, copy the items from the device to the current game + DatItem copyFrom = Items[game][0]; + List devItems = Items[deviceReference]; + foreach (DatItem item in devItems) { - foundnew = true; - Items.Add(game, datItem); - } - } - } - - // Now that every device is accounted for, add the new list of devices, if they don't already exist - foreach (ListXmlDeviceReference device in newdevs) - { - if (!Items[game][0].Machine.DeviceReferences.Select(d => d.Name).Contains(device.Name)) - Items[game][0].Machine.DeviceReferences.Add(new ListXmlDeviceReference() { Name = device.Name }); - } - - // If we're checking slotoptions too - if (slotoptions) - { - // Determine if the game has any slots or not - List slots = Items[game][0].Machine.Slots; - List newSlots = new List(); - foreach (ListXmlSlot slot in slots) - { - foreach (ListXmlSlotOption slotOption in slot.SlotOptions) - { - // If the slotoption doesn't exist then we continue - if (Items[slotOption.Name].Count == 0) - continue; - - // Otherwise, copy the items from the slotoption to the current game - DatItem copyFrom = Items[game][0]; - List slotItems = Items[slotOption.Name]; - foreach (DatItem item in slotItems) + DatItem datItem = (DatItem)item.Clone(); + newdevs.AddRange((datItem.Machine.DeviceReferences ?? new List()).Select(d => d.Name).ToList()); + datItem.CopyMachineInformation(copyFrom); + if (Items[game].Where(i => i.Name.ToLowerInvariant() == datItem.Name.ToLowerInvariant()).Count() == 0) { - DatItem datItem = (DatItem)item.Clone(); - newSlots.AddRange(datItem.Machine.Slots ?? new List()); - - datItem.CopyMachineInformation(copyFrom); - if (Items[game].Where(i => i.Name.ToLowerInvariant() == datItem.Name.ToLowerInvariant()).Count() == 0) - { - foundnew = true; - Items.Add(game, datItem); - } + foundnew = true; + Items.Add(game, datItem); } } } - // Now that every slotoption is accounted for, add the new list of slots, if they don't already exist - foreach (ListXmlSlot slot in newSlots) + // Now that every device is accounted for, add the new list of devices, if they don't already exist + foreach (string device in newdevs) { - Items[game][0].Machine.Slots.Add(slot); + if (!deviceReferences.Contains(device)) + Items[game][0].Machine.DeviceReferences.Add(new ListXmlDeviceReference() { Name = device }); + } + } + + + // If we're checking slotoptions + if (slotoptions) + { + // If the game has no slot options, we continue + if (Items[game][0].Machine.Slots == null + || Items[game][0].Machine.Slots + .SelectMany(s => s.SlotOptions ?? new List()).Count() == 0) + { + continue; + } + + // Determine if the game has any slot options or not + List slotOptions = Items[game][0].Machine.Slots + .Where(s => s.SlotOptions != null && s.SlotOptions.Count != 0) + .SelectMany(s => s.SlotOptions) + .Select(o => o.DeviceName) + .Distinct() + .ToList(); + List newSlotOptions = new List(); + foreach (string slotOption in slotOptions) + { + // If the slot option doesn't exist then we continue + if (Items[slotOption] == null || Items[slotOption].Count == 0) + continue; + + // Otherwise, copy the items from the slot option to the current game + DatItem copyFrom = Items[game][0]; + List slotOptionItems = Items[slotOption]; + foreach (DatItem item in slotOptionItems) + { + DatItem datItem = (DatItem)item.Clone(); + List machineSlotOptions = + (datItem.Machine.Slots ?? new List()) + .Where(s => s.SlotOptions != null && s.SlotOptions.Count != 0) + .SelectMany(s => s.SlotOptions) + .Select(o => o.DeviceName) + .Distinct() + .ToList(); + + newSlotOptions.AddRange(machineSlotOptions); + datItem.CopyMachineInformation(copyFrom); + if (Items[game].Where(i => i.Name.ToLowerInvariant() == datItem.Name.ToLowerInvariant()).Count() == 0) + { + foundnew = true; + Items.Add(game, datItem); + } + } + } + + // Ensure we don't have unnecessary duplicates + newSlotOptions = newSlotOptions.Distinct().ToList(); + + // Now that every slot option is accounted for, add the new list of options, if they don't already exist + foreach (string slotOption in newSlotOptions) + { + if (!slotOptions.Contains(slotOption)) + Items[game][0].Machine.Slots.Add(new ListXmlSlot() { SlotOptions = new List { new ListXmlSlotOption { DeviceName = slotOption } } }); } } } diff --git a/SabreTools.Library/DatFiles/ItemDictionary.cs b/SabreTools.Library/DatFiles/ItemDictionary.cs index 262f0bb6..f2d1d6da 100644 --- a/SabreTools.Library/DatFiles/ItemDictionary.cs +++ b/SabreTools.Library/DatFiles/ItemDictionary.cs @@ -750,9 +750,6 @@ namespace SabreTools.Library.DatFiles DatItem.Sort(ref sortedlist, false); }); } - - // Now clean up all empty keys - ClearEmpty(); } /// diff --git a/SabreTools.Library/DatFiles/Listxml.cs b/SabreTools.Library/DatFiles/Listxml.cs index b78844b4..5eb74cd0 100644 --- a/SabreTools.Library/DatFiles/Listxml.cs +++ b/SabreTools.Library/DatFiles/Listxml.cs @@ -116,7 +116,7 @@ namespace SabreTools.Library.DatFiles reader.MoveToContent(); // Create a new machine - MachineType machineType = MachineType.NULL; + MachineType machineType = 0x0; if (reader.GetAttribute("isbios").AsYesNo() == true) machineType |= MachineType.Bios; @@ -133,7 +133,7 @@ namespace SabreTools.Library.DatFiles CloneOf = reader.GetAttribute("cloneof"), RomOf = reader.GetAttribute("romof"), SampleOf = reader.GetAttribute("sampleof"), - MachineType = (machineType == MachineType.NULL ? MachineType.NULL : machineType), + MachineType = (machineType == 0x0 ? MachineType.NULL : machineType), SourceFile = reader.GetAttribute("sourcefile"), Runnable = reader.GetAttribute("runnable").AsRunnable(), diff --git a/SabreTools.Library/DatFiles/Logiqx.cs b/SabreTools.Library/DatFiles/Logiqx.cs index dac92795..9d2b0483 100644 --- a/SabreTools.Library/DatFiles/Logiqx.cs +++ b/SabreTools.Library/DatFiles/Logiqx.cs @@ -289,7 +289,7 @@ namespace SabreTools.Library.DatFiles bool containsItems = false; // Create a new machine - MachineType machineType = MachineType.NULL; + MachineType machineType = 0x0; if (reader.GetAttribute("isbios").AsYesNo() == true) machineType |= MachineType.Bios; @@ -313,7 +313,7 @@ namespace SabreTools.Library.DatFiles RomOf = reader.GetAttribute("romof"), SampleOf = reader.GetAttribute("sampleof"), - MachineType = (machineType == MachineType.NULL ? MachineType.NULL : machineType), + MachineType = (machineType == 0x0 ? MachineType.NULL : machineType), }; if (Header.Type == "SuperDAT" && !keep) diff --git a/SabreTools.Library/DatFiles/SoftwareList.cs b/SabreTools.Library/DatFiles/SoftwareList.cs index 658e4654..c4e22b09 100644 --- a/SabreTools.Library/DatFiles/SoftwareList.cs +++ b/SabreTools.Library/DatFiles/SoftwareList.cs @@ -115,7 +115,7 @@ namespace SabreTools.Library.DatFiles bool containsItems = false; // Create a new machine - MachineType machineType = MachineType.NULL; + MachineType machineType = 0x0; if (reader.GetAttribute("isbios").AsYesNo() == true) machineType |= MachineType.Bios; @@ -132,7 +132,7 @@ namespace SabreTools.Library.DatFiles Supported = reader.GetAttribute("supported").AsSupported(), CloneOf = reader.GetAttribute("cloneof"), - MachineType = (machineType != MachineType.NULL ? machineType : MachineType.NULL), + MachineType = (machineType == 0x0 ? MachineType.NULL : machineType), }; while (!reader.EOF) diff --git a/SabreTools.Library/DatItems/DatItem.cs b/SabreTools.Library/DatItems/DatItem.cs index 3516ddf5..76c2b2ea 100644 --- a/SabreTools.Library/DatItems/DatItem.cs +++ b/SabreTools.Library/DatItems/DatItem.cs @@ -1226,24 +1226,10 @@ namespace SabreTools.Library.DatItems { if (x.Machine.Name == y.Machine.Name) { - // Special case for comparing a Disk, Media, or Rom to another item type - if ((x.ItemType == ItemType.Disk || x.ItemType == ItemType.Media || x.ItemType == ItemType.Rom) - ^ (y.ItemType == ItemType.Disk || y.ItemType == ItemType.Media || x.ItemType == ItemType.Rom)) - { - if (x.ItemType == ItemType.Disk || x.ItemType == ItemType.Media || x.ItemType == ItemType.Rom) - return -1; - else - return 1; - } + if (Path.GetDirectoryName(Sanitizer.RemovePathUnsafeCharacters(x.Name)) == Path.GetDirectoryName(Sanitizer.RemovePathUnsafeCharacters(y.Name))) + return nc.Compare(Path.GetFileName(Sanitizer.RemovePathUnsafeCharacters(x.Name)), Path.GetFileName(Sanitizer.RemovePathUnsafeCharacters(y.Name))); - // Otherwise, we compare names naturally - else - { - if (Path.GetDirectoryName(Sanitizer.RemovePathUnsafeCharacters(x.Name)) == Path.GetDirectoryName(Sanitizer.RemovePathUnsafeCharacters(y.Name))) - return nc.Compare(Path.GetFileName(Sanitizer.RemovePathUnsafeCharacters(x.Name)), Path.GetFileName(Sanitizer.RemovePathUnsafeCharacters(y.Name))); - - return nc.Compare(Path.GetDirectoryName(Sanitizer.RemovePathUnsafeCharacters(x.Name)), Path.GetDirectoryName(Sanitizer.RemovePathUnsafeCharacters(y.Name))); - } + return nc.Compare(Path.GetDirectoryName(Sanitizer.RemovePathUnsafeCharacters(x.Name)), Path.GetDirectoryName(Sanitizer.RemovePathUnsafeCharacters(y.Name))); } return nc.Compare(x.Machine.Name, y.Machine.Name); diff --git a/SabreTools.Library/DatItems/Enums.cs b/SabreTools.Library/DatItems/Enums.cs index 7fd7ecfb..0cc6b863 100644 --- a/SabreTools.Library/DatItems/Enums.cs +++ b/SabreTools.Library/DatItems/Enums.cs @@ -439,7 +439,7 @@ namespace SabreTools.Library.DatItems /// /// This is a fake flag that is used for filter only /// - NULL = 0x00, + NULL = 0, None = 1 << 0, Good = 1 << 1, @@ -471,10 +471,14 @@ namespace SabreTools.Library.DatItems [Flags] public enum OpenMSXSubType { + /// + /// This is a fake flag that is used for filter only + /// NULL = 0, - Rom = 1, - MegaRom = 2, - SCCPlusCart = 3, + + Rom = 1 << 0, + MegaRom = 1 << 1, + SCCPlusCart = 1 << 2, } /// @@ -483,10 +487,14 @@ namespace SabreTools.Library.DatItems [Flags] public enum MachineType { - NULL = 0x00, - Bios = 1 << 0, - Device = 1 << 1, - Mechanical = 1 << 2, + /// + /// This is a fake flag that is used for filter only + /// + NULL = 1 << 0, + + Bios = 1 << 1, + Device = 1 << 2, + Mechanical = 1 << 3, } /// @@ -495,10 +503,14 @@ namespace SabreTools.Library.DatItems [Flags] public enum Runnable { - NULL, - No, - Partial, - Yes, + /// + /// This is a fake flag that is used for filter only + /// + NULL = 0, + + No = 1 << 0, + Partial = 1 << 1, + Yes = 1 << 2, } /// @@ -507,9 +519,13 @@ namespace SabreTools.Library.DatItems [Flags] public enum Supported { - NULL, - No, - Partial, - Yes, + /// + /// This is a fake flag that is used for filter only + /// + NULL = 0, + + No = 1 << 0, + Partial = 1 << 1, + Yes = 1 << 2, } } diff --git a/SabreTools.Library/DatItems/Machine.cs b/SabreTools.Library/DatItems/Machine.cs index 92ae5fbc..9578e638 100644 --- a/SabreTools.Library/DatItems/Machine.cs +++ b/SabreTools.Library/DatItems/Machine.cs @@ -85,7 +85,7 @@ namespace SabreTools.Library.DatItems /// [JsonProperty("type", DefaultValueHandling = DefaultValueHandling.Ignore)] [JsonConverter(typeof(StringEnumConverter))] - public MachineType MachineType { get; set; } = MachineType.NULL; + public MachineType MachineType { get; set; } = 0x0; #endregion @@ -740,9 +740,9 @@ namespace SabreTools.Library.DatItems return false; // Machine_Type - if (filter.Machine_Type.MatchesPositive(MachineType.NULL, MachineType) == false) + if (filter.Machine_Type.MatchesPositive(0x0, MachineType) == false) return false; - if (filter.Machine_Type.MatchesNegative(MachineType.NULL, MachineType) == true) + if (filter.Machine_Type.MatchesNegative(0x0, MachineType) == true) return false; #endregion @@ -1501,7 +1501,7 @@ namespace SabreTools.Library.DatItems SampleOf = null; if (fields.Contains(Field.Machine_Type)) - MachineType = MachineType.NULL; + MachineType = 0x0; #endregion diff --git a/SabreTools.Library/Filtering/Filter.cs b/SabreTools.Library/Filtering/Filter.cs index b9256df6..b04190fc 100644 --- a/SabreTools.Library/Filtering/Filter.cs +++ b/SabreTools.Library/Filtering/Filter.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using SabreTools.Library.Data; -using SabreTools.Library.DatFiles; using SabreTools.Library.DatItems; using SabreTools.Library.Tools; @@ -31,7 +30,7 @@ namespace SabreTools.Library.Filtering public FilterItem Machine_RomOf { get; private set; } = new FilterItem(); public FilterItem Machine_CloneOf { get; private set; } = new FilterItem(); public FilterItem Machine_SampleOf { get; private set; } = new FilterItem(); - public FilterItem Machine_Type { get; private set; } = new FilterItem() { Positive = MachineType.NULL, Negative = MachineType.NULL }; + public FilterItem Machine_Type { get; private set; } = new FilterItem() { Positive = 0x0, Negative = 0x0 }; #endregion @@ -51,7 +50,7 @@ namespace SabreTools.Library.Filtering public FilterItem Machine_SourceFile { get; private set; } = new FilterItem(); public FilterItem Machine_Runnable { get; private set; } = new FilterItem() { Positive = Runnable.NULL, Negative = Runnable.NULL }; - + // DeviceReferences public FilterItem Machine_DeviceReferences { get; private set; } = new FilterItem() { Neutral = null }; public FilterItem Machine_DeviceReference_Name { get; private set; } = new FilterItem();