diff --git a/SabreTools.Helper/Data/Build.cs b/SabreTools.Helper/Data/Build.cs
index 9bd79890..15a2acc2 100644
--- a/SabreTools.Helper/Data/Build.cs
+++ b/SabreTools.Helper/Data/Build.cs
@@ -315,9 +315,10 @@ namespace SabreTools.Helper.Data
helptext.Add(" -xof, --exclude-of Exclude romof, cloneof, sampleof tags");
helptext.Add(" -clean Clean game names according to WoD standards");
helptext.Add(" -sl, --softlist Use Software List name instead of description");
- helptext.Add(" -dnm, --dat-nm Create non-merged sets in the output DAT");
helptext.Add(" -dm, --dat-merge Create merged sets in the output DAT");
- helptext.Add(" -df, --dat-fnm Create fully merged sets in the output");
+ helptext.Add(" -ds, --dat-sp Create split sets in the output DAT");
+ helptext.Add(" -dnm, --dat-nm Create non-merged sets in the output DAT");
+ helptext.Add(" -df, --dat-fnm Create fully non-merged sets in the output");
helptext.Add(" -trim Trim file names to fit NTFS length");
helptext.Add(" -rd=, --root-dir= Set the root directory for calc");
helptext.Add(" -si, --single All game names replaced by '!'");
diff --git a/SabreTools.Helper/Data/Enums.cs b/SabreTools.Helper/Data/Enums.cs
index d826befe..a352c501 100644
--- a/SabreTools.Helper/Data/Enums.cs
+++ b/SabreTools.Helper/Data/Enums.cs
@@ -263,6 +263,7 @@
NonMerged,
Merged,
FullNonMerged,
+ Split,
}
#endregion
diff --git a/SabreTools.Helper/Dats/Partials/DatFile.Bucketing.cs b/SabreTools.Helper/Dats/Partials/DatFile.Bucketing.cs
index 0676c55b..0516a030 100644
--- a/SabreTools.Helper/Dats/Partials/DatFile.Bucketing.cs
+++ b/SabreTools.Helper/Dats/Partials/DatFile.Bucketing.cs
@@ -878,6 +878,219 @@ namespace SabreTools.Helper.Dats
}
}
+ ///
+ /// Use cloneof and romof tags to create split sets and remove the tags
+ ///
+ /// True if roms should be deduped, false otherwise
+ /// Logger object for file and console output
+ /// True if the number of hashes counted is to be output (default), false otherwise
+ public void CreateSplitSets(bool mergeroms, Logger logger, bool output = true)
+ {
+ logger.User("Creating split sets from the DAT");
+
+ // For sake of ease, the first thing we want to do is sort by game
+ BucketByGame(mergeroms, true, logger, output);
+ _sortedBy = SortedBy.Default;
+
+ // Now we want to loop through all of the games and set the correct information
+ List games = Keys.ToList();
+ foreach (string game in games)
+ {
+ // If the game has no items in it, we want to continue
+ if (this[game].Count == 0)
+ {
+ continue;
+ }
+
+ // Determine if the game has a parent or not
+ string parent = null;
+ if (!String.IsNullOrEmpty(this[game][0].Machine.CloneOf))
+ {
+ parent = this[game][0].Machine.CloneOf;
+ }
+
+ // If the parent doesnt exist, we want to continue
+ if (String.IsNullOrEmpty(parent))
+ {
+ continue;
+ }
+
+ // If the parent doesn't have any items, we want to continue
+ if (this[parent].Count == 0)
+ {
+ continue;
+ }
+
+ // If the parent exists and has items, we copy the items from the parent to the current game
+ Machine currentMachine = this[game][0].Machine;
+ List parentItems = this[parent];
+ foreach (DatItem item in parentItems)
+ {
+ // Figure out the type of the item and remove it accordingly
+ switch (item.Type)
+ {
+ case ItemType.Archive:
+ Archive archive = ((Archive)item).Clone() as Archive;
+ if (this[game].Contains(archive))
+ {
+ this[game].Remove(archive);
+ }
+
+ break;
+ case ItemType.BiosSet:
+ BiosSet biosSet = ((BiosSet)item).Clone() as BiosSet;
+ if (this[game].Contains(biosSet))
+ {
+ this[game].Remove(biosSet);
+ }
+
+ break;
+ case ItemType.Disk:
+ Disk disk = ((Disk)item).Clone() as Disk;
+ if (this[game].Contains(disk))
+ {
+ this[game].Remove(disk);
+ }
+
+ break;
+ case ItemType.Release:
+ Release release = ((Release)item).Clone() as Release;
+ if (this[game].Contains(release))
+ {
+ this[game].Remove(release);
+ }
+
+ break;
+ case ItemType.Rom:
+ Rom rom = ((Rom)item).Clone() as Rom;
+ if (this[game].Contains(rom))
+ {
+ this[game].Remove(rom);
+ }
+
+ break;
+ case ItemType.Sample:
+ Sample sample = ((Sample)item).Clone() as Sample;
+ if (this[game].Contains(sample))
+ {
+ this[game].Remove(sample);
+ }
+
+ break;
+ }
+ }
+
+ // Now we want to get the parent romof tag and put it in each of the items
+ List items = this[game];
+ string romof = this[parent][0].Machine.RomOf;
+ foreach (DatItem item in items)
+ {
+ item.Machine.RomOf = romof;
+ }
+ }
+
+ // Now that we have looped through the cloneof tags, we loop through the romof tags
+ games = Keys.ToList();
+ foreach (string game in games)
+ {
+ // If the game has no items in it, we want to continue
+ if (this[game].Count == 0)
+ {
+ continue;
+ }
+
+ // Determine if the game has a parent or not
+ string parent = null;
+ if (!String.IsNullOrEmpty(this[game][0].Machine.RomOf))
+ {
+ parent = this[game][0].Machine.RomOf;
+ }
+
+ // If the parent doesnt exist, we want to continue
+ if (String.IsNullOrEmpty(parent))
+ {
+ continue;
+ }
+
+ // If the parent doesn't have any items, we want to continue
+ if (this[parent].Count == 0)
+ {
+ continue;
+ }
+
+ // If the parent exists and has items, we remove the items that are in the parent from the current game
+ Machine currentMachine = this[game][0].Machine;
+ List parentItems = this[parent];
+ foreach (DatItem item in parentItems)
+ {
+ // Figure out the type of the item and add it accordingly
+ switch (item.Type)
+ {
+ case ItemType.Archive:
+ Archive archive = ((Archive)item).Clone() as Archive;
+ if (this[game].Contains(archive))
+ {
+ this[game].Remove(archive);
+ }
+
+ break;
+ case ItemType.BiosSet:
+ BiosSet biosSet = ((BiosSet)item).Clone() as BiosSet;
+ if (this[game].Contains(biosSet))
+ {
+ this[game].Remove(biosSet);
+ }
+
+ break;
+ case ItemType.Disk:
+ Disk disk = ((Disk)item).Clone() as Disk;
+ if (this[game].Contains(disk))
+ {
+ this[game].Remove(disk);
+ }
+
+ break;
+ case ItemType.Release:
+ Release release = ((Release)item).Clone() as Release;
+ if (this[game].Contains(release))
+ {
+ this[game].Remove(release);
+ }
+
+ break;
+ case ItemType.Rom:
+ Rom rom = ((Rom)item).Clone() as Rom;
+ if (this[game].Contains(rom))
+ {
+ this[game].Remove(rom);
+ }
+
+ break;
+ case ItemType.Sample:
+ Sample sample = ((Sample)item).Clone() as Sample;
+ if (this[game].Contains(sample))
+ {
+ this[game].Remove(sample);
+ }
+
+ break;
+ }
+ }
+ }
+
+ // Finally, remove the romof and cloneof tags so it's not picked up by the manager
+ games = Keys.ToList();
+ foreach (string game in games)
+ {
+ List items = this[game];
+ foreach (DatItem item in items)
+ {
+ item.Machine.CloneOf = null;
+ item.Machine.RomOf = null;
+ }
+ }
+ }
+
#endregion
#endregion // Instance Methods
diff --git a/SabreTools.Helper/Dats/Partials/DatFile.Parsers.cs b/SabreTools.Helper/Dats/Partials/DatFile.Parsers.cs
index ed39dfc7..4cedede2 100644
--- a/SabreTools.Helper/Dats/Partials/DatFile.Parsers.cs
+++ b/SabreTools.Helper/Dats/Partials/DatFile.Parsers.cs
@@ -127,17 +127,20 @@ namespace SabreTools.Helper.Dats
}
// Now we pre-process the DAT with the splitting/merging mode
- if (splitType == SplitType.NonMerged)
+ switch (splitType)
{
- CreateNonMergedSets(false, logger, output: false);
- }
- else if (splitType == SplitType.Merged)
- {
- CreateMergedSets(false, logger, output: false);
- }
- else if (splitType == SplitType.FullNonMerged)
- {
- CreateFullyNonMergedSets(false, logger, output: false);
+ case SplitType.FullNonMerged:
+ CreateFullyNonMergedSets(false, logger, output: false);
+ break;
+ case SplitType.NonMerged:
+ CreateNonMergedSets(false, logger, output: false);
+ break;
+ case SplitType.Merged:
+ CreateMergedSets(false, logger, output: false);
+ break;
+ case SplitType.Split:
+ CreateSplitSets(false, logger, output: false);
+ break;
}
}
diff --git a/SabreTools.Helper/README.1ST b/SabreTools.Helper/README.1ST
index 8217723b..f7d1f251 100644
--- a/SabreTools.Helper/README.1ST
+++ b/SabreTools.Helper/README.1ST
@@ -730,15 +730,21 @@ Options:
Enabling this flag allows for the original name to be preserved and keeping
the description as just a description.
- -dnm, --dat-nm Create non-merged sets in the output DAT
-dm, --dat-merge Create merged sets in the output DAT
- -df, --dat-fnm Create fully merged sets (including devices) in the output DAT
- Each of the above flags allow for preprocessing an outputted DAT in the case that
- your DAT manager of choice doesn't allow these on the fly. Non-merged will copy all
- parent items to the children so that each archive or folder contains everything
- necessary for each game. Fully non-merged copies all parent and device items to the
- children as well. Merge will copy all child items to a subfolder of the parent,
- reducing the space taken up on disk.
+ Preprocess the DAT to have parent sets contain all items from the children based
+ on the cloneof tag.
+
+ -ds, --dat-sp Create split sets in the output DAT
+ Preprocess the DAT to remove redundant files between parents and children based
+ on the romof and cloneof tags.
+
+ -dnm, --dat-nm Create non-merged sets in the output DAT
+ Preprocess the DAT to have child sets contain all items from the parent set based
+ on the cloneof tag.
+
+ -df, --dat-fnm Create fully non-merged sets in the output DAT
+ Preprocess the DAT to have child sets contain all items from the parent sets based
+ on the cloneof and romof tags as well as device references.
-trim Trim file names to fit NTFS length
In the cases where files will have too long a name, this allows for trimming
diff --git a/SabreTools/SabreTools.cs b/SabreTools/SabreTools.cs
index 493b8daa..c82e55ff 100644
--- a/SabreTools/SabreTools.cs
+++ b/SabreTools/SabreTools.cs
@@ -284,6 +284,10 @@ namespace SabreTools
case "--dat-nm":
splitType = SplitType.NonMerged;
break;
+ case "-ds":
+ case "--dat-sp":
+ splitType = SplitType.Split;
+ break;
case "-f":
case "--files":
parseArchivesAsFiles = true;