Debugger: Hex Editor - Added context menu options (watch, breakpoint, label)

This commit is contained in:
Sour 2019-05-05 20:29:55 -04:00
parent 7ad3bef9fd
commit 71b2add83b
4 changed files with 183 additions and 10 deletions

View file

@ -50,6 +50,10 @@
this.mnuPaste = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem5 = new System.Windows.Forms.ToolStripSeparator();
this.mnuSelectAll = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator();
this.mnuAddToWatch = new System.Windows.Forms.ToolStripMenuItem();
this.mnuEditBreakpoint = new System.Windows.Forms.ToolStripMenuItem();
this.mnuEditLabel = new System.Windows.Forms.ToolStripMenuItem();
this.tlpMain.SuspendLayout();
this.flowLayoutPanel1.SuspendLayout();
this.panelSearch.SuspendLayout();
@ -296,18 +300,23 @@
// ctxMenuStrip
//
this.ctxMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.mnuAddToWatch,
this.mnuEditBreakpoint,
this.mnuEditLabel,
this.toolStripMenuItem1,
this.mnuCopy,
this.mnuPaste,
this.toolStripMenuItem5,
this.mnuSelectAll});
this.ctxMenuStrip.Name = "ctxMenuStrip";
this.ctxMenuStrip.Size = new System.Drawing.Size(153, 98);
this.ctxMenuStrip.Size = new System.Drawing.Size(155, 170);
this.ctxMenuStrip.Opening += new System.ComponentModel.CancelEventHandler(this.ctxMenuStrip_Opening);
//
// mnuCopy
//
this.mnuCopy.Image = global::Mesen.GUI.Properties.Resources.Copy;
this.mnuCopy.Name = "mnuCopy";
this.mnuCopy.Size = new System.Drawing.Size(152, 22);
this.mnuCopy.Size = new System.Drawing.Size(154, 22);
this.mnuCopy.Text = "Copy";
this.mnuCopy.Click += new System.EventHandler(this.mnuCopy_Click);
//
@ -315,23 +324,52 @@
//
this.mnuPaste.Image = global::Mesen.GUI.Properties.Resources.Paste;
this.mnuPaste.Name = "mnuPaste";
this.mnuPaste.Size = new System.Drawing.Size(152, 22);
this.mnuPaste.Size = new System.Drawing.Size(154, 22);
this.mnuPaste.Text = "Paste";
this.mnuPaste.Click += new System.EventHandler(this.mnuPaste_Click);
//
// toolStripMenuItem5
//
this.toolStripMenuItem5.Name = "toolStripMenuItem5";
this.toolStripMenuItem5.Size = new System.Drawing.Size(149, 6);
this.toolStripMenuItem5.Size = new System.Drawing.Size(151, 6);
//
// mnuSelectAll
//
this.mnuSelectAll.Image = global::Mesen.GUI.Properties.Resources.SelectAll;
this.mnuSelectAll.Name = "mnuSelectAll";
this.mnuSelectAll.Size = new System.Drawing.Size(152, 22);
this.mnuSelectAll.Size = new System.Drawing.Size(154, 22);
this.mnuSelectAll.Text = "Select All";
this.mnuSelectAll.Click += new System.EventHandler(this.mnuSelectAll_Click);
//
// toolStripMenuItem1
//
this.toolStripMenuItem1.Name = "toolStripMenuItem1";
this.toolStripMenuItem1.Size = new System.Drawing.Size(151, 6);
//
// mnuAddToWatch
//
this.mnuAddToWatch.Image = global::Mesen.GUI.Properties.Resources.Add;
this.mnuAddToWatch.Name = "mnuAddToWatch";
this.mnuAddToWatch.Size = new System.Drawing.Size(154, 22);
this.mnuAddToWatch.Text = "Add to Watch";
this.mnuAddToWatch.Click += new System.EventHandler(this.mnuAddToWatch_Click);
//
// mnuEditBreakpoint
//
this.mnuEditBreakpoint.Image = global::Mesen.GUI.Properties.Resources.BreakpointEnableDisable;
this.mnuEditBreakpoint.Name = "mnuEditBreakpoint";
this.mnuEditBreakpoint.Size = new System.Drawing.Size(154, 22);
this.mnuEditBreakpoint.Text = "Edit Breakpoint";
this.mnuEditBreakpoint.Click += new System.EventHandler(this.mnuEditBreakpoint_Click);
//
// mnuEditLabel
//
this.mnuEditLabel.Image = global::Mesen.GUI.Properties.Resources.EditLabel;
this.mnuEditLabel.Name = "mnuEditLabel";
this.mnuEditLabel.Size = new System.Drawing.Size(154, 22);
this.mnuEditLabel.Text = "Edit Label";
this.mnuEditLabel.Click += new System.EventHandler(this.mnuEditLabel_Click);
//
// ctrlHexViewer
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@ -385,5 +423,9 @@
private System.Windows.Forms.ToolStripMenuItem mnuPaste;
private System.Windows.Forms.ToolStripMenuItem mnuSelectAll;
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem5;
private System.Windows.Forms.ToolStripMenuItem mnuAddToWatch;
private System.Windows.Forms.ToolStripMenuItem mnuEditBreakpoint;
private System.Windows.Forms.ToolStripMenuItem mnuEditLabel;
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem1;
}
}

View file

@ -12,6 +12,7 @@ using Be.Windows.Forms;
using Mesen.GUI.Controls;
using static Be.Windows.Forms.DynamicByteProvider;
using Mesen.GUI.Forms;
using Mesen.GUI.Debugger.Labels;
namespace Mesen.GUI.Debugger.Controls
{
@ -21,6 +22,9 @@ namespace Mesen.GUI.Debugger.Controls
private StaticByteProvider _byteProvider;
private SnesMemoryType _memoryType;
private int SelectionStartAddress { get { return (int)ctrlHexBox.SelectionStart; } }
private int SelectionEndAddress { get { return (int)(ctrlHexBox.SelectionStart + (ctrlHexBox.SelectionLength == 0 ? 0 : (ctrlHexBox.SelectionLength - 1))); } }
public ctrlHexViewer()
{
InitializeComponent();
@ -40,10 +44,18 @@ namespace Mesen.GUI.Debugger.Controls
base.OnLoad(e);
if(!IsDesignMode) {
this.cboNumberColumns.SelectedIndex = ConfigManager.Config.Debug.HexEditor.ColumnCount;
cboNumberColumns.SelectedIndex = ConfigManager.Config.Debug.HexEditor.ColumnCount;
InitShortcuts();
}
}
private void InitShortcuts()
{
mnuAddToWatch.InitShortcut(this, nameof(DebuggerShortcutsConfig.MemoryViewer_AddToWatch));
mnuEditBreakpoint.InitShortcut(this, nameof(DebuggerShortcutsConfig.MemoryViewer_EditBreakpoint));
mnuEditLabel.InitShortcut(this, nameof(DebuggerShortcutsConfig.MemoryViewer_EditLabel));
}
public new void Focus()
{
this.ctrlHexBox.Focus();
@ -209,6 +221,8 @@ namespace Mesen.GUI.Debugger.Controls
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
UpdateActionAvailability();
if(keyData == ConfigManager.Config.Debug.Shortcuts.Find) {
this.OpenSearchBox(true);
return true;
@ -458,5 +472,96 @@ namespace Mesen.GUI.Debugger.Controls
{
ctrlHexBox.SelectAll();
}
private void UpdateActionAvailability()
{
UInt32 startAddress = (UInt32)SelectionStartAddress;
UInt32 endAddress = (UInt32)SelectionEndAddress;
string address = "$" + startAddress.ToString("X4");
string addressRange;
if(startAddress != endAddress) {
addressRange = "$" + startAddress.ToString("X4") + "-$" + endAddress.ToString("X4");
} else {
addressRange = address;
}
mnuEditLabel.Text = $"Edit Label ({address})";
mnuEditBreakpoint.Text = $"Edit Breakpoint ({addressRange})";
mnuAddToWatch.Text = $"Add to Watch ({addressRange})";
if(_memoryType == SnesMemoryType.CpuMemory || _memoryType == SnesMemoryType.SpcMemory) {
AddressInfo relAddress = new AddressInfo() {
Address = (int)startAddress,
Type = _memoryType
};
AddressInfo absAddress = DebugApi.GetAbsoluteAddress(relAddress);
mnuEditLabel.Enabled = absAddress.Address != -1 && absAddress.Type.SupportsLabels();
mnuAddToWatch.Enabled = _memoryType.SupportsWatch();
} else {
mnuEditLabel.Enabled = _memoryType.SupportsLabels();
mnuAddToWatch.Enabled = false;
}
mnuEditBreakpoint.Enabled = true;
}
private void mnuAddToWatch_Click(object sender, EventArgs e)
{
if(_memoryType.SupportsWatch()) {
string[] toAdd = Enumerable.Range(SelectionStartAddress, SelectionEndAddress - SelectionStartAddress + 1).Select((num) => $"[${num.ToString("X6")}]").ToArray();
WatchManager.GetWatchManager(_memoryType.ToCpuType()).AddWatch(toAdd);
}
}
private void mnuEditBreakpoint_Click(object sender, EventArgs e)
{
UInt32 startAddress = (UInt32)SelectionStartAddress;
UInt32 endAddress = (UInt32)SelectionEndAddress;
BreakpointAddressType addressType = startAddress == endAddress ? BreakpointAddressType.SingleAddress : BreakpointAddressType.AddressRange;
Breakpoint bp = BreakpointManager.GetMatchingBreakpoint(startAddress, endAddress, _memoryType);
if(bp == null) {
bp = new Breakpoint() { Address = startAddress, MemoryType = _memoryType, StartAddress = startAddress, EndAddress = endAddress, AddressType = addressType, BreakOnWrite = true, BreakOnRead = true };
if(bp.IsCpuBreakpoint) {
bp.BreakOnExec = true;
}
}
BreakpointManager.EditBreakpoint(bp);
}
private void mnuEditLabel_Click(object sender, EventArgs e)
{
UInt32 address = (UInt32)ctrlHexBox.SelectionStart;
SnesMemoryType memType = _memoryType;
if(!memType.SupportsLabels()) {
AddressInfo relAddress = new AddressInfo() {
Address = (int)address,
Type = memType
};
AddressInfo absAddress = DebugApi.GetAbsoluteAddress(relAddress);
if(absAddress.Address < 0 || !absAddress.Type.SupportsLabels()) {
return;
}
address = (uint)absAddress.Address;
memType = absAddress.Type;
}
CodeLabel label = LabelManager.GetLabel(address, memType);
if(label == null) {
label = new CodeLabel() {
Address = address,
MemoryType = memType
};
}
ctrlLabelList.EditLabel(label);
}
private void ctxMenuStrip_Opening(object sender, CancelEventArgs e)
{
UpdateActionAvailability();
}
}
}

View file

@ -60,15 +60,15 @@ namespace Mesen.GUI.Debugger
};
ctrlDbgShortcutsMemoryViewer.Shortcuts = new FieldInfo[] {
/*GetMember(nameof(DebuggerShortcutsConfig.MemoryViewer_Freeze)),
GetMember(nameof(DebuggerShortcutsConfig.MemoryViewer_Unfreeze)),
//GetMember(nameof(DebuggerShortcutsConfig.MemoryViewer_Freeze)),
//GetMember(nameof(DebuggerShortcutsConfig.MemoryViewer_Unfreeze)),
GetMember(nameof(DebuggerShortcutsConfig.MemoryViewer_AddToWatch)),
GetMember(nameof(DebuggerShortcutsConfig.MemoryViewer_EditBreakpoint)),
GetMember(nameof(DebuggerShortcutsConfig.MemoryViewer_EditLabel)),
GetMember(nameof(DebuggerShortcutsConfig.MemoryViewer_Import)),
GetMember(nameof(DebuggerShortcutsConfig.MemoryViewer_Export)),
GetMember(nameof(DebuggerShortcutsConfig.MemoryViewer_ViewInCpuMemory)),
GetMember(nameof(DebuggerShortcutsConfig.MemoryViewer_ViewInMemoryType))*/
//GetMember(nameof(DebuggerShortcutsConfig.MemoryViewer_ViewInCpuMemory)),
//GetMember(nameof(DebuggerShortcutsConfig.MemoryViewer_ViewInMemoryType))
};
/*ctrlDbgShortcutsScriptWindow.Shortcuts = new FieldInfo[] {

View file

@ -179,6 +179,32 @@ namespace Mesen.GUI
return CpuType.Cpu;
}
}
public static bool SupportsLabels(this SnesMemoryType memType)
{
switch(memType) {
case SnesMemoryType.PrgRom:
case SnesMemoryType.WorkRam:
case SnesMemoryType.SaveRam:
case SnesMemoryType.Register:
case SnesMemoryType.SpcRam:
case SnesMemoryType.SpcRom:
return true;
}
return false;
}
public static bool SupportsWatch(this SnesMemoryType memType)
{
switch(memType) {
case SnesMemoryType.CpuMemory:
case SnesMemoryType.SpcMemory:
return true;
}
return false;
}
}
public struct AddressInfo