Convert Headerer to use external header files

This commit is contained in:
Matt Nadareski
2016-04-09 00:34:37 -07:00
parent 6642a837a5
commit 8a266e9c07
4 changed files with 202 additions and 38 deletions

View File

@@ -17,7 +17,21 @@ namespace SabreTools
{ {
private static string _dbName = "Headerer.sqlite"; private static string _dbName = "Headerer.sqlite";
private static string _connectionString = "Data Source=" + _dbName + ";Version = 3;"; private static string _connectionString = "Data Source=" + _dbName + ";Version = 3;";
private static Dictionary<string, int> types;
/// <summary>
/// Possible detected header type
/// </summary>
private enum HeaderType
{
None = 0,
A7800,
FDS,
Lynx,
//N64,
NES,
PCE,
SNES,
}
/// <summary> /// <summary>
/// Start deheader operation with supplied parameters /// Start deheader operation with supplied parameters
@@ -27,15 +41,6 @@ namespace SabreTools
{ {
Console.Title = "Headerer " + Build.Version; Console.Title = "Headerer " + Build.Version;
// Type mapped to header size (in decimal bytes)
types = new Dictionary<string, int>();
types.Add("a7800", 128);
types.Add("fds", 16);
types.Add("lynx", 64);
types.Add("pce", 512);
types.Add("nes", 16);
types.Add("snes", 512);
// Ensure that the header database is set up // Ensure that the header database is set up
DBTools.EnsureDatabase(_dbName, _connectionString); DBTools.EnsureDatabase(_dbName, _connectionString);
@@ -131,38 +136,64 @@ namespace SabreTools
string header = BitConverter.ToString(hbin).Replace("-", string.Empty); string header = BitConverter.ToString(hbin).Replace("-", string.Empty);
// Determine the type of the file from the header, if possible // Determine the type of the file from the header, if possible
string type = ""; HeaderType type = HeaderType.None;
if (Regex.IsMatch(header, "^.{2}415441524937383030") || Regex.IsMatch(header, "^.{200}41435455414C20434152542044415441205354415254532048455245")) int headerSize = 0;
// Loop over the header types and see if there's a match
foreach (HeaderType test in Enum.GetValues(typeof(HeaderType)))
{ {
type = "a7800"; Dictionary<string, int> tempDict = new Dictionary<string, int>();
} switch (test)
else if (Regex.IsMatch(header, "^4644531A0[1-4]0000000000000000000000"))
{ {
type = "fds"; case HeaderType.A7800:
} tempDict = Remapping.A7800;
else if (Regex.IsMatch(header, "^4C594E58") || Regex.IsMatch(header, "^425339")) break;
{ case HeaderType.FDS:
type = "lynx"; tempDict = Remapping.FDS;
} break;
else if (Regex.IsMatch(header, "^4000000000000000AABB02")) case HeaderType.Lynx:
{ tempDict = Remapping.Lynx;
type = "pce"; break;
} case HeaderType.PCE:
else if (Regex.IsMatch(header, "^4E45531A")) tempDict = Remapping.PCE;
{ break;
type = "nes"; /*
} case HeaderType.N64:
else if (Regex.IsMatch(header, "^.{16}0000000000000000") || Regex.IsMatch(header, "^.{16}AABB040000000000") || Regex.IsMatch(header, "^.{16}535550455255464F")) // fig, smc, ufo tempDict = Remapping.N64;
{ break;
type = "snes"; */
case HeaderType.NES:
tempDict = Remapping.NES;
break;
case HeaderType.SNES:
tempDict = Remapping.SNES;
break;
} }
Console.WriteLine("File has header: " + (type != "")); // Loop over the dictionary and see if there are matches
foreach (KeyValuePair<string, int> entry in tempDict)
{
if (Regex.IsMatch(header, entry.Key))
{
type = test;
headerSize = entry.Value;
break;
}
}
if (type != "") // If we found something, break out
if (type != HeaderType.None)
{
break;
}
}
Console.WriteLine("File has header: " + (type != HeaderType.None));
if (type != HeaderType.None)
{ {
Console.WriteLine("Deteched header type: " + type); Console.WriteLine("Deteched header type: " + type);
int hs = types[type]; int hs = headerSize;
// Save header as string in the database // Save header as string in the database
string realhead = ""; string realhead = "";
@@ -206,7 +237,7 @@ namespace SabreTools
query = @"INSERT INTO data (sha1, header, type) VALUES ('" + query = @"INSERT INTO data (sha1, header, type) VALUES ('" +
BitConverter.ToString(sha1.Hash) + "', " + BitConverter.ToString(sha1.Hash) + "', " +
"'" + realhead + "', " + "'" + realhead + "', " +
"'" + type + "')"; "'" + type.ToString() + "')";
using (SQLiteConnection dbc = new SQLiteConnection(_connectionString)) using (SQLiteConnection dbc = new SQLiteConnection(_connectionString))
{ {
dbc.Open(); dbc.Open();

View File

@@ -89,6 +89,7 @@
<Content Include="Skippers\lynx.xml" /> <Content Include="Skippers\lynx.xml" />
<Content Include="Skippers\n64.xml" /> <Content Include="Skippers\n64.xml" />
<Content Include="Skippers\nes.xml" /> <Content Include="Skippers\nes.xml" />
<Content Include="Skippers\pce.xml" />
<Content Include="Skippers\snes.xml" /> <Content Include="Skippers\snes.xml" />
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

13
Deheader/Skippers/pce.xml Normal file
View File

@@ -0,0 +1,13 @@
<?xml version="1.0"?>
<detector>
<name>NEC TurboGrafx-16/PC-Engine</name>
<author>Matt Nadareski (darksabre76)</author>
<version>1.0</version>
<rule start_offset="200">
<data offset="0" value="4000000000000000AABB02"/>
</rule>
</detector>

View File

@@ -10,7 +10,7 @@ namespace SabreTools.Helper
/// </summary> /// </summary>
public class Remapping public class Remapping
{ {
// Remapping classes represented by dictionaries // Remapping classes represented by dictionaries (from, to)
public static Dictionary<string, string> MAME = new Dictionary<string, string>(); public static Dictionary<string, string> MAME = new Dictionary<string, string>();
public static Dictionary<string, string> MaybeIntro = new Dictionary<string, string>(); public static Dictionary<string, string> MaybeIntro = new Dictionary<string, string>();
public static Dictionary<string, string> NoIntro = new Dictionary<string, string>(); public static Dictionary<string, string> NoIntro = new Dictionary<string, string>();
@@ -19,6 +19,15 @@ namespace SabreTools.Helper
public static Dictionary<string, string> TOSEC = new Dictionary<string, string>(); public static Dictionary<string, string> TOSEC = new Dictionary<string, string>();
public static Dictionary<string, string> TruRip = new Dictionary<string, string>(); public static Dictionary<string, string> TruRip = new Dictionary<string, string>();
// 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>();
public static Dictionary<string, int> SNES = new Dictionary<string, int>();
/// <summary> /// <summary>
/// Create all remappings to be used by the program /// Create all remappings to be used by the program
/// </summary> /// </summary>
@@ -111,5 +120,115 @@ namespace SabreTools.Helper
} }
} }
} }
/// <summary>
/// Create all header mappings to be used by the program
/// </summary>
public static void CreateHeaderSkips()
{
// Create array of dictionary names
string[] skippers =
{
"a780", "fds", "lynx", /* "n64", */ "nes", "pce", "snes",
};
// 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
node = node.FirstChild;
while (node.NodeType != XmlNodeType.Element && node.Name != "rule")
{
node = node.NextSibling;
}
// 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) + "}" : "^");
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;
}
}
}
} }
} }