diff --git a/DATabase/DATabase.cs b/DATabase/DATabase.cs index 89fbf3ef..48f7b253 100644 --- a/DATabase/DATabase.cs +++ b/DATabase/DATabase.cs @@ -51,6 +51,7 @@ namespace SabreTools // Set all default values bool help = false, + ad = false, add = false, bare = false, convertMiss = false, @@ -109,6 +110,10 @@ namespace SabreTools case "--add": add = true; break; + case "-ad": + case "--all-diff": + ad = true; + break; case "-b": case "--bare": bare = true; @@ -435,7 +440,7 @@ namespace SabreTools // Merge, diff, and dedupe at least 2 DATs else if (merge) { - InitMergeDiff(inputs, name, desc, cat, version, author, diff, dedup, bare, forceunpack, old); + InitMergeDiff(inputs, name, desc, cat, version, author, ad, diff, dedup, bare, forceunpack, old); } logger.Close(); @@ -854,7 +859,7 @@ Make a selection: private static void MergeDiffMenu() { string selection = "", input = "", name = "", desc = "", cat = "", version = "", author = ""; - bool dedup = false, diff = false, bare = false, forceunpack = false, old = false; + bool ad = false, dedup = false, diff = false, bare = false, forceunpack = false, old = false; while (selection.ToLowerInvariant() != "b") { Console.Clear(); @@ -869,12 +874,13 @@ Make a selection: 4) Category" + (cat != "" ? ":\t" + cat : "") + @" 5) Version" + (version != "" ? ":\t" + version : "") + @" 6) Author" + (author != "" ? ":\t" + author : "") + @" - 7) " + (dedup ? "Don't dedup files in output" : "Dedup files in output") + @" - 8) " + (diff ? "Only merge the input files" : "Diff the input files") + @" - 9) " + (bare ? "Don't append the date to the name" : "Append the date to the name") + @" - 10) " + (forceunpack ? "Remove 'forcepacking=\"unzip\"' from output" : "Add 'forcepacking=\"unzip\"' to output") + @" - 11) " + (old ? "Enable XML output" : "Enable ClrMamePro output") + @" - 12) Merge the DATs + 7) " + (ad ? "Only output normal diff" : "Output all diff variants") + @" + 8) " + (dedup ? "Don't dedup files in output" : "Dedup files in output") + @" + 9) " + (diff ? "Only merge the input files" : "Diff the input files") + @" + 10) " + (bare ? "Don't append the date to the name" : "Append the date to the name") + @" + 11) " + (forceunpack ? "Remove 'forcepacking=\"unzip\"' from output" : "Add 'forcepacking=\"unzip\"' to output") + @" + 12) " + (old ? "Enable XML output" : "Enable ClrMamePro output") + @" + 13) Merge the DATs B) Go back to the previous menu "); Console.Write("Enter selection: "); @@ -912,24 +918,27 @@ Make a selection: author = Console.ReadLine(); break; case "7": - dedup = !dedup; + ad = !ad; break; case "8": - diff = !diff; + dedup = !dedup; break; case "9": - bare = !bare; + diff = !diff; break; case "10": - forceunpack = !forceunpack; + bare = !bare; break; case "11": - old = !old; + forceunpack = !forceunpack; break; case "12": + old = !old; + break; + case "13": Console.Clear(); List inputs = new List(input.Split(';')); - InitMergeDiff(inputs, name, desc, cat, version, author, diff, dedup, bare, forceunpack, old); + InitMergeDiff(inputs, name, desc, cat, version, author, ad, diff, dedup, bare, forceunpack, old); Console.Write("\nPress any key to continue..."); Console.ReadKey(); break; @@ -1364,7 +1373,7 @@ Make a selection: /// True if the date should be omitted from the DAT, false otherwise /// True if the forcepacking="unzip" tag is to be added, false otherwise /// True if a old-style DAT should be output, false otherwise - private static void InitMergeDiff(List inputs, string name, string desc, string cat, string version, string author, bool diff, bool dedup, bool bare, bool forceunpack, bool old) + private static void InitMergeDiff(List inputs, string name, string desc, string cat, string version, string author, bool ad, bool diff, bool dedup, bool bare, bool forceunpack, bool old) { // Make sure there are no folders in inputs List newInputs = new List(); @@ -1383,7 +1392,7 @@ Make a selection: } } - MergeDiff md = new MergeDiff(newInputs, name, desc, cat, version, author, diff, dedup, bare, forceunpack, old, logger); + MergeDiff md = new MergeDiff(newInputs, name, desc, cat, version, author, ad, diff, dedup, bare, forceunpack, old, logger); md.Process(); } diff --git a/DATabase/MergeDiff.cs b/DATabase/MergeDiff.cs index a7f72e60..30cf5d50 100644 --- a/DATabase/MergeDiff.cs +++ b/DATabase/MergeDiff.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.IO; using SabreTools.Helper; @@ -11,6 +12,7 @@ namespace SabreTools private List _inputs; // User specified flags + private bool _ad; private bool _diff; private bool _dedup; private bool _bare; @@ -37,6 +39,7 @@ namespace SabreTools /// Category for the DAT /// Version of the DAT /// Author of the DAT + /// True if all diff variants should be outputted, false otherwise /// True if a DiffDat of all inputs is wanted, false otherwise /// True if the outputted file should remove duplicates, false otherwise /// True if the date should be omitted from the DAT, false otherwise @@ -44,7 +47,7 @@ namespace SabreTools /// True if a old-style DAT should be output, false otherwise /// Logger object for console and file output public MergeDiff(List inputs, string name, string desc, string cat, string version, string author, - bool diff, bool dedup, bool bare, bool forceunpack, bool old, Logger logger) + bool ad, bool diff, bool dedup, bool bare, bool forceunpack, bool old, Logger logger) { _inputs = inputs; _name = name; @@ -52,6 +55,7 @@ namespace SabreTools _cat = cat; _version = version; _author = author; + _ad = ad; _diff = diff; _dedup = dedup; _bare = bare; @@ -78,6 +82,8 @@ namespace SabreTools } List A = new List(); + List X = new List(); + foreach (string input in _inputs) { _logger.Log("Adding DAT: " + input); @@ -90,6 +96,56 @@ namespace SabreTools { A.AddRange(B); } + + // If we're in all-diff mode, get a master merged DAT to compare against + if (_ad) + { + X.AddRange(B); + } + } + + // If we're in all diff mode, diff against every DAT and output accordingly + if (_ad) + { + foreach (string input in _inputs) + { + List B = RomManipulation.Parse(input, 0, 0, _logger); + List C = RomManipulation.DiffOnlyInA(B, X); + List D = RomManipulation.DiffInAB(B, X); + + if (_dedup) + { + C = RomManipulation.Merge(C); + D = RomManipulation.Merge(D); + } + + if (_name == "") + { + _name = (_diff ? "diffdat" : "mergedat") + (_dedup ? "-merged" : ""); + } + if (_desc == "") + { + _desc = (_diff ? "diffdat" : "mergedat") + (_dedup ? "-merged" : ""); + if (!_bare) + { + _desc += " (" + _date + ")"; + } + } + if (_cat == "" && _diff) + { + _cat = "DiffDAT"; + } + if (_author == "") + { + _author = "SabreTools"; + } + + string realname = Path.GetFileNameWithoutExtension(input); + + // Now write the files out + Output.WriteToDat(_name + "-" + realname + "-inall", _desc + "-" + realname + "-inall", _version, _date, _cat, _author, _forceunpack, _old, "", C, _logger); + Output.WriteToDat(_name + "-" + realname + "-only", _desc + "-" + realname + "-only", _version, _date, _cat, _author, _forceunpack, _old, "", D, _logger); + } } // If we want a merged list, send it for merging before outputting diff --git a/SabreHelper/Build.cs b/SabreHelper/Build.cs index d04f54aa..8378cfdd 100644 --- a/SabreHelper/Build.cs +++ b/SabreHelper/Build.cs @@ -118,6 +118,7 @@ Options: -lso, --list-sources List all sources (id <= name) -lsy, --list-systems List all systems (id <= name) -m, --merge Merge two or more DATs + -ad, --all-diff Enable output of all diff variants -di, --diff Switch to diffdat mode -dd, --dedup Enable deduping in the created DAT -b, --bare Don't include date in file name diff --git a/SabreHelper/RomManipulation.cs b/SabreHelper/RomManipulation.cs index 8b712132..da2b79a5 100644 --- a/SabreHelper/RomManipulation.cs +++ b/SabreHelper/RomManipulation.cs @@ -451,5 +451,35 @@ namespace SabreTools.Helper List CString = AString.Except(BString).Union(BString.Except(AString)).ToList(); return Output.StringToRomData(CString); } + + /// + /// Get all RomData objects that are in A but not in B + /// + /// First RomData list + /// Second RomData list + /// Any rom that's only in the first list + /// Adapted from http://stackoverflow.com/questions/5620266/the-opposite-of-intersect + public static List DiffOnlyInA(List A, List B) + { + List AString = Output.RomDataToString(A); + List BString = Output.RomDataToString(B); + List CString = AString.Except(BString).ToList(); + return Output.StringToRomData(CString); + } + + /// + /// Get all RomData objects that are in A and B + /// + /// First RomData list + /// Second RomData list + /// Any rom that's in both lists + /// Adapted from http://stackoverflow.com/questions/5620266/the-opposite-of-intersect + public static List DiffInAB(List A, List B) + { + List AString = Output.RomDataToString(A); + List BString = Output.RomDataToString(B); + List CString = AString.Union(BString).Except(AString.Except(BString).Union(BString.Except(AString))).ToList(); + return Output.StringToRomData(CString); + } } }