2016-03-29 12:11:58 -07:00
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using System.IO;
|
|
|
|
|
|
using System.Xml;
|
2016-03-18 01:17:39 -07:00
|
|
|
|
|
2016-03-29 13:48:10 -07:00
|
|
|
|
namespace SabreTools.Helper
|
2016-03-18 01:17:39 -07:00
|
|
|
|
{
|
2016-03-29 14:49:03 -07:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Contains all remappings of known import classes
|
|
|
|
|
|
/// </summary>
|
2016-04-06 00:01:54 -07:00
|
|
|
|
public class Remapping
|
2016-03-18 01:17:39 -07:00
|
|
|
|
{
|
2016-04-09 00:34:37 -07:00
|
|
|
|
// Remapping classes represented by dictionaries (from, to)
|
2016-04-21 12:54:39 -07:00
|
|
|
|
public static Dictionary<string, string> Good = new Dictionary<string, string>();
|
2016-03-29 12:11:58 -07:00
|
|
|
|
public static Dictionary<string, string> MAME = new Dictionary<string, string>();
|
2016-04-07 12:37:23 -07:00
|
|
|
|
public static Dictionary<string, string> MaybeIntro = new Dictionary<string, string>();
|
2016-03-29 12:11:58 -07:00
|
|
|
|
public static Dictionary<string, string> NoIntro = new Dictionary<string, string>();
|
2016-04-06 15:45:33 -07:00
|
|
|
|
public static Dictionary<string, string> NonGood = new Dictionary<string, string>();
|
2016-03-29 12:11:58 -07:00
|
|
|
|
public static Dictionary<string, string> Redump = new Dictionary<string, string>();
|
|
|
|
|
|
public static Dictionary<string, string> TOSEC = new Dictionary<string, string>();
|
|
|
|
|
|
public static Dictionary<string, string> TruRip = new Dictionary<string, string>();
|
2016-03-18 01:17:39 -07:00
|
|
|
|
|
2016-04-09 00:34:37 -07:00
|
|
|
|
// Header skip classes represented by dictionaries (header, size)
|
|
|
|
|
|
public static Dictionary<string, int> A7800 = new Dictionary<string, int>();
|
|
|
|
|
|
public static Dictionary<string, int> FDS = new Dictionary<string, int>();
|
|
|
|
|
|
public static Dictionary<string, int> Lynx = new Dictionary<string, int>();
|
|
|
|
|
|
//public static Dictionary<string, int> N64 = new Dictionary<string, int>();
|
|
|
|
|
|
public static Dictionary<string, int> NES = new Dictionary<string, int>();
|
|
|
|
|
|
public static Dictionary<string, int> PCE = new Dictionary<string, int>();
|
2016-05-01 10:07:35 -07:00
|
|
|
|
public static Dictionary<string, int> PSID = new Dictionary<string, int>();
|
2016-04-09 00:34:37 -07:00
|
|
|
|
public static Dictionary<string, int> SNES = new Dictionary<string, int>();
|
2016-05-01 10:07:35 -07:00
|
|
|
|
public static Dictionary<string, int> SPC = new Dictionary<string, int>();
|
|
|
|
|
|
|
2016-04-09 00:34:37 -07:00
|
|
|
|
|
2016-03-29 14:49:03 -07:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Create all remappings to be used by the program
|
|
|
|
|
|
/// </summary>
|
2016-03-18 01:17:39 -07:00
|
|
|
|
public static void CreateRemappings()
|
|
|
|
|
|
{
|
2016-03-29 12:11:58 -07:00
|
|
|
|
// Create array of dictionary names
|
|
|
|
|
|
string[] remappings =
|
|
|
|
|
|
{
|
2016-04-21 12:54:39 -07:00
|
|
|
|
"Good", "MAME", "MaybeIntro", "NoIntro", "NonGood", "Redump", "TOSEC", "TruRip",
|
2016-03-29 12:11:58 -07:00
|
|
|
|
};
|
2016-03-18 01:17:39 -07:00
|
|
|
|
|
2016-03-29 12:11:58 -07:00
|
|
|
|
// Loop through and add all remappings
|
|
|
|
|
|
foreach (string remapping in remappings)
|
|
|
|
|
|
{
|
|
|
|
|
|
RemappingHelper(remapping);
|
|
|
|
|
|
}
|
2016-04-04 23:11:29 -07:00
|
|
|
|
}
|
2016-03-18 01:17:39 -07:00
|
|
|
|
|
2016-03-29 14:49:03 -07:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Create a remapping from XML
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="mapping">Name of the mapping to be populated</param>
|
2016-03-29 12:11:58 -07:00
|
|
|
|
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;
|
|
|
|
|
|
}
|
2016-03-18 01:17:39 -07:00
|
|
|
|
|
2016-03-29 12:11:58 -07:00
|
|
|
|
// Get the mappings parent node
|
|
|
|
|
|
XmlNode node = doc.FirstChild;
|
|
|
|
|
|
while (node.Name != "mappings")
|
|
|
|
|
|
{
|
|
|
|
|
|
node = node.NextSibling;
|
|
|
|
|
|
}
|
2016-03-18 01:17:39 -07:00
|
|
|
|
|
2016-04-21 14:12:14 -07:00
|
|
|
|
// If the node is empty, just return so it doesn't crash
|
|
|
|
|
|
if (!node.HasChildNodes)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2016-03-29 12:11:58 -07:00
|
|
|
|
// Get the first mapping node
|
|
|
|
|
|
node = node.FirstChild;
|
|
|
|
|
|
while (node.NodeType != XmlNodeType.Element && node.Name != "mapping")
|
|
|
|
|
|
{
|
|
|
|
|
|
node = node.NextSibling;
|
|
|
|
|
|
}
|
2016-03-18 01:17:39 -07:00
|
|
|
|
|
2016-03-29 12:11:58 -07:00
|
|
|
|
// Now read in the mappings
|
|
|
|
|
|
while (node != null && node.Name == "mapping")
|
|
|
|
|
|
{
|
|
|
|
|
|
switch (mapping)
|
|
|
|
|
|
{
|
2016-04-21 12:54:39 -07:00
|
|
|
|
case "Good":
|
|
|
|
|
|
Good.Add(node.Attributes["from"].Value, node.Attributes["to"].Value);
|
|
|
|
|
|
break;
|
2016-03-29 12:11:58 -07:00
|
|
|
|
case "MAME":
|
|
|
|
|
|
MAME.Add(node.Attributes["from"].Value, node.Attributes["to"].Value);
|
|
|
|
|
|
break;
|
2016-04-07 12:37:23 -07:00
|
|
|
|
case "MaybeIntro":
|
|
|
|
|
|
MaybeIntro.Add(node.Attributes["from"].Value, node.Attributes["to"].Value);
|
|
|
|
|
|
break;
|
2016-03-29 12:11:58 -07:00
|
|
|
|
case "NoIntro":
|
|
|
|
|
|
NoIntro.Add(node.Attributes["from"].Value, node.Attributes["to"].Value);
|
|
|
|
|
|
break;
|
2016-04-06 15:45:33 -07:00
|
|
|
|
case "NonGood":
|
|
|
|
|
|
NonGood.Add(node.Attributes["from"].Value, node.Attributes["to"].Value);
|
|
|
|
|
|
break;
|
2016-03-29 12:11:58 -07:00
|
|
|
|
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;
|
|
|
|
|
|
}
|
2016-03-18 01:17:39 -07:00
|
|
|
|
|
2016-03-29 12:11:58 -07:00
|
|
|
|
// Get the next node and skip over anything that's not an element
|
|
|
|
|
|
node = node.NextSibling;
|
2016-03-18 01:17:39 -07:00
|
|
|
|
|
2016-03-29 12:11:58 -07:00
|
|
|
|
if (node == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2016-03-18 01:17:39 -07:00
|
|
|
|
|
2016-03-29 12:11:58 -07:00
|
|
|
|
while (node.NodeType != XmlNodeType.Element && node.Name != "mapping")
|
|
|
|
|
|
{
|
|
|
|
|
|
node = node.NextSibling;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2016-04-09 00:34:37 -07:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Create all header mappings to be used by the program
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public static void CreateHeaderSkips()
|
|
|
|
|
|
{
|
|
|
|
|
|
// Create array of dictionary names
|
|
|
|
|
|
string[] skippers =
|
|
|
|
|
|
{
|
2016-05-01 10:07:35 -07:00
|
|
|
|
"a7800", "fds", "lynx", /* "n64", */ "nes", "pce", "psid", "snes", "spc",
|
2016-04-09 00:34:37 -07:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// Loop through and add all remappings
|
|
|
|
|
|
foreach (string skipper in skippers)
|
|
|
|
|
|
{
|
|
|
|
|
|
SkipperHelper(skipper);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Create a remapping from XML
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="skipper">Name of the header skipper to be populated</param>
|
|
|
|
|
|
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
|
2016-04-12 17:42:18 -07:00
|
|
|
|
node = node.SelectSingleNode("rule");
|
2016-04-09 00:34:37 -07:00
|
|
|
|
|
|
|
|
|
|
// 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
|
2016-04-12 18:11:43 -07:00
|
|
|
|
string header = (child.Attributes["offset"] != null && child.Attributes["offset"].Value != "0" ? "^.{" + (Convert.ToInt32(child.Attributes["offset"].Value, 16) * 2) + "}" : "^");
|
2016-04-09 00:34:37 -07:00
|
|
|
|
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;
|
2016-05-01 10:07:35 -07:00
|
|
|
|
case "psid":
|
|
|
|
|
|
PSID.Add(header, size);
|
|
|
|
|
|
break;
|
2016-04-09 00:34:37 -07:00
|
|
|
|
case "snes":
|
|
|
|
|
|
SNES.Add(header, size);
|
|
|
|
|
|
break;
|
2016-05-01 10:07:35 -07:00
|
|
|
|
case "spc":
|
|
|
|
|
|
SPC.Add(header, size);
|
|
|
|
|
|
break;
|
2016-04-09 00:34:37 -07:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 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;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2016-03-18 01:17:39 -07:00
|
|
|
|
}
|
|
|
|
|
|
}
|