diff --git a/SabreTools.Library/DatFiles/ClrMamePro.cs b/SabreTools.Library/DatFiles/ClrMamePro.cs
index e0fd9a35..c6265923 100644
--- a/SabreTools.Library/DatFiles/ClrMamePro.cs
+++ b/SabreTools.Library/DatFiles/ClrMamePro.cs
@@ -59,561 +59,6 @@ namespace SabreTools.Library.DatFiles
Encoding enc = Utilities.GetEncoding(filename);
StreamReader sr = new StreamReader(Utilities.TryOpenRead(filename), enc);
- bool block = false, superdat = false, containsItems = false;
- string blockname = "", tempgamename = "", gamedesc = "", cloneof = "",
- romof = "", sampleof = "", year = "", manufacturer = "";
- while (!sr.EndOfStream)
- {
- string line = sr.ReadLine();
-
- // Comments in CMP DATs start with a #
- if (line.Trim().StartsWith("#"))
- {
- continue;
- }
-
- // If the line is the header or a game
- if (Regex.IsMatch(line, Constants.HeaderPatternCMP))
- {
- GroupCollection gc = Regex.Match(line, Constants.HeaderPatternCMP).Groups;
-
- if (gc[1].Value == "clrmamepro" || gc[1].Value == "romvault" || gc[1].Value.ToLowerInvariant() == "doscenter")
- {
- blockname = "header";
- }
-
- block = true;
- containsItems = false;
- }
-
- // If the line is a rom-like item and we're in a block
- else if ((line.Trim().StartsWith("rom (")
- || line.Trim().StartsWith("disk (")
- || line.Trim().StartsWith("file (")
- || (line.Trim().StartsWith("sample") && !line.Trim().StartsWith("sampleof"))
- ) && block)
- {
- containsItems = true;
- ItemType temptype = ItemType.Rom;
- if (line.Trim().StartsWith("rom ("))
- {
- temptype = ItemType.Rom;
- }
- else if (line.Trim().StartsWith("disk ("))
- {
- temptype = ItemType.Disk;
- }
- else if (line.Trim().StartsWith("file ("))
- {
- temptype = ItemType.Rom;
- }
- else if (line.Trim().StartsWith("sample"))
- {
- temptype = ItemType.Sample;
- }
-
- // Create the proper DatItem based on the type
- DatItem item = Utilities.GetDatItem(temptype);
-
- // Then populate it with information
- item.MachineName = tempgamename;
- item.MachineDescription = gamedesc;
- item.CloneOf = cloneof;
- item.RomOf = romof;
- item.SampleOf = sampleof;
- item.Manufacturer = manufacturer;
- item.Year = year;
-
- item.SystemID = sysid;
- item.SourceID = srcid;
-
- // If we have a sample, treat it special
- if (temptype == ItemType.Sample)
- {
- line = line.Trim().Remove(0, 6).Trim().Replace("\"", ""); // Remove "sample" from the input string
- item.Name = line;
-
- // Now process and add the sample
- ParseAddHelper(item, clean, remUnicode);
-
- continue;
- }
-
- // Get the line split by spaces and quotes
- string[] gc = Utilities.SplitLineAsCMP(line);
-
- // Special cases for DOSCenter DATs only because of how the lines are arranged
- if (line.Trim().StartsWith("file ("))
- {
- // Loop over the specifics
- for (int i = 0; i < gc.Length; i++)
- {
- // Names are not quoted, for some stupid reason
- if (gc[i] == "name")
- {
- // Get the name in order until we find the next flag
- while (++i < gc.Length && gc[i] != "size" && gc[i] != "date" && gc[i] != "crc" && gc[i] != "md5"
- && gc[i] != "sha1" && gc[i] != "sha256" && gc[i] != "sha384" && gc[i] != "sha512")
- {
- item.Name += " " + gc[i];
- }
-
- // Perform correction
- item.Name = item.Name.TrimStart();
- i--;
- }
-
- // Get the size from the next part
- else if (gc[i] == "size")
- {
- long tempsize = -1;
- if (!Int64.TryParse(gc[++i], out tempsize))
- {
- tempsize = 0;
- }
- ((Rom)item).Size = tempsize;
- }
-
- // Get the date from the next part
- else if (gc[i] == "date")
- {
- ((Rom)item).Date = gc[++i].Replace("\"", "") + " " + gc[++i].Replace("\"", "");
- }
-
- // Get the CRC from the next part
- else if (gc[i] == "crc")
- {
- ((Rom)item).CRC = gc[++i].Replace("\"", "").ToLowerInvariant();
- }
-
- // Get the MD5 from the next part
- else if (gc[i] == "md5")
- {
- ((Rom)item).MD5 = gc[++i].Replace("\"", "").ToLowerInvariant();
- }
-
- // Get the SHA1 from the next part
- else if (gc[i] == "sha1")
- {
- ((Rom)item).SHA1 = gc[++i].Replace("\"", "").ToLowerInvariant();
- }
-
- // Get the SHA256 from the next part
- else if (gc[i] == "sha256")
- {
- ((Rom)item).SHA256 = gc[++i].Replace("\"", "").ToLowerInvariant();
- }
-
- // Get the SHA384 from the next part
- else if (gc[i] == "sha384")
- {
- ((Rom)item).SHA384 = gc[++i].Replace("\"", "").ToLowerInvariant();
- }
-
- // Get the SHA512 from the next part
- else if (gc[i] == "sha512")
- {
- ((Rom)item).SHA512 = gc[++i].Replace("\"", "").ToLowerInvariant();
- }
- }
-
- // Now process and add the rom
- ParseAddHelper(item, clean, remUnicode);
- continue;
- }
-
- // Loop over all attributes normally and add them if possible
- for (int i = 0; i < gc.Length; i++)
- {
- // Look at the current item and use it if possible
- string quoteless = gc[i].Replace("\"", "");
- switch (quoteless)
- {
- //If the item is empty, we automatically skip it because it's a fluke
- case "":
- continue;
-
- // Special cases for standalone item statuses
- case "baddump":
- if (item.Type == ItemType.Rom)
- {
- ((Rom)item).ItemStatus = ItemStatus.BadDump;
- }
- else if (item.Type == ItemType.Disk)
- {
- ((Disk)item).ItemStatus = ItemStatus.BadDump;
- }
- break;
- case "good":
- if (item.Type == ItemType.Rom)
- {
- ((Rom)item).ItemStatus = ItemStatus.Good;
- }
- else if (item.Type == ItemType.Disk)
- {
- ((Disk)item).ItemStatus = ItemStatus.Good;
- }
- break;
- case "nodump":
- if (item.Type == ItemType.Rom)
- {
- ((Rom)item).ItemStatus = ItemStatus.Nodump;
- }
- else if (item.Type == ItemType.Disk)
- {
- ((Disk)item).ItemStatus = ItemStatus.Nodump;
- }
- break;
- case "verified":
- if (item.Type == ItemType.Rom)
- {
- ((Rom)item).ItemStatus = ItemStatus.Verified;
- }
- else if (item.Type == ItemType.Disk)
- {
- ((Disk)item).ItemStatus = ItemStatus.Verified;
- }
- break;
-
- // Regular attributes
- case "name":
- quoteless = gc[++i].Replace("\"", "");
- item.Name = quoteless;
- break;
- case "size":
- if (item.Type == ItemType.Rom)
- {
- quoteless = gc[++i].Replace("\"", "");
- if (Int64.TryParse(quoteless, out long size))
- {
- ((Rom)item).Size = size;
- }
- else
- {
- ((Rom)item).Size = -1;
- }
- }
- break;
- case "crc":
- if (item.Type == ItemType.Rom)
- {
- quoteless = gc[++i].Replace("\"", "");
- ((Rom)item).CRC = quoteless.ToLowerInvariant();
- }
- break;
- case "md5":
- if (item.Type == ItemType.Rom)
- {
- quoteless = gc[++i].Replace("\"", "");
- ((Rom)item).MD5 = quoteless.ToLowerInvariant();
- }
- else if (item.Type == ItemType.Disk)
- {
- i++;
- quoteless = gc[i].Replace("\"", "");
- ((Disk)item).MD5 = quoteless.ToLowerInvariant();
- }
- break;
- case "sha1":
- if (item.Type == ItemType.Rom)
- {
- quoteless = gc[++i].Replace("\"", "");
- ((Rom)item).SHA1 = quoteless.ToLowerInvariant();
- }
- else if (item.Type == ItemType.Disk)
- {
- quoteless = gc[++i].Replace("\"", "");
- ((Disk)item).SHA1 = quoteless.ToLowerInvariant();
- }
- break;
- case "sha256":
- if (item.Type == ItemType.Rom)
- {
- quoteless = gc[++i].Replace("\"", "");
- ((Rom)item).SHA256 = quoteless.ToLowerInvariant();
- }
- else if (item.Type == ItemType.Disk)
- {
- quoteless = gc[++i].Replace("\"", "");
- ((Disk)item).SHA256 = quoteless.ToLowerInvariant();
- }
- break;
- case "sha384":
- if (item.Type == ItemType.Rom)
- {
- quoteless = gc[++i].Replace("\"", "");
- ((Rom)item).SHA384 = quoteless.ToLowerInvariant();
- }
- else if (item.Type == ItemType.Disk)
- {
- quoteless = gc[++i].Replace("\"", "");
- ((Disk)item).SHA384 = quoteless.ToLowerInvariant();
- }
- break;
- case "sha512":
- if (item.Type == ItemType.Rom)
- {
- quoteless = gc[++i].Replace("\"", "");
- ((Rom)item).SHA512 = quoteless.ToLowerInvariant();
- }
- else if (item.Type == ItemType.Disk)
- {
- quoteless = gc[++i].Replace("\"", "");
- ((Disk)item).SHA512 = quoteless.ToLowerInvariant();
- }
- break;
- case "status":
- case "flags":
- quoteless = gc[++i].Replace("\"", "");
- if (quoteless.ToLowerInvariant() == "good")
- {
- if (item.Type == ItemType.Rom)
- {
- ((Rom)item).ItemStatus = ItemStatus.Good;
- }
- else if (item.Type == ItemType.Disk)
- {
- ((Disk)item).ItemStatus = ItemStatus.Good;
- }
- }
- else if (quoteless.ToLowerInvariant() == "baddump")
- {
- if (item.Type == ItemType.Rom)
- {
- ((Rom)item).ItemStatus = ItemStatus.BadDump;
- }
- else if (item.Type == ItemType.Disk)
- {
- ((Disk)item).ItemStatus = ItemStatus.BadDump;
- }
- }
- else if (quoteless.ToLowerInvariant() == "nodump")
- {
- if (item.Type == ItemType.Rom)
- {
- ((Rom)item).ItemStatus = ItemStatus.Nodump;
- }
- else if (item.Type == ItemType.Disk)
- {
- ((Disk)item).ItemStatus = ItemStatus.Nodump;
- }
- }
- else if (quoteless.ToLowerInvariant() == "verified")
- {
- if (item.Type == ItemType.Rom)
- {
- ((Rom)item).ItemStatus = ItemStatus.Verified;
- }
- else if (item.Type == ItemType.Disk)
- {
- ((Disk)item).ItemStatus = ItemStatus.Verified;
- }
- }
- break;
- case "date":
- if (item.Type == ItemType.Rom)
- {
- // If we have quotes in the next item, assume only one item
- if (gc[i + 1].Contains("\""))
- {
- quoteless = gc[++i].Replace("\"", "");
- }
- // Otherwise, we assume we need to read the next two items
- else
- {
- quoteless = gc[++i].Replace("\"", "") + " " + gc[++i].Replace("\"", "");
- }
- ((Rom)item).Date = quoteless;
- }
- break;
- }
- }
-
- // Now process and add the rom
- ParseAddHelper(item, clean, remUnicode);
- }
-
- // If the line is anything but a rom or disk and we're in a block
- else if (Regex.IsMatch(line, Constants.ItemPatternCMP) && block)
- {
- GroupCollection gc = Regex.Match(line, Constants.ItemPatternCMP).Groups;
-
- if (blockname != "header")
- {
- string itemval = gc[2].Value.Replace("\"", "");
- switch (gc[1].Value)
- {
- case "name":
- tempgamename = (itemval.ToLowerInvariant().EndsWith(".zip") ? itemval.Remove(itemval.Length - 4) : itemval);
- break;
- case "description":
- gamedesc = itemval;
- break;
- case "romof":
- romof = itemval;
- break;
- case "cloneof":
- cloneof = itemval;
- break;
- case "year":
- year = itemval;
- break;
- case "manufacturer":
- manufacturer = itemval;
- break;
- case "sampleof":
- sampleof = itemval;
- break;
- }
- }
- else
- {
- string itemval = gc[2].Value.Replace("\"", "");
-
- if (line.Trim().StartsWith("Name:"))
- {
- Name = (String.IsNullOrWhiteSpace(Name) ? line.Substring(6) : Name);
- superdat = superdat || itemval.Contains(" - SuperDAT");
- if (keep && superdat)
- {
- Type = (String.IsNullOrWhiteSpace(Type) ? "SuperDAT" : Type);
- }
- continue;
- }
-
- switch (gc[1].Value)
- {
- case "name":
- case "Name:":
- Name = (String.IsNullOrWhiteSpace(Name) ? itemval : Name);
- superdat = superdat || itemval.Contains(" - SuperDAT");
- if (keep && superdat)
- {
- Type = (String.IsNullOrWhiteSpace(Type) ? "SuperDAT" : Type);
- }
- break;
- case "description":
- case "Description:":
- Description = (String.IsNullOrWhiteSpace(Description) ? itemval : Description);
- break;
- case "rootdir":
- RootDir = (String.IsNullOrWhiteSpace(RootDir) ? itemval : RootDir);
- break;
- case "category":
- Category = (String.IsNullOrWhiteSpace(Category) ? itemval : Category);
- break;
- case "version":
- case "Version:":
- Version = (String.IsNullOrWhiteSpace(Version) ? itemval : Version);
- break;
- case "date":
- case "Date:":
- Date = (String.IsNullOrWhiteSpace(Date) ? itemval : Date);
- break;
- case "author":
- case "Author:":
- Author = (String.IsNullOrWhiteSpace(Author) ? itemval : Author);
- break;
- case "email":
- Email = (String.IsNullOrWhiteSpace(Email) ? itemval : Email);
- break;
- case "homepage":
- case "Homepage:":
- Homepage = (String.IsNullOrWhiteSpace(Homepage) ? itemval : Homepage);
- break;
- case "url":
- Url = (String.IsNullOrWhiteSpace(Url) ? itemval : Url);
- break;
- case "comment":
- case "Comment:":
- Comment = (String.IsNullOrWhiteSpace(Comment) ? itemval : Comment);
- break;
- case "header":
- Header = (String.IsNullOrWhiteSpace(Header) ? itemval : Header);
- break;
- case "type":
- Type = (String.IsNullOrWhiteSpace(Type) ? itemval : Type);
- superdat = superdat || itemval.Contains("SuperDAT");
- break;
- case "forcemerging":
- if (ForceMerging == ForceMerging.None)
- {
- ForceMerging = Utilities.GetForceMerging(itemval);
- }
- break;
- case "forcezipping":
- if (ForcePacking == ForcePacking.None)
- {
- ForcePacking = Utilities.GetForcePacking(itemval);
- }
- break;
- case "forcepacking":
- if (ForcePacking == ForcePacking.None)
- {
- ForcePacking = Utilities.GetForcePacking(itemval);
- }
- break;
- }
- }
- }
-
- // If we find an end bracket that's not associated with anything else, the block is done
- else if (Regex.IsMatch(line, Constants.EndPatternCMP) && block)
- {
- // If no items were found for this machine, add a Blank placeholder
- if (!containsItems)
- {
- Blank blank = new Blank()
- {
- MachineName = tempgamename,
- MachineDescription = gamedesc,
- CloneOf = cloneof,
- RomOf = romof,
- SampleOf = sampleof,
- Manufacturer = manufacturer,
- Year = year,
-
- SystemID = sysid,
- SourceID = srcid,
- };
-
- // Now process and add the rom
- ParseAddHelper(blank, clean, remUnicode);
- }
-
- block = false; containsItems = false;
- blockname = ""; tempgamename = ""; gamedesc = ""; cloneof = "";
- romof = ""; sampleof = ""; year = ""; manufacturer = "";
- }
- }
-
- sr.Dispose();
- }
-
- ///
- /// Parse a ClrMamePro DAT and return all found games and roms within
- ///
- /// Name of the file to be parsed
- /// System ID for the DAT
- /// Source ID for the DAT
- /// True if full pathnames are to be kept, false otherwise (default)
- /// True if game names are sanitized, false otherwise (default)
- /// True if we should remove non-ASCII characters from output, false otherwise (default)
- public void ParseFileStripped(
- // Standard Dat parsing
- string filename,
- int sysid,
- int srcid,
-
- // Miscellaneous
- bool keep,
- bool clean,
- bool remUnicode)
- {
- // Open a file reader
- Encoding enc = Utilities.GetEncoding(filename);
- StreamReader sr = new StreamReader(Utilities.TryOpenRead(filename), enc);
-
while (!sr.EndOfStream)
{
string line = sr.ReadLine();
@@ -628,18 +73,20 @@ namespace SabreTools.Library.DatFiles
if (Regex.IsMatch(line, Constants.HeaderPatternCMP))
{
GroupCollection gc = Regex.Match(line, Constants.HeaderPatternCMP).Groups;
+ string normalizedValue = gc[1].Value.ToLowerInvariant();
// If we have a known header
- if (gc[1].Value == "clrmamepro"
- || gc[1].Value == "romvault"
- || gc[1].Value.ToLowerInvariant() == "doscenter")
+ if (normalizedValue == "clrmamepro"
+ || normalizedValue == "romvault"
+ || normalizedValue == "doscenter")
{
ReadHeader(sr, keep);
}
// If we have a known set type
- else if (gc[1].Value == "set"
- || gc[1].Value == "game"
- || gc[1].Value == "machine")
+ else if (normalizedValue == "set" // Used by the most ancient DATs
+ || normalizedValue == "game" // Used by most CMP DATs
+ || normalizedValue == "machine" // Possibly used by MAME CMP DATs
+ || normalizedValue == "resource") // Used by some other DATs to denote a BIOS set
{
ReadSet(sr, filename, sysid, srcid, keep, clean, remUnicode);
}
@@ -654,7 +101,6 @@ namespace SabreTools.Library.DatFiles
///
/// StreamReader to use to parse the header
/// True if full pathnames are to be kept, false otherwise (default)
- /// TODO: Make sure this only is called if the block is "clrmamepro", "doscenter", "romcenter"
private void ReadHeader(StreamReader reader, bool keep)
{
bool superdat = false;
@@ -787,7 +233,6 @@ namespace SabreTools.Library.DatFiles
/// True if full pathnames are to be kept, false otherwise (default)
/// True if game names are sanitized, false otherwise (default)
/// True if we should remove non-ASCII characters from output, false otherwise (default)
- /// TODO: Make sure this is only called if the block is "set", "game", "machine"
private void ReadSet(
StreamReader reader,