From 788990c2d66e85a82f9c0ee7ce19b3de4129b5bb Mon Sep 17 00:00:00 2001 From: Fiskbit <2811896+Fiskbit@users.noreply.github.com> Date: Sun, 12 Apr 2026 16:54:15 -0700 Subject: [PATCH] Tool: Makes header editor work with archived/soft-patched ROMs. The NES header editor is currently unable to save a ROM if it was loaded from an archive (such as .zip) or if the ROM was soft-patched. This is because the editor reloads the ROM from disk to then apply the new header and save a copy, but the C# compnent is not able to open archives or apply patches. If the ROM file is in an archive, it throws an Unexpected Error and fails. This change instead makes the editor use the current PRG and CHR ROM. This means it doesn't need to reload the ROM, so it can save it regardless of how it was loaded. It also means that it saves any changes that have been made to the ROM in the session, either by self-flashing or by editing them via tools, which could be seen as a pro or a con. Also, because Mesen does not currently use misc ROM, it is unable to include that in the saved ROM, but this is something we could feasibly add later. This change was written by Sour. --- .../ViewModels/NesHeaderEditViewModel.cs | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/UI/Debugger/ViewModels/NesHeaderEditViewModel.cs b/UI/Debugger/ViewModels/NesHeaderEditViewModel.cs index 49a26e527..9f3a2c4b1 100644 --- a/UI/Debugger/ViewModels/NesHeaderEditViewModel.cs +++ b/UI/Debugger/ViewModels/NesHeaderEditViewModel.cs @@ -29,12 +29,16 @@ public class NesHeaderEditViewModel : DisposableViewModel [Reactive] public string ErrorMessage { get; private set; } = ""; private RomInfo _romInfo; + private byte[] _prgRom; + private byte[] _chrRom; public NesHeaderEditViewModel() { bool releaseDebugger = !DebugWindowManager.HasOpenedDebugWindows(); bool paused = EmuApi.IsPaused(); byte[] headerBytes = DebugApi.GetRomHeader(); + _prgRom = DebugApi.GetMemoryState(MemoryType.NesPrgRom); + _chrRom = DebugApi.GetMemoryState(MemoryType.NesChrRom); if(releaseDebugger) { //GetRomHeader will initialize the debugger - stop the debugger if no other debug window is opened DebugApi.ReleaseDebugger(); @@ -150,16 +154,14 @@ private string GetErrorMessage() public async Task Save(Window wnd) { - string? filepath = await FileDialogHelper.SaveFile(Path.GetDirectoryName(_romInfo.RomPath), Path.GetFileName(_romInfo.RomPath), wnd, FileDialogHelper.NesExt); + string? filepath = await FileDialogHelper.SaveFile(Path.GetDirectoryName(_romInfo.RomPath), _romInfo.GetRomName(), wnd, FileDialogHelper.NesExt); if(filepath != null) { - byte[]? data = FileHelper.ReadAllBytes(_romInfo.RomPath); - if(data != null) { - byte[] header = Header.ToBytes(); - for(int i = 0; i < 16; i++) { - data[i] = header[i]; - } - return FileHelper.WriteAllBytes(filepath, data); - } + byte[] data = new byte[_prgRom.Length + _chrRom.Length + 16]; + byte[] header = Header.ToBytes(); + Array.Copy(header, data, 16); + Array.Copy(_prgRom, 0, data, 16, _prgRom.Length); + Array.Copy(_chrRom, 0, data, 16 + _prgRom.Length, _chrRom.Length); + return FileHelper.WriteAllBytes(filepath, data); } return false; }