From ac4b5345f7834d4bc62ef655c8a8ed17f68e3787 Mon Sep 17 00:00:00 2001 From: Sour Date: Thu, 28 Mar 2019 21:20:18 -0400 Subject: [PATCH] Debugger: Added TBL support --- InteropDLL/EmuApiWrapper.cpp | 22 ++++++ UI/Debugger/DebugWindowManager.cs | 8 +-- .../TblByteCharConverter.cs | 8 +-- UI/Debugger/MemoryTools/TblLoader.cs | 34 +++++----- UI/Debugger/MemoryTools/frmMemoryTools.cs | 52 +++++++------- UI/Debugger/Workspace/DebugWorkspace.cs | 60 ++++++++++++++++ .../Workspace/DebugWorkspaceManager.cs | 61 +++++++++++++++++ UI/Emulation/SaveStateManager.cs | 3 +- UI/Forms/Tools/frmRecordAvi.cs | 14 ++-- UI/Forms/frmMain.cs | 6 +- UI/Interop/EmuApi.cs | 68 +++++++++++++++++++ UI/UI.csproj | 4 +- 12 files changed, 274 insertions(+), 66 deletions(-) rename UI/Debugger/{HexBox => MemoryTools}/TblByteCharConverter.cs (97%) create mode 100644 UI/Debugger/Workspace/DebugWorkspace.cs create mode 100644 UI/Debugger/Workspace/DebugWorkspaceManager.cs diff --git a/InteropDLL/EmuApiWrapper.cpp b/InteropDLL/EmuApiWrapper.cpp index 8f5a866..a0deb3c 100644 --- a/InteropDLL/EmuApiWrapper.cpp +++ b/InteropDLL/EmuApiWrapper.cpp @@ -3,6 +3,7 @@ #include "../Core/EmuSettings.h" #include "../Core/VideoDecoder.h" #include "../Core/ControlManager.h" +#include "../Core/BaseCartridge.h" #include "../Core/SystemActionManager.h" #include "../Core/MessageManager.h" #include "../Core/SaveStateManager.h" @@ -34,6 +35,16 @@ string _logString; shared_ptr _console; InteropNotificationListeners _listeners; +struct InteropRomInfo +{ + const char* RomPath; + const char* PatchPath; + SnesCartInformation Header; +}; + +string _romPath; +string _patchPath; + extern "C" { DllExport bool __stdcall TestDll() { @@ -95,6 +106,17 @@ extern "C" { DllExport void __stdcall LoadRom(char* filename, char* patchFile) { _console->LoadRom((VirtualFile)filename, patchFile ? (VirtualFile)patchFile : VirtualFile()); } //DllExport void __stdcall AddKnownGameFolder(char* folder) { FolderUtilities::AddKnownGameFolder(folder); } + DllExport void __stdcall GetRomInfo(InteropRomInfo &info) + { + RomInfo romInfo = _console->GetCartridge()->GetRomInfo(); + _romPath = romInfo.RomFile; + _patchPath = romInfo.PatchFile; + + info.Header = romInfo.Header; + info.RomPath = _romPath.c_str(); + info.PatchPath = _patchPath.c_str(); + } + DllExport void __stdcall TakeScreenshot() { _console->GetVideoDecoder()->TakeScreenshot(); } DllExport const char* __stdcall GetArchiveRomList(char* filename) { diff --git a/UI/Debugger/DebugWindowManager.cs b/UI/Debugger/DebugWindowManager.cs index 7281f48..ee8e594 100644 --- a/UI/Debugger/DebugWindowManager.cs +++ b/UI/Debugger/DebugWindowManager.cs @@ -1,4 +1,5 @@ -using Mesen.GUI.Forms; +using Mesen.GUI.Debugger.Workspace; +using Mesen.GUI.Forms; using System; using System.Collections.Generic; using System.Linq; @@ -101,9 +102,8 @@ namespace Mesen.GUI.Debugger { if(_openedWindows.Count == 0) { //All windows have been closed, disable debugger - //TODO - //DebugWorkspaceManager.SaveWorkspace(); - //DebugWorkspaceManager.Clear(); + DebugWorkspaceManager.SaveWorkspace(); + DebugWorkspaceManager.Clear(); DebugApi.ReleaseDebugger(); } } diff --git a/UI/Debugger/HexBox/TblByteCharConverter.cs b/UI/Debugger/MemoryTools/TblByteCharConverter.cs similarity index 97% rename from UI/Debugger/HexBox/TblByteCharConverter.cs rename to UI/Debugger/MemoryTools/TblByteCharConverter.cs index 7dc0aed..da35eb9 100644 --- a/UI/Debugger/HexBox/TblByteCharConverter.cs +++ b/UI/Debugger/MemoryTools/TblByteCharConverter.cs @@ -1,11 +1,11 @@ -using System; +using Be.Windows.Forms; +using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; -using static Mesen.GUI.Debugger.TblLoader; -namespace Be.Windows.Forms +namespace Mesen.GUI.Debugger { /// /// The default implementation. @@ -72,7 +72,7 @@ namespace Be.Windows.Forms public virtual byte[] GetBytes(string text) { List bytes = new List(); - + bool match = false; while(text.Length > 0) { do { diff --git a/UI/Debugger/MemoryTools/TblLoader.cs b/UI/Debugger/MemoryTools/TblLoader.cs index c592023..e9b4f6a 100644 --- a/UI/Debugger/MemoryTools/TblLoader.cs +++ b/UI/Debugger/MemoryTools/TblLoader.cs @@ -10,23 +10,6 @@ namespace Mesen.GUI.Debugger { public class TblLoader { - public struct TblKey - { - public UInt64 Key; - public int Length; - - public byte[] GetBytes() - { - byte[] bytes = new byte[this.Length]; - UInt64 value = this.Key; - for(int i = 0; i < this.Length; i++) { - bytes[i] = (byte)value; - value >>= 8; - } - return bytes; - } - } - public static Dictionary ToDictionary(string[] fileContents) { try { @@ -58,4 +41,21 @@ namespace Mesen.GUI.Debugger } } } + + public struct TblKey + { + public UInt64 Key; + public int Length; + + public byte[] GetBytes() + { + byte[] bytes = new byte[this.Length]; + UInt64 value = this.Key; + for(int i = 0; i < this.Length; i++) { + bytes[i] = (byte)value; + value >>= 8; + } + return bytes; + } + } } diff --git a/UI/Debugger/MemoryTools/frmMemoryTools.cs b/UI/Debugger/MemoryTools/frmMemoryTools.cs index 91c5b3b..5da1f73 100644 --- a/UI/Debugger/MemoryTools/frmMemoryTools.cs +++ b/UI/Debugger/MemoryTools/frmMemoryTools.cs @@ -5,6 +5,8 @@ using System.Windows.Forms; using Mesen.GUI.Config; using Mesen.GUI.Forms; using Mesen.GUI.Debugger.Controls; +using System.Collections.Generic; +using Mesen.GUI.Debugger.Workspace; namespace Mesen.GUI.Debugger { @@ -67,8 +69,7 @@ namespace Mesen.GUI.Debugger this.UpdateFadeOptions(); - //TODO - //this.InitTblMappings(); + this.InitTblMappings(); this.ctrlHexViewer.StringViewVisible = mnuShowCharacters.Checked; //TODO @@ -215,7 +216,7 @@ namespace Mesen.GUI.Debugger GoToDestination(frm.Destination); } } - } + }*/ private void InitTblMappings() { @@ -228,7 +229,7 @@ namespace Mesen.GUI.Debugger } else { this.ctrlHexViewer.ByteCharConverter = null; } - }*/ + } private void OnNotificationReceived(NotificationEventArgs e) { @@ -243,6 +244,7 @@ namespace Mesen.GUI.Debugger if(_formClosed) { return; } + this.InitTblMappings(); this.InitMemoryTypeDropdown(false); //TODO ctrlMemoryAccessCounters.InitMemoryTypeDropdown(); })); @@ -312,14 +314,6 @@ namespace Mesen.GUI.Debugger return; } - //TODO - /* - if(DebugWorkspaceManager.GetWorkspace() != this._previousWorkspace) { - this.InitTblMappings(); - _previousWorkspace = DebugWorkspaceManager.GetWorkspace(); - } - */ - if(this.tabMain.SelectedTab == this.tpgAccessCounters) { //TODO this.ctrlMemoryAccessCounters.RefreshData(); } else if(this.tabMain.SelectedTab == this.tpgMemoryViewer) { @@ -416,7 +410,7 @@ namespace Mesen.GUI.Debugger using(SaveFileDialog sfd = new SaveFileDialog()) { sfd.SetFilter("Memory dump files (*.dmp)|*.dmp|All files (*.*)|*.*"); sfd.InitialDirectory = ConfigManager.DebuggerFolder; - //TODO sfd.FileName = InteropEmu.GetRomInfo().GetRomName() + " - " + cboMemoryType.SelectedItem.ToString() + ".dmp"; + sfd.FileName = EmuApi.GetRomInfo().GetRomName() + " - " + cboMemoryType.SelectedItem.ToString() + ".dmp"; sfd.FileName = cboMemoryType.SelectedItem.ToString() + ".dmp"; if(sfd.ShowDialog() == DialogResult.OK) { File.WriteAllBytes(sfd.FileName, this.ctrlHexViewer.GetData()); @@ -437,27 +431,27 @@ namespace Mesen.GUI.Debugger private void mnuLoadTblFile_Click(object sender, EventArgs e) { - //TODO - /*OpenFileDialog ofd = new OpenFileDialog(); - ofd.SetFilter("TBL files (*.tbl)|*.tbl"); - if(ofd.ShowDialog() == DialogResult.OK) { - string[] fileContents = File.ReadAllLines(ofd.FileName); - var tblDict = TblLoader.ToDictionary(fileContents); - if(tblDict == null) { - MessageBox.Show("Could not load TBL file. The file selected file appears to be invalid.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); - } else { - DebugWorkspaceManager.GetWorkspace().TblMappings = new List(fileContents); - this.ctrlHexViewer.ByteCharConverter = new TblByteCharConverter(tblDict); - this.mnuShowCharacters.Checked = true; + using(OpenFileDialog ofd = new OpenFileDialog()) { + ofd.SetFilter("TBL files (*.tbl)|*.tbl"); + if(ofd.ShowDialog() == DialogResult.OK) { + string[] fileContents = File.ReadAllLines(ofd.FileName); + var tblDict = TblLoader.ToDictionary(fileContents); + if(tblDict == null) { + MessageBox.Show("Could not load TBL file. The file selected file appears to be invalid.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + } else { + DebugWorkspaceManager.GetWorkspace().TblMappings = new List(fileContents); + this.ctrlHexViewer.ByteCharConverter = new TblByteCharConverter(tblDict); + this.mnuShowCharacters.Checked = true; + InitTblMappings(); + } } - }*/ + } } private void mnuResetTblMappings_Click(object sender, EventArgs e) { - //TODO - //DebugWorkspaceManager.GetWorkspace().TblMappings = null; - //this.ctrlHexViewer.ByteCharConverter = null; + DebugWorkspaceManager.GetWorkspace().TblMappings = null; + this.ctrlHexViewer.ByteCharConverter = null; } private void mnuShowCharacters_CheckedChanged(object sender, EventArgs e) diff --git a/UI/Debugger/Workspace/DebugWorkspace.cs b/UI/Debugger/Workspace/DebugWorkspace.cs new file mode 100644 index 0000000..c8ef7ee --- /dev/null +++ b/UI/Debugger/Workspace/DebugWorkspace.cs @@ -0,0 +1,60 @@ +using Mesen.GUI.Config; +using Mesen.GUI.Debugger; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml; +using System.Xml.Serialization; + +namespace Mesen.GUI.Debugger.Workspace +{ + public class DebugWorkspace + { + public List Breakpoints = new List(); + public List WatchValues = new List(); + //public List Labels = new List(); + public List TblMappings = null; + private string _filePath; + + public static DebugWorkspace GetWorkspace() + { + RomInfo info = EmuApi.GetRomInfo(); + return Deserialize(Path.Combine(ConfigManager.DebuggerFolder, info.GetRomName() + ".Workspace.xml")); + } + + private static DebugWorkspace Deserialize(string path) + { + DebugWorkspace config = new DebugWorkspace(); + + if(File.Exists(path)) { + try { + XmlSerializer xmlSerializer = new XmlSerializer(typeof(DebugWorkspace)); + using(TextReader textReader = new StreamReader(path)) { + config = (DebugWorkspace)xmlSerializer.Deserialize(textReader); + } + } catch { } + } + + config._filePath = path; + + return config; + } + + public void Save() + { + try { + XmlWriterSettings ws = new XmlWriterSettings(); + ws.NewLineHandling = NewLineHandling.Entitize; + + XmlSerializer xmlSerializer = new XmlSerializer(typeof(DebugWorkspace)); + using(XmlWriter xmlWriter = XmlWriter.Create(_filePath, ws)) { + xmlSerializer.Serialize(xmlWriter, this); + } + } catch { + } + } + } +} diff --git a/UI/Debugger/Workspace/DebugWorkspaceManager.cs b/UI/Debugger/Workspace/DebugWorkspaceManager.cs new file mode 100644 index 0000000..b54e4ee --- /dev/null +++ b/UI/Debugger/Workspace/DebugWorkspaceManager.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Mesen.GUI.Debugger.Workspace +{ + public class DebugWorkspaceManager + { + private static DebugWorkspace _workspace; + private static string _romName; + private static object _lock = new object(); + + public static void SaveWorkspace() + { + if(_workspace != null) { + _workspace.WatchValues = new List(WatchManager.WatchEntries); + _workspace.Breakpoints = new List(BreakpointManager.Breakpoints); + _workspace.Save(); + } + } + + public static void Clear() + { + _workspace = null; + _romName = null; + } + + public static void ResetWorkspace() + { + if(_workspace != null) { + _workspace.Breakpoints = new List(); + _workspace.WatchValues = new List(); + WatchManager.WatchEntries = _workspace.WatchValues; + BreakpointManager.SetBreakpoints(_workspace.Breakpoints); + _workspace.Save(); + Clear(); + } + } + + public static DebugWorkspace GetWorkspace() + { + string romName = EmuApi.GetRomInfo().GetRomName(); + if(_workspace == null || _romName != romName) { + if(_workspace != null) { + SaveWorkspace(); + } + _romName = romName; + _workspace = DebugWorkspace.GetWorkspace(); + + //Load watch entries + WatchManager.WatchEntries = _workspace.WatchValues; + + //Load breakpoints + BreakpointManager.SetBreakpoints(_workspace.Breakpoints); + } + return _workspace; + } + } +} diff --git a/UI/Emulation/SaveStateManager.cs b/UI/Emulation/SaveStateManager.cs index 5f7223a..ef1a6bb 100644 --- a/UI/Emulation/SaveStateManager.cs +++ b/UI/Emulation/SaveStateManager.cs @@ -103,8 +103,7 @@ namespace Mesen.GUI.Emulation if(EmuRunner.IsRunning()) { using(SaveFileDialog sfd = new SaveFileDialog()) { sfd.InitialDirectory = ConfigManager.SaveStateFolder; - //TODO - //sfd.FileName = EmuApi.GetRomInfo().GetRomName() + ".mst"; + sfd.FileName = EmuApi.GetRomInfo().GetRomName() + ".mst"; sfd.SetFilter(ResourceHelper.GetMessage("FilterSavestate")); if(sfd.ShowDialog(Application.OpenForms[0]) == DialogResult.OK) { EmuApi.SaveStateFile(sfd.FileName); diff --git a/UI/Forms/Tools/frmRecordAvi.cs b/UI/Forms/Tools/frmRecordAvi.cs index 902bc96..4f55216 100644 --- a/UI/Forms/Tools/frmRecordAvi.cs +++ b/UI/Forms/Tools/frmRecordAvi.cs @@ -38,13 +38,13 @@ namespace Mesen.GUI.Forms private void btnBrowse_Click(object sender, EventArgs e) { - SaveFileDialog sfd = new SaveFileDialog(); - sfd.SetFilter(ResourceHelper.GetMessage("FilterAvi")); - sfd.InitialDirectory = ConfigManager.AviFolder; - //TODO - //sfd.FileName = InteropEmu.GetRomInfo().GetRomName() + ".avi"; - if(sfd.ShowDialog() == System.Windows.Forms.DialogResult.OK) { - txtFilename.Text = sfd.FileName; + using(SaveFileDialog sfd = new SaveFileDialog()) { + sfd.SetFilter(ResourceHelper.GetMessage("FilterAvi")); + sfd.InitialDirectory = ConfigManager.AviFolder; + sfd.FileName = EmuApi.GetRomInfo().GetRomName() + ".avi"; + if(sfd.ShowDialog() == DialogResult.OK) { + txtFilename.Text = sfd.FileName; + } } } diff --git a/UI/Forms/frmMain.cs b/UI/Forms/frmMain.cs index 0078d60..5ef04dd 100644 --- a/UI/Forms/frmMain.cs +++ b/UI/Forms/frmMain.cs @@ -111,6 +111,9 @@ namespace Mesen.GUI.Forms ctrlRecentGames.Visible = false; SaveStateManager.UpdateStateMenu(mnuLoadState, false); SaveStateManager.UpdateStateMenu(mnuSaveState, true); + + RomInfo romInfo = EmuApi.GetRomInfo(); + this.Text = "Mesen-S - " + romInfo.GetRomName(); })); break; @@ -472,8 +475,7 @@ namespace Mesen.GUI.Forms using(SaveFileDialog sfd = new SaveFileDialog()) { sfd.SetFilter(ResourceHelper.GetMessage("FilterWave")); sfd.InitialDirectory = ConfigManager.WaveFolder; - //TODO - //sfd.FileName = InteropEmu.GetRomInfo().GetRomName() + ".wav"; + sfd.FileName = EmuApi.GetRomInfo().GetRomName() + ".wav"; if(sfd.ShowDialog(this) == DialogResult.OK) { RecordApi.WaveRecord(sfd.FileName); } diff --git a/UI/Interop/EmuApi.cs b/UI/Interop/EmuApi.cs index 32b4ba6..c1488b6 100644 --- a/UI/Interop/EmuApi.cs +++ b/UI/Interop/EmuApi.cs @@ -51,6 +51,14 @@ namespace Mesen.GUI [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(Utf8Marshaler))]string patchFile = "" ); + [DllImport(DllPath, EntryPoint = "GetRomInfo")] private static extern void GetRomInfoWrapper(out InteropRomInfo romInfo); + public static RomInfo GetRomInfo() + { + InteropRomInfo info; + EmuApi.GetRomInfoWrapper(out info); + return new RomInfo(info); + } + [DllImport(DllPath)] public static extern void LoadRecentGame([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(Utf8Marshaler))]string filepath, [MarshalAs(UnmanagedType.I1)]bool resetGame); [DllImport(DllPath)] public static extern void AddKnownGameFolder([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(Utf8Marshaler))]string folder); @@ -86,4 +94,64 @@ namespace Mesen.GUI public Int32 Height; public double Scale; } + + public struct InteropRomInfo + { + public IntPtr RomPath; + public IntPtr PatchPath; + public SnesCartInformation Header; + } + + public struct RomInfo + { + public string RomPath; + public string PatchPath; + public SnesCartInformation Header; + + public RomInfo(InteropRomInfo romInfo) + { + RomPath = (ResourcePath)Utf8Marshaler.GetStringFromIntPtr(romInfo.RomPath); + PatchPath = (ResourcePath)Utf8Marshaler.GetStringFromIntPtr(romInfo.PatchPath); + Header = romInfo.Header; + } + + public string GetRomName() + { + return Path.GetFileNameWithoutExtension(((ResourcePath)RomPath).FileName); + } + } + + public struct SnesCartInformation + { + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] + public byte[] MakerCode; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] + public byte[] GameCode; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 7)] + public byte[] Reserved; + + public byte ExpansionRamSize; + public byte SpecialVersion; + public byte CartridgeType; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 21)] + public byte[] CartName; + + public byte MapMode; + public byte RomType; + public byte RomSize; + public byte SramSize; + + public byte DestinationCode; + public byte Reserved2; + public byte Version; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] + public byte[] ChecksumComplement; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] + public byte[] Checksum; + } } diff --git a/UI/UI.csproj b/UI/UI.csproj index 27d1ede..e414cdc 100644 --- a/UI/UI.csproj +++ b/UI/UI.csproj @@ -248,6 +248,7 @@ + @@ -431,6 +432,7 @@ frmMemoryViewerColors.cs + UserControl @@ -488,7 +490,6 @@ - @@ -502,6 +503,7 @@ Form +