Next piece of the puzzle
This probably breaks something. I am sorry, grab me and I'll fix it
This commit is contained in:
parent
33a0954087
commit
5c5ffed5ff
|
@ -423,7 +423,50 @@ namespace BizHawk.Client.Common
|
||||||
throw new NotImplementedException("M3U not supported!");
|
throw new NotImplementedException("M3U not supported!");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LoadOther(string path, CoreComm nextComm, bool forceAccurateCore, HawkFile file, out IEmulator nextEmulator, out RomGame rom, out GameInfo game, out bool cancel)
|
private static string ForcedCoreToCoreName(string forcedCore)
|
||||||
|
{
|
||||||
|
// TODO: Is this yet another list of core names really needed? Let's just make the gamedb less dumb
|
||||||
|
return forcedCore switch
|
||||||
|
{
|
||||||
|
"snes9x" => CoreNames.Snes9X,
|
||||||
|
"bsnes" => CoreNames.Bsnes,
|
||||||
|
"quicknes" => CoreNames.QuickNes,
|
||||||
|
"pico" => CoreNames.PicoDrive,
|
||||||
|
_ => null
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private IEmulator MakeCoreFromCoreInventory(string systemId, CoreInventoryParameters cip, string forcedCoreGameDb)
|
||||||
|
{
|
||||||
|
_config.PreferredCores.TryGetValue(systemId, out var preferredCore);
|
||||||
|
var forcedCore = ForcedCoreToCoreName(forcedCoreGameDb);
|
||||||
|
var cores = CoreInventory.Instance.GetCores(systemId)
|
||||||
|
.OrderBy(c =>
|
||||||
|
{
|
||||||
|
if (c.Name == preferredCore)
|
||||||
|
return (int)CorePriority.UserPreference;
|
||||||
|
else if (c.Name == forcedCore)
|
||||||
|
return (int)CorePriority.GameDbPreference;
|
||||||
|
else
|
||||||
|
return (int)c.Priority;
|
||||||
|
})
|
||||||
|
.ToList();
|
||||||
|
var exceptions = new List<Exception>();
|
||||||
|
foreach (var core in cores)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return core.Create(cip);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
exceptions.Add(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new AggregateException("No core could load the ROM", exceptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadOther(string path, CoreComm nextComm, HawkFile file, out IEmulator nextEmulator, out RomGame rom, out GameInfo game, out bool cancel)
|
||||||
{
|
{
|
||||||
cancel = false;
|
cancel = false;
|
||||||
rom = new RomGame(file);
|
rom = new RomGame(file);
|
||||||
|
@ -463,92 +506,17 @@ namespace BizHawk.Client.Common
|
||||||
|
|
||||||
game = rom.GameInfo;
|
game = rom.GameInfo;
|
||||||
|
|
||||||
var isXml = false;
|
|
||||||
if (file.Extension.ToLowerInvariant() == ".xml")
|
|
||||||
{
|
|
||||||
game.System = "SNES"; // other xml has already been handled
|
|
||||||
isXml = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
nextEmulator = null;
|
nextEmulator = null;
|
||||||
if (game.System == null)
|
if (game.System == null)
|
||||||
return; // The user picked nothing in the Core picker
|
return; // The user picked nothing in the Core picker
|
||||||
|
|
||||||
CoreInventory.Core core;
|
|
||||||
switch (game.System)
|
switch (game.System)
|
||||||
{
|
{
|
||||||
case "SNES":
|
|
||||||
var name = game.ForcedCore?.ToLower() switch
|
|
||||||
{
|
|
||||||
"snes9x" => CoreNames.Snes9X,
|
|
||||||
"bsnes" => CoreNames.Bsnes,
|
|
||||||
_ => _config.PreferredCores["SNES"]
|
|
||||||
};
|
|
||||||
try
|
|
||||||
{
|
|
||||||
core = CoreInventory.Instance["SNES", name];
|
|
||||||
}
|
|
||||||
catch // TODO: CoreInventory should support some sort of trygetvalue
|
|
||||||
{
|
|
||||||
// need to get rid of this hack at some point
|
|
||||||
nextEmulator = new LibsnesCore(
|
|
||||||
game,
|
|
||||||
isXml ? null : rom.FileData,
|
|
||||||
isXml ? rom.FileData : null,
|
|
||||||
Path.GetDirectoryName(path.SubstringBefore('|')),
|
|
||||||
nextComm,
|
|
||||||
GetCoreSettings<LibsnesCore, LibsnesCore.SnesSettings>(),
|
|
||||||
GetCoreSyncSettings<LibsnesCore, LibsnesCore.SnesSyncSettings>()
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "NES":
|
|
||||||
// apply main spur-of-the-moment switcheroo as lowest priority
|
|
||||||
var preference = _config.PreferredCores["NES"];
|
|
||||||
|
|
||||||
// if user has saw fit to override in gamedb, apply that
|
|
||||||
if (!string.IsNullOrEmpty(game.ForcedCore))
|
|
||||||
{
|
|
||||||
preference = game.ForcedCore.ToLower() switch
|
|
||||||
{
|
|
||||||
"quicknes" => CoreNames.QuickNes,
|
|
||||||
_ => CoreNames.NesHawk
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// but only neshawk is accurate
|
|
||||||
if (forceAccurateCore)
|
|
||||||
{
|
|
||||||
preference = CoreNames.NesHawk;
|
|
||||||
}
|
|
||||||
|
|
||||||
core = CoreInventory.Instance["NES", preference];
|
|
||||||
break;
|
|
||||||
case "GB":
|
case "GB":
|
||||||
case "GBC":
|
case "GBC":
|
||||||
if (_config.GbAsSgb)
|
if (_config.GbAsSgb)
|
||||||
{
|
{
|
||||||
if (_config.SgbUseBsnes)
|
game.System = "SGB";
|
||||||
{
|
|
||||||
game.System = "SNES";
|
|
||||||
game.AddOption("SGB", "");
|
|
||||||
nextEmulator = new LibsnesCore(
|
|
||||||
game,
|
|
||||||
rom.FileData,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
nextComm,
|
|
||||||
GetCoreSettings<LibsnesCore, LibsnesCore.SnesSettings>(),
|
|
||||||
GetCoreSyncSettings<LibsnesCore, LibsnesCore.SnesSyncSettings>()
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
core = CoreInventory.Instance["SGB", CoreNames.SameBoy];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
core = CoreInventory.Instance["GB", _config.PreferredCores["GB"]];
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "ChannelF":
|
case "ChannelF":
|
||||||
|
@ -567,17 +535,10 @@ namespace BizHawk.Client.Common
|
||||||
);
|
);
|
||||||
rom.GameInfo.Name = gameName;
|
rom.GameInfo.Name = gameName;
|
||||||
return;
|
return;
|
||||||
case "GEN":
|
|
||||||
core = CoreInventory.Instance["GEN", game.ForcedCore?.ToLower() == "pico" ? CoreNames.PicoDrive : CoreNames.Gpgx];
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
core = _config.PreferredCores.TryGetValue(game.System, out var coreName)
|
|
||||||
? CoreInventory.Instance[game.System, coreName]
|
|
||||||
: CoreInventory.Instance[game.System];
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
var cip = new CoreInventoryParameters(this)
|
||||||
nextEmulator = core.Create(new CoreInventoryParameters(this)
|
|
||||||
{
|
{
|
||||||
Comm = nextComm,
|
Comm = nextComm,
|
||||||
Game = game,
|
Game = game,
|
||||||
|
@ -593,7 +554,8 @@ namespace BizHawk.Client.Common
|
||||||
},
|
},
|
||||||
DeterministicEmulationRequested = Deterministic
|
DeterministicEmulationRequested = Deterministic
|
||||||
|
|
||||||
});
|
};
|
||||||
|
nextEmulator = MakeCoreFromCoreInventory(game.System, cip, game.ForcedCore);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LoadPSF(string path, CoreComm nextComm, HawkFile file, out IEmulator nextEmulator, out RomGame rom, out GameInfo game)
|
private void LoadPSF(string path, CoreComm nextComm, HawkFile file, out IEmulator nextEmulator, out RomGame rom, out GameInfo game)
|
||||||
|
@ -747,7 +709,7 @@ namespace BizHawk.Client.Common
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool LoadRom(string path, CoreComm nextComm, string launchLibretroCore, bool forceAccurateCore = false, int recursiveCount = 0)
|
public bool LoadRom(string path, CoreComm nextComm, string launchLibretroCore, int recursiveCount = 0)
|
||||||
{
|
{
|
||||||
if (path == null) return false;
|
if (path == null) return false;
|
||||||
|
|
||||||
|
@ -862,7 +824,7 @@ namespace BizHawk.Client.Common
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LoadOther(path, nextComm, forceAccurateCore, file, out nextEmulator, out rom, out game, out cancel); // must be called after LoadXML because of SNES hacks
|
LoadOther(path, nextComm, file, out nextEmulator, out rom, out game, out cancel); // must be called after LoadXML because of SNES hacks
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -894,7 +856,7 @@ namespace BizHawk.Client.Common
|
||||||
DoMessageCallback("Unable to use quicknes, using NESHawk instead");
|
DoMessageCallback("Unable to use quicknes, using NESHawk instead");
|
||||||
}
|
}
|
||||||
|
|
||||||
return LoadRom(path, nextComm, launchLibretroCore, true, recursiveCount + 1);
|
return LoadRom(path, nextComm, launchLibretroCore, recursiveCount + 1);
|
||||||
}
|
}
|
||||||
else if (ex is MissingFirmwareException)
|
else if (ex is MissingFirmwareException)
|
||||||
{
|
{
|
||||||
|
@ -906,7 +868,7 @@ namespace BizHawk.Client.Common
|
||||||
// To avoid catch-22, disable SGB mode
|
// To avoid catch-22, disable SGB mode
|
||||||
_config.GbAsSgb = false;
|
_config.GbAsSgb = false;
|
||||||
DoMessageCallback("Failed to load a GB rom in SGB mode. Disabling SGB Mode.");
|
DoMessageCallback("Failed to load a GB rom in SGB mode. Disabling SGB Mode.");
|
||||||
return LoadRom(path, nextComm, launchLibretroCore, false, recursiveCount + 1);
|
return LoadRom(path, nextComm, launchLibretroCore, recursiveCount + 1);
|
||||||
}
|
}
|
||||||
else if (ex is NoAvailableCoreException)
|
else if (ex is NoAvailableCoreException)
|
||||||
{
|
{
|
||||||
|
|
|
@ -16,7 +16,8 @@ namespace BizHawk.Emulation.Cores.Consoles.NEC.PCE
|
||||||
{
|
{
|
||||||
private readonly LibHyperNyma _hyperNyma;
|
private readonly LibHyperNyma _hyperNyma;
|
||||||
|
|
||||||
[CoreConstructor(new[] { "PCE", "SGX" })]
|
[CoreConstructor("PCE", Priority = CorePriority.Low)]
|
||||||
|
[CoreConstructor("SGX", Priority = CorePriority.Low)]
|
||||||
public HyperNyma(GameInfo game, byte[] rom, CoreComm comm, string extension,
|
public HyperNyma(GameInfo game, byte[] rom, CoreComm comm, string extension,
|
||||||
NymaSettings settings, NymaSyncSettings syncSettings, bool deterministic)
|
NymaSettings settings, NymaSyncSettings syncSettings, bool deterministic)
|
||||||
: base(comm, "PCE", "PC Engine Controller", settings, syncSettings)
|
: base(comm, "PCE", "PC Engine Controller", settings, syncSettings)
|
||||||
|
|
|
@ -16,7 +16,8 @@ namespace BizHawk.Emulation.Cores.Consoles.NEC.PCE
|
||||||
{
|
{
|
||||||
private readonly LibTurboNyma _turboNyma;
|
private readonly LibTurboNyma _turboNyma;
|
||||||
|
|
||||||
[CoreConstructor(new[] { "PCE", "SGX" })]
|
[CoreConstructor("PCE")]
|
||||||
|
[CoreConstructor("SGX")]
|
||||||
public TurboNyma(GameInfo game, byte[] rom, CoreComm comm, string extension,
|
public TurboNyma(GameInfo game, byte[] rom, CoreComm comm, string extension,
|
||||||
NymaSettings settings, NymaSyncSettings syncSettings, bool deterministic)
|
NymaSettings settings, NymaSyncSettings syncSettings, bool deterministic)
|
||||||
: base(comm, "PCE", "PC Engine Controller", settings, syncSettings)
|
: base(comm, "PCE", "PC Engine Controller", settings, syncSettings)
|
||||||
|
|
|
@ -93,7 +93,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||||
|
|
||||||
private static byte[] GBA_override = { 0xFF, 0x00, 0xCD, 0x03, 0x35, 0xAA, 0x31, 0x90, 0x94, 0x00, 0x00, 0x00, 0x00 };
|
private static byte[] GBA_override = { 0xFF, 0x00, 0xCD, 0x03, 0x35, 0xAA, 0x31, 0x90, 0x94, 0x00, 0x00, 0x00, 0x00 };
|
||||||
|
|
||||||
[CoreConstructor(new[] { "GB", "GBC" })]
|
[CoreConstructor("GB")]
|
||||||
|
[CoreConstructor("GBC")]
|
||||||
public GBHawk(CoreComm comm, GameInfo game, byte[] rom, /*string gameDbFn,*/ GBSettings settings, GBSyncSettings syncSettings)
|
public GBHawk(CoreComm comm, GameInfo game, byte[] rom, /*string gameDbFn,*/ GBSettings settings, GBSyncSettings syncSettings)
|
||||||
{
|
{
|
||||||
var ser = new BasicServiceProvider(this);
|
var ser = new BasicServiceProvider(this);
|
||||||
|
|
|
@ -23,7 +23,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
|
||||||
IBoardInfo, IRomInfo, IDebuggable, ISettable<Gameboy.GambatteSettings, Gameboy.GambatteSyncSettings>,
|
IBoardInfo, IRomInfo, IDebuggable, ISettable<Gameboy.GambatteSettings, Gameboy.GambatteSyncSettings>,
|
||||||
IGameboyCommon, ICycleTiming, ILinkable
|
IGameboyCommon, ICycleTiming, ILinkable
|
||||||
{
|
{
|
||||||
[CoreConstructor(new[] { "GB", "GBC" })]
|
[CoreConstructor("GB")]
|
||||||
|
[CoreConstructor("GBC")]
|
||||||
public Gameboy(CoreComm comm, GameInfo game, byte[] file, Gameboy.GambatteSettings settings, Gameboy.GambatteSyncSettings syncSettings, bool deterministic)
|
public Gameboy(CoreComm comm, GameInfo game, byte[] file, Gameboy.GambatteSettings settings, Gameboy.GambatteSyncSettings syncSettings, bool deterministic)
|
||||||
{
|
{
|
||||||
var ser = new BasicServiceProvider(this);
|
var ser = new BasicServiceProvider(this);
|
||||||
|
|
|
@ -41,6 +41,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.Gameboy
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
[CoreConstructor("GB")]
|
[CoreConstructor("GB")]
|
||||||
|
[CoreConstructor("GBC")]
|
||||||
public Sameboy(CoreComm comm, byte[] rom, Settings settings, SyncSettings syncSettings, bool deterministic)
|
public Sameboy(CoreComm comm, byte[] rom, Settings settings, SyncSettings syncSettings, bool deterministic)
|
||||||
: this(rom, comm, false, settings, syncSettings, deterministic)
|
: this(rom, comm, false, settings, syncSettings, deterministic)
|
||||||
{ }
|
{ }
|
||||||
|
|
|
@ -33,7 +33,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.QuickNES
|
||||||
QN.qn_setup_mappers();
|
QN.qn_setup_mappers();
|
||||||
}
|
}
|
||||||
|
|
||||||
[CoreConstructor("NES")]
|
[CoreConstructor("NES", Priority = CorePriority.Low)]
|
||||||
public QuickNES(byte[] file, QuickNESSettings settings, QuickNESSyncSettings syncSettings)
|
public QuickNES(byte[] file, QuickNESSettings settings, QuickNESSyncSettings syncSettings)
|
||||||
{
|
{
|
||||||
FP = OSTailoredCode.IsUnixHost
|
FP = OSTailoredCode.IsUnixHost
|
||||||
|
|
|
@ -29,6 +29,13 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES
|
||||||
public unsafe partial class LibsnesCore : IEmulator, IVideoProvider, ISaveRam, IStatable, IInputPollable, IRegionable, ICodeDataLogger,
|
public unsafe partial class LibsnesCore : IEmulator, IVideoProvider, ISaveRam, IStatable, IInputPollable, IRegionable, ICodeDataLogger,
|
||||||
IDebuggable, ISettable<LibsnesCore.SnesSettings, LibsnesCore.SnesSyncSettings>
|
IDebuggable, ISettable<LibsnesCore.SnesSettings, LibsnesCore.SnesSyncSettings>
|
||||||
{
|
{
|
||||||
|
[CoreConstructor("SGB")]
|
||||||
|
[CoreConstructor("SNES")]
|
||||||
|
public LibsnesCore(GameInfo game, byte[] rom, CoreComm comm,
|
||||||
|
LibsnesCore.SnesSettings settings, LibsnesCore.SnesSyncSettings syncSettings)
|
||||||
|
:this(game, rom, null, null, comm, settings, syncSettings)
|
||||||
|
{}
|
||||||
|
|
||||||
public LibsnesCore(GameInfo game, byte[] romData, byte[] xmlData, string baseRomPath, CoreComm comm,
|
public LibsnesCore(GameInfo game, byte[] romData, byte[] xmlData, string baseRomPath, CoreComm comm,
|
||||||
LibsnesCore.SnesSettings settings, LibsnesCore.SnesSyncSettings syncSettings)
|
LibsnesCore.SnesSettings settings, LibsnesCore.SnesSyncSettings syncSettings)
|
||||||
{
|
{
|
||||||
|
@ -47,7 +54,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES
|
||||||
CoreComm = comm;
|
CoreComm = comm;
|
||||||
byte[] sgbRomData = null;
|
byte[] sgbRomData = null;
|
||||||
|
|
||||||
if (game["SGB"])
|
if (game.System == "SGB")
|
||||||
{
|
{
|
||||||
if ((romData[0x143] & 0xc0) == 0xc0)
|
if ((romData[0x143] & 0xc0) == 0xc0)
|
||||||
{
|
{
|
||||||
|
@ -112,7 +119,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES
|
||||||
romData = newData;
|
romData = newData;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (game["SGB"])
|
if (game.System == "SGB")
|
||||||
{
|
{
|
||||||
IsSGB = true;
|
IsSGB = true;
|
||||||
SystemId = "SNES";
|
SystemId = "SNES";
|
||||||
|
|
|
@ -14,7 +14,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.SubGBHawk
|
||||||
public partial class SubGBHawk : IEmulator, IStatable, IInputPollable,
|
public partial class SubGBHawk : IEmulator, IStatable, IInputPollable,
|
||||||
ISettable<GBHawk.GBHawk.GBSettings, GBHawk.GBHawk.GBSyncSettings>, IDebuggable
|
ISettable<GBHawk.GBHawk.GBSettings, GBHawk.GBHawk.GBSyncSettings>, IDebuggable
|
||||||
{
|
{
|
||||||
[CoreConstructor(new[] { "GB", "GBC" })]
|
[CoreConstructor("GB", Priority = CorePriority.SuperLow)]
|
||||||
|
[CoreConstructor("GBC", Priority = CorePriority.SuperLow)]
|
||||||
public SubGBHawk(CoreComm comm, GameInfo game, byte[] rom, /*string gameDbFn,*/ GBHawk.GBHawk.GBSettings settings, GBHawk.GBHawk.GBSyncSettings syncSettings)
|
public SubGBHawk(CoreComm comm, GameInfo game, byte[] rom, /*string gameDbFn,*/ GBHawk.GBHawk.GBSettings settings, GBHawk.GBHawk.GBSyncSettings syncSettings)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.SubNESHawk
|
||||||
public partial class SubNESHawk : IEmulator, IStatable, IInputPollable,
|
public partial class SubNESHawk : IEmulator, IStatable, IInputPollable,
|
||||||
ISettable<NES.NES.NESSettings, NES.NES.NESSyncSettings>
|
ISettable<NES.NES.NESSettings, NES.NES.NESSyncSettings>
|
||||||
{
|
{
|
||||||
[CoreConstructor("NES")]
|
[CoreConstructor("NES", Priority = CorePriority.SuperLow)]
|
||||||
public SubNESHawk(CoreComm comm, GameInfo game, byte[] rom, /*string gameDbFn,*/ NES.NES.NESSettings settings, NES.NES.NESSyncSettings syncSettings)
|
public SubNESHawk(CoreComm comm, GameInfo game, byte[] rom, /*string gameDbFn,*/ NES.NES.NESSettings settings, NES.NES.NESSyncSettings syncSettings)
|
||||||
{
|
{
|
||||||
var subNesSettings = (NES.NES.NESSettings)settings ?? new NES.NES.NESSettings();
|
var subNesSettings = (NES.NES.NESSettings)settings ?? new NES.NES.NESSettings();
|
||||||
|
|
|
@ -21,7 +21,8 @@ namespace BizHawk.Emulation.Cores.PCEngine
|
||||||
IDebuggable, ISettable<PCEngine.PCESettings, PCEngine.PCESyncSettings>, IDriveLight, ICodeDataLogger,
|
IDebuggable, ISettable<PCEngine.PCESettings, PCEngine.PCESyncSettings>, IDriveLight, ICodeDataLogger,
|
||||||
IPceGpuView
|
IPceGpuView
|
||||||
{
|
{
|
||||||
[CoreConstructor(new[] { "PCE", "SGX" })]
|
[CoreConstructor("PCE", Priority = CorePriority.Low)]
|
||||||
|
[CoreConstructor("SGX", Priority = CorePriority.Low)]
|
||||||
public PCEngine(GameInfo game, byte[] rom, PCEngine.PCESettings settings, PCEngine.PCESyncSettings syncSettings)
|
public PCEngine(GameInfo game, byte[] rom, PCEngine.PCESettings settings, PCEngine.PCESyncSettings syncSettings)
|
||||||
{
|
{
|
||||||
switch (game.System)
|
switch (game.System)
|
||||||
|
|
|
@ -19,7 +19,8 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.PicoDrive
|
||||||
private DiscSectorReader _cdReader;
|
private DiscSectorReader _cdReader;
|
||||||
private bool _isPal;
|
private bool _isPal;
|
||||||
|
|
||||||
[CoreConstructor(new[] { "GEN", "32X" })]
|
[CoreConstructor("GEN", Priority = CorePriority.Low)]
|
||||||
|
[CoreConstructor("32X")]
|
||||||
public PicoDrive(CoreComm comm, GameInfo game, byte[] rom, bool deterministic, SyncSettings syncSettings)
|
public PicoDrive(CoreComm comm, GameInfo game, byte[] rom, bool deterministic, SyncSettings syncSettings)
|
||||||
: this(comm, game, rom, null, deterministic, syncSettings)
|
: this(comm, game, rom, null, deterministic, syncSettings)
|
||||||
{ }
|
{ }
|
||||||
|
|
|
@ -23,7 +23,9 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
|
||||||
public partial class SMS : IEmulator, ISoundProvider, ISaveRam, IInputPollable, IRegionable,
|
public partial class SMS : IEmulator, ISoundProvider, ISaveRam, IInputPollable, IRegionable,
|
||||||
IDebuggable, ISettable<SMS.SmsSettings, SMS.SmsSyncSettings>, ICodeDataLogger
|
IDebuggable, ISettable<SMS.SmsSettings, SMS.SmsSyncSettings>, ICodeDataLogger
|
||||||
{
|
{
|
||||||
[CoreConstructor(new[] { "SMS", "SG", "GG" })]
|
[CoreConstructor("SMS")]
|
||||||
|
[CoreConstructor("SG")]
|
||||||
|
[CoreConstructor("GG")]
|
||||||
public SMS(CoreComm comm, GameInfo game, byte[] rom, SmsSettings settings, SmsSyncSettings syncSettings)
|
public SMS(CoreComm comm, GameInfo game, byte[] rom, SmsSettings settings, SmsSyncSettings syncSettings)
|
||||||
{
|
{
|
||||||
var ser = new BasicServiceProvider(this);
|
var ser = new BasicServiceProvider(this);
|
||||||
|
|
|
@ -28,11 +28,12 @@ namespace BizHawk.Emulation.Cores
|
||||||
// If true, this is a new style constructor that takes a CoreLoadParameters object
|
// If true, this is a new style constructor that takes a CoreLoadParameters object
|
||||||
private readonly bool _useCoreLoadParameters;
|
private readonly bool _useCoreLoadParameters;
|
||||||
|
|
||||||
public Core(string name, Type type, ConstructorInfo ctor)
|
public Core(string name, Type type, ConstructorInfo ctor, CorePriority priority)
|
||||||
{
|
{
|
||||||
Name = name;
|
Name = name;
|
||||||
Type = type;
|
Type = type;
|
||||||
CTor = ctor;
|
CTor = ctor;
|
||||||
|
Priority = priority;
|
||||||
|
|
||||||
var pp = CTor.GetParameters();
|
var pp = CTor.GetParameters();
|
||||||
if (pp.Length == 1
|
if (pp.Length == 1
|
||||||
|
@ -65,9 +66,14 @@ namespace BizHawk.Emulation.Cores
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// (hopefully) a CoreNames value
|
||||||
|
/// </summary>
|
||||||
|
/// <value></value>
|
||||||
public string Name { get; }
|
public string Name { get; }
|
||||||
public Type Type { get; }
|
public Type Type { get; }
|
||||||
public ConstructorInfo CTor { get; }
|
public ConstructorInfo CTor { get; }
|
||||||
|
public CorePriority Priority { get; }
|
||||||
public Type SettingsType { get; } = typeof(object);
|
public Type SettingsType { get; } = typeof(object);
|
||||||
public Type SyncSettingsType { get; } = typeof(object);
|
public Type SyncSettingsType { get; } = typeof(object);
|
||||||
|
|
||||||
|
@ -116,53 +122,22 @@ namespace BizHawk.Emulation.Cores
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ProcessConstructor(Type type, string system, CoreAttribute coreAttr, ConstructorInfo cons)
|
private void ProcessConstructor(Type type, CoreConstructorAttribute consAttr, CoreAttribute coreAttr, ConstructorInfo cons)
|
||||||
{
|
{
|
||||||
Core core = new Core(coreAttr.CoreName, type, cons);
|
Core core = new Core(coreAttr.CoreName, type, cons, consAttr.Priority);
|
||||||
if (!_systems.TryGetValue(system, out var ss))
|
if (!_systems.TryGetValue(consAttr.System, out var ss))
|
||||||
{
|
{
|
||||||
ss = new List<Core>();
|
ss = new List<Core>();
|
||||||
_systems.Add(system, ss);
|
_systems.Add(consAttr.System, ss);
|
||||||
}
|
}
|
||||||
|
|
||||||
ss.Add(core);
|
ss.Add(core);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
public IEnumerable<Core> GetCores(string system)
|
||||||
/// find a core matching a particular game.system
|
|
||||||
/// </summary>
|
|
||||||
public Core this[string system]
|
|
||||||
{
|
{
|
||||||
get
|
_systems.TryGetValue(system, out var cores);
|
||||||
{
|
return cores ?? Enumerable.Empty<Core>();
|
||||||
List<Core> ss = _systems[system];
|
|
||||||
if (ss.Count != 1)
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException("Ambiguous core selection!");
|
|
||||||
}
|
|
||||||
|
|
||||||
return ss[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// find a core matching a particular game.system with a particular CoreAttributes.Name
|
|
||||||
/// </summary>
|
|
||||||
public Core this[string system, string core]
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
List<Core> ss = _systems[system];
|
|
||||||
foreach (Core c in ss)
|
|
||||||
{
|
|
||||||
if (c.Name == core)
|
|
||||||
{
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new InvalidOperationException("No such core!");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -183,9 +158,9 @@ namespace BizHawk.Emulation.Cores
|
||||||
.Where(c => c.GetCustomAttributes(typeof(CoreConstructorAttribute), false).Length > 0);
|
.Where(c => c.GetCustomAttributes(typeof(CoreConstructorAttribute), false).Length > 0);
|
||||||
foreach(var con in cons)
|
foreach(var con in cons)
|
||||||
{
|
{
|
||||||
foreach (string system in ((CoreConstructorAttribute)con.GetCustomAttributes(typeof(CoreConstructorAttribute), false)[0]).Systems)
|
foreach (var consAttr in con.GetCustomAttributes(typeof(CoreConstructorAttribute), false).Cast<CoreConstructorAttribute>())
|
||||||
{
|
{
|
||||||
ProcessConstructor(typ, system, (CoreAttribute)coreAttr[0], con);
|
ProcessConstructor(typ, consAttr, (CoreAttribute)coreAttr[0], con);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -196,23 +171,45 @@ namespace BizHawk.Emulation.Cores
|
||||||
public static readonly CoreInventory Instance = new CoreInventory(new[] { typeof(CoreInventory).Assembly });
|
public static readonly CoreInventory Instance = new CoreInventory(new[] { typeof(CoreInventory).Assembly });
|
||||||
}
|
}
|
||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Constructor)]
|
public enum CorePriority
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The gamedb has requested this core for this game
|
||||||
|
/// </summary>
|
||||||
|
GameDbPreference = -300,
|
||||||
|
/// <summary>
|
||||||
|
/// The user has indicated in preferences that this is their favourite core
|
||||||
|
/// </summary>
|
||||||
|
UserPreference = -200,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A very good core that should be prefered over normal cores. Don't use this?
|
||||||
|
/// </summary>
|
||||||
|
High = -100,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Most cores should use this
|
||||||
|
/// </summary>
|
||||||
|
Normal = 0,
|
||||||
|
/// <summary>
|
||||||
|
/// Experimental, special use, or garbage core
|
||||||
|
/// </summary>
|
||||||
|
Low = 100,
|
||||||
|
/// <summary>
|
||||||
|
/// TODO: Do we need this? Does it need a better name?
|
||||||
|
/// </summary>
|
||||||
|
SuperLow = 200,
|
||||||
|
}
|
||||||
|
|
||||||
|
[AttributeUsage(AttributeTargets.Constructor, AllowMultiple = true)]
|
||||||
public sealed class CoreConstructorAttribute : Attribute
|
public sealed class CoreConstructorAttribute : Attribute
|
||||||
{
|
{
|
||||||
private readonly List<string> _systems = new List<string>();
|
public string System { get; }
|
||||||
|
|
||||||
/// <remarks>TODO neither array nor <see cref="IEnumerable{T}"/> is the correct collection to be using here, try <see cref="IReadOnlyList{T}"/>/<see cref="IReadOnlyCollection{T}"/> instead</remarks>
|
|
||||||
public CoreConstructorAttribute(string[] systems)
|
|
||||||
{
|
|
||||||
_systems.AddRange(systems);
|
|
||||||
}
|
|
||||||
|
|
||||||
public CoreConstructorAttribute(string system)
|
public CoreConstructorAttribute(string system)
|
||||||
{
|
{
|
||||||
_systems.Add(system);
|
System = system;
|
||||||
}
|
}
|
||||||
|
public CorePriority Priority { get; set; }
|
||||||
public IEnumerable<string> Systems => _systems;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
Loading…
Reference in New Issue