multi rom loading by xml all uses core inventory now

This commit is contained in:
nattthebear 2020-07-12 13:45:33 -04:00
parent 8d56b65734
commit 78bbc75f33
8 changed files with 73 additions and 156 deletions

View File

@ -121,29 +121,6 @@ namespace BizHawk.Client.Common
public List<IDiscAsset> Discs { get; set; } = new List<IDiscAsset>(); public List<IDiscAsset> Discs { get; set; } = new List<IDiscAsset>();
} }
private T MakeCore<T>(CoreLoadParametersShort clps)
where T : IEmulator
{
// TODO: Lots of stuff
var ctor = typeof(T)
.GetConstructors()
.Select(c => new { c, p = c.GetParameters() })
.Where(a => a.p.Length == 1)
.Select(a => new { a.c, p = a.p[0] })
.Where(a => a.p.ParameterType.IsGenericType && a.p.ParameterType.GetGenericTypeDefinition() == typeof(CoreLoadParameters<,>))
.Single();
var clp = (dynamic)Activator.CreateInstance(ctor.p.ParameterType);
clp.Comm = clps.Comm;
clp.Game = clps.Game;
clp.Roms = clps.Roms;
clp.Discs = clps.Discs;
clp.DeterministicEmulationRequested = Deterministic;
clp.Settings = (dynamic)GetCoreSettings(typeof(T), ctor.p.ParameterType.GetGenericArguments()[0]);
clp.SyncSettings = (dynamic)GetCoreSyncSettings(typeof(T), ctor.p.ParameterType.GetGenericArguments()[1]);
return (T)ctor.c.Invoke(new[] { clp });
}
// For not throwing errors but simply outputting information to the screen // For not throwing errors but simply outputting information to the screen
public Action<string> MessageCallback { get; set; } public Action<string> MessageCallback { get; set; }
@ -286,20 +263,13 @@ namespace BizHawk.Client.Common
private bool LoadDisc(string path, CoreComm nextComm, HawkFile file, string ext, out IEmulator nextEmulator, out GameInfo game) private bool LoadDisc(string path, CoreComm nextComm, HawkFile file, string ext, out IEmulator nextEmulator, out GameInfo game)
{ {
//--- load the disc in a context which will let us abort if it's going to take too long var disc = DiscExtensions.CreateAnyType(path, str => DoLoadErrorCallback(str, "???", LoadErrorType.DiscError));
var discMountJob = new DiscMountJob { IN_FromPath = path, IN_SlowLoadAbortThreshold = 8 }; if (disc == null)
discMountJob.Run();
if (discMountJob.OUT_SlowLoadAborted)
{ {
DoLoadErrorCallback("This disc would take too long to load. Run it through DiscoHawk first, or find a new rip because this one is probably junk", "", LoadErrorType.DiscError);
nextEmulator = null;
game = null; game = null;
nextEmulator = null;
return false; return false;
} }
if (discMountJob.OUT_ErrorLevel) throw new InvalidOperationException($"\r\n{discMountJob.OUT_Log}");
var disc = discMountJob.OUT_Disc;
// TODO - use more sophisticated IDer // TODO - use more sophisticated IDer
var discType = new DiscIdentifier(disc).DetectDiscType(); var discType = new DiscIdentifier(disc).DetectDiscType();
@ -361,26 +331,6 @@ namespace BizHawk.Client.Common
} }
} }
TEmulator MakeCoreFromCds<TEmulator>(GameInfo g)
where TEmulator : IEmulator
{
var clps = new CoreLoadParametersShort
{
Comm = nextComm,
Game = g,
Discs =
{
new DiscAsset
{
DiscData = disc,
DiscType = new DiscIdentifier(disc).DetectDiscType(),
DiscName = Path.GetFileNameWithoutExtension(path)
}
},
};
return MakeCore<TEmulator>(clps);
}
var cip = new CoreInventoryParameters(this) var cip = new CoreInventoryParameters(this)
{ {
Comm = nextComm, Comm = nextComm,
@ -564,33 +514,11 @@ namespace BizHawk.Client.Common
var xmlGame = XmlGame.Create(file); // if load fails, are we supposed to retry as a bsnes XML???????? var xmlGame = XmlGame.Create(file); // if load fails, are we supposed to retry as a bsnes XML????????
game = xmlGame.GI; game = xmlGame.GI;
List<IDiscAsset> DiscsFromXml(string systemId, DiscType diskType) var system = game.System;
{ var cip = new CoreInventoryParameters(this)
return xmlGame
.AssetFullPaths
.Where(path => Disc.IsValidExtension(Path.GetExtension(path)))
.Select(path => new
{
d = diskType.Create(path, str => DoLoadErrorCallback(str, systemId, LoadErrorType.DiscError)),
p = path,
})
.Where(a => a.d != null)
.Select(a => (IDiscAsset)new DiscAsset
{
DiscData = a.d,
DiscType = diskType,
DiscName = Path.GetFileNameWithoutExtension(a.p)
})
.ToList();
}
TEmulator MakeCoreFromXml<TEmulator>(GameInfo g, DiscType? type = null, string systemId = null)
where TEmulator : IEmulator
{
var clps = new CoreLoadParametersShort
{ {
Comm = nextComm, Comm = nextComm,
Game = g, Game = game,
Roms = xmlGame.Assets Roms = xmlGame.Assets
.Where(kvp => !Disc.IsValidExtension(kvp.Key)) .Where(kvp => !Disc.IsValidExtension(kvp.Key))
.Select(kvp => (IRomAsset)new RomAsset .Select(kvp => (IRomAsset)new RomAsset
@ -601,61 +529,25 @@ namespace BizHawk.Client.Common
Game = Database.GetGameInfo(kvp.Value, Path.GetFileName(kvp.Key)) Game = Database.GetGameInfo(kvp.Value, Path.GetFileName(kvp.Key))
}) })
.ToList(), .ToList(),
Discs = type.HasValue ? DiscsFromXml(systemId, type.Value) : new List<IDiscAsset>(), Discs = xmlGame.AssetFullPaths
.Where(path => Disc.IsValidExtension(Path.GetExtension(path)))
.Select(path => new
{
d = DiscExtensions.CreateAnyType(path, str => DoLoadErrorCallback(str, system, LoadErrorType.DiscError)),
p = path,
})
.Where(a => a.d != null)
.Select(a => (IDiscAsset)new DiscAsset
{
DiscData = a.d,
DiscType = new DiscIdentifier(a.d).DetectDiscType(),
DiscName = Path.GetFileNameWithoutExtension(a.p)
})
.ToList(),
}; };
return MakeCore<TEmulator>(clps); nextEmulator = MakeCoreFromCoreInventory(cip);
}
switch (game.System)
{
case "GB":
case "DGB":
if (_config.PreferredCores["GB"] == CoreNames.GbHawk)
{
nextEmulator = MakeCoreFromXml<GBHawkLink>(game);
return true; return true;
} }
else
{
nextEmulator = MakeCoreFromXml<GambatteLink>(game);
return true;
}
case "GB3x":
nextEmulator = MakeCoreFromXml<GBHawkLink3x>(game);
return true;
case "GB4x":
nextEmulator = MakeCoreFromXml<GBHawkLink4x>(game);
return true;
case "AppleII":
nextEmulator = MakeCoreFromXml<AppleII>(game);
return true;
case "C64":
nextEmulator = MakeCoreFromXml<C64>(game);
return true;
case "ZXSpectrum":
nextEmulator = MakeCoreFromXml<ZXSpectrum>(game);
return true;
case "AmstradCPC":
nextEmulator = MakeCoreFromXml<AmstradCPC>(game);
return true;
case "PSX":
nextEmulator = MakeCoreFromXml<Octoshock>(game, DiscType.SonyPSX, "PSX");
return true;
case "SAT":
nextEmulator = MakeCoreFromXml<Saturnus>(game, DiscType.SegaSaturn, "SAT");
return true;
case "PCFX":
nextEmulator = MakeCoreFromXml<Tst>(game, DiscType.PCFX, "PCFX");
return true;
case "GEN":
nextEmulator = MakeCoreFromXml<GPGX>(game, DiscType.MegaCD, "GEN");
return true;
case "Game Gear":
nextEmulator = MakeCoreFromXml<GGHawkLink>(game);
return true;
}
return false;
}
catch (Exception ex) catch (Exception ex)
{ {
try try

View File

@ -21,15 +21,10 @@ namespace BizHawk.Emulation.Cores.Computers.AppleII
AppleIIController.BoolButtons.AddRange(ExtraButtons); AppleIIController.BoolButtons.AddRange(ExtraButtons);
} }
[CoreConstructor("AppleII")]
public AppleII(CoreLoadParameters<Settings, object> lp) public AppleII(CoreLoadParameters<Settings, object> lp)
: this(lp.Comm, lp.Roms.First().RomData, lp.Settings)
{ {
_romSet = lp.Roms.Select(r => r.RomData).ToList(); _romSet = lp.Roms.Select(r => r.RomData).ToList();
}
[CoreConstructor("AppleII")]
public AppleII(CoreComm comm, byte[] rom, Settings settings)
{
var ser = new BasicServiceProvider(this); var ser = new BasicServiceProvider(this);
ServiceProvider = ser; ServiceProvider = ser;
@ -38,13 +33,11 @@ namespace BizHawk.Emulation.Cores.Computers.AppleII
Header = "6502: PC, opcode, register (A, X, Y, P, SP, Cy), flags (NVTBDIZC)" Header = "6502: PC, opcode, register (A, X, Y, P, SP, Cy), flags (NVTBDIZC)"
}; };
_disk1 = rom; _disk1 = _romSet[0];
// TODO: Doesn't this add the first rom twice in the case of multirom?
_romSet.Add(rom);
_appleIIRom = comm.CoreFileProvider.GetFirmware( _appleIIRom = lp.Comm.CoreFileProvider.GetFirmware(
SystemId, "AppleIIe", true, "The Apple IIe BIOS firmware is required"); SystemId, "AppleIIe", true, "The Apple IIe BIOS firmware is required");
_diskIIRom = comm.CoreFileProvider.GetFirmware( _diskIIRom = lp.Comm.CoreFileProvider.GetFirmware(
SystemId, "DiskII", true, "The DiskII firmware is required"); SystemId, "DiskII", true, "The DiskII firmware is required");
_machine = new Components(_appleIIRom, _diskIIRom); _machine = new Components(_appleIIRom, _diskIIRom);
@ -58,7 +51,7 @@ namespace BizHawk.Emulation.Cores.Computers.AppleII
SetCallbacks(); SetCallbacks();
SetupMemoryDomains(); SetupMemoryDomains();
PutSettings(settings ?? new Settings()); PutSettings(lp.Settings ?? new Settings());
} }
private static readonly ControllerDefinition AppleIIController; private static readonly ControllerDefinition AppleIIController;

View File

@ -1,4 +1,5 @@
using BizHawk.Emulation.Common; using System;
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink
{ {
@ -29,9 +30,12 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink
public bool do_frame_fill; public bool do_frame_fill;
//[CoreConstructor("GB", "GBC")] [CoreConstructor("DGB")]
public GBHawkLink(CoreLoadParameters<GBHawkLink.GBLinkSettings, GBHawkLink.GBLinkSyncSettings> lp) public GBHawkLink(CoreLoadParameters<GBHawkLink.GBLinkSettings, GBHawkLink.GBLinkSyncSettings> lp)
{ {
if (lp.Roms.Count != 2)
throw new InvalidOperationException("Wrong number of roms");
var ser = new BasicServiceProvider(this); var ser = new BasicServiceProvider(this);
ServiceProvider = ser; ServiceProvider = ser;

View File

@ -1,4 +1,5 @@
using BizHawk.Emulation.Common; using System;
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink3x namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink3x
{ {
@ -29,9 +30,12 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink3x
public bool do_frame_fill; public bool do_frame_fill;
//[CoreConstructor("GB", "GBC")] [CoreConstructor("GB3x")]
public GBHawkLink3x(CoreLoadParameters<GBLink3xSettings, GBLink3xSyncSettings> lp) public GBHawkLink3x(CoreLoadParameters<GBLink3xSettings, GBLink3xSyncSettings> lp)
{ {
if (lp.Roms.Count != 3)
throw new InvalidOperationException("Wrong number of roms");
var ser = new BasicServiceProvider(this); var ser = new BasicServiceProvider(this);
ServiceProvider = ser; ServiceProvider = ser;

View File

@ -1,4 +1,5 @@
using BizHawk.Emulation.Common; using System;
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink4x namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink4x
{ {
@ -50,9 +51,12 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawkLink4x
public bool do_frame_fill; public bool do_frame_fill;
//[CoreConstructor("GB", "GBC")] [CoreConstructor("GB4x")]
public GBHawkLink4x(CoreLoadParameters<GBLink4xSettings, GBLink4xSyncSettings> lp) public GBHawkLink4x(CoreLoadParameters<GBLink4xSettings, GBLink4xSyncSettings> lp)
{ {
if (lp.Roms.Count != 4)
throw new InvalidOperationException("Wrong number of roms");
var ser = new BasicServiceProvider(this); var ser = new BasicServiceProvider(this);
Link4xSettings = (GBLink4xSettings)lp.Settings ?? new GBLink4xSettings(); Link4xSettings = (GBLink4xSettings)lp.Settings ?? new GBLink4xSettings();

View File

@ -1,4 +1,5 @@
using BizHawk.Emulation.Common; using System;
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Nintendo.Gameboy namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
{ {
@ -11,8 +12,12 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
public partial class GambatteLink : IEmulator, IVideoProvider, ISoundProvider, IInputPollable, ISaveRam, IStatable, ILinkable, public partial class GambatteLink : IEmulator, IVideoProvider, ISoundProvider, IInputPollable, ISaveRam, IStatable, ILinkable,
IBoardInfo, IRomInfo, IDebuggable, ISettable<GambatteLink.GambatteLinkSettings, GambatteLink.GambatteLinkSyncSettings>, ICodeDataLogger IBoardInfo, IRomInfo, IDebuggable, ISettable<GambatteLink.GambatteLinkSettings, GambatteLink.GambatteLinkSyncSettings>, ICodeDataLogger
{ {
[CoreConstructor("DGB")]
public GambatteLink(CoreLoadParameters<GambatteLink.GambatteLinkSettings, GambatteLink.GambatteLinkSyncSettings> lp) public GambatteLink(CoreLoadParameters<GambatteLink.GambatteLinkSettings, GambatteLink.GambatteLinkSyncSettings> lp)
{ {
if (lp.Roms.Count != 2)
throw new InvalidOperationException("Wrong number of roms");
ServiceProvider = new BasicServiceProvider(this); ServiceProvider = new BasicServiceProvider(this);
GambatteLinkSettings linkSettings = (GambatteLinkSettings)lp.Settings ?? new GambatteLinkSettings(); GambatteLinkSettings linkSettings = (GambatteLinkSettings)lp.Settings ?? new GambatteLinkSettings();
GambatteLinkSyncSettings linkSyncSettings = (GambatteLinkSyncSettings)lp.SyncSettings ?? new GambatteLinkSyncSettings(); GambatteLinkSyncSettings linkSyncSettings = (GambatteLinkSyncSettings)lp.SyncSettings ?? new GambatteLinkSyncSettings();

View File

@ -1,4 +1,5 @@
using BizHawk.Emulation.Common; using System;
using BizHawk.Emulation.Common;
using BizHawk.Emulation.Cores.Sega.MasterSystem; using BizHawk.Emulation.Cores.Sega.MasterSystem;
namespace BizHawk.Emulation.Cores.Sega.GGHawkLink namespace BizHawk.Emulation.Cores.Sega.GGHawkLink
@ -25,8 +26,13 @@ namespace BizHawk.Emulation.Cores.Sega.GGHawkLink
private bool do_r_next = false; private bool do_r_next = false;
// TODO: Are there really xml games in the wild with this SystemId?
[CoreConstructor("Game Gear")]
public GGHawkLink(CoreLoadParameters<GGLinkSettings, GGLinkSyncSettings> lp) public GGHawkLink(CoreLoadParameters<GGLinkSettings, GGLinkSyncSettings> lp)
{ {
if (lp.Roms.Count != 2)
throw new InvalidOperationException("Wrong number of roms");
var ser = new BasicServiceProvider(this); var ser = new BasicServiceProvider(this);
linkSettings = (GGLinkSettings)lp.Settings ?? new GGLinkSettings(); linkSettings = (GGLinkSettings)lp.Settings ?? new GGLinkSettings();

View File

@ -4,7 +4,16 @@ namespace BizHawk.Emulation.DiscSystem
{ {
public static class DiscExtensions public static class DiscExtensions
{ {
public static Disc CreateAnyType(string path, Action<string> errorCallback)
{
return CreateImpl(null, path, errorCallback);
}
public static Disc Create(this DiscType type, string path, Action<string> errorCallback) public static Disc Create(this DiscType type, string path, Action<string> errorCallback)
{
return CreateImpl(type, path, errorCallback);
}
private static Disc CreateImpl(DiscType? type, string path, Action<string> errorCallback)
{ {
//--- load the disc in a context which will let us abort if it's going to take too long //--- load the disc in a context which will let us abort if it's going to take too long
var discMountJob = new DiscMountJob { IN_FromPath = path, IN_SlowLoadAbortThreshold = 8 }; var discMountJob = new DiscMountJob { IN_FromPath = path, IN_SlowLoadAbortThreshold = 8 };
@ -24,7 +33,7 @@ namespace BizHawk.Emulation.DiscSystem
var discType = new DiscIdentifier(disc).DetectDiscType(); var discType = new DiscIdentifier(disc).DetectDiscType();
if (discType != type) if (type.HasValue && discType != type)
{ {
errorCallback($"Not a {type} disc"); errorCallback($"Not a {type} disc");
return null; return null;