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
// 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...
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";
public RomGame(HawkFile file)

View File

@ -579,13 +579,13 @@ namespace BizHawk.Client.Common
RomData = kvp.Value,
FileData = kvp.Value, // TODO: Hope no one needed anything special here
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))
})
.ToList(),
Discs = xmlGame.AssetFullPaths
.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)
.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> 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> N64DD = new[] { "ndd" };
@ -961,6 +963,7 @@ namespace BizHawk.Client.Common
new FilesystemFilter("Nintendo 64 Disk Drive", RomFileExtensions.N64DD),
new FilesystemFilter("Gameboy", RomFileExtensions.GB.Concat(new[] { "gbs" }).ToList(), addArchiveExts: true),
new FilesystemFilter("Gameboy Advance", RomFileExtensions.GBA, addArchiveExts: true),
new FilesystemFilter("Nintendo 3DS", RomFileExtensions.N3DS),
new FilesystemFilter("Nintendo DS", RomFileExtensions.NDS),
new FilesystemFilter("Master System", RomFileExtensions.SMS, 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 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<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 =
{
System = y.Attributes["System"].Value,
System = y.Attributes!["System"].Value,
Name = y.Attributes["Name"].Value,
Status = RomStatus.Unknown
},
Xml = x
};
string fullPath = "";
var fullPath = "";
var n = y.SelectSingleNode("./LoadAssets");
if (n != null)
@ -52,7 +52,7 @@ namespace BizHawk.Client.Common
foreach (XmlNode a in n.ChildNodes)
{
string filename = a.Attributes["FileName"].Value;
var filename = a.Attributes!["FileName"].Value;
byte[] data;
if (filename[0] == '|')
{
@ -67,7 +67,7 @@ namespace BizHawk.Client.Common
}
else
{
throw new Exception($"Couldn't load XMLGame Asset \"{filename}\"");
throw new($"Couldn't load XMLGame Asset \"{filename}\"");
}
}
else
@ -89,16 +89,19 @@ namespace BizHawk.Client.Common
}
else
{
data = File.ReadAllBytes(fullPath.SubstringBefore('|'));
var path = fullPath.SubstringBefore('|');
data = RomGame.Is3DSRom(path)
? Array.Empty<byte>()
: File.ReadAllBytes(path);
}
}
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);
var sha1 = SHA1Checksum.Compute(data);
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];
if (!_core.Citra_LoadROM(_context, romPath, errorMessage, errorMessage.Length))
{