If a PSX `.bin` is loaded, try synthesising a `.cue`

this works but takes forever, which I'm guessing is because somewhere it's
trying to hash the whole file. that's not a new problem though
This commit is contained in:
YoshiRulz 2023-04-09 10:05:52 +10:00
parent 5f0683c1ae
commit 0469c04372
No known key found for this signature in database
GPG Key ID: C4DE31C245353FB7
2 changed files with 79 additions and 16 deletions

View File

@ -416,13 +416,21 @@ namespace BizHawk.Client.Common
throw new AggregateException("No core could load the game", exceptions);
}
private void LoadOther(CoreComm nextComm, HawkFile file, string forcedCoreName, out IEmulator nextEmulator, out RomGame rom, out GameInfo game, out bool cancel)
private void LoadOther(
CoreComm nextComm,
HawkFile file,
string ext,
string forcedCoreName,
out IEmulator nextEmulator,
out RomGame rom,
out GameInfo game,
out bool cancel)
{
cancel = false;
rom = new RomGame(file);
// hacky for now
rom.GameInfo.System = file.Extension switch
rom.GameInfo.System = ext switch
{
".exe" => VSystemID.Raw.PSX,
".nsf" => VSystemID.Raw.NES,
@ -463,7 +471,7 @@ namespace BizHawk.Client.Common
{
case VSystemID.Raw.GB:
case VSystemID.Raw.GBC:
if (file.Extension == ".gbs")
if (ext == ".gbs")
{
nextEmulator = new Sameboy(
nextComm,
@ -480,6 +488,34 @@ namespace BizHawk.Client.Common
game.System = VSystemID.Raw.SGB;
}
break;
case VSystemID.Raw.PSX when ext is ".bin":
const string FILE_EXT_CUE = ".cue";
var cuePath = TempFileManager.GetTempFilename(friendlyName: "syn", dotAndExtension: FILE_EXT_CUE, delete: false);
DiscMountJob.CreateSyntheticCue(cueFilePath: cuePath, binFilePath: file.Name);
var gameBak = game;
var nextEmulatorBak = nextEmulator;
try
{
if (LoadDisc(
path: cuePath,
nextComm,
new(cuePath),
ext: FILE_EXT_CUE,
forcedCoreName: forcedCoreName,
out nextEmulator,
out game))
{
return;
}
Console.WriteLine("synthesised .cue failed to load");
}
catch (Exception e)
{
Console.WriteLine($"synthesised .cue failed to load: {e}");
}
game = gameBak;
nextEmulator = nextEmulatorBak;
break;
}
var cip = new CoreInventoryParameters(this)
{
@ -589,11 +625,19 @@ namespace BizHawk.Client.Common
}
}
private void LoadMAME(string path, CoreComm nextComm, HawkFile file, out IEmulator nextEmulator, out RomGame rom, out GameInfo game, out bool cancel)
private void LoadMAME(
string path,
CoreComm nextComm,
HawkFile file,
string ext,
out IEmulator nextEmulator,
out RomGame rom,
out GameInfo game,
out bool cancel)
{
try
{
LoadOther(nextComm, file, null, out nextEmulator, out rom, out game, out cancel);
LoadOther(nextComm, file, ext: ext, forcedCoreName: null, out nextEmulator, out rom, out game, out cancel);
}
catch (Exception mex) // ok, MAME threw, let's try another core...
{
@ -601,7 +645,7 @@ namespace BizHawk.Client.Common
{
using var f = new HawkFile(path, allowArchives: true);
if (!HandleArchiveBinding(f)) throw;
LoadOther(nextComm, f, null, out nextEmulator, out rom, out game, out cancel);
LoadOther(nextComm, f, ext: ext, forcedCoreName: null, out nextEmulator, out rom, out game, out cancel);
}
catch (Exception oex)
{
@ -715,7 +759,7 @@ namespace BizHawk.Client.Common
break;
case ".zip" when forcedCoreName is null:
case ".7z" when forcedCoreName is null:
LoadMAME(path, nextComm, file, out nextEmulator, out rom, out game, out cancel);
LoadMAME(path: path, nextComm, file, ext: ext, out nextEmulator, out rom, out game, out cancel);
break;
default:
if (Disc.IsValidExtension(ext))
@ -727,7 +771,16 @@ namespace BizHawk.Client.Common
}
else
{
LoadOther(nextComm, file, forcedCoreName, out nextEmulator, out rom, out game, out cancel); // must be called after LoadXML because of SNES hacks
// must be called after LoadXML because of SNES hacks
LoadOther(
nextComm,
file,
ext: ext,
forcedCoreName: forcedCoreName,
out nextEmulator,
out rom,
out game,
out cancel);
}
break;
}
@ -901,7 +954,7 @@ namespace BizHawk.Client.Common
new FilesystemFilter("Disc Images", new[] { "cue", "ccd", "cdi", "mds", "m3u" }),
new FilesystemFilter("NES", RomFileExtensions.NES.Concat(new[] { "nsf" }).ToList(), addArchiveExts: true),
new FilesystemFilter("Super NES", RomFileExtensions.SNES, addArchiveExts: true),
new FilesystemFilter("PlayStation", new[] { "cue", "ccd", "mds", "m3u" }),
new FilesystemFilter("PlayStation", new[] { "bin", "cue", "ccd", "mds", "m3u" }),
new FilesystemFilter("PSX Executables (experimental)", Array.Empty<string>(), devBuildExtraExts: new[] { "exe" }),
new FilesystemFilter("PSF Playstation Sound File", new[] { "psf", "minipsf" }),
new FilesystemFilter("Nintendo 64", RomFileExtensions.N64),

View File

@ -203,13 +203,7 @@ namespace BizHawk.Emulation.DiscSystem
// make a fake .cue file to represent this .iso and mount that
// however... to save many users from a stupid mistake, check if the size is NOT a multiple of 2048 (but IS a multiple of 2352) and in that case consider it a mode2 disc
//TODO try it both ways and check the disc type to use whichever one succeeds in identifying a disc type
var len = new FileInfo(IN_FromPath).Length;
LoadCue(
dir,
$@"
FILE ""{file}"" BINARY
TRACK 01 {(len % 2048 is not 0 && len % 2352 is 0 ? "MODE2/2352" : "MODE1/2048")}
INDEX 01 00:00:00");
LoadCue(cueDirPath: dir, cueContent: GenerateCue(binFilename: file, binFilePath: IN_FromPath));
break;
case ".mds":
OUT_Disc = MDS_Format.LoadMDSToDisc(IN_FromPath, IN_DiscMountPolicy);
@ -219,5 +213,21 @@ namespace BizHawk.Emulation.DiscSystem
// set up the lowest level synth provider
if (OUT_Disc != null) OUT_Disc.SynthProvider = new ArraySectorSynthProvider { Sectors = OUT_Disc._Sectors, FirstLBA = -150 };
}
public static string GenerateCue(string binFilename, bool isMode2)
=> $@"FILE ""{binFilename}"" BINARY
TRACK 01 {(isMode2 ? "MODE2/2352" : "MODE1/2048")}
INDEX 01 00:00:00";
public static string GenerateCue(string binFilename, string binFilePath)
{
var len = new FileInfo(binFilePath).Length;
return GenerateCue(binFilename, isMode2: len % 2048 is not 0 && len % 2352 is 0);
}
public static void CreateSyntheticCue(string cueFilePath, string binFilePath)
=> File.WriteAllText(
path: cueFilePath,
contents: GenerateCue(binFilename: binFilePath/*abs is fine here*/, binFilePath: binFilePath)); //TODO as with .iso, may want to try both
}
}