Debugger: Add "Go to all" feature
This commit is contained in:
parent
6a3b71f36b
commit
aebde00928
13 changed files with 1043 additions and 43 deletions
|
@ -39,6 +39,10 @@ namespace Mesen.GUI.Debugger.Controls
|
|||
protected override void OnHandleCreated(EventArgs e)
|
||||
{
|
||||
base.OnHandleCreated(e);
|
||||
if(IsDesignMode) {
|
||||
return;
|
||||
}
|
||||
|
||||
InitShortcuts();
|
||||
}
|
||||
|
||||
|
@ -177,12 +181,13 @@ namespace Mesen.GUI.Debugger.Controls
|
|||
private SelectedAddressRange GetSelectedAddressRange()
|
||||
{
|
||||
int firstLineOfSelection = ctrlCode.SelectionStart;
|
||||
|
||||
while(_manager.Provider.GetLineAddress(firstLineOfSelection) < 0) {
|
||||
int lineCount = ctrlCode.LineCount;
|
||||
|
||||
while(firstLineOfSelection < lineCount && _manager.Provider.GetLineAddress(firstLineOfSelection) < 0) {
|
||||
firstLineOfSelection++;
|
||||
}
|
||||
int firstLineAfterSelection = ctrlCode.SelectionStart + ctrlCode.SelectionLength + 1;
|
||||
while(_manager.Provider.GetLineAddress(firstLineAfterSelection) < 0) {
|
||||
while(firstLineOfSelection < lineCount && _manager.Provider.GetLineAddress(firstLineAfterSelection) < 0) {
|
||||
firstLineAfterSelection++;
|
||||
}
|
||||
|
||||
|
@ -225,21 +230,58 @@ namespace Mesen.GUI.Debugger.Controls
|
|||
ctrlCode.Invalidate();
|
||||
}
|
||||
|
||||
public void ScrollToSymbol(SourceSymbol symbol)
|
||||
public void GoToDestination(GoToDestination dest)
|
||||
{
|
||||
bool bringToFront = true;
|
||||
if(dest.RelativeAddress?.Type == _manager.CpuType.ToMemoryType()) {
|
||||
ScrollToAddress((uint)dest.RelativeAddress.Value.Address);
|
||||
} else if(dest.RelativeAddress != null) {
|
||||
DebugWindowManager.OpenDebugger(dest.RelativeAddress.Value.Type.ToCpuType())?.GoToAddress(dest.RelativeAddress.Value.Address);
|
||||
bringToFront = false;
|
||||
} else if(dest.SourceLocation != null) {
|
||||
ScrollToSourceLocation(dest.SourceLocation);
|
||||
} else if(dest.File != null) {
|
||||
SelectFile(dest.File);
|
||||
}
|
||||
|
||||
if(bringToFront) {
|
||||
Form parent = this.ParentForm;
|
||||
if(parent.WindowState == FormWindowState.Minimized) {
|
||||
//Unminimize window if it was minimized
|
||||
parent.WindowState = FormWindowState.Normal;
|
||||
}
|
||||
parent.BringToFront();
|
||||
}
|
||||
}
|
||||
|
||||
public bool SelectFile(SourceFileInfo file)
|
||||
{
|
||||
if(!_inSourceView) {
|
||||
ToggleView();
|
||||
}
|
||||
|
||||
foreach(SourceFileInfo fileInfo in cboSourceFile.Items) {
|
||||
if(fileInfo == file) {
|
||||
cboSourceFile.SelectedItem = fileInfo;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void ScrollToSourceLocation(SourceCodeLocation location)
|
||||
{
|
||||
if(SelectFile(location.File)) {
|
||||
ctrlCode.ScrollToLineIndex(location.LineNumber);
|
||||
}
|
||||
}
|
||||
|
||||
public void ScrollToSymbol(SourceSymbol symbol)
|
||||
{
|
||||
SourceCodeLocation definition = _symbolProvider?.GetSymbolDefinition(symbol);
|
||||
if(definition != null) {
|
||||
foreach(SourceFileInfo fileInfo in cboSourceFile.Items) {
|
||||
if(fileInfo == definition.File) {
|
||||
cboSourceFile.SelectedItem = fileInfo;
|
||||
ctrlCode.ScrollToLineIndex(definition.LineNumber);
|
||||
return;
|
||||
}
|
||||
}
|
||||
ScrollToSourceLocation(definition);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
246
UI/Debugger/Controls/ctrlSearchResult.Designer.cs
generated
Normal file
246
UI/Debugger/Controls/ctrlSearchResult.Designer.cs
generated
Normal file
|
@ -0,0 +1,246 @@
|
|||
namespace Mesen.GUI.Debugger.Controls
|
||||
{
|
||||
partial class ctrlSearchResult
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if(disposing && (components != null)) {
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Component Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.tableLayoutPanel4 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.lblCpu = new System.Windows.Forms.Label();
|
||||
this.lblRelativeAddress = new System.Windows.Forms.Label();
|
||||
this.lblLocation = new System.Windows.Forms.Label();
|
||||
this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.lblAbsoluteAddress = new System.Windows.Forms.Label();
|
||||
this.lblMemoryType = new System.Windows.Forms.Label();
|
||||
this.tableLayoutPanel3 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.picWarning = new System.Windows.Forms.PictureBox();
|
||||
this.lblLabelName = new System.Windows.Forms.Label();
|
||||
this.picType = new System.Windows.Forms.PictureBox();
|
||||
this.tableLayoutPanel1.SuspendLayout();
|
||||
this.tableLayoutPanel4.SuspendLayout();
|
||||
this.tableLayoutPanel2.SuspendLayout();
|
||||
this.tableLayoutPanel3.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.picWarning)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.picType)).BeginInit();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// tableLayoutPanel1
|
||||
//
|
||||
this.tableLayoutPanel1.ColumnCount = 2;
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 160F));
|
||||
this.tableLayoutPanel1.Controls.Add(this.tableLayoutPanel4, 1, 1);
|
||||
this.tableLayoutPanel1.Controls.Add(this.lblLocation, 0, 1);
|
||||
this.tableLayoutPanel1.Controls.Add(this.tableLayoutPanel2, 1, 0);
|
||||
this.tableLayoutPanel1.Controls.Add(this.tableLayoutPanel3, 0, 0);
|
||||
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
|
||||
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||
this.tableLayoutPanel1.RowCount = 3;
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 17F));
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 17F));
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel1.Size = new System.Drawing.Size(274, 36);
|
||||
this.tableLayoutPanel1.TabIndex = 0;
|
||||
//
|
||||
// tableLayoutPanel4
|
||||
//
|
||||
this.tableLayoutPanel4.ColumnCount = 2;
|
||||
this.tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel4.Controls.Add(this.lblCpu, 0, 0);
|
||||
this.tableLayoutPanel4.Controls.Add(this.lblRelativeAddress, 1, 0);
|
||||
this.tableLayoutPanel4.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tableLayoutPanel4.Location = new System.Drawing.Point(114, 17);
|
||||
this.tableLayoutPanel4.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.tableLayoutPanel4.Name = "tableLayoutPanel4";
|
||||
this.tableLayoutPanel4.RowCount = 1;
|
||||
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel4.Size = new System.Drawing.Size(160, 17);
|
||||
this.tableLayoutPanel4.TabIndex = 6;
|
||||
//
|
||||
// lblCpu
|
||||
//
|
||||
this.lblCpu.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.lblCpu.AutoSize = true;
|
||||
this.lblCpu.Font = new System.Drawing.Font("Microsoft Sans Serif", 6.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.lblCpu.ForeColor = System.Drawing.SystemColors.GrayText;
|
||||
this.lblCpu.Location = new System.Drawing.Point(68, 0);
|
||||
this.lblCpu.Name = "lblCpu";
|
||||
this.lblCpu.Padding = new System.Windows.Forms.Padding(0, 3, 0, 0);
|
||||
this.lblCpu.Size = new System.Drawing.Size(25, 15);
|
||||
this.lblCpu.TabIndex = 4;
|
||||
this.lblCpu.Text = "CPU";
|
||||
//
|
||||
// lblRelativeAddress
|
||||
//
|
||||
this.lblRelativeAddress.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.lblRelativeAddress.AutoSize = true;
|
||||
this.lblRelativeAddress.Location = new System.Drawing.Point(99, 2);
|
||||
this.lblRelativeAddress.Name = "lblRelativeAddress";
|
||||
this.lblRelativeAddress.Padding = new System.Windows.Forms.Padding(0, 0, 0, 2);
|
||||
this.lblRelativeAddress.Size = new System.Drawing.Size(58, 15);
|
||||
this.lblRelativeAddress.TabIndex = 2;
|
||||
this.lblRelativeAddress.Text = "$FFFF:$00";
|
||||
//
|
||||
// lblLocation
|
||||
//
|
||||
this.lblLocation.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.lblLocation.AutoSize = true;
|
||||
this.lblLocation.Location = new System.Drawing.Point(3, 19);
|
||||
this.lblLocation.Name = "lblLocation";
|
||||
this.lblLocation.Padding = new System.Windows.Forms.Padding(0, 0, 0, 2);
|
||||
this.lblLocation.Size = new System.Drawing.Size(71, 15);
|
||||
this.lblLocation.TabIndex = 1;
|
||||
this.lblLocation.Text = "Filename.asm";
|
||||
//
|
||||
// tableLayoutPanel2
|
||||
//
|
||||
this.tableLayoutPanel2.ColumnCount = 2;
|
||||
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel2.Controls.Add(this.lblAbsoluteAddress, 1, 0);
|
||||
this.tableLayoutPanel2.Controls.Add(this.lblMemoryType, 0, 0);
|
||||
this.tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tableLayoutPanel2.Location = new System.Drawing.Point(114, 0);
|
||||
this.tableLayoutPanel2.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.tableLayoutPanel2.Name = "tableLayoutPanel2";
|
||||
this.tableLayoutPanel2.RowCount = 1;
|
||||
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel2.Size = new System.Drawing.Size(160, 17);
|
||||
this.tableLayoutPanel2.TabIndex = 4;
|
||||
//
|
||||
// lblAbsoluteAddress
|
||||
//
|
||||
this.lblAbsoluteAddress.Anchor = System.Windows.Forms.AnchorStyles.Right;
|
||||
this.lblAbsoluteAddress.AutoSize = true;
|
||||
this.lblAbsoluteAddress.Location = new System.Drawing.Point(93, 1);
|
||||
this.lblAbsoluteAddress.Name = "lblAbsoluteAddress";
|
||||
this.lblAbsoluteAddress.Padding = new System.Windows.Forms.Padding(0, 2, 0, 0);
|
||||
this.lblAbsoluteAddress.Size = new System.Drawing.Size(64, 15);
|
||||
this.lblAbsoluteAddress.TabIndex = 3;
|
||||
this.lblAbsoluteAddress.Text = "$12345:$55";
|
||||
//
|
||||
// lblMemoryType
|
||||
//
|
||||
this.lblMemoryType.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.lblMemoryType.AutoSize = true;
|
||||
this.lblMemoryType.Font = new System.Drawing.Font("Microsoft Sans Serif", 6.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.lblMemoryType.ForeColor = System.Drawing.SystemColors.GrayText;
|
||||
this.lblMemoryType.Location = new System.Drawing.Point(11, 0);
|
||||
this.lblMemoryType.Name = "lblMemoryType";
|
||||
this.lblMemoryType.Padding = new System.Windows.Forms.Padding(0, 3, 0, 0);
|
||||
this.lblMemoryType.Size = new System.Drawing.Size(76, 15);
|
||||
this.lblMemoryType.TabIndex = 4;
|
||||
this.lblMemoryType.Text = "NES RAM (2 KB)";
|
||||
//
|
||||
// tableLayoutPanel3
|
||||
//
|
||||
this.tableLayoutPanel3.ColumnCount = 3;
|
||||
this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel3.Controls.Add(this.picWarning, 0, 0);
|
||||
this.tableLayoutPanel3.Controls.Add(this.lblLabelName, 2, 0);
|
||||
this.tableLayoutPanel3.Controls.Add(this.picType, 1, 0);
|
||||
this.tableLayoutPanel3.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tableLayoutPanel3.Location = new System.Drawing.Point(0, 0);
|
||||
this.tableLayoutPanel3.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.tableLayoutPanel3.Name = "tableLayoutPanel3";
|
||||
this.tableLayoutPanel3.RowCount = 1;
|
||||
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel3.Size = new System.Drawing.Size(114, 17);
|
||||
this.tableLayoutPanel3.TabIndex = 5;
|
||||
//
|
||||
// picWarning
|
||||
//
|
||||
this.picWarning.Image = global::Mesen.GUI.Properties.Resources.Warning;
|
||||
this.picWarning.Location = new System.Drawing.Point(1, 0);
|
||||
this.picWarning.Margin = new System.Windows.Forms.Padding(1, 0, 0, 0);
|
||||
this.picWarning.Name = "picWarning";
|
||||
this.picWarning.Size = new System.Drawing.Size(16, 16);
|
||||
this.picWarning.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
|
||||
this.picWarning.TabIndex = 2;
|
||||
this.picWarning.TabStop = false;
|
||||
//
|
||||
// lblLabelName
|
||||
//
|
||||
this.lblLabelName.AutoSize = true;
|
||||
this.lblLabelName.Location = new System.Drawing.Point(37, 0);
|
||||
this.lblLabelName.Name = "lblLabelName";
|
||||
this.lblLabelName.Padding = new System.Windows.Forms.Padding(0, 2, 0, 0);
|
||||
this.lblLabelName.Size = new System.Drawing.Size(69, 28);
|
||||
this.lblLabelName.TabIndex = 0;
|
||||
this.lblLabelName.Text = "MyLabelName";
|
||||
//
|
||||
// picType
|
||||
//
|
||||
this.picType.Location = new System.Drawing.Point(18, 0);
|
||||
this.picType.Margin = new System.Windows.Forms.Padding(1, 0, 0, 0);
|
||||
this.picType.Name = "picType";
|
||||
this.picType.Size = new System.Drawing.Size(16, 16);
|
||||
this.picType.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
|
||||
this.picType.TabIndex = 1;
|
||||
this.picType.TabStop = false;
|
||||
//
|
||||
// ctrlSearchResult
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.tableLayoutPanel1);
|
||||
this.Margin = new System.Windows.Forms.Padding(0, 0, 0, 1);
|
||||
this.Name = "ctrlSearchResult";
|
||||
this.Size = new System.Drawing.Size(274, 36);
|
||||
this.tableLayoutPanel1.ResumeLayout(false);
|
||||
this.tableLayoutPanel1.PerformLayout();
|
||||
this.tableLayoutPanel4.ResumeLayout(false);
|
||||
this.tableLayoutPanel4.PerformLayout();
|
||||
this.tableLayoutPanel2.ResumeLayout(false);
|
||||
this.tableLayoutPanel2.PerformLayout();
|
||||
this.tableLayoutPanel3.ResumeLayout(false);
|
||||
this.tableLayoutPanel3.PerformLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.picWarning)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.picType)).EndInit();
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
|
||||
private System.Windows.Forms.Label lblLabelName;
|
||||
private System.Windows.Forms.Label lblLocation;
|
||||
private System.Windows.Forms.Label lblRelativeAddress;
|
||||
private System.Windows.Forms.Label lblAbsoluteAddress;
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2;
|
||||
private System.Windows.Forms.Label lblMemoryType;
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel3;
|
||||
private System.Windows.Forms.PictureBox picType;
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel4;
|
||||
private System.Windows.Forms.Label lblCpu;
|
||||
private System.Windows.Forms.PictureBox picWarning;
|
||||
}
|
||||
}
|
146
UI/Debugger/Controls/ctrlSearchResult.cs
Normal file
146
UI/Debugger/Controls/ctrlSearchResult.cs
Normal file
|
@ -0,0 +1,146 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using Mesen.GUI.Controls;
|
||||
using Mesen.GUI.Forms;
|
||||
using System.IO;
|
||||
using Mesen.GUI.Debugger.Labels;
|
||||
using Mesen.GUI.Debugger.Integration;
|
||||
|
||||
namespace Mesen.GUI.Debugger.Controls
|
||||
{
|
||||
public partial class ctrlSearchResult : BaseControl
|
||||
{
|
||||
public new event EventHandler Click;
|
||||
public new event EventHandler DoubleClick;
|
||||
|
||||
public ctrlSearchResult()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.TabStop = false;
|
||||
this.AddClickHandler(this);
|
||||
}
|
||||
|
||||
protected override bool ProcessTabKey(bool forward)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
private void ChildClickHandler(object sender, EventArgs e)
|
||||
{
|
||||
Click?.Invoke(this, e);
|
||||
}
|
||||
|
||||
private void CtrlDoubleClickHandler(object sender, EventArgs e)
|
||||
{
|
||||
DoubleClick?.Invoke(this, e);
|
||||
}
|
||||
|
||||
private void AddClickHandler(Control parent)
|
||||
{
|
||||
foreach(Control ctrl in parent.Controls) {
|
||||
ctrl.Click += ChildClickHandler;
|
||||
ctrl.DoubleClick += CtrlDoubleClickHandler;
|
||||
AddClickHandler(ctrl);
|
||||
}
|
||||
}
|
||||
|
||||
public void Initialize(SearchResultInfo info)
|
||||
{
|
||||
lblLabelName.Text = info.Caption;
|
||||
if(info.Length > 1) {
|
||||
if(info.Length == 2) {
|
||||
lblLabelName.Text += " (word)";
|
||||
} else {
|
||||
lblLabelName.Text += $" ({info.Length} bytes)";
|
||||
}
|
||||
}
|
||||
if(info.AbsoluteAddress?.Address >= 0) {
|
||||
lblAbsoluteAddress.Text = "$" + info.AbsoluteAddress?.Address.ToString("X4") + ":$" + info.Value.ToString("X2");
|
||||
if(info.RelativeAddress?.Address >= 0) {
|
||||
lblRelativeAddress.ForeColor = SystemColors.ControlText;
|
||||
lblRelativeAddress.Text = "$" + info.RelativeAddress?.Address.ToString("X4") + ":$" + info.Value.ToString("X2");
|
||||
} else {
|
||||
lblRelativeAddress.ForeColor = SystemColors.GrayText;
|
||||
lblRelativeAddress.Text = "<out of scope>";
|
||||
}
|
||||
SnesMemoryType memType = info.AbsoluteAddress?.Type ?? SnesMemoryType.Register;
|
||||
lblMemoryType.Text = ResourceHelper.GetEnumText(memType);
|
||||
lblCpu.Text = "CPU";
|
||||
if(info.SearchResultType == SearchResultType.Function) {
|
||||
picType.Image = Properties.Resources.Function;
|
||||
} else if(info.SearchResultType == SearchResultType.JumpTarget) {
|
||||
picType.Image = Properties.Resources.JumpTarget;
|
||||
} else if(memType == SnesMemoryType.Register) {
|
||||
picType.Image = Properties.Resources.RegisterIcon;
|
||||
} else {
|
||||
picType.Image = Properties.Resources.CheatCode;
|
||||
}
|
||||
} else if(info.SearchResultType == SearchResultType.File) {
|
||||
lblMemoryType.Text = "File";
|
||||
lblCpu.Text = "";
|
||||
lblAbsoluteAddress.Text = "";
|
||||
lblRelativeAddress.Text = "";
|
||||
picType.Image = Properties.Resources.LogWindow;
|
||||
} else if(info.SearchResultType == SearchResultType.Constant) {
|
||||
lblMemoryType.Text = "Constant";
|
||||
lblCpu.Text = "";
|
||||
lblAbsoluteAddress.Text = "";
|
||||
lblRelativeAddress.Text = "Value: $" + info.Value.ToString("X2");
|
||||
picType.Image = Properties.Resources.Enum;
|
||||
} else {
|
||||
lblAbsoluteAddress.Text = "";
|
||||
lblRelativeAddress.Text = "";
|
||||
lblCpu.Text = "";
|
||||
lblMemoryType.Text = "";
|
||||
picType.Image = null;
|
||||
}
|
||||
|
||||
picWarning.Visible = info.Disabled;
|
||||
if(info.Disabled) {
|
||||
this.Enabled = false;
|
||||
} else {
|
||||
this.Enabled = true;
|
||||
}
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(info.File?.Name)) {
|
||||
if(info.SearchResultType == SearchResultType.File) {
|
||||
lblLocation.Text = Path.GetFileName(info.File?.Name);
|
||||
} else {
|
||||
lblLocation.Text = Path.GetFileName(info.File?.Name) + ":" + (info.SourceLocation?.LineNumber + 1).ToString();
|
||||
}
|
||||
} else {
|
||||
lblLocation.Text = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum SearchResultType
|
||||
{
|
||||
Function,
|
||||
JumpTarget,
|
||||
Constant,
|
||||
Data,
|
||||
File
|
||||
}
|
||||
|
||||
public class SearchResultInfo
|
||||
{
|
||||
public string Caption;
|
||||
public AddressInfo? AbsoluteAddress;
|
||||
public AddressInfo? RelativeAddress;
|
||||
public int Value;
|
||||
public int Length;
|
||||
public SourceFileInfo File;
|
||||
public SourceCodeLocation SourceLocation;
|
||||
public SearchResultType SearchResultType;
|
||||
public CodeLabel CodeLabel;
|
||||
public bool Disabled;
|
||||
}
|
||||
}
|
|
@ -220,9 +220,9 @@ namespace Mesen.GUI.Debugger.Integration
|
|||
return null;
|
||||
}
|
||||
|
||||
private List<SymbolInfo> GetSymbols()
|
||||
public List<SourceSymbol> GetSymbols()
|
||||
{
|
||||
return _symbols.Values.ToList();
|
||||
return _symbols.Values.Select(s => s.SourceSymbol).ToList();
|
||||
}
|
||||
|
||||
public SourceSymbol GetSymbol(string word, int prgStartAddress, int prgEndAddress)
|
||||
|
@ -488,6 +488,11 @@ namespace Mesen.GUI.Debugger.Integration
|
|||
return false;
|
||||
}
|
||||
|
||||
public int GetSymbolSize(SourceSymbol srcSymbol)
|
||||
{
|
||||
return GetSymbolSize(srcSymbol.InternalSymbol as SymbolInfo);
|
||||
}
|
||||
|
||||
private int GetSymbolSize(SymbolInfo symbol)
|
||||
{
|
||||
if(symbol.SegmentID != null && _segments.ContainsKey(symbol.SegmentID.Value)) {
|
||||
|
|
|
@ -17,6 +17,8 @@ namespace Mesen.GUI.Debugger.Integration
|
|||
AddressInfo? GetSymbolAddressInfo(SourceSymbol symbol);
|
||||
SourceCodeLocation GetSymbolDefinition(SourceSymbol symbol);
|
||||
SourceSymbol GetSymbol(string word, int prgStartAddress, int prgEndAddress);
|
||||
List<SourceSymbol> GetSymbols();
|
||||
int GetSymbolSize(SourceSymbol srcSymbol);
|
||||
//List<DbgImporter.ReferenceInfo> GetSymbolReferences(SourceSymbol symbol);
|
||||
//int GetSymbolSize(SourceSymbol symbol);
|
||||
}
|
||||
|
|
14
UI/Debugger/MemoryTools/frmMemoryTools.Designer.cs
generated
14
UI/Debugger/MemoryTools/frmMemoryTools.Designer.cs
generated
|
@ -643,29 +643,29 @@
|
|||
//
|
||||
// mnuGoToAll
|
||||
//
|
||||
this.mnuGoToAll.Image = global::Mesen.GUI.Properties.Resources.Find;
|
||||
this.mnuGoToAll.Name = "mnuGoToAll";
|
||||
this.mnuGoToAll.Size = new System.Drawing.Size(145, 22);
|
||||
this.mnuGoToAll.Size = new System.Drawing.Size(180, 22);
|
||||
this.mnuGoToAll.Text = "Go to All";
|
||||
this.mnuGoToAll.Visible = false;
|
||||
this.mnuGoToAll.Click += new System.EventHandler(this.mnuGoToAll_Click);
|
||||
//
|
||||
// mnuGoTo
|
||||
//
|
||||
this.mnuGoTo.Name = "mnuGoTo";
|
||||
this.mnuGoTo.Size = new System.Drawing.Size(145, 22);
|
||||
this.mnuGoTo.Size = new System.Drawing.Size(180, 22);
|
||||
this.mnuGoTo.Text = "Go To...";
|
||||
this.mnuGoTo.Click += new System.EventHandler(this.mnuGoTo_Click);
|
||||
//
|
||||
// toolStripMenuItem14
|
||||
//
|
||||
this.toolStripMenuItem14.Name = "toolStripMenuItem14";
|
||||
this.toolStripMenuItem14.Size = new System.Drawing.Size(142, 6);
|
||||
this.toolStripMenuItem14.Size = new System.Drawing.Size(177, 6);
|
||||
//
|
||||
// mnuFind
|
||||
//
|
||||
this.mnuFind.Image = global::Mesen.GUI.Properties.Resources.Find;
|
||||
this.mnuFind.Name = "mnuFind";
|
||||
this.mnuFind.Size = new System.Drawing.Size(145, 22);
|
||||
this.mnuFind.Size = new System.Drawing.Size(180, 22);
|
||||
this.mnuFind.Text = "Find...";
|
||||
this.mnuFind.Click += new System.EventHandler(this.mnuFind_Click);
|
||||
//
|
||||
|
@ -673,7 +673,7 @@
|
|||
//
|
||||
this.mnuFindNext.Image = global::Mesen.GUI.Properties.Resources.NextArrow;
|
||||
this.mnuFindNext.Name = "mnuFindNext";
|
||||
this.mnuFindNext.Size = new System.Drawing.Size(145, 22);
|
||||
this.mnuFindNext.Size = new System.Drawing.Size(180, 22);
|
||||
this.mnuFindNext.Text = "Find Next";
|
||||
this.mnuFindNext.Click += new System.EventHandler(this.mnuFindNext_Click);
|
||||
//
|
||||
|
@ -681,7 +681,7 @@
|
|||
//
|
||||
this.mnuFindPrev.Image = global::Mesen.GUI.Properties.Resources.PreviousArrow;
|
||||
this.mnuFindPrev.Name = "mnuFindPrev";
|
||||
this.mnuFindPrev.Size = new System.Drawing.Size(145, 22);
|
||||
this.mnuFindPrev.Size = new System.Drawing.Size(180, 22);
|
||||
this.mnuFindPrev.Text = "Find Previous";
|
||||
this.mnuFindPrev.Click += new System.EventHandler(this.mnuFindPrev_Click);
|
||||
//
|
||||
|
|
|
@ -200,32 +200,40 @@ namespace Mesen.GUI.Debugger
|
|||
*/
|
||||
}
|
||||
|
||||
public void ShowAddress(AddressInfo address)
|
||||
{
|
||||
ShowAddress(address.Address, address.Type);
|
||||
}
|
||||
|
||||
public void ShowAddress(int address, SnesMemoryType memoryType)
|
||||
{
|
||||
cboMemoryType.SetEnumValue(memoryType);
|
||||
ctrlHexViewer.GoToAddress(address);
|
||||
}
|
||||
|
||||
//TODO
|
||||
/*
|
||||
public void GoToDestination(GoToDestination dest)
|
||||
{
|
||||
if(_memoryType == DebugMemoryType.CpuMemory && dest.CpuAddress >= 0) {
|
||||
this.ShowAddress(dest.CpuAddress, DebugMemoryType.CpuMemory);
|
||||
} else if(dest.AddressInfo != null) {
|
||||
this.ShowAddress(dest.AddressInfo.Address, dest.AddressInfo.Type.ToMemoryType());
|
||||
if(dest.RelativeAddress?.Type == _memoryType) {
|
||||
ShowAddress(dest.RelativeAddress.Value);
|
||||
} else if(dest.AbsoluteAddress?.Type == _memoryType) {
|
||||
ShowAddress(dest.AbsoluteAddress.Value);
|
||||
} else if(dest.RelativeAddress != null) {
|
||||
ShowAddress(dest.RelativeAddress.Value);
|
||||
} else if(dest.AbsoluteAddress != null) {
|
||||
ShowAddress(dest.AbsoluteAddress.Value);
|
||||
} else if(dest.Label != null) {
|
||||
int relAddress = dest.Label.GetRelativeAddress();
|
||||
if(_memoryType == DebugMemoryType.CpuMemory && relAddress >= 0) {
|
||||
this.ShowAddress(relAddress, DebugMemoryType.CpuMemory);
|
||||
AddressInfo relAddress = dest.Label.GetRelativeAddress();
|
||||
if(relAddress.Type == _memoryType && relAddress.Address >= 0) {
|
||||
ShowAddress(relAddress);
|
||||
} else {
|
||||
this.ShowAddress((int)dest.Label.Address, dest.Label.AddressType.ToMemoryType());
|
||||
AddressInfo absAddress = dest.Label.GetAbsoluteAddress();
|
||||
ShowAddress(absAddress);
|
||||
}
|
||||
} else if(dest.CpuAddress >= 0) {
|
||||
this.ShowAddress(dest.CpuAddress, DebugMemoryType.CpuMemory);
|
||||
} else if(dest.RelativeAddress != null) {
|
||||
ShowAddress(dest.RelativeAddress.Value);
|
||||
}
|
||||
|
||||
this.BringToFront();
|
||||
BringToFront();
|
||||
}
|
||||
|
||||
public void GoToAll()
|
||||
|
@ -235,7 +243,7 @@ namespace Mesen.GUI.Debugger
|
|||
GoToDestination(frm.Destination);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
private void InitTblMappings()
|
||||
{
|
||||
|
@ -359,8 +367,7 @@ namespace Mesen.GUI.Debugger
|
|||
|
||||
private void mnuGoToAll_Click(object sender, EventArgs e)
|
||||
{
|
||||
//TODO
|
||||
//this.GoToAll();
|
||||
this.GoToAll();
|
||||
}
|
||||
|
||||
private void mnuIncreaseFontSize_Click(object sender, EventArgs e)
|
||||
|
|
|
@ -39,7 +39,7 @@ namespace Mesen.GUI.Debugger
|
|||
GetMember(nameof(DebuggerShortcutsConfig.MarkAsCode)),
|
||||
GetMember(nameof(DebuggerShortcutsConfig.MarkAsData)),
|
||||
GetMember(nameof(DebuggerShortcutsConfig.MarkAsUnidentified)),
|
||||
//GetMember(nameof(DebuggerShortcutsConfig.GoToAll)),
|
||||
GetMember(nameof(DebuggerShortcutsConfig.GoToAll)),
|
||||
GetMember(nameof(DebuggerShortcutsConfig.CodeWindow_EditInMemoryViewer)),
|
||||
GetMember(nameof(DebuggerShortcutsConfig.MemoryViewer_ViewInDisassembly)),
|
||||
|
||||
|
|
31
UI/Debugger/frmDebugger.Designer.cs
generated
31
UI/Debugger/frmDebugger.Designer.cs
generated
|
@ -63,6 +63,8 @@
|
|||
this.mnuBreakIn = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuBreakOn = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.searchToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuGoToAll = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripMenuItem11 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.mnuFind = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuFindNext = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuFindPrev = new System.Windows.Forms.ToolStripMenuItem();
|
||||
|
@ -389,6 +391,8 @@
|
|||
// searchToolStripMenuItem
|
||||
//
|
||||
this.searchToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.mnuGoToAll,
|
||||
this.toolStripMenuItem11,
|
||||
this.mnuFind,
|
||||
this.mnuFindNext,
|
||||
this.mnuFindPrev,
|
||||
|
@ -399,6 +403,19 @@
|
|||
this.searchToolStripMenuItem.Size = new System.Drawing.Size(54, 20);
|
||||
this.searchToolStripMenuItem.Text = "Search";
|
||||
//
|
||||
// mnuGoToAll
|
||||
//
|
||||
this.mnuGoToAll.Image = global::Mesen.GUI.Properties.Resources.Find;
|
||||
this.mnuGoToAll.Name = "mnuGoToAll";
|
||||
this.mnuGoToAll.Size = new System.Drawing.Size(183, 22);
|
||||
this.mnuGoToAll.Text = "Go to All";
|
||||
this.mnuGoToAll.Click += new System.EventHandler(this.mnuGoToAll_Click);
|
||||
//
|
||||
// toolStripMenuItem11
|
||||
//
|
||||
this.toolStripMenuItem11.Name = "toolStripMenuItem11";
|
||||
this.toolStripMenuItem11.Size = new System.Drawing.Size(180, 6);
|
||||
//
|
||||
// mnuFind
|
||||
//
|
||||
this.mnuFind.Image = global::Mesen.GUI.Properties.Resources.Find;
|
||||
|
@ -543,19 +560,19 @@
|
|||
// mnuHideUnident
|
||||
//
|
||||
this.mnuHideUnident.Name = "mnuHideUnident";
|
||||
this.mnuHideUnident.Size = new System.Drawing.Size(180, 22);
|
||||
this.mnuHideUnident.Size = new System.Drawing.Size(170, 22);
|
||||
this.mnuHideUnident.Text = "Hide";
|
||||
//
|
||||
// mnuDisassembleUnident
|
||||
//
|
||||
this.mnuDisassembleUnident.Name = "mnuDisassembleUnident";
|
||||
this.mnuDisassembleUnident.Size = new System.Drawing.Size(180, 22);
|
||||
this.mnuDisassembleUnident.Size = new System.Drawing.Size(170, 22);
|
||||
this.mnuDisassembleUnident.Text = "Show disassembly";
|
||||
//
|
||||
// mnuShowUnident
|
||||
//
|
||||
this.mnuShowUnident.Name = "mnuShowUnident";
|
||||
this.mnuShowUnident.Size = new System.Drawing.Size(180, 22);
|
||||
this.mnuShowUnident.Size = new System.Drawing.Size(170, 22);
|
||||
this.mnuShowUnident.Text = "Show as data";
|
||||
//
|
||||
// mnuVerifiedData
|
||||
|
@ -573,19 +590,19 @@
|
|||
// mnuHideData
|
||||
//
|
||||
this.mnuHideData.Name = "mnuHideData";
|
||||
this.mnuHideData.Size = new System.Drawing.Size(180, 22);
|
||||
this.mnuHideData.Size = new System.Drawing.Size(170, 22);
|
||||
this.mnuHideData.Text = "Hide";
|
||||
//
|
||||
// mnuDisassembleData
|
||||
//
|
||||
this.mnuDisassembleData.Name = "mnuDisassembleData";
|
||||
this.mnuDisassembleData.Size = new System.Drawing.Size(180, 22);
|
||||
this.mnuDisassembleData.Size = new System.Drawing.Size(170, 22);
|
||||
this.mnuDisassembleData.Text = "Show disassembly";
|
||||
//
|
||||
// mnuShowData
|
||||
//
|
||||
this.mnuShowData.Name = "mnuShowData";
|
||||
this.mnuShowData.Size = new System.Drawing.Size(180, 22);
|
||||
this.mnuShowData.Size = new System.Drawing.Size(170, 22);
|
||||
this.mnuShowData.Text = "Show as data";
|
||||
//
|
||||
// toolStripMenuItem6
|
||||
|
@ -1077,5 +1094,7 @@
|
|||
private Controls.ctrlGsuStatus ctrlGsuStatus;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuUseAltSpcOpNames;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuUseLowerCaseDisassembly;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuGoToAll;
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem11;
|
||||
}
|
||||
}
|
|
@ -167,6 +167,7 @@ namespace Mesen.GUI.Debugger
|
|||
mnuReset.InitShortcut(this, nameof(DebuggerShortcutsConfig.Reset));
|
||||
mnuPowerCycle.InitShortcut(this, nameof(DebuggerShortcutsConfig.PowerCycle));
|
||||
|
||||
mnuGoToAll.InitShortcut(this, nameof(DebuggerShortcutsConfig.GoToAll));
|
||||
mnuGoToAddress.InitShortcut(this, nameof(DebuggerShortcutsConfig.GoTo));
|
||||
mnuGoToProgramCounter.InitShortcut(this, nameof(DebuggerShortcutsConfig.GoToProgramCounter));
|
||||
|
||||
|
@ -558,6 +559,20 @@ namespace Mesen.GUI.Debugger
|
|||
DebugApi.SetCdlData(emptyCdlLog, emptyCdlLog.Length);
|
||||
RefreshDisassembly();
|
||||
}
|
||||
|
||||
private void mnuGoToAll_Click(object sender, EventArgs e)
|
||||
{
|
||||
using(frmGoToAll frm = new frmGoToAll(false, true)) {
|
||||
if(frm.ShowDialog() == DialogResult.OK) {
|
||||
GoToDestination(frm.Destination);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void GoToDestination(GoToDestination dest)
|
||||
{
|
||||
ctrlDisassemblyView.GoToDestination(dest);
|
||||
}
|
||||
}
|
||||
|
||||
public enum CpuVector
|
||||
|
|
152
UI/Debugger/frmGoToAll.Designer.cs
generated
Normal file
152
UI/Debugger/frmGoToAll.Designer.cs
generated
Normal file
|
@ -0,0 +1,152 @@
|
|||
namespace Mesen.GUI.Debugger
|
||||
{
|
||||
partial class frmGoToAll
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if(disposing && (components != null)) {
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.lblSearch = new System.Windows.Forms.Label();
|
||||
this.txtSearch = new System.Windows.Forms.TextBox();
|
||||
this.pnlResults = new System.Windows.Forms.Panel();
|
||||
this.tlpResults = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.statusStrip1 = new System.Windows.Forms.StatusStrip();
|
||||
this.lblResultCount = new System.Windows.Forms.ToolStripStatusLabel();
|
||||
this.tableLayoutPanel1.SuspendLayout();
|
||||
this.pnlResults.SuspendLayout();
|
||||
this.statusStrip1.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// tableLayoutPanel1
|
||||
//
|
||||
this.tableLayoutPanel1.ColumnCount = 2;
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel1.Controls.Add(this.lblSearch, 0, 0);
|
||||
this.tableLayoutPanel1.Controls.Add(this.txtSearch, 1, 0);
|
||||
this.tableLayoutPanel1.Controls.Add(this.pnlResults, 0, 1);
|
||||
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
|
||||
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||
this.tableLayoutPanel1.RowCount = 2;
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
|
||||
this.tableLayoutPanel1.Size = new System.Drawing.Size(386, 417);
|
||||
this.tableLayoutPanel1.TabIndex = 0;
|
||||
//
|
||||
// lblSearch
|
||||
//
|
||||
this.lblSearch.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.lblSearch.AutoSize = true;
|
||||
this.lblSearch.Location = new System.Drawing.Point(3, 6);
|
||||
this.lblSearch.Name = "lblSearch";
|
||||
this.lblSearch.Size = new System.Drawing.Size(44, 13);
|
||||
this.lblSearch.TabIndex = 0;
|
||||
this.lblSearch.Text = "Search:";
|
||||
//
|
||||
// txtSearch
|
||||
//
|
||||
this.txtSearch.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.txtSearch.Location = new System.Drawing.Point(53, 3);
|
||||
this.txtSearch.Name = "txtSearch";
|
||||
this.txtSearch.Size = new System.Drawing.Size(330, 20);
|
||||
this.txtSearch.TabIndex = 1;
|
||||
this.txtSearch.TextChanged += new System.EventHandler(this.txtSearch_TextChanged);
|
||||
//
|
||||
// pnlResults
|
||||
//
|
||||
this.pnlResults.AutoScroll = true;
|
||||
this.pnlResults.BackColor = System.Drawing.SystemColors.ControlDarkDark;
|
||||
this.pnlResults.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||
this.tableLayoutPanel1.SetColumnSpan(this.pnlResults, 2);
|
||||
this.pnlResults.Controls.Add(this.tlpResults);
|
||||
this.pnlResults.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.pnlResults.Location = new System.Drawing.Point(3, 29);
|
||||
this.pnlResults.Name = "pnlResults";
|
||||
this.pnlResults.Size = new System.Drawing.Size(380, 385);
|
||||
this.pnlResults.TabIndex = 2;
|
||||
//
|
||||
// tlpResults
|
||||
//
|
||||
this.tlpResults.BackColor = System.Drawing.Color.Transparent;
|
||||
this.tlpResults.ColumnCount = 1;
|
||||
this.tlpResults.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tlpResults.Location = new System.Drawing.Point(0, 0);
|
||||
this.tlpResults.Name = "tlpResults";
|
||||
this.tlpResults.RowCount = 1;
|
||||
this.tlpResults.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tlpResults.Size = new System.Drawing.Size(361, 457);
|
||||
this.tlpResults.TabIndex = 0;
|
||||
//
|
||||
// statusStrip1
|
||||
//
|
||||
this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.lblResultCount});
|
||||
this.statusStrip1.Location = new System.Drawing.Point(0, 417);
|
||||
this.statusStrip1.Name = "statusStrip1";
|
||||
this.statusStrip1.Size = new System.Drawing.Size(386, 22);
|
||||
this.statusStrip1.SizingGrip = false;
|
||||
this.statusStrip1.TabIndex = 1;
|
||||
this.statusStrip1.Text = "statusStrip1";
|
||||
//
|
||||
// lblResultCount
|
||||
//
|
||||
this.lblResultCount.Name = "lblResultCount";
|
||||
this.lblResultCount.Size = new System.Drawing.Size(54, 17);
|
||||
this.lblResultCount.Text = "xx results";
|
||||
//
|
||||
// frmGoToAll
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(386, 439);
|
||||
this.Controls.Add(this.tableLayoutPanel1);
|
||||
this.Controls.Add(this.statusStrip1);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
|
||||
this.Name = "frmGoToAll";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||
this.Text = "Go to All";
|
||||
this.tableLayoutPanel1.ResumeLayout(false);
|
||||
this.tableLayoutPanel1.PerformLayout();
|
||||
this.pnlResults.ResumeLayout(false);
|
||||
this.statusStrip1.ResumeLayout(false);
|
||||
this.statusStrip1.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
|
||||
private System.Windows.Forms.Label lblSearch;
|
||||
private System.Windows.Forms.TextBox txtSearch;
|
||||
private System.Windows.Forms.Panel pnlResults;
|
||||
private System.Windows.Forms.TableLayoutPanel tlpResults;
|
||||
private System.Windows.Forms.StatusStrip statusStrip1;
|
||||
private System.Windows.Forms.ToolStripStatusLabel lblResultCount;
|
||||
}
|
||||
}
|
354
UI/Debugger/frmGoToAll.cs
Normal file
354
UI/Debugger/frmGoToAll.cs
Normal file
|
@ -0,0 +1,354 @@
|
|||
using Mesen.GUI.Debugger.Controls;
|
||||
using Mesen.GUI.Debugger.Integration;
|
||||
using Mesen.GUI.Debugger.Labels;
|
||||
using Mesen.GUI.Debugger.Workspace;
|
||||
using Mesen.GUI.Forms;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Mesen.GUI.Debugger
|
||||
{
|
||||
public partial class frmGoToAll : BaseForm
|
||||
{
|
||||
private const int MaxResultCount = 30;
|
||||
|
||||
private List<ctrlSearchResult> _results = new List<ctrlSearchResult>();
|
||||
private int _selectedResult = 0;
|
||||
private int _resultCount = 0;
|
||||
private ISymbolProvider _symbolProvider;
|
||||
private bool _allowOutOfScope;
|
||||
private bool _showFilesAndConstants;
|
||||
|
||||
public GoToDestination Destination { get; private set; }
|
||||
|
||||
public frmGoToAll(bool allowOutOfScope, bool showFilesAndConstants)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
Icon = Properties.Resources.Find;
|
||||
_symbolProvider = DebugWorkspaceManager.GetSymbolProvider();
|
||||
_allowOutOfScope = allowOutOfScope;
|
||||
_showFilesAndConstants = showFilesAndConstants;
|
||||
|
||||
tlpResults.SuspendLayout();
|
||||
for(int i = 0; i < MaxResultCount; i++) {
|
||||
ctrlSearchResult searchResult = new ctrlSearchResult();
|
||||
searchResult.Dock = DockStyle.Top;
|
||||
searchResult.BackColor = i % 2 == 0 ? SystemColors.ControlLight : SystemColors.ControlLightLight;
|
||||
searchResult.Visible = false;
|
||||
searchResult.Click += SearchResult_Click;
|
||||
searchResult.DoubleClick += SearchResult_DoubleClick;
|
||||
tlpResults.Controls.Add(searchResult, 0, i);
|
||||
tlpResults.RowStyles.Add(new RowStyle(SizeType.AutoSize));
|
||||
|
||||
_results.Add(searchResult);
|
||||
}
|
||||
tlpResults.ResumeLayout();
|
||||
|
||||
UpdateResults();
|
||||
}
|
||||
|
||||
private void SearchResult_Click(object sender, EventArgs e)
|
||||
{
|
||||
SelectedResult = _results.IndexOf(sender as ctrlSearchResult);
|
||||
}
|
||||
|
||||
private void SearchResult_DoubleClick(object sender, EventArgs e)
|
||||
{
|
||||
SelectedResult = _results.IndexOf(sender as ctrlSearchResult);
|
||||
SelectAndClose();
|
||||
}
|
||||
|
||||
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
|
||||
{
|
||||
if(keyData == Keys.Up) {
|
||||
SelectedResult--;
|
||||
return true;
|
||||
} else if(keyData == Keys.Down) {
|
||||
SelectedResult++;
|
||||
return true;
|
||||
} else if(keyData == Keys.PageUp) {
|
||||
SelectedResult -= pnlResults.ClientSize.Height / _results[0].Height;
|
||||
return true;
|
||||
} else if(keyData == Keys.PageDown) {
|
||||
SelectedResult += pnlResults.ClientSize.Height / _results[0].Height;
|
||||
return true;
|
||||
} else if(keyData == Keys.Enter) {
|
||||
SelectAndClose();
|
||||
} else if(keyData == Keys.Escape) {
|
||||
Close();
|
||||
}
|
||||
|
||||
return base.ProcessCmdKey(ref msg, keyData);
|
||||
}
|
||||
|
||||
private int SelectedResult
|
||||
{
|
||||
get { return _selectedResult; }
|
||||
set
|
||||
{
|
||||
//Reset currently highlighted element's color
|
||||
_results[_selectedResult].BackColor = _selectedResult % 2 == 0 ? SystemColors.ControlLight : SystemColors.ControlLightLight;
|
||||
|
||||
_selectedResult = Math.Max(0, Math.Min(_resultCount - 1, value));
|
||||
if(_resultCount == 0) {
|
||||
_results[0].BackColor = SystemColors.ControlLight;
|
||||
} else {
|
||||
_results[_selectedResult].BackColor = Color.LightBlue;
|
||||
}
|
||||
|
||||
if(_resultCount > 0) {
|
||||
if(Program.IsMono) {
|
||||
//Use this logic to replace ScrollControlIntoView (which doesn't work properly on Mono)
|
||||
int startPos = (_results[0].Height + 1) * _selectedResult;
|
||||
int endPos = startPos + _results[0].Height + 1;
|
||||
|
||||
int minVisiblePos = pnlResults.VerticalScroll.Value;
|
||||
int maxVisiblePos = pnlResults.Height + pnlResults.VerticalScroll.Value;
|
||||
|
||||
if(startPos < minVisiblePos) {
|
||||
pnlResults.VerticalScroll.Value = startPos;
|
||||
} else if(endPos > maxVisiblePos) {
|
||||
pnlResults.VerticalScroll.Value = endPos - pnlResults.Height;
|
||||
}
|
||||
} else {
|
||||
pnlResults.ScrollControlIntoView(_results[_selectedResult]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool Contains(string label, List<string> searchStrings)
|
||||
{
|
||||
label = label.ToLower();
|
||||
if(searchStrings.Count == 1) {
|
||||
return label.Contains(searchStrings[0]);
|
||||
} else {
|
||||
for(int i = 1; i < searchStrings.Count; i++) {
|
||||
if(!label.Contains(searchStrings[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateResults()
|
||||
{
|
||||
string searchString = txtSearch.Text.Trim();
|
||||
|
||||
List<string> searchStrings = new List<string>();
|
||||
searchStrings.Add(searchString.ToLower());
|
||||
searchStrings.AddRange(searchString.ToLower().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries));
|
||||
for(int i = 0; i < searchString.Length; i++) {
|
||||
char ch = searchString[i];
|
||||
if(ch >= 'A' && ch <= 'Z') {
|
||||
searchString = searchString.Remove(i, 1).Insert(i, " " + (char)(ch + 'a' - 'A'));
|
||||
}
|
||||
}
|
||||
searchStrings.AddRange(searchString.ToLower().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries));
|
||||
searchStrings = searchStrings.Distinct().ToList();
|
||||
|
||||
_resultCount = 0;
|
||||
|
||||
int size = DebugApi.GetMemorySize(SnesMemoryType.PrgRom);
|
||||
byte[] cdlData = DebugApi.GetCdlData(0, (uint)size, SnesMemoryType.PrgRom);
|
||||
|
||||
List<SearchResultInfo> searchResults = new List<SearchResultInfo>();
|
||||
bool isEmptySearch = string.IsNullOrWhiteSpace(searchString);
|
||||
if(!isEmptySearch) {
|
||||
if(_symbolProvider != null) {
|
||||
if(_showFilesAndConstants) {
|
||||
foreach(SourceFileInfo file in _symbolProvider.SourceFiles) {
|
||||
if(Contains(file.Name, searchStrings)) {
|
||||
searchResults.Add(new SearchResultInfo() {
|
||||
Caption = Path.GetFileName(file.Name),
|
||||
AbsoluteAddress = null,
|
||||
SearchResultType = SearchResultType.File,
|
||||
File = file,
|
||||
SourceLocation = null,
|
||||
RelativeAddress = null,
|
||||
CodeLabel = null
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach(SourceSymbol symbol in _symbolProvider.GetSymbols()) {
|
||||
if(Contains(symbol.Name, searchStrings)) {
|
||||
SourceCodeLocation def = _symbolProvider.GetSymbolDefinition(symbol);
|
||||
AddressInfo? addressInfo = _symbolProvider.GetSymbolAddressInfo(symbol);
|
||||
int value = 0;
|
||||
AddressInfo? relAddress = null;
|
||||
bool isConstant = addressInfo == null;
|
||||
if(!_showFilesAndConstants && isConstant) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(addressInfo != null) {
|
||||
value = DebugApi.GetMemoryValue(addressInfo.Value.Type, (uint)addressInfo.Value.Address);
|
||||
relAddress = DebugApi.GetRelativeAddress(addressInfo.Value);
|
||||
} else {
|
||||
//For constants, the address field contains the constant's value
|
||||
value = symbol.Address ?? 0;
|
||||
}
|
||||
|
||||
SearchResultType resultType = SearchResultType.Data;
|
||||
if(isConstant) {
|
||||
resultType = SearchResultType.Constant;
|
||||
} else if(addressInfo?.Type == SnesMemoryType.PrgRom && addressInfo.Value.Address < cdlData.Length) {
|
||||
if((cdlData[addressInfo.Value.Address] & (byte)CdlFlags.JumpTarget) != 0) {
|
||||
resultType = SearchResultType.JumpTarget;
|
||||
} else if((cdlData[addressInfo.Value.Address] & (byte)CdlFlags.SubEntryPoint) != 0) {
|
||||
resultType = SearchResultType.Function;
|
||||
}
|
||||
}
|
||||
|
||||
searchResults.Add(new SearchResultInfo() {
|
||||
Caption = symbol.Name,
|
||||
AbsoluteAddress = addressInfo,
|
||||
Length = _symbolProvider.GetSymbolSize(symbol),
|
||||
SearchResultType = resultType,
|
||||
Value = value,
|
||||
File = def?.File,
|
||||
SourceLocation = def,
|
||||
RelativeAddress = relAddress,
|
||||
CodeLabel = LabelManager.GetLabel(symbol.Name)
|
||||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
foreach(CodeLabel label in LabelManager.GetLabels(CpuType.Cpu)) { //TODO
|
||||
if(Contains(label.Label, searchStrings)) {
|
||||
SearchResultType resultType = SearchResultType.Data;
|
||||
AddressInfo addressInfo = label.GetAbsoluteAddress();
|
||||
if(addressInfo.Type == SnesMemoryType.PrgRom && addressInfo.Address < cdlData.Length) {
|
||||
if((cdlData[addressInfo.Address] & (byte)CdlFlags.JumpTarget) != 0) {
|
||||
resultType = SearchResultType.JumpTarget;
|
||||
} else if((cdlData[addressInfo.Address] & (byte)CdlFlags.SubEntryPoint) != 0) {
|
||||
resultType = SearchResultType.Function;
|
||||
}
|
||||
}
|
||||
|
||||
AddressInfo relAddress = label.GetRelativeAddress();
|
||||
searchResults.Add(new SearchResultInfo() {
|
||||
Caption = label.Label,
|
||||
AbsoluteAddress = label.GetAbsoluteAddress(),
|
||||
Length = (int)label.Length,
|
||||
Value = label.GetValue(),
|
||||
SearchResultType = resultType,
|
||||
File = null,
|
||||
Disabled = !_allowOutOfScope && relAddress.Address < 0,
|
||||
RelativeAddress = relAddress,
|
||||
CodeLabel = label
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
searchResults.Sort((SearchResultInfo a, SearchResultInfo b) => {
|
||||
int comparison = a.Disabled.CompareTo(b.Disabled);
|
||||
|
||||
if(comparison == 0) {
|
||||
bool aStartsWithSearch = a.Caption.StartsWith(searchString, StringComparison.InvariantCultureIgnoreCase);
|
||||
bool bStartsWithSearch = b.Caption.StartsWith(searchString, StringComparison.InvariantCultureIgnoreCase);
|
||||
|
||||
comparison = bStartsWithSearch.CompareTo(aStartsWithSearch);
|
||||
if(comparison == 0) {
|
||||
comparison = a.Caption.CompareTo(b.Caption);
|
||||
}
|
||||
}
|
||||
return comparison;
|
||||
});
|
||||
|
||||
_resultCount = Math.Min(searchResults.Count, MaxResultCount);
|
||||
SelectedResult = 0;
|
||||
|
||||
lblResultCount.Visible = !isEmptySearch;
|
||||
lblResultCount.Text = searchResults.Count.ToString() + (searchResults.Count == 1 ? " result" : " results");
|
||||
if(searchResults.Count > MaxResultCount) {
|
||||
lblResultCount.Text += " (" + MaxResultCount.ToString() + " shown)";
|
||||
}
|
||||
|
||||
if(searchResults.Count == 0 && !isEmptySearch) {
|
||||
_resultCount++;
|
||||
searchResults.Add(new SearchResultInfo() { Caption = "No results found." });
|
||||
pnlResults.BackColor = SystemColors.ControlLight;
|
||||
} else {
|
||||
pnlResults.BackColor = SystemColors.ControlDarkDark;
|
||||
}
|
||||
|
||||
if(Program.IsMono) {
|
||||
pnlResults.Visible = false;
|
||||
} else {
|
||||
//Suspend layout causes a crash on Mono
|
||||
tlpResults.SuspendLayout();
|
||||
}
|
||||
|
||||
for(int i = 0; i < _resultCount; i++) {
|
||||
_results[i].Initialize(searchResults[i]);
|
||||
_results[i].Tag = searchResults[i];
|
||||
_results[i].Visible = true;
|
||||
}
|
||||
|
||||
for(int i = _resultCount; i < MaxResultCount; i++) {
|
||||
_results[i].Visible = false;
|
||||
}
|
||||
|
||||
pnlResults.VerticalScroll.Value = 0;
|
||||
tlpResults.Height = (_results[0].Height + 1) * _resultCount;
|
||||
|
||||
pnlResults.ResumeLayout();
|
||||
if(Program.IsMono) {
|
||||
pnlResults.Visible = true;
|
||||
tlpResults.Width = pnlResults.ClientSize.Width - 17;
|
||||
} else {
|
||||
tlpResults.ResumeLayout();
|
||||
tlpResults.Width = pnlResults.ClientSize.Width - 1;
|
||||
}
|
||||
}
|
||||
|
||||
private void txtSearch_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
UpdateResults();
|
||||
}
|
||||
|
||||
private void SelectAndClose()
|
||||
{
|
||||
if(_resultCount > 0) {
|
||||
SearchResultInfo searchResult = _results[_selectedResult].Tag as SearchResultInfo;
|
||||
if(!searchResult.Disabled) {
|
||||
Destination = new GoToDestination() {
|
||||
AbsoluteAddress = searchResult.AbsoluteAddress,
|
||||
RelativeAddress = searchResult.RelativeAddress,
|
||||
Label = searchResult.CodeLabel,
|
||||
File = searchResult.File,
|
||||
SourceLocation = searchResult.SourceLocation
|
||||
};
|
||||
DialogResult = DialogResult.OK;
|
||||
Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public delegate void GoToDestinationEventHandler(GoToDestination dest);
|
||||
|
||||
public class GoToDestination
|
||||
{
|
||||
public CodeLabel Label;
|
||||
public AddressInfo? AbsoluteAddress;
|
||||
public AddressInfo? RelativeAddress;
|
||||
public SourceFileInfo File;
|
||||
public SourceCodeLocation SourceLocation;
|
||||
}
|
||||
}
|
12
UI/UI.csproj
12
UI/UI.csproj
|
@ -293,6 +293,12 @@
|
|||
<Compile Include="Debugger\Controls\ctrlGsuStatus.Designer.cs">
|
||||
<DependentUpon>ctrlGsuStatus.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Debugger\Controls\ctrlSearchResult.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Debugger\Controls\ctrlSearchResult.designer.cs">
|
||||
<DependentUpon>ctrlSearchResult.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Debugger\Controls\ctrlSpcStatus.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
|
@ -323,6 +329,12 @@
|
|||
<Compile Include="Debugger\frmBreakOn.Designer.cs">
|
||||
<DependentUpon>frmBreakOn.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Debugger\frmGoToAll.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Debugger\frmGoToAll.designer.cs">
|
||||
<DependentUpon>frmGoToAll.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Debugger\Integration\DbgImporter.cs" />
|
||||
<Compile Include="Debugger\Integration\frmIntegrationSettings.cs">
|
||||
<SubType>Form</SubType>
|
||||
|
|
Loading…
Add table
Reference in a new issue