Add in 3DS rom extensions to rom filter

make it so CIAs past index 0 will be "installed" (mostly only relevant for movies, as the temp user folder is wiped each session in deterministic mode)
ensure XMLs won't load 3DS roms into memory (same reasoning as other hack, might be >=2GiB)
do some cleanup with this code
This commit is contained in:
CasualPokePlayer 2023-07-28 05:33:56 -07:00
parent 4ff157f652
commit 8c41b09108
4 changed files with 32 additions and 11 deletions

View File

@ -26,7 +26,7 @@ namespace BizHawk.Client.Common
// 3DS roms typically exceed 2GiB, so we don't want to load them into memory // 3DS roms typically exceed 2GiB, so we don't want to load them into memory
// TODO: Don't rely only on extension if this is actually a 3DS ROM (validate in some way) // TODO: Don't rely only on extension if this is actually a 3DS ROM (validate in some way)
// TODO: ELF is another 3DS extension, but it's too generic / might be used for other systems... // TODO: ELF is another 3DS extension, but it's too generic / might be used for other systems...
private static bool Is3DSRom(string ext) public static bool Is3DSRom(string ext)
=> ext is ".3DS" or ".3DSX" or ".AXF" or ".CCI" or ".CXI" or ".APP" or ".CIA"; => ext is ".3DS" or ".3DSX" or ".AXF" or ".CCI" or ".CXI" or ".APP" or ".CIA";
public RomGame(HawkFile file) public RomGame(HawkFile file)

View File

@ -579,13 +579,13 @@ namespace BizHawk.Client.Common
RomData = kvp.Value, RomData = kvp.Value,
FileData = kvp.Value, // TODO: Hope no one needed anything special here FileData = kvp.Value, // TODO: Hope no one needed anything special here
Extension = Path.GetExtension(kvp.Key), Extension = Path.GetExtension(kvp.Key),
RomPath = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(path.SubstringBefore('|')), kvp.Key)), RomPath = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(path.SubstringBefore('|'))!, kvp.Key!)),
Game = Database.GetGameInfo(kvp.Value, Path.GetFileName(kvp.Key)) Game = Database.GetGameInfo(kvp.Value, Path.GetFileName(kvp.Key))
}) })
.ToList(), .ToList(),
Discs = xmlGame.AssetFullPaths Discs = xmlGame.AssetFullPaths
.Where(p => Disc.IsValidExtension(Path.GetExtension(p))) .Where(p => Disc.IsValidExtension(Path.GetExtension(p)))
.Select(path => (p: path, d: DiscExtensions.CreateAnyType(path, str => DoLoadErrorCallback(str, system, LoadErrorType.DiscError)))) .Select(discPath => (p: discPath, d: DiscExtensions.CreateAnyType(discPath, str => DoLoadErrorCallback(str, system, LoadErrorType.DiscError))))
.Where(a => a.d != null) .Where(a => a.d != null)
.Select(a => (IDiscAsset)new DiscAsset .Select(a => (IDiscAsset)new DiscAsset
{ {
@ -883,6 +883,8 @@ namespace BizHawk.Client.Common
public static readonly IReadOnlyCollection<string> MSX = new[] { "cas", "dsk", "mx1", "rom" }; public static readonly IReadOnlyCollection<string> MSX = new[] { "cas", "dsk", "mx1", "rom" };
public static readonly IReadOnlyCollection<string> N3DS = new[] { "3ds", "3dsx", "axf", "cci", "cxi", "app", "elf", "cia" };
public static readonly IReadOnlyCollection<string> N64 = new[] { "z64", "v64", "n64" }; public static readonly IReadOnlyCollection<string> N64 = new[] { "z64", "v64", "n64" };
public static readonly IReadOnlyCollection<string> N64DD = new[] { "ndd" }; public static readonly IReadOnlyCollection<string> N64DD = new[] { "ndd" };
@ -961,6 +963,7 @@ namespace BizHawk.Client.Common
new FilesystemFilter("Nintendo 64 Disk Drive", RomFileExtensions.N64DD), new FilesystemFilter("Nintendo 64 Disk Drive", RomFileExtensions.N64DD),
new FilesystemFilter("Gameboy", RomFileExtensions.GB.Concat(new[] { "gbs" }).ToList(), addArchiveExts: true), new FilesystemFilter("Gameboy", RomFileExtensions.GB.Concat(new[] { "gbs" }).ToList(), addArchiveExts: true),
new FilesystemFilter("Gameboy Advance", RomFileExtensions.GBA, addArchiveExts: true), new FilesystemFilter("Gameboy Advance", RomFileExtensions.GBA, addArchiveExts: true),
new FilesystemFilter("Nintendo 3DS", RomFileExtensions.N3DS),
new FilesystemFilter("Nintendo DS", RomFileExtensions.NDS), new FilesystemFilter("Nintendo DS", RomFileExtensions.NDS),
new FilesystemFilter("Master System", RomFileExtensions.SMS, addArchiveExts: true), new FilesystemFilter("Master System", RomFileExtensions.SMS, addArchiveExts: true),
new FilesystemFilter("PC Engine", RomFileExtensions.PCE.Concat(FilesystemFilter.DiscExtensions).ToList(), addArchiveExts: true), new FilesystemFilter("PC Engine", RomFileExtensions.PCE.Concat(FilesystemFilter.DiscExtensions).ToList(), addArchiveExts: true),

View File

@ -15,7 +15,7 @@ namespace BizHawk.Client.Common
public class XmlGame public class XmlGame
{ {
public XmlDocument Xml { get; set; } public XmlDocument Xml { get; set; }
public GameInfo GI { get; } = new GameInfo(); public GameInfo GI { get; } = new();
public IList<KeyValuePair<string, byte[]>> Assets { get; } = new List<KeyValuePair<string, byte[]>>(); public IList<KeyValuePair<string, byte[]>> Assets { get; } = new List<KeyValuePair<string, byte[]>>();
public IList<string> AssetFullPaths { get; } = new List<string>(); // TODO: Hack work around, to avoid having to refactor Assets into a object array, should be refactored! public IList<string> AssetFullPaths { get; } = new List<string>(); // TODO: Hack work around, to avoid having to refactor Assets into a object array, should be refactored!
@ -36,13 +36,13 @@ namespace BizHawk.Client.Common
{ {
GI = GI =
{ {
System = y.Attributes["System"].Value, System = y.Attributes!["System"].Value,
Name = y.Attributes["Name"].Value, Name = y.Attributes["Name"].Value,
Status = RomStatus.Unknown Status = RomStatus.Unknown
}, },
Xml = x Xml = x
}; };
string fullPath = ""; var fullPath = "";
var n = y.SelectSingleNode("./LoadAssets"); var n = y.SelectSingleNode("./LoadAssets");
if (n != null) if (n != null)
@ -52,7 +52,7 @@ namespace BizHawk.Client.Common
foreach (XmlNode a in n.ChildNodes) foreach (XmlNode a in n.ChildNodes)
{ {
string filename = a.Attributes["FileName"].Value; var filename = a.Attributes!["FileName"].Value;
byte[] data; byte[] data;
if (filename[0] == '|') if (filename[0] == '|')
{ {
@ -67,7 +67,7 @@ namespace BizHawk.Client.Common
} }
else else
{ {
throw new Exception($"Couldn't load XMLGame Asset \"{filename}\""); throw new($"Couldn't load XMLGame Asset \"{filename}\"");
} }
} }
else else
@ -89,16 +89,19 @@ namespace BizHawk.Client.Common
} }
else else
{ {
data = File.ReadAllBytes(fullPath.SubstringBefore('|')); var path = fullPath.SubstringBefore('|');
data = RomGame.Is3DSRom(path)
? Array.Empty<byte>()
: File.ReadAllBytes(path);
} }
} }
catch (Exception e) catch (Exception e)
{ {
throw new Exception($"Couldn't load XMLGame LoadAsset \"{filename}\"", e); throw new($"Couldn't load XMLGame LoadAsset \"{filename}\"", e);
} }
} }
ret.Assets.Add(new KeyValuePair<string, byte[]>(filename, data)); ret.Assets.Add(new(filename, data));
ret.AssetFullPaths.Add(fullPath); ret.AssetFullPaths.Add(fullPath);
var sha1 = SHA1Checksum.Compute(data); var sha1 = SHA1Checksum.Compute(data);
hashStream.Write(sha1, 0, sha1.Length); hashStream.Write(sha1, 0, sha1.Length);

View File

@ -128,6 +128,21 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.N3DS
} }
} }
// user could have other CIAs after the first ROM (e.g. DLCs, updates)
// they need to installed at once in the case of recording
// as the temp folder is cleaned for each session
var dummyBuffer = new byte[1];
for (var i = 1; i < lp.Roms.Count; i++)
{
// doesn't make sense if not a CIA
if (lp.Roms[i].Extension.ToLowerInvariant() != ".cia")
{
throw new("ROMs after the index 0 should be CIAs");
}
_core.Citra_InstallCIA(_context, lp.Roms[i].RomPath, dummyBuffer, dummyBuffer.Length);
}
var errorMessage = new byte[1024]; var errorMessage = new byte[1024];
if (!_core.Citra_LoadROM(_context, romPath, errorMessage, errorMessage.Length)) if (!_core.Citra_LoadROM(_context, romPath, errorMessage, errorMessage.Length))
{ {