Attempt to locate `.cue` for PSX `.bin` before synthesising one

see #4146
This commit is contained in:
YoshiRulz 2025-01-05 22:10:32 +10:00
parent 04955ea228
commit ddd14d5274
No known key found for this signature in database
GPG Key ID: C4DE31C245353FB7
3 changed files with 84 additions and 0 deletions

View File

@ -486,6 +486,21 @@ namespace BizHawk.Client.Common
} }
break; break;
case VSystemID.Raw.PSX when ext is ".bin": case VSystemID.Raw.PSX when ext is ".bin":
if (TryLoadSiblingCue(
nextComm,
binFilePath: file.Name,
forcedCoreName: forcedCoreName,
out var nextEmulator1,
out var game1,
out cancel))
{
nextEmulator = nextEmulator1;
rom = null;
game = game1;
return;
}
if (cancel) break; //TODO return? the cancel earlier in this method doesn't
const string FILE_EXT_CUE = ".cue"; const string FILE_EXT_CUE = ".cue";
var crc32Digest = CRC32Checksum.ComputeDigestHex(file.GetStream().ReadAllBytes()); // slow! var crc32Digest = CRC32Checksum.ComputeDigestHex(file.GetStream().ReadAllBytes()); // slow!
var cuePath = Path.Combine(Path.GetTempPath(), $"synthesised for {crc32Digest}{FILE_EXT_CUE}"); var cuePath = Path.Combine(Path.GetTempPath(), $"synthesised for {crc32Digest}{FILE_EXT_CUE}");
@ -534,6 +549,70 @@ namespace BizHawk.Client.Common
nextEmulator = MakeCoreFromCoreInventory(cip, forcedCoreName); nextEmulator = MakeCoreFromCoreInventory(cip, forcedCoreName);
} }
private bool TryLoadSiblingCue(
CoreComm nextComm,
string binFilePath,
string forcedCoreName,
out IEmulator nextEmulator,
out GameInfo game,
out bool cancel)
{
nextEmulator = null;
game = null;
cancel = false;
const string FILE_EXT_CUE = ".cue";
const string FMT_STR_ASK = "Found \"{0}\".\nLoad that instead? Select \"No\" to synthesise a new .cue file for this game.";
HawkFile/*?*/ hfChosen = null;
//TODO can probably express this logic flow in a better way
HawkFile hfMatching = new(binFilePath.RemoveSuffix(".bin") + ".cue");
if (hfMatching.Exists)
{
var result = nextComm.Question(string.Format(FMT_STR_ASK, hfMatching.Name));
if (result is null)
{
cancel = true;
return false;
}
if (result is true)
{
hfChosen = hfMatching;
}
}
if (hfChosen is null)
{
var soleCueSiblingPath = Directory.EnumerateFiles(Path.GetDirectoryName(binFilePath))
.Where(static s => s.EndsWithOrdinal(FILE_EXT_CUE))
.Except([ hfMatching.Name ]) // seen but denied by user; don't prompt for the same file again
.SingleOrDefault();
HawkFile hfSoleSibling = soleCueSiblingPath is null ? null : new(soleCueSiblingPath);
if (hfSoleSibling is { Exists: true })
{
var result = nextComm.Question(string.Format(FMT_STR_ASK, hfSoleSibling.Name));
if (result is null)
{
cancel = true;
return false;
}
if (result is true)
{
hfChosen = hfSoleSibling;
}
}
}
if (hfChosen is null) return false;
return LoadDisc(
path: hfChosen.Name,
nextComm,
file: hfChosen,
ext: FILE_EXT_CUE,
forcedCoreName: forcedCoreName,
out nextEmulator,
out game);
}
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)
{ {
// TODO: Why does the PSF loader need CbDeflater provided? Surely this is a matter internal to it. // TODO: Why does the PSF loader need CbDeflater provided? Surely this is a matter internal to it.

View File

@ -258,6 +258,7 @@ namespace BizHawk.Client.EmuHawk
return new CoreComm( return new CoreComm(
message => this.ModalMessageBox(message, "Warning", EMsgBoxIcon.Warning), message => this.ModalMessageBox(message, "Warning", EMsgBoxIcon.Warning),
AddOnScreenMessage, AddOnScreenMessage,
text => this.ModalMessageBox3(icon: EMsgBoxIcon.Question, caption: "ROM loader", text: text),
cfp, cfp,
prefs, prefs,
new OpenGLProvider()); new OpenGLProvider());

View File

@ -8,9 +8,12 @@ namespace BizHawk.Emulation.Common
/// </summary> /// </summary>
public class CoreComm public class CoreComm
{ {
public readonly Func<string, bool?> Question;
public CoreComm( public CoreComm(
Action<string> showMessage, Action<string> showMessage,
Action<string, int?> notifyMessage, Action<string, int?> notifyMessage,
Func<string, bool?> question,
ICoreFileProvider coreFileProvider, ICoreFileProvider coreFileProvider,
CorePreferencesFlags prefs, CorePreferencesFlags prefs,
IOpenGLProvider oglProvider IOpenGLProvider oglProvider
@ -18,6 +21,7 @@ namespace BizHawk.Emulation.Common
{ {
ShowMessage = showMessage; ShowMessage = showMessage;
Notify = notifyMessage; Notify = notifyMessage;
Question = question;
CoreFileProvider = coreFileProvider; CoreFileProvider = coreFileProvider;
CorePreferences = prefs; CorePreferences = prefs;
OpenGLProvider = oglProvider; OpenGLProvider = oglProvider;