diff --git a/src/BizHawk.Client.EmuHawk/MainForm.cs b/src/BizHawk.Client.EmuHawk/MainForm.cs index 8a8bd4c108..20f9f97e5d 100644 --- a/src/BizHawk.Client.EmuHawk/MainForm.cs +++ b/src/BizHawk.Client.EmuHawk/MainForm.cs @@ -172,113 +172,115 @@ namespace BizHawk.Client.EmuHawk return new CoreComm(ShowMessageCoreComm, NotifyCoreComm, cfp, prefs); } + void SetImages() + { + OpenRomMenuItem.Image = Properties.Resources.OpenFile; + RecentRomSubMenu.Image = Properties.Resources.Recent; + CloseRomMenuItem.Image = Properties.Resources.Close; + PreviousSlotMenuItem.Image = Properties.Resources.MoveLeft; + NextSlotMenuItem.Image = Properties.Resources.MoveRight; + ReadonlyMenuItem.Image = Properties.Resources.ReadOnly; + RecentMovieSubMenu.Image = Properties.Resources.Recent; + RecordMovieMenuItem.Image = Properties.Resources.RecordHS; + PlayMovieMenuItem.Image = Properties.Resources.Play; + StopMovieMenuItem.Image = Properties.Resources.Stop; + PlayFromBeginningMenuItem.Image = Properties.Resources.restart; + ImportMoviesMenuItem.Image = Properties.Resources.Import; + SaveMovieMenuItem.Image = Properties.Resources.SaveAs; + SaveMovieAsMenuItem.Image = Properties.Resources.SaveAs; + StopMovieWithoutSavingMenuItem.Image = Properties.Resources.Stop; + RecordAVMenuItem.Image = Properties.Resources.RecordHS; + ConfigAndRecordAVMenuItem.Image = Properties.Resources.AVI; + StopAVIMenuItem.Image = Properties.Resources.Stop; + ScreenshotMenuItem.Image = Properties.Resources.camera; + PauseMenuItem.Image = Properties.Resources.Pause; + RebootCoreMenuItem.Image = Properties.Resources.reboot; + SwitchToFullscreenMenuItem.Image = Properties.Resources.Fullscreen; + ControllersMenuItem.Image = Properties.Resources.GameController; + HotkeysMenuItem.Image = Properties.Resources.HotKeys; + DisplayConfigMenuItem.Image = Properties.Resources.tvIcon; + SoundMenuItem.Image = Properties.Resources.AudioHS; + PathsMenuItem.Image = Properties.Resources.CopyFolderHS; + FirmwaresMenuItem.Image = Properties.Resources.pcb; + MessagesMenuItem.Image = Properties.Resources.MessageConfig; + AutofireMenuItem.Image = Properties.Resources.Lightning; + RewindOptionsMenuItem.Image = Properties.Resources.Previous; + ProfilesMenuItem.Image = Properties.Resources.user_blue_small; + SaveConfigMenuItem.Image = Properties.Resources.Save; + LoadConfigMenuItem.Image = Properties.Resources.LoadConfig; + ToolBoxMenuItem.Image = Properties.Resources.ToolBox; + RamWatchMenuItem.Image = Properties.Resources.watch; + RamSearchMenuItem.Image = Properties.Resources.search; + LuaConsoleMenuItem.Image = Properties.Resources.Lua; + TAStudioMenuItem.Image = Properties.Resources.TAStudio; + HexEditorMenuItem.Image = Properties.Resources.poke; + TraceLoggerMenuItem.Image = Properties.Resources.pencil; + DebuggerMenuItem.Image = Properties.Resources.Bug; + CodeDataLoggerMenuItem.Image = Properties.Resources.cdlogger; + VirtualPadMenuItem.Image = Properties.Resources.GameController; + CheatsMenuItem.Image = Properties.Resources.Freeze; + GameSharkConverterMenuItem.Image = Properties.Resources.Shark; + MultiDiskBundlerFileMenuItem.Image = Properties.Resources.SaveConfig; + NesControllerSettingsMenuItem.Image = Properties.Resources.GameController; + NESGraphicSettingsMenuItem.Image = Properties.Resources.tvIcon; + NESSoundChannelsMenuItem.Image = Properties.Resources.AudioHS; + KeypadMenuItem.Image = Properties.Resources.calculator; + PSXControllerSettingsMenuItem.Image = Properties.Resources.GameController; + SNESControllerConfigurationMenuItem.Image = Properties.Resources.GameController; + SnesGfxDebuggerMenuItem.Image = Properties.Resources.Bug; + ColecoControllerSettingsMenuItem.Image = Properties.Resources.GameController; + N64PluginSettingsMenuItem.Image = Properties.Resources.monitor; + N64ControllerSettingsMenuItem.Image = Properties.Resources.GameController; + IntVControllerSettingsMenuItem.Image = Properties.Resources.GameController; + OnlineHelpMenuItem.Image = Properties.Resources.Help; + ForumsMenuItem.Image = Properties.Resources.TAStudio; + FeaturesMenuItem.Image = Properties.Resources.kitchensink; + AboutMenuItem.Image = Properties.Resources.CorpHawkSmall; + DumpStatusButton.Image = Properties.Resources.Blank; + PlayRecordStatusButton.Image = Properties.Resources.Blank; + PauseStatusButton.Image = Properties.Resources.Blank; + RebootStatusBarIcon.Image = Properties.Resources.reboot; + AVIStatusLabel.Image = Properties.Resources.Blank; + LedLightStatusLabel.Image = Properties.Resources.LightOff; + KeyPriorityStatusLabel.Image = Properties.Resources.Both; + CoreNameStatusBarButton.Image = Properties.Resources.CorpHawkSmall; + ProfileFirstBootLabel.Image = Properties.Resources.user_blue_small; + LinkConnectStatusBarButton.Image = Properties.Resources.connect_16x16; + OpenRomContextMenuItem.Image = Properties.Resources.OpenFile; + LoadLastRomContextMenuItem.Image = Properties.Resources.Recent; + StopAVContextMenuItem.Image = Properties.Resources.Stop; + RecordMovieContextMenuItem.Image = Properties.Resources.RecordHS; + PlayMovieContextMenuItem.Image = Properties.Resources.Play; + RestartMovieContextMenuItem.Image = Properties.Resources.restart; + StopMovieContextMenuItem.Image = Properties.Resources.Stop; + LoadLastMovieContextMenuItem.Image = Properties.Resources.Recent; + StopNoSaveContextMenuItem.Image = Properties.Resources.Stop; + SaveMovieContextMenuItem.Image = Properties.Resources.SaveAs; + SaveMovieAsContextMenuItem.Image = Properties.Resources.SaveAs; + UndoSavestateContextMenuItem.Image = Properties.Resources.undo; + toolStripMenuItem6.Image = Properties.Resources.GameController; + toolStripMenuItem7.Image = Properties.Resources.HotKeys; + toolStripMenuItem8.Image = Properties.Resources.tvIcon; + toolStripMenuItem9.Image = Properties.Resources.AudioHS; + toolStripMenuItem10.Image = Properties.Resources.CopyFolderHS; + toolStripMenuItem11.Image = Properties.Resources.pcb; + toolStripMenuItem12.Image = Properties.Resources.MessageConfig; + toolStripMenuItem13.Image = Properties.Resources.Lightning; + toolStripMenuItem14.Image = Properties.Resources.Previous; + toolStripMenuItem66.Image = Properties.Resources.Save; + toolStripMenuItem67.Image = Properties.Resources.LoadConfig; + ScreenshotContextMenuItem.Image = Properties.Resources.camera; + CloseRomContextMenuItem.Image = Properties.Resources.Close; + } + public MainForm(string[] args) { - void SetImages() - { - OpenRomMenuItem.Image = Properties.Resources.OpenFile; - RecentRomSubMenu.Image = Properties.Resources.Recent; - CloseRomMenuItem.Image = Properties.Resources.Close; - PreviousSlotMenuItem.Image = Properties.Resources.MoveLeft; - NextSlotMenuItem.Image = Properties.Resources.MoveRight; - ReadonlyMenuItem.Image = Properties.Resources.ReadOnly; - RecentMovieSubMenu.Image = Properties.Resources.Recent; - RecordMovieMenuItem.Image = Properties.Resources.RecordHS; - PlayMovieMenuItem.Image = Properties.Resources.Play; - StopMovieMenuItem.Image = Properties.Resources.Stop; - PlayFromBeginningMenuItem.Image = Properties.Resources.restart; - ImportMoviesMenuItem.Image = Properties.Resources.Import; - SaveMovieMenuItem.Image = Properties.Resources.SaveAs; - SaveMovieAsMenuItem.Image = Properties.Resources.SaveAs; - StopMovieWithoutSavingMenuItem.Image = Properties.Resources.Stop; - RecordAVMenuItem.Image = Properties.Resources.RecordHS; - ConfigAndRecordAVMenuItem.Image = Properties.Resources.AVI; - StopAVIMenuItem.Image = Properties.Resources.Stop; - ScreenshotMenuItem.Image = Properties.Resources.camera; - PauseMenuItem.Image = Properties.Resources.Pause; - RebootCoreMenuItem.Image = Properties.Resources.reboot; - SwitchToFullscreenMenuItem.Image = Properties.Resources.Fullscreen; - ControllersMenuItem.Image = Properties.Resources.GameController; - HotkeysMenuItem.Image = Properties.Resources.HotKeys; - DisplayConfigMenuItem.Image = Properties.Resources.tvIcon; - SoundMenuItem.Image = Properties.Resources.AudioHS; - PathsMenuItem.Image = Properties.Resources.CopyFolderHS; - FirmwaresMenuItem.Image = Properties.Resources.pcb; - MessagesMenuItem.Image = Properties.Resources.MessageConfig; - AutofireMenuItem.Image = Properties.Resources.Lightning; - RewindOptionsMenuItem.Image = Properties.Resources.Previous; - ProfilesMenuItem.Image = Properties.Resources.user_blue_small; - SaveConfigMenuItem.Image = Properties.Resources.Save; - LoadConfigMenuItem.Image = Properties.Resources.LoadConfig; - ToolBoxMenuItem.Image = Properties.Resources.ToolBox; - RamWatchMenuItem.Image = Properties.Resources.watch; - RamSearchMenuItem.Image = Properties.Resources.search; - LuaConsoleMenuItem.Image = Properties.Resources.Lua; - TAStudioMenuItem.Image = Properties.Resources.TAStudio; - HexEditorMenuItem.Image = Properties.Resources.poke; - TraceLoggerMenuItem.Image = Properties.Resources.pencil; - DebuggerMenuItem.Image = Properties.Resources.Bug; - CodeDataLoggerMenuItem.Image = Properties.Resources.cdlogger; - VirtualPadMenuItem.Image = Properties.Resources.GameController; - CheatsMenuItem.Image = Properties.Resources.Freeze; - GameSharkConverterMenuItem.Image = Properties.Resources.Shark; - MultiDiskBundlerFileMenuItem.Image = Properties.Resources.SaveConfig; - NesControllerSettingsMenuItem.Image = Properties.Resources.GameController; - NESGraphicSettingsMenuItem.Image = Properties.Resources.tvIcon; - NESSoundChannelsMenuItem.Image = Properties.Resources.AudioHS; - KeypadMenuItem.Image = Properties.Resources.calculator; - PSXControllerSettingsMenuItem.Image = Properties.Resources.GameController; - SNESControllerConfigurationMenuItem.Image = Properties.Resources.GameController; - SnesGfxDebuggerMenuItem.Image = Properties.Resources.Bug; - ColecoControllerSettingsMenuItem.Image = Properties.Resources.GameController; - N64PluginSettingsMenuItem.Image = Properties.Resources.monitor; - N64ControllerSettingsMenuItem.Image = Properties.Resources.GameController; - IntVControllerSettingsMenuItem.Image = Properties.Resources.GameController; - OnlineHelpMenuItem.Image = Properties.Resources.Help; - ForumsMenuItem.Image = Properties.Resources.TAStudio; - FeaturesMenuItem.Image = Properties.Resources.kitchensink; - AboutMenuItem.Image = Properties.Resources.CorpHawkSmall; - DumpStatusButton.Image = Properties.Resources.Blank; - PlayRecordStatusButton.Image = Properties.Resources.Blank; - PauseStatusButton.Image = Properties.Resources.Blank; - RebootStatusBarIcon.Image = Properties.Resources.reboot; - AVIStatusLabel.Image = Properties.Resources.Blank; - LedLightStatusLabel.Image = Properties.Resources.LightOff; - KeyPriorityStatusLabel.Image = Properties.Resources.Both; - CoreNameStatusBarButton.Image = Properties.Resources.CorpHawkSmall; - ProfileFirstBootLabel.Image = Properties.Resources.user_blue_small; - LinkConnectStatusBarButton.Image = Properties.Resources.connect_16x16; - OpenRomContextMenuItem.Image = Properties.Resources.OpenFile; - LoadLastRomContextMenuItem.Image = Properties.Resources.Recent; - StopAVContextMenuItem.Image = Properties.Resources.Stop; - RecordMovieContextMenuItem.Image = Properties.Resources.RecordHS; - PlayMovieContextMenuItem.Image = Properties.Resources.Play; - RestartMovieContextMenuItem.Image = Properties.Resources.restart; - StopMovieContextMenuItem.Image = Properties.Resources.Stop; - LoadLastMovieContextMenuItem.Image = Properties.Resources.Recent; - StopNoSaveContextMenuItem.Image = Properties.Resources.Stop; - SaveMovieContextMenuItem.Image = Properties.Resources.SaveAs; - SaveMovieAsContextMenuItem.Image = Properties.Resources.SaveAs; - UndoSavestateContextMenuItem.Image = Properties.Resources.undo; - toolStripMenuItem6.Image = Properties.Resources.GameController; - toolStripMenuItem7.Image = Properties.Resources.HotKeys; - toolStripMenuItem8.Image = Properties.Resources.tvIcon; - toolStripMenuItem9.Image = Properties.Resources.AudioHS; - toolStripMenuItem10.Image = Properties.Resources.CopyFolderHS; - toolStripMenuItem11.Image = Properties.Resources.pcb; - toolStripMenuItem12.Image = Properties.Resources.MessageConfig; - toolStripMenuItem13.Image = Properties.Resources.Lightning; - toolStripMenuItem14.Image = Properties.Resources.Previous; - toolStripMenuItem66.Image = Properties.Resources.Save; - toolStripMenuItem67.Image = Properties.Resources.LoadConfig; - ScreenshotContextMenuItem.Image = Properties.Resources.camera; - CloseRomContextMenuItem.Image = Properties.Resources.Close; - } - - Database.InitializeDatabase(Path.Combine(PathUtils.ExeDirectoryPath, "gamedb", "gamedb.txt")); - GlobalWin.MainForm = this; + //do this threaded stuff early so it has plenty of time to run in background + Database.InitializeDatabase(Path.Combine(PathUtils.ExeDirectoryPath, "gamedb", "gamedb.txt")); + BootGodDb.Initialize(Path.Combine(PathUtils.ExeDirectoryPath, "gamedb")); + GlobalWin.InputManager.ControllerInputCoalescer = new ControllerInputCoalescer(); GlobalWin.FirmwareManager = new FirmwareManager(); MovieSession = new MovieSession( @@ -302,23 +304,8 @@ namespace BizHawk.Client.EmuHawk UpdateStatusSlots(); UpdateKeyPriorityIcon(); - // 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 - BootGodDb.GetDatabaseBytes = () => - { - string xmlPath = Path.Combine(PathUtils.ExeDirectoryPath, "gamedb", "NesCarts.xml"); - string x7zPath = Path.Combine(PathUtils.ExeDirectoryPath, "gamedb", "NesCarts.7z"); - bool loadXml = File.Exists(xmlPath); - using var nesCartFile = new HawkFile(loadXml ? xmlPath : x7zPath); - if (!loadXml) - { - nesCartFile.BindFirst(); - } - return nesCartFile - .GetStream() - .ReadAllBytes(); - }; + try { _argParser.ParseArguments(args); diff --git a/src/BizHawk.Emulation.Common/Database/Database.cs b/src/BizHawk.Emulation.Common/Database/Database.cs index 31b8d38a68..f776051523 100644 --- a/src/BizHawk.Emulation.Common/Database/Database.cs +++ b/src/BizHawk.Emulation.Common/Database/Database.cs @@ -157,9 +157,6 @@ namespace BizHawk.Emulation.Common } } - //commit the finished database load - //it's left as null until now to help catch mistakes in using the resource - DB = DB; acquire.Set(); } diff --git a/src/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj b/src/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj index 09529723a7..6e04f0764b 100644 --- a/src/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj +++ b/src/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj @@ -11,6 +11,7 @@ + diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/BootGodDB.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/BootGodDB.cs index 7a48401603..253a22c936 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/BootGodDB.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/BootGodDB.cs @@ -1,40 +1,41 @@ using System; +using System.Diagnostics; using System.Collections.Generic; -using System.IO; +using System.IO; using System.Xml; +using System.Threading; using BizHawk.Common; namespace BizHawk.Emulation.Cores.Nintendo.NES { public class BootGodDb - { - static object staticsyncroot = new object(); - object syncroot = new object(); + { + /// + /// blocks until the DB is done loading + /// + static EventWaitHandle acquire; bool validate = true; private readonly Bag _sha1Table = new Bag(); - private static BootGodDb _instance; - public static BootGodDb Instance + static BootGodDb instance; + + public static void Initialize(string basePath) { - get { lock (staticsyncroot) { return _instance; } } + if (acquire != null) throw new InvalidOperationException("Bootgod DB multiply initialized"); + acquire = new EventWaitHandle(false, EventResetMode.ManualReset); ; + + var stopwatch = Stopwatch.StartNew(); + ThreadPool.QueueUserWorkItem(_ => + { + instance = new BootGodDb(basePath); + Console.WriteLine("Bootgod DB load: " + stopwatch.Elapsed + " sec"); + acquire.Set(); + }); } - private static Func _GetDatabaseBytes; - - public static Func GetDatabaseBytes - { - set { lock (staticsyncroot) { _GetDatabaseBytes = value; } } - } - - public static void Initialize() - { - lock (staticsyncroot) - { - _instance ??= new BootGodDb(); - } - } + private BootGodDb() { } private int ParseSize(string str) { @@ -48,14 +49,26 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES } return temp; } - public BootGodDb() + + public BootGodDb(string basePath) { // notes: there can be multiple each of prg,chr,wram,vram // we aren't tracking the individual hashes yet. + string xmlPath = Path.Combine(basePath, "NesCarts.xml"); + string x7zPath = Path.Combine(basePath, "NesCarts.7z"); + bool loadXml = File.Exists(xmlPath); + using var nesCartFile = new HawkFile(loadXml ? xmlPath : x7zPath); + if (!loadXml) + { + nesCartFile.BindFirst(); + } + + var stream = nesCartFile.GetStream(); + // 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())); + var xmlReader = XmlReader.Create(stream); CartInfo currCart = null; string currName = null; while (xmlReader.Read()) @@ -141,9 +154,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES } //end xmlreader loop } - public List Identify(string sha1) + public static List Identify(string sha1) { - lock (syncroot) return _sha1Table[sha1]; + if (acquire == null) throw new InvalidOperationException("Bootgod DB not initialized. It's a client responsibility because only a client knows where the database is located."); + acquire.WaitOne(); + return instance._sha1Table[sha1]; } } } diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NES.BoardSystem.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NES.BoardSystem.cs index 305b52e103..cbc0bfc8fb 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NES.BoardSystem.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NES.BoardSystem.cs @@ -140,10 +140,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES /// CartInfo IdentifyFromBootGodDB(IEnumerable hash_sha1) { - BootGodDb.Initialize(); foreach (var hash in hash_sha1) { - List choices = BootGodDb.Instance.Identify(hash); + List choices = BootGodDb.Identify(hash); //pick the first board for this hash arbitrarily. it probably doesn't make a difference if (choices.Count != 0) return choices[0]; diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NES.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NES.cs index 1b2f50d8f9..80b56fea45 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NES.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NES.cs @@ -35,7 +35,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES SyncSettings = (NESSyncSettings)syncSettings ?? new NESSyncSettings(); ControllerSettings = SyncSettings.Controls; - BootGodDb.Initialize(); videoProvider = new MyVideoProvider(this); Init(game, rom, fdsBios); if (Board is FDS fds) @@ -86,7 +85,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES private NES() { - BootGodDb.Initialize(); } public void WriteLogTimestamp() diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/QuickNES/QuickNES.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/QuickNES/QuickNES.cs index 24f29c85c9..1e32afa04c 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/QuickNES/QuickNES.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/QuickNES/QuickNES.cs @@ -241,7 +241,6 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.QuickNES void ComputeBootGod() { // inefficient, sloppy, etc etc - BootGodDb.Initialize(); var chrrom = _memoryDomains["CHR VROM"]; var prgrom = _memoryDomains["PRG ROM"]; @@ -262,7 +261,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.QuickNES } sha1 = "sha1:" + sha1; // huh? - var carts = BootGodDb.Instance.Identify(sha1); + var carts = BootGodDb.Identify(sha1); if (carts.Count > 0) {