diff --git a/SabreTools.Library/DatFiles/ItemDictionary.cs b/SabreTools.Library/DatFiles/ItemDictionary.cs index 31d211db..e4dd2b0f 100644 --- a/SabreTools.Library/DatFiles/ItemDictionary.cs +++ b/SabreTools.Library/DatFiles/ItemDictionary.cs @@ -119,6 +119,12 @@ namespace SabreTools.Library.DatFiles [JsonIgnore] public long ConfigurationCount { get; private set; } = 0; + /// + /// Number of DataArea items + /// + [JsonIgnore] + public long DataAreaCount { get; private set; } = 0; + /// /// Number of Device items /// @@ -143,6 +149,12 @@ namespace SabreTools.Library.DatFiles [JsonIgnore] public long DiskCount { get; private set; } = 0; + /// + /// Number of DiskArea items + /// + [JsonIgnore] + public long DiskAreaCount { get; private set; } = 0; + /// /// Number of Display items /// @@ -179,6 +191,12 @@ namespace SabreTools.Library.DatFiles [JsonIgnore] public long MediaCount { get; private set; } = 0; + /// + /// Number of Part items + /// + [JsonIgnore] + public long PartCount { get; private set; } = 0; + /// /// Number of PartFeature items /// @@ -586,6 +604,9 @@ namespace SabreTools.Library.DatFiles case ItemType.Configuration: ConfigurationCount++; break; + case ItemType.DataArea: + DataAreaCount++; + break; case ItemType.Device: DeviceCount++; break; @@ -608,6 +629,9 @@ namespace SabreTools.Library.DatFiles NodumpCount += ((item as Disk).ItemStatus == ItemStatus.Nodump ? 1 : 0); VerifiedCount += ((item as Disk).ItemStatus == ItemStatus.Verified ? 1 : 0); break; + case ItemType.DiskArea: + DiskAreaCount++; + break; case ItemType.Display: DisplayCount++; break; @@ -629,6 +653,9 @@ namespace SabreTools.Library.DatFiles SHA1Count += (string.IsNullOrWhiteSpace((item as Media).SHA1) ? 0 : 1); SHA256Count += (string.IsNullOrWhiteSpace((item as Media).SHA256) ? 0 : 1); break; + case ItemType.Part: + PartCount++; + break; case ItemType.PartFeature: PartFeatureCount++; break; @@ -772,6 +799,9 @@ namespace SabreTools.Library.DatFiles case ItemType.Configuration: ConfigurationCount--; break; + case ItemType.DataArea: + DataAreaCount--; + break; case ItemType.Device: DeviceCount--; break; @@ -794,6 +824,9 @@ namespace SabreTools.Library.DatFiles NodumpCount -= ((item as Disk).ItemStatus == ItemStatus.Nodump ? 1 : 0); VerifiedCount -= ((item as Disk).ItemStatus == ItemStatus.Verified ? 1 : 0); break; + case ItemType.DiskArea: + DiskAreaCount--; + break; case ItemType.Display: DisplayCount--; break; @@ -815,6 +848,9 @@ namespace SabreTools.Library.DatFiles SHA1Count -= (string.IsNullOrWhiteSpace((item as Media).SHA1) ? 0 : 1); SHA256Count -= (string.IsNullOrWhiteSpace((item as Media).SHA256) ? 0 : 1); break; + case ItemType.Part: + PartCount--; + break; case ItemType.PartFeature: PartFeatureCount--; break; diff --git a/SabreTools.Library/DatFiles/Json.cs b/SabreTools.Library/DatFiles/Json.cs index 2244e670..8ec1c536 100644 --- a/SabreTools.Library/DatFiles/Json.cs +++ b/SabreTools.Library/DatFiles/Json.cs @@ -235,6 +235,9 @@ namespace SabreTools.Library.DatFiles case ItemType.Control: datItem = datItemObj.ToObject(); break; + case ItemType.DataArea: + datItem = datItemObj.ToObject(); + break; case ItemType.Device: datItem = datItemObj.ToObject(); break; @@ -247,6 +250,9 @@ namespace SabreTools.Library.DatFiles case ItemType.Disk: datItem = datItemObj.ToObject(); break; + case ItemType.DiskArea: + datItem = datItemObj.ToObject(); + break; case ItemType.Display: datItem = datItemObj.ToObject(); break; @@ -274,6 +280,9 @@ namespace SabreTools.Library.DatFiles case ItemType.Media: datItem = datItemObj.ToObject(); break; + case ItemType.Part: + datItem = datItemObj.ToObject(); + break; case ItemType.PartFeature: datItem = datItemObj.ToObject(); break; diff --git a/SabreTools.Library/DatItems/Auxiliary.cs b/SabreTools.Library/DatItems/Auxiliary.cs index 07a1e749..ec61a292 100644 --- a/SabreTools.Library/DatItems/Auxiliary.cs +++ b/SabreTools.Library/DatItems/Auxiliary.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.IO; using System.Linq; @@ -32,78 +33,5 @@ namespace SabreTools.Library.DatItems #endregion - #region SoftwareList - - /// - /// Represents one SoftwareList dataarea object - /// - /// - /// One DataArea can contain multiple Rom items - /// - [JsonObject("dataarea")] - public class DataArea - { - /// - /// Name of the item - /// - [JsonProperty("name", DefaultValueHandling = DefaultValueHandling.Ignore)] - public string Name { get; set; } - - /// - /// Total size of the area - /// - [JsonProperty("size", DefaultValueHandling = DefaultValueHandling.Ignore)] - public long? Size { get; set; } - - /// - /// Word width for the area - /// - [JsonProperty("width", DefaultValueHandling = DefaultValueHandling.Ignore)] - public long? Width { get; set; } - - /// - /// Byte endianness of the area - /// - [JsonProperty("endianness", DefaultValueHandling = DefaultValueHandling.Ignore)] - public Endianness Endianness { get; set; } - } - - /// - /// Represents one SoftwareList diskarea object - /// - /// - /// One DiskArea can contain multiple Disk items - /// - [JsonObject("diskarea")] - public class DiskArea - { - /// - /// Name of the item - /// - [JsonProperty("name", DefaultValueHandling = DefaultValueHandling.Ignore)] - public string Name { get; set; } - } - - /// - /// Represents one SoftwareList part object - /// - /// - /// One Part can contain multiple PartFeature, DataArea, DiskArea, and DipSwitch items - /// - [JsonObject("part")] - public class Part - { - [JsonProperty("name")] - public string Name { get; set; } - - [JsonProperty("interface")] - public string Interface { get; set; } - - [JsonProperty("features", DefaultValueHandling = DefaultValueHandling.Ignore)] - public List Features { get; set; } - } - - #endregion - #endregion //DatItem } diff --git a/SabreTools.Library/DatItems/DatItem.cs b/SabreTools.Library/DatItems/DatItem.cs index 0cf87719..6cb1f0e5 100644 --- a/SabreTools.Library/DatItems/DatItem.cs +++ b/SabreTools.Library/DatItems/DatItem.cs @@ -114,15 +114,7 @@ namespace SabreTools.Library.DatItems Field.DatItem_Boot, // Rom (SoftwareList) - Field.DatItem_AreaName, - Field.DatItem_AreaSize, - Field.DatItem_AreaWidth, - Field.DatItem_AreaEndianness, Field.DatItem_LoadFlag, - Field.DatItem_Part_Name, - Field.DatItem_Part_Interface, - Field.DatItem_Part_Feature_Name, - Field.DatItem_Part_Feature_Value, Field.DatItem_Value, // Disk @@ -169,6 +161,12 @@ namespace SabreTools.Library.DatItems Field.DatItem_Control_Ways2, Field.DatItem_Control_Ways3, + // DataArea + Field.DatItem_AreaName, + Field.DatItem_AreaSize, + Field.DatItem_AreaWidth, + Field.DatItem_AreaEndianness, + // Device Field.DatItem_DeviceType, Field.DatItem_FixedImage, @@ -219,6 +217,14 @@ namespace SabreTools.Library.DatItems Field.DatItem_Location_Number, Field.DatItem_Location_Inverted, + // Part + Field.DatItem_Part_Name, + Field.DatItem_Part_Interface, + + // PartFeature + Field.DatItem_Part_Feature_Name, + Field.DatItem_Part_Feature_Value, + // RamOption Field.DatItem_Content, @@ -394,6 +400,9 @@ namespace SabreTools.Library.DatItems case ItemType.Control: return new Control(); + case ItemType.DataArea: + return new DataArea(); + case ItemType.Device: return new Device(); @@ -406,6 +415,9 @@ namespace SabreTools.Library.DatItems case ItemType.Disk: return new Disk(); + case ItemType.DiskArea: + return new DiskArea(); + case ItemType.Display: return new Display(); @@ -433,6 +445,9 @@ namespace SabreTools.Library.DatItems case ItemType.Media: return new Media(); + case ItemType.Part: + return new Part(); + case ItemType.PartFeature: return new PartFeature(); diff --git a/SabreTools.Library/DatItems/DataArea.cs b/SabreTools.Library/DatItems/DataArea.cs new file mode 100644 index 00000000..0c8370fb --- /dev/null +++ b/SabreTools.Library/DatItems/DataArea.cs @@ -0,0 +1,283 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +using SabreTools.Library.Filtering; +using SabreTools.Library.Tools; +using Newtonsoft.Json; + +namespace SabreTools.Library.DatItems +{ + /// + /// SoftwareList dataarea information + /// + /// One DataArea can contain multiple Rom items + [JsonObject("dataarea")] + public class DataArea : DatItem + { + #region Fields + + /// + /// Name of the item + /// + [JsonProperty("name", DefaultValueHandling = DefaultValueHandling.Ignore)] + public string Name { get; set; } + + /// + /// Total size of the area + /// + [JsonProperty("size", DefaultValueHandling = DefaultValueHandling.Ignore)] + public long? Size { get; set; } + + /// + /// Word width for the area + /// + [JsonProperty("width", DefaultValueHandling = DefaultValueHandling.Ignore)] + public long? Width { get; set; } + + /// + /// Byte endianness of the area + /// + [JsonProperty("endianness", DefaultValueHandling = DefaultValueHandling.Ignore)] + public Endianness Endianness { get; set; } + + #endregion + + #region Accessors + + /// + /// Gets the name to use for a DatItem + /// + /// Name if available, null otherwise + public override string GetName() + { + return Name; + } + + /// + /// Set fields with given values + /// + /// Mappings dictionary + public override void SetFields(Dictionary mappings) + { + // Set base fields + base.SetFields(mappings); + + // Handle DataArea-specific fields + if (mappings.Keys.Contains(Field.DatItem_AreaName)) + Name = mappings[Field.DatItem_AreaName]; + + if (mappings.Keys.Contains(Field.DatItem_AreaSize)) + { + if (Int64.TryParse(mappings[Field.DatItem_AreaSize], out long areaSize)) + Size = areaSize; + } + + if (mappings.Keys.Contains(Field.DatItem_AreaWidth)) + { + if (Int64.TryParse(mappings[Field.DatItem_AreaWidth], out long areaWidth)) + Width = areaWidth; + } + + if (mappings.Keys.Contains(Field.DatItem_AreaEndianness)) + Endianness = mappings[Field.DatItem_AreaEndianness].AsEndianness(); + } + + #endregion + + #region Constructors + + /// + /// Create a default, empty DataArea object + /// + public DataArea() + { + Name = string.Empty; + ItemType = ItemType.DataArea; + } + + #endregion + + #region Cloning Methods + + public override object Clone() + { + return new DataArea() + { + ItemType = this.ItemType, + DupeType = this.DupeType, + + Machine = this.Machine.Clone() as Machine, + Source = this.Source.Clone() as Source, + Remove = this.Remove, + + Name = this.Name, + Size = this.Size, + Width = this.Width, + Endianness = this.Endianness, + }; + } + + #endregion + + #region Comparision Methods + + public override bool Equals(DatItem other) + { + // If we don't have a DataArea, return false + if (ItemType != other.ItemType) + return false; + + // Otherwise, treat it as a DataArea + DataArea newOther = other as DataArea; + + // If the DataArea information matches + return (Name == newOther.Name + && Size == newOther.Size + && Width == newOther.Width + && Endianness == newOther.Endianness); + } + + #endregion + + #region Filtering + + /// + /// Clean a DatItem according to the cleaner + /// + /// Cleaner to implement + public override void Clean(Cleaner cleaner) + { + // Clean common items first + base.Clean(cleaner); + + // If we're stripping unicode characters, strip item name + if (cleaner?.RemoveUnicode == true) + Name = Sanitizer.RemoveUnicodeCharacters(Name); + + // If we are in NTFS trim mode, trim the game name + if (cleaner?.Trim == true) + { + // Windows max name length is 260 + int usableLength = 260 - Machine.Name.Length - (cleaner.Root?.Length ?? 0); + if (Name.Length > usableLength) + { + string ext = Path.GetExtension(Name); + Name = Name.Substring(0, usableLength - ext.Length); + Name += ext; + } + } + } + + /// + /// Check to see if a DatItem passes the filter + /// + /// Filter to check against + /// True if the item passed the filter, false otherwise + public override bool PassesFilter(Filter filter) + { + // Check common fields first + if (!base.PassesFilter(filter)) + return false; + + // Filter on area name + if (filter.DatItem_AreaName.MatchesPositiveSet(Name) == false) + return false; + if (filter.DatItem_AreaName.MatchesNegativeSet(Name) == true) + return false; + + // Filter on area size + if (filter.DatItem_AreaSize.MatchesNeutral(null, Size) == false) + return false; + else if (filter.DatItem_AreaSize.MatchesPositive(null, Size) == false) + return false; + else if (filter.DatItem_AreaSize.MatchesNegative(null, Size) == false) + return false; + + // Filter on area byte width + if (filter.DatItem_AreaWidth.MatchesPositive(null, Width) == false) + return false; + if (filter.DatItem_AreaWidth.MatchesNegative(null, Width) == true) + return false; + + // Filter on area endianness + if (filter.DatItem_AreaEndianness.MatchesPositive(Endianness.NULL, Endianness) == false) + return false; + if (filter.DatItem_AreaEndianness.MatchesNegative(Endianness.NULL, Endianness) == true) + return false; + + return true; + } + + /// + /// Remove fields from the DatItem + /// + /// List of Fields to remove + public override void RemoveFields(List fields) + { + // Remove common fields first + base.RemoveFields(fields); + + // Remove the fields + if (fields.Contains(Field.DatItem_AreaName)) + Name = null; + + if (fields.Contains(Field.DatItem_AreaSize)) + Size = null; + + if (fields.Contains(Field.DatItem_AreaWidth)) + Width = null; + + if (fields.Contains(Field.DatItem_AreaEndianness)) + Endianness = Endianness.NULL; + } + + /// + /// Set internal names to match One Rom Per Game (ORPG) logic + /// + public override void SetOneRomPerGame() + { + string[] splitname = Name.Split('.'); + Machine.Name += $"/{string.Join(".", splitname.Take(splitname.Length > 1 ? splitname.Length - 1 : 1))}"; + Name = Path.GetFileName(Name); + } + + #endregion + + #region Sorting and Merging + + /// + /// Replace fields from another item + /// + /// DatItem to pull new information from + /// List of Fields representing what should be updated + public override void ReplaceFields(DatItem item, List fields) + { + // Replace common fields first + base.ReplaceFields(item, fields); + + // If we don't have a DataArea to replace from, ignore specific fields + if (item.ItemType != ItemType.DataArea) + return; + + // Cast for easier access + DataArea newItem = item as DataArea; + + // Replace the fields + if (fields.Contains(Field.DatItem_AreaName)) + Name = newItem.Name; + + if (fields.Contains(Field.DatItem_AreaSize)) + Size = newItem.Size; + + if (fields.Contains(Field.DatItem_AreaWidth)) + Width = newItem.Width; + + if (fields.Contains(Field.DatItem_AreaEndianness)) + Endianness = newItem.Endianness; + } + + #endregion + } +} diff --git a/SabreTools.Library/DatItems/DipSwitch.cs b/SabreTools.Library/DatItems/DipSwitch.cs index 7fd27c03..3b43d1b3 100644 --- a/SabreTools.Library/DatItems/DipSwitch.cs +++ b/SabreTools.Library/DatItems/DipSwitch.cs @@ -129,23 +129,11 @@ namespace SabreTools.Library.DatItems #region SoftwareList - if (mappings.Keys.Contains(Field.DatItem_Part_Name)) - { - if (Part == null) - Part = new Part(); + // Handle Part-specific fields + if (Part == null) + Part = new Part(); - Part.Name = mappings[Field.DatItem_Part_Name]; - } - - if (mappings.Keys.Contains(Field.DatItem_Part_Interface)) - { - if (Part == null) - Part = new Part(); - - Part.Interface = mappings[Field.DatItem_Part_Interface]; - } - - // TODO: Handle DatItem_Part_Feature* + Part.SetFields(mappings); #endregion } @@ -209,7 +197,9 @@ namespace SabreTools.Library.DatItems if (!match) return match; - // TODO: Handle Part* + // If the part matches + if (Part != null) + match &= (Part == newOther.Part); // If the conditions match if (Conditions != null) @@ -337,19 +327,12 @@ namespace SabreTools.Library.DatItems #region SoftwareList - // Filter on part name - if (filter.DatItem_Part_Name.MatchesPositiveSet(Part?.Name) == false) - return false; - if (filter.DatItem_Part_Name.MatchesNegativeSet(Part?.Name) == true) - return false; - - // Filter on part interface - if (filter.DatItem_Part_Interface.MatchesPositiveSet(Part?.Interface) == false) - return false; - if (filter.DatItem_Part_Interface.MatchesNegativeSet(Part?.Interface) == true) - return false; - - // TODO: Handle DatItem_Part_Feature* + // Filter on Part + if (Part != null) + { + if (!Part.PassesFilter(filter)) + return false; + } #endregion @@ -406,13 +389,8 @@ namespace SabreTools.Library.DatItems #region SoftwareList - if (fields.Contains(Field.DatItem_Part_Name) && Part != null) - Part.Name = null; - - if (fields.Contains(Field.DatItem_Part_Interface) && Part != null) - Part.Interface = null; - - // TODO: Handle DatItem_Part_Feature* + if (Part != null) + Part.RemoveFields(fields); #endregion } @@ -477,23 +455,8 @@ namespace SabreTools.Library.DatItems #region SoftwareList - if (fields.Contains(Field.DatItem_Part_Name)) - { - if (Part == null) - Part = new Part(); - - Part.Name = newItem.Part?.Name; - } - - if (fields.Contains(Field.DatItem_Part_Interface)) - { - if (Part == null) - Part = new Part(); - - Part.Interface = newItem.Part?.Interface; - } - - // TODO: Handle DatItem_Part_Feature* + if (Part != null && newItem.Part != null) + Part.ReplaceFields(newItem.Part, fields); #endregion } diff --git a/SabreTools.Library/DatItems/Disk.cs b/SabreTools.Library/DatItems/Disk.cs index 9bf68118..d34bb75a 100644 --- a/SabreTools.Library/DatItems/Disk.cs +++ b/SabreTools.Library/DatItems/Disk.cs @@ -158,31 +158,17 @@ namespace SabreTools.Library.DatItems if (mappings.Keys.Contains(Field.DatItem_Optional)) Optional = mappings[Field.DatItem_Optional].AsYesNo(); - if (mappings.Keys.Contains(Field.DatItem_AreaName)) - { - if (DiskArea == null) - DiskArea = new DiskArea(); + // Handle DiskArea-specific fields + if (DiskArea == null) + DiskArea = new DiskArea(); - DiskArea.Name = mappings[Field.DatItem_AreaName]; - } + DiskArea.SetFields(mappings); - if (mappings.Keys.Contains(Field.DatItem_Part_Name)) - { - if (Part == null) - Part = new Part(); + // Handle Part-specific fields + if (Part == null) + Part = new Part(); - Part.Name = mappings[Field.DatItem_Part_Name]; - } - - if (mappings.Keys.Contains(Field.DatItem_Part_Interface)) - { - if (Part == null) - Part = new Part(); - - Part.Interface = mappings[Field.DatItem_Part_Interface]; - } - - // TODO: Handle DatItem_Part_Feature* + Part.SetFields(mappings); } #endregion @@ -474,25 +460,19 @@ namespace SabreTools.Library.DatItems #region SoftwareList - // Filter on area name - if (filter.DatItem_AreaName.MatchesPositiveSet(DiskArea?.Name) == false) - return false; - if (filter.DatItem_AreaName.MatchesNegativeSet(DiskArea?.Name) == true) - return false; + // Filter on DiskArea + if (DiskArea != null) + { + if (!DiskArea.PassesFilter(filter)) + return false; + } - // Filter on part name - if (filter.DatItem_Part_Name.MatchesPositiveSet(Part?.Name) == false) - return false; - if (filter.DatItem_Part_Name.MatchesNegativeSet(Part?.Name) == true) - return false; - - // Filter on part interface - if (filter.DatItem_Part_Interface.MatchesPositiveSet(Part?.Interface) == false) - return false; - if (filter.DatItem_Part_Interface.MatchesNegativeSet(Part?.Interface) == true) - return false; - - // TODO: Handle DatItem_Part_Feature* + // Filter on Part + if (Part != null) + { + if (!Part.PassesFilter(filter)) + return false; + } #endregion @@ -543,19 +523,11 @@ namespace SabreTools.Library.DatItems #region SoftwareList - if (fields.Contains(Field.DatItem_AreaName)) - { - if (DiskArea != null) - DiskArea.Name = null; - } + if (DiskArea != null) + DiskArea.RemoveFields(fields); - if (fields.Contains(Field.DatItem_Part_Name) && Part != null) - Part.Name = null; - - if (fields.Contains(Field.DatItem_Part_Interface) && Part != null) - Part.Interface = null; - - // TODO: Handle DatItem_Part_Feature* + if (Part != null) + Part.RemoveFields(fields); #endregion } @@ -667,31 +639,11 @@ namespace SabreTools.Library.DatItems #region SoftwareList - if (fields.Contains(Field.DatItem_AreaName)) - { - if (DiskArea == null) - DiskArea = new DiskArea(); + if (DiskArea != null && newItem.DiskArea != null) + DiskArea.ReplaceFields(newItem.DiskArea, fields); - DiskArea.Name = newItem.DiskArea?.Name; - } - - if (fields.Contains(Field.DatItem_Part_Name)) - { - if (Part == null) - Part = new Part(); - - Part.Name = newItem.Part?.Name; - } - - if (fields.Contains(Field.DatItem_Part_Interface)) - { - if (Part == null) - Part = new Part(); - - Part.Interface = newItem.Part?.Interface; - } - - // TODO: Handle DatItem_Part_Feature* + if (Part != null && newItem.Part != null) + Part.ReplaceFields(newItem.Part, fields); #endregion } diff --git a/SabreTools.Library/DatItems/DiskArea.cs b/SabreTools.Library/DatItems/DiskArea.cs new file mode 100644 index 00000000..57eb9c50 --- /dev/null +++ b/SabreTools.Library/DatItems/DiskArea.cs @@ -0,0 +1,206 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +using SabreTools.Library.Filtering; +using SabreTools.Library.Tools; +using Newtonsoft.Json; + +namespace SabreTools.Library.DatItems +{ + /// + /// SoftwareList diskarea information + /// + /// One DiskArea can contain multiple Disk items + [JsonObject("diskarea")] + public class DiskArea : DatItem + { + #region Fields + + /// + /// Name of the item + /// + [JsonProperty("name", DefaultValueHandling = DefaultValueHandling.Ignore)] + public string Name { get; set; } + + #endregion + + #region Accessors + + /// + /// Gets the name to use for a DatItem + /// + /// Name if available, null otherwise + public override string GetName() + { + return Name; + } + + /// + /// Set fields with given values + /// + /// Mappings dictionary + public override void SetFields(Dictionary mappings) + { + // Set base fields + base.SetFields(mappings); + + // Handle DiskArea-specific fields + if (mappings.Keys.Contains(Field.DatItem_AreaName)) + Name = mappings[Field.DatItem_AreaName]; + } + + #endregion + + #region Constructors + + /// + /// Create a default, empty DiskArea object + /// + public DiskArea() + { + Name = string.Empty; + ItemType = ItemType.DiskArea; + } + + #endregion + + #region Cloning Methods + + public override object Clone() + { + return new DiskArea() + { + ItemType = this.ItemType, + DupeType = this.DupeType, + + Machine = this.Machine.Clone() as Machine, + Source = this.Source.Clone() as Source, + Remove = this.Remove, + + Name = this.Name, + }; + } + + #endregion + + #region Comparision Methods + + public override bool Equals(DatItem other) + { + // If we don't have a DiskArea, return false + if (ItemType != other.ItemType) + return false; + + // Otherwise, treat it as a DiskArea + DiskArea newOther = other as DiskArea; + + // If the DiskArea information matches + return (Name == newOther.Name); + } + + #endregion + + #region Filtering + + /// + /// Clean a DatItem according to the cleaner + /// + /// Cleaner to implement + public override void Clean(Cleaner cleaner) + { + // Clean common items first + base.Clean(cleaner); + + // If we're stripping unicode characters, strip item name + if (cleaner?.RemoveUnicode == true) + Name = Sanitizer.RemoveUnicodeCharacters(Name); + + // If we are in NTFS trim mode, trim the game name + if (cleaner?.Trim == true) + { + // Windows max name length is 260 + int usableLength = 260 - Machine.Name.Length - (cleaner.Root?.Length ?? 0); + if (Name.Length > usableLength) + { + string ext = Path.GetExtension(Name); + Name = Name.Substring(0, usableLength - ext.Length); + Name += ext; + } + } + } + + /// + /// Check to see if a DatItem passes the filter + /// + /// Filter to check against + /// True if the item passed the filter, false otherwise + public override bool PassesFilter(Filter filter) + { + // Check common fields first + if (!base.PassesFilter(filter)) + return false; + + // Filter on area name + if (filter.DatItem_AreaName.MatchesPositiveSet(Name) == false) + return false; + if (filter.DatItem_AreaName.MatchesNegativeSet(Name) == true) + return false; + + return true; + } + + /// + /// Remove fields from the DatItem + /// + /// List of Fields to remove + public override void RemoveFields(List fields) + { + // Remove common fields first + base.RemoveFields(fields); + + // Remove the fields + if (fields.Contains(Field.DatItem_AreaName)) + Name = null; + } + + /// + /// Set internal names to match One Rom Per Game (ORPG) logic + /// + public override void SetOneRomPerGame() + { + string[] splitname = Name.Split('.'); + Machine.Name += $"/{string.Join(".", splitname.Take(splitname.Length > 1 ? splitname.Length - 1 : 1))}"; + Name = Path.GetFileName(Name); + } + + #endregion + + #region Sorting and Merging + + /// + /// Replace fields from another item + /// + /// DatItem to pull new information from + /// List of Fields representing what should be updated + public override void ReplaceFields(DatItem item, List fields) + { + // Replace common fields first + base.ReplaceFields(item, fields); + + // If we don't have a DiskArea to replace from, ignore specific fields + if (item.ItemType != ItemType.DiskArea) + return; + + // Cast for easier access + DiskArea newItem = item as DiskArea; + + // Replace the fields + if (fields.Contains(Field.DatItem_AreaName)) + Name = newItem.Name; + } + + #endregion + } +} diff --git a/SabreTools.Library/DatItems/Enums.cs b/SabreTools.Library/DatItems/Enums.cs index 9500ae94..b24ab3fa 100644 --- a/SabreTools.Library/DatItems/Enums.cs +++ b/SabreTools.Library/DatItems/Enums.cs @@ -302,15 +302,7 @@ namespace SabreTools.Library.DatItems DatItem_Boot, // Rom (SoftwareList) - DatItem_AreaName, // TODO: DataArea/DiskArea? - DatItem_AreaSize, // TODO: DataArea? - DatItem_AreaWidth, // TODO: DataArea? - DatItem_AreaEndianness, // TODO: DataArea? DatItem_LoadFlag, - DatItem_Part_Name, // TODO: Part? - DatItem_Part_Interface, // TODO: Part? - DatItem_Part_Feature_Name, // TODO: PartFeature? - DatItem_Part_Feature_Value, // TODO: PartFeature? DatItem_Value, // Disk @@ -357,6 +349,12 @@ namespace SabreTools.Library.DatItems DatItem_Control_Ways2, DatItem_Control_Ways3, + // DataArea + DatItem_AreaName, + DatItem_AreaSize, + DatItem_AreaWidth, + DatItem_AreaEndianness, + // Device DatItem_DeviceType, DatItem_FixedImage, @@ -407,6 +405,14 @@ namespace SabreTools.Library.DatItems DatItem_Location_Number, DatItem_Location_Inverted, + // Part + DatItem_Part_Name, + DatItem_Part_Interface, + + // PartFeature + DatItem_Part_Feature_Name, + DatItem_Part_Feature_Value, + // RamOption DatItem_Content, @@ -474,9 +480,11 @@ namespace SabreTools.Library.DatItems Condition, Configuration, Control, + DataArea, Device, DeviceReference, DipSwitch, + DiskArea, Display, Driver, Extension, @@ -485,6 +493,7 @@ namespace SabreTools.Library.DatItems Input, Instance, Location, + Part, PartFeature, Port, RamOption, diff --git a/SabreTools.Library/DatItems/Part.cs b/SabreTools.Library/DatItems/Part.cs new file mode 100644 index 00000000..2950c58f --- /dev/null +++ b/SabreTools.Library/DatItems/Part.cs @@ -0,0 +1,271 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +using SabreTools.Library.Filtering; +using SabreTools.Library.Tools; +using Newtonsoft.Json; + +namespace SabreTools.Library.DatItems +{ + /// + /// SoftwareList part information + /// + /// One Part can contain multiple PartFeature, DataArea, DiskArea, and DipSwitch items + [JsonObject("part")] + public class Part : DatItem + { + #region Fields + + [JsonProperty("name")] + public string Name { get; set; } + + [JsonProperty("interface")] + public string Interface { get; set; } + + [JsonProperty("features", DefaultValueHandling = DefaultValueHandling.Ignore)] + public List Features { get; set; } + + #endregion + + #region Accessors + + /// + /// Gets the name to use for a DatItem + /// + /// Name if available, null otherwise + public override string GetName() + { + return Name; + } + + /// + /// Set fields with given values + /// + /// Mappings dictionary + public override void SetFields(Dictionary mappings) + { + // Set base fields + base.SetFields(mappings); + + // Handle Part-specific fields + if (mappings.Keys.Contains(Field.DatItem_Part_Name)) + Name = mappings[Field.DatItem_Part_Name]; + + if (mappings.Keys.Contains(Field.DatItem_Part_Interface)) + Interface = mappings[Field.DatItem_Part_Interface]; + + // Handle Feature-specific fields + if (Features != null) + { + foreach (PartFeature partFeature in Features) + { + partFeature.SetFields(mappings); + } + } + } + + #endregion + + #region Constructors + + /// + /// Create a default, empty Part object + /// + public Part() + { + Name = string.Empty; + ItemType = ItemType.Part; + } + + #endregion + + #region Cloning Methods + + public override object Clone() + { + return new Part() + { + ItemType = this.ItemType, + DupeType = this.DupeType, + + Machine = this.Machine.Clone() as Machine, + Source = this.Source.Clone() as Source, + Remove = this.Remove, + + Name = this.Name, + Interface = this.Interface, + Features = this.Features, + }; + } + + #endregion + + #region Comparision Methods + + public override bool Equals(DatItem other) + { + // If we don't have a Part, return false + if (ItemType != other.ItemType) + return false; + + // Otherwise, treat it as a Part + Part newOther = other as Part; + + // If the Part information matches + bool match = (Name == newOther.Name + && Interface == newOther.Interface); + if (!match) + return match; + + // If the features match + if (Features != null) + { + foreach (PartFeature partFeature in Features) + { + match &= newOther.Features.Contains(partFeature); + } + } + + return match; + } + + #endregion + + #region Filtering + + /// + /// Clean a DatItem according to the cleaner + /// + /// Cleaner to implement + public override void Clean(Cleaner cleaner) + { + // Clean common items first + base.Clean(cleaner); + + // If we're stripping unicode characters, strip item name + if (cleaner?.RemoveUnicode == true) + Name = Sanitizer.RemoveUnicodeCharacters(Name); + + // If we are in NTFS trim mode, trim the game name + if (cleaner?.Trim == true) + { + // Windows max name length is 260 + int usableLength = 260 - Machine.Name.Length - (cleaner.Root?.Length ?? 0); + if (Name.Length > usableLength) + { + string ext = Path.GetExtension(Name); + Name = Name.Substring(0, usableLength - ext.Length); + Name += ext; + } + } + } + + /// + /// Check to see if a DatItem passes the filter + /// + /// Filter to check against + /// True if the item passed the filter, false otherwise + public override bool PassesFilter(Filter filter) + { + // Check common fields first + if (!base.PassesFilter(filter)) + return false; + + // Filter on part name + if (filter.DatItem_Part_Name.MatchesPositiveSet(Name) == false) + return false; + if (filter.DatItem_Part_Name.MatchesNegativeSet(Name) == true) + return false; + + // Filter on part interface + if (filter.DatItem_Part_Interface.MatchesPositiveSet(Interface) == false) + return false; + if (filter.DatItem_Part_Interface.MatchesNegativeSet(Interface) == true) + return false; + + // Filter on features + if (Features != null) + { + foreach (PartFeature partFeature in Features) + { + if (!partFeature.PassesFilter(filter)) + return false; + } + } + + return true; + } + + /// + /// Remove fields from the DatItem + /// + /// List of Fields to remove + public override void RemoveFields(List fields) + { + // Remove common fields first + base.RemoveFields(fields); + + // Remove the fields + if (fields.Contains(Field.DatItem_Part_Name)) + Name = null; + + if (fields.Contains(Field.DatItem_Part_Interface)) + Interface = null; + + if (Features != null) + { + foreach (PartFeature partFeature in Features) + { + partFeature.RemoveFields(fields); + } + } + } + + /// + /// Set internal names to match One Rom Per Game (ORPG) logic + /// + public override void SetOneRomPerGame() + { + string[] splitname = Name.Split('.'); + Machine.Name += $"/{string.Join(".", splitname.Take(splitname.Length > 1 ? splitname.Length - 1 : 1))}"; + Name = Path.GetFileName(Name); + } + + #endregion + + #region Sorting and Merging + + /// + /// Replace fields from another item + /// + /// DatItem to pull new information from + /// List of Fields representing what should be updated + public override void ReplaceFields(DatItem item, List fields) + { + // Replace common fields first + base.ReplaceFields(item, fields); + + // If we don't have a Part to replace from, ignore specific fields + if (item.ItemType != ItemType.Part) + return; + + // Cast for easier access + Part newItem = item as Part; + + // Replace the fields + if (fields.Contains(Field.DatItem_Part_Name)) + Name = newItem.Name; + + if (fields.Contains(Field.DatItem_Part_Interface)) + Interface = newItem.Interface; + + // DatItem_Part_Feature_* doesn't make sense here + // since not every part feature under the other item + // can replace every part feature under this item + } + + #endregion + } +} diff --git a/SabreTools.Library/DatItems/PartFeature.cs b/SabreTools.Library/DatItems/PartFeature.cs index 4c327273..83601180 100644 --- a/SabreTools.Library/DatItems/PartFeature.cs +++ b/SabreTools.Library/DatItems/PartFeature.cs @@ -51,11 +51,11 @@ namespace SabreTools.Library.DatItems base.SetFields(mappings); // Handle PartFeature-specific fields - if (mappings.Keys.Contains(Field.DatItem_Name)) - Name = mappings[Field.DatItem_Name]; + if (mappings.Keys.Contains(Field.DatItem_Part_Feature_Name)) + Name = mappings[Field.DatItem_Part_Feature_Name]; - if (mappings.Keys.Contains(Field.DatItem_Value)) - Value = mappings[Field.DatItem_Value]; + if (mappings.Keys.Contains(Field.DatItem_Part_Feature_Value)) + Value = mappings[Field.DatItem_Part_Feature_Value]; } #endregion @@ -151,15 +151,15 @@ namespace SabreTools.Library.DatItems return false; // Filter on item name - if (filter.DatItem_Name.MatchesPositiveSet(Name) == false) + if (filter.DatItem_Part_Feature_Name.MatchesPositiveSet(Name) == false) return false; - if (filter.DatItem_Name.MatchesNegativeSet(Name) == true) + if (filter.DatItem_Part_Feature_Name.MatchesNegativeSet(Name) == true) return false; // Filter on info value - if (filter.DatItem_Value.MatchesPositiveSet(Value) == false) + if (filter.DatItem_Part_Feature_Value.MatchesPositiveSet(Value) == false) return false; - if (filter.DatItem_Value.MatchesNegativeSet(Value) == true) + if (filter.DatItem_Part_Feature_Value.MatchesNegativeSet(Value) == true) return false; return true; @@ -175,10 +175,10 @@ namespace SabreTools.Library.DatItems base.RemoveFields(fields); // Remove the fields - if (fields.Contains(Field.DatItem_Name)) + if (fields.Contains(Field.DatItem_Part_Feature_Name)) Name = null; - if (fields.Contains(Field.DatItem_Value)) + if (fields.Contains(Field.DatItem_Part_Feature_Value)) Value = null; } @@ -214,10 +214,10 @@ namespace SabreTools.Library.DatItems PartFeature newItem = item as PartFeature; // Replace the fields - if (fields.Contains(Field.DatItem_Name)) + if (fields.Contains(Field.DatItem_Part_Feature_Name)) Name = newItem.Name; - if (fields.Contains(Field.DatItem_Value)) + if (fields.Contains(Field.DatItem_Part_Feature_Value)) Value = newItem.Value; } diff --git a/SabreTools.Library/DatItems/Rom.cs b/SabreTools.Library/DatItems/Rom.cs index c51c91af..0bcaa771 100644 --- a/SabreTools.Library/DatItems/Rom.cs +++ b/SabreTools.Library/DatItems/Rom.cs @@ -368,64 +368,24 @@ namespace SabreTools.Library.DatItems #region SoftwareList - if (mappings.Keys.Contains(Field.DatItem_AreaName)) - { - if (DataArea == null) - DataArea = new DataArea(); - - DataArea.Name = mappings[Field.DatItem_AreaName]; - } - - if (mappings.Keys.Contains(Field.DatItem_AreaSize)) - { - if (DataArea == null) - DataArea = new DataArea(); - - if (Int64.TryParse(mappings[Field.DatItem_AreaSize], out long areaSize)) - DataArea.Size = areaSize; - } - - if (mappings.Keys.Contains(Field.DatItem_AreaWidth)) - { - if (DataArea == null) - DataArea = new DataArea(); - - if (Int64.TryParse(mappings[Field.DatItem_AreaWidth], out long areaWidth)) - DataArea.Width = areaWidth; - } - - if (mappings.Keys.Contains(Field.DatItem_AreaEndianness)) - { - if (DataArea == null) - DataArea = new DataArea(); - - DataArea.Endianness = mappings[Field.DatItem_AreaEndianness].AsEndianness(); - } - if (mappings.Keys.Contains(Field.DatItem_LoadFlag)) LoadFlag = mappings[Field.DatItem_LoadFlag].AsLoadFlag(); - if (mappings.Keys.Contains(Field.DatItem_Part_Name)) - { - if (Part == null) - Part = new Part(); - - Part.Name = mappings[Field.DatItem_Part_Name]; - } - - if (mappings.Keys.Contains(Field.DatItem_Part_Interface)) - { - if (Part == null) - Part = new Part(); - - Part.Interface = mappings[Field.DatItem_Part_Interface]; - } - - // TODO: Handle DatItem_Part_Feature* - if (mappings.Keys.Contains(Field.DatItem_Value)) Value = mappings[Field.DatItem_Value]; + // Handle DataArea-specific fields + if (DataArea == null) + DataArea = new DataArea(); + + DataArea.SetFields(mappings); + + // Handle Part-specific fields + if (Part == null) + Part = new Part(); + + Part.SetFields(mappings); + #endregion } @@ -894,57 +854,31 @@ namespace SabreTools.Library.DatItems #region SoftwareList - // Filter on area name - if (filter.DatItem_AreaName.MatchesPositiveSet(DataArea?.Name) == false) - return false; - if (filter.DatItem_AreaName.MatchesNegativeSet(DataArea?.Name) == true) - return false; - - // Filter on area size - if (filter.DatItem_AreaSize.MatchesNeutral(null, DataArea?.Size) == false) - return false; - else if (filter.DatItem_AreaSize.MatchesPositive(null, DataArea?.Size) == false) - return false; - else if (filter.DatItem_AreaSize.MatchesNegative(null, DataArea?.Size) == false) - return false; - - // Filter on area byte width - if (filter.DatItem_AreaWidth.MatchesPositive(null, DataArea?.Width) == false) - return false; - if (filter.DatItem_AreaWidth.MatchesNegative(null, DataArea?.Width) == true) - return false; - - // Filter on area endianness - if (filter.DatItem_AreaEndianness.MatchesPositive(Endianness.NULL, DataArea?.Endianness ?? Endianness.NULL) == false) - return false; - if (filter.DatItem_AreaEndianness.MatchesNegative(Endianness.NULL, DataArea?.Endianness ?? Endianness.NULL) == true) - return false; - // Filter on load flag if (filter.DatItem_LoadFlag.MatchesPositive(LoadFlag.NULL, LoadFlag) == false) return false; if (filter.DatItem_LoadFlag.MatchesNegative(LoadFlag.NULL, LoadFlag) == true) return false; - // Filter on part name - if (filter.DatItem_Part_Name.MatchesPositiveSet(Part?.Name) == false) - return false; - if (filter.DatItem_Part_Name.MatchesNegativeSet(Part?.Name) == true) - return false; - - // Filter on part interface - if (filter.DatItem_Part_Interface.MatchesPositiveSet(Part?.Interface) == false) - return false; - if (filter.DatItem_Part_Interface.MatchesNegativeSet(Part?.Interface) == true) - return false; - // Filter on value if (filter.DatItem_Value.MatchesPositiveSet(Value) == false) return false; if (filter.DatItem_Value.MatchesNegativeSet(Value) == true) return false; - // TODO: Handle DatItem_Part_Feature* + // Filter on DataArea + if (DataArea != null) + { + if (!DataArea.PassesFilter(filter)) + return false; + } + + // Filter on Part + if (Part != null) + { + if (!Part.PassesFilter(filter)) + return false; + } #endregion @@ -1050,44 +984,18 @@ namespace SabreTools.Library.DatItems #region SoftwareList - if (fields.Contains(Field.DatItem_AreaName)) - { - if (DataArea != null) - DataArea.Name = null; - } - - if (fields.Contains(Field.DatItem_AreaSize)) - { - if (DataArea != null) - DataArea.Size = null; - } - - if (fields.Contains(Field.DatItem_AreaWidth)) - { - if (DataArea != null) - DataArea.Width = null; - } - - if (fields.Contains(Field.DatItem_AreaEndianness)) - { - if (DataArea != null) - DataArea.Endianness = Endianness.NULL; - } - if (fields.Contains(Field.DatItem_LoadFlag)) LoadFlag = LoadFlag.NULL; - if (fields.Contains(Field.DatItem_Part_Name) && Part != null) - Part.Name = null; - - if (fields.Contains(Field.DatItem_Part_Interface) && Part != null) - Part.Interface = null; - - // TODO: Handle DatItem_Part_Feature* - if (fields.Contains(Field.DatItem_Value)) Value = null; + if (DataArea != null) + DataArea.RemoveFields(fields); + + if (Part != null) + Part.RemoveFields(fields); + #endregion } @@ -1290,58 +1198,17 @@ namespace SabreTools.Library.DatItems #region SoftwareList - if (fields.Contains(Field.DatItem_AreaName)) - { - if (DataArea == null) - DataArea = new DataArea(); - - DataArea.Name = newItem.DataArea?.Name; - } - - if (fields.Contains(Field.DatItem_AreaSize)) - { - if (DataArea == null) - DataArea = new DataArea(); - - DataArea.Size = newItem.DataArea?.Size; - } - - if (fields.Contains(Field.DatItem_AreaWidth)) - { - if (DataArea == null) - DataArea = new DataArea(); - - DataArea.Width = newItem.DataArea?.Width; - } - - if (fields.Contains(Field.DatItem_AreaEndianness)) - { - if (DataArea == null) - DataArea = new DataArea(); - - DataArea.Endianness = newItem.DataArea?.Endianness ?? Endianness.NULL; - } - if (fields.Contains(Field.DatItem_LoadFlag)) LoadFlag = newItem.LoadFlag; - if (fields.Contains(Field.DatItem_Part_Name)) - { - if (Part == null) - Part = new Part(); + if (fields.Contains(Field.DatItem_Value)) + Value = newItem.Value; - Part.Name = newItem.Part?.Name; - } + if (DataArea != null && newItem.DataArea != null) + DataArea.ReplaceFields(newItem.DataArea, fields); - if (fields.Contains(Field.DatItem_Part_Interface)) - { - if (Part == null) - Part = new Part(); - - Part.Interface = newItem.Part?.Interface; - } - - // TODO: Handle DatItem_Part_Feature* + if (Part != null && newItem.Part != null) + Part.ReplaceFields(newItem.Part, fields); #endregion } diff --git a/SabreTools.Library/Filtering/Filter.cs b/SabreTools.Library/Filtering/Filter.cs index 85b43b4c..089ace63 100644 --- a/SabreTools.Library/Filtering/Filter.cs +++ b/SabreTools.Library/Filtering/Filter.cs @@ -134,15 +134,7 @@ namespace SabreTools.Library.Filtering public FilterItem DatItem_Boot { get; private set; } = new FilterItem(); // Rom (SoftwareList) - public FilterItem DatItem_AreaName { get; private set; } = new FilterItem(); - public FilterItem DatItem_AreaSize { get; private set; } = new FilterItem() { Positive = null, Negative = null, Neutral = null }; - public FilterItem DatItem_AreaWidth { get; private set; } = new FilterItem() { Positive = null, Negative = null, Neutral = null }; - public FilterItem DatItem_AreaEndianness { get; private set; } = new FilterItem() { Positive = Endianness.NULL, Negative = Endianness.NULL }; public FilterItem DatItem_LoadFlag { get; private set; } = new FilterItem() { Positive = LoadFlag.NULL, Negative = LoadFlag.NULL }; - public FilterItem DatItem_Part_Name { get; private set; } = new FilterItem(); - public FilterItem DatItem_Part_Interface { get; private set; } = new FilterItem(); - public FilterItem DatItem_Part_Feature_Name { get; private set; } = new FilterItem(); - public FilterItem DatItem_Part_Feature_Value { get; private set; } = new FilterItem(); public FilterItem DatItem_Value { get; private set; } = new FilterItem(); // Disk @@ -189,6 +181,12 @@ namespace SabreTools.Library.Filtering public FilterItem DatItem_Control_Ways2 { get; private set; } = new FilterItem(); public FilterItem DatItem_Control_Ways3 { get; private set; } = new FilterItem(); + // DataArea + public FilterItem DatItem_AreaName { get; private set; } = new FilterItem(); + public FilterItem DatItem_AreaSize { get; private set; } = new FilterItem() { Positive = null, Negative = null, Neutral = null }; + public FilterItem DatItem_AreaWidth { get; private set; } = new FilterItem() { Positive = null, Negative = null, Neutral = null }; + public FilterItem DatItem_AreaEndianness { get; private set; } = new FilterItem() { Positive = Endianness.NULL, Negative = Endianness.NULL }; + // Device public FilterItem DatItem_DeviceType { get; private set; } = new FilterItem(); public FilterItem DatItem_FixedImage { get; private set; } = new FilterItem(); @@ -238,6 +236,14 @@ namespace SabreTools.Library.Filtering public FilterItem DatItem_Location_Name { get; private set; } = new FilterItem(); public FilterItem DatItem_Location_Number { get; private set; } = new FilterItem(); public FilterItem DatItem_Location_Inverted { get; private set; } = new FilterItem() { Neutral = null }; + + // Part + public FilterItem DatItem_Part_Name { get; private set; } = new FilterItem(); + public FilterItem DatItem_Part_Interface { get; private set; } = new FilterItem(); + + // PartFeature + public FilterItem DatItem_Part_Feature_Name { get; private set; } = new FilterItem(); + public FilterItem DatItem_Part_Feature_Value { get; private set; } = new FilterItem(); // RamOption public FilterItem DatItem_Content { get; private set; } = new FilterItem(); @@ -643,25 +649,6 @@ namespace SabreTools.Library.Filtering break; // Rom (SoftwareList) - case Field.DatItem_AreaName: - SetStringFilter(DatItem_AreaName, value, negate); - break; - - case Field.DatItem_AreaSize: - SetOptionalLongFilter(DatItem_AreaSize, value, negate); - break; - - case Field.DatItem_AreaWidth: - SetOptionalLongFilter(DatItem_AreaWidth, value, negate); - break; - - case Field.DatItem_AreaEndianness: - if (negate) - DatItem_AreaEndianness.Negative |= value.AsEndianness(); - else - DatItem_AreaEndianness.Positive |= value.AsEndianness(); - break; - case Field.DatItem_LoadFlag: if (negate) DatItem_LoadFlag.Negative |= value.AsLoadFlag(); @@ -669,22 +656,6 @@ namespace SabreTools.Library.Filtering DatItem_LoadFlag.Positive |= value.AsLoadFlag(); break; - case Field.DatItem_Part_Name: - SetStringFilter(DatItem_Part_Name, value, negate); - break; - - case Field.DatItem_Part_Interface: - SetStringFilter(DatItem_Part_Interface, value, negate); - break; - - case Field.DatItem_Part_Feature_Name: - SetStringFilter(DatItem_Part_Feature_Name, value, negate); - break; - - case Field.DatItem_Part_Feature_Value: - SetStringFilter(DatItem_Part_Feature_Value, value, negate); - break; - case Field.DatItem_Value: SetStringFilter(DatItem_Value, value, negate); break; @@ -813,6 +784,26 @@ namespace SabreTools.Library.Filtering SetStringFilter(DatItem_Control_Ways3, value, negate); break; + // DataArea + case Field.DatItem_AreaName: + SetStringFilter(DatItem_AreaName, value, negate); + break; + + case Field.DatItem_AreaSize: + SetOptionalLongFilter(DatItem_AreaSize, value, negate); + break; + + case Field.DatItem_AreaWidth: + SetOptionalLongFilter(DatItem_AreaWidth, value, negate); + break; + + case Field.DatItem_AreaEndianness: + if (negate) + DatItem_AreaEndianness.Negative |= value.AsEndianness(); + else + DatItem_AreaEndianness.Positive |= value.AsEndianness(); + break; + // Device case Field.DatItem_DeviceType: SetStringFilter(DatItem_DeviceType, value, negate); @@ -981,6 +972,24 @@ namespace SabreTools.Library.Filtering SetBooleanFilter(DatItem_Location_Inverted, value, negate); break; + // Part + case Field.DatItem_Part_Name: + SetStringFilter(DatItem_Part_Name, value, negate); + break; + + case Field.DatItem_Part_Interface: + SetStringFilter(DatItem_Part_Interface, value, negate); + break; + + // PartFeature + case Field.DatItem_Part_Feature_Name: + SetStringFilter(DatItem_Part_Feature_Name, value, negate); + break; + + case Field.DatItem_Part_Feature_Value: + SetStringFilter(DatItem_Part_Feature_Value, value, negate); + break; + // RamOption case Field.DatItem_Content: SetStringFilter(DatItem_Content, value, negate); diff --git a/SabreTools.Library/Tools/Converters.cs b/SabreTools.Library/Tools/Converters.cs index b61881d4..71ac0b0e 100644 --- a/SabreTools.Library/Tools/Converters.cs +++ b/SabreTools.Library/Tools/Converters.cs @@ -1635,6 +1635,8 @@ namespace SabreTools.Library.Tools return ItemType.Configuration; case "control": return ItemType.Control; + case "dataarea": + return ItemType.DataArea; case "device": return ItemType.Device; case "device_ref": @@ -1643,6 +1645,8 @@ namespace SabreTools.Library.Tools return ItemType.DipSwitch; case "disk": return ItemType.Disk; + case "diskarea": + return ItemType.DiskArea; case "display": return ItemType.Display; case "driver": @@ -1661,6 +1665,8 @@ namespace SabreTools.Library.Tools return ItemType.Location; case "media": return ItemType.Media; + case "part": + return ItemType.Part; case "partfeature": case "part_feature": return ItemType.PartFeature; @@ -1701,10 +1707,12 @@ namespace SabreTools.Library.Tools "condition" => ItemType.Condition, "configuration" => ItemType.Configuration, "control" => ItemType.Control, + "dataarea" => ItemType.DataArea, "device" => ItemType.Device, "device_ref" => ItemType.DeviceReference, "dipswitch" => ItemType.DipSwitch, "disk" => ItemType.Disk, + "diskarea" => ItemType.DiskArea, "display" => ItemType.Display, "driver" => ItemType.Driver, "extension" => ItemType.Extension, @@ -1714,6 +1722,7 @@ namespace SabreTools.Library.Tools "instance" => ItemType.Instance, "location" => ItemType.Location, "media" => ItemType.Media, + "part" => ItemType.Part, "partfeature" => ItemType.PartFeature, "part_feature" => ItemType.PartFeature, "port" => ItemType.Port, @@ -2515,6 +2524,8 @@ namespace SabreTools.Library.Tools return "configuration"; case ItemType.Control: return "control"; + case ItemType.DataArea: + return "dataarea"; case ItemType.Device: return "device"; case ItemType.DeviceReference: @@ -2523,6 +2534,8 @@ namespace SabreTools.Library.Tools return "dipswitch"; case ItemType.Disk: return "disk"; + case ItemType.DiskArea: + return "diskarea"; case ItemType.Display: return "display"; case ItemType.Driver: @@ -2541,6 +2554,8 @@ namespace SabreTools.Library.Tools return "location"; case ItemType.Media: return "media"; + case ItemType.Part: + return "part"; case ItemType.PartFeature: return "part_feature"; case ItemType.Port: @@ -2580,10 +2595,12 @@ namespace SabreTools.Library.Tools ItemType.Condition => "condition", ItemType.Configuration => "configuration", ItemType.Control => "control", + ItemType.DataArea => "dataarea", ItemType.Device => "device", ItemType.DeviceReference => "device_ref", ItemType.DipSwitch => "dipswitch", ItemType.Disk => "disk", + ItemType.DiskArea => "diskarea", ItemType.Display => "display", ItemType.Driver => "driver", ItemType.Extension => "extension", @@ -2593,6 +2610,7 @@ namespace SabreTools.Library.Tools ItemType.Instance => "instance", ItemType.Location => "location", ItemType.Media => "media", + ItemType.Part => "part", ItemType.PartFeature => "part_feature", ItemType.Port => "port", ItemType.RamOption => "ramoption",