diff --git a/SabreTools.Library/DatFiles/ItemDictionary.cs b/SabreTools.Library/DatFiles/ItemDictionary.cs index 34ae5342..f2ad9346 100644 --- a/SabreTools.Library/DatFiles/ItemDictionary.cs +++ b/SabreTools.Library/DatFiles/ItemDictionary.cs @@ -161,6 +161,12 @@ namespace SabreTools.Library.DatFiles [JsonIgnore] public long MediaCount { get; private set; } = 0; + /// + /// Number of Port items + /// + [JsonIgnore] + public long PortCount { get; private set; } = 0; + /// /// Number of RamOption items /// @@ -584,6 +590,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.Port: + PortCount++; + break; case ItemType.RamOption: RamOptionCount++; break; @@ -752,6 +761,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.Port: + PortCount--; + break; case ItemType.RamOption: RamOptionCount--; break; diff --git a/SabreTools.Library/DatFiles/Json.cs b/SabreTools.Library/DatFiles/Json.cs index ac06d5fb..d1e9511e 100644 --- a/SabreTools.Library/DatFiles/Json.cs +++ b/SabreTools.Library/DatFiles/Json.cs @@ -259,6 +259,9 @@ namespace SabreTools.Library.DatFiles case ItemType.Media: datItem = datItemObj.ToObject(); break; + case ItemType.Port: + datItem = datItemObj.ToObject(); + break; case ItemType.RamOption: datItem = datItemObj.ToObject(); break; diff --git a/SabreTools.Library/DatFiles/Listxml.cs b/SabreTools.Library/DatFiles/Listxml.cs index 2dc9ab18..05633164 100644 --- a/SabreTools.Library/DatFiles/Listxml.cs +++ b/SabreTools.Library/DatFiles/Listxml.cs @@ -391,6 +391,27 @@ namespace SabreTools.Library.DatFiles reader.Read(); break; + case "port": + var port = new Port + { + Tag = reader.GetAttribute("tag"), + + Source = new Source + { + Index = indexId, + Name = filename, + }, + }; + + // Now read the internal tags + ReadPort(reader.ReadSubtree(), port); + + datItems.Add(port); + + // Skip the port now that we've processed it + reader.Skip(); + break; + case "rom": datItems.Add(new Rom { @@ -546,23 +567,6 @@ namespace SabreTools.Library.DatFiles reader.Skip(); break; - case "port": - var port = new Port(); - port.Tag = reader.GetAttribute("tag"); - - // Now read the internal tags - ReadPort(reader.ReadSubtree(), port); - - // Ensure the list exists - if (machine.Ports == null) - machine.Ports = new List(); - - machine.Ports.Add(port); - - // Skip the port now that we've processed it - reader.Skip(); - break; - default: reader.Read(); break; @@ -1303,24 +1307,6 @@ namespace SabreTools.Library.DatFiles xtw.WriteEndElement(); } } - if (datItem.Machine.Ports != null) - { - foreach (var port in datItem.Machine.Ports) - { - xtw.WriteStartElement("port"); - xtw.WriteOptionalAttributeString("tag", port.Tag); - if (port.Analogs != null) - { - foreach (var analog in port.Analogs) - { - xtw.WriteStartElement("analog"); - xtw.WriteOptionalAttributeString("mask", analog.Mask); - xtw.WriteEndElement(); - } - } - xtw.WriteEndElement(); - } - } xtw.Flush(); } @@ -1590,6 +1576,22 @@ namespace SabreTools.Library.DatFiles xtw.WriteEndElement(); break; + case ItemType.Port: + var port = datItem as Port; + xtw.WriteStartElement("port"); + xtw.WriteOptionalAttributeString("tag", port.Tag); + if (port.Analogs != null) + { + foreach (var analog in port.Analogs) + { + xtw.WriteStartElement("analog"); + xtw.WriteOptionalAttributeString("mask", analog.Mask); + xtw.WriteEndElement(); + } + } + xtw.WriteEndElement(); + break; + case ItemType.RamOption: var ramOption = datItem as RamOption; xtw.WriteStartElement("ramoption"); diff --git a/SabreTools.Library/DatFiles/SabreDat.cs b/SabreTools.Library/DatFiles/SabreDat.cs index cd064bd4..79376159 100644 --- a/SabreTools.Library/DatFiles/SabreDat.cs +++ b/SabreTools.Library/DatFiles/SabreDat.cs @@ -1229,14 +1229,6 @@ namespace SabreTools.Library.DatFiles xtw.WriteEndElement(); break; - case ItemType.Analog: - var analog = datItem as Analog; - xtw.WriteStartElement("file"); - xtw.WriteAttributeString("type", "analog"); - xtw.WriteOptionalAttributeString("mask", analog.Mask); - xtw.WriteEndElement(); - break; - case ItemType.Archive: var archive = datItem as Archive; xtw.WriteStartElement("file"); @@ -1471,6 +1463,23 @@ namespace SabreTools.Library.DatFiles xtw.WriteEndElement(); break; + case ItemType.Port: + var port = datItem as Port; + xtw.WriteStartElement("file"); + xtw.WriteAttributeString("type", "port"); + xtw.WriteOptionalAttributeString("tag", port.Tag); + if (port.Analogs != null) + { + foreach (var analog in port.Analogs) + { + xtw.WriteStartElement("analog"); + xtw.WriteOptionalAttributeString("mask", analog.Mask); + xtw.WriteEndElement(); + } + } + xtw.WriteEndElement(); + break; + case ItemType.RamOption: var ramOption = datItem as RamOption; xtw.WriteStartElement("file"); diff --git a/SabreTools.Library/DatItems/Analog.cs b/SabreTools.Library/DatItems/Analog.cs index 9e019f84..df401b77 100644 --- a/SabreTools.Library/DatItems/Analog.cs +++ b/SabreTools.Library/DatItems/Analog.cs @@ -34,8 +34,8 @@ namespace SabreTools.Library.DatItems base.SetFields(mappings); // Handle Analog-specific fields - if (mappings.Keys.Contains(Field.Machine_Port_Analog_Mask)) - Mask = mappings[Field.Machine_Port_Analog_Mask]; + if (mappings.Keys.Contains(Field.DatItem_Analog_Mask)) + Mask = mappings[Field.DatItem_Analog_Mask]; } #endregion @@ -138,7 +138,7 @@ namespace SabreTools.Library.DatItems base.RemoveFields(fields); // Remove the fields - if (fields.Contains(Field.Machine_Port_Analog_Mask)) + if (fields.Contains(Field.DatItem_Analog_Mask)) Mask = null; } @@ -164,7 +164,7 @@ namespace SabreTools.Library.DatItems Analog newItem = item as Analog; // Replace the fields - if (fields.Contains(Field.Machine_Port_Analog_Mask)) + if (fields.Contains(Field.DatItem_Analog_Mask)) Mask = newItem.Mask; } diff --git a/SabreTools.Library/DatItems/Auxiliary.cs b/SabreTools.Library/DatItems/Auxiliary.cs index 7f32395b..a08b4e93 100644 --- a/SabreTools.Library/DatItems/Auxiliary.cs +++ b/SabreTools.Library/DatItems/Auxiliary.cs @@ -265,30 +265,6 @@ namespace SabreTools.Library.DatItems #endregion } - /// - /// Represents one ListXML port - /// - /// TODO: Promote to DatItem level (contains list) - [JsonObject("port")] - public class Port - { - #region Fields - - /// - /// Tag for the port - /// - [JsonProperty("tag", DefaultValueHandling = DefaultValueHandling.Ignore)] - public string Tag { get; set; } - - /// - /// List of analogs on the port - /// - [JsonProperty("analogs", DefaultValueHandling = DefaultValueHandling.Ignore)] - public List Analogs { get; set; } - - #endregion - } - /// /// Represents one ListXML confsetting or dipvalue /// diff --git a/SabreTools.Library/DatItems/DatItem.cs b/SabreTools.Library/DatItems/DatItem.cs index abe911dd..ebf4b561 100644 --- a/SabreTools.Library/DatItems/DatItem.cs +++ b/SabreTools.Library/DatItems/DatItem.cs @@ -506,6 +506,9 @@ namespace SabreTools.Library.DatItems case ItemType.Media: return new Media(); + case ItemType.Port: + return new Port(); + case ItemType.RamOption: return new RamOption(); @@ -550,6 +553,7 @@ namespace SabreTools.Library.DatItems ItemType.Feature => new Feature(), ItemType.Instance => new Instance(), ItemType.Media => new Media(), + ItemType.Port => new Port(), ItemType.RamOption => new RamOption(), ItemType.Release => new Release(), ItemType.Rom => new Rom(), diff --git a/SabreTools.Library/DatItems/Enums.cs b/SabreTools.Library/DatItems/Enums.cs index 0052a501..10f956b0 100644 --- a/SabreTools.Library/DatItems/Enums.cs +++ b/SabreTools.Library/DatItems/Enums.cs @@ -225,14 +225,6 @@ namespace SabreTools.Library.DatItems Machine_Input_Control_Ways2, Machine_Input_Control_Ways3, - // Ports - Machine_Ports, - Machine_Port_Tag, - - // Ports.Analogs - Machine_Port_Analogs, - Machine_Port_Analog_Mask, - #endregion #region Logiqx @@ -428,6 +420,10 @@ namespace SabreTools.Library.DatItems DatItem_FeatureStatus, DatItem_FeatureOverall, + // Port.Analogs + DatItem_Analogs, + DatItem_Analog_Mask, + // Ram Option DatItem_Content, @@ -497,6 +493,7 @@ namespace SabreTools.Library.DatItems Extension, Feature, Instance, + Port, RamOption, Release, Sample, diff --git a/SabreTools.Library/DatItems/Machine.cs b/SabreTools.Library/DatItems/Machine.cs index 64b90065..91eea2f8 100644 --- a/SabreTools.Library/DatItems/Machine.cs +++ b/SabreTools.Library/DatItems/Machine.cs @@ -164,12 +164,6 @@ namespace SabreTools.Library.DatItems [JsonProperty("inputs", DefaultValueHandling = DefaultValueHandling.Ignore)] public List Inputs { get; set; } = null; - /// - /// List of associated ports - /// - [JsonProperty("ports", DefaultValueHandling = DefaultValueHandling.Ignore)] - public List Ports { get; set; } = null; - #endregion #region Logiqx Fields @@ -524,7 +518,6 @@ namespace SabreTools.Library.DatItems Runnable = this.Runnable, Displays = this.Displays, Inputs = this.Inputs, - Ports = this.Ports, #endregion @@ -1006,11 +999,6 @@ namespace SabreTools.Library.DatItems // TODO: Inputs // TODO: Inputs.Controls - // TODO: Ports - // TODO: Ports.Analogs - // TODO: Devices - // TODO: Devices.Instances - // TODO: Devices.Extensions #endregion // ListXML diff --git a/SabreTools.Library/DatItems/Port.cs b/SabreTools.Library/DatItems/Port.cs new file mode 100644 index 00000000..1a1eb6a2 --- /dev/null +++ b/SabreTools.Library/DatItems/Port.cs @@ -0,0 +1,196 @@ +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 +{ + /// + /// Represents a single port on a machine + /// + [JsonObject("port")] + public class Port : DatItem + { + #region Fields + + /// + /// Tag for the port + /// + [JsonProperty("tag", DefaultValueHandling = DefaultValueHandling.Ignore)] + public string Tag { get; set; } + + /// + /// List of analogs on the port + /// + [JsonProperty("analogs", DefaultValueHandling = DefaultValueHandling.Ignore)] + public List Analogs { get; set; } + + #endregion + + #region Accessors + + /// + /// Set fields with given values + /// + /// Mappings dictionary + public override void SetFields(Dictionary mappings) + { + // Set base fields + base.SetFields(mappings); + + // Handle Port-specific fields + if (mappings.Keys.Contains(Field.DatItem_Name)) + Tag = mappings[Field.DatItem_Name]; + + // TODO: Handle DatItem_Analog* + } + + #endregion + + #region Constructors + + /// + /// Create a default, empty Port object + /// + public Port() + { + ItemType = ItemType.Port; + } + + #endregion + + #region Cloning Methods + + public override object Clone() + { + return new Port() + { + ItemType = this.ItemType, + DupeType = this.DupeType, + + AltName = this.AltName, + AltTitle = this.AltTitle, + + Original = this.Original, + OpenMSXSubType = this.OpenMSXSubType, + OpenMSXType = this.OpenMSXType, + Remark = this.Remark, + Boot = this.Boot, + + Part = this.Part, + Features = this.Features, + AreaName = this.AreaName, + AreaSize = this.AreaSize, + AreaWidth = this.AreaWidth, + AreaEndianness = this.AreaEndianness, + Value = this.Value, + LoadFlag = this.LoadFlag, + + Machine = this.Machine.Clone() as Machine, + Source = this.Source.Clone() as Source, + Remove = this.Remove, + + Tag = this.Tag, + Analogs = this.Analogs, + }; + } + + #endregion + + #region Comparision Methods + + public override bool Equals(DatItem other) + { + // If we don't have a Port, return false + if (ItemType != other.ItemType) + return false; + + // Otherwise, treat it as a Port + Port newOther = other as Port; + + // If the Port information matches + return (Tag == newOther.Tag); // TODO: Handle DatItem_Analog* + } + + #endregion + + #region Filtering + + /// + /// 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 tag + if (filter.DatItem_Tag.MatchesPositiveSet(Tag) == false) + return false; + if (filter.DatItem_Tag.MatchesNegativeSet(Tag) == true) + return false; + + // TODO: Handle DatItem_Analog* + + 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_Tag)) + Tag = null; + + if (fields.Contains(Field.DatItem_Analogs)) + Analogs = null; + + // TODO: Handle DatItem_Analog* + } + + #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 Port to replace from, ignore specific fields + if (item.ItemType != ItemType.Port) + return; + + // Cast for easier access + Port newItem = item as Port; + + // Replace the fields + if (fields.Contains(Field.DatItem_Name)) + Tag = newItem.Tag; + + if (fields.Contains(Field.DatItem_Analogs)) + Analogs = newItem.Analogs; + + // TODO: Handle DatItem_Analog* + } + + #endregion + } +} diff --git a/SabreTools.Library/Filtering/Filter.cs b/SabreTools.Library/Filtering/Filter.cs index f9ca680c..3a644895 100644 --- a/SabreTools.Library/Filtering/Filter.cs +++ b/SabreTools.Library/Filtering/Filter.cs @@ -90,14 +90,6 @@ namespace SabreTools.Library.Filtering public FilterItem Machine_Input_Control_Ways2 { get; private set; } = new FilterItem(); public FilterItem Machine_Input_Control_Ways3 { get; private set; } = new FilterItem(); - // Ports - public FilterItem Machine_Ports { get; private set; } = new FilterItem() { Neutral = null }; - public FilterItem Machine_Port_Tag { get; private set; } = new FilterItem(); - - // Ports.Analogs - public FilterItem Machine_Port_Analogs { get; private set; } = new FilterItem() { Neutral = null }; - public FilterItem Machine_Port_Analog_Mask { get; private set; } = new FilterItem(); - #endregion #region Logiqx @@ -293,6 +285,10 @@ namespace SabreTools.Library.Filtering public FilterItem DatItem_FeatureStatus { get; private set; } = new FilterItem() { Positive = FeatureStatus.NULL, Negative = FeatureStatus.NULL }; public FilterItem DatItem_FeatureOverall { get; private set; } = new FilterItem() { Positive = FeatureStatus.NULL, Negative = FeatureStatus.NULL }; + // Port.Analogs + public FilterItem DatItem_Analogs { get; private set; } = new FilterItem() { Neutral = null }; + public FilterItem DatItem_Analog_Mask { get; private set; } = new FilterItem(); + // Ram Option public FilterItem DatItem_Content { get; private set; } = new FilterItem(); @@ -773,34 +769,20 @@ namespace SabreTools.Library.Filtering Machine_Input_Control_Ways3.PositiveSet.Add(value); break; - // Ports - case Field.Machine_Ports: - if (negate || value.Equals("false", StringComparison.OrdinalIgnoreCase)) - Machine_Ports.Neutral = false; - else - Machine_Ports.Neutral = true; - break; - - case Field.Machine_Port_Tag: - if (negate) - Machine_Port_Tag.NegativeSet.Add(value); - else - Machine_Port_Tag.PositiveSet.Add(value); - break; // Ports.Analogs - case Field.Machine_Port_Analogs: + case Field.DatItem_Analogs: if (negate || value.Equals("false", StringComparison.OrdinalIgnoreCase)) - Machine_Port_Analogs.Neutral = false; + DatItem_Analogs.Neutral = false; else - Machine_Port_Analogs.Neutral = true; + DatItem_Analogs.Neutral = true; break; - case Field.Machine_Port_Analog_Mask: + case Field.DatItem_Analog_Mask: if (negate) - Machine_Port_Analog_Mask.NegativeSet.Add(value); + DatItem_Analog_Mask.NegativeSet.Add(value); else - Machine_Port_Analog_Mask.PositiveSet.Add(value); + DatItem_Analog_Mask.PositiveSet.Add(value); break; #endregion diff --git a/SabreTools.Library/Tools/Converters.cs b/SabreTools.Library/Tools/Converters.cs index 1accfea3..1f70f01d 100644 --- a/SabreTools.Library/Tools/Converters.cs +++ b/SabreTools.Library/Tools/Converters.cs @@ -671,18 +671,6 @@ namespace SabreTools.Library.Tools case "input_control_ways3": return Field.Machine_Input_Control_Ways3; - case "ports": - return Field.Machine_Ports; - - case "port_tag": - return Field.Machine_Port_Tag; - - case "port_analogs": - return Field.Machine_Port_Analogs; - - case "port_analog_mask": - return Field.Machine_Port_Analog_Mask; - #endregion #region Logiqx @@ -1115,6 +1103,13 @@ namespace SabreTools.Library.Tools case "featureoverall": return Field.DatItem_FeatureOverall; + // Port + case "analogs": + return Field.DatItem_Analogs; + + case "analog_mask": + return Field.DatItem_Analog_Mask; + // Ram Option case "content": return Field.DatItem_Content; @@ -1685,6 +1680,8 @@ namespace SabreTools.Library.Tools return ItemType.Instance; case "media": return ItemType.Media; + case "port": + return ItemType.Port; case "ramoption": return ItemType.RamOption; case "release": @@ -1722,6 +1719,7 @@ namespace SabreTools.Library.Tools "feature" => ItemType.Feature, "instance" => ItemType.Instance, "media" => ItemType.Media, + "port" => ItemType.Port, "ramoption" => ItemType.RamOption, "release" => ItemType.Release, "rom" => ItemType.Rom, @@ -2305,6 +2303,8 @@ namespace SabreTools.Library.Tools return "instance"; case ItemType.Media: return "media"; + case ItemType.Port: + return "port"; case ItemType.RamOption: return "ramoption"; case ItemType.Release: @@ -2342,6 +2342,7 @@ namespace SabreTools.Library.Tools ItemType.Feature => "feature", ItemType.Instance => "instance", ItemType.Media => "media", + ItemType.Port => "port", ItemType.RamOption => "ramoption", ItemType.Release => "release", ItemType.Rom => "rom",