using System; using System.Collections.Generic; using System.IO; using System.Xml; namespace SabreTools.Helper { /// /// Contains all remappings of known import classes /// public class Remapping { // Remapping classes represented by dictionaries (from, to) public static Dictionary MAME = new Dictionary(); public static Dictionary MaybeIntro = new Dictionary(); public static Dictionary NoIntro = new Dictionary(); public static Dictionary NonGood = new Dictionary(); public static Dictionary Redump = new Dictionary(); public static Dictionary TOSEC = new Dictionary(); public static Dictionary TruRip = new Dictionary(); // Header skip classes represented by dictionaries (header, size) public static Dictionary A7800 = new Dictionary(); public static Dictionary FDS = new Dictionary(); public static Dictionary Lynx = new Dictionary(); //public static Dictionary N64 = new Dictionary(); public static Dictionary NES = new Dictionary(); public static Dictionary PCE = new Dictionary(); public static Dictionary SNES = new Dictionary(); /// /// Create all remappings to be used by the program /// public static void CreateRemappings() { // Create array of dictionary names string[] remappings = { "MAME", "MaybeIntro", "NoIntro", "NonGood", "Redump", "TOSEC", "TruRip", }; // Loop through and add all remappings foreach (string remapping in remappings) { RemappingHelper(remapping); } } /// /// Create a remapping from XML /// /// Name of the mapping to be populated private static void RemappingHelper(string mapping) { // Read in remapping from file XmlDocument doc = new XmlDocument(); try { doc.LoadXml(File.ReadAllText("Mappings/" + mapping + ".xml")); } catch (XmlException ex) { Console.WriteLine(mapping + " remappings could not be loaded! " + ex.ToString()); return; } // Get the mappings parent node XmlNode node = doc.FirstChild; while (node.Name != "mappings") { node = node.NextSibling; } // Get the first mapping node node = node.FirstChild; while (node.NodeType != XmlNodeType.Element && node.Name != "mapping") { node = node.NextSibling; } // Now read in the mappings while (node != null && node.Name == "mapping") { switch (mapping) { case "MAME": MAME.Add(node.Attributes["from"].Value, node.Attributes["to"].Value); break; case "MaybeIntro": MaybeIntro.Add(node.Attributes["from"].Value, node.Attributes["to"].Value); break; case "NoIntro": NoIntro.Add(node.Attributes["from"].Value, node.Attributes["to"].Value); break; case "NonGood": NonGood.Add(node.Attributes["from"].Value, node.Attributes["to"].Value); break; case "Redump": Redump.Add(node.Attributes["from"].Value, node.Attributes["to"].Value); break; case "TOSEC": TOSEC.Add(node.Attributes["from"].Value, node.Attributes["to"].Value); break; case "TruRip": TruRip.Add(node.Attributes["from"].Value, node.Attributes["to"].Value); break; } // Get the next node and skip over anything that's not an element node = node.NextSibling; if (node == null) { break; } while (node.NodeType != XmlNodeType.Element && node.Name != "mapping") { node = node.NextSibling; } } } /// /// Create all header mappings to be used by the program /// public static void CreateHeaderSkips() { // Create array of dictionary names string[] skippers = { "a7800", "fds", "lynx", /* "n64", */ "nes", "pce", "snes", }; // Loop through and add all remappings foreach (string skipper in skippers) { SkipperHelper(skipper); } } /// /// Create a remapping from XML /// /// Name of the header skipper to be populated private static void SkipperHelper(string skipper) { // Read in remapping from file XmlDocument doc = new XmlDocument(); try { doc.LoadXml(File.ReadAllText("Skippers/" + skipper + ".xml")); } catch (XmlException ex) { Console.WriteLine(skipper + " header skippers could not be loaded! " + ex.ToString()); return; } // Get the detector parent node XmlNode node = doc.FirstChild; while (node.Name != "detector") { node = node.NextSibling; } // Get the first rule node node = node.SelectSingleNode("rule"); // Now read in the rules while (node != null && node.Name == "rule") { // Size is the offset for the actual game data int size = (node.Attributes["start_offset"] != null ? Convert.ToInt32(node.Attributes["start_offset"].Value, 16) : 0); // Each rule set can have more than one data rule. We can't really use multiples right now if (node.SelectNodes("data") != null) { foreach (XmlNode child in node.SelectNodes("data")) { // Add an offset to the match if one exists string header = (child.Attributes["offset"] != null && child.Attributes["offset"].Value != "0" ? "^.{" + (Convert.ToInt32(child.Attributes["offset"].Value, 16) * 2) + "}" : "^"); header += child.Attributes["value"].Value; // Now add the header and value to the appropriate skipper dictionary switch (skipper) { case "a7800": A7800.Add(header, size); break; case "fds": FDS.Add(header, size); break; case "lynx": Lynx.Add(header, size); break; /* case "n64": N64.Add(header, size); break; */ case "nes": NES.Add(header, size); break; case "pce": PCE.Add(header, size); break; case "snes": SNES.Add(header, size); break; } } } // Get the next node and skip over anything that's not an element node = node.NextSibling; if (node == null) { break; } while (node.NodeType != XmlNodeType.Element && node.Name != "rule") { node = node.NextSibling; } } } } }