diff --git a/output/dll/faust.wbx.gz b/output/dll/faust.wbx.gz index c9e46e6133..92a221b31c 100644 Binary files a/output/dll/faust.wbx.gz and b/output/dll/faust.wbx.gz differ diff --git a/output/dll/hyper.wbx.gz b/output/dll/hyper.wbx.gz index deb01e967a..88b3e130b0 100644 Binary files a/output/dll/hyper.wbx.gz and b/output/dll/hyper.wbx.gz differ diff --git a/output/dll/ngp.wbx.gz b/output/dll/ngp.wbx.gz index f32baa492c..57fa429394 100644 Binary files a/output/dll/ngp.wbx.gz and b/output/dll/ngp.wbx.gz differ diff --git a/output/dll/pcfx.wbx.gz b/output/dll/pcfx.wbx.gz index 2218cb129d..a9c9ab95a0 100644 Binary files a/output/dll/pcfx.wbx.gz and b/output/dll/pcfx.wbx.gz differ diff --git a/output/dll/ss.wbx.gz b/output/dll/ss.wbx.gz index 36faf5d3e9..ef9ba4b2f6 100644 Binary files a/output/dll/ss.wbx.gz and b/output/dll/ss.wbx.gz differ diff --git a/output/dll/turbo.wbx.gz b/output/dll/turbo.wbx.gz index d94c53cf75..0d92d5176e 100644 Binary files a/output/dll/turbo.wbx.gz and b/output/dll/turbo.wbx.gz differ diff --git a/src/BizHawk.Emulation.Cores/Waterbox/LibNymaCore.cs b/src/BizHawk.Emulation.Cores/Waterbox/LibNymaCore.cs index 428b8bf5b4..434b3e55fd 100644 --- a/src/BizHawk.Emulation.Cores/Waterbox/LibNymaCore.cs +++ b/src/BizHawk.Emulation.Cores/Waterbox/LibNymaCore.cs @@ -168,6 +168,14 @@ namespace BizHawk.Emulation.Cores.Waterbox [BizImport(CC)] public abstract void SetFrontendSettingQuery(FrontendSettingQuery q); + public delegate void FrontendFirmwareNotify(string name); + /// + /// Set a callback to be called whenever the core calls MDFN_MakeFName for a firmware, so that we can load firmwares on demand + /// + /// + [BizImport(CC)] + public abstract void SetFrontendFirmwareNotify(FrontendFirmwareNotify cb); + [StructLayout(LayoutKind.Sequential)] public class TOC { diff --git a/src/BizHawk.Emulation.Cores/Waterbox/NymaCore.cs b/src/BizHawk.Emulation.Cores/Waterbox/NymaCore.cs index 9a3df175cc..51cfa80fae 100644 --- a/src/BizHawk.Emulation.Cores/Waterbox/NymaCore.cs +++ b/src/BizHawk.Emulation.Cores/Waterbox/NymaCore.cs @@ -53,10 +53,30 @@ namespace BizHawk.Emulation.Cores.Waterbox _cdTocCallback = CDTOCCallback; _cdSectorCallback = CDSectorCallback; + var filesToRemove = new List(); + + var firmwareDelegate = new LibNymaCore.FrontendFirmwareNotify((name) => + { + if (firmwares != null && firmwares.TryGetValue(name, out var info)) + { + var data = CoreComm.CoreFileProvider.GetFirmware(info.SystemID, info.FirmwareID, true, + "Firmware files are usually required and may stop your game from loading"); + if (data != null) + { + _exe.AddReadonlyFile(data, name); + filesToRemove.Add(name); + } + } + else + { + throw new InvalidOperationException($"Core asked for firmware `{name}`, but that was not understood by the system"); + } + }); + var t = PreInit(new WaterboxOptions { Filename = wbxFilename, - // MemoryBlock understands reserve vs commit semantics, so nothing to be gained by making these precisely sized + // WaterboxHost only saves parts of memory that have changed, so not much to be gained by making these precisely sized SbrkHeapSizeKB = 1024 * 16, SealedHeapSizeKB = 1024 * 48, InvisibleHeapSizeKB = 1024 * 48, @@ -64,50 +84,17 @@ namespace BizHawk.Emulation.Cores.Waterbox MmapHeapSizeKB = 1024 * 48, SkipCoreConsistencyCheck = CoreComm.CorePreferences.HasFlag(CoreComm.CorePreferencesFlags.WaterboxCoreConsistencyCheck), SkipMemoryConsistencyCheck = CoreComm.CorePreferences.HasFlag(CoreComm.CorePreferencesFlags.WaterboxMemoryConsistencyCheck), - }, new Delegate[] { _settingsQueryDelegate, _cdTocCallback, _cdSectorCallback }); + }, new Delegate[] { _settingsQueryDelegate, _cdTocCallback, _cdSectorCallback, firmwareDelegate }); _nyma = t; using (_exe.EnterExit()) { _nyma.PreInit(); + _nyma.SetFrontendFirmwareNotify(firmwareDelegate); var portData = GetInputPortsData(); InitAllSettingsInfo(portData); _nyma.SetFrontendSettingQuery(_settingsQueryDelegate); - var filesToRemove = new List(); - if (firmwares != null) - { - foreach (var kvp in firmwares) - { - var s = kvp.Key; - var tt = kvp.Value; - var data = CoreComm.CoreFileProvider.GetFirmware(tt.SystemID, tt.FirmwareID, false, - "Firmware files are usually required and may stop your game from loading"); - if (data != null) - { - _exe.AddReadonlyFile(data, kvp.Key); - filesToRemove.Add(s); - } - } - } - // if (firmwares != null) - // { - // _exe.MissingFileCallback = s => - // { - // if (firmwares.TryGetValue(s, out var tt)) - // { - // var data = CoreComm.CoreFileProvider.GetFirmware(tt.SystemID, tt.FirmwareID, false, - // "Firmware files are usually required and may stop your game from loading"); - // if (data != null) - // { - // _exe.AddReadonlyFile(data, s); - // filesToRemove.Add(s); - // return true; - // } - // } - // return false; - // }; - // } if (discs?.Length > 0) { _disks = discs; @@ -135,14 +122,13 @@ namespace BizHawk.Emulation.Cores.Waterbox _exe.RemoveReadonlyFile(fn); } - // if (firmwares != null) - // { - foreach (var s in filesToRemove) - { - _exe.RemoveReadonlyFile(s); - } - // _exe.MissingFileCallback = null; - // } + + foreach (var s in filesToRemove) + { + _exe.RemoveReadonlyFile(s); + } + // any later attempts to request a firmware will crash + _nyma.SetFrontendFirmwareNotify(null); var info = *_nyma.GetSystemInfo(); _videoBuffer = new int[Math.Max(info.MaxWidth * info.MaxHeight, info.LcmWidth * info.LcmHeight)]; diff --git a/waterbox/nyma/Interfaces.cpp b/waterbox/nyma/Interfaces.cpp index 11c13af65a..4fe7f1793f 100644 --- a/waterbox/nyma/Interfaces.cpp +++ b/waterbox/nyma/Interfaces.cpp @@ -36,6 +36,12 @@ CheatArea* FindCheatArea(uint32_t address) } } +static void (*FrontendFirmwareNotify)(const char* name); +ECL_EXPORT void SetFrontendFirmwareNotify(void (*cb)(const char* name)) +{ + FrontendFirmwareNotify = cb; +} + namespace Mednafen { MDFNGI *MDFNGameInfo = NULL; @@ -61,6 +67,8 @@ namespace Mednafen default: ret += "UNKNOWN:"; break; } ret += cd1; + if (type == MDFNMKF_FIRMWARE) + FrontendFirmwareNotify(ret.c_str()); return ret; }