RomLoader consolidate some Disc creation logic between xml and m3u code paths and abstact some of it out to the DiscSystem project

This commit is contained in:
adelikat 2020-05-16 13:46:48 -05:00
parent 8269b7dec4
commit 32aa623eff
3 changed files with 56 additions and 67 deletions

View File

@ -202,41 +202,12 @@ namespace BizHawk.Client.Common
private List<Disc> DiscsFromXml(XmlGame xmlGame, string systemId, DiscType diskType)
{
var discs = new List<Disc>();
var sw = new StringWriter();
foreach (var e in xmlGame.AssetFullPaths.Where(a => IsDisc(Path.GetExtension(a))))
{
string discPath = e;
//--- 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 = discPath, IN_SlowLoadAbortThreshold = 8 };
discMountJob.Run();
var disc = discMountJob.OUT_Disc;
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", systemId, LoadErrorType.DiscError);
}
else if (discMountJob.OUT_ErrorLevel)
{
throw new InvalidOperationException($"\r\n{discMountJob.OUT_Log}");
}
else if (disc == null)
{
throw new InvalidOperationException("Can't load one of the files specified in the XML");
}
else
var disc = diskType.Create(e, str => { DoLoadErrorCallback(str, systemId, LoadErrorType.DiscError); });
if (disc != null)
{
discs.Add(disc);
var discType = new DiscIdentifier(disc).DetectDiscType();
if (discType != diskType)
{
DoLoadErrorCallback($"Not a {systemId} disc", systemId, LoadErrorType.DiscError);
}
}
}
@ -407,35 +378,13 @@ namespace BizHawk.Client.Common
var sw = new StringWriter();
foreach (var e in m3u.Entries)
{
string discPath = e.Path;
//--- 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 = discPath, IN_SlowLoadAbortThreshold = 8 };
discMountJob.Run();
var disc = discMountJob.OUT_Disc;
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);
return false;
}
if (discMountJob.OUT_ErrorLevel)
{
throw new InvalidOperationException($"\r\n{discMountJob.OUT_Log}");
}
if (disc == null)
{
throw new InvalidOperationException("Can't load one of the files specified in the M3U");
}
var discName = Path.GetFileNameWithoutExtension(discPath);
var disc = DiscType.SonyPSX.Create(e.Path, (str) => { DoLoadErrorCallback(str, "PSX", LoadErrorType.DiscError); });
var discName = Path.GetFileNameWithoutExtension(e.Path);
discNames.Add(discName);
discs.Add(disc);
var discType = new DiscIdentifier(disc).DetectDiscType();
sw.WriteLine("{0}", Path.GetFileName(discPath));
sw.WriteLine("{0}", Path.GetFileName(e.Path));
if (discType == DiscType.SonyPSX)
{
string discHash = new DiscHasher(disc).Calculate_PSX_BizIDHash().ToString("X8");

View File

@ -1,18 +1,18 @@
using System;
using System.Collections.Generic;
//ARCHITECTURE NOTE:
//No provisions are made for caching synthesized data for later accelerated use.
//This is because, in the worst case that might result in synthesizing an entire disc in memory.
//Instead, users should be advised to `hawk` the disc first for most rapid access so that synthesis won't be necessary and speed will be maximized.
//This will result in a completely flattened CCD where everything comes right off the hard drive
//Our choice here might be an unwise decision for disc ID and miscellaneous purposes but it's best for gaming and stream-converting (hawking and hashing)
// ARCHITECTURE NOTE:
// No provisions are made for caching synthesized data for later accelerated use.
// This is because, in the worst case that might result in synthesizing an entire disc in memory.
// Instead, users should be advised to `hawk` the disc first for most rapid access so that synthesis won't be necessary and speed will be maximized.
// This will result in a completely flattened CCD where everything comes right off the hard drive
// Our choice here might be an unwise decision for disc ID and miscellaneous purposes but it's best for gaming and stream-converting (hawking and hashing)
//TODO: in principle, we could mount audio to decode only on an as-needed basis
//this might result in hiccups during emulation, though, so it should be an option.
//This would imply either decode-length processing (scan file without decoding) or decoding and discarding the data.
//We should probably have some richer policy specifications for this kind of thing, but it's not a high priority. Main workflow is still discohawking.
//Alternate policies would probably be associated with copious warnings (examples: ? ? ?)
// TODO: in principle, we could mount audio to decode only on an as-needed basis
// this might result in hiccups during emulation, though, so it should be an option.
// This would imply either decode-length processing (scan file without decoding) or decoding and discarding the data.
// We should probably have some richer policy specifications for this kind of thing, but it's not a high priority. Main workflow is still discohawking.
// Alternate policies would probably be associated with copious warnings (examples: ? ? ?)
namespace BizHawk.Emulation.DiscSystem
{

View File

@ -0,0 +1,40 @@
using System;
namespace BizHawk.Emulation.DiscSystem
{
public static class DiscExtensions
{
public static Disc Create(this DiscType diskType, string discPath, Action<string> errorCallback)
{
//--- 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 = discPath, IN_SlowLoadAbortThreshold = 8 };
discMountJob.Run();
var disc = discMountJob.OUT_Disc;
if (disc == null)
{
throw new InvalidOperationException($"Can't find the file specified: {discPath}");
}
if (discMountJob.OUT_SlowLoadAborted)
{
errorCallback("This disc would take too long to load. Run it through DiscoHawk first, or find a new rip because this one is probably junk");
return null;
}
if (discMountJob.OUT_ErrorLevel)
{
throw new InvalidOperationException($"\r\n{discMountJob.OUT_Log}");
}
var discType = new DiscIdentifier(disc).DetectDiscType();
if (discType != diskType)
{
errorCallback($"Not a {diskType} disc");
return null;
}
return disc;
}
}
}