diff --git a/RombaSharp/RombaSharp.Inits.cs b/RombaSharp/RombaSharp.Inits.cs index 1c87a861..38c96fe9 100644 --- a/RombaSharp/RombaSharp.Inits.cs +++ b/RombaSharp/RombaSharp.Inits.cs @@ -354,7 +354,7 @@ namespace RombaSharp // Now run the diff on the inputs datfile.DetermineUpdateType(dats, basedats, outdat, UpdateMode.DiffAgainst, false /* inplace */, false /* skip */, false /* clean */, false /* remUnicode */, false /* descAsName */, new Filter(), SplitType.None, - ReplaceMode.None, false /* onlySame */); + new List(), false /* onlySame */); } /// @@ -432,7 +432,7 @@ namespace RombaSharp // Now run the diff on the inputs datfile.DetermineUpdateType(dats, basedats, outdat, UpdateMode.DiffAgainst, false /* inplace */, false /* skip */, false /* clean */, false /* remUnicode */, false /* descAsName */, new Filter(), SplitType.None, - ReplaceMode.None, false /* onlySame */); + new List(), false /* onlySame */); } /// diff --git a/SabreTools.Library/DatFiles/ClrMamePro.cs b/SabreTools.Library/DatFiles/ClrMamePro.cs index 63830265..3250f534 100644 --- a/SabreTools.Library/DatFiles/ClrMamePro.cs +++ b/SabreTools.Library/DatFiles/ClrMamePro.cs @@ -922,7 +922,7 @@ namespace SabreTools.Library.DatFiles break; case ItemType.BiosSet: state += "\tbiosset ( name\"" + (!ExcludeFields[(int)Field.Name] ? rom.Name : "") + "\"" - + (!ExcludeFields[(int)Field.Description] && !String.IsNullOrWhiteSpace(((BiosSet)rom).Description) ? " description \"" + ((BiosSet)rom).Description + "\"" : "") + + (!ExcludeFields[(int)Field.BiosDescription] && !String.IsNullOrWhiteSpace(((BiosSet)rom).Description) ? " description \"" + ((BiosSet)rom).Description + "\"" : "") + (!ExcludeFields[(int)Field.Default] && ((BiosSet)rom).Default != null ? "default " + ((BiosSet)rom).Default.ToString().ToLowerInvariant() : "") diff --git a/SabreTools.Library/DatFiles/DatFile.cs b/SabreTools.Library/DatFiles/DatFile.cs index 281a9476..9daf6d9d 100644 --- a/SabreTools.Library/DatFiles/DatFile.cs +++ b/SabreTools.Library/DatFiles/DatFile.cs @@ -1487,10 +1487,10 @@ namespace SabreTools.Library.DatFiles /// True to use game descriptions as the names, false otherwise (default) /// Filter object to be passed to the DatItem level /// Type of the split that should be performed (split, merged, fully merged) - /// ReplaceMode representing what should be updated [only for base replacement] + /// List of Fields representing what should be updated [only for base replacement] /// True if descriptions should only be replaced if the game name is the same, false otherwise [only for base replacement] public void DetermineUpdateType(List inputPaths, List basePaths, string outDir, UpdateMode updateMode, bool inplace, bool skip, - bool clean, bool remUnicode, bool descAsName, Filter filter, SplitType splitType, ReplaceMode replaceMode, bool onlySame) + bool clean, bool remUnicode, bool descAsName, Filter filter, SplitType splitType, List updateFields, bool onlySame) { // Ensure we only have files in the inputs List inputFileNames = Utilities.GetOnlyFilesFromInputs(inputPaths, appendparent: true); @@ -1550,7 +1550,7 @@ namespace SabreTools.Library.DatFiles { // Populate the combined data PopulateUserData(baseFileNames, inplace, clean, remUnicode, descAsName, outDir, filter, splitType); - BaseReplace(inputFileNames, outDir, inplace, clean, remUnicode, descAsName, filter, splitType, replaceMode, onlySame); + BaseReplace(inputFileNames, outDir, inplace, clean, remUnicode, descAsName, filter, splitType, updateFields, onlySame); } return; @@ -1642,11 +1642,66 @@ namespace SabreTools.Library.DatFiles /// True to allow SL DATs to have game names used instead of descriptions, false otherwise (default) /// Filter object to be passed to the DatItem level /// Type of the split that should be performed (split, merged, fully merged) - /// ReplaceMode representing what should be updated + /// List of Fields representing what should be updated [only for base replacement] /// True if descriptions should only be replaced if the game name is the same, false otherwise public void BaseReplace(List inputFileNames, string outDir, bool inplace, bool clean, bool remUnicode, - bool descAsName, Filter filter, SplitType splitType, ReplaceMode replaceMode, bool onlySame) + bool descAsName, Filter filter, SplitType splitType, List updateFields, bool onlySame) { + // Fields unique to a DatItem + List datItemFields = new List() + { + Field.Name, + Field.PartName, + Field.PartInterface, + Field.Features, + Field.AreaName, + Field.AreaSize, + Field.BiosDescription, + Field.Default, + Field.Language, + Field.Date, + Field.Bios, + Field.Size, + Field.Offset, + Field.Merge, + Field.Region, + Field.Index, + Field.Writable, + Field.Optional, + Field.Status, + + Field.CRC, + Field.MD5, + Field.RIPEMD160, + Field.SHA1, + Field.SHA256, + Field.SHA384, + Field.SHA512, + }; + + // Fields unique to a Machine + List machineFields = new List() + { + Field.MachineName, + Field.Comment, + Field.Description, + Field.Year, + Field.Manufacturer, + Field.Publisher, + Field.RomOf, + Field.CloneOf, + Field.SampleOf, + Field.Supported, + Field.SourceFile, + Field.Runnable, + Field.Board, + Field.RebuildTo, + Field.Devices, + Field.SlotOptions, + Field.Infos, + Field.MachineType, + }; + // We want to try to replace each item in each input DAT from the base foreach (string path in inputFileNames) { @@ -1677,9 +1732,8 @@ namespace SabreTools.Library.DatFiles intDat.Parse(path, 1, 1, keep: true, clean: clean, remUnicode: remUnicode, descAsName: descAsName); filter.FilterDatFile(intDat); - // If we are matching based on hashes of any sort - if ((replaceMode & ReplaceMode.ItemName) != 0 - || (replaceMode & ReplaceMode.Hash) != 0) + // If we are matching based on DatItem fields of any sort + if (updateFields.Intersect(datItemFields).Any()) { // For comparison's sake, we want to use CRC as the base ordering BucketBy(SortedBy.CRC, DedupeType.Full); @@ -1694,90 +1748,291 @@ namespace SabreTools.Library.DatFiles foreach (DatItem datItem in datItems) { // If we have something other than a Rom or Disk, then this doesn't do anything + // TODO: Make this do something if (datItem.ItemType != ItemType.Disk && datItem.ItemType != ItemType.Rom) { - newDatItems.Add((DatItem)datItem.Clone()); + newDatItems.Add(datItem.Clone() as DatItem); continue; } List dupes = datItem.GetDuplicates(this, sorted: true); - DatItem newDatItem = (DatItem)datItem.Clone(); + DatItem newDatItem = datItem.Clone() as DatItem; + + // Cast versions of the new DatItem for use below + var archive = newDatItem as Archive; + var biosSet = newDatItem as BiosSet; + var blank = newDatItem as Blank; + var disk = newDatItem as Disk; + var release = newDatItem as Release; + var rom = newDatItem as Rom; + var sample = newDatItem as Sample; if (dupes.Count > 0) { - // If we're updating names, replace using the first found name - if ((replaceMode & ReplaceMode.ItemName) != 0) + // Get the first duplicate for grabbing information from + var firstDupe = dupes.First(); + var archiveDupe = firstDupe as Archive; + var biosSetDupe = firstDupe as BiosSet; + var blankDupe = firstDupe as Blank; + var diskDupe = firstDupe as Disk; + var releaseDupe = firstDupe as Release; + var romDupe = firstDupe as Rom; + var sampleDupe = firstDupe as Sample; + + #region Non-hash fields + + if (updateFields.Contains(Field.Name)) + newDatItem.Name = firstDupe.Name; + + if (updateFields.Contains(Field.PartName)) + newDatItem.PartName = firstDupe.PartName; + + if (updateFields.Contains(Field.PartInterface)) + newDatItem.PartInterface = firstDupe.PartInterface; + + if (updateFields.Contains(Field.Features)) + newDatItem.Features = firstDupe.Features; + + if (updateFields.Contains(Field.AreaName)) + newDatItem.AreaName = firstDupe.AreaName; + + if (updateFields.Contains(Field.AreaSize)) + newDatItem.AreaSize = firstDupe.AreaSize; + + if (updateFields.Contains(Field.BiosDescription)) { - newDatItem.Name = dupes[0].Name; + if (newDatItem.ItemType == ItemType.BiosSet) + biosSet.Description = biosSetDupe.Description; } - // If we're updating hashes, only replace if the current item doesn't have them - if ((replaceMode & ReplaceMode.Hash) != 0) + if (updateFields.Contains(Field.Default)) + { + if (newDatItem.ItemType == ItemType.BiosSet) + biosSet.Default = biosSetDupe.Default; + + else if (newDatItem.ItemType == ItemType.Release) + release.Default = releaseDupe.Default; + } + + if (updateFields.Contains(Field.Language)) + { + if (newDatItem.ItemType == ItemType.Release) + release.Language = releaseDupe.Language; + } + + if (updateFields.Contains(Field.Date)) + { + if (newDatItem.ItemType == ItemType.Release) + release.Date = releaseDupe.Date; + + else if (newDatItem.ItemType == ItemType.Rom) + rom.Date = romDupe.Date; + } + + if (updateFields.Contains(Field.Bios)) + { + if (newDatItem.ItemType == ItemType.Rom) + rom.Bios = romDupe.Bios; + } + + if (updateFields.Contains(Field.Size)) + { + if (newDatItem.ItemType == ItemType.Rom) + rom.Size = romDupe.Size; + } + + if (updateFields.Contains(Field.Offset)) + { + if (newDatItem.ItemType == ItemType.Rom) + rom.Offset = romDupe.Offset; + } + + if (updateFields.Contains(Field.Merge)) + { + if (newDatItem.ItemType == ItemType.Disk) + disk.MergeTag = diskDupe.MergeTag; + + else if (newDatItem.ItemType == ItemType.Rom) + rom.MergeTag = romDupe.MergeTag; + } + + if (updateFields.Contains(Field.Region)) + { + if (newDatItem.ItemType == ItemType.Disk) + disk.Region = diskDupe.Region; + + else if (newDatItem.ItemType == ItemType.Release) + release.Region = releaseDupe.Region; + + else if (newDatItem.ItemType == ItemType.Rom) + rom.Region = romDupe.Region; + } + + if (updateFields.Contains(Field.Index)) + { + if (newDatItem.ItemType == ItemType.Disk) + disk.Index = diskDupe.Index; + } + + if (updateFields.Contains(Field.Writable)) + { + if (newDatItem.ItemType == ItemType.Disk) + disk.Writable = diskDupe.Writable; + } + + if (updateFields.Contains(Field.Optional)) + { + if (newDatItem.ItemType == ItemType.Disk) + disk.Optional = diskDupe.Optional; + + else if (newDatItem.ItemType == ItemType.Rom) + rom.Optional = romDupe.Optional; + } + + if (updateFields.Contains(Field.Status)) + { + if (newDatItem.ItemType == ItemType.Disk) + disk.ItemStatus = diskDupe.ItemStatus; + + else if (newDatItem.ItemType == ItemType.Rom) + rom.ItemStatus = romDupe.ItemStatus; + } + + #endregion + + #region Hash fields + + if (updateFields.Contains(Field.CRC)) { if (newDatItem.ItemType == ItemType.Rom) { - Rom newRomItem = (Rom)newDatItem; - if (String.IsNullOrEmpty(newRomItem.CRC) && !String.IsNullOrEmpty(((Rom)dupes[0]).CRC)) - { - newRomItem.CRC = ((Rom)dupes[0]).CRC; - } - if (String.IsNullOrEmpty(newRomItem.MD5) && !String.IsNullOrEmpty(((Rom)dupes[0]).MD5)) - { - newRomItem.MD5 = ((Rom)dupes[0]).MD5; - } - if (String.IsNullOrEmpty(newRomItem.RIPEMD160) && !String.IsNullOrEmpty(((Rom)dupes[0]).RIPEMD160)) - { - newRomItem.RIPEMD160 = ((Rom)dupes[0]).RIPEMD160; - } - if (String.IsNullOrEmpty(newRomItem.SHA1) && !String.IsNullOrEmpty(((Rom)dupes[0]).SHA1)) - { - newRomItem.SHA1 = ((Rom)dupes[0]).SHA1; - } - if (String.IsNullOrEmpty(newRomItem.SHA256) && !String.IsNullOrEmpty(((Rom)dupes[0]).SHA256)) - { - newRomItem.SHA256 = ((Rom)dupes[0]).SHA256; - } - if (String.IsNullOrEmpty(newRomItem.SHA384) && !String.IsNullOrEmpty(((Rom)dupes[0]).SHA384)) - { - newRomItem.SHA384 = ((Rom)dupes[0]).SHA384; - } - if (String.IsNullOrEmpty(newRomItem.SHA512) && !String.IsNullOrEmpty(((Rom)dupes[0]).SHA512)) - { - newRomItem.SHA512 = ((Rom)dupes[0]).SHA512; - } - - newDatItem = (Rom)newRomItem.Clone(); + if (string.IsNullOrEmpty(rom.CRC) && !string.IsNullOrEmpty(romDupe.CRC)) + rom.CRC = romDupe.CRC; } - else if (newDatItem.ItemType == ItemType.Disk) + } + + if (updateFields.Contains(Field.MD5)) + { + if (newDatItem.ItemType == ItemType.Disk) { - Disk newDiskItem = (Disk)newDatItem; - if (String.IsNullOrEmpty(newDiskItem.MD5) && !String.IsNullOrEmpty(((Disk)dupes[0]).MD5)) - { - newDiskItem.MD5 = ((Disk)dupes[0]).MD5; - } - if (String.IsNullOrEmpty(newDiskItem.RIPEMD160) && !String.IsNullOrEmpty(((Disk)dupes[0]).RIPEMD160)) - { - newDiskItem.RIPEMD160 = ((Disk)dupes[0]).RIPEMD160; - } - if (String.IsNullOrEmpty(newDiskItem.SHA1) && !String.IsNullOrEmpty(((Disk)dupes[0]).SHA1)) - { - newDiskItem.SHA1 = ((Disk)dupes[0]).SHA1; - } - if (String.IsNullOrEmpty(newDiskItem.SHA256) && !String.IsNullOrEmpty(((Disk)dupes[0]).SHA256)) - { - newDiskItem.SHA256 = ((Disk)dupes[0]).SHA256; - } - if (String.IsNullOrEmpty(newDiskItem.SHA384) && !String.IsNullOrEmpty(((Disk)dupes[0]).SHA384)) - { - newDiskItem.SHA384 = ((Disk)dupes[0]).SHA384; - } - if (String.IsNullOrEmpty(newDiskItem.SHA512) && !String.IsNullOrEmpty(((Disk)dupes[0]).SHA512)) - { - newDiskItem.SHA512 = ((Disk)dupes[0]).SHA512; - } - - newDatItem = (Disk)newDiskItem.Clone(); + if (string.IsNullOrEmpty(disk.MD5) && !string.IsNullOrEmpty(diskDupe.MD5)) + disk.MD5 = diskDupe.MD5; } + + if (newDatItem.ItemType == ItemType.Rom) + { + if (string.IsNullOrEmpty(rom.MD5) && !string.IsNullOrEmpty(romDupe.MD5)) + rom.MD5 = romDupe.MD5; + } + } + + if (updateFields.Contains(Field.RIPEMD160)) + { + if (newDatItem.ItemType == ItemType.Disk) + { + if (string.IsNullOrEmpty(disk.RIPEMD160) && !string.IsNullOrEmpty(diskDupe.RIPEMD160)) + disk.RIPEMD160 = diskDupe.RIPEMD160; + } + + if (newDatItem.ItemType == ItemType.Rom) + { + if (string.IsNullOrEmpty(rom.RIPEMD160) && !string.IsNullOrEmpty(romDupe.RIPEMD160)) + rom.RIPEMD160 = romDupe.RIPEMD160; + } + } + + if (updateFields.Contains(Field.SHA1)) + { + if (newDatItem.ItemType == ItemType.Disk) + { + if (string.IsNullOrEmpty(disk.SHA1) && !string.IsNullOrEmpty(diskDupe.SHA1)) + disk.SHA1 = diskDupe.SHA1; + } + + if (newDatItem.ItemType == ItemType.Rom) + { + if (string.IsNullOrEmpty(rom.SHA1) && !string.IsNullOrEmpty(romDupe.SHA1)) + rom.SHA1 = romDupe.SHA1; + } + } + + if (updateFields.Contains(Field.SHA256)) + { + if (newDatItem.ItemType == ItemType.Disk) + { + if (string.IsNullOrEmpty(disk.SHA256) && !string.IsNullOrEmpty(diskDupe.SHA256)) + disk.SHA256 = diskDupe.SHA256; + } + + if (newDatItem.ItemType == ItemType.Rom) + { + if (string.IsNullOrEmpty(rom.SHA256) && !string.IsNullOrEmpty(romDupe.SHA256)) + rom.SHA256 = romDupe.SHA256; + } + } + + if (updateFields.Contains(Field.SHA384)) + { + if (newDatItem.ItemType == ItemType.Disk) + { + if (string.IsNullOrEmpty(disk.SHA384) && !string.IsNullOrEmpty(diskDupe.SHA384)) + disk.SHA384 = diskDupe.SHA384; + } + + if (newDatItem.ItemType == ItemType.Rom) + { + if (string.IsNullOrEmpty(rom.SHA384) && !string.IsNullOrEmpty(romDupe.SHA384)) + rom.SHA384 = romDupe.SHA384; + } + } + + if (updateFields.Contains(Field.SHA512)) + { + if (newDatItem.ItemType == ItemType.Disk) + { + if (string.IsNullOrEmpty(disk.SHA512) && !string.IsNullOrEmpty(diskDupe.SHA512)) + disk.SHA512 = diskDupe.SHA512; + } + + if (newDatItem.ItemType == ItemType.Rom) + { + if (string.IsNullOrEmpty(rom.SHA512) && !string.IsNullOrEmpty(romDupe.SHA512)) + rom.SHA512 = romDupe.SHA512; + } + } + + #endregion + + // Now assign back the duplicate archive to the original + switch (newDatItem.ItemType) + { + case ItemType.Archive: + newDatItem = archive.Clone() as Archive; + break; + + case ItemType.BiosSet: + newDatItem = biosSet.Clone() as BiosSet; + break; + + case ItemType.Blank: + newDatItem = blank.Clone() as Blank; + break; + + case ItemType.Disk: + newDatItem = disk.Clone() as Disk; + break; + + case ItemType.Release: + newDatItem = release.Clone() as Release; + break; + + case ItemType.Rom: + newDatItem = rom.Clone() as Rom; + break; + + case ItemType.Sample: + newDatItem = sample.Clone() as Sample; + break; } } @@ -1790,12 +2045,8 @@ namespace SabreTools.Library.DatFiles }); } - // If we are matching based on names of any sort - if ((replaceMode & ReplaceMode.Description) != 0 - || (replaceMode & ReplaceMode.MachineType) != 0 - || (replaceMode & ReplaceMode.Year) != 0 - || (replaceMode & ReplaceMode.Manufacturer) != 0 - || (replaceMode & ReplaceMode.Parents) != 0) + // If we are matching based on Machine fields of any sort + if (updateFields.Intersect(machineFields).Any()) { // For comparison's sake, we want to use Machine Name as the base ordering BucketBy(SortedBy.Game, DedupeType.Full); @@ -1809,34 +2060,67 @@ namespace SabreTools.Library.DatFiles List newDatItems = new List(); foreach (DatItem datItem in datItems) { - DatItem newDatItem = (DatItem)datItem.Clone(); + DatItem newDatItem = datItem.Clone() as DatItem; if (Contains(key) && this[key].Count() > 0) { - if ((replaceMode & ReplaceMode.Description) != 0) + var firstDupe = this[key][0]; + + if (updateFields.Contains(Field.MachineName)) + newDatItem.MachineName = firstDupe.MachineName; + + if (updateFields.Contains(Field.Comment)) + newDatItem.Comment = firstDupe.Comment; + + if (updateFields.Contains(Field.Description)) { if (!onlySame || (onlySame && newDatItem.MachineName == newDatItem.MachineDescription)) - { - newDatItem.MachineDescription = this[key][0].MachineDescription; - } - } - if ((replaceMode & ReplaceMode.MachineType) != 0) - { - newDatItem.MachineType = this[key][0].MachineType; - } - if ((replaceMode & ReplaceMode.Year) != 0) - { - newDatItem.Year = this[key][0].Year; - } - if ((replaceMode & ReplaceMode.Manufacturer) != 0) - { - newDatItem.Manufacturer = this[key][0].Manufacturer; - } - if ((replaceMode & ReplaceMode.Parents) != 0) - { - newDatItem.CloneOf = this[key][0].CloneOf; - newDatItem.RomOf = this[key][0].RomOf; - newDatItem.SampleOf = this[key][0].SampleOf; + newDatItem.MachineDescription = firstDupe.MachineDescription; } + + if (updateFields.Contains(Field.Year)) + newDatItem.Year = firstDupe.Year; + + if (updateFields.Contains(Field.Manufacturer)) + newDatItem.Manufacturer = firstDupe.Manufacturer; + + if (updateFields.Contains(Field.Publisher)) + newDatItem.Publisher = firstDupe.Publisher; + + if (updateFields.Contains(Field.RomOf)) + newDatItem.RomOf = firstDupe.RomOf; + + if (updateFields.Contains(Field.CloneOf)) + newDatItem.CloneOf = firstDupe.CloneOf; + + if (updateFields.Contains(Field.SampleOf)) + newDatItem.SampleOf = firstDupe.SampleOf; + + if (updateFields.Contains(Field.Supported)) + newDatItem.Supported = firstDupe.Supported; + + if (updateFields.Contains(Field.SourceFile)) + newDatItem.SourceFile = firstDupe.SourceFile; + + if (updateFields.Contains(Field.Runnable)) + newDatItem.Runnable = firstDupe.Runnable; + + if (updateFields.Contains(Field.Board)) + newDatItem.Board = firstDupe.Board; + + if (updateFields.Contains(Field.RebuildTo)) + newDatItem.RebuildTo = firstDupe.RebuildTo; + + if (updateFields.Contains(Field.Devices)) + newDatItem.Devices = firstDupe.Devices; + + if (updateFields.Contains(Field.SlotOptions)) + newDatItem.SlotOptions = firstDupe.SlotOptions; + + if (updateFields.Contains(Field.Infos)) + newDatItem.Infos = firstDupe.Infos; + + if (updateFields.Contains(Field.MachineType)) + newDatItem.MachineType = firstDupe.MachineType; } newDatItems.Add(newDatItem); @@ -1897,9 +2181,7 @@ namespace SabreTools.Library.DatFiles foreach (DatItem datItem in datItems) { if (!datItem.HasDuplicates(this, true)) - { keepDatItems.Add(datItem); - } } // Now add the new list to the key diff --git a/SabreTools.Library/DatFiles/Listxml.cs b/SabreTools.Library/DatFiles/Listxml.cs index 038e8a6d..937345aa 100644 --- a/SabreTools.Library/DatFiles/Listxml.cs +++ b/SabreTools.Library/DatFiles/Listxml.cs @@ -791,7 +791,7 @@ namespace SabreTools.Library.DatFiles break; case ItemType.BiosSet: // TODO: Separate out MachineDescription from Description state += "\t\t roms = datdata[key]; diff --git a/SabreTools.Library/DatItems/Disk.cs b/SabreTools.Library/DatItems/Disk.cs index 0618b9e1..6fe85b47 100644 --- a/SabreTools.Library/DatItems/Disk.cs +++ b/SabreTools.Library/DatItems/Disk.cs @@ -260,11 +260,9 @@ namespace SabreTools.Library.DatItems { bool dupefound = false; - // If we don't have a rom, return false + // If we don't have a disk, return false if (this.ItemType != other.ItemType) - { return dupefound; - } // Otherwise, treat it as a rom Disk newOther = (Disk)other; diff --git a/SabreTools.Library/Data/Enums.cs b/SabreTools.Library/Data/Enums.cs index d71c2e42..0fa477af 100644 --- a/SabreTools.Library/Data/Enums.cs +++ b/SabreTools.Library/Data/Enums.cs @@ -362,6 +362,7 @@ // BiosSet Default, + BiosDescription, // Disk MD5, diff --git a/SabreTools.Library/Data/Flags.cs b/SabreTools.Library/Data/Flags.cs index bf8539e4..61f6bb37 100644 --- a/SabreTools.Library/Data/Flags.cs +++ b/SabreTools.Library/Data/Flags.cs @@ -389,11 +389,11 @@ namespace SabreTools.Library.Data { CRC = 1 << 0, MD5 = 1 << 1, - SHA1 = 1 << 2, - SHA256 = 1 << 3, - SHA384 = 1 << 4, - SHA512 = 1 << 5, - RIPEMD160 = 1 << 6, + RIPEMD160 = 1 << 2, + SHA1 = 1 << 3, + SHA256 = 1 << 4, + SHA384 = 1 << 5, + SHA512 = 1 << 6, // Special combinations Standard = CRC | MD5 | SHA1, @@ -401,26 +401,6 @@ namespace SabreTools.Library.Data SecureHashes = MD5 | SHA1 | SHA256 | SHA384 | SHA512 | RIPEMD160, } - /// - /// Determine what to replace from base DATs - /// - [Flags] - public enum ReplaceMode - { - None = 0x00, - - // Sorted by hash - ItemName = 1 << 0, - Hash = 1 << 1, - - // Sorted by machine name - Description = 1 << 2, - MachineType = 1 << 3, - Year = 1 << 4, - Manufacturer = 1 << 5, - Parents = 1 << 6, - } - /// /// Determine which format to output Stats to /// diff --git a/SabreTools.Library/README.1ST b/SabreTools.Library/README.1ST index 2defe6b1..3cbdec5b 100644 --- a/SabreTools.Library/README.1ST +++ b/SabreTools.Library/README.1ST @@ -291,10 +291,6 @@ Options: preserving the directory structure of the inputted folder, if applicable. - -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. - -ef=, --exclude-field= Exclude a game/rom field from outputs Exclude any valid item or machine field from outputs. Examples include: romof, publisher, and offset. @@ -1067,10 +1063,6 @@ Options: Set the forcepacking tag to the given value. Possible values are: None, Zip, Unzip - -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. - -ef=, --exclude-field= Exclude a game/rom field from outputs Exclude any valid item or machine field from outputs. Examples include: romof, publisher, and offset. @@ -1100,30 +1092,6 @@ Options: for item naming. This flag removes all Unicode characters from the item names, machine names, and machine descriptions. - -rmd5, --remove-md5 Remove MD5 hashes from the output - By default, all available hashes will be written out to the DAT. This - will remove all MD5 hashes from the output file(s). - - -rripemd160, --remove-ripemd160 Remove RIPEMD160 hashes from the output - By default, all available hashes will be written out to the DAT. This - will remove all RIPEMD160 hashes from the output file(s). - - -rsha1, --remove-sha1 Remove SHA-1 hashes from the output - By default, all available hashes will be written out to the DAT. This - will remove all SHA-1 hashes from the output file(s). - - -rsha256, --remove-sha256 Remove SHA-256 hashes from the output - By default, all available hashes will be written out to the DAT. This - will remove all SHA-256 hashes from the output file(s). - - -rsha384, --remove-sha384 Remove SHA-384 hashes from the output - By default, all available hashes will be written out to the DAT. This - will remove all SHA-384 hashes from the output file(s). - - -rsha512, --remove-sha512 Remove SHA-512 hashes from the output - By default, all available hashes will be written out to the DAT. This - will remove all SHA-512 hashes from the output file(s). - -dan, --description-as-name Use description instead of machine name By default, all DATs are converted exactly as they are input. Enabling this flag allows for the machine names in the DAT to be @@ -1255,6 +1223,17 @@ Options: operations. Multiple instances of this flag are allowed. [Both base-replace and reverse-base-replace] + -uf, --update-field Update a game/rom field from base DATs + Update any valid item or machine field from base DAT(s). Examples + include: romof, publisher, and offset. + [Both base-replace and reverse-base-replace] + + -ons, --only-same Only update description if machine name matches description + Normally, updating the description will always overwrite if + the machine names are the same. With this flag, descriptions + will only be overwritten if they are the same as the machine + names. + -un, --update-names Update item names from base DATs This flag enables updating of item names from base DATs. [Both base-replace and reverse-base-replace] @@ -1757,10 +1736,12 @@ users of SabreTools. Thanks to Kludge for most of these suggestions! Note: This would output the created files to the SabreTools folder Long form: - SabreTools.exe --update --output-type=cmp --exclude-of Path\To\Dats + SabreTools.exe --update --output-type=cmp --exclude-of=romof + --exclude-of=sampleof --exclude-of=cloneof Path\To\Dats Short form: - SabreTools.exe -ud -oc -xof Path\To\Dats + SabreTools.exe -ud -oc -ef=romof --ef=sampleof --ef=cloneof + Path\To\Dats -- Example 3 -- Create an XML DAT from a folder of zipped sets setting a custom name @@ -1894,13 +1875,18 @@ This section contains remappings from old flag names to new ones for the purpose -rc, --rev-cascade -> -drc, --diff-reverse-cascade -rc, --reverse-cascade -> -drc, --diff-reverse-cascade -rep, --rep-ext -> -rep, --replace-extension --rmd5, --rem-md5 -> -rmd5, --remove-md5 +-rmd5, --rem-md5 -> -ef=md5, --exclude-field=md5 +-rmd5, --remove-md5 -> -ef=md5, --exclude-field=md5 -rme, --rem-ext -> -rme, --remove-extensions -rn, --rom-name -> -rn, --item-name --rsha1, --rem-sha1 -> -rsha1, --remove-sha1 --rsha256, --rem-sha256 -> -rsha256, --remove-sha256 --rsha384, --rem-sha384 -> -rsha384, --remove-sha384 --rsha512, --rem-sha512 -> -rsha512, --remove-sha512 +-rsha1, --rem-sha1 -> -ef=sha1, --exclude-field=sha1 +-rsha1, --remove-sha1 -> -ef=sha1, --exclude-field=sha1 +-rsha256, --rem-sha256 -> -ef=sha256, --exclude-field=sha256 +-rsha256, --remove-sha256 ->-ef=sha256, --exclude-field=sha256 +-rsha384, --rem-sha384 -> -ef=sha384, --exclude-field=sha384 +-rsha384, --remove-sha384 -> -ef=sha384, --exclude-field=sha384 +-rsha512, --rem-sha512 -> -ef=sha512, --exclude-field=sha512 +-rsha512, --remove-sha512 -> -ef=sha512, --exclude-field=sha512 -rt, --rom-type -> -rt, --item-type -ru, --rem-uni -> -ru, --remove-unicode -sf, --skip -> -sf, --skip-first-output @@ -1919,4 +1905,8 @@ This section contains remappings from old flag names to new ones for the purpose -tzpaq, --tzpaq -> -tzpaq, --torrent-zpaq -tzstd, --tzstd -> -tzstd, --torrent-zstd -udd, --update-desc -> -udd, --update-description --um, --update-manu -> -um, --update-manufacturer \ No newline at end of file +-um, --update-manu -> -um, --update-manufacturer +-xof, --exclude-of -> (-ef=romof -ef=cloneof -ef=sampleof + -ef=runnable -ef=machinetype), (--exclude-field=romof + --exclude-field=cloneof --exclude-field=sampleof + --exclude-field=runnable --exclude-field=machinetype) \ No newline at end of file diff --git a/SabreTools.Library/Tools/Utilities.cs b/SabreTools.Library/Tools/Utilities.cs index f8c364c6..6adb6f7a 100644 --- a/SabreTools.Library/Tools/Utilities.cs +++ b/SabreTools.Library/Tools/Utilities.cs @@ -811,6 +811,12 @@ namespace SabreTools.Library.Tools return Field.AreaSize; case "bios": return Field.Bios; + case "biosdescription": + case "bios description": + case "biossetdescription": + case "biosset description": + case "bios set description": + return Field.BiosDescription; case "board": return Field.Board; case "cloneof": diff --git a/SabreTools/SabreTools.Help.cs b/SabreTools/SabreTools.Help.cs index 64ad72b4..c9e93b96 100644 --- a/SabreTools/SabreTools.Help.cs +++ b/SabreTools/SabreTools.Help.cs @@ -321,18 +321,6 @@ namespace SabreTools longDescription: "This flag allows for a special type of diffing in which the last DAT is considered a base, and for each additional input DAT, it only leaves the files that are not in one of the previous DATs. This can allow for the creation of rollback sets or even just reduce the amount of duplicates across multiple sets."); } } - private static Feature _excludeOfFlag - { - get - { - return new Feature( - "exclude-of", - new List() { "-xof", "--exclude-of" }, - "Exclude romof, cloneof, sampleof tags", - FeatureType.Flag, - longDescription: "If this flag is enabled, then the romof, cloneof, and sampleof tags will be omitted from the outputted DAT."); - } - } // TODO: Remove private static Feature _extensionFlag { get @@ -585,78 +573,6 @@ namespace SabreTools longDescription: "For each item, remove the extension."); } } - private static Feature _removeMd5Flag - { - get - { - return new Feature( - "remove-md5", - new List() { "-rmd5", "--remove-md5" }, - "Remove MD5 hashes from the output", - FeatureType.Flag, - longDescription: "By default, all available hashes will be written out to the DAT. This will remove all MD5 hashes from the output file(s)."); - } - } // TODO: Remove - private static Feature _removeRipeMd160Flag - { - get - { - return new Feature( - "remove-ripemd160", - new List() { "-rripemd160", "--remove-ripemd160" }, - "Remove RIPEMD160 hashes from the output", - FeatureType.Flag, - longDescription: "By default, all available hashes will be written out to the DAT. This will remove all MD5 hashes from the output file(s)."); - } - } // TODO: Remove - private static Feature _removeSha1Flag - { - get - { - return new Feature( - "remove-sha1", - new List() { "-rsha1", "--remove-sha1" }, - "Remove SHA-1 hashes from the output", - FeatureType.Flag, - longDescription: "By default, all available hashes will be written out to the DAT. This will remove all SHA-1 hashes from the output file(s)."); - } - } // TODO: Remove - private static Feature _removeSha256Flag - { - get - { - return new Feature( - "remove-sha256", - new List() { "-rsha256", "--remove-sha256" }, - "Remove SHA-256 hashes from the output", - FeatureType.Flag, - longDescription: "By default, all available hashes will be written out to the DAT. This will remove all SHA-256 hashes from the output file(s)."); - } - } // TODO: Remove - private static Feature _removeSha384Flag - { - get - { - return new Feature( - "remove-sha384", - new List() { "-rsha384", "--remove-sha384" }, - "Remove SHA-384 hashes from the output", - FeatureType.Flag, - longDescription: "By default, all available hashes will be written out to the DAT. This will remove all SHA-384 hashes from the output file(s)."); - } - } // TODO: Remove - private static Feature _removeSha512Flag - { - get - { - return new Feature( - "remove-sha512", - new List() { "-rsha512", "--remove-sha512" }, - "Remove SHA-512 hashes from the output", - FeatureType.Flag, - longDescription: "By default, all available hashes will be written out to the DAT. This will remove all SHA-512 hashes from the output file(s)."); - } - } // TODO: Remove private static Feature _removeUnicodeFlag { get @@ -1677,11 +1593,11 @@ Possible values are: None, Good, BadDump, Nodump, Verified"); return new Feature( "update-field", new List() { "-uf", "--update-field" }, - "Update a game/rom field from base DAT(s)", + "Update a game/rom field from base DATs", FeatureType.List, longDescription: "Update any valid item or machine field from base DAT(s). Examples include: romof, publisher, and offset."); } - } // TODO: ADD THIS TO USED FLAGS + } #endregion @@ -2112,7 +2028,6 @@ Some special strings that can be used: datFromDir.AddFeature(_urlStringInput); datFromDir.AddFeature(_commentStringInput); datFromDir.AddFeature(_superdatFlag); - datFromDir.AddFeature(_excludeOfFlag); datFromDir.AddFeature(_excludeFieldListInput); datFromDir.AddFeature(_oneRomPerGameFlag); datFromDir.AddFeature(_sceneDateStripFlag); @@ -2339,19 +2254,12 @@ The stats that are outputted are as follows: update.AddFeature(_forcemergingStringInput); update.AddFeature(_forcenodumpStringInput); update.AddFeature(_forcepackingStringInput); - update.AddFeature(_excludeOfFlag); update.AddFeature(_excludeFieldListInput); update.AddFeature(_oneRomPerGameFlag); update.AddFeature(_keepEmptyGamesFlag); update.AddFeature(_sceneDateStripFlag); update.AddFeature(_cleanFlag); update.AddFeature(_removeUnicodeFlag); - update.AddFeature(_removeMd5Flag); - update.AddFeature(_removeRipeMd160Flag); - update.AddFeature(_removeSha1Flag); - update.AddFeature(_removeSha256Flag); - update.AddFeature(_removeSha384Flag); - update.AddFeature(_removeSha512Flag); update.AddFeature(_descriptionAsNameFlag); update.AddFeature(_datMergedFlag); update.AddFeature(_datSplitFlag); @@ -2377,6 +2285,8 @@ The stats that are outputted are as follows: update[_diffAgainstFlag].AddFeature(_baseDatListInput); update.AddFeature(_baseReplaceFlag); update[_baseReplaceFlag].AddFeature(_baseDatListInput); + update[_baseReplaceFlag].AddFeature(_updateFieldListInput); + update[_baseReplaceFlag][_updateFieldListInput].AddFeature(_onlySameFlag); update[_baseReplaceFlag].AddFeature(_updateNamesFlag); update[_baseReplaceFlag].AddFeature(_updateHashesFlag); update[_baseReplaceFlag].AddFeature(_updateDescriptionFlag); @@ -2387,6 +2297,8 @@ The stats that are outputted are as follows: update[_baseReplaceFlag].AddFeature(_updateParentsFlag); update.AddFeature(_reverseBaseReplaceFlag); update[_reverseBaseReplaceFlag].AddFeature(_baseDatListInput); + update[_baseReplaceFlag].AddFeature(_updateFieldListInput); + update[_baseReplaceFlag][_updateFieldListInput].AddFeature(_onlySameFlag); update[_reverseBaseReplaceFlag].AddFeature(_updateNamesFlag); update[_reverseBaseReplaceFlag].AddFeature(_updateHashesFlag); update[_reverseBaseReplaceFlag].AddFeature(_updateDescriptionFlag); diff --git a/SabreTools/SabreTools.Inits.cs b/SabreTools/SabreTools.Inits.cs index 49754f22..a36aaed3 100644 --- a/SabreTools/SabreTools.Inits.cs +++ b/SabreTools/SabreTools.Inits.cs @@ -302,7 +302,7 @@ namespace SabreTools /// True to clean the game names to WoD standard, false otherwise (default) /// True if we should remove non-ASCII characters from output, false otherwise (default) /// True if descriptions should be used as names, false otherwise (default) - /// ReplaceMode representing what should be updated [only for base replacement] + /// List of Fields representing what should be updated [only for base replacement] /// True if descriptions should only be replaced if the game name is the same, false otherwise [only for base replacement] private static void InitUpdate( List inputPaths, @@ -326,7 +326,7 @@ namespace SabreTools bool clean, bool remUnicode, bool descAsName, - ReplaceMode replaceMode, + List updateFields, bool onlySame) { // Normalize the extensions @@ -371,17 +371,15 @@ namespace SabreTools } } - // If no replacement mode is set, default to Names - if (replaceMode == ReplaceMode.None) - { - replaceMode = ReplaceMode.ItemName; - } + // If no update fields are set, default to Names + if (updateFields == null || updateFields.Count == 0) + updateFields = new List() { Field.Name }; // Populate the DatData object DatFile userInputDat = new DatFile(datHeader); userInputDat.DetermineUpdateType(inputPaths, basePaths, outDir, updateMode, inplace, skip, clean, - remUnicode, descAsName, filter, splitType, replaceMode, onlySame); + remUnicode, descAsName, filter, splitType, updateFields, onlySame); } /// diff --git a/SabreTools/SabreTools.cs b/SabreTools/SabreTools.cs index 5445b16f..5162e434 100644 --- a/SabreTools/SabreTools.cs +++ b/SabreTools/SabreTools.cs @@ -96,7 +96,6 @@ namespace SabreTools updateDat = false; Hash omitFromScan = Hash.DeepHashes; // TODO: All instances of Hash.DeepHashes should be made into 0x0 eventually OutputFormat outputFormat = OutputFormat.Folder; - ReplaceMode replaceMode = ReplaceMode.None; SkipFileType skipFileType = SkipFileType.None; SplittingMode splittingMode = SplittingMode.None; SplitType splitType = SplitType.None; @@ -282,14 +281,6 @@ namespace SabreTools case "diff-reverse-cascade": updateMode |= UpdateMode.DiffReverseCascade; break; - case "exclude-of": - Globals.Logger.User("This flag '{0}' is depreciated, please use {1} instead", feat.Key, String.Join(", ", _excludeFieldListInput.Flags)); - datHeader.ExcludeFields[(int)Field.CloneOf] = true; - datHeader.ExcludeFields[(int)Field.MachineType] = true; - datHeader.ExcludeFields[(int)Field.RomOf] = true; - datHeader.ExcludeFields[(int)Field.Runnable] = true; - datHeader.ExcludeFields[(int)Field.SampleOf] = true; - break; case "extension": splittingMode |= SplittingMode.Extension; break; @@ -353,30 +344,6 @@ namespace SabreTools case "remove-extensions": datHeader.RemoveExtension = true; break; - case "remove-md5": - Globals.Logger.User("This flag '{0}' is depreciated, please use {1} instead", feat.Key, String.Join(", ", _excludeFieldListInput.Flags)); - datHeader.ExcludeFields[(int)Field.MD5] = true; - break; - case "remove-ripemd160": - Globals.Logger.User("This flag '{0}' is depreciated, please use {1} instead", feat.Key, String.Join(", ", _excludeFieldListInput.Flags)); - datHeader.ExcludeFields[(int)Field.RIPEMD160] = true; - break; - case "remove-sha1": - Globals.Logger.User("This flag '{0}' is depreciated, please use {1} instead", feat.Key, String.Join(", ", _excludeFieldListInput.Flags)); - datHeader.ExcludeFields[(int)Field.SHA1] = true; - break; - case "remove-sha256": - Globals.Logger.User("This flag '{0}' is depreciated, please use {1} instead", feat.Key, String.Join(", ", _excludeFieldListInput.Flags)); - datHeader.ExcludeFields[(int)Field.SHA256] = true; - break; - case "remove-sha384": - Globals.Logger.User("This flag '{0}' is depreciated, please use {1} instead", feat.Key, String.Join(", ", _excludeFieldListInput.Flags)); - datHeader.ExcludeFields[(int)Field.SHA384] = true; - break; - case "remove-sha512": - Globals.Logger.User("This flag '{0}' is depreciated, please use {1} instead", feat.Key, String.Join(", ", _excludeFieldListInput.Flags)); - datHeader.ExcludeFields[(int)Field.SHA512] = true; - break; case "remove-unicode": removeUnicode = true; break; @@ -480,25 +447,40 @@ namespace SabreTools updateDat = true; break; case "update-description": - replaceMode |= ReplaceMode.Description; + Globals.Logger.User("This flag '{0}' is depreciated, please use {1} instead", feat.Key, String.Join(", ", _updateFieldListInput.Flags)); + updateFields.Add(Field.Description); break; case "update-game-type": - replaceMode |= ReplaceMode.MachineType; + Globals.Logger.User("This flag '{0}' is depreciated, please use {1} instead", feat.Key, String.Join(", ", _updateFieldListInput.Flags)); + updateFields.Add(Field.MachineType); break; case "update-hashes": - replaceMode |= ReplaceMode.Hash; + Globals.Logger.User("This flag '{0}' is depreciated, please use {1} instead", feat.Key, String.Join(", ", _updateFieldListInput.Flags)); + updateFields.Add(Field.CRC); + updateFields.Add(Field.MD5); + updateFields.Add(Field.RIPEMD160); + updateFields.Add(Field.SHA1); + updateFields.Add(Field.SHA256); + updateFields.Add(Field.SHA384); + updateFields.Add(Field.SHA512); break; case "update-manufacturer": - replaceMode |= ReplaceMode.Manufacturer; + Globals.Logger.User("This flag '{0}' is depreciated, please use {1} instead", feat.Key, String.Join(", ", _updateFieldListInput.Flags)); + updateFields.Add(Field.Manufacturer); break; case "update-names": - replaceMode |= ReplaceMode.ItemName; + Globals.Logger.User("This flag '{0}' is depreciated, please use {1} instead", feat.Key, String.Join(", ", _updateFieldListInput.Flags)); + updateFields.Add(Field.Name); break; case "update-parents": - replaceMode |= ReplaceMode.Parents; + Globals.Logger.User("This flag '{0}' is depreciated, please use {1} instead", feat.Key, String.Join(", ", _updateFieldListInput.Flags)); + updateFields.Add(Field.CloneOf); + updateFields.Add(Field.RomOf); + updateFields.Add(Field.SampleOf); break; case "update-year": - replaceMode |= ReplaceMode.Year; + Globals.Logger.User("This flag '{0}' is depreciated, please use {1} instead", feat.Key, String.Join(", ", _updateFieldListInput.Flags)); + updateFields.Add(Field.Year); break; #endregion @@ -517,9 +499,8 @@ namespace SabreTools case "threads": int val = (int)feat.Value.GetValue(); if (val != Int32.MinValue) - { Globals.MaxThreads = val; - } + break; case "zip": zip = (int)feat.Value.GetValue() == Int32.MinValue ? (int)feat.Value.GetValue() : 1; @@ -546,7 +527,7 @@ namespace SabreTools case "dat": datfiles.AddRange((List)feat.Value.GetValue()); break; - case "exclude-field": // TODO: Use this + case "exclude-field": foreach (string field in (List)feat.Value.GetValue()) { datHeader.ExcludeFields[(int)Utilities.GetField(field)] = true; @@ -662,7 +643,7 @@ namespace SabreTools filter.ItemStatuses.Positive |= Utilities.GetItemStatus(stat); } break; - case "update-field": // TODO: Use this + case "update-field": foreach (string field in (List)feat.Value.GetValue()) { updateFields.Add(Utilities.GetField(field)); @@ -801,7 +782,7 @@ namespace SabreTools case "Update": VerifyInputs(inputs, feature); InitUpdate(inputs, basePaths, datHeader, updateMode, inplace, skipFirstOutput, noAutomaticDate, filter, - splitType, outDir, cleanGameNames, removeUnicode, descAsName, replaceMode, onlySame); + splitType, outDir, cleanGameNames, removeUnicode, descAsName, updateFields, onlySame); break; // If we're using the verifier case "Verify":