diff --git a/DICUI.Library/Data/Enumerations.cs b/DICUI.Library/Data/Enumerations.cs
index ff37ddd4..7403604c 100644
--- a/DICUI.Library/Data/Enumerations.cs
+++ b/DICUI.Library/Data/Enumerations.cs
@@ -23,11 +23,12 @@ namespace DICUI.Data
// Dumping support
Aaru,
DD,
- DiscImageCreator, // Includes UmdImageCreator
+ DiscImageCreator,
// Verification support only
CleanRip,
DCDumper,
+ UmdImageCreator,
}
///
diff --git a/DICUI.Library/DiscImageCreator/Converters.cs b/DICUI.Library/DiscImageCreator/Converters.cs
index a5496170..0a01042b 100644
--- a/DICUI.Library/DiscImageCreator/Converters.cs
+++ b/DICUI.Library/DiscImageCreator/Converters.cs
@@ -103,7 +103,6 @@ namespace DICUI.DiscImageCreator
case MediaType.HDDVD:
case MediaType.BluRay:
case MediaType.NintendoWiiOpticalDisc:
- case MediaType.UMD:
return ".iso";
case MediaType.LaserDisc:
case MediaType.NintendoGameCubeGameDisc:
diff --git a/DICUI.Library/DiscImageCreator/Parameters.cs b/DICUI.Library/DiscImageCreator/Parameters.cs
index 81cb5367..90c39ec8 100644
--- a/DICUI.Library/DiscImageCreator/Parameters.cs
+++ b/DICUI.Library/DiscImageCreator/Parameters.cs
@@ -1622,14 +1622,6 @@ namespace DICUI.DiscImageCreator
break;
- case MediaType.UMD:
- return File.Exists(basePath + "_disc.txt")
- || File.Exists(basePath + "_mainError.txt")
- || File.Exists(basePath + "_mainInfo.txt")
- || File.Exists(basePath + "_volDesc.txt");
-
- break;
-
default:
// Non-dumping commands will usually produce no output, so this is irrelevant
return true;
@@ -1738,22 +1730,6 @@ namespace DICUI.DiscImageCreator
info.Extras.PIC = GetPIC(Path.Combine(outputDirectory, "PIC.bin")) ?? "";
break;
-
- case MediaType.UMD:
- info.Extras.PVD = GetPVD(basePath + "_mainInfo.txt") ?? "";
-
- if (GetUMDAuxInfo(basePath + "_disc.txt", out string title, out DiscCategory? umdcat, out string umdversion, out string umdlayer, out long umdsize))
- {
- info.CommonDiscInfo.Title = title ?? "";
- info.CommonDiscInfo.Category = umdcat ?? DiscCategory.Games;
- info.VersionAndEditions.Version = umdversion ?? "";
- info.SizeAndChecksums.Size = umdsize;
-
- if (!string.IsNullOrWhiteSpace(umdlayer))
- info.SizeAndChecksums.Layerbreak = Int64.Parse(umdlayer ?? "-1");
- }
-
- break;
}
// Extract info based specifically on KnownSystem
@@ -2734,55 +2710,6 @@ namespace DICUI.DiscImageCreator
}
}
- ///
- /// Get the UMD auxiliary info from the outputted files, if possible
- ///
- /// _disc.txt file location
- /// True on successful extraction of info, false otherwise
- private static bool GetUMDAuxInfo(string disc, out string title, out DiscCategory? umdcat, out string umdversion, out string umdlayer, out long umdsize)
- {
- title = null; umdcat = null; umdversion = null; umdlayer = null; umdsize = -1;
-
- // If the file doesn't exist, we can't get info from it
- if (!File.Exists(disc))
- return false;
-
- using (StreamReader sr = File.OpenText(disc))
- {
- try
- {
- // Loop through everything to get the first instance of each required field
- string line = string.Empty;
- while (!sr.EndOfStream)
- {
- line = sr.ReadLine().Trim();
-
- if (line.StartsWith("TITLE") && title == null)
- title = line.Substring("TITLE: ".Length);
- else if (line.StartsWith("DISC_VERSION") && umdversion == null)
- umdversion = line.Split(' ')[1];
- else if (line.StartsWith("pspUmdTypes"))
- umdcat = GetUMDCategory(line.Split(' ')[1]);
- else if (line.StartsWith("L0 length"))
- umdlayer = line.Split(' ')[2];
- else if (line.StartsWith("FileSize:"))
- umdsize = Int64.Parse(line.Split(' ')[1]);
- }
-
- // If the L0 length is the size of the full disc, there's no layerbreak
- if (Int64.Parse(umdlayer) * 2048 == umdsize)
- umdlayer = null;
-
- return true;
- }
- catch
- {
- // We don't care what the exception is right now
- return false;
- }
- }
- }
-
///
/// Get the write offset from the input file, if possible
///
diff --git a/DICUI.Library/UmdImageCreator/Parameters.cs b/DICUI.Library/UmdImageCreator/Parameters.cs
new file mode 100644
index 00000000..e0f0c2f3
--- /dev/null
+++ b/DICUI.Library/UmdImageCreator/Parameters.cs
@@ -0,0 +1,325 @@
+using System;
+using System.IO;
+using DICUI.Data;
+using DICUI.Utilities;
+using DICUI.Web;
+
+namespace DICUI.UmdImageCreator
+{
+ ///
+ /// Represents a generic set of UmdImageCreator parameters
+ ///
+ public class Parameters : BaseParameters
+ {
+ ///
+ /// Populate a Parameters object from a param string
+ ///
+ /// String possibly representing a set of parameters
+ public Parameters(string parameters)
+ : base(parameters)
+ {
+ this.InternalProgram = InternalProgram.UmdImageCreator;
+ }
+
+ ///
+ /// Generate parameters based on a set of known inputs
+ ///
+ /// KnownSystem value to use
+ /// MediaType value to use
+ /// Drive letter to use
+ /// Filename to use
+ /// Drive speed to use
+ /// Enable paranoid mode (safer dumping)
+ /// Enable quiet mode (no beeps)
+ /// User-defined reread count
+ public Parameters(KnownSystem? system, MediaType? type, char driveLetter, string filename, int? driveSpeed, bool paranoid, bool quietMode, int retryCount)
+ : base(system, type, driveLetter, filename, driveSpeed, paranoid, quietMode, retryCount)
+ {
+ }
+
+ ///
+ /// Blindly generate a parameter string based on the inputs
+ ///
+ /// Correctly formatted parameter string, null on error
+ public override string GenerateParameters() => null;
+
+ ///
+ /// Get the input path from the implementation
+ ///
+ /// String representing the path, null on error
+ public override string InputPath() => null;
+
+ ///
+ /// Get the output path from the implementation
+ ///
+ /// String representing the path, null on error
+ public override string OutputPath() => null;
+
+ ///
+ /// Get the processing speed from the implementation
+ ///
+ /// int? representing the speed, null on error
+ public override int? GetSpeed() => null;
+
+ ///
+ /// Set the processing speed int the implementation
+ ///
+ /// int? representing the speed
+ public override void SetSpeed(int? speed) { }
+
+ ///
+ /// Get the MediaType from the current set of parameters
+ ///
+ /// MediaType value if successful, null on error
+ public override MediaType? GetMediaType() => null;
+
+ ///
+ /// Gets if the current command is considered a dumping command or not
+ ///
+ /// True if it's a dumping command, false otherwise
+ public override bool IsDumpingCommand() => true;
+
+ ///
+ /// Reset all special variables to have default values
+ ///
+ protected override void ResetValues() { }
+
+ ///
+ /// Set default parameters for a given system and media type
+ ///
+ /// KnownSystem value to use
+ /// MediaType value to use
+ /// Drive letter to use
+ /// Filename to use
+ /// Drive speed to use
+ /// Enable paranoid mode (safer dumping)
+ /// User-defined reread count
+ protected override void SetDefaultParameters(
+ KnownSystem? system,
+ MediaType? type,
+ char driveLetter,
+ string filename,
+ int? driveSpeed,
+ bool paranoid,
+ int retryCount)
+ {
+ }
+
+ ///
+ /// Scan a possible parameter string and populate whatever possible
+ ///
+ /// String possibly representing parameters
+ ///
+ protected override bool ValidateAndSetParameters(string parameters) => true;
+
+ ///
+ /// Validate if all required output files exist
+ ///
+ /// Base filename and path to use for checking
+ /// KnownSystem type representing the media
+ /// MediaType type representing the media
+ /// Optional result progress callback
+ ///
+ public override bool CheckAllOutputFilesExist(string basePath, KnownSystem? system, MediaType? type, IProgress progress = null)
+ {
+ string missingFiles = string.Empty;
+ switch (type)
+ {
+ case MediaType.UMD:
+ if (!File.Exists($"{basePath}_disc.txt"))
+ missingFiles += $";{basePath}_disc.txt";
+ if (!File.Exists($"{basePath}_mainError.txt"))
+ missingFiles += $";{basePath}_mainError.txt";
+ if (!File.Exists($"{basePath}_mainInfo.txt"))
+ missingFiles += $";{basePath}_mainInfo.txt";
+ if (!File.Exists($"{basePath}_volDesc.txt"))
+ missingFiles += $";{basePath}_volDesc.txt";
+
+ break;
+
+ default:
+ // Non-dumping commands will usually produce no output, so this is irrelevant
+ return true;
+ }
+
+ // Use the missing files list as an indicator
+ if (string.IsNullOrEmpty(missingFiles))
+ {
+ return true;
+ }
+ else
+ {
+ progress?.Report(Result.Failure($"The following files were missing: {missingFiles.TrimStart(';')}"));
+ return false;
+ }
+ }
+
+ ///
+ /// Generate a SubmissionInfo for the output files
+ ///
+ /// Base submission info to fill in specifics for
+ /// Base filename and path to use for checking
+ /// KnownSystem type representing the media
+ /// MediaType type representing the media
+ /// Drive representing the disc to get information from
+ ///
+ public override void GenerateSubmissionInfo(SubmissionInfo info, string basePath, KnownSystem? system, MediaType? type, Drive drive)
+ {
+ // Fill in the hash data
+ info.TracksAndWriteOffsets.ClrMameProData = GetDatfile(basePath + ".dat");
+
+ // Extract info based generically on MediaType
+ switch (type)
+ {
+ case MediaType.UMD:
+ info.Extras.PVD = GetPVD(basePath + "_mainInfo.txt") ?? "";
+
+ if (GetUMDAuxInfo(basePath + "_disc.txt", out string title, out DiscCategory? umdcat, out string umdversion, out string umdlayer, out long umdsize))
+ {
+ info.CommonDiscInfo.Title = title ?? "";
+ info.CommonDiscInfo.Category = umdcat ?? DiscCategory.Games;
+ info.VersionAndEditions.Version = umdversion ?? "";
+ info.SizeAndChecksums.Size = umdsize;
+
+ if (!string.IsNullOrWhiteSpace(umdlayer))
+ info.SizeAndChecksums.Layerbreak = Int64.Parse(umdlayer ?? "-1");
+ }
+
+ break;
+ }
+ }
+
+ #region Information Extraction Methods
+
+ ///
+ /// Get the proper datfile from the input file, if possible
+ ///
+ /// .dat file location
+ /// Relevant pieces of the datfile, null on error
+ private static string GetDatfile(string dat)
+ {
+ // If the file doesn't exist, we can't get info from it
+ if (!File.Exists(dat))
+ return null;
+
+ using (StreamReader sr = File.OpenText(dat))
+ {
+ try
+ {
+ // Make sure this file is a .dat
+ if (sr.ReadLine() != "")
+ return null;
+ if (sr.ReadLine() != "")
+ return null;
+
+ // Fast forward to the rom lines
+ while (!sr.ReadLine().TrimStart().StartsWith("Games
+ sr.ReadLine(); // Plextor
+
+ // Now that we're at the relevant entries, read each line in and concatenate
+ string pvd = "", line = sr.ReadLine().Trim();
+ while (line.StartsWith("
+ /// Get the PVD from the input file, if possible
+ ///
+ /// _mainInfo.txt file location
+ /// Newline-deliminated PVD if possible, null on error
+ private static string GetPVD(string mainInfo)
+ {
+ // If the file doesn't exist, we can't get info from it
+ if (!File.Exists(mainInfo))
+ return null;
+
+ using (StreamReader sr = File.OpenText(mainInfo))
+ {
+ try
+ {
+ // Make sure we're in the right sector
+ while (!sr.ReadLine().StartsWith("========== LBA[000016, 0x00010]: Main Channel ==========")) ;
+
+ // Fast forward to the PVD
+ while (!sr.ReadLine().StartsWith("0310")) ;
+
+ // Now that we're at the PVD, read each line in and concatenate
+ string pvd = "";
+ for (int i = 0; i < 6; i++)
+ pvd += sr.ReadLine() + "\n"; // 320-370
+
+ return pvd;
+ }
+ catch
+ {
+ // We don't care what the exception is right now
+ return null;
+ }
+ }
+ }
+
+ ///
+ /// Get the UMD auxiliary info from the outputted files, if possible
+ ///
+ /// _disc.txt file location
+ /// True on successful extraction of info, false otherwise
+ private static bool GetUMDAuxInfo(string disc, out string title, out DiscCategory? umdcat, out string umdversion, out string umdlayer, out long umdsize)
+ {
+ title = null; umdcat = null; umdversion = null; umdlayer = null; umdsize = -1;
+
+ // If the file doesn't exist, we can't get info from it
+ if (!File.Exists(disc))
+ return false;
+
+ using (StreamReader sr = File.OpenText(disc))
+ {
+ try
+ {
+ // Loop through everything to get the first instance of each required field
+ string line = string.Empty;
+ while (!sr.EndOfStream)
+ {
+ line = sr.ReadLine().Trim();
+
+ if (line.StartsWith("TITLE") && title == null)
+ title = line.Substring("TITLE: ".Length);
+ else if (line.StartsWith("DISC_VERSION") && umdversion == null)
+ umdversion = line.Split(' ')[1];
+ else if (line.StartsWith("pspUmdTypes"))
+ umdcat = GetUMDCategory(line.Split(' ')[1]);
+ else if (line.StartsWith("L0 length"))
+ umdlayer = line.Split(' ')[2];
+ else if (line.StartsWith("FileSize:"))
+ umdsize = Int64.Parse(line.Split(' ')[1]);
+ }
+
+ // If the L0 length is the size of the full disc, there's no layerbreak
+ if (Int64.Parse(umdlayer) * 2048 == umdsize)
+ umdlayer = null;
+
+ return true;
+ }
+ catch
+ {
+ // We don't care what the exception is right now
+ return false;
+ }
+ }
+ }
+
+ #endregion
+ }
+}
diff --git a/DICUI.Library/Utilities/Converters.cs b/DICUI.Library/Utilities/Converters.cs
index e5869e81..8c58dc49 100644
--- a/DICUI.Library/Utilities/Converters.cs
+++ b/DICUI.Library/Utilities/Converters.cs
@@ -484,6 +484,9 @@ namespace DICUI.Utilities
case InternalProgram.DCDumper:
return "DCDumper";
+ case InternalProgram.UmdImageCreator:
+ return "UmdImageCreator";
+
#endregion
case InternalProgram.NONE:
@@ -1298,7 +1301,7 @@ namespace DICUI.Utilities
case "umd":
case "umdcreator":
case "umdimagecreator":
- return InternalProgram.DiscImageCreator; // TODO: Make separate internally
+ return InternalProgram.UmdImageCreator;
default:
return InternalProgram.NONE;
diff --git a/DICUI.Library/Utilities/DumpEnvironment.cs b/DICUI.Library/Utilities/DumpEnvironment.cs
index 23d72986..0e64ebd7 100644
--- a/DICUI.Library/Utilities/DumpEnvironment.cs
+++ b/DICUI.Library/Utilities/DumpEnvironment.cs
@@ -208,6 +208,10 @@ namespace DICUI.Utilities
this.Parameters = null; // TODO: Create correct parameter type when supported
break;
+ case InternalProgram.UmdImageCreator:
+ this.Parameters = new UmdImageCreator.Parameters(parameters);
+ break;
+
// This should never happen, but it needs a fallback
default:
this.Parameters = new DiscImageCreator.Parameters(parameters);
@@ -245,6 +249,10 @@ namespace DICUI.Utilities
this.Parameters.ExecutablePath = null;
break;
+ case InternalProgram.UmdImageCreator:
+ this.Parameters.ExecutablePath = null;
+ break;
+
// This should never happen, but it needs a fallback
default:
this.InternalProgram = InternalProgram.DiscImageCreator;