diff --git a/SabreTools.Library/DatFiles/DatFile.cs b/SabreTools.Library/DatFiles/DatFile.cs
index c69880b2..0ee6b444 100644
--- a/SabreTools.Library/DatFiles/DatFile.cs
+++ b/SabreTools.Library/DatFiles/DatFile.cs
@@ -4720,8 +4720,9 @@ namespace SabreTools.Library.DatFiles
/// Second extension to split on (Extension Split only)
/// True if short filenames should be used, false otherwise (Level Split only)
/// True if original filenames should be used as the base for output filename, false otherwise (Level Split only)
+ /// Long value representing the split point (Size Split only)
public void DetermineSplitType(List inputs, string outDir, bool inplace, SplittingMode splittingMode,
- List exta, List extb, bool shortname, bool basedat)
+ List exta, List extb, bool shortname, bool basedat, long radix)
{
// If we somehow have the "none" split type, return
if (splittingMode == SplittingMode.None)
@@ -4754,6 +4755,10 @@ namespace SabreTools.Library.DatFiles
{
SplitByLevel(outDir, shortname, basedat);
}
+ if ((splittingMode & SplittingMode.Size) != 0)
+ {
+ SplitBySize(outDir, radix);
+ }
if ((splittingMode & SplittingMode.Type) != 0)
{
SplitByType(outDir);
@@ -5212,7 +5217,94 @@ namespace SabreTools.Library.DatFiles
}
///
- /// Split a DAT by type of Rom
+ /// Split a DAT by size of Rom
+ ///
+ /// Name of the directory to write the DATs out to
+ /// Long value representing the split point
+ /// True if split succeeded, false otherwise
+ public bool SplitBySize(string outDir, long radix)
+ {
+ // Create each of the respective output DATs
+ Globals.Logger.User("Creating and populating new DATs");
+ DatFile lessDat = new DatFile
+ {
+ FileName = this.FileName + " (less than " + radix + " )",
+ Name = this.Name + " (less than " + radix + " )",
+ Description = this.Description + " (less than " + radix + " )",
+ Category = this.Category,
+ Version = this.Version,
+ Date = this.Date,
+ Author = this.Author,
+ Email = this.Email,
+ Homepage = this.Homepage,
+ Url = this.Url,
+ Comment = this.Comment,
+ Header = this.Header,
+ Type = this.Type,
+ ForceMerging = this.ForceMerging,
+ ForceNodump = this.ForceNodump,
+ ForcePacking = this.ForcePacking,
+ DatFormat = this.DatFormat,
+ DedupeRoms = this.DedupeRoms,
+ };
+ DatFile greaterEqualDat = new DatFile
+ {
+ FileName = this.FileName + " (equal-greater than " + radix + " )",
+ Name = this.Name + " (equal-greater than " + radix + " )",
+ Description = this.Description + " (equal-greater than " + radix + " )",
+ Category = this.Category,
+ Version = this.Version,
+ Date = this.Date,
+ Author = this.Author,
+ Email = this.Email,
+ Homepage = this.Homepage,
+ Url = this.Url,
+ Comment = this.Comment,
+ Header = this.Header,
+ Type = this.Type,
+ ForceMerging = this.ForceMerging,
+ ForceNodump = this.ForceNodump,
+ ForcePacking = this.ForcePacking,
+ DatFormat = this.DatFormat,
+ DedupeRoms = this.DedupeRoms,
+ };
+
+ // Now populate each of the DAT objects in turn
+ List keys = Keys;
+ Parallel.ForEach(keys, Globals.ParallelOptions, key =>
+ {
+ List items = this[key];
+ foreach (DatItem item in items)
+ {
+ // If the file is not a Rom, it automatically goes in the "lesser" dat
+ if (item.Type != ItemType.Rom)
+ {
+ lessDat.Add(key, item);
+ }
+ // If the file is a Rom and less than the radix, put it in the "lesser" dat
+ else if (item.Type == ItemType.Rom && ((Rom)item).Size < radix)
+ {
+ lessDat.Add(key, item);
+ }
+ // If the file is a Rom and greater than or equal to the radix, put it in the "greater" dat
+ else if (item.Type == ItemType.Rom && ((Rom)item).Size >= radix)
+ {
+ greaterEqualDat.Add(key, item);
+ }
+ }
+ });
+
+ // Now, output all of the files to the output directory
+ Globals.Logger.User("DAT information created, outputting new files");
+ bool success = true;
+ success &= lessDat.Write(outDir);
+ success &= greaterEqualDat.Write(outDir);
+
+ return success;
+ }
+
+ ///
+ /// Split a DAT by type of DatItem
///
/// Name of the directory to write the DATs out to
/// True if split succeeded, false otherwise
diff --git a/SabreTools.Library/Data/Flags.cs b/SabreTools.Library/Data/Flags.cs
index a3b81d7c..e9e21777 100644
--- a/SabreTools.Library/Data/Flags.cs
+++ b/SabreTools.Library/Data/Flags.cs
@@ -287,6 +287,7 @@ namespace SabreTools.Library.Data
Hash = Extension << 1,
Level = Hash << 1,
Type = Level << 1,
+ Size = Type << 1,
}
///
diff --git a/SabreTools.Library/README.1ST b/SabreTools.Library/README.1ST
index 434a3940..9a2c292b 100644
--- a/SabreTools.Library/README.1ST
+++ b/SabreTools.Library/README.1ST
@@ -531,6 +531,15 @@ Options:
the format of "Original Name (Dir - Name)". This can be used in
conjunction with --short to output in the format of "Original
Name (Name)" instead.
+
+ -szs, --size Split DAT(s) or folder by file sizes
+ For a DAT, or set of DATs, allow for splitting based on the sizes
+ of the files, specificially if the type is a rom (disks don't have
+ sizes)
+
+ -rad, --radix Set the midpoint to split at
+ Set the size at which all roms less than the size are put in the
+ first DAT, and everything greater than or equal goes in the second
-ts, --type Split DAT(s) or folder by file types (rom/disk)
For a DAT, or set of DATs, allow for splitting based on the types of
diff --git a/SabreTools/SabreTools.Help.cs b/SabreTools/SabreTools.Help.cs
index 3fe00b89..45b6b43a 100644
--- a/SabreTools/SabreTools.Help.cs
+++ b/SabreTools/SabreTools.Help.cs
@@ -896,6 +896,17 @@ namespace SabreTools
null);
}
}
+ private static Feature sizeFlag
+ {
+ get
+ {
+ return new Feature(
+ new List() { "-szs", "--size" },
+ "Split DAT(s) or folder by file sizes",
+ FeatureType.Flag,
+ null);
+ }
+ }
private static Feature skipFirstOutputFlag
{
get
@@ -1280,6 +1291,17 @@ namespace SabreTools
#region Private Int64 features
+ private static Feature radixInt64Input
+ {
+ get
+ {
+ return new Feature(
+ new List() { "-rad", "--radix" },
+ "Set the midpoint to split at",
+ FeatureType.Int64,
+ null);
+ }
+ }
#endregion
@@ -2095,6 +2117,8 @@ namespace SabreTools
split.AddFeature("level", levelFlag);
split["level"].AddFeature("short", shortFlag);
split["level"].AddFeature("base", baseFlag);
+ split.AddFeature("size", sizeFlag);
+ split["size"].AddFeature("radix", radixInt64Input);
split.AddFeature("type", typeFlag);
#endregion
diff --git a/SabreTools/SabreTools.Inits.cs b/SabreTools/SabreTools.Inits.cs
index 50dcb60f..0602e087 100644
--- a/SabreTools/SabreTools.Inits.cs
+++ b/SabreTools/SabreTools.Inits.cs
@@ -189,12 +189,13 @@ namespace SabreTools
/// Second extension to split on (Extension Split only)
/// True if short filenames should be used, false otherwise (Level Split only)
/// True if original filenames should be used as the base for output filename, false otherwise (Level Split only)
+ /// Long value representing the split point (Size Split only)
private static void InitSplit(List inputs, string outDir, bool inplace, DatFormat datFormat,
- SplittingMode splittingMode, List exta, List extb, bool shortname, bool basedat)
+ SplittingMode splittingMode, List exta, List extb, bool shortname, bool basedat, long radix)
{
DatFile datfile = new DatFile();
datfile.DatFormat = datFormat;
- datfile.DetermineSplitType(inputs, outDir, inplace, splittingMode, exta, extb, shortname, basedat);
+ datfile.DetermineSplitType(inputs, outDir, inplace, splittingMode, exta, extb, shortname, basedat, radix);
}
///
diff --git a/SabreTools/SabreTools.cs b/SabreTools/SabreTools.cs
index 9ffc6a82..1f699f79 100644
--- a/SabreTools/SabreTools.cs
+++ b/SabreTools/SabreTools.cs
@@ -109,6 +109,7 @@ namespace SabreTools
rar = 1,
sevenzip = 1,
zip = 1;
+ long radix = 0;
string outDir = null,
tempDir = "";
DatHeader datHeader = new DatHeader();
@@ -421,6 +422,9 @@ namespace SabreTools
case "short":
shortname = true;
break;
+ case "size":
+ splittingMode |= SplittingMode.Size;
+ break;
case "skip-archives":
skipFileType = SkipFileType.Archive;
break;
@@ -540,6 +544,10 @@ namespace SabreTools
#region User Int64 Inputs
+ case "radix":
+ radix = (long)feat.Value.GetValue() == Int64.MinValue ? (long)feat.Value.GetValue() : 0;
+ break;
+
#endregion
#region User List Inputs
@@ -755,7 +763,7 @@ namespace SabreTools
// Split a DAT by the split type
case "Split":
VerifyInputs(inputs, feature);
- InitSplit(inputs, outDir, inplace, datHeader.DatFormat, splittingMode, exta, extb, shortname, basedat);
+ InitSplit(inputs, outDir, inplace, datHeader.DatFormat, splittingMode, exta, extb, shortname, basedat, radix);
break;
// Get statistics on input files
case "Stats":