diff --git a/BizHawk.Client.Common/BizHawk.Client.Common.csproj b/BizHawk.Client.Common/BizHawk.Client.Common.csproj
index d59a5d43ea..10e8a7369e 100644
--- a/BizHawk.Client.Common/BizHawk.Client.Common.csproj
+++ b/BizHawk.Client.Common/BizHawk.Client.Common.csproj
@@ -150,6 +150,7 @@
+
diff --git a/BizHawk.Client.Common/RomLoader.cs b/BizHawk.Client.Common/RomLoader.cs
new file mode 100644
index 0000000000..3a29eed8af
--- /dev/null
+++ b/BizHawk.Client.Common/RomLoader.cs
@@ -0,0 +1,574 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+using BizHawk.Common;
+using BizHawk.Emulation.Common;
+using BizHawk.Emulation.DiscSystem;
+using System.IO;
+using BizHawk.Emulation.Cores.Consoles.Sega.gpgx;
+using BizHawk.Emulation.Cores.Sega.Saturn;
+using BizHawk.Emulation.Cores.Sony.PSP;
+using BizHawk.Emulation.Cores.Sony.PSX;
+using BizHawk.Emulation.Cores.PCEngine;
+using BizHawk.Emulation.Cores.Nintendo.Gameboy;
+using BizHawk.Emulation.Cores.Nintendo.SNES;
+using BizHawk.Emulation.Cores.Sega.MasterSystem;
+using BizHawk.Emulation.Cores.Nintendo.NES;
+using BizHawk.Emulation.Cores.Intellivision;
+using BizHawk.Emulation.Cores.ColecoVision;
+using BizHawk.Emulation.Cores.Nintendo.GBA;
+using BizHawk.Emulation.Cores.Atari.Atari7800;
+using BizHawk.Emulation.Cores.Computers.Commodore64;
+using BizHawk.Emulation.Cores.Calculators;
+using BizHawk.Emulation.Cores.Atari.Atari2600;
+using BizHawk.Emulation.Cores.Nintendo.N64;
+
+namespace BizHawk.Client.Common
+{
+ public class RomLoader
+ {
+ #region SNES specific stuff - clean up or move elsewhere
+
+ private readonly Dictionary _snesPrepared = new Dictionary();
+
+ // Contains a mapping: profilename->exepath ; or null if the exe wasnt available
+ private string SNES_Prepare(string profile)
+ {
+ SNES_Check(profile);
+ if (_snesPrepared[profile] == null)
+ {
+ throw new InvalidOperationException("Couldn't locate the executable for SNES emulation for profile: " + profile + ". Please make sure you're using a fresh dearchive of a BizHawk distribution.");
+ }
+
+ return _snesPrepared[profile];
+ }
+
+ private void SNES_Check(string profile)
+ {
+ if (_snesPrepared.ContainsKey(profile))
+ {
+ return;
+ }
+
+ const string bits = "32";
+
+ // disabled til it works
+ // if (Win32.Is64BitOperatingSystem)
+ // bits = "64";
+ var exename = "libsneshawk-" + bits + "-" + profile.ToLower() + ".exe";
+ var thisDir = PathManager.GetExeDirectoryAbsolute();
+ var exePath = Path.Combine(thisDir, exename);
+
+ if (!File.Exists(exePath))
+ {
+ exePath = Path.Combine(Path.Combine(thisDir, "dll"), exename);
+ }
+
+ if (!File.Exists(exePath))
+ {
+ exePath = null;
+ }
+
+ _snesPrepared[profile] = exePath;
+ }
+
+ #endregion
+
+ #region N64 specific stuff - clean up or move elsewhere
+
+ private static VideoPluginSettings N64GenerateVideoSettings(GameInfo game, bool hasmovie)
+ {
+ var pluginToUse = String.Empty;
+
+ if (hasmovie && Global.MovieSession.Movie.Header[HeaderKeys.PLATFORM] == "N64" && Global.MovieSession.Movie.Header.ContainsKey(HeaderKeys.VIDEOPLUGIN))
+ {
+ pluginToUse = Global.MovieSession.Movie.Header[HeaderKeys.VIDEOPLUGIN];
+ }
+
+ if (pluginToUse == string.Empty || (pluginToUse != "Rice" && pluginToUse != "Glide64"))
+ {
+ pluginToUse = Global.Config.N64VidPlugin;
+ }
+
+ var video_settings = new VideoPluginSettings(pluginToUse, Global.Config.N64VideoSizeX, Global.Config.N64VideoSizeY);
+
+ if (pluginToUse == "Rice")
+ {
+ Global.Config.RicePlugin.FillPerGameHacks(game);
+ video_settings.Parameters = Global.Config.RicePlugin.GetPluginSettings();
+ }
+ else if (pluginToUse == "Glide64")
+ {
+ Global.Config.GlidePlugin.FillPerGameHacks(game);
+ video_settings.Parameters = Global.Config.GlidePlugin.GetPluginSettings();
+ }
+ else if (pluginToUse == "Glide64mk2")
+ {
+ Global.Config.Glide64mk2Plugin.FillPerGameHacks(game);
+ video_settings.Parameters = Global.Config.Glide64mk2Plugin.GetPluginSettings();
+ }
+
+ if (hasmovie && Global.MovieSession.Movie.Header[HeaderKeys.PLATFORM] == "N64" && Global.MovieSession.Movie.Header.ContainsKey(HeaderKeys.VIDEOPLUGIN))
+ {
+ var settings = new List(video_settings.Parameters.Keys);
+ foreach (var setting in settings)
+ {
+ if (Global.MovieSession.Movie.Header.ContainsKey(setting))
+ {
+ var Value = Global.MovieSession.Movie.Header[setting];
+ if (video_settings.Parameters[setting] is bool)
+ {
+ try
+ {
+ video_settings.Parameters[setting] = bool.Parse(Value);
+ }
+ catch { }
+ }
+ else if (video_settings.Parameters[setting] is int)
+ {
+ try
+ {
+ video_settings.Parameters[setting] = int.Parse(Value);
+ }
+ catch { }
+ }
+ }
+ }
+ }
+
+ return video_settings;
+ }
+
+ #endregion
+
+ public RomLoader()
+ {
+ Deterministic = true;
+ }
+
+ // TODO: reconsider the need for exposing these;
+ public IEmulator LoadedEmulator { get; private set; }
+ public CoreComm NextComm { get; private set; }
+ public GameInfo Game { get; private set; }
+ public RomGame Rom { get; private set; }
+ public string CanonicalFullPath { get; private set; }
+
+ public bool Deterministic { get; private set; }
+
+ public class RomErrorArgs
+ {
+ // TODO: think about naming here, what to pass, a lot of potential good information about what went wrong could go here!
+ public RomErrorArgs(string message, string systemId)
+ {
+ Message = message;
+ AttemptedCoreLoad = systemId;
+ }
+
+ public string Message { get; private set; }
+ public string AttemptedCoreLoad { get; private set; }
+ }
+
+ public delegate void LoadErrorEventHandler(object sener, RomErrorArgs e);
+ public event LoadErrorEventHandler OnLoadError;
+
+ public Func ChooseArchive;
+
+ public Action CoreCommMessageCallback; // TODO: eww, do we have to do this?
+
+ private int? HandleArchive(HawkFile file)
+ {
+ if (ChooseArchive != null)
+ {
+ return ChooseArchive(file);
+ }
+
+ return null;
+ }
+
+ private void ThrowLoadError(string message, string systemId)
+ {
+ if (OnLoadError != null)
+ {
+ OnLoadError(this, new RomErrorArgs(message, systemId));
+ }
+ }
+
+ // TODO I'm in mainform.cs and here, move me to a common place that both can call, static method on the config object?
+ private void CommitCoreSettingsToConfig()
+ {
+ // save settings object
+ Type t = Global.Emulator.GetType();
+ Global.Config.PutCoreSettings(Global.Emulator.GetSettings(), t);
+
+ // don't trample config with loaded-from-movie settings
+ if (!Global.MovieSession.Movie.IsActive)
+ {
+ Global.Config.PutCoreSyncSettings(Global.Emulator.GetSyncSettings(), t);
+ }
+ }
+
+ // TODO: the hasMovie hack should be obsoleted by the standardized movie sync setting saving/loading
+ public bool LoadRom(string path, bool hasmovie = false)
+ {
+ if (path == null)
+ {
+ return false;
+ }
+
+ using (var file = new HawkFile())
+ {
+ var romExtensions = new[] { "SMS", "SMC", "SFC", "PCE", "SGX", "GG", "SG", "BIN", "GEN", "MD", "SMD", "GB", "NES", "FDS", "ROM", "INT", "GBC", "UNF", "A78", "CRT", "COL", "XML", "Z64", "V64", "N64" };
+
+ // lets not use this unless we need to
+ // file.NonArchiveExtensions = romExtensions;
+ file.Open(path);
+
+ // if the provided file doesnt even exist, give up!
+ if (!file.Exists)
+ {
+ return false;
+ }
+
+ // try binding normal rom extensions first
+ if (!file.IsBound)
+ {
+ file.BindSoleItemOf(romExtensions);
+ }
+
+ // if we have an archive and need to bind something, then pop the dialog
+ if (file.IsArchive && !file.IsBound)
+ {
+ var result = ChooseArchive(file);
+ if (result.HasValue)
+ {
+ file.BindArchiveMember(result.Value);
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ IEmulator nextEmulator = null;
+ RomGame rom = null;
+ GameInfo game = null;
+ var nextComm = new CoreComm(CoreCommMessageCallback);
+ CoreFileProvider.SyncCoreCommInputSignals(nextComm);
+
+ // this also happens in CloseGame(). but it needs to happen here since if we're restarting with the same core,
+ // any settings changes that we made need to make it back to config before we try to instantiate that core with
+ // the new settings objects
+ CommitCoreSettingsToConfig();
+
+ try
+ {
+ var ext = file.Extension.ToLower();
+ if (ext == ".iso" || ext == ".cue")
+ {
+ var disc = ext == ".iso" ? Disc.FromIsoPath(path) : Disc.FromCuePath(path, new CueBinPrefs());
+ var hash = disc.GetHash();
+ game = Database.CheckDatabase(hash);
+ if (game == null)
+ {
+ // try to use our wizard methods
+ game = new GameInfo { Name = Path.GetFileNameWithoutExtension(file.Name), Hash = hash };
+
+ switch (disc.DetectDiscType())
+ {
+ case DiscType.SegaSaturn:
+ game.System = "SAT";
+ break;
+ case DiscType.SonyPSP:
+ game.System = "PSP";
+ break;
+ case DiscType.SonyPSX:
+ game.System = "PSX";
+ break;
+ case DiscType.MegaCD:
+ game.System = "GEN";
+ break;
+ case DiscType.TurboCD:
+ case DiscType.UnknownCDFS:
+ case DiscType.UnknownFormat:
+ default: // PCECD was bizhawk's first CD core,
+ // and during that time, all CDs were blindly sent to it
+ // so this prevents regressions
+ game.System = "PCECD";
+ break;
+ }
+ }
+
+ switch (game.System)
+ {
+ case "GEN":
+ {
+ var genesis = new GPGX(
+ nextComm, null, disc, "GEN", Global.Config.GetCoreSyncSettings());
+ nextEmulator = genesis;
+ }
+ break;
+ case "SAT":
+ {
+ var saturn = new Yabause(nextComm, disc, Global.Config.SaturnUseGL);
+ nextEmulator = saturn;
+ }
+ break;
+ case "PSP":
+ {
+ var psp = new PSP(nextComm, file.Name);
+ nextEmulator = psp;
+ }
+ break;
+ case "PSX":
+ {
+ var psx = new Octoshock(nextComm);
+ nextEmulator = psx;
+ psx.LoadCuePath(file.CanonicalFullPath);
+ nextEmulator.CoreComm.RomStatusDetails = "PSX etc.";
+ }
+ break;
+ case "PCE":
+ case "PCECD":
+ {
+ var biosPath = Global.FirmwareManager.Request("PCECD", "Bios");
+ if (File.Exists(biosPath) == false)
+ {
+ ThrowLoadError("PCE-CD System Card not found. Please check the BIOS path in Config->Paths->PC Engine."
+ , game.System);
+ return false;
+ }
+
+ rom = new RomGame(new HawkFile(biosPath));
+
+ if (rom.GameInfo.Status == RomStatus.BadDump)
+ {
+ ThrowLoadError(
+ "The PCE-CD System Card you have selected is known to be a bad dump. This may cause problems playing PCE-CD games.\n\n"
+ + "It is recommended that you find a good dump of the system card. Sorry to be the bearer of bad news!"
+ , game.System);
+ }
+ else if (rom.GameInfo.NotInDatabase)
+ {
+ ThrowLoadError(
+ "The PCE-CD System Card you have selected is not recognized in our database. That might mean it's a bad dump, or isn't the correct rom."
+ , game.System);
+ }
+ else if (rom.GameInfo["BIOS"] == false)
+ {
+ ThrowLoadError(
+ "The PCE-CD System Card you have selected is not a BIOS image. You may have selected the wrong rom."
+ , game.System);
+ }
+
+ if (rom.GameInfo["SuperSysCard"])
+ {
+ game.AddOption("SuperSysCard");
+ }
+
+ if (game["NeedSuperSysCard"] && game["SuperSysCard"] == false)
+ {
+ ThrowLoadError(
+ "This game requires a version 3.0 System card and won't run with the system card you've selected. Try selecting a 3.0 System Card in Config->Paths->PC Engine."
+ , game.System);
+ }
+
+ game.FirmwareHash = Util.BytesToHexString(System.Security.Cryptography.SHA1.Create().ComputeHash(rom.RomData));
+ nextEmulator = new PCEngine(nextComm, game, disc, rom.RomData, Global.Config.GetCoreSettings());
+ break;
+ }
+ }
+ }
+ else if (file.Extension.ToLower() == ".xml")
+ {
+ try
+ {
+ var XMLG = XmlGame.Create(file); // if load fails, are we supposed to retry as a bsnes XML????????
+ game = XMLG.GI;
+
+ switch (game.System)
+ {
+ case "DGB":
+
+ var L = Database.GetGameInfo(XMLG.Assets["LeftRom"], "left.gb");
+ var R = Database.GetGameInfo(XMLG.Assets["RightRom"], "right.gb");
+
+ var gbl = new GambatteLink(nextComm, L, XMLG.Assets["LeftRom"], R, XMLG.Assets["RightRom"],
+ Global.Config.GetCoreSettings(),
+ Global.Config.GetCoreSyncSettings());
+ nextEmulator = gbl;
+
+ // other stuff todo
+ break;
+
+ default:
+ return false;
+ }
+ }
+ catch (Exception ex)
+ {
+ ThrowLoadError(ex.ToString(), "XMLGame Load Error"); // TODO: don't pass in XMLGame Load Error as a system ID
+ }
+ }
+ else // most extensions
+ {
+ rom = new RomGame(file);
+ game = rom.GameInfo;
+
+ bool isXml = false;
+
+ // other xml has already been handled
+ if (file.Extension.ToLower() == ".xml")
+ {
+ game.System = "SNES";
+ isXml = true;
+ }
+
+ switch (game.System)
+ {
+ case "SNES":
+ {
+ game.System = "SNES";
+ nextComm.SNES_ExePath = SNES_Prepare(Global.Config.SNESProfile);
+
+ // need to get rid of this hack at some point
+ ((CoreFileProvider)nextComm.CoreFileProvider).SubfileDirectory = Path.GetDirectoryName(path.Replace("|", string.Empty)); //Dirty hack to get around archive filenames (since we are just getting the directory path, it is safe to mangle the filename
+
+ var snes = new LibsnesCore(nextComm);
+ nextEmulator = snes;
+ byte[] romData = isXml ? null : rom.FileData;
+ byte[] xmlData = isXml ? rom.FileData : null;
+ snes.Load(game, romData, Deterministic, xmlData);
+ }
+ break;
+ case "SMS":
+ case "SG":
+ case "GG":
+ nextEmulator = new SMS(nextComm, game, rom.RomData, Global.Config.GetCoreSettings(), Global.Config.GetCoreSyncSettings());
+ break;
+ case "A26":
+ nextEmulator = new Atari2600(nextComm, game, rom.FileData,
+ Global.Config.GetCoreSettings(),
+ Global.Config.GetCoreSyncSettings());
+ break;
+ case "PCE":
+ case "PCECD":
+ case "SGX":
+ nextEmulator = new PCEngine(nextComm, game, rom.RomData, Global.Config.GetCoreSettings());
+ break;
+ case "GEN":
+ {
+ // nextEmulator = new Genesis(nextComm, game, rom.RomData);
+ nextEmulator = new GPGX(nextComm, rom.RomData, null, "GEN", Global.Config.GetCoreSyncSettings());
+ break;
+ }
+ case "TI83":
+ nextEmulator = new TI83(nextComm, game, rom.RomData);
+ break;
+ case "NES":
+ nextEmulator = new NES(nextComm, game, rom.FileData,
+ Global.Config.GetCoreSettings(),
+ Global.MovieSession.Movie.Header.BoardProperties);
+ break;
+ case "GB":
+ case "GBC":
+ if (!Global.Config.GB_AsSGB)
+ {
+ var gb = new Gameboy(nextComm, game, rom.FileData,
+ Global.Config.GetCoreSettings(),
+ Global.Config.GetCoreSyncSettings());
+ nextEmulator = gb;
+ }
+ else
+ {
+ try
+ {
+ game.System = "SNES";
+ game.AddOption("SGB");
+ nextComm.SNES_ExePath = SNES_Prepare(Global.Config.SNESProfile);
+ var snes = new LibsnesCore(nextComm);
+ nextEmulator = snes;
+ snes.Load(game, rom.FileData, Deterministic, null);
+ }
+ catch
+ {
+ // failed to load SGB bios. to avoid catch-22, disable SGB mode
+ ThrowLoadError("Failed to load a GB rom in SGB mode. Disabling SGB Mode."
+ , game.System);
+ Global.Config.GB_AsSGB = false;
+ throw;
+ }
+ }
+ break;
+ case "Coleco":
+ {
+ throw new Exception("Natt needs to refactor this!");
+ //var c = new ColecoVision(nextComm, game, rom.RomData, Global.Config.ColecoSkipBiosIntro);
+ //nextEmulator = c;
+ }
+ break;
+ case "INTV":
+ {
+ var intv = new Intellivision(nextComm, game, rom.RomData);
+ nextEmulator = intv;
+ }
+ break;
+ case "A78":
+ var gamedbpath = Path.Combine(PathManager.GetExeDirectoryAbsolute(), "gamedb", "EMU7800.csv");
+ var a78 = new Atari7800(nextComm, game, rom.RomData, gamedbpath);
+ nextEmulator = a78;
+ break;
+ case "C64":
+ C64 c64 = new C64(nextComm, game, rom.RomData, rom.Extension);
+ c64.HardReset();
+ nextEmulator = c64;
+ break;
+ case "GBA":
+ if (VersionInfo.INTERIM)
+ {
+ GBA gba = new GBA(nextComm);
+ gba.Load(rom.RomData);
+ nextEmulator = gba;
+ }
+ break;
+ case "N64":
+ Global.Game = game;
+ var video_settings = N64GenerateVideoSettings(game, hasmovie);
+ int SaveType = 0;
+ if (game.OptionValue("SaveType") == "EEPROM_16K")
+ {
+ SaveType = 1;
+ }
+ nextEmulator = new N64(nextComm, game, rom.RomData, video_settings, SaveType);
+ break;
+
+ case "DEBUG":
+ if (VersionInfo.INTERIM)
+ {
+ nextEmulator = LibRetroEmulator.CreateDebug(nextComm, rom.RomData);
+ }
+ break;
+ }
+ }
+
+ if (nextEmulator == null)
+ {
+ ThrowLoadError("No core could load the rom.", "NULL");
+ return false;
+ }
+ }
+ catch (Exception ex)
+ {
+ ThrowLoadError("Exception during loadgame:\n\n" + ex, "NULL");
+ return false;
+ }
+ Rom = rom;
+ LoadedEmulator = nextEmulator;
+ NextComm = nextComm;
+ Game = game;
+ CanonicalFullPath = file.CanonicalFullPath;
+ return true;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/BizHawk.Client.EmuHawk/MainForm.cs b/BizHawk.Client.EmuHawk/MainForm.cs
index 481b88a1b8..3682982d8f 100644
--- a/BizHawk.Client.EmuHawk/MainForm.cs
+++ b/BizHawk.Client.EmuHawk/MainForm.cs
@@ -970,7 +970,6 @@ namespace BizHawk.Client.EmuHawk
private Control _renderTarget;
private RetainedViewportPanel _retainedPanel;
private readonly SaveSlotManager _stateSlots = new SaveSlotManager();
- private readonly Dictionary _snesPrepared = new Dictionary();
// AVI/WAV state
private IVideoWriter _currAviWriter;
@@ -1614,47 +1613,6 @@ namespace BizHawk.Client.EmuHawk
}
}
- // Contains a mapping: profilename->exepath ; or null if the exe wasnt available
- private string SNES_Prepare(string profile)
- {
- SNES_Check(profile);
- if (_snesPrepared[profile] == null)
- {
- throw new InvalidOperationException("Couldn't locate the executable for SNES emulation for profile: " + profile + ". Please make sure you're using a fresh dearchive of a BizHawk distribution.");
- }
-
- return _snesPrepared[profile];
- }
-
- private void SNES_Check(string profile)
- {
- if (_snesPrepared.ContainsKey(profile))
- {
- return;
- }
-
- const string bits = "32";
-
- // disabled til it works
- // if (Win32.Is64BitOperatingSystem)
- // bits = "64";
- var exename = "libsneshawk-" + bits + "-" + profile.ToLower() + ".exe";
- var thisDir = PathManager.GetExeDirectoryAbsolute();
- var exePath = Path.Combine(thisDir, exename);
-
- if (!File.Exists(exePath))
- {
- exePath = Path.Combine(Path.Combine(thisDir, "dll"), exename);
- }
-
- if (!File.Exists(exePath))
- {
- exePath = null;
- }
-
- _snesPrepared[profile] = exePath;
- }
-
private void SyncPresentationMode()
{
GlobalWin.DisplayManager.Suspend();
@@ -1861,69 +1819,6 @@ namespace BizHawk.Client.EmuHawk
GlobalWin.OSD.AddMessage("Slot " + Global.Config.SaveSlot + " selected.");
}
- private static VideoPluginSettings N64GenerateVideoSettings(GameInfo game, bool hasmovie)
- {
- var pluginToUse = String.Empty;
-
- if (hasmovie && Global.MovieSession.Movie.Header[HeaderKeys.PLATFORM] == "N64" && Global.MovieSession.Movie.Header.ContainsKey(HeaderKeys.VIDEOPLUGIN))
- {
- pluginToUse = Global.MovieSession.Movie.Header[HeaderKeys.VIDEOPLUGIN];
- }
-
- if (pluginToUse == string.Empty || (pluginToUse != "Rice" && pluginToUse != "Glide64"))
- {
- pluginToUse = Global.Config.N64VidPlugin;
- }
-
- var video_settings = new VideoPluginSettings(pluginToUse, Global.Config.N64VideoSizeX, Global.Config.N64VideoSizeY);
-
- if (pluginToUse == "Rice")
- {
- Global.Config.RicePlugin.FillPerGameHacks(game);
- video_settings.Parameters = Global.Config.RicePlugin.GetPluginSettings();
- }
- else if (pluginToUse == "Glide64")
- {
- Global.Config.GlidePlugin.FillPerGameHacks(game);
- video_settings.Parameters = Global.Config.GlidePlugin.GetPluginSettings();
- }
- else if (pluginToUse == "Glide64mk2")
- {
- Global.Config.Glide64mk2Plugin.FillPerGameHacks(game);
- video_settings.Parameters = Global.Config.Glide64mk2Plugin.GetPluginSettings();
- }
-
- if (hasmovie && Global.MovieSession.Movie.Header[HeaderKeys.PLATFORM] == "N64" && Global.MovieSession.Movie.Header.ContainsKey(HeaderKeys.VIDEOPLUGIN))
- {
- var settings = new List(video_settings.Parameters.Keys);
- foreach (var setting in settings)
- {
- if (Global.MovieSession.Movie.Header.ContainsKey(setting))
- {
- var Value = Global.MovieSession.Movie.Header[setting];
- if (video_settings.Parameters[setting] is bool)
- {
- try
- {
- video_settings.Parameters[setting] = bool.Parse(Value);
- }
- catch { }
- }
- else if (video_settings.Parameters[setting] is int)
- {
- try
- {
- video_settings.Parameters[setting] = int.Parse(Value);
- }
- catch { }
- }
- }
- }
- }
-
- return video_settings;
- }
-
private void Render()
{
var video = Global.Emulator.VideoProvider;
@@ -2980,356 +2875,38 @@ namespace BizHawk.Client.EmuHawk
MessageBox.Show(this, message, "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
- public bool LoadRom(string path, bool deterministicemulation = false, bool hasmovie = false) // Move to client.common
+ private void ShowLoadError(object sender, RomLoader.RomErrorArgs e)
{
- if (path == null)
+ MessageBox.Show(this, e.Message, e.AttemptedCoreLoad + " load warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
+ }
+
+ // Still needs a good bit of refactoring
+ public bool LoadRom(string path, bool deterministicemulation = false, bool hasmovie = false)
+ {
+ RomLoader loader = new RomLoader();
+ loader.ChooseArchive = LoadArhiveChooser;
+ loader.CoreCommMessageCallback = ShowMessageCoreComm;
+ loader.OnLoadError += ShowLoadError;
+ var result = loader.LoadRom(path, hasmovie);
+
+ if (result)
{
- return false;
- }
+ var nextEmulator = loader.LoadedEmulator; // TODO: just reference the property and get rid of this
+ var nextComm = loader.NextComm; // Ditto
+ var game = loader.Game; // Ditto
+ var rom = loader.Rom; // Ditto
+ var canonicalPath = loader.CanonicalFullPath;
- using (var file = new HawkFile())
- {
- var romExtensions = new[] { "SMS", "SMC", "SFC", "PCE", "SGX", "GG", "SG", "BIN", "GEN", "MD", "SMD", "GB", "NES", "FDS", "ROM", "INT", "GBC", "UNF", "A78", "CRT", "COL", "XML", "Z64", "V64", "N64" };
-
- // lets not use this unless we need to
- // file.NonArchiveExtensions = romExtensions;
- file.Open(path);
-
- // if the provided file doesnt even exist, give up!
- if (!file.Exists)
+ if (loader.LoadedEmulator is Yabause)
{
- return false;
+ SaturnSetPrefs(loader.LoadedEmulator as Yabause);
}
-
- // try binding normal rom extensions first
- if (!file.IsBound)
+ else if (loader.LoadedEmulator is TI83)
{
- file.BindSoleItemOf(romExtensions);
- }
-
- // if we have an archive and need to bind something, then pop the dialog
- if (file.IsArchive && !file.IsBound)
- {
- var ac = new ArchiveChooser(file);
- if (ac.ShowDialog(this) == DialogResult.OK)
+ if (Global.Config.TI83autoloadKeyPad)
{
- file.BindArchiveMember(ac.SelectedMemberIndex);
+ GlobalWin.Tools.Load();
}
- else
- {
- return false;
- }
- }
-
- IEmulator nextEmulator = null;
- RomGame rom = null;
- GameInfo game = null;
- var nextComm = new CoreComm(ShowMessageCoreComm);
- CoreFileProvider.SyncCoreCommInputSignals(nextComm);
-
- // this also happens in CloseGame(). but it needs to happen here since if we're restarting with the same core,
- // any settings changes that we made need to make it back to config before we try to instantiate that core with
- // the new settings objects
- CommitCoreSettingsToConfig();
-
- try
- {
- var ext = file.Extension.ToLower();
- if (ext == ".iso" || ext == ".cue")
- {
- var disc = ext == ".iso" ? Disc.FromIsoPath(path) : Disc.FromCuePath(path, new CueBinPrefs());
- var hash = disc.GetHash();
- game = Database.CheckDatabase(hash);
- if (game == null)
- {
- // try to use our wizard methods
- game = new GameInfo { Name = Path.GetFileNameWithoutExtension(file.Name), Hash = hash };
-
- switch (disc.DetectDiscType())
- {
- case DiscType.SegaSaturn:
- game.System = "SAT";
- break;
- case DiscType.SonyPSP:
- game.System = "PSP";
- break;
- case DiscType.SonyPSX:
- game.System = "PSX";
- break;
- case DiscType.MegaCD:
- game.System = "GEN";
- break;
- case DiscType.TurboCD:
- case DiscType.UnknownCDFS:
- case DiscType.UnknownFormat:
- default: // PCECD was bizhawk's first CD core,
- // and during that time, all CDs were blindly sent to it
- // so this prevents regressions
- game.System = "PCECD";
- break;
- }
- }
-
- switch (game.System)
- {
- case "GEN":
- {
- var genesis = new GPGX(
- nextComm, null, disc, "GEN", GetCoreSyncSettings());
- nextEmulator = genesis;
- }
- break;
- case "SAT":
- {
- var saturn = new Yabause(nextComm, disc, Global.Config.SaturnUseGL);
- nextEmulator = saturn;
- SaturnSetPrefs(saturn);
- }
- break;
- case "PSP":
- {
- var psp = new PSP(nextComm, file.Name);
- nextEmulator = psp;
- }
- break;
- case "PSX":
- {
- var psx = new Octoshock(nextComm);
- nextEmulator = psx;
- psx.LoadCuePath(file.CanonicalFullPath);
- nextEmulator.CoreComm.RomStatusDetails = "PSX etc.";
- }
- break;
- case "PCE":
- case "PCECD":
- {
- var biosPath = Global.FirmwareManager.Request("PCECD", "Bios");
- if (File.Exists(biosPath) == false)
- {
- MessageBox.Show("PCE-CD System Card not found. Please check the BIOS path in Config->Paths->PC Engine.");
- return false;
- }
-
- rom = new RomGame(new HawkFile(biosPath));
-
- if (rom.GameInfo.Status == RomStatus.BadDump)
- {
- MessageBox.Show(
- "The PCE-CD System Card you have selected is known to be a bad dump. This may cause problems playing PCE-CD games.\n\n"
- + "It is recommended that you find a good dump of the system card. Sorry to be the bearer of bad news!");
- }
- else if (rom.GameInfo.NotInDatabase)
- {
- MessageBox.Show(
- "The PCE-CD System Card you have selected is not recognized in our database. That might mean it's a bad dump, or isn't the correct rom.");
- }
- else if (rom.GameInfo["BIOS"] == false)
- {
- MessageBox.Show(
- "The PCE-CD System Card you have selected is not a BIOS image. You may have selected the wrong rom.");
- }
-
- if (rom.GameInfo["SuperSysCard"])
- {
- game.AddOption("SuperSysCard");
- }
-
- if (game["NeedSuperSysCard"] && game["SuperSysCard"] == false)
- {
- MessageBox.Show(
- "This game requires a version 3.0 System card and won't run with the system card you've selected. Try selecting a 3.0 System Card in Config->Paths->PC Engine.");
- }
-
- game.FirmwareHash = Util.BytesToHexString(System.Security.Cryptography.SHA1.Create().ComputeHash(rom.RomData));
- nextEmulator = new PCEngine(nextComm, game, disc, rom.RomData, Global.Config.GetCoreSettings());
- break;
- }
- }
- }
- else if (file.Extension.ToLower() == ".xml")
- {
- try
- {
- var XMLG = XmlGame.Create(file); // if load fails, are we supposed to retry as a bsnes XML????????
- game = XMLG.GI;
-
- switch (game.System)
- {
- case "DGB":
-
- var L = Database.GetGameInfo(XMLG.Assets["LeftRom"], "left.gb");
- var R = Database.GetGameInfo(XMLG.Assets["RightRom"], "right.gb");
-
- var gbl = new GambatteLink(nextComm, L, XMLG.Assets["LeftRom"], R, XMLG.Assets["RightRom"],
- Global.Config.GetCoreSettings(),
- GetCoreSyncSettings());
- nextEmulator = gbl;
-
- // other stuff todo
- break;
-
- default:
- return false;
- }
- }
- catch (Exception ex)
- {
- MessageBox.Show(ex.ToString(), "XMLGame Load Error");
- }
- }
- else // most extensions
- {
- rom = new RomGame(file);
- game = rom.GameInfo;
-
- bool isXml = false;
-
- // other xml has already been handled
- if (file.Extension.ToLower() == ".xml")
- {
- game.System = "SNES";
- isXml = true;
- }
-
- switch (game.System)
- {
- case "SNES":
- {
- game.System = "SNES";
- nextComm.SNES_ExePath = SNES_Prepare(Global.Config.SNESProfile);
-
- // need to get rid of this hack at some point
- ((CoreFileProvider)nextComm.CoreFileProvider).SubfileDirectory = Path.GetDirectoryName(path.Replace("|", string.Empty)); //Dirty hack to get around archive filenames (since we are just getting the directory path, it is safe to mangle the filename
-
- var snes = new LibsnesCore(nextComm);
- nextEmulator = snes;
- byte[] romData = isXml ? null : rom.FileData;
- byte[] xmlData = isXml ? rom.FileData : null;
- snes.Load(game, romData, deterministicemulation, xmlData);
- }
- break;
- case "SMS":
- case "SG":
- case "GG":
- nextEmulator = new SMS(nextComm, game, rom.RomData, Global.Config.GetCoreSettings(), GetCoreSyncSettings());
- break;
- case "A26":
- nextEmulator = new Atari2600(nextComm, game, rom.FileData,
- Global.Config.GetCoreSettings(),
- GetCoreSyncSettings());
- break;
- case "PCE":
- case "PCECD":
- case "SGX":
- nextEmulator = new PCEngine(nextComm, game, rom.RomData, Global.Config.GetCoreSettings());
- break;
- case "GEN":
- {
- // nextEmulator = new Genesis(nextComm, game, rom.RomData);
- nextEmulator = new GPGX(nextComm, rom.RomData, null, "GEN", GetCoreSyncSettings());
- break;
- }
- case "TI83":
- nextEmulator = new TI83(nextComm, game, rom.RomData);
- if (Global.Config.TI83autoloadKeyPad)
- {
- GlobalWin.Tools.Load();
- }
- break;
- case "NES":
- nextEmulator = new NES(nextComm, game, rom.FileData,
- Global.Config.GetCoreSettings(),
- Global.MovieSession.Movie.Header.BoardProperties);
- break;
- case "GB":
- case "GBC":
- if (!Global.Config.GB_AsSGB)
- {
- var gb = new Gameboy(nextComm, game, rom.FileData,
- Global.Config.GetCoreSettings(),
- GetCoreSyncSettings());
- nextEmulator = gb;
- }
- else
- {
- try
- {
- game.System = "SNES";
- game.AddOption("SGB");
- nextComm.SNES_ExePath = SNES_Prepare(Global.Config.SNESProfile);
- var snes = new LibsnesCore(nextComm);
- nextEmulator = snes;
- snes.Load(game, rom.FileData, deterministicemulation, null);
- }
- catch
- {
- // failed to load SGB bios. to avoid catch-22, disable SGB mode
- ShowMessageCoreComm("Failed to load a GB rom in SGB mode. Disabling SGB Mode.");
- Global.Config.GB_AsSGB = false;
- throw;
- }
- }
- break;
- case "Coleco":
- {
- var c = new ColecoVision(nextComm, game, rom.RomData, GetCoreSyncSettings());
- nextEmulator = c;
- }
- break;
- case "INTV":
- {
- var intv = new Intellivision(nextComm, game, rom.RomData);
- nextEmulator = intv;
- }
- break;
- case "A78":
- var gamedbpath = Path.Combine(PathManager.GetExeDirectoryAbsolute(), "gamedb", "EMU7800.csv");
- var a78 = new Atari7800(nextComm, game, rom.RomData, gamedbpath);
- nextEmulator = a78;
- break;
- case "C64":
- C64 c64 = new C64(nextComm, game, rom.RomData, rom.Extension);
- c64.HardReset();
- nextEmulator = c64;
- break;
- case "GBA":
- if (VersionInfo.INTERIM)
- {
- GBA gba = new GBA(nextComm);
- // var gba = new GarboDev.GbaManager(nextComm);
- gba.Load(rom.RomData);
- nextEmulator = gba;
- }
- break;
- case "N64":
- Global.Game = game;
- var video_settings = N64GenerateVideoSettings(game, hasmovie);
- int SaveType = 0;
- if (game.OptionValue("SaveType") == "EEPROM_16K")
- {
- SaveType = 1;
- }
- nextEmulator = new N64(nextComm, game, rom.RomData, video_settings, SaveType);
- break;
-
- case "DEBUG":
- if (VersionInfo.INTERIM)
- {
- nextEmulator = LibRetroEmulator.CreateDebug(nextComm, rom.RomData);
- }
- break;
- }
- }
-
- if (nextEmulator == null)
- {
- throw new Exception("No core could load the rom.");
- }
- }
- catch (Exception ex)
- {
- MessageBox.Show("Exception during loadgame:\n\n" + ex);
- return false;
}
CloseGame();
@@ -3376,13 +2953,13 @@ namespace BizHawk.Client.EmuHawk
// restarts the lua console if a different rom is loaded.
// im not really a fan of how this is done..
- if (Global.Config.RecentRoms.Empty || Global.Config.RecentRoms[0] != file.CanonicalFullPath)
+ if (Global.Config.RecentRoms.Empty || Global.Config.RecentRoms[0] != canonicalPath)
{
GlobalWin.Tools.Restart();
}
- Global.Config.RecentRoms.Add(file.CanonicalFullPath);
- JumpLists.AddRecentItem(file.CanonicalFullPath);
+ Global.Config.RecentRoms.Add(canonicalPath);
+ JumpLists.AddRecentItem(canonicalPath);
if (File.Exists(PathManager.SaveRamPath(game)))
{
LoadSaveRam();
@@ -3403,7 +2980,7 @@ namespace BizHawk.Client.EmuHawk
}
}
- CurrentlyOpenRom = file.CanonicalFullPath;
+ CurrentlyOpenRom = canonicalPath;
HandlePlatformMenus();
_stateSlots.Clear();
UpdateStatusSlots();
@@ -3419,6 +2996,24 @@ namespace BizHawk.Client.EmuHawk
ToolHelpers.UpdateCheatRelatedTools(null, null);
return true;
}
+ else
+ {
+ return false;
+ }
+ }
+
+ // This is probably fine the way it is, but consider refactor
+ private int? LoadArhiveChooser(HawkFile file)
+ {
+ var ac = new ArchiveChooser(file);
+ if (ac.ShowDialog(this) == DialogResult.OK)
+ {
+ return ac.SelectedMemberIndex;
+ }
+ else
+ {
+ return null;
+ }
}
public void SaveState(string name) // Move to client.common