/// <summary> /// Clean a DatItem according to the cleaner /// </summary> /// <param name="datItem">DatItem to clean</param> internal void CleanDatItem(DatItem datItem) { // If we're stripping unicode characters, strip machine name and description if (RemoveUnicode) { datItem.Machine.Name = RemoveUnicodeCharacters(datItem.Machine.Name); datItem.Machine.Description = RemoveUnicodeCharacters(datItem.Machine.Description); datItem.SetName(RemoveUnicodeCharacters(datItem.GetName())); } // If we're in cleaning mode, sanitize machine name and description if (Clean) { datItem.Machine.Name = CleanGameName(datItem.Machine.Name); datItem.Machine.Description = CleanGameName(datItem.Machine.Description); } // If we are in single game mode, rename the machine if (Single) { datItem.Machine.Name = "!"; } // If we are in NTFS trim mode, trim the item name if (Trim && datItem.GetName() != null) { // Windows max name length is 260 int usableLength = 260 - datItem.Machine.Name.Length - (Root?.Length ?? 0); if (datItem.GetName().Length > usableLength) { string ext = Path.GetExtension(datItem.GetName()); datItem.SetName(datItem.GetName().Substring(0, usableLength - ext.Length) + ext); } } }
/// <summary> /// Apply SuperDAT naming logic to a merged DatFile /// </summary> /// <param name="datFile">Current DatFile object to run operations on</param> /// <param name="inputs">List of inputs to use for renaming</param> public static void ApplySuperDAT(DatFile datFile, List <ParentablePath> inputs) { List <string> keys = datFile.Items.Keys.ToList(); Parallel.ForEach(keys, Globals.ParallelOptions, key => { ConcurrentList <DatItem> items = datFile.Items[key]; ConcurrentList <DatItem> newItems = new ConcurrentList <DatItem>(); foreach (DatItem item in items) { DatItem newItem = item; string filename = inputs[newItem.Source.Index].CurrentPath; string rootpath = inputs[newItem.Source.Index].ParentPath; if (!string.IsNullOrWhiteSpace(rootpath)) { rootpath += Path.DirectorySeparatorChar.ToString(); } filename = filename.Remove(0, rootpath.Length); newItem.Machine.Name = Path.GetDirectoryName(filename) + Path.DirectorySeparatorChar + Path.GetFileNameWithoutExtension(filename) + Path.DirectorySeparatorChar + newItem.Machine.Name; newItems.Add(newItem); } datFile.Items.Remove(key); datFile.Items.AddRange(key, newItems); }); }
public override bool Equals(DatItem other) { // If we don't have a Adjuster, return false if (ItemType != other.ItemType) { return(false); } // Otherwise, treat it as a Adjuster Adjuster newOther = other as Adjuster; // If the Adjuster information matches bool match = (Name == newOther.Name && Default == newOther.Default); if (!match) { return(match); } // If the conditions match if (ConditionsSpecified) { foreach (Condition condition in Conditions) { match &= newOther.Conditions.Contains(condition); } } return(match); }
public override bool Equals(DatItem other) { // If we don't have a Display, return false if (ItemType != other.ItemType) { return(false); } // Otherwise, treat it as a Display Display newOther = other as Display; // If the Display information matches return(Tag == newOther.Tag && DisplayType == newOther.DisplayType && Rotate == newOther.Rotate && FlipX == newOther.FlipX && Width == newOther.Width && Height == newOther.Height && Refresh == newOther.Refresh && PixClock == newOther.PixClock && HTotal == newOther.HTotal && HBEnd == newOther.HBEnd && HBStart == newOther.HBStart && VTotal == newOther.VTotal && VBEnd == newOther.VBEnd && VBStart == newOther.VBStart); }
/// <summary> /// Write out Game start using the supplied StreamWriter /// </summary> /// <param name="sw">StreamWriter to output to</param> /// <param name="rom">DatItem object to be output</param> /// <returns>True if the data was written, false on error</returns> private bool WriteStartGame(StreamWriter sw, DatItem rom) { try { // No game should start with a path separator if (rom.MachineName.StartsWith(Path.DirectorySeparatorChar.ToString())) { rom.MachineName = rom.MachineName.Substring(1); } string state = "<software>\n" + "\t<title>" + (!ExcludeFields[(int)Field.MachineName] ? WebUtility.HtmlEncode(rom.MachineName) : "") + "</title>\n" // + "\t<genmsxid>" + msxid + "</genmsxid>\n" // + "\t<system>" + system + "</system>\n" + "\t<company>" + (!ExcludeFields[(int)Field.Manufacturer] ? rom.Manufacturer : "") + "</company>\n" + "\t<year>" + (!ExcludeFields[(int)Field.Year] ? rom.Year : "") + "</year>\n"; // + "\t<country>" + country + "</country>\n"; sw.Write(state); sw.Flush(); } catch (Exception ex) { Globals.Logger.Error(ex.ToString()); return(false); } return(true); }
/// <summary> /// Strip the dates from the beginning of scene-style set names /// </summary> /// <param name="datFile">Current DatFile object to run operations on</param> internal void StripSceneDatesFromItems(DatFile datFile) { // Output the logging statement logger.User("Stripping scene-style dates"); // Set the regex pattern to use string pattern = @"([0-9]{2}\.[0-9]{2}\.[0-9]{2}-)(.*?-.*?)"; // Now process all of the roms Parallel.ForEach(datFile.Items.Keys, Globals.ParallelOptions, key => { ConcurrentList <DatItem> items = datFile.Items[key]; for (int j = 0; j < items.Count; j++) { DatItem item = items[j]; if (Regex.IsMatch(item.Machine.Name, pattern)) { item.Machine.Name = Regex.Replace(item.Machine.Name, pattern, "$2"); } if (Regex.IsMatch(item.Machine.Description, pattern)) { item.Machine.Description = Regex.Replace(item.Machine.Description, pattern, "$2"); } items[j] = item; } datFile.Items.Remove(key); datFile.Items.AddRange(key, items); }); }
public override bool Equals(DatItem other) { // If we don't have a Slot, return false if (ItemType != other.ItemType) { return(false); } // Otherwise, treat it as a Slot Slot newOther = other as Slot; // If the Slot information matches bool match = (Name == newOther.Name); if (!match) { return(match); } // If the slot options match if (SlotOptionsSpecified) { foreach (SlotOption slotOption in SlotOptions) { match &= newOther.SlotOptions.Contains(slotOption); } } return(match); }
/// <summary> /// Output duplicate item diff /// </summary> /// <param name="datFile">Current DatFile object to use for updating</param> /// <param name="inputs">List of inputs to write out from</param> public static DatFile DiffDuplicates(DatFile datFile, List <ParentablePath> inputs) { InternalStopwatch watch = new InternalStopwatch("Initializing duplicate DAT"); // Fill in any information not in the base DAT if (string.IsNullOrWhiteSpace(datFile.Header.FileName)) { datFile.Header.FileName = "All DATs"; } if (string.IsNullOrWhiteSpace(datFile.Header.Name)) { datFile.Header.Name = "datFile.All DATs"; } if (string.IsNullOrWhiteSpace(datFile.Header.Description)) { datFile.Header.Description = "datFile.All DATs"; } string post = " (Duplicates)"; DatFile dupeData = DatFile.Create(datFile.Header); dupeData.Header.FileName += post; dupeData.Header.Name += post; dupeData.Header.Description += post; dupeData.Items = new ItemDictionary(); watch.Stop(); // Now, loop through the dictionary and populate the correct DATs watch.Start("Populating duplicate DAT"); Parallel.ForEach(datFile.Items.Keys, Globals.ParallelOptions, key => { ConcurrentList <DatItem> items = DatItem.Merge(datFile.Items[key]); // If the rom list is empty or null, just skip it if (items == null || items.Count == 0) { return; } // Loop through and add the items correctly foreach (DatItem item in items) { if (item.DupeType.HasFlag(DupeType.External)) { DatItem newrom = item.Clone() as DatItem; newrom.Machine.Name += $" ({Path.GetFileNameWithoutExtension(inputs[item.Source.Index].CurrentPath)})"; dupeData.Items.Add(key, newrom); } } }); watch.Stop(); return(dupeData); }
/// <summary> /// Write out Game start using the supplied StreamWriter /// </summary> /// <param name="sw">StreamWriter to output to</param> /// <param name="rom">DatItem object to be output</param> /// <returns>True if the data was written, false on error</returns> private bool WriteStartGame(StreamWriter sw, DatItem rom) { try { // No game should start with a path separator if (rom.MachineName.StartsWith(Path.DirectorySeparatorChar.ToString())) { rom.MachineName = rom.MachineName.Substring(1); } string state = (rom.MachineType == MachineType.Bios ? "resource" : "game") + " (\n\tname \"" + (!ExcludeFields[(int)Field.MachineName] ? rom.MachineName : "") + "\"\n" + (!ExcludeFields[(int)Field.RomOf] && String.IsNullOrWhiteSpace(rom.RomOf) ? "" : "\tromof \"" + rom.RomOf + "\"\n") + (!ExcludeFields[(int)Field.CloneOf] && String.IsNullOrWhiteSpace(rom.CloneOf) ? "" : "\tcloneof \"" + rom.CloneOf + "\"\n") + (!ExcludeFields[(int)Field.SampleOf] && String.IsNullOrWhiteSpace(rom.SampleOf) ? "" : "\tsampleof \"" + rom.SampleOf + "\"\n") + (!ExcludeFields[(int)Field.Description] ? "\tdescription \"" + (String.IsNullOrWhiteSpace(rom.MachineDescription) ? rom.MachineName : rom.MachineDescription) + "\"\n" : "") + (!ExcludeFields[(int)Field.Year] && String.IsNullOrWhiteSpace(rom.Year) ? "" : "\tyear " + rom.Year + "\n") + (!ExcludeFields[(int)Field.Manufacturer] && String.IsNullOrWhiteSpace(rom.Manufacturer) ? "" : "\tmanufacturer \"" + rom.Manufacturer + "\"\n"); sw.Write(state); sw.Flush(); } catch (Exception ex) { Globals.Logger.Error(ex.ToString()); return(false); } return(true); }
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 (FeaturesSpecified) { foreach (PartFeature partFeature in Features) { match &= newOther.Features.Contains(partFeature); } } return(match); }
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 bool match = (Tag == newOther.Tag); if (!match) { return(match); } // If the analogs match if (AnalogsSpecified) { foreach (Analog analog in Analogs) { match &= newOther.Analogs.Contains(analog); } } return(match); }
public override bool Equals(DatItem other) { bool dupefound = false; // If we don't have a rom, return false if (ItemType != other.ItemType) { return(dupefound); } // Otherwise, treat it as a Rom Rom newOther = other as Rom; // If all hashes are empty but they're both nodump and the names match, then they're dupes if ((ItemStatus == ItemStatus.Nodump && newOther.ItemStatus == ItemStatus.Nodump) && Name == newOther.Name && !HasHashes() && !newOther.HasHashes()) { dupefound = true; } // If we have a file that has no known size, rely on the hashes only else if (Size == null && HashMatch(newOther)) { dupefound = true; } // Otherwise if we get a partial match else if (Size == newOther.Size && HashMatch(newOther)) { dupefound = true; } return(dupefound); }
public override bool Equals(DatItem other) { bool dupefound = false; // If we don't have a rom, return false if (ItemType != other.ItemType) { return(dupefound); } // Otherwise, treat it as a Disk Disk newOther = other as Disk; // If all hashes are empty but they're both nodump and the names match, then they're dupes if ((ItemStatus == ItemStatus.Nodump && newOther.ItemStatus == ItemStatus.Nodump) && Name == newOther.Name && !HasHashes() && !newOther.HasHashes()) { dupefound = true; } // Otherwise if we get a partial match else if (HashMatch(newOther)) { dupefound = true; } return(dupefound); }
public override bool Equals(DatItem other) { // If we don't have a Control, return false if (ItemType != other.ItemType) { return(false); } // Otherwise, treat it as a Control Control newOther = other as Control; // If the Control information matches return(ControlType == newOther.ControlType && Player == newOther.Player && Buttons == newOther.Buttons && RequiredButtons == newOther.RequiredButtons && Minimum == newOther.Minimum && Maximum == newOther.Maximum && Sensitivity == newOther.Sensitivity && KeyDelta == newOther.KeyDelta && Reverse == newOther.Reverse && Ways == newOther.Ways && Ways2 == newOther.Ways2 && Ways3 == newOther.Ways3); }
public override bool Equals(DatItem other) { // If we don't have a Input, return false if (ItemType != other.ItemType) { return(false); } // Otherwise, treat it as a Input Input newOther = other as Input; // If the Input information matches bool match = (Service == newOther.Service && Tilt == newOther.Tilt && Players == newOther.Players && Coins == newOther.Coins); if (!match) { return(match); } // If the controls match if (ControlsSpecified) { foreach (Control control in Controls) { match &= newOther.Controls.Contains(control); } } return(match); }
public void CreateBaseFileTest(FileType fileType, ItemType?expected) { var baseFile = CreateBaseFile(fileType); var actual = DatItem.Create(baseFile); Assert.Equal(expected, actual?.ItemType); }
/// <summary> /// Get the Stream related to a file /// </summary> /// <param name="datItem">Information for the current file to rebuild from</param> /// <param name="file">Name of the file to process</param> /// <param name="isZip">Non-null if the input file is an archive</param> /// <param name="stream">Output stream representing the opened file</param> /// <returns>True if the stream opening succeeded, false otherwise</returns> private static bool GetFileStream(DatItem datItem, string file, bool?isZip, out Stream stream) { // Get a generic stream for the file stream = null; // If we have a zipfile, extract the stream to memory if (isZip != null) { BaseArchive archive = BaseArchive.Create(file); if (archive != null) { (stream, _) = archive.CopyToStream(datItem.GetName() ?? datItem.ItemType.ToString()); } } // Otherwise, just open the filestream else { stream = File.OpenRead(file); } // If the stream is null, then continue if (stream == null) { return(false); } // Seek to the beginning of the stream if (stream.CanSeek) { stream.Seek(0, SeekOrigin.Begin); } return(true); }
/// <summary> /// Write out Game start using the supplied StreamWriter /// </summary> /// <param name="sw">StreamWriter to output to</param> /// <param name="rom">DatItem object to be output</param> /// <param name="newsplit">Split path representing the parent game (SabreDAT only)</param> /// <param name="lastgame">The name of the last game to be output</param> /// <param name="depth">Current depth to output file at (SabreDAT only)</param> /// <param name="last">Last known depth to cycle back from (SabreDAT only)</param> /// <returns>The new depth of the tag</returns> private int WriteStartGame(StreamWriter sw, DatItem rom, List <string> newsplit, string lastgame, int depth, int last) { try { // No game should start with a path separator if (rom.MachineName.StartsWith(Path.DirectorySeparatorChar.ToString())) { rom.MachineName = rom.MachineName.Substring(1); } string state = ""; for (int i = (last == -1 ? 0 : last); i < newsplit.Count; i++) { for (int j = 0; j < depth - last + i - (lastgame == null ? 1 : 0); j++) { state += "\t"; } state += "<directory name=\"" + (!ExcludeFields[(int)Field.MachineName] ? HttpUtility.HtmlEncode(newsplit[i]) : "") + "\" description=\"" + HttpUtility.HtmlEncode(newsplit[i]) + "\">\n"; } depth = depth - (last == -1 ? 0 : last) + newsplit.Count; sw.Write(state); sw.Flush(); } catch (Exception ex) { Globals.Logger.Error(ex.ToString()); return(depth); } return(depth); }
/// <summary> /// Write out Game start using the supplied StreamWriter /// </summary> /// <param name="svw">SeparatedValueWriter to output to</param> /// <param name="datItem">DatItem object to be output</param> private void WriteDatItem(SeparatedValueWriter svw, DatItem datItem) { // No game should start with a path separator datItem.Machine.Name = datItem.Machine.Name.TrimStart(Path.DirectorySeparatorChar); // Pre-process the item name ProcessItemName(datItem, true); // Build the state switch (datItem.ItemType) { case ItemType.Rom: var rom = datItem as Rom; string[] fields = new string[] { rom.SHA256 ?? string.Empty, $"{rom.Machine.Name ?? string.Empty}/", rom.Name ?? string.Empty, rom.SHA1 ?? string.Empty, rom.MD5 ?? string.Empty, rom.CRC ?? string.Empty, }; svw.WriteValues(fields); break; } svw.Flush(); }
/// <summary> /// Set proper Game and Rom names from user inputs /// </summary> /// <param name="datFile">Current DatFile object to add to</param> /// <param name="datItem">DatItem representing the input file</param> /// <param name="item">Item name to use</param> /// <param name="parent">Parent name to use</param> /// <param name="basepath">Base path to use</param> private static void SetDatItemInfo(DatFile datFile, DatItem datItem, string item, string parent, string basepath) { // Get the data to be added as game and item names string machineName, itemName; // If the parent is blank, then we have a non-archive file if (string.IsNullOrWhiteSpace(parent)) { // If we have a SuperDAT, we want anything that's not the base path as the game, and the file as the rom if (datFile.Header.Type == "SuperDAT") { machineName = Path.GetDirectoryName(item.Remove(0, basepath.Length)); itemName = Path.GetFileName(item); } // Otherwise, we want just the top level folder as the game, and the file as everything else else { machineName = item.Remove(0, basepath.Length).Split(Path.DirectorySeparatorChar)[0]; itemName = item.Remove(0, (Path.Combine(basepath, machineName).Length)); } } // Otherwise, we assume that we have an archive else { // If we have a SuperDAT, we want the archive name as the game, and the file as everything else (?) if (datFile.Header.Type == "SuperDAT") { machineName = parent; itemName = datItem.GetName(); } // Otherwise, we want the archive name as the game, and the file as everything else else { machineName = parent; itemName = datItem.GetName(); } } // Sanitize the names machineName = machineName.Trim(Path.DirectorySeparatorChar); itemName = itemName?.Trim(Path.DirectorySeparatorChar) ?? string.Empty; if (!string.IsNullOrWhiteSpace(machineName) && string.IsNullOrWhiteSpace(itemName)) { itemName = machineName; machineName = "Default"; } // Update machine information datItem.Machine.Name = machineName; datItem.Machine.Description = machineName; // If we have a Disk, then the ".chd" extension needs to be removed if (datItem.ItemType == ItemType.Disk && itemName.EndsWith(".chd")) { itemName = itemName[0..^ 4];
/// <inheritdoc/> public override void ParseFile(string filename, int indexId, bool keep, bool statsOnly = false, bool throwOnError = false) { // Open a file reader Encoding enc = filename.GetEncoding(); SeparatedValueReader svr = new SeparatedValueReader(File.OpenRead(filename), enc) { Header = true, Quotes = true, Separator = _delim, VerifyFieldCount = true, }; // If we're somehow at the end of the stream already, we can't do anything if (svr.EndOfStream) { return; } // Read in the header svr.ReadHeader(); // Loop through all of the data lines while (!svr.EndOfStream) { try { // Get the current line, split and parse svr.ReadNextLine(); // Create mapping dictionaries Setter setter = new Setter(); setter.PopulateSettersFromList(svr.HeaderValues, svr.Line); // Set DatHeader fields DatHeader datHeader = new DatHeader(); setter.SetFields(datHeader); Header.ConditionalCopy(datHeader); // Set Machine and DatItem fields if (setter.DatItemMappings.ContainsKey(DatItemField.Type)) { DatItem datItem = DatItem.Create(setter.DatItemMappings[DatItemField.Type].AsItemType()); setter.SetFields(datItem); datItem.Machine = new Machine(); setter.SetFields(datItem.Machine); datItem.Source = new Source(indexId, filename); ParseAddHelper(datItem, statsOnly); } } catch (Exception ex) when(!throwOnError) { string message = $"'{filename}' - There was an error parsing line {svr.LineNumber} '{svr.CurrentLine}'"; logger.Error(ex, message); } } svr.Dispose(); }
/// <summary> /// Process a single file as a file /// </summary> /// <param name="datFile">Current DatFile object to add to</param> /// <param name="item">File to be added</param> /// <param name="basePath">Path the represents the parent directory</param> /// <param name="hashes">Hashes to include in the information</param> /// <param name="asFiles">TreatAsFiles representing CHD and Archive scanning</param> private static void ProcessFile(DatFile datFile, string item, string basePath, Hash hashes, TreatAsFile asFiles) { logger.Verbose($"'{Path.GetFileName(item)}' treated like a file"); BaseFile baseFile = BaseFile.GetInfo(item, header: datFile.Header.HeaderSkipper, hashes: hashes, asFiles: asFiles); DatItem datItem = DatItem.Create(baseFile); ProcessFileHelper(datFile, item, datItem, basePath, string.Empty); }
/// <summary> /// Write out DatItem using the supplied StreamWriter /// </summary> /// <param name="xtw">XmlTextWriter to output to</param> /// <param name="datItem">DatItem object to be output</param> private void WriteDatItem(XmlTextWriter xtw, DatItem datItem) { // Pre-process the item name ProcessItemName(datItem, true); // Build the state switch (datItem.ItemType) { case ItemType.Rom: var rom = datItem as Rom; xtw.WriteStartElement("dump"); if (rom.Original != null) { xtw.WriteStartElement("original"); xtw.WriteAttributeString("value", rom.Original.Value == true ? "true" : "false"); xtw.WriteString(rom.Original.Content); xtw.WriteEndElement(); } switch (rom.OpenMSXSubType) { // Default to Rom for converting from other formats case OpenMSXSubType.Rom: case OpenMSXSubType.NULL: xtw.WriteStartElement(rom.OpenMSXSubType.FromOpenMSXSubType()); xtw.WriteRequiredElementString("hash", rom.SHA1?.ToLowerInvariant()); xtw.WriteOptionalElementString("start", rom.Offset); xtw.WriteOptionalElementString("type", rom.OpenMSXType); xtw.WriteOptionalElementString("remark", rom.Remark); xtw.WriteEndElement(); break; case OpenMSXSubType.MegaRom: xtw.WriteStartElement(rom.OpenMSXSubType.FromOpenMSXSubType()); xtw.WriteRequiredElementString("hash", rom.SHA1?.ToLowerInvariant()); xtw.WriteOptionalElementString("start", rom.Offset); xtw.WriteOptionalElementString("type", rom.OpenMSXType); xtw.WriteOptionalElementString("remark", rom.Remark); xtw.WriteEndElement(); break; case OpenMSXSubType.SCCPlusCart: xtw.WriteStartElement(rom.OpenMSXSubType.FromOpenMSXSubType()); xtw.WriteOptionalElementString("boot", rom.Boot); xtw.WriteRequiredElementString("hash", rom.SHA1?.ToLowerInvariant()); xtw.WriteOptionalElementString("remark", rom.Remark); xtw.WriteEndElement(); break; } // End dump xtw.WriteEndElement(); break; } xtw.Flush(); }
/// <summary> /// Write out DatItem using the supplied StreamWriter /// </summary> /// <param name="sw">StreamWriter to output to</param> /// <param name="rom">DatItem object to be output</param> /// <param name="ignoreblanks">True if blank roms should be skipped on output, false otherwise (default)</param> /// <returns>True if the data was written, false on error</returns> private bool WriteDatItem(StreamWriter sw, DatItem rom, bool ignoreblanks = false) { // If we are in ignore blanks mode AND we have a blank (0-size) rom, skip if (ignoreblanks && (rom.ItemType == ItemType.Rom && (((Rom)rom).Size == 0 || ((Rom)rom).Size == -1))) { return(true); } try { string state = ""; // Pre-process the item name ProcessItemName(rom, true); switch (rom.ItemType) { case ItemType.Archive: break; case ItemType.BiosSet: break; case ItemType.Disk: break; case ItemType.Release: break; case ItemType.Rom: // Currently this encapsulates rom, megarom, and sccpluscart state += "\t\t<dump>" // + "<original value=\"true\">GoodMSX</original>" + "<rom>" + (!ExcludeFields[(int)Field.Offset] && !String.IsNullOrWhiteSpace(((Rom)rom).Offset) ? "<start>" + ((Rom)rom).Offset + "</start>" : "") // + "<type>Normal</type>" + "<hash>" + (!ExcludeFields[(int)Field.SHA1] ? ((Rom)rom).SHA1 : "") + "</hash>" // + "<remark></remark>" + "</rom></dump>\n"; break; case ItemType.Sample: break; } sw.Write(state); sw.Flush(); } catch (Exception ex) { Globals.Logger.Error(ex.ToString()); return(false); } return(true); }
public override bool Equals(DatItem other) { // If we don't have a DipSwitch, return false if (ItemType != other.ItemType) { return(false); } // Otherwise, treat it as a DipSwitch DipSwitch newOther = other as DipSwitch; // If the DipSwitch information matches bool match = (Name == newOther.Name && Tag == newOther.Tag && Mask == newOther.Mask); if (!match) { return(match); } // If the part matches if (PartSpecified) { match &= (Part == newOther.Part); } // If the conditions match if (ConditionsSpecified) { foreach (Condition condition in Conditions) { match &= newOther.Conditions.Contains(condition); } } // If the locations match if (LocationsSpecified) { foreach (Location location in Locations) { match &= newOther.Locations.Contains(location); } } // If the values match if (ValuesSpecified) { foreach (Setting value in Values) { match &= newOther.Values.Contains(value); } } return(match); }
/// <summary> /// Write out Game end using the supplied StreamWriter /// </summary> /// <param name="cmpw">ClrMameProWriter to output to</param> /// <param name="datItem">DatItem object to be output</param> private void WriteEndGame(ClrMameProWriter cmpw, DatItem datItem) { // Build the state cmpw.WriteOptionalStandalone("sampleof", datItem.Machine.SampleOf); // End game cmpw.WriteEndElement(); cmpw.Flush(); }
/// <summary> /// Set internal names to match One Rom Per Game (ORPG) logic /// </summary> /// <param name="datItem">DatItem to run logic on</param> internal void SetOneRomPerGame(DatItem datItem) { if (datItem.GetName() == null) { return; } string[] splitname = datItem.GetName().Split('.'); datItem.Machine.Name += $"/{string.Join(".", splitname.Take(splitname.Length > 1 ? splitname.Length - 1 : 1))}"; datItem.SetName(Path.GetFileName(datItem.GetName())); }
/// <summary> /// Use cloneof tags to add roms to the children, setting the new romof tag in the process /// </summary> /// <param name="datFile">Current DatFile object to run operations on</param> internal static void AddRomsFromParent(DatFile datFile) { List <string> games = datFile.Items.Keys.OrderBy(g => g).ToList(); foreach (string game in games) { // If the game has no items in it, we want to continue if (datFile.Items[game].Count == 0) { continue; } // Determine if the game has a parent or not string parent = null; if (!string.IsNullOrWhiteSpace(datFile.Items[game][0].Machine.CloneOf)) { parent = datFile.Items[game][0].Machine.CloneOf; } // If the parent doesnt exist, we want to continue if (string.IsNullOrWhiteSpace(parent)) { continue; } // If the parent doesn't have any items, we want to continue if (datFile.Items[parent].Count == 0) { continue; } // If the parent exists and has items, we copy the items from the parent to the current game DatItem copyFrom = datFile.Items[game][0]; ConcurrentList <DatItem> parentItems = datFile.Items[parent]; foreach (DatItem item in parentItems) { DatItem datItem = (DatItem)item.Clone(); datItem.CopyMachineInformation(copyFrom); if (datFile.Items[game].Where(i => i.GetName()?.ToLowerInvariant() == datItem.GetName()?.ToLowerInvariant()).Count() == 0 && !datFile.Items[game].Contains(datItem)) { datFile.Items.Add(game, datItem); } } // Now we want to get the parent romof tag and put it in each of the items ConcurrentList <DatItem> items = datFile.Items[game]; string romof = datFile.Items[parent][0].Machine.RomOf; foreach (DatItem item in items) { item.Machine.RomOf = romof; } } }
/// <summary> /// Write out Game start using the supplied StreamWriter /// </summary> /// <param name="cmpw">ClrMameProWriter to output to</param> /// <param name="datItem">DatItem object to be output</param> private void WriteStartGame(ClrMameProWriter cmpw, DatItem datItem) { // No game should start with a path separator datItem.Machine.Name = datItem.Machine.Name.TrimStart(Path.DirectorySeparatorChar); // Build the state cmpw.WriteStartElement("game"); cmpw.WriteRequiredStandalone("name", $"{datItem.Machine.Name}.zip", true); cmpw.Flush(); }
/// <summary> /// Write out Game start using the supplied StreamWriter /// </summary> /// <param name="sw">StreamWriter to output to</param> /// <param name="rom">DatItem object to be output</param> private void WriteStartGame(StreamWriter sw, DatItem rom) { // No game should start with a path separator rom.Machine.Name = rom.Machine.Name.TrimStart(Path.DirectorySeparatorChar); // Build the state sw.Write($"ROMs required for driver \"{rom.Machine.Name}\".\n"); sw.Write("Name Size Checksum\n"); sw.Flush(); }