NesHawk - move BootGodDb to its own file
This commit is contained in:
parent
01584431c4
commit
7fb89aed18
|
@ -235,7 +235,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
// In order to allow late construction of this database, we hook up a delegate here to dearchive the data and provide it on demand
|
||||
// we could background thread this later instead if we wanted to be real clever
|
||||
NES.BootGodDB.GetDatabaseBytes = () =>
|
||||
BootGodDb.GetDatabaseBytes = () =>
|
||||
{
|
||||
string xmlPath = Path.Combine(PathUtils.GetExeDirectoryAbsolute(), "gamedb", "NesCarts.xml");
|
||||
string x7zPath = Path.Combine(PathUtils.GetExeDirectoryAbsolute(), "gamedb", "NesCarts.7z");
|
||||
|
|
|
@ -0,0 +1,150 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using BizHawk.Common;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Nintendo.NES
|
||||
{
|
||||
public class BootGodDb
|
||||
{
|
||||
static object staticsyncroot = new object();
|
||||
object syncroot = new object();
|
||||
|
||||
bool validate = true;
|
||||
|
||||
private readonly Bag<string, CartInfo> _sha1Table = new Bag<string, CartInfo>();
|
||||
|
||||
private static BootGodDb _instance;
|
||||
public static BootGodDb Instance
|
||||
{
|
||||
get { lock (staticsyncroot) { return _instance; } }
|
||||
}
|
||||
|
||||
private static Func<byte[]> _GetDatabaseBytes;
|
||||
|
||||
public static Func<byte[]> GetDatabaseBytes
|
||||
{
|
||||
set { lock (staticsyncroot) { _GetDatabaseBytes = value; } }
|
||||
}
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
lock (staticsyncroot)
|
||||
{
|
||||
if (_instance == null)
|
||||
_instance = new BootGodDb();
|
||||
}
|
||||
}
|
||||
|
||||
private int ParseSize(string str)
|
||||
{
|
||||
int temp = 0;
|
||||
if(validate) if (!str.EndsWith("k")) throw new Exception();
|
||||
int len=str.Length-1;
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
temp *= 10;
|
||||
temp += (str[i] - '0');
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
public BootGodDb()
|
||||
{
|
||||
//notes: there can be multiple each of prg,chr,wram,vram
|
||||
//we arent tracking the individual hashes yet.
|
||||
|
||||
//in anticipation of any slowness annoying people, and just for shits and giggles, i made a super fast parser
|
||||
int state=0;
|
||||
var xmlReader = XmlReader.Create(new MemoryStream(_GetDatabaseBytes()));
|
||||
CartInfo currCart = null;
|
||||
string currName = null;
|
||||
while (xmlReader.Read())
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case 0:
|
||||
if (xmlReader.NodeType == XmlNodeType.Element && xmlReader.Name == "game")
|
||||
{
|
||||
currName = xmlReader.GetAttribute("name");
|
||||
state = 1;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (xmlReader.NodeType == XmlNodeType.Element && xmlReader.Name == "board")
|
||||
{
|
||||
currCart.BoardType = xmlReader.GetAttribute("type");
|
||||
currCart.Pcb = xmlReader.GetAttribute("pcb");
|
||||
int mapper = int.Parse(xmlReader.GetAttribute("mapper"));
|
||||
if (validate && mapper > 255) throw new Exception("didnt expect mapper>255!");
|
||||
// we don't actually use this value at all; only the board name
|
||||
state = 3;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (xmlReader.NodeType == XmlNodeType.Element)
|
||||
{
|
||||
switch(xmlReader.Name)
|
||||
{
|
||||
case "prg":
|
||||
currCart.PrgSize += (short)ParseSize(xmlReader.GetAttribute("size"));
|
||||
break;
|
||||
case "chr":
|
||||
currCart.ChrSize += (short)ParseSize(xmlReader.GetAttribute("size"));
|
||||
break;
|
||||
case "vram":
|
||||
currCart.VramSize += (short)ParseSize(xmlReader.GetAttribute("size"));
|
||||
break;
|
||||
case "wram":
|
||||
currCart.WramSize += (short)ParseSize(xmlReader.GetAttribute("size"));
|
||||
if (xmlReader.GetAttribute("battery") != null)
|
||||
currCart.WramBattery = true;
|
||||
break;
|
||||
case "pad":
|
||||
currCart.PadH = byte.Parse(xmlReader.GetAttribute("h"));
|
||||
currCart.PadV = byte.Parse(xmlReader.GetAttribute("v"));
|
||||
break;
|
||||
case "chip":
|
||||
currCart.Chips.Add(xmlReader.GetAttribute("type"));
|
||||
break;
|
||||
}
|
||||
} else
|
||||
if (xmlReader.NodeType == XmlNodeType.EndElement && xmlReader.Name == "board")
|
||||
{
|
||||
state = 4;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if (xmlReader.NodeType == XmlNodeType.EndElement && xmlReader.Name == "cartridge")
|
||||
{
|
||||
_sha1Table[currCart.Sha1].Add(currCart);
|
||||
currCart = null;
|
||||
state = 5;
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
case 1:
|
||||
if (xmlReader.NodeType == XmlNodeType.Element && xmlReader.Name == "cartridge")
|
||||
{
|
||||
currCart = new CartInfo();
|
||||
currCart.System = xmlReader.GetAttribute("system");
|
||||
currCart.Sha1 = "sha1:" + xmlReader.GetAttribute("sha1");
|
||||
currCart.Name = currName;
|
||||
state = 2;
|
||||
}
|
||||
if (xmlReader.NodeType == XmlNodeType.EndElement && xmlReader.Name == "game")
|
||||
{
|
||||
currName = null;
|
||||
state = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} //end xmlreader loop
|
||||
}
|
||||
|
||||
public List<CartInfo> Identify(string sha1)
|
||||
{
|
||||
lock (syncroot) return _sha1Table[sha1];
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,19 +1,15 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using BizHawk.Common;
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
//TODO - could stringpool the bootgod DB for a pedantic optimization
|
||||
|
||||
//TODO - could stringpool the BootGod DB for a pedantic optimization
|
||||
namespace BizHawk.Emulation.Cores.Nintendo.NES
|
||||
{
|
||||
partial class NES
|
||||
{
|
||||
static List<Type> INESBoardImplementors = new List<Type>();
|
||||
|
||||
static INesBoard CreateBoardInstance(Type boardType)
|
||||
private static INesBoard CreateBoardInstance(Type boardType)
|
||||
{
|
||||
var board = (INesBoard)Activator.CreateInstance(boardType);
|
||||
lock (INESBoardImplementors)
|
||||
|
@ -30,7 +26,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
|||
|
||||
public string BoardName => Board.GetType().Name;
|
||||
|
||||
void BoardSystemHardReset()
|
||||
private void BoardSystemHardReset()
|
||||
{
|
||||
INesBoard newboard;
|
||||
// FDS and NSF have a unique activation setup
|
||||
|
@ -144,10 +140,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
|||
/// </summary>
|
||||
CartInfo IdentifyFromBootGodDB(IEnumerable<string> hash_sha1)
|
||||
{
|
||||
BootGodDB.Initialize();
|
||||
BootGodDb.Initialize();
|
||||
foreach (var hash in hash_sha1)
|
||||
{
|
||||
List<CartInfo> choices = BootGodDB.Instance.Identify(hash);
|
||||
List<CartInfo> choices = BootGodDb.Instance.Identify(hash);
|
||||
//pick the first board for this hash arbitrarily. it probably doesn't make a difference
|
||||
if (choices.Count != 0)
|
||||
return choices[0];
|
||||
|
@ -219,143 +215,5 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
|||
|
||||
return cart;
|
||||
}
|
||||
|
||||
public class BootGodDB
|
||||
{
|
||||
static object staticsyncroot = new object();
|
||||
object syncroot = new object();
|
||||
|
||||
bool validate = true;
|
||||
|
||||
private static BootGodDB _Instance;
|
||||
public static BootGodDB Instance
|
||||
{
|
||||
get { lock (staticsyncroot) { return _Instance; } }
|
||||
}
|
||||
private static Func<byte[]> _GetDatabaseBytes;
|
||||
public static Func<byte[]> GetDatabaseBytes
|
||||
{
|
||||
set { lock (staticsyncroot) { _GetDatabaseBytes = value; } }
|
||||
}
|
||||
public static void Initialize()
|
||||
{
|
||||
lock (staticsyncroot)
|
||||
{
|
||||
if (_Instance == null)
|
||||
_Instance = new BootGodDB();
|
||||
}
|
||||
}
|
||||
int ParseSize(string str)
|
||||
{
|
||||
int temp = 0;
|
||||
if(validate) if (!str.EndsWith("k")) throw new Exception();
|
||||
int len=str.Length-1;
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
temp *= 10;
|
||||
temp += (str[i] - '0');
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
public BootGodDB()
|
||||
{
|
||||
//notes: there can be multiple each of prg,chr,wram,vram
|
||||
//we arent tracking the individual hashes yet.
|
||||
|
||||
//in anticipation of any slowness annoying people, and just for shits and giggles, i made a super fast parser
|
||||
int state=0;
|
||||
var xmlreader = XmlReader.Create(new MemoryStream(_GetDatabaseBytes()));
|
||||
CartInfo currCart = null;
|
||||
string currName = null;
|
||||
while (xmlreader.Read())
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case 0:
|
||||
if (xmlreader.NodeType == XmlNodeType.Element && xmlreader.Name == "game")
|
||||
{
|
||||
currName = xmlreader.GetAttribute("name");
|
||||
state = 1;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (xmlreader.NodeType == XmlNodeType.Element && xmlreader.Name == "board")
|
||||
{
|
||||
currCart.BoardType = xmlreader.GetAttribute("type");
|
||||
currCart.Pcb = xmlreader.GetAttribute("pcb");
|
||||
int mapper = int.Parse(xmlreader.GetAttribute("mapper"));
|
||||
if (validate && mapper > 255) throw new Exception("didnt expect mapper>255!");
|
||||
// we don't actually use this value at all; only the board name
|
||||
state = 3;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (xmlreader.NodeType == XmlNodeType.Element)
|
||||
{
|
||||
switch(xmlreader.Name)
|
||||
{
|
||||
case "prg":
|
||||
currCart.PrgSize += (short)ParseSize(xmlreader.GetAttribute("size"));
|
||||
break;
|
||||
case "chr":
|
||||
currCart.ChrSize += (short)ParseSize(xmlreader.GetAttribute("size"));
|
||||
break;
|
||||
case "vram":
|
||||
currCart.VramSize += (short)ParseSize(xmlreader.GetAttribute("size"));
|
||||
break;
|
||||
case "wram":
|
||||
currCart.WramSize += (short)ParseSize(xmlreader.GetAttribute("size"));
|
||||
if (xmlreader.GetAttribute("battery") != null)
|
||||
currCart.WramBattery = true;
|
||||
break;
|
||||
case "pad":
|
||||
currCart.PadH = byte.Parse(xmlreader.GetAttribute("h"));
|
||||
currCart.PadV = byte.Parse(xmlreader.GetAttribute("v"));
|
||||
break;
|
||||
case "chip":
|
||||
currCart.Chips.Add(xmlreader.GetAttribute("type"));
|
||||
break;
|
||||
}
|
||||
} else
|
||||
if (xmlreader.NodeType == XmlNodeType.EndElement && xmlreader.Name == "board")
|
||||
{
|
||||
state = 4;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if (xmlreader.NodeType == XmlNodeType.EndElement && xmlreader.Name == "cartridge")
|
||||
{
|
||||
sha1_table[currCart.Sha1].Add(currCart);
|
||||
currCart = null;
|
||||
state = 5;
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
case 1:
|
||||
if (xmlreader.NodeType == XmlNodeType.Element && xmlreader.Name == "cartridge")
|
||||
{
|
||||
currCart = new CartInfo();
|
||||
currCart.System = xmlreader.GetAttribute("system");
|
||||
currCart.Sha1 = "sha1:" + xmlreader.GetAttribute("sha1");
|
||||
currCart.Name = currName;
|
||||
state = 2;
|
||||
}
|
||||
if (xmlreader.NodeType == XmlNodeType.EndElement && xmlreader.Name == "game")
|
||||
{
|
||||
currName = null;
|
||||
state = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} //end xmlreader loop
|
||||
}
|
||||
|
||||
Bag<string, CartInfo> sha1_table = new Bag<string, CartInfo>();
|
||||
|
||||
public List<CartInfo> Identify(string sha1)
|
||||
{
|
||||
lock (syncroot) return sha1_table[sha1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
|||
SyncSettings = (NESSyncSettings)syncSettings ?? new NESSyncSettings();
|
||||
ControllerSettings = SyncSettings.Controls;
|
||||
|
||||
BootGodDB.Initialize();
|
||||
BootGodDb.Initialize();
|
||||
videoProvider = new MyVideoProvider(this);
|
||||
Init(game, rom, fdsBios);
|
||||
if (Board is FDS fds)
|
||||
|
@ -86,7 +86,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
|||
|
||||
private NES()
|
||||
{
|
||||
BootGodDB.Initialize();
|
||||
BootGodDb.Initialize();
|
||||
}
|
||||
|
||||
public void WriteLogTimestamp()
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
using BizHawk.Common;
|
||||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Emulation.Cores.Nintendo.NES;
|
||||
using BizHawk.BizInvoke;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Consoles.Nintendo.QuickNES
|
||||
|
@ -20,7 +22,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.QuickNES
|
|||
singleInstance: false)]
|
||||
[ServiceNotApplicable(new[] { typeof(IDriveLight) })]
|
||||
public partial class QuickNES : IEmulator, IVideoProvider, ISoundProvider, ISaveRam, IInputPollable, IBoardInfo, IVideoLogicalOffsets,
|
||||
IStatable, IDebuggable, ISettable<QuickNES.QuickNESSettings, QuickNES.QuickNESSyncSettings>, Cores.Nintendo.NES.INESPPUViewable
|
||||
IStatable, IDebuggable, ISettable<QuickNES.QuickNESSettings, QuickNES.QuickNESSyncSettings>, INESPPUViewable
|
||||
{
|
||||
static QuickNES()
|
||||
{
|
||||
|
@ -252,11 +254,11 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.QuickNES
|
|||
void ComputeBootGod()
|
||||
{
|
||||
// inefficient, sloppy, etc etc
|
||||
Emulation.Cores.Nintendo.NES.NES.BootGodDB.Initialize();
|
||||
BootGodDb.Initialize();
|
||||
var chrrom = _memoryDomains["CHR VROM"];
|
||||
var prgrom = _memoryDomains["PRG ROM"];
|
||||
|
||||
var ms = new System.IO.MemoryStream();
|
||||
var ms = new MemoryStream();
|
||||
for (int i = 0; i < prgrom.Size; i++)
|
||||
ms.WriteByte(prgrom.PeekByte(i));
|
||||
if (chrrom != null)
|
||||
|
@ -273,7 +275,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.QuickNES
|
|||
}
|
||||
|
||||
sha1 = "sha1:" + sha1; // huh?
|
||||
var carts = Emulation.Cores.Nintendo.NES.NES.BootGodDB.Instance.Identify(sha1);
|
||||
var carts = BootGodDb.Instance.Identify(sha1);
|
||||
|
||||
if (carts.Count > 0)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue