From 1d383a62cc67fa5801a7fbc94d43fe59f406e8ca Mon Sep 17 00:00:00 2001 From: goyuken Date: Sat, 23 Aug 2014 19:06:37 +0000 Subject: [PATCH] romloader stuffs, nag me if it breaks anything, i don't think it breaks anything --- BizHawk.Client.Common/RomLoader.cs | 105 ++++-------- .../BizHawk.Emulation.Cores.csproj | 1 + BizHawk.Emulation.Cores/Calculator/TI83.cs | 1 + .../Consoles/Atari/2600/Atari2600.cs | 1 + .../Consoles/Coleco/ColecoVision.cs | 1 + .../Consoles/Intellivision/Intellivision.cs | 1 + .../Consoles/Nintendo/GBA/Meteor.cs | 6 +- .../Consoles/Nintendo/GBA/VBANext.cs | 21 +-- .../Consoles/Nintendo/Gameboy/Gambatte.cs | 13 +- .../Consoles/Nintendo/N64/N64.cs | 1 + .../Consoles/Nintendo/NES/NES.cs | 1 + .../Consoles/Nintendo/QuickNES/QuickNES.cs | 5 +- .../Consoles/Nintendo/SNES9X/Snes9x.cs | 5 +- .../Consoles/PC Engine/PCEngine.cs | 1 + .../Consoles/Sega/SMS/SMS.cs | 1 + .../Consoles/Sega/gpgx/GPGX.cs | 12 +- .../Consoles/WonderSwan/WonderSwan.cs | 7 +- BizHawk.Emulation.Cores/CoreInventory.cs | 159 ++++++++++++++++++ BizHawk.Emulation.Cores/LibRetroEmulator.cs | 1 + 19 files changed, 243 insertions(+), 100 deletions(-) create mode 100644 BizHawk.Emulation.Cores/CoreInventory.cs diff --git a/BizHawk.Client.Common/RomLoader.cs b/BizHawk.Client.Common/RomLoader.cs index d8f159614b..1e142486b3 100644 --- a/BizHawk.Client.Common/RomLoader.cs +++ b/BizHawk.Client.Common/RomLoader.cs @@ -35,24 +35,31 @@ namespace BizHawk.Client.Common private object GetCoreSettings() where T : IEmulator { - var e = new SettingsLoadArgs(typeof(T)); - if (OnLoadSettings != null) - { - OnLoadSettings(this, e); - } - - return e.Settings; + return GetCoreSettings(typeof(T)); } private object GetCoreSyncSettings() where T : IEmulator { - var e = new SettingsLoadArgs(typeof(T)); + return GetCoreSyncSettings(typeof(T)); + } + + private object GetCoreSettings(Type t) + { + var e = new SettingsLoadArgs(t); + if (OnLoadSettings != null) + { + OnLoadSettings(this, e); + } + return e.Settings; + } + private object GetCoreSyncSettings(Type t) + { + var e = new SettingsLoadArgs(t); if (OnLoadSyncSettings != null) { OnLoadSyncSettings(this, e); } - return e.Settings; } @@ -235,7 +242,7 @@ namespace BizHawk.Client.Common { case "GEN": var genesis = new GPGX( - nextComm, null, disc, "GEN", GetCoreSettings(), GetCoreSyncSettings()); + nextComm, null, disc, GetCoreSettings(), GetCoreSyncSettings()); nextEmulator = genesis; break; case "SAT": @@ -317,13 +324,19 @@ namespace BizHawk.Client.Common isXml = true; } + + CoreInventory.Core core = null; + switch (game.System) { + default: + core = CoreInventory.Instance[game.System]; + break; + case "SNES": if (Global.Config.SNES_InSnes9x && VersionInfo.DeveloperBuild) { - var snes = new Emulation.Cores.Nintendo.SNES9X.Snes9x(nextComm, rom.FileData); - nextEmulator = snes; + core = CoreInventory.Instance["SNES", "Snes9x"]; } else { @@ -335,44 +348,15 @@ namespace BizHawk.Client.Common nextEmulator = snes; } - break; - case "SMS": - case "SG": - case "GG": - nextEmulator = new SMS(nextComm, game, rom.RomData, GetCoreSettings(), GetCoreSyncSettings()); - break; - case "A26": - nextEmulator = new Atari2600( - nextComm, - game, - rom.FileData, - GetCoreSettings(), - GetCoreSyncSettings()); - break; - case "PCE": - case "PCECD": - case "SGX": - nextEmulator = new PCEngine(nextComm, game, rom.RomData, GetCoreSettings(), GetCoreSyncSettings()); - break; - case "GEN": - nextEmulator = new GPGX(nextComm, rom.RomData, null, "GEN", GetCoreSettings(), GetCoreSyncSettings()); - break; - case "TI83": - nextEmulator = new TI83(nextComm, game, rom.RomData, GetCoreSettings()); break; case "NES": if (!Global.Config.NES_InQuickNES || forceAccurateCore) { - nextEmulator = new NES( - nextComm, - game, - rom.FileData, - GetCoreSettings(), - GetCoreSyncSettings()); + core = CoreInventory.Instance["NES", "NesHawk"]; } else { - nextEmulator = new QuickNES(nextComm, rom.FileData, GetCoreSettings()); + core = CoreInventory.Instance["NES", "QuickNes"]; } break; @@ -380,13 +364,7 @@ namespace BizHawk.Client.Common case "GBC": if (!Global.Config.GB_AsSGB) { - nextEmulator = new Gameboy( - nextComm, - game, - rom.FileData, - GetCoreSettings(), - GetCoreSyncSettings(), - Deterministic); + core = CoreInventory.Instance["GB", "Gambatte"]; } else { @@ -406,12 +384,6 @@ namespace BizHawk.Client.Common } } - break; - case "Coleco": - nextEmulator = new ColecoVision(nextComm, game, rom.RomData, GetCoreSyncSettings()); - break; - case "INTV": - nextEmulator = new Intellivision(nextComm, game, rom.RomData); break; case "A78": var gamedbpath = Path.Combine(PathManager.GetExeDirectoryAbsolute(), "gamedb", "EMU7800.csv"); @@ -424,24 +396,13 @@ namespace BizHawk.Client.Common case "GBA": if (false) { - var gba = new GBA(nextComm); // meteor - gba.Load(rom.RomData); - nextEmulator = gba; + core = CoreInventory.Instance["GBA", "Meteor"]; } else { - var gba = new VBANext(rom.RomData, nextComm, game, Deterministic, GetCoreSyncSettings()); - nextEmulator = gba; + core = CoreInventory.Instance["GBA", "VBA-Next"]; } break; - case "N64": - nextEmulator = new N64(nextComm, game, rom.RomData, - GetCoreSettings(), GetCoreSyncSettings()); - break; - case "WSWAN": - nextEmulator = new WonderSwan(nextComm, rom.RomData, Deterministic, - GetCoreSettings(), GetCoreSyncSettings()); - break; case "DEBUG": if (VersionInfo.DeveloperBuild) { @@ -450,6 +411,12 @@ namespace BizHawk.Client.Common break; } + + if (core != null) + { + // use coreinventory + nextEmulator = core.Create(nextComm, game, rom.RomData, null, Deterministic, GetCoreSettings(core.Type), GetCoreSyncSettings(core.Type)); + } } if (nextEmulator == null) diff --git a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj index d6d19607ae..5efa164f0e 100644 --- a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj +++ b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj @@ -482,6 +482,7 @@ + diff --git a/BizHawk.Emulation.Cores/Calculator/TI83.cs b/BizHawk.Emulation.Cores/Calculator/TI83.cs index ed43b2451f..6b8e175ba4 100644 --- a/BizHawk.Emulation.Cores/Calculator/TI83.cs +++ b/BizHawk.Emulation.Cores/Calculator/TI83.cs @@ -347,6 +347,7 @@ namespace BizHawk.Emulation.Cores.Calculators } } + [CoreConstructor("TI83")] public TI83(CoreComm comm, GameInfo game, byte[] rom, object Settings) { PutSettings(Settings ?? new TI83Settings()); diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.cs b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.cs index ede75061c8..56f68612c0 100644 --- a/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.cs +++ b/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.cs @@ -22,6 +22,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 private int _lagcount; private int _frame; + [CoreConstructor("A26")] public Atari2600(CoreComm comm, GameInfo game, byte[] rom, object settings, object syncSettings) { Ram = new byte[128]; diff --git a/BizHawk.Emulation.Cores/Consoles/Coleco/ColecoVision.cs b/BizHawk.Emulation.Cores/Consoles/Coleco/ColecoVision.cs index 1fc11ce9d2..c3030a5741 100644 --- a/BizHawk.Emulation.Cores/Consoles/Coleco/ColecoVision.cs +++ b/BizHawk.Emulation.Cores/Consoles/Coleco/ColecoVision.cs @@ -31,6 +31,7 @@ namespace BizHawk.Emulation.Cores.ColecoVision public SN76489 PSG; public byte[] Ram = new byte[1024]; + [CoreConstructor("Coleco")] public ColecoVision(CoreComm comm, GameInfo game, byte[] rom, object SyncSettings) { CoreComm = comm; diff --git a/BizHawk.Emulation.Cores/Consoles/Intellivision/Intellivision.cs b/BizHawk.Emulation.Cores/Consoles/Intellivision/Intellivision.cs index 05415ecb1f..7ba915c20f 100644 --- a/BizHawk.Emulation.Cores/Consoles/Intellivision/Intellivision.cs +++ b/BizHawk.Emulation.Cores/Consoles/Intellivision/Intellivision.cs @@ -64,6 +64,7 @@ namespace BizHawk.Emulation.Cores.Intellivision } } + [CoreConstructor("INTV")] public Intellivision(CoreComm comm, GameInfo game, byte[] rom) { CoreComm = comm; diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/Meteor.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/Meteor.cs index ca98a34ef0..e2e2150495 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/Meteor.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/Meteor.cs @@ -43,7 +43,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA public ControllerDefinition ControllerDefinition { get { return GBAController; } } public IController Controller { get; set; } - public GBA(CoreComm comm) + [CoreConstructor("GBA")] + public GBA(CoreComm comm, byte[] rom) { CoreComm = comm; comm.VsyncNum = 262144; @@ -52,10 +53,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA comm.TraceHeader = " -Addr--- -Opcode- -Instruction------------------- -R0----- -R1----- -R2----- -R3----- -R4----- -R5----- -R6----- -R7----- -R8----- -R9----- -R10---- -R11---- -R12---- -R13(SP) -R14(LR) -R15(PC) -CPSR--- -SPSR---"; comm.NominalWidth = 240; comm.NominalHeight = 160; - } - public void Load(byte[] rom) - { byte[] bios = CoreComm.CoreFileProvider.GetFirmware("GBA", "Bios", true, "GBA bios file is mandatory."); if (bios.Length != 16384) diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/VBANext.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/VBANext.cs index ccd57d863f..947bfea4ae 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/VBANext.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/VBANext.cs @@ -18,26 +18,27 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA { IntPtr Core; - public VBANext(byte[] romfile, CoreComm nextComm, GameInfo gi, bool deterministic, object _SS) + [CoreConstructor("GBA")] + public VBANext(byte[] rom, CoreComm comm, GameInfo game, bool deterministic, object syncsettings) { - CoreComm = nextComm; + CoreComm = comm; byte[] biosfile = CoreComm.CoreFileProvider.GetFirmware("GBA", "Bios", true, "GBA bios file is mandatory."); - if (romfile.Length > 32 * 1024 * 1024) + if (rom.Length > 32 * 1024 * 1024) throw new ArgumentException("ROM is too big to be a GBA ROM!"); if (biosfile.Length != 16 * 1024) throw new ArgumentException("BIOS file is not exactly 16K!"); LibVBANext.FrontEndSettings FES = new LibVBANext.FrontEndSettings(); - FES.saveType = (LibVBANext.FrontEndSettings.SaveType)gi.GetInt("saveType", 0); - FES.flashSize = (LibVBANext.FrontEndSettings.FlashSize)gi.GetInt("flashSize", 0x10000); - FES.enableRtc = gi.GetInt("rtcEnabled", 0) != 0; - FES.mirroringEnable = gi.GetInt("mirroringEnabled", 0) != 0; + FES.saveType = (LibVBANext.FrontEndSettings.SaveType)game.GetInt("saveType", 0); + FES.flashSize = (LibVBANext.FrontEndSettings.FlashSize)game.GetInt("flashSize", 0x10000); + FES.enableRtc = game.GetInt("rtcEnabled", 0) != 0; + FES.mirroringEnable = game.GetInt("mirroringEnabled", 0) != 0; Console.WriteLine("GameDB loaded settings: saveType={0}, flashSize={1}, rtcEnabled={2}, mirroringEnabled={3}", FES.saveType, FES.flashSize, FES.enableRtc, FES.mirroringEnable); - _SyncSettings = (SyncSettings)_SS ?? new SyncSettings(); + _SyncSettings = (SyncSettings)syncsettings ?? new SyncSettings(); DeterministicEmulation = deterministic; FES.skipBios = _SyncSettings.SkipBios; @@ -60,7 +61,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA throw new InvalidOperationException("Create() returned nullptr!"); try { - if (!LibVBANext.LoadRom(Core, romfile, (uint)romfile.Length, biosfile, (uint)biosfile.Length, FES)) + if (!LibVBANext.LoadRom(Core, rom, (uint)rom.Length, biosfile, (uint)biosfile.Length, FES)) throw new InvalidOperationException("LoadRom() returned false!"); CoreComm.VsyncNum = 262144; @@ -68,7 +69,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA CoreComm.NominalWidth = 240; CoreComm.NominalHeight = 160; - GameCode = Encoding.ASCII.GetString(romfile, 0xac, 4); + GameCode = Encoding.ASCII.GetString(rom, 0xac, 4); Console.WriteLine("Game code \"{0}\"", GameCode); savebuff = new byte[LibVBANext.BinStateSize(Core)]; diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.cs index f8571f7c7f..9fdfae42d5 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.cs @@ -120,7 +120,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy #endregion - public Gameboy(CoreComm comm, GameInfo game, byte[] romdata, object Settings, object SyncSettings, bool deterministic) + [CoreConstructor("GB", "GBC")] + public Gameboy(CoreComm comm, GameInfo game, byte[] rom, object Settings, object SyncSettings, bool deterministic) { CoreComm = comm; @@ -132,8 +133,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy comm.NominalWidth = 160; comm.NominalHeight = 144; - ThrowExceptionForBadRom(romdata); - BoardName = MapperName(romdata); + ThrowExceptionForBadRom(rom); + BoardName = MapperName(rom); DeterministicEmulation = deterministic; @@ -158,7 +159,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy if (this._SyncSettings.MulticartCompat) flags |= LibGambatte.LoadFlags.MULTICART_COMPAT; - if (LibGambatte.gambatte_load(GambatteState, romdata, (uint)romdata.Length, GetCurrentTime(), flags) != 0) + if (LibGambatte.gambatte_load(GambatteState, rom, (uint)rom.Length, GetCurrentTime(), flags) != 0) throw new InvalidOperationException("gambatte_load() returned non-zero (is this not a gb or gbc rom?)"); // set real default colors (before anyone mucks with them at all) @@ -178,8 +179,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy CoreComm.RomStatusDetails = string.Format("{0}\r\nSHA1:{1}\r\nMD5:{2}\r\n", game.Name, - romdata.HashSHA1(), - romdata.HashMD5()); + rom.HashSHA1(), + rom.HashMD5()); { byte[] buff = new byte[32]; diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/N64.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/N64.cs index 558704668e..ec9f1a04da 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/N64.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/N64.cs @@ -47,6 +47,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64 /// Game information of game to load /// Rom that should be loaded /// N64SyncSettings object + [CoreConstructor("N64")] public N64(CoreComm comm, GameInfo game, byte[] rom, object settings, object syncSettings) { int SaveType = 0; diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NES.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NES.cs index f43b7b45a9..7c5775a6bb 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NES.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NES.cs @@ -22,6 +22,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES static readonly bool USE_DATABASE = true; public RomStatus RomStatus; + [CoreConstructor("NES")] public NES(CoreComm comm, GameInfo game, byte[] rom, object Settings, object SyncSettings) { byte[] fdsbios = comm.CoreFileProvider.GetFirmware("NES", "Bios_FDS", false); diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/QuickNES/QuickNES.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/QuickNES/QuickNES.cs index 9e7477b07f..4a746d90e2 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/QuickNES/QuickNES.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/QuickNES/QuickNES.cs @@ -59,11 +59,12 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.QuickNES LibQuickNES.qn_setup_mappers(); } - public QuickNES(CoreComm nextComm, byte[] Rom, object Settings) + [CoreConstructor("NES")] + public QuickNES(CoreComm comm, byte[] Rom, object Settings) { using (FP.Save()) { - CoreComm = nextComm; + CoreComm = comm; Context = LibQuickNES.qn_new(); if (Context == IntPtr.Zero) diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES9X/Snes9x.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES9X/Snes9x.cs index e24844aa6a..3a77c1a160 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES9X/Snes9x.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES9X/Snes9x.cs @@ -27,12 +27,13 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES9X { } - public Snes9x(CoreComm NextComm, byte[] rom) + [CoreConstructor("SNES")] + public Snes9x(CoreComm comm, byte[] rom) { if (!LibSnes9x.debug_init(rom, rom.Length)) throw new Exception(); - CoreComm = NextComm; + CoreComm = comm; } public void FrameAdvance(bool render, bool rendersound = true) diff --git a/BizHawk.Emulation.Cores/Consoles/PC Engine/PCEngine.cs b/BizHawk.Emulation.Cores/Consoles/PC Engine/PCEngine.cs index 7dfca2fd03..1227f5e672 100644 --- a/BizHawk.Emulation.Cores/Consoles/PC Engine/PCEngine.cs +++ b/BizHawk.Emulation.Cores/Consoles/PC Engine/PCEngine.cs @@ -64,6 +64,7 @@ namespace BizHawk.Emulation.Cores.PCEngine // 21,477,270 Machine clocks / sec // 7,159,090 Cpu cycles / sec + [CoreConstructor("PCE", "SGX")] public PCEngine(CoreComm comm, GameInfo game, byte[] rom, object Settings, object syncSettings) { CoreComm = comm; diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/SMS/SMS.cs b/BizHawk.Emulation.Cores/Consoles/Sega/SMS/SMS.cs index d9cfa2f7b6..1adf17dab3 100644 --- a/BizHawk.Emulation.Cores/Consoles/Sega/SMS/SMS.cs +++ b/BizHawk.Emulation.Cores/Consoles/Sega/SMS/SMS.cs @@ -92,6 +92,7 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem public DisplayType DisplayType { get; set; } public bool DeterministicEmulation { get { return true; } } + [CoreConstructor("SMS", "SG", "GG")] public SMS(CoreComm comm, GameInfo game, byte[] rom, object settings, object syncSettings) { Settings = (SMSSettings)settings ?? new SMSSettings(); diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGX.cs b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGX.cs index 7ecdb3d886..6259730237 100644 --- a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGX.cs +++ b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGX.cs @@ -51,14 +51,18 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx Mouse }; - public GPGX(CoreComm NextComm, byte[] romfile, DiscSystem.Disc CD, string romextension, object Settings, object SyncSettings) + [CoreConstructor("GEN")] + public GPGX(CoreComm comm, byte[] rom, DiscSystem.Disc CD, object Settings, object SyncSettings) { + // this can influence some things internally + string romextension = "GEN"; + // three or six button? // http://www.sega-16.com/forum/showthread.php?4398-Forgotten-Worlds-giving-you-GAME-OVER-immediately-Fix-inside&highlight=forgotten%20worlds //hack, don't use //romfile = File.ReadAllBytes(@"D:\encodes\bizhawksrc\output\SANIC CD\PierSolar (E).bin"); - if (romfile != null && romfile.Length > 16 * 1024 * 1024) + if (rom != null && rom.Length > 16 * 1024 * 1024) { throw new InvalidOperationException("ROM too big! Did you try to load a CD as a ROM?"); } @@ -67,7 +71,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx { _SyncSettings = (GPGXSyncSettings)SyncSettings ?? new GPGXSyncSettings(); - CoreComm = NextComm; + CoreComm = comm; if (AttachedCore != null) { AttachedCore.Dispose(); @@ -77,7 +81,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx LoadCallback = new LibGPGX.load_archive_cb(load_archive); - this.romfile = romfile; + this.romfile = rom; this.CD = CD; LibGPGX.INPUT_SYSTEM system_a = LibGPGX.INPUT_SYSTEM.SYSTEM_NONE; diff --git a/BizHawk.Emulation.Cores/Consoles/WonderSwan/WonderSwan.cs b/BizHawk.Emulation.Cores/Consoles/WonderSwan/WonderSwan.cs index 2972db8701..f156e93c6e 100644 --- a/BizHawk.Emulation.Cores/Consoles/WonderSwan/WonderSwan.cs +++ b/BizHawk.Emulation.Cores/Consoles/WonderSwan/WonderSwan.cs @@ -85,20 +85,21 @@ namespace BizHawk.Emulation.Cores.WonderSwan #endregion - public WonderSwan(CoreComm comm, byte[] rom, bool deterministicEmulation, object Settings, object SyncSettings) + [CoreConstructor("WSWAN")] + public WonderSwan(CoreComm comm, byte[] rom, bool deterministic, object Settings, object SyncSettings) { CoreComm = comm; _Settings = (Settings)Settings ?? new Settings(); _SyncSettings = (SyncSettings)SyncSettings ?? new SyncSettings(); - DeterministicEmulation = deterministicEmulation; // when true, remember to force the RTC flag! + DeterministicEmulation = deterministic; // when true, remember to force the RTC flag! Core = BizSwan.bizswan_new(); if (Core == IntPtr.Zero) throw new InvalidOperationException("bizswan_new() returned NULL!"); try { var ss = _SyncSettings.GetNativeSettings(); - if (deterministicEmulation) + if (deterministic) ss.userealtime = false; bool rotate = false; diff --git a/BizHawk.Emulation.Cores/CoreInventory.cs b/BizHawk.Emulation.Cores/CoreInventory.cs new file mode 100644 index 0000000000..cbe34389b1 --- /dev/null +++ b/BizHawk.Emulation.Cores/CoreInventory.cs @@ -0,0 +1,159 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Reflection; +using BizHawk.Emulation.Common; +using BizHawk.Emulation.DiscSystem; + +namespace BizHawk.Emulation.Cores +{ + public class CoreInventory + { + public class Core + { + public readonly string Name; + public readonly Type Type; + public readonly ConstructorInfo CTor; + + public Core(string Name, Type Type, ConstructorInfo CTor) + { + this.Name = Name; + this.Type = Type; + this.CTor = CTor; + + var pp = CTor.GetParameters(); + for (int i = 0; i < pp.Length ; i++) + { + var p = pp[i]; + string pname = p.Name.ToLowerInvariant(); + Type expectedtype; + if (!paramtypes.TryGetValue(pname, out expectedtype)) + throw new InvalidOperationException(string.Format("Unexpected parameter name {0} in constructor for {1}", p.Name, Type)); + if (expectedtype != p.ParameterType) + throw new InvalidOperationException(string.Format("Unexpected type mismatch in parameter {0} in constructor for {1}", p.Name, Type)); + parammap.Add(pname, i); + } + } + + // map parameter names to locations in the constructor + private readonly Dictionary parammap = new Dictionary(); + // expected names and types of the parameters + private static readonly Dictionary paramtypes = new Dictionary(); + + static Core() + { + var pp = typeof(Core).GetMethod("Create").GetParameters(); + foreach (var p in pp) + paramtypes.Add(p.Name.ToLowerInvariant(), p.ParameterType); + } + + void bp(object[] parameters, string name, object value) + { + int i; + if (parammap.TryGetValue(name, out i)) + parameters[i] = value; + } + + public IEmulator Create + ( + CoreComm comm, + GameInfo game, + byte[] rom, + Disc cd, + bool deterministic, + object settings, + object syncsettings + ) + { + object[] o = new object[parammap.Count]; + bp(o, "comm", comm); + bp(o, "game", game); + bp(o, "rom", rom); + bp(o, "cd", cd); + bp(o, "deterministic", deterministic); + bp(o, "settings", settings); + bp(o, "syncsettings", syncsettings); + + return (IEmulator)CTor.Invoke(o); + } + } + + private readonly Dictionary> systems = new Dictionary>(); + + + private void ProcessConstructor(Type type, string system, CoreAttributes coreattr, ConstructorInfo cons) + { + Core core = new Core(coreattr.CoreName, type, cons); + List ss; + if (!systems.TryGetValue(system, out ss)) + { + ss = new List(); + systems.Add(system, ss); + } + ss.Add(core); + } + + public Core this[string system] + { + get + { + List ss = systems[system]; + if (ss.Count != 1) + throw new InvalidOperationException("Ambiguous core selection!"); + return ss[0]; + } + } + public Core this[string system, string core] + { + get + { + List ss = systems[system]; + foreach (Core c in ss) + { + if (c.Name == core) + return c; + } + throw new InvalidOperationException("No such core!"); + } + } + + public CoreInventory(IEnumerable assys) + { + foreach (var assy in assys) + { + foreach (var typ in assy.GetTypes()) + { + if (typ.GetInterfaces().Contains(typeof(IEmulator))) + { + var coreattr = typ.GetCustomAttributes(typeof(CoreAttributes), false); + if (coreattr.Length != 1) + throw new InvalidOperationException(string.Format("IEmulator {0} without CoreAttributes!", typ)); + var cons = typ.GetConstructors(BindingFlags.Public | BindingFlags.Instance) + .Where(c => c.GetCustomAttributes(typeof(CoreConstructorAttribute), false).Length > 0).ToList(); + foreach(var con in cons) + { + foreach (string system in ((CoreConstructorAttribute)con.GetCustomAttributes(typeof(CoreConstructorAttribute), false)[0]).Systems) + { + ProcessConstructor(typ, system, (CoreAttributes)coreattr[0], con); + } + } + } + } + } + } + + public static readonly CoreInventory Instance = new CoreInventory(new[] { typeof(CoreInventory).Assembly }); + } + + [AttributeUsage(AttributeTargets.Constructor)] + public class CoreConstructorAttribute : Attribute + { + public IEnumerable Systems { get { return _systems; } } + private readonly List _systems = new List(); + public CoreConstructorAttribute(params string[] Systems) + { + _systems.AddRange(Systems); + } + } +} diff --git a/BizHawk.Emulation.Cores/LibRetroEmulator.cs b/BizHawk.Emulation.Cores/LibRetroEmulator.cs index 9c1bbc1c67..45464de982 100644 --- a/BizHawk.Emulation.Cores/LibRetroEmulator.cs +++ b/BizHawk.Emulation.Cores/LibRetroEmulator.cs @@ -8,6 +8,7 @@ using BizHawk.Emulation.Common; namespace BizHawk.Emulation.Cores { + [CoreAttributes("DEBUG ONLY DON'T USE", "natt")] public unsafe class LibRetroEmulator : IEmulator, IVideoProvider { #region callbacks