From 74c92d2ef1df672d9c5ea5980b7410bb17d36597 Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Tue, 20 Mar 2018 15:10:43 -0700 Subject: [PATCH] [SabreTools, DatFile, DatHeader] Add one-rom-per-game --- SabreTools.Library/DatFiles/DatFile.cs | 74 +++++++++++++++++++----- SabreTools.Library/DatFiles/DatHeader.cs | 7 +++ SabreTools.Library/README.1ST | 12 +++- SabreTools/SabreTools.Help.cs | 14 +++++ SabreTools/SabreTools.cs | 55 +++++++++--------- 5 files changed, 120 insertions(+), 42 deletions(-) diff --git a/SabreTools.Library/DatFiles/DatFile.cs b/SabreTools.Library/DatFiles/DatFile.cs index 88c0b253..1ad91ad2 100644 --- a/SabreTools.Library/DatFiles/DatFile.cs +++ b/SabreTools.Library/DatFiles/DatFile.cs @@ -451,6 +451,27 @@ namespace SabreTools.Library.DatFiles _datHeader.ExcludeOf = value; } } + public bool OneRom + { + get + { + if (_datHeader == null) + { + _datHeader = new DatHeader(); + } + + return _datHeader.OneRom; + } + set + { + if (_datHeader == null) + { + _datHeader = new DatHeader(); + } + + _datHeader.ExcludeOf = value; + } + } public bool KeepEmptyGames { get @@ -1721,23 +1742,24 @@ namespace SabreTools.Library.DatFiles Globals.Logger.User("Adding DAT: {0}", input.Split('¬')[0]); datHeaders[i] = new DatFile() { - DatFormat = (DatFormat != 0 ? DatFormat : 0), + DatFormat = (this.DatFormat != 0 ? this.DatFormat : 0), // Filtering that needs to be copied over - ExcludeOf = ExcludeOf, - KeepEmptyGames = KeepEmptyGames, - SceneDateStrip = SceneDateStrip, - DedupeRoms = DedupeRoms, - StripHash = StripHash, - Prefix = Prefix, - Postfix = Postfix, - AddExtension = AddExtension, - ReplaceExtension = ReplaceExtension, - RemoveExtension = RemoveExtension, - Romba = Romba, - GameName = GameName, - Quotes = Quotes, - UseRomName = UseRomName, + ExcludeOf = this.ExcludeOf, + OneRom = this.OneRom, + KeepEmptyGames = this.KeepEmptyGames, + SceneDateStrip = this.SceneDateStrip, + DedupeRoms = this.DedupeRoms, + StripHash = this.StripHash, + Prefix = this.Prefix, + Postfix = this.Postfix, + AddExtension = this.AddExtension, + ReplaceExtension = this.ReplaceExtension, + RemoveExtension = this.RemoveExtension, + Romba = this.Romba, + GameName = this.GameName, + Quotes = this.Quotes, + UseRomName = this.UseRomName, }; datHeaders[i].Parse(input, i, i, splitType, keep: true, clean: clean, remUnicode: remUnicode, descAsName: descAsName); @@ -2492,6 +2514,22 @@ namespace SabreTools.Library.DatFiles } } + /// + /// Ensure that all roms are in their own game (or at least try to ensure) + /// + private void OneRomPerGame() + { + // For each rom, we want to update the game to be "/" + Parallel.ForEach(Keys, Globals.ParallelOptions, key => + { + List items = this[key]; + for (int i = 0; i < items.Count; i++) + { + items[i].MachineName += "/" + items[i].Name; + } + }); + } + /// /// Remove all items marked for removal from the DAT /// @@ -5586,6 +5624,12 @@ namespace SabreTools.Library.DatFiles WriteStatsToScreen(recalculate: (RomCount + DiskCount == 0), baddumpCol: true, nodumpCol: true); } + // Run the one rom per game logic, if required + if (OneRom) + { + OneRomPerGame(); + } + // Bucket and dedupe according to the flag if (DedupeRoms == DedupeType.Full) { diff --git a/SabreTools.Library/DatFiles/DatHeader.cs b/SabreTools.Library/DatFiles/DatHeader.cs index 5c841158..8aacf401 100644 --- a/SabreTools.Library/DatFiles/DatHeader.cs +++ b/SabreTools.Library/DatFiles/DatHeader.cs @@ -32,6 +32,7 @@ namespace SabreTools.Library.DatFiles private ForcePacking _forcePacking; private DatFormat _datFormat; private bool _excludeOf; + private bool _oneRom; private bool _keepEmptyGames; private bool _sceneDateStrip; private DedupeType _dedupeRoms; @@ -148,6 +149,11 @@ namespace SabreTools.Library.DatFiles get { return _excludeOf; } set { _excludeOf = value; } } + public bool OneRom + { + get { return _oneRom; } + set { _oneRom = value; } + } public bool KeepEmptyGames { get { return _keepEmptyGames; } @@ -249,6 +255,7 @@ namespace SabreTools.Library.DatFiles _forcePacking = this._forcePacking, _datFormat = this._datFormat, _excludeOf = this._excludeOf, + _oneRom = this._oneRom, _keepEmptyGames = this._keepEmptyGames, _sceneDateStrip = this._sceneDateStrip, _dedupeRoms = this._dedupeRoms, diff --git a/SabreTools.Library/README.1ST b/SabreTools.Library/README.1ST index 2cb6383f..9a9d6a01 100644 --- a/SabreTools.Library/README.1ST +++ b/SabreTools.Library/README.1ST @@ -287,7 +287,12 @@ Options: -xof, --exclude-of Exclude romof, cloneof, sampleof tags If this flag is enabled, then the romof, cloneof, and sampleof tags will be omitted from the outputted DAT. - + + -orpg, --one-rom-per-game Try to ensure each rom has its own game + In some cases, it is beneficial to have every rom put into its own + output set as a subfolder of the original parent. This flag enables + outputting each rom to its own game for this purpose. + -keg, --keep-empty-games Keep originally empty sets from the input(s) Normally, any sets that are considered empty will not be included in the output, this flag allows these empty sets to be added to the @@ -840,6 +845,11 @@ Options: If this flag is enabled, then the romof, cloneof, and sampleof tags will be omitted from the outputted DAT. + -orpg, --one-rom-per-game Try to ensure each rom has its own game + In some cases, it is beneficial to have every rom put into its own + output set as a subfolder of the original parent. This flag enables + outputting each rom to its own game for this purpose. + -sds, --scene-date-strip Remove date from scene-named sets If this flag is enabled, sets with "scene" names will have the date removed from the beginning. For example "01.01.01-Game_Name-GROUP" diff --git a/SabreTools/SabreTools.Help.cs b/SabreTools/SabreTools.Help.cs index 27a2e00e..09efd6cf 100644 --- a/SabreTools/SabreTools.Help.cs +++ b/SabreTools/SabreTools.Help.cs @@ -561,6 +561,18 @@ namespace SabreTools longDescription: "If filter or exclude by game name is used, this flag will allow those filters to be checked against the romof and cloneof tags as well. This can allow for more advanced set-building, especially in arcade-based sets."); } } + private static Feature _oneRomPerGameFlag + { + get + { + return new Feature( + "one-rom-per-game", + new List() { "-orpg", "--one-rom-per-game" }, + "Try to ensure each rom has its own game", + FeatureType.Flag, + longDescription: "In some cases, it is beneficial to have every rom put into its own output set as a subfolder of the original parent. This flag enables outputting each rom to its own game for this purpose."); + } + } private static Feature _onlySameFlag { get @@ -2361,6 +2373,7 @@ Some special strings that can be used: datFromDir.AddFeature(_commentStringInput); datFromDir.AddFeature(_superdatFlag); datFromDir.AddFeature(_excludeOfFlag); + datFromDir.AddFeature(_oneRomPerGameFlag); datFromDir.AddFeature(_sceneDateStripFlag); datFromDir.AddFeature(_addBlankFilesFlag); datFromDir.AddFeature(_addDateFlag); @@ -2633,6 +2646,7 @@ The stats that are outputted are as follows: update.AddFeature(_forcenodumpStringInput); update.AddFeature(_forcepackingStringInput); update.AddFeature(_excludeOfFlag); + update.AddFeature(_oneRomPerGameFlag); update.AddFeature(_keepEmptyGamesFlag); update.AddFeature(_sceneDateStripFlag); update.AddFeature(_cleanFlag); diff --git a/SabreTools/SabreTools.cs b/SabreTools/SabreTools.cs index 8e1bdcf0..6133c594 100644 --- a/SabreTools/SabreTools.cs +++ b/SabreTools/SabreTools.cs @@ -205,7 +205,7 @@ namespace SabreTools addFileDates = true; break; case "all-stats": - Globals.Logger.User("This flag '{0}' is depreciated, pleause use {1} instead", feat.Key, String.Join(", ", _reportTypeListInput.Flags)); + Globals.Logger.User("This flag '{0}' is depreciated, please use {1} instead", feat.Key, String.Join(", ", _reportTypeListInput.Flags)); statDatFormat = StatReportFormat.All; break; case "archives-as-files": @@ -230,7 +230,7 @@ namespace SabreTools cleanGameNames = true; break; case "csv": - Globals.Logger.User("This flag '{0}' is depreciated, pleause use {1} instead", feat.Key, String.Join(", ", _reportTypeListInput.Flags)); + Globals.Logger.User("This flag '{0}' is depreciated, please use {1} instead", feat.Key, String.Join(", ", _reportTypeListInput.Flags)); statDatFormat |= StatReportFormat.CSV; break; case "dat-device-non-merged": @@ -308,7 +308,7 @@ namespace SabreTools hashOnly = true; break; case "html": - Globals.Logger.User("This flag '{0}' is depreciated, pleause use {1} instead", feat.Key, String.Join(", ", _reportTypeListInput.Flags)); + Globals.Logger.User("This flag '{0}' is depreciated, please use {1} instead", feat.Key, String.Join(", ", _reportTypeListInput.Flags)); statDatFormat |= StatReportFormat.HTML; break; case "individual": @@ -344,92 +344,95 @@ namespace SabreTools case "no-store-header": nostore = true; break; + case "one-rom-per-game": + datHeader.OneRom = true; + break; case "only-same": onlySame = true; break; // TODO: Remove all "output-*" variant flags case "output-all": - Globals.Logger.User("This flag '{0}' is depreciated, pleause use {1} instead", feat.Key, String.Join(", ", _outputTypeListInput.Flags)); + Globals.Logger.User("This flag '{0}' is depreciated, please use {1} instead", feat.Key, String.Join(", ", _outputTypeListInput.Flags)); datHeader.DatFormat |= DatFormat.ALL; break; case "output-attractmode": - Globals.Logger.User("This flag '{0}' is depreciated, pleause use {1} instead", feat.Key, String.Join(", ", _outputTypeListInput.Flags)); + Globals.Logger.User("This flag '{0}' is depreciated, please use {1} instead", feat.Key, String.Join(", ", _outputTypeListInput.Flags)); datHeader.DatFormat |= DatFormat.AttractMode; break; case "output-cmp": - Globals.Logger.User("This flag '{0}' is depreciated, pleause use {1} instead", feat.Key, String.Join(", ", _outputTypeListInput.Flags)); + Globals.Logger.User("This flag '{0}' is depreciated, please use {1} instead", feat.Key, String.Join(", ", _outputTypeListInput.Flags)); datHeader.DatFormat |= DatFormat.ClrMamePro; break; case "output-csv": - Globals.Logger.User("This flag '{0}' is depreciated, pleause use {1} instead", feat.Key, String.Join(", ", _outputTypeListInput.Flags)); + Globals.Logger.User("This flag '{0}' is depreciated, please use {1} instead", feat.Key, String.Join(", ", _outputTypeListInput.Flags)); datHeader.DatFormat |= DatFormat.CSV; break; case "output-doscenter": - Globals.Logger.User("This flag '{0}' is depreciated, pleause use {1} instead", feat.Key, String.Join(", ", _outputTypeListInput.Flags)); + Globals.Logger.User("This flag '{0}' is depreciated, please use {1} instead", feat.Key, String.Join(", ", _outputTypeListInput.Flags)); datHeader.DatFormat |= DatFormat.DOSCenter; break; case "output-listrom": - Globals.Logger.User("This flag '{0}' is depreciated, pleause use {1} instead", feat.Key, String.Join(", ", _outputTypeListInput.Flags)); + Globals.Logger.User("This flag '{0}' is depreciated, please use {1} instead", feat.Key, String.Join(", ", _outputTypeListInput.Flags)); datHeader.DatFormat |= DatFormat.Listrom; break; case "output-listxml": // TODO: Not added to readme yet - Globals.Logger.User("This flag '{0}' is depreciated, pleause use {1} instead", feat.Key, String.Join(", ", _outputTypeListInput.Flags)); + Globals.Logger.User("This flag '{0}' is depreciated, please use {1} instead", feat.Key, String.Join(", ", _outputTypeListInput.Flags)); datHeader.DatFormat |= DatFormat.Listxml; break; case "output-miss": datHeader.DatFormat |= DatFormat.MissFile; - Globals.Logger.User("This flag '{0}' is depreciated, pleause use {1} instead", feat.Key, String.Join(", ", _outputTypeListInput.Flags)); + Globals.Logger.User("This flag '{0}' is depreciated, please use {1} instead", feat.Key, String.Join(", ", _outputTypeListInput.Flags)); break; case "output-md5": datHeader.DatFormat |= DatFormat.RedumpMD5; - Globals.Logger.User("This flag '{0}' is depreciated, pleause use {1} instead", feat.Key, String.Join(", ", _outputTypeListInput.Flags)); + Globals.Logger.User("This flag '{0}' is depreciated, please use {1} instead", feat.Key, String.Join(", ", _outputTypeListInput.Flags)); break; case "output-offlinelist": datHeader.DatFormat |= DatFormat.OfflineList; - Globals.Logger.User("This flag '{0}' is depreciated, pleause use {1} instead", feat.Key, String.Join(", ", _outputTypeListInput.Flags)); + Globals.Logger.User("This flag '{0}' is depreciated, please use {1} instead", feat.Key, String.Join(", ", _outputTypeListInput.Flags)); break; case "output-romcenter": datHeader.DatFormat |= DatFormat.RomCenter; - Globals.Logger.User("This flag '{0}' is depreciated, pleause use {1} instead", feat.Key, String.Join(", ", _outputTypeListInput.Flags)); + Globals.Logger.User("This flag '{0}' is depreciated, please use {1} instead", feat.Key, String.Join(", ", _outputTypeListInput.Flags)); break; case "output-sabredat": datHeader.DatFormat |= DatFormat.SabreDat; - Globals.Logger.User("This flag '{0}' is depreciated, pleause use {1} instead", feat.Key, String.Join(", ", _outputTypeListInput.Flags)); + Globals.Logger.User("This flag '{0}' is depreciated, please use {1} instead", feat.Key, String.Join(", ", _outputTypeListInput.Flags)); break; case "output-sfv": datHeader.DatFormat |= DatFormat.RedumpSFV; - Globals.Logger.User("This flag '{0}' is depreciated, pleause use {1} instead", feat.Key, String.Join(", ", _outputTypeListInput.Flags)); + Globals.Logger.User("This flag '{0}' is depreciated, please use {1} instead", feat.Key, String.Join(", ", _outputTypeListInput.Flags)); break; case "output-sha1": datHeader.DatFormat |= DatFormat.RedumpSHA1; - Globals.Logger.User("This flag '{0}' is depreciated, pleause use {1} instead", feat.Key, String.Join(", ", _outputTypeListInput.Flags)); + Globals.Logger.User("This flag '{0}' is depreciated, please use {1} instead", feat.Key, String.Join(", ", _outputTypeListInput.Flags)); break; case "output-sha256": datHeader.DatFormat |= DatFormat.RedumpSHA256; - Globals.Logger.User("This flag '{0}' is depreciated, pleause use {1} instead", feat.Key, String.Join(", ", _outputTypeListInput.Flags)); + Globals.Logger.User("This flag '{0}' is depreciated, please use {1} instead", feat.Key, String.Join(", ", _outputTypeListInput.Flags)); break; case "output-sha384": datHeader.DatFormat |= DatFormat.RedumpSHA384; - Globals.Logger.User("This flag '{0}' is depreciated, pleause use {1} instead", feat.Key, String.Join(", ", _outputTypeListInput.Flags)); + Globals.Logger.User("This flag '{0}' is depreciated, please use {1} instead", feat.Key, String.Join(", ", _outputTypeListInput.Flags)); break; case "output-sha512": datHeader.DatFormat |= DatFormat.RedumpSHA512; - Globals.Logger.User("This flag '{0}' is depreciated, pleause use {1} instead", feat.Key, String.Join(", ", _outputTypeListInput.Flags)); + Globals.Logger.User("This flag '{0}' is depreciated, please use {1} instead", feat.Key, String.Join(", ", _outputTypeListInput.Flags)); break; case "output-softwarelist": datHeader.DatFormat |= DatFormat.SoftwareList; - Globals.Logger.User("This flag '{0}' is depreciated, pleause use {1} instead", feat.Key, String.Join(", ", _outputTypeListInput.Flags)); + Globals.Logger.User("This flag '{0}' is depreciated, please use {1} instead", feat.Key, String.Join(", ", _outputTypeListInput.Flags)); break; case "output-ssv": datHeader.DatFormat |= DatFormat.SSV; - Globals.Logger.User("This flag '{0}' is depreciated, pleause use {1} instead", feat.Key, String.Join(", ", _outputTypeListInput.Flags)); + Globals.Logger.User("This flag '{0}' is depreciated, please use {1} instead", feat.Key, String.Join(", ", _outputTypeListInput.Flags)); break; case "output-tsv": datHeader.DatFormat |= DatFormat.TSV; - Globals.Logger.User("This flag '{0}' is depreciated, pleause use {1} instead", feat.Key, String.Join(", ", _outputTypeListInput.Flags)); + Globals.Logger.User("This flag '{0}' is depreciated, please use {1} instead", feat.Key, String.Join(", ", _outputTypeListInput.Flags)); break; case "output-xml": - Globals.Logger.User("This flag '{0}' is depreciated, pleause use {1} instead", feat.Key, String.Join(", ", _outputTypeListInput.Flags)); + Globals.Logger.User("This flag '{0}' is depreciated, please use {1} instead", feat.Key, String.Join(", ", _outputTypeListInput.Flags)); // Only set this flag if the depreciated flag is not already if ((datHeader.DatFormat & DatFormat.LogiqxDepreciated) == 0) { @@ -524,7 +527,7 @@ namespace SabreTools outputFormat = OutputFormat.TapeArchive; break; case "text": - Globals.Logger.User("This flag '{0}' is depreciated, pleause use {1} instead", feat.Key, String.Join(", ", _reportTypeListInput.Flags)); + Globals.Logger.User("This flag '{0}' is depreciated, please use {1} instead", feat.Key, String.Join(", ", _reportTypeListInput.Flags)); statDatFormat |= StatReportFormat.Textfile; break; case "torrent-7zip": @@ -558,7 +561,7 @@ namespace SabreTools filter.Trim = true; break; case "tsv": - Globals.Logger.User("This flag '{0}' is depreciated, pleause use {1} instead", feat.Key, String.Join(", ", _reportTypeListInput.Flags)); + Globals.Logger.User("This flag '{0}' is depreciated, please use {1} instead", feat.Key, String.Join(", ", _reportTypeListInput.Flags)); statDatFormat |= StatReportFormat.TSV; break; case "type":