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":