[SabreTools, DatFile, DatHeader] Add one-rom-per-game

This commit is contained in:
Matt Nadareski
2018-03-20 15:10:43 -07:00
parent 72830b5d98
commit 74c92d2ef1
5 changed files with 120 additions and 42 deletions

View File

@@ -451,6 +451,27 @@ namespace SabreTools.Library.DatFiles
_datHeader.ExcludeOf = value; _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 public bool KeepEmptyGames
{ {
get get
@@ -1721,23 +1742,24 @@ namespace SabreTools.Library.DatFiles
Globals.Logger.User("Adding DAT: {0}", input.Split('¬')[0]); Globals.Logger.User("Adding DAT: {0}", input.Split('¬')[0]);
datHeaders[i] = new DatFile() datHeaders[i] = new DatFile()
{ {
DatFormat = (DatFormat != 0 ? DatFormat : 0), DatFormat = (this.DatFormat != 0 ? this.DatFormat : 0),
// Filtering that needs to be copied over // Filtering that needs to be copied over
ExcludeOf = ExcludeOf, ExcludeOf = this.ExcludeOf,
KeepEmptyGames = KeepEmptyGames, OneRom = this.OneRom,
SceneDateStrip = SceneDateStrip, KeepEmptyGames = this.KeepEmptyGames,
DedupeRoms = DedupeRoms, SceneDateStrip = this.SceneDateStrip,
StripHash = StripHash, DedupeRoms = this.DedupeRoms,
Prefix = Prefix, StripHash = this.StripHash,
Postfix = Postfix, Prefix = this.Prefix,
AddExtension = AddExtension, Postfix = this.Postfix,
ReplaceExtension = ReplaceExtension, AddExtension = this.AddExtension,
RemoveExtension = RemoveExtension, ReplaceExtension = this.ReplaceExtension,
Romba = Romba, RemoveExtension = this.RemoveExtension,
GameName = GameName, Romba = this.Romba,
Quotes = Quotes, GameName = this.GameName,
UseRomName = UseRomName, Quotes = this.Quotes,
UseRomName = this.UseRomName,
}; };
datHeaders[i].Parse(input, i, i, splitType, keep: true, clean: clean, remUnicode: remUnicode, descAsName: descAsName); datHeaders[i].Parse(input, i, i, splitType, keep: true, clean: clean, remUnicode: remUnicode, descAsName: descAsName);
@@ -2492,6 +2514,22 @@ namespace SabreTools.Library.DatFiles
} }
} }
/// <summary>
/// Ensure that all roms are in their own game (or at least try to ensure)
/// </summary>
private void OneRomPerGame()
{
// For each rom, we want to update the game to be "<game name>/<rom name>"
Parallel.ForEach(Keys, Globals.ParallelOptions, key =>
{
List<DatItem> items = this[key];
for (int i = 0; i < items.Count; i++)
{
items[i].MachineName += "/" + items[i].Name;
}
});
}
/// <summary> /// <summary>
/// Remove all items marked for removal from the DAT /// Remove all items marked for removal from the DAT
/// </summary> /// </summary>
@@ -5586,6 +5624,12 @@ namespace SabreTools.Library.DatFiles
WriteStatsToScreen(recalculate: (RomCount + DiskCount == 0), baddumpCol: true, nodumpCol: true); 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 // Bucket and dedupe according to the flag
if (DedupeRoms == DedupeType.Full) if (DedupeRoms == DedupeType.Full)
{ {

View File

@@ -32,6 +32,7 @@ namespace SabreTools.Library.DatFiles
private ForcePacking _forcePacking; private ForcePacking _forcePacking;
private DatFormat _datFormat; private DatFormat _datFormat;
private bool _excludeOf; private bool _excludeOf;
private bool _oneRom;
private bool _keepEmptyGames; private bool _keepEmptyGames;
private bool _sceneDateStrip; private bool _sceneDateStrip;
private DedupeType _dedupeRoms; private DedupeType _dedupeRoms;
@@ -148,6 +149,11 @@ namespace SabreTools.Library.DatFiles
get { return _excludeOf; } get { return _excludeOf; }
set { _excludeOf = value; } set { _excludeOf = value; }
} }
public bool OneRom
{
get { return _oneRom; }
set { _oneRom = value; }
}
public bool KeepEmptyGames public bool KeepEmptyGames
{ {
get { return _keepEmptyGames; } get { return _keepEmptyGames; }
@@ -249,6 +255,7 @@ namespace SabreTools.Library.DatFiles
_forcePacking = this._forcePacking, _forcePacking = this._forcePacking,
_datFormat = this._datFormat, _datFormat = this._datFormat,
_excludeOf = this._excludeOf, _excludeOf = this._excludeOf,
_oneRom = this._oneRom,
_keepEmptyGames = this._keepEmptyGames, _keepEmptyGames = this._keepEmptyGames,
_sceneDateStrip = this._sceneDateStrip, _sceneDateStrip = this._sceneDateStrip,
_dedupeRoms = this._dedupeRoms, _dedupeRoms = this._dedupeRoms,

View File

@@ -288,6 +288,11 @@ Options:
If this flag is enabled, then the romof, cloneof, and sampleof tags If this flag is enabled, then the romof, cloneof, and sampleof tags
will be omitted from the outputted DAT. 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) -keg, --keep-empty-games Keep originally empty sets from the input(s)
Normally, any sets that are considered empty will not be included in 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 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 If this flag is enabled, then the romof, cloneof, and sampleof tags
will be omitted from the outputted DAT. 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 -sds, --scene-date-strip Remove date from scene-named sets
If this flag is enabled, sets with "scene" names will have the date 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" removed from the beginning. For example "01.01.01-Game_Name-GROUP"

View File

@@ -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."); 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<string>() { "-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 private static Feature _onlySameFlag
{ {
get get
@@ -2361,6 +2373,7 @@ Some special strings that can be used:
datFromDir.AddFeature(_commentStringInput); datFromDir.AddFeature(_commentStringInput);
datFromDir.AddFeature(_superdatFlag); datFromDir.AddFeature(_superdatFlag);
datFromDir.AddFeature(_excludeOfFlag); datFromDir.AddFeature(_excludeOfFlag);
datFromDir.AddFeature(_oneRomPerGameFlag);
datFromDir.AddFeature(_sceneDateStripFlag); datFromDir.AddFeature(_sceneDateStripFlag);
datFromDir.AddFeature(_addBlankFilesFlag); datFromDir.AddFeature(_addBlankFilesFlag);
datFromDir.AddFeature(_addDateFlag); datFromDir.AddFeature(_addDateFlag);
@@ -2633,6 +2646,7 @@ The stats that are outputted are as follows:
update.AddFeature(_forcenodumpStringInput); update.AddFeature(_forcenodumpStringInput);
update.AddFeature(_forcepackingStringInput); update.AddFeature(_forcepackingStringInput);
update.AddFeature(_excludeOfFlag); update.AddFeature(_excludeOfFlag);
update.AddFeature(_oneRomPerGameFlag);
update.AddFeature(_keepEmptyGamesFlag); update.AddFeature(_keepEmptyGamesFlag);
update.AddFeature(_sceneDateStripFlag); update.AddFeature(_sceneDateStripFlag);
update.AddFeature(_cleanFlag); update.AddFeature(_cleanFlag);

View File

@@ -205,7 +205,7 @@ namespace SabreTools
addFileDates = true; addFileDates = true;
break; break;
case "all-stats": 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; statDatFormat = StatReportFormat.All;
break; break;
case "archives-as-files": case "archives-as-files":
@@ -230,7 +230,7 @@ namespace SabreTools
cleanGameNames = true; cleanGameNames = true;
break; break;
case "csv": 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; statDatFormat |= StatReportFormat.CSV;
break; break;
case "dat-device-non-merged": case "dat-device-non-merged":
@@ -308,7 +308,7 @@ namespace SabreTools
hashOnly = true; hashOnly = true;
break; break;
case "html": 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; statDatFormat |= StatReportFormat.HTML;
break; break;
case "individual": case "individual":
@@ -344,92 +344,95 @@ namespace SabreTools
case "no-store-header": case "no-store-header":
nostore = true; nostore = true;
break; break;
case "one-rom-per-game":
datHeader.OneRom = true;
break;
case "only-same": case "only-same":
onlySame = true; onlySame = true;
break; break;
// TODO: Remove all "output-*" variant flags // TODO: Remove all "output-*" variant flags
case "output-all": 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; datHeader.DatFormat |= DatFormat.ALL;
break; break;
case "output-attractmode": 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; datHeader.DatFormat |= DatFormat.AttractMode;
break; break;
case "output-cmp": 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; datHeader.DatFormat |= DatFormat.ClrMamePro;
break; break;
case "output-csv": 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; datHeader.DatFormat |= DatFormat.CSV;
break; break;
case "output-doscenter": 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; datHeader.DatFormat |= DatFormat.DOSCenter;
break; break;
case "output-listrom": 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; datHeader.DatFormat |= DatFormat.Listrom;
break; break;
case "output-listxml": // TODO: Not added to readme yet 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; datHeader.DatFormat |= DatFormat.Listxml;
break; break;
case "output-miss": case "output-miss":
datHeader.DatFormat |= DatFormat.MissFile; 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; break;
case "output-md5": case "output-md5":
datHeader.DatFormat |= DatFormat.RedumpMD5; 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; break;
case "output-offlinelist": case "output-offlinelist":
datHeader.DatFormat |= DatFormat.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; break;
case "output-romcenter": case "output-romcenter":
datHeader.DatFormat |= DatFormat.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; break;
case "output-sabredat": case "output-sabredat":
datHeader.DatFormat |= DatFormat.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; break;
case "output-sfv": case "output-sfv":
datHeader.DatFormat |= DatFormat.RedumpSFV; 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; break;
case "output-sha1": case "output-sha1":
datHeader.DatFormat |= DatFormat.RedumpSHA1; 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; break;
case "output-sha256": case "output-sha256":
datHeader.DatFormat |= DatFormat.RedumpSHA256; 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; break;
case "output-sha384": case "output-sha384":
datHeader.DatFormat |= DatFormat.RedumpSHA384; 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; break;
case "output-sha512": case "output-sha512":
datHeader.DatFormat |= DatFormat.RedumpSHA512; 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; break;
case "output-softwarelist": case "output-softwarelist":
datHeader.DatFormat |= DatFormat.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; break;
case "output-ssv": case "output-ssv":
datHeader.DatFormat |= DatFormat.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; break;
case "output-tsv": case "output-tsv":
datHeader.DatFormat |= DatFormat.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; break;
case "output-xml": 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 // Only set this flag if the depreciated flag is not already
if ((datHeader.DatFormat & DatFormat.LogiqxDepreciated) == 0) if ((datHeader.DatFormat & DatFormat.LogiqxDepreciated) == 0)
{ {
@@ -524,7 +527,7 @@ namespace SabreTools
outputFormat = OutputFormat.TapeArchive; outputFormat = OutputFormat.TapeArchive;
break; break;
case "text": 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; statDatFormat |= StatReportFormat.Textfile;
break; break;
case "torrent-7zip": case "torrent-7zip":
@@ -558,7 +561,7 @@ namespace SabreTools
filter.Trim = true; filter.Trim = true;
break; break;
case "tsv": 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; statDatFormat |= StatReportFormat.TSV;
break; break;
case "type": case "type":